diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/arch/arm/common/gic.c_original linux-linaro-3.4-2012.05-1_cavium/arch/arm/common/gic.c_original
--- linux-linaro-3.4-2012.05-1_original/arch/arm/common/gic.c_original	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/arch/arm/common/gic.c_original	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,784 @@
+/*
+ *  linux/arch/arm/common/gic.c
+ *
+ *  Copyright (C) 2002 ARM Limited, 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.
+ *
+ * Interrupt architecture for the GIC:
+ *
+ * o There is one Interrupt Distributor, which receives interrupts
+ *   from system devices and sends them to the Interrupt Controllers.
+ *
+ * o There is one CPU Interface per CPU, which sends interrupts sent
+ *   by the Distributor, and interrupts generated locally, to the
+ *   associated CPU. The base address of the CPU interface is usually
+ *   aliased so that the same address points to different chips depending
+ *   on the CPU it is accessed from.
+ *
+ * Note that IRQs 0-31 are special - they are local to each CPU.
+ * As such, the enable set/clear, pending set/clear and active bit
+ * registers are banked per-cpu for these sources.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/list.h>
+#include <linux/smp.h>
+#include <linux/cpu_pm.h>
+#include <linux/cpumask.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/irqdomain.h>
+#include <linux/interrupt.h>
+#include <linux/percpu.h>
+#include <linux/slab.h>
+
+#include <asm/irq.h>
+#include <asm/exception.h>
+#include <asm/smp_plat.h>
+#include <asm/mach/irq.h>
+#include <asm/hardware/gic.h>
+
+union gic_base {
+	void __iomem *common_base;
+	void __percpu __iomem **percpu_base;
+};
+
+struct gic_chip_data {
+	union gic_base dist_base;
+	union gic_base cpu_base;
+#ifdef CONFIG_CPU_PM
+	u32 saved_spi_enable[DIV_ROUND_UP(1020, 32)];
+	u32 saved_spi_conf[DIV_ROUND_UP(1020, 16)];
+	u32 saved_spi_target[DIV_ROUND_UP(1020, 4)];
+	u32 __percpu *saved_ppi_enable;
+	u32 __percpu *saved_ppi_conf;
+#endif
+	struct irq_domain *domain;
+	unsigned int gic_irqs;
+#ifdef CONFIG_GIC_NON_BANKED
+	void __iomem *(*get_base)(union gic_base *);
+#endif
+};
+
+static DEFINE_RAW_SPINLOCK(irq_controller_lock);
+
+/*
+ * Supported arch specific GIC irq extension.
+ * Default make them NULL.
+ */
+struct irq_chip gic_arch_extn = {
+	.irq_eoi	= NULL,
+	.irq_mask	= NULL,
+	.irq_unmask	= NULL,
+	.irq_retrigger	= NULL,
+	.irq_set_type	= NULL,
+	.irq_set_wake	= NULL,
+};
+
+#ifndef MAX_GIC_NR
+#define MAX_GIC_NR	1
+#endif
+
+static struct gic_chip_data gic_data[MAX_GIC_NR] __read_mostly;
+
+#ifdef CONFIG_GIC_NON_BANKED
+static void __iomem *gic_get_percpu_base(union gic_base *base)
+{
+	return *__this_cpu_ptr(base->percpu_base);
+}
+
+static void __iomem *gic_get_common_base(union gic_base *base)
+{
+	return base->common_base;
+}
+
+static inline void __iomem *gic_data_dist_base(struct gic_chip_data *data)
+{
+	return data->get_base(&data->dist_base);
+}
+
+static inline void __iomem *gic_data_cpu_base(struct gic_chip_data *data)
+{
+	return data->get_base(&data->cpu_base);
+}
+
+static inline void gic_set_base_accessor(struct gic_chip_data *data,
+					 void __iomem *(*f)(union gic_base *))
+{
+	data->get_base = f;
+}
+#else
+#define gic_data_dist_base(d)	((d)->dist_base.common_base)
+#define gic_data_cpu_base(d)	((d)->cpu_base.common_base)
+#define gic_set_base_accessor(d,f)
+#endif
+
+static inline void __iomem *gic_dist_base(struct irq_data *d)
+{
+	struct gic_chip_data *gic_data = irq_data_get_irq_chip_data(d);
+	return gic_data_dist_base(gic_data);
+}
+
+static inline void __iomem *gic_cpu_base(struct irq_data *d)
+{
+	struct gic_chip_data *gic_data = irq_data_get_irq_chip_data(d);
+	return gic_data_cpu_base(gic_data);
+}
+
+static inline unsigned int gic_irq(struct irq_data *d)
+{
+	return d->hwirq;
+}
+
+/*
+ * Routines to acknowledge, disable and enable interrupts
+ */
+static void gic_mask_irq(struct irq_data *d)
+{
+	u32 mask = 1 << (gic_irq(d) % 32);
+
+	raw_spin_lock(&irq_controller_lock);
+	writel_relaxed(mask, gic_dist_base(d) + GIC_DIST_ENABLE_CLEAR + (gic_irq(d) / 32) * 4);
+	if (gic_arch_extn.irq_mask)
+		gic_arch_extn.irq_mask(d);
+	raw_spin_unlock(&irq_controller_lock);
+}
+
+static void gic_unmask_irq(struct irq_data *d)
+{
+	u32 mask = 1 << (gic_irq(d) % 32);
+
+	raw_spin_lock(&irq_controller_lock);
+	if (gic_arch_extn.irq_unmask)
+		gic_arch_extn.irq_unmask(d);
+	writel_relaxed(mask, gic_dist_base(d) + GIC_DIST_ENABLE_SET + (gic_irq(d) / 32) * 4);
+	raw_spin_unlock(&irq_controller_lock);
+}
+
+static void gic_eoi_irq(struct irq_data *d)
+{
+	if (gic_arch_extn.irq_eoi) {
+		raw_spin_lock(&irq_controller_lock);
+		gic_arch_extn.irq_eoi(d);
+		raw_spin_unlock(&irq_controller_lock);
+	}
+
+	writel_relaxed(gic_irq(d), gic_cpu_base(d) + GIC_CPU_EOI);
+}
+
+static int gic_set_type(struct irq_data *d, unsigned int type)
+{
+	void __iomem *base = gic_dist_base(d);
+	unsigned int gicirq = gic_irq(d);
+	u32 enablemask = 1 << (gicirq % 32);
+	u32 enableoff = (gicirq / 32) * 4;
+	u32 confmask = 0x2 << ((gicirq % 16) * 2);
+	u32 confoff = (gicirq / 16) * 4;
+	bool enabled = false;
+	u32 val;
+
+	/* Interrupt configuration for SGIs can't be changed */
+	if (gicirq < 16)
+		return -EINVAL;
+
+	if (type != IRQ_TYPE_LEVEL_HIGH && type != IRQ_TYPE_EDGE_RISING)
+		return -EINVAL;
+
+	raw_spin_lock(&irq_controller_lock);
+
+	if (gic_arch_extn.irq_set_type)
+		gic_arch_extn.irq_set_type(d, type);
+
+	val = readl_relaxed(base + GIC_DIST_CONFIG + confoff);
+	if (type == IRQ_TYPE_LEVEL_HIGH)
+		val &= ~confmask;
+	else if (type == IRQ_TYPE_EDGE_RISING)
+		val |= confmask;
+
+	/*
+	 * As recommended by the spec, disable the interrupt before changing
+	 * the configuration
+	 */
+	if (readl_relaxed(base + GIC_DIST_ENABLE_SET + enableoff) & enablemask) {
+		writel_relaxed(enablemask, base + GIC_DIST_ENABLE_CLEAR + enableoff);
+		enabled = true;
+	}
+
+	writel_relaxed(val, base + GIC_DIST_CONFIG + confoff);
+
+	if (enabled)
+		writel_relaxed(enablemask, base + GIC_DIST_ENABLE_SET + enableoff);
+
+	raw_spin_unlock(&irq_controller_lock);
+
+	return 0;
+}
+
+static int gic_retrigger(struct irq_data *d)
+{
+	if (gic_arch_extn.irq_retrigger)
+		return gic_arch_extn.irq_retrigger(d);
+
+	return -ENXIO;
+}
+
+#ifdef CONFIG_SMP
+static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
+			    bool force)
+{
+	void __iomem *reg = gic_dist_base(d) + GIC_DIST_TARGET + (gic_irq(d) & ~3);
+	unsigned int shift = (gic_irq(d) % 4) * 8;
+	unsigned int cpu = cpumask_any_and(mask_val, cpu_online_mask);
+	u32 val, mask, bit;
+
+	if (cpu >= 8 || cpu >= nr_cpu_ids)
+		return -EINVAL;
+
+	mask = 0xff << shift;
+	bit = 1 << (cpu_logical_map(cpu) + shift);
+
+	raw_spin_lock(&irq_controller_lock);
+	val = readl_relaxed(reg) & ~mask;
+	writel_relaxed(val | bit, reg);
+	raw_spin_unlock(&irq_controller_lock);
+
+	return IRQ_SET_MASK_OK;
+}
+#endif
+
+#ifdef CONFIG_PM
+static int gic_set_wake(struct irq_data *d, unsigned int on)
+{
+	int ret = -ENXIO;
+
+	if (gic_arch_extn.irq_set_wake)
+		ret = gic_arch_extn.irq_set_wake(d, on);
+
+	return ret;
+}
+
+#else
+#define gic_set_wake	NULL
+#endif
+
+asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs)
+{
+	u32 irqstat, irqnr;
+	struct gic_chip_data *gic = &gic_data[0];
+	void __iomem *cpu_base = gic_data_cpu_base(gic);
+
+	do {
+		irqstat = readl_relaxed(cpu_base + GIC_CPU_INTACK);
+		irqnr = irqstat & ~0x1c00;
+
+		if (likely(irqnr > 15 && irqnr < 1021)) {
+			irqnr = irq_find_mapping(gic->domain, irqnr);
+			handle_IRQ(irqnr, regs);
+			continue;
+		}
+		if (irqnr < 16) {
+			writel_relaxed(irqstat, cpu_base + GIC_CPU_EOI);
+#ifdef CONFIG_SMP
+			handle_IPI(irqnr, regs);
+#endif
+			continue;
+		}
+		break;
+	} while (1);
+}
+
+static void gic_handle_cascade_irq(unsigned int irq, struct irq_desc *desc)
+{
+	struct gic_chip_data *chip_data = irq_get_handler_data(irq);
+	struct irq_chip *chip = irq_get_chip(irq);
+	unsigned int cascade_irq, gic_irq;
+	unsigned long status;
+
+	chained_irq_enter(chip, desc);
+
+	raw_spin_lock(&irq_controller_lock);
+	status = readl_relaxed(gic_data_cpu_base(chip_data) + GIC_CPU_INTACK);
+	raw_spin_unlock(&irq_controller_lock);
+
+	gic_irq = (status & 0x3ff);
+	if (gic_irq == 1023)
+		goto out;
+
+	cascade_irq = irq_find_mapping(chip_data->domain, gic_irq);
+	if (unlikely(gic_irq < 32 || gic_irq > 1020))
+		do_bad_IRQ(cascade_irq, desc);
+	else
+		generic_handle_irq(cascade_irq);
+
+ out:
+	chained_irq_exit(chip, desc);
+}
+
+static struct irq_chip gic_chip = {
+	.name			= "GIC",
+	.irq_mask		= gic_mask_irq,
+	.irq_unmask		= gic_unmask_irq,
+	.irq_eoi		= gic_eoi_irq,
+	.irq_set_type		= gic_set_type,
+	.irq_retrigger		= gic_retrigger,
+#ifdef CONFIG_SMP
+	.irq_set_affinity	= gic_set_affinity,
+#endif
+	.irq_set_wake		= gic_set_wake,
+};
+
+void __init gic_cascade_irq(unsigned int gic_nr, unsigned int irq)
+{
+	if (gic_nr >= MAX_GIC_NR)
+		BUG();
+	if (irq_set_handler_data(irq, &gic_data[gic_nr]) != 0)
+		BUG();
+	irq_set_chained_handler(irq, gic_handle_cascade_irq);
+}
+
+static void __init gic_dist_init(struct gic_chip_data *gic)
+{
+	unsigned int i;
+	u32 cpumask;
+	unsigned int gic_irqs = gic->gic_irqs;
+	void __iomem *base = gic_data_dist_base(gic);
+	u32 cpu = cpu_logical_map(smp_processor_id());
+
+	cpumask = 1 << cpu;
+	cpumask |= cpumask << 8;
+	cpumask |= cpumask << 16;
+
+	writel_relaxed(0, base + GIC_DIST_CTRL);
+
+	/*
+	 * Set all global interrupts to be level triggered, active low.
+	 */
+	for (i = 32; i < gic_irqs; i += 16)
+		writel_relaxed(0, base + GIC_DIST_CONFIG + i * 4 / 16);
+
+	/*
+	 * Set all global interrupts to this CPU only.
+	 */
+	for (i = 32; i < gic_irqs; i += 4)
+		writel_relaxed(cpumask, base + GIC_DIST_TARGET + i * 4 / 4);
+
+	/*
+	 * Set priority on all global interrupts.
+	 */
+	for (i = 32; i < gic_irqs; i += 4)
+		writel_relaxed(0xa0a0a0a0, base + GIC_DIST_PRI + i * 4 / 4);
+
+	/*
+	 * Disable all interrupts.  Leave the PPI and SGIs alone
+	 * as these enables are banked registers.
+	 */
+	for (i = 32; i < gic_irqs; i += 32)
+		writel_relaxed(0xffffffff, base + GIC_DIST_ENABLE_CLEAR + i * 4 / 32);
+
+	writel_relaxed(1, base + GIC_DIST_CTRL);
+}
+
+static void __cpuinit gic_cpu_init(struct gic_chip_data *gic)
+{
+	void __iomem *dist_base = gic_data_dist_base(gic);
+	void __iomem *base = gic_data_cpu_base(gic);
+	int i;
+
+	/*
+	 * Deal with the banked PPI and SGI interrupts - disable all
+	 * PPI interrupts, ensure all SGI interrupts are enabled.
+	 */
+	writel_relaxed(0xffff0000, dist_base + GIC_DIST_ENABLE_CLEAR);
+	writel_relaxed(0x0000ffff, dist_base + GIC_DIST_ENABLE_SET);
+
+	/*
+	 * Set priority on PPI and SGI interrupts
+	 */
+	for (i = 0; i < 32; i += 4)
+		writel_relaxed(0xa0a0a0a0, dist_base + GIC_DIST_PRI + i * 4 / 4);
+
+	writel_relaxed(0xf0, base + GIC_CPU_PRIMASK);
+	writel_relaxed(1, base + GIC_CPU_CTRL);
+}
+
+#ifdef CONFIG_CPU_PM
+/*
+ * Saves the GIC distributor registers during suspend or idle.  Must be called
+ * with interrupts disabled but before powering down the GIC.  After calling
+ * this function, no interrupts will be delivered by the GIC, and another
+ * platform-specific wakeup source must be enabled.
+ */
+static void gic_dist_save(unsigned int gic_nr)
+{
+	unsigned int gic_irqs;
+	void __iomem *dist_base;
+	int i;
+
+	if (gic_nr >= MAX_GIC_NR)
+		BUG();
+
+	gic_irqs = gic_data[gic_nr].gic_irqs;
+	dist_base = gic_data_dist_base(&gic_data[gic_nr]);
+
+	if (!dist_base)
+		return;
+
+	for (i = 0; i < DIV_ROUND_UP(gic_irqs, 16); i++)
+		gic_data[gic_nr].saved_spi_conf[i] =
+			readl_relaxed(dist_base + GIC_DIST_CONFIG + i * 4);
+
+	for (i = 0; i < DIV_ROUND_UP(gic_irqs, 4); i++)
+		gic_data[gic_nr].saved_spi_target[i] =
+			readl_relaxed(dist_base + GIC_DIST_TARGET + i * 4);
+
+	for (i = 0; i < DIV_ROUND_UP(gic_irqs, 32); i++)
+		gic_data[gic_nr].saved_spi_enable[i] =
+			readl_relaxed(dist_base + GIC_DIST_ENABLE_SET + i * 4);
+}
+
+/*
+ * Restores the GIC distributor registers during resume or when coming out of
+ * idle.  Must be called before enabling interrupts.  If a level interrupt
+ * that occured while the GIC was suspended is still present, it will be
+ * handled normally, but any edge interrupts that occured will not be seen by
+ * the GIC and need to be handled by the platform-specific wakeup source.
+ */
+static void gic_dist_restore(unsigned int gic_nr)
+{
+	unsigned int gic_irqs;
+	unsigned int i;
+	void __iomem *dist_base;
+
+	if (gic_nr >= MAX_GIC_NR)
+		BUG();
+
+	gic_irqs = gic_data[gic_nr].gic_irqs;
+	dist_base = gic_data_dist_base(&gic_data[gic_nr]);
+
+	if (!dist_base)
+		return;
+
+	writel_relaxed(0, dist_base + GIC_DIST_CTRL);
+
+	for (i = 0; i < DIV_ROUND_UP(gic_irqs, 16); i++)
+		writel_relaxed(gic_data[gic_nr].saved_spi_conf[i],
+			dist_base + GIC_DIST_CONFIG + i * 4);
+
+	for (i = 0; i < DIV_ROUND_UP(gic_irqs, 4); i++)
+		writel_relaxed(0xa0a0a0a0,
+			dist_base + GIC_DIST_PRI + i * 4);
+
+	for (i = 0; i < DIV_ROUND_UP(gic_irqs, 4); i++)
+		writel_relaxed(gic_data[gic_nr].saved_spi_target[i],
+			dist_base + GIC_DIST_TARGET + i * 4);
+
+	for (i = 0; i < DIV_ROUND_UP(gic_irqs, 32); i++)
+		writel_relaxed(gic_data[gic_nr].saved_spi_enable[i],
+			dist_base + GIC_DIST_ENABLE_SET + i * 4);
+
+	writel_relaxed(1, dist_base + GIC_DIST_CTRL);
+}
+
+static void gic_cpu_save(unsigned int gic_nr)
+{
+	int i;
+	u32 *ptr;
+	void __iomem *dist_base;
+	void __iomem *cpu_base;
+
+	if (gic_nr >= MAX_GIC_NR)
+		BUG();
+
+	dist_base = gic_data_dist_base(&gic_data[gic_nr]);
+	cpu_base = gic_data_cpu_base(&gic_data[gic_nr]);
+
+	if (!dist_base || !cpu_base)
+		return;
+
+	ptr = __this_cpu_ptr(gic_data[gic_nr].saved_ppi_enable);
+	for (i = 0; i < DIV_ROUND_UP(32, 32); i++)
+		ptr[i] = readl_relaxed(dist_base + GIC_DIST_ENABLE_SET + i * 4);
+
+	ptr = __this_cpu_ptr(gic_data[gic_nr].saved_ppi_conf);
+	for (i = 0; i < DIV_ROUND_UP(32, 16); i++)
+		ptr[i] = readl_relaxed(dist_base + GIC_DIST_CONFIG + i * 4);
+
+}
+
+static void gic_cpu_restore(unsigned int gic_nr)
+{
+	int i;
+	u32 *ptr;
+	void __iomem *dist_base;
+	void __iomem *cpu_base;
+
+	if (gic_nr >= MAX_GIC_NR)
+		BUG();
+
+	dist_base = gic_data_dist_base(&gic_data[gic_nr]);
+	cpu_base = gic_data_cpu_base(&gic_data[gic_nr]);
+
+	if (!dist_base || !cpu_base)
+		return;
+
+	ptr = __this_cpu_ptr(gic_data[gic_nr].saved_ppi_enable);
+	for (i = 0; i < DIV_ROUND_UP(32, 32); i++)
+		writel_relaxed(ptr[i], dist_base + GIC_DIST_ENABLE_SET + i * 4);
+
+	ptr = __this_cpu_ptr(gic_data[gic_nr].saved_ppi_conf);
+	for (i = 0; i < DIV_ROUND_UP(32, 16); i++)
+		writel_relaxed(ptr[i], dist_base + GIC_DIST_CONFIG + i * 4);
+
+	for (i = 0; i < DIV_ROUND_UP(32, 4); i++)
+		writel_relaxed(0xa0a0a0a0, dist_base + GIC_DIST_PRI + i * 4);
+
+	writel_relaxed(0xf0, cpu_base + GIC_CPU_PRIMASK);
+	writel_relaxed(1, cpu_base + GIC_CPU_CTRL);
+}
+
+static int gic_notifier(struct notifier_block *self, unsigned long cmd,	void *v)
+{
+	int i;
+
+	for (i = 0; i < MAX_GIC_NR; i++) {
+#ifdef CONFIG_GIC_NON_BANKED
+		/* Skip over unused GICs */
+		if (!gic_data[i].get_base)
+			continue;
+#endif
+		switch (cmd) {
+		case CPU_PM_ENTER:
+			gic_cpu_save(i);
+			break;
+		case CPU_PM_ENTER_FAILED:
+		case CPU_PM_EXIT:
+			gic_cpu_restore(i);
+			break;
+		case CPU_CLUSTER_PM_ENTER:
+			gic_dist_save(i);
+			break;
+		case CPU_CLUSTER_PM_ENTER_FAILED:
+		case CPU_CLUSTER_PM_EXIT:
+			gic_dist_restore(i);
+			break;
+		}
+	}
+
+	return NOTIFY_OK;
+}
+
+static struct notifier_block gic_notifier_block = {
+	.notifier_call = gic_notifier,
+};
+
+static void __init gic_pm_init(struct gic_chip_data *gic)
+{
+	gic->saved_ppi_enable = __alloc_percpu(DIV_ROUND_UP(32, 32) * 4,
+		sizeof(u32));
+	BUG_ON(!gic->saved_ppi_enable);
+
+	gic->saved_ppi_conf = __alloc_percpu(DIV_ROUND_UP(32, 16) * 4,
+		sizeof(u32));
+	BUG_ON(!gic->saved_ppi_conf);
+
+	if (gic == &gic_data[0])
+		cpu_pm_register_notifier(&gic_notifier_block);
+}
+#else
+static void __init gic_pm_init(struct gic_chip_data *gic)
+{
+}
+#endif
+
+static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq,
+				irq_hw_number_t hw)
+{
+	if (hw < 32) {
+		irq_set_percpu_devid(irq);
+		irq_set_chip_and_handler(irq, &gic_chip,
+					 handle_percpu_devid_irq);
+		set_irq_flags(irq, IRQF_VALID | IRQF_NOAUTOEN);
+	} else {
+		irq_set_chip_and_handler(irq, &gic_chip,
+					 handle_fasteoi_irq);
+		set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+	}
+	irq_set_chip_data(irq, d->host_data);
+	return 0;
+}
+
+static int gic_irq_domain_xlate(struct irq_domain *d,
+				struct device_node *controller,
+				const u32 *intspec, unsigned int intsize,
+				unsigned long *out_hwirq, unsigned int *out_type)
+{
+	if (d->of_node != controller)
+		return -EINVAL;
+	if (intsize < 3)
+		return -EINVAL;
+
+	/* Get the interrupt number and add 16 to skip over SGIs */
+	*out_hwirq = intspec[1] + 16;
+
+	/* For SPIs, we need to add 16 more to get the GIC irq ID number */
+	if (!intspec[0])
+		*out_hwirq += 16;
+
+	*out_type = intspec[2] & IRQ_TYPE_SENSE_MASK;
+	return 0;
+}
+
+const struct irq_domain_ops gic_irq_domain_ops = {
+	.map = gic_irq_domain_map,
+	.xlate = gic_irq_domain_xlate,
+};
+
+void __init gic_init_bases(unsigned int gic_nr, int irq_start,
+			   void __iomem *dist_base, void __iomem *cpu_base,
+			   u32 percpu_offset, struct device_node *node)
+{
+	irq_hw_number_t hwirq_base;
+	struct gic_chip_data *gic;
+	int gic_irqs, irq_base;
+
+	BUG_ON(gic_nr >= MAX_GIC_NR);
+
+	gic = &gic_data[gic_nr];
+#ifdef CONFIG_GIC_NON_BANKED
+	if (percpu_offset) { /* Frankein-GIC without banked registers... */
+		unsigned int cpu;
+
+		gic->dist_base.percpu_base = alloc_percpu(void __iomem *);
+		gic->cpu_base.percpu_base = alloc_percpu(void __iomem *);
+		if (WARN_ON(!gic->dist_base.percpu_base ||
+			    !gic->cpu_base.percpu_base)) {
+			free_percpu(gic->dist_base.percpu_base);
+			free_percpu(gic->cpu_base.percpu_base);
+			return;
+		}
+
+		for_each_possible_cpu(cpu) {
+			unsigned long offset = percpu_offset * cpu_logical_map(cpu);
+			*per_cpu_ptr(gic->dist_base.percpu_base, cpu) = dist_base + offset;
+			*per_cpu_ptr(gic->cpu_base.percpu_base, cpu) = cpu_base + offset;
+		}
+
+		gic_set_base_accessor(gic, gic_get_percpu_base);
+	} else
+#endif
+	{			/* Normal, sane GIC... */
+		WARN(percpu_offset,
+		     "GIC_NON_BANKED not enabled, ignoring %08x offset!",
+		     percpu_offset);
+		gic->dist_base.common_base = dist_base;
+		gic->cpu_base.common_base = cpu_base;
+		gic_set_base_accessor(gic, gic_get_common_base);
+	}
+
+	/*
+	 * For primary GICs, skip over SGIs.
+	 * For secondary GICs, skip over PPIs, too.
+	 */
+	if (gic_nr == 0 && (irq_start & 31) > 0) {
+		hwirq_base = 16;
+		if (irq_start != -1)
+			irq_start = (irq_start & ~31) + 16;
+	} else {
+		hwirq_base = 32;
+	}
+
+	/*
+	 * Find out how many interrupts are supported.
+	 * The GIC only supports up to 1020 interrupt sources.
+	 */
+	gic_irqs = readl_relaxed(gic_data_dist_base(gic) + GIC_DIST_CTR) & 0x1f;
+	gic_irqs = (gic_irqs + 1) * 32;
+	if (gic_irqs > 1020)
+		gic_irqs = 1020;
+	gic->gic_irqs = gic_irqs;
+
+	gic_irqs -= hwirq_base; /* calculate # of irqs to allocate */
+	irq_base = irq_alloc_descs(irq_start, 16, gic_irqs, numa_node_id());
+	if (IS_ERR_VALUE(irq_base)) {
+		WARN(1, "Cannot allocate irq_descs @ IRQ%d, assuming pre-allocated\n",
+		     irq_start);
+		irq_base = irq_start;
+	}
+	gic->domain = irq_domain_add_legacy(node, gic_irqs, irq_base,
+				    hwirq_base, &gic_irq_domain_ops, gic);
+	if (WARN_ON(!gic->domain))
+		return;
+
+	gic_chip.flags |= gic_arch_extn.flags;
+	gic_dist_init(gic);
+	gic_cpu_init(gic);
+	gic_pm_init(gic);
+}
+
+void __cpuinit gic_secondary_init(unsigned int gic_nr)
+{
+	BUG_ON(gic_nr >= MAX_GIC_NR);
+
+	gic_cpu_init(&gic_data[gic_nr]);
+}
+
+#ifdef CONFIG_SMP
+void gic_raise_softirq(const struct cpumask *mask, unsigned int irq)
+{
+	int cpu;
+	unsigned long map = 0;
+
+	/* Convert our logical CPU mask into a physical one. */
+	for_each_cpu(cpu, mask)
+		map |= 1 << cpu_logical_map(cpu);
+
+	/*
+	 * Ensure that stores to Normal memory are visible to the
+	 * other CPUs before issuing the IPI.
+	 */
+	dsb();
+
+	/* this always happens on GIC0 */
+	writel_relaxed(map << 16 | irq, gic_data_dist_base(&gic_data[0]) + GIC_DIST_SOFTINT);
+}
+#endif
+
+#ifdef CONFIG_OF
+static int gic_cnt __initdata = 0;
+
+int __init gic_of_init(struct device_node *node, struct device_node *parent)
+{
+	void __iomem *cpu_base;
+	void __iomem *dist_base;
+	u32 percpu_offset;
+	int irq;
+
+	if (WARN_ON(!node))
+		return -ENODEV;
+
+	dist_base = of_iomap(node, 0);
+	WARN(!dist_base, "unable to map gic dist registers\n");
+
+	cpu_base = of_iomap(node, 1);
+	WARN(!cpu_base, "unable to map gic cpu registers\n");
+
+	if (of_property_read_u32(node, "cpu-offset", &percpu_offset))
+		percpu_offset = 0;
+
+	gic_init_bases(gic_cnt, -1, dist_base, cpu_base, percpu_offset, node);
+
+	if (parent) {
+		irq = irq_of_parse_and_map(node, 0);
+		gic_cascade_irq(gic_cnt, irq);
+	}
+	gic_cnt++;
+	return 0;
+}
+#endif
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/arch/arm/configs/cnc1900_android_defconfig linux-linaro-3.4-2012.05-1_cavium/arch/arm/configs/cnc1900_android_defconfig
--- linux-linaro-3.4-2012.05-1_original/arch/arm/configs/cnc1900_android_defconfig	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/arch/arm/configs/cnc1900_android_defconfig	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,1953 @@
+#
+# Automatically generated file; DO NOT EDIT.
+# Linux/arm 3.4.0 Kernel Configuration
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+# CONFIG_ARCH_USES_GETTIMEOFFSET is not set
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_KTIME_SCALAR=y
+CONFIG_HAVE_PROC_CPU=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_ARCH_HAS_CPUFREQ=y
+CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_ZONE_DMA=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_VECTORS_BASE=0xffff0000
+# CONFIG_ARM_PATCH_PHYS_VIRT is not set
+CONFIG_PHYS_OFFSET=0x0
+CONFIG_GENERIC_BUG=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_HAVE_IRQ_WORK=y
+CONFIG_IRQ_WORK=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+# CONFIG_INIT_PASS_ALL_PARAMS is not set
+CONFIG_CROSS_COMPILE=""
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_XZ=y
+CONFIG_HAVE_KERNEL_LZO=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_XZ is not set
+# CONFIG_KERNEL_LZO is not set
+CONFIG_DEFAULT_HOSTNAME="(none)"
+CONFIG_VERSION_SIGNATURE=""
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_FHANDLE=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+CONFIG_HAVE_GENERIC_HARDIRQS=y
+
+#
+# IRQ subsystem
+#
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_IRQ_DOMAIN=y
+# CONFIG_IRQ_DOMAIN_DEBUG is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TINY_RCU=y
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=17
+# CONFIG_CGROUPS is not set
+# CONFIG_CHECKPOINT_RESTORE is not set
+# CONFIG_NAMESPACES is not set
+# CONFIG_SCHED_AUTOGROUP is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_RELAY=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+# CONFIG_RD_XZ is not set
+# CONFIG_RD_LZO is not set
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_PANIC_TIMEOUT=0
+CONFIG_EXPERT=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL 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_SHMEM=y
+CONFIG_AIO=y
+CONFIG_EMBEDDED=y
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_PERF_EVENTS=y
+# CONFIG_PERF_COUNTERS is not set
+# CONFIG_DEBUG_PERF_USE_VMALLOC is not set
+CONFIG_VM_EVENT_COUNTERS=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+CONFIG_PROFILING=y
+CONFIG_TRACEPOINTS=y
+# CONFIG_OPROFILE is not set
+CONFIG_HAVE_OPROFILE=y
+CONFIG_KPROBES=y
+# CONFIG_JUMP_LABEL is not set
+CONFIG_KRETPROBES=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_DMA_CONTIGUOUS=y
+CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_HW_BREAKPOINT=y
+CONFIG_HAVE_ARCH_JUMP_LABEL=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+CONFIG_MODULE_FORCE_LOAD=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+CONFIG_BLK_DEV_BSG=y
+# CONFIG_BLK_DEV_BSGLIB is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+CONFIG_EFI_PARTITION=y
+# CONFIG_SYSV68_PARTITION is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_DEADLINE is not set
+CONFIG_IOSCHED_CFQ=y
+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_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=y
+
+#
+# System Type
+#
+CONFIG_MMU=y
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_VEXPRESS is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_BCMRING is not set
+# CONFIG_ARCH_HIGHBANK is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CNS3XXX is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_PRIMA2 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+CONFIG_ARCH_CELESTIAL=y
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_MXS is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_DOVE is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LPC32XX is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_TEGRA is not set
+# CONFIG_ARCH_PICOXCELL is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_SHMOBILE is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C24XX is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5P64X0 is not set
+# CONFIG_ARCH_S5PC100 is not set
+# CONFIG_ARCH_S5PV210 is not set
+# CONFIG_ARCH_EXYNOS is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_U8500 is not set
+# CONFIG_ARCH_NOMADIK is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_PLAT_SPEAR is not set
+# CONFIG_ARCH_VT8500 is not set
+# CONFIG_ARCH_ZYNQ is not set
+
+#
+# Cavium Celestial platform type
+#
+CONFIG_MACH_CELESTIAL_CNC1900=y
+CONFIG_PUREVU=y
+# CONFIG_CELESTIAL_EVB is not set
+CONFIG_CELESTIAL_HDK=y
+# CONFIG_CELESTIAL_FJ_TX is not set
+# CONFIG_CELESTIAL_FJ_RX is not set
+# CONFIG_CELESTIAL_OTT_EMMC is not set
+
+#
+# System MMU
+#
+
+#
+# Processor Type
+#
+CONFIG_CPU_V7=y
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_32v7=y
+CONFIG_CPU_ABRT_EV7=y
+CONFIG_CPU_PABRT_V7=y
+CONFIG_CPU_CACHE_V7=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_TLB_V7=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+# CONFIG_ARM_LPAE is not set
+# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
+CONFIG_ARM_THUMB=y
+CONFIG_ARM_THUMBEE=y
+# CONFIG_SWP_EMULATE is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_OUTER_CACHE=y
+CONFIG_OUTER_CACHE_SYNC=y
+CONFIG_MIGHT_HAVE_CACHE_L2X0=y
+CONFIG_CACHE_L2X0=y
+CONFIG_CACHE_PL310=y
+CONFIG_ARM_L1_CACHE_SHIFT=5
+CONFIG_ARM_DMA_MEM_BUFFERABLE=y
+CONFIG_ARM_NR_BANKS=8
+CONFIG_CPU_HAS_PMU=y
+CONFIG_MULTI_IRQ_HANDLER=y
+# CONFIG_ARM_ERRATA_430973 is not set
+# CONFIG_ARM_ERRATA_458693 is not set
+# CONFIG_ARM_ERRATA_460075 is not set
+CONFIG_PL310_ERRATA_588369=y
+# CONFIG_ARM_ERRATA_720789 is not set
+CONFIG_PL310_ERRATA_727915=y
+# CONFIG_ARM_ERRATA_743622 is not set
+# CONFIG_ARM_ERRATA_751472 is not set
+# CONFIG_PL310_ERRATA_753970 is not set
+CONFIG_ARM_ERRATA_754322=y
+# CONFIG_PL310_ERRATA_769419 is not set
+CONFIG_ARM_GIC=y
+# CONFIG_FIQ_DEBUGGER is not set
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_HAVE_SMP=y
+# CONFIG_SMP is not set
+CONFIG_HAVE_ARM_SCU=y
+CONFIG_HAVE_ARM_TWD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_ARCH_NR_GPIO=0
+# CONFIG_PREEMPT_NONE is not set
+CONFIG_PREEMPT_VOLUNTARY=y
+# CONFIG_PREEMPT is not set
+CONFIG_HZ=100
+# CONFIG_THUMB2_KERNEL is not set
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+CONFIG_HAVE_ARCH_PFN_VALID=y
+CONFIG_HIGHMEM=y
+# CONFIG_HIGHPTE is not set
+CONFIG_HW_PERF_EVENTS=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_HAVE_MEMBLOCK=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_COMPACTION=y
+CONFIG_MIGRATION=y
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+CONFIG_KSM=y
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_NEED_PER_CPU_KM=y
+# CONFIG_CLEANCACHE is not set
+CONFIG_FORCE_MAX_ZONEORDER=11
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+# CONFIG_SECCOMP is not set
+# CONFIG_CC_STACKPROTECTOR is not set
+# CONFIG_DEPRECATED_PARAM_STRUCT is not set
+# CONFIG_ARM_FLUSH_CONSOLE_ON_RESTART is not set
+
+#
+# Boot options
+#
+# CONFIG_USE_OF is not set
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_CMDLINE=""
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+# CONFIG_CRASH_DUMP is not set
+# CONFIG_AUTO_ZRELADDR is not set
+
+#
+# CPU Power Management
+#
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+# CONFIG_FPE_NWFPE is not set
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_VFP=y
+CONFIG_VFPv3=y
+# CONFIG_NEON is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y
+CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_HAS_WAKELOCK is not set
+# CONFIG_WAKELOCK is not set
+# CONFIG_USER_WAKELOCK is not set
+CONFIG_PM_SLEEP=y
+CONFIG_PM_RUNTIME=y
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+# CONFIG_APM_EMULATION is not set
+CONFIG_PM_CLK=y
+CONFIG_CPU_PM=y
+# CONFIG_SUSPEND_TIME is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ARM_CPU_SUSPEND=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_UNIX_DIAG=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+# CONFIG_IP_PNP is not set
+# 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=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+CONFIG_INET_LRO=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_INET_UDP_DIAG is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+CONFIG_IPV6=y
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_IPV6_OPTIMISTIC_DAD is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_IPV6_MIP6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+CONFIG_INET6_XFRM_MODE_TRANSPORT=y
+CONFIG_INET6_XFRM_MODE_TUNNEL=y
+CONFIG_INET6_XFRM_MODE_BEET=y
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=y
+# CONFIG_IPV6_SIT_6RD is not set
+CONFIG_IPV6_NDISC_NODETYPE=y
+# CONFIG_IPV6_TUNNEL is not set
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_IPV6_MROUTE is not set
+CONFIG_ANDROID_PARANOID_NETWORK=y
+CONFIG_NET_ACTIVITY_STATS=y
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETWORK_PHY_TIMESTAMPING is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_NETFILTER_ADVANCED=y
+
+#
+# Core Netfilter Configuration
+#
+CONFIG_NETFILTER_NETLINK=y
+CONFIG_NETFILTER_NETLINK_ACCT=y
+CONFIG_NETFILTER_NETLINK_QUEUE=y
+CONFIG_NETFILTER_NETLINK_LOG=y
+# CONFIG_NF_CONNTRACK is not set
+CONFIG_NETFILTER_TPROXY=y
+CONFIG_NETFILTER_XTABLES=y
+
+#
+# Xtables combined modules
+#
+# CONFIG_NETFILTER_XT_MARK is not set
+
+#
+# Xtables targets
+#
+# CONFIG_NETFILTER_XT_TARGET_CHECKSUM is not set
+# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set
+# CONFIG_NETFILTER_XT_TARGET_DSCP is not set
+# CONFIG_NETFILTER_XT_TARGET_HL is not set
+# CONFIG_NETFILTER_XT_TARGET_IDLETIMER is not set
+# CONFIG_NETFILTER_XT_TARGET_LOG is not set
+# CONFIG_NETFILTER_XT_TARGET_MARK is not set
+# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set
+# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set
+# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set
+# CONFIG_NETFILTER_XT_TARGET_TEE is not set
+# CONFIG_NETFILTER_XT_TARGET_TPROXY is not set
+# CONFIG_NETFILTER_XT_TARGET_TRACE is not set
+# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set
+# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set
+
+#
+# Xtables matches
+#
+# CONFIG_NETFILTER_XT_MATCH_ADDRTYPE is not set
+# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set
+# CONFIG_NETFILTER_XT_MATCH_CPU is not set
+# CONFIG_NETFILTER_XT_MATCH_DCCP is not set
+# CONFIG_NETFILTER_XT_MATCH_DEVGROUP is not set
+# CONFIG_NETFILTER_XT_MATCH_DSCP is not set
+# CONFIG_NETFILTER_XT_MATCH_ECN is not set
+# CONFIG_NETFILTER_XT_MATCH_ESP is not set
+# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set
+# CONFIG_NETFILTER_XT_MATCH_HL is not set
+# CONFIG_NETFILTER_XT_MATCH_IPRANGE is not set
+# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set
+# CONFIG_NETFILTER_XT_MATCH_LIMIT is not set
+# CONFIG_NETFILTER_XT_MATCH_MAC is not set
+# CONFIG_NETFILTER_XT_MATCH_MARK is not set
+# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set
+# CONFIG_NETFILTER_XT_MATCH_NFACCT is not set
+# CONFIG_NETFILTER_XT_MATCH_OSF is not set
+# CONFIG_NETFILTER_XT_MATCH_OWNER is not set
+# CONFIG_NETFILTER_XT_MATCH_POLICY is not set
+# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set
+CONFIG_NETFILTER_XT_MATCH_QTAGUID=y
+# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set
+CONFIG_NETFILTER_XT_MATCH_QUOTA2=y
+CONFIG_NETFILTER_XT_MATCH_QUOTA2_LOG=y
+# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set
+# CONFIG_NETFILTER_XT_MATCH_REALM is not set
+# CONFIG_NETFILTER_XT_MATCH_RECENT is not set
+# CONFIG_NETFILTER_XT_MATCH_SCTP is not set
+CONFIG_NETFILTER_XT_MATCH_SOCKET=y
+# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set
+# CONFIG_NETFILTER_XT_MATCH_STRING is not set
+# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set
+# CONFIG_NETFILTER_XT_MATCH_TIME is not set
+# CONFIG_NETFILTER_XT_MATCH_U32 is not set
+# CONFIG_IP_SET is not set
+# CONFIG_IP_VS is not set
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_NF_DEFRAG_IPV4=y
+# CONFIG_IP_NF_QUEUE is not set
+CONFIG_IP_NF_IPTABLES=y
+# CONFIG_IP_NF_MATCH_AH is not set
+# CONFIG_IP_NF_MATCH_ECN is not set
+# CONFIG_IP_NF_MATCH_RPFILTER is not set
+# CONFIG_IP_NF_MATCH_TTL is not set
+CONFIG_IP_NF_FILTER=y
+# CONFIG_IP_NF_TARGET_REJECT is not set
+# CONFIG_IP_NF_TARGET_ULOG is not set
+CONFIG_IP_NF_MANGLE=y
+# CONFIG_IP_NF_TARGET_ECN is not set
+# CONFIG_IP_NF_TARGET_TTL is not set
+CONFIG_IP_NF_RAW=y
+CONFIG_IP_NF_ARPTABLES=y
+CONFIG_IP_NF_ARPFILTER=y
+# CONFIG_IP_NF_ARP_MANGLE is not set
+
+#
+# IPv6: Netfilter Configuration
+#
+CONFIG_NF_DEFRAG_IPV6=y
+# CONFIG_IP6_NF_QUEUE is not set
+CONFIG_IP6_NF_IPTABLES=y
+# CONFIG_IP6_NF_MATCH_AH is not set
+# CONFIG_IP6_NF_MATCH_EUI64 is not set
+# CONFIG_IP6_NF_MATCH_FRAG is not set
+# CONFIG_IP6_NF_MATCH_OPTS is not set
+# CONFIG_IP6_NF_MATCH_HL is not set
+# CONFIG_IP6_NF_MATCH_IPV6HEADER is not set
+# CONFIG_IP6_NF_MATCH_MH is not set
+# CONFIG_IP6_NF_MATCH_RPFILTER is not set
+# CONFIG_IP6_NF_MATCH_RT is not set
+# CONFIG_IP6_NF_TARGET_HL is not set
+CONFIG_IP6_NF_FILTER=y
+# CONFIG_IP6_NF_TARGET_REJECT is not set
+CONFIG_IP6_NF_MANGLE=y
+CONFIG_IP6_NF_RAW=y
+# 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_DNS_RESOLVER=y
+# CONFIG_BATMAN_ADV is not set
+# CONFIG_OPENVSWITCH is not set
+CONFIG_BQL=y
+CONFIG_HAVE_BPF_JIT=y
+# CONFIG_BPF_JIT is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NET_TCPPROBE is not set
+# CONFIG_NET_DROP_MONITOR 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_WEXT_CORE=y
+CONFIG_WEXT_PROC=y
+CONFIG_CFG80211=m
+# CONFIG_NL80211_TESTMODE is not set
+# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set
+# CONFIG_CFG80211_REG_DEBUG is not set
+CONFIG_CFG80211_DEFAULT_PS=y
+# CONFIG_CFG80211_DEBUGFS is not set
+# CONFIG_CFG80211_INTERNAL_REGDB is not set
+CONFIG_CFG80211_WEXT=y
+# CONFIG_WIRELESS_EXT_SYSFS is not set
+CONFIG_LIB80211=y
+# CONFIG_LIB80211_DEBUG is not set
+CONFIG_CFG80211_ALLOW_RECONNECT=y
+# CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
+CONFIG_RFKILL=y
+CONFIG_RFKILL_PM=y
+# CONFIG_RFKILL_INPUT is not set
+# CONFIG_NET_9P is not set
+# CONFIG_CAIF is not set
+# CONFIG_CEPH_LIB is not set
+# CONFIG_NFC is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH=""
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_STANDALONE is not set
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_GENERIC_CPU_DEVICES is not set
+# CONFIG_DMA_SHARED_BUFFER is not set
+# CONFIG_SYNC is not set
+CONFIG_CMA=y
+# CONFIG_CMA_DEBUG is not set
+
+#
+# Default contiguous memory area size:
+#
+CONFIG_CMA_SIZE_MBYTES=16
+CONFIG_CMA_SIZE_SEL_MBYTES=y
+# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set
+# CONFIG_CMA_SIZE_SEL_MIN is not set
+# CONFIG_CMA_SIZE_SEL_MAX is not set
+CONFIG_CMA_ALIGNMENT=8
+CONFIG_CMA_AREAS=7
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+# CONFIG_MTD is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_LOOP_MIN_COUNT=2
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_DRBD is not set
+CONFIG_BLK_DEV_NBD=y
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=4
+CONFIG_BLK_DEV_RAM_SIZE=16384
+# 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
+
+#
+# Misc devices
+#
+# CONFIG_SENSORS_LIS3LV02D is not set
+# CONFIG_ATMEL_PWM is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_UID_STAT is not set
+# CONFIG_WL127X_RFKILL is not set
+CONFIG_ANDROID_PMEM=y
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_IWMC3200TOP is not set
+
+#
+# Texas Instruments shared transport line discipline
+#
+
+#
+# Altera FPGA firmware download module
+#
+
+#
+# SCSI device support
+#
+CONFIG_SCSI_MOD=y
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+CONFIG_SCSI_MULTI_LUN=y
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+# CONFIG_SCSI_LOWLEVEL is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+# CONFIG_ATA is not set
+CONFIG_MD=y
+# CONFIG_BLK_DEV_MD is not set
+CONFIG_BLK_DEV_DM=y
+# CONFIG_DM_DEBUG is not set
+CONFIG_DM_CRYPT=y
+# CONFIG_DM_SNAPSHOT is not set
+# CONFIG_DM_THIN_PROVISIONING is not set
+# CONFIG_DM_MIRROR is not set
+# CONFIG_DM_RAID is not set
+# CONFIG_DM_ZERO is not set
+# CONFIG_DM_MULTIPATH is not set
+# CONFIG_DM_DELAY is not set
+# CONFIG_DM_UEVENT is not set
+# CONFIG_DM_FLAKEY is not set
+# CONFIG_DM_VERITY is not set
+# CONFIG_TARGET_CORE is not set
+CONFIG_NETDEVICES=y
+CONFIG_NET_CORE=y
+# CONFIG_BONDING is not set
+# CONFIG_DUMMY is not set
+# CONFIG_EQUALIZER is not set
+CONFIG_MII=y
+# CONFIG_NET_TEAM is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+
+#
+# CAIF transport drivers
+#
+CONFIG_ETHERNET=y
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_CALXEDA_XGMAC is not set
+# CONFIG_NET_VENDOR_CHELSIO is not set
+# CONFIG_NET_VENDOR_CIRRUS is not set
+# CONFIG_DM9000 is not set
+# CONFIG_DNET is not set
+# CONFIG_NET_VENDOR_FARADAY is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_ETHOC is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_PHYLIB is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_USB_HSO is not set
+# CONFIG_USB_IPHETH is not set
+CONFIG_WLAN=y
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_USB_NET_RNDIS_WLAN is not set
+# CONFIG_WIFI_CONTROL_FUNC is not set
+# CONFIG_ATH_COMMON is not set
+# CONFIG_BCMDHD is not set
+# CONFIG_BRCMFMAC is not set
+# CONFIG_HOSTAP is not set
+# CONFIG_IWM is not set
+# CONFIG_LIBERTAS is not set
+# CONFIG_MWIFIEX is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+# CONFIG_WAN is not set
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+CONFIG_INPUT_FF_MEMLESS=y
+# CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1280
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=720
+CONFIG_INPUT_JOYDEV=y
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+# CONFIG_INPUT_KEYRESET is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
+# CONFIG_KEYBOARD_SAMSUNG is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_OMAP4 is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+CONFIG_INPUT_MOUSE=y
+# CONFIG_MOUSE_PS2 is not set
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_APPLETOUCH is not set
+# CONFIG_MOUSE_BCM5974 is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_MOUSE_SYNAPTICS_USB is not set
+CONFIG_INPUT_JOYSTICK=y
+# CONFIG_JOYSTICK_ANALOG is not set
+# CONFIG_JOYSTICK_A3D is not set
+# CONFIG_JOYSTICK_ADI is not set
+# CONFIG_JOYSTICK_COBRA is not set
+# CONFIG_JOYSTICK_GF2K is not set
+# CONFIG_JOYSTICK_GRIP is not set
+# CONFIG_JOYSTICK_GRIP_MP is not set
+# CONFIG_JOYSTICK_GUILLEMOT is not set
+# CONFIG_JOYSTICK_INTERACT is not set
+# CONFIG_JOYSTICK_SIDEWINDER is not set
+# CONFIG_JOYSTICK_TMDC is not set
+# CONFIG_JOYSTICK_IFORCE is not set
+# CONFIG_JOYSTICK_WARRIOR is not set
+# CONFIG_JOYSTICK_MAGELLAN is not set
+# CONFIG_JOYSTICK_SPACEORB is not set
+# CONFIG_JOYSTICK_SPACEBALL is not set
+# CONFIG_JOYSTICK_STINGER is not set
+# CONFIG_JOYSTICK_TWIDJOY is not set
+# CONFIG_JOYSTICK_ZHENHUA is not set
+# CONFIG_JOYSTICK_JOYDUMP is not set
+# CONFIG_JOYSTICK_XPAD is not set
+# CONFIG_INPUT_TABLET is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_TOUCHSCREEN_AD7879 is not set
+# CONFIG_TOUCHSCREEN_CYTTSP_CORE is not set
+# CONFIG_TOUCHSCREEN_DYNAPRO is not set
+# CONFIG_TOUCHSCREEN_HAMPSHIRE is not set
+# CONFIG_TOUCHSCREEN_FUJITSU is not set
+# CONFIG_TOUCHSCREEN_GUNZE is not set
+# CONFIG_TOUCHSCREEN_ELO is not set
+# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set
+# CONFIG_TOUCHSCREEN_MTOUCH is not set
+# CONFIG_TOUCHSCREEN_INEXIO is not set
+# CONFIG_TOUCHSCREEN_MK712 is not set
+# CONFIG_TOUCHSCREEN_PENMOUNT is not set
+# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
+# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
+# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
+# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
+# CONFIG_TOUCHSCREEN_TSC_SERIO is not set
+# CONFIG_TOUCHSCREEN_W90X900 is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_SERIO_ALTERA_PS2 is not set
+# CONFIG_SERIO_PS2MULT is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_VT_CONSOLE_SLEEP=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_DEVPTS_MULTIPLE_INSTANCES=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_N_GSM is not set
+# CONFIG_TRACE_SINK is not set
+CONFIG_DEVMEM=y
+CONFIG_DEVKMEM=y
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=32
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_MANY_PORTS=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_RSA is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
+# CONFIG_SERIAL_ALTERA_JTAGUART is not set
+# CONFIG_SERIAL_ALTERA_UART is not set
+# CONFIG_SERIAL_XILINX_PS_UART is not set
+# CONFIG_TTY_PRINTK is not set
+# CONFIG_HVC_DCC is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+# CONFIG_DCC_TTY is not set
+# CONFIG_RAMOOPS is not set
+# CONFIG_I2C is not set
+# CONFIG_SPI is not set
+# CONFIG_HSI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+
+#
+# PPS generators support
+#
+
+#
+# PTP clock support
+#
+
+#
+# Enable Device Drivers -> PPS to see the PTP clock options.
+#
+# 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_CORE=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_DW_WATCHDOG is not set
+# CONFIG_MPCORE_WATCHDOG is not set
+# CONFIG_MAX63XX_WATCHDOG is not set
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+CONFIG_BCMA_POSSIBLE=y
+
+#
+# Broadcom specific AMBA
+#
+# CONFIG_BCMA is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_ABX500_CORE is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_DRM is not set
+# CONFIG_ION is not set
+# CONFIG_MALI400MP is not set
+# CONFIG_UMP is not set
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+CONFIG_FB_FOREIGN_ENDIAN=y
+# CONFIG_FB_BOTH_ENDIAN is not set
+# CONFIG_FB_BIG_ENDIAN is not set
+CONFIG_FB_LITTLE_ENDIAN=y
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_WMT_GE_ROPS is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_ARMHDLCD is not set
+# CONFIG_FB_UVESA is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_SMSCUFX is not set
+# CONFIG_FB_UDL is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_BROADSHEET is not set
+# CONFIG_EXYNOS_VIDEO is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+CONFIG_FB_CELESTIAL=y
+CONFIG_FB0_SIZE=0x708000
+CONFIG_FB2_SIZE=0x384000
+CONFIG_FB1_SIZE=0x0
+CONFIG_FB3_SIZE=0x0
+CONFIG_ANDROID_FB0_ONLY=y
+
+#
+# Console display driver support
+#
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE is not set
+# CONFIG_LOGO is not set
+# CONFIG_SOUND is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+# CONFIG_HID_PID is not set
+# CONFIG_USB_HIDDEV is not set
+
+#
+# Special HID drivers
+#
+# CONFIG_HID_A4TECH is not set
+# CONFIG_HID_ACRUX is not set
+# CONFIG_HID_APPLE is not set
+# CONFIG_HID_BELKIN is not set
+# CONFIG_HID_CHERRY is not set
+# CONFIG_HID_CHICONY is not set
+# CONFIG_HID_CYPRESS is not set
+# CONFIG_HID_DRAGONRISE is not set
+# CONFIG_HID_EMS_FF is not set
+# CONFIG_HID_EZKEY is not set
+# CONFIG_HID_HOLTEK is not set
+# CONFIG_HID_KEYTOUCH is not set
+# CONFIG_HID_KYE is not set
+# CONFIG_HID_UCLOGIC is not set
+# CONFIG_HID_WALTOP is not set
+# CONFIG_HID_GYRATION is not set
+# CONFIG_HID_TWINHAN is not set
+# CONFIG_HID_KENSINGTON is not set
+# CONFIG_HID_LCPOWER is not set
+# CONFIG_HID_LOGITECH is not set
+# CONFIG_HID_MICROSOFT is not set
+# CONFIG_HID_MONTEREY is not set
+# CONFIG_HID_MULTITOUCH is not set
+# CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
+# CONFIG_HID_PANTHERLORD is not set
+# CONFIG_HID_PETALYNX is not set
+# CONFIG_HID_PICOLCD is not set
+# CONFIG_HID_PRIMAX is not set
+# CONFIG_HID_ROCCAT is not set
+# CONFIG_HID_SAITEK is not set
+# CONFIG_HID_SAMSUNG is not set
+# CONFIG_HID_SONY is not set
+# CONFIG_HID_SPEEDLINK is not set
+# CONFIG_HID_SUNPLUS is not set
+# CONFIG_HID_GREENASIA is not set
+# CONFIG_HID_SMARTJOYPLUS is not set
+# CONFIG_HID_TIVO is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_HID_THRUSTMASTER is not set
+# CONFIG_HID_ZEROPLUS is not set
+# CONFIG_HID_ZYDACRON is not set
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+# CONFIG_USB_ARCH_HAS_XHCI is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_COMMON=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEVICEFS is not set
+# CONFIG_USB_DEVICE_CLASS is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+CONFIG_USB_SUSPEND=y
+CONFIG_USB_OTG=y
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+# CONFIG_USB_DWC3 is not set
+# CONFIG_USB_MON is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+CONFIG_USB_EHCI_HCD=y
+# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+CONFIG_USB_EHCI_TT_NEWSCHED=y
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_OHCI_HCD_PLATFORM=y
+CONFIG_USB_EHCI_HCD_PLATFORM=y
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_MUSB_HDRC is not set
+# CONFIG_USB_RENESAS_USBHS is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# also be needed; see USB_STORAGE Help for more info
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_REALTEK is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_STORAGE_ENE_UB6250 is not set
+# CONFIG_USB_UAS is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_YUREX is not set
+CONFIG_USB_GADGET=y
+# CONFIG_USB_GADGET_DEBUG is not set
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+# CONFIG_USB_GADGET_DEBUG_FS is not set
+CONFIG_USB_GADGET_VBUS_DRAW=2
+CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2
+# CONFIG_USB_FUSB300 is not set
+# CONFIG_USB_R8A66597 is not set
+# CONFIG_USB_MV_UDC is not set
+# CONFIG_USB_M66592 is not set
+# CONFIG_USB_NET2272 is not set
+# CONFIG_USB_DUMMY_HCD is not set
+CONFIG_USB_GADGET_DUALSPEED=y
+# CONFIG_USB_ZERO is not set
+# CONFIG_USB_ETH is not set
+# CONFIG_USB_G_NCM is not set
+# CONFIG_USB_GADGETFS is not set
+# CONFIG_USB_FUNCTIONFS is not set
+# CONFIG_USB_FILE_STORAGE is not set
+CONFIG_USB_MASS_STORAGE=m
+# CONFIG_USB_G_SERIAL is not set
+# CONFIG_USB_G_PRINTER is not set
+# CONFIG_USB_CDC_COMPOSITE is not set
+# CONFIG_USB_G_ACM_MS is not set
+# CONFIG_USB_G_MULTI is not set
+CONFIG_USB_G_HID=m
+# CONFIG_USB_G_HID_KEYBOARD is not set
+# CONFIG_USB_G_HID_MOUSE is not set
+# CONFIG_USB_G_HID_JOYSTICK is not set
+# CONFIG_USB_G_HID_MCU is not set
+# CONFIG_USB_G_HID_MULTITOUCH is not set
+# CONFIG_USB_G_DBGP is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_USB_ULPI is not set
+# CONFIG_NOP_USB_XCEIV is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+CONFIG_MMC_CLKGATE=y
+CONFIG_MMC_EMBEDDED_SDIO=y
+# CONFIG_MMC_PARANOID_SD_INIT is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_MINORS=8
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_MMC_BLOCK_DEFERRED_RESUME is not set
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+# CONFIG_MMC_SDHCI is not set
+# CONFIG_MMC_SDHCI_PXAV3 is not set
+# CONFIG_MMC_SDHCI_PXAV2 is not set
+CONFIG_MMC_DW=y
+# CONFIG_MMC_DW_IDMAC is not set
+CONFIG_MMC_DW_PLTFM=y
+# CONFIG_MMC_VUB300 is not set
+# CONFIG_MMC_USHC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_SWITCH is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# Virtio drivers
+#
+# CONFIG_VIRTIO_BALLOON is not set
+# CONFIG_VIRTIO_MMIO is not set
+
+#
+# Microsoft Hyper-V guest support
+#
+CONFIG_STAGING=y
+# CONFIG_USBIP_CORE is not set
+# CONFIG_PRISM2_USB is not set
+# CONFIG_ECHO is not set
+# CONFIG_ASUS_OLED is not set
+# CONFIG_RTLLIB is not set
+# CONFIG_R8712U is not set
+# CONFIG_RTS5139 is not set
+# CONFIG_TRANZPORT is not set
+# CONFIG_VT6656 is not set
+# CONFIG_IIO is not set
+# CONFIG_FB_SM7XX is not set
+# CONFIG_USB_ENESTORAGE is not set
+# CONFIG_BCM_WIMAX is not set
+# CONFIG_FT1000 is not set
+
+#
+# Speakup console speech
+#
+# CONFIG_SPEAKUP is not set
+# CONFIG_STAGING_MEDIA is not set
+
+#
+# Android
+#
+CONFIG_ANDROID=y
+CONFIG_ANDROID_BINDER_IPC=y
+CONFIG_ASHMEM=y
+CONFIG_ANDROID_LOGGER=y
+# CONFIG_ANDROID_RAM_CONSOLE is not set
+# CONFIG_PERSISTENT_TRACER is not set
+CONFIG_ANDROID_TIMED_OUTPUT=y
+CONFIG_ANDROID_LOW_MEMORY_KILLER=y
+CONFIG_ANDROID_SWITCH=y
+# CONFIG_PHONE is not set
+# CONFIG_USB_WPAN_HCD is not set
+CONFIG_CLKDEV_LOOKUP=y
+CONFIG_HAVE_CLK_PREPARE=y
+CONFIG_COMMON_CLK=y
+
+#
+# Common Clock Framework
+#
+# CONFIG_COMMON_CLK_DISABLE_UNUSED is not set
+# CONFIG_COMMON_CLK_DEBUG is not set
+
+#
+# Hardware Spinlock drivers
+#
+CONFIG_CLKSRC_MMIO=y
+# CONFIG_IOMMU_SUPPORT is not set
+
+#
+# Remoteproc drivers (EXPERIMENTAL)
+#
+
+#
+# Rpmsg drivers (EXPERIMENTAL)
+#
+# CONFIG_VIRT_DRIVERS is not set
+# CONFIG_PM_DEVFREQ is not set
+# CONFIG_GATOR is not set
+
+#
+# Celestial Device Drivers
+#
+
+#
+# Celestial DF Drivers
+#
+CONFIG_CELESTIAL_DF=y
+# CONFIG_HD2SD_ENABLE is not set
+# CONFIG_YPBPR_DAC_ENABLE is not set
+# CONFIG_CELESTIAL_DF_DEBUG is not set
+
+#
+# Celestial Xport Drivers
+#
+# CONFIG_CELESTIAL_XPORT is not set
+
+#
+# Celestial Video Drivers
+#
+CONFIG_CELESTIAL_VIDEO=y
+CONFIG_VIDEO_DECODER=y
+# CONFIG_VIDEO_ENCODER is not set
+CONFIG_VIDEO_CODA_CLOCK=0
+CONFIG_VIDEO_NUM=1
+CONFIG_VIDEO_CPB_SIZE=0x400000
+# CONFIG_CELESTIAL_VIDEO_DEBUG is not set
+
+#
+# Celestial Audio Drivers
+#
+CONFIG_CELESTIAL_AUDIO=y
+CONFIG_AUDIO_DECODER=y
+# CONFIG_AUDIO_ENCODER is not set
+# CONFIG_AUDIO_AAB is not set
+CONFIG_AUDIO_NUM=1
+CONFIG_AUDIO_CAB_SIZE=0x18000
+# CONFIG_CELESTIAL_AUDIO_DEBUG is not set
+# CONFIG_AUDIO_FW_DUMP_DEBUG is not set
+
+#
+# Celestial Peripheral Devices
+#
+CONFIG_CELESTIAL_ETH=y
+# CONFIG_CELESTIAL_MULT_ETH is not set
+CONFIG_CELESTIAL_MMC=y
+# CONFIG_CELESTIAL_MULT_MMC is not set
+# CONFIG_CELESTIAL_8BIT_MMC is not set
+CONFIG_CELESTIAL_HCI=y
+CONFIG_CELESTIAL_OTG=y
+# CONFIG_CELESTIAL_SCI is not set
+CONFIG_CELESTIAL_GPIO=y
+CONFIG_CELESTIAL_FPC=y
+CONFIG_CELESTIAL_FPC_IR_GPIO=11
+# CONFIG_CELESTIAL_WDT is not set
+# CONFIG_CELESTIAL_SEC is not set
+# CONFIG_VGA_SWITCHER_SUPPORT is not set
+
+#
+# Celestial Graphics driver
+#
+# CONFIG_CELESTIAL_GRAPHICS is not set
+
+#
+# Ubuntu Supplied Third-Party Device Drivers
+#
+# CONFIG_AUFS_FS is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT2_FS_XIP=y
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_DEFAULTS_TO_ORDERED=y
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_XATTR=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+# CONFIG_EXT4_DEBUG is not set
+CONFIG_FS_XIP=y
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_JBD2=y
+# CONFIG_JBD2_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# 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=y
+CONFIG_EXPORTFS=y
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY_USER=y
+CONFIG_FANOTIFY=y
+# CONFIG_QUOTA is not set
+# CONFIG_QUOTACTL is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+# CONFIG_OVERLAYFS_FS is not set
+CONFIG_GENERIC_ACL=y
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_TMPFS_XATTR=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_ECRYPT_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_LOGFS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX6FS_FS is not set
+# CONFIG_ROMFS_FS 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 is not set
+# CONFIG_NFSD is not set
+# CONFIG_CEPH_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+CONFIG_NLS_CODEPAGE_936=y
+# 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=y
+# CONFIG_NLS_ISO8859_1 is not set
+# 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=y
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_FRAME_WARN=2048
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_SECTION_MISMATCH is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+# CONFIG_LOCKUP_DETECTOR is not set
+# CONFIG_HARDLOCKUP_DETECTOR is not set
+# CONFIG_DETECT_HUNG_TASK is not set
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_SPARSE_RCU_POINTER is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_ATOMIC_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_STACKTRACE is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_HIGHMEM is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_TEST_LIST_SORT is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_TRACE is not set
+# CONFIG_KPROBES_SANITY_TEST is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_LKDTM is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_DEBUG_PAGEALLOC is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_HAVE_C_RECORDMCOUNT=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_DMA_API_DEBUG is not set
+# CONFIG_ATOMIC64_SELFTEST is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+# CONFIG_TEST_KSTRTOX is not set
+# CONFIG_STRICT_DEVMEM is not set
+# CONFIG_ARM_UNWIND is not set
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_RODATA is not set
+# CONFIG_DEBUG_LL is not set
+# CONFIG_ARM_KPROBES_TEST is not set
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+# CONFIG_ENCRYPTED_KEYS is not set
+# CONFIG_KEYS_DEBUG_PROC_KEYS is not set
+# CONFIG_SECURITY_DMESG_RESTRICT is not set
+# CONFIG_SECURITY is not set
+CONFIG_SECURITYFS=y
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP2=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+# CONFIG_CRYPTO_USER is not set
+CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
+# 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=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=y
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=y
+# CONFIG_CRYPTO_GHASH is not set
+CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+CONFIG_CRYPTO_ARC4=y
+# 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=y
+# 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=y
+CONFIG_CRYPTO_TWOFISH_COMMON=y
+
+#
+# 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 is not set
+# 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_GENERIC_PCI_IOMAP=y
+CONFIG_GENERIC_IO=y
+# CONFIG_CRC_CCITT is not set
+CONFIG_CRC16=y
+CONFIG_CRC_T10DIF=y
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC32_SELFTEST is not set
+CONFIG_CRC32_SLICEBY8=y
+# CONFIG_CRC32_SLICEBY4 is not set
+# CONFIG_CRC32_SARWATE is not set
+# CONFIG_CRC32_BIT is not set
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+# CONFIG_CRC8 is not set
+CONFIG_ZLIB_INFLATE=y
+# CONFIG_XZ_DEC is not set
+# CONFIG_XZ_DEC_BCJ is not set
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_DQL=y
+CONFIG_NLATTR=y
+# CONFIG_AVERAGE is not set
+# CONFIG_CORDIC is not set
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/arch/arm/configs/cnc1900_EVB_Debug_defconfig linux-linaro-3.4-2012.05-1_cavium/arch/arm/configs/cnc1900_EVB_Debug_defconfig
--- linux-linaro-3.4-2012.05-1_original/arch/arm/configs/cnc1900_EVB_Debug_defconfig	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/arch/arm/configs/cnc1900_EVB_Debug_defconfig	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,1940 @@
+#
+# Automatically generated file; DO NOT EDIT.
+# Linux/arm 3.4.0 Kernel Configuration
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+# CONFIG_ARCH_USES_GETTIMEOFFSET is not set
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_KTIME_SCALAR=y
+CONFIG_HAVE_PROC_CPU=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_ARCH_HAS_CPUFREQ=y
+CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_ZONE_DMA=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_VECTORS_BASE=0xffff0000
+# CONFIG_ARM_PATCH_PHYS_VIRT is not set
+CONFIG_PHYS_OFFSET=0x0
+CONFIG_GENERIC_BUG=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_HAVE_IRQ_WORK=y
+CONFIG_IRQ_WORK=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+# CONFIG_INIT_PASS_ALL_PARAMS is not set
+CONFIG_CROSS_COMPILE=""
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_XZ=y
+CONFIG_HAVE_KERNEL_LZO=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_XZ is not set
+# CONFIG_KERNEL_LZO is not set
+CONFIG_DEFAULT_HOSTNAME="(none)"
+CONFIG_VERSION_SIGNATURE=""
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# 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
+CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_IRQ_DOMAIN=y
+
+#
+# RCU Subsystem
+#
+CONFIG_TINY_RCU=y
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=17
+# CONFIG_CGROUPS is not set
+# CONFIG_CHECKPOINT_RESTORE is not set
+# CONFIG_NAMESPACES is not set
+# CONFIG_SCHED_AUTOGROUP is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_RELAY=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+# CONFIG_RD_XZ is not set
+# CONFIG_RD_LZO is not set
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_PANIC_TIMEOUT=0
+CONFIG_EXPERT=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL 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_SHMEM=y
+CONFIG_AIO=y
+CONFIG_EMBEDDED=y
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_PERF_EVENTS=y
+# CONFIG_PERF_COUNTERS is not set
+# CONFIG_DEBUG_PERF_USE_VMALLOC is not set
+CONFIG_VM_EVENT_COUNTERS=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+CONFIG_PROFILING=y
+CONFIG_TRACEPOINTS=y
+# CONFIG_OPROFILE is not set
+CONFIG_HAVE_OPROFILE=y
+CONFIG_KPROBES=y
+# CONFIG_JUMP_LABEL is not set
+CONFIG_KRETPROBES=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_DMA_CONTIGUOUS=y
+CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_HW_BREAKPOINT=y
+CONFIG_HAVE_ARCH_JUMP_LABEL=y
+
+#
+# GCOV-based kernel profiling
+#
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+CONFIG_MODULE_FORCE_LOAD=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+CONFIG_BLK_DEV_BSG=y
+CONFIG_BLK_DEV_BSGLIB=y
+CONFIG_BLK_DEV_INTEGRITY=y
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# 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_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=y
+
+#
+# System Type
+#
+CONFIG_MMU=y
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_VEXPRESS is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_BCMRING is not set
+# CONFIG_ARCH_HIGHBANK is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CNS3XXX is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_PRIMA2 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+CONFIG_ARCH_CELESTIAL=y
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_MXS is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_DOVE is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LPC32XX is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_TEGRA is not set
+# CONFIG_ARCH_PICOXCELL is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_SHMOBILE is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C24XX is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5P64X0 is not set
+# CONFIG_ARCH_S5PC100 is not set
+# CONFIG_ARCH_S5PV210 is not set
+# CONFIG_ARCH_EXYNOS is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_U8500 is not set
+# CONFIG_ARCH_NOMADIK is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_PLAT_SPEAR is not set
+# CONFIG_ARCH_VT8500 is not set
+# CONFIG_ARCH_ZYNQ is not set
+
+#
+# Cavium Celestial platform type
+#
+CONFIG_MACH_CELESTIAL_CNC1900=y
+CONFIG_CELESTIAL_EVB=y
+# CONFIG_CELESTIAL_HDK is not set
+# CONFIG_CELESTIAL_FJ_TX is not set
+# CONFIG_CELESTIAL_FJ_RX is not set
+
+#
+# System MMU
+#
+
+#
+# Processor Type
+#
+CONFIG_CPU_V7=y
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_32v7=y
+CONFIG_CPU_ABRT_EV7=y
+CONFIG_CPU_PABRT_V7=y
+CONFIG_CPU_CACHE_V7=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_TLB_V7=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+# CONFIG_ARM_LPAE is not set
+# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
+CONFIG_ARM_THUMB=y
+CONFIG_ARM_THUMBEE=y
+# CONFIG_SWP_EMULATE is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_MIGHT_HAVE_CACHE_L2X0=y
+# CONFIG_CACHE_L2X0 is not set
+CONFIG_ARM_L1_CACHE_SHIFT=5
+CONFIG_ARM_DMA_MEM_BUFFERABLE=y
+CONFIG_ARM_NR_BANKS=8
+CONFIG_CPU_HAS_PMU=y
+CONFIG_MULTI_IRQ_HANDLER=y
+# CONFIG_ARM_ERRATA_430973 is not set
+# CONFIG_ARM_ERRATA_458693 is not set
+# CONFIG_ARM_ERRATA_460075 is not set
+# CONFIG_ARM_ERRATA_720789 is not set
+# CONFIG_ARM_ERRATA_743622 is not set
+# CONFIG_ARM_ERRATA_751472 is not set
+CONFIG_ARM_ERRATA_754322=y
+CONFIG_ARM_GIC=y
+# CONFIG_FIQ_DEBUGGER is not set
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_HAVE_SMP=y
+# CONFIG_SMP is not set
+CONFIG_HAVE_ARM_SCU=y
+CONFIG_HAVE_ARM_TWD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_ARCH_NR_GPIO=0
+# CONFIG_PREEMPT_NONE is not set
+CONFIG_PREEMPT_VOLUNTARY=y
+# CONFIG_PREEMPT is not set
+CONFIG_HZ=100
+# CONFIG_THUMB2_KERNEL is not set
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+CONFIG_HAVE_ARCH_PFN_VALID=y
+CONFIG_HIGHMEM=y
+# CONFIG_HIGHPTE is not set
+CONFIG_HW_PERF_EVENTS=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_HAVE_MEMBLOCK=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_COMPACTION=y
+CONFIG_MIGRATION=y
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+CONFIG_KSM=y
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_NEED_PER_CPU_KM=y
+# CONFIG_CLEANCACHE is not set
+CONFIG_FORCE_MAX_ZONEORDER=11
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+# CONFIG_SECCOMP is not set
+# CONFIG_CC_STACKPROTECTOR is not set
+# CONFIG_DEPRECATED_PARAM_STRUCT is not set
+# CONFIG_ARM_FLUSH_CONSOLE_ON_RESTART is not set
+
+#
+# Boot options
+#
+# CONFIG_USE_OF is not set
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_CMDLINE=""
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+# CONFIG_CRASH_DUMP is not set
+# CONFIG_AUTO_ZRELADDR is not set
+
+#
+# CPU Power Management
+#
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_VFP=y
+CONFIG_VFPv3=y
+# CONFIG_NEON is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y
+CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_HAS_WAKELOCK is not set
+# CONFIG_WAKELOCK is not set
+# CONFIG_USER_WAKELOCK is not set
+CONFIG_PM_SLEEP=y
+CONFIG_PM_RUNTIME=y
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+# CONFIG_APM_EMULATION is not set
+CONFIG_PM_CLK=y
+CONFIG_CPU_PM=y
+# CONFIG_SUSPEND_TIME is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ARM_CPU_SUSPEND=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+# CONFIG_UNIX_DIAG is not set
+# 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_INET_UDP_DIAG is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_ANDROID_PARANOID_NETWORK is not set
+# CONFIG_NET_ACTIVITY_STATS 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_DNS_RESOLVER=y
+# CONFIG_BATMAN_ADV is not set
+# CONFIG_OPENVSWITCH is not set
+CONFIG_BQL=y
+CONFIG_HAVE_BPF_JIT=y
+# CONFIG_BPF_JIT is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NET_TCPPROBE is not set
+# CONFIG_NET_DROP_MONITOR 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
+# CONFIG_NFC is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH=""
+CONFIG_DEVTMPFS=y
+# CONFIG_DEVTMPFS_MOUNT is not set
+CONFIG_STANDALONE=y
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_GENERIC_CPU_DEVICES is not set
+CONFIG_REGMAP=y
+CONFIG_REGMAP_I2C=y
+CONFIG_REGMAP_SPI=y
+# CONFIG_DMA_SHARED_BUFFER is not set
+# CONFIG_SYNC is not set
+CONFIG_CMA=y
+# CONFIG_CMA_DEBUG is not set
+
+#
+# Default contiguous memory area size:
+#
+CONFIG_CMA_SIZE_MBYTES=16
+CONFIG_CMA_SIZE_SEL_MBYTES=y
+# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set
+# CONFIG_CMA_SIZE_SEL_MIN is not set
+# CONFIG_CMA_SIZE_SEL_MAX is not set
+CONFIG_CMA_ALIGNMENT=8
+CONFIG_CMA_AREAS=7
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+CONFIG_MTD=y
+# CONFIG_MTD_TESTS is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AFS_PARTS is not set
+# 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 is not set
+# CONFIG_MTD_JEDECPROBE 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_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_DATAFLASH is not set
+CONFIG_MTD_M25P80=y
+# CONFIG_M25PXX_USE_FAST_READ is not set
+# CONFIG_MTD_SST25L is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+# CONFIG_MTD_DOCG3 is not set
+CONFIG_MTD_NAND_IDS=y
+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_DISKONCHIP is not set
+# CONFIG_MTD_NAND_DOCG4 is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA 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_LOOP_MIN_COUNT=8
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+# CONFIG_BLK_DEV_DRBD is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+# CONFIG_BLK_DEV_XIP is not set
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+CONFIG_ATA_OVER_ETH=m
+# CONFIG_BLK_DEV_RBD is not set
+
+#
+# Misc devices
+#
+# CONFIG_SENSORS_LIS3LV02D is not set
+# CONFIG_AD525X_DPOT is not set
+# CONFIG_ATMEL_PWM is not set
+# CONFIG_ICS932S401 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_APDS9802ALS is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_ISL29020 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_SENSORS_BH1780 is not set
+# CONFIG_SENSORS_BH1770 is not set
+# CONFIG_SENSORS_APDS990X is not set
+# CONFIG_HMC6352 is not set
+# CONFIG_SENSORS_AK8975 is not set
+# CONFIG_DS1682 is not set
+# CONFIG_TI_DAC7512 is not set
+# CONFIG_UID_STAT is not set
+# CONFIG_BMP085 is not set
+# CONFIG_USB_SWITCH_FSA9480 is not set
+# CONFIG_ANDROID_PMEM is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_AT25 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_EEPROM_93XX46 is not set
+# CONFIG_IWMC3200TOP is not set
+
+#
+# Texas Instruments shared transport line discipline
+#
+# CONFIG_SENSORS_LIS3_SPI is not set
+# CONFIG_SENSORS_LIS3_I2C is not set
+
+#
+# Altera FPGA firmware download module
+#
+# CONFIG_ALTERA_STAPL is not set
+
+#
+# SCSI device support
+#
+CONFIG_SCSI_MOD=y
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+CONFIG_CHR_DEV_SG=y
+# CONFIG_CHR_DEV_SCH is not set
+CONFIG_SCSI_MULTI_LUN=y
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+# CONFIG_SCSI_LOWLEVEL is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_TARGET_CORE is not set
+CONFIG_NETDEVICES=y
+CONFIG_NET_CORE=y
+# CONFIG_BONDING is not set
+# CONFIG_DUMMY is not set
+# CONFIG_EQUALIZER is not set
+CONFIG_MII=y
+# CONFIG_NET_TEAM is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+
+#
+# CAIF transport drivers
+#
+CONFIG_ETHERNET=y
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_CALXEDA_XGMAC is not set
+# CONFIG_NET_VENDOR_CHELSIO is not set
+# CONFIG_NET_VENDOR_CIRRUS is not set
+# CONFIG_DM9000 is not set
+# CONFIG_DNET is not set
+# CONFIG_NET_VENDOR_FARADAY is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+CONFIG_NET_VENDOR_MICROCHIP=y
+# CONFIG_ENC28J60 is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_ETHOC is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_PHYLIB is not set
+# CONFIG_MICREL_KS8995MA is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_USB_IPHETH is not set
+# CONFIG_WLAN is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+# CONFIG_WAN is not set
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+CONFIG_INPUT_FF_MEMLESS=y
+# CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+# CONFIG_INPUT_KEYRESET is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ADP5588 is not set
+# CONFIG_KEYBOARD_ADP5589 is not set
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_QT1070 is not set
+# CONFIG_KEYBOARD_QT2160 is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_TCA6416 is not set
+# CONFIG_KEYBOARD_TCA8418 is not set
+# CONFIG_KEYBOARD_MAX7359 is not set
+# CONFIG_KEYBOARD_MCS is not set
+# CONFIG_KEYBOARD_MPR121 is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
+# CONFIG_KEYBOARD_SAMSUNG is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_OMAP4 is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+CONFIG_INPUT_MOUSE=y
+# CONFIG_MOUSE_PS2 is not set
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_APPLETOUCH is not set
+# CONFIG_MOUSE_BCM5974 is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_MOUSE_SYNAPTICS_I2C is not set
+# CONFIG_MOUSE_SYNAPTICS_USB 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=y
+CONFIG_SERIO_SERPORT=y
+CONFIG_SERIO_LIBPS2=y
+CONFIG_SERIO_RAW=m
+# CONFIG_SERIO_ALTERA_PS2 is not set
+# CONFIG_SERIO_PS2MULT is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_VT_CONSOLE_SLEEP=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_DEVPTS_MULTIPLE_INSTANCES=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_N_GSM is not set
+# CONFIG_TRACE_SINK is not set
+CONFIG_DEVMEM=y
+CONFIG_DEVKMEM=y
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=32
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_MANY_PORTS=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_RSA is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_MAX3100 is not set
+# CONFIG_SERIAL_MAX3107 is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
+# CONFIG_SERIAL_ALTERA_JTAGUART is not set
+# CONFIG_SERIAL_ALTERA_UART is not set
+# CONFIG_SERIAL_XILINX_PS_UART is not set
+# CONFIG_TTY_PRINTK is not set
+# CONFIG_HVC_DCC is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+# CONFIG_DCC_TTY is not set
+# CONFIG_RAMOOPS is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+# CONFIG_I2C_COMPAT is not set
+# CONFIG_I2C_CHARDEV is not set
+# CONFIG_I2C_MUX is not set
+# CONFIG_I2C_HELPER_AUTO is not set
+# CONFIG_I2C_SMBUS is not set
+
+#
+# I2C Algorithms
+#
+CONFIG_I2C_ALGOBIT=y
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_DESIGNWARE_PLATFORM is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_PXA_PCI is not set
+# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_DIOLAN_U2C is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+CONFIG_SPI=y
+# CONFIG_SPI_DEBUG is not set
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+# CONFIG_SPI_ALTERA is not set
+# CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_PXA2XX_PCI is not set
+# CONFIG_SPI_XILINX is not set
+CONFIG_SPI_DESIGNWARE=y
+CONFIG_SPI_DW_MMIO=y
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
+# CONFIG_HSI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+
+#
+# PPS generators support
+#
+
+#
+# PTP clock support
+#
+
+#
+# Enable Device Drivers -> PPS to see the PTP clock options.
+#
+# 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_CORE=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_DW_WATCHDOG is not set
+# CONFIG_MPCORE_WATCHDOG is not set
+# CONFIG_MAX63XX_WATCHDOG is not set
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+CONFIG_BCMA_POSSIBLE=y
+
+#
+# Broadcom specific AMBA
+#
+# CONFIG_BCMA is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_TPS6105X is not set
+# CONFIG_TPS6507X is not set
+# CONFIG_MFD_TPS65217 is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_TWL6040_CORE is not set
+# CONFIG_MFD_STMPE is not set
+# CONFIG_MFD_TC3589X is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_DA9052_SPI is not set
+# CONFIG_MFD_DA9052_I2C is not set
+# CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
+# CONFIG_MFD_MAX8997 is not set
+# CONFIG_MFD_MAX8998 is not set
+# CONFIG_MFD_S5M_CORE is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X_I2C is not set
+# CONFIG_MFD_WM831X_SPI is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_MC13XXX is not set
+# CONFIG_ABX500_CORE is not set
+# CONFIG_EZX_PCAP is not set
+# CONFIG_MFD_WL1273_CORE is not set
+# CONFIG_MFD_TPS65090 is not set
+# CONFIG_MFD_RC5T583 is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_DRM is not set
+# CONFIG_ION is not set
+# CONFIG_MALI400MP is not set
+# CONFIG_UMP is not set
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+CONFIG_FB_FOREIGN_ENDIAN=y
+# CONFIG_FB_BOTH_ENDIAN is not set
+# CONFIG_FB_BIG_ENDIAN is not set
+CONFIG_FB_LITTLE_ENDIAN=y
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_WMT_GE_ROPS is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_ARMHDLCD is not set
+# CONFIG_FB_UVESA is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_SMSCUFX is not set
+# CONFIG_FB_UDL is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_BROADSHEET is not set
+# CONFIG_EXYNOS_VIDEO is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+CONFIG_FB_CELESTIAL=y
+CONFIG_FB0_SIZE=0x2800000
+CONFIG_FB2_SIZE=0x1E00000
+CONFIG_FB1_SIZE=0x0
+CONFIG_FB3_SIZE=0x0
+# CONFIG_ANDROID_FB0_ONLY is not set
+
+#
+# Console display driver support
+#
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE is not set
+# CONFIG_LOGO is not set
+CONFIG_SOUND=y
+# CONFIG_SOUND_OSS_CORE is not set
+CONFIG_SND=y
+CONFIG_SND_TIMER=y
+CONFIG_SND_PCM=y
+CONFIG_SND_JACK=y
+# CONFIG_SND_SEQUENCER is not set
+# CONFIG_SND_MIXER_OSS is not set
+# CONFIG_SND_PCM_OSS is not set
+CONFIG_SND_HRTIMER=y
+CONFIG_SND_DYNAMIC_MINORS=y
+# CONFIG_SND_SUPPORT_OLD_API is not set
+# CONFIG_SND_VERBOSE_PROCFS is not set
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+# CONFIG_SND_RAWMIDI_SEQ is not set
+# CONFIG_SND_OPL3_LIB_SEQ is not set
+# CONFIG_SND_OPL4_LIB_SEQ is not set
+# CONFIG_SND_SBAWE_SEQ is not set
+# CONFIG_SND_EMU10K1_SEQ is not set
+CONFIG_SND_DRIVERS=y
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_ALOOP is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+# CONFIG_SND_ARM is not set
+# CONFIG_SND_SPI is not set
+CONFIG_SND_USB=y
+# CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_UA101 is not set
+# CONFIG_SND_USB_CAIAQ is not set
+# CONFIG_SND_USB_6FIRE is not set
+CONFIG_SND_SOC=y
+CONFIG_SND_SOC_I2C_AND_SPI=y
+# CONFIG_SND_SOC_ALL_CODECS is not set
+# CONFIG_SOUND_PRIME is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+# CONFIG_HID_PID is not set
+# CONFIG_USB_HIDDEV is not set
+
+#
+# Special HID drivers
+#
+# CONFIG_HID_A4TECH is not set
+# CONFIG_HID_ACRUX is not set
+# CONFIG_HID_APPLE is not set
+# CONFIG_HID_BELKIN is not set
+# CONFIG_HID_CHERRY is not set
+# CONFIG_HID_CHICONY is not set
+# CONFIG_HID_PRODIKEYS is not set
+# CONFIG_HID_CYPRESS is not set
+# CONFIG_HID_DRAGONRISE is not set
+# CONFIG_HID_EMS_FF is not set
+# CONFIG_HID_EZKEY is not set
+# CONFIG_HID_HOLTEK is not set
+# CONFIG_HID_KEYTOUCH is not set
+# CONFIG_HID_KYE is not set
+# CONFIG_HID_UCLOGIC is not set
+# CONFIG_HID_WALTOP is not set
+# CONFIG_HID_GYRATION is not set
+# CONFIG_HID_TWINHAN is not set
+# CONFIG_HID_KENSINGTON is not set
+# CONFIG_HID_LCPOWER is not set
+# CONFIG_HID_LOGITECH is not set
+# CONFIG_HID_MICROSOFT is not set
+# CONFIG_HID_MONTEREY is not set
+# CONFIG_HID_MULTITOUCH is not set
+# CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
+# CONFIG_HID_PANTHERLORD is not set
+# CONFIG_HID_PETALYNX is not set
+# CONFIG_HID_PICOLCD is not set
+# CONFIG_HID_PRIMAX is not set
+# CONFIG_HID_ROCCAT is not set
+# CONFIG_HID_SAITEK is not set
+# CONFIG_HID_SAMSUNG is not set
+# CONFIG_HID_SONY is not set
+# CONFIG_HID_SPEEDLINK is not set
+# CONFIG_HID_SUNPLUS is not set
+# CONFIG_HID_GREENASIA is not set
+# CONFIG_HID_SMARTJOYPLUS is not set
+# CONFIG_HID_TIVO is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_HID_THRUSTMASTER is not set
+# CONFIG_HID_ZEROPLUS is not set
+# CONFIG_HID_ZYDACRON is not set
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+# CONFIG_USB_ARCH_HAS_XHCI is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_COMMON=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEVICEFS is not set
+# CONFIG_USB_DEVICE_CLASS is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+CONFIG_USB_SUSPEND=y
+CONFIG_USB_OTG=y
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+# CONFIG_USB_DWC3 is not set
+# CONFIG_USB_MON is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+CONFIG_USB_EHCI_HCD=y
+# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+CONFIG_USB_EHCI_TT_NEWSCHED=y
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_OHCI_HCD_PLATFORM=y
+CONFIG_USB_EHCI_HCD_PLATFORM=y
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_MUSB_HDRC is not set
+# CONFIG_USB_RENESAS_USBHS is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# also be needed; see USB_STORAGE Help for more info
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_REALTEK is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_STORAGE_ENE_UB6250 is not set
+# CONFIG_USB_UAS is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_YUREX is not set
+CONFIG_USB_GADGET=y
+# CONFIG_USB_GADGET_DEBUG is not set
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+CONFIG_USB_GADGET_VBUS_DRAW=2
+CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2
+# CONFIG_USB_FUSB300 is not set
+# CONFIG_USB_R8A66597 is not set
+# CONFIG_USB_MV_UDC is not set
+# CONFIG_USB_M66592 is not set
+# CONFIG_USB_NET2272 is not set
+# CONFIG_USB_DUMMY_HCD is not set
+CONFIG_USB_GADGET_DUALSPEED=y
+# CONFIG_USB_ZERO is not set
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_ETH is not set
+# CONFIG_USB_G_NCM is not set
+# CONFIG_USB_GADGETFS is not set
+# CONFIG_USB_FUNCTIONFS is not set
+# CONFIG_USB_FILE_STORAGE is not set
+CONFIG_USB_MASS_STORAGE=m
+# CONFIG_USB_G_SERIAL is not set
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+# CONFIG_USB_CDC_COMPOSITE is not set
+# CONFIG_USB_G_ACM_MS is not set
+# CONFIG_USB_G_MULTI is not set
+CONFIG_USB_G_HID=m
+# CONFIG_USB_G_HID_MCU is not set
+# CONFIG_USB_G_HID_MULTITOUCH is not set
+# CONFIG_USB_G_DBGP is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_USB_ULPI is not set
+# CONFIG_NOP_USB_XCEIV is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+CONFIG_MMC_CLKGATE=y
+CONFIG_MMC_EMBEDDED_SDIO=y
+# CONFIG_MMC_PARANOID_SD_INIT is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_MINORS=8
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_MMC_BLOCK_DEFERRED_RESUME is not set
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+# CONFIG_MMC_SDHCI is not set
+# CONFIG_MMC_SDHCI_PXAV3 is not set
+# CONFIG_MMC_SDHCI_PXAV2 is not set
+CONFIG_MMC_DW=y
+CONFIG_MMC_DW_IDMAC=y
+CONFIG_MMC_DW_PLTFM=y
+# CONFIG_MMC_VUB300 is not set
+# CONFIG_MMC_USHC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_SWITCH is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# Virtio drivers
+#
+# CONFIG_VIRTIO_BALLOON is not set
+# CONFIG_VIRTIO_MMIO is not set
+
+#
+# Microsoft Hyper-V guest support
+#
+# CONFIG_STAGING is not set
+CONFIG_CLKDEV_LOOKUP=y
+CONFIG_HAVE_CLK_PREPARE=y
+CONFIG_COMMON_CLK=y
+
+#
+# Common Clock Framework
+#
+# CONFIG_COMMON_CLK_DISABLE_UNUSED is not set
+# CONFIG_COMMON_CLK_DEBUG is not set
+
+#
+# Hardware Spinlock drivers
+#
+CONFIG_CLKSRC_MMIO=y
+# CONFIG_IOMMU_SUPPORT is not set
+
+#
+# Remoteproc drivers (EXPERIMENTAL)
+#
+
+#
+# Rpmsg drivers (EXPERIMENTAL)
+#
+# CONFIG_VIRT_DRIVERS is not set
+# CONFIG_PM_DEVFREQ is not set
+# CONFIG_GATOR is not set
+
+#
+# Celestial Device Drivers
+#
+
+#
+# Celestial DF Drivers
+#
+CONFIG_CELESTIAL_DF=y
+# CONFIG_HD2SD_ENABLE is not set
+# CONFIG_CELESTIAL_DF_DEBUG is not set
+
+#
+# Celestial Xport Drivers
+#
+# CONFIG_CELESTIAL_XPORT is not set
+
+#
+# Celestial Video Drivers
+#
+CONFIG_CELESTIAL_VIDEO=y
+CONFIG_VIDEO_DECODER=y
+CONFIG_VIDEO_ENCODER=y
+CONFIG_VIDEO_NUM=1
+CONFIG_VIDEO_CPB_SIZE=0xc00000
+CONFIG_VIDEO_ENC_NUM=1
+CONFIG_VIDEO_ENC_CPB_SIZE=0x400000
+# CONFIG_CELESTIAL_VIDEO_DEBUG is not set
+
+#
+# Celestial Audio Drivers
+#
+CONFIG_CELESTIAL_AUDIO=y
+CONFIG_AUDIO_DECODER=y
+CONFIG_AUDIO_ENCODER=y
+CONFIG_AUDIO_NUM=1
+CONFIG_AUDIO_CAB_SIZE=0x200000
+CONFIG_AUDIO_ENC_NUM=2
+CONFIG_AUDIO_ENC_CAB_SIZE=0x18000
+# CONFIG_CELESTIAL_AUDIO_DEBUG is not set
+# CONFIG_AUDIO_FW_DUMP_DEBUG is not set
+
+#
+# Celestial Peripheral Devices
+#
+CONFIG_CELESTIAL_NAND=y
+CONFIG_CELESTIAL_ETH=y
+# CONFIG_CELESTIAL_MULT_ETH is not set
+CONFIG_CELESTIAL_SPI=y
+CONFIG_CELESTIAL_MMC=y
+# CONFIG_CELESTIAL_MULT_MMC is not set
+# CONFIG_CELESTIAL_8BIT_MMC is not set
+CONFIG_CELESTIAL_HCI=y
+CONFIG_CELESTIAL_OTG=y
+CONFIG_CELESTIAL_I2C=y
+# CONFIG_CELESTIAL_SCI is not set
+CONFIG_CELESTIAL_GPIO=y
+CONFIG_CELESTIAL_FPC=y
+# CONFIG_CELESTIAL_WDT is not set
+# CONFIG_CELESTIAL_SEC is not set
+# CONFIG_VGA_SWITCHER_SUPPORT is not set
+
+#
+# Celestial Graphics driver
+#
+# CONFIG_CELESTIAL_GRAPHICS is not set
+
+#
+# Ubuntu Supplied Third-Party Device Drivers
+#
+# CONFIG_AUFS_FS is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT2_FS_XIP=y
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_FS_XIP=y
+CONFIG_FS_MBCACHE=y
+# 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=y
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY_USER=y
+CONFIG_FANOTIFY=y
+# CONFIG_QUOTA is not set
+# CONFIG_QUOTACTL is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+# CONFIG_OVERLAYFS_FS is not set
+CONFIG_GENERIC_ACL=y
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_TMPFS_XATTR=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_ECRYPT_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_YAFFS_FS=y
+# CONFIG_YAFFS_DEBUG is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+CONFIG_JFFS2_FS_WBUF_VERIFY=y
+CONFIG_JFFS2_SUMMARY=y
+# 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 is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX6FS_FS is not set
+# CONFIG_ROMFS_FS 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=y
+# CONFIG_NFS_V4 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_ACL_SUPPORT=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_DEBUG is not set
+# CONFIG_CEPH_FS is not set
+CONFIG_CIFS=y
+# CONFIG_CIFS_STATS is not set
+# CONFIG_CIFS_WEAK_PW_HASH is not set
+# CONFIG_CIFS_UPCALL is not set
+# CONFIG_CIFS_XATTR is not set
+# CONFIG_CIFS_DEBUG2 is not set
+# CONFIG_CIFS_DFS_UPCALL is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+CONFIG_NLS_CODEPAGE_936=y
+# 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=y
+# CONFIG_NLS_ISO8859_1 is not set
+# 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=y
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_FRAME_WARN=2048
+# 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=y
+# CONFIG_DEBUG_SHIRQ is not set
+# CONFIG_LOCKUP_DETECTOR is not set
+# CONFIG_HARDLOCKUP_DETECTOR is not set
+# CONFIG_DETECT_HUNG_TASK is not set
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_SPARSE_RCU_POINTER is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_ATOMIC_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_STACKTRACE is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_HIGHMEM is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_TEST_LIST_SORT is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_TRACE is not set
+# CONFIG_KPROBES_SANITY_TEST is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_DEBUG_PAGEALLOC is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_HAVE_C_RECORDMCOUNT=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
+# CONFIG_ATOMIC64_SELFTEST is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+# CONFIG_TEST_KSTRTOX is not set
+# CONFIG_STRICT_DEVMEM is not set
+# CONFIG_ARM_UNWIND is not set
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_RODATA is not set
+# CONFIG_DEBUG_LL is not set
+# CONFIG_ARM_KPROBES_TEST is not set
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+# CONFIG_ENCRYPTED_KEYS is not set
+# CONFIG_KEYS_DEBUG_PROC_KEYS is not set
+# CONFIG_SECURITY_DMESG_RESTRICT is not set
+# CONFIG_SECURITY is not set
+CONFIG_SECURITYFS=y
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP2=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+# CONFIG_CRYPTO_USER is not set
+CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
+# 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=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=y
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=y
+# CONFIG_CRYPTO_GHASH is not set
+CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+CONFIG_CRYPTO_ARC4=y
+# 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=y
+# 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 is not set
+# 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_GENERIC_PCI_IOMAP=y
+CONFIG_GENERIC_IO=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+CONFIG_CRC_T10DIF=y
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC32_SELFTEST is not set
+CONFIG_CRC32_SLICEBY8=y
+# CONFIG_CRC32_SLICEBY4 is not set
+# CONFIG_CRC32_SARWATE is not set
+# CONFIG_CRC32_BIT is not set
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+# CONFIG_CRC8 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_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_DQL=y
+CONFIG_NLATTR=y
+# CONFIG_AVERAGE is not set
+# CONFIG_CORDIC is not set
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/arch/arm/configs/cnc1900_SMP_defconfig linux-linaro-3.4-2012.05-1_cavium/arch/arm/configs/cnc1900_SMP_defconfig
--- linux-linaro-3.4-2012.05-1_original/arch/arm/configs/cnc1900_SMP_defconfig	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/arch/arm/configs/cnc1900_SMP_defconfig	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,1989 @@
+#
+# Automatically generated file; DO NOT EDIT.
+# Linux/arm 3.4.0 Kernel Configuration
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+# CONFIG_ARCH_USES_GETTIMEOFFSET is not set
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
+CONFIG_KTIME_SCALAR=y
+CONFIG_HAVE_PROC_CPU=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_ARCH_HAS_CPUFREQ=y
+CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_ZONE_DMA=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_VECTORS_BASE=0xffff0000
+# CONFIG_ARM_PATCH_PHYS_VIRT is not set
+CONFIG_PHYS_OFFSET=0x0
+CONFIG_GENERIC_BUG=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_HAVE_IRQ_WORK=y
+CONFIG_IRQ_WORK=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+# CONFIG_INIT_PASS_ALL_PARAMS is not set
+CONFIG_CROSS_COMPILE=""
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_XZ=y
+CONFIG_HAVE_KERNEL_LZO=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_XZ is not set
+# CONFIG_KERNEL_LZO is not set
+CONFIG_DEFAULT_HOSTNAME="(none)"
+CONFIG_VERSION_SIGNATURE=""
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# 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
+CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_IRQ_DOMAIN=y
+# CONFIG_IRQ_DOMAIN_DEBUG is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_PREEMPT_RCU is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_RCU_FAST_NO_HZ is not set
+# CONFIG_TREE_RCU_TRACE is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=17
+# CONFIG_CGROUPS is not set
+# CONFIG_CHECKPOINT_RESTORE is not set
+# CONFIG_NAMESPACES is not set
+# CONFIG_SCHED_AUTOGROUP is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_RELAY=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+# CONFIG_RD_XZ is not set
+# CONFIG_RD_LZO is not set
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_PANIC_TIMEOUT=0
+CONFIG_EXPERT=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL 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_SHMEM=y
+CONFIG_AIO=y
+CONFIG_EMBEDDED=y
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_PERF_EVENTS=y
+# CONFIG_PERF_COUNTERS is not set
+# CONFIG_DEBUG_PERF_USE_VMALLOC is not set
+CONFIG_VM_EVENT_COUNTERS=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+CONFIG_PROFILING=y
+CONFIG_TRACEPOINTS=y
+# CONFIG_OPROFILE is not set
+CONFIG_HAVE_OPROFILE=y
+CONFIG_KPROBES=y
+# CONFIG_JUMP_LABEL is not set
+CONFIG_KRETPROBES=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_DMA_CONTIGUOUS=y
+CONFIG_USE_GENERIC_SMP_HELPERS=y
+CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_HW_BREAKPOINT=y
+CONFIG_HAVE_ARCH_JUMP_LABEL=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+CONFIG_MODULE_FORCE_LOAD=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_STOP_MACHINE=y
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+CONFIG_BLK_DEV_BSG=y
+CONFIG_BLK_DEV_BSGLIB=y
+CONFIG_BLK_DEV_INTEGRITY=y
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# 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_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=y
+CONFIG_FREEZER=y
+
+#
+# System Type
+#
+CONFIG_MMU=y
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_VEXPRESS is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_BCMRING is not set
+# CONFIG_ARCH_HIGHBANK is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CNS3XXX is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_PRIMA2 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+CONFIG_ARCH_CELESTIAL=y
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_MXS is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_DOVE is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LPC32XX is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_TEGRA is not set
+# CONFIG_ARCH_PICOXCELL is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_SHMOBILE is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C24XX is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5P64X0 is not set
+# CONFIG_ARCH_S5PC100 is not set
+# CONFIG_ARCH_S5PV210 is not set
+# CONFIG_ARCH_EXYNOS is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_U8500 is not set
+# CONFIG_ARCH_NOMADIK is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_PLAT_SPEAR is not set
+# CONFIG_ARCH_VT8500 is not set
+# CONFIG_ARCH_ZYNQ is not set
+
+#
+# Cavium Celestial platform type
+#
+CONFIG_MACH_CELESTIAL_CNC1900=y
+CONFIG_PUREVU=y
+CONFIG_CELESTIAL_EVB=y
+# CONFIG_CELESTIAL_HDK is not set
+# CONFIG_CELESTIAL_FJ_TX is not set
+# CONFIG_CELESTIAL_FJ_RX is not set
+# CONFIG_CELESTIAL_OTT_EMMC is not set
+
+#
+# System MMU
+#
+
+#
+# Processor Type
+#
+CONFIG_CPU_V7=y
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_32v7=y
+CONFIG_CPU_ABRT_EV7=y
+CONFIG_CPU_PABRT_V7=y
+CONFIG_CPU_CACHE_V7=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_TLB_V7=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+# CONFIG_ARM_LPAE is not set
+# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
+CONFIG_ARM_THUMB=y
+CONFIG_ARM_THUMBEE=y
+# CONFIG_SWP_EMULATE is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_MIGHT_HAVE_CACHE_L2X0=y
+# CONFIG_CACHE_L2X0 is not set
+CONFIG_ARM_L1_CACHE_SHIFT=5
+CONFIG_ARM_DMA_MEM_BUFFERABLE=y
+CONFIG_ARM_NR_BANKS=8
+CONFIG_CPU_HAS_PMU=y
+CONFIG_MULTI_IRQ_HANDLER=y
+# CONFIG_ARM_ERRATA_430973 is not set
+# CONFIG_ARM_ERRATA_458693 is not set
+# CONFIG_ARM_ERRATA_460075 is not set
+# CONFIG_ARM_ERRATA_742230 is not set
+# CONFIG_ARM_ERRATA_742231 is not set
+# CONFIG_ARM_ERRATA_720789 is not set
+# CONFIG_ARM_ERRATA_743622 is not set
+# CONFIG_ARM_ERRATA_751472 is not set
+CONFIG_ARM_ERRATA_754322=y
+# CONFIG_ARM_ERRATA_754327 is not set
+# CONFIG_ARM_ERRATA_764369 is not set
+CONFIG_SW_SUPPORT=y
+CONFIG_ARM_GIC=y
+# CONFIG_FIQ_DEBUGGER is not set
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_HAVE_SMP=y
+CONFIG_SMP=y
+CONFIG_SMP_ON_UP=y
+CONFIG_ARM_CPU_TOPOLOGY=y
+# CONFIG_SCHED_MC is not set
+# CONFIG_SCHED_SMT is not set
+CONFIG_HAVE_ARM_SCU=y
+CONFIG_HAVE_ARM_TWD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_NR_CPUS=2
+CONFIG_HOTPLUG_CPU=y
+CONFIG_LOCAL_TIMERS=y
+CONFIG_ARCH_NR_GPIO=0
+# CONFIG_PREEMPT_NONE is not set
+CONFIG_PREEMPT_VOLUNTARY=y
+# CONFIG_PREEMPT is not set
+CONFIG_HZ=100
+# CONFIG_THUMB2_KERNEL is not set
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+CONFIG_HAVE_ARCH_PFN_VALID=y
+CONFIG_HIGHMEM=y
+# CONFIG_HIGHPTE is not set
+CONFIG_HW_PERF_EVENTS=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_HAVE_MEMBLOCK=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_COMPACTION=y
+CONFIG_MIGRATION=y
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+CONFIG_KSM=y
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+# CONFIG_CLEANCACHE is not set
+CONFIG_FORCE_MAX_ZONEORDER=11
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+# CONFIG_SECCOMP is not set
+# CONFIG_CC_STACKPROTECTOR is not set
+# CONFIG_DEPRECATED_PARAM_STRUCT is not set
+# CONFIG_ARM_FLUSH_CONSOLE_ON_RESTART is not set
+
+#
+# Boot options
+#
+# CONFIG_USE_OF is not set
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_CMDLINE=""
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+# CONFIG_CRASH_DUMP is not set
+# CONFIG_AUTO_ZRELADDR is not set
+
+#
+# CPU Power Management
+#
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_VFP=y
+CONFIG_VFPv3=y
+# CONFIG_NEON is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y
+CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_HAS_WAKELOCK is not set
+# CONFIG_WAKELOCK is not set
+# CONFIG_USER_WAKELOCK is not set
+CONFIG_PM_SLEEP=y
+CONFIG_PM_SLEEP_SMP=y
+CONFIG_PM_RUNTIME=y
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+# CONFIG_APM_EMULATION is not set
+CONFIG_PM_CLK=y
+CONFIG_CPU_PM=y
+# CONFIG_SUSPEND_TIME is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ARM_CPU_SUSPEND=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+# CONFIG_UNIX_DIAG is not set
+# 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_INET_UDP_DIAG is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_ANDROID_PARANOID_NETWORK is not set
+# CONFIG_NET_ACTIVITY_STATS 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_DNS_RESOLVER=y
+# CONFIG_BATMAN_ADV is not set
+# CONFIG_OPENVSWITCH is not set
+CONFIG_RPS=y
+CONFIG_RFS_ACCEL=y
+CONFIG_XPS=y
+CONFIG_BQL=y
+CONFIG_HAVE_BPF_JIT=y
+# CONFIG_BPF_JIT is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NET_TCPPROBE is not set
+# CONFIG_NET_DROP_MONITOR 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_WIRELESS_EXT=y
+CONFIG_WEXT_CORE=y
+CONFIG_WEXT_PROC=y
+CONFIG_WEXT_SPY=y
+CONFIG_WEXT_PRIV=y
+CONFIG_CFG80211=m
+# CONFIG_NL80211_TESTMODE is not set
+# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set
+# CONFIG_CFG80211_REG_DEBUG is not set
+CONFIG_CFG80211_DEFAULT_PS=y
+# CONFIG_CFG80211_DEBUGFS is not set
+# CONFIG_CFG80211_INTERNAL_REGDB is not set
+CONFIG_CFG80211_WEXT=y
+# CONFIG_WIRELESS_EXT_SYSFS is not set
+CONFIG_LIB80211=y
+CONFIG_LIB80211_CRYPT_WEP=y
+CONFIG_LIB80211_CRYPT_CCMP=y
+CONFIG_LIB80211_CRYPT_TKIP=y
+# CONFIG_LIB80211_DEBUG is not set
+# CONFIG_CFG80211_ALLOW_RECONNECT is not set
+# CONFIG_MAC80211 is not set
+# 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
+# CONFIG_NFC is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH=""
+CONFIG_DEVTMPFS=y
+# CONFIG_DEVTMPFS_MOUNT is not set
+CONFIG_STANDALONE=y
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_GENERIC_CPU_DEVICES is not set
+CONFIG_REGMAP=y
+CONFIG_REGMAP_I2C=y
+# CONFIG_DMA_SHARED_BUFFER is not set
+# CONFIG_SYNC is not set
+CONFIG_CMA=y
+# CONFIG_CMA_DEBUG is not set
+
+#
+# Default contiguous memory area size:
+#
+CONFIG_CMA_SIZE_MBYTES=16
+CONFIG_CMA_SIZE_SEL_MBYTES=y
+# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set
+# CONFIG_CMA_SIZE_SEL_MIN is not set
+# CONFIG_CMA_SIZE_SEL_MAX is not set
+CONFIG_CMA_ALIGNMENT=8
+CONFIG_CMA_AREAS=7
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+CONFIG_MTD=y
+# CONFIG_MTD_TESTS is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AFS_PARTS is not set
+# 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 is not set
+# CONFIG_MTD_JEDECPROBE 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_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+# CONFIG_MTD_DOCG3 is not set
+CONFIG_MTD_NAND_IDS=y
+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_DISKONCHIP is not set
+# CONFIG_MTD_NAND_DOCG4 is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA 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_LOOP_MIN_COUNT=8
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+# CONFIG_BLK_DEV_DRBD is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=65536
+# CONFIG_BLK_DEV_XIP is not set
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+CONFIG_ATA_OVER_ETH=m
+# CONFIG_BLK_DEV_RBD is not set
+
+#
+# Misc devices
+#
+# CONFIG_SENSORS_LIS3LV02D is not set
+# CONFIG_AD525X_DPOT is not set
+# CONFIG_ATMEL_PWM is not set
+# CONFIG_ICS932S401 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_APDS9802ALS is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_ISL29020 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_SENSORS_BH1780 is not set
+# CONFIG_SENSORS_BH1770 is not set
+# CONFIG_SENSORS_APDS990X is not set
+# CONFIG_HMC6352 is not set
+# CONFIG_SENSORS_AK8975 is not set
+# CONFIG_DS1682 is not set
+# CONFIG_UID_STAT is not set
+# CONFIG_BMP085 is not set
+# CONFIG_USB_SWITCH_FSA9480 is not set
+# CONFIG_ANDROID_PMEM is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_IWMC3200TOP is not set
+
+#
+# Texas Instruments shared transport line discipline
+#
+# CONFIG_SENSORS_LIS3_I2C is not set
+
+#
+# Altera FPGA firmware download module
+#
+# CONFIG_ALTERA_STAPL is not set
+
+#
+# SCSI device support
+#
+CONFIG_SCSI_MOD=y
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+CONFIG_CHR_DEV_SG=y
+# CONFIG_CHR_DEV_SCH is not set
+CONFIG_SCSI_MULTI_LUN=y
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+# CONFIG_SCSI_LOWLEVEL is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_TARGET_CORE is not set
+CONFIG_NETDEVICES=y
+CONFIG_NET_CORE=y
+# CONFIG_BONDING is not set
+# CONFIG_DUMMY is not set
+# CONFIG_EQUALIZER is not set
+CONFIG_MII=y
+# CONFIG_NET_TEAM is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+
+#
+# CAIF transport drivers
+#
+CONFIG_ETHERNET=y
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_CALXEDA_XGMAC is not set
+# CONFIG_NET_VENDOR_CHELSIO is not set
+# CONFIG_NET_VENDOR_CIRRUS is not set
+# CONFIG_DM9000 is not set
+# CONFIG_DNET is not set
+# CONFIG_NET_VENDOR_FARADAY is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_ETHOC is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_PHYLIB is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_USB_IPHETH is not set
+CONFIG_WLAN=y
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_USB_NET_RNDIS_WLAN is not set
+# CONFIG_WIFI_CONTROL_FUNC is not set
+# CONFIG_ATH_COMMON is not set
+# CONFIG_BCMDHD is not set
+# CONFIG_BRCMFMAC is not set
+CONFIG_HOSTAP=y
+# CONFIG_HOSTAP_FIRMWARE is not set
+# CONFIG_IWM is not set
+# CONFIG_LIBERTAS is not set
+# CONFIG_MWIFIEX is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+# CONFIG_WAN is not set
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+CONFIG_INPUT_FF_MEMLESS=y
+# CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+# CONFIG_INPUT_KEYRESET is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ADP5588 is not set
+# CONFIG_KEYBOARD_ADP5589 is not set
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_QT1070 is not set
+# CONFIG_KEYBOARD_QT2160 is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_TCA6416 is not set
+# CONFIG_KEYBOARD_TCA8418 is not set
+# CONFIG_KEYBOARD_MAX7359 is not set
+# CONFIG_KEYBOARD_MCS is not set
+# CONFIG_KEYBOARD_MPR121 is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
+# CONFIG_KEYBOARD_SAMSUNG is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_OMAP4 is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+CONFIG_INPUT_MOUSE=y
+# CONFIG_MOUSE_PS2 is not set
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_APPLETOUCH is not set
+# CONFIG_MOUSE_BCM5974 is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_MOUSE_SYNAPTICS_I2C is not set
+# CONFIG_MOUSE_SYNAPTICS_USB 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=y
+CONFIG_SERIO_SERPORT=y
+CONFIG_SERIO_LIBPS2=y
+CONFIG_SERIO_RAW=m
+# CONFIG_SERIO_ALTERA_PS2 is not set
+# CONFIG_SERIO_PS2MULT is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_VT_CONSOLE_SLEEP=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_DEVPTS_MULTIPLE_INSTANCES=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_N_GSM is not set
+# CONFIG_TRACE_SINK is not set
+CONFIG_DEVMEM=y
+CONFIG_DEVKMEM=y
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=32
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_MANY_PORTS=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_RSA is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
+# CONFIG_SERIAL_ALTERA_JTAGUART is not set
+# CONFIG_SERIAL_ALTERA_UART is not set
+# CONFIG_SERIAL_XILINX_PS_UART is not set
+# CONFIG_TTY_PRINTK is not set
+# CONFIG_HVC_DCC is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+# CONFIG_DCC_TTY is not set
+# CONFIG_RAMOOPS is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+# CONFIG_I2C_COMPAT is not set
+# CONFIG_I2C_CHARDEV is not set
+# CONFIG_I2C_MUX is not set
+# CONFIG_I2C_HELPER_AUTO is not set
+# CONFIG_I2C_SMBUS is not set
+
+#
+# I2C Algorithms
+#
+CONFIG_I2C_ALGOBIT=y
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_DESIGNWARE_PLATFORM is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_PXA_PCI is not set
+# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_DIOLAN_U2C is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_SPI is not set
+# CONFIG_HSI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+
+#
+# PPS generators support
+#
+
+#
+# PTP clock support
+#
+
+#
+# Enable Device Drivers -> PPS to see the PTP clock options.
+#
+# 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_CORE=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_DW_WATCHDOG is not set
+# CONFIG_MPCORE_WATCHDOG is not set
+# CONFIG_MAX63XX_WATCHDOG is not set
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+CONFIG_BCMA_POSSIBLE=y
+
+#
+# Broadcom specific AMBA
+#
+# CONFIG_BCMA is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_TPS6105X is not set
+# CONFIG_TPS6507X is not set
+# CONFIG_MFD_TPS65217 is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_TWL6040_CORE is not set
+# CONFIG_MFD_STMPE is not set
+# CONFIG_MFD_TC3589X is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_DA9052_I2C is not set
+# CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
+# CONFIG_MFD_MAX8997 is not set
+# CONFIG_MFD_MAX8998 is not set
+# CONFIG_MFD_S5M_CORE is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X_I2C is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_ABX500_CORE is not set
+# CONFIG_MFD_WL1273_CORE is not set
+# CONFIG_MFD_TPS65090 is not set
+# CONFIG_MFD_RC5T583 is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_DRM is not set
+# CONFIG_ION is not set
+# CONFIG_MALI400MP is not set
+# CONFIG_UMP is not set
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+CONFIG_FB_FOREIGN_ENDIAN=y
+# CONFIG_FB_BOTH_ENDIAN is not set
+# CONFIG_FB_BIG_ENDIAN is not set
+CONFIG_FB_LITTLE_ENDIAN=y
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_WMT_GE_ROPS is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_ARMHDLCD is not set
+# CONFIG_FB_UVESA is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_SMSCUFX is not set
+# CONFIG_FB_UDL is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_BROADSHEET is not set
+# CONFIG_EXYNOS_VIDEO is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+CONFIG_FB_CELESTIAL=y
+CONFIG_FB0_SIZE=0x1000000
+CONFIG_FB2_SIZE=0x800000
+CONFIG_FB1_SIZE=0x0
+CONFIG_FB3_SIZE=0x0
+# CONFIG_ANDROID_FB0_ONLY is not set
+
+#
+# Console display driver support
+#
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE is not set
+# CONFIG_LOGO is not set
+CONFIG_SOUND=y
+# CONFIG_SOUND_OSS_CORE is not set
+CONFIG_SND=y
+CONFIG_SND_TIMER=y
+CONFIG_SND_PCM=y
+CONFIG_SND_JACK=y
+# CONFIG_SND_SEQUENCER is not set
+# CONFIG_SND_MIXER_OSS is not set
+# CONFIG_SND_PCM_OSS is not set
+CONFIG_SND_HRTIMER=y
+CONFIG_SND_DYNAMIC_MINORS=y
+# CONFIG_SND_SUPPORT_OLD_API is not set
+# CONFIG_SND_VERBOSE_PROCFS is not set
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+# CONFIG_SND_RAWMIDI_SEQ is not set
+# CONFIG_SND_OPL3_LIB_SEQ is not set
+# CONFIG_SND_OPL4_LIB_SEQ is not set
+# CONFIG_SND_SBAWE_SEQ is not set
+# CONFIG_SND_EMU10K1_SEQ is not set
+CONFIG_SND_DRIVERS=y
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_ALOOP is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+# CONFIG_SND_ARM is not set
+CONFIG_SND_USB=y
+# CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_UA101 is not set
+# CONFIG_SND_USB_CAIAQ is not set
+# CONFIG_SND_USB_6FIRE is not set
+CONFIG_SND_SOC=y
+CONFIG_SND_SOC_I2C_AND_SPI=y
+# CONFIG_SND_SOC_ALL_CODECS is not set
+# CONFIG_SOUND_PRIME is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+# CONFIG_HID_PID is not set
+# CONFIG_USB_HIDDEV is not set
+
+#
+# Special HID drivers
+#
+# CONFIG_HID_A4TECH is not set
+# CONFIG_HID_ACRUX is not set
+# CONFIG_HID_APPLE is not set
+# CONFIG_HID_BELKIN is not set
+# CONFIG_HID_CHERRY is not set
+# CONFIG_HID_CHICONY is not set
+# CONFIG_HID_PRODIKEYS is not set
+# CONFIG_HID_CYPRESS is not set
+# CONFIG_HID_DRAGONRISE is not set
+# CONFIG_HID_EMS_FF is not set
+# CONFIG_HID_EZKEY is not set
+# CONFIG_HID_HOLTEK is not set
+# CONFIG_HID_KEYTOUCH is not set
+# CONFIG_HID_KYE is not set
+# CONFIG_HID_UCLOGIC is not set
+# CONFIG_HID_WALTOP is not set
+# CONFIG_HID_GYRATION is not set
+# CONFIG_HID_TWINHAN is not set
+# CONFIG_HID_KENSINGTON is not set
+# CONFIG_HID_LCPOWER is not set
+# CONFIG_HID_LOGITECH is not set
+# CONFIG_HID_MICROSOFT is not set
+# CONFIG_HID_MONTEREY is not set
+# CONFIG_HID_MULTITOUCH is not set
+# CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
+# CONFIG_HID_PANTHERLORD is not set
+# CONFIG_HID_PETALYNX is not set
+# CONFIG_HID_PICOLCD is not set
+# CONFIG_HID_PRIMAX is not set
+# CONFIG_HID_ROCCAT is not set
+# CONFIG_HID_SAITEK is not set
+# CONFIG_HID_SAMSUNG is not set
+# CONFIG_HID_SONY is not set
+# CONFIG_HID_SPEEDLINK is not set
+# CONFIG_HID_SUNPLUS is not set
+# CONFIG_HID_GREENASIA is not set
+# CONFIG_HID_SMARTJOYPLUS is not set
+# CONFIG_HID_TIVO is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_HID_THRUSTMASTER is not set
+# CONFIG_HID_ZEROPLUS is not set
+# CONFIG_HID_ZYDACRON is not set
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+# CONFIG_USB_ARCH_HAS_XHCI is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_COMMON=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEVICEFS is not set
+# CONFIG_USB_DEVICE_CLASS is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+CONFIG_USB_SUSPEND=y
+CONFIG_USB_OTG=y
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+# CONFIG_USB_DWC3 is not set
+# CONFIG_USB_MON is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+CONFIG_USB_EHCI_HCD=y
+# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+CONFIG_USB_EHCI_TT_NEWSCHED=y
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_OHCI_HCD_PLATFORM=y
+CONFIG_USB_EHCI_HCD_PLATFORM=y
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_MUSB_HDRC is not set
+# CONFIG_USB_RENESAS_USBHS is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# also be needed; see USB_STORAGE Help for more info
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_REALTEK is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_STORAGE_ENE_UB6250 is not set
+# CONFIG_USB_UAS is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_YUREX is not set
+CONFIG_USB_GADGET=y
+# CONFIG_USB_GADGET_DEBUG is not set
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+# CONFIG_USB_GADGET_DEBUG_FS is not set
+CONFIG_USB_GADGET_VBUS_DRAW=2
+CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2
+# CONFIG_USB_FUSB300 is not set
+# CONFIG_USB_R8A66597 is not set
+# CONFIG_USB_MV_UDC is not set
+# CONFIG_USB_M66592 is not set
+# CONFIG_USB_NET2272 is not set
+# CONFIG_USB_DUMMY_HCD is not set
+CONFIG_USB_GADGET_DUALSPEED=y
+# CONFIG_USB_ZERO is not set
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_ETH is not set
+# CONFIG_USB_G_NCM is not set
+# CONFIG_USB_GADGETFS is not set
+# CONFIG_USB_FUNCTIONFS is not set
+# CONFIG_USB_FILE_STORAGE is not set
+CONFIG_USB_MASS_STORAGE=m
+# CONFIG_USB_G_SERIAL is not set
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+# CONFIG_USB_CDC_COMPOSITE is not set
+# CONFIG_USB_G_ACM_MS is not set
+# CONFIG_USB_G_MULTI is not set
+CONFIG_USB_G_HID=m
+# CONFIG_USB_G_HID_KEYBOARD is not set
+# CONFIG_USB_G_HID_MOUSE is not set
+# CONFIG_USB_G_HID_JOYSTICK is not set
+# CONFIG_USB_G_HID_MCU is not set
+# CONFIG_USB_G_HID_MULTITOUCH is not set
+# CONFIG_USB_G_DBGP is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_USB_ULPI is not set
+# CONFIG_NOP_USB_XCEIV is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+CONFIG_MMC_CLKGATE=y
+CONFIG_MMC_EMBEDDED_SDIO=y
+# CONFIG_MMC_PARANOID_SD_INIT is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_MINORS=8
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_MMC_BLOCK_DEFERRED_RESUME is not set
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+# CONFIG_MMC_SDHCI is not set
+# CONFIG_MMC_SDHCI_PXAV3 is not set
+# CONFIG_MMC_SDHCI_PXAV2 is not set
+CONFIG_MMC_DW=y
+CONFIG_MMC_DW_IDMAC=y
+CONFIG_MMC_DW_PLTFM=y
+# CONFIG_MMC_VUB300 is not set
+# CONFIG_MMC_USHC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_SWITCH is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# Virtio drivers
+#
+# CONFIG_VIRTIO_BALLOON is not set
+# CONFIG_VIRTIO_MMIO is not set
+
+#
+# Microsoft Hyper-V guest support
+#
+# CONFIG_STAGING is not set
+CONFIG_CLKDEV_LOOKUP=y
+CONFIG_HAVE_CLK_PREPARE=y
+CONFIG_COMMON_CLK=y
+
+#
+# Common Clock Framework
+#
+# CONFIG_COMMON_CLK_DISABLE_UNUSED is not set
+# CONFIG_COMMON_CLK_DEBUG is not set
+
+#
+# Hardware Spinlock drivers
+#
+CONFIG_CLKSRC_MMIO=y
+# CONFIG_IOMMU_SUPPORT is not set
+
+#
+# Remoteproc drivers (EXPERIMENTAL)
+#
+
+#
+# Rpmsg drivers (EXPERIMENTAL)
+#
+# CONFIG_VIRT_DRIVERS is not set
+# CONFIG_PM_DEVFREQ is not set
+# CONFIG_GATOR is not set
+
+#
+# Celestial Device Drivers
+#
+
+#
+# Celestial DF Drivers
+#
+CONFIG_CELESTIAL_DF=y
+CONFIG_HD2SD_ENABLE=y
+# CONFIG_YPBPR_DAC_ENABLE is not set
+# CONFIG_CELESTIAL_DF_DEBUG is not set
+
+#
+# Celestial Xport Drivers
+#
+# CONFIG_CELESTIAL_XPORT is not set
+
+#
+# Celestial Video Drivers
+#
+CONFIG_CELESTIAL_VIDEO=y
+CONFIG_VIDEO_DECODER=y
+CONFIG_VIDEO_ENCODER=y
+CONFIG_VIDEO_CODA_CLOCK=0
+CONFIG_VIDEO_NUM=1
+CONFIG_VIDEO_CPB_SIZE=0xc00000
+CONFIG_VIDEO_ENC_NUM=1
+CONFIG_VIDEO_ENC_CPB_SIZE=0x400000
+# CONFIG_CELESTIAL_VIDEO_DEBUG is not set
+
+#
+# Celestial Audio Drivers
+#
+CONFIG_CELESTIAL_AUDIO=y
+CONFIG_AUDIO_DECODER=y
+CONFIG_AUDIO_ENCODER=y
+CONFIG_AUDIO_AAB=y
+CONFIG_AUDIO_NUM=1
+CONFIG_AUDIO_CAB_SIZE=0x200000
+CONFIG_AUDIO_ENC_NUM=1
+CONFIG_AUDIO_ENC_CAB_SIZE=0x400000
+# CONFIG_CELESTIAL_AUDIO_DEBUG is not set
+# CONFIG_AUDIO_FW_DUMP_DEBUG is not set
+
+#
+# Celestial Peripheral Devices
+#
+CONFIG_CELESTIAL_NAND=y
+CONFIG_CELESTIAL_ETH=y
+# CONFIG_CELESTIAL_MULT_ETH is not set
+CONFIG_CELESTIAL_MMC=y
+# CONFIG_CELESTIAL_MULT_MMC is not set
+# CONFIG_CELESTIAL_8BIT_MMC is not set
+CONFIG_CELESTIAL_HCI=y
+CONFIG_CELESTIAL_OTG=y
+CONFIG_CELESTIAL_I2C=y
+# CONFIG_CELESTIAL_SCI is not set
+CONFIG_CELESTIAL_GPIO=y
+CONFIG_CELESTIAL_FPC=y
+CONFIG_CELESTIAL_FPC_IR_GPIO=11
+# CONFIG_CELESTIAL_WDT is not set
+# CONFIG_CELESTIAL_SEC is not set
+# CONFIG_VGA_SWITCHER_SUPPORT is not set
+
+#
+# Celestial Graphics driver
+#
+# CONFIG_CELESTIAL_GRAPHICS is not set
+
+#
+# Ubuntu Supplied Third-Party Device Drivers
+#
+# CONFIG_AUFS_FS is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT2_FS_XIP=y
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_FS_XIP=y
+CONFIG_FS_MBCACHE=y
+# 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=y
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY_USER=y
+CONFIG_FANOTIFY=y
+# CONFIG_QUOTA is not set
+# CONFIG_QUOTACTL is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+# CONFIG_OVERLAYFS_FS is not set
+CONFIG_GENERIC_ACL=y
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_TMPFS_XATTR=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_ECRYPT_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_YAFFS_FS=y
+# CONFIG_YAFFS_DEBUG is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+CONFIG_JFFS2_FS_WBUF_VERIFY=y
+CONFIG_JFFS2_SUMMARY=y
+# 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 is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX6FS_FS is not set
+# CONFIG_ROMFS_FS 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=y
+# CONFIG_NFS_V4 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_ACL_SUPPORT=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_DEBUG is not set
+# CONFIG_CEPH_FS is not set
+CONFIG_CIFS=y
+# CONFIG_CIFS_STATS is not set
+# CONFIG_CIFS_WEAK_PW_HASH is not set
+# CONFIG_CIFS_UPCALL is not set
+# CONFIG_CIFS_XATTR is not set
+# CONFIG_CIFS_DEBUG2 is not set
+# CONFIG_CIFS_DFS_UPCALL is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+CONFIG_NLS_CODEPAGE_936=y
+# 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=y
+# CONFIG_NLS_ISO8859_1 is not set
+# 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=y
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_FRAME_WARN=2048
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_SECTION_MISMATCH is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+# CONFIG_LOCKUP_DETECTOR is not set
+# CONFIG_HARDLOCKUP_DETECTOR is not set
+# CONFIG_DETECT_HUNG_TASK is not set
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_SPARSE_RCU_POINTER is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_ATOMIC_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+CONFIG_STACKTRACE=y
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_HIGHMEM is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_TEST_LIST_SORT is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+CONFIG_RCU_CPU_STALL_TIMEOUT=60
+# CONFIG_RCU_CPU_STALL_INFO is not set
+# CONFIG_RCU_TRACE is not set
+# CONFIG_KPROBES_SANITY_TEST is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_DEBUG_PER_CPU_MAPS is not set
+# CONFIG_LKDTM is not set
+# CONFIG_CPU_NOTIFIER_ERROR_INJECT is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_DEBUG_PAGEALLOC is not set
+CONFIG_NOP_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_HAVE_C_RECORDMCOUNT=y
+CONFIG_RING_BUFFER=y
+CONFIG_EVENT_TRACING=y
+# CONFIG_EVENT_POWER_TRACING_DEPRECATED is not set
+CONFIG_CONTEXT_SWITCH_TRACER=y
+CONFIG_TRACING=y
+CONFIG_GENERIC_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
+CONFIG_FUNCTION_TRACER=y
+# CONFIG_FUNCTION_GRAPH_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_KPROBE_EVENT is not set
+# CONFIG_DYNAMIC_FTRACE is not set
+# CONFIG_FUNCTION_PROFILER is not set
+# CONFIG_FTRACE_STARTUP_TEST is not set
+# CONFIG_RING_BUFFER_BENCHMARK is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_DMA_API_DEBUG is not set
+# CONFIG_ATOMIC64_SELFTEST is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+# CONFIG_TEST_KSTRTOX is not set
+# CONFIG_STRICT_DEVMEM is not set
+# CONFIG_ARM_UNWIND is not set
+CONFIG_OLD_MCOUNT=y
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_RODATA is not set
+# CONFIG_DEBUG_LL is not set
+# CONFIG_ARM_KPROBES_TEST is not set
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+# CONFIG_ENCRYPTED_KEYS is not set
+# CONFIG_KEYS_DEBUG_PROC_KEYS is not set
+# CONFIG_SECURITY_DMESG_RESTRICT is not set
+# CONFIG_SECURITY is not set
+CONFIG_SECURITYFS=y
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP2=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+# CONFIG_CRYPTO_USER is not set
+CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_PCRYPT is not set
+CONFIG_CRYPTO_WORKQUEUE=y
+# 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=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=y
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=y
+# CONFIG_CRYPTO_GHASH is not set
+CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_MICHAEL_MIC=y
+# 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=y
+# CONFIG_CRYPTO_ANUBIS is not set
+CONFIG_CRYPTO_ARC4=y
+# 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=y
+# 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 is not set
+# 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=y
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_PCI_IOMAP=y
+CONFIG_GENERIC_IO=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+CONFIG_CRC_T10DIF=y
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC32_SELFTEST is not set
+CONFIG_CRC32_SLICEBY8=y
+# CONFIG_CRC32_SLICEBY4 is not set
+# CONFIG_CRC32_SARWATE is not set
+# CONFIG_CRC32_BIT is not set
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+# CONFIG_CRC8 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_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_CPU_RMAP=y
+CONFIG_DQL=y
+CONFIG_NLATTR=y
+# CONFIG_AVERAGE is not set
+# CONFIG_CORDIC is not set
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/arch/arm/include/asm/hardirq.h linux-linaro-3.4-2012.05-1_cavium/arch/arm/include/asm/hardirq.h
--- linux-linaro-3.4-2012.05-1_original/arch/arm/include/asm/hardirq.h	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/arch/arm/include/asm/hardirq.h	2014-07-29 17:28:38.819972000 +0800
@@ -5,7 +5,11 @@
 #include <linux/threads.h>
 #include <asm/irq.h>
 
+#ifdef CONFIG_SW_SUPPORT
+#define NR_IPI	7
+#else
 #define NR_IPI	6
+#endif
 
 typedef struct {
 	unsigned int __softirq_pending;
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/arch/arm/include/asm/hardware/debug-8250.S linux-linaro-3.4-2012.05-1_cavium/arch/arm/include/asm/hardware/debug-8250.S
--- linux-linaro-3.4-2012.05-1_original/arch/arm/include/asm/hardware/debug-8250.S	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/arch/arm/include/asm/hardware/debug-8250.S	2014-07-29 17:28:38.819972000 +0800
@@ -10,11 +10,11 @@
 #include <linux/serial_reg.h>
 
 		.macro	senduart,rd,rx
-		strb	\rd, [\rx, #UART_TX << UART_SHIFT]
+		str	\rd, [\rx, #UART_TX << UART_SHIFT]
 		.endm
 
 		.macro	busyuart,rd,rx
-1002:		ldrb	\rd, [\rx, #UART_LSR << UART_SHIFT]
+1002:		ldr	\rd, [\rx, #UART_LSR << UART_SHIFT]
 		and	\rd, \rd, #UART_LSR_TEMT | UART_LSR_THRE
 		teq	\rd, #UART_LSR_TEMT | UART_LSR_THRE
 		bne	1002b
@@ -22,7 +22,7 @@
 
 		.macro	waituart,rd,rx
 #ifdef FLOW_CONTROL
-1001:		ldrb	\rd, [\rx, #UART_MSR << UART_SHIFT]
+1001:		ldr	\rd, [\rx, #UART_MSR << UART_SHIFT]
 		tst	\rd, #UART_MSR_CTS
 		beq	1001b
 #endif
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/arch/arm/include/asm/smp.h linux-linaro-3.4-2012.05-1_cavium/arch/arm/include/asm/smp.h
--- linux-linaro-3.4-2012.05-1_original/arch/arm/include/asm/smp.h	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/arch/arm/include/asm/smp.h	2014-07-29 17:28:38.819972000 +0800
@@ -95,4 +95,10 @@
 
 extern void smp_send_all_cpu_backtrace(void);
 
+#ifdef CONFIG_SW_SUPPORT
+typedef void (ipi_secure_notify_handler)(struct pt_regs *regs);
+int register_secure_notify_handler(ipi_secure_notify_handler handler);
+int unregister_secure_notify_handler(void);
+#endif
+
 #endif /* ifndef __ASM_ARM_SMP_H */
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/arch/arm/Kconfig linux-linaro-3.4-2012.05-1_cavium/arch/arm/Kconfig
--- linux-linaro-3.4-2012.05-1_original/arch/arm/Kconfig	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/arch/arm/Kconfig	2014-07-29 17:28:38.819972000 +0800
@@ -453,6 +453,23 @@
 	  Support for systems based on the DC21285 companion chip
 	  ("FootBridge"), such as the Simtec CATS and the Rebel NetWinder.
 
+config ARCH_CELESTIAL
+	bool "Cavium Celestial"
+	select CPU_V7
+ 	select ARM_GIC
+	select ZONE_DMA
+	select COMMON_CLK
+	select CLKSRC_MMIO
+	select CLKDEV_LOOKUP
+	select HAVE_ARM_TWD
+	select MIGHT_HAVE_CACHE_L2X0
+	select GENERIC_CLOCKEVENTS
+	select HAVE_ARM_SCU
+	select HAVE_SMP
+	select ARCH_HAS_CPUFREQ
+	help
+	  Support for Cavium's CNC1900.
+
 config ARCH_MXC
 	bool "Freescale MXC/iMX-based"
 	select GENERIC_CLOCKEVENTS
@@ -1018,6 +1035,8 @@
 # Kconfigs may be included either alphabetically (according to the
 # plat- suffix) or along side the corresponding mach-* source.
 #
+source "arch/arm/mach-celestial/Kconfig"
+
 source "arch/arm/mach-at91/Kconfig"
 
 source "arch/arm/mach-bcmring/Kconfig"
@@ -1407,6 +1426,14 @@
 	  on systems with an outer cache, the store buffer is drained
 	  explicitly.
 
+config SW_SUPPORT
+       bool "Enable Sierrware Trustzone support"
+       depends on MACH_CELESTIAL_CNC1900
+       default n
+       help
+	When enabled, linux runs in non secure world with
+	secure world interface provided by Sierraware.
+
 endmenu
 
 source "arch/arm/common/Kconfig"
@@ -1556,7 +1583,7 @@
 
 config HAVE_ARM_TWD
 	bool
-	depends on SMP
+#	depends on SMP
 	select TICK_ONESHOT
 	help
 	  This options enables support for the ARM timer and watchdog unit
@@ -1588,7 +1615,7 @@
 	int "Maximum number of CPUs (2-32)"
 	range 2 32
 	depends on SMP
-	default "4"
+	default "2"
 
 config HOTPLUG_CPU
 	bool "Support for hot-pluggable CPUs (EXPERIMENTAL)"
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/arch/arm/kernel/Makefile linux-linaro-3.4-2012.05-1_cavium/arch/arm/kernel/Makefile
--- linux-linaro-3.4-2012.05-1_original/arch/arm/kernel/Makefile	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/arch/arm/kernel/Makefile	2014-07-29 17:28:38.819972000 +0800
@@ -82,3 +82,5 @@
 obj-$(CONFIG_EARLY_PRINTK)	+= early_printk.o
 
 extra-y := $(head-y) init_task.o vmlinux.lds
+obj-$(CONFIG_SW_SUPPORT) += sw_ipi.o
+obj-$(CONFIG_SW_SUPPORT) += notify_hypervisor.o
\ No newline at end of file
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/arch/arm/kernel/notify_hypervisor.c linux-linaro-3.4-2012.05-1_cavium/arch/arm/kernel/notify_hypervisor.c
--- linux-linaro-3.4-2012.05-1_original/arch/arm/kernel/notify_hypervisor.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/arch/arm/kernel/notify_hypervisor.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,12 @@
+#include <linux/notify_hypervisor.h>
+#include <linux/sw_ipi.h>
+
+void invoke_hypercall(int cmd_id, int param1, int param2, int param3)
+{
+	sw_send_smc(cmd_id, param1, param2, param3);
+}
+
+void notify_hypervisor(int cmd_id, int param1, int param2, int param3)
+{
+	invoke_hypercall(cmd_id, param1, param2, param3);
+}
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/arch/arm/kernel/smp.c linux-linaro-3.4-2012.05-1_cavium/arch/arm/kernel/smp.c
--- linux-linaro-3.4-2012.05-1_original/arch/arm/kernel/smp.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/arch/arm/kernel/smp.c	2014-07-29 17:28:38.819972000 +0800
@@ -51,6 +51,10 @@
  */
 struct secondary_data secondary_data;
 
+#ifdef CONFIG_SW_SUPPORT
+static ipi_secure_notify_handler *secure_notify_handler = NULL;
+#endif
+
 enum ipi_msg_type {
 	IPI_TIMER = 2,
 	IPI_RESCHEDULE,
@@ -58,6 +62,9 @@
 	IPI_CALL_FUNC_SINGLE,
 	IPI_CPU_STOP,
 	IPI_CPU_BACKTRACE,
+#ifdef CONFIG_SW_SUPPORT
+	IPI_SECURE_NOTIFY,
+#endif
 };
 
 static DECLARE_COMPLETION(cpu_running);
@@ -386,6 +393,9 @@
 	S(IPI_CALL_FUNC_SINGLE, "Single function call interrupts"),
 	S(IPI_CPU_STOP, "CPU stop interrupts"),
 	S(IPI_CPU_BACKTRACE, "CPU backtrace"),
+#ifdef CONFIG_SW_SUPPORT
+	S(IPI_SECURE_NOTIFY, "Secure kernel notification"),
+#endif
 };
 
 void show_ipi_list(struct seq_file *p, int prec)
@@ -617,7 +627,12 @@
 	case IPI_CPU_BACKTRACE:
 		ipi_cpu_backtrace(cpu, regs);
 		break;
-
+#ifdef CONFIG_SW_SUPPORT
+    case IPI_SECURE_NOTIFY:
+		if(secure_notify_handler)
+			secure_notify_handler(regs);
+		break;
+#endif
 	default:
 		printk(KERN_CRIT "CPU%u: Unknown IPI message 0x%x\n",
 		       cpu, ipinr);
@@ -670,6 +685,25 @@
 	return -EINVAL;
 }
 
+#ifdef CONFIG_SW_SUPPORT
+int register_secure_notify_handler(ipi_secure_notify_handler handler)
+{
+	printk(KERN_EMERG"register secure notify handler\n");
+	secure_notify_handler = handler;
+	return 0;
+}
+
+int unregister_secure_notify_handler(void)
+{
+	secure_notify_handler = NULL;
+	return 0;
+}
+
+
+EXPORT_SYMBOL(register_secure_notify_handler);
+EXPORT_SYMBOL(unregister_secure_notify_handler);
+#endif
+
 #ifdef CONFIG_CPU_FREQ
 
 static DEFINE_PER_CPU(unsigned long, l_p_j_ref);
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/arch/arm/kernel/smp_scu.c linux-linaro-3.4-2012.05-1_cavium/arch/arm/kernel/smp_scu.c
--- linux-linaro-3.4-2012.05-1_original/arch/arm/kernel/smp_scu.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/arch/arm/kernel/smp_scu.c	2014-07-29 17:28:38.819972000 +0800
@@ -52,6 +52,9 @@
 	if (scu_ctrl & 1)
 		return;
 
+	//enable scu clock gating and the interrupt controller clock gating.
+	scu_ctrl |= 0x00000060;
+
 	scu_ctrl |= 1;
 	__raw_writel(scu_ctrl, scu_base + SCU_CTRL);
 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/arch/arm/kernel/smp_twd.c linux-linaro-3.4-2012.05-1_cavium/arch/arm/kernel/smp_twd.c
--- linux-linaro-3.4-2012.05-1_original/arch/arm/kernel/smp_twd.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/arch/arm/kernel/smp_twd.c	2014-07-29 17:28:38.819972000 +0800
@@ -13,6 +13,7 @@
 #include <linux/clk.h>
 #include <linux/cpufreq.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <linux/device.h>
 #include <linux/err.h>
 #include <linux/smp.h>
@@ -31,7 +32,7 @@
 static void __iomem *twd_base;
 
 static struct clk *twd_clk;
-static unsigned long twd_timer_rate;
+unsigned long twd_timer_rate;
 
 static struct clock_event_device __percpu **twd_evt;
 static int twd_ppi;
@@ -279,10 +280,13 @@
 	}
 
 	err = local_timer_register(&twd_lt_ops);
-	if (err)
-		goto out_irq;
 
-	return 0;
+	if (smp_processor_id() == 0) {
+		twd_evt[0] = kzalloc(sizeof(struct clock_event_device), GFP_KERNEL);
+		err = twd_timer_setup(twd_evt[0]);
+	}
+
+	return err;
 
 out_irq:
 	free_percpu_irq(twd_ppi, twd_evt);
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/arch/arm/kernel/sw_ipi.c linux-linaro-3.4-2012.05-1_cavium/arch/arm/kernel/sw_ipi.c
--- linux-linaro-3.4-2012.05-1_original/arch/arm/kernel/sw_ipi.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/arch/arm/kernel/sw_ipi.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,246 @@
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/sw_ipi.h>
+#include <linux/interrupt.h>
+#include <linux/virtio_mmio.h>
+#include <asm/smp.h>
+#include <asm/cacheflush.h>
+
+#define VIRTIO_NET_IPI_NUM 0x10
+
+struct ipi_shared_mem_info {
+	void* sw_ipi_pri_data;
+	int sw_ipi_pri_data_size;
+	char* sw_ipi_bit_map;
+	char* sw_ipi_bit_map_end;
+};
+
+static struct ipi_shared_mem_info ipi_sh_mem_info;
+static struct workqueue_struct* ipi_work_queue;
+static struct list_head sw_ipi_hndl_list;
+static unsigned int cacheline_size;
+struct sw_ipi_handlers{
+    struct list_head head;
+    int ipi_num;
+    work_func_t ipi_hndl;
+	int irq_num;
+	void *data;
+};
+
+#define SMC_CMD_GET_IPI_DAT_SHMEM_ADDR  (-40)
+#define SMC_CMD_GET_IPI_DAT_SHMEM_SIZE  (-41)
+#define SMC_CMD_GET_IPI_BIT_SHMEM_ADDR  (-42)
+#define SMC_CMD_GET_IPI_BIT_SHMEM_SIZE  (-43)
+
+static void sw_inv_range(unsigned long start, unsigned long end)
+{
+	start = round_down(start, cacheline_size);
+	end = round_up(end, cacheline_size);
+	while (start < end) {
+		asm ("mcr p15, 0, %0, c7, c6, 1" : : "r" (start)
+				: "memory");
+		start += cacheline_size;
+	}
+	dsb();
+	isb();
+}
+
+u32 sw_send_smc(u32 cmd, u32 arg1, u32 arg2, u32 arg3)
+{
+    register u32 reg0 __asm__("r0") = cmd;
+    register u32 reg1 __asm__("r1") = arg1;
+    register u32 reg2 __asm__("r2") = arg2;
+    register u32 reg3 __asm__("r3") = arg3;
+
+    __asm__ volatile (
+		".arch_extension sec\n"
+        "smc    0\n"
+        : "+r"(reg0), "+r"(reg1), "+r"(reg2), "+r"(reg3)
+    );
+
+    return reg0;
+}
+
+static int get_ipi_num(void)
+{
+    int ipi_num = 0;
+    char* bit_map, bit_val;
+
+	clean_dcache_area((void *)&ipi_sh_mem_info, sizeof(ipi_sh_mem_info));
+	/*sw_inv_range((unsigned long)&ipi_sh_mem_info , (unsigned
+			long)&ipi_sh_mem_info + sizeof(ipi_sh_mem_info));*/
+	bit_map = ipi_sh_mem_info.sw_ipi_bit_map;
+
+   while(!(*bit_map)){
+        ipi_num += 8;
+        bit_map++;
+		if((int)bit_map >= (int)ipi_sh_mem_info.sw_ipi_bit_map_end){
+       		printk("Invalid ipi number\n");	
+		return -1;
+		}
+    }
+	bit_val = *bit_map;
+
+    while(!(bit_val & 1)){
+        ipi_num++;
+        bit_val >>= 1;
+    }
+
+    return ipi_num;
+}
+
+static void reset_ipi(int ipi_num)
+{
+	char* bit_map;
+
+	bit_map = ipi_sh_mem_info.sw_ipi_bit_map;
+
+	while(ipi_num > 7){
+		ipi_num -= 8;
+		bit_map++;
+	}
+	*bit_map = (*bit_map) & (~(1 << ipi_num));
+}
+
+
+int hyp_notify_handler(unsigned int irq, void (*handler) (struct work_struct *),
+		unsigned long irqflags, const char *devname, void *dev_id)
+{
+	int err;
+#ifdef CONFIG_SW_A15_HYP
+	err = request_irq(irq, vm_interrupt, irqflags, devname, dev_id);
+	if (err)
+		return err;
+#else
+	err = sw_register_ipi_handler(VIRTIO_NET_IPI_NUM, irq, handler, dev_id);	
+	if (err) { 
+		printk(KERN_ALERT "Unable to register ipi handler\n");
+		return err;
+	}
+	printk(KERN_ALERT "IPI handler registered successfully\n");
+#endif
+	return 0;
+}
+
+static void sw_ns_ipi_handler(struct pt_regs *regs)
+{
+    int ipi_num;
+    struct sw_ipi_info *new_wq;
+    struct sw_ipi_handlers *tem_handler;
+    int ipi_hndl_found = 0;
+
+    ipi_num = get_ipi_num();
+	if(ipi_num < 0){
+		return;
+	}
+	reset_ipi(ipi_num);
+    list_for_each_entry(tem_handler, &sw_ipi_hndl_list, head) {
+        if(tem_handler->ipi_num == ipi_num){
+            ipi_hndl_found = 1;
+            break;
+        }
+    }
+    if(!ipi_hndl_found){
+        printk(KERN_ALERT "Could not find registered handler for this ipi\n");
+        return;
+    }
+    new_wq = (struct sw_ipi_info*)kmalloc(sizeof(struct sw_ipi_info) ,GFP_KERNEL);
+    if(!new_wq){
+        printk("Allocation of work queue failed for the ipi %d\n",ipi_num);
+        return;
+    }
+	if(ipi_num == VIRTIO_NET_IPI_NUM) {
+		new_wq->irq_num = tem_handler->irq_num;
+	new_wq->pri_data = tem_handler->data;
+	}
+	else {
+		new_wq->pri_data = (char*)kmalloc(ipi_sh_mem_info.sw_ipi_pri_data_size, GFP_KERNEL);
+    	if(!new_wq->pri_data){
+        	printk("Allocation of buffer for copying the shared mem failed"
+				" for the ipi %d\n",ipi_num);
+			kfree(new_wq);
+     	  	return;
+   		 }
+
+		 memcpy(new_wq->pri_data, ipi_sh_mem_info.sw_ipi_pri_data, 
+			ipi_sh_mem_info.sw_ipi_pri_data_size);
+	}
+	INIT_WORK(&new_wq->work , tem_handler->ipi_hndl);
+	queue_work(ipi_work_queue, &new_wq->work);
+	return;
+}
+
+int sw_register_ipi_handler(int ipi_num, int irq, void* func, void *data)
+{
+	struct sw_ipi_handlers* new_handler;
+	static int wq_create = 0;
+
+	if(!wq_create){
+		printk("*** Creating work queue *** \n");
+		ipi_work_queue = create_workqueue("sw_ipi_handler");
+		wq_create = 1;
+	}
+
+	new_handler = (struct sw_ipi_handlers*)kmalloc(sizeof(struct sw_ipi_handlers), GFP_KERNEL);
+	if(!new_handler){
+		printk("Failed to allocate memory for the new handler registration \n");
+		printk("Failed to register the ipi handler %d \n",ipi_num);
+		return -ENOMEM;
+	}
+
+	INIT_LIST_HEAD(&new_handler->head);
+	new_handler->ipi_num = ipi_num;
+	new_handler->ipi_hndl = func;
+	new_handler->data = data;
+	new_handler->irq_num = irq;
+	list_add(&new_handler->head, &sw_ipi_hndl_list);
+	return 0;
+}
+EXPORT_SYMBOL(sw_register_ipi_handler);
+
+void sw_unregister_ipi_handler(int ipi_num)
+{
+	int ipi_hndl_found = 0;
+	struct sw_ipi_handlers *tem_handler;
+	list_for_each_entry(tem_handler, &sw_ipi_hndl_list, head) {
+		if(tem_handler->ipi_num == ipi_num){
+			ipi_hndl_found = 1;
+			break;
+		}
+	}
+	if(ipi_hndl_found){
+		list_del(&tem_handler->head);
+		kfree(tem_handler);
+	}
+}
+EXPORT_SYMBOL(sw_unregister_ipi_handler);
+
+void sw_ipi_handler_init(void)
+{
+	unsigned int sh_mem_addr,sh_mem_size;
+	unsigned long ctr;
+	
+	asm volatile("mrc p15, 0, %0, c0, c0, 1" : "=r" (ctr));
+	cacheline_size =  4 << ((ctr >> 16) & 0xf);
+
+	printk("*** Initializing sw ipi handler *** \n");
+	register_secure_notify_handler(sw_ns_ipi_handler);
+
+	/* Registering shared memory for ipi handling */
+	sh_mem_addr = sw_send_smc(SMC_CMD_GET_IPI_DAT_SHMEM_ADDR, 0, 0, 0);
+	ipi_sh_mem_info.sw_ipi_pri_data_size = sw_send_smc(SMC_CMD_GET_IPI_DAT_SHMEM_SIZE, 0, 0, 0);
+	printk(KERN_ALERT "IPI_DATA_SHMEM_ADDR = 0x%08x  *** \n", sh_mem_addr);
+	printk(KERN_ALERT "IPI_DATA_SHMEM_SIZE = 0x%08x  *** \n", ipi_sh_mem_info.sw_ipi_pri_data_size);
+	ipi_sh_mem_info.sw_ipi_pri_data = (void *)ioremap(sh_mem_addr,
+			ipi_sh_mem_info.sw_ipi_pri_data_size);
+
+	sh_mem_addr = sw_send_smc(SMC_CMD_GET_IPI_BIT_SHMEM_ADDR, 0, 0, 0);
+	sh_mem_size = sw_send_smc(SMC_CMD_GET_IPI_BIT_SHMEM_SIZE, 0, 0, 0);
+	ipi_sh_mem_info.sw_ipi_bit_map = (char *)ioremap(sh_mem_addr, sh_mem_size);
+	ipi_sh_mem_info.sw_ipi_bit_map_end = ipi_sh_mem_info.sw_ipi_bit_map + sh_mem_size;
+	printk(KERN_ALERT "IPI_BIT_SHMEM_ADDR = 0x%08x  *** \n", sh_mem_addr);
+	printk(KERN_ALERT "IPI_BIT_SHMEM_SIZE = 0x%08x  *** \n", sh_mem_size);
+	INIT_LIST_HEAD(&sw_ipi_hndl_list);
+}
+
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/arch/arm/mach-celestial/clock.c linux-linaro-3.4-2012.05-1_cavium/arch/arm/mach-celestial/clock.c
--- linux-linaro-3.4-2012.05-1_original/arch/arm/mach-celestial/clock.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/arch/arm/mach-celestial/clock.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,148 @@
+#include <linux/clk-private.h>
+#include <linux/clkdev.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <asm/timex.h>
+#include <linux/interrupt.h>
+#include <mach/hardware.h>
+#include <asm/hardware/cache-l2x0.h>
+#include <linux/irq.h>
+#include <asm/hardware/gic.h>
+#include <asm/cacheflush.h>
+#include <mach/cnc1900_clock_reg.h>
+
+#define PLL_CLK_EN      0x0140 
+#define SOFT_RESET      0x0200 
+#define OTG_CTRL	0x0390 
+
+extern unsigned int cnc1900_get_cpufreq(void);
+
+static void __iomem *iomem;
+
+static struct clk_ops pclk_ops = {
+};
+
+static struct clk pclk = {
+	.flags = CLK_IS_ROOT,
+	.rate = PCLK_FREQ / 2,
+	.ops = &pclk_ops,
+};
+
+static int mmc_enable(struct clk_hw *hw)
+{
+	u32 val = __raw_readl(iomem + PLL_CLK_EN);
+
+	val |= 0x00000080;
+	__raw_writel(val, iomem + PLL_CLK_EN);
+	return 0;	
+}
+
+static void mmc_disable(struct clk_hw *hw)
+{
+	u32 val = __raw_readl(iomem + PLL_CLK_EN);
+
+	val &= ~0x00000080;
+	__raw_writel(val, iomem + PLL_CLK_EN);
+}
+
+static struct clk_ops mmc_ops = {
+	.enable = mmc_enable,
+	.disable = mmc_disable,
+};
+
+static struct clk mmc_clk = {
+	.parent = &pclk,
+	.ops = &mmc_ops,
+};
+
+static int hci_enable(struct clk_hw *hw)
+{
+	u32 val;
+	
+	val = __raw_readl(iomem + PLL_CLK_EN);
+	val |= 0x02000000;
+	__raw_writel(val, iomem + PLL_CLK_EN);
+	udelay(100);
+
+	val = __raw_readl(iomem + SOFT_RESET);
+	val |= 0xEB800000;
+	__raw_writel(val, iomem + SOFT_RESET);
+	udelay(100);
+	return 0;
+}
+
+static void hci_disable(struct clk_hw *hw)
+{
+	u32 val = __raw_readl(iomem + PLL_CLK_EN);
+
+	val &= ~0x02000000;
+	__raw_writel(val, iomem + PLL_CLK_EN);
+}
+
+static struct clk_ops hci_ops = {
+	.enable = hci_enable,
+	.disable = hci_disable,
+};
+
+static struct clk hci_clk = {
+	.parent = &pclk,
+	.ops = &hci_ops,
+};
+
+static int otg_enable(struct clk_hw *hw)
+{
+	u32 val;
+	
+	val = __raw_readl(iomem + PLL_CLK_EN);
+	val |= 0x02000000;
+	__raw_writel(val, iomem + PLL_CLK_EN);
+	udelay(100);
+
+	val = __raw_readl(iomem + SOFT_RESET);
+	val |= 0x55800000;
+	__raw_writel(val, iomem + SOFT_RESET);
+	udelay(100);
+
+	__raw_writel(0x1, iomem + OTG_CTRL);
+	udelay(100);
+	return 0;
+}
+
+static void otg_disable(struct clk_hw *hw)
+{
+	u32 val = __raw_readl(iomem + PLL_CLK_EN);
+
+	val &= ~0x02000000;
+	__raw_writel(val, iomem + PLL_CLK_EN);
+}
+
+static struct clk_ops otg_ops = {
+	.enable = otg_enable,
+	.disable = otg_disable,
+};
+
+static struct clk otg_clk = {
+	.parent = &pclk,
+	.ops = &otg_ops,
+};
+
+static struct clk_lookup lookups[] = {
+	CLKDEV_INIT("smp_gbl",     NULL, &pclk),
+	CLKDEV_INIT("smp_twd",     NULL, &pclk),
+	CLKDEV_INIT("dw_spi_mmio", NULL, &pclk),
+	CLKDEV_INIT("dw_mmc.0",    NULL, &mmc_clk),
+	CLKDEV_INIT("dw_mmc.1",    NULL, &mmc_clk),
+	CLKDEV_INIT("ehci-platform", NULL, &hci_clk),
+	CLKDEV_INIT("dwc_otg", NULL, &otg_clk),
+};
+
+unsigned int cnc1900_get_cpufreq(void);
+
+void __init plat_clock_init(void)
+{
+	iomem = ioremap(CNC1900_ID_SCS, CLOCK_REG_SIZE);
+	pclk.rate = cnc1900_get_cpufreq() / 2;
+
+	clk_prepare(&pclk);
+	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+}
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/arch/arm/mach-celestial/cnc1900_cpufreq_plat.c linux-linaro-3.4-2012.05-1_cavium/arch/arm/mach-celestial/cnc1900_cpufreq_plat.c
--- linux-linaro-3.4-2012.05-1_original/arch/arm/mach-celestial/cnc1900_cpufreq_plat.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/arch/arm/mach-celestial/cnc1900_cpufreq_plat.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,168 @@
+#include <linux/clk-private.h>
+#include <linux/clkdev.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <asm/timex.h>
+#include <linux/interrupt.h>
+#include <mach/hardware.h>
+#include <asm/hardware/cache-l2x0.h>
+#include <linux/irq.h>
+#include <asm/hardware/gic.h>
+#include <asm/cacheflush.h>
+#include <asm/div64.h>
+#include <mach/cnc1900_clock_reg.h>
+
+#define CPUFREQ_ADJUST_IRQ 81
+
+const u32 pll_cpu_div_qv[4] = {1, 2, 4, 6};
+
+unsigned int timer_prescaler_val;
+
+unsigned int cnc1900_get_cpufreq(void)
+{
+	u32 pll_cpu_div_f, pll_cpu_div_q;
+	uint64_t freq;
+
+	/* Get default CPU frequency from PLL settings */
+	pll_cpu_div_f = (__raw_readl(IO_ADDRESS(PLL_CPU_DIV)) >> 6) & 0x7f;
+	pll_cpu_div_q = (__raw_readl(IO_ADDRESS(PLL_CPU_DIV)) >> 3) & 0x7;
+
+	freq = 	(unsigned long long)(pll_cpu_div_f + 1) * 54000000LL;
+	do_div(freq, pll_cpu_div_qv[pll_cpu_div_q]);
+	return (uint32_t)freq;
+}
+/*
+ * Some code only need the multiple of current frequency rather than the real frequency,
+ * so I add this function for speed up.
+ */
+unsigned int cnc1900_get_cpufreq_multiple(void)
+{
+	u32 pll_cpu_div_f, pll_cpu_div_q;
+
+	/* Get default CPU frequency from PLL settings */
+	pll_cpu_div_f = (__raw_readl(IO_ADDRESS(PLL_CPU_DIV)) >> 6) & 0x7f;
+	pll_cpu_div_q = (__raw_readl(IO_ADDRESS(PLL_CPU_DIV)) >> 3) & 0x7;
+
+	return (pll_cpu_div_f + 1) * 2 / pll_cpu_div_qv[pll_cpu_div_q];
+}
+
+void cnc1900_set_cpufreq(unsigned int target_freq)
+{
+	extern struct cpu_cache_fns cpu_cache;
+	unsigned int data;
+	unsigned long flags;
+	int i;
+	unsigned int bits_buf[DIV_ROUND_UP(NR_IRQS, 32)]={0};
+    void __iomem *l2x0_base = (void *)IO_ADDRESS(CNC1900_L2X0);
+	void __iomem *dist_base = (void *)IO_ADDRESS(CNC1900_CA9_GIC_DIST);
+	unsigned int wdog_load_val;
+	unsigned int wdog_counter_val;
+	unsigned int twd_load_val;
+	unsigned int twd_counter_val;
+	unsigned int old_cpufreq_multiple;
+	unsigned int ctrl;
+
+	local_irq_save(flags);
+	for (i = 0; i < DIV_ROUND_UP(NR_IRQS, 32); i++)
+		bits_buf[i] = readl_relaxed(dist_base + GIC_DIST_ENABLE_SET + i * 4);
+	for (i = 0; i < DIV_ROUND_UP(NR_IRQS, 32); i++)
+		writel_relaxed(0xFFFFFFFF,dist_base + GIC_DIST_ENABLE_CLEAR + i * 4);
+	writel_relaxed(1 << (CPUFREQ_ADJUST_IRQ % 32),dist_base + GIC_DIST_ENABLE_SET + (CPUFREQ_ADJUST_IRQ / 32) * 4); //only enable interrupt CPUFREQ_ADJUST_IRQ.
+	local_irq_restore(flags);
+
+	data = 0;
+	__asm__ __volatile__(
+	"@invalidate branch predictor\n\t"
+	"mcr p15, 0, %0, c7, c1, 6  @issue the command of invalidate entire branch predictor array inner shareable \n\t"
+	"dsb \n\t"
+	"isb \n\t"
+	:
+	:"r"(data)
+	:);
+
+	//disable dynamic clock gating of L2 cache
+	data = readl(l2x0_base + L2X0_POWER_CTRL);//read power control register of L2 cache
+    data = data & 0xfffffffd;                 //prepare data
+	writel(data, l2x0_base + L2X0_POWER_CTRL);//write power control register of L2 cache
+
+	//set PMU POWER_MODE register to no transaction clock adjustment mode
+	__raw_writel(1,(IO_ADDRESS(CPU_PWR_MODE)));
+
+	target_freq/=27000000;
+	target_freq-=1;
+
+	old_cpufreq_multiple=cnc1900_get_cpufreq_multiple();
+	
+	/* Set new CPU frequency */
+	__raw_writel((target_freq<<6)|0xB,(IO_ADDRESS(PLL_CPU_DIV)));
+
+	__asm__("dsb");
+	__asm__("isb");
+
+	__asm__("wfi");
+	timer_prescaler_val=((cnc1900_get_cpufreq_multiple()-1)<<8);
+	//set PMU POWER_MODE register to normal mode
+	__raw_writel(0,(IO_ADDRESS(CPU_PWR_MODE)));
+
+	//enable dynamic clock gating and standby mode of L2 cache
+	data = readl(l2x0_base + L2X0_POWER_CTRL); //read power control register of L2 cache
+	data = data | 0x3;                         //prepare data
+	writel(data, l2x0_base + L2X0_POWER_CTRL); //write power control register of L2 cache
+
+	local_irq_save(flags);
+	for (i = 0; i < DIV_ROUND_UP(NR_IRQS, 32); i++)
+		writel_relaxed(bits_buf[i],dist_base + GIC_DIST_ENABLE_SET + i * 4);
+	writel_relaxed(1 << (CPUFREQ_ADJUST_IRQ % 32),dist_base + GIC_DIST_ENABLE_CLEAR + (CPUFREQ_ADJUST_IRQ / 32) * 4); //disable interrupt CPUFREQ_ADJUST_IRQ.
+
+	//tune global,private,watchdog timers as the input clock are also changed.
+	wdog_load_val = __raw_readl(IO_ADDRESS(CNC1900_CA9_TWD) + CAV_WDOG_LOAD);
+	wdog_counter_val = __raw_readl(IO_ADDRESS(CNC1900_CA9_TWD) + CAV_WDOG_COUNTER);
+	twd_load_val = __raw_readl(IO_ADDRESS(CNC1900_CA9_TWD) + CAV_TIMER_LOAD);
+	twd_counter_val = __raw_readl(IO_ADDRESS(CNC1900_CA9_TWD) + CAV_TIMER_COUNTER);
+	
+	wdog_load_val = wdog_load_val*cnc1900_get_cpufreq_multiple()/old_cpufreq_multiple;
+	wdog_counter_val = wdog_counter_val*cnc1900_get_cpufreq_multiple()/old_cpufreq_multiple;
+	twd_load_val = twd_load_val*cnc1900_get_cpufreq_multiple()/old_cpufreq_multiple;
+	twd_counter_val = twd_counter_val*cnc1900_get_cpufreq_multiple()/old_cpufreq_multiple;
+
+	__raw_writel(wdog_load_val, IO_ADDRESS(CNC1900_CA9_TWD) + CAV_WDOG_LOAD);
+	__raw_writel(wdog_counter_val, IO_ADDRESS(CNC1900_CA9_TWD) + CAV_WDOG_COUNTER);
+	__raw_writel(twd_load_val, IO_ADDRESS(CNC1900_CA9_TWD) + CAV_TIMER_LOAD);
+	__raw_writel(twd_counter_val, IO_ADDRESS(CNC1900_CA9_TWD) + CAV_TIMER_COUNTER);
+	
+	ctrl = __raw_readl(IO_ADDRESS(CNC1900_CA9_TWD) + CAV_WDOG_CONTROL);
+	ctrl &= 0xFFFF00FF;
+	ctrl |=timer_prescaler_val;
+	__raw_writel(ctrl, IO_ADDRESS(CNC1900_CA9_TWD) + CAV_WDOG_CONTROL);
+
+	ctrl = __raw_readl(IO_ADDRESS(CNC1900_CA9_TWD) + CAV_TIMER_CONTROL);
+	ctrl &= 0xFFFF00FF;
+	ctrl |=timer_prescaler_val;
+	__raw_writel(ctrl, IO_ADDRESS(CNC1900_CA9_TWD) + CAV_TIMER_CONTROL);
+
+	ctrl = __raw_readl(IO_ADDRESS(CNC1900_CA9_GBL_TIMER) + GBL_TIMER_CONTROL);
+	ctrl &= 0xFFFF00FF;
+	ctrl |=timer_prescaler_val;
+	__raw_writel(ctrl, IO_ADDRESS(CNC1900_CA9_GBL_TIMER) + GBL_TIMER_CONTROL);
+
+	local_irq_restore(flags);
+}
+
+static irqreturn_t cnc1900_pmu_interrupt(int irq, void *dev_id)
+{
+	//clear interrupt request
+	__raw_writel(0,(IO_ADDRESS(CPUCLK_ST_INT)));
+	
+	return IRQ_HANDLED;
+}
+
+int cnc1900_cpufreq_plat_init(void)
+{
+	if (request_irq(CPUFREQ_ADJUST_IRQ, cnc1900_pmu_interrupt, 0, "cpufreq_irq", NULL)) {
+		printk(KERN_ERR "cnc1900_cpufreq_driver_init: cannot register cpufreq IRQ \n");
+		return -EIO;
+	}
+	return 0;
+}
+
+
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/arch/arm/mach-celestial/cnc1900_power_clk.c linux-linaro-3.4-2012.05-1_cavium/arch/arm/mach-celestial/cnc1900_power_clk.c
--- linux-linaro-3.4-2012.05-1_original/arch/arm/mach-celestial/cnc1900_power_clk.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/arch/arm/mach-celestial/cnc1900_power_clk.c	2015-05-21 18:59:42.256307000 +0800
@@ -0,0 +1,1434 @@
+#include <linux/types.h>
+#include <asm/io.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/export.h>
+#include <linux/fs.h>
+#include <linux/module.h>
+#include <linux/clk.h>
+#include <linux/ctype.h>
+#include <linux/spinlock.h>
+#include <linux/miscdevice.h>
+#include <linux/proc_fs.h>
+#include <linux/sched.h>
+#include <mach/cnc1900_clock_reg.h>
+#include <mach/cnc1900_power_clk.h>
+
+#define FREQ_REF    27.0      //MHz
+#define VCO_MAX     3600.0
+#define VCO_MIN     1800.0
+
+struct __u__kvpair {
+	unsigned value;
+	char *string;
+};
+
+struct __u__kvpair pwr_ioctls[] = {
+	{ USB_POWER_DOWN, "USB_POWER_DOWN" },
+	{ XPORT_CLK_DOWN, "XPORT_CLK_DOWN" },
+	{ VIB_CLK_DOWN, "VIB_CLK_DOWN" },
+	{ VPB_CLK_DOWN, "VPB_CLK_DOWN" },
+	{ AUD_CLK_DOWN, "AUD_CLK_DOWN" },
+	{ CRYPTO_CLK_DOWN, "CRYPTO_CLK_DOWN" },
+	{ GRAPHICS_CLK_DOWN, "GRAPHICS_CLK_DOWN" },
+	{ DF_CLK_DOWN, "DF_CLK_DOWN" },
+	{ VIDECOD_CLK_DOWN, "VIDECOD_CLK_DOWN" },
+	{ AUDDACIF_CLK_DOWN, "AUDDACIF_CLK_DOWN" },
+	{ SD_CLK_DOWN, "SD_CLK_DOWN" },
+	{ TVE1_CLK_DOWN, "TVE1_CLK_DOWN" },
+	{ TVE0_CLK_DOWN, "TVE0_CLK_DOWN" },
+	{ AUD_POWER_DOWN, "AUD_POWER_DOWN" },
+	{ VID_POWER_DOWN, "VID_POWER_DOWN" },
+	{ AUD_PLLCLK_DOWN, "AUD_PLLCLK_DOWN" },
+	{ VDAC0_POWER_DOWN, "VDAC0_POWER_DOWN" },
+	{ VDAC1_POWER_DOWN, "VDAC1_POWER_DOWN" },
+	{ HDMI_POWER_DOWN, "HDMI_POWER_DOWN" },
+    { JPEG_CLK_DOWN, "JPEG_CLK_DOWN" },
+    { AHB2_CLK_DOWN, "AHB2_CLK_DOWN" },
+    { CEC_CLK_DOWN, "CEC_CLK_DOWN" },
+    { IR_CLK_DOWN, "IR_CLK_DOWN" },
+    { VPBIN_CLK_DOWN, "VPBIN_CLK_DOWN" },
+	{ 0, NULL },
+	{ 0, "<undefined ioctl>" }
+};
+
+volatile unsigned char  *power_clk_base = NULL;
+// volatile uint32_t       *power_clk_base_ui = NULL;
+
+DEFINE_SPINLOCK(cnc_pwr_lock);
+#define power_clk_write(a,v) writel(v,power_clk_base+((a)&0xfff))
+#define power_clk_read(a)    readl(power_clk_base+((a)&0xfff))
+
+static char *ioctl_name(unsigned cmd)
+{
+	struct __u__kvpair *iter;
+	for (iter = &pwr_ioctls[0]; iter->string != NULL; ++iter) {
+		if (iter->value == cmd) {
+			goto done;
+		}
+	}
+	++iter;
+done:
+	return iter->string;
+}
+
+
+//Coda PLL
+void InitCodaplldiv(    unsigned long  codapll_div_q   ,
+                        unsigned long  codapll_div_f   ,
+                        unsigned short codaaclk_postdiv,
+                        unsigned short codacclk_postdiv,
+                        unsigned short use_codapll_for_cclk  )
+{
+    unsigned int   data;
+
+    data = power_clk_read(CLOCK_PLL_CLK_EN) & 0xFFFEFFFF;
+    power_clk_write(CLOCK_PLL_CLK_EN, data);   //disable coda aclk & cclk
+
+    data = power_clk_read(CLOCK_PLL_SLEEP_N) & 0xFFFFFF3F;
+    power_clk_write(CLOCK_PLL_SLEEP_N, data);  //coda pll & divider reset
+
+    if(use_codapll_for_cclk) {
+      data = (power_clk_read(CLK_SRC_SEL) & 0xFF3FFFFF) | 0x00800000;
+      power_clk_write(CLK_SRC_SEL, data);
+    }
+
+    power_clk_write(PLL_CODA_PARA_Q, codapll_div_q);
+    power_clk_write(PLL_CODA_PARA_F, codapll_div_f);    //coda pll parameter
+    data = (power_clk_read(CLOCK_CLK_GEN_DIV) & 0xFF1FFFFF) | (codaaclk_postdiv << 21) ;
+    power_clk_write(CLOCK_CLK_GEN_DIV, data);     //coda aclk post divider
+
+    data = (power_clk_read(CLOCK_PLL_AVS_DIV) & 0xFFFFFFF0) | codacclk_postdiv ;
+    power_clk_write(CLOCK_PLL_AVS_DIV, data);     //aud cclk post divider
+
+    udelay(2);
+
+    data = power_clk_read(CLOCK_PLL_SLEEP_N ) | 0x00000040;
+    power_clk_write(CLOCK_PLL_SLEEP_N, data);  //deassert coda pll reset
+
+    udelay(70);
+
+    data = power_clk_read(CLOCK_PLL_SLEEP_N ) | 0x00000080;
+    power_clk_write(CLOCK_PLL_SLEEP_N, data);  //deassert coda divider reset
+
+    data = power_clk_read(CLOCK_PLL_CLK_EN ) | 0x00010000;
+    power_clk_write(CLOCK_PLL_CLK_EN, data);   //enable coda aclk & cclk
+
+}
+
+#if 0
+static unsigned long __ceil(double value)
+{
+	double temp_val = 0;
+	unsigned long a = (unsigned long)value;
+	unsigned long ret_val = 0;
+
+	temp_val = value - (double)a;
+	if(temp_val <= 0){
+		ret_val = a;
+	}
+	else{
+		ret_val = a+1;
+	}
+
+	return ret_val;
+}
+
+void abit_fnpll_calc(double fin, double fout, double vmin, double vmax, unsigned long *iDIVF, unsigned long *iDIVQ)
+{
+	const long long i4G = (1LL << 32);
+	//unsigned long iDIVF, iDIVQ;
+	double fDIVQ_PLUS1_MAX, fDIVQ_PLUS1_MIN;
+	double vco;
+
+	fDIVQ_PLUS1_MAX = vmax / (2 * fout);
+	fDIVQ_PLUS1_MIN = vmin / (2 * fout);
+
+	if( fDIVQ_PLUS1_MAX < 1 ||  fDIVQ_PLUS1_MIN > 32) {
+		return;
+	}
+
+	*iDIVQ = fDIVQ_PLUS1_MIN < 1 ? 0 : (unsigned long)__ceil(fDIVQ_PLUS1_MIN - 1);
+
+	vco = fout * ((*iDIVQ + 1) << 1);
+	*iDIVF = (unsigned long) (fin * i4G / vco);
+//	pllout = fin * i4G / (*iDIVF * ((*iDIVQ + 1) << 1));
+
+	return;
+}
+#endif
+void clock_coda_setclock(double codapll_clk, unsigned short codaaclk_postdiv, unsigned short codacclk_postdiv, unsigned short use_codapll_for_cclk )
+{
+        unsigned long CodaPLL_DIVF = 0;
+        unsigned long CodaPLL_DIVQ = 0;
+
+        printk("Coda PLL output frequency in MHz = %f\n", codapll_clk);
+
+ //       abit_fnpll_calc(FREQ_REF, codapll_clk, VCO_MIN, VCO_MAX, &CodaPLL_DIVF, &CodaPLL_DIVQ);
+
+        InitCodaplldiv( CodaPLL_DIVQ   ,
+                        CodaPLL_DIVF   ,
+                        codaaclk_postdiv ,
+                        codacclk_postdiv ,
+                        use_codapll_for_cclk);
+}
+
+enum disp0_pll_cfg {
+   target_freq       ,
+   ref_div           ,
+   fbdiv             ,
+   postdiv1          ,
+   postdiv2          ,
+   disp0_div         ,
+   disp0_clk0_div     ,
+   disp0_clk234_div   ,
+   disp0_clk6_div
+};
+//Display
+static const unsigned int disp0_pll_cfg[70][9] =
+{   //target_freq   ref_div  fbdiv  postdiv1  postdiv2  disp0_div  disp0_clk0_div  disp0_clk234_div  disp0_clk6_div
+    {  148500000,      1,      99,     4,       2,         2,          0,            0,               0 },          //
+    {  148500000,      1,      99,     4,       2,         2,          0,            0,               0 },          //
+    {   74250000,      1,      99,     4,       2,         4,          2,            2,               4 },          //
+    {   74250000,      1,      99,     4,       2,         4,          2,            2,               4 },          //
+    {   74250000,      1,      99,     4,       2,         4,          2,            2,               4 },          //
+    {   74250000,      1,      99,     4,       2,         4,          2,            2,               4 },          //
+    {   74250000,      1,      99,     4,       2,         4,          2,            2,               4 },          //
+    {   74250000,      1,      99,     4,       2,         4,          2,            2,               4 },          //
+    {   74250000,      1,      99,     4,       2,         4,          2,            2,               4 },          //
+                                                                                                                			//
+    {  148351648,     13,    1125,     7,       1,         2,          2,            2,               4 },          // 6,
+    {   74175824,     13,    1125,     7,       1,         4,          2,            2,               4 },          // ,
+    {   74175824,     13,    1125,     7,       1,         4,          2,            2,               4 },          // ,
+    {   74175824,     13,    1125,     7,       1,         4,          2,            2,               4 },          // ,
+    {   74175824,     13,    1125,     7,       1,         4,          2,            2,               4 },          // ,
+                                                                                                                //
+    {   27000000,      1,      63,     7,       2,         4,          2,            2,               2 },          //
+    {   27000000,      1,      63,     7,       2,         4,          2,            2,               2 },          //
+    {   27027000,     20,    1802,     5,       4,         4,          2,            2,               2 },          //
+
+#if 1
+    {   13500000,      1,      63,     7,       2,         8,          2,            2,               4 },          //
+    {   13500000,      1,      63,     7,       2,         8,          2,            2,               4 },          //
+    {   13513500,     20,    1802,     5,       4,         8,          2,            2,               4 },        
+#else
+    {   13500000,      1,      63,     7,       2,         4,          2,            2,               4 },          //
+    {   13500000,      1,      63,     7,       2,         4,          2,            2,               4 },          //
+    {   13513500,     20,    1802,     5,       4,         4,          2,            2,               4 },          // ,
+#endif                                                                                                                //
+    {   31500000,      1,      84,     4,       2,         8,          0,            0,               0 },          // 00,
+    {   31500000,      1,      84,     4,       2,         8,          0,            0,               0 },          // 00,
+    {   35500000,      1,      71,     6,       1,         8,          0,            0,               0 },          // 00,
+    {   25200000,     1,    84,     5,       2,         8,          0,            0,               0 },
+    {   31500000,      1,      84,     4,       2,         8,          0,            0,               0 },          // 00,
+    {   31500000,      1,      84,     4,       2,         8,          0,            0,               0 },          // 00,
+    {   36000000,      1,      60,     5,       2,         4,          0,            0,               0 },          //
+    {   36000000,      1,      60,     5,       2,         4,          0,            0,               0 },          //
+    {   40000000,      1,      90,     6,       3,         3,          0,            0,               0 },          //
+    {   50000000,      1,      50,     4,       3,         2,          0,            0,               0 },          //
+    {   49500000,      1,      99,     4,       3,         4,          0,            0,               0 },          //
+    {   56250000,      1,      75,     4,       2,         4,          0,            0,               0 },          //
+    {   73250000,      4,     293,     4,       2,         3,          0,            0,               0 },          //
+                                                                                                                //
+    {   33750000,      1,      90,     4,       2,         8,          0,            0,               0 },          //
+                                                                                                                //
+    {   44900000,      6,     449,     5,       4,         2,          0,            0,               0 },          //
+    {   65000000,      1,      65,     4,       2,         3,          0,            0,               0 },          //
+    {   75000000,      1,      75,     4,       2,         3,          0,            0,               0 },          //
+    {   78750000,      2,     105,     4,       2,         2,          0,            0,               0 },          //
+    {   94500000,      1,      63,     4,       2,         2,          0,            0,               0 },          //
+    {  115500000,      1,      77,     4,       2,         2,          0,            0,               0 },          //
+                                                                                                                //
+    {  108000000,      1,      72,     4,       2,         2,          0,            0,               0 },          //
+                                                                                                                //
+    {   68250000,      2,      91,     4,       2,         2,          0,            0,               0 },          //
+    {   79500000,      1,      53,     4,       2,         2,          0,            0,               0 },          //
+    {  102250000,      6,     409,     4,       2,         2,          0,            0,               0 },          //
+    {  117500000,      3,     235,     4,       2,         2,          0,            0,               0 },          //
+    {  104250000,      2,     139,     4,       2,         2,          0,            0,               0 },          //
+                                                                                                                //
+    {   71000000,      1,      71,     4,       2,         3,          0,            0,               0 },          //
+    {   83500000,      2,     167,     4,       2,         3,          0,            0,               0 },          //
+    {  106500000,      1,      71,     4,       2,         2,          0,            0,               0 },          //
+    {  122500000,      3,     245,     4,       2,         2,          0,            0,               0 },          //
+    {  146250000,      2,     195,     4,       2,         2,          0,            0,               0 },          //
+                                                                                                                //
+    {  108000000,      1,      72,     4,       2,         2,          0,            0,               0 },          //
+    {  148500000,      1,      99,     4,       2,         2,          0,            0,               0 },          //
+                                                                                                                    //
+    {  108000000,      1,      72,     4,       2,         2,          0,            0,               0 },          //
+    {  135000000,      1,      45,     4,       1,         2,          0,            0,               0 },          //
+    {  157500000,      2,     105,     4,       1,         2,          0,            0,               0 },          //
+                                                                                                                //
+    {   85500000,      1,      57,     4,       2,         2,          0,            0,               0 },          //
+    {  148250000,      8,     593,     6,       1,         2,          0,            0,               0 },          //
+                                                                                                                    //
+    {  101000000,      3,     202,     4,       2,         2,          0,            0,               0 },          //
+    {  121750000,      6,     487,     4,       2,         2,          0,            0,               0 },          //
+    {  156000000,      1,      52,     4,       1,         2,          0,            0,               0 },          //
+                                                                                                                    //
+    {   88750000,      4,     355,     4,       2,         3,          0,            0,               0 },          //
+    {  106500000,      1,      71,     4,       2,         2,          0,            0,               0 },          //
+    {  136750000,      8,     547,     6,       1,         2,          0,            0,               0 },          //
+    {  157000000,      2,     157,     6,       1,         2,          0,            0,               0 },          //
+                                                                                                                    //
+    {  162000000,      1,      81,     6,       1,         2,          0,            0,               0 },          //
+                                                                                                                    //
+    {  119000000,      6,     476,     4,       2,         2,          0,            0,               0 },          //
+    {  146250000,      2,     195,     4,       2,         2,          0,            0,               0 },          //
+                                                                                                                    //
+    {  154000000,      2,     154,     6,       1,         2,          0,            0,               0 },           //
+
+    {   25175000,     20,    1007,     6,       1,         8,          0,            0,               0 },          //
+
+
+};
+
+void clock_disp0_setclock(CLOCK_DISP0_MODE mode_disp0)
+{
+    unsigned int   div_m               = 0;
+    unsigned int   div_fb              = 0;
+    unsigned int   div_fb_29_27;
+    unsigned int   div_fb_25_23;
+    unsigned int   div_fb_19_17;
+    unsigned int   div_fb_16_13;
+    unsigned int   div_fb_9_8;
+    unsigned int   div_fb_7_5;
+    unsigned int   div_fb_3_1;
+    unsigned int   data;
+    div_m  = (disp0_pll_cfg[mode_disp0][fbdiv] & 0xE00) >> 9;
+    div_fb_29_27 = (disp0_pll_cfg[mode_disp0][fbdiv] & 0x1C0) << 21;
+    div_fb_25_23 = (disp0_pll_cfg[mode_disp0][fbdiv] & 0x038) << 20;
+    div_fb_19_17 = (disp0_pll_cfg[mode_disp0][fbdiv] & 0x007) << 17;
+    div_fb_16_13 = (disp0_pll_cfg[mode_disp0][ref_div] & 0x00f) << 13;
+    div_fb_9_8   = (disp0_pll_cfg[mode_disp0][ref_div] & 0x030) << 4;
+    div_fb_7_5   = (disp0_pll_cfg[mode_disp0][postdiv1] & 0x007) << 5;
+    div_fb_3_1   = (disp0_pll_cfg[mode_disp0][postdiv2] & 0x007) << 1;
+
+    div_fb       = div_fb_29_27 | div_fb_25_23 | div_fb_19_17 | div_fb_16_13 | div_fb_9_8 | div_fb_7_5 | div_fb_3_1;
+
+    data = power_clk_read(CLOCK_PLL_CLK_EN ) & 0xFFFFFFEF;
+    power_clk_write(CLOCK_PLL_CLK_EN, data);   //disable tve clock, disp clock
+
+    data = power_clk_read(CLOCK_PLL_SLEEP_N ) & 0xFFFFFFFC;
+    power_clk_write(CLOCK_PLL_SLEEP_N, data);  //tve pll & divider reset
+
+    power_clk_write(PLL_TVE_PARA_Q, div_m);
+    power_clk_write(PLL_TVE_PARA_F, div_fb);    //tve pll parameter
+    data = power_clk_read(CLOCK_TVE_DIV_N ) & 0x0FFFF000;
+    power_clk_write(CLOCK_TVE_DIV_N, (data | (disp0_pll_cfg[mode_disp0][disp0_clk234_div] << 28) | (disp0_pll_cfg[mode_disp0][disp0_div] << 8) | (disp0_pll_cfg[mode_disp0][disp0_clk6_div] << 4) | disp0_pll_cfg[mode_disp0][disp0_clk0_div]));    //tve divider
+
+    udelay(2);
+
+    data = power_clk_read(CLOCK_PLL_SLEEP_N ) | 0x00000001;
+    power_clk_write(CLOCK_PLL_SLEEP_N, data);  //deassert tve pll reset
+
+    udelay(70);
+
+    data = power_clk_read(CLOCK_PLL_SLEEP_N ) | 0x00000002;
+    power_clk_write(CLOCK_PLL_SLEEP_N, data);  //deassert tve divider reset
+
+    data = power_clk_read(CLOCK_PLL_CLK_EN ) | 0x00000010;
+    power_clk_write(CLOCK_PLL_CLK_EN, data);   //enable tve clock, disp clock
+
+}
+
+enum disp1_pll_postdiv {
+   target_freq_disp1  ,
+   sys_div          ,
+   disp1_div         ,
+   disp1_clk0_div     ,
+   disp1_clk234_div   ,
+   disp1_clk6_div
+};
+
+static const unsigned int disp1_cfg[8][6] =
+{   //target_freq    sys_div  disp1_div  disp1_clk0_div  disp1_clk234_div  disp1_clk6_div
+    {   27000000,       10,        4,          2,            2,               2 },          //  576P
+    {   27000000,       10,        4,          2,            2,               2 },          //   480P
+    {   27000000,       10,        4,          2,            2,               4 },          //   PAL
+    {   27000000,       10,        4,          2,            2,               4 },          //    NTSL
+    {   27000000,       10,        4,          2,            2,               4 },          //   SECAM
+    {   27000000,       10,        4,          2,            2,               4 },          //   PAL_M
+    {   27000000,       10,        4,          2,            2,               4 },          //   PAL_N
+    {   27000000,       10,        4,          2,            2,               4 },          //    PAL_CN
+};
+
+void clock_disp1_setclock(CLOCK_DISP1_MODE mode_disp1)
+{
+    unsigned int   data;
+
+    data = power_clk_read(CLOCK_PLL_CLK_EN ) & 0xFFFFFFDF;
+    power_clk_write(CLOCK_PLL_CLK_EN, data);   //disable tve clock, disp clock
+
+    data = power_clk_read(CLOCK_PLL_SLEEP_N ) & 0xFFFFFFFD;
+    power_clk_write(CLOCK_PLL_SLEEP_N, data);  //tve divider reset
+
+    data = (power_clk_read(CLK_SRC_SEL ) & 0xFFF0FFFF) | 0x00050000;
+    power_clk_write(CLK_SRC_SEL, data);        //select sys pll as disp1 clock source
+
+    data = power_clk_read(CLOCK_TVE_DIV_N ) & 0xF0000FFF;
+    power_clk_write(CLOCK_TVE_DIV_N, (data | (disp1_cfg[mode_disp1][disp1_div] << 24) | (disp1_cfg[mode_disp1][disp1_clk6_div] << 20) | (disp1_cfg[mode_disp1][disp1_clk234_div] << 16) | (disp1_cfg[mode_disp1][disp1_clk0_div] << 12)));    //tve divider
+
+    data = power_clk_read(CLOCK_CLK_GEN_DIV ) & 0xFFFF03FF;
+    power_clk_write(CLOCK_CLK_GEN_DIV, (data | (disp1_cfg[mode_disp1][sys_div] << 10)) );    //cpu/sys  divider
+
+    udelay(10);
+
+    data = power_clk_read(CLOCK_PLL_SLEEP_N ) | 0x00000002;
+    power_clk_write(CLOCK_PLL_SLEEP_N, data);  //deassert tve divider reset
+
+    data = power_clk_read(CLOCK_PLL_CLK_EN ) | 0x00000020;
+    power_clk_write(CLOCK_PLL_CLK_EN, data);   //enable tve clock, disp clock
+
+}
+
+enum aud_pll_postdiv {
+   aud_target_freq      ,
+   audpll_div_F         ,
+   audpll_div_Q         ,
+   audclk_postdiv
+};
+#if 0
+static const unsigned int aud_pll_cfg[13][4] =
+{   //target_freq  audpll_div_F  audpll_div_Q  audclk_postdiv 
+    {  192000,      58982400,      9,                  2     },       
+    {   96000,      62086737,     18,                  2     },       
+    {   88200,      64198531,     19,                  2     },       
+    {   64000,      63195429,     27,                  2     },       
+    {   48000,      58982400,     19,                  2     },       
+    {   44100,      33349886,     10,                  7     },       
+    {   32000,      58982400,     29,                  2     },       
+    {   24000,      62086737,     18,                  8     },       
+    {   22050,      64198531,     19,                  8     },       
+    {   16000,      63195429,     13,                  8     },       
+    {   12000,      62086737,     18,                 16     },       
+    {   11025,      64198531,     19,                 16     },       
+    {    8000,      63195429,     27,                 16     }        
+};
+#endif
+
+static const unsigned int aud_pll_cfg[16][4] =
+{   //target_freq  audpll_div_F  audpll_div_Q  audclk_postdiv 
+	{  192000,      32768000,      8,                  2     },   
+	{  176400,      35665850,      8,                  2     }, 
+	{  128000,      32768000,      8,                  3     }, 
+	{   96000,      32768000,     17,                  2     },   
+	{   88200,      64198531,     19,                  2     },            
+	{   64000,      32768000,     26,                  2     },       
+	{   48000,      32768000,     23,                  3     },       
+	{   44100,      33349886,     10,                  7     },       
+	{   32000,      32768000,     26,                  4     }, 
+	{   24000,      62086737,     18,                  8     },       
+	{   22050,      64198531,     19,                  8     },       
+	{   16000,      32768000,     26,                  8     }, 
+	{   12000,      62086737,     18,                 16     },       
+	{   11025,      64198531,     19,                 16     },       
+	{    8000,      63195429,     27,                 16     }      
+};
+
+void clock_audio_setclock(AUDIO_CLOCK_MODE audclk_rate)
+{
+    unsigned int   data;
+
+   // printk("CNC1900 Audio Target freq = %d\n", aud_pll_cfg[audclk_rate][aud_target_freq]);
+
+    data = power_clk_read(CLOCK_PLL_CLK_EN ) & 0xFFFFF7FF;
+    power_clk_write(CLOCK_PLL_CLK_EN, data);   //disable audio pcm clock
+
+    data = power_clk_read(CLOCK_PLL_SLEEP_N ) & 0xFFFFFFCF;
+    power_clk_write(CLOCK_PLL_SLEEP_N, data);  //aud pll & divider reset
+
+    power_clk_write(PLL_AUD_PARA_Q, aud_pll_cfg[audclk_rate][audpll_div_Q]);
+    power_clk_write(PLL_AUD_PARA_F, aud_pll_cfg[audclk_rate][audpll_div_F]);
+    power_clk_write(CLOCK_AUD_DIV, aud_pll_cfg[audclk_rate][audclk_postdiv]);
+
+    udelay(2);
+
+    data = power_clk_read(CLOCK_PLL_SLEEP_N ) | 0x00000010;
+    power_clk_write(CLOCK_PLL_SLEEP_N, data);  //deassert audio pll reset
+
+    udelay(70);
+
+    data = power_clk_read(CLOCK_PLL_SLEEP_N ) | 0x00000030;
+    power_clk_write(CLOCK_PLL_SLEEP_N, data);  //deassert audio divider reset
+
+    data = power_clk_read(CLOCK_PLL_CLK_EN ) | 0x00000800;
+    power_clk_write(CLOCK_PLL_CLK_EN, data);   //enable audio pcm clock
+
+}
+
+void clock_alsa_setclock(int rate)
+{
+	int i;
+    unsigned int data;
+
+	for (i = 0; i < 13; i++) {
+		if (aud_pll_cfg[i][0] == rate)
+			break;
+	}
+
+	if (i == 13)
+		return;
+
+   // printk("CNC1900 Audio Target freq = %d\n", aud_pll_cfg[audclk_rate][aud_target_freq]);
+
+    data = power_clk_read(CLOCK_PLL_CLK_EN ) & 0xFFFFF7FF;
+    power_clk_write(CLOCK_PLL_CLK_EN, data);   //disable audio pcm clock
+
+    data = power_clk_read(CLOCK_PLL_SLEEP_N ) & 0xFFFFFFCF;
+    power_clk_write(CLOCK_PLL_SLEEP_N, data);  //aud pll & divider reset
+
+    power_clk_write(PLL_AUD_PARA_Q, aud_pll_cfg[i][audpll_div_Q]);
+    power_clk_write(PLL_AUD_PARA_F, aud_pll_cfg[i][audpll_div_F]);
+    power_clk_write(CLOCK_AUD_DIV,  aud_pll_cfg[i][audclk_postdiv]);
+
+    udelay(2);
+
+    data = power_clk_read(CLOCK_PLL_SLEEP_N ) | 0x00000010;
+    power_clk_write(CLOCK_PLL_SLEEP_N, data);  //deassert audio pll reset
+
+    udelay(70);
+
+    data = power_clk_read(CLOCK_PLL_SLEEP_N ) | 0x00000030;
+    power_clk_write(CLOCK_PLL_SLEEP_N, data);  //deassert audio divider reset
+
+    data = power_clk_read(CLOCK_PLL_CLK_EN ) | 0x00000800;
+    power_clk_write(CLOCK_PLL_CLK_EN, data);   //enable audio pcm clock
+
+}
+void clock_xport_reset(CLOCK_RESET ResetOrSet)
+{
+    unsigned int reg_val;
+
+    if (ResetOrSet==_do_reset) {
+        reg_val = power_clk_read(CLOCK_SOFT_RESET);
+        power_clk_write(CLOCK_SOFT_RESET, reg_val&(~(0x1<<1)));
+    } else {
+        reg_val = power_clk_read(CLOCK_SOFT_RESET);
+        power_clk_write(CLOCK_SOFT_RESET, reg_val|(0x1<<1));
+    }
+
+    return;
+}
+
+void clock_ether_reset(CLOCK_RESET ResetOrSet)
+{
+    unsigned int reg_val;
+
+    if (ResetOrSet==_do_reset) {
+        reg_val = power_clk_read(CLOCK_SOFT_RESET);
+        power_clk_write(CLOCK_SOFT_RESET, reg_val&(~(0x1<<2)));
+    } else {
+        reg_val = power_clk_read(CLOCK_SOFT_RESET);
+        power_clk_write(CLOCK_SOFT_RESET, reg_val|(0x1<<2));
+    }
+
+    return;
+}
+
+void clock_audio_reset(CLOCK_RESET ResetOrSet)
+{
+    unsigned int reg_val;
+
+    if (ResetOrSet==_do_reset) {
+        reg_val = power_clk_read(CLOCK_SOFT_RESET);
+        power_clk_write(CLOCK_SOFT_RESET, reg_val&(~(0x1<<3)));
+    } else {
+        reg_val = power_clk_read(CLOCK_SOFT_RESET);
+        power_clk_write(CLOCK_SOFT_RESET, reg_val|(0x1<<3));
+    }
+
+    return;
+}
+
+void clock_crypto_reset(CLOCK_RESET ResetOrSet)
+{
+    unsigned int reg_val;
+
+    if (ResetOrSet==_do_reset) {
+        reg_val = power_clk_read(CLOCK_SOFT_RESET);
+        power_clk_write(CLOCK_SOFT_RESET, reg_val&(~(0x1<<5)));
+    } else {
+        reg_val = power_clk_read(CLOCK_SOFT_RESET);
+        power_clk_write(CLOCK_SOFT_RESET, reg_val|(0x1<<5));
+    }
+
+    return;
+}
+
+void clock_video_reset(CLOCK_RESET ResetOrSet)
+{
+    unsigned int reg_val;
+
+    if (ResetOrSet==_do_reset) {
+        reg_val = power_clk_read(CLOCK_SOFT_RESET);
+        power_clk_write(CLOCK_SOFT_RESET, reg_val&(~(0x1<<6)));
+    } else {
+        reg_val = power_clk_read(CLOCK_SOFT_RESET);
+        power_clk_write(CLOCK_SOFT_RESET, reg_val|(0x1<<6));
+    }
+
+    return;
+}
+
+void clock_gfx_reset(CLOCK_RESET ResetOrSet)
+{
+    unsigned int reg_val;
+
+    if (ResetOrSet==_do_reset) {
+        reg_val = power_clk_read(CLOCK_SOFT_RESET);
+        power_clk_write(CLOCK_SOFT_RESET, reg_val&(~(0x1<<7)));
+    } else {
+        reg_val = power_clk_read(CLOCK_SOFT_RESET);
+        power_clk_write(CLOCK_SOFT_RESET, reg_val|(0x1<<7));
+    }
+
+    return;
+}
+
+void clock_dfr_reset(CLOCK_RESET ResetOrSet)
+{
+    unsigned int reg_val;
+
+    if (ResetOrSet==_do_reset) {
+        reg_val = power_clk_read(CLOCK_SOFT_RESET);
+        power_clk_write(CLOCK_SOFT_RESET, reg_val&(~(0x1<<11)));
+    } else {
+        reg_val = power_clk_read(CLOCK_SOFT_RESET);
+        power_clk_write(CLOCK_SOFT_RESET, reg_val|(0x1<<11));
+    }
+
+    return;
+}
+
+void clock_disp0_reset(CLOCK_RESET ResetOrSet)
+{
+    unsigned int reg_val;
+
+    if (ResetOrSet==_do_reset) {
+        reg_val = power_clk_read(CLOCK_SOFT_RESET);
+        power_clk_write(CLOCK_SOFT_RESET, reg_val&(~(0x1<<12)));
+    } else {
+        reg_val = power_clk_read(CLOCK_SOFT_RESET);
+        power_clk_write(CLOCK_SOFT_RESET, reg_val|(0x1<<12));
+    }
+
+    return;
+}
+
+void clock_disp1_reset(CLOCK_RESET ResetOrSet)
+{
+    unsigned int reg_val;
+
+    if (ResetOrSet==_do_reset) {
+        reg_val = power_clk_read(CLOCK_SOFT_RESET);
+        power_clk_write(CLOCK_SOFT_RESET, reg_val&(~(0x1<<13)));
+    } else {
+        reg_val = power_clk_read(CLOCK_SOFT_RESET);
+        power_clk_write(CLOCK_SOFT_RESET, reg_val|(0x1<<13));
+    }
+
+    return;
+}
+
+void clock_tve0_reset(CLOCK_RESET ResetOrSet)
+{
+    unsigned int reg_val;
+
+    if (ResetOrSet==_do_reset) {
+        reg_val = power_clk_read(CLOCK_SOFT_RESET);
+        power_clk_write(CLOCK_SOFT_RESET, reg_val&(~(0x1<<14)));
+    } else {
+        reg_val = power_clk_read(CLOCK_SOFT_RESET);
+        power_clk_write(CLOCK_SOFT_RESET, reg_val|(0x1<<14));
+    }
+
+    return;
+}
+
+void clock_tve1_reset(CLOCK_RESET ResetOrSet)
+{
+    unsigned int reg_val;
+
+    if (ResetOrSet==_do_reset) {
+        reg_val = power_clk_read(CLOCK_SOFT_RESET);
+        power_clk_write(CLOCK_SOFT_RESET, reg_val&(~(0x1<<15)));
+    } else {
+        reg_val = power_clk_read(CLOCK_SOFT_RESET);
+        power_clk_write(CLOCK_SOFT_RESET, reg_val|(0x1<<15));
+    }
+
+    return;
+}
+
+void clock_vib_reset(CLOCK_RESET ResetOrSet)
+{
+    unsigned int reg_val;
+
+    if (ResetOrSet==_do_reset) {
+        reg_val = power_clk_read(CLOCK_SOFT_RESET);
+        power_clk_write(CLOCK_SOFT_RESET, reg_val&(~(0x1<<16)));
+    } else {
+        reg_val = power_clk_read(CLOCK_SOFT_RESET);
+        power_clk_write(CLOCK_SOFT_RESET, reg_val|(0x1<<16));
+    }
+
+    return;
+}
+
+void clock_jpeg_reset(CLOCK_RESET ResetOrSet)
+{
+    unsigned int reg_val;
+
+    if (ResetOrSet==_do_reset) {
+        reg_val = power_clk_read(CLOCK_SOFT_RESET);
+        power_clk_write(CLOCK_SOFT_RESET, reg_val&(~(0x1<<17)));
+    } else {
+        reg_val = power_clk_read(CLOCK_SOFT_RESET);
+        power_clk_write(CLOCK_SOFT_RESET, reg_val|(0x1<<17));
+    }
+
+    return;
+}
+
+void clock_coda_reset(CLOCK_RESET ResetOrSet)
+{
+    unsigned int reg_val;
+
+    if (ResetOrSet==_do_reset) {
+        reg_val = power_clk_read(CLOCK_SOFT_RESET);
+        power_clk_write(CLOCK_SOFT_RESET, reg_val&(~(0x1<<18)));
+    } else {
+        reg_val = power_clk_read(CLOCK_SOFT_RESET);
+        power_clk_write(CLOCK_SOFT_RESET, reg_val|(0x1<<18));
+    }
+
+    return;
+}
+
+void clock_hdmi_reset(CLOCK_RESET ResetOrSet)
+{
+    unsigned int reg_val;
+
+    if (ResetOrSet==_do_reset) {
+        reg_val = power_clk_read(CLOCK_SOFT_RESET);
+        power_clk_write(CLOCK_SOFT_RESET, reg_val&(~(0x1<<19)));
+    } else {
+        reg_val = power_clk_read(CLOCK_SOFT_RESET);
+        power_clk_write(CLOCK_SOFT_RESET, reg_val|(0x1<<19));
+    }
+
+    return;
+}
+
+void clock_hdmi_bypass(HDMI_SEL vpbOrdisp)
+{
+    unsigned int reg_val;
+
+    if (vpbOrdisp==_sel_ttl) {
+        reg_val = power_clk_read(CLOCK_HDMI_CLK_SEL);
+        power_clk_write(CLOCK_HDMI_CLK_SEL, reg_val&(~(0x1<<0)));
+    } else {
+        reg_val = power_clk_read(CLOCK_HDMI_CLK_SEL);
+        power_clk_write(CLOCK_HDMI_CLK_SEL, reg_val|(0x1<<0));
+    }
+
+    return;
+}
+void clock_spdif_reset(CLOCK_RESET ResetOrSet)
+{
+    unsigned int reg_val;
+
+    if (ResetOrSet==_do_reset) {
+        reg_val = power_clk_read(CLOCK_SOFT_RESET);
+        power_clk_write(CLOCK_SOFT_RESET, reg_val&(~(0x1<<20)));
+    } else {
+        reg_val = power_clk_read(CLOCK_SOFT_RESET);
+        power_clk_write(CLOCK_SOFT_RESET, reg_val|(0x1<<20));
+    }
+
+    return;
+}
+
+void clock_dramporta_reset(CLOCK_RESET ResetOrSet)
+{
+    unsigned int reg_val;
+
+    if (ResetOrSet==_do_reset) {
+        reg_val = power_clk_read(CLOCK_SOFT_RESET);
+        power_clk_write(CLOCK_SOFT_RESET, reg_val&(~(0x1<<21)));
+    } else {
+        reg_val = power_clk_read(CLOCK_SOFT_RESET);
+        power_clk_write(CLOCK_SOFT_RESET, reg_val|(0x1<<21));
+    }
+
+    return;
+}
+
+void clock_ir_reset(CLOCK_RESET ResetOrSet)
+{
+    unsigned int reg_val;
+
+    if (ResetOrSet==_do_reset) {
+        reg_val = power_clk_read(CLOCK_SOFT_RESET);
+        power_clk_write(CLOCK_SOFT_RESET, reg_val&(~(0x1<<22)));
+    } else {
+        reg_val = power_clk_read(CLOCK_SOFT_RESET);
+        power_clk_write(CLOCK_SOFT_RESET, reg_val|(0x1<<22));
+    }
+
+    return;
+}
+
+void clock_dac0_enaclock(CLOCK_ENA ClockEna)
+{
+	unsigned int reg_val= 0;
+
+	if(ClockEna == _clock_disable){
+		reg_val = power_clk_read(VDAC0_CTRL);
+		power_clk_write(VDAC0_CTRL, reg_val&(~(0x7<<3)));
+	}
+	else{
+		reg_val = power_clk_read(VDAC0_CTRL);
+		power_clk_write(VDAC0_CTRL, reg_val|(0x7<<3)|0xfffffc0);
+
+	}
+	return;
+}
+
+void clock_dac1_enaclock(CLOCK_ENA ClockEna)
+{
+	unsigned int reg_val= 0;
+
+	if(ClockEna == _clock_disable){
+		reg_val = power_clk_read(VDAC1_CTRL);
+		power_clk_write(VDAC1_CTRL, reg_val&(~(0x7<<3)));
+	}
+	else{
+		reg_val = power_clk_read(VDAC1_CTRL);
+		power_clk_write(VDAC1_CTRL, reg_val|(0x1<<3)|0xfffffc0);
+	}
+	return;
+}
+
+void clock_dram_enaclock(CLOCK_ENA ClockEna)
+{
+	unsigned int reg_val= 0;
+
+	if (ClockEna == _clock_disable){
+		reg_val = power_clk_read(CLOCK_PLL_CLK_EN);
+		power_clk_write(CLOCK_PLL_CLK_EN, reg_val&(~(0x1<<1)));
+	}else{
+		reg_val = power_clk_read(CLOCK_PLL_CLK_EN);
+		power_clk_write(CLOCK_PLL_CLK_EN, reg_val|(0x1<<1));
+	}
+	return;
+}
+
+void clock_tve0_enaclock(CLOCK_ENA ClockEna)
+{
+	unsigned int reg_val= 0;
+
+	if (ClockEna == _clock_disable){
+		reg_val = power_clk_read(CLOCK_PLL_CLK_EN);
+		power_clk_write(CLOCK_PLL_CLK_EN, reg_val&(~(0x1<<4)));
+	}else{
+		reg_val = power_clk_read(CLOCK_PLL_CLK_EN);
+		power_clk_write(CLOCK_PLL_CLK_EN, reg_val|(0x1<<4));
+	}
+	return;
+}
+
+void clock_tve1_enaclock(CLOCK_ENA ClockEna)
+{
+	unsigned int reg_val= 0;
+
+	if (ClockEna == _clock_disable){
+		reg_val = power_clk_read(CLOCK_PLL_CLK_EN);
+		power_clk_write(CLOCK_PLL_CLK_EN, reg_val&(~(0x1<<5)));
+	}else{
+		reg_val = power_clk_read(CLOCK_PLL_CLK_EN);
+		power_clk_write(CLOCK_PLL_CLK_EN, reg_val|(0x1<<5));
+	}
+	return;
+}
+
+void clock_sdio_enaclock(CLOCK_ENA ClockEna)
+{
+	unsigned int reg_val= 0;
+
+	if (ClockEna == _clock_disable){
+		reg_val = power_clk_read(CLOCK_PLL_CLK_EN);
+		power_clk_write(CLOCK_PLL_CLK_EN, reg_val&(~(0x1<<7)));
+	}else{
+		reg_val = power_clk_read(CLOCK_PLL_CLK_EN);
+		power_clk_write(CLOCK_PLL_CLK_EN, reg_val|(0x1<<7));
+	}
+	return;
+}
+
+void clock_audiopll_enaclock(CLOCK_ENA ClockEna)
+{
+	unsigned int reg_val= 0;
+
+	if (ClockEna == _clock_disable){
+		reg_val = power_clk_read(CLOCK_PLL_CLK_EN);
+		power_clk_write(CLOCK_PLL_CLK_EN, reg_val&(~(0x1<<11)));
+	}else{
+		reg_val = power_clk_read(CLOCK_PLL_CLK_EN);
+		power_clk_write(CLOCK_PLL_CLK_EN, reg_val|(0x1<<11));
+	}
+	return;
+}
+
+void clock_jpeg_enaclock(CLOCK_ENA ClockEna)
+{
+	unsigned int reg_val= 0;
+
+	if (ClockEna == _clock_disable){
+		reg_val = power_clk_read(CLOCK_PLL_CLK_EN);
+		power_clk_write(CLOCK_PLL_CLK_EN, reg_val&(~(0x1<<15)));
+	}else{
+		reg_val = power_clk_read(CLOCK_PLL_CLK_EN);
+		power_clk_write(CLOCK_PLL_CLK_EN, reg_val|(0x1<<15));
+	}
+	return;
+}
+
+void clock_coda_enaclock(CLOCK_ENA ClockEna)
+{
+	unsigned int reg_val= 0;
+
+	if (ClockEna == _clock_disable){
+		reg_val = power_clk_read(CLOCK_PLL_CLK_EN);
+		power_clk_write(CLOCK_PLL_CLK_EN, reg_val&(~(0x1<<16)));
+	}else{
+		reg_val = power_clk_read(CLOCK_PLL_CLK_EN);
+		power_clk_write(CLOCK_PLL_CLK_EN, reg_val|(0x1<<16));
+	}
+	return;
+}
+
+void clock_df_enaclock(CLOCK_ENA ClockEna)
+{
+	unsigned int reg_val= 0;
+
+	if (ClockEna == _clock_disable){
+		reg_val = power_clk_read(CLOCK_PLL_CLK_EN);
+		power_clk_write(CLOCK_PLL_CLK_EN, reg_val&(~(0x1<<17)));
+	}else{
+		reg_val = power_clk_read(CLOCK_PLL_CLK_EN);
+		power_clk_write(CLOCK_PLL_CLK_EN, reg_val|(0x1<<17));
+	}
+	return;
+}
+
+void clock_gpu_enaclock(CLOCK_ENA ClockEna)
+{
+	unsigned int reg_val= 0;
+
+	if (ClockEna == _clock_disable){
+		reg_val = power_clk_read(CLOCK_PLL_CLK_EN);
+		power_clk_write(CLOCK_PLL_CLK_EN, reg_val&(~(0x1<<18)));
+	}else{
+		reg_val = power_clk_read(CLOCK_PLL_CLK_EN);
+		power_clk_write(CLOCK_PLL_CLK_EN, reg_val|(0x1<<18));
+	}
+	return;
+}
+
+void clock_ahb2_enaclock(CLOCK_ENA ClockEna)
+{
+	unsigned int reg_val= 0;
+
+	if (ClockEna == _clock_disable){
+		reg_val = power_clk_read(CLOCK_PLL_CLK_EN);
+		power_clk_write(CLOCK_PLL_CLK_EN, reg_val&(~(0x1<<19)));
+	}else{
+		reg_val = power_clk_read(CLOCK_PLL_CLK_EN);
+		power_clk_write(CLOCK_PLL_CLK_EN, reg_val|(0x1<<19));
+	}
+	return;
+}
+
+void clock_crypto_enaclock(CLOCK_ENA ClockEna)
+{
+	unsigned int reg_val= 0;
+
+	if (ClockEna == _clock_disable){
+		reg_val = power_clk_read(CLOCK_PLL_CLK_EN);
+		power_clk_write(CLOCK_PLL_CLK_EN, reg_val&(~(0x1<<20)));
+	}else{
+		reg_val = power_clk_read(CLOCK_PLL_CLK_EN);
+		power_clk_write(CLOCK_PLL_CLK_EN, reg_val|(0x1<<20));
+	}
+	return;
+}
+
+void clock_xport_enaclock(CLOCK_ENA ClockEna)
+{
+	unsigned int reg_val= 0;
+
+	if (ClockEna == _clock_disable){
+		reg_val = power_clk_read(CLOCK_PLL_CLK_EN);
+		power_clk_write(CLOCK_PLL_CLK_EN, reg_val&(~(0x1<<21)));
+	}else{
+		reg_val = power_clk_read(CLOCK_PLL_CLK_EN);
+		power_clk_write(CLOCK_PLL_CLK_EN, reg_val|(0x1<<21));
+	}
+	return;
+}
+
+void clock_audio_enaclock(CLOCK_ENA ClockEna)
+{
+	unsigned int reg_val= 0;
+
+	if (ClockEna == _clock_disable){
+		reg_val = power_clk_read(CLOCK_PLL_CLK_EN);
+		power_clk_write(CLOCK_PLL_CLK_EN, reg_val&(~(0x1<<22)));
+	}else{
+		reg_val = power_clk_read(CLOCK_PLL_CLK_EN);
+		power_clk_write(CLOCK_PLL_CLK_EN, reg_val|(0x1<<22));
+	}
+	return;
+}
+
+void clock_video_enaclock(CLOCK_ENA ClockEna)
+{
+	unsigned int reg_val= 0;
+
+	if (ClockEna == _clock_disable){
+		reg_val = power_clk_read(CLOCK_PLL_CLK_EN);
+		power_clk_write(CLOCK_PLL_CLK_EN, reg_val&(~(0x1<<23)));
+	}else{
+		reg_val = power_clk_read(CLOCK_PLL_CLK_EN);
+		power_clk_write(CLOCK_PLL_CLK_EN, reg_val|(0x1<<23));
+	}
+	return;
+}
+void clock_dramporta_enaclock(CLOCK_ENA ClockEna)
+{
+	unsigned int reg_val= 0;
+
+	if (ClockEna == _clock_disable){
+		reg_val = power_clk_read(CLOCK_PLL_CLK_EN);
+		power_clk_write(CLOCK_PLL_CLK_EN, reg_val&(~(0x1<<24)));
+	}else{
+		reg_val = power_clk_read(CLOCK_PLL_CLK_EN);
+		power_clk_write(CLOCK_PLL_CLK_EN, reg_val|(0x1<<24));
+	}
+	return;
+}
+
+void clock_usb_enaclock(CLOCK_ENA ClockEna)
+{
+	unsigned int reg_val= 0;
+
+	if (ClockEna == _clock_disable){
+		reg_val = power_clk_read(CLOCK_PLL_CLK_EN);
+		power_clk_write(CLOCK_PLL_CLK_EN, reg_val&(~(0x1<<25)));
+	}else{
+		reg_val = power_clk_read(CLOCK_PLL_CLK_EN);
+		power_clk_write(CLOCK_PLL_CLK_EN, reg_val|(0x1<<25));
+	}
+	return;
+}
+
+void clock_cec_enaclock(CLOCK_ENA ClockEna)
+{
+	unsigned int reg_val= 0;
+
+	if (ClockEna == _clock_disable){
+		reg_val = power_clk_read(CLOCK_PLL_CLK_EN);
+		power_clk_write(CLOCK_PLL_CLK_EN, reg_val&(~(0x1<<26)));
+	}else{
+		reg_val = power_clk_read(CLOCK_PLL_CLK_EN);
+		power_clk_write(CLOCK_PLL_CLK_EN, reg_val|(0x1<<26));
+	}
+	return;
+}
+
+void clock_ir_enaclock(CLOCK_ENA ClockEna)
+{
+	unsigned int reg_val= 0;
+
+	if (ClockEna == _clock_disable){
+		reg_val = power_clk_read(CLOCK_PLL_CLK_EN);
+		power_clk_write(CLOCK_PLL_CLK_EN, reg_val&(~(0x1<<27)));
+	}else{
+		reg_val = power_clk_read(CLOCK_PLL_AVS_DIV);
+		power_clk_write(CLOCK_PLL_AVS_DIV, (reg_val&(~((0xf<<25)))) | (0x8<<25) ); // change to 135MHz IR clock
+		reg_val = power_clk_read(CLOCK_PLL_CLK_EN);
+		power_clk_write(CLOCK_PLL_CLK_EN, reg_val|(0x1<<27));
+	}
+	return;
+}
+
+void clock_vpb_enaclock(CLOCK_ENA ClockEna)
+{
+	unsigned int reg_val= 0;
+
+	if (ClockEna == _clock_disable){
+		reg_val = power_clk_read(CLOCK_PLL_CLK_EN);
+		power_clk_write(CLOCK_PLL_CLK_EN, reg_val&(~(0x1<<28)));
+	}else{
+		reg_val = power_clk_read(CLOCK_PLL_CLK_EN);
+		power_clk_write(CLOCK_PLL_CLK_EN, reg_val|(0x1<<28));
+	}
+	return;
+}
+
+void clock_vpbinput_enaclock(CLOCK_ENA ClockEna)
+{
+	unsigned int reg_val= 0;
+
+	if (ClockEna == _clock_disable){
+		reg_val = power_clk_read(CLOCK_PLL_CLK_EN);
+		power_clk_write(CLOCK_PLL_CLK_EN, reg_val&(~(0x1<<29)));
+	}else{
+		reg_val = power_clk_read(CLOCK_PLL_CLK_EN);
+		power_clk_write(CLOCK_PLL_CLK_EN, reg_val|(0x1<<29));
+	}
+	return;
+}
+
+void clock_cpu_enaclock(CLOCK_ENA ClockEna)
+{
+	unsigned int reg_val= 0;
+
+	if (ClockEna == _clock_disable){
+		reg_val = power_clk_read(CLOCK_PLL_CLK_EN);
+		power_clk_write(CLOCK_PLL_CLK_EN, reg_val&(~(0x1<<30)));
+	}else{
+		reg_val = power_clk_read(CLOCK_PLL_CLK_EN);
+		power_clk_write(CLOCK_PLL_CLK_EN, reg_val|(0x1<<30));
+	}
+	return;
+}
+
+void clock_cpusrc_enaclock(CLOCK_ENA ClockEna)
+{
+	unsigned int reg_val= 0;
+
+	if (ClockEna == _clock_disable){
+		reg_val = power_clk_read(CLOCK_PLL_CLK_EN);
+		power_clk_write(CLOCK_PLL_CLK_EN, reg_val&(~(0x1<<31)));
+	}else{
+		reg_val = power_clk_read(CLOCK_PLL_CLK_EN);
+		power_clk_write(CLOCK_PLL_CLK_EN, reg_val|(0x1<<31));
+	}
+	return;
+}
+
+void clock_hdmi_enaclock(CLOCK_ENA ClockEna)
+{
+	unsigned int clock_reset_state_before = 0, clock_reset_state_after = 0;
+
+	clock_reset_state_before = power_clk_read(CLOCK_CLK_RESET);
+	if (ClockEna == _clock_disable) {
+		clock_reset_state_after = clock_reset_state_before & ~(3 << 2);
+		printk(KERN_INFO "turn OFF HDMI clock: (0x%08x): before=%08x, after=%08x\n", CLOCK_CLK_RESET, clock_reset_state_before, clock_reset_state_after);
+	} else {
+		clock_reset_state_after = clock_reset_state_before | (3 << 2);
+		printk(KERN_INFO "turn ON HDMI clock: (0x%08x): before=%08x, after=%08x\n", CLOCK_CLK_RESET, clock_reset_state_before, clock_reset_state_after);
+	}
+	power_clk_write(CLOCK_CLK_RESET, clock_reset_state_after);
+	return;
+}
+
+EXPORT_SYMBOL(clock_hdmi_reset);
+EXPORT_SYMBOL(clock_disp0_setclock);
+EXPORT_SYMBOL(clock_disp1_setclock);
+EXPORT_SYMBOL(clock_audio_setclock);
+EXPORT_SYMBOL(clock_dac0_enaclock);
+EXPORT_SYMBOL(clock_dac1_enaclock);
+EXPORT_SYMBOL(clock_dram_enaclock);
+EXPORT_SYMBOL(clock_tve0_enaclock);
+EXPORT_SYMBOL(clock_tve1_enaclock);
+EXPORT_SYMBOL(clock_sdio_enaclock);
+EXPORT_SYMBOL(clock_audiopll_enaclock);
+EXPORT_SYMBOL(clock_jpeg_enaclock);
+EXPORT_SYMBOL(clock_coda_enaclock);
+EXPORT_SYMBOL(clock_df_enaclock);
+EXPORT_SYMBOL(clock_gpu_enaclock);
+EXPORT_SYMBOL(clock_ahb2_enaclock);
+EXPORT_SYMBOL(clock_crypto_enaclock);
+EXPORT_SYMBOL(clock_xport_enaclock);
+EXPORT_SYMBOL(clock_audio_enaclock);
+EXPORT_SYMBOL(clock_video_enaclock);
+EXPORT_SYMBOL(clock_dramporta_enaclock);
+EXPORT_SYMBOL(clock_usb_enaclock);
+EXPORT_SYMBOL(clock_cec_enaclock);
+EXPORT_SYMBOL(clock_ir_enaclock);
+EXPORT_SYMBOL(clock_vpb_enaclock);
+EXPORT_SYMBOL(clock_vpbinput_enaclock);
+EXPORT_SYMBOL(clock_cpu_enaclock);
+EXPORT_SYMBOL(clock_cpusrc_enaclock);
+EXPORT_SYMBOL(clock_hdmi_enaclock);
+
+static long cs_pwr_ioctl( struct file *file, unsigned int cmd, unsigned long arg)
+{
+	unsigned long flags;
+	char *name;
+    int pid_this;
+	name = ioctl_name(cmd);
+    pid_this = current->pid;
+	printk(KERN_INFO "(pid %d) %s: ioctl 0x%x{%s}(%lu)\n", pid_this, __func__, cmd, name, arg);
+	switch (cmd) {
+		case USB_POWER_DOWN:
+			spin_lock_irqsave(&cnc_pwr_lock, flags);
+			clock_usb_enaclock(arg);
+			spin_unlock_irqrestore(&cnc_pwr_lock, flags);
+			break;
+		case XPORT_CLK_DOWN:
+			spin_lock_irqsave(&cnc_pwr_lock, flags);
+			clock_xport_enaclock(arg);
+			spin_unlock_irqrestore(&cnc_pwr_lock, flags);
+			break;
+		case VPB_CLK_DOWN:
+			spin_lock_irqsave(&cnc_pwr_lock, flags);
+			clock_vpb_enaclock(arg);
+			spin_unlock_irqrestore(&cnc_pwr_lock, flags);
+			break;
+		case AUD_CLK_DOWN:
+			spin_lock_irqsave(&cnc_pwr_lock, flags);
+			clock_audio_enaclock(arg);
+			spin_unlock_irqrestore(&cnc_pwr_lock, flags);
+			break;
+		case CRYPTO_CLK_DOWN:
+			spin_lock_irqsave(&cnc_pwr_lock, flags);
+			clock_crypto_enaclock(arg);
+			spin_unlock_irqrestore(&cnc_pwr_lock, flags);
+			break;
+		case GRAPHICS_CLK_DOWN:
+			spin_lock_irqsave(&cnc_pwr_lock, flags);
+			clock_gpu_enaclock(arg);
+			spin_unlock_irqrestore(&cnc_pwr_lock, flags);
+			break;
+		case DF_CLK_DOWN:
+			spin_lock_irqsave(&cnc_pwr_lock, flags);
+			clock_df_enaclock(arg);
+			spin_unlock_irqrestore(&cnc_pwr_lock, flags);
+			break;
+		case VIDECOD_CLK_DOWN:
+			spin_lock_irqsave(&cnc_pwr_lock, flags);
+			clock_coda_enaclock(arg);
+			spin_unlock_irqrestore(&cnc_pwr_lock, flags);
+			break;
+		case SD_CLK_DOWN:
+			spin_lock_irqsave(&cnc_pwr_lock, flags);
+			clock_sdio_enaclock(arg);
+			spin_unlock_irqrestore(&cnc_pwr_lock, flags);
+			break;
+		case TVE1_CLK_DOWN:
+			spin_lock_irqsave(&cnc_pwr_lock, flags);
+			clock_tve1_enaclock(arg);
+			spin_unlock_irqrestore(&cnc_pwr_lock, flags);
+			break;
+		case TVE0_CLK_DOWN:
+			spin_lock_irqsave(&cnc_pwr_lock, flags);
+			clock_tve0_enaclock(arg);
+			spin_unlock_irqrestore(&cnc_pwr_lock, flags);
+			break;
+		case VDAC0_POWER_DOWN:
+			spin_lock_irqsave(&cnc_pwr_lock, flags);
+			clock_dac0_enaclock(arg);
+			spin_unlock_irqrestore(&cnc_pwr_lock, flags);
+			break;
+		case VDAC1_POWER_DOWN:
+			spin_lock_irqsave(&cnc_pwr_lock, flags);
+			clock_dac1_enaclock(arg);
+			spin_unlock_irqrestore(&cnc_pwr_lock, flags);
+			break;
+		case VID_POWER_DOWN:
+			spin_lock_irqsave(&cnc_pwr_lock, flags);
+            clock_video_enaclock(arg);
+			spin_unlock_irqrestore(&cnc_pwr_lock, flags);
+            break;
+		case AUD_PLLCLK_DOWN:
+			spin_lock_irqsave(&cnc_pwr_lock, flags);
+            clock_audiopll_enaclock(arg);
+			spin_unlock_irqrestore(&cnc_pwr_lock, flags);
+            break;
+		/* Pretend to do these, since they don't seem to be supported any more (at least not
+		   in the way they were on the 1800L). */
+		case AUDDACIF_CLK_DOWN:
+		case AUD_POWER_DOWN:
+			break;
+		case HDMI_POWER_DOWN:
+			spin_lock_irqsave(&cnc_pwr_lock, flags);
+			clock_hdmi_enaclock(arg);
+			spin_unlock_irqrestore(&cnc_pwr_lock, flags);
+			break;
+        case JPEG_CLK_DOWN:
+			spin_lock_irqsave(&cnc_pwr_lock, flags);
+            clock_jpeg_enaclock(arg);
+			spin_unlock_irqrestore(&cnc_pwr_lock, flags);
+			break;
+        case AHB2_CLK_DOWN:
+			spin_lock_irqsave(&cnc_pwr_lock, flags);
+            clock_ahb2_enaclock(arg);
+			spin_unlock_irqrestore(&cnc_pwr_lock, flags);
+			break;
+        case CEC_CLK_DOWN:
+			spin_lock_irqsave(&cnc_pwr_lock, flags);
+            clock_cec_enaclock(arg);
+			spin_unlock_irqrestore(&cnc_pwr_lock, flags);
+			break;
+        case IR_CLK_DOWN:
+			spin_lock_irqsave(&cnc_pwr_lock, flags);
+            clock_ir_enaclock(arg);
+			spin_unlock_irqrestore(&cnc_pwr_lock, flags);
+            break;
+        case VPBIN_CLK_DOWN:
+			spin_lock_irqsave(&cnc_pwr_lock, flags);
+            clock_vpbinput_enaclock(arg);
+			spin_unlock_irqrestore(&cnc_pwr_lock, flags);
+            break;
+		default:
+			return -EINVAL;
+	}
+	return 0;
+}
+
+static struct class *cnc_powerctl_class;
+static struct proc_dir_entry *power_proc_entry = NULL;
+static struct file_operations cnc_powerctl_fops = {
+	.owner	= THIS_MODULE,
+	.unlocked_ioctl		= cs_pwr_ioctl,
+};
+
+static int power_proc_write(struct file *file, const char __user *buffer,
+			   unsigned long count, void *data)
+{
+	int cmd_length;
+	const char *cmd_line = buffer;
+
+	cmd_length = strlen(cmd_line);
+
+	if (strncmp("dumpreg",cmd_line,7) == 0) {
+		unsigned int count = 0;
+
+		for(count = 0; count < 0x400; count +=4){
+			switch(count){
+				case 0x0:
+					printk("\n CLOCK_ID_BASE\n");
+					break;
+				case 0x100:
+					printk("\n CLOCK_PLL_BASE\n");
+					break;
+				case 0x140:
+					printk("\n CLOCK_MUX_BASE\n");
+					break;
+				case 0x200:
+					printk("\n CLOCK_RESET_BASE\n");
+					break;
+				case 0x300:
+					printk("\n PLL_PARA_BASE\n");
+					break;
+				case 0x350:
+					printk("\n VDAC_BASE\n");
+					break;
+				case 0x360:
+					printk("\n CPU_PWR_BASE\n");
+					break;
+			}
+			printk(" addr[0x%08x] = 0x%08x \n", CNC1900_ID_SCS + count, power_clk_read(CNC1900_ID_SCS+count));
+		}
+	}
+	else if(strncmp("dac0_enable",cmd_line,11) == 0){
+		printk("dac0_enable\n");
+		clock_dac0_enaclock(1);
+	}
+	else if(strncmp("dac0_disable",cmd_line,12) == 0){
+		printk("dac0_disable\n");
+		clock_dac0_enaclock(0);
+	}
+	else if(strncmp("dac1_enable",cmd_line,11) == 0){
+		printk("dac1_enable\n");
+		clock_dac1_enaclock(1);
+	}
+	else if(strncmp("dac1_disable",cmd_line,12) == 0){
+		printk("dac1_disable\n");
+		clock_dac1_enaclock(0);
+	}
+
+	return count;
+}
+
+#define POWER_CLOCK_MAJOR 500
+static int __init
+cnc1900_power_clock_init(void)
+{
+	struct device *power_clk_device = NULL;
+	dev_t maj_min = MKDEV(POWER_CLOCK_MAJOR, 1);
+
+	if (NULL == power_clk_base) {
+		if (!(power_clk_base = (volatile unsigned char *)ioremap(CNC1900_ID_SCS, CLOCK_REG_SIZE))) {
+			printk(KERN_ERR "ERROR: cnc1900_clock_init ioremap failed\n");
+			return (-1);
+		}
+		// power_clk_base_ui = (volatile uint32_t *)power_clk_base;
+	}
+
+	if (register_chrdev(POWER_CLOCK_MAJOR, "cnc1900_powerctl", &cnc_powerctl_fops)){
+		iounmap((void *)power_clk_base);
+		printk(KERN_ERR "ERROR: cnc1900_clock_init register_chrdev failed\n");
+		return -ENODEV;
+	}
+
+	cnc_powerctl_class = class_create(THIS_MODULE,"cnc1900_powerctl");
+	if (IS_ERR(cnc_powerctl_class)){
+		printk(KERN_ERR "ERROR: cnc1900_clock_init class_create failed\n");
+		iounmap((void *)power_clk_base);
+		unregister_chrdev(POWER_CLOCK_MAJOR, "cnc_powerctl");
+		cnc_powerctl_class = NULL;
+		return -ENODEV;
+	}
+
+	power_clk_device = device_create(cnc_powerctl_class, NULL, maj_min, NULL, "cs_pwr");
+	if (IS_ERR(power_clk_device)) {
+		printk(KERN_ERR "ERROR: cnc1900_clock_init device_create failed\n");
+		iounmap((void *)power_clk_base);
+		class_destroy(cnc_powerctl_class);
+		unregister_chrdev(POWER_CLOCK_MAJOR, "cnc_powerctl");
+		cnc_powerctl_class = NULL;
+		return -ENODEV;
+	}
+
+	power_proc_entry = create_proc_entry("cnc_powerctl", 0, NULL);
+	if (NULL != power_proc_entry) {
+		power_proc_entry->write_proc = power_proc_write;
+	}
+	else{
+		iounmap((void *)power_clk_base);
+		device_destroy(cnc_powerctl_class, maj_min);
+		class_destroy(cnc_powerctl_class);
+		unregister_chrdev(POWER_CLOCK_MAJOR, "cnc_powerctl");
+		printk(KERN_ERR "ERROR: cnc1900_power_clock_init create_proc_entry failed\n");
+		return (-1);
+	}
+
+	printk("cnc1900_power_clock_init done.\n");
+	return 0;
+}
+
+static void __exit
+cnc1900_power_clock_exit(void)
+{
+	dev_t maj_min = MKDEV(POWER_CLOCK_MAJOR, 1);
+	iounmap((void *)power_clk_base);
+	device_destroy(cnc_powerctl_class, maj_min);
+	class_destroy(cnc_powerctl_class);
+	unregister_chrdev(POWER_CLOCK_MAJOR, "cnc_powerctl");
+
+	if (NULL != power_proc_entry){
+		remove_proc_entry("cnc_powerctl", NULL);
+	}
+	printk("cnc1900_power_clock_exit done.\n");
+	return;
+}
+
+postcore_initcall(cnc1900_power_clock_init);
+
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/arch/arm/mach-celestial/cnc19xx.c linux-linaro-3.4-2012.05-1_cavium/arch/arm/mach-celestial/cnc19xx.c
--- linux-linaro-3.4-2012.05-1_original/arch/arm/mach-celestial/cnc19xx.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/arch/arm/mach-celestial/cnc19xx.c	2015-07-15 15:16:57.551868000 +0800
@@ -0,0 +1,546 @@
+/*
+ *  arch/arm/mach-celestial/cnc19xx.c
+ *  Copyright (C) 2011 Cavium
+ */
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/mach/map.h>
+#include <asm/setup.h>
+#include <linux/memblock.h>
+#include <asm/hardware/gic.h>
+#include <asm/hardware/cache-l2x0.h>
+
+#include <linux/dma-mapping.h>
+#include <linux/serial_8250.h>
+#include <linux/spi/flash.h>
+#include <linux/spi/spi.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/dw_mmc.h>
+#ifdef CONFIG_PM
+#include <linux/suspend.h>
+#endif
+
+#include <mach/hardware.h>
+#include <mach/nand.h>
+#ifdef CONFIG_SW_SUPPORT
+#include <mach/smc.h>
+#endif
+
+extern __init int platform_add_usbs(void);
+extern __init int pmem_register(void);
+
+#ifdef CONFIG_PM
+static int cnc1900_pm_suspend(suspend_state_t desired_state);
+#endif
+
+static struct map_desc cs_io_desc[] __initdata = {
+	/**
+	 * CPU CA9 Private Memory Region:
+	 */
+	{
+		.virtual	= IO_ADDRESS(CNC1900_CA9_PMR),
+		.pfn		= __phys_to_pfn(CNC1900_CA9_PMR),
+		.length		= SZ_8K,
+		.type		= MT_DEVICE,
+	},
+	/**
+	 * L2 Cache Controller:
+	 */
+	{
+		.virtual    = IO_ADDRESS(CNC1900_L2X0),
+		.pfn        = __phys_to_pfn(CNC1900_L2X0),
+		.length     = SZ_4K,
+		.type       = MT_DEVICE,
+	},
+	/**
+	 * On-Chip Peripherals I/O space:
+	 */
+	{
+		.virtual	= IO_ADDRESS(CNC1900_PERIPH_BASE),
+		.pfn		= __phys_to_pfn(CNC1900_PERIPH_BASE),
+		.length		= CNC1900_PERIPH_SIZE,
+		.type		= MT_DEVICE,
+	},
+	{
+		.virtual	=  VA_IO_MEDIA_PROCESSOR_BASE,
+		.pfn		= __phys_to_pfn(PA_IO_MEDIA_PROCESSOR_BASE),
+		.length		= IO_MEDIA_PROCESSOR_SIZE,
+		.type		= MT_DEVICE
+	},
+	{
+		.virtual	=  VA_IO_SYSTEM_CONTROL_BASE,
+		.pfn		= __phys_to_pfn(PA_IO_SYSTEM_CONTROL_BASE),
+		.length		= IO_SYSTEM_CONTROL_SIZE,
+		.type		= MT_DEVICE
+	},
+};
+
+#ifdef CONFIG_PM
+static struct platform_suspend_ops cnc1900_pm_suspend_ops = {
+    .valid = suspend_valid_only_mem,
+    .enter = cnc1900_pm_suspend,
+};
+#endif
+
+static void __init plat_map_io(void)
+{
+	iotable_init(cs_io_desc, ARRAY_SIZE(cs_io_desc));
+}
+
+#ifdef CONFIG_PM
+static int cnc1900_pm_suspend(suspend_state_t S)
+{
+    /* Note: There appear to be several drivers that do not properly suspend,
+       notably the phy0 driver and the ehci-cnc18xx driver, and so we have to
+       resort to some hackery. This function does nothing, and the actual
+       sleeping of the CPU and DDR takes place in kernel/power/suspend.c. Most
+       of the clock-gating still happens in the "lowpower" and "wakeup"
+       scripts. The final step of the lowpower script is to write 'mem' to
+       /sys/power/state, kicking off the sleeping of the CPU. The only thing
+       we do in the cnc1900 module is to copy the naptime routine to the
+       line buffer. */
+    printk(KERN_INFO "entering %s with requested state %d\n", __func__, S);
+    return 0;
+}
+#endif
+
+static struct plat_serial8250_port plat_serial[] = {
+	{
+		.membase    = (void *)IO_ADDRESS(CNC1900_UART0),
+		.mapbase    = CNC1900_UART0,
+		.irq        = UART0_IRQ,
+		.uartclk    = 45000000,
+		.regshift   = 2,
+		.iotype		= UPIO_MEM32,
+		.type       = PORT_16550A,
+		.flags      = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_FIXED_TYPE,
+	},
+#ifdef CONFIG_CELESTIAL_UART1
+	{
+		.membase    = (void *)IO_ADDRESS(CNC1900_UART1),
+		.mapbase    = CNC1900_UART1,
+		.irq        = UART1_IRQ,
+		.uartclk    = 45000000,
+		.regshift   = 2,
+		.iotype		= UPIO_MEM32,
+		.type       = PORT_16550A,
+		.flags      = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_FIXED_TYPE,
+	},
+#endif
+	{
+	}
+};
+
+static struct platform_device dev_uart = {
+	.name   = "serial8250",
+	.id     = PLAT8250_DEV_PLATFORM,
+	.dev = {
+		.platform_data = plat_serial,
+	},
+};
+
+
+
+static struct resource eth0_resources[] = {
+	{
+		.start		= CNC1900_ETH,
+		.end		= CNC1900_ETH + 0x1000 - 1,
+		.flags		= IORESOURCE_MEM,
+	}, {
+		.start		= ETH0_IRQ,
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device dev_eth0 = {
+	.name = "cnc-eth",
+	.id	= 0,
+	.resource = eth0_resources,
+	.num_resources = ARRAY_SIZE(eth0_resources),
+};
+
+#ifdef CONFIG_CELESTIAL_MULT_ETH
+static struct resource eth1_resources[] = {
+	{
+		.start		= CNC1900_ETH,
+		.end		= CNC1900_ETH + 0x1000 - 1,
+		.flags		= IORESOURCE_MEM,
+	}, {
+		.start		= ETH1_IRQ,
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device dev_eth1 = {
+	.name = "cnc-eth",
+	.id	= 1,
+	.resource = eth1_resources,
+	.num_resources = ARRAY_SIZE(eth1_resources),
+};
+#endif
+
+static struct plat_cncnand_port cncnand_ports[] = {
+	{
+		.membase = CNC1900_SM_CS0,
+		.reg_base = (void *)IO_ADDRESS(CNC1900_SMC),
+		.reg_port = (void *)IO_ADDRESS(CNC1900_SMC_CS0),
+		.cle = MASK_CLE,
+		.ale = MASK_ALE,
+	}, {
+	}
+};
+
+static struct platform_device dev_nand = {
+	.name = "cnc-nand",
+	.id	= -1,
+	.dev = {
+		.platform_data = cncnand_ports,
+	},
+};
+
+static struct resource spi_resources[] = {
+	{
+		.start		= CNC1900_SPI,
+		.end		= CNC1900_SPI + SZ_4K - 1,
+		.flags		= IORESOURCE_MEM,
+	}, {
+		.start		= SPI_IRQ,
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device dev_spi = {
+	.name = "dw_spi_mmio",
+	.id	= -1,
+	.resource = spi_resources,
+	.num_resources = ARRAY_SIZE(spi_resources),
+};
+
+static const struct flash_platform_data spi_slave_data = {
+	.name = "cnc-spi",
+	.parts = NULL,
+	.nr_parts = 0,
+};
+
+static struct spi_board_info __initdata spi_slave_info[] = {
+	{
+		.modalias = "mx25u6435f",
+		.mode = SPI_CPHA | SPI_CPOL,
+		.platform_data = &spi_slave_data,
+		.max_speed_hz = 2000000,
+	},
+};
+
+static int dwmci_init(u32 slot_id, irq_handler_t handler, void *data)
+{
+	return 0;
+}
+
+static int dwmci_get_bus_wd(u32 slot_id)
+{
+	return 4;
+}
+
+static struct dw_mci_board dwci_pdata = {
+	.num_slots			= 1,
+	.detect_delay_ms	= 200,
+	.bus_hz				= 90000000,
+//	.caps				= MMC_CAP_UHS_SDR104 | MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_DDR50 | MMC_CAP_1_8V_DDR,
+	.caps				= MMC_CAP_UHS_SDR104 | MMC_CAP_UHS_SDR50 | MMC_CAP_SDIO_IRQ,
+	.caps2				= MMC_CAP2_BOOTPART_NOACC,
+	.init				= dwmci_init,
+	.get_bus_wd			= dwmci_get_bus_wd,
+};
+
+static u64 dwmci_dmamask = DMA_BIT_MASK(32);
+
+static struct resource mmc0_resources[] = {
+	{
+		.start		= CNC1900_SD0,
+		.end		= CNC1900_SD0 + SZ_4K - 1,
+		.flags		= IORESOURCE_MEM,
+	}, {
+		.start		= SD0_IRQ,
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device dev_mmc0 = {
+	.name	= "dw_mmc",
+	.id		= 0,
+	.resource	= mmc0_resources,
+	.num_resources	= ARRAY_SIZE(mmc0_resources),
+	.dev = {
+		.dma_mask = &dwmci_dmamask,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
+		.platform_data	= &dwci_pdata,
+	},
+};
+
+#ifdef CONFIG_CELESTIAL_MULT_MMC
+static struct resource mmc1_resources[] = {
+	{
+		.start		= CNC1900_SD1,
+		.end		= CNC1900_SD1 + SZ_4K - 1,
+		.flags		= IORESOURCE_MEM,
+	}, {
+		.start		= SD1_IRQ,
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device dev_mmc1 = {
+	.name	= "dw_mmc",
+	.id		= 1,
+	.resource	= mmc1_resources,
+	.num_resources	= ARRAY_SIZE(mmc1_resources),
+	.dev = {
+		.dma_mask = &dwmci_dmamask,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
+		.platform_data	= &dwci_pdata,
+	},
+};
+#endif
+
+static struct resource wdt_resources[] = {
+	{
+		.start		= CNC1900_CA9_TWD,
+		.end		= CNC1900_CA9_TWD + SZ_4K - 1,
+		.flags		= IORESOURCE_MEM,
+	}, {
+		.start		= CPU_WDT_TIMER_IRQ,
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device dev_wdt = {
+	.name = "mpcore_wdt",
+	.id	= -1,
+	.resource = wdt_resources,
+	.num_resources = ARRAY_SIZE(wdt_resources),
+};
+
+static struct platform_device snd_i2s = {
+	.name = "cnc-snd-i2s",
+	.id	= -1,
+};
+
+static struct resource i2s_resources[] = {
+	{
+		.start		= CNC1900_AUDIO_I2S,
+		.end		= CNC1900_AUDIO_I2S + SZ_4K - 1,
+		.flags		= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device pcm_i2s = {
+	.name = "cnc-pcm-i2s",
+	.id	= -1,
+	.resource = i2s_resources,
+	.num_resources = ARRAY_SIZE(i2s_resources),
+};
+
+static struct resource hdmi_resources[] = {
+	{
+		.start		= CNC1900_HDMI,
+		.end		= CNC1900_HDMI + SZ_8K - 1,
+		.flags		= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device hdmi_i2s = {
+	.name = "hdmi-i2s-codec",
+	.id	= -1,
+	.resource = hdmi_resources,
+	.num_resources = ARRAY_SIZE(hdmi_resources),
+};
+
+static struct platform_device *devices[] __initdata = {
+	&dev_spi,
+	&dev_uart,
+	&dev_nand,
+	&dev_eth0,
+#ifdef CONFIG_CELESTIAL_MULT_ETH
+	&dev_eth1,
+#endif
+	&dev_mmc0,
+#ifdef CONFIG_CELESTIAL_MULT_MMC
+	&dev_mmc1,
+#endif
+	&dev_wdt,
+#ifdef CONFIG_SOUND
+	&snd_i2s,
+	&pcm_i2s,
+	&hdmi_i2s,
+#endif
+};
+
+#define CNC1900_SMEM_RESERVED 0x8001FFF0
+
+static inline void plat_restart(char mode, const char *cmd)
+{
+	volatile unsigned int *p;
+	char *m = ioremap(CNC1900_SMEM_RESERVED, 0xF);
+	memset(m, 0x0, 0xF);
+	if (cmd != NULL)
+		strcpy(m, cmd);
+
+	/* WatchDog base */
+	p = ioremap(CNC1900_CA9_TWD, 0x3C);
+	p[0x28>>2] = 0x8;
+	p[0x20>>2] = 100000;
+	p[0x28>>2] = 0xD;
+}
+
+static int l2x0_enable = 1;
+
+static int __init l2x0_disable(char *s)
+{
+	l2x0_enable = 0;
+	return 1;
+}
+__setup ("nol2x0", l2x0_disable);
+
+static void __init plat_init_machine(void)
+{
+#ifdef CONFIG_PM
+    volatile void *line_buffer_addr = NULL;
+    volatile uint32_t *s, *d;
+
+    extern void naptime(void);
+    extern void INSN_END(void);
+#endif
+#ifdef CONFIG_CACHE_L2X0
+    void __iomem *l2x0_base = (void *)IO_ADDRESS(CNC1900_L2X0);
+
+    if(l2x0_enable){
+#ifdef CONFIG_SW_SUPPORT /* Sierraware Tzone support */
+	    /* SETUP1: arg1 - tag ram latency, arg2 - data ram latency,
+	       arg3 - prefetch offset(kept as default value)  */
+	    sw_smc(SMC_CMD_L2X0SETUP1, 0x111, 0x111, 0x0);
+
+#else /* CONFIG_SW_SUPPORT */
+	    unsigned int data;
+
+		//enable dynamic clock gating and standby mode of L2 cache.
+		data = readl(l2x0_base + L2X0_POWER_CTRL); //read power control register of L2 cache
+		data = data | 0x3;                         //prepare data
+		writel(data, l2x0_base + L2X0_POWER_CTRL); //write power control register of L2 cache
+
+		/* set RAM latencies to 2 cycle */
+		writel(0x111, l2x0_base + L2X0_TAG_LATENCY_CTRL);
+		writel(0x111, l2x0_base + L2X0_DATA_LATENCY_CTRL);
+
+#endif /* CONFIG_SW_SUPPORT */
+
+		l2x0_init(l2x0_base, 0x00000000, 0xffffffff);
+	}else{
+		printk(KERN_INFO "Disable L2X0 by cmdline\n");
+	}
+#endif  /* CONFIG_CACHE_L2X0 */
+
+	platform_add_devices(devices, ARRAY_SIZE(devices));
+	spi_register_board_info(spi_slave_info, ARRAY_SIZE(spi_slave_info));
+
+	platform_add_usbs();
+
+#ifdef CONFIG_ANDROID_PMEM
+	pmem_register();
+#endif
+#ifdef CONFIG_PM
+    /* Allow 16 words storage. */
+    line_buffer_addr = ioremap_nocache(0x80000040, 0x10000);
+
+    /* Copy the storage routine into the line buffer. */
+    printk(KERN_INFO "Copying naptime routine to line buffer\n");
+    d = (volatile uint32_t *)line_buffer_addr;
+    for (s = (volatile uint32_t *)naptime; s != (volatile uint32_t *)INSN_END; ++s) {
+        *d++ = *s;
+    }
+
+    printk(KERN_INFO "calling suspend_set_ops for cnc1900\n");
+    suspend_set_ops(&cnc1900_pm_suspend_ops);
+#endif
+}
+
+static void __init plat_gic_init(void)
+{
+	gic_init(0, -1, (void *)IO_ADDRESS(CNC1900_CA9_GIC_DIST), (void *)IO_ADDRESS(CNC1900_CA9_GIC_CPUIF));
+}
+
+#ifdef CONFIG_ANDROID_PMEM
+	#define FIRST_ZONE_SIZE (PMEM_REGION & 0xFFF00000)
+#else
+	#define FIRST_ZONE_SIZE (XPORT_REGION & 0xFFF00000)
+#endif
+
+static void __init plat_fixup(struct tag *t, char **c, struct meminfo *mi)
+{
+    printk("FIRST_ZONE_SIZE is 0x%x\n", FIRST_ZONE_SIZE);
+
+#ifdef CONFIG_SW_SUPPORT
+	mi->nr_banks = 1;
+	mi->bank[0].start = 0x00;
+	mi->bank[0].size = SZ_16M;
+#ifdef SW_FEED_VIDEO
+#if (FIRST_ZONE_SIZE > SZ_128M)
+        mi->nr_banks = 2;
+	mi->bank[1].start = SZ_128M;
+	mi->bank[1].size = FIRST_ZONE_SIZE - SZ_128M;
+
+    printk("FIRST_ZONE_SIZE is 0x%x, mi->bank[1].size is 0x%x\n", FIRST_ZONE_SIZE, mi->bank[1].size);
+#if (CELESTIAL_MEM_SIZE > 256)
+	mi->nr_banks = 3;
+	mi->bank[2].start = SZ_256M;
+	mi->bank[2].size = (CELESTIAL_MEM_SIZE-256)*SZ_1M;
+#endif
+#else
+#if (CELESTIAL_MEM_SIZE > 256)
+	mi->nr_banks = 2;
+	mi->bank[1].start = SZ_256M;
+	mi->bank[1].size = (CELESTIAL_MEM_SIZE-256)*SZ_1M;
+#endif
+#endif
+#else
+	mi->nr_banks = 2;
+	mi->bank[1].start = SZ_32M;
+	mi->bank[1].size = FIRST_ZONE_SIZE - SZ_32M;
+#if (CELESTIAL_MEM_SIZE > 256)
+	mi->nr_banks = 3;
+	mi->bank[2].start = SZ_256M;
+	mi->bank[2].size = (CELESTIAL_MEM_SIZE-256)*SZ_1M;
+#endif
+#endif
+#else
+	mi->nr_banks = 1;
+	mi->bank[0].start = 0x00;
+	mi->bank[0].size = FIRST_ZONE_SIZE;
+#if (CELESTIAL_MEM_SIZE > 256)
+	mi->nr_banks = 2;
+	mi->bank[1].start = SZ_256M;
+	mi->bank[1].size = (CELESTIAL_MEM_SIZE-256)*SZ_1M;
+#endif
+#endif
+}
+
+void __init plat_reserve(void)
+{
+	memblock_reserve(PHYS_OFFSET, 0x1000000);
+}
+
+extern struct sys_timer plat_timer;
+
+MACHINE_START(CELESTIAL, "CNC1900")
+	.timer       = &plat_timer,
+	.fixup       = plat_fixup,
+	.map_io	     = plat_map_io,
+	.init_irq    = plat_gic_init,
+	.handle_irq  = gic_handle_irq,
+	.init_machine = plat_init_machine,
+#ifdef CONFIG_SW_SUPPORT
+	.reserve = plat_reserve,
+#endif
+//	.dma_zone_size = FIRST_ZONE_SIZE,
+	.restart = plat_restart,
+MACHINE_END
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/arch/arm/mach-celestial/cnc19xx_mem_info.c linux-linaro-3.4-2012.05-1_cavium/arch/arm/mach-celestial/cnc19xx_mem_info.c
--- linux-linaro-3.4-2012.05-1_original/arch/arm/mach-celestial/cnc19xx_mem_info.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/arch/arm/mach-celestial/cnc19xx_mem_info.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,29 @@
+/*
+ *  arch/arm/mach-celestial/cnc19xx.c
+ *  Copyright (C) 2011 Cavium
+ */
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/mach/map.h>
+#include <asm/setup.h>
+
+#include <asm/hardware/gic.h>
+#include <asm/hardware/cache-l2x0.h>
+
+#include <linux/dma-mapping.h>
+#include <linux/serial_8250.h>
+#include <linux/spi/flash.h>
+#include <linux/spi/spi.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/dw_mmc.h>
+#ifdef CONFIG_PM
+#include <linux/suspend.h>
+#endif
+
+#include <mach/hardware.h>
+#include <mach/nand.h>
+
+int mCncBlobSize = BLOB_SIZE;
+int mCncBlobBase = BLOB_BASE;
+
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/arch/arm/mach-celestial/hotplug.c linux-linaro-3.4-2012.05-1_cavium/arch/arm/mach-celestial/hotplug.c
--- linux-linaro-3.4-2012.05-1_original/arch/arm/mach-celestial/hotplug.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/arch/arm/mach-celestial/hotplug.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,44 @@
+/*
+ * arch/arm/mach-celestial/hotplug.c
+ * Cavium CNC1900 Timer System, 2013
+ * 
+ * This file is licensed unde the terms of the GNU General Public License 
+ * version 2. This program is licensed "as is" without any warranty of 
+ * any kind, whether express or implied.
+ */
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/smp.h>
+
+#include <asm/cacheflush.h>
+#include <asm/smp_plat.h>
+#include <asm/cp15.h>
+
+extern volatile int pen_release;
+
+int platform_cpu_kill(unsigned int cpu)
+{
+	printk("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nplatform_cpu_kill\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
+
+	return 1;
+}
+
+/*
+ * platform-specific code to shutdown a CPU
+ *
+ * Called with IRQs disabled
+ */
+void platform_cpu_die(unsigned int cpu)
+{
+	printk("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nplatform_cpu_die\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
+}
+
+int platform_cpu_disable(unsigned int cpu)
+{
+	printk("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nplatform_cpu_disable\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
+	/*
+	 * we don't allow CPU 0 to be shutdown (it is still too special
+	 * e.g. clock tick interrupts)
+	 */
+	return cpu == 0 ? -EPERM : 0;
+}
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/arch/arm/mach-celestial/include/mach/cnc1900_clock_reg.h linux-linaro-3.4-2012.05-1_cavium/arch/arm/mach-celestial/include/mach/cnc1900_clock_reg.h
--- linux-linaro-3.4-2012.05-1_original/arch/arm/mach-celestial/include/mach/cnc1900_clock_reg.h	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/arch/arm/mach-celestial/include/mach/cnc1900_clock_reg.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,79 @@
+#ifndef _CNC1900_CLOCK_REG_H_
+#define _CNC1900_CLOCK_REG_H_
+
+#ifdef __cplusplus
+extern "C"{
+#endif
+typedef enum _CLOCK_REG_BANK_
+{
+  CNC1900_ID_SCS                    =0xB2100000,
+
+  CLOCK_ID_BASE                     =(CNC1900_ID_SCS+(0<<2)),
+  CLOCK_PLL_BASE                    =(CNC1900_ID_SCS+(0x40<<2)),
+  CLOCK_MUX_BASE                    =(CNC1900_ID_SCS+(0x50<<2)),
+  CLOCK_RESET_BASE                  =(CNC1900_ID_SCS+(0x80<<2)),
+  PLL_PARA_BASE                     =(CNC1900_ID_SCS+(0xC0<<2)),
+  VDAC_BASE                         =(CNC1900_ID_SCS+(0xD4<<2)),
+  CPU_PWR_BASE                      =(CNC1900_ID_SCS+(0xD8<<2)),
+
+  CLOCK_ID_LO                       =(CLOCK_ID_BASE+(0<<2)),
+  CLOCK_ID_HI                       =(CLOCK_ID_BASE+(1<<2)),
+
+  //B2100100
+  CLOCK_PLL_AVS_DIV                 =(CLOCK_PLL_BASE+(1<<2)),       
+  CLOCK_AUD_DIV                     =(CLOCK_PLL_BASE+(6<<2)),
+  CLOCK_CLK_GEN_DIV                 =(CLOCK_PLL_BASE+(8<<2)),
+
+  //B2100140
+  CLOCK_PLL_CLK_EN                  =(CLOCK_MUX_BASE+(0<<2)),
+  CLK_SRC_SEL                       =(CLOCK_MUX_BASE+(1<<2)),
+  CLOCK_TVE_DIV_N		            =(CLOCK_MUX_BASE+(2<<2)),
+
+  //B2100200
+  CLOCK_SOFT_RESET                  =(CLOCK_RESET_BASE+(0<<2)),
+  CLOCK_CLK_RESET                   =(CLOCK_RESET_BASE+(1<<2)),
+  CLOCK_PLL_SLEEP_N                 =(CLOCK_RESET_BASE+(3<<2)),
+  CLOCK_HDMI_CLK_SEL                =(CLOCK_RESET_BASE+(6<<2)),
+  SB_CTRL                           =(CLOCK_RESET_BASE+(7<<2)),
+  SB_STATUS                         =(CLOCK_RESET_BASE+(8<<2)),
+
+  //B2100300
+  CPUCLK_ST_INT                     =(PLL_PARA_BASE+ (5<<2)),
+  PLL_CPU_DIV                       =(PLL_PARA_BASE+ (6<<2)),
+  PLL_TVE_PARA_Q                    =(PLL_PARA_BASE+ (7<<2)),
+  PLL_TVE_PARA_F                    =(PLL_PARA_BASE+ (8<<2)),
+  PLL_AUD_PARA_Q                    =(PLL_PARA_BASE+ (9<<2)),
+  PLL_AUD_PARA_F                    =(PLL_PARA_BASE+ (0x0A<<2)),
+  PLL_SYS_PARA_Q                    =(PLL_PARA_BASE+ (0x0B<<2)),
+  PLL_SYS_PARA_F                    =(PLL_PARA_BASE+ (0x0C<<2)),
+  PLL_DDR_PARA_Q                    =(PLL_PARA_BASE+ (0x0D<<2)),
+  PLL_DDR_PARA_F                    =(PLL_PARA_BASE+ (0x0E<<2)),
+  PLL_NEWDIV                        =(PLL_PARA_BASE+ (0x0F<<2)),
+  PLL_CODA_PARA_Q                   =(PLL_PARA_BASE+ (0x11<<2)),
+  PLL_CODA_PARA_F                   =(PLL_PARA_BASE+ (0x12<<2)),
+  CPU_PWR_MODE                   	=(PLL_PARA_BASE+ (0x20<<2)),
+  PLL_CLK_EN                   		=(PLL_PARA_BASE+ (0x50<<2)),
+
+  //B2100350
+  VDAC0_CTRL                        =(VDAC_BASE    + (0<<2)),
+  VDAC1_CTRL                        =(VDAC_BASE    + (1<<2)),
+  VDAC_CABLE_DET                    =(VDAC_BASE    + (2<<2)),
+
+  //B2100360
+  CPU_POWER_STATUS                  =(CPU_PWR_BASE + (0<<2)),
+  CPU_POWER_CTRL                    =(CPU_PWR_BASE + (1<<2)),
+  CPU_RST_CTRL                      =(CPU_PWR_BASE + (2<<2)),
+  CPU_SCU_EV_ABORT                  =(CPU_PWR_BASE + (3<<2)),
+  CPU_SCU_CHRC_CNT                  =(CPU_PWR_BASE + (4<<2)),
+  CPU_POWER_MODE                    =(CPU_PWR_BASE + (8<<2)),
+  USB_CTRL                          =(CPU_PWR_BASE + (0x0C<<2)),
+  STC_CTRL                          =(CPU_PWR_BASE + (0x10<<2)),
+
+  CLOCK_REG_SIZE = 0x1000,
+}CLOCK_REG_BANK;
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/arch/arm/mach-celestial/include/mach/cnc1900_df.h linux-linaro-3.4-2012.05-1_cavium/arch/arm/mach-celestial/include/mach/cnc1900_df.h
--- linux-linaro-3.4-2012.05-1_original/arch/arm/mach-celestial/include/mach/cnc1900_df.h	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/arch/arm/mach-celestial/include/mach/cnc1900_df.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,398 @@
+#ifndef __CNC1900_DF_H__
+#define __CNC1900_DF_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define  CSTVE_IOC_MAGIC  'e'
+#define  CSDF_IOC_MAGIC   'x'
+
+/*****************IOCTL for TVE******************/
+#define CSTVE_IOC_ENABLE                      _IOW(CSTVE_IOC_MAGIC, 0x0b, int)
+#define CSTVE_IOC_DISABLE                     _IOR(CSTVE_IOC_MAGIC, 0x0c, int)
+#define CSTVE_IOC_SET_MODE                    _IOW(CSTVE_IOC_MAGIC, 0x01, int)
+#define CSTVE_IOC_GET_MODE                    _IOW(CSTVE_IOC_MAGIC, 0x02, int)
+#define CSTVE_IOC_SET_WHILE_LEVEL             _IOW(CSTVE_IOC_MAGIC, 0x03, int)
+#define CSTVE_IOC_GET_WHILE_LEVEL             _IOR(CSTVE_IOC_MAGIC, 0x04, int)
+#define CSTVE_IOC_SET_BLACK_LEVEL             _IOW(CSTVE_IOC_MAGIC, 0x05, int)
+#define CSTVE_IOC_GET_BLACK_LEVEL             _IOR(CSTVE_IOC_MAGIC, 0x06, int)
+#define CSTVE_IOC_SET_SATURATION_LEVEL        _IOW(CSTVE_IOC_MAGIC, 0x07, int)
+#define CSTVE_IOC_GET_SATURATION_LEVEL        _IOR(CSTVE_IOC_MAGIC, 0x08, int)
+#define CSTVE_IOC_SET_COMP_CHAN               _IOW(CSTVE_IOC_MAGIC, 0x15, int)
+#define CSTVE_IOC_SET_COLOR_MODULATOR_COEF    _IOW(CSTVE_IOC_MAGIC, 0x16, int)
+
+/* dual output */
+#define CSTVE_IOC_BIND_GFX                    _IOW(CSTVE_IOC_MAGIC, 0x17, int)
+#define CSTVE_IOC_BIND_VID                    _IOW(CSTVE_IOC_MAGIC, 0x18, int)
+#define CSTVE_IOC_SET_OUTPUT                  _IOW(CSTVE_IOC_MAGIC, 0x19, int)
+#define CSTVE_IOC_GET_BIND_INF                _IOW(CSTVE_IOC_MAGIC, 0x20, int)
+
+#define CSTVE_IOC_WSS_CTRL                    _IOW(CSTVE_IOC_MAGIC, 0x22, int)
+#define CSTVE_IOC_WSS_SETCONFIG               _IOW(CSTVE_IOC_MAGIC, 0x23, int)
+#define CSTVE_IOC_WSS_SETINFO                 _IOW(CSTVE_IOC_MAGIC, 0x24, int)
+#define CSTVE_IOC_TTX_CTRL                    _IOW(CSTVE_IOC_MAGIC, 0x25, int)
+#define CSTVE_IOC_TTX_SETCONFIG               _IOW(CSTVE_IOC_MAGIC, 0x26, int)
+#define CSTVE_IOC_TTX_SETINFO                 _IOW(CSTVE_IOC_MAGIC, 0x27, int)
+
+
+/*******IOCTL for Display Feeder ********/
+#define CSDF_IOC_DISP_ON                      _IOW(CSDF_IOC_MAGIC, 0x0F, int)
+#define CSDF_IOC_DISP_OFF                     _IOW(CSDF_IOC_MAGIC, 0x10, int)
+#define CSDF_IOC_DISP_VID_ON                  _IOW(CSDF_IOC_MAGIC, 0x11, int)
+#define CSDF_IOC_DISP_VID_OFF                 _IOW(CSDF_IOC_MAGIC, 0x12, int)
+#define CSDF_IOC_DISP_GFX_ON                  _IOW(CSDF_IOC_MAGIC, 0x1C, int)
+#define CSDF_IOC_DISP_GFX_OFF                 _IOW(CSDF_IOC_MAGIC, 0x1D, int)
+#define CSDF_IOC_DISP_POS                     _IOW(CSDF_IOC_MAGIC, 0x13, df_output_pos)
+//#define CSDF_IOC_DISP_GET_POS               _IOW(CSDF_IOC_MAGIC, 0x14, int)
+#define CSDF_IOC_DISP_VID_ALPHA               _IOW(CSDF_IOC_MAGIC, 0x15, int)
+//#define CSDF_IOC_DISP_GET_ALPHA             _IOW(CSDF_IOC_MAGIC, 0x16, int)
+#define CSDF_IOC_DISP_VIDFMT                  _IOW(CSDF_IOC_MAGIC, 0x18, int)
+#define CSDF_IOC_Z_ORDER                      _IOW(CSDF_IOC_MAGIC, 0x19, int)
+#define CSDF_IOC_GET_Z_ORDER                _IOW(CSDF_IOC_MAGIC, 0x1A, int)
+#define CSDF_IOC_DISP_SETBGCOLOR              _IOW(CSDF_IOC_MAGIC, 0x1B, int)
+#define CSDF_IOC_DISP_SETMODE                 _IOW(CSDF_IOC_MAGIC, 0x1E, int)
+//#define CSDF_IOC_DISP_CROP                  _IOW(CSDF_IOC_MAGIC, 0x1F, struct df_vid_crop)
+#define CSDF_IOC_DISP_HD2SD_ENABLE            _IOW(CSDF_IOC_MAGIC, 0x20, int)
+#define CSDF_IOC_DISP_HD2SD_CONFIG            _IOW(CSDF_IOC_MAGIC, 0x21, int)
+
+#define CSDF_IOC_SET_BRIGHTNESS               _IOW(CSDF_IOC_MAGIC, 0x22, int)
+#define CSDF_IOC_GET_BRIGHTNESS               _IOR(CSDF_IOC_MAGIC, 0x23, int)
+#define CSDF_IOC_SET_CONTRAST                 _IOW(CSDF_IOC_MAGIC, 0x24, int)
+#define CSDF_IOC_GET_CONTRAST                 _IOR(CSDF_IOC_MAGIC, 0x25, int)
+#define CSDF_IOC_SET_SATURATION               _IOW(CSDF_IOC_MAGIC, 0x26, int)
+#define CSDF_IOC_GET_SATURATION               _IOR(CSDF_IOC_MAGIC, 0x27, int)
+
+#define CSDF_IOC_GET_INIT_OUTPUTMODE		  _IOW(CSDF_IOC_MAGIC, 0x28, int)
+#define CSDF_IOC_GET_IDCS_DDR_DIV_VAL		  _IOW(CSDF_IOC_MAGIC, 0x29, int)
+#define CSDF_IOC_GET_VPP_REG_ADDR		  _IOW(CSDF_IOC_MAGIC, 0x2a, int)
+#define CSDF_IOC_GET_VPP_REG_SIZE		  _IOW(CSDF_IOC_MAGIC, 0x2b, int)
+
+#define CSTVE_IOC_SET_HDMI_IN_ENBALE              _IOW(CSTVE_IOC_MAGIC, 0x2c, int)
+#define CSTVE_IOC_SET_HDMI_IN_BYPASS             _IOW(CSTVE_IOC_MAGIC, 0x2d, int)
+
+#define CSDF_IOC_SET_SHARPNESS               _IOW(CSDF_IOC_MAGIC, 0x2e, int)
+#define CSDF_IOC_GET_SHARPNESS               _IOR(CSDF_IOC_MAGIC, 0x2f, int)
+
+typedef enum
+{
+	CSVOUT_COMP_YVU = 0,
+	CSVOUT_COMP_RGB
+
+}CSVOUT_CompChannType_t;
+
+typedef enum {
+	DF_DEV_NUKOWN = -1,
+	DF_DEV_GFX0 = 0,
+	DF_DEV_GFX1,
+	DF_DEV_VIDEO0,
+	DF_DEV_VIDEO1,
+	DF_DEV_OUT0,
+	DF_DEV_OUT1,
+	DF_DEV_TVE0,
+	DF_DEV_TVE1,
+	DF_DEV_MAX
+} DF_DEV_TYPE;
+
+typedef enum _DF_VIDEO_FORMAT_
+{
+	NOT_STANDARD_VIDEO_MODE = -1,		
+	DISP_YUV_720P_60FPS        =0,    
+	DISP_YUV_1080I_30FPS       =1,   
+	DISP_YUV_480P              =2,          
+	DISP_YUV_NTSC              =3,          
+	DISP_YUV_720P_50FPS        =4,    
+	DISP_YUV_1080I_25FPS       =5,   
+	DISP_YUV_576P              =6,          
+	DISP_YUV_PAL               =7,           
+	DISP_YUV_1080P_60FPS       =8,   
+	DISP_YUV_1080P_50FPS       =9,   
+	DISP_YUV_1080P_24FPS       =10,   
+	DISP_YUV_1080P_25FPS       =11,   
+	DISP_YUV_1080P_30FPS       =12,   
+	DISP_YUV_1080I_25FPS_AS    =13,
+	DISP_RGB_VGA_60FPS         =14,     
+	DISP_RGB_SVGA_60FPS        =15,    
+	DISP_RGB_XGA_60FPS         =16,     
+	DISP_RGB_SXGA_60FPS        =17,    
+	DISP_RGB_UXGA_60FPS        =18,
+	DISP_RGB_720P_60FPS        =19,
+	DISP_1440x288P_50_M1       =20,   
+	DISP_1440x288P_50_M2       =21,   
+	DISP_1440x288P_50_M3       =22,   
+	DISP_2880x576I_50          =23,      
+	DISP_2880x288P_50_M1       =24,   
+	DISP_2880x288P_50_M2       =25,   
+	DISP_2880x288P_50_M3       =26,   
+	DISP_1440x576P_50          =27,      
+	DISP_1440x240P_60_M1       =28,   
+	DISP_1440x240P_60_M2       =29,   
+	DISP_2880x480I_60          =30,      
+	DISP_2880x240P_60_M1       =31,   
+	DISP_2880x240P_60_M2       =32,   
+	DISP_1440x480P_60          =33,
+	DISP_RGB_DMT_640x480_60    =34,    
+	DISP_RGB_DMT_640x480_75    =35,    
+	DISP_RGB_DMT_800x600_60    =36,    
+	DISP_RGB_DMT_800x600_75    =37,    
+	DISP_RGB_DMT_848x480_60    =38,    
+	DISP_RGB_DMT_1152x864_75   =39,   
+	DISP_RGB_DMT_1280x768_60   =40,   
+	DISP_RGB_DMT_1280x960_60   =41,   
+	DISP_RGB_DMT_1280x1024_60  =42,  
+	DISP_RGB_DMT_1360x768_60   =43,   
+	DISP_RGB_DMT_1440x900_60   =44,   
+	DISP_RGB_CVT_640x480_75    =45,    
+	DISP_RGB_CVT_800x600_60    =46,    
+	DISP_RGB_CVT_800x600_75    =47,    
+	DISP_RGB_CVT_1024x768_60   =48,   
+	DISP_RGB_CVT_1280x1024_60  =49,  
+	DISP_RGB_CVT_848x480_60    =50,    
+	DISP_RGB_CVT_848x480_75    =51,    
+	DISP_RGB_CVT_1024x576_60   =52,   
+	DISP_RGB_CVT_1024x576_75   =53,   
+	DISP_RGB_CVT_1280x720_60   =54,   
+	DISP_RGB_CVT_1280x720_75   =55,   
+	DISP_RGB_CVT_640x400_75    =56,    
+	DISP_RGB_CVT_768x480_60    =57,    
+	DISP_RGB_CVT_768x480_75    =58,    
+	DISP_RGB_CVT_1024x640_60   =59,   
+	DISP_RGB_CVT_1024x640_75   =60,   
+	DISP_RGB_CVT_1280x800_75   =61,   
+	DISP_RGB_CVT_800x600_RED   =62,   
+	DISP_RGB_CVT_1024x768_RED  =63,  
+	DISP_RGB_CVT_1280x960_RED  =64,  
+	DISP_RGB_CVT_848x480_RED   =65,   
+	DISP_RGB_CVT_1024x576_RED  =66,  
+	DISP_RGB_CVT_1280x720_RED  =67,  
+	DISP_RGB_CVT_1600x900_RED  =68,  
+	DISP_RGB_CVT_768x480_RED   =69,   
+	DISP_RGB_CVT_1024x640_RED  =70,  
+	DISP_RGB_CVT_1280x800_RED  =71,  
+	DISP_RGB_CVT_1600x1000_RED =72, 
+    	DISP_64x64                 =73,
+    	DISP_VGA_1366x768		   =74,
+    	DISP_YUV_480P_3D,
+	DISP_YUV_NTSC_3D,          
+	DISP_YUV_576P_3D,          
+	DISP_YUV_PAL_3D,  
+	DISP_YUV_720P_60FPS_3D,
+	DISP_YUV_1080P_30FPS_3D,
+	DISP_YUV_1080I_30FPS_3D,
+	DISP_YUV_720P_50FPS_3D,
+	DISP_YUV_1080P_24FPS_3D,
+	DISP_YUV_1080P_25FPS_3D,
+	DISP_YUV_720P_30FPS_3D,
+	DISP_YUV_1080P_30FPS_3D_TEMP,
+	DISP_YUV_1080I_30FPS_3D_TEMP,
+	DISP_RGB_VGA_59P94FPS,
+	DISP_1600x1200_60FPS,
+ 	DISP_FMT_MAX,
+}DF_VIDEO_FORMAT;
+
+typedef enum
+{
+	TVOUT_MODE_576I = 0,
+	TVOUT_MODE_480I,
+	TVOUT_MODE_576P,
+	TVOUT_MODE_480P,
+	TVOUT_MODE_720P50,
+	TVOUT_MODE_720P60,
+	TVOUT_MODE_1080I25,
+	TVOUT_MODE_1080I30,
+
+	TVOUT_MODE_SECAM,
+	TVOUT_MODE_PAL_M,
+	TVOUT_MODE_PAL_N,
+	TVOUT_MODE_PAL_CN,
+	TVOUT_MODE_1080P24,
+	TVOUT_MODE_1080P25,
+	TVOUT_MODE_1080P30,
+	TVOUT_MODE_1080P50,
+	TVOUT_MODE_1080P60,
+
+	TVOUT_MODE_576I_16TO9,
+	TVOUT_MODE_480I5994,
+	TVOUT_MODE_480I5994_16TO9,
+	TVOUT_MODE_480I60_16TO9,
+	TVOUT_MODE_576P50_16TO9,
+	TVOUT_MODE_480P5994,
+	TVOUT_MODE_480P5994_16TO9,
+	TVOUT_MODE_480P60_16TO9,
+	TVOUT_MODE_720P5994,
+	TVOUT_MODE_1080I5994,
+	TVOUT_MODE_1080P2397,
+	TVOUT_MODE_1080P5994,
+
+	TVOUT_MODE_720P5994_3DFP,
+	TVOUT_MODE_720P60_3DFP,
+	TVOUT_MODE_720P50_3DFP,
+	TVOUT_MODE_1080P2397_3DFP,
+	TVOUT_MODE_1080P24_3DFP,
+
+	TVOUT_MODE_1080I50_3DSS,
+	TVOUT_MODE_1080I5994_3DSS,
+	TVOUT_MODE_1080I60_3DSS,
+
+	TVOUT_MODE_720P50_3DTB,
+	TVOUT_MODE_720P5994_3DTB,
+	TVOUT_MODE_720P60_3DTB,
+	TVOUT_MODE_1080P2397_3DTB,
+	TVOUT_MODE_1080P24_3DTB,
+
+	TVOUT_RGB_640X480_60FPS,
+	TVOUT_RGB_800X600_60FPS,
+	TVOUT_RGB_1024X768_60FPS,
+       TVOUT_RGB_1280X720_60FPS,
+       TVOUT_RGB_800X480_60FPS,
+       TVOUT_RGB_1440X900_60FPS,
+       TVOUT_RGB_1280X1024_60FPS,
+       TVOUT_RGB_1360X768_60FPS,
+       TVOUT_RGB_1920X1080P30,
+       TVOUT_RGB_1920X1080P60,
+       TVOUT_RGB_1920X1080I30,
+       TVOUT_RGB_1366X768_60FPS,
+       TVOUT_RGB_640X480_5994FPS,
+       TVOUT_MODE_1600X1200_60FPS,
+} TVOUT_MODE;
+
+typedef enum
+{
+        DF_OUTPUT_CVBS_SVIDEO = 0,
+        DF_OUTPUT_YPBPR,
+        DF_OUTPUT_VGA
+} DF_OUTPUT_MODE;
+
+typedef struct DF_DEV_t {
+	unsigned int dev_minor;
+	DF_DEV_TYPE dev_type;
+	spinlock_t spin_lock;
+	unsigned int enable;
+	TVOUT_MODE tve_format;
+	char* name;
+} dfdev;
+
+typedef struct DF_OUTPUT_CONFIG_t_{
+	int gfx_output[2]; //gfx_layer_id
+	int vid_output[3]; //video_layer_id
+	DF_OUTPUT_MODE output_mode[2];//outif_id
+}DF_OUTPUT_CONFIG_t;
+
+typedef struct df_rect
+{
+        int left;
+        int right;
+        int top;
+        int bottom;
+}df_rect;
+
+typedef struct df_output_pos
+{
+	df_rect src;
+	df_rect dst;
+}df_output_pos;
+
+typedef struct _DF_OUTIF_FORMAT_INFO_
+{
+	int  mIsYUVorRGB;
+	int  mWidth;
+	int  mHeight;
+	int  mFPS;
+	int  mFreq;
+	int  mIsHD;
+	int  mVSyncPol;
+	int  mHSyncPol;
+	int  mHRes;
+	int  mHActive;
+	int  mHSyncFP;
+	int  mHSyncWidth;
+	int  mHSyncBP;
+	int  mVRes;
+	int  mVActline;
+	int  mVSyncFP;
+	int  mVSyncWidth;
+	int  mVSyncBP;
+	int  m3dEn;
+	int  m3dVactSpace;
+	int  mVidType;
+	int  mVidrptr;
+	int  mYCMuxEn;
+	int  mPALFmt;
+	int  mFmtIdx;
+	char *mFmtName;
+
+} df_out_if_timing;
+
+enum _DF_SCALER_COEFF_TYPE_
+{
+	DF_VIDEO1_Y_HFIR_COEFF_IDX = 0,//              0 : Video 1 HFIR Coeff
+	DF_VIDEO1_Y_VFIR_COEFF_IDX = 1,//              1 : Video 1 VFIR Coeff
+	DF_VIDEO2_Y_HFIR_COEFF_IDX = 2,//              2 : Video 2 HFIR Coeff
+	DF_VIDEO2_Y_VFIR_COEFF_IDX = 3,//              3 : Video 2 VFIR Coeff
+	DF_HD2SD_Y_HFIR_COEFF_IDX  = 4,//              4 : HD2SD 1 HFIR Coeff
+	DF_HD2SD_Y_VFIR_COEFF_IDX   =5,//              5 : HD2SD 1 VFIR Coeff
+};
+
+enum _DF_VIDEO_SCALER_CFG_
+{
+	//Scaler Coeff Cfg
+	DF_SCL_STEP_FRACTION_BIT_WIDTH  = 13,
+
+	DF_SCL_COEFF_FRACTION_BIT_WIDTH = 10,
+	DF_SCL_COEFF_INTREGER_BIT_WIDTH = 1,
+	DF_SCL_COEFF_POLARITY_BIT       = 15,
+
+	DF_SCL_WIDTH_MAX = 2048,
+	DF_SCL_FIR_TAP_MAX  = 32,
+
+	//Video Scaler Cfg
+	DF_VIDEO_SCL_LUMA_VFIR_TAP_NUM          = 4,
+	DF_VIDEO_SCL_LUMA_VFIR_PHASE_LOG2BITS   = 4,
+	DF_VIDEO_SCL_LUMA_VFIR_PHASE_NUM        = 1 << DF_VIDEO_SCL_LUMA_VFIR_PHASE_LOG2BITS,
+	DF_VIDEO_SCL_LUMA_HFIR_TAP_NUM          = 4,
+	DF_VIDEO_SCL_LUMA_HFIR_PHASE_LOG2BITS   = 4,
+	DF_VIDEO_SCL_LUMA_HFIR_PHASE_NUM        = 1 << DF_VIDEO_SCL_LUMA_HFIR_PHASE_LOG2BITS,
+
+	DF_VIDEO_SCL_CHROMA_VFIR_TAP_NUM        = 2,
+	DF_VIDEO_SCL_CHROMA_VFIR_PHASE_LOG2BITS = 4,
+	DF_VIDEO_SCL_CHROMA_VFIR_PHASE_NUM      = 1 << DF_VIDEO_SCL_CHROMA_VFIR_PHASE_LOG2BITS,
+	DF_VIDEO_SCL_CHROMA_HFIR_TAP_NUM        = 2,
+	DF_VIDEO_SCL_CHROMA_HFIR_PHASE_LOG2BITS = 4,
+	DF_VIDEO_SCL_CHROMA_HFIR_PHASE_NUM      = 1 << DF_VIDEO_SCL_CHROMA_HFIR_PHASE_LOG2BITS,
+
+	//HD2SD Capture Block
+	DF_HD2SD_SCL_LUMA_VFIR_TAP_NUM          = 4,
+	DF_HD2SD_SCL_LUMA_VFIR_PHASE_LOG2BITS   = 4,
+	DF_HD2SD_SCL_LUMA_VFIR_PHASE_NUM        = 1 << DF_HD2SD_SCL_LUMA_VFIR_PHASE_LOG2BITS,
+	DF_HD2SD_SCL_LUMA_HFIR_TAP_NUM          = 4,
+	DF_HD2SD_SCL_LUMA_HFIR_PHASE_LOG2BITS   = 4,
+	DF_HD2SD_SCL_LUMA_HFIR_PHASE_NUM        = 1 << DF_HD2SD_SCL_LUMA_HFIR_PHASE_LOG2BITS,
+
+	DF_HD2SD_SCL_CHROMA_VFIR_TAP_NUM        = 2,
+	DF_HD2SD_SCL_CHROMA_VFIR_PHASE_LOG2BITS = 4,
+	DF_HD2SD_SCL_CHROMA_VFIR_PHASE_NUM      = 1 << DF_HD2SD_SCL_CHROMA_VFIR_PHASE_LOG2BITS,
+	DF_HD2SD_SCL_CHROMA_HFIR_TAP_NUM        = 2,
+	DF_HD2SD_SCL_CHROMA_HFIR_PHASE_LOG2BITS = 4,
+	DF_HD2SD_SCL_CHROMA_HFIR_PHASE_NUM      = 1 << DF_HD2SD_SCL_CHROMA_HFIR_PHASE_LOG2BITS,
+
+	//Gfx Horizontal Scaler
+	DF_GFX_SCL_STEP_FRACTION_BIT_WIDTH  = 10,
+	DF_GFX_SCL_HFIR_TAP_NUM        = 2,
+	DF_GFX_SCL_HFIR_PHASE_LOG2BITS = 6,
+	DF_GFX_SCL_HFIR_PHASE_NUM      = 1 << DF_GFX_SCL_HFIR_PHASE_LOG2BITS,
+};
+
+typedef struct{
+	wait_queue_head_t wait;
+	unsigned int count;
+	int is_display;
+	struct fb_info *cur_fb_info;
+}CNC_FB_INTERRUPT;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/arch/arm/mach-celestial/include/mach/cnc1900.h linux-linaro-3.4-2012.05-1_cavium/arch/arm/mach-celestial/include/mach/cnc1900.h
--- linux-linaro-3.4-2012.05-1_original/arch/arm/mach-celestial/include/mach/cnc1900.h	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/arch/arm/mach-celestial/include/mach/cnc1900.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,241 @@
+/*
+ *  arch/arm/mach-celestial/include/mach/cnc1900.h
+ *
+ *  This file contains the hardware definitions of the cavium Celestial CNC1900 1900 FPGA-V7 Platform.
+ *
+ *  Copyright (C) 2012 Cavium
+ */
+
+#ifndef __ASM_ARCH_CNC1900_H
+#define __ASM_ARCH_CNC1900_H
+
+/* macro to get at IO space when running virtually */
+#define IO_ADDRESS(phys) (0xF0000000 + ((((phys) >> 4) & 0x0ff00000) + ((phys) & 0xFFFFFFF)))
+
+#include <mach/mem_define.h>
+
+#define PCLK_KHZ                   45000
+#define PCLK_MHZ                   45
+
+
+
+
+
+
+
+
+
+
+
+/** Cortex-A9 Private Memory Region **/
+#define CNC1900_CA9_PMR                 0x80020000
+/* Snoop Control Unit */
+#define CNC1900_CA9_SCU                 (CNC1900_CA9_PMR + 0x00000000)
+/* GIC CPU Interface */
+#define CNC1900_CA9_GIC_CPUIF           (CNC1900_CA9_PMR + 0x00000100)
+/* Global Timer */
+#define CNC1900_CA9_GBL_TIMER           (CNC1900_CA9_PMR + 0x00000200)
+/* Private Timer and Watchdog */
+#define CNC1900_CA9_TWD                 (CNC1900_CA9_PMR + 0x00000600)
+/* GIC Distributor */
+#define CNC1900_CA9_GIC_DIST            (CNC1900_CA9_PMR + 0x00001000)
+/* Private Timer */
+#define CNC1900_CA9_PVT_TIMER           (CNC1900_CA9_TWD + 0x00000000)
+/* Private Watchdog */
+#define CNC1900_CA9_PVT_WDT             (CNC1900_CA9_TWD + 0x00000020)
+
+
+/** L2 Cache Controller **/
+#define CNC1900_L2X0                    0x80030000
+
+
+/** Trust-Zone APB **/
+#define CNC1900_TZ_APB                  0x80040000
+/* TZ Address Space Controller 0 */
+#define CNC1900_TZ_ASC0                 (CNC1900_TZ_APB + 0x00000000)
+/* TZ Address Space Controller 1 */
+#define CNC1900_TZ_ASC1                 (CNC1900_TZ_APB + 0x00010000)
+/* TZ Config */
+#define CNC1900_TZ_CFG                  (CNC1900_TZ_APB + 0x00020000)
+/* TZ Timer */
+#define CNC1900_TZ_TIMER                (CNC1900_TZ_APB + 0x00030000)
+
+
+/** On-chip Peripheral **/
+#define CNC1900_PERIPH_BASE             0x80100000
+/* Static Memory Controller - SMC */
+#define CNC1900_SMC                     0x80100000
+/* Dynamic Memory Controller - DMC */
+#define CNC1900_DMC                     0x80110000
+/* Serial Peripheral Interface - SPI */
+#define CNC1900_SPI                     0x80150000
+/* TV Encoder - TVE */
+#define CNC1900_TVE                     0x80160000
+/* I2C0 */
+#define CNC1900_I2C0                    0x80170000
+#define VA_I2C_BASE                IO_ADDRESS(CNC1900_I2C0)
+
+/* Panel CTL */
+#define CNC1900_PCTL                    0x80172000
+#define PA_FPC_BASE                    CNC1900_PCTL
+
+#define VA_FPC_BASE			IO_ADDRESS(CNC1900_PCTL)
+/* I2C1 */
+#define CNC1900_I2C1                    0x80174000
+/* IR Repeater */
+#define CNC1900_IR_REPEATER      0x801E7000
+/* SMIO */
+#define CNC1900_SMIO                    0x801F0000
+/* UART 0 */
+#define CNC1900_UART0                   0x801F1000
+/* UART 1 */
+#define CNC1900_UART1                   0x801F2000
+/* USB EHCI */
+#define CNC1900_USB_EHCI                0x80200000
+/* USB OHCI */
+#define CNC1900_USB_OHCI                0x80210000
+/* Crypto Engine */
+#define CNC1900_CRYPTO                  0x80240000
+/* PCMCIA */
+#define CNC1900_PCMCIA                  0x80250000
+/* GPIO */
+#define CNC1900_GPIO                    0x80260000
+#define VA_GPIO_BASE	IO_ADDRESS(CNC1900_GPIO)
+/* SD0 */
+#define CNC1900_SD0                     0x80290000
+/* SD1 */
+#define CNC1900_SD1                     0x802A0000
+/* USB OTG */
+#define CNC1900_USB_OTG                 0x802C0000
+/* HDMI */
+#define CNC1900_HDMI                    0x80400000
+#define VA_HDMI_BASE                    IO_ADDRESS(CNC1900_HDMI)
+#define CNC1900_HDMI_PHY                0x80401800
+#define VA_HDMI_PHY_BASE                IO_ADDRESS(CNC1900_HDMI_PHY)
+#define CNC1900_MHL_PHY                 0x80403800
+#define VA_MHL_PHY_BASE                 IO_ADDRESS(CNC1900_MHL_PHY)
+
+/** Peripheral Space Size **/
+#define CNC1900_PERIPH_SIZE             0x00500000
+
+
+/** CoreSight **/
+#define CNC1900_CORESIGHT               0x90000000
+
+
+/** Static Memory **/
+#define CNC1900_SM_BASE                 0xA0000000
+/* Static Memory - CS0 */
+#define CNC1900_SM_CS0                  (CNC1900_SM_BASE + 0x04000000)
+/* Static Memory - CS1 */
+#define CNC1900_SM_CS1                  (CNC1900_SM_BASE + 0x06000000)
+/* Static Memory - CS2 */
+#define CNC1900_SM_CS2                  (CNC1900_SM_BASE + 0x08000000)
+/* Static Memory - CS3 */
+#define CNC1900_SM_CS3                  (CNC1900_SM_BASE + 0x0A000000)
+
+
+/** Media Processor **/
+#define CNC1900_MEDIA_BASE              0xB1000000
+/* Audio */
+#define CNC1900_AUDIO                   (CNC1900_MEDIA_BASE + 0x00200000)
+/* Ethernet */
+#define CNC1900_ETH                     (CNC1900_MEDIA_BASE + 0x00400000)
+/* Video */
+#define CNC1900_VIDEO                   (CNC1900_MEDIA_BASE + 0x00600000)
+/* VPP */
+#define CNC1900_VPP                     (CNC1900_MEDIA_BASE + 0x00800000)
+/* VPB */
+#define CNC1900_VPB                     (CNC1900_MEDIA_BASE + 0x00C00000)
+
+
+/* Audio Common */
+#define CNC1900_AUDIO_COMMON            (CNC1900_AUDIO + 0x00000000)
+/* Audio I2S */
+#define CNC1900_AUDIO_I2S               (CNC1900_AUDIO + 0x00001000)
+/* Audio SPDIF */
+#define CNC1900_AUDIO_SPDIF             (CNC1900_AUDIO + 0x00002000)
+/* Audio IFIFO */
+#define CNC1900_AUDIO_IFIFO             (CNC1900_AUDIO + 0x00004000)
+
+
+/* Video Common */
+#define CNC1900_VIDEO_COMMON            (CNC1900_VIDEO + 0x00000000)
+/* CODA */
+#define CNC1900_VIDEO_CODA              (CNC1900_VIDEO + 0x00040000)
+/* Video RISC cpu */
+#define CNC1900_VIDEO_RISC_CPU          (CNC1900_VIDEO + 0x00090000)
+
+
+/** System Cotrol */
+#define CNC1900_SYSCTL_BASE             0xB2000000
+/* Pin Mux */
+#define CNC1900_PIN_MUX                 (CNC1900_SYSCTL_BASE + 0x00110000)
+#define CNC1900_PIN_MUX_SIZE	(0x100)
+
+
+
+/*bin added*/
+#define PA_IO_REGS_BASE            0x80100000
+#define IO_REGS_SIZE               0x500000
+#define VA_IO_REGS_BASE            IO_ADDRESS(PA_IO_REGS_BASE)
+
+#define PA_IO_GRAPHICS_BASE        0xB0000000
+
+#define IO_GRAPHICS_SIZE           0x200 // bigger than required (0x100)
+#define VA_IO_GRAPHICS_BASE        IO_ADDRESS(PA_IO_GRAPHICS_BASE)
+
+#define PA_IO_MEDIA_PROCESSOR_BASE 0xB1000000
+#define IO_MEDIA_PROCESSOR_SIZE    0xf00000
+#define VA_IO_MEDIA_PROCESSOR_BASE IO_ADDRESS(PA_IO_MEDIA_PROCESSOR_BASE)
+
+#define PA_IO_SYSTEM_CONTROL_BASE 0xB2100000
+#define IO_SYSTEM_CONTROL_SIZE    0x100000
+#define VA_IO_SYSTEM_CONTROL_BASE IO_ADDRESS(PA_IO_SYSTEM_CONTROL_BASE)
+
+#define PA_IO_LINE_BUFFER_BASE  0x80000000
+#define IO_LINE_BUFFER_SIZE             0x20000
+#define VA_IO_LINE_BUFFER_BASE      IO_ADDRESS(PA_IO_LINE_BUFFER_BASE)
+
+#define PA_CRYPTO_BASE             (PA_IO_REGS_BASE + 0x140000)
+#define VA_CRYPTO_BASE             IO_ADDRESS(PA_CRYPTO_BASE)
+
+#define PA_XPORT_REG_BASE          0xB1400000
+#define VA_XPORT_BASE              IO_ADDRESS(PA_XPORT_REG_BASE)
+
+#define CAV_TIMER_LOAD			0x00
+#define CAV_TIMER_COUNTER		0x04
+#define CAV_TIMER_CONTROL		0x08
+#define CAV_TIMER_INTSTAT		0x0C
+
+#define CAV_WDOG_LOAD			0x20
+#define CAV_WDOG_COUNTER		0x24
+#define CAV_WDOG_CONTROL		0x28
+#define CAV_WDOG_INTSTAT		0x2C
+#define CAV_WDOG_RESETSTAT		0x30
+#define CAV_WDOG_DISABLE		0x34
+
+#define CAV_TIMER_CONTROL_ENABLE	(1 << 0)
+#define CAV_TIMER_CONTROL_ONESHOT	(0 << 1)
+#define CAV_TIMER_CONTROL_PERIODIC	(1 << 1)
+#define CAV_TIMER_CONTROL_IT_ENABLE	(1 << 2)
+
+#define CAV_WDOG_CONTROL_ENABLE	(1 << 0)
+#define CAV_WDOG_CONTROL_ONESHOT	(0 << 1)
+#define CAV_WDOG_CONTROL_PERIODIC	(1 << 1)
+#define CAV_WDOG_CONTROL_IT_ENABLE	(1 << 2)
+
+#define GBL_TIMER_COUNTER_L 0x00
+#define GBL_TIMER_COUNTER_H 0x04
+#define GBL_TIMER_CONTROL   0x08
+#define GBL_TIMER_INTSTAT   0x0C
+#define GBL_TIMER_COMPARE_L 0x10
+#define GBL_TIMER_COMPARE_H 0x14
+#define GBL_TIMER_INCREMENT 0x18
+
+#define TIMER_CTRL_EN  (1 << 0)
+#define TIMER_CTRL_COM (1 << 1)
+#define TIMER_CTRL_IRQ (1 << 2)
+#define TIMER_CTRL_INC (1 << 3)
+
+#endif
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/arch/arm/mach-celestial/include/mach/cnc1900_power_clk.h linux-linaro-3.4-2012.05-1_cavium/arch/arm/mach-celestial/include/mach/cnc1900_power_clk.h
--- linux-linaro-3.4-2012.05-1_original/arch/arm/mach-celestial/include/mach/cnc1900_power_clk.h	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/arch/arm/mach-celestial/include/mach/cnc1900_power_clk.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,246 @@
+#ifndef _CNC1900_POWER_CLK_H_
+#define _CNC1900_POWER_CLK_H_
+
+#ifdef __cplusplus
+extern "C"{
+#endif
+
+#define POWER_BASE 'P'
+#define USB_POWER_DOWN          _IOW (POWER_BASE, 0, int)
+#define XPORT_CLK_DOWN          _IOW (POWER_BASE, 1, int)
+
+#define VIB_CLK_DOWN            _IOW (POWER_BASE, 2, int)
+#define VPB_CLK_DOWN            _IOW (POWER_BASE, 2, int)
+
+#define AUD_CLK_DOWN            _IOW (POWER_BASE, 3, int)
+#define CRYPTO_CLK_DOWN         _IOW (POWER_BASE, 4, int)
+#define GRAPHICS_CLK_DOWN       _IOW (POWER_BASE, 5, int)
+#define DF_CLK_DOWN             _IOW (POWER_BASE, 6, int)
+#define VIDECOD_CLK_DOWN        _IOW (POWER_BASE, 7, int)
+#define AUDDACIF_CLK_DOWN       _IOW (POWER_BASE, 8, int)
+#define SD_CLK_DOWN             _IOW (POWER_BASE, 9, int)
+#define TVE1_CLK_DOWN           _IOW (POWER_BASE, 10, int)
+#define TVE0_CLK_DOWN           _IOW (POWER_BASE, 11, int)
+#define AUD_POWER_DOWN          _IOW (POWER_BASE, 12, int)
+#define VID_POWER_DOWN          _IOW (POWER_BASE, 13, int)
+#define AUD_PLLCLK_DOWN         _IOW (POWER_BASE, 14, int)
+#define VDAC0_POWER_DOWN	    _IOW (POWER_BASE, 15, int)
+#define VDAC1_POWER_DOWN	    _IOW (POWER_BASE, 16, int)
+#define HDMI_POWER_DOWN			_IOW (POWER_BASE, 17, int)
+#define JPEG_CLK_DOWN           _IOW (POWER_BASE, 18, int)
+#define AHB2_CLK_DOWN           _IOW (POWER_BASE, 19, int)
+#define CEC_CLK_DOWN            _IOW (POWER_BASE, 20, int)
+#define IR_CLK_DOWN             _IOW (POWER_BASE, 21, int)
+#define VPBIN_CLK_DOWN          _IOW (POWER_BASE, 22, int)
+
+typedef enum _POWER_MODE_
+{
+	_clock_sleep =0,
+	_clock_wake  =1,
+}POWER_MODE;
+
+typedef enum _CLOCK_RESET_
+{
+  _do_reset =0,
+  _do_set   =1,
+}CLOCK_RESET;
+
+typedef enum _HDMI_SEL_
+{
+	_sel_ttl =0,
+	_sel_vib   =1,
+}HDMI_SEL;
+
+typedef enum _CLOCK_ENA_
+{
+        _clock_enable =1,
+        _clock_disable =0,
+}CLOCK_ENA;
+
+//Coda
+/*
+void clock_coda_setclock(double codapll_clk, unsigned short codaaclk_postdiv, unsigned short codacclk_postdiv, unsigned short use_codapll_for_cclk );
+*/
+
+//Display
+typedef enum _CLOCK_DISP0_MODE_e_ {                
+    _YUV_1080P_60Hz             ,          
+    _YUV_1080P_50Hz             ,          
+    _YUV_1080P_30Hz             ,          
+    _YUV_1080P_25Hz             ,          
+    _YUV_1080P_24Hz             ,          
+    _YUV_1080I_60Hz             ,          
+    _YUV_1080I_50Hz             ,          
+    _YUV_720P_60Hz              ,          
+    _YUV_720P_50Hz              ,          
+
+    _YUV_1080P_59p94Hz          ,          
+    _YUV_1080P_29p97Hz          ,          
+    _YUV_1080P_23p98Hz          ,          
+    _YUV_1080I_59p94Hz          ,          
+    _YUV_720P_59p94Hz           ,          
+
+    _YUV_576P_50Hz              ,          
+    _YUV_480P_59p94Hz              ,          
+    _YUV_480P_60Hz           ,          
+    _YUV_PAL                    ,          
+    _YUV_NTSC                   ,          
+    _YUV_480I_60Hz           ,          
+
+    _RGB_DMT_640x350_85Hz       ,          
+    _RGB_DMT_640x400_85Hz       ,          
+    _RGB_DMT_720x400_85Hz       ,          
+    _RGB_DMT_640x480_60Hz       ,          
+    _RGB_DMT_640x480_72Hz       ,          
+    _RGB_DMT_640x480_75Hz       ,          
+    _RGB_DMT_640x480_85Hz       ,          
+    _RGB_DMT_800x600_56Hz       ,          
+    _RGB_DMT_800x600_60Hz       ,          
+    _RGB_DMT_800x600_72Hz       ,          
+    _RGB_DMT_800x600_75Hz       ,          
+    _RGB_DMT_800x600_85Hz       ,          
+    _RGB_DMT_800x600_120Hz_RED  ,          
+
+    _RGB_DMT_848x480_60Hz       ,          
+
+    _RGB_DMT_1024x768_43Hz      ,          
+    _RGB_DMT_1024x768_60Hz      ,          
+    _RGB_DMT_1024x768_70Hz      ,          
+    _RGB_DMT_1024x768_75Hz      ,          
+    _RGB_DMT_1024x768_85Hz      ,          
+    _RGB_DMT_1024x768_120Hz_RED ,          
+
+    _RGB_DMT_1152x864_75Hz      ,          
+
+    _RGB_DMT_1280x768_60Hz_RED  ,          
+    _RGB_DMT_1280x768_60Hz      ,          
+    _RGB_DMT_1280x768_75Hz      ,          
+    _RGB_DMT_1280x768_85Hz      ,          
+    _RGB_DMT_1280x768_120Hz_RED ,          
+
+    _RGB_DMT_1280x800_60Hz_RED  ,          
+    _RGB_DMT_1280x800_60Hz      ,          
+    _RGB_DMT_1280x800_75Hz      ,          
+    _RGB_DMT_1280x800_85Hz      ,          
+    _RGB_DMT_1280x800_120Hz_RED ,          
+
+    _RGB_DMT_1280x960_60Hz      ,          
+    _RGB_DMT_1280x960_85Hz      ,          
+
+    _RGB_DMT_1280x1024_60Hz     ,          
+    _RGB_DMT_1280x1024_75Hz     ,          
+    _RGB_DMT_1280x1024_85Hz     ,          
+
+    _RGB_DMT_1360x768_60Hz      ,          
+    _RGB_DMT_1360x768_120Hz_RED ,          
+
+    _RGB_DMT_1400x1050_60Hz_RED ,          
+    _RGB_DMT_1400x1050_60Hz     ,          
+    _RGB_DMT_1400x1050_75Hz     ,          
+
+    _RGB_DMT_1440x900_60Hz_RED  ,          
+    _RGB_DMT_1440x900_60Hz      ,          
+    _RGB_DMT_1440x900_75Hz      ,          
+    _RGB_DMT_1440x900_85Hz      ,          
+
+    _RGB_DMT_1600x1200_60Hz     ,          
+
+    _RGB_DMT_1680x1050_60Hz_RED ,          
+    _RGB_DMT_1680x1050_60Hz     ,          
+
+    _RGB_DMT_1920x1200_60Hz_RED,
+    _RGB_DMT_640x480_59P94Hz,
+}CLOCK_DISP0_MODE;
+
+void clock_disp0_setclock(CLOCK_DISP0_MODE mode_disp0);
+
+typedef enum _CLOCK_DISP1_MODE_e_
+{
+    _YUV_576P_50Hz_disp1,
+    _YUV_480P_60Hz_disp1,
+    _YUV_PAL_disp1,
+    _YUV_NTSC_disp1,
+    _YUV_SECAM_disp1,
+    _YUV_PAL_M_disp1,
+    _YUV_PAL_N_disp1,
+    _YUV_PAL_CN_disp1,
+}CLOCK_DISP1_MODE;
+
+void clock_disp1_setclock(CLOCK_DISP1_MODE mode_disp1);
+
+//Audio
+typedef enum _AUDIO_CLOCK_MODE_e_
+{
+	_AUDIO_192KHz       ,
+	_AUDIO_176KHZ		,
+	_AUDIO_128KHZ		,
+	_AUDIO_96KHz 		,
+	_AUDIO_88_2KHz		,
+	_AUDIO_64KHz		,
+	_AUDIO_48KHz		,
+	_AUDIO_44_1KHz		,
+	_AUDIO_32KHz		,
+	_AUDIO_24KHz		,
+	_AUDIO_22_05KHz		,
+	_AUDIO_16KHz		,
+	_AUDIO_12KHz		,
+	_AUDIO_11_025KHz	,
+	_AUDIO_8KHz	        ,
+}AUDIO_CLOCK_MODE;
+
+
+void clock_audio_setclock(AUDIO_CLOCK_MODE audclk_rate);
+
+//Reset
+void clock_xport_reset(CLOCK_RESET ResetOrSet);
+void clock_ether_reset(CLOCK_RESET ResetOrSet);
+void clock_audio_reset(CLOCK_RESET ResetOrSet);
+void clock_crypto_reset(CLOCK_RESET ResetOrSet);
+void clock_video_reset(CLOCK_RESET ResetOrSet);
+void clock_gfx_reset(CLOCK_RESET ResetOrSet);
+void clock_dfr_reset(CLOCK_RESET ResetOrSet);
+void clock_disp0_reset(CLOCK_RESET ResetOrSet);
+void clock_disp1_reset(CLOCK_RESET ResetOrSet);
+void clock_tve0_reset(CLOCK_RESET ResetOrSet);
+void clock_tve1_reset(CLOCK_RESET ResetOrSet);
+void clock_vib_reset(CLOCK_RESET ResetOrSet);
+void clock_jpeg_reset(CLOCK_RESET ResetOrSet);
+void clock_coda_reset(CLOCK_RESET ResetOrSet);
+void clock_hdmi_reset(CLOCK_RESET ResetOrSet);
+void clock_hdmi_bypass(HDMI_SEL vpbOrdisp);
+void clock_spdif_reset(CLOCK_RESET ResetOrSet);
+void clock_dramporta_reset(CLOCK_RESET ResetOrSet);
+void clock_ir_reset(CLOCK_RESET ResetOrSet);
+
+/* Clock Enable/disable */
+void clock_dac0_enaclock(CLOCK_ENA ClockEna);
+void clock_dac1_enaclock(CLOCK_ENA ClockEna);
+
+void clock_dram_enaclock(CLOCK_ENA ClockEna);
+void clock_tve0_enaclock(CLOCK_ENA ClockEna);
+void clock_tve1_enaclock(CLOCK_ENA ClockEna);
+void clock_sdio_enaclock(CLOCK_ENA ClockEna);
+void clock_audiopll_enaclock(CLOCK_ENA ClockEna);
+void clock_jpeg_enaclock(CLOCK_ENA ClockEna);
+void clock_coda_enaclock(CLOCK_ENA ClockEna);
+void clock_df_enaclock(CLOCK_ENA ClockEna);
+void clock_gpu_enaclock(CLOCK_ENA ClockEna);
+void clock_ahb2_enaclock(CLOCK_ENA ClockEna);
+void clock_crypto_enaclock(CLOCK_ENA ClockEna);
+void clock_xport_enaclock(CLOCK_ENA ClockEna); /* It will control eth also.*/
+void clock_audio_enaclock(CLOCK_ENA ClockEna);
+void clock_video_enaclock(CLOCK_ENA ClockEna);
+void clock_dramporta_enaclock(CLOCK_ENA ClockEna);
+void clock_usb_enaclock(CLOCK_ENA ClockEna);
+void clock_cec_enaclock(CLOCK_ENA ClockEna);
+void clock_ir_enaclock(CLOCK_ENA ClockEna);
+void clock_vpb_enaclock(CLOCK_ENA ClockEna);
+void clock_vpbinput_enaclock(CLOCK_ENA ClockEna);
+void clock_cpu_enaclock(CLOCK_ENA ClockEna); /* In low power mode, this one can be set by Audio. others, no need to call this one.*/
+void clock_cpusrc_enaclock(CLOCK_ENA ClockEna); /* Should be always write 1 */
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/arch/arm/mach-celestial/include/mach/cnc1900_scalor_coef.h linux-linaro-3.4-2012.05-1_cavium/arch/arm/mach-celestial/include/mach/cnc1900_scalor_coef.h
--- linux-linaro-3.4-2012.05-1_original/arch/arm/mach-celestial/include/mach/cnc1900_scalor_coef.h	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/arch/arm/mach-celestial/include/mach/cnc1900_scalor_coef.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,260 @@
+#ifndef _CNC1900_SCALOR_COEF_
+#define _CNC1900_SCALOR_COEF_
+#define COEFF_DATA_NUM 640
+
+
+const long long cof3tap[COEFF_DATA_NUM]=
+{
+0x0000000824412412LL,0x00000008254453e0LL,0x00000008254773aeLL,0x00000008264a937dLL,0x00000008274db34cLL,0x000000082850c31cLL,0x000000082953d2ecLL,0x000000082a56c2beLL,
+0x000000082b59b290LL,0x000000082d5ca263LL,0x000000082e5f6238LL,0x000000082f62120eLL,0x000000083164b1e6LL,0x00000008326741beLL,0x000000083369a199LL,0x00000008346bf175LL,
+0x00000008356e3152LL,0x0000000836705131LL,0x0000000836724112LL,0x00000008367420f4LL,0x000000083675e0d8LL,0x00000008357770beLL,0x000000083478f0a5LL,0x00000008327a408eLL,
+0x00000008307b7079LL,0x000000082d7c8065LL,0x00000008297d7052LL,0x00000008257e4041LL,0x000000081f7ee031LL,0x00000008197f6023LL,0x00000008127fc016LL,0x00000008097fe00bLL,
+0x0000000000800000LL,0x000000000b7ff809LL,0x00000000167fb812LL,0x00000000237f6819LL,0x00000000317ee81fLL,0x00000000417e3825LL,0x00000000527d7829LL,0x00000000657c882dLL,
+0x00000000797b7830LL,0x000000008e7a4832LL,0x00000000a578f834LL,0x00000000be777835LL,0x00000000d875e836LL,0x00000000f4742836LL,0x0000000112724836LL,0x0000000131705836LL,
+0x00000001526e3835LL,0x00000001756c0834LL,0x000000019969a833LL,0x00000001be674832LL,0x00000001e664b831LL,0x000000020e62182fLL,0x00000002385f682eLL,0x00000002635c982dLL,
+0x000000029059b82bLL,0x00000002be56c82aLL,0x00000002ec53d829LL,0x000000031c50c828LL,0x000000034c4db827LL,0x000000037d4a9826LL,0x00000003ae477825LL,0x00000003e0444825LL,
+0x000000081640b40bLL,0x000000081542f3e6LL,0x00000008144533c1LL,0x000000081447839cLL,0x000000081349b378LL,0x00000008124bf353LL,0x00000008114e232fLL,0x000000081050430cLL,
+0x000000080f5262e9LL,0x000000080e5482c6LL,0x000000080d5692a4LL,0x000000080b588283LL,0x000000080a5a8262LL,0x00000008085c7241LL,0x00000008065e4222LL,0x0000000803600203LL,
+0x000000000061b1e5LL,0x00000000036351c8LL,0x000000000764d1acLL,0x000000000c664190LL,0x000000001067a176LL,0x000000001668e15cLL,0x000000001c6a1143LL,0x00000000236b212bLL,
+0x000000002a6c1115LL,0x00000000326cf0ffLL,0x000000003b6db0eaLL,0x00000000456e50d6LL,0x000000004f6ee0c3LL,0x000000005a6f50b1LL,0x00000000676f80a1LL,0x00000000746fb091LL,
+0x00000000826fc082LL,0x00000000916fc074LL,0x00000000a16f9067LL,0x00000000b16f405aLL,0x00000000c36ee04fLL,0x00000000d66e5045LL,0x00000000ea6db03bLL,0x00000000ff6cf032LL,
+0x00000001156c102aLL,0x000000012b6b2023LL,0x00000001436a101cLL,0x000000015c68e016LL,0x000000017667a010LL,0x000000019066400cLL,0x00000001ac64d007LL,0x00000001c8635003LL,
+0x00000001e561b000LL,0x0000000203600803LL,0x00000002225e4806LL,0x00000002415c6808LL,0x00000002625a880aLL,0x000000028358980bLL,0x00000002a456980dLL,0x00000002c654880eLL,
+0x00000002e952680fLL,0x000000030c504810LL,0x000000032f4e2811LL,0x00000003534bf812LL,0x000000037849b813LL,0x000000039c477814LL,0x00000003c1453814LL,0x00000003e642f815LL,
+0x000000080f407408LL,0x000000080e4293e5LL,0x000000080d44b3c2LL,0x000000080c46c3a0LL,0x000000080b48d37eLL,0x000000080a4ae35cLL,0x00000008084ce33aLL,0x00000008074ee319LL,
+0x000000080650e2f8LL,0x000000080452d2d7LL,0x000000080254b2b7LL,0x0000000000569297LL,0x0000000002586278LL,0x00000000055a2259LL,0x00000000085bd23bLL,0x000000000b5d821dLL,
+0x000000000f5f1200LL,0x00000000136091e4LL,0x000000001861f1c9LL,0x000000001d6351aeLL,0x0000000023649194LL,0x000000002965c17bLL,0x000000003066d163LL,0x000000003867d14bLL,
+0x000000004068c134LL,0x000000004969811fLL,0x00000000536a310aLL,0x000000005e6ac0f6LL,0x00000000696b40e3LL,0x00000000756bb0d0LL,0x00000000826bf0bfLL,0x00000000906c20aeLL,
+0x000000009f6c209fLL,0x00000000ae6c1090LL,0x00000000bf6bf082LL,0x00000000d06ba075LL,0x00000000e36b4069LL,0x00000000f66ad05eLL,0x000000010a6a3053LL,0x000000011f698049LL,
+0x000000013468b040LL,0x000000014b67d038LL,0x000000016366d030LL,0x000000017b65c029LL,0x0000000194649023LL,0x00000001ae63501dLL,0x00000001c961f018LL,0x00000001e4608013LL,
+0x00000002005f000fLL,0x000000021d5d700bLL,0x000000023b5bd008LL,0x00000002595a2005LL,0x0000000278586002LL,0x0000000297569000LL,0x00000002b754b802LL,0x00000002d752d804LL,
+0x00000002f850e806LL,0x00000003194ee807LL,0x000000033a4ce808LL,0x000000035c4ae80aLL,0x000000037e48d80bLL,0x00000003a046c80cLL,0x00000003c244b80dLL,0x00000003e542980eLL,
+0x0000000000400400LL,0x000000000141e3e1LL,0x000000000343a3c3LL,0x00000000044583a4LL,0x0000000006474386LL,0x0000000008490368LL,0x00000000094ae349LL,0x000000000c4c832cLL,
+0x000000000e4e430eLL,0x00000000105002f0LL,0x000000001351a2d3LL,0x00000000165342b6LL,0x000000001a54c29aLL,0x000000001e56427eLL,0x000000002257c262LL,0x0000000027592247LL,
+0x000000002c5a822cLL,0x00000000315be211LL,0x00000000385d01f8LL,0x000000003e5e41deLL,0x00000000455f61c5LL,0x000000004d6061adLL,0x0000000056614196LL,0x000000005f62217fLL,
+0x000000006962e169LL,0x000000007363a153LL,0x000000007e64413eLL,0x000000008a64c12aLL,0x0000000097652117LL,0x00000000a4658104LL,0x00000000b265c0f2LL,0x00000000c165e0e1LL,
+0x00000000d165e0d1LL,0x00000000e165d0c1LL,0x00000000f265b0b2LL,0x00000001046570a4LL,0x0000000117652097LL,0x000000012a64b08aLL,0x000000013e64307eLL,0x0000000153639073LL,
+0x000000016962e069LL,0x000000017f62205fLL,0x0000000196614056LL,0x00000001ad60504dLL,0x00000001c55f5045LL,0x00000001de5e403eLL,0x00000001f85d1038LL,0x00000002115bd031LL,
+0x000000022c5a902cLL,0x0000000247593027LL,0x000000026257c022LL,0x000000027e56501eLL,0x000000029a54c01aLL,0x00000002b6533016LL,0x00000002d351a013LL,0x00000002f04ff010LL,
+0x000000030e4e400eLL,0x000000032c4c900cLL,0x00000003494ad009LL,0x0000000368491008LL,0x0000000386474006LL,0x00000003a4457004LL,0x00000003c343a003LL,0x00000003e141d001LL,
+0x00000000233ee3efLL,0x00000000244063d6LL,0x000000002641c3beLL,0x00000000284333a5LL,0x000000002a44a38cLL,0x000000002c460374LL,0x000000002f47635bLL,0x000000003248b343LL,
+0x00000000354a132aLL,0x00000000394b5312LL,0x000000003e4c92f9LL,0x00000000424dd2e1LL,0x00000000484ef2c9LL,0x000000004d5022b1LL,0x0000000053514299LL,0x000000005a525281LL,
+0x0000000061536269LL,0x0000000069545252LL,0x000000007155423bLL,0x000000007a561225LL,0x000000008356f20eLL,0x000000008d57b1f8LL,0x00000000985861e2LL,0x00000000a35901cdLL,
+0x00000000af5991b8LL,0x00000000bb5a11a4LL,0x00000000c85a8190LL,0x00000000d55af17cLL,0x00000000e45b3169LL,0x00000000f25b8156LL,0x00000001015bb144LL,0x00000001115bc133LL,
+0x00000001225bc122LL,0x00000001335bc111LL,0x00000001445ba101LL,0x00000001565b70f2LL,0x00000001695b40e4LL,0x000000017c5af0d5LL,0x00000001905a80c8LL,0x00000001a45a10bbLL,
+0x00000001b85990afLL,0x00000001cd5900a3LL,0x00000001e2586098LL,0x00000001f857b08dLL,0x000000020e56f083LL,0x000000022556207aLL,0x000000023b554071LL,0x0000000252545069LL,
+0x0000000269535061LL,0x000000028152505aLL,0x0000000299514053LL,0x00000002b150204dLL,0x00000002c94f0048LL,0x00000002e14dd042LL,0x00000002f94c903eLL,0x00000003124b5039LL,
+0x000000032a4a0035LL,0x000000034348b032LL,0x000000035b47602fLL,0x000000037446002cLL,0x000000038c44a02aLL,0x00000003a5433028LL,0x00000003be41d026LL,0x00000003d6406024LL,
+0x00000000383e43e4LL,0x00000000393f93ceLL,0x000000003a40d3b9LL,0x000000003c4213a3LL,0x000000003e43538dLL,0x0000000041448377LL,0x000000004445b361LL,0x000000004846e34aLL,
+0x000000004c480334LL,0x000000005049231eLL,0x00000000554a3308LL,0x000000005a4b52f1LL,0x00000000604c52dbLL,0x00000000674d42c5LL,0x000000006e4e32afLL,0x00000000754f2299LL,
+0x000000007d500283LL,0x000000008650d26dLL,0x000000008f519258LL,0x0000000098526242LL,0x00000000a353022dLL,0x00000000ad53b218LL,0x00000000b9544203LL,0x00000000c454d1efLL,
+0x00000000d15541dbLL,0x00000000de55b1c7LL,0x00000000eb5611b4LL,0x00000000f95671a0LL,0x000000010856a18eLL,0x000000011756e17bLL,0x000000012657016aLL,0x0000000136572158LL,
+0x0000000147572147LL,0x0000000158571136LL,0x000000016a570126LL,0x000000017b56e117LL,0x000000018e56a108LL,0x00000001a05660f9LL,0x00000001b45610ebLL,0x00000001c755b0deLL,
+0x00000001db5540d1LL,0x00000001ef54d0c4LL,0x00000002035440b9LL,0x000000021853b0adLL,0x000000022d5310a3LL,0x0000000242526098LL,0x000000025851a08fLL,0x000000026d50d086LL,
+0x000000028350007dLL,0x00000002994f2075LL,0x00000002af4e406eLL,0x00000002c54d4067LL,0x00000002db4c5060LL,0x00000002f14b405aLL,0x00000003084a3055LL,0x000000031e492050LL,
+0x000000033448004cLL,0x000000034a46e048LL,0x000000036145b044LL,0x0000000377448041LL,0x000000038d43503eLL,0x00000003a342103cLL,0x00000003b940d03aLL,0x00000003ce3f9039LL,
+0x00000000453dd3deLL,0x00000000453f13caLL,0x00000000474043b5LL,0x00000000494163a1LL,0x000000004b42938cLL,0x000000004e43a378LL,0x000000005144c363LL,0x000000005445e34eLL,
+0x000000005946e339LL,0x000000005d47f324LL,0x000000006348e30fLL,0x000000006849f2f9LL,0x000000006f4ad2e4LL,0x00000000754bc2cfLL,0x000000007d4c92baLL,0x00000000854d62a5LL,
+0x000000008d4e3290LL,0x00000000964ef27bLL,0x000000009f4fb266LL,0x00000000a9506251LL,0x00000000b450f23dLL,0x00000000bf518229LL,0x00000000cb521214LL,0x00000000d7528201LL,
+0x00000000e452f1edLL,0x00000000f15351daLL,0x00000000ff53b1c6LL,0x000000010d53f1b4LL,0x000000011c5431a1LL,0x000000012b54618fLL,0x000000013a54917dLL,0x000000014b54916cLL,
+0x000000015b54a15bLL,0x000000016c54914bLL,0x000000017d54813aLL,0x000000018f54612bLL,0x00000001a154311cLL,0x00000001b453f10dLL,0x00000001c653b0ffLL,0x00000001da5360f1LL,
+0x00000001ed52f0e4LL,0x00000002015280d7LL,0x00000002145210cbLL,0x00000002295180bfLL,0x000000023d50f0b4LL,0x00000002515050a9LL,0x00000002664fb09fLL,0x000000027b4ef096LL,
+0x00000002904e308dLL,0x00000002a54d7085LL,0x00000002ba4c907dLL,0x00000002cf4bc075LL,0x00000002e44ad06fLL,0x00000002f949e068LL,0x000000030f48f063LL,0x000000032447f05dLL,
+0x000000033946f059LL,0x000000034e45e054LL,0x000000036344c051LL,0x000000037843b04eLL,0x000000038c42904bLL,0x00000003a1416049LL,0x00000003b5404047LL,0x00000003ca3f1045LL,
+0x00000000523d73d7LL,0x00000000533e93c4LL,0x00000000543fa3b2LL,0x000000005640b39fLL,0x000000005841d38bLL,0x000000005b42d378LL,0x000000005e43e364LL,0x000000006244d351LL,
+0x000000006645d33dLL,0x000000006b46c329LL,0x000000007147a315LL,0x0000000077488301LL,0x000000007d4962edLL,0x00000000854a32d8LL,0x000000008c4b02c4LL,0x00000000954bb2b0LL,
+0x000000009d4c729cLL,0x00000000a74d1288LL,0x00000000b14db274LL,0x00000000bb4e5260LL,0x00000000c64ee24cLL,0x00000000d14f7238LL,0x00000000dd4fe225LL,0x00000000ea504212LL,
+0x00000000f750b1feLL,0x00000001045111ebLL,0x00000001125151d9LL,0x00000001215191c6LL,0x000000012f51d1b4LL,0x000000013f51f1a2LL,0x000000014e521191LL,0x000000015e522180LL,
+0x000000016f52216fLL,0x000000018052215eLL,0x000000019152114eLL,0x00000001a251f13fLL,0x00000001b451c12fLL,0x00000001c6519121LL,0x00000001d9515112LL,0x00000001eb510104LL,
+0x00000001fe50b0f7LL,0x00000002125050eaLL,0x00000002254fe0ddLL,0x00000002384f60d1LL,0x000000024c4ee0c6LL,0x00000002604e50bbLL,0x00000002744dc0b1LL,0x00000002884d20a7LL,
+0x000000029c4c709dLL,0x00000002b04bb095LL,0x00000002c44af08cLL,0x00000002d84a3085LL,0x00000002ed49607dLL,0x0000000301488077LL,0x000000031547a071LL,0x000000032946c06bLL,
+0x000000033d45d066LL,0x000000035144d062LL,0x000000036443e05eLL,0x000000037842d05bLL,0x000000038b41d058LL,0x000000039f40c056LL,0x00000003b23fa054LL,0x00000003c43e9053LL,
+0x00000000593d33d4LL,0x00000000593e53c2LL,0x000000005a3f63b0LL,0x000000005c40739dLL,0x000000005e41738bLL,0x0000000061427378LL,0x0000000064437365LL,0x0000000068446352LL,
+0x000000006d45433fLL,0x000000007246332bLL,0x0000000078470318LL,0x000000007e47e304LL,0x000000008448c2f0LL,0x000000008c4972ddLL,0x00000000944a32c9LL,0x000000009c4af2b5LL,
+0x00000000a54ba2a1LL,0x00000000af4c328eLL,0x00000000b94cd27aLL,0x00000000c34d7266LL,0x00000000ce4df253LL,0x00000000da4e6240LL,0x00000000e64ee22cLL,0x00000000f34f4219LL,
+0x00000001004fa206LL,0x000000010d4ff1f4LL,0x000000011b5041e1LL,0x000000012a5071cfLL,0x000000013850b1bdLL,0x000000014850d1abLL,0x000000015750f19aLL,0x0000000167510189LL,
+0x0000000178510178LL,0x0000000189510167LL,0x000000019a50f157LL,0x00000001ab50d148LL,0x00000001bd50b138LL,0x00000001cf50812aLL,0x00000001e150411bLL,0x00000001f44ff10dLL,
+0x00000002064fa100LL,0x00000002194f40f3LL,0x000000022c4ee0e6LL,0x00000002404e70daLL,0x00000002534df0ceLL,0x00000002664d60c3LL,0x000000027a4cd0b9LL,0x000000028e4c40afLL,
+0x00000002a14ba0a5LL,0x00000002b54af09cLL,0x00000002c94a3094LL,0x00000002dd49808cLL,0x00000002f048b084LL,0x000000030447e07eLL,0x0000000318471078LL,0x000000032b463072LL,
+0x000000033f45506dLL,0x0000000352446068LL,0x0000000365437064LL,0x0000000378427061LL,0x000000038b41705eLL,0x000000039d40705cLL,0x00000003b03f605aLL,0x00000003c23e5059LL,
+0x00000000643ce3ceLL,0x00000000643df3bdLL,0x00000000653ef3acLL,0x00000000673fe39bLL,0x000000006940e389LL,0x000000006c41c378LL,0x000000006f42b366LL,0x000000007343a353LL,
+0x0000000078447341LL,0x000000007d45532eLL,0x000000008346131cLL,0x000000008946e309LL,0x000000009047a2f6LL,0x00000000984852e3LL,0x00000000a04902d0LL,0x00000000a849b2bdLL,
+0x00000000b24a42aaLL,0x00000000bb4ae297LL,0x00000000c64b6284LL,0x00000000d14be271LL,0x00000000dc4c625eLL,0x00000000e84cd24bLL,0x00000000f44d4238LL,0x00000001014da225LL,
+0x000000010e4df213LL,0x000000011c4e4200LL,0x000000012a4e81eeLL,0x00000001384ec1dcLL,0x00000001474ee1cbLL,0x00000001564f11b9LL,0x00000001664f21a8LL,0x00000001764f3197LL,
+0x00000001864f4186LL,0x00000001974f3176LL,0x00000001a84f2166LL,0x00000001b94f0156LL,0x00000001cb4ee147LL,0x00000001dc4eb138LL,0x00000001ee4e812aLL,0x00000002004e411cLL,
+0x00000002134df10eLL,0x00000002254da101LL,0x00000002384d40f4LL,0x000000024b4ce0e8LL,0x000000025e4c70dcLL,0x00000002714bf0d1LL,0x00000002844b70c6LL,0x00000002974ae0bbLL,
+0x00000002aa4a50b2LL,0x00000002bd49b0a8LL,0x00000002d04900a0LL,0x00000002e3485098LL,0x00000002f647a090LL,0x000000030946e089LL,0x000000031c462083LL,0x000000032e45507dLL,
+0x0000000341447078LL,0x000000035343a073LL,0x000000036642b06fLL,0x000000037841d06cLL,0x000000038940e069LL,0x000000039b3fe067LL,0x00000003ac3ef065LL,0x00000003bd3de064LL
+};
+
+const long long cof4tap[COEFF_DATA_NUM]=
+{
+0x0000000000400000LL,0x0000200809400411LL,0x0000201812bff420LL,0x000020201d3fc42eLL,0x0000202827bf8c3bLL,0x0000203833bf3c47LL,0x000020403fbedc52LL,0x000020504cbe645bLL,
+0x000020605a3de464LL,0x00002070683d4c6bLL,0x0000208076bcac72LL,0x00002090863bec77LL,0x000020a0963b247cLL,0x000020b0a6ba4c80LL,0x000020c8b7b96482LL,0x000020d8c9386c84LL,
+0x000020f0dbb76c86LL,0x00002108ee365c86LL,0x0000212101354486LL,0x0000213914b42486LL,0x0000215928b2fc85LL,0x000021713d31bc83LL,0x0000219151b08481LL,0x000021b166af3c7eLL,
+0x000021d17c2df47cLL,0x000021f1922c9478LL,0x00002211a7ab4475LL,0x00002231be29dc71LL,0x00002259d428846dLL,0x00002279eaa71c69LL,0x000022a20125bc65LL,0x000022c217a45461LL,
+0x000022e22e22e45cLL,0x0000230a45217c58LL,0x0000232a5ba01454LL,0x0000234a719eac4fLL,0x0000236a881d444bLL,0x0000238a9d9be446LL,0x000023aab41a7c42LL,0x000023c2c919243eLL,
+0x000023e2df17c43aLL,0x000023f2f3966c36LL,0x0000240b08151c32LL,0x0000241b1b93d42eLL,0x0000242b2f928c2bLL,0x0000243342114c27LL,0x0000243354101424LL,0x00002433658ee421LL,
+0x00002433768dbc1eLL,0x00002423868c941bLL,0x00002413960b7c19LL,0x00002403a48a6c16LL,0x000023e3b2096414LL,0x000023bbbe886412LL,0x00002393ca876c10LL,0x0000235bd486840eLL,
+0x00002323de05a40cLL,0x000022dbe604cc0aLL,0x00002293ed83fc08LL,0x0000223bf3833c07LL,0x000021dbf8827c05LL,0x00002173fc01d404LL,0x00002103ff012c03LL,0x0000208a00004a00LL,
+0x000020c868b3b8d1LL,0x000020d07233c0beLL,0x000020d07c33a8adLL,0x000020d886b3909cLL,0x000020e091b3708bLL,0x000020e09cb3387cLL,0x000020e8a833006dLL,0x000020f0b3b2c05fLL,
+0x000020f8c0327051LL,0x00002100cc321845LL,0x00002108d931b039LL,0x00002118e631482eLL,0x00002120f330d823LL,0x0000212900b05819LL,0x000021310eafc810LL,0x000021411caf3808LL,
+0x000021492aaea000LL,0x00002151392dfc07LL,0x0000216147ad5c0eLL,0x00002169562cac14LL,0x00002179652bf419LL,0x00002181742b341eLL,0x00002189832a7423LL,0x0000219192a9a427LL,
+0x00002199a1a8d42aLL,0x000021a1b127fc2dLL,0x000021a9c0a71c2fLL,0x000021b1cfa64c32LL,0x000021b9df256433LL,0x000021b9ee248435LL,0x000021b9fda39436LL,0x000021ba0ca2ac37LL,
+0x000021ba1ba1bc37LL,0x000021ba2aa0cc37LL,0x000021b2391fdc37LL,0x000021aa481ee437LL,0x0000219a561df437LL,0x00002192649cfc36LL,0x0000217a719c0c35LL,0x0000216a7f9b1434LL,
+0x000021528d1a1c33LL,0x0000213a9a192c32LL,0x0000211aa7183431LL,0x000020f2b3174430LL,0x000020cabf16542fLL,0x000020a2ca95642dLL,0x00002072d5947c2cLL,0x0000203adf93942aLL,
+0x00000002ea12ac29LL,0x00000042f391cc28LL,0x00000082fc90ec26LL,0x000000cb05900c25LL,0x0000011b0d8f3424LL,0x00000173148e6423LL,0x000001cb1b0d9421LL,0x0000022b218cc420LL,
+0x0000028b270c041fLL,0x000002fb2c0b3c1eLL,0x0000036b300a841dLL,0x000003e33389cc1cLL,0x0000045b37091c1cLL,0x000004e339086c1bLL,0x0000056b3a87c41aLL,0x000005f33c07241aLL,
+0x000020d87db128fbLL,0x000020d8873120e9LL,0x000020d8913110d7LL,0x000020e09b3100c6LL,0x000020e0a5b0d8b6LL,0x000020e0b030b0a6LL,0x000020e8bb308097LL,0x000020f0c6b04089LL,
+0x000020f0d22ff87bLL,0x000020f8de2fa86eLL,0x00002100ea2f5861LL,0x00002108f62f0055LL,0x0000210902ae904aLL,0x000021110f2e2040LL,0x000021191c2da836LL,0x00002121292d302cLL,
+0x0000212936aca024LL,0x0000212943ac181bLL,0x00002131512b8014LL,0x000021395f2ae00dLL,0x000021416caa4806LL,0x000021417aa99800LL,0x0000214988a8f406LL,0x000021499628440bLL,
+0x00002151a4278c0fLL,0x00002151b226cc13LL,0x00002151c0260c17LL,0x00002151ce25441aLL,0x00002149dc24741dLL,0x00002149ea23ac20LL,0x00002141f7a2dc22LL,0x0000213a05220c24LL,
+0x0000213213213426LL,0x0000212220a05427LL,0x000021122d9f7c28LL,0x000021023a9ea429LL,0x000020ea471dc429LL,0x000020d2541ce42aLL,0x000020ba609c042aLL,0x0000209a6c9b242aLL,
+0x0000207a789a442aLL,0x0000205a84196429LL,0x000020328f188c29LL,0x000000029997ac28LL,0x00000032a496cc28LL,0x0000006aae15f427LL,0x000000a2b8151426LL,0x000000dac1943c25LL,
+0x00000122ca136c25LL,0x00000162d3129424LL,0x000001b2da91c423LL,0x00000202e210f422LL,0x00000252e9102c21LL,0x000002aaf00f6421LL,0x0000030af58ea420LL,0x00000372fa8de41fLL,
+0x000003daff8d241eLL,0x0000044b040c6c1eLL,0x000004bb080bb41dLL,0x000005330b0b041cLL,0x000005b30d8a5c1cLL,0x000006331009b41cLL,0x000006bb1109141bLL,0x0000074b1208741bLL,
+0x000020c0a02cc140LL,0x000020b8a92cb92eLL,0x000020b8b22cb11dLL,0x000020b8bbac990dLL,0x000020b8c52c80fdLL,0x000020b8cf2c60edLL,0x000020b8d92c38deLL,0x000020b8e32c10cfLL,
+0x000020b8edabd8c1LL,0x000020b8f82b98b4LL,0x000020b9032b50a7LL,0x000020b90dab109aLL,0x000020b9192ab88eLL,0x000020b9242a6083LL,0x000020b92faa0078LL,0x000020b93aa9a86dLL,
+0x000020b146293863LL,0x000020b151a8c85aLL,0x000020b15da85051LL,0x000020a96927d848LL,0x000020a975275840LL,0x000020a180a6d039LL,0x000020998ca64032LL,0x0000209198a5b02bLL,
+0x00002089a4252025LL,0x00002081b024881fLL,0x00002071bba3f019LL,0x00002069c7235814LL,0x00002059d2a2b80fLL,0x00002041de22080bLL,0x00002031e9a16007LL,0x00002019f520b003LL,
+0x0000000200200000LL,0x0000001a0b1f5403LL,0x0000003a161e9c06LL,0x0000005a209de408LL,0x0000007a2b9d2c0bLL,0x000000a2359c740dLL,0x000000ca3f1bbc0eLL,0x000000fa489b0410LL,
+0x0000012a521a4411LL,0x0000015a5b198c12LL,0x000001926418cc13LL,0x000001ca6d180c14LL,0x0000020275975415LL,0x000002427d969415LL,0x0000028a8515dc16LL,0x000002d28c951c16LL,
+0x0000031a93946416LL,0x0000036a9a93ac17LL,0x000003c2a012fc17LL,0x0000041aa6124417LL,0x00000472ab919417LL,0x000004d2b110dc17LL,0x0000053ab5103417LL,0x000005a2b98f8417LL,
+0x0000060abd8edc17LL,0x0000067ac10e3417LL,0x000006f2c38d9417LL,0x0000076ac60cf417LL,0x000007eac80c5417LL,0x0000086ac98bbc17LL,0x000008eacb0b2417LL,0x00000972cb8a9417LL,
+0x00000000d0a5f1a1LL,0x00000008d825e992LL,0x00000010e025d983LL,0x00000010e7a5d974LL,0x00000018efa5c166LL,0x00000020f7a5a958LL,0x000000290025894aLL,0x000000310825713cLL,
+0x0000003910a5492fLL,0x0000004118a52922LL,0x000000512124f915LL,0x0000005929a4c909LL,0x00000061322498fdLL,0x000000713aa460f1LL,0x00000081432420e6LL,0x000000894c23e8daLL,
+0x0000009954a3a0d0LL,0x000000b15d2358c5LL,0x000000c165a310bbLL,0x000000d16ea2c0b1LL,0x000000e9772268a8LL,0x000001017fa2109fLL,0x000001198821b896LL,0x0000013190a1608dLL,
+0x000001519920f885LL,0x00000169a120a07dLL,0x00000189a9a03875LL,0x000001a9b19fd06eLL,0x000001d1b99f6067LL,0x000001f9c19ef060LL,0x00000221c99e785aLL,0x00000249d19e0054LL,
+0x00000271d91d904eLL,0x000002a1e01d1849LL,0x000002d1e79c9844LL,0x00000301ef1c183fLL,0x00000339f61b983aLL,0x00000371fd1b1835LL,0x000003aa039a9831LL,0x000003ea0a1a102dLL,
+0x0000042a0f99902aLL,0x0000046a16190826LL,0x000004b21b988023LL,0x000004fa2117f820LL,0x000005422697701dLL,0x0000058a2c16e81aLL,0x000005da31165818LL,0x0000062a3595d016LL,
+0x000006823a154813LL,0x000006d23e94c011LL,0x0000073242143010LL,0x0000078a4613a80eLL,0x000007ea4993200cLL,0x0000084a4c92980bLL,0x000008aa4f92100aLL,0x0000091252918808LL,
+0x0000097a54910807LL,0x000009e257108006LL,0x00000a5258900005LL,0x00000ac25a8f7804LL,0x00000b325c0ef803LL,0x00000ba25d8e7802LL,0x00000c1a5d8e0002LL,0x00000c925e8d8001LL,
+0x000000a8e422d9c8LL,0x000000b0eb22d1baLL,0x000000b0f1a2d9acLL,0x000000b8f8a2c99fLL,0x000000c0ffa2b992LL,0x000000d106a2a185LL,0x000000d90e228978LL,0x000000e11522796bLL,
+0x000000f11c22615eLL,0x000000f923a24152LL,0x000001092aa22146LL,0x000001193221f93aLL,0x0000012939a1d12eLL,0x0000013940a1a923LL,0x0000015148217118LL,0x000001614f21490dLL,
+0x0000017956a11102LL,0x000001915da0d8f8LL,0x000001a96520a0edLL,0x000001c96c2060e3LL,0x000001e173a018daLL,0x000002017a9fd8d0LL,0x00000221819f90c7LL,0x00000241889f48beLL,
+0x000002698f9ef8b5LL,0x00000289969ea8adLL,0x000002b19d1e58a5LL,0x000002d9a39e089dLL,0x00000309aa9da895LL,0x00000331b11d508eLL,0x00000361b71d0086LL,0x00000391bd9c9880LL,
+0x000003c9c39c3879LL,0x00000401c99bd872LL,0x00000431d01b706cLL,0x00000471d51b1066LL,0x000004a9da9aa861LL,0x000004e9e09a385bLL,0x00000529e599d056LL,0x00000569ea996851LL,
+0x000005a9ef98f84dLL,0x000005f1f4988848LL,0x00000639f9181844LL,0x00000681fd97a840LL,0x000006d20197383cLL,0x0000071a0616c039LL,0x0000076a0a165035LL,0x000007c20d95d832LL,
+0x000008121115682fLL,0x0000086a1494f02cLL,0x000008c21714802aLL,0x0000091a1a940827LL,0x000009721d139825LL,0x000009d21f932023LL,0x00000a322212a821LL,0x00000a922412381fLL,
+0x00000af22611c01eLL,0x00000b5a2791501cLL,0x00000bc22890e01bLL,0x00000c2a2a10681aLL,0x00000c922b8ff818LL,0x00000cfa2c8f8817LL,0x00000d622d8f1816LL,0x00000dd22d0eb016LL,
+0x00000118eda139dbLL,0x00000120f42131ceLL,0x00000128fa2131c1LL,0x0000013100a129b4LL,0x00000139072119a8LL,0x000001410da1119bLL,0x0000014914a0f98fLL,0x000001591b20e183LL,
+0x0000016121a0d177LL,0x000001712820b96bLL,0x000001812f209160LL,0x0000019135a07954LL,0x000001a93c205149LL,0x000001b942a0313eLL,0x000001d149a00133LL,0x000001e9501fd928LL,
+0x00000201569fb11dLL,0x000002215d1f7913LL,0x00000239639f4909LL,0x000002596a1f10ffLL,0x00000279709ed8f5LL,0x00000299769ea0ecLL,0x000002c17d1e60e2LL,0x000002e9831e20d9LL,
+0x00000311899dd8d0LL,0x000003398f9d90c8LL,0x00000361959d50bfLL,0x000003919b9d00b7LL,0x000003c1a11cb8afLL,0x000003f1a71c68a7LL,0x00000421ac9c18a0LL,0x00000459b21bc898LL,
+0x00000489b79b7891LL,0x000004c1bc9b208bLL,0x00000501c19ac884LL,0x00000539c69a707eLL,0x00000579cb9a1078LL,0x000005b9d019b872LL,0x000005f9d519586cLL,0x00000641d918f867LL,
+0x00000681dd989862LL,0x000006c9e218305dLL,0x00000711e617d058LL,0x00000761ea176853LL,0x000007a9ed97084fLL,0x000007f9f116a04bLL,0x00000849f4963847LL,0x00000899f795d044LL,
+0x000008e9fb156840LL,0x00000941fd95003dLL,0x0000099a0014983aLL,0x000009f203142837LL,0x00000a4a0513c035LL,0x00000aa207935832LL,0x00000b020912f030LL,0x00000b5a0b92802eLL,
+0x00000bba0d12182cLL,0x00000c1a0e11b02bLL,0x00000c7a0f914829LL,0x00000cda1110d828LL,0x00000d4211907027LL,0x00000da212900826LL,0x00000e0a130fa025LL,0x00000e72130f4024LL,
+0x000001a0f61fa1ecLL,0x000001a0fc1fa1e0LL,0x000001a9021f99d4LL,0x000001b1081f91c8LL,0x000001b90e1f81bdLL,0x000001c1141f79b1LL,0x000001c91a1f71a5LL,0x000001d9201f599aLL,
+0x000001e9261f498eLL,0x000001f92c1f3183LL,0x00000209321f1978LL,0x00000219381f016dLL,0x000002313e1ee162LL,0x00000249441ec157LL,0x000002614a1e994dLL,0x000002794f9e8142LL,
+0x00000299559e5138LL,0x000002b95b9e212eLL,0x000002d9611df924LL,0x000002f9671dc91aLL,0x000003196c9da110LL,0x00000341721d6907LL,0x00000369779d38fdLL,0x000003917d1d00f4LL,
+0x000003c1829cc0ebLL,0x000003e9881c88e2LL,0x000004198d1c48daLL,0x00000449929c08d1LL,0x00000479979bc8c9LL,0x000004b19c9b80c1LL,0x000004e1a19b40b9LL,0x00000519a61af8b2LL,
+0x00000551ab1ab0aaLL,0x00000591af9a60a3LL,0x000005c9b41a189cLL,0x00000609b819c896LL,0x00000649bc99788fLL,0x00000689c0992889LL,0x000006d1c498d083LL,0x00000711c898807dLL,
+0x00000759cc182878LL,0x000007a1d017d072LL,0x000007e9d397786dLL,0x00000839d6972068LL,0x00000881da16c863LL,0x000008d1dc96705fLL,0x00000921df96105bLL,0x00000971e215b857LL,
+0x000009c1e5155853LL,0x00000a11e814f84fLL,0x00000a69e994a04cLL,0x00000ab9ec144049LL,0x00000b11ee13e046LL,0x00000b69f0138043LL,0x00000bc1f1932041LL,0x00000c19f312c03fLL,
+0x00000c71f492603dLL,0x00000cd1f592003bLL,0x00000d29f711a039LL,0x00000d89f7914038LL,0x00000de9f810e037LL,0x00000e41f9108036LL,0x00000ea1f9902035LL,0x00000f01fa0fc034LL,
+0x000001e0fa1ee1f4LL,0x000001e0ff9ee9e8LL,0x000001e9059ed9ddLL,0x000001f10b1ed9d1LL,0x000001f9111ec9c6LL,0x00000201169ec9baLL,0x000002091c9eb9afLL,0x00000219221ea9a4LL,
+0x00000229281e9199LL,0x000002392d9e818eLL,0x00000249331e7183LL,0x00000261391e5178LL,0x000002793e9e316eLL,0x00000291441e1963LL,0x000002a94a1df958LL,0x000002c14f9dd94eLL,
+0x000002e1551db144LL,0x000003015a9d893aLL,0x00000321601d6130LL,0x00000349659d3126LL,0x000003696a9d091dLL,0x00000391701cd913LL,0x000003b9751ca90aLL,0x000003e97a1c7101LL,
+0x000004117f9c38f8LL,0x00000441849c00efLL,0x00000471891bd0e6LL,0x000004a18e1b90deLL,0x000004d1931b58d5LL,0x00000509979b18cdLL,0x000005419c1ad8c5LL,0x00000579a09a90beLL,
+0x000005b1a51a50b6LL,0x000005f1a91a08afLL,0x00000629ad99c0a8LL,0x00000669b19978a1LL,0x000006a9b599309aLL,0x000006f1b918e094LL,0x00000731bd18908eLL,0x00000779c0184888LL,
+0x000007c1c397f882LL,0x00000809c717a07dLL,0x00000851ca975077LL,0x00000899cd970072LL,0x000008e9d096a86dLL,0x00000931d3165869LL,0x00000981d6160064LL,0x000009d1d895a860LL,
+0x00000a21db15505cLL,0x00000a71dd94f858LL,0x00000ac1df94a055LL,0x00000b19e1944052LL,0x00000b71e313e84fLL,0x00000bc1e513904cLL,0x00000c19e7133049LL,0x00000c71e812d847LL,
+0x00000cc9e9128045LL,0x00000d21ea922043LL,0x00000d79eb91c841LL,0x00000dd1ec916840LL,0x00000e31ec91103fLL,0x00000e89ed90b03eLL,0x00000ee9ed90583dLL,0x00000f41ee8ff83cLL,
+0x00000250ff9dc1ffLL,0x00000251051dc1f4LL,0x000002590a1dc1e9LL,0x000002590f9db9dfLL,0x00000261151db1d4LL,0x000002711a9da1c9LL,0x000002791f9da1beLL,0x00000289251d89b4LL,
+0x000002992a9d79a9LL,0x000002a92f9d699fLL,0x000002b9351d5994LL,0x000002d13a1d418aLL,0x000002e93f9d297fLL,0x00000301449d1175LL,0x00000321499cf16bLL,0x000003394e9cd961LL,
+0x00000359539cb957LL,0x00000381589c914dLL,0x000003a15d9c7143LL,0x000003c9629c413aLL,0x000003f1671c2130LL,0x000004196c1bf127LL,0x00000441709bc91eLL,0x00000471751b9915LL,
+0x000004997a1b690cLL,0x000004c97e1b4103LL,0x00000501829b08faLL,0x00000531871ad0f2LL,0x000005698b1aa0e9LL,0x000005a18f9a60e1LL,0x000005d9939a28d9LL,0x000006119799f0d1LL,
+0x000006519b19b0caLL,0x000006899f1978c2LL,0x000006c9a29938bbLL,0x00000709a618f8b4LL,0x00000749aa18b0adLL,0x00000791ad1870a6LL,0x000007d1b09828a0LL,0x00000819b417e099LL,
+0x00000861b697a093LL,0x000008a9b997508eLL,0x000008f1bc970888LL,0x00000939bf16c083LL,0x00000981c216707eLL,0x000009d1c4162879LL,0x00000a19c715d874LL,0x00000a69c9158870LL,
+0x00000ab9cb95386bLL,0x00000b09cd94e867LL,0x00000b59cf149864LL,0x00000ba9d1144860LL,0x00000bf9d293f85dLL,0x00000c51d413a05aLL,0x00000ca1d5935057LL,0x00000cf9d692f855LL,
+0x00000d49d792a853LL,0x00000da1d8925051LL,0x00000df1da11f84fLL,0x00000e49da11a84eLL,0x00000ea1db11504cLL,0x00000ef9db90f84bLL,0x00000f49dc10a04bLL,0x00000fa1dc10504aLL
+};
+
+
+const long long cof6tap[COEFF_DATA_NUM]=
+{
+0x0000000080000000LL,0x00c050197fe83005LL,0x0140a0347fa85e09LL,0x01c1004f7f48880eLL,0x0241606c7ed8b212LL,0x0241c08a7e58d815LL,0x02c230a87db8fc19LL,0x034290c87ce91e1cLL,
+0x03c300e97c093c1eLL,0x0443710b7b095a21LL,0x04c3f12e79f97423LL,0x0544615278b98c25LL,0x05c4e1777769a227LL,0x06c5619d75e9b629LL,0x0745e1c37479c82aLL,0x07c661eb72d9d82bLL,
+0x0846f2137129e42cLL,0x08c7723b6f69f02dLL,0x0947f2656d89fa2dLL,0x0a48828e6baa022dLL,0x0ac902b9699a082dLL,0x0b4992e4677a0a2dLL,0x0c4a130f654a0e2dLL,0x0cca933b62fa0e2dLL,
+0x0d4b236660ca0c2cLL,0x0e4ba3925e5a0a2cLL,0x0ecc13be5bea062bLL,0x0f4c93eb596a002aLL,0x104d041756d9fa29LL,0x10cd74435449f228LL,0x114de46f51b9ea27LL,0x124e449a4f09e026LL,
+0x12cea4c54c59d425LL,0x134f04f049a9c824LL,0x13cf551b46f9bc22LL,0x144f95444439ae21LL,0x14cfd56d4179a020LL,0x155005963eb9921eLL,0x15d035be3be9821dLL,0x165055e53929741cLL,
+0x1650660c3669641aLL,0x16d0762f33b95219LL,0x16d0765430f94218LL,0x16d056772e493216LL,0x16d046992b992015LL,0x16d016ba28e91014LL,0x16cfd6d82658fe12LL,0x16cf86f623b8ee11LL,
+0x164f27122138de10LL,0x15cec72d1eb8cc0fLL,0x154e47471c38bc0eLL,0x14cdb75e19d8ac0dLL,0x13cd177617789c0bLL,0x12cc678b15288c0aLL,0x11cba79f12e87e09LL,0x10cad7b010b86e08LL,
+0x0f49e7c00e986007LL,0x0e48f7ce0c885206LL,0x0cc7e7db0a884605LL,0x0ac6c7e508a83804LL,0x094597ed06c82c04LL,0x074447f404f82003LL,0x04c2f7fa03481402LL,0x02c187fe01980a01LL,
+0x0846012666424d60LL,0x0846413e6622215cLL,0x084681556621f358LL,0x0846c16e65e1c954LL,0x0847018665b19f50LL,0x0847319f6561754cLL,0x084771b965014d48LL,0x0847b1d364912744LL,
+0x07c7e1ed64210140LL,0x07c8220863a0dd3dLL,0x07c852236300b939LL,0x07c8823e62509735LL,0x07c8b25a61907732LL,0x0748e27660d0572eLL,0x074902925ff0392bLL,0x074932ae5f101d28LL,
+0x06c952ca5e300125LL,0x06c972e65d281b21LL,0x064983035c18351eLL,0x0649a3205b084d1cLL,0x05c9b33c59e86319LL,0x05c9b35958887716LL,0x0549c37557788d14LL,0x0549c39256089f11LL,
+0x04c9c3ae54c8b10fLL,0x0449b3cb5358c10dLL,0x03c9a3e751e8d10aLL,0x034984035068df08LL,0x02c9641e4ef8eb07LL,0x0249443a4d68f705LL,0x01c914554bd90303LL,0x00c8e46f4a490b01LL,
+0x0048a48a48a91400LL,0x80c854a446f91c01LL,0x81c814bd45592203LL,0x82c7b4d643a92804LL,0x83c754ef41e92c05LL,0x8446f50640393006LL,0x8546851e3e793407LL,0x86c605353cb93608LL,
+0x87c5854c3ae93809LL,0x88c4f5603929380aLL,0x8a4465773759380aLL,0x8b43b5883599360bLL,0x8cc3159e33c9360bLL,0x8e4265b03209340cLL,0x8f41a5c13039300cLL,0x90c0d5d22e692e0dLL,
+0x928005e32ca92a0dLL,0x9400e5f12ae9260eLL,0x9581c5ff2929200eLL,0x9702b60d27691c0eLL,0x9903b61925a9160fLL,0x9a84b62523e9100fLL,0x9c85c63022390a0fLL,0x9e86e63a2089040fLL,
+0xa00806421ed8fc0fLL,0xa20936491d38f610LL,0xa40a66501b98ee10LL,0xa60ba65619f8e610LL,0xa80cf65b1868e010LL,0xaa0e465e16e8d810LL,0xac0f96621558d010LL,0xae11066213e8c810LL,
+0x06c6515e6012bd65LL,0x0646817460129362LL,0x0646a18a5ff2695fLL,0x05c6d1a15fe23f5cLL,0x05c701b85fa21758LL,0x05c721cf5f51f155LL,0x054751e75f21c952LL,0x054771ff5eb1a54fLL,
+0x04c792175e617f4cLL,0x04c7b22f5de15b48LL,0x0447d2485d613945LL,0x0447f2615cd11742LL,0x03c8027a5c30f73fLL,0x03c812935b80d73cLL,0x034822ac5ad0b939LL,0x034832c55a109b36LL,
+0x02c832df59307f33LL,0x024842f858706330LL,0x024843125770492dLL,0x01c8332b5670312aLL,0x0148234555701928LL,0x00c8135e54700125LL,0x0048037753681722LL,0x80c7e39152382b20LL,
+0x8147c3aa51183f1eLL,0x81c7a3c34fe8531bLL,0x824773db4eb86519LL,0x834733f44d687517LL,0x83c7040c4c288515LL,0x84c6c4244ad89313LL,0x8546743c4968a111LL,0x864624534818af0fLL,
+0x86c5d46a46a8bb0dLL,0x87c574814538c50cLL,0x88c5049643c8cf0aLL,0x89c494ad4248d909LL,0x8ac424c240c8e107LL,0x8bc3a4d63f48e706LL,0x8cc324eb3db8ef04LL,0x8dc294fe3c38f503LL,
+0x8f41f5113aa8f902LL,0x904155233918fd01LL,0x9140b53637790000LL,0x9280054735e90201LL,0x9400c55734590402LL,0x9501856732b90603LL,0x9682457731290804LL,0x980315872f890804LL,
+0x9983f5932df90605LL,0x9b04d5a12c590606LL,0x9c85c5ad2ac90406LL,0x9e06b5b829390207LL,0x9f87b5c327a90007LL,0xa108b5cd2618fe08LL,0xa289c5d62488fa08LL,0xa40ad5de22f8f609LL,
+0xa60bf5e62178f209LL,0xa78d25eb1ff8ee0aLL,0xa90e45f21e78ea0aLL,0xaa8f85f51cf8e40bLL,0xac10b5fa1b88e00bLL,0xae11f5fe1a18da0bLL,0xaf9345ff18a8d40cLL,0xb11496011748d00cLL,
+0x004571b054e36157LL,0x80c581c354e33d56LL,0x80c591d654d31955LL,0x814591e954c2f554LL,0x814591fd5492d153LL,0x81c5a2105472af51LL,0x8245a22454428d50LL,0x8245923853e26b4eLL,
+0x82c5924c53b2494dLL,0x834592605362294bLL,0x8345827452f20949LL,0x83c5728852a1e948LL,0x8445629c5231cb46LL,0x84c542b151a1ad44LL,0x854522c551218f42LL,0x854502d950817340LL,
+0x85c4e2ed4ff1573eLL,0x8644c3024f413d3cLL,0x86c493164e91233aLL,0x8744632a4de10938LL,0x87c4233e4d20ef36LL,0x8843f3524c60d734LL,0x8943b3664b90c132LL,0x89c363794ac0a930LL,
+0x8a43238d49e0932eLL,0x8ac2d3a048f07f2cLL,0x8bc273b348006b2aLL,0x8c4223c647205729LL,0x8d41c3d846304527LL,0x8dc153eb45103325LL,0x8ec0f3fd44202123LL,0x8f40740e43101122LL,
+0x9000042042000120LL,0x9100843140e80f1eLL,0x918104423fd81f1dLL,0x928194513eb82b1bLL,0x938224633d88391aLL,0x9482b4723c684518LL,0x950354803b384f17LL,0x9603f48f3a085b15LL,
+0x9704949e38d86514LL,0x980544ac37986d13LL,0x990604b936687712LL,0x9a06b4c635287f10LL,0x9b0774d233e8850fLL,0x9c0844de32a88d0eLL,0x9d0914e93168930dLL,0x9e09e4f43028990cLL,
+0x9f0ab4ff2ed89d0bLL,0xa00b95082d98a10aLL,0xa10c75122c58a50aLL,0xa20d651a2b18a909LL,0xa30e552329c8ad08LL,0xa40f452a2888af07LL,0xa490452f2748b106LL,0xa59145362608b306LL,
+0xa692453b24c8b305LL,0xa713553e2388b304LL,0xa81465442248b504LL,0xa89575472108b503LL,0xa99685491fd8b302LL,0xaa17a54c1e98b302LL,0xaa98c54d1d68b301LL,0xab19e54e1c38b101LL,
+0x890001ff4143fe00LL,0x8900320c4123e702LL,0x890052184133cf05LL,0x890082244123b707LL,0x8900b23141139d09LL,0x8900f23d40f3850bLL,0x8981224a40e36d0dLL,0x8981525640c3550eLL,
+0x8981926340833f10LL,0x8981d26f40532711LL,0x8a02127b40430f13LL,0x8a0252883ff2f914LL,0x8a02a2943fb2e115LL,0x8a02e2a03f72cb16LL,0x8a8332ac3f32b517LL,0x8a8382b83ee29f18LL,
+0x8a83d2c43e828918LL,0x8b0422d03e427319LL,0x8b0482dc3dd25d19LL,0x8b04e2e73d82471aLL,0x8b8542f33d12331aLL,0x8b85a2fe3cb21f1bLL,0x8b86030a3c320b1bLL,0x8c0663153bd1f71bLL,
+0x8c06d3203b51e31bLL,0x8c87432b3ae1cf1bLL,0x8c87b3353a61bd1bLL,0x8c88234039d1ab1bLL,0x8d08a34a3951991bLL,0x8d09135438d1871bLL,0x8d09935e3841751bLL,0x8d0a136837b1631bLL,
+0x8d8a93723721531bLL,0x8d8b137b3681431aLL,0x8d8ba38435e1331aLL,0x8d8c338d3541231aLL,0x8d8cc39534a1151aLL,0x8d8d539d34010519LL,0x8d8de3a63350f719LL,0x8d8e73ae32b0e919LL,
+0x8d8f13b53200db18LL,0x8d8fb3bd3150cd18LL,0x8d9053c330a0c117LL,0x8d90f3cb2fe0b517LL,0x8d1193d12f30a917LL,0x8d1233d82e709d16LL,0x8c92e3dd2dc09116LL,0x8c9393e42d008516LL,
+0x8c1443e82c407b15LL,0x8c14f3ee2b807115LL,0x8b95a3f32ac06715LL,0x8b1653f72a005d14LL,0x8a9703fb29405514LL,0x8a17c3ff28804b14LL,0x8998740427b04314LL,0x8899340526f03b13LL,
+0x8819f40826303313LL,0x871aa40c25602b13LL,0x869b640e24a02513LL,0x859c240f23d01f12LL,0x849ce41123101712LL,0x839db41222401112LL,0x829e741321800b12LL,0x811f341220c00712LL,
+0x8584120737b40e41LL,0x8584421037c3fc3dLL,0x8584821a37a3ea3aLL,0x8504c2233793d836LL,0x8505022c3793c433LL,0x850542353783b230LL,0x8505823e3773a02dLL,0x8505d24737538e2aLL,
+0x8486125037337c27LL,0x8486625937136825LL,0x8486b26236f35622LL,0x8487026a36d34420LL,0x8487527336b3321dLL,0x8407a27c3673201bLL,0x8407f28436530e19LL,0x8408428d3622fc17LL,
+0x8408a29535e2ec15LL,0x8389029e3592da13LL,0x838952a63572c811LL,0x8389b2ae3532b610LL,0x830a12b634e2a60eLL,0x830a72be34b2940cLL,0x830ae2c63452840bLL,0x828b42ce34027409LL,
+0x828ba2d533d26208LL,0x820c12dd33625207LL,0x820c82e433124206LL,0x818cf2eb32b23205LL,0x818d62f332522204LL,0x810dd2f932021203LL,0x808e430031920402LL,0x808eb3073141f401LL,
+0x000f330d30d1e600LL,0x008fa3143071d701LL,0x011023193001c901LL,0x019093202f91bb02LL,0x021113252f31ad03LL,0x0291932b2eb19f03LL,0x031213312e419104LL,0x039293362dd18304LL,
+0x0413133d2d517505LL,0x0493a3402ce16905LL,0x059423452c615d06LL,0x0614a34b2be14f06LL,0x0715334e2b614306LL,0x0815b3532ae13707LL,0x089643572a612b07LL,0x0996d35929e12107LL,
+0x0a97635e29511508LL,0x0b97e36228d10908LL,0x0c9873652840ff08LL,0x0d99036727c0f508LL,0x0e99936b2730eb09LL,0x101a236d26a0e109LL,0x111ab36f2620d709LL,0x129b43712590cd09LL,
+0x139be3732500c309LL,0x151c73752470bb0aLL,0x169d037723e0b10aLL,0x181d93782350a90aLL,0x199e237922c0a10aLL,0x1b1ec3792230990aLL,0x1d1f537a21a0910bLL,0x1e9fe37c2100890bLL,
+0x0006820332a40668LL,0x0006c20b3293f864LL,0x008702123293e860LL,0x0087421a3283da5cLL,0x008782213283ca59LL,0x0107d2283273ba55LL,0x010812303263aa52LL,0x0188623732439c4eLL,
+0x0188b23e32338c4bLL,0x0188f24532337c48LL,0x0209424c32036e45LL,0x0209925431e35e42LL,0x0289e25a31c3503fLL,0x028a326131b3403cLL,0x030a926831833039LL,0x030ae26f31532237LL,
+0x038b327631331234LL,0x040b927c30f30432LL,0x040bf28330d2f42fLL,0x048c428930a2e62dLL,0x050ca2903062d62bLL,0x050d02963032c829LL,0x058d629c2ff2ba27LL,0x060dc2a22fc2aa25LL,
+0x068e22a82f829c23LL,0x070e82ae2f428e21LL,0x078ef2b42ef2801fLL,0x080f52ba2ec2701dLL,0x088fb2bf2e82621cLL,0x091022c52e32541aLL,0x099082ca2de24819LL,0x0a90f2cf2d923a17LL,
+0x0b1162d42d422c16LL,0x0b91d2d92cf21e15LL,0x0c9242de2ca21013LL,0x0d12a2e32c520412LL,0x0e1312e82bf1f611LL,0x0e9382ec2ba1ea10LL,0x0f9402ef2b41de0fLL,0x109472f42ae1d00eLL,
+0x1194e2f82a81c40dLL,0x129552fc2a21b80cLL,0x1395d2ff29c1ac0bLL,0x149643032961a00aLL,0x1596b3062901940aLL,0x1697330a28918809LL,0x1797a30d28317e08LL,0x1918230f27c17208LL,
+0x1a18931327616607LL,0x1b99131526f15c06LL,0x1c99831826815206LL,0x1e1a031b26114605LL,0x1f9a831c25a13c05LL,0x211af31e25413204LL,0x229b732024c12804LL,0x241be32324511e03LL,
+0x259c632323e11603LL,0x271ce32423710c03LL,0x291d532623010202LL,0x2a9dd3272280fa02LL,0x2c9e53282210f001LL,0x2e1ed32821a0e801LL,0x301f43292120e001LL,0x321fc32920b0d800LL,
+0x090901fa2da3f490LL,0x090942002da3e88cLL,0x090982062da3dc88LL,0x0989d20c2d83d084LL,0x098a12112d93c480LL,0x098a62172d83b87cLL,0x0a0aa21d2d83aa78LL,0x0a0af2232d639e75LL,
+0x0a8b32282d639271LL,0x0b0b822e2d33866eLL,0x0b0bd2332d337a6aLL,0x0b8c22392d136c67LL,0x0c0c723e2d036063LL,0x0c0cc2432cf35460LL,0x0c8d12492cc3485dLL,0x0d0d624e2cb33a5aLL,
+0x0d8db2532c932e57LL,0x0e0e02582c732254LL,0x0e8e625d2c431651LL,0x0f0eb2622c33084eLL,0x0f8f02672c02fc4cLL,0x100f626c2bd2f049LL,0x108fb2702bc2e446LL,0x119012752b82d644LL,
+0x1210627a2b62ca41LL,0x1290c27e2b32be3fLL,0x139122822af2b23dLL,0x141172872ac2a63bLL,0x1511d28b2a929a38LL,0x1592328f2a628e36LL,0x169292932a228234LL,0x1792f29729e27632LL,
+0x1893529b29926a31LL,0x1913b29e29725e2fLL,0x1a1412a22932522dLL,0x1b1472a628f2462bLL,0x1c14d2a928b23a2aLL,0x1d9532ac28722e28LL,0x1e9592af28222427LL,0x1f95f2b327e21825LL,
+0x209652b627a20c24LL,0x2216b2b827520223LL,0x231722bc2701f621LL,0x249782bd26c1ec20LL,0x2617e2c02671e01fLL,0x271842c32621d61eLL,0x2898b2c425d1cc1dLL,0x2a1912c72581c01cLL,
+0x2b9972c92531b61bLL,0x2d19d2cb24e1ac1aLL,0x2e9a42cc2491a219LL,0x301aa2cf24319818LL,0x319b02d023e18e18LL,0x339b62d123918417LL,0x351bd2d323317a16LL,0x371c32d322e17016LL,
+0x389c92d622816615LL,0x3a9cf2d622315e14LL,0x3c1d52d821d15414LL,0x3e1dc2d821714c13LL,0x401e22d921114213LL,0x421e82d820c13a13LL,0x441ee2da20613012LL,0x461f42da20012812LL,
+0x0e0a31f42b63e8a3LL,0x0e0a71f92b63de9fLL,0x0e8ab1fe2b63d29bLL,0x0e8b02042b43c897LL,0x0e8b42092b53bc93LL,0x0f0b820e2b43b28fLL,0x0f0bd2132b43a68bLL,0x0f8c12182b339c87LL,
+0x0f8c621d2b339083LL,0x100cb2222b038680LL,0x108cf2262b137a7cLL,0x108d422b2af37079LL,0x110d92302ae36475LL,0x118de2342ad35872LL,0x120e32392ab34e6eLL,0x128e823e2a93426bLL,
+0x130ed2422a733868LL,0x138f22472a532c65LL,0x140f724b2a432062LL,0x148fc24f2a23165fLL,0x159012532a030a5cLL,0x1610625829e2fe59LL,0x1690b25c29c2f456LL,0x179112602982e854LL,
+0x181162642972dc51LL,0x1911b2672942d24fLL,0x1992126b2922c64cLL,0x1a92626f28f2ba4aLL,0x1b92b27228d2b047LL,0x1c9312762892a445LL,0x1d93627928629a43LL,0x1e93c27d28228e41LL,
+0x1f9412802802823fLL,0x2094728227d2783dLL,0x2194d28627926c3bLL,0x2295228927626239LL,0x2395828d27225637LL,0x2515d28f26f24c35LL,0x2616329226b24233LL,0x2796929426723632LL,
+0x2896e29726422c30LL,0x2a1742982602222fLL,0x2b17a29c25c2162dLL,0x2c97f29e25820c2cLL,0x2e1852a02532022bLL,0x2f98b2a224f1f829LL,0x311902a424b1ee28LL,0x329962a52471e427LL,
+0x3419c2a72421da26LL,0x359a12a923e1d025LL,0x371a72ab2391c624LL,0x391ac2ad2341bc23LL,0x3a9b22ae2301b222LL,0x3c9b82af22b1a821LL,0x3e1bd2b122619e21LL,0x401c32b022219620LL,
+0x419c82b321d18c1fLL,0x439ce2b32181821fLL,0x459d32b421317a1eLL,0x479d92b420e1701eLL,0x499de2b52091681dLL,0x4b9e42b42041601dLL,0x4d9e92b61fe1561dLL,0x4f9ef2b61f914e1cLL,
+0x180c11e827e3d0c1LL,0x180c51ec27e3c8bdLL,0x180c91f127d3c0b9LL,0x188cd1f527d3b6b5LL,0x188d21f927c3aeb1LL,0x188d61fd27c3a6adLL,0x190da20127c39ca9LL,0x190df20527b394a5LL,
+0x198e320927b38aa1LL,0x198e720c27c3829dLL,0x1a0ec21027a3789aLL,0x1a8f021427a36e96LL,0x1b0f521827836692LL,0x1b8f921b27835c8fLL,0x1c0fe21f2763548bLL,0x1c90322327434a88LL,
+0x1d10722627434085LL,0x1d90c22927333881LL,0x1e91122d27032e7eLL,0x1f1152302703247bLL,0x2011a23326e31a78LL,0x2091f23726b31275LL,0x2192323a26a30872LL,0x2212823d2692fe6fLL,
+0x2312d2402672f46cLL,0x241322432652ea69LL,0x251372462622e266LL,0x2613b2492612d863LL,0x2714024b25f2ce61LL,0x2814524e25d2c45eLL,0x2914a25125a2ba5cLL,0x2a14f2532592b059LL,
+0x2b9542562542a857LL,0x2c95825925329e54LL,0x2e15d25a25129452LL,0x2f16225d24e28a50LL,0x3096725f24b2804eLL,0x3196c2612492764cLL,0x3317126224626e4aLL,0x3497526524326448LL,
+0x3617a26724025a46LL,0x3797f26923d25044LL,0x3918426a23a24643LL,0x3a98926b23723e41LL,0x3c18d26e23323440LL,0x3d99227023022a3eLL,0x3f19727022d2223dLL,0x4099c2732292183bLL,
+0x429a027422620e3aLL,0x441a527422320639LL,0x459aa27621f1fc38LL,0x479ae27821b1f237LL,0x491b32782181ea36LL,0x4b1b727a2141e035LL,0x4d1bc27a2101d834LL,0x4e9c127c20c1ce33LL,
+0x509c527b2091c633LL,0x529ca27b2051be32LL,0x549ce27c2011b432LL,0x569d327c1fd1ac31LL,0x589d727c1f91a431LL,0x5a9db27d1f519a31LL,0x5c9e027d1f119230LL,0x5e9e427e1ec18a30LL
+};
+
+#endif
+
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/arch/arm/mach-celestial/include/mach/cnc1900_vpp_reg_def.h linux-linaro-3.4-2012.05-1_cavium/arch/arm/mach-celestial/include/mach/cnc1900_vpp_reg_def.h
--- linux-linaro-3.4-2012.05-1_original/arch/arm/mach-celestial/include/mach/cnc1900_vpp_reg_def.h	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/arch/arm/mach-celestial/include/mach/cnc1900_vpp_reg_def.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,2388 @@
+#ifndef __CNC1900_VPP_REG_DEF_H_
+#define __CNC1900_VPP_REG_DEF_H_
+
+#define TVE0_REG_BASE		0x80168000
+#define TVE0_REG_SIZE		0x00001000
+#define TVE1_REG_BASE		0x80160000
+#define TVE1_REG_SIZE		0x00001000
+
+#define     VPP_REG_BASE                0xb1800000
+#define 	  VPP_REG_SIZE			0x1000
+
+#define     VPP_REG_CTRL_BASE           (VPP_REG_BASE + (0x000 << 2 ))//CTRL     //0-6    ----1
+#define     VPP_REG_GFX_DMA_BASE        (VPP_REG_BASE + (0x020 << 2 ))//GFX_S    //0-9    ----1
+#define     VPP_REG_GFX_UI1_BASE         (VPP_REG_BASE + (0x050 << 2 ))//GFX_U    //0-9    ----1
+#define     VPP_REG_GFX_UI2_BASE       (VPP_REG_BASE + (0x040 << 2 ))//GFX_U    //0-9    ----1
+#define     VPP_REG_HD2SD_RD_BASE       (VPP_REG_BASE + (0x060 << 2) )//HD2SD_RD //0-8    ----1
+#define     VPP_REG_CAP_BASE           (VPP_REG_BASE + (0x080 << 2 ))//CAP //0-19   ----2
+#define     VPP_REG_COMP_BASE           (VPP_REG_BASE + (0x0a0 << 2 ))//ENH      //0-4    ----1
+#define     VPP_REG_TG1_BASE            (VPP_REG_BASE + (0x0b0 << 2 ))//DISP1    //0-7    ----1
+#define     VPP_REG_TG2_BASE            (VPP_REG_BASE + (0x0c0 << 2 ))//DISP2    //0-7    ----1
+#define     VPP_REG_MAIN_CH_BASE        (VPP_REG_BASE + (0x100 << 2 ))//MCH      //0-40   ----3
+#define     VPP_REG_SR_CH_BASE          (VPP_REG_BASE + (0x140 << 2 ))//SR       //0-33   ----2
+/***********GLB_CTRL_Register******/
+#define     VPP_REG_GLB_CTRL_H_UPDATE_REG         ((VPP_REG_CTRL_BASE       ) + ( 0 << 2))
+#define     VPP_REG_GLB_CTRL_M_UPDATE_REG         ((VPP_REG_CTRL_BASE       ) + ( 1 << 2))
+#define     VPP_REG_GLB_CTRL_C_UPDATE_REG         ((VPP_REG_CTRL_BASE       ) + ( 2 << 2))
+#define     VPP_REG_GLB_CTRL_SETTING              ((VPP_REG_CTRL_BASE       ) + ( 3 << 2))
+#define     VPP_REG_GLB_CTRL_CLK_SETTING          ((VPP_REG_CTRL_BASE       ) + ( 4 << 2))
+#define     VPP_REG_GLB_CTRL_INT_STA_COP          ((VPP_REG_CTRL_BASE       ) + ( 5 << 2))
+#define     VPP_REG_GLB_CTRL_INT_MSK_COP          ((VPP_REG_CTRL_BASE       ) + ( 6 << 2))
+#define     VPP_REG_GLB_CTRL_INT_STA_HOST         ((VPP_REG_CTRL_BASE       ) + ( 7 << 2))
+#define     VPP_REG_GLB_CTRL_INT_MSK_HOST         ((VPP_REG_CTRL_BASE       ) + ( 8 << 2))
+#define     VPP_REG_GLB_CTRL_SCALE_COEF3          ((VPP_REG_CTRL_BASE       ) + ( 9 << 2))
+#define     VPP_REG_GLB_CTRL_SCALE_COEF4          ((VPP_REG_CTRL_BASE       ) + (10 << 2))
+#define     VPP_REG_GLB_CTRL_SCALE_COEF6          ((VPP_REG_CTRL_BASE       ) + (11 << 2))
+#define     VPP_REG_GLB_CTRL_CPU_WQ               ((VPP_REG_CTRL_BASE       ) + (12 << 2))
+#define     VPP_REG_GLB_CTRL_COP_RQ               ((VPP_REG_CTRL_BASE       ) + (13 << 2))
+#define     VPP_REG_GLB_CTRL_HAND_STATUS          ((VPP_REG_CTRL_BASE       ) + (14 << 2))
+#define     VPP_REG_GLB_CTRL_TG_SETTING           ((VPP_REG_CTRL_BASE       ) + (15 << 2))
+/***********DMA Register**********/
+#define     VPP_REG_DMA_CTRL                      ((VPP_REG_GFX_DMA_BASE    ) + ( 0 << 2))
+#define     VPP_REG_DMA_DES_X_POSITION             ((VPP_REG_GFX_DMA_BASE    ) + ( 1 << 2))
+#define     VPP_REG_DMA_DES_Y_POSITION             ((VPP_REG_GFX_DMA_BASE    ) + ( 2 << 2))
+#define     VPP_REG_DMA_SRC_X_CROP                ((VPP_REG_GFX_DMA_BASE    ) + ( 3 << 2))
+#define     VPP_REG_DMA_SRC_Y_CROP                ((VPP_REG_GFX_DMA_BASE    ) + ( 4 << 2))
+#define     VPP_REG_DMA_RD_YF_ADDR                ((VPP_REG_GFX_DMA_BASE    ) + ( 5 << 2))
+#define     VPP_REG_DMA_RD_CF_ADDR                ((VPP_REG_GFX_DMA_BASE    ) + ( 6 << 2))
+#define     VPP_REG_DMA_WR_YF_ADDR                ((VPP_REG_GFX_DMA_BASE    ) + ( 7 << 2))
+#define     VPP_REG_DMA_WR_CF_ADDR                ((VPP_REG_GFX_DMA_BASE    ) + ( 8 << 2))
+
+/***********GFX UI1   Register******/
+#define     VPP_REG_GFX_UI1_CTRL                 ((VPP_REG_GFX_UI1_BASE    ) + ( 0 << 2))
+#define     VPP_REG_GFX_UI1_ALPHA_CTRL           ((VPP_REG_GFX_UI1_BASE    ) + ( 1 << 2))
+#define     VPP_REG_GFX_UI1_SIZE                 ((VPP_REG_GFX_UI1_BASE    ) + ( 2 << 2))
+#define     VPP_REG_GFX_UI1_KEY_RED              ((VPP_REG_GFX_UI1_BASE    ) + ( 3 << 2))
+#define     VPP_REG_GFX_UI1_KEY_BLUE             ((VPP_REG_GFX_UI1_BASE    ) + ( 4 << 2))
+#define     VPP_REG_GFX_UI1_KEY_GREEN            ((VPP_REG_GFX_UI1_BASE    ) + ( 5 << 2))
+#define     VPP_REG_GFX_UI1_BUF_START            ((VPP_REG_GFX_UI1_BASE    ) + ( 6 << 2))
+#define     VPP_REG_GFX_UI1_LINE_PITCH           ((VPP_REG_GFX_UI1_BASE    ) + ( 7 << 2))
+#define     VPP_REG_GFX_UI1_X_POSITON            ((VPP_REG_GFX_UI1_BASE    ) + ( 8 << 2))
+#define     VPP_REG_GFX_UI1_Y_POSITON            ((VPP_REG_GFX_UI1_BASE    ) + ( 9 << 2))
+#define     VPP_REG_GFX_UI1_BUF_START_3D         ((VPP_REG_GFX_UI1_BASE    ) + (10 << 2))
+#define     VPP_REG_GFX_UI1_A8                   ((VPP_REG_GFX_UI1_BASE    ) + (11 << 2))
+#define     VPP_REG_GFX_UI1_PHASE                ((VPP_REG_GFX_UI1_BASE    ) + (12 << 2))
+#define     VPP_REG_GFX_UI1_COEFF_GID            ((VPP_REG_GFX_UI1_BASE    ) + (13 << 2))
+/*****GFX UI2   Register******/
+#define     VPP_REG_GFX_UI2_CTRL                  ((VPP_REG_GFX_UI2_BASE    ) + ( 0 << 2))
+#define     VPP_REG_GFX_UI2_ALPHA_CTRL             ((VPP_REG_GFX_UI2_BASE    ) + ( 1 << 2))
+#define     VPP_REG_GFX_UI2_SIZE                   ((VPP_REG_GFX_UI2_BASE    ) + ( 2 << 2))
+#define     VPP_REG_GFX_UI2_KEY_RED                ((VPP_REG_GFX_UI2_BASE    ) + ( 3 << 2))
+#define     VPP_REG_GFX_UI2_KEY_BLUE               ((VPP_REG_GFX_UI2_BASE    ) + ( 4 << 2))
+#define     VPP_REG_GFX_UI2_KEY_GREEN              ((VPP_REG_GFX_UI2_BASE    ) + ( 5 << 2))
+#define     VPP_REG_GFX_UI2_BUF_START              ((VPP_REG_GFX_UI2_BASE    ) + ( 6 << 2))
+#define     VPP_REG_GFX_UI2_LINE_PITCH             ((VPP_REG_GFX_UI2_BASE    ) + ( 7 << 2))
+#define     VPP_REG_GFX_UI2_X_POSITON              ((VPP_REG_GFX_UI2_BASE    ) + ( 8 << 2))
+#define     VPP_REG_GFX_UI2_Y_POSITON             ((VPP_REG_GFX_UI2_BASE    ) + ( 9 << 2))
+#define     VPP_REG_GFX_UI2_BUF_START_3D           ((VPP_REG_GFX_UI2_BASE    ) + (10 << 2))
+#define     VPP_REG_GFX_UI2_A8                     ((VPP_REG_GFX_UI2_BASE    ) + (11 << 2))
+#define     VPP_REG_GFX_UI2_PHASE                  ((VPP_REG_GFX_UI2_BASE    ) + (12 << 2))
+#define     VPP_REG_GFX_UI2_COEFF_GID              ((VPP_REG_GFX_UI2_BASE    ) + (13 << 2))
+/***********HD2SD_RD Register******/
+#define     VPP_REG_HD2SD_RD_CTRL                 ((VPP_REG_HD2SD_RD_BASE   ) + ( 0 << 2))
+#define     VPP_REG_HD2SD_RD_X_POSITION            ((VPP_REG_HD2SD_RD_BASE   ) + ( 1 << 2))
+#define     VPP_REG_HD2SD_RD_Y_POSITION            ((VPP_REG_HD2SD_RD_BASE   ) + ( 2 << 2))
+#define     VPP_REG_HD2SD_RD_SRC_X_CROP           ((VPP_REG_HD2SD_RD_BASE   ) + ( 3 << 2))
+#define     VPP_REG_HD2SD_RD_SRC_Y_CROP           ((VPP_REG_HD2SD_RD_BASE   ) + ( 4 << 2))
+#define     VPP_REG_HD2SD_RD_YF_ADDR              ((VPP_REG_HD2SD_RD_BASE   ) + ( 5 << 2))
+#define     VPP_REG_HD2SD_RD_CF_ADDR              ((VPP_REG_HD2SD_RD_BASE   ) + ( 6 << 2))
+#define     VPP_REG_HD2SD_RD_STA_DISP_NUM         ((VPP_REG_HD2SD_RD_BASE   ) + ( 7 << 2))
+/*********HD2SD_CAPTURE Register***/
+#define     VPP_REG_CAP_CTRL                      ((VPP_REG_CAP_BASE   ) + ( 0 << 2))
+#define     VPP_REG_CAP_SCR_SETTING               ((VPP_REG_CAP_BASE   ) + ( 1 << 2))
+#define     VPP_REG_CAP_SCR_H_POSITION             ((VPP_REG_CAP_BASE   ) + ( 2 << 2))
+#define     VPP_REG_CAP_SCR_V_POSITION             ((VPP_REG_CAP_BASE   ) + ( 3 << 2))
+#define     VPP_REG_CAP_DES_H_POSITION            ((VPP_REG_CAP_BASE   ) + ( 4 << 2))
+#define     VPP_REG_CAP_DES_V_POSITION            ((VPP_REG_CAP_BASE   ) + ( 5 << 2))
+#define     VPP_REG_CAP_YV_RATIO                  ((VPP_REG_CAP_BASE   ) + ( 6 << 2))
+#define     VPP_REG_CAP_YH_RATIO                  ((VPP_REG_CAP_BASE   ) + ( 7 << 2))
+#define     VPP_REG_CAP_CV_RATIO                  ((VPP_REG_CAP_BASE   ) + ( 8 << 2))
+#define     VPP_REG_CAP_CH_RATIO                  ((VPP_REG_CAP_BASE   ) + ( 9 << 2))
+#define     VPP_REG_CAP_Y_NOLINE_D                ((VPP_REG_CAP_BASE   ) + (10 << 2))
+#define     VPP_REG_CAP_C_NOLINE_D                ((VPP_REG_CAP_BASE   ) + (11 << 2))
+#define     VPP_REG_CAP_Y_NOLINE_K                ((VPP_REG_CAP_BASE   ) + (12 << 2))
+#define     VPP_REG_CAP_C_NOLINE_K                ((VPP_REG_CAP_BASE   ) + (13 << 2))
+#define     VPP_REG_CAP_HOR_PHASE                 ((VPP_REG_CAP_BASE   ) + (14 << 2))
+#define     VPP_REG_CAP_VER_PHASE                 ((VPP_REG_CAP_BASE   ) + (15 << 2))
+#define     VPP_REG_CAP_YT_ADDR0                  ((VPP_REG_CAP_BASE   ) + (16 << 2))
+#define     VPP_REG_CAP_CT_ADDR0                  ((VPP_REG_CAP_BASE   ) + (17 << 2))
+#define     VPP_REG_CAP_YT_ADDR1                  ((VPP_REG_CAP_BASE   ) + (18 << 2))
+#define     VPP_REG_CAP_CT_ADDR1                  ((VPP_REG_CAP_BASE   ) + (19 << 2))
+#define     VPP_REG_CAP_YT_ADDR2                  ((VPP_REG_CAP_BASE   ) + (20 << 2))
+#define     VPP_REG_CAP_CT_ADDR2                  ((VPP_REG_CAP_BASE   ) + (21 << 2))
+#define     VPP_REG_CAP_YT_ADDR3                  ((VPP_REG_CAP_BASE   ) + (22 << 2))
+#define     VPP_REG_CAP_CT_ADDR3                  ((VPP_REG_CAP_BASE   ) + (23 << 2))
+#define     VPP_REG_CAP_YT_ADDR4                  ((VPP_REG_CAP_BASE   ) + (24 << 2))
+#define     VPP_REG_CAP_CT_ADDR4                  ((VPP_REG_CAP_BASE   ) + (25 << 2))
+#define     VPP_REG_CAP_COEFF_NO                  ((VPP_REG_CAP_BASE   ) + (26 << 2))
+#define     VPP_REG_CAP_IDX                       ((VPP_REG_CAP_BASE   ) + (27 << 2))
+#define     VPP_REG_CAP_PTS                       ((VPP_REG_CAP_BASE   ) + (28 << 2))
+#define     VPP_REG_CAP_STA_TG1                   ((VPP_REG_CAP_BASE   ) + (29 << 2))
+#define     VPP_REG_CAP_LINE_CNT                 ((VPP_REG_CAP_BASE   ) + (30 << 2))
+#define     VPP_REG_CAP_FORMAT                  ((VPP_REG_CAP_BASE   ) + (31 << 2))
+/***********COMPOSITOR Register****/
+#define     VPP_REG_COMP_B2_BACK_GROUND           ((VPP_REG_COMP_BASE       ) + ( 0 << 2))
+#define     VPP_REG_COMP_B2_Z_ORDER               ((VPP_REG_COMP_BASE       ) + ( 1 << 2))
+#define     VPP_REG_COMP_B2_DEFAULT_ALPHA         ((VPP_REG_COMP_BASE       ) + ( 2 << 2))
+#define     VPP_REG_COMP_COLOR_ADJUST             ((VPP_REG_COMP_BASE       ) + ( 3 << 2))
+#define     VPP_REG_COMP_SHARP_Y_CTRL             ((VPP_REG_COMP_BASE       ) + ( 4 << 2))
+#define     VPP_REG_COMP_SHARP_C_CTRL             ((VPP_REG_COMP_BASE       ) + ( 5 << 2))
+#define     VPP_REG_COMP_B3_BACK_GROUND          ((VPP_REG_COMP_BASE       ) + ( 6 << 2))
+#define     VPP_REG_COMP_B3_Z_ORDER                ((VPP_REG_COMP_BASE       ) + ( 7 << 2))
+#define     VPP_REG_COMP_B3_DEFAULT_ALPHA          ((VPP_REG_COMP_BASE       ) + ( 8 << 2))
+/**********TG1 Register*********/
+#define     VPP_REG_TG1_CTRL                   ((VPP_REG_TG1_BASE     ) + ( 0 << 2))
+#define     VPP_REG_TG1_X_SIZE                 ((VPP_REG_TG1_BASE     ) + ( 1 << 2))
+#define     VPP_REG_TG1_Y_SIZE                 ((VPP_REG_TG1_BASE     ) + ( 2 << 2))
+#define     VPP_REG_TG1_HSYNC                  ((VPP_REG_TG1_BASE     ) + ( 3 << 2))
+#define     VPP_REG_TG1_VSYNC                  ((VPP_REG_TG1_BASE     ) + ( 4 << 2))
+#define     VPP_REG_TG1_VGA_LEVEL              ((VPP_REG_TG1_BASE     ) + ( 5 << 2))
+#define     VPP_REG_TG1_V_START_LINE           ((VPP_REG_TG1_BASE     ) + ( 6 << 2))
+#define     VPP_REG_TG1_STA_DISP_SIZE          ((VPP_REG_TG1_BASE     ) + ( 8 << 2))
+#define     VPP_REG_TG1_STA_LINE               ((VPP_REG_TG1_BASE     ) + ( 9 << 2))
+/***********TG2 Register********/
+#define     VPP_REG_TG2_CTRL                   ((VPP_REG_TG2_BASE     ) + ( 0 << 2))
+#define     VPP_REG_TG2_X_SIZE                 ((VPP_REG_TG2_BASE     ) + ( 1 << 2))
+#define     VPP_REG_TG2_Y_SIZE                 ((VPP_REG_TG2_BASE     ) + ( 2 << 2))
+#define     VPP_REG_TG2_HSYNC                  ((VPP_REG_TG2_BASE     ) + ( 3 << 2))
+#define     VPP_REG_TG2_VSYNC                  ((VPP_REG_TG2_BASE     ) + ( 4 << 2))
+#define     VPP_REG_TG2_VGA_LEVEL              ((VPP_REG_TG2_BASE     ) + ( 5 << 2))
+#define     VPP_REG_TG2_V_START_LINE           ((VPP_REG_TG2_BASE     ) + ( 6 << 2))
+#define     VPP_REG_TG2_STA_DISP_SIZE          ((VPP_REG_TG2_BASE     ) + ( 8 << 2))
+#define     VPP_REG_TG2_STA_LINE               ((VPP_REG_TG2_BASE     ) + ( 9 << 2))
+/*********MAIN CH Register*********/
+#define     VPP_REG_MAIN_CH_DYN_SETTING           ((VPP_REG_MAIN_CH_BASE    ) + ( 0 << 2))
+#define     VPP_REG_MAIN_CH_DYN_FLD_ADDR_FY       ((VPP_REG_MAIN_CH_BASE    ) + ( 1 << 2))
+#define     VPP_REG_MAIN_CH_DYN_FLD_ADDR_CY       ((VPP_REG_MAIN_CH_BASE    ) + ( 2 << 2))
+#define     VPP_REG_MAIN_CH_DYN_FLD_ADDR_BY       ((VPP_REG_MAIN_CH_BASE    ) + ( 3 << 2))
+#define     VPP_REG_MAIN_CH_DYN_FLD_ADDR_BBY      ((VPP_REG_MAIN_CH_BASE    ) + ( 4 << 2))
+#define     VPP_REG_MAIN_CH_DYN_FLD_ADDR_FY_3DR   ((VPP_REG_MAIN_CH_BASE    ) + ( 5 << 2))
+#define     VPP_REG_MAIN_CH_DYN_FLD_ADDR_CY_3DR   ((VPP_REG_MAIN_CH_BASE    ) + ( 6 << 2))
+#define     VPP_REG_MAIN_CH_DYN_FLD_ADDR_BY_3DR   ((VPP_REG_MAIN_CH_BASE    ) + ( 7 << 2))
+#define     VPP_REG_MAIN_CH_DYN_FLD_ADDR_BBY_3DR  ((VPP_REG_MAIN_CH_BASE    ) + ( 8 << 2))
+#define     VPP_REG_MAIN_CH_DYN_FLD_ADDR_FC       ((VPP_REG_MAIN_CH_BASE    ) + ( 9 << 2))
+#define     VPP_REG_MAIN_CH_DYN_FLD_ADDR_CC       ((VPP_REG_MAIN_CH_BASE    ) + (10 << 2))
+#define     VPP_REG_MAIN_CH_DYN_FLD_ADDR_BC       ((VPP_REG_MAIN_CH_BASE    ) + (11 << 2))
+#define     VPP_REG_MAIN_CH_DYN_FLD_ADDR_BBC      ((VPP_REG_MAIN_CH_BASE    ) + (12 << 2))
+#define     VPP_REG_MAIN_CH_DYN_FLD_ADDR_FC_3DR   ((VPP_REG_MAIN_CH_BASE    ) + (13 << 2))
+#define     VPP_REG_MAIN_CH_DYN_FLD_ADDR_CC_3DR   ((VPP_REG_MAIN_CH_BASE    ) + (14 << 2))
+#define     VPP_REG_MAIN_CH_DYN_FLD_ADDR_BC_3DR   ((VPP_REG_MAIN_CH_BASE    ) + (15 << 2))
+#define     VPP_REG_MAIN_CH_DYN_FLD_ADDR_BBC_3DR  ((VPP_REG_MAIN_CH_BASE    ) + (16 << 2))
+#define     VPP_REG_MAIN_CH_DYN_STORE_FRM_ADDR_Y  ((VPP_REG_MAIN_CH_BASE    ) + (17 << 2))
+#define     VPP_REG_MAIN_CH_DYN_STORE_FRM_ADDR_C  ((VPP_REG_MAIN_CH_BASE    ) + (18 << 2))
+#define     VPP_REG_MAIN_CH_CTRL                  ((VPP_REG_MAIN_CH_BASE    ) + (19 << 2))
+#define     VPP_REG_MAIN_CH_SRC_SETTING           ((VPP_REG_MAIN_CH_BASE    ) + (20 << 2))
+#define     VPP_REG_MAIN_CH_SRC_H_POSITION        ((VPP_REG_MAIN_CH_BASE    ) + (21 << 2))
+#define     VPP_REG_MAIN_CH_SRC_V_POSITION        ((VPP_REG_MAIN_CH_BASE    ) + (22 << 2))
+#define     VPP_REG_MAIN_CH_DES_SETTING           ((VPP_REG_MAIN_CH_BASE    ) + (23 << 2))
+#define     VPP_REG_MAIN_CH_DES_H_POSITION        ((VPP_REG_MAIN_CH_BASE    ) + (24 << 2))
+#define     VPP_REG_MAIN_CH_DES_V_POSITION        ((VPP_REG_MAIN_CH_BASE    ) + (25 << 2))
+#define     VPP_REG_MAIN_CH_Y_INIT_CENTOR         ((VPP_REG_MAIN_CH_BASE    ) + (26 << 2))
+#define     VPP_REG_MAIN_CH_Y_INIT_PHASE          ((VPP_REG_MAIN_CH_BASE    ) + (27 << 2))
+#define     VPP_REG_MAIN_CH_C_INIT_CENTOR         ((VPP_REG_MAIN_CH_BASE    ) + (28 << 2))
+#define     VPP_REG_MAIN_CH_C_INIT_PHASE          ((VPP_REG_MAIN_CH_BASE    ) + (29 << 2))
+#define     VPP_REG_MAIN_CH_COF_CTRL              ((VPP_REG_MAIN_CH_BASE    ) + (30 << 2))
+#define     VPP_REG_MAIN_CH_Y_TNR_SETTING         ((VPP_REG_MAIN_CH_BASE    ) + (31 << 2))
+#define     VPP_REG_MAIN_CH_Y_MADI_SETTING        ((VPP_REG_MAIN_CH_BASE    ) + (32 << 2))
+#define     VPP_REG_MAIN_CH_Y_DIR_SETTING         ((VPP_REG_MAIN_CH_BASE    ) + (33 << 2))
+#define     VPP_REG_MAIN_CH_Y_V_INIT_R0           ((VPP_REG_MAIN_CH_BASE    ) + (34 << 2))
+#define     VPP_REG_MAIN_CH_Y_H_INIT_R0           ((VPP_REG_MAIN_CH_BASE    ) + (35 << 2))
+#define     VPP_REG_MAIN_CH_Y_H_D0_ABS            ((VPP_REG_MAIN_CH_BASE    ) + (36 << 2))
+#define     VPP_REG_MAIN_CH_Y_H_K                 ((VPP_REG_MAIN_CH_BASE    ) + (37 << 2))
+#define     VPP_REG_MAIN_CH_Y_H_N1                ((VPP_REG_MAIN_CH_BASE    ) + (38 << 2))
+#define     VPP_REG_MAIN_CH_C_TNR_SETTING         ((VPP_REG_MAIN_CH_BASE    ) + (39 << 2))
+#define     VPP_REG_MAIN_CH_C_MADI_SETTING        ((VPP_REG_MAIN_CH_BASE    ) + (40 << 2))
+#define     VPP_REG_MAIN_CH_C_DIR_SETTING         ((VPP_REG_MAIN_CH_BASE    ) + (41 << 2))
+#define     VPP_REG_MAIN_CH_C_V_INIT_R0           ((VPP_REG_MAIN_CH_BASE    ) + (42 << 2))
+#define     VPP_REG_MAIN_CH_C_H_INIT_R0           ((VPP_REG_MAIN_CH_BASE    ) + (43 << 2))
+#define     VPP_REG_MAIN_CH_C_H_D0_ABS            ((VPP_REG_MAIN_CH_BASE    ) + (44 << 2))
+#define     VPP_REG_MAIN_CH_C_H_K                 ((VPP_REG_MAIN_CH_BASE    ) + (45 << 2))
+#define     VPP_REG_MAIN_CH_C_H_N1                ((VPP_REG_MAIN_CH_BASE    ) + (46 << 2))
+#define     VPP_REG_MAIN_F2F_STORE_PITCH          ((VPP_REG_MAIN_CH_BASE    ) + (49 << 2))
+#define     VPP_REG_MAIN_UPS_SETTING              ((VPP_REG_MAIN_CH_BASE    ) + (50 << 2))
+#define     VPP_REG_MAIN_B1_CTRL                  ((VPP_REG_MAIN_CH_BASE    ) + (51 << 2))
+#define     VPP_REG_MAIN_B1_BACK_GROUND           ((VPP_REG_MAIN_CH_BASE    ) + (52 << 2))
+#define     VPP_REG_MAIN_B1_DES_POSITION_X        ((VPP_REG_MAIN_CH_BASE    ) + (53 << 2))
+#define     VPP_REG_MAIN_B1_DES_POSITION_Y        ((VPP_REG_MAIN_CH_BASE    ) + (54 << 2))
+#define     VPP_REG_MAIN_CH_STA_DISP_NUM          ((VPP_REG_MAIN_CH_BASE    ) + (55 << 2))
+/***********SR CH Register*********/
+#define     VPP_REG_SR_CH_DYN_SETTING             ((VPP_REG_SR_CH_BASE      ) + ( 0 << 2))
+#define     VPP_REG_SR_CH_DYN_ADDR_CY             ((VPP_REG_SR_CH_BASE      ) + ( 1 << 2))
+#define     VPP_REG_SR_CH_DYN_ADDR_CY_3DR         ((VPP_REG_SR_CH_BASE      ) + ( 2 << 2))
+#define     VPP_REG_SR_CH_DYN_ADDR_CC             ((VPP_REG_SR_CH_BASE      ) + ( 3 << 2))
+#define     VPP_REG_SR_CH_DYN_ADDR_CC_3DR         ((VPP_REG_SR_CH_BASE      ) + ( 4 << 2))
+#define     VPP_REG_SR_CH_DYN_STORE_FRM_ADDR_Y    ((VPP_REG_SR_CH_BASE      ) + ( 5 << 2))
+#define     VPP_REG_SR_CH_DYN_STORE_FRM_ADDR_C    ((VPP_REG_SR_CH_BASE      ) + ( 6 << 2))
+#define     VPP_REG_SR_CH_CTRL                    ((VPP_REG_SR_CH_BASE      ) + (16 << 2))
+#define     VPP_REG_SR_CH_SRC_SETTING             ((VPP_REG_SR_CH_BASE      ) + (17 << 2))
+#define     VPP_REG_SR_CH_SRC_H_POS               ((VPP_REG_SR_CH_BASE      ) + (18 << 2))
+#define     VPP_REG_SR_CH_SRC_V_POS               ((VPP_REG_SR_CH_BASE      ) + (19 << 2))
+#define     VPP_REG_SR_CH_DES_SETTING             ((VPP_REG_SR_CH_BASE      ) + (20 << 2))
+#define     VPP_REG_SR_CH_DES_H_POS               ((VPP_REG_SR_CH_BASE      ) + (21 << 2))
+#define     VPP_REG_SR_CH_DES_V_POS               ((VPP_REG_SR_CH_BASE      ) + (22 << 2))
+#define     VPP_REG_SR_CH_SRC_LINE_PITCH          ((VPP_REG_SR_CH_BASE      ) + (23 << 2))
+#define     VPP_REG_SR_CH_SCALE_Y_V_R             ((VPP_REG_SR_CH_BASE      ) + (24 << 2))
+#define     VPP_REG_SR_CH_SCALE_Y_H_R             ((VPP_REG_SR_CH_BASE      ) + (25 << 2))
+#define     VPP_REG_SR_CH_SCALE_Y_H_D             ((VPP_REG_SR_CH_BASE      ) + (26 << 2))
+#define     VPP_REG_SR_CH_SCALE_Y_H_K             ((VPP_REG_SR_CH_BASE      ) + (27 << 2))
+#define     VPP_REG_SR_CH_SCALE_Y_H_N             ((VPP_REG_SR_CH_BASE      ) + (28 << 2))
+#define     VPP_REG_SR_CH_SCALE_C_V_R             ((VPP_REG_SR_CH_BASE      ) + (29 << 2))
+#define     VPP_REG_SR_CH_SCALE_C_H_R             ((VPP_REG_SR_CH_BASE      ) + (30 << 2))
+#define     VPP_REG_SR_CH_SCALE_C_H_D             ((VPP_REG_SR_CH_BASE      ) + (31 << 2))
+#define     VPP_REG_SR_CH_SCALE_C_H_K             ((VPP_REG_SR_CH_BASE      ) + (32 << 2))
+#define     VPP_REG_SR_CH_SCALE_C_H_N             ((VPP_REG_SR_CH_BASE      ) + (33 << 2))
+
+typedef struct _GLB
+{
+    union
+    {
+        struct
+        {
+            unsigned int wr_lb_limit:16;
+            unsigned int reserved:16;
+        }bits;
+
+        unsigned int val;
+    }reg_glb_ctrl_setting;
+	union
+	{
+		struct 
+		{
+			unsigned int clk_gate:5;
+			unsigned int reserved1:3;
+			unsigned int clk_en_sr:1;
+			unsigned int clk_en_main:1;
+			unsigned int clk_en_ui1:1;
+			unsigned int clk_en_ui2:1;
+			unsigned int clk_en_cap:1;
+			unsigned int clk_en_rd2:1;
+			unsigned int reserved2:19;
+		}bits;
+
+		unsigned int val;
+	}reg_glb_ctrl_clk_setting;
+    union
+    {
+        struct
+        {
+            unsigned int update_reg:1;
+            unsigned int reserved:31;
+        }bits;
+        unsigned int val;
+    }reg_glb_h_update;
+    union
+    {
+        struct
+        {
+            unsigned int update_reg:1;
+            unsigned int reserved:31;
+        }bits;
+        unsigned int val;
+    }reg_glb_m_update;
+    union
+    {
+        struct
+        {
+            unsigned int update_reg:1;
+            unsigned int reserved:31;
+        }bits;
+
+        unsigned int val;
+    }reg_glb_c_update;
+
+    union
+    {
+        struct
+        {
+            unsigned int cop_int_sta_disp1_err:1;
+            unsigned int cop_int_sta_disp2_err:1;
+            unsigned int cop_int_sta_cap_err:1;     
+            unsigned int cop_int_sta_disp1_sync:1;
+            unsigned int cop_int_sta_disp1_field:1;
+            unsigned int cop_int_sta_disp1_frame:1;
+            unsigned int cop_int_sta_disp2_frame:1;
+            unsigned int cop_int_sta_cap_finish:1;  
+            unsigned int cop_int_sta_main_f2f_finish:1;
+            unsigned int cop_int_sta_cap_change:1;
+            unsigned int reserved:22;
+        }bits;
+
+        unsigned int val;
+    }reg_glb_int_sta_cop;
+
+    union
+    {
+        struct
+        {
+            unsigned int cop_int_msk_disp1_err:1;
+            unsigned int cop_int_msk_disp2_err:1;
+            unsigned int cop_int_msk_cap_err:1;      
+            unsigned int cop_int_msk_disp1_sync:1;
+            unsigned int cop_int_msk_disp1_field:1;
+            unsigned int cop_int_msk_disp1_frame:1;
+            unsigned int cop_int_msk_disp2_frame:1;
+            unsigned int cop_int_msk_cap_finish:1;    
+            unsigned int cop_int_msk_main_f2f_finish:1;
+            unsigned int cop_int_msk_cap_change:1;
+            unsigned int reserved:22;
+        }bits;
+
+        unsigned int val;
+    }reg_glb_int_msk_cop;
+
+    union
+    {
+        struct
+        {
+            unsigned int host_int_sta_disp1_err:1;
+            unsigned int host_int_sta_disp2_err:1;
+            unsigned int host_int_sta_cap_err:1;     
+            unsigned int host_int_sta_disp1_sync:1;
+            unsigned int host_int_sta_disp1_field:1;
+            unsigned int host_int_sta_disp1_frame:1;
+            unsigned int host_int_sta_disp2_frame:1;
+            unsigned int host_int_sta_cap_finish:1;   
+            unsigned int host_int_sta_main_f2f_finish:1;
+            unsigned int host_int_sta_cap_change:1;
+            unsigned int reserved:22;
+        }bits;
+
+        unsigned int val;
+    }reg_glb_int_sta_host;
+
+    union
+    {
+        struct
+        {
+            unsigned int host_int_msk_disp1_err:1;
+            unsigned int host_int_msk_disp2_err:1;
+            unsigned int host_int_msk_cap_err:1;
+            unsigned int host_int_msk_disp1_sync:1;
+            unsigned int host_int_msk_disp1_field:1;
+            unsigned int host_int_msk_disp1_frame:1;
+            unsigned int host_int_msk_disp2_frame:1;
+            unsigned int host_int_msk_cap_finish:1;   
+            unsigned int host_int_msk_main_f2f_finish:1;
+            unsigned int host_int_msk_cap_change:1;
+            unsigned int reserved:22;
+        }bits;
+
+        unsigned int val;
+    }reg_glb_int_msk_host;
+
+    union
+    {
+       struct
+       {
+              unsigned int reserved:7;
+          unsigned int scale_coef3:25;
+       }bits;
+       unsigned int val;
+    }reg_glb_scale_coef3;
+
+    union
+    {
+       struct
+       {
+              unsigned int reserved:7;
+          unsigned int scale_coef4:25;
+       }bits;
+       unsigned int val;
+    }reg_glb_scale_coef4;
+
+    union
+    {
+       struct
+       {
+              unsigned int reserved:7;
+          unsigned int scale_coef6:25;
+       }bits;
+       unsigned int val;
+    }reg_glb_scale_coef6;
+
+    union
+    {
+       struct
+       {
+          unsigned int cpu_wq:1;
+              unsigned int reserved:31;
+       }bits;
+       unsigned int val;
+    }reg_glb_cpu_wq;
+
+    union
+    {
+       struct
+       {
+          unsigned int mips_rq:1;
+              unsigned int reserved:31;
+       }bits;
+       unsigned int val;
+    }reg_glb_mips_rq;
+
+    union
+    {
+       struct
+       {
+          unsigned int cur_status:2;
+              unsigned int reserved1:14;
+              unsigned int need_update:1;
+              unsigned int reserved2:15;
+       }bits;
+       unsigned int val;
+    }reg_glb_cur_status;
+
+    union
+    {
+       struct
+       {
+              unsigned int tg1_v_int_before_line_num:11;
+          unsigned int tg1_frame_int_sel:1;
+              unsigned int reserved1:4;
+              unsigned int tg2_v_int_before_line_num:11;
+          unsigned int tg2_frame_int_sel:1;
+              unsigned int reserved2:4;
+       }bits;
+       unsigned int val;
+    }reg_glb_tg_setting;
+}df_ctrl_reg;
+
+typedef struct _SR
+{
+
+    union
+    {
+        struct
+        {
+            unsigned int sr_src_top_field:1;
+            unsigned int reserved_1:3;
+            unsigned int sr_f2f_start:1;
+            unsigned int reserved_2:3;
+            unsigned int sr_f2f_3dr:1;
+            unsigned int reserved_3:3;
+            unsigned int sr_f2f_des_top_field:1;
+            unsigned int reserved_4:19;
+        }bits;
+        unsigned int val;
+    }reg_sr_ch_dyn_setting;
+    union
+    {
+        struct
+        {
+            unsigned int reserved_1:7;
+            unsigned int sr_f2f_store_frame_addr_y:25;
+        }bits;
+        unsigned int val;
+    }reg_sr_ch_dyn_store_frm_addr_y;
+
+    union
+    {
+        struct
+        {
+            unsigned int reserved_1:7;
+            unsigned int sr_f2f_store_frame_addr_c:25;
+        }bits;
+        unsigned int val;
+    }reg_sr_ch_dyn_store_frm_addr_c;
+
+    union
+    {
+        struct
+        {
+            unsigned int reserved_1:7;
+            unsigned int sr_frame_addr_cy:25;
+        }bits;
+        unsigned int val;
+    }reg_sr_ch_dyn_addr_cy;
+
+    union
+    {
+        struct
+        {
+            unsigned int reserved_1:7;
+            unsigned int sr_frame_addr_cy_3dr:25;
+        }bits;
+        unsigned int val;
+    }reg_sr_ch_dyn_addr_cy_3dr;
+
+    union
+    {
+        struct
+        {
+            unsigned int reserved_1:7;
+            unsigned int sr_frame_addr_cc:25;
+        }bits;
+        unsigned int val;
+    }reg_sr_ch_dyn_addr_cc;
+
+    union
+    {
+        struct
+        {
+            unsigned int reserved_1:7;
+            unsigned int sr_frame_addr_cc_3dr:25;
+        }bits;
+        unsigned int val;
+    }reg_sr_ch_dyn_addr_cc_3dr;
+
+    union
+    {
+        struct
+        {
+            unsigned int sr_y_src_line_pitch_128x:6;
+            unsigned int reserved_1:2;
+            unsigned int sr_c_src_line_pitch_128x:6;
+            unsigned int reserved_2:18;
+        }bits;
+        unsigned int val;
+    }reg_sr_ch_line_pitch;
+    union
+    {
+        struct
+        {
+            unsigned int sr_en:1;
+            unsigned int reserved_1:3;
+			unsigned int sr_rd_qa_en:1;
+            unsigned int reserved_2:3;
+            unsigned int sr_f2f_mode:1;
+			unsigned int sr_lb_init_step:6;
+			unsigned int reserved_3:1;
+            unsigned int sr_k:8;
+            unsigned int reserved_4:8;
+        }bits;
+        unsigned int val;
+    }reg_sr_ch_ctrl;
+
+    union
+    {
+        struct
+        {
+            unsigned int sr_src_is_i:1;
+            unsigned int reserved_1:7;
+            unsigned int sr_src_c_h_sample:1;
+            unsigned int reserved_2:3;
+            unsigned int sr_src_c_v_sample:1;
+            unsigned int reserved_3:3;
+            unsigned int sr_scr_v1_full:12;
+            unsigned int reserved_4:4;
+        }bits;
+        unsigned int val;
+    }reg_sr_ch_src_setting;
+
+    union
+    {
+        struct
+        {
+            unsigned int sr_src_h_start:11;
+            unsigned int reserved_1:5;
+            unsigned int sr_src_h_end:11;
+            unsigned int reserved_2:5;
+        }bits;
+        unsigned int val;
+    }reg_sr_ch_src_h_pos;
+
+    union
+    {
+        struct
+        {
+            unsigned int sr_src_v_start:12;
+            unsigned int reserved_1:4;
+            unsigned int sr_src_v_end:12;
+            unsigned int reserved_2:4;
+        }bits;
+        unsigned int val;
+    }reg_sr_ch_src_v_pos;
+
+    union
+    {
+        struct
+        {
+            unsigned int sr_des_is_i:1;
+            unsigned int reserved_1:3;
+            unsigned int sr_des_c_h_sample:1;
+            unsigned int reserved_2:3;
+            unsigned int sr_des_c_v_sample:1;
+            unsigned int reserved_3:23;
+        }bits;
+        unsigned int val;
+    }reg_sr_ch_des_setting;
+
+    union
+    {
+        struct
+        {
+            unsigned int sr_des_h_start:12;
+            unsigned int reserved_1:4;
+            unsigned int sr_des_h_end:12;
+            unsigned int reserved_2:4;
+        }bits;
+        unsigned int val;
+    }reg_sr_ch_des_h_pos;
+
+    union
+    {
+        struct
+        {
+            unsigned int sr_des_v_start:12;
+            unsigned int reserved_1:4;
+            unsigned int sr_des_v_end:12;
+            unsigned int reserved_2:4;
+            }bits;
+        unsigned int val;
+    }reg_sr_ch_des_v_pos;
+
+
+    union
+    {
+        struct
+        {
+            unsigned int sr_y_v_i_phase:6;
+            unsigned int reserved_1:2;
+            unsigned int sr_y_v_r0:17;
+            unsigned int reserved_2:7;
+        }bits;
+        unsigned int val;
+    }reg_sr_ch_scale_y_v_r;
+
+    union
+    {
+        struct
+        {
+            unsigned int sr_y_h_i_phase:6;
+            unsigned int reserved_1:2;
+            unsigned int sr_y_h_r0:17;
+            unsigned int reserved_2:7;
+        }bits;
+        unsigned int val;
+    }reg_sr_ch_scale_y_h_r;
+
+    union
+    {
+        struct
+        {
+            unsigned int sr_y_h_d0_abs:24;
+            unsigned int reserved_1:8;
+        }bits;
+        unsigned int val;
+    }reg_sr_ch_scale_y_h_d;
+
+    union
+    {
+        struct
+        {
+            unsigned int sr_y_h_k_abs:13;
+            unsigned int reserved_1:3;
+            unsigned int sr_y_h_k_sign:1;
+            unsigned int reserved_2:3;
+            unsigned int sr_y_h_k_radix:5;
+            unsigned int reserved_3:7;
+            }bits;
+        unsigned int val;
+    }reg_sr_ch_scale_y_h_k;
+
+    union
+    {
+        struct
+        {
+            unsigned int sr_y_h_n1:11;
+            unsigned int reserved_1:21;
+        }bits;
+        unsigned int val;
+    }reg_sr_ch_scale_y_h_n;
+
+    union
+    {
+        struct
+        {
+            unsigned int reserved_1:8;
+            unsigned int sr_c_v_r0:17;
+            unsigned int reserved_2:7;
+        }bits;
+        unsigned int val;
+    }reg_sr_ch_scale_c_v_r;
+
+    union
+    {
+        struct
+        {
+            unsigned int sr_c_h_i_phase:6;
+            unsigned int reserved_1:2;
+            unsigned int sr_c_h_r0:17;
+            unsigned int reserved_2:7;
+        }bits;
+        unsigned int val;
+    }reg_sr_ch_scale_c_h_r;
+
+    union
+    {
+        struct
+        {
+            unsigned int sr_c_h_d0_abs:24;
+            unsigned int reserved_1:8;
+        }bits;
+        unsigned int val;
+    }reg_sr_ch_scale_c_h_d;
+
+    union
+    {
+        struct
+        {
+            unsigned int sr_c_h_k_abs:13;
+            unsigned int reserved_1:3;
+            unsigned int sr_c_h_k_sign:1;
+            unsigned int reserved_2:3;
+            unsigned int sr_c_h_k_radix:5;
+            unsigned int reserved_3:7;
+        }bits;
+        unsigned int val;
+    }reg_sr_ch_scale_c_h_k;
+
+    union
+    {
+        struct
+        {
+            unsigned int sr_c_h_n1:11;
+            unsigned int reserved_1:21;
+        }bits;
+        unsigned int val;
+    }reg_sr_ch_scale_c_h_n;
+}SR;
+
+typedef struct _MAIN
+{
+
+    union
+    {
+        struct
+        {
+            unsigned int main_f2f_start:1;
+            unsigned int reserved_1:3;
+            unsigned int main_src_top_field:1;
+            unsigned int reserved_2:3;
+            unsigned int main_f2f_3dr:1;
+            unsigned int reserved_3:7;
+            unsigned int main_f2f_des_top_field:1;
+            unsigned int reserved_4:15;
+            }bits;
+        unsigned int val;
+    }reg_main_ch_dysetting;
+    union
+    {
+        struct
+        {
+            unsigned int reserved_1:7;
+            unsigned int main_f2f_store_frame_addr_y:25;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_dyn_store_frm_addr_y;
+
+    union
+    {
+        struct
+        {
+            unsigned int reserved_1:7;
+            unsigned int main_f2f_store_frame_addr_c:25;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_dyn_store_frm_addr_c;
+
+    union
+    {
+        struct
+        {
+            unsigned int reserved_1:7;
+            unsigned int main_frame_addr_fy:25;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_dyn_frm_addr_fy;
+    union
+    {
+        struct
+        {
+            unsigned int reserved_1:7;
+            unsigned int main_frame_addr_cy:25;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_dyn_frm_addr_cy;
+
+    union
+    {
+        struct
+        {
+            unsigned int reserved_1:7;
+            unsigned int main_frame_addr_by:25;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_dyn_frm_addr_by;
+
+    union
+    {
+        struct
+        {
+            unsigned int reserved_1:7;
+            unsigned int main_frame_addr_bby:25;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_dyn_frm_addr_bby;
+
+
+    union
+    {
+        struct
+        {
+            unsigned int reserved_1:7;
+            unsigned int main_frame_addr_fy_3dr:25;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_dyn_frm_addr_fy_3dr;
+    union
+    {
+        struct
+        {
+            unsigned int reserved_1:7;
+            unsigned int main_frame_addr_cy_3dr:25;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_dyn_frm_addr_cy_3dr;
+
+    union
+    {
+        struct
+        {
+            unsigned int reserved_1:7;
+            unsigned int main_frame_addr_by_3dr:25;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_dyn_frm_addr_by_3dr;
+    union
+    {
+        struct
+        {
+            unsigned int reserved_1:7;
+            unsigned int main_frame_addr_bby_3dr:25;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_dyn_frm_addr_bby_3dr;
+
+
+    union
+    {
+        struct
+        {
+            unsigned int reserved_1:7;
+            unsigned int main_frame_addr_fc:25;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_dyn_frm_addr_fc;
+
+    union
+    {
+        struct
+        {
+            unsigned int reserved_1:7;
+            unsigned int main_frame_addr_cc:25;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_dyn_frm_addr_cc;
+
+    union
+    {
+        struct
+        {
+            unsigned int reserved_1:7;
+            unsigned int main_frame_addr_bc:25;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_dyn_frm_addr_bc;
+    union
+    {
+        struct
+        {
+            unsigned int reserved_1:7;
+            unsigned int main_frame_addr_bbc:25;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_dyn_frm_addr_bbc;
+
+    union
+    {
+        struct
+        {
+            unsigned int reserved_1:7;
+            unsigned int main_frame_addr_fc_3dr:25;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_dyn_frm_addr_fc_3dr;
+    union
+    {
+        struct
+        {
+            unsigned int reserved_1:7;
+            unsigned int main_frame_addr_cc_3dr:25;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_dyn_frm_addr_cc_3dr;
+
+    union {
+        struct{
+            unsigned int reserved_1:7;
+            unsigned int main_frame_addr_bc_3dr:25;
+            }bits;
+        unsigned int val;
+    }reg_main_ch_dyn_frm_addr_bc_3dr;
+
+    union
+    {
+        struct
+        {
+            unsigned int reserved_1:7;
+            unsigned int main_frame_addr_bbc_3dr:25;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_dyn_frm_addr_bbc_3dr;
+
+    union
+    {
+        struct
+        {
+            unsigned int main_f2f_store_line_pitch:6;
+            unsigned int reserved_1:26;
+        }bits;
+        unsigned int val;
+    }reg_main_f2f_store_pitch;
+
+
+
+    union
+    {
+        struct
+        {
+            unsigned int reserved_0:1;
+            unsigned int main_src_c_h_sample:1;
+            unsigned int main_src_c_v_sample:1;
+            unsigned int reserved_1:1;
+            unsigned int main_src_is_i:1;
+            unsigned int reserved_2:11;
+            unsigned int main_src_y_line_pitch_128x:6;
+            unsigned int reserved_3:2;
+            unsigned int main_src_c_line_pitch_128x:6;
+            unsigned int reserved_4:2;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_src_setting;
+
+    union
+    {
+        struct
+        {
+            unsigned int main_src_h_start:11;
+            unsigned int reserved_1:5;
+            unsigned int main_src_h_end:11;
+            unsigned int reserved_2:5;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_src_h_position;
+
+    union
+    {
+        struct
+        {
+            unsigned int main_src_v_start:12;
+            unsigned int reserved_1:4;
+            unsigned int main_src_v_end:12;
+            unsigned int reserved_2:4;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_src_v_position;
+
+    union
+    {
+        struct
+        {
+            unsigned int main_des_is_i:1;
+            unsigned int main_des_c_h_sample:1;
+            unsigned int main_des_c_v_sample:1;
+            unsigned int reserved_1:29;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_des_setting;
+
+    union
+    {
+        struct
+        {
+            unsigned int main_des_h_start:12;
+            unsigned int reserved_1:4;
+            unsigned int main_des_h_end:12;
+            unsigned int reserved_2:4;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_des_h_position;
+
+    union
+    {
+        struct
+        {
+            unsigned int main_des_v_start:12;
+            unsigned int reserved_1:4;
+            unsigned int main_des_v_end:12;
+            unsigned int reserved_2:4;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_des_v_position;
+
+
+    union {
+        struct
+        {
+            unsigned int main_y_v_r0:17;
+            unsigned int reserved_1:3;
+            unsigned int main_y_v_i_phase:6;
+            unsigned int reserved_2:6;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_y_v_init_r0;
+
+    union
+    {
+        struct
+        {
+            unsigned int main_y_h_r0:17;
+            unsigned int reserved_1:3;
+            unsigned int main_y_h_i_phase:6;
+            unsigned int reserved_2:6;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_y_h_init_r0;
+
+    union
+    {
+        struct
+        {
+            unsigned int main_y_h_d0_abs:24;
+            unsigned int reserved_1:8;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_y_h_d0_abs;
+
+    union
+    {
+        struct
+        {
+            unsigned int main_y_h_k_abs:13;
+            unsigned int reserved_1:3;
+            unsigned int main_y_h_k_sign:1;
+            unsigned int reserved_2:3;
+            unsigned int main_y_h_k_radix:5;
+            unsigned int reserved_3:7;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_y_h_k;
+
+    union
+    {
+        struct
+        {
+            unsigned int main_y_h_n1:11;
+            unsigned int reserved_1:21;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_y_h_n1;
+
+
+    union
+    {
+        struct
+        {
+            unsigned int main_c_v_r0:17;
+            unsigned int reserved_1:3;
+            unsigned int reserved_2:12;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_c_v_init_r0;
+
+    union
+    {
+        struct
+        {
+            unsigned int main_c_h_r0:17;
+            unsigned int reserved_1:3;
+            unsigned int main_c_h_i_phase:6;
+            unsigned int reserved_2:6;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_c_h_init_r0;
+
+    union
+    {
+        struct
+        {
+            unsigned int main_c_h_d0_abs:24;
+            unsigned int reserved_1:8;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_c_h_d0_abs;
+
+    union
+    {
+        struct
+        {
+            unsigned int main_c_h_k_abs:13;
+            unsigned int reserved_1:3;
+            unsigned int main_c_h_k_sign:1;
+            unsigned int reserved_2:3;
+            unsigned int main_c_h_k_radix:5;
+            unsigned int reserved_3:7;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_c_h_k;
+
+    union
+    {
+        struct
+        {
+            unsigned int main_c_h_n1:11;
+            unsigned int reserved_1:21;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_c_h_n1;
+    union
+    {
+        struct
+        {
+            unsigned int main_cof_yv6_group:4;
+            unsigned int main_cof_yv3_group:4;
+            unsigned int main_cof_yh6_group:4;
+            unsigned int main_cof_ch6_group:4;
+            unsigned int reserved_1:16;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_cof_ctrl;
+
+    union
+    {
+        struct
+        {
+            unsigned int main_ups_en:1;
+            unsigned int reserved_1:3;
+            unsigned int main_ups_pv:1;
+            unsigned int reserved_2:3;
+            unsigned int main_ups_th_up:8;
+            unsigned int main_ups_th_dn:8;
+            unsigned int main_ups_th_factor:8;
+        }bits;
+        unsigned int val;
+    }reg_main_ups_setting;
+    union
+    {
+        struct
+        {
+            unsigned int main_y_en:1;
+            unsigned int main_c_en:1;
+            unsigned int main_src_i_bf_invert:1;
+            unsigned int reserved_1:1;
+            unsigned int main_rd_qa_en:1;
+            unsigned int reserved_2:3;
+            unsigned int main_f2f_mode:1;
+			unsigned int main_lb_init_step:6;
+			unsigned int reserved_3:1;
+            unsigned int main_scr_v1_full:12;
+            unsigned int reserved_4:4;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_ctrl;
+    union
+    {
+        struct
+        {
+            unsigned int main_y_tnr_en:1;
+            unsigned int reserved_1:3;
+            unsigned int main_y_tnr_frame:1;
+            unsigned int reserved_2:3;
+            unsigned int main_y_tnr_gate:6;
+            unsigned int reserved_3:2;
+            unsigned int main_y_tnr_div:2;
+            unsigned int reserved_4:14;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_y_tnr_setting;
+
+    union
+    {
+        struct
+        {
+            unsigned int main_y_madi_en:1;
+            unsigned int reserved_1:3;
+            unsigned int main_y_madi_gate:3;
+            unsigned int reserved_2:1;
+            unsigned int main_y_madi_force_3d:1;
+            unsigned int reserved_3:23;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_y_madi_setting;
+
+    union
+    {
+        struct
+        {
+            unsigned int main_y_dir_en:1;
+            unsigned int reserved_1:3;
+            unsigned int main_y_dir_min0:5;
+            unsigned int reserved_2:3;
+            unsigned int main_y_dir_min1:5;
+            unsigned int reserved_3:3;
+            unsigned int main_y_dir_k0:4;
+            unsigned int main_y_dir_k1:4;
+            unsigned int main_y_dir_max:4;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_y_dir_setting;
+    union
+    {
+        struct
+        {
+            unsigned int main_c_tnr_en:1;
+            unsigned int reserved_1:7;
+            unsigned int main_c_tnr_gate:6;
+            unsigned int reserved_3:2;
+            unsigned int main_c_tnr_div:2;
+            unsigned int reserved_4:14;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_c_tnr_setting;
+
+    union
+    {
+        struct
+        {
+            unsigned int main_c_madi_en:1;
+            unsigned int reserved_1:3;
+            unsigned int main_c_madi_gate:3;
+            unsigned int reserved_2:25;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_c_madi_setting;
+
+    union
+    {
+        struct
+        {
+            unsigned int main_c_dir_en:1;
+            unsigned int reserved_1:3;
+            unsigned int main_c_dir_min0:5;
+            unsigned int reserved_2:3;
+            unsigned int main_c_dir_min1:5;
+            unsigned int reserved_3:3;
+            unsigned int main_c_dir_k0:4;
+            unsigned int main_c_dir_k1:4;
+            unsigned int main_c_dir_max:4;
+        }bits;
+        unsigned int val;
+    }reg_main_ch_c_dir_setting;
+
+    union
+    {
+        struct
+        {
+            unsigned int blend1_bg_y:10;
+            unsigned int blend1_bg_u:10;
+            unsigned int blend1_bg_v:10;
+            unsigned int reserved_1:2;
+        }bits;
+        unsigned int val;
+    }reg_main_b1_back_ground;
+
+    union
+    {
+        struct
+        {
+            unsigned int blend1_result_x_start:12;
+            unsigned int reserved_1:4;
+            unsigned int blend1_result_x_end:12;
+            unsigned int reserved_2:4;
+        }bits;
+        unsigned int val;
+    }reg_main_b1_des_position_x;
+
+    union
+    {
+        struct
+        {
+            unsigned int blend1_result_y_start:12;
+            unsigned int reserved_1:4;
+            unsigned int blend1_result_y_end:12;
+            unsigned int reserved_2:4;
+        }bits;
+        unsigned int val;
+    }reg_main_b1_des_position_y;
+    union
+    {
+        struct
+        {
+            unsigned int main_bg_en:1;
+            unsigned int reserved_1:31;
+        }bits;
+        unsigned int val;
+    }reg_main_b1_ctrl;
+    union
+    {
+        struct
+        {
+            unsigned int line_cnt_y_f2f_wr:12;
+            unsigned int reserved_1:4;
+            unsigned int main_wr_f2f_finish:1;
+            unsigned int reserved_2:15;
+        }bits;
+        unsigned int val;
+    }reg_main_sta_vpp_num;
+}MAIN;
+
+typedef struct _F2F_RD
+{
+    union
+    {
+        struct
+        {
+            unsigned int reserved_1:7;
+            unsigned int f2f_rd_frame_addr_y:25;
+        }bits;
+        unsigned int val;
+    }reg_f2f_rd_yf_addr;
+
+    union
+    {
+        struct
+        {
+            unsigned int reserved_1:7;
+            unsigned int f2f_rd_frame_addr_c:25;
+        }bits;
+        unsigned int val;
+    }reg_f2f_rd_cf_addr;
+    union
+    {
+        struct
+        {
+            unsigned int f2f_rd_video_en:1;
+            unsigned int reserved_1:15;
+            unsigned int f2f_rd_line_pitch:6;
+            unsigned int reserved_2:10;
+        }bits;
+        unsigned int val;
+    }reg_f2f_rd_ctrl;
+    union
+    {
+        struct
+        {
+            unsigned int f2f_rd_src_x_start:12;
+            unsigned int reserved_1:4;
+            unsigned int f2f_rd_src_x_end:12;
+            unsigned int reserved_2:4;
+        }bits;
+        unsigned int val;
+    }reg_f2f_rd_src_x_crop;
+
+    union
+    {
+        struct
+        {
+            unsigned int f2f_rd_src_y_start:12;
+            unsigned int reserved_1:4;
+            unsigned int f2f_rd_src_y_end:12;
+            unsigned int reserved_2:4;
+        }bits;
+        unsigned int val;
+    }reg_f2f_rd_src_y_crop;
+
+    union
+    {
+        struct
+        {
+            unsigned int f2f_rd_disp_x_start:12;
+            unsigned int reserved_1:4;
+            unsigned int f2f_rd_disp_x_end:12;
+            unsigned int reserved_2:4;
+        }bits;
+        unsigned int val;
+    }reg_f2f_rd_x_position;
+
+    union
+    {
+        struct
+        {
+            unsigned int f2f_rd_disp_y_start:12;
+            unsigned int reserved_1:4;
+            unsigned int f2f_rd_disp_y_end:12;
+            unsigned int reserved_2:4;
+        }bits;
+        unsigned int val;
+    }reg_f2f_rd_y_position;
+
+    union
+    {
+        struct
+        {
+            unsigned int f2f_rd_disp_num:32;
+        }bits;
+        unsigned int val;
+    }reg_f2f_rd_disp_num;
+
+}F2F_RD;
+
+typedef struct _HD2SD_RD
+{
+    union
+    {
+        struct
+        {
+            unsigned int reserved_1:7;
+            unsigned int hd2sd_rd_y_128_addr_frame:25;
+        }bits;
+        unsigned int val;
+    }reg_hd2sd_rd_yf_addr;
+
+    union
+    {
+        struct
+        {
+            unsigned int reserved_1:7;
+            unsigned int hd2sd_rd_c_128_addr_frame:25;
+        }bits;
+        unsigned int val;
+    }reg_hd2sd_rd_cf_addr;
+    union
+    {
+        struct
+        {
+            unsigned int hd2sd_rd_video_en:1;
+            unsigned int reserved_1:15;
+            unsigned int hd2sd_rd_line_pitch:6;
+            unsigned int reserved_2:10;
+        }bits;
+        unsigned int val;
+    }reg_hd2sd_rd_ctrl;
+    union
+    {
+        struct
+        {
+            unsigned int hd2sd_rd_src_x_start:12;
+            unsigned int reserved_1:4;
+            unsigned int hd2sd_rd_src_x_end:12;
+            unsigned int reserved_2:4;
+        }bits;
+        unsigned int val;
+    }reg_hd2sd_rd_src_x_crop;
+
+    union
+    {
+        struct
+        {
+            unsigned int hd2sd_rd_src_y_start:12;
+            unsigned int reserved_1:4;
+            unsigned int hd2sd_rd_src_y_end:12;
+            unsigned int reserved_2:4;
+        }bits;
+        unsigned int val;
+    }reg_hd2sd_rd_src_y_crop;
+
+    union
+    {
+        struct
+        {
+            unsigned int hd2sd_rd_video_x_start:12;
+            unsigned int reserved_1:4;
+            unsigned int hd2sd_rd_video_x_end:12;
+            unsigned int reserved_2:4;
+        }bits;
+        unsigned int val;
+    }reg_hd2sd_rd_x_position;
+
+    union
+    {
+        struct
+        {
+            unsigned int hd2sd_rd_video_y_start:12;
+            unsigned int reserved_1:4;
+            unsigned int hd2sd_rd_video_y_end:12;
+            unsigned int reserved_2:4;
+        }bits;
+        unsigned int val;
+    }reg_hd2sd_rd_y_position;
+
+    union
+    {
+        struct
+        {
+            unsigned int hd2sd_rd_disp_num:32;
+        }bits;
+        unsigned int val;
+    }reg_hd2sd_rd_disp_num;
+}HD2SD_RD;
+
+typedef struct _DMA
+{
+        union
+        {
+            struct
+            {
+                unsigned int reserved1:7;
+                unsigned int dma_rd_yf_addr:25;
+         }bits;
+            unsigned int val;
+        }reg_dma_rd_yf_addr;
+        union
+        {
+            struct
+            {
+                unsigned int reserved1:7;
+                unsigned int dma_rd_cf_addr:25;
+         }bits;
+            unsigned int val;
+        }reg_dma_rd_cf_addr;
+        union
+        {
+            struct
+            {
+                unsigned int reserved1:7;
+                unsigned int dma_wr_yf_addr:25;
+         }bits;
+            unsigned int val;
+        }reg_dma_wr_yf_addr;
+        union
+        {
+            struct
+            {
+                unsigned int reserved1:7;
+                unsigned int dma_wr_cf_addr:25;
+         }bits;
+            unsigned int val;
+        }reg_dma_wr_cf_addr;
+        union
+        {
+            struct
+            {
+                unsigned int dma_en:1;
+                unsigned int reserved1:3;
+                unsigned int dma_src_c_v_sample:1;
+                unsigned int reserved2:3;
+                unsigned int dma_start:1;
+                unsigned int reserved3:7;
+                unsigned int dma_rd_line_pitch:6;
+                unsigned int reserved4:2;
+                unsigned int dma_wr_line_pitch:6;
+                unsigned int reserved5:2;
+         }bits;
+            unsigned int val;
+        }reg_dma_ctrl;
+        union
+        {
+            struct
+            {
+                unsigned int dma_src_x_start:12;
+                unsigned int reserved1:4;
+                unsigned int dma_src_x_end:12;
+                unsigned int reserved2:4;
+         }bits;
+            unsigned int val;
+        }reg_dma_src_x_crop;
+        union
+        {
+            struct
+            {
+                unsigned int dma_src_y_start:12;
+                unsigned int reserved1:4;
+                unsigned int dma_src_y_end:12;
+                unsigned int reserved2:4;
+         }bits;
+            unsigned int val;
+        }reg_dma_src_y_crop;
+        union
+        {
+            struct
+            {
+                unsigned int dma_des_x_start:12;
+                unsigned int reserved1:4;
+                unsigned int dma_des_x_end:12;
+                unsigned int reserved2:4;
+         }bits;
+            unsigned int val;
+        }reg_dma_des_x_position;
+        union
+        {
+            struct
+            {
+                unsigned int dma_des_y_start:12;
+                unsigned int reserved1:4;
+                unsigned int dma_des_y_end:12;
+                unsigned int reserved2:4;
+         }bits;
+            unsigned int val;
+        }reg_dma_des_y_position;
+}DMA;
+
+typedef struct _CAP
+{
+
+    union
+    {
+        struct
+        {
+			unsigned int cap_en:1;
+			unsigned int cap_c_v_sample:1;
+			unsigned int reserved_1:2;
+			unsigned int cap_des_is_i:1;
+			unsigned int reserved_2:3;
+			unsigned int cap_cap_left:1;
+			unsigned int reserved_3:3;
+			unsigned int hd2sd_3frame_mode:1;
+            unsigned int reserved_4:1;
+            unsigned int cap_frame_get:1;
+			unsigned int hd2sd_frame_release:1;
+			unsigned int cap_line_pitch:6;
+			unsigned int reserved_5:10;
+        }bits;
+        unsigned int val;
+	}reg_cap_ctrl;
+	union
+	{
+		struct
+		{
+			unsigned int cap_src_ext:1;
+			unsigned int cap_ext_fs_sel:1;
+			unsigned int cap_ext_fs_pol:1;
+			unsigned int cap_ext_vs_pol:1;
+			unsigned int cap_ext_hs_pol:1;
+			unsigned int cap_ext_emb_en:1;
+			unsigned int cap_ext_2lane:1;
+			unsigned int cap_ext_10bpc:1;
+			unsigned int cap_ext_csc_en:1;
+			unsigned int cap_scr_is_i:1;
+			unsigned int cap_scr_c_h_sample:1;
+			unsigned int reserved_1:21;
+		}bits;
+		unsigned int val;
+	}reg_cap_scr_setting;
+	union
+	{
+		struct
+		{
+			unsigned int cap_scr_h_start:12;
+			unsigned int reserved_1:4;
+			unsigned int cap_scr_h_end:12;
+			unsigned int reserved_2:4;
+		}bits;
+		unsigned int val;
+	}reg_cap_scr_h_position;
+	union
+	{
+		struct
+		{
+			unsigned int cap_scr_v_start:12;
+			unsigned int reserved_1:4;
+			unsigned int cap_scr_v1_full:12;
+			unsigned int reserved_2:4;
+		}bits;
+		unsigned int val;
+	}reg_cap_scr_v_position;
+
+    union
+    {
+        struct
+        {
+			unsigned int cap_des_h_start:12;
+            unsigned int reserved_1:4;
+			unsigned int cap_des_h_end:12;
+            unsigned int reserved_2:4;
+        }bits;
+        unsigned int val;
+	}reg_cap_des_h_position;
+	union
+	{
+		struct
+		{
+			unsigned int cap_des_v_start:12;
+			unsigned int reserved_1:4;
+			unsigned int cap_des_v_end:12;
+			unsigned int reserved_2:4;
+		}bits;
+		unsigned int val;
+	}reg_cap_des_v_position;
+
+    union
+    {
+        struct
+        {
+			unsigned int cap_sca_y_v_r0:17;
+			unsigned int reserved_1:15;
+		}bits;
+		unsigned int val;
+	}reg_cap_yv_ratio;
+
+    union
+    {
+        struct
+        {
+			unsigned int cap_sca_y_h_r0:17;
+			unsigned int reserved_1:15;
+		}bits;
+		unsigned int val;
+	}reg_cap_yh_ratio;
+
+    union
+    {
+        struct
+        {
+			unsigned int cap_sca_c_v_r0:17;
+			unsigned int reserved_1:15;
+		}bits;
+		unsigned int val;
+	}reg_cap_cv_ratio;
+
+    union
+    {
+        struct
+        {
+			unsigned int cap_sca_c_h_r0:17;
+            unsigned int reserved_1:15;
+        }bits;
+        unsigned int val;
+	}reg_cap_ch_ratio;
+
+    union
+    {
+        struct
+        {
+			unsigned int cap_sca_y_d0_abs:24;
+			unsigned int reserved_1:8;
+        }bits;
+        unsigned int val;
+	}reg_cap_y_noline_d;
+
+    union
+    {
+        struct
+        {
+			unsigned int cap_sca_c_d0_abs:24;
+			unsigned int reserved_1:8;
+		}bits;
+		unsigned int val;
+	}reg_cap_c_noline_d;
+    union
+    {
+        struct
+		{
+			unsigned int cap_sca_y_h_k_abs:13;
+			unsigned int reserved_1:2;
+			unsigned int cap_sca_y_h_k_sign:1;
+			unsigned int cap_sca_y_h_k_radix:5;
+			unsigned int cap_sca_y_h_n1:11;
+		}bits;
+		unsigned int val;
+	}reg_cap_y_noline_k;
+
+    union
+    {
+        struct
+        {
+			unsigned int cap_sca_c_h_k_abs:13;
+			unsigned int reserved_1:2;
+			unsigned int cap_sca_c_h_k_sign:1;
+			unsigned int cap_sca_c_h_k_radix:5;
+			unsigned int cap_sca_c_h_n1:11;
+        }bits;
+        unsigned int val;
+	}reg_cap_c_noline_k;
+	union
+	{
+		struct
+		{
+			unsigned int cap_iphase_h_y:6;
+			unsigned int reserved_1:10;
+			unsigned int cap_iphase_h_c:6;
+			unsigned int reserved_2:10;
+		}bits;
+		unsigned int val;
+	}reg_cap_hor_phase;
+
+	union
+	{
+		struct
+		{
+			unsigned int cap_iphase_v_y:6;
+			unsigned int reserved_1:26;
+		}bits;
+		unsigned int val;
+	}reg_cap_ver_phase;
+
+	union
+	{
+		struct
+		{
+			unsigned int reserved_1:7;
+			unsigned int cap_y_128_addr_frame0:25;
+		}bits;
+		unsigned int val;
+	}reg_cap_yt_addr0;
+
+	union
+	{
+		struct
+		{
+			unsigned int reserved_1:7;
+			unsigned int cap_c_128_addr_frame0:25;
+		}bits;
+		unsigned int val;
+	}reg_cap_ct_addr0;
+	union
+	{
+		struct
+		{
+			unsigned int reserved_1:7;
+			unsigned int cap_y_128_addr_frame1:25;
+		}bits;
+		unsigned int val;
+	}reg_cap_yt_addr1;
+
+	union
+	{
+		struct
+		{
+			unsigned int reserved_1:7;
+			unsigned int cap_c_128_addr_frame1:25;
+		}bits;
+		unsigned int val;
+	}reg_cap_ct_addr1;
+	union
+	{
+		struct
+		{
+			unsigned int reserved_1:7;
+			unsigned int cap_y_128_addr_frame2:25;
+		}bits;
+		unsigned int val;
+	}reg_cap_yt_addr2;
+
+	union
+	{
+		struct
+		{
+			unsigned int reserved_1:7;
+			unsigned int cap_c_128_addr_frame2:25;
+		}bits;
+		unsigned int val;
+	}reg_cap_ct_addr2;
+	union
+	{
+		struct
+		{
+			unsigned int reserved_1:7;
+			unsigned int cap_y_128_addr_frame3:25;
+		}bits;
+		unsigned int val;
+	}reg_cap_yt_addr3;
+
+	union
+	{
+		struct
+		{
+			unsigned int reserved_1:7;
+			unsigned int cap_c_128_addr_frame3:25;
+		}bits;
+		unsigned int val;
+	}reg_cap_ct_addr3;
+	union
+	{
+		struct
+		{
+			unsigned int reserved_1:7;
+			unsigned int cap_y_128_addr_frame4:25;
+		}bits;
+		unsigned int val;
+	}reg_cap_yt_addr4;
+
+	union
+	{
+		struct
+		{
+			unsigned int reserved_1:7;
+			unsigned int cap_c_128_addr_frame4:25;
+		}bits;
+		unsigned int val;
+	}reg_cap_ct_addr4;
+	union
+	{
+		struct
+		{
+			unsigned int cap_cof_yv4_group:4;
+			unsigned int cap_cof_cv4_group:4;
+			unsigned int cap_cof_yh6_group:4;
+			unsigned int cap_cof_ch6_group:4;
+			unsigned int cap_line_finish_cnt:12;
+			unsigned int reserved_2:4;
+        }bits;
+        unsigned int val;
+	}reg_cap_coeff_no;
+
+	union
+	{
+		struct
+		{
+			unsigned int cap_idx:3;
+			unsigned int reserved:29;
+		}bits;
+		unsigned int val;
+	}reg_cap_idx;
+
+	union
+	{
+		struct
+		{
+			unsigned int cap_pts:32;
+		}bits;
+		unsigned int val;
+	}reg_cap_pts;
+
+	union
+	{
+		struct
+		{
+			unsigned int cap_stc:32;
+		}bits;
+		unsigned int val;
+	}reg_cap_stc_tg1;
+	union
+	{
+		struct
+		{
+			unsigned int cap_line_cnt:12;
+			unsigned int reserved_1:20;
+		}bits;
+		unsigned int val;
+	}reg_cap_line_cnt;
+
+    union
+    {
+        struct
+        {
+            unsigned int cap_status:32;
+        }bits;
+        unsigned int val;
+    }reg_cap_status;
+    union
+    {
+        struct
+        {
+            unsigned int cap_h_resolution:12;
+            unsigned int reserved_1:4;
+            unsigned int cap_v_resolution:12;
+            unsigned int reserved_2:3;
+            unsigned int cap_format_change:1;
+        }bits;
+        unsigned int val;
+    }reg_cap_format;
+
+}CAP;
+
+typedef struct _COMP
+{
+    union{
+        struct{
+            unsigned int blending2_bg_y:10;
+            unsigned int blending2_bg_u:10;
+            unsigned int blending2_bg_v:10;
+            unsigned int reserved_1:2;
+        }bits;
+        unsigned int val;
+    }reg_comp_b2_back_ground;
+
+    union{
+        struct{
+            unsigned int blending2_video1_z_order:2;
+            unsigned int reserved_1:2;
+            unsigned int blending2_video2_z_order:2;
+            unsigned int reserved_2:2;
+            unsigned int blending2_gfx1_z_order:2;
+            unsigned int reserved_3:2;
+            unsigned int blending2_gfx2_z_order:2;
+            unsigned int reserved_4:18;
+        }bits;
+        unsigned int val;
+    }reg_comp_b2_z_order;
+
+    union{
+        struct{
+            unsigned int blending2_default_alpha1:10;
+            unsigned int reserved_1:6;
+            unsigned int blending2_default_alpha2:10;
+            unsigned int reserved_2:6;
+        }bits;
+        unsigned int val;
+    }reg_comp_b2_default_alpha;
+    union{
+        struct{
+            unsigned int blending3_bg_y:10;
+            unsigned int blending3_bg_u:10;
+            unsigned int blending3_bg_v:10;
+            unsigned int reserved_1:2;
+        }bits;
+        unsigned int val;
+    }reg_comp_b3_back_ground;
+
+    union{
+        struct{
+            unsigned int blending3_video1_z_order:2;
+            unsigned int reserved_1:2;
+            unsigned int reserved_2:4;
+            unsigned int blending3_gfx1_z_order:2;
+            unsigned int reserved_3:4;
+            unsigned int reserved_4:18;
+        }bits;
+        unsigned int val;
+    }reg_comp_b3_z_order;
+
+    union{
+        struct{
+            unsigned int blending3_default_alpha1:10;
+            unsigned int reserved_1:6;
+            unsigned int reserved_2:16;
+        }bits;
+        unsigned int val;
+    }reg_comp_b3_default_alpha;
+
+
+    union{
+        struct{
+            unsigned int enh_y_sharp_en:1;
+            unsigned int enh_y_median_en:1;
+            unsigned int enh_y_coring_soft:1;
+            unsigned int reserved_1:1;
+            unsigned int enh_y_peaking_shrink:3;
+            unsigned int reserved_2:1;
+            unsigned int enh_y_coring:6;
+            unsigned int reserved_3:2;
+            unsigned int enh_y_bpw:8;
+            unsigned int enh_y_hpw:8;
+        }bits;
+        unsigned int val;
+    }reg_comp_sharp_y;
+
+    union{
+        struct{
+            unsigned int enh_c_sharp_en:1;
+            unsigned int enh_c_median_en:1;
+            unsigned int enh_c_coring_soft:1;
+            unsigned int reserved_1:1;
+            unsigned int enh_c_peaking_shrink:3;
+            unsigned int reserved_2:1;
+            unsigned int enh_c_coring:6;
+            unsigned int reserved_3:2;
+            unsigned int enh_c_bpw:8;
+            unsigned int enh_c_hpw:8;
+        }bits;
+        unsigned int val;
+    }reg_comp_sharp_c;
+
+    union{
+        struct{
+            unsigned int enh_bright:8;
+            unsigned int enh_contrast:6;
+            unsigned int reserved_1:2;
+            unsigned int enh_saturation:8;
+            unsigned int reserved_2:8;
+        }bits;
+        unsigned int val;
+    }reg_comp_color_adjust;
+}df_compositor_reg;
+
+typedef struct _TG
+{
+    union
+    {
+        struct
+        {
+            unsigned int tg_en:1;
+            unsigned int reserved_1:1;
+            unsigned int tg_is_hd:1;
+            unsigned int reserved_2:2;
+            unsigned int tg_is_interlaced:1;
+            unsigned int reserved_3:1;
+            unsigned int tg_is_pal:1;
+            unsigned int reserved_3_1:3;
+            unsigned int tg_dither_mode:1;
+            unsigned int tg_hsync_pol:1;
+            unsigned int tg_vsync_pol:1;
+            unsigned int tg_dither_ena:1;
+            unsigned int reserved_4:1;
+            unsigned int tg_3d_act_space:8;
+            unsigned int tg_3d_en:1;
+            unsigned int reserved_5:7;
+        }bits;
+        unsigned int val;
+    }reg_tg_ctrl;
+
+    union
+    {
+        struct
+        {
+            unsigned int tg_htotal:13;
+            unsigned int reserved_1:3;
+            unsigned int tg_hactive_width:12;
+            unsigned int reserved_2:4;
+        }bits;
+        unsigned int val;
+    }reg_tg_x_size;
+
+    union
+    {
+        struct
+        {
+            unsigned int tg_vtotal:13;
+            unsigned int reserved_1:3;
+            unsigned int tg_vactive_height:12;
+            unsigned int reserved_2:4;
+        }bits;
+        unsigned int val;
+    }reg_tg_y_size;
+
+    union
+    {
+        struct
+        {
+            unsigned int tg_hsync_front_porch:10;
+            unsigned int tg_hsync_width:10;
+            unsigned int tg_hsync_back_porch:10;
+            unsigned int reserved_1:2;
+        }bits;
+        unsigned int val;
+    }reg_tg_hsync;
+
+    union
+    {
+        struct
+        {
+            unsigned int tg_vsync_front_porch:8;
+            unsigned int tg_vsync_width:8;
+            unsigned int tg_vsync_back_porch:8;
+            unsigned int reserved_1:8;
+        }bits;
+        unsigned int val;
+    }reg_tg_vsync;
+
+    union
+    {
+        struct
+        {
+            unsigned int tg_vga_black_level:10;
+            unsigned int reserved_1:6;
+            unsigned int tg_vga_white_level:10;
+            unsigned int reserved_2:6;
+        }bits;
+        unsigned int val;
+    }reg_tg_vga_level;
+
+    union
+    {
+        struct
+        {
+            unsigned int tg_v_start_line_num: 6;
+            unsigned int reserved_1:10;
+            unsigned int reserved_2:16;
+        }bits;
+        unsigned int val;
+    }reg_tg_sta_line;
+
+    union
+    {
+        struct
+        {
+            unsigned int disp_width: 12;
+            unsigned int reserved_1:4;
+            unsigned int disp_height: 12;
+            unsigned int reserved_2:4;
+        }bits;
+        unsigned int val;
+    }reg_tg_sta_disp_size;
+
+    union
+    {
+        struct
+        {
+            unsigned int disp_scan_line_cnt: 13;
+            unsigned int reserved_1:3;
+            unsigned int disp_scan_line_active_line: 1;
+            unsigned int reserved_2:3;
+            unsigned int disp_bottom_flag: 1;
+            unsigned int reserved_3:3;
+            unsigned int disp_vsync: 1;
+            unsigned int reserved_4:7;
+        }bits;
+        unsigned int val;
+    }reg_tg_sta_disp_line;
+}df_outif_reg;
+
+typedef struct _UI
+{
+        union
+        {
+            struct
+            {
+                unsigned int gfx_ui_ena:1;
+                unsigned int gfx_ui_format:3;
+                unsigned int gfx_ui_endian:2;
+                unsigned int gfx_ui_opaque:1;
+                unsigned int gfx_ui_color_keying_en:1;
+                unsigned int gfx_ui_ena_premul:1;
+                unsigned int gfx_ui_af_sc_dis:1;
+                unsigned int gfx_ui_antiflicker_en_a:1;
+                unsigned int gfx_ui_antiflicker_en_c:1;
+                unsigned int gfx_ui_ena_demul:1;
+                unsigned int gfx_ui_yuv_conv_ena:1;
+                unsigned int reserved1:2;
+                unsigned int gfx_ui_bw_limit:8;
+                unsigned int ui_tg1_en:1;
+                unsigned int reserved2:7;
+            }bits;
+            unsigned int val;
+        }reg_gfx_ui_ctrl;
+        union
+        {
+            struct
+            {
+                unsigned int gfx_ui_src_width:16;
+                unsigned int gfx_ui_src_height:16;
+            }bits;
+            unsigned int val;
+        }reg_gfx_ui_size;
+        union
+        {
+            struct
+            {
+                unsigned int gfx_ui_default_alpha:8;
+                unsigned int reserved1:2;
+                unsigned int gfx_ui_argb1555_a0:8;
+                unsigned int reserved2:2;
+                unsigned int gfx_ui_argb1555_a1:8;
+                unsigned int reserved3:4;
+            }bits;
+            unsigned int val;
+        }reg_gfx_ui_alpha_ctrl;
+        union
+        {
+            struct
+            {
+                unsigned int gfx_ui_r_min:8;
+                unsigned int gfx_ui_r_max:8;
+                unsigned int reserved1:16;
+            }bits;
+            unsigned int val;
+        }reg_gfx_ui_key_red;
+        union
+        {
+            struct
+            {
+                unsigned int gfx_ui_b_min:8;
+                unsigned int gfx_ui_b_max:8;
+                unsigned int reserved1:16;
+            }bits;
+            unsigned int val;
+        }reg_gfx_ui_key_blue;
+        union
+        {
+            struct
+            {
+                unsigned int gfx_ui_g_min:8;
+                unsigned int gfx_ui_g_max:8;
+                unsigned int reserved1:16;
+            }bits;
+            unsigned int val;
+        }reg_gfx_ui_key_green;
+        union
+        {
+            struct
+            {
+                unsigned int gfx_ui_buf_start:32;
+            }bits;
+            unsigned int val;
+        }reg_gfx_ui_buf_start;
+        union
+        {
+            struct
+            {
+                unsigned int gfx_ui_buf_start_3d:32;
+            }bits;
+            unsigned int val;
+        }reg_gfx_ui_buf_start_3d;
+        union
+        {
+            struct
+            {
+                unsigned int gfx_ui_line_pitch:32;
+            }bits;
+            unsigned int val;
+        }reg_gfx_ui_line_pitch;
+        union
+        {
+            struct
+            {
+                unsigned int gfx_ui_dst_x_start:16;
+                unsigned int gfx_ui_dst_x_end:16;
+            }bits;
+            unsigned int val;
+        }reg_gfx_ui_x_position;
+        union
+        {
+            struct
+            {
+                unsigned int gfx_ui_dst_y_start:16;
+                unsigned int gfx_ui_dst_y_end:16;
+            }bits;
+            unsigned int val;
+        }reg_gfx_ui_y_position;
+        union
+        {
+            struct
+            {
+                unsigned int gfx_ui_a8_r:8;
+                unsigned int gfx_ui_a8_g:8;
+                unsigned int gfx_ui_a8_b:8;
+                unsigned int reserved1:8;
+            }bits;
+            unsigned int val;
+        }reg_gfx_ui_a8;
+        union
+        {
+            struct
+            {
+                unsigned int gfx_ui_hphase:6;
+                unsigned int reserved1:2;
+                unsigned int gfx_ui_vphase:6;
+                unsigned int reserved2:18;
+            }bits;
+            unsigned int val;
+        }reg_gfx_ui_phase;
+
+        union
+        {
+            struct
+            {
+                unsigned int gfx_ui_hcoeff_gid:4;
+                unsigned int gfx_ui_vcoeff_gid:4;
+                unsigned int reserved1:24;
+            }bits;
+            unsigned int val;
+        }reg_gfx_ui_coeff_gid;
+
+}df_gfx_reg;
+
+typedef struct _DF_REG_PARA_
+{
+	df_ctrl_reg		Ctrl;
+	df_gfx_reg		Gfx[2];
+//	df_video1_reg		Video1;
+//	df_video2_reg		Video2;
+//	df_video3_reg		Video3;
+	df_compositor_reg	Comp;
+//	df_hd2sd_reg		HD2SD;
+	df_outif_reg		OutIF[2];
+}df_reg_para;
+#endif
+
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/arch/arm/mach-celestial/include/mach/debug-macro.S linux-linaro-3.4-2012.05-1_cavium/arch/arm/mach-celestial/include/mach/debug-macro.S
--- linux-linaro-3.4-2012.05-1_original/arch/arm/mach-celestial/include/mach/debug-macro.S	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/arch/arm/mach-celestial/include/mach/debug-macro.S	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,18 @@
+/*
+ * Debugging macro for Cavium CNC1900 Platform
+ * Author: xiaodong fan
+ *
+ * This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+#include <mach/hardware.h>
+
+	.macro  addruart, rp, rv, tmp
+	ldr	\rp, =CNC1900_UART0				@ physical
+	ldr	\rv, =IO_ADDRESS(CNC1900_UART0)	@ virtual
+	.endm
+
+#define UART_SHIFT 2
+#include <asm/hardware/debug-8250.S>
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/arch/arm/mach-celestial/include/mach/hardware.h linux-linaro-3.4-2012.05-1_cavium/arch/arm/mach-celestial/include/mach/hardware.h
--- linux-linaro-3.4-2012.05-1_original/arch/arm/mach-celestial/include/mach/hardware.h	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/arch/arm/mach-celestial/include/mach/hardware.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,19 @@
+/*
+ *  arch/arm/mach-celestial/include/mach/hardware.h
+ *
+ *  This file contains the hardware definitions of the Cavium CNC1900 Platform.
+ *
+ *  Copyright (C) 2012 Cavium 
+ *  Author: Xaodong Fan <xiaodong.fan@cavium.com>
+ */
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+#include <mach/cnc1900.h>
+
+/* macro to get at IO space when running virtually */
+#define IO_ADDRESS(phys) (0xF0000000 + ((((phys) >> 4) & 0x0ff00000) + ((phys) & 0xFFFFFFF)))
+ 
+#endif
+
+
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/arch/arm/mach-celestial/include/mach/irqs.h linux-linaro-3.4-2012.05-1_cavium/arch/arm/mach-celestial/include/mach/irqs.h
--- linux-linaro-3.4-2012.05-1_original/arch/arm/mach-celestial/include/mach/irqs.h	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/arch/arm/mach-celestial/include/mach/irqs.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,68 @@
+/*
+ *  linux/arch/arm/mach-celestialsemi/include/mach/irqs.h
+ *
+ *  Copyright (C) 2013 Cavium  
+
+ *  Author: Jia Ma <jma@caviumnetworks.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __ASM_ARM_ARCH_IRQ_H
+#define __ASM_ARM_ARCH_IRQ_H
+
+#define NR_IRQS        96
+
+#define CPU_PRI_TIMER_IRQ  29
+#define CPU_WDT_TIMER_IRQ  30
+#define CPU_PMU_IRQ		51
+#define EX_IRQ_PCMCIA_IRQ	52
+#define PCMCIA_IRQ	53
+#define GPIO_IRQ		54
+#define SPI_IRQ        55
+#define SECURITY_CORE_IRQ	56
+#define SD0_IRQ        57
+#define SD1_IRQ        58
+#define EHCI_IRQ	59
+#define CRYPTO_IRQ	60
+#define OHCI_IRQ	61
+#define READY_PCMCIA_N_IRQ		62
+#define IREQ_PCMCIA_N_IRQ		63
+#define HDMI_IRQ		64
+#define OTG_IRQ		65
+#define DISP2_IRQ	66
+#define DISP1_IRQ	67
+#define VIDEO_IRQ	68
+#define AUDIO_IRQ	69
+#define ETH0_IRQ       70
+#define XPORT_IRQ2	71
+#define XPORT_IRQ1	72
+#define IR_IRQ		73
+#define PANEL_CONTROL_IRQ		74
+#define I2C0_IRQ     75
+#define I2C1_IRQ       76
+#define UART1_IRQ      77
+#define UART0_IRQ      78
+#define SMART_CARD_IRQ		79
+#define GFX_IRQ		80
+#define CLKSET_IRQ	81
+#define ETH1_IRQ       83
+#define TZASC1		93
+#define TZASC0		94
+#define SECURE_TIMER_IRQ	95
+
+#define IRQ_CRYPTO_ENG 26
+
+#endif
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/arch/arm/mach-celestial/include/mach/mem_define.h linux-linaro-3.4-2012.05-1_cavium/arch/arm/mach-celestial/include/mach/mem_define.h
--- linux-linaro-3.4-2012.05-1_original/arch/arm/mach-celestial/include/mach/mem_define.h	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/arch/arm/mach-celestial/include/mach/mem_define.h	2015-06-19 15:58:42.412211000 +0800
@@ -0,0 +1,256 @@
+#ifndef __ARCH_MEM_DEF_H
+#define __ARCH_MEM_DEF_H
+
+//#define SW_FEED_VIDEO
+
+#if defined(CONFIG_CELESTIAL_HDK) ||defined(CONFIG_CELESTIAL_EVB) ||defined(CONFIG_CELESTIAL_OTT_EMMC)
+#ifdef CONFIG_SW_SUPPORT
+#define CELESTIAL_MEM_SIZE 480
+//#define AUDIO_ALIGN_GAP 0x0
+//#define AUDIO_PTS_FIXED_SIZE 0x0
+#else
+#define CELESTIAL_MEM_SIZE 512
+//#define AUDIO_ALIGN_GAP 0x100
+//#define AUDIO_PTS_FIXED_SIZE 0x100000
+#endif
+#elif defined(CONFIG_CELESTIAL_FJ_RX) || defined(CONFIG_CELESTIAL_FJ_TX)
+#define CELESTIAL_MEM_SIZE 256
+//#define AUDIO_ALIGN_GAP 0x100
+//#define AUDIO_PTS_FIXED_SIZE 0x100000
+#else
+#ifdef CONFIG_SW_SUPPORT
+#define CELESTIAL_MEM_SIZE 480
+//#define AUDIO_ALIGN_GAP 0x0
+//#define AUDIO_PTS_FIXED_SIZE 0x0
+#else
+#define CELESTIAL_MEM_SIZE 512
+//#define AUDIO_ALIGN_GAP 0x100
+//#define AUDIO_PTS_FIXED_SIZE 0x100000
+#endif
+#endif
+
+#define AUDIO_ALIGN_GAP 0x100
+#define AUDIO_PTS_FIXED_SIZE 0x100000
+
+#define        BASE_DDR_ADDR          0x10000000
+
+#ifdef CONFIG_FB0_SIZE
+#define        FB0_SIZE                   CONFIG_FB0_SIZE
+#else
+#define        FB0_SIZE                   0x1000000
+#endif
+#define        FB0_REGION             (BASE_DDR_ADDR - FB0_SIZE)
+#ifdef CONFIG_FB1_SIZE
+#define        FB1_SIZE               CONFIG_FB1_SIZE
+#else
+#define        FB1_SIZE               0x1000000
+#endif
+#define        FB1_REGION             (FB0_REGION - FB1_SIZE)
+
+#ifdef CONFIG_FB2_SIZE
+#define        FB2_SIZE               CONFIG_FB2_SIZE
+#else
+#define        FB2_SIZE               0x800000
+#endif
+#define        FB2_REGION             (FB0_REGION + FB0_SIZE - FB2_SIZE)
+
+#ifdef CONFIG_FB3_SIZE
+#define        FB3_SIZE               CONFIG_FB3_SIZE
+#else
+#define        FB3_SIZE               0x800000
+#endif
+#define        FB3_REGION             (FB1_REGION + FB1_SIZE - FB3_SIZE)
+
+#define        BLOB_SIZE              0x100000
+#define        BLOB_BASE              (FB1_REGION-BLOB_SIZE)
+
+#define        GPU_SIZE      		  0x2000000
+#define        GPU_BASE     		  (BLOB_BASE-GPU_SIZE)
+
+//for scalor coef data
+#define        SCALOR_COEF_SIZE       (0x2000*3)
+#define        SCALOR_COEF_REGION     (GPU_BASE-SCALOR_COEF_SIZE)
+
+#ifdef CONFIG_SW_SUPPORT 
+#define		CRYPTO_MEM_SIZE 0x0
+#else
+#define        CRYPTO_MEM_SIZE        0x300000
+#endif
+#define        CRYPTO_MEM_REGION      (SCALOR_COEF_REGION - CRYPTO_MEM_SIZE)
+
+#define        VIDEO_STUFF_SIZE       (0x400000)
+#define        VIDEO_STUFF_REGION     (CRYPTO_MEM_REGION - VIDEO_STUFF_SIZE)
+
+#if (defined CONFIG_SW_SUPPORT) && (defined SW_FEED_VIDEO)
+#define        VIDEO_NUM              (1)
+#define        VIDEO_DPB_SIZE         (0x0)
+#define        VIDEO_DPB_REGION       (VIDEO_STUFF_REGION - VIDEO_DPB_SIZE)
+#define        VIDEO_CPB_SIZE         (0x0 * VIDEO_NUM)
+#define        VIDEO_CPB_REGION       (VIDEO_DPB_REGION - VIDEO_CPB_SIZE)
+#define        VIDEO_CPB_DIR_SIZE     (0x0)
+#define        VIDEO_CPB_DIR_REGION   (VIDEO_CPB_REGION - VIDEO_CPB_DIR_SIZE)
+
+#ifdef CONFIG_VIDEO_ENC_NUM
+#define        VIDEO_ENC_NUM              CONFIG_VIDEO_ENC_NUM
+#else
+#define        VIDEO_ENC_NUM              0
+#endif
+
+#ifdef CONFIG_VIDEO_ENC_CPB_SIZE
+#define        VIDEO_ENC_CPB_SIZE     (CONFIG_VIDEO_ENC_CPB_SIZE * VIDEO_ENC_NUM)
+#else
+#define        VIDEO_ENC_CPB_SIZE     (0x400000 * VIDEO_ENC_NUM)
+#endif
+
+#define        VIDEO_ENC_CPB_REGION   (VIDEO_CPB_DIR_REGION - VIDEO_ENC_CPB_SIZE)
+#define        VIDEO_ENC_DIR_SIZE     (VIDEO_ENC_CPB_SIZE/0x100)
+#define        VIDEO_ENC_DIR_REGION   (VIDEO_ENC_CPB_REGION - VIDEO_ENC_DIR_SIZE)
+
+#define        VIDEO_USER_DATA_SIZE   (0x0 * VIDEO_NUM)
+#define        VIDEO_USER_DATA_REGION (VIDEO_ENC_DIR_REGION - VIDEO_USER_DATA_SIZE)
+
+#else
+
+#ifdef CONFIG_VIDEO_NUM
+#define        VIDEO_NUM              CONFIG_VIDEO_NUM
+#else
+#define        VIDEO_NUM              0
+#endif
+#if defined(CONFIG_CELESTIAL_FJ_RX) || defined(CONFIG_CELESTIAL_FJ_TX)
+//#define        VIDEO_DPB_SIZE         (0x1e9c000) // ((2048*1088*1.8 + 2047) >> 11 << 11) * 12
+#define        VIDEO_DPB_SIZE           (0x2ded000) // ((2048*1088*1.8 + 2047) >> 11 << 11) * 12
+#elif defined(CONFIG_CELESTIAL_HDK) || defined(CONFIG_CELESTIAL_OTT_EMMC)
+#define        VIDEO_DPB_SIZE         (0x4600000) // previosu one is 0x4600000. increase 0x1300000 under Jerry's suggestion. // go back to 0x46000000 for orange
+#else
+#define        VIDEO_DPB_SIZE         (0x7900000) // 2048*1088*1.8*27 + 2048*1088*2*3
+#endif
+#define        VIDEO_DPB_REGION       (VIDEO_STUFF_REGION - VIDEO_DPB_SIZE)
+#ifdef CONFIG_VIDEO_CPB_SIZE
+#define        VIDEO_CPB_SIZE         (CONFIG_VIDEO_CPB_SIZE * VIDEO_NUM)
+#else
+#define        VIDEO_CPB_SIZE         (0x400000 * VIDEO_NUM)
+#endif
+#define        VIDEO_CPB_REGION       (VIDEO_DPB_REGION - VIDEO_CPB_SIZE)
+#define        VIDEO_CPB_DIR_SIZE     (VIDEO_CPB_SIZE/0x100)
+#define        VIDEO_CPB_DIR_REGION   (VIDEO_CPB_REGION - VIDEO_CPB_DIR_SIZE)
+
+#ifdef CONFIG_VIDEO_ENC_NUM
+#define        VIDEO_ENC_NUM              CONFIG_VIDEO_ENC_NUM
+#else
+#define        VIDEO_ENC_NUM              0
+#endif
+
+#ifdef CONFIG_VIDEO_ENC_CPB_SIZE
+#define        VIDEO_ENC_CPB_SIZE     (CONFIG_VIDEO_ENC_CPB_SIZE * VIDEO_ENC_NUM)
+#else
+#define        VIDEO_ENC_CPB_SIZE     (0x400000 * VIDEO_ENC_NUM)
+#endif
+
+#define        VIDEO_ENC_CPB_REGION   (VIDEO_CPB_DIR_REGION - VIDEO_ENC_CPB_SIZE)
+#define        VIDEO_ENC_DIR_SIZE     (VIDEO_ENC_CPB_SIZE/0x100)
+#define        VIDEO_ENC_DIR_REGION   (VIDEO_ENC_CPB_REGION - VIDEO_ENC_DIR_SIZE)
+
+#define        VIDEO_USER_DATA_SIZE   (0x80000 * VIDEO_NUM)
+#define        VIDEO_USER_DATA_REGION (VIDEO_ENC_DIR_REGION - VIDEO_USER_DATA_SIZE)
+
+#endif
+
+#ifdef CONFIG_AUDIO_NUM
+#define        AUDIO_NUM		      CONFIG_AUDIO_NUM
+#else
+#define        AUDIO_NUM		      0
+#endif
+
+#ifdef CONFIG_AUDIO_CAB_SIZE
+#define        AUDIO_CAB_SIZE         (CONFIG_AUDIO_CAB_SIZE * AUDIO_NUM)
+#else
+#define        AUDIO_CAB_SIZE         (0x200000 * AUDIO_NUM)
+#endif
+
+#define        AUDIO_CAB_REGION	      (VIDEO_USER_DATA_REGION - AUDIO_CAB_SIZE)
+#define        AUDIO_CAB_EXT	      (AUDIO_CAB_REGION - AUDIO_ALIGN_GAP)
+#define        AUDIO_PTS_SIZE	      (AUDIO_PTS_FIXED_SIZE * (AUDIO_NUM))
+#define        AUDIO_PTS_REGION	      (AUDIO_CAB_EXT - AUDIO_PTS_SIZE)
+#define        AUDIO_PTS_EXT	      (AUDIO_PTS_REGION - AUDIO_ALIGN_GAP)
+
+#ifdef CONFIG_AUDIO_ENC_NUM
+#define 	   AUDIO_ENC_NUM          CONFIG_AUDIO_ENC_NUM
+#else
+#define        AUDIO_ENC_NUM          0
+#endif
+
+#ifdef CONFIG_AUDIO_ENC_CAB_SIZE
+#define        AUDIO_ENC_CAB_SIZE     (CONFIG_AUDIO_ENC_CAB_SIZE * AUDIO_ENC_NUM)
+#else
+#define        AUDIO_ENC_CAB_SIZE     (0x200000 * AUDIO_ENC_NUM)
+#endif
+
+#define        AUDIO_ENC_CAB_REGION	  (AUDIO_PTS_EXT - AUDIO_ENC_CAB_SIZE)
+#define        AUDIO_ENC_CAB_EXT	  (AUDIO_ENC_CAB_REGION - 0x100)
+#define        AUDIO_ENC_PTS_SIZE	  (0x6000 * (AUDIO_ENC_NUM))
+#define        AUDIO_ENC_PTS_REGION	  (AUDIO_ENC_CAB_EXT - AUDIO_ENC_PTS_SIZE)
+#define        AUDIO_ENC_PTS_EXT	  (AUDIO_ENC_PTS_REGION - 0x100)
+
+#ifdef CONFIG_AUDIO_AAB
+#define        AUDIO_AAB_SIZE	      (0x500000 * AUDIO_NUM)
+#define        AUDIO_AAB_PTS_SIZE     (0xa0000 * AUDIO_NUM)
+#define        AUDIO_AAB_REGION       (AUDIO_ENC_PTS_EXT - AUDIO_AAB_SIZE)
+#define        AUDIO_AAB_PTS_REGION   (AUDIO_AAB_REGION - AUDIO_AAB_PTS_SIZE)
+#else
+#define        AUDIO_AAB_SIZE	      (0x0)
+#define        AUDIO_AAB_PTS_SIZE     (0x0)
+#define        AUDIO_AAB_REGION       (AUDIO_ENC_PTS_EXT - AUDIO_AAB_SIZE)
+#define        AUDIO_AAB_PTS_REGION   (AUDIO_AAB_REGION - AUDIO_AAB_PTS_SIZE)
+#endif
+
+#ifdef CONFIG_CELESTIAL_FJ_RX
+#define        AUDIO_MIX_SIZE	(0x0)
+#else
+#define        AUDIO_MIX_SIZE	(0x40000)
+#endif
+#define        AUDIO_MIX_REGION	(AUDIO_AAB_PTS_REGION - AUDIO_MIX_SIZE)
+
+//disabled load firmware at TZ side
+#if 0// def CONFIG_SW_SUPPORT
+#define        AUDIO_STUFF_SIZE	(0x10000)
+#else
+#define        AUDIO_STUFF_SIZE       (0x280000)
+#endif
+#define        AUDIO_STUFF_REGION     (AUDIO_MIX_REGION - AUDIO_STUFF_SIZE)
+
+#ifdef CONFIG_AUDIO_FW_DUMP_DEBUG
+#define	     AUDIO_DEBUG_SIZE	(0x500000)
+#else
+#define        AUDIO_DEBUG_SIZE (0)
+#endif
+#define	     AUDIO_DEBUG_REGION    (AUDIO_STUFF_REGION - AUDIO_DEBUG_SIZE)
+
+#ifdef CONFIG_CELESTIAL_XPORT
+#define        XPORT_SIZE             (0xd50000)
+#else
+#define        XPORT_SIZE             (0)
+#endif
+#define        XPORT_REGION        (AUDIO_DEBUG_REGION-XPORT_SIZE)
+
+#if (defined CONFIG_SW_SUPPORT) && (defined SW_FEED_VIDEO)
+#define TZ_BOUNDARY (0x8000000)
+#else
+#define TZ_BOUNDARY (0x2000000)
+#endif
+
+#ifdef CONFIG_ANDROID_PMEM
+  #define PMEM_SIZE SZ_32M
+#else
+  #define PMEM_SIZE 0
+#endif
+
+#define PMEM_REGION (XPORT_REGION - PMEM_SIZE)
+
+#ifdef CONFIG_SW_SUPPORT
+#if (PMEM_REGION < TZ_BOUNDARY)
+#error "ERROR: Kernel memory overlap TZ reserved memory!"
+#endif
+#endif
+
+#endif
+
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/arch/arm/mach-celestial/include/mach/nand.h linux-linaro-3.4-2012.05-1_cavium/arch/arm/mach-celestial/include/mach/nand.h
--- linux-linaro-3.4-2012.05-1_original/arch/arm/mach-celestial/include/mach/nand.h	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/arch/arm/mach-celestial/include/mach/nand.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,38 @@
+/*
+ * mach-celestialsemi/include/mach/nand.h
+ */
+
+#ifndef __ARCH_ARM_CNC_NAND_H
+#define __ARCH_ARM_CNC_NAND_H
+
+#define CNC1900_SMC_CS0 (CNC1900_SMC + 0x00)
+#define CNC1900_SMC_CS1 (CNC1900_SMC + 0x0C)
+#define CNC1900_SMC_CS2 (CNC1900_SMC + 0x18)
+#define CNC1900_SMC_CS3 (CNC1900_SMC + 0x24)
+
+#define CEN_CFG_0 0x00
+#define CEN_CFG_1 0x04
+#define CEN_CFG_2 0x08
+
+#define STATUS 0x30
+#define MODE 0x38
+#define ECC_CODE 0x40
+#define ECC_COUNT 0x44
+#define ECC_ADDRESS  0x48
+
+#define MASK_ALE (1 << 22) 
+#define MASK_CLE (1 << 21)
+
+#define FORCE_CE_LOW 0x200
+#define STATUS_READY 0x001
+
+struct plat_cncnand_port {
+	phys_addr_t membase;
+	void __iomem *mapbase;
+	void __iomem *reg_port;
+	void __iomem *reg_base;
+	unsigned int cle;
+	unsigned int ale;
+};
+
+#endif	/* __ARCH_ARM_CNC_NAND_H */
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/arch/arm/mach-celestial/include/mach/pinmux.h linux-linaro-3.4-2012.05-1_cavium/arch/arm/mach-celestial/include/mach/pinmux.h
--- linux-linaro-3.4-2012.05-1_original/arch/arm/mach-celestial/include/mach/pinmux.h	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/arch/arm/mach-celestial/include/mach/pinmux.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,182 @@
+/*
+ *  arch/arm/mach-celestial/include/mach/mux.h
+ *  Celestial Platform IO address definitions
+ *   
+ * This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+
+#ifndef __MACH_MUX_H
+#define __MACH_MUX_H
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/vmalloc.h>
+
+#define RC_CTL_L                (0x008)    /*RC Control Register*/
+#define RC_CTL_H                (0x00a) //
+
+enum pinmux_1{
+	I2C0_EN = 0,
+	I2C1_EN,
+	VGA_OUT_EN,
+	DISP1_OUT_EN,
+};
+
+enum pinmux_disp{
+	TVE0_YPbPr = 1 ,
+	OUTIF0_RGB,
+	TVE1_CVBS_S_video,
+	TVE1_YPbPr,
+	OUTIF1_RGB,
+};
+
+typedef enum _GPIO_ID_{
+	_gpio_0     =0,
+	_gpio_1     =1,
+	_gpio_2     =2,
+	_gpio_3     =3,
+	_gpio_4     =4,
+	_gpio_5     =5,
+	_gpio_6     =6,
+	_gpio_7     =7,
+	_gpio_8     =8,
+	_gpio_9     =9,
+	_gpio_10    =10,
+	_gpio_11    =11,
+	_gpio_12    =12,
+	_gpio_13    =13,
+	_gpio_14    =14,
+	_gpio_15    =15,
+	_gpio_16    =16,
+	_gpio_17    =17,
+	_gpio_18    =18,
+	_gpio_19    =19,
+	_gpio_20    =20,
+	_gpio_21    =21,
+	_gpio_22    =22,
+	_gpio_23    =23,
+	_gpio_24    =24,
+	_gpio_25    =25,
+	_gpio_26    =26,
+	_gpio_27    =27,
+	_gpio_28    =28,
+	_gpio_29    =29,
+	_gpio_30    =30,
+	_gpio_31    =31,
+	_gpio_32    =32,
+	_gpio_33    =33,
+	_gpio_34    =34,
+	_gpio_35    =35,
+	_gpio_36    =36,
+	_gpio_37    =37,
+	_gpio_38    =38,
+	_gpio_39    =39,
+	_gpio_40    =40,
+	_gpio_41    =41,
+	_gpio_42    =42,
+	_gpio_43    =43,
+	_gpio_44    =44,
+	_gpio_45    =45,
+	_gpio_46    =46,
+	_gpio_47    =47,
+	_gpio_48    =48,
+	_gpio_49    =49,
+	_gpio_50    =50,
+	_gpio_51    =51,
+	_gpio_52    =52,
+	_gpio_53    =53,
+	_gpio_54    =54,
+	_gpio_55    =55,
+	_gpio_56    =56,
+	_gpio_57    =57,
+	_gpio_58    =58,
+	_gpio_59    =59,
+	_gpio_60    =60,
+	_gpio_61    =61,
+	_gpio_62    =62,
+	_gpio_63    =63,
+}GPIO_ID;
+
+//I2C
+typedef enum _I2C_ID_
+{
+	_i2c_0      =0,
+	_i2c_1      =1,
+}I2C_ID;
+
+int PinMuxEnableI2C(I2C_ID I2C);
+
+//IR Repeater
+typedef enum _IR_REPEATER_ID_
+{
+	_IR0      =0,
+	_IR1      =1,
+} IR_REPEATER_ID;
+
+//UART
+typedef enum _UART_ID_
+{
+	_uart_1		=1,
+	_uart_2		=2,
+	_uart_audio	=3,
+	_uart_video	=4,
+}UART_ID;
+
+//Analog Video
+typedef enum _DAC0_MODE_
+{
+	_dac0_rgb0 =0,
+	_dac0_rgb1 =1,
+	_dac0_tve0_ypbpr =2,
+	_dac0_tve0_cvbs_svideo =3,
+	_dac0_tve1_ypbpr =4,
+	_dac0_tve1_cvbs_svideo  =5,
+}DAC0_MODE;
+
+typedef enum _DAC1_MODE_
+{
+	_dac1_rgb1 = 0,
+	_dac1_tve1_ypbpr =1,
+	_dac1_tve1_cvbs_svideo  =2,
+}DAC1_MODE;
+
+//Xport
+typedef enum _XPORT_MODE_
+{
+	_xport_serial_mode	    =0,
+	_xport_paralell_mode    =1,
+} XPORT_MODE;
+
+enum pinmux_class{
+	PINMUX_I2C = 0,
+	PINMUX_UART,    // UART1/Audio_uart/Video_uart/UART2/IRDA,GPIO[6],GPIO[3],UART0,GPIO[19:18]
+	PINMUX_DISP,    // 3'b11x:OUTIF1 RGB,TVE1 YPbPr,TVE1 CVBS+S-video,OUTIF0 RGB,TVE0 YPbPr
+	PINMUX_SMI,     // GPIO[31:27] ,SMI
+	PINMUX_TS,      // xport 1
+	PINMUX_DVIO,    // 1800H GPIO[40:32],digital video input / 1800L GPIO[63:40],digital video input
+	PINMUX_SDIO,    // SDIO / GPIO [39:32]
+};
+
+/* function declaration ------------------------------------- */
+int pinmux_scan_status_bit(int  mode);
+int pinmux_set_status_bit(int  mode, int bit, int set);
+int pinmux_get_status_bit(int  mode,int bit);
+int pinmux_update_fpc_status(void);
+int pinmux_update_rc_status(void);
+int pinmux_set_xportmode(XPORT_MODE Mode);
+int pinmux_enable_uart(UART_ID UART);
+int pinmux_enable_i2c(I2C_ID I2C);
+int pinmux_enable_ir_repeater(IR_REPEATER_ID IR);
+int pinmux_enable_irda(void);
+int pinmux_enable_spi(void);
+int pinmux_enable_smi(void);
+int pinmux_enable_vib(void);
+int pinmux_enable_ttlout(void);
+int pinmux_set_dac0mode(DAC0_MODE Mode);
+int pinmux_set_dac1mode(DAC1_MODE Mode);
+
+#endif 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/arch/arm/mach-celestial/include/mach/smc.h linux-linaro-3.4-2012.05-1_cavium/arch/arm/mach-celestial/include/mach/smc.h
--- linux-linaro-3.4-2012.05-1_original/arch/arm/mach-celestial/include/mach/smc.h	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/arch/arm/mach-celestial/include/mach/smc.h	2014-08-25 16:45:04.079934000 +0800
@@ -0,0 +1,46 @@
+#ifndef __SMC_H__
+#define __SMC_H__
+
+#if defined(__GNUC__) && \
+    defined(__GNUC_MINOR__) && \
+defined(__GNUC_PATCHLEVEL__) && \
+((__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)) \
+> 40700
+#define USE_ARCH_EXTENSION_SEC 1
+#else
+#define USE_ARCH_EXTENSION_SEC 0
+#endif
+
+
+#define SMC_CMD_L2X0CTRL	(-21)
+#define SMC_CMD_L2X0SETUP1	(-22)
+#define SMC_CMD_L2X0SETUP2	(-23)
+
+#define SMC_CMD_VIDEO_WIRTE_REG	(-110)
+#define SMC_CMD_VIDEO_READ_REG  (-111)
+#define SMC_CMD_AUDIO_WIRTE_REG	(-112)
+#define SMC_CMD_AUDIO_READ_REG  (-113)
+#define SMC_CMD_VIDEO_WIRTE_IRQ_REG	(-114)
+#define SMC_CMD_VIDEO_READ_IRQ_REG  (-115)
+
+#ifndef __ASSEMBLY__
+static inline u32 sw_smc(u32 cmd, u32 arg1, u32 arg2, u32 arg3)
+{
+	register u32 reg0 __asm__("r0") = cmd;
+	register u32 reg1 __asm__("r1") = arg1;
+	register u32 reg2 __asm__("r2") = arg2;
+	register u32 reg3 __asm__("r3") = arg3;
+
+	__asm__ volatile (
+#ifdef USE_ARCH_EXTENSION_SEC
+		".arch_extension sec\n\t"
+#endif
+		"smc	0\n"
+		: "+r"(reg0), "+r"(reg1), "+r"(reg2), "+r"(reg3)
+	);
+
+	return reg0;
+}
+#endif
+
+#endif //__SMC_H__
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/arch/arm/mach-celestial/include/mach/timex.h linux-linaro-3.4-2012.05-1_cavium/arch/arm/mach-celestial/include/mach/timex.h
--- linux-linaro-3.4-2012.05-1_original/arch/arm/mach-celestial/include/mach/timex.h	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/arch/arm/mach-celestial/include/mach/timex.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,27 @@
+/*
+ * arch/arm/mach-celestialsemi/include/mach/timex.h
+ *
+ *  Copyright (C) 2003 Xiaodong Fan
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __ASM_ARCH_TIMEX_H
+#define __ASM_ARCH_TIMEX_H
+
+#define PCLK_FREQ 810000000
+#define CLOCK_TICK_RATE (100 * HZ)
+
+#endif
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/arch/arm/mach-celestial/include/mach/uncompress.h linux-linaro-3.4-2012.05-1_cavium/arch/arm/mach-celestial/include/mach/uncompress.h
--- linux-linaro-3.4-2012.05-1_original/arch/arm/mach-celestial/include/mach/uncompress.h	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/arch/arm/mach-celestial/include/mach/uncompress.h	2014-11-19 00:25:03.684040000 +0800
@@ -0,0 +1,58 @@
+/*
+ *  arch/arm/mach-celestial/include/mach/uncompress.h
+ *
+ *  Copyright (C) 2010 Celestial
+ *   xiaodong.fan@celestialsemi.com
+  *  Copyright (C) 2012 Cavium
+ *   xiaodong.fan@cavium.com
+*  
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include <linux/types.h>
+#include <linux/serial_reg.h>
+#include <mach/hardware.h>
+
+/*
+ * This does not append a newline
+ */
+
+#ifndef CONFIG_UNCOMPRESS_QUIET
+static volatile u32 *uart = (u32 *)CNC1900_UART0;
+#endif
+
+static inline void putc(int c)
+{
+#ifndef CONFIG_UNCOMPRESS_QUIET
+	while (!(uart[UART_LSR] & UART_LSR_THRE))
+		barrier();
+	uart[UART_TX] = c;
+#endif
+}
+
+static inline void flush(void)
+{
+#ifndef CONFIG_UNCOMPRESS_QUIET
+	while (!(uart[UART_LSR] & UART_LSR_THRE))
+	barrier();
+#endif
+}
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_setup()
+#define arch_decomp_wdog()
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/arch/arm/mach-celestial/include/mach/usb.h linux-linaro-3.4-2012.05-1_cavium/arch/arm/mach-celestial/include/mach/usb.h
--- linux-linaro-3.4-2012.05-1_original/arch/arm/mach-celestial/include/mach/usb.h	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/arch/arm/mach-celestial/include/mach/usb.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,16 @@
+/*
+ *  arch/arm/mach-celestial/include/mach/usb.h
+ *
+ *
+ *  Copyright (C) 2012 Cavium
+ */
+
+#ifndef __ASM_ARCH_USB_H
+#define __ASM_ARCH_USB_H
+
+#include <linux/usb/g_hid.h>
+
+extern int platform_add_usb_hid_device(int device_type, struct hidg_func_descriptor *func_descriptor);
+extern int platform_remove_usb_hid_device(int device_type);
+
+#endif
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/arch/arm/mach-celestial/Kconfig linux-linaro-3.4-2012.05-1_cavium/arch/arm/mach-celestial/Kconfig
--- linux-linaro-3.4-2012.05-1_original/arch/arm/mach-celestial/Kconfig	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/arch/arm/mach-celestial/Kconfig	2014-11-19 00:25:03.684040000 +0800
@@ -0,0 +1,58 @@
+menu "Cavium Celestial platform type"
+choice
+	prompt "Celestial platform Series SoC Version"
+	depends on ARCH_CELESTIAL
+	default MACH_CELESTIAL_CNC1900
+
+config MACH_CELESTIAL_CNC1900
+	bool "Cavium Celestial CNC1900"
+	help
+	  Include support for the Cavium Celestial CNC1900 platform.
+
+endchoice
+
+config PUREVU
+	bool "Support for PUREVU"
+	depends on MACH_CELESTIAL_CNC1900
+	default y
+	help
+	  Enable support for PUREVU.
+config UNCOMPRESS_QUIET
+	bool "Quiet when uncompress the kernel"
+	depends on MACH_CELESTIAL_CNC1900
+	default n
+	help
+	  Not output to UART0 when uncompress from zImage
+
+choice
+	prompt "CNC1900 Series Boards"
+	depends on MACH_CELESTIAL_CNC1900
+	default CELESTIAL_HDK
+
+config CELESTIAL_EVB
+	bool "Config for Celestial EVB board"
+        help
+          If select this option, will use memory defines for EVB board
+
+config CELESTIAL_HDK
+	bool "Config for Celestial HDK board"
+        help
+          If select this option, will use memory defines for HDK board
+
+config CELESTIAL_FJ_TX
+	bool "Config for Celestial FJ TX board"
+        help
+          If select this option, will use memory defines for FJ_TX board
+
+config CELESTIAL_FJ_RX
+	bool "Config for Celestial FJ RX board"
+        help
+          If select this option, will use memory defines for FJ_RX board
+
+config CELESTIAL_OTT_EMMC
+	bool "Config for Celestial OTT_EMMC board"
+        help
+          If select this option, will use memory defines for OTT_EMMC board
+endchoice
+
+endmenu
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/arch/arm/mach-celestial/Makefile linux-linaro-3.4-2012.05-1_cavium/arch/arm/mach-celestial/Makefile
--- linux-linaro-3.4-2012.05-1_original/arch/arm/mach-celestial/Makefile	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/arch/arm/mach-celestial/Makefile	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,7 @@
+#
+# Makefile for the linux kernel.
+#
+
+obj-$(CONFIG_ARCH_CELESTIAL) += cnc19xx.o clock.o timer.o cnc1900_power_clk.o pinmux.o usb.o pmem.o nap.o cnc1900_cpufreq_plat.o cnc19xx_mem_info.o
+obj-$(CONFIG_HOTPLUG_CPU)    += hotplug.o
+obj-$(CONFIG_SMP)            += platsmp.o
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/arch/arm/mach-celestial/Makefile.boot linux-linaro-3.4-2012.05-1_cavium/arch/arm/mach-celestial/Makefile.boot
--- linux-linaro-3.4-2012.05-1_original/arch/arm/mach-celestial/Makefile.boot	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/arch/arm/mach-celestial/Makefile.boot	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,4 @@
+   zreladdr-y	:= 0x00008000
+params_phys-y	:= 0x00000100
+initrd_phys-y	:= 0x00800000
+
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/arch/arm/mach-celestial/nap.S linux-linaro-3.4-2012.05-1_cavium/arch/arm/mach-celestial/nap.S
--- linux-linaro-3.4-2012.05-1_original/arch/arm/mach-celestial/nap.S	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/arch/arm/mach-celestial/nap.S	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,534 @@
+    .global naptime
+    .global INSN_END
+
+    /* For debugging purposes. Normally, we enable everything. */
+    .set    DO_AUDIO, 0
+    .set    DO_DDR3, 0
+    .set    DO_FPC, 0
+    .set    DO_GPIO, 1
+    .set    DO_UART, 0
+    .set    DO_USB_EHCI, 0
+    .set    DO_USB_OHCI, 0
+    .set    DO_VIDEO, 0
+    .set    DO_WDT, 0
+    .set    DO_CPUTIMER, 0
+
+    .set    GPIO_PB_BITNO, 8        /* Wake-up push button is GPIO bit #8. */
+    .set    GPIO_A_DATA, 32         /* Offset of the GPIO port A data register. */
+    .set    GPIO_A_INTR_EN, 40      /*    ...and the GPIO interrupt enable register */
+    .set    GPIO_A_INTR_POL, 44     /*    ...and the GPIO interrupt polarity register */
+    .set    GPIO_A_DDR, 36          /*    ... and the data direction register. */
+
+    .set    TIMER_INTR_EN, 20       /* Offset of the AHB timer 0 interrupt enable register. */
+    .set    TIMER_INTR_ENABLE_MASK, 1       /* Mask to enable/disable timer interrupt in INTR_EN. */
+    .set    TIMER_INTR_CLR, 24      /*     ...and the interrupt clear register. */
+    .set    TIMER_ENR, 28           /*     ...and the timer enable register. */
+    .set    TIMER_ENABLE_DISABLE_MASK, 1    /* Mask to enable/disable timer in ENR. */
+    .set    TIMER_INTR_STA, 40      /*     ...and the timer interrupt status register. */
+
+    .set    UART_LCR, 12            /* 16550A/8250 console UART line control register offset. */
+    .set    UART_LCR_DL, 7          /* LCR divisor latch enable bit */
+    .set    UART_IER, 4             /*    ...and the interrupt enable register */
+    .set    UART_FCR, 8             /*    ...and the FIFO control register (write only!) */
+
+    .set    DDR_LP_CTRL, 0x40           /* Offset of the DDR low power control register. */
+    .set    SELF_REFRESH_SW_CTRL, 1     /* Bit mask of auto self-refresh SW control enable. */
+    .set    SELF_REFRESH_ENTER, 2       /* Bit mask of the DDR auto self-refresh enter bit. */
+    .set    SELF_REFRESH_EXIT, 4        /* Bit mask of the DDR auto self-refresh exit bit. */
+    .set    SELF_REFRESH_ACK_CLEAR, 8   /* Bit mask of the auto self-refresh ACK clear bit. */
+    .set    SELF_REFRESH_ACK, 16        /* Bit mask of the auto self-refresh entry/exit ACK bit. */
+
+    /* This one is a mask, not a shift. */
+    .set    ID_SCS_CKEN_DDR_MASK, 0x2
+
+    .set    CPSR_FIQ_MASK, 0x40     /* Bit mask for the FIQ bit in the ARM CPSR */
+    .set    CPSR_IRQ_MASK, 0x80     /*    ...and for the IRQ bit */
+
+    .set    WDT_DISABLE, 0x34       /* Offset of the watchdog disable register (write only). */
+    .set    WDT_CONTROL, 0x28       /* Offset of the watchdog (IRQ 30) control register. */
+    .set    WDT_CTRL_ENABLE, 1      /* Bit 0 is the enable/disable bit of the WD control reg. */
+    .set    CPU_TIMER_CONTROL, 8    /* Offset of CPU timer (IRQ 29) control register */
+    .set    CPU_TIMER_INTEN, 5      /* Bits in the timer control that enable interrupts. */
+    .set    CPU_TIMER_INTST, 0x0c   /* Offset of the CPU timer interrupt status register. */
+    .set    WDT_INTR_STAT, 0x2c     /* Offset of the Watchdog timer interrupt status register. */
+    
+    .set    FPC_INTM, 4             /* Offset of front panel control interrupt mask register. */
+
+    .set    USBSTS, 4               /* Offset of USB EHCI status register */
+    .set    USBINTR, 8              /* Offset of USB EHCI interrupt enable register */
+
+    .set    OHCI_INTRSTAT, 12       /* USB OHCI interrupt status register. */
+    .set    OHCI_INTRENAB, 16       /* USB OHCI interrupt enable register. */
+    .set    OHCI_INTRDISAB, 20      /* USB OHCI interrupt disable register. */
+    .set    OHCI_MIE_SHIFT, 31      /* Master interrupt bit in the OHCI interrupt enable/disable register. */
+
+    .set    COPSW_INTEN, 192         /* Video interrupt enable offset */
+
+    .set    AUD_INTMASK, 0x208          /* Offset of DSP_INT_MASK. */
+    .set    AUD_INTMASK_BITS, 31        /* Bits 0-4 of DSP_INT_MASK are maskable. */
+
+    .set    GPIO_INTSAVE, 4         /* Offset in the stack frame holding the old GPIO interrupt mask. */
+    .set    FPC_INTSAVE, 8          /* Offset in the stack frame holding the old front panel control interrupt mask. */
+    .set    EHCI_INTSAVE, 12        /* Offset in the stack frame holding the old USB EHCI interrupt mask. */
+    .set    VIDEO_INTSAVE, 16       /* Offset in the stack frame holding the old video interrupt mask. */
+    .set    AUDIO_INTSAVE, 20       /* Offset in the stack frame holding the old audio interrupt mask. */
+
+
+    .set    PARAM1_SAVE, 24
+    .set    PARAM2_SAVE, 28
+
+/* ARM register equivalents, designed to make the code more readable. */
+
+timerbase   .req    r0
+idscsclken  .req    r1
+uartbase    .req    r6
+
+naptime:
+
+    /* So we're here in the line buffer now. Interrupts are disabled globally,
+       but not from the peripherals. We need to do the latter so that no
+       interrupts will happen that wake us up (except for the push button)
+       The 1176JZF-S TRM states that even if an interrupt occurs that is masked,
+       the CPU still will wake up from the WFI state. Therefore, we must still
+       disable interrupts at the source.
+
+       At this point, the MMU is on, but we are running out of the
+       line buffer. I don't want to turn off the MMU because I don't
+       see any benefit to doing that, and I would need to map the line
+       buffer to a virtual address of 0xb1000000 prior to jumping to
+       the line buffer and turning it off. Otherwise, once I've disabled it,
+       pc will hold an invalid address. */
+
+    /* Set up stack frame */
+    stmfd   sp!, {fp, lr}
+    add     fp, sp, #4
+    sub     sp, sp, #64
+
+    ldr     uartbase, UART_BASE_VA
+
+    /* Disable all interrupts (both IRQ and FIQ) */
+    dsb
+    mrs    r4, cpsr
+    orr    r4, r4, #(CPSR_IRQ_MASK|CPSR_FIQ_MASK)
+    msr    cpsr, r4
+
+    /* Pre-load a shiftable 1-bit. */
+    mov     r8, #1
+
+    /* R0 contains the irq mask list length, R1 points to the list. They are
+       uint32_t and uint32_t *, respectively. R2 is the GPIO wakeup list. */
+
+    str     r0, [sp, #PARAM1_SAVE]  /* save list length */
+    str     r1, [sp, #PARAM2_SAVE]  /* save list address. */
+    cmp     r0, #0          /* See how many masks remain. */
+    beq     maskdone1
+nextmask1:
+    ldr     r7, GIC_DIST_CLREN_VA
+    ldr     r4, [r1]        /* r4 := the next IRQ #. */
+    mov     r4, r4, lsr #5  /* r4 := word offset from base in GIC */
+    mov     r4, r4, lsl #2  /* r4 := byte offset from base in GIC (of start of word) */
+    add     r7, r7, r4      /* r7 := the address of the clear enable reg in the GIC */
+    ldr     r4, [r1], #4    /* r4 := the next IRQ #, increment to next address */
+    and     r4, r4, #31     /* bit # is now in r4. */
+    mov     r5, r8, lsl r4  /* shift a 1 bit r4 to the left */
+    str     r5, [r7]        /* change that bit in the GIC clear enable register. */
+    dmb                     /* make sure mem op completes before doing next. */
+    subs    r0, r0, #1
+    bne     nextmask1
+maskdone1:
+
+    ldr     idscsclken, ID_SCS_CLKEN_VA
+    ldr     timerbase, WDT_BASE_VA
+
+    .if     DO_WDT != 0
+    /* Rather than switch the watchdog back to timer mode, simply stop it from counting. */
+    ldr     r4, [timerbase, #WDT_CONTROL]
+    bic     r4, r4, #WDT_CTRL_ENABLE
+    str     r4, [timerbase, #WDT_CONTROL]
+    dmb
+    .endif
+
+    .if     DO_CPUTIMER != 0
+    ldr     r4, [timerbase, #CPU_TIMER_CONTROL]
+    bic     r4, r4, #CPU_TIMER_INTEN
+    str     r4, [timerbase, #CPU_TIMER_CONTROL]
+    dmb
+    ldr     r4, [timerbase, #CPU_TIMER_INTST]
+    bic     r4, r4, #1                          /* Clear out any pending timer interrupt. */
+    str     r4, [timerbase, #CPU_TIMER_INTST]
+    dmb
+    .endif
+
+    .if     DO_GPIO != 0
+    ldr     r5, GPIO_BASE_VA
+    ldr     r4, [r5, #GPIO_A_INTR_EN]       /* Save old GPIO interrupt mask */
+    str     r4, [sp, #GPIO_INTSAVE]
+    str     r2, [r5, #GPIO_A_INTR_EN]       /* Store the one from /sys/power/gpio_wakeup */
+    .endif
+
+    .if     DO_FPC != 0
+    /* Disable front panel control interrupts. */
+    ldr     r5, FPC_BASE_VA
+    ldr     r4, [r5, #FPC_INTM]
+    str     r4, [sp, #FPC_INTSAVE]                    /* Save old mask. */
+    dmb
+    mov     r4, #0
+    str     r4, [r5, #FPC_INTM]
+    dmb
+    .endif
+
+    .if     DO_UART != 0
+    /* Turn off serial port interrupts on UART 0 */
+    ldr     r4, [uartbase, #UART_LCR]
+    bic     r4, r4, r8, lsl #UART_LCR_DL  /* Set LCR bit 7 to 0 */
+    str     r4, [uartbase, #UART_LCR]
+    dmb
+
+    ldr     r4, [uartbase, #UART_IER]
+    and     r9, r4, #0xf        /* save bits in r9 for restore */
+    bic     r4, r4, #0xf        /* disable interrupts of interest. */
+    str     r4, [uartbase, #UART_IER]
+    dmb
+    .endif
+
+    .if     DO_USB_EHCI != 0
+    /* Now disable USB EHCI interrupts. */
+    ldr     r7, USB_EHCI_VA
+    ldr     r4, [r7, #USBSTS]   /* Read USB status in prep for intr clear. */
+    and     r4, r4, #63         /* Mask all but possible interrupt sources. */
+    str     r4, [r7, #USBSTS]   /* Clear the condition by writing a 1 bit. */
+    dmb
+
+    ldr     r4, [r7, #USBINTR]  /* Read interrupt mask register. */
+    and     r5, r4, #63         /* Set reserved bits to 0. */
+    str     r5, [sp, #EHCI_INTSAVE]       /* Save old interrupt enable bits. */
+    dmb
+    eor     r4, r4, r4          /* Clear all bits and disable interrupts. */
+    str     r4, [r7, #USBINTR]
+    dmb
+    .endif
+
+    .if     DO_USB_OHCI != 0
+    /* Disable USB OHCI interrupts. These come from 1.0a of the OHCI spec. */
+    ldr     r7, USB_OHCI_VA
+    mov     r4, r8, lsl #OHCI_MIE_SHIFT /* Disable interrupts via master intr bit. */
+    str     r4, [r7, #OHCI_INTRDISAB]
+    dmb
+
+    ldr     r4, [r7, #OHCI_INTRSTAT]   /* Read USB status in prep for intr clear. */
+    ldr     r5, OHCI_STAT_CLEAR
+    bic     r4, r4, r5          /* Mask all but possible interrupt sources. */
+    str     r4, [r7, #USBSTS]   /* Clear the condition by writing a 1 bit. */
+    dmb
+    .endif
+
+    .if     DO_VIDEO != 0
+    /* Disable video interrupt. */
+    ldr     r7, VIDEO_INTR_REGS_VA
+    ldr     r4, [r7, #COPSW_INTEN]      /* Save old interrupt enable bit. */
+    and     r4, r4, r8
+    str     r4, [sp, #VIDEO_INTSAVE]
+    dmb
+    bic     r4, r4, r8
+    str     r4, [r7, #COPSW_INTEN]
+    dmb
+    .endif
+
+    .if     DO_AUDIO != 0
+    /* Disable audio interrupt. */
+    ldr     r7, AUDIO_INTR_REGS_VA
+    ldr     r4, [r7, #AUD_INTMASK]
+    and     r4, r4, #AUD_INTMASK_BITS
+    str     r4, [sp, #AUDIO_INTSAVE]    /* Save old interrupt enable bits. */
+    dmb
+    bic     r4, r4, #AUD_INTMASK_BITS
+    str     r4, [r7, #AUD_INTMASK]
+    dmb
+    .endif
+
+    .if     DO_DDR3 != 0
+    dsb
+/*
+        Desired register access sequence:
+
+        LP_CTRL[1] := 1 to request entry into auto self-refresh.
+        Wait for ack (LP_CTRL[4] == 1)
+        LP_CTRL[3] := 1 to clear ack bit.
+
+        Now in auto self-refresh mode.
+        Turn off DDR clock.
+        Enter WFI state
+
+        LP_CTRL[2] := 1 to request exit from auto self-refresh
+        Wait for ack (LP_CTRL[4] == 1)
+        LP_CTRL[3] := 1 to clear ack bit.
+
+        Truth table (from Samsung DDR3 Device Operations Rev1.21_Sep.10)
+        X = don't care, v = valid
+                        CKE
+                        prev curr  CS*  RAS* CAS* WE* BA
+        SRE             1    0     0    0    0    1   v   cmd 1
+        SRX             0    1     0    1    1    1   v   cmd 7
+                            also   1    v    v    v   X   cmd 8-f
+*/
+    /* Move DDR base address into R7. */
+    ldr     r7, DDR_BASE_VA
+
+    /* Request entry into self-refresh. */
+    mov     r4, #SELF_REFRESH_ENTER
+    str     r4, [r7, #DDR_LP_CTRL]
+    dmb
+
+    /* Wait for ACK. */
+notrdy1:
+    ldr     r4, [r7, #DDR_LP_CTRL]
+    ands    r4, r4, #SELF_REFRESH_ACK
+    beq     notrdy1
+
+    /* Clear ACK. */
+    mov     r4, #SELF_REFRESH_ACK_CLEAR
+    str     r4, [r7, #DDR_LP_CTRL]
+    dsb
+
+    /* Allow time for any remaining DDR access to finish. */
+    mov     r1, r8, lsl #17
+xxx:
+    subs    r1, r1, #1
+    bne     xxx
+
+    /* Turn off DDR clock. */
+    isb
+    ldr     r1, ID_SCS_CLKEN_VA
+    ldr     r4, [r1]
+    bic     r4, #1
+    str     r4, [r1]
+    dsb
+
+    .endif
+
+    /* Wait for interrupt */
+    mov     r4, #0
+    wfi
+    /* Used to be mcr     p15,0,r4,c7,c0,4 */
+
+    .if     DO_DDR3 != 0
+
+    /* Turn on DDR clock. */
+    ldr     r4, [r1]
+    orr     r4, #1
+    str     r4, [r1]
+    dsb
+    isb
+
+    /* Might not be necessary. Wait a bit. */
+    mov     r1, r8, lsl #17
+xxx2:
+    subs    r1, r1, #1
+    bne     xxx2
+
+    /* Request exit from self refresh. */
+    mov     r4, #SELF_REFRESH_EXIT
+    str     r4, [r7, #DDR_LP_CTRL]
+    dmb
+
+    /* Wait for ACK. */
+notrdy2:
+    ldr     r4, [r7, #DDR_LP_CTRL]
+    ands    r4, r4, #SELF_REFRESH_ACK
+    beq     notrdy2
+
+    /* Clear ACK. */
+    mov     r4, #SELF_REFRESH_ACK_CLEAR
+    str     r4, [r7, #DDR_LP_CTRL]
+    dsb
+
+    .endif
+
+    .if     DO_AUDIO != 0
+    /* Re-enable audio interrupt. */
+    ldr     r5, [sp, #AUDIO_INTSAVE]    /* Load old interrupt enable bits. */
+    ldr     r7, AUDIO_INTR_REGS_VA
+    ldr     r4, [r7, #AUD_INTMASK]
+    orr     r4, r4, r5
+    str     r4,  [r7, #AUD_INTMASK]
+    dmb
+    .endif
+
+    .if     DO_VIDEO != 0
+    /* Re-enable video interrupt. */
+    ldr     r4, [sp, #VIDEO_INTSAVE]    /* Load old interrupt enable bit. */
+    ldr     r7, VIDEO_INTR_REGS_VA
+    ldr     r5, [r7, #COPSW_INTEN]
+    orr     r5, r4, r5
+    str     r5, [r7, #COPSW_INTEN]
+    dmb
+    .endif
+
+    .if     DO_USB_OHCI != 0
+    /* Re-enable OHCI interrupt by setting MIE. */
+    mov     r4, r8, lsl #OHCI_MIE_SHIFT
+    ldr     r7, USB_OHCI_VA
+    str     r4, [r7, #OHCI_INTRENAB]
+    dmb
+    .endif
+
+    .if     DO_USB_EHCI != 0
+    /* Re-enable EHCI interrupt. */
+    ldr     r4, [sp, #EHCI_INTSAVE]
+    ldr     r7, USB_EHCI_VA
+    str     r4, [r7, #USBINTR]
+    dmb
+    .endif
+
+    .if     DO_UART != 0
+    /* Re-enable serial port interrupts on UART 0 */
+    ldr     r4, [uartbase, #UART_LCR]
+    bic     r4, r4, r8, lsl #UART_LCR_DL          /* Set LCR bit 7 to 0 */
+    str     r4, [uartbase, #UART_LCR]
+    dmb
+
+    ldr     r4, [uartbase, #UART_IER]
+    orr     r4, r4, r9                  /* Restore saved bits from r9. */
+    str     r4, [uartbase, #UART_IER]   /* Restore IER */
+    dmb
+    .endif
+
+    .if     DO_FPC != 0
+    /* Re-enable front panel control interrupts. */
+    ldr     r4, [sp, #FPC_INTSAVE]      /* Load old interrupt enable bits. */
+    ldr     r7, FPC_BASE_VA
+    str     r4, [r7, #FPC_INTM]
+    dmb
+    .endif
+
+    .if     DO_GPIO != 0
+    ldr     r5, GPIO_BASE_VA
+    ldr     r4, [sp, #GPIO_INTSAVE]         /* Restore old GPIO interrupt mask */
+    str     r4, [r5, #GPIO_A_INTR_EN]
+    .endif
+
+    .if     DO_CPUTIMER != 0
+    ldr     r4, [timerbase, #CPU_TIMER_CONTROL]
+    orr     r4, r4, #CPU_TIMER_INTEN
+    str     r4, [timerbase, #CPU_TIMER_CONTROL]
+    dmb
+    .endif
+
+    .if     DO_WDT != 0
+    /* Re-start the watchdog timer. I'm assuming that the prescale and load
+       values have been preserved since they haven't been touched. */
+    ldr     r4, [timerbase, #WDT_CONTROL]
+    orr     r4, r4, #WDT_CTRL_ENABLE
+    str     r4, [timerbase, #WDT_CONTROL]
+    dmb
+    .endif
+
+    ldr     r0, [sp, #PARAM1_SAVE]  /* recall list length */
+    ldr     r1, [sp, #PARAM2_SAVE]  /* recall list address. */
+    cmp     r0, #0          /* See how many masks remain. */
+    beq     maskdone2
+nextmask2:
+    ldr     r7, GIC_DIST_SETEN_VA
+    ldr     r4, [r1]        /* r4 := the next IRQ #. */
+    mov     r4, r4, lsr #5  /* r4 := word offset from base in GIC */
+    mov     r4, r4, lsl #2  /* r4 := byte offset from base in GIC (of start of word) */
+    add     r7, r7, r4      /* r7 := the address of the clear enable reg in the GIC */
+    ldr     r4, [r1], #4    /* r4 := the next IRQ #, increment to next address */
+    and     r4, r4, #31     /* bit # is now in r4. */
+    mov     r5, r8, lsl r4  /* shift a 1 bit r4 to the left */
+    str     r5, [r7]        /* change that bit in the GIC clear enable register. */
+    dmb                     /* make sure mem op completes before doing next. */
+    subs    r0, r0, #1
+    bne     nextmask2
+maskdone2:
+
+    /* Re-enable interrupts globally. */
+    mrs    r4, cpsr
+    bic    r4, r4, #(CPSR_IRQ_MASK|CPSR_FIQ_MASK)
+    msr    cpsr, r4
+
+    mov     r0, #0
+    sub     sp, fp, #4
+    ldmfd   sp!, {fp, pc} 
+
+
+
+
+
+
+/* These are the CNC1900 definitions. */
+
+GIC_DIST_SETEN_VA:
+    .word   0xf8021100
+
+GIC_DIST_CLREN_VA:
+    .word   0xf8021180
+
+/* Watchdog timer. */
+WDT_BASE_VA:
+    .word   0xf8020600
+
+GIC_BASE_VA:
+    .word   0xf8021d00
+
+/* Front panel control virtual address. */
+FPC_BASE_VA:
+    .word   0xf8172000
+
+/* Virtual address of GPIO port A registers. */
+GPIO_BASE_VA:
+    .word   0xf8260000
+
+/* Virtual address of the console UART. */
+UART_BASE_VA:
+    .word   0xf81f1000
+
+/* USB EHCI virtual address */
+USB_EHCI_VA:
+    .word   0xf8200000
+
+/* USB OHCI virtual address */
+USB_OHCI_VA:
+    .word   0xf8210000
+
+/* Use the COPSWA */
+VIDEO_INTR_REGS_VA:
+    .word   0xfcd10000
+
+IO_REGS_BASE_VA:
+    .word   0xf8100000
+
+IO_MEDIA_PROCESSOR_BASE_VA:
+    .word   0xfc100000
+
+/* Virtual address of the clock enable register of ID_SCS. */
+ID_SCS_CLKEN_VA:
+    .word   0xfd300140
+
+IO_LINE_BUFFER_BASE_VA:
+    .word   0xf8000000
+
+AUDIO_INTR_REGS_VA:
+    .word   0xfc300000
+
+/* Base address of the DDR control registers. */
+DDR_BASE_VA:
+    .word   0xf8110000
+/* End CNC1900 definitions */
+
+
+
+
+
+/* These two values must be written in order to the watchdog timer
+   disable register in order to disable it. */
+WD_DISABLE_VALUE1:
+    .word   0x12345678
+WD_DISABLE_VALUE2:
+    .word   0x87654321
+
+OHCI_STAT_CLEAR:
+    .word   0x4000007f
+
+INSN_END:
+    nop
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/arch/arm/mach-celestial/pinmux.c linux-linaro-3.4-2012.05-1_cavium/arch/arm/mach-celestial/pinmux.c
--- linux-linaro-3.4-2012.05-1_original/arch/arm/mach-celestial/pinmux.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/arch/arm/mach-celestial/pinmux.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,945 @@
+#include <linux/version.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/ioport.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <linux/proc_fs.h>
+#include <mach/cnc1900.h>
+#include <mach/pinmux.h>
+
+#define REG_PINMUX_VER		0x000
+#define REG_PINMUX_I2C		0x004
+#define REG_PINMUX_UART	0x008
+#define REG_PINMUX_SMI		0x010
+#define REG_PINMUX_DISP	0x014
+#define REG_PINMUX_TS		0x018
+#define REG_PINMUX_DVIO	0x01c
+#define REG_PINMUX_SDIO	0x024
+
+enum pinmux_class  mode;
+volatile unsigned int *pinmux_base;
+volatile unsigned short *rc_base;
+volatile unsigned short *fpc_base;
+volatile unsigned int * gpio_base;
+
+#define REG_GPIO_SWPORTA_DDR	0x24
+#define REG_GPIO_SWPORTB_DDR  0x38
+/* ----------------------------------------------------------- */
+
+#if 1
+extern void gpio_configure_status_bit(unsigned int bit, const char * configure_cmd,char is_pinmux);
+#else
+void gpio_configure_status_bit(unsigned int bit, char * configure_cmd, char is_pinmux)
+{
+	;
+}
+#endif
+int cnc_gpio_register_module_set(const char * module, unsigned int  cnc_module_status) /* status: 0 disable, 1 enable */
+{
+	int gpionum;
+
+	if(strncmp("RC", module, 2)==0){
+		if (cnc_module_status == 1){
+			gpio_configure_status_bit(11 ,"SET",1);
+		}
+		if (cnc_module_status == 0){
+			gpio_configure_status_bit(11 ,"CLR",1);
+		}
+	}else if(strncmp("FPC-COMMON", module, 10)==0){
+		if (cnc_module_status == 1){
+			gpio_configure_status_bit(10, "SET",1);
+			gpio_configure_status_bit(8,  "SET",1);
+			gpio_configure_status_bit(9,  "SET",1);
+			gpio_configure_status_bit(7,  "SET",1);
+			gpio_configure_status_bit(2,  "SET",1);
+		}
+		if (cnc_module_status == 0){
+			gpio_configure_status_bit(10, "CLR",1);
+			gpio_configure_status_bit(9,  "CLR",1);
+			gpio_configure_status_bit(8,  "CLR",1);
+			gpio_configure_status_bit(7,  "CLR",1);
+			gpio_configure_status_bit(2,  "CLR",1);
+		}
+	}else if(strncmp("FPC-LED-SPECIAL", module, 15)==0){
+		if (cnc_module_status == 1){
+			gpio_configure_status_bit(4, "SET",1);
+			gpio_configure_status_bit(5,  "SET",1);
+		}
+		if (cnc_module_status == 0){
+			gpio_configure_status_bit(4,  "CLR",1);
+			gpio_configure_status_bit(5,  "CLR",1);
+		}
+	}else if(strncmp("PCMCIA", module, 6)==0){
+		if (cnc_module_status == 1){
+			gpio_configure_status_bit(14, "SET", 1);
+			gpio_configure_status_bit(13, "SET", 1);
+			gpio_configure_status_bit(12, "SET", 1);
+		}
+		if (cnc_module_status == 0){
+			gpio_configure_status_bit(14, "CLR", 1);
+			gpio_configure_status_bit(13, "CLR", 1);
+			gpio_configure_status_bit(12, "CLR", 1);
+		}
+	}else if (strncmp("I2C1", module, 4)==0){
+		if (cnc_module_status == 1){
+			gpio_configure_status_bit(0,"SET",1);
+			gpio_configure_status_bit(1,"SET",1);
+		}
+		if (cnc_module_status == 0){
+			gpio_configure_status_bit(0,"CLR",1);
+			gpio_configure_status_bit(1,"CLR",1);
+		}
+	}else if (strncmp("IR1", module, 3)==0){
+		if (cnc_module_status == 1){
+			gpio_configure_status_bit(11,"SET",1);
+		}
+		if (cnc_module_status == 0){
+			gpio_configure_status_bit(11,"CLR",1);
+		}
+	}else if (strncmp("VGA", module, 4)==0){
+		if (cnc_module_status == 1){
+			gpio_configure_status_bit(0,"SET",1);
+			gpio_configure_status_bit(1,"SET",1);
+		}
+		if (cnc_module_status == 0){
+			gpio_configure_status_bit(0,"CLR",1);
+			gpio_configure_status_bit(1,"CLR",1);
+		}
+	}else if (strncmp("I2C0", module, 4)==0){
+		if (cnc_module_status == 1){
+			gpio_configure_status_bit(16,"SET",1);
+			gpio_configure_status_bit(17,"SET",1);
+		}
+		if (cnc_module_status == 0){
+			gpio_configure_status_bit(16,"CLR",1);
+			gpio_configure_status_bit(17,"CLR",1);
+		}
+	}else if (strncmp("UART1", module, 5)==0){
+		if (cnc_module_status == 1){
+			gpio_configure_status_bit(3,"SET",1);
+			gpio_configure_status_bit(6,"SET",1);
+		}
+		if (cnc_module_status == 0){
+			gpio_configure_status_bit(3,"CLR",1);
+			gpio_configure_status_bit(6,"CLR",1);
+		}
+	}else if (strncmp("UART1-CTS_RTS", module, 13)==0){
+		if (cnc_module_status == 1){
+			gpio_configure_status_bit(14,"SET",1);
+			gpio_configure_status_bit(15,"SET",1);
+		}
+		if (cnc_module_status == 0){
+			gpio_configure_status_bit(14,"CLR",1);
+			gpio_configure_status_bit(15,"CLR",1);
+		}
+	}else if (strncmp("SMI", module, 3)==0){
+		if (cnc_module_status == 1){
+			gpio_configure_status_bit(27,"SET",1);
+			gpio_configure_status_bit(28,"SET",1);
+			gpio_configure_status_bit(29,"SET",1);
+			gpio_configure_status_bit(30,"SET",1);
+			gpio_configure_status_bit(31,"SET",1);
+		}
+		if (cnc_module_status == 0){
+			gpio_configure_status_bit(27,"CLR",1);
+			gpio_configure_status_bit(28,"CLR",1);
+			gpio_configure_status_bit(29,"CLR",1);
+			gpio_configure_status_bit(30,"CLR",1);
+			gpio_configure_status_bit(31,"CLR",1);
+		}
+	}else if (strncmp("SDIO", module, 4)==0){
+		if (cnc_module_status == 1){
+			for (gpionum=32; gpionum<=39; gpionum ++) {
+				gpio_configure_status_bit(gpionum,"SET",1);
+			}
+		}
+		if (cnc_module_status == 0){
+			for (gpionum=32; gpionum<=39; gpionum ++) {
+				gpio_configure_status_bit(gpionum,"CLR",1);
+			}
+		}
+	}else if (strncmp("VIB", module, 3)==0 || strncmp("TTLOUT", module, 6)==0){
+		if (cnc_module_status == 1){
+			for (gpionum=40; gpionum<=63; gpionum ++) {
+				gpio_configure_status_bit(gpionum,"SET",1);
+			}
+		}
+		if (cnc_module_status == 0){
+			for (gpionum=40; gpionum<=63; gpionum ++) {
+				gpio_configure_status_bit(gpionum,"CLR",1);
+			}
+		}
+	}
+	else {
+		return 0;
+	}
+	return 1;
+}
+
+int pinmux_set_status_bit(int mode, int bit, int set)
+{
+	switch(mode){
+		case PINMUX_I2C:
+			if(set)
+				pinmux_base[REG_PINMUX_I2C>>2] |= (1<<(bit));
+			else
+				pinmux_base[REG_PINMUX_I2C>>2] &= ~(1<<(bit));
+			break;
+
+		case PINMUX_UART:
+			if(set)
+				pinmux_base[REG_PINMUX_UART>>2] |= (1<<(bit));
+			else
+				pinmux_base[REG_PINMUX_UART>>2] &= ~(1<<(bit));
+			break;
+
+		case PINMUX_DISP:
+			if(bit <= 5){
+				if(set ){
+					if(bit == TVE0_YPbPr){
+						pinmux_base[REG_PINMUX_DISP>>2] &= 0;
+					}
+					else if(bit == OUTIF0_RGB){
+						pinmux_base[REG_PINMUX_DISP>>2] |= 1<<8;
+						pinmux_base[REG_PINMUX_DISP>>2] &= ~(1<<10);
+					}
+					else if(bit == TVE1_CVBS_S_video){
+						pinmux_base[REG_PINMUX_DISP>>2] |= 1<<10;
+						pinmux_base[REG_PINMUX_DISP>>2] &= ~(1<<9);
+						pinmux_base[REG_PINMUX_DISP>>2] &= ~(1<<8);
+					}
+					else if(bit == TVE1_YPbPr){
+						pinmux_base[REG_PINMUX_DISP>>2] |= 1<<10;
+						pinmux_base[REG_PINMUX_DISP>>2] &= ~(1<<9);
+						pinmux_base[REG_PINMUX_DISP>>2] |= 1<<8;
+					}
+					else if(bit == OUTIF1_RGB){
+						pinmux_base[REG_PINMUX_DISP>>2] |= 1<< 10;
+						pinmux_base[REG_PINMUX_DISP>>2] |= 1<< 9;
+					}
+				}
+				else
+					printk("invalid bit \n");
+			}
+			else
+				printk("invalid bit \n");
+			break;
+		case PINMUX_SMI:
+			if(bit == 1){
+				if(set)
+					pinmux_base[REG_PINMUX_SMI>>2] |= (1<<(bit));
+				else
+					pinmux_base[REG_PINMUX_SMI>>2] &= ~(1<<(bit));
+			}
+			else
+				printk("invalid bit ");
+			break;
+		case PINMUX_TS:
+			if(bit == 14){
+				if(set)
+					pinmux_base[REG_PINMUX_TS>>2] |= (1<<(bit));
+				else
+					pinmux_base[REG_PINMUX_TS>>2] &= ~(1<<(bit));
+			}
+			else
+				printk("invalid bit ");
+			break;
+
+		case PINMUX_DVIO:
+			if(bit == 2 || bit==1){
+				if(set)
+					pinmux_base[REG_PINMUX_DVIO>>2] |= (1<<(bit));
+				else
+					pinmux_base[REG_PINMUX_DVIO>>2] &= ~(1<<(bit));
+			}
+			else
+				printk("invalid bit ");
+			break;
+
+		case PINMUX_SDIO:
+			if(set)
+				pinmux_base[REG_PINMUX_SDIO>>2] |= (1<<bit);
+			else
+				pinmux_base[REG_PINMUX_SDIO>>2] &= ~(1<<bit);
+			break;
+
+		default:
+			break;
+	}
+
+	return 0;
+}
+
+int pinmux_scan_status_bit(int regType)
+{
+	int ret;
+	switch(regType){
+		case PINMUX_I2C:
+			ret = pinmux_base[REG_PINMUX_I2C>>2];
+			if(ret & 0x1)
+				printk("I2C0 ENA \n");
+			else
+				printk("GPIO17:16 ENA \n");
+			if(ret & 0x2){
+				if(ret & 0x6)
+					printk(" VGA ENA \n");
+				else
+					printk("I2C1 ENA  \n");
+			}
+			else
+				printk("GPIO 1:0 ENA  \n");
+			if(ret & 0x8)
+				printk("output disp1 hsync and vsync  \n");
+			else
+				printk("output disp2 hsync and vsync  \n");
+			break;
+		case PINMUX_UART:
+			ret = pinmux_base[REG_PINMUX_UART>>2];
+			if(ret & 0x2){
+				if(ret & 0x8){
+					if(ret & 0x4)
+						printk("VIDEO UART ENA  \n");
+					else
+						printk("AUDIO UART ENA  \n");
+				}else{
+						printk("UART1 ENA  \n");
+						if(ret & 0x0c){
+							printk("UART1 RTS/CTS ENA \n");
+						}else{
+							printk("GPIO 14, 15 ENA \n");
+						}
+				}
+			}else{
+				printk("GPIO 3, 6, 14, 15 ENA  \n");
+			}
+			break;
+		case PINMUX_DISP:
+			ret = pinmux_base[REG_PINMUX_DISP>>2];
+			if(ret & 0)
+				printk("TVE0 YPbPr ENA  \n");
+			if(ret & 0x100)
+				printk("OUTIF0 RGB ENA   \n");
+			if(ret & 0x400)
+				printk("TVE1 CVBS+S-video ENA  \n");
+			if(ret & 0x500)
+				printk("TVE1 YPbPr ENA  \n");
+			if(ret & 0x600)
+				printk("OUTIF1 RGB ENA  \n");
+			break;
+		case PINMUX_SMI:
+			ret = pinmux_base[REG_PINMUX_SMI>>2];
+			if(ret & 0x1)
+				printk("SMI enable  \n");
+			else
+				printk("GPIO[31:27] enable  \n");
+			break;
+		case PINMUX_DVIO:
+			ret = pinmux_base[REG_PINMUX_DVIO>>2];
+			if(ret & 0x2)
+				printk("digital video input enable  \n");
+			else if (ret & 0x1)
+				printk("digital video output(TTL) enable  \n");
+			else
+				printk("GPIO[63:40] enable  \n");
+			break;
+		case PINMUX_SDIO:
+			ret = pinmux_base[REG_PINMUX_SDIO>>2];
+			if(ret & 0x1)
+				printk("SDIO enable  \n");
+			else
+				printk("GPIO[39:32] enable  \n");
+			break;
+		case PINMUX_TS:
+			ret = pinmux_base[REG_PINMUX_TS>>2];
+			if(ret & 0x4000)
+				printk("xport 1 enable(xport 0 and xport 1 work under serial mode)  \n");
+			else
+				printk("xport 1 disalbe(xport 0 work under parallel mode)  \n");
+			break;
+
+		default:
+			printk(" errorr  \n");
+
+	}
+	return 0;
+}
+
+int pinmux_get_status_bit(int  regType,int bit)
+{
+	int ret = 0;
+	switch(regType){
+		case PINMUX_I2C:
+			ret = pinmux_base[REG_PINMUX_I2C>>2]&(1<<(bit-1));
+			printk("the REG_PINMUX_I2C's %d bit number is %d",bit,ret);
+			break;
+		case PINMUX_UART:
+			ret = pinmux_base[REG_PINMUX_UART>>2]&(1<<(bit-1));
+			printk("the PINMUX_UART's %d bit number is %d",bit,ret);
+			break;
+		case PINMUX_SMI:
+			ret = pinmux_base[REG_PINMUX_SMI>>2]&(1<<(bit-1));
+			printk("the PINMUX_SMI's %d bit number is %d",bit,ret);
+			break;
+		case PINMUX_DISP:
+			ret = pinmux_base[REG_PINMUX_DISP>>2]&(1<<(bit-1));
+			printk("the PINMUX_DISP's %d bit number is %d",bit,ret);
+			break;
+		case PINMUX_TS:
+			ret = pinmux_base[REG_PINMUX_TS>>2]&(1<<(bit-1));
+			printk("the PINMUX_TS's %d bit number is %d",bit,ret);
+			break;
+		case PINMUX_DVIO:
+			ret = pinmux_base[REG_PINMUX_DVIO>>2]&(1<<(bit-1));
+			printk("the PINMUX_DVIO's %d bit number is %d",bit,ret);
+			break;
+		case PINMUX_SDIO:
+			ret = pinmux_base[REG_PINMUX_SDIO>>2]&(1<<(bit-1));
+			printk("the PINMUX_DVIO's %d bit number is %d",bit,ret);
+			break;
+		default :
+			printk("errorr\n");
+	}
+	return 0;
+}
+
+int pinmux_enable_gpio(GPIO_ID GPIO)
+{
+	int rt=0;
+
+	switch(GPIO){
+		case _gpio_0     :
+		case _gpio_1     :
+			pinmux_base[REG_PINMUX_I2C>>2] &= ~(1<<1);
+			cnc_gpio_register_module_set("I2C1",0);
+			break;
+		case _gpio_2     :
+			break;
+		case _gpio_3     :
+		case _gpio_6     :
+			pinmux_base[REG_PINMUX_UART>>2] &= ~(1<<1);
+			cnc_gpio_register_module_set("UART1",0);
+			break;
+		case _gpio_4     :
+			break;
+		case _gpio_5     :
+			break;
+		case _gpio_7     :
+			break;
+		case _gpio_8     :
+			break;
+		case _gpio_9     :
+			break;
+		case _gpio_10    :
+			break;
+		case _gpio_11    :
+			break;
+		case _gpio_12    :
+			break;
+		case _gpio_13    :
+			break;
+		case _gpio_14    :
+			break;
+		case _gpio_15    :
+			break;
+		case _gpio_16    :
+		case _gpio_17    :
+			break;
+		case _gpio_18    :
+		case _gpio_19    :
+			break;
+		case _gpio_20    :
+			printk("has not used \n");
+			break;
+		case _gpio_21    :
+			printk("has not used \n");
+			break;
+		case _gpio_22    :
+		case _gpio_23    :
+		case _gpio_24    :
+		case _gpio_25    :
+		case _gpio_26    :
+			break;
+		case _gpio_27    :
+		case _gpio_28    :
+		case _gpio_29    :
+		case _gpio_30    :
+		case _gpio_31    :
+			pinmux_base[REG_PINMUX_SMI>>2] &= ~1;
+			cnc_gpio_register_module_set("SMI",0);
+			break;
+		case _gpio_32    :
+		case _gpio_33    :
+		case _gpio_34    :
+		case _gpio_35    :
+		case _gpio_36    :
+		case _gpio_37    :
+		case _gpio_38    :
+		case _gpio_39    :
+			pinmux_base[REG_PINMUX_SDIO>>2] &= ~(1<<1);
+			cnc_gpio_register_module_set("SDIO",0);
+			break;
+		case _gpio_40    :
+		case _gpio_41    :
+		case _gpio_42    :
+		case _gpio_43    :
+		case _gpio_44    :
+		case _gpio_45    :
+		case _gpio_46    :
+		case _gpio_47    :
+		case _gpio_48    :
+		case _gpio_49    :
+		case _gpio_50    :
+		case _gpio_51    :
+		case _gpio_52    :
+		case _gpio_53    :
+		case _gpio_54    :
+		case _gpio_55    :
+		case _gpio_56    :
+		case _gpio_57    :
+		case _gpio_58    :
+		case _gpio_59    :
+		case _gpio_60    :
+		case _gpio_61    :
+		case _gpio_62    :
+		case _gpio_63    :
+			pinmux_base[REG_PINMUX_DVIO>>2] = 0;
+			cnc_gpio_register_module_set("DVIO",0);
+			break;
+		default:
+			;
+
+	}
+	return rt;
+
+}
+
+
+int pinmux_enable_i2c(I2C_ID I2C)
+{
+	switch(I2C)
+	{
+		case _i2c_0:
+			break;
+		case _i2c_1:
+			pinmux_base[REG_PINMUX_I2C>>2] |= (1<<1);
+			cnc_gpio_register_module_set("I2C1",1);
+			break;
+		default:
+			;
+	}
+
+	return 0;
+
+}
+
+int pinmux_enable_ir_repeater(IR_REPEATER_ID IR)
+{
+	switch(IR)
+	{
+		case _IR0:
+			break;
+		case _IR1:
+			pinmux_base[REG_PINMUX_I2C>>2] |= (1<<2);
+			cnc_gpio_register_module_set("IR1",1);
+			break;
+		default:
+			;
+	}
+
+	return 0;
+
+}
+int pinmux_enable_uart(UART_ID UART)
+{
+	switch(UART)
+	{
+		case _uart_1:
+			pinmux_base[REG_PINMUX_UART>>2] &= ~(1<<3);
+			pinmux_base[REG_PINMUX_UART>>2] |= (1<<1);
+#ifdef CONFIG_CELESTIAL_UART1_CTS_RTS
+			pinmux_base[REG_PINMUX_UART>>2] |= (1<<4);
+			cnc_gpio_register_module_set("UART1-CTS-RTS",1);
+#endif
+			break;
+		case _uart_audio:
+			pinmux_base[REG_PINMUX_UART>>2] |= (1<<1);
+			pinmux_base[REG_PINMUX_UART>>2] |= (1<<3);
+			pinmux_base[REG_PINMUX_UART>>2] &= ~(1<<2);
+			break;
+		case _uart_video:
+			pinmux_base[REG_PINMUX_UART>>2] |= (1<<1);
+			pinmux_base[REG_PINMUX_UART>>2] |= (1<<3);
+			pinmux_base[REG_PINMUX_UART>>2] |= (1<<2);
+			break;
+		default:
+			;
+	}
+	cnc_gpio_register_module_set("UART1",1);
+	return 0;
+}
+
+int pinmux_enable_smi(void)
+{
+	pinmux_base[REG_PINMUX_SMI>>2] |= 1;
+	cnc_gpio_register_module_set("SMI",1);
+	return 0;
+}
+
+int pinmux_enable_vib(void)
+{
+	pinmux_base[REG_PINMUX_DVIO>>2] = (1<<1);
+	gpio_base[REG_GPIO_SWPORTB_DDR>>2] |= 0xffffff00;
+	cnc_gpio_register_module_set("VIB",1);
+	return 0;
+}
+
+int pinmux_enable_ttlout(void)
+{
+	pinmux_base[REG_PINMUX_DVIO>>2] = 0x1;
+	cnc_gpio_register_module_set("TTL",1);
+	return 0;
+}
+
+int pinmux_set_dac0mode(DAC0_MODE Mode)
+{
+	switch(Mode)
+	{
+		case _dac0_rgb0:
+			pinmux_base[REG_PINMUX_DISP>>2] |= (1<<9);
+			pinmux_base[REG_PINMUX_DISP>>2] &= (~(1<<10));
+			break;
+		case _dac0_rgb1:
+			pinmux_base[REG_PINMUX_DISP>>2] |= (1<<9);
+			pinmux_base[REG_PINMUX_DISP>>2] |= (1<<10);
+			break;
+		case _dac0_tve0_ypbpr:
+			pinmux_base[REG_PINMUX_DISP>>2] |= (1<<8);
+			pinmux_base[REG_PINMUX_DISP>>2] &= (~(1<<9));
+			pinmux_base[REG_PINMUX_DISP>>2] &= (~(1<<10));
+			break;
+		case _dac0_tve0_cvbs_svideo:
+			pinmux_base[REG_PINMUX_DISP>>2] &= (~(1<<8));
+			pinmux_base[REG_PINMUX_DISP>>2] &= (~(1<<9));
+			pinmux_base[REG_PINMUX_DISP>>2] &= (~(1<<10));
+			break;
+		case _dac0_tve1_ypbpr:
+			pinmux_base[REG_PINMUX_DISP>>2] |= (1<<8);
+			pinmux_base[REG_PINMUX_DISP>>2] &= (~(1<<9));
+			pinmux_base[REG_PINMUX_DISP>>2] |= (1<<10);
+			break;
+		case _dac0_tve1_cvbs_svideo:
+			pinmux_base[REG_PINMUX_DISP>>2] &= (~(1<<8));
+			pinmux_base[REG_PINMUX_DISP>>2] &= (~(1<<9));
+			pinmux_base[REG_PINMUX_DISP>>2] |= (1<<10);
+			break;
+	}
+
+	return 0;
+}
+
+int pinmux_set_dac1mode(DAC1_MODE Mode)
+{
+	switch(Mode){
+		case _dac1_rgb1:
+			pinmux_base[REG_PINMUX_DISP>>2] |= (1<<12);
+			break;
+		case _dac1_tve1_ypbpr:
+			pinmux_base[REG_PINMUX_DISP>>2] |= (1<<11);
+			pinmux_base[REG_PINMUX_DISP>>2] &= (~(1<<12));
+			break;
+		case _dac1_tve1_cvbs_svideo:
+			pinmux_base[REG_PINMUX_DISP>>2] &= (~(1<<11));
+			pinmux_base[REG_PINMUX_DISP>>2] &= (~(1<<12));
+			break;
+	}
+
+	return 0;
+}
+
+int pinmux_set_xportmode(XPORT_MODE Mode)
+{
+
+	switch (Mode)
+	{
+		case _xport_serial_mode:
+			pinmux_base[REG_PINMUX_TS>>2] |= (1<<14);
+			break;
+		case _xport_paralell_mode:
+			pinmux_base[REG_PINMUX_TS>>2] &= ~(1<<14);
+			break;
+		default:
+			printk("set wrong mode \n");
+	}
+
+	return 0;
+}
+
+int pinmux_enable_tsout(int enable)
+{
+	if (enable)
+		pinmux_base[REG_PINMUX_TS>>2] |= (1<<15);
+	else
+		pinmux_base[REG_PINMUX_TS>>2] &= ~(1<<15);
+
+	return 0;
+}
+
+int pinmux_update_rc_status(void)
+{
+	unsigned short rc_ctl;
+
+	rc_ctl = rc_base[RC_CTL_H>>1] & 0x8000;
+	//    rc_ctl = rc_ctl >> 15;
+	cnc_gpio_register_module_set("RC", rc_ctl?1:0);
+	return 0;
+}
+
+#define FPC_LED_CNTL_H 		0x206 /* Led Display Control Register */
+#define FPC_KEYSCAN_CNTL_L  0x304
+int pinmux_update_fpc_status(void)
+{
+	unsigned short keyscan_ctl, led_ctl;
+	unsigned int arg;
+
+	led_ctl = fpc_base[FPC_LED_CNTL_H >> 1] & 0x8000;
+	keyscan_ctl = fpc_base[FPC_KEYSCAN_CNTL_L >>1] & 0x1;
+
+	arg = (led_ctl | keyscan_ctl) ? 1: 0;
+	cnc_gpio_register_module_set("FPC-COMMON", arg);
+
+	cnc_gpio_register_module_set("FPC-LED-SPECIAL", led_ctl? 1: 0);
+
+	return 0;
+}
+
+EXPORT_SYMBOL(pinmux_update_fpc_status);
+EXPORT_SYMBOL(pinmux_get_status_bit);
+EXPORT_SYMBOL(pinmux_set_status_bit);
+EXPORT_SYMBOL(pinmux_scan_status_bit);
+EXPORT_SYMBOL(pinmux_set_xportmode);
+EXPORT_SYMBOL(pinmux_enable_tsout);
+EXPORT_SYMBOL(pinmux_enable_uart);
+EXPORT_SYMBOL(pinmux_enable_i2c);
+EXPORT_SYMBOL(pinmux_enable_ir_repeater);
+//EXPORT_SYMBOL(pinmux_enable_irda);
+//EXPORT_SYMBOL(pinmux_enable_spi);
+EXPORT_SYMBOL(pinmux_enable_smi);
+EXPORT_SYMBOL(pinmux_enable_vib);
+EXPORT_SYMBOL(pinmux_set_dac0mode);
+EXPORT_SYMBOL(pinmux_set_dac1mode);
+EXPORT_SYMBOL(pinmux_enable_gpio);
+EXPORT_SYMBOL(pinmux_update_rc_status);
+EXPORT_SYMBOL(pinmux_enable_ttlout);
+
+static int  pinmux_proc_read(char *page, char **start, off_t off, int count, int *eof, void *data)
+{
+	int len=0;
+	int i =1;
+	int ret;
+
+	ret = pinmux_base[REG_PINMUX_I2C>>2];
+	if(ret & 0x2)
+		len += sprintf(page+len,"==> REG_PINMUX_I2C's PINMUX %d is held by I2C1 output. \n",i++);
+	else
+		len += sprintf(page+len,"==> REG_PINMUX_I2C's PINMUX %d is held by GPIO[1:0]. \n",i++);
+
+	if(ret & 0x4)
+		len += sprintf(page+len,"==> REG_PINMUX_I2C's PINMUX %d is held by IR1. \n",i++);
+	else
+		len += sprintf(page+len,"==> REG_PINMUX_I2C's PINMUX %d is held by GPIO[11]. \n",i++);
+
+	ret = pinmux_base[REG_PINMUX_UART>>2];
+	if(ret & 0x2){
+		if(ret & 0x8){
+			if(ret & 0x4)
+				len += sprintf(page+len,"==> REG_PINMUX_UART's PINMUX %d is held by Video UART. \n",i++);
+			else
+				len += sprintf(page+len,"==> REG_PINMUX_UART's PINMUX %d is held by Audio UART. \n",i++);
+		}
+		else{
+			len += sprintf(page+len,"==> REG_PINMUX_UART's PINMUX %d is held by UART1. \n",i++);
+			if(ret & 0x10)
+				len += sprintf(page+len,"==>UART1 with cts/rts handshake. \n");
+			else
+				len += sprintf(page+len,"==>UART1 no handshake. \n");
+		}
+	}
+	else
+		len += sprintf(page+len,"==> REG_PINMUX_UART's PINMUX %d is held by GPIO[3,6]. \n",i++);
+
+	ret = pinmux_base[REG_PINMUX_SMI>>2];
+	if(ret & 0x1)
+		len += sprintf(page+len,"==> REG_PINMUX_SPI's PINMUX %d is held by SMI. \n",i);
+	else
+		len += sprintf(page+len,"==> REG_PINMUX_SPI's PINMUX %d is held by GPIO[31:27]. \n",i++);
+
+	ret = pinmux_base[REG_PINMUX_DISP>>2];
+	switch((ret >>8) & 0x7){
+		case 0x0:
+			len += sprintf(page+len,"==> REG_PINMUX_DISP's DAC0 %d is held by TVE0 CVBS+S-video. \n",i++);
+			break;
+		case 0x1:
+			len += sprintf(page+len,"==> REG_PINMUX_DISP's DAC0 %d is held by TVE0 YPbPr. \n",i++);
+			break;
+		case 0x2:
+		case 0x3:
+			len += sprintf(page+len,"==> REG_PINMUX_DISP's DAC0 %d is held by OUTIF0 RGB. \n",i++);
+			break;
+		case 0x4:
+			len += sprintf(page+len,"==> REG_PINMUX_DISP's DAC0 %d is held by TVE1 CVBS+S-video. \n",i++);
+			break;
+		case 0x5:
+			len += sprintf(page+len,"==> REG_PINMUX_DISP's DAC0 %d is held by TVE1 YPbPr. \n",i++);
+			break;
+		case 0x6:
+		case 0x7:
+			len += sprintf(page+len,"==> REG_PINMUX_DISP's DAC0 %d is held by OUTIF1 RGB. \n",i++);
+			break;
+	}
+
+	switch((ret >>11) & 0x3){
+		case 0x0:
+			len += sprintf(page+len,"==> REG_PINMUX_DISP's DAC1 %d is held by TVE1 CVBS+S-video. \n",i++);
+			break;
+		case 0x1:
+			len += sprintf(page+len,"==> REG_PINMUX_DISP's DAC1 %d is held by TVE1 YPbPr. \n",i++);
+			break;
+		case 0x2:
+		case 0x3:
+			len += sprintf(page+len,"==> REG_PINMUX_DISP's DAC1 %d is held by OUTIF1 RGB. \n",i++);
+			break;
+	}
+
+	ret = pinmux_base[REG_PINMUX_TS>>2];
+	if(ret & 0x4000)
+		len += sprintf(page+len,"==> REG_PINMUX_TS's PINMUX %d xport 1 enable(xport 0 and xport 1 work under serial mode). \n",i++);
+	else
+		len += sprintf(page+len,"==> REG_PINMUX_TS's PINMUX %d  xport 1 disalbe(xport 0 work under parallel mode). \n",i++);
+
+	if(ret & 0x8000)
+		len += sprintf(page+len,"==> REG_PINMUX_TS's PINMUX %d TS out enable(I2S output disbale). \n",i++);
+	else
+		len += sprintf(page+len,"==> REG_PINMUX_TS's PINMUX %d TS out disalbe(I2S output enable). \n",i++);
+
+	ret = pinmux_base[REG_PINMUX_DVIO>>2];
+	if(ret & 0x1)
+		len += sprintf(page+len,"==> REG_PINMUX_DVIO's PINMUX %d is held by digital video output(TTL)\n",i++);
+	else if(ret & 0x2)
+		len += sprintf(page+len,"==> REG_PINMUX_DVIO's PINMUX %d is held by digital video input(VPB) . \n",i++);
+	else
+		len += sprintf(page+len,"==> REG_PINMUX_DVIO's PINMUX %d is held by GPIO[63:40]. \n",i++);
+
+	ret = pinmux_base[REG_PINMUX_SDIO>>2];
+	if(ret & 0x1)
+		len += sprintf(page+len,"==> REG_PINMUX_SDIO's PINMUX %d  SDIO enable. \n",i);
+	else
+		len += sprintf(page+len,"==> REG_PINMUX_SDIO's PINMUX %d is held by GPIO[39:32] . \n",i++);
+	return len;
+
+}
+
+static int pinmux_proc_write(struct file *file, const char __user *buffer,
+		unsigned long count, void *data)
+{
+	unsigned short bit;
+	unsigned short val;
+
+	const char *cmd_line = buffer;
+
+	if (strncmp("WW_I2C", cmd_line, 6) == 0) {
+		bit = simple_strtol(&cmd_line[7], NULL, 16);
+		val = simple_strtol(&cmd_line[9], NULL, 16);
+		pinmux_set_status_bit(PINMUX_I2C, bit, val);
+	} else if (strncmp("WW_UAR", cmd_line, 6) == 0) {
+		bit = simple_strtol(&cmd_line[7], NULL, 16);
+		val = simple_strtol(&cmd_line[9], NULL, 16);
+		pinmux_set_status_bit(PINMUX_UART, bit, val);
+	}else if(strncmp("WW_DIS", cmd_line, 6) == 0){
+		bit = simple_strtol(&cmd_line[7], NULL, 16);
+		val = simple_strtol(&cmd_line[9], NULL, 16);
+		pinmux_set_status_bit(PINMUX_DISP, bit, val);
+	}else if(strncmp("WW_SMI", cmd_line, 6) == 0){
+		bit = simple_strtol(&cmd_line[7], NULL, 16);
+		val = simple_strtol(&cmd_line[9], NULL, 16);
+		pinmux_set_status_bit(PINMUX_SMI, bit, val);
+	}else if(strncmp("WW_TS1", cmd_line, 6) == 0){
+		bit = simple_strtol(&cmd_line[7], NULL, 16);
+		val = simple_strtol(&cmd_line[9], NULL, 16);
+		pinmux_set_status_bit(PINMUX_TS, bit, val);
+	}else if(strncmp("WW_DVI", cmd_line, 6) == 0){
+		bit = simple_strtol(&cmd_line[7], NULL, 16);
+		val = simple_strtol(&cmd_line[9], NULL, 16);
+		pinmux_set_status_bit(PINMUX_DVIO, bit, val);
+	}else if(strncmp("WW_SDIO", cmd_line, 6) == 0){
+		bit = simple_strtol(&cmd_line[7], NULL, 16);
+		val = simple_strtol(&cmd_line[9], NULL, 16);
+		pinmux_set_status_bit(PINMUX_SDIO, bit, val);
+	}
+	else if(strncmp("dumpreg",cmd_line,7) == 0){
+		unsigned int count = 0;
+
+		for(count = 0; count < 10; count ++){
+			if(count == 0){
+				printk("\n CNC1900_PIN_MUX_REG_BASE\n");
+			}
+			printk(" addr[0x%08x] = 0x%08x \n", CNC1900_PIN_MUX + count*4, pinmux_base[count]);
+		}
+	}
+	return count;
+}
+
+int cnc1900_pinmux_init_setting(void)
+{
+
+#ifdef CONFIG_CELESTIAL_UART1
+	pinmux_enable_uart(_uart_1);
+#endif
+	return 0;
+}
+
+static struct proc_dir_entry *cnc_pinmux_proc_entry = NULL;
+static int __init cnc19xx_pinmux_init(void)
+{
+	if (!request_mem_region(CNC1900_PIN_MUX, CNC1900_PIN_MUX_SIZE, "CNC1900 PINMUX")) {
+		printk("cnc19xx_pinmux_init request_mem_region failed.\n");
+		return -EIO;
+	}
+
+	pinmux_base = (volatile unsigned int *) ioremap(CNC1900_PIN_MUX, CNC1900_PIN_MUX_SIZE);
+	if (!pinmux_base) {
+		printk("cnc19xx_pinmux_init ioremap failed.\n");
+		return -EIO;
+	}
+
+	gpio_base =(unsigned int *) VA_GPIO_BASE;
+	rc_base = (unsigned short *)VA_FPC_BASE;
+	fpc_base = (unsigned short *)VA_FPC_BASE;
+	if (!fpc_base) {
+		printk("cnc19xx_pinmux_init  failed.\n");
+		return -EIO;
+	}
+
+	cnc_pinmux_proc_entry = create_proc_entry("cnc_pinmux", 0, NULL);
+	if (NULL != cnc_pinmux_proc_entry) {
+		cnc_pinmux_proc_entry->write_proc = &pinmux_proc_write;
+		cnc_pinmux_proc_entry->read_proc = &pinmux_proc_read;
+	}
+
+	cnc1900_pinmux_init_setting();
+	printk("cnc19xx_pinmux_init  done.\n");
+	return 0;
+}
+
+static void __exit cnc19xx_pinmux_exit(void)
+{
+	iounmap((void *) pinmux_base);
+	release_mem_region(CNC1900_PIN_MUX, CNC1900_PIN_MUX_SIZE);
+	printk("cnc19xx_pinmux_exit  done.\n");
+}
+
+postcore_initcall(cnc19xx_pinmux_init);
+
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/arch/arm/mach-celestial/platsmp.c linux-linaro-3.4-2012.05-1_cavium/arch/arm/mach-celestial/platsmp.c
--- linux-linaro-3.4-2012.05-1_original/arch/arm/mach-celestial/platsmp.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/arch/arm/mach-celestial/platsmp.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,52 @@
+/*
+ * arch/arm/mach-celestial/platsmp.c
+ * Cavium CNC1900 Timer System, 2013
+ *
+ * This file is licensed unde the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of
+ * any kind, whether express or implied.
+ */
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/smp.h>
+#include <linux/io.h>
+#include <linux/of_fdt.h>
+
+#include <asm/smp_scu.h>
+#include <asm/hardware/gic.h>
+#include <asm/mach/map.h>
+
+#include <mach/hardware.h>
+
+void __cpuinit platform_secondary_init(unsigned int cpu)
+{
+	printk("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nplatform_secondary_init\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
+}
+
+int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+	printk("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nboot_secondary\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
+
+	return 0;
+}
+
+/*
+ * Initialise the CPU possible map early - this describes the CPUs
+ * which may be present or become present in the system.
+ */
+void __init smp_init_cpus(void)
+{
+	printk("smp_init_cpus\n");
+
+    set_smp_cross_call(gic_raise_softirq);
+}
+
+static void __init cnc19xx_smp_prepare_cpus(void)
+{
+	scu_enable(IO_ADDRESS(CNC1900_CA9_SCU));
+}
+
+void __init platform_smp_prepare_cpus(unsigned int max_cpus)
+{
+	cnc19xx_smp_prepare_cpus();
+}
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/arch/arm/mach-celestial/pmem.c linux-linaro-3.4-2012.05-1_cavium/arch/arm/mach-celestial/pmem.c
--- linux-linaro-3.4-2012.05-1_original/arch/arm/mach-celestial/pmem.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/arch/arm/mach-celestial/pmem.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,26 @@
+#include <linux/platform_device.h>
+#include <linux/android_pmem.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+
+static struct android_pmem_platform_data pmem_pdata = {
+    .name = "pmem",
+    .no_allocator = 0,
+    .cached = 0,
+    .start = PMEM_REGION,
+    .size  = PMEM_SIZE
+};
+            
+static struct platform_device pmem_dev = {
+    .name = "android_pmem",
+    .id = -1,
+    .dev = {
+		.platform_data = &pmem_pdata
+	},
+};
+
+__init int pmem_register(void)
+{
+	platform_device_register(&pmem_dev);
+}
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/arch/arm/mach-celestial/timer.c linux-linaro-3.4-2012.05-1_cavium/arch/arm/mach-celestial/timer.c
--- linux-linaro-3.4-2012.05-1_original/arch/arm/mach-celestial/timer.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/arch/arm/mach-celestial/timer.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,52 @@
+/*
+ * arch/arm/mach-celestial/timer.c
+ * Cavium CNC1900 Timer System, 2012
+ * 
+ * This file is licensed unde the terms of the GNU General Public License 
+ * version 2. This program is licensed "as is" without any warranty of 
+ * any kind, whether express or implied.
+ */
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/clocksource.h>
+#include <asm/mach/time.h>
+#include <asm/smp_twd.h>
+
+#include <mach/hardware.h>
+#include <mach/irqs.h>
+
+extern void __init plat_clock_init(void);
+
+static void __init gbl_clocksource_init(void)
+{
+	void __iomem *base = ioremap(CNC1900_CA9_GBL_TIMER, 0x1C);
+	struct clk *clk = clk_get_sys("smp_gbl", NULL);
+	unsigned long hz;
+
+	if (!base || !clk)
+		return;
+
+	__raw_writel(0, base + GBL_TIMER_CONTROL);
+	__raw_writel(0, base + GBL_TIMER_COUNTER_L);
+	__raw_writel(0, base + GBL_TIMER_COUNTER_H);
+	__raw_writel(0x0000FF01, base + GBL_TIMER_CONTROL);
+
+	hz = clk_get_rate(clk) / 256;
+	clocksource_mmio_init(base + GBL_TIMER_COUNTER_L, "smp_gbl", hz, 300, 32,
+		clocksource_mmio_readl_up);
+}
+
+static DEFINE_TWD_LOCAL_TIMER(local_timer, CNC1900_CA9_TWD, CPU_PRI_TIMER_IRQ);
+
+static void __init plat_timer_init(void)
+{
+	plat_clock_init();
+
+	gbl_clocksource_init();
+	twd_local_timer_register(&local_timer);
+}
+
+struct sys_timer plat_timer = {
+	.init = plat_timer_init,
+};
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/arch/arm/mach-celestial/usb.c linux-linaro-3.4-2012.05-1_cavium/arch/arm/mach-celestial/usb.c
--- linux-linaro-3.4-2012.05-1_original/arch/arm/mach-celestial/usb.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/arch/arm/mach-celestial/usb.c	2015-04-29 14:37:06.741752000 +0800
@@ -0,0 +1,110 @@
+#include <linux/kernel.h>
+#include <linux/utsname.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+
+#include <linux/usb/ohci_pdriver.h>
+#include <linux/usb/ehci_pdriver.h>
+#include <linux/usb/g_hid.h>
+
+#include <mach/hardware.h>
+#include <mach/irqs.h>
+
+#include <linux/export.h>
+#include <mach/usb.h>
+#include <linux/kobject.h>
+
+static u64 dmamask = DMA_BIT_MASK(32);
+
+static struct resource ehci_resources[] = {
+	{
+		.start = CNC1900_USB_EHCI,
+		.end   = CNC1900_USB_EHCI + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = EHCI_IRQ,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct usb_ehci_pdata pdata_ehci = {
+	.caps_offset = 0x100,
+};
+
+static struct platform_device dev_ehci = {
+	.name = "ehci-platform",
+	.id   = -1,
+	.dev  = {
+		.dma_mask = &dmamask,
+		.coherent_dma_mask = DMA_BIT_MASK(32),
+		.platform_data = &pdata_ehci,
+	},
+	.resource = ehci_resources,
+	.num_resources = ARRAY_SIZE(ehci_resources),
+};
+
+static struct resource ohci_resources[] = {
+	{
+		.start = CNC1900_USB_OHCI,
+		.end   = CNC1900_USB_OHCI + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = OHCI_IRQ,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct usb_ehci_pdata pdata_ohci = {
+};
+
+static struct platform_device dev_ohci = {
+	.name = "ohci-platform",
+	.id   = -1,
+	.dev  = {
+		.dma_mask = &dmamask,
+		.coherent_dma_mask = DMA_BIT_MASK(32),
+		.platform_data = &pdata_ohci,
+	},
+	.resource = ohci_resources,
+	.num_resources = ARRAY_SIZE(ohci_resources),
+};
+
+static struct resource otg_resources[] = {
+	{
+		.start = CNC1900_USB_OTG,
+		.end   = CNC1900_USB_OTG + SZ_256K - 1,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = OTG_IRQ,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device dev_otg = {
+	.name = "dwc_otg",
+	.id   = -1,
+	.dev  = {
+		.dma_mask = &dmamask,
+		.coherent_dma_mask = DMA_BIT_MASK(32),
+	},
+	.resource = otg_resources,
+	.num_resources = ARRAY_SIZE(otg_resources),
+};
+
+static struct platform_device *devices[] __initdata = {
+#ifdef CONFIG_CELESTIAL_HCI
+	&dev_ehci,
+	&dev_ohci,
+#endif
+#ifdef CONFIG_CELESTIAL_OTG
+	&dev_otg,
+#endif
+};
+
+int __init platform_add_usbs()
+{
+	platform_add_devices(devices, ARRAY_SIZE(devices));
+	return 0;
+}
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/arch/arm/Makefile linux-linaro-3.4-2012.05-1_cavium/arch/arm/Makefile
--- linux-linaro-3.4-2012.05-1_original/arch/arm/Makefile	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/arch/arm/Makefile	2014-07-29 17:28:38.819972000 +0800
@@ -197,7 +197,7 @@
 machine-$(CONFIG_MACH_SPEAR320)		:= spear3xx
 machine-$(CONFIG_MACH_SPEAR600)		:= spear6xx
 machine-$(CONFIG_ARCH_ZYNQ)		:= zynq
-
+machine-$(CONFIG_ARCH_CELESTIAL)    := celestial
 # Platform directory name.  This list is sorted alphanumerically
 # by CONFIG_* macro name.
 plat-$(CONFIG_ARCH_MXC)		:= mxc
@@ -267,7 +267,8 @@
 KBUILD_IMAGE := zImage
 endif
 
-all:	$(KBUILD_IMAGE)
+all: $(KBUILD_IMAGE)
+	cp arch/arm/mach-celestial/cnc19xx_mem_info.o  $(CNC_PLATFORM)/configs/cnc19xx_$(CUSTOMER_NAME)_mem_info.o
 
 boot := arch/arm/boot
 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/arch/arm/mm/cache-l2x0.c linux-linaro-3.4-2012.05-1_cavium/arch/arm/mm/cache-l2x0.c
--- linux-linaro-3.4-2012.05-1_original/arch/arm/mm/cache-l2x0.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/arch/arm/mm/cache-l2x0.c	2014-07-29 17:28:38.819972000 +0800
@@ -23,6 +23,10 @@
 #include <linux/of.h>
 #include <linux/of_address.h>
 
+#ifdef CONFIG_SW_SUPPORT
+#include <mach/smc.h>
+#endif
+
 #include <asm/cacheflush.h>
 #include <asm/hardware/cache-l2x0.h>
 
@@ -353,6 +357,9 @@
 {
 	u32 aux;
 	u32 way_size = 0;
+#ifdef CONFIG_SW_SUPPORT
+	u32 pctrl, val;
+#endif
 	const char *type;
 
 	l2x0_base = base;
@@ -402,6 +409,21 @@
 	l2x0_size = l2x0_ways * way_size;
 	l2x0_sets = way_size / CACHE_LINE_SIZE;
 
+#ifdef CONFIG_SW_SUPPORT /* Sierraware Tzone support */
+	pctrl = readl(l2x0_base + L2X0_POWER_CTRL); //read power control register of L2 cache
+	pctrl = pctrl | 0x3;                         //prepare data
+
+	aux &= aux_mask;
+	aux |= aux_val;
+
+	/* SETUP2: arg1 - power ctrl, arg2 - aux ctrl, 
+	 *  arg3 - aux mask  
+	 */
+	sw_smc(SMC_CMD_L2X0SETUP1, pctrl, aux, aux_mask);
+
+	/* Init and Enable L2 cache */
+	sw_smc(SMC_CMD_L2X0CTRL, 1, 0, 0);
+#else
 	/*
 	 * Check if l2x0 controller is already enabled.
 	 * If you are booting from non-secure mode
@@ -424,7 +446,7 @@
 		/* enable L2X0 */
 		writel_relaxed(1, l2x0_base + L2X0_CTRL);
 	}
-
+#endif
 	outer_cache.inv_range = l2x0_inv_range;
 	outer_cache.clean_range = l2x0_clean_range;
 	outer_cache.flush_range = l2x0_flush_range;
@@ -432,7 +454,10 @@
 	outer_cache.flush_all = l2x0_flush_all;
 	outer_cache.inv_all = l2x0_inv_all;
 	outer_cache.disable = l2x0_disable;
-
+#ifdef CONFIG_SW_SUPPORT
+	val = readl_relaxed(l2x0_base + L2X0_CTRL);
+	pr_err("<<>>l2x0: l2x0 ctrl = %d\n", val);
+#endif
 	printk(KERN_INFO "%s cache controller enabled\n", type);
 	printk(KERN_INFO "l2x0: %d ways, CACHE_ID 0x%08x, AUX_CTRL 0x%08x, Cache size: %d B\n",
 			l2x0_ways, l2x0_cache_id, aux, l2x0_size);
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/arch/arm/mm/Kconfig linux-linaro-3.4-2012.05-1_cavium/arch/arm/mm/Kconfig
--- linux-linaro-3.4-2012.05-1_original/arch/arm/mm/Kconfig	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/arch/arm/mm/Kconfig	2014-07-29 17:28:38.819972000 +0800
@@ -883,7 +883,6 @@
 
 config ARM_L1_CACHE_SHIFT_6
 	bool
-	default y if CPU_V7
 	help
 	  Setting ARM L1 cache line size to 64 Bytes.
 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/arch/arm/mm/proc-v7.S linux-linaro-3.4-2012.05-1_cavium/arch/arm/mm/proc-v7.S
--- linux-linaro-3.4-2012.05-1_original/arch/arm/mm/proc-v7.S	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/arch/arm/mm/proc-v7.S	2014-07-29 17:28:38.819972000 +0800
@@ -243,6 +243,13 @@
 	mcrlt	p15, 0, r10, c15, c0, 1		@ write diagnostic register
 1:
 #endif
+	
+#ifndef CONFIG_SW_SUPPORT /* Sierraware Trustzone */
+	@enable high-level clock gating of cortex-a9	
+	mrc p15, 0, r10, c15, c0, 0  	@read power control register	
+	orr r10, r10, #1             	@prepare data
+	mcr p15, 0, r10, c15, c0, 0  	@write power control register
+#endif
 
 3:	mov	r10, #0
 	mcr	p15, 0, r10, c7, c5, 0		@ I+BTB cache invalidate
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/arch/arm/tools/mach-types linux-linaro-3.4-2012.05-1_cavium/arch/arm/tools/mach-types
--- linux-linaro-3.4-2012.05-1_original/arch/arm/tools/mach-types	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/arch/arm/tools/mach-types	2014-07-29 17:28:38.819972000 +0800
@@ -289,6 +289,7 @@
 trizeps4wl		MACH_TRIZEPS4WL		TRIZEPS4WL		1649
 ts78xx			MACH_TS78XX		TS78XX			1652
 sffsdr			MACH_SFFSDR		SFFSDR			1657
+celestial	    MACH_CELESTIAL	    CELESTIAL 		1662
 pcm037			MACH_PCM037		PCM037			1673
 db88f6281_bp		MACH_DB88F6281_BP	DB88F6281_BP		1680
 rd88f6192_nas		MACH_RD88F6192_NAS	RD88F6192_NAS		1681
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/build.sh linux-linaro-3.4-2012.05-1_cavium/build.sh
--- linux-linaro-3.4-2012.05-1_original/build.sh	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/build.sh	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,16 @@
+if [ -z "$CNC_PLATFORM" ]; then
+echo "*** ERROR: ${CNC_PLATFORM} is not a directory"
+exit
+fi	
+
+cp ${CNC_PLATFORM}/configs/kernel_config arch/arm/configs/cnc83xx_temp_defconfig
+make distclean;
+make cnc83xx_temp_defconfig
+make uImage -j24
+cp ./arch/arm/boot/uImage ${CNC_PLATFORM}/images
+UpdateVersionInfo.sh ${CNC_PLATFORM}/images/version.info uImage	${PWD}
+
+cnc_mem_info ./arch/arm/mach-celestial/cnc19xx_mem_info.o     ${CNC_PLATFORM}/configs/cnc19xx_${CUSTOMER_NAME}_mem_info.inc
+cat ${CNC_PLATFORM}/configs/cnc19xx_${CUSTOMER_NAME}_mem_info.inc
+UpdateVersionInfo.sh ${CNC_PLATFORM}/configs/version.info cnc19xx_${CUSTOMER_NAME}_mem_info.inc	${PWD}
+
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/debian/commit-templates/bumpabi linux-linaro-3.4-2012.05-1_cavium/debian/commit-templates/bumpabi
--- linux-linaro-3.4-2012.05-1_original/debian/commit-templates/bumpabi	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/debian/commit-templates/bumpabi	1970-01-01 08:00:00.000000000 +0800
@@ -1,3 +0,0 @@
-UBUNTU: Bump ABI
-
-Ignore: yes
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/debian/commit-templates/config-updates linux-linaro-3.4-2012.05-1_cavium/debian/commit-templates/config-updates
--- linux-linaro-3.4-2012.05-1_original/debian/commit-templates/config-updates	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/debian/commit-templates/config-updates	1970-01-01 08:00:00.000000000 +0800
@@ -1,15 +0,0 @@
-#
-# This template is used for commit messages that don't need to
-# show up in debian/changelog. Administrative stuff like config
-# updates, ABI bumps, etc. Setting 'Ignore: yes' prevents
-# 'debian/rules insertchanges' from inserting this commit meesage
-# as a changelog entry.
-#
-# Please give a one-line description of the config change followed
-# by a detailed explanation if necessary
-
-UBUNTU: [Config] XXXX
-
-# BugLink: http://bugs.launchpad.net/bugs/<enter bug# here>
-# Ignore: yes
-# Other text below here.
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/debian/commit-templates/external-driver linux-linaro-3.4-2012.05-1_cavium/debian/commit-templates/external-driver
--- linux-linaro-3.4-2012.05-1_original/debian/commit-templates/external-driver	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/debian/commit-templates/external-driver	1970-01-01 08:00:00.000000000 +0800
@@ -1,20 +0,0 @@
-# Ubuntu external driver commit.
-#
-# NOTE: This gets reformatted for README.Ubuntu-External-Drivers and
-# debian/changelog.
-#
-# This is only needed when a driver is added, updated or removed. It is
-# not needed when patches or fixes are applied to the driver. If the
-# driver is being removed, add the line:
-#
-# Removing: yes
-#
-# to the commit, and you can remove all other tags (except UBUNTU:).
-#
-UBUNTU: 
-
-ExternalDriver: 
-Description:
-Url:
-Mask:
-Version:
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/debian/commit-templates/missing-modules linux-linaro-3.4-2012.05-1_cavium/debian/commit-templates/missing-modules
--- linux-linaro-3.4-2012.05-1_original/debian/commit-templates/missing-modules	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/debian/commit-templates/missing-modules	1970-01-01 08:00:00.000000000 +0800
@@ -1,3 +0,0 @@
-UBUNTU: build/modules: Add modules that have intentionally gone missing
-
-Ignore: yes
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/debian/commit-templates/newrelease linux-linaro-3.4-2012.05-1_cavium/debian/commit-templates/newrelease
--- linux-linaro-3.4-2012.05-1_original/debian/commit-templates/newrelease	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/debian/commit-templates/newrelease	1970-01-01 08:00:00.000000000 +0800
@@ -1,3 +0,0 @@
-LINARO: Start new release
-
-Ignore: yes
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/debian/commit-templates/sauce-patch linux-linaro-3.4-2012.05-1_cavium/debian/commit-templates/sauce-patch
--- linux-linaro-3.4-2012.05-1_original/debian/commit-templates/sauce-patch	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/debian/commit-templates/sauce-patch	1970-01-01 08:00:00.000000000 +0800
@@ -1,40 +0,0 @@
-# Ubuntu commit template.
-#
-# NOTE: This gets reformatted for debian/changelog
-#
-#
-# SAUCE refers to the fact that this patch might not go upstream, but we need to
-# carry it to successive releases. In most cases you DONOT want to use this
-# template. 
-#
-# An example of a SAUCE patch is the ACPI DSDT-in-initramfs patch which has been
-# refused upstream, but still provides useful functionality to users with broken
-# BIOSes.
-#
-#-------------------------------------------------------------------------
-#
-# The initial UBUNTU is a flag that this is an Ubuntu commit. It will be
-# referenced to the Author in the debian/changelog entry.
-#
-# The text following is the short message that will be placed in the
-# changelog. Extra text on the following lines will be ignored, but left
-# in the git commit. Lines with # will be ignored in the commit.
-#
-# OriginalAuthor allows for alternate attribution.
-#
-# OriginalLocation allows for a URL or description of where the patch came
-# from.
-#
-# BugLink is a URL to a Malone bug.
-#
-# Ignore: yes will keep this commit from showing up in the changelog.
-#
-UBUNTU: SAUCE: 
-
-<Why is this patch not going upstream?>
-
-# OriginalAuthor: 
-# OriginalLocation: 
-# BugLink: http://bugs.launchpad.net/bugs/<enter bug# here>
-# Ignore: yes
-# Other text below here.
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/debian/commit-templates/upstream-patch linux-linaro-3.4-2012.05-1_cavium/debian/commit-templates/upstream-patch
--- linux-linaro-3.4-2012.05-1_original/debian/commit-templates/upstream-patch	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/debian/commit-templates/upstream-patch	1970-01-01 08:00:00.000000000 +0800
@@ -1,27 +0,0 @@
-# Ubuntu commit template.
-#
-# NOTE: This gets reformatted for debian/changelog
-#
-# The initial UBUNTU is a flag that this is an Ubuntu commit. It will be
-# referenced to the Author in the debian/changelog entry.
-#
-# The text following is the short message that will be placed in the
-# changelog. Extra text on the following lines will be ignored, but left
-# in the git commit. Lines with # will be ignored in the commit.
-#
-# OriginalAuthor allows for alternate attribution.
-#
-# OriginalLocation allows for a URL or description of where the patch came
-# from.
-#
-# BugLink is a URL to a Malone bug.
-#
-# Ignore: yes will keep this commit from showing up in the changelog.
-#
-UBUNTU: [Upstream]
-
-# OriginalAuthor: 
-# OriginalLocation: 
-# BugLink: http://bugs.launchpad.net/bugs/<enter bug# here>
-# Ignore: yes
-# Other text below here.
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/debian/compat linux-linaro-3.4-2012.05-1_cavium/debian/compat
--- linux-linaro-3.4-2012.05-1_original/debian/compat	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/debian/compat	1970-01-01 08:00:00.000000000 +0800
@@ -1 +0,0 @@
-5
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/debian/control-scripts/headers-postinst linux-linaro-3.4-2012.05-1_cavium/debian/control-scripts/headers-postinst
--- linux-linaro-3.4-2012.05-1_original/debian/control-scripts/headers-postinst	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/debian/control-scripts/headers-postinst	1970-01-01 08:00:00.000000000 +0800
@@ -1,126 +0,0 @@
-#!/usr/bin/perl
-#                              -*- Mode: Cperl -*- 
-# debian.postinst ---
-# Author           : Manoj Srivastava ( srivasta@pilgrim.umass.edu )
-# Created On       : Sat Apr 27 05:42:43 1996
-# Created On Node  : melkor.pilgrim.umass.edu
-# Last Modified By : Manoj Srivastava
-# Last Modified On : Sat Aug  5 13:20:22 2006
-# Last Machine Used: glaurung.internal.golden-gryphon.com
-# Update Count     : 45
-# Status           : Unknown, Use with caution!
-# HISTORY          :
-# Description      :
-#
-#
-#
-#  arch-tag: 1c716174-2f0a-476d-a626-a1322e62503a
-#
-
-
-$|=1;
-
-# Predefined values:
-my $version           = "=V";
-my $kimage            = "=K";
-my $package_name    = "linux-image-$version";
-
-
-# Ignore all invocations uxcept when called on to configure.
-exit 0 unless ($ARGV[0] && $ARGV[0] =~ /configure/);
-
-#known variables
-my $image_dest      = "/";
-my $realimageloc    = "/boot/";
-my $silent_modules  = '';
-my $modules_base    = '/lib/modules';
-my $CONF_LOC        = '/etc/kernel-img.conf';
-# remove multiple leading slashes; make sure there is at least one.
-$realimageloc  =~ s|^/*|/|o;
-$realimageloc  =~ s|/+|/|o;
-
-chdir '/usr/src' or die "Could not chdir to /usr/src:$!";
-
-if (-r "$CONF_LOC" && -f "$CONF_LOC"  ) {
-  if (open(CONF, "$CONF_LOC")) {
-    while (<CONF>) {
-      chomp;
-      s/\#.*$//g;
-      next if /^\s*$/;
-
-      $header_postinst_hook   = "$1"  if /^\s*header_postinst_hook\s*=\s*(\S+)/ig;
-    }
-    close CONF;
-  }
-}
-
-sub exec_script {
-  my $type   = shift;
-  my $script = shift;
-  print STDERR "Running $type hook script $script.\n";
-  system ("$script $version $realimageloc$kimage-$version") &&
-    print STDERR "User $type hook script [$script] ";
-  if ($?) {
-    if ($? == -1) {
-      print STDERR "failed to execute: $!\n";
-    }
-    elsif ($? & 127) {
-      printf STDERR "died with signal %d, %s coredump\n",
-        ($? & 127),  ($? & 128) ? 'with' : 'without';
-    }
-    else {
-      printf STDERR "exited with value %d\n", $? >> 8;
-    }
-    exit $? >> 8;
-  }
-}
-sub run_hook {
-  my $type   = shift;
-  my $script = shift;
-  if ($script =~ m,^/,) {
-    # Full path provided for the hook script
-    if (-x "$script") {
-      &exec_script($type,$script);
-    }
-    else {
-      die "The provided $type hook script [$script] could not be run.\n";
-    }
-  }
-  else {
-    # Look for it in a safe path
-    for my $path ('/bin', '/sbin', '/usr/bin', '/usr/sbin') {
-      if (-x "$path/$script") {
-        &exec_script($type, "$path/$script");
-        return 0;
-      }
-    }
-    # No luck
-    print STDERR "Could not find $type hook script [$script].\n";
-    die "Looked in: '/bin', '/sbin', '/usr/bin', '/usr/sbin'\n";
-  }
-}
-
-## Run user hook script here, if any
-if (-x "$header_postinst_hook") {
-  &run_hook("postinst", $header_postinst_hook);
-}
-
-if (-d "/etc/kernel/header_postinst.d") {
-  print STDERR "Examining /etc/kernel/header_postinst.d.\n";
-  system ("run-parts --verbose --exit-on-error --arg=$version " .
-          "--arg=$realimageloc$kimage-$version " .
-          "/etc/kernel/header_postinst.d") &&
-            die "Failed to process /etc/kernel/header_postinst.d";
-}
-
-if (-d "/etc/kernel/header_postinst.d/$version") {
-  print STDERR "Examining /etc/kernel/header_postinst.d/$version.\n";
-  system ("run-parts --verbose --exit-on-error --arg=$version " .
-          "--arg=$realimageloc$kimage-$version " .
-          "/etc/kernel/header_postinst.d/$version") &&
-            die "Failed to process /etc/kernel/header_postinst.d/$version";
-}
-
-exit 0;
-
-__END__
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/debian/control-scripts/postinst linux-linaro-3.4-2012.05-1_cavium/debian/control-scripts/postinst
--- linux-linaro-3.4-2012.05-1_original/debian/control-scripts/postinst	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/debian/control-scripts/postinst	1970-01-01 08:00:00.000000000 +0800
@@ -1,1095 +0,0 @@
-#! /usr/bin/perl
-# OriginalAuthor : Manoj Srivastava ( srivasta@pilgrim.umass.edu )
-#
-# Customized for Ubuntu by: Ben Collins <bcollins@ubuntu.com>
-
-#use strict; #for debugging
-use Cwd 'abs_path';
-
-$|=1;
-
-# Predefined values:
-my $version           = "=V";
-my $link_in_boot      = "";  # Should be empty, mostly
-my $no_symlink        = "";   # Should be empty, mostly
-my $reverse_symlink   = "";   # Should be empty, mostly
-my $do_symlink        = "Yes";  # target machine defined
-my $do_boot_enable    = "Yes";  # target machine defined
-my $do_bootfloppy     = "Yes";  # target machine defined
-my $do_bootloader     = "Yes";  # target machine defined
-my $move_image        = '';     # target machine defined
-my $kimage            = "=K";   # Should be empty, mostly
-my $loader            = "=L"; # lilo, silo, quik, palo, vmelilo, nettrom, arcboot or delo
-my $image_dir         = "/boot";        # where the image is located
-my $clobber_modules   = '';          # target machine defined
-my $relative_links    = "";          # target machine defined
-my $initrd            = "YES";        # initrd kernel
-my $do_initrd         = '';     # Normally we do not
-my $use_hard_links    = ''; # hardlinks do not work across fs boundaries
-my $postinst_hook     = '';          #Normally we do not
-my $postrm_hook       = '';          #Normally we do not
-my $preinst_hook      = '';          #Normally we do not
-my $prerm_hook        = '';          #Normally we do not
-my $minimal_swap      = '';          # Do not swap symlinks
-my $ignore_depmod_err = '';          # normally we do not
-my $kernel_arch       = "=B";
-my $ramdisk           = "/usr/sbin/update-initramfs";  # List of tools to create initial ram fs.
-my $notifier          = "/usr/share/update-notifier/notify-reboot-required";
-my $package_name      = "linux-image-$version";
-my $explicit_do_loader = 'Yes';
-
-my $Loader          = "NoLOADER"; #
-$Loader             = "LILO"     if $loader =~ /^lilo/io;
-$Loader             = "SILO"     if $loader =~ /^silo/io;
-$Loader             = "QUIK"     if $loader =~ /^quik/io;
-$Loader             = "yaboot"   if $loader =~ /^yaboot/io;
-$Loader             = "PALO"     if $loader =~ /^palo/io;
-$Loader             = "NETTROM"  if $loader =~ /^nettrom/io;
-$Loader             = "VMELILO"  if $loader =~ /^vmelilo/io;
-$Loader             = "ZIPL"     if $loader =~ /^zipl/io;
-$Loader             = "ELILO"    if $loader =~ /^elilo/io;
-$Loader             = "ARCBOOT"  if $loader =~ /^arcboot/io;
-$Loader             = "DELO"     if $loader =~ /^delo/io;
-
-# This should not point to /tmp, because of security risks.
-my $temp_file_name = "/var/log/$loader" . "_log.$$";
-
-#known variables
-my $image_dest      = "/";
-my $realimageloc    = "/$image_dir/";
-my $have_conffile   = "";
-my $silent_modules  = '';
-my $silent_loader   = '';
-my $warn_reboot     = 'Yes';     # Warn that we are installing a version of
-                                 # the kernel we are running
-
-my $modules_base    = '/lib/modules';
-my $CONF_LOC        = '/etc/kernel-img.conf';
-
-# Ignore all invocations except when called on to configure.
-exit 0 unless $ARGV[0] =~ /configure/;
-
-my $DEBUG = 0;
-
-# Do some preliminary sanity checks here to ensure we actually have an
-# valid image dir
-chdir('/')           or die "could not chdir to /:$!\n";
-die "Internal Error: ($image_dir) is not a directory!\n"
-  unless -d $image_dir;
-
-# remove multiple leading slashes; make sure there is at least one.
-$realimageloc  =~ s|^/*|/|o;
-$realimageloc  =~ s|/+|/|o;
-die "Internal Error: ($realimageloc) is not a directory!\n"
-  unless -d $realimageloc;
-
-if (-r "$CONF_LOC" && -f "$CONF_LOC"  ) {
-  if (open(CONF, "$CONF_LOC")) {
-    while (<CONF>) {
-      chomp;
-      s/\#.*$//g;
-      next if /^\s*$/;
-
-      $do_symlink      = "" if /^\s*do_symlinks\s*=\s*(no|false|0)\s*$/ig;
-      $no_symlink      = "" if /^\s*no_symlinks\s*=\s*(no|false|0)\s*$/ig;
-      $reverse_symlink = "" if /^\s*reverse_symlink\s*=\s*(no|false|0)\s*$/ig;
-      $link_in_boot    = "" if /^\s*image_in_boot\s*=\s*(no|false|0)\s*$/ig;
-      $link_in_boot    = "" if /^\s*link_in_boot\s*=\s*(no|false|0)\s*$/ig;
-      $move_image      = "" if /^\s*move_image\s*=\s*(no|false|0)\s*$/ig;
-      $clobber_modules = '' if /^\s*clobber_modules\s*=\s*(no|false|0)\s*$/ig;
-      $do_boot_enable  = '' if /^\s*do_boot_enable\s*=\s*(no|false|0)\s*$/ig;
-      $do_bootfloppy   = '' if /^\s*do_bootfloppy\s*=\s*(no|false|0)\s*$/ig;
-      $relative_links  = '' if /^\s*relative_links \s*=\s*(no|false|0)\s*$/ig;
-      $do_bootloader   = '' if /^\s*do_bootloader\s*=\s*(no|false|0)\s*$/ig;
-      $explicit_do_loader = '' if /^\s*do_bootloader\s*=\s*(no|false|0)\s*$/ig;
-      $do_initrd       = '' if /^\s*do_initrd\s*=\s*(no|false|0)\s*$/ig;
-      $use_hard_links  = '' if /^\s*use_hard_links\s*=\s*(no|false|0)\s*$/ig;
-      $silent_modules  = '' if /^\s*silent_modules\s*=\s*(no|false|0)\s*$/ig;
-      $silent_loader   = '' if /^\s*silent_loader\s*=\s*(no|false|0)\s*$/ig;
-      $warn_reboot     = '' if /^\s*warn_reboot\s*=\s*(no|false|0)\s*$/ig;
-      $minimal_swap    = '' if /^\s*minimal_swap\s*=\s*(no|false|0)\s*$/ig;
-      $ignore_depmod_err = '' if /^\s*ignore_depmod_err\s*=\s*(no|false|0)\s*$/ig;
-
-      $do_symlink      = "Yes" if /^\s*do_symlinks\s*=\s*(yes|true|1)\s*$/ig;
-      $no_symlink      = "Yes" if /^\s*no_symlinks\s*=\s*(yes|true|1)\s*$/ig;
-      $reverse_symlink = "Yes" if /^\s*reverse_symlinks\s*=\s*(yes|true|1)\s*$/ig;
-      $link_in_boot    = "Yes" if /^\s*image_in_boot\s*=\s*(yes|true|1)\s*$/ig;
-      $link_in_boot    = "Yes" if /^\s*link_in_boot\s*=\s*(yes|true|1)\s*$/ig;
-      $move_image      = "Yes" if /^\s*move_image\s*=\s*(yes|true|1)\s*$/ig;
-      $clobber_modules = "Yes" if /^\s*clobber_modules\s*=\s*(yes|true|1)\s*$/ig;
-      $do_boot_enable  = "Yes" if /^\s*do_boot_enable\s*=\s*(yes|true|1)\s*$/ig;
-      $do_bootfloppy   = "Yes" if /^\s*do_bootfloppy\s*=\s*(yes|true|1)\s*$/ig;
-      $do_bootloader   = "Yes" if /^\s*do_bootloader\s*=\s*(yes|true|1)\s*$/ig;
-      $explicit_do_loader = "YES" if /^\s*do_bootloader\s*=\s*(yes|true|1)\s*$/ig;
-      $relative_links  = "Yes" if /^\s*relative_links\s*=\s*(yes|true|1)\s*$/ig;
-      $do_initrd       = "Yes" if /^\s*do_initrd\s*=\s*(yes|true|1)\s*$/ig;
-      $use_hard_links  = "Yes" if /^\s*use_hard_links\s*=\s*(yes|true|1)\s*$/ig;
-      $silent_modules  = 'Yes' if /^\s*silent_modules\s*=\s*(yes|true|1)\s*$/ig;
-      $silent_loader   = 'Yes' if /^\s*silent_loader\s*=\s*(yes|true|1)\s*$/ig;
-      $warn_reboot     = 'Yes' if /^\s*warn_reboot\s*=\s*(yes|true|1)\s*$/ig;
-      $minimal_swap    = 'Yes' if /^\s*minimal_swap\s*=\s*(yes|true|1)\s*$/ig;
-      $ignore_depmod_err = 'Yes' if /^\s*ignore_depmod_err\s*=\s*(yes|true|1)\s*$/ig;
-
-      $image_dest      = "$1"  if /^\s*image_dest\s*=\s*(\S+)/ig;
-      $postinst_hook   = "$1"  if /^\s*postinst_hook\s*=\s*(\S+)/ig;
-      $postrm_hook     = "$1"  if /^\s*postrm_hook\s*=\s*(\S+)/ig;
-      $preinst_hook    = "$1"  if /^\s*preinst_hook\s*=\s*(\S+)/ig;
-      $prerm_hook      = "$1"  if /^\s*prerm_hook\s*=\s*(\S+)/ig;
-      $ramdisk         = "$1"  if /^\s*ramdisk\s*=\s*(.+)$/ig;
-    }
-    close CONF;
-    $have_conffile = "Yes";
-  }
-}
-
-
-
-# For some versions of kernel-package, we had this warning in the
-# postinst, but the rules did not really interpolate the value in.
-# Here is a sanity check.
-my $pattern = "=" . "I";
-$initrd=~ s/^$pattern$//;
-
-if ($link_in_boot) {
-  $image_dest = "/$image_dir/"; # same as realimageloc
-}
-
-# Tack on at least one trainling /
-$image_dest = "$image_dest/";
-$image_dest =~ s|^/*|/|o;
-$image_dest =~ s|/+$|/|o;
-
-if (! -d "$image_dest") {
-  die "Expected Image Destination dir ($image_dest) to be a valid directory!\n";
-}
-
-# sanity
-if (!($do_bootfloppy || $do_bootloader)) {
-  $do_boot_enable = '';
-}
-if ($do_symlink && $no_symlink) {
-  warn "Both do_symlinks and no_symlinks options enabled; disabling no_symlinks\n";
-  $no_symlink = 0;
-}
-
-# most of our work is done in $image_dest (nominally /)
-chdir("$image_dest") or die "could not chdir to $image_dest:$!\n";
-
-# Paranoid check to make sure that the correct value is put in there
-if    (! $kimage)                 { $kimage = "vmlinuz"; } # Hmm. empty
-elsif ($kimage =~ m/^b?uImage$/o) { $kimage = "vmlinuz"; } # these produce vmlinuz
-elsif ($kimage =~ m/^b?zImage$/o) { $kimage = "vmlinuz"; } # these produce vmlinuz
-elsif ($kimage =~ m/^[iI]mage$/o) { my $nop = $kimage;   }
-elsif ($kimage =~ m/^vmlinux$/o)  { my $nop = $kimage;   }
-else                              { $kimage = "vmlinuz"; } # Default
-
-$ENV{KERNEL_ARCH}=$kernel_arch if $kernel_arch;
-
-
-die "Internal Error: Could not find image (" . $realimageloc
-  . "$kimage-$version)\n" unless -e $realimageloc
-  . "$kimage-$version";
-
-# search for the boot loader in the path
-my $loader_exec;
-($loader_exec = $loader)  =~ s|.*/||;
-my ($loaderloc) = grep -x, map "$_/$loader_exec",
-  map { length($_) ? $_ : "." }  split /:/, $ENV{PATH};
-
-
-######################################################################
-######################################################################
-###########        Test whether a relative symlinkwould be OK #######
-######################################################################
-######################################################################
-sub test_relative {
-  my %params = @_;
-  my $cwd;
-
-  die "Internal Error: Missing Required paramater 'Old Dir' "
-    unless $params{'Old Dir'};
-  die "Internal Error: Missing Required paramater New Dir' "
-    unless $params{'New Dir'};
-
-
-  die "Internal Error: No such dir $params{'Old Dir'} "
-    unless -d $params{'Old Dir'};
-  die "Internal Error: No such dir $params{'New Dir'} "
-    unless -d $params{'New Dir'};
-
-  warn "Test relative: testing $params{'Old Dir'} -> $params{'New Dir'}"
-    if $DEBUG;
-  chomp($cwd = `pwd`);
-  chdir ($params{'New Dir'}) or die "Could not chdir to $params{'New Dir'}:$!";
-  my $ok = 0;
-  $params{'Old Dir'}  =~ s|^/*||o;
-  if (-d $params{'Old Dir'} ) {
-    if (defined $params{'Test File'}) {
-      if (-e $params{'Old Dir'} . $params{'Test File'}) {
-        $ok  = 1;
-      }
-    } else {
-      $ok = 1;                  # well, backward compatibility
-    }
-  }
-  chdir ($cwd) or die "Could not chdir to $params{'New Dir'}:$!";
-  return $ok;
-}
-
-######################################################################
-######################################################################
-############
-######################################################################
-######################################################################
-# sub CanonicalizePath {
-#   my $path = join '/', @_;
-#   my @work = split '/', $path;
-#   my @out;
-#   my $is_absolute;
-
-#   if (@work && $work[0] eq "") {
-#     $is_absolute = 1; shift @work;
-#   }
-
-#   while (@work) {
-#     my $seg = shift @work;
-#     if ($seg eq "." || $seg eq "") {
-#     } 
-#     elsif ($seg eq "..") {
-#       if (@out && $out[-1] ne "..") {
-#         pop @out;
-#       } 
-#       else {
-#         # Leading "..", or "../..", etc.
-#         push @out, $seg;
-#       }
-#     } 
-#     else {
-#       push @out, $seg;
-#     }
-#   }
-
-#   unshift @out, "" if $is_absolute;
-#   return join('/', @out);
-# }
-######################################################################
-######################################################################
-############
-######################################################################
-######################################################################
-
-sub spath {
-  my %params = @_;
-
-  die "Missing Required paramater 'Old'" unless $params{'Old'};
-  die "Missing Required paramater 'New'" unless  $params{'New'};
-
-  my @olddir  = split '/', `readlink -q -m $params{'Old'}`;
-  my @newdir  = split '/', `readlink -q -m $params{'New'}`;
-  my @outdir  = @olddir;
-
-  my $out = '';
-  my $i;
-  for ($i = 0; $i <= $#olddir && $i <= $#newdir; $i++) {
-    $out++ if ($olddir[$i] ne $newdir[$i]);
-    shift @outdir unless $out;
-    unshift @outdir, ".." if $out;
-  }
-  if ($#newdir > $#olddir) {
-    for ($i=0; $i < $#newdir; $i++) {
-      unshift @outdir, "..";
-    }
-  }
-  return join ('/', @outdir);
-}
-######################################################################
-######################################################################
-############
-######################################################################
-######################################################################
-
-
-# This routine actually moves the kernel image
-# From: $realimageloc/$kimage-$version (/boot/vmlinuz-2.6.12)
-# To:   $image_dest/$kimage-$version   (/vmlinuz-2.6.12)
-# Note that the image is moved to a versioned destination, but ordinary
-# symlinks we create otherwise are not normally versioned
-sub really_move_image {
-  my $src_dir  = $_[0];
-  my $target   = $_[1];
-  my $dest_dir = $_[2];
-
-  warn "Really move image: src_dir=$src_dir, target=$target,\n destdir=$dest_dir"
-    if $DEBUG;
-  if (-e "$target") {
-    # we should be in dir $dest_dir == $image_dest /, normally
-    rename("$target", "$target.$$") ||
-      die "failed to move " . $dest_dir . "$target:$!";
-    warn "mv $target $target.$$" if $DEBUG;
-  }
-  warn "mv -f $src_dir$target $target" if $DEBUG;
-  my $ret = system("mv -f " . $src_dir . "$target " .
-                   " $target");
-  if ($ret) {
-    die("Failed to move " . $src_dir . "$target to "
-        . $dest_dir . "$target.\n");
-  }
-  # Ok, now we may clobber the previous .old files
-  if (-e "$target.$$") {
-    rename("$target.$$", "$target.old") ||
-      die "failed to move " . $dest_dir . "$target:$!";
-    warn "mv $target.$$ $target " if $DEBUG;
-  }
-}
-
-# Normally called after really_move_image; and only called if we asked for 
-# reversed link this routine reverses the symbolic link that is notmally 
-# created. Since the real kernel image has been moved over to 
-# $image_dest/$kimage-$version. So, this routine links
-# From:   $image_dest/$kimage-$version   (/vmlinuz-2.6.12)
-# To:     $realimageloc/$kimage-$version (/boot/vmlinuz-2.6.12)
-sub really_reverse_link {
-  my $src_dir    = $_[0];
-  my $link_name  = $_[1];
-  my $dest_dir   = $_[2];
-  warn "Really reverse link: src_dir=$src_dir, link name=$link_name\n" .
-    "\tdestdir=$dest_dir" if $DEBUG;
-
-  my $Old = $dest_dir;
-  if (test_relative ('Old Dir' => $Old, 'New Dir' => $src_dir,
-                     'Test File' => "$link_name")) {
-    $Old   =~ s|^/*||o;
-  }
-  # Special case is they are in the same dir
-  my $rel_path = spath('Old' => "$Old", 'New' => "$src_dir" );
-  $Old ="" if $rel_path =~ m/^\s*$/o;
-
-  if ($use_hard_links =~ m/YES/i) {
-    link($Old . "$link_name", $src_dir . "$link_name") ||
-      die("Failed to link " . $dest_dir . "$link_name to " . $src_dir . 
-          "$link_name .\n");
-    warn "ln " . $Old . "$link_name " . $src_dir . "$link_name"  if $DEBUG;
-  }
-  else {
-    symlink($Old . "$link_name", $src_dir . "$link_name") ||
-      die("Failed to symbolic-link " . $dest_dir . "$link_name to " . $src_dir
-          . "$link_name : $!\n");
-    warn "ln -s " . $Old . "$link_name " . $src_dir . "$link_name" if $DEBUG;
-  }
-}
-
-# This routine is invoked if there is a symbolic link in place
-# in $image_dest/$kimage -- so a symlink exists in the destination.
-# What we are trying to determine is if we need to move the symbolic link over
-# to the the .old location
-sub move_p {
-  my $kimage     = $_[0];       # Name of the symbolic link
-  my $image_dest = $_[1];       # The directory the links goes into
-  my $image_name = $_[2]; 
-  my $src_dir    = $_[3]; 
-  my $force_move = 0;
-  warn "Move?: kimage=$kimage, image_dest=$image_dest, \n" .
-    "\timage_name=$image_name, src_dir=$src_dir" if $DEBUG;
-
-  if ($no_symlink || $reverse_symlink) {
-    # we do not want links, yet we have a symbolic link here!
-    warn "found a symbolic link in " . $image_dest . "$kimage \n" .
-      "even though no_symlink is defined\n" if $no_symlink;
-    warn "found a symbolic link in " . $image_dest . "$kimage \n" .
-      "even though reverse_symlink is defined\n" if $reverse_symlink;
-    # make sure we change this state of affairs
-    $force_move = 1;
-    return $force_move;
-  }
-
-  warn "DEBUG: OK. We found symlink, and we should have a symlink here.\n"
-    if $DEBUG;
-  my $vmlinuz_target = readlink "$kimage";
-  my $real_target = '';
-  my $target = `readlink -q -m "${realimageloc}${kimage-$version}"`;
-  $real_target = abs_path($vmlinuz_target) if defined($vmlinuz_target);
-
-  if (!defined($vmlinuz_target) || ! -f "$real_target") {
-    # what, a dangling symlink?
-    warn "The link "  . $image_dest . "$kimage is a dangling link" .
-      "to $real_target\n";
-    $force_move = 1;
-    return $force_move;
-  }
-
-
-  warn "DEBUG: The link $kimage points to ($vmlinuz_target)\n" if $DEBUG;
-  warn "DEBUG: ($vmlinuz_target) is really ($real_target)\n" if $DEBUG;
-  my $cwd;
-  chomp ($cwd=`pwd`);
-  if ($vmlinuz_target !~ m|^/|o) {
-    $vmlinuz_target = $cwd . "/" . $vmlinuz_target;
-    $vmlinuz_target =~ s|/+|/|o;
-  }
-  $vmlinuz_target = `readlink -q -m $vmlinuz_target`;
-
-  if ("$vmlinuz_target" ne "$target") {
-    warn "DEBUG: We need to handle this.\n" if $DEBUG;
-    if ($minimal_swap) {
-      warn "DEBUG: Minimal swap.\n" if $DEBUG;
-      if (-l "$kimage.old") {
-        warn "DEBUG: There is an old link at $kimage.old\n" if $DEBUG;
-        my $old_target = readlink "$kimage.old";
-        my $real_old_target = '';
-        $real_old_target=abs_path($old_target) if defined ($old_target);
-
-        if ($real_old_target  && -f "$real_old_target") {
-          if ($old_target !~ m|^/|o) {
-            $old_target = $cwd . "/" . $old_target;
-            $old_target =~ s|/+|/|o;
-          }
-          $old_target = `readlink -q -m $old_target`;
-          if ("$old_target"  ne "$target") {
-            $force_move = 1;
-            warn "DEBUG: Old link ($old_target) does not point to us ($target)\n"
-              if $DEBUG;
-          } 
-          else {            # The .old points to the current
-            warn "$kimage.old --> $target -- doing nothing";
-            $force_move = 0;
-          }
-        } 
-        else { 
-          warn "DEBUG: Well, the old link does not exist -- so we move\n"
-            if $DEBUG;
-          $force_move = 1;
-        }
-      } 
-      else {
-        warn "DEBUG: No .old link -- OK to move\n"
-          if $DEBUG;
-        $force_move = 1;
-      }
-    } 
-    else {
-      warn "DEBUG: ok, minimal swap is no-- so we move.\n"
-        if $DEBUG;
-      $force_move = 1;
-    }
-  }
-  else {                  # already have proper link
-    warn "$kimage($vmlinuz_target) points to $target ($real_target) -- doing nothing";
-    $force_move = 0;
-  }
-  return $force_move;
-}
-
-
-# This routine moves the symbolic link around (/vmlinuz -> /vmlinuz.old)
-# It pays attention to whether we should the fact whether we should be using
-# hard links or not.
-sub really_move_link {
-  my $kimage     = $_[0];       # Name of the symbolic link
-  my $image_dest = $_[1];       # The directory the links goes into
-  my $image_name = $_[2]; 
-  my $src_dir    = $_[3]; 
-  warn "really_move_link: kimage=$kimage, image_dest=$image_dest\n" .
-    "\t image_name=$image_name, src_dir=$src_dir" if $DEBUG;
-
-  # don't clobber $kimage.old quite yet
-  rename("$kimage", "$kimage.$$") ||
-    die "failed to move " . $image_dest . "$kimage:$!";
-  warn "mv $kimage $kimage.$$" if $DEBUG;
-  my $Old = $src_dir;
-  my $cwd;
-
-  chomp($cwd=`pwd`);
-  if (test_relative ('Old Dir' => $Old, 'New Dir' => $cwd,
-                     'Test File' => "$image_name")) {
-    $Old   =~ s|^/*||o;
-  }
-  # Special case is they are in the same dir
-  my $rel_path = spath('Old' => "$Old", 'New' => "$cwd" );
-  $Old ="" if $rel_path =~ m/^\s*$/o;
-
-  if ($use_hard_links =~ m/YES/i) {
-    warn "ln ${Old}${image_name} $kimage" if $DEBUG;
-    if (! link("${Old}${image_name}", "$kimage")) {
-      rename("$kimage.$$", "$kimage");
-      die("Failed to link ${Old}${image_name} to " .
-          "${image_dest}${kimage}.\n");
-    }
-  } 
-  else {
-    warn "ln -s ${Old}${image_name} $kimage" if $DEBUG;
-    if (! symlink("${Old}${image_name}", "$kimage")) {
-      rename("$kimage.$$", "$kimage");
-      die("Failed to symbolic-link ${Old}${image_name} to " .
-          "${image_dest}${kimage}: $!\n");
-    }
-  }
-
-  # Ok, now we may clobber the previous .old file
-  if (-l "$kimage.old" || ! -e "$kimage.old" ) {
-    rename("$kimage.$$", "$kimage.old");
-    warn "mv $kimage.$$ $kimage.old" if $DEBUG;
-  }
-  else {
-    warn "$kimage.old is not a symlink, not clobbering\n";
-    warn "rm $kimage.$$";
-    unlink "$kimage.$$" if $DEBUG;
-  }
-}
-
-# This routine handles a request to do symlinks, but there is no
-# symlink file already there.  Either we are supposed to use copy, or we are
-# installing on a pristine system, or the user does not want symbolic links at
-# all.  We use a configuration file to tell the last two cases apart, creating
-# a config file if needed.
-sub handle_missing_link {
-  my $kimage     = $_[0];       # Name of the symbolic link
-  my $image_dest = $_[1];       # The directory the links goes into
-  my $image_name = $_[2]; 
-  my $src_dir    = $_[3]; 
-  warn "handle_missing_link: kimage=$kimage, image_dest=$image_dest\n" .
-    "\t image_name=$image_name, src_dir=$src_dir" if $DEBUG;
-
-  if ($no_symlink) {
-    warn "cp -a --backup=t $realimageloc$image_name $kimage" if $DEBUG;
-    my $ret = system("cp -a --backup=t " . $realimageloc .
-                     "$image_name "   . " $kimage");
-    if ($ret) {
-      die("Failed to copy " . $realimageloc . "$image_name to "
-          . $image_dest . "$kimage .\n");
-    }
-  } 
-  elsif ($reverse_symlink) {
-    warn "mv -f $realimageloc$image_name $kimage" if $DEBUG;
-    my $ret = system("mv -f " . $realimageloc . "$image_name "
-                     . "$kimage");
-    if ($ret) {
-      die("Failed to move " . $realimageloc . "$image_name to "
-          . $image_dest . "$kimage .\n");
-    }
-  } 
-  else {
-    if (! $have_conffile) {
-      my $ret;
-      my $answer='';
-      $do_symlink = "Yes";
-
-      if (open(CONF, ">$CONF_LOC")) {
-        print CONF "# Kernel Image management overrides\n";
-        print CONF "# See kernel-img.conf(5) for details\n";
-        if ($loader =~ /palo/i) {
-          print CONF "link_in_boot = Yes\n";
-          print CONF "do_symlinks = Yes\n";
-          print CONF "relative_links = Yes\n";
-          print CONF "do_bootloader = No\n";
-        } else {
-          print CONF "do_symlinks = $do_symlink\n";
-        }
-        close CONF;
-      }
-      $have_conffile = "Yes";
-    }
-  }
-
-  if (! $no_symlink && $do_symlink =~ /Yes/i) {
-    my $Old = $realimageloc;
-    my $New = $image_dest;
-    my $Name = "$image_name";
-    my $Link_Dest = "$kimage";
-
-    if ($reverse_symlink) {
-      $Old = $image_dest;
-      $New = $realimageloc;
-      $Name = "$kimage";
-      $Link_Dest = $realimageloc . "$image_name";
-    }
-    if (test_relative ('Old Dir' => $Old,
-                       'New Dir' => $New,
-                       'Test File' => $Name)) {
-      $Old   =~ s|^/*||o;
-    }
-    # Special case is they are in the same dir
-    my $rel_path = spath('Old' => "$Old", 'New' => "$New" );
-    $Old ="" if $rel_path =~ m/^\s*$/o;
-
-    symlink($Old . "$Name", "$Link_Dest") ||
-      die("Failed to symbolic-link ${Old}$Name to $Link_Dest: $!\n");
-    warn "ln -s ${Old}$Name $Link_Dest" if $DEBUG;
-
-  }
-}
-
-# This routine handles the rest of the cases, where the user has requested 
-# non-traditional handling, like using cp, or reverse symlinks, or hard links.
-sub handle_non_symlinks {
-  my $kimage     = $_[0];       # Name of the symbolic link
-  my $image_dest = $_[1];       # The directory the links goes into
-  my $image_name = $_[2]; 
-  my $src_dir    = $_[3]; 
-  warn "handle_non_link: kimage=$kimage, image_dest=$image_dest\n" .
-    "\t image_name=$image_name, src_dir=$src_dir" if $DEBUG;
-
-  # Save the current image. We do this in all four cases
-  rename("$kimage", "$kimage.$$") || 
-    die "failed to move " . $image_dest . "$kimage:$!";
-  warn "mv $kimage $kimage.$$" if $DEBUG;
-
-  ##,#### 
-  # case One
-  #`####
-  if ($no_symlink) {
-    # Maybe /$image_dest is on a dos system?
-    warn "cp -a --backup=t $realimageloc$image_name $kimage" if $DEBUG;
-    my $ret = system("cp -a --backup=t " . $realimageloc
-                     . "$image_name " . "$kimage");
-    if ($ret) {
-      if (-e "$kimage.$$") {
-        rename("$kimage.$$", "$kimage");
-        warn "mv $kimage.$$ $kimage" if $DEBUG;
-      }
-      die("Failed to copy " . $realimageloc . "$image_name to "
-          . $image_dest . "$kimage .\n");
-    }
-  }
-  ##,#### 
-  # case Two
-  #`####
-  elsif ($reverse_symlink) {  # Maybe /$image_dest is on a dos system?
-    warn "mv -f  $realimageloc$image_name $kimage" if $DEBUG;
-    my $ret = system("mv -f " . $realimageloc . "$image_name "
-                     . $image_dest . "$kimage");
-    if ($ret) {
-      if (-e "$kimage.$$") {
-        rename("$kimage.$$", "$kimage");
-        warn "mv $kimage.$$ $kimage" if $DEBUG;
-      }
-      die("Failed to move " . $realimageloc . "$image_name to "
-          . $image_dest . "$kimage .\n");
-    }
-    my $Old = $image_dest;
-    if (test_relative ('Old Dir' => $Old, 'New Dir' => $realimageloc,
-                       'Test File' => "$kimage")) {
-      $Old   =~ s|^/*||o;
-    }
-    # Special case is they are in the same dir
-    my $rel_path = spath('Old' => "$Old", 'New' => "$realimageloc" );
-    $Old ="" if $rel_path =~ m/^\s*$/o;
-
-    if ($use_hard_links =~ m/YES/i) {
-      warn "ln " . $Old . "$kimage " . $realimageloc . "$image_name" if $DEBUG;
-      if (! link($Old . "$kimage", $realimageloc . "$image_name")) {
-        warn "Could not link " . $image_dest .
-          "$kimage to $image_name :$!";
-      }
-    }
-    else {
-      warn "ln -s " . $Old . "$kimage " . $realimageloc . "$image_name" if $DEBUG;
-      if (! symlink($Old . "$kimage", $realimageloc . "$image_name")) {
-        warn "Could not symlink " . $image_dest .
-          "$kimage to $image_name :$!";
-      }
-    }
-  }
-  ##,####
-  # case Three
-  #`####
-  elsif ($use_hard_links =~ m/YES/i ) {
-    # Ok then. this ought to be a hard link, and hence fair game
-    # don't clobber $kimage.old quite yet
-    my $Old = $realimageloc;
-    my $cwd;
-    chomp($cwd=`pwd`);
-    if (test_relative ('Old Dir' => $Old, 'New Dir' => $cwd,
-                       'Test File' => "$image_name")) {
-      $Old   =~ s|^/*||o;
-    }
-    # Special case is they are in the same dir
-    my $rel_path = spath('Old' => "$Old", 'New' => "$cwd" );
-    $Old ="" if $rel_path =~ m/^\s*$/o;
-
-    warn "ln " . $Old . "$image_name " . "$kimage" if $DEBUG;
-    if (! link($Old . "$image_name", "$kimage")) {
-      warn "mv $kimage.$$ $kimage" if $DEBUG;
-      rename("$kimage.$$", "$kimage");
-      die("Failed to link " . $realimageloc . "$image_name to "
-          . $image_dest . "$kimage .\n");
-    }
-  }
-  ##,####
-  # case Four
-  #`####
-  else {
-    # We just use cp
-    warn "cp -a --backup=t $realimageloc$image_name $kimage" if $DEBUG;
-    my $ret = system("cp -a --backup=t " . $realimageloc
-                     . "$image_name " . "$kimage");
-    if ($ret) {
-      if (-e "$kimage.$$") {
-        warn "mv $kimage.$$ $kimage" if $DEBUG;
-        rename("$kimage.$$", "$kimage");
-      }
-      die("Failed to copy " . $realimageloc . "$image_name to "
-          . $image_dest . "$kimage .\n");
-    }
-  }
-  # Ok, now we may clobber the previous .old file
-  warn "mv $kimage.$$ $kimage.old if -e $kimage.$$" if $DEBUG;
-  rename("$kimage.$$", "$kimage.old") if -e "$kimage.$$";
-}
-
-# This routine is responsible for setting up the symbolic links
-# So, the actual kernel image lives in
-# $realimageloc/$image_name (/boot/vmlinuz-2.6.12).
-# This routine creates symbolic links in $image_dest/$kimage (/vmlinuz)
-sub image_magic {
-  my $kimage     = $_[0];       # Name of the symbolic link
-  my $image_dest = $_[1];       # The directory the links goes into
-  my $image_name = "$kimage-$version";
-  my $src_dir    = $realimageloc;
-  warn "image_magic: kimage=$kimage, image_dest=$image_dest\n" .
-    "\t image_name=$image_name, src_dir=$src_dir" if $DEBUG;
-
-  # Well, in any case, if the destination (the symlink we are trying
-  # to create) is a directory, we should do nothing, except throw a
-  # diagnostic.
-  if (-d "$kimage" ) {
-    die ("Hmm. $kimage is a directory, which I did not expect.  I am\n" .
-         "trying to create a symbolic link with that name linked to \n" .
-         "$image_dest . Since a directory exists here, my assumptions \n" .
-         "are way off, and I am aborting.\n" );
-    exit (3);
-  }
-
-  if ($move_image) {   # Maybe $image_dest is in on dos, or something?
-    #                   source dir,    link name,        dest dir
-    really_move_image(  $realimageloc, $image_name, $image_dest);
-    really_reverse_link($realimageloc, $image_name, $image_dest)
-      if $reverse_symlink;
-    return;
-  }
-
-  if (-l "$kimage") {           # There is a symbolic link
-    warn "DEBUG: There is a symlink for $kimage\n" if $DEBUG;
-    my $force_move = move_p($kimage, $image_dest, $image_name, $src_dir);
-
-    if ($force_move) {
-      really_move_link($kimage, $image_dest, $image_name, $src_dir);
-    }
-  }
-  elsif (! -e "$kimage") {
-    # Hmm. Pristine system? How can that be? Installing from scratch?
-    # Or maybe the user does not want a symbolic link here.
-    # Possibly they do not want a link here. (we should be in /
-    # here[$image_dest, really]
-    handle_missing_link($kimage, $image_dest, $image_name, $src_dir);
-  }
-  elsif (-e "$kimage" ) {
-    # OK, $kimage exists -- but is not a link
-    handle_non_symlinks($kimage, $image_dest, $image_name, $src_dir);
-  }
-}
-
-######################################################################
-######################################################################
-######################################################################
-######################################################################
-
-# We may not have any modules installed
-if ( -d "$modules_base/$version" ) {
-  print STDERR "Running depmod.\n";
-  my $ret = system("depmod -a $version");
-  if ($ret) {
-    print STDERR "Failed to run depmod\n";
-    exit(1);
-  }
-}
-
-
-
-sub find_initrd_tool {
-  my $hostversion = shift;
-  my $version = shift;
-  print STDERR "Finding valid ramdisk creators.\n";
-  my @ramdisks =
-    grep {
-      my $args = 
-        "$_ " .
-          "--supported-host-version=$hostversion " .
-            "--supported-target-version=$version " .
-              "1>/dev/null 2>&1"
-                ;
-      system($args) == 0;
-    }
-      split (/[:,\s]+/, $ramdisk);
-}
-
-# The initrd symlink should probably be in the same dir that the
-# symlinks are in
-if ($initrd) {
-  my $success = 0;
-
-  # Update-initramfs is called slightly different than mkinitrd and
-  # mkinitramfs. XXX It should really be made compatible with this stuff
-  # some how.
-  my $upgrading = 1;
-  if (! defined $ARGV[1] || ! $ARGV[1] || $ARGV[1] =~ m/<unknown>/og) {
-    $upgrading = 0;
-  }
-  my $ret = system("$ramdisk " . ($upgrading ? "-u" : "-c") . " -k " . $version . " >&2");
-  $success = 1 unless $ret;
-  die "Failed to create initrd image.\n" unless $success;
-  if (! defined $ARGV[1] || ! $ARGV[1] || $ARGV[1] =~ m/<unknown>/og) {
-    image_magic("initrd.img", $image_dest);
-  }
-  else {
-    if (! -e "initrd.img") {
-      handle_missing_link("initrd.img", $image_dest, "initrd.img-$version",
-                          $realimageloc);
-    }
-    else {
-      print STDERR
-        "Not updating initrd symbolic links since we are being updated/reinstalled \n";
-      print STDERR
-        "($ARGV[1] was configured last, according to dpkg)\n";
-    }
-  }
-
-  if ($initrd && -l "initrd" ) {
-    unlink "initrd";
-  }
-
-  if ($initrd && -l "$image_dir/initrd" && ! $link_in_boot) {
-    unlink "$image_dir/initrd";
-  }
-}
-else {                        # Not making an initrd emage
-  if (-l "initrd.img") {
-    # Ooh, last image was an initrd image? in any case, we should move it. 
-    my $target = readlink "initrd.img";
-    my $real_target = '';
-    $real_target = abs_path($target) if defined ($target);
-
-    if (!defined($target) || ! -f "$real_target") {
-      # Eh. dangling link. can safely be removed.
-      unlink("initrd.img");
-    } else {
-      if (-l "initrd.img.old" || ! -e "initrd.img.old" ) {
-        rename("initrd.img", "initrd.img.old");
-      } else {
-        warn "initrd.img.old is not a symlink, not clobbering\n";
-        unlink("initrd.img");
-      }
-    }
-  }
-}
-
-# Warn of a reboot
-if (-x $notifier) {
-  system($notifier);
-}
-
-# Let programs know not to hibernate if the kernel that would be used for
-# resume-from-hibernate is likely to differ from the currently running kernel.
-system("mountpoint -q /var/run");
-if ($? eq 0) {
-	system("touch /var/run/do-not-hibernate");
-}
-
-# Only change the symlinks if we are not being upgraded
-if (! defined $ARGV[1] || ! $ARGV[1] || $ARGV[1] =~ m/<unknown>/og) {
-  image_magic($kimage, $image_dest);
-}
-else {
-  if (! -e "$kimage") {
-    handle_missing_link($kimage, $image_dest, "$kimage-$version", 
-                        $realimageloc);
-  }
-  else {
-    print STDERR
-      "Not updating image symbolic links since we are being updated/reinstalled \n";
-    print STDERR
-      "($ARGV[1] was configured last, according to dpkg)\n";
-  }
-}
-
-# We used to have System.* files in /
-if (-e "/System.map" || -e "/System.old") {
-  unlink '/System.map' if -e '/System.map';
-  unlink '/System.old' if -e '/System.old';
-}
-
-# creating some info about kernel and initrd
-if ($DEBUG) {
-  my $ksize=sprintf("%.0f",(stat($realimageloc .
-                                 "$kimage-$version"))[7]/1024)."kB";
-  my $initrdsize='';
-  if ($initrd) {
-    $initrdsize=sprintf("%.0f",(stat($realimageloc .
-                                     "initrd.img-$version"))[7]/1024)."kB";
-  }
-
-  print STDERR <<"EOMSG";
-A new kernel image has been installed at $realimageloc$kimage-$version
- (Size: $ksize)
-
-Symbolic links, unless otherwise specified, can be found in $image_dest
-
-EOMSG
-  ;
-
-  if ($initrd) {
-    print STDERR <<"EOMSGA";
-
- Initial rootdisk image: ${realimageloc}initrd.img-$version (Size: $initrdsize)
-EOMSGA
-    ;
-  }
-}
-
-# set the env var stem
-$ENV{'STEM'} = "linux";
-sub exec_script {
-  my $type   = shift;
-  my $script = shift;
-  print STDERR "Running $type hook script $script.\n";
-  system ("$script $version $realimageloc$kimage-$version") &&
-    print STDERR "User $type hook script [$script] ";
-  if ($?) {
-    if ($? == -1) {
-      print STDERR "failed to execute: $!\n";
-    }
-    elsif ($? & 127) {
-      printf STDERR "died with signal %d, %s coredump\n",
-        ($? & 127),  ($? & 128) ? 'with' : 'without';
-    }
-    else {
-      printf STDERR "exited with value %d\n", $? >> 8;
-    }
-    exit $? >> 8;
-  }
-}
-sub run_hook {
-  my $type   = shift;
-  my $script = shift;
-  if ($script =~ m,^/,) {
-    # Full path provided for the hook script
-    if (-x "$script") {
-      &exec_script($type,$script);
-    }
-    else {
-      die "The provided $type hook script [$script] could not be run.\n";
-    }
-  }
-  else {
-    # Look for it in a safe path
-    for my $path ('/bin', '/sbin', '/usr/bin', '/usr/sbin') {
-      if (-x "$path/$script") {
-        &exec_script($type, "$path/$script");
-        return 0;
-      }
-    }
-    # No luck
-    print STDERR "Could not find $type hook script [$script].\n";
-    die "Looked in: '/bin', '/sbin', '/usr/bin', '/usr/sbin'\n";
-  }
-}
-
-my $options;
-for (@ARGV) {
-	s,','\\'',g;
-	$options .= " '$_'";
-}
-$ENV{'DEB_MAINT_PARAMS'}="$options";
-
-## Run user hook script here, if any
-if ($postinst_hook) {
-  &run_hook("postinst", $postinst_hook);
-}
-
-if (-d "/etc/kernel/postinst.d") {
-  print STDERR "Examining /etc/kernel/postinst.d.\n";
-  system ("run-parts --verbose --exit-on-error --arg=$version " .
-          "--arg=$realimageloc$kimage-$version " .
-          "/etc/kernel/postinst.d") &&
-            die "Failed to process /etc/kernel/postinst.d";
-}
-
-if (-d "/etc/kernel/postinst.d/$version") {
-  print STDERR "Examining /etc/kernel/postinst.d/$version.\n";
-  system ("run-parts --verbose --exit-on-error --arg=$version " .
-          "--arg=$realimageloc$kimage-$version " .
-          "/etc/kernel/postinst.d/$version") &&
-            die "Failed to process /etc/kernel/postinst.d/$version";
-}
-
-LOADER: {
-  last unless $do_boot_enable; # Exit if explicitly asked to
-
-  last if $loader =~ /silo/i; # SILO does not have to be executed.
-  last if $loader =~ /yaboot/i; # yaboot does not have to be executed.
-  last if $loader =~ /milo/i; # MILO does not have to be executed.
-  last if $loader =~ /nettrom/i; # NETTROM does not have to be executed.
-  last if $loader =~ /arcboot/i; # ARCBOOT does not have to be executed.
-  last if $loader =~ /delo/i; # DELO does not have to be executed.
-  last if $loader =~ /quik/i; # maintainer asked quik invocation to be ignored
-
-  last unless $loaderloc;
-  last unless -x $loaderloc;
-  last unless $do_bootloader;
-
-  if (-T "/etc/$loader.conf") {
-    # Trust and use the existing lilo.conf.
-    print STDERR "You already have a $Loader configuration in /etc/$loader.conf\n";
-    my $ret = &run_lilo();
-    exit $ret if $ret;
-  }
-}
-
-
-sub run_lilo (){
-  my $ret;
-  # Try and figure out if the user really wants lilo to be run --
-  # since the default is to run the boot laoder, which is ! grub -- but
-  # the user may be using grub now, and not changed the default.
-
-  # So, if the user has explicitly asked for the loader to be run, or
-  # if there is no postinst hook, or if there is no grub installed --
-  # we are OK. Or else, we ask.
-  if ($explicit_do_loader || (! ($postinst_hook && -x '/usr/sbin/grub')))  {
-    print STDERR "Running boot loader as requested\n";
-  } else {
-    print STDERR "Ok, not running $loader\n";
-  }
-  if ($loader =~ /^lilo/io or $loader =~ /vmelilo/io) {
-    print STDERR "Testing $loader.conf ... \n";
-    unlink $temp_file_name;     # security
-    $ret = system("$loaderloc -t >$temp_file_name 2>&1");
-    if ($ret) {
-      print STDERR "Boot loader test failed\n";
-      return $ret;
-    }
-    unlink "$temp_file_name";
-    print STDERR "Testing successful.\n";
-    print STDERR "Installing the ";
-    print STDERR "partition " if $loader =~ /^lilo/io;
-    print STDERR "boot sector... \n";
-  }
-
-  print STDERR "Running $loaderloc  ... \n";
-  if ($loader =~ /^elilo/io) {
-    $ret = system("$loaderloc 2>&1 | tee $temp_file_name");
-  } else {
-    $ret = system("$loaderloc >$temp_file_name 2>&1");
-  }
-  if ($ret) {
-    print STDERR "Boot loader failed to run\n";
-    return $ret;
-  }
-  unlink $temp_file_name;
-  print STDERR "Installation successful.\n";
-  return 0;
-}
-
-exit 0;
-
-__END__
-
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/debian/control-scripts/postinst.extra linux-linaro-3.4-2012.05-1_cavium/debian/control-scripts/postinst.extra
--- linux-linaro-3.4-2012.05-1_original/debian/control-scripts/postinst.extra	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/debian/control-scripts/postinst.extra	1970-01-01 08:00:00.000000000 +0800
@@ -1,8 +0,0 @@
-#!/bin/sh
-
-case "$1" in
-  configure)
-    depmod -a -F /boot/System.map-@@KVER@@ @@KVER@@
-    update-initramfs -u -k @@KVER@@
-    ;;
-esac
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/debian/control-scripts/postrm linux-linaro-3.4-2012.05-1_cavium/debian/control-scripts/postrm
--- linux-linaro-3.4-2012.05-1_original/debian/control-scripts/postrm	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/debian/control-scripts/postrm	1970-01-01 08:00:00.000000000 +0800
@@ -1,361 +0,0 @@
-#! /usr/bin/perl
-#                              -*- Mode: Cperl -*- 
-# image.postrm --- 
-# Author           : Manoj Srivastava ( srivasta@glaurung.green-gryphon.com ) 
-# Created On       : Sat May 15 11:05:13 1999
-# Created On Node  : glaurung.green-gryphon.com
-# Last Modified By : Manoj Srivastava
-# Last Modified On : Wed Sep 13 11:26:19 2006
-# Last Machine Used: glaurung.internal.golden-gryphon.com
-# Update Count     : 57
-# Status           : Unknown, Use with caution!
-# HISTORY          : 
-# Description      : 
-# 
-#     $Id: image.postrm,v 1.31 2003/10/07 16:24:20 srivasta Exp $
-#
-
-
-# 
-#use strict; #for debugging
-use Cwd 'abs_path';
-
-$|=1;
-
-# Predefined values:
-my $version           = "=V";
-my $link_in_boot      = "";	# Should be empty, mostly
-my $no_symlink        = "";	# Should be empty, mostly
-my $reverse_symlink   = "";	# Should be empty, mostly
-my $do_symlink        = "Yes";	# target machine defined
-my $do_boot_enable    = "Yes";	# target machine defined
-my $do_bootfloppy     = "Yes";	# target machine defined
-my $do_bootloader     = "Yes";	# target machine defined
-my $move_image        = '';       # target machine defined
-my $kimage            = "=K";	# Should be empty, mostly
-my $loader            = "=L";     # lilo, silo, quik, palo, vmelilo, or nettrom
-my $image_dir         = "/boot";     # where the image is located
-my $clobber_modules   = '';       # target machine defined
-my $initrd            = "YES";     # initrd kernel
-my $do_initrd         = '';       # Normally, we don't
-my $warn_initrd       = 'YES';    # Normally we do
-my $use_hard_links    = '';       # hardlinks do not work across fs boundaries
-my $postinst_hook     = '';       #Normally we do not
-my $postrm_hook       = '';       #Normally we do not
-my $preinst_hook      = '';       #Normally we do not
-my $prerm_hook        = '';       #Normally we do not
-my $minimal_swap      = '';       # Do not swap symlinks
-my $ignore_depmod_err = '';	# normally we do not
-my $relink_build_link = 'YES';	# There is no harm in checking the link
-my $force_build_link  = '';	# we shall not create a dangling link
-my $kernel_arch       = "=B";
-my $ramdisk           = "/usr/sbin/update-initramfs";
-my $package_name    = "linux-image-$version";
-
-my $Loader          = "NoLOADER"; # 
-$Loader             = "LILO"     if $loader =~ /^lilo/io;
-$Loader             = "SILO"     if $loader =~ /^silo/io;
-$Loader             = "QUIK"     if $loader =~ /^quik/io;
-$Loader             = "yaboot"   if $loader =~ /^yaboot/io;
-$Loader             = "PALO"     if $loader =~ /^palo/io;
-$Loader             = "NETTROM"  if $loader =~ /^nettrom/io;
-$Loader             = "VMELILO"  if $loader =~ /^vmelilo/io;
-$Loader             = "ZIPL"     if $loader =~ /^zipl/io;
-$Loader             = "ELILO"    if $loader =~ /^elilo/io;
-
-
-# This should not point to /tmp, because of security risks.
-my $temp_file_name = "/var/log/$loader" . "_log.$$";
-
-#known variables
-my @boilerplate     = ();
-my @silotemplate    = ();
-my @quiktemplate    = ();
-my @palotemplate    = ();
-my @vmelilotemplate = ();
-my $bootdevice      = '';
-my $rootdevice      = '';
-my $rootdisk        = '';
-my $rootpartition   = '';
-my $image_dest      = "/";
-my $realimageloc    = "/$image_dir/";
-my $have_conffile   = "";
-my $CONF_LOC        = '/etc/kernel-img.conf';
-my $relative_links = '';
-my $silent_modules  = '';
-my $silent_loader   = '';
-my $warn_reboot     = 'Yes';     # Warn that we are installing a version of
-                                 # the kernel we are running
-
-chdir('/')           or die "could not chdir to /:$!\n";
-# remove multiple leading slashes; make sure there is at least one.
-$realimageloc  =~ s|^/*|/|o;
-$realimageloc  =~ s|/+|/|o;
-
-
-if (-r "$CONF_LOC" && -f "$CONF_LOC"  ) {
-  if (open(CONF, "$CONF_LOC")) {
-    while (<CONF>) {
-      chomp;
-      s/\#.*$//g;
-      next if /^\s*$/;
-
-      $do_symlink      = "" if /^\s*do_symlinks\s*=\s*(no|false|0)\s*$/ig;
-      $no_symlink      = "" if /^\s*no_symlinks\s*=\s*(no|false|0)\s*$/ig;
-      $reverse_symlink = "" if /^\s*reverse_symlinks\s*=\s*(no|false|0)\s*$/ig;
-      $link_in_boot    = "" if /^\s*image_in_boot\s*=\s*(no|false|0)\s*$/ig;
-      $link_in_boot    = "" if /^\s*link_in_boot\s*=\s*(no|false|0)\s*$/ig;
-      $move_image      = "" if /^\s*move_image\s*=\s*(no|false|0)\s*$/ig;
-      $clobber_modules = '' if /^\s*clobber_modules\s*=\s*(no|false|0)\s*$/ig;
-      $do_boot_enable  = '' if /^\s*do_boot_enable\s*=\s*(no|false|0)\s*$/ig;
-      $do_bootfloppy   = '' if /^\s*do_bootfloppy\s*=\s*(no|false|0)\s*$/ig;
-      $relative_links  = '' if /^\s*relative_links \s*=\s*(no|false|0)\s*$/ig;
-      $do_bootloader   = '' if /^\s*do_bootloader\s*=\s*(no|false|0)\s*$/ig;
-      $do_initrd       = '' if /^\s*do_initrd\s*=\s*(no|false|0)\s*$/ig;
-      $warn_initrd     = '' if /^\s*warn_initrd\s*=\s*(no|false|0)\s*$/ig;
-      $use_hard_links  = '' if /^\s*use_hard_links\s*=\s*(no|false|0)\s*$/ig;
-      $silent_modules  = '' if /^\s*silent_modules\s*=\s*(no|false|0)\s*$/ig;
-      $silent_loader   = '' if /^\s*silent_loader\s*=\s*(no|false|0)\s*$/ig;
-      $warn_reboot     = '' if /^\s*warn_reboot\s*=\s*(no|false|0)\s*$/ig;
-      $minimal_swap    = '' if /^\s*minimal_swap\s*=\s*(no|false|0)\s*$/ig;
-      $ignore_depmod_err = '' if /^\s*ignore_depmod_err\s*=\s*(no|false|0)\s*$/ig;
-      $relink_build_link = '' if /^\s*relink_build_link\s*=\s*(no|false|0)\s*$/ig;
-      $force_build_link = '' if /^\s*force_build_link\s*=\s*(no|false|0)\s*$/ig;
-
-      $do_symlink      = "Yes" if /^\s*do_symlinks\s*=\s*(yes|true|1)\s*$/ig;
-      $no_symlink      = "Yes" if /^\s*no_symlinks\s*=\s*(yes|true|1)\s*$/ig;
-      $reverse_symlink = "Yes" if /^\s*reverse_symlinks\s*=\s*(yes|true|1)\s*$/ig;
-      $link_in_boot    = "Yes" if /^\s*image_in_boot\s*=\s*(yes|true|1)\s*$/ig;
-      $link_in_boot    = "Yes" if /^\s*link_in_boot\s*=\s*(yes|true|1)\s*$/ig;
-      $move_image      = "Yes" if /^\s*move_image\s*=\s*(yes|true|1)\s*$/ig;
-      $clobber_modules = "Yes" if /^\s*clobber_modules\s*=\s*(yes|true|1)\s*$/ig;
-      $do_boot_enable  = "Yes" if /^\s*do_boot_enable\s*=\s*(yes|true|1)\s*$/ig;
-      $do_bootfloppy   = "Yes" if /^\s*do_bootfloppy\s*=\s*(yes|true|1)\s*$/ig;
-      $do_bootloader   = "Yes" if /^\s*do_bootloader\s*=\s*(yes|true|1)\s*$/ig;
-      $relative_links  = "Yes" if /^\s*relative_links\s*=\s*(yes|true|1)\s*$/ig;
-      $do_initrd       = "Yes" if /^\s*do_initrd\s*=\s*(yes|true|1)\s*$/ig;
-      $warn_initrd     = "Yes" if /^\s*warn_initrd\s*=\s*(yes|true|1)\s*$/ig;
-      $use_hard_links  = "Yes" if /^\s*use_hard_links\s*=\s*(yes|true|1)\s*$/ig;
-      $silent_modules  = 'Yes' if /^\s*silent_modules\s*=\s*(yes|true|1)\s*$/ig;
-      $silent_loader   = 'Yes' if /^\s*silent_loader\s*=\s*(yes|true|1)\s*$/ig;
-      $warn_reboot     = 'Yes' if /^\s*warn_reboot\s*=\s*(yes|true|1)\s*$/ig;
-      $minimal_swap    = 'Yes' if /^\s*minimal_swap\s*=\s*(yes|true|1)\s*$/ig;
-      $ignore_depmod_err = 'Yes' if /^\s*ignore_depmod_err\s*=\s*(yes|true|1)\s*$/ig;
-      $relink_build_link = 'Yes' if /^\s*relink_build_link\s*=\s*(yes|true|1)\s*$/ig;
-      $force_build_link = 'Yes' if /^\s*force_build_link\s*=\s*(yes|true|1)\s*$/ig;
-
-      $image_dest      = "$1"  if /^\s*image_dest\s*=\s*(\S+)/ig;
-      $postinst_hook   = "$1"  if /^\s*postinst_hook\s*=\s*(\S+)/ig;
-      $postrm_hook     = "$1"  if /^\s*postrm_hook\s*=\s*(\S+)/ig;
-      $preinst_hook    = "$1"  if /^\s*preinst_hook\s*=\s*(\S+)/ig;
-      $prerm_hook      = "$1"  if /^\s*prerm_hook\s*=\s*(\S+)/ig;
-      $ramdisk         = "$1"  if /^\s*ramdisk\s*=\s*(.+)$/ig;
-    }
-    close CONF;
-    $have_conffile = "Yes";
-  }
-}
-
-if ($link_in_boot) {
-  $image_dest = "/$image_dir/";
-  $image_dest =~ s|^/*|/|o;
-}
-
-$image_dest = "$image_dest/";
-$image_dest =~ s|/+$|/|o;
-
-# The destdir may be gone by now.
-if (-d "$image_dest") {
-  chdir("$image_dest") or die "could not chdir to $image_dest:$!\n";
-}
-
-# Paranoid check to make sure that the correct value is put in there
-if (! $kimage)                    {$kimage = "vmlinuz"} # Hmm. empty
-elsif ($kimage =~ m/^b?uImage$/o) {$kimage = "vmlinuz"} # these produce vmlinuz
-elsif ($kimage =~ m/^b?zImage$/o) {$kimage = "vmlinuz"} # these produce vmlinuz
-elsif ($kimage =~ m/^[iI]mage$/o) { my $nop = $kimage;}
-elsif ($kimage =~ m/^vmlinux$/o)  { my $nop = $kimage;}
-else                              {$kimage = "vmlinuz"} # default
-
-$ENV{KERNEL_ARCH}=$kernel_arch if $kernel_arch;
-
-
-######################################################################
-######################################################################
-############
-######################################################################
-######################################################################
-sub remove_sym_link {
-  my $bad_image = $_[0];
-
-  warn "Removing symbolic link $bad_image \n";
-  if ($loader =~ /lilo/i) 
-    {
-      warn "Unless you used the optional flag in lilo, \n";
-    }
-  warn " you may need to re-run your boot loader" . ($loader ? "[$loader]":"")
-    . "\n";
-  # Remove the dangling link
-  unlink "$bad_image";
-}
-
-######################################################################
-######################################################################
-############
-######################################################################
-######################################################################
-sub CanonicalizePath {
-  my $path = join '/', @_;
-  my @work = split '/', $path;
-  my @out;
-  my $is_absolute;
-
-  if (@work && $work[0] eq "") { $is_absolute = 1; shift @work; }
-
-  while (@work) {
-    my $seg = shift @work;
-    if ($seg eq "." || $seg eq "") {
-    } elsif ($seg eq "..") {
-      if (@out && $out[-1] ne "..") {
-        pop @out;
-      } else {
-        # Leading "..", or "../..", etc.
-        push @out, $seg;
-      }
-    } else {
-      push @out, $seg;
-    }
-  }
-
-  unshift @out, "" if $is_absolute;
-  return join('/', @out);
-}
-
-######################################################################
-######################################################################
-############
-######################################################################
-######################################################################
-# This removes dangling symlinks. What do we do about hard links? Surely a 
-# something with the nane $image_dest . "$kimage" ought not to be left behind? 
-sub image_magic {
-  my $kimage = $_[0];
-  my $image_dest = $_[1];
-
-  if (-l "$kimage") {
-    # There is a symbolic link
-    my $force_move = 0;
-    my $vmlinuz_target = readlink "$kimage";
-    my $real_target = '';
-    $real_target = abs_path($vmlinuz_target) if defined ($vmlinuz_target);
-    if (!defined($vmlinuz_target) || ! -f "$real_target") {
-      # what, a dangling symlink?
-      warn "The link "  . $image_dest . "$kimage is a damaged link\n";
-      # Remove the dangling link
-      &remove_sym_link("$kimage");
-    }
-    else {
-      my $canonical_target = CanonicalizePath("$vmlinuz_target");
-      if (! -e $canonical_target) {
-	warn "The link "  . $image_dest . "$kimage is a dangling link\n";
-	&remove_sym_link("$kimage");
-      }
-    }
-  }
-}
-
-# set the env var stem
-$ENV{'STEM'} = "linux";
-
-sub exec_script {
-  my $type   = shift;
-  my $script = shift;
-  print STDERR "Running $type hook script $script.\n";
-  system ("$script $version $realimageloc$kimage-$version") &&
-    print STDERR "User $type hook script [$script] ";
-  if ($?) {
-    if ($? == -1) {
-      print STDERR "failed to execute: $!\n";
-    }
-    elsif ($? & 127) {
-      printf STDERR "died with signal %d, %s coredump\n",
-        ($? & 127),  ($? & 128) ? 'with' : 'without';
-    }
-    else {
-      printf STDERR "exited with value %d\n", $? >> 8;
-    }
-  }
-}
-sub run_hook {
-  my $type   = shift;
-  my $script = shift;
-  if ($script =~ m,^/,) {
-    # Full path provided for the hook script
-    if (-x "$script") {
-      &exec_script($type,$script);
-    }
-    else {
-      warn "The provided $type hook script [$script] could not be run.\n";
-    }
-  }
-  else {
-    # Look for it in a safe path
-    for my $path ('/bin', '/sbin', '/usr/bin', '/usr/sbin') {
-      if (-x "$path/$script") {
-        &exec_script($type, "$path/$script");
-        return 0;
-      }
-    }
-    # No luck
-    print STDERR "Could not find $type hook script [$script].\n";
-    warn "Looked in: '/bin', '/sbin', '/usr/bin', '/usr/sbin'\n";
-  }
-}
-
-my $options;
-for (@ARGV) {
-	s,','\\'',g;
-	$options .= " '$_'";
-}
-$ENV{'DEB_MAINT_PARAMS'}="$options";
-
-## Run user hook script here, if any
-if ($postrm_hook) {
-  &run_hook("postrm", $postrm_hook);
-}
-if (-d "/etc/kernel/postrm.d") {
-  warn "Examining /etc/kernel/postrm.d .\n";
-  system ("run-parts --verbose --exit-on-error --arg=$version " .
-          "--arg=$realimageloc$kimage-$version " .
-          "/etc/kernel/postrm.d") &&
-            die "Failed to process /etc/kernel/postrm.d";
-}
-if (-d "/etc/kernel/postrm.d/$version") {
-  warn "Examining /etc/kernel/postrm.d/$version .\n";
-  system ("run-parts --verbose --exit-on-error --arg=$version " .
-          "--arg=$realimageloc$kimage-$version " .
-          "/etc/kernel/postrm.d/$version") &&
-            die "Failed to process /etc/kernel/postrm.d/$version";
-}
-
-# check and remove damaged and dangling symlinks
-if ($ARGV[0] !~ /upgrade/) {
-  system("$ramdisk -d -k " . $version . " > /dev/null 2>&1");
-  if (-f $realimageloc . "initrd.img-$version.bak") {
-    unlink $realimageloc . "initrd.img-$version.bak";
-  }
-  image_magic($kimage,          $image_dest);
-  image_magic($kimage . ".old", $image_dest);
-  image_magic("initrd.img",     $image_dest) if $initrd;
-  image_magic("initrd.img.old", $image_dest) if $initrd;
-}
-
-exit 0;
-
-__END__
-
-
-
-
-
-
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/debian/control-scripts/postrm.extra linux-linaro-3.4-2012.05-1_cavium/debian/control-scripts/postrm.extra
--- linux-linaro-3.4-2012.05-1_original/debian/control-scripts/postrm.extra	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/debian/control-scripts/postrm.extra	1970-01-01 08:00:00.000000000 +0800
@@ -1,8 +0,0 @@
-#!/bin/sh
-
-case "$1" in
-  remove|purge)
-    depmod -a -F /boot/System.map-@@KVER@@ @@KVER@@
-    update-initramfs -u -k @@KVER@@
-    ;;
-esac
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/debian/control-scripts/preinst linux-linaro-3.4-2012.05-1_cavium/debian/control-scripts/preinst
--- linux-linaro-3.4-2012.05-1_original/debian/control-scripts/preinst	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/debian/control-scripts/preinst	1970-01-01 08:00:00.000000000 +0800
@@ -1,315 +0,0 @@
-#! /usr/bin/perl
-#                              -*- Mode: Cperl -*-
-# image.preinst ---
-# Author           : Manoj Srivastava ( srivasta@tiamat.datasync.com )
-# Created On       : Sun Jun 14 03:38:02 1998
-# Created On Node  : tiamat.datasync.com
-# Last Modified By : Manoj Srivastava
-# Last Modified On : Sun Sep 24 14:04:42 2006
-# Last Machine Used: glaurung.internal.golden-gryphon.com
-# Update Count     : 99
-# Status           : Unknown, Use with caution!
-# HISTORY          :
-# Description      :
-#
-#
-
-#
-#use strict; #for debugging
-
-use Debconf::Client::ConfModule qw(:all);
-version('2.0');
-my $capb=capb("backup");
-
-$|=1;
-
-# Predefined values:
-my $version         = "=V";
-my $link_in_boot    = "";     # Should be empty, mostly
-my $no_symlink      = "";     # Should be empty, mostly
-my $reverse_symlink = "";     # Should be empty, mostly
-my $do_symlink      = "Yes";	# target machine defined
-my $do_boot_enable  = "Yes";	# target machine defined
-my $do_bootfloppy   = "Yes";	# target machine defined
-my $do_bootloader   = "Yes";	# target machine defined
-my $move_image      = '';       # target machine defined
-my $kimage          = "=K";     # Should be empty, mostly
-my $loader          = "=L";     # lilo, silo, quik, palo, vmelilo, nettrom
-                                # or elilo
-my $image_dir       = "/boot";     # where the image is located
-my $initrd          = "YES";     # initrd kernel
-my $use_hard_links  = '';       # hardlinks do not wirk across fs boundaries
-my $postinst_hook   = '';       #Normally we do not
-my $postrm_hook     = '';       #Normally we do not
-my $preinst_hook    = '';       #Normally we do not
-my $prerm_hook      = '';       #Normally we do not
-my $minimal_swap    = '';       # Do not swap symlinks
-my $ignore_depmod_err = '';    # normally we do not
-my $relink_src_link   = 'YES';	# There is no harm in checking the link
-my $relink_build_link = 'YES'; # There is no harm in checking the link
-my $force_build_link  = '';	 # There is no harm in checking the link
-my $kernel_arch       = "=B";
-my $ramdisk           = "/usr/sbin/update-initramfs";  # List of tools to create initial ram fs.
-my $package_name    = "linux-image-$version";
-
-my $Loader          = "NoLOADER"; #
-$Loader             = "LILO"     if $loader =~ /^lilo/io;
-$Loader             = "SILO"     if $loader =~ /^silo/io;
-$Loader             = "QUIK"     if $loader =~ /^quik/io;
-$Loader             = "yaboot"   if $loader =~ /^yaboot/io;
-$Loader             = "PALO"     if $loader =~ /^palo/io;
-$Loader             = "NETTROM"  if $loader =~ /^nettrom/io;
-$Loader             = "VMELILO"  if $loader =~ /^vmelilo/io;
-$Loader             = "ZIPL"     if $loader =~ /^zipl/io;
-$Loader             = "ELILO"    if $loader =~ /^elilo/io;
-
-
-#known variables
-my @boilerplate     = ();
-my @silotemplate    = ();
-my @quiktemplate    = ();
-my @palotemplate    = ();
-my @vmelilotemplate = ();
-my $bootdevice      = '';
-my $rootdevice      = '';
-my $rootdisk        = '';
-my $rootpartition   = '';
-my $image_dest      = "/";
-my $realimageloc    = "/$image_dir/";
-my $have_conffile   = "";
-my $CONF_LOC        = '/etc/kernel-img.conf';
-my $relative_links  = '';
-my $silent_loader   = '';
-my $warn_reboot     = '';        # Warn that we are installing a version of
-                                 # the kernel we are running
-
-my $modules_base    = '/lib/modules';
-
-die "Pre inst Internal error. Aborting." unless $version;
-
-exit 0 if $ARGV[0] =~ /abort-upgrade/;
-exit 1 unless $ARGV[0] =~ /(install|upgrade)/;
-
-$arch = `uname -i`;
-if ($arch =~ m/86/) {
-	system ("grep -q ' pae ' /proc/cpuinfo");
-	if ($?) {
-			print STDERR "This kernel does not support a non-PAE CPU.\n";
-			exit 1;
-	}
-}
-
-# remove multiple leading slashes; make sure there is at least one.
-$realimageloc  =~ s|^/*|/|o;
-$realimageloc  =~ s|/+|/|o;
-
-if (-r "$CONF_LOC" && -f "$CONF_LOC"  ) {
-  if (open(CONF, "$CONF_LOC")) {
-    while (<CONF>) {
-      chomp;
-      s/\#.*$//g;
-      next if /^\s*$/;
-
-      $do_symlink      = "" if /^\s*do_symlinks\s*=\s*(no|false|0)\s*$/ig;
-      $no_symlink      = "" if /^\s*no_symlinks\s*=\s*(no|false|0)\s*$/ig;
-      $reverse_symlink = "" if /^\s*reverse_symlinks\s*=\s*(no|false|0)\s*$/ig;
-      $link_in_boot    = "" if /^\s*image_in_boot\s*=\s*(no|false|0)\s*$/ig;
-      $link_in_boot    = "" if /^\s*link_in_boot\s*=\s*(no|false|0)\s*$/ig;
-      $move_image      = "" if /^\s*move_image\s*=\s*(no|false|0)\s*$/ig;
-      $do_boot_enable  = '' if /^\s*do_boot_enable\s*=\s*(no|false|0)\s*$/ig;
-      $do_bootfloppy   = '' if /^\s*do_bootfloppy\s*=\s*(no|false|0)\s*$/ig;
-      $do_bootloader   = '' if /^\s*do_bootloader\s*=\s*(no|false|0)\s*$/ig;
-      $relative_links  = '' if /^\s*relative_links \s*=\s*(no|false|0)\s*$/ig;
-      $use_hard_links  = '' if /^\s*use_hard_links\s*=\s*(no|false|0)\s*$/ig;
-      $silent_loader   = '' if /^\s*silent_loader\s*=\s*(no|false|0)\s*$/ig;
-      $warn_reboot     = '' if /^\s*warn_reboot\s*=\s*(no|false|0)\s*$/ig;
-      $minimal_swap    = '' if /^\s*minimal_swap\s*=\s*(no|false|0)\s*$/ig;
-      $ignore_depmod_err = '' if /^\s*ignore_depmod_err\s*=\s*(no|false|0)\s*$/ig;
-      $relink_src_link   = '' if /^\s*relink_src_link\s*=\s*(no|false|0)\s*$/ig;
-      $relink_build_link = '' if /^\s*relink_build_link\s*=\s*(no|false|0)\s*$/ig;
-      $force_build_link = '' if /^\s*force_build_link\s*=\s*(no|false|0)\s*$/ig;
-
-      $do_symlink      = "Yes" if /^\s*do_symlinks\s*=\s*(yes|true|1)\s*$/ig;
-      $no_symlink      = "Yes" if /^\s*no_symlinks\s*=\s*(yes|true|1)\s*$/ig;
-      $reverse_symlink = "Yes" if /^\s*reverse_symlinks\s*=\s*(yes|true|1)\s*$/ig;
-      $link_in_boot    = "Yes" if /^\s*image_in_boot\s*=\s*(yes|true|1)\s*$/ig;
-      $link_in_boot    = "Yes" if /^\s*link_in_boot\s*=\s*(yes|true|1)\s*$/ig;
-      $move_image      = "Yes" if /^\s*move_image\s*=\s*(yes|true|1)\s*$/ig;
-      $do_boot_enable  = "Yes" if /^\s*do_boot_enable\s*=\s*(yes|true|1)\s*$/ig;
-      $do_bootfloppy   = "Yes" if /^\s*do_bootfloppy\s*=\s*(yes|true|1)\s*$/ig;
-      $do_bootloader   = "Yes" if /^\s*do_bootloader\s*=\s*(yes|true|1)\s*$/ig;
-      $relative_links  = "Yes" if /^\s*relative_links\s*=\s*(yes|true|1)\s*$/ig;
-      $use_hard_links  = "Yes" if /^\s*use_hard_links\s*=\s*(yes|true|1)\s*$/ig;
-      $silent_loader   = 'Yes' if /^\s*silent_loader\s*=\s*(yes|true|1)\s*$/ig;
-      $warn_reboot     = 'Yes' if /^\s*warn_reboot\s*=\s*(yes|true|1)\s*$/ig;
-      $minimal_swap    = 'Yes' if /^\s*minimal_swap\s*=\s*(yes|true|1)\s*$/ig;
-      $ignore_depmod_err = 'Yes' if /^\s*ignore_depmod_err\s*=\s*(yes|true|1)\s*$/ig;
-      $relink_src_link   = 'Yes' if /^\s*relink_src_link\s*=\s*(yes|true|1)\s*$/ig;
-      $relink_build_link = 'Yes' if /^\s*relink_build_link\s*=\s*(yes|true|1)\s*$/ig;
-      $force_build_link = 'Yes' if /^\s*force_build_link\s*=\s*(yes|true|1)\s*$/ig;
-
-      $image_dest      = "$1"  if /^\s*image_dest\s*=\s*(\S+)/ig;
-      $postinst_hook   = "$1"  if /^\s*postinst_hook\s*=\s*(\S+)/ig;
-      $postrm_hook     = "$1"  if /^\s*postrm_hook\s*=\s*(\S+)/ig;
-      $preinst_hook    = "$1"  if /^\s*preinst_hook\s*=\s*(\S+)/ig;
-      $prerm_hook      = "$1"  if /^\s*prerm_hook\s*=\s*(\S+)/ig;
-      $ramdisk         = "$1"  if /^\s*ramdisk\s*=\s*(.+)$/ig;
-    }
-    close CONF;
-    $have_conffile = "Yes";
-    $have_conffile = "Yes";	# stop perl complaining
-  }
-}
-
-$ENV{KERNEL_ARCH}=$kernel_arch if $kernel_arch;
-
-# About to upgrade this package from version $2 TO THIS VERSION.
-# "prerm upgrade" has already been called for the old version of
-# this package.
-
-sub find_initrd_tool {
-  my $hostversion = shift;
-  my $version = shift;
-  my @ramdisks =
-    grep {
-      my $args = 
-        "$_ " .
-          "--supported-host-version=$hostversion " .
-            "--supported-target-version=$version " .
-              "1>/dev/null 2>&1"
-                ;
-      system($args) == 0;
-    }
-      split (/[:,\s]+/, $ramdisk);
-}
-
-sub check {
-  my $version = shift;
-  my $lib_modules="$modules_base/$version";
-  my $message = '';
-
-  if (-d "$lib_modules") {
-    opendir(DIR, $lib_modules) || die "can’t opendir $lib_modules: $!";
-    my @children = readdir(DIR);
-    if ($#children > 1) {
-      my @dirs  = grep { -d "$lib_modules/$_" } @children;
-      if ($#dirs > 1) { # we have subdirs
-        my $dir_message='';
-        for my $dir (@dirs) {
-          if ($dir =~/kernel$/) {
-            $dir_message="An older install was detected.\n";
-          }
-          else {
-            $dir_message="Module sub-directories were detected.\n"
-              unless $dir_message;
-          }
-        }
-        $message += $dir_message if $dir_message;
-      }
-
-      my @links = grep { -l "$lib_modules/$_" } @children;
-      if ($#links > -1) {
-        my $links_message = '';
-        for my $link (@links) {
-          next if ($link =~ /^build$/);
-          next if ($link =~ /^source$/);
-          $links_message = "Symbolic links were detected in $modules_base/$version.\n";
-        }
-        $message += $links_message if $links_message;
-      }
-      my @files = grep { -f "$lib_modules/$_" } @children;
-      $message += "Additional files also exist in $modules_base/$version.\n"
-        if ($#files > -1);
-    }
-  }
-  else { $message .= "$lib_modules does not exist. ";}
-  return $message;
-}
-
-if (-d "$modules_base/$version") {
-  my $errors=check($version);
-  warn "Info:\n$errors\n" if $errors;
-}
-
-# set the env var stem
-$ENV{'STEM'} = "linux";
-
-sub exec_script {
-  my $type   = shift;
-  my $script = shift;
-  print STDERR "Running $type hook script $script.\n";
-  system ("$script $version $realimageloc$kimage-$version") &&
-    print STDERR "User $type hook script [$script] ";
-  if ($?) {
-    if ($? == -1) {
-      print STDERR "failed to execute: $!\n";
-    }
-    elsif ($? & 127) {
-      printf STDERR "died with signal %d, %s coredump\n",
-        ($? & 127),  ($? & 128) ? 'with' : 'without';
-    }
-    else {
-      printf STDERR "exited with value %d\n", $? >> 8;
-    }
-    exit $? >> 8;
-  }
-}
-sub run_hook {
-  my $type   = shift;
-  my $script = shift;
-  if ($script =~ m,^/,) {
-    # Full path provided for the hook script
-    if (-x "$script") {
-      &exec_script($type,$script);
-    }
-    else {
-      die "The provided $type hook script [$script] could not be run.\n";
-    }
-  }
-  else {
-    # Look for it in a safe path
-    for my $path ('/bin', '/sbin', '/usr/bin', '/usr/sbin') {
-      if (-x "$path/$script") {
-        &exec_script($type, "$path/$script");
-        return 0;
-      }
-    }
-    # No luck
-    print STDERR "Could not find $type hook script [$script].\n";
-    die "Looked in: '/bin', '/sbin', '/usr/bin', '/usr/sbin'\n";
-  }
-}
-
-
-my $options;
-for (@ARGV) {
-	s,','\\'',g;
-	$options .= " '$_'";
-}
-$ENV{'DEB_MAINT_PARAMS'}="$options";
-
-## Run user hook script here, if any
-if (-x "$preinst_hook") {
-  &run_hook("preinst", $preinst_hook);
-}
-if (-d "/etc/kernel/preinst.d") {
-  print STDERR "Examining /etc/kernel/preinst.d/\n";
-  system ("run-parts --verbose --exit-on-error --arg=$version" .
-          " --arg=$realimageloc$kimage-$version" .
-          " /etc/kernel/preinst.d") &&
-            die "Failed to process /etc/kernel/preinst.d";
-}
-if (-d "/etc/kernel/preinst.d/$version") {
-  print STDERR "Examining /etc/kernel/preinst.d/$version.\n";
-  system ("run-parts --verbose --exit-on-error --arg=$version" .
-          " --arg=$realimageloc$kimage-$version" .
-          " /etc/kernel/preinst.d/$version") &&
-            die "Failed to process /etc/kernel/preinst.d/$version";
-}
-print STDERR "Done.\n";
-
-exit 0;
-
-__END__
-
-
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/debian/control-scripts/prerm linux-linaro-3.4-2012.05-1_cavium/debian/control-scripts/prerm
--- linux-linaro-3.4-2012.05-1_original/debian/control-scripts/prerm	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/debian/control-scripts/prerm	1970-01-01 08:00:00.000000000 +0800
@@ -1,312 +0,0 @@
-#! /usr/bin/perl
-#                              -*- Mode: Perl -*- 
-# image.prerm --- 
-# Author           : root ( root@melkor.pilgrim.umass.edu ) 
-# Created On       : Fri May 17 03:28:59 1996
-# Created On Node  : melkor.pilgrim.umass.edu
-# Last Modified By : Manoj Srivastava
-# Last Modified On : Sat Aug  5 13:14:17 2006
-# Last Machine Used: glaurung.internal.golden-gryphon.com
-# Update Count     : 85
-# Status           : Unknown, Use with caution!
-# HISTORY          : 
-# Description      : 
-# 
-#
-#    $Id: image.prerm,v 1.22 2003/10/07 16:24:20 srivasta Exp $
-#
-# 
-#use strict;
-
-$|=1;
-# Predefined values:
-my $version         = "=V";
-my $link_in_boot    = "";	# Should be empty, mostly
-my $no_symlink      = "";	# Should be empty, mostly
-my $reverse_symlink = "";	# Should be empty, mostly
-my $do_symlinks     = "Yes";	# target machine defined
-my $do_boot_enable  = "Yes";	# target machine defined
-my $do_bootfloppy   = "Yes";	# target machine defined
-my $do_bootloader   = "Yes";	# target machine defined
-my $move_image      = '';       # target machine defined
-my $kimage          = "=K";	# Should be empty, mostly
-my $loader          = "=L";     # lilo, silo, quik, palo, vmelilo, or nettrom
-my $image_dir       = "/boot";     # where the image is located
-my $clobber_modules = '';       # target machine defined
-my $initrd          = "YES";     # initrd kernel
-my $use_hard_links  = '';       # hardlinks do not wirk across fs boundaries
-my $postinst_hook   = '';       #Normally we do not
-my $postrm_hook     = '';       #Normally we do not
-my $preinst_hook    = '';       #Normally we do not
-my $prerm_hook      = '';       #Normally we do not
-my $minimal_swap    = '';       # Do not swap symlinks
-my $ignore_depmod_err = '';	# normally we do not
-my $relink_build_link = 'YES';	# There is no harm in checking the link
-my $force_build_link = '';	# There is no harm in checking the link
-my $kernel_arch       = "=B";
-my $ramdisk           = "/usr/sbin/update-initramfs";
-my $package_name    = "linux-image-$version";
-
-my $Loader          = "NoLOADER"; # 
-$Loader             = "LILO"     if $loader =~ /^lilo/io;
-$Loader             = "SILO"     if $loader =~ /^silo/io;
-$Loader             = "QUIK"     if $loader =~ /^quik/io;
-$Loader             = "yaboot"   if $loader =~ /^yaboot/io;
-$Loader             = "PALO"     if $loader =~ /^palo/io;
-$Loader             = "NETTROM"  if $loader =~ /^nettrom/io;
-$Loader             = "VMELILO"  if $loader =~ /^vmelilo/io;
-$Loader             = "ZIPL"     if $loader =~ /^zipl/io;
-$Loader             = "ELILO"    if $loader =~ /^elilo/io;
-
-
-# This should not point to /tmp, because of security risks.
-my $temp_file_name = "/var/log/$loader" . "_log.$$";
-
-#known variables
-my $image_dest      = "/";
-my $realimageloc    = "/$image_dir/";
-my $have_conffile   = "";
-my $CONF_LOC        = '/etc/kernel-img.conf';
-my $relative_links = '';
-my $silent_loader   = '';
-my $warn_reboot     = 'Yes';     # Warn that we are installing a version of
-                                 # the kernel we are running
-
-# remove multiple leading slashes; make sure there is at least one.
-$realimageloc  =~ s|^/*|/|o;
-$realimageloc  =~ s|/+|/|o;
-
-my $DEBUG = 0;
-
-# Variables used
-my $image='';
-my $ret=0;
-my $seen='';
-my $answer='';
-my $running = '';
-my $WouldInvalidate = 0;
-
-if ($ARGV[0] && ($ARGV[0] =~ /remove/ || $ARGV[0] =~ /upgrade/)) {
-  if (-l "/usr/doc/linux-image-$version") {
-    unlink "/usr/doc/linux-image-$version";
-  }
-}
-
-# Ignore all invocations uxcept when called on to remove
-exit 0 unless ($ARGV[0] && $ARGV[0] =~ /remove/) ;
-
-# Paranoid check to make sure that the correct value is put in there
-if (! $kimage)                    { $kimage = "vmlinuz";} # Hmm. empty
-elsif ($kimage =~ m/^b?uImage$/o) { $kimage = "vmlinuz";} # these produce vmlinuz
-elsif ($kimage =~ m/^b?zImage$/o) { $kimage = "vmlinuz";} # these produce vmlinuz
-elsif ($kimage =~ m/^[iI]mage$/o) { my $nop = $kimage;  }
-elsif ($kimage =~ m/^vmlinux$/o)  { my $nop = $kimage;  }
-else                              { $kimage = "vmlinuz";} # Default
-
-if (-r "$CONF_LOC" && -f "$CONF_LOC"  ) {
-  if (open(CONF, "$CONF_LOC")) {
-    while (<CONF>) {
-      chomp;
-      s/\#.*$//g;
-      next if /^\s*$/;
-
-      $do_symlink      = "" if /^\s*do_symlinks\s*=\s*(no|false|0)\s*$/ig;
-      $no_symlink      = "" if /^\s*no_symlinks\s*=\s*(no|false|0)\s*$/ig;
-      $reverse_symlink = "" if /^\s*reverse_symlinks\s*=\s*(no|false|0)\s*$/ig;
-      $link_in_boot    = "" if /^\s*image_in_boot\s*=\s*(no|false|0)\s*$/ig;
-      $link_in_boot    = "" if /^\s*link_in_boot\s*=\s*(no|false|0)\s*$/ig;
-      $move_image      = "" if /^\s*move_image\s*=\s*(no|false|0)\s*$/ig;
-      $clobber_modules = '' if /^\s*clobber_modules\s*=\s*(no|false|0)\s*$/ig;
-      $do_boot_enable  = '' if /^\s*do_boot_enable\s*=\s*(no|false|0)\s*$/ig;
-      $do_bootfloppy   = '' if /^\s*do_bootfloppy\s*=\s*(no|false|0)\s*$/ig;
-      $relative_links  = '' if /^\s*relative_links \s*=\s*(no|false|0)\s*$/ig;
-      $do_bootloader   = '' if /^\s*do_bootloader\s*=\s*(no|false|0)\s*$/ig;
-      $do_initrd       = '' if /^\s*do_initrd\s*=\s*(no|false|0)\s*$/ig;
-      $use_hard_links  = '' if /^\s*use_hard_links\s*=\s*(no|false|0)\s*$/ig;
-      $silent_loader   = '' if /^\s*silent_loader\s*=\s*(no|false|0)\s*$/ig;
-      $warn_reboot     = '' if /^\s*warn_reboot\s*=\s*(no|false|0)\s*$/ig;
-      $minimal_swap    = '' if /^\s*minimal_swap\s*=\s*(no|false|0)\s*$/ig;
-      $ignore_depmod_err = '' if /^\s*ignore_depmod_err\s*=\s*(no|false|0)\s*$/ig;
-      $relink_build_link = '' if /^\s*relink_build_link\s*=\s*(no|false|0)\s*$/ig;
-      $force_build_link = '' if /^\s*force_build_link\s*=\s*(no|false|0)\s*$/ig;
-
-
-      $do_symlink      = "Yes" if /^\s*do_symlinks\s*=\s*(yes|true|1)\s*$/ig;
-      $no_symlink      = "Yes" if /^\s*no_symlinks\s*=\s*(yes|true|1)\s*$/ig;
-      $reverse_symlink = "Yes" if /^\s*reverse_symlinks\s*=\s*(yes|true|1)\s*$/ig;
-      $link_in_boot    = "Yes" if /^\s*image_in_boot\s*=\s*(yes|true|1)\s*$/ig;
-      $link_in_boot    = "Yes" if /^\s*link_in_boot\s*=\s*(yes|true|1)\s*$/ig;
-      $move_image      = "Yes" if /^\s*move_image\s*=\s*(yes|true|1)\s*$/ig;
-      $clobber_modules = "Yes" if /^\s*clobber_modules\s*=\s*(yes|true|1)\s*$/ig;
-      $do_boot_enable  = "Yes" if /^\s*do_boot_enable\s*=\s*(yes|true|1)\s*$/ig;
-      $do_bootfloppy   = "Yes" if /^\s*do_bootfloppy\s*=\s*(yes|true|1)\s*$/ig;
-      $do_bootloader   = "Yes" if /^\s*do_bootloader\s*=\s*(yes|true|1)\s*$/ig;
-      $relative_links  = "Yes" if /^\s*relative_links\s*=\s*(yes|true|1)\s*$/ig;
-      $do_initrd       = "Yes" if /^\s*do_initrd\s*=\s*(yes|true|1)\s*$/ig;
-      $use_hard_links  = "Yes" if /^\s*use_hard_links\s*=\s*(yes|true|1)\s*$/ig;
-      $silent_loader   = 'Yes' if /^\s*silent_loader\s*=\s*(yes|true|1)\s*$/ig;
-      $warn_reboot     = 'Yes' if /^\s*warn_reboot\s*=\s*(yes|true|1)\s*$/ig;
-      $minimal_swap    = 'Yes' if /^\s*minimal_swap\s*=\s*(yes|true|1)\s*$/ig;
-      $ignore_depmod_err = 'Yes' if /^\s*ignore_depmod_err\s*=\s*(yes|true|1)\s*$/ig;
-      $relink_build_link = 'Yes' if /^\s*relink_build_link\s*=\s*(yes|true|1)\s*$/ig;
-      $force_build_link = 'Yes' if /^\s*force_build_link\s*=\s*(yes|true|1)\s*$/ig;
-
-      $image_dest      = "$1"  if /^\s*image_dest\s*=\s*(\S+)/ig;
-      $postinst_hook   = "$1"  if /^\s*postinst_hook\s*=\s*(\S+)/ig;
-      $postrm_hook     = "$1"  if /^\s*postrm_hook\s*=\s*(\S+)/ig;
-      $preinst_hook    = "$1"  if /^\s*preinst_hook\s*=\s*(\S+)/ig;
-      $prerm_hook      = "$1"  if /^\s*prerm_hook\s*=\s*(\S+)/ig;
-      $ramdisk         = "$1"  if /^\s*ramdisk\s*=\s*(.+)$/ig;
-    }
-    close CONF;
-    $have_conffile = "Yes";
-  }
-}
-
-
-$ENV{KERNEL_ARCH}=$kernel_arch if $kernel_arch;
-
-#check to see if we are trying to remove a running kernel
-# if so we abort right now.
-chop($running=`uname -r`);
-if ($running eq $version) {
-  print STDERR "WARN: Proceeding with removing running kernel image.\n";
-}
-
-#Now, they have an alternate kernel which they are currently running
-
-# This is just us being nice to lilo users.
-
-chdir("/") or die "could not chdir to /:$!\n";
-
-if (-f "/etc/$loader.conf") { #I know, could be a link, but ..
-  open (LILO, "/etc/$loader.conf") || &success(); # this is not critical
-  while (<LILO>) {
-    chop;
-    s/\#.*//;			  # nix the comments
-    next unless /^\s*image\s*=\s(\S+)/o;
-    $image = $1;
-    if ($image && -e $image) {
-      while (defined($image) && -l $image) {
-	$image = readlink ($image);
-      }
-      if (defined($image) && -e $image) {
-	$WouldInvalidate |= $image =~ /$kimage-$version/;
-      }
-      else {
-	&success(); # invalid $loader.conf file
-      }
-    }
-    else {
-      &success(); # invalid $loader.conf file
-    }
-  }
-  close (LILO);
-  if ($WouldInvalidate) {
-    print STFERR "WARN: Proceeding with removing running kernel image.\n";
-    &success();
-  }
-}
-
-
-# set the env var stem
-$ENV{'STEM'} = "linux";
-
-sub exec_script {
-  my $type   = shift;
-  my $script = shift;
-  print STDERR "Running $type hook script $script.\n";
-  system ("$script $version $realimageloc$kimage-$version") &&
-    print STDERR "User $type hook script [$script] ";
-  if ($?) {
-    if ($? == -1) {
-      print STDERR "failed to execute: $!\n";
-    }
-    elsif ($? & 127) {
-      printf STDERR "died with signal %d, %s coredump\n",
-        ($? & 127),  ($? & 128) ? 'with' : 'without';
-    }
-    else {
-      printf STDERR "exited with value %d\n", $? >> 8;
-    }
-    exit $? >> 8;
-  }
-}
-sub run_hook {
-  my $type   = shift;
-  my $script = shift;
-  if ($script =~ m,^/,) {
-    # Full path provided for the hook script
-    if (-x "$script") {
-      &exec_script($type,$script);
-    }
-    else {
-      die "The provided $type hook script [$script] could not be run.\n";
-    }
-  }
-  else {
-    # Look for it in a safe path
-    for my $path ('/bin', '/sbin', '/usr/bin', '/usr/sbin') {
-      if (-x "$path/$script") {
-        &exec_script($type, "$path/$script");
-        return 0;
-      }
-    }
-    # No luck
-    print STDERR "Could not find $type hook script [$script].\n";
-    die "Looked in: '/bin', '/sbin', '/usr/bin', '/usr/sbin'\n";
-  }
-}
-
-
-my $options;
-for (@ARGV) {
-	s,','\\'',g;
-	$options .= " '$_'";
-}
-$ENV{'DEB_MAINT_PARAMS'}="$options";
-
-## Run user hook script here, if any
-if (-x "$prerm_hook") {
-  &run_hook("prerm", $prerm_hook);
-}
-if (-d "/etc/kernel/prerm.d") {
-  print STDERR "Examining /etc/kernel/prerm.d.\n";
-  system ("run-parts --verbose --exit-on-error --arg=$version " . 
-          "--arg=$realimageloc$kimage-$version /etc/kernel/prerm.d") &&
-            die "Failed to process /etc/kernel/prerm.d";
-}
-if (-d "/etc/kernel/prerm.d/$version") {
-  print STDERR "Examining /etc/kernel/prerm.d/$version.\n";
-  system ("run-parts --verbose --exit-on-error --arg=$version" .
-          " --arg=$realimageloc$kimage-$version " .
-          "/etc/kernel/prerm.d/$version") &&
-            die "Failed to process /etc/kernel/prerm.d/$version";
-}
-
-sub success () {
-  # NOTE: need to keep this list in sync with rules.d/2-binary-arch.mk
-  my %files_to_keep = (
-	'modules.builtin'	=> 1,
-	'modules.order'		=> 1,
-  );
-  my $short;
-  for my $file (</lib/modules/$version/modules.*>) {
-    $short = $file; $short =~ s,.*/,,;
-    if (!defined $files_to_keep{$short}) {
-      unlink "$file";
-    }
-  }
-  exit 0;
-}
-
-
-
-&success();
-exit 0;
-__END__
-
-
-
-
-
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/debian/debian.env linux-linaro-3.4-2012.05-1_cavium/debian/debian.env
--- linux-linaro-3.4-2012.05-1_original/debian/debian.env	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/debian/debian.env	1970-01-01 08:00:00.000000000 +0800
@@ -1 +0,0 @@
-DEBIAN=debian.linaro
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/debian/docs/README.inclusion-list linux-linaro-3.4-2012.05-1_cavium/debian/docs/README.inclusion-list
--- linux-linaro-3.4-2012.05-1_original/debian/docs/README.inclusion-list	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/debian/docs/README.inclusion-list	1970-01-01 08:00:00.000000000 +0800
@@ -1,51 +0,0 @@
-This README describes the reason for, and the use of, module
-inclusion lists.
-
-The original Hardy release had the notion of sub-flavours,
-e.g., a flavour that was constructed as a subset of an existing flavour.
-For example, the virtual flavour was extracted from the server flavour using
-a subset of the server flavour modules. However, there were some difficult
-mainteneance issues with regard to packaging, make rules, and scripts. This
-re-implementation of the sub-flavours philosophy is hopefully simpler,
-and retrofitable to all releases.
-
-A module inclusion list looks at the problem of of constructing a package
-from the perspective of what modules do we _want_ in the package, as opposed
-to what modules we _don't_ want. As the kernel matures, more and more devices are added
-which makes the problem of configuration maintenance a real pain in the ass.
-If we took the approach of disabling all of the config options that we don't want,
-then the differences between flavours will quickly become quite large, making
-it difficult to quickly compare the individual flavour configs.  Each time a
-new config option is added then we also have to make a decision about disabling in
-order to continue to keep the minimal number of modules.
-
-A module inclusion list is applied on a per-flavour basis. For example,
-debian.<BRANCH>/control.d/${flavour}.inclusion-list. For example, the
-config for virtual is very close to server and generic, but the inclusion list
-causes the virtual package to be constructed with _only_ the modules described 
-in the inclusion list.
-
-The inclusion list format is a simple bash regular expression list of files. For example,
-
-arch/*/{crypto,kernel,oprofile}
-drivers/acpi/*
-drivers/ata/ahci.ko
-
-These 3 regular expression forms are suitable for expansion by bash and as inputs to 'find'.
-See debian/scripts/module-inclusion for details.
-
-There are 2 log files created as a side effect of the application of the module
-inclusion list; $(flavour).inclusion-list.log and $(flavour).depmod.log.
-
-$(flavour).inclusion-list.log : This log is created while the inclusion list
-modules are being copied. If any are missing, then those warnings go in this log.
-While its not considered a fatal error, you should endevour to correct your inclusion
-list such that there are no missing modules.
-
-$(flavour).depmod.log : The log is created as a result of running depmod on the
-resulting set of modules. If there are missing symbols then you'll find that information
-here. Again, you should modify your inclusion list such that there are no missing
-symbols.
-
-Tim Gardner <tim.gardner@canonical.com>
-June 2, 2010
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/debian/rules linux-linaro-3.4-2012.05-1_cavium/debian/rules
--- linux-linaro-3.4-2012.05-1_original/debian/rules	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/debian/rules	1970-01-01 08:00:00.000000000 +0800
@@ -1,245 +0,0 @@
-#!/usr/bin/make -f
-#
-# $(DEBIAN)/rules for Ubuntu linux
-#
-# Use this however you want, just give credit where credit is due.
-#
-# Copyright (c) 2007 Ben Collins <bcollins@ubuntu.com>
-#
-
-DEBIAN=$(shell awk -F= '($$1 == "DEBIAN") { print $$2 }' <debian/debian.env)
-TIMESTAMP:=$(shell printf %x $$(date +%s))
-_DUMMY:=$(shell sed -i -e '1 s/%TIMESTAMP%/$(TIMESTAMP)/'  $(DEBIAN)/changelog)
-
-# dpkg-buildpackage passes options that are incomptatible
-# with the kernel build.
-unexport CFLAGS
-unexport LDFLAGS
-
-export LC_ALL=C
-export SHELL=/bin/bash -e
-
-# Where do we find the common configuration.
-export DROOT=debian
-
-# Common variables for all architectures
-include $(DROOT)/rules.d/0-common-vars.mk
-
-# Pull in some arch specific stuff
--include $(DEBIAN)/rules.d/$(arch).mk
-
-# Maintainer targets
-include $(DROOT)/rules.d/1-maintainer.mk
-
-# Stages
-ifeq ($(DEB_STAGE),stage1)
-    do_tools=false
-    do_doc_package=false
-    do_source_package=false
-    do_flavour_image_package=false
-    do_flavour_header_package=false
-endif
-
-# Debian Build System targets
-binary: binary-indep binary-arch
-
-binary-arch: binary-indep
-
-build: build-arch build-indep
-
-clean: debian/control
-	dh_testdir
-	dh_testroot
-	dh_clean
-
-	# d-i stuff
-	rm -rf $(DEBIAN)/d-i-$(arch)
-
-	# normal build junk
-	rm -rf $(DEBIAN)/abi/$(release)-$(revision)
-	rm -rf $(builddir)
-	rm -f $(stampdir)/stamp-*
-	rm -rf $(DEBIAN)/linux-*
-
-	# This gets rid of the d-i packages in control
-	cp -f $(DEBIAN)/control.stub $(DEBIAN)/control
-	cat $(DEBIAN)/changelog debian/changelog | \
-		sed -e '1 s/%TIMESTAMP%/$(TIMESTAMP)/' > debian/changelog
-
-	# Install the copyright information.
-	cp -p $(DEBIAN)/copyright debian/copyright
-
-distclean: clean
-	rm -rf $(DEBIAN)/control $(DEBIAN)/control.stub \
-		$(DEBIAN)/d-i/kernel-versions debian/changelog \
-		debian/control debian/control.stub debian/copyright
-
-# Builds the image, arch headers and debug packages
-include $(DROOT)/rules.d/2-binary-arch.mk
-
-# Rules for building the udebs ($(DEBIAN)-installer)
-include $(DROOT)/rules.d/5-udebs.mk
-
-# Builds the source, doc and linux-headers indep packages
-include $(DROOT)/rules.d/3-binary-indep.mk
-
-# Various checks to be performed on builds
-include $(DROOT)/rules.d/4-checks.mk
-
-# Misc stuff
-.PHONY: $(DEBIAN)/control.stub
-$(DEBIAN)/control.stub: $(DEBIAN)/d-i/kernel-versions.in	\
-		$(DROOT)/scripts/control-create		\
-		$(DEBIAN)/control.stub.in			\
-		$(DEBIAN)/changelog			\
-		$(wildcard $(DEBIAN)/control.d/* $(DEBIAN)/sub-flavours/*.vars)
-	for i in $(DEBIAN)/d-i/kernel-versions.in $(DEBIAN)/control.stub.in; do	\
-	  new=`echo $$i | sed 's/\.in$$//'`;					\
-	  cat $$i | sed -e 's/PKGVER/$(release)/g'                              \
-	        -e 's/ABINUM/$(abinum)/g'                                       \
-		-e 's/COMMONSRCPKGNAME/$(common_src_pkg_name)/g'          \
-		-e 's/SRCPKGNAME/$(src_pkg_name)/g'                             \
-		-e 's/=HUMAN=/$(human_arch)/g'                                    \
-	  > $$new;								\
-	done
-	flavours="$(wildcard $(DEBIAN)/control.d/vars.* $(DEBIAN)/sub-flavours/*.vars)";\
-	for i in $$flavours; do							\
-	  $(SHELL) $(DROOT)/scripts/control-create $$i |			\
-		sed -e 's/PKGVER/$(release)/g'                                  \
-		-e 's/ABINUM/$(abinum)/g'                                       \
-		-e 's/COMMONSRCPKGNAME/$(common_src_pkg_name)/g'          \
-		-e 's/SRCPKGNAME/$(src_pkg_name)/g'                             \
-		-e 's/=HUMAN=/$(human_arch)/g'                                    \
-		>> $(DEBIAN)/control.stub;						\
-	done
-	cp $(DEBIAN)/control.stub $(DEBIAN)/control
-
-.PHONY: debian/control
-debian/control: $(DEBIAN)/control.stub
-	rm -rf $(builddir)/modules $(builddir)/firmware			\
-		$(builddir)/kernel-versions $(builddir)/package-list	\
-		$(builddir)/$(DEBIAN)
-	mkdir -p $(builddir)/modules/$(arch)/
-	cp $(DEBIAN)/d-i/modules/* $(builddir)/modules/$(arch)/
-	mkdir -p $(builddir)/firmware/$(arch)/
-	cp $(DEBIAN)/d-i/firmware/* $(builddir)/firmware/$(arch)/
-	cp $(DEBIAN)/d-i/package-list $(DEBIAN)/d-i/kernel-versions $(builddir)/
-	touch $(builddir)/modules/$(arch)/kernel-image
-	# kernel-wedge needs to poke around in $(DEBIAN)/
-	ln -nsf $(CURDIR)/debian $(builddir)/debian
-
-	# Some files may need to differ between architectures
-	if [ -d $(DEBIAN)/d-i/modules-$(arch) ]; then			\
-	    cp $(DEBIAN)/d-i/modules-$(arch)/* \
-		$(builddir)/modules/$(arch)/;				\
-	fi
-	if [ -d $(DEBIAN)/d-i/firmware-$(arch) ]; then			\
-	    cp $(DEBIAN)/d-i/firmware-$(arch)/* \
-		$(builddir)/firmware/$(arch)/;				\
-	fi
-
-	# Remove unwanted stuff for this architecture
-	if [ -r "$(DEBIAN)/d-i/exclude-modules.$(arch)" ]; then		\
-	    (cat $(DEBIAN)/d-i/exclude-modules.$(arch);			\
-	     ls $(builddir)/modules/$(arch)/) | sort | uniq -d |	\
-		(cd $(builddir)/modules/$(arch)/; xargs rm -f);		\
-	fi
-	if [ -r "$(DEBIAN)/d-i/exclude-firmware.$(arch)" ]; then		\
-	    (cat $(DEBIAN)/d-i/exclude-firmware.$(arch);			\
-	     ls $(builddir)/firmware/$(arch)/) | sort | uniq -d |	\
-		(cd $(builddir)/firmware/$(arch)/; xargs rm -f);	\
-	fi
-
-	# Per flavour module lists
-	flavour_modules=`ls $(DEBIAN)/d-i/modules.$(arch)-* 2>/dev/null`	\
-		|| true;						\
-	if [ "$$flavour_modules" != "" ]; then				\
-	    for flav in $$flavour_modules; do				\
-		name=`echo $$flav | sed 's/.*\/modules.$(arch)-//'`;	\
-		mkdir $(builddir)/modules/$(arch)-$$name;		\
-		(cd $(builddir)/modules/; tar cf - `cat ../$$flav`) |	\
-		    (cd $(builddir)/modules/$(arch)-$$name/; tar xf -);	\
-		touch $(builddir)/modules/$(arch)-$$name/kernel-image;	\
-	    done;							\
-	fi
-	flavour_firmware=`ls $(DEBIAN)/d-i/firmware.$(arch)-* 2>/dev/null`	\
-		|| true;						\
-	if [ "$$flavour_firmware" != "" ]; then				\
-	    for flav in $$flavour_firmware; do				\
-		name=`echo $$flav | sed 's/.*\/firmware.$(arch)-//'`;	\
-		mkdir $(builddir)/firmware/$(arch)-$$name;		\
-		(cd $(builddir)/firmware/; tar cf - `cat ../$$flav`) |	\
-		    (cd $(builddir)/firmware/$(arch)-$$name/; tar xf -);\
-		touch $(builddir)/firmware/$(arch)-$$name/kernel-image;	\
-	    done;							\
-	fi
-
-	# Some files may need to differ between flavours
-	flavour_module_dirs=`ls -d $(DEBIAN)/d-i/modules-$(arch)-* 2>/dev/null`\
-		|| true;						\
-	if [ "$$flavour_module_dirs" ]; then				\
-	    for flav in $$flavour_module_dirs; do			\
-		name=`echo $$flav | sed 's/.*\/modules-$(arch)-//'`;	\
-		[ -d $(builddir)/modules/$(arch)-$$name ] ||		\
-		    cp -a $(builddir)/modules/$(arch)			\
-			modules/$(arch)-$$name;				\
-		cp $$flav/* $(builddir)/modules/$(arch)-$$name/;	\
-	    done;							\
-	fi
-	flavour_firmware_dirs=`ls -d $(DEBIAN)/d-i/firmware-$(arch)-* 2>/dev/null`\
-		|| true;						\
-	if [ "$$flavour_firmware_dirs" ]; then				\
-	    for flav in $$flavour_firmware_dirs; do			\
-		name=`echo $$flav | sed 's/.*\/firmware-$(arch)-//'`;	\
-		[ -d $(builddir)/firmware/$(arch)-$$name ] ||		\
-		    cp -a $(builddir)/firmware/$(arch)			\
-			firmware/$(arch)-$$name;			\
-		cp $$flav/* $(builddir)/firmware/$(arch)-$$name/;	\
-	    done;							\
-	fi
-
-	# Remove unwanted stuff for each flavour
-	flavour_exclude=`ls $(DEBIAN)/d-i/exclude-modules.$(arch)-* 2>/dev/null`\
-		|| true;						\
-	if [ "$$flavour_exclude" ]; then				\
-	    for flav in $$flavour_exclude; do				\
-		name=`echo $$flav | sed 's/.*\/exclude-modules.$(arch)-//'`;\
-		[ -d $(builddir)/modules/$(arch)-$$name ] ||		\
-		    cp -a $(builddir)/modules/$(arch) 			\
-			$(builddir)/modules/$(arch)-$$name;		\
-		(cat $$flav;						\
-		 ls $(builddir)/modules/$(arch)-$$name) |		\
-		 sort |	uniq -d |					\
-		    (cd $(builddir)/modules/$(arch)-$$name/;		\
-		     xargs rm -f);					\
-	    done;							\
-	fi
-	flavour_exclude=`ls $(DEBIAN)/d-i/exclude-firmware.$(arch)-* 2>/dev/null`\
-		|| true;						\
-	if [ "$$flavour_exclude" ]; then				\
-	    for flav in $$flavour_exclude; do				\
-		name=`echo $$flav | sed 's/.*\/exclude-firmware.$(arch)-//'`;\
-		[ -d $(builddir)/firmware/$(arch)-$$name ] ||		\
-		    cp -a $(builddir)/firmware/$(arch) 			\
-			$(builddir)/firmware/$(arch)-$$name;		\
-		(cat $$flav;						\
-		 ls $(builddir)/firmware/$(arch)-$$name) |		\
-		 sort |	uniq -d |					\
-		    (cd $(builddir)/firmware/$(arch)-$$name/;		\
-		     xargs rm -f);					\
-	    done;							\
-	fi
-
-	if [ ! -d $(builddir)/modules/$(build_arch) ]; then		\
-		mkdir -p $(builddir)/modules/$(build_arch);		\
-		cp $(builddir)/modules/$(arch)/*			\
-			$(builddir)/modules/$(build_arch);		\
-	fi
-	if [ ! -d $(builddir)/firmware/$(build_arch) ]; then		\
-		mkdir -p $(builddir)/firmware/$(build_arch);		\
-		cp $(builddir)/firmware/$(arch)/*			\
-			$(builddir)/firmware/$(build_arch);		\
-	fi
-
-	cp $(DEBIAN)/control.stub debian/control.stub
-	cd $(builddir) && kernel-wedge gen-control > $(CURDIR)/debian/control
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/debian/rules.d/0-common-vars.mk linux-linaro-3.4-2012.05-1_cavium/debian/rules.d/0-common-vars.mk
--- linux-linaro-3.4-2012.05-1_original/debian/rules.d/0-common-vars.mk	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/debian/rules.d/0-common-vars.mk	1970-01-01 08:00:00.000000000 +0800
@@ -1,235 +0,0 @@
-#
-# The source package name will be the first token from $(DEBIAN)/changelog
-#
-src_pkg_name=$(shell sed -n '1s/^\(.*\) (.*).*$$/\1/p' $(DEBIAN)/changelog)
-# Allow for overriding common_src_pkg_name when we have perflavour source packages
--include $(DEBIAN)/rules.d/vars.mk
-common_src_pkg_name?=src_pkg_name
-
-# Get some version info
-series := oneiric
-release := $(shell sed -n '1s/^$(src_pkg_name).*(\(.*\)-.*).*$$/\1/p' $(DEBIAN)/changelog)
-revisions := $(shell sed -n 's/^$(src_pkg_name)\ .*($(release)-\(.*\)).*$$/\1/p' $(DEBIAN)/changelog | tac)
-revision ?= $(word $(words $(revisions)),$(revisions))
-prev_revisions := $(filter-out $(revision),0.0 $(revisions))
-prev_revision := $(word $(words $(prev_revisions)),$(prev_revisions))
-
-family=ubuntu
-
-# This is an internally used mechanism for the daily kernel builds. It
-# creates packages whose ABI is suffixed with a minimal representation of
-# the current git HEAD sha. If .git/HEAD is not present, then it uses the
-# uuidgen program,
-#
-# AUTOBUILD can also be used by anyone wanting to build a custom kernel
-# image, or rebuild the entire set of Ubuntu packages using custom patches
-# or configs.
-AUTOBUILD=
-
-#
-# This is a way to support some external variables. A good example is
-# a local setup for ccache and distcc See LOCAL_ENV_CC and
-# LOCAL_ENV_DISTCC_HOSTS in the definition of kmake.
-# For example:
-#      LOCAL_ENV_CC="ccache distcc"
-#      LOCAL_ENV_DISTCC_HOSTS="localhost 10.0.2.5 10.0.2.221"
-#
--include $(CURDIR)/../.$(series)-env
-
-ifneq ($(AUTOBUILD),)
-skipabi		= true
-skipmodule	= true
-skipdbg		= true
-gitver=$(shell if test -f .git/HEAD; then cat .git/HEAD; else uuidgen; fi)
-gitverpre=$(shell echo $(gitver) | cut -b -3)
-gitverpost=$(shell echo $(gitver) | cut -b 38-40)
-abi_suffix = -$(gitverpre)$(gitverpost)
-endif
-
-ifneq ($(NOKERNLOG),)
-ubuntu_log_opts += --no-kern-log
-endif
-ifneq ($(PRINTSHAS),)
-ubuntu_log_opts += --print-shas
-endif
-
-# Get the kernels own extra version to be added to the release signature.
-raw_kernelversion=$(shell make kernelversion)
-
-#
-# full_build -- are we doing a full buildd style build
-#
-ifeq ($(wildcard /CurrentlyBuilding),)
-full_build?=false
-else
-full_build?=true
-endif
-
-#
-# The debug packages are ginormous, so you probably want to skip
-# building them (as a developer).
-#
-#ifeq ($(full_build),false)
-#skipdbg=true
-#endif
-
-abinum		:= $(shell echo $(revision) | sed -e 's/\..*//')$(abi_suffix)
-prev_abinum	:= $(shell echo $(prev_revision) | sed -e 's/\..*//')$(abi_suffix)
-abi_release	:= $(release)-$(abinum)
-
-uploadnum	:= $(shell echo $(revision) | sed -e 's/.*\.//')
-ifneq ($(full_build),false)
-  uploadnum	:= $(uploadnum)-Ubuntu
-endif
-
-# XXX: linux-libc-dev got bumped to -803.N inadvertantly by a ti-omap4 upload
-#      shift our version higher for this package only.  Ensure this only
-#      occurs for the v2.6.35 kernel so that we do not propogate this into
-#      any other series.
-raw_uploadnum	:= $(shell echo $(revision) | sed -e 's/.*\.//')
-libc_dev_version :=
-ifeq ($(DEBIAN),debian.master)
-ifeq ($(release),2.6.35)
-libc_dev_version := -v$(release)-$(shell expr "$(abinum)" + 1000).$(raw_uploadnum)
-endif
-endif
-
-DEB_HOST_MULTIARCH = $(shell dpkg-architecture -qDEB_HOST_MULTIARCH)
-DEB_HOST_GNU_TYPE  = $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
-DEB_BUILD_GNU_TYPE = $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)
-DEB_HOST_ARCH = $(shell dpkg-architecture -qDEB_HOST_ARCH)
-DEB_BUILD_ARCH = $(shell dpkg-architecture -qDEB_BUILD_ARCH)
-
-#
-# Detect invocations of the form 'fakeroot debian/rules binary arch=armel'
-# within an x86'en schroot. This only gets you part of the way since the
-# packaging phase fails, but you can at least compile the kernel quickly.
-#
-arch := $(DEB_HOST_ARCH)
-ifneq ($(arch),$(DEB_HOST_ARCH))
-	CROSS_COMPILE ?= $(shell dpkg-architecture -a$(arch) -qDEB_HOST_GNU_TYPE -f 2>/dev/null)-
-endif
-
-#
-# Detect invocations of the form 'dpkg-buildpackage -B -aarmel' within
-# an x86'en schroot. This is the only way to build all of the packages
-# (except for tools).
-#
-ifneq ($(DEB_BUILD_GNU_TYPE),$(DEB_HOST_GNU_TYPE))
-	CROSS_COMPILE ?= $(DEB_HOST_GNU_TYPE)-
-endif
-
-abidir		:= $(CURDIR)/$(DEBIAN)/abi/$(release)-$(revision)/$(arch)
-prev_abidir	:= $(CURDIR)/$(DEBIAN)/abi/$(release)-$(prev_revision)/$(arch)
-commonconfdir	:= $(CURDIR)/$(DEBIAN)/config
-archconfdir	:= $(CURDIR)/$(DEBIAN)/config/$(arch)
-sharedconfdir	:= $(CURDIR)/debian.linaro/config
-builddir	:= $(CURDIR)/debian/build
-stampdir	:= $(CURDIR)/debian/stamps
-
-#
-# The binary package name always starts with linux-image-$KVER-$ABI.$UPLOAD_NUM. There
-# are places that you'll find linux-image hard coded, but I guess thats OK since the
-# assumption that the binary package always starts with linux-image will never change.
-#
-bin_pkg_name=linux-image-$(abi_release)
-extra_pkg_name=linux-image-extra-$(abi_release)
-hdrs_pkg_name=linux-headers-$(abi_release)
-#
-# The generation of content in the doc package depends on both 'AUTOBUILD=' and
-# 'do_doc_package_content=true'. There are usually build errors during the development
-# cycle, so its OK to leave 'do_doc_package_content=false' until those build
-# failures get sorted out. Finally, the doc package doesn't really need to be built
-# for developer testing (its kind of slow), so only do it if on a buildd.
-do_doc_package=true
-do_doc_package_content=true
-ifeq ($(full_build),false)
-do_doc_package_content=false
-endif
-doc_pkg_name=$(common_src_pkg_name)-doc
-
-#
-# Similarly with the linux-source package, you need not build it as a developer. Its
-# somewhat I/O intensive and utterly useless.
-#
-do_source_package=true
-do_source_package_content=true
-ifeq ($(full_build),false)
-do_source_package_content=false
-endif
-
-# linux-libc-dev may not be needed, default to building it.
-do_libc_dev_package=true
-
-# common headers normally is built as an indep package, but may be arch
-do_common_headers_indep=true
-
-# add a 'full source' mode
-do_full_source=false
-
-# build tools
-ifneq ($(wildcard $(CURDIR)/tools),)
-	ifeq ($(do_tools),)
-		ifneq ($(DEB_BUILD_GNU_TYPE),$(DEB_HOST_GNU_TYPE))
-			do_tools=false
-		endif
-	endif
-	do_tools?=true
-else
-	do_tools?=false
-endif
-tools_pkg_name=$(common_src_pkg_name)-tools-$(abi_release)
-tools_common_pkg_name=$(common_src_pkg_name)-tools-common
-
-# The general flavour specific image package.
-do_flavour_image_package=true
-
-# The general flavour specific header package.
-do_flavour_header_package=true
-
-# Support parallel=<n> in DEB_BUILD_OPTIONS (see #209008)
-#
-# These 2 environment variables set the -j value of the kernel build. For example,
-# CONCURRENCY_LEVEL=16 fakeroot $(DEBIAN)/rules binary-debs
-# or
-# DEB_BUILD_OPTIONS=parallel=16 fakeroot $(DEBIAN)/rules binary-debs
-#
-# The default is to use the number of CPUs.
-#
-COMMA=,
-DEB_BUILD_OPTIONS_PARA = $(subst parallel=,,$(filter parallel=%,$(subst $(COMMA), ,$(DEB_BUILD_OPTIONS))))
-ifneq (,$(DEB_BUILD_OPTIONS_PARA))
-  CONCURRENCY_LEVEL := $(DEB_BUILD_OPTIONS_PARA)
-endif
-
-ifeq ($(CONCURRENCY_LEVEL),)
-  # Check the environment
-  CONCURRENCY_LEVEL := $(shell echo $$CONCURRENCY_LEVEL)
-  # No? Then build with the number of CPUs on the host.
-  ifeq ($(CONCURRENCY_LEVEL),)
-      CONCURRENCY_LEVEL := $(shell expr `getconf _NPROCESSORS_ONLN` \* 1)
-  endif
-  # Oh hell, give 'em one
-  ifeq ($(CONCURRENCY_LEVEL),)
-    CONCURRENCY_LEVEL := 1
-  endif
-endif
-
-conc_level		= -j$(CONCURRENCY_LEVEL)
-
-# target_flavour is filled in for each step
-kmake = make ARCH=$(build_arch) \
-	CROSS_COMPILE=$(CROSS_COMPILE) \
-	KERNELVERSION=$(abi_release)-$(target_flavour) \
-	CONFIG_DEBUG_SECTION_MISMATCH=y \
-	KBUILD_BUILD_VERSION="$(uploadnum)" \
-	LOCALVERSION= localver-extra=
-ifneq ($(LOCAL_ENV_CC),)
-kmake += CC=$(LOCAL_ENV_CC) DISTCC_HOSTS=$(LOCAL_ENV_DISTCC_HOSTS)
-endif
-
-# Locking is required in parallel builds to prevent loss of contents
-# of the debian/files.
-lockme_file = $(CURDIR)/debian/.LOCK
-lockme_cmd = flock -w 60
-lockme = $(lockme_cmd) $(lockme_file)
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/debian/rules.d/1-maintainer.mk linux-linaro-3.4-2012.05-1_cavium/debian/rules.d/1-maintainer.mk
--- linux-linaro-3.4-2012.05-1_original/debian/rules.d/1-maintainer.mk	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/debian/rules.d/1-maintainer.mk	1970-01-01 08:00:00.000000000 +0800
@@ -1,121 +0,0 @@
-# The following targets are for the maintainer only! do not run if you don't
-# know what they do.
-
-.PHONY: printenv updateconfigs printchanges insertchanges startnewrelease diffupstream help updateportsconfigs editportsconfigs
-
-help:
-	@echo "These are the targets in addition to the normal $(DEBIAN) ones:"
-	@echo
-	@echo "  printenv        : Print some variables used in the build"
-	@echo
-	@echo "  updateconfigs        : Update core arch configs"
-	@echo
-	@echo "  editconfigs          : Update core arch configs interractively"
-	@echo "  genconfigs           : Generate core arch configs in CONFIGS/*"
-	@echo
-	@echo "  updateportsconfigs   : Update ports arch configs"
-	@echo
-	@echo "  editportsconfigs     : Update ports arch configs interactivly"
-	@echo "  genportconfigs       : Generate ports arch configs in CONFIGS/*"
-	@echo
-	@echo "  printchanges    : Print the current changelog entries (from git)"
-	@echo
-	@echo "  insertchanges   : Insert current changelog entries (from git)"
-	@echo
-	@echo "  startnewrelease : Start a new changelog set"
-	@echo
-	@echo "  diffupstream    : Diff stock kernel code against upstream (git)"
-	@echo
-	@echo "  help            : If you are kernel hacking, you need the professional"
-	@echo "                    version of this"
-	@echo
-	@echo "Environment variables:"
-	@echo
-	@echo "  NOKERNLOG       : Do not add upstream kernel commits to changelog"
-	@echo "  CONCURRENCY_LEVEL=X"
-	@echo "                  : Use -jX for kernel compile"
-	@echo "  PRINTSHAS       : Include SHAs for commits in changelog"
-
-printdebian:
-	@echo "$(DEBIAN)"
-
-updateconfigs defaultconfigs editconfigs genconfigs dumpconfigs:
-	dh_testdir;
-	$(SHELL) $(DROOT)/scripts/misc/kernelconfig $@
-	rm -rf build
-
-updateportsconfigs defaultportsconfigs editportsconfigs genportsconfigs askconfigs:
-	dh_testdir;
-	$(SHELL) $(DROOT)/scripts/misc/kernelconfig $@ ports
-	rm -rf build
-
-printenv:
-	dh_testdir
-	@echo "src package name  = $(src_pkg_name)"
-	@echo "src package name no flavour  = $(common_src_pkg_name)"
-	@echo "release           = $(release)"
-	@echo "revisions         = $(revisions)"
-	@echo "revision          = $(revision)"
-	@echo "uploadnum         = $(uploadnum)"
-	@echo "prev_revisions    = $(prev_revisions)"
-	@echo "prev_revision     = $(prev_revision)"
-	@echo "abinum            = $(abinum)"
-	@echo "gitver            = $(gitver)"
-	@echo "flavours          = $(flavours)"
-	@echo "skipabi           = $(skipabi)"
-	@echo "skipmodule        = $(skipmodule)"
-	@echo "skipdbg           = $(skipdbg)"
-	@echo "ubuntu_log_opts   = $(ubuntu_log_opts)"
-	@echo "CONCURRENCY_LEVEL = $(CONCURRENCY_LEVEL)"
-	@echo "bin package name  = $(bin_pkg_name)"
-	@echo "hdr package name  = $(hdrs_pkg_name)"
-	@echo "doc package name  = $(doc_pkg_name)"
-	@echo "do_doc_package            = $(do_doc_package)"
-	@echo "do_doc_package_content    = $(do_doc_package_content)"
-	@echo "do_source_package         = $(do_source_package)"
-	@echo "do_source_package_content = $(do_source_package_content)"
-	@echo "do_libc_dev_package       = $(do_libc_dev_package)"
-	@echo "do_flavour_image_package  = $(do_flavour_image_package)"
-	@echo "do_flavour_header_package = $(do_flavour_header_package)"
-	@echo "do_common_headers_indep   = $(do_common_headers_indep)"
-	@echo "do_full_source            = $(do_full_source)"
-	@echo "do_tools                  = $(do_tools)"
-	@echo "full_build                = $(full_build)"
-	@echo "libc_dev_version		 = $(libc_dev_version)"
-	@echo "DEB_HOST_GNU_TYPE         = $(DEB_HOST_GNU_TYPE)"
-	@echo "DEB_BUILD_GNU_TYPE        = $(DEB_BUILD_GNU_TYPE)"
-	@echo "DEB_HOST_ARCH             = $(DEB_HOST_ARCH)"
-	@echo "DEB_BUILD_ARCH            = $(DEB_BUILD_ARCH)"
-	@echo "arch                      = $(arch)"
-	@echo "kmake                     = $(kmake)"
-
-prev_release="$(release)-$(prev_revision)"
-printchanges:
-	@baseCommit=$$(git log --pretty=format:'%H %s' | \
-		awk '/LINARO: '".*Linaro-$(release)-$(prev_revision)"'$$/ { print $$1; exit }'); \
-		git log "$$baseCommit"..HEAD | \
-		perl -w -f $(DROOT)/scripts/misc/git-ubuntu-log $(ubuntu_log_opts)
-
-insertchanges:
-	@perl -w -f $(DROOT)/scripts/misc/insert-changes.pl $(DROOT) $(DEBIAN) 
-
-diffupstream:
-	@git diff-tree -p refs/remotes/linux-2.6/master..HEAD $(shell ls | grep -vE '^(ubuntu|$(DEBIAN)|\.git.*)')
-
-startnewrelease:
-	dh_testdir
-	@nextminor=$(shell expr `echo $(revision) | awk -F. '{print $$2}'` + 1); \
-	now="$(shell date -R)"; \
-	echo "Creating new changelog set for $(abi_release).$$nextminor..."; \
-	echo -e "$(src_pkg_name) ($(abi_release).$$nextminor) UNRELEASED; urgency=low\n" > $(DEBIAN)/changelog.new; \
-	echo "  CHANGELOG: Do not edit directly. Autogenerated at release." >> \
-		$(DEBIAN)/changelog.new; \
-	echo "  CHANGELOG: Use the printchanges target to see the curent changes." \
-		>> $(DEBIAN)/changelog.new; \
-	echo "  CHANGELOG: Use the insertchanges target to create the final log." \
-		>> $(DEBIAN)/changelog.new; \
-	echo -e "\n -- $$DEBFULLNAME <$$DEBEMAIL>  $$now\n" >> \
-		$(DEBIAN)/changelog.new ; \
-	cat $(DEBIAN)/changelog >> $(DEBIAN)/changelog.new; \
-	mv $(DEBIAN)/changelog.new $(DEBIAN)/changelog
-
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/debian/rules.d/2-binary-arch.mk linux-linaro-3.4-2012.05-1_cavium/debian/rules.d/2-binary-arch.mk
--- linux-linaro-3.4-2012.05-1_original/debian/rules.d/2-binary-arch.mk	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/debian/rules.d/2-binary-arch.mk	1970-01-01 08:00:00.000000000 +0800
@@ -1,494 +0,0 @@
-# We don't want make removing intermediary stamps
-.SECONDARY :
-
-# Prepare the out-of-tree build directory
-ifeq ($(do_full_source),true)
-build_cd = cd $(builddir)/build-$*; #
-build_O  =
-else
-build_cd =
-build_O  = O=$(builddir)/build-$*
-endif
-
-kbsr      = $(builddir)/build-$*
-
-$(stampdir)/stamp-prepare-%: config-prepare-check-%
-	@echo Debug: $@
-	@touch $@
-$(stampdir)/stamp-prepare-tree-%: target_flavour = $*
-$(stampdir)/stamp-prepare-tree-%: $(commonconfdir)/config.common.$(family) $(archconfdir)/config.common.$(arch) $(archconfdir)/config.flavour.%
-	@echo Debug: $@
-	install -d $(builddir)/build-$*
-	touch $(builddir)/build-$*/ubuntu-build
-	[ "$(do_full_source)" != 'true' ] && true || \
-		rsync -a --exclude debian --exclude debian.master --exclude debian.linaro --exclude $(DEBIAN) * $(builddir)/build-$*
-	cat $^ | sed -e 's/.*CONFIG_VERSION_SIGNATURE.*/CONFIG_VERSION_SIGNATURE="Ubuntu $(release)-$(revision)-$* $(release)$(extraversion)"/' > $(builddir)/build-$*/.config
-	find $(builddir)/build-$* -name "*.ko" | xargs rm -f
-	$(build_cd) $(kmake) $(build_O) -j1 silentoldconfig prepare scripts
-	touch $@
-
-# Used by developers as a shortcut to prepare a tree for compilation.
-prepare-%: $(stampdir)/stamp-prepare-%
-	@echo Debug: $@
-# Used by developers to allow efficient pre-building without fakeroot.
-build-%: $(stampdir)/stamp-build-%
-	@echo Debug: $@
-
-# Do the actual build, including image and modules
-$(stampdir)/stamp-build-%: target_flavour = $*
-$(stampdir)/stamp-build-%: $(stampdir)/stamp-prepare-%
-	@echo Debug: $@
-	$(build_cd) $(kmake) $(build_O) $(conc_level) $(build_image) modules dtbs
-	@touch $@
-
-# Install the finished build
-install-%: pkgdir = $(CURDIR)/debian/$(bin_pkg_name)-$*
-install-%: pkgdir_ex = $(CURDIR)/debian/$(extra_pkg_name)-$*
-install-%: bindoc = $(pkgdir)/usr/share/doc/$(bin_pkg_name)-$*
-install-%: dbgpkgdir = $(CURDIR)/debian/$(bin_pkg_name)-$*-dbgsym
-install-%: basepkg = $(hdrs_pkg_name)
-install-%: hdrdir = $(CURDIR)/debian/$(basepkg)-$*/usr/src/$(basepkg)-$*
-install-%: target_flavour = $*
-install-%: | install-headers
-install-%: checks-%
-	@echo Debug: $@
-	dh_testdir
-	dh_testroot
-	dh_clean -k -p$(bin_pkg_name)-$*
-	dh_clean -k -p$(hdrs_pkg_name)-$*
-	dh_clean -k -p$(dbg_pkg_name)-$*
-
-	# The main image
-	# compress_file logic required because not all architectures
-	# generate a zImage automatically out of the box
-ifeq ($(compress_file),)
-	install -m600 -D $(builddir)/build-$*/$(kernel_file) \
-		$(pkgdir)/boot/$(install_file)-$(abi_release)-$*
-else
-	install -d $(pkgdir)/boot
-	gzip -c9v $(builddir)/build-$*/$(kernel_file) > \
-		$(pkgdir)/boot/$(install_file)-$(abi_release)-$*
-	chmod 600 $(pkgdir)/boot/$(install_file)-$(abi_release)-$*
-endif
-
-	install -m644 $(builddir)/build-$*/.config \
-		$(pkgdir)/boot/config-$(abi_release)-$*
-	install -m644 $(abidir)/$* \
-		$(pkgdir)/boot/abi-$(abi_release)-$*
-	install -m600 $(builddir)/build-$*/System.map \
-		$(pkgdir)/boot/System.map-$(abi_release)-$*
-	mkdir -p $(pkgdir)/boot/dt-$(abi_release)-$*/
-	install -m644 -D $(builddir)/build-$*/arch/$(build_arch)/boot/*.dtb \
-		$(pkgdir)/boot/dt-$(abi_release)-$*/ || \
-		echo "No dtb files for this platform" > \
-		$(pkgdir)/boot/dt-$(abi_release)-$*/README
-ifeq ($(no_dumpfile),)
-	makedumpfile -g $(pkgdir)/boot/vmcoreinfo-$(abi_release)-$* \
-		-x $(builddir)/build-$*/vmlinux
-	chmod 0600 $(pkgdir)/boot/vmcoreinfo-$(abi_release)-$*
-endif
-
-	$(build_cd) $(kmake) $(build_O) $(conc_level) modules_install \
-		INSTALL_MOD_STRIP=1 INSTALL_MOD_PATH=$(pkgdir)/ \
-		INSTALL_FW_PATH=$(pkgdir)/lib/firmware/$(abi_release)-$*
-
-	#
-	# Remove all modules not in the inclusion list.
-	#
-	if [ -f $(DEBIAN)/control.d/$(target_flavour).inclusion-list ] ; then \
-		mkdir -p $(pkgdir_ex)/lib/modules/$(abi_release)-$*; \
-		mv $(pkgdir)/lib/modules/$(abi_release)-$*/kernel \
-			$(pkgdir_ex)/lib/modules/$(abi_release)-$*/kernel; \
-		$(SHELL) $(DROOT)/scripts/module-inclusion --master \
-			$(pkgdir_ex)/lib/modules/$(abi_release)-$*/kernel \
-			$(pkgdir)/lib/modules/$(abi_release)-$*/kernel \
-			$(DEBIAN)/control.d/$(target_flavour).inclusion-list 2>&1 | \
-				tee $(target_flavour).inclusion-list.log; \
-		/sbin/depmod -b $(pkgdir) -ea -F $(pkgdir)/boot/System.map-$(abi_release)-$* \
-			$(abi_release)-$* 2>&1 |tee $(target_flavour).depmod.log; \
-	fi
-
-ifeq ($(no_dumpfile),)
-	makedumpfile -g $(pkgdir)/boot/vmcoreinfo-$(abi_release)-$* \
-		-x $(builddir)/build-$*/vmlinux
-	chmod 0600 $(pkgdir)/boot/vmcoreinfo-$(abi_release)-$*
-endif
-	rm -f $(pkgdir)/lib/modules/$(abi_release)-$*/build
-	rm -f $(pkgdir)/lib/modules/$(abi_release)-$*/source
-
-	# Some initramfs-tools specific modules
-	install -d $(pkgdir)/lib/modules/$(abi_release)-$*/initrd
-	if [ -f $(pkgdir)/lib/modules/$(abi_release)-$*/kernel/drivers/video/vesafb.ko ]; then\
-	  ln -f $(pkgdir)/lib/modules/$(abi_release)-$*/kernel/drivers/video/vesafb.ko \
-		$(pkgdir)/lib/modules/$(abi_release)-$*/initrd/; \
-	fi
-
-	# Now the image scripts
-	install -d $(pkgdir)/DEBIAN
-	for script in postinst postrm preinst prerm; do				\
-	  sed -e 's/=V/$(abi_release)-$*/g' -e 's/=K/$(install_file)/g'		\
-	      -e 's/=L/$(loader)/g'         -e 's@=B@$(build_arch)@g'		\
-	       $(DROOT)/control-scripts/$$script > $(pkgdir)/DEBIAN/$$script;	\
-	  chmod 755 $(pkgdir)/DEBIAN/$$script;					\
-	done
-	# Install the postinit/postrm scripts in the extras package.
-	if [ -f $(DEBIAN)/control.d/$(target_flavour).inclusion-list ] ; then	\
-		install -d $(pkgdir_ex)/DEBIAN;					\
-		for script in postinst postrm ; do				\
-			sed -e 's/@@KVER@@/$(release)-$(abinum)-$(target_flavour)/g' \
-				debian/control-scripts/$$script.extra > $(pkgdir_ex)/DEBIAN/$$script; \
-			chmod 755 $(pkgdir_ex)/DEBIAN/$$script;			\
-		done;								\
-	fi
-
-	# Install the full changelog.
-ifeq ($(do_doc_package),true)
-	install -d $(bindoc)
-	cat $(DEBIAN)/changelog $(DEBIAN)/changelog.historical | \
-		gzip -9 >$(bindoc)/changelog.Debian.old.gz
-	chmod 644 $(bindoc)/changelog.Debian.old.gz
-endif
-
-ifneq ($(skipsub),true)
-	for sub in $($(*)_sub); do					\
-		if ! (TO=$$sub FROM=$* ABI_RELEASE=$(abi_release) $(SHELL)		\
-			$(DROOT)/scripts/sub-flavour); then exit 1; fi;		\
-		/sbin/depmod -b debian/$(bin_pkg_name)-$$sub		\
-			-ea -F debian/$(bin_pkg_name)-$$sub/boot/System.map-$(abi_release)-$* \
-			$(abi_release)-$*;					\
-		install -d debian/$(bin_pkg_name)-$$sub/DEBIAN;	\
-		for script in postinst postrm preinst prerm; do			\
-			sed -e 's/=V/$(abi_release)-$*/g'			\
-			    -e 's/=K/$(install_file)/g'				\
-			    -e 's/=L/$(loader)/g'				\
-			    -e 's@=B@$(build_arch)@g'				\
-				$(DROOT)/control-scripts/$$script >		\
-				debian/$(bin_pkg_name)-$$sub/DEBIAN/$$script;\
-			chmod 755  debian/$(bin_pkg_name)-$$sub/DEBIAN/$$script;\
-		done;								\
-	done
-endif
-
-ifneq ($(skipdbg),true)
-	# Debug image is simple
-	install -m644 -D $(builddir)/build-$*/vmlinux \
-		$(dbgpkgdir)/usr/lib/debug/boot/vmlinux-$(abi_release)-$*
-	$(build_cd) $(kmake) $(build_O) modules_install \
-		INSTALL_MOD_PATH=$(dbgpkgdir)/usr/lib/debug
-	# Add .gnu_debuglink sections to each stripped .ko
-	# pointing to unstripped verson
-	find $(pkgdir) -name '*.ko' | sed 's|$(pkgdir)||' | while read module ; do \
-		$(CROSS_COMPILE)objcopy \
-			--add-gnu-debuglink=$(dbgpkgdir)/usr/lib/debug/$$module \
-			$(pkgdir)/$$module; \
-	done
-	rm -f $(dbgpkgdir)/usr/lib/debug/lib/modules/$(abi_release)-$*/build
-	rm -f $(dbgpkgdir)/usr/lib/debug/lib/modules/$(abi_release)-$*/source
-	rm -f $(dbgpkgdir)/usr/lib/debug/lib/modules/$(abi_release)-$*/modules.*
-	rm -fr $(dbgpkgdir)/usr/lib/debug/lib/firmware
-endif
-
-	# The flavour specific headers image
-	# TODO: Would be nice if we didn't have to dupe the original builddir
-	install -d -m755 $(hdrdir)
-	cat $(builddir)/build-$*/.config | \
-		sed -e 's/.*CONFIG_DEBUG_INFO=.*/# CONFIG_DEBUG_INFO is not set/g' > \
-		$(hdrdir)/.config
-	chmod 644 $(hdrdir)/.config
-	$(kmake) HOSTCC=$(CROSS_COMPILE)gcc KBUILD_SCRIPTROOT=$(kbsr) O=$(hdrdir) -j1 silentoldconfig prepare scripts
-	# We'll symlink this stuff
-	rm -f $(hdrdir)/Makefile
-	rm -rf $(hdrdir)/include2
-	# powerpc seems to need some .o files for external module linking. Add them in.
-ifeq ($(arch),powerpc)
-	mkdir -p $(hdrdir)/arch/powerpc/lib
-	cp $(builddir)/build-$*/arch/powerpc/lib/*.o $(hdrdir)/arch/powerpc/lib
-endif
-	# Script to symlink everything up
-	$(SHELL) $(DROOT)/scripts/link-headers "$(hdrdir)" "$(basepkg)" "$*"
-ifeq ($(do_complete_flavour_headers),true)
-	rsync -a debian/$(basepkg)/usr debian/$(basepkg)-$*
-endif
-	# The build symlink
-	install -d debian/$(basepkg)-$*/lib/modules/$(abi_release)-$*
-	ln -s /usr/src/$(basepkg)-$* \
-		debian/$(basepkg)-$*/lib/modules/$(abi_release)-$*/build
-	# And finally the symvers
-	install -m644 $(builddir)/build-$*/Module.symvers \
-		$(hdrdir)/Module.symvers
-
-	# Now the header scripts
-	install -d $(CURDIR)/debian/$(basepkg)-$*/DEBIAN
-	for script in postinst; do						\
-	  sed -e 's/=V/$(abi_release)-$*/g' -e 's/=K/$(install_file)/g'	\
-		$(DROOT)/control-scripts/headers-$$script > 			\
-			$(CURDIR)/debian/$(basepkg)-$*/DEBIAN/$$script;		\
-	  chmod 755 $(CURDIR)/debian/$(basepkg)-$*/DEBIAN/$$script;		\
-	done
-
-	# At the end of the package prep, call the tests
-	DPKG_ARCH="$(arch)" KERN_ARCH="$(build_arch)" FLAVOUR="$*"	\
-	 VERSION="$(abi_release)" REVISION="$(revision)"		\
-	 PREV_REVISION="$(prev_revision)" ABI_NUM="$(abinum)"		\
-	 PREV_ABI_NUM="$(prev_abinum)" BUILD_DIR="$(builddir)/build-$*"	\
-	 INSTALL_DIR="$(pkgdir)" SOURCE_DIR="$(CURDIR)"			\
-	 run-parts -v $(DROOT)/tests
-
-	#
-	# Remove files which are generated at installation by postinst,
-	# except for modules.order and modules.builtin
-	# 
-	# NOTE: need to keep this list in sync with postrm
-	#
-	mkdir $(pkgdir)/lib/modules/$(abi_release)-$*/_
-	mv $(pkgdir)/lib/modules/$(abi_release)-$*/modules.order \
-		$(pkgdir)/lib/modules/$(abi_release)-$*/_
-	if [ -f $(pkgdir)/lib/modules/$(abi_release)-$*/modules.builtin ] ; then \
-	    mv $(pkgdir)/lib/modules/$(abi_release)-$*/modules.builtin \
-		$(pkgdir)/lib/modules/$(abi_release)-$*/_; \
-	fi
-	rm -f $(pkgdir)/lib/modules/$(abi_release)-$*/modules.*
-	mv $(pkgdir)/lib/modules/$(abi_release)-$*/_/* \
-		$(pkgdir)/lib/modules/$(abi_release)-$*
-	rmdir $(pkgdir)/lib/modules/$(abi_release)-$*/_
-
-headers_tmp := $(CURDIR)/debian/tmp-headers
-headers_dir := $(CURDIR)/debian/linux-libc-dev
-
-hmake := $(MAKE) -C $(CURDIR) O=$(headers_tmp) \
-	KERNELVERSION=$(abi_release) INSTALL_HDR_PATH=$(headers_tmp)/install \
-	SHELL="$(SHELL)" ARCH=$(header_arch)
-
-install-arch-headers:
-	@echo Debug: $@
-	dh_testdir
-	dh_testroot
-	dh_clean -k -plinux-libc-dev
-
-	rm -rf $(headers_tmp)
-	install -d $(headers_tmp) $(headers_dir)/usr/include/
-
-	$(hmake) $(defconfig)
-	mv $(headers_tmp)/.config $(headers_tmp)/.config.old
-	sed -e 's/^# \(CONFIG_MODVERSIONS\) is not set$$/\1=y/' \
-	  -e 's/.*CONFIG_LOCALVERSION_AUTO.*/# CONFIG_LOCALVERSION_AUTO is not set/' \
-	  $(headers_tmp)/.config.old > $(headers_tmp)/.config
-	$(hmake) silentoldconfig
-	$(hmake) $(conc_level) headers_install
-
-	( cd $(headers_tmp)/install/include/ && \
-		find . -name '.' -o -name '.*' -prune -o -print | \
-                cpio -pvd --preserve-modification-time \
-			$(headers_dir)/usr/include/ )
-	mkdir $(headers_dir)/usr/include/$(DEB_HOST_MULTIARCH)
-	mv $(headers_dir)/usr/include/asm $(headers_dir)/usr/include/$(DEB_HOST_MULTIARCH)/
-
-	rm -rf $(headers_tmp)
-
-binary-arch-headers: install-arch-headers
-	@echo Debug: $@
-	dh_testdir
-	dh_testroot
-ifeq ($(do_libc_dev_package),true)
-ifneq ($(DEBIAN),debian.master)
-	echo "non-master branch building linux-libc-dev, aborting"
-	exit 1
-endif
-	dh_installchangelogs -plinux-libc-dev
-	dh_installdocs -plinux-libc-dev
-	dh_compress -plinux-libc-dev
-	dh_fixperms -plinux-libc-dev
-	dh_installdeb -plinux-libc-dev
-	$(lockme) dh_gencontrol -plinux-libc-dev -- $(libc_dev_version)
-	dh_md5sums -plinux-libc-dev
-	dh_builddeb -plinux-libc-dev
-endif
-
-binary-%: pkgimg = $(bin_pkg_name)-$*
-binary-%: pkgimg_ex = $(extra_pkg_name)-$*
-binary-%: pkghdr = $(hdrs_pkg_name)-$*
-binary-%: dbgpkg = $(bin_pkg_name)-$*-dbgsym
-binary-%: dbgpkgdir = $(CURDIR)/debian/$(bin_pkg_name)-$*-dbgsym
-binary-%: target_flavour = $*
-binary-%: install-%
-	@echo Debug: $@
-	dh_testdir
-	dh_testroot
-
-	dh_installchangelogs -p$(pkgimg)
-	dh_installdocs -p$(pkgimg)
-	dh_compress -p$(pkgimg)
-	dh_fixperms -p$(pkgimg) -X/boot/
-	dh_installdeb -p$(pkgimg)
-	dh_shlibdeps -p$(pkgimg)
-	$(lockme) dh_gencontrol -p$(pkgimg)
-	dh_md5sums -p$(pkgimg)
-	dh_builddeb -p$(pkgimg) -- -Zbzip2 -z9
-
-	if [ -f $(DEBIAN)/control.d/$(target_flavour).inclusion-list ] ; then \
-		dh_installchangelogs -p$(pkgimg_ex); \
-		dh_installdocs -p$(pkgimg_ex); \
-		dh_compress -p$(pkgimg_ex); \
-		dh_fixperms -p$(pkgimg_ex) -X/boot/; \
-		dh_installdeb -p$(pkgimg_ex); \
-		dh_shlibdeps -p$(pkgimg_ex); \
-		$(lockme) dh_gencontrol -p$(pkgimg_ex); \
-		dh_md5sums -p$(pkgimg_ex); \
-		dh_builddeb -p$(pkgimg_ex) -- -Zbzip2 -z9; \
-	fi
-
-	dh_installchangelogs -p$(pkghdr)
-	dh_installdocs -p$(pkghdr)
-	dh_strip -p$(pkghdr)
-	dh_compress -p$(pkghdr)
-	dh_fixperms -p$(pkghdr)
-	dh_shlibdeps -p$(pkghdr)
-	dh_installdeb -p$(pkghdr)
-	$(lockme) dh_gencontrol -p$(pkghdr)
-	dh_md5sums -p$(pkghdr)
-	dh_builddeb -p$(pkghdr)
-
-ifneq ($(skipsub),true)
-	@set -e; for sub in $($(*)_sub); do		\
-		pkg=$(bin_pkg_name)-$$sub;	\
-		dh_installchangelogs -p$$pkg;		\
-		dh_installdocs -p$$pkg;			\
-		dh_compress -p$$pkg;			\
-		dh_fixperms -p$$pkg -X/boot/;		\
-		dh_shlibdeps -p$$pkg;			\
-		dh_installdeb -p$$pkg;			\
-		$(lockme) dh_gencontrol -p$$pkg;			\
-		dh_md5sums -p$$pkg;			\
-		dh_builddeb -p$$pkg;			\
-	done
-endif
-
-ifneq ($(skipdbg),true)
-	dh_installchangelogs -p$(dbgpkg)
-	dh_installdocs -p$(dbgpkg)
-	dh_compress -p$(dbgpkg)
-	dh_fixperms -p$(dbgpkg)
-	dh_installdeb -p$(dbgpkg)
-	$(lockme) dh_gencontrol -p$(dbgpkg)
-	dh_md5sums -p$(dbgpkg)
-	dh_builddeb -p$(dbgpkg)
-
-	# Hack Alert! Commenting the section out for linaro ppa build only
-	# Must not upload this to primary archive as is.
-	# Turns out that Purpose: PRIMARY is in /CurrentlyBuilding
-	# and not PPA as was expected
-	
-	# Hokay...here's where we do a little twiddling...
-	# Renaming the debug package prevents it from getting into
-	# the primary archive, and therefore prevents this very large
-	# package from being mirrored. It is instead, through some
-	# archive admin hackery, copied to http://ddebs.ubuntu.com.
-	#
-	# Only do this for PRIMARY archive for now
-	#
-	#set -e; \
-	#( \
-	#	$(lockme_cmd) 9 || exit 1; \
-	#	if grep -qs '^Purpose: PRIMARY$$' /CurrentlyBuilding; then \
-	#		mv ../$(dbgpkg)_$(release)-$(revision)_$(arch).deb \
-	#			../$(dbgpkg)_$(release)-$(revision)_$(arch).ddeb; \
-	#		if grep -qs '^Build-Debug-Symbols: yes$$' /CurrentlyBuilding; then \
-	#			sed -i '/^$(dbgpkg)_/s/\.deb /.ddeb /' debian/files; \
-	#		else \
-	#			grep -v '^$(dbgpkg)_.*$$' debian/files > debian/files.new; \
-	#			mv debian/files.new debian/files; \
-	#		fi; \
-	#	fi; \
-	#) 9>$(lockme_file)
-	# Now, the package wont get into the archive, but it will get put
-	# into the debug system.
-endif
-ifneq ($(full_build),false)
-	# Clean out this flavours build directory.
-	rm -rf $(builddir)/build-$*
-	# Clean out the debugging package source directory.
-	rm -rf $(dbgpkgdir)
-endif
-
-#
-# per-architecture packages
-#
-builddirpa = $(builddir)/tools-perarch
-
-$(stampdir)/stamp-prepare-perarch:
-	@echo Debug: $@
-ifeq ($(do_tools),true)
-	rm -rf $(builddirpa)
-	install -d $(builddirpa)
-	for i in *; do ln -s $(CURDIR)/$$i $(builddirpa); done
-	rm $(builddirpa)/tools
-	rsync -a tools/ $(builddirpa)/tools/
-endif
-	touch $@
-
-$(stampdir)/stamp-build-perarch: $(stampdir)/stamp-prepare-perarch
-	@echo Debug: $@
-ifeq ($(do_tools),true)
-	cd $(builddirpa)/tools/perf && \
-		make HAVE_CPLUS_DEMANGLE=1 CROSS_COMPILE=$(CROSS_COMPILE)
-	if [ "$(arch)" = "amd64" ] || [ "$(arch)" = "i386" ]; then \
-		cd $(builddirpa)/tools/power/x86/x86_energy_perf_policy && make CROSS_COMPILE=$(CROSS_COMPILE); \
-		cd $(builddirpa)/tools/power/x86/turbostat && make CROSS_COMPILE=$(CROSS_COMPILE); \
-		cd $(builddirpa)/tools/hv && make CROSS_COMPILE=$(CROSS_COMPILE) CFLAGS=-I../../include; \
-	fi
-endif
-	@touch $@
-
-install-perarch: toolspkgdir = $(CURDIR)/debian/$(tools_pkg_name)
-install-perarch: $(stampdir)/stamp-build-perarch
-	@echo Debug: $@
-	# Add the tools.
-ifeq ($(do_tools),true)
-	install -d $(toolspkgdir)/usr/bin
-	install -s -m755 $(builddirpa)/tools/perf/perf \
-		$(toolspkgdir)/usr/bin/perf_$(abi_release)
-	if [ "$(arch)" = "amd64" ] || [ "$(arch)" = "i386" ]; then \
-		install -s -m755 $(builddirpa)/tools/power/x86/x86_energy_perf_policy/x86_energy_perf_policy \
-			$(toolspkgdir)/usr/bin/x86_energy_perf_policy_$(abi_release); \
-		install -s -m755 $(builddirpa)/tools/power/x86/turbostat/turbostat \
-			$(toolspkgdir)/usr/bin/turbostat_$(abi_release); \
-		install -d $(toolspkgdir)/usr/sbin; \
-		install -s -m755 $(builddirpa)/tools/hv/hv_kvp_daemon \
-			$(toolspkgdir)/usr/sbin/hv_kvp_daemon_$(abi_release); \
-	fi
-endif
-
-binary-perarch: toolspkg = $(tools_pkg_name)
-binary-perarch: install-perarch
-	@echo Debug: $@
-ifeq ($(do_tools),true)
-	dh_installchangelogs -p$(toolspkg)
-	dh_installdocs -p$(toolspkg)
-	dh_compress -p$(toolspkg)
-	dh_fixperms -p$(toolspkg)
-	dh_shlibdeps -p$(toolspkg)
-	dh_installdeb -p$(toolspkg)
-	$(lockme) dh_gencontrol -p$(toolspkg)
-	dh_md5sums -p$(toolspkg)
-	dh_builddeb -p$(toolspkg)
-endif
-
-binary-debs: binary-perarch $(addprefix binary-,$(flavours))
-	@echo Debug: $@
-
-build-arch-deps-$(do_flavour_image_package) += $(addprefix $(stampdir)/stamp-build-,$(flavours))
-build-arch: $(build-arch-deps-true)
-	@echo Debug: $@
-
-ifeq ($(AUTOBUILD),)
-binary-arch-deps-$(do_flavour_image_package) += binary-udebs
-else
-binary-arch-deps-$(do_flavour_image_package) = binary-debs
-endif
-binary-arch-deps-$(do_libc_dev_package) += binary-arch-headers
-ifneq ($(do_common_headers_indep),true)
-binary-arch-deps-$(do_flavour_header_package) += binary-headers
-endif
-binary-arch: $(binary-arch-deps-true)
-	@echo Debug: $@
-
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/debian/rules.d/3-binary-indep.mk linux-linaro-3.4-2012.05-1_cavium/debian/rules.d/3-binary-indep.mk
--- linux-linaro-3.4-2012.05-1_original/debian/rules.d/3-binary-indep.mk	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/debian/rules.d/3-binary-indep.mk	1970-01-01 08:00:00.000000000 +0800
@@ -1,155 +0,0 @@
-build-indep:
-	@echo Debug: $@
-
-docpkg = $(doc_pkg_name)
-docdir = $(CURDIR)/debian/$(docpkg)/usr/share/doc/$(docpkg)
-install-doc: install-headers
-	@echo Debug: $@
-ifeq ($(do_doc_package),true)
-	dh_testdir
-	dh_testroot
-	dh_clean -k -p$(docpkg)
-
-	install -d $(docdir)
-ifeq ($(do_doc_package_content),true)
-	# First the html docs. We skip these for autobuilds
-	if [ -z "$(AUTOBUILD)" ]; then \
-		install -d $(docdir)/$(doc_pkg_name)-tmp; \
-		$(kmake) O=$(docdir)/$(doc_pkg_name)-tmp htmldocs; \
-		mv $(docdir)/$(doc_pkg_name)-tmp/Documentation/DocBook \
-			$(docdir)/html; \
-		rm -rf $(docdir)/$(doc_pkg_name)-tmp; \
-	fi
-endif
-	# Copy the rest
-	cp -a Documentation/* $(docdir)
-	rm -rf $(docdir)/DocBook
-	find $(docdir) -name .gitignore | xargs rm -f
-endif
-
-indep_hdrpkg = $(hdrs_pkg_name)
-indep_hdrdir = $(CURDIR)/debian/$(indep_hdrpkg)/usr/src/$(indep_hdrpkg)
-install-headers:
-	@echo Debug: $@
-ifeq ($(do_flavour_header_package),true)
-	dh_testdir
-	dh_testroot
-	dh_clean -k -p$(indep_hdrpkg)
-
-	install -d $(indep_hdrdir)
-	find . -path './debian' -prune -o -path './$(DEBIAN)' -prune \
-	  -o -path './include/*' -prune \
-	  -o -path './scripts/*' -prune -o -type f \
-	  \( -name 'Makefile*' -o -name 'Kconfig*' -o -name 'Kbuild*' -o \
-	     -name '*.sh' -o -name '*.pl' -o -name '*.lds' \) \
-	  -print | cpio -pd --preserve-modification-time $(indep_hdrdir)
-	cp -a drivers/media/dvb/dvb-core/*.h $(indep_hdrdir)/drivers/media/dvb/dvb-core
-	cp -a drivers/media/video/*.h $(indep_hdrdir)/drivers/media/video
-	cp -a drivers/media/dvb/frontends/*.h $(indep_hdrdir)/drivers/media/dvb/frontends
-	cp -a scripts include $(indep_hdrdir)
-	(find arch -name include -type d -print | \
-		xargs -n1 -i: find : -type f) | \
-		cpio -pd --preserve-modification-time $(indep_hdrdir)
-endif
-
-srcpkg = $(src_pkg_name)-source-$(release)
-srcdir = $(CURDIR)/debian/$(srcpkg)/usr/src/$(srcpkg)
-balldir = $(CURDIR)/debian/$(srcpkg)/usr/src/$(srcpkg)/$(srcpkg)
-install-source: install-doc
-	@echo Debug: $@
-ifeq ($(do_source_package),true)
-	dh_testdir
-	dh_testroot
-	dh_clean -k -p$(srcpkg)
-
-	install -d $(srcdir)
-ifeq ($(do_source_package_content),true)
-	find . -path './debian' -prune -o -path './$(DEBIAN)' -prune -o \
-		-path './.*' -prune -o -print | \
-		cpio -pd --preserve-modification-time $(balldir)
-	(cd $(srcdir); tar cf - $(srcpkg)) | bzip2 -9c > \
-		$(srcdir)/$(srcpkg).tar.bz2
-	rm -rf $(balldir)
-	find './debian' './$(DEBIAN)' \
-		-path './debian/linux-*' -prune -o \
-		-path './debian/$(src_pkg_name)-*' -prune -o \
-		-path './debian/build' -prune -o \
-		-path './debian/files' -prune -o \
-		-path './debian/stamps' -prune -o \
-		-path './debian/tmp' -prune -o \
-		-print | \
-		cpio -pd --preserve-modification-time $(srcdir)
-	ln -s $(srcpkg)/$(srcpkg).tar.bz2 $(srcdir)/..
-endif
-endif
-
-install-tools: toolspkg = $(tools_common_pkg_name)
-install-tools: toolsbin = $(CURDIR)/debian/$(toolspkg)/usr/bin
-install-tools: toolssbin = $(CURDIR)/debian/$(toolspkg)/usr/sbin
-install-tools: toolsman = $(CURDIR)/debian/$(toolspkg)/usr/share/man
-install-tools: install-source $(stampdir)/stamp-build-perarch
-	@echo Debug: $@
-ifeq ($(do_tools),true)
-	dh_testdir
-	dh_testroot
-	dh_clean -k -p$(toolspkg)
-
-	install -d $(toolsbin)
-	install -d $(toolsman)/man1
-
-	install -m755 debian/tools/perf $(toolsbin)/perf
-	if [ "$(arch)" = "amd64" ] || [ "$(arch)" = "i386" ]; then \
-		install -m755 debian/tools/x86_energy_perf_policy $(toolsbin)/x86_energy_perf_policy; \
-		install -m755 debian/tools/turbostat $(toolsbin)/turbostat; \
-		install -d $(toolssbin) ; \
-		install -m755 debian/tools/generic $(toolssbin)/hv_kvp_daemon; \
-	fi
-
-	rm -rf $(builddir)/tools
-	install -d $(builddir)/tools
-	for i in *; do ln -s $(CURDIR)/$$i $(builddir)/tools/; done
-	rm $(builddir)/tools/tools
-	rsync -a tools/ $(builddir)/tools/tools/
-
-	cd $(builddir)/tools/tools/perf && make man
-	install -m644 $(builddir)/tools/tools/perf/Documentation/*.1 \
-		$(toolsman)/man1
-	if [ "$(arch)" = "amd64" ] || [ "$(arch)" = "i386" ]; then \
-		install -d $(toolsman)/man8; \
-		install -m644 $(CURDIR)/tools/power/x86/x86_energy_perf_policy/*.8 $(toolsman)/man8; \
-		install -m644 $(CURDIR)/tools/power/x86/turbostat/*.8 $(toolsman)/man8; \
-		install -m644 $(CURDIR)/tools/hv/*.8 $(toolsman)/man8; \
-	fi
-endif
-
-install-indep: install-tools
-	@echo Debug: $@
-
-# This is just to make it easy to call manually. Normally done in
-# binary-indep target during builds.
-binary-headers: install-headers
-	@echo Debug: $@
-	dh_testdir
-	dh_testroot
-	dh_installchangelogs -p$(indep_hdrpkg)
-	dh_installdocs -p$(indep_hdrpkg)
-	dh_compress -p$(indep_hdrpkg)
-	dh_fixperms -p$(indep_hdrpkg)
-	dh_installdeb -p$(indep_hdrpkg)
-	$(lockme) dh_gencontrol -p$(indep_hdrpkg)
-	dh_md5sums -p$(indep_hdrpkg)
-	dh_builddeb -p$(indep_hdrpkg)
-
-binary-indep: install-indep
-	@echo Debug: $@
-	dh_testdir
-	dh_testroot
-
-	dh_installchangelogs -i
-	dh_installdocs -i
-	dh_compress -i
-	dh_fixperms -i
-	dh_installdeb -i
-	$(lockme) dh_gencontrol -i
-	dh_md5sums -i
-	dh_builddeb -i
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/debian/rules.d/4-checks.mk linux-linaro-3.4-2012.05-1_cavium/debian/rules.d/4-checks.mk
--- linux-linaro-3.4-2012.05-1_original/debian/rules.d/4-checks.mk	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/debian/rules.d/4-checks.mk	1970-01-01 08:00:00.000000000 +0800
@@ -1,27 +0,0 @@
-# Check ABI for package against last release (if not same abinum)
-abi-check-%: $(stampdir)/stamp-build-%
-	@echo Debug: $@
-	install -d $(abidir)
-	sed -e 's/^\(.\+\)[[:space:]]\+\(.\+\)[[:space:]]\(.\+\)$$/\3 \2 \1/'	\
-		$(builddir)/build-$*/Module.symvers | sort > $(abidir)/$*
-	@perl -f $(DROOT)/scripts/abi-check "$*" "$(prev_abinum)" "$(abinum)" \
-		"$(prev_abidir)" "$(abidir)" "$(skipabi)"
-
-# Check the module list against the last release (always)
-module-check-%: $(stampdir)/stamp-build-%
-	@echo Debug: $@
-	install -d $(abidir)
-	find $(builddir)/build-$*/ -name \*.ko | \
-		sed -e 's/.*\/\([^\/]*\)\.ko/\1/' | sort > $(abidir)/$*.modules
-	@perl -f $(DROOT)/scripts/module-check "$*" \
-		"$(prev_abidir)" "$(abidir)" $(skipmodule)
-
-checks-%: module-check-% abi-check-%
-	@echo Debug: $@
-
-# Check the config against the known options list.
-config-prepare-check-%: $(stampdir)/stamp-prepare-tree-%
-	@echo Debug: $@
-	@perl -f $(DROOT)/scripts/config-check \
-		$(builddir)/build-$*/.config "$(arch)" "$*" "$(sharedconfdir)" "$(skipconfig)"
-
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/debian/rules.d/5-udebs.mk linux-linaro-3.4-2012.05-1_cavium/debian/rules.d/5-udebs.mk
--- linux-linaro-3.4-2012.05-1_original/debian/rules.d/5-udebs.mk	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/debian/rules.d/5-udebs.mk	1970-01-01 08:00:00.000000000 +0800
@@ -1,41 +0,0 @@
-# Do udebs if not disabled in the arch-specific makefile
-binary-udebs: binary-debs
-	@echo Debug: $@
-ifeq ($(disable_d_i),)
-	@$(MAKE) --no-print-directory -f $(DROOT)/rules DEBIAN=$(DEBIAN) \
-		do-binary-udebs
-endif
-
-do-binary-udebs: debian/control
-	@echo Debug: $@
-	dh_testdir
-	dh_testroot
-
-	# unpack the kernels into a temporary directory
-	mkdir -p debian/d-i-${arch}
-
-	imagelist=$$(cat $(builddir)/kernel-versions | grep ^${arch} | awk '{print $$4}') && \
-	for i in $$imagelist; do \
-	  dpkg -x $$(ls ../linux-image-$$i\_$(release)-$(revision)_${arch}.deb) \
-		debian/d-i-${arch}; \
-	  /sbin/depmod -b debian/d-i-${arch} $$i; \
-	done
-
-	# kernel-wedge will error if no modules unless this is touched
-	touch $(CURDIR)/debian/build/no-modules
-
-	touch ignore-dups
-	export SOURCEDIR=$(CURDIR)/debian/d-i-${arch} && \
-	  cd $(builddir) && \
-	  kernel-wedge install-files && \
-	  kernel-wedge check || \
-	  true
-
-        # Build just the udebs
-	dilist=$$(dh_listpackages -s | grep "\-di$$") && \
-	[ -z "$dilist" ] || \
-	for i in $$dilist; do \
-	  dh_fixperms -p$$i; \
-	  $(lockme) dh_gencontrol -p$$i; \
-	  dh_builddeb -p$$i; \
-	done
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/debian/scripts/abi-check linux-linaro-3.4-2012.05-1_cavium/debian/scripts/abi-check
--- linux-linaro-3.4-2012.05-1_original/debian/scripts/abi-check	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/debian/scripts/abi-check	1970-01-01 08:00:00.000000000 +0800
@@ -1,210 +0,0 @@
-#!/usr/bin/perl -w
-
-my $flavour = shift;
-my $prev_abinum = shift;
-my $abinum = shift;
-my $prev_abidir = shift;
-my $abidir = shift;
-my $skipabi = shift;
-
-my $fail_exit = 1;
-my $EE = "EE:";
-my $errors = 0;
-my $abiskip = 0;
-
-my $count;
-
-print "II: Checking ABI for $flavour...\n";
-
-if (-f "$prev_abidir/ignore"
-    or -f "$prev_abidir/$flavour.ignore" or "$skipabi" eq "true") {
-	print "WW: Explicitly asked to ignore ABI, running in no-fail mode\n";
-	$fail_exit = 0;
-	$abiskip = 1;
-	$EE = "WW:";
-}
-
-if ($prev_abinum != $abinum) {
-	print "II: Different ABI's, running in no-fail mode\n";
-	$fail_exit = 0;
-	$EE = "WW:";
-}
-
-if (not -f "$abidir/$flavour" or not -f "$prev_abidir/$flavour") {
-	print "EE: Previous or current ABI file missing!\n";
-	print "    $abidir/$flavour\n" if not -f "$abidir/$flavour";
-	print "    $prev_abidir/$flavour\n" if not -f "$prev_abidir/$flavour";
-
-	# Exit if the ABI files are missing, but return status based on whether
-	# skip ABI was indicated.
-	if ("$abiskip" eq "1") {
-		exit(0);
-	} else {
-		exit(1);
-	}
-}
-
-my %symbols;
-my %symbols_ignore;
-my %modules_ignore;
-my %module_syms;
-
-# See if we have any ignores
-my $ignore = 0;
-print "    Reading symbols/modules to ignore...";
-
-for $file ("$prev_abidir/../blacklist", "$prev_abidir/../../perm-blacklist") {
-	if (-f $file) {
-		open(IGNORE, "< $file") or
-			die "Could not open $file";
-		while (<IGNORE>) {
-			chomp;
-			if ($_ =~ m/M: (.*)/) {
-				$modules_ignore{$1} = 1;
-			} else {
-				$symbols_ignore{$_} = 1;
-			}
-			$ignore++;
-		}
-		close(IGNORE);
-	}
-}
-print "read $ignore symbols/modules.\n";
-
-sub is_ignored($$) {
-	my ($mod, $sym) = @_;
-
-	die "Missing module name in is_ignored()" if not defined($mod);
-	die "Missing symbol name in is_ignored()" if not defined($sym);
-
-	if (defined($symbols_ignore{$sym}) or defined($modules_ignore{$mod})) {
-		return 1;
-	}
-	return 0;
-}
-
-# Read new syms first
-print "    Reading new symbols ($abinum)...";
-$count = 0;
-open(NEW, "< $abidir/$flavour") or
-	die "Could not open $abidir/$flavour";
-while (<NEW>) {
-	chomp;
-	m/^(\S+)\s(.+)\s(0x[0-9a-f]+)\s(.+)$/;
-	$symbols{$4}{'type'} = $1;
-	$symbols{$4}{'loc'} = $2;
-	$symbols{$4}{'hash'} = $3;
-	$module_syms{$2} = 0;
-	$count++;
-}
-close(NEW);
-print "read $count symbols.\n";
-
-# Now the old symbols, checking for missing ones
-print "    Reading old symbols ($prev_abinum)...";
-$count = 0;
-open(OLD, "< $prev_abidir/$flavour") or
-	die "Could not open $prev_abidir/$flavour";
-while (<OLD>) {
-	chomp;
-	m/^(\S+)\s(.+)\s(0x[0-9a-f]+)\s(.+)$/;
-	$symbols{$4}{'old_type'} = $1;
-	$symbols{$4}{'old_loc'} = $2;
-	$symbols{$4}{'old_hash'} = $3;
-	$count++;
-}
-close(OLD);
-
-print "read $count symbols.\n";
-
-print "II: Checking for missing symbols in new ABI...";
-$count = 0;
-foreach $sym (keys(%symbols)) {
-	if (!defined($symbols{$sym}{'type'})) {
-		print "\n" if not $count;
-		printf("    MISS : %s%s\n", $sym,
-			is_ignored($symbols{$sym}{'old_loc'}, $sym) ? " (ignored)" : "");
-		$count++ if !is_ignored($symbols{$sym}{'old_loc'}, $sym);
-	}
-}
-print "    " if $count;
-print "found $count missing symbols\n";
-if ($count) {
-	print "$EE Symbols gone missing (what did you do!?!)\n";
-	$errors++;
-}
-
-
-print "II: Checking for new symbols in new ABI...";
-$count = 0;
-foreach $sym (keys(%symbols)) {
-	if (!defined($symbols{$sym}{'old_type'})) {
-		print "\n" if not $count;
-		print "    NEW : $sym\n";
-		$count++;
-	}
-}
-print "    " if $count;
-print "found $count new symbols\n";
-if ($count and $prev_abinum == $abinum) {
-	print "WW: Found new symbols within same ABI. Not recommended\n";
-}
-
-print "II: Checking for changes to ABI...\n";
-$count = 0;
-my $moved = 0;
-my $changed_type = 0;
-my $changed_hash = 0;
-foreach $sym (keys(%symbols)) {
-	if (!defined($symbols{$sym}{'old_type'}) or
-	    !defined($symbols{$sym}{'type'})) {
-		next;
-	}
-
-	# Changes in location don't hurt us, but log it anyway
-	if ($symbols{$sym}{'loc'} ne $symbols{$sym}{'old_loc'}) {
-		printf("    MOVE : %-40s : %s => %s\n", $sym, $symbols{$sym}{'old_loc'},
-			$symbols{$sym}{'loc'});
-		$moved++;
-	}
-
-	# Changes to export type are only bad if new type isn't
-	# EXPORT_SYMBOL. Changing things to GPL are bad.
-	if ($symbols{$sym}{'type'} ne $symbols{$sym}{'old_type'}) {
-		printf("    TYPE : %-40s : %s => %s%s\n", $sym, $symbols{$sym}{'old_type'}.
-			$symbols{$sym}{'type'}, is_ignored($symbols{$sym}{'loc'}, $sym)
-			? " (ignored)" : "");
-		$changed_type++ if $symbols{$sym}{'type'} ne "EXPORT_SYMBOL"
-			and !is_ignored($symbols{$sym}{'loc'}, $sym);
-	}
-
-	# Changes to the hash are always bad
-	if ($symbols{$sym}{'hash'} ne $symbols{$sym}{'old_hash'}) {
-		printf("    HASH : %-40s : %s => %s%s\n", $sym, $symbols{$sym}{'old_hash'},
-			$symbols{$sym}{'hash'}, is_ignored($symbols{$sym}{'loc'}, $sym)
-			? " (ignored)" : "");
-		$changed_hash++ if !is_ignored($symbols{$sym}{'loc'}, $sym);
-		$module_syms{$symbols{$sym}{'loc'}}++;
-	}
-}
-
-print "WW: $moved symbols changed location\n" if $moved;
-print "$EE $changed_type symbols changed export type and weren't ignored\n" if $changed_type;
-print "$EE $changed_hash symbols changed hash and weren't ignored\n" if $changed_hash;
-
-$errors++ if $changed_hash or $changed_type;
-if ($changed_hash) {
-	print "II: Module hash change summary...\n";
-	foreach $mod (sort { $module_syms{$b} <=> $module_syms{$a} } keys %module_syms) {
-		next if ! $module_syms{$mod};
-		printf("    %-40s: %d\n", $mod, $module_syms{$mod});
-	}
-}
-
-print "II: Done\n";
-
-if ($errors) {
-	exit($fail_exit);
-} else {
-	exit(0);
-}
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/debian/scripts/config-check linux-linaro-3.4-2012.05-1_cavium/debian/scripts/config-check
--- linux-linaro-3.4-2012.05-1_original/debian/scripts/config-check	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/debian/scripts/config-check	1970-01-01 08:00:00.000000000 +0800
@@ -1,401 +0,0 @@
-#!/usr/bin/perl
-#
-# check-config -- check the current config for issues
-#
-use strict;
-
-my $P = 'check-config';
-
-my $test = -1;
-if ($ARGV[0] eq '--test') {
-	$test = $ARGV[1] + 0;
-} elsif ($#ARGV != 4) {
-	die "Usage: $P <config> <arch> <flavour> <commonconfig> <warn-only>\n";
-}
-
-my ($config, $arch, $flavour, $commonconfig, $warn_only) = @ARGV;
-
-my $checks = "$commonconfig/enforce";
-my %values = ();
-
-# If we are in overridden then still perform the checks and emit the messages
-# but do not return failure.  Those items marked FATAL will alway trigger
-# failure.
-my $fail_exit = 1;
-$fail_exit = 0 if ($warn_only eq 'true' || $warn_only eq '1');
-my $exit_val = 0;
-
-# Predicate execution engine.
-sub pred_first {
-	my ($rest) = @_;
-	my $depth = 0;
-	my $off;
-	my $char;
-	my $pred;
-	
-	for ($off = 0; $off <= length($rest); $off++) {
-		$char = substr($rest, $off, 1);
-		if ($char eq '(') {
-			$depth++;
-		} elsif ($char eq ')') {
-			$depth--;
-		} elsif ($depth == 0 && $char eq '&') {
-			last;
-		} elsif ($depth == 0 && $char eq '|') {
-			last;
-		}
-	}
-	if ($depth > 0) {
-		die "$P: $rest: missing close parenthesis ')'\n";
-	} elsif ($depth < 0) {
-		die "$P: $rest: missing open parenthesis '('\n";
-	}
-
-	($pred, $rest) = (substr($rest, 0, $off), substr($rest, $off + 1));
-
-	$pred =~ s/^\s*//;
-	$pred =~ s/\s*$//;
-
-	#print "pred<$pred> rest<$rest> char<$char>\n";
-	($pred, $rest, $char);
-}
-		
-sub pred_do {
-	my ($pred) = @_;
-	my (@a) = split(' ', $pred);
-	my $possible;
-
-	if ($a[0] eq 'arch') {
-		die "$P: $pred: malformed -- $pred <arch>\n" if ($#a < 1);
-		for $possible (@a[1..$#a]) {
-			#print "    *** ARCH<$flavour ?? $possible>\n";
-			return 1 if ($arch eq $possible);
-		}
-		return 0;
-	} elsif ($a[0] eq 'flavour') {
-		die "$P: $pred: malformed -- $pred <flavour>\n" if ($#a < 1);
-		for $possible (@a[1..$#a]) {
-			#print "    *** FLAVOUR<$flavour ?? $a[1]>\n";
-			return 1 if ($flavour eq $possible);
-		}
-		return 0;
-	} elsif ($a[0] eq 'value') {
-		die "$P: $pred: malformed -- $pred <name> <val>\n" if ($#a != 2);
-		#print "    *** CHECK<$a[1] $a[2] ?? " . $values{$a[1]} . ">\n";
-		return ($values{$a[1]} eq $a[2]);
-	} elsif ($a[0] eq 'exists') {
-		die "$P: $pred: malformed -- $pred <name>\n" if ($#a != 1);
-		return (defined $values{$a[1]});
-	} else {
-		die "$P: $pred: unknown predicate\n";
-	}
-	return 1;
-}
-sub pred_exec {
-	my ($rest) = @_;
-	my $pred;
-	my $res;
-	my $sep;
-
-	#print "pred_exec<$rest>\n";
-
-	($pred, $rest, $sep) = pred_first($rest);
-
-	# Leading ! implies inversion.
-	if ($pred =~ /^\s*!\s*(.*)$/) {
-		#print " invert<$1>\n";
-		$res = !pred_exec($1);
-
-	# Recurse left for complex expressions.
-	} elsif ($pred =~ /^\s*\((.*)\)\s*$/) {
-		#print " left<$1>\n";
-		$res = pred_exec($1);
-
-	# Check for common syntax issues.
-	} elsif ($pred eq '') {
-		if ($sep eq '&' || $sep eq '|') {
-			die "$P: $pred$rest: malformed binary operator\n";
-		} else {
-			die "$P: $pred$rest: syntax error\n";
-		}
-		
-	# A predicate, execute it.
-	} else {
-		#print " DO<$pred> sep<$sep>\n";
-		$res = pred_do($pred);
-	}
-
-	#print " pre-return res<$res> sep<$sep>\n";
-	if ($sep eq '') {
-		#
-		
-	# Recurse right for binary operators -- note these are lazy.
-	} elsif ($sep eq '&' || $sep eq '|') {
-		#print " right<$rest> ? sep<$sep> res<$res>\n";
-		if ($rest =~ /^\s*($|\||\&)/) {
-			die "$P: $pred$rest: malformed binary operator\n";
-		}
-		if (($res && $sep eq '&') || (!$res && $sep eq '|')) {
-			#print " right<$rest>\n";
-			$res = pred_exec($rest);
-		}
-
-	} else {
-		die "$P: $pred$rest: malformed predicate\n";
-	}
-	#print " return res<$res> sep<$sep>\n";
-	return $res;
-}
-
-#
-# PREDICATE TESTS
-#
-my $test_total = 1;
-my $test_good = 0;
-sub pred_test {
-	my ($pred, $eres, $eerr) = @_;
-	my ($res, $err, $fail);
-
-	$test_total++;
-	if ($test != 0 && $test != $test_total - 1) {
-		return;
-	}
-
-	eval {
-		$res = pred_exec($pred);
-	};
-	$err = $@;
-	chomp($err);
-
-	$res = !!$res;
-	$eres = !!$eres;
-
-	$fail = '';
-	if (defined $eres && $res != $eres) {
-		$fail = "result missmatch, expected $eres returned $res";
-	}
-	if (defined $eerr && $err eq '') {
-		$fail = "error missmatch, expected '$eerr' returned success";
-	} elsif (defined $eerr && $err !~ /$eerr/) {
-		$fail = "error missmatch, expected '$eerr' returned '$err'";
-	} elsif (!defined $eerr && $err ne '') {
-		$fail = "error missmatch, expected success returned '$err'";
-	}
-	
-	if ($fail eq '') {
-		$test_good++;
-	} else {
-		print "$pred: $test_total: FAIL: $fail\n";
-	}
-	#print "TEST<$pred> eres<$eres> eerr<$eerr> res<$res> err<$err>\n";
-}
-if ($test >= 0) {
-	$arch = 'MYARCH';
-	$flavour = 'MYFLAVOUR';
-	%values = ( 'ENABLED' => 'y', 'DISABLED' => 'n' );
-
-	# Errors.
-	my $eunkn = 'unknown predicate';
-	my $epred = 'malformed';
-	my $eclose = 'missing close parenthesis';
-	my $eopen = 'missing open parenthesis';
-	my $ebinary = 'malformed binary operator';
-
-	# Basic predicate tests.
-	print "TEST: $test_total: basic predicate tests ...\n";
-
-	pred_test('nosuchcommand', undef, $eunkn);
-	pred_test('arch', undef, $epred);
-	pred_test('arch MYARCH', 1, undef);
-	pred_test('arch MYARCH NOTMYARCH', 1, undef);
-	pred_test('arch NOTMYARCH MYARCH', 1, undef);
-	pred_test('arch NOTMYARCH NOTMYARCH MYARCH', 1, undef);
-	pred_test('arch NOTMYARCH MYARCH NOTMYARCH', 1, undef);
-	pred_test('arch NOTMYARCH', 0, undef);
-
-	pred_test('flavour', undef, $epred);
-	pred_test('flavour MYFLAVOUR', 1, undef);
-	pred_test('flavour NOTMYFLAVOUR MYFLAVOUR', 1, undef);
-	pred_test('flavour NOTMYFLAVOUR NOTMYFLAVOUR MYFLAVOUR', 1, undef);
-	pred_test('flavour NOTMYFLAVOUR MYFLAVOUR NOTMYFLAVOUR', 1, undef);
-	pred_test('flavour NOTMYFLAVOUR', 0, undef);
-
-	pred_test('value', undef, $epred);
-	pred_test('value ENABLED', undef, $epred);
-	pred_test('value ENABLED ENABLED ENABLED', undef, $epred);
-	pred_test('value ENABLED y', 1, undef);
-	pred_test('value ENABLED n', 0, undef);
-	pred_test('value DISABLED n', 1, undef);
-	pred_test('value DISABLED y', 0, undef);
-
-	pred_test('exists', undef, $epred);
-	pred_test('exists ENABLED ENABLED', undef, $epred);
-	pred_test('exists ENABLED', 1, undef);
-	pred_test('exists DISABLED', 1, undef);
-	pred_test('exists MISSING', 0, undef);
-
-	print "TEST: $test_total: inversion tests ...\n";	
-	pred_test('!exists ENABLED', 0, undef);
-	pred_test('!exists MISSING', 1, undef);
-	pred_test('!!exists ENABLED', 1, undef);
-	pred_test('!!exists MISSING', 0, undef);
-	pred_test('!!!exists ENABLED', 0, undef);
-	pred_test('!!!exists MISSING', 1, undef);
-
-	print "TEST: $test_total: parentheses tests ...\n";	
-	pred_test('(exists ENABLED)', 1, undef);
-	pred_test('((exists ENABLED))', 1, undef);
-	pred_test('(((exists ENABLED)))', 1, undef);
-	pred_test('(exists MISSING)', 0, undef);
-	pred_test('((exists MISSING))', 0, undef);
-	pred_test('(((exists MISSING)))', 0, undef);
-
-	pred_test('(!exists ENABLED)', 0, undef);
-	pred_test('((!exists ENABLED))', 0, undef);
-	pred_test('(((!exists ENABLED)))', 0, undef);
-	pred_test('(!exists MISSING)', 1, undef);
-	pred_test('((!exists MISSING))', 1, undef);
-	pred_test('(((!exists MISSING)))', 1, undef);
-
-	pred_test('((!(exists ENABLED)))', 0, undef);
-	pred_test('((!(exists MISSING)))', 1, undef);
-	pred_test('(!((exists ENABLED)))', 0, undef);
-	pred_test('(!((exists MISSING)))', 1, undef);
-	pred_test('!(((exists ENABLED)))', 0, undef);
-	pred_test('!(((exists MISSING)))', 1, undef);
-	pred_test('!((!(exists ENABLED)))', 1, undef);
-	pred_test('!((!(exists MISSING)))', 0, undef);
-	pred_test('!(!(!(exists ENABLED)))', 0, undef);
-	pred_test('!(!(!(exists MISSING)))', 1, undef);
-
-	pred_test('(', undef, $eclose);
-	pred_test('()(', undef, $eclose);
-	pred_test('(())(', undef, $eclose);
-	pred_test('((()))(', undef, $eclose);
-	pred_test('(()', undef, $eclose);
-	pred_test('((())', undef, $eclose);
-	pred_test('(((()))', undef, $eclose);
-	pred_test('(()()', undef, $eclose);
-	pred_test('((())()', undef, $eclose);
-
-	pred_test(')', undef, $eopen);
-	pred_test('())', undef, $eopen);
-	pred_test('(()))', undef, $eopen);
-	pred_test('((())))', undef, $eopen);
-
-	print "TEST: $test_total: binary and tests ...\n";
-
-	pred_test('exists ENABLED &', undef, $ebinary);
-	pred_test('& exists ENABLED', undef, $ebinary);
-	pred_test('exists ENABLED & & exists ENABLED', undef, $ebinary);
-
-	pred_test('exists MISSING & exists MISSING', 0, undef);
-	pred_test('exists MISSING & exists ENABLED', 0, undef);
-	pred_test('exists ENABLED & exists MISSING', 0, undef);
-	pred_test('exists ENABLED & exists ENABLED', 1, undef);
-
-	pred_test('exists MISSING & exists MISSING & exists MISSING', 0, undef);
-	pred_test('exists MISSING & exists MISSING & exists ENABLED', 0, undef);
-	pred_test('exists MISSING & exists ENABLED & exists MISSING', 0, undef);
-	pred_test('exists MISSING & exists ENABLED & exists ENABLED', 0, undef);
-	pred_test('exists ENABLED & exists MISSING & exists MISSING', 0, undef);
-	pred_test('exists ENABLED & exists MISSING & exists ENABLED', 0, undef);
-	pred_test('exists ENABLED & exists ENABLED & exists MISSING', 0, undef);
-	pred_test('exists ENABLED & exists ENABLED & exists ENABLED', 1, undef);
-
-	print "TEST: $test_total: binary or tests ...\n";
-
-	pred_test('exists ENABLED |', undef, $ebinary);
-	pred_test('| exists ENABLED', undef, $ebinary);
-	pred_test('exists ENABLED | | exists ENABLED', undef, $ebinary);
-
-	pred_test('exists MISSING | exists MISSING', 0, undef);
-	pred_test('exists MISSING | exists ENABLED', 1, undef);
-	pred_test('exists ENABLED | exists MISSING', 1, undef);
-	pred_test('exists ENABLED | exists ENABLED', 1, undef);
-
-	pred_test('exists MISSING | exists MISSING | exists MISSING', 0, undef);
-	pred_test('exists MISSING | exists MISSING | exists ENABLED', 1, undef);
-	pred_test('exists MISSING | exists ENABLED | exists MISSING', 1, undef);
-	pred_test('exists MISSING | exists ENABLED | exists ENABLED', 1, undef);
-	pred_test('exists ENABLED | exists MISSING | exists MISSING', 1, undef);
-	pred_test('exists ENABLED | exists MISSING | exists ENABLED', 1, undef);
-	pred_test('exists ENABLED | exists ENABLED | exists MISSING', 1, undef);
-	pred_test('exists ENABLED | exists ENABLED | exists ENABLED', 1, undef);
-
-	print "TEST: $test_total: binary or/and combination tests ...\n";
-
-	pred_test('exists MISSING | exists MISSING & exists MISSING', 0, undef);
-	pred_test('exists MISSING | exists MISSING & exists ENABLED', 0, undef);
-	pred_test('exists MISSING | exists ENABLED & exists MISSING', 0, undef);
-	pred_test('exists MISSING | exists ENABLED & exists ENABLED', 1, undef);
-	pred_test('exists ENABLED | exists MISSING & exists MISSING', 1, undef);
-	pred_test('exists ENABLED | exists MISSING & exists ENABLED', 1, undef);
-	pred_test('exists ENABLED | exists ENABLED & exists MISSING', 1, undef);
-	pred_test('exists ENABLED | exists ENABLED & exists ENABLED', 1, undef);
-
-	print "TEST: $test_total: binary and/or combination tests ...\n";
-
-	pred_test('exists MISSING & exists MISSING | exists MISSING', 0, undef);
-	pred_test('exists MISSING & exists MISSING | exists ENABLED', 0, undef);
-	pred_test('exists MISSING & exists ENABLED | exists MISSING', 0, undef);
-	pred_test('exists MISSING & exists ENABLED | exists ENABLED', 0, undef);
-	pred_test('exists ENABLED & exists MISSING | exists MISSING', 0, undef);
-	pred_test('exists ENABLED & exists MISSING | exists ENABLED', 1, undef);
-	pred_test('exists ENABLED & exists ENABLED | exists MISSING', 1, undef);
-	pred_test('exists ENABLED & exists ENABLED | exists ENABLED', 1, undef);
-
-	$test_total--;
-	print "TEST: $test_good/$test_total succeeded\n";
-
-	exit $exit_val;
-}
-
-# Load up the current configuration values -- FATAL if this fails
-print "$P: $config: loading config\n";
-open(CONFIG, "<$config") || die "$P: $config: open failed -- $! -- aborting\n";
-while (<CONFIG>) {
-	# Pull out values.
-	/^#*\s*(CONFIG_\w+)[\s=](.*)$/ or next;
-	if ($2 eq 'is not set') {
-		$values{$1} = 'n';
-	} else {
-		$values{$1} = $2;
-	}
-}
-close(CONFIG);
-
-# FATAL: Check if we have an enforcement list.
-my $pass = 0;
-my $total = 0;
-my $line = '';
-print "$P: $checks: loading checks\n";
-open(CHECKS, "<$checks") || die "$P: $checks: open failed -- $! -- aborting\n";
-while (<CHECKS>) {
-	/^#/ && next;
-	chomp;
-
-	$line .= $_;
-	if ($line =~ /\\$/) {
-		chop($line);
-		$line .= " ";
-		next;
-	}
-	$line =~ /^\s*$/ && next;
-
-	#print "CHECK: <$line>\n";
-	$total++;
-	my $result = pred_exec($line);
-	if (!$result) {
-		print "$P: FAIL: $line\n";
-		$exit_val = $fail_exit;
-	} else {
-		$pass++;
-	}
-
-	$line = '';
-}
-close(CHECKS);
-
-print "$P: $pass/$total checks passed -- exit $exit_val\n";
-exit $exit_val;
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/debian/scripts/control-create linux-linaro-3.4-2012.05-1_cavium/debian/scripts/control-create
--- linux-linaro-3.4-2012.05-1_original/debian/scripts/control-create	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/debian/scripts/control-create	1970-01-01 08:00:00.000000000 +0800
@@ -1,25 +0,0 @@
-#!/bin/bash
-
-. debian/debian.env
-
-vars=$1
-
-. $vars
-
-if [ "$is_sub" = "" ]; then
-	flavour=$(basename $vars | sed 's/.*\.//')
-	stub=${DEBIAN}/control.d/flavour-control.stub
-else
-	flavour=$(basename $vars .vars)
-	stub=${DEBIAN}/sub-flavours/control.stub
-fi
-
-cat $stub | grep -v '^#' | sed			\
-	-e "s#FLAVOUR#$flavour#g"		\
-	-e "s#DESC#$desc#g"			\
-	-e "s#ARCH#$arch#g"			\
-	-e "s#SUPPORTED#$supported#g"		\
-	-e "s#TARGET#$target#g"			\
-	-e "s#BOOTLOADER#$bootloader#g" 	\
-	-e "s#=PROVIDES=#$provides#g"		\
-	-e "s#=CONFLICTS=#$conflicts#g"
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/debian/scripts/link-headers linux-linaro-3.4-2012.05-1_cavium/debian/scripts/link-headers
--- linux-linaro-3.4-2012.05-1_original/debian/scripts/link-headers	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/debian/scripts/link-headers	1970-01-01 08:00:00.000000000 +0800
@@ -1,42 +0,0 @@
-#!/bin/bash -e
-
-. debian/debian.env
-
-hdrdir="$1"
-symdir="$2"
-flavour="$3"
-
-echo "Symlinking and copying headers for $flavour..."
-
-excludes="( -path ./debian -prune -o -path ./${DEBIAN} -prune -o -path ./.git ) -prune -o"
-
-(
-find . $excludes  -type f \
-	\( -name 'Makefile*' -o -name 'Kconfig*' -o -name 'Kbuild*' -o \
-	-name '*.sh' -o -name '*.pl' -o -name '*.lds' \) -print
-find ./include ./scripts -name .gitignore -prune -o -type f -print
-find ./include -mindepth 1 -maxdepth 1 $excludes -type d -print
-) | (
-while read file; do
-	dir=$file
-	lastdir=$file
-
-	if [ -e "$hdrdir/$file" -o -L "$hdrdir/$file" ]; then
-		continue
-	fi
-
-	while [ ! -e "$hdrdir/$dir" -a ! -L "$hdrdir/$dir" ]; do
-		lastdir=$dir
-		dir=`dirname $dir`
-	done
-	# If the last item to exist is a symlink we assume all is good
-	if [ ! -L "$hdrdir/$dir" ]; then
-		# Turns things like "./foo" into "../"
-		deref="`echo -n $lastdir | sed -e 's/^\.//' -e's,/[^/]*,../,g'`"
-		item="`echo -n $lastdir | sed -e 's/^\.\///'`"
-		ln -s $deref$symdir/$item $hdrdir/$item
-	fi
-done
-)
-
-exit
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/debian/scripts/misc/getabis linux-linaro-3.4-2012.05-1_cavium/debian/scripts/misc/getabis
--- linux-linaro-3.4-2012.05-1_original/debian/scripts/misc/getabis	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/debian/scripts/misc/getabis	1970-01-01 08:00:00.000000000 +0800
@@ -1,98 +0,0 @@
-#!/bin/bash
-
-. debian/debian.env
-
-if [ "$#" != "2" ]; then
-	echo "Usage: $0 <release> <revision>" 1>&2
-	exit 1
-fi
-
-ver=$1
-revision=$2
-abi=$(echo $revision | awk -F. '{print $1}')
-
-verabi=$ver-$abi
-verfull=$ver-$revision
-
-src_pkg_name=$(dpkg-parsechangelog -l${DEBIAN}/changelog|grep Source|sed 's/^.*Source: //')
-
-WGET="wget --quiet -c"
-
-abidir="`pwd`/$DEBIAN/abi/$verfull"
-tmpdir="`pwd`/abi-tmp-$verfull"
-origdir="`pwd`"
-
-test -d $tmpdir || mkdir $tmpdir
-
-getall() {
-	arch=$1
-	shift
-
-	mkdir -p $abidir/$arch
-
-	for sub in $@; do
-		if [ -f $abidir/$arch/$sub ]; then
-			echo "Exists: $sub"
-			continue
-		fi
-		echo -n "Fetching $sub..."
-		filename=linux-image-${verabi}-${sub}_${verfull}_${arch}.deb
-		cd $tmpdir
-		for r in "${repo_list[@]}"
-		do
-			url="`echo $r | sed 's/linux$/'${src_pkg_name}'/'`"
-			if ! [ -f $filename ]; then
-				$WGET $url/$filename
-			fi
-		done
-		if [ "$?" = "0" ]; then
-			echo -n "extracting..."
-			dpkg-deb --extract $filename tmp
-			if [ -f tmp/boot/abi-* ]; then
-				mv tmp/boot/abi-* $abidir/$arch/$sub
-			else
-				echo -n "NO ABI FILE..."
-			fi
-			(cd tmp; find lib/modules/$verabi-$sub/kernel -name '*.ko') | \
-				sed -e 's/.*\/\([^\/]*\)\.ko/\1/' | sort > \
-				$abidir/$arch/$sub.modules
-			(
-				cd tmp;
-				ko=`find lib/modules/$verabi-$sub/kernel -name '*.ko' | head -1`
-				readelf -p .comment "$ko" | awk '
-					($1 == "[") {
-						printf("%s", $3);
-						for (n=4; n<=NF; n++) {
-							printf(" %s", $n);
-						}
-						print ""
-					}' | sort -u >$abidir/$arch/$sub.compiler
-				version=`cat $abidir/$arch/$sub.compiler`
-				echo -n "$version..."
-			)
-			rm -rf tmp $filename
-			echo "done."
-		else
-			echo "FAILED."
-		fi
-		cd $origdir
-	done
-}
-
-# MAIN
-
-# Setup abi directory
-mkdir -p $abidir
-echo $abi > $abidir/abiname
-
-# NOTE: The flavours are hardcoded, because they may have changed from the
-# current build.
-
-. $DEBIAN/etc/getabis
-
-compilers=`cat $abidir/*/*.compiler | sort -u | wc -l`
-if [ "$compilers" != 1 ]; then
-	echo "WARNING: inconsistant compiler versions detected" 1>&2
-fi
-
-rmdir $tmpdir
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/debian/scripts/misc/git-ubuntu-log linux-linaro-3.4-2012.05-1_cavium/debian/scripts/misc/git-ubuntu-log
--- linux-linaro-3.4-2012.05-1_original/debian/scripts/misc/git-ubuntu-log	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/debian/scripts/misc/git-ubuntu-log	1970-01-01 08:00:00.000000000 +0800
@@ -1,232 +0,0 @@
-#!/usr/bin/perl -w
-
-use strict;
-use Text::Wrap;
-
-my $kernel_auth = "Upstream Kernel Changes";
-
-my (%map, @reverts);
-my $pstate = 1;
-my $no_kern_log = 0;
-my $print_shas = 0;
-my $first_print = 1;
-
-while (@ARGV) {
-	my $opt = $ARGV[0];
-	shift;
-	if ($opt eq "--no-kern-log") {
-		$no_kern_log = 1;
-	} elsif ($opt eq "--print-shas") {
-		$print_shas = 1;
-	} else {
-		print STDERR "Unknown options: $opt\n";
-		exit(1);
-	}
-}
-
-sub check_reverts($) {
-	my ($entry) = @_;
-	my ($check);
-
-	foreach $check (reverse @reverts) {
-		my $desc = "Revert \"" . $entry->{'desc'} . "\"";
-		if ($check->{'desc'} eq $desc) {
-			@reverts = grep($_->{'desc'} ne $desc, @reverts);
-			return 1;
-		}
-	}
-
-	return 0;
-}
-
-sub add_entry($) {
-	my ($entry) = @_;
-	my $key = $entry->{'author'};
-
-        # store description in array, in email->{desc list} map
-        if (exists $map{$key}) {
-                # grab ref
-                my $obj = $map{$key};
-
-                # add desc to array
-                push(@$obj, $entry);
-        } else {
-                # create new array, containing 1 item
-                my @arr = ($entry);
-
-                # store ref to array
-                $map{$key} = \@arr;
-        }
-}
-
-sub shortlog_entry($$$$$) {
-	my ($name, $desc, $bug, $cve, $commit) = @_;
-	my $entry;
-
-	$desc =~ s#/pub/scm/linux/kernel/git/#/.../#g;
-	$desc =~ s#\[PATCH\] ##g;
-
-	$desc =~ s#^\s*##g;
-	$desc =~ s# *UBUNTU: ##g;
-
-	$entry->{'desc'} = $desc;
-	if ($bug ne '') {
-		$entry->{'bugno'} = $bug;
-	}
-	$entry->{'cve'} = $cve;
-	$entry->{'commit'} = $commit;
-	$entry->{'author'} = $name;
-
-	if ($desc =~ /^Revert "/) {
-		push(@reverts, $entry);
-		return;
-	}
-
-	return if check_reverts($entry);
-
-	add_entry($entry);
-}
-
-# sort comparison function
-sub by_name($$) {
-	my ($a, $b) = @_;
-
-	uc($a) cmp uc($b);
-}
-
-sub shortlog_output {
-	my ($obj, $key, $entry);
-
-	foreach $key (sort by_name keys %map) {
-		next if $key eq $kernel_auth and $no_kern_log;
-
-		print "\n" unless $first_print;
-		$first_print = 0;
-
-		# output author
-		printf "  [ %s ]\n\n", $key;
-
-		# output author's 1-line summaries
-		$obj = $map{$key};
-		foreach $entry (reverse @$obj) {
-			print wrap("  * ", "    ", $entry->{'desc'}) . "\n";
-			# For non upstream changes, add other info.
-			if ($key ne $kernel_auth) {
-				if ($print_shas) {
-					print "    - GIT-SHA " . $entry->{'commit'} .
-						"\n";
-				}
-			}
-			if (defined($entry->{'bugno'})) {
-				print "    - LP: #" .  $entry->{'bugno'} . "\n";
-			}
-			if (defined($entry->{'cve'})) {
-				print "    - " . $entry->{'cve'} . "\n";
-			}
-		}
-	}
-}
-
-sub changelog_input {
-	my ($author, $desc, $commit, $entry, $cve);
-
-	while (<STDIN>) {
-		# get commit
-		if ($pstate == 1) {
-			next unless /^commit (.*)/;
-
-			$commit = $1;
-
-			$pstate++;
-		}
-
-		# get author and email
-		elsif ($pstate == 2) {
-			my ($email);
-
-			next unless /^[Aa]uthor:?\s*(.*?)\s*<(.*)>/;
-
-			$author = $1;
-			$email = $2;
-			$desc = undef;
-			$cve = undef;
-
-			# cset author fixups
-			if (!$author) {
-				$author = $email;
-			}
-			$pstate++;
-		}
-
-		# skip to blank line
-		elsif ($pstate == 3) {
-			next unless /^\s*$/;
-			$pstate++;
-		}
-
-		# skip to non-blank line
-		elsif ($pstate == 4) {
-			next unless /^\s*?(.*)/;
-			my $ignore = 0;
-			my $do_ignore = 0;
-			my $bug = undef;
-			my %bugz = ();
-			my $k;
-
-			# skip lines that are obviously not
-			# a 1-line cset description
-			next if /^\s*From: /;
-
-			chomp;
-			$desc = $1;
-
-			if ($desc =~ /^ *(Revert "|)UBUNTU:/) {
-				$do_ignore = 1;
-			} else {
-				$do_ignore = 0;
-				$author = $kernel_auth;
-				$ignore = 1 if $desc =~ /Merge /;
-			}
-			while (<STDIN>) {
-				$ignore  =  1 if ($do_ignore && /^ *Ignore: yes/i);
-				if    (/^ *Bug: *(#|)([0-9#,\s]*)\s*$/i) {
-					foreach $k (split('(,|\s)\s*(#|)', $2)) {
-						$bugz{$k} = 1 if (($k ne '') and ($k =~ /[0-9]+/));
-					}
-				}
-				elsif (/^ *BugLink: *http.*:\/\/.*\/([0-9]+)/i) {
-					$bugz{$1} = 1;
-				}
-				elsif (/^ *(CVE-.*)/) {
-					$cve = $1
-				}
-				last if /^commit /;
-			}
-
-                        $bug = join(", #", sort keys(%bugz));
-			if (!$ignore) {
-				&shortlog_entry($author, $desc, $bug,
-						$cve, $commit, 0);
-			}
-
-			$pstate = 1;
-			if ($_ && /^commit (.*)/) {
-				$commit = $1;
-				$pstate++;
-			}
-		}
-	
-		else {
-			die "invalid parse state $pstate";
-		}
-	}
-
-	foreach $entry (@reverts) {
-		add_entry($entry);
-	}	
-}
-
-&changelog_input;
-&shortlog_output;
-
-exit(0);
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/debian/scripts/misc/insert-changes.pl linux-linaro-3.4-2012.05-1_cavium/debian/scripts/misc/insert-changes.pl
--- linux-linaro-3.4-2012.05-1_original/debian/scripts/misc/insert-changes.pl	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/debian/scripts/misc/insert-changes.pl	1970-01-01 08:00:00.000000000 +0800
@@ -1,36 +0,0 @@
-#!/usr/bin/perl -w
-
-my $debian;
-$droot = $ARGV[0] if (defined $ARGV[0]);
-$droot = 'debian' if (!defined $droot);
-$debian = $ARGV[1] if (defined $ARGV[1]);
-$debian = 'debian.linaro' if (!defined $debian);
-
-system("make -s -f $droot/rules printchanges > $debian/changes");
-
-open(CHANGELOG, "< $debian/changelog") or die "Cannot open changelog";
-open(CHANGES, "< $debian/changes") or die "Cannot open new changes";
-open(NEW, "> $debian/changelog.new") or die "Cannot open new changelog";
-
-$printed = 0;
-
-while (<CHANGELOG>) {
-	if (/^  CHANGELOG: /) {
-		next if $printed;
-
-		while (<CHANGES>) {
-			print NEW;
-		}
-
-		$printed = 1;
-	} else {
-		print NEW;
-	}
-}
-
-close(NEW);
-close(CHANGES);
-close(CHANGELOG);
-
-rename("$debian/changelog.new", "$debian/changelog");
-unlink("$debian/changes");
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/debian/scripts/misc/insert-mainline-changes linux-linaro-3.4-2012.05-1_cavium/debian/scripts/misc/insert-mainline-changes
--- linux-linaro-3.4-2012.05-1_original/debian/scripts/misc/insert-mainline-changes	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/debian/scripts/misc/insert-mainline-changes	1970-01-01 08:00:00.000000000 +0800
@@ -1,42 +0,0 @@
-#!/usr/bin/perl
-
-if ($#ARGV != 2) {
-	warn "Usage: $0 <changelog> <to> <range>\n";
-	die  "       $0 debian.master/changelog v3.2.3 v3.2.2..v3.2.3\n";
-}
-my ($changelog, $to, $range) = @ARGV;
-
-my @changes = ();
-
-push(@changes, "\n");
-push(@changes, "  [ Upstream Kernel Changes ]\n\n");
-push(@changes, "  * rebase to $to\n");
-
-open(LOG, "git log '$range'|") || die "$0: git log failed: - $!\n";
-while (<LOG>) {
-	if (m@BugLink: .*launchpad.net/.*/([0-9]+)\s$@) {
-		push(@changes, "    - LP: #$1\n");
-	}
-}
-close(LOG);
-
-open(CHANGELOG, "< $changelog") or die "Cannot open changelog";
-open(NEW, "> $changelog.new") or die "Cannot open new changelog";
-
-$printed = 3;
-while (<CHANGELOG>) {
-	if (/^  CHANGELOG: /) {
-		$printed--;
-		print NEW;
-		if ($printed == 0) {
-			print NEW @changes;
-		}
-		next;
-	}
-	print NEW;
-}
-
-close(NEW);
-close(CHANGELOG);
-
-rename("$changelog.new", "$changelog");
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/debian/scripts/misc/insert-ubuntu-changes linux-linaro-3.4-2012.05-1_cavium/debian/scripts/misc/insert-ubuntu-changes
--- linux-linaro-3.4-2012.05-1_original/debian/scripts/misc/insert-ubuntu-changes	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/debian/scripts/misc/insert-ubuntu-changes	1970-01-01 08:00:00.000000000 +0800
@@ -1,58 +0,0 @@
-#!/usr/bin/perl
-
-if ($#ARGV != 2) {
-	die "Usage: $0 <changelog> <stop at> <start at>\n";
-}
-my ($changelog, $end, $start) = @ARGV;
-
-$end =~ s/.*\.//;
-$start =~ s/.*\.//;
-
-my @changes = ();
-my $output = 0;
-open(CHG, "<debian.linaro/changelog") ||
-	open(CHG, "<debian/changelog") ||
-	die "$0: debian/changelog: open failed - $!\n";
-while (<CHG>) {
-	if (/^\S+\s+\((.*\.(\d+))\)/) {
-		if ($2 <= $end) {
-			last;
-		}
-		if ($2 == $start) {
-			$output = 1;
-		}
-		if ($output) {
-			push(@changes, "\n  [ Ubuntu: $1 ]\n\n");
-			next;
-		}
-	}
-	next if ($output == 0);
-
-	next if (/^\s*$/);
-	next if (/^\s--/);
-	next if (/^\s\s[^\*\s]/);
-
-	push(@changes, $_);
-}
-close(CHG);
-
-open(CHANGELOG, "< $changelog") or die "Cannot open changelog";
-open(NEW, "> $changelog.new") or die "Cannot open new changelog";
-
-$printed = 3;
-while (<CHANGELOG>) {
-	if (/^  CHANGELOG: /) {
-		$printed--;
-		print NEW;
-		if ($printed == 0) {
-			print NEW @changes;
-		}
-		next;
-	}
-	print NEW;
-}
-
-close(NEW);
-close(CHANGELOG);
-
-rename("$changelog.new", "$changelog");
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/debian/scripts/misc/kernelconfig linux-linaro-3.4-2012.05-1_cavium/debian/scripts/misc/kernelconfig
--- linux-linaro-3.4-2012.05-1_original/debian/scripts/misc/kernelconfig	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/debian/scripts/misc/kernelconfig	1970-01-01 08:00:00.000000000 +0800
@@ -1,172 +0,0 @@
-#!/bin/bash
-
-. debian/debian.env
-
-# Script to merge all configs and run 'make silentoldconfig' on it to wade out bad juju.
-# Then split the configs into distro-commmon and flavour-specific parts
-
-# We have to be in the top level kernel source directory
-if [ ! -f MAINTAINERS ] || [ ! -f Makefile ]; then
-	echo "This does not appear to be the kernel source directory." 1>&2
-	exit 1
-fi
-
-mode=${1:?"Usage: $0 [oldconfig|editconfig]"}
-yes=0
-case "$mode" in
-    update*configs)  mode='silentoldconfig' ;;
-    default*configs) mode='oldconfig'; yes=1 ;;
-    edit*configs)    ;; # All is good
-    gen*configs)     mode='genconfigs' ;; # All is good
-    dump*configs)    mode='config'; yes=1 ;;
-    *) echo "$0 called with invalid mode" 1>&2
-       exit 1 ;;
-esac
-kerneldir="`pwd`"
-confdir="$kerneldir/${DEBIAN}/config"
-sharedconfdir="$kerneldir/debian.linaro/config"
-variant="$2"
-
-. $DEBIAN/etc/kernelconfig
-
-bindir="`pwd`/${DROOT}/scripts/misc"
-common_conf="$confdir/config.common.$family"
-tmpdir=`mktemp -d`
-mkdir "$tmpdir/CONFIGS"
-
-if [ "$mode" = "genconfigs" ]; then
-	keep=1
-	mode="oldconfig"
-	test -d CONFIGS || mkdir CONFIGS
-fi
-
-for arch in $archs; do
-	rm -rf build
-	mkdir build
-
-	# Map debian archs to kernel archs
-	case "$arch" in
-		ppc64)		kernarch="powerpc"	;;
-		amd64)		kernarch="x86_64"	;;
-		lpia)		kernarch="x86" 		;;
-		sparc)		kernarch="sparc64"	;;
-		armel|armhf)	kernarch="arm"		;;
-		*)		kernarch="$arch"	;;
-	esac
-
-	archconfdir=$confdir/$arch
-	flavourconfigs=$(cd $archconfdir && ls config.flavour.*)
-
-	# Merge configs
-	# We merge config.common.ubuntu + config.common.<arch> +
-	# config.flavour.<flavour>
-
-	for config in $flavourconfigs; do
-		fullconf="$tmpdir/$arch-$config-full"
-		case $config in
-		*)
-			: >"$fullconf"
-			if [ -f $common_conf ]; then
-				cat $common_conf >> "$fullconf"
-			fi
-			if [ -f $archconfdir/config.common.$arch ]; then
-				cat $archconfdir/config.common.$arch >> "$fullconf"
-			fi
-			cat "$archconfdir/$config" >>"$fullconf"
-			if [ -f $confdir/OVERRIDES ]; then
-				cat $confdir/OVERRIDES >> "$fullconf"
-			fi
-			;;
-		esac
-	done
-
-	for config in $flavourconfigs; do
-		if [ -f $archconfdir/$config ]; then
-			fullconf="$tmpdir/$arch-$config-full"
-			cat "$fullconf" > build/.config
-			# Call oldconfig or menuconfig
-			case "$mode" in
-			    editconfigs)
-				# Interactively edit config parameters
-				while : ; do
-					echo -n "Do you want to edit config: $arch/$config? [Y/n] "
-					read choice
-					
-					case "$choice" in
-					y* | Y* | "" )
-						make O=`pwd`/build ARCH=$kernarch menuconfig
-						break ;;
-					n* | N* )
-						break ;;
-					*)
-						echo "Entry not valid"
-					esac
-				done
-				;;
-			    *)
-				echo "* Run $mode (yes=$yes) on $arch/$config ..."
-				if [ "$yes" -eq 1 ]; then
-					yes "" | make O=`pwd`/build ARCH=$kernarch "$mode"
-				else
-					make O=`pwd`/build ARCH=$kernarch "$mode"
-				fi ;;
-			esac
-			cat build/.config > $archconfdir/$config
-			cat build/.config > "$tmpdir/CONFIGS/$arch-$config"
-			if [ "$keep" = "1" ]; then
-				cat build/.config > CONFIGS/$arch-$config
-			fi
-		else
-			echo "!! Config not found $archconfdir/$config..."
-		fi
-	done
-
-	echo "Running splitconfig.pl for $arch"
-	echo
-
-	# Can we make this more robust by avoiding $tmpdir completely?
-	# This approach was used for now because I didn't want to change
-	# splitconfig.pl
-	(cd $archconfdir; $bindir/splitconfig.pl; mv config.common \
-	 config.common.$arch; cp config.common.$arch $tmpdir)
-done
-
-rm -f $common_conf
-
-# Now run splitconfig.pl on all the config.common.<arch> copied to
-# $tmpdir
-(cd $tmpdir; $bindir/splitconfig.pl)
-(
-	cd $confdir;
-	rm -f *-full
-	grep -v 'is UNMERGABLE' <$tmpdir/config.common >$common_conf
-	for arch in $archs; do
-		grep -v 'is UNMERGABLE' <$tmpdir/config.common.$arch \
-			>$arch/config.common.$arch
-	done
-)
-
-echo ""
-echo "Running config-check for all configurations ..."
-echo ""
-fail=0
-for arch in $archs; do
-	archconfdir=$confdir/$arch
-	flavourconfigs=$(cd $archconfdir && ls config.flavour.*)
-	for config in $flavourconfigs; do
-		flavour="${config##*.}"
-		if [ -f $archconfdir/$config ]; then
-			fullconf="$tmpdir/CONFIGS/$arch-$config"
-			"$bindir/../config-check" "$fullconf" "$arch" "$flavour" "$sharedconfdir" "0" || let "fail=$fail+1"
-		fi
-	done
-done
-
-if [ "$fail" != 0 ]; then
-	echo ""
-	echo "*** ERROR: $fail config-check failures detected"
-	echo ""
-fi
-
-rm -rf build
-
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/debian/scripts/misc/retag linux-linaro-3.4-2012.05-1_cavium/debian/scripts/misc/retag
--- linux-linaro-3.4-2012.05-1_original/debian/scripts/misc/retag	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/debian/scripts/misc/retag	1970-01-01 08:00:00.000000000 +0800
@@ -1,34 +0,0 @@
-#!/usr/bin/perl -w
-
-open(TAGS, "git tag -l |") or die "Could not get list of tags";
-@tags = <TAGS>;
-close(TAGS);
-
-open(LOGS, "git log --pretty=short |") or die "ERROR: Calling git log";
-my $commit = "";
-
-while (<LOGS>) {
-	my $origtag;
-
-	if (m|^commit (.*)$|) {
-		$commit = $1;
-		next;
-	}
-
-	m|\s*UBUNTU: (Ubuntu-2\.6\..*)| or next;
-
-	$tag = $1;
-
-	($origtag) = grep(/^$tag.orig$/, @tags);
-
-	if (!defined($origtag)) {
-		print "I: Adding original tag for $tag\n";
-		system("git tag -m $tag $tag.orig $tag");
-	}
-
-	print "I: Tagging $tag => $commit\n";
-
-	system("git tag -f -m $tag $tag $commit");
-}
-
-close(LOGS);
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/debian/scripts/misc/splitconfig.pl linux-linaro-3.4-2012.05-1_cavium/debian/scripts/misc/splitconfig.pl
--- linux-linaro-3.4-2012.05-1_original/debian/scripts/misc/splitconfig.pl	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/debian/scripts/misc/splitconfig.pl	1970-01-01 08:00:00.000000000 +0800
@@ -1,111 +0,0 @@
-#!/usr/bin/perl -w
-
-%allconfigs = ();
-%common = ();
-
-print "Reading config's ...\n";
-
-opendir(DIR, ".");
-
-while (defined($config = readdir(DIR))) {
-	# Only config.*
-	next if $config !~ /^config\..*/;
-	# Nothing that is disabled, or remnant
-	next if $config =~ /.*\.(default|disabled|stub)$/;
-
-	%{$allconfigs{$config}} = ();
-
-	print "  processing $config ... ";
-
-	open(CONFIG, "< $config");
-
-	while (<CONFIG>) {
-		# Skip comments
-		/^#*\s*CONFIG_(\w+)[\s=](.*)$/ or next;
-
-		${$allconfigs{$config}}{$1} = $2;
-
-		$common{$1} = $2;
-	}
-
-	close(CONFIG);
-
-	print "done.\n";
-}
-
-closedir(DIR);
-
-print "\n";
-
-print "Merging lists ... \n";
-
-# %options - pointer to flavour config inside the allconfigs array
-for $config (keys(%allconfigs)) {
-	my %options = %{$allconfigs{$config}};
-
-	print "   processing $config ... ";
-
-	for $key (keys(%common)) {
-		next if not defined $common{$key};
-
-		# If we don't have the common option, then it isn't
-		# common. If we do have that option, it must have the same
-		# value.  EXCEPT where this file does not have a value at all
-		# which may safely be merged with any other value; the value
-		# will be elided during recombination of the parts.
-		if (!defined($options{$key})) {
-			# Its ok really ... let it merge
-		} elsif (not defined($options{$key})) {
-			undef $common{$key};
-		} elsif ($common{$key} ne $options{$key}) {
-			undef $common{$key};
-		}
-	}
-
-	print "done.\n";
-}
-
-print "\n";
-
-print "Creating common config ... ";
-
-open(COMMON, "> config.common");
-print COMMON "#\n# Common config options automatically generated by splitconfig.pl\n#\n";
-
-for $key (sort(keys(%common))) {
-	if (not defined $common{$key}) {
-		print COMMON "# CONFIG_$key is UNMERGABLE\n";
-	} elsif ($common{$key} eq "is not set") {
-		print COMMON "# CONFIG_$key is not set\n";
-	} else {
-		print COMMON "CONFIG_$key=$common{$key}\n";
-	}
-}
-close(COMMON);
-
-print "done.\n\n";
-
-print "Creating stub configs ...\n";
-
-for $config (keys(%allconfigs)) {
-	my %options = %{$allconfigs{$config}};
-
-	print "  processing $config ... ";
-
-	open(STUB, "> $config");
-	print STUB "#\n# Config options for $config automatically generated by splitconfig.pl\n#\n";
-
-	for $key (sort(keys(%options))) {
-		next if defined $common{$key};
-
-		if ($options{$key} =~ /^is /) {
-			print STUB "# CONFIG_$key $options{$key}\n";
-		} else {
-			print STUB "CONFIG_$key=$options{$key}\n";
-		}
-	}
-
-	close(STUB);
-
-	print "done.\n";
-}
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/debian/scripts/module-check linux-linaro-3.4-2012.05-1_cavium/debian/scripts/module-check
--- linux-linaro-3.4-2012.05-1_original/debian/scripts/module-check	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/debian/scripts/module-check	1970-01-01 08:00:00.000000000 +0800
@@ -1,120 +0,0 @@
-#!/usr/bin/perl -w
-
-$flavour = shift;
-$prev_abidir = shift;
-$abidir = shift;
-$skipmodule = shift;
-
-print "II: Checking modules for $flavour...";
-
-if (-f "$prev_abidir/ignore.modules"
-    or -f "$prev_abidir/$flavour.ignore.modules") {
-	print "explicitly ignoring modules\n";
-	exit(0);
-}
-
-if (not -f "$abidir/$flavour.modules" or not -f
-    "$prev_abidir/$flavour.modules") {
-	print "previous or current modules file missing!\n";
-	print "   $abidir/$flavour.modules\n";
-	print "   $prev_abidir/$flavour.modules\n";
-	if (defined($skipmodule)) {
-		exit(0);
-	} else {
-		exit(1);
-	}
-}
-
-print "\n";
-
-my %modules;
-my %modules_ignore;
-my $missing = 0;
-my $new = 0;
-my $errors = 0;
-
-# See if we have any ignores
-if (-f "$prev_abidir/../modules.ignore") {
-	my $ignore = 0;
-	open(IGNORE, "< $prev_abidir/../modules.ignore") or
-		die "Could not open $prev_abidir/../modules.ignore";
-	print "   reading modules to ignore...";
-	while (<IGNORE>) {
-		chomp;
-		next if /\s*#/;
-		$modules_ignore{$_} = 1;
-		$ignore++;
-	}
-	close(IGNORE);
-	print "read $ignore modules.\n";
-}
-
-# Read new modules first
-print "   reading new modules...";
-$new_count = 0;
-open(NEW, "< $abidir/$flavour.modules") or
-	die "Could not open $abidir/$flavour.modules";
-while (<NEW>) {
-	chomp;
-	$modules{$_} = 1;
-	$new_count++;
-}
-close(NEW);
-print "read $new_count modules.\n";
-
-# Now the old modules, checking for missing ones
-print "   reading old modules...";
-$old_count = 0;
-open(OLD, "< $prev_abidir/$flavour.modules") or
-	die "Could not open $prev_abidir/$flavour.modules";
-while (<OLD>) {
-	chomp;
-	if (not defined($modules{$_})) {
-		print "\n" if not $missing;
-		$missing++;
-		if (not defined($modules_ignore{$_})) {
-			print "      MISS: $_\n";
-			$errors++;
-		} else {
-			print "      MISS: $_ (ignored)\n";
-		}
-	} else {
-		$modules{$_}++;
-	}
-	$old_count++;
-}
-close(OLD);
-# Check for new modules
-foreach $mod (keys(%modules)) {
-	if ($modules{$mod} < 2) {
-		print "\n" if not $missing and not $new;
-		print "      NEW : $mod\n";
-		$new++;
-	}
-}
-if ($new or $missing) {
-	print "      read $old_count modules : new($new)  missing($missing)\n";
-} else {
-	print "read $old_count modules.\n";
-}
-
-
-# Let's see where we stand...
-if ($errors) {
-	if (defined($skipmodule)) {
-		print "WW: Explicitly asked to ignore failures (probably not good)\n";
-	} else {
-		print "EE: Missing modules (start begging for mercy)\n";
-		exit 1
-	}
-}
-
-if ($new) {
-	print "II: New modules (you've been busy, wipe the poop off your nose)\n";
-} else {
-	print "II: No new modules (hope you're happy, slacker)\n";
-}
-
-print "II: Done\n";
-
-exit(0);
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/debian/scripts/module-inclusion linux-linaro-3.4-2012.05-1_cavium/debian/scripts/module-inclusion
--- linux-linaro-3.4-2012.05-1_original/debian/scripts/module-inclusion	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/debian/scripts/module-inclusion	1970-01-01 08:00:00.000000000 +0800
@@ -1,60 +0,0 @@
-#!/bin/bash
-
-#
-# Build a new directory of modules based on an inclusion list.
-# The includsion list format must be a bash regular expression.
-#
-# usage: $0 ROOT INCLUSION_LIST
-# example: $0 debian/build/build-virtual \
-#       debian/build/build-virtual-ALL debian/build/build-virtual \
-#	debian.master/control.d/virtual.inclusion-list
-master=0
-if [ "$1" = "--master" ]; then
-	master=1
-	shift
-fi
-
-ROOT=$1
-NROOT=$2
-ILIST=$3
-
-#
-# Prep a destination directory.
-#
-mkdir -p ${NROOT}
-
-# Copy over the framework...
-if  [ "$master" -eq 1 ]; then
-	(cd ${ROOT}; find . ! -name "*.ko" -type f) | \
-	while read f
-	do
-		mkdir -p ${NROOT}/`dirname $f`
-		mv ${ROOT}/$f ${NROOT}/$f
-	done
-fi
-
-cat ${ILIST} |while read i
-do
-	#
-	# 'find' blurts a warning if it cannot find any ko files.
-	#
-	if echo "$i" | grep '\*' > /dev/null
-	then
-		(cd ${ROOT}; eval find "${i}" -name "*.ko") |while read f
-		do
-			mkdir -p ${NROOT}/`dirname $f`
-			mv ${ROOT}/$f ${NROOT}/$f
-		done
-	else
-		if [ -f "${ROOT}/$i" ]
-		then
-			mkdir -p ${NROOT}/`dirname $i`
-			mv ${ROOT}/$i ${NROOT}/$i
-		else
-			echo Warning: Could not find ${ROOT}/$i
-		fi
-	fi
-
-done
-
-exit 0
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/debian/scripts/sub-flavour linux-linaro-3.4-2012.05-1_cavium/debian/scripts/sub-flavour
--- linux-linaro-3.4-2012.05-1_original/debian/scripts/sub-flavour	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/debian/scripts/sub-flavour	1970-01-01 08:00:00.000000000 +0800
@@ -1,69 +0,0 @@
-#!/bin/bash
-
-. debian/debian.env
-
-echo "SUB_PROCESS $FROM => $TO"
-
-export from_pkg="linux-image-$ABI_RELEASE-$FROM"
-export to_pkg="linux-image-$ABI_RELEASE-$TO"
-
-from_moddir="debian/$from_pkg/lib/modules/$ABI_RELEASE-$FROM"
-to_moddir="debian/$to_pkg/lib/modules/$ABI_RELEASE-$FROM"
-
-install -d "debian/$to_pkg/boot"
-install -m644 debian/$from_pkg/boot/config-$ABI_RELEASE-$FROM \
-	debian/$to_pkg/boot/
-install -m600 debian/$from_pkg/boot/{vmlinuz,System.map}-$ABI_RELEASE-$FROM \
-	debian/$to_pkg/boot/
-
-#
-# Print some warnings if there are files in the sub-flavours list
-# that do not actually exist.
-#
-cat ${DEBIAN}/sub-flavours/$TO.list | while read line
-do
-(
-	cd debian/$from_pkg/lib/modules/$ABI_RELEASE-$FROM/kernel;
-	#
-	# If its a wildcard, then check that there are files that match.
-	#
-	if echo "$line" | grep '\*' > /dev/null
-	then
-		if [ `eval find "$line" -name '*.ko' 2>/dev/null|wc -l` -lt 1 ]
-		then
-			echo SUB_INST Warning - No files in $line
-		fi
-	#
-	# Else it should be a single file reference.
-	#
-	elif [ ! -f "$line" ]
-	then
-		echo SUB_INST Warning - could not find "$line"
-	fi
-)
-done
-
-cat ${DEBIAN}/sub-flavours/$TO.list | while read line; do
-	(
-	cd debian/$from_pkg/lib/modules/$ABI_RELEASE-$FROM/kernel;
-	if echo "$line" | grep '\*' > /dev/null
-	then
-		eval find "$line" -name '*.ko' 2>/dev/null || true
-	elif [ -f "$line" ]
-	then
-		echo "$line"
-	fi
-	);
-done | while read mod; do
-	echo "SUB_INST checking: $mod"
-	fromdir="/lib/modules/$ABI_RELEASE-$FROM/"
-	egrep "^($fromdir)?kernel/$mod:" \
-		$from_moddir/modules.dep | sed -e "s|^$fromdir||" -e 's/://' -e 's/ /\n/g' | \
-	while read m; do
-		m="${fromdir}$m"
-		test -f debian/$to_pkg/$m && continue
-		echo "SUB_INST installing: $m"
-		install -D -m644 debian/$from_pkg/$m \
-			debian/$to_pkg/$m
-	done
-done
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/debian/source/format linux-linaro-3.4-2012.05-1_cavium/debian/source/format
--- linux-linaro-3.4-2012.05-1_original/debian/source/format	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/debian/source/format	1970-01-01 08:00:00.000000000 +0800
@@ -1 +0,0 @@
-1.0
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/debian/stamps/keep-dir linux-linaro-3.4-2012.05-1_cavium/debian/stamps/keep-dir
--- linux-linaro-3.4-2012.05-1_original/debian/stamps/keep-dir	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/debian/stamps/keep-dir	1970-01-01 08:00:00.000000000 +0800
@@ -1 +0,0 @@
-Place holder
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/debian/tests/check-aliases linux-linaro-3.4-2012.05-1_cavium/debian/tests/check-aliases
--- linux-linaro-3.4-2012.05-1_original/debian/tests/check-aliases	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/debian/tests/check-aliases	1970-01-01 08:00:00.000000000 +0800
@@ -1,24 +0,0 @@
-#!/usr/bin/perl -w
-
-my %map;
-
-print "Checking for dupe aliases in $ENV{'FLAVOUR'}...\n";
-
-$aliases =
-  "$ENV{'INSTALL_DIR'}/lib/modules/$ENV{'VERSION'}-$ENV{'FLAVOUR'}/modules.alias";
-
-open(ALIASES, "< $aliases") or die "Could not open $aliases";
-
-while (<ALIASES>) {
-	chomp;
-	my ($junk, $alias, $module) = split;
-
-	if (defined($map{$alias})) {
-		printf("%s %20s / %-20s : %s \n", ("$map{$alias}" eq "$module")
-			? "INT" : "   ", $map{$alias}, $module, $alias);
-	} else {
-		$map{$alias} = $module;
-	}
-}
-
-exit(0);
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/debian/tests/README linux-linaro-3.4-2012.05-1_cavium/debian/tests/README
--- linux-linaro-3.4-2012.05-1_original/debian/tests/README	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/debian/tests/README	1970-01-01 08:00:00.000000000 +0800
@@ -1,21 +0,0 @@
-Scripts placed in this directory get called one at a time by run-parts(8).
-The scripts are expected to perform some sort of sanity checks on the
-finished build. Scripts will be called once for each flavour.
-
-Some environment variables are exported to make life a little easier:
-
-DPKG_ARCH     : The dpkg architecture (e.g. "amd64")
-KERN_ARCH     : The kernel architecture (e.g. "x86_64")
-FLAVOUR       : The specific flavour for this run (e.g. "generic")
-VERSION       : The full version of this build (e.g. 2.6.22-1)
-REVISION      : The exact revision of this build (e.g. 1.3)
-PREV_REVISION : The revision prior to this one
-ABI_NUM       : The specific ABI number for this build (e.g. 2)
-PREV_ABI_NUM  : The previous ABI number. Can be the same as ABI_NUM.
-BUILD_DIR     : The directory where this build took place
-INSTALL_DIR   : The directory where the package is prepared
-SOURCE_DIR    : Where the main kernel source is
-
-Scripts are expected to have a zero exit status when no problems occur,
-and non-zero when an error occurs that should stop the build. Scripts
-should print whatever info they deem needed to deduce the problem.
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/debian/tools/generic linux-linaro-3.4-2012.05-1_cavium/debian/tools/generic
--- linux-linaro-3.4-2012.05-1_original/debian/tools/generic	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/debian/tools/generic	1970-01-01 08:00:00.000000000 +0800
@@ -1,16 +0,0 @@
-#!/bin/bash
-full_version=`uname -r`
-
-# Removing flavour from version i.e. generic or server.
-flavour_abi=${full_version#*-}
-flavour=${flavour_abi#*-}
-version=${full_version%-$flavour}
-this="$0_$version"
-
-if [ ! -f "$this" ]; then
-    echo "$this not found" >&2
-    echo "You may need to install linux-tools-$version" >&2
-    exit 2
-fi
-
-exec "$this" "$@"
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/debian/tools/perf linux-linaro-3.4-2012.05-1_cavium/debian/tools/perf
--- linux-linaro-3.4-2012.05-1_original/debian/tools/perf	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/debian/tools/perf	1970-01-01 08:00:00.000000000 +0800
@@ -1,16 +0,0 @@
-#!/bin/bash
-full_version=`uname -r`
-
-# Removing flavour from version i.e. generic or server.
-flavour_abi=${full_version#*-}
-flavour=${flavour_abi#*-}
-version=${full_version%-$flavour}
-perf="perf_$version"
-
-if ! which "$perf" > /dev/null; then
-    echo "$perf not found" >&2
-    echo "You may need to install linux-tools-$version" >&2
-    exit 2
-fi
-
-exec "$perf" "$@"
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/debian/tools/turbostat linux-linaro-3.4-2012.05-1_cavium/debian/tools/turbostat
--- linux-linaro-3.4-2012.05-1_original/debian/tools/turbostat	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/debian/tools/turbostat	1970-01-01 08:00:00.000000000 +0800
@@ -1,16 +0,0 @@
-#!/bin/bash
-full_version=`uname -r`
-
-# Removing flavour from version i.e. generic or server.
-flavour_abi=${full_version#*-}
-flavour=${flavour_abi#*-}
-version=${full_version%-$flavour}
-turbostat="turbostat_$version"
-
-if ! which "$turbostat" > /dev/null; then
-    echo "$turbostat not found" >&2
-    echo "You may need to install linux-tools-$version" >&2
-    exit 2
-fi
-
-exec "$turbostat" "$@"
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/debian/tools/x86_energy_perf_policy linux-linaro-3.4-2012.05-1_cavium/debian/tools/x86_energy_perf_policy
--- linux-linaro-3.4-2012.05-1_original/debian/tools/x86_energy_perf_policy	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/debian/tools/x86_energy_perf_policy	1970-01-01 08:00:00.000000000 +0800
@@ -1,16 +0,0 @@
-#!/bin/bash
-full_version=`uname -r`
-
-# Removing flavour from version i.e. generic or server.
-flavour_abi=${full_version#*-}
-flavour=${flavour_abi#*-}
-version=${full_version%-$flavour}
-x86_energy_perf_policy="x86_energy_perf_policy_$version"
-
-if ! which "$x86_energy_perf_policy" > /dev/null; then
-    echo "$x86_energy_perf_policy not found" >&2
-    echo "You may need to install linux-tools-$version" >&2
-    exit 2
-fi
-
-exec "$x86_energy_perf_policy" "$@"
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/base/core.c linux-linaro-3.4-2012.05-1_cavium/drivers/base/core.c
--- linux-linaro-3.4-2012.05-1_original/drivers/base/core.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/base/core.c	2015-04-21 14:24:43.374116000 +0800
@@ -190,10 +190,10 @@
 		dev->type->release(dev);
 	else if (dev->class && dev->class->dev_release)
 		dev->class->dev_release(dev);
-	else
+	/*else
 		WARN(1, KERN_ERR "Device '%s' does not have a release() "
 			"function, it is broken and must be fixed.\n",
-			dev_name(dev));
+			dev_name(dev));*/
 	kfree(p);
 }
 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/base/firmware_class.c linux-linaro-3.4-2012.05-1_cavium/drivers/base/firmware_class.c
--- linux-linaro-3.4-2012.05-1_original/drivers/base/firmware_class.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/base/firmware_class.c	2014-07-29 17:28:38.819972000 +0800
@@ -80,7 +80,7 @@
 	FW_STATUS_ABORT,
 };
 
-static int loading_timeout = 60;	/* In seconds */
+static int loading_timeout = 1;	/* In seconds */
 
 static inline long firmware_loading_timeout(void)
 {
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/celestial/audio/audio_reg_def.h linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/audio/audio_reg_def.h
--- linux-linaro-3.4-2012.05-1_original/drivers/celestial/audio/audio_reg_def.h	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/audio/audio_reg_def.h	2014-08-13 14:09:14.922849000 +0800
@@ -0,0 +1,193 @@
+#ifndef __AUDIO_REG_DEF_H__
+#define __AUDIO_REG_DEF_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define CSM_AUDIO_REG_BASE	(0xB1200000)
+#define CSM_AUDIO_REG_SIZE		(0x100000)
+
+/* ----------------- Common Register ------------------ */
+#define CSM1800_AUD_STC             (CSM_AUDIO_REG_BASE + 0x0000)
+#define CSM1800_AUD_HISTC           (CSM_AUDIO_REG_BASE + 0x0004)
+#define CSM1800_AUD_MAILBOX0        (CSM_AUDIO_REG_BASE + 0x0100)
+#define CSM1800_AUD_MAILBOX1        (CSM_AUDIO_REG_BASE + 0x0104)
+#define CSM1800_AUD_MAILBOX2        (CSM_AUDIO_REG_BASE + 0x0108)
+#define CSM1800_AUD_MAILBOX3        (CSM_AUDIO_REG_BASE + 0x010c)
+#define CSM1800_AUD_MAILBOX4        (CSM_AUDIO_REG_BASE + 0x0110)
+#define CSM1800_AUD_MAILBOX5        (CSM_AUDIO_REG_BASE + 0x0114)
+#define CSM1800_AUD2VID_MAILBOX0    (CSM_AUDIO_REG_BASE + 0x0118)
+#define CSM1800_VID2AUD_MAILBOX0    (CSM_AUDIO_REG_BASE + 0x011c)
+#define CSM1800_AUD2VID_MAILBOX1    (CSM_AUDIO_REG_BASE + 0x0120)
+#define CSM1800_VID2AUD_MAILBOX1    (CSM_AUDIO_REG_BASE + 0x0124)
+#define CSM1800_AUD_INT             (CSM_AUDIO_REG_BASE + 0x0200)
+#define CSM1800_DSP_INT_SRC         (CSM_AUDIO_REG_BASE + 0x0204)
+#define CSM1800_DSP_INT_MASK        (CSM_AUDIO_REG_BASE + 0x0208)
+#define CSM1800_DSP_INT_INPUT_BIT   0x01
+#define CSM1800_DSP_INT_SFT_BIT     0x02
+#define CSM1800_DSP_INT_UART_BIT    0x04
+#define CSM1800_DSP_INT_TIMER0_BIT  0x08
+#define CSM1800_DSP_INT_TIMER1_BIT  0x10
+#define CSM1800_AUD_SRC_MIX_BOUND   (CSM_AUDIO_REG_BASE + 0x0500)
+#define CSM1800_AUD_DDR_IO          (CSM_AUDIO_REG_BASE + 0x0504)
+
+/* ------------------ I2s input ---------------------- */
+#define CSM1800_AUDIO_INPUT_LEVEL   (CSM_AUDIO_REG_BASE + 0x0300)
+#define CSM1800_AUDIO_INPUT_CTRL    (CSM_AUDIO_REG_BASE + 0x0304)
+#define CSM1800_AUDIO_INPUT_CTRL_ENABLE_BIT     0x1
+#define CSM1800_AUDIO_INPUT_CTRL_INVERT_WS_BIT  0x10
+#define CSM1800_AUDIO_INPUT_CTRL_INVERT_SCK_BIT 0x100
+#define CSM1800_AUDIO_INPUT_CTRL_SHIFT_CNT_BIT  0x1f0000
+
+#define CSM1800_AUDIO_INPUT_CNT     (CSM_AUDIO_REG_BASE + 0x0308)
+#define CSM1800_AUDIO_INPUT_SAMPLE  (CSM_AUDIO_REG_BASE + 0x030c)
+#define CSM1800_AUDIO_INPUT_RATE    (CSM_AUDIO_REG_BASE + 0x0310)
+
+#define CSM1800_AUD_PTS0RP          (CSM_AUDIO_REG_BASE + 0x0400)
+#define CSM1800_AUD_PTS0WP          (CSM_AUDIO_REG_BASE + 0x0404)
+#define CSM1800_AUD_PTS0UP          (CSM_AUDIO_REG_BASE + 0x0408)
+#define CSM1800_AUD_PTS0LOW         (CSM_AUDIO_REG_BASE + 0x040c)
+#define CSM1800_AUD_PTS1RP          (CSM_AUDIO_REG_BASE + 0x0410)
+#define CSM1800_AUD_PTS1WP          (CSM_AUDIO_REG_BASE + 0x0414)
+#define CSM1800_AUD_PTS1UP          (CSM_AUDIO_REG_BASE + 0x0418)
+#define CSM1800_AUD_PTS1LOW         (CSM_AUDIO_REG_BASE + 0x041c)
+#define CSM1800_AUD_PTS_BITWIDTH    (0x0FFFFFF8)
+#define CSM1800_AUD_PTS_TOGGLEBIT   (0x10000000)
+
+/* ------------------ AUDIO I2S ----------------------- */
+#define CSM1800_AUD_I2S_SHIFTCNT    (CSM_AUDIO_REG_BASE + 0x1000)
+#define CSM1800_AUD_I2S_CNTL        (CSM_AUDIO_REG_BASE + 0x1004)
+#define CSM1800_AUD_I2S_RP0         (CSM_AUDIO_REG_BASE + 0x1100)
+#define CSM1800_AUD_I2S_WP0         (CSM_AUDIO_REG_BASE + 0x1104)
+#define CSM1800_AUD_I2S_UP0         (CSM_AUDIO_REG_BASE + 0x1108)
+#define CSM1800_AUD_I2S_LOW0        (CSM_AUDIO_REG_BASE + 0x110c)
+#define CSM1800_AUD_I2S_SCAL0       (CSM_AUDIO_REG_BASE + 0x1110)
+#define CSM1800_AUD_I2S_RP1         (CSM_AUDIO_REG_BASE + 0x1114)
+#define CSM1800_AUD_I2S_WP1         (CSM_AUDIO_REG_BASE + 0x1118)
+#define CSM1800_AUD_I2S_UP1         (CSM_AUDIO_REG_BASE + 0x111c)
+#define CSM1800_AUD_I2S_LOW1        (CSM_AUDIO_REG_BASE + 0x1120)
+#define CSM1800_AUD_I2S_SCAL1       (CSM_AUDIO_REG_BASE + 0x1124)
+#define CSM1800_AUD_I2S_BITWIDTH    0x7FFFFFF8
+#define CSM1800_AUD_I2S_TOGGLEBIT   0x80000000
+
+/* ------------------ AUDIO I2S ----------------------- */
+#define CSM1800_AUD_SPDIF_CNTL      (CSM_AUDIO_REG_BASE + 0x2000)
+#define CSM1800_AUD_SPDIF_RP0       (CSM_AUDIO_REG_BASE + 0x2100)
+#define CSM1800_AUD_SPDIF_WP0       (CSM_AUDIO_REG_BASE + 0x2104)
+#define CSM1800_AUD_SPDIF_UP0       (CSM_AUDIO_REG_BASE + 0x2108)
+#define CSM1800_AUD_SPDIF_LOW0      (CSM_AUDIO_REG_BASE + 0x210c)
+#define CSM1800_AUD_SPDIF_SCAL0     (CSM_AUDIO_REG_BASE + 0x2110)
+#define CSM1800_AUD_SPDIF_RP1       (CSM_AUDIO_REG_BASE + 0x2114)
+#define CSM1800_AUD_SPDIF_WP1       (CSM_AUDIO_REG_BASE + 0x2118)
+#define CSM1800_AUD_SPDIF_UP1       (CSM_AUDIO_REG_BASE + 0x211c)
+#define CSM1800_AUD_SPDIF_LOW1      (CSM_AUDIO_REG_BASE + 0x2120)
+#define CSM1800_AUD_SPDIF_SCAL1     (CSM_AUDIO_REG_BASE + 0x2124)
+#define CSM1800_AUD_SPDIF_VERSION   (CSM_AUDIO_REG_BASE + 0x2200)
+#define CSM1800_AUD_SPDIF_CHANNELSTATUS1  (CSM_AUDIO_REG_BASE + 0x2204)
+#define CSM1800_AUD_SPDIF_CHANNELSTATUS12 (CSM_AUDIO_REG_BASE + 0x2208)
+#define CSM1800_AUD_SPDIF_CHANNELSTATUS2  (CSM_AUDIO_REG_BASE + 0x220c)
+#define CSM1800_AUD_SPDIF_CHANNELSTATUS3  (CSM_AUDIO_REG_BASE + 0x2210) // Audio Bit Rate 
+#define CSM1800_AUD_SPDIF_VALID           (CSM_AUDIO_REG_BASE + 0x2238)
+#define CSM1800_AUD_SPDIF_FIFO_STATUS     (CSM_AUDIO_REG_BASE + 0x223c)
+#define CSM1800_AUD_SPDIF_BITWIDTH    0x7FFFFFF8
+#define CSM1800_AUD_SPDIF_TOGGLEBIT   0x80000000
+
+/* not used spdif regs */
+#define CSM1800_AUD_SPDIF_CHANNELSTATUS4 (CSM_AUDIO_REG_BASE + 0x2214)
+#define CSM1800_AUD_SPDIF_CHANNELSTATUS5 (CSM_AUDIO_REG_BASE + 0x2218)
+#define CSM1800_AUD_SPDIF_CHANNELSTATUS6 (CSM_AUDIO_REG_BASE + 0x221C)
+#define CSM1800_AUD_SPDIF_USERDATA1      (CSM_AUDIO_REG_BASE + 0x2220)
+#define CSM1800_AUD_SPDIF_USERDATA2      (CSM_AUDIO_REG_BASE + 0x2224)
+#define CSM1800_AUD_SPDIF_USERDATA3      (CSM_AUDIO_REG_BASE + 0x2228)
+#define CSM1800_AUD_SPDIF_USERDATA4      (CSM_AUDIO_REG_BASE + 0x222C)
+#define CSM1800_AUD_SPDIF_USERDATA5      (CSM_AUDIO_REG_BASE + 0x2230)
+#define CSM1800_AUD_SPDIF_USERDATA6      (CSM_AUDIO_REG_BASE + 0x2234)
+
+/* ------------------ AUDIO SRC ---------------------- */
+#define CSM1800_AUD_SRC_BASEADDR    (CSM_AUDIO_REG_BASE + 0x3000)
+#define CSM1800_AUD_SRC_BASEADDR_BITS 0x3FC00000 // b29:b22
+#define CSM1800_AUD_SRC_ADDRPARA    (CSM_AUDIO_REG_BASE + 0x3004)
+#define CSM1800_AUD_SRC_CONTROL     (CSM_AUDIO_REG_BASE + 0x3008)
+#define CSM1800_AUD_SRC_INWP        (CSM_AUDIO_REG_BASE + 0x3100) // 8 copy
+#define CSM1800_AUD_SRC_INRP        (CSM_AUDIO_REG_BASE + 0x3200) // 8 copy
+#define CSM1800_AUD_SRC_INLOW       (CSM_AUDIO_REG_BASE + 0x3300) // 8 copy
+#define CSM1800_AUD_SRC_INUP        (CSM_AUDIO_REG_BASE + 0x3400) // 8 copy
+#define CSM1800_AUD_SRC_OUTWP       (CSM_AUDIO_REG_BASE + 0x3500) // 8 copy
+#define CSM1800_AUD_SRC_OUTRP       (CSM_AUDIO_REG_BASE + 0x3600) // 8 copy
+#define CSM1800_AUD_SRC_OUTLOW      (CSM_AUDIO_REG_BASE + 0x3700) // 8 copy
+#define CSM1800_AUD_SRC_OUTUP       (CSM_AUDIO_REG_BASE + 0x3800) // 8 copy
+#define CSM1800_AUD_SRC_INFRLTH     (CSM_AUDIO_REG_BASE + 0x3900) // 8 copy
+#define CSM1800_AUD_SRC_OUTFRLTH    (CSM_AUDIO_REG_BASE + 0x3a00) // 8 copy
+#define CSM1800_AUD_SRC_BITWIDTH    (0x3ffff8)
+#define CSM1800_AUD_SRC_TOGGLEBIT   (0x400000)
+
+/* -----------------AUDIO DAC ------------------------ */
+#define CSM_AUDIO_DAC_REG_BASE (CSM_AUDIO_REG_BASE + 0x8000)
+#define CNC1900_AUD_DAC_RESET_ADDR (CSM_AUDIO_DAC_REG_BASE+0x0)
+#define CNC1900_AUD_DAC_LATCH_ADDR (CSM_AUDIO_DAC_REG_BASE+(0x1<<2))
+#define CNC1900_AUD_DAC_I2SMSMODE_ADDR (CSM_AUDIO_DAC_REG_BASE+(0xe<<2))
+#define CNC1900_AUD_DAC_POWER_CONTROL3_ADDR (CSM_AUDIO_DAC_REG_BASE+(0x18<<2))
+#define CNC1900_AUD_DAC_POWER_CONTROL0_ADDR (CSM_AUDIO_DAC_REG_BASE+(0x15<<2))
+#define CNC1900_AUD_DAC_POP_SUPPRESSION_1 (CSM_AUDIO_DAC_REG_BASE+(0xA2<<2))
+#define CNC1900_AUD_DAC_POP_SUPPRESSION_2 (CSM_AUDIO_DAC_REG_BASE+(0xA3<<2))
+#define CNC1900_AUD_DAC_POP_SUPPRESSION_SEG_START (CSM_AUDIO_DAC_REG_BASE+(0xA4<<2))
+#define CNC1900_AUD_DAC_POWER_CONSUMPTION (CSM_AUDIO_DAC_REG_BASE+(0x12<<2))
+#define CNC1900_AUD_DAC_SLEEPMODE    (CSM_AUDIO_DAC_REG_BASE + (0x11<<2))
+
+/* ------------------ INPUT FIFO --------------------- */
+#define CSM1800_AUD_CAB0RP          (CSM_AUDIO_REG_BASE + 0x4100)
+#define CSM1800_AUD_CAB0WP          (CSM_AUDIO_REG_BASE + 0x4104)
+#define CSM1800_AUD_CAB0UP          (CSM_AUDIO_REG_BASE + 0x4108)
+#define CSM1800_AUD_CAB0LOW         (CSM_AUDIO_REG_BASE + 0x410c)
+#define CSM1800_AUD_IFIFO0          (CSM_AUDIO_REG_BASE + 0x4110)
+#define CSM1800_AUD_CAB1RP          (CSM_AUDIO_REG_BASE + 0x4200)
+#define CSM1800_AUD_CAB1WP          (CSM_AUDIO_REG_BASE + 0x4204)
+#define CSM1800_AUD_CAB1UP          (CSM_AUDIO_REG_BASE + 0x4208)
+#define CSM1800_AUD_CAB1LOW         (CSM_AUDIO_REG_BASE + 0x420c)
+#define CSM1800_AUD_CAB_BITWIDTH    (0x7FFFFFFF)
+#define CSM1800_AUD_CAB_TOGGLEBIT   (0x80000000)
+
+#define CSM1800_AUD_IFIFO1          (CSM_AUDIO_REG_BASE + 0x4210)
+#define CSM1800_AUD_IFIFO_CTRL      (CSM_AUDIO_REG_BASE + 0x4000)
+#define CSM1800_AUD_IFIFO_CTRL_ENABLE0 0x1
+#define CSM1800_AUD_IFIFO_CTRL_ENABLE1 0x2
+#define CSM1800_AUD_IFIFO_CTRL_CLEAR0  0x4 // disable first, then clear
+#define CSM1800_AUD_IFIFO_CTRL_CLEAR1  0x8
+#define CSM1800_AUD_IFIFOCNT        (CSM_AUDIO_REG_BASE + 0x4004)
+                                    // high 16 bits for fifo1,
+                                    // low 16 bits for fifo0.
+                                    
+/* ------------------ Audio DMA -------------------------- */
+#define CSM1800_AUD_DMA_REG_BASE    (0xB1230000)
+#define CSM1800_AUD_DMA_SDRAM_BASE  (CSM1800_AUD_DMA_REG_BASE + 0xc000)
+#define CSM1800_AUD_DMA_LEN         (CSM1800_AUD_DMA_REG_BASE + 0xc004)
+#define CSM1800_AUD_DMA_CTRL        (CSM1800_AUD_DMA_REG_BASE + 0xc008)
+#define CSM1800_AUD_DMA_STATUS      (CSM1800_AUD_DMA_REG_BASE + 0xc00c)    
+#define CSM1800_AUD_DMA_SRAM0_BASE  (CSM1800_AUD_DMA_REG_BASE + 0xe000)
+#define CSM1800_AUD_DMA_SRAM1_BASE  (CSM1800_AUD_DMA_REG_BASE + 0xf000)
+
+/* --------------- RISC CPU control ------------------ */
+#define CSM1800_AUDIO_RISC_CTRL     (0xB1230000)
+#define CSM1800_RISC_IO_PROT        (0xB1230004)
+
+/* ------------------ Code & Data ------------------------ */
+#define CSM1800_AUD_ICACHE_BASE     (0xB1210000)
+#define CSM1800_AUD_DSRAM_BASE      (0xB1220000)
+
+/* ------------------ Assistant registers ------------- */
+#define REGPACK_REGBASE 0xB1400000
+#define XPORT_CAB0_WP               (REGPACK_REGBASE+0x0410)
+#define XPORT_CAB1_WP               (REGPACK_REGBASE+0x0418)
+#define CSM1800_XPORT_CAB_TOGGLEBIT (0x80000000)
+
+#define ID_SCS_BASE                 (0xB2100000)
+#define ID_SCS_SOFT_RESET           (ID_SCS_BASE + 0x200)
+#define Audio_rst_bit               0x8
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/celestial/audio/cnc1900_audio.c linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/audio/cnc1900_audio.c
--- linux-linaro-3.4-2012.05-1_original/drivers/celestial/audio/cnc1900_audio.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/audio/cnc1900_audio.c	2015-05-21 18:59:42.256307000 +0800
@@ -0,0 +1,902 @@
+/****************************************************************************
+  * Copyright (C) 2008-2010 Celestial Semiconductor Inc.
+  * All rights reserved
+  *
+  * [RELEASE HISTORY]
+  * VERSION  DATE       AUTHOR                  DESCRIPTION
+  * 0.1      10-03-30       Jia Ma           		Original
+  ****************************************************************************
+*/
+
+#include <linux/device.h>
+#include <linux/types.h>
+#include <linux/fs.h>
+#include <linux/delay.h>
+#include <linux/miscdevice.h>
+#include <linux/proc_fs.h>
+#include <linux/delay.h>
+#include <linux/firmware.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/poll.h>
+#include <linux/sched.h>
+#include <linux/export.h>
+#include <linux/module.h>
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+
+#include <mach/cnc1900.h>
+#include <mach/cnc1900_power_clk.h>
+#include "../xport/xport_drv1900.h"
+#include "audio_reg_def.h"
+#include "cnc1900_audio.h"
+#ifdef CONFIG_SW_SUPPORT
+#include <mach/smc.h>
+#endif
+
+typedef enum _UART_ID_
+{
+	_uart_0 	=0,
+	_uart_1		=1,
+	_uart_2		=2,
+	_uart_audio	=3,
+	_uart_video	=4,
+}UART_ID;
+
+#ifdef CONFIG_CELESTIAL_AUDIO_DEBUG
+#define DEBUG_PRINTF  printk
+#else
+#define DEBUG_PRINTF(fmt,args...)
+#endif
+extern int pinmux_enable_uart(UART_ID UART);
+extern void clock_audio_setclock(AUDIO_CLOCK_MODE AudioClockMode);
+
+static struct platform_device *audio_pdev;
+static const struct firmware* audio_data_fw=(struct firmware*)NULL;
+static const struct firmware* audio_text_fw=(struct firmware*)NULL;
+static const struct firmware* audio_ext_fw=(struct firmware*)NULL;
+
+volatile unsigned char *audmcu_base = NULL;
+volatile unsigned char *cnc_audio_reg_base = NULL;
+
+#ifdef CONFIG_SW_SUPPORT
+void audio_writel(unsigned int a, unsigned int val){
+	a = (a)&0xfffff; 
+	sw_smc(SMC_CMD_AUDIO_WIRTE_REG, a, val, 0x0);
+}
+
+unsigned int audio_readl(unsigned int a){
+	a = (a)&0xfffff;
+	return sw_smc(SMC_CMD_AUDIO_READ_REG, a, 0x0, 0x0);
+}
+#else
+#define audio_writel(a,v)	writel(v,(cnc_audio_reg_base+((a)&0xfffff)))
+#define audio_readl(a)	readl(cnc_audio_reg_base+((a)&0xfffff))
+#endif
+
+unsigned int irq_audio_samplerate_change = 0;
+AUDIO_CLOCK_MODE audio_clock_mode = _AUDIO_48KHz;
+
+//static int process_num = 0;
+typedef struct CSM1800_AUDIO_DEV_t {
+	int instance_num;
+} csm1800_audio_dev;
+
+DEFINE_SPINLOCK(cnc_audio_lock);
+DECLARE_WAIT_QUEUE_HEAD(audio_notify_queue);
+//static DECLARE_WAIT_QUEUE_HEAD(cnc_audio_queue);
+//static DEFINE_SPINLOCK(cnc_audio_queue_lock);
+
+void set_up_internal_dac(void)
+{
+	int i = 0;
+	unsigned int s_pop = 2;
+	//rstdacdpz set to 0
+	audio_writel(CNC1900_AUD_DAC_RESET_ADDR , 0x0);
+
+	audio_writel(CNC1900_AUD_DAC_LATCH_ADDR , 0x1);
+	audio_writel(CNC1900_AUD_DAC_LATCH_ADDR , 0x0);
+	msleep(10);
+	//rstdacdpz set to 0
+	audio_writel(CNC1900_AUD_DAC_RESET_ADDR, 0x1);
+	audio_writel(CNC1900_AUD_DAC_LATCH_ADDR, 0x1);
+	audio_writel(CNC1900_AUD_DAC_LATCH_ADDR, 0x0);
+	// open dac sub-module
+	audio_writel(CNC1900_AUD_DAC_POWER_CONTROL3_ADDR , 0xc3);
+
+	//set pop suppression
+	audio_writel(CNC1900_AUD_DAC_POP_SUPPRESSION_1 , 0x03);
+	audio_writel(CNC1900_AUD_DAC_POP_SUPPRESSION_2 , s_pop_mode[s_pop]);
+	for(i=0;i<32;i++)
+	{
+		audio_writel(CNC1900_AUD_DAC_POP_SUPPRESSION_SEG_START+i*4,s_pop_para[s_pop][i]);
+	}
+	//i2s mode
+	audio_writel(CNC1900_AUD_DAC_I2SMSMODE_ADDR , 0x1);//Sleep(100);
+
+	//pdz
+	audio_writel(CNC1900_AUD_DAC_POWER_CONSUMPTION ,0xB);
+	audio_writel(CNC1900_AUD_DAC_LATCH_ADDR , 0x1);
+	audio_writel(CNC1900_AUD_DAC_LATCH_ADDR , 0x0);
+	msleep(10);
+	audio_writel(CNC1900_AUD_DAC_POWER_CONTROL0_ADDR , 0x1);//Sleep(100);
+	audio_writel(CNC1900_AUD_DAC_LATCH_ADDR , 0x1);
+	audio_writel(CNC1900_AUD_DAC_LATCH_ADDR , 0x0);
+	msleep(10);
+	audio_writel(CNC1900_AUD_DAC_POWER_CONSUMPTION ,0x5);
+	audio_writel(CNC1900_AUD_DAC_LATCH_ADDR , 0x1);
+	audio_writel(CNC1900_AUD_DAC_LATCH_ADDR , 0x0);
+}
+
+typedef enum _BIT_CMD_STATE
+{
+	DRV_NO_CMD = 0,
+	DRV_NEW_CMD = 1,
+}eBIT_CMD_STATE;
+
+#define INIT_TRIGGER_BIT        0x1
+#define INIT_TYPE_MASK_OFFSET   0x0
+#define INIT_TYPE_MASK_WIDTH    0x6
+#define INIT_TYPE_MASK          (((1<<INIT_TYPE_MASK_WIDTH)-1) << INIT_TYPE_MASK_OFFSET)
+
+#define MUTE_TRIGGER_BIT	    0x2
+#define MUTE_MASK_OFFSET	    (INIT_TYPE_MASK_OFFSET + INIT_TYPE_MASK_WIDTH)
+#define MUTE_MASK_WIDTH         0x1
+#define MUTE_MASK			    (((1<<MUTE_MASK_WIDTH)-1) << MUTE_MASK_OFFSET)
+
+#define VOLUME_TRIGGER_BIT	    0x4
+#define VOLUME_MASK_OFFSET	    (MUTE_MASK_OFFSET + MUTE_MASK_WIDTH)
+#define VOLUME_MASK_WIDTH       0x7
+#define VOLUME_MASK			    (((1<<VOLUME_MASK_WIDTH)-1) << VOLUME_MASK_OFFSET)
+
+#define RUN_STATE_TRIGGER_BIT   0x8
+#define RUN_STATE_MASK_OFFSET   (VOLUME_MASK_OFFSET + VOLUME_MASK_WIDTH)
+#define RUN_STATE_MASK_WIDTH    0x2
+#define RUN_STATE_MASK          (((1<<RUN_STATE_MASK_WIDTH)-1) << RUN_STATE_MASK_OFFSET)
+
+typedef enum{
+	CMD_STOP = 0,   // set by playmode trigger.
+	CMD_PLAY = 1,   // set by playmode trigger.
+	CMD_PAUSE = 2,  // set by playmode trigger.
+	CMD_RESUME = 3, // set by playmode trigger.
+
+	CMD_INIT = 4,   // got by init trigger.
+	CMD_IDLE = 5,   // set by audio firmware.
+}eDRIVER_CODER_STATE;
+
+/*
+    register driver bit position
+*/
+#define TOP_INFO_WIDTH 4
+#define TOP_INFO_MASK 0xf
+
+/* mailbox2 */
+#define TOP_INUSE_BIT_OFFSET    0
+//#define TOP_HOST_LOCK_BIT_OFFSET     1
+#define TOP_NEWCMD_BIT_OFFSET   2
+
+unsigned int *audio_handshake_addr;
+static int try_lock_host_driver(int channel, int wait_times)
+{
+	unsigned int holock = audio_readl(CSM1800_AUD_MAILBOX0);
+	unsigned int mask = 1 << channel;;
+
+	/* wait fw until unlock */
+	while(audio_readl(CSM1800_AUD_MAILBOX1) & (1 << channel)){
+		wait_times--;
+		udelay(500);
+		if (wait_times <= 0){
+			return -1;
+		}
+	}
+
+	/* lock host driver */
+	audio_writel(CSM1800_AUD_MAILBOX0, holock | mask);
+
+	/* wait fw lock until unlock */
+	if (audio_readl(CSM1800_AUD_MAILBOX1) & (1 << channel)){
+		/* release host driver */
+		holock = audio_readl(CSM1800_AUD_MAILBOX0);
+		mask = 1 << channel;
+		mask = ~mask;
+		audio_writel(CSM1800_AUD_MAILBOX0, holock & mask);
+		return -1;
+	}
+
+	return 0;
+}
+
+static void get_driver_cmd(int channel, unsigned int *trigger, unsigned int which_trigger, unsigned int *status,unsigned int which_status)
+{
+	if (-1 == try_lock_host_driver(channel, 1000)){
+		printk("%s : %s in line %d\n",__FILE__,__FUNCTION__,__LINE__);
+		udelay(10);
+	}
+
+	*trigger = *(audio_handshake_addr + channel*8 + which_trigger);
+	*status = *(audio_handshake_addr + channel*8 + 1 + which_status);
+
+	return;
+}
+
+static void send_driver_cmd(int channel, unsigned int trigger, unsigned int which_trigger, unsigned int status, unsigned int which_status)
+{
+	unsigned int holock = audio_readl(CSM1800_AUD_MAILBOX0);
+	unsigned int mask = 1 << channel;
+	unsigned int top_cmd;
+
+	/* write host to fw driver information*/
+	*(audio_handshake_addr + channel*8 + which_trigger) = trigger;
+	*(audio_handshake_addr + channel*8 + 1 + which_status) = status;
+
+	/* write new command */
+	top_cmd = audio_readl(CSM1800_AUD_MAILBOX2);
+	top_cmd = top_cmd | (DRV_NEW_CMD<<(TOP_NEWCMD_BIT_OFFSET+channel*TOP_INFO_WIDTH));
+	audio_writel(CSM1800_AUD_MAILBOX2, top_cmd);
+
+	/* release host driver */
+	holock = audio_readl(CSM1800_AUD_MAILBOX0);
+	mask = 1 << channel;
+	mask = ~mask;
+	audio_writel(CSM1800_AUD_MAILBOX0, holock & mask);
+
+	return;
+}
+
+static void cnc_audio_send_stop_cmd(int channel)
+{
+	unsigned int trigger, status, counter = 0;
+
+	printk(KERN_DEBUG "1audio channel = %d, trigger = 0x%x, status= 0x%x\n", channel, *(audio_handshake_addr + channel*8), *(audio_handshake_addr + channel*8+2));
+	get_driver_cmd(channel, &trigger, 0, &status, 1);
+	printk(KERN_DEBUG "2audio channel = %d, trigger = 0x%x, status= 0x%x\n", channel,*(audio_handshake_addr + channel*8), *(audio_handshake_addr + channel*8+2));
+
+	trigger = trigger | RUN_STATE_TRIGGER_BIT;
+	status = (status & (~RUN_STATE_MASK)) | (CMD_STOP<< RUN_STATE_MASK_OFFSET);
+
+	send_driver_cmd(channel, trigger, 0, status, 1);
+	printk(KERN_DEBUG "3audio channel = %d, trigger = 0x%x, status= 0x%x\n", channel,*(audio_handshake_addr + channel*8), *(audio_handshake_addr + channel*8+2));
+
+	while((*(audio_handshake_addr + channel*8))&RUN_STATE_TRIGGER_BIT){
+		if(counter > 200){
+			printk(KERN_DEBUG "4audio channel = %d, trigger = 0x%x, status= 0x%x\n", channel,*(audio_handshake_addr + channel*8), *(audio_handshake_addr + channel*8+2));
+
+			printk("%s : %s in line %d\n",__FILE__,__FUNCTION__,__LINE__);
+			break;
+		}
+		counter ++;
+		udelay(500);
+	}
+
+	return;
+}
+
+static void __load_audio_firmware(volatile unsigned char *pDst, unsigned char *pSrc, int len_in_byte)
+{
+	unsigned long tmp_val;
+	volatile unsigned long *tcm_addr = (volatile unsigned long*)pDst;
+	int tcm_wr_size = len_in_byte>>2;
+
+	while(tcm_wr_size-- > 0) {
+		tmp_val  = (unsigned long)(*pSrc++);
+		tmp_val |= (unsigned long)(*pSrc++) << 8;
+		tmp_val |= (unsigned long)(*pSrc++) << 16;
+		tmp_val |= (unsigned long)(*pSrc++) << 24;
+
+		*tcm_addr++ = tmp_val;
+	}
+//	memcpy((unsigned char *)pDst, pSrc, len_in_byte);
+	return;
+}
+
+static void audio_load_firmware(void)
+{
+
+	/************* load 32K to ICACHE *************/
+	__load_audio_firmware(cnc_audio_reg_base+(CSM1800_AUD_ICACHE_BASE&0xfffff), (unsigned char *)audio_text_fw->data, 0x8000);
+
+	/************* load text to DDR ****************/
+	__load_audio_firmware(audmcu_base+AUDIO_INS_OFFSET, (unsigned char *)audio_text_fw->data, audio_text_fw->size);
+
+	/************* load data to DCACHE ************/
+	__load_audio_firmware(cnc_audio_reg_base+(CSM1800_AUD_DSRAM_BASE&0xfffff) , (unsigned char *)audio_data_fw->data, audio_data_fw->size);
+
+	/************* load ext data to DDR ************/
+	__load_audio_firmware(audmcu_base + AUDIO_DATA_OFFSET, (unsigned char *)audio_ext_fw->data, audio_ext_fw->size);
+
+	audio_writel(CSM1800_AUD_MAILBOX5, AUDIO_DATA_REGION);
+
+	return;
+}
+
+void audio_fw_reset(void)
+{
+#if 1
+	// Base on 1800L datasheet, I change the reset sequence below.
+	audio_writel(CSM1800_RISC_IO_PROT, 0x0);
+	while(audio_readl(CSM1800_RISC_IO_PROT) & 0x100);
+	audio_writel(CSM1800_AUDIO_RISC_CTRL, 1<<25);
+	audio_load_firmware();
+	audio_writel(CSM1800_RISC_IO_PROT, 1);
+#else
+	/************** risc stop **************/
+	/* Due to that only two way mips access ddr, instruction cache and dma, which can't be stop by audio risc_ctrl*/
+	audio_writel(CSM1800_AUDIO_RISC_CTRL, 1<<25);
+	/* wait until cache and dma no action */
+	while(audio_readl(CSM1800_RISC_IO_PROT) & 0x100);
+	audio_writel(CSM1800_RISC_IO_PROT, 0x0);
+
+	/* place those two line here to wait the suspending caching finish, if not, it may damage firmware. */
+	/* because we "stop mips then wait io" in audio_mips_stop, so, this two line omitted */
+	//write_ahb32(CSM1300_RISC_IO_PROT, 1); // enable IO
+	//while(read_ahb32(CSM1300_RISC_IO_PROT) & 0x100);// Is it busy?
+//	printk(KERN_INFO "%s : %s in %d\n",__FILE__,__FUNCTION__,__LINE__);
+	audio_load_firmware();
+//	printk(KERN_INFO "%s : %s in %d\n",__FILE__,__FUNCTION__,__LINE__);
+	/*************** risc start **************/
+	audio_writel(CSM1800_RISC_IO_PROT, 1); // enable IO
+	//audio_writel(CSM1800_AUDIO_RISC_CTRL, 0 | (AUDIO_INS_REGION>>3)); // start
+#endif
+	return;
+}
+
+static inline void __kernel_load_audio_firmware(void)
+{
+	int ret;
+	if(audio_text_fw == NULL){
+		ret = request_firmware(&audio_text_fw, "audio_fw_text.bin", &(audio_pdev->dev));
+		if (unlikely(ret != 0 || audio_text_fw== NULL)) {
+			printk(KERN_ERR "Failed to load audio firmware code section 1\n");
+			return;
+		}
+		else{
+			if (unlikely(audio_text_fw->size > AUDIO_INS_SIZE)){
+					release_firmware(audio_text_fw);
+					audio_text_fw=NULL;
+					printk(KERN_ERR "Failed to load audio firmware code section 2\n");
+					return;
+			}
+			if(audio_text_fw!=NULL){
+				ret = request_firmware(&audio_data_fw, "audio_fw_data.bin", &(audio_pdev->dev));
+				if (unlikely(ret != 0 || audio_data_fw== NULL)) {
+					release_firmware(audio_text_fw);
+					audio_text_fw=NULL;
+					printk(KERN_ERR "Failed to load audio firmware data section 1\n");
+					return;
+				}
+				else{
+					if (unlikely(audio_data_fw->size > AUDIO_DATA_SIZE)){
+				    		release_firmware(audio_data_fw);
+							audio_data_fw=NULL;
+							release_firmware(audio_text_fw);
+							audio_text_fw=NULL;
+							printk(KERN_ERR "Failed to load audio firmware data section 2\n");
+							return;
+					}
+				}
+			}
+		}
+
+		ret = request_firmware(&audio_ext_fw, "audio_fw_ext_data.bin", &(audio_pdev->dev));
+		if (unlikely(ret != 0 || audio_ext_fw== NULL)) {
+			printk(KERN_ERR "Failed to load audio external firmware 1\n");
+			return;
+		}
+		else{
+			if (unlikely(audio_ext_fw->size > AUDIO_DATA_SIZE)){
+					release_firmware(audio_ext_fw);
+					audio_ext_fw=NULL;
+					printk(KERN_ERR "Failed to load audio external firmware 2\n");
+					return;
+			}
+		}
+	}
+//	printk(KERN_INFO "%s : %s in %d\n",__FILE__,__FUNCTION__,__LINE__);
+	return;
+}
+
+unsigned int audio_irq_type = 0;
+#define AUDIO_IRQ_TYPE_SAMPLERATE_CHANGE 0x1
+
+static long cnc_audio_ioctl(struct file *file,unsigned int cmd, unsigned long arg)
+{
+	unsigned long flags;
+
+	switch (cmd) {
+		case CSAUD_IOC_GET_AUDIO_REG_ADDR:
+			spin_lock_irqsave(&cnc_audio_lock, flags);
+			__put_user(CSM_AUDIO_REG_BASE, (unsigned int __user *) arg);
+			spin_unlock_irqrestore(&cnc_audio_lock, flags);
+			break;
+		case CSAUD_IOC_GET_AUDIO_REG_SIZE:
+			spin_lock_irqsave(&cnc_audio_lock, flags);
+			__put_user(CSM_AUDIO_REG_SIZE, (unsigned int __user *) arg);
+			spin_unlock_irqrestore(&cnc_audio_lock, flags);
+			break;
+
+		case CSAUD_IOC_GET_AUDIO_NUM:
+ 			spin_lock_irqsave(&cnc_audio_lock, flags);
+			__put_user(AUDIO_NUM, (unsigned int __user *) arg);
+			spin_unlock_irqrestore(&cnc_audio_lock, flags);
+			break;
+		case CSAUD_IOC_GET_AUDIO_ENC_NUM:
+ 			spin_lock_irqsave(&cnc_audio_lock, flags);
+			__put_user(AUDIO_ENC_NUM, (unsigned int __user *) arg);
+			spin_unlock_irqrestore(&cnc_audio_lock, flags);
+			break;
+
+		case CSAUD_IOC_GET_AUDIO_CAB_ADDR:
+			spin_lock_irqsave(&cnc_audio_lock, flags);
+			__put_user(AUDIO_CAB_REGION, (unsigned int __user *) arg);
+			spin_unlock_irqrestore(&cnc_audio_lock, flags);
+			break;
+		case  CSAUD_IOC_GET_AUDIO_CAB_SIZE:
+			spin_lock_irqsave(&cnc_audio_lock, flags);
+			__put_user(AUDIO_CAB_SIZE, (unsigned int __user *) arg);
+			spin_unlock_irqrestore(&cnc_audio_lock, flags);
+			break;
+		case CSAUD_IOC_GET_AUDIO_PTS_ADDR:
+			spin_lock_irqsave(&cnc_audio_lock, flags);
+			__put_user(AUDIO_PTS_REGION, (unsigned int __user *) arg);
+			spin_unlock_irqrestore(&cnc_audio_lock, flags);
+			break;
+		case  CSAUD_IOC_GET_AUDIO_PTS_SIZE:
+			spin_lock_irqsave(&cnc_audio_lock, flags);
+			__put_user(AUDIO_PTS_SIZE, (unsigned int __user *) arg);
+			spin_unlock_irqrestore(&cnc_audio_lock, flags);
+			break;
+
+		case CSAUD_IOC_GET_AUDIO_AAB_ADDR:
+			spin_lock_irqsave(&cnc_audio_lock, flags);
+			__put_user(AUDIO_AAB_REGION, (unsigned int __user *) arg);
+			spin_unlock_irqrestore(&cnc_audio_lock, flags);
+			break;
+		case  CSAUD_IOC_GET_AUDIO_AAB_SIZE:
+			spin_lock_irqsave(&cnc_audio_lock, flags);
+			__put_user(AUDIO_AAB_SIZE, (unsigned int __user *) arg);
+			spin_unlock_irqrestore(&cnc_audio_lock, flags);
+			break;
+		case CSAUD_IOC_GET_AUDIO_AAB_PTS_ADDR:
+			spin_lock_irqsave(&cnc_audio_lock, flags);
+			__put_user(AUDIO_AAB_PTS_REGION, (unsigned int __user *) arg);
+			spin_unlock_irqrestore(&cnc_audio_lock, flags);
+			break;
+		case  CSAUD_IOC_GET_AUDIO_AAB_PTS_SIZE:
+			spin_lock_irqsave(&cnc_audio_lock, flags);
+			__put_user(AUDIO_AAB_PTS_SIZE, (unsigned int __user *) arg);
+			spin_unlock_irqrestore(&cnc_audio_lock, flags);
+			break;
+
+		case CSAUD_IOC_GET_AUDIO_ENC_CAB_ADDR:
+			spin_lock_irqsave(&cnc_audio_lock, flags);
+			__put_user(AUDIO_ENC_CAB_REGION, (unsigned int __user *) arg);
+			spin_unlock_irqrestore(&cnc_audio_lock, flags);
+			break;
+		case  CSAUD_IOC_GET_AUDIO_ENC_CAB_SIZE:
+			spin_lock_irqsave(&cnc_audio_lock, flags);
+			__put_user(AUDIO_ENC_CAB_SIZE, (unsigned int __user *) arg);
+			spin_unlock_irqrestore(&cnc_audio_lock, flags);
+			break;
+		case CSAUD_IOC_GET_AUDIO_ENC_PTS_ADDR:
+			spin_lock_irqsave(&cnc_audio_lock, flags);
+			__put_user(AUDIO_ENC_PTS_REGION, (unsigned int __user *) arg);
+			spin_unlock_irqrestore(&cnc_audio_lock, flags);
+			break;
+		case  CSAUD_IOC_GET_AUDIO_ENC_PTS_SIZE:
+			spin_lock_irqsave(&cnc_audio_lock, flags);
+			__put_user(AUDIO_ENC_PTS_SIZE, (unsigned int __user *) arg);
+			spin_unlock_irqrestore(&cnc_audio_lock, flags);
+			break;
+
+		case CSAUD_IOC_GET_AUDIO_HOST_IF_ADDR:
+			spin_lock_irqsave(&cnc_audio_lock, flags);
+			__put_user(AUDIO_HOST_FW_IF_REGION, (unsigned int __user *) arg);
+			spin_unlock_irqrestore(&cnc_audio_lock, flags);
+			break;
+		case CSAUD_IOC_GET_AUDIO_HOST_IF_SIZE:
+			spin_lock_irqsave(&cnc_audio_lock, flags);
+			__put_user(AUDIO_HOST_FW_IF_SIZE, (unsigned int __user *) arg);
+			spin_unlock_irqrestore(&cnc_audio_lock, flags);
+			break;
+		case CSAUD_IOC_GET_AUDIO_MIXER_ADDR:
+			spin_lock_irqsave(&cnc_audio_lock, flags);
+			__put_user(AUDIO_MIX_REGION, (unsigned int __user *) arg);
+			spin_unlock_irqrestore(&cnc_audio_lock, flags);
+			break;
+		case CSAUD_IOC_GET_AUDIO_MIXER_IF_SIZE:
+			spin_lock_irqsave(&cnc_audio_lock, flags);
+			__put_user(AUDIO_MIX_SIZE, (unsigned int __user *) arg);
+			spin_unlock_irqrestore(&cnc_audio_lock, flags);
+			break;
+		case CSAUD_IOC_GET_AUDIO_INS_ADDR	:
+			spin_lock_irqsave(&cnc_audio_lock, flags);
+			__put_user(AUDIO_INS_REGION, (unsigned int __user *) arg);
+			spin_unlock_irqrestore(&cnc_audio_lock, flags);
+			break;
+
+		case CSAUD_IOC_SET_SAMPLE_RATE:
+			spin_lock_irqsave(&cnc_audio_lock, flags);
+			clock_audio_setclock(arg);
+			spin_unlock_irqrestore(&cnc_audio_lock, flags);
+			break;
+
+		case CSAUD_IOC_GET_XPORT_AUDIO:
+			spin_lock_irqsave(&cnc_audio_lock, flags);
+			__put_user((MIPS_EXTERNAL_BASE_ADDR+512), (unsigned int __user *) arg);
+			spin_unlock_irqrestore(&cnc_audio_lock, flags);
+			break;
+
+		case CSAUD_IOC_GET_IRQ_TYPE:
+			spin_lock_irqsave(&cnc_audio_lock, flags);
+			__put_user(audio_irq_type, (unsigned int __user *) arg);
+			audio_irq_type = 0;
+			spin_unlock_irqrestore(&cnc_audio_lock, flags);
+			break;
+
+		case CSAUD_IOC_GET_SAMPLE_RATE:
+			spin_lock_irqsave(&cnc_audio_lock, flags);
+			__put_user(audio_clock_mode, (unsigned int __user *) arg);
+			spin_unlock_irqrestore(&cnc_audio_lock, flags);
+			break;
+
+		case CSAUD_IOC_ENA_AUDIO_DAC:
+ 			spin_lock_irqsave(&cnc_audio_lock, flags);
+#ifndef CONFIG_CELESTIAL_OTT_EMMC
+			audio_writel(CNC1900_AUD_DAC_SLEEPMODE, 0x0);
+#endif
+			spin_unlock_irqrestore(&cnc_audio_lock, flags);
+			break;
+		case CSAUD_IOC_DIS_AUDIO_DAC:
+ 			spin_lock_irqsave(&cnc_audio_lock, flags);
+			audio_writel(CNC1900_AUD_DAC_SLEEPMODE, 0x1);
+			spin_unlock_irqrestore(&cnc_audio_lock, flags);
+			break;
+		case CSAUD_IOC_RELOAD_FIRMWARE:
+			cnc_audio_send_stop_cmd(0);
+			cnc_audio_send_stop_cmd(1);
+			audio_writel(CSM1800_AUDIO_RISC_CTRL, 1<<25);
+			release_firmware(audio_text_fw);
+			audio_text_fw = NULL;
+			release_firmware(audio_data_fw);
+			audio_data_fw = NULL;
+			release_firmware(audio_ext_fw);
+			audio_ext_fw = NULL;
+			__kernel_load_audio_firmware();
+			audio_fw_reset();
+			break;
+
+		default:
+			return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int cnc_audio_proc_write(struct file *file, const char *buffer, unsigned long count, void *data)
+{
+	const char *cmd_line = buffer;;
+
+	if (strncmp("rl", cmd_line, 2) == 0) {
+		int addr;
+		addr = simple_strtol(&buffer[3], NULL, 16);
+		printk(" addr[0x%08x] = 0x%08x \n", addr, audio_readl(addr));
+	}
+	else if(strncmp("print", cmd_line, 5) == 0){
+		//pinmux_enable_uart(_uart_audio);
+	}
+
+	return count;
+}
+
+static int cnc_audio_open(struct inode *inode, struct file *file)
+{
+//	csm1800_audio_dev *audio_dev = NULL;
+
+	DEBUG_PRINTF("CSM AUDIO prepare open\n");
+#if 0
+	if(NULL == file->private_data){
+		printk("func:%s  line:%d \n",__FUNCTION__,__LINE__);
+		audio_dev = kmalloc(sizeof(csm1800_audio_dev), GFP_KERNEL);
+		if(NULL == audio_dev){
+			printk("func:%s  line:%d \n",__FUNCTION__,__LINE__);
+			return -EBUSY;
+		}
+		audio_dev->instance_num = 1;
+		file->private_data = (void *)audio_dev;
+		if(process_num > 0){
+			process_num ++;
+			goto CSM_AUDIO_OPEN_SUCCEED;
+		}
+		else{
+			process_num ++;
+		}
+	}
+	else{
+		audio_dev = file->private_data;
+		audio_dev->instance_num ++;
+		printk("func:%s  line:%d instance_num = %d\n",__FUNCTION__,__LINE__,audio_dev->instance_num);
+		goto CSM_AUDIO_OPEN_SUCCEED;
+	}
+#endif
+
+#ifndef CONFIG_SW_SUPPORT
+	__kernel_load_audio_firmware();
+	audio_fw_reset();
+	set_up_internal_dac();
+#endif
+
+	printk(KERN_INFO "CNC AUDIO has been opened\n");
+	return 0;
+}
+
+static int cnc_audio_release(struct inode *inode, struct file *file)
+{
+//	csm1800_audio_dev *audio_dev = NULL;
+	audio_handshake_addr = (unsigned int *)(audmcu_base + AUDIO_HOST_FW_IF_OFFSET);
+#if 0
+	audio_dev = file->private_data;
+	audio_dev->instance_num--;
+
+	if(audio_dev->instance_num > 0){
+		printk("func:%s  line:%d instance_num = %d, process_num = %d\n",__FUNCTION__,__LINE__,audio_dev->instance_num, process_num);
+		return 0;
+	}
+	else{
+		printk("func:%s  line:%d instance_num = %d, process_num = %d\n",__FUNCTION__,__LINE__,audio_dev->instance_num, process_num);
+		kfree(file->private_data);
+		process_num --;
+		if(process_num <= 0){
+			cnc_audio_send_stop_cmd(0);
+			cnc_audio_send_stop_cmd(1);
+
+			audio_writel(CSM1800_AUDIO_RISC_CTRL, 1<<25);
+			release_firmware(audio_text_fw);
+			audio_text_fw = NULL;
+			release_firmware(audio_data_fw);
+			audio_data_fw = NULL;
+			release_firmware(audio_ext_fw);
+			audio_ext_fw = NULL;
+		}
+	}
+#else
+			cnc_audio_send_stop_cmd(0);
+			cnc_audio_send_stop_cmd(1);
+#ifndef CONFIG_SW_SUPPORT
+			audio_writel(CSM1800_AUDIO_RISC_CTRL, 1<<25);
+#endif
+			if(NULL != audio_text_fw){	
+				release_firmware(audio_text_fw);
+				audio_text_fw = NULL;
+			}
+			if(NULL != audio_data_fw){
+				release_firmware(audio_data_fw);
+				audio_data_fw = NULL;
+			}
+			if(NULL != audio_ext_fw){
+				release_firmware(audio_ext_fw);
+				audio_ext_fw = NULL;
+			}
+#endif
+	printk(KERN_INFO "CNC AUDIO has been released\n");
+
+	return 0;
+}
+
+static unsigned int cnc_audio_poll(struct file *filp, poll_table * wait)
+{
+	unsigned int mask = 0;
+
+	if(irq_audio_samplerate_change){
+		mask = POLLIN | POLLWRNORM;
+		irq_audio_samplerate_change = 0;
+		return mask;
+	}
+	poll_wait(filp, &audio_notify_queue, wait);
+
+	return mask;
+}
+
+static struct class *cnc_audio_class;
+static struct proc_dir_entry *cnc_audio_proc_entry = NULL;
+static struct file_operations cnc_audio_fops = {
+	.owner	= THIS_MODULE,
+	.open	=  cnc_audio_open,
+	.release	= cnc_audio_release,
+	.unlocked_ioctl = cnc_audio_ioctl,
+	.poll 	= cnc_audio_poll,
+};
+static struct miscdevice csdrv_audio_miscdev = {
+	        MISC_DYNAMIC_MINOR,
+	        "cnc_audio",
+	        &cnc_audio_fops
+};
+
+#if 1
+#define AUD_SAMPLE_RATE_INT     		0xf0000002
+irqreturn_t cnc_audio_irq(int irq, void *dev_id)
+{
+	unsigned int flags;
+	unsigned long flags1;
+	unsigned int irq_reg;
+
+	irq_reg = audio_readl(CSM1800_AUD_MAILBOX4);
+	//printk(KERN_INFO "cnc_audio_irq : interrupt:  0x%x\n", irq_reg);
+	switch (irq_reg) {
+	case AUD_SAMPLE_RATE_INT:
+	{
+		flags = audio_readl(CSM1800_AUD_MAILBOX5);
+		printk(KERN_INFO "AUD_SAMPLE_RATE_INT:  0x%x\n", flags);
+
+		switch(flags){
+			case 192000:
+				audio_clock_mode = _AUDIO_192KHz;
+				break;
+			case 176400:
+				audio_clock_mode = _AUDIO_176KHZ;
+				break;
+			case 128000:
+				audio_clock_mode = _AUDIO_128KHZ;
+				break;
+			case 96000:
+				audio_clock_mode = _AUDIO_96KHz;
+				break;
+			case 88200:
+				audio_clock_mode = _AUDIO_88_2KHz;
+				break;
+			case 64000:
+				audio_clock_mode = _AUDIO_64KHz;
+				break;
+			case 48000:
+				audio_clock_mode = _AUDIO_48KHz;
+				break;
+			case 44100:
+				audio_clock_mode = _AUDIO_44_1KHz;
+				break;
+			case 32000:
+				audio_clock_mode = _AUDIO_32KHz;
+				break;
+			case 24000:
+				audio_clock_mode = _AUDIO_24KHz;
+				break;
+			case 22050:
+				audio_clock_mode = _AUDIO_22_05KHz;
+				break;
+			case 16000:
+				audio_clock_mode = _AUDIO_16KHz;
+				break;
+			case 12000:
+				audio_clock_mode = _AUDIO_12KHz;
+				break;
+			case 11025:
+				audio_clock_mode = _AUDIO_11_025KHz;
+				break;
+			case 8000:
+				audio_clock_mode = _AUDIO_8KHz;
+				break;
+			default:
+				audio_clock_mode = _AUDIO_48KHz;
+				break;
+		}
+		clock_audio_setclock(audio_clock_mode);
+		spin_lock_irqsave(&cnc_audio_lock, flags1);
+		irq_audio_samplerate_change = 1;
+		audio_irq_type|=AUDIO_IRQ_TYPE_SAMPLERATE_CHANGE;
+		wake_up(&audio_notify_queue);
+		spin_unlock_irqrestore(&cnc_audio_lock, flags1);
+
+		break;
+
+	}
+	default:
+		printk("interrupt: Unknow type 0x%x\n", irq_reg);
+		irq_reg = audio_readl(CSM1800_AUD_MAILBOX5);
+		printk("interrupt:  0x%x\n", irq_reg);
+		break;
+	}
+
+	irq_reg = audio_readl(CSM1800_AUD_INT);
+	audio_writel(CSM1800_AUD_INT, irq_reg & 0xfffffffe);
+
+	return IRQ_HANDLED;
+}
+#endif
+
+void __audio_mem_initialize(void)
+{
+    cnc_audio_reg_base = (volatile unsigned char *)IO_ADDRESS(CSM_AUDIO_REG_BASE);
+
+	if (!request_mem_region(AUDIO_STUFF_REGION, AUDIO_STUFF_SIZE, "MCU Audio"))
+		goto ERR_MEM1;
+
+	if (NULL == (audmcu_base = ioremap(AUDIO_STUFF_REGION, AUDIO_STUFF_SIZE)))
+		goto ERR_MEM2;
+	return;
+
+ERR_MEM2:
+	printk("%s: %s ERR_MEM4\n",__FILE__,__FUNCTION__);
+	release_mem_region(AUDIO_STUFF_REGION, AUDIO_STUFF_SIZE);
+ERR_MEM1:
+	printk("%s: %s ERR_MEM3\n",__FILE__,__FUNCTION__);
+
+	return;
+}
+
+void __audio_mem_destroy(void)
+{
+	iounmap((void *)audmcu_base);
+	release_mem_region(AUDIO_STUFF_REGION, AUDIO_STUFF_SIZE);
+}
+
+static int __init cnc_audio_init(void)
+{
+	int ret = 0;
+
+	ret = misc_register(&csdrv_audio_miscdev);
+	if(ret){
+		/* return if failure ... */
+		printk(KERN_INFO "Failed to register the cnc_audio misc device\n");
+		return ret;
+	}
+
+	audio_pdev = platform_device_register_simple("audio_device", 0, NULL, 0);
+    	if (IS_ERR(audio_pdev)) {
+        	return -ENODEV;
+    	}
+
+	cnc_audio_class = class_create(THIS_MODULE,"cnc_audio");
+	if (IS_ERR(cnc_audio_class)){
+		printk(KERN_ERR "AUDIO: class create failed.\n");
+		__audio_mem_destroy();
+		cnc_audio_class = NULL;
+		return -ENODEV;
+	}
+
+	cnc_audio_proc_entry = create_proc_entry("audio_io", 0, NULL);
+	if (NULL != cnc_audio_proc_entry) {
+		cnc_audio_proc_entry->write_proc = &cnc_audio_proc_write;
+	}
+
+	__audio_mem_initialize();
+
+	clock_audio_enaclock(_clock_enable);
+	clock_audiopll_enaclock(_clock_enable);
+
+#if 1
+	if (request_irq(AUDIO_IRQ, cnc_audio_irq,IRQF_DISABLED | IRQF_TRIGGER_HIGH, "cs_audio", NULL)) {
+		printk(KERN_ERR "csdrv_aud: cannot register IRQ \n");
+		return -EIO;
+	}
+#endif
+
+	printk("CNC1900 Audio System Version : 0.2 @\n");
+
+	printk(KERN_INFO "%s: CNC Audio driver was initialized, at address@[phyical addr = %08x, size = %x] \n",
+		"cnc1900_audio", CSM_AUDIO_REG_BASE, CSM_AUDIO_REG_SIZE);
+	printk(KERN_INFO "%s: CNC Audio stuff at address@[phyical addr = %08x, size = %x] \n",
+		"cn1900_audio", AUDIO_STUFF_REGION, AUDIO_STUFF_SIZE);
+	printk("AUDIO_DEBUG_REGION 0x%x, AUDIO_DEBUG_SIZE = 0x%x\n",AUDIO_DEBUG_REGION, AUDIO_DEBUG_SIZE);
+	return 0;
+}
+
+static void __exit cnc_audio_exit(void)
+{
+	__audio_mem_destroy();
+
+	if (NULL != cnc_audio_proc_entry)
+		remove_proc_entry("audio_io", NULL);
+
+	class_destroy(cnc_audio_class);
+	unregister_chrdev(AUDIO_MAJOR, "cnc_audio");
+
+	printk(KERN_INFO " CNC AUDIO Exit ...... OK. \n");
+
+	return;
+}
+
+module_init(cnc_audio_init);
+module_exit(cnc_audio_exit);
+
+MODULE_AUTHOR("<jia.ma@caviumnetworks.com>");
+MODULE_DESCRIPTION("Cavium Audio sub-system");
+MODULE_LICENSE("GPL");
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/celestial/audio/cnc1900_audio.h linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/audio/cnc1900_audio.h
--- linux-linaro-3.4-2012.05-1_original/drivers/celestial/audio/cnc1900_audio.h	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/audio/cnc1900_audio.h	2015-06-19 15:58:42.412211000 +0800
@@ -0,0 +1,101 @@
+#ifndef __CNC1900_AUDIO_H__
+#define __CNC1900_AUDIO_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define AUDIO_MAJOR 400
+
+#ifdef CONFIG_SW_SUPPORT
+#undef CONFIG_SW_SUPPORT
+#endif
+
+#ifdef CONFIG_SW_SUPPORT
+#define AUDIO_INS_REGION	AUDIO_STUFF_REGION
+#define AUDIO_INS_SIZE (0x0)
+#define AUDIO_DATA_REGION	(AUDIO_INS_REGION + AUDIO_INS_SIZE)
+#define AUDIO_DATA_SIZE	(0x0)
+#define AUDIO_HOST_FW_IF_REGION	(AUDIO_DATA_REGION + AUDIO_DATA_SIZE)
+#define AUDIO_HOST_FW_IF_SIZE	(AUDIO_STUFF_SIZE - AUDIO_INS_SIZE - AUDIO_DATA_SIZE) /* AUDIO_HOST_FW_IF_SIZE + AUDIO pointer*/
+
+#define AUDIO_INS_OFFSET	(AUDIO_INS_REGION - AUDIO_STUFF_REGION)
+#define AUDIO_DATA_OFFSET	(AUDIO_DATA_REGION - AUDIO_STUFF_REGION)
+#define AUDIO_HOST_FW_IF_OFFSET	(AUDIO_HOST_FW_IF_REGION - AUDIO_STUFF_REGION)
+#else
+#define AUDIO_INS_REGION	AUDIO_STUFF_REGION
+#define AUDIO_INS_SIZE (0xf0000)
+#define AUDIO_DATA_REGION	(AUDIO_INS_REGION + AUDIO_INS_SIZE)
+#define AUDIO_DATA_SIZE	(0x180000)
+#define AUDIO_HOST_FW_IF_REGION	(AUDIO_DATA_REGION + AUDIO_DATA_SIZE)
+#define AUDIO_HOST_FW_IF_SIZE	(AUDIO_STUFF_SIZE - AUDIO_INS_SIZE - AUDIO_DATA_SIZE) /* AUDIO_HOST_FW_IF_SIZE + AUDIO pointer*/
+
+#define AUDIO_INS_OFFSET	(AUDIO_INS_REGION - AUDIO_STUFF_REGION)
+#define AUDIO_DATA_OFFSET	(AUDIO_DATA_REGION - AUDIO_STUFF_REGION)
+#define AUDIO_HOST_FW_IF_OFFSET	(AUDIO_HOST_FW_IF_REGION - AUDIO_STUFF_REGION)
+#endif
+#define CSAUD_IOC_GET_AUDIO_REG_ADDR	    _IOR('a', 0x01, int)
+#define CSAUD_IOC_GET_AUDIO_REG_SIZE		_IOR('a', 0x02, int)
+
+#define CSAUD_IOC_GET_AUDIO_HOST_IF_ADDR	_IOR('a', 0x03, int)
+#define CSAUD_IOC_GET_AUDIO_HOST_IF_SIZE	_IOR('a', 0x04, int)
+
+#define CSAUD_IOC_GET_AUDIO_NUM		        _IOR('a', 0x05, int)
+#define CSAUD_IOC_GET_AUDIO_ENC_NUM         _IOR('a', 0x06, int)
+#define	CSAUD_IOC_GET_AUDIO_CAB_ADDR        _IOR('a', 0x07, int)
+#define	CSAUD_IOC_GET_AUDIO_CAB_SIZE        _IOR('a', 0x08, int)
+#define	CSAUD_IOC_GET_AUDIO_PTS_ADDR        _IOR('a', 0x09, int)
+#define	CSAUD_IOC_GET_AUDIO_PTS_SIZE        _IOR('a', 0x0a, int)
+#define	CSAUD_IOC_GET_AUDIO_AAB_ADDR        _IOR('a', 0x0b, int)
+#define	CSAUD_IOC_GET_AUDIO_AAB_SIZE        _IOR('a', 0x0c, int)
+#define	CSAUD_IOC_GET_AUDIO_AAB_PTS_ADDR    _IOR('a', 0x0d, int)
+#define	CSAUD_IOC_GET_AUDIO_AAB_PTS_SIZE    _IOR('a', 0x0e, int)
+#define	CSAUD_IOC_GET_AUDIO_ENC_CAB_ADDR    _IOR('a', 0x0f, int)
+#define	CSAUD_IOC_GET_AUDIO_ENC_CAB_SIZE    _IOR('a', 0x10, int)
+#define	CSAUD_IOC_GET_AUDIO_ENC_PTS_ADDR    _IOR('a', 0x11, int)
+#define	CSAUD_IOC_GET_AUDIO_ENC_PTS_SIZE    _IOR('a', 0x12, int)
+
+
+
+#define CSAUD_IOC_GET_AUDIO_MIXER_ADDR	    _IOR('a', 0x13, int)
+#define CSAUD_IOC_GET_AUDIO_MIXER_IF_SIZE	_IOR('a', 0x14, int)
+#define CSAUD_IOC_GET_AUDIO_INS_ADDR		_IOR('a', 0x15, int)
+
+#define CSAUD_IOC_GET_XPORT_AUDIO	        _IOR('a', 0x16, int)
+#define CSAUD_IOC_GET_IRQ_TYPE		        _IOR('a', 0x17, int)
+
+#define CSAUD_IOC_GET_AUDIO_PROCESS_NUMBER  _IOR('a', 0x18, int)
+
+#define CSAUD_IOC_GET_SAMPLE_RATE		    _IOR('a', 0x19, int)
+#define CSAUD_IOC_SET_SAMPLE_RATE	        _IOW('a', 0x1a, int)
+
+#define CSAUD_IOC_ENA_AUDIO_DAC             _IOW('a', 0x1b, int)
+#define CSAUD_IOC_DIS_AUDIO_DAC             _IOW('a', 0x1c, int)
+
+#define CSAUD_IOC_RELOAD_FIRMWARE		    _IOW('a', 0x1d, int)
+
+typedef enum{
+	AUDIO_TYPE_MPA = 0,
+	AUDIO_TYPE_AC3 = 1,
+	AUDIO_TYPE_DTS = 2,
+	AUDIO_TYPE_LPCM = 3,
+	AUDIO_TYPE_AAC_ADTS = 4,
+	AUDIO_TYPE_AAC_LATM = 5,
+	AUDIO_TYPE_AIB = 6,
+	AUDIO_TYPE_UNKNOWN = 7,  // 5 bit
+}AUDIO_TYPE_e;
+
+unsigned int s_pop_mode[3] = {0x53,0xb3,0xf3};
+unsigned int s_pop_para[3][32] =
+	{	 // 1                                        9                                      17                                      25                                 32
+		  {0x01,0x2c,0x53,0x30,0x00,0x34,0x00,0x38,0x7f,0x3c,0x49,0x3c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+		  {0x00,0x10,0x00,0x18,0x00,0x20,0x00,0x28,0x7f,0x2c,0x7f,0x2c,0x3f,0x2c,0x71,0x30,0x00,0x34,0x00,0x38,0x7f,0x3c,0x1f,0x3c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+		  {0x00,0x00,0x01,0x08,0x00,0x0c,0x00,0x10,0x01,0x18,0x02,0x20,0x7f,0x28,0x7f,0x28,0x40,0x28,0x7f,0x2c,0x7f,0x2c,0x7f,0x2c,0x7f,0x30,0x7f,0x34,0x7f,0x3c,0x65,0x3c}
+	};
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/celestial/audio/Kconfig linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/audio/Kconfig
--- linux-linaro-3.4-2012.05-1_original/drivers/celestial/audio/Kconfig	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/audio/Kconfig	2014-08-19 17:41:23.254284000 +0800
@@ -0,0 +1,89 @@
+# drivers/celestial/audio/Kconfig
+
+menu "Celestial Audio Drivers"
+
+config CELESTIAL_AUDIO
+	bool "CNC1900 Audio"
+	depends on ARCH_CELESTIAL
+	default y
+	help 
+	    Include support drvier for Audio of celestial platform
+
+config AUDIO_DECODER
+	bool "Audio Decoder"
+	depends on CELESTIAL_AUDIO
+	default y
+	help 
+	    Enable Audio Decoder.Some projects no need to decoder audio date. It can be disabled for saving memory
+	    
+config AUDIO_ENCODER
+	bool "Audio Encoder"
+	depends on CELESTIAL_AUDIO
+	default y
+	help 
+	    Enable Audio Encoder.Some projects no need to encoder audio date. It can be disabled for saving memory
+
+config AUDIO_AAB
+	bool "Audio AAB"
+	depends on CELESTIAL_AUDIO
+	default y
+	help
+	    PCM audio buffer size for Dolby.Size 0x500000. 
+
+config AUDIO_NUM
+	int "Audio Decoder Number"
+	depends on AUDIO_DECODER
+	range 1 8
+	default 1
+	help
+	    Number of audio supported by audio decoder. Range from 1 to 8.
+
+config AUDIO_CAB_SIZE
+	hex "Audio Decoder CAB Size"
+	depends on AUDIO_DECODER
+	range 0x0 0x400000
+	default 0x200000
+	help
+	    Compressed audio buffer size for one audio. Range from 0x18000 to 0x400000.
+
+config AUDIO_ENC_NUM
+	int "Audio Encoder Number"
+	depends on AUDIO_ENCODER
+	range 1 8
+	default 1
+	help
+	    Number of audio supported by audio decoder. Range from 1 to 8.
+
+config AUDIO_ENC_CAB_SIZE
+	hex "Audio Encoder CAB Size"
+	depends on AUDIO_ENCODER
+	range 0x18000 0x400000
+	default 0x200000
+	help
+	    Compressed audio buffer size for one audio. Range from 0x18000 to 0x400000.
+
+
+config CELESTIAL_AUDIO_DEBUG
+	bool "Audio Debugging"
+	depends on CELESTIAL_AUDIO
+	help
+	    This turns on low-level debugging for the celestial audio driver.
+	    Normally, you should say 'N'.
+
+config AUDIO_DEBUG_VERBOSE
+	int "Audio Debugging verbosity (0 = quiet, 3 = noisy)"
+	depends on CELESTIAL_AUDIO_DEBUG
+	default "0"
+	help
+	    Determines the verbosity level of the audio debugging messages.
+
+config AUDIO_FW_DUMP_DEBUG
+        bool "Audio fw dump Debugging"
+        depends on CELESTIAL_AUDIO
+        default n
+        help
+            This turns on fw dump data debugging for the celestial audio driver.
+            It will occupy 5MB memory.
+            Normally, you should say 'N'.
+
+endmenu
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/celestial/audio/Makefile linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/audio/Makefile
--- linux-linaro-3.4-2012.05-1_original/drivers/celestial/audio/Makefile	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/audio/Makefile	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,9 @@
+#
+# Makefile for the linux kernel.
+# 
+#
+
+obj-$(CONFIG_MACH_CELESTIALSEMI_CSM1201) += 
+obj-$(CONFIG_MACH_CELESTIALSEMI_CSM1800H) += csm1800_audio.o
+obj-$(CONFIG_MACH_CELESTIAL_CNC1900) += cnc1900_audio.o
+
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/celestial/df/cnc1900_df.c linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/df/cnc1900_df.c
--- linux-linaro-3.4-2012.05-1_original/drivers/celestial/df/cnc1900_df.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/df/cnc1900_df.c	2015-04-15 17:25:10.999290000 +0800
@@ -0,0 +1,2643 @@
+#include <linux/device.h>
+#include <linux/types.h>
+#include <linux/fs.h>
+#include <linux/delay.h>
+#include <linux/miscdevice.h>
+#include <linux/proc_fs.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/fb.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <mach/pinmux.h>
+#include <mach/cnc1900_vpp_reg_def.h>
+#include <mach/cnc1900_df.h>
+#include <mach/cnc1900_power_clk.h>
+#include <mach/cnc1900_scalor_coef.h>
+#include <mach/mem_define.h>
+
+#include "tve0_1900.h"
+#include "tve1_1900.h"
+#include "df_output_format.h"
+//#include "../video/video_handshake_def.h"
+//#include "../video/cnc1900_video.h"
+//#include "../video/video_reg_def_cnc1900.h"
+
+#define DF_IRQ_DEBUG (0)
+
+#ifdef CONFIG_CELESTIAL_DF_DEBUG
+#define DEBUG_PRINTF  printk
+#else
+#define DEBUG_PRINTF(fmt,args...)
+#endif
+
+#if DF_IRQ_DEBUG
+#define DF_IRQ_PRINTF printk
+#else
+#define DF_IRQ_PRINTF(fmt,args...)
+#endif
+
+#define DF_MAJOR			200
+
+#define DF_MINOR_GFX0		0
+#define DF_MINOR_GFX1		1
+#define DF_MINOR_VID0		2
+#define DF_MINOR_VID1		3
+#define DF_MINOR_OUT0		4
+#define DF_MINOR_OUT1		5
+#define DF_MINOR_TVE0		6
+#define DF_MINOR_TVE1		7
+#define DF_MINOR_VIDAUX	8
+
+#ifdef CONFIG_HD2SD_ENABLE
+int __Is_hd2sd = 1;
+#else
+int __Is_hd2sd = 0;
+#endif
+static int __Is_ColorBar = 0;
+static int __Is_first = 1;
+int __VGA_Support = 0;
+int __Is_TV = 1;
+
+static int _Is_interlace = 0;
+static unsigned int _Frame_rate = 3000;
+
+#if 1
+extern int outputmode;
+#else
+int outputmode = -1;
+#endif
+
+int hdcp_enabled = -1;
+EXPORT_SYMBOL(hdcp_enabled);
+static int __init root_hdcp_setup(char *str)
+{
+	hdcp_enabled = simple_strtoul(str, NULL, 0);
+	return 1;
+}
+
+__setup("hdcp=", root_hdcp_setup);
+
+//extern _HOST_FW_IF_t *host2videofw_if;
+//extern unsigned int __video_write(unsigned int val, unsigned int addr);
+//extern unsigned int __video_read(unsigned int addr);
+//extern unsigned int clock_read_fixme(unsigned int idcs_reg_addr);
+extern int __change_tg_request(unsigned int TgId);
+extern int __change_tg_release(unsigned int TgId);
+extern int __video_tve_2_tg(int layer);
+extern void __video_set_hd2sd(unsigned int tg1_width, unsigned int tg1_height, unsigned int tg2_width, unsigned int tg2_height);
+extern void __video_send_hd2sd_cmd(int cmd);
+extern void __video_set_layer_position(int layer, unsigned int w, unsigned int h, unsigned int is_interlace, unsigned int frame_rate);
+
+volatile unsigned char  *disp_base = NULL;
+volatile unsigned char  *tve0_base = NULL;
+volatile unsigned char  *tve1_base = NULL;
+
+static dfdev df_dev[9];
+static int tve_2_df[] = {
+	DISP_YUV_PAL,
+	DISP_YUV_NTSC,
+	DISP_YUV_576P,
+	DISP_YUV_480P,
+	DISP_YUV_720P_50FPS,
+	DISP_YUV_720P_60FPS,
+	DISP_YUV_1080I_25FPS,
+	DISP_YUV_1080I_30FPS,
+
+	DISP_YUV_PAL,
+	DISP_YUV_NTSC,
+	DISP_YUV_PAL,
+	DISP_YUV_PAL,
+	DISP_YUV_1080P_24FPS,
+	DISP_YUV_1080P_25FPS,
+	DISP_YUV_1080P_30FPS,
+	DISP_YUV_1080P_50FPS,
+	DISP_YUV_1080P_60FPS,
+
+	DISP_YUV_PAL,
+	DISP_YUV_NTSC,
+	DISP_YUV_NTSC,
+	DISP_YUV_NTSC,
+	DISP_YUV_576P,
+	DISP_YUV_480P,
+	DISP_YUV_480P,
+	DISP_YUV_480P,
+	DISP_YUV_720P_60FPS,
+	DISP_YUV_1080I_30FPS,
+	DISP_YUV_1080P_24FPS,
+	DISP_YUV_1080P_60FPS,
+
+	DISP_YUV_720P_60FPS_3D,
+	DISP_YUV_720P_60FPS_3D,
+	DISP_YUV_720P_50FPS_3D,
+	DISP_YUV_1080P_24FPS_3D,
+	DISP_YUV_1080P_24FPS_3D,
+
+	DISP_YUV_1080I_25FPS,
+	DISP_YUV_1080I_30FPS,
+	DISP_YUV_1080I_30FPS,
+
+	DISP_YUV_720P_50FPS,
+	DISP_YUV_720P_60FPS,
+	DISP_YUV_720P_60FPS,
+	DISP_YUV_1080P_24FPS,
+	DISP_YUV_1080P_24FPS,
+
+	DISP_RGB_VGA_60FPS,
+	DISP_RGB_CVT_800x600_60,
+	DISP_RGB_XGA_60FPS,
+	DISP_RGB_CVT_1280x720_60,
+	DISP_RGB_DMT_800x600_60,
+	DISP_RGB_DMT_1440x900_60,
+	DISP_RGB_DMT_1280x1024_60,
+	DISP_RGB_DMT_1360x768_60,
+	DISP_YUV_1080P_30FPS,
+	DISP_YUV_1080P_60FPS,
+	DISP_YUV_1080I_30FPS,
+	DISP_VGA_1366x768,
+	DISP_RGB_VGA_59P94FPS,
+	DISP_1600x1200_60FPS,
+};
+
+static int tve_2_clock[] = {
+	_YUV_PAL,
+	_YUV_480I_60Hz,
+	_YUV_576P_50Hz,
+	_YUV_480P_60Hz,
+	_YUV_720P_50Hz,
+	_YUV_720P_60Hz,
+	_YUV_1080I_50Hz,
+	_YUV_1080I_60Hz,
+
+	_YUV_PAL,
+	_YUV_NTSC,
+	_YUV_PAL,
+	_YUV_PAL,
+	_YUV_1080P_24Hz,
+	_YUV_1080P_25Hz,
+	_YUV_1080P_30Hz,
+	_YUV_1080P_50Hz,
+	_YUV_1080P_60Hz,
+
+	_YUV_PAL,
+	_YUV_NTSC,
+	_YUV_NTSC,
+	_YUV_480I_60Hz,
+	_YUV_576P_50Hz,
+	_YUV_480P_59p94Hz,
+	_YUV_480P_59p94Hz,
+	_YUV_480P_60Hz,
+	_YUV_720P_59p94Hz,
+	_YUV_1080I_59p94Hz,
+	_YUV_1080P_23p98Hz,
+	_YUV_1080P_59p94Hz,
+
+	_YUV_1080P_59p94Hz,
+	_YUV_1080P_60Hz,
+	_YUV_1080P_60Hz,
+	_YUV_1080P_59p94Hz,
+	_YUV_1080P_60Hz,
+
+	_YUV_1080I_50Hz,
+	_YUV_1080I_59p94Hz,
+	_YUV_1080I_60Hz,
+
+	_YUV_720P_50Hz,
+	_YUV_720P_59p94Hz,
+	_YUV_720P_60Hz,
+	_YUV_1080P_23p98Hz,
+	_YUV_1080P_24Hz,
+
+	_RGB_DMT_640x480_60Hz,
+	_RGB_DMT_800x600_60Hz,
+	_RGB_DMT_1024x768_60Hz,
+	_YUV_720P_60Hz,
+	_RGB_DMT_800x600_60Hz,
+	_RGB_DMT_1440x900_60Hz,
+	_RGB_DMT_1280x1024_60Hz,
+	_RGB_DMT_1360x768_60Hz,
+	_YUV_1080P_30Hz,
+	_YUV_1080P_60Hz,
+	_YUV_1080I_60Hz,
+	_RGB_DMT_1360x768_60Hz,
+	_RGB_DMT_640x480_59P94Hz,
+	_RGB_DMT_1600x1200_60Hz,
+};
+
+static int tve_2_clock1[]={
+	_YUV_PAL_disp1,
+	_YUV_NTSC_disp1,
+	_YUV_576P_50Hz_disp1,
+	_YUV_480P_60Hz_disp1,
+	-1,
+	-1,
+	-1,
+	-1,
+	_YUV_SECAM_disp1,
+	_YUV_PAL_M_disp1,
+	_YUV_PAL_N_disp1,
+	_YUV_PAL_CN_disp1,
+};
+
+DEFINE_SPINLOCK(cnc_df_lock);
+
+#define REG_MAP_ADDR(x)	(((((x)>>16)&0xffff) == 0xb180)  ? (disp_base+((x)&0xffff)) :  \
+		(((((x)>>12)&0xfffff) == 0x80160) ? (tve1_base+((x)&0xfff)) :      \
+		 ((((x)>>12)&0xfffff) == 0x80168) ? (tve0_base+((x)&0xfff)):0))
+
+#define df_write8(a,v)	writeb(v,REG_MAP_ADDR(a))
+#define df_write16(a,v)	writew(v,REG_MAP_ADDR(a))
+#define df_write(a,v)	writel(v,REG_MAP_ADDR(a))
+#define df_read8(a)	readb(REG_MAP_ADDR(a))
+#define df_read16(a)	readw(REG_MAP_ADDR(a))
+#define df_read(a)	readl(REG_MAP_ADDR(a))
+
+df_reg_para dfreg;
+
+#define USE_VIDEO_LAYER2 0
+
+DF_OUTPUT_CONFIG_t df_output_config = {
+	.gfx_output = {0,0},
+#if	USE_VIDEO_LAYER2
+	.vid_output = {0,0,1},
+#else
+	.vid_output = {0,1,0},
+#endif
+	.output_mode = {DF_OUTPUT_YPBPR, DF_OUTPUT_YPBPR},
+};
+
+typedef enum
+{
+    DF_ZORDER_G1_G2_V1_V2 = 0X2301, //<front to Back: gfx0, gfx1, video0, video1
+    DF_ZORDER_V1_V2_G1_G2 = 0X123,  //<front to Back: video0, video1, gfx0, gfx1
+    DF_ZORDER_G2_G1_V2_V1 = 0X3210, //<front to Back: gfx1, gfx0, video1, video0
+    DF_ZORDER_V2_V1_G2_G1 = 0X1032, //<front to Back: video1, video0, gfx1, gfx0
+    DF_ZORDER_G1_V1_G2_V2 = 0X1302, //<front to Back: gfx0, video0, gfx1, video1
+    DF_ZORDER_V2_G2_V1_G1 = 0X2031  //<front to Back: video1, gfx1, video0, gfx0
+} CSTVOUT_DF_ZORDER;
+
+unsigned int DF_Read(unsigned int addr)
+{
+	return df_read(addr);
+}
+EXPORT_SYMBOL(DF_Read);
+
+void DF_Write(unsigned int addr, unsigned int data)
+{
+	df_write(addr, data);
+	return;
+}
+EXPORT_SYMBOL(DF_Write);
+
+unsigned char TVE_Read(unsigned int tveid, unsigned int addr)
+{
+	unsigned int data_rd;
+	unsigned int addr_full;
+	unsigned int addr32;
+	unsigned int data32;
+
+	if(tveid == 0)
+		addr_full = TVE0_REG_BASE + addr;
+	else if(tveid == 1)
+		addr_full = TVE1_REG_BASE+addr;
+	else
+		return (-1);
+
+	addr32 = addr_full & (~3);
+	data32 = df_read(addr32);
+
+	switch(addr_full&0x3){
+	case 0x0:
+		data_rd = data32 & 0xFF;
+		break;
+	case 0x1:
+		data_rd =(data32>>8)&0xFF;
+		break;
+	case 0x2:
+		data_rd =(data32>>16)&0xFF;
+		break;
+	case 0x3:
+		data_rd =(data32>>24)&0xFF;
+		break;
+	default:
+		data_rd=0;
+	}
+	return (((unsigned char)data_rd) & 0xFF);
+}
+
+void TVE_Write(unsigned int tveid, unsigned int addr, unsigned char data)
+{
+	unsigned char data_rd;
+	unsigned int addr_full;
+	unsigned int addr32;
+	unsigned int data32;
+
+	if(tveid == 0)
+		addr_full = TVE0_REG_BASE + addr;
+	else if(tveid == 1)
+		addr_full = TVE1_REG_BASE + addr;
+	else
+		return;
+
+	addr32 = addr_full & (~3);
+	data32 = df_read(addr32);
+
+	switch(addr_full & 0x3)
+	{
+	case 0x0:
+		data32 = (data32 & (~0xFF))|data;
+		break;
+	case 0x1:
+		data32 = (data32 & (~0xFF00))|(((unsigned int)data)<<8);
+		break;
+	case 0x2:
+		data32 = (data32 & (~0xFF0000))|(((unsigned int)data)<<16);
+		break;
+	case 0x3:
+		data32 = (data32 & (~0xFF000000))|(((unsigned int)data)<<24);
+		break;
+	}
+
+	df_write(addr32, data32);
+
+	udelay(1);
+	data_rd = TVE_Read(tveid, addr);
+	if(data_rd != data){
+		DEBUG_PRINTF("TVE%d: Reg Write ERROR: addr_base = %02x, wr_data =%08x,rd_data = %08x\n",
+				tveid,addr,data,data_rd);
+	}
+
+	return;
+}
+
+int InitTVE0Raw(TVOUT_MODE DispFormat , int EnableColorBar)
+{
+	int i = 0;
+	int VIDEO_TYPE  = TVOUT_MODE_576I;
+	int IsHD = 0;
+	int IsProgressive = 0;
+
+	//Map the Display Format Value to TVE0 Format Value
+	switch (DispFormat)
+	{
+		case TVOUT_MODE_SECAM:
+			VIDEO_TYPE = TYPE_SECAM;
+			IsHD = 0;
+			IsProgressive = 0;
+			break;
+		case TVOUT_MODE_PAL_N:
+			VIDEO_TYPE = TYPE_PAL_N;
+			IsHD = 0;
+			IsProgressive = 0;
+			break;
+		case TVOUT_MODE_PAL_M:
+			VIDEO_TYPE = TYPE_PAL_M;
+			IsHD = 0;
+			IsProgressive = 0;
+			break;
+		case TVOUT_MODE_PAL_CN:
+			VIDEO_TYPE = TYPE_PAL_CN;
+			IsHD = 0;
+			IsProgressive = 0;
+			break;
+		case TVOUT_MODE_576I:
+			VIDEO_TYPE = TYPE_PAL;
+			IsHD = 0;
+			IsProgressive = 0;
+			break;
+		case TVOUT_MODE_480I:
+			VIDEO_TYPE = TYPE_NTSC;
+			IsHD = 0;
+			IsProgressive = 0;
+			break;
+		case TVOUT_MODE_1080I30:
+		case TVOUT_MODE_1080I5994:
+			VIDEO_TYPE = TYPE_1080i30;
+			IsHD = 1;
+			IsProgressive = 0;
+			break;
+		case TVOUT_MODE_1080I25:
+			VIDEO_TYPE = TYPE_1080i;
+			IsHD = 1;
+			IsProgressive = 0;
+			break;
+		case TVOUT_MODE_720P60:
+		case TVOUT_MODE_720P5994:
+			VIDEO_TYPE = TYPE_720p60;
+			IsHD = 1;
+			IsProgressive = 1;
+			break;
+		case TVOUT_MODE_720P50:
+			VIDEO_TYPE = TYPE_720p50;
+			IsHD = 1;
+			IsProgressive = 1;
+			break;
+		case TVOUT_MODE_480P:
+		case TVOUT_MODE_480P5994:
+			VIDEO_TYPE = TYPE_480p;
+			IsHD = 0;
+			IsProgressive = 1;
+			break;
+		case TVOUT_MODE_576P:
+			VIDEO_TYPE = TYPE_480p;
+			IsHD = 0;
+			IsProgressive = 1;
+			break;
+		case TVOUT_MODE_1080P24:
+		case TVOUT_MODE_1080P25:
+		case TVOUT_MODE_1080P30:
+		case TVOUT_MODE_1080P50:
+		case TVOUT_MODE_1080P60:
+		case TVOUT_MODE_1080P2397:
+		case TVOUT_MODE_1080P5994:
+		case TVOUT_MODE_720P5994_3DFP:
+		case TVOUT_MODE_720P60_3DFP:
+		case TVOUT_MODE_720P50_3DFP:
+		case TVOUT_MODE_1080P2397_3DFP:
+		case TVOUT_MODE_1080P24_3DFP:
+		case TVOUT_MODE_1080I50_3DSS:
+		case TVOUT_MODE_1080I5994_3DSS:
+		case TVOUT_MODE_1080I60_3DSS:
+		case TVOUT_MODE_1080P2397_3DTB:
+		case TVOUT_MODE_1080P24_3DTB:
+		case TVOUT_MODE_720P50_3DTB:
+		case TVOUT_MODE_720P5994_3DTB:
+		case TVOUT_MODE_720P60_3DTB:
+		case TVOUT_MODE_1600X1200_60FPS:
+			return 0;
+		default:
+			VIDEO_TYPE = TYPE_PAL;
+			IsHD = 0;
+			IsProgressive = 0;
+			break;
+	}
+
+	//Hold TVE0 Timing
+	TVE_Write(0,TVE0_REG[0][REG_ADDR],0x1);
+
+	//DEBUG_PRINTF("[TVE0: INFO]probe REV_ID ..%d\n",TVE0_REG[1][REG_ADDR]);
+
+	for (i=2; i<TVE0_REG_NUM; i++)
+	{
+		//DEBUG_PRINTF("TVE0: ADDR=%03x,WriteDATA=%03x\n",TVE0_REG[i][REG_ADDR],TVE0_REG[i][VIDEO_TYPE]);
+		TVE_Write(0,TVE0_REG[i][REG_ADDR],TVE0_REG[i][VIDEO_TYPE]);
+	}
+
+	if (EnableColorBar)
+	{
+		unsigned char  RegValue = 0;
+		RegValue = TVE_Read(0,0x2);
+		RegValue |= (1 << 5);
+		TVE_Write(0,0x2,RegValue);
+	}
+	TVE_Write(0,TVE0_REG[0][REG_ADDR],0x0);
+	return 0;
+}
+
+int InitTVE1Raw( TVOUT_MODE DispFormat , int EnableColorBar)
+{
+	int i = 0;
+	int VIDEO_TYPE  = TVOUT_MODE_576I;
+	int IsHD = 0;
+	int IsProgressive = 0;
+
+	//Map the Display Format Value to TVE1 Format Value
+	switch (DispFormat){
+		case TVOUT_MODE_SECAM:
+			VIDEO_TYPE = TYPE_SECAM;
+			IsHD = 0;
+			IsProgressive = 0;
+			break;
+		case TVOUT_MODE_PAL_N:
+			VIDEO_TYPE = TYPE_PAL_N;
+			IsHD = 0;
+			IsProgressive = 0;
+			break;
+		case TVOUT_MODE_PAL_M:
+			VIDEO_TYPE = TYPE_PAL_M;
+			IsHD = 0;
+			IsProgressive = 0;
+			break;
+		case TVOUT_MODE_PAL_CN:
+			VIDEO_TYPE = TYPE_PAL_CN;
+			IsHD = 0;
+			IsProgressive = 0;
+			break;
+		case TVOUT_MODE_576I:
+			VIDEO_TYPE = TYPE_PAL;
+			IsHD = 0;
+			IsProgressive = 0;
+			break;
+		case TVOUT_MODE_480I:
+			VIDEO_TYPE = TYPE_NTSC;
+			IsHD = 0;
+			IsProgressive = 0;
+			break;
+		case TVOUT_MODE_1080I30:
+		case TVOUT_MODE_1080I25:
+			VIDEO_TYPE = TYPE_1080i;
+			IsHD = 1;
+			IsProgressive = 0;
+			break;
+		case TVOUT_MODE_720P60:
+			VIDEO_TYPE = TYPE_720p60;
+			IsHD = 1;
+			IsProgressive = 1;
+			break;
+		case TVOUT_MODE_720P50:
+			VIDEO_TYPE = TYPE_720p50;
+			IsHD = 1;
+			IsProgressive = 1;
+			break;
+		case TVOUT_MODE_480P:
+			VIDEO_TYPE = TYPE_480p;
+			IsHD = 0;
+			IsProgressive = 1;
+			break;
+		case TVOUT_MODE_576P:
+			VIDEO_TYPE = TYPE_480p;
+			IsHD = 0;
+			IsProgressive = 1;
+			break;
+		case TVOUT_MODE_1080P24:
+		case TVOUT_MODE_1080P25:
+		case TVOUT_MODE_1080P30:
+		case TVOUT_MODE_1080P50:
+		case TVOUT_MODE_1080P60:
+		case TVOUT_MODE_1080P2397:
+		case TVOUT_MODE_1080P5994:
+		case TVOUT_MODE_1080P2397_3DFP:
+		case TVOUT_MODE_1080P24_3DFP:
+			return 0;
+		default:
+			VIDEO_TYPE = TYPE_PAL;
+			IsHD = 0;
+			IsProgressive = 0;
+			break;
+	}
+	//printascii("1111111111\n");
+	//Hold TVE1 Timing
+	TVE_Write(1,TVE1_REG[0][REG_ADDR],0x1);
+	//DEBUG_PRINTF("[TVE1: INFO]probe REV_ID ..%d\n",TVE1_REG[1][REG_ADDR]);
+	//printascii("222222222222\n");
+
+	for (i=2; i<TVE1_REG_NUM; i++)
+	{
+		//DEBUG_PRINTF("TVE1: ADDR=%03x,WriteDATA=%03x\n",TVE1_REG[i][REG_ADDR],TVE1_REG[i][VIDEO_TYPE]);
+		TVE_Write(1,TVE1_REG[i][REG_ADDR],TVE1_REG[i][VIDEO_TYPE]);
+	}
+
+	if (EnableColorBar)
+	{
+		unsigned char RegValue = 0;
+		RegValue = TVE_Read(1,0x2);
+		RegValue |= (1 << 5);
+		TVE_Write(1,0x2,RegValue);
+	}
+	TVE_Write(1,TVE1_REG[0][REG_ADDR],0x0);
+
+	return 0;
+}
+
+static int dfreg_ctrl[16] =
+{
+	VPP_REG_GLB_CTRL_H_UPDATE_REG,VPP_REG_GLB_CTRL_M_UPDATE_REG,VPP_REG_GLB_CTRL_C_UPDATE_REG,VPP_REG_GLB_CTRL_SETTING,VPP_REG_GLB_CTRL_CLK_SETTING,
+		VPP_REG_GLB_CTRL_INT_STA_COP,VPP_REG_GLB_CTRL_INT_MSK_COP,VPP_REG_GLB_CTRL_INT_STA_HOST,VPP_REG_GLB_CTRL_INT_MSK_HOST,VPP_REG_GLB_CTRL_SCALE_COEF3,
+		VPP_REG_GLB_CTRL_SCALE_COEF4,VPP_REG_GLB_CTRL_SCALE_COEF6,VPP_REG_GLB_CTRL_CPU_WQ,VPP_REG_GLB_CTRL_COP_RQ,VPP_REG_GLB_CTRL_HAND_STATUS,VPP_REG_GLB_CTRL_TG_SETTING,
+};
+
+static int dfreg_gfx[2][14] =
+{
+	{VPP_REG_GFX_UI1_CTRL,VPP_REG_GFX_UI1_ALPHA_CTRL,VPP_REG_GFX_UI1_SIZE,VPP_REG_GFX_UI1_KEY_RED,VPP_REG_GFX_UI1_KEY_BLUE,VPP_REG_GFX_UI1_KEY_GREEN,
+		VPP_REG_GFX_UI1_BUF_START,VPP_REG_GFX_UI1_LINE_PITCH,VPP_REG_GFX_UI1_X_POSITON,VPP_REG_GFX_UI1_Y_POSITON,VPP_REG_GFX_UI1_BUF_START_3D,
+		VPP_REG_GFX_UI1_A8,VPP_REG_GFX_UI1_PHASE,VPP_REG_GFX_UI1_COEFF_GID,
+	},
+	{VPP_REG_GFX_UI2_CTRL,VPP_REG_GFX_UI2_ALPHA_CTRL,VPP_REG_GFX_UI2_SIZE,VPP_REG_GFX_UI2_KEY_RED,VPP_REG_GFX_UI2_KEY_BLUE,VPP_REG_GFX_UI2_KEY_GREEN,
+		VPP_REG_GFX_UI2_BUF_START,VPP_REG_GFX_UI2_LINE_PITCH,VPP_REG_GFX_UI2_X_POSITON,VPP_REG_GFX_UI2_Y_POSITON,VPP_REG_GFX_UI2_BUF_START_3D,
+		VPP_REG_GFX_UI2_A8,VPP_REG_GFX_UI2_PHASE,VPP_REG_GFX_UI2_COEFF_GID,
+	},
+};
+
+static int dfreg_comp[9] =
+{
+	VPP_REG_COMP_B2_BACK_GROUND,VPP_REG_COMP_B2_Z_ORDER,VPP_REG_COMP_B2_DEFAULT_ALPHA,VPP_REG_COMP_COLOR_ADJUST,VPP_REG_COMP_SHARP_Y_CTRL,
+		VPP_REG_COMP_SHARP_C_CTRL,VPP_REG_COMP_B3_BACK_GROUND,VPP_REG_COMP_B3_Z_ORDER,VPP_REG_COMP_B3_DEFAULT_ALPHA
+};
+
+static int dfreg_outif[2][9] =
+{
+	{VPP_REG_TG1_CTRL,VPP_REG_TG1_X_SIZE,VPP_REG_TG1_Y_SIZE,VPP_REG_TG1_HSYNC,VPP_REG_TG1_VSYNC,
+		VPP_REG_TG1_VGA_LEVEL,VPP_REG_TG1_V_START_LINE,VPP_REG_TG1_STA_DISP_SIZE,VPP_REG_TG1_STA_LINE
+	},
+	{VPP_REG_TG2_CTRL,VPP_REG_TG2_X_SIZE,VPP_REG_TG2_Y_SIZE,VPP_REG_TG2_HSYNC,VPP_REG_TG2_VSYNC,
+		VPP_REG_TG2_VGA_LEVEL,VPP_REG_TG2_V_START_LINE,VPP_REG_TG2_STA_DISP_SIZE,VPP_REG_TG2_STA_LINE
+	},
+};
+
+static int process_num = 0;
+typedef struct CSM1900_df_DEV_t {
+	int instance_num;
+} csm1900_df_dev;
+
+void __df_update_start(void)
+{
+	df_write(dfreg_ctrl[0], 1);
+	df_write(dfreg_ctrl[2], 1);
+}
+EXPORT_SYMBOL(__df_update_start);
+
+void __df_update_end(void)
+{
+	df_write(dfreg_ctrl[0], 0);
+	df_write(dfreg_ctrl[2], 0);
+}
+
+void __df_update_outif_start(void)
+{
+	df_write(dfreg_ctrl[1], 1);
+}
+EXPORT_SYMBOL(__df_update_outif_start);
+
+void __df_update_outif_end(void)
+{
+	df_write(dfreg_ctrl[1], 0);
+}
+EXPORT_SYMBOL(__df_update_outif_end);
+
+void __update_vid_handshake_start(void)
+{
+	int wait_times = 10;
+
+	do{
+		df_write(VPP_REG_GLB_CTRL_CPU_WQ,1);
+		wait_times--;
+		mdelay(10);
+		if (wait_times <= 0){
+			printk("%s : %s in line %d\n",__FILE__,__FUNCTION__,__LINE__);
+			return;
+		}
+	}while((df_read(VPP_REG_GLB_CTRL_HAND_STATUS)&0x03)!=0x01);
+}
+
+void __update_vid_handshake_finish(void)
+{
+	df_write(VPP_REG_GLB_CTRL_CPU_WQ,0);
+}
+
+void DFSetOutIFVideoFmt(int OutIFId, DF_VIDEO_FORMAT Format, int En)
+{
+	//For Safety Format Switching It's better Disable the output clk First
+	df_outif_reg *OutIFReg= NULL;
+
+	OutIFId = OutIFId & 0x1;
+	OutIFReg = &dfreg.OutIF[OutIFId];
+
+	OutIFReg->reg_tg_ctrl.val = df_read(dfreg_outif[OutIFId][0]);
+	OutIFReg->reg_tg_x_size.val = df_read(dfreg_outif[OutIFId][1]);
+	OutIFReg->reg_tg_y_size.val = df_read(dfreg_outif[OutIFId][2]);
+	OutIFReg->reg_tg_hsync.val = df_read(dfreg_outif[OutIFId][3]);
+	OutIFReg->reg_tg_vsync.val = df_read(dfreg_outif[OutIFId][4]);
+
+    OutIFReg->reg_tg_ctrl.bits.tg_en=En;
+    OutIFReg->reg_tg_ctrl.bits.tg_is_hd=outputFormatInfo[Format].mIsHD&0x01;
+    OutIFReg->reg_tg_ctrl.bits.tg_is_interlaced=0x01&outputFormatInfo[Format].mVidType&0x01;
+    OutIFReg->reg_tg_ctrl.bits.tg_is_pal=outputFormatInfo[Format].mPALFmt&0x01;
+    OutIFReg->reg_tg_ctrl.bits.tg_dither_mode=0;
+    OutIFReg->reg_tg_ctrl.bits.tg_hsync_pol=outputFormatInfo[Format].mHSyncPol&0x01;
+    OutIFReg->reg_tg_ctrl.bits.tg_vsync_pol=outputFormatInfo[Format].mVSyncPol&0x01;
+    OutIFReg->reg_tg_ctrl.bits.tg_dither_ena=1;
+    OutIFReg->reg_tg_ctrl.bits.tg_3d_act_space=outputFormatInfo[Format].m3dVactSpace&0xff;
+    OutIFReg->reg_tg_ctrl.bits.tg_3d_en=outputFormatInfo[Format].m3dEn&0x01;
+
+    OutIFReg->reg_tg_hsync.bits.tg_hsync_front_porch=outputFormatInfo[Format].mHSyncFP&0x3ff;
+    OutIFReg->reg_tg_hsync.bits.tg_hsync_width=outputFormatInfo[Format].mHSyncWidth&0x3ff;
+    OutIFReg->reg_tg_hsync.bits.tg_hsync_back_porch=outputFormatInfo[Format].mHSyncBP&0x3ff;
+
+    OutIFReg->reg_tg_vsync.bits.tg_vsync_front_porch=outputFormatInfo[Format].mVSyncFP&0xff;
+    OutIFReg->reg_tg_vsync.bits.tg_vsync_width=outputFormatInfo[Format].mVSyncWidth&0xff;
+    OutIFReg->reg_tg_vsync.bits.tg_vsync_back_porch=outputFormatInfo[Format].mVSyncBP&0xff;
+
+
+    OutIFReg->reg_tg_x_size.bits.tg_htotal=outputFormatInfo[Format].mHRes&0x1fff;
+    OutIFReg->reg_tg_x_size.bits.tg_hactive_width=outputFormatInfo[Format].mHActive&0xfff;
+    OutIFReg->reg_tg_y_size.bits.tg_vtotal=outputFormatInfo[Format].mVRes&0x1fff;
+    OutIFReg->reg_tg_y_size.bits.tg_vactive_height= outputFormatInfo[Format].mVActline&0xfff;
+
+    if(outputFormatInfo[Format].mIsYUVorRGB){
+	    OutIFReg->reg_tg_vga_level.bits.tg_vga_black_level=0;
+	    OutIFReg->reg_tg_vga_level.bits.tg_vga_white_level=1023;
+    }
+    else{
+	    OutIFReg->reg_tg_vga_level.bits.tg_vga_black_level=252;
+	    OutIFReg->reg_tg_vga_level.bits.tg_vga_white_level=800;
+    }
+
+    OutIFReg->reg_tg_sta_line.bits.tg_v_start_line_num=6;
+
+    df_write(dfreg_outif[OutIFId][1], dfreg.OutIF[OutIFId].reg_tg_x_size.val);
+    df_write(dfreg_outif[OutIFId][2], dfreg.OutIF[OutIFId].reg_tg_y_size.val);
+    df_write(dfreg_outif[OutIFId][3], dfreg.OutIF[OutIFId].reg_tg_hsync.val);
+    df_write(dfreg_outif[OutIFId][4], dfreg.OutIF[OutIFId].reg_tg_vsync.val);
+    df_write(dfreg_outif[OutIFId][5], dfreg.OutIF[OutIFId].reg_tg_vga_level.val);
+    df_write(dfreg_outif[OutIFId][6], dfreg.OutIF[OutIFId].reg_tg_sta_line.val);
+    df_write(dfreg_outif[OutIFId][0], dfreg.OutIF[OutIFId].reg_tg_ctrl.val);
+
+	return;
+}
+
+void DFSetZOrder(int OutIFId, int Gfx1ZOrder, int Gfx2ZOrder, int Video1ZOrder, int Video2ZOrder)
+{
+	df_compositor_reg *Reg= NULL;
+
+	Reg = &dfreg.Comp;
+	Reg->reg_comp_b2_z_order.val = df_read(dfreg_comp[1]);
+
+	Reg->reg_comp_b2_z_order.bits.blending2_gfx1_z_order   = Gfx1ZOrder;
+	Reg->reg_comp_b2_z_order.bits.blending2_gfx1_z_order   = Gfx2ZOrder;
+	Reg->reg_comp_b2_z_order.bits.blending2_video1_z_order = Video1ZOrder;
+	Reg->reg_comp_b2_z_order.bits.blending2_video2_z_order = Video2ZOrder;
+
+	df_write(dfreg_comp[1], Reg->reg_comp_b2_z_order.val);
+	return;
+}
+
+void DFSetBackGroud(int OutIFId, unsigned char BGY, unsigned char BGU, unsigned char BGV)
+{
+	df_compositor_reg *Reg= NULL;
+
+	Reg = &dfreg.Comp;
+	Reg->reg_comp_b2_back_ground.val = df_read(dfreg_comp[0]);
+
+	Reg->reg_comp_b2_back_ground.bits.blending2_bg_y = BGY;
+	Reg->reg_comp_b2_back_ground.bits.blending2_bg_u = BGU;
+	Reg->reg_comp_b2_back_ground.bits.blending2_bg_v = BGV;
+
+	df_write(dfreg_comp[0], Reg->reg_comp_b2_back_ground.val);
+	return;
+}
+
+void DFGfxSetEndian(int GfxId, unsigned int GfxEndian)
+{
+    df_gfx_reg *Reg= NULL;
+
+    GfxId   = GfxId & 0x1;
+	Reg = &dfreg.Gfx[GfxId];
+
+    Reg->reg_gfx_ui_ctrl.val = df_read(dfreg_gfx[GfxId][0]);
+    Reg->reg_gfx_ui_ctrl.bits.gfx_ui_endian = (GfxEndian & 0x3);
+
+    df_write(dfreg_gfx[GfxId][0], Reg->reg_gfx_ui_ctrl.val);
+
+    return;
+}
+
+void DFGfxEna(int GfxId, int IsEna, int IsRGB2YUVEna)
+{
+	df_gfx_reg *Reg= NULL;
+
+	GfxId   = GfxId & 0x1;
+	Reg = &dfreg.Gfx[GfxId];
+
+	Reg->reg_gfx_ui_ctrl.val = df_read(dfreg_gfx[GfxId][0]);
+
+	if(DF_OUTPUT_VGA == df_output_config.output_mode[df_output_config.gfx_output[GfxId]]){
+		IsRGB2YUVEna = 0;
+	}
+	else{
+		IsRGB2YUVEna = 1;
+	}
+
+	if(IsEna)
+	{
+		Reg->reg_gfx_ui_ctrl.bits.gfx_ui_ena = (1 << df_output_config.gfx_output[GfxId]);
+		Reg->reg_gfx_ui_ctrl.bits.gfx_ui_yuv_conv_ena = IsRGB2YUVEna;
+	}
+	else
+	{
+		Reg->reg_gfx_ui_ctrl.bits.gfx_ui_ena = 0;
+	}
+
+	DEBUG_PRINTF("layer_output.gfx_output[%d] = %d\n",GfxId,df_output_config.gfx_output[GfxId]);
+	DEBUG_PRINTF("Reg->df_gfx_control_reg.bits.iGfxEna = %d\n",Reg->reg_gfx_ui_ctrl.bits.gfx_ui_ena);
+
+	df_write(dfreg_gfx[GfxId][0], Reg->reg_gfx_ui_ctrl.val);
+
+	return;
+}
+
+void DFGfxSetAlpha(int GfxId, unsigned char DefaultAlpha, unsigned char ARGB1555Alpha0, unsigned char ARGB1555Alpha1)
+{
+	df_gfx_reg *Reg= NULL;
+
+	GfxId   = GfxId & 0x1;
+	Reg = &dfreg.Gfx[GfxId];
+
+	Reg->reg_gfx_ui_alpha_ctrl.val = df_read(dfreg_gfx[GfxId][1]);
+
+	Reg->reg_gfx_ui_alpha_ctrl.bits.gfx_ui_default_alpha   = DefaultAlpha & 0x3ff;
+	Reg->reg_gfx_ui_alpha_ctrl.bits.gfx_ui_argb1555_a0 = ARGB1555Alpha0 & 0x3ff;
+	Reg->reg_gfx_ui_alpha_ctrl.bits.gfx_ui_argb1555_a1 = ARGB1555Alpha1 & 0x3ff;
+
+	df_write(dfreg_gfx[GfxId][1], Reg->reg_gfx_ui_alpha_ctrl.val);
+	return;
+}
+
+void DFGfxGetAlpha(int GfxId, unsigned char *DefaultAlpha, unsigned char *ARGB1555Alpha0, unsigned char *ARGB1555Alpha1)
+{
+	df_gfx_reg *Reg= NULL;
+
+	GfxId   = GfxId & 0x1;
+	Reg = &dfreg.Gfx[GfxId];
+
+
+	Reg->reg_gfx_ui_alpha_ctrl.val = df_read(dfreg_gfx[GfxId][2]);
+
+	*DefaultAlpha = Reg->reg_gfx_ui_alpha_ctrl.bits.gfx_ui_default_alpha;
+	*ARGB1555Alpha0 = Reg->reg_gfx_ui_alpha_ctrl.bits.gfx_ui_argb1555_a0;
+	*ARGB1555Alpha1 = Reg->reg_gfx_ui_alpha_ctrl.bits.gfx_ui_argb1555_a1;
+
+	return;
+}
+
+void DFGfxSetColorKey(int GfxId, unsigned char KeyRMin, unsigned char KeyRMax, unsigned char KeyGMin, unsigned char KeyGMax, unsigned char KeyBMin, unsigned char KeyBMax)
+{
+	df_gfx_reg *Reg= NULL;
+
+	GfxId   = GfxId & 0x1;
+	Reg = &dfreg.Gfx[GfxId];
+
+	Reg->reg_gfx_ui_key_red.val = df_read(dfreg_gfx[GfxId][3]);
+	Reg->reg_gfx_ui_key_blue.val = df_read(dfreg_gfx[GfxId][4]);
+	Reg->reg_gfx_ui_key_green.val = df_read(dfreg_gfx[GfxId][5]);
+
+	Reg->reg_gfx_ui_key_red.bits.gfx_ui_r_min   = KeyRMin;
+	Reg->reg_gfx_ui_key_red.bits.gfx_ui_r_max   = KeyRMax;
+	Reg->reg_gfx_ui_key_blue.bits.gfx_ui_b_min  = KeyBMin;
+	Reg->reg_gfx_ui_key_blue.bits.gfx_ui_b_max  = KeyBMax;
+	Reg->reg_gfx_ui_key_green.bits.gfx_ui_g_min = KeyGMin;
+	Reg->reg_gfx_ui_key_green.bits.gfx_ui_g_max = KeyGMax;
+
+	df_write(dfreg_gfx[GfxId][3], Reg->reg_gfx_ui_key_red.val);
+	df_write(dfreg_gfx[GfxId][4], Reg->reg_gfx_ui_key_blue.val);
+	df_write(dfreg_gfx[GfxId][5], Reg->reg_gfx_ui_key_green.val);
+
+	return;
+}
+
+void DFGfxColorKeyEna(int GfxId,int IsEna)
+{
+	df_gfx_reg*Reg = NULL;
+
+	GfxId = GfxId & 0x1;
+	Reg = &dfreg.Gfx[GfxId];
+	Reg->reg_gfx_ui_ctrl.val = df_read(dfreg_gfx[GfxId][0]);
+
+	Reg->reg_gfx_ui_ctrl.bits.gfx_ui_color_keying_en = IsEna;
+
+	df_write(dfreg_gfx[GfxId][0], Reg->reg_gfx_ui_ctrl.val);
+
+	return;
+}
+
+
+void DFGfxOpaqueOnOff(int GfxId,int OnOff)
+{
+	df_gfx_reg*Reg = NULL;
+
+	GfxId = GfxId & 0x1;
+	Reg = &dfreg.Gfx[GfxId];
+	Reg->reg_gfx_ui_ctrl.val = df_read(dfreg_gfx[GfxId][0]);
+
+	Reg->reg_gfx_ui_ctrl.bits.gfx_ui_opaque = OnOff;
+
+	df_write(dfreg_gfx[GfxId][0], Reg->reg_gfx_ui_ctrl.val);
+
+	return;
+}
+
+
+void DFGfxConfigDistrect(int GfxId,unsigned int startx,unsigned int starty,unsigned int endx,unsigned int endy)
+{
+	df_gfx_reg*Reg = NULL;
+
+	GfxId = GfxId & 0x1;
+	Reg = &dfreg.Gfx[GfxId];
+	Reg->reg_gfx_ui_x_position.val = df_read(dfreg_gfx[GfxId][8]);
+
+	Reg->reg_gfx_ui_x_position.bits.gfx_ui_dst_x_start =startx;
+	Reg->reg_gfx_ui_x_position.bits.gfx_ui_dst_x_end=endx;
+
+	df_write(dfreg_gfx[GfxId][8], Reg->reg_gfx_ui_x_position.val);
+
+	Reg->reg_gfx_ui_y_position.val = df_read(dfreg_gfx[GfxId][9]);
+
+	Reg->reg_gfx_ui_y_position.bits.gfx_ui_dst_y_start =starty;
+	Reg->reg_gfx_ui_y_position.bits.gfx_ui_dst_y_end=endy;
+
+	df_write(dfreg_gfx[GfxId][9], Reg->reg_gfx_ui_y_position.val);
+}
+
+
+unsigned int coefflaginited=0;
+void DFGfxScalorCoef(void)
+{
+	unsigned int *regaddr3 = NULL;
+	unsigned int *regaddr4 = NULL;
+	unsigned int *regaddr6 = NULL;
+
+	if(!coefflaginited)
+		{
+		if(NULL== request_mem_region( SCALOR_COEF_REGION, SCALOR_COEF_SIZE, "scalor coef data"))
+			printk("failed to request scalor coef data\n");
+
+	        regaddr3=ioremap_nocache(SCALOR_COEF_REGION, SCALOR_COEF_SIZE/3);
+		//printk(KERN_INFO"scalor coef data 3=0x%08x\n",(unsigned int)regaddr3);
+		regaddr4=ioremap_nocache(SCALOR_COEF_REGION+SCALOR_COEF_SIZE/3, SCALOR_COEF_SIZE/3);
+		//printk(KERN_INFO"scalor coef data 4=0x%08x\n",(unsigned int)regaddr4);
+		regaddr6=ioremap_nocache(SCALOR_COEF_REGION+SCALOR_COEF_SIZE*2/3, SCALOR_COEF_SIZE/3);
+		//printk(KERN_INFO"scalor coef data 6=0x%08x\n",(unsigned int)regaddr6);
+
+		memcpy((char*)regaddr3,cof3tap,sizeof(cof3tap));
+		memcpy((char*)regaddr4,cof4tap,sizeof(cof4tap));
+		memcpy((char*)regaddr6,cof6tap,sizeof(cof6tap));
+
+
+		df_write(dfreg_ctrl[9],SCALOR_COEF_REGION);
+		df_write(dfreg_ctrl[10],SCALOR_COEF_REGION+SCALOR_COEF_SIZE/3);
+		df_write(dfreg_ctrl[11],SCALOR_COEF_REGION+SCALOR_COEF_SIZE*2/3);
+		/*printk(KERN_INFO"cof3tap readout=%x\n",df_read(dfreg_ctrl[9]));
+		printk(KERN_INFO"cof4tap readout=%x\n",df_read(dfreg_ctrl[10]));
+		printk(KERN_INFO"cof6tap readout=%x\n",df_read(dfreg_ctrl[11]));*/
+		}
+	coefflaginited=1;
+}
+
+
+void __df_calc_video_position(TVOUT_MODE pre_mode,TVOUT_MODE cur_mode, df_output_pos *pos)
+{
+	switch(cur_mode){
+		case TVOUT_MODE_576I:
+		case TVOUT_MODE_576I_16TO9:
+		case TVOUT_MODE_576P:
+		case TVOUT_MODE_576P50_16TO9:
+		case TVOUT_MODE_PAL_N:
+		case TVOUT_MODE_PAL_CN:
+		case TVOUT_MODE_SECAM:
+			pos->src.top = pos->dst.top = 0;
+			pos->src.bottom = pos->dst.bottom = 576;
+			pos->src.left = pos->dst.left = 0;
+			pos->src.right = pos->dst.right = 720;
+			break;
+		case TVOUT_MODE_480I:
+		case TVOUT_MODE_480I60_16TO9:
+		case TVOUT_MODE_480I5994:
+		case TVOUT_MODE_480I5994_16TO9:
+		case TVOUT_MODE_480P:
+		case TVOUT_MODE_PAL_M:
+		case TVOUT_MODE_480P5994:
+		case TVOUT_MODE_480P5994_16TO9:
+		case TVOUT_MODE_480P60_16TO9:
+			pos->src.top = pos->dst.top = 0;
+			pos->src.bottom = pos->dst.bottom = 480;
+			pos->src.left = pos->dst.left = 0;
+			pos->src.right = pos->dst.right = 720;
+			break;
+		case TVOUT_MODE_720P50:
+		case TVOUT_MODE_720P60:
+		case TVOUT_MODE_720P5994:
+		case TVOUT_MODE_720P5994_3DFP:
+		case TVOUT_MODE_720P60_3DFP:
+        	case TVOUT_MODE_720P50_3DFP:
+			pos->src.top = pos->dst.top = 0;
+			pos->src.bottom = pos->dst.bottom = 720;
+			pos->src.left = pos->dst.left = 0;
+			pos->src.right = pos->dst.right = 1280;
+			break;
+		case TVOUT_MODE_1080I25:
+		case TVOUT_MODE_1080I30:
+		case TVOUT_MODE_1080P24:
+		case TVOUT_MODE_1080P25:
+		case TVOUT_MODE_1080P30:
+		case TVOUT_MODE_1080P50:
+		case TVOUT_MODE_1080P60:
+		case TVOUT_MODE_1080I5994:
+		case TVOUT_MODE_1080P2397:
+		case TVOUT_MODE_1080P5994:
+		case TVOUT_MODE_1080P2397_3DFP:
+		case TVOUT_MODE_1080P24_3DFP:
+		case TVOUT_RGB_1920X1080P30:
+		case TVOUT_RGB_1920X1080P60:
+		case TVOUT_RGB_1920X1080I30:
+			pos->src.top = pos->dst.top = 0;
+			pos->src.bottom = pos->dst.bottom = 1080;
+			pos->src.left = pos->dst.left = 0;
+			pos->src.right = pos->dst.right = 1920;
+			break;
+		case TVOUT_RGB_640X480_60FPS:
+		case TVOUT_RGB_640X480_5994FPS:
+			pos->src.top = pos->dst.top = 0;
+			pos->src.bottom = pos->dst.bottom = 480;
+			pos->src.left = pos->dst.left = 0;
+			pos->src.right = pos->dst.right = 640;
+			break;
+		case TVOUT_RGB_800X600_60FPS:
+			pos->src.top = pos->dst.top = 0;
+			pos->src.bottom = pos->dst.bottom = 600;
+			pos->src.left = pos->dst.left = 0;
+			pos->src.right = pos->dst.right = 800;
+			break;
+		case TVOUT_RGB_1024X768_60FPS:
+			pos->src.top = pos->dst.top = 0;
+			pos->src.bottom = pos->dst.bottom = 768;
+			pos->src.left = pos->dst.left = 0;
+			pos->src.right = pos->dst.right = 1024;
+			break;
+#if 0
+		case TVOUT_RGB_1280X1024_50FPS:
+			pos->src.top = pos->dst.top = 0;
+			pos->src.bottom = pos->dst.bottom = 1024;
+			pos->src.left = pos->dst.left = 0;
+			pos->src.right = pos->dst.right = 1280;
+			break;
+
+		case TVOUT_RGB_1600X1000_60FPS:
+			pos->src.top = pos->dst.top = 0;
+			pos->src.bottom = pos->dst.bottom = 1000;
+			pos->src.left = pos->dst.left = 0;
+			pos->src.right = pos->dst.right = 1600;
+			break;
+#endif
+		case TVOUT_RGB_1280X720_60FPS:
+			pos->src.top = pos->dst.top = 0;
+			pos->src.bottom = pos->dst.bottom = 720;
+			pos->src.left = pos->dst.left = 0;
+			pos->src.right = pos->dst.right = 1280;
+			break;
+#if 0
+		case TVOUT_RGB_848X480_60FPS:
+			pos->src.top = pos->dst.top = 0;
+			pos->src.bottom = pos->dst.bottom = 848;
+			pos->src.left = pos->dst.left = 0;
+			pos->src.right = pos->dst.right = 480;
+			break;
+#endif
+		case TVOUT_RGB_1280X1024_60FPS:
+			pos->src.top = pos->dst.top = 0;
+			pos->src.bottom = pos->dst.bottom = 1024;
+			pos->src.left = pos->dst.left = 0;
+			pos->src.right = pos->dst.right = 1280;
+			break;
+		case TVOUT_RGB_800X480_60FPS:
+			pos->src.top = pos->dst.top = 0;
+			pos->src.bottom = pos->dst.bottom = 800;
+			pos->src.left = pos->dst.left = 0;
+			pos->src.right = pos->dst.right = 480;
+			break;
+		case TVOUT_RGB_1440X900_60FPS:
+			pos->src.top = pos->dst.top = 0;
+			pos->src.bottom = pos->dst.bottom = 1440;
+			pos->src.left = pos->dst.left = 0;
+			pos->src.right = pos->dst.right = 900;
+			break;
+		case TVOUT_RGB_1360X768_60FPS:
+			pos->src.top = pos->dst.top = 0;
+			pos->src.bottom = pos->dst.bottom = 768;
+			pos->src.left = pos->dst.left = 0;
+			pos->src.right = pos->dst.right = 1360;
+			break;
+		case TVOUT_RGB_1366X768_60FPS:
+			pos->src.top = pos->dst.top = 0;
+			pos->src.bottom = pos->dst.bottom = 768;
+			pos->src.left = pos->dst.left = 0;
+			pos->src.right = pos->dst.right = 1366;
+			break;
+		case TVOUT_MODE_1600X1200_60FPS:
+			pos->src.top = pos->dst.top = 0;
+			pos->src.bottom = pos->dst.bottom = 1200;
+			pos->src.left = pos->dst.left = 0;
+			pos->src.right = pos->dst.right = 1600;
+			break;
+		default:
+			pos->src.top = pos->dst.top = 0;
+			pos->src.bottom = pos->dst.bottom = 576;
+			pos->src.left = pos->dst.left = 0;
+			pos->src.right = pos->dst.right = 720;
+			break;
+	}
+}
+
+int Get_Outif_Id(int gfx_id)
+{
+	return df_output_config.gfx_output[gfx_id];
+}
+
+int Get_Video_Id(int tve_id)
+{
+	if(tve_id == df_output_config.vid_output[0]) return 0;
+	else if(tve_id == df_output_config.vid_output[1]) return 1;
+	else if(tve_id == df_output_config.vid_output[2]) return 2;
+
+	return -1;
+}
+
+int Get_Gfx_Id(int tve_id)
+{
+	if(tve_id == df_output_config.gfx_output[0]) return 0;
+	else if(tve_id == df_output_config.gfx_output[1]) return 1;
+
+	return -1;
+}
+
+EXPORT_SYMBOL(Get_Outif_Id);
+
+//#define HAND_SHAKE_WITH_VIDEO_FIRMWARE DF_STATUS_SWITCH_REG //0x48 //0x23
+static int dummy_bri = 0;
+static void __SetBrightness(unsigned int bri)
+{
+    unsigned char brightness = bri & 0xff;
+    union{
+        struct{
+            unsigned int enh_bright:8;
+            unsigned int enh_contrast:6;
+            unsigned int reserved_1:2;
+            unsigned int enh_saturation:8;
+            unsigned int reserved_2:8;
+        }bits;
+        unsigned int val;
+    }adjust;
+
+    //fixed df bug that the brightness is 127, the display too dark
+    if(brightness == 127){
+        dummy_bri = 1;    
+        return;
+    }else{
+        dummy_bri = 0;    
+    }
+
+    if(brightness & 128)
+        brightness = brightness - 128; 
+    else
+        brightness = 255 - brightness; 
+
+    adjust.val = df_read(VPP_REG_COMP_COLOR_ADJUST);
+
+    adjust.bits.enh_bright = brightness;
+    df_write(VPP_REG_COMP_COLOR_ADJUST, adjust.val);
+}
+
+static unsigned int __GetBrightness(void)
+{
+    unsigned char brightness;
+    union{
+        struct{
+            unsigned int enh_bright:8;
+            unsigned int enh_contrast:6;
+            unsigned int reserved_1:2;
+            unsigned int enh_saturation:8;
+            unsigned int reserved_2:8;
+        }bits;
+        unsigned int val;
+    }adjust;
+
+    if(dummy_bri){
+        return 127;
+    }
+
+    adjust.val = df_read(VPP_REG_COMP_COLOR_ADJUST);
+    brightness = adjust.bits.enh_bright & 0xff;
+
+    if(brightness & 128)
+        brightness = 255 - brightness; 
+    else
+        brightness = 128 + brightness; 
+    return brightness;
+}
+static void __SetContrast(unsigned int con)
+{
+    union{
+        struct{
+            unsigned int enh_bright:8;
+            unsigned int enh_contrast:6;
+            unsigned int reserved_1:2;
+            unsigned int enh_saturation:8;
+            unsigned int reserved_2:8;
+        }bits;
+        unsigned int val;
+    }adjust;
+
+    adjust.val = df_read(VPP_REG_COMP_COLOR_ADJUST);
+
+    adjust.bits.enh_contrast = con & 0x3F;
+    df_write(VPP_REG_COMP_COLOR_ADJUST, adjust.val);
+}
+static unsigned int __GetContrast(void)
+{
+    union{
+        struct{
+            unsigned int enh_bright:8;
+            unsigned int enh_contrast:6;
+            unsigned int reserved_1:2;
+            unsigned int enh_saturation:8;
+            unsigned int reserved_2:8;
+        }bits;
+        unsigned int val;
+    }adjust;
+
+    adjust.val = DF_Read(VPP_REG_COMP_COLOR_ADJUST);
+    return adjust.bits.enh_contrast;
+}
+
+static void __SetSaturation(unsigned int sat)
+{
+    union{
+        struct{
+            unsigned int enh_bright:8;
+            unsigned int enh_contrast:6;
+            unsigned int reserved_1:2;
+            unsigned int enh_saturation:8;
+            unsigned int reserved_2:8;
+        }bits;
+        unsigned int val;
+    }adjust;
+
+    adjust.val = df_read(VPP_REG_COMP_COLOR_ADJUST);
+    adjust.bits.enh_saturation = sat & 0xFF;
+    df_write(VPP_REG_COMP_COLOR_ADJUST, adjust.val);
+}
+static unsigned int __GetSaturation(void)
+{
+    union{
+        struct{
+            unsigned int enh_bright:8;
+            unsigned int enh_contrast:6;
+            unsigned int reserved_1:2;
+            unsigned int enh_saturation:8;
+            unsigned int reserved_2:8;
+        }bits;
+        unsigned int val;
+    }adjust;
+
+    adjust.val = DF_Read(VPP_REG_COMP_COLOR_ADJUST);
+    return adjust.bits.enh_saturation;
+
+}
+static void __SetSharpness(unsigned int sharpness)
+{
+    union{
+        struct{
+            unsigned int enh_y_sharp_en:1;
+            unsigned int enh_y_median_en:1;
+            unsigned int enh_y_coring_soft:1;
+            unsigned int reserved_1:1;
+            unsigned int enh_y_peaking_shrink:3;
+            unsigned int reserved_2:1;
+            unsigned int enh_y_coring:6;
+            unsigned int reserved_3:2;
+            unsigned int enh_y_bpw:8;
+            unsigned int enh_y_hpw:8;
+        }bits;
+        unsigned int val;
+    }reg_comp_sharp_y;
+
+    union{
+        struct{
+            unsigned int enh_c_sharp_en:1;
+            unsigned int enh_c_median_en:1;
+            unsigned int enh_c_coring_soft:1;
+            unsigned int reserved_1:1;
+            unsigned int enh_c_peaking_shrink:3;
+            unsigned int reserved_2:1;
+            unsigned int enh_c_coring:6;
+            unsigned int reserved_3:2;
+            unsigned int enh_c_bpw:8;
+            unsigned int enh_c_hpw:8;
+        }bits;
+        unsigned int val;
+    }reg_comp_sharp_c;
+
+    reg_comp_sharp_y.val = DF_Read(VPP_REG_COMP_SHARP_Y_CTRL);
+    reg_comp_sharp_c.val = DF_Read(VPP_REG_COMP_SHARP_C_CTRL);
+
+    reg_comp_sharp_y.bits.enh_y_sharp_en = sharpness ? 1 : 0;
+    reg_comp_sharp_c.bits.enh_c_sharp_en = sharpness ? 1 : 0;
+
+    DF_Write(VPP_REG_COMP_SHARP_Y_CTRL, reg_comp_sharp_y.val);
+    DF_Write(VPP_REG_COMP_SHARP_C_CTRL, reg_comp_sharp_c.val);
+}
+static unsigned int __GetSharpness(void)
+{
+     union{
+        struct{
+            unsigned int enh_y_sharp_en:1;
+            unsigned int enh_y_median_en:1;
+            unsigned int enh_y_coring_soft:1;
+            unsigned int reserved_1:1;
+            unsigned int enh_y_peaking_shrink:3;
+            unsigned int reserved_2:1;
+            unsigned int enh_y_coring:6;
+            unsigned int reserved_3:2;
+            unsigned int enh_y_bpw:8;
+            unsigned int enh_y_hpw:8;
+        }bits;
+        unsigned int val;
+    }reg_comp_sharp_y;
+
+    union{
+        struct{
+            unsigned int enh_c_sharp_en:1;
+            unsigned int enh_c_median_en:1;
+            unsigned int enh_c_coring_soft:1;
+            unsigned int reserved_1:1;
+            unsigned int enh_c_peaking_shrink:3;
+            unsigned int reserved_2:1;
+            unsigned int enh_c_coring:6;
+            unsigned int reserved_3:2;
+            unsigned int enh_c_bpw:8;
+            unsigned int enh_c_hpw:8;
+        }bits;
+        unsigned int val;
+    }reg_comp_sharp_c;
+
+    reg_comp_sharp_y.val = DF_Read(VPP_REG_COMP_SHARP_Y_CTRL);
+    reg_comp_sharp_c.val = DF_Read(VPP_REG_COMP_SHARP_C_CTRL);
+
+    return reg_comp_sharp_y.bits.enh_y_sharp_en & reg_comp_sharp_c.bits.enh_c_sharp_en;
+}
+
+
+//G1_G2_V1_V2:0x1032
+//V1_V2_G1_G2:0x3210
+//G2_G1_V2_V1:0x123
+//V2_V1_G2_G1:0x2301
+//G1_V1_G2_V2:0x2031
+
+static void __Set_B2_ZOrder(unsigned int zorder)
+{
+    DF_Write(VPP_REG_COMP_B2_Z_ORDER, zorder);
+}
+
+static unsigned int __Get_B2_ZOrder(void)
+{
+    return DF_Read(VPP_REG_COMP_B3_Z_ORDER);
+}
+
+//static void __Set_B3_ZOrder(unsigned int zorder)
+//{
+//    union{
+//        struct{
+//            unsigned int blending3_video1_z_order:2;
+//            unsigned int reserved_1:2;
+//            unsigned int reserved_2:4;
+//            unsigned int blending3_gfx1_z_order:2;
+//            unsigned int reserved_3:4;
+//            unsigned int reserved_4:18;
+//        }bits;
+//        unsigned int val;
+//    }b3_z_order;
+//
+//    b3_z_order.val = 0;
+//    b3_z_order.bits.blending3_gfx1_z_order = 1;
+//    b3_z_order.bits.blending3_video1_z_order = 2;
+//
+//    DF_Write(VPP_REG_COMP_B3_Z_ORDER, DF_Read(VPP_REG_COMP_B3_Z_ORDER) | b3_z_order.val);
+//}
+//static int __Get_B3_ZOrder(void)
+//{
+//   union{
+//        struct{
+//            unsigned int blending3_video1_z_order:2;
+//            unsigned int reserved_1:2;
+//            unsigned int reserved_2:4;
+//            unsigned int blending3_gfx1_z_order:2;
+//            unsigned int reserved_3:4;
+//            unsigned int reserved_4:18;
+//        }bits;
+//        unsigned int val;
+//    }b3_z_order;
+//
+//    b3_z_order.val = DF_Read(VPP_REG_COMP_B3_Z_ORDER);
+//    return b3_z_order.val;
+//}
+
+static int __set_tv_mode(unsigned long arg, unsigned int minor_id)
+{
+	int tveid;
+	df_output_pos pos;
+
+	tveid = (minor_id == DF_MINOR_TVE1)? 1:0;
+
+	if(__Is_first){
+		pinmux_set_dac0mode(_dac0_tve0_ypbpr);
+		pinmux_set_dac1mode(_dac1_tve1_cvbs_svideo);
+#ifdef CONFIG_YPBPR_DAC_ENABLE
+		clock_dac0_enaclock(_clock_enable);
+#endif
+#ifdef CONFIG_HD2SD_ENABLE
+		clock_dac1_enaclock(_clock_enable);
+#endif
+	}
+
+    switch(arg){
+		case TVOUT_MODE_SECAM:
+		case TVOUT_MODE_PAL_N:
+		case TVOUT_MODE_PAL_M:
+		case TVOUT_MODE_PAL_CN:
+		case TVOUT_MODE_576I:
+		case TVOUT_MODE_576I_16TO9:
+		case TVOUT_MODE_480I:
+		case TVOUT_MODE_480I60_16TO9:
+		case TVOUT_MODE_480I5994:
+		case TVOUT_MODE_480I5994_16TO9:
+		case TVOUT_MODE_1080I25:
+		case TVOUT_MODE_1080I30:
+		case TVOUT_MODE_1080I5994:
+		case TVOUT_MODE_1080I50_3DSS:
+		case TVOUT_MODE_1080I5994_3DSS:
+		case TVOUT_MODE_1080I60_3DSS:
+            _Is_interlace = 1;
+            break;
+        default:
+            _Is_interlace = 0;
+    }
+
+    switch(arg){
+    	case TVOUT_MODE_SECAM:
+		case TVOUT_MODE_PAL_N:
+		case TVOUT_MODE_PAL_M:
+		case TVOUT_MODE_PAL_CN:
+		case TVOUT_MODE_480I:
+		case TVOUT_MODE_480I60_16TO9:
+		case TVOUT_MODE_480I5994:
+		case TVOUT_MODE_480I5994_16TO9:
+		case TVOUT_MODE_1080I30:
+		case TVOUT_MODE_1080P30:
+		case TVOUT_RGB_1920X1080I30:
+		case TVOUT_RGB_1920X1080P30:
+		case TVOUT_MODE_1080I5994:
+		case TVOUT_MODE_1080I5994_3DSS:
+		case TVOUT_MODE_1080I60_3DSS:
+            _Frame_rate = 3000;
+            break;
+		case TVOUT_MODE_1080P24:
+		case TVOUT_MODE_1080P2397:
+		case TVOUT_MODE_1080P2397_3DFP:
+		case TVOUT_MODE_1080P24_3DFP:
+		case TVOUT_MODE_1080P24_3DTB:
+		case TVOUT_MODE_1080P2397_3DTB:
+            _Frame_rate = 2400;
+            break;
+		case TVOUT_MODE_576I:
+		case TVOUT_MODE_576I_16TO9:
+		case TVOUT_MODE_1080I25:
+		case TVOUT_MODE_1080P25:
+		case TVOUT_MODE_1080I50_3DSS:
+            _Frame_rate = 2500;
+            break;
+		case TVOUT_MODE_576P:
+		case TVOUT_MODE_576P50_16TO9:
+		case TVOUT_MODE_720P50:
+		case TVOUT_MODE_1080P50:
+		case TVOUT_MODE_720P50_3DFP:
+		case TVOUT_MODE_720P50_3DTB:
+            _Frame_rate = 5000;
+            break;
+		case TVOUT_MODE_480P:
+		case TVOUT_MODE_480P60_16TO9:
+		case TVOUT_MODE_480P5994:
+		case TVOUT_MODE_480P5994_16TO9:
+		case TVOUT_MODE_720P60:
+		case TVOUT_MODE_1080P60:
+    		case TVOUT_RGB_640X480_60FPS:
+    		case TVOUT_RGB_640X480_5994FPS:
+		case TVOUT_RGB_800X600_60FPS:
+		case TVOUT_RGB_800X480_60FPS:
+		case TVOUT_RGB_1024X768_60FPS:
+		case TVOUT_RGB_1280X720_60FPS:
+		case TVOUT_RGB_1440X900_60FPS:
+		case TVOUT_RGB_1280X1024_60FPS:
+		case TVOUT_RGB_1360X768_60FPS:
+		case TVOUT_RGB_1366X768_60FPS:
+		case TVOUT_RGB_1920X1080P60:
+		case TVOUT_MODE_720P5994:
+		case TVOUT_MODE_1080P5994:
+		case TVOUT_MODE_720P5994_3DFP:
+		case TVOUT_MODE_720P60_3DFP:
+		case TVOUT_MODE_720P5994_3DTB:
+		case TVOUT_MODE_720P60_3DTB:
+		case TVOUT_MODE_1600X1200_60FPS:
+            _Frame_rate = 6000;
+            break;
+        default:
+            _Frame_rate = 3000;
+    }
+
+	switch (arg){
+		case TVOUT_MODE_SECAM:
+		case TVOUT_MODE_PAL_N:
+		case TVOUT_MODE_PAL_M:
+		case TVOUT_MODE_PAL_CN:
+		case TVOUT_MODE_576I:
+		case TVOUT_MODE_576P:
+		case TVOUT_MODE_480I:
+		case TVOUT_MODE_480P:
+		case TVOUT_MODE_720P50:
+		case TVOUT_MODE_720P60:
+		case TVOUT_MODE_1080I25:
+		case TVOUT_MODE_1080I30:
+		case TVOUT_MODE_1080P24:
+		case TVOUT_MODE_1080P25:
+		case TVOUT_MODE_1080P30:
+		case TVOUT_MODE_1080P50:
+		case TVOUT_MODE_1080P60:
+		case TVOUT_MODE_576I_16TO9:
+		case TVOUT_MODE_576P50_16TO9:
+		case TVOUT_MODE_480I60_16TO9:
+		case TVOUT_MODE_480I5994:
+		case TVOUT_MODE_480I5994_16TO9:
+		case TVOUT_MODE_480P5994:
+		case TVOUT_MODE_480P5994_16TO9:
+		case TVOUT_MODE_480P60_16TO9:
+		case TVOUT_MODE_720P5994:
+		case TVOUT_MODE_1080I5994:
+		case TVOUT_MODE_1080P2397:
+		case TVOUT_MODE_1080P5994:
+		case TVOUT_MODE_720P5994_3DFP:
+		case TVOUT_MODE_720P60_3DFP:
+		case TVOUT_MODE_720P50_3DFP:
+		case TVOUT_MODE_1080P2397_3DFP:
+		case TVOUT_MODE_1080P24_3DFP:
+		case TVOUT_MODE_1080I50_3DSS:
+		case TVOUT_MODE_1080I5994_3DSS:
+		case TVOUT_MODE_1080I60_3DSS:
+		case TVOUT_MODE_720P50_3DTB:
+		case TVOUT_MODE_720P5994_3DTB:
+		case TVOUT_MODE_720P60_3DTB:
+		case TVOUT_MODE_1080P2397_3DTB:
+		case TVOUT_MODE_1080P24_3DTB:
+		case TVOUT_MODE_1600X1200_60FPS:
+			if(DF_OUTPUT_CVBS_SVIDEO == df_output_config.output_mode[tveid]){
+				pinmux_set_dac0mode(_dac0_tve0_cvbs_svideo);
+			}
+			else{
+				pinmux_set_dac0mode(_dac0_tve0_ypbpr);
+			}
+			__Is_TV = 1;
+			break;
+		case TVOUT_RGB_640X480_60FPS:
+		case TVOUT_RGB_640X480_5994FPS:
+		case TVOUT_RGB_800X600_60FPS:
+		case TVOUT_RGB_800X480_60FPS:
+		case TVOUT_RGB_1024X768_60FPS:
+		case TVOUT_RGB_1280X720_60FPS:
+		case TVOUT_RGB_1440X900_60FPS:
+		case TVOUT_RGB_1280X1024_60FPS:
+		case TVOUT_RGB_1360X768_60FPS:
+		case TVOUT_RGB_1920X1080P30:
+		case TVOUT_RGB_1920X1080P60:
+		case TVOUT_RGB_1920X1080I30:
+		case TVOUT_RGB_1366X768_60FPS:
+			pinmux_set_dac0mode(_dac0_rgb0);
+			__Is_TV = 0;
+			break;
+
+		default:
+			break;
+	}
+	DEBUG_PRINTF("tevid = %d, mode = %d\n",tveid,(int)arg);
+
+    __change_tg_request(tveid);
+
+	__df_calc_video_position(df_dev[minor_id].tve_format,arg,&pos);
+	df_dev[minor_id].tve_format = arg;
+
+	if(0 == tveid){
+	        printk("df_dev[minor_id].tve_format=%d\n",df_dev[minor_id].tve_format);
+	        printk("tve_2_clock[df_dev[minor_id].tve_format]=%d\n",tve_2_clock[df_dev[minor_id].tve_format]);
+
+		clock_disp0_setclock(tve_2_clock[df_dev[minor_id].tve_format]);
+	}
+	else if(1 == tveid){
+		clock_disp1_setclock(tve_2_clock1[df_dev[minor_id].tve_format]);
+	}
+
+	mdelay(10);
+
+	if(__Is_TV){
+		if(tveid == 0){
+#ifdef CONFIG_YPBPR_DAC_ENABLE
+			InitTVE0Raw(df_dev[minor_id].tve_format, __Is_ColorBar);
+#else
+			;
+#endif
+		}
+		else if(tveid == 1){
+#ifdef CONFIG_HD2SD_ENABLE
+			InitTVE1Raw(df_dev[minor_id].tve_format, __Is_ColorBar);
+#else
+			;
+#endif
+		}
+		mdelay(10);
+	}
+
+	__df_update_outif_start();
+	        printk("tve_2_df[df_dev[minor_id].tve_format]=%d\n",tve_2_df[df_dev[minor_id].tve_format]);
+	DFSetOutIFVideoFmt(tveid,tve_2_df[df_dev[minor_id].tve_format],1);
+	__df_update_outif_end();
+	mdelay(10);
+#if 1
+	__update_vid_handshake_start();
+	__video_set_layer_position(__video_tve_2_tg(tveid), pos.dst.right, pos.dst.bottom, _Is_interlace, _Frame_rate);
+	__update_vid_handshake_finish();
+#endif
+    __change_tg_release(tveid);
+
+	if((tveid == 0) && (__Is_hd2sd)){
+		switch (df_dev[minor_id].tve_format){
+			case TVOUT_MODE_SECAM:
+				df_dev[minor_id+1].tve_format = TVOUT_MODE_SECAM;
+				break;
+			case TVOUT_MODE_PAL_CN:
+				df_dev[minor_id+1].tve_format = TVOUT_MODE_PAL_CN;
+				break;
+			case TVOUT_MODE_PAL_N:
+				df_dev[minor_id+1].tve_format = TVOUT_MODE_PAL_N;
+				break;
+			case TVOUT_MODE_PAL_M:
+				df_dev[minor_id+1].tve_format = TVOUT_MODE_PAL_M;
+				break;
+			case TVOUT_MODE_576I:
+			case TVOUT_MODE_576I_16TO9:
+			case TVOUT_MODE_1080I25:
+			case TVOUT_MODE_576P:
+			case TVOUT_MODE_576P50_16TO9:
+			case TVOUT_MODE_720P50:
+			case TVOUT_MODE_1080P25:
+			case TVOUT_MODE_1080P50:
+			case TVOUT_MODE_1080I50_3DSS:
+			case TVOUT_MODE_720P50_3DTB:
+				df_dev[minor_id+1].tve_format = TVOUT_MODE_576I;
+				break;
+			case TVOUT_MODE_480I:
+			case TVOUT_MODE_480I60_16TO9:
+			case TVOUT_MODE_480I5994:
+			case TVOUT_MODE_480I5994_16TO9:
+			case TVOUT_MODE_480P:
+			case TVOUT_MODE_720P60:
+			case TVOUT_MODE_1080I30:
+			case TVOUT_MODE_1080P24:
+			case TVOUT_MODE_1080P30:
+			case TVOUT_MODE_1080P60:
+			case TVOUT_MODE_480P5994:
+			case TVOUT_MODE_480P5994_16TO9:
+			case TVOUT_MODE_480P60_16TO9:
+			case TVOUT_MODE_720P5994:
+			case TVOUT_MODE_1080I5994:
+			case TVOUT_MODE_1080P2397:
+			case TVOUT_MODE_1080P5994:
+			case TVOUT_MODE_720P5994_3DFP:
+			case TVOUT_MODE_720P60_3DFP:
+			case TVOUT_MODE_720P50_3DFP:
+			case TVOUT_MODE_1080P2397_3DFP:
+			case TVOUT_MODE_1080P24_3DFP:
+			case TVOUT_RGB_640X480_60FPS:
+			case TVOUT_RGB_640X480_5994FPS:
+			case TVOUT_RGB_800X600_60FPS:
+			case TVOUT_RGB_1024X768_60FPS:
+			case TVOUT_RGB_1280X720_60FPS:
+			case TVOUT_RGB_800X480_60FPS:
+			case TVOUT_RGB_1440X900_60FPS:
+			case TVOUT_RGB_1280X1024_60FPS:
+			case TVOUT_RGB_1360X768_60FPS:
+			case TVOUT_RGB_1920X1080P30:
+			case TVOUT_RGB_1920X1080P60:
+			case TVOUT_RGB_1920X1080I30:
+			case TVOUT_RGB_1366X768_60FPS:
+			case TVOUT_MODE_1080I5994_3DSS:
+			case TVOUT_MODE_1080I60_3DSS:
+			case TVOUT_MODE_720P5994_3DTB:
+			case TVOUT_MODE_720P60_3DTB:
+			case TVOUT_MODE_1080P2397_3DTB:
+			case TVOUT_MODE_1080P24_3DTB:
+			case TVOUT_MODE_1600X1200_60FPS:
+				df_dev[minor_id+1].tve_format = TVOUT_MODE_480I;
+				break;
+
+			default:
+				df_dev[minor_id+1].tve_format = TVOUT_MODE_576I;
+				DEBUG_PRINTF("kernel: TVOUT_MODE_576I\n");
+				break;
+		}
+
+		switch(df_dev[minor_id+1].tve_format){
+			case TVOUT_MODE_576I:
+			case TVOUT_MODE_PAL_N:
+			case TVOUT_MODE_PAL_CN:
+			case TVOUT_MODE_SECAM:
+				pos.dst.right = 720;
+				pos.dst.bottom = 576;
+				break;
+			case TVOUT_MODE_480I:
+			case TVOUT_MODE_PAL_M:
+				pos.dst.right = 720;
+				pos.dst.bottom = 480;
+				break;
+			default:
+				pos.dst.right = 720;
+				pos.dst.bottom = 480;
+				break;
+		}
+
+		clock_disp1_setclock(tve_2_clock1[df_dev[minor_id+1].tve_format]);
+		mdelay(10);
+		InitTVE1Raw(df_dev[minor_id+1].tve_format, __Is_ColorBar);
+		__df_update_outif_start();
+		DFSetOutIFVideoFmt(1,tve_2_df[df_dev[minor_id+1].tve_format],1);
+		__df_update_outif_end();
+		mdelay(10);
+#if 1
+		__update_vid_handshake_start();
+        __video_set_hd2sd(pos.src.right - pos.src.left, pos.src.bottom - pos.src.top, pos.dst.right - pos.dst.left, pos.dst.bottom - pos.dst.top);
+		//__video_set_hd2sd(pos);
+		__update_vid_handshake_finish();
+		__video_send_hd2sd_cmd(1); //play
+#endif
+	}
+
+	__Is_first = 0;
+
+    return 0;
+}
+
+static int cnc_tve_ioctl(unsigned int cmd, unsigned long arg, unsigned int minor_id)
+{
+	int tveid;
+
+	tveid = (minor_id == DF_MINOR_TVE1)? 1:0;
+
+	switch (cmd) {
+		case CSTVE_IOC_GET_BIND_INF:
+			if (copy_to_user((void *) arg, (void *) &df_output_config, sizeof(DF_OUTPUT_CONFIG_t))) {
+				return -EFAULT;
+			}
+			break;
+		case CSDF_IOC_GET_INIT_OUTPUTMODE:
+			__put_user(outputmode, (int __user *) arg);
+			break;
+
+		case CSTVE_IOC_ENABLE:
+			if(tveid == 0){
+#ifdef CONFIG_YPBPR_DAC_ENABLE
+				clock_dac0_enaclock(_clock_enable);
+#endif
+				clock_hdmi_reset(_do_set);
+			}
+			else if(tveid == 1){
+#ifdef CONFIG_HD2SD_ENABLE
+				clock_dac1_enaclock(_clock_enable);
+#else
+				;
+#endif
+			}
+			else
+				printk("parameters errorn\n!");
+			break;
+
+		case CSTVE_IOC_DISABLE:
+			if(tveid == 0){
+				clock_dac0_enaclock(_clock_disable);
+				clock_hdmi_reset(_do_reset);
+			}
+			else if(tveid == 1)
+				clock_dac1_enaclock(_clock_disable);
+			else
+				printk("parameters errorn\n!");
+			break;
+
+		case CSTVE_IOC_SET_OUTPUT:
+			df_output_config.output_mode[tveid] = arg;
+			DEBUG_PRINTF("layer_output.output_mode[%d] = %d\n",tveid,(int)arg);
+			break;
+		case CSTVE_IOC_SET_HDMI_IN_BYPASS:
+			if((unsigned int)arg == 0)
+				clock_hdmi_bypass(_sel_ttl);
+			else if((unsigned int)arg == 1)
+				clock_hdmi_bypass(_sel_vib);
+			else
+				printk("parameters errorn\n!");
+			break;
+
+		case CSTVE_IOC_SET_HDMI_IN_ENBALE:
+			if((unsigned int)arg == 0)
+				pinmux_enable_ttlout();
+			else if((unsigned int)arg == 1)
+				pinmux_enable_vib();
+			else
+				printk("parameters errorn\n!");
+			break;
+		case CSTVE_IOC_SET_MODE:
+		printk("arg=%d\n",arg);
+            __set_tv_mode((unsigned int)arg, minor_id);
+		    break;
+		case CSTVE_IOC_GET_MODE:
+			__put_user(df_dev[minor_id].tve_format, (int __user *) arg);
+			break;
+		case CSDF_IOC_Z_ORDER:
+			//df_write(dfreg_comp[1], arg);
+			__df_update_start();
+ 			__Set_B2_ZOrder((unsigned int)arg);
+			__df_update_end();
+			break;
+        case CSDF_IOC_GET_Z_ORDER:
+            __put_user(__Get_B2_ZOrder(), (int __user*)arg);
+        break;
+        case CSDF_IOC_SET_BRIGHTNESS:
+		__df_update_start();
+		__SetBrightness((unsigned int)arg);
+		__df_update_end();
+	 break;
+        case CSDF_IOC_GET_BRIGHTNESS:
+            __put_user(__GetBrightness(), (int __user*)arg);
+            break;
+        case CSDF_IOC_SET_CONTRAST:
+		__df_update_start();
+		__SetContrast((unsigned int)arg);
+		__df_update_end();
+		break;
+        case CSDF_IOC_GET_CONTRAST:
+            __put_user(__GetContrast(), (int __user*)arg);
+            break;
+        case CSDF_IOC_SET_SATURATION:
+		__df_update_start();
+            __SetSaturation((unsigned int)arg);
+		__df_update_end();
+            break;
+        case CSDF_IOC_GET_SATURATION:
+            __put_user(__GetSaturation(), (int __user*)arg);
+            break;
+        case CSDF_IOC_SET_SHARPNESS:
+		__df_update_start();
+            __SetSharpness((unsigned int)arg);
+		__df_update_end();
+            break;
+        case CSDF_IOC_GET_SHARPNESS:
+            __put_user(__GetSharpness(), (int __user*)arg);
+            break;
+        case CSDF_IOC_DISP_HD2SD_ENABLE:
+#ifdef CONFIG_HD2SD_ENABLE
+            if(arg == 1)
+                __Is_hd2sd = 1;
+            else
+                __Is_hd2sd = 0;
+#endif
+            break;
+		default:
+			break;
+	}
+	return 0;
+}
+
+static int cnc_df_gfx_ioctl(unsigned int cmd, unsigned long arg, unsigned int minor_id)
+{
+	printk("This node(Gfx layer) is not used!\n");
+	return 0;
+}
+
+static int cnc_df_vid_ioctl(unsigned int cmd, unsigned long arg, unsigned int minor_id)
+{
+	int vid_id;
+
+	if(DF_MINOR_VID0 == minor_id)
+		vid_id = 0;
+	else if(DF_MINOR_VID1 == minor_id)
+		vid_id = 1;
+	else if(DF_MINOR_VIDAUX == minor_id)
+		vid_id = 2;
+	else
+		return 0;
+
+	DEBUG_PRINTF("cnc_df_vid_ioctl : df video layer id = %d\n",vid_id);
+
+	switch (cmd) {
+		case CSDF_IOC_GET_VPP_REG_ADDR:
+			DEBUG_PRINTF("CSDF_IOC_GET_VPP_REG_ADDR\n");
+			__put_user(VPP_REG_BASE, (unsigned int __user *) arg);
+			break;
+
+		case CSDF_IOC_GET_VPP_REG_SIZE:
+			DEBUG_PRINTF("CSDF_IOC_GET_VPP_REG_SIZE\n");
+			__put_user(VPP_REG_SIZE, (unsigned int __user *) arg);
+			break;
+
+		case CSDF_IOC_DISP_VID_ALPHA:
+			DEBUG_PRINTF("CSDF_IOC_DISP_VID_ALPHA\n");
+		break;
+
+		case CSDF_IOC_DISP_POS:
+			{
+				DEBUG_PRINTF("CSDF_IOC_DISP_POS\n");
+				break;
+			}
+
+		default:
+			DEBUG_PRINTF("unknown cmd 0x%x\n",cmd);
+			break;
+	}
+
+	return 0;
+}
+
+static int cnc_df_outif_ioctl(unsigned int cmd, unsigned long arg, unsigned int minor_id)
+{
+	printk("This node(outif) is not used!\n");
+	return 0;
+}
+
+static long cnc_df_ioctl(struct file *file,unsigned int cmd, unsigned long arg)
+{
+	unsigned int minor_id = iminor(file->f_mapping->host);
+	DEBUG_PRINTF("cnc_df_ioctl\n");
+	if (minor_id == DF_MINOR_TVE0 || minor_id == DF_MINOR_TVE1){
+		cnc_tve_ioctl(cmd, arg, minor_id);
+	}
+
+	else if (minor_id == DF_MINOR_GFX0 || minor_id == DF_MINOR_GFX1){
+		cnc_df_gfx_ioctl(cmd, arg, minor_id);
+	}
+
+	else if (minor_id == DF_MINOR_VID0 || minor_id == DF_MINOR_VID1){
+		cnc_df_vid_ioctl(cmd, arg, minor_id);
+	}
+
+	else if (minor_id == DF_MINOR_VIDAUX){
+		cnc_df_vid_ioctl(cmd, arg, minor_id);
+	}
+
+	else if (minor_id == DF_MINOR_OUT0 || minor_id == DF_MINOR_OUT1){
+		cnc_df_outif_ioctl(cmd, arg, minor_id);
+	}
+
+	return 0;
+}
+
+int __df_mem_initialize(void)
+{
+	if (NULL == request_mem_region(VPP_REG_BASE, VPP_REG_SIZE, "CNC1900 VPP space")) {
+		goto INIT_ERR0;
+	}
+
+	if (NULL == disp_base){
+		if(!(disp_base = (unsigned char *)ioremap(VPP_REG_BASE, VPP_REG_SIZE))) {
+			goto INIT_ERR1;
+		}
+	}
+
+	if (NULL == request_mem_region(TVE0_REG_BASE, TVE0_REG_SIZE, "CNC1900 TVE0 space")) {
+		goto INIT_ERR2;
+	}
+
+	if (NULL == tve0_base){
+		if(!(tve0_base = (unsigned char *)ioremap(TVE0_REG_BASE, TVE0_REG_SIZE))) {
+			goto INIT_ERR3;
+		}
+	}
+
+	if (NULL == request_mem_region(TVE1_REG_BASE, TVE1_REG_SIZE, "CNC1900 TVE1 space")) {
+		goto INIT_ERR4;
+	}
+
+	if (NULL == tve1_base){
+		if(!(tve1_base = (unsigned char *)ioremap(TVE1_REG_BASE, TVE1_REG_SIZE))) {
+			goto INIT_ERR5;
+		}
+	}
+
+	printk("disp_base 0x%x, tve0_base 0x%x, tve1_base 0x%x\n",(unsigned int)disp_base,(unsigned int)tve0_base,(unsigned int)tve1_base);
+	return 0;
+
+INIT_ERR5:
+	printk(KERN_INFO "__df_mem_initialize INIT_ERR5 ...\n");
+	release_mem_region(TVE1_REG_BASE, TVE1_REG_SIZE);
+INIT_ERR4:
+	printk(KERN_INFO "__df_mem_initialize INIT_ERR4 ...\n");
+	iounmap((void *)tve0_base);
+INIT_ERR3:
+	printk(KERN_INFO "__df_mem_initialize INIT_ERR3 ...\n");
+	release_mem_region(TVE0_REG_BASE, TVE0_REG_SIZE);
+INIT_ERR2:
+	printk(KERN_INFO "__df_mem_initialize INIT_ERR2 ...\n");
+	iounmap((void *)disp_base);
+INIT_ERR1:
+	printk(KERN_INFO "__df_mem_initialize INIT_ERR1 ...\n");
+	release_mem_region(VPP_REG_BASE, VPP_REG_SIZE);
+INIT_ERR0:
+	printk(KERN_INFO "__df_mem_initialize INIT_ERR0 ...\n");
+	return -1;
+}
+
+void __df_mem_destroy(void)
+{
+	iounmap((void *)tve1_base);
+	release_mem_region(TVE1_REG_BASE, TVE1_REG_SIZE);
+	iounmap((void *)tve0_base);
+	release_mem_region(TVE0_REG_BASE, TVE0_REG_SIZE);
+	iounmap((void *)disp_base);
+	release_mem_region(VPP_REG_BASE, VPP_REG_SIZE);
+}
+
+static int df_proc_write(struct file *file, const char *buffer, unsigned long count, void *data)
+{
+	const char *cmd_line = buffer;
+
+	if (strncmp("tver1", cmd_line, 5) == 0) {
+		int addr;
+		addr = simple_strtol(&buffer[6], NULL, 16);
+		printk(" tve1[0x%08x] = 0x%08x \n", addr&0xff, TVE_Read(1, addr&0xff));
+	}
+	else if (strncmp("tvew1", cmd_line, 5) == 0) {
+		int addr, val;
+		addr = simple_strtol(&buffer[6], NULL, 16);
+		val = simple_strtol(&buffer[9], NULL, 16);
+		TVE_Write(1, addr&0xff, val&0xff);
+	}
+	else if (strncmp("tver0", cmd_line, 5) == 0) {
+		int addr;
+		addr = simple_strtol(&buffer[6], NULL, 16);
+		printk(" tve0[0x%08x] = 0x%08x \n", addr&0xff, TVE_Read(0, addr&0xff));
+	}
+	else if (strncmp("tvew0", cmd_line, 5) == 0) {
+		int addr, val;
+		addr = simple_strtol(&buffer[6], NULL, 16);
+		val = simple_strtol(&buffer[9], NULL, 16);
+		TVE_Write(0, addr&0xff, val&0xff);
+	}
+	else if (strncmp("rl", cmd_line, 2) == 0) {
+		int addr;
+		addr = simple_strtol(&buffer[3], NULL, 16);
+		printk(" addr[0x%08x] = 0x%08x \n", addr, df_read(addr));
+	}
+	else if (strncmp("wl", cmd_line, 2) == 0) {
+		int addr, val;
+		addr = simple_strtol(&buffer[3], NULL, 16);
+		val = simple_strtol(&buffer[12], NULL, 16);
+//		__df_update_start();
+		df_write(addr, val);
+//		__df_update_end();
+	}
+	else if (strncmp("enable_colorbar", cmd_line, 15) == 0) {
+		__Is_ColorBar = 1;
+	}
+	else if (strncmp("disable_colorbar", cmd_line, 16) == 0) {
+		__Is_ColorBar = 0;
+	}
+	else if(strncmp("480i", cmd_line, 4) == 0){
+		df_rect DispRect;
+		DispRect.top = 0;
+		DispRect.left = 0;
+		DispRect.right = 720;
+		DispRect.bottom = 480;
+
+		pinmux_enable_ttlout();
+
+		pinmux_set_dac0mode(_dac0_tve0_ypbpr);
+		pinmux_set_dac1mode(_dac1_tve1_cvbs_svideo);
+
+		clock_dac0_enaclock(_clock_enable);
+		clock_dac1_enaclock(_clock_enable);
+		clock_disp0_setclock(_YUV_480P_60Hz);
+		clock_disp1_setclock(_YUV_NTSC_disp1);
+
+//		clock_hdmiset_clockmode(_YUV_NTSC, _1x_disp_clk);
+printk("111111111\n");
+		InitTVE0Raw(TVOUT_MODE_480P, 1);
+printk("22222222\n");
+		InitTVE1Raw(TVOUT_MODE_480I, 1);
+printk("3333333\n");
+		__df_update_outif_start();
+printk("%s:%s in line %d\n",__FILE__,__FUNCTION__,__LINE__);
+		DFSetOutIFVideoFmt(0, DISP_YUV_480P,1);
+printk("%s:%s in line %d\n",__FILE__,__FUNCTION__,__LINE__);
+		DFSetOutIFVideoFmt(1, DISP_YUV_NTSC,1);
+printk("%s:%s in line %d\n",__FILE__,__FUNCTION__,__LINE__);
+		__df_update_outif_end();
+printk("4444444\n");
+	}
+	else if(strncmp("aaa", cmd_line, 3) == 0){
+		df_rect DispRect;
+		DispRect.top = 0;
+		DispRect.left = 0;
+		DispRect.right = 720;
+		DispRect.bottom = 480;
+
+		pinmux_enable_ttlout();
+
+		pinmux_set_dac0mode(_dac0_tve1_cvbs_svideo);
+		pinmux_set_dac1mode(_dac1_tve1_cvbs_svideo);
+
+		clock_dac0_enaclock(_clock_enable);
+		clock_dac1_enaclock(_clock_enable);
+		clock_disp0_setclock(_YUV_480P_60Hz);
+		clock_disp1_setclock(_YUV_NTSC_disp1);
+
+//		clock_hdmiset_clockmode(_YUV_NTSC, _1x_disp_clk);
+printk("111111111\n");
+		InitTVE0Raw(TVOUT_MODE_480P, 1);
+printk("22222222\n");
+		InitTVE1Raw(TVOUT_MODE_480I, 1);
+printk("3333333\n");
+		__df_update_outif_start();
+printk("%s:%s in line %d\n",__FILE__,__FUNCTION__,__LINE__);
+		DFSetOutIFVideoFmt(0, DISP_YUV_480P,1);
+printk("%s:%s in line %d\n",__FILE__,__FUNCTION__,__LINE__);
+		DFSetOutIFVideoFmt(1, DISP_YUV_NTSC,1);
+printk("%s:%s in line %d\n",__FILE__,__FUNCTION__,__LINE__);
+		__df_update_outif_end();
+printk("4444444\n");
+	}
+#if 0
+	else if(strncmp("480p", cmd_line, 4) == 0){
+		df_rect DispRect;
+		DispRect.top = 0;
+		DispRect.left = 0;
+		DispRect.right = 720;
+		DispRect.bottom = 480;
+
+		clock_dispset_dac1mode(_clock_wake);
+		clock_dispset_clockmode0(_disp0, _YUV_480P);
+		clock_hdmiset_clockmode(_YUV_480P, _1x_disp_clk);
+
+		InitTVE0Raw(TVOUT_MODE_480P, 1);
+		__df_update_start();
+		DFSetOutIFVideoFmt(0, DISP_YUV_480P);
+		DFOutIFEna(0, 1);
+		__df_update_end();
+
+	}
+	else if(strncmp("576i", cmd_line, 4) == 0){
+		df_rect DispRect;
+		DispRect.top = 0;
+		DispRect.left = 0;
+		DispRect.right = 720;
+		DispRect.bottom = 576;
+
+		clock_dispset_dac0mode(_clock_wake);
+		clock_dispset_dac1mode(_clock_wake);
+		clock_dispset_clockmode0(_disp0, _YUV_PAL);
+		clock_dispset_clockmode0(_disp1, _YUV_PAL);
+		clock_hdmiset_clockmode(_YUV_PAL, _1x_disp_clk);
+
+		InitTVE0Raw(TVOUT_MODE_576I, 1);
+		InitTVE1Raw(TVOUT_MODE_576I, 1);
+		__df_update_start();
+		DFSetOutIFVideoFmt(0, DISP_YUV_PAL);
+		DFSetOutIFVideoFmt(1, DISP_YUV_PAL);
+		DFOutIFEna(0, 1);
+		DFOutIFEna(1, 1);
+		__df_update_end();
+
+	}
+	else if(strncmp("576p", cmd_line, 4) == 0){
+		df_rect DispRect;
+		DispRect.top = 0;
+		DispRect.left = 0;
+		DispRect.right = 720;
+		DispRect.bottom = 576;
+
+		clock_dispset_dac1mode(_clock_wake);
+		clock_dispset_clockmode0(_disp0, _YUV_576P);
+		clock_hdmiset_clockmode(_YUV_576P, _1x_disp_clk);
+
+		InitTVE0Raw(TVOUT_MODE_576P, 1);
+		__df_update_start();
+		DFSetOutIFVideoFmt(0, DISP_YUV_576P);
+		DFOutIFEna(0, 1);
+		__df_update_end();
+
+	}
+	else if(strncmp("720p", cmd_line, 4) == 0){
+		df_rect DispRect;
+		DispRect.top = 0;
+		DispRect.left = 0;
+		DispRect.right = 720;
+		DispRect.bottom = 576;
+
+		clock_dispset_dac1mode(_clock_wake);
+		clock_dispset_clockmode0(_disp0, _YUV_720P_60Hz);
+		InitTVE0Raw(TVOUT_MODE_720P60, 1);
+		clock_hdmiset_clockmode(_YUV_720P_60Hz, _1x_disp_clk);
+
+		__df_update_start();
+		DFSetOutIFVideoFmt(0, DISP_YUV_720P_60FPS);
+		DFOutIFEna(0, 1);
+		__df_update_end();
+
+	}
+	else if(strncmp("1080p", cmd_line, 5) == 0){
+		df_rect DispRect;
+		DispRect.top = 0;
+		DispRect.left = 0;
+		DispRect.right = 720;
+		DispRect.bottom = 576;
+
+		clock_dispset_dac1mode(_clock_wake);
+		clock_dispset_clockmode0(_disp0, _YUV_1080P_60Hz);
+		clock_hdmiset_clockmode(_YUV_1080P_60Hz, _1x_disp_clk);
+
+		//	InitTVE0Raw(TVOUT_MODE_1, 0);
+		//	InitTVE1Raw(TVOUT_MODE_576P, 0);
+		__df_update_start();
+		DFSetOutIFVideoFmt(0, DISP_YUV_1080P_60FPS);
+		DFOutIFEna(0, 1);
+		__df_update_end();
+
+	}
+#endif
+#if 0
+	else if(strncmp("vga", cmd_line, 3) == 0){
+		df_rect DispRect;
+		DispRect.top = 0;
+		DispRect.left = 0;
+		DispRect.right = 720;
+		DispRect.bottom = 576;
+
+		pinmux_set_dac1mode(_dac1_disp0_rgb);
+		clock_dispset_dac0mode(_clock_wake);
+		clock_dispset_dac1mode(_clock_wake);
+		clock_dispset_clockmode0(_disp0, _RGB_CVT_1366x768_60Hz);
+		//		clock_dispset_clockmode0(_disp1, _YUV_1080P_60Hz);
+		//	InitTVE0Raw(TVOUT_MODE_1, 0);
+		//	InitTVE1Raw(TVOUT_MODE_576P, 0);
+		__df_update_start();
+		DFSetOutIFVideoFmt(0, DISP_RGB_1366x768);
+		__df_update_end();
+
+	}
+#endif
+#if 0
+	else if((strncmp("df_clock",cmd_line,8) == 0)){
+		CLOCK_ENA ClockEna = _clock_enable;
+		ClockEna = simple_strtol(&buffer[9], NULL, 16);
+		printk(" ClockEna = %d \n", ClockEna);
+		clock_df_clockena(ClockEna);
+	}
+	else if((strncmp("clock_tms_clockena",cmd_line,18) == 0)){
+		CLOCK_ENA ClockEna = _clock_enable;
+		ClockEna = simple_strtol(&buffer[19], NULL, 16);
+		printk(" ClockEna = %d \n", ClockEna);
+		clock_tms_clockena(ClockEna);
+	}
+	else if((strncmp("clock_cec_clockena",cmd_line,18) == 0)){
+		CLOCK_ENA ClockEna = _clock_enable;
+		ClockEna = simple_strtol(&buffer[19], NULL, 16);
+		printk(" ClockEna = %d \n", ClockEna);
+		clock_cec_clockena(ClockEna);
+	}
+#endif
+	else if((strncmp("dumpreg",cmd_line,7) == 0)){
+		unsigned int count = 0;
+
+		for(count = 0; count < 0x300; count +=4){
+			switch(count){
+				case 0x0:
+					printk("\n VPP_REG_CTRL_BASE\n");
+					break;
+				case (0x20<<2):
+					printk("\n VPP_REG_GFX_DMA_BASE\n");
+					break;
+				case (0x50<<2):
+					printk("\n VPP_REG_GFX_UI1_BASE\n");
+					break;
+				case (0x40<<2):
+					printk("\n VPP_REG_GFX_UI2_BASE\n");
+					break;
+				case (0x60<<2):
+					printk("\n VPP_REG_HD2SD_RD_BASE\n");
+					break;
+				case (0x80<<2):
+					printk("\n VPP_REG_CAP_BASE\n");
+					break;
+				case (0xa0<<2):
+					printk("\n VPP_REG_COMP_BASE\n");
+					break;
+				case (0xb0<<2):
+					printk("\n VPP_REG_TG1_BASE\n");
+					break;
+				case (0xc0<<2):
+					printk("\n VPP_REG_TG2_BASE\n");
+					break;
+				case (0x100<<2):
+					printk("\n VPP_REG_MAIN_CH_BASE\n");
+					break;
+				case (0x140<<2):
+					printk("\n VPP_REG_SR_CH_BASE\n");
+					break;
+			}
+			printk(" addr[0x%08x] = 0x%08x \n", VPP_REG_BASE + count, df_read(VPP_REG_BASE+count));
+		}
+
+	}
+
+	return count;
+}
+
+static int cnc_df_open(struct inode *inode, struct file *file)
+{
+	unsigned int minor_id = iminor(inode);
+    csm1900_df_dev *df_dev_temp = NULL;
+
+    if(NULL == file->private_data){
+        printk("func:%s  line:%d \n",__FUNCTION__,__LINE__);
+        df_dev_temp = kmalloc(sizeof(csm1900_df_dev), GFP_KERNEL);
+        if(NULL == df_dev_temp){
+            printk("func:%s  line:%d \n",__FUNCTION__,__LINE__);
+            return -EBUSY;
+        }
+        df_dev_temp->instance_num = 1;
+        file->private_data = (void *)df_dev_temp;
+        if(process_num > 0){
+            process_num ++;
+            if(__Is_first&&(minor_id==DF_MINOR_TVE0))
+            df_dev[minor_id].tve_format = outputmode;
+            goto CSM_DF_OPEN_SUCCEED;
+        }
+        else{
+            process_num ++;
+        }
+    }
+    else{
+        df_dev_temp = file->private_data;
+        df_dev_temp->instance_num ++;
+        printk("func:%s  line:%d instance_num = %d\n",__FUNCTION__,__LINE__,df_dev_temp->instance_num);
+        goto CSM_DF_OPEN_SUCCEED;
+    }
+
+	spin_lock_init(&(df_dev[minor_id].spin_lock));
+	df_dev[minor_id].enable = 1;
+	df_dev[minor_id].tve_format = outputmode;
+
+	DEBUG_PRINTF("%s was opened\n",df_dev[minor_id].name);
+
+	//	clock_ddc_clockena(_clock_enable);
+	//	clock_cec_clockena(_clock_enable);
+	//	clock_tms_clockena(_clock_enable);
+CSM_DF_OPEN_SUCCEED:
+	return 0;
+}
+
+static int cnc_df_release(struct inode *inode, struct file *file)
+{
+	unsigned int minor_id = iminor(inode);
+    csm1900_df_dev *df_dev_temp = NULL;
+
+    df_dev_temp = file->private_data;
+    df_dev_temp->instance_num--;
+
+	if(df_dev_temp->instance_num > 0){
+		//printk("func:%s  line:%d instance_num = %d, process_num = %d\n",__FUNCTION__,__LINE__,df_dev_temp->instance_num, process_num);
+		return 0;
+	}
+	else{
+		//printk("func:%s  line:%d instance_num = %d, process_num = %d\n",__FUNCTION__,__LINE__,df_dev_temp->instance_num, process_num);
+		kfree(file->private_data);
+		process_num --;
+		if(process_num <= 0){
+			df_dev[minor_id].enable = 0;
+		}
+	}
+
+	DEBUG_PRINTF("%s was released\n",df_dev[minor_id].name);
+
+	return 0;
+}
+
+
+static struct class *cnc_df_class;
+static struct proc_dir_entry *cnc_df_proc_entry = NULL;
+static struct file_operations cnc_df_fops = {
+	.owner	= THIS_MODULE,
+	.open	=  cnc_df_open,
+	.release	= cnc_df_release,
+	.unlocked_ioctl		= cnc_df_ioctl,
+};
+
+CNC_FB_INTERRUPT cncdf_1800_vblank_int[2];
+
+irqreturn_t cnc_outif0_irq(int irq, void *dev_id)
+{
+	DF_IRQ_PRINTF("cnc_outif0_irq!\n");
+
+	if (DF_Read(VPP_REG_GLB_CTRL_INT_STA_HOST) & 0x8)
+	{
+		if(cncdf_1800_vblank_int[0].is_display == 1){
+			cncdf_1800_vblank_int[0].is_display = 0;
+			wake_up(&cncdf_1800_vblank_int[0].wait);
+		}
+
+		if(cncdf_1800_vblank_int[1].is_display == 1){
+			cncdf_1800_vblank_int[1].is_display = 0;
+			wake_up(&cncdf_1800_vblank_int[1].wait);
+		}
+	}
+
+	DF_Write(VPP_REG_GLB_CTRL_INT_STA_HOST, DF_Read(VPP_REG_GLB_CTRL_INT_STA_HOST) | 0x8);
+
+	return IRQ_HANDLED;
+}
+
+#if 0
+irqreturn_t cnc_outif1_irq(int irq, void *dev_id)
+{
+	DF_IRQ_PRINTF("cnc_outif1_irq!\n");
+
+	if(cncdf_1800_vblank_int[1].is_display == 1){
+		cncdf_1800_vblank_int[1].is_display = 0;
+		wake_up(&cncdf_1800_vblank_int[1].wait);
+	}
+
+	DF_Write(DISP_INT_STA_HOST, DF_Read(DISP_INT_STA_HOST) | 0x20);
+
+	return IRQ_HANDLED;
+}
+#endif
+
+static void cnc_df_setup_dev(unsigned int minor_id, char * dev_name)
+{
+	device_create(cnc_df_class, NULL, MKDEV(DF_MAJOR, minor_id), NULL, dev_name);
+	df_dev[minor_id].dev_minor = minor_id;
+	df_dev[minor_id].dev_type = minor_id;
+	df_dev[minor_id].enable = 0;
+	df_dev[minor_id].tve_format = TVOUT_MODE_576I;
+	df_dev[minor_id].name = dev_name;
+}
+
+void __cnc_init_vpp(void)
+{
+    df_compositor_reg comp;
+
+    memset((void*)&comp, 0, sizeof(comp));
+
+    /*b2 bg*/
+    comp.reg_comp_b2_back_ground.bits.blending2_bg_y= 0;//Blend2.BgY;
+    comp.reg_comp_b2_back_ground.bits.blending2_bg_u= 128<<2;//Blend2.BgU;
+    comp.reg_comp_b2_back_ground.bits.blending2_bg_v= 128<<2;//Blend2.BgV;
+    /*b3 bg*/
+    comp.reg_comp_b3_back_ground.bits.blending3_bg_y= 0;//Blend3.BgY;
+    comp.reg_comp_b3_back_ground.bits.blending3_bg_u= 128<<2;//Blend3.BgU;
+    comp.reg_comp_b3_back_ground.bits.blending3_bg_v= 128<<2;//Blend3.BgV;
+
+    /*b2 order*/
+    comp.reg_comp_b2_z_order.bits.blending2_gfx1_z_order= 0;//Blend2.G1Order;
+    comp.reg_comp_b2_z_order.bits.blending2_gfx2_z_order= 1;//Blend2.G2Order;
+    comp.reg_comp_b2_z_order.bits.blending2_video1_z_order= 2;//Blend2.V1Order;
+    comp.reg_comp_b2_z_order.bits.blending2_video2_z_order= 3;//Blend2.V2Order;
+    /*b3 order*/
+    comp.reg_comp_b3_z_order.bits.blending3_gfx1_z_order= 1;//Blend3.G1Order;
+    comp.reg_comp_b3_z_order.bits.blending3_video1_z_order= 2;//Blend3.V1Order;
+
+    /*b2 alpha*/
+    comp.reg_comp_b2_default_alpha.bits.blending2_default_alpha1=0x3ff;
+    comp.reg_comp_b2_default_alpha.bits.blending2_default_alpha2=0x3ff;
+    /*b3 alpha*/
+    comp.reg_comp_b3_default_alpha.bits.blending3_default_alpha1=0x3ff;//--TBD
+
+    /*adjust*/
+    comp.reg_comp_color_adjust.bits.enh_bright= 0x0;//Color.Bright;
+    comp.reg_comp_color_adjust.bits.enh_contrast= 0x20;//Color.Contrast;
+    comp.reg_comp_color_adjust.bits.enh_saturation= 0x40;//Color.Saturation;
+    /*sharpness*/
+    comp.reg_comp_sharp_c.bits.enh_c_sharp_en= 1;//Color.sharp_en;// --TBD
+    comp.reg_comp_sharp_c.bits.enh_c_median_en=0;
+    comp.reg_comp_sharp_c.bits.enh_c_coring_soft=1;
+    comp.reg_comp_sharp_c.bits.enh_c_peaking_shrink=0;
+    comp.reg_comp_sharp_c.bits.enh_c_coring=0;
+    comp.reg_comp_sharp_c.bits.enh_c_bpw=0;
+    comp.reg_comp_sharp_c.bits.enh_c_hpw=0;
+
+    comp.reg_comp_sharp_y.bits.enh_y_sharp_en=1;
+    comp.reg_comp_sharp_y.bits.enh_y_median_en=0;
+    comp.reg_comp_sharp_y.bits.enh_y_coring_soft=1;// soft/hardware
+    comp.reg_comp_sharp_y.bits.enh_y_peaking_shrink=0;
+    comp.reg_comp_sharp_y.bits.enh_y_coring=0;
+    comp.reg_comp_sharp_y.bits.enh_y_bpw=0;
+    comp.reg_comp_sharp_y.bits.enh_y_hpw=0;
+
+    /*b2 bg*/
+    DF_Write(VPP_REG_COMP_B2_BACK_GROUND, comp.reg_comp_b2_back_ground.val);
+    /*b2 alpha*/
+    DF_Write(VPP_REG_COMP_B2_DEFAULT_ALPHA, comp.reg_comp_b2_default_alpha.val);
+    /*b2 order*/
+    //DF_Write(VPP_REG_COMP_B2_Z_ORDER, comp.reg_comp_b2_z_order.val);
+    /*b3 bg*/
+    DF_Write(VPP_REG_COMP_B3_BACK_GROUND, comp.reg_comp_b3_back_ground.val);
+    /*b3 alpha*/
+    DF_Write(VPP_REG_COMP_B3_DEFAULT_ALPHA, comp.reg_comp_b3_default_alpha.val);
+    /*b3 order*/
+    DF_Write(VPP_REG_COMP_B3_Z_ORDER, comp.reg_comp_b3_z_order.val);
+    /*adjust*/
+    DF_Write(VPP_REG_COMP_COLOR_ADJUST, comp.reg_comp_color_adjust.val);
+    /*sharpness*/
+    DF_Write(VPP_REG_COMP_SHARP_C_CTRL, comp.reg_comp_sharp_c.val);
+    DF_Write(VPP_REG_COMP_SHARP_Y_CTRL, comp.reg_comp_sharp_y.val);
+}
+
+static int __init cnc_df_init(void)
+{
+	clock_df_enaclock(_clock_enable);
+	clock_video_enaclock(_clock_enable);
+	clock_coda_enaclock(_clock_enable);
+	clock_jpeg_enaclock(_clock_enable);
+//#ifndef CONFIG_CELESTIAL_OTT_EMMC //Jack, if disable the fowllowing two lines, video will do not work
+	clock_vpb_enaclock(_clock_enable);
+	clock_vpbinput_enaclock(_clock_enable);
+//#endif
+
+	if (register_chrdev(DF_MAJOR, "cnc1900_df", &cnc_df_fops)){
+		__df_mem_destroy();
+		return -ENODEV;
+	}
+
+	cnc_df_class = class_create(THIS_MODULE,"cnc1900_df");
+	if (IS_ERR(cnc_df_class)){
+		printk(KERN_ERR "DF: class create failed.\n");
+		cnc_df_class = NULL;
+		return -ENODEV;
+	}
+
+	cnc_df_setup_dev(DF_MINOR_GFX0,  "cnc_1900_df_gfx0");
+	cnc_df_setup_dev(DF_MINOR_GFX1,  "cnc_1900_df_gfx1" );
+	cnc_df_setup_dev(DF_MINOR_VID0,  "cnc_1900_df_video0");
+	cnc_df_setup_dev(DF_MINOR_VID1,  "cnc_1900_df_video1");
+	cnc_df_setup_dev(DF_MINOR_OUT0,  "cnc_1900_df_output0");
+	cnc_df_setup_dev(DF_MINOR_OUT1,  "cnc_1900_df_output1");
+	cnc_df_setup_dev(DF_MINOR_TVE0,  "cnc_1900_tvout0");
+	cnc_df_setup_dev(DF_MINOR_TVE1,  "cnc_1900_tvout1");
+	cnc_df_setup_dev(DF_MINOR_VIDAUX,  "cnc_1900_df_vidaux");
+
+	__df_mem_initialize();
+
+	cnc_df_proc_entry = create_proc_entry("df19_io", 0, NULL);
+	if (NULL != cnc_df_proc_entry) {
+		cnc_df_proc_entry->write_proc = &df_proc_write;
+	}
+
+    //must be put after __df_mem_initialize() Jack.Sun 2013.8.8
+    //initialization tg1 tg2 alpha zorder sharpness bright contrast saturation and colors of background[2-3]
+    __cnc_init_vpp();
+
+	DF_Write(VPP_REG_GLB_CTRL_INT_MSK_HOST, DF_Read(VPP_REG_GLB_CTRL_INT_MSK_HOST) | 0x28);
+
+	if (request_irq(DISP1_IRQ, cnc_outif0_irq, 0, "cnc_df0", NULL)) {
+		printk(KERN_ERR "csdrv_df: cannot register outif0 IRQ \n");
+		return -EIO;
+	}
+
+#if 0
+	if (request_irq(25, cnc_outif1_irq, 0, "cs_df1", NULL)) {
+		printk(KERN_ERR "csdrv_df: cannot register outif1 IRQ \n");
+		return -EIO;
+	}
+#endif
+
+	printk("CNC1900L Display System Version : 0.2\n");
+
+	printk(KERN_INFO "%s: CNC Display feeder driver was initialized, at address@[phyical addr = %08x, size = %x] \n",
+			"cnc1800l_df", VPP_REG_BASE, VPP_REG_SIZE);
+	printk(KERN_INFO "%s: CNC TVE0 driver was initialized, at address@[phyical addr = %08x, size = %x] \n",
+			"cnc1800l_df", TVE0_REG_BASE, TVE0_REG_SIZE);
+	printk(KERN_INFO "%s: CNC TVE1 driver was initialized, at address@[phyical addr = %08x, size = %x] \n",
+			"cnc1800l_df", TVE1_REG_BASE, TVE1_REG_SIZE);
+
+	return 0;
+}
+
+inline static void cnc_df_remove_dev(dev_t df_dev)
+{
+	device_destroy(cnc_df_class,df_dev);
+}
+
+static void __exit cnc_df_exit(void)
+{
+	__df_mem_destroy();
+
+	if (NULL != cnc_df_proc_entry)
+		remove_proc_entry("df19_io", NULL);
+
+	cnc_df_remove_dev(MKDEV(DF_MAJOR, DF_MINOR_GFX0));
+	cnc_df_remove_dev(MKDEV(DF_MAJOR, DF_MINOR_GFX1));
+	cnc_df_remove_dev(MKDEV(DF_MAJOR, DF_MINOR_VID0));
+	cnc_df_remove_dev(MKDEV(DF_MAJOR, DF_MINOR_VID1));
+	cnc_df_remove_dev(MKDEV(DF_MAJOR, DF_MINOR_OUT0));
+	cnc_df_remove_dev(MKDEV(DF_MAJOR, DF_MINOR_OUT1));
+	cnc_df_remove_dev(MKDEV(DF_MAJOR, DF_MINOR_TVE0));
+	cnc_df_remove_dev(MKDEV(DF_MAJOR, DF_MINOR_TVE1));
+	cnc_df_remove_dev(MKDEV(DF_MAJOR, DF_MINOR_VIDAUX));
+
+	class_destroy(cnc_df_class);
+	unregister_chrdev(DF_MAJOR, "cnc_df");
+	printk(KERN_INFO "CNC DF Exit ...... OK. \n");
+
+	return;
+}
+
+postcore_initcall(cnc_df_init);
+
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/celestial/df/df_output_format.h linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/df/df_output_format.h
--- linux-linaro-3.4-2012.05-1_original/drivers/celestial/df/df_output_format.h	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/df/df_output_format.h	2015-04-16 19:50:45.310836000 +0800
@@ -0,0 +1,102 @@
+#ifndef _CSM_OUTPUT_FORMAT_H
+#define _CSM_OUTPUT_FORMAT_H
+
+static  df_out_if_timing outputFormatInfo[] =
+{
+ //                 Frequency IsHD VSyncPol  HSyncPol   HTol   HActive HSyncFP HSyncWidth HSyncBP   VTol  VActline VSyncFP VSyncWidth VSyncBP VidType Vidrptr 
+ //(KHZ)   
+	{ 1,1280, 720,60, 74250,    1,  0,         0,       1650,  1280,    110,      40,      220,      750,   720,      5,       5,        20,   0,      0, 0,      0, 0,0, DISP_YUV_720P_60FPS,         "DISP_YUV_720P_60FPS"        },
+	{ 1,1920,1080,30, 74250,    1,  0,         0,       2200,  1920,     88,      44,      148,     1125,   1080,     2,       5,        15,    0,      0,1,      0, 0,0, DISP_YUV_1080I_30FPS,        "DISP_YUV_1080I_30FPS"       },
+	{ 1, 720, 480,60, 27000,    0,  1,         1,        858,   720,     16,      62,       60,      525,   480,      9,       6,        30,   0,      0, 0,      0, 0,0, DISP_YUV_480P,               "DISP_YUV_480P"              },
+	{ 1, 720, 480,30, 27000,    1,  1,         1,       1716/2,  1440/2,     38/2,     124/2,      114/2,      525,   480,      4,       3,        15,    0,      0,1,      1, 1,0, DISP_YUV_NTSC,               "DISP_YUV_NTSC"              },
+	{ 1,1280, 720,50, 74250,    1,  0,         0,       1980,  1280,    440,      40,      220,      750,   720,      5,       5,        20,    0,      0,0,      0, 0,0, DISP_YUV_720P_50FPS,         "DISP_YUV_720P_50FPS"        },
+	{ 1,1920,1080,25, 74250,    1,  0,         0,       2640,  1920,    528,      44,      148,     1125,   1080,     2,       5,        15,    0,      0,1,      0, 0,0, DISP_YUV_1080I_25FPS,        "DISP_YUV_1080I_25FPS"       },
+	{ 1, 720, 576,50, 27000,    0,  1,         1,        864,   720,     12,      64,       68,      625,   576,      5,       5,        39,    0,      0,0,      0, 0,0, DISP_YUV_576P,               "DISP_YUV_576P"              },
+	{ 1, 720, 576,25, 27000,    1,  1,         1,       1728/2,  1440/2,     24/2,     126/2,      138/2,      625,   576,      2,       3,        19,    0,      0,1,      1, 1,1, DISP_YUV_PAL,                "DISP_YUV_PAL"               },
+	{ 1,1920,1080,60,148500,    1,  0,         0,       2200,  1920,     88,      44,      148,     1125,  1080,      4,       5,        36,    0,      0,0,      0, 0,0, DISP_YUV_1080P_60FPS,        "DISP_YUV_1080P_60FPS"       },
+	{ 1,1920,1080,50,148500,    1,  0,         0,       2640,  1920,    528,      44,      148,     1125,  1080,      4,       5,        36,    0,      0,0,      0, 0,0, DISP_YUV_1080P_50FPS,        "DISP_YUV_1080P_50FPS"       },
+	{ 1,1920,1080,24, 74250,    1,  0,         0,       2750,  1920,    638,      44,      148,     1125,  1080,      4,       5,        36,    0,      0,0,      0, 0,0, DISP_YUV_1080P_24FPS,        "DISP_YUV_1080P_24FPS"       },
+	{ 1,1920,1080,25, 74250,    1,  0,         0,       2640,  1920,    528,      44,      148,     1125,  1080,      4,       5,        36,    0,      0,0,      0, 0,0, DISP_YUV_1080P_25FPS,        "DISP_YUV_1080P_25FPS"       },
+	{ 1,1920,1080,30, 74250,    1,  0,         0,       2200,  1920,     88,      44,      148,     1125,  1080,      4,       5,        36,    0,      0,0,      0, 0,0, DISP_YUV_1080P_30FPS,        "DISP_YUV_1080P_30FPS"       },
+	{ 1,1920,1080,25, 72000,    1,  1,         0,       2304,  1920,     32,     168,      184,     1250,  1080,     23,       5,        57,    0,      0,1,      0, 0,0, DISP_YUV_1080I_25FPS_AS,     "DISP_YUV_1080I_50FPS_F1"    },
+	{ 0, 640, 480,60, 25200,    0,  1,         1,        800,   640,     16,      96,       48,      525,   480,     10,       2,        33,    0,      0,      0,      0, 0,0, DISP_RGB_VGA_60FPS,          "DISP_RGB_VGA_60FPS"         },
+	{ 0, 800, 600,60, 40000,    0,  0,         0,       1056,   800,     40,     128,       88,      628,   600,      1,       4,        23,    0,      0,      0,      0, 0,0, DISP_RGB_SVGA_60FPS,         "DISP_RGB_SVGA_60FPS"        },
+	{ 0,1024, 768,60, 65000,    0,  1,         1,       1344,  1024,     24,     136,      160,      806,   768,      3,       6,        29,    0,      0,      0,      0, 0,0, DISP_RGB_XGA_60FPS,          "DISP_RGB_XGA_60FPS"         },
+	{ 0,1280,1024,60,108000,    1,  0,         0,       1688,  1280,     48,     112,      248,     1066,  1024,      1,       3,        38,    0,      0,      0,      0, 0,0, DISP_RGB_SXGA_60FPS,         "DISP_RGB_SXGA_60FPS"        },
+	{ 0,1600,1200,60,162000,    1,  0,         0,       2160,  1600,     64,     192,      304,     1250,  1200,      1,       3,        46,    0,      0,      0,      0, 0,0, DISP_RGB_UXGA_60FPS,         "DISP_RGB_UXGA_60FPS"        },
+	{ 0,1280, 720,60, 74375,    1,  0,         0,       1664,  1280,     56,     136,      192,      746,   720,      1,       3,        22,    0,      0,      0,      0, 0,0, DISP_RGB_720P_60FPS,         "DISP_RGB_720P_60FPS"        },
+	{ 1, 360, 288,50, 27000,    0,  1,         1,       1728,  1440,     24,     126,      138,      312,   288,      2,       3,        19,    0,      0,      0,      1, 0,0, DISP_1440x288P_50_M1,        "DISP_1440x288P_50_M1"       },
+	{ 1, 360, 288,50, 27000,    0,  1,         1,       1728,  1440,     24,     126,      138,      313,   288,      3,       3,        19,    0,      0,      0,      1, 0,0, DISP_1440x288P_50_M2,        "DISP_1440x288P_50_M2"       },
+	{ 1, 360, 288,50, 27000,    0,  1,         1,       1728,  1440,     24,     126,      138,      314,   288,      4,       3,        19,    0,      0,      0,      1, 0,0, DISP_1440x288P_50_M3,        "DISP_1440x288P_50_M3"       },
+	{ 1, 720, 576,25, 54000,    0,  1,         1,       3456,  2880,     48,     252,      276,      625,   576,      2,       3,        19,    0,      0,      1,      3, 0,1, DISP_2880x576I_50,           "DISP_2880x576I_50"          },
+	{ 1, 720, 288,50, 54000,    0,  1,         1,       3456,  2880,     48,     252,      276,      312,   288,      2,       3,        19,    0,      0,      0,      3, 0,0, DISP_2880x288P_50_M1,        "DISP_2880x288P_50_M1"       },
+	{ 1, 720, 288,50, 54000,    0,  1,         1,       3456,  2880,     48,     252,      276,      313,   288,      3,       3,        19,    0,      0,      0,      3, 0,0, DISP_2880x288P_50_M2,        "DISP_2880x288P_50_M2"       },
+	{ 1, 720, 288,50, 54000,    0,  1,         1,       3456,  2880,     48,     252,      276,      314,   288,      4,       3,        19,    0,      0,      0,      3, 0,0, DISP_2880x288P_50_M3,        "DISP_2880x288P_50_M3"       },
+	{ 1, 720, 576,50, 54000,    0,  1,         1,       1728,  1440,     24,     128,      136,      625,   576,      5,       5,        39,    0,      0,      0,      1, 0,0, DISP_1440x576P_50,           "DISP_1440x576P_50"          },
+	{ 1, 720, 240,60, 27000,    0,  1,         1,       1716,  1440,     38,     124,      114,      262,   240,      4,       3,        15,    0,      0,      0,      1, 0,0, DISP_1440x240P_60_M1,        "DISP_1440x240P_60_M1"       },
+	{ 1, 720, 240,60, 27000,    0,  1,         1,       1716,  1440,     38,     124,      114,      263,   240,      5,       3,        15,    0,      0,      0,      1, 0,0, DISP_1440x240P_60_M2,        "DISP_1440x240P_60_M2"       },
+	{ 1, 720, 480,30, 54000,    0,  1,         1,       3432,  2880,     76,     248,      228,      525,   480,      4,       3,        15,    0,      0,      1,      3, 0,0, DISP_2880x480I_60,           "DISP_2880x480I_60"          },
+	{ 1, 720, 240,60, 54000,    0,  1,         1,       3432,  2880,     76,     248,      228,      262,   240,      4,       3,        15,    0,      0,      0,      3, 0,0, DISP_2880x240P_60_M1,        "DISP_2880x240P_60_M1"       },
+	{ 1, 720, 240,60, 54000,    0,  1,         1,       3432,  2880,     76,     248,      228,      263,   240,      5,       3,        15,    0,      0,      0,      3, 0,0, DISP_2880x240P_60_M2,        "DISP_2880x240P_60_M2"       },
+	{ 1, 720, 480,60, 54000,    0,  1,         1,       1716,  1440,     32,     124,      120,      525,   480,      9,       6,        30,    0,      0,      0,      1, 0,0, DISP_1440x480P_60,           "DISP_1440x480P_60"          },
+	{ 0, 640, 480,60, 25175,    0,  1,         1,        800,   640,      8,      96,       40,      525,   480,     10,       2,        33,    0,      0,      0,      0, 0,0, DISP_RGB_DMT_640x480_60,     "DISP_RGB_DMT_640x480_60"    },
+	{ 0, 640, 480,75, 31500,    0,  1,         1,        840,   640,     16,      64,      120,      500,   480,      1,       3,        16,    0,      0,      0,      0, 0,0, DISP_RGB_DMT_640x480_75,     "DISP_RGB_DMT_640x480_75"    },
+	{ 0, 800, 600,60, 40000,    0,  0,         0,       1056,   800,     40,     128,       88,      628,   600,      1,       4,        23,    0,      0,      0,      0, 0,0, DISP_RGB_DMT_800x600_60,     "DISP_RGB_DMT_800x600_60"    },
+	{ 0, 800, 600,75, 49500,    0,  0,         0,       1056,   800,     16,      80,      160,      625,   600,      1,       3,        21,    0,      0,      0,      0, 0,0, DISP_RGB_DMT_800x600_75,     "DISP_RGB_DMT_800x600_75"    },
+	{ 0, 848, 480,60, 33750,    0,  0,         0,       1088,   848,     16,     112,      112,      517,   480,      6,       8,        23,    0,      0,      0,      0, 0,0, DISP_RGB_DMT_848x480_60,     "DISP_RGB_DMT_848x480_60"    },
+	{ 0,1152, 864,75,108000,    1,  0,         0,       1600,  1152,     64,     128,      256,      900,   864,      1,       3,        32,    0,      0,      0,      0, 0,0, DISP_RGB_DMT_1152x864_75,    "DISP_RGB_DMT_1152x864_75"   },
+	{ 0,1280, 768,60, 68250,    1,  1,         0,       1440,  1280,     48,      32,       80,      790,   768,      3,       7,        12,    0,      0,      0,      0, 0,0, DISP_RGB_DMT_1280x768_60,    "DISP_RGB_DMT_1280x768_60"   },
+	{ 0,1280, 960,60,108000,    1,  0,         0,       1800,  1280,     96,     112,      312,     1000,   960,      1,       3,        36,    0,      0,      0,      0, 0,0, DISP_RGB_DMT_1280x960_60,    "DISP_RGB_DMT_1280x960_60"   },
+	{ 0,1280,1024,60,108000,    1,  0,         0,       1688,  1280,     48,     112,      248,     1066,  1024,      1,       3,        38,    0,      0,      0,      0, 0,0, DISP_RGB_DMT_1280x1024_60,   "DISP_RGB_DMT_1280x1024_60"  },
+	{ 0,1360, 768,60, 85500,    1,  0,         0,       1792,  1360,     64,     112,      256,      795,   768,      3,       6,        18,    0,      0,      0,      0, 0,0, DISP_RGB_DMT_1360x768_60,    "DISP_RGB_DMT_1360x768_60"   },
+	{ 0,1440, 900,60,106500,    1,  0,         1,       1904,  1440,     80,     152,      232,      934,   900,      3,       6,        25,    0,      0,      0,      0, 0,0, DISP_RGB_DMT_1440x900_60,    "DISP_RGB_DMT_1440x900_60"   },
+	{ 0, 640, 480,75, 30625,    0,  0,         1,        816,   640,     24,      64,       88,      502,   480,      1,       3,        18,    0,      0,      0,      0, 0,0, DISP_RGB_CVT_640x480_75,     "DISP_RGB_CVT_640x480_75"    },
+	{ 0, 800, 600,60, 38125,    0,  0,         1,       1024,   800,     32,      80,      112,      622,   600,      1,       3,        18,    0,      0,      0,      0, 0,0, DISP_RGB_CVT_800x600_60,     "DISP_RGB_CVT_800x600_60"    },
+	{ 0, 800, 600,75, 48875,    0,  0,         1,       1040,   800,     40,      80,      120,      627,   600,      1,       3,        23,    0,      0,      0,      0, 0,0, DISP_RGB_CVT_800x600_75,     "DISP_RGB_CVT_800x600_75"    },
+	{ 0,1024, 768,60, 64125,    1,  0,         1,       1344,  1024,     56,     112,      168,      802,   768,      1,       3,        30,    0,      0,      0,      0, 0,0, DISP_RGB_CVT_1024x768_60,    "DISP_RGB_CVT_1024x768_60"   },
+	{ 0,1280,1024,60,108875,    1,  0,         1,       1712,  1280,     80,     136,      216,     1060,  1024,      1,       3,        41,    0,      0,      0,      0, 0,0, DISP_RGB_CVT_1280x1024_60,   "DISP_RGB_CVT_1280x1024_60"  },
+	{ 0, 848, 480,60, 31500,    0,  0,         1,       1056,   848,     16,      88,      104,      497,   480,      1,       3,        13,    0,      0,      0,      0, 0,0, DISP_RGB_CVT_848x480_60,     "DISP_RGB_CVT_848x480_60"    },
+	{ 0, 848, 480,75, 40875,    0,  0,         1,       1088,   848,     32,      88,      120,      502,   480,      1,       3,        18,   0,      0,      0,      0, 0,0, DISP_RGB_CVT_848x480_75,     "DISP_RGB_CVT_848x480_75"    },
+	{ 0,1024, 576,60, 46875,    1,  0,         1,       1312,  1024,     40,     104,      144,      597,   576,      1,       3,        17,    0,      0,      0,      0, 0,0, DISP_RGB_CVT_1024x576_60,    "DISP_RGB_CVT_1024x576_60"   },
+	{ 0,1024, 576,75, 60625,    1,  0,         1,       1344,  1024,     56,     104,      160,      602,   576,      1,       3,        22,    0,      0,      0,      0, 0,0, DISP_RGB_CVT_1024x576_75,    "DISP_RGB_CVT_1024x576_75"   },
+	{ 0,1280, 720,60, 74375,    1,  0,         1,       1664,  1280,     56,     136,      192,      746,   720,      1,       3,        22,    0,      0,      0,      0, 0,0, DISP_RGB_CVT_1280x720_60,    "DISP_RGB_CVT_1280x720_60"   },
+	{ 0,1280, 720,75, 95625,    1,  0,         1,       1696,  1280,     72,     136,      208,      752,   720,      1,       3,        28,    0,      0,      0,      0, 0,0, DISP_RGB_CVT_1280x720_75,    "DISP_RGB_CVT_1280x720_75"   },
+	{ 0, 640, 400,75, 25000,    0,  0,         1,        800,   640,     16,      64,       80,      418,   400,      1,       3,        14,    0,      0,      0,      0, 0,0, DISP_RGB_CVT_640x400_75,     "DISP_RGB_CVT_640x400_75"    },
+	{ 0, 768, 480,60, 28625,    0,  0,         1,        960,   768,     16,      80,       96,      497,   480,      1,       3,        13,    0,      0,      0,      0, 0,0, DISP_RGB_CVT_768x480_60,     "DISP_RGB_CVT_768x480_60"    },
+	{ 0, 768, 480,75, 37250,    0,  0,         1,        992,   768,     32,      80,      112,      502,   480,      1,       3,        18,    0,      0,      0,      0, 0,0, DISP_RGB_CVT_768x480_75,     "DISP_RGB_CVT_768x480_75"    },
+	{ 0,1024, 640,60, 52750,    1,  0,         1,       1328,  1024,     48,     104,      152,      663,   640,      1,       3,        19,    0,      0,      0,      0, 0,0, DISP_RGB_CVT_1024x640_60,    "DISP_RGB_CVT_1024x640_60"   },
+	{ 0,1024, 640,75, 67375,    1,  0,         1,       1344,  1024,     56,     104,      160,      669,   640,      1,       3,        25,    0,      0,      0,      0, 0,0, DISP_RGB_CVT_1024x640_75,    "DISP_RGB_CVT_1024x640_75"   },
+	{ 0,1280, 800,75,107250,    1,  0,         1,       1712,  1280,     80,     136,      216,      835,   800,      1,       3,        31,    0,      0,      0,      0, 0,0, DISP_RGB_CVT_1280x800_75,    "DISP_RGB_CVT_1280x800_75"   },
+	{ 0, 800, 600,60, 34375,    0,  1,         0,        928,   800,     32,      32,       64,      618,   600,      1,       3,        14,    0,      0,      0,      0, 0,0, DISP_RGB_CVT_800x600_RED,    "DISP_RGB_CVT_800x600_RED"   },
+	{ 0,1024, 768,60, 54500,    1,  1,         0,       1152,  1024,     32,      32,       64,      790,   768,      1,       3,        18,    0,      0,      0,      0, 0,0, DISP_RGB_CVT_1024x768_RED,   "DISP_RGB_CVT_1024x768_RED"  },
+	{ 0,1280, 960,60, 83375,    1,  1,         0,       1408,  1280,     32,      32,       64,      988,   960,      1,       3,        24,    0,      0,      0,      0, 0,0, DISP_RGB_CVT_1280x960_RED,   "DISP_RGB_CVT_1280x960_RED"  },
+	{ 0, 848, 480,60, 28875,    0,  1,         0,        976,   848,     32,      32,       64,      494,   480,      1,       3,        10,    0,      0,      0,      0, 0,0, DISP_RGB_CVT_848x480_RED,    "DISP_RGB_CVT_848x480_RED"   },
+	{ 0,1024, 576,60, 40875,    1,  1,         0,       1152,  1024,     32,      32,       64,      593,   576,      1,       3,        13,    0,      0,      0,      0, 0,0, DISP_RGB_CVT_1024x576_RED,   "DISP_RGB_CVT_1024x576_RED"  },
+	{ 0,1280, 720,60, 62500,    1,  1,         0,       1408,  1280,     32,      32,       64,      741,   720,      1,       3,        17,    0,      0,      0,      0, 0,0, DISP_RGB_CVT_1280x720_RED,   "DISP_RGB_CVT_1280x720_RED"  },
+	{ 0,1600, 900,60, 96000,    1,  1,         0,       1728,  1600,     32,      32,       64,      926,   900,      1,       3,        22,    0,      0,      0,      0, 0,0, DISP_RGB_CVT_1600x900_RED,   "DISP_RGB_CVT_1600x900_RED"  },
+	{ 0, 768, 480,60, 26500,    0,  1,         0,        896,   768,     32,      32,       64,      494,   480,      1,       3,        10,    0,      0,      0,      0, 0,0, DISP_RGB_CVT_768x480_RED,    "DISP_RGB_CVT_768x480_RED"   },
+	{ 0,1024, 640,60, 45500,    1,  1,         0,       1152,  1024,     32,      32,       64,      659,   640,      1,       3,        15,    0,      0,      0,      0, 0,0, DISP_RGB_CVT_1024x640_RED,   "DISP_RGB_CVT_1024x640_RED"  },
+	{ 0,1280, 800,60, 69500,    1,  1,         0,       1408,  1280,     32,      32,       64,      823,   800,      1,       3,        19,    0,      0,      0,      0, 0,0, DISP_RGB_CVT_1280x800_RED,   "DISP_RGB_CVT_1280x800_RED"  },
+	{ 0,1600,1000,60,106625,    1,  1,         0,       1728,  1600,     32,      32,       64,     1029,  1000,      1,       3,        25,    0,      0,      0,      0, 0,0, DISP_RGB_CVT_1600x1000_RED,  "DISP_RGB_CVT_1600x1000_RED" },
+	{ 1,  64, 64, 60, 11111,    0,  1,         1,       128,    64,     20,      10,        34,     128,    64,       1,       3,        60,    0,      0,      0,      0, 0,0, DISP_64x64,"DISP_64x64"},
+    { 1,1366, 768,60, 85500,    1,  0,         0,       1792,  1366,    70,      143,       213,     798,   768,      3,       3,        24,    0,      0,      0,      0, 0,0, DISP_VGA_1366x768,"DISP_VGA_1366x768"},
+	{ 1, 720, 480,60, 54000,    0,  1,         1,        858,   720,     16,      62,       60,      525,   480,      9,       6,        30,    1,      45,      0,      0, 0,0, DISP_YUV_480P_3D,               "DISP_YUV_480P_3D"              },
+	//{ 1, 720, 480,30, 54000,    0,  1,         1,       1716,  1440,     38,     124,      114,      525,   480,      4,       3,        15,    1,      23,      1,      1, 1,0, DISP_YUV_NTSC_3D,               "DISP_YUV_NTSC_3D"              },
+	{ 1, 720, 480,30, 54000,    0,  1,         1,       858,   720,     16,      62,       60,      525,   480,      4,       3,        15,    1,      23,      1,      1, 1,0, DISP_YUV_NTSC_3D,               "DISP_YUV_NTSC_3D"              },
+	{ 1, 720, 576,50, 54000,    0,  1,         1,        864,   720,     12,      64,       68,      625,   576,      5,       5,        39,    1,      49,      0,      0, 0,0, DISP_YUV_576P_3D,               "DISP_YUV_576P_3D"              },
+	{ 1, 720, 576,25, 54000,    0,  1,         1,       1728,  1440,     24,     126,      138,      625,   576,      2,       3,        19,    1,      25,      1,      1, 1,1, DISP_YUV_PAL_3D,                "DISP_YUV_PAL_3D"               },
+	{ 1,1280, 720,60, 74250,    1,  0,         0,       1650,  1280,    110,      40,      220,      750,   720,      5,       5,        20,   1,      30, 		0,      0, 0,0, DISP_YUV_720P_60FPS_3D,         "DISP_YUV_720P_60FPS_3D"        },
+	{ 1,1920,1080,30, 74250,    1,  0,         0,       2200,  1920,     88,      44,      148,     1125,  1080,      4,       5,        36,    1,      45,		0,      0, 0,0, DISP_YUV_1080P_30FPS_3D,        "DISP_YUV_1080P_30FPS_3D"       },
+	{ 1,1920,1080,30, 74250,    1,  0,         0,       2200,  1920,     88,      44,      148,     1125,   1080,     2,       5,        15,    1,      23,		1,      0, 0,0, DISP_YUV_1080I_30FPS_3D,        "DISP_YUV_1080I_30FPS_3D"       },
+	{ 1,1280, 720,50, 74250,    1,  0,         0,       1980,  1280,    440,      40,      220,      750,   720,      5,       5,        20,    1,      30,		0,      0, 0,0, DISP_YUV_720P_50FPS_3D,         "DISP_YUV_720P_50FPS_3D"        },
+	{ 1,1920,1080,24, 74250,    1,  0,         0,       2750,  1920,    638,      44,      148,     1125,  1080,      4,       5,        36,    1,      45,		0,      0, 0,0, DISP_YUV_1080P_24FPS_3D,        "DISP_YUV_1080P_24FPS_3D"       },
+	{ 1,1920,1080,25, 74250,    1,  0,         0,       2640,  1920,    528,      44,      148,     1125,  1080,      4,       5,        36,    1,      45,		0,      0, 0,0, DISP_YUV_1080P_25FPS_3D,        "DISP_YUV_1080P_25FPS_3D"       },
+	{ 1,1280, 720,30, 74250,    1,  0,         0,       1650,  1280,    110,      40,      220,      750,   720,      5,       5,        20,   1,      30, 		0,      0, 0,0, DISP_YUV_720P_30FPS_3D,         "DISP_YUV_720P_30FPS_3D"        },
+	{ 1,1920,1080,30, 74250,    1,  0,         0,       2200,  1920,     88,      44,      148,     1125,   530,      4,       5,        36,    1,      20,		0,      0, 0,0, DISP_YUV_1080P_30FPS_3D_TEMP,        "DISP_YUV_1080P_30FPS_3D_TEMP"       },
+	{ 1,1920,1080,30, 74250,    1,  0,         0,       2200,  1920,     88,      44,      148,      500,   250*2,     4,       5,        36,    1,      17,		1,      0, 0,0, DISP_YUV_1080I_30FPS_3D_TEMP,        "DISP_YUV_1080I_30FPS_3D_TEMP"       },
+	{ 0, 640, 480,60, 25175,    0,  1,         1,        800,   640,     16,      96,       48,      525,   480,     10,       2,        33,    0,      0,      0,      0, 0,0, DISP_RGB_VGA_59P94FPS,          "DISP_RGB_VGA_59P94FPS"         },
+	{ 0,1600,1200,60,162000,    1,  0,         0,       2160,  1600,     64,     192,      304,     1250,   1200,     1,       3,        46,    0,      0,      0,      0, 0,0, DISP_1600x1200_60FPS,          "DISP_1600x1200_60FPS"         }
+	//              Frequency IsHD VSyncPol  HSyncPol   HTol   HActive HSyncFP HSyncWidth HSyncBP   VTol  VActline VSyncFP VSyncWidth VSyncBP 3dEn 	VactSpace 	VidType 	Vidrptr
+};
+
+#endif
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/celestial/df/Kconfig linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/df/Kconfig
--- linux-linaro-3.4-2012.05-1_original/drivers/celestial/df/Kconfig	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/df/Kconfig	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,45 @@
+
+menu "Celestial DF Drivers"
+	
+if ARCH_CELESTIAL
+config CELESTIAL_DF
+	bool "CNC1900 Display"
+	depends on ARCH_CELESTIAL
+	default y
+	help 
+	Include support drvier for DF of celestial platform
+endif
+
+if CELESTIAL_DF
+config HD2SD_ENABLE
+       bool "HD2SD (passthrough HDMI to CVBS)"
+       depends on CELESTIAL_DF
+       help
+            enable passthrough HDMI to CVBS or disable only HDMI       
+endif
+
+if CELESTIAL_DF
+config YPBPR_DAC_ENABLE
+        bool "CNC1900 YPBPR DAC"
+        depends on CELESTIAL_DF
+        default n
+        help
+        Enable YPBPR DAC.
+endif
+
+config CELESTIAL_DF_DEBUG
+       bool "DF Debugging"
+       depends on CELESTIAL_DF
+       help
+         This turns on low-level debugging for the celestial df driver.
+           Normally, you should say 'N'.
+
+
+config DF_DEBUG_VERBOSE
+       int "DF Debugging verbosity (0 = quiet, 3 = noisy)"
+       depends on CELESTIAL_DF_DEBUG
+       default "0"
+       help
+         Determines the verbosity level of the df debugging messages.
+
+endmenu
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/celestial/df/Makefile linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/df/Makefile
--- linux-linaro-3.4-2012.05-1_original/drivers/celestial/df/Makefile	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/df/Makefile	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,7 @@
+#
+# Makefile for the linux kernel.
+# 
+#
+
+obj-$(CONFIG_MACH_CELESTIAL_CNC1900) +=  cnc1900_df.o
+
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/celestial/df/tve0_1900.h linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/df/tve0_1900.h
--- linux-linaro-3.4-2012.05-1_original/drivers/celestial/df/tve0_1900.h	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/df/tve0_1900.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,77 @@
+#ifndef _CSM_TVE0_H
+#define _CSM_TVE0_H
+
+//2 TVE
+#define  TVE0_REG_NUM		(45)
+#define  REG_ADDR    		(0) 
+#define  TYPE_NTSC   		(1)
+#define  TYPE_PAL    		(2)
+#define  TYPE_PAL_M  		(3)
+#define  TYPE_PAL_N  		(4)
+#define  TYPE_PAL_CN 		(5)
+#define  TYPE_SECAM  		(6)
+#define  TYPE_480p   		(7)
+#define  TYPE_720p50   		(8)
+#define  TYPE_720p60   		(9)
+#define  TYPE_1080i  		(10)
+#define  TYPE_1080i30		(11)//duliguo
+#define  TVE0_TYPE_TOTAL  	(12)
+
+//1TVE0
+
+//dont change this table
+static unsigned char TVE0_REG[TVE0_REG_NUM][TVE0_TYPE_TOTAL] =
+{
+/*      address ntsc  pal   PAL_M PAL-N PAL-CN SECAM 480p  720p50 720p60 1080i25 1080i30 */
+/*0*/   {0x00,  0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00,  0x00,  0x00,   0x00    }, //CVE_SOFT_RESET_VAL
+/*1*/   {0x01,  0x50, 0x50, 0x50, 0x50, 0x50,  0x50, 0x50, 0x50,  0x50,  0x51,   0x50    }, //CVE_REV_ID_VAL
+/*2*/   {0x02,  0x1d, 0x1d, 0x1d, 0x1d, 0x1d,  0x1d, 0x1d, 0x1d,  0x1d,  0x1c,   0x11    }, //CVE_INPUT_CTL_VAL
+/*3*/   {0x04,  0x09, 0x09, 0x09, 0x09, 0x09,  0x09, 0x09, 0x09,  0x09,  0x09,   0x09    }, //CVE_OUT_CTL_VAL
+/*4*/   {0x06,  0x01, 0x01, 0x01, 0x01, 0x01,  0x01, 0x01, 0x01,  0x01,  0x01,   0x01    }, //CVE_SLV_MD_TH_VAL
+/*5*/   {0x07,  0x00, 0x04, 0x24, 0x24, 0x34,  0x3C, 0x01, 0x03,  0x03,  0x02,   0x02    }, //CVE_VID_STD_VAL
+/*6*/   {0x08,  0x02, 0x02, 0x02, 0x02, 0x02,  0x02, 0x02, 0x02,  0x02,  0x04,   0x04    }, //CVE_NUM_LINES_H_VAL
+/*7*/   {0x09,  0x0d, 0x71, 0x0D, 0x71, 0x71,  0x71, 0x0D, 0xEE,  0xEE,  0x65,   0x65    }, //CVE_NUM_LINES_L_VAL
+/*8*/   {0x0a,  0x15, 0x17, 0x15, 0x17, 0x17,  0x17, 0x2a, 0x19,  0x19,  0x14,   20      }, //CVE_FST_VID_LINE_VAL
+/*9*/   {0x0b,  0x7e, 0x7e, 0x7e, 0x7e, 0x7e,  0x7e, 0x7e, 0x40,  0x50,  0x58,   88      }, //CVE_HSYNC_WIDTH_VAL
+/*10*/  {0x0d,  0x68, 0x80, 0x76, 0x8a, 0x8a,  0x8a, 0x68, 0xdc,  0xd0,  0x94,   148     }, //CVE_BACK_PORCH_VAL
+/*11*/  {0x0e,  0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x01,  0x00,  0x02,   0       }, //CVE_FRONT_PORCH_H_VAL
+/*12*/  {0x0f,  0x32, 0x28, 0x20, 0x18, 0x18,  0x18, 0x32, 0xb8,  0x48,  0x10,   44      }, //CVE_FRONT_PORCH_L_VAL
+/*13*/  {0x10,  0x05, 0x05, 0x05, 0x05, 0x05,  0x05, 0x05, 0x05,  0x05,  0x09,   7       }, //CVE_ACTIVELINE_H_VAL
+/*14*/  {0x11,  0x9c, 0x9a, 0xa0, 0xa0, 0xa0,  0xa0, 0x9c, 0x00,  0x0a,  0x38,   128     }, //CVE_ACTIVELINE_L_VAL
+/*15*/  {0x12,  0x44, 0x40, 0x44, 0x40, 0x44,  0x40, 0x44, 0x08,  0x08,  0x08,   8       }, //CVE_BURST_WDITH_VAL
+/*16*/  {0x13,  0x16, 0x1a, 0x12, 0x1a, 0x1a,  0x1a, 0x16, 0x08,  0x08,  0x08,   8       }, //CVE_BREEZE_WAY_VAL
+/*17*/  {0x16,  0x10, 0x15, 0x10, 0x15, 0x10,  0x14, 0x15, 0x15,  0x15,  0x15,   0x10    }, //CVE_CHROMA_FREQ_3_VAL
+/*18*/  {0x17,  0xf8, 0x04, 0xF3, 0x04, 0xFB,  0xE3, 0x04, 0x04,  0x04,  0x04,   0xf8    }, //CVE_CHROMA_FREQ_2_VAL
+/*19*/  {0x18,  0x3e, 0xc5, 0x77, 0xc5, 0x4A,  0x8E, 0xc5, 0xc5,  0xc5,  0xc5,   0x3e    }, //CVE_CHROMA_FREQ_1_VAL
+/*20*/  {0x19,  0x0f, 0x66, 0xD2, 0x66, 0x23,  0x39, 0x66, 0x66,  0x66,  0x66,   0x0f    }, //CVE_CHROMA_FREQ_0_VAL
+/*21*/  {0x1a,  0x14, 0x14, 0x14, 0x14, 0x00,  0x14, 0x14, 0x14,  0x14,  0xc5,   0x00    }, /*freq2*/
+/*22*/  {0x1b,  0x25, 0x25, 0x25, 0x00, 0x00,  0x25, 0x25, 0x25,  0x25,  0x66,   0x00    },
+/*23*/  {0x1c,  0xed, 0xed, 0xed, 0x00, 0x00,  0xed, 0xed, 0xed,  0xed,  0x00,   0x00    },
+/*24*/  {0x1d,  0x09, 0x09, 0x09, 0x00, 0x00,  0x09, 0x09, 0x09,  0x09,  0x00,   0x00    },
+/*25*/  {0x1e,  0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00,  0x00,  0x00,   0x00    }, //CVE_CHROMA_PHASE_VAL
+/*26*/  {0x1f,  0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00,  0x00,  0x00,   0x00    }, //CVE_TINT_VAL
+/*27*/  {0x20,  0x14, 0x04, 0x04, 0x04, 0x04,  0x04, 0x04, 0x04,  0x04,  0x04,   36      }, //CVE_NA_WI_CH_CH_CP_VAL
+/*28*/  {0x21,  0x44, 0x30, 0x2a, 0x2a, 0x2c,  0x00, 0x30, 0x30,  0x30,  0x30,   60      }, //CVE_CB_BURST_AMP_VAL
+/*29*/  {0x22,  0x00, 0x24, 0x1d, 0x1d, 0x1f,  0x00, 0x24, 0x24,  0x24,  0x24,   0       }, //CVE_CR_BURST_AMP_VAL
+/*30*/  {0x23,  0xa2, 0xb2, 0xa2, 0xa2, 0xa2,  0xa2, 0xb8, 0xb8,  0xb8,  0xbc,   180     }, //CVE_CB_GAIN_VAL
+/*31*/  {0x24,  0xa2, 0xb2, 0xa2, 0xa2, 0xa2,  0xa2, 0xb8, 0xb8,  0xb8,  0xbc,   180     }, //CVE_CR_GAIN_VAL
+/*32*/  {0x27,  0x02, 0x03, 0x02, 0x02, 0x02,  0x02, 0x02, 0x02,  0x02,  0x03,   3       }, //CVE_WHITE_LEVEL_H_VAL
+/*33*/  {0x28,  0xf8, 0x10, 0xf8, 0x00, 0xf8,  0xf8, 0xf8, 0xf8,  0xf8,  0x20,   32      }, //CVE_WHITE_LEVEL_L_VAL
+/*34*/  {0x29,  0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00,  0x00,  0x00,   0       }, //CVE_BLACK_LEVEL_H_VAL
+/*35*/  {0x2a,  0xb0, 0xb0, 0xb0, 0xb0, 0xb0,  0xb0, 0xb0, 0xfb,  0xfb,  0xfc,   208     }, //CVE_BLACK_LEVEL_L_VAL
+/*36*/  {0x2b,  0x01, 0x01, 0x01, 0x01, 0x01,  0x01, 0x01, 0x01,  0x01,  0x00,   0       }, //CVE_BLANK_LEVEL_H_VAL
+/*37*/  {0x2c,  0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00,  0x00,  0xfc,   251     }, //CVE_BLANK_LEVEL_L_VAL
+/*38*/  {0x2d,  0x01, 0x01, 0x01, 0x01, 0x01,  0x01, 0x01, 0x01,  0x01,  0x00,   0       }, //CVE_VBI_BLANK_LEVEL_H_VAL
+/*39*/  {0x2e,  0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00,  0x00,  0xfc,   251     }, //CVE_VBI_BLANK_LEVEL_L_VAL
+/*40*/  {0x2f,  0x01, 0x01, 0x01, 0x01, 0x01,  0x01, 0x01, 0x01,  0x01,  0x00,   0       }, //CVE_CLAMP_LEVEL_H_VAL
+/*41*/  {0x30,  0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00,  0x00,  0xfc,   0       }, //CVE_CLAMP_LEVEL_L_VAL
+/*42*/  {0x31,  0x10, 0x10, 0x10, 0x10, 0x10,  0x10, 0x10, 0x10,  0x10,  0x10,   16      }, //CVE_SYNC_LEVEL_VAL
+/*43*/  {0x33,  0x01, 0x01, 0x01, 0x01, 0x01,  0x01, 0x01, 0x01,  0x01,  0x01,   1       }, //CVE_SYNC_HIGH_LEVEL_H_VAL
+/*44*/  {0x34,  0xeb, 0xeb, 0xeb, 0xeb, 0xeb,  0xeb, 0xeb, 0xeb,  0xeb,  0xe8,   230     }, //CVE_SYNC_HIGH_LEVEL_L_VAL
+//*45*/ {0x37,  0x09, 0x15, 0x08, 0x08, 0x08,  0x08, 0x15, 0x15,  0x15,  0x08,   8       }, //CVE_NOTCH_EN_WI_FR_VAL
+//*46*/ {0x38,  0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00,  0x00,  0x00,   0       }, //CVE_NO_SH_NO_VAL
+//*47*/ {0x39,  0x05, 0x05, 0x05, 0x05, 0x05,  0x05, 0x05, 0x05,  0x05,  0x05,   5       }, //CVE_NOISE_THRESHOLD_VAL
+//*48*/ {0x3a,  0x0a, 0x0a, 0x0a, 0x0a, 0x0a,  0x0a, 0x0a, 0x0a,  0x0a,  0x0a,   10      }, //CVE_SHARPEN_THRESHOLD_VAL
+};
+
+#endif
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/celestial/df/tve1_1900.h linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/df/tve1_1900.h
--- linux-linaro-3.4-2012.05-1_original/drivers/celestial/df/tve1_1900.h	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/df/tve1_1900.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,64 @@
+
+#ifndef _CSM_TVE1_H
+#define _CSM_TVE1_H
+
+//1TVE1
+
+#define  TVE1_REG_NUM		(49)
+#define  TVE1_TYPE_TOTAL  	(13)
+
+//dont change this table
+static unsigned char TVE1_REG[TVE1_REG_NUM][TVE1_TYPE_TOTAL] =
+{
+/*      address ntsc  pal   PAL_M PAL-N PAL-CN SECAM 480p  720p50 720p60 1080i25 1080i30 */
+/*0*/   {0x00,  0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00,  0x00,  0x00,   0x00    }, //CVE_SOFT_RESET_VAL
+/*1*/   {0x01,  0x50, 0x51, 0x50, 0x50, 0x50,  0x50, 0x50, 0x50,  0x50,  0x50,   0x50    }, //CVE_REV_ID_VAL
+/*2*/   {0x02,  0x1d, 0x11, 0x11, 0x1d, 0x1d,  0x1d, 0x1d, 0x1d,  0x1d,  0x1d,   0x1d    }, //CVE_INPUT_CTL_VAL
+/*3*/   {0x04,  0x09, 0x09, 0x09, 0x09, 0x09,  0x09, 0x09, 0x09,  0x09,  0x09,   0x09    }, //CVE_OUT_CTL_VAL
+/*4*/   {0x06,  0x01, 0x01, 0x01, 0x01, 0x01,  0x01, 0x01, 0x01,  0x01,  0x01,   0x01    }, //CVE_SLV_MD_TH_VAL
+/*5*/   {0x07,  0x00, 0x04, 0x24, 0x24, 0x34,  0x3C, 0x01, 0x03,  0x03,  0x02,   0x01    }, //CVE_VID_STD_VAL
+/*6*/   {0x08,  0x02, 0x02, 0x02, 0x02, 0x02,  0x02, 0x02, 0x02,  0x02,  0x04,   0x02    }, //CVE_NUM_LINES_H_VAL
+/*7*/   {0x09,  0x0d, 0x71, 0x0D, 0x71, 0x71,  0x71, 0x0D, 0xEE,  0xEE,  0x65,   0x0D    }, //CVE_NUM_LINES_L_VAL
+/*8*/   {0x0a,  0x15, 0x17, 0x15, 0x17, 0x17,  0x17, 0x2a, 0x19,  0x19,  0x14,   0x2c    }, //CVE_FST_VID_LINE_VAL
+/*9*/   {0x0b,  0x7e, 0x7e, 0x7e, 0x7e, 0x7e,  0x7e, 0x7e, 0x40,  0x50,  0x66,   0xC0    }, //CVE_HSYNC_WIDTH_VAL
+/*10*/  {0x0d,  0x76, 0x80, 0x76, 0x8a, 0x8a,  0x8a, 0x68, 0xdc,  0xd0,  0x80,   0x60    }, //CVE_BACK_PORCH_VAL
+/*11*/  {0x0e,  0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x01,  0x00,  0x00,   0x00    }, //CVE_FRONT_PORCH_H_VAL
+/*12*/  {0x0f,  0x20, 0x28, 0x20, 0x18, 0x18,  0x18, 0x32, 0xb8,  0x48,  0x40,   0x20    }, //CVE_FRONT_PORCH_L_VAL
+/*13*/  {0x10,  0x05, 0x05, 0x05, 0x05, 0x05,  0x05, 0x05, 0x05,  0x05,  0x07,   0x05    }, //CVE_ACTIVELINE_H_VAL
+/*14*/  {0x11,  0xa0, 0x9a, 0xa0, 0xa0, 0xa0,  0xa0, 0x9c, 0x00,  0x0a,  0x80,   0x00    }, //CVE_ACTIVELINE_L_VAL
+/*15*/  {0x12,  0x44, 0x40, 0x44, 0x40, 0x44,  0x40, 0x44, 0x08,  0x08,  0x08,   0x44    }, //CVE_BURST_WDITH_VAL
+/*16*/  {0x13,  0x16, 0x1a, 0x12, 0x1a, 0x1a,  0x1a, 0x16, 0x08,  0x08,  0x08,   0x16    }, //CVE_BREEZE_WAY_VAL
+/*17*/  {0x16,  0x10, 0x15, 0x10, 0x10, 0x10,  0x14, 0x15, 0x15,  0x15,  0x15,   0x15    }, //CVE_CHROMA_FREQ_3_VAL
+/*18*/  {0x17,  0xf8, 0x04, 0xF3, 0xFB, 0xFB,  0xE3, 0x04, 0x04,  0x04,  0x04,   0x04    }, //CVE_CHROMA_FREQ_2_VAL
+/*19*/  {0x18,  0x3e, 0xc5, 0x77, 0x4A, 0x4A,  0x8E, 0xc5, 0xc5,  0xc5,  0xc5,   0xC5    }, //CVE_CHROMA_FREQ_1_VAL
+/*20*/  {0x19,  0x0f, 0x66, 0xD0, 0x33, 0x23,  0x39, 0x66, 0x66,  0x66,  0x66,   0x66    }, //CVE_CHROMA_FREQ_0_VAL
+/*21*/  {0x1a,  0x14, 0x14, 0x14, 0x14, 0x00,  0x14, 0x14, 0x14,  0x14,  0x14,   0x14    }, /*freq2*/
+/*22*/  {0x1b,  0x25, 0x25, 0x25, 0x00, 0x00,  0x25, 0x25, 0x25,  0x25,  0x25,   0x25    },
+/*23*/  {0x1c,  0xed, 0xed, 0xed, 0x00, 0x00,  0xed, 0xed, 0xed,  0xed,  0xed,   0xED    },
+/*24*/  {0x1d,  0x09, 0x09, 0x09, 0x00, 0x00,  0x09, 0x09, 0x09,  0x09,  0x09,   0x09    },
+/*25*/  {0x1e,  0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00,  0x00,  0x00,   0x00    }, //CVE_CHROMA_PHASE_VAL
+/*26*/  {0x1f,  0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00,  0x00,  0x00,   0x00    }, //CVE_TINT_VAL
+/*27*/  {0x20,  0x14, 0x04, 0x04, 0x04, 0x04,  0x04, 0x04, 0x04,  0x04,  0x04,   0x04    }, //CVE_NA_WI_CH_CH_CP_VAL
+/*28*/  {0x21,  0x44, 0x30, 0x2a, 0x2a, 0x2c,  0x00, 0x30, 0x30,  0x30,  0x30,   0x30    }, //CVE_CB_BURST_AMP_VAL
+/*29*/  {0x22,  0x00, 0x24, 0x1d, 0x1d, 0x1f,  0x00, 0x24, 0x24,  0x24,  0x24,   0x24    }, //CVE_CR_BURST_AMP_VAL
+/*30*/  {0x23,  0xcd, 0x94, 0xcc, 0xa2, 0xa2,  0xa2, 0xb8, 0xb8,  0xb8,  0xb8,   0xD4    }, //CVE_CB_GAIN_VAL
+/*31*/  {0x24,  0xcd, 0x94, 0xcc, 0xa2, 0xa2,  0xa2, 0xb8, 0xb8,  0xb8,  0xb8,   0xD0    }, //CVE_CR_GAIN_VAL
+/*32*/  {0x27,  0x03, 0x03, 0x02, 0x02, 0x02,  0x02, 0x02, 0x02,  0x02,  0x02,   0x03    }, //CVE_WHITE_LEVEL_H_VAL
+/*33*/  {0x28,  0x20, 0x20, 0xc6, 0x80, 0xf8,  0xf8, 0xf8, 0xf8,  0xf8,  0xf8,   0x28    }, //CVE_WHITE_LEVEL_L_VAL
+/*34*/  {0x29,  0x01, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00,  0x00,  0x00,   0x00    }, //CVE_BLACK_LEVEL_H_VAL
+/*35*/  {0x2a,  0x1a, 0xfb, 0xb0, 0xb0, 0xb0,  0xb0, 0xb0, 0xfb,  0xfb,  0xb0,   0xB0    }, //CVE_BLACK_LEVEL_L_VAL
+/*36*/  {0x2b,  0x00, 0x00, 0x01, 0x01, 0x01,  0x01, 0x01, 0x01,  0x01,  0x01,   0x01    }, //CVE_BLANK_LEVEL_H_VAL
+/*37*/  {0x2c,  0xf0, 0xfb, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00,  0x00,  0x00,   0x00    }, //CVE_BLANK_LEVEL_L_VAL
+/*38*/  {0x2d,  0x00, 0x00, 0x01, 0x01, 0x01,  0x01, 0x01, 0x01,  0x01,  0x01,   0x01    }, //CVE_VBI_BLANK_LEVEL_H_VAL
+/*39*/  {0x2e,  0xf0, 0xfb, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00,  0x00,  0x00,   0x00    }, //CVE_VBI_BLANK_LEVEL_L_VAL
+/*40*/  {0x2f,  0x01, 0x01, 0x01, 0x01, 0x01,  0x01, 0x01, 0x01,  0x01,  0x01,   0x01    }, //CVE_CLAMP_LEVEL_H_VAL
+/*41*/  {0x30,  0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00,  0x00,  0x00,   0x00    }, //CVE_CLAMP_LEVEL_L_VAL
+/*42*/  {0x31,  0x10, 0x10, 0x10, 0x10, 0x10,  0x10, 0x10, 0x10,  0x10,  0x10,   0x10    }, //CVE_SYNC_LEVEL_VAL
+/*43*/  {0x33,  0x01, 0x01, 0x01, 0x01, 0x01,  0x01, 0x01, 0x01,  0x01,  0x01,   0x01    }, //CVE_SYNC_HIGH_LEVEL_H_VAL
+/*44*/  {0x34,  0xeb, 0xeb, 0xeb, 0xeb, 0xeb,  0xeb, 0xeb, 0xeb,  0xeb,  0xeb,   0xEB    }, //CVE_SYNC_HIGH_LEVEL_L_VAL
+//*45*/ {0x37,  0x09, 0x08, 0x08, 0x08, 0x08,  0x08, 0x15, 0x15,  0x15,  0x15,   0x15    }, //CVE_NOTCH_EN_WI_FR_VAL
+//*46*/ {0x38,  0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00,  0x00,  0x00,   0x00    }, //CVE_NO_SH_NO_VAL
+//*47*/ {0x39,  0x05, 0x05, 0x05, 0x05, 0x05,  0x05, 0x05, 0x05,  0x05,  0x05,   0x05    }, //CVE_NOISE_THRESHOLD_VAL
+//*48*/ {0x3a,  0x0a, 0x0a, 0x0a, 0x0a, 0x0a,  0x0a, 0x0a, 0x0a,  0x0a,  0x0a,   0x0A    }, //CVE_SHARPEN_THRESHOLD_VAL
+};
+#endif
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/celestial/graphics/blit_cmd_reg_def.h linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/graphics/blit_cmd_reg_def.h
--- linux-linaro-3.4-2012.05-1_original/drivers/celestial/graphics/blit_cmd_reg_def.h	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/graphics/blit_cmd_reg_def.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,319 @@
+/*******************************************************************************
+
+File name   : blit_cmd_reg_def.h
+
+Description : blitter defs head file
+
+COPYRIGHT (C) Celestial Semiconductor 2000.
+
+Date               Modification                                     Name
+----               ------------                                     ----
+20 Jun 2000        Created                                           XM.Chen
+*******************************************************************************/
+
+#ifndef _BLIT_CMD_REG_DEF_H_
+#define _BLIT_CMD_REG_DEF_H_
+
+/* C++ support */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum _BLIT_COLOR_BIT_WIDTH_   //ARGB8565
+{
+	BLIT_ALPHA_BIT_WIDTH = 8,
+	BLIT_RED_BIT_WIDTH   = 5,
+	BLIT_GREEN_BIT_WIDTH = 6,
+	BLIT_BLUE_BIT_WIDTH  = 5,
+} BLIT_COLOR_BIT_WIDTH;
+
+typedef enum _CLUT_CONST_
+{
+	CLUT4_TABLE_LEN  = 16,
+	CLUT8_TABLE_LEN  = 256,
+} CLUT_CONST;
+
+typedef enum _BLIT_COMMAND_INDEX_
+{
+    CMD_STARTUP            = 0x00 ,
+    CMD_S0_ADDR_INFO       = 0x04 ,
+    CMD_S0_ADDR_INFO_L     = 0x05 ,
+    CMD_S0_FORMAT          = 0x06 ,
+    CMD_S0_FORMAT_L        = 0x07 ,
+    CMD_S0_COLOR_KEY_MIN   = 0x08 ,
+    CMD_S0_COLOR_KEY_MAX   = 0x0A ,
+    CMD_S1_ADDR_INFO       = 0x0C ,
+    CMD_S1_ADDR_INFO_L     = 0x0D ,
+    CMD_S1_FORMAT          = 0x0E ,
+    CMD_S1_FORMAT_L        = 0x0F ,
+    CMD_S1_COLOR_KEY_MIN   = 0x10 ,
+    CMD_S1_COLOR_KEY_MAX   = 0x12 ,
+    CMD_D_ADDR_INFO        = 0x14 ,
+    CMD_D_ADDR_INFO_L      = 0x15 ,
+    CMD_D_FORMAT           = 0x16 ,
+    //CMD_PIXEL_MAP          = 0x18 ,
+    CMD_PIXEL_NUM_PER_LINE = 0x18,
+    CMD_TOTAL_LINE_NUM     = 0x19,    
+
+    CMD_ENDIAN_CTRL        = 0x1A ,
+    CMD_CLUT4_TAB          = 0x1C ,
+    CMD_CLUT4_IDX          = 0x1D ,
+    CMD_CLUT8_TAB          = 0x1E ,
+    CMD_CLUT8_IDX          = 0x1F ,
+
+    //SCALOR Related
+    CMD_SCALOR_S_PIXEL_NUM_PER_LINE = 0x30,
+    CMD_SCALOR_S_TOTAL_LINE_NUM     = 0x31,
+    CMD_SCALOR_INITIAL_PHASE        = 0x38,
+    CMD_HFIR_COEFFICIETN_DATA       = 0x3B,
+    CMD_VFIR_COEFFICIETN_DATA       = 0x3D,
+    CMD_VALID_MAX,
+    
+} BLIT_COMMAND_INDEX;
+
+typedef enum _BLIT_REG_STATUS_FORMAT_
+{
+	BLIT_STATUS_BIT     = 0,
+	BLIT_INT_STATUS_BIT = 1,
+	BLIT_ERR_BIT        = 2,
+	BLIT_AHB_ERR_BIT    = 3, 
+}BLIT_REG_STATUS_FORMAT;
+
+typedef enum _BLIT_REG_CMDQUE_EMPTY_CNT_FORMAT_
+{
+	BLIT_REG_CMDQUE_EMPTY_CNT_LSB   = 0,
+	BLIT_REG_CMDQUE_EMPTY_CNT_WIDTH = 9,	
+}BLIT_REG_CMDQUE_EMPTY_CNT_FORMAT;
+
+typedef enum _COMPOSITOR_OPT_FORMAT_
+{
+	COMPOSITOR_ENABLE_BIT  = 3,
+	ROP_ENABLE_BIT         = 3,
+	S0_ON_TOP_S1_BIT       = 0,
+}COMPOSITOR_OPT_FORMAT;
+
+typedef enum _S_OPT_FORMAT_
+{
+	S_ENABLE_BIT          = 3,
+	S_COLORKEY_ENABLE_BIT = 2,
+	S_CLUT_ENABLE_BIT     = 1,
+	S_FETCH_DATA_BIT      = 0,	
+}S_OPT_FORMAT;
+typedef enum _S_SCAN_CTRL_FORMAT_
+{
+	S0_REVERSE_SCAN_BIT   = 0,
+	S1_REVERSE_SCAN_BIT   = 1,
+	D_REVERSE_SCAN_BIT    = 2,
+}S_SCAN_CTRL_FORMAT;
+
+typedef enum _ENDIAN_CTRL_FORMAT_
+{
+	ENDIAN_ENABLE_BIT   =  3,//Global no Enable Bit
+	TWO_BYTE_ENDIAN_BIT =  2,
+	NIBBLE_ENDIAN_BIT   =  1,
+	BYTE_ENDIAN_BIT     =  0,	
+}ENDIAN_CTRL_FORMAT;
+
+typedef enum _BLIT_REG_FORMAT_
+{
+	REG_INFO_CMD_CNT_WIDTH   =  4,
+	REG_INFO_CMD_CNT_LSB     = 28,
+	
+	REG_ENDIAN_CTRL_D_WIDTH  =  3,
+	REG_ENDIAN_CTRL_D_LSB    =  0,
+	REG_ENDIAN_CTRL_S1_WIDTH =  3,
+	REG_ENDIAN_CTRL_S1_LSB   =  3,
+	REG_ENDIAN_CTRL_S0_WIDTH =  3,
+	REG_ENDIAN_CTRL_S0_LSB   =  6,		
+	
+}BLIT_REG_FORMAT;
+
+typedef enum _BLIT_CMD_FORMAT_
+{
+	//ALL
+	CMD_IDX_WIDTH =  8,
+	CMD_IDX_LSB   = 24,  //Start up Bit
+	//CMD_STARTUP
+	SCAN_CTRL_WIDTH  =  4,
+	SCAN_CTRL_LSB    = 20,
+	S0_SCAL_ENA_BIT  = 17, 
+	INT_ENABLE_WIDTH =  1,
+	INT_ENABLE_LSB   = 16,
+	ROP_ALPHA_CTRL_WIDTH = 2,
+	ROP_ALPHA_CTRL_LSB   = 18,
+	ROP_VAL_WIDTH    =  4,
+	ROP_VAL_LSB      = 12,
+	CMP_OPT_WIDTH    =  4,//Compositor Operation
+	CMP_OPT_LSB      =  8,
+	S1_OPT_WIDTH     =  4,
+	S1_OPT_LSB       =  4,
+	S0_OPT_WIDTH     =  4,
+	S0_OPT_LSB       =  0, 
+	
+	//CMD_XX_FORMAT    
+	CMD_FORMAT_WIDTH        =  4,
+	CMD_FORMAT_LSB          =  0,
+	CMD_FORMAT_ALPHA0_LSB   =  8,
+	CMD_FORMAT_ALPHA0_WIDTH =  8,
+	CMD_FORMAT_ALPHA1_LSB   = 16,
+	CMD_FORMAT_ALPHA1_WIDTH =  8,
+
+	CMD_FORMAT_ALPHA0_MIN_LSB   =  8,
+	CMD_FORMAT_ALPHA0_MIN_WIDTH =  8,
+	CMD_FORMAT_ALPHA0_MAX_LSB   = 16,
+	CMD_FORMAT_ALPHA0_MAX_WIDTH =  8,
+	
+
+	//CMD_XX_ADDR_INFO
+	CMD_SKIP_PIXEL_WIDTH =  1,
+	CMD_SKIP_PIXEL_LSB   = 16,
+	CMD_PITCH_WIDTH      = 16,
+	CMD_PITCH_LSB        =  0,
+
+	//CMD_XX_COLOR_KEY_MAX
+	//CMD_XX_COLOR_KEY_MIN
+	//CMD_XX_DEFAULT_COLOR
+	CMD_ALPHA_WIDTH     =  8,
+	CMD_ALPHA_LSB       = 24,
+	CMD_RED_WIDTH       =  8,
+	CMD_RED_LSB         = 16,
+	CMD_GREEN_WIDTH     =  8,
+	CMD_GREEN_LSB       =  8,
+	CMD_BLUE_WIDTH      =  8,
+	CMD_BLUE_LSB        =  0,
+
+	//CMD_PIXEL_MAP
+	CMD_LPIXEL_NUM_WIDTH = 16,
+	CMD_LPIXEL_NUM_LSB   = 0,
+	CMD_LINE_NUM_WIDTH   = 16,
+	CMD_LINE_NUM_LSB     =  0,
+	
+	//CMD_CLUT4_IDX
+	CMD_CLUT4_IDX_WIDTH  =  4,
+	CMD_CLUT4_IDX_LSB    =  0,
+	
+	//CMD_CLUT8_IDX	
+	CMD_CLUT8_IDX_WIDTH  =  8,
+	CMD_CLUT8_IDX_LSB    =  0,
+	
+	//CMD_ENDIAN_CTRL
+	//Extend for S0 and S1 and D ENDIAN
+	CMD_GLOBAL_ENDIAN_WIDTH   =  3,
+	CMD_GLOBAL_ENDIAN_LSB     =  0,
+
+	CMD_S0_ENDIAN_WIDTH       =  4,
+	CMD_S0_ENDIAN_LSB         =  4,
+
+	CMD_S1_ENDIAN_WIDTH       =  4,
+	CMD_S1_ENDIAN_LSB         =  8,
+
+	CMD_D_ENDIAN_WIDTH        =  4,
+	CMD_D_ENDIAN_LSB          = 12,
+
+	//CMD_SCALOR_INITIAL_PHASE
+	CMD_SCALOR_V_INIT_PHASE_WIDTH = 3,
+	CMD_SCALOR_V_INIT_PHASE_LSB   = 8,
+	CMD_SCALOR_H_INIT_PHASE_WIDTH = 3,
+	CMD_SCALOR_H_INIT_PHASE_LSB   = 0,
+
+	//CMD_HFIR_COEFFICIETN_DATA
+	//CMD_VFIR_COEFFICIETN_DATA
+	CMD_FIR_COEFF_PHASE_IDX_WIDTH =  3,
+	CMD_FIR_COEFF_PHASE_IDX_LSB   = 20,
+	CMD_FIR_COEFF_TAP_IDX_WIDTH   =  2,
+	CMD_FIR_COEFF_TAP_IDX_LSB     = 16,
+	CMD_FIR_COEFF_VALUE_WIDTH     = 16,
+	CMD_FIR_COEFF_VALUE_LSB       =  0,
+}BLIT_CMD_FORMAT;
+
+
+#define SCALOR_FIR_COEFF_RED_REG_AVAILABLE (0)
+//Register Define
+typedef enum _BLIT_REG_ADDR_DEF_
+{
+// Register address
+  BLIT_REG_CMD_QUE                = 0x000000 << 2          , // 32'b4000_0000
+  BLIT_REG_STATUS                 = 0x000001 << 2         , // 32'b4000_0004
+  BLIT_REG_CMDQUE_EMPTY_CNT       = 0x000002 << 2         , // 32'b4000_0008
+  BLIT_REG_CMD_INFO               = 0x000003 << 2         , // 32'b4000_000C
+  BLIT_REG_CLUT_IDX               = 0x000004 << 2         , // 32'b4000_0010
+  BLIT_REG_CLUT_ENTRY             = 0x000005 << 2         , // 32'b4000_0014
+  BLIT_REG_S0_ADDR                = 0x000008 << 2         , // 32'b4000_0020
+  BLIT_REG_S0_LINE_PITCH          = 0x000009 << 2         , // 32'b4000_0024
+  BLIT_REG_S0_SKIP_PIXEL          = 0x00000A << 2         , // 32'b4000_0028
+  BLIT_REG_S0_COLOR_FORMAT        = 0x00000B << 2         , // 32'b4000_002C
+  BLIT_REG_S0_COLOR_KEY_MIN       = 0x00000C << 2         , // 32'b4000_0030
+  BLIT_REG_S0_COLOR_KEY_MAX       = 0x00000D << 2         , // 32'b4000_0034
+  BLIT_REG_S0_DEFAULT_COLOR       = 0x00000E << 2         , // 32'b4000_0038
+  BLIT_REG_S1_ADDR                = 0x00000F << 2         , // 32'b4000_003C
+  BLIT_REG_S1_LINE_PITCH          = 0x000010 << 2         , //  32'b4000_0040
+  BLIT_REG_S1_SKIP_PIXEL          = 0x000011 << 2         , //  32'b4000_0044
+  BLIT_REG_S1_COLOR_FORMAT        = 0x000012 << 2         , //  32'b4000_0048
+  BLIT_REG_S1_COLOR_KEY_MIN       = 0x000013 << 2         , //  32'b4000_004C
+  BLIT_REG_S1_COLOR_KEY_MAX       = 0x000014 << 2         , //  32'b4000_0050
+  BLIT_REG_S1_DEFAULT_COLOR       = 0x000015 << 2         , //  32'b4000_0054
+  BLIT_REG_D_ADDR                 = 0x000016 << 2         , //  32'b4000_0058
+  BLIT_REG_D_LINE_PITCH           = 0x000017 << 2         , //  32'b4000_005C
+  BLIT_REG_D_SKIP_PIXEL           = 0x000018 << 2         , //  32'b4000_0060
+  BLIT_REG_D_COLOR_FORMAT         = 0x000019 << 2         , //  32'b4000_0064
+  BLIT_REG_PIXEL_NUM_PER_LINE     = 0x00001A << 2         , //  32'b4000_0068
+  BLIT_REG_TOTAL_LINE_NUM         = 0x00001B << 2         , //  32'b4000_006C
+  BLIT_REG_ENDIAN_CTRL            = 0x00001C << 2         , //  32'b4000_0070
+  BLIT_REG_INT_CLEAR              = 0x00001D << 2         , //  32'b4000_0074
+  BLIT_REG_SW_RESET               = 0x00001E << 2         , //  32'b4000_0078
+	//Scalor Related Register
+  BLIT_REG_S0_PIXEL_NUM_PER_LINE  = 0x000020 << 2         , //  32'b4000_0080
+  BLIT_REG_S0_TOTAL_LINE_NUM      = 0x000021 << 2         , //  32'b4000_0084
+  
+  BLIT_REG_SCALOR_HORIZONTAL_INITIAL_PHASE
+                                 = 0x000022 << 2         , //  32'b4000_0088
+  BLIT_REG_SCALOR_VERTICAL_INITIAL_PHASE
+                                 = 0x000023 << 2         , //  32'b4000_008C
+#if SCALOR_FIR_COEFF_RED_REG_AVAILABLE                                 
+  //For Orion 1.4 Version SCalor FIR Coefficient Read not available in HW GfxCore
+  BLIT_REG_SCALER_HORIZONTAL_FIR_COEFFICIENT
+                                 = 0x000024 << 2         , //  32'b4000_0090
+  BLIT_REG_SCALER_VERTICAL_FIR_COEFFICIENT
+                                 = 0x000025 << 2         , //  32'b4000_0094
+#endif
+}BLIT_REG_ADDR_DEF;
+
+typedef enum _BLIT_REG_MASK_
+{
+	BLIT_COLOR_REG_MASK = ~((((1 << (CMD_ALPHA_WIDTH - BLIT_ALPHA_BIT_WIDTH)) - 1) << CMD_ALPHA_LSB) |
+		                   (((1 << (CMD_RED_WIDTH   - BLIT_RED_BIT_WIDTH  )) - 1) << CMD_RED_LSB  ) |
+		                   (((1 << (CMD_GREEN_WIDTH - BLIT_GREEN_BIT_WIDTH)) - 1) << CMD_GREEN_LSB) |
+		                   (((1 << (CMD_BLUE_WIDTH  - BLIT_BLUE_BIT_WIDTH )) - 1) << CMD_BLUE_LSB ) ),
+}BLIT_REG_MASk;
+
+
+typedef enum _BLIT_SCALOR_CONST_
+{
+	SCALOR_H_FIR_TAP_NUM            = 4,//Max >=2
+	SCALOR_V_FIR_TAP_NUM            = 2,
+	SCALOR_COEFF_FRACTION_BIT_WIDTH = 10,//
+	SCALOR_COEFF_INTREGER_BIT_WIDTH = 1,
+	SCALOR_COEFF_POLARITY_BIT       = 15,
+	
+	SCALOR_PAHSE_BIT_WIDTH          = 3,
+	SCALOR_PAHSE_NUM                = (1 << SCALOR_PAHSE_BIT_WIDTH),
+	SCALOR_STEP_FRACTION_BIT_WIDTH  = 13,
+
+	SCALOR_HFIR_DATA_BUF_LEN = SCALOR_H_FIR_TAP_NUM,
+	
+} BLIT_SCALOR_CONST;
+
+typedef enum _BLIT_SCALOR_FIR_IDX_
+{
+	SCALOR_HORIZON_FIR  = 0,
+	SCALOR_VERTICAL_FIR = 1,
+	
+}BLIT_SCALOR_FIR_IDX;
+
+/* C++ support */
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/celestial/graphics/blit_hw.c linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/graphics/blit_hw.c
--- linux-linaro-3.4-2012.05-1_original/drivers/celestial/graphics/blit_hw.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/graphics/blit_hw.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,1490 @@
+/*******************************************************************************
+
+File name   : blit_hw.c
+
+Description : blitter hardware related source file
+
+COPYRIGHT (C) Celestial Semiconductor 2007.
+
+Date               Modification                                     Name
+----               ------------                                     ----
+20 Jun 2007        Created                                           XM.Chen
+*******************************************************************************/
+
+/* Private preliminary definitions (internal use only) ---------------------- */
+#include <linux/version.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/miscdevice.h>
+#include <linux/ioport.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/miscdevice.h>
+#include <linux/errno.h>
+#include <asm/io.h>
+#include "blit_hw.h"
+
+#define ReadRegMem32LE(addr) ioread32((void*)(addr))
+#define WriteRegMem32LE(addr, val) iowrite32((val),(void*)(addr))
+/*--------------------------------------------------
+* #define CHECK_REG_AFTER_SEND_CMD
+* #define RESET_BLIT_ONLY_ONE_TIME
+* #define CHECK_REG_BEFORE_SEND_CMD
+*--------------------------------------------------*/
+
+#ifdef RESET_BLIT_ONLY_ONE_TIME
+static s32 IsBlitHWReset = 0;
+static s32 IsBlitSWReset = 0;
+#endif
+
+//Hardware Reset
+void HardWareReset(CSBlit_HW_Device_t *hBlitDC)
+{
+	DEBUG_PRINTF("2BlitIdelStatus = 0x%x, BlitCMDQueuSpace = 0x%x\n",ioread32(hBlitDC->RegBaseAddr + BLIT_REG_STATUS),ioread32(hBlitDC->RegBaseAddr + BLIT_REG_CMDQUE_EMPTY_CNT));
+#ifdef RESET_BLIT_ONLY_ONE_TIME
+	if(IsBlitHWReset)
+	{
+		return;
+	}
+	else
+	{
+		IsBlitHWReset++;
+	}	
+#endif
+	/*BlitHWReset();*/
+	CMDGroupCntSyncHW(hBlitDC);
+}
+/*
+//Return BlitCMDQueuSpace, 0 means Command Queue Full
+*/
+
+s32 SendCMD(CSBlit_HW_Device_t *hBlitDC, u32 BlitCMD)
+{
+	//Check Available Space
+	u32 BlitCMDQueuSpace = 0;
+	u32 BlitStatusRegValue = 0;
+	s32 AHBErrStatus    = 0;
+	s32 BlitErrStatus    = 0;
+	s32 InterruptStatus = 0; 
+	
+	//Clear Interrupt and ERR
+	BlitStatusRegValue = ReadRegMem32LE(hBlitDC->RegBaseAddr + BLIT_REG_STATUS);
+	AHBErrStatus      = (BlitStatusRegValue >> BLIT_AHB_ERR_BIT) &(1);
+	BlitErrStatus      = (BlitStatusRegValue >> BLIT_ERR_BIT) &(1);
+	InterruptStatus   = (BlitStatusRegValue >> BLIT_INT_STATUS_BIT) &(1);
+	if(AHBErrStatus)
+	{
+		printk("##ERROR: Blit AHB status Err\n");
+		return 0;		/* error happened */
+
+	}
+	if (InterruptStatus == 1)
+	{
+		if (BlitErrStatus)
+		{				
+			printk("##ERROR: SendCMD Blit Command Interpret Err\n");
+		}
+
+		//Clear Interrupt
+		WriteRegMem32LE(hBlitDC->RegBaseAddr + BLIT_REG_INT_CLEAR, 1);//Write Any Value
+	}
+	
+	do
+	{
+		BlitCMDQueuSpace = (ReadRegMem32LE(hBlitDC->RegBaseAddr + BLIT_REG_CMDQUE_EMPTY_CNT) >> 
+		                   BLIT_REG_CMDQUE_EMPTY_CNT_LSB) &
+		                  ((1 << BLIT_REG_CMDQUE_EMPTY_CNT_WIDTH) - 1);
+		if (BlitCMDQueuSpace <= 0)
+		{
+			//Some User Defined Sleep Function
+			printk("Blit Command Queue Full, Waiting.....\n");
+		}
+	}while(BlitCMDQueuSpace <= 0);
+	
+	if (BlitCMDQueuSpace > 0)
+	{
+/*--------------------------------------------------
+* printk("CMD: 0x%8x\n",BlitCMD);
+*--------------------------------------------------*/
+/*--------------------------------------------------
+* HAL_DCACHE_SYNC();
+*--------------------------------------------------*/
+		DEBUG_PRINTF("dump : 2D CMD 0x%x\n",BlitCMD);
+		WriteRegMem32LE(hBlitDC->RegBaseAddr + BLIT_REG_CMD_QUE, BlitCMD);
+	}
+
+	return BlitCMDQueuSpace;
+}
+
+/*
+//Before Call Set Active Context, make sure the the Command Queue Have enough Space 
+//and Blit's Interrupt Has been Cleared, it's better that the Status is Idle
+*/
+static u32 sBlitCMDGroupCnt = 0;
+static void CMDGroupCntInc(void)
+{
+	sBlitCMDGroupCnt++;
+}
+
+void CMDGroupCntSyncHW(CSBlit_HW_Device_t *hBlitDC)
+{
+	//Sync with Hardware
+	sBlitCMDGroupCnt = (ReadRegMem32LE(hBlitDC->RegBaseAddr + BLIT_REG_CMD_INFO) >> REG_INFO_CMD_CNT_LSB) & 
+	                  ((1 << REG_INFO_CMD_CNT_WIDTH) -1 );
+}
+
+u32 GetCMDGroupCnt(void)
+{
+	return sBlitCMDGroupCnt;
+}
+
+s32 ActiveDeviceContext( CSBlit_HW_Device_t *hBlitDC, BLIT_DC_UPDATE_TYPE BlitDCType)
+{
+	//Send S0 Related Command
+	u32 BlitCMD   = 0;
+	u32 BlitCMDQueSpace = 0;
+	u32 CompositorOperation = 0;
+	u32 S0Operation     = 0;
+	u32 S1Operation     = 0;
+	u32 ScanCtrl        = 0;
+	u32 S0EndianCtrl    = 0;
+	u32 S1EndianCtrl    = 0;
+	u32 DEndianCtrl     = 0;
+	u32 GlobalEndianCtrl  = 0;
+	if (hBlitDC == NULL)
+	{
+		return 0;
+	}
+
+	if (hBlitDC->S0Enable || hBlitDC->S0ScalorEnable)
+	{
+		if ((hBlitDC->S0FetchDram || hBlitDC->S0ScalorEnable )&& 
+			(BlitDCType & BLIT_DC_S0_DRAM_PARA) )
+		{			
+			//Dram Access Para
+			if(hBlitDC->BlitType == CSBLIT_DEVICE_TYPE_1_3)
+			{
+				BlitCMD = ((CMD_S0_ADDR_INFO_L & ((1<< CMD_IDX_WIDTH) -1)) << CMD_IDX_LSB) |
+					(((hBlitDC->S0BaseAddr & 0x3) >> 1) << CMD_SKIP_PIXEL_LSB) |
+					((hBlitDC->S0LinePitch 
+					  & ((1 << CMD_PITCH_WIDTH) -1)) << CMD_PITCH_LSB) >> 2 ;
+				BlitCMDQueSpace = SendCMD(hBlitDC, BlitCMD);
+				BlitCMDQueSpace = SendCMD(hBlitDC, hBlitDC->S0BaseAddr >> 2);
+			}
+			else if(hBlitDC->BlitType == CSBLIT_DEVICE_TYPE_1_3_1)
+			{
+				BlitCMD = ((CMD_S0_ADDR_INFO_L & ((1<< CMD_IDX_WIDTH) -1)) << CMD_IDX_LSB) |
+					((hBlitDC->S0SkipPixelLine 
+					  & ((1 << CMD_SKIP_PIXEL_WIDTH) -1)) << CMD_SKIP_PIXEL_LSB) |
+					((hBlitDC->S0LinePitch 
+					  & ((1 << CMD_PITCH_WIDTH) -1)) << CMD_PITCH_LSB) ;
+				BlitCMDQueSpace = SendCMD(hBlitDC, BlitCMD);
+				BlitCMDQueSpace = SendCMD(hBlitDC, hBlitDC->S0BaseAddr);
+			}
+
+			if (hBlitDC->IsUsingSDSpecificEndian)
+			{				
+				S0EndianCtrl = ((hBlitDC->S0ByteLittleNotBigEndian   & 0x1)    << BYTE_ENDIAN_BIT  )|
+					           ((hBlitDC->S0NibbleLittleNotBigEndian & 0x1)    << NIBBLE_ENDIAN_BIT)|
+					           ((hBlitDC->S0TwoBytesLittleNotBigEndian  & 0x1)    << TWO_BYTE_ENDIAN_BIT)|
+					           ((1 & 0x1) << ENDIAN_ENABLE_BIT);
+			}
+
+			if(hBlitDC->BlitType == CSBLIT_DEVICE_TYPE_1_3_1)
+			{
+				BlitCMD = ((CMD_SCALOR_S_PIXEL_NUM_PER_LINE & ((1 << CMD_IDX_WIDTH) -1)) << CMD_IDX_LSB) |
+					((hBlitDC->S0PixelNumOneLine
+					  & ((1 << CMD_LPIXEL_NUM_WIDTH) -1)) << CMD_LPIXEL_NUM_LSB);
+				BlitCMDQueSpace = SendCMD(hBlitDC, BlitCMD);
+
+				BlitCMD = ((CMD_SCALOR_S_TOTAL_LINE_NUM & ((1 << CMD_IDX_WIDTH) -1)) << CMD_IDX_LSB) |
+					((hBlitDC->S0TotalLineNum
+					  & ((1 << CMD_LINE_NUM_WIDTH) -1)) << CMD_LINE_NUM_LSB) ;
+				BlitCMDQueSpace = SendCMD(hBlitDC, BlitCMD);
+			}
+		}
+
+		//Color Info
+		if (BlitDCType & (BLIT_DC_S0_COLOR_FORMAT))
+		{
+			if (BlitDCType & BLIT_DC_S0_DEFAULT_COLOR)
+			{
+				if (hBlitDC->S0ColorType != CSBLIT_COLOR_TYPE_ARGB1555)
+				{
+					BlitCMD = ((CMD_S0_FORMAT_L   & ((1 << CMD_IDX_WIDTH) -1)) << CMD_IDX_LSB) |
+							 ((hBlitDC->S0ColorType
+							                     & ((1 << CMD_FORMAT_WIDTH) -1)) << CMD_FORMAT_LSB);
+				}
+				else
+				{
+					BlitCMD = ((CMD_S0_FORMAT_L   & ((1 << CMD_IDX_WIDTH) -1)) << CMD_IDX_LSB) |
+							 ((hBlitDC->S0ColorType
+							                     & ((1 << CMD_FORMAT_WIDTH) -1)) << CMD_FORMAT_LSB)|
+							 ((hBlitDC->S0Alpha0
+							                     & ((1 << CMD_FORMAT_ALPHA0_WIDTH) -1)) << CMD_FORMAT_ALPHA0_LSB)|
+							 ((hBlitDC->S0Alpha1
+							                     & ((1 << CMD_FORMAT_ALPHA1_WIDTH) -1)) << CMD_FORMAT_ALPHA1_LSB);
+				}
+			
+				BlitCMDQueSpace = SendCMD(hBlitDC, BlitCMD);
+				BlitCMD = (((hBlitDC->S0DefaultColor.Value.ARGB8888.Alpha >> (8-8))
+					                     & ((1 << CMD_ALPHA_WIDTH) -1)) << CMD_ALPHA_LSB)|
+					     (((hBlitDC->S0DefaultColor.Value.ARGB8888.R >> (8-8))
+					                     & ((1 << CMD_RED_WIDTH) -1)) << CMD_RED_LSB)|
+					     (((hBlitDC->S0DefaultColor.Value.ARGB8888.G >> (8-8))
+					                     & ((1 << CMD_GREEN_WIDTH) -1)) << CMD_GREEN_LSB)|
+					     (((hBlitDC->S0DefaultColor.Value.ARGB8888.B >> (8-8))
+					                     & ((1 << CMD_BLUE_WIDTH) -1)) << CMD_BLUE_LSB);
+				BlitCMDQueSpace = SendCMD(hBlitDC, BlitCMD);
+			}
+			else
+			{
+				if (hBlitDC->S0ColorType != CSBLIT_COLOR_TYPE_ARGB1555)
+				{
+					BlitCMD = ((CMD_S0_FORMAT     & ((1 << CMD_IDX_WIDTH) -1)) << CMD_IDX_LSB) |
+							 ((hBlitDC->S0ColorType
+							                     & ((1 << CMD_FORMAT_WIDTH) -1)) << CMD_FORMAT_LSB);
+				}
+				else
+				{
+					BlitCMD = ((CMD_S0_FORMAT     & ((1 << CMD_IDX_WIDTH) -1)) << CMD_IDX_LSB) |
+							 ((hBlitDC->S0ColorType
+							                     & ((1 << CMD_FORMAT_WIDTH) -1)) << CMD_FORMAT_LSB)|
+							 ((hBlitDC->S0Alpha0
+							                     & ((1 << CMD_FORMAT_ALPHA0_WIDTH) -1)) << CMD_FORMAT_ALPHA0_LSB)|
+							 ((hBlitDC->S0Alpha1
+							                     & ((1 << CMD_FORMAT_ALPHA1_WIDTH) -1)) << CMD_FORMAT_ALPHA1_LSB);
+				}
+			
+				BlitCMDQueSpace = SendCMD(hBlitDC, BlitCMD);				
+			}
+		}
+		//ColorKey ARGB8888
+		if (hBlitDC->S0ColorKeyRGB.RGBEnable && (BlitDCType & BLIT_DC_S0_COLORKEY_PARA))
+		{
+			BlitCMD = ((CMD_S0_COLOR_KEY_MIN & ((1 << CMD_IDX_WIDTH) -1))   << CMD_IDX_LSB)    |
+				     ((hBlitDC->S0ColorKeyRGB.RMin
+				                     & ((1 << CMD_RED_WIDTH) -1))   << CMD_RED_LSB)    |
+				     ((hBlitDC->S0ColorKeyRGB.GMin
+				                     & ((1 << CMD_GREEN_WIDTH) -1)) << CMD_GREEN_LSB)|
+				     ((hBlitDC->S0ColorKeyRGB.BMin
+				                     & ((1 << CMD_BLUE_WIDTH) -1))  << CMD_BLUE_LSB);
+			BlitCMDQueSpace = SendCMD(hBlitDC, BlitCMD);
+			BlitCMD = ((CMD_S0_COLOR_KEY_MAX & ((1 << CMD_IDX_WIDTH) -1))   << CMD_IDX_LSB)    |
+				     ((hBlitDC->S0ColorKeyRGB.RMax
+				                     & ((1 << CMD_RED_WIDTH) -1))   << CMD_RED_LSB)    |
+				     ((hBlitDC->S0ColorKeyRGB.GMax
+				                     & ((1 << CMD_GREEN_WIDTH) -1)) << CMD_GREEN_LSB)|
+				     ((hBlitDC->S0ColorKeyRGB.BMax
+				                     & ((1 << CMD_BLUE_WIDTH) -1))  << CMD_BLUE_LSB);
+			BlitCMDQueSpace = SendCMD(hBlitDC, BlitCMD);		
+		}		
+	}
+	//Send S1 Related Command
+	if (hBlitDC->S1Enable)
+	{
+		if (hBlitDC->S1FetchDram && (BlitDCType & BLIT_DC_S1_DRAM_PARA) )
+		{
+			
+			//Dram Access Para
+			if(hBlitDC->BlitType == CSBLIT_DEVICE_TYPE_1_3)
+			{
+				BlitCMD = ((CMD_S1_ADDR_INFO_L & ((1<< CMD_IDX_WIDTH) -1)) << CMD_IDX_LSB) |
+					(((hBlitDC->S1BaseAddr & 0x3) >> 1) << CMD_SKIP_PIXEL_LSB) |
+					((hBlitDC->S1LinePitch 
+					  & ((1 << CMD_PITCH_WIDTH) -1)) << CMD_PITCH_LSB) >> 2 ;
+				BlitCMDQueSpace = SendCMD(hBlitDC, BlitCMD);
+				BlitCMDQueSpace = SendCMD(hBlitDC, hBlitDC->S1BaseAddr >> 2);
+			}
+			else if(hBlitDC->BlitType == CSBLIT_DEVICE_TYPE_1_3_1)
+			{
+				BlitCMD = ((CMD_S1_ADDR_INFO_L & ((1 << CMD_IDX_WIDTH) -1)) << CMD_IDX_LSB) |
+					((hBlitDC->S1SkipPixelLine 
+					  & ((1 << CMD_SKIP_PIXEL_WIDTH) -1)) << CMD_SKIP_PIXEL_LSB) |
+					((hBlitDC->S1LinePitch 
+					  & ((1 << CMD_PITCH_WIDTH) -1)) << CMD_PITCH_LSB) ;
+				BlitCMDQueSpace = SendCMD(hBlitDC, BlitCMD);
+				BlitCMDQueSpace = SendCMD(hBlitDC, hBlitDC->S1BaseAddr);
+			}
+			
+			if (hBlitDC->IsUsingSDSpecificEndian)
+			{				
+				S1EndianCtrl = ((hBlitDC->S1ByteLittleNotBigEndian   & 0x1)    << BYTE_ENDIAN_BIT  )|
+					           ((hBlitDC->S1NibbleLittleNotBigEndian & 0x1)    << NIBBLE_ENDIAN_BIT)|
+					           ((hBlitDC->S1TwoBytesLittleNotBigEndian  & 0x1)    << TWO_BYTE_ENDIAN_BIT)|
+					           ((1 & 0x1)    << ENDIAN_ENABLE_BIT);
+			}
+
+			if(hBlitDC->BlitType == CSBLIT_DEVICE_TYPE_1_3_1)
+			{
+				BlitCMD = ((CMD_PIXEL_NUM_PER_LINE & ((1 << CMD_IDX_WIDTH) -1)) << CMD_IDX_LSB) |
+					((hBlitDC->S1PixelNumOneLine
+					  & ((1 << CMD_LPIXEL_NUM_WIDTH) -1)) << CMD_LPIXEL_NUM_LSB);
+				BlitCMDQueSpace = SendCMD(hBlitDC, BlitCMD);
+
+				BlitCMD = ((CMD_TOTAL_LINE_NUM & ((1 << CMD_IDX_WIDTH) -1)) << CMD_IDX_LSB) |
+					((hBlitDC->S1TotalLineNum
+					  & ((1 << CMD_LINE_NUM_WIDTH) -1)) << CMD_LINE_NUM_LSB) ;
+				BlitCMDQueSpace = SendCMD(hBlitDC, BlitCMD);
+			}
+		}
+/*--------------------------------------------------
+* printk("R:0x%x G:0x%x B: 0x%x A:0x%x\n",hBlitDC->S1DefaultColor.Value.ARGB8888.R,hBlitDC->S1DefaultColor.Value.ARGB8888.G,hBlitDC->S1DefaultColor.Value.ARGB8888.B,hBlitDC->S1DefaultColor.Value.ARGB8888.Alpha);
+*--------------------------------------------------*/
+
+		//Color Info
+		if (BlitDCType & BLIT_DC_S1_COLOR_FORMAT)
+		{
+			if (BlitDCType & BLIT_DC_S1_DEFAULT_COLOR)
+			{
+				if (hBlitDC->S1ColorType != CSBLIT_COLOR_TYPE_ARGB1555)
+				{
+/*--------------------------------------------------
+* printk("R:0x%x G:0x%x B: 0x%x A:0x%x\n",hBlitDC->S1DefaultColor.Value.ARGB8888.R,hBlitDC->S1DefaultColor.Value.ARGB8888.G,hBlitDC->S1DefaultColor.Value.ARGB8888.B,hBlitDC->S1DefaultColor.Value.ARGB8888.Alpha);
+*--------------------------------------------------*/
+					BlitCMD = ((CMD_S1_FORMAT_L   & ((1 << CMD_IDX_WIDTH) -1)) << CMD_IDX_LSB) |
+							 ((hBlitDC->S1ColorType
+							                     & ((1 << CMD_FORMAT_WIDTH) -1)) << CMD_FORMAT_LSB);
+				}
+				else
+				{
+					BlitCMD = ((CMD_S1_FORMAT_L   & ((1 << CMD_IDX_WIDTH) -1)) << CMD_IDX_LSB) |
+							 ((hBlitDC->S1ColorType
+							                     & ((1 << CMD_FORMAT_WIDTH) -1)) << CMD_FORMAT_LSB)|
+							 ((hBlitDC->S1Alpha0
+							                     & ((1 << CMD_FORMAT_ALPHA0_WIDTH) -1)) << CMD_FORMAT_ALPHA0_LSB)|
+							 ((hBlitDC->S1Alpha1
+							                     & ((1 << CMD_FORMAT_ALPHA1_WIDTH) -1)) << CMD_FORMAT_ALPHA1_LSB);
+				}
+				BlitCMDQueSpace = SendCMD(hBlitDC, BlitCMD);
+
+				BlitCMD = (((hBlitDC->S1DefaultColor.Value.ARGB8888.Alpha >> (8-8))
+						                     & ((1 << CMD_ALPHA_WIDTH) -1)) << CMD_ALPHA_LSB)|
+						 (((hBlitDC->S1DefaultColor.Value.ARGB8888.R >> (8-8))
+						                     & ((1 << CMD_RED_WIDTH) -1)) << CMD_RED_LSB)|
+						 (((hBlitDC->S1DefaultColor.Value.ARGB8888.G >> (8-8))
+						                     & ((1 << CMD_GREEN_WIDTH) -1)) << CMD_GREEN_LSB)|
+						 (((hBlitDC->S1DefaultColor.Value.ARGB8888.B >> (8-8))
+						                     & ((1 << CMD_BLUE_WIDTH) -1)) << CMD_BLUE_LSB);
+				/*--------------------------------------------------
+				* BlitCMD = ((((BlitCMD >> 16) & 0xFF) << 8 |
+				*     ((BlitCMD >> 16) & 0xFF00) >> 8) << 16)
+				*     |
+				*     (((BlitCMD & 0xFFFF) & 0xFF) << 8 |
+				*     ((BlitCMD & 0xFFFF) & 0xFF00) >> 8);
+				*--------------------------------------------------*/
+				BlitCMDQueSpace = SendCMD(hBlitDC, BlitCMD);	
+			}
+			else
+			{
+				if (hBlitDC->S1ColorType != CSBLIT_COLOR_TYPE_ARGB1555)
+				{
+					BlitCMD = ((CMD_S1_FORMAT     & ((1 << CMD_IDX_WIDTH) -1)) << CMD_IDX_LSB) |
+							 ((hBlitDC->S1ColorType
+							                     & ((1 << CMD_FORMAT_WIDTH) -1)) << CMD_FORMAT_LSB);
+				}
+				else
+				{
+					BlitCMD = ((CMD_S1_FORMAT     & ((1 << CMD_IDX_WIDTH) -1)) << CMD_IDX_LSB) |
+							 ((hBlitDC->S1ColorType
+							                     & ((1 << CMD_FORMAT_WIDTH) -1)) << CMD_FORMAT_LSB)|
+							 ((hBlitDC->S1Alpha0
+							                     & ((1 << CMD_FORMAT_ALPHA0_WIDTH) -1)) << CMD_FORMAT_ALPHA0_LSB)|
+							 ((hBlitDC->S1Alpha1
+							                     & ((1 << CMD_FORMAT_ALPHA1_WIDTH) -1)) << CMD_FORMAT_ALPHA1_LSB);
+				}
+			
+				BlitCMDQueSpace = SendCMD(hBlitDC, BlitCMD);				
+			}
+		}
+		
+		//ColorKey
+		if (hBlitDC->S1ColorKeyRGB.RGBEnable && (BlitDCType & BLIT_DC_S1_COLORKEY_PARA))
+		{
+			BlitCMD = ((CMD_S1_COLOR_KEY_MIN & ((1 << CMD_IDX_WIDTH) -1))   << CMD_IDX_LSB)    |
+				     ((hBlitDC->S1ColorKeyRGB.RMin
+				                     & ((1 << CMD_RED_WIDTH) -1))   << CMD_RED_LSB)    |
+				     ((hBlitDC->S1ColorKeyRGB.GMin
+				                     & ((1 << CMD_GREEN_WIDTH) -1)) << CMD_GREEN_LSB)|
+				     ((hBlitDC->S1ColorKeyRGB.BMin
+				                     & ((1 << CMD_BLUE_WIDTH) -1))  << CMD_BLUE_LSB);
+			BlitCMDQueSpace = SendCMD(hBlitDC, BlitCMD);
+			BlitCMD = ((CMD_S1_COLOR_KEY_MAX & ((1 << CMD_IDX_WIDTH) -1))   << CMD_IDX_LSB)    |
+				     ((hBlitDC->S1ColorKeyRGB.RMax
+				                     & ((1 << CMD_RED_WIDTH) -1))   << CMD_RED_LSB)    |
+				     ((hBlitDC->S1ColorKeyRGB.GMax
+				                     & ((1 << CMD_GREEN_WIDTH) -1)) << CMD_GREEN_LSB)|
+				     ((hBlitDC->S1ColorKeyRGB.BMax
+				                     & ((1 << CMD_BLUE_WIDTH) -1))  << CMD_BLUE_LSB);
+			BlitCMDQueSpace = SendCMD(hBlitDC, BlitCMD);		
+		}		
+	}
+
+	//Clut Table Update
+			//Clut4
+	if (hBlitDC->UpdateClut4Table && (BlitDCType & BLIT_DC_CLUT4_TABLE))
+	{
+		if (hBlitDC->UpdateClut4TableMode)//Update According Idx
+		{
+			u32 Clut4TableIdx = 0;
+			Clut4TableIdx = (hBlitDC->Clut4TableIdx & ((1 << CMD_CLUT4_IDX_WIDTH) -1));
+			//assert(Clut4TableIdx < CLUT4_TABLE_LEN);
+			if(Clut4TableIdx < CLUT4_TABLE_LEN) return 0;
+			BlitCMD =((CMD_CLUT4_IDX & ((1 << CMD_IDX_WIDTH) -1)) << CMD_IDX_LSB) | 
+				    ( Clut4TableIdx << CMD_CLUT4_IDX_LSB);
+				
+			BlitCMDQueSpace = SendCMD(hBlitDC, BlitCMD);
+			//Send Clut4 Entry
+			BlitCMDQueSpace = SendCMD(hBlitDC, hBlitDC->Clut4Table[Clut4TableIdx]);
+		}
+		else
+		{
+			u32 i = 0;
+			BlitCMD =((CMD_CLUT4_TAB & ((1 << CMD_IDX_WIDTH) -1)) << CMD_IDX_LSB);
+			BlitCMDQueSpace = SendCMD(hBlitDC, BlitCMD);
+			for (i = 0; i < CLUT4_TABLE_LEN; i++)
+			{
+				BlitCMDQueSpace = SendCMD(hBlitDC, hBlitDC->Clut4Table[i]);
+			}
+		}
+	#ifdef CHECK_REG_AFTER_SEND_CMD
+		if (!RegCheckClutTable(hBlitDC, BlitDCType, 1))
+		{
+			printk("##Failed to Check Clut4 Table Register\n");
+			return 0;
+		}
+	#endif
+	}
+		//Clut8
+	if (hBlitDC->UpdateClut8Table && (BlitDCType & BLIT_DC_CLUT8_TABLE))
+	{
+		if (hBlitDC->UpdateClut8TableMode)//Update According Idx
+		{
+			u32 Clut8TableIdx = 0;
+			Clut8TableIdx = (hBlitDC->Clut8TableIdx & ((1 << CMD_CLUT8_IDX_WIDTH) -1));
+			//assert(Clut8TableIdx < CLUT8_TABLE_LEN);
+			if(Clut8TableIdx < CLUT8_TABLE_LEN) return 0;
+			BlitCMD =((CMD_CLUT8_IDX & ((1 << CMD_IDX_WIDTH) -1)) << CMD_IDX_LSB) | 
+				    ( Clut8TableIdx << CMD_CLUT8_IDX_LSB);
+			
+			BlitCMDQueSpace = SendCMD(hBlitDC, BlitCMD);
+			//Send Clut8 Entry
+			BlitCMDQueSpace = SendCMD(hBlitDC, hBlitDC->Clut8Table[Clut8TableIdx]);
+		}
+		else
+		{
+			u32 i = 0;
+			BlitCMD =((CMD_CLUT8_TAB & ((1 << CMD_IDX_WIDTH) -1)) << CMD_IDX_LSB);
+			BlitCMDQueSpace = SendCMD(hBlitDC, BlitCMD);
+			for (i = 0; i < CLUT8_TABLE_LEN; i++)
+			{
+				BlitCMDQueSpace = SendCMD(hBlitDC, hBlitDC->Clut8Table[i]);
+			}
+		}
+	#ifdef CHECK_REG_AFTER_SEND_CMD
+		if (!RegCheckClutTable(hBlitDC, BlitDCType, 0))
+		{
+			printk("##Failed to Check Clut8 Table Register\n");
+			return 0;
+		}
+	#endif
+	}
+
+	//Send D Related Command
+	//D Dram Para
+	if ((BlitDCType & BLIT_DC_D_DRAM_PARA))
+	{
+		if(hBlitDC->BlitType == CSBLIT_DEVICE_TYPE_1_3)
+		{
+			BlitCMD = ((CMD_D_ADDR_INFO_L & ((1 << CMD_IDX_WIDTH) -1)) << CMD_IDX_LSB) |
+				(((hBlitDC->DBaseAddr & 0x3) >> 1) << CMD_SKIP_PIXEL_LSB) |
+				((hBlitDC->DLinePitch 
+				  & ((1 << CMD_PITCH_WIDTH) -1)) << CMD_PITCH_LSB) >> 2 ;
+			BlitCMDQueSpace = SendCMD(hBlitDC, BlitCMD);
+			BlitCMDQueSpace = SendCMD(hBlitDC, hBlitDC->DBaseAddr >> 2);
+		}
+		else if(hBlitDC->BlitType == CSBLIT_DEVICE_TYPE_1_3_1)
+		{
+			BlitCMD = ((CMD_D_ADDR_INFO_L & ((1 << CMD_IDX_WIDTH) -1)) << CMD_IDX_LSB) |
+				((hBlitDC->DSkipPixelLine 
+				  & ((1 << CMD_SKIP_PIXEL_WIDTH) -1)) << CMD_SKIP_PIXEL_LSB) |
+				((hBlitDC->DLinePitch 
+				  & ((1 << CMD_PITCH_WIDTH) -1)) << CMD_PITCH_LSB) ;
+			BlitCMDQueSpace = SendCMD(hBlitDC, BlitCMD);
+			BlitCMDQueSpace = SendCMD(hBlitDC, hBlitDC->DBaseAddr);
+		}
+
+		if (hBlitDC->IsUsingSDSpecificEndian)
+		{				
+			DEndianCtrl = ((hBlitDC->DByteLittleNotBigEndian   & 0x1)    << BYTE_ENDIAN_BIT  )|
+				          ((hBlitDC->DNibbleLittleNotBigEndian & 0x1)    << NIBBLE_ENDIAN_BIT)|
+				          ((hBlitDC->DTwoBytesLittleNotBigEndian  & 0x1)    << TWO_BYTE_ENDIAN_BIT)|
+				          ((1 & 0x1)    << ENDIAN_ENABLE_BIT);
+		}
+
+		if(hBlitDC->BlitType == CSBLIT_DEVICE_TYPE_1_3)
+		{
+			BlitCMD = ((CMD_PIXEL_NUM_PER_LINE & ((1 << CMD_IDX_WIDTH) -1)) << CMD_IDX_LSB) |
+				((hBlitDC->DPixelNumOneLine & ((1 << 12) -1)) << 12)|
+				((hBlitDC->DTotalLineNum & ((1 << 12) -1)) << 0) ;
+			BlitCMDQueSpace = SendCMD(hBlitDC, BlitCMD);
+		}
+		else if(hBlitDC->BlitType == CSBLIT_DEVICE_TYPE_1_3_1)
+		{
+			BlitCMD = ((CMD_PIXEL_NUM_PER_LINE & ((1 << CMD_IDX_WIDTH) -1)) << CMD_IDX_LSB) |
+			     ((hBlitDC->DPixelNumOneLine
+		                           & ((1 << CMD_LPIXEL_NUM_WIDTH) -1)) << CMD_LPIXEL_NUM_LSB);
+			BlitCMDQueSpace = SendCMD(hBlitDC, BlitCMD);
+
+			BlitCMD = ((CMD_TOTAL_LINE_NUM & ((1 << CMD_IDX_WIDTH) -1)) << CMD_IDX_LSB) |
+				((hBlitDC->DTotalLineNum
+				  & ((1 << CMD_LINE_NUM_WIDTH) -1)) << CMD_LINE_NUM_LSB) ;
+			BlitCMDQueSpace = SendCMD(hBlitDC, BlitCMD);
+		}
+	}
+
+	/*D Color Info should not be A0, no Default Color*/
+	if ((BlitDCType & BLIT_DC_D_COLOR_FORMAT))
+	{
+		if (hBlitDC->DColorType != CSBLIT_COLOR_TYPE_ARGB1555)
+		{
+			BlitCMD = ((CMD_D_FORMAT   & ((1 << CMD_IDX_WIDTH) -1)) << CMD_IDX_LSB) |
+					 ((hBlitDC->DColorType
+					                     & ((1 << CMD_FORMAT_WIDTH) -1)) << CMD_FORMAT_LSB);
+		}
+		else
+		{
+			BlitCMD = ((CMD_D_FORMAT   & ((1 << CMD_IDX_WIDTH) -1)) << CMD_IDX_LSB) |
+					 ((hBlitDC->DColorType
+					                     & ((1 << CMD_FORMAT_WIDTH) -1)) << CMD_FORMAT_LSB)|
+					 ((hBlitDC->DAlpha0Min
+					                     & ((1 << CMD_FORMAT_ALPHA0_MIN_WIDTH) -1)) << CMD_FORMAT_ALPHA0_MIN_LSB)|
+					 ((hBlitDC->DAlpha0Max
+					                     & ((1 << CMD_FORMAT_ALPHA0_MAX_WIDTH) -1)) << CMD_FORMAT_ALPHA0_MAX_LSB);
+		}	
+		BlitCMDQueSpace = SendCMD(hBlitDC, BlitCMD);
+	}
+	//Set Blit Interrupt Mode and Pipeline Enable
+	//Send Scalor Command
+/*
+	u32 S0ScalorEnable;
+	u32 IsUpdateHFIRCoeff;
+	u32 IsUpdateVFIRCoeff;
+	u32 HInitialPhase;
+	u32 VInitialPhase;
+	u32 HFIRCoeffTable[SCALOR_PAHSE_NUM][SCALOR_H_FIR_TAP_NUM];
+	u32 VFIRCoeffTable[SCALOR_PAHSE_NUM][SCALOR_V_FIR_TAP_NUM];
+*/
+	//Update VFIR Coeff
+	if ( (hBlitDC->UpdateHFIRCoeff) && (BlitDCType & BLIT_DC_SCALOR_HFIR_COFF))
+	{
+		u32 Phase = 0;
+		u32 Tap   = 0;
+		for (Phase = 0; Phase < SCALOR_PAHSE_NUM; Phase++)
+		{
+			for (Tap =0; Tap < SCALOR_H_FIR_TAP_NUM; Tap++)
+			{
+				BlitCMD = ((CMD_HFIR_COEFFICIETN_DATA & ((1 << CMD_IDX_WIDTH) -1)) << CMD_IDX_LSB) |
+				 		 ((Phase & ((1 << CMD_FIR_COEFF_PHASE_IDX_WIDTH) -1)) << CMD_FIR_COEFF_PHASE_IDX_LSB)|
+				 		 ((Tap   & ((1 << CMD_FIR_COEFF_TAP_IDX_WIDTH) -1))   << CMD_FIR_COEFF_TAP_IDX_LSB)|
+				 		 ((hBlitDC->HFIRCoeffTable[Phase][Tap]
+				 		         & ((1 << CMD_FIR_COEFF_VALUE_WIDTH) -1))     << CMD_FIR_COEFF_VALUE_LSB);
+				BlitCMDQueSpace = SendCMD (hBlitDC, BlitCMD);
+			}
+		}
+	}
+	//Update HFIR Coeff
+	if ((hBlitDC->UpdateVFIRCoeff) && (BlitDCType & BLIT_DC_SCALOR_VFIR_COFF))
+	{
+		u32 Phase = 0;
+		u32 Tap   = 0;
+		for (Phase = 0; Phase < SCALOR_PAHSE_NUM; Phase++)
+		{
+			for (Tap =0; Tap < SCALOR_V_FIR_TAP_NUM; Tap++)
+			{
+				BlitCMD = ((CMD_VFIR_COEFFICIETN_DATA & ((1 << CMD_IDX_WIDTH) -1)) << CMD_IDX_LSB) |
+				 		 ((Phase & ((1 << CMD_FIR_COEFF_PHASE_IDX_WIDTH) -1)) << CMD_FIR_COEFF_PHASE_IDX_LSB)|
+				 		 ((Tap   & ((1 << CMD_FIR_COEFF_TAP_IDX_WIDTH) -1))   << CMD_FIR_COEFF_TAP_IDX_LSB)|
+				 		 ((hBlitDC->VFIRCoeffTable[Phase][Tap]
+				 		         & ((1 << CMD_FIR_COEFF_VALUE_WIDTH) -1))     << CMD_FIR_COEFF_VALUE_LSB);
+				BlitCMDQueSpace = SendCMD(hBlitDC, BlitCMD);
+			}
+		}
+	}
+	if (hBlitDC->S0ScalorEnable)
+	{
+		//Scalor Source Pixel Map
+		//Send InitialPhase
+		if ((BlitDCType & BLIT_DC_SCALOR_INIT_PHASE))
+		{
+			BlitCMD = ((CMD_SCALOR_INITIAL_PHASE & ((1 << CMD_IDX_WIDTH) -1)) << CMD_IDX_LSB) |
+				 		 ((hBlitDC->HInitialPhase 
+				 		         & ((1 << CMD_SCALOR_H_INIT_PHASE_WIDTH) -1)) << CMD_SCALOR_H_INIT_PHASE_LSB)|
+				 		 ((hBlitDC->VInitialPhase    
+				 		         & ((1 << CMD_SCALOR_V_INIT_PHASE_WIDTH) -1)) << CMD_SCALOR_V_INIT_PHASE_LSB);
+			BlitCMDQueSpace = SendCMD(hBlitDC, BlitCMD);
+		}
+	}	
+	#ifdef CHECK_REG_AFTER_SEND_CMD
+	if (!RegCheckPreStartup(hBlitDC, BlitDCType))
+	{
+		printk("##Failed to Check Register Before Startup\n");
+		return 0;
+	}
+	#endif
+
+	//Send Startup Command
+	if ((BlitDCType & BLIT_DC_CTRL))
+	{
+		//Send Endian Mode		
+		GlobalEndianCtrl = ((hBlitDC->DByteLittleNotBigEndian & 0x1) << BYTE_ENDIAN_BIT  )|
+			((hBlitDC->DNibbleLittleNotBigEndian & 0x1) << NIBBLE_ENDIAN_BIT)|
+			((hBlitDC->DTwoBytesLittleNotBigEndian  & 0x1) << TWO_BYTE_ENDIAN_BIT);
+
+		BlitCMD     = ((CMD_ENDIAN_CTRL  & ((1 << CMD_IDX_WIDTH)-1)) << CMD_IDX_LSB)|
+			((S0EndianCtrl     & ((1 << CMD_S0_ENDIAN_WIDTH)-1)) << CMD_S0_ENDIAN_LSB)|
+			((S1EndianCtrl     & ((1 << CMD_S1_ENDIAN_WIDTH)-1)) << CMD_S1_ENDIAN_LSB)|
+			((DEndianCtrl      & ((1 << CMD_D_ENDIAN_WIDTH)-1)) << CMD_D_ENDIAN_LSB )|
+			((GlobalEndianCtrl & ((1 << CMD_GLOBAL_ENDIAN_WIDTH)-1)) << CMD_GLOBAL_ENDIAN_LSB); 
+
+		BlitCMDQueSpace = SendCMD(hBlitDC, BlitCMD);	
+
+		//Send Ctrl and Startup CMD
+		if(hBlitDC->BlitType == CSBLIT_DEVICE_TYPE_1_3_1)
+		{
+			ScanCtrl = ((hBlitDC->S0VReverseScan   & (1)) << S0_REVERSE_SCAN_BIT)  |
+				((hBlitDC->S1VReverseScan   & (1)) << S1_REVERSE_SCAN_BIT)  |
+				((hBlitDC->DVReverseScan    & (1)) << D_REVERSE_SCAN_BIT);
+		}
+
+		CompositorOperation = 
+			           ((hBlitDC->CompositorEnable & (1)) << COMPOSITOR_ENABLE_BIT)|
+		               ((hBlitDC->S0OnTopS1        & (1)) << S0_ON_TOP_S1_BIT);
+
+		S1Operation =  ((hBlitDC->S1Enable         & (1)) << S_ENABLE_BIT)|
+		               ((hBlitDC->S1ColorKeyRGB.RGBEnable & (1)) << S_COLORKEY_ENABLE_BIT)|
+		               ((hBlitDC->S1ClutEnable     & (1)) << S_CLUT_ENABLE_BIT)    |
+		               ((hBlitDC->S1FetchDram      & (1)) << S_FETCH_DATA_BIT);
+
+		S0Operation =  ((hBlitDC->S0Enable         & (1)) << S_ENABLE_BIT)|
+		               ((hBlitDC->S0ColorKeyRGB.RGBEnable & (1)) << S_COLORKEY_ENABLE_BIT)|
+		               ((hBlitDC->S0ClutEnable     & (1)) << S_CLUT_ENABLE_BIT)    |
+		               ((hBlitDC->S0FetchDram      & (1)) << S_FETCH_DATA_BIT);
+
+		BlitCMD = ((CMD_STARTUP  & ((1 << CMD_IDX_WIDTH)    -1)) << CMD_IDX_LSB)    |
+				 ((ScanCtrl     & ((1 << SCAN_CTRL_WIDTH)  -1)) << SCAN_CTRL_LSB)  |
+				 ((hBlitDC->S0ScalorEnable & (0x1))   << S0_SCAL_ENA_BIT)|
+			     ((hBlitDC->InterruptEnable
+				                & ((1 << INT_ENABLE_WIDTH) -1)) << INT_ENABLE_LSB) |
+				 ((hBlitDC->ROPAlphaCtrl
+				                & ((1 << ROP_ALPHA_CTRL_WIDTH)    -1)) << ROP_ALPHA_CTRL_LSB) |
+				 ((hBlitDC->RopValue
+				                & ((1 << ROP_VAL_WIDTH)    -1)) << ROP_VAL_LSB)    |
+				 ((CompositorOperation
+				                & ((1 << CMP_OPT_WIDTH)    -1)) << CMP_OPT_LSB)    |
+				 ((S1Operation  & ((1 << S1_OPT_WIDTH)     -1)) << S1_OPT_LSB)     |
+				 ((S0Operation  & ((1 << S0_OPT_WIDTH)     -1)) << S0_OPT_LSB);
+		//Check Point
+		BlitCMDQueSpace = SendCMD(hBlitDC, BlitCMD/*0xa080*/);
+		CMDGroupCntInc();
+	}
+	
+	/* store the BlitDCType */
+	hBlitDC->BlitDCType = BlitDCType;
+
+	return BlitCMDQueSpace;
+}
+
+s32 WaitBlitToBeIdle(CSBlit_HW_Device_t *hBlitDC) //Boolean Type Return
+{
+	//Run Time Info
+	s32 hResult = 1;
+	s32 BlitIdelStatus   = 0;
+	s32 AHBErrStatus    = 0;
+	s32 BlitErrStatus    = 0;
+	s32 InterruptStatus = 0; 
+	u32 BlitCMDQueuSpace = 0;
+
+	s32 InterruptEnable = 0;
+
+	u32 BlitStatusRegValue = 0;
+	u32 BlitInfoRegValue   = 0;
+	u32 TimeCnt = 0;
+	u32 TimeOut = 0;
+	if (hBlitDC == NULL)
+	{
+		TimeOut = 100;
+	}
+	else
+	{
+		u32 MaxWidth  = 0;
+		u32 MaxHeight = 0;
+		MaxWidth  = hBlitDC->S0PixelNumOneLine > hBlitDC->S1PixelNumOneLine ?
+			        hBlitDC->S0PixelNumOneLine : hBlitDC->S1PixelNumOneLine ;
+		MaxWidth  = MaxWidth > hBlitDC->DPixelNumOneLine ?
+			        MaxWidth : hBlitDC->DPixelNumOneLine ;
+		MaxHeight = hBlitDC->S0TotalLineNum > hBlitDC->S1TotalLineNum ?
+			        hBlitDC->S0TotalLineNum : hBlitDC->S1TotalLineNum ;
+		MaxHeight = MaxHeight > hBlitDC->DTotalLineNum ?
+			        MaxHeight : hBlitDC->DTotalLineNum ;
+		TimeOut = MaxWidth * MaxHeight *10; //One Circle One Pixel, for Scalor 3 Circle/pixel, so *10 is Enough
+		if (TimeOut < 100) TimeOut = 100;
+	}
+
+	do 
+	{
+		BlitInfoRegValue   = ReadRegMem32LE(hBlitDC->RegBaseAddr + BLIT_REG_CMD_INFO);
+		InterruptEnable   = (BlitInfoRegValue >> INT_ENABLE_LSB) &((1 << INT_ENABLE_WIDTH) -1); 
+		//Check Blit Status
+		BlitStatusRegValue = ReadRegMem32LE(hBlitDC->RegBaseAddr + BLIT_REG_STATUS);
+		BlitIdelStatus     = (BlitStatusRegValue >> BLIT_STATUS_BIT ) &(1);
+		AHBErrStatus      = (BlitStatusRegValue >> BLIT_AHB_ERR_BIT) &(1);
+		BlitErrStatus      = (BlitStatusRegValue >> BLIT_ERR_BIT    ) &(1);
+		InterruptStatus   = (BlitStatusRegValue >> BLIT_INT_STATUS_BIT) &(1);
+		BlitCMDQueuSpace   = (ReadRegMem32LE(hBlitDC->RegBaseAddr + BLIT_REG_CMDQUE_EMPTY_CNT) 
+			                                   >> BLIT_REG_CMDQUE_EMPTY_CNT_LSB) 
+			                                   & ((1 << BLIT_REG_CMDQUE_EMPTY_CNT_WIDTH) - 1);
+		DEBUG_PRINTF("3BlitIdelStatus = 0x%x, BlitCMDQueuSpace = 0x%x\n",BlitIdelStatus,BlitCMDQueuSpace);
+		if(AHBErrStatus)
+		{
+			printk("##ERROR: Blit AHB status Err\n");
+			return 0;
+		}
+		if (BlitErrStatus)
+		{
+			printk("##ERROR: Blit Command Interpret Err\n");
+			hResult = 0;
+		}
+		if (InterruptEnable || BlitErrStatus) //if Err Must Be a Interrupt 
+		{
+			if (InterruptStatus == 1)
+			{
+				//Clear Interrupt
+				WriteRegMem32LE(hBlitDC->RegBaseAddr + BLIT_REG_INT_CLEAR, 1);//Write Any Value
+			}
+		}
+		TimeCnt++;
+		//Some User Definde Sleep Function	
+	}while(!BlitIdelStatus && TimeCnt < TimeOut);
+
+	if(hBlitDC != NULL)
+	{
+		hBlitDC->BlitIdelStatus   = BlitIdelStatus;
+		hBlitDC->AHBErrStatus    = AHBErrStatus;
+		hBlitDC->BlitErrStatus    = BlitErrStatus;
+		hBlitDC->InterruptStatus = InterruptStatus; 
+		hBlitDC->CMDCnt          = BlitCMDQueuSpace;
+	}
+
+	if (TimeCnt >= TimeOut)
+	{
+		int i = 0;
+		printk("##ERROR: TimeOut (TimeCnt = %d)\n", TimeCnt);
+		if(hBlitDC->BlitType == CSBLIT_DEVICE_TYPE_1_3)
+		{
+			hResult = 0;
+		}
+		else if(hBlitDC->BlitType == CSBLIT_DEVICE_TYPE_1_3_1)
+		{
+			printk("Try To Reset Blit Engine\n");
+			WriteRegMem32LE(hBlitDC->RegBaseAddr + BLIT_REG_SW_RESET, 1);
+			for (i =0; i < 10; i++)
+			{
+				BlitStatusRegValue = ReadRegMem32LE(hBlitDC->RegBaseAddr + BLIT_REG_STATUS);
+				BlitIdelStatus     = (BlitStatusRegValue >> BLIT_STATUS_BIT ) &(1);		
+				if (BlitIdelStatus)
+				{
+					break;
+				}
+			}		
+			AHBErrStatus      = (BlitStatusRegValue >> BLIT_AHB_ERR_BIT) &(1);
+			BlitErrStatus      = (BlitStatusRegValue >> BLIT_ERR_BIT    ) &(1);
+			InterruptStatus   = (BlitStatusRegValue >> BLIT_INT_STATUS_BIT) &(1);
+			if (!BlitIdelStatus || AHBErrStatus || BlitErrStatus || InterruptStatus)
+			{
+				printk("##ERROR: Failed to Reset Blit AfterTimeOut\n");
+			}
+			WriteRegMem32LE(hBlitDC->RegBaseAddr + BLIT_REG_SW_RESET, 0);
+			CMDGroupCntSyncHW(hBlitDC);
+			hResult = 0;
+		}
+	}
+	else
+	{
+		/*--------------------------------------------------
+		* printk("Blit Idel Waitting Time = %d\n", TimeCnt);
+		*--------------------------------------------------*/
+	}
+	if(AHBErrStatus)
+	{
+		printk("##ERROR: Blit AHBErr\n");
+		hResult = 0;
+	}
+	if (BlitErrStatus)
+	{
+		printk("##ERROR: Blit Command Interpret Err\n");
+		hResult = 0;
+	}
+
+	return hResult;
+}
+
+/* This 'waittobeidle' only for scalor operation */
+s32 WaitBlitScalorToBeIdle(CSBlit_HW_Device_t *hBlitDC) //Boolean Type Return
+{
+	//Run Time Info
+	s32 hResult = 1;
+	s32 BlitIdelStatus   = 0;
+	s32 AHBErrStatus    = 0;
+	s32 BlitErrStatus    = 0;
+	s32 InterruptStatus = 0; 
+	u32 BlitCMDQueuSpace = 0;
+
+	s32 InterruptEnable = 0;
+
+	u32 BlitStatusRegValue = 0;
+	u32 BlitInfoRegValue   = 0;
+	u32 TimeCnt = 0;
+	u32 TimeOut = 0;
+	if (hBlitDC == NULL)
+	{
+		TimeOut = 100;
+	}
+	else
+	{
+		u32 MaxWidth  = 0;
+		u32 MaxHeight = 0;
+		MaxWidth  = hBlitDC->S0PixelNumOneLine > hBlitDC->S1PixelNumOneLine ?
+			        hBlitDC->S0PixelNumOneLine : hBlitDC->S1PixelNumOneLine ;
+		MaxWidth  = MaxWidth > hBlitDC->DPixelNumOneLine ?
+			        MaxWidth : hBlitDC->DPixelNumOneLine ;
+		MaxHeight = hBlitDC->S0TotalLineNum > hBlitDC->S1TotalLineNum ?
+			        hBlitDC->S0TotalLineNum : hBlitDC->S1TotalLineNum ;
+		MaxHeight = MaxHeight > hBlitDC->DTotalLineNum ?
+			        MaxHeight : hBlitDC->DTotalLineNum ;
+		TimeOut = MaxWidth * MaxHeight /8; //One Circle One Pixel, for Scalor 3 Circle/pixel, so *10 is Enough
+		if (TimeOut < 100) TimeOut = 100;
+	}
+
+	do
+	{
+		BlitInfoRegValue   = ReadRegMem32LE(hBlitDC->RegBaseAddr + BLIT_REG_CMD_INFO);
+		InterruptEnable   = (BlitInfoRegValue >> INT_ENABLE_LSB) &((1 << INT_ENABLE_WIDTH) -1); 
+		//Check Blit Status
+		BlitStatusRegValue = ReadRegMem32LE(hBlitDC->RegBaseAddr + BLIT_REG_STATUS);
+		BlitIdelStatus     = (BlitStatusRegValue >> BLIT_STATUS_BIT ) &(1);
+		AHBErrStatus      = (BlitStatusRegValue >> BLIT_AHB_ERR_BIT) &(1);
+		BlitErrStatus      = (BlitStatusRegValue >> BLIT_ERR_BIT    ) &(1);
+		InterruptStatus   = (BlitStatusRegValue >> BLIT_INT_STATUS_BIT) &(1);
+		BlitCMDQueuSpace   = (ReadRegMem32LE(hBlitDC->RegBaseAddr + BLIT_REG_CMDQUE_EMPTY_CNT) 
+			                                   >> BLIT_REG_CMDQUE_EMPTY_CNT_LSB) 
+			                                   & ((1 << BLIT_REG_CMDQUE_EMPTY_CNT_WIDTH) - 1);
+		if(AHBErrStatus)
+		{
+			printk("##ERROR: Blit AHB status Err\n");
+			return 0;
+		}
+		if (BlitErrStatus)
+		{
+			printk("##ERROR: Blit Command Interpret Err\n");
+			hResult = 0;
+		}
+		if (InterruptEnable || BlitErrStatus) //if Err Must Be a Interrupt 
+		{
+			if (InterruptStatus == 1)
+			{
+				//Clear Interrupt
+				WriteRegMem32LE(hBlitDC->RegBaseAddr + BLIT_REG_INT_CLEAR, 1);//Write Any Value
+			}
+		}
+		TimeCnt++;
+		//Some User Definde Sleep Function	
+	}while(!BlitIdelStatus && TimeCnt < TimeOut);
+
+	if(hBlitDC != NULL)
+	{
+		hBlitDC->BlitIdelStatus   = BlitIdelStatus;
+		hBlitDC->AHBErrStatus    = AHBErrStatus;
+		hBlitDC->BlitErrStatus    = BlitErrStatus;
+		hBlitDC->InterruptStatus = InterruptStatus; 
+		hBlitDC->CMDCnt          = BlitCMDQueuSpace;
+	}
+
+	if (TimeCnt >= TimeOut)
+	{
+		int i = 0;
+		printk("##ERROR: TimeOut (TimeCnt = %d)\n", TimeCnt);
+		if(hBlitDC->BlitType == CSBLIT_DEVICE_TYPE_1_3)
+		{
+			hResult = 0;
+		}
+		else if(hBlitDC->BlitType == CSBLIT_DEVICE_TYPE_1_3_1)
+		{
+			printk("Try To Reset Blit Engine\n");
+			WriteRegMem32LE(hBlitDC->RegBaseAddr + BLIT_REG_SW_RESET, 1);
+			for (i =0; i < 10; i++)
+			{
+				BlitStatusRegValue = ReadRegMem32LE(hBlitDC->RegBaseAddr + BLIT_REG_STATUS);
+				BlitIdelStatus     = (BlitStatusRegValue >> BLIT_STATUS_BIT ) &(1);		
+				if (BlitIdelStatus)
+				{
+					break;
+				}
+			}		
+			AHBErrStatus      = (BlitStatusRegValue >> BLIT_AHB_ERR_BIT) &(1);
+			BlitErrStatus      = (BlitStatusRegValue >> BLIT_ERR_BIT    ) &(1);
+			InterruptStatus   = (BlitStatusRegValue >> BLIT_INT_STATUS_BIT) &(1);
+			if (!BlitIdelStatus || AHBErrStatus || BlitErrStatus || InterruptStatus)
+			{
+				printk("##ERROR: Failed to Reset Blit AfterTimeOut\n");
+			}
+			WriteRegMem32LE(hBlitDC->RegBaseAddr + BLIT_REG_SW_RESET, 0);
+			CMDGroupCntSyncHW(hBlitDC);
+			hResult = 0;
+		}
+	}
+
+	if(AHBErrStatus)
+	{
+		printk("##ERROR: Blit AHBErr\n");
+		hResult = 0;
+	}
+	if (BlitErrStatus)
+	{
+		printk("##ERROR: Blit Command Interpret Err\n");
+		hResult = 0;
+	}
+
+	return hResult;
+}
+
+static u32 sBlitCMDQueueDepth = 0; // 0 means not initial
+static void SetCMDQueueDepth(u32 BlitCMDQueueDepth)
+{
+	sBlitCMDQueueDepth = BlitCMDQueueDepth;
+}
+
+u32 GetCMDQueueDepth()
+{
+	return sBlitCMDQueueDepth ;
+}
+
+void SWReset(CSBlit_HW_Device_t *hBlitDC)
+{
+	u32 BlitCMDQueueDepth = 0;
+#ifdef RESET_GFX_ONLY_ONE_TIME
+	if(IsBlitSWReset && IsBlitHWReset)
+	{
+		return;
+	}
+	else
+	{
+		IsBlitSWReset++;
+	}	
+#endif
+	WriteRegMem32LE(hBlitDC->RegBaseAddr + BLIT_REG_SW_RESET, 1);
+	//Waitting Blit to be Idel
+	WaitBlitToBeIdle(hBlitDC); // To Ensure Reset is Stable, must Wait for the Idel
+	WriteRegMem32LE(hBlitDC->RegBaseAddr + BLIT_REG_SW_RESET, 0);
+	BlitCMDQueueDepth = (ReadRegMem32LE(hBlitDC->RegBaseAddr + BLIT_REG_CMDQUE_EMPTY_CNT) 
+			              >> BLIT_REG_CMDQUE_EMPTY_CNT_LSB) 
+			              & ((1 << BLIT_REG_CMDQUE_EMPTY_CNT_WIDTH) - 1);
+	/*assert(BlitCMDQueueDepth != 0);*/
+	SetCMDQueueDepth(BlitCMDQueueDepth);
+	CMDGroupCntSyncHW(hBlitDC);
+}
+
+s32 WaitCMDQueueEmpty(CSBlit_HW_Device_t *hBlitDC)
+{
+	u32 BlitCMDQueueDepth = 0;
+	u32 BlitCMDQueuSpace  = 0;
+	u32 BlitStatusRegValue = 0;
+	s32 AHBErrStatus    = 0;
+	s32 BlitErrStatus    = 0;
+	s32 InterruptStatus = 0; 
+	//s32 InterruptEnable = 0;
+	//Clear Interrupt and ERR
+	BlitStatusRegValue = ReadRegMem32LE(hBlitDC->RegBaseAddr + BLIT_REG_STATUS);
+	AHBErrStatus      = (BlitStatusRegValue >> BLIT_AHB_ERR_BIT) &(1);
+	BlitErrStatus      = (BlitStatusRegValue >> BLIT_ERR_BIT    ) &(1);
+	InterruptStatus   = (BlitStatusRegValue >> BLIT_INT_STATUS_BIT) &(1);
+	if(AHBErrStatus)
+	{
+		printk("##ERROR: Blit AHB status Err\n");
+		return 0;		/* error happened */
+
+	}
+	if (InterruptStatus == 1)
+	{
+		if (BlitErrStatus)
+		{				
+			printk("##ERROR: Blit Command Interpret Err\n");
+		}
+		//Clear Interrupt		
+		WriteRegMem32LE(hBlitDC->RegBaseAddr + BLIT_REG_INT_CLEAR, 1);//Write Any Value
+	}
+	BlitCMDQueueDepth = GetCMDQueueDepth();
+	//assert(BlitCMDQueueDepth != 0);
+	if (BlitCMDQueueDepth == 0)
+	{
+		return 0;
+	}
+	do
+	{
+		BlitCMDQueuSpace = (ReadRegMem32LE(hBlitDC->RegBaseAddr + BLIT_REG_CMDQUE_EMPTY_CNT) 
+			              >> BLIT_REG_CMDQUE_EMPTY_CNT_LSB) 
+			              & ((1 << BLIT_REG_CMDQUE_EMPTY_CNT_WIDTH) - 1);
+	}while(BlitCMDQueuSpace < BlitCMDQueueDepth );
+	/*assert(BlitCMDQueuSpace == BlitCMDQueueDepth );*/
+	/*if (BlitCMDQueuSpace > BlitCMDQueueDepth )*/
+	if (BlitCMDQueuSpace != BlitCMDQueueDepth )
+	{		
+		printk("##ERROR: BlitCMDQueuSpace != BlitCMDQueueDepth \n");
+		return 0;
+	}
+	return (BlitCMDQueuSpace == BlitCMDQueueDepth );	
+}
+
+static s32 BlitRegCheck (CSBlit_HW_Device_t *hBlitDC, u32 RegAddr, u32 ExpectedValue)  
+{ 
+	u32 BlitRegValue = 0;
+	BlitRegValue = ReadRegMem32LE(hBlitDC->RegBaseAddr + (RegAddr));
+	if (BlitRegValue != ExpectedValue)
+	{
+		printk("RegAddr(%08x),BlitRegValue(%08x)!= ExpectedValue(%08x)\n",
+			         RegAddr,BlitRegValue, ExpectedValue);
+	}
+	//assert(BlitRegValue == (ExpectedValue));
+	return(BlitRegValue == (ExpectedValue));
+}
+
+s32 RegCheckClutTable(CSBlit_HW_Device_t *hBlitDC, BLIT_DC_UPDATE_TYPE BlitDCType, s32 IsClut4orClut8) //0: Clut4, 1: Clut8
+{
+	if (hBlitDC == NULL) return 0;
+	if (!WaitCMDQueueEmpty(hBlitDC)) return 0;
+	//Clut Table Update
+	//Clut4
+	if (hBlitDC->UpdateClut4Table && (BlitDCType & BLIT_DC_CLUT4_TABLE) && (IsClut4orClut8 == 1))
+	{
+		u32 Clut4TableIdx  = 0;
+		u32 Clut4TableData = 0;
+		if (hBlitDC->UpdateClut4TableMode)//Update According Idx
+		{
+			Clut4TableIdx = (hBlitDC->Clut4TableIdx & ((1 << CMD_CLUT4_IDX_WIDTH) -1));
+			//assert(Clut4TableIdx < CLUT4_TABLE_LEN);
+			if(Clut4TableIdx < CLUT4_TABLE_LEN) return 0;
+			WriteRegMem32LE(hBlitDC->RegBaseAddr + BLIT_REG_CLUT_IDX, Clut4TableIdx);
+			//Change to ARGB8565 Type
+			Clut4TableData = (hBlitDC->Clut4Table[Clut4TableIdx]) & 
+			                 ((0xFF000000)|(0x1F0000 << 3)|(0x3F00 << 2)|(0x1F<<3));
+			if (!BlitRegCheck(hBlitDC, (BLIT_REG_CLUT_ENTRY), (Clut4TableData))) return 0;			
+		}
+		else
+		{
+			for (Clut4TableIdx = 0; Clut4TableIdx < CLUT4_TABLE_LEN; Clut4TableIdx++)
+			{
+				WriteRegMem32LE(hBlitDC->RegBaseAddr + BLIT_REG_CLUT_IDX, Clut4TableIdx);
+				//Change to ARGB8565 Type
+				Clut4TableData = (hBlitDC->Clut4Table[Clut4TableIdx]) & 
+				                 ((0xFF000000)|(0x1F0000 << 3)|(0x3F00 << 2)|(0x1F<<3));
+				if (!BlitRegCheck(hBlitDC, (BLIT_REG_CLUT_ENTRY), (Clut4TableData))) return 0;			
+			}
+		}
+	}
+		//Clut8
+	if (hBlitDC->UpdateClut8Table && (BlitDCType & BLIT_DC_CLUT8_TABLE) && (IsClut4orClut8 == 0))
+	{
+		u32 Clut8TableIdx = 0;
+		u32 Clut8TableData = 0;
+		if (hBlitDC->UpdateClut8TableMode)//Update According Idx
+		{
+			Clut8TableIdx = (hBlitDC->Clut8TableIdx & ((1 << CMD_CLUT8_IDX_WIDTH) -1));
+			//assert(Clut8TableIdx < CLUT8_TABLE_LEN);
+			if(Clut8TableIdx < CLUT8_TABLE_LEN) return 0;
+			WriteRegMem32LE(hBlitDC->RegBaseAddr + BLIT_REG_CLUT_IDX, Clut8TableIdx);
+			//Change to ARGB8565 Type
+			Clut8TableData = (hBlitDC->Clut8Table[Clut8TableIdx]) & 
+			                 ((0xFF000000)|(0x1F0000 << 3)|(0x3F00 << 2)|(0x1F<<3));
+			if (!BlitRegCheck(hBlitDC, (BLIT_REG_CLUT_ENTRY), (Clut8TableData))) return 0;			
+		}
+		else
+		{
+			for (Clut8TableIdx = 0; Clut8TableIdx < CLUT8_TABLE_LEN; Clut8TableIdx++)
+			{
+				WriteRegMem32LE(hBlitDC->RegBaseAddr + BLIT_REG_CLUT_IDX, Clut8TableIdx);
+				//Change to ARGB8565 Type
+				Clut8TableData = (hBlitDC->Clut8Table[Clut8TableIdx]) & 
+				                 ((0xFF000000)|(0x1F0000 << 3)|(0x3F00 << 2)|(0x1F<<3));
+				if (!BlitRegCheck(hBlitDC, (BLIT_REG_CLUT_ENTRY), (Clut8TableData))) return 0;			
+			}
+		}
+	}	
+	return 1;
+}
+
+
+s32 RegCheckPosStartup(CSBlit_HW_Device_t *hBlitDC, BLIT_DC_UPDATE_TYPE BlitDCType)
+{
+	u32 S0EndianCtrl     = 0;
+	u32 S1EndianCtrl     = 0;
+	u32 DEndianCtrl      = 0;
+	u32 GlobalEndianCtrl = 0;
+	u32 BlitRegValue      = 0;
+	if (hBlitDC == NULL) return 0;
+	if (!WaitCMDQueueEmpty(hBlitDC)) return 0;
+	
+	if (hBlitDC->S0Enable || hBlitDC->S0ScalorEnable)
+	{
+		if ((hBlitDC->S0FetchDram || hBlitDC->S0ScalorEnable) && 
+			(BlitDCType & BLIT_DC_S0_DRAM_PARA) )
+		{
+			if (hBlitDC->IsUsingSDSpecificEndian)
+			{
+				S0EndianCtrl = ((hBlitDC->S0ByteLittleNotBigEndian   & 0x1)    << BYTE_ENDIAN_BIT  )|
+					           ((hBlitDC->S0NibbleLittleNotBigEndian & 0x1)    << NIBBLE_ENDIAN_BIT)|
+					           ((hBlitDC->S0TwoBytesLittleNotBigEndian  & 0x1)    << TWO_BYTE_ENDIAN_BIT)|
+					           ((1 & 0x1)    << ENDIAN_ENABLE_BIT);
+			}
+		}
+	}
+	if (hBlitDC->S1Enable)
+	{
+		if (hBlitDC->S1FetchDram && (BlitDCType & BLIT_DC_S1_DRAM_PARA) )
+		{
+			if (hBlitDC->IsUsingSDSpecificEndian)
+			{
+				S1EndianCtrl = ((hBlitDC->S1ByteLittleNotBigEndian   & 0x1)    << BYTE_ENDIAN_BIT  )|
+					           ((hBlitDC->S1NibbleLittleNotBigEndian & 0x1)    << NIBBLE_ENDIAN_BIT)|
+					           ((hBlitDC->S1TwoBytesLittleNotBigEndian  & 0x1)    << TWO_BYTE_ENDIAN_BIT)|
+					           ((1 & 0x1)    << ENDIAN_ENABLE_BIT);
+			}
+		}
+	}
+	if ((BlitDCType & BLIT_DC_D_DRAM_PARA))
+	{
+		if (hBlitDC->IsUsingSDSpecificEndian)
+		{
+			DEndianCtrl = ((hBlitDC->DByteLittleNotBigEndian   & 0x1)    << BYTE_ENDIAN_BIT  )|
+					      ((hBlitDC->DNibbleLittleNotBigEndian & 0x1)    << NIBBLE_ENDIAN_BIT)|
+					      ((hBlitDC->DTwoBytesLittleNotBigEndian  & 0x1)    << TWO_BYTE_ENDIAN_BIT)|
+					      ((1 & 0x1)    << ENDIAN_ENABLE_BIT);
+		}	
+	}
+	//Scalor S0, S1 and D Dram Access Para Check
+	if (!hBlitDC->S0ScalorEnable)
+	{
+		if (!BlitRegCheck(hBlitDC, (BLIT_REG_S0_PIXEL_NUM_PER_LINE), ReadRegMem32LE(hBlitDC->RegBaseAddr + BLIT_REG_PIXEL_NUM_PER_LINE))) return 0;
+
+		if (!BlitRegCheck(hBlitDC, (BLIT_REG_S0_TOTAL_LINE_NUM)    , ReadRegMem32LE(hBlitDC->RegBaseAddr + BLIT_REG_TOTAL_LINE_NUM))) return 0;
+	}
+	//Ctrl Status Check
+	if ((BlitDCType & BLIT_DC_CTRL))
+	{
+		u32 CompositorOperation = 0;
+		u32 S0Operation     = 0;
+		u32 S1Operation     = 0;
+		u32 ScanCtrl        = 0;
+		u32 BlitCMDGroupCnt  = 0;
+		//Send Endian Mode
+		//Endian Check
+		GlobalEndianCtrl = ((hBlitDC->DByteLittleNotBigEndian   & 0x1)    << BYTE_ENDIAN_BIT  )|
+			               ((hBlitDC->DNibbleLittleNotBigEndian & 0x1)    << NIBBLE_ENDIAN_BIT)|
+			               ((hBlitDC->DTwoBytesLittleNotBigEndian  & 0x1)    << TWO_BYTE_ENDIAN_BIT);
+		S0EndianCtrl = ((S0EndianCtrl >> ENDIAN_ENABLE_BIT)& 0x1) ?
+			            (S0EndianCtrl & ((1 << REG_ENDIAN_CTRL_S0_WIDTH) - 1)) : 
+					    (GlobalEndianCtrl & ((1 << REG_ENDIAN_CTRL_S0_WIDTH) - 1)) ;
+	  	S1EndianCtrl = ((S1EndianCtrl >> ENDIAN_ENABLE_BIT)& 0x1) ?
+						(S1EndianCtrl & ((1 << REG_ENDIAN_CTRL_S0_WIDTH) - 1)) : 
+						(GlobalEndianCtrl & ((1 << REG_ENDIAN_CTRL_S0_WIDTH) - 1)) ;
+		DEndianCtrl  = ((DEndianCtrl >> ENDIAN_ENABLE_BIT)& 0x1) ?
+						(DEndianCtrl & ((1 << REG_ENDIAN_CTRL_S0_WIDTH) - 1)) : 
+						(GlobalEndianCtrl & ((1 << REG_ENDIAN_CTRL_S0_WIDTH) - 1)) ;
+		if (hBlitDC->S0ScalorEnable)
+		{
+			S1EndianCtrl = S0EndianCtrl;
+		}
+		BlitRegValue = ((S0EndianCtrl & ((1 << REG_ENDIAN_CTRL_S0_WIDTH) - 1)) << (REG_ENDIAN_CTRL_S0_LSB)) |
+					  ((S1EndianCtrl & ((1 << REG_ENDIAN_CTRL_S1_WIDTH) - 1)) << (REG_ENDIAN_CTRL_S1_LSB)) |
+					  ((DEndianCtrl  & ((1 << REG_ENDIAN_CTRL_D_WIDTH ) - 1)) << (REG_ENDIAN_CTRL_D_LSB)) ;
+
+		if (!BlitRegCheck(hBlitDC, (BLIT_REG_ENDIAN_CTRL), (BlitRegValue))) return 0;
+		
+		//Send Ctrl and Startup CMD
+		if (hBlitDC->S0ScalorEnable)
+		{
+			ScanCtrl   =   ((hBlitDC->S0VReverseScan   & (1)) << S0_REVERSE_SCAN_BIT)  |
+				           ((hBlitDC->S0VReverseScan   & (1)) << S1_REVERSE_SCAN_BIT)  | //Scalor S0 S1 Scan the Same
+				           ((hBlitDC->DVReverseScan    & (1)) << D_REVERSE_SCAN_BIT);
+		}
+		else
+		{
+			ScanCtrl   =   ((hBlitDC->S0VReverseScan   & (1)) << S0_REVERSE_SCAN_BIT)  |
+				           ((hBlitDC->S1VReverseScan   & (1)) << S1_REVERSE_SCAN_BIT)  |
+				           ((hBlitDC->DVReverseScan    & (1)) << D_REVERSE_SCAN_BIT);
+		}
+		if (hBlitDC->S0ScalorEnable)
+		{
+			CompositorOperation = 0;		
+		}
+		else
+		{
+			CompositorOperation = 
+				           ((hBlitDC->CompositorEnable & (1)) << COMPOSITOR_ENABLE_BIT)|
+			               ((hBlitDC->S0OnTopS1        & (1)) << S0_ON_TOP_S1_BIT);
+		}
+		if (hBlitDC->S0ScalorEnable)
+		{
+			S1Operation = 0;
+		}
+		else
+		{
+			S1Operation =  ((hBlitDC->S1Enable         & (1)) << S_ENABLE_BIT)|
+		                   ((hBlitDC->S1ColorKeyRGB.RGBEnable & (1)) << S_COLORKEY_ENABLE_BIT)|
+		                   ((hBlitDC->S1ClutEnable     & (1)) << S_CLUT_ENABLE_BIT)    |
+		                   ((hBlitDC->S1FetchDram      & (1)) << S_FETCH_DATA_BIT);
+			
+		}
+
+		S0Operation =  ((hBlitDC->S0Enable         & (1)) << S_ENABLE_BIT)|
+		               ((hBlitDC->S0ColorKeyRGB.RGBEnable & (1)) << S_COLORKEY_ENABLE_BIT)|
+		               ((hBlitDC->S0ClutEnable     & (1)) << S_CLUT_ENABLE_BIT)    |
+		               ((hBlitDC->S0FetchDram      & (1)) << S_FETCH_DATA_BIT);
+		
+		BlitCMDGroupCnt = GetCMDGroupCnt();
+		BlitRegValue  = ((BlitCMDGroupCnt & ((1 << REG_INFO_CMD_CNT_WIDTH)- 1)) << REG_INFO_CMD_CNT_LSB)|
+				       ((ScanCtrl     & ((1 << SCAN_CTRL_WIDTH)  -1)) << SCAN_CTRL_LSB)  |
+				       ((hBlitDC->S0ScalorEnable & (0x1))   << S0_SCAL_ENA_BIT)|
+			           ((hBlitDC->InterruptEnable
+				                & ((1 << INT_ENABLE_WIDTH) -1)) << INT_ENABLE_LSB) |
+				       ((hBlitDC->ROPAlphaCtrl
+				                & ((1 << ROP_ALPHA_CTRL_WIDTH)    -1)) << ROP_ALPHA_CTRL_LSB) |
+				       ((hBlitDC->RopValue
+				                & ((1 << ROP_VAL_WIDTH)    -1)) << ROP_VAL_LSB)    |
+				       ((CompositorOperation
+				                & ((1 << CMP_OPT_WIDTH)    -1)) << CMP_OPT_LSB)    |
+				       ((S1Operation  & ((1 << S1_OPT_WIDTH)     -1)) << S1_OPT_LSB)     |
+				       ((S0Operation  & ((1 << S0_OPT_WIDTH)     -1)) << S0_OPT_LSB);
+		//Check Point
+		if (!BlitRegCheck(hBlitDC, (BLIT_REG_CMD_INFO), (BlitRegValue))) return 0;
+	}
+	return 1;
+	
+}
+
+s32 RegCheckPreStartup(CSBlit_HW_Device_t *hBlitDC, BLIT_DC_UPDATE_TYPE BlitDCType) //Boolean Type Return
+{
+	u32 BlitRegValue      = 0;
+	if (hBlitDC == NULL) return 0;
+	if (!WaitCMDQueueEmpty(hBlitDC)) return 0;
+		
+	if (hBlitDC->S0Enable || hBlitDC->S0ScalorEnable)
+	{
+		if ((hBlitDC->S0FetchDram || hBlitDC->S0ScalorEnable) && 
+			(BlitDCType & BLIT_DC_S0_DRAM_PARA) )
+		{	
+			if (!BlitRegCheck(hBlitDC, (BLIT_REG_S0_SKIP_PIXEL), 
+				(hBlitDC->S0SkipPixelLine & ((1 << CMD_SKIP_PIXEL_WIDTH) -1)))) return 0;
+			if (!BlitRegCheck(hBlitDC, (BLIT_REG_S0_LINE_PITCH), 
+				(hBlitDC->S0LinePitch & ((1 << CMD_PITCH_WIDTH) -1)))) return 0;
+			if (!BlitRegCheck(hBlitDC, (BLIT_REG_S0_ADDR)      , 
+				(hBlitDC->S0BaseAddr))) return 0;			
+			
+			if (!BlitRegCheck(hBlitDC, (BLIT_REG_S0_PIXEL_NUM_PER_LINE), 
+				(hBlitDC->S0PixelNumOneLine & ((1 << CMD_LPIXEL_NUM_WIDTH) -1)))) return 0;
+
+			if (!BlitRegCheck(hBlitDC, (BLIT_REG_S0_TOTAL_LINE_NUM), 
+				(hBlitDC->S0TotalLineNum & ((1 << CMD_LINE_NUM_WIDTH) -1)))) return 0;
+		}
+		//Color Info
+		if (BlitDCType & (BLIT_DC_S0_COLOR_FORMAT))
+		{
+			if (hBlitDC->S0ColorType != CSBLIT_COLOR_TYPE_ARGB1555)
+			{
+				BlitRegValue = ((hBlitDC->S0ColorType
+						                     & ((1 << CMD_FORMAT_WIDTH) -1)) << CMD_FORMAT_LSB);
+			}
+			else
+			{
+				BlitRegValue = ((hBlitDC->S0ColorType
+						                     & ((1 << CMD_FORMAT_WIDTH) -1)) << CMD_FORMAT_LSB)|
+						      ((hBlitDC->S0Alpha0
+						                     & ((1 << CMD_FORMAT_ALPHA0_WIDTH) -1)) << CMD_FORMAT_ALPHA0_LSB)|
+						      ((hBlitDC->S0Alpha1
+						                     & ((1 << CMD_FORMAT_ALPHA1_WIDTH) -1)) << CMD_FORMAT_ALPHA1_LSB);
+			}				
+			if (!BlitRegCheck(hBlitDC, (BLIT_REG_S0_COLOR_FORMAT), BlitRegValue)) return 0;
+				
+			if (BlitDCType & BLIT_DC_S0_DEFAULT_COLOR)
+			{	
+				BlitRegValue = (((hBlitDC->S0DefaultColor.Value.ARGB8888.Alpha >> (8-8))
+					                     & ((1 << CMD_ALPHA_WIDTH) -1)) << CMD_ALPHA_LSB)|
+					     (((hBlitDC->S0DefaultColor.Value.ARGB8888.R >> (8-8))
+					                     & ((1 << CMD_RED_WIDTH) -1)) << CMD_RED_LSB)|
+					     (((hBlitDC->S0DefaultColor.Value.ARGB8888.G >> (8-8))
+					                     & ((1 << CMD_GREEN_WIDTH) -1)) << CMD_GREEN_LSB)|
+					     (((hBlitDC->S0DefaultColor.Value.ARGB8888.B >> (8-8))
+					                     & ((1 << CMD_BLUE_WIDTH) -1)) << CMD_BLUE_LSB);
+				
+				if (!BlitRegCheck(hBlitDC, (BLIT_REG_S0_DEFAULT_COLOR), (BlitRegValue & BLIT_COLOR_REG_MASK))) return 0;
+			}
+		}
+		
+		//ColorKey ARGB8888
+		if (hBlitDC->S0ColorKeyRGB.RGBEnable && (BlitDCType & BLIT_DC_S0_COLORKEY_PARA))
+		{
+			BlitRegValue =  ((hBlitDC->S0ColorKeyRGB.RMin
+				                     & ((1 << CMD_RED_WIDTH) -1))   << CMD_RED_LSB)    |
+				           ((hBlitDC->S0ColorKeyRGB.GMin
+				                     & ((1 << CMD_GREEN_WIDTH) -1)) << CMD_GREEN_LSB)|
+				           ((hBlitDC->S0ColorKeyRGB.BMin
+				                     & ((1 << CMD_BLUE_WIDTH) -1))  << CMD_BLUE_LSB);
+			if (!BlitRegCheck(hBlitDC, (BLIT_REG_S0_COLOR_KEY_MIN), (BlitRegValue & BLIT_COLOR_REG_MASK))) return 0;
+			
+			BlitRegValue = ((hBlitDC->S0ColorKeyRGB.RMax
+				                     & ((1 << CMD_RED_WIDTH) -1))   << CMD_RED_LSB)    |
+				          ((hBlitDC->S0ColorKeyRGB.GMax
+				                     & ((1 << CMD_GREEN_WIDTH) -1)) << CMD_GREEN_LSB)|
+				          ((hBlitDC->S0ColorKeyRGB.BMax
+				                     & ((1 << CMD_BLUE_WIDTH) -1))  << CMD_BLUE_LSB);
+			if (!BlitRegCheck(hBlitDC, (BLIT_REG_S0_COLOR_KEY_MAX), (BlitRegValue & BLIT_COLOR_REG_MASK))) return 0;
+		}		
+	}	
+	//S1 Related Register Check
+	if (hBlitDC->S1Enable)
+	{
+		if (hBlitDC->S1FetchDram && (BlitDCType & BLIT_DC_S1_DRAM_PARA) )
+		{	
+			if (!BlitRegCheck(hBlitDC, (BLIT_REG_S1_SKIP_PIXEL), 
+				(hBlitDC->S1SkipPixelLine & ((1 << CMD_SKIP_PIXEL_WIDTH) -1)))) return 0;
+			if (!BlitRegCheck(hBlitDC, (BLIT_REG_S1_LINE_PITCH), 
+				(hBlitDC->S1LinePitch & ((1 << CMD_PITCH_WIDTH) -1)))) return 0;
+			if (!BlitRegCheck(hBlitDC, (BLIT_REG_S1_ADDR)      , 
+				(hBlitDC->S1BaseAddr))) return 0;
+			
+			if (!(BlitDCType & BLIT_DC_D_DRAM_PARA))
+			{
+				if (!BlitRegCheck(hBlitDC, (BLIT_REG_PIXEL_NUM_PER_LINE), 
+					(hBlitDC->S1PixelNumOneLine & ((1 << CMD_LPIXEL_NUM_WIDTH) -1)))) return 0;
+
+				if (!BlitRegCheck(hBlitDC, (BLIT_REG_TOTAL_LINE_NUM), 
+					(hBlitDC->S1TotalLineNum & ((1 << CMD_LINE_NUM_WIDTH) -1)))) return 0;
+			}
+		}
+		//Color Info
+		if (BlitDCType & (BLIT_DC_S1_COLOR_FORMAT))
+		{
+			if (hBlitDC->S1ColorType != CSBLIT_COLOR_TYPE_ARGB1555)
+			{
+				BlitRegValue = ((hBlitDC->S1ColorType
+						                     & ((1 << CMD_FORMAT_WIDTH) -1)) << CMD_FORMAT_LSB);
+			}
+			else
+			{
+				BlitRegValue = ((hBlitDC->S1ColorType
+						                     & ((1 << CMD_FORMAT_WIDTH) -1)) << CMD_FORMAT_LSB)|
+						      ((hBlitDC->S1Alpha0
+						                     & ((1 << CMD_FORMAT_ALPHA0_WIDTH) -1)) << CMD_FORMAT_ALPHA0_LSB)|
+						      ((hBlitDC->S1Alpha1
+						                     & ((1 << CMD_FORMAT_ALPHA1_WIDTH) -1)) << CMD_FORMAT_ALPHA1_LSB);
+			}				
+			if (!BlitRegCheck(hBlitDC, (BLIT_REG_S1_COLOR_FORMAT), BlitRegValue)) return 0;
+			
+			if (BlitDCType & BLIT_DC_S1_DEFAULT_COLOR)
+			{
+				
+				BlitRegValue = (((hBlitDC->S1DefaultColor.Value.ARGB8888.Alpha >> (8-8))
+					                     & ((1 << CMD_ALPHA_WIDTH) -1)) << CMD_ALPHA_LSB)|
+					     (((hBlitDC->S1DefaultColor.Value.ARGB8888.R >> (8-8))
+					                     & ((1 << CMD_RED_WIDTH) -1)) << CMD_RED_LSB)|
+					     (((hBlitDC->S1DefaultColor.Value.ARGB8888.G >> (8-8))
+					                     & ((1 << CMD_GREEN_WIDTH) -1)) << CMD_GREEN_LSB)|
+					     (((hBlitDC->S1DefaultColor.Value.ARGB8888.B >> (8-8))
+					                     & ((1 << CMD_BLUE_WIDTH) -1)) << CMD_BLUE_LSB);
+				
+				if (!BlitRegCheck(hBlitDC, (BLIT_REG_S1_DEFAULT_COLOR), (BlitRegValue & BLIT_COLOR_REG_MASK))) return 0;
+			}
+		}
+		
+		//ColorKey ARGB8888
+		if (hBlitDC->S1ColorKeyRGB.RGBEnable && (BlitDCType & BLIT_DC_S1_COLORKEY_PARA))
+		{
+			BlitRegValue =  ((hBlitDC->S1ColorKeyRGB.RMin
+				                     & ((1 << CMD_RED_WIDTH) -1))   << CMD_RED_LSB)    |
+				           ((hBlitDC->S1ColorKeyRGB.GMin
+				                     & ((1 << CMD_GREEN_WIDTH) -1)) << CMD_GREEN_LSB)|
+				           ((hBlitDC->S1ColorKeyRGB.BMin
+				                     & ((1 << CMD_BLUE_WIDTH) -1))  << CMD_BLUE_LSB);
+			if (!BlitRegCheck(hBlitDC, (BLIT_REG_S1_COLOR_KEY_MIN), (BlitRegValue & BLIT_COLOR_REG_MASK))) return 0;
+			
+			BlitRegValue = ((hBlitDC->S1ColorKeyRGB.RMax
+				                     & ((1 << CMD_RED_WIDTH) -1))   << CMD_RED_LSB)    |
+				          ((hBlitDC->S1ColorKeyRGB.GMax
+				                     & ((1 << CMD_GREEN_WIDTH) -1)) << CMD_GREEN_LSB)|
+				          ((hBlitDC->S1ColorKeyRGB.BMax
+				                     & ((1 << CMD_BLUE_WIDTH) -1))  << CMD_BLUE_LSB);
+			if (!BlitRegCheck(hBlitDC, (BLIT_REG_S1_COLOR_KEY_MAX), (BlitRegValue & BLIT_COLOR_REG_MASK))) return 0;
+		}		
+	}
+	//Send D Related Command
+	
+	//D Dram Para
+	if ((BlitDCType & BLIT_DC_D_DRAM_PARA))
+	{
+		if (!BlitRegCheck(hBlitDC, (BLIT_REG_D_SKIP_PIXEL), 
+				(hBlitDC->DSkipPixelLine & ((1 << CMD_SKIP_PIXEL_WIDTH) -1)))) return 0;
+		if (!BlitRegCheck(hBlitDC, (BLIT_REG_D_LINE_PITCH), 
+				(hBlitDC->DLinePitch & ((1 << CMD_PITCH_WIDTH) -1)))) return 0;
+		if (!BlitRegCheck(hBlitDC, (BLIT_REG_D_ADDR)      , 
+				(hBlitDC->DBaseAddr))) return 0;
+		
+		if (!(BlitDCType & BLIT_DC_D_DRAM_PARA))
+		{
+			if (!BlitRegCheck(hBlitDC, (BLIT_REG_PIXEL_NUM_PER_LINE), 
+					(hBlitDC->DPixelNumOneLine & ((1 << CMD_LPIXEL_NUM_WIDTH) -1)))) return 0;
+
+			if (!BlitRegCheck(hBlitDC, (BLIT_REG_TOTAL_LINE_NUM), 
+					(hBlitDC->DTotalLineNum & ((1 << CMD_LINE_NUM_WIDTH) -1)))) return 0;
+		}
+
+	}
+	//D Color Info should not be A0, no Default Color
+	if ((BlitDCType & BLIT_DC_D_COLOR_FORMAT))
+	{
+		if (hBlitDC->S0ColorType != CSBLIT_COLOR_TYPE_ARGB1555)
+		{
+			BlitRegValue = ((hBlitDC->DColorType
+					                     & ((1 << CMD_FORMAT_WIDTH) -1)) << CMD_FORMAT_LSB);
+		}
+		else
+		{
+			BlitRegValue = ((hBlitDC->DColorType
+					                     & ((1 << CMD_FORMAT_WIDTH) -1)) << CMD_FORMAT_LSB)|
+					      ((hBlitDC->DAlpha0Min
+					                     & ((1 << CMD_FORMAT_ALPHA0_MIN_WIDTH) -1)) << CMD_FORMAT_ALPHA0_MIN_LSB)|
+					      ((hBlitDC->DAlpha0Max
+					                     & ((1 << CMD_FORMAT_ALPHA0_MAX_WIDTH) -1)) << CMD_FORMAT_ALPHA0_MAX_LSB);
+		}				
+		if (!BlitRegCheck(hBlitDC, (BLIT_REG_D_COLOR_FORMAT), BlitRegValue)) return 0;
+	}
+	//Clut
+	//Check it Separately
+	//Scalor
+	if (hBlitDC->S0ScalorEnable)
+	{
+		//Scalor Source Pixel Map
+		//Send InitialPhase
+		if ((BlitDCType & BLIT_DC_SCALOR_INIT_PHASE))
+		{			
+			BlitRegValue = (hBlitDC->HInitialPhase 
+				 		         & ((1 << CMD_SCALOR_H_INIT_PHASE_WIDTH) -1));
+			if (!BlitRegCheck(hBlitDC, (BLIT_REG_SCALOR_HORIZONTAL_INITIAL_PHASE), (BlitRegValue))) return 0;
+			
+			BlitRegValue = ((hBlitDC->VInitialPhase    
+				 		         & ((1 << CMD_SCALOR_V_INIT_PHASE_WIDTH) -1))) ;
+			if (!BlitRegCheck(hBlitDC, (BLIT_REG_SCALOR_VERTICAL_INITIAL_PHASE), (BlitRegValue))) return 0;
+		}	
+	}
+	return 1;
+}
+
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/celestial/graphics/blit_hw.h linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/graphics/blit_hw.h
--- linux-linaro-3.4-2012.05-1_original/drivers/celestial/graphics/blit_hw.h	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/graphics/blit_hw.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,218 @@
+/*******************************************************************************
+File name   : blit_hw.h
+
+Description : hardware related header file
+
+COPYRIGHT (C) Celestial Semiconductor 2007.
+
+Date               Modification                                     Name
+----               ------------                                     ----
+20 Jun 2007        Created                                           XM.Chen
+20 Oct 2009		   Modified							 			   Jia.Ma
+*******************************************************************************/
+
+#ifndef _BLIT_HW_H_
+#define _BLIT_HW_H_
+
+#include "cnc18xx_gfxobj.h"
+#include "blit_cmd_reg_def.h"
+
+#ifdef CONFIG_FB_ORION_BLIT_DEBUG
+#define DEBUG_PRINTF  printk
+#else
+#define DEBUG_PRINTF(fmt,args...)
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define CSBLIT_DEVICE_TYPE_1_3 		BLIT_TYPE_1100
+#define CSBLIT_DEVICE_TYPE_1_3_1 	BLIT_TYPE_1200
+
+typedef enum _BLIT_DC_UPDATE_TYPE_
+{
+	BLIT_DC_S0_COLOR_FORMAT   = (1 << 0),
+	BLIT_DC_S0_DEFAULT_COLOR  = (1 << 1),
+	BLIT_DC_S0_COLORKEY_PARA  = (1 << 2),
+	BLIT_DC_S0_DRAM_PARA      = (1 << 3),
+
+	BLIT_DC_S1_COLOR_FORMAT   = (1 << 4),
+	BLIT_DC_S1_DEFAULT_COLOR  = (1 << 5),
+	BLIT_DC_S1_COLORKEY_PARA  = (1 << 6),
+	BLIT_DC_S1_DRAM_PARA      = (1 << 7),
+
+	BLIT_DC_D_COLOR_FORMAT    = (1 << 8),
+	BLIT_DC_D_DRAM_PARA       = (1 << 9),
+
+	BLIT_DC_CLUT4_TABLE       = (1 << 10),
+	BLIT_DC_CLUT8_TABLE       = (1 << 11),
+	//Scalor
+	BLIT_DC_SCALOR_HFIR_COFF  = (1 << 12),
+	BLIT_DC_SCALOR_VFIR_COFF  = (1 << 13),
+	BLIT_DC_SCALOR_INIT_PHASE = (1 << 14),
+	BLIT_DC_CTRL              = (1 << 31),	
+	BLIT_DC_ALL               = (~0x0),
+	
+}BLIT_DC_UPDATE_TYPE;
+
+typedef enum  CSBLIT_AluMode_e
+{
+    CSBLIT_ALU_CLEAR            = 0,      //0      0000
+    CSBLIT_ALU_NOR              = 1,      //~(D|P) 0001
+    CSBLIT_ALU_AND_INVERT       = 2,      //D&~P   0010
+    CSBLIT_ALU_COPY_INVERT      = 3,      //~P     0011
+    CSBLIT_ALU_AND_REV          = 4,      //P&~D   0100
+    CSBLIT_ALU_INVERT           = 5,      //~D     0101
+    CSBLIT_ALU_XOR              = 6,      //D^P    0110
+    CSBLIT_ALU_NAND             = 7,      //~(D&P) 0111
+    CSBLIT_ALU_AND              = 8,      //D&P    1000
+    CSBLIT_ALU_EQUIV            = 9,      //~(P^D) 1001
+    CSBLIT_ALU_NOOP             = 10,     //D      1010
+    CSBLIT_ALU_OR_INVERT        = 11,     //D|~P   1011
+    CSBLIT_ALU_COPY             = 12,     //P      1100
+    CSBLIT_ALU_OR_REVERSE       = 13,     //P|~D   1101
+    CSBLIT_ALU_OR               = 14,     //D|P    1110
+    CSBLIT_ALU_SET              = 15      //1      1111
+//    CSBLIT_ALU_ALPHA_BLEND      = 16
+} CSBLIT_AluMode_t;
+
+enum
+{
+	BLIT_INTERRUPT_MODE   = (0), //1 Enable, 0 Disable
+};
+
+typedef enum CSBLIT_DeviceType_e
+{
+	BLIT_TYPE_1100   = 1, 
+	BLIT_TYPE_1200   = 2
+} CSBLIT_DeviceType_t;
+
+typedef struct CSBlit_HW_Device 
+{
+	u32						RegBaseAddr;	//blitter Register Base address after ioremapped
+	CSBLIT_DeviceType_t 	BlitType;
+	
+	//Run Time Info
+	s32 			BlitIdelStatus;
+	s32 			AHBErrStatus;
+	s32 			BlitErrStatus;
+	s32 			InterruptStatus;    //Interrupt Satatus
+	u32 			CMDCnt;			//CMD count
+	u8				UpdateClut4Table;	//1 Update, 0 donot Update
+	u8				UpdateClut4TableMode;            //0 Update all, 1 Update accoding Idx                               
+	u32 			Clut4TableIdx;
+	u32 			Clut4Table[CLUT4_TABLE_LEN];
+	u8				UpdateClut8Table;                //1 Update, 0 donot Update
+	u8				UpdateClut8TableMode;            //0 Update all, 1 Update accoding Idx
+	u32 			Clut8TableIdx;
+	u32 			Clut8Table[CLUT8_TABLE_LEN];
+	u8				InterruptEnable; 	// 1 interrupt enable
+	
+	//S0 Control
+	u8 			S0Enable;
+	u8 			S0VReverseScan;
+	u8 			S0FetchDram;      // 1 Fetch, 0 do not Fetch Using Default Color in ARGB
+						//if S0 Using Default Color then S0ColorType should be ARGB565 or A0
+	CSBLIT_ColorType_t 	S0ColorType;
+	u32					S0Alpha0;   		//For ARGB1555 Alpha Value 0
+	u32					S0Alpha1;			//For ARGB1555 Alpha Value 1
+	CSBLIT_Color_t   	S0DefaultColor; //ARGB8888 Type
+	u32					S0BaseAddr; 	//Bytes Addr
+	u32					S0LinePitch;    //Bytes Addr
+	u32					S0SkipPixelLine; //Valid Only When Clut4
+	u32					S0PixelNumOneLine;
+	u32					S0TotalLineNum;	
+	u8					S0ByteLittleNotBigEndian;
+	u8					S0NibbleLittleNotBigEndian;
+	u8					S0TwoBytesLittleNotBigEndian;
+
+	u8					S0ClutEnable;
+	//u8				S0ColorKeyEnable;
+	//CSBLIT_Color_t 	S0ColorKeyMin;
+	//CSBLIT_Color_t 	S0ColorKeyMax;
+	CSBLIT_ColorKeyRGB_t 	S0ColorKeyRGB;
+	
+	//S1 Control
+	u8					S1Enable;
+	u8					S1VReverseScan;
+	u8					S1FetchDram;      // 1 Fetch, 0 do not Fetch Using Default Color in ARGB
+						//if S1 Using Default Color then S1ColorType should be ARGB565 or A0
+	CSBLIT_ColorType_t 	S1ColorType;
+	u32					S1Alpha0;   //For ARGB1555 Alpha Value 0
+	u32					S1Alpha1;	//For ARGB1555 Alpha Value 1
+
+	CSBLIT_Color_t   	S1DefaultColor;
+	u32					S1BaseAddr;    //Bytes Addr
+	u32					S1LinePitch;   //Bytes Addr
+	u32					S1SkipPixelLine;  //Valid Only When Clut4
+	u32					S1PixelNumOneLine;
+	u32					S1TotalLineNum;	
+	u8					S1ByteLittleNotBigEndian;
+	u8					S1NibbleLittleNotBigEndian;
+	u8					S1TwoBytesLittleNotBigEndian;
+
+	u8					S1ClutEnable;
+	//u8				S1ColorKeyEnable;
+	//CSBLIT_Color_t 	S1ColorKeyMin;
+	//CSBLIT_Color_t 	S1ColorKeyMax;
+	CSBLIT_ColorKeyRGB_t 	S1ColorKeyRGB;
+
+    	//ROP and Compositor
+	u8					CompositorEnable;
+	u32					ROPAlphaCtrl;
+
+	/*ROP_OPT*/
+    CSBLIT_AluMode_t 	RopValue;
+	u8					S0OnTopS1;  // 1 S0 On Top S1
+
+	//D Dram Para
+	u8					DVReverseScan;
+	u32					DBaseAddr;  //Bytes Addr
+	u32					DLinePitch; //Bytes Addr
+	u32					DSkipPixelLine; //Valid Only When Clut4
+	u32					DPixelNumOneLine;
+	u32					DTotalLineNum;
+	CSBLIT_ColorType_t 	DColorType;
+	u32					DAlpha0Min;
+	u32					DAlpha0Max;
+	u8					DByteLittleNotBigEndian;
+	u8					DNibbleLittleNotBigEndian;
+	u8					DTwoBytesLittleNotBigEndian;
+
+	//Special Endian Ctrl
+	u8					IsUsingSDSpecificEndian; //0, Global Endian, 1 Specifica Endian
+
+	//Scalor Control
+	u8					S0ScalorEnable;
+	u32					HInitialPhase;
+	u32					VInitialPhase;
+	u8					UpdateHFIRCoeff;
+	u8					UpdateVFIRCoeff;
+	u32					HFIRCoeffTable[SCALOR_PAHSE_NUM][SCALOR_H_FIR_TAP_NUM];
+	u32					VFIRCoeffTable[SCALOR_PAHSE_NUM][SCALOR_V_FIR_TAP_NUM];
+	BLIT_DC_UPDATE_TYPE 	BlitDCType;
+} CSBlit_HW_Device_t;
+
+void HardWareReset(CSBlit_HW_Device_t *hBlitDC);
+u32 GetCMDQueueDepth(void);
+void SWReset(CSBlit_HW_Device_t *hBlitDC);
+s32 WaitCMDQueueEmpty(CSBlit_HW_Device_t *hBlitDC);
+
+u32 GetCMDGroupCnt(void);
+void CMDGroupCntSyncHW(CSBlit_HW_Device_t *hBlitDC);
+s32 SendCMD(CSBlit_HW_Device_t *hBlitDC, u32 BlitCMD);
+s32 WaitBlitToBeIdle(CSBlit_HW_Device_t *hBlitDC); //Boolean Type Return
+s32 WaitBlitScalorToBeIdle(CSBlit_HW_Device_t *hBlitDC); //Boolean Type Return
+s32 ActiveDeviceContext( CSBlit_HW_Device_t *hBlitDC, BLIT_DC_UPDATE_TYPE BlitDCType);
+
+s32 RegCheckClutTable(CSBlit_HW_Device_t *hBlitDC, BLIT_DC_UPDATE_TYPE BlitDCType, s32 IsClut4orClut8); //0: Clut4, 1: Clut8;
+s32 RegCheckPosStartup(CSBlit_HW_Device_t *hBlitDC, BLIT_DC_UPDATE_TYPE BlitDCType);
+s32 RegCheckPreStartup(CSBlit_HW_Device_t *hBlitDC, BLIT_DC_UPDATE_TYPE BlitDCType); //Boolean Type Return
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //_BLIT_HW_H_
+
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/celestial/graphics/blit_ioctl.c linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/graphics/blit_ioctl.c
--- linux-linaro-3.4-2012.05-1_original/drivers/celestial/graphics/blit_ioctl.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/graphics/blit_ioctl.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,1317 @@
+#include <linux/version.h>
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/cdev.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+
+#include "blit_ioctl.h"
+
+/* function declaration ------------------------------------- */
+
+/* valid returns 1, invalid returns 0 */
+static s32 IsRectValid(CSBLIT_Bitmap_t *Img, CSBLIT_Rectangle_t *Rect) //Boolean
+{
+	if (Img == NULL || Rect == NULL) 
+	{
+		return 0;
+	}
+	else if (Rect->PositionX   < 0 || Rect->PositionX   > Img->Width  ||
+		     Rect->PositionY    < 0 || Rect->PositionY    > Img->Height ||
+		     Rect->PositionX + Rect->Width  < 0 || Rect->PositionX + Rect->Width  > Img->Width  ||
+		     Rect->PositionY + Rect->Height < 0 || Rect->PositionY + Rect->Height > Img->Height )
+	{
+		return 0;
+	}
+	else if (!(Rect->PositionX  <= Rect->PositionX + Rect->Width) || 
+		     !(Rect->PositionY   <= Rect->PositionY + Rect->Height) )
+	{
+		return 0;
+	}
+	else
+	{
+		return 1;
+	}
+
+}
+
+/* compare rect, Equal return 1; not Equal return 0 */
+static s32 CmpRect( CSBLIT_Rectangle_t *Rect0, CSBLIT_Rectangle_t *Rect1) 
+{
+	if (!(Rect0->PositionX <= Rect0->PositionX + Rect0->Width) || 
+		!(Rect0->PositionY <= Rect0->PositionY + Rect0->Height) )
+	{
+		return 0;
+	}
+	else if (!(Rect1->PositionX <= Rect1->PositionX + Rect1->Width) || 
+		     !(Rect1->PositionY <= Rect1->PositionY + Rect1->Height) )
+	{
+		return 0;
+	}
+	else if ((Rect0->Width != Rect1->Width) || (Rect0->Height != Rect1->Height))	
+	{
+		return 0;
+	}
+	else
+	{
+		return 1;
+	}
+}
+
+/* valid returns 1, invalid returns 0 */
+static s32 IsColorTypeValid( CSBLIT_ColorType_t ColorType)
+{
+	switch (ColorType)
+	{
+		case CSBLIT_COLOR_TYPE_RGB565:
+		case CSBLIT_COLOR_TYPE_ARGB4444:
+		case CSBLIT_COLOR_TYPE_A0:
+		case CSBLIT_COLOR_TYPE_CLUT8:
+		case CSBLIT_COLOR_TYPE_CLUT4:
+		case CSBLIT_COLOR_TYPE_ARGB1555:
+		case CSBLIT_COLOR_TYPE_ARGB8888:
+			return 1;
+		default:
+			return 0;
+	}
+}
+
+static int CalcuDramPara
+(
+    	CSBLIT_Bitmap_t 		*DesImg, 
+    	CSBLIT_Rectangle_t      	*DesRect,	
+    	s32        			IsVReverse,
+	u32       			*pBaseAddr,          //Bytes Addr
+	u32       			*pLinePitch,         //Bytes Addr
+	u32       			*pSkipPixelLine      //Valid Only When Clut4
+)
+{
+    u32 PixelBitWidth = 0;
+    u32 BaseAddr      = 0;                        //Bytes Addr
+    u32 LinePitch     = 0;                       //Bytes Addr
+    u32 SkipPixelLine = 0;              //Valid Only When Clut4
+
+    switch (DesImg->ColorType)
+    {
+	case CSBLIT_COLOR_TYPE_ARGB8888:
+		PixelBitWidth = 32;
+		break;
+	case CSBLIT_COLOR_TYPE_RGB565:			
+	case CSBLIT_COLOR_TYPE_ARGB4444:
+	case CSBLIT_COLOR_TYPE_ARGB1555:
+	case CSBLIT_COLOR_TYPE_A0:
+	    PixelBitWidth = 16;
+	    break;
+	case CSBLIT_COLOR_TYPE_CLUT8:
+	    PixelBitWidth =  8;
+	    break;
+	case CSBLIT_COLOR_TYPE_CLUT4:
+	    PixelBitWidth =  4;
+	    break;
+	default:
+	    PixelBitWidth =  0;
+	    break;
+    }
+
+    if (PixelBitWidth == 0)
+	return -EINVAL;
+
+    /*if Clut4 and Width is odd, the Line width should be Bytes Aligned*/
+    //LinePitch = (DesImg->Width * PixelBitWidth + 8 - 1) / 8;
+    LinePitch = DesImg->Pitch;
+    if (!IsVReverse)
+    {
+	BaseAddr = (u32)DesImg->Data_p + 
+	    DesRect->PositionY * LinePitch +                
+	    (DesRect->PositionX * PixelBitWidth) / 8;
+    }
+    else
+    {
+	u32 LineIdx 	= 0;
+	LineIdx  	= DesRect->PositionY + DesRect->Height;
+	if (LineIdx > 0) 
+	    LineIdx--;
+	BaseAddr 	= (u32)DesImg->Data_p + LineIdx* LinePitch +   \
+	    			(DesRect->PositionX * PixelBitWidth) / 8;
+    }
+    SkipPixelLine   = ((DesRect->PositionX * PixelBitWidth) % 8) / PixelBitWidth;
+    *pBaseAddr      = BaseAddr;                        //Bytes Addr
+    *pLinePitch     = LinePitch;                       //Bytes Addr
+    *pSkipPixelLine = SkipPixelLine;              //Valid Only When Clut4
+
+    return 0;
+}
+
+static u32 SCALOR_COEFF( u32 SignBit, u32 Numerator, u32 Denominator) 
+{
+	return (((SignBit) << SCALOR_COEFF_POLARITY_BIT)  | \
+		   ((((Numerator)) << SCALOR_COEFF_FRACTION_BIT_WIDTH ) / (Denominator)));
+}
+
+static u32 *GetDefaultScalorHFIRCoeff(void)
+{
+	static u32 HFIRCoeffTable[SCALOR_PAHSE_NUM][SCALOR_H_FIR_TAP_NUM];
+	u32 Phase = 0;
+	
+	/*assert(SCALOR_H_FIR_TAP_NUM == 4);*/
+	for (Phase = 0 ; Phase < SCALOR_PAHSE_NUM; Phase++)
+	{
+		HFIRCoeffTable[Phase][0] = 0;
+		HFIRCoeffTable[Phase][1] = SCALOR_COEFF( 0, (SCALOR_PAHSE_NUM - Phase), SCALOR_PAHSE_NUM);
+		HFIRCoeffTable[Phase][2] = SCALOR_COEFF( 0, (Phase), SCALOR_PAHSE_NUM);
+		HFIRCoeffTable[Phase][3] = 0;
+	}
+	return HFIRCoeffTable[0];
+}
+
+static u32 *GetDefaultScalorVFIRCoeff(void)
+{
+	static u32 VFIRCoeffTable[SCALOR_PAHSE_NUM][SCALOR_V_FIR_TAP_NUM];
+	u32 Phase = 0;
+	
+	/*assert(SCALOR_V_FIR_TAP_NUM == 2);*/
+	for (Phase = 0 ; Phase < SCALOR_PAHSE_NUM; Phase++)
+	{
+		VFIRCoeffTable[Phase][0] = SCALOR_COEFF( 0, (SCALOR_PAHSE_NUM - Phase), SCALOR_PAHSE_NUM);
+		VFIRCoeffTable[Phase][1] = SCALOR_COEFF( 0, (Phase), SCALOR_PAHSE_NUM);
+	}
+	return VFIRCoeffTable[0];	
+}
+
+static int InitScalorHFIRCoeff(CSBlit_HW_Device_t *hBlitDC, u32 *HFIRCoeff)
+{
+	if (hBlitDC == NULL || HFIRCoeff == NULL) 
+	{
+		return -EINVAL;
+	}
+	else
+	{
+		int Err = -EINVAL;
+		u32 *p = NULL;
+		for (p = hBlitDC->HFIRCoeffTable[0];
+		     p < hBlitDC->HFIRCoeffTable[0] + SCALOR_PAHSE_NUM * SCALOR_H_FIR_TAP_NUM;
+			 p++)
+		{
+			*p = *HFIRCoeff++;
+		}
+		hBlitDC->UpdateHFIRCoeff = TRUE;
+		if (!ActiveDeviceContext(hBlitDC, BLIT_DC_SCALOR_HFIR_COFF))
+		{
+			Err = -EINVAL;
+		}
+		else
+		{	
+			Err = 0;
+		}
+		hBlitDC->UpdateHFIRCoeff = FALSE;
+		return Err;
+	}
+}
+
+static int InitScalorVFIRCoeff(CSBlit_HW_Device_t *hBlitDC, u32 *VFIRCoeff)
+{
+	if (hBlitDC == NULL || VFIRCoeff == NULL) 
+		return -EINVAL;
+	else
+	{
+		int Err = -EINVAL;
+		u32 *p = NULL;
+		for (p = hBlitDC->VFIRCoeffTable[0];
+		     p < hBlitDC->VFIRCoeffTable[0] + SCALOR_PAHSE_NUM * SCALOR_V_FIR_TAP_NUM;
+			 p++)
+		{
+			*p = *VFIRCoeff++;
+		}
+		hBlitDC->UpdateVFIRCoeff = TRUE;
+		if (!ActiveDeviceContext(hBlitDC, BLIT_DC_SCALOR_VFIR_COFF))
+		{
+			Err = -EINVAL;
+		}
+		else
+		{	
+			Err = 0;
+		}
+		hBlitDC->UpdateVFIRCoeff = FALSE;
+
+		return Err;
+	}	
+}
+
+static int SetDefaultScalorHFIRCoeff(CSBlit_HW_Device_t *hBlitDC)
+{
+	if (hBlitDC == NULL)
+	{
+		return -EINVAL;
+	}
+	else //Scalor Coeffecient Setting
+	{
+		int Err = -EINVAL;
+		u32 *HFIRCoeff = NULL;
+		HFIRCoeff = GetDefaultScalorHFIRCoeff();
+		if (HFIRCoeff == NULL)
+		{
+			return -EINVAL;
+		}
+		Err   = InitScalorHFIRCoeff(hBlitDC, HFIRCoeff);
+		
+		return Err;
+	}
+}
+
+static int SetDefaultScalorVFIRCoeff(CSBlit_HW_Device_t *hBlitDC)
+{
+	if (hBlitDC == NULL)
+	{
+		return -EINVAL;
+	}
+	else	//Scalor Coeffecient Setting
+	{
+		int Err = -EINVAL;
+		u32 *VFIRCoeff = NULL;
+		VFIRCoeff = GetDefaultScalorVFIRCoeff();
+		if (VFIRCoeff == NULL)
+		{
+			return -EINVAL;
+		}
+		Err   = InitScalorVFIRCoeff(hBlitDC, VFIRCoeff);
+		return Err;
+	}
+}
+
+//Hardware initialize
+int blit_initialize(CSBlit_HW_Device_t *hBlitDC)
+{
+    HardWareReset(hBlitDC);
+    if(hBlitDC->BlitType == BLIT_TYPE_1200)
+    {
+    	SWReset(hBlitDC);
+	SetDefaultScalorVFIRCoeff(hBlitDC);
+	SetDefaultScalorHFIRCoeff(hBlitDC);
+    }
+    return 0;
+}
+
+int Fill
+( 
+    CSBlit_HW_Device_t 		*hBlitDC, 
+    s32                 	BlitSrcId,
+    CSBLIT_Bitmap_t       	*DesImg, 
+    CSBLIT_Rectangle_t    	*DesRect, 
+    CSBLIT_Color_t 		*FillColor,
+    CSBLIT_AluMode_t 		AluMode
+)
+{
+	DEBUG_PRINTF("ORION_BLIT : %s, %d\n",__FUNCTION__,__LINE__);
+	if (hBlitDC  == NULL || BlitSrcId > 1 || DesImg  == NULL || DesRect == NULL || FillColor == NULL)
+	{
+		DEBUG_PRINTF("ORION_BLIT : %s, %d\n",__FUNCTION__,__LINE__);
+		return -EINVAL;
+	}
+	else if (!IsColorTypeValid(DesImg->ColorType))
+	{
+		DEBUG_PRINTF("ORION_BLIT : %s, %d\n",__FUNCTION__,__LINE__);
+		return -EINVAL;
+	}
+	else if (!IsRectValid(DesImg, DesRect))
+	{
+		DEBUG_PRINTF("ORION_BLIT : %s, %d\n",__FUNCTION__,__LINE__);
+		return -EINVAL;
+	}
+	else
+	{
+		int Err = -EINVAL;
+	//S0 Control
+		DEBUG_PRINTF("ORION_BLIT : %s, %d\n",__FUNCTION__,__LINE__);
+		if (BlitSrcId == 0)
+		{
+			hBlitDC->S0Enable       = TRUE;
+			hBlitDC->S0VReverseScan = FALSE;
+			hBlitDC->S0FetchDram    = FALSE;          // 1 Fetch, 0 do not Fetch Using Default Color in ARGB
+			                                     // if S0 Using Default Color then S0ColorType should be or A0
+			hBlitDC->S0ColorType  = CSBLIT_COLOR_TYPE_A0;  //Must
+
+			hBlitDC->S0DefaultColor.Type =  CSBLIT_COLOR_TYPE_ARGB8888;     //ARGB8888 Format
+			hBlitDC->S0DefaultColor.Value.ARGB8888.Alpha = FillColor->Value.ARGB8888.Alpha;     //ARGB8888 Format
+			hBlitDC->S0DefaultColor.Value.ARGB8888.R = FillColor->Value.ARGB8888.R;       //ARGB8888 Format
+			hBlitDC->S0DefaultColor.Value.ARGB8888.G = FillColor->Value.ARGB8888.G;     //ARGB8888 Format
+			hBlitDC->S0DefaultColor.Value.ARGB8888.B = FillColor->Value.ARGB8888.B;      //ARGB8888 Format
+			/*
+			hBlitDC->S0BaseAddr;                      //Bytes Addr
+			hBlitDC->S0LinePitch;                     //Bytes Addr
+			hBlitDC->S0SkipPixelLine;            //Valid Only When Clut4
+			hBlitDC->S0PixelNumOneLine;
+			hBlitDC->S0TotalLineNum;	
+			hBlitDC->S0ByteLittleNotBigEndian;
+			hBlitDC->S0NibbleLittleNotBigEndian;
+			*/
+			hBlitDC->S0ClutEnable     = FALSE;
+			hBlitDC->S0ColorKeyRGB.RGBEnable = FALSE;
+			/*
+			hBlitDC->S0ColorKeyMin;
+			hBlitDC->S0ColorKeyMax;
+			*/
+		}
+		else
+		{
+			hBlitDC->S0Enable       =  FALSE;
+			hBlitDC->S0FetchDram    =  FALSE;
+		}
+	//S1 Control
+		if (BlitSrcId == 1)
+		{
+			hBlitDC->S1Enable       = TRUE;
+			hBlitDC->S1VReverseScan =  FALSE;
+			hBlitDC->S1FetchDram    =  FALSE;          // 1 Fetch, 0 do not Fetch Using Default Color in ARGB
+			                                     // if S1 Using Default Color then S1ColorType should be or A0
+			hBlitDC->S1ColorType  = CSBLIT_COLOR_TYPE_A0;  //Must
+
+			hBlitDC->S1DefaultColor.Type =  CSBLIT_COLOR_TYPE_ARGB8888;     //ARGB8888 Format
+			hBlitDC->S1DefaultColor.Value.ARGB8888.Alpha = FillColor->Value.ARGB8888.Alpha;     //ARGB8888 Format
+			hBlitDC->S1DefaultColor.Value.ARGB8888.R = FillColor->Value.ARGB8888.R;       //ARGB8888 Format
+			hBlitDC->S1DefaultColor.Value.ARGB8888.G = FillColor->Value.ARGB8888.G;     //ARGB8888 Format
+			hBlitDC->S1DefaultColor.Value.ARGB8888.B = FillColor->Value.ARGB8888.B;      //ARGB8888 Format
+/*--------------------------------------------------
+* printf("R:0x%x G:0x%x B: 0x%x A:0x%x\n",hBlitDC->S1DefaultColor.Value.ARGB8888.R,hBlitDC->S1DefaultColor.Value.ARGB8888.G,hBlitDC->S1DefaultColor.Value.ARGB8888.B,hBlitDC->S1DefaultColor.Value.ARGB8888.Alpha);
+*--------------------------------------------------*/
+			/*
+			hBlitDC->S1BaseAddr;                      //Bytes Addr
+			hBlitDC->S1LinePitch;                     //Bytes Addr
+			hBlitDC->S1SkipPixelLine;            //Valid Only When Clut4
+			hBlitDC->S1PixelNumOneLine;
+			hBlitDC->S1TotalLineNum;	
+			hBlitDC->S1ByteLittleNotBigEndian;
+			hBlitDC->S1NibbleLittleNotBigEndian;
+			*/
+			hBlitDC->S1ClutEnable     = FALSE;
+			hBlitDC->S1ColorKeyRGB.RGBEnable = FALSE;
+			/*
+			hBlitDC->S1ColorKeyMin;
+			hBlitDC->S1ColorKeyMax;
+			*/
+		}
+		else
+		{
+			hBlitDC->S1Enable       = FALSE;
+			hBlitDC->S1FetchDram    = FALSE; 			
+		}
+
+	    //ROP and Compositor
+		if(hBlitDC->BlitType == CSBLIT_DEVICE_TYPE_1_3)
+		{
+			hBlitDC->ROPAlphaCtrl       = FALSE;
+		}
+		else if(hBlitDC->BlitType == CSBLIT_DEVICE_TYPE_1_3_1)
+		{
+			hBlitDC->ROPAlphaCtrl       = TRUE;
+		}
+		hBlitDC->CompositorEnable   = FALSE;
+		hBlitDC->RopValue = AluMode;
+		/*hBlitDC->S0OnTopS1;*/                        // 1 S0 On Top S1
+		/*D Dram Para*/		
+		if(CalcuDramPara (
+		    DesImg, 
+		    DesRect,	
+		    hBlitDC->DVReverseScan = FALSE,
+			&hBlitDC->DBaseAddr,     /*Bytes Addr*/
+			&hBlitDC->DLinePitch,    /*Bytes Addr*/
+			&hBlitDC->DSkipPixelLine /*Valid Only When Clut4*/) != 0)
+		{
+			DEBUG_PRINTF("ORION_BLIT : %s, %d\n",__FUNCTION__,__LINE__);
+			return -EINVAL;
+		}
+		hBlitDC->DPixelNumOneLine    = DesRect->Width;
+		hBlitDC->DTotalLineNum       = DesRect->Height;
+		
+		hBlitDC->DColorType        = DesImg->ColorType;
+		hBlitDC->DNibbleLittleNotBigEndian = 0;	
+		hBlitDC->DByteLittleNotBigEndian = 1;
+		hBlitDC->DTwoBytesLittleNotBigEndian = 1;
+		if(DesImg->ColorType == CSBLIT_COLOR_TYPE_ARGB8888){
+			hBlitDC->DTwoBytesLittleNotBigEndian = 0;
+		}
+
+		//Scalor Control
+		hBlitDC->S0ScalorEnable  = FALSE;
+		//hBlitDC->HInitialPhase   = 0;
+		//hBlitDC->VInitialPhase   = 0;
+		hBlitDC->UpdateHFIRCoeff = FALSE;
+		hBlitDC->UpdateVFIRCoeff = FALSE;
+
+		//Clut para
+		hBlitDC->UpdateClut4Table = FALSE;
+		hBlitDC->UpdateClut8Table = FALSE;
+		//RunTimeControl
+		hBlitDC->InterruptEnable  = BLIT_INTERRUPT_MODE;
+
+		//active DC
+		if (!ActiveDeviceContext(hBlitDC, BLIT_DC_ALL))
+		{
+			Err = -EINVAL;
+		}
+		//Waitting for Idiel
+		else if (!WaitBlitToBeIdle(hBlitDC))
+		{
+			Err = -EINVAL;
+		}
+		else
+		{
+			Err = 0;
+		}
+
+		DEBUG_PRINTF("ORION_BLIT : %s, %d , Err = %d\n",__FUNCTION__,__LINE__,Err);
+		return Err;
+	}
+}
+
+int Copy
+( 
+    CSBlit_HW_Device_t  	*hBlitDC, 
+    s32                  	BlitSrcId,
+    CSBLIT_Bitmap_t			*SrcImg, 
+    CSBLIT_Rectangle_t		*SrcRect, 
+    s32                  	SrcVReverse,
+    CSBLIT_Bitmap_t			*DesImg, 
+    CSBLIT_Rectangle_t		*DesRect, 
+    CSBLIT_AluMode_t 		AluMode,
+    s32                  	DesVReverse
+)
+{
+	if (hBlitDC  == NULL || SrcImg  == NULL || SrcRect == NULL || DesImg  == NULL || DesRect == NULL)
+	{
+		return -EINVAL;
+	}
+	if(BlitSrcId != 0 && BlitSrcId != 1)
+	{
+		return -EINVAL;
+	}
+	else if (!IsColorTypeValid(SrcImg->ColorType) || //Scalor RTL S0 Support ARGB4444 and RGB565 Only
+		     !IsColorTypeValid(DesImg->ColorType)  )
+	{
+		return -EINVAL;
+	}
+	else if (!IsRectValid(SrcImg, SrcRect))
+	{
+		return -EINVAL;
+	}
+	else if (!IsRectValid(DesImg, DesRect))
+	{
+		return -EINVAL;
+	}
+	else if (!CmpRect(SrcRect, DesRect))//Check SrcRect and DesRect
+	{
+		return -EINVAL;
+	}
+	else
+	{
+		int Err = -EINVAL;
+	//S0 Control
+		if (BlitSrcId == 0)
+		{
+			hBlitDC->S0Enable       = TRUE;
+			hBlitDC->S0VReverseScan = SrcVReverse;
+			hBlitDC->S0FetchDram    = TRUE;          // 1 Fetch, 0 do not Fetch Using Default Color in ARGB
+			                                     // if S0 Using Default Color then S0ColorType should be or A0
+			hBlitDC->S0ColorType  = SrcImg->ColorType;  //Must
+			hBlitDC->S0DefaultColor.Type =  CSBLIT_COLOR_TYPE_ARGB8888;     //ARGB8888 Format
+			hBlitDC->S0DefaultColor.Value.ARGB8888.Alpha = 0xFF;	/*FillColor->Value.ARGB8888.Alpha;*/     //ARGB8888 Format
+			//hBlitDC->S0DefaultColor.Alpha = 0xFF;     //ARGB8888 Format, For Copy Don't change Source Alpha
+			/*
+			hBlitDC->S0DefaultColor.Red   = SrcImg->DefaultColor->Red;       //ARGB8888 Format
+			hBlitDC->S0DefaultColor.Green = SrcImg->DefaultColor->Green;     //ARGB8888 Format
+			hBlitDC->S0DefaultColor.Blue  = SrcImg->DefaultColor->Blue;      //ARGB8888 Format
+			*/
+			CalcuDramPara
+			(
+			    SrcImg, 
+			    SrcRect,	
+			    hBlitDC->S0VReverseScan,
+				&hBlitDC->S0BaseAddr,              //Bytes Addr
+				&hBlitDC->S0LinePitch,             //Bytes Addr
+				&hBlitDC->S0SkipPixelLine         //Valid Only When Clut4
+			);
+			hBlitDC->S0PixelNumOneLine    = SrcRect->Width;
+			hBlitDC->S0TotalLineNum       = SrcRect->Height;
+
+			hBlitDC->S0NibbleLittleNotBigEndian = 0;	
+			hBlitDC->S0ByteLittleNotBigEndian = 1;
+			hBlitDC->S0TwoBytesLittleNotBigEndian = 1;
+			if(SrcImg->ColorType == CSBLIT_COLOR_TYPE_ARGB8888){
+				hBlitDC->S0TwoBytesLittleNotBigEndian = 0;
+			}
+
+			hBlitDC->S0ClutEnable     = (SrcImg->ColorType == CSBLIT_COLOR_TYPE_CLUT4 ||
+				                        SrcImg->ColorType == CSBLIT_COLOR_TYPE_CLUT8 );
+			hBlitDC->S0ColorKeyRGB.RGBEnable = FALSE;
+			/*
+			hBlitDC->S0ColorKeyMin;
+			hBlitDC->S0ColorKeyMax;
+			*/
+		}
+		else
+		{
+			hBlitDC->S0Enable       = FALSE;
+			hBlitDC->S0FetchDram    = FALSE;
+		}
+	//S1 Control
+		if (BlitSrcId == 1)
+		{
+			hBlitDC->S1Enable       = TRUE;
+			hBlitDC->S1VReverseScan = SrcVReverse;
+			hBlitDC->S1FetchDram    = TRUE;          // 1 Fetch, 0 do not Fetch Using Default Color in ARGB
+			                                     // if S1 Using Default Color then S1ColorType should be or A0
+			hBlitDC->S1ColorType  = SrcImg->ColorType;  //Must
+			hBlitDC->S1DefaultColor.Type =  CSBLIT_COLOR_TYPE_ARGB8888;     //ARGB8888 Format
+			hBlitDC->S1DefaultColor.Value.ARGB8888.Alpha = 0xFF;	/*FillColor->Value.ARGB8888.Alpha;*/     //ARGB8888 Format
+			//hBlitDC->S1DefaultColor.Alpha = 0xFF;     //ARGB8888 Format, For Copy Don't change Source Alpha
+			/*
+			hBlitDC->S1DefaultColor.Red   = SrcImg->DefaultColor->Red;       //ARGB8888 Format
+			hBlitDC->S1DefaultColor.Green = SrcImg->DefaultColor->Green;     //ARGB8888 Format
+			hBlitDC->S1DefaultColor.Blue  = SrcImg->DefaultColor->Blue;      //ARGB8888 Format
+			*/
+			CalcuDramPara
+			(
+			    SrcImg, 
+			    SrcRect,	
+			    hBlitDC->S1VReverseScan,
+				&hBlitDC->S1BaseAddr,              //Bytes Addr
+				&hBlitDC->S1LinePitch,             //Bytes Addr
+				&hBlitDC->S1SkipPixelLine         //Valid Only When Clut4
+			);
+			hBlitDC->S1PixelNumOneLine    = SrcRect->Width;
+			hBlitDC->S1TotalLineNum       = SrcRect->Height;
+
+			hBlitDC->S1NibbleLittleNotBigEndian = 0;	
+			hBlitDC->S1ByteLittleNotBigEndian = 1;
+			hBlitDC->S1TwoBytesLittleNotBigEndian = 1;
+			if(SrcImg->ColorType == CSBLIT_COLOR_TYPE_ARGB8888){
+				hBlitDC->S1TwoBytesLittleNotBigEndian = 0;
+			}
+
+			hBlitDC->S1ClutEnable     = (SrcImg->ColorType == CSBLIT_COLOR_TYPE_CLUT4 ||
+				                        SrcImg->ColorType == CSBLIT_COLOR_TYPE_CLUT8 );
+			hBlitDC->S1ColorKeyRGB.RGBEnable = FALSE;
+			/*
+			hBlitDC->S1ColorKeyMin;
+			hBlitDC->S1ColorKeyMax;
+			*/
+		}
+		else
+		{
+			hBlitDC->S1Enable       = FALSE;
+			hBlitDC->S1FetchDram    = FALSE;
+		}
+
+		//ROP and Compositor
+		if(hBlitDC->BlitType == CSBLIT_DEVICE_TYPE_1_3)
+		{
+			hBlitDC->ROPAlphaCtrl       = FALSE;
+		}
+		else if(hBlitDC->BlitType == CSBLIT_DEVICE_TYPE_1_3_1)
+		{
+			hBlitDC->ROPAlphaCtrl       = TRUE;
+		}
+		hBlitDC->CompositorEnable   = FALSE;
+		hBlitDC->RopValue = AluMode;
+		//hBlitDC->S0OnTopS1;                        // 1 S0 On Top S1
+		//D Dram Para		
+		CalcuDramPara
+		(
+		    DesImg, 
+		    DesRect,	
+		    hBlitDC->DVReverseScan = DesVReverse,
+			&hBlitDC->DBaseAddr,              //Bytes Addr
+			&hBlitDC->DLinePitch,             //Bytes Addr
+			&hBlitDC->DSkipPixelLine         //Valid Only When Clut4
+		);
+		hBlitDC->DPixelNumOneLine    = DesRect->Width;
+		hBlitDC->DTotalLineNum       = DesRect->Height;
+		
+		hBlitDC->DColorType        = DesImg->ColorType;
+
+		hBlitDC->DNibbleLittleNotBigEndian = 0;	
+		hBlitDC->DByteLittleNotBigEndian = 1;
+		hBlitDC->DTwoBytesLittleNotBigEndian = 1;
+		if(DesImg->ColorType == CSBLIT_COLOR_TYPE_ARGB8888){
+			hBlitDC->DTwoBytesLittleNotBigEndian = 0;
+		}
+
+		//Scalor Control
+		hBlitDC->S0ScalorEnable   = FALSE;
+		//hBlitDC->HInitialPhase   = 0;
+		//hBlitDC->VInitialPhase   = 0;
+		hBlitDC->UpdateHFIRCoeff  = FALSE;
+		hBlitDC->UpdateVFIRCoeff  = FALSE;
+
+		//Clut para
+		hBlitDC->UpdateClut4Table = FALSE;
+		hBlitDC->UpdateClut8Table = FALSE;
+		//RunTimeControl
+		hBlitDC->InterruptEnable  = BLIT_INTERRUPT_MODE;
+		
+		//active DC
+		if (!ActiveDeviceContext(hBlitDC, BLIT_DC_ALL))
+		{
+			Err = -EINVAL;
+		}
+		else if (!WaitBlitToBeIdle(hBlitDC))
+		{
+			Err = -EINVAL;
+		}
+		else
+		{
+			Err = 0;
+		}
+		return Err;
+	}
+}
+
+
+int Scalor
+( 
+    CSBlit_HW_Device_t  	*hBlitDC, 
+    CSBLIT_Source_t		*SrcPara,    
+    CSBLIT_Destination_t 	*DesPara,
+    u32                  	VInitialPhase, 
+    u32                  	HInitialPhase,
+    CSBLIT_AluMode_t 		AluMode
+)
+{
+    CSBLIT_Bitmap_t     	*SrcImg = &SrcPara->Data.Bitmap;
+    CSBLIT_Rectangle_t  	*SrcRect = &SrcPara->Rectangle; 
+    CSBLIT_Bitmap_t		   	*DesImg = &DesPara->Bitmap; 
+   	CSBLIT_Rectangle_t		*DesRect = &DesPara->Rectangle;
+
+	if (hBlitDC == NULL || SrcPara == NULL || DesPara == NULL ||
+			SrcImg == NULL || SrcRect == NULL || 
+			DesImg == NULL || DesRect == NULL)
+	{
+		DEBUG_PRINTF("ORION_BLIT : %s, %d\n",__FUNCTION__,__LINE__);
+		return -EINVAL;
+	}
+	else if (!IsColorTypeValid(SrcImg->ColorType)) //Scalor RTL S0 Support ARGB4444 and RGB565 Only
+	{
+		DEBUG_PRINTF("ORION_BLIT : %s, %d\n",__FUNCTION__,__LINE__);
+		return -EINVAL;
+	}
+	else if (!IsRectValid(SrcImg, SrcRect))
+	{
+		DEBUG_PRINTF("ORION_BLIT : %s, %d\n",__FUNCTION__,__LINE__);
+		return -EINVAL;
+	}
+	else if (!IsRectValid(DesImg, DesRect))
+	{
+		DEBUG_PRINTF("ORION_BLIT : %s, %d\n",__FUNCTION__,__LINE__);
+		return -EINVAL;
+	}
+	else
+	{
+		int Err = -EINVAL;
+		{	//S0 Control
+			hBlitDC->S0Enable       = TRUE;
+			hBlitDC->S0VReverseScan = SrcPara->VReverse;
+			hBlitDC->S0FetchDram    = TRUE;          // 1 Fetch, 0 do not Fetch Using Default Color in ARGB
+			                                     // if S0 Using Default Color then S0ColorType should be ARGB565 or A0
+			hBlitDC->S0ColorType  = SrcImg->ColorType;  //Must
+			//hBlitDC->S0DefaultColor.Alpha = SrcImg->DefaultColor.Alpha;     //ARGB8888 Format
+			hBlitDC->S0DefaultColor.Type = CSBLIT_COLOR_TYPE_ARGB8888;
+			hBlitDC->S0DefaultColor.Value.ARGB8888.Alpha = SrcPara->DefaultColor.Value.ARGB8888.Alpha;     //ARGB8888 Format
+			/*
+			hBlitDC->S0DefaultColor.Red   = SrcImg->DefaultColor->Red;       //ARGB8888 Format
+			hBlitDC->S0DefaultColor.Green = SrcImg->DefaultColor->Green;     //ARGB8888 Format
+			hBlitDC->S0DefaultColor.Blue  = SrcImg->DefaultColor->Blue;      //ARGB8888 Format
+			*/
+			CalcuDramPara
+			(
+			    SrcImg, 
+			    SrcRect,	
+			    hBlitDC->S0VReverseScan,
+				&hBlitDC->S0BaseAddr,              //Bytes Addr
+				&hBlitDC->S0LinePitch,             //Bytes Addr
+				&hBlitDC->S0SkipPixelLine         //Valid Only When Clut4
+			);
+			hBlitDC->S0PixelNumOneLine    = SrcRect->Width;
+			hBlitDC->S0TotalLineNum       = SrcRect->Height;
+
+			hBlitDC->S0NibbleLittleNotBigEndian = 0;	
+			hBlitDC->S0ByteLittleNotBigEndian = 1;
+			hBlitDC->S0TwoBytesLittleNotBigEndian = 1;
+			if(SrcImg->ColorType == CSBLIT_COLOR_TYPE_ARGB8888){
+				hBlitDC->S0TwoBytesLittleNotBigEndian = 0;
+			}
+			
+			hBlitDC->S0ClutEnable     = FALSE; //Do not support Clut Type In Scalor
+			hBlitDC->S0ColorKeyRGB.RGBEnable = FALSE; 
+			/*
+			hBlitDC->S0ColorKeyMin;
+			hBlitDC->S0ColorKeyMax;
+			*/
+		}
+		//S1 Control
+		{
+			hBlitDC->S1Enable       = FALSE;
+			hBlitDC->S1FetchDram    = FALSE;
+		}
+
+	    //ROP and Compositor
+		if(hBlitDC->BlitType == CSBLIT_DEVICE_TYPE_1_3)
+		{
+			hBlitDC->ROPAlphaCtrl       = FALSE;
+		}
+		else if(hBlitDC->BlitType == CSBLIT_DEVICE_TYPE_1_3_1)
+		{
+			hBlitDC->ROPAlphaCtrl       = TRUE;
+		}
+		hBlitDC->CompositorEnable   = FALSE;
+		hBlitDC->RopValue = AluMode;
+		//hBlitDC->S0OnTopS1;                        // 1 S0 On Top S1
+		//D Dram Para		
+		CalcuDramPara
+		(
+		    DesImg, 
+		    DesRect,	
+		    hBlitDC->DVReverseScan = DesPara->VReverse,
+			&hBlitDC->DBaseAddr,              //Bytes Addr
+			&hBlitDC->DLinePitch,             //Bytes Addr
+			&hBlitDC->DSkipPixelLine          //Valid Only When Clut4
+		);
+		hBlitDC->DPixelNumOneLine    = DesRect->Width;
+		hBlitDC->DTotalLineNum       = DesRect->Height;
+		
+		hBlitDC->DColorType        = DesImg->ColorType;
+
+		hBlitDC->DNibbleLittleNotBigEndian = 0;	
+		hBlitDC->DByteLittleNotBigEndian = 1;
+		hBlitDC->DTwoBytesLittleNotBigEndian = 1;
+		if(DesImg->ColorType == CSBLIT_COLOR_TYPE_ARGB8888){
+			hBlitDC->DTwoBytesLittleNotBigEndian = 0;
+		}
+
+		//Scalor Control
+		hBlitDC->S0ScalorEnable   = TRUE;
+		hBlitDC->HInitialPhase    = HInitialPhase;
+		hBlitDC->VInitialPhase    = VInitialPhase;
+		hBlitDC->UpdateHFIRCoeff  = FALSE;
+		hBlitDC->UpdateVFIRCoeff  = FALSE;
+
+		//Clut para
+		hBlitDC->UpdateClut4Table = FALSE;
+		hBlitDC->UpdateClut8Table = FALSE;
+		//RunTimeControl
+		hBlitDC->InterruptEnable  = BLIT_INTERRUPT_MODE;
+		
+		//active DC
+		/*--------------------------------------------------
+		* if (!ActiveDeviceContext(hBlitDC, BLIT_DC_ALL))
+		* {
+		* 	Err = -EINVAL;
+		* }
+		* else if (!WaitBlitToBeIdle(hBlitDC))
+		* {
+		* 	Err = -EINVAL;
+		* }
+		* else
+		* {
+		* 	Err = 0;
+		* }
+		*--------------------------------------------------*/
+
+		if (ActiveDeviceContext(hBlitDC, BLIT_DC_ALL))
+		{
+		    if (!WaitBlitScalorToBeIdle(hBlitDC))
+		    {
+			/* Blit maybe reset, so setup FIR Coeffient repeatedly */
+			SetDefaultScalorVFIRCoeff(hBlitDC);
+			SetDefaultScalorHFIRCoeff(hBlitDC);
+			Err = -EINVAL;
+		    }
+		    Err = 0;
+		}
+		else
+		{
+		    Err = -EINVAL;
+		}
+		DEBUG_PRINTF("ORION_BLIT : %s, %d\n",__FUNCTION__,__LINE__);
+		return Err;	
+	}	
+}
+
+int Composite
+(
+    CSBlit_HW_Device_t 		*hBlitDC, 
+    CSBLIT_Source_t 		*Src0Para,
+    CSBLIT_Source_t 		*Src1Para, 
+    CSBLIT_Destination_t 	*DesPara,
+    CSBLIT_AluMode_t 		AluMode,
+    boolean 			BlendEnable, 
+    boolean 			IsS0OnTopS1, 	
+    u32 			ROPAlphaCtrl
+)
+{
+	if (hBlitDC == NULL || Src0Para == NULL || Src1Para == NULL || DesPara == NULL)
+	{
+		DEBUG_PRINTF("ORION_BLIT : %s, %d\n",__FUNCTION__,__LINE__);
+		return -EINVAL;
+	}
+	else if (!IsColorTypeValid(Src0Para->Data.Bitmap.ColorType) || 
+	         !IsColorTypeValid(Src1Para->Data.Bitmap.ColorType) || 
+	         !IsColorTypeValid(DesPara->Bitmap.ColorType)  )
+	{
+		DEBUG_PRINTF("ORION_BLIT : %s, %d\n",__FUNCTION__,__LINE__);
+		return -EINVAL;
+	}
+	else if (!IsRectValid(&Src0Para->Data.Bitmap, &Src0Para->Rectangle) || 
+		     !IsRectValid(&Src1Para->Data.Bitmap, &Src1Para->Rectangle) )
+	{
+		DEBUG_PRINTF("ORION_BLIT : %s, %d\n",__FUNCTION__,__LINE__);
+		return -EINVAL;
+	}
+	else if (!IsRectValid(&DesPara->Bitmap, &DesPara->Rectangle) )
+	{
+		DEBUG_PRINTF("ORION_BLIT : %s, %d\n",__FUNCTION__,__LINE__);
+		return -EINVAL;
+	}
+	else if (!CmpRect(&Src0Para->Rectangle, &Src1Para->Rectangle) || 
+		     !CmpRect(&Src0Para->Rectangle, &DesPara->Rectangle)  )
+	{
+		DEBUG_PRINTF("ORION_BLIT : %s, %d\n",__FUNCTION__,__LINE__);
+		return -EINVAL;
+	}
+	else
+	{
+		int Err = -EINVAL;
+		CSBLIT_Bitmap_t *S0Img = NULL, *S1Img = NULL, *DImg = NULL;
+		S0Img = &Src0Para->Data.Bitmap;
+		S1Img = &Src1Para->Data.Bitmap;
+		DImg  = &DesPara->Bitmap;
+	//S0 Control
+		{
+			hBlitDC->S0Enable       = TRUE;
+			hBlitDC->S0VReverseScan = Src0Para->VReverse;
+			hBlitDC->S0FetchDram    = TRUE;          // 1 Fetch, 0 do not Fetch Using Default Color in ARGB
+			                                     // if S0 Using Default Color then S0ColorType should be ARGB565 or A0
+			hBlitDC->S0ColorType  = S0Img->ColorType;  //Must
+			hBlitDC->S0DefaultColor.Type = CSBLIT_COLOR_TYPE_ARGB8888;
+			hBlitDC->S0DefaultColor.Value.ARGB8888.Alpha = Src0Para->DefaultColor.Value.ARGB8888.Alpha;     //ARGB8888 Format
+			/*
+			hBlitDC->S0DefaultColor.Red   = SrcImg->DefaultColor->Red;       //ARGB8888 Format
+			hBlitDC->S0DefaultColor.Green = SrcImg->DefaultColor->Green;     //ARGB8888 Format
+			hBlitDC->S0DefaultColor.Blue  = SrcImg->DefaultColor->Blue;      //ARGB8888 Format
+			*/
+			CalcuDramPara
+			(
+			    S0Img, 
+			    &Src0Para->Rectangle,	
+			    hBlitDC->S0VReverseScan,
+				&hBlitDC->S0BaseAddr,              //Bytes Addr
+				&hBlitDC->S0LinePitch,             //Bytes Addr
+				&hBlitDC->S0SkipPixelLine         //Valid Only When Clut4
+			);
+			hBlitDC->S0PixelNumOneLine    = Src0Para->Rectangle.Width;
+			hBlitDC->S0TotalLineNum       = Src0Para->Rectangle.Height;
+
+			hBlitDC->S0NibbleLittleNotBigEndian = 0;	
+			hBlitDC->S0ByteLittleNotBigEndian = 1;
+			hBlitDC->S0TwoBytesLittleNotBigEndian = 1;
+			if(S0Img->ColorType == CSBLIT_COLOR_TYPE_ARGB8888){
+				hBlitDC->S0TwoBytesLittleNotBigEndian = 0;
+			}
+
+			hBlitDC->S0ClutEnable     = (S0Img->ColorType == CSBLIT_COLOR_TYPE_CLUT4 || 
+				                        S0Img->ColorType == CSBLIT_COLOR_TYPE_CLUT8 );
+			//hBlitDC->S0ColorKeyEnable = Src0Para->ColorKeyRGB.RGBEnable;
+			//memcpy(&hBlitDC->S0ColorKeyMin, &Src0Para->MinColor, sizeof(CSBLIT_Corlor_t));
+			//memcpy(&hBlitDC->S0ColorKeyMax, &Src0Para->MaxColor, sizeof(CSBLIT_Corlor_t));
+			memcpy(&hBlitDC->S0ColorKeyRGB, &Src0Para->ColorKeyRGB, sizeof(CSBLIT_ColorKeyRGB_t));
+		}
+	//S1 Control
+		{
+			hBlitDC->S1Enable       = TRUE;
+			hBlitDC->S1VReverseScan = Src1Para->VReverse;
+			hBlitDC->S1FetchDram    = TRUE;          // 1 Fetch, 0 do not Fetch Using Default Color in ARGB
+			                                     // if S1 Using Default Color then S1ColorType should be ARGB565 or A0
+
+			hBlitDC->S1ColorType  = S1Img->ColorType;  //Must
+			hBlitDC->S1DefaultColor.Type = CSBLIT_COLOR_TYPE_ARGB8888;
+			hBlitDC->S1DefaultColor.Value.ARGB8888.Alpha = Src1Para->DefaultColor.Value.ARGB8888.Alpha;     //ARGB8888 Format
+			/*
+			hBlitDC->S1DefaultColor.Red   = SrcImg->DefaultColor->Red;       //ARGB8888 Format
+			hBlitDC->S1DefaultColor.Green = SrcImg->DefaultColor->Green;     //ARGB8888 Format
+			hBlitDC->S1DefaultColor.Blue  = SrcImg->DefaultColor->Blue;      //ARGB8888 Format
+			*/
+			CalcuDramPara
+			(
+			    S1Img, 
+			    &Src1Para->Rectangle,	
+			    hBlitDC->S1VReverseScan,
+				&hBlitDC->S1BaseAddr,              //Bytes Addr
+				&hBlitDC->S1LinePitch,             //Bytes Addr
+				&hBlitDC->S1SkipPixelLine         //Valid Only When Clut4
+			);
+			hBlitDC->S1PixelNumOneLine    = Src1Para->Rectangle.Width;
+			hBlitDC->S1TotalLineNum       = Src1Para->Rectangle.Height;
+
+			hBlitDC->S1NibbleLittleNotBigEndian = 0;	
+			hBlitDC->S1ByteLittleNotBigEndian = 1;
+			hBlitDC->S1TwoBytesLittleNotBigEndian = 1;
+			if(S1Img->ColorType == CSBLIT_COLOR_TYPE_ARGB8888){
+				hBlitDC->S1TwoBytesLittleNotBigEndian = 0;
+			}
+
+			hBlitDC->S1ClutEnable     = (S1Img->ColorType == CSBLIT_COLOR_TYPE_CLUT4 || 
+				                        S1Img->ColorType == CSBLIT_COLOR_TYPE_CLUT8 );
+			//hBlitDC->S1ColorKeyEnable = Src1Para->ColorKeyEnable;
+			//memcpy(&hBlitDC->S1ColorKeyMin, &Src1Para->MinColor, sizeof(CSBLIT_Corlor_t));
+			//memcpy(&hBlitDC->S1ColorKeyMax, &Src1Para->MaxColor, sizeof(CSBLIT_Corlor_t));
+			memcpy(&hBlitDC->S1ColorKeyRGB, &Src1Para->ColorKeyRGB, sizeof(CSBLIT_ColorKeyRGB_t));
+		}
+	    //ROP and Compositor
+		hBlitDC->CompositorEnable   = BlendEnable;
+		hBlitDC->ROPAlphaCtrl       = ROPAlphaCtrl;
+		hBlitDC->RopValue           = AluMode;
+		hBlitDC->S0OnTopS1          = IsS0OnTopS1;                        // 1 S0 On Top S1
+		//D Dram Para		
+		CalcuDramPara
+		(
+		    DImg, 
+		    &DesPara->Rectangle,	
+		    hBlitDC->DVReverseScan = DesPara->VReverse,
+			&hBlitDC->DBaseAddr,              //Bytes Addr
+			&hBlitDC->DLinePitch,             //Bytes Addr
+			&hBlitDC->DSkipPixelLine          //Valid Only When Clut4
+		);
+		hBlitDC->DPixelNumOneLine    = DesPara->Rectangle.Width;
+		hBlitDC->DTotalLineNum       = DesPara->Rectangle.Height;
+		
+		hBlitDC->DColorType        = DImg->ColorType;
+		hBlitDC->DNibbleLittleNotBigEndian = 0;	
+		hBlitDC->DByteLittleNotBigEndian = 1;
+		hBlitDC->DTwoBytesLittleNotBigEndian = 1;
+		if(DImg->ColorType == CSBLIT_COLOR_TYPE_ARGB8888){
+			hBlitDC->DTwoBytesLittleNotBigEndian = 0;
+		}
+
+		//Scalor Control
+		hBlitDC->S0ScalorEnable   = FALSE;
+		//hBlitDC->HInitialPhase   = FALSE;
+		//hBlitDC->VInitialPhase   = FALSE;
+		hBlitDC->UpdateHFIRCoeff  = FALSE;
+		hBlitDC->UpdateVFIRCoeff  = FALSE;
+
+		//Clut para
+		hBlitDC->UpdateClut4Table = FALSE;
+		hBlitDC->UpdateClut8Table = FALSE;
+		//RunTimeControl
+		hBlitDC->InterruptEnable  = BLIT_INTERRUPT_MODE;
+		
+		//active DC
+		if (!ActiveDeviceContext(hBlitDC, BLIT_DC_ALL))
+		{
+			Err = -EINVAL;
+		}
+		else if (!WaitBlitToBeIdle(hBlitDC))
+		{
+			Err = -EINVAL;
+		}
+		else
+		{
+			Err = 0;
+		}
+		return Err;
+	}
+}
+
+int CompositeSrc0
+(
+    CSBlit_HW_Device_t 		*hBlitDC, 
+    CSBLIT_Source_t  		*Src0Para,
+    CSBLIT_Source_t     	*Src1Para,
+    CSBLIT_Destination_t  	*DesPara,
+    CSBLIT_AluMode_t 		AluMode,
+    boolean 			BlendEnable, 
+    boolean 			IsS0OnTopS1, 
+    u32 			ROPAlphaCtrl
+)
+{
+	if (hBlitDC  == NULL || Src0Para  == NULL || DesPara == NULL)
+	{
+		return -EINVAL;
+	}
+	else if (!IsColorTypeValid(Src0Para->Data.Bitmap.ColorType) || 
+		     !IsColorTypeValid(DesPara->Bitmap.ColorType)  )
+	{
+		return -EINVAL;
+	}
+	else if (!IsRectValid(&Src0Para->Data.Bitmap, &Src0Para->Rectangle))
+	{
+		return -EINVAL;
+	}
+	else if (!IsRectValid(&DesPara->Bitmap,  &DesPara->Rectangle) )
+	{
+		return -EINVAL;
+	}
+	else if (!CmpRect(&Src0Para->Rectangle, &DesPara->Rectangle)  )
+	{
+		return -EINVAL;
+	}
+	else
+	{
+		int Err = -EINVAL;
+		CSBLIT_Bitmap_t *S0Img = NULL, *DImg = NULL;
+		S0Img = &Src0Para->Data.Bitmap;
+		DImg  = &DesPara->Bitmap;
+	//S0 Control
+		{
+			hBlitDC->S0Enable       = TRUE;
+			hBlitDC->S0VReverseScan = Src0Para->VReverse;
+			hBlitDC->S0FetchDram    = TRUE;          // 1 Fetch, 0 do not Fetch Using Default Color in ARGB
+			                                     // if S0 Using Default Color then S0ColorType should be ARGB565 or A0
+			hBlitDC->S0ColorType  = S0Img->ColorType;  //Must
+			//hBlitDC->S0DefaultColor.Alpha = S0Img->DefaultColor.Alpha;     //ARGB8888 Format
+			hBlitDC->S0DefaultColor.Type = CSBLIT_COLOR_TYPE_ARGB8888;
+			hBlitDC->S0DefaultColor.Value.ARGB8888.Alpha = Src0Para->DefaultColor.Value.ARGB8888.Alpha;     //ARGB8888 Format
+			/*
+			hBlitDC->S0DefaultColor.Red   = SrcImg->DefaultColor->Red;       //ARGB8888 Format
+			hBlitDC->S0DefaultColor.Green = SrcImg->DefaultColor->Green;     //ARGB8888 Format
+			hBlitDC->S0DefaultColor.Blue  = SrcImg->DefaultColor->Blue;      //ARGB8888 Format
+			*/
+			CalcuDramPara
+			(
+			    S0Img, 
+			    &Src0Para->Rectangle,	
+			    hBlitDC->S0VReverseScan,
+				&hBlitDC->S0BaseAddr,              //Bytes Addr
+				&hBlitDC->S0LinePitch,             //Bytes Addr
+				&hBlitDC->S0SkipPixelLine         //Valid Only When Clut4
+			);
+			hBlitDC->S0PixelNumOneLine    = Src0Para->Rectangle.Width;
+			hBlitDC->S0TotalLineNum       = Src0Para->Rectangle.Height;
+			hBlitDC->S0NibbleLittleNotBigEndian = 0;	
+			hBlitDC->S0ByteLittleNotBigEndian = 1;
+			hBlitDC->S0TwoBytesLittleNotBigEndian = 1;
+			if(S0Img->ColorType == CSBLIT_COLOR_TYPE_ARGB8888){
+				hBlitDC->S0TwoBytesLittleNotBigEndian = 0;
+			}
+
+			hBlitDC->S0ClutEnable     = (S0Img->ColorType == CSBLIT_COLOR_TYPE_CLUT4 || 
+				                        S0Img->ColorType == CSBLIT_COLOR_TYPE_CLUT8 );
+			memcpy(&hBlitDC->S0ColorKeyRGB, &Src0Para->ColorKeyRGB, sizeof(CSBLIT_ColorKeyRGB_t));
+		}
+	//S1 Control
+		{
+			hBlitDC->S1Enable       =  BlendEnable;	/*if want to blend, then must enable S1*/
+			hBlitDC->S1FetchDram    = FALSE;          // 1 Fetch, 0 do not Fetch Using Default Color in ARGB
+			hBlitDC->S1ColorType  = CSBLIT_COLOR_TYPE_A0;                                     // if S1 Using Default Color then S1ColorType should be ARGB565 or A0
+			memcpy(&hBlitDC->S0DefaultColor, &Src1Para->Data.Color, sizeof(CSBLIT_Color_t));
+			hBlitDC->S1ClutEnable     = FALSE;
+			hBlitDC->S1ColorKeyRGB.RGBEnable = FALSE;
+		}
+	    //ROP and Compositor
+		hBlitDC->CompositorEnable   = BlendEnable;
+		hBlitDC->ROPAlphaCtrl       = ROPAlphaCtrl;
+		hBlitDC->RopValue           = AluMode;		
+		hBlitDC->S0OnTopS1          = IsS0OnTopS1;                        // 1 S0 On Top S1
+		//D Dram Para		
+		CalcuDramPara
+		(
+		    DImg, 
+		    &DesPara->Rectangle,	
+		    hBlitDC->DVReverseScan = DesPara->VReverse,
+			&hBlitDC->DBaseAddr,              //Bytes Addr
+			&hBlitDC->DLinePitch,             //Bytes Addr
+			&hBlitDC->DSkipPixelLine         //Valid Only When Clut4
+		);
+		hBlitDC->DPixelNumOneLine    = DesPara->Rectangle.Width;
+		hBlitDC->DTotalLineNum       = DesPara->Rectangle.Height;
+		
+		hBlitDC->DColorType        = DImg->ColorType;
+		hBlitDC->DNibbleLittleNotBigEndian = 0;	
+		hBlitDC->DByteLittleNotBigEndian = 1;
+		hBlitDC->DTwoBytesLittleNotBigEndian = 1;
+		if(DImg->ColorType == CSBLIT_COLOR_TYPE_ARGB8888){
+			hBlitDC->DTwoBytesLittleNotBigEndian = 0;
+		}
+
+		//Scalor Control
+		hBlitDC->S0ScalorEnable   = FALSE;
+		//hBlitDC->HInitialPhase   = FALSE;
+		//hBlitDC->VInitialPhase   = FALSE;
+		hBlitDC->UpdateHFIRCoeff  = FALSE;
+		hBlitDC->UpdateVFIRCoeff  = FALSE;
+
+		//Clut para
+		hBlitDC->UpdateClut4Table = FALSE;
+		hBlitDC->UpdateClut8Table = FALSE;
+		//RunTimeControl
+		hBlitDC->InterruptEnable  = BLIT_INTERRUPT_MODE;
+		
+		//active DC
+		if (!ActiveDeviceContext(hBlitDC, BLIT_DC_ALL))
+		{
+			Err = -EINVAL;
+		}
+		else if (!WaitBlitToBeIdle(hBlitDC))
+		{
+			Err = -EINVAL;
+		}
+		else
+		{
+			Err = 0;
+		}
+		return Err;
+	}
+}
+
+int CompositeSrc1
+(
+    CSBlit_HW_Device_t 		*hBlitDC, 
+    CSBLIT_Source_t     	*Src0Para, 
+    CSBLIT_Source_t     	*Src1Para,
+    CSBLIT_Destination_t  	*DesPara,
+    CSBLIT_AluMode_t 		AluMode,
+    boolean 			BlendEnable, 
+    boolean 			IsS0OnTopS1, 
+    u32 			ROPAlphaCtrl
+)
+{
+	if (hBlitDC  == NULL || Src1Para  == NULL || DesPara == NULL)
+	{
+		return -EINVAL;
+	}
+	else if (!IsColorTypeValid(Src1Para->Data.Bitmap.ColorType) || 
+		     !IsColorTypeValid(DesPara->Bitmap.ColorType)  )
+	{
+		return -EINVAL;
+	}
+	else if (!IsRectValid(&Src1Para->Data.Bitmap, &Src1Para->Rectangle))
+	{
+		return -EINVAL;
+	}
+	else if (!IsRectValid(&DesPara->Bitmap,  &DesPara->Rectangle) )
+	{
+		return -EINVAL;
+	}
+	else if (!CmpRect(&Src1Para->Rectangle, &DesPara->Rectangle)  )
+	{
+		return -EINVAL;
+	}
+	else
+	{
+		int Err = -EINVAL;
+		CSBLIT_Bitmap_t *S1Img = NULL, *DImg = NULL;
+		S1Img = &Src1Para->Data.Bitmap;
+		DImg  = &DesPara->Bitmap;
+		//S0 Control
+		{
+			hBlitDC->S0Enable       = BlendEnable;	/*if Want to blend,then must enable s0*/
+			hBlitDC->S0FetchDram    = FALSE;        // TRUE Fetch, FALSE do not Fetch Using Default Color in ARGB
+			// if S0 Using Default Color then S0ColorType should be ARGB565 or A0
+			hBlitDC->S0ColorType  = CSBLIT_COLOR_TYPE_A0;
+			memcpy(&hBlitDC->S0DefaultColor, &Src0Para->Data.Color, sizeof(CSBLIT_Color_t));
+			hBlitDC->S0ClutEnable     = FALSE;
+			hBlitDC->S0ColorKeyRGB.RGBEnable = FALSE;
+		}
+
+		//S1 Control
+		{
+			hBlitDC->S1Enable       = TRUE;
+			hBlitDC->S1VReverseScan = Src1Para->VReverse;
+			hBlitDC->S1FetchDram    = TRUE;          // 1 Fetch, 0 do not Fetch Using Default Color in ARGB
+			// if S1 Using Default Color then S1ColorType should be ARGB565 or A0
+			hBlitDC->S1ColorType  = S1Img->ColorType;  //Must
+			//hBlitDC->S1DefaultColor.Alpha = S1Img->DefaultColor.Alpha;     //ARGB8888 Format
+			hBlitDC->S1DefaultColor.Type = CSBLIT_COLOR_TYPE_ARGB8888;
+			hBlitDC->S1DefaultColor.Value.ARGB8888.Alpha = Src1Para->DefaultColor.Value.ARGB8888.Alpha;     //ARGB8888 Format
+			/*
+			   hBlitDC->S1DefaultColor.Red   = SrcImg->DefaultColor->Red;      //ARGB8888 Format
+			   hBlitDC->S1DefaultColor.Green = SrcImg->DefaultColor->Green;    //ARGB8888 Format
+			   hBlitDC->S1DefaultColor.Blue  = SrcImg->DefaultColor->Blue;     //ARGB8888 Format
+			   */
+			CalcuDramPara
+				(
+				 S1Img, 
+				 &Src1Para->Rectangle,	
+				 hBlitDC->S1VReverseScan,
+				 &hBlitDC->S1BaseAddr,              //Bytes Addr
+				 &hBlitDC->S1LinePitch,             //Bytes Addr
+				 &hBlitDC->S1SkipPixelLine         //Valid Only When Clut4
+				);
+			hBlitDC->S1PixelNumOneLine    = Src1Para->Rectangle.Width;
+			hBlitDC->S1TotalLineNum       = Src1Para->Rectangle.Height;
+
+			hBlitDC->S1NibbleLittleNotBigEndian = 0;	
+			hBlitDC->S1ByteLittleNotBigEndian = 1;
+			hBlitDC->S1TwoBytesLittleNotBigEndian = 1;
+			if(S1Img->ColorType == CSBLIT_COLOR_TYPE_ARGB8888){
+				hBlitDC->S1TwoBytesLittleNotBigEndian = 0;
+			}
+
+			hBlitDC->S1ClutEnable     = (S1Img->ColorType == CSBLIT_COLOR_TYPE_CLUT4 || 
+					S1Img->ColorType == CSBLIT_COLOR_TYPE_CLUT8 );
+			//hBlitDC->S1ColorKeyEnable = Src1Para->ColorKeyEnable;
+			//memcpy(&hBlitDC->S1ColorKeyMin, &Src1Para->MinColor, sizeof(CSBLIT_Corlor_t));
+			//memcpy(&hBlitDC->S1ColorKeyMax, &Src1Para->MaxColor, sizeof(CSBLIT_Corlor_t));
+			memcpy(&hBlitDC->S1ColorKeyRGB, &Src1Para->ColorKeyRGB, sizeof(CSBLIT_ColorKeyRGB_t));
+		}
+	    //ROP and Compositor
+		hBlitDC->CompositorEnable   = BlendEnable;
+		hBlitDC->ROPAlphaCtrl       = ROPAlphaCtrl;
+		hBlitDC->RopValue           = AluMode;		
+		hBlitDC->S0OnTopS1          = IsS0OnTopS1;                        // 1 S0 On Top S1
+		//D Dram Para		
+		CalcuDramPara
+		(
+		    DImg, 
+		    &DesPara->Rectangle,	
+		    hBlitDC->DVReverseScan = DesPara->VReverse,
+			&hBlitDC->DBaseAddr,              //Bytes Addr
+			&hBlitDC->DLinePitch,             //Bytes Addr
+			&hBlitDC->DSkipPixelLine         //Valid Only When Clut4
+		);
+		hBlitDC->DPixelNumOneLine    = DesPara->Rectangle.Width;
+		hBlitDC->DTotalLineNum       = DesPara->Rectangle.Height;
+		
+		hBlitDC->DColorType        = DImg->ColorType;
+		hBlitDC->DNibbleLittleNotBigEndian = 0;	
+		hBlitDC->DByteLittleNotBigEndian = 1;
+		hBlitDC->DTwoBytesLittleNotBigEndian = 1;
+		if(DImg->ColorType == CSBLIT_COLOR_TYPE_ARGB8888){
+			hBlitDC->DTwoBytesLittleNotBigEndian = 0;
+		}
+
+		//Scalor Control
+		hBlitDC->S0ScalorEnable   = FALSE;
+		//hBlitDC->HInitialPhase   = FALSE;
+		//hBlitDC->VInitialPhase   = FALSE;
+		hBlitDC->UpdateHFIRCoeff  = FALSE;
+		hBlitDC->UpdateVFIRCoeff  = FALSE;
+
+		//Clut para
+		hBlitDC->UpdateClut4Table = FALSE;
+		hBlitDC->UpdateClut8Table = FALSE;
+		//RunTimeControl
+		hBlitDC->InterruptEnable  = BLIT_INTERRUPT_MODE;
+		
+		//active DC
+		if (!ActiveDeviceContext(hBlitDC, BLIT_DC_ALL))
+		{
+			Err = -EINVAL;
+		}
+		else if (!WaitBlitToBeIdle(hBlitDC))
+		{
+			Err = -EINVAL;
+		}
+		else
+		{
+			Err = 0;
+		}
+		return Err;
+	}
+}
+
+/*end of blit_ioctl.c*/
+
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/celestial/graphics/blit_ioctl.h linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/graphics/blit_ioctl.h
--- linux-linaro-3.4-2012.05-1_original/drivers/celestial/graphics/blit_ioctl.h	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/graphics/blit_ioctl.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,166 @@
+/*******************************************************************************
+
+File name   : blit_ioctl.h
+
+Description : orion blitter driver source file
+
+COPYRIGHT (C) Celestial Semiconductor 2007.
+
+Date               Modification                                     Name
+----               ------------                                     ----
+14 Nov 2007        Created                                           XM.Chen
+*******************************************************************************/
+
+
+#ifndef	_BLIT_IOCTL_H_
+#define _BLIT_IOCTL_H_
+
+#include "blit_hw.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum BLIT_SourceType_e
+{
+    CSBLIT_SOURCE_TYPE_COLOR,
+    CSBLIT_SOURCE_TYPE_BITMAP
+} CSBLIT_SourceType_t;
+
+typedef struct CSBLIT_Source_s
+{
+    CSBLIT_SourceType_t     	Type;
+    union {
+	    CSBLIT_Color_t   	Color;
+            CSBLIT_Bitmap_t  	Bitmap;
+    } Data;
+    CSBLIT_Rectangle_t    	Rectangle;
+    CSBLIT_ColorKeyRGB_t  	ColorKeyRGB;	/* ColorKey default is not used */
+    CSBLIT_Color_t	    	DefaultColor; 	/* not valid if source type is CSBLIT_SOURCE_TYPE_COLOR */
+    boolean		    	VReverse;
+} CSBLIT_Source_t;
+
+typedef struct CSBLIT_Destination_s
+{
+    CSBLIT_Bitmap_t	      	Bitmap;
+    CSBLIT_Rectangle_t	Rectangle;
+    boolean		    	VReverse;
+} CSBLIT_Destination_t;
+
+typedef struct CSBLIT_FillRectParams_s
+{
+    CSBLIT_Bitmap_t        	Bitmap;
+    CSBLIT_Rectangle_t     	Rectangle;
+    CSBLIT_Color_t         	Color;
+    CSBLIT_AluMode_t 		AluMode;
+} CSBLIT_FillRectParams_t;
+
+typedef struct CSBLIT_CopyRectParams_s
+{
+    CSBLIT_Bitmap_t        	SrcBitmap;
+    CSBLIT_Rectangle_t     	SrcRectangle;
+    CSBLIT_Bitmap_t        	DstBitmap;
+    s32                   	DstPositionX;
+    s32                   	DstPositionY;
+    CSBLIT_AluMode_t 		AluMode;
+} CSBLIT_CopyRectParams_t;
+
+typedef struct CSBLIT_ScalorParams_s
+{
+    CSBLIT_Source_t		Src;
+    CSBLIT_Destination_t   	Dst;
+    u32				VInitialPhase;	/*default is 4*/
+    u32				HInitialPhase;	/*default is 0*/
+    CSBLIT_AluMode_t 		AluMode;
+} CSBLIT_ScalorParams_t;
+
+typedef struct CSBLIT_CompParams_s
+{
+    boolean			BlendEnable;
+    boolean			IsS0OnTopS1;
+    u32				ROPAlphaCtrl;
+    CSBLIT_Source_t		Src0;
+    CSBLIT_Source_t		Src1;
+    CSBLIT_Destination_t   	Dst;
+    CSBLIT_AluMode_t 		AluMode;
+} CSBLIT_CompParams_t;
+
+
+/* exported functions */
+int blit_initialize(CSBlit_HW_Device_t *hBlitDC);
+
+int Fill
+( 
+    CSBlit_HW_Device_t 		*hBlitDC, 
+    s32                 	BlitSrcId,
+    CSBLIT_Bitmap_t       	*DesImg, 
+    CSBLIT_Rectangle_t    	*DesRect, 
+    CSBLIT_Color_t 		*FillColor,
+    CSBLIT_AluMode_t 		AluMode
+);
+
+int Copy
+( 
+    CSBlit_HW_Device_t  	*hBlitDC, 
+    s32                  	BlitSrcId,
+    CSBLIT_Bitmap_t    	*SrcImg, 
+    CSBLIT_Rectangle_t 	*SrcRect, 
+    s32                  	SrcVReverse,
+    CSBLIT_Bitmap_t    	*DesImg, 
+    CSBLIT_Rectangle_t 	*DesRect, 
+    CSBLIT_AluMode_t 		AluMode,
+    s32                  	DesVReverse
+);
+
+int Scalor
+( 
+    CSBlit_HW_Device_t  	*hBlitDC, 
+    CSBLIT_Source_t		*SrcPara,    
+    CSBLIT_Destination_t 	*DesPara,
+    u32                  	VInitialPhase, 
+    u32                  	HInitialPhase,
+    CSBLIT_AluMode_t 		AluMode
+);
+
+int Composite
+(
+    CSBlit_HW_Device_t 		*hBlitDC, 
+    CSBLIT_Source_t 		*Src0Para,
+    CSBLIT_Source_t 		*Src1Para, 
+    CSBLIT_Destination_t 	*DesPara,
+    CSBLIT_AluMode_t 		AluMode,
+    boolean 			BlendEnable, 
+    boolean 			IsS0OnTopS1, 	
+    u32 			ROPAlphaCtrl
+);
+
+int CompositeSrc0
+(
+    CSBlit_HW_Device_t 		*hBlitDC, 
+    CSBLIT_Source_t  		*Src0Para,
+    CSBLIT_Source_t     	*Src1Para,
+    CSBLIT_Destination_t  	*DesPara,
+    CSBLIT_AluMode_t 		AluMode,
+    boolean 			BlendEnable, 
+    boolean 			IsS0OnTopS1, 
+    u32 			ROPAlphaCtrl
+);
+
+int CompositeSrc1
+(
+    CSBlit_HW_Device_t 		*hBlitDC, 
+    CSBLIT_Source_t     	*Src0Para, 
+    CSBLIT_Source_t     	*Src1Para,
+    CSBLIT_Destination_t  	*DesPara,
+    CSBLIT_AluMode_t 		AluMode,
+    boolean 			BlendEnable, 
+    boolean 			IsS0OnTopS1, 
+    u32 			ROPAlphaCtrl
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //_BLIT_IOCTL_H_
+
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/celestial/graphics/cnc18xx_blit.c linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/graphics/cnc18xx_blit.c
--- linux-linaro-3.4-2012.05-1_original/drivers/celestial/graphics/cnc18xx_blit.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/graphics/cnc18xx_blit.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,620 @@
+#include <linux/version.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/miscdevice.h>
+#include <linux/ioport.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/miscdevice.h>
+#include <linux/errno.h>
+#include <linux/spinlock.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <linux/mm.h> 
+#include <asm/page.h> 
+#include <mach/mem_define.h>
+#include <linux/proc_fs.h>
+#include <linux/list.h>
+#include <mach/hardware.h>
+#include "blit_ioctl.h"
+
+// extern unsigned int ioread32(void __iomem *);
+// extern void iowrite32(u32, void __iomem *);
+
+#define BLIT_MAGIC          'B'
+#define BLIT_FILL 	         _IOW(BLIT_MAGIC, 1,  int)
+#define BLIT_COPY 	         _IOW(BLIT_MAGIC, 2,  int)
+#define BLIT_SCALOR 	     _IOW(BLIT_MAGIC, 3,  int)
+#define BLIT_COMP 	         _IOW(BLIT_MAGIC, 4,  int)
+#define BLIT_GET_FB0_ADDR 	 _IOW(BLIT_MAGIC, 5,  int)
+#define BLIT_GET_FB1_ADDR 	 _IOW(BLIT_MAGIC, 6,  int)
+#define BLIT_MALLOC_DMA 	 _IOW(BLIT_MAGIC, 7,  int)
+#define BLIT_FREE_DMA 	     _IOW(BLIT_MAGIC, 8,  int)
+#define BLIT_GET_FB0_SIZE 	 _IOW(BLIT_MAGIC, 9,  int)
+#define BLIT_GET_FB1_SIZE 	 _IOW(BLIT_MAGIC, 10, int)
+#define CSBLIT_GET_FB2_ADDR  _IOW(BLIT_MAGIC, 11, int)
+#define CSBLIT_GET_FB2_SIZE  _IOW(BLIT_MAGIC, 12, int)
+#define CSBLIT_GET_FB3_ADDR  _IOW(BLIT_MAGIC, 13, int)
+#define CSBLIT_GET_FB3_SIZE  _IOW(BLIT_MAGIC, 14, int)
+#define BLIT_MAXNR 15
+
+typedef struct BLIT_DMA_BUFFER_STUFF_s
+{
+	void *phy_addr;/*physics memory address*/
+	void *kernel_virt_addr;/*virtual memory address in kernel level*/
+	unsigned int kernel_needed_size;
+	void *user_virt_addr;/*user can use mapped memory start address in user level*/
+	unsigned int user_needed_size;/*how many buffer do user want to malloc*/
+}BLIT_DMA_BUFFER_STUFF_t;
+
+typedef struct CSBlit_Device 
+{
+	CSBlit_HW_Device_t	hwdev;
+	struct list_head		buffer_head;
+} blit_dev;
+
+typedef struct BLIT_DMA_BUFFER_LIST_s
+{
+	struct list_head buffer_list;
+	BLIT_DMA_BUFFER_STUFF_t pointer;
+}blit_buffer_list;
+
+blit_dev*  pblit_dev = NULL;	/* allocated in blit_init_module */
+volatile unsigned int *cs_blit_base = NULL;
+static spinlock_t 	blit_lock;
+static struct proc_dir_entry *blit_proc_entry = NULL;
+/* function declaration ------------------------------------- */
+static int __init 	blit_init(void);
+static void __exit 	blit_exit(void);
+static int csblit_open(struct inode *inode, struct file *file);
+static int csblit_release(struct inode *inode, struct file *file);
+static long blit_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
+//static int cs_blit_mmap(struct file *file, struct vm_area_struct *vma);
+/* ----------------------------------------------------------- */
+/* Allocate physic continue memory for buffers */
+void *testpage = NULL;
+static void *malloc_config(unsigned int buf_size)
+{
+	void *mem = 0;
+	unsigned int size = PAGE_SIZE << (get_order(buf_size));
+#if 1
+	struct page * page;
+
+	page = alloc_pages(GFP_KERNEL, get_order(size));
+	if (!page){
+		printk( "dma memory can't be alloced error 1!!\n");
+		return 0;
+	}
+	else{
+		mem = page_address(page);
+		if (mem) {
+			unsigned long adr = (unsigned long)mem;
+			while (size > 0) {
+                SetPageReserved(page);
+
+                //ClearPagePrivate(virt_to_page(adr));
+                //ClearPageDirty(virt_to_page(adr));
+			
+                adr += PAGE_SIZE;
+                size -= PAGE_SIZE;
+			}
+		} 
+		else{
+			__free_pages(page, get_order(size));
+			printk( "dma memory can't be alloced error 2!!\n");
+			return 0;
+		}
+		//phy_addr = page_to_phys(page);
+		printk("mem->flag = 0x%x\n",(unsigned int)page->flags);
+	}
+#else
+    mem = (void *)__get_dma_pages(GFP_KERNEL, get_order(buf_size));
+    if (mem) {
+        unsigned long adr = (unsigned long)mem;
+        while (size > 0) {
+            SetPageReserved(virt_to_page(adr));
+            adr += PAGE_SIZE;
+            size -= PAGE_SIZE;
+        }
+    } else
+        printk( "dma memory can't be alloced!!\n");
+#endif
+    return mem;
+}
+
+/* Free continue memory for buffers */
+static void free_contig(void *addr, unsigned int buf_size)
+{
+	unsigned int size, adr;
+
+	if (!addr)
+		return;
+	adr = (unsigned int)addr;
+	size = PAGE_SIZE << (get_order(buf_size));
+	while (size > 0) {
+		ClearPageReserved(virt_to_page(adr));
+		adr += PAGE_SIZE;
+		size -= PAGE_SIZE;
+	}
+	free_pages((unsigned int)addr, get_order(buf_size));
+}
+
+/* blit device struct */
+struct file_operations cs_blit_fops = 
+    {
+        .owner 	=  THIS_MODULE,
+        .open = csblit_open,
+        .release = csblit_release,
+        .unlocked_ioctl  =  blit_ioctl,
+        //        .mmap = cs_blit_mmap
+    };
+
+static struct miscdevice cs_blit_miscdev = {
+	MISC_DYNAMIC_MINOR,
+	"cs_blit",
+	&cs_blit_fops
+};
+
+/*
+ * Architectures vary in how they handle caching for addresses
+ * outside of main memory.
+ *
+ */
+static inline int uncached_access(struct file *file, unsigned long addr)
+{
+
+	/*
+	 * Accessing memory above the top the kernel knows about or through a file pointer
+	 * that was marked O_SYNC will be done non-cached.
+	 */
+	if (file->f_flags & O_SYNC)
+		return 1;
+	return addr >= __pa(high_memory);
+
+}
+#if 0
+struct page *cs_vma_nopage(struct vm_area_struct *vma,unsigned long address, int *type)
+{
+	struct page *pageptr;
+	unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
+	unsigned long phyaddr = address -vma->vm_start + offset;
+	unsigned long pageframe = phyaddr >> PAGE_SHIFT;
+
+	DEBUG_PRINTF("address = 0x%lx,phyaddr = 0x%lx, offset = 0x%lx,pageframe = 0x%lx\n",
+                 address,phyaddr,offset,pageframe);
+	DEBUG_PRINTF("call cs_vma_nopage\n");
+	if(!pfn_valid(pageframe)){
+		printk("pfn invalid!!!\n");
+		return NOPAGE_SIGBUS;
+	}
+	//pageptr = virt_to_page(testpage+(pagecount<<PAGE_SHIFT));
+	pageptr = pfn_to_page(pageframe);
+
+	get_page(pageptr);
+	SetPageReserved(pageptr);
+	ClearPagePrivate(pageptr);
+	ClearPageDirty(pageptr);
+
+	if(type){
+		*type = VM_FAULT_MINOR;
+	}
+	return pageptr;
+}
+#endif
+// static struct vm_operations_struct cs_vm_ops =
+//     {
+//         .nopage = cs_vma_nopage,
+//     };
+
+
+// #ifndef __HAVE_PHYS_MEM_ACCESS_PROT
+// static pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
+// 				     unsigned long size, pgprot_t vma_prot)
+// {
+// #ifdef pgprot_noncached
+// 	unsigned long offset = pfn << PAGE_SHIFT;
+
+// 	if (uncached_access(file, offset))
+// 		return pgprot_noncached(vma_prot);
+// #endif
+// 	return vma_prot;
+// }
+// #endif
+
+// static int cs_blit_mmap(struct file *file, struct vm_area_struct *vma)
+// {
+// 	unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
+// 	size_t size = vma->vm_end - vma->vm_start;
+    
+// 	if((FB0_REGION == offset)||(FB1_REGION == offset)||(offset == offset)){
+//         if (!valid_mmap_phys_addr_range(vma->vm_pgoff, size))
+//             return -EINVAL;
+        
+//         if (!(vma->vm_flags & VM_MAYSHARE))
+//             return -ENOSYS;
+        
+//         vma->vm_page_prot = phys_mem_access_prot(file, vma->vm_pgoff,
+//                                                  size,
+//                                                  vma->vm_page_prot);
+    
+// 		/* Remap-pfn-range will mark the range VM_IO and VM_RESERVED */
+// 		if (remap_pfn_range(vma, 
+//                             vma->vm_start, 
+//                             vma->vm_pgoff, 
+//                             vma->vm_end - vma->vm_start, 
+//                             vma->vm_page_prot))
+// 			return -EAGAIN;
+// 	}
+// 	// else{
+// 	// 	if((offset >= __pa(high_memory))||(file->f_flags & O_SYNC)){
+// 	// 		vma->vm_flags |= VM_IO;
+// 	// 	}
+// 	// 	vma->vm_flags |= VM_RESERVED;
+// 	// 	vma->vm_ops = &cs_vm_ops;
+// 	// }
+// 	return 0;
+// }
+
+static int csblit_open(struct inode *inode, struct file *file)
+{
+	DEBUG_PRINTF("%s\n",__FUNCTION__);
+	
+	return 0;
+}
+
+static int csblit_release(struct inode *inode, struct file *file)
+{
+	blit_buffer_list * dma_buffer_list;
+	struct list_head *pos, *temp;
+    
+	DEBUG_PRINTF("%s\n",__FUNCTION__);
+    
+	list_for_each_safe(pos, temp, &pblit_dev->buffer_head){
+		dma_buffer_list = list_entry(pos, blit_buffer_list, buffer_list);
+        DEBUG_PRINTF("pointer = 0x%x\n",(unsigned int)dma_buffer_list->pointer.phy_addr);
+        if(dma_buffer_list->pointer.phy_addr !=0){
+            free_contig(dma_buffer_list->pointer.kernel_virt_addr, dma_buffer_list->pointer.kernel_needed_size);
+        }
+        list_del(pos);
+        kfree(dma_buffer_list);
+	}
+    
+	return 0;
+}
+
+static long blit_ioctl (struct file *file, unsigned int cmd, unsigned long arg)
+{
+    int err = -1;
+    union _cmd_param_
+    {
+        CSBLIT_FillRectParams_t fillparam;
+        CSBLIT_CopyRectParams_t copyparam;
+        CSBLIT_ScalorParams_t 	scalorparam;
+        CSBLIT_CompParams_t 	compparam;
+    } cmd_param;
+    
+    CSBLIT_Rectangle_t tmprect;		/* only for dest rectangle copy */
+    
+    spin_lock(&blit_lock);
+    
+    switch(cmd) 
+        {
+        case BLIT_FILL:
+            DEBUG_PRINTF("CS_BLIT_IOCTL_CMD_FILL\n");
+            if(copy_from_user(&cmd_param.fillparam, (void *)arg, sizeof(CSBLIT_FillRectParams_t)))
+                goto ERR_INVAL;
+            err = Fill(&pblit_dev->hwdev, 1,        \
+                       &cmd_param.fillparam.Bitmap,     \
+                       &cmd_param.fillparam.Rectangle,	\
+                       &cmd_param.fillparam.Color,      \
+                       cmd_param.fillparam.AluMode);
+            DEBUG_PRINTF("CS_BLIT : %s, %d\n",__FUNCTION__,__LINE__);
+            break;
+            
+        case BLIT_COPY:
+            DEBUG_PRINTF("CS_BLIT_IOCTL_CMD_COPY\n");
+            if(copy_from_user(&cmd_param.copyparam, (void *)arg, sizeof(CSBLIT_CopyRectParams_t)))
+                goto ERR_INVAL;
+            
+            tmprect.PositionX = cmd_param.copyparam.DstPositionX;
+            tmprect.PositionY = cmd_param.copyparam.DstPositionY;
+            tmprect.Width = cmd_param.copyparam.SrcRectangle.Width;
+            tmprect.Height = cmd_param.copyparam.SrcRectangle.Height;
+            err = Copy(&pblit_dev->hwdev, 1,        \
+                       &cmd_param.copyparam.SrcBitmap,	\
+                       &cmd_param.copyparam.SrcRectangle,	\
+                       0,                                   \
+                       &cmd_param.copyparam.DstBitmap,      \
+                       &tmprect,                            \
+                       cmd_param.copyparam.AluMode,  0);
+            break;
+            
+        case BLIT_SCALOR:
+            DEBUG_PRINTF("CS_BLIT_IOCTL_CMD_SCALOR\n");
+            if(copy_from_user(&cmd_param.scalorparam, (void *)arg, sizeof(CSBLIT_ScalorParams_t)))
+                goto ERR_INVAL;
+        
+            if(cmd_param.scalorparam.VInitialPhase > 7)
+                cmd_param.scalorparam.VInitialPhase = 4;
+            if(cmd_param.scalorparam.HInitialPhase > 7)
+                cmd_param.scalorparam.HInitialPhase = 0;
+        
+            err = Scalor(&pblit_dev->hwdev,     \
+                         &cmd_param.scalorparam.Src,    \
+                         &cmd_param.scalorparam.Dst,    \
+                         cmd_param.scalorparam.VInitialPhase,   \
+                         cmd_param.scalorparam.HInitialPhase,   \
+                         cmd_param.scalorparam.AluMode);
+            break;
+
+        case BLIT_COMP:
+            DEBUG_PRINTF("CS_BLIT_IOCTL_CMD_COMP\n");
+            if(copy_from_user(&cmd_param.compparam, (void *)arg, sizeof(CSBLIT_CompParams_t)))
+                goto ERR_INVAL;
+            
+            if(cmd_param.compparam.Src0.Type == CSBLIT_SOURCE_TYPE_BITMAP && 
+               cmd_param.compparam.Src1.Type == CSBLIT_SOURCE_TYPE_BITMAP)
+                {
+                    err = Composite(&pblit_dev->hwdev,              \
+                                    &cmd_param.compparam.Src0, 		\
+                                    &cmd_param.compparam.Src1, 		\
+                                    &cmd_param.compparam.Dst,           \
+                                    cmd_param.compparam.AluMode, 		\
+                                    cmd_param.compparam.BlendEnable, 	\
+                                    cmd_param.compparam.IsS0OnTopS1, 	\
+                                    cmd_param.compparam.ROPAlphaCtrl);
+                }
+            else if(cmd_param.compparam.Src0.Type == CSBLIT_SOURCE_TYPE_COLOR &&
+                    cmd_param.compparam.Src1.Type == CSBLIT_SOURCE_TYPE_BITMAP)
+                {
+                    err = CompositeSrc1(&pblit_dev->hwdev,		\
+                                        &cmd_param.compparam.Src0, 		\
+                                        &cmd_param.compparam.Src1, 		\
+                                        &cmd_param.compparam.Dst, 		\
+                                        cmd_param.compparam.AluMode, 		\
+                                        cmd_param.compparam.BlendEnable, 	\
+                                        cmd_param.compparam.IsS0OnTopS1, 	\
+                                        cmd_param.compparam.ROPAlphaCtrl);
+                }
+            else if(cmd_param.compparam.Src1.Type == CSBLIT_SOURCE_TYPE_COLOR &&
+                    cmd_param.compparam.Src0.Type == CSBLIT_SOURCE_TYPE_BITMAP)
+                {
+                    err = CompositeSrc1(&pblit_dev->hwdev,		\
+                                        &cmd_param.compparam.Src0, 		\
+                                        &cmd_param.compparam.Src1, 		\
+                                        &cmd_param.compparam.Dst, 		\
+                                        cmd_param.compparam.AluMode, 		\
+                                        cmd_param.compparam.BlendEnable, 	\
+                                        !cmd_param.compparam.IsS0OnTopS1,	/*src0/1 reversed*/ 	\
+                                        cmd_param.compparam.ROPAlphaCtrl);
+                }
+            else 
+                {
+                    printk(KERN_WARNING "Slave Now can't support 2 A0 Source Composite!\n");
+                    goto ERR_INVAL;
+                }
+            break;
+
+        case BLIT_GET_FB0_ADDR:
+            DEBUG_PRINTF("BLIT_GET_FB0_ADDR\n");
+            err = __put_user(FB0_REGION, (unsigned int __user *) arg);
+            break;
+        case BLIT_GET_FB1_ADDR:
+            DEBUG_PRINTF("BLIT_GET_FB1_ADDR\n");
+            err = __put_user(FB1_REGION, (unsigned int __user *) arg);
+            break;
+        case BLIT_GET_FB0_SIZE:
+            DEBUG_PRINTF("BLIT_GET_FB0_SIZE\n");
+            err = __put_user(FB0_SIZE, (unsigned int __user *) arg);
+            break;
+        case BLIT_GET_FB1_SIZE:
+            DEBUG_PRINTF("BLIT_GET_FB1_SIZE\n");
+            err = __put_user(FB1_SIZE, (unsigned int __user *) arg);
+            break;
+
+        case BLIT_MALLOC_DMA:
+            {
+                BLIT_DMA_BUFFER_STUFF_t dma_buf;
+                blit_buffer_list * dma_buffer_list;
+                DEBUG_PRINTF("BLIT_MALLOC_DMA\n");
+                copy_from_user(&dma_buf, (unsigned int __user *) arg, sizeof(BLIT_DMA_BUFFER_STUFF_t));
+                dma_buf.kernel_virt_addr = malloc_config(dma_buf.user_needed_size);
+                if(dma_buf.kernel_virt_addr == 0){
+                    dma_buf.kernel_needed_size = 0;
+                    dma_buf.phy_addr = 0;
+                    dma_buf.user_needed_size = 0;
+                    dma_buf.user_virt_addr = 0;
+                }
+                else{
+                    dma_buf.kernel_needed_size = PAGE_SIZE << (get_order(dma_buf.user_needed_size));
+                    dma_buf.phy_addr = (void*)page_to_phys(virt_to_page(dma_buf.kernel_virt_addr));
+                }
+                DEBUG_PRINTF("BLIT_MALLOC_DMA:0x%x,0x%x,0x%x,0x%x,0x%x\n",dma_buf.user_needed_size,
+                             (unsigned int)dma_buf.user_virt_addr,(unsigned int)dma_buf.phy_addr,
+                             dma_buf.kernel_needed_size,(unsigned int)dma_buf.kernel_virt_addr);
+
+                copy_to_user((unsigned int __user *) arg, &dma_buf, sizeof(BLIT_DMA_BUFFER_STUFF_t));
+                dma_buffer_list = (blit_buffer_list *)kmalloc(sizeof(blit_buffer_list),GFP_KERNEL);
+                memcpy(&dma_buffer_list->pointer,&dma_buf,sizeof(BLIT_DMA_BUFFER_STUFF_t));
+                INIT_LIST_HEAD(&dma_buffer_list->buffer_list);
+                list_add_tail(&dma_buffer_list->buffer_list, &pblit_dev->buffer_head);
+                err = 0;
+            }
+            break;
+        case BLIT_FREE_DMA:
+            {
+                BLIT_DMA_BUFFER_STUFF_t dma_buf;
+                blit_buffer_list * dma_buffer_list;
+                struct list_head *pos, *temp;
+
+                DEBUG_PRINTF("BLIT_FREE_DMA\n");
+                copy_from_user(&dma_buf, (unsigned int __user *) arg, sizeof(BLIT_DMA_BUFFER_STUFF_t));
+                DEBUG_PRINTF("BLIT_FREE_DMA:0x%x,0x%x,0x%x,0x%x,0x%x\n",dma_buf.user_needed_size,
+                             (unsigned int)dma_buf.user_virt_addr,(unsigned int)dma_buf.phy_addr,
+                             dma_buf.kernel_needed_size,(unsigned int)dma_buf.kernel_virt_addr);
+
+                list_for_each_safe(pos, temp, &pblit_dev->buffer_head){
+                    dma_buffer_list = list_entry(pos, blit_buffer_list, buffer_list);
+                    if(dma_buffer_list->pointer.phy_addr == dma_buf.phy_addr){
+                        list_del(pos);
+                        kfree(dma_buffer_list);
+                    }
+                }
+
+                free_contig(dma_buf.kernel_virt_addr, dma_buf.kernel_needed_size);
+                dma_buf.kernel_virt_addr = 0;
+                dma_buf.phy_addr = 0;
+                dma_buf.kernel_needed_size = 0;
+                copy_to_user((unsigned int __user *) arg, &dma_buf, sizeof(BLIT_DMA_BUFFER_STUFF_t));
+                err = 0;
+            }
+            break;
+
+        default:
+            goto ERR_INVAL;
+        }
+
+    spin_unlock(&blit_lock);
+    return err;
+
+ ERR_INVAL:
+    spin_unlock(&blit_lock);
+    return -EINVAL;
+}
+
+static unsigned char*v_addr = NULL;
+static unsigned int * phy_addr = NULL;
+static unsigned int size = 0;
+static int blit_proc_write(struct file *file, const char *buffer,unsigned long count, void *data)
+{
+	unsigned int addr;
+	unsigned int val;
+
+	const char *cmd_line = buffer;
+
+	if (strncmp("rl", cmd_line, 2) == 0) {
+		addr = simple_strtol(&cmd_line[3], NULL, 16);
+		val = ioread32((void __iomem *)cs_blit_base+addr);
+		printk(" readl [0x%04x] = 0x%08x \n", addr, val);
+	}
+	else if (strncmp("wl", cmd_line, 2) == 0) {
+		addr = simple_strtol(&cmd_line[3], NULL, 16);
+		val = simple_strtol(&cmd_line[7], NULL, 16);
+		iowrite32(val, (void __iomem *)cs_blit_base+(addr>>2));
+	}
+	else if(strncmp("dumpreg", cmd_line, 7) == 0){
+		int i = 0;
+		for(i = 0;i<100;i +=4){
+			printk(" cs_blit register : addr[0x%08x] = 0x%08x \n", 0x40000000+i, ioread32((void __iomem *)(cs_blit_base+(i>>2))));
+		}
+	}
+	else if(strncmp("page_malloc", cmd_line, 11) == 0){
+		int i = 0;
+		unsigned int aaa = 0;
+		struct page * page;
+		size = simple_strtol(&cmd_line[12], NULL, 16);
+		printk("size = 0x%x\n",size);
+		//v_addr = __get_free_pages(GFP_DMA|GFP_KERNEL, size);
+		//phy_addr = virt_to_phys(v_addr);
+		page = alloc_pages(GFP_DMA|GFP_KERNEL, get_order(size));
+		aaa =size;
+		if (!page){
+			printk("111111111111111111111111\n");
+		}
+		else{
+			v_addr = (unsigned char *) page_address(page);
+			if (v_addr) {
+				unsigned long adr = (unsigned long)v_addr;
+				while (size > 0) {
+					//SetPageReserved(virt_to_page(adr));
+					adr += PAGE_SIZE;
+					size -= PAGE_SIZE;
+				}
+			} else
+				printk( "dma memory can't be alloced!!\n");
+
+            phy_addr = (unsigned int *)page_to_phys(page);
+			for(i = 0; i< 0x1000;i++){
+				*(v_addr+i) = 0xee;
+				printk("0x%x = %d\n",(unsigned int)v_addr+i,*(v_addr+i));
+			}
+		}
+		printk("dma_malloc:wanted size = 0x%x, malloced phy_addr = 0x%x, v_addr = 0x%x\n",size,(unsigned int)phy_addr,(unsigned int)v_addr);
+	}
+	else if(strncmp("page_free", cmd_line, 9) == 0){
+		free_pages((unsigned long)v_addr, size);
+		printk("dma_free:wanted size = 0x%x, phy_addr = 0x%x, v_addr = 0x%x\n",size,(unsigned int)phy_addr,(unsigned int)v_addr);
+	}
+	return count;
+}
+
+static int __init blit_init(void)
+{
+	if (misc_register(&cs_blit_miscdev))
+		return -EIO;
+
+    // if (!request_mem_region(CS_BLIT_BASE, CS_BLIT_SIZE, "ORION BLIT"))
+    // {
+    // misc_deregister(&cs_blit_miscdev);
+    // return -EIO;
+    // }
+
+	// cs_blit_base = ioremap(CS_BLIT_BASE, CS_BLIT_SIZE);
+ 
+    cs_blit_base = (unsigned int *)VA_IO_GRAPHICS_BASE;
+	if(!cs_blit_base) {
+		// release_mem_region(CS_BLIT_BASE, CS_BLIT_SIZE);
+		misc_deregister(&cs_blit_miscdev);
+		return -EIO;
+	}
+
+	pblit_dev = kzalloc ( 1 * sizeof(blit_dev), GFP_KERNEL);
+	if (!pblit_dev) {
+		// iounmap((void *)cs_blit_base);
+		// release_mem_region(CS_BLIT_BASE, CS_BLIT_SIZE);
+        misc_deregister(&cs_blit_miscdev);
+		return -ENOMEM;
+	}
+
+	// memset ( pblit_dev, 0, 1 * sizeof(blit_dev));
+
+	INIT_LIST_HEAD(&pblit_dev->buffer_head);
+	
+	spin_lock_init(&blit_lock);
+
+	/* Initialize hardware device. */
+	spin_lock(&blit_lock);
+	pblit_dev->hwdev.RegBaseAddr = (unsigned int)cs_blit_base;
+	pblit_dev->hwdev.BlitType = BLIT_TYPE_1200;
+	blit_initialize(&pblit_dev->hwdev);
+	spin_unlock(&blit_lock);
+
+	blit_proc_entry = create_proc_entry("blit_io", 0, NULL);
+	if (NULL != (void *)blit_proc_entry) {
+		blit_proc_entry->write_proc = &blit_proc_write;
+	}
+
+	printk(KERN_INFO "CS BLIT Initialed\n");
+
+	return 0;
+}
+
+static void __exit blit_exit(void)
+{
+	if (pblit_dev) {
+        // iounmap((void *)pblit_dev->hwdev.RegBaseAddr);
+        kfree ( pblit_dev );
+        pblit_dev = NULL;
+    }
+    
+    // release_mem_region(CS_BLIT_BASE, CS_BLIT_SIZE);
+	misc_deregister(&cs_blit_miscdev);
+}
+
+module_init(blit_init);
+module_exit(blit_exit);
+
+MODULE_AUTHOR("jia.ma,Celestial Semiconductor");
+MODULE_DESCRIPTION("Celestial Semiconductor BLIT driver");
+MODULE_LICENSE("GPL");
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/celestial/graphics/cnc18xx_blit.h linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/graphics/cnc18xx_blit.h
--- linux-linaro-3.4-2012.05-1_original/drivers/celestial/graphics/cnc18xx_blit.h	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/graphics/cnc18xx_blit.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,42 @@
+/*******************************************************************************
+
+File name   : orion_blit.h
+
+Description : orion blitter driver head file
+
+COPYRIGHT (C) Celestial Semiconductor 2007.
+
+Date               Modification                                     Name
+----               ------------                                     ----
+14 Nov 2007        Created                                           XM.Chen
+*******************************************************************************/
+
+
+#ifndef	_ORION_BLIT_H_
+#define _ORION_BLIT_H_
+
+#include "blit_hw.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define BLIT_MAGIC 'B'
+#define CMD_FILL 	_IOW(BLIT_MAGIC, 1, int)
+#define CMD_COPY 	_IOW(BLIT_MAGIC, 2, int)
+#define CMD_SCALOR 	_IOW(BLIT_MAGIC, 3, int)
+#define CMD_COMP 	_IOW(BLIT_MAGIC, 4, int)
+#define BLIT_MAXNR 4
+
+typedef struct CSBlit_Device 
+{
+	CSBlit_HW_Device_t	hwdev;
+	struct list_head		buffer_head;
+} blit_dev;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //_ORION_BLIT_H_
+
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/celestial/graphics/cnc18xx_gfxobj.h linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/graphics/cnc18xx_gfxobj.h
--- linux-linaro-3.4-2012.05-1_original/drivers/celestial/graphics/cnc18xx_gfxobj.h	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/graphics/cnc18xx_gfxobj.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,117 @@
+/*******************************************************************************
+
+File name   : orion_gfxobj.h
+
+Description : 
+
+COPYRIGHT (C) CelestialSemi 2007.
+
+Date               Modification                               Name
+----               ------------                               ----
+2007-03-30         Created                                    xm.chen
+*******************************************************************************/
+
+/* Define to prevent recursive inclusion */
+
+#ifndef __ORION_GFXOBJ_H____
+#define __ORION_GFXOBJ_H____
+
+/* Includes ----------------------------------------------------------------- */
+#include <linux/types.h>
+
+/* C++ support */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Exported Constants ------------------------------------------------------- */
+typedef u8 boolean;
+#ifndef TRUE
+	#define TRUE 1
+#endif
+#ifndef FALSE
+	#define FALSE 0
+#endif
+
+typedef enum CSBLIT_ColorType_e
+{
+  CSBLIT_COLOR_TYPE_A0 = 2,       /*one single color, can't be set to output colortype*/
+  CSBLIT_COLOR_TYPE_RGB565 = 0,
+  CSBLIT_COLOR_TYPE_ARGB1555 = 3,
+  CSBLIT_COLOR_TYPE_ARGB4444 = 1,
+  CSBLIT_COLOR_TYPE_ARGB8888 = 6,
+  CSBLIT_COLOR_TYPE_CLUT4 = 4,
+  CSBLIT_COLOR_TYPE_CLUT8 = 5,
+} CSBLIT_ColorType_t;
+
+typedef struct CSBLIT_Bitmap_s
+{
+  CSBLIT_ColorType_t			ColorType;
+  unsigned int                                   Width;
+  unsigned int                                   Height;
+  unsigned int                                   Pitch;
+  unsigned int                                   Offset;
+  void*                                 Data_p;
+  unsigned int                                   Size;
+} CSBLIT_Bitmap_t;
+
+typedef struct CSBLIT_ColorARGB_s
+{
+  unsigned char Alpha;
+  unsigned char R;
+  unsigned char G;
+  unsigned char B;
+} CSBLIT_ColorARGB_t;
+
+typedef struct CSBLIT_ColorRGB_s
+{
+  unsigned char R;
+  unsigned char G;
+  unsigned char B;
+} CSBLIT_ColorRGB_t;
+
+typedef struct CSBLIT_ColorKeyRGB_s
+{
+  unsigned char      RMin;
+  unsigned char      RMax;
+  unsigned char    ROut;
+  
+  unsigned char      GMin;
+  unsigned char      GMax;
+  unsigned char    GOut;
+
+  unsigned char      BMin;
+  unsigned char      BMax;
+  unsigned char    BOut;
+
+  unsigned char    RGBEnable;
+} CSBLIT_ColorKeyRGB_t;
+
+typedef union CSBLIT_ColorValue_u
+{
+  CSBLIT_ColorARGB_t           ARGB8888;
+  CSBLIT_ColorRGB_t            RGB565;
+} CSBLIT_ColorValue_t;
+
+typedef struct CSBLIT_Color_s
+{
+  CSBLIT_ColorType_t            Type;
+  CSBLIT_ColorValue_t           Value;
+} CSBLIT_Color_t;
+
+typedef struct CSBLIT_Rectangle_s
+{
+  int PositionX;
+  int PositionY;
+  unsigned int Width;
+  unsigned int Height;
+} CSBLIT_Rectangle_t;
+/* C++ support */
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* #ifndef __ORION_GFXOBJ_H */
+
+/* End of orion_gxobj.h */
+
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/celestial/graphics/Kconfig linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/graphics/Kconfig
--- linux-linaro-3.4-2012.05-1_original/drivers/celestial/graphics/Kconfig	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/graphics/Kconfig	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,30 @@
+#
+# Character device configuration
+#
+
+menu "Celestial Graphics driver"
+
+config CELESTIAL_GRAPHICS
+	bool "GRAPHICS(2D)"
+	depends on ARCH_CELESTIAL
+	default y
+    help 
+      Include support drvier for graphic of celestial platform
+
+config CELESTIAL_GRAPHICS_DEBUG
+       bool "Debugging 2D graphics engine"
+       depends on CELESTIAL_GRAPHICS
+       help
+         This turns on low-level debugging for the celestial graphics driver.
+           Normally, you should say 'N'.
+
+
+config GRAPHICS_DEBUG_VERBOSE
+       int "2D Engine Debugging verbosity (0 = quiet, 3 = noisy)"
+       depends on CELESTIAL_GRAPHICS_DEBUG
+       default "0"
+       help
+         Determines the verbosity level of the Graphics debugging messages.
+
+endmenu
+
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/celestial/graphics/Makefile linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/graphics/Makefile
--- linux-linaro-3.4-2012.05-1_original/drivers/celestial/graphics/Makefile	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/graphics/Makefile	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,9 @@
+#
+# Makefile for the linux kernel.
+# 
+#
+
+
+ifdef CONFIG_ARCH_CELESTIAL
+obj-$(CONFIG_CELESTIAL_GRAPHICS) += blit_hw.o cnc18xx_blit.o blit_ioctl.o
+endif
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/celestial/Kconfig linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/Kconfig
--- linux-linaro-3.4-2012.05-1_original/drivers/celestial/Kconfig	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/Kconfig	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,17 @@
+# drivers/celestial/Kconfig
+
+menu "Celestial Device Drivers"
+
+source "drivers/celestial/df/Kconfig"
+
+source "drivers/celestial/xport/Kconfig"
+
+source "drivers/celestial/video/Kconfig"
+
+source "drivers/celestial/audio/Kconfig"
+
+source "drivers/celestial/peripheral/Kconfig"
+
+source "drivers/celestial/graphics/Kconfig"
+
+endmenu
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/celestial/Makefile linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/Makefile
--- linux-linaro-3.4-2012.05-1_original/drivers/celestial/Makefile	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/Makefile	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,10 @@
+#
+# Makefile for the Linux kernel device drivers.
+#
+
+obj-y				+= peripheral/
+obj-$(CONFIG_CELESTIAL_DF)	+= df/
+obj-$(CONFIG_CELESTIAL_XPORT)	+= xport/
+obj-$(CONFIG_CELESTIAL_VIDEO)   += video/
+obj-$(CONFIG_CELESTIAL_AUDIO)	+= audio/
+obj-$(CONFIG_CELESTIAL_GRAPHICS)	+= graphics/
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/celestial/peripheral/cnc18xx_fpc.c linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/peripheral/cnc18xx_fpc.c
--- linux-linaro-3.4-2012.05-1_original/drivers/celestial/peripheral/cnc18xx_fpc.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/peripheral/cnc18xx_fpc.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,1033 @@
+/*
+Rev Date        Author      Comments
+--------------------------------------------------------------------------------
+
+*/
+
+//#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/miscdevice.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <mach/system.h>
+#include <linux/input.h>
+#include <linux/major.h>
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/proc_fs.h>
+#include <linux/poll.h>
+#include <mach/hardware.h>
+#include <asm/atomic.h>
+#include <asm/uaccess.h>
+#include <mach/mux.h>
+#include "cnc18xx_fpc.h"
+
+MODULE_AUTHOR("Cavium Celestial SDK team");
+MODULE_DESCRIPTION("Cavium Celestial Front Panel Controller driver");
+MODULE_LICENSE("GPL");
+
+//#define REPEAT_PERIOD		150	/* NEC: 110ms, RC5: 114ms */
+
+/* Global variables */
+static cs_rc_t *rc_dev;
+static struct proc_dir_entry *fpc_proc_entry = NULL;
+static void __iomem *cs_fpc_base;
+static int rc_system_code = 0xffffffff;
+DEFINE_SPINLOCK(cs_fpc_lock);
+
+#define fpc_writew(v,a)    	iowrite16(v, (cs_fpc_base + (a)))
+#define fpc_readw(a)       	ioread16((cs_fpc_base + (a)))
+
+/* Predefined value */
+typedef struct {
+	unsigned int h_low;
+	unsigned int h_high;
+	unsigned int t_low;
+	unsigned int t_high;
+} pta_t;	/* protocal time ajust */
+
+/* NEC State Machine */
+#define NEC_HEAD   	    0
+#define NEC_REPEAT  	1
+#define NEC_ZERO    	2
+#define NEC_ONE     	3
+#define NEC_DROP   	    4
+
+#define NEC_ENTRY 4
+static pta_t pta_nec[NEC_ENTRY] = {
+	{ 8500, 9500, 13000, 14000 },	/* head */
+	{ 8500, 9500, 11000, 12000 },	/* repeat */
+	{ 400, 700, 1000, 1250 },	/* zero */
+	{ 400, 700, 2100, 2350 }	/* one */
+};
+
+/* RC5 State Machine */
+#define RC5_ONE_BIT	0
+#define RC5_ZO_BITS	1
+#define RC5_OZ_BITS	2
+#define RC5_OZO_BITS	3
+#define RC5_DROP	4
+#define RC_OVERFLOW_FLAG 7
+
+static pta_t pta_rc5[] = {
+	{ 750, 1050, 1600, 1900 },	/* normal */
+	{ 750, 1050, 2400, 2720 },	/* zero one one */
+	{ 1600, 1800, 2300, 2720 },	/* one zero zero */
+	{ 1600, 1900, 3100, 3700 },	/* one zero one */
+};
+
+/* RC6 state machine */
+#define RC6_STATE_LEARDER        0
+#define RC6_STATE_ONE            1
+#define RC6_STATE_OhZ            2
+#define RC6_STATE_hZO            3
+#define RC6_STATE_hZOhZ          4
+#define RC6_STATE_hT0O           5
+#define RC6_STATE_hT0OhZ         6
+#define RC6_STATE_hO             7
+#define RC6_STATE_hZhO           8
+#define RC6_STATE_ERROR          10
+
+/* There is no T1 in Mode 6A, so no status of T1 in this status machine */
+/* In the second note '-' means v+ and '_' means v- */
+static pta_t pta_rc6[] = {
+	{ 2000, 2800, 3300, 3700 },	/* LEARDER 2667 3556 */ /* ------__ */
+	{  100,  550,  600, 1000 },	/* One 444 889 */ /* -_ */
+	{  100,  550, 1100, 1550 },	/* One & half Zero 444 1333 , also could be half Zero & half T0 */ /* -__ */
+	{  560, 1000, 1100, 1550 },	/* half Zero & One 889 1333 */ /* --_ */
+	{  560, 1000, 1600, 1900 },	/* half Zero & One & half Zero 889 1778 */ /* --__ */
+	{ 1100, 1600, 1600, 1900 },	/* half T0 & One 1333 1778 */ /* ---_ */
+	{ 1100, 1600, 2000, 2500 },	/* half T0 & One & half Zero 1333 2222 */ /* ---__ */
+	{  100,  550,    0,    0 },	/* half One 444 0 */ /* - */
+    {  560, 1000,    0,    0 }	/* half Zero & half One 889 0 */ /* -- */
+                                /* if the last bit is one, maybe can only get the first half */
+};
+
+#define RC6_LEADER_BIT        0x11
+#define RC6_ONE_BIT           0x12
+#define RC6_ZERO_BIT          0x13
+#define RC6_T0_BIT            0x14
+#define RC6_T1_BIT            0x15
+#define RC6_OZ_BIT            0x16
+#define RC6_ZO_BIT            0x17
+#define RC6_T0O_BIT           0x18
+/* End of RC6 state machine */
+
+/* Decode protocal */
+static int cnc_nec_decode_bit(unsigned int high_val, unsigned int total_val)
+{
+	int ret = NEC_DROP;
+
+	if((high_val >= pta_nec[NEC_HEAD].h_low) &&
+			(high_val <= pta_nec[NEC_HEAD].h_high) &&
+			(total_val >= pta_nec[NEC_HEAD].t_low) &&
+			(total_val <= pta_nec[NEC_HEAD].t_high)) {
+
+		PDEBUG("NEC_HEAD: high_val: %d, total_val: %d--NEC HEAD\n", high_val, total_val);
+		ret = NEC_HEAD;
+
+	} else if((high_val >= pta_nec[NEC_REPEAT].h_low) &&
+			(high_val <= pta_nec[NEC_REPEAT].h_high) &&
+			(total_val >= pta_nec[NEC_REPEAT].t_low) &&
+			(total_val <= pta_nec[NEC_REPEAT].t_high)) {
+
+		PDEBUG("NEC_REPEAT: high_val: %d, total_val: %d--NEC REPEAT\n", high_val, total_val);
+		ret = NEC_REPEAT;
+
+	} else if((high_val >= pta_nec[NEC_ZERO].h_low) &&
+			(high_val <= pta_nec[NEC_ZERO].h_high) &&
+			(total_val >= pta_nec[NEC_ZERO].t_low) &&
+			(total_val <= pta_nec[NEC_ZERO].t_high)) {
+
+		PDEBUG("NEC_ZERO: high_val: %d, total_val: %d--NEC ZERO\n", high_val, total_val);
+		ret = NEC_ZERO;
+
+	} else if ((high_val >= pta_nec[NEC_ONE].h_low) &&
+			(high_val <= pta_nec[NEC_ONE].h_high) &&
+			(total_val >= pta_nec[NEC_ONE].t_low) &&
+			(total_val <= pta_nec[NEC_ONE].t_high)) {
+
+		PDEBUG("NEC_ONE : high_val: %d, total_val: %d--NEC ONE\n", high_val, total_val);
+		ret = NEC_ONE;
+
+	} else {
+
+		PDEBUG("NECXXXXXXXXX_DROP: high_val: %d, total_val: %d--NEC DROP\n", high_val, total_val);
+		ret = NEC_DROP;
+	}
+
+	return ret;
+}
+
+static int cnc_nec_decode(int idx)
+{
+	int nec_st;
+
+	PDEBUG("idx %2d ", idx);
+	nec_st = cnc_nec_decode_bit(rc_dev->fifo1[idx], rc_dev->fifo2[idx]);
+
+	switch(rc_dev->record.decode_period) {
+		case HEAD_PERIOD:              /* Head Period */
+			switch (nec_st) {
+				case NEC_HEAD:
+					rc_dev->record.bit = 0;
+					rc_dev->record.rpt = 0;
+					rc_dev->record.decode_period = ADDR_PERIOD;
+					break;
+
+				case NEC_REPEAT:
+					rc_dev->record.bit = 0;
+
+					// rc_dev->max_rpt = 2; /* FIXME: To be set outside */
+#if 1
+					if (rc_dev->record.rpt == (rc_dev->max_rpt-1)) {
+						rc_dev->record.rpt = 0;
+						return 1;
+					} else {
+						rc_dev->record.rpt++;
+					}
+#else	/* for test */
+					rc_dev->record.rpt++;
+					return 1;
+#endif
+					rc_dev->record.decode_period = HEAD_PERIOD;
+					break;
+
+
+				case NEC_DROP:
+				case NEC_ZERO:
+				case NEC_ONE:
+				default:
+					rc_dev->record.bit = 0;
+					//					rc_dev->record.rpt =0;
+					//                    rc_dev->record.decode_period = HEAD_PERIOD;
+			}
+
+			break;
+
+		case ADDR_PERIOD:        /* Address Period */
+			switch (nec_st) {
+				case NEC_HEAD:
+					rc_dev->record.bit = 0;
+					rc_dev->record.rpt = 0;
+					rc_dev->record.decode_period = HEAD_PERIOD;
+					return 0;
+				case NEC_REPEAT:
+					rc_dev->record.rpt++;
+					rc_dev->record.decode_period = HEAD_PERIOD;
+					break;
+				case NEC_DROP:
+					rc_dev->record.bit = 0;
+					rc_dev->record.rpt = 0;
+					rc_dev->record.decode_period = HEAD_PERIOD;
+					break;
+				case NEC_ZERO:
+					clear_bit(rc_dev->record.bit, (unsigned long *)&rc_dev->record.addr);
+					break;
+				case NEC_ONE:
+					set_bit(rc_dev->record.bit, (unsigned long *)&rc_dev->record.addr);
+					break;
+			}
+
+			if(rc_dev->record.bit == (16-1)) {
+				rc_dev->record.bit = 0;
+				rc_dev->record.addr = rc_dev->record.addr & 0xffff;
+				rc_dev->record.decode_period = CMD_PERIOD;	/* FIXME: Sun: temparary enable cmd process */
+			} else {
+				rc_dev->record.bit++;
+			}
+#if 0
+			if(rc_dev->addr == rc_dev->record.addr)
+				rc_dev->record.decode_period = CMD_PERIOD;
+			else
+				rc_dev->record.decode_period = HEAD_PERIOD;
+#endif
+
+			break;
+
+		case CMD_PERIOD:                                           /* Command Period */
+			switch (nec_st) {
+				case NEC_HEAD:
+					rc_dev->record.bit = 0;
+					rc_dev->record.rpt = 0;
+					rc_dev->record.decode_period = HEAD_PERIOD;
+					return 0;
+				case NEC_REPEAT:
+				case NEC_DROP:
+					rc_dev->record.bit = 0;
+					rc_dev->record.rpt = 0;
+					rc_dev->record.decode_period = HEAD_PERIOD;
+					break;
+				case NEC_ZERO:
+					clear_bit(rc_dev->record.bit, (unsigned long *)&rc_dev->record.cmd);
+					break;
+				case NEC_ONE:
+					set_bit(rc_dev->record.bit, (unsigned long *)&rc_dev->record.cmd);
+					break;
+			}
+
+			if(rc_dev->record.bit == (16-1)) {
+				rc_dev->record.bit = 0;
+				rc_dev->record.cmd = rc_dev->record.cmd & 0xff;
+				rc_dev->record.decode_period = HEAD_PERIOD;
+				return 1;
+			} else {
+				rc_dev->record.bit++;
+			}
+
+			break;
+
+		default:
+			;
+	}
+
+	return 0;
+}
+
+/*RC5 Decorder*/
+static unsigned int cnc_rc5_decode_bit(unsigned int high_val,unsigned int total_val)
+{
+	int ret = RC5_DROP;
+
+	if(((high_val >= pta_rc5[RC5_ONE_BIT].h_low) &&
+				(high_val <= pta_rc5[RC5_ONE_BIT].h_high)) &&
+
+			(((total_val >= pta_rc5[RC5_ONE_BIT].t_low) &&
+			  (total_val <= pta_rc5[RC5_ONE_BIT].t_high)) ||
+
+			 rc_dev->record.bit == 13)) { /* total_val equal 0 , this means received last  one bit, (one or zero) */
+
+		PDEBUG("RC5_ONE_BIT: bit: %d, high_val: %d, total_val: %d\n", rc_dev->record.bit, high_val, total_val);
+		ret = RC5_ONE_BIT;
+
+	} else if((high_val >= pta_rc5[RC5_ZO_BITS].h_low) &&
+			(high_val <= pta_rc5[RC5_ZO_BITS].h_high) &&
+			(total_val >= pta_rc5[RC5_ZO_BITS].t_low) &&
+			(total_val <= pta_rc5[RC5_ZO_BITS].t_high)) {
+
+		PDEBUG("RC5_ZO_BITS: bit: %d, high_val: %d, total_val: %d\n", rc_dev->record.bit, high_val, total_val);
+		ret = RC5_ZO_BITS;
+
+	} else if(((high_val >= pta_rc5[RC5_OZ_BITS].h_low) &&
+				(high_val <= pta_rc5[RC5_OZ_BITS].h_high)) &&
+
+			(((total_val >= pta_rc5[RC5_OZ_BITS].t_low) &&
+			  (total_val <= pta_rc5[RC5_OZ_BITS].t_high)) ||
+
+			 rc_dev->record.bit == 12)) { /* total_val equal 0, it means received both one and zero bits */
+
+		PDEBUG("RC5_OZ_BITS: bit: %d, high_val: %d, total_val: %d\n", rc_dev->record.bit, high_val, total_val);
+		ret = RC5_OZ_BITS;
+
+	} else if((high_val >= pta_rc5[RC5_OZO_BITS].h_low) &&
+			(high_val <= pta_rc5[RC5_OZO_BITS].h_high) &&
+			(total_val >= pta_rc5[RC5_OZO_BITS].t_low) &&
+			(total_val <= pta_rc5[RC5_OZO_BITS].t_high)) {
+
+		PDEBUG("RC5_OZO_BITS: bit: %d, high_val: %d, total_val: %d\n", rc_dev->record.bit, high_val, total_val);
+		ret = RC5_OZO_BITS;
+
+	} else {
+
+		PDEBUG("RC5XXXXXXXXX_DROP: bit: %d, high_val: %d, total_val: %d\n", rc_dev->record.bit, high_val, total_val);
+		ret = RC5_DROP;
+	}
+
+	return ret;
+}
+
+static unsigned int cnc_rc5_decode(int idx)
+{
+	int rc5_st;
+	int toggle;
+
+	PDEBUG("idx %2d ", idx);
+	rc5_st = cnc_rc5_decode_bit(rc_dev->fifo1[idx], rc_dev->fifo2[idx]);
+
+	switch (rc5_st) {
+		case RC5_ONE_BIT:
+			rc_dev->record.rc5_data <<= 1;
+			if (! rc_dev->record.next_bit_is_zero)
+				rc_dev->record.rc5_data |= 1;
+			rc_dev->record.bit += 1;
+			break;
+		case RC5_ZO_BITS:
+			rc_dev->record.rc5_data <<= 1;
+			//rc_dev->record.rc5_data |= 1;
+			rc_dev->record.next_bit_is_zero = 0;
+			rc_dev->record.bit += 1;
+			break;
+		case RC5_OZ_BITS:
+			rc_dev->record.rc5_data <<= 2;
+			rc_dev->record.rc5_data |= 2;
+			rc_dev->record.next_bit_is_zero = 1;
+			rc_dev->record.bit += 2;
+			break;
+		case RC5_OZO_BITS:
+			rc_dev->record.rc5_data <<= 2;
+			rc_dev->record.rc5_data |= 2;
+			rc_dev->record.next_bit_is_zero = 0;
+			rc_dev->record.bit += 2;
+			break;
+		default:	/* Error occurs */
+			rc_dev->record.bit = 0;
+			rc_dev->record.next_bit_is_zero = 0;
+			rc_dev->bit_err = 1;
+	}
+
+	if (rc_dev->record.bit == 14) {	/* Ok, we received all bits */
+
+		rc_dev->record.addr = (rc_dev->record.rc5_data & 0x07c0) >> 6;
+		rc_dev->record.cmd = rc_dev->record.rc5_data & 0x003f;
+		toggle = (rc_dev->record.rc5_data & 0x0800) ? 1: 0;
+
+		PDEBUG ("bit : %d, rc5_data: 0x%4x, toggle: %x, addr %x, cmd %x\n",
+				rc_dev->record.bit, rc_dev->record.rc5_data, toggle, rc_dev->record.addr, rc_dev->record.cmd);
+
+#if 0
+		/* Handle repeat */
+		if (rc_dev->record.pre_T == toggle && rc_dev->record.rpt++ != 0) {
+			if (rc_dev->record.rpt < 3) {
+				rc_dev->record.bit = 0;
+				rc_dev->record.next_bit_is_zero = 0;
+				return 0;
+			} else {
+				rc_dev->record.pre_T = toggle;
+			}
+		}
+#endif
+
+		rc_dev->record.rpt = 0;
+		rc_dev->record.bit = 0;
+		rc_dev->record.next_bit_is_zero = 0;
+		return 1;
+	}
+
+	return 0;
+}
+
+static unsigned int cnc_rc6_mode6a_decode_bit(unsigned int high_val, unsigned int total_val)
+{
+	int ret = RC6_STATE_ERROR;
+
+    return ret;
+}
+
+/* this part is defined by OEM */
+static unsigned int cnc_rc6_mode6a_decode(int idx)
+{
+	return 0;
+}
+
+#if 0
+static unsigned int cnc_rcmm_decode(struct cnc_rc *rc)
+{
+	unsigned int ret;
+	PDEBUG("The protocol type %d is not a valid type\n",cnc_rc_gbl->protocal);
+	ret=0;
+	return ret;
+}
+static unsigned int cnc_recs80_decode(struct cnc_rc *rc)
+{
+	unsigned int ret;
+	PDEBUG("The protocol type %d is not a valid type\n",cnc_rc_gbl->protocal);
+	ret=0;
+	return ret;
+}
+static unsigned int cnc_rca_decode(struct cnc_rc *rc)
+{
+	unsigned int ret;
+	PDEBUG("The protocol type %d is not a valid type\n",cnc_rc_gbl->protocal);
+	ret=0;
+	return ret;
+}
+static unsigned int cnc_xsat_decode(struct cnc_rc *rc)
+{
+	unsigned int ret;
+	PDEBUG("The protocol type %d is not a valid type\n",cnc_rc_gbl->protocal);
+	ret=0;
+	return ret;
+}
+
+static unsigned int cnc_jvc_decode(struct cnc_rc *rc)
+{
+	unsigned int ret;
+	PDEBUG("The protocol type %d is not a valid type\n",cnc_rc_gbl->protocal);
+	ret=0;
+	return ret;
+}
+
+static unsigned int cnc_nrc17_decode(struct cnc_rc *rc)
+{
+	unsigned int ret;
+	PDEBUG("The protocol type %d is not a valid type\n",cnc_rc_gbl->protocal);
+	ret=0;
+	return ret;
+}
+
+static unsigned int cnc_sharp_decode(struct cnc_rc *rc)
+{
+	unsigned int ret;
+	PDEBUG("The protocol type %d is not a valid type\n",cnc_rc_gbl->protocal);
+	ret=0;
+	return ret;
+}
+static unsigned int cnc_sirc_decode(struct cnc_rc *rc)
+{
+	unsigned int ret;
+	PDEBUG("The protocol type %d is not a valid type\n",cnc_rc_gbl->protocal);
+	ret=0;
+	return ret;
+}
+
+static unsigned int cnc_itt_decode(struct cnc_rc *rc)
+{
+	unsigned int ret;
+	PDEBUG("The protocol type %d is not a valid type\n",cnc_rc_gbl->protocal);
+	ret=0;
+	return ret;
+}
+#endif
+
+
+static void rc_do_tasklet(unsigned long data)
+{
+	unsigned long flags;
+	int idx;
+	int got_data = 0;
+
+#ifdef CONFIG_RC_DEBUG	/* Print the fifo count */
+	int i;
+	for (i = 0; i < rc_dev->fc_idx; i++)
+		PDEBUG("  FIFO COUNT fifo1_cnt: %d, fifo2_cnt: %d\n", rc_dev->fc[i][0], rc_dev->fc[i][1]);
+	spin_lock_irqsave(&rc_dev->lock, flags);
+	rc_dev->fc_idx = 0;
+	spin_unlock_irqrestore(&rc_dev->lock, flags);
+	PDEBUG("***************  f1_idx: %d, f2_idx: %d ***************\n", rc_dev->f1_idx, rc_dev->f2_idx);
+#endif
+
+	for (idx = 0; idx < rc_dev->f2_idx || idx< rc_dev->f1_idx; idx++) {
+		if (rc_dev->bit_err)
+			break;
+
+		switch (rc_dev->protocal) {
+			case NEC:
+				got_data = cnc_nec_decode(idx);
+				break;
+			case RC5:
+				got_data = cnc_rc5_decode(idx);
+				break;
+			case RC6_6A:
+				got_data = cnc_rc6_mode6a_decode(idx);
+				break;
+#if 0
+			case TYPE_RCMM:
+				decoder_status=cnc_rcmm_decode(rc_dev);
+				break;
+			case TYPE_RECS80:
+				decoder_status=cnc_recs80_decode(rc_dev);
+				break;
+			case TYPE_RCA:
+				decoder_status=cnc_rca_decode(rc_dev);
+				break;
+			case TYPE_XSAT:
+				decoder_status=cnc_xsat_decode(rc_dev);
+				break;
+			case TYPE_JVC:
+				decoder_status=cnc_jvc_decode(rc_dev);
+				break;
+			case TYPE_NRC17:
+				decoder_status=cnc_nrc17_decode(rc_dev);
+				break;
+			case TYPE_SHARP:
+				decoder_status=cnc_sharp_decode(rc_dev);
+				break;
+			case TYPE_SIRC:
+				decoder_status=cnc_sirc_decode(rc_dev);
+				break;
+			case TYPE_ITT:
+				decoder_status=cnc_itt_decode(rc_dev);
+				break;
+#endif
+			default:
+				PDEBUG("The protocol type %d is not a valid type\n",rc_dev->protocal);
+		}
+
+		/* FIXME: this value should be determined outside */
+		if(got_data) {
+			PDEBUG("\nYES YES YES Got it! bit: %x rpt: %x addr: %x, cmd: %x\n\n",
+					rc_dev->record.bit, rc_dev->record.rpt, rc_dev->record.addr, rc_dev->record.cmd);
+
+			if ((0xffffffff == rc_system_code) ||
+					((rc_dev->record.addr & 0xff)   == rc_system_code) ||
+					((rc_dev->record.addr & 0xff00) == rc_system_code) ||
+					(rc_dev->record.addr == rc_system_code)) {
+				input_report_key(rc_dev->dev, rc_dev->record.cmd, 1);
+				input_report_key(rc_dev->dev, rc_dev->record.cmd, 0);
+				input_sync(rc_dev->dev);
+			}
+		}
+	}
+
+	spin_lock_irqsave(&rc_dev->lock, flags);
+	/* When data is handled, clear the fifo, and reset err state */
+	rc_dev->bit_err = 0;
+	rc_dev->f1_idx = rc_dev->f2_idx = 0;
+#if 0
+	memset(rc_dev->fifo1, 0, ARRAY_SIZE(rc_dev->fifo1));
+	memset(rc_dev->fifo2, 0, ARRAY_SIZE(rc_dev->fifo2));
+#endif
+	spin_unlock_irqrestore(&rc_dev->lock, flags);
+}
+
+static irqreturn_t rc_dev_interrupt(int irq, void *dev_id)
+{
+	unsigned long  flags;
+	int intr_status;
+	int fifo1_cnt, fifo2_cnt;
+
+	intr_status = fpc_readw(FPC_INTS_L);
+	if ((intr_status & 0x1) || (intr_status & 0x4)) {	/* rc available | timeout */
+		spin_lock_irqsave(&rc_dev->lock, flags);
+
+		fifo1_cnt = fpc_readw(FPC_RC_FIFO1_CNT_L) & 0xf;
+		fifo2_cnt = fpc_readw(FPC_RC_FIFO2_CNT_L) & 0xf;
+
+		if (fifo1_cnt >=  RC_OVERFLOW_FLAG || fifo2_cnt >= RC_OVERFLOW_FLAG) {
+			while(fifo1_cnt --) {
+				fpc_readw(FPC_RC_FIFO1_L);
+			}
+
+			while(fifo2_cnt --) {
+				fpc_readw(FPC_RC_FIFO2_L);
+			}
+			rc_dev->f1_idx = 0;
+			rc_dev->f2_idx = 0;
+		} else {
+			while(fifo1_cnt --) {
+				rc_dev->fifo1[rc_dev->f1_idx++] = fpc_readw(FPC_RC_FIFO1_L);
+				if (rc_dev->f1_idx == FIFO_LEN) rc_dev->f1_idx = 0;
+			}
+			while(fifo2_cnt --) {
+				rc_dev->fifo2[rc_dev->f2_idx++] = fpc_readw(FPC_RC_FIFO2_L);
+				if (rc_dev->f2_idx == FIFO_LEN) rc_dev->f2_idx = 0;
+			}
+		}
+
+		rc_dev->tasklet.data = (unsigned int)0; /* FIXME: to be modified */
+		tasklet_schedule(&rc_dev->tasklet);
+
+		spin_unlock_irqrestore(&rc_dev->lock, flags);
+
+	} else if (intr_status & 0x2) {
+		static unsigned long ticks = 0;
+		unsigned long curr_ticks = jiffies;
+
+		if (curr_ticks - ticks > 23) {
+			rc_dev->record.cmd = fpc_readw(FPC_KSCAN_DATA_L) & 0xff;
+			rc_dev->record.cmd |= 0x100;
+
+			if (rc_dev->record.cmd & 0x80) {
+				spin_lock_irqsave(&rc_dev->lock, flags);
+
+				input_report_key(rc_dev->dev, rc_dev->record.cmd, 1);
+				input_report_key(rc_dev->dev, rc_dev->record.cmd, 0);
+				input_sync(rc_dev->dev);
+
+				spin_unlock_irqrestore(&rc_dev->lock, flags);
+			}
+
+			ticks = curr_ticks;
+		}
+	}
+
+	return IRQ_HANDLED;
+}
+
+static int cs_fpc_ioctl(struct file *file,
+	unsigned int cmd, unsigned long arg)
+{
+   
+    
+	unsigned long flags,userbit,Key_Val;
+	unsigned short rc_ctl, btc;
+	//    unsigned long *arg_temp = (unsigned long *)arg;
+	switch (cmd) {
+		case FPC_LED_EN:
+			
+			spin_lock_irqsave(&cs_fpc_lock, flags);
+
+            fpc_writew(0!=arg ? 0x8000:0x0000, FPC_LED_CNTL_H);
+            fpc_writew(0xff, FPC_LED_CNTL_L);
+            pinmux_update_fpc_status();
+
+			spin_unlock_irqrestore(&cs_fpc_lock, flags);
+
+			break;
+
+		case FPC_LED_DISP:
+			
+			spin_lock_irqsave(&cs_fpc_lock, flags);
+
+			
+
+			fpc_writew((arg >> 16) & 0xffff, FPC_LED_DATA_H);
+
+			
+			fpc_writew(arg & 0xffff, FPC_LED_DATA_L);
+
+			spin_unlock_irqrestore(&cs_fpc_lock, flags);
+
+			break;
+		case FPC_LED_GET:
+			
+			spin_lock_irqsave(&cs_fpc_lock, flags);
+			userbit = fpc_readw(FPC_LED_DATA_H);
+			userbit = userbit << 16;
+			userbit |= fpc_readw(FPC_LED_DATA_L);
+            spin_unlock_irqrestore(&cs_fpc_lock, flags);
+
+			copy_to_user((unsigned long *)arg, &userbit, 4);
+			break;
+
+		case FPC_RC_SET_SYSTEMCODE:
+			
+			spin_lock_irqsave(&cs_fpc_lock, flags);
+			rc_system_code = arg;
+			spin_unlock_irqrestore(&cs_fpc_lock, flags);
+
+			break;
+		case FPC_KEYSCAN_EN:
+			
+			spin_lock_irqsave(&cs_fpc_lock, flags);
+			fpc_writew(arg & 0xffff,FPC_KSCAN_CNTL_L);
+			fpc_writew((arg << 15) & 0xffff,FPC_LED_CNTL_H);
+			spin_unlock_irqrestore(&cs_fpc_lock, flags);
+            pinmux_update_fpc_status();
+			break;
+		case FPC_KSCAN_GET:
+			
+			spin_lock_irqsave(&cs_fpc_lock, flags);
+			Key_Val = fpc_readw(FPC_KSCAN_DATA_H);
+			Key_Val = Key_Val << 16;
+			Key_Val |= fpc_readw(FPC_KSCAN_DATA_L);
+			spin_unlock_irqrestore(&cs_fpc_lock, flags);
+
+			copy_to_user((unsigned long*)arg, &Key_Val, 4);
+			break;
+		case FPC_RC_EN:
+			
+			spin_lock_irqsave(&cs_fpc_lock, flags);
+			rc_ctl = fpc_readw(FPC_RC_CTL_H);
+			if (arg == 1){
+				fpc_writew(rc_ctl | 0x8000, FPC_RC_CTL_H);
+                //			cnc_gpio_register_module_set("RC", 1);
+   			}
+			else if (arg == 0){
+				fpc_writew(rc_ctl & 0x7fff,FPC_RC_CTL_H);
+                //		cnc_gpio_register_module_set("RC", 0);
+			}
+            pinmux_update_rc_status();
+			spin_unlock_irqrestore(&cs_fpc_lock, flags);
+			break;
+		case FPC_SET_BitTimeCnt:
+			
+			spin_lock_irqsave(&cs_fpc_lock, flags);
+
+			rc_ctl = fpc_readw(FPC_RC_CTL_L);
+			rc_ctl &= 0x00ff; rc_ctl |= (arg & 0xff) << 8;
+			fpc_writew(rc_ctl, FPC_RC_CTL_L);
+
+			rc_ctl = fpc_readw(FPC_RC_CTL_H);
+			rc_ctl &= 0xff00; rc_ctl |= (arg >> 8) & 0xff;
+			fpc_writew(rc_ctl, FPC_RC_CTL_H);
+
+			spin_unlock_irqrestore(&cs_fpc_lock, flags);
+			break;
+		case FPC_GET_BitTimeCnt:
+			
+			spin_lock_irqsave(&cs_fpc_lock, flags);
+			rc_ctl = fpc_readw(FPC_RC_CTL_L);
+			btc = (rc_ctl & 0xff00) >> 8;
+
+			rc_ctl = fpc_readw(FPC_RC_CTL_H);
+			btc |= (rc_ctl & 0xff) << 8;
+			spin_unlock_irqrestore(&cs_fpc_lock, flags);
+
+			copy_to_user((unsigned long*)arg, &btc, 2);
+			break;
+
+        case FPC_RC_SET_PROTOCAL:
+			
+            spin_lock_irqsave(&rc_dev->lock, flags);
+            rc_dev->protocal = arg;
+        	spin_unlock_irqrestore(&rc_dev->lock, flags);
+            break;
+		default:
+			
+			break;
+	}
+
+	return 0;
+}
+
+static struct file_operations fpc_fops = {
+	.owner		= THIS_MODULE,
+	.unlocked_ioctl		= cs_fpc_ioctl,
+};
+
+static struct miscdevice fpc_miscdev = {
+	.name = "cs_fpc",
+	.minor = MISC_DYNAMIC_MINOR,
+	.fops = &fpc_fops
+};
+
+static int fpc_proc_write(struct file *file,
+                const char *buffer, unsigned long count, void *data)
+{
+	u32 addr;
+	u16 val;
+
+    const char *cmd_line = buffer;;
+
+    if (strncmp("rw", cmd_line, 2) == 0) {
+		addr = simple_strtol(&cmd_line[3], NULL, 16);
+        val = fpc_readw(addr);
+        printk(" readl [0x%04x] = 0x%04x \n", addr, val);
+    } else if (strncmp("ww", cmd_line, 2) == 0) {
+        addr = simple_strtol(&cmd_line[3], NULL, 16);
+        val = simple_strtol(&cmd_line[9], NULL, 16);
+        fpc_writew(val, addr);
+        pinmux_update_rc_status();
+        pinmux_update_fpc_status();
+    } else if (strncmp("reboot", cmd_line, 6) == 0) {
+        printk("reboot the systme ....\n ");
+        arch_reset(0,0);
+    } else if (strncmp("st", cmd_line, 2) == 0) {	/* set time ajust value */
+		int entry;
+		int hl, hh, tl, th;
+		entry = simple_strtol(&cmd_line[3], NULL, 10);
+
+		hl = simple_strtol(&cmd_line[5], NULL, 10);
+		hh = simple_strtol(&cmd_line[11], NULL, 10);
+		tl = simple_strtol(&cmd_line[17], NULL, 10);
+		th = simple_strtol(&cmd_line[23], NULL, 10);
+
+		pta_nec[entry].h_low = hl; /* pta_nec: protocal time ajust */
+		pta_nec[entry].h_high = hh;
+		pta_nec[entry].t_low = tl;
+		pta_nec[entry].t_high = th;
+	} else if (strncmp("rt", cmd_line, 2) == 0) {	/* read time ajust value */
+		int entry;
+		entry = simple_strtol(&cmd_line[3], NULL, 10);
+		printk (
+				"pta: pta[%d].h_low  = %d\n"
+				"pta: pta[%d].h_high = %d\n"
+				"pta: pta[%d].t_low  = %d\n"
+				"pta: pta[%d].t_high = %d\n",
+				entry, pta_nec[entry].h_low,
+				entry, pta_nec[entry].h_high,
+				entry, pta_nec[entry].t_low,
+				entry, pta_nec[entry].t_high
+		       );
+	} else if (strncmp("sp", cmd_line, 2) == 0) {	/* set remote controller protocals */
+		int protocal;
+		protocal = simple_strtol(&cmd_line[3], NULL, 10);
+		rc_dev->protocal = protocal;
+	} else if (strncmp("rpt", cmd_line, 3) == 0) {	/* set remote controller protocals */
+		val = simple_strtol(&cmd_line[4], NULL, 10);
+		rc_dev->max_rpt = val;
+	} else if (strncmp("dbg", cmd_line, 3) == 0) {	/* set remote controller protocals */
+		if (RC_DEBUG) 	RC_DEBUG = 0;
+		else 		RC_DEBUG = 1;
+	} else if (strncmp("syscode", cmd_line, 7) == 0) {
+		printk("system code: 0x%x\n", rc_dev->record.addr);
+	} else if (strncmp("rms", cmd_line, 3) == 0) {
+        printk("repeat ms is %d.\n", rc_dev->repeat_ms);
+	} else if (strncmp("wms", cmd_line, 3) == 0) {
+    	val = simple_strtol(&cmd_line[4], NULL, 10);
+        if (val > 0 && val < 1000) {
+            printk("set repeat ms to %d.\n", val);
+    	    rc_dev->repeat_ms = val;
+        }
+        else {
+            printk("repeat ms must less than 1000.\n");
+        }
+	}
+	else {
+		printk(KERN_ERR "Illegal command\n");
+	}
+
+    return count;
+}
+
+int __init cs_fpc_init(void)
+{
+    int i;
+    int ret = 0;
+    unsigned short dummy;
+    unsigned short fir_psn;
+    unsigned int rc_ctl;
+
+	
+
+    if (request_irq(CS_RC_IRQ, rc_dev_interrupt, IRQF_DISABLED, "cs_fpc", NULL)) {
+        ret = -EBUSY;
+        goto out;
+    }
+
+    if (!request_mem_region(CS_FPC_BASE, CS_FPC_SIZE, "CNC FPC")) {
+        ret = -EBUSY;
+        goto err1;
+    }
+
+    if (!(cs_fpc_base = (unsigned short *)ioremap(CS_FPC_BASE, CS_FPC_SIZE))) {
+        ret = -EIO;
+        goto err2;
+    }
+
+    if (misc_register(&fpc_miscdev)) {
+        ret = -EBUSY;
+        goto err3;
+    }
+
+	if (!(fpc_proc_entry = create_proc_entry("fpc_io", 0, NULL))) {
+        ret = -EFAULT;
+        goto err4;
+	} else {
+	    fpc_proc_entry->write_proc = fpc_proc_write;
+	}
+
+    if (!(rc_dev = kzalloc(sizeof(cs_rc_t), GFP_KERNEL))) {
+        ret = -ENOMEM;
+        goto err5;
+    }
+
+    //init_input_dev(&rc_dev->dev);
+    rc_dev->dev = input_allocate_device();
+    if (rc_dev->dev == NULL){
+        return -ENOMEM;
+        goto err6;
+    }
+
+    //rc_dev->dev = input;
+    rc_dev->dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+    rc_dev->dev->keycode = rc_dev->keycode;
+    rc_dev->dev->keycodesize = sizeof(unsigned short);
+    rc_dev->dev->keycodemax = ARRAY_SIZE(rc_dev->keycode);
+    //  rc_dev->dev->private = rc_dev;
+
+    for (i = 0; i < CS_FPC_KNUM; i++)            /* Output RAW Code */
+        rc_dev->keycode[i] = i;
+
+    for (i = 0; i < CS_FPC_KNUM; i++)
+        set_bit(rc_dev->keycode[i], rc_dev->dev->keybit);
+
+    rc_dev->dev->name = DRIVER_DESC;
+    rc_dev->dev->phys = "cs_rc";
+    rc_dev->dev->id.bustype = BUS_HOST;
+    rc_dev->dev->id.vendor = 0x0001;
+    rc_dev->dev->id.product = 0x0001;
+    rc_dev->dev->id.version = 0x0104;
+
+    ret = input_register_device(rc_dev->dev);
+    if (ret < 0) {
+        goto err7;
+    }
+
+    /* default repeat is too fast */
+    rc_dev->dev->rep[REP_DELAY]   = 500;
+    rc_dev->dev->rep[REP_PERIOD]  = 100;
+    rc_dev->max_rpt = 3;    /* real repeat every 2 repeat */
+
+    /* init spin lock */
+    spin_lock_init(&rc_dev->lock);
+
+    /* init tasklet */
+    rc_dev->tasklet.func = rc_do_tasklet;
+    {
+        rc_dev->protocal = NEC;
+
+        rc_dev->repeat_ms = 150;    /* for RC6_6A */
+
+        /* Remote Controller config */
+        fpc_writew(0x0, FPC_INTM_L); /* Intr mask */
+
+        /* Noise filter */
+        fir_psn = FILTER_PRECISION * 27000 / PCLK_KHZ;
+        fpc_writew(fir_psn, FPC_FIR_L);  /* Filter precision (0xe0*47.25)/27 = 450us */
+        fpc_writew(0x0031, FPC_FIR_H);   /* Devider */
+
+        /* Interrupt count */
+        fpc_writew(0x4, FPC_RC_INTR_CNT_L); /* time_out << 4 | const_count */
+        fpc_writew(0x3a94, FPC_RC_INTR_CNT_H); /* time out count */
+
+        /* RC control */
+        rc_ctl = (RC_CTL_OPTION<<29) | (BITTIME_CNT<<8) | (PANNEL_SELECT<<2);
+        fpc_writew((rc_ctl<<16)>>16, FPC_RC_CTL_L); /* bittime_cnt & pannel_select ; 0x372c */
+        /* noise filter must be enabled, or else no interrupt */
+        fpc_writew(rc_ctl>>16, FPC_RC_CTL_H);   /* 00a, rc_en | rc_pol | noise_filter_en | bittime_cnt ; 0xe000 */
+
+#if 0
+        /* temparary not set */
+        fpc_writew(0x1, RC_TIME_INTERVAL_L); /* RC_TIME_INTERVAL */
+#endif
+        dummy = fpc_readw(FPC_RC_FIFO1_L);
+        PDEBUG("Throw out useless data: fifo1_cnt: %d, fifo2_cnt: %d , dummy: %d\n",
+                fpc_readw(FPC_RC_FIFO1_CNT_L), fpc_readw(FPC_RC_FIFO2_CNT_L), dummy);
+
+	/* KeyScan config  */
+        //fpc_writew(0x0001, FPC_KSCAN_CNTL_L);    /* enable keyscan */
+        fpc_writew(0 & 0xffff, FPC_KSCAN_CNTL_L);
+        fpc_writew((0 << 15) & 0xffff, FPC_LED_CNTL_H);
+
+        pinmux_update_rc_status();
+        pinmux_update_fpc_status();
+    }
+
+    fpc_writew(0xff, FPC_LED_CNTL_L);
+
+    goto out;
+
+err7:
+    input_free_device(rc_dev->dev);
+err6:
+    kfree(rc_dev);
+err5:
+    remove_proc_entry("rc_io", NULL);
+err4:
+    misc_deregister(&fpc_miscdev);
+err3:
+	iounmap((void*)cs_fpc_base);
+err2:
+    release_mem_region(CS_FPC_BASE, CS_FPC_SIZE);
+err1:
+    free_irq(CS_RC_IRQ, NULL);
+out:
+	return ret;
+
+}
+
+static void __exit cs_fpc_exit(void)
+{   
+   
+    input_free_device(rc_dev->dev);
+    kfree(rc_dev);
+    remove_proc_entry("rc_io", NULL);
+    misc_deregister(&fpc_miscdev);
+	iounmap((void*)cs_fpc_base);
+    release_mem_region(CS_FPC_BASE, CS_FPC_SIZE);
+    free_irq(CS_RC_IRQ, NULL);
+}
+
+module_init(cs_fpc_init);
+module_exit(cs_fpc_exit);
+
+EXPORT_SYMBOL(rc_system_code);
+
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/celestial/peripheral/cnc18xx_fpc.h linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/peripheral/cnc18xx_fpc.h
--- linux-linaro-3.4-2012.05-1_original/drivers/celestial/peripheral/cnc18xx_fpc.h	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/peripheral/cnc18xx_fpc.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,167 @@
+#ifndef _CS_FPC_H_
+#define _CS_FPC_H_
+
+#include <mach/hardware.h>
+
+#define FPC_MAGIC 'z'
+
+#define FPC_LED_EN	 	        _IOW(FPC_MAGIC, 0x06, int)
+#define FPC_LED_DISP	 	    _IOW(FPC_MAGIC, 0x08, int)
+#define FPC_RC_SET_SYSTEMCODE	_IOW(FPC_MAGIC, 0x09, int)
+#define FPC_LED_GET		        _IOR(FPC_MAGIC, 0x0a, int)
+#define FPC_KEYSCAN_EN          _IOW(FPC_MAGIC, 0x0b, int)
+#define FPC_KSCAN_GET		    _IOR(FPC_MAGIC, 0x0c, int)
+#define FPC_RC_SET_PROTOCAL     _IOR(FPC_MAGIC, 0x10, int)
+
+/* Adjust bit time count outside for nonstandard rc protocal */
+#define FPC_SET_BitTimeCnt	_IOR(FPC_MAGIC, 0x0d, int)
+#define FPC_GET_BitTimeCnt	_IOR(FPC_MAGIC, 0x0e, int)
+
+#define FPC_RC_EN      _IOW(FPC_MAGIC, 0x14, int)
+
+
+/* Register Map */
+#define FPC_INTS_L		         (0x000)    /*Interrupt Status Register*/
+#define FPC_INTS_H		         (0x002)
+#define FPC_INTM_L		         (0x004)    /*Interrupt Mask Register*/
+#define FPC_INTM_H		         (0x006)
+#define FPC_RC_CTL_L             (0x008)    /*FPC Control Register*/
+#define FPC_RC_CTL_H             (0x00a)
+#define FPC_RC_TIME_INTERVAL_L   (0x00c)    /*FPC Time Interval Register*/
+#define FPC_RC_TIME_INTERVAL_H   (0x00e)
+#define FPC_UHF_CTL_L            (0x010)    /*UHF control Register*/
+#define FPC_UHF_CTL_H            (0x012)
+#define FPC_UHF_TIME_INTERVAL_L  (0x014)    /*UHF Time Interval  Register*/
+#define FPC_UHF_TIME_INTERVAL_H	 (0x016)
+#define FPC_RC_INTR_CNT_L        (0x018)    /*FPC Interrupt counter Register*/
+#define FPC_RC_INTR_CNT_H        (0x01a)
+#define FPC_UHF_INTR_CNT_L       (0x01c)    /*UHF Interrupt counter Register*/
+#define FPC_UHF_INTR_CNT_H       (0x01e)
+#define FPC_RC_FIFO1_L           (0x020)    /*FPC FIFO1*/
+#define FPC_RC_FIFO1_H           (0x022)
+#define FPC_RC_FIFO1_CNT_L       (0x024)    /*FPC FIFO1 count*/
+#define FPC_RC_FIFO1_CNT_H       (0x026)
+#define FPC_RC_FIFO2_L           (0x028)    /*FPC FIFO2*/
+#define FPC_RC_FIFO2_H           (0x02a)
+#define FPC_RC_FIFO2_CNT_L       (0x02c)    /*FPC FIFO2 count*/
+#define FPC_RC_FIFO2_CNT_H       (0x02e)
+#define FPC_UHF_FIFO1_L          (0x030)    /*UHF FIFO1 */
+#define FPC_UHF_FIFO1_H          (0x032)
+#define FPC_UHF_FIFO1_CNT_L      (0x034)    /*UHF FIFO1 Count*/
+#define FPC_UHF_FIFO1_CNT_H      (0x036)
+#define FPC_UHF_FIFO2_L          (0x038)    /*UHF FIFO2 */
+#define FPC_UHF_FIFO2_H          (0x03a)
+#define FPC_UHF_FIFO2_CNT_L      (0x03c)    /*UHF FIFO2 Count*/
+#define FPC_UHF_FIFO2_CNT_H      (0x03e)
+#define FPC_FIR_L                (0x040)    /*FPC FIR Register*/
+#define FPC_FIR_H                (0x042)
+#define FPC_UHF_FIR_L            (0x044)    /*UHF FIR Register*/
+#define FPC_UHF_FIR_H            (0x046)
+#define FPC_LED_DATA_L           (0x200)    /*LED DATA Register*/
+#define FPC_LED_DATA_H           (0x202)
+#define FPC_LED_CNTL_L           (0x204)    /*LED Counter Register*/
+#define FPC_LED_CNTL_H           (0x206)    /*LED Counter Register*/
+#define FPC_KSCAN_DATA_L         (0x300)    /*KSCAN DATA Register*/
+#define FPC_KSCAN_DATA_H         (0x302)
+#define FPC_KSCAN_CNTL_L         (0x304)    /*KSCAN Counter Register*/
+#define FPC_KSCAN_CNTL_H         (0x306)
+#define FPC_KSCAN_ARB_CNTL_L     (0x308)    /*KSCAN Arbitrates Register*/
+#define FPC_KSCAN_ARB_CNTL_H     (0x30a)
+
+#define CS_FPC_BASE		        PA_FPC_BASE
+#define CS_FPC_SIZE             0x1000
+#define CS_RC_IRQ		        IRQ_PANEL_CTL
+
+#define FILTER_PRECISION 	(450)
+
+#define RC_CTL_OPTION 		( 7) 	/* rc_en | rc_pol | noise_filter_en */
+#define BITTIME_CNT 		(PCLK_MHZ)
+#define PANNEL_SELECT 		(11) 	/* GPIO input for remote controller */
+
+#define DRIVER_DESC		    "CS Remote Controller"
+
+/* Key number */
+#define CS_FPC_KNUM 		KEY_MAX
+
+/* Parse period */
+#define HEAD_PERIOD		0
+#define ADDR_PERIOD		1
+#define CMD_PERIOD		2
+
+#undef PDEBUG
+
+//#define CONFIG_FPC_DEBUG
+static int RC_DEBUG = 0;
+#ifdef CONFIG_FPC_DEBUG
+# ifdef __KERNEL__
+#  define PDEBUG(fmt, args...) printk( fmt, ## args)
+# else
+#  define PDEBUG(fmt, args...) printf(fmt, ## args)
+# endif
+#else
+# define PDEBUG(fmt, args...) \
+	if (RC_DEBUG) printk( fmt, ## args)
+#endif
+
+/* Infrared Remote Control Protocol type */
+typedef enum rc_protocal_ {
+	NEC, RC5, RC6_6A,
+#if 0
+	FPCMM, RECS80, FPCA, XSAT, JVC, NFPC17, SHARP, SIFPC, ITT,
+#endif
+	P_TOTAL
+} rc_protocal_t;
+
+typedef struct rc_record_ {
+	unsigned short addr;
+	unsigned short cmd;
+	unsigned short bit;
+	unsigned short rpt;
+
+	unsigned short decode_period;
+
+	unsigned short rc5_data;
+	unsigned short next_bit_is_zero;
+	unsigned short pre_T;      /* Only FPC5 use */
+
+    /* for rc6 mode 6a */
+    unsigned char mode;
+    unsigned char half_bit; // 0 no half bit left, 1 have half bit of ONE or ZERO, 2 have half bit of T0 or T1
+} rc_record_t;
+
+typedef struct cs_rc_ {
+	spinlock_t lock;
+	struct tasklet_struct tasklet;
+	struct input_dev *dev;
+
+	unsigned short keycode[CS_FPC_KNUM];
+	rc_record_t record;
+
+	/* To be set outside, used as condition restriction */
+	unsigned short addr;
+	unsigned short max_rpt;
+	unsigned short protocal;
+
+#define FIFO_LEN 80
+	unsigned short fifo1[FIFO_LEN];
+	unsigned short fifo2[FIFO_LEN];
+	short f1_idx;
+	short f2_idx;
+
+    /* for FPC6 mode 6A */
+    unsigned short last_report_cmd;
+    unsigned long last_report_jiffies;
+    unsigned repeat_ms;        /* can set by writing proc file */
+
+#ifdef CONFIG_FPC_DEBUG
+	unsigned short fc[32][2];	/* For debug only */
+	short fc_idx;
+#endif
+
+	int bit_err;
+} cs_rc_t;
+
+//extern int cnc_gpio_register_module_status(const char * module, unsigned int  orion_module_status); /* status: 0 disable, 1 enable */
+
+#endif
+
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/celestial/peripheral/cnc18xx_i2c.c linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/peripheral/cnc18xx_i2c.c
--- linux-linaro-3.4-2012.05-1_original/drivers/celestial/peripheral/cnc18xx_i2c.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/peripheral/cnc18xx_i2c.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,1064 @@
+//#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/miscdevice.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/rwsem.h>
+#include <linux/slab.h>
+#include <linux/seq_file.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <mach/hardware.h>
+#include "cnc18xx_i2c.h"
+
+typedef enum _I2C_ID_
+{
+	_i2c_0      =0,
+	_i2c_1      =1,
+}I2C_ID;
+extern int pinmux_enable_i2c(I2C_ID I2C);
+
+
+#define CFG_I2C_CLK  810000000/1000000
+
+#ifdef CONFIG_CNC18XX_I2C_EEPROM
+#define DEV_NUM 0
+#else
+#define DEV_NUM 1
+#endif
+
+#define I2C_SET	       _IOW('I', 0, unsigned long)
+#define I2C_GET        _IOR('I', 1, unsigned long)
+#define I2C_SETSPEED   _IOW('I', 2, unsigned long)
+#define I2C_GETSPEED   _IOR('I', 3, unsigned long)
+#define I2C_SETLOOPADDR   _IOW('I', 4, unsigned long)
+#define I2C_CLRLOOPADDR   _IOW('I', 5, unsigned long)
+#define I2C_GETLOOPINFO     _IOR('I', 6, unsigned long)
+#define I2C_SETCHIPADDRESS  _IOW('I', 7, unsigned long)
+#define I2C_GETCHIPADDRESS  _IOR('I', 8, unsigned long)
+#define I2C_SETADDRALEN     _IOW('I', 9, unsigned long)
+
+#define I2C_SPEED_100K 1
+#define I2C_SPEED_400K 2
+#define i2c_set_speed_100k(x)  x = (void *)(((unsigned long)1<<20) + (unsigned long)((unsigned long)(x) & 0xff0fffff))
+#define i2c_set_speed_400k(x)  x = (void *)(((unsigned long)1<<21) + (unsigned long)((unsigned long)(x) & 0xff0fffff))
+#define i2c_get_speed(x)  ((unsigned long)x >> 20) & 0xf
+
+#define i2c_set_loop_address(x) x = (void *)((1<< 24) + ((unsigned long)x & 0xf0ffffff))
+#define i2c_clr_loop_address(x) x = (void *)((unsigned long)x & 0xf0ffffff)
+#define i2c_get_loop_info(x) ((unsigned long)x>>24) & 0xf
+
+#define i2c_set_chip_address(x,chipaddress) x = (void *)(((unsigned long)x & 0xffffff00) | (chipaddress & 0xff))
+#define i2c_get_chip_address(x) (unsigned char) ((unsigned long)x & 0xff)
+
+#define i2c_get_sleeptime(x) ((unsigned long)x >> 8) & 0xff
+#define i2c_get_chipaddress(x) ((unsigned long)x) & 0xff;
+#define i2c_get_address_alen(x) (((unsigned long)x) >> 16) & 0xff;
+#define i2c_set_address_alen(x,alen) x = (void *)(((unsigned long)x & 0xfff0ffff) | (alen & 0xf)<<16)
+#define i2c_set_default_privatedata(x) x=(void *) (1 << 16)
+
+#define I2C_DEBUG_LEVEL0	(0)	/* Quiet   */
+#define I2C_DEBUG_LEVEL1	(1)	/* Audible */
+#define I2C_DEBUG_LEVEL2	(2)	/* Loud    */
+#define I2C_DEBUG_LEVEL3	(3)	/* Noisy   */
+
+#ifdef CONFIG_CELESTIAL_I2C_DEBUG
+#define DEBUG(n, args...)				\
+ 	do {						\
+		if (n <= CONFIG_I2C_DEBUG_VERBOSE)	\
+			printk(KERN_INFO args);		\
+	} while(0)
+#else /* CONFIG_I2C_DEBUG */
+#define DEBUG(n, args...) do { } while(0)
+#endif
+
+static void __iomem *cs_i2c_base;
+static void __iomem *cs_i2c2_base;
+static spinlock_t cs_i2c_lock;
+
+typedef unsigned char uchar;
+static uchar previous_chip;
+static unsigned int previous_speed_cnt;
+
+
+static unsigned int ss_ic_sclh_cnt;
+static unsigned int ss_ic_scl_cnt;
+static unsigned int fs_ic_sclh_cnt;
+static unsigned int fs_ic_scl_cnt;
+static unsigned int default_speed_cnt;
+
+#define i2c_writeb( v,a)    writeb(v, (cs_i2c_base + (a)))
+#define i2c_writew(v,a,n)    ((n==0)?writew(v, (cs_i2c_base + (a))):writew(v, (cs_i2c2_base + (a)))) 
+#define i2c_writel(v,a)    writel(v, (cs_i2c_base + (a)))
+
+#define i2c_readb(a)       readb((cs_i2c_base + (a)))
+
+#define i2c_readw(a,n)    ((n==0)?readw((cs_i2c_base + (a))):readw((cs_i2c2_base + (a))))
+
+		
+#define i2c_readl(a)       readl((cs_i2c_base + (a)))
+
+static int i2c_read(uchar chip,uint addr, unsigned int speed_cnt,int alen,
+	 uchar * buffer, int len,unsigned num)
+{
+    int i;
+	int cmd_cnt;
+	int data_cnt;
+    unsigned int time_cnt;
+	unsigned char *byte_addr = (unsigned char *) &addr;
+	unsigned char *p = buffer;
+
+    time_cnt=0;
+    while(i2c_readw(IC_STAT,num)&0x20)
+    {
+    	if(unlikely(time_cnt>=100000))          //Bus Err
+    	{
+    		i2c_writew(0x1,IC_RESET,num);
+    		i2c_writew(0x0,IC_RESET,num);
+    		i2c_writew(0x1,IC_ENABLE,num);
+    		i2c_writew(0x700,IC_DATA_CMD,num);     //write stop bit
+    		previous_chip = 0;
+    		DEBUG(I2C_DEBUG_LEVEL0,"Error:Timeout!\n");
+    		return 1;
+    	}
+    	time_cnt++;
+    }
+	if(speed_cnt!=previous_speed_cnt)
+		{
+			i2c_writew(0x0, IC_ENABLE,num);
+			while(!(i2c_readw(IC_STAT,num)& 0x1));							//wait disabled
+			if((speed_cnt==ss_ic_scl_cnt))									//Standard Speed
+				{
+					i2c_writew(ss_ic_sclh_cnt,IC_SCLH_CNT,num);
+					i2c_writew(ss_ic_scl_cnt-ss_ic_sclh_cnt,IC_SCLL_CNT,num);
+					previous_speed_cnt = ss_ic_scl_cnt;
+				}
+			else if(speed_cnt==fs_ic_scl_cnt)								//Fast Speed
+				{
+					
+					i2c_writew(fs_ic_sclh_cnt,IC_SCLH_CNT,num);
+					i2c_writew(fs_ic_scl_cnt-fs_ic_sclh_cnt,IC_SCLL_CNT,num);
+					previous_speed_cnt =fs_ic_scl_cnt;
+					
+				}
+		}
+	i2c_writew(0x1, IC_ENABLE,num);
+	
+	if (alen > 0){
+		i2c_writew(((chip<<1)&0xff)|0x100,IC_DATA_CMD,num);
+	}
+	for (i = alen - 1; i >= 0; i--)
+	{
+		i2c_writew(0x200|(byte_addr[i]& 0xff),IC_DATA_CMD,num);
+	}
+	i2c_writew(0x101|((chip<<1)&0xff),IC_DATA_CMD,num);
+	data_cnt = 0;
+	cmd_cnt = 0;
+	time_cnt=0;
+	while (data_cnt < len) {
+		/*if(unlikely(time_cnt>=100000))          //Bus Err
+    	{
+    		i2c_writew(0x1,IC_RESET);
+    		i2c_writew(0x0,IC_RESET);
+    		i2c_writew(0x1,IC_ENABLE);
+    		i2c_writew(0x700,IC_DATA_CMD);     //write stop bit
+    		previous_chip = 0;
+    		DEBUG(I2C_DEBUG_LEVEL0,"Error:Timeout!\n");
+    		return 1;
+    	}*/
+    	time_cnt++;
+    	
+		while ((cmd_cnt < len) && (i2c_readw(IC_STAT,num) & 0x2)) {
+			
+			if(cmd_cnt+1==len)
+				{
+				i2c_writew(0x600,IC_DATA_CMD,num);		//write stop bit
+			  }
+			else
+				{
+				i2c_writew(0x400, IC_DATA_CMD,num);
+			  }
+			cmd_cnt++;
+		}
+
+		if (i2c_readw(IC_STAT,num) & 0x8) {
+			*p = i2c_readw(IC_DATA_CMD,num);
+			p++;
+			data_cnt++;
+		}
+
+		if (unlikely((i=i2c_readw(IC_RAW_INTR_STAT,num)) & 0xe0)) {
+			
+			DEBUG(I2C_DEBUG_LEVEL0,"Chipaddress=0x%x, subaddr=0x%x, IC_RAW_INTR_STAT=0x%x\n",
+			     chip, addr, i);
+			i2c_writew(0x03,IC_FIFO_CLR,num);			//clear tx/rx fifo			
+			if(i&0x40)								//Arbitration Lost
+				{
+					i2c_writew(0x40,IC_INTR_CLR,num);
+					DEBUG(I2C_DEBUG_LEVEL0,"Error:Arbitration lost!\n");
+				}
+			if(i&0x80)
+				{
+					i2c_writew(0x80,IC_INTR_CLR,num);
+					DEBUG(I2C_DEBUG_LEVEL0,"Error:Timeout!\n");
+				}
+			if(i&0x20)								//No ACK
+				{
+					i2c_writew(0x20,IC_INTR_CLR,num);
+					i2c_writew(0x700,IC_DATA_CMD,num);
+					DEBUG(I2C_DEBUG_LEVEL0,"Error:No Slave sends ack!\n");
+				}
+			previous_chip = 0;
+			return -1;
+		}
+	}
+	time_cnt=0;
+	while (!(i2c_readw(IC_STAT,num)&0x04))
+	{
+		if(unlikely(time_cnt>=100000))          //Bus Err
+    	{
+    		i2c_writew(0x1,IC_RESET,num);
+    		i2c_writew(0x0,IC_RESET,num);
+    		i2c_writew(0x1,IC_ENABLE,num);
+    		i2c_writew(0x700,IC_DATA_CMD,num);     //write stop bit
+    		previous_chip = 0;
+    		DEBUG(I2C_DEBUG_LEVEL0,"Error:Timeout!\n");
+    		return 1;
+    	}
+    	time_cnt++;
+    	
+		if (unlikely((i=i2c_readw(IC_RAW_INTR_STAT,num)) & 0xe0)) {
+			
+			DEBUG(I2C_DEBUG_LEVEL0,"Chipaddress=0x%x, subaddr=0x%x, IC_RAW_INTR_STAT=0x%x\n",
+			     chip, addr, i);
+			i2c_writew(0x03,IC_FIFO_CLR,num);			//clear tx/rx fifo			
+			if(i&0x40)								//Arbitration Lost
+				{
+					i2c_writew(0x40,IC_INTR_CLR,num);
+					DEBUG(I2C_DEBUG_LEVEL0,"Error:Arbitration lost!\n");
+				}
+			if(i&0x80)
+				{
+					i2c_writew(0x80,IC_INTR_CLR,num);
+					DEBUG(I2C_DEBUG_LEVEL0,"Error:Timeout!\n");
+				}
+			if(i&0x20)								//No ACK
+				{
+					i2c_writew(0x20,IC_INTR_CLR,num);
+					i2c_writew(0x700,IC_DATA_CMD,num);
+					DEBUG(I2C_DEBUG_LEVEL0,"Error:No Slave sends ack!\n");
+				}
+			previous_chip = 0;
+			return -1;
+			}
+		}             //wait all data send
+		
+	time_cnt=0;
+	while (i2c_readw(IC_STAT,num) & 0x20)
+	{
+		if (unlikely((i=i2c_readw(IC_RAW_INTR_STAT,num)) & 0xe0)) {
+			
+			DEBUG(I2C_DEBUG_LEVEL0,"Chipaddress=0x%x, subaddr=0x%x, IC_RAW_INTR_STAT=0x%x\n",
+			     chip, addr, i);
+			i2c_writew(0x03,IC_FIFO_CLR,num);			//clear tx/rx fifo			
+			if(i&0x40)								//Arbitration Lost
+				{
+					i2c_writew(0x40,IC_INTR_CLR,num);
+					DEBUG(I2C_DEBUG_LEVEL0,"Error:Arbitration lost!\n");
+				}
+			if(i&0x80)
+				{
+					i2c_writew(0x80,IC_INTR_CLR,num);
+					DEBUG(I2C_DEBUG_LEVEL0,"Error:Timeout!\n");
+				}
+			if(i&0x20)								//No ACK
+				{
+					i2c_writew(0x20,IC_INTR_CLR,num);
+					i2c_writew(0x700,IC_DATA_CMD,num);
+					DEBUG(I2C_DEBUG_LEVEL0,"Error:No Slave sends ack!\n");
+				}
+			previous_chip = 0;
+			return -1;
+		}
+		
+		if(unlikely(time_cnt>=100000))          //Bus Err
+    	{
+    		i2c_writew(0x1,IC_RESET,num);
+    		i2c_writew(0x0,IC_RESET,num);
+    		i2c_writew(0x1,IC_ENABLE,num);
+    		i2c_writew(0x700,IC_DATA_CMD,num);     //write stop bit
+    		previous_chip = 0;
+    		DEBUG(I2C_DEBUG_LEVEL0,"Error:Timeout!\n");
+    		return 1;
+    	}
+    	time_cnt++;
+		}
+						//wait for stop signal
+	return 0;
+}
+
+static int
+i2c_write(uchar chip,uint addr, unsigned int speed_cnt, int alen,
+	  uchar * buffer, int len,unsigned num)
+{
+	int i;
+	int data_cnt;
+    unsigned int  time_cnt;
+	unsigned char *byte_addr = (unsigned char *) &addr;
+	unsigned char *p = buffer;
+    
+    time_cnt=0;
+    while(i2c_readw(IC_STAT,num)&0x20)
+    {
+    	if(unlikely(time_cnt>=100000))          //Bus Err
+    	{
+    		i2c_writew(0x1,IC_RESET,num);
+    		i2c_writew(0x0,IC_RESET,num);
+    		i2c_writew(0x1,IC_ENABLE,num);
+    		i2c_writew(0x700,IC_DATA_CMD,num);     //write stop bit
+    		previous_chip = 0;
+    		DEBUG(I2C_DEBUG_LEVEL0,"Error:Timeout!\n");
+    		return 1;
+    	}
+    	time_cnt++;
+    }
+
+if(speed_cnt!=previous_speed_cnt)
+		{
+			i2c_writew(0x0, IC_ENABLE,num);
+			while(!(i2c_readw(IC_STAT,num)& 0x1));							//wait disabled
+			if((speed_cnt==ss_ic_scl_cnt))									//Standard Speed
+				{
+					i2c_writew(ss_ic_sclh_cnt,IC_SCLH_CNT,num);
+					i2c_writew(ss_ic_scl_cnt-ss_ic_sclh_cnt,IC_SCLL_CNT,num);
+					previous_speed_cnt = ss_ic_scl_cnt;
+				}
+			else if(speed_cnt==fs_ic_scl_cnt)								//Fast Speed
+				{
+					
+					i2c_writew(fs_ic_sclh_cnt,IC_SCLH_CNT,num);
+					i2c_writew(fs_ic_scl_cnt-fs_ic_sclh_cnt,IC_SCLL_CNT,num);
+					previous_speed_cnt =fs_ic_scl_cnt;
+					
+				}
+		}
+		
+  i2c_writew(0x1, IC_ENABLE,num);
+	i2c_writew(((chip<<1)&0xff)|0x100,IC_DATA_CMD,num);
+	for (i = alen - 1; i >= 0; i--)
+	{
+		i2c_writew(0x200|byte_addr[i],IC_DATA_CMD,num);
+	}
+	
+	data_cnt = 0;
+
+	time_cnt=0;
+	while (data_cnt < len) {
+		
+		/*if(unlikely(time_cnt>=6000000))          //Bus Err
+    	{
+    		i2c_writew(0x1,IC_RESET);
+    		i2c_writew(0x0,IC_RESET);
+    		i2c_writew(0x1,IC_ENABLE);
+    		i2c_writew(0x700,IC_DATA_CMD);     //write stop bit
+    		previous_chip = 0;
+    		DEBUG(I2C_DEBUG_LEVEL0,"Error:Timeout!\n");
+    		return 1;
+    	}*/
+    	time_cnt++;
+    	
+    	
+		if (i2c_readw(IC_STAT,num) & 0x2) {
+			if(data_cnt!=len-1)
+				{
+				i2c_writew(0x200|(*p), IC_DATA_CMD,num);
+				}
+			else
+				{
+				i2c_writew(0x300|(*p),IC_DATA_CMD,num);				//Stop
+				
+			}
+			p++;
+			data_cnt++;
+		}
+
+		if (unlikely((i=i2c_readw(IC_RAW_INTR_STAT,num)) & 0xe0)) {
+			
+			DEBUG(I2C_DEBUG_LEVEL0,"Chipaddress=0x%x, subaddr=0x%x, IC_RAW_INTR_STAT=0x%x\n",
+			     chip, addr, i);
+			
+			i2c_writew(0x03,IC_FIFO_CLR,num);				//clear tx/rx fifo			
+			if(i&0x40)									//Arbitration Lost
+				{
+					i2c_writew(0x40,IC_INTR_CLR,num);
+					DEBUG(I2C_DEBUG_LEVEL0,"Error:Arbitration lost!\n");
+				}
+			if(i&0x80)
+				{
+					i2c_writew(0x80,IC_INTR_CLR,num);
+					DEBUG(I2C_DEBUG_LEVEL0,"Error:Timeout!\n");
+				}
+			if(i&0x20)									//No ACK
+				{
+					i2c_writew(0x20,IC_INTR_CLR,num);
+					i2c_writew(0x700,IC_DATA_CMD,num);		//Stop
+					DEBUG(I2C_DEBUG_LEVEL0,"Error:No Slave sends ack!\n");
+				}
+			previous_chip = 0;
+			return -1;
+		}
+	}
+
+	time_cnt=0;
+	while (!(i2c_readw(IC_STAT,num)&0x04))
+	{
+		if(unlikely(time_cnt>=100000))          //Bus Err
+    	{
+    		i2c_writew(0x1,IC_RESET,num);
+    		i2c_writew(0x0,IC_RESET,num);
+    		i2c_writew(0x1,IC_ENABLE,num);
+    		i2c_writew(0x700,IC_DATA_CMD,num);     //write stop bit
+    		previous_chip = 0;
+    		DEBUG(I2C_DEBUG_LEVEL0,"Error:Timeout!\n");
+    		return 1;
+    	}
+    	time_cnt++;
+		
+		  if (unlikely((i=i2c_readw(IC_RAW_INTR_STAT,num)) & 0xe0)) {
+			
+			DEBUG(I2C_DEBUG_LEVEL0,"Chipaddress=0x%x, subaddr=0x%x, IC_RAW_INTR_STAT=0x%x\n",
+			     chip, addr, i);
+			i2c_writew(0x03,IC_FIFO_CLR,num);				//clear tx/rx fifo			
+			if(i&0x40)									//Arbitration Lost
+				{
+					i2c_writew(0x40,IC_INTR_CLR,num);
+					DEBUG(I2C_DEBUG_LEVEL0,"Error:Arbitration lost!\n");
+				}
+			if(i&0x80)
+				{
+					i2c_writew(0x80,IC_INTR_CLR,num);
+					DEBUG(I2C_DEBUG_LEVEL0,"Error:Timeout!\n");
+				}
+			if(i&0x20)									//No ACK
+				{
+					i2c_writew(0x20,IC_INTR_CLR,num);
+					i2c_writew(0x700,IC_DATA_CMD,num);		//Stop
+					DEBUG(I2C_DEBUG_LEVEL0,"Error:No Slave sends ack!\n");
+				}
+			previous_chip = 0;
+			return -1;
+		}
+		}             //wait all data send
+	time_cnt=0;
+	while (i2c_readw(IC_STAT,num) & 0x20)
+	{
+			if(unlikely(time_cnt>=100000))          //Bus Err
+    		{
+    			i2c_writew(0x1,IC_RESET,num);
+    			i2c_writew(0x0,IC_RESET,num);
+    			i2c_writew(0x1,IC_ENABLE,num);
+    			i2c_writew(0x700,IC_DATA_CMD,num);     //write stop bit
+    			previous_chip = 0;
+    			DEBUG(I2C_DEBUG_LEVEL0,"Error:Timeout!\n");
+    			return 1;
+    		}
+    		time_cnt++;
+    	
+			if (unlikely((i=i2c_readw(IC_RAW_INTR_STAT,num)) & 0xe0)) {
+			
+			DEBUG(I2C_DEBUG_LEVEL0,"Chipaddress=0x%x, subaddr=0x%x, IC_RAW_INTR_STAT=0x%x\n",
+			     chip, addr, i);
+				
+			i2c_writew(0x03,IC_FIFO_CLR,num);				//clear tx/rx fifo			
+			if(i&0x40)									//Arbitration Lost
+				{
+					i2c_writew(0x40,IC_INTR_CLR,num);
+					DEBUG(I2C_DEBUG_LEVEL0,"Error:Arbitration lost!\n");
+				}
+			if(i&0x80)
+				{
+					i2c_writew(0x80,IC_INTR_CLR,num);
+					DEBUG(I2C_DEBUG_LEVEL0,"Error:Timeout!\n");
+				}
+			if(i&0x20)									//No ACK
+				{
+					i2c_writew(0x20,IC_INTR_CLR,num);
+					i2c_writew(0x700,IC_DATA_CMD,num);		//Stop
+					DEBUG(I2C_DEBUG_LEVEL0,"Error:No Slave sends ack!\n");
+				}
+			previous_chip = 0;
+			return -1;
+		}
+		
+		}
+	return 0;
+}
+
+#ifdef CONFIG_CNC18XX_I2C_EEPROM
+static int
+cs_i2c_eeprom_open(struct inode *inode, struct file *file)
+{
+	file->private_data =
+	    (void *) (((CONFIG_CNC18XX_I2C_EEPROM_PAGE_SIZE & 0xfff) << 20) |
+		      ((CONFIG_CNC18XX_I2C_EEPROM_SUBADDR_LEN & 0xf) << 16) |
+		      ((CONFIG_CNC18XX_I2C_EEPROM_SLEEP_TIME & 0xff) << 8) |
+		      ((CONFIG_CNC18XX_I2C_EEPROM_CHIP_1_ADDR & 0xff) << 0)
+	    );
+	return 0;
+}
+#endif
+
+#ifdef CONFIG_CNC18XX_I2C_MULTI_EEPROMS
+static int
+cs_i2c_multi_eeprom_open(struct inode *inode, struct file *file)
+{
+	file->private_data =
+	    (void *) (((CONFIG_CNC18XX_I2C_EEPROM_2_PAGE_SIZE & 0xfff) << 20) |
+		      ((CONFIG_CNC18XX_I2C_EEPROM_2_SUBADDR_LEN & 0xf) << 16) |
+		      ((CONFIG_CNC18XX_I2C_EEPROM_2_SLEEP_TIME & 0xff) << 8) |
+		      ((CONFIG_CNC18XX_I2C_EEPROM_CHIP_2_ADDR & 0xff) << 0)
+	    );
+	return 0;
+}
+#endif
+
+static int
+cs_i2c_open(struct inode *inode, struct file *file)
+{
+		unsigned m = 0;		
+		i2c_writew(0x0, IC_ENABLE,m);
+#ifdef CONFIG_CNC18XX_I2C_FASTSPEED
+		i2c_writew(fs_ic_sclh_cnt, IC_SCLH_CNT,m);
+		i2c_writew(fs_ic_scl_cnt - fs_ic_sclh_cnt, IC_SCLL_CNT,m);
+		previous_speed_cnt = fs_ic_scl_cnt;
+		default_speed_cnt = fs_ic_scl_cnt;
+		printk(KERN_INFO "CNC I2C default 400KHZ\n");
+#else
+		i2c_writew(ss_ic_sclh_cnt, IC_SCLH_CNT,m);
+		i2c_writew(ss_ic_scl_cnt - ss_ic_sclh_cnt, IC_SCLL_CNT,m);
+		previous_speed_cnt = ss_ic_scl_cnt;
+		default_speed_cnt = ss_ic_scl_cnt;
+
+		printk(KERN_INFO "CNC I2C default 100KHZ\n");
+#endif
+	i2c_set_default_privatedata(file->private_data);
+
+	if (default_speed_cnt == fs_ic_scl_cnt)
+		i2c_set_speed_400k(file->private_data);
+	else
+		i2c_set_speed_100k(file->private_data);
+
+	return 0;
+}
+#ifdef CONFIG_CNC18XX_I2C_DEV2
+static int
+cs_i2c2_open(struct inode *inode, struct file *file)
+{
+		unsigned m = 1;
+		i2c_writew(0x0, IC_ENABLE,m);
+#ifdef CONFIG_CNC18XX_I2C_FASTSPEED
+		i2c_writew(fs_ic_sclh_cnt, IC_SCLH_CNT,m);
+		i2c_writew(fs_ic_scl_cnt - fs_ic_sclh_cnt, IC_SCLL_CNT,m);
+		previous_speed_cnt = fs_ic_scl_cnt;
+		default_speed_cnt = fs_ic_scl_cnt;
+		printk(KERN_INFO "CNC I2C2 initial: default 400KHZ\n");
+#else
+		i2c_writew(ss_ic_sclh_cnt, IC_SCLH_CNT,m);
+		i2c_writew(ss_ic_scl_cnt - ss_ic_sclh_cnt, IC_SCLL_CNT,m);
+		previous_speed_cnt = ss_ic_scl_cnt;
+		default_speed_cnt = ss_ic_scl_cnt;
+
+		printk(KERN_INFO "CNC I2C2 initial:default 100KHZ\n");
+#endif
+	i2c_set_default_privatedata(file->private_data);
+	if (default_speed_cnt == fs_ic_scl_cnt)
+		i2c_set_speed_400k(file->private_data);
+	else
+		i2c_set_speed_100k(file->private_data);
+
+	return 0;
+}
+#endif
+
+
+
+static ssize_t
+cs_i2c_read(struct file *file, char __user * buffer, size_t len,
+	       loff_t * offset)
+{
+	unsigned long flags;
+	unsigned int ret;
+	uchar chip;
+	int alen;
+	int rest;
+	unsigned int burst_len;
+	char *i2c_buffer;
+	char __user *user_ptr;
+	unsigned int speedcnt;
+	unsigned char loop_info;
+	unsigned m;
+	chip = ((unsigned long) file->private_data) & 0xff;
+	alen = (((unsigned long) file->private_data) >> 16) & 0xf;
+	loop_info = (unsigned char) i2c_get_loop_info(file->private_data);
+
+	if (strncmp("cs_i2c1", file->f_dentry->d_iname, 7) == 0)
+		m = 0;
+	else if(strncmp("cs_i2c2", file->f_dentry->d_iname, 7) == 0)
+		m = 1;
+	else{
+			printk("Baffling Error !\n");
+			return -1;	
+		}
+		
+	
+	
+	switch (i2c_get_speed(file->private_data)) {
+	case I2C_SPEED_100K:
+		speedcnt = ss_ic_scl_cnt;
+		break;
+	case I2C_SPEED_400K:
+		speedcnt = fs_ic_scl_cnt;
+		break;
+	default:
+		speedcnt = default_speed_cnt;
+		break;
+	}
+
+	if (loop_info)
+		burst_len = 1;
+	//else if (len > 256)
+	//	burst_len = 256;
+	else
+		burst_len = len;
+
+	i2c_buffer = (char *) kmalloc(burst_len, GFP_KERNEL);
+	user_ptr = buffer;
+	rest = len;
+	DEBUG(I2C_DEBUG_LEVEL0, "burst_len =%d, len=%d,chip=%d,speedcnt=%d, alen=%d,offset=%d\n", burst_len, len,chip,speedcnt,alen,(int)*offset);
+
+	while (rest > 0) {
+
+		spin_lock_irqsave(&cs_i2c_lock, flags);
+		ret =i2c_read(chip,*offset, speedcnt, alen, i2c_buffer, burst_len,m);
+		spin_unlock_irqrestore(&cs_i2c_lock, flags);
+
+		if (unlikely(ret)) {
+			kfree(i2c_buffer);
+			msleep(2);
+			return -EIO;
+		}
+		DEBUG(I2C_DEBUG_LEVEL0, "burst_len =%d, len=%d,speedcnt=%d, alen=%d, chip=%d, offset=%d\n", burst_len, len,speedcnt,alen,chip,(int)*offset);
+
+		if (unlikely(copy_to_user(user_ptr, i2c_buffer, burst_len))) {
+			kfree(i2c_buffer);
+			return -EFAULT;
+		}
+		*offset += burst_len;
+		user_ptr += burst_len;
+		rest -= burst_len;
+		if (rest < burst_len){
+			burst_len = rest;
+		}
+		
+	}
+
+	kfree(i2c_buffer);
+	return len;
+}
+
+
+static ssize_t
+cs_i2c_write(struct file *file, const char __user * buffer, size_t len,
+		loff_t * offset)
+{
+	unsigned long flags;
+	unsigned int ret;
+	uchar chip;
+	int alen;
+	int sleep_time;
+	int rest;
+	unsigned int burst_len;
+	char *i2c_buffer;
+	char *user_ptr;
+	unsigned int speedcnt;
+	unsigned char loop_info;
+	unsigned m;
+
+	chip = ((unsigned long) file->private_data) & 0xff;
+	sleep_time = (((unsigned long) file->private_data) >> 8) & 0xff;
+	alen = (((unsigned long) file->private_data) >> 16) & 0xf;
+	loop_info = (unsigned char) i2c_get_loop_info(file->private_data);
+
+	if (strncmp("cs_i2c1", file->f_dentry->d_iname, 7) == 0)
+		m = 0;
+	else if(strncmp("cs_i2c2", file->f_dentry->d_iname, 7) == 0)
+		m = 1;
+	else{
+		printk("Baffling Error !\n");
+		return -1;	
+		}
+	switch (i2c_get_speed(file->private_data)) {
+	case I2C_SPEED_100K:
+		speedcnt = ss_ic_scl_cnt;
+		break;
+	case I2C_SPEED_400K:
+		speedcnt = fs_ic_scl_cnt;
+		break;
+	default:
+		speedcnt = default_speed_cnt;
+		break;
+	}
+
+	if (loop_info)
+		burst_len = 1;
+	//else if (len > 256)
+		//burst_len = 256;
+	else
+		burst_len = len;
+	i2c_buffer = (char *) kmalloc(burst_len, GFP_KERNEL);
+	user_ptr = (char *) buffer;
+	rest = len;
+
+	DEBUG(I2C_DEBUG_LEVEL3, "burst_len =%d, len=%d,speedcnt=%d, alen=%d, chip=%d, offset=%d, loop_info=%d\n", burst_len, len,speedcnt,alen,chip,(int)*offset,loop_info);
+	while (rest > 0) {
+
+		if (unlikely(copy_from_user(i2c_buffer, user_ptr, burst_len))) {
+			kfree(i2c_buffer);
+			return -EFAULT;
+		}
+		DEBUG(I2C_DEBUG_LEVEL3, "i2c_buffer=%d\n",(*i2c_buffer) & 0xff);
+	       DEBUG(I2C_DEBUG_LEVEL3, "burst_len =%d, len=%d,speedcnt=%d, alen=%d, chip=%d, offset=%d, loop_info=%d\n", burst_len, len,speedcnt,alen,chip,(int)*offset,loop_info);
+		spin_lock_irqsave(&cs_i2c_lock, flags);
+		ret = i2c_write(chip, *offset, speedcnt, alen, i2c_buffer,burst_len,m);
+		spin_unlock_irqrestore(&cs_i2c_lock, flags);
+
+		if (unlikely(ret)) {
+			kfree(i2c_buffer);
+			msleep(2);
+			return -EIO;
+		}
+		*offset += burst_len;
+		user_ptr += burst_len;
+		rest -= burst_len;
+
+		if (rest < burst_len)
+			burst_len = rest;
+
+		if (sleep_time > 0)
+			msleep(sleep_time);
+
+	}
+
+	kfree(i2c_buffer);
+	return len;
+}
+
+
+#ifdef CONFIG_CNC18XX_I2C_EEPROM
+static ssize_t
+cs_i2c_eeprom_write(struct file *file, const char __user * buffer,
+		       size_t len, loff_t * offset)
+{
+	unsigned long flags;
+	unsigned int ret;
+	uchar chip;
+	int alen;
+	int sleep_time;
+	int page_size;
+	int rest;
+	int burst_len;
+	char *i2c_buffer;
+	char *user_ptr;
+	
+	chip = ((unsigned long) file->private_data) & 0xff;
+	sleep_time = (((unsigned long) file->private_data) >> 8) & 0xff;
+	alen = (((unsigned long) file->private_data) >> 16) & 0xf;
+	page_size = (((unsigned long) file->private_data) >> 20) & 0xfff;
+	page_size = page_size ? page_size : 256;
+
+	i2c_buffer = (char *) kmalloc(page_size, GFP_KERNEL);
+	user_ptr = (char *) buffer;
+	rest = len;
+
+	while (rest > 0) {
+		if (!sleep_time || !(*offset & (page_size - 1))) {
+			burst_len = rest > page_size ? page_size : rest;
+		} else {
+			/* EEPROM page write */
+			burst_len = page_size - (*offset & (page_size - 1));
+			burst_len = burst_len > rest ? rest : burst_len;
+		}
+
+		if (copy_from_user(i2c_buffer, user_ptr, burst_len)) {
+				kfree(i2c_buffer);
+			return -EFAULT;
+		}
+		spin_lock_irqsave(&cs_i2c_lock, flags);
+		ret =
+			i2c_write(chip, *offset, default_speed_cnt, alen, i2c_buffer, burst_len,DEV_NUM);
+		spin_unlock_irqrestore(&cs_i2c_lock, flags);
+
+		if (ret) {
+			kfree(i2c_buffer);
+			return -EIO;
+		}
+
+		user_ptr += burst_len;
+		*offset += burst_len;
+		rest -= burst_len;
+		if (sleep_time > 0)
+			msleep(sleep_time);
+
+	}
+
+	kfree(i2c_buffer);
+	return len;
+}
+
+static ssize_t
+cs_i2c_eeprom_read(struct file *file, char __user * buffer, size_t len,
+		      loff_t * offset)
+{
+	unsigned long flags;
+	unsigned int ret;
+	uchar chip;
+	int alen;
+	int page_size;
+	int rest;
+	int burst_len;
+	char *i2c_buffer;
+	char *user_ptr;
+	
+	chip = ((unsigned long) file->private_data) & 0xff;
+	alen = (((unsigned long) file->private_data) >> 16) & 0xf;
+	page_size = (((unsigned long) file->private_data) >> 20) & 0xfff;
+	page_size = page_size ? page_size : 256;
+
+	i2c_buffer = (char *) kmalloc(page_size, GFP_KERNEL);
+	user_ptr = buffer;
+	rest = len;
+
+	while (rest > 0) {
+		burst_len = rest > page_size ? page_size : rest;
+
+		spin_lock_irqsave(&cs_i2c_lock, flags);
+		ret = i2c_read(chip, *offset, default_speed_cnt, alen, i2c_buffer,burst_len,DEV_NUM);
+		spin_unlock_irqrestore(&cs_i2c_lock, flags);
+
+		if (ret) {
+			kfree(i2c_buffer);
+			return -EIO;
+		}
+
+		if (copy_to_user(user_ptr, i2c_buffer, burst_len)) {
+			kfree(i2c_buffer);
+			return -EFAULT;
+		}
+
+		user_ptr += burst_len;
+		*offset += burst_len;
+		rest -= burst_len;
+	}
+
+	kfree(i2c_buffer);
+	return len;
+}
+#endif
+
+# if 0
+static loff_t
+cs_i2c_lseek(struct file *file, loff_t offset, int orig)
+{
+	loff_t ret;
+
+	down_read(&file->f_dentry->d_inode->i_alloc_sem);
+	switch (orig) {
+	case 0: /* SEEK_SET*/
+		file->f_pos = offset;
+		ret = file->f_pos;
+		break;
+	case 1: /* SEEK_CUR*/
+		file->f_pos += offset;
+		ret = file->f_pos;
+		break;
+	default:
+		ret = -EINVAL;
+	}
+	up_read(&file->f_dentry->d_inode->i_alloc_sem);
+	return ret;
+}
+#endif
+
+static long
+cs_i2c_ioctl(struct file *file,
+		unsigned int cmd, unsigned long arg)
+{
+	char speed;
+	switch (cmd) {
+	case I2C_SET:
+		file->private_data = (void *) arg;
+		return 0;
+	case I2C_GET:
+		return (int) file->private_data;
+
+	case I2C_SETCHIPADDRESS:
+		i2c_set_chip_address(file->private_data, arg);
+		return 0;
+	case I2C_GETCHIPADDRESS:
+		return (int) i2c_get_chip_address(file->private_data);
+	case I2C_SETSPEED:
+		if (arg == I2C_SPEED_100K)
+			i2c_set_speed_100k(file->private_data);
+		else if (arg == I2C_SPEED_400K)
+			i2c_set_speed_400k(file->private_data);
+		else
+			return -EINVAL;
+	case I2C_GETSPEED:
+		speed = i2c_get_speed(file->private_data);
+		if (speed == I2C_SPEED_100K || speed == I2C_SPEED_400K)
+			return (int) speed;
+		else
+			return 0;
+	case I2C_SETLOOPADDR:
+		i2c_set_loop_address(file->private_data);
+		return 0;
+	case I2C_CLRLOOPADDR:
+		i2c_clr_loop_address(file->private_data);
+		return 0;
+	case I2C_GETLOOPINFO:
+		return i2c_get_loop_info(file->private_data);
+
+	case I2C_SETADDRALEN:
+		if (arg >= 0) {
+			i2c_set_address_alen(file->private_data, arg);
+			return 0;
+		} else
+			return -EINVAL;
+	default:
+		return -EINVAL;
+	}
+}
+
+static struct file_operations cs_i2c_fops = {
+	.owner = THIS_MODULE,
+	.read = cs_i2c_read,
+	.write = cs_i2c_write,
+	.llseek = seq_lseek,
+	.unlocked_ioctl = cs_i2c_ioctl,
+	.open = cs_i2c_open,
+};
+
+static struct miscdevice cs_i2c_miscdev = {
+	MISC_DYNAMIC_MINOR,
+	"cs_i2c1",
+	&cs_i2c_fops
+};
+
+#ifdef CONFIG_CNC18XX_I2C_EEPROM
+static struct file_operations cs_i2c_eeprom_fops = {
+	.owner = THIS_MODULE,
+	.open = cs_i2c_eeprom_open,
+	.read = cs_i2c_eeprom_read,
+	.write = cs_i2c_eeprom_write,
+	.llseek = seq_lseek,
+};
+
+static struct miscdevice cs_i2c_eeprom_miscdev = {
+	MISC_DYNAMIC_MINOR,
+	"eeprom",
+	&cs_i2c_eeprom_fops
+};
+#endif
+
+#ifdef CONFIG_CNC18XX_I2C_MULTI_EEPROMS
+static struct file_operations cs_i2c_multi_eeprom_fops = {
+	.owner = THIS_MODULE,
+	.open = cs_i2c_multi_eeprom_open,
+	.read = cs_i2c_eeprom_read,
+	.write = cs_i2c_eeprom_write,
+	.llseek = seq_lseek,
+};
+
+static struct miscdevice cs_i2c_multi_eeprom_miscdev = {
+	MISC_DYNAMIC_MINOR,
+	"eeprom2",
+	&cs_i2c_multi_eeprom_fops
+};
+#endif
+
+#ifdef CONFIG_CNC18XX_I2C_DEV2
+static struct file_operations cs_i2c_dev2_fops = {
+	.owner = THIS_MODULE,
+	.read = cs_i2c_read,
+	.write = cs_i2c_write,
+	.llseek = seq_lseek,
+	.unlocked_ioctl = cs_i2c_ioctl,
+	.open = cs_i2c2_open,
+};
+
+static struct miscdevice cs_i2c_dev2_miscdev = {
+	MISC_DYNAMIC_MINOR,
+	"cs_i2c2",
+	&cs_i2c_dev2_fops
+};
+#endif
+
+int __init
+cs_i2c_init(void)
+{
+	if (misc_register(&cs_i2c_miscdev))
+		return -ENODEV;
+
+#ifdef CONFIG_CNC18XX_I2C_EEPROM
+	if (misc_register(&cs_i2c_eeprom_miscdev))
+		return -ENODEV;
+#endif
+#ifdef CONFIG_CNC18XX_I2C_DEV2
+	if (misc_register(&cs_i2c_dev2_miscdev))
+		return -ENODEV;
+#endif
+
+#ifdef CONFIG_CNC18XX_I2C_MULTI_EEPROMS
+	if (misc_register(&cs_i2c_multi_eeprom_miscdev))
+		return -ENODEV;
+#endif
+
+
+	cs_i2c_base =(void *) VA_I2C_BASE;   
+
+#ifdef CONFIG_CNC18XX_I2C_DEV2
+	pinmux_enable_i2c(1);
+	cs_i2c2_base =(void *) VA_I2C2_BASE;  
+#endif
+	{
+
+		ss_ic_sclh_cnt = (10 * CFG_I2C_CLK) / 4 ;
+		ss_ic_scl_cnt = CFG_I2C_CLK * 5;
+
+		fs_ic_sclh_cnt = (10 * CFG_I2C_CLK) / 24 ;
+		fs_ic_scl_cnt = (CFG_I2C_CLK * 10) / 8 ;
+
+
+	}
+
+	spin_lock_init(&cs_i2c_lock);
+
+	return 0;
+}
+
+static void __exit
+cs_i2c_exit(void)
+{
+
+	misc_deregister(&cs_i2c_miscdev);
+
+}
+
+module_init(cs_i2c_init);
+module_exit(cs_i2c_exit);
+
+MODULE_LICENSE("GPL");
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/celestial/peripheral/cnc18xx_i2c.h linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/peripheral/cnc18xx_i2c.h
--- linux-linaro-3.4-2012.05-1_original/drivers/celestial/peripheral/cnc18xx_i2c.h	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/peripheral/cnc18xx_i2c.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,24 @@
+#ifndef __CELESTIAL_I2C_H__
+#define	__CELESTIAL_I2C_H__
+
+#define		IC_ENABLE			0x00
+#define		IC_SCLH_CNT			0x04
+#define		IC_SCLL_CNT			0x08
+#define		IC_DATA_CMD			0x0c
+#define		IC_INTR_STAT		0x10
+#define		IC_RAW_INTR_STAT	0x14
+#define		IC_INTR_MASK		0x18
+#define		IC_INTR_CLR			0x1c
+#define		IC_STAT				0x20
+#define		IC_RX_TL			0x24
+#define		IC_TX_TL			0x28
+#define		IC_TXFLR			0x2c
+#define		IC_RXFLR			0x30
+#define		IC_FIFO_CLR			0x34
+#define		IC_RESET			0x38
+#define		IC_SLV_TIMEOUT_L	0x3c
+#define		IC_SLV_TIMEOUT_H	0x3e	
+#define		IC_SLV_TIMEOUT_EN	0x40
+
+#endif
+
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/celestial/peripheral/cnc18xx_sci.c linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/peripheral/cnc18xx_sci.c
--- linux-linaro-3.4-2012.05-1_original/drivers/celestial/peripheral/cnc18xx_sci.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/peripheral/cnc18xx_sci.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,1565 @@
+//#include <linux/config.h>
+#include <linux/autoconf.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/workqueue.h>
+#include <linux/timer.h>
+#include <linux/poll.h>
+#include <linux/init.h>
+#include <linux/miscdevice.h>
+#include <linux/i2c.h>
+#include <linux/string.h>
+#include <linux/proc_fs.h>
+#include <linux/poll.h>
+
+#include <linux/semaphore.h>
+#include <asm/atomic.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <mach/hardware.h>
+#include <mach/irqs.h>
+
+MODULE_AUTHOR("Celestial");
+MODULE_DESCRIPTION("Cavium Celestial SoC Smart card driver");
+MODULE_LICENSE("GPL");
+
+
+
+#define SCI_MINOR			160
+#define SCI_NUM				1
+
+//#define SCI_BASE_ADDR0		0X101F0000   
+
+//#define SCI_BASE_SIZE		0x1000
+
+#define SCI_IRQ				IRQ_SMART_CART
+#define SCI_MAX_FIFOSIZE    32
+
+#define SCI_REF_CLK         810000000
+
+
+/*
+ * Debugging macro and defines
+ */
+
+#define SCI_DEBUG_LEVEL0	(0)	/* Quiet   */
+#define SCI_DEBUG_LEVEL1	(1)	/* Audible */
+#define SCI_DEBUG_LEVEL2	(2)	/* Loud    */
+#define SCI_DEBUG_LEVEL3	(3)	/* Noisy   */
+
+#ifdef CONFIG_CELESTIAL_SCI_DEBUG
+#define DEBUG(n, args...)				\
+ 	do {						\
+		if (n <= CONFIG_SCI_DEBUG_VERBOSE)	\
+			printk(KERN_INFO args);		\
+	} while(0)
+#else /* CONFIG_SCI_DEBUG */
+#define DEBUG(n, args...) do { } while(0)
+
+#endif /* CONFIG_SCI_DEBUG */
+
+static volatile unsigned short *sci_base = NULL;
+
+//static int irq_sci_cardin = 0;	/*Flag to check the interrupt of card insert added by tata team*/
+//static int irq_sci_cardout = 0;  /*Flag to check the interrupt of card remove added by tata team*/
+#define sci_get_regs(reg, ch) \
+	(*(volatile unsigned short*)(sci_base + (int)(ch)*(0x3000) + (int)(reg >> 1)))
+#define sci_set_regs(reg, ch, v) \
+	(*(volatile unsigned short*)(sci_base + (int)(ch)*(0x3000) + (int)(reg >> 1)) = (unsigned short)(v))
+
+#define SCI_DATA			0x00 /* data register */
+
+#define SCI_CR0				0x04 	/* control register 0 */
+#define CR0_INIT_VALUE  		0x00 //0x28
+#define CR0_SENSE			(1<<0) 	/* inverts sense of input/output line for data and parity bits */
+									/* 0 - direct convention */
+									/* 1 - inverse convention */
+#define CR0_ORDER			(1<<1) 	/* specifies ordering of the data bits */
+									/* 0 - LOW interpreted as logic 0, LSB (direct convention) */
+									/* 1 - LOW interpreted as logic 1, MSB (inverse convention) */
+#define CR0_TXPARITY		(1<<2)	/* transmit parity setting */
+									/* 0 - even parity */
+									/* 1 - odd parity */
+#define CR0_TXNAK			(1<<3)	/* enables character transmission handshaking */
+									/* 0 - the SCI does not check to see if the receiver 
+									    has pulled the input/output line LOW to indicate a parity error
+									    1 - the SCI checks, after each character has been transmitted, 
+									    to see if the receiver has pulled the input/output line LOW to indicate a parity error */
+#define CR0_RXPARITY		(1<<4)	/* receive parity setting 
+									    0 - even parity 
+									    1 - odd parity */
+#define CR0_RXNAK			(1<<5)	/* enables character receipt handshaking
+									    0 - the SCI does not pull the input/ouput line LOW if it detects a parity error
+									    1 - the SCI pulls the input/output line LOW if it detects a parity error */
+#define CR0_CLKDIS			(1<<6)	/* if the card supports clock stop mode, this bit ban be used to
+									    stop and start the clock:
+									    0 - clock start initiated
+									    1 - clock stop initiated */
+#define CR0_CLKVAL			(1<<7)	/* define the inactive state of the card clock when clock stop mode is supported:
+									    0 - clock held LOW when inactive
+									    1 - clock held HIGH when inactive */
+									
+#define SCI_CR1				0x08 	/* control register 1 */
+#define CR1_INIT_VALUE  		0x1
+#define CR1_VAL				0x001b	/* ... */
+#define CR1_BLKEN           (1<<1) /* interface block time out 
+                                       0 -disable
+                                       1 -enable */
+
+#define CR1_MOD				(1<<2)	/* interface direction of communication control:
+									    0 -receive 
+									    1 - transmit */
+#define CR1_BGTEN           (1<<4) /* interface block guard timer enable 
+                                       0 -disable
+                                       1 -enable */
+
+
+#define SCI_CR2				0x0c	/* control register 2 */
+#define CR2_STARTUP			(1<<0)	/* writing a 1 to this bit starts the activation of the card */
+#define CR2_FINISH			(1<<1)	/* writing a 1 to this bit deactivates the card */
+#define CR2_WRESET			(1<<2)	/* writing a 1 to this bit initiates a warm reset */
+
+#define SCI_CLKICC			0x10 	/* external smart card clock frequency */
+#define CLKICC_INIT_VAL			0x1a 	/* define the smart card clock frequency */
+
+#define SCI_VALUE			0x14 	/* Number of SCIBAUD cycles per etu */
+#define VALUE_INIT_VAL			0x08	/* defines the number of SCIBAUD cycles per etu */
+
+#define SCI_BAUD			0x18 	/* Baud rate clock divisor value */
+#define BAUD_INIT_VAL			0x9ce	/* the divide valud used to define the baudrate clock frequency */
+
+#define SCI_TIDE			0x1c 	/* Transmit and eceive FIFO water level marks */
+#define TIDE_INIT_RX			0x10 	/* trigger point for SCIRXTIDEINTR */
+#define TIDE_INIT_TX			0x01 //0x00	/* trigger point for SCITXTIDEINTR */
+#define TIDE_INIT_VAL      TIDE_INIT_RX | TIDE_INIT_TX
+
+#define SCI_DMACR			0x20 	/* Direct Memory Access control register */
+#define DAMCR_VAL			0x00	/* no DMA support */
+
+#define SCI_STABLE			0x24 	/* Card stable after insertion debounce duration */
+#define STABLE_INIT_VAL			0x05 //0x54	/* stores the debounce time */
+
+#define SCI_ATIME			0x28 	/* Card activation event time */
+#define ATIME_INIT_VAL			0x9c40 //0xafc8	/* stores the time for each of the three stages of the card activation process time */
+									    
+									    
+#define SCI_DTIME			0x2c	/* card deactivation event time */
+#define DTIME_INIT_VAL			0x00c8	/*  stores the time for each of the three stages of the card 
+									    deactivation process time */
+									    
+#define SCI_ATRSTIME		0x30 	/* Time to start of the ATR reception */
+#define ATRSTIME_INIT_VAL		0xffff /*0xafc8*/ 	/*  ATR reception start timeout threshold from the assertion
+									    or deassertion of nSCICARDRST */
+									    
+#define SCI_ATRDTIME		0x34 	/* Maximum allowed duration of the ATR character stream */
+#define ATRDTIME_INIT_VAL		0xab00	/*0xffff*/	/* ATR reception duration timeout threshold from the start
+									    bit of the first ATR character */
+									    
+#define SCI_STOPTIME		0x38 	/* Duration before the card clock can be stopped */
+#define STOPTIME_VAL			0x00	/* FIXME! duration from card clock stop initiation to the card clock
+									    becoming inactive, and the clock stopped interrupt SCICLKSTPINTR
+									    becoming  asserted */
+
+#define SCI_STARTTIME		0x3c 	/* Duration before transactions can commence after clock is restarted */
+#define STARTTIME_VAL			0x00	/* FIXME! duration from the card clock start initiation to the card 
+									    clock active interrupt SCICLKACTINTR becoming asserted */
+
+#define SCI_RETRY			0x40 	/* Retry limit register */
+#define RETRY_VAL				0x00	/* FIXME! [2:0] - specifies the maximum number of times that a 
+									    char is retransmitted following the detection of a parity error by the card 
+									    [5:3] - specifies the maximum number of retries to receive when a parity
+									    error has occurred in reception */
+
+#define SCI_CHTIMELS		0x44 	/* character to character timeout (least significant 16 bits) */
+#define SCI_CHTIMEMS		0x48 	/* character to character timeout (most significant 16 bits) */
+#define CHTIMELS_INIT_VAL		0x2580	/* FIXME! */
+#define CHTIMEMS_INIT_VAL		0x00	/* FIXME! */
+
+#define SCI_BLKTIMELS		0x4c 	/* Receive timeout between blocks (least significant 16 bits) */
+#define SCI_BLKTIMEMS		0x50 	/* Receive timeout between blocks (most significant 16 bits) */
+#define BLKTIMELS_VAL			0xfff0	/* FIXME! */
+#define BLKTIMEMS_VAL			0x00	/* FIXME! */
+
+#define SCI_CHGUARD			0x54 	/* character to character extra guard time */
+/* 
+    CHGUARD defines the extra guard time that is added to the minimum duration 
+    between leading edges of the start bits of two consecutive characters, for subsequent 
+    communication from the interface to the Smart Card.
+
+    The CHGUARD valus is derived from the TC1 value that is extracted from the ATR character stream. 
+    Writing a value to this register while the timeout is in progress causes the internal timer to be loaded
+    with the new value, and  then cound down from this value.
+
+    The TC1 value can be between 0 and 255. The software must read the TC1 value and program the 
+    CHGUARD register as described in the follow table to provide the resultan guard time in etus 
+
+               CHGUARD VALUE                 RESULTAN GUARD TIME (ETUS)
+    --------------------------------------------------------------------------
+                     T0           T1            T0                T1
+    --------------------------------------------------------------------------
+    0 =< TC1 < 255   TC1         TC1+1         TC1+12            TC1+11
+    --------------------------------------------------------------------------
+    255              0             0            12                11
+    --------------------------------------------------------------------------
+ */
+#define CHGUARD_VAL			0x00	/* FIXME!*/
+
+#define SCI_BLKGUARD		0x58 	/* block guard time */
+/* 
+   Defines the minimum time in etus between the leading edges of two consecutive characters sent 
+   in opposite directions:
+   1) For T0, the blkguard minimum time is 16 work etus.
+   2) For T1, the blkguard minimum time is 22 work etus.
+
+   NOTE:
+   For T0, blkguard is effecitively offset by 12 etus internally, so the value to be programmed into the 
+   blkguard register should be required time period in etus minus 12.
+   For T1, blkguard is effecitively offset by 11 etus internally, so the value to be programmed into the 
+   blkguard register should be required time period in etus minus 11.
+*/
+#define BLKGUARD_VAL		0x00	/* FIXME! */
+
+#define SCI_RXTIME			0x5c 	/* receive read time-out register */
+#define RXTIME_INIT_VAL			0xffff	/* receive read time out value */
+									/* the following table list the range and resolution of the timeout 
+									value for various smart card clock frequencies:
+									FREQ/RANGE(APPROX)/RESOLUTION
+									10MHZ/0 -6 ms/0.1us
+									5 MHZ/0  -13ms/0.2us
+									1 MHZ/0  -65ms/  1us
+									500KHz/0-131ms/2us */
+
+#define SCI_FIFOSTATUS		0x60 	/* transmit and receive FIFO status */
+#define FIFOST_TXFF			(1<<0)	/* TXFIFO full status */
+#define FIFOST_TXFE			(1<<1)	/* TXFIFO empty status */
+#define FIFOST_RXFF			(1<<2)	/* RXFIFO full status */
+#define FIFOST_RXFE			(1<<3)	/* RXFIFO empty status */
+
+/* 
+   SCITXCOUNT returns the number of characters (including any character currently being 
+   transmitted) in the transmit FIFO when read, and flushes the transmit FIFO when written 
+   (with any value)
+   [15:4] reserved, do not modify, read as zero.
+   [3:0] a read transmits the FIFO count. a write flushes the tranmit FIFO.
+*/
+#define SCI_TXCOUNT			0x64 	/* transmit FIFO fill level */
+
+/* 
+   SCIRXCOUNT returns the number of characters in the receive FIFO when read, 
+   and flushes the receive FIFO when written (with any value)
+   [15:4] reserved, do not modify, read as zero.
+   [3:0] a read receive the FIFO count. a write flushes the receive FIFO.
+*/
+#define SCI_RXCOUNT			0x68 	/* receive FIFO fill level */
+
+#define SCI_IMSC			0x6c 	/* interrupt mask set or clear mask */
+#define SCI_RIS				0x70 	/* raw interrupt status register */
+#define SCI_MIS				0x74 	/* masked interrupt status register */ 
+#define SCI_ICR				0x78 	/* interrutp clear register */
+#define INT_IN 				(1<<0)	/* card in interrupt */
+#define INT_OUT 			(1<<1)	/* card out interrupt */
+#define INT_PWUP 			(1<<2)	/* card power up interrupt */
+#define INT_PWDN 			(1<<3)	/* card power down interrupt */
+#define INT_TRANSERR 		(1<<4)	/* transmit error interrupt */
+#define INT_ATRSTOUT 		(1<<5)	/* ATR start time out */
+#define INT_ATRDTOUT 		(1<<6)	/* ATR data stream duration time out */
+#define INT_BLKOUT 			(1<<7)	/* block time out interrupt */
+#define INT_CHOUT 			(1<<8)	/* character time out interrupt */
+#define INT_RDOUT 			(1<<9)	/* read time out interrupt */
+#define INT_OVERRUN 		(1<<10)	/* overrun interrupt */
+#define INT_CLKSTOP 		(1<<11)	/* clock stop interrupt */
+#define INT_CLKACTIVE 		(1<<12)	/* clock active interrupt */
+#define INT_RXTIDE 			(1<<13)	/* receive FIFO tide level interrupt */
+#define INT_TXTIDE 			(1<<14)	/* transmit FIFO tide level interrupt */
+
+/* 
+  * the following 3 registers is not used for csm1201 chip 
+ */
+// DELME #define SCI_SYNCACT	0x7c 	/* synchronous mode activation register */
+// DELME #define SCI_SYNCTX	0x80 	/* synchronous mode transmit clock and data stream register */
+// DELME #define SCI_SYNCRX	0x84 	/* synchronous mode receive clock and data stream register */
+#define SCI_IOC_MAGIC 'p'
+#define SCI_IOC_WARMRESET			 _IOW(SCI_IOC_MAGIC, 0x01, int)
+#define SCI_IOC_ISPRESENT			 _IOR(SCI_IOC_MAGIC, 0x02, int)
+#define SCI_IOC_ACTIVE				 _IOW(SCI_IOC_MAGIC, 0x03, int)
+#define SCI_IOC_DEACTIVE			 _IOW(SCI_IOC_MAGIC, 0x04, int)
+#define SCI_IOC_CLKSTART			 _IOW(SCI_IOC_MAGIC, 0x05, int)
+#define SCI_IOC_CLKSTOP				 _IOW(SCI_IOC_MAGIC, 0x06, int)
+#define SCI_IOC_SELPROTOCOL 		 _IOW(SCI_IOC_MAGIC, 0x07, int)
+#define SCI_IOC_RXINTTIGGER    		 _IOW(SCI_IOC_MAGIC, 0x08, int)
+#define SCI_IOC_TXINTTIGGER    		 _IOW(SCI_IOC_MAGIC, 0x09, int)
+#define SCI_IOC_SET_ETU     		 _IOW(SCI_IOC_MAGIC, 0x0a, int)
+#define SCI_IOC_SET_SC_CLOCK     	 _IOW(SCI_IOC_MAGIC, 0x0b, int)
+#define SCI_IOC_SET_TXRETRY    		 _IOW(SCI_IOC_MAGIC, 0x0c, int)
+#define SCI_IOC_SET_RXRETRY    	     _IOW(SCI_IOC_MAGIC, 0x0d, int)
+#define SCI_IOC_SET_CHGUARD 		 _IOW(SCI_IOC_MAGIC, 0x0e, int)
+#define SCI_IOC_SET_BLOCKGUARD	 	 _IOW(SCI_IOC_MAGIC, 0x0f, int)
+#define SCI_IOC_SET_RXTIMEOUT  		 _IOW(SCI_IOC_MAGIC, 0x10, int)
+#define SCI_IOC_SET_CONVENTION 		 _IOW(SCI_IOC_MAGIC, 0x11, int)
+#define SCI_IOC_SET_PARITY     		 _IOW(SCI_IOC_MAGIC, 0x12, int)
+#define SCI_IOC_GET_RXRDYSIZE  	 _IOR(SCI_IOC_MAGIC, 0x13, int)
+#define SCI_IOC_GET_TXRDYSIZE  	 _IOR(SCI_IOC_MAGIC, 0x14, int)
+#define SCI_IOC_SET_RXFIFO_THRESHOLD _IOW(SCI_IOC_MAGIC, 0x15, int)
+#define SCI_IOC_SET_TXFIFO_THRESHOLD _IOW(SCI_IOC_MAGIC, 0x16, int)
+#define SCI_IOC_GET_RXFIFO_THRESHOLD _IOR(SCI_IOC_MAGIC, 0x17, int)
+#define SCI_IOC_GET_TXFIFO_THRESHOLD _IOR(SCI_IOC_MAGIC, 0x18, int)
+#define SCI_IOC_SET_RX_READREADY_REPORT _IOW(SCI_IOC_MAGIC, 0x19, int)
+#define SCI_IOC_SET_TX_WRITEREADY_REPORT _IOW(SCI_IOC_MAGIC, 0x1a, int)
+#define SCI_IOC_GET_BLOCKGUARD			_IOW(SCI_IOC_MAGIC, 0x1b, int)
+#define SCI_IOC_GET_SC_CLOCK     	 _IOR(SCI_IOC_MAGIC, 0x1c, int)
+#define SCI_IOC_GET_TXRETRY			_IOR(SCI_IOC_MAGIC, 0x1e, int)
+#define SCI_IOC_GET_CHGUARD			_IOR(SCI_IOC_MAGIC, 0x1f, int)
+#define SCI_IOC_GET_RXTIMEOUT			_IOR(SCI_IOC_MAGIC, 0x20, int)
+#define SCI_IOC_GET_RXRETRY			_IOR(SCI_IOC_MAGIC, 0x22, int)
+#define SCI_IOC_SET_TXRXNAK			_IOR(SCI_IOC_MAGIC, 0x23, int)
+
+/*
+ * loop queue definitions and implement 
+ */
+#define IFD_BUF_SIZE 512//8192
+
+struct dat_queue {
+		u32 head;
+		u32 tail;
+		u8  buf[IFD_BUF_SIZE];
+};
+
+
+
+#define INC(a) 			((a) = ((a)+1) & (IFD_BUF_SIZE-1))
+#define DEC(a) 			((a) = ((a)-1) & (IFD_BUF_SIZE-1))
+#define EMPTY(a) 		((a).head == (a).tail)
+#define CHARS(a) 		(((a).head-(a).tail-1)&(IFD_BUF_SIZE-1))
+#define LEFT(a) 		(((a).tail-(a).head)&(IFD_BUF_SIZE-1))
+#define LAST(a) 		((a).buf[(IFD_BUF_SIZE-1)&((a).head-1)])
+#define FULL(a) 		((a).head == (((a).tail+1) & (IFD_BUF_SIZE-1)))
+#define GETCH(queue,c) 	(void)({c=(queue).buf[(queue).head];INC((queue).head);})
+#define PUTCH(c,queue) 	(void)({(queue).buf[(queue).tail]=(c);INC((queue).tail);})
+
+/* stats */
+//static u16 frames_rx = 0;
+//static u16 frames_tx = 0;
+//static u16 frames_lost = 0;
+
+/* flags */
+static char card_inserted = 0;
+static char card_noatr =0;
+//static char clock_stopped = 0;
+//static char flag_reverse = 0;
+static char sci_channel = 0;
+static char card_inout_change = 0;
+
+
+#define RXTIMEOUT_DEFAULT 15
+static char rxtimeout;
+
+static int receive_exception =0;
+static struct dat_queue rq;
+static DECLARE_WAIT_QUEUE_HEAD(rq_queue);
+
+static struct dat_queue tq;
+static struct semaphore tq_sem;
+static DECLARE_WAIT_QUEUE_HEAD(tq_queue);
+
+//static DECLARE_WAIT_QUEUE_HEAD(CardInOut_queue);
+/*
+ * Feeding the output queue to the device is handled by a workqueue.
+ */
+//static void sci_do_work(void *);
+//static DECLARE_WORK(sci_work, sci_do_work, NULL);
+//static struct workqueue_struct *sci_workqueue;
+
+/*
+ * 
+ */
+static void sci_do_tasklet(unsigned long unused);
+DECLARE_TASKLET(sci_tasklet, sci_do_tasklet, 0);
+
+/*
+ * The output "process" is controlled by a spin lock; decisions on
+ * sci_output_active require that this lock be held.
+ */
+static spinlock_t sci_lock = SPIN_LOCK_UNLOCKED;
+volatile static int sci_output_active;
+volatile static int sci_input_active;
+
+static unsigned char clkicc_value = 0;
+static u16 baud_value = 0;
+
+/* BUFFER status and event report releated*/
+static spinlock_t sci_buffer_status_lock = SPIN_LOCK_UNLOCKED;
+//static unsigned int sci_read_buffer_threshold = IFD_BUF_SIZE /2;
+//static unsigned int sci_write_buffer_threshold =IFD_BUF_SIZE /2;
+//static unsigned int sci_write_ready_report_en =0;
+//static unsigned int sci_read_ready_report_en =0;
+//static unsigned int sci_write_ready_report_flag =0;
+//static unsigned int sci_read_ready_report_flag =0;
+
+typedef struct{
+int sci_buffer_threshold;
+int sci_buffer_report_en;
+int sci_buffer_report_flag;
+} sci_buffer_t;
+sci_buffer_t sci_rx_buffer={IFD_BUF_SIZE /2,0,1};
+sci_buffer_t sci_tx_buffer={IFD_BUF_SIZE /2,0,1};
+static DECLARE_WAIT_QUEUE_HEAD(sci_write_ready);
+static DECLARE_WAIT_QUEUE_HEAD(sci_read_ready);
+
+static DECLARE_WAIT_QUEUE_HEAD(sci_empty_queue); /* waked when queue empties */
+
+
+
+static void _sci_clkstart(int ch)
+{
+	u16 old_cr0_value;
+	old_cr0_value = sci_get_regs(SCI_CR0, ch);
+	sci_set_regs(SCI_CR0, ch, old_cr0_value & (~CR0_CLKDIS));
+	return;
+}
+
+
+static void _sci_clkstop(int ch)
+{
+	u16 old_cr0_value;
+	old_cr0_value = sci_get_regs(SCI_CR0, ch);
+	sci_set_regs(SCI_CR0, ch, old_cr0_value | CR0_CLKDIS);
+	return;
+}
+
+
+/*static void _sci_disable_blkguardtimer(int ch)
+{
+    u16 old_cr1_value;
+	old_cr1_value = sci_get_regs(SCI_CR1, ch);
+	sci_set_regs(SCI_CR1, ch, old_cr1_value & (~CR1_BGTEN));
+	return;
+}
+
+static void _sci_enable_blkguardtimer(int ch)
+{
+	
+    u16 old_cr1_value;
+	old_cr1_value = sci_get_regs(SCI_CR1, ch);
+	sci_set_regs(SCI_CR1, ch, old_cr1_value | CR1_BGTEN);
+	return;
+}*/
+
+static unsigned char _sci_rxfifocount(int ch)
+{
+	return sci_get_regs(SCI_RXCOUNT, ch) & 0xff;  /* fixed by fxd from 0xf to 0xff. Because fifo size is 32 byte */ 
+}
+
+static void _sci_flush_rxfifo(int ch)
+{
+	sci_set_regs(SCI_RXCOUNT, ch, 0);
+}
+
+static void _sci_set_txint_trigger(int ch, unsigned char value ) /* invalid value is from 0 ~ 8 */
+{
+	unsigned char temp_value;
+	if ( value > 8 )
+		value = 8;
+	temp_value = (sci_get_regs(SCI_TIDE, ch) & 0xf0) | value;
+	sci_set_regs(SCI_TIDE, ch, temp_value);
+}
+
+static void _sci_set_rxint_trigger(int ch, unsigned char value ) /* invalid value is from 0 ~ 8 */
+{
+	unsigned char temp_value;
+	if ( value > 8 )
+		value = 8;
+	temp_value = (sci_get_regs(SCI_TIDE, ch) & 0x0f) | (value << 4);
+	sci_set_regs(SCI_TIDE, ch, temp_value);
+}
+static unsigned char _sci_txfifocount(int ch)
+{
+	return sci_get_regs(SCI_TXCOUNT, ch) & 0xff; /* fixed by fxd from 0xf to 0xff. Because fifo size is 32 byte */ 
+}
+
+static void _sci_flush_txfifo(int ch)
+{
+	sci_set_regs(SCI_TXCOUNT, ch, 0);
+}
+
+static void _sci_set_txrxmode(int ch,int mode) /*0: receive, 1:transmit */
+{
+	u16 old_cr1_value;
+	old_cr1_value = sci_get_regs(SCI_CR1, ch);
+	do {
+		mode?sci_set_regs(SCI_CR1, ch, old_cr1_value | CR1_MOD):sci_set_regs(SCI_CR1, ch, old_cr1_value & (~CR1_MOD));
+//		DEBUG(SCI_DEBUG_LEVEL3, "CR1 mode 0x%x \n", sci_get_regs(SCI_CR1, ch)& CR1_MOD);		
+	}while((int)(sci_get_regs(SCI_CR1, ch)& CR1_MOD) != (mode << 2));
+	
+}
+
+static inline unsigned char _sci_read_date(int ch)
+{
+	return sci_get_regs(SCI_DATA, 0) & 0xff;
+}
+
+static inline void _sci_write_date(int ch, unsigned char value)
+{
+	sci_set_regs(SCI_DATA, ch, value);	
+	return;
+}
+
+static void _sci_set_rxretry(int ch, unsigned char retrytimes)
+{
+	u16 old_retry_value;
+	if (retrytimes < 8){
+		old_retry_value = sci_get_regs(SCI_RETRY, ch);	
+		sci_set_regs(SCI_RETRY, ch, (old_retry_value & 0x7) | retrytimes << 3);
+	}
+}
+
+static void _sci_set_txretry(int ch, unsigned char retrytimes)
+{
+	u16 old_retry_value;
+	if (retrytimes < 8){
+		old_retry_value = sci_get_regs(SCI_RETRY, ch);	
+		sci_set_regs(SCI_RETRY, ch, (old_retry_value & 0x38) | retrytimes );
+	}
+}
+
+static void _sci_get_rxretry(int ch, unsigned char *retrytimes)
+{
+	u16 retry_value;
+	
+	retry_value = sci_get_regs(SCI_RETRY, ch);	
+	*retrytimes = (unsigned char)((retry_value & 0x38) >> 3);	
+}
+
+static void _sci_get_txretry(int ch, unsigned char *retrytimes)
+{
+	u16 retry_value;
+
+	retry_value = sci_get_regs(SCI_RETRY, ch);	
+	*retrytimes = (unsigned char)(retry_value & 0x7);
+}
+
+static void _sci_set_chguard(int ch, unsigned char value)
+{
+	sci_set_regs(SCI_CHGUARD, ch, value);	
+	return;
+}
+
+static void _sci_set_blkguard(int ch, unsigned char value)
+{
+	sci_set_regs(SCI_BLKGUARD, ch, value);	
+	return;
+}
+
+static void _sci_get_chguard(int ch, unsigned char *guard)
+{
+	u16 value;
+	
+	value = sci_get_regs(SCI_CHGUARD, ch);	
+	*guard = (unsigned char)value;	
+}
+
+static void _sci_get_blockguard(int ch, unsigned char *guard)
+{
+	u16 value;
+
+	value = sci_get_regs(SCI_BLKGUARD, ch);	
+	*guard = (unsigned char)value;
+}
+
+static void _sci_set_rxtimeout(int ch, unsigned short value)
+{
+	sci_set_regs(SCI_RXTIME, ch, value);	
+	return;
+}
+
+static void _sci_get_rxtimeout(int ch, unsigned short *timeout)
+{
+	u16 value;
+	
+	value = sci_get_regs(SCI_RXTIME, ch);	
+	*timeout = value;	
+}
+
+static void _sci_set_rxparity(int ch, unsigned char value) /*value: 0 for even parity, 1 for odd parity */
+{
+	u16 old_cr0_value;
+	old_cr0_value = sci_get_regs(SCI_CR0, ch);
+	value?sci_set_regs(SCI_CR0, ch, old_cr0_value | CR0_RXPARITY):sci_set_regs(SCI_CR0, ch, old_cr0_value & (~CR0_RXPARITY));
+	return;
+}
+
+
+static void _sci_set_txparity(int ch, unsigned char value) /*value: 0 for even parity, 1 for odd parity */
+{
+	u16 old_cr0_value;
+	old_cr0_value = sci_get_regs(SCI_CR0, ch);
+	value?sci_set_regs(SCI_CR0, ch, old_cr0_value | CR0_TXPARITY):sci_set_regs(SCI_CR0, ch, old_cr0_value & (~CR0_TXPARITY));
+	return;
+}
+
+static void _sci_set_rxnak(int ch, unsigned char value) /*value: 0 disable, 1 enable */
+{
+	u16 old_cr0_value;
+	old_cr0_value = sci_get_regs(SCI_CR0, ch);
+	value?sci_set_regs(SCI_CR0, ch, old_cr0_value | CR0_RXNAK):sci_set_regs(SCI_CR0, ch, old_cr0_value & (~CR0_RXNAK));
+	return;
+}
+
+static void _sci_set_txnak(int ch, unsigned char value) /*value: 0 disable, 1 enable */
+{
+	u16 old_cr0_value;
+	old_cr0_value = sci_get_regs(SCI_CR0, ch);
+	value?sci_set_regs(SCI_CR0, ch, old_cr0_value | CR0_TXNAK):sci_set_regs(SCI_CR0, ch, old_cr0_value & (~CR0_TXNAK));
+	return;
+}
+
+static void _sci_direct_sense(int ch) /* high level for logic 1, lsb is fist bit */ 
+{
+	u16 old_cr0_value;
+	old_cr0_value = sci_get_regs(SCI_CR0, ch);
+	sci_set_regs(SCI_CR0, ch, old_cr0_value & (~(CR0_SENSE | CR0_ORDER)));
+	return;
+}
+
+static void _sci_indirect_sense(int ch) /* low level for logic 1, msb is fist bit */ 
+{
+	u16 old_cr0_value;
+	old_cr0_value = sci_get_regs(SCI_CR0, ch);
+	sci_set_regs(SCI_CR0, ch, old_cr0_value | CR0_SENSE | CR0_ORDER);
+	return;
+}
+
+static void _sci_set_etu(int ch, unsigned int F, unsigned int D)
+{
+	u16 sci_value;
+	u16 sci_baud;
+	u16 sci_clkicc;
+	sci_value = sci_get_regs(SCI_VALUE,ch);
+	sci_clkicc = sci_get_regs(SCI_CLKICC,ch);
+	sci_baud = ((u16)F * (sci_clkicc + 1) * 2)/((u16)D * sci_value) - 1;
+	baud_value = sci_baud;
+
+	sci_set_regs(SCI_BAUD, ch, baud_value);
+
+}
+
+static void _sci_set_sc_clock(int ch, unsigned int f) /* f is smart card clock (Hz)*/
+{
+	u32 sci_clkicc;
+
+	sci_clkicc= (u32)(SCI_REF_CLK * 10/(f * 2))-10;		/* "*10","-10"  are used for rounding */
+	if( (sci_clkicc - (sci_clkicc/10)*10) > 4 )
+		sci_clkicc += 10;
+
+	clkicc_value = (sci_clkicc/10)&0xff;
+	
+	sci_set_regs( SCI_CLKICC,ch,  (u16)((sci_clkicc/10)&0xff));
+}
+
+static unsigned int _sci_get_sc_clock(int ch) /* return value is smart card clock (Hz)*/
+{
+	u16 sci_clkicc;
+	unsigned int ret;
+	
+	sci_clkicc = sci_get_regs(SCI_CLKICC,ch) & 0xff;
+	ret = (unsigned int)(SCI_REF_CLK / ((sci_clkicc +1)*2));
+	return ret;
+}
+
+static void _sci_set_init_value(int ch)
+{
+	unsigned short direction;
+	
+	_sci_flush_rxfifo(ch);
+	_sci_flush_txfifo(ch);
+	sci_set_regs(SCI_ICR, ch, 0x7fff);
+	
+	direction = sci_get_regs(SCI_CR0,ch) & (unsigned short)(CR0_SENSE | CR0_ORDER);
+	sci_set_regs(SCI_CR0, ch, CR0_INIT_VALUE | direction );
+	
+	sci_set_regs(SCI_CR1, ch, CR1_INIT_VALUE);
+	sci_set_regs(SCI_STABLE, ch, STABLE_INIT_VAL);
+	sci_set_regs(SCI_ATIME, ch, ATIME_INIT_VAL);
+	sci_set_regs(SCI_DTIME, ch, DTIME_INIT_VAL);
+	sci_set_regs(SCI_ATRSTIME, ch, ATRSTIME_INIT_VAL);
+	sci_set_regs(SCI_ATRDTIME, ch, ATRDTIME_INIT_VAL);
+	sci_set_regs(SCI_CHTIMEMS, ch, 0);	/* CHTIMEMS must be written first, followed by CHTIMELS */
+	sci_set_regs(SCI_CHTIMELS, ch, CHTIMELS_INIT_VAL);
+	sci_set_regs(SCI_TIDE, ch, TIDE_INIT_VAL);
+	
+	if( clkicc_value == 0 ){
+		clkicc_value = CLKICC_INIT_VAL;
+		baud_value = BAUD_INIT_VAL;
+	}
+	sci_set_regs(SCI_CLKICC, ch, clkicc_value);	
+	sci_set_regs(SCI_BAUD, ch, baud_value);
+	
+	sci_set_regs(SCI_VALUE, ch, VALUE_INIT_VAL);
+	
+	sci_set_regs(SCI_RXTIME, ch, RXTIME_INIT_VAL);
+	sci_set_regs(SCI_BLKTIMEMS, ch, 0);
+	sci_set_regs(SCI_BLKTIMELS, ch, BLKTIMELS_VAL);
+	return;
+}
+
+static void _sci_mask_interrupt(int ch, unsigned short intbits)
+{
+	u16 old_mask;
+	old_mask = sci_get_regs(SCI_IMSC, ch);
+	old_mask &= ~intbits;
+	sci_set_regs(SCI_IMSC, 0, old_mask);
+	return;
+}
+
+static void _sci_unmask_interrupt(int ch, unsigned short intbits)
+{
+	u16 old_mask;
+	old_mask = sci_get_regs(SCI_IMSC, ch);
+	old_mask |= intbits;
+	sci_set_regs(SCI_IMSC, 0, old_mask);
+	return;
+}
+
+static void _sci_active(int ch)
+{
+	sci_output_active = 0;
+	sci_input_active = 0;
+	card_noatr =0;
+	_sci_set_rxint_trigger(ch, 1);
+	_sci_set_init_value(ch);
+	
+/* each active will clear all rx/tx buffer */
+	_sci_flush_txfifo(0);
+	_sci_flush_rxfifo(0);
+	rq.head = 0;
+	rq.tail = 0;
+	tq.head = 0;
+	tq.tail = 0;
+	sci_set_regs(SCI_CR2, ch, CR2_STARTUP);
+	return;
+}
+
+static void _sci_warmreset(int ch)
+{
+	sci_output_active = 0;
+	sci_input_active = 0;
+	card_noatr =0;
+	_sci_set_rxint_trigger(ch, 1);
+	_sci_set_init_value(ch);
+	
+/* each active will clear all rx/tx buffer */
+	_sci_flush_txfifo(0);
+	_sci_flush_rxfifo(0);
+	rq.head = 0;
+	rq.tail = 0;
+	tq.head = 0;
+	tq.tail = 0;
+	sci_set_regs(SCI_CR2, ch, CR2_WRESET);
+	return;
+}
+
+static void _sci_deactive(int ch)
+{
+	card_noatr =0;
+	_sci_flush_txfifo(0);
+	_sci_flush_rxfifo(0);
+	sci_set_regs(SCI_CR2, ch, CR2_FINISH);
+	return;
+}
+
+/* --------------------------------------------------------------------------------- */
+/*
+ * Open the device.
+ */
+static int sci_open(struct inode *inode, struct file *filp)
+{
+	unsigned long flags;
+	
+/* set empty for receive/transmitt queue */
+	rq.head = 0;
+	rq.tail = 0;
+	tq.head = 0;
+	tq.tail = 0;
+
+/* set init value for register to receive ATR*/
+	spin_lock_irqsave(&sci_lock, flags);
+	card_noatr =0;
+	receive_exception =0;
+	_sci_set_init_value(0);
+	_sci_direct_sense(0);
+	spin_unlock_irqrestore(&sci_lock, flags);
+	_sci_unmask_interrupt(0, 0x3fff); /* enable all interrupts */
+	return 0;
+}
+
+
+static int sci_release(struct inode *inode, struct file *filp)
+{
+	/* Wait for any pending output to complete */
+	if (!EMPTY(tq))
+		wait_event_interruptible(sci_empty_queue, sci_output_active == 0);
+
+	_sci_deactive(0);
+	_sci_mask_interrupt(0, 0xfffc); /* Only enable card in/out*/
+	return 0;
+}
+
+static unsigned int sci_poll(struct file *filp, poll_table *wait)
+{
+	unsigned int mask = 0;
+//	poll_wait(filp, &CardInOut_queue, wait);
+
+	poll_wait(filp, &rq_queue, wait);
+	poll_wait(filp, &tq_queue, wait);
+	poll_wait(filp, &sci_read_ready, wait);
+	poll_wait(filp, &sci_write_ready, wait);
+	
+
+	if (sci_rx_buffer.sci_buffer_report_flag ==1 && sci_rx_buffer.sci_buffer_report_en == 1){
+		if (LEFT(rq) >= sci_rx_buffer.sci_buffer_threshold ){
+			mask |= POLLIN | POLLRDNORM;
+			return mask;
+		}
+	}		
+	if (sci_tx_buffer.sci_buffer_report_flag ==1 && sci_tx_buffer.sci_buffer_report_en == 1){
+		if (LEFT(tq) < sci_tx_buffer.sci_buffer_threshold ){
+			mask |= POLLOUT | POLLWRNORM;
+			return mask;
+		}
+	}
+	
+	if( card_inout_change == 1 ){
+//		mdelay(4000);
+		card_inout_change = 0;
+		mask = POLLPRI;
+		return mask;
+	}
+	
+/*	if(irq_sci_cardin == 1){
+		spin_lock_irqsave(&sci_lock, flags);
+		irq_sci_cardin = 0;
+		mask = POLLPRI;
+		spin_unlock_irqrestore(&sci_lock, flags);
+		return mask;
+	}
+	if(irq_sci_cardout == 1){
+		spin_lock_irqsave(&sci_lock, flags);
+		irq_sci_cardout = 0;
+		mask = POLLPRI;
+		spin_unlock_irqrestore(&sci_lock, flags);
+		return mask;
+	}*/	
+	if (!EMPTY(rq)) mask |= POLLIN | POLLRDNORM; /* read enabled */
+	if (!FULL(tq)) mask |= POLLOUT | POLLWRNORM; /* write enabled */
+
+	return mask;
+}
+
+static int sci_ioctl(struct inode *inode, struct file *filp,
+			   unsigned int cmd, unsigned long arg)
+{
+	int ret = 0;
+	char tmp_val = 0;
+	unsigned int fifo_size =0;
+	struct SCI_BAUD_t{
+		unsigned int F;
+		unsigned int D;
+	}sci_etu;
+	unsigned long lock_flags;
+	unsigned int sci_clk;
+	unsigned char	retry = 0, guard = 0;
+	unsigned short rxfifotimeout;
+	
+	switch (cmd) {
+		case SCI_IOC_WARMRESET: 
+			if (card_inserted == 1)
+				_sci_warmreset(sci_channel);
+			/* else
+				ret = -EPERM;
+			*/
+			break;
+			
+		case SCI_IOC_ISPRESENT: 
+			tmp_val = card_inserted;
+			if (copy_to_user((void*)arg, &tmp_val, sizeof(char))) 
+				ret = -EFAULT;
+			break;
+			
+		case SCI_IOC_ACTIVE:
+			if (card_inserted == 1){	
+				_sci_active(sci_channel);
+			   
+            }
+			/*else 
+				ret = -EPERM;
+			*/
+			break;
+			
+		case SCI_IOC_DEACTIVE:
+			if (card_inserted == 1){
+                //state_atr = 0;
+				_sci_deactive(sci_channel);
+            }
+			/* else
+				ret = -EPERM;
+			*/
+			break;
+			
+		case SCI_IOC_CLKSTOP:
+			if (card_inserted == 1)
+				_sci_clkstart(sci_channel);
+			/* else
+				ret = -EPERM;
+			*/
+			break;
+			
+		case SCI_IOC_CLKSTART: 
+			_sci_clkstop(sci_channel);
+			break;
+
+		case SCI_IOC_RXINTTIGGER:
+			if (arg < 8)
+				_sci_set_rxint_trigger(sci_channel, (unsigned char)arg);
+			else
+				return -EINVAL;
+			break;
+		case SCI_IOC_TXINTTIGGER:
+			if (arg < 8)
+				_sci_set_txint_trigger(sci_channel, (unsigned char)arg);
+			else
+				return -EINVAL;
+			break;
+
+		case SCI_IOC_SET_ETU:
+			if (copy_from_user(&sci_etu, (void *)arg, sizeof(struct SCI_BAUD_t)))
+				return -EFAULT;
+			_sci_set_etu(sci_channel, sci_etu.F, sci_etu.D);
+			
+			break;
+		case SCI_IOC_GET_SC_CLOCK:
+			sci_clk = _sci_get_sc_clock(sci_channel);
+			
+			if (copy_to_user((void*)arg, &sci_clk, sizeof(unsigned int))) 
+				ret = -EFAULT;
+			break;
+		case SCI_IOC_SET_SC_CLOCK:
+			_sci_set_sc_clock(sci_channel,arg);
+			break;
+
+		case SCI_IOC_SET_TXRETRY:
+			_sci_set_txretry(0, (unsigned char)arg);
+			break;
+
+		case SCI_IOC_SET_RXRETRY:
+			_sci_set_rxretry(0, (unsigned char)arg);
+			break;
+
+		case SCI_IOC_GET_TXRETRY:
+			_sci_get_txretry(0, &retry);
+			if (copy_to_user((void*)arg, &retry, sizeof(unsigned char))) 
+				ret = -EFAULT;
+			break;
+
+		case SCI_IOC_GET_RXRETRY:
+			_sci_get_rxretry(0, &retry);
+			if (copy_to_user((void*)arg, &retry, sizeof(unsigned char))) 
+				ret = -EFAULT;
+			break;
+			
+		case SCI_IOC_SET_CHGUARD:
+			_sci_set_chguard(0, (unsigned char)arg);
+			break;
+			
+		case SCI_IOC_SET_BLOCKGUARD:
+			_sci_set_blkguard(0, (unsigned char)arg);
+			break;
+
+		case SCI_IOC_GET_CHGUARD:
+			_sci_get_chguard(0, &guard);
+			if (copy_to_user((void*)arg, &guard, sizeof(unsigned char))) 
+				ret = -EFAULT;
+			break;
+
+		case SCI_IOC_GET_BLOCKGUARD:
+			_sci_get_blockguard(0, &guard);
+			if (copy_to_user((void*)arg, &guard, sizeof(unsigned char))) 
+				ret = -EFAULT;
+			break;
+			
+		case SCI_IOC_SET_CONVENTION:  
+			if (arg == 0)
+				_sci_direct_sense(0);
+			else if (arg == 1)
+				_sci_indirect_sense(0);
+			else 
+				ret = -EINVAL;
+			break;
+			
+		case SCI_IOC_SET_PARITY:
+			if (arg == 0 || arg ==1){
+				_sci_set_rxparity(0, (unsigned char)arg);
+				_sci_set_txparity(0, (unsigned char)arg);
+			}
+			else 
+				ret = -EINVAL;
+			break;
+
+		case SCI_IOC_SET_TXRXNAK:
+			if (arg == 0 || arg ==1){
+				_sci_set_rxnak(0, (unsigned char)arg);
+				_sci_set_txnak(0, (unsigned char)arg);
+			}
+			else 
+				ret = -EINVAL;
+			break;
+			
+		case SCI_IOC_SET_RXTIMEOUT:
+			_sci_set_rxtimeout(0, (unsigned short)arg);
+			break;
+
+		case SCI_IOC_GET_RXTIMEOUT:
+			_sci_get_rxtimeout(0, &rxfifotimeout);
+			if (copy_to_user((void*)arg, &rxfifotimeout, sizeof(unsigned short))) 
+				ret = -EFAULT;
+			break;
+			
+		case SCI_IOC_GET_RXRDYSIZE:
+			fifo_size = LEFT(rq);
+			if (copy_to_user((void*)arg, &fifo_size, sizeof(unsigned int))) 
+				ret = -EFAULT;
+			break;
+			
+		case SCI_IOC_GET_TXRDYSIZE:
+			fifo_size = CHARS(tq);
+			if (copy_to_user((void*)arg, &fifo_size, sizeof(unsigned int))) 
+				ret = -EFAULT;
+			break;
+			
+		case SCI_IOC_SET_RXFIFO_THRESHOLD:
+			if (arg < IFD_BUF_SIZE){
+				spin_lock_irqsave(&sci_buffer_status_lock, lock_flags);
+				sci_rx_buffer.sci_buffer_threshold = arg;
+				spin_unlock_irqrestore(&sci_buffer_status_lock, lock_flags);
+			}			
+			break;
+			
+		case SCI_IOC_GET_RXFIFO_THRESHOLD:
+				if (copy_to_user((void*)arg, &(sci_rx_buffer.sci_buffer_threshold), sizeof(int))) 
+					ret = -EFAULT;
+			break;
+			
+		case SCI_IOC_SET_TXFIFO_THRESHOLD:
+			if (arg < IFD_BUF_SIZE){
+				spin_lock_irqsave(&sci_buffer_status_lock, lock_flags);
+				sci_tx_buffer.sci_buffer_threshold = arg;
+				spin_unlock_irqrestore(&sci_buffer_status_lock, lock_flags);
+			}
+			break;
+			
+		case SCI_IOC_GET_TXFIFO_THRESHOLD:
+				if (copy_to_user((void*)arg, &(sci_tx_buffer.sci_buffer_threshold), sizeof(int))) 
+					ret = -EFAULT;
+			break;
+			
+		case SCI_IOC_SET_RX_READREADY_REPORT:
+			if (arg == 0 || arg == 1){
+				spin_lock_irqsave(&sci_buffer_status_lock, lock_flags);
+				sci_rx_buffer.sci_buffer_report_en = arg;
+				spin_unlock_irqrestore(&sci_buffer_status_lock, lock_flags);
+			}
+			break;	
+			
+		case SCI_IOC_SET_TX_WRITEREADY_REPORT:	
+			if (arg == 0 || arg == 1){
+				spin_lock_irqsave(&sci_buffer_status_lock, lock_flags);
+				sci_tx_buffer.sci_buffer_report_en = arg;
+				spin_unlock_irqrestore(&sci_buffer_status_lock, lock_flags);
+			}
+			break;	
+			
+		default:
+			ret = -EINVAL;
+			break;
+	}
+
+	return ret;
+}
+
+/*
+ * Start input; call under lock.
+ */
+static void sci_start_input(void)
+{
+	if (sci_input_active) /* Should never happen */
+		return;
+	
+	_sci_set_txrxmode(0, 0);
+	_sci_mask_interrupt(0, INT_TXTIDE);
+//	_sci_unmask_interrupt(0, INT_RXTIDE);
+	
+
+	sci_input_active = 1;
+	sci_output_active = 0;
+}
+
+
+/*
+ * Read from the device 
+ */
+static ssize_t sci_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
+{
+	unsigned long flags;
+	unsigned int i,count0 = 0;
+	u8 read_buf[IFD_BUF_SIZE] = { 0 };
+	
+//	DEFINE_WAIT(wait);
+	
+	if ((card_inserted == 0) || (card_noatr == 1)){
+		DEBUG(SCI_DEBUG_LEVEL0, "card status is wrong\n");
+		return 0;
+	}
+	if (EMPTY(rq) && (filp->f_flags & O_NONBLOCK))
+		return -EAGAIN;
+	
+	
+	spin_lock_irqsave(&sci_lock, flags);
+	sci_start_input();
+	spin_unlock_irqrestore(&sci_lock, flags);
+	receive_exception =0;
+	
+	if (LEFT(rq) < count){
+	//if (EMPTY(rq)){
+		wait_event_interruptible_timeout(rq_queue, (LEFT(rq) >= count || receive_exception == 1), rxtimeout*HZ); /* 10 sec */
+#if 0 
+		prepare_to_wait(&rq_queue, &wait, TASK_INTERRUPTIBLE);
+		if (LEFT(rq) < count){
+			schedule_timeout(rxtimeout*HZ); /* max sleep time is 5 secs */
+			finish_wait(&rq_queue, &wait);
+			if (signal_pending(current))
+				return -ERESTARTSYS;
+		}
+#endif
+		}
+	if(receive_exception == 1){
+		if( EMPTY(rq) )
+			return -EFAULT;
+	}
+	/* count0 is the number of readable data bytes */
+	
+	count0 = LEFT(rq);
+	if (count0 < count) count = count0;
+
+	for (i = 0; i<count && (!EMPTY(rq)); i++) { 
+		GETCH(rq, read_buf[i]); 
+//		DEBUG(SCI_DEBUG_LEVEL3, "Read ch is 0x%x\n",read_buf[i]);
+	}
+
+	if (count > 0){
+		if (copy_to_user(buf, read_buf, count)) 
+			return -EFAULT;
+	}
+	return count;
+}
+
+/*
+ * Start output; call under lock.
+ */
+static inline void sci_start_output(void)
+{
+//	_sci_mask_interrupt(0, INT_RXTIDE);
+	_sci_unmask_interrupt(0, INT_TXTIDE);
+	if (!sci_output_active){
+		_sci_set_txint_trigger(0, 4);
+		_sci_set_txrxmode(0, 1);
+		sci_output_active = 1;
+		sci_input_active = 0;
+	}
+}
+
+
+/*
+ * Write to the device.
+ */
+static ssize_t sci_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos)
+{
+	unsigned long flags;
+	int i, space, written = 0;
+	char write_buf[IFD_BUF_SIZE];
+
+	if (card_inserted == 0 || card_noatr == 1){
+		DEBUG(SCI_DEBUG_LEVEL0, "card status is wrong\n");
+		return 0;
+	}
+	if (FULL(tq) && (filp->f_flags & O_NONBLOCK))
+		return -EAGAIN;
+	/*
+	 * Take and hold the semaphore for the entire duration of the operation.  The
+	 * consumer side ignores it, and it will keep other data from interleaving
+	 * with ours.
+	 */
+	if (down_interruptible(&tq_sem)) return -ERESTARTSYS;
+
+	/*
+	 * Out with the data.
+	 */
+	while (written < count) {
+		/* Hang out until some buffer space is available. */
+		space = CHARS(tq);
+		if (space == 0) {
+			if (wait_event_interruptible(tq_queue,(space = CHARS(tq)) > 0)) /* the return value should be zero, otherwise go out*/
+				goto out;
+		}
+
+		/* Move data into the buffer. */
+		if ((space + written) > count) space = count - written;
+		if (copy_from_user(write_buf, buf, space)) {
+			up(&tq_sem);
+			return -EFAULT;
+		}
+		
+		for (i=0; i<space && !FULL(tq); i++) {
+			PUTCH(write_buf[i], tq); 
+			DEBUG(SCI_DEBUG_LEVEL3, "\nwirte_buf[%d]=0x%x",i,write_buf[i]);
+		}
+		
+/*		buf += space;
+		written += space;*/
+		buf += i;
+		written += i;
+
+		/* If no output is active, make it active. */
+		spin_lock_irqsave(&sci_lock, flags);
+		sci_start_output();
+		spin_unlock_irqrestore(&sci_lock, flags);
+	}
+
+	if (!EMPTY(tq)){
+		if (wait_event_interruptible(sci_empty_queue, sci_output_active == 0))
+			goto out;
+		sci_start_input();
+	}
+
+out:
+	*f_pos += written;
+	up(&tq_sem);
+	return written;
+}
+
+
+static void sci_do_tasklet(unsigned long rx_tx_flag)
+{
+	unsigned long flags;
+
+	if (rx_tx_flag == INT_RXTIDE || rx_tx_flag == INT_RDOUT || rx_tx_flag == INT_CHOUT){    /* processing for receive data */
+
+		spin_lock_irqsave(&sci_buffer_status_lock, flags);
+		if (sci_rx_buffer.sci_buffer_report_flag ==1 && sci_rx_buffer.sci_buffer_report_en == 1){
+			if (LEFT(rq) >= sci_rx_buffer.sci_buffer_threshold ){
+				wake_up_interruptible(&sci_read_ready);
+			}
+		}		
+		spin_unlock_irqrestore(&sci_buffer_status_lock, flags);
+		if (rx_tx_flag == INT_CHOUT) {
+			printk("SCI Attention info: Character timed out!\n");
+		}
+		DEBUG(SCI_DEBUG_LEVEL3, " rq.tail=%d, rq.head=%d\n",rq.tail,rq.head); 
+		wake_up_interruptible(&rq_queue);
+	}
+	else if (rx_tx_flag == INT_TXTIDE) { /* processing for transmit data */
+		spin_lock_irqsave(&sci_lock, flags);
+
+		/* Have we written everything? */
+		if (EMPTY(tq)) { /* empty */ /*The buffer size should be greater than 8 */
+			sci_output_active = 0;
+			wake_up_interruptible(&sci_empty_queue);
+			if( _sci_txfifocount(0) == 0 )	/* tx fifo empty, ready to rx mode */
+					sci_start_input();
+		}
+		else{
+			_sci_unmask_interrupt(0, INT_TXTIDE);
+		}
+		
+		wake_up_interruptible(&tq_queue);
+		
+		if (sci_tx_buffer.sci_buffer_report_flag ==1 && sci_tx_buffer.sci_buffer_report_en == 1){
+			if (LEFT(tq) < sci_tx_buffer.sci_buffer_threshold ){
+				wake_up_interruptible(&sci_write_ready);
+			}
+		}	
+		spin_unlock_irqrestore(&sci_lock, flags);
+	}
+	else if (rx_tx_flag == INT_ATRSTOUT )
+	{
+		if ( sci_input_active ){
+			receive_exception =1;
+			wake_up_interruptible(&rq_queue);
+			printk( "Information From Kernel: sci_do tasklet --> rx_tx_flag == 0x%x\n", (unsigned int)rx_tx_flag );	/* add for DeHe */
+		}
+	}
+
+
+	return;
+}
+
+static irqreturn_t sci_interrupt(int irq, void *dev_id)
+{
+	u16 int_status = sci_get_regs(SCI_RIS, 0);
+	unsigned char count_status;
+	unsigned char ch;
+	//int					timeout;
+	
+	if (int_status & INT_IN) { 
+		sci_set_regs(SCI_ICR, 0, INT_IN);  
+		card_inserted = 1; 		
+		card_inout_change = 1;
+/*		if(irq_sci_cardin == 0)
+		{
+			spin_lock_irqsave(&sci_lock, flags);
+			irq_sci_cardin = 1;
+			wake_up_interruptible(&CardInOut_queue);
+			spin_unlock_irqrestore(&sci_lock, flags);
+		}*/
+		DEBUG(SCI_DEBUG_LEVEL3, " INTR_CARDIN \n"); 	
+	}
+	else if (int_status & INT_OUT) { 
+		sci_set_regs(SCI_ICR, 0, INT_OUT); 
+		card_inserted = 0; 
+		clkicc_value = 0;
+		receive_exception =1;
+		wake_up_interruptible(&rq_queue);
+		wake_up_interruptible(&sci_empty_queue);
+		rq.head = 0;
+		rq.tail = 0;
+		tq.head = 0;
+		tq.tail = 0;
+
+		_sci_flush_txfifo(0);
+		_sci_flush_rxfifo(0);
+		sci_start_input();
+		
+		card_inout_change = 1;
+		DEBUG(SCI_DEBUG_LEVEL3, " INTR_CARDOUT \n"); 
+	}
+	else if (int_status & INT_PWUP) { 
+		sci_set_regs(SCI_ICR, 0, INT_PWUP);  
+		DEBUG( SCI_DEBUG_LEVEL3, " INTR_PWUP \n"); 
+	}
+	else if (int_status & INT_PWDN) { 
+		sci_set_regs(SCI_ICR, 0, INT_PWDN);  
+		sci_set_regs(SCI_TIDE, 0, 0x0011);
+		DEBUG( SCI_DEBUG_LEVEL3, " INTR_PWDN \n"); 
+	}
+	else if (int_status & INT_TRANSERR) { 
+		sci_set_regs(SCI_ICR, 0, INT_TRANSERR);  
+		_sci_flush_txfifo(0);
+		DEBUG( SCI_DEBUG_LEVEL3, " INTR_TRANSERR \n"); 
+	}
+	else if (int_status & INT_ATRSTOUT) { 
+		sci_set_regs(SCI_ICR, 0, INT_ATRSTOUT);  
+		DEBUG( SCI_DEBUG_LEVEL3, " INTR_ATRSTOUT \n"); 
+		card_noatr= 1;
+		sci_tasklet.data = INT_ATRSTOUT; /* register for receive timeout*/
+		tasklet_schedule(& sci_tasklet);  /* wakeup tasklet to execute*/
+		
+	}
+	else if (int_status & INT_ATRDTOUT) { 
+		sci_set_regs(SCI_ICR, 0, INT_ATRDTOUT);  
+		DEBUG( SCI_DEBUG_LEVEL3, " INTR_ATRDTOUT \n"); 
+	}
+	else if (int_status & INT_BLKOUT) { 
+		sci_set_regs(SCI_ICR, 0, INT_BLKOUT);  
+		DEBUG( SCI_DEBUG_LEVEL3, " INTR_BLKOUT \n"); 
+	}
+	else if (int_status & INT_CHOUT) { 
+		sci_set_regs(SCI_ICR, 0, INT_CHOUT);
+		count_status =_sci_rxfifocount(0); /* ensure all data has been stored in receive buffer */
+		while (count_status ){
+			PUTCH(_sci_read_date(0),rq);
+			count_status --;	
+		}
+		DEBUG( SCI_DEBUG_LEVEL3, " INTR_CHOUT \n"); 
+		sci_tasklet.data = INT_CHOUT; /* register for character timeout*/
+		tasklet_schedule(& sci_tasklet);  /* wakeup tasklet to execute*/
+	}
+	else if (int_status & INT_RDOUT) { 
+		sci_set_regs(SCI_ICR, 0, INT_RDOUT);  
+		DEBUG( SCI_DEBUG_LEVEL3, " INTR_RDOUT \n"); 
+		count_status =_sci_rxfifocount(0);
+		DEBUG( SCI_DEBUG_LEVEL3, "\nrxfifo-count[%02x], txfifo-count[%02x]\n", count_status,_sci_txfifocount(0));	
+		while (count_status ){
+			ch =_sci_read_date(0);
+			PUTCH(ch,rq);
+			DEBUG( SCI_DEBUG_LEVEL3, " [%02x]\n", ch);	
+			count_status --;	
+		}
+		sci_tasklet.data = INT_RDOUT; /* register for receive timeout*/
+		tasklet_schedule(& sci_tasklet);  /* wakeup tasklet to execute*/
+	}
+	else if (int_status & INT_OVERRUN) { 
+		sci_set_regs(SCI_ICR, 0, INT_OVERRUN);  
+		DEBUG( SCI_DEBUG_LEVEL3, " INTR_OVERRUN \n"); 
+	}
+	else if (int_status & INT_CLKSTOP) { 
+		sci_set_regs(SCI_ICR, 0, INT_CLKSTOP);  
+		DEBUG( SCI_DEBUG_LEVEL3, " INTR_CLKSTOP \n"); 
+	}
+	else if (int_status & INT_CLKACTIVE) { 
+		sci_set_regs(SCI_ICR, 0, INT_CLKACTIVE);  
+		DEBUG( SCI_DEBUG_LEVEL3, " INTR_CLKACTIVE \n"); 
+	}
+	else if (int_status & INT_RXTIDE) { 
+		sci_set_regs(SCI_ICR, 0, INT_RXTIDE); 
+		DEBUG( SCI_DEBUG_LEVEL3, " INTR_RXTIDE \n");
+		count_status =_sci_rxfifocount(0);
+		DEBUG( SCI_DEBUG_LEVEL3, "\nrxfifo-count[%02x], txfifo-count[%02x]\n", count_status,_sci_txfifocount(0));	
+		if (count_status == 0) { // should not happen, but for speical case
+			printk("count_status=%d, tide=0x%x\n", count_status, sci_get_regs(SCI_TIDE, 0));
+			_sci_flush_rxfifo(0);
+		}
+		while (count_status ){
+			ch =_sci_read_date(0);
+			PUTCH(ch,rq);
+			DEBUG( SCI_DEBUG_LEVEL3, " r[%02x]\n", ch);	
+			count_status --;	
+		}
+		sci_tasklet.data = INT_RXTIDE; /* register for receive*/
+		tasklet_schedule(& sci_tasklet);  /* wakeup tasklet to execute*/
+		}
+	else if (int_status & INT_TXTIDE) { 
+		sci_set_regs(SCI_ICR, 0, INT_TXTIDE); /* clr interrupt */
+		DEBUG( SCI_DEBUG_LEVEL3, " INTR_TXTIDE \n");
+		count_status = SCI_MAX_FIFOSIZE - _sci_txfifocount(0);
+		while (count_status && !EMPTY(tq)){
+			GETCH(tq, ch);
+			_sci_write_date(0, ch);
+			DEBUG( SCI_DEBUG_LEVEL3, " w[%02x]  ", ch );	
+			count_status --;	
+		}
+
+		if (EMPTY(tq)){
+			_sci_mask_interrupt(0, INT_TXTIDE);
+		/*timeout = 0x10000;
+		count_status = SCI_MAX_FIFOSIZE - _sci_txfifocount(0);
+		while( count_status && (timeout>0) ){
+					timeout--;
+					count_status = SCI_MAX_FIFOSIZE - _sci_txfifocount(0);
+					timeout--;
+		}*/
+			sci_start_input();
+		}
+			
+		sci_tasklet.data = INT_TXTIDE; /* register for transmation*/
+		tasklet_schedule(& sci_tasklet);  /* wakeup tasklet to execute*/
+		
+	}
+
+	return IRQ_HANDLED;
+}
+
+static struct file_operations sci_fops = {
+	.read = sci_read,
+	.write = sci_write,
+	.open = sci_open,
+	.release = sci_release,
+	.poll = sci_poll,
+	.ioctl = sci_ioctl,
+	.owner = THIS_MODULE
+};
+
+static struct miscdevice sci_dev = {
+	SCI_MINOR,
+	"smartcard",
+	&sci_fops,
+};
+
+static struct proc_dir_entry *sci_proc_entry = NULL;
+
+static int sci_proc_read(char *page, char **start, off_t off,
+		int count, int *eof, void *data)
+{
+	sprintf(page, "No define\n");
+	return strlen(page);
+}
+
+static int sci_proc_write(struct file *file, 
+		const char __user*buffer, unsigned long count, void *data)
+{
+	char cmd_line[25];
+
+	if (copy_from_user( cmd_line, buffer, count )) {
+    return -EFAULT;
+   }
+
+	if (strncmp("get", cmd_line, 3) == 0) {
+		unsigned short val = sci_get_regs(simple_strtol(&cmd_line[4], NULL, 16), 0);
+		printk("Get [0x%08x] = 0x%04x \n", (unsigned int)simple_strtol(&cmd_line[4], NULL, 16), val);
+	}
+	else if (strncmp("set", cmd_line, 3) == 0) {
+		unsigned short addr = simple_strtol(&cmd_line[4], NULL, 16);
+		unsigned short val = simple_strtol(&cmd_line[7], NULL, 16);
+		printk("Set [0x%04x] = 0x%02x \n", addr, val);
+		sci_set_regs(addr, 0, val);
+	}
+	
+	return count;
+}
+
+/*
+ * Module initialization
+ */
+int __init cs_sci_init(void)
+{
+	int error = 0;
+
+	error = misc_register(&sci_dev);
+	if (error) {
+		printk(KERN_ERR "smart card: unable to get misc minor\n");
+		return error;
+	}
+
+	sci_base = (unsigned short *)VA_SCI_BASE;
+	{
+		sci_proc_entry = create_proc_entry("sci_io", (mode_t)0, NULL);
+		if (NULL != sci_proc_entry) {
+			sci_proc_entry->write_proc = &sci_proc_write;
+			sci_proc_entry->read_proc = &sci_proc_read;
+		}
+	}
+
+	sema_init(&tq_sem, 1);
+
+	if ((sci_get_regs(SCI_RIS, 0) & INT_IN) != 0) {
+		card_inserted = 1;
+	}
+	else {
+		card_inserted = 0;
+	}
+	if ((error = request_irq(SCI_IRQ, sci_interrupt, IRQF_DISABLED, "smartcard", NULL)) != 0){
+		printk(KERN_ERR "smart card: request irq fails!\n");
+		
+	}
+
+	/* do something here */
+	/* ... ... */
+	rxtimeout = RXTIMEOUT_DEFAULT;
+	printk( "Celestial Smart Card interface initialized!\n");
+
+	return error;
+}
+
+static void __exit cs_sci_exit(void)
+{
+	misc_deregister(&sci_dev);
+	remove_proc_entry("sci_io", NULL);
+	free_irq(SCI_IRQ, NULL);
+	
+}
+
+module_init(cs_sci_init);
+module_exit(cs_sci_exit);
+
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/celestial/peripheral/cnc18xx_sec.c linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/peripheral/cnc18xx_sec.c
--- linux-linaro-3.4-2012.05-1_original/drivers/celestial/peripheral/cnc18xx_sec.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/peripheral/cnc18xx_sec.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,164 @@
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/delay.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/fcntl.h>
+#include <linux/spinlock.h>
+#include <linux/sched.h>
+#include <linux/proc_fs.h>
+#include <linux/errno.h>
+#include <linux/cdev.h>
+#include <linux/miscdevice.h>
+#include <linux/workqueue.h>
+#include <linux/preempt.h>
+#include <linux/interrupt.h>
+#include <linux/poll.h>
+
+#include <asm/uaccess.h>
+#include <asm/io.h>
+
+#define CNC18XX_SEC_BASE 0xfffff000
+#define CNC18XX_SEC_SIZE 0x50
+
+#define SEC_RD_OTP      13
+#define SEC_RD_UNIID    14
+
+#define WriteReg32(r, v) writel((v), cnc18xx_sec_base+(r))
+#define ReadReg32(r) readl(cnc18xx_sec_base+(r))
+
+static void __iomem *cnc18xx_sec_base;
+DEFINE_SPINLOCK(sec_lock);
+
+
+#if 0
+#define MAILBOX0 (0x00)
+#define MAILBOX1 (0x04)
+#define MAILBOX2 (0x08)
+#define MAILBOX3 (0x0C)
+#define MAILBOX4 (0x10)
+#define MAILBOX5 (0x14)
+#define MAILBOX6 (0x18)
+#define MAILBOX7 (0x1C)
+
+typedef struct SEC_UNI_KEY {
+    unsigned int ukey0;
+    unsigned int ukey1;
+    unsigned int ukey2;
+    unsigned int ukey3;
+    unsigned int pkey0;
+    unsigned int pkey1;
+    unsigned int pkey2;
+    unsigned int pkey3;
+} CSSEC_UNI_KEY;
+#endif
+
+static int
+cnc18xx_sec_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+{
+    unsigned long flags;
+    unsigned int ret = 0;
+
+    switch (cmd) {
+#if 0
+    case SEC_RD_OTP:
+        {
+            CSSEC_UNI_KEY *key = (CSSEC_UNI_KEY *) arg;
+
+            spin_lock_irqsave(&sec_lock, flags);
+            WriteReg32(MAILBOX1, 0x0);
+            WriteReg32(MAILBOX0, 0x80000010);
+            while(!(ReadReg32(MAILBOX7) & 0x80000000));
+            key->ukey0 = ReadReg32(MAILBOX2);  /* OTP0, Word 64 */
+            key->ukey1 = ReadReg32(MAILBOX3);  /* OTP0, Word 65 */
+            key->ukey2 = ReadReg32(MAILBOX4);  /* OTP0, Word 66 */
+            key->ukey3 = ReadReg32(MAILBOX5);  /* OTP0, Word 67 */
+            WriteReg32(MAILBOX7, 0x0);
+            WriteReg32(MAILBOX1, 0x0);
+            WriteReg32(MAILBOX0, 0x80000011);
+            while(!(ReadReg32(MAILBOX7) & 0x80000000));
+            key->pkey0 = ReadReg32(MAILBOX2);  /* OTP0, Word 68 */
+            key->pkey1 = ReadReg32(MAILBOX3);  /* OTP0, Word 69 */
+            key->pkey2 = ReadReg32(MAILBOX4);  /* OTP0, Word 70 */
+            key->pkey3 = ReadReg32(MAILBOX5);  /* OTP0, Word 71 */
+            WriteReg32(MAILBOX7, 0x0);
+            spin_unlock_irqrestore(&sec_lock, flags);
+        }
+        break;
+#endif
+
+    case SEC_RD_UNIID:
+        spin_lock_irqsave(&sec_lock, flags);
+        *(unsigned int *)arg = ReadReg32(0x14);  /* read unique id from 0xfffff014 */
+        spin_unlock_irqrestore(&sec_lock, flags);
+        break;
+
+    default:
+        return -EINVAL;
+    }
+
+    return ret;
+}
+
+static int
+cnc18xx_sec_open(struct inode *inode, struct file *file)
+{
+    return 0;
+}
+
+static int
+cnc18xx_sec_release(struct inode *inode, struct file *file)
+{
+    return 0;
+}
+
+
+static struct file_operations cnc18xx_sec_fops = {
+    .owner  = THIS_MODULE,
+    .ioctl  = cnc18xx_sec_ioctl,
+    .open   = cnc18xx_sec_open,
+    .release= cnc18xx_sec_release,
+};
+
+static struct miscdevice cnc18xx_sec_miscdev = {
+    MISC_DYNAMIC_MINOR,
+    "cnc18xx_sec",
+    &cnc18xx_sec_fops
+};
+
+int __init cnc18xx_sec_init(void)
+{
+    int ret = 0;
+
+    /* System init */
+    if (misc_register(&cnc18xx_sec_miscdev))
+        return -ENODEV;
+
+    cnc18xx_sec_base = ioremap(CNC18XX_SEC_BASE, CNC18XX_SEC_SIZE);
+    if (!cnc18xx_sec_base)
+        return -EIO;
+
+    return ret;
+}
+
+static void __exit cnc18xx_sec_exit(void)
+{
+    iounmap((void *)cnc18xx_sec_base);
+    misc_deregister(&cnc18xx_sec_miscdev);
+}
+
+module_init(cnc18xx_sec_init);
+module_exit(cnc18xx_sec_exit);
+
+/*----------------------------------------------------------------------------*/
+
+
+MODULE_AUTHOR("Sun He, <he.sun@celestialsemi.com>");
+MODULE_DESCRIPTION("Celestial Semiconductor Secure driver");
+MODULE_VERSION("1.0");
+MODULE_LICENSE("Dual BSD/GPL");
+
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/celestial/peripheral/cnc1900_fpc.c linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/peripheral/cnc1900_fpc.c
--- linux-linaro-3.4-2012.05-1_original/drivers/celestial/peripheral/cnc1900_fpc.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/peripheral/cnc1900_fpc.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,1318 @@
+/*
+Rev Date        Author      Comments
+--------------------------------------------------------------------------------
+
+*/
+
+//#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/miscdevice.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+//#include <mach/system.h>
+#include <linux/input.h>
+#include <linux/major.h>
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/proc_fs.h>
+#include <linux/poll.h>
+#include <mach/hardware.h>
+#include <asm/atomic.h>
+#include <asm/uaccess.h>
+#include <mach/pinmux.h>
+#include "cnc1900_fpc.h"
+
+MODULE_AUTHOR("Cavium Celestial SDK team");
+MODULE_DESCRIPTION("Cavium Celestial Front Panel Controller driver");
+MODULE_LICENSE("GPL");
+
+//#define REPEAT_PERIOD		150	/* NEC: 110ms, RC5: 114ms */
+
+/* Global variables */
+static unsigned short upcmd;
+
+static cs_rc_t *rc_dev;
+static struct proc_dir_entry *fpc_proc_entry = NULL;
+static void __iomem *cs_fpc_base;
+static int rc_system_code = 0xffffffff;
+DEFINE_SPINLOCK(cs_fpc_lock);
+
+#define fpc_writew(v,a)    	iowrite16(v, (cs_fpc_base + (a)))
+#define fpc_readw(a)       	ioread16((cs_fpc_base + (a)))
+
+///////wx///////////
+//#define CONFIG_RC_DEBUG
+struct timer_list fpc_rc_netgear_timer;
+static int fpc_rc_netgear_rpt=0;
+static int fpc_rc_netgear_rpt_tag=0;
+//static int fpc_rc_netgear_rpt_tag_cmd=0;
+
+
+///////wx//////////
+
+/* Predefined value */
+typedef struct {
+	unsigned int h_low;
+	unsigned int h_high;
+	unsigned int t_low;
+	unsigned int t_high;
+} pta_t;	/* protocal time ajust */
+
+/* NEC State Machine */
+#define NEC_HEAD   	    0
+#define NEC_REPEAT  	1
+#define NEC_ZERO    	2
+#define NEC_ONE     	3
+#define NEC_DROP   	    4
+
+#define NEC_ENTRY 4
+static pta_t pta_nec[NEC_ENTRY] = {
+	{ 8500, 9500, 12500, 14000 },	/* head */
+	{ 8500, 9500, 11000, 12000 },	/* repeat */
+	{ 400, 700, 1000, 1250 },	/* zero */
+	{ 400, 700, 2100, 2350 }	/* one */
+};
+
+/* SONY State Machine */
+#define SONY_HEAD   	    0
+
+#define SONY_ZERO    	1
+#define SONY_ONE     	2
+#define SONY_DROP   	    3
+
+
+static pta_t pta_sony[] = {
+	{ 2300, 2500, 2900, 3100 },	/* head */
+	{ 500, 700, 1100, 1300 },	/* zero */
+	{ 1100, 1300, 1700, 1900 }	/* one */
+};
+
+
+/* RC5 State Machine */
+#define RC5_ONE_BIT	0
+#define RC5_ZO_BITS	1
+#define RC5_OZ_BITS	2
+#define RC5_OZO_BITS	3
+#define RC5_DROP	4
+#define RC_OVERFLOW_FLAG 7
+
+static pta_t pta_rc5[] = {
+	{ 750, 1050, 1600, 1900 },	/* normal */
+	{ 750, 1050, 2400, 2720 },	/* zero one one */
+	{ 1600, 1800, 2300, 2720 },	/* one zero zero */
+	{ 1600, 1900, 3100, 3700 },	/* one zero one */
+};
+
+/* RC6 state machine */
+#define RC6_STATE_LEARDER        0
+#define RC6_STATE_ONE            1
+#define RC6_STATE_OhZ            2
+#define RC6_STATE_hZO            3
+#define RC6_STATE_hZOhZ          4
+#define RC6_STATE_hT0O           5
+#define RC6_STATE_hT0OhZ         6
+#define RC6_STATE_hO             7
+#define RC6_STATE_hZhO           8
+#define RC6_STATE_ERROR          10
+
+/* There is no T1 in Mode 6A, so no status of T1 in this status machine */
+/* In the second note '-' means v+ and '_' means v- */
+static pta_t pta_rc6[] = {
+	{ 2000, 2800, 3300, 3700 },	/* LEARDER 2667 3556 */ /* ------__ */
+	{  100,  550,  600, 1000 },	/* One 444 889 */ /* -_ */
+	{  100,  550, 1100, 1550 },	/* One & half Zero 444 1333 , also could be half Zero & half T0 */ /* -__ */
+	{  560, 1000, 1100, 1550 },	/* half Zero & One 889 1333 */ /* --_ */
+	{  560, 1000, 1600, 1900 },	/* half Zero & One & half Zero 889 1778 */ /* --__ */
+	{ 1100, 1600, 1600, 1900 },	/* half T0 & One 1333 1778 */ /* ---_ */
+	{ 1100, 1600, 2000, 2500 },	/* half T0 & One & half Zero 1333 2222 */ /* ---__ */
+	{  100,  550,    0,    0 },	/* half One 444 0 */ /* - */
+    {  560, 1000,    0,    0 }	/* half Zero & half One 889 0 */ /* -- */
+                                /* if the last bit is one, maybe can only get the first half */
+};
+
+#define RC6_LEADER_BIT        0x11
+#define RC6_ONE_BIT           0x12
+#define RC6_ZERO_BIT          0x13
+#define RC6_T0_BIT            0x14
+#define RC6_T1_BIT            0x15
+#define RC6_OZ_BIT            0x16
+#define RC6_ZO_BIT            0x17
+#define RC6_T0O_BIT           0x18
+/* End of RC6 state machine */
+
+static void netgear_nec_rc_rpt(unsigned long arg)
+{
+   
+   
+   if(fpc_rc_netgear_rpt==1)
+   	{
+   	   
+   	    rc_dev->record.cmd=0xfb;
+		        input_report_key(rc_dev->dev, upcmd, 0);
+				input_sync(rc_dev->dev);
+		        input_report_key(rc_dev->dev, rc_dev->record.cmd, 1);
+				input_report_key(rc_dev->dev, rc_dev->record.cmd, 0);
+				input_sync(rc_dev->dev);
+				
+   	}
+   if(fpc_rc_netgear_rpt_tag==0 && fpc_rc_netgear_rpt==2)
+	{
+       
+   	    rc_dev->record.cmd=0xfb;
+		        input_report_key(rc_dev->dev, upcmd, 0);
+				input_sync(rc_dev->dev);
+		        input_report_key(rc_dev->dev, rc_dev->record.cmd, 1);
+				input_report_key(rc_dev->dev, rc_dev->record.cmd, 0);
+				input_sync(rc_dev->dev);
+				
+			
+	}
+  
+	
+   
+}
+
+/* Decode protocal */
+static int cnc_nec_decode_bit(unsigned int high_val, unsigned int total_val)
+{
+	int ret = NEC_DROP;
+
+	if((high_val >= pta_nec[NEC_HEAD].h_low) &&
+			(high_val <= pta_nec[NEC_HEAD].h_high) &&
+			(total_val >= pta_nec[NEC_HEAD].t_low) &&
+			(total_val <= pta_nec[NEC_HEAD].t_high)) {
+
+		PDEBUG("NEC_HEAD: high_val: %d, total_val: %d--NEC HEAD\n", high_val, total_val);
+		ret = NEC_HEAD;
+
+	} else if((high_val >= pta_nec[NEC_REPEAT].h_low) &&
+			(high_val <= pta_nec[NEC_REPEAT].h_high) &&
+			(total_val >= pta_nec[NEC_REPEAT].t_low) &&
+			(total_val <= pta_nec[NEC_REPEAT].t_high)) {
+
+		PDEBUG("NEC_REPEAT: high_val: %d, total_val: %d--NEC REPEAT\n", high_val, total_val);
+		ret = NEC_REPEAT;
+
+	} else if((high_val >= pta_nec[NEC_ZERO].h_low) &&
+			(high_val <= pta_nec[NEC_ZERO].h_high) &&
+			(total_val >= pta_nec[NEC_ZERO].t_low) &&
+			(total_val <= pta_nec[NEC_ZERO].t_high)) {
+
+		PDEBUG("NEC_ZERO: high_val: %d, total_val: %d--NEC ZERO\n", high_val, total_val);
+		ret = NEC_ZERO;
+
+	} else if ((high_val >= pta_nec[NEC_ONE].h_low) &&
+			(high_val <= pta_nec[NEC_ONE].h_high) &&
+			(total_val >= pta_nec[NEC_ONE].t_low) &&
+			(total_val <= pta_nec[NEC_ONE].t_high)) {
+
+		PDEBUG("NEC_ONE : high_val: %d, total_val: %d--NEC ONE\n", high_val, total_val);
+		ret = NEC_ONE;
+
+	} else {
+
+		PDEBUG("NECXXXXXXXXX_DROP: high_val: %d, total_val: %d--NEC DROP\n", high_val, total_val);
+		ret = NEC_DROP;
+	}
+
+	return ret;
+}
+
+static int cnc_nec_decode(int idx)
+{
+	int nec_st;
+
+	PDEBUG("idx %2d ", idx);
+	//printk("idx %2d ", idx);
+	nec_st = cnc_nec_decode_bit(rc_dev->fifo1[idx], rc_dev->fifo2[idx]);
+
+	switch(rc_dev->record.decode_period) {
+		case HEAD_PERIOD:              /* Head Period */
+			switch (nec_st) {
+				case NEC_HEAD:
+					rc_dev->record.bit = 0;
+					rc_dev->record.rpt = 0;
+					rc_dev->record.decode_period = ADDR_PERIOD;
+					break;
+
+				case NEC_REPEAT:
+					rc_dev->record.bit = 0;
+
+					// rc_dev->max_rpt = 2; /* FIXME: To be set outside */
+#if 1
+					if (rc_dev->record.rpt == (rc_dev->max_rpt-1)) {
+						rc_dev->record.rpt = 0;
+						
+						return 2;
+					} else {
+						rc_dev->record.rpt++;
+					}
+#else	/* for test */
+					rc_dev->record.rpt++;
+					return 1;
+#endif
+					rc_dev->record.decode_period = HEAD_PERIOD;
+					break;
+
+
+				case NEC_DROP:
+				case NEC_ZERO:
+				case NEC_ONE:
+				default:
+					rc_dev->record.bit = 0;
+					//					rc_dev->record.rpt =0;
+					//                    rc_dev->record.decode_period = HEAD_PERIOD;
+			}
+
+			break;
+
+		case ADDR_PERIOD:        /* Address Period */
+			switch (nec_st) {
+				case NEC_HEAD:
+					rc_dev->record.bit = 0;
+					rc_dev->record.rpt = 0;
+					rc_dev->record.decode_period = HEAD_PERIOD;
+					return 0;
+				case NEC_REPEAT:
+					rc_dev->record.rpt++;
+					rc_dev->record.decode_period = HEAD_PERIOD;
+					break;
+				case NEC_DROP:
+					rc_dev->record.bit = 0;
+					rc_dev->record.rpt = 0;
+					rc_dev->record.decode_period = HEAD_PERIOD;
+					break;
+				case NEC_ZERO:
+					__clear_bit(rc_dev->record.bit, (unsigned long *)&rc_dev->record.addr);
+					break;
+				case NEC_ONE:
+					__set_bit(rc_dev->record.bit, (unsigned long *)&rc_dev->record.addr);
+					break;
+			}
+
+			if(rc_dev->record.bit == (16-1)) {
+				
+				rc_dev->record.bit = 0;
+				rc_dev->record.addr = rc_dev->record.addr & 0xffff;
+				rc_dev->record.decode_period = CMD_PERIOD;	/* FIXME: Sun: temparary enable cmd process */
+			} else {
+				rc_dev->record.bit++;
+			}
+#if 0
+			if(rc_dev->addr == rc_dev->record.addr)
+				rc_dev->record.decode_period = CMD_PERIOD;
+			else
+				rc_dev->record.decode_period = HEAD_PERIOD;
+#endif
+
+			break;
+
+		case CMD_PERIOD:                                           /* Command Period */
+			switch (nec_st) {
+				case NEC_HEAD:
+					rc_dev->record.bit = 0;
+					rc_dev->record.rpt = 0;
+					rc_dev->record.decode_period = HEAD_PERIOD;
+					return 0;
+				case NEC_REPEAT:
+				case NEC_DROP:
+					rc_dev->record.bit = 0;
+					rc_dev->record.rpt = 0;
+					rc_dev->record.decode_period = HEAD_PERIOD;
+					break;
+				case NEC_ZERO:
+					__clear_bit(rc_dev->record.bit, (unsigned long *)&rc_dev->record.cmd);
+					break;
+				case NEC_ONE:
+					__set_bit(rc_dev->record.bit, (unsigned long *)&rc_dev->record.cmd);
+					break;
+			}
+
+			if(rc_dev->record.bit == (16-1)) {
+				
+				rc_dev->record.bit = 0;
+				rc_dev->record.cmd = rc_dev->record.cmd & 0xff;
+				rc_dev->record.decode_period = HEAD_PERIOD;
+				
+				return 1;
+			} else {
+				rc_dev->record.bit++;
+			}
+
+			break;
+
+		default:
+			;
+	}
+
+	return 0;
+}
+
+static int cnc_sony_decode_bit(unsigned int high_val, unsigned int total_val)
+{
+	int ret = SONY_DROP;
+
+	if((high_val >= pta_sony[SONY_HEAD].h_low) &&
+			(high_val <= pta_sony[SONY_HEAD].h_high) &&
+			(total_val >= pta_sony[SONY_HEAD].t_low) &&
+			(total_val <= pta_sony[SONY_HEAD].t_high)) {
+
+		PDEBUG("SONY_HEAD: high_val: %d, total_val: %d--SONY HEAD\n", high_val, total_val);
+        //printk("SONY_HEAD: high_val: %d, total_val: %d--SONY HEAD\n", high_val, total_val);
+		ret = SONY_HEAD;
+
+	} else if((high_val >= pta_sony[SONY_ZERO].h_low) &&
+			(high_val <= pta_sony[SONY_ZERO].h_high) &&
+			(total_val >= pta_sony[SONY_ZERO].t_low) &&
+			(total_val <= pta_sony[SONY_ZERO].t_high)) {
+
+		PDEBUG("SONY_ZERO: high_val: %d, total_val: %d--SONY ZERO\n", high_val, total_val);
+		//printk("SONY_ZERO: high_val: %d, total_val: %d--SONY ZERO\n", high_val, total_val);
+		ret = SONY_ZERO;
+
+	} else if ((high_val >= pta_sony[SONY_ONE].h_low) &&
+			(high_val <= pta_sony[SONY_ONE].h_high) &&
+			(total_val >= pta_sony[SONY_ONE].t_low) &&
+			(total_val <= pta_sony[SONY_ONE].t_high)) {
+
+		PDEBUG("SONY_ONE : high_val: %d, total_val: %d--SONY ONE\n", high_val, total_val);
+		//printk("SONY_ONE : high_val: %d, total_val: %d--SONY ONE\n", high_val, total_val);
+		ret = SONY_ONE;
+
+	} else {
+
+		PDEBUG("SONYXXXXXXXXX_DROP: high_val: %d, total_val: %d--SONY DROP\n", high_val, total_val);
+		//printk("SONYXXXXXXXXX_DROP: high_val: %d, total_val: %d--SONY DROP\n", high_val, total_val);
+		ret = SONY_DROP;
+	}
+
+	return ret;
+}
+
+static int cnc_sony_decode(int idx)
+{
+	int sony_st;
+
+	PDEBUG("idx %2d ", idx);
+	//printk("idx %2d ", idx);
+	sony_st = cnc_sony_decode_bit(rc_dev->fifo1[idx], rc_dev->fifo2[idx]);
+
+	switch(rc_dev->record.decode_period) {
+		case HEAD_PERIOD:              /* Head Period */
+			switch (sony_st) {
+				case SONY_HEAD:
+					rc_dev->record.bit = 0;
+					//rc_dev->record.rpt = 0;
+					rc_dev->record.decode_period = CMD_PERIOD;
+					break;
+
+				
+
+
+				case SONY_DROP:
+				case SONY_ZERO:
+				case SONY_ONE:
+				default:
+					rc_dev->record.bit = 0;
+					//					rc_dev->record.rpt =0;
+					//                    rc_dev->record.decode_period = HEAD_PERIOD;
+			}
+
+			break;
+
+		case CMD_PERIOD:        /* Address Period */
+			switch (sony_st) {
+				case SONY_HEAD:
+					rc_dev->record.bit = 0;
+					//rc_dev->record.rpt = 0;
+					rc_dev->record.decode_period = HEAD_PERIOD;
+					return 0;
+				
+				case SONY_DROP:
+					rc_dev->record.bit = 0;
+					rc_dev->record.rpt = 0;
+					rc_dev->record.decode_period = HEAD_PERIOD;
+					break;
+				case SONY_ZERO:
+					__clear_bit(rc_dev->record.bit, (unsigned long *)&rc_dev->record.cmd);
+					break;
+				case SONY_ONE:
+					__set_bit(rc_dev->record.bit, (unsigned long *)&rc_dev->record.cmd);
+					break;
+			}
+            
+			if(rc_dev->record.bit == 6) {
+				
+				rc_dev->record.bit = 0;
+				rc_dev->record.cmd = rc_dev->record.cmd & 0xff;
+				rc_dev->record.decode_period = ADDR_PERIOD;	/* FIXME: Sun: temparary enable cmd process */
+			} else {
+				rc_dev->record.bit++;
+			}
+#if 0
+			if(rc_dev->addr == rc_dev->record.addr)
+				rc_dev->record.decode_period = CMD_PERIOD;
+			else
+				rc_dev->record.decode_period = HEAD_PERIOD;
+#endif
+
+			break;
+
+		case ADDR_PERIOD:                                           /* Command Period */
+			switch (sony_st) {
+				case SONY_HEAD:
+					rc_dev->record.bit = 0;
+					rc_dev->record.rpt = 0;
+					rc_dev->record.decode_period = HEAD_PERIOD;
+					return 0;
+				
+				case SONY_DROP:
+					rc_dev->record.bit = 0;
+					rc_dev->record.rpt = 0;
+					rc_dev->record.decode_period = HEAD_PERIOD;
+					break;
+				case SONY_ZERO:
+					__clear_bit(rc_dev->record.bit, (unsigned long *)&rc_dev->record.addr);
+					break;
+				case SONY_ONE:
+					__set_bit(rc_dev->record.bit, (unsigned long *)&rc_dev->record.addr);
+					break;
+			}
+
+            
+			if(rc_dev->record.bit == 4) {
+				
+				rc_dev->record.bit = 0;
+				rc_dev->record.addr = rc_dev->record.addr & 0xff;
+				rc_dev->record.decode_period = EXTEND_PERIOD;
+				
+				
+			} else {
+				rc_dev->record.bit++;
+			}
+
+			break;
+
+		case EXTEND_PERIOD:                                           /* Command Period */
+			switch (sony_st) {
+				case SONY_HEAD:
+					rc_dev->record.bit = 0;
+					rc_dev->record.rpt = 0;
+					rc_dev->record.decode_period = HEAD_PERIOD;
+					return 0;
+				
+				case SONY_DROP:
+					rc_dev->record.bit = 0;
+					rc_dev->record.rpt = 0;
+					rc_dev->record.decode_period = HEAD_PERIOD;
+					break;
+				case SONY_ZERO:
+					//clear_bit(rc_dev->record.bit, (unsigned long *)&rc_dev->record.cmd);
+					break;
+				case SONY_ONE:
+					//set_bit(rc_dev->record.bit, (unsigned long *)&rc_dev->record.cmd);
+					break;
+			}
+
+            
+			if(rc_dev->record.bit == 6) {
+				
+				rc_dev->record.bit = 0;
+				//rc_dev->record.cmd = rc_dev->record.cmd & 0xff;
+				rc_dev->record.decode_period = HEAD_PERIOD;
+				
+				return 1;
+			} else {
+				rc_dev->record.bit++;
+			}
+
+			break;
+
+		default:
+			;
+	}
+
+	return 0;
+}
+
+
+/*RC5 Decorder*/
+static unsigned int cnc_rc5_decode_bit(unsigned int high_val,unsigned int total_val)
+{
+	int ret = RC5_DROP;
+
+	if(((high_val >= pta_rc5[RC5_ONE_BIT].h_low) &&
+				(high_val <= pta_rc5[RC5_ONE_BIT].h_high)) &&
+
+			(((total_val >= pta_rc5[RC5_ONE_BIT].t_low) &&
+			  (total_val <= pta_rc5[RC5_ONE_BIT].t_high)) ||
+
+			 rc_dev->record.bit == 13)) { /* total_val equal 0 , this means received last  one bit, (one or zero) */
+
+		PDEBUG("RC5_ONE_BIT: bit: %d, high_val: %d, total_val: %d\n", rc_dev->record.bit, high_val, total_val);
+		ret = RC5_ONE_BIT;
+
+	} else if((high_val >= pta_rc5[RC5_ZO_BITS].h_low) &&
+			(high_val <= pta_rc5[RC5_ZO_BITS].h_high) &&
+			(total_val >= pta_rc5[RC5_ZO_BITS].t_low) &&
+			(total_val <= pta_rc5[RC5_ZO_BITS].t_high)) {
+
+		PDEBUG("RC5_ZO_BITS: bit: %d, high_val: %d, total_val: %d\n", rc_dev->record.bit, high_val, total_val);
+		ret = RC5_ZO_BITS;
+
+	} else if(((high_val >= pta_rc5[RC5_OZ_BITS].h_low) &&
+				(high_val <= pta_rc5[RC5_OZ_BITS].h_high)) &&
+
+			(((total_val >= pta_rc5[RC5_OZ_BITS].t_low) &&
+			  (total_val <= pta_rc5[RC5_OZ_BITS].t_high)) ||
+
+			 rc_dev->record.bit == 12)) { /* total_val equal 0, it means received both one and zero bits */
+
+		PDEBUG("RC5_OZ_BITS: bit: %d, high_val: %d, total_val: %d\n", rc_dev->record.bit, high_val, total_val);
+		ret = RC5_OZ_BITS;
+
+	} else if((high_val >= pta_rc5[RC5_OZO_BITS].h_low) &&
+			(high_val <= pta_rc5[RC5_OZO_BITS].h_high) &&
+			(total_val >= pta_rc5[RC5_OZO_BITS].t_low) &&
+			(total_val <= pta_rc5[RC5_OZO_BITS].t_high)) {
+
+		PDEBUG("RC5_OZO_BITS: bit: %d, high_val: %d, total_val: %d\n", rc_dev->record.bit, high_val, total_val);
+		ret = RC5_OZO_BITS;
+
+	} else {
+
+		PDEBUG("RC5XXXXXXXXX_DROP: bit: %d, high_val: %d, total_val: %d\n", rc_dev->record.bit, high_val, total_val);
+		ret = RC5_DROP;
+	}
+
+	return ret;
+}
+
+static unsigned int cnc_rc5_decode(int idx)
+{
+	int rc5_st;
+	int toggle;
+
+	PDEBUG("idx %2d ", idx);
+	rc5_st = cnc_rc5_decode_bit(rc_dev->fifo1[idx], rc_dev->fifo2[idx]);
+
+	switch (rc5_st) {
+		case RC5_ONE_BIT:
+			rc_dev->record.rc5_data <<= 1;
+			if (! rc_dev->record.next_bit_is_zero)
+				rc_dev->record.rc5_data |= 1;
+			rc_dev->record.bit += 1;
+			break;
+		case RC5_ZO_BITS:
+			rc_dev->record.rc5_data <<= 1;
+			//rc_dev->record.rc5_data |= 1;
+			rc_dev->record.next_bit_is_zero = 0;
+			rc_dev->record.bit += 1;
+			break;
+		case RC5_OZ_BITS:
+			rc_dev->record.rc5_data <<= 2;
+			rc_dev->record.rc5_data |= 2;
+			rc_dev->record.next_bit_is_zero = 1;
+			rc_dev->record.bit += 2;
+			break;
+		case RC5_OZO_BITS:
+			rc_dev->record.rc5_data <<= 2;
+			rc_dev->record.rc5_data |= 2;
+			rc_dev->record.next_bit_is_zero = 0;
+			rc_dev->record.bit += 2;
+			break;
+		default:	/* Error occurs */
+			rc_dev->record.bit = 0;
+			rc_dev->record.next_bit_is_zero = 0;
+			rc_dev->bit_err = 1;
+	}
+
+	if (rc_dev->record.bit == 14) {	/* Ok, we received all bits */
+
+		rc_dev->record.addr = (rc_dev->record.rc5_data & 0x07c0) >> 6;
+		rc_dev->record.cmd = rc_dev->record.rc5_data & 0x003f;
+		toggle = (rc_dev->record.rc5_data & 0x0800) ? 1: 0;
+
+		PDEBUG ("bit : %d, rc5_data: 0x%4x, toggle: %x, addr %x, cmd %x\n",
+				rc_dev->record.bit, rc_dev->record.rc5_data, toggle, rc_dev->record.addr, rc_dev->record.cmd);
+
+#if 0
+		/* Handle repeat */
+		if (rc_dev->record.pre_T == toggle && rc_dev->record.rpt++ != 0) {
+			if (rc_dev->record.rpt < 3) {
+				rc_dev->record.bit = 0;
+				rc_dev->record.next_bit_is_zero = 0;
+				return 0;
+			} else {
+				rc_dev->record.pre_T = toggle;
+			}
+		}
+#endif
+
+		rc_dev->record.rpt = 0;
+		rc_dev->record.bit = 0;
+		rc_dev->record.next_bit_is_zero = 0;
+		return 1;
+	}
+
+	return 0;
+}
+
+static unsigned int cnc_rc6_mode6a_decode_bit(unsigned int high_val, unsigned int total_val)
+{
+	int ret = RC6_STATE_ERROR;
+
+    return ret;
+}
+
+/* this part is defined by OEM */
+static unsigned int cnc_rc6_mode6a_decode(int idx)
+{
+	return 0;
+}
+
+#if 0
+static unsigned int cnc_rcmm_decode(struct cnc_rc *rc)
+{
+	unsigned int ret;
+	PDEBUG("The protocol type %d is not a valid type\n",cnc_rc_gbl->protocal);
+	ret=0;
+	return ret;
+}
+static unsigned int cnc_recs80_decode(struct cnc_rc *rc)
+{
+	unsigned int ret;
+	PDEBUG("The protocol type %d is not a valid type\n",cnc_rc_gbl->protocal);
+	ret=0;
+	return ret;
+}
+static unsigned int cnc_rca_decode(struct cnc_rc *rc)
+{
+	unsigned int ret;
+	PDEBUG("The protocol type %d is not a valid type\n",cnc_rc_gbl->protocal);
+	ret=0;
+	return ret;
+}
+static unsigned int cnc_xsat_decode(struct cnc_rc *rc)
+{
+	unsigned int ret;
+	PDEBUG("The protocol type %d is not a valid type\n",cnc_rc_gbl->protocal);
+	ret=0;
+	return ret;
+}
+
+static unsigned int cnc_jvc_decode(struct cnc_rc *rc)
+{
+	unsigned int ret;
+	PDEBUG("The protocol type %d is not a valid type\n",cnc_rc_gbl->protocal);
+	ret=0;
+	return ret;
+}
+
+static unsigned int cnc_nrc17_decode(struct cnc_rc *rc)
+{
+	unsigned int ret;
+	PDEBUG("The protocol type %d is not a valid type\n",cnc_rc_gbl->protocal);
+	ret=0;
+	return ret;
+}
+
+static unsigned int cnc_sharp_decode(struct cnc_rc *rc)
+{
+	unsigned int ret;
+	PDEBUG("The protocol type %d is not a valid type\n",cnc_rc_gbl->protocal);
+	ret=0;
+	return ret;
+}
+static unsigned int cnc_sirc_decode(struct cnc_rc *rc)
+{
+	unsigned int ret;
+	PDEBUG("The protocol type %d is not a valid type\n",cnc_rc_gbl->protocal);
+	ret=0;
+	return ret;
+}
+
+static unsigned int cnc_itt_decode(struct cnc_rc *rc)
+{
+	unsigned int ret;
+	PDEBUG("The protocol type %d is not a valid type\n",cnc_rc_gbl->protocal);
+	ret=0;
+	return ret;
+}
+#endif
+
+
+static void rc_do_tasklet(unsigned long data)
+{
+	unsigned long flags;
+	int idx;
+	int got_data = 0;
+
+	
+#ifdef CONFIG_RC_DEBUG	/* Print the fifo count */
+	int i;
+	for (i = 0; i < rc_dev->fc_idx; i++)
+		PDEBUG("  FIFO COUNT fifo1_cnt: %d, fifo2_cnt: %d\n", rc_dev->fc[i][0], rc_dev->fc[i][1]);
+	spin_lock_irqsave(&rc_dev->lock, flags);
+	rc_dev->fc_idx = 0;
+	spin_unlock_irqrestore(&rc_dev->lock, flags);
+	PDEBUG("***************  f1_idx: %d, f2_idx: %d ***************\n", rc_dev->f1_idx, rc_dev->f2_idx);
+#endif
+
+    //printk("((((***************  f1_idx: %d, f2_idx: %d ***************\n", rc_dev->f1_idx, rc_dev->f2_idx);
+	for (idx = 0; idx < rc_dev->f2_idx || idx< rc_dev->f1_idx; idx++) {
+       
+		
+		if (rc_dev->bit_err)
+			{
+			
+			break;
+			}
+
+		switch (rc_dev->protocal) {
+            case SONY:
+				 got_data = cnc_sony_decode(idx);
+				break;
+			case NEC:
+				got_data = cnc_nec_decode(idx);
+				break;
+			case RC5:
+				got_data = cnc_rc5_decode(idx);
+				break;
+			case RC6_6A:
+				got_data = cnc_rc6_mode6a_decode(idx);
+				break;
+#if 0
+			case TYPE_RCMM:
+				decoder_status=cnc_rcmm_decode(rc_dev);
+				break;
+			case TYPE_RECS80:
+				decoder_status=cnc_recs80_decode(rc_dev);
+				break;
+			case TYPE_RCA:
+				decoder_status=cnc_rca_decode(rc_dev);
+				break;
+			case TYPE_XSAT:
+				decoder_status=cnc_xsat_decode(rc_dev);
+				break;
+			case TYPE_JVC:
+				decoder_status=cnc_jvc_decode(rc_dev);
+				break;
+			case TYPE_NRC17:
+				decoder_status=cnc_nrc17_decode(rc_dev);
+				break;
+			case TYPE_SHARP:
+				decoder_status=cnc_sharp_decode(rc_dev);
+				break;
+			case TYPE_SIRC:
+				decoder_status=cnc_sirc_decode(rc_dev);
+				break;
+			case TYPE_ITT:
+				decoder_status=cnc_itt_decode(rc_dev);
+				break;
+#endif
+			default:
+				PDEBUG("The protocol type %d is not a valid type\n",rc_dev->protocal);
+		}
+
+		/* FIXME: this value should be determined outside */
+		if(got_data) {
+			//printk("\nYES YES YES Got it! bit: %x rpt: %x addr: %x, cmd: %x\n\n",
+					//rc_dev->record.bit, rc_dev->record.rpt, rc_dev->record.addr, rc_dev->record.cmd);
+
+		   if(rc_dev->protocal == NEC)
+		   	{
+           fpc_rc_netgear_rpt=got_data;
+
+
+           if(fpc_rc_netgear_rpt==1)
+           	{
+           	   
+		       mod_timer(&fpc_rc_netgear_timer,jiffies+ msecs_to_jiffies(300));
+           	}
+		
+		     if(fpc_rc_netgear_rpt==2)
+           	{
+           	   fpc_rc_netgear_rpt_tag=1;
+		       mod_timer(&fpc_rc_netgear_timer,jiffies+ msecs_to_jiffies(450));
+           	}
+		   
+		   	}
+			if ((0xffffffff == rc_system_code) ||
+					((rc_dev->record.addr & 0xff)   == rc_system_code) ||
+					((rc_dev->record.addr & 0xff00) == rc_system_code) ||
+					(rc_dev->record.addr == rc_system_code)) {
+
+					upcmd=rc_dev->record.cmd;
+						
+				input_report_key(rc_dev->dev, rc_dev->record.cmd, 1);
+				//input_report_key(rc_dev->dev, rc_dev->record.cmd, 0);
+				input_sync(rc_dev->dev);
+			}
+		}
+        if(rc_dev->protocal == NEC)
+        	{
+		fpc_rc_netgear_rpt_tag=0;
+        	}
+		
+	}
+
+	spin_lock_irqsave(&rc_dev->lock, flags);
+	/* When data is handled, clear the fifo, and reset err state */
+	rc_dev->bit_err = 0;
+	rc_dev->f1_idx = rc_dev->f2_idx = 0;
+#if 0
+	memset(rc_dev->fifo1, 0, ARRAY_SIZE(rc_dev->fifo1));
+	memset(rc_dev->fifo2, 0, ARRAY_SIZE(rc_dev->fifo2));
+#endif
+	spin_unlock_irqrestore(&rc_dev->lock, flags);
+}
+
+static irqreturn_t rc_dev_interrupt(int irq, void *dev_id)
+{
+	unsigned long  flags;
+	int intr_status;
+	int fifo1_cnt, fifo2_cnt;
+
+	intr_status = fpc_readw(FPC_INTS_L);
+	if ((intr_status & 0x1) || (intr_status & 0x4)) {	/* rc available | timeout */
+		spin_lock_irqsave(&rc_dev->lock, flags);
+
+		fifo1_cnt = fpc_readw(FPC_RC_FIFO1_CNT_L) & 0xf;
+		fifo2_cnt = fpc_readw(FPC_RC_FIFO2_CNT_L) & 0xf;
+
+		if (fifo1_cnt >=  RC_OVERFLOW_FLAG || fifo2_cnt >= RC_OVERFLOW_FLAG) {
+			while(fifo1_cnt --) {
+				fpc_readw(FPC_RC_FIFO1_L);
+			}
+
+			while(fifo2_cnt --) {
+				fpc_readw(FPC_RC_FIFO2_L);
+			}
+			rc_dev->f1_idx = 0;
+			rc_dev->f2_idx = 0;
+		} else {
+			while(fifo1_cnt --) {
+				rc_dev->fifo1[rc_dev->f1_idx++] = fpc_readw(FPC_RC_FIFO1_L);
+				if (rc_dev->f1_idx == FIFO_LEN) rc_dev->f1_idx = 0;
+			}
+			while(fifo2_cnt --) {
+				rc_dev->fifo2[rc_dev->f2_idx++] = fpc_readw(FPC_RC_FIFO2_L);
+				if (rc_dev->f2_idx == FIFO_LEN) rc_dev->f2_idx = 0;
+			}
+		}
+
+		rc_dev->tasklet.data = (unsigned int)0; /* FIXME: to be modified */
+		tasklet_schedule(&rc_dev->tasklet);
+
+		spin_unlock_irqrestore(&rc_dev->lock, flags);
+
+	} else if (intr_status & 0x2) {
+		static unsigned long ticks = 0;
+		unsigned long curr_ticks = jiffies;
+
+		if (curr_ticks - ticks > 23) {
+			rc_dev->record.cmd = fpc_readw(FPC_KSCAN_DATA_L) & 0xff;
+			rc_dev->record.cmd |= 0x100;
+
+			if (rc_dev->record.cmd & 0x80) {
+				spin_lock_irqsave(&rc_dev->lock, flags);
+
+				input_report_key(rc_dev->dev, rc_dev->record.cmd, 1);
+				input_report_key(rc_dev->dev, rc_dev->record.cmd, 0);
+				input_sync(rc_dev->dev);
+
+				spin_unlock_irqrestore(&rc_dev->lock, flags);
+			}
+
+			ticks = curr_ticks;
+		}
+	}
+
+	return IRQ_HANDLED;
+}
+
+static int cs_fpc_ioctl(struct inode *inode, struct file *file,
+	unsigned int cmd, unsigned long arg)
+{
+	unsigned long flags,userbit,Key_Val;
+	unsigned short rc_ctl, btc;
+	//    unsigned long *arg_temp = (unsigned long *)arg;
+	switch (cmd) {
+		case FPC_LED_EN:
+			spin_lock_irqsave(&cs_fpc_lock, flags);
+
+            fpc_writew(0!=arg ? 0x8000:0x0000, FPC_LED_CNTL_H);
+            fpc_writew(0xff, FPC_LED_CNTL_L);
+            pinmux_update_fpc_status();
+
+			spin_unlock_irqrestore(&cs_fpc_lock, flags);
+
+			break;
+
+		case FPC_LED_DISP:
+			spin_lock_irqsave(&cs_fpc_lock, flags);
+
+			fpc_writew((arg >> 16) & 0xffff, FPC_LED_DATA_H);
+			fpc_writew(arg & 0xffff, FPC_LED_DATA_L);
+
+			spin_unlock_irqrestore(&cs_fpc_lock, flags);
+
+			break;
+		case FPC_LED_GET:
+			spin_lock_irqsave(&cs_fpc_lock, flags);
+			userbit = fpc_readw(FPC_LED_DATA_H);
+			userbit = userbit << 16;
+			userbit |= fpc_readw(FPC_LED_DATA_L);
+            spin_unlock_irqrestore(&cs_fpc_lock, flags);
+
+			copy_to_user((unsigned long *)arg, &userbit, 4);
+			break;
+
+		case FPC_RC_SET_SYSTEMCODE:
+			spin_lock_irqsave(&cs_fpc_lock, flags);
+			rc_system_code = arg;
+			spin_unlock_irqrestore(&cs_fpc_lock, flags);
+
+			break;
+		case FPC_KEYSCAN_EN:
+			spin_lock_irqsave(&cs_fpc_lock, flags);
+			fpc_writew(arg & 0xffff,FPC_KSCAN_CNTL_L);
+			fpc_writew((arg << 15) & 0xffff,FPC_LED_CNTL_H);
+			spin_unlock_irqrestore(&cs_fpc_lock, flags);
+            pinmux_update_fpc_status();
+			break;
+		case FPC_KSCAN_GET:
+			spin_lock_irqsave(&cs_fpc_lock, flags);
+			Key_Val = fpc_readw(FPC_KSCAN_DATA_H);
+			Key_Val = Key_Val << 16;
+			Key_Val |= fpc_readw(FPC_KSCAN_DATA_L);
+			spin_unlock_irqrestore(&cs_fpc_lock, flags);
+
+			copy_to_user((unsigned long*)arg, &Key_Val, 4);
+			break;
+		case FPC_RC_EN:
+			spin_lock_irqsave(&cs_fpc_lock, flags);
+			rc_ctl = fpc_readw(FPC_RC_CTL_H);
+			if (arg == 1){
+				fpc_writew(rc_ctl | 0x8000, FPC_RC_CTL_H);
+                //			cnc_gpio_register_module_set("RC", 1);
+   			}
+			else if (arg == 0){
+				fpc_writew(rc_ctl & 0x7fff,FPC_RC_CTL_H);
+                //		cnc_gpio_register_module_set("RC", 0);
+			}
+            pinmux_update_rc_status();
+			spin_unlock_irqrestore(&cs_fpc_lock, flags);
+			break;
+		case FPC_SET_BitTimeCnt:
+			spin_lock_irqsave(&cs_fpc_lock, flags);
+
+			rc_ctl = fpc_readw(FPC_RC_CTL_L);
+			rc_ctl &= 0x00ff; rc_ctl |= (arg & 0xff) << 8;
+			fpc_writew(rc_ctl, FPC_RC_CTL_L);
+
+			rc_ctl = fpc_readw(FPC_RC_CTL_H);
+			rc_ctl &= 0xff00; rc_ctl |= (arg >> 8) & 0xff;
+			fpc_writew(rc_ctl, FPC_RC_CTL_H);
+
+			spin_unlock_irqrestore(&cs_fpc_lock, flags);
+			break;
+		case FPC_GET_BitTimeCnt:
+			spin_lock_irqsave(&cs_fpc_lock, flags);
+			rc_ctl = fpc_readw(FPC_RC_CTL_L);
+			btc = (rc_ctl & 0xff00) >> 8;
+
+			rc_ctl = fpc_readw(FPC_RC_CTL_H);
+			btc |= (rc_ctl & 0xff) << 8;
+			spin_unlock_irqrestore(&cs_fpc_lock, flags);
+
+			copy_to_user((unsigned long*)arg, &btc, 2);
+			break;
+
+        case FPC_RC_SET_PROTOCAL:
+            spin_lock_irqsave(&rc_dev->lock, flags);
+            rc_dev->protocal = arg;
+        	spin_unlock_irqrestore(&rc_dev->lock, flags);
+            break;
+		default:
+			break;
+	}
+
+	return 0;
+}
+
+static struct file_operations fpc_fops = {
+	.owner		= THIS_MODULE,
+	.unlocked_ioctl  = cs_fpc_ioctl,
+};
+
+static struct miscdevice fpc_miscdev = {
+	.name = "cs_fpc",
+	.minor = MISC_DYNAMIC_MINOR,
+	.fops = &fpc_fops
+};
+
+static int fpc_proc_write(struct file *file,
+                const char *buffer, unsigned long count, void *data)
+{
+	u32 addr;
+	u16 val;
+
+    const char *cmd_line = buffer;;
+
+    if (strncmp("rw", cmd_line, 2) == 0) {
+		addr = simple_strtol(&cmd_line[3], NULL, 16);
+        val = fpc_readw(addr);
+        printk(" readl [0x%04x] = 0x%04x \n", addr, val);
+    } else if (strncmp("ww", cmd_line, 2) == 0) {
+        addr = simple_strtol(&cmd_line[3], NULL, 16);
+        val = simple_strtol(&cmd_line[9], NULL, 16);
+        fpc_writew(val, addr);
+        pinmux_update_rc_status();
+        pinmux_update_fpc_status();
+    } else if (strncmp("reboot", cmd_line, 6) == 0) {
+        printk("reboot the systme ....\n ");
+       // arch_reset(0,0);
+    } else if (strncmp("st", cmd_line, 2) == 0) {	/* set time ajust value */
+		int entry;
+		int hl, hh, tl, th;
+		entry = simple_strtol(&cmd_line[3], NULL, 10);
+
+		hl = simple_strtol(&cmd_line[5], NULL, 10);
+		hh = simple_strtol(&cmd_line[11], NULL, 10);
+		tl = simple_strtol(&cmd_line[17], NULL, 10);
+		th = simple_strtol(&cmd_line[23], NULL, 10);
+
+		pta_nec[entry].h_low = hl; /* pta_nec: protocal time ajust */
+		pta_nec[entry].h_high = hh;
+		pta_nec[entry].t_low = tl;
+		pta_nec[entry].t_high = th;
+	} else if (strncmp("rt", cmd_line, 2) == 0) {	/* read time ajust value */
+		int entry;
+		entry = simple_strtol(&cmd_line[3], NULL, 10);
+		printk (
+				"pta: pta[%d].h_low  = %d\n"
+				"pta: pta[%d].h_high = %d\n"
+				"pta: pta[%d].t_low  = %d\n"
+				"pta: pta[%d].t_high = %d\n",
+				entry, pta_nec[entry].h_low,
+				entry, pta_nec[entry].h_high,
+				entry, pta_nec[entry].t_low,
+				entry, pta_nec[entry].t_high
+		       );
+	} else if (strncmp("sp", cmd_line, 2) == 0) {	/* set remote controller protocals */
+		int protocal;
+		protocal = simple_strtol(&cmd_line[3], NULL, 10);
+		rc_dev->protocal = protocal;
+	} else if (strncmp("rpt", cmd_line, 3) == 0) {	/* set remote controller protocals */
+		val = simple_strtol(&cmd_line[4], NULL, 10);
+		rc_dev->max_rpt = val;
+	} else if (strncmp("dbg", cmd_line, 3) == 0) {	/* set remote controller protocals */
+		if (RC_DEBUG) 	RC_DEBUG = 0;
+		else 		RC_DEBUG = 1;
+	} else if (strncmp("syscode", cmd_line, 7) == 0) {
+		printk("system code: 0x%x\n", rc_dev->record.addr);
+	} else if (strncmp("rms", cmd_line, 3) == 0) {
+        printk("repeat ms is %d.\n", rc_dev->repeat_ms);
+	} else if (strncmp("wms", cmd_line, 3) == 0) {
+    	val = simple_strtol(&cmd_line[4], NULL, 10);
+        if (val > 0 && val < 1000) {
+            printk("set repeat ms to %d.\n", val);
+    	    rc_dev->repeat_ms = val;
+        }
+        else {
+            printk("repeat ms must less than 1000.\n");
+        }
+	}
+	else {
+		printk(KERN_ERR "Illegal command\n");
+	}
+
+    return count;
+}
+
+int __init cs_fpc_init(void)
+{
+    int i;
+    int ret = 0;
+    unsigned short dummy;
+    unsigned short fir_psn;
+    unsigned int rc_ctl;
+	unsigned int iqwx;
+
+
+	
+    init_timer(&fpc_rc_netgear_timer);
+	fpc_rc_netgear_timer.expires =jiffies+ msecs_to_jiffies(110);
+	//fpc_rc_netgear_timer.date =0;
+	fpc_rc_netgear_timer.function =&netgear_nec_rc_rpt;
+	add_timer(&fpc_rc_netgear_timer); 
+
+	
+	
+    if (iqwx=request_irq(CS_RC_IRQ, rc_dev_interrupt, IRQF_DISABLED, "cs_fpc", NULL)) {
+		 
+        ret = -EBUSY;
+        goto out;
+    }
+
+   
+    if (!request_mem_region(CS_FPC_BASE, CS_FPC_SIZE, "CNC FPC")) {
+        ret = -EBUSY;
+        goto err1;
+    }
+
+    
+    if (!(cs_fpc_base = (unsigned short *)ioremap(CS_FPC_BASE, CS_FPC_SIZE))) {
+        ret = -EIO;
+        goto err2;
+    }
+
+    
+    if (misc_register(&fpc_miscdev)) {
+        ret = -EBUSY;
+        goto err3;
+    }
+	
+
+	if (!(fpc_proc_entry = create_proc_entry("fpc_io", 0, NULL))) {
+        ret = -EFAULT;
+        goto err4;
+	} else {
+	    fpc_proc_entry->write_proc = fpc_proc_write;
+	}
+
+    if (!(rc_dev = kzalloc(sizeof(cs_rc_t), GFP_KERNEL))) {
+        ret = -ENOMEM;
+        goto err5;
+    }
+
+    //init_input_dev(&rc_dev->dev);
+    rc_dev->dev = input_allocate_device();
+    if (rc_dev->dev == NULL){
+        return -ENOMEM;
+        goto err6;
+    }
+
+    //rc_dev->dev = input;
+    rc_dev->dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+    rc_dev->dev->keycode = rc_dev->keycode;
+    rc_dev->dev->keycodesize = sizeof(unsigned short);
+    rc_dev->dev->keycodemax = ARRAY_SIZE(rc_dev->keycode);
+    //  rc_dev->dev->private = rc_dev;
+
+    for (i = 0; i < CS_FPC_KNUM; i++)            /* Output RAW Code */
+        rc_dev->keycode[i] = i;
+
+    for (i = 0; i < CS_FPC_KNUM; i++)
+        set_bit(rc_dev->keycode[i], rc_dev->dev->keybit);
+
+    rc_dev->dev->name = DRIVER_DESC;
+    rc_dev->dev->phys = "cs_rc";
+    rc_dev->dev->id.bustype = BUS_HOST;
+    rc_dev->dev->id.vendor = 0x0001;
+    rc_dev->dev->id.product = 0x0001;
+    rc_dev->dev->id.version = 0x0104;
+
+    ret = input_register_device(rc_dev->dev);
+    if (ret < 0) {
+        goto err7;
+    }
+
+    /* default repeat is too fast */
+    rc_dev->dev->rep[REP_DELAY]   = 500;
+    rc_dev->dev->rep[REP_PERIOD]  = 100;
+    rc_dev->max_rpt = 3;    /* real repeat every 2 repeat */
+
+    /* init spin lock */
+    spin_lock_init(&rc_dev->lock);
+
+    /* init tasklet */
+    rc_dev->tasklet.func = rc_do_tasklet;
+    {
+        rc_dev->protocal = NEC;
+
+        rc_dev->repeat_ms = 150;    /* for RC6_6A */
+
+        /* Remote Controller config */
+        fpc_writew(0x0, FPC_INTM_L); /* Intr mask */
+
+        /* Noise filter */
+        fir_psn = FILTER_PRECISION * 27000 / PCLK_KHZ;
+        fpc_writew(fir_psn, FPC_FIR_L);  /* Filter precision (0xe0*47.25)/27 = 450us */
+        fpc_writew(0x0031, FPC_FIR_H);   /* Devider */
+
+        /* Interrupt count */
+        fpc_writew(0x4, FPC_RC_INTR_CNT_L); /* time_out << 4 | const_count */
+        fpc_writew(0x3a94, FPC_RC_INTR_CNT_H); /* time out count */
+
+        /* RC control */
+        rc_ctl = (RC_CTL_OPTION<<29) | (BITTIME_CNT<<8) | (CONFIG_CELESTIAL_FPC_IR_GPIO << 2);
+        fpc_writew((rc_ctl<<16)>>16, FPC_RC_CTL_L); /* bittime_cnt & pannel_select ; 0x372c */
+        /* noise filter must be enabled, or else no interrupt */
+        fpc_writew(rc_ctl>>16, FPC_RC_CTL_H);   /* 00a, rc_en | rc_pol | noise_filter_en | bittime_cnt ; 0xe000 */
+
+#if 0
+        /* temparary not set */
+        fpc_writew(0x1, RC_TIME_INTERVAL_L); /* RC_TIME_INTERVAL */
+#endif
+        dummy = fpc_readw(FPC_RC_FIFO1_L);
+        PDEBUG("Throw out useless data: fifo1_cnt: %d, fifo2_cnt: %d , dummy: %d\n",
+                fpc_readw(FPC_RC_FIFO1_CNT_L), fpc_readw(FPC_RC_FIFO2_CNT_L), dummy);
+
+	/* KeyScan config  */
+        //fpc_writew(0x0001, FPC_KSCAN_CNTL_L);    /* enable keyscan */
+        fpc_writew(0 & 0xffff, FPC_KSCAN_CNTL_L);
+        fpc_writew((0 << 15) & 0xffff, FPC_LED_CNTL_H);
+
+        pinmux_update_rc_status();
+        pinmux_update_fpc_status();
+    }
+
+    fpc_writew(0xff, FPC_LED_CNTL_L);
+
+    goto out;
+
+err7:
+    input_free_device(rc_dev->dev);
+err6:
+    kfree(rc_dev);
+err5:
+    remove_proc_entry("rc_io", NULL);
+err4:
+    misc_deregister(&fpc_miscdev);
+err3:
+	iounmap((void*)cs_fpc_base);
+err2:
+    release_mem_region(CS_FPC_BASE, CS_FPC_SIZE);
+err1:
+    free_irq(CS_RC_IRQ, NULL);
+out:
+	return ret;
+
+}
+
+static void __exit cs_fpc_exit(void)
+{
+    del_timer(&fpc_rc_netgear_timer);
+    input_free_device(rc_dev->dev);
+    kfree(rc_dev);
+    remove_proc_entry("rc_io", NULL);
+    misc_deregister(&fpc_miscdev);
+	iounmap((void*)cs_fpc_base);
+    release_mem_region(CS_FPC_BASE, CS_FPC_SIZE);
+    free_irq(CS_RC_IRQ, NULL);
+}
+
+module_init(cs_fpc_init);
+module_exit(cs_fpc_exit);
+
+EXPORT_SYMBOL(rc_system_code);
+
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/celestial/peripheral/cnc1900_fpc.h linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/peripheral/cnc1900_fpc.h
--- linux-linaro-3.4-2012.05-1_original/drivers/celestial/peripheral/cnc1900_fpc.h	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/peripheral/cnc1900_fpc.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,169 @@
+#ifndef _CS_FPC_H_
+#define _CS_FPC_H_
+
+#include <mach/hardware.h>
+
+#define FPC_MAGIC 'z'
+
+#define FPC_LED_EN	 	        _IOW(FPC_MAGIC, 0x06, int)
+#define FPC_LED_DISP	 	    _IOW(FPC_MAGIC, 0x08, int)
+#define FPC_RC_SET_SYSTEMCODE	_IOW(FPC_MAGIC, 0x09, int)
+#define FPC_LED_GET		        _IOR(FPC_MAGIC, 0x0a, int)
+#define FPC_KEYSCAN_EN          _IOW(FPC_MAGIC, 0x0b, int)
+#define FPC_KSCAN_GET		    _IOR(FPC_MAGIC, 0x0c, int)
+#define FPC_RC_SET_PROTOCAL     _IOR(FPC_MAGIC, 0x10, int)
+
+/* Adjust bit time count outside for nonstandard rc protocal */
+#define FPC_SET_BitTimeCnt	_IOR(FPC_MAGIC, 0x0d, int)
+#define FPC_GET_BitTimeCnt	_IOR(FPC_MAGIC, 0x0e, int)
+
+#define FPC_RC_EN      _IOW(FPC_MAGIC, 0x14, int)
+
+
+/* Register Map */
+#define FPC_INTS_L		         (0x000)    /*Interrupt Status Register*/
+#define FPC_INTS_H		         (0x002)
+#define FPC_INTM_L		         (0x004)    /*Interrupt Mask Register*/
+#define FPC_INTM_H		         (0x006)
+#define FPC_RC_CTL_L             (0x008)    /*FPC Control Register*/
+#define FPC_RC_CTL_H             (0x00a)
+#define FPC_RC_TIME_INTERVAL_L   (0x00c)    /*FPC Time Interval Register*/
+#define FPC_RC_TIME_INTERVAL_H   (0x00e)
+#define FPC_UHF_CTL_L            (0x010)    /*UHF control Register*/
+#define FPC_UHF_CTL_H            (0x012)
+#define FPC_UHF_TIME_INTERVAL_L  (0x014)    /*UHF Time Interval  Register*/
+#define FPC_UHF_TIME_INTERVAL_H	 (0x016)
+#define FPC_RC_INTR_CNT_L        (0x018)    /*FPC Interrupt counter Register*/
+#define FPC_RC_INTR_CNT_H        (0x01a)
+#define FPC_UHF_INTR_CNT_L       (0x01c)    /*UHF Interrupt counter Register*/
+#define FPC_UHF_INTR_CNT_H       (0x01e)
+#define FPC_RC_FIFO1_L           (0x020)    /*FPC FIFO1*/
+#define FPC_RC_FIFO1_H           (0x022)
+#define FPC_RC_FIFO1_CNT_L       (0x024)    /*FPC FIFO1 count*/
+#define FPC_RC_FIFO1_CNT_H       (0x026)
+#define FPC_RC_FIFO2_L           (0x028)    /*FPC FIFO2*/
+#define FPC_RC_FIFO2_H           (0x02a)
+#define FPC_RC_FIFO2_CNT_L       (0x02c)    /*FPC FIFO2 count*/
+#define FPC_RC_FIFO2_CNT_H       (0x02e)
+#define FPC_UHF_FIFO1_L          (0x030)    /*UHF FIFO1 */
+#define FPC_UHF_FIFO1_H          (0x032)
+#define FPC_UHF_FIFO1_CNT_L      (0x034)    /*UHF FIFO1 Count*/
+#define FPC_UHF_FIFO1_CNT_H      (0x036)
+#define FPC_UHF_FIFO2_L          (0x038)    /*UHF FIFO2 */
+#define FPC_UHF_FIFO2_H          (0x03a)
+#define FPC_UHF_FIFO2_CNT_L      (0x03c)    /*UHF FIFO2 Count*/
+#define FPC_UHF_FIFO2_CNT_H      (0x03e)
+#define FPC_FIR_L                (0x040)    /*FPC FIR Register*/
+#define FPC_FIR_H                (0x042)
+#define FPC_UHF_FIR_L            (0x044)    /*UHF FIR Register*/
+#define FPC_UHF_FIR_H            (0x046)
+#define FPC_LED_DATA_L           (0x200)    /*LED DATA Register*/
+#define FPC_LED_DATA_H           (0x202)
+#define FPC_LED_CNTL_L           (0x204)    /*LED Counter Register*/
+#define FPC_LED_CNTL_H           (0x206)    /*LED Counter Register*/
+#define FPC_KSCAN_DATA_L         (0x300)    /*KSCAN DATA Register*/
+#define FPC_KSCAN_DATA_H         (0x302)
+#define FPC_KSCAN_CNTL_L         (0x304)    /*KSCAN Counter Register*/
+#define FPC_KSCAN_CNTL_H         (0x306)
+#define FPC_KSCAN_ARB_CNTL_L     (0x308)    /*KSCAN Arbitrates Register*/
+#define FPC_KSCAN_ARB_CNTL_H     (0x30a)
+
+#define CS_FPC_BASE		        PA_FPC_BASE
+#define CS_FPC_SIZE             0x1000
+#define CS_RC_IRQ		        PANEL_CONTROL_IRQ
+
+#define FILTER_PRECISION 	(450)
+
+#define RC_CTL_OPTION 		( 7) 	/* rc_en | rc_pol | noise_filter_en */
+#define BITTIME_CNT 		(PCLK_MHZ)
+#define PANNEL_SELECT 		(11) 	/* GPIO input for remote controller */
+
+#define DRIVER_DESC		    "CS Remote Controller"
+
+/* Key number */
+#define CS_FPC_KNUM 		KEY_MAX
+
+/* Parse period */
+#define HEAD_PERIOD		0
+#define ADDR_PERIOD		1
+#define CMD_PERIOD		2
+#define EXTEND_PERIOD		3
+
+
+#undef PDEBUG
+
+//#define CONFIG_FPC_DEBUG
+static int RC_DEBUG = 0;
+#ifdef CONFIG_FPC_DEBUG
+# ifdef __KERNEL__
+#  define PDEBUG(fmt, args...) printk( fmt, ## args)
+# else
+#  define PDEBUG(fmt, args...) printf(fmt, ## args)
+# endif
+#else
+# define PDEBUG(fmt, args...) \
+	if (RC_DEBUG) printk( fmt, ## args)
+#endif
+
+/* Infrared Remote Control Protocol type */
+typedef enum rc_protocal_ {
+	NEC, RC5,SONY, RC6_6A,
+#if 0
+	FPCMM, RECS80, FPCA, XSAT, JVC, NFPC17, SHARP, SIFPC, ITT,
+#endif
+	P_TOTAL
+} rc_protocal_t;
+
+typedef struct rc_record_ {
+	unsigned short addr;
+	unsigned short cmd;
+	unsigned short bit;
+	unsigned short rpt;
+
+	unsigned short decode_period;
+
+	unsigned short rc5_data;
+	unsigned short next_bit_is_zero;
+	unsigned short pre_T;      /* Only FPC5 use */
+
+    /* for rc6 mode 6a */
+    unsigned char mode;
+    unsigned char half_bit; // 0 no half bit left, 1 have half bit of ONE or ZERO, 2 have half bit of T0 or T1
+} rc_record_t;
+
+typedef struct cs_rc_ {
+	spinlock_t lock;
+	struct tasklet_struct tasklet;
+	struct input_dev *dev;
+
+	unsigned short keycode[CS_FPC_KNUM];
+	rc_record_t record;
+
+	/* To be set outside, used as condition restriction */
+	unsigned short addr;
+	unsigned short max_rpt;
+	unsigned short protocal;
+
+#define FIFO_LEN 80
+	unsigned short fifo1[FIFO_LEN];
+	unsigned short fifo2[FIFO_LEN];
+	short f1_idx;
+	short f2_idx;
+
+    /* for FPC6 mode 6A */
+    unsigned short last_report_cmd;
+    unsigned long last_report_jiffies;
+    unsigned repeat_ms;        /* can set by writing proc file */
+
+#ifdef CONFIG_FPC_DEBUG
+	unsigned short fc[32][2];	/* For debug only */
+	short fc_idx;
+#endif
+
+	int bit_err;
+} cs_rc_t;
+
+//extern int cnc_gpio_register_module_status(const char * module, unsigned int  orion_module_status); /* status: 0 disable, 1 enable */
+
+#endif
+
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/celestial/peripheral/cnc1900_gpio.c linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/peripheral/cnc1900_gpio.c
--- linux-linaro-3.4-2012.05-1_original/drivers/celestial/peripheral/cnc1900_gpio.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/peripheral/cnc1900_gpio.c	2015-01-08 12:04:08.078171000 +0800
@@ -0,0 +1,820 @@
+/****************************************************************************
+ * Copyright (C) 2010-2013 Caviumnetwroks Inc.
+ * All rights reserved
+ *
+ * [RELEASE HISTORY]
+ * VERSION  DATE       AUTHOR                  DESCRIPTION
+ * 0.1      13-06-17   weixin           			Original
+ ****************************************************************************
+ */
+#include <linux/version.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+
+#include <linux/ioport.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/cdev.h>
+#include <linux/spinlock.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <linux/proc_fs.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <mach/hardware.h>
+#include <linux/poll.h>
+#include <linux/sched.h>
+#include <asm/mach/irq.h>
+
+#define CMD_READ_GPIO         _IOR('G', 1, unsigned long)
+#define CMD_WRITE_GPIO        _IOW('G', 2, unsigned long)
+#define CMD_SET_DIRECTION     _IOW('G', 3, unsigned long)
+#define CMD_ENA_GPIO_INTR     _IOW('G', 4, unsigned long)
+
+#define GPIO_READ 0
+#define GPIO_WRITE 1
+
+
+struct gpio_cmd {
+	int gpio;
+	int value;
+};
+
+#define REG_GPIO_SWPORTA_DR             0x20
+#define REG_GPIO_SWPORTA_DDR            0x24
+#define REG_GPIO_EXT_PORTA              0x60
+
+#define REG_GPIO_INTMASK_A		        0x28
+#define REG_GPIO_INTMASK_B		        0x3c
+
+#define REG_GPIO_POLARITY_A		        0x2c
+#define REG_GPIO_POLARITY_B		        0x40
+
+#define REG_GPIO_SWPORTB_DR             0x34
+#define REG_GPIO_SWPORTB_DDR            0x38
+#define REG_GPIO_EXT_PORTB              0x64
+
+#define GPIO_MAJOR  	0
+
+
+//#ifdef CONFIG_MACH_CELESTIAL_CNC1900L
+#define GPIO_NR_DEVS	64
+//#else
+//#define GPIO_NR_DEVS	41
+//#endif
+
+#define GPIO_PINMUXA    0x30
+#define GPIO_PINMUXB    0x44
+
+static int gpio_major = GPIO_MAJOR;
+static int gpio_nr_devs = GPIO_NR_DEVS;
+
+module_param(gpio_major, int, GPIO_MAJOR);
+module_param(gpio_nr_devs, int, GPIO_NR_DEVS);
+MODULE_PARM_DESC(gpio_major, "GPIO major number");
+MODULE_PARM_DESC(gpio_nr_devs, "GPIO number of lines");
+
+typedef struct gpio_devs {
+	u32 gpio_id;
+	struct cdev cdev;
+	wait_queue_head_t irq_wait_queue;
+	u32 irq_enable : 8;
+	u32 cur_irq_type  : 8;       // current irq type set by user, level_low or level_high
+	u32 report_event  : 8;       // receive a irq and need to report
+} gpio_devs_t;
+
+typedef enum {
+	GPIO_IRQ_TYPE_LEVEL_LOW = 0,
+	GPIO_IRQ_TYPE_LEVEL_HIGH
+}CSGPIO_IRQ_TYPE;
+
+typedef struct __gpio_intr_param
+{
+	u32 enable     : 1;       // 1 for enable, 0 for disable
+	u32 irq_type   : 16;
+	u32 gpio_index : 15;
+}gpio_intr_param;
+
+static struct class *cnc1900_gpio_class;
+
+/*
+ * The devices
+ */
+struct gpio_devs *gpio_devices = NULL;	/* allocated in gpio_init_module */
+
+/* function declaration ------------------------------------- */
+static int __init cnc_gpio_init(void);
+static void __exit cnc_gpio_exit(void);
+
+static void gpio_setup_cdev(struct gpio_devs *dev, int index);
+
+static ssize_t cnc_gpio_write(struct file *filp, const char __user * buf,
+		size_t count, loff_t * f_pos);
+static ssize_t cnc_gpio_read(struct file *filp, char __user * buf, size_t count,
+		loff_t * f_pos);
+static long cnc_gpio_ioctl(struct file *file, unsigned int cmd,
+		unsigned long arg);
+static unsigned int cnc_gpio_poll(struct file *filp, poll_table *wait);
+static int cnc_gpio_open(struct inode *inode, struct file *file);
+static int cnc_gpio_close (struct inode *inode, struct file *file);
+static int gpio_get_status_bit(unsigned int gpio,char is_pinmux);
+void gpio_configure_status_bit(unsigned int bit, const char * configure_cmd,char is_pinmux);
+
+//int cnc_gpio_register_module_set(const char * module, unsigned int  cnc_module_status);
+
+static spinlock_t gpio_lock;
+static volatile unsigned int *gpio_base;
+static unsigned int gpio_status1 = 0;
+static unsigned int gpio_status2 = 0;
+static unsigned int gpio_pinmux_status1 =0;
+static unsigned int gpio_pinmux_status2 =0;
+static struct proc_dir_entry *gpio_proc_entry = NULL;
+static struct proc_dir_entry *system_config_proc_entry=NULL;
+/* ----------------------------------------------------------- */
+
+/* gpio device struct */
+struct file_operations gpio_fops = {
+	.owner = THIS_MODULE,
+	.read = cnc_gpio_read,
+	.write = cnc_gpio_write,
+	.unlocked_ioctl = cnc_gpio_ioctl,
+	.open = cnc_gpio_open,
+	.release  = cnc_gpio_close,
+	.poll = cnc_gpio_poll,
+};
+
+int gpio_get_status_bit(unsigned int gpio,char is_pinmux)
+{
+
+	int ret;
+	if((gpio >= 0)&&(gpio < 32))
+	{
+		ret = ((gpio_status1 >> gpio) & 0x1);
+		if (is_pinmux ==1)
+			ret = ret & ((gpio_pinmux_status1 >> gpio) & 0x1);
+	}
+	else
+	{
+		gpio = gpio - 32;
+		ret = ((gpio_status2 >> gpio) & 0x1);
+		if (is_pinmux ==1)
+			ret = ret & ((gpio_pinmux_status2 >> gpio) & 0x1);
+	}
+	return ret;
+}
+
+void gpio_configure_status_bit(unsigned int bit, const char * configure_cmd,char is_pinmux)
+{
+
+
+	if((bit >= 0)&&(bit < 32))
+	{
+		if (strncmp("CLR", configure_cmd, 3) == 0){
+			gpio_status1 &= ~(1<<bit);
+			if (is_pinmux == 1)
+				gpio_pinmux_status1 &= ~(1<<bit);
+		}
+		if (strncmp("SET", configure_cmd, 3) == 0){
+			gpio_status1 |= (1<<bit);
+			if (is_pinmux == 1)
+				gpio_pinmux_status1 |= (1<<bit);
+		}
+	}
+	else
+	{
+		bit = bit - 32;
+		if (strncmp("CLR", configure_cmd, 3) == 0){
+			gpio_status2 &= ~(1<<bit);
+			if (is_pinmux == 1)
+				gpio_pinmux_status2 &= ~(1<<bit);
+		}
+		if (strncmp("SET", configure_cmd, 3) == 0){
+			gpio_status2 |= (1<<bit);
+			if (is_pinmux == 1)
+				gpio_pinmux_status2 |= (1<<bit);
+		}
+	}
+}
+
+
+int gpio_hw_set_direct(int gpio_id, int dir)
+{
+	unsigned int flags;
+	spin_lock(&gpio_lock);
+	if((gpio_id < 32)&&(gpio_id >= 0))
+	{
+
+		flags = (1<<gpio_id);
+		if (dir == GPIO_READ) {
+			gpio_base[REG_GPIO_SWPORTA_DDR >> 2] |= flags;
+		} else if (dir == GPIO_WRITE){
+			gpio_base[REG_GPIO_SWPORTA_DDR >> 2] &= ~flags;
+		} else{
+			return -1;
+		}
+
+	}
+	else if((gpio_id >= 32)&&(gpio_id < GPIO_NR_DEVS))
+	{
+		gpio_id = gpio_id - 32;
+		flags = (1<<gpio_id);
+		if (dir == GPIO_READ) {
+			gpio_base[REG_GPIO_SWPORTB_DDR >> 2] |= flags;
+		} else if (dir == GPIO_WRITE){
+			gpio_base[REG_GPIO_SWPORTB_DDR >> 2] &= ~flags;
+		} else{
+			return -1;
+		}
+	}
+
+	spin_unlock(&gpio_lock);
+	return 0;
+}
+
+static unsigned short gpio_hw_read(unsigned char gpio_id)
+{
+	if((gpio_id < 32)&&(gpio_id >= 0))
+	{
+		return (gpio_base[REG_GPIO_EXT_PORTA >> 2] >> gpio_id) & 0x1;
+	}
+	else if((gpio_id >= 32)&&(gpio_id < GPIO_NR_DEVS))
+	{
+		return (gpio_base[REG_GPIO_EXT_PORTB >> 2] >> gpio_id) & 0x1;
+	}
+	return 0;
+}
+
+int gpio_hw_write(unsigned char gpio_id, unsigned char data)
+{
+	unsigned int flags ;
+	if((gpio_id < 32)&&(gpio_id >= 0))
+	{
+		flags = (1<<gpio_id);
+		if (!data) {
+			gpio_base[REG_GPIO_SWPORTA_DR>>2 ] &= ~flags;
+			gpio_status1 &= ~flags;
+		} else {
+			gpio_base[REG_GPIO_SWPORTA_DR>>2 ] |= flags;
+			gpio_status1 |= flags;
+		}
+	}
+	else if((gpio_id >= 32)&&(gpio_id < GPIO_NR_DEVS))
+	{
+		gpio_id = gpio_id - 32;
+		flags = (1<<gpio_id);
+		if (!data) {
+			gpio_base[REG_GPIO_SWPORTB_DR>>2 ] &= ~flags;
+			gpio_status2 &= ~flags;
+		} else {
+			gpio_base[REG_GPIO_SWPORTB_DR>>2 ] |= flags;
+			gpio_status2 |= flags;
+		}
+	}
+	return 0;
+}
+
+static void gpio_setup_cdev(struct gpio_devs *dev, int index)
+{
+	int errorcode = 0;
+	char device_name[80];
+
+	int devno = MKDEV(gpio_major, index);
+
+	cdev_init(&dev->cdev, &gpio_fops);
+	dev->cdev.owner = THIS_MODULE;
+	dev->cdev.ops = &gpio_fops;
+
+	errorcode = cdev_add(&dev->cdev, devno, 1);
+	if (errorcode) {
+		printk(KERN_NOTICE "GPIO: Error %d adding gpio %d", errorcode,
+				index);
+	}
+
+	snprintf(device_name, sizeof (device_name), "gpio%d", index);
+	device_create(cnc1900_gpio_class, NULL, MKDEV(gpio_major, index), NULL, device_name);
+
+}
+
+void cnc_gpio_irq_mask(unsigned int gpio_id)
+{
+	unsigned long flags;
+	unsigned int value;
+	spin_lock_irqsave(&gpio_lock, flags);
+	//    printk("Entered gpio mask status: 0x%x, 0x%x, mask: 0x%x\n", gpio_base[REG_GPIO_INT_S_A>>2], gpio_base[REG_GPIO_INT_S_B>>2], gpio_base[REG_GPIO_INTMASK_A >> 2]);
+	if(gpio_id < 32){
+		value = (1<<gpio_id);
+		gpio_base[REG_GPIO_INTMASK_A >> 2] |= value;
+
+	} else if((gpio_id >= 32)&&(gpio_id < GPIO_NR_DEVS)) {
+
+		value = (1 << (gpio_id - 32));
+		gpio_base[REG_GPIO_INTMASK_B >> 2] |= value;
+	}
+
+	spin_unlock_irqrestore(&gpio_lock, flags);
+	//    printk("Out gpio intrrupt! status: 0x%x, 0x%x, mask: 0x%x\n", gpio_base[REG_GPIO_INT_S_A>>2], gpio_base[REG_GPIO_INT_S_B>>2], gpio_base[REG_GPIO_INTMASK_A >> 2]);
+}
+EXPORT_SYMBOL(cnc_gpio_irq_mask);
+
+void cnc_gpio_irq_unmask(unsigned int gpio_id)
+{
+	unsigned long flags;
+	unsigned int value;
+
+	spin_lock_irqsave(&gpio_lock, flags);
+
+	if(gpio_id < 32){
+		value = (1<<gpio_id);
+		gpio_base[REG_GPIO_INTMASK_A >> 2] &= ~value;
+
+	} else if((gpio_id >= 32)&&(gpio_id < GPIO_NR_DEVS)) {
+
+		value = (1 << (gpio_id - 32));
+		gpio_base[REG_GPIO_INTMASK_B >> 2] &= ~value;
+
+	}
+	spin_unlock_irqrestore(&gpio_lock, flags);
+}
+EXPORT_SYMBOL(cnc_gpio_irq_unmask);
+
+static int cnc_gpio_set_irq_type(unsigned int gpio_id, unsigned int type)
+{
+	unsigned int value;
+
+	gpio_hw_set_direct(gpio_id, GPIO_READ);
+	//printk("Set irq:%d, gpio:%d 's type : %d\n", irq,  gpio_id, type);
+	switch (type) {
+		case GPIO_IRQ_TYPE_LEVEL_HIGH: /* Attentation Document is wrong */
+
+			if(gpio_id < 32){
+				value = (1<<gpio_id);
+				gpio_base[REG_GPIO_POLARITY_A >> 2] &= ~value;
+
+			} else if((gpio_id >= 32)&&(gpio_id < GPIO_NR_DEVS)) {
+				value = (1 << (gpio_id - 32));
+				gpio_base[REG_GPIO_POLARITY_B >> 2] &= ~value;
+			}
+			break;
+		case GPIO_IRQ_TYPE_LEVEL_LOW:
+			if(gpio_id < 32){
+				value = (1<<gpio_id);
+				gpio_base[REG_GPIO_POLARITY_A >> 2] |= value;
+			} else if((gpio_id >= 32)&&(gpio_id < GPIO_NR_DEVS)) {
+
+				value = (1 << (gpio_id - 32));
+				gpio_base[REG_GPIO_POLARITY_B >> 2] |= value;
+			}
+			break;
+
+		default :
+			pr_err("cnc: failed to set irq type %d for gpio %d\n", type, gpio_id);
+			return -EINVAL;
+	}
+
+	return 0;
+}
+
+EXPORT_SYMBOL(gpio_hw_write);
+EXPORT_SYMBOL(gpio_hw_set_direct);
+EXPORT_SYMBOL(gpio_configure_status_bit);
+static int cnc_gpio_open(struct inode *inode, struct file *file)
+{
+	unsigned m = iminor(file->f_dentry->d_inode);
+	if (gpio_get_status_bit(m,1) != 0 )
+	{
+		printk("\n EBUSY   \n");
+		return -EBUSY;
+	}
+	gpio_configure_status_bit(m ,"SET",1);
+	init_waitqueue_head(&gpio_devices[m].irq_wait_queue);
+	return 0;
+}
+
+static int cnc_gpio_close (struct inode *inode, struct file *file)
+{
+	unsigned m = iminor(file->f_dentry->d_inode);
+	if (gpio_get_status_bit(m,1) != 0 )
+		gpio_configure_status_bit(m ,"CLR",0);
+
+	if (gpio_devices[m].irq_enable)
+	{
+		cnc_gpio_irq_mask(m);
+		gpio_devices[m].irq_enable = 0;
+	}
+	return 0;
+}
+
+static ssize_t cnc_gpio_write(struct file *file, const char __user * data,
+		size_t len, loff_t * ppos)
+{
+	unsigned m = iminor(file->f_dentry->d_inode);
+	size_t i;
+	for (i = 0; i < len; ++i) {
+		char c;
+		if (get_user(c, data + i))
+			return -EFAULT;
+		switch (c) {
+			case '0':
+				gpio_hw_write(m, 0);
+				break;
+			case '1':
+				gpio_hw_write(m, 1);
+				break;
+			case 'O':
+				gpio_hw_set_direct(m, GPIO_WRITE);
+				break;
+			case 'o':
+				gpio_hw_set_direct(m, GPIO_READ);
+				break;
+		}
+	}
+
+	return len;
+}
+
+static int system_config_proc_read(char *page, char **start, off_t off, int count, int *eof, void *data)
+{
+	int len=0;
+    len += sprintf(page+len,"VIDEO Number: %d. \n",VIDEO_NUM);
+    len += sprintf(page+len,"DBP start address is 0x%x. \n",VIDEO_DPB_REGION);
+    len += sprintf(page+len,"DBP size is %dMB. \n",VIDEO_DPB_SIZE/(1024*1024));
+    len += sprintf(page+len,"CBP start address is 0x%x. \n",VIDEO_CPB_REGION);
+    len += sprintf(page+len,"CPB size is %dMB. \n",VIDEO_CPB_SIZE/(1024*1024));
+    len += sprintf(page+len,"CBP Dir start address is 0x%x. \n",VIDEO_CPB_DIR_REGION);
+    len += sprintf(page+len,"CPB Dir size is %dKB. \n",VIDEO_CPB_DIR_SIZE/1024);
+    len += sprintf(page+len,"VIDEO User Data start address is 0x%x. \n",VIDEO_USER_DATA_REGION);
+    len += sprintf(page+len,"VIDEO User Data size is %dKB. \n",VIDEO_USER_DATA_SIZE/1024);
+    len += sprintf(page+len,"GPU Base address is 0x%x. \n",GPU_BASE );
+
+#if 0
+#if defined(CONFIG_MACH_CELESTIAL_CNC1800H)
+	len += sprintf(page+len,"Linux kernel is configured for CNC1800H. \n");
+	len += sprintf(page+len,"System is configured for %d Total Memory.\n", CONFIG_CELESTIAL_MEM_SIZE);
+#elif defined(CONFIG_MACH_CELESTIAL_CNC1800L)
+	len += sprintf(page+len,"Linux kernel is configured for CNC1800L. \n");
+	len += sprintf(page+len,"System is configured for %d Total Memory.\n", CONFIG_CELESTIAL_MEM_SIZE);
+#else
+	len += sprintf(page+len,"Linux kernel is configured for UNKNOWN system. \n");
+#endif
+
+#if defined(BASE_DDR_ADDR)
+	len += sprintf(page+len,"Memsize is %dMB. \n",BASE_DDR_ADDR/(1024*1024));
+
+	len += sprintf(page+len,"FB0 buffer size is %dMB.\n",FB0_SIZE/(1024*1024));
+	len += sprintf(page+len,"FB0 buffer start is 0x%x.\n",FB0_REGION);
+	len += sprintf(page+len,"FB1 buffer size is %dMB. \n",FB1_SIZE/(1024*1024));
+	len += sprintf(page+len,"FB1 buffer start is 0x%x.\n",FB1_REGION);
+
+	len += sprintf(page+len,"FB2 buffer size is %dMB. \n",FB2_SIZE/(1024*1024));
+	len += sprintf(page+len,"FB2 buffer start is 0x%x.\n",FB2_REGION);
+	len += sprintf(page+len,"FB3 buffer size is %dMB. \n",FB3_SIZE/(1024*1024));
+	len += sprintf(page+len,"FB3 buffer start is 0x%x.\n",FB3_REGION);
+
+	len += sprintf(page+len,"ETHERNET buffer size is %dMB. \n",ETHERNET_SIZE/(1024*1024));
+	len += sprintf(page+len,"ETHERNET is 0x%x. \n",ETHERNET_REGION);
+
+	len += sprintf(page+len,"HD2SD data buffer size is %dKB. \n",HD2SD_DATA_SIZE/1024);
+	len += sprintf(page+len,"HD2SD start is 0x%x. \n",HD2SD_DATA_REGION);
+
+	len += sprintf(page+len,"VIDEO STUFF buffer size is %dKB. \n",VIDEO_STUFF_SIZE/1024);
+	len += sprintf(page+len,"VIDEO STUFF start is 0x%x. \n",VIDEO_STUFF_REGION);
+
+	len += sprintf(page+len,"VIDEO Number: %d. \n",VIDEO_NUM);
+	len += sprintf(page+len,"DBP start address is 0x%x. \n",VIDEO_DPB_REGION);
+	len += sprintf(page+len,"DBP size is %dMB. \n",VIDEO_DPB_SIZE/(1024*1024));
+	len += sprintf(page+len,"CBP start address is 0x%x. \n",VIDEO_CPB_REGION);
+	len += sprintf(page+len,"CPB size is %dMB. \n",VIDEO_CPB_SIZE/(1024*1024));
+	len += sprintf(page+len,"CBP Dir start address is 0x%x. \n",VIDEO_CPB_DIR_REGION);
+	len += sprintf(page+len,"CPB Dir size is %dKB. \n",VIDEO_CPB_DIR_SIZE/1024);
+	len += sprintf(page+len,"VIDEO User Data start address is 0x%x. \n",VIDEO_USER_DATA_REGION);
+	len += sprintf(page+len,"VIDEO User Data size is %dKB. \n",VIDEO_USER_DATA_SIZE/1024);
+
+	len += sprintf(page+len,"AUDIO Number: %d. \n",AUDIO_NUM );
+	len += sprintf(page+len,"CAB start address is 0x%x. \n",AUDIO_CAB_REGION);
+	len += sprintf(page+len,"CAB size is %dKB. \n",AUDIO_CAB_SIZE/1024);
+	len += sprintf(page+len,"PTS start address is 0x%x. \n",AUDIO_PTS_REGION);
+	len += sprintf(page+len,"PTS size is %dKB. \n",AUDIO_PTS_SIZE/1024);
+	len += sprintf(page+len,"MIX start address is 0x%x. \n",AUDIO_MIX_REGION);
+	len += sprintf(page+len,"MIX size is %dKB. \n",AUDIO_MIX_SIZE/1024);
+
+	len += sprintf(page+len,"Audio buffer start address is 0x%x. \n",AUDIO_STUFF_REGION);
+	len += sprintf(page+len,"Audio buffer size is %dMB. \n",AUDIO_STUFF_SIZE/(1024*1024));
+
+	len += sprintf(page+len,"Demux buffer start address is 0x%x. \n",XPORT_REGION);
+	len += sprintf(page+len,"Demux buffer size is %dKB. \n",XPORT_SIZE/1024);
+
+	len += sprintf(page+len,"System/Firmwares used memory size is %dMB. \n",(BASE_DDR_ADDR-XPORT_REGION)/(1024*1024));
+#if (CONFIG_CELESTIAL_MEM_SIZE == 512)
+	len += sprintf(page+len,"There is %dMB memory for kernel/user. \n",XPORT_REGION/(1024*1024)+256);
+#elif (CONFIG_CELESTIAL_MEM_SIZE == 1024)
+	len += sprintf(page+len,"There is %dMB memory for kernel/user. \n",XPORT_REGION/(1024*1024)+256+512);
+#else
+	len += sprintf(page+len,"There is %dMB memory for kernel/user. \n",XPORT_REGION/(1024*1024));
+#endif
+#else
+	len += sprintf(page+len,"Cannot find Maxmium DDR Size. \n");
+#endif
+#endif
+	return len;
+}
+
+static int gpio_proc_read(char *page, char **start, off_t off, int count, int *eof, void *data)
+{
+	int gpioa,gpiob;
+	int len=0;
+	for (gpioa=0;gpioa<GPIO_NR_DEVS;gpioa++){
+		if(gpioa < 32)
+		{
+			if ((gpio_status1>>gpioa) & 0x1)
+			{
+				if ((gpio_pinmux_status1>>gpioa) & 0x1)
+					len += sprintf(page+len,"==> GPIOa %d is held by other component. \n",gpioa);
+				else
+					len += sprintf(page+len,"==> GPIOa %d is using. \n",gpioa);
+			}
+			else
+			{
+				len += sprintf(page+len,"==> GPIOa %d is free.\n",gpioa);
+			}
+		}
+		else
+		{
+			gpiob = gpioa - 32;
+			if ((gpio_status2>>gpiob) & 0x1)
+			{
+				if ((gpio_pinmux_status2>>gpiob) & 0x1)
+					len += sprintf(page+len,"==> GPIOb %d(%d) is held by other component. \n",gpiob,gpioa);
+				else
+					len += sprintf(page+len,"==> GPIOb %d(%d) is using. \n",gpiob,gpioa);
+			}
+			else
+			{
+				len += sprintf(page+len,"==> GPIOb %d(%d) free.\n",gpiob,gpioa);
+			}
+		}
+	}
+	return len;
+}
+
+static int gpio_proc_write(struct file *file, const char __user *buffer,
+		unsigned long count, void *data)
+{
+	unsigned char addr;
+	unsigned char val;
+
+	const char *cmd_line = buffer;;
+
+	if (strncmp("wwgpio", cmd_line, 6) == 0) {
+		addr = simple_strtol(&cmd_line[7], NULL, 16);
+		val = simple_strtol(&cmd_line[9], NULL, 16);
+		//printk("==> GPIO addr 0x%08x is set to 0x%04x \n",addr,val);
+		//gpio_base[addr>>2] = val;
+		gpio_hw_set_direct(addr, GPIO_WRITE);
+		gpio_hw_write(addr,val);
+	} else if (strncmp("rrgpio", cmd_line, 6) == 0) {
+		addr = simple_strtol(&cmd_line[7], NULL, 16);
+		gpio_hw_set_direct(addr, GPIO_READ);
+		val = gpio_hw_read(addr);
+		printk("gpio %d = %d\n", addr, val);
+	}
+
+	return count;
+}
+
+
+static ssize_t cnc_gpio_read(struct file *file, char __user * buf, size_t len, loff_t * ppos)
+{
+	unsigned m = iminor(file->f_dentry->d_inode);
+	int value;
+	value = gpio_hw_read(m);
+	if (put_user(value ? '1' : '0', buf))
+		return -EFAULT;
+
+	return 1;
+}
+
+static long cnc_gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+	struct gpio_cmd gpio_cmd;
+	unsigned long direction;
+	unsigned m = iminor(file->f_dentry->d_inode);
+	gpio_intr_param intr_param;
+
+	switch (cmd) {
+		case CMD_READ_GPIO:
+		case CMD_WRITE_GPIO:
+			if (copy_from_user
+					(&gpio_cmd, (void *) arg, sizeof (struct gpio_cmd)))
+				return -EFAULT;
+
+			switch (cmd) {
+				case CMD_READ_GPIO:
+					gpio_cmd.value = gpio_hw_read(gpio_cmd.gpio);
+					if (copy_to_user
+							((void *) arg, &gpio_cmd, sizeof (struct gpio_cmd)))
+						return -EFAULT;
+					else
+						return 0;
+
+				case CMD_WRITE_GPIO:
+					gpio_hw_set_direct(gpio_cmd.gpio, GPIO_WRITE);
+					gpio_hw_write(gpio_cmd.gpio, gpio_cmd.value);
+					return 0;
+			}
+			break;
+		case CMD_SET_DIRECTION:
+			direction = arg;
+			if (direction == GPIO_READ){
+				gpio_hw_set_direct(m,GPIO_READ);
+			}else if ( direction == GPIO_WRITE){
+				gpio_hw_set_direct(m,GPIO_WRITE);
+			}else {
+				return -EINVAL;
+			}
+			break;
+
+		case CMD_ENA_GPIO_INTR:
+			copy_from_user(&intr_param, (const void __user *)arg, sizeof(gpio_intr_param));
+			if (intr_param.enable) {
+				if (gpio_devices[intr_param.gpio_index].irq_enable &&
+						intr_param.irq_type == gpio_devices[intr_param.gpio_index].cur_irq_type) {
+					//printk("irq of gpio %d already enabled, type is %d\n", intr_param.gpio_index,
+					//    gpio_devices[intr_param.gpio_index].cur_irq_type);
+				} else {
+					cnc_gpio_set_irq_type(intr_param.gpio_index, intr_param.irq_type);
+					gpio_devices[intr_param.gpio_index].cur_irq_type = intr_param.irq_type;
+					cnc_gpio_irq_unmask(intr_param.gpio_index);
+					gpio_devices[intr_param.gpio_index].irq_enable = 1;
+				}
+			} else if (gpio_devices[intr_param.gpio_index].irq_enable) {
+				cnc_gpio_irq_mask(intr_param.gpio_index);
+				gpio_devices[intr_param.gpio_index].irq_enable = 0;
+			}
+			break;
+
+		default:
+			return -EINVAL;
+	}
+	return 0;
+}
+
+static unsigned int cnc_gpio_poll(struct file *filp, poll_table *wait)
+{
+	unsigned m = iminor(filp->f_dentry->d_inode);
+
+	poll_wait(filp, &gpio_devices[m].irq_wait_queue, wait);
+
+	if (gpio_devices[m].report_event == 1) {
+		gpio_devices[m].report_event = 0;
+		return POLLIN | POLLRDNORM;
+	} else if (gpio_devices[m].report_event == 2) {
+		gpio_devices[m].report_event = 0;
+		return POLLOUT | POLLWRNORM;
+	}
+
+	return 0;
+}
+
+#if defined(CONFIG_ARCH_CNC_DELAY)
+
+#define GPIO_PINMUX() do {udelay(20);} while(0)
+
+#else
+
+#define GPIO_PINMUX() do {} while(0)
+
+#endif
+
+#define GPIO_REGINTR() do {} while(0)
+
+irqreturn_t gpio_irq_handle(int irq, void *dev_id, struct pt_regs * egs)
+{
+	int i;
+	int value;
+
+	for (i=0; i<GPIO_NR_DEVS; i++)
+	{
+		if (gpio_devices[i].irq_enable)
+		{
+			value = gpio_hw_read(i);
+			if (value == gpio_devices[i].cur_irq_type)
+			{
+				//printk("got irq of gpio %d, type is %d\n", i, gpio_devices[i].cur_irq_type);
+				cnc_gpio_set_irq_type(i, !gpio_devices[i].cur_irq_type);
+				gpio_devices[i].cur_irq_type = !gpio_devices[i].cur_irq_type;
+				gpio_devices[i].report_event = value + 1;   // 1 for low, 2 for high
+				wake_up(&gpio_devices[i].irq_wait_queue);
+			}
+		}
+	}
+
+	return IRQ_HANDLED;
+}
+
+static int __init cnc_gpio_init(void)
+{
+	int result, i;
+	dev_t dev = 0;
+	int err=0;
+	if (gpio_major) {
+		dev = MKDEV(gpio_major, 0);
+		result = register_chrdev_region(dev, gpio_nr_devs, "gpio");
+	} else {
+		result = alloc_chrdev_region(&dev, 0, gpio_nr_devs, "gpio");
+		gpio_major = MAJOR(dev);
+	}
+
+	if (result < 0) {
+		printk(KERN_WARNING "GPIO: can't get major %d\n", gpio_major);
+		return result;
+	}
+
+	gpio_base =(volatile unsigned int *) VA_GPIO_BASE;
+
+	if (!gpio_base) {
+		unregister_chrdev_region(dev, gpio_nr_devs);
+		printk(KERN_WARNING "GPIO: ioremap failed.\n");
+		return -EIO;
+	}
+
+	cnc1900_gpio_class = class_create(THIS_MODULE,"gpio");
+
+	if (IS_ERR(cnc1900_gpio_class)){
+		err = PTR_ERR(cnc1900_gpio_class);
+		unregister_chrdev_region(dev, gpio_nr_devs);
+		printk(KERN_WARNING "GPIO: class create failed.\n");
+		return -EIO;
+	}
+
+	gpio_devices =
+		kzalloc(gpio_nr_devs * sizeof (struct gpio_devs), GFP_KERNEL);
+	if (!gpio_devices) {
+		unregister_chrdev_region(dev, gpio_nr_devs);
+		printk(KERN_WARNING "GPIO cannot allocate device structure\n");
+		return -ENOMEM;
+	}
+	//memset(gpio_devices, 0, gpio_nr_devs * sizeof (struct gpio_devs));
+
+	/* Initialize each device. */
+	for (i = 0; i < gpio_nr_devs; i++) {
+		gpio_devices[i].gpio_id = i;
+		gpio_setup_cdev(&gpio_devices[i], i);
+	}
+
+	spin_lock_init(&gpio_lock);
+
+	printk(KERN_INFO "CNC GPIO at 0x%x, %d lines\n", VA_GPIO_BASE,
+			gpio_nr_devs);
+
+	gpio_proc_entry = create_proc_entry("gpio", 0, NULL);
+	if (NULL != gpio_proc_entry) {
+		gpio_proc_entry->write_proc = &gpio_proc_write;
+		gpio_proc_entry->read_proc = &gpio_proc_read;
+	}
+
+	system_config_proc_entry = create_proc_entry("systemconfig", 0, NULL);
+	if (NULL != system_config_proc_entry) {
+		system_config_proc_entry->read_proc = &system_config_proc_read;
+	}
+
+	// init irq
+	gpio_base[REG_GPIO_INTMASK_B >> 2] = 0xffffffff;
+	gpio_base[REG_GPIO_INTMASK_A >> 2] = 0xffffffff;
+
+	if (0 != request_irq(GPIO_IRQ, (irq_handler_t)gpio_irq_handle, IRQF_DISABLED, "cnc_gpio", NULL)) {
+		printk(KERN_ERR "GPIO: failed to request irq.\n");
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static void __exit cnc_gpio_exit(void)
+{
+	int i;
+	dev_t devno = MKDEV(gpio_major, 0);
+
+	if (gpio_devices) {
+		for (i = 0; i < gpio_nr_devs; i++) {
+			cdev_del(&gpio_devices[i].cdev);
+		}
+		kfree(gpio_devices);
+		gpio_devices = NULL;
+	}
+
+	unregister_chrdev_region(devno, gpio_nr_devs);
+}
+
+// module_init(cnc_gpio_init);
+// module_exit(cnc_gpio_exit);
+postcore_initcall(cnc_gpio_init);
+MODULE_AUTHOR("Cavium");
+MODULE_DESCRIPTION("Cavium Celestial GPIO driver");
+MODULE_LICENSE("GPL");
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/celestial/peripheral/cnc1900_i2c.c linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/peripheral/cnc1900_i2c.c
--- linux-linaro-3.4-2012.05-1_original/drivers/celestial/peripheral/cnc1900_i2c.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/peripheral/cnc1900_i2c.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,1129 @@
+//#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/miscdevice.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/rwsem.h>
+#include <linux/slab.h>
+#include <linux/seq_file.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <mach/hardware.h>
+#include "cnc1900_i2c.h"
+
+
+typedef enum _I2C_ID_
+{
+	_i2c_0      =0,
+	_i2c_1      =1,
+}I2C_ID;
+extern int pinmux_enable_i2c(I2C_ID I2C);
+
+
+#define CFG_I2C_CLK  45000000/1000000
+
+#ifdef CONFIG_CNC1900_I2C_EEPROM
+#define DEV_NUM 0
+#else
+#define DEV_NUM 1
+#endif
+
+#define I2C_SET	       _IOW('I', 0, unsigned long)
+#define I2C_GET        _IOR('I', 1, unsigned long)
+#define I2C_SETSPEED   _IOW('I', 2, unsigned long)
+#define I2C_GETSPEED   _IOR('I', 3, unsigned long)
+#define I2C_SETLOOPADDR   _IOW('I', 4, unsigned long)
+#define I2C_CLRLOOPADDR   _IOW('I', 5, unsigned long)
+#define I2C_GETLOOPINFO     _IOR('I', 6, unsigned long)
+#define I2C_SETCHIPADDRESS  _IOW('I', 7, unsigned long)
+#define I2C_GETCHIPADDRESS  _IOR('I', 8, unsigned long)
+#define I2C_SETADDRALEN     _IOW('I', 9, unsigned long)
+
+#define I2C_SPEED_100K 1
+#define I2C_SPEED_400K 2
+#define i2c_set_speed_100k(x)  x = (void *)(((unsigned long)1<<20) + (unsigned long)((unsigned long)(x) & 0xff0fffff))
+#define i2c_set_speed_400k(x)  x = (void *)(((unsigned long)1<<21) + (unsigned long)((unsigned long)(x) & 0xff0fffff))
+#define i2c_get_speed(x)  ((unsigned long)x >> 20) & 0xf
+
+#define i2c_set_loop_address(x) x = (void *)((1<< 24) + ((unsigned long)x & 0xf0ffffff))
+#define i2c_clr_loop_address(x) x = (void *)((unsigned long)x & 0xf0ffffff)
+#define i2c_get_loop_info(x) ((unsigned long)x>>24) & 0xf
+
+#define i2c_set_chip_address(x,chipaddress) x = (void *)(((unsigned long)x & 0xffffff00) | (chipaddress & 0xff))
+#define i2c_get_chip_address(x) (unsigned char) ((unsigned long)x & 0xff)
+
+#define i2c_get_sleeptime(x) ((unsigned long)x >> 8) & 0xff
+#define i2c_get_chipaddress(x) ((unsigned long)x) & 0xff;
+#define i2c_get_address_alen(x) (((unsigned long)x) >> 16) & 0xff;
+#define i2c_set_address_alen(x,alen) x = (void *)(((unsigned long)x & 0xfff0ffff) | (alen & 0xf)<<16)
+#define i2c_set_default_privatedata(x) x=(void *) (1 << 16)
+
+#define I2C_DEBUG_LEVEL0	(0)	/* Quiet   */
+#define I2C_DEBUG_LEVEL1	(1)	/* Audible */
+#define I2C_DEBUG_LEVEL2	(2)	/* Loud    */
+#define I2C_DEBUG_LEVEL3	(3)	/* Noisy   */
+
+#if 0
+#define CONFIG_CNC1900_I2C_EEPROM
+#define CONFIG_CNC1900_I2C_EEPROM_CHIP_1_ADDR 0x50
+#define CONFIG_CNC1900_I2C_EEPROM_SUBADDR_LEN 2
+#define CONFIG_CNC1900_I2C_EEPROM_PAGE_SIZE 32
+#define CONFIG_CNC1900_I2C_EEPROM_SLEEP_TIME 5
+#endif
+
+
+
+
+#ifdef CONFIG_CELESTIAL_I2C_DEBUG
+#define DEBUG(n, args...)				\
+ 	do {						\
+		if (n <= CONFIG_I2C_DEBUG_VERBOSE)	\
+			printk(KERN_INFO args);		\
+	} while(0)
+#else /* CONFIG_I2C_DEBUG */
+#define DEBUG(n, args...) do { } while(0)
+#endif
+
+static void __iomem *cs_i2c_base;
+static void __iomem *cs_i2c2_base;
+static spinlock_t cs_i2c_lock;
+
+typedef unsigned char uchar;
+static uchar previous_chip;
+static unsigned int previous_speed_cnt;
+
+
+static unsigned int ss_ic_sclh_cnt;
+static unsigned int ss_ic_scl_cnt;
+static unsigned int fs_ic_sclh_cnt;
+static unsigned int fs_ic_scl_cnt;
+static unsigned int default_speed_cnt;
+
+#define i2c_writeb( v,a)    writeb(v, (cs_i2c_base + (a)))
+#define i2c_writew(v,a,n)    ((n==0)?writew(v, (cs_i2c_base + (a))):writew(v, (cs_i2c2_base + (a)))) 
+#define i2c_writel(v,a)    writel(v, (cs_i2c_base + (a)))
+
+#define i2c_readb(a)       readb((cs_i2c_base + (a)))
+
+#define i2c_readw(a,n)    ((n==0)?readw((cs_i2c_base + (a))):readw((cs_i2c2_base + (a))))
+
+		
+#define i2c_readl(a)       readl((cs_i2c_base + (a)))
+
+static int i2c_read(uchar chip,uint addr, unsigned int speed_cnt,int alen,
+	 uchar * buffer, int len,unsigned num)
+{
+    int i;
+	int cmd_cnt;
+	int data_cnt;
+    unsigned int time_cnt;
+	unsigned char *byte_addr = (unsigned char *) &addr;
+	unsigned char *p = buffer;
+
+    time_cnt=0;
+    while(i2c_readw(IC_STAT,num)&0x20)
+    {
+    	if(unlikely(time_cnt>=100000))          //Bus Err
+    	{
+    		i2c_writew(0x1,IC_RESET,num);
+    		i2c_writew(0x0,IC_RESET,num);
+    		i2c_writew(0x1,IC_ENABLE,num);
+    		i2c_writew(0x700,IC_DATA_CMD,num);     //write stop bit
+    		previous_chip = 0;
+    		DEBUG(I2C_DEBUG_LEVEL0,"Error:Timeout!\n");
+    		return 1;
+    	}
+    	time_cnt++;
+    }
+	if(speed_cnt!=previous_speed_cnt)
+		{
+			i2c_writew(0x0, IC_ENABLE,num);
+			while(!(i2c_readw(IC_STAT,num)& 0x1));							//wait disabled
+			if((speed_cnt==ss_ic_scl_cnt))									//Standard Speed
+				{
+					i2c_writew(ss_ic_sclh_cnt,IC_SCLH_CNT,num);
+					i2c_writew(ss_ic_scl_cnt-ss_ic_sclh_cnt,IC_SCLL_CNT,num);
+					previous_speed_cnt = ss_ic_scl_cnt;
+				}
+			else if(speed_cnt==fs_ic_scl_cnt)								//Fast Speed
+				{
+					
+					i2c_writew(fs_ic_sclh_cnt,IC_SCLH_CNT,num);
+					i2c_writew(fs_ic_scl_cnt-fs_ic_sclh_cnt,IC_SCLL_CNT,num);
+					previous_speed_cnt =fs_ic_scl_cnt;
+					
+				}
+		}
+	i2c_writew(0x1, IC_ENABLE,num);
+	
+	if (alen > 0){
+		i2c_writew(((chip<<1)&0xff)|0x100,IC_DATA_CMD,num);
+	}
+	for (i = alen - 1; i >= 0; i--)
+	{
+		i2c_writew(0x200|(byte_addr[i]& 0xff),IC_DATA_CMD,num);
+	}
+	i2c_writew(0x101|((chip<<1)&0xff),IC_DATA_CMD,num);
+	data_cnt = 0;
+	cmd_cnt = 0;
+	time_cnt=0;
+	while (data_cnt < len) {
+		/*if(unlikely(time_cnt>=100000))          //Bus Err
+    	{
+    		i2c_writew(0x1,IC_RESET);
+    		i2c_writew(0x0,IC_RESET);
+    		i2c_writew(0x1,IC_ENABLE);
+    		i2c_writew(0x700,IC_DATA_CMD);     //write stop bit
+    		previous_chip = 0;
+    		DEBUG(I2C_DEBUG_LEVEL0,"Error:Timeout!\n");
+    		return 1;
+    	}*/
+    	time_cnt++;
+    	
+		while ((cmd_cnt < len) && (i2c_readw(IC_STAT,num) & 0x2)) {
+			
+			if(cmd_cnt+1==len)
+				{
+				i2c_writew(0x600,IC_DATA_CMD,num);		//write stop bit
+			  }
+			else
+				{
+				i2c_writew(0x400, IC_DATA_CMD,num);
+			  }
+			cmd_cnt++;
+		}
+
+		if (i2c_readw(IC_STAT,num) & 0x8) {
+			*p = i2c_readw(IC_DATA_CMD,num);
+			p++;
+			data_cnt++;
+		}
+
+		if (unlikely((i=i2c_readw(IC_RAW_INTR_STAT,num)) & 0xe0)) {
+			
+			DEBUG(I2C_DEBUG_LEVEL0,"Chipaddress=0x%x, subaddr=0x%x, IC_RAW_INTR_STAT=0x%x\n",
+			     chip, addr, i);
+			i2c_writew(0x03,IC_FIFO_CLR,num);			//clear tx/rx fifo			
+			if(i&0x40)								//Arbitration Lost
+				{
+					i2c_writew(0x40,IC_INTR_CLR,num);
+					DEBUG(I2C_DEBUG_LEVEL0,"Error:Arbitration lost!\n");
+				}
+			if(i&0x80)
+				{
+					i2c_writew(0x80,IC_INTR_CLR,num);
+					DEBUG(I2C_DEBUG_LEVEL0,"Error:Timeout!\n");
+				}
+			if(i&0x20)								//No ACK
+				{
+					i2c_writew(0x20,IC_INTR_CLR,num);
+					i2c_writew(0x700,IC_DATA_CMD,num);
+					DEBUG(I2C_DEBUG_LEVEL0,"Error:No Slave sends ack!\n");
+				}
+			previous_chip = 0;
+			return -1;
+		}
+	}
+	time_cnt=0;
+	while (!(i2c_readw(IC_STAT,num)&0x04))
+	{
+		if(unlikely(time_cnt>=100000))          //Bus Err
+    	{
+    		i2c_writew(0x1,IC_RESET,num);
+    		i2c_writew(0x0,IC_RESET,num);
+    		i2c_writew(0x1,IC_ENABLE,num);
+    		i2c_writew(0x700,IC_DATA_CMD,num);     //write stop bit
+    		previous_chip = 0;
+    		DEBUG(I2C_DEBUG_LEVEL0,"Error:Timeout!\n");
+    		return 1;
+    	}
+    	time_cnt++;
+    	
+		if (unlikely((i=i2c_readw(IC_RAW_INTR_STAT,num)) & 0xe0)) {
+			
+			DEBUG(I2C_DEBUG_LEVEL0,"Chipaddress=0x%x, subaddr=0x%x, IC_RAW_INTR_STAT=0x%x\n",
+			     chip, addr, i);
+			i2c_writew(0x03,IC_FIFO_CLR,num);			//clear tx/rx fifo			
+			if(i&0x40)								//Arbitration Lost
+				{
+					i2c_writew(0x40,IC_INTR_CLR,num);
+					DEBUG(I2C_DEBUG_LEVEL0,"Error:Arbitration lost!\n");
+				}
+			if(i&0x80)
+				{
+					i2c_writew(0x80,IC_INTR_CLR,num);
+					DEBUG(I2C_DEBUG_LEVEL0,"Error:Timeout!\n");
+				}
+			if(i&0x20)								//No ACK
+				{
+					i2c_writew(0x20,IC_INTR_CLR,num);
+					i2c_writew(0x700,IC_DATA_CMD,num);
+					DEBUG(I2C_DEBUG_LEVEL0,"Error:No Slave sends ack!\n");
+				}
+			previous_chip = 0;
+			return -1;
+			}
+		}             //wait all data send
+		
+	time_cnt=0;
+	while (i2c_readw(IC_STAT,num) & 0x20)
+	{
+		if (unlikely((i=i2c_readw(IC_RAW_INTR_STAT,num)) & 0xe0)) {
+			
+			DEBUG(I2C_DEBUG_LEVEL0,"Chipaddress=0x%x, subaddr=0x%x, IC_RAW_INTR_STAT=0x%x\n",
+			     chip, addr, i);
+			i2c_writew(0x03,IC_FIFO_CLR,num);			//clear tx/rx fifo			
+			if(i&0x40)								//Arbitration Lost
+				{
+					i2c_writew(0x40,IC_INTR_CLR,num);
+					DEBUG(I2C_DEBUG_LEVEL0,"Error:Arbitration lost!\n");
+				}
+			if(i&0x80)
+				{
+					i2c_writew(0x80,IC_INTR_CLR,num);
+					DEBUG(I2C_DEBUG_LEVEL0,"Error:Timeout!\n");
+				}
+			if(i&0x20)								//No ACK
+				{
+					i2c_writew(0x20,IC_INTR_CLR,num);
+					i2c_writew(0x700,IC_DATA_CMD,num);
+					DEBUG(I2C_DEBUG_LEVEL0,"Error:No Slave sends ack!\n");
+				}
+			previous_chip = 0;
+			return -1;
+		}
+		
+		if(unlikely(time_cnt>=100000))          //Bus Err
+    	{
+    		i2c_writew(0x1,IC_RESET,num);
+    		i2c_writew(0x0,IC_RESET,num);
+    		i2c_writew(0x1,IC_ENABLE,num);
+    		i2c_writew(0x700,IC_DATA_CMD,num);     //write stop bit
+    		previous_chip = 0;
+    		DEBUG(I2C_DEBUG_LEVEL0,"Error:Timeout!\n");
+    		return 1;
+    	}
+    	time_cnt++;
+		}
+						//wait for stop signal
+	return 0;
+}
+
+static int
+i2c_write(uchar chip,uint addr, unsigned int speed_cnt, int alen,
+	  uchar * buffer, int len,unsigned num)
+{
+	int i;
+	int data_cnt;
+    unsigned int  time_cnt;
+	unsigned char *byte_addr = (unsigned char *) &addr;
+	unsigned char *p = buffer;
+    
+    time_cnt=0;
+    while(i2c_readw(IC_STAT,num)&0x20)
+    {
+    	if(unlikely(time_cnt>=100000))          //Bus Err
+    	{
+    		i2c_writew(0x1,IC_RESET,num);
+    		i2c_writew(0x0,IC_RESET,num);
+    		i2c_writew(0x1,IC_ENABLE,num);
+    		i2c_writew(0x700,IC_DATA_CMD,num);     //write stop bit
+    		previous_chip = 0;
+    		DEBUG(I2C_DEBUG_LEVEL0,"Error:Timeout!\n");
+    		return 1;
+    	}
+    	time_cnt++;
+    }
+
+if(speed_cnt!=previous_speed_cnt)
+		{
+			i2c_writew(0x0, IC_ENABLE,num);
+			while(!(i2c_readw(IC_STAT,num)& 0x1));							//wait disabled
+			if((speed_cnt==ss_ic_scl_cnt))									//Standard Speed
+				{
+					i2c_writew(ss_ic_sclh_cnt,IC_SCLH_CNT,num);
+					i2c_writew(ss_ic_scl_cnt-ss_ic_sclh_cnt,IC_SCLL_CNT,num);
+					previous_speed_cnt = ss_ic_scl_cnt;
+				}
+			else if(speed_cnt==fs_ic_scl_cnt)								//Fast Speed
+				{
+					
+					i2c_writew(fs_ic_sclh_cnt,IC_SCLH_CNT,num);
+					i2c_writew(fs_ic_scl_cnt-fs_ic_sclh_cnt,IC_SCLL_CNT,num);
+					previous_speed_cnt =fs_ic_scl_cnt;
+					
+				}
+		}
+		
+  i2c_writew(0x1, IC_ENABLE,num);
+	i2c_writew(((chip<<1)&0xff)|0x100,IC_DATA_CMD,num);
+	for (i = alen - 1; i >= 0; i--)
+	{
+		i2c_writew(0x200|byte_addr[i],IC_DATA_CMD,num);
+	}
+	
+	data_cnt = 0;
+
+	time_cnt=0;
+	while (data_cnt < len) {
+		
+		/*if(unlikely(time_cnt>=6000000))          //Bus Err
+    	{
+    		i2c_writew(0x1,IC_RESET);
+    		i2c_writew(0x0,IC_RESET);
+    		i2c_writew(0x1,IC_ENABLE);
+    		i2c_writew(0x700,IC_DATA_CMD);     //write stop bit
+    		previous_chip = 0;
+    		DEBUG(I2C_DEBUG_LEVEL0,"Error:Timeout!\n");
+    		return 1;
+    	}*/
+    	time_cnt++;
+    	
+    	
+		if (i2c_readw(IC_STAT,num) & 0x2) {
+			if(data_cnt!=len-1)
+				{
+				i2c_writew(0x200|(*p), IC_DATA_CMD,num);
+				}
+			else
+				{
+				i2c_writew(0x300|(*p),IC_DATA_CMD,num);				//Stop
+				
+			}
+			p++;
+			data_cnt++;
+		}
+
+		if (unlikely((i=i2c_readw(IC_RAW_INTR_STAT,num)) & 0xe0)) {
+			
+			DEBUG(I2C_DEBUG_LEVEL0,"Chipaddress=0x%x, subaddr=0x%x, IC_RAW_INTR_STAT=0x%x\n",
+			     chip, addr, i);
+			
+			i2c_writew(0x03,IC_FIFO_CLR,num);				//clear tx/rx fifo			
+			if(i&0x40)									//Arbitration Lost
+				{
+					i2c_writew(0x40,IC_INTR_CLR,num);
+					DEBUG(I2C_DEBUG_LEVEL0,"Error:Arbitration lost!\n");
+				}
+			if(i&0x80)
+				{
+					i2c_writew(0x80,IC_INTR_CLR,num);
+					DEBUG(I2C_DEBUG_LEVEL0,"Error:Timeout!\n");
+				}
+			if(i&0x20)									//No ACK
+				{
+					i2c_writew(0x20,IC_INTR_CLR,num);
+					i2c_writew(0x700,IC_DATA_CMD,num);		//Stop
+					DEBUG(I2C_DEBUG_LEVEL0,"Error:No Slave sends ack!\n");
+				}
+			previous_chip = 0;
+			return -1;
+		}
+	}
+
+	time_cnt=0;
+	while (!(i2c_readw(IC_STAT,num)&0x04))
+	{
+		if(unlikely(time_cnt>=100000))          //Bus Err
+    	{
+    		i2c_writew(0x1,IC_RESET,num);
+    		i2c_writew(0x0,IC_RESET,num);
+    		i2c_writew(0x1,IC_ENABLE,num);
+    		i2c_writew(0x700,IC_DATA_CMD,num);     //write stop bit
+    		previous_chip = 0;
+    		DEBUG(I2C_DEBUG_LEVEL0,"Error:Timeout!\n");
+    		return 1;
+    	}
+    	time_cnt++;
+		
+		  if (unlikely((i=i2c_readw(IC_RAW_INTR_STAT,num)) & 0xe0)) {
+			
+			DEBUG(I2C_DEBUG_LEVEL0,"Chipaddress=0x%x, subaddr=0x%x, IC_RAW_INTR_STAT=0x%x\n",
+			     chip, addr, i);
+			i2c_writew(0x03,IC_FIFO_CLR,num);				//clear tx/rx fifo			
+			if(i&0x40)									//Arbitration Lost
+				{
+					i2c_writew(0x40,IC_INTR_CLR,num);
+					DEBUG(I2C_DEBUG_LEVEL0,"Error:Arbitration lost!\n");
+				}
+			if(i&0x80)
+				{
+					i2c_writew(0x80,IC_INTR_CLR,num);
+					DEBUG(I2C_DEBUG_LEVEL0,"Error:Timeout!\n");
+				}
+			if(i&0x20)									//No ACK
+				{
+					i2c_writew(0x20,IC_INTR_CLR,num);
+					i2c_writew(0x700,IC_DATA_CMD,num);		//Stop
+					DEBUG(I2C_DEBUG_LEVEL0,"Error:No Slave sends ack!\n");
+				}
+			previous_chip = 0;
+			return -1;
+		}
+		}             //wait all data send
+	time_cnt=0;
+	while (i2c_readw(IC_STAT,num) & 0x20)
+	{
+			if(unlikely(time_cnt>=100000))          //Bus Err
+    		{
+    			i2c_writew(0x1,IC_RESET,num);
+    			i2c_writew(0x0,IC_RESET,num);
+    			i2c_writew(0x1,IC_ENABLE,num);
+    			i2c_writew(0x700,IC_DATA_CMD,num);     //write stop bit
+    			previous_chip = 0;
+    			DEBUG(I2C_DEBUG_LEVEL0,"Error:Timeout!\n");
+    			return 1;
+    		}
+    		time_cnt++;
+    	
+			if (unlikely((i=i2c_readw(IC_RAW_INTR_STAT,num)) & 0xe0)) {
+			
+			DEBUG(I2C_DEBUG_LEVEL0,"Chipaddress=0x%x, subaddr=0x%x, IC_RAW_INTR_STAT=0x%x\n",
+			     chip, addr, i);
+				
+			i2c_writew(0x03,IC_FIFO_CLR,num);				//clear tx/rx fifo			
+			if(i&0x40)									//Arbitration Lost
+				{
+					i2c_writew(0x40,IC_INTR_CLR,num);
+					DEBUG(I2C_DEBUG_LEVEL0,"Error:Arbitration lost!\n");
+				}
+			if(i&0x80)
+				{
+					i2c_writew(0x80,IC_INTR_CLR,num);
+					DEBUG(I2C_DEBUG_LEVEL0,"Error:Timeout!\n");
+				}
+			if(i&0x20)									//No ACK
+				{
+					i2c_writew(0x20,IC_INTR_CLR,num);
+					i2c_writew(0x700,IC_DATA_CMD,num);		//Stop
+					DEBUG(I2C_DEBUG_LEVEL0,"Error:No Slave sends ack!\n");
+				}
+			previous_chip = 0;
+			return -1;
+		}
+		
+		}
+	return 0;
+}
+
+#ifdef CONFIG_CNC1900_I2C_EEPROM
+static int
+cs_i2c_eeprom_open(struct inode *inode, struct file *file)
+{
+	file->private_data =
+	    (void *) (((CONFIG_CNC1900_I2C_EEPROM_PAGE_SIZE & 0xfff) << 20) |
+		      ((CONFIG_CNC1900_I2C_EEPROM_SUBADDR_LEN & 0xf) << 16) |
+		      ((CONFIG_CNC1900_I2C_EEPROM_SLEEP_TIME & 0xff) << 8) |
+		      ((CONFIG_CNC1900_I2C_EEPROM_CHIP_1_ADDR & 0xff) << 0)
+	    );
+	return 0;
+}
+#endif
+
+#ifdef CONFIG_CNC1900_I2C_MULTI_EEPROMS
+static int
+cs_i2c_multi_eeprom_open(struct inode *inode, struct file *file)
+{
+	file->private_data =
+	    (void *) (((CONFIG_CNC1900_I2C_EEPROM_2_PAGE_SIZE & 0xfff) << 20) |
+		      ((CONFIG_CNC1900_I2C_EEPROM_2_SUBADDR_LEN & 0xf) << 16) |
+		      ((CONFIG_CNC1900_I2C_EEPROM_2_SLEEP_TIME & 0xff) << 8) |
+		      ((CONFIG_CNC1900_I2C_EEPROM_CHIP_2_ADDR & 0xff) << 0)
+	    );
+	return 0;
+}
+#endif
+
+static int
+cs_i2c_open(struct inode *inode, struct file *file)
+{
+       
+#if 1		
+		unsigned m = 0;		
+		i2c_writew(0x0, IC_ENABLE,m);
+		
+#ifdef CONFIG_CNC1900_I2C_FASTSPEED
+		i2c_writew(fs_ic_sclh_cnt, IC_SCLH_CNT,m);
+		i2c_writew(fs_ic_scl_cnt - fs_ic_sclh_cnt, IC_SCLL_CNT,m);
+		previous_speed_cnt = fs_ic_scl_cnt;
+		default_speed_cnt = fs_ic_scl_cnt;
+//		printk(KERN_INFO "CNC I2C default 400KHZ\n");
+#else
+		i2c_writew(ss_ic_sclh_cnt, IC_SCLH_CNT,m);
+		i2c_writew(ss_ic_scl_cnt - ss_ic_sclh_cnt, IC_SCLL_CNT,m);
+		previous_speed_cnt = ss_ic_scl_cnt;
+		default_speed_cnt = ss_ic_scl_cnt;
+
+//		printk(KERN_INFO "CNC I2C default 100KHZ\n");
+#endif
+
+     
+	i2c_set_default_privatedata(file->private_data);
+
+    
+
+
+	if (default_speed_cnt == fs_ic_scl_cnt)
+		i2c_set_speed_400k(file->private_data);
+	else
+		i2c_set_speed_100k(file->private_data);
+
+#endif	
+	
+
+	return 0;
+}
+#ifdef CONFIG_CNC1900_I2C_DEV2
+static int
+cs_i2c2_open(struct inode *inode, struct file *file)
+{
+		unsigned m = 1;
+		i2c_writew(0x0, IC_ENABLE,m);
+#ifdef CONFIG_CNC1900_I2C_FASTSPEED
+		i2c_writew(fs_ic_sclh_cnt, IC_SCLH_CNT,m);
+		i2c_writew(fs_ic_scl_cnt - fs_ic_sclh_cnt, IC_SCLL_CNT,m);
+		previous_speed_cnt = fs_ic_scl_cnt;
+		default_speed_cnt = fs_ic_scl_cnt;
+//		printk(KERN_INFO "CNC I2C2 initial: default 400KHZ\n");
+#else
+		i2c_writew(ss_ic_sclh_cnt, IC_SCLH_CNT,m);
+		i2c_writew(ss_ic_scl_cnt - ss_ic_sclh_cnt, IC_SCLL_CNT,m);
+		previous_speed_cnt = ss_ic_scl_cnt;
+		default_speed_cnt = ss_ic_scl_cnt;
+
+//		printk(KERN_INFO "CNC I2C2 initial:default 100KHZ\n");
+#endif
+	i2c_set_default_privatedata(file->private_data);
+	if (default_speed_cnt == fs_ic_scl_cnt)
+		i2c_set_speed_400k(file->private_data);
+	else
+		i2c_set_speed_100k(file->private_data);
+
+	return 0;
+}
+#endif
+
+
+
+static ssize_t
+cs_i2c_read(struct file *file, char __user * buffer, size_t len,
+	       loff_t * offset)
+{
+	unsigned long flags;
+	unsigned int ret;
+	uchar chip;
+	int alen;
+	int rest;
+	unsigned int burst_len;
+	char *i2c_buffer;
+	char __user *user_ptr;
+	unsigned int speedcnt;
+	unsigned char loop_info;
+	unsigned m;
+	chip = ((unsigned long) file->private_data) & 0xff;
+	alen = (((unsigned long) file->private_data) >> 16) & 0xf;
+	loop_info = (unsigned char) i2c_get_loop_info(file->private_data);
+
+	if (strncmp("cs_i2c1", file->f_dentry->d_iname, 7) == 0)
+		m = 0;
+	else if(strncmp("cs_i2c2", file->f_dentry->d_iname, 7) == 0)
+		m = 1;
+	else{
+			printk("Baffling Error !\n");
+			return -1;	
+		}
+		
+	
+	
+	switch (i2c_get_speed(file->private_data)) {
+	case I2C_SPEED_100K:
+		speedcnt = ss_ic_scl_cnt;
+		break;
+	case I2C_SPEED_400K:
+		speedcnt = fs_ic_scl_cnt;
+		break;
+	default:
+		speedcnt = default_speed_cnt;
+		break;
+	}
+
+	if (loop_info)
+		burst_len = 1;
+	//else if (len > 256)
+	//	burst_len = 256;
+	else
+		burst_len = len;
+
+	i2c_buffer = (char *) kmalloc(burst_len, GFP_KERNEL);
+	user_ptr = buffer;
+	rest = len;
+	DEBUG(I2C_DEBUG_LEVEL0, "burst_len =%d, len=%d,chip=%d,speedcnt=%d, alen=%d,offset=%d\n", burst_len, len,chip,speedcnt,alen,(int)*offset);
+
+	while (rest > 0) {
+
+		spin_lock_irqsave(&cs_i2c_lock, flags);
+		ret =i2c_read(chip,*offset, speedcnt, alen, i2c_buffer, burst_len,m);
+		spin_unlock_irqrestore(&cs_i2c_lock, flags);
+
+		if (unlikely(ret)) {
+			kfree(i2c_buffer);
+			msleep(2);
+			return -EIO;
+		}
+		DEBUG(I2C_DEBUG_LEVEL0, "burst_len =%d, len=%d,speedcnt=%d, alen=%d, chip=%d, offset=%d\n", burst_len, len,speedcnt,alen,chip,(int)*offset);
+
+		if (unlikely(copy_to_user(user_ptr, i2c_buffer, burst_len))) {
+			kfree(i2c_buffer);
+			return -EFAULT;
+		}
+		*offset += burst_len;
+		user_ptr += burst_len;
+		rest -= burst_len;
+		if (rest < burst_len){
+			burst_len = rest;
+		}
+		
+	}
+
+	kfree(i2c_buffer);
+	return len;
+}
+
+
+static ssize_t
+cs_i2c_write(struct file *file, const char __user * buffer, size_t len,
+		loff_t * offset)
+{
+	unsigned long flags;
+	unsigned int ret;
+	uchar chip;
+	int alen;
+	int sleep_time;
+	int rest;
+	unsigned int burst_len;
+	char *i2c_buffer;
+	char *user_ptr;
+	unsigned int speedcnt;
+	unsigned char loop_info;
+	unsigned m;
+
+	chip = ((unsigned long) file->private_data) & 0xff;
+	sleep_time = (((unsigned long) file->private_data) >> 8) & 0xff;
+	alen = (((unsigned long) file->private_data) >> 16) & 0xf;
+	loop_info = (unsigned char) i2c_get_loop_info(file->private_data);
+
+	if (strncmp("cs_i2c1", file->f_dentry->d_iname, 7) == 0)
+		m = 0;
+	else if(strncmp("cs_i2c2", file->f_dentry->d_iname, 7) == 0)
+		m = 1;
+	else{
+		printk("Baffling Error !\n");
+		return -1;	
+		}
+	switch (i2c_get_speed(file->private_data)) {
+	case I2C_SPEED_100K:
+		speedcnt = ss_ic_scl_cnt;
+		break;
+	case I2C_SPEED_400K:
+		speedcnt = fs_ic_scl_cnt;
+		break;
+	default:
+		speedcnt = default_speed_cnt;
+		break;
+	}
+
+	if (loop_info)
+		burst_len = 1;
+	//else if (len > 256)
+		//burst_len = 256;
+	else
+		burst_len = len;
+	i2c_buffer = (char *) kmalloc(burst_len, GFP_KERNEL);
+	user_ptr = (char *) buffer;
+	rest = len;
+
+	DEBUG(I2C_DEBUG_LEVEL3, "burst_len =%d, len=%d,speedcnt=%d, alen=%d, chip=%d, offset=%d, loop_info=%d\n", burst_len, len,speedcnt,alen,chip,(int)*offset,loop_info);
+	while (rest > 0) {
+
+		if (unlikely(copy_from_user(i2c_buffer, user_ptr, burst_len))) {
+			kfree(i2c_buffer);
+			return -EFAULT;
+		}
+		DEBUG(I2C_DEBUG_LEVEL3, "i2c_buffer=%d\n",(*i2c_buffer) & 0xff);
+	       DEBUG(I2C_DEBUG_LEVEL3, "burst_len =%d, len=%d,speedcnt=%d, alen=%d, chip=%d, offset=%d, loop_info=%d\n", burst_len, len,speedcnt,alen,chip,(int)*offset,loop_info);
+		spin_lock_irqsave(&cs_i2c_lock, flags);
+		ret = i2c_write(chip, *offset, speedcnt, alen, i2c_buffer,burst_len,m);
+		spin_unlock_irqrestore(&cs_i2c_lock, flags);
+
+		if (unlikely(ret)) {
+			kfree(i2c_buffer);
+			msleep(2);
+			return -EIO;
+		}
+		*offset += burst_len;
+		user_ptr += burst_len;
+		rest -= burst_len;
+
+		if (rest < burst_len)
+			burst_len = rest;
+
+		if (sleep_time > 0)
+			msleep(sleep_time);
+
+	}
+
+	kfree(i2c_buffer);
+	return len;
+}
+
+
+#ifdef CONFIG_CNC1900_I2C_EEPROM
+static ssize_t
+cs_i2c_eeprom_write(struct file *file, const char __user * buffer,
+		       size_t len, loff_t * offset)
+{
+	unsigned long flags;
+	unsigned int ret;
+	uchar chip;
+	int alen;
+	int sleep_time;
+	int page_size;
+	int rest;
+	int burst_len;
+	char *i2c_buffer;
+	char *user_ptr;
+	
+	chip = ((unsigned long) file->private_data) & 0xff;
+	sleep_time = (((unsigned long) file->private_data) >> 8) & 0xff;
+	alen = (((unsigned long) file->private_data) >> 16) & 0xf;
+	page_size = (((unsigned long) file->private_data) >> 20) & 0xfff;
+	page_size = page_size ? page_size : 256;
+
+	i2c_buffer = (char *) kmalloc(page_size, GFP_KERNEL);
+	user_ptr = (char *) buffer;
+	rest = len;
+
+	while (rest > 0) {
+		if (!sleep_time || !(*offset & (page_size - 1))) {
+			burst_len = rest > page_size ? page_size : rest;
+		} else {
+			/* EEPROM page write */
+			burst_len = page_size - (*offset & (page_size - 1));
+			burst_len = burst_len > rest ? rest : burst_len;
+		}
+
+		if (copy_from_user(i2c_buffer, user_ptr, burst_len)) {
+				kfree(i2c_buffer);
+			return -EFAULT;
+		}
+		spin_lock_irqsave(&cs_i2c_lock, flags);
+		ret =
+			i2c_write(chip, *offset, default_speed_cnt, alen, i2c_buffer, burst_len,DEV_NUM);
+		spin_unlock_irqrestore(&cs_i2c_lock, flags);
+
+		if (ret) {
+			kfree(i2c_buffer);
+			return -EIO;
+		}
+
+		user_ptr += burst_len;
+		*offset += burst_len;
+		rest -= burst_len;
+		if (sleep_time > 0)
+			msleep(sleep_time);
+
+	}
+
+	kfree(i2c_buffer);
+	return len;
+}
+
+static ssize_t
+cs_i2c_eeprom_read(struct file *file, char __user * buffer, size_t len,
+		      loff_t * offset)
+{
+	unsigned long flags;
+	unsigned int ret;
+	uchar chip;
+	int alen;
+	int page_size;
+	int rest;
+	int burst_len;
+	char *i2c_buffer;
+	char *user_ptr;
+	
+	chip = ((unsigned long) file->private_data) & 0xff;
+	alen = (((unsigned long) file->private_data) >> 16) & 0xf;
+	page_size = (((unsigned long) file->private_data) >> 20) & 0xfff;
+	page_size = page_size ? page_size : 256;
+
+	i2c_buffer = (char *) kmalloc(page_size, GFP_KERNEL);
+	user_ptr = buffer;
+	rest = len;
+
+	while (rest > 0) {
+		burst_len = rest > page_size ? page_size : rest;
+
+		spin_lock_irqsave(&cs_i2c_lock, flags);
+		ret = i2c_read(chip, *offset, default_speed_cnt, alen, i2c_buffer,burst_len,DEV_NUM);
+		spin_unlock_irqrestore(&cs_i2c_lock, flags);
+
+		if (ret) {
+			kfree(i2c_buffer);
+			return -EIO;
+		}
+
+		if (copy_to_user(user_ptr, i2c_buffer, burst_len)) {
+			kfree(i2c_buffer);
+			return -EFAULT;
+		}
+
+		user_ptr += burst_len;
+		*offset += burst_len;
+		rest -= burst_len;
+	}
+
+	kfree(i2c_buffer);
+	return len;
+}
+#endif
+
+# if 0
+static loff_t
+cs_i2c_lseek(struct file *file, loff_t offset, int orig)
+{
+	loff_t ret;
+
+	down_read(&file->f_dentry->d_inode->i_alloc_sem);
+	switch (orig) {
+	case 0: /* SEEK_SET*/
+		file->f_pos = offset;
+		ret = file->f_pos;
+		break;
+	case 1: /* SEEK_CUR*/
+		file->f_pos += offset;
+		ret = file->f_pos;
+		break;
+	default:
+		ret = -EINVAL;
+	}
+	up_read(&file->f_dentry->d_inode->i_alloc_sem);
+	return ret;
+}
+#endif
+static loff_t
+cs_i2c_lseek(struct file *file, loff_t offset, int orig)
+{
+	loff_t ret;
+
+	down_read(&file->f_dentry->d_inode->i_sb->s_umount);
+	switch (orig) {
+	case 0: /* SEEK_SET*/
+		file->f_pos = offset;
+		ret = file->f_pos;
+		break;
+	case 1: /* SEEK_CUR*/
+		file->f_pos += offset;
+		ret = file->f_pos;
+		break;
+	default:
+		ret = -EINVAL;
+	}
+	up_read(&file->f_dentry->d_inode->i_sb->s_umount);
+	return ret;
+}
+
+
+static long
+cs_i2c_ioctl(struct file *file,
+		unsigned int cmd, unsigned long arg)
+{
+	char speed;
+	switch (cmd) {
+	case I2C_SET:
+		file->private_data = (void *) arg;
+		return 0;
+	case I2C_GET:
+		return (int) file->private_data;
+
+	case I2C_SETCHIPADDRESS:
+		i2c_set_chip_address(file->private_data, arg);
+		return 0;
+	case I2C_GETCHIPADDRESS:
+		return (int) i2c_get_chip_address(file->private_data);
+	case I2C_SETSPEED:
+		if (arg == I2C_SPEED_100K)
+			i2c_set_speed_100k(file->private_data);
+		else if (arg == I2C_SPEED_400K)
+			i2c_set_speed_400k(file->private_data);
+		else
+			return -EINVAL;
+	case I2C_GETSPEED:
+		speed = i2c_get_speed(file->private_data);
+		if (speed == I2C_SPEED_100K || speed == I2C_SPEED_400K)
+			return (int) speed;
+		else
+			return 0;
+	case I2C_SETLOOPADDR:
+		i2c_set_loop_address(file->private_data);
+		return 0;
+	case I2C_CLRLOOPADDR:
+		i2c_clr_loop_address(file->private_data);
+		return 0;
+	case I2C_GETLOOPINFO:
+		return i2c_get_loop_info(file->private_data);
+
+	case I2C_SETADDRALEN:
+		if (arg >= 0) {
+			i2c_set_address_alen(file->private_data, arg);
+			return 0;
+		} else
+			return -EINVAL;
+	default:
+		return -EINVAL;
+	}
+}
+
+static struct file_operations cs_i2c_fops = {
+	.owner = THIS_MODULE,
+	.read = cs_i2c_read,
+	.write = cs_i2c_write,
+	.llseek = cs_i2c_lseek,
+	.unlocked_ioctl = cs_i2c_ioctl,
+	.open = cs_i2c_open,
+};
+
+static struct miscdevice cs_i2c_miscdev = {
+    .name="cs_i2c1",
+	.minor =MISC_DYNAMIC_MINOR,
+	.fops=&cs_i2c_fops
+};
+
+
+
+
+#ifdef CONFIG_CNC1900_I2C_EEPROM
+static struct file_operations cs_i2c_eeprom_fops = {
+	.owner = THIS_MODULE,
+	.open = cs_i2c_eeprom_open,
+	.read = cs_i2c_eeprom_read,
+	.write = cs_i2c_eeprom_write,
+	.llseek = cs_i2c_lseek,
+};
+
+static struct miscdevice cs_i2c_eeprom_miscdev = {
+	MISC_DYNAMIC_MINOR,
+	"eeprom",
+	&cs_i2c_eeprom_fops
+};
+#endif
+
+#ifdef CONFIG_CNC1900_I2C_MULTI_EEPROMS
+static struct file_operations cs_i2c_multi_eeprom_fops = {
+	.owner = THIS_MODULE,
+	.open = cs_i2c_multi_eeprom_open,
+	.read = cs_i2c_eeprom_read,
+	.write = cs_i2c_eeprom_write,
+	.llseek = cs_i2c_lseek,
+};
+
+static struct miscdevice cs_i2c_multi_eeprom_miscdev = {
+	MISC_DYNAMIC_MINOR,
+	"eeprom2",
+	&cs_i2c_multi_eeprom_fops
+};
+#endif
+
+#ifdef CONFIG_CNC1900_I2C_DEV2
+static struct file_operations cs_i2c_dev2_fops = {
+	.owner = THIS_MODULE,
+	.read = cs_i2c_read,
+	.write = cs_i2c_write,
+	.llseek = cs_i2c_lseek,
+	.unlocked_ioctl = cs_i2c_ioctl,
+	.open = cs_i2c2_open,
+};
+
+static struct miscdevice cs_i2c_dev2_miscdev = {
+	MISC_DYNAMIC_MINOR,
+	"cs_i2c2",
+	&cs_i2c_dev2_fops
+};
+#endif
+
+int __init
+cs_i2c_init(void)
+{
+   
+	if (misc_register(&cs_i2c_miscdev))
+		{
+		
+		return -ENODEV;
+		}
+
+	
+
+#ifdef CONFIG_CNC1900_I2C_EEPROM
+	if (misc_register(&cs_i2c_eeprom_miscdev))
+		return -ENODEV;
+#endif
+#ifdef CONFIG_CNC1900_I2C_DEV2
+	if (misc_register(&cs_i2c_dev2_miscdev))
+		return -ENODEV;
+#endif
+
+#ifdef CONFIG_CNC1900_I2C_MULTI_EEPROMS
+	if (misc_register(&cs_i2c_multi_eeprom_miscdev))
+		return -ENODEV;
+#endif
+
+
+	cs_i2c_base =(void *) VA_I2C_BASE; 
+
+	
+
+#ifdef CONFIG_CNC1900_I2C_DEV2
+	pinmux_enable_i2c(1);
+	cs_i2c2_base =(void *) VA_I2C2_BASE; 
+
+	 
+#endif
+	{
+
+		ss_ic_sclh_cnt = (10 * CFG_I2C_CLK) / 4 ;
+		ss_ic_scl_cnt = CFG_I2C_CLK * 5;
+
+		fs_ic_sclh_cnt = (10 * CFG_I2C_CLK) / 24 ;
+		fs_ic_scl_cnt = (CFG_I2C_CLK * 10) / 8 ;
+
+
+	}
+
+	spin_lock_init(&cs_i2c_lock);
+
+	
+
+	return 0;
+}
+
+static void __exit
+cs_i2c_exit(void)
+{
+
+	misc_deregister(&cs_i2c_miscdev);
+
+}
+
+module_init(cs_i2c_init);
+module_exit(cs_i2c_exit);
+
+
+
+//MODULE_AUTHOR("Cavium Celestial SDK team");
+//MODULE_DESCRIPTION("Cavium Celestial I2c Controller driver");
+MODULE_LICENSE("GPL");
+
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/celestial/peripheral/cnc1900_i2c.h linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/peripheral/cnc1900_i2c.h
--- linux-linaro-3.4-2012.05-1_original/drivers/celestial/peripheral/cnc1900_i2c.h	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/peripheral/cnc1900_i2c.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,24 @@
+#ifndef __CELESTIAL_I2C_H__
+#define	__CELESTIAL_I2C_H__
+
+#define		IC_ENABLE			0x00
+#define		IC_SCLH_CNT			0x04
+#define		IC_SCLL_CNT			0x08
+#define		IC_DATA_CMD			0x0c
+#define		IC_INTR_STAT		0x10
+#define		IC_RAW_INTR_STAT	0x14
+#define		IC_INTR_MASK		0x18
+#define		IC_INTR_CLR			0x1c
+#define		IC_STAT				0x20
+#define		IC_RX_TL			0x24
+#define		IC_TX_TL			0x28
+#define		IC_TXFLR			0x2c
+#define		IC_RXFLR			0x30
+#define		IC_FIFO_CLR			0x34
+#define		IC_RESET			0x38
+#define		IC_SLV_TIMEOUT_L	0x3c
+#define		IC_SLV_TIMEOUT_H	0x3e	
+#define		IC_SLV_TIMEOUT_EN	0x40
+
+#endif
+
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/celestial/peripheral/cnc1900_nand.c linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/peripheral/cnc1900_nand.c
--- linux-linaro-3.4-2012.05-1_original/drivers/celestial/peripheral/cnc1900_nand.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/peripheral/cnc1900_nand.c	2014-10-23 20:22:19.978715000 +0800
@@ -0,0 +1,242 @@
+/*
+ *  drivers/mtd/nand/xx.c
+ *
+ *  Copyrigth (C) 2010 Celestial Semiconductor
+ *                2011 Cavium
+ *
+ * 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 <linux/slab.h>
+#include <linux/io.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/mtd/partitions.h>
+#include <linux/platform_device.h>
+
+#include <mach/nand.h>
+
+struct plat_runtime {
+	struct plat_cncnand_port *cur;
+	struct plat_cncnand_port *ports;
+};
+
+static void cnc_nand_hwctl(struct mtd_info *mtd, int mode)
+{
+	struct nand_chip *nand = mtd->priv;
+	struct plat_runtime *runtime = nand->priv;
+
+	if (mode == NAND_ECC_READ)
+		__raw_writel(runtime->cur->membase + (nand->IO_ADDR_R - runtime->cur->mapbase),
+			runtime->cur->reg_base + ECC_ADDRESS);
+
+	if (mode == NAND_ECC_WRITE)
+		__raw_writel(runtime->cur->membase + (nand->IO_ADDR_W - runtime->cur->mapbase),
+			runtime->cur->reg_base + ECC_ADDRESS);
+}
+
+/*
+ * Read hardware ECC value and pack into three bytes
+ */
+static int cnc_nand_calculate(struct mtd_info *mtd,
+		const u_char *dat, u_char *ecc_code)
+{
+	struct nand_chip *nand = mtd->priv;
+	struct plat_runtime *runtime = nand->priv;
+	unsigned int ecc = __raw_readl(runtime->cur->reg_base + ECC_CODE);
+
+	ecc_code[0] = (u_char)(ecc);
+	ecc_code[1] = (u_char)(ecc >> 8);
+	ecc_code[2] = (u_char)(ecc >> 16);
+	return 0;
+}
+
+static int cnc_nand_dev_ready(struct mtd_info *mtd)
+{
+	struct nand_chip *nand = mtd->priv;
+	struct plat_runtime *runtime = nand->priv;
+	unsigned int st = __raw_readl(runtime->cur->reg_base + STATUS);
+
+	return st & STATUS_READY;
+}
+
+static void cnc_nand_read_buf(struct mtd_info *mtd, u8 *buf, int len)
+{
+	struct nand_chip *nand = mtd->priv;
+
+	if (len % 4)
+		__raw_readsb(nand->IO_ADDR_R, buf, len);
+	else
+		__raw_readsl(nand->IO_ADDR_R, buf, len / 4);
+}
+
+static void cnc_nand_write_buf(struct mtd_info *mtd, const u8 *buf, int len)
+{
+	struct nand_chip *nand = mtd->priv;
+
+	if (len % 4)
+		__raw_writesb(nand->IO_ADDR_W, buf, len);
+	else
+		__raw_writesl(nand->IO_ADDR_W, buf, len / 4);
+}
+
+static void cnc_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
+{
+	struct nand_chip *nand = mtd->priv;
+	struct plat_runtime *runtime = nand->priv;
+	unsigned int addr = (u32)runtime->cur->mapbase;
+
+	if (ctrl & NAND_CTRL_CHANGE) {
+		if (ctrl & NAND_CLE)
+			addr |= runtime->cur->cle;
+		if (ctrl & NAND_ALE)
+			addr |= runtime->cur->ale;
+
+		nand->IO_ADDR_W = (void *)addr; 
+	}
+
+	if (cmd != NAND_CMD_NONE)
+		iowrite8(cmd, nand->IO_ADDR_W);
+}
+
+static void cnc_nand_select_chip(struct mtd_info *mtd, int chip)
+{
+	struct nand_chip *nand = mtd->priv;
+	struct plat_runtime *runtime = nand->priv;
+	unsigned int cfg0 = 0;
+
+	if (chip >= 0) {
+		runtime->cur = runtime->ports + chip;
+		nand->IO_ADDR_R = nand->IO_ADDR_W = runtime->cur->mapbase;
+		cfg0 = __raw_readl(runtime->cur->reg_port + CEN_CFG_0);
+		__raw_writel(cfg0 | FORCE_CE_LOW, runtime->cur->reg_port + CEN_CFG_0);
+	} else if (runtime->cur) {
+		cfg0 = __raw_readl(runtime->cur->reg_port + CEN_CFG_0);
+		__raw_writel(cfg0 & ~FORCE_CE_LOW, runtime->cur->reg_port + CEN_CFG_0);
+		nand->IO_ADDR_R = nand->IO_ADDR_W = runtime->cur = NULL;
+	}
+}
+
+static int __init cnc_nand_probe(struct platform_device *pdev)
+{
+	struct plat_cncnand_port *p = pdev->dev.platform_data;
+	struct mtd_info *mtd = NULL;
+	struct nand_chip *nand = NULL;
+	struct plat_runtime *runtime = NULL;
+	int chips = 0, ret = 0;
+
+	for (; p && p->membase; p++, chips++) {
+		p->mapbase = ioremap(p->membase, SZ_8M);
+		if (!p->mapbase) {
+			dev_err(&pdev->dev, "ioremap failed\n");
+			ret = -EINVAL;
+			goto err;
+		}
+	}
+
+	if (!chips)
+		return -ENODEV;
+
+	mtd = (struct mtd_info *)kzalloc(sizeof(struct mtd_info), GFP_KERNEL);
+	nand = (struct nand_chip *)kzalloc(sizeof(struct nand_chip), GFP_KERNEL);
+	runtime = (struct plat_runtime *)kzalloc(sizeof(struct plat_runtime), GFP_KERNEL);
+	if (!mtd || !nand || !runtime) {
+		dev_err(&pdev->dev, "unable to allocate memory\n");
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	mtd->priv = nand;
+	nand->priv = runtime;
+	runtime->ports = pdev->dev.platform_data;
+	platform_set_drvdata(pdev, mtd);
+
+	mtd->name		= dev_name(&pdev->dev);
+	mtd->owner		= THIS_MODULE;
+	nand->numchips  = chips;
+	nand->bbt_options = NAND_BBT_USE_FLASH;
+
+	/* Set address of hardware control function */
+	nand->select_chip = cnc_nand_select_chip;
+	nand->cmd_ctrl	  = cnc_nand_cmd_ctrl;
+	nand->dev_ready	  = cnc_nand_dev_ready;
+
+	/* Speed up buffer I/O */
+	nand->read_buf    = cnc_nand_read_buf;
+	nand->write_buf   = cnc_nand_write_buf;
+
+	/* Use board-specific ECC config */
+	nand->ecc.mode      = NAND_ECC_HW;
+	nand->ecc.hwctl     = cnc_nand_hwctl;
+	nand->ecc.calculate = cnc_nand_calculate;
+	nand->ecc.correct   = nand_correct_data;
+	nand->ecc.size      = 512;
+	nand->ecc.bytes     = 3;
+
+	ret = nand_scan(mtd, nand->numchips);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "no NAND chip(s) found\n");
+		goto err;
+	}
+
+    return mtd_device_parse_register(mtd, NULL, NULL, NULL, 0);
+
+err:
+	for (p = pdev->dev.platform_data; p && p->mapbase; p++) {
+		if (p->mapbase)
+			iounmap(p->mapbase);
+	}
+	if (mtd)
+		kfree(mtd);
+	if (nand)
+		kfree(nand);
+	if (runtime)
+		kfree(runtime);
+	return ret;
+}
+
+static int __exit cnc_nand_remove(struct platform_device *pdev)
+{
+	struct plat_cncnand_port *p = pdev->dev.platform_data;
+	struct mtd_info *mtd = platform_get_drvdata(pdev);
+	for (; p && p->mapbase; p++) {
+		if (p->mapbase)
+			iounmap(p->mapbase);
+	}
+
+	nand_release(mtd);
+	kfree(mtd->priv);
+	kfree(mtd);
+	return 0;
+}
+
+static struct platform_driver cnc_nand_driver = {
+	.remove		= __exit_p(cnc_nand_remove),
+	.driver		= {
+		.name	= "cnc-nand",
+		.owner	= THIS_MODULE,
+	},
+};
+
+static int __init cnc_nand_init(void)
+{
+	return platform_driver_probe(&cnc_nand_driver, cnc_nand_probe);
+}
+
+static void __exit cnc_nand_exit(void)
+{
+	platform_driver_unregister(&cnc_nand_driver);
+}
+
+module_init(cnc_nand_init);
+module_exit(cnc_nand_exit);
+
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("xiaodong fan <xiaodong.fan@caviumnetworks.com>");
+MODULE_DESCRIPTION("NAND flash driver for Cavium celestial SOC");
+MODULE_ALIAS("platform:cnc-nand");
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/celestial/peripheral/eth.c linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/peripheral/eth.c
--- linux-linaro-3.4-2012.05-1_original/drivers/celestial/peripheral/eth.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/peripheral/eth.c	2015-08-06 17:17:34.924148000 +0800
@@ -0,0 +1,910 @@
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/mii.h>
+
+#include <linux/interrupt.h>
+#include <linux/dma-mapping.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <linux/crc32.h>
+#include <asm/cacheflush.h>
+
+#include <linux/seq_file.h>
+#include <linux/proc_fs.h>
+
+#include "mach/cnc1900_power_clk.h"
+
+#define	ETH_CFG_ADDR		    0x0800
+#define	ETH_INT_REG_ADDR        0x0840
+#define	ETH_INT_ENB_ADDR        0x0844
+#define	ETH_INT_SET_ADDR        0x0848
+#define	ETH_INT_CLS_ADDR        0x084C
+
+#define	ETH_TX_DMA_ADDR        	(priv->ctl_offset + 0x09C0)
+#define	ETH_TX_STAT_ADDR     	(priv->ctl_offset + 0x09C4)
+#define	ETH_RX_BASE_ADDR       	(priv->ctl_offset + 0x09C8)
+#define	ETH_RX_CFG_ADDR        	(priv->ctl_offset + 0x09CC)
+#define	ETH_RX_RD_ADDR         	(priv->ctl_offset + 0x09D0)
+#define	ETH_RX_WR_ADDR         	(priv->ctl_offset + 0x09D4)
+#define	ETH_RX_STAT_ADDR     	(priv->ctl_offset + 0x09DC)
+
+#define	ETH_MAC_CFG0          	(priv->mac_offset + 0x0A40)
+#define	ETH_MAC_CFG1          	(priv->mac_offset + 0x0A44)
+#define	ETH_MAC_IPGT          	(priv->mac_offset + 0x0A48)
+#define	ETH_MAC_IPGR          	(priv->mac_offset + 0x0A4C)
+#define	ETH_MAC_CLRT          	(priv->mac_offset + 0x0A50)
+#define	ETH_MAC_MAXF          	(priv->mac_offset + 0x0A54)
+#define	ETH_MAC_SUPP          	(priv->mac_offset + 0x0A58)
+#define	ETH_MAC_TEST          	(priv->mac_offset + 0x0A5C)
+#define	ETH_MAC_MCFG          	(0x0A60)
+#define	ETH_MAC_MCMD          	(0x0A64)
+#define	ETH_MAC_MADR          	(0x0A68)
+#define	ETH_MAC_MWTD          	(0x0A6C)
+#define	ETH_MAC_MRDD          	(0x0A70)
+#define	ETH_MAC_MIND          	(0x0A74)
+#define	ETH_MAC_SA0           	(priv->mac_offset + 0x0A80)
+#define	ETH_MAC_SA1           	(priv->mac_offset + 0x0A84)
+#define	ETH_MAC_SA2           	(priv->mac_offset + 0x0A88)
+#define	ETH_MAC_TSV0           	(priv->mac_offset + 0x0A8C)
+#define	ETH_MAC_TSV1           	(priv->mac_offset + 0x0A90)
+#define	ETH_MAC_RSV            	(priv->mac_offset + 0x0A94)
+#define	ETH_MAC_SA_MASK        	(priv->mac_offset + 0x0A98)
+#define	ETH_MAC_HASH_TAB0      	(priv->mac_offset + 0x0A9C)
+#define	ETH_MAC_HASH_TAB1      	(priv->mac_offset + 0x0AA0)
+
+#define	ETH0_CTL_BASE			0x09C0
+#define	ETH0_MAC_BASE			0x0A40
+#define	ETH1_CTL_BASE			0x0A00
+#define	ETH1_MAC_BASE			0x0AC0
+
+#define ETH_INT_TX		(0x01 << priv->shift)
+#define ETH_INT_RX		(0x02 << priv->shift)
+#define ETH_INT_HALF	(0x04 << priv->shift)
+#define ETH_INT_MASK	(0x07 << priv->shift)
+
+#define ETH_FIFO_TOG		0x80000000
+#define ETH_FIFO_EMPTY		0x40000000
+#define ETH_FIFO_MASK		0x00000FFF
+
+#define RX_ITEM_SIZE 	1544
+#define RX_ITEM_MAX 	255
+#define TX_ITEM_SIZE	1552
+
+#define DEBUG(...)
+//#define DEBUG printk
+
+struct tx_desc
+{
+	volatile u32 buffer_addr;
+	volatile u32 buffer_len;
+	volatile u32 next_link_item;
+	volatile u32 next_item_valid_flag;
+};
+
+struct rx_unit
+{
+	volatile u32 reserved;
+	volatile u32 size;
+	u8 packet[4];
+};
+
+struct cn100_private
+{
+	void __iomem *iomem;
+	struct net_device *netdev;
+
+	struct napi_struct napi;
+
+	spinlock_t tx_lock;
+	spinlock_t rx_lock;
+
+	spinlock_t lock;
+	struct mii_if_info mii;
+	struct timer_list timer;
+
+	/* RX and TX Buffer Info */
+
+	int shift;
+	int ctl_offset;
+	int mac_offset;
+
+	int dma_size;
+	dma_addr_t dma_addr;
+	void __iomem *dma_area;
+
+	dma_addr_t tx_desc_addr;
+	void __iomem *tx_data_area;
+	struct tx_desc *tx_desc_p;
+
+	dma_addr_t rx_fifo_addr;
+	struct rx_unit *rx_fifo_p[RX_ITEM_MAX];
+	int rx_fifo_num;
+};
+
+/*
+ * SQOS hook handling functionality
+ * sqos submodule in Purevu driver will register hook handlers
+ * net drivers will call hook functions if they are non-null
+ */
+typedef int ( *pfn_cvm_on_before_skb_tx )           ( struct net_device* net_dev, struct sk_buff *skb );
+typedef int ( *pfn_cvm_on_skb_tx_done )             ( struct net_device* net_dev, struct sk_buff *skb );
+typedef int ( *pfn_cvm_on_skb_dropped )             ( struct net_device* net_dev, struct sk_buff *skb );
+typedef int ( *pfn_cvm_on_tx_rate_limit_changed )   ( struct net_device* net_dev, int worst_stream_rate_in_mbps, int combined_stream_rate_in_mbps, int worst_stream_udp_rate_in_mbps, int combined_stream_udp_rate_in_mbps );
+typedef int ( *pfn_cvm_on_tx_skb_cloned )           ( struct net_device* net_dev, struct sk_buff *skb, struct sk_buff* new_skb );
+
+/*
+ * Before sk_buff is put on ip transmit queue
+ */
+pfn_cvm_on_before_skb_tx cvm_on_before_skb_tx_ip;
+
+/*
+ * Before sk_buff is put on device transmit queue
+ */
+pfn_cvm_on_before_skb_tx cvm_on_before_skb_tx;
+
+/*
+ * After device is done transmitting sk_buff
+ */
+pfn_cvm_on_skb_tx_done cvm_on_skb_tx_done;
+
+/*
+ * If the device drops sk_buff
+ */
+pfn_cvm_on_skb_dropped cvm_on_skb_dropped;
+
+/*
+ * When tx_rate changes,
+ * device has to provide
+ * 1) worst tx rate and corresponding udp rate in case of multiple connections
+ * 2) maximum tx rate which will support all connections simultaneously
+ *
+ * eg. in wifi ap with 2 stations connected at sta1( 24mbps ), sta2 ( 54 mbps )
+ * if max supported rate of ap is 54
+ * worst tx rate will be 24
+ * combined tx rate can probably be weighted average of 24 and 54
+ * since ap's max rate is 54, it is being shared by sta1 and sta 2
+ *
+ */
+pfn_cvm_on_tx_rate_limit_changed cvm_on_tx_rate_limit_changed;
+
+/*
+ * if the device clones original sk_buff
+ */
+pfn_cvm_on_tx_skb_cloned cvm_on_tx_skb_cloned;
+
+EXPORT_SYMBOL( cvm_on_before_skb_tx_ip );
+EXPORT_SYMBOL( cvm_on_before_skb_tx );
+EXPORT_SYMBOL( cvm_on_skb_tx_done );
+EXPORT_SYMBOL( cvm_on_skb_dropped );
+EXPORT_SYMBOL( cvm_on_tx_rate_limit_changed );
+EXPORT_SYMBOL( cvm_on_tx_skb_cloned );
+
+static int show_proc_eth(struct seq_file *m, void *v, int eth)
+{
+	struct {
+		int ctl_offset; int mac_offset;
+	} *priv, priv_offsets[2] = {
+		/* eth0: */ { .ctl_offset = 0, .mac_offset = 0 },
+		/* eth1: */ { .ctl_offset = ETH1_CTL_BASE - ETH0_CTL_BASE, .mac_offset = ETH1_MAC_BASE - ETH0_MAC_BASE }
+	};
+	static void *eth_virt_base_addr = NULL;
+
+	if (eth_virt_base_addr == NULL) {
+		eth_virt_base_addr = ioremap(0xB1400000, 0x1000);
+	}
+
+	if (eth_virt_base_addr == NULL) return -1;
+
+	priv = &priv_offsets[eth]; // priv->... is used in the following macros
+#define READ_ETH(addr) __raw_readl(eth_virt_base_addr + (addr))
+
+	seq_printf(m, "eth%d:\n", eth);
+
+	seq_printf(m, "%08x <= ETH_CFG_ADDR\n", READ_ETH(ETH_CFG_ADDR));
+	seq_printf(m, "%08x <= ETH_INT_REG_ADDR\n", READ_ETH(ETH_INT_REG_ADDR));
+	seq_printf(m, "%08x <= ETH_INT_ENB_ADDR\n", READ_ETH(ETH_INT_ENB_ADDR));
+	seq_printf(m, "%08x <= ETH_INT_SET_ADDR\n", READ_ETH(ETH_INT_SET_ADDR));
+	seq_printf(m, "%08x <= ETH_INT_CLS_ADDR\n", READ_ETH(ETH_INT_CLS_ADDR));
+
+	seq_printf(m, "%08x <= ETH_TX_DMA_ADDR\n", READ_ETH(ETH_TX_DMA_ADDR));
+	seq_printf(m, "%08x <= ETH_TX_STAT_ADDR\n", READ_ETH(ETH_TX_STAT_ADDR));
+	seq_printf(m, "%08x <= ETH_RX_BASE_ADDR\n", READ_ETH(ETH_RX_BASE_ADDR));
+	seq_printf(m, "%08x <= ETH_RX_CFG_ADDR\n", READ_ETH(ETH_RX_CFG_ADDR));
+	seq_printf(m, "%08x <= ETH_RX_RD_ADDR\n", READ_ETH(ETH_RX_RD_ADDR));
+	seq_printf(m, "%08x <= ETH_RX_WR_ADDR\n", READ_ETH(ETH_RX_WR_ADDR));
+	seq_printf(m, "%08x <= ETH_RX_STAT_ADDR\n", READ_ETH(ETH_RX_STAT_ADDR));
+
+	seq_printf(m, "%08x <= ETH_MAC_CFG0\n", READ_ETH(ETH_MAC_CFG0));
+	seq_printf(m, "%08x <= ETH_MAC_CFG1\n", READ_ETH(ETH_MAC_CFG1));
+	seq_printf(m, "%08x <= ETH_MAC_IPGT\n", READ_ETH(ETH_MAC_IPGT));
+	seq_printf(m, "%08x <= ETH_MAC_IPGR\n", READ_ETH(ETH_MAC_IPGR));
+	seq_printf(m, "%08x <= ETH_MAC_CLRT\n", READ_ETH(ETH_MAC_CLRT));
+	seq_printf(m, "%08x <= ETH_MAC_MAXF\n", READ_ETH(ETH_MAC_MAXF));
+	seq_printf(m, "%08x <= ETH_MAC_SUPP\n", READ_ETH(ETH_MAC_SUPP));
+	seq_printf(m, "%08x <= ETH_MAC_TEST\n", READ_ETH(ETH_MAC_TEST));
+	seq_printf(m, "%08x <= ETH_MAC_MCFG\n", READ_ETH(ETH_MAC_MCFG));
+	seq_printf(m, "%08x <= ETH_MAC_MCMD\n", READ_ETH(ETH_MAC_MCMD));
+	seq_printf(m, "%08x <= ETH_MAC_MADR\n", READ_ETH(ETH_MAC_MADR));
+	seq_printf(m, "%08x <= ETH_MAC_MWTD\n", READ_ETH(ETH_MAC_MWTD));
+	seq_printf(m, "%08x <= ETH_MAC_MRDD\n", READ_ETH(ETH_MAC_MRDD));
+	seq_printf(m, "%08x <= ETH_MAC_MIND\n", READ_ETH(ETH_MAC_MIND));
+	seq_printf(m, "%08x <= ETH_MAC_SA0\n", READ_ETH(ETH_MAC_SA0));
+	seq_printf(m, "%08x <= ETH_MAC_SA1\n", READ_ETH(ETH_MAC_SA1));
+	seq_printf(m, "%08x <= ETH_MAC_SA2\n", READ_ETH(ETH_MAC_SA2));
+	seq_printf(m, "%08x <= ETH_MAC_TSV0\n", READ_ETH(ETH_MAC_TSV0));
+	seq_printf(m, "%08x <= ETH_MAC_TSV1\n", READ_ETH(ETH_MAC_TSV1));
+	seq_printf(m, "%08x <= ETH_MAC_RSV\n", READ_ETH(ETH_MAC_RSV));
+	seq_printf(m, "%08x <= ETH_MAC_SA_MASK\n", READ_ETH(ETH_MAC_SA_MASK));
+	seq_printf(m, "%08x <= ETH_MAC_HASH_TAB0\n", READ_ETH(ETH_MAC_HASH_TAB0));
+	seq_printf(m, "%08x <= ETH_MAC_HASH_TAB1\n", READ_ETH(ETH_MAC_HASH_TAB1));
+
+	return 0;
+}
+
+static int show_proc_eth0(struct seq_file *m, void *v)
+{
+	return show_proc_eth(m, v, 0);
+}
+
+static int show_proc_eth1(struct seq_file *m, void *v)
+{
+	return show_proc_eth(m, v, 1);
+}
+
+/**
+ * /proc/eth0 was openned. Use the single_open iterator
+ *
+ * @param inode
+ * @param file
+ * @return
+ */
+static int proc_eth0_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, show_proc_eth0, NULL);
+}
+
+/**
+ * /proc/eth1 was openned. Use the single_open iterator
+ *
+ * @param inode
+ * @param file
+ * @return
+ */
+static int proc_eth1_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, show_proc_eth1, NULL);
+}
+
+static struct file_operations proc_eth0_operations = {
+	.open           = proc_eth0_open,
+	.read           = seq_read,
+	.llseek         = seq_lseek,
+	.release        = single_release,
+};
+
+static struct file_operations proc_eth1_operations = {
+	.open           = proc_eth1_open,
+	.read           = seq_read,
+	.llseek         = seq_lseek,
+	.release        = single_release,
+};
+
+static int __init eth_proc_init(void)
+{
+	static struct proc_dir_entry *entry;
+	if (entry) return 0;
+
+	entry = create_proc_entry("eth0", 0, NULL);
+	if (entry) {
+		entry->proc_fops = &proc_eth0_operations;
+	}
+	entry = create_proc_entry("eth1", 0, NULL);
+	if (entry) {
+		entry->proc_fops = &proc_eth1_operations;
+	}
+	return 0;
+}
+
+static unsigned char MacAddr[] = {0x00, 0x1A, 0xCC, 0x00, 0x00, 0x00};
+static unsigned char MacAddr1[] = {0x00, 0x1A, 0xCC, 0x00, 0x00, 0x01};
+
+static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+	struct cn100_private *priv = netdev_priv(dev);
+	int rc;
+
+	if (!netif_running(dev))
+		return -EINVAL;
+
+	spin_lock_irq(&priv->lock);
+	rc = generic_mii_ioctl(&priv->mii, if_mii(rq), cmd, NULL);
+	spin_unlock_irq(&priv->lock);
+	return rc;
+}
+
+static int netdev_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+	struct cn100_private *priv = netdev_priv(dev);
+	int rc;
+
+	spin_lock_irq(&priv->lock);
+	rc = mii_ethtool_gset(&priv->mii, cmd);
+	spin_unlock_irq(&priv->lock);
+	return rc;
+}
+
+static int netdev_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+	struct cn100_private *priv = netdev_priv(dev);
+	int rc;
+
+	spin_lock_irq(&priv->lock);
+	rc = mii_ethtool_sset(&priv->mii, cmd);
+	spin_unlock_irq(&priv->lock);
+	return rc;
+}
+
+static int netdev_nway_reset(struct net_device *dev)
+{
+	struct cn100_private *priv = netdev_priv(dev);
+	return mii_nway_restart(&priv->mii);
+}
+
+static u32 netdev_get_link(struct net_device *dev)
+{
+	struct cn100_private *priv = netdev_priv(dev);
+	return mii_link_ok(&priv->mii);
+}
+
+static struct ethtool_ops netdev_ethtool_ops = {
+	.get_settings = netdev_get_settings,
+	.set_settings = netdev_set_settings,
+	.nway_reset = netdev_nway_reset,
+	.get_link   = netdev_get_link,
+};
+
+static void cn100_hw_set_addr(unsigned char *MacAddr, struct cn100_private *priv)
+{
+	__raw_writel((MacAddr[1] << 8) | MacAddr[0], priv->iomem + ETH_MAC_SA2);
+	__raw_writel((MacAddr[3] << 8) | MacAddr[2], priv->iomem + ETH_MAC_SA1);
+	__raw_writel((MacAddr[5] << 8) | MacAddr[4], priv->iomem + ETH_MAC_SA0);
+}
+
+static int cn100_set_mac_address(struct net_device *dev, void *addr)
+{
+	struct cn100_private *priv = netdev_priv(dev);
+	int ret = eth_mac_addr(dev, addr);
+	if (ret < 0)
+		return ret;
+
+	/*	memcpy(MacAddr, dev->dev_addr, ETH_ALEN);*/
+	cn100_hw_set_addr(dev->dev_addr, priv);
+	return 0;
+}
+
+static inline void __raw_clearbit(unsigned int mask, volatile void __iomem *addr)
+{
+	unsigned int val = __raw_readl(addr);
+	__raw_writel(val&(~mask), addr);
+}
+
+static void cn100_hw_close(struct cn100_private *priv)
+{
+	__raw_clearbit(ETH_INT_MASK, priv->iomem + ETH_INT_ENB_ADDR);
+	__raw_writel(0x00, priv->iomem + ETH_RX_CFG_ADDR);
+
+	__raw_writel(0x8000, priv->iomem + ETH_MAC_CFG0);
+	udelay(800);
+}
+
+static void cn100_hw_open(struct cn100_private *priv)
+{
+	int full = priv->mii.full_duplex;
+
+	__raw_writel(0x20002000, priv->iomem + ETH_CFG_ADDR);
+
+	__raw_writel(0x0100, priv->iomem + ETH_MAC_SUPP);
+	__raw_writel(full ? 0x00B3 : 0x00B2, priv->iomem + ETH_MAC_CFG1);
+	__raw_writel(0x001C, priv->iomem + ETH_MAC_MCFG);
+	__raw_writel(0x0015, priv->iomem + ETH_MAC_IPGT);
+	__raw_writel(0x0C12, priv->iomem + ETH_MAC_IPGR);
+}
+
+static inline void __raw_setbit(unsigned int mask, volatile void __iomem *addr)
+{
+	unsigned int val = __raw_readl(addr);
+	__raw_writel(val|mask, addr);
+}
+
+static void cn100_hw_start(struct cn100_private *priv)
+{
+	__raw_writel((priv->rx_fifo_addr >> 3), priv->iomem + ETH_RX_BASE_ADDR);
+	__raw_writel((priv->rx_fifo_num << 8) | (RX_ITEM_SIZE >> 3) | 0x80000000, priv->iomem + ETH_RX_CFG_ADDR);
+	__raw_writel(0x00, priv->iomem + ETH_RX_RD_ADDR);
+	__raw_writel(0x00, priv->iomem + ETH_RX_WR_ADDR);
+
+	__raw_writel(0x01, priv->iomem + ETH_MAC_CFG0);
+	__raw_writel(ETH_INT_MASK, priv->iomem + ETH_INT_CLS_ADDR);
+	__raw_setbit(ETH_INT_MASK, priv->iomem + ETH_INT_ENB_ADDR);
+}
+
+static void cn100_hw_tx(struct cn100_private *priv)
+{
+	u32 val = priv->tx_desc_addr;
+
+	__raw_writel(val, priv->iomem + ETH_TX_DMA_ADDR);
+}
+
+static int cn100_hw_rx(struct cn100_private *priv, int budget)
+{
+	struct net_device *dev = priv->netdev;
+	struct rx_unit *unit;
+	struct sk_buff *skb;
+	u32 read_ptr, pkt_size;
+	int received = 0;
+
+	while (netif_running(dev) && received < budget) {
+
+		read_ptr = __raw_readl(priv->iomem + ETH_RX_RD_ADDR);
+		if (read_ptr & ETH_FIFO_EMPTY)
+			break;
+
+		unit = priv->rx_fifo_p[read_ptr & ETH_FIFO_MASK];
+		pkt_size = be32_to_cpu(unit->size) - 4; // Exclude CRC
+
+		if (pkt_size <= RX_ITEM_SIZE) {
+			/* Copy packet to skb_buff */
+			skb = dev_alloc_skb(pkt_size);
+			if (likely(skb)) {
+				skb_put(skb, pkt_size);
+				memcpy(skb->data, unit->packet, pkt_size);
+				skb->protocol = eth_type_trans(skb, dev);
+				netif_receive_skb(skb);
+
+				dev->stats.rx_bytes += pkt_size;
+				dev->stats.rx_packets++;
+			} else
+				dev->stats.rx_dropped++;
+		}
+
+		received++;
+		read_ptr++;
+
+		if ((read_ptr & ETH_FIFO_MASK) == priv->rx_fifo_num)
+			read_ptr = (~read_ptr) & ETH_FIFO_TOG;;
+
+		__raw_writel(read_ptr, priv->iomem + ETH_RX_RD_ADDR);
+	}
+
+	return received;
+}
+
+static void cn100_hw_set_dma(struct cn100_private *priv)
+{
+	dma_addr_t dma_addr = priv->dma_addr;
+	void __iomem *dma_area = priv->dma_area;
+	int i;
+
+	priv->tx_desc_addr = dma_addr;
+	priv->tx_data_area = dma_area + sizeof(struct tx_desc);
+
+	priv->tx_desc_p = (struct tx_desc *)dma_area;
+	priv->tx_desc_p->buffer_addr = cpu_to_be32(dma_addr + sizeof(struct tx_desc));
+	priv->tx_desc_p->buffer_len = 0;
+	priv->tx_desc_p->next_link_item = 0;
+	priv->tx_desc_p->next_item_valid_flag = 0;
+
+	dma_addr += TX_ITEM_SIZE + sizeof(struct tx_desc);
+	dma_area += TX_ITEM_SIZE + sizeof(struct tx_desc);
+
+
+	/* init rx buffer struct */
+	priv->rx_fifo_addr = dma_addr;
+	priv->rx_fifo_num = (priv->dma_size - (dma_addr - priv->dma_addr)) / RX_ITEM_SIZE;
+	if (priv->rx_fifo_num > RX_ITEM_MAX)
+		priv->rx_fifo_num = RX_ITEM_MAX;
+	for (i = 0; i < priv->rx_fifo_num; i++) {
+		priv->rx_fifo_p[i] = (struct rx_unit *)dma_area;
+		dma_area += RX_ITEM_SIZE;
+	}
+
+	DEBUG("Ethernet DMA Unit RX %d\n", priv->rx_fifo_num);
+	DEBUG("Tx desc: %x\n", priv->tx_desc_addr);
+	DEBUG("Rx fifo: %x\n", priv->rx_fifo_addr);
+}
+
+static void cn100_hw_tx_desc_add(struct sk_buff *skb, struct net_device *dev)
+{
+	struct cn100_private *priv = (struct cn100_private *)netdev_priv(dev);
+
+	memcpy(priv->tx_data_area, skb->data, skb->len);
+	dma_map_single(NULL, priv->tx_data_area, skb->len, DMA_TO_DEVICE);
+
+	priv->tx_desc_p->buffer_len = cpu_to_be32(skb->len);
+
+	dev->stats.tx_packets ++;
+	dev->stats.tx_bytes += skb->len;
+	dev_kfree_skb(skb);
+}
+
+static irqreturn_t cn100_interrupt(int irq, void *dev_id)
+{
+	struct net_device *dev = dev_id;
+	struct cn100_private *priv = netdev_priv(dev);
+	int status = __raw_readl(priv->iomem + ETH_INT_REG_ADDR);
+
+	// Fix HW FIFO BUG
+	if (status & ETH_INT_HALF) {
+		u32	ptr = __raw_readl(priv->iomem + ETH_RX_WR_ADDR);
+
+		DEBUG("Int Half Full\n");
+		__raw_writel(ETH_INT_HALF, priv->iomem + ETH_INT_CLS_ADDR);
+		__raw_writel(ptr, priv->iomem + ETH_RX_RD_ADDR);
+	}
+
+	if (status & ETH_INT_RX) {
+		DEBUG("Int RX\n");
+		__raw_writel(ETH_INT_RX, priv->iomem + ETH_INT_CLS_ADDR);
+
+		napi_schedule(&priv->napi);
+	}
+
+	if (status & ETH_INT_TX) {
+		DEBUG("Int TX\n");
+		__raw_writel(ETH_INT_TX, priv->iomem + ETH_INT_CLS_ADDR);
+
+		netif_wake_queue(dev);
+	}
+
+	return IRQ_HANDLED;
+}
+
+static void cn100_set_rx_mode(struct net_device *dev)
+{
+	struct cn100_private *priv = netdev_priv(dev);
+	u32 hash[2] = { 0, 0 };
+	u32 mask = 0;
+
+	if (dev->flags & IFF_PROMISC)
+		mask |= 0x04;
+
+	if (dev->flags & IFF_BROADCAST)
+		mask |= 0x01;
+
+	if (dev->flags & IFF_MULTICAST) {
+		mask |= 0x02;
+
+		if (dev->flags & IFF_ALLMULTI) {
+			hash[0] = 0xFFFFFFFF;
+			hash[1] = 0xFFFFFFFF;
+		} else {
+			struct netdev_hw_addr *ha;
+
+			netdev_for_each_mc_addr(ha, dev) {
+				u32 crc = ether_crc(ETH_ALEN, ha->addr);
+				int bit = (crc >> 26) & 0x3F;
+				hash[bit >> 5] |= 1 << (bit & 0x1F);
+			}
+		}
+	}
+
+	DEBUG("Rx mode %x %x %x\n", mask, hash[0], hash[1]);
+
+	__raw_writel(mask, priv->iomem + ETH_MAC_SA_MASK);
+	__raw_writel(hash[0], priv->iomem + ETH_MAC_HASH_TAB0);
+	__raw_writel(hash[1], priv->iomem + ETH_MAC_HASH_TAB1);
+}
+
+static void cn100_timer(unsigned long data)
+{
+	struct net_device *dev = (struct net_device *)data;
+	struct cn100_private *priv = netdev_priv(dev);
+
+	if (mii_check_media(&priv->mii, true, false)) {
+		int full = priv->mii.full_duplex;
+		__raw_writel(full ? 0x00B3 : 0x00B2, priv->iomem + ETH_MAC_CFG1);
+	}
+
+	priv->timer.expires = jiffies + (HZ << 1);
+	add_timer(&priv->timer);
+}
+
+static int cn100_open(struct net_device *dev)
+{
+	struct cn100_private *priv = netdev_priv(dev);
+	int nt = priv->shift;
+	int ret, id;
+
+	DEBUG("--> %s\n", __func__);
+
+	cn100_hw_open(priv);
+	cn100_hw_set_dma(priv);
+
+	if (mii_check_media(&priv->mii, true, true)) {
+		int full = priv->mii.full_duplex;
+		__raw_writel(full ? 0x00B3 : 0x00B2, priv->iomem + ETH_MAC_CFG1);
+	}
+
+	cn100_set_rx_mode(dev);
+
+	/* add intterrupt request */
+	napi_enable(&priv->napi);
+	ret = request_irq(dev->irq, cn100_interrupt, IRQF_SHARED, dev->name, dev);
+	if (ret < 0) {
+		napi_disable(&priv->napi);
+		cn100_hw_close(priv);
+		return -EAGAIN;
+	}
+
+	cn100_hw_start(priv);
+	netif_start_queue(dev);
+
+	for (id = 0; id < 32; id++) {
+		ret = priv->mii.mdio_read(dev, id, MII_BMSR);
+		if (ret != 0xffff && ret != 0x0000) {
+			if (nt) {
+				nt = 0;
+				continue;
+			}
+
+			priv->mii.phy_id = id;
+			printk(KERN_INFO "CSM CN100 %s: MII ID %d\n", dev->name, id);
+			break;
+		}
+	}
+
+	init_timer(&priv->timer);
+	priv->timer.expires = jiffies + (HZ << 1);
+	priv->timer.data = (unsigned long)dev;
+	priv->timer.function = cn100_timer;
+	add_timer(&priv->timer);
+	return 0;
+}
+
+static int cn100_close(struct net_device *dev)
+{
+	struct cn100_private *priv = (struct cn100_private *)netdev_priv(dev);
+
+	DEBUG("--> %s\n", __func__);
+
+	netif_stop_queue(dev);
+	napi_disable(&priv->napi);
+	free_irq(dev->irq, dev);
+
+	del_timer_sync(&priv->timer);
+	cn100_hw_close(priv);
+	return 0;
+}
+
+static netdev_tx_t cn100_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	struct cn100_private *priv = (struct cn100_private *)netdev_priv(dev);
+
+	netif_stop_queue(dev);
+
+	spin_lock(&priv->tx_lock);
+
+	if( cvm_on_before_skb_tx )
+	{
+		cvm_on_before_skb_tx( dev, NULL );
+	}
+
+	cn100_hw_tx_desc_add(skb, dev);
+
+	dev->trans_start = jiffies;
+
+	cn100_hw_tx(priv);
+
+	if( cvm_on_skb_tx_done )
+	{
+		cvm_on_skb_tx_done( dev, NULL );
+	}
+
+	spin_unlock(&priv->tx_lock);
+	return NETDEV_TX_OK;
+}
+
+static int cn100_poll(struct napi_struct *napi, int budget)
+{
+	struct cn100_private *priv = container_of(napi, struct cn100_private, napi);
+	int work_done = 0;
+	u32 ptr;
+
+	spin_lock(&priv->rx_lock);
+
+rx_action:
+
+	work_done += cn100_hw_rx(priv, budget - work_done);
+	ptr = __raw_readl(priv->iomem + ETH_RX_RD_ADDR);
+
+	if (work_done < budget) {
+		if (ptr & ETH_FIFO_EMPTY)
+			__napi_complete(napi);
+		else
+			goto rx_action;
+	}
+
+	if (ptr & ETH_FIFO_EMPTY)
+		__raw_writel(ETH_INT_RX, priv->iomem + ETH_INT_CLS_ADDR);
+
+	spin_unlock(&priv->rx_lock);
+
+	return work_done;
+}
+
+static const struct net_device_ops cn100_netdev_ops = {
+	.ndo_open = cn100_open,
+	.ndo_stop = cn100_close,
+	.ndo_start_xmit = cn100_start_xmit,
+	.ndo_set_rx_mode = cn100_set_rx_mode,
+	.ndo_set_mac_address = cn100_set_mac_address,
+	.ndo_do_ioctl = netdev_ioctl,
+	.ndo_change_mtu = eth_change_mtu,
+};
+
+static int cn100_phy_read(struct net_device *dev, int phy_id, int reg)
+{
+	struct cn100_private *priv = (struct cn100_private *)netdev_priv(dev);
+	__raw_writel(0x00, priv->iomem + ETH_MAC_MCMD);
+
+	__raw_writel((phy_id << 8) | reg, priv->iomem + ETH_MAC_MADR);
+	__raw_writel(0x01, priv->iomem + ETH_MAC_MCMD);
+
+	while (__raw_readl(priv->iomem + ETH_MAC_MIND) & 0x01);
+	return __raw_readl(priv->iomem + ETH_MAC_MRDD);
+}
+
+static void cn100_phy_write(struct net_device *dev, int phy_id, int reg, int value)
+{
+	struct cn100_private *priv = (struct cn100_private *) netdev_priv(dev);
+
+	__raw_writel((phy_id << 8) | reg, priv->iomem + ETH_MAC_MADR);
+	__raw_writel(value, priv->iomem + ETH_MAC_MWTD);
+
+	while (__raw_readl(priv->iomem + ETH_MAC_MIND) & 0x01);
+}
+
+static u64 dma_mask = DMA_BIT_MASK(32);
+
+static int __devinit cn100_probe(struct platform_device *pdev)
+{
+	struct net_device *netdev;
+	struct cn100_private *priv;
+	struct resource *memres, *irqres;
+	struct device *dev;
+
+	DEBUG("--> %s\n", __func__);
+
+	/* Enable clock */
+	clock_xport_enaclock(_clock_enable);
+
+	/* Alloc network device object and init it */
+	netdev = alloc_etherdev(sizeof(struct cn100_private));
+	if (!netdev)
+		return -ENOMEM;
+
+	SET_NETDEV_DEV(netdev, &pdev->dev);
+	platform_set_drvdata(pdev, netdev);
+
+	memres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!memres)
+		return -ENXIO;
+
+	netdev->base_addr = (unsigned long)ioremap(memres->start, resource_size(memres));
+	if (!netdev->base_addr)
+		return -EBUSY;
+
+	irqres = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	if (!irqres)
+		return -ENXIO;
+
+	netdev->irq	= irqres->start;
+
+	ether_setup(netdev);
+
+	/* setup driver-private data */
+	priv = netdev_priv(netdev);
+	priv->netdev = netdev;
+
+	dev = &netdev->dev;
+	if (!dev->dma_mask)
+		dev->dma_mask = &dma_mask;
+	if (!dev->coherent_dma_mask)
+		dev->coherent_dma_mask = DMA_BIT_MASK(32);
+
+	priv->dma_size = SZ_512K;
+	priv->dma_area = dma_alloc_coherent(dev, priv->dma_size, &priv->dma_addr, GFP_KERNEL);
+	if (!priv->dma_area)
+		return -ENOMEM;
+
+	priv->iomem = (void *)netdev->base_addr;
+
+	if (pdev->id > 0) {
+		priv->shift = 16;
+		priv->ctl_offset = ETH1_CTL_BASE - ETH0_CTL_BASE;
+		priv->mac_offset = ETH1_MAC_BASE - ETH0_MAC_BASE;
+	}
+
+	cn100_hw_close(priv);
+
+	spin_lock_init(&priv->lock);
+	spin_lock_init(&priv->tx_lock);
+	spin_lock_init(&priv->rx_lock);
+
+	netdev->ethtool_ops = &netdev_ethtool_ops;
+	netdev->netdev_ops = &cn100_netdev_ops;
+
+	netif_napi_add(netdev, &priv->napi, cn100_poll, 8);
+
+	priv->mii.dev = netdev;
+	priv->mii.mdio_read = cn100_phy_read;
+	priv->mii.mdio_write = cn100_phy_write;
+	priv->mii.full_duplex = 1;
+	priv->mii.phy_id_mask = 0x1F;
+	priv->mii.reg_num_mask = 0x1F;
+
+	cn100_hw_set_addr(pdev->id > 0 ? MacAddr1 : MacAddr, priv);
+	memcpy(netdev->dev_addr, pdev->id > 0 ? MacAddr1 : MacAddr, ETH_ALEN);
+
+	eth_proc_init();
+
+	return register_netdev(netdev);
+}
+
+static int __devexit cn100_remove(struct platform_device *pdev)
+{
+	struct net_device *dev = platform_get_drvdata(pdev);
+	struct cn100_private *priv = netdev_priv(dev);
+
+	remove_proc_entry("eth0", NULL);
+	remove_proc_entry("eth1", NULL);
+
+	platform_set_drvdata(pdev, NULL);
+
+	if (dev) {
+		free_irq(dev->irq, dev);
+		netif_napi_del(&priv->napi);
+
+		unregister_netdev(dev);
+		free_netdev(dev);
+		cn100_hw_close(priv);
+	}
+
+	return 0;
+}
+
+static struct platform_driver cn100_driver = {
+	.driver  = {
+		.name = "cnc-eth",
+		.owner = THIS_MODULE,
+	},
+	.probe   = cn100_probe,
+	.remove  = __devexit_p(cn100_remove),
+};
+
+module_platform_driver(cn100_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Celestial CN100 MAC Driver");
+
+static int __init setup_mac(char *str)
+{
+	char *p = str;
+	int i;
+
+	if (p != NULL && *p != '\0') {
+		printk("CSM ETH Get MAC: %s\n", p);
+		for (i = 0; i < sizeof(MacAddr); i++) {
+			MacAddr[i] = simple_strtoul(p, &p, 16);
+			MacAddr1[i] = MacAddr[i];
+			p++;
+		}
+		MacAddr1[5]++;
+	}
+	return 0;
+}
+__setup("ethaddr=", setup_mac);
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/celestial/peripheral/Kconfig linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/peripheral/Kconfig
--- linux-linaro-3.4-2012.05-1_original/drivers/celestial/peripheral/Kconfig	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/peripheral/Kconfig	2014-10-23 20:22:19.978715000 +0800
@@ -0,0 +1,112 @@
+#
+# Character device configuration
+#
+
+if ARCH_CELESTIAL 
+menu "Celestial Peripheral Devices"
+
+config CELESTIAL_NAND
+	tristate "NAND Flash Controller(based SMC)"
+	depends on MTD_NAND
+	help
+	  Include support drvier for NAND of celestial platform
+
+config CELESTIAL_ETH
+	bool "CN100 MAC Controller"
+	depends on NET
+	help
+	  Include support drvier for ETH of celestial platform
+
+config CELESTIAL_MULT_ETH
+	bool "Support Mult ETH"
+	depends on CELESTIAL_ETH
+
+config CELESTIAL_SPI
+	bool "SPI Host Controller(based DesignWare IP)"
+	depends on SPI_MASTER
+	select SPI_DESIGNWARE
+	select SPI_DW_MMIO
+	help
+	  Include support drvier for SPI Host of celestial platform
+
+config CELESTIAL_UART1
+	bool "Enable UART1"
+
+config CELESTIAL_UART1_CTS_RTS
+	bool "Enable Hardware CTS/RTS"
+	depends on CELESTIAL_UART1
+
+config CELESTIAL_MMC
+	bool "MMC Host Controller(based DesignWare IP)"
+	depends on MMC
+	select MMC_DW
+	select MMC_DW_IDMAC
+	select MMC_DW_PLTFM
+	help
+	  Include support drvier for MMC Host of celestial platform
+
+config CELESTIAL_MULT_MMC
+	bool "Support Mult SD Card"
+	depends on CELESTIAL_MMC
+
+config CELESTIAL_8BIT_MMC
+	bool "Support 8Bit MMC Card"
+	depends on CELESTIAL_MMC && !CELESTIAL_MULT_MMC
+
+config CELESTIAL_HCI
+	bool "USB OHCI/EHCI Controller"
+	depends on USB
+	select USB_OHCI_HCD
+	select USB_OHCI_HCD_PLATFORM
+	select USB_EHCI_HCD
+	select USB_EHCI_HCD_PLATFORM
+	help
+	  Include support drvier for USB Host of celestial platform
+
+config CELESTIAL_OTG
+	bool "USB OTG Controller(based DesignWare IP)"
+	depends on USB
+	select USB_GADGET_DUALSPEED
+	help
+	  Include support drvier for USB OTG of celestial platform
+
+config CELESTIAL_I2C
+	bool "I2C Host Controller"
+	depends on I2C
+	help
+	  Include support drvier for I2C Host of celestial platform
+
+config CELESTIAL_SCI
+	bool "Smart Card"
+	help 
+	  Include support drvier for smartcard of celestial platform
+
+config CELESTIAL_GPIO
+	bool "GPIO driver"
+	help
+	  Include support drvier for GPIO of celestial platform
+
+config CELESTIAL_FPC
+	bool "FPC driver"
+	help
+	  Include support drvier for FPC of celestial platform
+
+config CELESTIAL_FPC_IR_GPIO
+	int "GPIO# for FPC IR receiver"
+	depends on CELESTIAL_FPC
+	default 11
+	help
+	  GPIO number (0~15) for FPC IR Receiver connection
+
+config CELESTIAL_SEC
+	bool "Secure driver"
+	help
+	  Include support drvier for Secure id of celestial platform
+
+config VGA_SWITCHER_SUPPORT
+	bool "vga switcher"
+	help 
+	  Support VGA Switcher Function by using GPIO interrupt
+
+endmenu
+endif
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/celestial/peripheral/Makefile linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/peripheral/Makefile
--- linux-linaro-3.4-2012.05-1_original/drivers/celestial/peripheral/Makefile	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/peripheral/Makefile	2014-10-23 20:22:19.978715000 +0800
@@ -0,0 +1,13 @@
+#
+# Makefile for the linux kernel.
+#
+
+ifdef CONFIG_ARCH_CELESTIAL
+obj-$(CONFIG_CELESTIAL_NAND) += cnc1900_nand.o
+obj-$(CONFIG_CELESTIAL_ETH)  += eth.o
+obj-$(CONFIG_CELESTIAL_I2C)  += cnc1900_i2c.o
+obj-$(CONFIG_CELESTIAL_SCI)  += cnc18xx_sci.o
+obj-$(CONFIG_CELESTIAL_GPIO) += cnc1900_gpio.o
+obj-$(CONFIG_CELESTIAL_FPC)  += cnc1900_fpc.o
+obj-$(CONFIG_CELESTIAL_SEC)  += cnc18xx_sec.o
+endif
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/celestial/peripheral/vga_switcher.c linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/peripheral/vga_switcher.c
--- linux-linaro-3.4-2012.05-1_original/drivers/celestial/peripheral/vga_switcher.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/peripheral/vga_switcher.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,164 @@
+#include <linux/version.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+
+#include <linux/ioport.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/cdev.h>
+#include <linux/spinlock.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <linux/proc_fs.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <mach/hardware.h>
+#include <asm/mach/irq.h>
+#include <linux/miscdevice.h>
+#include <linux/timer.h>
+
+#define TIGA_MAGIC   't'
+
+
+
+#define POLL_TIMEOUT (2*HZ) 
+
+
+static spinlock_t gpio_tiga_lock;
+static int v_sync_is_coming = 0;
+static void tiga_detect_v_sync(unsigned long data);
+struct timer_list tiga_detect_v_sync_timer; // = TIMER_INITIALIZER(tiga_detect_v_sync, jiffies + POLL_TIMEOUT, 0);
+static int detect_v_sync_status = 0; // 0: mask. 1: unmask.
+
+
+
+#define GPIO_READ 0
+#define GPIO_WRITE 1
+
+#define VGA_INT_GPIO_NUM 12
+#define CNL_GPIO_NUM 14
+#define VGA_GPIO_IRQ  gpio_to_irq(VGA_INT_GPIO_NUM)
+
+extern int gpio_hw_write(unsigned char gpio_id, unsigned char data);
+extern int gpio_hw_set_direct(int gpio_id, int dir);
+
+
+static struct file_operations vga_switching_fops = {
+	.owner		= THIS_MODULE,
+};
+
+static struct miscdevice vga_switcher_miscdev = {
+	.name = "vga_switcher",
+	.minor = MISC_DYNAMIC_MINOR,
+	.fops = &vga_switching_fops
+};
+
+static void tiga_detect_v_sync(unsigned long data)
+{
+	static int count = 0;
+	unsigned long flags;
+
+    //	printk("%s:%s in line %d\n",__FILE__,__FUNCTION__,__LINE__);
+
+	spin_lock_irqsave(&gpio_tiga_lock, flags);
+
+	if(detect_v_sync_status == 0){ // mask
+        enable_irq(VGA_GPIO_IRQ);
+        v_sync_is_coming = 0;
+        detect_v_sync_status= 1;
+        count = 0;
+   
+	}
+	else if(detect_v_sync_status == 1){ // unmask
+
+		if(v_sync_is_coming == 0){
+			gpio_hw_write(CNL_GPIO_NUM, 1);
+		}
+	}
+
+	spin_unlock_irqrestore(&gpio_tiga_lock, flags);
+    tiga_detect_v_sync_timer.expires = jiffies + POLL_TIMEOUT;
+    add_timer(&tiga_detect_v_sync_timer);
+
+}
+
+
+irqreturn_t csm_gpio_irq_for_vga_sync(int irq, void *dev_id)
+{	
+	unsigned long flags;
+
+    //	printk("%s:%s in line %d\n",__FILE__,__FUNCTION__,__LINE__);
+
+	spin_lock_irqsave(&gpio_tiga_lock, flags);
+	v_sync_is_coming ++;
+
+    if(v_sync_is_coming >= 3){
+        disable_irq_nosync(VGA_GPIO_IRQ);
+        gpio_hw_write(CNL_GPIO_NUM, 0);
+        v_sync_is_coming= 0;
+        detect_v_sync_status = 0;
+    }
+	spin_unlock_irqrestore(&gpio_tiga_lock, flags);
+	return IRQ_HANDLED;
+}
+
+static int __init 
+vga_switcher_init(void)
+{
+    int ret = 0;
+    int data;
+    
+    
+    if (misc_register(&vga_switcher_miscdev)) {
+        ret = -EBUSY;
+        printk("VGA swithcer device register failed\n");
+        free_irq(VGA_GPIO_IRQ, &data);
+        return ret;
+    }
+	spin_lock_init(&gpio_tiga_lock);
+
+
+    printk("Enable V Sync Timer!\n");
+#if 1
+	detect_v_sync_status = 1;
+    init_timer(&tiga_detect_v_sync_timer);
+    tiga_detect_v_sync_timer.function = tiga_detect_v_sync;
+    tiga_detect_v_sync_timer.expires = jiffies + POLL_TIMEOUT;
+    tiga_detect_v_sync_timer.data = 0;
+	add_timer(&tiga_detect_v_sync_timer);
+#endif
+    gpio_hw_set_direct(CNL_GPIO_NUM, GPIO_WRITE);
+
+    printk("Register VGA Interrupt!\n");
+    set_irq_type(VGA_GPIO_IRQ, IRQ_TYPE_LEVEL_HIGH);
+    if (ret=request_irq(VGA_GPIO_IRQ, csm_gpio_irq_for_vga_sync, IRQF_DISABLED | IRQF_TRIGGER_HIGH, "vga_switcher_interrupt", &data)) {
+        printk("Init GPIO VGA Switcher IRQ request is failed= %d\n", ret);
+        return ret;
+    }
+
+    return 0;
+
+}
+
+
+
+static void __exit
+vga_switcher_exit(void)
+{
+   misc_deregister(&vga_switcher_miscdev);
+   free_irq(VGA_GPIO_IRQ, NULL);
+
+}
+
+module_init(vga_switcher_init);
+module_exit(vga_switcher_exit);
+MODULE_AUTHOR("Cavium Beijing");
+MODULE_DESCRIPTION("VGA Switcher");
+MODULE_LICENSE("GPL");
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/celestial/video/cnc1900_video.c linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/video/cnc1900_video.c
--- linux-linaro-3.4-2012.05-1_original/drivers/celestial/video/cnc1900_video.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/video/cnc1900_video.c	2014-08-28 10:34:39.797376000 +0800
@@ -0,0 +1,1234 @@
+/****************************************************************************
+  * [RELEASE HISTORY]
+  * VERSION  DATE       AUTHOR                  DESCRIPTION
+  * 0.1      13-04-16       Jia Ma           		Original
+  ****************************************************************************
+*/
+
+#include <linux/device.h>
+#include <linux/types.h>
+#include <linux/fs.h>
+#include <linux/delay.h>
+#include <linux/miscdevice.h>
+#include <linux/proc_fs.h>
+#include <linux/delay.h>
+#include <linux/firmware.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/poll.h>
+#include <linux/sched.h>
+#include <linux/module.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+
+#include <mach/mem_define.h>
+#include <mach/cnc1900_power_clk.h>
+#include <mach/cnc1900_df.h>
+#include <mach/cnc1900_vpp_reg_def.h>
+//#include "../xport/xport_drv1800.h"
+#include "video_reg_def.h"
+#include "cnc1900_video.h"
+#include "video_handshake_def.h"
+#include "../xport/xport_drv1900.h"
+
+#ifdef CONFIG_SW_SUPPORT
+#include <mach/smc.h>
+#endif
+
+#ifdef CONFIG_CELESTIAL_VIDEO_DEBUG
+#define DEBUG_PRINT  printk
+#else
+#define DEBUG_PRINT(fmt,args...)
+#endif
+
+//#define IRQ_DEBUG
+
+union _irq_flags {
+    struct {
+        unsigned int picture_ready_enable:1;
+        unsigned int picture_ready:1;
+
+        unsigned int av_sync_enable:1;
+        unsigned int av_sync:1;
+
+        unsigned int enc_frame_done_enable:1;
+        unsigned int enc_frame_done:1;
+
+        unsigned int yuv_frame_done_enable:1;
+        unsigned int yuv_frame_done:1;
+
+        unsigned int yuv_buf_info_done_enable:1;
+        unsigned int yuv_buf_info_done:1;
+
+        unsigned int dec_seq_change_enable:1;
+        unsigned int dec_seq_change:1;
+
+        unsigned int reserved:20;
+    }bits;
+    unsigned int val;
+};
+
+typedef enum _UART_ID_
+{
+	_uart_0 	=0,
+	_uart_1		=1,
+	_uart_2		=2,
+	_uart_audio	=3,
+	_uart_video	=4,
+}UART_ID;
+
+typedef enum _I2C_ID_
+{
+	_i2c_0      =0,
+	_i2c_1      =1,
+}I2C_ID;
+
+typedef enum
+{
+    CHANGE_TG_REQUEST=0,
+    CHANGE_TG_GRANT,
+    CHANGE_TG_FINISH
+}ChangeTgT;
+
+typedef enum{
+    CODA_CLOCK_INDEX_0,//default 270/340
+    CODA_CLOCK_INDEX_1,//290/290
+    CODA_CLOCK_INDEX_2 //300/300
+}CODA_CLOCK_t;
+
+typedef struct CNC1900_video_DEV_t {
+	int instance_num; //instance numbers in the process 
+} cnc1900_video_dev;
+
+#ifndef CONFIG_SW_SUPPORT
+#define video_int_write(v,a)    	do { *(vidint_base + (a)) = (v) ;udelay(10);}while(0)
+#define video_int_read(a)       	*(vidint_base + (a))
+#else
+void video_int_write(unsigned int val, unsigned int a){
+	a = (a)&0xfffff; 
+	sw_smc(SMC_CMD_VIDEO_WIRTE_IRQ_REG, a, val, 0x0);
+}
+
+unsigned int video_int_read(unsigned int a){
+	a = (a)&0xfffff;
+	return sw_smc(SMC_CMD_VIDEO_READ_IRQ_REG, a, 0x0, 0x0);
+}
+#endif
+
+#ifndef CONFIG_SW_SUPPORT
+#define video_write(v,a)    	do { *(csm_video_base + (a)) = (v) ;udelay(10);}while(0)
+#define video_read(a)       	*(csm_video_base + (a))
+#else
+void video_write(unsigned int val, unsigned int a){
+	a = (a)&0xfffff; 
+	sw_smc(SMC_CMD_VIDEO_WIRTE_REG, a, val, 0x0);
+}
+
+unsigned int video_read(unsigned int a){
+	a = (a)&0xfffff;
+	return sw_smc(SMC_CMD_VIDEO_READ_REG, a, 0x0, 0x0);
+}
+#endif
+
+#define REG_SET_BIT(reg, mask) {unsigned int t = __video_read(reg); t |= (mask); __video_write(reg, t);}
+#define REG_CLEAR_BIT(reg, mask) {unsigned int t = __video_read(reg); t &= ~(mask); __video_write(reg, t);}
+
+#define SET_UPDATE_FLAG(reg, updateFlag, cmdType) __video_write(reg, (updateFlag)|(cmdType))
+#define CLEAR_UPDATE_FLAG(reg) __video_write(reg, 0)
+
+
+extern int pinmux_enable_i2c(I2C_ID I2C);
+extern int pinmux_enable_vib(void);
+extern int pinmux_enable_uart(UART_ID UART);
+
+extern void clock_coda_reset(CLOCK_RESET ResetOrSet);
+
+extern void DF_Write(unsigned int addr, unsigned int data);
+extern unsigned int DF_Read(unsigned int addr);
+
+static int __csm_video_release_firmware(void);
+#ifndef CONFIG_SW_SUPPORT
+static void __kernel_load_firmware(int load_coda_flag);
+#endif
+static int __video_init(int load_coda_flag);
+
+DEFINE_SPINLOCK(csm_video_lock);
+DEFINE_SPINLOCK(notify_lock);
+DECLARE_WAIT_QUEUE_HEAD(notify_queue);
+
+DdrFwAttrT* host2videofw_if = NULL;
+
+
+extern int __Is_hd2sd;
+
+static int fw_initialized;
+static int process_num = 0;
+//static int fix_bug_av_sync = 0;
+static union _irq_flags  irq_flags;
+
+static volatile unsigned int *vidmcu_base = NULL;
+#ifndef CONFIG_SW_SUPPORT
+static volatile unsigned int *csm_video_base = NULL;
+static volatile unsigned int *vidint_base = NULL;
+#endif
+
+static struct platform_device *video_pdev;
+#ifndef CONFIG_SW_SUPPORT
+static const struct firmware* video_data_fw=(struct firmware*)NULL;
+static const struct firmware* video_text_fw=(struct firmware*)NULL;
+static const struct firmware* video_coda_fw=(struct firmware*)NULL;
+#endif
+static int csm_video_open(struct inode *inode, struct file *file);
+static int csm_video_release(struct inode *inode, struct file *file);
+static long csm_video_ioctl(struct file *file,unsigned int cmd, unsigned long arg);
+static unsigned int csm_video_poll(struct file *filp, poll_table * wait);
+irqreturn_t csm_vid_irq(int irq, void *dev_id);
+static int csm_video_proc_write(struct file *file, const char *buffer, unsigned long count, void *data);
+
+static struct class *csm_video_class;
+static struct proc_dir_entry *csm_video_proc_entry = NULL;
+static struct file_operations csm_video_fops = {
+	.owner	= THIS_MODULE,
+	.open	=  csm_video_open,
+	.release	= csm_video_release,
+	.unlocked_ioctl	= csm_video_ioctl,
+	.poll		= csm_video_poll,
+};
+
+#ifndef CONFIG_SW_SUPPORT
+unsigned int  __video_write(unsigned int addr, unsigned int val)
+{
+	video_write(val,((addr-CNC_VIDEO_REG_BASE)>>2));
+	return video_read((addr-CNC_VIDEO_REG_BASE)>>2);
+}
+
+unsigned int __video_read(unsigned int addr)
+{
+	return video_read((addr-CNC_VIDEO_REG_BASE)>>2);
+}
+
+#else
+void __video_write(unsigned int a, unsigned int val){
+	a = (a)&0xfffff; 
+	sw_smc(SMC_CMD_VIDEO_WIRTE_REG, a, val, 0x0);
+}
+
+unsigned int __video_read(unsigned int a){
+	a = (a)&0xfffff;
+	return sw_smc(SMC_CMD_VIDEO_READ_REG, a, 0x0, 0x0);
+}
+#endif
+void __HostSendCmd(unsigned int Cmd, UpdateCmdType CmdType, unsigned int Param1, unsigned int Param2)
+{
+	int wait_times = 10;
+
+	while (__video_read(MAILBOX_CMD_UPDATE_FLAG) & BIT_UPDATE_FLAG){
+		wait_times--;
+		mdelay(10);
+		if (wait_times <= 0){
+            break;
+		}
+	}
+
+	switch(CmdType){
+		case UPDATE_PLAY_CMD:
+		{
+			__video_write(MAILBOX_CMD_UPDATE_MSG, Cmd);
+			break;
+		}
+		case UPDATE_REC_CMD:
+		{
+			__video_write(MAILBOX_CMD_UPDATE_MSG, Cmd);
+			break;
+		}
+		case UPDATE_DEBUG_CMD:
+		{
+			__video_write(MAILBOX_CMD_UPDATE_MSG, Cmd);
+			__video_write(MAILBOX_CMD_DEBUG_PARAM1, Param1);
+			__video_write(MAILBOX_CMD_DEBUG_PARAM2, Param2);
+			break;
+		}
+		case UPDATE_TG_CHG_CMD:
+		{
+			__video_write(MAILBOX_CMD_UPDATE_MSG, Cmd);
+			break;
+		}
+		case UPDATE_CODA_RESET_CMD:
+		{
+			__video_write(MAILBOX_CMD_UPDATE_MSG, Cmd);
+			break;
+		}
+		default:
+			return;
+	}
+
+	SET_UPDATE_FLAG(MAILBOX_CMD_UPDATE_FLAG, BIT_UPDATE_FLAG, CmdType);
+	wait_times = 10;
+	while (__video_read(MAILBOX_CMD_UPDATE_FLAG) & BIT_UPDATE_FLAG){
+		wait_times--;
+		mdelay(10);
+		if (wait_times <= 0){
+            break;
+		}
+	}
+
+	return;
+}
+int __video_tve_2_tg(int layer)
+{
+	int buf_num = 0;
+
+	if(0 == layer)
+		buf_num = BUF_TG1;
+	if(1 == layer)
+		buf_num = BUF_TG2;
+
+	return buf_num;
+}
+
+int __change_tg_request(unsigned int TgId)
+{
+    unsigned int Cmd = ((CHANGE_TG_REQUEST&0xf)<<4)|(TgId&0xf);
+
+    __HostSendCmd(Cmd, UPDATE_TG_CHG_CMD, 0, 0);
+
+    return 0;
+}
+
+int __change_tg_release(unsigned int TgId)
+{
+    unsigned int Cmd = ((CHANGE_TG_FINISH&0xf)<<4)|(TgId&0xf);
+
+    __HostSendCmd(Cmd, UPDATE_TG_CHG_CMD, 0, 0);
+    return 0;
+}
+
+void __video_set_layer_position(int layer, unsigned int w, unsigned int h, unsigned int is_interlace, unsigned int frame_rate)
+{
+     host2videofw_if->VppBufAttr[layer].PicFormat.PicWidth = w;
+     host2videofw_if->VppBufAttr[layer].PicFormat.PicHeight = h;
+     host2videofw_if->VppBufAttr[layer].PicFormat.IsInterlace = is_interlace;
+     host2videofw_if->VppBufAttr[layer].PicFormat.FrameRate = frame_rate;
+}
+
+void __video_set_hd2sd(unsigned int tg1_width, unsigned int tg1_height, unsigned int tg2_width, unsigned int tg2_height)
+{
+     host2videofw_if->VppWinAttr[WIN_D2F_CAP].En= 1;
+     host2videofw_if->VppWinAttr[WIN_D2F_CAP].HwSel= LAYER_HWSEL_CAP;
+     host2videofw_if->VppWinAttr[WIN_D2F_CAP].F2fOrder= 0;
+     host2videofw_if->VppWinAttr[WIN_D2F_CAP].SrcBufNo= BUF_TG1;
+     host2videofw_if->VppWinAttr[WIN_D2F_CAP].DesBufNo= BUF_CAP;
+     host2videofw_if->VppWinAttr[WIN_D2F_CAP].Src.StartX= 0;
+     host2videofw_if->VppWinAttr[WIN_D2F_CAP].Src.EndX= tg1_width;
+     host2videofw_if->VppWinAttr[WIN_D2F_CAP].Src.StartY= 0;
+     host2videofw_if->VppWinAttr[WIN_D2F_CAP].Src.EndY= tg1_height;
+     host2videofw_if->VppWinAttr[WIN_D2F_CAP].Des.StartX= 0;
+     host2videofw_if->VppWinAttr[WIN_D2F_CAP].Des.EndX= tg2_width;
+     host2videofw_if->VppWinAttr[WIN_D2F_CAP].Des.StartY= 0;
+     host2videofw_if->VppWinAttr[WIN_D2F_CAP].Des.EndY= tg2_height;
+
+     host2videofw_if->VppBufAttr[BUF_CAP].PicFormat.Format3D = FORMAT_2D;
+     host2videofw_if->VppBufAttr[BUF_CAP].PicFormat.FrameRate = 30;
+     host2videofw_if->VppBufAttr[BUF_CAP].PicFormat.HorSample = 1;
+     host2videofw_if->VppBufAttr[BUF_CAP].PicFormat.VerSample = 0;
+     host2videofw_if->VppBufAttr[BUF_CAP].PicFormat.IsInterlace = host2videofw_if->VppBufAttr[BUF_TG1].PicFormat.IsInterlace;
+     host2videofw_if->VppBufAttr[BUF_CAP].PicFormat.PicWidth = tg2_width;
+     host2videofw_if->VppBufAttr[BUF_CAP].PicFormat.PicHeight = tg2_height;
+     host2videofw_if->VppBufAttr[BUF_CAP].PicFormat.TopFieldFirst = 1;
+     host2videofw_if->VppBufAttr[BUF_CAP].PicFormat.VactSpace1 = 0;
+     host2videofw_if->VppBufAttr[BUF_CAP].PicFormat.VactSpace2 = 0;
+
+     host2videofw_if->VppWinAttr[WIN_F2D_RD2].En= 1;
+     host2videofw_if->VppWinAttr[WIN_F2D_RD2].HwSel= LAYER_HWSEL_RD2;
+     host2videofw_if->VppWinAttr[WIN_F2D_RD2].F2fOrder= 0;
+     host2videofw_if->VppWinAttr[WIN_F2D_RD2].SrcBufNo= BUF_CAP;
+     host2videofw_if->VppWinAttr[WIN_F2D_RD2].DesBufNo= BUF_TG2;
+     host2videofw_if->VppWinAttr[WIN_F2D_RD2].Src.StartX= 0;
+     host2videofw_if->VppWinAttr[WIN_F2D_RD2].Src.EndX= tg2_width;
+     host2videofw_if->VppWinAttr[WIN_F2D_RD2].Src.StartY= 0;
+     host2videofw_if->VppWinAttr[WIN_F2D_RD2].Src.EndY= tg2_height;
+     host2videofw_if->VppWinAttr[WIN_F2D_RD2].Des.StartX= 0;
+     host2videofw_if->VppWinAttr[WIN_F2D_RD2].Des.EndX= tg2_width;
+     host2videofw_if->VppWinAttr[WIN_F2D_RD2].Des.StartY= 0;
+     host2videofw_if->VppWinAttr[WIN_F2D_RD2].Des.EndY= tg2_height;
+
+     host2videofw_if->VppBufAttr[BUF_TG2].PicFormat.Format3D = FORMAT_2D;
+     host2videofw_if->VppBufAttr[BUF_TG2].PicFormat.FrameRate = 3000;
+     host2videofw_if->VppBufAttr[BUF_TG2].PicFormat.HorSample = 0;
+     host2videofw_if->VppBufAttr[BUF_TG2].PicFormat.VerSample = 0;
+     host2videofw_if->VppBufAttr[BUF_TG2].PicFormat.IsInterlace = 1;
+     host2videofw_if->VppBufAttr[BUF_TG2].PicFormat.PicWidth = tg2_width;
+     host2videofw_if->VppBufAttr[BUF_TG2].PicFormat.PicHeight = tg2_height;
+     host2videofw_if->VppBufAttr[BUF_TG2].PicFormat.TopFieldFirst = 1;
+     host2videofw_if->VppBufAttr[BUF_TG2].PicFormat.VactSpace1 = 0;
+     host2videofw_if->VppBufAttr[BUF_TG2].PicFormat.VactSpace2 = 0;
+}
+
+void __video_send_hd2sd_cmd(int cmd)
+{
+	unsigned int  Cmd = 1;
+    
+    Cmd |= CH_CAP0 << 24;
+    __HostSendCmd(Cmd, UPDATE_PLAY_CMD, 0, 0);
+}
+
+
+static int csm_video_proc_write(struct file *file, const char *buffer, unsigned long count, void *data)
+{
+	const char *cmd_line = buffer;;
+
+	if (strncmp("rl", cmd_line, 2) == 0) {
+		int addr;
+		addr = simple_strtol(&buffer[3], NULL, 16);
+		printk(" addr[0x%08x] = 0x%08x \n", addr, video_read(addr));
+	}else if((strncmp("dumpreg",cmd_line,7) == 0)){
+	    printk("MAILBOX_FW_ATTR_UPDATE_FLAG   addr:0x%x = 0x%x\n", (MAILBOX_FW_ATTR_UPDATE_FLAG  ) , __video_read(MAILBOX_FW_ATTR_UPDATE_FLAG  ));
+	    printk("MAILBOX_FIRMWARE_CONFIG_BADDR addr:0x%x = 0x%x\n", (MAILBOX_FIRMWARE_CONFIG_BADDR) , __video_read(MAILBOX_FIRMWARE_CONFIG_BADDR));
+	    printk("MAILBOX_DEC_CPB_WPRP_BADDR    addr:0x%x = 0x%x\n", (MAILBOX_DEC_CPB_WPRP_BADDR   ) , __video_read(MAILBOX_DEC_CPB_WPRP_BADDR   ));
+	    printk("MAILBOX_ENC_CPB_WPRP_BADDR    addr:0x%x = 0x%x\n", (MAILBOX_ENC_CPB_WPRP_BADDR   ) , __video_read(MAILBOX_ENC_CPB_WPRP_BADDR   ));
+	    printk("MAILBOX_CODAFW_CONFIG_BADDR   addr:0x%x = 0x%x\n", (MAILBOX_CODAFW_CONFIG_BADDR  ) , __video_read(MAILBOX_CODAFW_CONFIG_BADDR  ));
+	    printk("MAILBOX_CMD_UPDATE_FLAG       addr:0x%x = 0x%x\n", (MAILBOX_CMD_UPDATE_FLAG      ) , __video_read(MAILBOX_CMD_UPDATE_FLAG      ));
+	    printk("MAILBOX_CMD_UPDATE_MSG        addr:0x%x = 0x%x\n", (MAILBOX_CMD_UPDATE_MSG       ) , __video_read(MAILBOX_CMD_UPDATE_MSG       ));
+	    printk("MAILBOX_INT_MSG_UPDATE_FLAG   addr:0x%x = 0x%x\n", (MAILBOX_INT_MSG_UPDATE_FLAG  ) , __video_read(MAILBOX_INT_MSG_UPDATE_FLAG  ));
+	    printk("MAILBOX_DEBUG_CMD_UPDATE_FLAG addr:0x%x = 0x%x\n", (MAILBOX_DEBUG_CMD_UPDATE_FLAG) , __video_read(MAILBOX_DEBUG_CMD_UPDATE_FLAG));
+	    printk("MAILBOX_DEBUG_CMD_UPDATE_MSG  addr:0x%x = 0x%x\n", (MAILBOX_DEBUG_CMD_UPDATE_MSG ) , __video_read(MAILBOX_DEBUG_CMD_UPDATE_MSG ));
+	    printk("MAILBOX_CMD_DEBUG_PARAM1      addr:0x%x = 0x%x\n", (MAILBOX_CMD_DEBUG_PARAM1     ) , __video_read(MAILBOX_CMD_DEBUG_PARAM1     ));
+	    printk("MAILBOX_CMD_DEBUG_PARAM2      addr:0x%x = 0x%x\n", (MAILBOX_CMD_DEBUG_PARAM2     ) , __video_read(MAILBOX_CMD_DEBUG_PARAM2     ));
+	    printk("MAILBOX_FIRMWARE_VERSION      addr:0x%x = 0x%x\n", (MAILBOX_FIRMWARE_VERSION    ) , __video_read(MAILBOX_FIRMWARE_VERSION     ));
+	    printk("MAILBOX_CODA_VERSION          addr:0x%x = 0x%x\n", (MAILBOX_CODA_VERSION        ) , __video_read(MAILBOX_CODA_VERSION         ));
+	    printk("MAILBOX_MIPS_DEBUG_FEEDBACK1  addr:0x%x = 0x%x\n", (MAILBOX_MIPS_DEBUG_FEEDBACK1) , __video_read(MAILBOX_MIPS_DEBUG_FEEDBACK1 ));
+	    printk("MAILBOX_MIPS_DEBUG_FEEDBACK2  addr:0x%x = 0x%x\n", (MAILBOX_MIPS_DEBUG_FEEDBACK2) , __video_read(MAILBOX_MIPS_DEBUG_FEEDBACK2 ));
+	    printk("MAILBOX_FW_LOG_BADDR          addr:0x%x = 0x%x\n", (MAILBOX_FW_LOG_BADDR        ) , __video_read(MAILBOX_FW_LOG_BADDR         ));
+	    printk("MAILBOX_FW_LOG_UPDATE_FLAG    addr:0x%x = 0x%x\n", (MAILBOX_FW_LOG_UPDATE_FLAG  ) , __video_read(MAILBOX_FW_LOG_UPDATE_FLAG   ));
+	    printk("MAILBOX_INT_TYPE              addr:0x%x = 0x%x\n", (MAILBOX_INT_TYPE            ) , __video_read(MAILBOX_INT_TYPE             ));
+	    printk("MAILBOX_VIDEO_PTS             addr:0x%x = 0x%x\n", (MAILBOX_VIDEO_PTS           ) , __video_read(MAILBOX_VIDEO_PTS            ));
+	    printk("MAILBOX_STATIC_BUF_ADDR       addr:0x%x = 0x%x\n", (MAILBOX_STATIC_BUF_ADDR   	) , __video_read(MAILBOX_STATIC_BUF_ADDR   	));
+	    printk("MAILBOX_PIC_MEM_SIZE          addr:0x%x = 0x%x\n", (MAILBOX_PIC_MEM_SIZE   		) , __video_read(MAILBOX_PIC_MEM_SIZE   		));
+	    printk("MAILBOX_MIPS_TIME             addr:0x%x = 0x%x\n", (MAILBOX_MIPS_TIME           ) , __video_read(MAILBOX_MIPS_TIME            ));
+	    printk("MAILBOX_MIPS_HEART_BEAT       addr:0x%x = 0x%x\n", (MAILBOX_MIPS_HEART_BEAT     ) , __video_read(MAILBOX_MIPS_HEART_BEAT      ));
+
+	    printk("INT_RISCCPU_EN                addr:0x%x = 0x%x\n", (INT_RISCCPU_EN          ), video_int_read(0x00));
+#ifndef CONFIG_SW_SUPPORT
+	    printk("INT_RISCCPU_MASK              addr:0x%x = 0x%x\n", (INT_RISCCPU_MASK        ), video_int_read(0x08>>2));
+	    printk("INT_RISCCPU_FORCE             addr:0x%x = 0x%x\n", (INT_RISCCPU_FORCE       ), video_int_read(0x10>>2));
+	    printk("INT_RISCCPU_FINALSTATUS       addr:0x%x = 0x%x\n", (INT_RISCCPU_FINALSTATUS ), video_int_read(0x30>>2));
+	    printk("INT_COPSW_EN                  addr:0x%x = 0x%x\n", (INT_COPSW_EN            ), video_int_read(0xc0>>2));
+	    printk("INT_COPSW_MASK                addr:0x%x = 0x%x\n", (INT_COPSW_MASK          ), video_int_read(0xc4>>2));
+	    printk("INT_COPSW_FORCE               addr:0x%x = 0x%x\n", (INT_COPSW_FORCE         ), video_int_read(0xc8>>2));
+	    printk("INT_COPSW_FINALSTATUS         addr:0x%x = 0x%x\n", (INT_COPSW_FINALSTATUS   ), video_int_read(0xd4>>2));
+#else
+	    printk("INT_RISCCPU_MASK              addr:0x%x = 0x%x\n", (INT_RISCCPU_MASK        ), video_int_read(0x08));
+	    printk("INT_RISCCPU_FORCE             addr:0x%x = 0x%x\n", (INT_RISCCPU_FORCE       ), video_int_read(0x10));
+	    printk("INT_RISCCPU_FINALSTATUS       addr:0x%x = 0x%x\n", (INT_RISCCPU_FINALSTATUS ), video_int_read(0x30));
+	    printk("INT_COPSW_EN                  addr:0x%x = 0x%x\n", (INT_COPSW_EN            ), video_int_read(0xc0));
+	    printk("INT_COPSW_MASK                addr:0x%x = 0x%x\n", (INT_COPSW_MASK          ), video_int_read(0xc4));
+	    printk("INT_COPSW_FORCE               addr:0x%x = 0x%x\n", (INT_COPSW_FORCE         ), video_int_read(0xc8));
+	    printk("INT_COPSW_FINALSTATUS         addr:0x%x = 0x%x\n", (INT_COPSW_FINALSTATUS   ), video_int_read(0xd4));
+#endif
+	}
+
+	return count;
+}
+
+#ifndef CONFIG_SW_SUPPORT
+static int __video_firmware_to_mips(int load_coda_flag)
+{
+	size_t firmware_size_txt = 0, firmware_size_dat = 0;
+	unsigned int *p_src = NULL,*p_src_dat = NULL;
+	volatile unsigned int *p_buf = NULL,*p_buf_dat = NULL;
+	volatile unsigned int *start_addr = NULL;
+	unsigned int i = 0;
+
+	if (video_text_fw!=(struct firmware*)NULL){
+		firmware_size_txt= video_text_fw->size>>2;
+		p_src= (unsigned int *)video_text_fw->data;
+		firmware_size_dat = (video_data_fw->size)>>2;
+		p_src_dat= (unsigned int *)video_data_fw->data;
+	}
+
+	if(p_src!=NULL){
+		start_addr = (volatile unsigned int *) vidmcu_base;
+		memset((char *)start_addr, 0,VIDEO_MCU_SIZE);
+		for (i = INST_OUT_MEM_SIZE / sizeof(unsigned int); i < firmware_size_txt; i++)
+			*start_addr++ = p_src[i];
+		for (i = 0; i < 4; i++)
+			*start_addr++ = 0;
+
+		p_buf = csm_video_base + MIPS_ISRAM_OFFSET;
+		memset((char *)p_buf, 0,MIPS_ISRAM_MEM_SIZE);
+		if (firmware_size_txt > (MIPS_ISRAM_MEM_SIZE) / sizeof(unsigned int))
+			firmware_size_txt = (MIPS_ISRAM_MEM_SIZE) / sizeof(unsigned int);
+
+		for (i = 0; i < firmware_size_txt; i++)
+			p_buf[i] = p_src[i];
+
+		p_buf_dat= csm_video_base + MIPS_DSRAM_OFFSET;
+		memset((char *)p_buf_dat, 0,MIPS_DSRAM_MEM_SIZE);
+		for (i = 0; i < firmware_size_dat; i++)
+		{
+			p_buf_dat[i] = p_src_dat[i];
+		}
+
+		for (; i < MIPS_DSRAM_MEM_SIZE / sizeof(unsigned int); i++)
+			p_buf_dat[i] = 0x0;
+	}
+
+if(0){
+	int i = 0;
+	printk("VIDEO_STUFF_REGION = 0x%x\n",VIDEO_STUFF_REGION);
+	for(i = 0; i<10; i++){
+		printk("0x%08x ",p_src[i]);
+		printk("0x%08x ",*(csm_video_base + MIPS_ISRAM_OFFSET+i));
+	}
+	printk("\n");
+
+	for(i = 0; i < 10;i++){
+		printk("0x%08x ",p_src[i+1024/4]);
+		printk("0x%08x ",*(vidmcu_base+i));
+	}
+	printk("\n");
+}
+	if (load_coda_flag){
+	    	if(video_coda_fw!=(struct firmware*)NULL){
+	    		firmware_size_txt = video_coda_fw->size;
+	    		p_src = (unsigned int *)video_coda_fw->data;
+	    	}
+
+	    	if(p_src!=NULL){
+	    		volatile char *start_addr = NULL;
+	    		volatile char *temp = NULL;
+
+	    		start_addr = (volatile char *)(vidmcu_base + (VIDEO_CODA_OFFSET>>2));
+	    		temp = (volatile char *)p_src;
+
+	    		for (i = 0; i < firmware_size_txt; i++)
+	    		{
+	    			start_addr[i] = temp[i];
+	    		}
+	    	}
+if(0){
+		for(i = 0; i < 10;i++){
+			printk("0x%08x ",p_src[i]);
+			printk("0x%08x ",*(vidmcu_base+(VIDEO_CODA_OFFSET>>2)+i));
+		}
+		printk("\n, firmware_size_txt = 0x%x\n",firmware_size_txt);
+		for(i = (firmware_size_txt>>2); i > ((firmware_size_txt>>2)-10);i--){
+			printk("0x%08x ",p_src[i-1]);
+			printk("0x%08x ",*(vidmcu_base+(VIDEO_CODA_OFFSET>>2)+ i -1));
+		}
+		printk("\n");
+}
+	}
+
+	return 0;
+}
+#endif
+static int __video_init(int load_coda_flag)
+{
+	/* reset mcu */
+	video_write(0xffffffff, MIPS_RESET_OFFSET);
+	udelay(5);
+
+	clock_coda_reset(_do_reset);
+	mdelay(10);
+	clock_coda_reset(_do_set);
+#ifndef CONFIG_SW_SUPPORT
+	__video_firmware_to_mips(load_coda_flag);
+#endif
+	return 0;
+}
+
+#ifndef CONFIG_SW_SUPPORT
+static void __kernel_load_firmware(int load_coda_flag)
+{
+	int ret;
+	if (video_text_fw == NULL) {
+        ret = request_firmware(&video_text_fw, "video_fw_text.bin", &(video_pdev->dev));
+        if (unlikely(ret != 0 || video_text_fw== NULL)) {
+            printk(KERN_ERR "Failed to load video firmware code section 1\n");
+            return;
+        }
+        else{
+            if (unlikely(video_text_fw->size > VIDEO_MCU_SIZE)){
+				release_firmware(video_text_fw);
+				video_text_fw=NULL;
+				printk(KERN_ERR "Failed to load video firmware code section 2\n");
+				return;
+            }
+            if(video_text_fw!=NULL && video_data_fw == NULL){
+                ret = request_firmware(&video_data_fw, "video_fw_data.bin", &(video_pdev->dev));
+                if (unlikely(ret != 0 || video_data_fw== NULL)) {
+                    release_firmware(video_text_fw);
+                    video_text_fw=NULL;
+                    printk(KERN_ERR "Failed to load video firmware data section 1\n");
+                    return;
+                }
+                else{
+                    if (unlikely(video_data_fw->size > MIPS_DSRAM_MEM_SIZE )){
+			    		release_firmware(video_data_fw);
+						video_data_fw=NULL;
+						release_firmware(video_text_fw);
+						video_text_fw=NULL;
+						printk(KERN_ERR "Failed to load video firmware data section 2\n");
+						return;
+                    }
+                }
+            }
+        }
+	}
+
+	if (load_coda_flag){
+	    	if (video_coda_fw == NULL) {
+	            ret = request_firmware(&video_coda_fw, "video_fw_coda.bin", &(video_pdev->dev));
+	            if (unlikely(ret != 0 || video_coda_fw== NULL)) {
+	                printk(KERN_ERR "Failed to load video coda firmware 1\n");
+	                return;
+	            }
+	            else{
+	                if (unlikely(video_coda_fw->size > VIDEO_CODA_SIZE)){
+	    				release_firmware(video_coda_fw);
+	    				video_coda_fw=NULL;
+	    				printk(KERN_ERR "Failed to load video coda firmware 2\n");
+	    				return;
+	                }
+	            }
+	    	}
+	}
+
+	return;
+}
+#endif
+static int __csm_video_release_firmware(void)
+{
+
+#if 0
+	/* stop video */
+	for (ch = 0; ch < MAX_CHANNEL_NUM; ch++){
+		printk("channel %d \n", ch);
+		if (host2videofw_if->channel_num & (1 << ch)){ // current channel enable, send stop cmd
+			i = 0;
+			while (video_read(HOST_CMD_REG) >> 31){ // wait last cmd ack
+				i++;
+				udelay(100);
+
+				if(1000 == i)
+					break;
+			}
+
+			i = 0;
+			cmd = (ch << 24) | 2; // 2: send stop cmd
+			video_write(cmd|0x80000000, HOST_CMD_REG);
+
+			do{
+				if((video_read(HOST_CMD_REG) >> 31) == 0x0)
+					break;
+
+				udelay(100);
+				i++;
+
+				//printk("CNC VIDEO release failed %d!\n", i);
+
+				if (1000 == i)
+					break;
+			}while(1);
+
+			printk("CNC VIDEO %d release success!\n", ch);
+		}
+	}
+
+	// close interrupt
+	reg = *(vidint_base + VID_RISC_ENA);
+	//    printk("HOST_INT_ENABLE = 0x%08x\n", reg);
+	reg |= (1 << 31);
+	*(vidint_base + VID_RISC_ENA) = reg;
+	//    printk("HOST_INT_ENABLE = 0x%08x\n", reg);
+	*(vidint_base + VID_RISC_INT) = (1 << 31);
+
+	i = 0;
+	do{
+		reg = *(vidint_base + VID_RISC_INT);
+		//        printk("HOST_INT_FORCE = 0x%08x\n", reg);
+		if(video_read(0x3d) == 0x1004e)
+			break;
+
+		i++;
+		if(1000 == i)
+			break;
+
+		udelay(100);
+
+	}while (1);
+#endif
+
+	/* reset mcu */
+	video_write(0xffffffff, MIPS_RESET_OFFSET);
+
+#ifndef CONFIG_SW_SUPPORT
+	if (video_text_fw != NULL ){
+		release_firmware(video_text_fw);
+		video_text_fw = NULL;
+	}
+	if (video_data_fw != NULL){
+		release_firmware(video_data_fw);
+		video_data_fw = NULL;
+	}
+	if (video_coda_fw != NULL) {
+		release_firmware(video_coda_fw);
+		video_coda_fw = NULL;
+	}
+#endif
+	// coda reset
+//	printk("start code clock reset!\n");
+//	clock_coda_reset(_do_reset);
+//	printk("reset code step 1 done\n");
+//	clock_coda_reset(_do_set);
+//	printk("reset step 2 done\n");
+
+	//video_write(0xf, 0x15C>>2);//video clock disable
+//	clock_video_clockena(_clock_disable);
+//	clock_vib_clockena(_clock_disable);
+//	clock_coda_clockena(_clock_disable);
+
+	return 0;
+}
+
+static int csm_video_open(struct inode *inode, struct file *file)
+{
+	volatile char *start_addr = (volatile char *)vidmcu_base;
+    cnc1900_video_dev *cnc1900_video = NULL;
+
+	printk("CNC VIDEO has been opened\n");
+	printk("CNC VIDEO sizeof(DdrFwAttrT) = %d\n",sizeof(DdrFwAttrT));
+
+    if(NULL == file->private_data){
+
+        cnc1900_video = kmalloc(sizeof(cnc1900_video_dev), GFP_KERNEL); 
+        if(NULL == cnc1900_video){
+            printk("Cant't open video device\n"); 
+            return -EBUSY;
+        } 
+
+        process_num++;
+        cnc1900_video->instance_num = 1;
+
+        if(0 == fw_initialized){
+	        request_irq(VIDEO_IRQ, csm_vid_irq, 0, "cnc_video_irq", NULL);
+
+            printk("CNC VIDEO load video firmware ...\n");
+            irq_flags.val = 0;
+            irq_flags.bits.picture_ready_enable = 1;
+            irq_flags.bits.av_sync_enable       = 1;
+            //irq_flags.bits.yuv_frame_done_enable = 1;
+
+#ifndef CONFIG_SW_SUPPORT
+            video_int_write(0x1, INT_COPSW_EN_OFFSET>>2);
+            video_int_write(0x0, INT_COPSW_MASK_OFFSET>>2);
+            video_int_write(0x0, INT_COPSW_FORCE_OFFSET>>2);
+            __kernel_load_firmware(1);
+#else
+            video_int_write(0x1, INT_COPSW_EN_OFFSET);
+            video_int_write(0x0, INT_COPSW_MASK_OFFSET);
+            video_int_write(0x0, INT_COPSW_FORCE_OFFSET);
+#endif
+            memset((char *)start_addr,0x0,VIDEO_STUFF_SIZE);
+            __video_init(1);
+
+            fw_initialized = 1;
+        }
+        file->private_data = cnc1900_video;
+    }else{
+        cnc1900_video->instance_num++;
+    }
+	return 0;
+}
+
+
+static int csm_video_release(struct inode *inode, struct file *file)
+{
+    cnc1900_video_dev *cnc1900_video = NULL;
+    
+    if(file->private_data){ 
+
+        cnc1900_video = file->private_data;
+        cnc1900_video->instance_num--;
+     
+        if(cnc1900_video->instance_num > 0){
+
+        }else{
+            process_num--;
+            kfree(cnc1900_video);
+            file->private_data = NULL;
+
+            if(process_num <= 0){
+                if(fw_initialized){
+                    fw_initialized = 0;
+                    __csm_video_release_firmware();
+	                printk("CNC VIDEO release video firmware ...\n");
+                }
+            }
+        }
+        return 0;
+    }else{
+        //printk("Multi-times release video firmware don't again\n");
+        return -1;
+    }
+}
+static long csm_video_ioctl(struct file *file,unsigned int cmd, unsigned long arg)
+{
+	unsigned long flags;
+
+	switch (cmd){
+		case CSVID_IOC_GET_VIDEO_TO_HOST_MSG_SIZE:
+			__put_user(VIDEO_VIDEO_TO_HOST_MSG_SIZE, (unsigned int __user *) arg);
+			break;
+		case CSVID_IOC_GET_VIDEO_TO_HOST_MSG_ADDR:
+			__put_user(VIDEO_VIDEO_TO_HOST_MSG_REGION, (unsigned int __user *) arg);
+			break;
+		case CSVID_IOC_GET_HOST_TO_VIDEO_MSG_SIZE:
+			__put_user(VIDEO_HOST_TO_VIDEO_MSG_SIZE, (unsigned int __user *) arg);
+			break;
+		case CSVID_IOC_GET_HOST_TO_VIDEO_MSG_ADDR:
+			__put_user(VIDEO_HOST_TO_VIDEO_MSG_REGION, (unsigned int __user *) arg);
+			break;
+		case CSVID_IOC_GET_VIDEO_DPB_SIZE:
+			__put_user(VIDEO_DPB_SIZE, (unsigned int __user *) arg);
+			break;
+		case CSVID_IOC_GET_VIDEO_DPB_ADDR:
+			__put_user(VIDEO_DPB_REGION, (unsigned int __user *) arg);
+			break;
+		case CSVID_IOC_GET_VIDEO_CODA_ADDR:
+			__put_user(VIDEO_CODA_REGION, (unsigned int __user *) arg);
+			break;
+		case CSVID_IOC_GET_VIDEO_NUM:
+			__put_user(VIDEO_NUM, (unsigned int __user *) arg);
+			break;
+		case CSVID_IOC_GET_VIDEO_CPB_ADDR:
+			__put_user(VIDEO_CPB_REGION, (unsigned int __user *) arg);
+			break;
+		case CSVID_IOC_GET_VIDEO_CPB_SIZE:
+			__put_user(VIDEO_CPB_SIZE, (unsigned int __user *) arg);
+			break;
+		case CSVID_IOC_GET_VIDEO_CPB_DIR_ADDR:
+			__put_user(VIDEO_CPB_DIR_REGION, (unsigned int __user *) arg);
+			break;
+		case CSVID_IOC_GET_VIDEO_CPB_DIR_SIZE:
+			__put_user(VIDEO_CPB_DIR_SIZE, (unsigned int __user *) arg);
+			break;
+		case CSVID_IOC_GET_VIDEO_ENC_NUM:
+			__put_user(VIDEO_ENC_NUM, (unsigned int __user *) arg);
+			break;
+		case CSVID_IOC_GET_VIDEO_ENC_CPB_ADDR:
+			__put_user(VIDEO_ENC_CPB_REGION, (unsigned int __user *) arg);
+			break;
+		case CSVID_IOC_GET_VIDEO_ENC_CPB_SIZE:
+			__put_user(VIDEO_ENC_CPB_SIZE, (unsigned int __user *) arg);
+			break;
+		case CSVID_IOC_GET_VIDEO_ENC_DIR_ADDR:
+			__put_user(VIDEO_ENC_DIR_REGION, (unsigned int __user *) arg);
+			break;
+		case CSVID_IOC_GET_VIDEO_ENC_DIR_SIZE:
+			__put_user(VIDEO_ENC_DIR_SIZE, (unsigned int __user *) arg);
+			break;
+		case CSVID_IOC_GET_VIDEO_HOST_IF_ADDR:
+			__put_user(VIDEO_HOST_IF_REGION, (unsigned int __user *) arg);
+			break;
+		case CSVID_IOC_GET_VIDEO_HOST_IF_SIZE:
+			__put_user(VIDEO_HOST_IF_SIZE, (unsigned int __user *) arg);
+			break;
+		case CSVID_IOC_GET_VIDEO_REG_ADDR:
+			__put_user(CNC_VIDEO_REG_BASE, (unsigned int __user *) arg);
+			break;
+		case CSVID_IOC_GET_VIDEO_REG_SIZE:
+			__put_user(CNC_VIDEO_REG_SIZE, (unsigned int __user *) arg);
+			break;
+		case CSVID_IOC_GET_XPORT_SIZE:
+			__put_user(XPORT_SIZE, (unsigned int __user *) arg);
+			break;
+		case CSVID_IOC_GET_XPORT_WPRP_ADDR:
+			__put_user(MIPS_EXTERNAL_BASE_ADDR, (unsigned int __user *) arg);
+			break;
+		case CSVID_IOC_GET_XPORT_WPRP_SIZE:
+			__put_user(MIPS_EXTERNAL_SIZE, (unsigned int __user *) arg);
+			break;
+		case CSVID_IOC_GET_VIDEO_UD_ADDR:
+			__put_user(VIDEO_USER_DATA_REGION, (unsigned int __user *) arg);
+			break;
+		case CSVID_IOC_GET_VIDEO_UD_SIZE:
+			__put_user(VIDEO_USER_DATA_SIZE, (unsigned int __user *) arg);
+			break;
+        case CSVID_IOC_GET_HD2SD_MODE:
+            __put_user(__Is_hd2sd, (unsigned int __user *)arg);
+            break;
+        case CSVID_IOC_GET_VIDEO_CODA_CLOCK:
+			__put_user(CONFIG_VIDEO_CODA_CLOCK, (unsigned int __user *) arg);
+			break;
+        case CSVID_IOC_SET_VIDEO_ALPHA:
+        {
+            union{
+                struct{
+                    unsigned int blending2_alpha1:10;
+                    unsigned int reserved_1:6;
+                    unsigned int blending2_alpha2:10;
+                    unsigned int reserved_2:6;
+                }bits;
+                unsigned int val;
+            }b2_alpha;
+
+            b2_alpha.val = 0;
+            b2_alpha.bits.blending2_alpha1 = (unsigned int)arg & 0x3ff; 
+            b2_alpha.bits.blending2_alpha2 = (unsigned int)arg & 0x3ff; 
+
+            DF_Write(VPP_REG_COMP_B2_DEFAULT_ALPHA, b2_alpha.val);
+            break;
+        }
+        case CSVID_IOC_GET_VIDEO_ALPHA:
+        {
+            union{
+                struct{
+                    unsigned int blending2_alpha1:10;
+                    unsigned int reserved_1:6;
+                    unsigned int blending2_alpha2:10;
+                    unsigned int reserved_2:6;
+                }bits;
+                unsigned int val;
+            }b2_alpha;
+            b2_alpha.val = 0;
+            b2_alpha.val = DF_Read(VPP_REG_COMP_B2_DEFAULT_ALPHA);
+            __put_user(b2_alpha.bits.blending2_alpha1, (unsigned int __user*)arg);
+            break;
+        }
+        case CSVID_IOC_GET_TG1_PIC_FORMAT:
+        { 
+            if(copy_to_user((void*)arg, (void*)&host2videofw_if->VppBufAttr[BUF_TG1].PicFormat, sizeof(PicFormatT))){
+                return -EFAULT;
+            }
+            break; 
+        }
+		case CSVID_IOC_SET_VIDEO_START:
+//			printk("mips start\n");
+			video_write(VIDEO_MCU_REGION >> 3, MIPS_RESET_OFFSET);
+			break;
+
+		case CSVID_IOC_GET_NOTIFY_TYPE:
+		{
+			int tempval = 0;
+#ifdef IRQ_DEBUG
+			printk("\n--CSVID_IOC_GET_NOTIFY_TYPE-- flags:0x%x\n", irq_flags.val);
+#endif
+            spin_lock_irqsave(&notify_lock, flags);
+            if(irq_flags.bits.picture_ready_enable && irq_flags.bits.picture_ready){
+                tempval |= VID_INT_DEC_PIC_READY;
+                irq_flags.bits.picture_ready = 0;
+            }
+            if(irq_flags.bits.av_sync_enable && irq_flags.bits.av_sync){
+                tempval |= VID_INT_AV_SYNC_OK;
+                irq_flags.bits.av_sync = 0;
+            } 
+            if(irq_flags.bits.enc_frame_done_enable && irq_flags.bits.enc_frame_done){
+
+                tempval |= VID_INT_ENC_FRAME_DONE;
+                irq_flags.bits.enc_frame_done = 0;
+            } 
+            if(irq_flags.bits.yuv_frame_done_enable && irq_flags.bits.yuv_frame_done){
+
+                tempval |= VID_INT_FRAME_OUTPUT;
+                irq_flags.bits.yuv_frame_done = 0;
+            } 
+            if(irq_flags.bits.yuv_buf_info_done_enable && irq_flags.bits.yuv_buf_info_done){
+
+                tempval |= VID_INT_YUV_BUF_INFO;
+                irq_flags.bits.yuv_buf_info_done = 0;
+            } 
+            if(irq_flags.bits.dec_seq_change_enable && irq_flags.bits.dec_seq_change){
+
+                tempval |= VID_INT_DEC_SEQ_CHANGE;
+                irq_flags.bits.dec_seq_change = 0;
+            } 
+      
+			__put_user(tempval, (unsigned int __user *) arg);
+			spin_unlock_irqrestore(&notify_lock, flags);
+			break;
+		}
+
+		case CSVID_IOC_SET_NOTIFY_TYPE:
+		{
+			int type_val = 0;
+			int enable_bit = 0;
+#ifdef IRQ_DEBUG
+			printk("CSVID_IOC_SET_NOTIFY_TYPE!\n");
+#endif
+            spin_lock_irqsave(&notify_lock, flags);
+            type_val = arg & (~VID_INT_ENABLE);
+            enable_bit = arg>>31;
+#ifdef IRQ_DEBUG
+			printk("type_val = 0x%x, enable_bit = %d\n",type_val,enable_bit);
+#endif
+            if(type_val & VID_INT_DEC_PIC_READY){
+                irq_flags.bits.picture_ready_enable = enable_bit;
+                irq_flags.bits.picture_ready        = 0;
+            }
+            if(type_val & VID_INT_AV_SYNC_OK){
+                irq_flags.bits.av_sync_enable = enable_bit;
+                irq_flags.bits.av_sync        = 0;
+            }
+            if(type_val & VID_INT_ENC_FRAME_DONE){
+                irq_flags.bits.enc_frame_done_enable = enable_bit;
+                irq_flags.bits.enc_frame_done        = 0;
+            }
+            if(type_val & VID_INT_FRAME_OUTPUT){
+                irq_flags.bits.yuv_frame_done_enable = enable_bit;
+                irq_flags.bits.yuv_frame_done        = 0;
+            }
+            if(type_val & VID_INT_YUV_BUF_INFO){
+                irq_flags.bits.yuv_buf_info_done_enable = enable_bit;
+                irq_flags.bits.yuv_buf_info_done        = 0;
+            }
+            if(type_val & VID_INT_DEC_SEQ_CHANGE){
+                irq_flags.bits.dec_seq_change_enable = enable_bit;
+                irq_flags.bits.dec_seq_change        = 0;
+            }
+
+			spin_unlock_irqrestore(&notify_lock, flags);
+			break;
+		}
+
+		case CSVID_IOC_SET_VIB_PINMUX:
+			if(arg == 1){
+				pinmux_enable_i2c(_i2c_0);
+				pinmux_enable_vib();
+			}
+			else{
+				/* need do something here. */
+			}
+
+			clock_vib_reset(0);
+			udelay(10);
+			clock_vib_reset(1);
+			break;
+		case CSVID_IOC_RELOAD_FIRMWARE:
+			//__csm_video_release_firmware();
+			//udelay(100);
+#ifndef CONFIG_SW_SUPPORT
+			__kernel_load_firmware(0);
+#endif
+            //udelay(100);
+			//mdelay(1000);
+			__video_init(0);
+			//udelay(100);
+//			video_write(0x0, HOST_DPB_STATUS);
+//			video_write(0x0, MIPS_DPB_STATUS);
+	//		video_write(VIDEO_HOST_IF_REGION, HOST_IF_VID_MIPS_MAILBOX_0);
+#ifndef CONFIG_SW_SUPPORT
+			video_write(VIDEO_MCU_REGION >> 3, MIPS_RESET_OFFSET);
+#endif
+			//mdelay(10);
+			break;
+
+		default:
+			return -EINVAL;
+	}
+
+	return 0;
+}
+
+static unsigned int csm_video_poll(struct file *filp, poll_table * wait)
+{
+	unsigned int mask = 0;
+
+    if(irq_flags.bits.picture_ready || irq_flags.bits.av_sync || irq_flags.bits.enc_frame_done || irq_flags.bits.yuv_frame_done || irq_flags.bits.yuv_buf_info_done || irq_flags.bits.dec_seq_change){
+		mask = POLLIN | POLLWRNORM;
+		return mask;
+    }
+
+	poll_wait(filp, &notify_queue, wait);
+	return mask;
+}
+
+irqreturn_t csm_vid_irq(int irq, void *dev_id)
+{
+	unsigned long flag;
+	unsigned int irq_reg = 0;
+	unsigned int temp_val = 0;
+	//unsigned int channel_id = 0;
+
+	irq_reg = __video_read(MAILBOX_INT_TYPE);
+
+    if(irq_reg & VID_INT_DEC_PIC_READY){
+#ifdef IRQ_DEBUG
+        printk("csm_vid_irq VID_INT_DEC_PIC_READY\n");
+#endif
+        spin_lock_irqsave(&notify_lock, flag);
+        irq_flags.bits.picture_ready = 1;
+        spin_unlock_irqrestore(&notify_lock, flag);
+
+    }
+    if(irq_reg & VID_INT_AV_SYNC_OK){
+#ifdef IRQ_DEBUG
+        printk("csm_vid_irq VID_INT_AV_SYNC_OK\n");
+#endif
+        spin_lock_irqsave(&notify_lock, flag);
+        irq_flags.bits.av_sync = 1;
+        spin_unlock_irqrestore(&notify_lock, flag);
+    }
+    if(irq_reg & VID_INT_ENC_FRAME_DONE){
+#ifdef IRQ_DEBUG
+        //printk("csm_vid_irq VID_INT_ENC_FRAME_DONE\n");
+#endif
+        spin_lock_irqsave(&notify_lock, flag);
+        irq_flags.bits.enc_frame_done = 1;
+        spin_unlock_irqrestore(&notify_lock, flag);
+    }
+
+    if(irq_reg & VID_INT_FRAME_OUTPUT){
+#ifdef IRQ_DEBUG
+        printk("csm_vid_irq VID_INT_FRAME_OUTPUT\n");
+#endif
+        spin_lock_irqsave(&notify_lock, flag);
+        irq_flags.bits.yuv_frame_done = 1;
+        spin_unlock_irqrestore(&notify_lock, flag);
+    }
+
+    if(irq_reg & VID_INT_YUV_BUF_INFO){
+#ifdef IRQ_DEBUG
+        printk("csm_vid_irq VID_INT_YUV_BUF_INFO\n");
+#endif
+        spin_lock_irqsave(&notify_lock, flag);
+        irq_flags.bits.yuv_buf_info_done = 1;
+        spin_unlock_irqrestore(&notify_lock, flag);
+    }
+
+    if(irq_reg & VID_INT_DEC_SEQ_CHANGE){
+#ifdef IRQ_DEBUG
+        printk("csm_vid_irq VID_INT_DEC_SEQ_CHANGE\n");
+#endif
+        spin_lock_irqsave(&notify_lock, flag);
+        irq_flags.bits.dec_seq_change = 1;
+        spin_unlock_irqrestore(&notify_lock, flag);
+    }
+
+	temp_val = __video_read(MAILBOX_INT_TYPE);
+	temp_val = temp_val^irq_reg;
+	__video_write(MAILBOX_INT_TYPE, temp_val);
+
+#ifndef CONFIG_SW_SUPPORT
+    video_int_write(0, INT_COPSW_FORCE_OFFSET>>2);
+#else
+    video_int_write(0, INT_COPSW_FORCE_OFFSET);
+#endif
+	udelay(10);
+
+	return IRQ_HANDLED;
+}
+
+static void __video_mem_initialize(void)
+{
+#ifndef CONFIG_SW_SUPPORT
+	if (!request_mem_region(CNC_VIDEO_REG_BASE, CNC_VIDEO_REG_SIZE, "CNC1900 Video"))
+		goto ERR_MEM1;
+
+	if (NULL == (csm_video_base = ioremap(CNC_VIDEO_REG_BASE, CNC_VIDEO_REG_SIZE)))
+		goto ERR_MEM2;
+#endif
+	if (!request_mem_region(VIDEO_STUFF_REGION, VIDEO_STUFF_SIZE, "MCU Video"))
+		goto ERR_MEM3;
+
+	if (NULL == (vidmcu_base = ioremap(VIDEO_STUFF_REGION, VIDEO_STUFF_SIZE)))
+		goto ERR_MEM4;
+#ifndef CONFIG_SW_SUPPORT
+	if (!request_mem_region(CNC_INT_REG_BASE, CNC_INT_REG_SIZE, "Video INT"))
+		goto ERR_MEM5;
+
+	if (NULL == (vidint_base = ioremap(CNC_INT_REG_BASE, CNC_INT_REG_SIZE)))
+		goto ERR_MEM6;
+#endif
+	return;
+
+#ifndef CONFIG_SW_SUPPORT
+	ERR_MEM6:
+	release_mem_region(CNC_INT_REG_BASE, CNC_INT_REG_SIZE);
+	ERR_MEM5:
+	iounmap((void *) vidmcu_base);
+	ERR_MEM4:
+	release_mem_region(VIDEO_STUFF_REGION, VIDEO_STUFF_SIZE);
+	ERR_MEM3:
+	iounmap((void *) csm_video_base);
+	ERR_MEM2:
+	release_mem_region(CNC_VIDEO_REG_BASE, CNC_VIDEO_REG_SIZE);
+	ERR_MEM1:
+#else
+	ERR_MEM4:
+	release_mem_region(VIDEO_STUFF_REGION, VIDEO_STUFF_SIZE);
+	ERR_MEM3:
+#endif
+	return;
+}
+static void __video_mem_destroy(void)
+{
+#ifndef CONFIG_SW_SUPPORT
+	iounmap((void *)csm_video_base);
+	release_mem_region(CNC_VIDEO_REG_BASE, CNC_VIDEO_REG_SIZE);
+#endif
+	iounmap((void *)vidmcu_base);
+	release_mem_region(VIDEO_STUFF_REGION, VIDEO_STUFF_SIZE);
+#ifndef CONFIG_SW_SUPPORT
+	iounmap((void *)vidint_base);
+	release_mem_region(CNC_INT_REG_BASE, CNC_INT_REG_SIZE);
+#endif
+}
+
+static int __init cnc_video_init(void)
+{
+	if (register_chrdev(VIDEO_MAJOR, "cnc_1900_video", &csm_video_fops)){
+		printk("cnc_video_init register_chrdev failed.\n");
+		return -ENODEV;
+	}
+
+	video_pdev = platform_device_register_simple("cnc_1900_video", 0, NULL, 0);
+    	if (IS_ERR(video_pdev)) {
+		unregister_chrdev(VIDEO_MAJOR, "cnc_1900_video");
+		printk("cnc_video_init platform_device_register_simple failed.\n");
+        	return -ENODEV;
+    	}
+
+	csm_video_class = class_create(THIS_MODULE,"cnc_1900_video");
+	if (IS_ERR(csm_video_class)){
+		class_destroy(csm_video_class);
+		unregister_chrdev(VIDEO_MAJOR, "cnc_1900_video");
+		printk("cnc_video_init class create failed.\n");
+		csm_video_class = NULL;
+		return -ENODEV;
+	}
+
+	device_create(csm_video_class, NULL, MKDEV(VIDEO_MAJOR, 0), NULL, "cnc_1900_video");
+
+	csm_video_proc_entry = create_proc_entry("cnc_video", 0, NULL);
+	if (NULL != csm_video_proc_entry) {
+		csm_video_proc_entry->write_proc = &csm_video_proc_write;
+	}
+
+	__video_mem_initialize();
+
+	host2videofw_if = (DdrFwAttrT *)(vidmcu_base + (VIDEO_HOST_IF_OFFSET>>2));
+    memset(host2videofw_if, 0, sizeof(DdrFwAttrT));
+	printk("cnc_video_init done.\n");
+	return 0;
+}
+
+static void __exit cnc_video_exit(void)
+{
+	__video_mem_destroy();
+
+	if (NULL != csm_video_proc_entry)
+		remove_proc_entry("cnc_video", NULL);
+
+	device_destroy(csm_video_class,MKDEV(VIDEO_MAJOR, 0));
+	class_destroy(csm_video_class);
+	unregister_chrdev(VIDEO_MAJOR, "cnc_1900_video");
+
+	printk("cnc_video_exit done.\n");
+	return;
+}
+
+module_init(cnc_video_init);
+module_exit(cnc_video_exit);
+
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/celestial/video/cnc1900_video.h linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/video/cnc1900_video.h
--- linux-linaro-3.4-2012.05-1_original/drivers/celestial/video/cnc1900_video.h	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/video/cnc1900_video.h	2014-08-27 20:38:14.286427000 +0800
@@ -0,0 +1,133 @@
+#ifndef __CNC1900_VIDEO_H__
+#define __CNC1900_VIDEO_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define VIDEO_MAJOR 300
+
+#define VIDEO_MCU_REGION (VIDEO_STUFF_REGION)
+#define VIDEO_MCU_SIZE (0x80000)
+#define VIDEO_CODA_REGION (VIDEO_MCU_REGION+VIDEO_MCU_SIZE)
+#define VIDEO_CODA_SIZE (0x200000)
+#define VIDEO_CODA_OFFSET (VIDEO_CODA_REGION - VIDEO_MCU_REGION)
+#define VIDEO_HOST_IF_REGION (VIDEO_CODA_REGION +VIDEO_CODA_SIZE)
+#define VIDEO_HOST_IF_SIZE (0x80000)
+#define VIDEO_HOST_IF_OFFSET (VIDEO_HOST_IF_REGION - VIDEO_MCU_REGION)
+#define VIDEO_HOST_TO_VIDEO_MSG_REGION (VIDEO_HOST_IF_REGION +VIDEO_HOST_IF_SIZE)
+#define VIDEO_HOST_TO_VIDEO_MSG_SIZE (0x80000)
+#define VIDEO_HOST_TO_VIDEO_MSG_OFFSET (VIDEO_HOST_TO_VIDEO_MSG_REGION - VIDEO_MCU_REGION)
+#define VIDEO_VIDEO_TO_HOST_MSG_REGION (VIDEO_HOST_TO_VIDEO_MSG_REGION +VIDEO_HOST_TO_VIDEO_MSG_SIZE)
+#define VIDEO_VIDEO_TO_HOST_MSG_SIZE (0x80000)
+#define VIDEO_VIDEO_TO_HOST_MSG_OFFSET (VIDEO_VIDEO_TO_HOST_MSG_REGION - VIDEO_MCU_REGION)
+
+/* Need to check below */
+#define MIPS_ISRAM_MEM_SIZE	(1024 * 9)	/* 9KB */
+#define MIPS_DSRAM_MEM_SIZE	(1024 * 16)	/* 16KB */
+
+#define INST_OUT_MEM_SIZE	(1024 * 1)
+#define INST_MIPS_MEM_SIZE	(1024 * 8)
+
+#if (defined CONFIG_SW_SUPPORT)
+#define MIPS_ISRAM_OFFSET	(0xb1690000)
+#define MIPS_DSRAM_OFFSET	(0xb16A0000)
+#define MIPS_RESET_OFFSET	(0xb16B0000)
+#else
+#define MIPS_ISRAM_OFFSET	((0xb1690000 - CNC_VIDEO_REG_BASE) >> 2)
+#define MIPS_DSRAM_OFFSET	((0xb16A0000 - CNC_VIDEO_REG_BASE) >> 2)
+#define MIPS_RESET_OFFSET	((0xb16B0000 - CNC_VIDEO_REG_BASE) >> 2)
+#endif
+#define MEM_SWAP32(x)	( (((x) & 0xff) << 24) | (((x) & 0xff00) <<8) |	(((x) & 0xff0000) >> 8) | (((x) & 0xff000000) >> 24) )
+
+#define CSVID_IOC_GET_VIDEO_CPB_ADDR	        _IOW('z', 0x01, int)
+#define CSVID_IOC_GET_VIDEO_CPB_SIZE	        _IOW('z', 0x02, int)
+#define CSVID_IOC_GET_VIDEO_CPB_DIR_ADDR	    _IOW('z', 0x03, int)
+#define CSVID_IOC_GET_VIDEO_CPB_DIR_SIZE	    _IOW('z', 0x04, int)
+                                                
+#define CSVID_IOC_GET_VIDEO_HOST_IF_ADDR	    _IOW('z', 0x05, int)
+#define CSVID_IOC_GET_VIDEO_HOST_IF_SIZE	    _IOW('z', 0x06, int)
+#define CSVID_IOC_GET_VIDEO_REG_ADDR		    _IOW('z', 0x07, int)
+#define CSVID_IOC_GET_VIDEO_REG_SIZE		    _IOW('z', 0x08, int)
+                                                
+#define CSVID_IOC_GET_NOTIFY_TYPE	            _IOW('z', 0x09, int)
+#define CSVID_IOC_SET_NOTIFY_TYPE	            _IOW('z', 0x0a, int)
+                                                
+#define CSVID_IOC_GET_XPORT_VIDEO	            _IOW('z', 0x0b, int)
+#define CSVID_IOC_SET_VIB_PINMUX                _IOW('z', 0x0c, int)
+                                                
+#define CSVID_IOC_GET_VIDEO_UD_ADDR             _IOW('z', 0x0d, int)
+#define CSVID_IOC_GET_VIDEO_UD_SIZE             _IOW('z', 0x0e, int)
+                                                
+#define CSVID_IOC_RELOAD_FIRMWARE               _IOW('z', 0x0f, int)
+#define CSVID_IOC_GET_VIDEO_NUM	                _IOW('z', 0x10, int)
+                                                
+#define CSVID_IOC_SET_VIDEO_ALPHA               _IOW('z', 0x11, int)
+#define CSVID_IOC_GET_VIDEO_ALPHA               _IOR('z', 0x12, int)
+#define CSVID_IOC_GET_TG1_PIC_FORMAT            _IOR('z', 0x13, int)
+#define CSVID_IOC_GET_HD2SD_MODE                _IOR('z', 0x14, int)
+#define CSVID_IOC_GET_VIDEO_CODA_CLOCK          _IOR('z', 0x15, int)
+                                                
+#define CSVID_IOC_GET_VIDEO_CODA_ADDR	        _IOW('z', 0x20, int)
+#define CSVID_IOC_GET_VIDEO_DPB_ADDR	        _IOW('z', 0x21, int)
+#define CSVID_IOC_GET_VIDEO_DPB_SIZE	        _IOW('z', 0x22, int)
+#define CSVID_IOC_GET_HOST_TO_VIDEO_MSG_ADDR	_IOW('z', 0x23, int)
+#define CSVID_IOC_GET_HOST_TO_VIDEO_MSG_SIZE	_IOW('z', 0x24, int)
+#define CSVID_IOC_GET_VIDEO_TO_HOST_MSG_ADDR	_IOW('z', 0x25, int)
+#define CSVID_IOC_GET_VIDEO_TO_HOST_MSG_SIZE	_IOW('z', 0x26, int)
+
+#define CSVID_IOC_GET_VIDEO_ENC_NUM	            _IOW('z', 0x30, int)
+#define CSVID_IOC_GET_VIDEO_ENC_CPB_ADDR 	    _IOW('z', 0x31, int)
+#define CSVID_IOC_GET_VIDEO_ENC_CPB_SIZE 	    _IOW('z', 0x32, int)
+#define CSVID_IOC_GET_VIDEO_ENC_DIR_ADDR 	    _IOW('z', 0x33, int)
+#define CSVID_IOC_GET_VIDEO_ENC_DIR_SIZE 	    _IOW('z', 0x34, int)
+
+#define CSVID_IOC_GET_XPORT_SIZE	            _IOR('z', 0x35, int)
+#define CSVID_IOC_GET_XPORT_WPRP_ADDR	        _IOR('z', 0x36, int)
+#define CSVID_IOC_GET_XPORT_WPRP_SIZE	        _IOR('z', 0x37, int)
+
+#define CSVID_IOC_SET_VIDEO_START		        _IOW('z', 0xfe, int)
+
+//#define VIDEO_NOTIFY_TYPE_ENABLE 0x80000000
+//#define VIDEO_NOTIFY_TYPE_PICTURE_READY     (1<<0)
+//#define VIDEO_NOTIFY_TYPE_AV_SYNC           (1<<1)
+//#define VIDEO_NOTIFY_TYPE_ENC_FRAME_DONE    (1<<2)
+//#define VIDEO_NOTIFY_TYPE_TIMECODE 0x1
+//#define VIDEO_NOTIFY_TYPE_DECODERERROR 0x2
+//#define VIDEO_NOTIFY_TYPE_ASPECTRATIO 0x4
+//#define VIDEO_NOTIFY_TYPE_PANSCANCROP 0x8
+//#define VIDEO_NOTIFY_TYPE_SYNC1 0x10
+//#define VIDEO_NOTIFY_TYPE_SYNC2 0x20
+//#define VIDEO_NOTIFY_TYPE_UNDERFLOW 0x40
+//#define VIDEO_NOTIFY_TYPE_FORMATCHANGE 0x80
+//#define VIDEO_NOTIFY_TYPE_SRC_FORMATCHANGE 0x100
+//#define VIDEO_NOTIFY_TYPE_DECODE_FINISHED 0x200
+//
+
+//!!!Note: please must be to update kernel you will can properly to use video (decoder & encoder).
+/*Video interrupt type*/
+typedef enum _VID_INT_TYPE{
+    VID_INI_UNKNOWN        =  -1    ,
+    VID_INT_FW_ERROR       =  (1<<0),
+    VID_INT_CMD_ACK        =  (1<<1),
+    VID_INT_LOG_MESSAGE    =  (1<<2),
+    VID_INT_ENC_FRAME_DONE =  (1<<3),//encoder frame interrupt flags
+    VID_INT_MEM_ALLOC      =  (1<<4),
+    VID_INT_MEM_FREE       =  (1<<5),
+    VID_INT_FRAME_OUTPUT   =  (1<<6),
+    VID_INT_FRAME_RELEASE  =  (1<<7),
+    VID_INT_DEC_PIC_READY  =  (1<<8),//decoder frame interrupt flags
+    VID_INT_AV_SYNC_OK     =  (1<<9),//av sync interrupt flags
+    VID_INT_DISPLAY_VSYNC  =  (1<<10),//vsync from vpp
+    VID_INT_YUV_BUF_INFO   =  (1<<11),//YUV buffer info for playback
+    VID_INT_DEC_SEQ_CHANGE =  (1<<12),//Decoder sequence change
+
+    VID_INT_ENABLE         =  (1<<31),//interrupt enable bit
+}CSVID_INT;                  
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/celestial/video/Kconfig linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/video/Kconfig
--- linux-linaro-3.4-2012.05-1_original/drivers/celestial/video/Kconfig	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/video/Kconfig	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,82 @@
+
+menu "Celestial Video Drivers"
+
+if ARCH_CELESTIAL
+config CELESTIAL_VIDEO
+	bool "CNC1900 Video"
+	depends on ARCH_CELESTIAL
+	default y
+	help 
+	    Include support drvier for video of celestial platform.
+endif
+
+config VIDEO_DECODER
+	bool "Video Decoder"
+	depends on CELESTIAL_VIDEO
+	default y
+	help
+	    Enable video decoder. Some projects no need to decoder video date. It can be disabled for saving memory.
+
+config VIDEO_ENCODER
+	bool "Video Enocder"
+	depends on CELESTIAL_VIDEO
+	default n
+	help
+	    Enable video encoder. Some projects no need to encoder video date. It can be disabled for saving memory.
+
+config VIDEO_CODA_CLOCK
+	int "Video Coda clock"
+	depends on CELESTIAL_VIDEO
+	range 0 2
+	default 0
+	help
+	    The coda clock of video engine, default is 0.
+
+config VIDEO_NUM
+	int "Video Number"
+	depends on VIDEO_DECODER
+	range 1 2
+	default 1
+	help
+	    The number of video supported by video decoder, can be set to 1 or 2.
+
+config VIDEO_CPB_SIZE
+	hex "Video CPB Size"
+	depends on VIDEO_DECODER
+	range 0x400000 0x1000000
+	default 0x400000
+	help
+	    Compressed picture buffer size of one video, range from 0x400000 to 0xc00000.
+
+config VIDEO_ENC_NUM
+	int "Video Encoder Number"
+	depends on VIDEO_ENCODER
+	range 1 1
+	default 1
+	help
+	    The number of video supported by video encoder, can be set to 1.
+
+config VIDEO_ENC_CPB_SIZE
+	hex "Video Encoder CPB Size"
+	depends on VIDEO_ENCODER
+	range 0x400000 0x1000000
+	default 0x400000
+	help
+	    Compressed picture buffer size of one video, range from 0x400000 to 0xc00000.
+
+config CELESTIAL_VIDEO_DEBUG
+	bool "Video Debugging"
+	depends on CELESTIAL_VIDEO
+	help
+	    This turns on low-level debugging for the celestial video driver.
+	    Normally, you should say 'N'.
+
+
+config VIDEO_DEBUG_VERBOSE
+	int "VIDEO Debugging verbosity (0 = quiet, 3 = noisy)"
+	depends on CELESTIAL_VIDEO_DEBUG
+	default "0"
+	help
+	    Determines the verbosity level of the video debugging messages.
+
+endmenu
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/celestial/video/Makefile linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/video/Makefile
--- linux-linaro-3.4-2012.05-1_original/drivers/celestial/video/Makefile	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/video/Makefile	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,6 @@
+#
+# Makefile for the linux kernel.
+# 
+#
+obj-$(CONFIG_MACH_CELESTIAL_CNC1900) += cnc1900_video.o
+
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/celestial/video/video_handshake_def.h linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/video/video_handshake_def.h
--- linux-linaro-3.4-2012.05-1_original/drivers/celestial/video/video_handshake_def.h	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/video/video_handshake_def.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,569 @@
+
+#ifndef _FW_ATTR_H_ 
+#define _FW_ATTR_H_
+#ifdef __cplusplus
+extern "C"{
+#endif
+
+/*FPGA related definition*/
+//#define MIPS_RUN 1
+//
+//#define VIDEO_CODA  1
+//#define VIDEO_VPP 1
+//#define VIDEO_VPB 1
+//#define INT_CONTROLLER 1
+//#define HAND_BY_SEM 0 //set to '1' to support mips run without VPP
+//#define UES_OLD_CMD 0
+//#define VPP_CONFIG_DYN   1
+//
+//==============================================================================
+
+#define MAX_WIN_NUM   4
+#define DEC_CPB_NUM   4
+#define ENC_CPB_NUM   4
+#define VPB_NUM       1
+#define CAP_NUM        1
+#define ROT_NUM       1
+#define SRC_BUF_NUM   (DEC_CPB_NUM + VPB_NUM+CAP_NUM)
+
+#define SRC_BUF_MASK ((1<<SRC_BUF_NUM) - 1)
+
+//==============================================================================
+typedef enum
+{
+    CH_CPB0,
+    CH_CPB1,
+    CH_CPB2,
+    CH_CPB3,
+    CH_VPB0,
+    CH_CAP0
+}ChannelDecT;
+
+typedef enum
+{
+    CH_ENC0,
+    CH_ENC1,
+    CH_ENC2,
+    CH_ENC3
+}ChannelEncT;
+
+typedef enum {
+    VID_WINDOW_DEST_TG1 = 0,
+    VID_WINDOW_DEST_TG2,
+    VID_WINDOW_DEST_ENC0,
+    VID_WINDOW_DEST_ENC1,
+    VID_WINDOW_DEST_ENC2,
+    VID_WINDOW_DEST_ENC3,
+    VID_WINDOW_DEST_INVALID = 0xff
+} VidWindowDestT;
+
+typedef enum {
+    VID_WINDOW_SRC_CPB0 = 0,
+    VID_WINDOW_SRC_CPB1,
+    VID_WINDOW_SRC_CPB2,
+    VID_WINDOW_SRC_CPB3,
+    VID_WINDOW_SRC_VPB,
+    VID_WINDOW_SRC_CAP_TG1,
+    VID_WINDOW_SRC_CAP_EXT
+} VidWindowSrcT;
+
+typedef enum
+{
+    LAYER_HWSEL_NONE=0,
+    LAYER_HWSEL_SR,
+    LAYER_HWSEL_MAIN,
+    LAYER_HWSEL_RD2,
+    LAYER_HWSEL_DMA,
+    LAYER_HWSEL_CAP,
+    LAYER_HWSEL_VPB,
+    LAYER_HWSEL_DEC,
+    LAYER_HWSEL_ENC,
+    LAYER_HWSEL_NUM
+}LayerHwSelT;
+
+typedef enum
+{
+    FORMAT_2D, //normal 2D progressive or line-interleaved interlaced video
+    FORMAT_SBS, //normal 3D side-by-side progressive or line-interleaved interlaced video
+    FORMAT_TAB, //normal 3D top-and-bottom progressive video
+    FORMAT_FP, //normal 3D frame packing, left & right eye separated frame
+    FORMAT_PV_FP_2D_I, //PureVu 2D frame-packing (interlaced), top/bottom field separated
+    FORMAT_PV_FP_3D //PureVu 3D frame-packing, left & right eye packed in one frame
+}Format3DT;
+
+typedef enum
+{
+    PLAY_MODE_STOP = 0,
+    PLAY_MODE_RUN,
+    PLAY_MODE_PAUSE,
+    PLAY_MODE_FREEZE,
+    PLAY_MODE_STEP
+}PlayModeT;
+
+typedef enum
+{
+    ENC_MODE_STOP = 0,
+    ENC_MODE_RUN
+}EncModeT;
+
+typedef enum
+{
+    UPDATE_PLAY_CMD = 0,
+    UPDATE_REC_CMD,
+    UPDATE_DEBUG_CMD,
+    UPDATE_TG_CHG_CMD,
+    UPDATE_CODA_RESET_CMD
+}UpdateCmdType;
+
+typedef enum
+{
+    DECODE_IPB = 0,
+    DECODE_I,
+    DECODE_IP,
+    DECODE_NONE
+}DecModeT;
+
+typedef enum
+{
+    PLAY_SPEED_1_32 = 0,
+    PLAY_SPEED_1_16,
+    PLAY_SPEED_1_8,
+    PLAY_SPEED_1_4,
+    PLAY_SPEED_1_2,
+    PLAY_SPEED_NORMAL,
+    PLAY_SPEED_2,
+    PLAY_SPEED_4,
+    PLAY_SPEED_8,
+    PLAY_SPEED_16,
+    PLAY_SPEED_32
+}PlaySpeedT;
+
+typedef enum
+{
+    VID_CODEC_STD_AVC = 0,
+    VID_CODEC_STD_VC1,
+    VID_CODEC_STD_MPEG2,
+    VID_CODEC_STD_MPEG4,
+    VID_CODEC_STD_H263,
+    VID_CODEC_STD_DIV3,
+    VID_CODEC_STD_RV,
+    VID_CODEC_STD_AVS,
+    VID_CODEC_STD_MJPG,
+    VID_CODEC_STD_THO = 9,
+    VID_CODEC_STD_VP3,
+    VID_CODEC_STD_VP8,
+    VID_CODEC_STD_MVC,
+    VID_CODEC_STD_UNKNOW = 0xff
+} VidCodecStdT;
+
+typedef enum
+{
+    LLD_DISABLE = 0,
+    LLD_PARTIAL_FRAME_MODE = (1<<0), //start display earlier. Only support H.264. NOTE:reorder will be off
+    LLD_STREAM_LOW_DELAY_MODE = (1<<1) //start decoding earlier.
+}LowLatencyDecModeT;
+
+//==============================================================================
+typedef enum
+{
+    DEBUG_BITSTREAM_STATUS = 0,
+    DEBUG_MIPS_READ_DATA,
+    DEBUG_MIPS_WRITE_ADDR,
+    DEBUG_MIPS_WRITE_DATA,
+    DEBUG_MIPS_LOG_ADDR,
+    DEBUG_VPP_MEM_USAGE,
+    DEBUG_FIFO_STATUS,
+    DEBUG_FIFO_OPEN,
+    DEBUG_FIFO_PUSH,
+    DEBUG_FIFO_POP,
+    DEBUG_FIFO_CLOSE,
+    DEBUG_FIFO_READ,
+    DEBUG_LOG_ENABLE,
+    DEBUG_MIPS_TEST
+}HostDebugCmdT;
+
+typedef enum
+{
+    VID_FW_STACK_OVERFLOW = 0,  //MIPS firmware stack overflow.
+    VID_MEM_OVERFLOW,           //Picture buffer memory overflow.
+    VID_MEM_CONFIG_INVALID,     //Host configured memory with invalid parameters such as alignment, 420/422 size etc.
+    VID_DEC_FATAL_ERR,          //Fatal error of VPU that current channel must be closed.
+    VID_DEC_SEQ_INIT_TIMEOUT,   //Could not find sequence header for decoder.
+    VID_DEC_SEQ_INIT_FAIL,      //Sequence header decode fail.
+    VID_DEC_TOO_MANY_REF_FRAMES,//Too many reference frames for decoder.
+    VID_DEC_FRAME_ERR,          //Error detected in the current frame for decoder.
+    VID_DEC_EOF,                //EOF detected and decoder will be closed.
+    VID_DEC_TIMEOUT,            //VPU timeout during frame decoding. Need to be reset.
+    VID_ENC_FATAL_ERR,          //Fatal error of VPU that current channel must be closed.
+    VID_ENC_TOO_MANY_REF_FRAMES,//Too many reference frames for encoder.
+    VID_ENC_TIMEOUT,            //VPU timeout during frame encoding. Need to be reset.
+    VID_VPP_CONFIG_INVALID      //Invalid parameters for VPP.
+}VidFwErrorTypeT;
+
+typedef struct
+{
+    unsigned char PlayMode:3;
+    unsigned char PlaySpeed:5;
+}PlayCtrlCmdT;
+
+//==============================================================================
+
+typedef struct
+{
+    unsigned int   Format3D:4; 		//2D, SbS, TaB, FP, PVFP-2D-i, PVFP-3D
+    unsigned int   IsInterlace:1;
+    unsigned int   HorSample:1;
+    unsigned int   VerSample:1;
+    unsigned int   TopFieldFirst:1;
+    unsigned int   VactSpace1:8;		//for interlace or progressive frame packing, see HDMI Spec
+    unsigned int   VactSpace2:8;		//for interlace frame packing, see HDMI Spec
+    unsigned int   PicWidth:16;
+    unsigned int   PicHeight:16;
+    unsigned int   FrameRate;
+}PicFormatT;
+
+//==============================================================================
+
+typedef struct
+{
+    unsigned int Pts;
+    unsigned int EsByteCounter; 
+    unsigned int Eof:1;
+    unsigned int Rotate:2;
+    unsigned int Mirror:2;
+    unsigned int SubPicLast:1;   
+    unsigned int SubPicStartX:13;
+    unsigned int SubPicStartY:13;
+    unsigned int Reserved;
+}PtsFifoT;
+
+typedef struct
+{
+    unsigned int Pts;
+    unsigned int EsByteCounter; 
+    unsigned int Reserved0;
+    unsigned int Reserved1;
+}EncCpbPtsFifoT; 
+
+//==============================================================================
+
+typedef struct
+{
+    unsigned int YTnrEn:1;
+    unsigned int YTnrGate:6;
+    unsigned int YTnrDiv:2;
+    unsigned int CTnrEn:1;
+    unsigned int CTnrGate:6;
+    unsigned int CTnrDiv:2;
+}MainT;
+
+typedef struct
+{
+    unsigned char SrK;
+}SrT;
+
+typedef struct
+{
+    unsigned int BgY:10;
+    unsigned int BgU:10;
+    unsigned int BgV:10;
+    unsigned char  V1Order: 2;
+    unsigned char  V2Order: 2;
+    unsigned char  G1Order: 2;
+    unsigned char  G2Order: 2;
+    /*
+    unsigned short StartX;
+    unsigned short StartY;
+    unsigned short EndX;
+    unsigned short EndY;
+    */
+}BlendT;
+
+typedef struct
+{
+    unsigned int Bright:8;
+    unsigned int Contrast:6;
+    unsigned int Saturation:8;
+    unsigned int sharp_en:1;
+}ColorT;
+
+typedef enum
+{
+    TG_ID1=0,
+    TG_ID2,
+    TG_NUM
+}TG_ID;
+
+typedef enum
+{
+    BLEND_ID1=0,
+    BLEND_ID2,
+    BLEND_ID3,
+    BLEND_NUM
+}BLEND_ID;
+
+typedef enum
+{
+    UI_ID1=0,
+    UI_ID2,
+    UI_NUM
+}UI_ID;
+
+ 
+
+typedef struct
+{
+    MainT Main;
+    SrT Sr;
+    //BlendT Blend[BLEND_NUM];
+    //ColorT Color;
+ }SocAttrT;
+
+//==============================================================================
+typedef enum
+{
+    INT_DISABLE=0,
+    INT_ENABLE
+}IntMode;
+typedef struct
+{
+    //unsigned int CodaBitCodeAddr;
+    unsigned int VppBufAddr;
+    unsigned int VppBufSize;
+    unsigned int FwUploadMsgBufAddr;
+    unsigned int FwUploadMsgBufSize;
+    unsigned int FwDownloadMsgBufAddr;
+    unsigned int FwDownloadMsgBufSize;
+    unsigned int HdPicHeight:12;
+    unsigned int V420BlockNum:8;
+    unsigned int DecIntMode:1;
+    unsigned int VppIntMode:1;
+    unsigned int VpbIntMode:1;
+    unsigned int SubPicAppEn:1;//Only for acer project
+    unsigned int VppMainForceF2fEn:1; //for multi-win case
+    unsigned int AddrDynAllocSwitch:1;//Dynamic allocate address switch
+    unsigned int AvSyncByHostSwitch:1;//Av sync by host switch.
+    unsigned int CodaProfileEn:1;
+    unsigned int Hd2SdEn:1;
+}FwAttrT;
+
+//==============================================================================
+typedef struct
+{
+    unsigned short AvsyncEn:1;
+    unsigned short AvsyncByFrc:1;
+    unsigned short NoAudio:1;
+    unsigned short AvDelay:13;    //--TBD
+}AvSyncAttrT;
+
+typedef struct
+{
+    unsigned int HorSyncPolarity:1; //0: high pulse, 1: low pulse
+    unsigned int VerSyncPolarity:1; //0: high pulse, 1: low pulse
+    unsigned int FldSyncPolarity:1; //0: high pulse, 1: low pulse
+    unsigned int SyncMode:2;        //0: embedded sync, 1: separate sync (H/V), 2: DE only mode, 3: SMPTE
+    unsigned int IsHd:1;
+    unsigned int RgbMode:1;
+    unsigned int BodaFormat:1;
+    unsigned int InterfBitWidth:2;//0: 8-bit interface, 1: 16-bit interface, 2: 24-bit interface
+    unsigned int HorSyncPulse:8;
+    unsigned int VerSyncPulse:8;
+    unsigned int StartEncThres:7; //Threshold to begin encoding the frame (in unit of MB rows).
+
+    unsigned int PixelFreqHz;
+    unsigned int HorFrontPorch:16;   
+    unsigned int HorBackPorch:16;
+    unsigned int VerFrontPorch:16;  
+    unsigned int VerBackPorch:16;      
+} VpbDetailFormatT;
+
+typedef struct
+{
+    VpbDetailFormatT VpbDetailFormat;
+}VpbAttrT;
+
+typedef struct
+{
+    unsigned int DecMode:2; //DecModeT
+    unsigned int DecFile:1;
+    unsigned int CodecStd:4;
+    unsigned int LowLatencyMode:3; //set LowLatencyDecModeT
+    unsigned int LowLatencyMbRowPercent:7; //0~100 to represent 0 to full frame
+    unsigned int ReserveBufAtClose:1; //do not release buffer at close for display or switch reason
+    unsigned int DecOneJpeg:1;
+    unsigned int RotationEnable:1;
+    unsigned int ReorderEnable:1;
+    unsigned int StreamEndFlag:1;
+    unsigned int JpegFrameAddr;
+    unsigned int PtsFifoStartAddr;
+    unsigned int PtsFifoEndAddr;
+    unsigned int EsFifoStartAddr;
+    unsigned int EsFifoEndAddr;
+    unsigned int MjpgEsFifoStartAddr;
+    unsigned int MjpgEsFifoEndAddr;
+}DecCpbAttrT;
+
+//==============================================================================
+
+typedef struct{
+    unsigned int sliceMode:1;    //0: one slice per picture; 1: multiple slices per picture.
+    unsigned int sliceSizeMode:1;//0 means the sliceSize is defined by the amount of bits, and 1 means the sliceSize is defined by the number of MBs.
+    unsigned int sliceSize:30;   //size of a slice in bits or in MB numbers included in a slice
+} EncSliceModeT;
+
+typedef struct
+{
+    unsigned char Mp4_DataPartitionEn:1;
+    unsigned char Mp4_RvlcEn:1;
+}EncMp4ParamT;
+
+typedef struct
+{
+    unsigned char H263_AnnexIEn:1;
+    unsigned char H263_AnnexJEn:1;
+    unsigned char H263_AnnexKEn:1;
+    unsigned char H263_AnnexTEn:1;
+}EncH263ParamT;
+
+typedef struct
+{
+    unsigned int Avc_DisableDeblocking:1;
+}EncAvcParamT;
+
+typedef struct
+{
+    unsigned char Mjpg_SrcFormat; //0-4:2:0, 1-4:2:2 horizontal, 2-4:2:2 vertical, 3-4:4:4, 4-4:0:0
+    unsigned char *HuffVal;	
+	unsigned char *HuffBits;	
+	unsigned char *QMatTab;
+	unsigned char *CInfoTab;
+}EncMjpgParamT;
+
+typedef struct
+{
+    int FrameRateInfo;
+    unsigned int BitRate:16; // Maximum bitrate value is 65535 kbps. 0 to disable rc.
+    unsigned int IntraRefresh:16;
+    unsigned int RateCtrlMode:2; // rate control enable (0:constant QP, 1:CBR, 2:ABR)
+    unsigned int QpY:6;      // 1~31 for MPEG4; 0~51 for H.264
+    unsigned int EnableAutoSkip:1;
+    unsigned int GopSize:15; //Maximum value will be 32767.
+    unsigned int MeSearchRangeX:2; // 0:(-64~63) 1:(-48~47) 2:(-32~31) 3:(-16~15)
+    unsigned int MeSearchRangeY:2; // 0:(-48~47) 1:(-32~31) 2:(-16~15)
+    unsigned int Profile:2; //H.264: 0:BP 1:MP 2:HP  MPEG4:ignored
+    EncSliceModeT EncSliceMode;
+    union {
+		EncMp4ParamT Mp4Param;
+		EncH263ParamT H263Param;
+		EncAvcParamT AvcParam;
+		EncMjpgParamT MjpgParam;  	
+	} EncStdParam;
+}EncOpenParamT;
+
+typedef struct
+{
+    unsigned int SrcBufNo:8;//DpbBufNo:8;
+    unsigned int CodecStd:4;
+    unsigned int SubFrameSyncEn:1;
+    unsigned int EncOneJpeg:1;
+    unsigned int JpegFrameAddr;
+    unsigned int PtsFifoStartAddr;
+    unsigned int PtsFifoEndAddr;
+    unsigned int EsFifoStartAddr;
+    unsigned int EsFifoEndAddr;
+    unsigned int MjpgEsFifoStartAddr;
+    unsigned int MjpgEsFifoEndAddr;
+    PicFormatT PicFormat;
+    EncOpenParamT EncOpenParam;
+}EncCpbAttrT;
+/********************************new achitecture******************************/
+typedef enum//f2d,f2f,d2f must be that order
+{
+    WIN_F2D_SR=0,
+    WIN_F2D_MAIN,
+    WIN_F2D_RD2,
+    WIN_F2F_MAIN_IDX0,
+    WIN_F2F_MAIN_IDX1,
+    WIN_F2F_MAIN_IDX2,
+    WIN_F2F_MAIN_IDX3,
+    WIN_F2F_DMA,
+    WIN_D2F_CAP,
+    WIN_D2F_VPB,
+    WIN_NUM
+}WinNoT;
+typedef enum
+{
+    BUF_DEC_IDX0=0,
+    BUF_DEC_IDX1,
+    BUF_DEC_IDX2,
+    BUF_DEC_IDX3,
+    BUF_VPB,
+    BUF_CAP,
+    BUF_F2F_MAIN_IDX0,
+    BUF_F2F_MAIN_IDX1,
+    BUF_F2F_MAIN_IDX2,
+    BUF_F2F_MAIN_IDX3,
+    BUF_F2F_MAIN_TG1MUL,
+    BUF_F2F_DMA,
+    BUF_TG1,
+    BUF_TG2,
+    BUF_ENC_IDX0,
+    BUF_ENC_IDX1,
+    BUF_ENC_IDX2,
+    BUF_ENC_IDX3,
+    BUF_EXT,
+    BUF_ROT_IDX0,
+    BUF_ROT_IDX1,
+    BUF_ROT_IDX2,
+    BUF_ROT_IDX3,
+    BUF_NUM
+}BufNoT;
+typedef struct
+{
+    unsigned short StartX;
+    unsigned short EndX;
+    unsigned short StartY;
+    unsigned short EndY;
+}WinRectT;
+typedef struct
+{
+    unsigned char En:1;
+    unsigned char HwSel:3;								//f2d: tg1(main/sr)/tg2(rd2); f2f: main/dma; d2f: vpb/cap; together 6(main/sr/dma/rd2/cap/vpb)
+    unsigned char F2fOrder:4;
+    unsigned char AlphaEn; //windows alpha , 1:en,0:dis,default 1. add by wanglixin
+    unsigned char SrcBufNo;						//d2f: see tg1/ext as buf
+    unsigned char DesBufNo;						//f2d: see tg1/tg2 as buf
+    WinRectT Src;
+    WinRectT Des;
+}VppWinAttrT;
+
+typedef struct
+{
+    PicFormatT PicFormat;
+    AvSyncAttrT AvSyncAttr; //En just for DecBuf[DecMax] & DmaBuf[1]******
+}VppBufAttrT;
+
+typedef struct
+{
+    SocAttrT SocAttr;
+    FwAttrT FwAttr;
+    DecCpbAttrT DecCpbAttr[DEC_CPB_NUM];
+    EncCpbAttrT EncCpbAttr[ENC_CPB_NUM];
+    VpbAttrT VpbAttr[VPB_NUM];
+    VppWinAttrT VppWinAttr[WIN_NUM];
+    VppBufAttrT VppBufAttr[BUF_NUM];
+}DdrFwAttrT;
+
+//==============================================================================
+
+//extern DdrFwAttrT DdrFwAttr;
+//extern PlayCtrlCmdT PlayCtrlCmd[SRC_BUF_NUM];
+
+//==============================================================================
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/celestial/video/video_reg_def.h linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/video/video_reg_def.h
--- linux-linaro-3.4-2012.05-1_original/drivers/celestial/video/video_reg_def.h	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/video/video_reg_def.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,94 @@
+#ifndef _VIDEO_REG_DEF_H_
+#define _VIDEO_REG_DEF_H_
+
+#ifdef __cplusplus
+extern "C"{
+#endif
+
+#define CNC_VIDEO_REG_BASE (0xb1600000)
+#define CNC_VIDEO_REG_SIZE	(0x100000)
+#define CNC_INT_REG_BASE            (0xb1c10000)
+#define CNC_INT_REG_SIZE            (0x1000)
+/*mailbox*/
+#define VID_MIPS_MAILBOX(n)         (CNC_VIDEO_REG_BASE + ((n)<<2))
+
+
+/*  dma */
+#define REG_DMA_BASE                (0x20c000)
+#define REG_DMA_LEN                 (REG_DMA_BASE + (0x1 << 2))
+#define REG_DMA_CMD                 (REG_DMA_BASE + (0x2 << 2))
+#define REG_DMA_STATUS              (REG_DMA_BASE + (0x3 << 2))
+
+#define REG_DMA_BUFFER0             (0x20e000)
+#define REG_DMA_BUFFER1             (0x20f000)
+
+/*ARM write mailbox update flag masks*/
+#define BIT_UPDATE_FLAG                 ((unsigned int)(1<<31))
+
+/*ARM read mailbox update flag masks*/
+
+/*ARM write mailbox list*/
+#define MAILBOX_FW_ATTR_UPDATE_FLAG     (VID_MIPS_MAILBOX(0))
+#define MAILBOX_FIRMWARE_CONFIG_BADDR   (VID_MIPS_MAILBOX(1))
+#define MAILBOX_DEC_CPB_WPRP_BADDR      (VID_MIPS_MAILBOX(2)) //ES_RP/WP, PTS_RP/WP
+#define MAILBOX_ENC_CPB_WPRP_BADDR      (VID_MIPS_MAILBOX(3)) //ES_RP/WP, PTS_RP/WP
+#define MAILBOX_CODAFW_CONFIG_BADDR     (VID_MIPS_MAILBOX(4))
+#define MAILBOX_CMD_UPDATE_FLAG         (VID_MIPS_MAILBOX(5))//BIT[31] - Update Flag; BIT[0:30] - Update CMD Type
+#define MAILBOX_CMD_UPDATE_MSG          (VID_MIPS_MAILBOX(6))//BIT[24:31] - CH; BIT[0:23] - CMD
+#define MAILBOX_INT_MSG_UPDATE_FLAG     (VID_MIPS_MAILBOX(7))//BIT[31] - Update Flag; BIT[0:30] - Update MSG Type
+#define MAILBOX_DEBUG_CMD_UPDATE_FLAG   (VID_MIPS_MAILBOX(8))//BIT[31] - Update Flag; BIT[0:30] - Update CMD Type
+#define MAILBOX_DEBUG_CMD_UPDATE_MSG    (VID_MIPS_MAILBOX(9))//BIT[24:31] - CH; BIT[0:23] - CMD
+#define MAILBOX_CMD_DEBUG_PARAM1        (VID_MIPS_MAILBOX(10))
+#define MAILBOX_CMD_DEBUG_PARAM2        (VID_MIPS_MAILBOX(11))
+
+
+/*ARM read mailbox list*/
+#define MAILBOX_FIRMWARE_VERSION        (VID_MIPS_MAILBOX(17))
+#define MAILBOX_CODA_VERSION            (VID_MIPS_MAILBOX(18))
+#define MAILBOX_MIPS_DEBUG_FEEDBACK1    (VID_MIPS_MAILBOX(19))
+#define MAILBOX_MIPS_DEBUG_FEEDBACK2    (VID_MIPS_MAILBOX(20))
+#define MAILBOX_FW_LOG_BADDR            (VID_MIPS_MAILBOX(21))
+#define MAILBOX_FW_LOG_UPDATE_FLAG      (VID_MIPS_MAILBOX(22))
+#define MAILBOX_INT_TYPE                (VID_MIPS_MAILBOX(23))
+#define MAILBOX_VIDEO_PTS               (VID_MIPS_MAILBOX(24))
+
+#define MAILBOX_STATIC_BUF_ADDR   		(VID_MIPS_MAILBOX(32))
+#define MAILBOX_PIC_MEM_SIZE   			(VID_MIPS_MAILBOX(33))
+
+#define MAILBOX_MIPS_TIME               (VID_MIPS_MAILBOX(62))
+#define MAILBOX_MIPS_HEART_BEAT         (VID_MIPS_MAILBOX(63))
+
+/*misc*/
+//#define VID_CPBRP0                  (VIDEO_REG_ADDR_BASE + (0x40<<2) )
+//#define VID_CPBWP0                  (VIDEO_REG_ADDR_BASE + (0x41<<2) )
+//#define VID_HISTC                   (VIDEO_REG_ADDR_BASE + (0x42<<2) )
+//#define VID_STC0                    (VIDEO_REG_ADDR_BASE + (0x43<<2) )
+//#define VID_CPBRP1                  (VIDEO_REG_ADDR_BASE + (0x44<<2) )
+//#define VID_CPBWP1                  (VIDEO_REG_ADDR_BASE + (0x45<<2) )
+//#define VID_PTS_DIFF_TO_AUDIO       (VIDEO_REG_ADDR_BASE + (0x46<<2) )
+//#define VID_STC_DIFF_ADDR_AUDIO     (VIDEO_REG_ADDR_BASE + (0x47<<2) )
+//#define VID_WR_TO_AUDIO1            (VIDEO_REG_ADDR_BASE + (0x48<<2) )
+//#define VID_RD_FROM_AUDIO1          (VIDEO_REG_ADDR_BASE + (0x49<<2) )
+
+/*interrupt controller*/
+#define  INT_RISCCPU_EN                 (CNC_INT_REG_BASE+(0x00))
+#define  INT_RISCCPU_MASK               (CNC_INT_REG_BASE+(0x08))
+#define  INT_RISCCPU_FORCE              (CNC_INT_REG_BASE+(0x10))
+#define  INT_RISCCPU_FINALSTATUS        (CNC_INT_REG_BASE+(0x30))
+#define  INT_COPSW_EN                   (CNC_INT_REG_BASE+(0xc0))
+#define  INT_COPSW_MASK                 (CNC_INT_REG_BASE+(0xc4))
+#define  INT_COPSW_FORCE                (CNC_INT_REG_BASE+(0xc8))
+#define  INT_COPSW_FINALSTATUS          (CNC_INT_REG_BASE+(0xd4))
+
+#define  INT_COPSW_EN_OFFSET            (0xc0)
+#define  INT_COPSW_MASK_OFFSET          (0xc4)
+#define  INT_COPSW_FORCE_OFFSET         (0xc8)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
+
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/celestial/xport/Kconfig linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/xport/Kconfig
--- linux-linaro-3.4-2012.05-1_original/drivers/celestial/xport/Kconfig	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/xport/Kconfig	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,29 @@
+# drivers/celestial/xport/Kconfig
+
+menu "Celestial Xport Drivers"
+
+
+config CELESTIAL_XPORT
+	bool "Xport drive"
+	depends on ARCH_CELESTIAL
+	default n
+	help
+	Include support driver for Xport of celestial platform
+
+config CELESTIAL_XPORT_DEBUG
+	bool "Debugging"
+	depends on CELESTIAL_XPORT
+	help
+	This turns on low-level debugging for the celestial xport driver.
+	Normally, you should say 'N'.
+
+
+config XPORT_DEBUG_VERBOSE
+	int "Debugging verbosity (0 = quiet, 3 = noisy)"
+	depends on CELESTIAL_XPORT_DEBUG
+	default "0"
+	help
+	Determines the verbosity level of the xport debugging messages.
+
+
+endmenu
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/celestial/xport/Makefile linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/xport/Makefile
--- linux-linaro-3.4-2012.05-1_original/drivers/celestial/xport/Makefile	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/xport/Makefile	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,7 @@
+#
+# Makefile for the linux kernel
+
+ifdef CONFIG_CELESTIAL_XPORT
+obj-$(CONFIG_ARCH_CELESTIAL) +=xport_filter1900.o xport_mips1900.o
+obj-$(CONFIG_MACH_CELESTIAL_CNC1900) +=xport_dma1900.o xport_drv1900.o 
+endif
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/celestial/xport/xport_dma1900.c linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/xport/xport_dma1900.c
--- linux-linaro-3.4-2012.05-1_original/drivers/celestial/xport/xport_dma1900.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/xport/xport_dma1900.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,483 @@
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/miscdevice.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <linux/semaphore.h>
+
+#include <linux/sched.h>
+#include <linux/poll.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include "xport_drv1900.h"
+#include "xport_dma1900.h"
+#include "xport_regs1900.h"
+
+
+
+#define  ML_ALIGN(x)   	((x)<<24 | (x)>>24 | ((x)>>8 & 0xff00) | ((x)<<8 & 0xff0000))
+#define	 MAX_INPUT_CHL_NUM   4
+#define  DMA_ENB    1
+static 	XPORT_DMA xport_dma[2];
+static  XPORT_DIR dir_dma[XPORT_MAX_CHL_NUM];
+#define  GET_DMA_HADDR(v)  (0xFFFFFFF&v)
+
+
+
+typedef enum
+{
+	DMA0_INPUT = 0,
+	DMA1_INPUT = 1
+}DMA_INPUT_MODE;
+
+/*
+	actually ,the dir mode stand for the write pointer value should be got from
+	dma mail box.
+*/
+typedef enum
+{
+	DMA0_DIRC  = 0,
+	DMA1_DIRC = 1
+}DMA_DIR_MODE;
+
+
+void xport_dma_init(void)
+{
+	unsigned int i;
+	unsigned int tmp_buf_addr;
+	unsigned int tmp_list_addr;
+
+	xport_dma[0].dma_list[0].head_node = xport_mem_base + (DMA0_LIST0_HEAD_ADDR - XPORT_MEM_BASE);
+	xport_dma[0].dma_list[0].max_block_size = DMA0_MAX_BLOCK_SIZE;
+	xport_dma[0].dma_list[0].max_block_num = DMA0_MAX_BLOCK_NUM;
+	xport_dma[0].dma_list[0].cur_index = 0;
+	xport_dma[0].dma_list[0].next_index = 0;
+	xport_dma[0].dma_list[0].locked_flag = 0;
+
+	tmp_buf_addr = DMA0_BUF0_BASE_ADDR;
+	tmp_list_addr = DMA0_LIST0_HEAD_ADDR;
+
+	for (i = 0; i < DMA0_MAX_BLOCK_NUM; i++)
+	{
+		tmp_list_addr += sizeof(DMA_LIST_NODE);
+
+		xport_dma[0].dma_list[0].head_node[i].buf_addr = ML_ALIGN(tmp_buf_addr);
+		xport_dma[0].dma_list[0].head_node[i].data_size = 0;
+		xport_dma[0].dma_list[0].head_node[i].next_addr = (DMA_LIST_NODE *) (ML_ALIGN(tmp_list_addr));
+		xport_dma[0].dma_list[0].head_node[i].next_valid = 0;
+
+		tmp_buf_addr += DMA0_MAX_BLOCK_SIZE;
+	}
+
+	xport_dma[0].dma_list[1].head_node = xport_mem_base + (DMA0_LIST1_HEAD_ADDR - XPORT_MEM_BASE);
+	xport_dma[0].dma_list[1].max_block_size = DMA0_MAX_BLOCK_SIZE;
+	xport_dma[0].dma_list[1].max_block_num = DMA0_MAX_BLOCK_NUM;
+	xport_dma[0].dma_list[1].cur_index = 0;
+	xport_dma[0].dma_list[1].next_index = 0;
+	xport_dma[0].dma_list[1].locked_flag = 0;
+
+	tmp_buf_addr = DMA0_BUF1_BASE_ADDR;
+	tmp_list_addr = DMA0_LIST1_HEAD_ADDR;
+
+	for (i = 0; i < DMA0_MAX_BLOCK_NUM; i++) {
+		tmp_list_addr += sizeof(DMA_LIST_NODE);
+
+		xport_dma[0].dma_list[1].head_node[i].buf_addr = ML_ALIGN(tmp_buf_addr);
+		xport_dma[0].dma_list[1].head_node[i].data_size = 0;
+		xport_dma[0].dma_list[1].head_node[i].next_addr = (DMA_LIST_NODE *) (ML_ALIGN(tmp_list_addr));
+		xport_dma[0].dma_list[1].head_node[i].next_valid = 0;
+
+		tmp_buf_addr += DMA0_MAX_BLOCK_SIZE;
+	}
+
+	sema_init(&(xport_dma[0].dma_sem), 1);
+	sema_init(&(dir_dma[0].dir_sem), 1);
+	sema_init(&(dir_dma[1].dir_sem), 1);
+
+	xport_dma[0].cur_index = 0;
+	xport_dma[0].next_jiffies = 0;
+
+	return;
+}
+
+int xport_dma_set(unsigned int chl_id)
+{
+	int rt_val = -EFAULT;
+    unsigned int dma_id = 0;
+	unsigned int regs_val = 0;
+	DMA_LIST *dma_cur_list_ptr = NULL;
+	DMA_LIST *dma_done_list_ptr = NULL;
+
+	if (down_interruptible(&(xport_dma[dma_id].dma_sem)))
+		return rt_val;
+
+	dma_cur_list_ptr = &(xport_dma[dma_id].dma_list[xport_dma[dma_id].cur_index]);
+	dma_done_list_ptr = &(xport_dma[dma_id].dma_list[1 - xport_dma[dma_id].cur_index]);
+
+	regs_val = xport_readl((DMA_INPUT0_HEAD_ADDR + (dma_id << 2)));
+
+#if 0
+	{
+		int i = 0;
+		DMA_LIST_NODE *dma_list_node_ptr = NULL;
+
+		dma_list_node_ptr = xport_dma[dma_id].dma_list[xport_dma[dma_id].cur_index].head_node;
+		printk("dma_link: \n");
+		do
+		{
+			unsigned int buf = dma_list_node_ptr->buf_addr;
+			unsigned int next_buf = (unsigned int )(dma_list_node_ptr->next_addr);
+			unsigned int offset = 0;
+
+			buf = ML_ALIGN(buf);
+			printk("\tnode %d: addr 0x%08x size 0x%08x next_addr 0x%08x next_valid 0x%08x\n", i, buf,
+				dma_list_node_ptr->data_size,
+				ML_ALIGN(next_buf),
+				dma_list_node_ptr->next_valid);
+
+			buf -= XPORT_MEM_BASE;
+			buf += xport_mem_base;
+
+			i++;
+
+			while(offset < ML_ALIGN(dma_list_node_ptr->data_size))
+			{
+				if (((unsigned char *)buf)[offset+2] == 0xeb)
+				{
+					printk("data: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n",
+						((unsigned char *)buf)[offset+0], ((unsigned char *)buf)[offset+1], ((unsigned char *)buf)[offset+2], ((unsigned char *)buf)[offset+3],
+						((unsigned char *)buf)[offset+4], ((unsigned char *)buf)[offset+5], ((unsigned char *)buf)[offset+6], ((unsigned char *)buf)[offset+7]);
+
+				}
+				offset += 0xbc;
+			}
+
+		}while ((dma_list_node_ptr++)->next_valid);
+	}
+#endif
+	if(regs_val == 0 && dma_cur_list_ptr->next_index > 0)
+	{
+		dma_cur_list_ptr->head_node[dma_cur_list_ptr->cur_index].next_valid = 0;
+
+        if (chl_id == 0)
+            xport_writel(XPORT_INT_CLS_ADDR0, XPORT_IRQ0_DMA0_EMPTY_MSK);
+        else if (chl_id == 1)
+            xport_writel(XPORT_INT_CLS_ADDR0, XPORT_IRQ0_DMA1_EMPTY_MSK);
+
+		if (xport_dma[dma_id].cur_index == 0)
+		{
+			xport_writel(DMA_INPUT0_HEAD_ADDR, (DMA0_LIST0_HEAD_ADDR|0x80000000));
+		}
+		else
+		{
+			xport_writel(DMA_INPUT0_HEAD_ADDR, (DMA0_LIST1_HEAD_ADDR|0x80000000));
+		}
+
+		/* software bitrate control ,no need now.cur_delay_clk27 = ((dma_cur_list_ptr->block_size_sum * (CLK27_MHZ << 3)) / MAX_DMA_MBPS);
+
+		if (dma_id)
+			xport_writel(MAIL_BOX_ADDR(7), cur_delay_clk27);
+		else
+			xport_writel(MAIL_BOX_ADDR(6), cur_delay_clk27);
+
+		 end of SW bitrate control */
+
+		dma_done_list_ptr->cur_index = 0;
+		dma_done_list_ptr->next_index = 0;
+		dma_done_list_ptr->block_size_sum = 0;
+
+		xport_dma[dma_id].cur_index = 1 - xport_dma[dma_id].cur_index;
+
+		rt_val = 0;
+	}
+
+	up(&(xport_dma[dma_id].dma_sem));
+
+	return rt_val;
+}
+
+/* xunli: for direct dma mode */
+int xport_dma_direct_write(const char __user * buffer, size_t len,unsigned int chl_id, ssize_t packet_size)
+{
+	ssize_t rt_val = -EFAULT;
+
+	void __iomem *write_addr;
+	void __iomem *base_addr;
+
+	unsigned int tmp_addr = 0;
+	unsigned int chl_buf_unit_num = 0, chl_buf_unit_size = 0, chl_buf_type = 0;
+	unsigned int free_block_num = 0, chl_buf_wp = 0, chl_buf_rp = 0;
+	unsigned int regs_val = 0;
+	unsigned int write_len = 0;
+
+	if(down_interruptible(&(dir_dma[chl_id].dir_sem)))
+		return -EFAULT;
+
+	regs_val = xport_readl(IN_CHL_CFG_ADDR(chl_id));
+	chl_buf_type = ((regs_val >> 29) & 0x3);
+	chl_buf_unit_num = (regs_val >> 8) & 0xfff;
+	chl_buf_unit_size = (regs_val & 0xff) << 3;
+
+	tmp_addr = xport_readl(IN_CHL_BASE_ADDR(chl_id)) << 3;
+	if(chl_buf_type!=3 || (tmp_addr!=IN_CHL0_BASE_ADDR_DEF && tmp_addr!=IN_CHL1_BASE_ADDR_DEF))
+	{
+		up(&(dir_dma[chl_id].dir_sem));
+		return -EFAULT;
+	}
+
+	tmp_addr -= XPORT_MEM_BASE;
+	base_addr = xport_mem_base + tmp_addr;
+
+	chl_buf_wp = xport_readl(chl_id%2?(chl_id==3?XPORT_CHL_DMA3_WP_ADDR: XPORT_CHL_DMA1_WP_ADDR):
+		(chl_id==2?XPORT_CHL_DMA2_WP_ADDR: XPORT_CHL_DMA0_WP_ADDR));
+
+	chl_buf_rp = xport_readl(IN_CHL_RP_ADDR(chl_id));
+
+	if ((chl_buf_wp ^ chl_buf_rp) >> 31)
+		free_block_num = (chl_buf_rp & 0xfff) - (chl_buf_wp & 0xfff);
+	else
+		free_block_num = chl_buf_unit_num + (chl_buf_rp & 0xfff) - (chl_buf_wp & 0xfff);
+
+	rt_val = 0;
+
+	while (((int) len >= packet_size) && ((int) free_block_num > 0) && (free_block_num <= chl_buf_unit_num)) {
+
+		write_addr = base_addr + ((chl_buf_wp & 0xfff) * chl_buf_unit_size);
+		write_len = 0;
+
+		while ((len >= packet_size) && (write_len + packet_size + 8 <= chl_buf_unit_size))
+		{
+			//printk("func:%s line:%d len:0x%08x write_len:0x%08x--\n",
+				//__FUNCTION__,__LINE__,len,write_len);
+			write_len += packet_size;
+			len -= packet_size;
+		}
+
+		if (write_len == 0)
+		{
+			up(&(dir_dma[chl_id].dir_sem));
+			return -EFAULT;
+		}
+
+		writel(0, write_addr);
+		write_addr += 4;
+		writel(ML_ALIGN(write_len), write_addr);
+		write_addr += 4;
+
+		copy_from_user(write_addr, buffer, write_len);
+
+		buffer += write_len;
+		rt_val += write_len;
+
+		/* update wp pointer */
+		chl_buf_wp++;
+
+		if ((chl_buf_wp & 0xfff) >= chl_buf_unit_num)
+		{chl_buf_wp = (~chl_buf_wp) & 0x80000000;}
+
+		free_block_num--;
+	}
+
+	xport_writel((chl_id%2?(chl_id==3?XPORT_CHL_DMA3_WP_ADDR: XPORT_CHL_DMA1_WP_ADDR):
+		(chl_id==2?XPORT_CHL_DMA2_WP_ADDR: XPORT_CHL_DMA0_WP_ADDR)), chl_buf_wp);
+	up(&(dir_dma[chl_id].dir_sem));
+
+	//printk("---func:%s line:%d rt_val:0x%08x  \n",__FUNCTION__,__LINE__,rt_val);
+
+	return rt_val;
+}
+
+int xport_dma_write(const char __user * buffer, size_t len, unsigned int chl_id, ssize_t packet_size)
+{
+	ssize_t rt_val = -EFAULT;
+
+	void __iomem *write_addr;
+	DMA_LIST *dma_list_ptr = NULL;
+
+	unsigned int tmp_addr = 0;
+	unsigned int regs_val = 0;
+	unsigned int hw_set_req = 0;
+    unsigned int dma_id = 0;
+	char *ptr = NULL;
+
+    packet_size = packet_size;      // unused variable packet_size;
+
+START_LAB:
+	hw_set_req = 0;
+
+	if(down_interruptible(&(xport_dma[dma_id].dma_sem)))
+		return -EFAULT;
+	dma_list_ptr = &(xport_dma[dma_id].dma_list[xport_dma[dma_id].cur_index]);
+
+	if(len > dma_list_ptr->max_block_size)
+	{
+		up(&(xport_dma[dma_id].dma_sem));
+		return -EFAULT;
+	}
+
+    //printk("xport_dma_write : chl id is %d, dma id is %d\n", chl_id, dma_id);
+
+	if (dma_list_ptr->next_index < dma_list_ptr->max_block_num)
+	{
+		tmp_addr = ML_ALIGN(dma_list_ptr->head_node[dma_list_ptr->next_index].buf_addr);
+		tmp_addr -= XPORT_MEM_BASE;
+		write_addr = xport_mem_base + tmp_addr;
+
+		copy_from_user(write_addr, buffer, len);
+
+		ptr = write_addr;
+
+		//printk(" --func:%s	line:%d --\n",__FUNCTION__,__LINE__);
+
+		dma_list_ptr->head_node[dma_list_ptr->next_index].data_size = ML_ALIGN(len);
+		dma_list_ptr->head_node[dma_list_ptr->next_index].next_valid = 0;
+
+
+		if (dma_list_ptr->next_index != 0) {
+			dma_list_ptr->head_node[dma_list_ptr->cur_index].next_valid = 0x01000000;	//
+			dma_list_ptr->cur_index++;
+		}
+
+		dma_list_ptr->next_index++;
+		dma_list_ptr->block_size_sum += len;
+
+		rt_val = len;
+
+	}
+	else
+	{
+		rt_val = 0;
+		regs_val = xport_readl((DMA_INPUT0_HEAD_ADDR + (dma_id << 2)));
+		if (regs_val == 0)
+			hw_set_req = 1;
+	}
+
+	up(&(xport_dma[dma_id].dma_sem));
+
+	if (hw_set_req) {
+		xport_dma_set(chl_id);
+		goto START_LAB;
+	}
+
+	return rt_val;
+}
+
+int xport_dma_reset(unsigned int dma_id)
+{
+
+	if(down_interruptible(&(xport_dma[dma_id].dma_sem)))
+		return -EFAULT;
+
+	xport_dma[dma_id].cur_index = 0;
+	xport_dma[dma_id].next_jiffies = 0;
+	xport_dma[dma_id].dma_list[0].cur_index = 0;
+	xport_dma[dma_id].dma_list[0].next_index = 0;
+	xport_dma[dma_id].dma_list[0].locked_flag = 0;
+	xport_dma[dma_id].dma_list[1].cur_index = 0;
+	xport_dma[dma_id].dma_list[1].next_index = 0;
+	xport_dma[dma_id].dma_list[1].locked_flag = 0;
+
+	up(&(xport_dma[dma_id].dma_sem));
+
+	return 0;
+}
+
+int xport_dma_input_check(unsigned int dma_id)
+{
+	int rt_val = -EFAULT;
+	DMA_LIST *dma_list_ptr = NULL;
+
+	if (down_interruptible(&(xport_dma[dma_id].dma_sem)))
+		return rt_val;
+
+	dma_list_ptr = &(xport_dma[dma_id].dma_list[xport_dma[dma_id].cur_index]);
+	if (dma_list_ptr->next_index < dma_list_ptr->max_block_num) {
+		rt_val = 0;
+	}
+
+	up(&(xport_dma[dma_id].dma_sem));
+
+	return rt_val;
+}
+
+int xport_dma_half_empty_check(unsigned int dma_id,unsigned int chl_id)
+{
+	int rt_val = -EFAULT;
+
+	unsigned int chl_wp, chl_rp, chl_wp_addr, chl_rp_addr;
+	unsigned int space_cnt = 0;
+	unsigned int tmp = 0;
+	unsigned int val = 0;
+	struct semaphore * sp = NULL ;
+
+	val = xport_readl(XPORT_CFG_ADDR0);
+	tmp = xport_readl(IN_CHL_CFG_ADDR(chl_id));
+
+	sp = (((tmp>>29)&0x3) ==3 ? (&dir_dma[chl_id].dir_sem) : (&xport_dma[dma_id].dma_sem));
+
+	if(down_interruptible(sp))
+	{return -EFAULT;}
+
+
+	tmp = xport_readl(IN_CHL_CFG_ADDR(chl_id));
+	chl_rp_addr = IN_CHL_RP_ADDR(chl_id);
+	chl_wp_addr = IN_CHL_WP_ADDR(chl_id);
+
+
+	if(0x3 == ((tmp>>29)&0x3))
+	{
+		chl_wp_addr = XPORT_CHL_DMA_WP_ADDR(chl_id);
+	}
+
+	if(DMA_ENB==xport_get_bit(val,(chl_id*8)) && dma_id == xport_get_bit(val,(1+chl_id*8)))
+	{
+
+		chl_wp = xport_readl(chl_wp_addr);
+		chl_rp = xport_readl(chl_rp_addr);
+
+
+		if ((chl_wp ^ chl_rp) >> 31)
+			{space_cnt = (chl_rp&0xfff)-(chl_wp&0xfff);}
+		else
+			{space_cnt = IN_CHL_UNIT_NUM_DEF(chl_id)+(chl_rp&0xfff)-(chl_wp&0xfff);}
+		if (space_cnt > IN_CHL_UNIT_NUM_DEF(chl_id)>>1)
+			rt_val = 0;
+	}
+	else
+	{return -EFAULT;}
+
+
+	up(sp);
+
+	return rt_val;
+}
+
+
+int xport_dma_enable(unsigned int dma_id)
+{
+	unsigned int reg = 0;
+
+
+	if(down_interruptible(&(xport_dma[dma_id].dma_sem)))
+		return -EFAULT;
+
+	reg = xport_readl(dma_id ?DMA_INPUT1_HEAD_ADDR: DMA_INPUT0_HEAD_ADDR);
+	//printk("dma_input_head%d reg value:[%04x]  line:%d \n",dma_id,reg,__LINE__);
+
+
+	xport_writel((dma_id ?DMA_INPUT1_HEAD_ADDR: DMA_INPUT0_HEAD_ADDR),xport_set_bit(reg,31));
+	up(&(xport_dma[dma_id].dma_sem));
+	//printk(" set dma[%d] succ! line:%d \n",dma_id,__LINE__);
+
+	return 1;
+
+}
+
+
+
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/celestial/xport/xport_dma1900.h linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/xport/xport_dma1900.h
--- linux-linaro-3.4-2012.05-1_original/drivers/celestial/xport/xport_dma1900.h	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/xport/xport_dma1900.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,35 @@
+#ifndef __XPORT_DMA1900_H__
+#define __XPORT_DMA1900_H__
+
+#include "xport_regs1900.h"
+#include "xport_drv1900.h"
+
+
+#define CLK27_MHZ                       27	/* 27MHZ */
+#define MAX_DMA_MBPS                    20	/* 20MB/s */
+
+#define XPORT_CHL0_MIN_SPACES           (IN_CHL0_UNIT_NUM_DEF >> 1)
+#define XPORT_CHL1_MIN_SPACES           (IN_CHL1_UNIT_NUM_DEF >> 1)
+
+#define XPORT_IRQ0_DMA0_MSK             0x00000001
+#define XPORT_IRQ0_DMA1_MSK             0x00000002
+
+#define XPORT_IRQ0_DMA0_EMPTY_MSK       0x00000010
+#define XPORT_IRQ0_DMA1_EMPTY_MSK       0x00000020
+#define XPORT_IRQ0_DMA2_EMPTY_MSK       0x00000040
+#define XPORT_IRQ0_DMA3_EMPTY_MSK       0x00000080
+
+void xport_dma_init(void);
+int xport_dma_set(unsigned int chl_id);
+int xport_dma_write(const char __user * buffer, size_t len, unsigned int chl_id, ssize_t packet_size);
+int xport_dma_direct_write(const char __user * buffer, size_t len,unsigned int chl_id, ssize_t packet_size);
+int xport_dma_input_check(unsigned int dma_id);
+int xport_dma_reset(unsigned int dma_id);
+int xport_dma_half_empty_check(unsigned int dma_id,unsigned int chl_id);
+int xport_dma_enable(unsigned int dma_id);
+
+
+#endif
+
+
+
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/celestial/xport/xport_drv1900.c linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/xport/xport_drv1900.c
--- linux-linaro-3.4-2012.05-1_original/drivers/celestial/xport/xport_drv1900.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/xport/xport_drv1900.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,1942 @@
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+//#include <linux/devfs_fs_kernel.h>
+#include <linux/miscdevice.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <linux/semaphore.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/sched.h>
+#include <linux/poll.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/proc_fs.h>
+#include <linux/device.h>
+#include <linux/firmware.h>
+#include <linux/platform_device.h>
+#include <linux/signal.h>
+
+#include <mach/hardware.h>
+#include <mach/pinmux.h>
+#include "xport_drv1900.h"
+#include "xport_dma1900.h"
+#include "xport_mips1900.h"
+#include "xport_filter1900.h"
+
+#include "mach/cnc1900_power_clk.h"
+
+#define MAX_FW_DATA_SIZE 2048*4
+#define MAX_FW_TEXT_SIZE  3072*4
+#define  TS_SIZE      	188
+
+
+#define SLEEP_TIMEOUT 2  /* sec*/
+
+void __iomem *xport_regs_base;
+void __iomem *xport_mem_base;
+
+#define DEBUG_ON()
+
+
+static struct class *cnc180x_xport_class;
+static struct platform_device *xport_pdev;
+
+static unsigned int irq0_dev_id = XPORT_IRQ0_ID;
+static unsigned int irq1_dev_id = XPORT_IRQ1_ID;
+
+static unsigned int crc_err_idx = 0x0000ffff;
+static unsigned int last_crc_error_idx = -1;
+
+
+static DECLARE_WAIT_QUEUE_HEAD(crc_wait_queue);
+static DECLARE_WAIT_QUEUE_HEAD(irq0_wait_queue);
+static DECLARE_WAIT_QUEUE_HEAD(irq1_wait_queue);
+static DECLARE_WAIT_QUEUE_HEAD(irq0_dma0_wait_queue);
+static DECLARE_WAIT_QUEUE_HEAD(irq0_dma1_wait_queue);
+static DECLARE_WAIT_QUEUE_HEAD(irq0_dma2_wait_queue);
+static DECLARE_WAIT_QUEUE_HEAD(irq0_dma3_wait_queue);
+
+static wait_queue_head_t filter_wait_queue[MAX_FILTER_NUM];
+
+extern int pinmux_enable_tsout(int enable);
+
+void xport_writeb(int a,int v)
+{
+	writeb(v, xport_regs_base + __OFFSET_ADDR__(a)); udelay(5);
+}
+
+
+void xport_writew(int a,int v)
+{
+	writew(v, xport_regs_base + __OFFSET_ADDR__(a)); udelay(5);
+}
+
+void xport_writel(int a,int v)
+{
+	writel(v, xport_regs_base + __OFFSET_ADDR__(a)); udelay(5);
+}
+
+unsigned char xport_readb(int a)
+{
+	return readb( xport_regs_base    + __OFFSET_ADDR__(a) );
+}
+
+unsigned short xport_readw(int a)
+{
+	return readw( xport_regs_base    + __OFFSET_ADDR__(a) );
+}
+
+/*read data from mem mapped from usr space's device to kernel*/
+unsigned int xport_readl(int a)
+{
+	return readl( xport_regs_base    + __OFFSET_ADDR__(a) );
+}
+
+
+EXPORT_SYMBOL(xport_readb);
+EXPORT_SYMBOL(xport_readw);
+EXPORT_SYMBOL(xport_readl);
+EXPORT_SYMBOL(xport_writeb);
+EXPORT_SYMBOL(xport_writew);
+EXPORT_SYMBOL(xport_writel);
+
+
+static int xport_load_firmware(void)
+{
+	int ret,i;
+	const struct firmware *xport_data_fw=NULL;
+	const struct firmware *xport_text_fw=NULL;
+	unsigned int wr_data;
+
+	printk("loading xport firmware\n ");
+
+	ret = request_firmware(&xport_data_fw, "xport_fw_data.bin", &(xport_pdev->dev));
+	if (ret != 0 || xport_data_fw == NULL ) {
+		printk(KERN_ERR "Failed to load xport firmware data section\n");
+		return -1;
+	}
+	if (xport_data_fw->size > MAX_FW_DATA_SIZE){
+		printk(KERN_ERR "Firmware data senction is too larage!\n");
+		return -1;
+	}
+	printk("readed xport fw data section size =%d\n", xport_data_fw->size);
+
+	ret = request_firmware(&xport_text_fw, "xport_fw_text.bin", &(xport_pdev->dev));
+	if (ret != 0 || xport_text_fw == NULL) {
+		printk(KERN_ERR "Failed to load xport firmware code section\n");
+		return -1;
+	}
+	if (xport_text_fw->size > MAX_FW_TEXT_SIZE){
+		printk(KERN_ERR "Firmware text senction is too larage!\n");
+		return -1;
+	}
+	printk("readed xport fw text section size =%d\n", xport_text_fw->size);
+
+	xport_writel(MIPS_FW_EN, 1);
+	for (i = 0; i < xport_data_fw->size; i+=4) {
+		wr_data = (xport_data_fw->data)[i+3]<<24 | (xport_data_fw->data)[i+2]<<16 | (xport_data_fw->data)[i+1]<<8 | (xport_data_fw->data)[i];
+		xport_writel(MIPS_FW_WRITE_DATA+i, wr_data);
+	}
+	for (; i < MAX_FW_DATA_SIZE; i+=4) {
+		xport_writel(MIPS_FW_WRITE_DATA +i, 0);
+	}
+
+
+	for (i = 0; i < xport_text_fw->size; i+=4) {
+		wr_data = (xport_text_fw->data)[i+3]<<24 | (xport_text_fw->data)[i+2]<<16 | (xport_text_fw->data)[i+1]<<8 | (xport_text_fw->data)[i];
+		xport_writel(MIPS_FW_WRITE_INST+i, wr_data);
+	}
+
+	xport_writel(MIPS_FW_EN, 0);
+
+	printk("xport firmware loaded.\n");
+
+	if (xport_data_fw != NULL )
+		release_firmware(xport_data_fw);
+	if (xport_text_fw != NULL )
+		release_firmware(xport_text_fw);
+
+	return 0;
+}
+
+#if 0 // majia add these macro in mem_define.h
+/**get buf from mips for xport psi component region**/
+#define AUDIO_CAB_REGION	AUDIO_STUFF_REGION
+#if (BASE_DDR_ADDR==0x8000000)
+#define AUDIO_CAB_SIZE	(0x18000*1)
+#define AUDIO_PTS_SIZE	(0x3000*1)
+#else
+#define AUDIO_CAB_SIZE	(0x18000*4)
+#define AUDIO_PTS_SIZE	(0x3000*4)
+#endif
+#define AUDIO_PTS_REGION	(AUDIO_CAB_REGION + AUDIO_CAB_SIZE)
+#endif
+
+static int xport_config_buf(void)
+{
+	xport_mips_write(MIPS_CHL_BUF_LOW_ADDR(0), VIDEO_CPB_REGION);
+	xport_mips_write(MIPS_CHL_BUF_UP_ADDR(0), VIDEO_CPB_REGION + VIDEO_CPB_SIZE/VIDEO_NUM);
+	xport_mips_write(MIPS_CHL_DIR_LOW_ADDR(0), VIDEO_CPB_DIR_REGION);
+	xport_mips_write(MIPS_CHL_DIR_UP_ADDR(0), VIDEO_CPB_DIR_REGION + VIDEO_CPB_DIR_SIZE/VIDEO_NUM);
+
+	xport_mips_write(MIPS_CHL_BUF_LOW_ADDR(1), VIDEO_CPB_REGION + VIDEO_CPB_SIZE/VIDEO_NUM);
+	xport_mips_write(MIPS_CHL_BUF_UP_ADDR(1), VIDEO_CPB_REGION + (VIDEO_CPB_SIZE/VIDEO_NUM)*2);
+	xport_mips_write(MIPS_CHL_DIR_LOW_ADDR(1), VIDEO_CPB_DIR_REGION + VIDEO_CPB_DIR_SIZE/VIDEO_NUM);
+	xport_mips_write(MIPS_CHL_DIR_UP_ADDR(1), VIDEO_CPB_DIR_REGION + (VIDEO_CPB_DIR_SIZE/VIDEO_NUM)*2);
+
+	xport_mips_write(MIPS_CHL_DIR_LOW_ADDR(XPORT_AV_CHNL_NUM), AUDIO_CAB_REGION);
+	xport_mips_write(MIPS_CHL_DIR_UP_ADDR(XPORT_AV_CHNL_NUM), AUDIO_CAB_REGION + (AUDIO_CAB_SIZE/AUDIO_NUM));
+
+	xport_mips_write(MIPS_CHL_BUF_LOW_ADDR(XPORT_AV_CHNL_NUM), AUDIO_PTS_REGION);
+	xport_mips_write(MIPS_CHL_BUF_UP_ADDR(XPORT_AV_CHNL_NUM), AUDIO_PTS_REGION + (AUDIO_PTS_SIZE/AUDIO_NUM));
+
+	/* set external base address */
+	printk("write to mips external base addr = 0x%08x\n", MIPS_EXTERNAL_BASE_ADDR);
+	xport_mips_write(MIPS_CHL_EXTERNAL_BASE(0), MIPS_EXTERNAL_BASE_ADDR);
+
+
+	return 0;
+}
+
+
+/**initialize xport input channel register status**/
+static int xport_hw_init(void)
+{
+	xport_writel(IN_CHL0_BASE_ADDR, (XPORT_CHL0_BASE_ADDR_DEF >> 3));
+	xport_writel(IN_CHL0_CFG_ADDR, IN_CHL0_CFG_DEF);
+	xport_writel(IN_CHL0_CFG_ADDR, IN_CHL0_CFG_DEF);
+
+	xport_writel(IN_CHL1_BASE_ADDR, (IN_CHL1_BASE_ADDR_DEF >> 3));
+	xport_writel(IN_CHL1_CFG_ADDR, IN_CHL1_CFG_DEF);
+	xport_writel(IN_CHL1_CFG_ADDR, IN_CHL1_CFG_DEF);
+
+	xport_writel(XPORT_CFG_ADDR1,
+			XPORT_CFG1_OUT_CHL0_LINE_SYNC |
+			XPORT_CFG1_OUT_CHL1_LINE_SYNC |
+			XPORT_CFG1_OUT_CHL2_LINE_SYNC |
+			XPORT_CFG1_OUT_CHL3_LINE_SYNC);
+
+	xport_writel(CLK0_PWM_CTRL_ADDR, 0x2);      // for high
+
+	return 0;
+}
+
+
+/**initialize and activate irq0 signal of xport module**/
+irqreturn_t xport_irq0(int irq, void *dev_id, struct pt_regs * egs)
+{
+	unsigned int irq_reg0;
+	unsigned int idx;
+	unsigned int i;
+
+	irq_reg0 = xport_readl(XPORT_INT_REG_ADDR0);
+	xport_writel(XPORT_INT_CLS_ADDR0, irq_reg0);
+
+	idx = xport_readl(XPORT_INT_EXT_ADDR);
+	xport_writel(XPORT_INT_EXT_ADDR, xport_readl(XPORT_INT_EXT_ADDR) ^ idx);
+
+	if (irq_reg0 & XPORT_IRQ0_DMA0_EMPTY_MSK)
+	{
+		wake_up_interruptible(&irq0_dma0_wait_queue);
+	}
+
+	if (irq_reg0 & XPORT_IRQ0_DMA1_EMPTY_MSK)
+	{
+		wake_up_interruptible(&irq0_dma1_wait_queue);
+	}
+
+	if (irq_reg0 & XPORT_IRQ0_DMA2_EMPTY_MSK)
+	{
+		wake_up_interruptible(&irq0_dma2_wait_queue);
+	}
+
+	if (irq_reg0 & XPORT_IRQ0_DMA3_EMPTY_MSK)
+	{
+		wake_up_interruptible(&irq0_dma3_wait_queue);
+	}
+
+	if (irq_reg0 & XPORT_IRQ0_CRC_NOTIFY)
+	{
+		crc_err_idx = (irq_reg0 & XPORT_IRQ0_CRC_INDEX)>>XPORT_IRQ0_CRC_IDX_SHIFT;
+		wake_up_interruptible(&crc_wait_queue);
+	}
+
+	if(irq_reg0 & XPORT_IRQ0_FILTER_NOTIFY)
+	{
+		for(i = 32; i < MAX_FILTER_NUM; i++)
+		{
+			if(idx & 0x1)
+			{
+				wake_up_interruptible(&filter_wait_queue[i]);
+			}
+			idx >>= 1;
+		}
+	}
+
+	wake_up_interruptible(&irq0_wait_queue);
+	return IRQ_HANDLED;
+}
+
+
+/**initialize and activate irq1 signal of xport module**/
+irqreturn_t xport_irq1(int irq, void *dev_id, struct pt_regs * egs)
+{
+	unsigned int i;
+	unsigned int irq_reg1;
+
+	irq_reg1 = xport_readl(XPORT_INT_REG_ADDR1);
+	xport_writel(XPORT_INT_CLS_ADDR1, irq_reg1);
+
+	for (i = 0; i < 32; i++)
+	{
+		if (irq_reg1 & 1)
+		{
+			wake_up_interruptible(&filter_wait_queue[i]);
+		}
+		irq_reg1 >>= 1;
+	}
+
+	wake_up_interruptible(&irq1_wait_queue);
+
+	return IRQ_HANDLED;
+}
+
+/***initialize xport device object***/
+static int xport_open(struct inode *inode, struct file *file)
+{
+	unsigned int filter_index;
+	XPORT_DEV *xport_dev = NULL;
+	unsigned int chl_id = 0;
+	unsigned int dma_id;
+
+	xport_dev = kmalloc(sizeof(XPORT_DEV), GFP_KERNEL);
+
+	if(xport_dev == NULL)
+	{
+		//printk("func:%s  line:%d chl_id:%d \n",__FUNCTION__,__LINE__,chl_id);
+		return -EBUSY;
+	}
+	xport_dev->dev_minor = iminor(inode);
+
+	chl_id = (int)(xport_dev->dev_minor-XPORT_MINOR_CHL(0));
+	dma_id = 0;
+
+	//printk("chl_id:%d,dma_id:%d \n",chl_id,dma_id);
+
+	if(chl_id>=0 && chl_id <XPORT_MAX_CHL_NUM)
+	{
+		//printk("func:%s  line:%d chl_id:%d \n",__FUNCTION__,__LINE__,chl_id);
+		//xport_dev->irq_wait_queue_ptr = (dma_id?(&irq0_dma1_wait_queue):(&irq0_dma0_wait_queue));
+		xport_dev->irq_wait_queue_ptr = chl_id==0?&irq0_dma0_wait_queue:&irq0_dma1_wait_queue;
+
+		xport_dev->stream_type = XPORT_INPUT_TS_TYPE;
+		xport_dev->packet_size = TS_SIZE;
+		xport_dma_reset(dma_id);
+		xport_writel((dma_id?DMA_INPUT1_HEAD_ADDR: DMA_INPUT0_HEAD_ADDR),0);
+		//xport_writel(IN_CHL_RP_ADDR(chl_id),xport_readl(IN_CHL_WP_ADDR(chl_id)));
+		/* reset chl wp & rp here, 2011-05-03 by xp */
+		xport_writel(IN_CHL_RP_ADDR(chl_id), 0x40000000);
+		xport_writel(IN_CHL_WP_ADDR(chl_id), 0);
+		xport_writel(XPORT_CHL_DMA_WP_ADDR(chl_id),0);
+
+		memset(xport_mem_base+ (IN_CHL_BASE_DEF(chl_id)-XPORT_MEM_BASE),
+				0,IN_CHL_UNIT_SIZE_DEF(chl_id)*IN_CHL_UNIT_NUM_DEF(chl_id));
+	}
+	else if ((xport_dev->dev_minor >= XPORT_MINOR_FT_BASE)
+			&& (xport_dev->dev_minor < (XPORT_MINOR_FT_BASE + MAX_FILTER_NUM)))
+	{
+		filter_index = xport_dev->dev_minor - XPORT_MINOR_FT_BASE;
+		xport_dev->filter_type = FILTER_TYPE_NUKOWN;
+		xport_dev->irq_wait_queue_ptr = &filter_wait_queue[filter_index];
+		xport_filter_reset(filter_index);
+	}
+	else
+		xport_dev->irq_wait_queue_ptr = NULL;
+
+	spin_lock_init(&(xport_dev->spin_lock));
+	sema_init(&(xport_dev->xport_sem), 1);
+	file->private_data = (void *) xport_dev;
+
+	return 0;
+}
+
+static int xport_release(struct inode *inode, struct file *file)
+{
+	XPORT_DEV *xport_dev = file->private_data;
+	unsigned int mnr =	xport_dev->dev_minor;
+	unsigned int regs_val = 0;
+	unsigned int tmp_val = 0;
+	unsigned int mask_val = 0;
+	unsigned int filter_index;
+
+	if(xport_dev->dev_minor >= XPORT_MINOR_CHL(0) &&
+			xport_dev->dev_minor < XPORT_MINOR_CHL(XPORT_MAX_CHL_NUM))
+	{
+		// disable xport input channel
+		tmp_val = xport_readl(IN_CHL_CFG_ADDR(xport_dev->dev_minor-XPORT_MINOR_CHL(0)));
+		tmp_val &= ~0x80000000;
+		xport_writel(IN_CHL_CFG_ADDR(xport_dev->dev_minor-XPORT_MINOR_CHL(0)),tmp_val);
+
+		// disable tuner input channel
+		mask_val = 0x1 << (mnr - XPORT_MINOR_CHL(0));
+		tmp_val = xport_readl(XPORT_TUNER_EN);
+		tmp_val &= ~mask_val;
+		xport_writel(XPORT_TUNER_EN, tmp_val);
+
+		// disable DMA
+		mask_val = 0x3 << (8 * (mnr - XPORT_MINOR_CHL(0)));
+		tmp_val = xport_readl(XPORT_CFG_ADDR0);
+		tmp_val &= ~mask_val;
+		xport_writel(XPORT_CFG_ADDR0, tmp_val);
+
+		// clear channel buffer
+		regs_val = (xport_dev->dev_minor-XPORT_MINOR_CHL(0)) ;
+		xport_writel(IN_CHL_RP_ADDR(regs_val), 0x40000000);
+		xport_writel(XPORT_CHL_DMA_WP_ADDR(regs_val),0);
+		memset(xport_mem_base+(IN_CHL_BASE_DEF(regs_val)-XPORT_MEM_BASE),0,
+				IN_CHL_UNIT_SIZE_DEF(regs_val)*IN_CHL_UNIT_NUM_DEF(regs_val));
+		printk("xport channel %d has been released. \n", regs_val);
+	}
+	else if ((xport_dev->dev_minor >= XPORT_MINOR_FT_BASE)
+			&& (xport_dev->dev_minor < (XPORT_MINOR_FT_BASE + MAX_FILTER_NUM)))
+	{
+		filter_index = xport_dev->dev_minor - XPORT_MINOR_FT_BASE;
+		xport_filter_reset(filter_index);
+		printk("xport filter %d has been released. \n", filter_index);
+	}
+
+	// free structure
+	kfree(file->private_data);
+	return 0;
+}
+
+
+static ssize_t xport_read(struct file *file, char __user * buffer, size_t len, loff_t * offset)
+{
+	unsigned int addr;
+	unsigned int filter_index;
+	ssize_t ret = -EFAULT;
+
+	XPORT_DEV *xport_dev = file->private_data;
+
+	if (likely((xport_dev->dev_minor >= XPORT_MINOR_FT_BASE)
+				&& (xport_dev->dev_minor < (XPORT_MINOR_FT_BASE + MAX_FILTER_NUM)))) {
+
+		if (unlikely(xport_dev->filter_type == FILTER_TYPE_NUKOWN)) {
+			return -EFAULT;
+		}
+
+		filter_index = xport_dev->dev_minor - XPORT_MINOR_FT_BASE;
+
+		if (down_interruptible(&xport_dev->xport_sem)) {
+			return -ERESTARTSYS;
+		}
+
+		if(xport_dev->filter_type == FILTER_TYPE_SECTION) {
+
+			ret = xport_filter_check_section_number(filter_index);
+			//printk("---func:%s line:%d--ret:[%d]---\n",__FUNCTION__,__LINE__,ret);
+
+			if (ret > 0) {
+				ret = xport_filter_read_section_data(filter_index, buffer, len);
+			}
+		}
+		else if (xport_dev->filter_type == FILTER_TYPE_PES) {
+			ret = xport_filter_check_pes_size(filter_index);
+			if (ret > 0) {
+				ret = xport_filter_read_pes_data(filter_index, buffer, len);
+			}
+		}
+		else {
+			ret = xport_filter_check_data_size(filter_index);
+			if (ret >0) {
+				ret = xport_filter_read_data(filter_index, buffer, len);
+
+			} else{
+				ret = 0;
+			}
+		}
+		up(&xport_dev->xport_sem);
+
+		return ret;
+	}
+	else if (unlikely(xport_dev->dev_minor == XPORT_MINOR)) { //?
+		/* It should be deleted branch*/
+		void __iomem *read_addr;
+
+		if (down_interruptible(&xport_dev->xport_sem)) {
+			return -ERESTARTSYS;
+		}
+
+		copy_from_user(&addr, buffer, 4);	/* FIXME@debug used interface, can dump all date of xport buffer. It can be deleted */
+
+		read_addr = xport_mem_base + (addr - XPORT_MEM_BASE);
+		if (copy_to_user(buffer, read_addr, len)) {
+			up(&xport_dev->xport_sem);
+			return -EFAULT;
+		}
+
+		up(&xport_dev->xport_sem);
+
+		return len;
+	}
+	return -EFAULT;
+}
+typedef  ssize_t(*WRITE_FN)(const char __user *buffer,size_t len,unsigned int chl_id, ssize_t packet_size);
+
+static ssize_t xport_write(struct file *file, const char __user * buffer, size_t len, loff_t * offset)
+{
+	WRITE_FN fn;
+	unsigned int chl_id = 0;
+	unsigned int chl_type = 0;
+	unsigned int dma_id = 0;
+
+	ssize_t ret = -EFAULT;
+	XPORT_DEV *xport_dev = file->private_data;
+	ssize_t packet_size = xport_dev->packet_size;
+
+	DECLARE_WAITQUEUE(wait, current);
+
+	if(xport_dev->dev_minor >= XPORT_MINOR_CHL(0)
+			&& xport_dev->dev_minor < XPORT_MINOR_CHL(XPORT_MAX_CHL_NUM) )
+	{
+		chl_id = xport_dev->dev_minor - XPORT_MINOR_CHL(0);
+	}
+	else
+	{
+		//		printk("--func:%s line:%d dma_id:%d --	\n",__FUNCTION__,__LINE__,dma_id);
+		return -EFAULT;
+	}
+
+	if (len < packet_size || ((len % packet_size) != 0))
+	{
+		printk(KERN_ERR"error 2 happend len = %d  packet_size = %d\n", len, packet_size);
+		return -EFAULT;
+	}
+
+	/*xunli: for direct dma mode */
+	chl_type = xport_readl(IN_CHL_CFG_ADDR(xport_dev->dev_minor - XPORT_MINOR_CHL(0)));
+	chl_type = (chl_type >> 29) & 0x3;
+
+	if(chl_type == 3)
+	{
+		fn = (WRITE_FN)xport_dma_direct_write;
+	}
+	else
+	{
+		if (xport_dev->stream_type != XPORT_INPUT_TS_TYPE)
+		{
+			printk(KERN_ERR"error 3 happend\n");
+			return -EFAULT; // only support TS format in dma or tuner mode
+		}
+		fn = (WRITE_FN)xport_dma_write;
+	}
+
+	add_wait_queue(xport_dev->irq_wait_queue_ptr, &wait);
+
+	while (1) {
+
+		set_current_state(TASK_INTERRUPTIBLE);
+		//		printk("--func:%s line:%d ret:%d dma_id:%d --  \n",__FUNCTION__,__LINE__,ret,dma_id);
+
+		ret = xport_dma_half_empty_check(dma_id, chl_id);
+
+		if (ret == -EFAULT)
+		{
+			//			printk("--func:%s line:%d ret:%d dma_id:%d --  \n",__FUNCTION__,__LINE__,ret,dma_id);
+			ret = 0;
+		}
+		else
+		{
+
+			ret = ( chl_type!=3 ? fn(buffer, len, chl_id, packet_size):
+					fn(buffer, len, xport_dev->dev_minor-XPORT_MINOR_CHL(0), packet_size) );
+		}
+
+
+		if (ret == -EFAULT || ret == len)
+			break;
+
+		else if (file->f_flags & O_NONBLOCK)
+			break;
+
+		else if (ret > 0 && ret < len) {
+			buffer += ret;
+			len -= ret;
+		}
+
+		if (signal_pending(current))
+		{
+			ret = -EFAULT;
+			break;
+		}
+
+		schedule();
+	}
+	set_current_state(TASK_RUNNING);
+	remove_wait_queue(xport_dev->irq_wait_queue_ptr, &wait);
+
+	return ret;
+}
+
+
+static inline int uncached_access(struct file *file, unsigned long addr)
+{
+	/*
+	 * Accessing memory above the top the kernel knows about or through a file pointer
+	 * that was marked O_SYNC will be done non-cached.
+	 */
+	if (file->f_flags & O_SYNC)
+		return 1;
+	return addr >= __pa(high_memory);
+}
+
+static int xport_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+#if defined(__HAVE_PHYS_MEM_ACCESS_PROT)
+	unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
+
+	vma->vm_page_prot = phys_mem_access_prot(filp, offset,
+			vma->vm_end - vma->vm_start,
+			vma->vm_page_prot);
+#elif defined(pgprot_noncached)
+	unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
+	int uncached;
+
+	uncached = uncached_access(filp, offset);
+	if (uncached)
+		vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+#endif
+
+	/* Remap-pfn-range will mark the range VM_IO and VM_RESERVED */
+	if (remap_pfn_range(vma,
+				vma->vm_start,
+				vma->vm_pgoff,
+				vma->vm_end-vma->vm_start,
+				vma->vm_page_prot))
+		return -EAGAIN;
+
+	return 0;
+}
+
+
+static unsigned int xport_poll(struct file *file, poll_table * wait)
+{
+
+
+	unsigned int filter_index;
+	XPORT_DEV *xport_dev = file->private_data;
+
+	poll_wait(file, xport_dev->irq_wait_queue_ptr, wait);
+	poll_wait(file, &crc_wait_queue, wait);
+
+	if(xport_dev->dev_minor == XPORT_MINOR_CHL(0))
+	{
+		if (xport_dma_input_check(0))
+			return POLLOUT | POLLWRNORM;
+	}
+	else if(xport_dev->dev_minor == XPORT_MINOR_CHL(1))
+	{
+		if (xport_dma_input_check(1))
+			return POLLOUT | POLLWRNORM;
+	}
+
+	else if ((xport_dev->dev_minor >= XPORT_MINOR_FT_BASE)
+			&& (xport_dev->dev_minor < (XPORT_MINOR_FT_BASE + MAX_FILTER_NUM))) {
+		filter_index = xport_dev->dev_minor - XPORT_MINOR_FT_BASE;
+
+		if (xport_dev->filter_type == FILTER_TYPE_NUKOWN)
+			return 0;
+
+		else if (xport_dev->filter_type == FILTER_TYPE_SECTION) {
+			if (0x0000ffff != crc_err_idx)
+			{
+				last_crc_error_idx = crc_err_idx;
+				crc_err_idx = 0x0000ffff;
+
+				return POLLPRI;
+			}
+
+			if (xport_filter_check_section_number(filter_index) > 0)
+				return POLLIN | POLLRDNORM;
+		}
+
+		else if (xport_dev->filter_type == FILTER_TYPE_PES) {
+			if (xport_filter_check_pes_size(filter_index) > 0)
+				return POLLIN | POLLRDNORM;
+		}
+
+		else {
+			if (xport_filter_check_data_size(filter_index) > 0)
+				return POLLIN | POLLRDNORM;
+		}
+	}
+
+	return 0;
+}
+
+
+typedef struct __ioctl_params__
+{
+	unsigned int pid_idx;
+	unsigned int pid_en;
+	unsigned int pid_val;
+	unsigned int pid_chl;
+	unsigned int des_idx;
+	unsigned int des_en;
+	unsigned int des_len;
+	unsigned int des_key[6];
+
+	unsigned int avout_idx;
+	unsigned int avout_en;
+	unsigned int avout_pid;
+	unsigned int avout_mode;
+	unsigned int vid_low_latency;
+	unsigned int avout_chl_switch;
+
+	unsigned int filter_idx;
+	unsigned int filter_en;
+	unsigned int filter_crc_idx;
+	unsigned int filter_crc_en;
+	unsigned int filter_crc_save;
+	unsigned int filter_crc_notify_en;
+
+	unsigned int pcr_idx;
+	unsigned int pcr_en;
+	unsigned int pcr_pid;
+	unsigned int pcr_hi_val;
+	unsigned int pcr_lo_val;
+} xport_ioctl_params;
+
+typedef enum
+{
+    DEMUX_TSOUT_DISABLE = 0,
+    DEMUX_TSOUT_ENABLE
+}CSDEMUX_TSOUT_ENA;
+
+typedef enum
+{
+    DEMUX_TSOUT_PARALLEL = 0,
+    DEMUX_TSOUT_SERIAL
+}CSDEMUX_TSOUT_MODE;
+
+typedef enum
+{
+    DEMUX_TSOUT_CLK_INV_DISABLE = 0,
+    DEMUX_TSOUT_CLK_INV_ENABLE
+}CSDEMUX_TSOUT_INVERSE_CLK;
+
+typedef enum
+{
+    CSDEMUX_TSOUT_CLOCK_54M = 4,
+    CSDEMUX_TSOUT_CLOCK_27M = 8,
+    CSDEMUX_TSOUT_CLOCK_13_5M = 16,
+    CSDEMUX_TSOUT_CLOCK_6_75M = 32,
+    CSDEMUX_TSOUT_CLOCK_3_375M = 64
+}CSDEMUX_TSOUT_CLOCK_DIV;
+
+typedef enum
+{
+    DEMUX_TSOUT_DMA0 = 0,
+    DEMUX_TSOUT_DMA1
+}CSDEMUX_TSOUT_DMA_SOURCE;
+
+typedef struct
+{
+    CSDEMUX_TSOUT_ENA ena : 1;
+    CSDEMUX_TSOUT_MODE mode : 1;
+    CSDEMUX_TSOUT_INVERSE_CLK inv_clk : 1;
+    CSDEMUX_TSOUT_CLOCK_DIV clk_div : 7;
+    CSDEMUX_TSOUT_DMA_SOURCE dma_src : 1;
+    unsigned int tsout_gap : 8;
+    unsigned int reserve : 13;
+}CSDEMUX_TSOUT_PARAM;
+
+/*here may integrate single set filter action into one seriel action?*/
+static long xport_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+	int addr = 0;
+	unsigned int regs_val = 0;
+	unsigned int tmp_val = 0;
+	unsigned int mask_val = 0;
+	unsigned int filter_index = 0;
+	unsigned int filter_data =0;
+	unsigned char filter_mask[24];
+	XPORT_DEV *xport_dev = file->private_data;
+	unsigned int mnr =	xport_dev->dev_minor;
+	xport_ioctl_params ioc_params = {0};
+
+	/*filter operation*/
+	if(mnr>=XPORT_MINOR_FT_BASE && mnr<(XPORT_MINOR_FT_BASE+MAX_FILTER_NUM))
+	{
+		filter_index = xport_dev->dev_minor - XPORT_MINOR_FT_BASE;
+
+		switch (cmd) {
+			case XPORT_FILTER_IOC_PID0:
+				__get_user(regs_val, (int __user *) arg);
+				xport_filter_set_pidx(filter_index, regs_val, 0);
+				break;
+
+			case XPORT_FILTER_IOC_PID1:
+				__get_user(regs_val, (int __user *) arg);
+				xport_filter_set_pidx(filter_index, regs_val, 1);
+				break;
+
+			case XPORT_FILTER_IOC_PID2:
+				__get_user(regs_val, (int __user *) arg);
+				xport_filter_set_pidx(filter_index, regs_val, 2);
+				break;
+
+			case XPORT_FILTER_IOC_PID3:
+				__get_user(regs_val, (int __user *) arg);
+				xport_filter_set_pidx(filter_index, regs_val, 3);
+				break;
+
+			case XPORT_FILTER_IOC_PID4:
+				__get_user(regs_val, (int __user *) arg);
+				xport_filter_set_pidx(filter_index, regs_val, 4);
+				break;
+
+			case XPORT_FILTER_IOC_PID5:
+				__get_user(regs_val, (int __user *) arg);
+				xport_filter_set_pidx(filter_index, regs_val, 5);
+				break;
+
+			case XPORT_FILTER_IOC_PID6:
+				__get_user(regs_val, (int __user *) arg);
+				xport_filter_set_pidx(filter_index, regs_val, 6);
+				break;
+
+			case XPORT_FILTER_IOC_PID7:
+				__get_user(regs_val, (int __user *) arg);
+				xport_filter_set_pidx(filter_index, regs_val, 7);
+				break;
+
+			case XPORT_FILTER_IOC_PID8:
+				__get_user(regs_val, (int __user *) arg);
+				xport_filter_set_pidx(filter_index, regs_val, 8);
+				break;
+
+			case XPORT_FILTER_IOC_PID9:
+				__get_user(regs_val, (int __user *) arg);
+				xport_filter_set_pidx(filter_index, regs_val, 9);
+				break;
+
+			case XPORT_FILTER_IOC_PID10:
+				__get_user(regs_val, (int __user *) arg);
+				xport_filter_set_pidx(filter_index, regs_val, 10);
+				break;
+
+			case XPORT_FILTER_IOC_PID11:
+				__get_user(regs_val, (int __user *) arg);
+				xport_filter_set_pidx(filter_index, regs_val, 11);
+				break;
+
+			case XPORT_FILTER_IOC_FILTER:
+				copy_from_user(filter_mask, (int __user *) arg, 24);
+				xport_filter_set_filter(filter_index, filter_mask, filter_mask + 12);
+				break;
+
+			case XPORT_FILTER_IOC_TYPE:
+				__get_user(regs_val, (int __user *) arg);
+				if (regs_val == FILTER_TYPE_SECTION || regs_val == FILTER_TYPE_TS || regs_val == FILTER_TYPE_PES
+						|| regs_val == FILTER_TYPE_ES)
+				{
+					//printk(" FILTER_TYPE:[%d]  line:%d  \n",regs_val,__LINE__);
+					if (xport_filter_set_type(filter_index, regs_val) == 0)
+						xport_dev->filter_type = regs_val;
+				}
+				break;
+
+			case XPORT_FILTER_IOC_ENABLE:
+				__get_user(regs_val, (int __user *) arg);
+				if (xport_dev->filter_type == FILTER_TYPE_SECTION
+						|| xport_dev->filter_type == FILTER_TYPE_TS
+						|| xport_dev->filter_type == FILTER_TYPE_PES || xport_dev->filter_type == FILTER_TYPE_ES) {
+					if (regs_val)
+						xport_filter_enable(filter_index, &(xport_dev->spin_lock));
+					else
+					{
+						xport_filter_disable(filter_index, &(xport_dev->spin_lock));
+					}
+
+					xport_filter_clear_buffer(filter_index);
+				}
+				break;
+
+			case XPORT_FILTER_IOC_QUERY_NUM:
+				if (xport_dev->filter_type == FILTER_TYPE_SECTION) {
+					regs_val = xport_filter_check_section_number(filter_index);
+				}
+				else if (xport_dev->filter_type == FILTER_TYPE_PES) {
+					regs_val = xport_filter_check_pes_size(filter_index);
+				}
+				else if (xport_dev->filter_type == FILTER_TYPE_TS || xport_dev->filter_type == FILTER_TYPE_ES) {
+					regs_val = xport_filter_check_data_size(filter_index);
+				}
+				else
+					regs_val = 0;
+
+				__put_user(regs_val, (int __user *) arg);
+
+				break;
+
+			case XPORT_FILTER_IOC_QUERY_SIZE:
+				if (xport_dev->filter_type == FILTER_TYPE_SECTION)
+					regs_val = xport_filter_check_section_size(filter_index);
+				else
+					regs_val = 0;
+
+				__put_user(regs_val, (int __user *) arg);
+
+				break;
+
+			case XPORT_FILTER_IOC_CRC_ENABLE:
+				copy_from_user(&ioc_params, (void*)arg, sizeof(xport_ioctl_params));
+
+				tmp_val  = ioc_params.filter_crc_en << 7;
+				tmp_val |= ioc_params.filter_crc_save << 6;
+				tmp_val |= ioc_params.filter_crc_idx;
+				/* the section filter index ~(0,127) but former*/
+				xport_mips_write(MIPS_CHL_CRC_EN((filter_index+16)), tmp_val);
+				break;
+
+			case XPORT_FILTER_IOC_CRC_NTF_ENB:
+				copy_from_user(&ioc_params, (void*)arg, sizeof(xport_ioctl_params));
+				tmp_val  = ioc_params.filter_crc_notify_en << 31;
+				xport_mips_write(MIPS_CHL_CRC_NOTIFY_EN((filter_index+16)), tmp_val);
+				break;
+
+			case XPORT_FILTER_IOC_SAVE_ENABLE:
+				copy_from_user(&ioc_params, (void*)arg, sizeof(xport_ioctl_params));
+				xport_mips_read(MIPS_CHL_CRC_EN((filter_index+16)), &tmp_val);
+				tmp_val |= ioc_params.filter_crc_save << 6;
+				xport_mips_write(MIPS_CHL_CRC_EN((filter_index+16)), tmp_val); /* the same reason, see the above */
+				break;
+
+			case XPORT_FILTER_IOC_SWITCH:
+				xport_mips_write(MIPS_CHL_SWITCH((filter_index + 16)), (int)arg);
+				break;
+
+				/*get filter buffer end addr*/
+			case XPORT_FILTER_IOC_BUFFER_UPADDR:
+				if ((void *)arg != NULL){
+					filter_data=get_filter_buf_top_addr(filter_index);
+					copy_to_user((void __user *)arg, &filter_data, sizeof(unsigned int));
+				}
+				else
+					return -EINVAL;
+				break;
+
+				/*get filter buffer start addr*/
+			case XPORT_FILTER_IOC_BUFFER_LOWADDR:
+				if ((void *)arg != NULL){
+					filter_data=get_filter_buf_base_addr(filter_index);
+					copy_to_user((void __user *)arg, &filter_data, sizeof(unsigned int));
+				}
+				else
+					return -EINVAL;
+				break;
+
+			case XPORT_FILTER_IOC_BUFFER_RP_ADDR:
+				if ((void *)arg != NULL){
+					filter_data=get_xport_filter_rp(filter_index);
+					copy_to_user((void __user *)arg, &filter_data, sizeof(unsigned int));
+				}
+				else
+					return -EINVAL;
+				break;
+
+			case XPORT_FILTER_IOC_BUFFER_WP_ADDR:
+				if ((void *)arg != NULL){
+					filter_data=get_xport_filter_wp(filter_index);
+					copy_to_user((void __user *)arg, &filter_data, sizeof(unsigned int));
+				}
+				else
+					return -EINVAL;
+				break;
+
+			case XPORT_DMA_IOC_ENABLE:
+				if((void *)arg != NULL)
+				{
+					//__get_user(regs_val, (int __user *) arg);
+					regs_val = xport_dma_enable(0);
+					regs_val = xport_readl(DMA_INPUT0_HEAD_ADDR);
+					//printk("dma addr regs_val:[%04x]  line:%d  \n",regs_val,__LINE__);
+					copy_to_user((void __user *)arg,&regs_val,sizeof(unsigned int));
+				}
+				break;
+
+			case XPORT_FLT_IOC_CLEAR:
+				/*get sec filter number */
+				xport_filter_clear_buffer(filter_index);
+				memset((char *)get_filter_buf_base_addr(filter_index),0,FLT_BUF_SIZE(filter_index));
+				break;
+		}
+
+		return 0;
+	}
+
+	/*send or get cmd*/
+	else if (__IS_HW_ADDR__(cmd))
+	{
+		if (__WR_FLAGS__(cmd))
+		{
+			regs_val = arg;
+			xport_writel(cmd, regs_val);
+		}
+		else {/*kernel to usr space*/
+			regs_val = xport_readl(cmd);
+			__put_user(regs_val, (int __user *) arg);
+		}
+
+		return 0;
+	}
+	else if (__IS_MIPS_ADDR__(cmd))
+	{
+		if (__WR_FLAGS__(cmd))
+		{
+			regs_val = arg;
+			if (xport_mips_write(__OFFSET_ADDR__(cmd), regs_val))
+				return -EINVAL;
+		}
+		else {
+			if (xport_mips_read(__OFFSET_ADDR__(cmd), &regs_val))
+				return -EINVAL;
+			__put_user(regs_val, (int __user *) arg);\
+		}
+
+		return 0;
+	}
+
+	else {
+		int i = 0;
+        CSDEMUX_TSOUT_PARAM tsout_param;
+
+		switch (cmd)
+		{
+            case XPORT_IOC_ENABLE_TSOUT:
+                copy_from_user(&tsout_param, (void*)arg, sizeof(tsout_param));
+                if (tsout_param.ena)
+                {
+                    pinmux_enable_tsout(1);
+
+                    tmp_val = xport_readl(XPORT_CFG_ADDR1);
+                    if (tsout_param.mode)
+                    {
+                        tmp_val |= (1<<19);
+                    } else {
+                        tmp_val &= ~(1<<19);
+                    }
+                    if (tsout_param.inv_clk)
+                    {
+                        tmp_val |= (1<<18);
+                    } else {
+                        tmp_val &= ~(1<<18);
+                    }
+                    if (tsout_param.dma_src)
+                    {
+                        tmp_val |= (1<<10);
+                    } else {
+                        tmp_val &= ~(1<<10);
+                    }
+                    tmp_val &= ~(0x7f << 11);
+                    if (tsout_param.clk_div)
+                        tmp_val |= (tsout_param.clk_div << 11);
+                    else    // use 3.75MHz as default
+                        tmp_val |= (0x40 << 11);
+                    xport_writel(XPORT_CFG_ADDR1, tmp_val);
+
+                    tmp_val = xport_readl(XPORT_TSOUT_GAP);
+                    tmp_val &= ~(0xff);
+                    if (tsout_param.tsout_gap)
+                    {
+                        tmp_val |= tsout_param.tsout_gap;
+                    }
+                    xport_writel(XPORT_TSOUT_GAP, tmp_val);
+
+                    tmp_val = xport_readl(XPORT_TUNER_EN);
+                    tmp_val |= (1<<4);
+                    xport_writel(XPORT_TUNER_EN, tmp_val);
+                } else {
+                    pinmux_enable_tsout(0);
+
+                    tmp_val = xport_readl(XPORT_TUNER_EN);
+                    tmp_val &= ~(1<<4);
+                    xport_writel(XPORT_TUNER_EN, tmp_val);
+
+                    tmp_val = xport_readl(XPORT_CFG_ADDR1);
+                    tmp_val &= ~(0x3ff << 10);
+                    xport_writel(XPORT_CFG_ADDR1, tmp_val);
+                }
+                break;
+			case XPORT_PIDFT_IOC_ENABLE:
+				/*get usr cmd from mips by*/
+				copy_from_user(&ioc_params, (void*)arg, sizeof(xport_ioctl_params));
+				tmp_val = xport_readl(__PID_FILTER__(ioc_params.pid_idx));
+				tmp_val = ioc_params.pid_en!=0 ? xport_set_bit(tmp_val,31): xport_cls_bit(tmp_val,31);
+				addr =  ioc_params.pid_idx< 64 ?PID_GRP0_FLTR(ioc_params.pid_idx):
+					PID_GRP1_FLTR(ioc_params.pid_idx);
+				xport_writel(addr, tmp_val);
+				break;
+
+
+			case XPORT_PIDFT_IOC_CHANNEL:
+				/*operation to channel by write regs*/
+				copy_from_user(&ioc_params, (void*)arg, sizeof(xport_ioctl_params));
+				tmp_val = xport_readl(__PID_FILTER__(ioc_params.pid_idx));
+				tmp_val = ioc_params.pid_chl%2 ? xport_set_bit(tmp_val,30): xport_cls_bit(tmp_val,30);
+				addr =  ioc_params.pid_idx<64?PID_GRP0_FLTR(ioc_params.pid_idx):
+					PID_GRP1_FLTR(ioc_params.pid_idx);
+				xport_writel(addr, tmp_val);
+				break;
+
+
+			case XPORT_PIDFT_IOC_PIDVAL:
+				copy_from_user(&ioc_params, (void*)arg, sizeof(xport_ioctl_params));
+				//printk("get ioctl pid val:[%04x] function:%s line:%d \n",
+				//ioc_params.pid_idx,__FUNCTION__,__LINE__);
+
+				tmp_val = xport_readl(__PID_FILTER__(ioc_params.pid_idx));
+				tmp_val &= ~0x1fff;
+				tmp_val |= ioc_params.pid_val;
+				addr =  ioc_params.pid_idx<64?PID_GRP0_FLTR(ioc_params.pid_idx):
+					PID_GRP1_FLTR(ioc_params.pid_idx);
+				xport_writel(addr, tmp_val);
+
+				break;
+
+
+			case XPORT_PIDFT_IOC_DESC_ODDKEY:
+
+				copy_from_user(&ioc_params, (void*)arg, sizeof(xport_ioctl_params));
+				for (i = 0; i < ioc_params.des_len; i++)
+
+				{xport_writel(__DSCRB_ODD_ADDR_(i,ioc_params.des_idx),
+						ioc_params.des_key[i]);}
+
+				break;
+
+			case XPORT_PIDFT_IOC_DESC_EVENKEY:
+
+				copy_from_user(&ioc_params, (void*)arg, sizeof(xport_ioctl_params));
+				for (i = 0; i < ioc_params.des_len; i++)
+					xport_writel(__DSCRB_EVN_ADDR_(i,ioc_params.des_idx),
+							ioc_params.des_key[i]);
+
+				break;
+
+			case XPORT_PIDFT_IOC_DESC_ENABLE:
+				copy_from_user(&ioc_params, (void*)arg, sizeof(xport_ioctl_params));
+
+				/* write bit26~29 of PID_FILTERx. */
+				/* bit29: enable / disable DES */
+				/* bit26~28: DES id */
+				// regs_val = i;
+				// regs_val |= 0x80000000; /* bit31 indicates enabling flags, 1 - enable, 0 = disable. */
+				// regs_val |= (pidft_ptr->pid_filter_id << 30);
+
+				addr =  ioc_params.pid_idx<=63?PID_GRP0_FLTR(ioc_params.pid_idx):
+					PID_GRP1_FLTR(ioc_params.pid_idx);
+				tmp_val = xport_readl(addr);
+				tmp_val &= ~0x3c000000;
+
+				if (ioc_params.des_en) {
+					tmp_val |= 0x20000000;
+					tmp_val |= (ioc_params.des_idx << 26);
+				}
+				xport_writel(addr, tmp_val);
+				break;
+
+
+			case XPORT_CHL_IOC_CLEAR:
+
+				regs_val = (xport_dev->dev_minor-XPORT_MINOR_CHL(0)) ;
+				xport_writel(IN_CHL_RP_ADDR(regs_val), 0x40000000);
+				xport_writel(XPORT_CHL_DMA_WP_ADDR(regs_val),0);
+				memset(xport_mem_base+(IN_CHL_BASE_DEF(regs_val)-XPORT_MEM_BASE),0,
+						IN_CHL_UNIT_SIZE_DEF(regs_val)*IN_CHL_UNIT_NUM_DEF(regs_val));
+				break;
+
+
+				/*enable channel for tuner*/
+			case XPORT_CHL_IOC_ENABLE:
+
+				regs_val = (unsigned int) arg;
+				//printk("func:%s line:%d \n",__FUNCTION__,__LINE__);
+
+				if(xport_dev->dev_minor >= XPORT_MINOR_CHL(0) &&
+						xport_dev->dev_minor < XPORT_MINOR_CHL(XPORT_MAX_CHL_NUM))
+				{
+					tmp_val = xport_readl(IN_CHL_CFG_ADDR(xport_dev->dev_minor-XPORT_MINOR_CHL(0)));
+				}
+				else
+				{
+					//printk("func:%s line:%d wrong input device ! minor:[0x%08x] --\n",
+					//__FUNCTION__,__LINE__,xport_dev->dev_minor);
+					break;
+				}
+
+				tmp_val = (regs_val?(tmp_val|0x80000000):(tmp_val&~0x80000000));
+				xport_writel(IN_CHL_CFG_ADDR(xport_dev->dev_minor-XPORT_MINOR_CHL(0)),tmp_val);
+
+				mask_val = 0x1 << (mnr - XPORT_MINOR_CHL(0));
+				tmp_val = xport_readl(XPORT_TUNER_EN);
+				tmp_val = regs_val>0 ? tmp_val|mask_val : tmp_val&~mask_val;
+				xport_writel(XPORT_TUNER_EN, tmp_val);
+
+				break;
+
+			case XPORT_CHL_IOC_DES_MODE:
+				regs_val = (unsigned int) arg;
+				tmp_val = xport_readl(XPORT_CFG_ADDR0);
+				/*set io to alter to descriptor mode*/
+				mnr = (mnr==XPORT_MINOR_CHL(0)?0:1);
+				tmp_val = regs_val==0 ? tmp_val&mnr : tmp_val|mnr ;
+				mnr = 0;
+				xport_writel(XPORT_CFG_ADDR0, tmp_val);//?
+
+				break;
+
+			case XPORT_CHL_IOC_SERIAL_MODE:
+				// 0 for MSB, 1 for LSB
+				regs_val = (unsigned int) arg;
+				tmp_val = xport_readl(XPORT_CFG_ADDR0);
+				mnr = (mnr - XPORT_MINOR_CHL(0));
+				tmp_val = (regs_val==0 ? tmp_val&~(8<<mnr*8) : tmp_val|(8<<mnr*8));
+				mnr = 0;
+				xport_writel(XPORT_CFG_ADDR0, tmp_val);
+
+				break;
+
+
+			case XPORT_CHL_IOC_TUNER_MODE:
+
+				regs_val = (unsigned int) arg;
+				if (regs_val == 1)  // serial mode
+				{
+					pinmux_set_xportmode(_xport_serial_mode);
+				}
+				else if (regs_val == 0)
+				{
+					pinmux_set_xportmode(_xport_paralell_mode);
+				}
+
+				tmp_val = xport_readl(XPORT_CFG_ADDR0);
+				mnr = (mnr-XPORT_MINOR_CHL(0));
+				//0 for Par.1 for Ser.
+				tmp_val = (regs_val==0 ? tmp_val&~(4<<mnr*8) : tmp_val|(4<<mnr*8)) ;
+				tmp_val = (regs_val==0 ? tmp_val : tmp_val|(0x10<<mnr*8)) ;
+				mnr = 0;
+				xport_writel(XPORT_CFG_ADDR0, tmp_val);
+
+				break;
+
+			case XPORT_CHL_IOC_INPUT_MODE:
+
+				regs_val = (unsigned int) arg;
+				tmp_val = xport_readl(XPORT_CFG_ADDR0);
+				mask_val = (mnr-XPORT_MINOR_CHL(0))==0 ? 0x1 : 0x100;
+
+				tmp_val = regs_val? tmp_val|mask_val: tmp_val&~mask_val ;
+				xport_writel(XPORT_CFG_ADDR0, tmp_val);
+				tmp_val = xport_readl(IN_CHL_CFG_ADDR(xport_dev->dev_minor-XPORT_MINOR_CHL(0)));
+				tmp_val|= 0x80000000;
+
+				switch (regs_val) {
+					case 0:	/* TUNER */
+						break;
+
+					case 1:	/* DMA */
+						tmp_val &= ~0x20000000;
+						tmp_val |= 0x40000000;
+						break;
+
+					case 2:	/* DIR DMA */
+						tmp_val |= 0x60000000;
+						break;
+
+					default:
+						break;
+				}
+
+				xport_writel(IN_CHL_CFG_ADDR(mnr-XPORT_MINOR_CHL(0)),tmp_val);
+				/*
+				 * enable interrupt, according the following flow:
+				 * INT0_ENB_ADDR | 0x11, for DEMUX_INPUT_MOD_TUNER.
+				 * INT0_ENB_ADDR | 0x11, for DMA_MOD / CHL0.
+				 * INT0_ENB_ADDR | 0x22, for DMA_MOD / CHL1.
+				 */
+				tmp_val = xport_readl(XPORT_INT_ENB_ADDR0);
+
+				switch (regs_val)
+				{
+					case 0:	/* tuner */
+						if(mnr == XPORT_MINOR_CHL(0))
+						{tmp_val &= ~(XPORT_IRQ0_DMA0_EMPTY_MSK);}
+						/* WARNING: this parameters are undocumented, pls don't change it. */
+						if(mnr == XPORT_MINOR_CHL(1))
+							tmp_val &= ~(XPORT_IRQ0_DMA1_EMPTY_MSK);
+						/* WARNING: this parameters are undocumented, pls don't change it. */
+						break;
+
+					case 1:	/* DMA */
+					case 2:	/* direct */
+						if(mnr == XPORT_MINOR_CHL(0)) 		//?
+							tmp_val |= (XPORT_IRQ0_DMA0_EMPTY_MSK);
+						if(mnr == XPORT_MINOR_CHL(1))
+							tmp_val |= (XPORT_IRQ0_DMA1_EMPTY_MSK);
+						break;
+				}
+				xport_writel(XPORT_INT_ENB_ADDR0, tmp_val);
+				break;
+
+
+			case XPORT_CHL_IOC_RESET:
+				break;
+
+			case XPORT_CHL_IOC_DMA_RESET:
+
+				xport_dma_reset(arg);//?
+
+				break;
+
+			case XPORT_CHL_IOC_INPUT_TYPE:
+				__get_user(regs_val, (int __user *) arg);
+				xport_dev->stream_type = regs_val;
+				printk(KERN_INFO"stream type = %d\n", regs_val);
+				switch(regs_val)
+				{
+					case XPORT_INPUT_M2TS_TYPE:
+						xport_dev->packet_size = TS_SIZE + 4;
+						break;
+					case XPORT_INPUT_TS_TYPE:
+						xport_dev->packet_size = TS_SIZE;
+						break;
+					case XPORT_INPUT_TS204_TYPE:
+						xport_dev->packet_size = TS_SIZE + 16;
+						break;
+					default:
+						printk(KERN_ERR"unsupported input stream (only m2ts, ts, ts204 supported\n");
+						return -EFAULT;
+				}
+				printk(KERN_INFO"set input type for demux, packet size = %d\n", xport_dev->packet_size);
+				if ((xport_dev->dev_minor<XPORT_MINOR_CHL(0)) ||
+						(xport_dev->dev_minor>=XPORT_MINOR_CHL(XPORT_MAX_CHL_NUM)))
+				{
+					printk(KERN_ERR"invalid xport channel handler\n");
+					return -EFAULT;
+				}
+				tmp_val = xport_dev->dev_minor - XPORT_MINOR_CHL(0);
+				if (xport_mips_write(MIPS_INCHL_TYPE | (tmp_val << 8), regs_val) < 0)
+				{
+					printk(KERN_ERR"xport mips write XPORT_CHL_IOC_INPUT_TYPE failed\n");
+					return -EFAULT;
+				}
+				break;
+			case XPORT_VID_IOC_OUTPUT_MODE:
+				break;
+
+			case XPORT_VID_IOC_RESET:
+				break;
+
+			case XPORT_VID_IOC_ENABLE:
+				copy_from_user(&ioc_params, (void*)arg, sizeof(xport_ioctl_params));
+
+				if (ioc_params.avout_en)
+				{
+					tmp_val = 0x80000000; /* enable flags */
+					tmp_val |= ioc_params.avout_mode << 7; /* output mode, bit7 */
+					tmp_val |= ioc_params.vid_low_latency << 3; /* low latency, bit3 */
+					tmp_val |= 0x00000002; /* output type, ES */
+
+					xport_mips_write(MIPS_CHL_EN(ioc_params.avout_idx), tmp_val);
+				}
+				else
+					xport_mips_write(MIPS_CHL_DISABLE(ioc_params.avout_idx), 0);
+
+				break;
+
+			case XPORT_VID_IOC_PIDVAL:
+				copy_from_user(&ioc_params, (void*)arg, sizeof(xport_ioctl_params));
+				//printk("[lixun_kernel] xport_vid_ioc_pidval, pid = 0x%08x, avout_id 0x%x\n", ioc_params.avout_pid,ioc_params.avout_idx);
+				xport_mips_write(MIPS_CHL_PID(0,ioc_params.avout_idx), ioc_params.avout_pid);
+
+				break;
+
+			case XPORT_AUD_IOC_OUTPUT_MODE:
+				break;
+
+			case XPORT_AUD_IOC_RESET:
+				break;
+
+			case XPORT_AUD_IOC_ENABLE:
+				copy_from_user(&ioc_params, (void*)arg, sizeof(xport_ioctl_params));
+				if (ioc_params.avout_en)
+				{
+					tmp_val  = 0x80000000; /* enable flags */
+					tmp_val |= ioc_params.avout_mode << 7; /* output mode, bit7 */
+					tmp_val |= 0x00000002; /* output type, ES */
+
+					xport_mips_write(MIPS_CHL_EN(ioc_params.avout_idx), tmp_val);
+				}
+				else
+					xport_mips_write(MIPS_CHL_DISABLE(ioc_params.avout_idx), 0);
+
+				break;
+
+			case XPORT_AUD_IOC_PIDVAL:
+				copy_from_user(&ioc_params, (void*)arg, sizeof(xport_ioctl_params));
+				//printk("[lixun_kernel] xport_aud_ioc_pidval, pid = 0x%08x, avout_id 0x%x\n", ioc_params.avout_pid,ioc_params.avout_idx);
+				xport_mips_write(MIPS_CHL_PID(0,ioc_params.avout_idx), ioc_params.avout_pid);
+
+				break;
+
+			case XPORT_PCR_IOC_ENABLE:
+				copy_from_user(&ioc_params, (void*)arg, sizeof(xport_ioctl_params));
+
+				xport_mips_read(MIPS_PCR_PID(ioc_params.pcr_idx), &tmp_val);
+				tmp_val &= ~0x80000000;
+				tmp_val |= (ioc_params.pcr_en << 31);
+				xport_mips_write(MIPS_PCR_PID(ioc_params.pcr_idx), tmp_val);
+
+				break;
+
+			case XPORT_PCR_IOC_GETVAL:
+				copy_from_user(&ioc_params, (void*)arg, sizeof(xport_ioctl_params));
+
+				xport_mips_read_ex(MIPS_PCR_GET(ioc_params.pcr_idx), &ioc_params.pcr_hi_val, &ioc_params.pcr_lo_val);
+				copy_to_user((void*)arg, &ioc_params, sizeof(xport_ioctl_params));
+
+				break;
+
+			case XPORT_PCR_IOC_PIDVAL:
+				copy_from_user(&ioc_params, (void*)arg, sizeof(xport_ioctl_params));
+
+				xport_mips_read(MIPS_PCR_PID(ioc_params.pcr_idx), &tmp_val);
+				tmp_val &= ~0x1fff;
+				tmp_val |= ioc_params.pcr_pid;
+				xport_mips_write(MIPS_PCR_PID(ioc_params.pcr_idx), tmp_val);
+
+				break;
+
+			case XPORT_FW_INIT:
+				//			printk("load fw ... func:%s line:%d  \n",__FUNCTION__,__LINE__);
+				xport_load_firmware();
+				xport_config_buf();
+				//			printk("load fw suc  func:%s line:%d  \n",__FUNCTION__,__LINE__);
+				break;
+
+			case XPORT_VID_IOC_SWITCH:
+				copy_from_user(&ioc_params, (void*)arg, sizeof(xport_ioctl_params));
+				xport_mips_write(MIPS_CHL_SWITCH(ioc_params.avout_idx), ioc_params.avout_chl_switch);
+				break;
+
+			case XPORT_AUD_IOC_SWITCH:
+				copy_from_user(&ioc_params, (void*)arg, sizeof(xport_ioctl_params));
+				xport_mips_write(MIPS_CHL_SWITCH(ioc_params.avout_idx/*only one audio output*/), ioc_params.avout_chl_switch);
+				break;
+
+			case XPORT_IOC_MEM_BASE_PHYADDR:
+				if (NULL != (void *)arg){
+					tmp_val = XPORT_MEM_BASE;
+					copy_to_user((void __user *)arg, &tmp_val, sizeof(unsigned int));
+				}
+				else
+					return -EINVAL;
+				break;
+
+			case XPORT_IOC_MEM_SIZE:
+				if (NULL != (void *)arg){
+					tmp_val = XPORT_MEM_SIZE;
+					copy_to_user((void __user *)arg, &tmp_val, sizeof(unsigned int));
+				}
+				else
+					return -EINVAL;
+
+				break;
+			case XPORT_CHL_IOC_UNIT_NUM_DEF:
+
+				if (NULL != (void *)arg)
+				{
+					if(xport_dev->dev_minor >= XPORT_MINOR_CHL(0) &&
+							xport_dev->dev_minor < XPORT_MINOR_CHL(XPORT_MAX_CHL_NUM) )
+					{tmp_val = IN_CHL_UNIT_NUM_DEF(mnr-XPORT_MINOR_CHL(0));}
+
+					else
+						return -EINVAL;
+					copy_to_user((void __user *)arg, &tmp_val, sizeof(unsigned int));
+				}
+
+				else
+					return -EINVAL;
+
+				break;
+
+			case XPORT_CHL_IOC_UNIT_SIZE_DEF:
+
+				if (NULL != (void *)arg)
+				{
+
+					if(xport_dev->dev_minor >= XPORT_MINOR_CHL(0) &&
+							xport_dev->dev_minor < XPORT_MINOR_CHL(XPORT_MAX_CHL_NUM) )
+					{tmp_val = IN_CHL_UNIT_SIZE_DEF(mnr-XPORT_MINOR_CHL(0));}
+
+					else
+						return -EINVAL;
+					copy_to_user((void __user *)arg, &tmp_val, sizeof(unsigned int));
+				}
+				else
+					return -EINVAL;
+				break;
+
+
+			case XPORT_CHL_IOC_MIN_SPACES:
+				if (NULL != (void *)arg){
+					if (xport_dev->dev_minor == XPORT_MINOR_CHL(0))
+						tmp_val = XPORT_CHL0_MIN_SPACES;
+					else if (xport_dev->dev_minor == XPORT_MINOR_CHL(1))
+						tmp_val = XPORT_CHL1_MIN_SPACES;
+					else
+						return -EINVAL;
+					copy_to_user((void __user *)arg, &tmp_val, sizeof(unsigned int));
+				}
+				else
+					return -EINVAL;
+				break;
+
+			case XPORT_TUN_IOC_ENABLE:
+				if(arg!= 1 && arg!= 0)
+				{
+					return -EINVAL;
+				}
+
+				tmp_val = xport_readl(XPORT_TUNER_EN);
+				xport_writel(XPORT_TUNER_EN, xport_set_bit(tmp_val,arg));
+				break;
+
+			case XPORT_TUN_IOC_DISABLE:
+				if(arg!= 1 && arg!= 0)
+				{
+					return -EINVAL;
+				}
+
+				tmp_val = xport_readl(XPORT_TUNER_EN);
+				xport_writel(XPORT_TUNER_EN, xport_cls_bit(tmp_val,arg));
+				break;
+
+			case XPORT_IOC_DMA0_LIST0_HEAD_ADDR:
+				__put_user(DMA0_LIST0_HEAD_ADDR, (int __user *)arg);
+				break;
+			case XPORT_IOC_DMA0_BUF0_BASE_ADDR:
+				__put_user(DMA0_BUF0_BASE_ADDR, (int __user *)arg);
+				break;
+			case XPORT_IOC_DMA0_LIST1_HEAD_ADDR:
+				__put_user(DMA0_LIST1_HEAD_ADDR, (int __user *)arg);
+				break;
+			case XPORT_IOC_DMA0_BUF1_BASE_ADDR:
+				__put_user(DMA0_BUF1_BASE_ADDR, (int __user *)arg);
+				break;
+			case XPORT_IOC_DMA0_MAX_BLOCK_SIZE:
+				__put_user(DMA0_MAX_BLOCK_SIZE, (int __user *)arg);
+				break;
+			case XPORT_IOC_DMA0_MAX_BLOCK_NUM:
+				__put_user(DMA0_MAX_BLOCK_NUM, (int __user *)arg);
+				break;
+		}
+
+		return 0;
+	}
+
+	return -EINVAL;
+}
+
+
+static struct file_operations xport_fops = {
+	.owner = THIS_MODULE,
+	.open = xport_open,
+	.release = xport_release,
+	.read = xport_read,
+	.write = xport_write,
+	.poll = xport_poll,
+	.unlocked_ioctl = xport_ioctl,
+	.mmap = xport_mmap,
+};
+
+static struct proc_dir_entry *xport_proc_entry = NULL;
+
+
+static void xport_dump_regs(void)
+{
+	unsigned int chl_id;
+	unsigned int reg_val;
+
+	printk("==============> Hardware Register <=====================\n");
+
+	reg_val = xport_readl(PA_XPORT_REG_BASE + (0x0008 << 2));
+	printk("xport_cfg0         = 0x%08x\n", reg_val);
+	reg_val = xport_readl(PA_XPORT_REG_BASE + (0x0009 << 2));
+	printk("xport_cfg1         = 0x%08x\n", reg_val);
+	reg_val = xport_readl(PA_XPORT_REG_BASE + (0x0018 << 2));
+	printk("tuner enable       = 0x%08x\n", reg_val);
+	reg_val = xport_readl(PA_XPORT_REG_BASE + (0x0011 << 2));
+	printk("IRQ0 En            = 0x%08x\n", reg_val);
+	reg_val = xport_readl(PA_XPORT_REG_BASE + (0x0015 << 2));
+	printk("IRQ1 En            = 0x%08x\n", reg_val);
+	reg_val = xport_readl(PA_XPORT_REG_BASE + (0x0010 << 2));
+	printk("IRQ0 ST            = 0x%08x\n", reg_val);
+	reg_val = xport_readl(PA_XPORT_REG_BASE + (0x0014 << 2));
+	printk("IRQ1 ST            = 0x%08x\n", reg_val);
+	reg_val = xport_readl(PA_XPORT_REG_BASE + (0x0040 << 2));
+	printk("channel0 base addr = 0x%08x\n", reg_val);
+	reg_val = xport_readl(PA_XPORT_REG_BASE + (0x0041 << 2));
+	printk("channel0 cfg       = 0x%08x\n", reg_val);
+	reg_val = xport_readl(PA_XPORT_REG_BASE + (0x0042 << 2));
+	printk("channel0 rp        = 0x%08x\n", reg_val);
+	reg_val = xport_readl(PA_XPORT_REG_BASE + (0x0043 << 2));
+	printk("channel0 wp        = 0x%08x\n", reg_val);
+	reg_val = xport_readl(PA_XPORT_REG_BASE + (0x0045 << 2));
+	printk("channel0 st        = 0x%08x\n", reg_val);
+	reg_val = xport_readl(PA_XPORT_REG_BASE + (0x0060 << 2));
+	printk("pid filter0        = 0x%08x\n", reg_val);
+	reg_val = xport_readl(PA_XPORT_REG_BASE + (0x0061 << 2));
+	printk("pid filter1        = 0x%08x\n", reg_val);
+	reg_val = xport_readl(PA_XPORT_REG_BASE + (0x0003 << 2));
+	printk("Mail Box3          = 0x%08x\n", reg_val);
+	reg_val = xport_readl(PA_XPORT_REG_BASE + (0x0004 << 2));
+	printk("Mail Box4          = 0x%08x\n", reg_val);
+	reg_val = xport_readl(PA_XPORT_REG_BASE + (0x0005 << 2));
+	printk("Mail Box5          = 0x%08x\n", reg_val);
+
+	printk("\n==============>   Mips Register   <=====================\n");
+	for (chl_id = 0; chl_id < 6; chl_id++) {
+		printk("==============> Output Channel %d <=====================\n", chl_id);
+
+		xport_mips_read(MIPS_CHL_EN(chl_id), &reg_val);
+		printk("channel en           = 0x%08x\n", reg_val);
+
+		xport_mips_read(MIPS_CHL_PID(0,chl_id), &reg_val);
+		printk("channel PID0         = 0x%08x\n", reg_val);
+
+		xport_mips_read(MIPS_CHL_PID(1,chl_id), &reg_val);
+		printk("channel PID1         = 0x%08x\n", reg_val);
+
+		xport_mips_read(MIPS_CHL_PID(2,chl_id), &reg_val);
+		printk("channel PID2         = 0x%08x\n", reg_val);
+
+		xport_mips_read(MIPS_CHL_PID(3,chl_id), &reg_val);
+		printk("channel PID3         = 0x%08x\n", reg_val);
+
+		xport_mips_read(MIPS_CHL_DIR_LOW_ADDR(chl_id), &reg_val);
+		printk("channel DIR_LOW_ADRR = 0x%08x\n", reg_val);
+
+		xport_mips_read(MIPS_CHL_DIR_UP_ADDR(chl_id), &reg_val);
+		printk("channel DIR_UP_ADRR  = 0x%08x\n", reg_val);
+
+		xport_mips_read(MIPS_CHL_WP(chl_id), &reg_val);
+		printk("channel WP           = 0x%08x\n", reg_val);
+
+		xport_mips_read(MIPS_CHL_BUF_LOW_ADDR(chl_id), &reg_val);
+		printk("channel BUF_LOW_ADRR = 0x%08x\n", reg_val);
+
+		xport_mips_read(MIPS_CHL_BUF_UP_ADDR(chl_id), &reg_val);
+		printk("channel BUF_UP_ADRR  = 0x%08x\n", reg_val);
+
+		xport_mips_read(MIPS_CHL_ERR_PKT_CNT(chl_id), &reg_val);
+		printk("channel ERR Packet   = 0x%08x\n", reg_val);
+
+		xport_mips_read(MIPS_CHL_OUT_PKT_CNT(chl_id), &reg_val);
+		printk("channel Out Packet   = 0x%08x\n", reg_val);
+	}
+
+	return;
+}
+
+static void xport_show_buffer_define(void)
+{
+	unsigned int it;
+	printk("Xport Mem Base: 0x%x\n", XPORT_MEM_BASE);
+	printk("Xport Mem Size: 0x%x\n", XPORT_SIZE);
+
+	for (it = 0; it < 4; it++){
+		printk("Xport CHL%d BASE: 0x%x\n", it, IN_CHL_BASE_DEF(it));
+		printk("Xport CHL%d SIZE: 0x%x\n", it, IN_CHL_BUF_SIZE(it));
+	}
+	printk("Xport DMA0 Buf0 Base: 0x%x\n", DMA0_BUF0_BASE_ADDR);
+	printk("Xport DMA0 Buf0 Size: 0x%x\n", DMA0_BUF0_SIZE);
+	printk("Xport DMA0 Buf1 Base: 0x%x\n", DMA0_BUF1_BASE_ADDR);
+	printk("Xport DMA0 Buf1 Size: 0x%x\n", DMA0_BUF1_SIZE);
+	printk("Xport DMA0 List0 Head Base: 0x%x\n", DMA0_LIST0_HEAD_ADDR);
+	printk("Xport DMA0 List0 Head Size: 0x%x\n", DMA_LIST_HEAD_SIZE);
+	printk("Xport DMA0 List1 Head Base: 0x%x\n", DMA0_LIST1_HEAD_ADDR);
+	printk("Xport DMA0 List1 Head Size: 0x%x\n", DMA_LIST_HEAD_SIZE);
+	printk("Xport MIPS_EXTERNAL_BASE_ADDR: 0x%x\n", MIPS_EXTERNAL_BASE_ADDR);
+	printk("Xport  MIPS_EXTERNAL_SIZE: 0x%x\n",  MIPS_EXTERNAL_SIZE);
+
+	for (it = 0; it < MAX_FILTER_NUM ; it++){
+		printk("Xport Filter%d Buffer BASE: 0x%x\n", it, FLT_BUF_BASE_ADDR(it));
+		printk("Xport Filter%d Buffer SIZE: 0x%x\n", it, FLT_BUF_SIZE(it));
+	}
+
+}
+
+
+/*achieve serial write operation of xport module*/
+static int xport_proc_write(struct file *file, const char *buffer, unsigned long count, void *data)
+{
+	u32 addr;
+	u32 val;
+
+	const char *cmd_line = buffer;;
+
+	if (strncmp("rl", cmd_line, 2) == 0) {
+		addr = simple_strtol(&cmd_line[3], NULL, 16);
+		val = xport_readl(addr);
+		printk(" xport_readl [0x%08x] = 0x%08x \n", addr, val);
+	}
+	else if (strncmp("wl", cmd_line, 2) == 0) {
+		addr = simple_strtol(&cmd_line[3], NULL, 16);
+		val = simple_strtol(&cmd_line[12], NULL, 16);
+		xport_writel(addr, val);
+	}
+	else if (strncmp("mips_rl", cmd_line, 7) == 0) {
+		addr = simple_strtol(&cmd_line[8], NULL, 16);
+		xport_mips_read(addr, &val);
+		printk(" xport_readl [0x%08x] = 0x%08x \n", addr, val);
+	}
+	else if (strncmp("mips_wl", cmd_line, 7) == 0) {
+		addr = simple_strtol(&cmd_line[8], NULL, 16);
+		val = simple_strtol(&cmd_line[13], NULL, 16);
+		xport_mips_write(addr, val);
+	}
+	else if (strncmp("dumpall", cmd_line, 7) == 0)
+		xport_dump_regs();
+	else if (strncmp("loadfw", cmd_line, 6) == 0)
+		xport_load_firmware();
+	else if (strncmp("allocbufs", cmd_line, 9) == 0)
+		xport_config_buf();
+	else if (strncmp("clearpids", cmd_line, 9) == 0)
+	{
+		int i;
+		for (i = 0; i < 64; i ++)
+			xport_writel(__PID_FILTER__(i), 0);
+	}
+	else if (strncmp("crcerr", cmd_line, 6) == 0)
+		printk(" last_crc_error_idx = %d \n", last_crc_error_idx);
+	else if (strncmp("getpcr", cmd_line, 6) == 0)
+	{
+		unsigned int pcr_hi, pcr_lo;
+		xport_mips_write(MIPS_PCR_PID(0), 0x80000000);
+		xport_mips_read_ex(MIPS_PCR_GET(0), &pcr_hi, &pcr_lo);
+		printk(" pcr = %08x:%08x \n", pcr_hi, pcr_lo);
+	}
+	else if (strncmp("checkbufs", cmd_line, 9) == 0){
+		xport_show_buffer_define();
+
+	}
+	else {
+		printk("\nonly following commands are supported: \n");
+		printk(" rl \n");
+		printk(" wl \n");
+		printk(" mips_rl \n");
+		printk(" mips_wl \n");
+		printk(" dumpall \n");
+		printk(" allocbufs \n");
+		printk(" loadfw \n");
+		printk(" getpcr \n");
+		printk(" clearpids \n");
+		printk(" crcerr \n");
+		printk(" checkbufs \n");
+	}
+
+	return count;
+}
+
+static void xport_setup_dev(dev_t xport_dev, char * dev_name)
+{
+
+	/*
+	   replace class_simple_device_add() in pre version
+	   by ZJ. 1st Apr 2010
+	   */
+	device_create(cnc180x_xport_class,NULL,xport_dev,NULL,dev_name);
+	/*NULL might be alternated by some data array*/
+}
+
+static int __init xport_init(void)
+{
+	int i;
+	char devname[100];
+
+	printk("xport_init.\n");
+
+	clock_xport_enaclock(_clock_enable);
+
+	//(void)signal(SIGINT, &xport_signal_handler_clear);
+	//signal(SIGINT,(xport_signal_handler_clear)) ;
+	xport_regs_base = ( __iomem char *)VA_XPORT_BASE;
+	if (NULL == xport_regs_base) {
+		goto outerr6;
+	}
+
+	if (NULL == request_mem_region(XPORT_MEM_BASE, XPORT_MEM_SIZE, "CS Xport Memory space")) {
+		goto outerr5;
+	}
+	printk("xport region:0x%08x, used mem:0x%x, baseaddress:0x%x\n",XPORT_MEM_BASE, XPORT_MEM_USED_SIZE, xport_regs_base);
+
+	xport_mem_base = ioremap(XPORT_MEM_BASE, XPORT_MEM_SIZE);
+	//printk("xport mem base:[%04x] line:%d \n",xport_mem_base,__LINE__);
+
+	if (NULL == xport_mem_base) {
+		goto outerr4;
+	}
+
+	for (i = 0; i < MAX_FILTER_NUM; i++)
+		init_waitqueue_head(&filter_wait_queue[i]);
+
+
+	if (register_chrdev(XPORT_MAJOR, "cs_xport", &xport_fops)){
+		goto outerr3;
+	}
+	/*
+	   replace class_simple_create() in pre version
+	   by ZJ .1st Apr 2010
+	   */
+	cnc180x_xport_class = class_create(THIS_MODULE,"cnc_xport");
+	if (IS_ERR(cnc180x_xport_class)){
+		printk(KERN_ERR "XPORT: class create failed.\n");
+		goto outerr2;
+		// return -EIO;
+	}
+
+	//create a platform device aim to obtain a device structure
+	xport_pdev = platform_device_register_simple("xport_device", 0, NULL, 0);
+	if (IS_ERR(xport_pdev)) {
+		printk(KERN_ERR "XPORT: Failed to register device for \"%s\"\n",
+				"xport");
+		goto outerr1;
+		//  return -EINVAL;
+	}
+
+	xport_setup_dev(MKDEV(XPORT_MAJOR, XPORT_MINOR), "cnc_xport");
+
+	for(i = 0 ; i < XPORT_MAX_CHL_NUM; i++)
+	{
+		memset(devname,0,100);
+		sprintf(devname,"channel_%d",i);
+		xport_setup_dev(MKDEV(XPORT_MAJOR, XPORT_MINOR_CHL(i)),devname);
+	}
+
+	for (i = 0; i < MAX_FILTER_NUM; i++) {
+		memset(devname,0,100);
+		sprintf(devname, "xport_filter%d", i);
+		xport_setup_dev(MKDEV(XPORT_MAJOR, XPORT_MINOR_FT_BASE + i), devname);
+	}
+
+	xport_dma_init();
+	xport_hw_init();
+
+	if (0 != request_irq(XPORT_IRQ1,(irq_handler_t)xport_irq0, IRQF_DISABLED, "cs_xport0", &irq0_dev_id)) {
+		printk(KERN_ERR "XPORT: cannot register IRQ0 \n");
+		goto outerr0;
+		//	return -EIO;
+	}
+
+	if (0 != request_irq(XPORT_IRQ2, (irq_handler_t)xport_irq1, IRQF_DISABLED, "cs_xport1", &irq1_dev_id)) {
+		printk(KERN_ERR "XPORT: cannot register IRQ1 \n");
+		goto outerr0;
+		//	return -EIO;
+	}
+
+	xport_proc_entry = create_proc_entry("xport_io", 0, NULL);
+	if (NULL != xport_proc_entry) {
+		xport_proc_entry->write_proc = &xport_proc_write;
+	}
+
+	// sema_init(&read_sem, 1);
+	printk(KERN_INFO "Xport: Init OK [0x%08x]. \n", XPORT_MEM_BASE);
+	return 0;
+
+outerr0:
+	platform_device_unregister(xport_pdev);
+outerr1:  /*replace class_simple_destroy() in pre version . by ZhangJi . 1st Apr 2010*/
+	class_destroy(cnc180x_xport_class);
+outerr2:
+	unregister_chrdev(XPORT_MAJOR, "cs_xport");
+outerr3:
+	iounmap(xport_mem_base);
+outerr4:
+	release_mem_region(XPORT_MEM_BASE, XPORT_MEM_SIZE);
+outerr5:
+outerr6:
+
+
+	return -ENODEV;
+}
+
+
+static void __exit xport_exit(void)
+{
+	int i;
+	char devname[100];
+
+	for (i = 0; i < 48; i++)
+	{
+		sprintf(devname, "cs_xport/filter%d", i);
+		devres_free(devname);
+	}
+
+	if (NULL != xport_proc_entry)
+	{
+		remove_proc_entry("xport_io", NULL);
+	}
+
+	/*
+	   replace class_simple_device_remove()
+	   by Zhang.Ji .1st Apr 2010
+	   */
+	device_destroy(cnc180x_xport_class,MKDEV(XPORT_MAJOR, XPORT_MINOR));
+	for(i = 0 ; i < XPORT_MAX_CHL_NUM; i++)
+	{
+		device_destroy(cnc180x_xport_class,MKDEV(XPORT_MAJOR, XPORT_MINOR_CHL(i)));
+	}
+
+	for (i = 0; i < MAX_FILTER_NUM; i++)
+	{
+		device_destroy(cnc180x_xport_class,MKDEV(XPORT_MAJOR,XPORT_MINOR_FT_BASE+i));
+	}
+
+	platform_device_unregister(xport_pdev);
+	class_destroy(cnc180x_xport_class);
+	iounmap(xport_regs_base);
+	//release_mem_region(VA_XPORT_BASE, XPORT_REGS_SIZE);
+
+	iounmap(xport_mem_base);
+	release_mem_region(XPORT_MEM_BASE, XPORT_MEM_SIZE);
+
+	free_irq(XPORT_IRQ1, &irq0_dev_id);
+	free_irq(XPORT_IRQ2, &irq1_dev_id);
+
+	unregister_chrdev(XPORT_MAJOR, "cs_xport");
+	printk(KERN_INFO " cs Xport Exit ...... OK. \n");
+
+	return;
+}
+
+
+
+module_init(xport_init);
+module_exit(xport_exit);
+
+MODULE_AUTHOR("zhang.ji(ji.zhang@celestialsemi.com)");
+MODULE_DESCRIPTION("cs 1.0.0 Xport Driver");
+MODULE_VERSION("1.0.0");
+MODULE_LICENSE("GPL");
+
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/celestial/xport/xport_drv1900.h linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/xport/xport_drv1900.h
--- linux-linaro-3.4-2012.05-1_original/drivers/celestial/xport/xport_drv1900.h	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/xport/xport_drv1900.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,278 @@
+#ifndef __XPORT_DRV_H__
+#define __XPORT_DRV_H__
+
+#include "xport_regs1900.h"
+#include "xport_filter1900.h"
+#include <mach/hardware.h>
+
+#define  AUD_TEST
+
+#define XPORT_TIMEOUT           msecs_to_jiffies(5)
+
+#define XPORT_MEM_BASE          (( XPORT_REGION - 0x1000 + 1 ) & ~(0xfff))
+
+#define XPORT_MEM_SIZE          XPORT_SIZE
+
+#define MAX_FILTER_NUM          63
+
+#define XPORT_CHL0_BASE_ADDR_DEF    XPORT_MEM_BASE
+
+#define IN_CHL_UNIT_SIZE_DEF(n)    ((n)==0?IN_CHL0_UNIT_SIZE_DEF: IN_CHL1_UNIT_SIZE_DEF)
+#define IN_CHL_UNIT_NUM_DEF(n)     ((n)==0?IN_CHL0_UNIT_NUM_DEF: IN_CHL1_UNIT_NUM_DEF)
+#define IN_CHL_CFG_DEF(n)          ((n)==0?IN_CHL0_CFG_DEF: IN_CHL1_CFG_DEF)
+#define IN_CHL_BASE_DEF(n)         ((n)==0?IN_CHL0_BASE_ADDR_DEF: IN_CHL1_BASE_ADDR_DEF)
+#define IN_CHL_BUF_SIZE(n)         ((n)==0?IN_CHL0_BUF_SIZE: IN_CHL1_BUF_SIZE)
+
+#ifndef CONFIG_XPORT_BIG_DMABUFFER
+
+#define IN_CHL0_UNIT_SIZE_DEF    512
+#define IN_CHL0_UNIT_NUM_DEF     256
+#define IN_CHL0_BUF_SIZE         0x20000 // should equal/greater than IN_CHL0_UNIT_SIZE_DEF * IN_CHL0_UNIT_NUM_DEF
+#define IN_CHL0_CFG_DEF          ((IN_CHL0_UNIT_NUM_DEF<<8) | (IN_CHL0_UNIT_SIZE_DEF>>3))
+#define IN_CHL0_BASE_ADDR_DEF     XPORT_CHL0_BASE_ADDR_DEF
+
+#define IN_CHL1_UNIT_SIZE_DEF    512
+#define IN_CHL1_UNIT_NUM_DEF     256
+#define IN_CHL1_BUF_SIZE         0x20000 // should equal/greater than IN_CHL1_UNIT_SIZE_DEF * IN_CHL1_UNIT_NUM_DEF
+#define IN_CHL1_CFG_DEF          ((IN_CHL1_UNIT_NUM_DEF<<8) | (IN_CHL1_UNIT_SIZE_DEF>>3))
+#define IN_CHL1_BASE_ADDR_DEF     (IN_CHL0_BASE_ADDR_DEF+IN_CHL0_BUF_SIZE)
+
+#else // define BIG DMA BUFFER
+
+#define IN_CHL0_UNIT_SIZE_DEF    2000
+#define IN_CHL0_UNIT_NUM_DEF     128
+#define IN_CHL0_CFG_DEF          ((0x60000000) | (IN_CHL0_UNIT_NUM_DEF<<8) | (IN_CHL0_UNIT_SIZE_DEF>>3))
+#define IN_CHL0_BASE_ADDR_DEF     XPORT_CHL0_BASE_ADDR_DEF
+
+#define IN_CHL1_UNIT_SIZE_DEF    512
+#define IN_CHL1_UNIT_NUM_DEF     256
+#define IN_CHL1_CFG_DEF          ((IN_CHL1_UNIT_NUM_DEF<<8) | (IN_CHL1_UNIT_SIZE_DEF>>3))
+#define IN_CHL1_BASE_ADDR_DEF    (IN_CHL0_BASE_ADDR_DEF+0x20000)
+
+#endif // #ifndef CONFIG_XPORT_BIG_DMABUFFER
+
+
+#define DMA0_BUF0_BASE_ADDR         (IN_CHL1_BASE_ADDR_DEF + IN_CHL1_BUF_SIZE)  //(XPORT_MEM_BASE+0x40000)
+#define DMA0_BUF0_SIZE              0x10000
+#define DMA0_BUF1_BASE_ADDR         (DMA0_BUF0_BASE_ADDR + DMA0_BUF0_SIZE) //(XPORT_MEM_BASE+0x50000)
+#define DMA0_BUF1_SIZE              0x10000
+#define DMA0_MAX_BLOCK_SIZE         2048    // 2k  bytes
+#define DMA0_MAX_BLOCK_NUM          16
+
+#define DMA_LIST_HEAD_SIZE          0x800
+#define DMA0_LIST0_HEAD_ADDR        (DMA0_BUF1_BASE_ADDR + DMA0_BUF1_SIZE)  //(XPORT_MEM_BASE+0x80000)
+#define DMA0_LIST1_HEAD_ADDR        (DMA0_LIST0_HEAD_ADDR + DMA_LIST_HEAD_SIZE)    //(XPORT_MEM_BASE+0x80800)
+
+#define MIPS_EXTERNAL_BASE_ADDR     (DMA0_LIST1_HEAD_ADDR + DMA_LIST_HEAD_SIZE)    // size = 0xE000
+#define MIPS_EXTERNAL_SIZE          0xE000
+
+/* Filter Buffer define ******/
+#define FLT_BUF_SIZE_1              0x20000
+
+#if (BASE_DDR_ADDR==0x8000000)
+#define FLT_BUF_SIZE_2              0x10000
+#define FLT_PVR_BUF_SIZE            0x190000
+#else
+#define FLT_BUF_SIZE_2              0x20000
+#define FLT_PVR_BUF_SIZE            0x270000
+#endif
+
+#define FLT_BUF_SIZE(x)             ((x)>FLT_BUF_SIZE_SPLIT ? (((x) > 60)? FLT_PVR_BUF_SIZE:FLT_BUF_SIZE_2): FLT_BUF_SIZE_1)
+#define FLT_BUF_SIZE_SPLIT          (36)
+#define FLT_BUF_BASE                (MIPS_EXTERNAL_BASE_ADDR + MIPS_EXTERNAL_SIZE)//(XPORT_MEM_BASE+0x90000)
+
+#define FLT_NORMAL_SIZE_SUM(x)      (((x)>FLT_BUF_SIZE_SPLIT) ? (FLT_BUF_SIZE_1 * FLT_BUF_SIZE_SPLIT + FLT_BUF_SIZE_2 * (x-FLT_BUF_SIZE_SPLIT)) : (FLT_BUF_SIZE_1 * (x)) )
+#define FLT_NORMAL_BASE_ADDR(y)     (FLT_BUF_BASE + FLT_NORMAL_SIZE_SUM(y))
+#define FLT_PVR_BUFF_ADDR(m)        (FLT_NORMAL_BASE_ADDR(61) + (m-61)*FLT_PVR_BUF_SIZE) // m should be 61,62
+#define FLT_BUF_BASE_ADDR(n)        ((n)<61 ?(FLT_NORMAL_BASE_ADDR(n)): (FLT_PVR_BUFF_ADDR(n)))
+
+#define XPORT_MEM_USED_SIZE         (FLT_PVR_BUFF_ADDR(63) - XPORT_MEM_BASE) //(FLT_BUF_BASE - XPORT_MEM_BASE + FLT_BUF_SIZE * 61 + FLT_PVR_BUF_SIZE * 2)
+
+
+/***********Driver Constant Defines*********/
+#define XPORT_MAJOR                 100
+#define XPORT_MINOR                 0
+
+/*VID now support to 8 channels. but  with no limit in theory*/
+#define XPORT_MAX_CHL_NUM           2
+#define XPORT_AV_CHNL_NUM           8
+#define XPORT_MINOR_CHL(n)          (10+n)
+#define XPORT_MINOR_FT_BASE         100
+
+
+#define XPORT_CFG0_TUNER0_SER_MOD       0x00000001
+#define XPORT_CFG0_TUNER1_SER_MOD       0x00000002
+#define XPORT_CFG0_CHL0_DMA_EN          0x00000004
+#define XPORT_CFG0_CHL1_DMA_EN          0x00000010
+#define XPORT_CFG0_CHL0_ATSC_EN         0x00000100
+#define XPORT_CFG0_CHL1_ATSC_EN         0x00000200
+
+#define XPORT_CFG1_OUT_CHL0_LINE_SYNC   0x00000001
+#define XPORT_CFG1_OUT_CHL1_LINE_SYNC   0x00000002
+#define XPORT_CFG1_OUT_CHL2_LINE_SYNC   0x00000004
+#define XPORT_CFG1_OUT_CHL3_LINE_SYNC   0x00000008
+
+#define XPORT_TUNER0_EN                 0x00000001
+#define XPORT_TUNER1_EN                 0x00000002
+
+#define XPORT_IRQ0_ID                   100
+#define XPORT_IRQ1_ID                   101
+
+/************ Driver Macro Defines*********/
+extern void __iomem *xport_regs_base;
+extern void __iomem *xport_mem_base;
+
+#define __IS_HW_ADDR__(x)              (((x)&0xbff00000)==XPORT_REG_ADDR_BASE)
+#define __IS_MIPS_ADDR__(x)            (((x)&0xbff00000)==(XPORT_REG_ADDR_BASE+0x100000))
+#define __WR_FLAGS__(x)                (((x)>>30)&0x1)
+#define __OFFSET_ADDR__(x)             ((x)&0x000fffff)
+
+void xport_writeb(int a,int v);
+void xport_writew(int a,int v);
+void xport_writel(int a,int v);
+unsigned char xport_readb(int a);
+unsigned short xport_readw(int a);
+unsigned int xport_readl(int a);
+
+/******Xport Data Object*********/
+typedef enum
+{
+	XPORT_INPUT_TS_TYPE = 0,
+	XPORT_INPUT_M2TS_TYPE,
+	XPORT_INPUT_TS204_TYPE,
+	XPORT_INPUT_OTHER_TYPE
+} XPORT_STREAM_TYPE;
+
+typedef struct XPORT_DEV_t {
+	unsigned int dev_minor;
+	XPORT_FILTER_TYPE filter_type;
+	XPORT_STREAM_TYPE stream_type;
+	ssize_t packet_size;
+	wait_queue_head_t wait_queue;
+	wait_queue_head_t *irq_wait_queue_ptr;
+	spinlock_t spin_lock;
+	struct semaphore xport_sem;
+
+} XPORT_DEV;
+
+typedef struct DMA_LIST_NODE_t {
+	unsigned int buf_addr;
+	unsigned int data_size;
+	struct DMA_LIST_NODE_t *next_addr;
+	unsigned int next_valid;
+} DMA_LIST_NODE;
+
+typedef struct DMA_LIST_t {
+	DMA_LIST_NODE *head_node;
+	unsigned int max_block_size;
+	unsigned int max_block_num;
+	unsigned int cur_index;
+	unsigned int next_index;
+	unsigned int locked_flag;
+	unsigned int block_size_sum;
+} DMA_LIST;
+
+typedef struct XPORT_DMA_t {
+	DMA_LIST dma_list[2];
+	unsigned long next_jiffies;
+	unsigned int cur_index;
+	struct semaphore dma_sem;
+} XPORT_DMA;
+
+typedef struct XPORT_DIR_T{
+	struct semaphore dir_sem;
+}XPORT_DIR;
+
+
+#define XPORT_FILTER_IOC_PID0           _IOW('k', 1, int)
+#define XPORT_FILTER_IOC_PID1           _IOW('k', 2, int)
+#define XPORT_FILTER_IOC_PID2           _IOW('k', 3, int)
+#define XPORT_FILTER_IOC_PID3           _IOW('k', 4, int)
+#define XPORT_FILTER_IOC_FILTER         _IOW('k', 5, int)
+
+#define XPORT_FILTER_IOC_TYPE           _IOW('k', 6, int)
+#define XPORT_FILTER_IOC_ENABLE         _IOW('k', 8, int)
+
+#define XPORT_FILTER_IOC_QUERY_NUM      _IOR('k', 10, int)
+#define XPORT_FILTER_IOC_QUERY_SIZE     _IOR('k', 11, int)
+
+#define XPORT_FILTER_IOC_CRC_ENABLE     _IOW('k', 12, int)
+
+#define XPORT_PIDFT_IOC_ENABLE          _IOW('k', 13, int)
+#define XPORT_PIDFT_IOC_CHANNEL         _IOW('k', 14, int)
+#define XPORT_PIDFT_IOC_PIDVAL          _IOW('k', 15, int)
+#define XPORT_PIDFT_IOC_DESC_ODDKEY     _IOW('k', 16, int)
+#define XPORT_PIDFT_IOC_DESC_EVENKEY    _IOW('k', 17, int)
+#define XPORT_PIDFT_IOC_DESC_ENABLE     _IOW('k', 18, int)
+
+#define XPORT_CHL_IOC_ENABLE            _IOW('k', 19, int)
+#define XPORT_CHL_IOC_INPUT_MODE        _IOW('k', 20, int)
+#define XPORT_CHL_IOC_RESET             _IOW('k', 21, int)
+#define XPORT_CHL_IOC_DMA_RESET         _IOW('k', 22, int)
+
+#define XPORT_VID_IOC_OUTPUT_MODE       _IOW('k', 23, int)
+#define XPORT_VID_IOC_RESET             _IOW('k', 24, int)
+#define XPORT_VID_IOC_ENABLE            _IOW('k', 25, int)
+#define XPORT_VID_IOC_PIDVAL            _IOW('k', 26, int)
+
+#define XPORT_AUD_IOC_OUTPUT_MODE       _IOW('k', 27, int)
+#define XPORT_AUD_IOC_RESET             _IOW('k', 28, int)
+#define XPORT_AUD_IOC_ENABLE            _IOW('k', 29, int)
+#define XPORT_AUD_IOC_PIDVAL            _IOW('k', 30, int)
+
+#define XPORT_PCR_IOC_ENABLE            _IOW('k', 31, int)
+#define XPORT_PCR_IOC_GETVAL            _IOW('k', 32, int)
+#define XPORT_PCR_IOC_PIDVAL            _IOW('k', 33, int)
+
+#define XPORT_FW_INIT                   _IOW('k', 34, int)
+#define XPORT_FILTER_IOC_CRC_NTF_ENB    _IOW('k', 35, int)
+#define XPORT_FILTER_IOC_SAVE_ENABLE    _IOW('k', 36, int)
+
+#define XPORT_FILTER_IOC_PID4           _IOW('k', 37, int)
+#define XPORT_FILTER_IOC_PID5           _IOW('k', 38, int)
+#define XPORT_FILTER_IOC_PID6           _IOW('k', 39, int)
+#define XPORT_FILTER_IOC_PID7           _IOW('k', 40, int)
+#define XPORT_FILTER_IOC_PID8           _IOW('k', 41, int)
+#define XPORT_FILTER_IOC_PID9           _IOW('k', 42, int)
+#define XPORT_FILTER_IOC_PID10          _IOW('k', 43, int)
+#define XPORT_FILTER_IOC_PID11          _IOW('k', 44, int)
+
+#define XPORT_CHL_IOC_CLEAR             _IOW('k', 45, int)
+#define XPORT_CHL_IOC_TUNER_MODE        _IOW('k', 46, int)
+
+#define XPORT_VID_IOC_SWITCH            _IOW('k', 47, int)
+#define XPORT_AUD_IOC_SWITCH            _IOW('k', 48, int)
+#define XPORT_FILTER_IOC_SWITCH         _IOW('k', 49, int)
+#define XPORT_CHL_IOC_DES_MODE          _IOW('k', 50, int)
+
+#define XPORT_IOC_MEM_BASE_PHYADDR      _IOR('k', 51, int)
+#define XPORT_IOC_MEM_SIZE              _IOR('k', 52, int)
+#define XPORT_FILTER_IOC_BUFFER_UPADDR  _IOR('k', 53, int)
+#define XPORT_FILTER_IOC_BUFFER_LOWADDR _IOR('k', 54, int)
+#define XPORT_FILTER_IOC_BUFFER_RP_ADDR _IOR('k', 55, int)
+#define XPORT_FILTER_IOC_BUFFER_WP_ADDR _IOR('k', 56, int)
+
+#define XPORT_CHL_IOC_UNIT_NUM_DEF      _IOR('k', 57, int)
+#define XPORT_CHL_IOC_UNIT_SIZE_DEF     _IOR('k', 58, int)
+#define XPORT_CHL_IOC_MIN_SPACES        _IOR('k', 59, int)
+#define XPORT_DMA_IOC_ENABLE            _IOR('k', 60, int)
+
+#define XPORT_FLT_IOC_CLEAR             _IOR('k', 61, int)
+#define XPORT_TUN_IOC_ENABLE            _IOR('k', 63, int)
+#define XPORT_TUN_IOC_DISABLE           _IOR('k', 64, int)
+
+#define XPORT_CHL_IOC_INPUT_TYPE        _IOR('k', 65, int)
+#define XPORT_CHL_IOC_SERIAL_MODE       _IOW('k', 66, int)
+
+#define XPORT_IOC_DMA0_LIST0_HEAD_ADDR  _IOR('k', 70, int)
+#define XPORT_IOC_DMA0_BUF0_BASE_ADDR   _IOR('k', 71, int)
+#define XPORT_IOC_DMA0_LIST1_HEAD_ADDR  _IOR('k', 72, int)
+#define XPORT_IOC_DMA0_BUF1_BASE_ADDR   _IOR('k', 73, int)
+#define XPORT_IOC_DMA0_MAX_BLOCK_SIZE   _IOR('k', 74, int)
+#define XPORT_IOC_DMA0_MAX_BLOCK_NUM    _IOR('k', 75, int)
+
+#define XPORT_IOC_ENABLE_TSOUT          _IOR('k', 84, int)
+
+#endif
+
+
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/celestial/xport/xport_filter1900.c linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/xport/xport_filter1900.c
--- linux-linaro-3.4-2012.05-1_original/drivers/celestial/xport/xport_filter1900.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/xport/xport_filter1900.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,629 @@
+/*
+ *  Copyright (C) 2010 Celestial Corporation
+ *  sdk@celestialsemi.cn 
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/miscdevice.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <asm/uaccess.h>
+#include <linux/io.h> 
+#include <linux/semaphore.h>
+
+#include <linux/sched.h>
+#include <linux/poll.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+
+#include "xport_drv1900.h"
+#include "xport_filter1900.h"
+#include "xport_mips1900.h"
+
+/*mips cmd */
+#define  FLT_CMD_BASE                     (XPORT_AV_CHNL_NUM << 9)
+#define SECTION_BUCKET_SIZE               0x1000
+
+#define  FLT_EN_ADDR(x)                   (FLT_CMD_BASE+(x<<8))  
+#define  FLT_FLT0_ADDR(x)                 (FLT_CMD_BASE+0x1+(x<<8))
+#define  FLT_FLT1_ADDR(x)                 (FLT_CMD_BASE+0x2+(x<<8))
+#define  FLT_FLT2_ADDR(x)                 (FLT_CMD_BASE+0x3+(x<<8))
+#define  FLT_MASK0_ADDR(x)                (FLT_CMD_BASE+0x4+(x<<8))
+#define  FLT_MASK1_ADDR(x)                (FLT_CMD_BASE+0x5+(x<<8))
+#define  FLT_MASK2_ADDR(x)		          (FLT_CMD_BASE+0x6+(x<<8))
+#define  FLT_BUF_LOW_ADDR(x)              (FLT_CMD_BASE+0x07+(x<<8))
+#define  FLT_BUF_UP_ADDR(x)               (FLT_CMD_BASE+0x08+(x<<8))
+
+#define  FLT_TC0_ERR_CNT_ADDR(x)          (FLT_CMD_BASE+0x0a+(x<<8))
+#define  FLT_TC1_ERR_CNT_ADDR(x)          (FLT_CMD_BASE+0x0b+(x<<8))
+#define  FLT_TC2_ERR_CNT_ADDR(x)          (FLT_CMD_BASE+0x0c+(x<<8))
+#define  FLT_TC3_ERR_CNT_ADDR(x)          (FLT_CMD_BASE+0x0d+(x<<8))
+#define  FLT_ERR_PACKET_CNT_ADDR(x)       (FLT_CMD_BASE+0x0e+(x<<8))
+#define  FLT_OUT_PACKET_CNT_ADDR(x)       (FLT_CMD_BASE+0x0f+(x<<8))
+
+#define  FLT_DISABLE_ADDR(x)		  		(FLT_CMD_BASE+0x36+(x<<8))
+#define  PID_CMD_BASE                     (FLT_CMD_BASE+0x16)
+/***********************n~(0,11)   x~(0,62)**********************/
+#define  FLT_PID_ADDR(n,x)                (PID_CMD_BASE+n+(x<<8))
+#define  FLT_BUF_WP_ADDR(x)               (XPORT_REG_ADDR_BASE+0x440+(x<<3))
+#define  FLT_BUF_RP_ADDR(x)               (XPORT_REG_ADDR_BASE+0x444+(x<<3))
+
+
+typedef enum
+{
+	RSV_OUTPUT = 0,
+	TS_OUTPUT = 1,
+	ES_OUTPUT,
+	SEC_OUTPUT,
+	PES_OUTPUT
+}CHL_OUTPUT_TYPE;
+
+
+inline unsigned int get_filter_buf_base_addr(unsigned int filter_index)
+{
+	unsigned int idx = filter_index;
+
+	return (idx>= 0&&idx<MAX_FILTER_NUM ? FLT_BUF_BASE_ADDR(idx):-1);
+}
+
+inline unsigned int get_filter_buf_top_addr(unsigned int filter_index)
+{
+	unsigned int idx = filter_index;
+	return (idx>= 0&&idx<MAX_FILTER_NUM ?(FLT_BUF_BASE_ADDR(idx + 1)):-1);
+}
+
+inline unsigned int get_filter_buf_size(unsigned int filter_index) 
+{
+	unsigned int idx = filter_index;
+	return ((idx>= 0&&idx<MAX_FILTER_NUM) ? (FLT_BUF_SIZE(idx)): -1);
+}
+
+
+inline unsigned int get_xport_filter_wp(unsigned int filter_index)
+{
+	return xport_readl(FLT_BUF_WP_ADDR(filter_index));
+}
+
+inline unsigned int get_xport_filter_rp(unsigned int filter_index)
+{
+	return xport_readl(FLT_BUF_RP_ADDR(filter_index));
+}
+
+
+int xport_filter_reset(unsigned int filter_index)
+{
+	unsigned int idx = filter_index;
+	xport_mips_write(FLT_DISABLE_ADDR(idx),0);
+	xport_mips_write(FLT_BUF_LOW_ADDR(idx),get_filter_buf_base_addr(idx));
+	xport_mips_write(FLT_BUF_UP_ADDR(idx),get_filter_buf_top_addr(idx));
+	xport_writel(FLT_BUF_WP_ADDR(idx),get_filter_buf_base_addr(idx));
+	xport_writel(FLT_BUF_RP_ADDR(idx),get_filter_buf_base_addr(idx));
+
+	return 0;
+}
+
+
+/**set filter type cmd to I/D ram of MIPs**/
+int xport_filter_set_type(unsigned int filter_index, XPORT_FILTER_TYPE filter_type)
+{
+	unsigned int en;
+	int rt;
+	unsigned int idx = filter_index;
+	XPORT_FILTER_TYPE ft = filter_type;
+
+
+	rt = xport_mips_read(FLT_EN_ADDR(idx), &en);
+
+	/* bit31: enable flag: 1 - output channel enabled */
+	en = xport_get_bit(en,31); 
+
+	if (rt == 0  &&  en == 0) 
+	{
+		en = (ft==FILTER_TYPE_SECTION ? SEC_OUTPUT:
+				(ft==FILTER_TYPE_TS ? TS_OUTPUT:
+				 (ft==FILTER_TYPE_PES? PES_OUTPUT:
+				  (ft==FILTER_TYPE_ES ? ES_OUTPUT : RSV_OUTPUT))));
+
+		xport_mips_write(FLT_EN_ADDR(idx), en);
+
+		return 0;
+	}
+
+	return -1;
+}
+
+int xport_filter_set_input(unsigned int filter_index, XPORT_INPUT_CHANNEL input_channel)
+{
+	return -1;
+}
+
+int xport_filter_set_crc(unsigned int filter_index, unsigned int crc_index)
+{
+	return -1;
+}
+
+int xport_filter_set_pidx(unsigned int filter_index, unsigned int pid, unsigned int slot)
+{
+	if(filter_index >=0 && filter_index <= 60 && slot>0)
+	{
+		printk("wrong operation.filter idx 0-61 shoule with only slot 0 work! \n");
+		return -1;
+	}
+
+	return slot>=0&&slot<=11 ? xport_mips_write(FLT_PID_ADDR(slot,filter_index),pid):-1;
+}
+
+int xport_filter_set_filter(unsigned int filter_index, unsigned char *filter, unsigned char *mask)
+{
+	xport_mips_write(FLT_FLT0_ADDR(filter_index), *(unsigned int *) filter);
+	xport_mips_write(FLT_FLT1_ADDR(filter_index), *(unsigned int *) (filter + 4));
+	xport_mips_write(FLT_FLT2_ADDR(filter_index), *(unsigned int *) (filter + 8));
+	xport_mips_write(FLT_MASK0_ADDR(filter_index), *(unsigned int *) mask);
+	xport_mips_write(FLT_MASK1_ADDR(filter_index), *(unsigned int *) (mask + 4));
+	xport_mips_write(FLT_MASK2_ADDR(filter_index), *(unsigned int *) (mask + 8));
+
+	return 0;
+}
+
+int xport_filter_crc_enable(unsigned int filter_index)
+{
+	return -1;
+}
+
+int xport_filter_crc_disable(unsigned int filter_index)
+{
+	return -1;
+}
+
+int xport_filter_crc_is_enable(unsigned int filter_index)
+{
+	return -1;
+}
+
+int xport_filter_enable(unsigned int filter_index, spinlock_t * spin_lock_ptr)
+{
+	int rt;
+	unsigned int en;
+	unsigned long irq1_en;
+	unsigned long spin_flags;
+
+	rt = xport_mips_read(FLT_EN_ADDR(filter_index), &en);
+
+	if(rt != 0)
+	{
+		return -1;
+	}
+
+	/**asign iomem addr into filter's register**/
+
+	xport_writel(FLT_BUF_RP_ADDR(filter_index), get_filter_buf_base_addr(filter_index));
+	spin_lock_irqsave(spin_lock_ptr, spin_flags);
+	irq1_en = (filter_index <32 ? xport_readl(XPORT_INT_ENB_ADDR1): xport_readl(XPORT_INT_ENB_ADDR0));	 	
+	irq1_en |=(filter_index<32 ? 1<<filter_index : XPORT_IRQ0_FILTER_NOTIFY);
+
+
+	if(filter_index <32)
+	{
+		xport_writel(XPORT_INT_CLS_ADDR1, (1 << filter_index));
+	}
+
+	xport_writel((filter_index<32? XPORT_INT_ENB_ADDR1: XPORT_INT_ENB_ADDR0),irq1_en);
+	spin_unlock_irqrestore(spin_lock_ptr, spin_flags);
+
+	return xport_mips_write(FLT_EN_ADDR(filter_index), 0x80000000 | en);
+}
+
+
+int xport_filter_disable(unsigned int filter_index, spinlock_t * spin_lock_ptr)
+{
+	int rt;
+	unsigned int en;
+	unsigned long irq1_en;
+	unsigned long spin_flags;
+
+
+	rt = xport_mips_read(FLT_EN_ADDR(filter_index), &en);
+
+	if (rt != 0)
+		return -1;
+
+
+	spin_lock_irqsave(spin_lock_ptr, spin_flags);
+
+	irq1_en = (filter_index <32 ? xport_readl(XPORT_INT_ENB_ADDR1) : xport_readl(XPORT_INT_ENB_ADDR0));
+	irq1_en&=(~(filter_index<32?1<<filter_index: XPORT_IRQ0_FILTER_NOTIFY));
+	xport_writel((filter_index<32?XPORT_INT_ENB_ADDR1: XPORT_INT_ENB_ADDR0),irq1_en);
+	spin_unlock_irqrestore(spin_lock_ptr, spin_flags);
+
+#if 1
+	return xport_mips_write(FLT_EN_ADDR(filter_index), 0x7fffffff & en);
+#else
+	return xport_mips_write(FILTER_DISABLE_ADDR(filter_index), 0);
+#endif
+
+
+}
+
+int xport_filter_is_enable(unsigned int filter_index)
+{
+	int rt;
+	unsigned int en;
+
+	rt = xport_mips_read(FLT_EN_ADDR(filter_index), &en);
+	en >>= 31;
+
+	if (rt == 0)
+		return en;
+
+	return -1;
+}
+/* seciton filter */
+int xport_filter_check_section_number(unsigned int filter_index)
+{
+	unsigned int len;
+	unsigned int wp, wp_tog;
+	unsigned int rp, rp_tog;
+	unsigned int up_addr, low_addr;
+
+
+	up_addr = get_filter_buf_top_addr(filter_index);
+	low_addr = get_filter_buf_base_addr(filter_index);
+	wp = xport_readl(FLT_BUF_WP_ADDR(filter_index));
+	rp = xport_readl(FLT_BUF_RP_ADDR(filter_index));
+
+
+	wp_tog = wp & 0x80000000;
+	rp_tog = rp & 0x80000000;
+
+	wp = wp & 0x7fffffff;
+	rp = rp & 0x7fffffff;
+
+	if (wp_tog == rp_tog) {
+		len = wp - rp;
+	}
+	else {
+		len = (up_addr - low_addr) + wp - rp;
+	}
+
+	len = len & 0xfffff000;
+
+	return len;
+}
+
+int xport_filter_check_section_size(unsigned int filter_index)
+{
+	return 0;
+}
+
+int xport_filter_clear_buffer(unsigned int filter_index)
+{
+	xport_writel(FLT_BUF_RP_ADDR(filter_index), get_filter_buf_base_addr(filter_index));
+	xport_writel(FLT_BUF_WP_ADDR(filter_index), get_filter_buf_base_addr(filter_index));
+
+	return 0;
+}
+
+int xport_filter_read_section_data(unsigned int filter_index, char __user * buffer, size_t len)
+{
+	void __iomem *read_addr;	
+	unsigned int rp, rp_tog;
+	unsigned int section_len;
+
+	if (xport_filter_check_section_number(filter_index) <= 0) {
+		return -1;
+	}
+
+	rp = xport_readl(FLT_BUF_RP_ADDR(filter_index));
+
+	rp_tog = rp & 0x80000000;
+	rp = rp & 0x7fffffff;
+
+	read_addr = xport_mem_base + (rp - XPORT_MEM_BASE);
+
+	section_len = ((unsigned char *) read_addr)[1];
+	section_len <<= 8;
+	section_len += ((unsigned char *) read_addr)[2];
+	section_len &= 0xfff;
+	section_len += 3;
+
+
+
+	if(section_len > 4096 || section_len > len) {
+		return -EFAULT;
+	}
+
+	if(copy_to_user(buffer, read_addr, section_len)) {
+		return -EFAULT;
+	}
+
+	rp += 0x1000;
+
+	if(rp >= get_filter_buf_top_addr(filter_index)) 
+	{
+		rp = get_filter_buf_base_addr(filter_index);
+		rp_tog = rp_tog ^ 0x80000000;
+	}	
+	xport_writel(FLT_BUF_RP_ADDR(filter_index), rp_tog | rp);
+
+
+
+	return section_len;
+}
+/* ts filter */
+int xport_filter_check_data_size(unsigned int filter_index)
+{
+	unsigned int len = 0;
+	unsigned int wp, wp_tog;
+	unsigned int rp, rp_tog;
+	unsigned int up_addr, low_addr;
+
+	up_addr = get_filter_buf_top_addr(filter_index);
+	low_addr = get_filter_buf_base_addr(filter_index);
+
+	wp = xport_readl(FLT_BUF_WP_ADDR(filter_index));
+	rp = xport_readl(FLT_BUF_RP_ADDR(filter_index));
+
+	wp_tog = wp & 0x80000000;
+	rp_tog = rp & 0x80000000;
+	wp = wp & 0x7fffffff;
+	rp = rp & 0x7fffffff;
+
+	if (wp_tog == rp_tog) {
+		len = wp - rp;
+	}
+	else {
+		len = (up_addr - low_addr) + wp - rp;
+	}
+
+	len = (len / 188) * 188;  
+
+	return len;
+}
+
+
+int xport_filter_read_data(unsigned int filter_index, char __user * buffer, size_t len)
+{
+	void __iomem *read_addr;
+
+	unsigned int rp, rp_tog;
+	unsigned int size_tmp;
+
+	/*check available data in buffer for reading*/
+	if (xport_filter_check_data_size(filter_index) < len)
+		return -1;
+
+	rp = xport_readl(FLT_BUF_RP_ADDR(filter_index));
+	rp_tog = rp & 0x80000000;
+	rp = rp & 0x7fffffff;
+
+	size_tmp = get_filter_buf_top_addr(filter_index) - rp;
+
+	if(size_tmp <= len) 
+	{
+		read_addr = xport_mem_base + (rp - XPORT_MEM_BASE);
+		if (copy_to_user(buffer, read_addr, size_tmp))
+			return -EFAULT;
+
+		len -= size_tmp;
+		buffer += size_tmp;
+		size_tmp += len;
+
+		rp = get_filter_buf_base_addr(filter_index);
+		rp_tog = rp_tog ^ 0x80000000;
+	}
+	else
+		size_tmp = len;
+
+	if (len > 0) {
+		read_addr = xport_mem_base + (rp - XPORT_MEM_BASE);
+		if (copy_to_user(buffer, read_addr, len))
+			return -EFAULT;
+
+		rp += len;
+	}
+
+	xport_writel(FLT_BUF_RP_ADDR(filter_index), rp_tog | rp);
+
+
+	return size_tmp;
+}
+
+
+
+/* pes filter */
+int xport_filter_check_pes_size(unsigned int filter_index)
+{
+	int len;
+	unsigned int pes_len = 0;
+
+	unsigned int wp, wp_tog;
+	unsigned int rp, rp_tog;
+	unsigned int up_addr, low_addr;
+
+	unsigned int section_size, data[3];
+	unsigned int mask = SECTION_BUCKET_SIZE - 1;
+	void __iomem *read_addr;
+
+	up_addr = get_filter_buf_top_addr(filter_index);
+	low_addr = get_filter_buf_base_addr(filter_index);
+
+	wp = xport_readl(FLT_BUF_WP_ADDR(filter_index));
+	rp = xport_readl(FLT_BUF_RP_ADDR(filter_index));
+
+	wp_tog = wp & 0x80000000;
+	rp_tog = rp & 0x80000000;
+	wp = wp & (0x7fffffff & ~mask);
+	rp = rp & (0x7fffffff & ~mask);
+
+	if (wp_tog == rp_tog) {
+		len = wp - rp;
+	}
+	else {//?
+		len = (up_addr - low_addr) + wp - rp;
+	}
+
+	if (len < SECTION_BUCKET_SIZE)
+		return 0;
+
+	if (rp & mask) 	 /* rp is not aligned with 0x1000 size */
+		return -EFAULT;
+
+	section_size = 0;
+
+	/* find the position that new pes packet starts */
+	while ((len & ~mask) > 0) {
+		read_addr = xport_mem_base + (rp - XPORT_MEM_BASE);
+
+		data[0] = *(unsigned int *) (read_addr);	 /* first 4 byte of bucket header */
+		data[1] = *(unsigned int *) (read_addr + 4);
+		data[2] = *(unsigned int *) (read_addr + 8);
+
+		if ((data[0] & 0x010000) && ((data[1] & 0xffffff) == 0x010000)) {	 /* new pes packet */
+			section_size += data[0] & 0xffff;
+			section_size -= 4;
+			pes_len = (data[2] & 0xff) << 8;
+			pes_len |= (data[2] & 0xff00) >> 8;
+
+			xport_writel(FLT_BUF_RP_ADDR(filter_index), rp | rp_tog);
+
+			rp += SECTION_BUCKET_SIZE;
+			len -= SECTION_BUCKET_SIZE;
+
+			if (rp >= up_addr) {
+				rp = low_addr;
+				rp_tog ^= 0x80000000;
+			}
+
+			break;
+		}
+
+		rp += SECTION_BUCKET_SIZE;
+		len -= SECTION_BUCKET_SIZE;
+
+		if (rp >= up_addr) {
+			rp = low_addr;
+			rp_tog ^= 0x80000000;
+		}
+	}
+
+	if (section_size == 0) {	 /* new pes packet is not found */
+		xport_writel(FLT_BUF_RP_ADDR(filter_index), (wp & 0xfffff000) | wp_tog);
+		return 0;
+	}
+
+	/* 
+	 * find the the position of next new pes packet, to get the 
+	 * size of current pes packet
+	 */
+	while (len > 0) {
+		read_addr = xport_mem_base + (rp - XPORT_MEM_BASE);
+		data[0] = *(unsigned int *) (read_addr);	 /* first 4 byte of bucket header */
+		data[1] = *(unsigned int *) (read_addr + 4);
+		data[2] = *(unsigned int *) (read_addr + 8);
+
+		if ((data[0] & 0x010000) && ((data[1] & 0xffffff) == 0x010000))
+			break;
+		else {
+			section_size += (data[0] & 0xffff);
+			section_size -= 4;
+		}
+
+		if (section_size > pes_len + 6)
+			section_size = pes_len + 6;
+
+		if ((section_size == pes_len + 6) && (pes_len != 0))
+			break;  /* video pes is exception */
+
+		rp += SECTION_BUCKET_SIZE;
+		len -= SECTION_BUCKET_SIZE;
+
+		if (rp >= up_addr) {
+			rp = low_addr;
+			rp_tog ^= 0x80000000;
+		}
+	}
+
+	if (len <= 0) {
+		unsigned int buffer_size = up_addr - low_addr;
+		if (section_size >= (buffer_size - (buffer_size >> 10))) {
+			printk(KERN_INFO
+					"PES packet size exceed the size of filter buffer: filter id = %d, buffer size = %d section size = %d\n",
+					filter_index, up_addr - low_addr, section_size);
+			return -EFAULT;
+		}
+		else if ((section_size == pes_len + 6) && (pes_len != 0))
+			return section_size;
+		else
+			/* not find the next pes packet, that means current packet is not ready */
+			return 0;
+	}
+
+	return section_size;
+}
+
+int xport_filter_read_pes_data(unsigned int filter_index, char __user * buffer, size_t len)
+{
+	unsigned int rp, rp_tog;
+	unsigned int up_addr, low_addr;
+	unsigned int data, bucket_size;
+	int pes_size, byte_written;
+	unsigned int mask = SECTION_BUCKET_SIZE - 1;
+
+	void __iomem *read_addr;
+
+	pes_size = xport_filter_check_pes_size(filter_index);
+	if (pes_size <= 0) {
+		printk(KERN_INFO "pes size = %d, empty now \n", pes_size);
+		return -EFAULT;
+	}
+	if (pes_size > len)
+		pes_size = len;
+
+	byte_written = pes_size;
+
+	up_addr = get_filter_buf_top_addr(filter_index);
+	low_addr = get_filter_buf_base_addr(filter_index);
+
+	rp = xport_readl(FLT_BUF_RP_ADDR(filter_index));
+
+	rp_tog = rp & 0x80000000;
+	rp = rp & 0x7fffffff;
+	if (rp & mask) {	 /* rp is not aligned with 0x1000 */
+		printk(KERN_INFO "rp 0x%08x is not aligned with 0x1000\n", rp);
+		return -EFAULT;
+	}
+
+	while (pes_size > 0) {
+		read_addr = xport_mem_base + (rp - XPORT_MEM_BASE);
+		data = *(unsigned int *) read_addr; /* first 4 byte of bucket header */
+		read_addr += 4;
+		bucket_size = (data & 0xffff);
+		bucket_size -= 4;
+
+		if (bucket_size > pes_size)
+			bucket_size = pes_size;
+
+		if (copy_to_user(buffer, read_addr, bucket_size) > 0) {
+			printk(KERN_INFO " user buffer is not enough \n");
+			return -EFAULT;
+		}
+
+		pes_size -= bucket_size;
+		buffer += bucket_size;
+		rp += SECTION_BUCKET_SIZE;
+
+		if (rp >= up_addr) {
+			rp = low_addr;
+			rp_tog ^= 0x80000000;
+		}
+	}
+
+	xport_writel(FLT_BUF_RP_ADDR(filter_index), rp_tog | rp);
+
+	return byte_written;
+}
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/celestial/xport/xport_filter1900.h linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/xport/xport_filter1900.h
--- linux-linaro-3.4-2012.05-1_original/drivers/celestial/xport/xport_filter1900.h	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/xport/xport_filter1900.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,70 @@
+#ifndef __XPORT_FILTER_H__
+#define __XPORT_FILTER_H__
+
+typedef enum {
+	FILTER_TYPE_NUKOWN = -1,
+	FILTER_TYPE_SECTION = 0,
+	FILTER_TYPE_TS,
+	FILTER_TYPE_PES,
+	FILTER_TYPE_ES
+} XPORT_FILTER_TYPE;
+
+typedef enum {
+	INPUT_CHANNEL_0 = 0,
+	INPUT_CHANNEL_1,
+	INPUT_CHANNEL_2,
+	INPUT_CHANNEL_3	
+} XPORT_INPUT_CHANNEL;
+
+typedef enum {
+    INPUT_DMA0 = 0,
+	INPUT_DMA1
+}XPORT_DMA_INPUT_TYPE ;
+
+
+#define XPORT_IRQ0_CRC_NOTIFY		0x00000100
+#define XPORT_IRQ0_CRC_INDEX		0x00007e00
+#define XPORT_IRQ0_CRC_IDX_SHIFT	0x9
+#define XPORT_IRQ0_FILTER_NOTIFY	0x00008000	/* filter index > 31 */
+#define XPORT_IRQ0_FILTER_INDEX		0x003f0000
+#define XPORT_IRQ0_FILTER_IDX_SHIFT	0x10
+
+
+int xport_filter_reset(unsigned int filter_index);
+
+int xport_filter_set_type(unsigned int filter_index, XPORT_FILTER_TYPE filter_type);
+int xport_filter_set_input(unsigned int filter_index, XPORT_INPUT_CHANNEL input_channel);
+int xport_filter_set_crc(unsigned int filter_index, unsigned int crc_index);
+
+int xport_filter_set_pidx(unsigned int filter_index, unsigned int pid, unsigned int slot);
+
+int xport_filter_set_filter(unsigned int filter_index, unsigned char *filter, unsigned char *mask);
+
+int xport_filter_crc_enable(unsigned int filter_index);
+int xport_filter_crc_disable(unsigned int filter_index);
+int xport_filter_crc_is_enable(unsigned int filter_index);
+
+int xport_filter_enable(unsigned int filter_index, spinlock_t * spin_lock_ptr);
+int xport_filter_disable(unsigned int filter_index, spinlock_t * spin_lock_ptr);
+int xport_filter_is_enable(unsigned int filter_index);
+
+int xport_filter_check_section_number(unsigned int filter_index);
+int xport_filter_check_section_size(unsigned int filter_index);
+int xport_filter_read_section_data(unsigned int filter_index, char __user * buffer, size_t len);
+
+int xport_filter_check_data_size(unsigned int section_filter_id);
+int xport_filter_read_data(unsigned int section_filter_id, char __user * buffer, size_t len);
+
+int xport_filter_check_pes_size(unsigned int filter_index);
+int xport_filter_read_pes_data(unsigned int filter_index, char __user * buffer, size_t len);
+
+int xport_filter_clear_buffer(unsigned int filter_index);
+
+unsigned int get_filter_buf_base_addr(unsigned int filter_index);
+unsigned int get_filter_buf_top_addr(unsigned int filter_index);
+unsigned int get_filter_buf_size(unsigned int filter_index);
+unsigned int get_xport_filter_rp(unsigned int filter_index);
+unsigned int get_xport_filter_wp(unsigned int filter_index);
+
+#endif
+
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/celestial/xport/xport_mips1900.c linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/xport/xport_mips1900.c
--- linux-linaro-3.4-2012.05-1_original/drivers/celestial/xport/xport_mips1900.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/xport/xport_mips1900.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,196 @@
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/miscdevice.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <linux/semaphore.h>
+
+#include <linux/sched.h>
+#include <linux/poll.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+
+#include "xport_mips1900.h"
+#include "xport_drv1900.h"
+
+
+#ifdef CONFIG_ORION_XPORT_DEBUG
+#define DEBUG(n, args...)				\
+	do {						\
+		if (n <= CONFIG_XPORT_DEBUG_VERBOSE)	\
+		printk(KERN_INFO args);		\
+	} while(0)
+#else /* CONFIG_XPORT_DEBUG */
+#define DEBUG(n, args...) do { } while(0)
+#endif
+
+
+typedef enum
+{
+	FW_NO_REPLAY = 0,
+	FW_PREPARED = 1		
+}FW_STATUS;
+
+
+
+DEFINE_SEMAPHORE(mips_cmd_sem);
+
+
+
+/*get enable flag from  request addr in pull time*/
+static unsigned int xport_pull_mips(int addr,unsigned int delay,unsigned int n, struct semaphore *sem)
+{
+	unsigned int ret = FW_PREPARED;
+	unsigned int pull_cnt = n;
+	unsigned int reg_v = 0;
+
+
+	do
+	{/*read enable flag of request info in mail box addr*/
+		reg_v = xport_readl(addr);
+		udelay(delay);
+	}
+	while((pull_cnt-- > 0) && xport_get_bit(reg_v,31));
+
+	if (xport_get_bit(reg_v, 31))
+	{
+		ret = FW_NO_REPLAY;		
+		up(sem);
+	}
+
+
+	return ret;
+}
+
+
+int xport_mips_write(unsigned int cmd, unsigned int req_dat)
+{
+	unsigned int cnt = 1000;
+
+	union firmware_req req ;
+
+	req.val = cmd;
+	req.val = xport_set_bit(xport_set_bit(req.val,31),30);
+	/* bit31 = 1, indicates that will have a request */
+	/* bit30 = 1, indicates that a request will send to firmware */
+
+	if (down_interruptible(&mips_cmd_sem)) {
+		DEBUG(" mips_write error: down_interruptible () \n");
+		return -1;
+	}
+
+	if(FW_NO_REPLAY == xport_pull_mips(MIPS_CMD_REQ,50,cnt,&mips_cmd_sem))
+	{
+		printk("[lixun] mips_write error: timeout \n");
+		return -1;
+	}
+
+
+	//printk("[lixun]cmd = 0x%0x   data = 0x%08x\n", req.val, req_dat);
+
+	xport_writel(MIPS_CMD_DATA, req_dat);	/* write a request to firmware */
+	xport_writel(MIPS_CMD_REQ, req.val);
+
+	up(&mips_cmd_sem);
+
+	return 0;
+}
+
+
+int xport_mips_read(unsigned int cmd, unsigned int *req_dat)
+{
+
+	unsigned int cnt = 1000;
+	union firmware_req req  ;
+
+
+	req.val = cmd;
+	req.val = xport_set_bit(req.val,31) ;
+	/* bit31 = 1, indicates that will have a request */
+	/* bit30 = 0, indicates that get information from firmware */
+
+	if(down_interruptible(&mips_cmd_sem)) 
+	{
+		DEBUG(" mips_read error: down_interruptible () \n");
+		return -1;
+	}
+
+
+	if(FW_NO_REPLAY == xport_pull_mips(MIPS_CMD_REQ,50,cnt,&mips_cmd_sem))
+	{
+		printk(" mips_read error: timeout0 \n");
+		return -1;
+	}
+
+
+	xport_writel(MIPS_CMD_REQ, req.val);	/* send read-request to firmware */
+	udelay(50);
+	cnt = 1000;
+
+
+	if(FW_NO_REPLAY == xport_pull_mips(MIPS_CMD_REQ,50,cnt,&mips_cmd_sem))
+	{
+		printk(" mips_read error: timeout0 \n");
+		return -1;
+	}
+
+
+	*req_dat = xport_readl(MIPS_CMD_DATA);
+	up(&mips_cmd_sem);
+
+	return 0;
+}
+
+int xport_mips_read_ex(unsigned int cmd, unsigned int *req_dat, unsigned int *req_dat2)
+{
+	unsigned int cnt = 1000;
+	union firmware_req req;
+
+	req.val = cmd;
+	req.val = xport_set_bit(req.val,31);
+	/* bit31 = 1, indicates that will have a request */
+	/* bit30 = 0, indicates that get information from firmware */
+
+	if (down_interruptible(&mips_cmd_sem)) {
+		DEBUG(" mips_read error: down_interruptible () \n");
+		return -1;
+	}
+
+	if(FW_NO_REPLAY == xport_pull_mips(MIPS_CMD_REQ,50,cnt,&mips_cmd_sem))
+	{
+		DEBUG(KERN_INFO " mips_read error: timeout0 \n");
+		return -1;   	  
+	}
+
+
+	xport_writel(MIPS_CMD_REQ, req.val);	/* send read-request to firmware */
+	udelay(50);
+	cnt = 1000;
+
+
+	if(FW_NO_REPLAY == xport_pull_mips(MIPS_CMD_REQ,50,cnt,&mips_cmd_sem))
+	{
+		DEBUG(KERN_INFO " mips_read error: timeout1 \n");
+		return -1;   	  
+	}
+
+
+	*req_dat = xport_readl(MIPS_CMD_DATA);
+	*req_dat2 = xport_readl(MIPS_CMD_DATA2);
+	up(&mips_cmd_sem);
+
+	return 0;
+}
+
+EXPORT_SYMBOL(xport_mips_write);
+EXPORT_SYMBOL(xport_mips_read);
+EXPORT_SYMBOL(xport_mips_read_ex);
+
+
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/celestial/xport/xport_mips1900.h linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/xport/xport_mips1900.h
--- linux-linaro-3.4-2012.05-1_original/drivers/celestial/xport/xport_mips1900.h	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/xport/xport_mips1900.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,73 @@
+
+#ifndef __XPORT_MIPS1900_H__
+#define __XPORT_MIPS1900_H__
+
+#include "xport_regs1900.h"
+
+
+/*x stand for channel index. here Max to 19*/
+#define MIPS_CHL_EN(x)                  ((x<<8)|MIPS_OUTCHL_EN)
+
+/****n~(0,11)  x~(0,60) .note: pid0 can be used in every filter.
+  but  pid1-pid11 should be used only in PVR channel (filter 63)**/
+#define MIPS_CHL_PID(n,x)               ((x<<8)|MIPS_OUTCHL_PID(n))
+#define MIPS_CHL_FILTER0(x)             ((x<<8)|MIPS_OUTCHL_FILTER0)
+#define MIPS_CHL_FILTER1(x)             ((x<<8)|MIPS_OUTCHL_FILTER1)
+#define MIPS_CHL_FILTER2(x)             ((x<<8)|MIPS_OUTCHL_FILTER2)
+#define MIPS_CHL_MASK0(x)               ((x<<8)|MIPS_OUTCHL_MASK0)
+#define MIPS_CHL_MASK1(x)               ((x<<8)|MIPS_OUTCHL_MASK1)
+#define MIPS_CHL_MASK2(x)               ((x<<8)|MIPS_OUTCHL_MASK2)
+#define MIPS_CHL_DIR_LOW_ADDR(x)        ((x<<8)|MIPS_OUTCHL_DIR_LOW_ADRR)
+#define MIPS_CHL_DIR_UP_ADDR(x)         ((x<<8)|MIPS_OUTCHL_DIR_UP_ADRR)
+#define MIPS_CHL_WP(x)                  ((x<<8)|MIPS_OUTCHL_DIR_WP)
+#define MIPS_CHL_TC0_ERR_CNT(x)         ((x<<8)|MIPS_OUTCHL_BUF_TC0_ERR_CNT)
+#define MIPS_CHL_TC1_ERR_CNT(x)         ((x<<8)|MIPS_OUTCHL_BUF_TC1_ERR_CNT)
+#define MIPS_CHL_TC2_ERR_CNT(x)         ((x<<8)|MIPS_OUTCHL_BUF_TC2_ERR_CNT)
+#define MIPS_CHL_TC3_ERR_CNT(x)         ((x<<8)|MIPS_OUTCHL_BUF_TC3_ERR_CNT)
+#define MIPS_CHL_ERR_PKT_CNT(x)         ((x<<8)|MIPS_OUTCHL_BUF_ERR_PACKET_CNT)
+#define MIPS_CHL_OUT_PKT_CNT(x)         ((x<<8)|MIPS_OUTCHL_BUF_OUT_PACKET_CNT)
+#define MIPS_CHL_BUF_LOW_ADDR(x)        ((x<<8)|MIPS_OUTCHL_BUF_LOW_ADRR)
+#define MIPS_CHL_BUF_UP_ADDR(x)         ((x<<8)|MIPS_OUTCHL_BUF_UP_ADRR)
+#define MIPS_PCR_PID(x)                 ((x<<8)|MIPS_PCR_PID_ADDR)
+#define MIPS_PCR_GET(x)                 ((x<<8)|MIPS_PCR_GET_ADDR)
+#define MIPS_CHL_CRC_EN(x)              ((x<<8)|MIPS_OUTCHL_CRC_EN)
+#define MIPS_CHL_CRC_NOTIFY_EN(x)       ((x<<8)|MIPS_OUTCHL_CRC_NOTIFY_EN)
+#define MIPS_CHL_DISABLE(x)             ((x<<8)|MIPS_OUTCHL_DISABLE)
+#define MIPS_CHL_SWITCH(x)              ((x<<8)|MIPS_OUTCHL_SWITCH)
+#define MIPS_CHL_EXTERNAL_BASE(x)       (((x)<<8)|MIPS_EXTERNAL_BASE)
+#define MIPS_CHL_BITWISE0(x)            (((x)<<8)|MIPS_OUTCHL_BITWISE0)
+#define MIPS_CHL_BITWISE1(x)            (((x)<<8)|MIPS_OUTCHL_BITWISE1)
+#define MIPS_CHL_BITWISE2(x)            (((x)<<8)|MIPS_OUTCHL_BITWISE2)
+#define MIPS_CHL_FILTER_MAX_SIZE(x)     (((x)<<8)|MIPS_OUTCHL_FILTER_MAX_SIZE) 
+
+
+/**I/D ram addr for storeing firmware message**/
+#define MIPS_FW_WRITE_DATA              (0xc1400000+(0x4000<<2))
+#define MIPS_FW_WRITE_INST              (0xc1400000+(0x2000<<2))
+#define MIPS_FW_EN                      (0xc1400000+(0x6000<<2))
+
+/*firmware appoint MBOX0/1/4 as its info exchange to host for communicate*/
+#define MIPS_CMD_REQ 	                MAIL_BOX_ADDR(0)
+#define MIPS_CMD_DATA	                MAIL_BOX_ADDR(1)
+#define MIPS_CMD_DATA2	                MAIL_BOX_ADDR(4)
+
+
+union firmware_req {
+
+	struct {
+		unsigned int req_type:8;
+		unsigned int output_idx:8;
+		unsigned int reserved:14;
+		unsigned int rw:1;
+		unsigned int enable:1;
+	} bits;
+
+	unsigned int val;
+};
+
+int xport_mips_write(unsigned int cmd, unsigned int req_dat);
+int xport_mips_read(unsigned int cmd, unsigned int *req_dat);
+int xport_mips_read_ex(unsigned int cmd, unsigned int *req_dat, unsigned int *req_dat2);
+
+#endif
+
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/celestial/xport/xport_regs1900.h linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/xport/xport_regs1900.h
--- linux-linaro-3.4-2012.05-1_original/drivers/celestial/xport/xport_regs1900.h	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/celestial/xport/xport_regs1900.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,169 @@
+#ifndef _XPORT_REGS1900_H__
+#define _XPORT_REGS1900_H__
+
+
+#define xport_set_bit(v,n)                (v|(0x1<<(n)))
+#define xport_cls_bit(v,n)                (v&~(0x1<<(n)))
+#define xport_get_bit(v,n)                (((v)>>(n))&0x1)
+#define xport_get_bits(v,m,n)/*m>=n*/     ((v<<(31-m))>>(31-m+n))
+
+#define XPORT_REG_ADDR_BASE         PA_XPORT_REG_BASE
+
+/***********************HW Register Define********************/
+
+/************************Mail Box Addr0-7**********************/
+#define XPORT_REG_OFST              0x4
+#define MAIL_BOX_ADDR(n)            (XPORT_REG_ADDR_BASE+((n)*XPORT_REG_OFST))
+
+
+/************************Xport Config Addr**********************/
+#define XPORT_CFG_ADDR0             (XPORT_REG_ADDR_BASE+0x20)
+#define XPORT_CFG_ADDR1             (XPORT_REG_ADDR_BASE+0x24)
+
+
+/*********************Xport Config to Tuner Addr******************/
+#define XPORT_TUN_STS_ADDR          (XPORT_REG_ADDR_BASE+0x28)
+#define XPORT_TUN_STS_CFG_ADDR      (XPORT_REG_ADDR_BASE+0x2C)
+#define DMA_INPUT0_HEAD_ADDR        (XPORT_REG_ADDR_BASE+0x30)
+#define DMA_INPUT1_HEAD_ADDR        (XPORT_REG_ADDR_BASE+0x34)
+
+
+/*******************Xport Raw Interrupt Reg Addr******************/
+#define XPORT_INT_RAW_REG_ADDR0     (XPORT_REG_ADDR_BASE+0x38)
+#define XPORT_INT_RAW_REG_ADDR1     (XPORT_REG_ADDR_BASE+0x3C)
+
+
+/*******************Xport Interrupt Reg Addr0*********************/
+#define XPORT_INT_REG_ADDR0         (XPORT_REG_ADDR_BASE+0x40)
+#define XPORT_INT_ENB_ADDR0         (XPORT_REG_ADDR_BASE+0x44)
+#define XPORT_INT_SET_ADDR0         (XPORT_REG_ADDR_BASE+0x48)
+#define XPORT_INT_CLS_ADDR0         (XPORT_REG_ADDR_BASE+0x4C)
+
+
+/*******************Xport Interrupt Reg Addr1*********************/
+#define XPORT_INT_REG_ADDR1         (XPORT_REG_ADDR_BASE+0x50)
+#define XPORT_INT_ENB_ADDR1         (XPORT_REG_ADDR_BASE+0x54)
+#define XPORT_INT_SET_ADDR1         (XPORT_REG_ADDR_BASE+0x58)
+#define XPORT_INT_CLS_ADDR1         (XPORT_REG_ADDR_BASE+0x5C)
+#define XPORT_INT_EXT_ADDR          (MAIL_BOX_ADDR(5))
+
+
+/********************Xport  Enable Tuner0/1**********************/
+#define XPORT_TUNER_EN              (XPORT_REG_ADDR_BASE+0x60)
+
+
+/*************Input channel update configure register****************/
+#define XPORT_IN_CHL_UP_CFG         (XPORT_REG_ADDR_BASE+0x64)
+#define XPORT_TSOUT_GAP             (XPORT_REG_ADDR_BASE+0x68)
+
+#define CLK0_STC_HIGH_ADDR          (XPORT_REG_ADDR_BASE+0x80)
+#define CLK0_STC_LOW_ADDR           (XPORT_REG_ADDR_BASE+0x84)
+
+#define CLK0_PCR_HIGH_ADDR          (XPORT_REG_ADDR_BASE+0x88)
+#define CLK0_PCR_LOW_ADDR           (XPORT_REG_ADDR_BASE+0x8C)
+
+#define CLK0_PCR_CNT_ADDR           (XPORT_REG_ADDR_BASE+0x90)
+#define CLK0_PCR_INTERVAL_ADDR      (XPORT_REG_ADDR_BASE+0x94)
+
+
+/*************Xport Clock Component Addr************************/
+#define CLK0_DELTA_CYL_ADDR         (XPORT_REG_ADDR_BASE+0x98)
+#define CLK0_DELTA_CYL_THRS_ADDR    (XPORT_REG_ADDR_BASE+0x9C)
+#define CLK0_PWM_CTRL_ADDR          (XPORT_REG_ADDR_BASE+0xA4)
+#define CLK0_PWM_CWORD_ADDR         (XPORT_REG_ADDR_BASE+0xA8)
+#define CLK0_PCR_VALID_ADDR         (XPORT_REG_ADDR_BASE+0xAC)
+#define CLK0_REC_DELAY_TIME_ADDR    (XPORT_REG_ADDR_BASE+0xB0)
+#define CLK0_CLK_CNT_ADDR           (XPORT_REG_ADDR_BASE+0xB4)
+
+
+/**********Xport input channel generate macro Addr *****************/
+#define IN_CHL_BASE_ADDR(n)         ((n)==0?IN_CHL0_BASE_ADDR: IN_CHL1_BASE_ADDR)
+#define IN_CHL_CFG_ADDR(n)          ((n)==0?IN_CHL0_CFG_ADDR : IN_CHL1_CFG_ADDR)
+#define IN_CHL_RP_ADDR(n)           ((n)==0?IN_CHL0_RP_ADDR  : IN_CHL1_RP_ADDR)
+#define IN_CHL_WP_ADDR(n)           ((n)==0?IN_CHL0_WP_ADDR  : IN_CHL1_WP_ADDR)
+
+
+/*************Xport input Channel0 Option Addr ********************/
+#define IN_CHL0_BASE_ADDR           (XPORT_REG_ADDR_BASE+0x100)
+#define IN_CHL0_CFG_ADDR            (XPORT_REG_ADDR_BASE+0x104)
+#define IN_CHL0_RP_ADDR             (XPORT_REG_ADDR_BASE+0x108)
+#define IN_CHL0_WP_ADDR             (XPORT_REG_ADDR_BASE+0x10C)
+
+
+/*************Xport input Channel1 Option Addr ********************/
+#define IN_CHL1_BASE_ADDR           (XPORT_REG_ADDR_BASE+0x118)
+#define IN_CHL1_CFG_ADDR            (XPORT_REG_ADDR_BASE+0x11C)
+#define IN_CHL1_RP_ADDR             (XPORT_REG_ADDR_BASE+0x120)
+#define IN_CHL1_WP_ADDR             (XPORT_REG_ADDR_BASE+0x124)
+
+
+/****xunli: direct dma mode ****/
+#define XPORT_CHL_DMA_WP_ADDR(n)    ((n)<2?MAIL_BOX_ADDR(n+2): MAIL_BOX_ADDR(n+4))
+#define XPORT_CHL_DMA0_WP_ADDR      (MAIL_BOX_ADDR(2))
+#define XPORT_CHL_DMA1_WP_ADDR      (MAIL_BOX_ADDR(3))
+#define XPORT_CHL_DMA2_WP_ADDR      (MAIL_BOX_ADDR(6))
+#define XPORT_CHL_DMA3_WP_ADDR      (MAIL_BOX_ADDR(7))
+
+
+/********For Setting Xport filter Group0/1 (0-63/64-128)**************/
+
+#define __PID_FILTER__(n) (n>63?PID_GRP1_FLTR(n): PID_GRP0_FLTR(n))
+/***Set Pid filter Reg 0-63***/
+#define FLTR_PID_ADDR_BASE0         (0x180+XPORT_REG_ADDR_BASE)
+#define PID_GRP0_FLTR(n)            (FLTR_PID_ADDR_BASE0+(XPORT_REG_OFST*(n)))
+
+
+/***Set Pid filter Reg 64-127***/
+#define FLTR_PID_ADDR_BASE1         (0xC00+XPORT_REG_ADDR_BASE)
+#define PID_GRP1_FLTR(n)            (FLTR_PID_ADDR_BASE1+(XPORT_REG_OFST*(n-64)))
+
+
+/******************Xport Descramble Reg Addr Base***********************/
+#define DSCRB_REG_ODD_BASE          (XPORT_REG_ADDR_BASE+0x280)
+#define DSCRB_REG_EVN_BASE          (XPORT_REG_ADDR_BASE+0x298)
+
+/**i~(0,5) for Key Cnt.   j~(0,7) for Group Cnt**/
+#define __DSCRB_ODD_ADDR_(i, j)     (DSCRB_REG_ODD_BASE+(XPORT_REG_OFST*(i))+(0x30*(j)))
+#define __DSCRB_EVN_ADDR_(i, j)     (DSCRB_REG_EVN_BASE+(XPORT_REG_OFST*(i))+(0x30*(j)))
+
+
+/**32 output channel define ?**/
+/******************MIPS software Register define************************/
+
+#define MIPS_OUTCHL_EN                   0x0000
+#define MIPS_OUTCHL_FILTER0              0x0001
+#define MIPS_OUTCHL_FILTER1              0x0002
+#define MIPS_OUTCHL_FILTER2              0x0003
+#define MIPS_OUTCHL_MASK0                0x0004
+#define MIPS_OUTCHL_MASK1                0x0005
+#define MIPS_OUTCHL_MASK2                0x0006
+#define MIPS_OUTCHL_DIR_LOW_ADRR         0x0007
+#define MIPS_OUTCHL_DIR_UP_ADRR          0x0008
+#define MIPS_OUTCHL_DIR_WP               0x0009
+#define MIPS_OUTCHL_BUF_TC0_ERR_CNT      0x000a
+#define MIPS_OUTCHL_BUF_TC1_ERR_CNT      0x000b
+#define MIPS_OUTCHL_BUF_TC2_ERR_CNT      0x000c
+#define MIPS_OUTCHL_BUF_TC3_ERR_CNT      0x000d
+#define MIPS_OUTCHL_BUF_ERR_PACKET_CNT   0x000e
+#define MIPS_OUTCHL_BUF_OUT_PACKET_CNT   0x000f
+#define MIPS_OUTCHL_BUF_LOW_ADRR         0x0010
+#define MIPS_OUTCHL_BUF_UP_ADRR          0x0011
+#define MIPS_PCR_PID_ADDR                0x0012
+#define MIPS_PCR_GET_ADDR                0x0013
+#define MIPS_OUTCHL_CRC_EN               0x0014
+#define MIPS_OUTCHL_CRC_NOTIFY_EN        0x0015
+#define MIPS_OUTCHL_PID_BASE             0x0016
+
+/*n~(0,16)*/
+#define MIPS_OUTCHL_PID(n)               (MIPS_OUTCHL_PID_BASE+(n))
+#define MIPS_OUTCHL_DISABLE              (MIPS_OUTCHL_PID_BASE + 0x20)
+#define MIPS_OUTCHL_SWITCH               (MIPS_OUTCHL_PID_BASE + 0x21)
+#define  MIPS_EXTERNAL_BASE              (MIPS_OUTCHL_PID_BASE + 0x22)
+#define  MIPS_OUTCHL_BITWISE0            (MIPS_OUTCHL_PID_BASE + 0x23)
+#define  MIPS_OUTCHL_BITWISE1            (MIPS_OUTCHL_PID_BASE + 0x24)
+#define  MIPS_OUTCHL_BITWISE2            (MIPS_OUTCHL_PID_BASE + 0x25)
+#define  MIPS_OUTCHL_FILTER_MAX_SIZE     (MIPS_OUTCHL_PID_BASE + 0x26)
+
+#define MIPS_INCHL_TYPE                  (MIPS_OUTCHL_PID_BASE + 0x27)
+#endif
+
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/cpufreq/cnc1900_cpufreq_drv.c linux-linaro-3.4-2012.05-1_cavium/drivers/cpufreq/cnc1900_cpufreq_drv.c
--- linux-linaro-3.4-2012.05-1_original/drivers/cpufreq/cnc1900_cpufreq_drv.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/cpufreq/cnc1900_cpufreq_drv.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,200 @@
+/*
+ * Copyright 2013 caviumnetworks,inc
+ *
+ * Cavium CNC1900 CPUfreq Support
+ *
+ * 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.
+ */
+
+#define pr_fmt(fmt) "cpufreq: " fmt
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/cpufreq.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/regulator/consumer.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/vmalloc.h>
+
+static struct cpufreq_frequency_table *cnc1900_freq_table = NULL;
+#if 0
+[] = {
+	{ 0,  27000  },
+	{ 1,  54000  },
+	{ 2,  81000  },
+	{ 3,  108000 },
+	{ 4,  135000 },
+	{ 5,  162000 },
+	{ 6,  189000 },
+	{ 7,  216000 },
+	{ 8,  243000 },
+	{ 9,  270000 },
+	{ 10, 297000 },
+	{ 11, 324000 },
+	{ 12, 351000 },
+	{ 13, 378000 },
+	{ 14, 405000 },
+	{ 15, 432000 },
+	{ 16, 459000 },
+	{ 17, 486000 },
+	{ 18, 513000 },
+	{ 19, 540000 },
+	{ 20, 567000 },
+	{ 21, 594000 },
+	{ 22, 621000 },
+	{ 23, 648000 },
+#if (1==CONFIG_CACHE_L2X0)
+	{ 24, 675000 },
+	{ 25, 702000 },
+	{ 26, 729000 },
+	{ 27, 756000 },
+	{ 28, 783000 },
+	{ 29, 810000 },
+#endif		
+	{ 0, CPUFREQ_TABLE_END },
+};
+#endif
+extern unsigned int cnc1900_get_cpufreq(void);
+extern void cnc1900_set_cpufreq(unsigned int target_freq);
+extern int cnc1900_cpufreq_plat_init(void);
+
+static int cnc1900_cpufreq_verify_speed(struct cpufreq_policy *policy)
+{
+	if (policy->cpu != 0)
+		return -EINVAL;
+
+	return cpufreq_frequency_table_verify(policy, cnc1900_freq_table);
+}
+
+static unsigned int cnc1900_cpufreq_get_speed(unsigned int cpu)
+{
+	if (cpu != 0)
+		return 0;
+
+	return cnc1900_get_cpufreq() / 1000;
+}
+
+static int cnc1900_cpufreq_set_target(struct cpufreq_policy *policy,
+				      unsigned int target_freq,
+				      unsigned int relation)
+{
+	int ret;
+	unsigned int i;
+	struct cpufreq_freqs freqs;
+
+	ret = cpufreq_frequency_table_target(policy, cnc1900_freq_table,
+					     target_freq, relation, &i);
+	if (ret != 0)
+		return ret;
+
+	freqs.cpu = 0;
+	freqs.old = cnc1900_get_cpufreq() / 1000;
+	freqs.new = cnc1900_freq_table[i].frequency;
+	freqs.flags = 0;
+
+	if (freqs.old == freqs.new)
+		return 0;
+
+	pr_debug("Transition %d-%dkHz\n", freqs.old, freqs.new);
+
+	cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+
+	cnc1900_set_cpufreq(freqs.new * 1000);
+
+	cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+
+	pr_debug("Set actual frequency %dkHz\n",freqs.new);
+
+	return 0;
+}
+
+static int cnc1900_cpufreq_driver_init(struct cpufreq_policy *policy)
+{
+	int ret;
+
+	if (policy->cpu != 0)
+		return -EINVAL;
+
+	if (cnc1900_freq_table == NULL) {
+		pr_err("No frequency information for this CPU\n");
+		return -ENODEV;
+	}
+	policy->cur = cnc1900_get_cpufreq() / 1000;
+
+	policy->cpuinfo.transition_latency = 300 * 1000;
+
+	ret = cpufreq_frequency_table_cpuinfo(policy, cnc1900_freq_table);
+	if (ret != 0) {
+		pr_err("Failed to configure frequency table: %d\n",
+		       ret);
+	}
+
+	cnc1900_cpufreq_plat_init();
+
+	return ret;
+}
+
+static struct cpufreq_driver cnc1900_cpufreq_driver = {
+	.owner		= THIS_MODULE,
+	.flags      = 0,
+	.verify		= cnc1900_cpufreq_verify_speed,
+	.target		= cnc1900_cpufreq_set_target,
+	.get		= cnc1900_cpufreq_get_speed,
+	.init		= cnc1900_cpufreq_driver_init,
+	.name		= "cnc1900 cpufreq",
+};
+
+/*
+ * This function prepare available cpu frequencies based on the initial frequency for cnc1900.
+ * This module is statically linked, so we don't consider the initial frequency changing by module dynamicly load. 
+ */
+static void __init cnc1900_cpufreq_prepare_freq_tbl(void)
+{
+#define CNC1900_FREQ_STEP   27000
+    unsigned int freq;
+    unsigned int min_freq = CNC1900_FREQ_STEP;
+    unsigned int i;
+    unsigned int max_freq = cnc1900_get_cpufreq() / 1000;
+    unsigned int freq_cnt = 0;
+
+    WARN_ON(NULL != cnc1900_freq_table);
+    freq_cnt = max_freq/CNC1900_FREQ_STEP;
+    cnc1900_freq_table = vmalloc(freq_cnt*sizeof(struct cpufreq_frequency_table));
+    
+    for(i = 0,freq = min_freq;freq <= max_freq;i++,freq += CNC1900_FREQ_STEP)
+    {
+      cnc1900_freq_table[i].index = i;
+      cnc1900_freq_table[i].frequency = freq;
+    }
+
+    cnc1900_freq_table[i].index = 0;
+    cnc1900_freq_table[i].frequency = CPUFREQ_TABLE_END;
+  
+    printk("cnc1900 cpufreq init,freq interval=[%dKHz,%dKHz],step=%dKHz.\n",min_freq,cnc1900_freq_table[i-1].frequency,CNC1900_FREQ_STEP);
+}
+
+static void __exit cnc1900_cpufreq_exit(void)
+{
+  vfree(cnc1900_freq_table);
+  cnc1900_freq_table=NULL;
+}
+
+static int __init cnc1900_cpufreq_init(void)
+{
+  cnc1900_cpufreq_prepare_freq_tbl();
+	return cpufreq_register_driver(&cnc1900_cpufreq_driver);
+}
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Yu.Lei <yu.lei@caviumnetworks.com>");
+MODULE_DESCRIPTION("cpufreq driver for caviumnetworks's cnc1900 SOC");
+
+module_init(cnc1900_cpufreq_init);
+module_exit(cnc1900_cpufreq_exit);
+
+
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/cpufreq/Kconfig.arm linux-linaro-3.4-2012.05-1_cavium/drivers/cpufreq/Kconfig.arm
--- linux-linaro-3.4-2012.05-1_original/drivers/cpufreq/Kconfig.arm	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/cpufreq/Kconfig.arm	2014-07-29 17:28:38.819972000 +0800
@@ -76,3 +76,12 @@
 	help
 	  This adds the CPUFreq driver for Samsung EXYNOS5250
 	  SoC.
+
+config ARM_CELESTIAL_CNC1900_CPUFREQ
+	bool "CELESTIAL_CNC1900"
+	depends on MACH_CELESTIAL_CNC1900 && CACHE_L2X0
+	default y
+	help
+	  This adds the CPUFreq driver for CELESTIAL CNC1900 SoC.
+
+	  If in doubt, say N.
\ No newline at end of file
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/cpufreq/Makefile linux-linaro-3.4-2012.05-1_cavium/drivers/cpufreq/Makefile
--- linux-linaro-3.4-2012.05-1_original/drivers/cpufreq/Makefile	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/cpufreq/Makefile	2014-07-29 17:28:38.819972000 +0800
@@ -51,6 +51,7 @@
 obj-$(CONFIG_ARM_EXYNOS4X12_CPUFREQ)	+= exynos4x12-cpufreq.o
 obj-$(CONFIG_ARM_EXYNOS5250_CPUFREQ)	+= exynos5250-cpufreq.o
 obj-$(CONFIG_ARM_OMAP2PLUS_CPUFREQ)     += omap-cpufreq.o
+obj-$(CONFIG_ARM_CELESTIAL_CNC1900_CPUFREQ)     += cnc1900_cpufreq_drv.o
 
 ##################################################################################
 # PowerPC platform drivers
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/hid/hid-core.c linux-linaro-3.4-2012.05-1_cavium/drivers/hid/hid-core.c
--- linux-linaro-3.4-2012.05-1_original/drivers/hid/hid-core.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/hid/hid-core.c	2014-07-29 17:28:38.819972000 +0800
@@ -1158,7 +1158,7 @@
 static bool hid_match_one_id(struct hid_device *hdev,
 		const struct hid_device_id *id)
 {
-	return id->bus == hdev->bus &&
+	return (id->bus == HID_BUS_ANY || id->bus == hdev->bus) &&
 		(id->vendor == HID_ANY_ID || id->vendor == hdev->vendor) &&
 		(id->product == HID_ANY_ID || id->product == hdev->product);
 }
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/hid/hid-generic.c linux-linaro-3.4-2012.05-1_cavium/drivers/hid/hid-generic.c
--- linux-linaro-3.4-2012.05-1_original/drivers/hid/hid-generic.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/hid/hid-generic.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,60 @@
+/*
+ *  HID support for Linux
+ *
+ *  Copyright (c) 1999 Andreas Gal
+ *  Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz>
+ *  Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc
+ *  Copyright (c) 2007-2008 Oliver Neukum
+ *  Copyright (c) 2006-2012 Jiri Kosina
+ *  Copyright (c) 2012 Henrik Rydberg
+ *  Copyright (c) 2014 Andrzej Kaczmarek
+ */
+
+/*
+ * 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/slab.h>
+#include <linux/kernel.h>
+#include <asm/unaligned.h>
+#include <asm/byteorder.h>
+
+#include <linux/hid.h>
+
+static const struct hid_device_id hid_generic_devices[] = {
+	{ HID_DEVICE(HID_BUS_ANY, HID_ANY_ID, HID_ANY_ID) },
+	{ }
+};
+MODULE_DEVICE_TABLE(hid, hid_generic_devices);
+
+static struct hid_driver hid_generic_driver = {
+	.name = "hid-generic",
+	.id_table = hid_generic_devices,
+};
+
+static int __init hid_generic_init2(void)
+{
+	int ret;
+
+	ret = hid_register_driver(&hid_generic_driver);
+	if (ret)
+		pr_err("can't register hid-generic driver\n");
+
+	return ret;
+}
+
+static void __exit hid_generic_exit2(void)
+{
+	hid_unregister_driver(&hid_generic_driver);
+}
+
+module_init(hid_generic_init2);
+module_exit(hid_generic_exit2);
+
+MODULE_AUTHOR("Henrik Rydberg");
+MODULE_DESCRIPTION("HID generic driver");
+MODULE_LICENSE("GPL");
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/hid/Makefile linux-linaro-3.4-2012.05-1_cavium/drivers/hid/Makefile
--- linux-linaro-3.4-2012.05-1_original/drivers/hid/Makefile	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/hid/Makefile	2014-07-29 17:28:38.819972000 +0800
@@ -33,6 +33,7 @@
 	hid-wiimote-y	+= hid-wiimote-debug.o
 endif
 
+obj-y				+= hid-generic.o
 obj-$(CONFIG_HID_A4TECH)	+= hid-a4tech.o
 obj-$(CONFIG_HID_ACRUX)		+= hid-axff.o
 obj-$(CONFIG_HID_APPLE)		+= hid-apple.o
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/input/evdev.c linux-linaro-3.4-2012.05-1_cavium/drivers/input/evdev.c
--- linux-linaro-3.4-2012.05-1_original/drivers/input/evdev.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/input/evdev.c	2014-07-29 17:28:38.819972000 +0800
@@ -1084,8 +1084,20 @@
 
 MODULE_DEVICE_TABLE(input, evdev_ids);
 
+static bool evdev_match(struct input_handler *handler, struct input_dev *dev)
+{
+        #define VID_EETI 0x0EEF
+        /* Avoid EETI USB touchscreens */
+        if ((BUS_USB == dev->id.bustype) && (VID_EETI == dev->id.vendor))
+        {
+                return false;
+        }
+        return true;
+}
+
 static struct input_handler evdev_handler = {
 	.event		= evdev_event,
+        .match          = evdev_match,/* Added by EETI */
 	.connect	= evdev_connect,
 	.disconnect	= evdev_disconnect,
 	.fops		= &evdev_fops,
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/input/joydev.c linux-linaro-3.4-2012.05-1_cavium/drivers/input/joydev.c
--- linux-linaro-3.4-2012.05-1_original/drivers/input/joydev.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/input/joydev.c	2014-07-29 17:28:38.819972000 +0800
@@ -791,6 +791,11 @@
 	if (test_bit(EV_KEY, dev->evbit) && test_bit(BTN_DIGI, dev->keybit))
 		return false;
 
+        /* Avoid EETI virtual devices */
+#define VID_EETI 0x0EEF
+        if ((BUS_VIRTUAL == dev->id.bustype) && (VID_EETI == dev->id.vendor))
+                return false;
+
 	return true;
 }
 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/input/mousedev.c linux-linaro-3.4-2012.05-1_cavium/drivers/input/mousedev.c
--- linux-linaro-3.4-2012.05-1_original/drivers/input/mousedev.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/input/mousedev.c	2014-07-29 17:28:38.819972000 +0800
@@ -1054,8 +1054,25 @@
 
 MODULE_DEVICE_TABLE(input, mousedev_ids);
 
+static bool mousedev_match(struct input_handler *handler, struct input_dev *dev)
+{
+#define VID_EETI 0x0EEF
+        /* Avoid EETI USB touchscreens */
+        if ((BUS_USB == dev->id.bustype) && (VID_EETI == dev->id.vendor))
+        {
+                return false;
+        }
+        /* Avoid EETI virtual devices */
+        if ((BUS_VIRTUAL == dev->id.bustype) && (VID_EETI == dev->id.vendor))
+        {
+                return false;
+        }
+        return true;
+}
+
 static struct input_handler mousedev_handler = {
 	.event =	mousedev_event,
+        .match =        mousedev_match,/* Added by EETI */
 	.connect =	mousedev_connect,
 	.disconnect =	mousedev_disconnect,
 	.fops =		&mousedev_fops,
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/Kconfig linux-linaro-3.4-2012.05-1_cavium/drivers/Kconfig
--- linux-linaro-3.4-2012.05-1_original/drivers/Kconfig	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/Kconfig	2014-07-29 17:28:38.819972000 +0800
@@ -144,4 +144,6 @@
 
 source "drivers/gator/Kconfig"
 
+source "drivers/celestial/Kconfig"
+
 endmenu
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/Makefile linux-linaro-3.4-2012.05-1_cavium/drivers/Makefile
--- linux-linaro-3.4-2012.05-1_original/drivers/Makefile	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/Makefile	2014-07-29 17:28:38.819972000 +0800
@@ -137,3 +137,5 @@
 obj-$(CONFIG_PM_DEVFREQ)	+= devfreq/
 
 obj-$(CONFIG_GATOR)		+= gator/
+#some celestial driver
+obj-y				+= celestial/
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/misc/Kconfig linux-linaro-3.4-2012.05-1_cavium/drivers/misc/Kconfig
--- linux-linaro-3.4-2012.05-1_original/drivers/misc/Kconfig	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/misc/Kconfig	2014-07-29 17:28:38.819972000 +0800
@@ -517,7 +517,11 @@
 	---help---
 	 Creates an rfkill entry in sysfs for power control of Bluetooth
 	 TI wl127x chips.
-	 
+
+config ANDROID_PMEM
+    bool "Android Pmem Allocator"
+    default n
+
 source "drivers/misc/c2port/Kconfig"
 source "drivers/misc/eeprom/Kconfig"
 source "drivers/misc/cb710/Kconfig"
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/misc/Makefile linux-linaro-3.4-2012.05-1_cavium/drivers/misc/Makefile
--- linux-linaro-3.4-2012.05-1_original/drivers/misc/Makefile	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/misc/Makefile	2014-07-29 17:28:38.819972000 +0800
@@ -52,3 +52,4 @@
 obj-$(CONFIG_MAX8997_MUIC)	+= max8997-muic.o
 obj-$(CONFIG_WL127X_RFKILL)	+= wl127x-rfkill.o
 obj-$(CONFIG_SENSORS_AK8975)	+= akm8975.o
+obj-$(CONFIG_ANDROID_PMEM)      += pmem.o
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/misc/pmem.c linux-linaro-3.4-2012.05-1_cavium/drivers/misc/pmem.c
--- linux-linaro-3.4-2012.05-1_original/drivers/misc/pmem.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/misc/pmem.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,1355 @@
+/* drivers/android/pmem.c
+ *
+ * Copyright (C) 2007 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ *
+ */
+
+#include <linux/miscdevice.h>
+#include <linux/platform_device.h>
+#include <linux/fs.h>
+#include <linux/file.h>
+#include <linux/mm.h>
+#include <linux/list.h>
+#include <linux/mutex.h>
+#include <linux/debugfs.h>
+#include <linux/android_pmem.h>
+#include <linux/mempolicy.h>
+#include <linux/sched.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/cacheflush.h>
+
+#define PMEM_MAX_DEVICES 10
+#define PMEM_MAX_ORDER 128
+#define PMEM_MIN_ALLOC PAGE_SIZE
+
+#define PMEM_DEBUG 1
+
+/* indicates that a refernce to this file has been taken via get_pmem_file,
+ * the file should not be released until put_pmem_file is called */
+#define PMEM_FLAGS_BUSY 0x1
+/* indicates that this is a suballocation of a larger master range */
+#define PMEM_FLAGS_CONNECTED 0x1 << 1
+/* indicates this is a master and not a sub allocation and that it is mmaped */
+#define PMEM_FLAGS_MASTERMAP 0x1 << 2
+/* submap and unsubmap flags indicate:
+ * 00: subregion has never been mmaped
+ * 10: subregion has been mmaped, reference to the mm was taken
+ * 11: subretion has ben released, refernece to the mm still held
+ * 01: subretion has been released, reference to the mm has been released
+ */
+#define PMEM_FLAGS_SUBMAP 0x1 << 3
+#define PMEM_FLAGS_UNSUBMAP 0x1 << 4
+
+struct pmem_data {
+    /* in alloc mode: an index into the bitmap
+     * in no_alloc mode: the size of the allocation */
+    int index;
+    /* see flags above for descriptions */
+    unsigned int flags;
+    /* protects this data field, if the mm_mmap sem will be held at the
+     * same time as this sem, the mm sem must be taken first (as this is
+     * the order for vma_open and vma_close ops */
+    struct rw_semaphore sem;
+    /* info about the mmaping process */
+    struct vm_area_struct *vma;
+    /* task struct of the mapping process */
+    struct task_struct *task;
+    /* process id of teh mapping process */
+    pid_t pid;
+    /* file descriptor of the master */
+    int master_fd;
+    /* file struct of the master */
+    struct file *master_file;
+    /* a list of currently available regions if this is a suballocation */
+    struct list_head region_list;
+    /* a linked list of data so we can access them for debugging */
+    struct list_head list;
+#if PMEM_DEBUG
+    int ref;
+#endif
+};
+
+struct pmem_bits {
+    unsigned allocated:1;           /* 1 if allocated, 0 if free */
+    unsigned order:7;               /* size of the region in pmem space */
+};
+
+struct pmem_region_node {
+    struct pmem_region region;
+    struct list_head list;
+};
+
+#define PMEM_DEBUG_MSGS 0
+#if PMEM_DEBUG_MSGS
+#define DLOG(fmt,args...) \
+    do { printk(KERN_INFO "[%s:%s:%d] "fmt, __FILE__, __func__, __LINE__, \
+##args); } \
+while (0)
+#else
+#define DLOG(x...) do {} while (0)
+#endif
+
+struct pmem_info {
+    struct miscdevice dev;
+    /* physical start address of the remaped pmem space */
+    unsigned long base;
+    /* vitual start address of the remaped pmem space */
+    unsigned char __iomem *vbase;
+    /* total size of the pmem space */
+    unsigned long size;
+    /* number of entries in the pmem space */
+    unsigned long num_entries;
+    /* pfn of the garbage page in memory */
+    unsigned long garbage_pfn;
+    /* index of the garbage page in the pmem space */
+    int garbage_index;
+    /* the bitmap for the region indicating which entries are allocated
+     * and which are free */
+    struct pmem_bits *bitmap;
+    /* indicates the region should not be managed with an allocator */
+    unsigned no_allocator;
+    /* indicates maps of this region should be cached, if a mix of
+     * cached and uncached is desired, set this and open the device with
+     * O_SYNC to get an uncached region */
+    unsigned cached;
+    unsigned buffered;
+    /* in no_allocator mode the first mapper gets the whole space and sets
+     * this flag */
+    unsigned allocated;
+    /* for debugging, creates a list of pmem file structs, the
+     * data_list_lock should be taken before pmem_data->sem if both are
+     * needed */
+    struct mutex data_list_lock;
+    struct list_head data_list;
+    /* pmem_sem protects the bitmap array
+     * a write lock should be held when modifying entries in bitmap
+     * a read lock should be held when reading data from bits or
+     * dereferencing a pointer into bitmap
+     *
+     * pmem_data->sem protects the pmem data of a particular file
+     * Many of the function that require the pmem_data->sem have a non-
+     * locking version for when the caller is already holding that sem.
+     *
+     * IF YOU TAKE BOTH LOCKS TAKE THEM IN THIS ORDER:
+     * down(pmem_data->sem) => down(bitmap_sem)
+     */
+    struct rw_semaphore bitmap_sem;
+
+    long (*ioctl)(struct file *, unsigned int, unsigned long);
+    int (*release)(struct inode *, struct file *);
+};
+
+static struct pmem_info pmem[PMEM_MAX_DEVICES];
+static int id_count;
+
+struct platform_device *pmem_dev = NULL;
+
+#define PMEM_IS_FREE(id, index) !(pmem[id].bitmap[index].allocated)
+#define PMEM_ORDER(id, index) pmem[id].bitmap[index].order
+#define PMEM_BUDDY_INDEX(id, index) (index ^ (1 << PMEM_ORDER(id, index)))
+#define PMEM_NEXT_INDEX(id, index) (index + (1 << PMEM_ORDER(id, index)))
+#define PMEM_OFFSET(index) (index * PMEM_MIN_ALLOC)
+#define PMEM_START_ADDR(id, index) (PMEM_OFFSET(index) + pmem[id].base)
+#define PMEM_LEN(id, index) ((1 << PMEM_ORDER(id, index)) * PMEM_MIN_ALLOC)
+#define PMEM_END_ADDR(id, index) (PMEM_START_ADDR(id, index) + \
+        PMEM_LEN(id, index))
+#define PMEM_START_VADDR(id, index) (PMEM_OFFSET(id, index) + pmem[id].vbase)
+#define PMEM_END_VADDR(id, index) (PMEM_START_VADDR(id, index) + \
+        PMEM_LEN(id, index))
+#define PMEM_REVOKED(data) (data->flags & PMEM_FLAGS_REVOKED)
+#define PMEM_IS_PAGE_ALIGNED(addr) (!((addr) & (~PAGE_MASK)))
+#define PMEM_IS_SUBMAP(data) ((data->flags & PMEM_FLAGS_SUBMAP) && \
+        (!(data->flags & PMEM_FLAGS_UNSUBMAP)))
+
+static int pmem_release(struct inode *, struct file *);
+static int pmem_mmap(struct file *, struct vm_area_struct *);
+static int pmem_open(struct inode *, struct file *);
+static long pmem_ioctl(struct file *, unsigned int, unsigned long);
+
+struct file_operations pmem_fops = {
+    .release = pmem_release,
+    .mmap = pmem_mmap,
+    .open = pmem_open,
+    .unlocked_ioctl = pmem_ioctl,
+};
+
+static int get_id(struct file *file)
+{
+    return MINOR(file->f_dentry->d_inode->i_rdev);
+}
+
+int is_pmem_file(struct file *file)
+{
+    int id;
+
+    if (unlikely(!file || !file->f_dentry || !file->f_dentry->d_inode))
+        return 0;
+    id = get_id(file);
+    if (unlikely(id >= PMEM_MAX_DEVICES))
+        return 0;
+    if (unlikely(file->f_dentry->d_inode->i_rdev !=
+                MKDEV(MISC_MAJOR, pmem[id].dev.minor)))
+        return 0;
+    return 1;
+}
+
+static int has_allocation(struct file *file)
+{
+    struct pmem_data *data;
+    /* check is_pmem_file first if not accessed via pmem_file_ops */
+
+    if (unlikely(!file->private_data))
+        return 0;
+    data = (struct pmem_data *)file->private_data;
+    if (unlikely(data->index < 0))
+        return 0;
+    return 1;
+}
+
+static int is_master_owner(struct file *file)
+{
+    struct file *master_file;
+    struct pmem_data *data;
+    int put_needed, ret = 0;
+
+    if (!is_pmem_file(file) || !has_allocation(file))
+        return 0;
+    data = (struct pmem_data *)file->private_data;
+    if (PMEM_FLAGS_MASTERMAP & data->flags)
+        return 1;
+    master_file = fget_light(data->master_fd, &put_needed);
+    if (master_file && data->master_file == master_file)
+        ret = 1;
+    fput_light(master_file, put_needed);
+    return ret;
+}
+
+static int pmem_free(int id, int index)
+{
+    /* caller should hold the write lock on pmem_sem! */
+    int buddy, curr = index;
+    DLOG("index %d\n", index);
+
+    if (pmem[id].no_allocator) {
+        pmem[id].allocated = 0;
+        return 0;
+    }
+    /* clean up the bitmap, merging any buddies */
+    pmem[id].bitmap[curr].allocated = 0;
+    /* find a slots buddy Buddy# = Slot# ^ (1 << order)
+     * if the buddy is also free merge them
+     * repeat until the buddy is not free or end of the bitmap is reached
+     */
+    do {
+        buddy = PMEM_BUDDY_INDEX(id, curr);
+        if (PMEM_IS_FREE(id, buddy) &&
+                PMEM_ORDER(id, buddy) == PMEM_ORDER(id, curr)) {
+            PMEM_ORDER(id, buddy)++;
+            PMEM_ORDER(id, curr)++;
+            curr = min(buddy, curr);
+        } else {
+            break;
+        }
+    } while (curr < pmem[id].num_entries);
+
+    return 0;
+}
+
+static void pmem_revoke(struct file *file, struct pmem_data *data);
+
+static int pmem_release(struct inode *inode, struct file *file)
+{
+    struct pmem_data *data = (struct pmem_data *)file->private_data;
+    struct pmem_region_node *region_node;
+    struct list_head *elt, *elt2;
+    int id = get_id(file), ret = 0;
+
+
+    mutex_lock(&pmem[id].data_list_lock);
+    /* if this file is a master, revoke all the memory in the connected
+     *  files */
+    if (PMEM_FLAGS_MASTERMAP & data->flags) {
+        struct pmem_data *sub_data;
+        list_for_each(elt, &pmem[id].data_list) {
+            sub_data = list_entry(elt, struct pmem_data, list);
+            down_read(&sub_data->sem);
+            if (PMEM_IS_SUBMAP(sub_data) &&
+                    file == sub_data->master_file) {
+                up_read(&sub_data->sem);
+                pmem_revoke(file, sub_data);
+            }  else
+                up_read(&sub_data->sem);
+        }
+    }
+    list_del(&data->list);
+    mutex_unlock(&pmem[id].data_list_lock);
+
+
+    down_write(&data->sem);
+
+    /* if its not a conencted file and it has an allocation, free it */
+    if (!(PMEM_FLAGS_CONNECTED & data->flags) && has_allocation(file)) {
+        down_write(&pmem[id].bitmap_sem);
+        ret = pmem_free(id, data->index);
+        up_write(&pmem[id].bitmap_sem);
+    }
+
+    /* if this file is a submap (mapped, connected file), downref the
+     * task struct */
+    if (PMEM_FLAGS_SUBMAP & data->flags)
+        if (data->task) {
+            put_task_struct(data->task);
+            data->task = NULL;
+        }
+
+    file->private_data = NULL;
+
+    list_for_each_safe(elt, elt2, &data->region_list) {
+        region_node = list_entry(elt, struct pmem_region_node, list);
+        list_del(elt);
+        kfree(region_node);
+    }
+    BUG_ON(!list_empty(&data->region_list));
+
+    up_write(&data->sem);
+    kfree(data);
+    if (pmem[id].release)
+        ret = pmem[id].release(inode, file);
+
+    return ret;
+}
+
+static int pmem_open(struct inode *inode, struct file *file)
+{
+    struct pmem_data *data;
+    int id = get_id(file);
+    int ret = 0;
+
+    DLOG("current %u file %p(%d)\n", current->pid, file, file_count(file));
+    /* setup file->private_data to indicate its unmapped */
+    /*  you can only open a pmem device one time */
+#if 0
+    if (file->private_data != NULL)
+    {
+        printk("file -> private_data !=NULL %d \n", __LINE__);
+        return -1;
+    }
+#endif
+    data = kmalloc(sizeof(struct pmem_data), GFP_KERNEL);
+    if (!data) {
+        printk("pmem: unable to allocate memory for pmem metadata.");
+        return -1;
+    }
+    data->flags = 0;
+    data->index = -1;
+    data->task = NULL;
+    data->vma = NULL;
+    data->pid = 0;
+    data->master_file = NULL;
+#if PMEM_DEBUG
+    data->ref = 0;
+#endif
+    INIT_LIST_HEAD(&data->region_list);
+    init_rwsem(&data->sem);
+
+    file->private_data = data;
+    INIT_LIST_HEAD(&data->list);
+
+    mutex_lock(&pmem[id].data_list_lock);
+    list_add(&data->list, &pmem[id].data_list);
+    mutex_unlock(&pmem[id].data_list_lock);
+
+    return ret;
+}
+
+static unsigned long pmem_order(unsigned long len)
+{
+    int i;
+
+    len = (len + PMEM_MIN_ALLOC - 1)/PMEM_MIN_ALLOC;
+    len--;
+    for (i = 0; i < sizeof(len)*8; i++)
+        if (len >> i == 0)
+            break;
+    return i;
+}
+
+static int pmem_allocate(int id, unsigned long len)
+{
+    /* caller should hold the write lock on pmem_sem! */
+    /* return the corresponding pdata[] entry */
+    int curr = 0;
+    int end = pmem[id].num_entries;
+    int best_fit = -1;
+    unsigned long order = pmem_order(len);
+
+    if (pmem[id].no_allocator) {
+        DLOG("no allocator");
+        if ((len > pmem[id].size) || pmem[id].allocated)
+            return -1;
+        pmem[id].allocated = 1;
+        return len;
+    }
+
+    if (order > PMEM_MAX_ORDER)
+        return -1;
+    DLOG("order %lx\n", order);
+
+    /* look through the bitmap:
+     *      if you find a free slot of the correct order use it
+     *      otherwise, use the best fit (smallest with size > order) slot
+     */
+    while (curr < end) {
+        if (PMEM_IS_FREE(id, curr)) {
+            if (PMEM_ORDER(id, curr) == (unsigned char)order) {
+                /* set the not free bit and clear others */
+                best_fit = curr;
+                break;
+            }
+            if (PMEM_ORDER(id, curr) > (unsigned char)order &&
+                    (best_fit < 0 ||
+                     PMEM_ORDER(id, curr) < PMEM_ORDER(id, best_fit)))
+                best_fit = curr;
+        }
+        curr = PMEM_NEXT_INDEX(id, curr);
+    }
+
+    /* if best_fit < 0, there are no suitable slots,
+     * return an error
+     */
+    if (best_fit < 0) {
+        printk("pmem: no space left to allocate!\n");
+        return -1;
+    }
+
+    /* now partition the best fit:
+     *      split the slot into 2 buddies of order - 1
+     *      repeat until the slot is of the correct order
+     */
+    while (PMEM_ORDER(id, best_fit) > (unsigned char)order) {
+        int buddy;
+        PMEM_ORDER(id, best_fit) -= 1;
+        buddy = PMEM_BUDDY_INDEX(id, best_fit);
+        PMEM_ORDER(id, buddy) = PMEM_ORDER(id, best_fit);
+    }
+    pmem[id].bitmap[best_fit].allocated = 1;
+    return best_fit;
+}
+
+static pgprot_t pmem_access_prot(struct file *file, pgprot_t vma_prot)
+{
+    int id = get_id(file);
+#ifdef pgprot_noncached
+    if (pmem[id].cached == 0 || file->f_flags & O_SYNC)
+        return pgprot_noncached(vma_prot);
+#endif
+#ifdef pgprot_ext_buffered
+    else if (pmem[id].buffered)
+        return pgprot_ext_buffered(vma_prot);
+#endif
+    return vma_prot;
+}
+
+static unsigned long pmem_start_addr(int id, struct pmem_data *data)
+{
+    if (pmem[id].no_allocator)
+        return PMEM_START_ADDR(id, 0);
+    else
+        return PMEM_START_ADDR(id, data->index);
+
+}
+
+static void *pmem_start_vaddr(int id, struct pmem_data *data)
+{
+    return pmem_start_addr(id, data) - pmem[id].base + pmem[id].vbase;
+}
+
+static unsigned long pmem_len(int id, struct pmem_data *data)
+{
+    if (pmem[id].no_allocator)
+        return data->index;
+    else
+        return PMEM_LEN(id, data->index);
+}
+
+static int pmem_map_garbage(int id, struct vm_area_struct *vma,
+        struct pmem_data *data, unsigned long offset,
+        unsigned long len)
+{
+    int i, garbage_pages = len >> PAGE_SHIFT;
+
+    vma->vm_flags |= VM_IO | VM_RESERVED | VM_PFNMAP | VM_SHARED | VM_WRITE;
+    for (i = 0; i < garbage_pages; i++) {
+        if (vm_insert_pfn(vma, vma->vm_start + offset + (i * PAGE_SIZE),
+                    pmem[id].garbage_pfn))
+            return -EAGAIN;
+    }
+    return 0;
+}
+
+static int pmem_unmap_pfn_range(int id, struct vm_area_struct *vma,
+        struct pmem_data *data, unsigned long offset,
+        unsigned long len)
+{
+    int garbage_pages;
+    DLOG("unmap offset %lx len %lx\n", offset, len);
+
+    BUG_ON(!PMEM_IS_PAGE_ALIGNED(len));
+
+    garbage_pages = len >> PAGE_SHIFT;
+    zap_page_range(vma, vma->vm_start + offset, len, NULL);
+    pmem_map_garbage(id, vma, data, offset, len);
+    return 0;
+}
+
+static int pmem_map_pfn_range(int id, struct vm_area_struct *vma,
+        struct pmem_data *data, unsigned long offset,
+        unsigned long len)
+{
+    DLOG("map offset %lx len %lx\n", offset, len);
+    BUG_ON(!PMEM_IS_PAGE_ALIGNED(vma->vm_start));
+    BUG_ON(!PMEM_IS_PAGE_ALIGNED(vma->vm_end));
+    BUG_ON(!PMEM_IS_PAGE_ALIGNED(len));
+    BUG_ON(!PMEM_IS_PAGE_ALIGNED(offset));
+
+    if (io_remap_pfn_range(vma, vma->vm_start + offset,
+                (pmem_start_addr(id, data) + offset) >> PAGE_SHIFT,
+                len, vma->vm_page_prot)) {
+        return -EAGAIN;
+    }
+    return 0;
+}
+
+static int pmem_remap_pfn_range(int id, struct vm_area_struct *vma,
+        struct pmem_data *data, unsigned long offset,
+        unsigned long len)
+{
+    /* hold the mm semp for the vma you are modifying when you call this */
+    BUG_ON(!vma);
+    zap_page_range(vma, vma->vm_start + offset, len, NULL);
+    return pmem_map_pfn_range(id, vma, data, offset, len);
+}
+
+static void pmem_vma_open(struct vm_area_struct *vma)
+{
+    struct file *file = vma->vm_file;
+    struct pmem_data *data = file->private_data;
+    int id = get_id(file);
+    /* this should never be called as we don't support copying pmem
+     * ranges via fork */
+    BUG_ON(!has_allocation(file));
+    down_write(&data->sem);
+    /* remap the garbage pages, forkers don't get access to the data */
+    pmem_unmap_pfn_range(id, vma, data, 0, vma->vm_start - vma->vm_end);
+    up_write(&data->sem);
+}
+
+static void pmem_vma_close(struct vm_area_struct *vma)
+{
+    struct file *file = vma->vm_file;
+    struct pmem_data *data = file->private_data;
+
+    DLOG("current %u ppid %u file %p count %d\n", current->pid,
+            current->parent->pid, file, file_count(file));
+    if (unlikely(!is_pmem_file(file) || !has_allocation(file))) {
+        printk(KERN_WARNING "pmem: something is very wrong, you are "
+                "closing a vm backing an allocation that doesn't "
+                "exist!\n");
+        return;
+    }
+    down_write(&data->sem);
+    if (data->vma == vma) {
+        data->vma = NULL;
+        if ((data->flags & PMEM_FLAGS_CONNECTED) &&
+                (data->flags & PMEM_FLAGS_SUBMAP))
+            data->flags |= PMEM_FLAGS_UNSUBMAP;
+    }
+    /* the kernel is going to free this vma now anyway */
+    up_write(&data->sem);
+}
+
+static struct vm_operations_struct vm_ops = {
+    .open = pmem_vma_open,
+    .close = pmem_vma_close,
+};
+
+static int pmem_mmap(struct file *file, struct vm_area_struct *vma)
+{
+    struct pmem_data *data;
+    int index;
+    unsigned long vma_size =  vma->vm_end - vma->vm_start;
+    int ret = 0, id = get_id(file);
+
+    if (vma->vm_pgoff || !PMEM_IS_PAGE_ALIGNED(vma_size)) {
+#if PMEM_DEBUG
+        printk(KERN_ERR "pmem: mmaps must be at offset zero, aligned"
+                " and a multiple of pages_size.\n");
+#endif
+        return -EINVAL;
+    }
+
+    data = (struct pmem_data *)file->private_data;
+    down_write(&data->sem);
+    /* check this file isn't already mmaped, for submaps check this file
+     * has never been mmaped */
+    if ((data->flags & PMEM_FLAGS_SUBMAP) ||
+            (data->flags & PMEM_FLAGS_UNSUBMAP)) {
+#if PMEM_DEBUG
+        printk(KERN_ERR "pmem: you can only mmap a pmem file once, "
+                "this file is already mmaped. %x\n", data->flags);
+#endif
+        ret = -EINVAL;
+        goto error;
+    }
+    /* if file->private_data == unalloced, alloc*/
+    if (data && data->index == -1) {
+        down_write(&pmem[id].bitmap_sem);
+        index = pmem_allocate(id, vma->vm_end - vma->vm_start);
+        up_write(&pmem[id].bitmap_sem);
+        data->index = index;
+    }
+    /* either no space was available or an error occured */
+    if (!has_allocation(file)) {
+        ret = -EINVAL;
+        printk("pmem: could not find allocation for map.\n");
+        goto error;
+    }
+
+    if (pmem_len(id, data) < vma_size) {
+#if PMEM_DEBUG
+        printk(KERN_WARNING "pmem: mmap size [%lu] does not match"
+                "size of backing region [%lu].\n", vma_size,
+                pmem_len(id, data));
+#endif
+        ret = -EINVAL;
+        goto error;
+    }
+
+    vma->vm_pgoff = pmem_start_addr(id, data) >> PAGE_SHIFT;
+    vma->vm_page_prot = pmem_access_prot(file, vma->vm_page_prot);
+
+    if (data->flags & PMEM_FLAGS_CONNECTED) {
+        struct pmem_region_node *region_node;
+        struct list_head *elt;
+        if (pmem_map_garbage(id, vma, data, 0, vma_size)) {
+            printk("pmem: mmap failed in kernel!\n");
+            ret = -EAGAIN;
+            goto error;
+        }
+        list_for_each(elt, &data->region_list) {
+            region_node = list_entry(elt, struct pmem_region_node,
+                    list);
+            DLOG("remapping file: %p %lx %lx\n", file,
+                    region_node->region.offset,
+                    region_node->region.len);
+            if (pmem_remap_pfn_range(id, vma, data,
+                        region_node->region.offset,
+                        region_node->region.len)) {
+                ret = -EAGAIN;
+                goto error;
+            }
+        }
+        data->flags |= PMEM_FLAGS_SUBMAP;
+        get_task_struct(current->group_leader);
+        data->task = current->group_leader;
+        data->vma = vma;
+#if PMEM_DEBUG
+        data->pid = current->pid;
+#endif
+        DLOG("submmapped file %p vma %p pid %u\n", file, vma,
+                current->pid);
+    } else {
+        if (pmem_map_pfn_range(id, vma, data, 0, vma_size)) {
+            printk(KERN_INFO "pmem: mmap failed in kernel!\n");
+            ret = -EAGAIN;
+            goto error;
+        }
+        data->flags |= PMEM_FLAGS_MASTERMAP;
+        data->pid = current->pid;
+    }
+    vma->vm_ops = &vm_ops;
+error:
+    up_write(&data->sem);
+    return ret;
+}
+
+/* the following are the api for accessing pmem regions by other drivers
+ * from inside the kernel */
+int get_pmem_user_addr(struct file *file, unsigned long *start,
+        unsigned long *len)
+{
+    struct pmem_data *data;
+    if (!is_pmem_file(file) || !has_allocation(file)) {
+#if PMEM_DEBUG
+        printk(KERN_INFO "pmem: requested pmem data from invalid"
+                "file.\n");
+#endif
+        return -1;
+    }
+    data = (struct pmem_data *)file->private_data;
+    down_read(&data->sem);
+    if (data->vma) {
+        *start = data->vma->vm_start;
+        *len = data->vma->vm_end - data->vma->vm_start;
+    } else {
+        *start = 0;
+        *len = 0;
+    }
+    up_read(&data->sem);
+    return 0;
+}
+
+int get_pmem_addr(struct file *file, unsigned long *start,
+        unsigned long *vstart, unsigned long *len)
+{
+    struct pmem_data *data;
+    int id;
+
+    if (!is_pmem_file(file) || !has_allocation(file)) {
+        return -1;
+    }
+
+    data = (struct pmem_data *)file->private_data;
+    if (data->index == -1) {
+#if PMEM_DEBUG
+        printk(KERN_INFO "pmem: requested pmem data from file with no "
+                "allocation.\n");
+        return -1;
+#endif
+    }
+    id = get_id(file);
+
+    down_read(&data->sem);
+    *start = pmem_start_addr(id, data);
+    *len = pmem_len(id, data);
+    *vstart = (unsigned long)pmem_start_vaddr(id, data);
+    up_read(&data->sem);
+#if PMEM_DEBUG
+    down_write(&data->sem);
+    data->ref++;
+    up_write(&data->sem);
+#endif
+    return 0;
+}
+
+int get_pmem_file(int fd, unsigned long *start, unsigned long *vstart,
+        unsigned long *len, struct file **filp)
+{
+    struct file *file;
+
+    file = fget(fd);
+    if (unlikely(file == NULL)) {
+        printk(KERN_INFO "pmem: requested data from file descriptor "
+                "that doesn't exist.");
+        return -1;
+    }
+
+    if (get_pmem_addr(file, start, vstart, len))
+        goto end;
+
+    if (filp)
+        *filp = file;
+    return 0;
+end:
+    fput(file);
+    return -1;
+}
+
+void put_pmem_file(struct file *file)
+{
+    struct pmem_data *data;
+    int id;
+
+    if (!is_pmem_file(file))
+        return;
+    id = get_id(file);
+    data = (struct pmem_data *)file->private_data;
+#if PMEM_DEBUG
+    down_write(&data->sem);
+    if (data->ref == 0) {
+        printk("pmem: pmem_put > pmem_get %s (pid %d)\n",
+                pmem[id].dev.name, data->pid);
+        BUG();
+    }
+    data->ref--;
+    up_write(&data->sem);
+#endif
+    fput(file);
+}
+
+void flush_pmem_file(struct file *file, unsigned long offset, unsigned long len)
+{
+    struct pmem_data *data;
+    int id;
+    void *vaddr;
+    struct pmem_region_node *region_node;
+    struct list_head *elt;
+    void *flush_start, *flush_end;
+
+    if (!is_pmem_file(file) || !has_allocation(file)) {
+        return;
+    }
+
+    id = get_id(file);
+    data = (struct pmem_data *)file->private_data;
+    if (!pmem[id].cached || file->f_flags & O_SYNC)
+        return;
+
+    down_read(&data->sem);
+    vaddr = pmem_start_vaddr(id, data);
+    /* if this isn't a submmapped file, flush the whole thing */
+    if (unlikely(!(data->flags & PMEM_FLAGS_CONNECTED))) {
+        dmac_flush_range(vaddr, vaddr + pmem_len(id, data));
+        goto end;
+    }
+    /* otherwise, flush the region of the file we are drawing */
+    list_for_each(elt, &data->region_list) {
+        region_node = list_entry(elt, struct pmem_region_node, list);
+        if ((offset >= region_node->region.offset) &&
+                ((offset + len) <= (region_node->region.offset +
+                    region_node->region.len))) {
+            flush_start = vaddr + region_node->region.offset;
+            flush_end = flush_start + region_node->region.len;
+            dmac_flush_range(flush_start, flush_end);
+            break;
+        }
+    }
+end:
+    up_read(&data->sem);
+}
+
+static int pmem_connect(unsigned long connect, struct file *file)
+{
+    struct pmem_data *data = (struct pmem_data *)file->private_data;
+    struct pmem_data *src_data;
+    struct file *src_file;
+    int ret = 0, put_needed;
+
+    down_write(&data->sem);
+    /* retrieve the src file and check it is a pmem file with an alloc */
+    src_file = fget_light(connect, &put_needed);
+    DLOG("connect %p to %p\n", file, src_file);
+    if (!src_file) {
+        printk("pmem: src file not found!\n");
+        ret = -EINVAL;
+        goto err_no_file;
+    }
+    if (unlikely(!is_pmem_file(src_file) || !has_allocation(src_file))) {
+        printk(KERN_INFO "pmem: src file is not a pmem file or has no "
+                "alloc!\n");
+        ret = -EINVAL;
+        goto err_bad_file;
+    }
+    src_data = (struct pmem_data *)src_file->private_data;
+
+    if (has_allocation(file) && (data->index != src_data->index)) {
+        printk("pmem: file is already mapped but doesn't match this"
+                " src_file!\n");
+        ret = -EINVAL;
+        goto err_bad_file;
+    }
+    data->index = src_data->index;
+    data->flags |= PMEM_FLAGS_CONNECTED;
+    data->master_fd = connect;
+    data->master_file = src_file;
+
+err_bad_file:
+    fput_light(src_file, put_needed);
+err_no_file:
+    up_write(&data->sem);
+    return ret;
+}
+
+static void pmem_unlock_data_and_mm(struct pmem_data *data,
+        struct mm_struct *mm)
+{
+    up_write(&data->sem);
+    if (mm != NULL) {
+        up_write(&mm->mmap_sem);
+        mmput(mm);
+    }
+}
+
+static int pmem_lock_data_and_mm(struct file *file, struct pmem_data *data,
+        struct mm_struct **locked_mm)
+{
+    int ret = 0;
+    struct mm_struct *mm = NULL;
+    *locked_mm = NULL;
+lock_mm:
+    down_read(&data->sem);
+    if (PMEM_IS_SUBMAP(data)) {
+        mm = get_task_mm(data->task);
+        if (!mm) {
+#if PMEM_DEBUG
+            printk("pmem: can't remap task is gone!\n");
+#endif
+            up_read(&data->sem);
+            return -1;
+        }
+    }
+    up_read(&data->sem);
+
+    if (mm)
+        down_write(&mm->mmap_sem);
+
+    down_write(&data->sem);
+    /* check that the file didn't get mmaped before we could take the
+     * data sem, this should be safe b/c you can only submap each file
+     * once */
+    if (PMEM_IS_SUBMAP(data) && !mm) {
+        pmem_unlock_data_and_mm(data, mm);
+        up_write(&data->sem);
+        goto lock_mm;
+    }
+    /* now check that vma.mm is still there, it could have been
+     * deleted by vma_close before we could get the data->sem */
+    if ((data->flags & PMEM_FLAGS_UNSUBMAP) && (mm != NULL)) {
+        /* might as well release this */
+        if (data->flags & PMEM_FLAGS_SUBMAP) {
+            put_task_struct(data->task);
+            data->task = NULL;
+            /* lower the submap flag to show the mm is gone */
+            data->flags &= ~(PMEM_FLAGS_SUBMAP);
+        }
+        pmem_unlock_data_and_mm(data, mm);
+        return -1;
+    }
+    *locked_mm = mm;
+    return ret;
+}
+
+int pmem_remap(struct pmem_region *region, struct file *file,
+        unsigned operation)
+{
+    int ret;
+    struct pmem_region_node *region_node;
+    struct mm_struct *mm = NULL;
+    struct list_head *elt, *elt2;
+    int id = get_id(file);
+    struct pmem_data *data = (struct pmem_data *)file->private_data;
+
+    /* pmem region must be aligned on a page boundry */
+    if (unlikely(!PMEM_IS_PAGE_ALIGNED(region->offset) ||
+                !PMEM_IS_PAGE_ALIGNED(region->len))) {
+#if PMEM_DEBUG
+        printk("pmem: request for unaligned pmem suballocation "
+                "%lx %lx\n", region->offset, region->len);
+#endif
+        return -EINVAL;
+    }
+
+    /* if userspace requests a region of len 0, there's nothing to do */
+    if (region->len == 0)
+        return 0;
+
+    /* lock the mm and data */
+    ret = pmem_lock_data_and_mm(file, data, &mm);
+    if (ret)
+        return 0;
+
+    /* only the owner of the master file can remap the client fds
+     * that back in it */
+    if (!is_master_owner(file)) {
+#if PMEM_DEBUG
+        printk("pmem: remap requested from non-master process\n");
+#endif
+        ret = -EINVAL;
+        goto err;
+    }
+
+    /* check that the requested range is within the src allocation */
+    if (unlikely((region->offset > pmem_len(id, data)) ||
+                (region->len > pmem_len(id, data)) ||
+                (region->offset + region->len > pmem_len(id, data)))) {
+#if PMEM_DEBUG
+        printk(KERN_INFO "pmem: suballoc doesn't fit in src_file!\n");
+#endif
+        ret = -EINVAL;
+        goto err;
+    }
+
+    if (operation == PMEM_MAP) {
+        region_node = kmalloc(sizeof(struct pmem_region_node),
+                GFP_KERNEL);
+        if (!region_node) {
+            ret = -ENOMEM;
+#if PMEM_DEBUG
+            printk(KERN_INFO "No space to allocate metadata!");
+#endif
+            goto err;
+        }
+        region_node->region = *region;
+        list_add(&region_node->list, &data->region_list);
+    } else if (operation == PMEM_UNMAP) {
+        int found = 0;
+        list_for_each_safe(elt, elt2, &data->region_list) {
+            region_node = list_entry(elt, struct pmem_region_node,
+                    list);
+            if (region->len == 0 ||
+                    (region_node->region.offset == region->offset &&
+                     region_node->region.len == region->len)) {
+                list_del(elt);
+                kfree(region_node);
+                found = 1;
+            }
+        }
+        if (!found) {
+#if PMEM_DEBUG
+            printk("pmem: Unmap region does not map any mapped "
+                    "region!");
+#endif
+            ret = -EINVAL;
+            goto err;
+        }
+    }
+
+    if (data->vma && PMEM_IS_SUBMAP(data)) {
+        if (operation == PMEM_MAP)
+            ret = pmem_remap_pfn_range(id, data->vma, data,
+                    region->offset, region->len);
+        else if (operation == PMEM_UNMAP)
+            ret = pmem_unmap_pfn_range(id, data->vma, data,
+                    region->offset, region->len);
+    }
+
+err:
+    pmem_unlock_data_and_mm(data, mm);
+    return ret;
+}
+
+static void pmem_revoke(struct file *file, struct pmem_data *data)
+{
+    struct pmem_region_node *region_node;
+    struct list_head *elt, *elt2;
+    struct mm_struct *mm = NULL;
+    int id = get_id(file);
+    int ret = 0;
+
+    data->master_file = NULL;
+    ret = pmem_lock_data_and_mm(file, data, &mm);
+    /* if lock_data_and_mm fails either the task that mapped the fd, or
+     * the vma that mapped it have already gone away, nothing more
+     * needs to be done */
+    if (ret)
+        return;
+    /* unmap everything */
+    /* delete the regions and region list nothing is mapped any more */
+    if (data->vma)
+        list_for_each_safe(elt, elt2, &data->region_list) {
+            region_node = list_entry(elt, struct pmem_region_node,
+                    list);
+            pmem_unmap_pfn_range(id, data->vma, data,
+                    region_node->region.offset,
+                    region_node->region.len);
+            list_del(elt);
+            kfree(region_node);
+        }
+    /* delete the master file */
+    pmem_unlock_data_and_mm(data, mm);
+}
+
+static void pmem_get_size(struct pmem_region *region, struct file *file)
+{
+    struct pmem_data *data = (struct pmem_data *)file->private_data;
+    int id = get_id(file);
+
+    if (!has_allocation(file)) {
+        region->offset = 0;
+        region->len = 0;
+        return;
+    } else {
+        region->offset = pmem_start_addr(id, data);
+        region->len = pmem_len(id, data);
+    }
+    DLOG("offset %lx len %lx\n", region->offset, region->len);
+}
+
+
+static long pmem_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+    struct pmem_data *data;
+    int id = get_id(file);
+
+    switch (cmd) {
+        case PMEM_GET_PHYS:
+            {
+                struct pmem_region region;
+                DLOG("get_phys\n");
+                if (!has_allocation(file)) {
+                    region.offset = 0;
+                    region.len = 0;
+                } else {
+                    data = (struct pmem_data *)file->private_data;
+                    region.offset = pmem_start_addr(id, data);
+                    region.len = pmem_len(id, data);
+                }
+                printk(KERN_INFO "pmem: request for physical address of pmem region "
+                        "from process %d.\n", current->pid);
+                if (copy_to_user((void __user *)arg, &region,
+                            sizeof(struct pmem_region)))
+                    return -EFAULT;
+                break;
+            }
+        case PMEM_MAP:
+            {
+                struct pmem_region region;
+                if (copy_from_user(&region, (void __user *)arg,
+                            sizeof(struct pmem_region)))
+                    return -EFAULT;
+                data = (struct pmem_data *)file->private_data;
+                return pmem_remap(&region, file, PMEM_MAP);
+            }
+            break;
+        case PMEM_UNMAP:
+            {
+                struct pmem_region region;
+                if (copy_from_user(&region, (void __user *)arg,
+                            sizeof(struct pmem_region)))
+                    return -EFAULT;
+                data = (struct pmem_data *)file->private_data;
+                return pmem_remap(&region, file, PMEM_UNMAP);
+                break;
+            }
+        case PMEM_GET_SIZE:
+            {
+                struct pmem_region region;
+                DLOG("get_size\n");
+                pmem_get_size(&region, file);
+                if (copy_to_user((void __user *)arg, &region,
+                            sizeof(struct pmem_region)))
+                    return -EFAULT;
+                break;
+            }
+        case PMEM_GET_TOTAL_SIZE:
+            {
+                struct pmem_region region;
+                DLOG("get total size\n");
+                region.offset = 0;
+                get_id(file);
+                region.len = pmem[id].size;
+                if (copy_to_user((void __user *)arg, &region,
+                            sizeof(struct pmem_region)))
+                    return -EFAULT;
+                break;
+            }
+        case PMEM_ALLOCATE:
+            {
+                if (has_allocation(file))
+                    return -EINVAL;
+                data = (struct pmem_data *)file->private_data;
+                data->index = pmem_allocate(id, arg);
+                break;
+            }
+        case PMEM_CONNECT:
+            DLOG("connect\n");
+            return pmem_connect(arg, file);
+            break;
+
+        case PMEM_CACHE_FLUSH:
+            {
+                struct pmem_region region;
+                DLOG("flush\n");
+                if (copy_from_user(&region, (void __user *)arg,
+                            sizeof(struct pmem_region)))
+                    return -EFAULT;
+                flush_pmem_file(file, region.offset, region.len);
+                printk("pmem ioctl PMEM_CACHE_FLUSH!\n");
+                break;
+            }
+
+        default:
+            if (pmem[id].ioctl)
+                return pmem[id].ioctl(file, cmd, arg);
+            return -EINVAL;
+    }
+    return 0;
+}
+
+#if PMEM_DEBUG
+static ssize_t debug_open(struct inode *inode, struct file *file)
+{
+    file->private_data = inode->i_private;
+    return 0;
+}
+
+static ssize_t debug_read(struct file *file, char __user *buf, size_t count,
+        loff_t *ppos)
+{
+    struct list_head *elt, *elt2;
+    struct pmem_data *data;
+    struct pmem_region_node *region_node;
+    int id = (int)file->private_data;
+    const int debug_bufmax = 4096;
+    static char buffer[4096];
+    int n = 0;
+
+    DLOG("debug open\n");
+    n = scnprintf(buffer, debug_bufmax,
+            "pid #: mapped regions (offset, len) (offset,len)...\n");
+
+    mutex_lock(&pmem[id].data_list_lock);
+    list_for_each(elt, &pmem[id].data_list) {
+        data = list_entry(elt, struct pmem_data, list);
+        down_read(&data->sem);
+        n += scnprintf(buffer + n, debug_bufmax - n, "pid %u:",
+                data->pid);
+        list_for_each(elt2, &data->region_list) {
+            region_node = list_entry(elt2, struct pmem_region_node,
+                    list);
+            n += scnprintf(buffer + n, debug_bufmax - n,
+                    "(%lx,%lx) ",
+                    region_node->region.offset,
+                    region_node->region.len);
+        }
+        n += scnprintf(buffer + n, debug_bufmax - n, "\n");
+        up_read(&data->sem);
+    }
+    mutex_unlock(&pmem[id].data_list_lock);
+
+    n++;
+    buffer[n] = 0;
+    return simple_read_from_buffer(buf, count, ppos, buffer, n);
+}
+
+static struct file_operations debug_fops = {
+    .read = debug_read,
+    .open = debug_open,
+};
+#endif
+
+#if 0
+static struct miscdevice pmem_dev = {
+    .name = "pmem",
+    .fops = &pmem_fops,
+};
+#endif
+
+int pmem_setup(struct android_pmem_platform_data *pdata,
+        long (*ioctl)(struct file *, unsigned int, unsigned long),
+        int (*release)(struct inode *, struct file *))
+{
+    int err = 0;
+    int i, index = 0;
+    int id = id_count;
+    id_count++;
+
+    pmem[id].no_allocator = pdata->no_allocator;
+    pmem[id].cached = pdata->cached;
+    pmem[id].buffered = pdata->buffered;
+    pmem[id].base = pdata->start;
+    pmem[id].size = pdata->size;
+    pmem[id].ioctl = ioctl;
+    pmem[id].release = release;
+    init_rwsem(&pmem[id].bitmap_sem);
+    mutex_init(&pmem[id].data_list_lock);
+    INIT_LIST_HEAD(&pmem[id].data_list);
+    pmem[id].dev.name = pdata->name;
+    pmem[id].dev.minor = id;
+    pmem[id].dev.fops = &pmem_fops;
+    printk(KERN_INFO "%s: %d init\n", pdata->name, pdata->cached);
+
+    err = misc_register(&pmem[id].dev);
+    if (err) {
+        printk(KERN_ALERT "Unable to register pmem driver!\n");
+        goto err_cant_register_device;
+    }
+    pmem[id].num_entries = pmem[id].size / PMEM_MIN_ALLOC;
+
+    pmem[id].bitmap = kmalloc(pmem[id].num_entries *
+            sizeof(struct pmem_bits), GFP_KERNEL);
+    if (!pmem[id].bitmap)
+        goto err_no_mem_for_metadata;
+
+    memset(pmem[id].bitmap, 0, sizeof(struct pmem_bits) *
+            pmem[id].num_entries);
+
+    for (i = sizeof(pmem[id].num_entries) * 8 - 1; i >= 0; i--) {
+        if ((pmem[id].num_entries) &  1<<i) {
+            PMEM_ORDER(id, index) = i;
+            index = PMEM_NEXT_INDEX(id, index);
+        }
+    }
+
+    if (pmem[id].cached)
+        pmem[id].vbase = ioremap_cached(pmem[id].base,
+                pmem[id].size);
+#ifdef ioremap_ext_buffered
+    else if (pmem[id].buffered)
+        pmem[id].vbase = ioremap_ext_buffered(pmem[id].base,
+                pmem[id].size);
+#endif
+    else
+        pmem[id].vbase = ioremap(pmem[id].base, pmem[id].size);
+
+    if (pmem[id].vbase == 0)
+        goto error_cant_remap;
+
+    pmem[id].garbage_pfn = page_to_pfn(alloc_page(GFP_KERNEL));
+    if (pmem[id].no_allocator)
+        pmem[id].allocated = 0;
+
+#if PMEM_DEBUG
+    debugfs_create_file(pdata->name, S_IFREG | S_IRUGO, NULL, (void *)id,
+            &debug_fops);
+#endif
+    return 0;
+error_cant_remap:
+    kfree(pmem[id].bitmap);
+err_no_mem_for_metadata:
+    misc_deregister(&pmem[id].dev);
+err_cant_register_device:
+    return -1;
+}
+
+static int pmem_probe(struct platform_device *pdev)
+{
+    struct android_pmem_platform_data *pdata;
+
+    if (!pdev || !pdev->dev.platform_data) {
+        printk(KERN_ALERT "Unable to probe pmem!\n");
+        return -1;
+    }
+    pdata = pdev->dev.platform_data;
+    pmem_dev = pdev;
+    return pmem_setup(pdata, NULL, NULL);
+}
+
+
+static int pmem_remove(struct platform_device *pdev)
+{
+    int id = pdev->id;
+    __free_page(pfn_to_page(pmem[id].garbage_pfn));
+    misc_deregister(&pmem[id].dev);
+    return 0;
+}
+
+static struct platform_driver pmem_driver = {
+    .probe = pmem_probe,
+    .remove = pmem_remove,
+    .driver = { .name = "android_pmem" }
+};
+
+
+static int __init pmem_init(void)
+{
+    return platform_driver_register(&pmem_driver);
+}
+
+static void __exit pmem_exit(void)
+{
+    platform_driver_unregister(&pmem_driver);
+}
+
+module_init(pmem_init);
+module_exit(pmem_exit);
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/card/block.c linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/card/block.c
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/card/block.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/card/block.c	2014-09-12 15:59:37.348052000 +0800
@@ -57,6 +57,13 @@
 #define INAND_CMD38_ARG_SECERASE 0x80
 #define INAND_CMD38_ARG_SECTRIM1 0x81
 #define INAND_CMD38_ARG_SECTRIM2 0x88
+#define MMC_BLK_TIMEOUT_MS  (10 * 60 * 1000)        /* 10 minute timeout */
+
+#define mmc_req_rel_wr(req)	(((req->cmd_flags & REQ_FUA) || \
+				  (req->cmd_flags & REQ_META)) && \
+				  (rq_data_dir(req) == WRITE))
+#define PACKED_CMD_VER	0x01
+#define PACKED_CMD_WR	0x02
 
 static DEFINE_MUTEX(block_mutex);
 
@@ -88,6 +95,7 @@
 	unsigned int	flags;
 #define MMC_BLK_CMD23	(1 << 0)	/* Can do SET_BLOCK_COUNT for multiblock */
 #define MMC_BLK_REL_WR	(1 << 1)	/* MMC Reliable write support */
+#define MMC_BLK_PACKED_CMD	(1 << 2)	/* MMC packed command support */
 
 	unsigned int	usage;
 	unsigned int	read_only;
@@ -112,20 +120,32 @@
 
 static DEFINE_MUTEX(open_lock);
 
-enum mmc_blk_status {
-	MMC_BLK_SUCCESS = 0,
-	MMC_BLK_PARTIAL,
-	MMC_BLK_CMD_ERR,
-	MMC_BLK_RETRY,
-	MMC_BLK_ABORT,
-	MMC_BLK_DATA_ERR,
-	MMC_BLK_ECC_ERR,
-	MMC_BLK_NOMEDIUM,
+enum {
+	MMC_PACKED_NR_IDX = -1,
+	MMC_PACKED_NR_ZERO,
+	MMC_PACKED_NR_SINGLE,
 };
 
 module_param(perdev_minors, int, 0444);
 MODULE_PARM_DESC(perdev_minors, "Minors numbers to allocate per device");
 
+static inline int mmc_blk_part_switch(struct mmc_card *card,
+				      struct mmc_blk_data *md);
+static int get_card_status(struct mmc_card *card, u32 *status, int retries);
+
+static inline void mmc_blk_clear_packed(struct mmc_queue_req *mqrq)
+{
+	struct mmc_packed *packed = mqrq->packed;
+
+	BUG_ON(!packed);
+
+	mqrq->cmd_type = MMC_PACKED_NONE;
+	packed->nr_entries = MMC_PACKED_NR_ZERO;
+	packed->idx_failure = MMC_PACKED_NR_IDX;
+	packed->retries = 0;
+	packed->blocks = 0;
+}
+
 static struct mmc_blk_data *mmc_blk_get(struct gendisk *disk)
 {
 	struct mmc_blk_data *md;
@@ -143,7 +163,11 @@
 
 static inline int mmc_get_devidx(struct gendisk *disk)
 {
-	int devidx = disk->first_minor / perdev_minors;
+	int devmaj = MAJOR(disk_devt(disk));
+	int devidx = MINOR(disk_devt(disk)) / perdev_minors;
+
+	if (!devmaj)
+		devidx = disk->first_minor / perdev_minors;
 	return devidx;
 }
 
@@ -280,14 +304,13 @@
 	return ret;
 }
 
-static int mmc_blk_release(struct gendisk *disk, fmode_t mode)
+static void mmc_blk_release(struct gendisk *disk, fmode_t mode)
 {
 	struct mmc_blk_data *md = disk->private_data;
 
 	mutex_lock(&block_mutex);
 	mmc_blk_put(md);
 	mutex_unlock(&block_mutex);
-	return 0;
 }
 
 static int
@@ -353,6 +376,38 @@
 	return ERR_PTR(err);
 }
 
+static int ioctl_rpmb_card_status_poll(struct mmc_card *card, u32 *status,
+				       u32 retries_max)
+{
+	int err;
+	u32 retry_count = 0;
+
+	if (!status || !retries_max)
+		return -EINVAL;
+
+	do {
+		err = get_card_status(card, status, 5);
+		if (err)
+			break;
+
+		if (!R1_STATUS(*status) &&
+				(R1_CURRENT_STATE(*status) != R1_STATE_PRG))
+			break; /* RPMB programming operation complete */
+
+		/*
+		 * Rechedule to give the MMC device a chance to continue
+		 * processing the previous command without being polled too
+		 * frequently.
+		 */
+		usleep_range(1000, 5000);
+	} while (++retry_count < retries_max);
+
+	if (retry_count == retries_max)
+		err = -EPERM;
+
+	return err;
+}
+
 static int mmc_blk_ioctl_cmd(struct block_device *bdev,
 	struct mmc_ioc_cmd __user *ic_ptr)
 {
@@ -364,6 +419,8 @@
 	struct mmc_request mrq = {NULL};
 	struct scatterlist sg;
 	int err;
+	int is_rpmb = false;
+	u32 status = 0;
 
 	/*
 	 * The caller must have CAP_SYS_RAWIO, and must be calling this on the
@@ -380,9 +437,12 @@
 	md = mmc_blk_get(bdev->bd_disk);
 	if (!md) {
 		err = -EINVAL;
-		goto cmd_done;
+		goto cmd_err;
 	}
 
+	if (md->area_type & MMC_BLK_DATA_AREA_RPMB)
+		is_rpmb = true;
+
 	card = md->queue.card;
 	if (IS_ERR(card)) {
 		err = PTR_ERR(card);
@@ -433,12 +493,23 @@
 
 	mmc_claim_host(card->host);
 
+	err = mmc_blk_part_switch(card, md);
+	if (err)
+		goto cmd_rel_host;
+
 	if (idata->ic.is_acmd) {
 		err = mmc_app_cmd(card->host, card);
 		if (err)
 			goto cmd_rel_host;
 	}
 
+	if (is_rpmb) {
+		err = mmc_set_blockcount(card, data.blocks,
+			idata->ic.write_flag & (1 << 31));
+		if (err)
+			goto cmd_rel_host;
+	}
+
 	mmc_wait_for_req(card->host, &mrq);
 
 	if (cmd.error) {
@@ -474,11 +545,24 @@
 		}
 	}
 
+	if (is_rpmb) {
+		/*
+		 * Ensure RPMB command has completed by polling CMD13
+		 * "Send Status".
+		 */
+		err = ioctl_rpmb_card_status_poll(card, &status, 5);
+		if (err)
+			dev_err(mmc_dev(card->host),
+					"%s: Card Status=0x%08X, error %d\n",
+					__func__, status, err);
+	}
+
 cmd_rel_host:
 	mmc_release_host(card->host);
 
 cmd_done:
 	mmc_blk_put(md);
+cmd_err:
 	kfree(idata->buf);
 	kfree(idata);
 	return err;
@@ -549,7 +633,6 @@
 	struct mmc_request mrq = {NULL};
 	struct mmc_command cmd = {0};
 	struct mmc_data data = {0};
-	unsigned int timeout_us;
 
 	struct scatterlist sg;
 
@@ -569,23 +652,12 @@
 	cmd.arg = 0;
 	cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;
 
-	data.timeout_ns = card->csd.tacc_ns * 100;
-	data.timeout_clks = card->csd.tacc_clks * 100;
-
-	timeout_us = data.timeout_ns / 1000;
-	timeout_us += data.timeout_clks * 1000 /
-		(card->host->ios.clock / 1000);
-
-	if (timeout_us > 100000) {
-		data.timeout_ns = 100000000;
-		data.timeout_clks = 0;
-	}
-
 	data.blksz = 4;
 	data.blocks = 1;
 	data.flags = MMC_DATA_READ;
 	data.sg = &sg;
 	data.sg_len = 1;
+	mmc_set_data_timeout(&data, card);
 
 	mrq.cmd = &cmd;
 	mrq.data = &data;
@@ -656,22 +728,18 @@
 			req->rq_disk->disk_name, "timed out", name, status);
 
 		/* If the status cmd initially failed, retry the r/w cmd */
-		if (!status_valid) {
-			pr_err("%s: status not valid, retrying timeout\n", req->rq_disk->disk_name);
+		if (!status_valid)
 			return ERR_RETRY;
-		}
+
 		/*
 		 * If it was a r/w cmd crc error, or illegal command
 		 * (eg, issued in wrong state) then retry - we should
 		 * have corrected the state problem above.
 		 */
-		if (status & (R1_COM_CRC_ERROR | R1_ILLEGAL_COMMAND)) {
-			pr_err("%s: command error, retrying timeout\n", req->rq_disk->disk_name);
+		if (status & (R1_COM_CRC_ERROR | R1_ILLEGAL_COMMAND))
 			return ERR_RETRY;
-		}
 
 		/* Otherwise abort the command */
-		pr_err("%s: not retrying timeout\n", req->rq_disk->disk_name);
 		return ERR_ABORT;
 
 	default:
@@ -701,7 +769,7 @@
  * Otherwise we don't understand what happened, so abort.
  */
 static int mmc_blk_cmd_recovery(struct mmc_card *card, struct request *req,
-	struct mmc_blk_request *brq, int *ecc_err)
+	struct mmc_blk_request *brq, int *ecc_err, int *gen_err)
 {
 	bool prev_cmd_status_valid = true;
 	u32 status, stop_status = 0;
@@ -739,6 +807,16 @@
 	    (brq->cmd.resp[0] & R1_CARD_ECC_FAILED))
 		*ecc_err = 1;
 
+	/* Flag General errors */
+	if (!mmc_host_is_spi(card->host) && rq_data_dir(req) != READ)
+		if ((status & R1_ERROR) ||
+			(brq->stop.resp[0] & R1_ERROR)) {
+			pr_err("%s: %s: general error sending stop or status command, stop cmd response %#x, card status %#x\n",
+			       req->rq_disk->disk_name, __func__,
+			       brq->stop.resp[0], status);
+			*gen_err = 1;
+		}
+
 	/*
 	 * Check the current card state.  If it is in some data transfer
 	 * mode, tell it to stop (and hopefully transition back to TRAN.)
@@ -758,6 +836,13 @@
 			return ERR_ABORT;
 		if (stop_status & R1_CARD_ECC_FAILED)
 			*ecc_err = 1;
+		if (!mmc_host_is_spi(card->host) && rq_data_dir(req) != READ)
+			if (stop_status & R1_ERROR) {
+				pr_err("%s: %s: general error sending stop command, stop cmd response %#x\n",
+				       req->rq_disk->disk_name, __func__,
+				       stop_status);
+				*gen_err = 1;
+			}
 	}
 
 	/* Check for set block count errors */
@@ -861,9 +946,7 @@
 		goto retry;
 	if (!err)
 		mmc_blk_reset_success(md, type);
-	spin_lock_irq(&md->lock);
-	__blk_end_request(req, err, blk_rq_bytes(req));
-	spin_unlock_irq(&md->lock);
+	blk_end_request(req, err, blk_rq_bytes(req));
 
 	return err ? 0 : 1;
 }
@@ -945,9 +1028,7 @@
 	if (!err)
 		mmc_blk_reset_success(md, type);
 out:
-	spin_lock_irq(&md->lock);
-	__blk_end_request(req, err, blk_rq_bytes(req));
-	spin_unlock_irq(&md->lock);
+	blk_end_request(req, err, blk_rq_bytes(req));
 
 	return err ? 0 : 1;
 }
@@ -962,9 +1043,7 @@
 	if (ret)
 		ret = -EIO;
 
-	spin_lock_irq(&md->lock);
-	__blk_end_request_all(req, ret);
-	spin_unlock_irq(&md->lock);
+	blk_end_request_all(req, ret);
 
 	return ret ? 0 : 1;
 }
@@ -1007,7 +1086,7 @@
 						    mmc_active);
 	struct mmc_blk_request *brq = &mq_mrq->brq;
 	struct request *req = mq_mrq->req;
-	int ecc_err = 0;
+	int ecc_err = 0, gen_err = 0;
 
 	/*
 	 * sbc.error indicates a problem with the set block count
@@ -1021,7 +1100,7 @@
 	 */
 	if (brq->sbc.error || brq->cmd.error || brq->stop.error ||
 	    brq->data.error) {
-		switch (mmc_blk_cmd_recovery(card, req, brq, &ecc_err)) {
+		switch (mmc_blk_cmd_recovery(card, req, brq, &ecc_err, &gen_err)) {
 		case ERR_RETRY:
 			return MMC_BLK_RETRY;
 		case ERR_ABORT:
@@ -1051,6 +1130,17 @@
 	 */
 	if (!mmc_host_is_spi(card->host) && rq_data_dir(req) != READ) {
 		u32 status;
+		unsigned long timeout;
+
+		/* Check stop command response */
+		if (brq->stop.resp[0] & R1_ERROR) {
+			pr_err("%s: %s: general error sending stop command, stop cmd response %#x\n",
+			       req->rq_disk->disk_name, __func__,
+			       brq->stop.resp[0]);
+			gen_err = 1;
+		}
+
+		timeout = jiffies + msecs_to_jiffies(MMC_BLK_TIMEOUT_MS);
 		do {
 			int err = get_card_status(card, &status, 5);
 			if (err) {
@@ -1058,6 +1148,24 @@
 				       req->rq_disk->disk_name, err);
 				return MMC_BLK_CMD_ERR;
 			}
+
+			if (status & R1_ERROR) {
+				pr_err("%s: %s: general error sending status command, card status %#x\n",
+				       req->rq_disk->disk_name, __func__,
+				       status);
+				gen_err = 1;
+			}
+
+			/* Timeout if the device never becomes ready for data
+			 * and never leaves the program state.
+			 */
+			if (time_after(jiffies, timeout)) {
+				pr_err("%s: Card stuck in programming state!"\
+					" %s %s\n", mmc_hostname(card->host),
+					req->rq_disk->disk_name, __func__);
+
+				return MMC_BLK_CMD_ERR;
+			}
 			/*
 			 * Some cards mishandle the status bits,
 			 * so make sure to check both the busy
@@ -1067,6 +1175,13 @@
 			 (R1_CURRENT_STATE(status) == R1_STATE_PRG));
 	}
 
+	/* if general error occurs, retry the write operation. */
+	if (gen_err) {
+		pr_warn("%s: retrying write for general error\n",
+				req->rq_disk->disk_name);
+		return MMC_BLK_RETRY;
+	}
+
 	if (brq->data.error) {
 		pr_err("%s: error %d transferring data, sector %u, nr %u, cmd response %#x, card status %#x\n",
 		       req->rq_disk->disk_name, brq->data.error,
@@ -1079,10 +1194,6 @@
 				return MMC_BLK_ECC_ERR;
 			return MMC_BLK_DATA_ERR;
 		} else {
-			if (brq->data.blocks > 1) {
-				   /* Hack to redo transfer one sector at a time */
-				   return MMC_BLK_DATA_ERR;
-			}
 			return MMC_BLK_CMD_ERR;
 		}
 	}
@@ -1090,12 +1201,78 @@
 	if (!brq->data.bytes_xfered)
 		return MMC_BLK_RETRY;
 
+	if (mmc_packed_cmd(mq_mrq->cmd_type)) {
+		if (unlikely(brq->data.blocks << 9 != brq->data.bytes_xfered))
+			return MMC_BLK_PARTIAL;
+		else
+			return MMC_BLK_SUCCESS;
+	}
+
 	if (blk_rq_bytes(req) != brq->data.bytes_xfered)
 		return MMC_BLK_PARTIAL;
 
 	return MMC_BLK_SUCCESS;
 }
 
+static int mmc_blk_packed_err_check(struct mmc_card *card,
+				    struct mmc_async_req *areq)
+{
+	struct mmc_queue_req *mq_rq = container_of(areq, struct mmc_queue_req,
+			mmc_active);
+	struct request *req = mq_rq->req;
+	struct mmc_packed *packed = mq_rq->packed;
+	int err, check, status;
+	u8 *ext_csd;
+
+	BUG_ON(!packed);
+
+	packed->retries--;
+	check = mmc_blk_err_check(card, areq);
+	err = get_card_status(card, &status, 0);
+	if (err) {
+		pr_err("%s: error %d sending status command\n",
+		       req->rq_disk->disk_name, err);
+		return MMC_BLK_ABORT;
+	}
+
+	if (status & R1_EXCEPTION_EVENT) {
+		ext_csd = kzalloc(512, GFP_KERNEL);
+		if (!ext_csd) {
+			pr_err("%s: unable to allocate buffer for ext_csd\n",
+			       req->rq_disk->disk_name);
+			return -ENOMEM;
+		}
+
+		err = mmc_send_ext_csd(card, ext_csd);
+		if (err) {
+			pr_err("%s: error %d sending ext_csd\n",
+			       req->rq_disk->disk_name, err);
+			check = MMC_BLK_ABORT;
+			goto free;
+		}
+
+		if ((ext_csd[EXT_CSD_EXP_EVENTS_STATUS] &
+		     EXT_CSD_PACKED_FAILURE) &&
+		    (ext_csd[EXT_CSD_PACKED_CMD_STATUS] &
+		     EXT_CSD_PACKED_GENERIC_ERROR)) {
+			if (ext_csd[EXT_CSD_PACKED_CMD_STATUS] &
+			    EXT_CSD_PACKED_INDEXED_ERROR) {
+				packed->idx_failure =
+				  ext_csd[EXT_CSD_PACKED_FAILURE_INDEX] - 1;
+				check = MMC_BLK_PARTIAL;
+			}
+			pr_err("%s: packed cmd failed, nr %u, sectors %u, "
+			       "failure index: %d\n",
+			       req->rq_disk->disk_name, packed->nr_entries,
+			       packed->blocks, packed->idx_failure);
+		}
+free:
+		kfree(ext_csd);
+	}
+
+	return check;
+}
+
 static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq,
 			       struct mmc_card *card,
 			       int disable_multi,
@@ -1250,10 +1427,221 @@
 	mmc_queue_bounce_pre(mqrq);
 }
 
+static inline u8 mmc_calc_packed_hdr_segs(struct request_queue *q,
+					  struct mmc_card *card)
+{
+	unsigned int hdr_sz = mmc_large_sector(card) ? 4096 : 512;
+	unsigned int max_seg_sz = queue_max_segment_size(q);
+	unsigned int len, nr_segs = 0;
+
+	do {
+		len = min(hdr_sz, max_seg_sz);
+		hdr_sz -= len;
+		nr_segs++;
+	} while (hdr_sz);
+
+	return nr_segs;
+}
+
+static u8 mmc_blk_prep_packed_list(struct mmc_queue *mq, struct request *req)
+{
+	struct request_queue *q = mq->queue;
+	struct mmc_card *card = mq->card;
+	struct request *cur = req, *next = NULL;
+	struct mmc_blk_data *md = mq->data;
+	struct mmc_queue_req *mqrq = mq->mqrq_cur;
+	bool en_rel_wr = card->ext_csd.rel_param & EXT_CSD_WR_REL_PARAM_EN;
+	unsigned int req_sectors = 0, phys_segments = 0;
+	unsigned int max_blk_count, max_phys_segs;
+	bool put_back = true;
+	u8 max_packed_rw = 0;
+	u8 reqs = 0;
+
+	if (!(md->flags & MMC_BLK_PACKED_CMD))
+		goto no_packed;
+
+	if ((rq_data_dir(cur) == WRITE) &&
+	    mmc_host_packed_wr(card->host))
+		max_packed_rw = card->ext_csd.max_packed_writes;
+
+	if (max_packed_rw == 0)
+		goto no_packed;
+
+	if (mmc_req_rel_wr(cur) &&
+	    (md->flags & MMC_BLK_REL_WR) && !en_rel_wr)
+		goto no_packed;
+
+	if (mmc_large_sector(card) &&
+	    !IS_ALIGNED(blk_rq_sectors(cur), 8))
+		goto no_packed;
+
+	mmc_blk_clear_packed(mqrq);
+
+	max_blk_count = min(card->host->max_blk_count,
+			    card->host->max_req_size >> 9);
+	if (unlikely(max_blk_count > 0xffff))
+		max_blk_count = 0xffff;
+
+	max_phys_segs = queue_max_segments(q);
+	req_sectors += blk_rq_sectors(cur);
+	phys_segments += cur->nr_phys_segments;
+
+	if (rq_data_dir(cur) == WRITE) {
+		req_sectors += mmc_large_sector(card) ? 8 : 1;
+		phys_segments += mmc_calc_packed_hdr_segs(q, card);
+	}
+
+	do {
+		if (reqs >= max_packed_rw - 1) {
+			put_back = false;
+			break;
+		}
+
+		spin_lock_irq(q->queue_lock);
+		next = blk_fetch_request(q);
+		spin_unlock_irq(q->queue_lock);
+		if (!next) {
+			put_back = false;
+			break;
+		}
+
+		if (mmc_large_sector(card) &&
+		    !IS_ALIGNED(blk_rq_sectors(next), 8))
+			break;
+
+		if (next->cmd_flags & REQ_DISCARD ||
+		    next->cmd_flags & REQ_FLUSH)
+			break;
+
+		if (rq_data_dir(cur) != rq_data_dir(next))
+			break;
+
+		if (mmc_req_rel_wr(next) &&
+		    (md->flags & MMC_BLK_REL_WR) && !en_rel_wr)
+			break;
+
+		req_sectors += blk_rq_sectors(next);
+		if (req_sectors > max_blk_count)
+			break;
+
+		phys_segments +=  next->nr_phys_segments;
+		if (phys_segments > max_phys_segs)
+			break;
+
+		list_add_tail(&next->queuelist, &mqrq->packed->list);
+		cur = next;
+		reqs++;
+	} while (1);
+
+	if (put_back) {
+		spin_lock_irq(q->queue_lock);
+		blk_requeue_request(q, next);
+		spin_unlock_irq(q->queue_lock);
+	}
+
+	if (reqs > 0) {
+		list_add(&req->queuelist, &mqrq->packed->list);
+		mqrq->packed->nr_entries = ++reqs;
+		mqrq->packed->retries = reqs;
+		return reqs;
+	}
+
+no_packed:
+	mqrq->cmd_type = MMC_PACKED_NONE;
+	return 0;
+}
+
+static void mmc_blk_packed_hdr_wrq_prep(struct mmc_queue_req *mqrq,
+					struct mmc_card *card,
+					struct mmc_queue *mq)
+{
+	struct mmc_blk_request *brq = &mqrq->brq;
+	struct request *req = mqrq->req;
+	struct request *prq;
+	struct mmc_blk_data *md = mq->data;
+	struct mmc_packed *packed = mqrq->packed;
+	bool do_rel_wr, do_data_tag;
+	u32 *packed_cmd_hdr;
+	u8 hdr_blocks;
+	u8 i = 1;
+
+	BUG_ON(!packed);
+
+	mqrq->cmd_type = MMC_PACKED_WRITE;
+	packed->blocks = 0;
+	packed->idx_failure = MMC_PACKED_NR_IDX;
+
+	packed_cmd_hdr = packed->cmd_hdr;
+	memset(packed_cmd_hdr, 0, sizeof(packed->cmd_hdr));
+	packed_cmd_hdr[0] = (packed->nr_entries << 16) |
+		(PACKED_CMD_WR << 8) | PACKED_CMD_VER;
+	hdr_blocks = mmc_large_sector(card) ? 8 : 1;
+
+	/*
+	 * Argument for each entry of packed group
+	 */
+	list_for_each_entry(prq, &packed->list, queuelist) {
+		do_rel_wr = mmc_req_rel_wr(prq) && (md->flags & MMC_BLK_REL_WR);
+		do_data_tag = (card->ext_csd.data_tag_unit_size) &&
+			(prq->cmd_flags & REQ_META) &&
+			(rq_data_dir(prq) == WRITE) &&
+			((brq->data.blocks * brq->data.blksz) >=
+			 card->ext_csd.data_tag_unit_size);
+		/* Argument of CMD23 */
+		packed_cmd_hdr[(i * 2)] =
+			(do_rel_wr ? MMC_CMD23_ARG_REL_WR : 0) |
+			(do_data_tag ? MMC_CMD23_ARG_TAG_REQ : 0) |
+			blk_rq_sectors(prq);
+		/* Argument of CMD18 or CMD25 */
+		packed_cmd_hdr[((i * 2)) + 1] =
+			mmc_card_blockaddr(card) ?
+			blk_rq_pos(prq) : blk_rq_pos(prq) << 9;
+		packed->blocks += blk_rq_sectors(prq);
+		i++;
+	}
+
+	memset(brq, 0, sizeof(struct mmc_blk_request));
+	brq->mrq.cmd = &brq->cmd;
+	brq->mrq.data = &brq->data;
+	brq->mrq.sbc = &brq->sbc;
+	brq->mrq.stop = &brq->stop;
+
+	brq->sbc.opcode = MMC_SET_BLOCK_COUNT;
+	brq->sbc.arg = MMC_CMD23_ARG_PACKED | (packed->blocks + hdr_blocks);
+	brq->sbc.flags = MMC_RSP_R1 | MMC_CMD_AC;
+
+	brq->cmd.opcode = MMC_WRITE_MULTIPLE_BLOCK;
+	brq->cmd.arg = blk_rq_pos(req);
+	if (!mmc_card_blockaddr(card))
+		brq->cmd.arg <<= 9;
+	brq->cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;
+
+	brq->data.blksz = 512;
+	brq->data.blocks = packed->blocks + hdr_blocks;
+	brq->data.flags |= MMC_DATA_WRITE;
+
+	brq->stop.opcode = MMC_STOP_TRANSMISSION;
+	brq->stop.arg = 0;
+	brq->stop.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC;
+
+	mmc_set_data_timeout(&brq->data, card);
+
+	brq->data.sg = mqrq->sg;
+	brq->data.sg_len = mmc_queue_map_sg(mq, mqrq);
+
+	mqrq->mmc_active.mrq = &brq->mrq;
+	mqrq->mmc_active.err_check = mmc_blk_packed_err_check;
+
+	mmc_queue_bounce_pre(mqrq);
+}
+
 static int mmc_blk_cmd_err(struct mmc_blk_data *md, struct mmc_card *card,
 			   struct mmc_blk_request *brq, struct request *req,
 			   int ret)
 {
+	struct mmc_queue_req *mq_rq;
+	mq_rq = container_of(brq, struct mmc_queue_req, brq);
+
 	/*
 	 * If this is an SD card and we're writing, we can first
 	 * mark the known good sectors as ok.
@@ -1267,18 +1655,87 @@
 
 		blocks = mmc_sd_num_wr_blocks(card);
 		if (blocks != (u32)-1) {
-			spin_lock_irq(&md->lock);
-			ret = __blk_end_request(req, 0, blocks << 9);
-			spin_unlock_irq(&md->lock);
+			ret = blk_end_request(req, 0, blocks << 9);
 		}
 	} else {
-		spin_lock_irq(&md->lock);
-		ret = __blk_end_request(req, 0, brq->data.bytes_xfered);
-		spin_unlock_irq(&md->lock);
+		if (!mmc_packed_cmd(mq_rq->cmd_type))
+			ret = blk_end_request(req, 0, brq->data.bytes_xfered);
+	}
+	return ret;
+}
+
+static int mmc_blk_end_packed_req(struct mmc_queue_req *mq_rq)
+{
+	struct request *prq;
+	struct mmc_packed *packed = mq_rq->packed;
+	int idx = packed->idx_failure, i = 0;
+	int ret = 0;
+
+	BUG_ON(!packed);
+
+	while (!list_empty(&packed->list)) {
+		prq = list_entry_rq(packed->list.next);
+		if (idx == i) {
+			/* retry from error index */
+			packed->nr_entries -= idx;
+			mq_rq->req = prq;
+			ret = 1;
+
+			if (packed->nr_entries == MMC_PACKED_NR_SINGLE) {
+				list_del_init(&prq->queuelist);
+				mmc_blk_clear_packed(mq_rq);
+			}
+			return ret;
+		}
+		list_del_init(&prq->queuelist);
+		blk_end_request(prq, 0, blk_rq_bytes(prq));
+		i++;
 	}
+
+	mmc_blk_clear_packed(mq_rq);
 	return ret;
 }
 
+static void mmc_blk_abort_packed_req(struct mmc_queue_req *mq_rq)
+{
+	struct request *prq;
+	struct mmc_packed *packed = mq_rq->packed;
+
+	BUG_ON(!packed);
+
+	while (!list_empty(&packed->list)) {
+		prq = list_entry_rq(packed->list.next);
+		list_del_init(&prq->queuelist);
+		blk_end_request(prq, -EIO, blk_rq_bytes(prq));
+	}
+
+	mmc_blk_clear_packed(mq_rq);
+}
+
+static void mmc_blk_revert_packed_req(struct mmc_queue *mq,
+				      struct mmc_queue_req *mq_rq)
+{
+	struct request *prq;
+	struct request_queue *q = mq->queue;
+	struct mmc_packed *packed = mq_rq->packed;
+
+	BUG_ON(!packed);
+
+	while (!list_empty(&packed->list)) {
+		prq = list_entry_rq(packed->list.prev);
+		if (prq->queuelist.prev != &packed->list) {
+			list_del_init(&prq->queuelist);
+			spin_lock_irq(q->queue_lock);
+			blk_requeue_request(mq->queue, prq);
+			spin_unlock_irq(q->queue_lock);
+		} else {
+			list_del_init(&prq->queuelist);
+		}
+	}
+
+	mmc_blk_clear_packed(mq_rq);
+}
+
 static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc)
 {
 	struct mmc_blk_data *md = mq->data;
@@ -1287,21 +1744,45 @@
 	int ret = 1, disable_multi = 0, retry = 0, type;
 	enum mmc_blk_status status;
 	struct mmc_queue_req *mq_rq;
-	struct request *req;
+	struct request *req = rqc;
 	struct mmc_async_req *areq;
+	const u8 packed_nr = 2;
+	u8 reqs = 0;
 
 	if (!rqc && !mq->mqrq_prev->req)
 		return 0;
 
+	if (rqc)
+		reqs = mmc_blk_prep_packed_list(mq, rqc);
+
 	do {
 		if (rqc) {
-			mmc_blk_rw_rq_prep(mq->mqrq_cur, card, 0, mq);
+			/*
+			 * When 4KB native sector is enabled, only 8 blocks
+			 * multiple read or write is allowed
+			 */
+			if ((brq->data.blocks & 0x07) &&
+			    (card->ext_csd.data_sector_size == 4096)) {
+				pr_err("%s: Transfer size is not 4KB sector size aligned\n",
+					req->rq_disk->disk_name);
+				mq_rq = mq->mqrq_cur;
+				goto cmd_abort;
+			}
+
+			if (reqs >= packed_nr)
+				mmc_blk_packed_hdr_wrq_prep(mq->mqrq_cur,
+							    card, mq);
+			else
+				mmc_blk_rw_rq_prep(mq->mqrq_cur, card, 0, mq);
 			areq = &mq->mqrq_cur->mmc_active;
 		} else
 			areq = NULL;
 		areq = mmc_start_req(card->host, areq, (int *) &status);
-		if (!areq)
+		if (!areq) {
+			if (status == MMC_BLK_NEW_REQUEST)
+				mq->flags |= MMC_QUEUE_NEW_REQUEST;
 			return 0;
+		}
 
 		mq_rq = container_of(areq, struct mmc_queue_req, mmc_active);
 		brq = &mq_rq->brq;
@@ -1316,10 +1797,15 @@
 			 * A block was successfully transferred.
 			 */
 			mmc_blk_reset_success(md, type);
-			spin_lock_irq(&md->lock);
-			ret = __blk_end_request(req, 0,
+
+			if (mmc_packed_cmd(mq_rq->cmd_type)) {
+				ret = mmc_blk_end_packed_req(mq_rq);
+				break;
+			} else {
+				ret = blk_end_request(req, 0,
 						brq->data.bytes_xfered);
-			spin_unlock_irq(&md->lock);
+			}
+
 			/*
 			 * If the blk_end_request function returns non-zero even
 			 * though all data has been transferred and no errors
@@ -1352,14 +1838,15 @@
 			err = mmc_blk_reset(md, card->host, type);
 			if (!err)
 				break;
-			if (err == -ENODEV)
+			if (err == -ENODEV ||
+				mmc_packed_cmd(mq_rq->cmd_type))
 				goto cmd_abort;
 			/* Fall through */
 		}
 		case MMC_BLK_ECC_ERR:
 			if (brq->data.blocks > 1) {
 				/* Redo read one sector at a time */
-				pr_warning("%s: retrying using single block transfer\n",
+				pr_warning("%s: retrying using single block read\n",
 					   req->rq_disk->disk_name);
 				disable_multi = 1;
 				break;
@@ -1369,61 +1856,82 @@
 			 * time, so we only reach here after trying to
 			 * read a single sector.
 			 */
-			spin_lock_irq(&md->lock);
-			ret = __blk_end_request(req, -EIO,
+			ret = blk_end_request(req, -EIO,
 						brq->data.blksz);
-			spin_unlock_irq(&md->lock);
 			if (!ret)
 				goto start_new_req;
 			break;
 		case MMC_BLK_NOMEDIUM:
 			goto cmd_abort;
+		default:
+			pr_err("%s: Unhandled return value (%d)",
+					req->rq_disk->disk_name, status);
+			goto cmd_abort;
 		}
 
 		if (ret) {
-			/*
-			 * In case of a incomplete request
-			 * prepare it again and resend.
-			 */
-			mmc_blk_rw_rq_prep(mq_rq, card, disable_multi, mq);
-			mmc_start_req(card->host, &mq_rq->mmc_active, NULL);
+			if (mmc_packed_cmd(mq_rq->cmd_type)) {
+				if (!mq_rq->packed->retries)
+					goto cmd_abort;
+				mmc_blk_packed_hdr_wrq_prep(mq_rq, card, mq);
+				mmc_start_req(card->host,
+					      &mq_rq->mmc_active, NULL);
+			} else {
+
+				/*
+				 * In case of a incomplete request
+				 * prepare it again and resend.
+				 */
+				mmc_blk_rw_rq_prep(mq_rq, card,
+						disable_multi, mq);
+				mmc_start_req(card->host,
+						&mq_rq->mmc_active, NULL);
+			}
 		}
 	} while (ret);
 
 	return 1;
 
  cmd_abort:
-	spin_lock_irq(&md->lock);
-	if (mmc_card_removed(card))
-		req->cmd_flags |= REQ_QUIET;
-	while (ret)
-		ret = __blk_end_request(req, -EIO, blk_rq_cur_bytes(req));
-	spin_unlock_irq(&md->lock);
+	if (mmc_packed_cmd(mq_rq->cmd_type)) {
+		mmc_blk_abort_packed_req(mq_rq);
+	} else {
+		if (mmc_card_removed(card))
+			req->cmd_flags |= REQ_QUIET;
+		while (ret)
+			ret = blk_end_request(req, -EIO,
+					blk_rq_cur_bytes(req));
+	}
 
  start_new_req:
 	if (rqc) {
-		mmc_blk_rw_rq_prep(mq->mqrq_cur, card, 0, mq);
-		mmc_start_req(card->host, &mq->mqrq_cur->mmc_active, NULL);
+		if (mmc_card_removed(card)) {
+			rqc->cmd_flags |= REQ_QUIET;
+			blk_end_request_all(rqc, -EIO);
+		} else {
+			/*
+			 * If current request is packed, it needs to put back.
+			 */
+			if (mmc_packed_cmd(mq->mqrq_cur->cmd_type))
+				mmc_blk_revert_packed_req(mq, mq->mqrq_cur);
+
+			mmc_blk_rw_rq_prep(mq->mqrq_cur, card, 0, mq);
+			mmc_start_req(card->host,
+				      &mq->mqrq_cur->mmc_active, NULL);
+		}
 	}
 
 	return 0;
 }
 
-static int
-mmc_blk_set_blksize(struct mmc_blk_data *md, struct mmc_card *card);
-
 static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
 {
 	int ret;
 	struct mmc_blk_data *md = mq->data;
 	struct mmc_card *card = md->queue.card;
-
-#ifdef CONFIG_MMC_BLOCK_DEFERRED_RESUME
-	if (mmc_bus_needs_resume(card->host)) {
-		mmc_resume_bus(card->host);
-		mmc_blk_set_blksize(md, card);
-	}
-#endif
+	struct mmc_host *host = card->host;
+	unsigned long flags;
+	unsigned int cmd_flags = req ? req->cmd_flags : 0;
 
 	if (req && !mq->mqrq_prev->req)
 		/* claim host only for the first request */
@@ -1432,34 +1940,45 @@
 	ret = mmc_blk_part_switch(card, md);
 	if (ret) {
 		if (req) {
-			spin_lock_irq(&md->lock);
-			__blk_end_request_all(req, -EIO);
-			spin_unlock_irq(&md->lock);
+			blk_end_request_all(req, -EIO);
 		}
 		ret = 0;
 		goto out;
 	}
 
-	if (req && req->cmd_flags & REQ_DISCARD) {
+	mq->flags &= ~MMC_QUEUE_NEW_REQUEST;
+	if (cmd_flags & REQ_DISCARD) {
 		/* complete ongoing async transfer before issuing discard */
 		if (card->host->areq)
 			mmc_blk_issue_rw_rq(mq, NULL);
-		if (req->cmd_flags & REQ_SECURE)
+		if (req->cmd_flags & REQ_SECURE &&
+			!(card->quirks & MMC_QUIRK_SEC_ERASE_TRIM_BROKEN))
 			ret = mmc_blk_issue_secdiscard_rq(mq, req);
 		else
 			ret = mmc_blk_issue_discard_rq(mq, req);
-	} else if (req && req->cmd_flags & REQ_FLUSH) {
+	} else if (cmd_flags & REQ_FLUSH) {
 		/* complete ongoing async transfer before issuing flush */
 		if (card->host->areq)
 			mmc_blk_issue_rw_rq(mq, NULL);
 		ret = mmc_blk_issue_flush(mq, req);
 	} else {
+		if (!req && host->areq) {
+			spin_lock_irqsave(&host->context_info.lock, flags);
+			host->context_info.is_waiting_last_req = true;
+			spin_unlock_irqrestore(&host->context_info.lock, flags);
+		}
 		ret = mmc_blk_issue_rw_rq(mq, req);
 	}
 
 out:
-	if (!req)
-		/* release host only when there are no more requests */
+	if ((!req && !(mq->flags & MMC_QUEUE_NEW_REQUEST)) ||
+	     (cmd_flags & MMC_REQ_SPECIAL_MASK))
+		/*
+		 * Release host when there are no more requests
+		 * and after special request(discard, flush) is done.
+		 * In case sepecial request, there is no reentry to
+		 * the 'mmc_blk_issue_rq' with 'mqrq_prev->req'.
+		 */
 		mmc_release_host(card->host);
 	return ret;
 }
@@ -1536,7 +2055,8 @@
 	md->disk->queue = md->queue.queue;
 	md->disk->driverfs_dev = parent;
 	set_disk_ro(md->disk, md->read_only || default_ro);
-	md->disk->flags = GENHD_FL_EXT_DEVT;
+	if (area_type & MMC_BLK_DATA_AREA_RPMB)
+		md->disk->flags |= GENHD_FL_NO_PART_SCAN;
 
 	/*
 	 * As discussed on lkml, GENHD_FL_REMOVABLE should:
@@ -1553,7 +2073,12 @@
 	snprintf(md->disk->disk_name, sizeof(md->disk->disk_name),
 		 "mmcblk%d%s", md->name_idx, subname ? subname : "");
 
-	blk_queue_logical_block_size(md->queue.queue, 512);
+	if (mmc_card_mmc(card))
+		blk_queue_logical_block_size(md->queue.queue,
+					     card->ext_csd.data_sector_size);
+	else
+		blk_queue_logical_block_size(md->queue.queue, 512);
+
 	set_capacity(md->disk, size);
 
 	if (mmc_host_cmd23(card->host)) {
@@ -1571,6 +2096,14 @@
 		blk_queue_flush(md->queue.queue, REQ_FLUSH | REQ_FUA);
 	}
 
+	if (mmc_card_mmc(card) &&
+	    (area_type == MMC_BLK_DATA_AREA_MAIN) &&
+	    (md->flags & MMC_BLK_CMD23) &&
+	    card->ext_csd.packed_event_en) {
+		if (!mmc_packed_init(&md->queue, card))
+			md->flags |= MMC_BLK_PACKED_CMD;
+	}
+
 	return md;
 
  err_putdisk:
@@ -1679,6 +2212,8 @@
 
 		/* Then flush out any already in there */
 		mmc_cleanup_queue(&md->queue);
+		if (md->flags & MMC_BLK_PACKED_CMD)
+			mmc_packed_clean(&md->queue);
 		mmc_blk_put(md);
 	}
 }
@@ -1745,6 +2280,7 @@
 #define CID_MANFID_SANDISK	0x2
 #define CID_MANFID_TOSHIBA	0x11
 #define CID_MANFID_MICRON	0x13
+#define CID_MANFID_SAMSUNG	0x15
 
 static const struct mmc_fixup blk_fixups[] =
 {
@@ -1781,6 +2317,28 @@
 	MMC_FIXUP(CID_NAME_ANY, CID_MANFID_MICRON, 0x200, add_quirk_mmc,
 		  MMC_QUIRK_LONG_READ_TIME),
 
+	/*
+	 * On these Samsung MoviNAND parts, performing secure erase or
+	 * secure trim can result in unrecoverable corruption due to a
+	 * firmware bug.
+	 */
+	MMC_FIXUP("M8G2FA", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc,
+		  MMC_QUIRK_SEC_ERASE_TRIM_BROKEN),
+	MMC_FIXUP("MAG4FA", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc,
+		  MMC_QUIRK_SEC_ERASE_TRIM_BROKEN),
+	MMC_FIXUP("MBG8FA", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc,
+		  MMC_QUIRK_SEC_ERASE_TRIM_BROKEN),
+	MMC_FIXUP("MCGAFA", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc,
+		  MMC_QUIRK_SEC_ERASE_TRIM_BROKEN),
+	MMC_FIXUP("VAL00M", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc,
+		  MMC_QUIRK_SEC_ERASE_TRIM_BROKEN),
+	MMC_FIXUP("VYL00M", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc,
+		  MMC_QUIRK_SEC_ERASE_TRIM_BROKEN),
+	MMC_FIXUP("KYL00M", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc,
+		  MMC_QUIRK_SEC_ERASE_TRIM_BROKEN),
+	MMC_FIXUP("VZL00M", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc,
+		  MMC_QUIRK_SEC_ERASE_TRIM_BROKEN),
+
 	END_FIXUP
 };
 
@@ -1811,9 +2369,6 @@
 	mmc_set_drvdata(card, md);
 	mmc_fixup_device(card, blk_fixups);
 
-#ifdef CONFIG_MMC_BLOCK_DEFERRED_RESUME
-	mmc_set_bus_resume_policy(card->host, 1);
-#endif
 	if (mmc_add_disk(md))
 		goto out;
 
@@ -1839,9 +2394,6 @@
 	mmc_release_host(card->host);
 	mmc_blk_remove_req(md);
 	mmc_set_drvdata(card, NULL);
-#ifdef CONFIG_MMC_BLOCK_DEFERRED_RESUME
-	mmc_set_bus_resume_policy(card->host, 0);
-#endif
 }
 
 #ifdef CONFIG_PM
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/card/Kconfig linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/card/Kconfig
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/card/Kconfig	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/card/Kconfig	2014-09-12 15:59:37.348052000 +0800
@@ -50,17 +50,9 @@
 
 	  If unsure, say Y here.
 
-config MMC_BLOCK_DEFERRED_RESUME
-	bool "Deferr MMC layer resume until I/O is requested"
-	depends on MMC_BLOCK
-	default n
-	help
-	  Say Y here to enable deferred MMC resume until I/O
-	  is requested. This will reduce overall resume latency and
-	  save power when theres an SD card inserted but not being used.
-
 config SDIO_UART
 	tristate "SDIO UART/GPS class support"
+	depends on TTY
 	help
 	  SDIO function driver for SDIO cards that implements the UART
 	  class, as well as the GPS class which appears like a UART.
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/card/queue.c linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/card/queue.c
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/card/queue.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/card/queue.c	2014-09-12 15:59:37.348052000 +0800
@@ -22,8 +22,6 @@
 
 #define MMC_QUEUE_BOUNCESZ	65536
 
-#define MMC_QUEUE_SUSPENDED	(1 << 0)
-
 /*
  * Prepare a MMC request. This just filters out odd stuff.
  */
@@ -58,6 +56,7 @@
 	do {
 		struct request *req = NULL;
 		struct mmc_queue_req *tmp;
+		unsigned int cmd_flags = 0;
 
 		spin_lock_irq(q->queue_lock);
 		set_current_state(TASK_INTERRUPTIBLE);
@@ -67,7 +66,28 @@
 
 		if (req || mq->mqrq_prev->req) {
 			set_current_state(TASK_RUNNING);
+			cmd_flags = req ? req->cmd_flags : 0;
 			mq->issue_fn(mq, req);
+			if (mq->flags & MMC_QUEUE_NEW_REQUEST) {
+				mq->flags &= ~MMC_QUEUE_NEW_REQUEST;
+				continue; /* fetch again */
+			}
+
+			/*
+			 * Current request becomes previous request
+			 * and vice versa.
+			 * In case of special requests, current request
+			 * has been finished. Do not assign it to previous
+			 * request.
+			 */
+			if (cmd_flags & MMC_REQ_SPECIAL_MASK)
+				mq->mqrq_cur->req = NULL;
+
+			mq->mqrq_prev->brq.mrq.data = NULL;
+			mq->mqrq_prev->req = NULL;
+			tmp = mq->mqrq_prev;
+			mq->mqrq_prev = mq->mqrq_cur;
+			mq->mqrq_cur = tmp;
 		} else {
 			if (kthread_should_stop()) {
 				set_current_state(TASK_RUNNING);
@@ -77,13 +97,6 @@
 			schedule();
 			down(&mq->thread_sem);
 		}
-
-		/* Current request becomes previous request and vice versa. */
-		mq->mqrq_prev->brq.mrq.data = NULL;
-		mq->mqrq_prev->req = NULL;
-		tmp = mq->mqrq_prev;
-		mq->mqrq_prev = mq->mqrq_cur;
-		mq->mqrq_cur = tmp;
 	} while (1);
 	up(&mq->thread_sem);
 
@@ -96,10 +109,12 @@
  * on any queue on this host, and attempt to issue it.  This may
  * not be the queue we were asked to process.
  */
-static void mmc_request(struct request_queue *q)
+static void mmc_request_fn(struct request_queue *q)
 {
 	struct mmc_queue *mq = q->queuedata;
 	struct request *req;
+	unsigned long flags;
+	struct mmc_context_info *cntx;
 
 	if (!mq) {
 		while ((req = blk_fetch_request(q)) != NULL) {
@@ -109,7 +124,20 @@
 		return;
 	}
 
-	if (!mq->mqrq_cur->req && !mq->mqrq_prev->req)
+	cntx = &mq->card->host->context_info;
+	if (!mq->mqrq_cur->req && mq->mqrq_prev->req) {
+		/*
+		 * New MMC request arrived when MMC thread may be
+		 * blocked on the previous request to be complete
+		 * with no current request fetched
+		 */
+		spin_lock_irqsave(&cntx->lock, flags);
+		if (cntx->is_waiting_last_req) {
+			cntx->is_new_req = true;
+			wake_up_interruptible(&cntx->wait);
+		}
+		spin_unlock_irqrestore(&cntx->lock, flags);
+	} else if (!mq->mqrq_cur->req && !mq->mqrq_prev->req)
 		wake_up_process(mq->thread);
 }
 
@@ -171,12 +199,10 @@
 		limit = *mmc_dev(host)->dma_mask;
 
 	mq->card = card;
-	mq->queue = blk_init_queue(mmc_request, lock);
+	mq->queue = blk_init_queue(mmc_request_fn, lock);
 	if (!mq->queue)
 		return -ENOMEM;
 
-	memset(&mq->mqrq_cur, 0, sizeof(mq->mqrq_cur));
-	memset(&mq->mqrq_prev, 0, sizeof(mq->mqrq_prev));
 	mq->mqrq_cur = mqrq_cur;
 	mq->mqrq_prev = mqrq_prev;
 	mq->queue->queuedata = mq;
@@ -333,6 +359,49 @@
 }
 EXPORT_SYMBOL(mmc_cleanup_queue);
 
+int mmc_packed_init(struct mmc_queue *mq, struct mmc_card *card)
+{
+	struct mmc_queue_req *mqrq_cur = &mq->mqrq[0];
+	struct mmc_queue_req *mqrq_prev = &mq->mqrq[1];
+	int ret = 0;
+
+
+	mqrq_cur->packed = kzalloc(sizeof(struct mmc_packed), GFP_KERNEL);
+	if (!mqrq_cur->packed) {
+		pr_warn("%s: unable to allocate packed cmd for mqrq_cur\n",
+			mmc_card_name(card));
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	mqrq_prev->packed = kzalloc(sizeof(struct mmc_packed), GFP_KERNEL);
+	if (!mqrq_prev->packed) {
+		pr_warn("%s: unable to allocate packed cmd for mqrq_prev\n",
+			mmc_card_name(card));
+		kfree(mqrq_cur->packed);
+		mqrq_cur->packed = NULL;
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	INIT_LIST_HEAD(&mqrq_cur->packed->list);
+	INIT_LIST_HEAD(&mqrq_prev->packed->list);
+
+out:
+	return ret;
+}
+
+void mmc_packed_clean(struct mmc_queue *mq)
+{
+	struct mmc_queue_req *mqrq_cur = &mq->mqrq[0];
+	struct mmc_queue_req *mqrq_prev = &mq->mqrq[1];
+
+	kfree(mqrq_cur->packed);
+	mqrq_cur->packed = NULL;
+	kfree(mqrq_prev->packed);
+	mqrq_prev->packed = NULL;
+}
+
 /**
  * mmc_queue_suspend - suspend a MMC request queue
  * @mq: MMC queue to suspend
@@ -377,6 +446,41 @@
 	}
 }
 
+static unsigned int mmc_queue_packed_map_sg(struct mmc_queue *mq,
+					    struct mmc_packed *packed,
+					    struct scatterlist *sg,
+					    enum mmc_packed_type cmd_type)
+{
+	struct scatterlist *__sg = sg;
+	unsigned int sg_len = 0;
+	struct request *req;
+
+	if (mmc_packed_wr(cmd_type)) {
+		unsigned int hdr_sz = mmc_large_sector(mq->card) ? 4096 : 512;
+		unsigned int max_seg_sz = queue_max_segment_size(mq->queue);
+		unsigned int len, remain, offset = 0;
+		u8 *buf = (u8 *)packed->cmd_hdr;
+
+		remain = hdr_sz;
+		do {
+			len = min(remain, max_seg_sz);
+			sg_set_buf(__sg, buf + offset, len);
+			offset += len;
+			remain -= len;
+			(__sg++)->page_link &= ~0x02;
+			sg_len++;
+		} while (remain);
+	}
+
+	list_for_each_entry(req, &packed->list, queuelist) {
+		sg_len += blk_rq_map_sg(mq->queue, req, __sg);
+		__sg = sg + (sg_len - 1);
+		(__sg++)->page_link &= ~0x02;
+	}
+	sg_mark_end(sg + (sg_len - 1));
+	return sg_len;
+}
+
 /*
  * Prepare the sg list(s) to be handed of to the host driver
  */
@@ -385,14 +489,26 @@
 	unsigned int sg_len;
 	size_t buflen;
 	struct scatterlist *sg;
+	enum mmc_packed_type cmd_type;
 	int i;
 
-	if (!mqrq->bounce_buf)
-		return blk_rq_map_sg(mq->queue, mqrq->req, mqrq->sg);
+	cmd_type = mqrq->cmd_type;
+
+	if (!mqrq->bounce_buf) {
+		if (mmc_packed_cmd(cmd_type))
+			return mmc_queue_packed_map_sg(mq, mqrq->packed,
+						       mqrq->sg, cmd_type);
+		else
+			return blk_rq_map_sg(mq->queue, mqrq->req, mqrq->sg);
+	}
 
 	BUG_ON(!mqrq->bounce_sg);
 
-	sg_len = blk_rq_map_sg(mq->queue, mqrq->req, mqrq->bounce_sg);
+	if (mmc_packed_cmd(cmd_type))
+		sg_len = mmc_queue_packed_map_sg(mq, mqrq->packed,
+						 mqrq->bounce_sg, cmd_type);
+	else
+		sg_len = blk_rq_map_sg(mq->queue, mqrq->req, mqrq->bounce_sg);
 
 	mqrq->bounce_sg_len = sg_len;
 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/card/queue.h linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/card/queue.h
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/card/queue.h	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/card/queue.h	2014-09-12 15:59:37.348052000 +0800
@@ -1,6 +1,8 @@
 #ifndef MMC_QUEUE_H
 #define MMC_QUEUE_H
 
+#define MMC_REQ_SPECIAL_MASK	(REQ_DISCARD | REQ_FLUSH)
+
 struct request;
 struct task_struct;
 
@@ -12,6 +14,23 @@
 	struct mmc_data		data;
 };
 
+enum mmc_packed_type {
+	MMC_PACKED_NONE = 0,
+	MMC_PACKED_WRITE,
+};
+
+#define mmc_packed_cmd(type)	((type) != MMC_PACKED_NONE)
+#define mmc_packed_wr(type)	((type) == MMC_PACKED_WRITE)
+
+struct mmc_packed {
+	struct list_head	list;
+	u32			cmd_hdr[1024];
+	unsigned int		blocks;
+	u8			nr_entries;
+	u8			retries;
+	s16			idx_failure;
+};
+
 struct mmc_queue_req {
 	struct request		*req;
 	struct mmc_blk_request	brq;
@@ -20,6 +39,8 @@
 	struct scatterlist	*bounce_sg;
 	unsigned int		bounce_sg_len;
 	struct mmc_async_req	mmc_active;
+	enum mmc_packed_type	cmd_type;
+	struct mmc_packed	*packed;
 };
 
 struct mmc_queue {
@@ -27,6 +48,9 @@
 	struct task_struct	*thread;
 	struct semaphore	thread_sem;
 	unsigned int		flags;
+#define MMC_QUEUE_SUSPENDED	(1 << 0)
+#define MMC_QUEUE_NEW_REQUEST	(1 << 1)
+
 	int			(*issue_fn)(struct mmc_queue *, struct request *);
 	void			*data;
 	struct request_queue	*queue;
@@ -46,4 +70,7 @@
 extern void mmc_queue_bounce_pre(struct mmc_queue_req *);
 extern void mmc_queue_bounce_post(struct mmc_queue_req *);
 
+extern int mmc_packed_init(struct mmc_queue *, struct mmc_card *);
+extern void mmc_packed_clean(struct mmc_queue *);
+
 #endif
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/card/sdio_uart.c linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/card/sdio_uart.c
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/card/sdio_uart.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/card/sdio_uart.c	2014-09-12 15:59:37.348052000 +0800
@@ -66,8 +66,6 @@
 
 struct sdio_uart_port {
 	struct tty_port		port;
-	struct kref		kref;
-	struct tty_struct	*tty;
 	unsigned int		index;
 	struct sdio_func	*func;
 	struct mutex		func_lock;
@@ -93,7 +91,6 @@
 {
 	int index, ret = -EBUSY;
 
-	kref_init(&port->kref);
 	mutex_init(&port->func_lock);
 	spin_lock_init(&port->write_lock);
 	if (kfifo_alloc(&port->xmit_fifo, FIFO_SIZE, GFP_KERNEL))
@@ -123,29 +120,20 @@
 	spin_lock(&sdio_uart_table_lock);
 	port = sdio_uart_table[index];
 	if (port)
-		kref_get(&port->kref);
+		tty_port_get(&port->port);
 	spin_unlock(&sdio_uart_table_lock);
 
 	return port;
 }
 
-static void sdio_uart_port_destroy(struct kref *kref)
-{
-	struct sdio_uart_port *port =
-		container_of(kref, struct sdio_uart_port, kref);
-	kfifo_free(&port->xmit_fifo);
-	kfree(port);
-}
-
 static void sdio_uart_port_put(struct sdio_uart_port *port)
 {
-	kref_put(&port->kref, sdio_uart_port_destroy);
+	tty_port_put(&port->port);
 }
 
 static void sdio_uart_port_remove(struct sdio_uart_port *port)
 {
 	struct sdio_func *func;
-	struct tty_struct *tty;
 
 	BUG_ON(sdio_uart_table[port->index] != port);
 
@@ -166,12 +154,8 @@
 	sdio_claim_host(func);
 	port->func = NULL;
 	mutex_unlock(&port->func_lock);
-	tty = tty_port_tty_get(&port->port);
 	/* tty_hangup is async so is this safe as is ?? */
-	if (tty) {
-		tty_hangup(tty);
-		tty_kref_put(tty);
-	}
+	tty_port_tty_hangup(&port->port, false);
 	mutex_unlock(&port->port.mutex);
 	sdio_release_irq(func);
 	sdio_disable_func(func);
@@ -392,7 +376,6 @@
 static void sdio_uart_receive_chars(struct sdio_uart_port *port,
 				    unsigned int *status)
 {
-	struct tty_struct *tty = tty_port_tty_get(&port->port);
 	unsigned int ch, flag;
 	int max_count = 256;
 
@@ -429,23 +412,19 @@
 		}
 
 		if ((*status & port->ignore_status_mask & ~UART_LSR_OE) == 0)
-			if (tty)
-				tty_insert_flip_char(tty, ch, flag);
+			tty_insert_flip_char(&port->port, ch, flag);
 
 		/*
 		 * Overrun is special.  Since it's reported immediately,
 		 * it doesn't affect the current character.
 		 */
 		if (*status & ~port->ignore_status_mask & UART_LSR_OE)
-			if (tty)
-				tty_insert_flip_char(tty, 0, TTY_OVERRUN);
+			tty_insert_flip_char(&port->port, 0, TTY_OVERRUN);
 
 		*status = sdio_in(port, UART_LSR);
 	} while ((*status & UART_LSR_DR) && (max_count-- > 0));
-	if (tty) {
-		tty_flip_buffer_push(tty);
-		tty_kref_put(tty);
-	}
+
+	tty_flip_buffer_push(&port->port);
 }
 
 static void sdio_uart_transmit_chars(struct sdio_uart_port *port)
@@ -508,17 +487,13 @@
 			wake_up_interruptible(&port->port.open_wait);
 		else {
 			/* DCD drop - hang up if tty attached */
-			tty = tty_port_tty_get(&port->port);
-			if (tty) {
-				tty_hangup(tty);
-				tty_kref_put(tty);
-			}
+			tty_port_tty_hangup(&port->port, false);
 		}
 	}
 	if (status & UART_MSR_DCTS) {
 		port->icount.cts++;
 		tty = tty_port_tty_get(&port->port);
-		if (tty && (tty->termios->c_cflag & CRTSCTS)) {
+		if (tty && (tty->termios.c_cflag & CRTSCTS)) {
 			int cts = (status & UART_MSR_CTS);
 			if (tty->hw_stopped) {
 				if (cts) {
@@ -671,12 +646,12 @@
 	port->ier = UART_IER_RLSI|UART_IER_RDI|UART_IER_RTOIE|UART_IER_UUE;
 	port->mctrl = TIOCM_OUT2;
 
-	sdio_uart_change_speed(port, tty->termios, NULL);
+	sdio_uart_change_speed(port, &tty->termios, NULL);
 
-	if (tty->termios->c_cflag & CBAUD)
+	if (tty->termios.c_cflag & CBAUD)
 		sdio_uart_set_mctrl(port, TIOCM_RTS | TIOCM_DTR);
 
-	if (tty->termios->c_cflag & CRTSCTS)
+	if (tty->termios.c_cflag & CRTSCTS)
 		if (!(sdio_uart_get_mctrl(port) & TIOCM_CTS))
 			tty->hw_stopped = 1;
 
@@ -737,6 +712,14 @@
 	sdio_uart_release_func(port);
 }
 
+static void sdio_uart_port_destroy(struct tty_port *tport)
+{
+	struct sdio_uart_port *port =
+		container_of(tport, struct sdio_uart_port, port);
+	kfifo_free(&port->xmit_fifo);
+	kfree(port);
+}
+
 /**
  *	sdio_uart_install	-	install method
  *	@driver: the driver in use (sdio_uart in our case)
@@ -850,7 +833,7 @@
 {
 	struct sdio_uart_port *port = tty->driver_data;
 
-	if (!I_IXOFF(tty) && !(tty->termios->c_cflag & CRTSCTS))
+	if (!I_IXOFF(tty) && !(tty->termios.c_cflag & CRTSCTS))
 		return;
 
 	if (sdio_uart_claim_func(port) != 0)
@@ -861,7 +844,7 @@
 		sdio_uart_start_tx(port);
 	}
 
-	if (tty->termios->c_cflag & CRTSCTS)
+	if (tty->termios.c_cflag & CRTSCTS)
 		sdio_uart_clear_mctrl(port, TIOCM_RTS);
 
 	sdio_uart_irq(port->func);
@@ -872,7 +855,7 @@
 {
 	struct sdio_uart_port *port = tty->driver_data;
 
-	if (!I_IXOFF(tty) && !(tty->termios->c_cflag & CRTSCTS))
+	if (!I_IXOFF(tty) && !(tty->termios.c_cflag & CRTSCTS))
 		return;
 
 	if (sdio_uart_claim_func(port) != 0)
@@ -887,7 +870,7 @@
 		}
 	}
 
-	if (tty->termios->c_cflag & CRTSCTS)
+	if (tty->termios.c_cflag & CRTSCTS)
 		sdio_uart_set_mctrl(port, TIOCM_RTS);
 
 	sdio_uart_irq(port->func);
@@ -898,12 +881,12 @@
 						struct ktermios *old_termios)
 {
 	struct sdio_uart_port *port = tty->driver_data;
-	unsigned int cflag = tty->termios->c_cflag;
+	unsigned int cflag = tty->termios.c_cflag;
 
 	if (sdio_uart_claim_func(port) != 0)
 		return;
 
-	sdio_uart_change_speed(port, tty->termios, old_termios);
+	sdio_uart_change_speed(port, &tty->termios, old_termios);
 
 	/* Handle transition to B0 status */
 	if ((old_termios->c_cflag & CBAUD) && !(cflag & CBAUD))
@@ -1045,6 +1028,7 @@
 	.carrier_raised = uart_carrier_raised,
 	.shutdown = sdio_uart_shutdown,
 	.activate = sdio_uart_activate,
+	.destruct = sdio_uart_port_destroy,
 };
 
 static const struct tty_operations sdio_uart_ops = {
@@ -1132,8 +1116,8 @@
 		kfree(port);
 	} else {
 		struct device *dev;
-		dev = tty_register_device(sdio_uart_tty_driver,
-						port->index, &func->dev);
+		dev = tty_port_register_device(&port->port,
+				sdio_uart_tty_driver, port->index, &func->dev);
 		if (IS_ERR(dev)) {
 			sdio_uart_port_remove(port);
 			ret = PTR_ERR(dev);
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/core/bus.c linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/core/bus.c
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/core/bus.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/core/bus.c	2014-09-12 15:59:37.348052000 +0800
@@ -122,6 +122,7 @@
 	return 0;
 }
 
+#ifdef CONFIG_PM_SLEEP
 static int mmc_bus_suspend(struct device *dev)
 {
 	struct mmc_driver *drv = to_mmc_driver(dev->driver);
@@ -143,6 +144,7 @@
 		ret = drv->resume(card);
 	return ret;
 }
+#endif
 
 #ifdef CONFIG_PM_RUNTIME
 
@@ -223,8 +225,7 @@
 
 	sdio_free_common_cis(card);
 
-	if (card->info)
-		kfree(card->info);
+	kfree(card->info);
 
 	kfree(card);
 }
@@ -320,6 +321,7 @@
 #ifdef CONFIG_DEBUG_FS
 	mmc_add_card_debugfs(card);
 #endif
+	mmc_init_context_info(card->host);
 
 	ret = device_add(&card->dev);
 	if (ret)
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/core/cd-gpio.c linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/core/cd-gpio.c
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/core/cd-gpio.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/core/cd-gpio.c	1970-01-01 08:00:00.000000000 +0800
@@ -1,80 +0,0 @@
-/*
- * Generic GPIO card-detect helper
- *
- * Copyright (C) 2011, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
- *
- * 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/err.h>
-#include <linux/gpio.h>
-#include <linux/interrupt.h>
-#include <linux/jiffies.h>
-#include <linux/mmc/cd-gpio.h>
-#include <linux/mmc/host.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-
-struct mmc_cd_gpio {
-	unsigned int gpio;
-	char label[0];
-};
-
-static irqreturn_t mmc_cd_gpio_irqt(int irq, void *dev_id)
-{
-	/* Schedule a card detection after a debounce timeout */
-	mmc_detect_change(dev_id, msecs_to_jiffies(100));
-	return IRQ_HANDLED;
-}
-
-int mmc_cd_gpio_request(struct mmc_host *host, unsigned int gpio)
-{
-	size_t len = strlen(dev_name(host->parent)) + 4;
-	struct mmc_cd_gpio *cd;
-	int irq = gpio_to_irq(gpio);
-	int ret;
-
-	if (irq < 0)
-		return irq;
-
-	cd = kmalloc(sizeof(*cd) + len, GFP_KERNEL);
-	if (!cd)
-		return -ENOMEM;
-
-	snprintf(cd->label, len, "%s cd", dev_name(host->parent));
-
-	ret = gpio_request_one(gpio, GPIOF_DIR_IN, cd->label);
-	if (ret < 0)
-		goto egpioreq;
-
-	ret = request_threaded_irq(irq, NULL, mmc_cd_gpio_irqt,
-				   IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
-				   cd->label, host);
-	if (ret < 0)
-		goto eirqreq;
-
-	cd->gpio = gpio;
-	host->hotplug.irq = irq;
-	host->hotplug.handler_priv = cd;
-
-	return 0;
-
-eirqreq:
-	gpio_free(gpio);
-egpioreq:
-	kfree(cd);
-	return ret;
-}
-EXPORT_SYMBOL(mmc_cd_gpio_request);
-
-void mmc_cd_gpio_free(struct mmc_host *host)
-{
-	struct mmc_cd_gpio *cd = host->hotplug.handler_priv;
-
-	free_irq(host->hotplug.irq, host);
-	gpio_free(cd->gpio);
-	kfree(cd);
-}
-EXPORT_SYMBOL(mmc_cd_gpio_free);
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/core/core.c linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/core/core.c
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/core/core.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/core/core.c	2014-10-22 17:08:19.590661000 +0800
@@ -26,7 +26,7 @@
 #include <linux/suspend.h>
 #include <linux/fault-inject.h>
 #include <linux/random.h>
-#include <linux/wakelock.h>
+#include <linux/slab.h>
 
 #include <linux/mmc/card.h>
 #include <linux/mmc/host.h>
@@ -42,7 +42,17 @@
 #include "sd_ops.h"
 #include "sdio_ops.h"
 
+/* If the device is not responding */
+#define MMC_CORE_TIMEOUT_MS	(10 * 60 * 1000) /* 10 minute timeout */
+
+/*
+ * Background operations can take a long time, depending on the housekeeping
+ * operations the card has to perform.
+ */
+#define MMC_BKOPS_MAX_TIMEOUT	(4 * 60 * 1000) /* max time to wait in ms */
+
 static struct workqueue_struct *workqueue;
+static const unsigned freqs[] = { 400000, 300000, 200000, 100000 };
 
 /*
  * Enabling software CRCs on the data blocks can be a significant (30%)
@@ -110,8 +120,8 @@
 	    !should_fail(&host->fail_mmc_request, data->blksz * data->blocks))
 		return;
 
-	data->error = data_errors[random32() % ARRAY_SIZE(data_errors)];
-	data->bytes_xfered = (random32() % (data->bytes_xfered >> 9)) << 9;
+	data->error = data_errors[prandom_u32() % ARRAY_SIZE(data_errors)];
+	data->bytes_xfered = (prandom_u32() % (data->bytes_xfered >> 9)) << 9;
 }
 
 #else /* CONFIG_FAIL_MMC_REQUEST */
@@ -245,11 +255,109 @@
 	host->ops->request(host, mrq);
 }
 
+/**
+ *	mmc_start_bkops - start BKOPS for supported cards
+ *	@card: MMC card to start BKOPS
+ *	@form_exception: A flag to indicate if this function was
+ *			 called due to an exception raised by the card
+ *
+ *	Start background operations whenever requested.
+ *	When the urgent BKOPS bit is set in a R1 command response
+ *	then background operations should be started immediately.
+*/
+void mmc_start_bkops(struct mmc_card *card, bool from_exception)
+{
+	int err;
+	int timeout;
+	bool use_busy_signal;
+
+	BUG_ON(!card);
+
+	if (!card->ext_csd.bkops_en || mmc_card_doing_bkops(card))
+		return;
+
+	err = mmc_read_bkops_status(card);
+	if (err) {
+		pr_err("%s: Failed to read bkops status: %d\n",
+		       mmc_hostname(card->host), err);
+		return;
+	}
+
+	if (!card->ext_csd.raw_bkops_status)
+		return;
+
+	if (card->ext_csd.raw_bkops_status < EXT_CSD_BKOPS_LEVEL_2 &&
+	    from_exception)
+		return;
+
+	mmc_claim_host(card->host);
+	if (card->ext_csd.raw_bkops_status >= EXT_CSD_BKOPS_LEVEL_2) {
+		timeout = MMC_BKOPS_MAX_TIMEOUT;
+		use_busy_signal = true;
+	} else {
+		timeout = 0;
+		use_busy_signal = false;
+	}
+
+	err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
+			EXT_CSD_BKOPS_START, 1, timeout, use_busy_signal);
+	if (err) {
+		pr_warn("%s: Error %d starting bkops\n",
+			mmc_hostname(card->host), err);
+		goto out;
+	}
+
+	/*
+	 * For urgent bkops status (LEVEL_2 and more)
+	 * bkops executed synchronously, otherwise
+	 * the operation is in progress
+	 */
+	if (!use_busy_signal)
+		mmc_card_set_doing_bkops(card);
+out:
+	mmc_release_host(card->host);
+}
+EXPORT_SYMBOL(mmc_start_bkops);
+
+/*
+ * mmc_wait_data_done() - done callback for data request
+ * @mrq: done data request
+ *
+ * Wakes up mmc context, passed as a callback to host controller driver
+ */
+static void mmc_wait_data_done(struct mmc_request *mrq)
+{
+	mrq->host->context_info.is_done_rcv = true;
+	wake_up_interruptible(&mrq->host->context_info.wait);
+}
+
 static void mmc_wait_done(struct mmc_request *mrq)
 {
 	complete(&mrq->completion);
 }
 
+/*
+ *__mmc_start_data_req() - starts data request
+ * @host: MMC host to start the request
+ * @mrq: data request to start
+ *
+ * Sets the done callback to be called when request is completed by the card.
+ * Starts data mmc request execution
+ */
+static int __mmc_start_data_req(struct mmc_host *host, struct mmc_request *mrq)
+{
+	mrq->done = mmc_wait_data_done;
+	mrq->host = host;
+	if (mmc_card_removed(host->card)) {
+		mrq->cmd->error = -ENOMEDIUM;
+		mmc_wait_data_done(mrq);
+		return -ENOMEDIUM;
+	}
+	mmc_start_request(host, mrq);
+
+	return 0;
+}
+
 static int __mmc_start_req(struct mmc_host *host, struct mmc_request *mrq)
 {
 	init_completion(&mrq->completion);
@@ -263,6 +371,62 @@
 	return 0;
 }
 
+/*
+ * mmc_wait_for_data_req_done() - wait for request completed
+ * @host: MMC host to prepare the command.
+ * @mrq: MMC request to wait for
+ *
+ * Blocks MMC context till host controller will ack end of data request
+ * execution or new request notification arrives from the block layer.
+ * Handles command retries.
+ *
+ * Returns enum mmc_blk_status after checking errors.
+ */
+static int mmc_wait_for_data_req_done(struct mmc_host *host,
+				      struct mmc_request *mrq,
+				      struct mmc_async_req *next_req)
+{
+	struct mmc_command *cmd;
+	struct mmc_context_info *context_info = &host->context_info;
+	int err;
+	unsigned long flags;
+
+	while (1) {
+		wait_event_interruptible(context_info->wait,
+				(context_info->is_done_rcv ||
+				 context_info->is_new_req));
+		spin_lock_irqsave(&context_info->lock, flags);
+		context_info->is_waiting_last_req = false;
+		spin_unlock_irqrestore(&context_info->lock, flags);
+		if (context_info->is_done_rcv) {
+			context_info->is_done_rcv = false;
+			context_info->is_new_req = false;
+			cmd = mrq->cmd;
+			if (!cmd->error || !cmd->retries ||
+			    mmc_card_removed(host->card)) {
+				err = host->areq->err_check(host->card,
+							    host->areq);
+				break; /* return err */
+			} else {
+				pr_info("%s: req failed (CMD%u): %d, retrying...\n",
+					mmc_hostname(host),
+					cmd->opcode, cmd->error);
+				cmd->retries--;
+				cmd->error = 0;
+				host->ops->request(host, mrq);
+				continue; /* wait for done/new event again */
+			}
+		} else if (context_info->is_new_req) {
+			context_info->is_new_req = false;
+			if (!next_req) {
+				err = MMC_BLK_NEW_REQUEST;
+				break; /* return err */
+			}
+		}
+	}
+	return err;
+}
+
 static void mmc_wait_for_req_done(struct mmc_host *host,
 				  struct mmc_request *mrq)
 {
@@ -352,19 +516,35 @@
 		mmc_pre_req(host, areq->mrq, !host->areq);
 
 	if (host->areq) {
-		mmc_wait_for_req_done(host, host->areq->mrq);
-		err = host->areq->err_check(host->card, host->areq);
+		err = mmc_wait_for_data_req_done(host, host->areq->mrq,	areq);
+		if (err == MMC_BLK_NEW_REQUEST) {
+			if (error)
+				*error = err;
+			/*
+			 * The previous request was not completed,
+			 * nothing to return
+			 */
+			return NULL;
+		}
+		/*
+		 * Check BKOPS urgency for each R1 response
+		 */
+		if (host->card && mmc_card_mmc(host->card) &&
+		    ((mmc_resp_type(host->areq->mrq->cmd) == MMC_RSP_R1) ||
+		     (mmc_resp_type(host->areq->mrq->cmd) == MMC_RSP_R1B)) &&
+		    (host->areq->mrq->cmd->resp[0] & R1_EXCEPTION_EVENT))
+			mmc_start_bkops(host->card, true);
 	}
 
 	if (!err && areq)
-		start_err = __mmc_start_req(host, areq->mrq);
+		start_err = __mmc_start_data_req(host, areq->mrq);
 
 	if (host->areq)
 		mmc_post_req(host, host->areq->mrq, 0);
 
 	 /* Cancel a prepared request if it was not started. */
 	if ((err || start_err) && areq)
-			mmc_post_req(host, areq->mrq, -EINVAL);
+		mmc_post_req(host, areq->mrq, -EINVAL);
 
 	if (err)
 		host->areq = NULL;
@@ -398,12 +578,13 @@
  *	@card: the MMC card associated with the HPI transfer
  *
  *	Issued High Priority Interrupt, and check for card status
- *	util out-of prg-state.
+ *	until out-of prg-state.
  */
 int mmc_interrupt_hpi(struct mmc_card *card)
 {
 	int err;
 	u32 status;
+	unsigned long prg_wait;
 
 	BUG_ON(!card);
 
@@ -419,30 +600,39 @@
 		goto out;
 	}
 
-	/*
-	 * If the card status is in PRG-state, we can send the HPI command.
-	 */
-	if (R1_CURRENT_STATE(status) == R1_STATE_PRG) {
-		do {
-			/*
-			 * We don't know when the HPI command will finish
-			 * processing, so we need to resend HPI until out
-			 * of prg-state, and keep checking the card status
-			 * with SEND_STATUS.  If a timeout error occurs when
-			 * sending the HPI command, we are already out of
-			 * prg-state.
-			 */
-			err = mmc_send_hpi_cmd(card, &status);
-			if (err)
-				pr_debug("%s: abort HPI (%d error)\n",
-					 mmc_hostname(card->host), err);
+	switch (R1_CURRENT_STATE(status)) {
+	case R1_STATE_IDLE:
+	case R1_STATE_READY:
+	case R1_STATE_STBY:
+	case R1_STATE_TRAN:
+		/*
+		 * In idle and transfer states, HPI is not needed and the caller
+		 * can issue the next intended command immediately
+		 */
+		goto out;
+	case R1_STATE_PRG:
+		break;
+	default:
+		/* In all other states, it's illegal to issue HPI */
+		pr_debug("%s: HPI cannot be sent. Card state=%d\n",
+			mmc_hostname(card->host), R1_CURRENT_STATE(status));
+		err = -EINVAL;
+		goto out;
+	}
 
-			err = mmc_send_status(card, &status);
-			if (err)
-				break;
-		} while (R1_CURRENT_STATE(status) == R1_STATE_PRG);
-	} else
-		pr_debug("%s: Left prg-state\n", mmc_hostname(card->host));
+	err = mmc_send_hpi_cmd(card, &status);
+	if (err)
+		goto out;
+
+	prg_wait = jiffies + msecs_to_jiffies(card->ext_csd.out_of_int_time);
+	do {
+		err = mmc_send_status(card, &status);
+
+		if (!err && R1_CURRENT_STATE(status) == R1_STATE_TRAN)
+			break;
+		if (time_after(jiffies, prg_wait))
+			err = -ETIMEDOUT;
+	} while (!err);
 
 out:
 	mmc_release_host(card->host);
@@ -480,6 +670,64 @@
 EXPORT_SYMBOL(mmc_wait_for_cmd);
 
 /**
+ *	mmc_stop_bkops - stop ongoing BKOPS
+ *	@card: MMC card to check BKOPS
+ *
+ *	Send HPI command to stop ongoing background operations to
+ *	allow rapid servicing of foreground operations, e.g. read/
+ *	writes. Wait until the card comes out of the programming state
+ *	to avoid errors in servicing read/write requests.
+ */
+int mmc_stop_bkops(struct mmc_card *card)
+{
+	int err = 0;
+
+	BUG_ON(!card);
+	err = mmc_interrupt_hpi(card);
+
+	/*
+	 * If err is EINVAL, we can't issue an HPI.
+	 * It should complete the BKOPS.
+	 */
+	if (!err || (err == -EINVAL)) {
+		mmc_card_clr_doing_bkops(card);
+		err = 0;
+	}
+
+	return err;
+}
+EXPORT_SYMBOL(mmc_stop_bkops);
+
+int mmc_read_bkops_status(struct mmc_card *card)
+{
+	int err;
+	u8 *ext_csd;
+
+	/*
+	 * In future work, we should consider storing the entire ext_csd.
+	 */
+	ext_csd = kmalloc(512, GFP_KERNEL);
+	if (!ext_csd) {
+		pr_err("%s: could not allocate buffer to receive the ext_csd.\n",
+		       mmc_hostname(card->host));
+		return -ENOMEM;
+	}
+
+	mmc_claim_host(card->host);
+	err = mmc_send_ext_csd(card, ext_csd);
+	mmc_release_host(card->host);
+	if (err)
+		goto out;
+
+	card->ext_csd.raw_bkops_status = ext_csd[EXT_CSD_BKOPS_STATUS];
+	card->ext_csd.raw_exception_status = ext_csd[EXT_CSD_EXP_EVENTS_STATUS];
+out:
+	kfree(ext_csd);
+	return err;
+}
+EXPORT_SYMBOL(mmc_read_bkops_status);
+
+/**
  *	mmc_set_data_timeout - set the timeout for a data command
  *	@data: data phase for command
  *	@card: the MMC card associated with the data transfer
@@ -941,7 +1189,7 @@
 
 	return result;
 }
-EXPORT_SYMBOL(mmc_regulator_get_ocrmask);
+EXPORT_SYMBOL_GPL(mmc_regulator_get_ocrmask);
 
 /**
  * mmc_regulator_set_ocr - set regulator to match host->ios voltage
@@ -966,7 +1214,8 @@
 		int		tmp;
 		int		voltage;
 
-		/* REVISIT mmc_vddrange_to_ocrmask() may have set some
+		/*
+		 * REVISIT mmc_vddrange_to_ocrmask() may have set some
 		 * bits this regulator doesn't quite support ... don't
 		 * be too picky, most cards and regulators are OK with
 		 * a 0.1V range goof (it's a small error percentage).
@@ -980,12 +1229,13 @@
 			max_uV = min_uV + 100 * 1000;
 		}
 
-		/* avoid needless changes to this voltage; the regulator
-		 * might not allow this operation
+		/*
+		 * If we're using a fixed/static regulator, don't call
+		 * regulator_set_voltage; it would fail.
 		 */
 		voltage = regulator_get_voltage(supply);
 
-		if (mmc->caps2 & MMC_CAP2_BROKEN_VOLTAGE)
+		if (!regulator_can_change_voltage(supply))
 			min_uV = max_uV = voltage;
 
 		if (voltage < 0)
@@ -1011,7 +1261,30 @@
 			"could not set regulator OCR (%d)\n", result);
 	return result;
 }
-EXPORT_SYMBOL(mmc_regulator_set_ocr);
+EXPORT_SYMBOL_GPL(mmc_regulator_set_ocr);
+
+int mmc_regulator_get_supply(struct mmc_host *mmc)
+{
+	struct device *dev = mmc_dev(mmc);
+	struct regulator *supply;
+	int ret;
+
+	supply = devm_regulator_get(dev, "vmmc");
+	mmc->supply.vmmc = supply;
+	mmc->supply.vqmmc = devm_regulator_get(dev, "vqmmc");
+
+	if (IS_ERR(supply))
+		return PTR_ERR(supply);
+
+	ret = mmc_regulator_get_ocrmask(supply);
+	if (ret > 0)
+		mmc->ocr_avail = ret;
+	else
+		dev_warn(mmc_dev(mmc), "Failed getting OCR mask: %d\n", ret);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(mmc_regulator_get_supply);
 
 #endif /* CONFIG_REGULATOR */
 
@@ -1044,7 +1317,26 @@
 	return ocr;
 }
 
-int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage, bool cmd11)
+int __mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage)
+{
+	int err = 0;
+	int old_signal_voltage = host->ios.signal_voltage;
+
+	host->ios.signal_voltage = signal_voltage;
+	if (host->ops->start_signal_voltage_switch) {
+		mmc_host_clk_hold(host);
+		err = host->ops->start_signal_voltage_switch(host, &host->ios);
+		mmc_host_clk_release(host);
+	}
+
+	if (err)
+		host->ios.signal_voltage = old_signal_voltage;
+
+	return err;
+
+}
+
+int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage)
 {
 	struct mmc_command cmd = {0};
 	int err = 0;
@@ -1055,28 +1347,28 @@
 	 * Send CMD11 only if the request is to switch the card to
 	 * 1.8V signalling.
 	 */
-	if ((signal_voltage != MMC_SIGNAL_VOLTAGE_330) && cmd11) {
-		cmd.opcode = SD_SWITCH_VOLTAGE;
-		cmd.arg = 0;
-		cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
+	if (signal_voltage == MMC_SIGNAL_VOLTAGE_330)
+		return __mmc_set_signal_voltage(host, signal_voltage);
 
-		err = mmc_wait_for_cmd(host, &cmd, 0);
-		if (err)
-			return err;
+	/*
+	 * If we cannot switch voltages, return failure so the caller
+	 * can continue without UHS mode
+	 */
+	if (!host->ops->start_signal_voltage_switch)
+		return -EPERM;
 
-		if (!mmc_host_is_spi(host) && (cmd.resp[0] & R1_ERROR))
-			return -EIO;
-	}
+	cmd.opcode = SD_SWITCH_VOLTAGE;
+	cmd.arg = 0;
+	cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
 
-	host->ios.signal_voltage = signal_voltage;
+	err = mmc_wait_for_cmd(host, &cmd, 0);
+	if (err)
+		return err;
 
-	if (host->ops->start_signal_voltage_switch) {
-		mmc_host_clk_hold(host);
-		err = host->ops->start_signal_voltage_switch(host, &host->ios);
-		mmc_host_clk_release(host);
-	}
+	if (!mmc_host_is_spi(host) && (cmd.resp[0] & R1_ERROR))
+		return -EIO;
 
-	return err;
+	return __mmc_set_signal_voltage(host, signal_voltage);
 }
 
 /*
@@ -1101,48 +1393,6 @@
 	mmc_host_clk_release(host);
 }
 
-static void mmc_poweroff_notify(struct mmc_host *host)
-{
-	struct mmc_card *card;
-	unsigned int timeout;
-	unsigned int notify_type = EXT_CSD_NO_POWER_NOTIFICATION;
-	int err = 0;
-
-	card = host->card;
-	mmc_claim_host(host);
-
-	/*
-	 * Send power notify command only if card
-	 * is mmc and notify state is powered ON
-	 */
-	if (card && mmc_card_mmc(card) &&
-	    (card->poweroff_notify_state == MMC_POWERED_ON)) {
-
-		if (host->power_notify_type == MMC_HOST_PW_NOTIFY_SHORT) {
-			notify_type = EXT_CSD_POWER_OFF_SHORT;
-			timeout = card->ext_csd.generic_cmd6_time;
-			card->poweroff_notify_state = MMC_POWEROFF_SHORT;
-		} else {
-			notify_type = EXT_CSD_POWER_OFF_LONG;
-			timeout = card->ext_csd.power_off_longtime;
-			card->poweroff_notify_state = MMC_POWEROFF_LONG;
-		}
-
-		err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
-				 EXT_CSD_POWER_OFF_NOTIFICATION,
-				 notify_type, timeout);
-
-		if (err && err != -EBADMSG)
-			pr_err("Device failed to respond within %d poweroff "
-			       "time. Forcefully powering down the device\n",
-			       timeout);
-
-		/* Set the card state to no notification after the poweroff */
-		card->poweroff_notify_state = MMC_NO_POWER_NOTIFICATION;
-	}
-	mmc_release_host(host);
-}
-
 /*
  * Apply power to the MMC stack.  This is a two-stage process.
  * First, we enable power to the card without the clock running.
@@ -1158,6 +1408,9 @@
 {
 	int bit;
 
+	if (host->ios.power_mode == MMC_POWER_ON)
+		return;
+
 	mmc_host_clk_hold(host);
 
 	/* If ocr is set, we use it */
@@ -1177,6 +1430,9 @@
 	host->ios.timing = MMC_TIMING_LEGACY;
 	mmc_set_ios(host);
 
+	/* Set signal voltage to 3.3V */
+	__mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_330);
+
 	/*
 	 * This delay should be sufficient to allow the power supply
 	 * to reach the minimum voltage.
@@ -1199,28 +1455,14 @@
 
 void mmc_power_off(struct mmc_host *host)
 {
-	int err = 0;
+	if (host->ios.power_mode == MMC_POWER_OFF)
+		return;
+
 	mmc_host_clk_hold(host);
 
 	host->ios.clock = 0;
 	host->ios.vdd = 0;
 
-	/*
-	 * For eMMC 4.5 device send AWAKE command before
-	 * POWER_OFF_NOTIFY command, because in sleep state
-	 * eMMC 4.5 devices respond to only RESET and AWAKE cmd
-	 */
-	if (host->card && mmc_card_is_sleep(host->card) &&
-	    host->bus_ops->resume) {
-		err = host->bus_ops->resume(host);
-
-		if (!err)
-			mmc_poweroff_notify(host);
-		else
-			pr_warning("%s: error %d during resume "
-				   "(continue with poweroff sequence)\n",
-				   mmc_hostname(host), err);
-	}
 
 	/*
 	 * Reset ocr mask to be the highest possible voltage supported for
@@ -1247,6 +1489,14 @@
 	mmc_host_clk_release(host);
 }
 
+void mmc_power_cycle(struct mmc_host *host)
+{
+	mmc_power_off(host);
+	/* Wait at least 1 ms according to SD spec */
+	mmc_delay(1);
+	mmc_power_up(host);
+}
+
 /*
  * Cleanup when the last reference to the bus operator is dropped.
  */
@@ -1286,36 +1536,6 @@
 	spin_unlock_irqrestore(&host->lock, flags);
 }
 
-int mmc_resume_bus(struct mmc_host *host)
-{
-	unsigned long flags;
-
-	if (!mmc_bus_needs_resume(host))
-		return -EINVAL;
-
-	printk("%s: Starting deferred resume\n", mmc_hostname(host));
-	spin_lock_irqsave(&host->lock, flags);
-	host->bus_resume_flags &= ~MMC_BUSRESUME_NEEDS_RESUME;
-	host->rescan_disable = 0;
-	spin_unlock_irqrestore(&host->lock, flags);
-
-	mmc_bus_get(host);
-	if (host->bus_ops && !host->bus_dead) {
-		mmc_power_up(host);
-		BUG_ON(!host->bus_ops->resume);
-		host->bus_ops->resume(host);
-	}
-
-	if (host->bus_ops->detect && !host->bus_dead)
-		host->bus_ops->detect(host);
-
-	mmc_bus_put(host);
-	printk("%s: Deferred resume completed\n", mmc_hostname(host));
-	return 0;
-}
-
-EXPORT_SYMBOL(mmc_resume_bus);
-
 /*
  * Assign a mmc bus handler to a host. Only one bus handler may control a
  * host at any given time.
@@ -1381,8 +1601,6 @@
 	spin_unlock_irqrestore(&host->lock, flags);
 #endif
 	host->detect_change = 1;
-
-	wake_lock(&host->detect_wake_lock);
 	mmc_schedule_delayed_work(&host->detect, delay);
 }
 
@@ -1541,6 +1759,7 @@
 {
 	struct mmc_command cmd = {0};
 	unsigned int qty = 0;
+	unsigned long timeout;
 	int err;
 
 	/*
@@ -1618,6 +1837,7 @@
 	if (mmc_host_is_spi(card->host))
 		goto out;
 
+	timeout = jiffies + msecs_to_jiffies(MMC_CORE_TIMEOUT_MS);
 	do {
 		memset(&cmd, 0, sizeof(struct mmc_command));
 		cmd.opcode = MMC_SEND_STATUS;
@@ -1631,8 +1851,19 @@
 			err = -EIO;
 			goto out;
 		}
+
+		/* Timeout if the device never becomes ready for data and
+		 * never leaves the program state.
+		 */
+		if (time_after(jiffies, timeout)) {
+			pr_err("%s: Card stuck in programming state! %s\n",
+				mmc_hostname(card->host), __func__);
+			err =  -EIO;
+			goto out;
+		}
+
 	} while (!(cmd.resp[0] & R1_READY_FOR_DATA) ||
-		 R1_CURRENT_STATE(cmd.resp[0]) == R1_STATE_PRG);
+		 (R1_CURRENT_STATE(cmd.resp[0]) == R1_STATE_PRG));
 out:
 	return err;
 }
@@ -1852,6 +2083,20 @@
 }
 EXPORT_SYMBOL(mmc_set_blocklen);
 
+int mmc_set_blockcount(struct mmc_card *card, unsigned int blockcount,
+			bool is_rel_write)
+{
+	struct mmc_command cmd = {0};
+
+	cmd.opcode = MMC_SET_BLOCK_COUNT;
+	cmd.arg = blockcount & 0x0000FFFF;
+	if (is_rel_write)
+		cmd.arg |= 1 << 31;
+	cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC;
+	return mmc_wait_for_cmd(card->host, &cmd, 5);
+}
+EXPORT_SYMBOL(mmc_set_blockcount);
+
 static void mmc_hw_reset_for_init(struct mmc_host *host)
 {
 	if (!(host->caps & MMC_CAP_HW_RESET) || !host->ops->hw_reset)
@@ -1956,9 +2201,6 @@
 	 */
 	mmc_hw_reset_for_init(host);
 
-	/* Initialization should be done at 3.3 V I/O voltage. */
-	mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_330, 0);
-
 	/*
 	 * sdio_reset sends CMD52 to reset card.  Since we do not know
 	 * if the card is being re-initialized, just send it.  CMD52
@@ -1992,6 +2234,19 @@
 		return 1;
 
 	ret = host->bus_ops->alive(host);
+
+	/*
+	 * Card detect status and alive check may be out of sync if card is
+	 * removed slowly, when card detect switch changes while card/slot
+	 * pads are still contacted in hardware (refer to "SD Card Mechanical
+	 * Addendum, Appendix C: Card Detection Switch"). So reschedule a
+	 * detect work 200ms later for this case.
+	 */
+	if (!ret && host->ops->get_cd && !host->ops->get_cd(host)) {
+		mmc_detect_change(host, msecs_to_jiffies(200));
+		pr_debug("%s: card removed too slowly\n", mmc_hostname(host));
+	}
+
 	if (ret) {
 		mmc_card_set_removed(host->card);
 		pr_debug("%s: card remove detected\n", mmc_hostname(host));
@@ -2038,15 +2293,18 @@
 
 void mmc_rescan(struct work_struct *work)
 {
-	static const unsigned freqs[] = { 400000, 300000, 200000, 100000 };
 	struct mmc_host *host =
 		container_of(work, struct mmc_host, detect.work);
 	int i;
-	bool extend_wakelock = false;
 
 	if (host->rescan_disable)
 		return;
 
+	/* If there is a non-removable card registered, only scan once */
+	if ((host->caps & MMC_CAP_NONREMOVABLE) && host->rescan_entered)
+		return;
+	host->rescan_entered = 1;
+
 	mmc_bus_get(host);
 
 	/*
@@ -2059,12 +2317,6 @@
 
 	host->detect_change = 0;
 
-	/* If the card was removed the bus will be marked
-	 * as dead - extend the wakelock so userspace
-	 * can respond */
-	if (host->bus_dead)
-		extend_wakelock = 1;
-
 	/*
 	 * Let mmc_bus_put() free the bus/bus_ops if we've found that
 	 * the card is no longer present.
@@ -2084,34 +2336,35 @@
 	 */
 	mmc_bus_put(host);
 
-	if (host->ops->get_cd && host->ops->get_cd(host) == 0)
+	if (host->ops->get_cd && host->ops->get_cd(host) == 0) {
+		mmc_claim_host(host);
+		mmc_power_off(host);
+		mmc_release_host(host);
 		goto out;
+	}
 
 	mmc_claim_host(host);
 	for (i = 0; i < ARRAY_SIZE(freqs); i++) {
-		if (!mmc_rescan_try_freq(host, max(freqs[i], host->f_min))) {
-			extend_wakelock = true;
+		if (!mmc_rescan_try_freq(host, max(freqs[i], host->f_min)))
 			break;
-		}
 		if (freqs[i] <= host->f_min)
 			break;
 	}
 	mmc_release_host(host);
 
  out:
-	if (extend_wakelock)
-		wake_lock_timeout(&host->detect_wake_lock, HZ / 2);
-	else
-		wake_unlock(&host->detect_wake_lock);
-	if (host->caps & MMC_CAP_NEEDS_POLL) {
-		wake_lock(&host->detect_wake_lock);
+	if (host->caps & MMC_CAP_NEEDS_POLL)
 		mmc_schedule_delayed_work(&host->detect, HZ);
-	}
 }
 
 void mmc_start_host(struct mmc_host *host)
 {
-	mmc_power_off(host);
+	host->f_init = max(freqs[0], host->f_min);
+	host->rescan_disable = 0;
+	if (host->caps2 & MMC_CAP2_NO_PRESCAN_POWERUP)
+		mmc_power_off(host);
+	else
+		mmc_power_up(host);
 	mmc_detect_change(host, 0);
 }
 
@@ -2124,8 +2377,8 @@
 	spin_unlock_irqrestore(&host->lock, flags);
 #endif
 
-	if (cancel_delayed_work_sync(&host->detect))
-		wake_unlock(&host->detect_wake_lock);
+	host->rescan_disable = 1;
+	cancel_delayed_work_sync(&host->detect);
 	mmc_flush_scheduled_work();
 
 	/* clear pm flags now and let card drivers set them as needed */
@@ -2276,6 +2529,7 @@
  * Turn the cache ON/OFF.
  * Turning the cache OFF shall trigger flushing of the data
  * to the non-volatile storage.
+ * This function should be called with host claimed
  */
 int mmc_cache_ctrl(struct mmc_host *host, u8 enable)
 {
@@ -2287,7 +2541,6 @@
 			mmc_card_is_removable(host))
 		return err;
 
-	mmc_claim_host(host);
 	if (card && mmc_card_mmc(card) &&
 			(card->ext_csd.cache_size > 0)) {
 		enable = !!enable;
@@ -2305,7 +2558,6 @@
 				card->ext_csd.cache_ctrl = enable;
 		}
 	}
-	mmc_release_host(host);
 
 	return err;
 }
@@ -2321,22 +2573,19 @@
 {
 	int err = 0;
 
-	if (mmc_bus_needs_resume(host))
-		return 0;
-
-	if (cancel_delayed_work(&host->detect))
-		wake_unlock(&host->detect_wake_lock);
+	cancel_delayed_work(&host->detect);
 	mmc_flush_scheduled_work();
 
-	err = mmc_cache_ctrl(host, 0);
-	if (err)
-		goto out;
-
 	mmc_bus_get(host);
 	if (host->bus_ops && !host->bus_dead) {
-
-		if (host->bus_ops->suspend)
+		if (host->bus_ops->suspend) {
+			if (mmc_card_doing_bkops(host->card)) {
+				err = mmc_stop_bkops(host->card);
+				if (err)
+					goto out;
+			}
 			err = host->bus_ops->suspend(host);
+		}
 
 		if (err == -ENOSYS || !host->bus_ops->resume) {
 			/*
@@ -2375,12 +2624,6 @@
 	int err = 0;
 
 	mmc_bus_get(host);
-	if (mmc_bus_manual_resume(host)) {
-		host->bus_resume_flags |= MMC_BUSRESUME_NEEDS_RESUME;
-		mmc_bus_put(host);
-		return 0;
-	}
-
 	if (host->bus_ops && !host->bus_dead) {
 		if (!mmc_card_keep_power(host)) {
 			mmc_power_up(host);
@@ -2424,22 +2667,26 @@
 	struct mmc_host *host = container_of(
 		notify_block, struct mmc_host, pm_notify);
 	unsigned long flags;
-
+	int err = 0;
 
 	switch (mode) {
 	case PM_HIBERNATION_PREPARE:
 	case PM_SUSPEND_PREPARE:
+		if (host->card && mmc_card_mmc(host->card) &&
+		    mmc_card_doing_bkops(host->card)) {
+			err = mmc_stop_bkops(host->card);
+			if (err) {
+				pr_err("%s: didn't stop bkops\n",
+					mmc_hostname(host));
+				return err;
+			}
+			mmc_card_clr_doing_bkops(host->card);
+		}
 
 		spin_lock_irqsave(&host->lock, flags);
-		if (mmc_bus_needs_resume(host)) {
-			spin_unlock_irqrestore(&host->lock, flags);
-			break;
-		}
 		host->rescan_disable = 1;
-		host->power_notify_type = MMC_HOST_PW_NOTIFY_SHORT;
 		spin_unlock_irqrestore(&host->lock, flags);
-		if (cancel_delayed_work_sync(&host->detect))
-			wake_unlock(&host->detect_wake_lock);
+		cancel_delayed_work_sync(&host->detect);
 
 		if (!host->bus_ops || host->bus_ops->suspend)
 			break;
@@ -2460,12 +2707,7 @@
 	case PM_POST_RESTORE:
 
 		spin_lock_irqsave(&host->lock, flags);
-		if (mmc_bus_manual_resume(host)) {
-			spin_unlock_irqrestore(&host->lock, flags);
-			break;
-		}
 		host->rescan_disable = 0;
-		host->power_notify_type = MMC_HOST_PW_NOTIFY_LONG;
 		spin_unlock_irqrestore(&host->lock, flags);
 		mmc_detect_change(host, 0);
 
@@ -2475,22 +2717,23 @@
 }
 #endif
 
-#ifdef CONFIG_MMC_EMBEDDED_SDIO
-void mmc_set_embedded_sdio_data(struct mmc_host *host,
-				struct sdio_cis *cis,
-				struct sdio_cccr *cccr,
-				struct sdio_embedded_func *funcs,
-				int num_funcs)
-{
-	host->embedded_sdio_data.cis = cis;
-	host->embedded_sdio_data.cccr = cccr;
-	host->embedded_sdio_data.funcs = funcs;
-	host->embedded_sdio_data.num_funcs = num_funcs;
+/**
+ * mmc_init_context_info() - init synchronization context
+ * @host: mmc host
+ *
+ * Init struct context_info needed to implement asynchronous
+ * request mechanism, used by mmc core, host driver and mmc requests
+ * supplier.
+ */
+void mmc_init_context_info(struct mmc_host *host)
+{
+	spin_lock_init(&host->context_info.lock);
+	host->context_info.is_new_req = false;
+	host->context_info.is_done_rcv = false;
+	host->context_info.is_waiting_last_req = false;
+	init_waitqueue_head(&host->context_info.wait);
 }
 
-EXPORT_SYMBOL(mmc_set_embedded_sdio_data);
-#endif
-
 static int __init mmc_init(void)
 {
 	int ret;
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/core/core.h linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/core/core.h
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/core/core.h	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/core/core.h	2014-09-12 15:59:37.348052000 +0800
@@ -40,11 +40,12 @@
 void mmc_set_bus_mode(struct mmc_host *host, unsigned int mode);
 void mmc_set_bus_width(struct mmc_host *host, unsigned int width);
 u32 mmc_select_voltage(struct mmc_host *host, u32 ocr);
-int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage,
-			   bool cmd11);
+int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage);
+int __mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage);
 void mmc_set_timing(struct mmc_host *host, unsigned int timing);
 void mmc_set_driver_type(struct mmc_host *host, unsigned int drv_type);
 void mmc_power_off(struct mmc_host *host);
+void mmc_power_cycle(struct mmc_host *host);
 
 static inline void mmc_delay(unsigned int ms)
 {
@@ -76,5 +77,6 @@
 void mmc_add_card_debugfs(struct mmc_card *card);
 void mmc_remove_card_debugfs(struct mmc_card *card);
 
+void mmc_init_context_info(struct mmc_host *host);
 #endif
 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/core/debugfs.c linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/core/debugfs.c
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/core/debugfs.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/core/debugfs.c	2014-09-12 15:59:37.348052000 +0800
@@ -144,6 +144,22 @@
 	}
 	seq_printf(s, "timing spec:\t%u (%s)\n", ios->timing, str);
 
+	switch (ios->signal_voltage) {
+	case MMC_SIGNAL_VOLTAGE_330:
+		str = "3.30 V";
+		break;
+	case MMC_SIGNAL_VOLTAGE_180:
+		str = "1.80 V";
+		break;
+	case MMC_SIGNAL_VOLTAGE_120:
+		str = "1.20 V";
+		break;
+	default:
+		str = "invalid";
+		break;
+	}
+	seq_printf(s, "signal voltage:\t%u (%s)\n", ios->chip_select, str);
+
 	return 0;
 }
 
@@ -281,7 +297,7 @@
 	if (err)
 		goto out_free;
 
-	for (i = 511; i >= 0; i--)
+	for (i = 0; i < 512; i++)
 		n += sprintf(buf + n, "%02x", ext_csd[i]);
 	n += sprintf(buf + n, "\n");
 	BUG_ON(n != EXT_CSD_STR_LEN);
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/core/host.c linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/core/host.c
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/core/host.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/core/host.c	2014-09-12 15:59:37.348052000 +0800
@@ -15,6 +15,8 @@
 #include <linux/device.h>
 #include <linux/err.h>
 #include <linux/idr.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
 #include <linux/pagemap.h>
 #include <linux/export.h>
 #include <linux/leds.h>
@@ -23,6 +25,7 @@
 
 #include <linux/mmc/host.h>
 #include <linux/mmc/card.h>
+#include <linux/mmc/slot-gpio.h>
 
 #include "core.h"
 #include "host.h"
@@ -32,6 +35,7 @@
 static void mmc_host_classdev_release(struct device *dev)
 {
 	struct mmc_host *host = cls_dev_to_mmc_host(dev);
+	mutex_destroy(&host->slot.lock);
 	kfree(host);
 }
 
@@ -203,8 +207,8 @@
 	host->clk_requests--;
 	if (mmc_host_may_gate_card(host->card) &&
 	    !host->clk_requests)
-		queue_delayed_work(system_nrt_wq, &host->clk_gate_work,
-				msecs_to_jiffies(host->clkgate_delay));
+		schedule_delayed_work(&host->clk_gate_work,
+				      msecs_to_jiffies(host->clkgate_delay));
 	spin_unlock_irqrestore(&host->clk_lock, flags);
 }
 
@@ -294,6 +298,126 @@
 #endif
 
 /**
+ *	mmc_of_parse() - parse host's device-tree node
+ *	@host: host whose node should be parsed.
+ *
+ * To keep the rest of the MMC subsystem unaware of whether DT has been
+ * used to to instantiate and configure this host instance or not, we
+ * parse the properties and set respective generic mmc-host flags and
+ * parameters.
+ */
+void mmc_of_parse(struct mmc_host *host)
+{
+	struct device_node *np;
+	u32 bus_width;
+	bool explicit_inv_wp, gpio_inv_wp = false;
+	enum of_gpio_flags flags;
+	int len, ret, gpio;
+
+	if (!host->parent || !host->parent->of_node)
+		return;
+
+	np = host->parent->of_node;
+
+	/* "bus-width" is translated to MMC_CAP_*_BIT_DATA flags */
+	if (of_property_read_u32(np, "bus-width", &bus_width) < 0) {
+		dev_dbg(host->parent,
+			"\"bus-width\" property is missing, assuming 1 bit.\n");
+		bus_width = 1;
+	}
+
+	switch (bus_width) {
+	case 8:
+		host->caps |= MMC_CAP_8_BIT_DATA;
+		/* Hosts capable of 8-bit transfers can also do 4 bits */
+	case 4:
+		host->caps |= MMC_CAP_4_BIT_DATA;
+		break;
+	case 1:
+		break;
+	default:
+		dev_err(host->parent,
+			"Invalid \"bus-width\" value %ud!\n", bus_width);
+	}
+
+	/* f_max is obtained from the optional "max-frequency" property */
+	of_property_read_u32(np, "max-frequency", &host->f_max);
+
+	/*
+	 * Configure CD and WP pins. They are both by default active low to
+	 * match the SDHCI spec. If GPIOs are provided for CD and / or WP, the
+	 * mmc-gpio helpers are used to attach, configure and use them. If
+	 * polarity inversion is specified in DT, one of MMC_CAP2_CD_ACTIVE_HIGH
+	 * and MMC_CAP2_RO_ACTIVE_HIGH capability-2 flags is set. If the
+	 * "broken-cd" property is provided, the MMC_CAP_NEEDS_POLL capability
+	 * is set. If the "non-removable" property is found, the
+	 * MMC_CAP_NONREMOVABLE capability is set and no card-detection
+	 * configuration is performed.
+	 */
+
+	/* Parse Card Detection */
+	if (of_find_property(np, "non-removable", &len)) {
+		host->caps |= MMC_CAP_NONREMOVABLE;
+	} else {
+		bool explicit_inv_cd, gpio_inv_cd = false;
+
+		explicit_inv_cd = of_property_read_bool(np, "cd-inverted");
+
+		if (of_find_property(np, "broken-cd", &len))
+			host->caps |= MMC_CAP_NEEDS_POLL;
+
+		gpio = of_get_named_gpio_flags(np, "cd-gpios", 0, &flags);
+		if (gpio_is_valid(gpio)) {
+			if (!(flags & OF_GPIO_ACTIVE_LOW))
+				gpio_inv_cd = true;
+
+			ret = mmc_gpio_request_cd(host, gpio);
+			if (ret < 0)
+				dev_err(host->parent,
+					"Failed to request CD GPIO #%d: %d!\n",
+					gpio, ret);
+			else
+				dev_info(host->parent, "Got CD GPIO #%d.\n",
+					 gpio);
+		}
+
+		if (explicit_inv_cd ^ gpio_inv_cd)
+			host->caps2 |= MMC_CAP2_CD_ACTIVE_HIGH;
+	}
+
+	/* Parse Write Protection */
+	explicit_inv_wp = of_property_read_bool(np, "wp-inverted");
+
+	gpio = of_get_named_gpio_flags(np, "wp-gpios", 0, &flags);
+	if (gpio_is_valid(gpio)) {
+		if (!(flags & OF_GPIO_ACTIVE_LOW))
+			gpio_inv_wp = true;
+
+		ret = mmc_gpio_request_ro(host, gpio);
+		if (ret < 0)
+			dev_err(host->parent,
+				"Failed to request WP GPIO: %d!\n", ret);
+	}
+	if (explicit_inv_wp ^ gpio_inv_wp)
+		host->caps2 |= MMC_CAP2_RO_ACTIVE_HIGH;
+
+	if (of_find_property(np, "cap-sd-highspeed", &len))
+		host->caps |= MMC_CAP_SD_HIGHSPEED;
+	if (of_find_property(np, "cap-mmc-highspeed", &len))
+		host->caps |= MMC_CAP_MMC_HIGHSPEED;
+	if (of_find_property(np, "cap-power-off-card", &len))
+		host->caps |= MMC_CAP_POWER_OFF_CARD;
+	if (of_find_property(np, "cap-sdio-irq", &len))
+		host->caps |= MMC_CAP_SDIO_IRQ;
+	if (of_find_property(np, "keep-power-in-suspend", &len))
+		host->pm_caps |= MMC_PM_KEEP_POWER;
+	if (of_find_property(np, "enable-sdio-wakeup", &len))
+		host->pm_caps |= MMC_PM_WAKE_SDIO_IRQ;
+}
+
+EXPORT_SYMBOL(mmc_of_parse);
+
+/**
  *	mmc_alloc_host - initialise the per-host structure.
  *	@extra: sizeof private data structure
  *	@dev: pointer to host device model structure
@@ -305,17 +429,20 @@
 	int err;
 	struct mmc_host *host;
 
-	if (!idr_pre_get(&mmc_host_idr, GFP_KERNEL))
-		return NULL;
-
 	host = kzalloc(sizeof(struct mmc_host) + extra, GFP_KERNEL);
 	if (!host)
 		return NULL;
 
+	/* scanning will be enabled when we're ready */
+	host->rescan_disable = 1;
+	idr_preload(GFP_KERNEL);
 	spin_lock(&mmc_host_lock);
-	err = idr_get_new(&mmc_host_idr, host, &host->index);
+	err = idr_alloc(&mmc_host_idr, host, 0, 0, GFP_NOWAIT);
+	if (err >= 0)
+		host->index = err;
 	spin_unlock(&mmc_host_lock);
-	if (err)
+	idr_preload_end();
+	if (err < 0)
 		goto free;
 
 	dev_set_name(&host->class_dev, "mmc%d", host->index);
@@ -327,10 +454,11 @@
 
 	mmc_host_clk_init(host);
 
+	mutex_init(&host->slot.lock);
+	host->slot.cd_irq = -EINVAL;
+
 	spin_lock_init(&host->lock);
 	init_waitqueue_head(&host->wq);
-	wake_lock_init(&host->detect_wake_lock, WAKE_LOCK_SUSPEND,
-		kasprintf(GFP_KERNEL, "%s_detect", mmc_hostname(host)));
 	INIT_DELAYED_WORK(&host->detect, mmc_rescan);
 #ifdef CONFIG_PM
 	host->pm_notify.notifier_call = mmc_pm_notify;
@@ -383,8 +511,7 @@
 	mmc_host_clk_sysfs_init(host);
 
 	mmc_start_host(host);
-	if (!(host->pm_flags & MMC_PM_IGNORE_PM_NOTIFY))
-		register_pm_notifier(&host->pm_notify);
+	register_pm_notifier(&host->pm_notify);
 
 	return 0;
 }
@@ -401,9 +528,7 @@
  */
 void mmc_remove_host(struct mmc_host *host)
 {
-	if (!(host->pm_flags & MMC_PM_IGNORE_PM_NOTIFY))
-		unregister_pm_notifier(&host->pm_notify);
-
+	unregister_pm_notifier(&host->pm_notify);
 	mmc_stop_host(host);
 
 #ifdef CONFIG_DEBUG_FS
@@ -430,7 +555,6 @@
 	spin_lock(&mmc_host_lock);
 	idr_remove(&mmc_host_idr, host->index);
 	spin_unlock(&mmc_host_lock);
-	wake_lock_destroy(&host->detect_wake_lock);
 
 	put_device(&host->class_dev);
 }
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/core/Kconfig linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/core/Kconfig
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/core/Kconfig	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/core/Kconfig	2014-09-12 15:59:37.348052000 +0800
@@ -18,8 +18,7 @@
 	  module parameter "removable=0" or "removable=1".
 
 config MMC_CLKGATE
-	bool "MMC host clock gating (EXPERIMENTAL)"
-	depends on EXPERIMENTAL
+	bool "MMC host clock gating"
 	help
 	  This will attempt to aggressively gate the clock to the MMC card.
 	  This is done to save power due to gating off the logic and bus
@@ -27,20 +26,3 @@
 	  support handling this in order for it to be of any use.
 
 	  If unsure, say N.
-
-config MMC_EMBEDDED_SDIO
-	boolean "MMC embedded SDIO device support (EXPERIMENTAL)"
-	depends on EXPERIMENTAL
-	help
-	  If you say Y here, support will be added for embedded SDIO
-	  devices which do not contain the necessary enumeration
-	  support in hardware to be properly detected.
-
-config MMC_PARANOID_SD_INIT
-	bool "Enable paranoid SD card initialization (EXPERIMENTAL)"
-	depends on EXPERIMENTAL
-	help
-	  If you say Y here, the MMC layer will be extra paranoid
-	  about re-trying SD init requests. This can be a useful
-	  work-around for buggy controllers and hardware. Enable
-	  if you are experiencing issues with SD detection.
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/core/Makefile linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/core/Makefile
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/core/Makefile	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/core/Makefile	2014-09-12 15:59:37.348052000 +0800
@@ -7,6 +7,6 @@
 				   mmc.o mmc_ops.o sd.o sd_ops.o \
 				   sdio.o sdio_ops.o sdio_bus.o \
 				   sdio_cis.o sdio_io.o sdio_irq.o \
-				   quirks.o cd-gpio.o
+				   quirks.o slot-gpio.o
 
 mmc_core-$(CONFIG_DEBUG_FS)	+= debugfs.o
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/core/mmc.c linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/core/mmc.c
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/core/mmc.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/core/mmc.c	2015-04-09 12:12:40.757730000 +0800
@@ -96,6 +96,7 @@
 		card->cid.prod_name[3]	= UNSTUFF_BITS(resp, 72, 8);
 		card->cid.prod_name[4]	= UNSTUFF_BITS(resp, 64, 8);
 		card->cid.prod_name[5]	= UNSTUFF_BITS(resp, 56, 8);
+		card->cid.prv		= UNSTUFF_BITS(resp, 48, 8);
 		card->cid.serial	= UNSTUFF_BITS(resp, 16, 32);
 		card->cid.month		= UNSTUFF_BITS(resp, 12, 4);
 		card->cid.year		= UNSTUFF_BITS(resp, 8, 4) + 1997;
@@ -235,6 +236,36 @@
 	return err;
 }
 
+static void mmc_select_card_type(struct mmc_card *card)
+{
+	struct mmc_host *host = card->host;
+	u8 card_type = card->ext_csd.raw_card_type & EXT_CSD_CARD_TYPE_MASK;
+	u32 caps = host->caps, caps2 = host->caps2;
+	unsigned int hs_max_dtr = 0;
+
+	if (card_type & EXT_CSD_CARD_TYPE_26)
+		hs_max_dtr = MMC_HIGH_26_MAX_DTR;
+
+	if (caps & MMC_CAP_MMC_HIGHSPEED &&
+			card_type & EXT_CSD_CARD_TYPE_52)
+		hs_max_dtr = MMC_HIGH_52_MAX_DTR;
+
+	if ((caps & MMC_CAP_1_8V_DDR &&
+			card_type & EXT_CSD_CARD_TYPE_DDR_1_8V) ||
+	    (caps & MMC_CAP_1_2V_DDR &&
+			card_type & EXT_CSD_CARD_TYPE_DDR_1_2V))
+		hs_max_dtr = MMC_HIGH_DDR_MAX_DTR;
+
+	if ((caps2 & MMC_CAP2_HS200_1_8V_SDR &&
+			card_type & EXT_CSD_CARD_TYPE_SDR_1_8V) ||
+	    (caps2 & MMC_CAP2_HS200_1_2V_SDR &&
+			card_type & EXT_CSD_CARD_TYPE_SDR_1_2V))
+		hs_max_dtr = MMC_HS200_MAX_DTR;
+
+	card->ext_csd.hs_max_dtr = hs_max_dtr;
+	card->ext_csd.card_type = card_type;
+}
+
 /*
  * Decode extended CSD.
  */
@@ -262,12 +293,6 @@
 	}
 
 	card->ext_csd.rev = ext_csd[EXT_CSD_REV];
-	if (card->ext_csd.rev > 6) {
-		pr_err("%s: unrecognised EXT_CSD revision %d\n",
-			mmc_hostname(card->host), card->ext_csd.rev);
-		err = -EINVAL;
-		goto out;
-	}
 
 	card->ext_csd.raw_sectors[0] = ext_csd[EXT_CSD_SEC_CNT + 0];
 	card->ext_csd.raw_sectors[1] = ext_csd[EXT_CSD_SEC_CNT + 1];
@@ -284,56 +309,9 @@
 		if (card->ext_csd.sectors > (2u * 1024 * 1024 * 1024) / 512)
 			mmc_card_set_blockaddr(card);
 	}
+
 	card->ext_csd.raw_card_type = ext_csd[EXT_CSD_CARD_TYPE];
-	switch (ext_csd[EXT_CSD_CARD_TYPE] & EXT_CSD_CARD_TYPE_MASK) {
-	case EXT_CSD_CARD_TYPE_SDR_ALL:
-	case EXT_CSD_CARD_TYPE_SDR_ALL_DDR_1_8V:
-	case EXT_CSD_CARD_TYPE_SDR_ALL_DDR_1_2V:
-	case EXT_CSD_CARD_TYPE_SDR_ALL_DDR_52:
-		card->ext_csd.hs_max_dtr = 200000000;
-		card->ext_csd.card_type = EXT_CSD_CARD_TYPE_SDR_200;
-		break;
-	case EXT_CSD_CARD_TYPE_SDR_1_2V_ALL:
-	case EXT_CSD_CARD_TYPE_SDR_1_2V_DDR_1_8V:
-	case EXT_CSD_CARD_TYPE_SDR_1_2V_DDR_1_2V:
-	case EXT_CSD_CARD_TYPE_SDR_1_2V_DDR_52:
-		card->ext_csd.hs_max_dtr = 200000000;
-		card->ext_csd.card_type = EXT_CSD_CARD_TYPE_SDR_1_2V;
-		break;
-	case EXT_CSD_CARD_TYPE_SDR_1_8V_ALL:
-	case EXT_CSD_CARD_TYPE_SDR_1_8V_DDR_1_8V:
-	case EXT_CSD_CARD_TYPE_SDR_1_8V_DDR_1_2V:
-	case EXT_CSD_CARD_TYPE_SDR_1_8V_DDR_52:
-		card->ext_csd.hs_max_dtr = 200000000;
-		card->ext_csd.card_type = EXT_CSD_CARD_TYPE_SDR_1_8V;
-		break;
-	case EXT_CSD_CARD_TYPE_DDR_52 | EXT_CSD_CARD_TYPE_52 |
-	     EXT_CSD_CARD_TYPE_26:
-		card->ext_csd.hs_max_dtr = 52000000;
-		card->ext_csd.card_type = EXT_CSD_CARD_TYPE_DDR_52;
-		break;
-	case EXT_CSD_CARD_TYPE_DDR_1_2V | EXT_CSD_CARD_TYPE_52 |
-	     EXT_CSD_CARD_TYPE_26:
-		card->ext_csd.hs_max_dtr = 52000000;
-		card->ext_csd.card_type = EXT_CSD_CARD_TYPE_DDR_1_2V;
-		break;
-	case EXT_CSD_CARD_TYPE_DDR_1_8V | EXT_CSD_CARD_TYPE_52 |
-	     EXT_CSD_CARD_TYPE_26:
-		card->ext_csd.hs_max_dtr = 52000000;
-		card->ext_csd.card_type = EXT_CSD_CARD_TYPE_DDR_1_8V;
-		break;
-	case EXT_CSD_CARD_TYPE_52 | EXT_CSD_CARD_TYPE_26:
-		card->ext_csd.hs_max_dtr = 52000000;
-		break;
-	case EXT_CSD_CARD_TYPE_26:
-		card->ext_csd.hs_max_dtr = 26000000;
-		break;
-	default:
-		/* MMC v4 spec says this cannot happen */
-		pr_warning("%s: card is mmc v4 but doesn't "
-			"support any high-speed modes.\n",
-			mmc_hostname(card->host));
-	}
+	mmc_select_card_type(card);
 
 	card->ext_csd.raw_s_a_timeout = ext_csd[EXT_CSD_S_A_TIMEOUT];
 	card->ext_csd.raw_erase_timeout_mult =
@@ -385,13 +363,13 @@
 		ext_csd[EXT_CSD_SEC_FEATURE_SUPPORT];
 	card->ext_csd.raw_trim_mult =
 		ext_csd[EXT_CSD_TRIM_MULT];
+	card->ext_csd.raw_partition_support = ext_csd[EXT_CSD_PARTITION_SUPPORT];
 	if (card->ext_csd.rev >= 4) {
 		/*
 		 * Enhanced area feature support -- check whether the eMMC
 		 * card has the Enhanced area enabled.  If so, export enhanced
 		 * area offset and size to user by adding sysfs interface.
 		 */
-		card->ext_csd.raw_partition_support = ext_csd[EXT_CSD_PARTITION_SUPPORT];
 		if ((ext_csd[EXT_CSD_PARTITION_SUPPORT] & 0x2) &&
 		    (ext_csd[EXT_CSD_PARTITION_ATTRIBUTE] & 0x1)) {
 			hc_erase_grp_sz =
@@ -480,6 +458,17 @@
 	}
 
 	if (card->ext_csd.rev >= 5) {
+		/* check whether the eMMC card supports BKOPS */
+		if (ext_csd[EXT_CSD_BKOPS_SUPPORT] & 0x1) {
+			card->ext_csd.bkops = 1;
+			card->ext_csd.bkops_en = ext_csd[EXT_CSD_BKOPS_EN];
+			card->ext_csd.raw_bkops_status =
+				ext_csd[EXT_CSD_BKOPS_STATUS];
+			if (!card->ext_csd.bkops_en)
+				pr_info("%s: BKOPS_EN bit is not set\n",
+					mmc_hostname(card->host));
+		}
+
 		/* check whether the eMMC card supports HPI */
 		if (ext_csd[EXT_CSD_HPI_FEATURES] & 0x1) {
 			card->ext_csd.hpi = 1;
@@ -497,6 +486,17 @@
 
 		card->ext_csd.rel_param = ext_csd[EXT_CSD_WR_REL_PARAM];
 		card->ext_csd.rst_n_function = ext_csd[EXT_CSD_RST_N_FUNCTION];
+
+		/*
+		 * RPMB regions are defined in multiples of 128K.
+		 */
+		card->ext_csd.raw_rpmb_size_mult = ext_csd[EXT_CSD_RPMB_MULT];
+		if (ext_csd[EXT_CSD_RPMB_MULT] && mmc_host_cmd23(card->host)) {
+			mmc_part_add(card, ext_csd[EXT_CSD_RPMB_MULT] << 17,
+				EXT_CSD_PART_CONFIG_ACC_RPMB,
+				"rpmb", 0, false,
+				MMC_BLK_DATA_AREA_RPMB);
+		}
 	}
 
 	card->ext_csd.raw_erased_mem_count = ext_csd[EXT_CSD_ERASED_MEM_CONT];
@@ -533,6 +533,13 @@
 		} else {
 			card->ext_csd.data_tag_unit_size = 0;
 		}
+
+		card->ext_csd.max_packed_writes =
+			ext_csd[EXT_CSD_MAX_PACKED_WRITES];
+		card->ext_csd.max_packed_reads =
+			ext_csd[EXT_CSD_MAX_PACKED_READS];
+	} else {
+		card->ext_csd.data_sector_size = 512;
 	}
 
 out:
@@ -556,14 +563,10 @@
 	err = mmc_get_ext_csd(card, &bw_ext_csd);
 
 	if (err || bw_ext_csd == NULL) {
-		if (bus_width != MMC_BUS_WIDTH_1)
-			err = -EINVAL;
+		err = -EINVAL;
 		goto out;
 	}
 
-	if (bus_width == MMC_BUS_WIDTH_1)
-		goto out;
-
 	/* only compare read only fields */
 	err = !((card->ext_csd.raw_partition_support ==
 			bw_ext_csd[EXT_CSD_PARTITION_SUPPORT]) &&
@@ -619,10 +622,13 @@
 MMC_DEV_ATTR(manfid, "0x%06x\n", card->cid.manfid);
 MMC_DEV_ATTR(name, "%s\n", card->cid.prod_name);
 MMC_DEV_ATTR(oemid, "0x%04x\n", card->cid.oemid);
+MMC_DEV_ATTR(prv, "0x%x\n", card->cid.prv);
 MMC_DEV_ATTR(serial, "0x%08x\n", card->cid.serial);
 MMC_DEV_ATTR(enhanced_area_offset, "%llu\n",
 		card->ext_csd.enhanced_area_offset);
 MMC_DEV_ATTR(enhanced_area_size, "%u\n", card->ext_csd.enhanced_area_size);
+MMC_DEV_ATTR(raw_rpmb_size_mult, "%#x\n", card->ext_csd.raw_rpmb_size_mult);
+MMC_DEV_ATTR(rel_sectors, "%#x\n", card->ext_csd.rel_sectors);
 
 static struct attribute *mmc_std_attrs[] = {
 	&dev_attr_cid.attr,
@@ -635,9 +641,12 @@
 	&dev_attr_manfid.attr,
 	&dev_attr_name.attr,
 	&dev_attr_oemid.attr,
+	&dev_attr_prv.attr,
 	&dev_attr_serial.attr,
 	&dev_attr_enhanced_area_offset.attr,
 	&dev_attr_enhanced_area_size.attr,
+	&dev_attr_raw_rpmb_size_mult.attr,
+	&dev_attr_rel_sectors.attr,
 	NULL,
 };
 
@@ -745,7 +754,7 @@
  */
 static int mmc_select_hs200(struct mmc_card *card)
 {
-	int idx, err = 0;
+	int idx, err = -EINVAL;
 	struct mmc_host *host;
 	static unsigned ext_csd_bits[] = {
 		EXT_CSD_BUS_WIDTH_4,
@@ -761,10 +770,12 @@
 	host = card->host;
 
 	if (card->ext_csd.card_type & EXT_CSD_CARD_TYPE_SDR_1_2V &&
-	    host->caps2 & MMC_CAP2_HS200_1_2V_SDR)
-		if (mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_120, 0))
-			err = mmc_set_signal_voltage(host,
-						     MMC_SIGNAL_VOLTAGE_180, 0);
+			host->caps2 & MMC_CAP2_HS200_1_2V_SDR)
+		err = __mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_120);
+
+	if (err && card->ext_csd.card_type & EXT_CSD_CARD_TYPE_SDR_1_8V &&
+			host->caps2 & MMC_CAP2_HS200_1_8V_SDR)
+		err = __mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180);
 
 	/* If fails try again during next card power cycle */
 	if (err)
@@ -835,9 +846,6 @@
 	if (!mmc_host_is_spi(host))
 		mmc_set_bus_mode(host, MMC_BUSMODE_OPENDRAIN);
 
-	/* Initialization should be done at 3.3 V I/O voltage. */
-	mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_330, 0);
-
 	/*
 	 * Since we're changing the OCR value, we seem to
 	 * need to tell some cards to go back to the idle
@@ -1016,7 +1024,7 @@
 		 * so check for success and update the flag
 		 */
 		if (!err)
-			card->poweroff_notify_state = MMC_POWERED_ON;
+			card->ext_csd.power_off_notification = EXT_CSD_POWER_ON;
 	}
 
 	/*
@@ -1060,6 +1068,8 @@
 	if (mmc_card_highspeed(card) || mmc_card_hs200(card)) {
 		if (max_dtr > card->ext_csd.hs_max_dtr)
 			max_dtr = card->ext_csd.hs_max_dtr;
+		if (mmc_card_highspeed(card) && (max_dtr > 52000000))
+			max_dtr = 52000000;
 	} else if (max_dtr > card->csd.max_dtr) {
 		max_dtr = card->csd.max_dtr;
 	}
@@ -1213,8 +1223,8 @@
 			 * WARNING: eMMC rules are NOT the same as SD DDR
 			 */
 			if (ddr == MMC_1_2V_DDR_MODE) {
-				err = mmc_set_signal_voltage(host,
-					MMC_SIGNAL_VOLTAGE_120, 0);
+				err = __mmc_set_signal_voltage(host,
+					MMC_SIGNAL_VOLTAGE_120);
 				if (err)
 					goto err;
 			}
@@ -1267,6 +1277,29 @@
 		}
 	}
 
+	/*
+	 * The mandatory minimum values are defined for packed command.
+	 * read: 5, write: 3
+	 */
+	if (card->ext_csd.max_packed_writes >= 3 &&
+	    card->ext_csd.max_packed_reads >= 5 &&
+	    host->caps2 & MMC_CAP2_PACKED_CMD) {
+		err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
+				EXT_CSD_EXP_EVENTS_CTRL,
+				EXT_CSD_PACKED_EVENT_EN,
+				card->ext_csd.generic_cmd6_time);
+		if (err && err != -EBADMSG)
+			goto free_card;
+		if (err) {
+			pr_warn("%s: Enabling packed event failed\n",
+				mmc_hostname(card->host));
+			card->ext_csd.packed_event_en = 0;
+			err = 0;
+		} else {
+			card->ext_csd.packed_event_en = 1;
+		}
+	}
+
 	if (!oldcard)
 		host->card = card;
 
@@ -1282,6 +1315,35 @@
 	return err;
 }
 
+static int mmc_can_poweroff_notify(const struct mmc_card *card)
+{
+	return card &&
+		mmc_card_mmc(card) &&
+		(card->ext_csd.power_off_notification == EXT_CSD_POWER_ON);
+}
+
+static int mmc_poweroff_notify(struct mmc_card *card, unsigned int notify_type)
+{
+	unsigned int timeout = card->ext_csd.generic_cmd6_time;
+	int err;
+
+	/* Use EXT_CSD_POWER_OFF_SHORT as default notification type. */
+	if (notify_type == EXT_CSD_POWER_OFF_LONG)
+		timeout = card->ext_csd.power_off_longtime;
+
+	err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
+			 EXT_CSD_POWER_OFF_NOTIFICATION,
+			 notify_type, timeout);
+	if (err)
+		pr_err("%s: Power Off Notification timed out, %u\n",
+		       mmc_hostname(card->host), timeout);
+
+	/* Disable the power off notification after the switch operation. */
+	card->ext_csd.power_off_notification = EXT_CSD_NO_POWER_NOTIFICATION;
+
+	return err;
+}
+
 /*
  * Host is being removed. Free up the current card.
  */
@@ -1342,15 +1404,21 @@
 	BUG_ON(!host->card);
 
 	mmc_claim_host(host);
-	if (mmc_card_can_sleep(host)) {
+
+	err = mmc_cache_ctrl(host, 0);
+	if (err)
+		goto out;
+
+	if (mmc_can_poweroff_notify(host->card))
+		err = mmc_poweroff_notify(host->card, EXT_CSD_POWER_OFF_SHORT);
+	else if (mmc_card_can_sleep(host))
 		err = mmc_card_sleep(host);
-		if (!err)
-			mmc_card_set_sleep(host->card);
-	} else if (!mmc_host_is_spi(host))
-		mmc_deselect_cards(host);
+	else if (!mmc_host_is_spi(host))
+		err = mmc_deselect_cards(host);
 	host->card->state &= ~(MMC_STATE_HIGHSPEED | MMC_STATE_HIGHSPEED_200);
-	mmc_release_host(host);
 
+out:
+	mmc_release_host(host);
 	return err;
 }
 
@@ -1368,11 +1436,7 @@
 	BUG_ON(!host->card);
 
 	mmc_claim_host(host);
-	if (mmc_card_is_sleep(host->card)) {
-		err = mmc_card_awake(host);
-		mmc_card_clr_sleep(host->card);
-	} else
-		err = mmc_init_card(host, host->ocr, host->card);
+	err = mmc_init_card(host, host->ocr, host->card);
 	mmc_release_host(host);
 
 	return err;
@@ -1383,7 +1447,6 @@
 	int ret;
 
 	host->card->state &= ~(MMC_STATE_HIGHSPEED | MMC_STATE_HIGHSPEED_200);
-	mmc_card_clr_sleep(host->card);
 	mmc_claim_host(host);
 	ret = mmc_init_card(host, host->ocr, host->card);
 	mmc_release_host(host);
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/core/mmc_ops.c linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/core/mmc_ops.c
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/core/mmc_ops.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/core/mmc_ops.c	2014-09-12 15:59:37.348052000 +0800
@@ -21,6 +21,8 @@
 #include "core.h"
 #include "mmc_ops.h"
 
+#define MMC_OPS_TIMEOUT_MS	(10 * 60 * 1000) /* 10 minute timeout */
+
 static int _mmc_select_card(struct mmc_host *host, struct mmc_card *card)
 {
 	int err;
@@ -230,6 +232,10 @@
 	return 0;
 }
 
+/*
+ * NOTE: void *buf, caller for the buf is required to use DMA-capable
+ * buffer or on-stack buffer (with some overhead in callee).
+ */
 static int
 mmc_send_cxd_data(struct mmc_card *card, struct mmc_host *host,
 		u32 opcode, void *buf, unsigned len)
@@ -239,13 +245,19 @@
 	struct mmc_data data = {0};
 	struct scatterlist sg;
 	void *data_buf;
+	int is_on_stack;
 
-	/* dma onto stack is unsafe/nonportable, but callers to this
-	 * routine normally provide temporary on-stack buffers ...
-	 */
-	data_buf = kmalloc(len, GFP_KERNEL);
-	if (data_buf == NULL)
-		return -ENOMEM;
+	is_on_stack = object_is_on_stack(buf);
+	if (is_on_stack) {
+		/*
+		 * dma onto stack is unsafe/nonportable, but callers to this
+		 * routine normally provide temporary on-stack buffers ...
+		 */
+		data_buf = kmalloc(len, GFP_KERNEL);
+		if (!data_buf)
+			return -ENOMEM;
+	} else
+		data_buf = buf;
 
 	mrq.cmd = &cmd;
 	mrq.data = &data;
@@ -280,8 +292,10 @@
 
 	mmc_wait_for_req(host, &mrq);
 
-	memcpy(buf, data_buf, len);
-	kfree(data_buf);
+	if (is_on_stack) {
+		memcpy(buf, data_buf, len);
+		kfree(data_buf);
+	}
 
 	if (cmd.error)
 		return cmd.error;
@@ -294,24 +308,32 @@
 int mmc_send_csd(struct mmc_card *card, u32 *csd)
 {
 	int ret, i;
+	u32 *csd_tmp;
 
 	if (!mmc_host_is_spi(card->host))
 		return mmc_send_cxd_native(card->host, card->rca << 16,
 				csd, MMC_SEND_CSD);
 
-	ret = mmc_send_cxd_data(card, card->host, MMC_SEND_CSD, csd, 16);
+	csd_tmp = kmalloc(16, GFP_KERNEL);
+	if (!csd_tmp)
+		return -ENOMEM;
+
+	ret = mmc_send_cxd_data(card, card->host, MMC_SEND_CSD, csd_tmp, 16);
 	if (ret)
-		return ret;
+		goto err;
 
 	for (i = 0;i < 4;i++)
-		csd[i] = be32_to_cpu(csd[i]);
+		csd[i] = be32_to_cpu(csd_tmp[i]);
 
-	return 0;
+err:
+	kfree(csd_tmp);
+	return ret;
 }
 
 int mmc_send_cid(struct mmc_host *host, u32 *cid)
 {
 	int ret, i;
+	u32 *cid_tmp;
 
 	if (!mmc_host_is_spi(host)) {
 		if (!host->card)
@@ -320,14 +342,20 @@
 				cid, MMC_SEND_CID);
 	}
 
-	ret = mmc_send_cxd_data(NULL, host, MMC_SEND_CID, cid, 16);
+	cid_tmp = kmalloc(16, GFP_KERNEL);
+	if (!cid_tmp)
+		return -ENOMEM;
+
+	ret = mmc_send_cxd_data(NULL, host, MMC_SEND_CID, cid_tmp, 16);
 	if (ret)
-		return ret;
+		goto err;
 
 	for (i = 0;i < 4;i++)
-		cid[i] = be32_to_cpu(cid[i]);
+		cid[i] = be32_to_cpu(cid_tmp[i]);
 
-	return 0;
+err:
+	kfree(cid_tmp);
+	return ret;
 }
 
 int mmc_send_ext_csd(struct mmc_card *card, u8 *ext_csd)
@@ -335,6 +363,7 @@
 	return mmc_send_cxd_data(card, card->host, MMC_SEND_EXT_CSD,
 			ext_csd, 512);
 }
+EXPORT_SYMBOL_GPL(mmc_send_ext_csd);
 
 int mmc_spi_read_ocr(struct mmc_host *host, int highcap, u32 *ocrp)
 {
@@ -367,21 +396,23 @@
 }
 
 /**
- *	mmc_switch - modify EXT_CSD register
+ *	__mmc_switch - modify EXT_CSD register
  *	@card: the MMC card associated with the data transfer
  *	@set: cmd set values
  *	@index: EXT_CSD register index
  *	@value: value to program into EXT_CSD register
  *	@timeout_ms: timeout (ms) for operation performed by register write,
  *                   timeout of zero implies maximum possible timeout
+ *	@use_busy_signal: use the busy signal as response type
  *
  *	Modifies the EXT_CSD register for selected card.
  */
-int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,
-	       unsigned int timeout_ms)
+int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,
+	       unsigned int timeout_ms, bool use_busy_signal)
 {
 	int err;
 	struct mmc_command cmd = {0};
+	unsigned long timeout;
 	u32 status;
 
 	BUG_ON(!card);
@@ -392,14 +423,25 @@
 		  (index << 16) |
 		  (value << 8) |
 		  set;
-	cmd.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC;
+	cmd.flags = MMC_CMD_AC;
+	if (use_busy_signal)
+		cmd.flags |= MMC_RSP_SPI_R1B | MMC_RSP_R1B;
+	else
+		cmd.flags |= MMC_RSP_SPI_R1 | MMC_RSP_R1;
+
+
 	cmd.cmd_timeout_ms = timeout_ms;
 
 	err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES);
 	if (err)
 		return err;
 
+	/* No need to check card status in case of unblocking command */
+	if (!use_busy_signal)
+		return 0;
+
 	/* Must check status to be sure of no errors */
+	timeout = jiffies + msecs_to_jiffies(MMC_OPS_TIMEOUT_MS);
 	do {
 		err = mmc_send_status(card, &status);
 		if (err)
@@ -408,6 +450,13 @@
 			break;
 		if (mmc_host_is_spi(card->host))
 			break;
+
+		/* Timeout if the device never leaves the program state. */
+		if (time_after(jiffies, timeout)) {
+			pr_err("%s: Card stuck in programming state! %s\n",
+				mmc_hostname(card->host), __func__);
+			return -ETIMEDOUT;
+		}
 	} while (R1_CURRENT_STATE(status) == R1_STATE_PRG);
 
 	if (mmc_host_is_spi(card->host)) {
@@ -423,6 +472,13 @@
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(__mmc_switch);
+
+int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,
+		unsigned int timeout_ms)
+{
+	return __mmc_switch(card, set, index, value, timeout_ms, true);
+}
 EXPORT_SYMBOL_GPL(mmc_switch);
 
 int mmc_send_status(struct mmc_card *card, u32 *status)
@@ -569,7 +625,6 @@
 
 	cmd.opcode = opcode;
 	cmd.arg = card->rca << 16 | 1;
-	cmd.cmd_timeout_ms = card->ext_csd.out_of_int_time;
 
 	err = mmc_wait_for_cmd(card->host, &cmd, 0);
 	if (err) {
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/core/sd.c linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/core/sd.c
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/core/sd.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/core/sd.c	2014-09-12 15:59:37.348052000 +0800
@@ -244,7 +244,7 @@
 	 * bitfield positions accordingly.
 	 */
 	au = UNSTUFF_BITS(ssr, 428 - 384, 4);
-	if (au > 0 || au <= 9) {
+	if (au > 0 && au <= 9) {
 		card->ssr.au = 1 << (au + 4);
 		es = UNSTUFF_BITS(ssr, 408 - 384, 16);
 		et = UNSTUFF_BITS(ssr, 402 - 384, 6);
@@ -290,8 +290,12 @@
 		return -ENOMEM;
 	}
 
-	/* Find out the supported Bus Speed Modes. */
-	err = mmc_sd_switch(card, 0, 0, 1, status);
+	/*
+	 * Find out the card's support bits with a mode 0 operation.
+	 * The argument does not matter, as the support bits do not
+	 * change with the arguments.
+	 */
+	err = mmc_sd_switch(card, 0, 0, 0, status);
 	if (err) {
 		/*
 		 * If the host or the card can't do the switch,
@@ -312,46 +316,8 @@
 
 	if (card->scr.sda_spec3) {
 		card->sw_caps.sd3_bus_mode = status[13];
-
-		/* Find out Driver Strengths supported by the card */
-		err = mmc_sd_switch(card, 0, 2, 1, status);
-		if (err) {
-			/*
-			 * If the host or the card can't do the switch,
-			 * fail more gracefully.
-			 */
-			if (err != -EINVAL && err != -ENOSYS && err != -EFAULT)
-				goto out;
-
-			pr_warning("%s: problem reading "
-				"Driver Strength.\n",
-				mmc_hostname(card->host));
-			err = 0;
-
-			goto out;
-		}
-
+		/* Driver Strengths supported by the card */
 		card->sw_caps.sd3_drv_type = status[9];
-
-		/* Find out Current Limits supported by the card */
-		err = mmc_sd_switch(card, 0, 3, 1, status);
-		if (err) {
-			/*
-			 * If the host or the card can't do the switch,
-			 * fail more gracefully.
-			 */
-			if (err != -EINVAL && err != -ENOSYS && err != -EFAULT)
-				goto out;
-
-			pr_warning("%s: problem reading "
-				"Current Limit.\n",
-				mmc_hostname(card->host));
-			err = 0;
-
-			goto out;
-		}
-
-		card->sw_caps.sd3_curr_limit = status[7];
 	}
 
 out:
@@ -478,8 +444,7 @@
 	 * If the host doesn't support any of the UHS-I modes, fallback on
 	 * default speed.
 	 */
-	if (!(card->host->caps & (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 |
-	    MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104 | MMC_CAP_UHS_DDR50))) {
+	if (!mmc_host_uhs(card->host)) {
 		card->sd_bus_speed = 0;
 		return;
 	}
@@ -551,60 +516,80 @@
 	return 0;
 }
 
+/* Get host's max current setting at its current voltage */
+static u32 sd_get_host_max_current(struct mmc_host *host)
+{
+	u32 voltage, max_current;
+
+	voltage = 1 << host->ios.vdd;
+	switch (voltage) {
+	case MMC_VDD_165_195:
+		max_current = host->max_current_180;
+		break;
+	case MMC_VDD_29_30:
+	case MMC_VDD_30_31:
+		max_current = host->max_current_300;
+		break;
+	case MMC_VDD_32_33:
+	case MMC_VDD_33_34:
+		max_current = host->max_current_330;
+		break;
+	default:
+		max_current = 0;
+	}
+
+	return max_current;
+}
+
 static int sd_set_current_limit(struct mmc_card *card, u8 *status)
 {
-	int current_limit = 0;
+	int current_limit = SD_SET_CURRENT_NO_CHANGE;
 	int err;
+	u32 max_current;
 
 	/*
 	 * Current limit switch is only defined for SDR50, SDR104, and DDR50
-	 * bus speed modes. For other bus speed modes, we set the default
-	 * current limit of 200mA.
+	 * bus speed modes. For other bus speed modes, we do not change the
+	 * current limit.
 	 */
-	if ((card->sd_bus_speed == UHS_SDR50_BUS_SPEED) ||
-	    (card->sd_bus_speed == UHS_SDR104_BUS_SPEED) ||
-	    (card->sd_bus_speed == UHS_DDR50_BUS_SPEED)) {
-		if (card->host->caps & MMC_CAP_MAX_CURRENT_800) {
-			if (card->sw_caps.sd3_curr_limit & SD_MAX_CURRENT_800)
-				current_limit = SD_SET_CURRENT_LIMIT_800;
-			else if (card->sw_caps.sd3_curr_limit &
-					SD_MAX_CURRENT_600)
-				current_limit = SD_SET_CURRENT_LIMIT_600;
-			else if (card->sw_caps.sd3_curr_limit &
-					SD_MAX_CURRENT_400)
-				current_limit = SD_SET_CURRENT_LIMIT_400;
-			else if (card->sw_caps.sd3_curr_limit &
-					SD_MAX_CURRENT_200)
-				current_limit = SD_SET_CURRENT_LIMIT_200;
-		} else if (card->host->caps & MMC_CAP_MAX_CURRENT_600) {
-			if (card->sw_caps.sd3_curr_limit & SD_MAX_CURRENT_600)
-				current_limit = SD_SET_CURRENT_LIMIT_600;
-			else if (card->sw_caps.sd3_curr_limit &
-					SD_MAX_CURRENT_400)
-				current_limit = SD_SET_CURRENT_LIMIT_400;
-			else if (card->sw_caps.sd3_curr_limit &
-					SD_MAX_CURRENT_200)
-				current_limit = SD_SET_CURRENT_LIMIT_200;
-		} else if (card->host->caps & MMC_CAP_MAX_CURRENT_400) {
-			if (card->sw_caps.sd3_curr_limit & SD_MAX_CURRENT_400)
-				current_limit = SD_SET_CURRENT_LIMIT_400;
-			else if (card->sw_caps.sd3_curr_limit &
-					SD_MAX_CURRENT_200)
-				current_limit = SD_SET_CURRENT_LIMIT_200;
-		} else if (card->host->caps & MMC_CAP_MAX_CURRENT_200) {
-			if (card->sw_caps.sd3_curr_limit & SD_MAX_CURRENT_200)
-				current_limit = SD_SET_CURRENT_LIMIT_200;
-		}
-	} else
+	if ((card->sd_bus_speed != UHS_SDR50_BUS_SPEED) &&
+	    (card->sd_bus_speed != UHS_SDR104_BUS_SPEED) &&
+	    (card->sd_bus_speed != UHS_DDR50_BUS_SPEED))
+		return 0;
+
+	/*
+	 * Host has different current capabilities when operating at
+	 * different voltages, so find out its max current first.
+	 */
+	max_current = sd_get_host_max_current(card->host);
+
+	/*
+	 * We only check host's capability here, if we set a limit that is
+	 * higher than the card's maximum current, the card will be using its
+	 * maximum current, e.g. if the card's maximum current is 300ma, and
+	 * when we set current limit to 200ma, the card will draw 200ma, and
+	 * when we set current limit to 400/600/800ma, the card will draw its
+	 * maximum 300ma from the host.
+	 */
+	if (max_current >= 800)
+		current_limit = SD_SET_CURRENT_LIMIT_800;
+	else if (max_current >= 600)
+		current_limit = SD_SET_CURRENT_LIMIT_600;
+	else if (max_current >= 400)
+		current_limit = SD_SET_CURRENT_LIMIT_400;
+	else if (max_current >= 200)
 		current_limit = SD_SET_CURRENT_LIMIT_200;
 
-	err = mmc_sd_switch(card, 1, 3, current_limit, status);
-	if (err)
-		return err;
+	if (current_limit != SD_SET_CURRENT_NO_CHANGE) {
+		err = mmc_sd_switch(card, 1, 3, current_limit, status);
+		if (err)
+			return err;
 
-	if (((status[15] >> 4) & 0x0F) != current_limit)
-		pr_warning("%s: Problem setting current limit!\n",
-			mmc_hostname(card->host));
+		if (((status[15] >> 4) & 0x0F) != current_limit)
+			pr_warning("%s: Problem setting current limit!\n",
+				mmc_hostname(card->host));
+
+	}
 
 	return 0;
 }
@@ -726,6 +711,15 @@
 int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid, u32 *rocr)
 {
 	int err;
+	u32 max_current;
+	int retries = 10;
+
+try_again:
+	if (!retries) {
+		ocr &= ~SD_OCR_S18R;
+		pr_warning("%s: Skipping voltage switch\n",
+			mmc_hostname(host));
+	}
 
 	/*
 	 * Since we're changing the OCR value, we seem to
@@ -747,18 +741,20 @@
 
 	/*
 	 * If the host supports one of UHS-I modes, request the card
-	 * to switch to 1.8V signaling level.
+	 * to switch to 1.8V signaling level. If the card has failed
+	 * repeatedly to switch however, skip this.
 	 */
-	if (host->caps & (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 |
-	    MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104 | MMC_CAP_UHS_DDR50))
+	if (retries && mmc_host_uhs(host))
 		ocr |= SD_OCR_S18R;
 
-	/* If the host can supply more than 150mA, XPC should be set to 1. */
-	if (host->caps & (MMC_CAP_SET_XPC_330 | MMC_CAP_SET_XPC_300 |
-	    MMC_CAP_SET_XPC_180))
+	/*
+	 * If the host can supply more than 150mA at current voltage,
+	 * XPC should be set to 1.
+	 */
+	max_current = sd_get_host_max_current(host);
+	if (max_current > 150)
 		ocr |= SD_OCR_XPC;
 
-try_again:
 	err = mmc_send_app_op_cond(host, ocr, rocr);
 	if (err)
 		return err;
@@ -769,9 +765,12 @@
 	 */
 	if (!mmc_host_is_spi(host) && rocr &&
 	   ((*rocr & 0x41000000) == 0x41000000)) {
-		err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180, true);
-		if (err) {
-			ocr &= ~SD_OCR_S18R;
+		err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180);
+		if (err == -EAGAIN) {
+			retries--;
+			goto try_again;
+		} else if (err) {
+			retries = 0;
 			goto try_again;
 		}
 	}
@@ -806,9 +805,6 @@
 	bool reinit)
 {
 	int err;
-#ifdef CONFIG_MMC_PARANOID_SD_INIT
-	int retries;
-#endif
 
 	if (!reinit) {
 		/*
@@ -835,26 +831,7 @@
 		/*
 		 * Fetch switch information from card.
 		 */
-#ifdef CONFIG_MMC_PARANOID_SD_INIT
-		for (retries = 1; retries <= 3; retries++) {
-			err = mmc_read_switch(card);
-			if (!err) {
-				if (retries > 1) {
-					printk(KERN_WARNING
-					       "%s: recovered\n", 
-					       mmc_hostname(host));
-				}
-				break;
-			} else {
-				printk(KERN_WARNING
-				       "%s: read switch failed (attempt %d)\n",
-				       mmc_hostname(host), retries);
-			}
-		}
-#else
 		err = mmc_read_switch(card);
-#endif
-
 		if (err)
 			return err;
 	}
@@ -933,9 +910,6 @@
 	BUG_ON(!host);
 	WARN_ON(!host->claimed);
 
-	/* The initialization should be done at 3.3 V I/O voltage. */
-	mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_330, 0);
-
 	err = mmc_sd_get_cid(host, ocr, cid, &rocr);
 	if (err)
 		return err;
@@ -995,16 +969,6 @@
 
 		/* Card is an ultra-high-speed card */
 		mmc_card_set_uhs(card);
-
-		/*
-		 * Since initialization is now complete, enable preset
-		 * value registers for UHS-I cards.
-		 */
-		if (host->ops->enable_preset_value) {
-			mmc_host_clk_hold(card->host);
-			host->ops->enable_preset_value(host, true);
-			mmc_host_clk_release(card->host);
-		}
 	} else {
 		/*
 		 * Attempt to change to high-speed (if supported)
@@ -1068,36 +1032,18 @@
  */
 static void mmc_sd_detect(struct mmc_host *host)
 {
-	int err = 0;
-#ifdef CONFIG_MMC_PARANOID_SD_INIT
-        int retries = 5;
-#endif
+	int err;
 
 	BUG_ON(!host);
 	BUG_ON(!host->card);
-       
+
 	mmc_claim_host(host);
 
 	/*
 	 * Just check if our card has been removed.
 	 */
-#ifdef CONFIG_MMC_PARANOID_SD_INIT
-	while(retries) {
-		err = mmc_send_status(host->card, NULL);
-		if (err) {
-			retries--;
-			udelay(5);
-			continue;
-		}
-		break;
-	}
-	if (!retries) {
-		printk(KERN_ERR "%s(%s): Unable to re-detect card (%d)\n",
-		       __func__, mmc_hostname(host), err);
-	}
-#else
 	err = _mmc_detect_card_removed(host);
-#endif
+
 	mmc_release_host(host);
 
 	if (err) {
@@ -1115,16 +1061,18 @@
  */
 static int mmc_sd_suspend(struct mmc_host *host)
 {
+	int err = 0;
+
 	BUG_ON(!host);
 	BUG_ON(!host->card);
 
 	mmc_claim_host(host);
 	if (!mmc_host_is_spi(host))
-		mmc_deselect_cards(host);
+		err = mmc_deselect_cards(host);
 	host->card->state &= ~MMC_STATE_HIGHSPEED;
 	mmc_release_host(host);
 
-	return 0;
+	return err;
 }
 
 /*
@@ -1136,31 +1084,12 @@
 static int mmc_sd_resume(struct mmc_host *host)
 {
 	int err;
-#ifdef CONFIG_MMC_PARANOID_SD_INIT
-	int retries;
-#endif
 
 	BUG_ON(!host);
 	BUG_ON(!host->card);
 
 	mmc_claim_host(host);
-#ifdef CONFIG_MMC_PARANOID_SD_INIT
-	retries = 5;
-	while (retries) {
-		err = mmc_sd_init_card(host, host->ocr, host->card);
-
-		if (err) {
-			printk(KERN_ERR "%s: Re-init card rc = %d (retries = %d)\n",
-			       mmc_hostname(host), err, retries);
-			mdelay(5);
-			retries--;
-			continue;
-		}
-		break;
-	}
-#else
 	err = mmc_sd_init_card(host, host->ocr, host->card);
-#endif
 	mmc_release_host(host);
 
 	return err;
@@ -1214,20 +1143,10 @@
 {
 	int err;
 	u32 ocr;
-#ifdef CONFIG_MMC_PARANOID_SD_INIT
-	int retries;
-#endif
 
 	BUG_ON(!host);
 	WARN_ON(!host->claimed);
 
-	/* Disable preset value enable if already set since last time */
-	if (host->ops->enable_preset_value) {
-		mmc_host_clk_hold(host);
-		host->ops->enable_preset_value(host, false);
-		mmc_host_clk_release(host);
-	}
-
 	err = mmc_send_app_op_cond(host, 0, &ocr);
 	if (err)
 		return err;
@@ -1279,27 +1198,9 @@
 	/*
 	 * Detect and init the card.
 	 */
-#ifdef CONFIG_MMC_PARANOID_SD_INIT
-	retries = 5;
-	while (retries) {
-		err = mmc_sd_init_card(host, host->ocr, NULL);
-		if (err) {
-			retries--;
-			continue;
-		}
-		break;
-	}
-
-	if (!retries) {
-		printk(KERN_ERR "%s: mmc_sd_init_card() failure (err = %d)\n",
-		       mmc_hostname(host), err);
-		goto err;
-	}
-#else
 	err = mmc_sd_init_card(host, host->ocr, NULL);
 	if (err)
 		goto err;
-#endif
 
 	mmc_release_host(host);
 	err = mmc_add_card(host->card);
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/core/sdio_bus.c linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/core/sdio_bus.c
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/core/sdio_bus.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/core/sdio_bus.c	2014-09-12 15:59:37.348052000 +0800
@@ -16,6 +16,7 @@
 #include <linux/export.h>
 #include <linux/slab.h>
 #include <linux/pm_runtime.h>
+#include <linux/acpi.h>
 
 #include <linux/mmc/card.h>
 #include <linux/mmc/host.h>
@@ -24,10 +25,6 @@
 #include "sdio_cis.h"
 #include "sdio_bus.h"
 
-#ifdef CONFIG_MMC_EMBEDDED_SDIO
-#include <linux/mmc/host.h>
-#endif
-
 /* show configuration fields */
 #define sdio_config_attr(field, format_string)				\
 static ssize_t								\
@@ -141,7 +138,7 @@
 	if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD) {
 		ret = pm_runtime_get_sync(dev);
 		if (ret < 0)
-			goto out;
+			goto disable_runtimepm;
 	}
 
 	/* Set the default block size so the driver is sure it's something
@@ -161,7 +158,6 @@
 disable_runtimepm:
 	if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD)
 		pm_runtime_put_noidle(dev);
-out:
 	return ret;
 }
 
@@ -198,10 +194,17 @@
 
 #ifdef CONFIG_PM
 
+#ifdef CONFIG_PM_SLEEP
 static int pm_no_operation(struct device *dev)
 {
+	/*
+	 * Prevent the PM core from calling SDIO device drivers' suspend
+	 * callback routines, which it is not supposed to do, by using this
+	 * empty function as the bus type suspend callaback for SDIO.
+	 */
 	return 0;
 }
+#endif
 
 static const struct dev_pm_ops sdio_bus_pm_ops = {
 	SET_SYSTEM_SLEEP_PM_OPS(pm_no_operation, pm_no_operation)
@@ -267,17 +270,9 @@
 {
 	struct sdio_func *func = dev_to_sdio_func(dev);
 
-#ifdef CONFIG_MMC_EMBEDDED_SDIO
-	/*
-	 * If this device is embedded then we never allocated
-	 * cis tables for this func
-	 */
-	if (!func->card->host->embedded_sdio_data.funcs)
-#endif
-		sdio_free_func_cis(func);
+	sdio_free_func_cis(func);
 
-	if (func->info)
-		kfree(func->info);
+	kfree(func->info);
 
 	kfree(func);
 }
@@ -304,6 +299,19 @@
 	return func;
 }
 
+#ifdef CONFIG_ACPI
+static void sdio_acpi_set_handle(struct sdio_func *func)
+{
+	struct mmc_host *host = func->card->host;
+	u64 addr = (host->slotno << 16) | func->num;
+
+	ACPI_HANDLE_SET(&func->dev,
+			acpi_get_child(ACPI_HANDLE(host->parent), addr));
+}
+#else
+static inline void sdio_acpi_set_handle(struct sdio_func *func) {}
+#endif
+
 /*
  * Register a new SDIO function with the driver model.
  */
@@ -313,9 +321,12 @@
 
 	dev_set_name(&func->dev, "%s:%d", mmc_card_id(func->card), func->num);
 
+	sdio_acpi_set_handle(func);
 	ret = device_add(&func->dev);
-	if (ret == 0)
+	if (ret == 0) {
 		sdio_func_set_present(func);
+		acpi_dev_pm_attach(&func->dev, false);
+	}
 
 	return ret;
 }
@@ -331,6 +342,7 @@
 	if (!sdio_func_present(func))
 		return;
 
+	acpi_dev_pm_detach(&func->dev, false);
 	device_del(&func->dev);
 	put_device(&func->dev);
 }
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/core/sdio.c linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/core/sdio.c
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/core/sdio.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/core/sdio.c	2014-09-12 15:59:37.348052000 +0800
@@ -10,7 +10,6 @@
  */
 
 #include <linux/err.h>
-#include <linux/module.h>
 #include <linux/pm_runtime.h>
 
 #include <linux/mmc/host.h>
@@ -29,10 +28,6 @@
 #include "sdio_ops.h"
 #include "sdio_cis.h"
 
-#ifdef CONFIG_MMC_EMBEDDED_SDIO
-#include <linux/mmc/sdio_ids.h>
-#endif
-
 static int sdio_read_fbr(struct sdio_func *func)
 {
 	int ret;
@@ -162,10 +157,7 @@
 			if (ret)
 				goto out;
 
-			if (card->host->caps &
-				(MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 |
-				 MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104 |
-				 MMC_CAP_UHS_DDR50)) {
+			if (mmc_host_uhs(card->host)) {
 				if (data & SDIO_UHS_DDR50)
 					card->sw_caps.sd3_bus_mode
 						|= SD_MODE_UHS_DDR50;
@@ -223,6 +215,12 @@
 	if (ret)
 		return ret;
 
+	if ((ctrl & SDIO_BUS_WIDTH_MASK) == SDIO_BUS_WIDTH_RESERVED)
+		pr_warning("%s: SDIO_CCCR_IF is invalid: 0x%02x\n",
+			   mmc_hostname(card->host), ctrl);
+
+	/* set as 4-bit bus width */
+	ctrl &= ~SDIO_BUS_WIDTH_MASK;
 	ctrl |= SDIO_BUS_WIDTH_4BIT;
 
 	ret = mmc_io_rw_direct(card, 1, 0, SDIO_CCCR_IF, ctrl, NULL);
@@ -477,8 +475,7 @@
 	 * If the host doesn't support any of the UHS-I modes, fallback on
 	 * default speed.
 	 */
-	if (!(card->host->caps & (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 |
-	    MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104 | MMC_CAP_UHS_DDR50)))
+	if (!mmc_host_uhs(card->host))
 		return 0;
 
 	bus_speed = SDIO_SPEED_SDR12;
@@ -488,23 +485,27 @@
 			bus_speed = SDIO_SPEED_SDR104;
 			timing = MMC_TIMING_UHS_SDR104;
 			card->sw_caps.uhs_max_dtr = UHS_SDR104_MAX_DTR;
+			card->sd_bus_speed = UHS_SDR104_BUS_SPEED;
 	} else if ((card->host->caps & MMC_CAP_UHS_DDR50) &&
 		   (card->sw_caps.sd3_bus_mode & SD_MODE_UHS_DDR50)) {
 			bus_speed = SDIO_SPEED_DDR50;
 			timing = MMC_TIMING_UHS_DDR50;
 			card->sw_caps.uhs_max_dtr = UHS_DDR50_MAX_DTR;
+			card->sd_bus_speed = UHS_DDR50_BUS_SPEED;
 	} else if ((card->host->caps & (MMC_CAP_UHS_SDR104 |
 		    MMC_CAP_UHS_SDR50)) && (card->sw_caps.sd3_bus_mode &
 		    SD_MODE_UHS_SDR50)) {
 			bus_speed = SDIO_SPEED_SDR50;
 			timing = MMC_TIMING_UHS_SDR50;
 			card->sw_caps.uhs_max_dtr = UHS_SDR50_MAX_DTR;
+			card->sd_bus_speed = UHS_SDR50_BUS_SPEED;
 	} else if ((card->host->caps & (MMC_CAP_UHS_SDR104 |
 		    MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR25)) &&
 		   (card->sw_caps.sd3_bus_mode & SD_MODE_UHS_SDR25)) {
 			bus_speed = SDIO_SPEED_SDR25;
 			timing = MMC_TIMING_UHS_SDR25;
 			card->sw_caps.uhs_max_dtr = UHS_SDR25_MAX_DTR;
+			card->sd_bus_speed = UHS_SDR25_BUS_SPEED;
 	} else if ((card->host->caps & (MMC_CAP_UHS_SDR104 |
 		    MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR25 |
 		    MMC_CAP_UHS_SDR12)) && (card->sw_caps.sd3_bus_mode &
@@ -512,6 +513,7 @@
 			bus_speed = SDIO_SPEED_SDR12;
 			timing = MMC_TIMING_UHS_SDR12;
 			card->sw_caps.uhs_max_dtr = UHS_SDR12_MAX_DTR;
+			card->sd_bus_speed = UHS_SDR12_BUS_SPEED;
 	}
 
 	err = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_SPEED, 0, &speed);
@@ -582,17 +584,23 @@
 {
 	struct mmc_card *card;
 	int err;
+	int retries = 10;
 
 	BUG_ON(!host);
 	WARN_ON(!host->claimed);
 
+try_again:
+	if (!retries) {
+		pr_warning("%s: Skipping voltage switch\n",
+				mmc_hostname(host));
+		ocr &= ~R4_18V_PRESENT;
+		host->ocr &= ~R4_18V_PRESENT;
+	}
+
 	/*
 	 * Inform the card of the voltage
 	 */
 	if (!powered_resume) {
-		/* The initialization should be done at 3.3 V I/O voltage. */
-		mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_330, 0);
-
 		err = mmc_send_io_op_cond(host, host->ocr, &ocr);
 		if (err)
 			goto err;
@@ -643,18 +651,20 @@
 	/*
 	 * If the host and card support UHS-I mode request the card
 	 * to switch to 1.8V signaling level.  No 1.8v signalling if
-	 * UHS mode is not enabled to maintain compatibilty and some
+	 * UHS mode is not enabled to maintain compatibility and some
 	 * systems that claim 1.8v signalling in fact do not support
 	 * it.
 	 */
-	if ((ocr & R4_18V_PRESENT) &&
-		(host->caps &
-			(MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 |
-			 MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104 |
-			 MMC_CAP_UHS_DDR50))) {
-		err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180,
-				true);
-		if (err) {
+	if (!powered_resume && (ocr & R4_18V_PRESENT) && mmc_host_uhs(host)) {
+		err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180);
+		if (err == -EAGAIN) {
+			sdio_reset(host);
+			mmc_go_idle(host);
+			mmc_send_if_cond(host, host->ocr_avail);
+			mmc_remove_card(card);
+			retries--;
+			goto try_again;
+		} else if (err) {
 			ocr &= ~R4_18V_PRESENT;
 			host->ocr &= ~R4_18V_PRESENT;
 		}
@@ -718,35 +728,19 @@
 		goto finish;
 	}
 
-#ifdef CONFIG_MMC_EMBEDDED_SDIO
-	if (host->embedded_sdio_data.cccr)
-		memcpy(&card->cccr, host->embedded_sdio_data.cccr, sizeof(struct sdio_cccr));
-	else {
-#endif
-		/*
-		 * Read the common registers.
-		 */
-		err = sdio_read_cccr(card,  ocr);
-		if (err)
-			goto remove;
-#ifdef CONFIG_MMC_EMBEDDED_SDIO
-	}
-#endif
+	/*
+	 * Read the common registers.
+	 */
+	err = sdio_read_cccr(card, ocr);
+	if (err)
+		goto remove;
 
-#ifdef CONFIG_MMC_EMBEDDED_SDIO
-	if (host->embedded_sdio_data.cis)
-		memcpy(&card->cis, host->embedded_sdio_data.cis, sizeof(struct sdio_cis));
-	else {
-#endif
-		/*
-		 * Read the common CIS tuples.
-		 */
-		err = sdio_read_common_cis(card);
-		if (err)
-			goto remove;
-#ifdef CONFIG_MMC_EMBEDDED_SDIO
-	}
-#endif
+	/*
+	 * Read the common CIS tuples.
+	 */
+	err = sdio_read_common_cis(card);
+	if (err)
+		goto remove;
 
 	if (oldcard) {
 		int same = (card->cis.vendor == oldcard->cis.vendor &&
@@ -867,8 +861,10 @@
 	/* Make sure card is powered before detecting it */
 	if (host->caps & MMC_CAP_POWER_OFF_CARD) {
 		err = pm_runtime_get_sync(&host->card->dev);
-		if (err < 0)
+		if (err < 0) {
+			pm_runtime_put_noidle(&host->card->dev);
 			goto out;
+		}
 	}
 
 	mmc_claim_host(host);
@@ -955,10 +951,12 @@
 	mmc_claim_host(host);
 
 	/* No need to reinitialize powered-resumed nonremovable cards */
-	if (mmc_card_is_removable(host) || !mmc_card_keep_power(host))
+	if (mmc_card_is_removable(host) || !mmc_card_keep_power(host)) {
+		sdio_reset(host);
+		mmc_go_idle(host);
 		err = mmc_sdio_init_card(host, host->ocr, host->card,
 					mmc_card_keep_power(host));
-	else if (mmc_card_keep_power(host) && mmc_card_wake_sdio_irq(host)) {
+	} else if (mmc_card_keep_power(host) && mmc_card_wake_sdio_irq(host)) {
 		/* We may have switched to 1-bit mode during suspend */
 		err = sdio_enable_4bit_bus(host->card);
 		if (err > 0) {
@@ -968,7 +966,7 @@
 	}
 
 	if (!err && host->sdio_irqs)
-		mmc_signal_sdio_irq(host);
+		wake_up_process(host->sdio_irq_thread);
 	mmc_release_host(host);
 
 	/*
@@ -1021,10 +1019,6 @@
 	 * restore the correct voltage setting of the card.
 	 */
 
-	/* The initialization should be done at 3.3 V I/O voltage. */
-	if (!mmc_card_keep_power(host))
-		mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_330, 0);
-
 	sdio_reset(host);
 	mmc_go_idle(host);
 	mmc_send_if_cond(host, host->ocr_avail);
@@ -1042,6 +1036,10 @@
 		goto out;
 	}
 
+	if (mmc_host_uhs(host))
+		/* to query card if 1.8V signalling is supported */
+		host->ocr |= R4_18V_PRESENT;
+
 	ret = mmc_sdio_init_card(host, host->ocr, host->card,
 				mmc_card_keep_power(host));
 	if (!ret && host->sdio_irqs)
@@ -1107,6 +1105,10 @@
 	/*
 	 * Detect and init the card.
 	 */
+	if (mmc_host_uhs(host))
+		/* to query card if 1.8V signalling is supported */
+		host->ocr |= R4_18V_PRESENT;
+
 	err = mmc_sdio_init_card(host, host->ocr, NULL, 0);
 	if (err) {
 		if (err == -EAGAIN) {
@@ -1145,36 +1147,14 @@
 	funcs = (ocr & 0x70000000) >> 28;
 	card->sdio_funcs = 0;
 
-#ifdef CONFIG_MMC_EMBEDDED_SDIO
-	if (host->embedded_sdio_data.funcs)
-		card->sdio_funcs = funcs = host->embedded_sdio_data.num_funcs;
-#endif
-
 	/*
 	 * Initialize (but don't add) all present functions.
 	 */
 	for (i = 0; i < funcs; i++, card->sdio_funcs++) {
-#ifdef CONFIG_MMC_EMBEDDED_SDIO
-		if (host->embedded_sdio_data.funcs) {
-			struct sdio_func *tmp;
-
-			tmp = sdio_alloc_func(host->card);
-			if (IS_ERR(tmp))
-				goto remove;
-			tmp->num = (i + 1);
-			card->sdio_func[i] = tmp;
-			tmp->class = host->embedded_sdio_data.funcs[i].f_class;
-			tmp->max_blksize = host->embedded_sdio_data.funcs[i].f_maxblksize;
-			tmp->vendor = card->cis.vendor;
-			tmp->device = card->cis.device;
-		} else {
-#endif
-			err = sdio_init_func(host->card, i + 1);
-			if (err)
-				goto remove;
-#ifdef CONFIG_MMC_EMBEDDED_SDIO
-		}
-#endif
+		err = sdio_init_func(host->card, i + 1);
+		if (err)
+			goto remove;
+
 		/*
 		 * Enable Runtime PM for this func (if supported)
 		 */
@@ -1222,77 +1202,3 @@
 	return err;
 }
 
-int sdio_reset_comm(struct mmc_card *card)
-{
-	struct mmc_host *host = card->host;
-	u32 ocr;
-	int err;
-
-	printk("%s():\n", __func__);
-	mmc_claim_host(host);
-
-	mmc_go_idle(host);
-
-	mmc_set_clock(host, host->f_min);
-
-	err = mmc_send_io_op_cond(host, 0, &ocr);
-	if (err)
-		goto err;
-
-	host->ocr = mmc_select_voltage(host, ocr);
-	if (!host->ocr) {
-		err = -EINVAL;
-		goto err;
-	}
-
-	err = mmc_send_io_op_cond(host, host->ocr, &ocr);
-	if (err)
-		goto err;
-
-	if (mmc_host_is_spi(host)) {
-		err = mmc_spi_set_crc(host, use_spi_crc);
-		if (err)
-			goto err;
-	}
-
-	if (!mmc_host_is_spi(host)) {
-		err = mmc_send_relative_addr(host, &card->rca);
-		if (err)
-			goto err;
-		mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL);
-	}
-	if (!mmc_host_is_spi(host)) {
-		err = mmc_select_card(card);
-		if (err)
-			goto err;
-	}
-
-	/*
-	 * Switch to high-speed (if supported).
-	 */
-	err = sdio_enable_hs(card);
-	if (err > 0)
-		mmc_sd_go_highspeed(card);
-	else if (err)
-		goto err;
-
-	/*
-	 * Change to the card's maximum speed.
-	 */
-	mmc_set_clock(host, mmc_sdio_get_max_clock(card));
-
-	err = sdio_enable_4bit_bus(card);
-	if (err > 0)
-		mmc_set_bus_width(host, MMC_BUS_WIDTH_4);
-	else if (err)
-		goto err;
-
-	mmc_release_host(host);
-	return 0;
-err:
-	printk("%s: Error resetting SDIO communications (%d)\n",
-	       mmc_hostname(host), err);
-	mmc_release_host(host);
-	return err;
-}
-EXPORT_SYMBOL(sdio_reset_comm);
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/core/sdio_cis.c linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/core/sdio_cis.c
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/core/sdio_cis.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/core/sdio_cis.c	2014-09-12 15:59:37.348052000 +0800
@@ -313,7 +313,7 @@
 
 			if (ret == -ENOENT) {
 				/* warn about unknown tuples */
-				pr_warning("%s: queuing unknown"
+				printk("%s: queuing unknown"
 				       " CIS tuple 0x%02x (%u bytes)\n",
 				       mmc_hostname(card->host),
 				       tpl_code, tpl_link);
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/core/sdio_io.c linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/core/sdio_io.c
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/core/sdio_io.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/core/sdio_io.c	2014-09-12 15:59:37.348052000 +0800
@@ -188,8 +188,7 @@
  */
 static inline unsigned int sdio_max_byte_size(struct sdio_func *func)
 {
-	unsigned mval =	min(func->card->host->max_seg_size,
-			    func->card->host->max_blk_size);
+	unsigned mval =	func->card->host->max_blk_size;
 
 	if (mmc_blksz_for_byte_mode(func->card))
 		mval = min(mval, func->cur_blksize);
@@ -311,11 +310,8 @@
 	/* Do the bulk of the transfer using block mode (if supported). */
 	if (func->card->cccr.multi_block && (size > sdio_max_byte_size(func))) {
 		/* Blocks per command is limited by host count, host transfer
-		 * size (we only use a single sg entry) and the maximum for
-		 * IO_RW_EXTENDED of 511 blocks. */
-		max_blocks = min(func->card->host->max_blk_count,
-			func->card->host->max_seg_size / func->cur_blksize);
-		max_blocks = min(max_blocks, 511u);
+		 * size and the maximum for IO_RW_EXTENDED of 511 blocks. */
+		max_blocks = min(func->card->host->max_blk_count, 511u);
 
 		while (remainder >= func->cur_blksize) {
 			unsigned blocks;
@@ -388,39 +384,6 @@
 EXPORT_SYMBOL_GPL(sdio_readb);
 
 /**
- *	sdio_readb_ext - read a single byte from a SDIO function
- *	@func: SDIO function to access
- *	@addr: address to read
- *	@err_ret: optional status value from transfer
- *	@in: value to add to argument
- *
- *	Reads a single byte from the address space of a given SDIO
- *	function. If there is a problem reading the address, 0xff
- *	is returned and @err_ret will contain the error code.
- */
-unsigned char sdio_readb_ext(struct sdio_func *func, unsigned int addr,
-	int *err_ret, unsigned in)
-{
-	int ret;
-	unsigned char val;
-
-	BUG_ON(!func);
-
-	if (err_ret)
-		*err_ret = 0;
-
-	ret = mmc_io_rw_direct(func->card, 0, func->num, addr, (u8)in, &val);
-	if (ret) {
-		if (err_ret)
-			*err_ret = ret;
-		return 0xFF;
-	}
-
-	return val;
-}
-EXPORT_SYMBOL_GPL(sdio_readb_ext);
-
-/**
  *	sdio_writeb - write a single byte to a SDIO function
  *	@func: SDIO function to access
  *	@b: byte to write
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/core/sdio_irq.c linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/core/sdio_irq.c
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/core/sdio_irq.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/core/sdio_irq.c	2014-09-12 15:59:37.348052000 +0800
@@ -28,23 +28,25 @@
 
 #include "sdio_ops.h"
 
-static int process_sdio_pending_irqs(struct mmc_card *card)
+static int process_sdio_pending_irqs(struct mmc_host *host)
 {
+	struct mmc_card *card = host->card;
 	int i, ret, count;
 	unsigned char pending;
 	struct sdio_func *func;
 
 	/*
 	 * Optimization, if there is only 1 function interrupt registered
-	 * call irq handler directly
+	 * and we know an IRQ was signaled then call irq handler directly.
+	 * Otherwise do the full probe.
 	 */
 	func = card->sdio_single_irq;
-	if (func) {
+	if (func && host->sdio_irq_pending) {
 		func->irq_handler(func);
 		return 1;
 	}
 
-	ret = mmc_io_rw_direct_irq(card, &pending);
+	ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_INTx, 0, &pending);
 	if (ret) {
 		pr_debug("%s: error %d reading SDIO_CCCR_INTx\n",
 		       mmc_card_id(card), ret);
@@ -116,7 +118,8 @@
 		ret = __mmc_claim_host(host, &host->sdio_irq_thread_abort);
 		if (ret)
 			break;
-		ret = process_sdio_pending_irqs(host->card);
+		ret = process_sdio_pending_irqs(host);
+		host->sdio_irq_pending = false;
 		mmc_release_host(host);
 
 		/*
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/core/sdio_ops.c linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/core/sdio_ops.c
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/core/sdio_ops.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/core/sdio_ops.c	2014-09-12 15:59:37.348052000 +0800
@@ -111,46 +111,6 @@
 	return 0;
 }
 
-static struct mmc_command sdio_intx_cmd = {
-	.opcode = SD_IO_RW_DIRECT,
-	.arg = SDIO_CCCR_INTx << 9,
-	.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_AC,
-};
-
-int mmc_io_rw_direct_irq(struct mmc_card *card, u8 *out)
-{
-	int err;
-	struct mmc_host *host ;
-
-	BUG_ON(!card);
-	host = card->host;
-	BUG_ON(!host);
-
-	err = mmc_wait_for_cmd(host, &sdio_intx_cmd, 0);
-	if (err)
-		return err;
-
-	if (mmc_host_is_spi(host)) {
-		/* host driver already reported errors */
-	} else {
-		if (sdio_intx_cmd.resp[0] & R5_ERROR)
-			return -EIO;
-		if (sdio_intx_cmd.resp[0] & R5_FUNCTION_NUMBER)
-			return -EINVAL;
-		if (sdio_intx_cmd.resp[0] & R5_OUT_OF_RANGE)
-			return -ERANGE;
-	}
-
-	if (out) {
-		if (mmc_host_is_spi(host))
-			*out = (sdio_intx_cmd.resp[0] >> 8) & 0xFF;
-		else
-			*out = sdio_intx_cmd.resp[0] & 0xFF;
-	}
-
-	return 0;
-}
-
 int mmc_io_rw_direct(struct mmc_card *card, int write, unsigned fn,
 	unsigned addr, u8 in, u8 *out)
 {
@@ -164,7 +124,10 @@
 	struct mmc_request mrq = {NULL};
 	struct mmc_command cmd = {0};
 	struct mmc_data data = {0};
-	struct scatterlist sg;
+	struct scatterlist sg, *sg_ptr;
+	struct sg_table sgtable;
+	unsigned int nents, left_size, i;
+	unsigned int seg_size = card->host->max_seg_size;
 
 	BUG_ON(!card);
 	BUG_ON(fn > 7);
@@ -192,15 +155,36 @@
 	/* Code in host drivers/fwk assumes that "blocks" always is >=1 */
 	data.blocks = blocks ? blocks : 1;
 	data.flags = write ? MMC_DATA_WRITE : MMC_DATA_READ;
-	data.sg = &sg;
-	data.sg_len = 1;
 
-	sg_init_one(&sg, buf, data.blksz * data.blocks);
+	left_size = data.blksz * data.blocks;
+	nents = (left_size - 1) / seg_size + 1;
+	if (nents > 1) {
+		if (sg_alloc_table(&sgtable, nents, GFP_KERNEL))
+			return -ENOMEM;
+
+		data.sg = sgtable.sgl;
+		data.sg_len = nents;
+
+		for_each_sg(data.sg, sg_ptr, data.sg_len, i) {
+			sg_set_page(sg_ptr, virt_to_page(buf + (i * seg_size)),
+					min(seg_size, left_size),
+					offset_in_page(buf + (i * seg_size)));
+			left_size = left_size - seg_size;
+		}
+	} else {
+		data.sg = &sg;
+		data.sg_len = 1;
+
+		sg_init_one(&sg, buf, left_size);
+	}
 
 	mmc_set_data_timeout(&data, card);
 
 	mmc_wait_for_req(card->host, &mrq);
 
+	if (nents > 1)
+		sg_free_table(&sgtable);
+
 	if (cmd.error)
 		return cmd.error;
 	if (data.error)
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/core/sdio_ops.h linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/core/sdio_ops.h
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/core/sdio_ops.h	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/core/sdio_ops.h	2014-09-12 15:59:37.348052000 +0800
@@ -15,7 +15,6 @@
 int mmc_send_io_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr);
 int mmc_io_rw_direct(struct mmc_card *card, int write, unsigned fn,
 	unsigned addr, u8 in, u8* out);
-int mmc_io_rw_direct_irq(struct mmc_card *card, u8 *out);
 int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn,
 	unsigned addr, int incr_addr, u8 *buf, unsigned blocks, unsigned blksz);
 int sdio_reset(struct mmc_host *host);
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/core/slot-gpio.c linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/core/slot-gpio.c
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/core/slot-gpio.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/core/slot-gpio.c	2014-09-12 15:59:37.348052000 +0800
@@ -0,0 +1,246 @@
+/*
+ * Generic GPIO card-detect helper
+ *
+ * Copyright (C) 2011, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+ *
+ * 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/err.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/jiffies.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/slot-gpio.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+
+struct mmc_gpio {
+	int ro_gpio;
+	int cd_gpio;
+	char *ro_label;
+	char cd_label[0];
+};
+
+static irqreturn_t mmc_gpio_cd_irqt(int irq, void *dev_id)
+{
+	/* Schedule a card detection after a debounce timeout */
+	struct mmc_host *host = dev_id;
+
+	if (host->ops->card_event)
+		host->ops->card_event(host);
+
+	mmc_detect_change(host, msecs_to_jiffies(200));
+
+	return IRQ_HANDLED;
+}
+
+static int mmc_gpio_alloc(struct mmc_host *host)
+{
+	size_t len = strlen(dev_name(host->parent)) + 4;
+	struct mmc_gpio *ctx;
+
+	mutex_lock(&host->slot.lock);
+
+	ctx = host->slot.handler_priv;
+	if (!ctx) {
+		/*
+		 * devm_kzalloc() can be called after device_initialize(), even
+		 * before device_add(), i.e., between mmc_alloc_host() and
+		 * mmc_add_host()
+		 */
+		ctx = devm_kzalloc(&host->class_dev, sizeof(*ctx) + 2 * len,
+				   GFP_KERNEL);
+		if (ctx) {
+			ctx->ro_label = ctx->cd_label + len;
+			snprintf(ctx->cd_label, len, "%s cd", dev_name(host->parent));
+			snprintf(ctx->ro_label, len, "%s ro", dev_name(host->parent));
+			ctx->cd_gpio = -EINVAL;
+			ctx->ro_gpio = -EINVAL;
+			host->slot.handler_priv = ctx;
+		}
+	}
+
+	mutex_unlock(&host->slot.lock);
+
+	return ctx ? 0 : -ENOMEM;
+}
+
+int mmc_gpio_get_ro(struct mmc_host *host)
+{
+	struct mmc_gpio *ctx = host->slot.handler_priv;
+
+	if (!ctx || !gpio_is_valid(ctx->ro_gpio))
+		return -ENOSYS;
+
+	return !gpio_get_value_cansleep(ctx->ro_gpio) ^
+		!!(host->caps2 & MMC_CAP2_RO_ACTIVE_HIGH);
+}
+EXPORT_SYMBOL(mmc_gpio_get_ro);
+
+int mmc_gpio_get_cd(struct mmc_host *host)
+{
+	struct mmc_gpio *ctx = host->slot.handler_priv;
+
+	if (!ctx || !gpio_is_valid(ctx->cd_gpio))
+		return -ENOSYS;
+
+	return !gpio_get_value_cansleep(ctx->cd_gpio) ^
+		!!(host->caps2 & MMC_CAP2_CD_ACTIVE_HIGH);
+}
+EXPORT_SYMBOL(mmc_gpio_get_cd);
+
+/**
+ * mmc_gpio_request_ro - request a gpio for write-protection
+ * @host: mmc host
+ * @gpio: gpio number requested
+ *
+ * As devm_* managed functions are used in mmc_gpio_request_ro(), client
+ * drivers do not need to explicitly call mmc_gpio_free_ro() for freeing up,
+ * if the requesting and freeing are only needed at probing and unbinding time
+ * for once.  However, if client drivers do something special like runtime
+ * switching for write-protection, they are responsible for calling
+ * mmc_gpio_request_ro() and mmc_gpio_free_ro() as a pair on their own.
+ *
+ * Returns zero on success, else an error.
+ */
+int mmc_gpio_request_ro(struct mmc_host *host, unsigned int gpio)
+{
+	struct mmc_gpio *ctx;
+	int ret;
+
+	if (!gpio_is_valid(gpio))
+		return -EINVAL;
+
+	ret = mmc_gpio_alloc(host);
+	if (ret < 0)
+		return ret;
+
+	ctx = host->slot.handler_priv;
+
+#if 0
+	ret = devm_gpio_request_one(&host->class_dev, gpio, GPIOF_DIR_IN,
+				    ctx->ro_label);
+	if (ret < 0)
+		return ret;
+#endif
+	ctx->ro_gpio = gpio;
+
+	return 0;
+}
+EXPORT_SYMBOL(mmc_gpio_request_ro);
+
+/**
+ * mmc_gpio_request_cd - request a gpio for card-detection
+ * @host: mmc host
+ * @gpio: gpio number requested
+ *
+ * As devm_* managed functions are used in mmc_gpio_request_cd(), client
+ * drivers do not need to explicitly call mmc_gpio_free_cd() for freeing up,
+ * if the requesting and freeing are only needed at probing and unbinding time
+ * for once.  However, if client drivers do something special like runtime
+ * switching for card-detection, they are responsible for calling
+ * mmc_gpio_request_cd() and mmc_gpio_free_cd() as a pair on their own.
+ *
+ * Returns zero on success, else an error.
+ */
+int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio)
+{
+	struct mmc_gpio *ctx;
+	int irq = gpio_to_irq(gpio);
+	int ret;
+
+	ret = mmc_gpio_alloc(host);
+	if (ret < 0)
+		return ret;
+
+	ctx = host->slot.handler_priv;
+#if 0
+	ret = devm_gpio_request_one(&host->class_dev, gpio, GPIOF_DIR_IN,
+				    ctx->cd_label);
+	if (ret < 0)
+		/*
+		 * don't bother freeing memory. It might still get used by other
+		 * slot functions, in any case it will be freed, when the device
+		 * is destroyed.
+		 */
+		return ret;
+#endif
+	/*
+	 * Even if gpio_to_irq() returns a valid IRQ number, the platform might
+	 * still prefer to poll, e.g., because that IRQ number is already used
+	 * by another unit and cannot be shared.
+	 */
+	if (irq >= 0 && host->caps & MMC_CAP_NEEDS_POLL)
+		irq = -EINVAL;
+
+	if (irq >= 0) {
+		ret = devm_request_threaded_irq(&host->class_dev, irq,
+			NULL, mmc_gpio_cd_irqt,
+			IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+			ctx->cd_label, host);
+		if (ret < 0)
+			irq = ret;
+	}
+
+	host->slot.cd_irq = irq;
+
+	if (irq < 0)
+		host->caps |= MMC_CAP_NEEDS_POLL;
+
+	ctx->cd_gpio = gpio;
+
+	return 0;
+}
+EXPORT_SYMBOL(mmc_gpio_request_cd);
+
+/**
+ * mmc_gpio_free_ro - free the write-protection gpio
+ * @host: mmc host
+ *
+ * It's provided only for cases that client drivers need to manually free
+ * up the write-protection gpio requested by mmc_gpio_request_ro().
+ */
+void mmc_gpio_free_ro(struct mmc_host *host)
+{
+	struct mmc_gpio *ctx = host->slot.handler_priv;
+	int gpio;
+
+	if (!ctx || !gpio_is_valid(ctx->ro_gpio))
+		return;
+
+	gpio = ctx->ro_gpio;
+	ctx->ro_gpio = -EINVAL;
+
+	//devm_gpio_free(&host->class_dev, gpio);
+}
+EXPORT_SYMBOL(mmc_gpio_free_ro);
+
+/**
+ * mmc_gpio_free_cd - free the card-detection gpio
+ * @host: mmc host
+ *
+ * It's provided only for cases that client drivers need to manually free
+ * up the card-detection gpio requested by mmc_gpio_request_cd().
+ */
+void mmc_gpio_free_cd(struct mmc_host *host)
+{
+	struct mmc_gpio *ctx = host->slot.handler_priv;
+	int gpio;
+
+	if (!ctx || !gpio_is_valid(ctx->cd_gpio))
+		return;
+
+	if (host->slot.cd_irq >= 0) {
+		devm_free_irq(&host->class_dev, host->slot.cd_irq, host);
+		host->slot.cd_irq = -EINVAL;
+	}
+
+	gpio = ctx->cd_gpio;
+	ctx->cd_gpio = -EINVAL;
+
+	//devm_gpio_free(&host->class_dev, gpio);
+}
+EXPORT_SYMBOL(mmc_gpio_free_cd);
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/android-goldfish.c linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/android-goldfish.c
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/android-goldfish.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/android-goldfish.c	2014-09-12 15:59:37.348052000 +0800
@@ -0,0 +1,570 @@
+/*
+ *  Copyright 2007, Google Inc.
+ *  Copyright 2012, Intel Inc.
+ *
+ *  based on omap.c driver, which was
+ *  Copyright (C) 2004 Nokia Corporation
+ *  Written by Tuukka Tikkanen and Juha Yrjölä <juha.yrjola@nokia.com>
+ *  Misc hacks here and there by Tony Lindgren <tony@atomide.com>
+ *  Other hacks (DMA, SD, etc) by David Brownell
+ *
+ * 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 <linux/platform_device.h>
+#include <linux/major.h>
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/errno.h>
+#include <linux/hdreg.h>
+#include <linux/kdev_t.h>
+#include <linux/blkdev.h>
+#include <linux/mutex.h>
+#include <linux/scatterlist.h>
+#include <linux/mmc/mmc.h>
+#include <linux/mmc/sdio.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/card.h>
+
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/dma-mapping.h>
+#include <linux/delay.h>
+#include <linux/spinlock.h>
+#include <linux/timer.h>
+#include <linux/clk.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/scatterlist.h>
+
+#include <asm/types.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+
+#define DRIVER_NAME "goldfish_mmc"
+
+#define BUFFER_SIZE   16384
+
+#define GOLDFISH_MMC_READ(host, addr)   (readl(host->reg_base + addr))
+#define GOLDFISH_MMC_WRITE(host, addr, x)   (writel(x, host->reg_base + addr))
+
+enum {
+	/* status register */
+	MMC_INT_STATUS	        = 0x00,
+	/* set this to enable IRQ */
+	MMC_INT_ENABLE	        = 0x04,
+	/* set this to specify buffer address */
+	MMC_SET_BUFFER          = 0x08,
+
+	/* MMC command number */
+	MMC_CMD	                = 0x0C,
+
+	/* MMC argument */
+	MMC_ARG	                = 0x10,
+
+	/* MMC response (or R2 bits 0 - 31) */
+	MMC_RESP_0		        = 0x14,
+
+	/* MMC R2 response bits 32 - 63 */
+	MMC_RESP_1		        = 0x18,
+
+	/* MMC R2 response bits 64 - 95 */
+	MMC_RESP_2		        = 0x1C,
+
+	/* MMC R2 response bits 96 - 127 */
+	MMC_RESP_3		        = 0x20,
+
+	MMC_BLOCK_LENGTH        = 0x24,
+	MMC_BLOCK_COUNT         = 0x28,
+
+	/* MMC state flags */
+	MMC_STATE               = 0x2C,
+
+	/* MMC_INT_STATUS bits */
+
+	MMC_STAT_END_OF_CMD     = 1U << 0,
+	MMC_STAT_END_OF_DATA    = 1U << 1,
+	MMC_STAT_STATE_CHANGE   = 1U << 2,
+	MMC_STAT_CMD_TIMEOUT    = 1U << 3,
+
+	/* MMC_STATE bits */
+	MMC_STATE_INSERTED     = 1U << 0,
+	MMC_STATE_READ_ONLY    = 1U << 1,
+};
+
+/*
+ * Command types
+ */
+#define OMAP_MMC_CMDTYPE_BC	0
+#define OMAP_MMC_CMDTYPE_BCR	1
+#define OMAP_MMC_CMDTYPE_AC	2
+#define OMAP_MMC_CMDTYPE_ADTC	3
+
+
+struct goldfish_mmc_host {
+	struct mmc_request	*mrq;
+	struct mmc_command	*cmd;
+	struct mmc_data		*data;
+	struct mmc_host		*mmc;
+	struct device		*dev;
+	unsigned char		id; /* 16xx chips have 2 MMC blocks */
+	void __iomem		*virt_base;
+	unsigned int		phys_base;
+	int			irq;
+	unsigned char		bus_mode;
+	unsigned char		hw_bus_mode;
+
+	unsigned int		sg_len;
+	unsigned		dma_done:1;
+	unsigned		dma_in_use:1;
+
+	void __iomem		*reg_base;
+};
+
+static inline int
+goldfish_mmc_cover_is_open(struct goldfish_mmc_host *host)
+{
+	return 0;
+}
+
+static ssize_t
+goldfish_mmc_show_cover_switch(struct device *dev,
+			       struct device_attribute *attr, char *buf)
+{
+	struct goldfish_mmc_host *host = dev_get_drvdata(dev);
+
+	return sprintf(buf, "%s\n", goldfish_mmc_cover_is_open(host) ? "open" :
+		       "closed");
+}
+
+static DEVICE_ATTR(cover_switch, S_IRUGO, goldfish_mmc_show_cover_switch, NULL);
+
+static void
+goldfish_mmc_start_command(struct goldfish_mmc_host *host, struct mmc_command *cmd)
+{
+	u32 cmdreg;
+	u32 resptype;
+	u32 cmdtype;
+
+	host->cmd = cmd;
+
+	resptype = 0;
+	cmdtype = 0;
+
+	/* Our hardware needs to know exact type */
+	switch (mmc_resp_type(cmd)) {
+	case MMC_RSP_NONE:
+		break;
+	case MMC_RSP_R1:
+	case MMC_RSP_R1B:
+		/* resp 1, 1b, 6, 7 */
+		resptype = 1;
+		break;
+	case MMC_RSP_R2:
+		resptype = 2;
+		break;
+	case MMC_RSP_R3:
+		resptype = 3;
+		break;
+	default:
+		dev_err(mmc_dev(host->mmc),
+			"Invalid response type: %04x\n", mmc_resp_type(cmd));
+		break;
+	}
+
+	if (mmc_cmd_type(cmd) == MMC_CMD_ADTC)
+		cmdtype = OMAP_MMC_CMDTYPE_ADTC;
+	else if (mmc_cmd_type(cmd) == MMC_CMD_BC)
+		cmdtype = OMAP_MMC_CMDTYPE_BC;
+	else if (mmc_cmd_type(cmd) == MMC_CMD_BCR)
+		cmdtype = OMAP_MMC_CMDTYPE_BCR;
+	else
+		cmdtype = OMAP_MMC_CMDTYPE_AC;
+
+	cmdreg = cmd->opcode | (resptype << 8) | (cmdtype << 12);
+
+	if (host->bus_mode == MMC_BUSMODE_OPENDRAIN)
+		cmdreg |= 1 << 6;
+
+	if (cmd->flags & MMC_RSP_BUSY)
+		cmdreg |= 1 << 11;
+
+	if (host->data && !(host->data->flags & MMC_DATA_WRITE))
+		cmdreg |= 1 << 15;
+
+	GOLDFISH_MMC_WRITE(host, MMC_ARG, cmd->arg);
+	GOLDFISH_MMC_WRITE(host, MMC_CMD, cmdreg);
+}
+
+static void goldfish_mmc_xfer_done(struct goldfish_mmc_host *host,
+				   struct mmc_data *data)
+{
+	if (host->dma_in_use) {
+		enum dma_data_direction dma_data_dir;
+
+		if (data->flags & MMC_DATA_WRITE)
+			dma_data_dir = DMA_TO_DEVICE;
+		else
+			dma_data_dir = DMA_FROM_DEVICE;
+
+		if (dma_data_dir == DMA_FROM_DEVICE) {
+			/*
+			 * We don't really have DMA, so we need
+			 * to copy from our platform driver buffer
+			 */
+			uint8_t *dest = (uint8_t *)sg_virt(data->sg);
+			memcpy(dest, host->virt_base, data->sg->length);
+		}
+		host->data->bytes_xfered += data->sg->length;
+		dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->sg_len,
+			     dma_data_dir);
+	}
+
+	host->data = NULL;
+	host->sg_len = 0;
+
+	/*
+	 * NOTE:  MMC layer will sometimes poll-wait CMD13 next, issuing
+	 * dozens of requests until the card finishes writing data.
+	 * It'd be cheaper to just wait till an EOFB interrupt arrives...
+	 */
+
+	if (!data->stop) {
+		host->mrq = NULL;
+		mmc_request_done(host->mmc, data->mrq);
+		return;
+	}
+
+	goldfish_mmc_start_command(host, data->stop);
+}
+
+static void goldfish_mmc_end_of_data(struct goldfish_mmc_host *host,
+				     struct mmc_data *data)
+{
+	if (!host->dma_in_use) {
+		goldfish_mmc_xfer_done(host, data);
+		return;
+	}
+	if (host->dma_done)
+		goldfish_mmc_xfer_done(host, data);
+}
+
+static void goldfish_mmc_cmd_done(struct goldfish_mmc_host *host,
+				  struct mmc_command *cmd)
+{
+	host->cmd = NULL;
+	if (cmd->flags & MMC_RSP_PRESENT) {
+		if (cmd->flags & MMC_RSP_136) {
+			/* response type 2 */
+			cmd->resp[3] =
+				GOLDFISH_MMC_READ(host, MMC_RESP_0);
+			cmd->resp[2] =
+				GOLDFISH_MMC_READ(host, MMC_RESP_1);
+			cmd->resp[1] =
+				GOLDFISH_MMC_READ(host, MMC_RESP_2);
+			cmd->resp[0] =
+				GOLDFISH_MMC_READ(host, MMC_RESP_3);
+		} else {
+			/* response types 1, 1b, 3, 4, 5, 6 */
+			cmd->resp[0] =
+				GOLDFISH_MMC_READ(host, MMC_RESP_0);
+		}
+	}
+
+	if (host->data == NULL || cmd->error) {
+		host->mrq = NULL;
+		mmc_request_done(host->mmc, cmd->mrq);
+	}
+}
+
+static irqreturn_t goldfish_mmc_irq(int irq, void *dev_id)
+{
+	struct goldfish_mmc_host *host = (struct goldfish_mmc_host *)dev_id;
+	u16 status;
+	int end_command = 0;
+	int end_transfer = 0;
+	int transfer_error = 0;
+	int state_changed = 0;
+	int cmd_timeout = 0;
+
+	while ((status = GOLDFISH_MMC_READ(host, MMC_INT_STATUS)) != 0) {
+		GOLDFISH_MMC_WRITE(host, MMC_INT_STATUS, status);
+
+		if (status & MMC_STAT_END_OF_CMD)
+			end_command = 1;
+
+		if (status & MMC_STAT_END_OF_DATA)
+			end_transfer = 1;
+
+		if (status & MMC_STAT_STATE_CHANGE)
+			state_changed = 1;
+
+                if (status & MMC_STAT_CMD_TIMEOUT) {
+			end_command = 0;
+			cmd_timeout = 1;
+                }
+	}
+
+	if (cmd_timeout) {
+		struct mmc_request *mrq = host->mrq;
+		mrq->cmd->error = -ETIMEDOUT;
+		host->mrq = NULL;
+		mmc_request_done(host->mmc, mrq);
+	}
+
+	if (end_command)
+		goldfish_mmc_cmd_done(host, host->cmd);
+
+	if (transfer_error)
+		goldfish_mmc_xfer_done(host, host->data);
+	else if (end_transfer) {
+		host->dma_done = 1;
+		goldfish_mmc_end_of_data(host, host->data);
+	} else if (host->data != NULL) {
+		/*
+		 * WORKAROUND -- after porting this driver from 2.6 to 3.4,
+		 * during device initialization, cases where host->data is
+		 * non-null but end_transfer is false would occur. Doing
+		 * nothing in such cases results in no further interrupts,
+		 * and initialization failure.
+		 * TODO -- find the real cause.
+		 */
+		host->dma_done = 1;
+		goldfish_mmc_end_of_data(host, host->data);
+	}
+
+	if (state_changed) {
+		u32 state = GOLDFISH_MMC_READ(host, MMC_STATE);
+		pr_info("%s: Card detect now %d\n", __func__,
+			(state & MMC_STATE_INSERTED));
+		mmc_detect_change(host->mmc, 0);
+	}
+
+	if (!end_command && !end_transfer &&
+	    !transfer_error && !state_changed && !cmd_timeout) {
+		status = GOLDFISH_MMC_READ(host, MMC_INT_STATUS);
+		dev_info(mmc_dev(host->mmc),"spurious irq 0x%04x\n", status);
+		if (status != 0) {
+			GOLDFISH_MMC_WRITE(host, MMC_INT_STATUS, status);
+			GOLDFISH_MMC_WRITE(host, MMC_INT_ENABLE, 0);
+		}
+	}
+
+	return IRQ_HANDLED;
+}
+
+static void goldfish_mmc_prepare_data(struct goldfish_mmc_host *host,
+				      struct mmc_request *req)
+{
+	struct mmc_data *data = req->data;
+	int block_size;
+	unsigned sg_len;
+	enum dma_data_direction dma_data_dir;
+
+	host->data = data;
+	if (data == NULL) {
+		GOLDFISH_MMC_WRITE(host, MMC_BLOCK_LENGTH, 0);
+		GOLDFISH_MMC_WRITE(host, MMC_BLOCK_COUNT, 0);
+		host->dma_in_use = 0;
+		return;
+	}
+
+	block_size = data->blksz;
+
+	GOLDFISH_MMC_WRITE(host, MMC_BLOCK_COUNT, data->blocks - 1);
+	GOLDFISH_MMC_WRITE(host, MMC_BLOCK_LENGTH, block_size - 1);
+
+	/*
+	 * Cope with calling layer confusion; it issues "single
+	 * block" writes using multi-block scatterlists.
+	 */
+	sg_len = (data->blocks == 1) ? 1 : data->sg_len;
+
+	if (data->flags & MMC_DATA_WRITE)
+		dma_data_dir = DMA_TO_DEVICE;
+	else
+		dma_data_dir = DMA_FROM_DEVICE;
+
+	host->sg_len = dma_map_sg(mmc_dev(host->mmc), data->sg,
+				  sg_len, dma_data_dir);
+	host->dma_done = 0;
+	host->dma_in_use = 1;
+
+	if (dma_data_dir == DMA_TO_DEVICE) {
+		/*
+		 * We don't really have DMA, so we need to copy to our
+		 * platform driver buffer
+		 */
+		const uint8_t *src = (uint8_t *)sg_virt(data->sg);
+		memcpy(host->virt_base, src, data->sg->length);
+	}
+}
+
+static void goldfish_mmc_request(struct mmc_host *mmc, struct mmc_request *req)
+{
+	struct goldfish_mmc_host *host = mmc_priv(mmc);
+
+	WARN_ON(host->mrq != NULL);
+
+	host->mrq = req;
+	goldfish_mmc_prepare_data(host, req);
+	goldfish_mmc_start_command(host, req->cmd);
+
+	/*
+	 * This is to avoid accidentally being detected as an SDIO card
+	 * in mmc_attach_sdio().
+	 */
+	if (req->cmd->opcode == SD_IO_SEND_OP_COND &&
+	    req->cmd->flags == (MMC_RSP_SPI_R4 | MMC_RSP_R4 | MMC_CMD_BCR))
+		req->cmd->error = -EINVAL;
+}
+
+static void goldfish_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+{
+	struct goldfish_mmc_host *host = mmc_priv(mmc);
+
+	host->bus_mode = ios->bus_mode;
+	host->hw_bus_mode = host->bus_mode;
+}
+
+static int goldfish_mmc_get_ro(struct mmc_host *mmc)
+{
+	uint32_t state;
+	struct goldfish_mmc_host *host = mmc_priv(mmc);
+
+	state = GOLDFISH_MMC_READ(host, MMC_STATE);
+	return ((state & MMC_STATE_READ_ONLY) != 0);
+}
+
+static const struct mmc_host_ops goldfish_mmc_ops = {
+	.request	= goldfish_mmc_request,
+	.set_ios	= goldfish_mmc_set_ios,
+	.get_ro		= goldfish_mmc_get_ro,
+};
+
+static int goldfish_mmc_probe(struct platform_device *pdev)
+{
+	struct mmc_host *mmc;
+	struct goldfish_mmc_host *host = NULL;
+	struct resource *res;
+	int ret = 0;
+	int irq;
+	dma_addr_t buf_addr;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	irq = platform_get_irq(pdev, 0);
+	if (res == NULL || irq < 0)
+		return -ENXIO;
+
+	mmc = mmc_alloc_host(sizeof(struct goldfish_mmc_host), &pdev->dev);
+	if (mmc == NULL) {
+		ret = -ENOMEM;
+		goto err_alloc_host_failed;
+	}
+
+	host = mmc_priv(mmc);
+	host->mmc = mmc;
+
+	pr_err("mmc: Mapping %lX to %lX\n", (long)res->start, (long)res->end);
+	host->reg_base = ioremap(res->start, resource_size(res));
+	if (host->reg_base == NULL) {
+		ret = -ENOMEM;
+		goto ioremap_failed;
+	}
+	host->virt_base = dma_alloc_coherent(&pdev->dev, BUFFER_SIZE,
+					     &buf_addr, GFP_KERNEL);
+
+	if (host->virt_base == 0) {
+		ret = -ENOMEM;
+		goto dma_alloc_failed;
+	}
+	host->phys_base = buf_addr;
+
+	host->id = pdev->id;
+	host->irq = irq;
+
+	mmc->ops = &goldfish_mmc_ops;
+	mmc->f_min = 400000;
+	mmc->f_max = 24000000;
+	mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
+	mmc->caps = MMC_CAP_4_BIT_DATA;
+
+	/* Use scatterlist DMA to reduce per-transfer costs.
+	 * NOTE max_seg_size assumption that small blocks aren't
+	 * normally used (except e.g. for reading SD registers).
+	 */
+	mmc->max_segs = 32;
+	mmc->max_blk_size = 2048;	/* MMC_BLOCK_LENGTH is 11 bits (+1) */
+	mmc->max_blk_count = 2048;	/* MMC_BLOCK_COUNT is 11 bits (+1) */
+	mmc->max_req_size = BUFFER_SIZE;
+	mmc->max_seg_size = mmc->max_req_size;
+
+	ret = request_irq(host->irq, goldfish_mmc_irq, 0, DRIVER_NAME, host);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed IRQ Adding goldfish MMC\n");
+		goto err_request_irq_failed;
+	}
+
+	host->dev = &pdev->dev;
+	platform_set_drvdata(pdev, host);
+
+	ret = device_create_file(&pdev->dev, &dev_attr_cover_switch);
+	if (ret)
+		dev_warn(mmc_dev(host->mmc),
+			 "Unable to create sysfs attributes\n");
+
+	GOLDFISH_MMC_WRITE(host, MMC_SET_BUFFER, host->phys_base);
+	GOLDFISH_MMC_WRITE(host, MMC_INT_ENABLE,
+			   MMC_STAT_END_OF_CMD | MMC_STAT_END_OF_DATA |
+			   MMC_STAT_STATE_CHANGE | MMC_STAT_CMD_TIMEOUT);
+
+	mmc_add_host(mmc);
+	return 0;
+
+err_request_irq_failed:
+	dma_free_coherent(&pdev->dev, BUFFER_SIZE, host->virt_base,
+			  host->phys_base);
+dma_alloc_failed:
+	iounmap(host->reg_base);
+ioremap_failed:
+	mmc_free_host(host->mmc);
+err_alloc_host_failed:
+	return ret;
+}
+
+static int goldfish_mmc_remove(struct platform_device *pdev)
+{
+	struct goldfish_mmc_host *host = platform_get_drvdata(pdev);
+
+	platform_set_drvdata(pdev, NULL);
+
+	BUG_ON(host == NULL);
+
+	mmc_remove_host(host->mmc);
+	free_irq(host->irq, host);
+	dma_free_coherent(&pdev->dev, BUFFER_SIZE, host->virt_base, host->phys_base);
+	iounmap(host->reg_base);
+	mmc_free_host(host->mmc);
+	return 0;
+}
+
+static struct platform_driver goldfish_mmc_driver = {
+	.probe		= goldfish_mmc_probe,
+	.remove		= goldfish_mmc_remove,
+	.driver		= {
+		.name	= DRIVER_NAME,
+	},
+};
+
+module_platform_driver(goldfish_mmc_driver);
+MODULE_LICENSE("GPL v2");
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/at91_mci.c linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/at91_mci.c
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/at91_mci.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/at91_mci.c	1970-01-01 08:00:00.000000000 +0800
@@ -1,1219 +0,0 @@
-/*
- *  linux/drivers/mmc/host/at91_mci.c - ATMEL AT91 MCI Driver
- *
- *  Copyright (C) 2005 Cougar Creek Computing Devices Ltd, All Rights Reserved
- *
- *  Copyright (C) 2006 Malcolm Noyes
- *
- * 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 is the AT91 MCI driver that has been tested with both MMC cards
-   and SD-cards.  Boards that support write protect are now supported.
-   The CCAT91SBC001 board does not support SD cards.
-
-   The three entry points are at91_mci_request, at91_mci_set_ios
-   and at91_mci_get_ro.
-
-   SET IOS
-     This configures the device to put it into the correct mode and clock speed
-     required.
-
-   MCI REQUEST
-     MCI request processes the commands sent in the mmc_request structure. This
-     can consist of a processing command and a stop command in the case of
-     multiple block transfers.
-
-     There are three main types of request, commands, reads and writes.
-
-     Commands are straight forward. The command is submitted to the controller and
-     the request function returns. When the controller generates an interrupt to indicate
-     the command is finished, the response to the command are read and the mmc_request_done
-     function called to end the request.
-
-     Reads and writes work in a similar manner to normal commands but involve the PDC (DMA)
-     controller to manage the transfers.
-
-     A read is done from the controller directly to the scatterlist passed in from the request.
-     Due to a bug in the AT91RM9200 controller, when a read is completed, all the words are byte
-     swapped in the scatterlist buffers.  AT91SAM926x are not affected by this bug.
-
-     The sequence of read interrupts is: ENDRX, RXBUFF, CMDRDY
-
-     A write is slightly different in that the bytes to write are read from the scatterlist
-     into a dma memory buffer (this is in case the source buffer should be read only). The
-     entire write buffer is then done from this single dma memory buffer.
-
-     The sequence of write interrupts is: ENDTX, TXBUFE, NOTBUSY, CMDRDY
-
-   GET RO
-     Gets the status of the write protect pin, if available.
-*/
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/ioport.h>
-#include <linux/platform_device.h>
-#include <linux/interrupt.h>
-#include <linux/blkdev.h>
-#include <linux/delay.h>
-#include <linux/err.h>
-#include <linux/dma-mapping.h>
-#include <linux/clk.h>
-#include <linux/atmel_pdc.h>
-#include <linux/gfp.h>
-#include <linux/highmem.h>
-
-#include <linux/mmc/host.h>
-#include <linux/mmc/sdio.h>
-
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/gpio.h>
-
-#include <mach/board.h>
-#include <mach/cpu.h>
-
-#include "at91_mci.h"
-
-#define DRIVER_NAME "at91_mci"
-
-static inline int at91mci_is_mci1rev2xx(void)
-{
-	return (   cpu_is_at91sam9260()
-		|| cpu_is_at91sam9263()
-		|| cpu_is_at91sam9rl()
-		|| cpu_is_at91sam9g10()
-		|| cpu_is_at91sam9g20()
-		);
-}
-
-#define FL_SENT_COMMAND	(1 << 0)
-#define FL_SENT_STOP	(1 << 1)
-
-#define AT91_MCI_ERRORS	(AT91_MCI_RINDE | AT91_MCI_RDIRE | AT91_MCI_RCRCE	\
-		| AT91_MCI_RENDE | AT91_MCI_RTOE | AT91_MCI_DCRCE		\
-		| AT91_MCI_DTOE | AT91_MCI_OVRE | AT91_MCI_UNRE)
-
-#define at91_mci_read(host, reg)	__raw_readl((host)->baseaddr + (reg))
-#define at91_mci_write(host, reg, val)	__raw_writel((val), (host)->baseaddr + (reg))
-
-#define MCI_BLKSIZE 		512
-#define MCI_MAXBLKSIZE 		4095
-#define MCI_BLKATONCE 		256
-#define MCI_BUFSIZE 		(MCI_BLKSIZE * MCI_BLKATONCE)
-
-/*
- * Low level type for this driver
- */
-struct at91mci_host
-{
-	struct mmc_host *mmc;
-	struct mmc_command *cmd;
-	struct mmc_request *request;
-
-	void __iomem *baseaddr;
-	int irq;
-
-	struct at91_mmc_data *board;
-	int present;
-
-	struct clk *mci_clk;
-
-	/*
-	 * Flag indicating when the command has been sent. This is used to
-	 * work out whether or not to send the stop
-	 */
-	unsigned int flags;
-	/* flag for current bus settings */
-	u32 bus_mode;
-
-	/* DMA buffer used for transmitting */
-	unsigned int* buffer;
-	dma_addr_t physical_address;
-	unsigned int total_length;
-
-	/* Latest in the scatterlist that has been enabled for transfer, but not freed */
-	int in_use_index;
-
-	/* Latest in the scatterlist that has been enabled for transfer */
-	int transfer_index;
-
-	/* Timer for timeouts */
-	struct timer_list timer;
-};
-
-/*
- * Reset the controller and restore most of the state
- */
-static void at91_reset_host(struct at91mci_host *host)
-{
-	unsigned long flags;
-	u32 mr;
-	u32 sdcr;
-	u32 dtor;
-	u32 imr;
-
-	local_irq_save(flags);
-	imr = at91_mci_read(host, AT91_MCI_IMR);
-
-	at91_mci_write(host, AT91_MCI_IDR, 0xffffffff);
-
-	/* save current state */
-	mr = at91_mci_read(host, AT91_MCI_MR) & 0x7fff;
-	sdcr = at91_mci_read(host, AT91_MCI_SDCR);
-	dtor = at91_mci_read(host, AT91_MCI_DTOR);
-
-	/* reset the controller */
-	at91_mci_write(host, AT91_MCI_CR, AT91_MCI_MCIDIS | AT91_MCI_SWRST);
-
-	/* restore state */
-	at91_mci_write(host, AT91_MCI_CR, AT91_MCI_MCIEN);
-	at91_mci_write(host, AT91_MCI_MR, mr);
-	at91_mci_write(host, AT91_MCI_SDCR, sdcr);
-	at91_mci_write(host, AT91_MCI_DTOR, dtor);
-	at91_mci_write(host, AT91_MCI_IER, imr);
-
-	/* make sure sdio interrupts will fire */
-	at91_mci_read(host, AT91_MCI_SR);
-
-	local_irq_restore(flags);
-}
-
-static void at91_timeout_timer(unsigned long data)
-{
-	struct at91mci_host *host;
-
-	host = (struct at91mci_host *)data;
-
-	if (host->request) {
-		dev_err(host->mmc->parent, "Timeout waiting end of packet\n");
-
-		if (host->cmd && host->cmd->data) {
-			host->cmd->data->error = -ETIMEDOUT;
-		} else {
-			if (host->cmd)
-				host->cmd->error = -ETIMEDOUT;
-			else
-				host->request->cmd->error = -ETIMEDOUT;
-		}
-
-		at91_reset_host(host);
-		mmc_request_done(host->mmc, host->request);
-	}
-}
-
-/*
- * Copy from sg to a dma block - used for transfers
- */
-static inline void at91_mci_sg_to_dma(struct at91mci_host *host, struct mmc_data *data)
-{
-	unsigned int len, i, size;
-	unsigned *dmabuf = host->buffer;
-
-	size = data->blksz * data->blocks;
-	len = data->sg_len;
-
-	/* MCI1 rev2xx Data Write Operation and number of bytes erratum */
-	if (at91mci_is_mci1rev2xx())
-		if (host->total_length == 12)
-			memset(dmabuf, 0, 12);
-
-	/*
-	 * Just loop through all entries. Size might not
-	 * be the entire list though so make sure that
-	 * we do not transfer too much.
-	 */
-	for (i = 0; i < len; i++) {
-		struct scatterlist *sg;
-		int amount;
-		unsigned int *sgbuffer;
-
-		sg = &data->sg[i];
-
-		sgbuffer = kmap_atomic(sg_page(sg)) + sg->offset;
-		amount = min(size, sg->length);
-		size -= amount;
-
-		if (cpu_is_at91rm9200()) {	/* AT91RM9200 errata */
-			int index;
-
-			for (index = 0; index < (amount / 4); index++)
-				*dmabuf++ = swab32(sgbuffer[index]);
-		} else {
-			char *tmpv = (char *)dmabuf;
-			memcpy(tmpv, sgbuffer, amount);
-			tmpv += amount;
-			dmabuf = (unsigned *)tmpv;
-		}
-
-		kunmap_atomic(sgbuffer);
-
-		if (size == 0)
-			break;
-	}
-
-	/*
-	 * Check that we didn't get a request to transfer
-	 * more data than can fit into the SG list.
-	 */
-	BUG_ON(size != 0);
-}
-
-/*
- * Handle after a dma read
- */
-static void at91_mci_post_dma_read(struct at91mci_host *host)
-{
-	struct mmc_command *cmd;
-	struct mmc_data *data;
-	unsigned int len, i, size;
-	unsigned *dmabuf = host->buffer;
-
-	pr_debug("post dma read\n");
-
-	cmd = host->cmd;
-	if (!cmd) {
-		pr_debug("no command\n");
-		return;
-	}
-
-	data = cmd->data;
-	if (!data) {
-		pr_debug("no data\n");
-		return;
-	}
-
-	size = data->blksz * data->blocks;
-	len = data->sg_len;
-
-	at91_mci_write(host, AT91_MCI_IDR, AT91_MCI_ENDRX);
-	at91_mci_write(host, AT91_MCI_IER, AT91_MCI_RXBUFF);
-
-	for (i = 0; i < len; i++) {
-		struct scatterlist *sg;
-		int amount;
-		unsigned int *sgbuffer;
-
-		sg = &data->sg[i];
-
-		sgbuffer = kmap_atomic(sg_page(sg)) + sg->offset;
-		amount = min(size, sg->length);
-		size -= amount;
-
-		if (cpu_is_at91rm9200()) {	/* AT91RM9200 errata */
-			int index;
-			for (index = 0; index < (amount / 4); index++)
-				sgbuffer[index] = swab32(*dmabuf++);
-		} else {
-			char *tmpv = (char *)dmabuf;
-			memcpy(sgbuffer, tmpv, amount);
-			tmpv += amount;
-			dmabuf = (unsigned *)tmpv;
-		}
-
-		flush_kernel_dcache_page(sg_page(sg));
-		kunmap_atomic(sgbuffer);
-		data->bytes_xfered += amount;
-		if (size == 0)
-			break;
-	}
-
-	pr_debug("post dma read done\n");
-}
-
-/*
- * Handle transmitted data
- */
-static void at91_mci_handle_transmitted(struct at91mci_host *host)
-{
-	struct mmc_command *cmd;
-	struct mmc_data *data;
-
-	pr_debug("Handling the transmit\n");
-
-	/* Disable the transfer */
-	at91_mci_write(host, ATMEL_PDC_PTCR, ATMEL_PDC_RXTDIS | ATMEL_PDC_TXTDIS);
-
-	/* Now wait for cmd ready */
-	at91_mci_write(host, AT91_MCI_IDR, AT91_MCI_TXBUFE);
-
-	cmd = host->cmd;
-	if (!cmd) return;
-
-	data = cmd->data;
-	if (!data) return;
-
-	if (cmd->data->blocks > 1) {
-		pr_debug("multiple write : wait for BLKE...\n");
-		at91_mci_write(host, AT91_MCI_IER, AT91_MCI_BLKE);
-	} else
-		at91_mci_write(host, AT91_MCI_IER, AT91_MCI_NOTBUSY);
-}
-
-/*
- * Update bytes tranfered count during a write operation
- */
-static void at91_mci_update_bytes_xfered(struct at91mci_host *host)
-{
-	struct mmc_data *data;
-
-	/* always deal with the effective request (and not the current cmd) */
-
-	if (host->request->cmd && host->request->cmd->error != 0)
-		return;
-
-	if (host->request->data) {
-		data = host->request->data;
-		if (data->flags & MMC_DATA_WRITE) {
-			/* card is in IDLE mode now */
-			pr_debug("-> bytes_xfered %d, total_length = %d\n",
-				data->bytes_xfered, host->total_length);
-			data->bytes_xfered = data->blksz * data->blocks;
-		}
-	}
-}
-
-
-/*Handle after command sent ready*/
-static int at91_mci_handle_cmdrdy(struct at91mci_host *host)
-{
-	if (!host->cmd)
-		return 1;
-	else if (!host->cmd->data) {
-		if (host->flags & FL_SENT_STOP) {
-			/*After multi block write, we must wait for NOTBUSY*/
-			at91_mci_write(host, AT91_MCI_IER, AT91_MCI_NOTBUSY);
-		} else return 1;
-	} else if (host->cmd->data->flags & MMC_DATA_WRITE) {
-		/*After sendding multi-block-write command, start DMA transfer*/
-		at91_mci_write(host, AT91_MCI_IER, AT91_MCI_TXBUFE | AT91_MCI_BLKE);
-		at91_mci_write(host, ATMEL_PDC_PTCR, ATMEL_PDC_TXTEN);
-	}
-
-	/* command not completed, have to wait */
-	return 0;
-}
-
-
-/*
- * Enable the controller
- */
-static void at91_mci_enable(struct at91mci_host *host)
-{
-	unsigned int mr;
-
-	at91_mci_write(host, AT91_MCI_CR, AT91_MCI_MCIEN);
-	at91_mci_write(host, AT91_MCI_IDR, 0xffffffff);
-	at91_mci_write(host, AT91_MCI_DTOR, AT91_MCI_DTOMUL_1M | AT91_MCI_DTOCYC);
-	mr = AT91_MCI_PDCMODE | 0x34a;
-
-	if (at91mci_is_mci1rev2xx())
-		mr |= AT91_MCI_RDPROOF | AT91_MCI_WRPROOF;
-
-	at91_mci_write(host, AT91_MCI_MR, mr);
-
-	/* use Slot A or B (only one at same time) */
-	at91_mci_write(host, AT91_MCI_SDCR, host->board->slot_b);
-}
-
-/*
- * Disable the controller
- */
-static void at91_mci_disable(struct at91mci_host *host)
-{
-	at91_mci_write(host, AT91_MCI_CR, AT91_MCI_MCIDIS | AT91_MCI_SWRST);
-}
-
-/*
- * Send a command
- */
-static void at91_mci_send_command(struct at91mci_host *host, struct mmc_command *cmd)
-{
-	unsigned int cmdr, mr;
-	unsigned int block_length;
-	struct mmc_data *data = cmd->data;
-
-	unsigned int blocks;
-	unsigned int ier = 0;
-
-	host->cmd = cmd;
-
-	/* Needed for leaving busy state before CMD1 */
-	if ((at91_mci_read(host, AT91_MCI_SR) & AT91_MCI_RTOE) && (cmd->opcode == 1)) {
-		pr_debug("Clearing timeout\n");
-		at91_mci_write(host, AT91_MCI_ARGR, 0);
-		at91_mci_write(host, AT91_MCI_CMDR, AT91_MCI_OPDCMD);
-		while (!(at91_mci_read(host, AT91_MCI_SR) & AT91_MCI_CMDRDY)) {
-			/* spin */
-			pr_debug("Clearing: SR = %08X\n", at91_mci_read(host, AT91_MCI_SR));
-		}
-	}
-
-	cmdr = cmd->opcode;
-
-	if (mmc_resp_type(cmd) == MMC_RSP_NONE)
-		cmdr |= AT91_MCI_RSPTYP_NONE;
-	else {
-		/* if a response is expected then allow maximum response latancy */
-		cmdr |= AT91_MCI_MAXLAT;
-		/* set 136 bit response for R2, 48 bit response otherwise */
-		if (mmc_resp_type(cmd) == MMC_RSP_R2)
-			cmdr |= AT91_MCI_RSPTYP_136;
-		else
-			cmdr |= AT91_MCI_RSPTYP_48;
-	}
-
-	if (data) {
-
-		if (cpu_is_at91rm9200() || cpu_is_at91sam9261()) {
-			if (data->blksz & 0x3) {
-				pr_debug("Unsupported block size\n");
-				cmd->error = -EINVAL;
-				mmc_request_done(host->mmc, host->request);
-				return;
-			}
-			if (data->flags & MMC_DATA_STREAM) {
-				pr_debug("Stream commands not supported\n");
-				cmd->error = -EINVAL;
-				mmc_request_done(host->mmc, host->request);
-				return;
-			}
-		}
-
-		block_length = data->blksz;
-		blocks = data->blocks;
-
-		/* always set data start - also set direction flag for read */
-		if (data->flags & MMC_DATA_READ)
-			cmdr |= (AT91_MCI_TRDIR | AT91_MCI_TRCMD_START);
-		else if (data->flags & MMC_DATA_WRITE)
-			cmdr |= AT91_MCI_TRCMD_START;
-
-		if (cmd->opcode == SD_IO_RW_EXTENDED) {
-			cmdr |= AT91_MCI_TRTYP_SDIO_BLOCK;
-		} else {
-			if (data->flags & MMC_DATA_STREAM)
-				cmdr |= AT91_MCI_TRTYP_STREAM;
-			if (data->blocks > 1)
-				cmdr |= AT91_MCI_TRTYP_MULTIPLE;
-		}
-	}
-	else {
-		block_length = 0;
-		blocks = 0;
-	}
-
-	if (host->flags & FL_SENT_STOP)
-		cmdr |= AT91_MCI_TRCMD_STOP;
-
-	if (host->bus_mode == MMC_BUSMODE_OPENDRAIN)
-		cmdr |= AT91_MCI_OPDCMD;
-
-	/*
-	 * Set the arguments and send the command
-	 */
-	pr_debug("Sending command %d as %08X, arg = %08X, blocks = %d, length = %d (MR = %08X)\n",
-		cmd->opcode, cmdr, cmd->arg, blocks, block_length, at91_mci_read(host, AT91_MCI_MR));
-
-	if (!data) {
-		at91_mci_write(host, ATMEL_PDC_PTCR, ATMEL_PDC_TXTDIS | ATMEL_PDC_RXTDIS);
-		at91_mci_write(host, ATMEL_PDC_RPR, 0);
-		at91_mci_write(host, ATMEL_PDC_RCR, 0);
-		at91_mci_write(host, ATMEL_PDC_RNPR, 0);
-		at91_mci_write(host, ATMEL_PDC_RNCR, 0);
-		at91_mci_write(host, ATMEL_PDC_TPR, 0);
-		at91_mci_write(host, ATMEL_PDC_TCR, 0);
-		at91_mci_write(host, ATMEL_PDC_TNPR, 0);
-		at91_mci_write(host, ATMEL_PDC_TNCR, 0);
-		ier = AT91_MCI_CMDRDY;
-	} else {
-		/* zero block length and PDC mode */
-		mr = at91_mci_read(host, AT91_MCI_MR) & 0x5fff;
-		mr |= (data->blksz & 0x3) ? AT91_MCI_PDCFBYTE : 0;
-		mr |= (block_length << 16);
-		mr |= AT91_MCI_PDCMODE;
-		at91_mci_write(host, AT91_MCI_MR, mr);
-
-		if (!(cpu_is_at91rm9200() || cpu_is_at91sam9261()))
-			at91_mci_write(host, AT91_MCI_BLKR,
-				AT91_MCI_BLKR_BCNT(blocks) |
-				AT91_MCI_BLKR_BLKLEN(block_length));
-
-		/*
-		 * Disable the PDC controller
-		 */
-		at91_mci_write(host, ATMEL_PDC_PTCR, ATMEL_PDC_RXTDIS | ATMEL_PDC_TXTDIS);
-
-		if (cmdr & AT91_MCI_TRCMD_START) {
-			data->bytes_xfered = 0;
-			host->transfer_index = 0;
-			host->in_use_index = 0;
-			if (cmdr & AT91_MCI_TRDIR) {
-				/*
-				 * Handle a read
-				 */
-				host->total_length = 0;
-
-				at91_mci_write(host, ATMEL_PDC_RPR, host->physical_address);
-				at91_mci_write(host, ATMEL_PDC_RCR, (data->blksz & 0x3) ?
-					(blocks * block_length) : (blocks * block_length) / 4);
-				at91_mci_write(host, ATMEL_PDC_RNPR, 0);
-				at91_mci_write(host, ATMEL_PDC_RNCR, 0);
-
-				ier = AT91_MCI_ENDRX /* | AT91_MCI_RXBUFF */;
-			}
-			else {
-				/*
-				 * Handle a write
-				 */
-				host->total_length = block_length * blocks;
-				/*
-				 * MCI1 rev2xx Data Write Operation and
-				 * number of bytes erratum
-				 */
-				if (at91mci_is_mci1rev2xx())
-					if (host->total_length < 12)
-						host->total_length = 12;
-
-				at91_mci_sg_to_dma(host, data);
-
-				pr_debug("Transmitting %d bytes\n", host->total_length);
-
-				at91_mci_write(host, ATMEL_PDC_TPR, host->physical_address);
-				at91_mci_write(host, ATMEL_PDC_TCR, (data->blksz & 0x3) ?
-						host->total_length : host->total_length / 4);
-
-				ier = AT91_MCI_CMDRDY;
-			}
-		}
-	}
-
-	/*
-	 * Send the command and then enable the PDC - not the other way round as
-	 * the data sheet says
-	 */
-
-	at91_mci_write(host, AT91_MCI_ARGR, cmd->arg);
-	at91_mci_write(host, AT91_MCI_CMDR, cmdr);
-
-	if (cmdr & AT91_MCI_TRCMD_START) {
-		if (cmdr & AT91_MCI_TRDIR)
-			at91_mci_write(host, ATMEL_PDC_PTCR, ATMEL_PDC_RXTEN);
-	}
-
-	/* Enable selected interrupts */
-	at91_mci_write(host, AT91_MCI_IER, AT91_MCI_ERRORS | ier);
-}
-
-/*
- * Process the next step in the request
- */
-static void at91_mci_process_next(struct at91mci_host *host)
-{
-	if (!(host->flags & FL_SENT_COMMAND)) {
-		host->flags |= FL_SENT_COMMAND;
-		at91_mci_send_command(host, host->request->cmd);
-	}
-	else if ((!(host->flags & FL_SENT_STOP)) && host->request->stop) {
-		host->flags |= FL_SENT_STOP;
-		at91_mci_send_command(host, host->request->stop);
-	} else {
-		del_timer(&host->timer);
-		/* the at91rm9200 mci controller hangs after some transfers,
-		 * and the workaround is to reset it after each transfer.
-		 */
-		if (cpu_is_at91rm9200())
-			at91_reset_host(host);
-		mmc_request_done(host->mmc, host->request);
-	}
-}
-
-/*
- * Handle a command that has been completed
- */
-static void at91_mci_completed_command(struct at91mci_host *host, unsigned int status)
-{
-	struct mmc_command *cmd = host->cmd;
-	struct mmc_data *data = cmd->data;
-
-	at91_mci_write(host, AT91_MCI_IDR, 0xffffffff & ~(AT91_MCI_SDIOIRQA | AT91_MCI_SDIOIRQB));
-
-	cmd->resp[0] = at91_mci_read(host, AT91_MCI_RSPR(0));
-	cmd->resp[1] = at91_mci_read(host, AT91_MCI_RSPR(1));
-	cmd->resp[2] = at91_mci_read(host, AT91_MCI_RSPR(2));
-	cmd->resp[3] = at91_mci_read(host, AT91_MCI_RSPR(3));
-
-	pr_debug("Status = %08X/%08x [%08X %08X %08X %08X]\n",
-		 status, at91_mci_read(host, AT91_MCI_SR),
-		 cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3]);
-
-	if (status & AT91_MCI_ERRORS) {
-		if ((status & AT91_MCI_RCRCE) && !(mmc_resp_type(cmd) & MMC_RSP_CRC)) {
-			cmd->error = 0;
-		}
-		else {
-			if (status & (AT91_MCI_DTOE | AT91_MCI_DCRCE)) {
-				if (data) {
-					if (status & AT91_MCI_DTOE)
-						data->error = -ETIMEDOUT;
-					else if (status & AT91_MCI_DCRCE)
-						data->error = -EILSEQ;
-				}
-			} else {
-				if (status & AT91_MCI_RTOE)
-					cmd->error = -ETIMEDOUT;
-				else if (status & AT91_MCI_RCRCE)
-					cmd->error = -EILSEQ;
-				else
-					cmd->error = -EIO;
-			}
-
-			pr_debug("Error detected and set to %d/%d (cmd = %d, retries = %d)\n",
-				cmd->error, data ? data->error : 0,
-				 cmd->opcode, cmd->retries);
-		}
-	}
-	else
-		cmd->error = 0;
-
-	at91_mci_process_next(host);
-}
-
-/*
- * Handle an MMC request
- */
-static void at91_mci_request(struct mmc_host *mmc, struct mmc_request *mrq)
-{
-	struct at91mci_host *host = mmc_priv(mmc);
-	host->request = mrq;
-	host->flags = 0;
-
-	/* more than 1s timeout needed with slow SD cards */
-	mod_timer(&host->timer, jiffies +  msecs_to_jiffies(2000));
-
-	at91_mci_process_next(host);
-}
-
-/*
- * Set the IOS
- */
-static void at91_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
-{
-	int clkdiv;
-	struct at91mci_host *host = mmc_priv(mmc);
-	unsigned long at91_master_clock = clk_get_rate(host->mci_clk);
-
-	host->bus_mode = ios->bus_mode;
-
-	if (ios->clock == 0) {
-		/* Disable the MCI controller */
-		at91_mci_write(host, AT91_MCI_CR, AT91_MCI_MCIDIS);
-		clkdiv = 0;
-	}
-	else {
-		/* Enable the MCI controller */
-		at91_mci_write(host, AT91_MCI_CR, AT91_MCI_MCIEN);
-
-		if ((at91_master_clock % (ios->clock * 2)) == 0)
-			clkdiv = ((at91_master_clock / ios->clock) / 2) - 1;
-		else
-			clkdiv = (at91_master_clock / ios->clock) / 2;
-
-		pr_debug("clkdiv = %d. mcck = %ld\n", clkdiv,
-			at91_master_clock / (2 * (clkdiv + 1)));
-	}
-	if (ios->bus_width == MMC_BUS_WIDTH_4 && host->board->wire4) {
-		pr_debug("MMC: Setting controller bus width to 4\n");
-		at91_mci_write(host, AT91_MCI_SDCR, at91_mci_read(host, AT91_MCI_SDCR) | AT91_MCI_SDCBUS);
-	}
-	else {
-		pr_debug("MMC: Setting controller bus width to 1\n");
-		at91_mci_write(host, AT91_MCI_SDCR, at91_mci_read(host, AT91_MCI_SDCR) & ~AT91_MCI_SDCBUS);
-	}
-
-	/* Set the clock divider */
-	at91_mci_write(host, AT91_MCI_MR, (at91_mci_read(host, AT91_MCI_MR) & ~AT91_MCI_CLKDIV) | clkdiv);
-
-	/* maybe switch power to the card */
-	if (gpio_is_valid(host->board->vcc_pin)) {
-		switch (ios->power_mode) {
-			case MMC_POWER_OFF:
-				gpio_set_value(host->board->vcc_pin, 0);
-				break;
-			case MMC_POWER_UP:
-				gpio_set_value(host->board->vcc_pin, 1);
-				break;
-			case MMC_POWER_ON:
-				break;
-			default:
-				WARN_ON(1);
-		}
-	}
-}
-
-/*
- * Handle an interrupt
- */
-static irqreturn_t at91_mci_irq(int irq, void *devid)
-{
-	struct at91mci_host *host = devid;
-	int completed = 0;
-	unsigned int int_status, int_mask;
-
-	int_status = at91_mci_read(host, AT91_MCI_SR);
-	int_mask = at91_mci_read(host, AT91_MCI_IMR);
-
-	pr_debug("MCI irq: status = %08X, %08X, %08X\n", int_status, int_mask,
-		int_status & int_mask);
-
-	int_status = int_status & int_mask;
-
-	if (int_status & AT91_MCI_ERRORS) {
-		completed = 1;
-
-		if (int_status & AT91_MCI_UNRE)
-			pr_debug("MMC: Underrun error\n");
-		if (int_status & AT91_MCI_OVRE)
-			pr_debug("MMC: Overrun error\n");
-		if (int_status & AT91_MCI_DTOE)
-			pr_debug("MMC: Data timeout\n");
-		if (int_status & AT91_MCI_DCRCE)
-			pr_debug("MMC: CRC error in data\n");
-		if (int_status & AT91_MCI_RTOE)
-			pr_debug("MMC: Response timeout\n");
-		if (int_status & AT91_MCI_RENDE)
-			pr_debug("MMC: Response end bit error\n");
-		if (int_status & AT91_MCI_RCRCE)
-			pr_debug("MMC: Response CRC error\n");
-		if (int_status & AT91_MCI_RDIRE)
-			pr_debug("MMC: Response direction error\n");
-		if (int_status & AT91_MCI_RINDE)
-			pr_debug("MMC: Response index error\n");
-	} else {
-		/* Only continue processing if no errors */
-
-		if (int_status & AT91_MCI_TXBUFE) {
-			pr_debug("TX buffer empty\n");
-			at91_mci_handle_transmitted(host);
-		}
-
-		if (int_status & AT91_MCI_ENDRX) {
-			pr_debug("ENDRX\n");
-			at91_mci_post_dma_read(host);
-		}
-
-		if (int_status & AT91_MCI_RXBUFF) {
-			pr_debug("RX buffer full\n");
-			at91_mci_write(host, ATMEL_PDC_PTCR, ATMEL_PDC_RXTDIS | ATMEL_PDC_TXTDIS);
-			at91_mci_write(host, AT91_MCI_IDR, AT91_MCI_RXBUFF | AT91_MCI_ENDRX);
-			completed = 1;
-		}
-
-		if (int_status & AT91_MCI_ENDTX)
-			pr_debug("Transmit has ended\n");
-
-		if (int_status & AT91_MCI_NOTBUSY) {
-			pr_debug("Card is ready\n");
-			at91_mci_update_bytes_xfered(host);
-			completed = 1;
-		}
-
-		if (int_status & AT91_MCI_DTIP)
-			pr_debug("Data transfer in progress\n");
-
-		if (int_status & AT91_MCI_BLKE) {
-			pr_debug("Block transfer has ended\n");
-			if (host->request->data && host->request->data->blocks > 1) {
-				/* multi block write : complete multi write
-				 * command and send stop */
-				completed = 1;
-			} else {
-				at91_mci_write(host, AT91_MCI_IER, AT91_MCI_NOTBUSY);
-			}
-		}
-
-		if (int_status & AT91_MCI_SDIOIRQA)
-			mmc_signal_sdio_irq(host->mmc);
-
-		if (int_status & AT91_MCI_SDIOIRQB)
-			mmc_signal_sdio_irq(host->mmc);
-
-		if (int_status & AT91_MCI_TXRDY)
-			pr_debug("Ready to transmit\n");
-
-		if (int_status & AT91_MCI_RXRDY)
-			pr_debug("Ready to receive\n");
-
-		if (int_status & AT91_MCI_CMDRDY) {
-			pr_debug("Command ready\n");
-			completed = at91_mci_handle_cmdrdy(host);
-		}
-	}
-
-	if (completed) {
-		pr_debug("Completed command\n");
-		at91_mci_write(host, AT91_MCI_IDR, 0xffffffff & ~(AT91_MCI_SDIOIRQA | AT91_MCI_SDIOIRQB));
-		at91_mci_completed_command(host, int_status);
-	} else
-		at91_mci_write(host, AT91_MCI_IDR, int_status & ~(AT91_MCI_SDIOIRQA | AT91_MCI_SDIOIRQB));
-
-	return IRQ_HANDLED;
-}
-
-static irqreturn_t at91_mmc_det_irq(int irq, void *_host)
-{
-	struct at91mci_host *host = _host;
-	int present;
-
-	/* entering this ISR means that we have configured det_pin:
-	 * we can use its value in board structure */
-	present = !gpio_get_value(host->board->det_pin);
-
-	/*
-	 * we expect this irq on both insert and remove,
-	 * and use a short delay to debounce.
-	 */
-	if (present != host->present) {
-		host->present = present;
-		pr_debug("%s: card %s\n", mmc_hostname(host->mmc),
-			present ? "insert" : "remove");
-		if (!present) {
-			pr_debug("****** Resetting SD-card bus width ******\n");
-			at91_mci_write(host, AT91_MCI_SDCR, at91_mci_read(host, AT91_MCI_SDCR) & ~AT91_MCI_SDCBUS);
-		}
-		/* 0.5s needed because of early card detect switch firing */
-		mmc_detect_change(host->mmc, msecs_to_jiffies(500));
-	}
-	return IRQ_HANDLED;
-}
-
-static int at91_mci_get_ro(struct mmc_host *mmc)
-{
-	struct at91mci_host *host = mmc_priv(mmc);
-
-	if (gpio_is_valid(host->board->wp_pin))
-		return !!gpio_get_value(host->board->wp_pin);
-	/*
-	 * Board doesn't support read only detection; let the mmc core
-	 * decide what to do.
-	 */
-	return -ENOSYS;
-}
-
-static void at91_mci_enable_sdio_irq(struct mmc_host *mmc, int enable)
-{
-	struct at91mci_host *host = mmc_priv(mmc);
-
-	pr_debug("%s: sdio_irq %c : %s\n", mmc_hostname(host->mmc),
-		host->board->slot_b ? 'B':'A', enable ? "enable" : "disable");
-	at91_mci_write(host, enable ? AT91_MCI_IER : AT91_MCI_IDR,
-		host->board->slot_b ? AT91_MCI_SDIOIRQB : AT91_MCI_SDIOIRQA);
-
-}
-
-static const struct mmc_host_ops at91_mci_ops = {
-	.request	= at91_mci_request,
-	.set_ios	= at91_mci_set_ios,
-	.get_ro		= at91_mci_get_ro,
-	.enable_sdio_irq = at91_mci_enable_sdio_irq,
-};
-
-/*
- * Probe for the device
- */
-static int __init at91_mci_probe(struct platform_device *pdev)
-{
-	struct mmc_host *mmc;
-	struct at91mci_host *host;
-	struct resource *res;
-	int ret;
-
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!res)
-		return -ENXIO;
-
-	if (!request_mem_region(res->start, resource_size(res), DRIVER_NAME))
-		return -EBUSY;
-
-	mmc = mmc_alloc_host(sizeof(struct at91mci_host), &pdev->dev);
-	if (!mmc) {
-		ret = -ENOMEM;
-		dev_dbg(&pdev->dev, "couldn't allocate mmc host\n");
-		goto fail6;
-	}
-
-	mmc->ops = &at91_mci_ops;
-	mmc->f_min = 375000;
-	mmc->f_max = 25000000;
-	mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
-	mmc->caps = 0;
-
-	mmc->max_blk_size  = MCI_MAXBLKSIZE;
-	mmc->max_blk_count = MCI_BLKATONCE;
-	mmc->max_req_size  = MCI_BUFSIZE;
-	mmc->max_segs      = MCI_BLKATONCE;
-	mmc->max_seg_size  = MCI_BUFSIZE;
-
-	host = mmc_priv(mmc);
-	host->mmc = mmc;
-	host->bus_mode = 0;
-	host->board = pdev->dev.platform_data;
-	if (host->board->wire4) {
-		if (at91mci_is_mci1rev2xx())
-			mmc->caps |= MMC_CAP_4_BIT_DATA;
-		else
-			dev_warn(&pdev->dev, "4 wire bus mode not supported"
-				" - using 1 wire\n");
-	}
-
-	host->buffer = dma_alloc_coherent(&pdev->dev, MCI_BUFSIZE,
-					&host->physical_address, GFP_KERNEL);
-	if (!host->buffer) {
-		ret = -ENOMEM;
-		dev_err(&pdev->dev, "Can't allocate transmit buffer\n");
-		goto fail5;
-	}
-
-	/* Add SDIO capability when available */
-	if (at91mci_is_mci1rev2xx()) {
-		/* at91mci MCI1 rev2xx sdio interrupt erratum */
-		if (host->board->wire4 || !host->board->slot_b)
-			mmc->caps |= MMC_CAP_SDIO_IRQ;
-	}
-
-	/*
-	 * Reserve GPIOs ... board init code makes sure these pins are set
-	 * up as GPIOs with the right direction (input, except for vcc)
-	 */
-	if (gpio_is_valid(host->board->det_pin)) {
-		ret = gpio_request(host->board->det_pin, "mmc_detect");
-		if (ret < 0) {
-			dev_dbg(&pdev->dev, "couldn't claim card detect pin\n");
-			goto fail4b;
-		}
-	}
-	if (gpio_is_valid(host->board->wp_pin)) {
-		ret = gpio_request(host->board->wp_pin, "mmc_wp");
-		if (ret < 0) {
-			dev_dbg(&pdev->dev, "couldn't claim wp sense pin\n");
-			goto fail4;
-		}
-	}
-	if (gpio_is_valid(host->board->vcc_pin)) {
-		ret = gpio_request(host->board->vcc_pin, "mmc_vcc");
-		if (ret < 0) {
-			dev_dbg(&pdev->dev, "couldn't claim vcc switch pin\n");
-			goto fail3;
-		}
-	}
-
-	/*
-	 * Get Clock
-	 */
-	host->mci_clk = clk_get(&pdev->dev, "mci_clk");
-	if (IS_ERR(host->mci_clk)) {
-		ret = -ENODEV;
-		dev_dbg(&pdev->dev, "no mci_clk?\n");
-		goto fail2;
-	}
-
-	/*
-	 * Map I/O region
-	 */
-	host->baseaddr = ioremap(res->start, resource_size(res));
-	if (!host->baseaddr) {
-		ret = -ENOMEM;
-		goto fail1;
-	}
-
-	/*
-	 * Reset hardware
-	 */
-	clk_enable(host->mci_clk);		/* Enable the peripheral clock */
-	at91_mci_disable(host);
-	at91_mci_enable(host);
-
-	/*
-	 * Allocate the MCI interrupt
-	 */
-	host->irq = platform_get_irq(pdev, 0);
-	ret = request_irq(host->irq, at91_mci_irq, IRQF_SHARED,
-			mmc_hostname(mmc), host);
-	if (ret) {
-		dev_dbg(&pdev->dev, "request MCI interrupt failed\n");
-		goto fail0;
-	}
-
-	setup_timer(&host->timer, at91_timeout_timer, (unsigned long)host);
-
-	platform_set_drvdata(pdev, mmc);
-
-	/*
-	 * Add host to MMC layer
-	 */
-	if (gpio_is_valid(host->board->det_pin)) {
-		host->present = !gpio_get_value(host->board->det_pin);
-	}
-	else
-		host->present = -1;
-
-	mmc_add_host(mmc);
-
-	/*
-	 * monitor card insertion/removal if we can
-	 */
-	if (gpio_is_valid(host->board->det_pin)) {
-		ret = request_irq(gpio_to_irq(host->board->det_pin),
-				at91_mmc_det_irq, 0, mmc_hostname(mmc), host);
-		if (ret)
-			dev_warn(&pdev->dev, "request MMC detect irq failed\n");
-		else
-			device_init_wakeup(&pdev->dev, 1);
-	}
-
-	pr_debug("Added MCI driver\n");
-
-	return 0;
-
-fail0:
-	clk_disable(host->mci_clk);
-	iounmap(host->baseaddr);
-fail1:
-	clk_put(host->mci_clk);
-fail2:
-	if (gpio_is_valid(host->board->vcc_pin))
-		gpio_free(host->board->vcc_pin);
-fail3:
-	if (gpio_is_valid(host->board->wp_pin))
-		gpio_free(host->board->wp_pin);
-fail4:
-	if (gpio_is_valid(host->board->det_pin))
-		gpio_free(host->board->det_pin);
-fail4b:
-	if (host->buffer)
-		dma_free_coherent(&pdev->dev, MCI_BUFSIZE,
-				host->buffer, host->physical_address);
-fail5:
-	mmc_free_host(mmc);
-fail6:
-	release_mem_region(res->start, resource_size(res));
-	dev_err(&pdev->dev, "probe failed, err %d\n", ret);
-	return ret;
-}
-
-/*
- * Remove a device
- */
-static int __exit at91_mci_remove(struct platform_device *pdev)
-{
-	struct mmc_host *mmc = platform_get_drvdata(pdev);
-	struct at91mci_host *host;
-	struct resource *res;
-
-	if (!mmc)
-		return -1;
-
-	host = mmc_priv(mmc);
-
-	if (host->buffer)
-		dma_free_coherent(&pdev->dev, MCI_BUFSIZE,
-				host->buffer, host->physical_address);
-
-	if (gpio_is_valid(host->board->det_pin)) {
-		if (device_can_wakeup(&pdev->dev))
-			free_irq(gpio_to_irq(host->board->det_pin), host);
-		device_init_wakeup(&pdev->dev, 0);
-		gpio_free(host->board->det_pin);
-	}
-
-	at91_mci_disable(host);
-	del_timer_sync(&host->timer);
-	mmc_remove_host(mmc);
-	free_irq(host->irq, host);
-
-	clk_disable(host->mci_clk);			/* Disable the peripheral clock */
-	clk_put(host->mci_clk);
-
-	if (gpio_is_valid(host->board->vcc_pin))
-		gpio_free(host->board->vcc_pin);
-	if (gpio_is_valid(host->board->wp_pin))
-		gpio_free(host->board->wp_pin);
-
-	iounmap(host->baseaddr);
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	release_mem_region(res->start, resource_size(res));
-
-	mmc_free_host(mmc);
-	platform_set_drvdata(pdev, NULL);
-	pr_debug("MCI Removed\n");
-
-	return 0;
-}
-
-#ifdef CONFIG_PM
-static int at91_mci_suspend(struct platform_device *pdev, pm_message_t state)
-{
-	struct mmc_host *mmc = platform_get_drvdata(pdev);
-	struct at91mci_host *host = mmc_priv(mmc);
-	int ret = 0;
-
-	if (gpio_is_valid(host->board->det_pin) && device_may_wakeup(&pdev->dev))
-		enable_irq_wake(host->board->det_pin);
-
-	if (mmc)
-		ret = mmc_suspend_host(mmc);
-
-	return ret;
-}
-
-static int at91_mci_resume(struct platform_device *pdev)
-{
-	struct mmc_host *mmc = platform_get_drvdata(pdev);
-	struct at91mci_host *host = mmc_priv(mmc);
-	int ret = 0;
-
-	if (gpio_is_valid(host->board->det_pin) && device_may_wakeup(&pdev->dev))
-		disable_irq_wake(host->board->det_pin);
-
-	if (mmc)
-		ret = mmc_resume_host(mmc);
-
-	return ret;
-}
-#else
-#define at91_mci_suspend	NULL
-#define at91_mci_resume		NULL
-#endif
-
-static struct platform_driver at91_mci_driver = {
-	.remove		= __exit_p(at91_mci_remove),
-	.suspend	= at91_mci_suspend,
-	.resume		= at91_mci_resume,
-	.driver		= {
-		.name	= DRIVER_NAME,
-		.owner	= THIS_MODULE,
-	},
-};
-
-static int __init at91_mci_init(void)
-{
-	return platform_driver_probe(&at91_mci_driver, at91_mci_probe);
-}
-
-static void __exit at91_mci_exit(void)
-{
-	platform_driver_unregister(&at91_mci_driver);
-}
-
-module_init(at91_mci_init);
-module_exit(at91_mci_exit);
-
-MODULE_DESCRIPTION("AT91 Multimedia Card Interface driver");
-MODULE_AUTHOR("Nick Randell");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:at91_mci");
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/at91_mci.h linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/at91_mci.h
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/at91_mci.h	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/at91_mci.h	1970-01-01 08:00:00.000000000 +0800
@@ -1,115 +0,0 @@
-/*
- * drivers/mmc/host/at91_mci.h
- *
- * Copyright (C) 2005 Ivan Kokshaysky
- * Copyright (C) SAN People
- *
- * MultiMedia Card Interface (MCI) registers.
- * Based on AT91RM9200 datasheet revision F.
- *
- * 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 AT91_MCI_H
-#define AT91_MCI_H
-
-#define AT91_MCI_CR		0x00		/* Control Register */
-#define		AT91_MCI_MCIEN		(1 <<  0)	/* Multi-Media Interface Enable */
-#define		AT91_MCI_MCIDIS		(1 <<  1)	/* Multi-Media Interface Disable */
-#define		AT91_MCI_PWSEN		(1 <<  2)	/* Power Save Mode Enable */
-#define		AT91_MCI_PWSDIS		(1 <<  3)	/* Power Save Mode Disable */
-#define		AT91_MCI_SWRST		(1 <<  7)	/* Software Reset */
-
-#define AT91_MCI_MR		0x04		/* Mode Register */
-#define		AT91_MCI_CLKDIV		(0xff  <<  0)	/* Clock Divider */
-#define		AT91_MCI_PWSDIV		(7     <<  8)	/* Power Saving Divider */
-#define		AT91_MCI_RDPROOF	(1     << 11)	/* Read Proof Enable [SAM926[03] only] */
-#define		AT91_MCI_WRPROOF	(1     << 12)	/* Write Proof Enable [SAM926[03] only] */
-#define		AT91_MCI_PDCFBYTE	(1     << 13)	/* PDC Force Byte Transfer [SAM926[03] only] */
-#define		AT91_MCI_PDCPADV	(1     << 14)	/* PDC Padding Value */
-#define		AT91_MCI_PDCMODE	(1     << 15)	/* PDC-orientated Mode */
-#define		AT91_MCI_BLKLEN		(0xfff << 18)	/* Data Block Length */
-
-#define AT91_MCI_DTOR		0x08		/* Data Timeout Register */
-#define		AT91_MCI_DTOCYC		(0xf << 0)	/* Data Timeout Cycle Number */
-#define		AT91_MCI_DTOMUL		(7   << 4)	/* Data Timeout Multiplier */
-#define		AT91_MCI_DTOMUL_1		(0 <<  4)
-#define		AT91_MCI_DTOMUL_16		(1 <<  4)
-#define		AT91_MCI_DTOMUL_128		(2 <<  4)
-#define		AT91_MCI_DTOMUL_256		(3 <<  4)
-#define		AT91_MCI_DTOMUL_1K		(4 <<  4)
-#define		AT91_MCI_DTOMUL_4K		(5 <<  4)
-#define		AT91_MCI_DTOMUL_64K		(6 <<  4)
-#define		AT91_MCI_DTOMUL_1M		(7 <<  4)
-
-#define AT91_MCI_SDCR		0x0c		/* SD Card Register */
-#define		AT91_MCI_SDCSEL		(3 << 0)	/* SD Card Selector */
-#define		AT91_MCI_SDCBUS		(1 << 7)	/* 1-bit or 4-bit bus */
-
-#define AT91_MCI_ARGR		0x10		/* Argument Register */
-
-#define AT91_MCI_CMDR		0x14		/* Command Register */
-#define		AT91_MCI_CMDNB		(0x3f << 0)	/* Command Number */
-#define		AT91_MCI_RSPTYP		(3    << 6)	/* Response Type */
-#define			AT91_MCI_RSPTYP_NONE	(0 <<  6)
-#define			AT91_MCI_RSPTYP_48	(1 <<  6)
-#define			AT91_MCI_RSPTYP_136	(2 <<  6)
-#define		AT91_MCI_SPCMD		(7    << 8)	/* Special Command */
-#define			AT91_MCI_SPCMD_NONE	(0 <<  8)
-#define			AT91_MCI_SPCMD_INIT	(1 <<  8)
-#define			AT91_MCI_SPCMD_SYNC	(2 <<  8)
-#define			AT91_MCI_SPCMD_ICMD	(4 <<  8)
-#define			AT91_MCI_SPCMD_IRESP	(5 <<  8)
-#define		AT91_MCI_OPDCMD		(1 << 11)	/* Open Drain Command */
-#define		AT91_MCI_MAXLAT		(1 << 12)	/* Max Latency for Command to Response */
-#define		AT91_MCI_TRCMD		(3 << 16)	/* Transfer Command */
-#define			AT91_MCI_TRCMD_NONE	(0 << 16)
-#define			AT91_MCI_TRCMD_START	(1 << 16)
-#define			AT91_MCI_TRCMD_STOP	(2 << 16)
-#define		AT91_MCI_TRDIR		(1 << 18)	/* Transfer Direction */
-#define		AT91_MCI_TRTYP		(3 << 19)	/* Transfer Type */
-#define			AT91_MCI_TRTYP_BLOCK	(0 << 19)
-#define			AT91_MCI_TRTYP_MULTIPLE	(1 << 19)
-#define			AT91_MCI_TRTYP_STREAM	(2 << 19)
-#define			AT91_MCI_TRTYP_SDIO_BYTE	(4 << 19)
-#define			AT91_MCI_TRTYP_SDIO_BLOCK	(5 << 19)
-
-#define AT91_MCI_BLKR		0x18		/* Block Register */
-#define		AT91_MCI_BLKR_BCNT(n)	((0xffff & (n)) << 0)	/* Block count */
-#define		AT91_MCI_BLKR_BLKLEN(n)	((0xffff & (n)) << 16)	/* Block length */
-
-#define AT91_MCI_RSPR(n)	(0x20 + ((n) * 4))	/* Response Registers 0-3 */
-#define AT91_MCR_RDR		0x30		/* Receive Data Register */
-#define AT91_MCR_TDR		0x34		/* Transmit Data Register */
-
-#define AT91_MCI_SR		0x40		/* Status Register */
-#define		AT91_MCI_CMDRDY		(1 <<  0)	/* Command Ready */
-#define		AT91_MCI_RXRDY		(1 <<  1)	/* Receiver Ready */
-#define		AT91_MCI_TXRDY		(1 <<  2)	/* Transmit Ready */
-#define		AT91_MCI_BLKE		(1 <<  3)	/* Data Block Ended */
-#define		AT91_MCI_DTIP		(1 <<  4)	/* Data Transfer in Progress */
-#define		AT91_MCI_NOTBUSY	(1 <<  5)	/* Data Not Busy */
-#define		AT91_MCI_ENDRX		(1 <<  6)	/* End of RX Buffer */
-#define		AT91_MCI_ENDTX		(1 <<  7)	/* End fo TX Buffer */
-#define		AT91_MCI_SDIOIRQA	(1 <<  8)	/* SDIO Interrupt for Slot A */
-#define		AT91_MCI_SDIOIRQB	(1 <<  9)	/* SDIO Interrupt for Slot B */
-#define		AT91_MCI_RXBUFF		(1 << 14)	/* RX Buffer Full */
-#define		AT91_MCI_TXBUFE		(1 << 15)	/* TX Buffer Empty */
-#define		AT91_MCI_RINDE		(1 << 16)	/* Response Index Error */
-#define		AT91_MCI_RDIRE		(1 << 17)	/* Response Direction Error */
-#define		AT91_MCI_RCRCE		(1 << 18)	/* Response CRC Error */
-#define		AT91_MCI_RENDE		(1 << 19)	/* Response End Bit Error */
-#define		AT91_MCI_RTOE		(1 << 20)	/* Response Time-out Error */
-#define		AT91_MCI_DCRCE		(1 << 21)	/* Data CRC Error */
-#define		AT91_MCI_DTOE		(1 << 22)	/* Data Time-out Error */
-#define		AT91_MCI_OVRE		(1 << 30)	/* Overrun */
-#define		AT91_MCI_UNRE		(1 << 31)	/* Underrun */
-
-#define AT91_MCI_IER		0x44		/* Interrupt Enable Register */
-#define AT91_MCI_IDR		0x48		/* Interrupt Disable Register */
-#define AT91_MCI_IMR		0x4c		/* Interrupt Mask Register */
-
-#endif
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/atmel-mci.c linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/atmel-mci.c
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/atmel-mci.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/atmel-mci.c	2014-09-12 15:59:37.348052000 +0800
@@ -19,12 +19,16 @@
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
 #include <linux/platform_device.h>
 #include <linux/scatterlist.h>
 #include <linux/seq_file.h>
 #include <linux/slab.h>
 #include <linux/stat.h>
 #include <linux/types.h>
+#include <linux/platform_data/atmel.h>
 
 #include <linux/mmc/host.h>
 #include <linux/mmc/sdio.h>
@@ -37,7 +41,6 @@
 #include <asm/unaligned.h>
 
 #include <mach/cpu.h>
-#include <mach/board.h>
 
 #include "atmel-mci-regs.h"
 
@@ -45,19 +48,19 @@
 #define ATMCI_DMA_THRESHOLD	16
 
 enum {
-	EVENT_CMD_COMPLETE = 0,
+	EVENT_CMD_RDY = 0,
 	EVENT_XFER_COMPLETE,
-	EVENT_DATA_COMPLETE,
+	EVENT_NOTBUSY,
 	EVENT_DATA_ERROR,
 };
 
 enum atmel_mci_state {
 	STATE_IDLE = 0,
 	STATE_SENDING_CMD,
-	STATE_SENDING_DATA,
-	STATE_DATA_BUSY,
+	STATE_DATA_XFER,
+	STATE_WAITING_NOTBUSY,
 	STATE_SENDING_STOP,
-	STATE_DATA_ERROR,
+	STATE_END_REQUEST,
 };
 
 enum atmci_xfer_dir {
@@ -71,13 +74,17 @@
 };
 
 struct atmel_mci_caps {
-	bool    has_dma;
+	bool    has_dma_conf_reg;
 	bool    has_pdc;
 	bool    has_cfg_reg;
 	bool    has_cstor_reg;
 	bool    has_highspeed;
 	bool    has_rwproof;
 	bool	has_odd_clk_div;
+	bool	has_bad_data_ordering;
+	bool	need_reset_after_xfer;
+	bool	need_blksz_mul_4;
+	bool	need_notbusy_for_read_ops;
 };
 
 struct atmel_mci_dma {
@@ -91,6 +98,11 @@
  * @regs: Pointer to MMIO registers.
  * @sg: Scatterlist entry currently being processed by PIO or PDC code.
  * @pio_offset: Offset into the current scatterlist entry.
+ * @buffer: Buffer used if we don't have the r/w proof capability. We
+ *      don't have the time to switch pdc buffers so we have to use only
+ *      one buffer for the full transaction.
+ * @buf_size: size of the buffer.
+ * @phys_buf_addr: buffer address needed for pdc.
  * @cur_slot: The slot which is currently using the controller.
  * @mrq: The request currently being processed on @cur_slot,
  *	or NULL if the controller is idle.
@@ -116,6 +128,7 @@
  * @queue: List of slots waiting for access to the controller.
  * @need_clock_update: Update the clock rate before the next request.
  * @need_reset: Reset controller before next request.
+ * @timer: Timer to balance the data timeout error flag which cannot rise.
  * @mode_reg: Value of the MR register.
  * @cfg_reg: Value of the CFG register.
  * @bus_hz: The rate of @mck in Hz. This forms the basis for MMC bus
@@ -165,7 +178,11 @@
 	void __iomem		*regs;
 
 	struct scatterlist	*sg;
+	unsigned int		sg_len;
 	unsigned int		pio_offset;
+	unsigned int		*buffer;
+	unsigned int		buf_size;
+	dma_addr_t		buf_phys_addr;
 
 	struct atmel_mci_slot	*cur_slot;
 	struct mmc_request	*mrq;
@@ -189,6 +206,7 @@
 
 	bool			need_clock_update;
 	bool			need_reset;
+	struct timer_list	timer;
 	u32			mode_reg;
 	u32			cfg_reg;
 	unsigned long		bus_hz;
@@ -378,11 +396,17 @@
 	clk_disable(host->mck);
 	spin_unlock_bh(&host->lock);
 
-	seq_printf(s, "MR:\t0x%08x%s%s CLKDIV=%u\n",
+	seq_printf(s, "MR:\t0x%08x%s%s ",
 			buf[ATMCI_MR / 4],
 			buf[ATMCI_MR / 4] & ATMCI_MR_RDPROOF ? " RDPROOF" : "",
-			buf[ATMCI_MR / 4] & ATMCI_MR_WRPROOF ? " WRPROOF" : "",
-			buf[ATMCI_MR / 4] & 0xff);
+			buf[ATMCI_MR / 4] & ATMCI_MR_WRPROOF ? " WRPROOF" : "");
+	if (host->caps.has_odd_clk_div)
+		seq_printf(s, "{CLKDIV,CLKODD}=%u\n",
+				((buf[ATMCI_MR / 4] & 0xff) << 1)
+				| ((buf[ATMCI_MR / 4] >> 16) & 1));
+	else
+		seq_printf(s, "CLKDIV=%u\n",
+				(buf[ATMCI_MR / 4] & 0xff));
 	seq_printf(s, "DTOR:\t0x%08x\n", buf[ATMCI_DTOR / 4]);
 	seq_printf(s, "SDCR:\t0x%08x\n", buf[ATMCI_SDCR / 4]);
 	seq_printf(s, "ARGR:\t0x%08x\n", buf[ATMCI_ARGR / 4]);
@@ -398,7 +422,7 @@
 	atmci_show_status_reg(s, "SR", buf[ATMCI_SR / 4]);
 	atmci_show_status_reg(s, "IMR", buf[ATMCI_IMR / 4]);
 
-	if (host->caps.has_dma) {
+	if (host->caps.has_dma_conf_reg) {
 		u32 val;
 
 		val = buf[ATMCI_DMA / 4];
@@ -480,6 +504,103 @@
 	dev_err(&mmc->class_dev, "failed to initialize debugfs for slot\n");
 }
 
+#if defined(CONFIG_OF)
+static const struct of_device_id atmci_dt_ids[] = {
+	{ .compatible = "atmel,hsmci" },
+	{ /* sentinel */ }
+};
+
+MODULE_DEVICE_TABLE(of, atmci_dt_ids);
+
+static struct mci_platform_data*
+atmci_of_init(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct device_node *cnp;
+	struct mci_platform_data *pdata;
+	u32 slot_id;
+
+	if (!np) {
+		dev_err(&pdev->dev, "device node not found\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+	if (!pdata) {
+		dev_err(&pdev->dev, "could not allocate memory for pdata\n");
+		return ERR_PTR(-ENOMEM);
+	}
+
+	for_each_child_of_node(np, cnp) {
+		if (of_property_read_u32(cnp, "reg", &slot_id)) {
+			dev_warn(&pdev->dev, "reg property is missing for %s\n",
+				 cnp->full_name);
+			continue;
+		}
+
+		if (slot_id >= ATMCI_MAX_NR_SLOTS) {
+			dev_warn(&pdev->dev, "can't have more than %d slots\n",
+			         ATMCI_MAX_NR_SLOTS);
+			break;
+		}
+
+		if (of_property_read_u32(cnp, "bus-width",
+		                         &pdata->slot[slot_id].bus_width))
+			pdata->slot[slot_id].bus_width = 1;
+
+		pdata->slot[slot_id].detect_pin =
+			of_get_named_gpio(cnp, "cd-gpios", 0);
+
+		pdata->slot[slot_id].detect_is_active_high =
+			of_property_read_bool(cnp, "cd-inverted");
+
+		pdata->slot[slot_id].wp_pin =
+			of_get_named_gpio(cnp, "wp-gpios", 0);
+	}
+
+	return pdata;
+}
+#else /* CONFIG_OF */
+static inline struct mci_platform_data*
+atmci_of_init(struct platform_device *dev)
+{
+	return ERR_PTR(-EINVAL);
+}
+#endif
+
+static inline unsigned int atmci_get_version(struct atmel_mci *host)
+{
+	return atmci_readl(host, ATMCI_VERSION) & 0x00000fff;
+}
+
+static void atmci_timeout_timer(unsigned long data)
+{
+	struct atmel_mci *host;
+
+	host = (struct atmel_mci *)data;
+
+	dev_dbg(&host->pdev->dev, "software timeout\n");
+
+	if (host->mrq->cmd->data) {
+		host->mrq->cmd->data->error = -ETIMEDOUT;
+		host->data = NULL;
+		/*
+		 * With some SDIO modules, sometimes DMA transfer hangs. If
+		 * stop_transfer() is not called then the DMA request is not
+		 * removed, following ones are queued and never computed.
+		 */
+		if (host->state == STATE_DATA_XFER)
+			host->stop_transfer(host);
+	} else {
+		host->mrq->cmd->error = -ETIMEDOUT;
+		host->cmd = NULL;
+	}
+	host->need_reset = 1;
+	host->state = STATE_END_REQUEST;
+	smp_wmb();
+	tasklet_schedule(&host->tasklet);
+}
+
 static inline unsigned int atmci_ns_to_clocks(struct atmel_mci *host,
 					unsigned int ns)
 {
@@ -591,6 +712,7 @@
 
 static void atmci_send_stop_cmd(struct atmel_mci *host, struct mmc_data *data)
 {
+	dev_dbg(&host->pdev->dev, "send stop command\n");
 	atmci_send_command(host, data->stop, host->stop_cmdr);
 	atmci_writel(host, ATMCI_IER, ATMCI_CMDRDY);
 }
@@ -603,6 +725,7 @@
 	enum atmci_xfer_dir dir, enum atmci_pdc_buf buf_nb)
 {
 	u32 pointer_reg, counter_reg;
+	unsigned int buf_size;
 
 	if (dir == XFER_RECEIVE) {
 		pointer_reg = ATMEL_PDC_RPR;
@@ -617,8 +740,15 @@
 		counter_reg += ATMEL_PDC_SCND_BUF_OFF;
 	}
 
-	atmci_writel(host, pointer_reg, sg_dma_address(host->sg));
-	if (host->data_size <= sg_dma_len(host->sg)) {
+	if (!host->caps.has_rwproof) {
+		buf_size = host->buf_size;
+		atmci_writel(host, pointer_reg, host->buf_phys_addr);
+	} else {
+		buf_size = sg_dma_len(host->sg);
+		atmci_writel(host, pointer_reg, sg_dma_address(host->sg));
+	}
+
+	if (host->data_size <= buf_size) {
 		if (host->data_size & 0x3) {
 			/* If size is different from modulo 4, transfer bytes */
 			atmci_writel(host, counter_reg, host->data_size);
@@ -670,7 +800,20 @@
  */
 static void atmci_pdc_complete(struct atmel_mci *host)
 {
+	int transfer_size = host->data->blocks * host->data->blksz;
+	int i;
+
 	atmci_writel(host, ATMEL_PDC_PTCR, ATMEL_PDC_RXTDIS | ATMEL_PDC_TXTDIS);
+
+	if ((!host->caps.has_rwproof)
+	    && (host->data->flags & MMC_DATA_READ)) {
+		if (host->caps.has_bad_data_ordering)
+			for (i = 0; i < transfer_size; i++)
+				host->buffer[i] = swab32(host->buffer[i]);
+		sg_copy_from_buffer(host->data->sg, host->data->sg_len,
+		                    host->buffer, transfer_size);
+	}
+
 	atmci_pdc_cleanup(host);
 
 	/*
@@ -678,9 +821,10 @@
 	 * to send the stop command or waiting for NBUSY in this case.
 	 */
 	if (host->data) {
+		dev_dbg(&host->pdev->dev,
+		        "(%s) set pending xfer complete\n", __func__);
 		atmci_set_pending(host, EVENT_XFER_COMPLETE);
 		tasklet_schedule(&host->tasklet);
-		atmci_writel(host, ATMCI_IER, ATMCI_NOTBUSY);
 	}
 }
 
@@ -705,7 +849,7 @@
 
 	dev_vdbg(&host->pdev->dev, "DMA complete\n");
 
-	if (host->caps.has_dma)
+	if (host->caps.has_dma_conf_reg)
 		/* Disable DMA hardware handshaking on MCI */
 		atmci_writel(host, ATMCI_DMA, atmci_readl(host, ATMCI_DMA) & ~ATMCI_DMAEN);
 
@@ -716,6 +860,8 @@
 	 * to send the stop command or waiting for NBUSY in this case.
 	 */
 	if (data) {
+		dev_dbg(&host->pdev->dev,
+		        "(%s) set pending xfer complete\n", __func__);
 		atmci_set_pending(host, EVENT_XFER_COMPLETE);
 		tasklet_schedule(&host->tasklet);
 
@@ -754,6 +900,7 @@
 	data->error = -EINPROGRESS;
 
 	host->sg = data->sg;
+	host->sg_len = data->sg_len;
 	host->data = data;
 	host->data_chan = NULL;
 
@@ -791,6 +938,7 @@
 	u32 iflags, tmp;
 	unsigned int sg_len;
 	enum dma_data_direction dir;
+	int i;
 
 	data->error = -EINPROGRESS;
 
@@ -806,7 +954,7 @@
 		iflags |= ATMCI_ENDRX | ATMCI_RXBUFF;
 	} else {
 		dir = DMA_TO_DEVICE;
-		iflags |= ATMCI_ENDTX | ATMCI_TXBUFE;
+		iflags |= ATMCI_ENDTX | ATMCI_TXBUFE | ATMCI_BLKE;
 	}
 
 	/* Set BLKLEN */
@@ -818,6 +966,16 @@
 	/* Configure PDC */
 	host->data_size = data->blocks * data->blksz;
 	sg_len = dma_map_sg(&host->pdev->dev, data->sg, data->sg_len, dir);
+
+	if ((!host->caps.has_rwproof)
+	    && (host->data->flags & MMC_DATA_WRITE)) {
+		sg_copy_to_buffer(host->data->sg, host->data->sg_len,
+		                  host->buffer, host->data_size);
+		if (host->caps.has_bad_data_ordering)
+			for (i = 0; i < host->data_size; i++)
+				host->buffer[i] = swab32(host->buffer[i]);
+	}
+
 	if (host->data_size)
 		atmci_pdc_set_both_buf(host,
 			((dir == DMA_FROM_DEVICE) ? XFER_RECEIVE : XFER_TRANSMIT));
@@ -835,6 +993,7 @@
 	enum dma_data_direction		direction;
 	enum dma_transfer_direction	slave_dirn;
 	unsigned int			sglen;
+	u32				maxburst;
 	u32 iflags;
 
 	data->error = -EINPROGRESS;
@@ -868,17 +1027,20 @@
 	if (!chan)
 		return -ENODEV;
 
-	if (host->caps.has_dma)
-		atmci_writel(host, ATMCI_DMA, ATMCI_DMA_CHKSIZE(3) | ATMCI_DMAEN);
-
 	if (data->flags & MMC_DATA_READ) {
 		direction = DMA_FROM_DEVICE;
 		host->dma_conf.direction = slave_dirn = DMA_DEV_TO_MEM;
+		maxburst = atmci_convert_chksize(host->dma_conf.src_maxburst);
 	} else {
 		direction = DMA_TO_DEVICE;
 		host->dma_conf.direction = slave_dirn = DMA_MEM_TO_DEV;
+		maxburst = atmci_convert_chksize(host->dma_conf.dst_maxburst);
 	}
 
+	if (host->caps.has_dma_conf_reg)
+		atmci_writel(host, ATMCI_DMA, ATMCI_DMA_CHKSIZE(maxburst) |
+			ATMCI_DMAEN);
+
 	sglen = dma_map_sg(chan->device->dev, data->sg,
 			data->sg_len, direction);
 
@@ -931,17 +1093,18 @@
 
 static void atmci_stop_transfer(struct atmel_mci *host)
 {
+	dev_dbg(&host->pdev->dev,
+	        "(%s) set pending xfer complete\n", __func__);
 	atmci_set_pending(host, EVENT_XFER_COMPLETE);
 	atmci_writel(host, ATMCI_IER, ATMCI_NOTBUSY);
 }
 
 /*
- * Stop data transfer because error(s) occured.
+ * Stop data transfer because error(s) occurred.
  */
 static void atmci_stop_transfer_pdc(struct atmel_mci *host)
 {
-	atmci_set_pending(host, EVENT_XFER_COMPLETE);
-	atmci_writel(host, ATMCI_IER, ATMCI_NOTBUSY);
+	atmci_writel(host, ATMEL_PDC_PTCR, ATMEL_PDC_RXTDIS | ATMEL_PDC_TXTDIS);
 }
 
 static void atmci_stop_transfer_dma(struct atmel_mci *host)
@@ -953,6 +1116,8 @@
 		atmci_dma_cleanup(host);
 	} else {
 		/* Data transfer was stopped by the interrupt handler */
+		dev_dbg(&host->pdev->dev,
+		        "(%s) set pending xfer complete\n", __func__);
 		atmci_set_pending(host, EVENT_XFER_COMPLETE);
 		atmci_writel(host, ATMCI_IER, ATMCI_NOTBUSY);
 	}
@@ -977,9 +1142,12 @@
 
 	host->pending_events = 0;
 	host->completed_events = 0;
+	host->cmd_status = 0;
 	host->data_status = 0;
 
-	if (host->need_reset) {
+	dev_dbg(&host->pdev->dev, "start request: cmd %u\n", mrq->cmd->opcode);
+
+	if (host->need_reset || host->caps.need_reset_after_xfer) {
 		iflags = atmci_readl(host, ATMCI_IMR);
 		iflags &= (ATMCI_SDIOIRQA | ATMCI_SDIOIRQB);
 		atmci_writel(host, ATMCI_CR, ATMCI_CR_SWRST);
@@ -994,7 +1162,7 @@
 
 	iflags = atmci_readl(host, ATMCI_IMR);
 	if (iflags & ~(ATMCI_SDIOIRQA | ATMCI_SDIOIRQB))
-		dev_warn(&slot->mmc->class_dev, "WARNING: IMR=0x%08x\n",
+		dev_dbg(&slot->mmc->class_dev, "WARNING: IMR=0x%08x\n",
 				iflags);
 
 	if (unlikely(test_and_clear_bit(ATMCI_CARD_NEED_INIT, &slot->flags))) {
@@ -1020,11 +1188,22 @@
 	iflags |= ATMCI_CMDRDY;
 	cmd = mrq->cmd;
 	cmdflags = atmci_prepare_command(slot->mmc, cmd);
-	atmci_send_command(host, cmd, cmdflags);
+
+	/*
+	 * DMA transfer should be started before sending the command to avoid
+	 * unexpected errors especially for read operations in SDIO mode.
+	 * Unfortunately, in PDC mode, command has to be sent before starting
+	 * the transfer.
+	 */
+	if (host->submit_data != &atmci_submit_data_dma)
+		atmci_send_command(host, cmd, cmdflags);
 
 	if (data)
 		host->submit_data(host, data);
 
+	if (host->submit_data == &atmci_submit_data_dma)
+		atmci_send_command(host, cmd, cmdflags);
+
 	if (mrq->stop) {
 		host->stop_cmdr = atmci_prepare_command(slot->mmc, mrq->stop);
 		host->stop_cmdr |= ATMCI_CMDR_STOP_XFER;
@@ -1043,6 +1222,8 @@
 	 * prepared yet.)
 	 */
 	atmci_writel(host, ATMCI_IER, iflags);
+
+	mod_timer(&host->timer, jiffies +  msecs_to_jiffies(2000));
 }
 
 static void atmci_queue_request(struct atmel_mci *host,
@@ -1057,6 +1238,7 @@
 		host->state = STATE_SENDING_CMD;
 		atmci_start_request(host, slot);
 	} else {
+		dev_dbg(&host->pdev->dev, "queue request\n");
 		list_add_tail(&slot->queue_node, &host->queue);
 	}
 	spin_unlock_bh(&host->lock);
@@ -1069,6 +1251,7 @@
 	struct mmc_data		*data;
 
 	WARN_ON(slot->mrq);
+	dev_dbg(&host->pdev->dev, "MRQ: cmd %u\n", mrq->cmd->opcode);
 
 	/*
 	 * We may "know" the card is gone even though there's still an
@@ -1308,6 +1491,8 @@
 		host->state = STATE_IDLE;
 	}
 
+	del_timer(&host->timer);
+
 	spin_unlock(&host->lock);
 	mmc_request_done(prev_mmc, mrq);
 	spin_lock(&host->lock);
@@ -1330,21 +1515,13 @@
 		cmd->error = -EILSEQ;
 	else if (status & (ATMCI_RINDE | ATMCI_RDIRE | ATMCI_RENDE))
 		cmd->error = -EIO;
-	else
-		cmd->error = 0;
-
-	if (cmd->error) {
-		dev_dbg(&host->pdev->dev,
-			"command error: status=0x%08x\n", status);
-
-		if (cmd->data) {
-			host->stop_transfer(host);
-			host->data = NULL;
-			atmci_writel(host, ATMCI_IDR, ATMCI_NOTBUSY
-					| ATMCI_TXRDY | ATMCI_RXRDY
-					| ATMCI_DATA_ERROR_FLAGS);
+	else if (host->mrq->data && (host->mrq->data->blksz & 3)) {
+		if (host->caps.need_blksz_mul_4) {
+			cmd->error = -EINVAL;
+			host->need_reset = 1;
 		}
-	}
+	} else
+		cmd->error = 0;
 }
 
 static void atmci_detect_change(unsigned long data)
@@ -1407,23 +1584,21 @@
 					break;
 				case STATE_SENDING_CMD:
 					mrq->cmd->error = -ENOMEDIUM;
-					if (!mrq->data)
-						break;
-					/* fall through */
-				case STATE_SENDING_DATA:
+					if (mrq->data)
+						host->stop_transfer(host);
+					break;
+				case STATE_DATA_XFER:
 					mrq->data->error = -ENOMEDIUM;
 					host->stop_transfer(host);
 					break;
-				case STATE_DATA_BUSY:
-				case STATE_DATA_ERROR:
-					if (mrq->data->error == -EINPROGRESS)
-						mrq->data->error = -ENOMEDIUM;
-					if (!mrq->stop)
-						break;
-					/* fall through */
+				case STATE_WAITING_NOTBUSY:
+					mrq->data->error = -ENOMEDIUM;
+					break;
 				case STATE_SENDING_STOP:
 					mrq->stop->error = -ENOMEDIUM;
 					break;
+				case STATE_END_REQUEST:
+					break;
 				}
 
 				atmci_request_end(host, mrq);
@@ -1451,7 +1626,6 @@
 	struct atmel_mci	*host = (struct atmel_mci *)priv;
 	struct mmc_request	*mrq = host->mrq;
 	struct mmc_data		*data = host->data;
-	struct mmc_command	*cmd = host->cmd;
 	enum atmel_mci_state	state = host->state;
 	enum atmel_mci_state	prev_state;
 	u32			status;
@@ -1467,107 +1641,189 @@
 
 	do {
 		prev_state = state;
+		dev_dbg(&host->pdev->dev, "FSM: state=%d\n", state);
 
 		switch (state) {
 		case STATE_IDLE:
 			break;
 
 		case STATE_SENDING_CMD:
+			/*
+			 * Command has been sent, we are waiting for command
+			 * ready. Then we have three next states possible:
+			 * END_REQUEST by default, WAITING_NOTBUSY if it's a
+			 * command needing it or DATA_XFER if there is data.
+			 */
+			dev_dbg(&host->pdev->dev, "FSM: cmd ready?\n");
 			if (!atmci_test_and_clear_pending(host,
-						EVENT_CMD_COMPLETE))
+						EVENT_CMD_RDY))
 				break;
 
+			dev_dbg(&host->pdev->dev, "set completed cmd ready\n");
 			host->cmd = NULL;
-			atmci_set_completed(host, EVENT_CMD_COMPLETE);
+			atmci_set_completed(host, EVENT_CMD_RDY);
 			atmci_command_complete(host, mrq->cmd);
-			if (!mrq->data || cmd->error) {
-				atmci_request_end(host, host->mrq);
-				goto unlock;
-			}
+			if (mrq->data) {
+				dev_dbg(&host->pdev->dev,
+				        "command with data transfer");
+				/*
+				 * If there is a command error don't start
+				 * data transfer.
+				 */
+				if (mrq->cmd->error) {
+					host->stop_transfer(host);
+					host->data = NULL;
+					atmci_writel(host, ATMCI_IDR,
+					             ATMCI_TXRDY | ATMCI_RXRDY
+					             | ATMCI_DATA_ERROR_FLAGS);
+					state = STATE_END_REQUEST;
+				} else
+					state = STATE_DATA_XFER;
+			} else if ((!mrq->data) && (mrq->cmd->flags & MMC_RSP_BUSY)) {
+				dev_dbg(&host->pdev->dev,
+				        "command response need waiting notbusy");
+				atmci_writel(host, ATMCI_IER, ATMCI_NOTBUSY);
+				state = STATE_WAITING_NOTBUSY;
+			} else
+				state = STATE_END_REQUEST;
 
-			prev_state = state = STATE_SENDING_DATA;
-			/* fall through */
+			break;
 
-		case STATE_SENDING_DATA:
+		case STATE_DATA_XFER:
 			if (atmci_test_and_clear_pending(host,
 						EVENT_DATA_ERROR)) {
-				host->stop_transfer(host);
-				if (data->stop)
-					atmci_send_stop_cmd(host, data);
-				state = STATE_DATA_ERROR;
+				dev_dbg(&host->pdev->dev, "set completed data error\n");
+				atmci_set_completed(host, EVENT_DATA_ERROR);
+				state = STATE_END_REQUEST;
 				break;
 			}
 
+			/*
+			 * A data transfer is in progress. The event expected
+			 * to move to the next state depends of data transfer
+			 * type (PDC or DMA). Once transfer done we can move
+			 * to the next step which is WAITING_NOTBUSY in write
+			 * case and directly SENDING_STOP in read case.
+			 */
+			dev_dbg(&host->pdev->dev, "FSM: xfer complete?\n");
 			if (!atmci_test_and_clear_pending(host,
 						EVENT_XFER_COMPLETE))
 				break;
 
+			dev_dbg(&host->pdev->dev,
+			        "(%s) set completed xfer complete\n",
+				__func__);
 			atmci_set_completed(host, EVENT_XFER_COMPLETE);
-			prev_state = state = STATE_DATA_BUSY;
-			/* fall through */
-
-		case STATE_DATA_BUSY:
-			if (!atmci_test_and_clear_pending(host,
-						EVENT_DATA_COMPLETE))
-				break;
 
-			host->data = NULL;
-			atmci_set_completed(host, EVENT_DATA_COMPLETE);
-			status = host->data_status;
-			if (unlikely(status & ATMCI_DATA_ERROR_FLAGS)) {
-				if (status & ATMCI_DTOE) {
-					dev_dbg(&host->pdev->dev,
-							"data timeout error\n");
-					data->error = -ETIMEDOUT;
-				} else if (status & ATMCI_DCRCE) {
-					dev_dbg(&host->pdev->dev,
-							"data CRC error\n");
-					data->error = -EILSEQ;
-				} else {
-					dev_dbg(&host->pdev->dev,
-						"data FIFO error (status=%08x)\n",
-						status);
-					data->error = -EIO;
-				}
+			if (host->caps.need_notbusy_for_read_ops ||
+			   (host->data->flags & MMC_DATA_WRITE)) {
+				atmci_writel(host, ATMCI_IER, ATMCI_NOTBUSY);
+				state = STATE_WAITING_NOTBUSY;
+			} else if (host->mrq->stop) {
+				atmci_writel(host, ATMCI_IER, ATMCI_CMDRDY);
+				atmci_send_stop_cmd(host, data);
+				state = STATE_SENDING_STOP;
 			} else {
+				host->data = NULL;
 				data->bytes_xfered = data->blocks * data->blksz;
 				data->error = 0;
-				atmci_writel(host, ATMCI_IDR, ATMCI_DATA_ERROR_FLAGS);
+				state = STATE_END_REQUEST;
 			}
+			break;
 
-			if (!data->stop) {
-				atmci_request_end(host, host->mrq);
-				goto unlock;
-			}
+		case STATE_WAITING_NOTBUSY:
+			/*
+			 * We can be in the state for two reasons: a command
+			 * requiring waiting not busy signal (stop command
+			 * included) or a write operation. In the latest case,
+			 * we need to send a stop command.
+			 */
+			dev_dbg(&host->pdev->dev, "FSM: not busy?\n");
+			if (!atmci_test_and_clear_pending(host,
+						EVENT_NOTBUSY))
+				break;
 
-			prev_state = state = STATE_SENDING_STOP;
-			if (!data->error)
-				atmci_send_stop_cmd(host, data);
-			/* fall through */
+			dev_dbg(&host->pdev->dev, "set completed not busy\n");
+			atmci_set_completed(host, EVENT_NOTBUSY);
+
+			if (host->data) {
+				/*
+				 * For some commands such as CMD53, even if
+				 * there is data transfer, there is no stop
+				 * command to send.
+				 */
+				if (host->mrq->stop) {
+					atmci_writel(host, ATMCI_IER,
+					             ATMCI_CMDRDY);
+					atmci_send_stop_cmd(host, data);
+					state = STATE_SENDING_STOP;
+				} else {
+					host->data = NULL;
+					data->bytes_xfered = data->blocks
+					                     * data->blksz;
+					data->error = 0;
+					state = STATE_END_REQUEST;
+				}
+			} else
+				state = STATE_END_REQUEST;
+			break;
 
 		case STATE_SENDING_STOP:
+			/*
+			 * In this state, it is important to set host->data to
+			 * NULL (which is tested in the waiting notbusy state)
+			 * in order to go to the end request state instead of
+			 * sending stop again.
+			 */
+			dev_dbg(&host->pdev->dev, "FSM: cmd ready?\n");
 			if (!atmci_test_and_clear_pending(host,
-						EVENT_CMD_COMPLETE))
+						EVENT_CMD_RDY))
 				break;
 
+			dev_dbg(&host->pdev->dev, "FSM: cmd ready\n");
 			host->cmd = NULL;
+			data->bytes_xfered = data->blocks * data->blksz;
+			data->error = 0;
 			atmci_command_complete(host, mrq->stop);
-			atmci_request_end(host, host->mrq);
-			goto unlock;
+			if (mrq->stop->error) {
+				host->stop_transfer(host);
+				atmci_writel(host, ATMCI_IDR,
+				             ATMCI_TXRDY | ATMCI_RXRDY
+				             | ATMCI_DATA_ERROR_FLAGS);
+				state = STATE_END_REQUEST;
+			} else {
+				atmci_writel(host, ATMCI_IER, ATMCI_NOTBUSY);
+				state = STATE_WAITING_NOTBUSY;
+			}
+			host->data = NULL;
+			break;
 
-		case STATE_DATA_ERROR:
-			if (!atmci_test_and_clear_pending(host,
-						EVENT_XFER_COMPLETE))
-				break;
+		case STATE_END_REQUEST:
+			atmci_writel(host, ATMCI_IDR, ATMCI_TXRDY | ATMCI_RXRDY
+			                   | ATMCI_DATA_ERROR_FLAGS);
+			status = host->data_status;
+			if (unlikely(status)) {
+				host->stop_transfer(host);
+				host->data = NULL;
+				if (data) {
+					if (status & ATMCI_DTOE) {
+						data->error = -ETIMEDOUT;
+					} else if (status & ATMCI_DCRCE) {
+						data->error = -EILSEQ;
+					} else {
+						data->error = -EIO;
+					}
+				}
+			}
 
-			state = STATE_DATA_BUSY;
+			atmci_request_end(host, host->mrq);
+			state = STATE_IDLE;
 			break;
 		}
 	} while (state != prev_state);
 
 	host->state = state;
 
-unlock:
 	spin_unlock(&host->lock);
 }
 
@@ -1592,7 +1848,8 @@
 			if (offset == sg->length) {
 				flush_dcache_page(sg_page(sg));
 				host->sg = sg = sg_next(sg);
-				if (!sg)
+				host->sg_len--;
+				if (!sg || !host->sg_len)
 					goto done;
 
 				offset = 0;
@@ -1605,7 +1862,8 @@
 
 			flush_dcache_page(sg_page(sg));
 			host->sg = sg = sg_next(sg);
-			if (!sg)
+			host->sg_len--;
+			if (!sg || !host->sg_len)
 				goto done;
 
 			offset = 4 - remaining;
@@ -1620,9 +1878,6 @@
 						| ATMCI_DATA_ERROR_FLAGS));
 			host->data_status = status;
 			data->bytes_xfered += nbytes;
-			smp_wmb();
-			atmci_set_pending(host, EVENT_DATA_ERROR);
-			tasklet_schedule(&host->tasklet);
 			return;
 		}
 	} while (status & ATMCI_RXRDY);
@@ -1659,7 +1914,8 @@
 			nbytes += 4;
 			if (offset == sg->length) {
 				host->sg = sg = sg_next(sg);
-				if (!sg)
+				host->sg_len--;
+				if (!sg || !host->sg_len)
 					goto done;
 
 				offset = 0;
@@ -1673,7 +1929,8 @@
 			nbytes += remaining;
 
 			host->sg = sg = sg_next(sg);
-			if (!sg) {
+			host->sg_len--;
+			if (!sg || !host->sg_len) {
 				atmci_writel(host, ATMCI_TDR, value);
 				goto done;
 			}
@@ -1691,9 +1948,6 @@
 						| ATMCI_DATA_ERROR_FLAGS));
 			host->data_status = status;
 			data->bytes_xfered += nbytes;
-			smp_wmb();
-			atmci_set_pending(host, EVENT_DATA_ERROR);
-			tasklet_schedule(&host->tasklet);
 			return;
 		}
 	} while (status & ATMCI_TXRDY);
@@ -1711,16 +1965,6 @@
 	atmci_set_pending(host, EVENT_XFER_COMPLETE);
 }
 
-static void atmci_cmd_interrupt(struct atmel_mci *host, u32 status)
-{
-	atmci_writel(host, ATMCI_IDR, ATMCI_CMDRDY);
-
-	host->cmd_status = status;
-	smp_wmb();
-	atmci_set_pending(host, EVENT_CMD_COMPLETE);
-	tasklet_schedule(&host->tasklet);
-}
-
 static void atmci_sdio_interrupt(struct atmel_mci *host, u32 status)
 {
 	int	i;
@@ -1748,17 +1992,21 @@
 			break;
 
 		if (pending & ATMCI_DATA_ERROR_FLAGS) {
+			dev_dbg(&host->pdev->dev, "IRQ: data error\n");
 			atmci_writel(host, ATMCI_IDR, ATMCI_DATA_ERROR_FLAGS
-					| ATMCI_RXRDY | ATMCI_TXRDY);
-			pending &= atmci_readl(host, ATMCI_IMR);
+					| ATMCI_RXRDY | ATMCI_TXRDY
+					| ATMCI_ENDRX | ATMCI_ENDTX
+					| ATMCI_RXBUFF | ATMCI_TXBUFE);
 
 			host->data_status = status;
+			dev_dbg(&host->pdev->dev, "set pending data error\n");
 			smp_wmb();
 			atmci_set_pending(host, EVENT_DATA_ERROR);
 			tasklet_schedule(&host->tasklet);
 		}
 
 		if (pending & ATMCI_TXBUFE) {
+			dev_dbg(&host->pdev->dev, "IRQ: tx buffer empty\n");
 			atmci_writel(host, ATMCI_IDR, ATMCI_TXBUFE);
 			atmci_writel(host, ATMCI_IDR, ATMCI_ENDTX);
 			/*
@@ -1774,6 +2022,7 @@
 				atmci_pdc_complete(host);
 			}
 		} else if (pending & ATMCI_ENDTX) {
+			dev_dbg(&host->pdev->dev, "IRQ: end of tx buffer\n");
 			atmci_writel(host, ATMCI_IDR, ATMCI_ENDTX);
 
 			if (host->data_size) {
@@ -1784,6 +2033,7 @@
 		}
 
 		if (pending & ATMCI_RXBUFF) {
+			dev_dbg(&host->pdev->dev, "IRQ: rx buffer full\n");
 			atmci_writel(host, ATMCI_IDR, ATMCI_RXBUFF);
 			atmci_writel(host, ATMCI_IDR, ATMCI_ENDRX);
 			/*
@@ -1799,6 +2049,7 @@
 				atmci_pdc_complete(host);
 			}
 		} else if (pending & ATMCI_ENDRX) {
+			dev_dbg(&host->pdev->dev, "IRQ: end of rx buffer\n");
 			atmci_writel(host, ATMCI_IDR, ATMCI_ENDRX);
 
 			if (host->data_size) {
@@ -1808,23 +2059,44 @@
 			}
 		}
 
+		/*
+		 * First mci IPs, so mainly the ones having pdc, have some
+		 * issues with the notbusy signal. You can't get it after
+		 * data transmission if you have not sent a stop command.
+		 * The appropriate workaround is to use the BLKE signal.
+		 */
+		if (pending & ATMCI_BLKE) {
+			dev_dbg(&host->pdev->dev, "IRQ: blke\n");
+			atmci_writel(host, ATMCI_IDR, ATMCI_BLKE);
+			smp_wmb();
+			dev_dbg(&host->pdev->dev, "set pending notbusy\n");
+			atmci_set_pending(host, EVENT_NOTBUSY);
+			tasklet_schedule(&host->tasklet);
+		}
 
 		if (pending & ATMCI_NOTBUSY) {
-			atmci_writel(host, ATMCI_IDR,
-					ATMCI_DATA_ERROR_FLAGS | ATMCI_NOTBUSY);
-			if (!host->data_status)
-				host->data_status = status;
+			dev_dbg(&host->pdev->dev, "IRQ: not_busy\n");
+			atmci_writel(host, ATMCI_IDR, ATMCI_NOTBUSY);
 			smp_wmb();
-			atmci_set_pending(host, EVENT_DATA_COMPLETE);
+			dev_dbg(&host->pdev->dev, "set pending notbusy\n");
+			atmci_set_pending(host, EVENT_NOTBUSY);
 			tasklet_schedule(&host->tasklet);
 		}
+
 		if (pending & ATMCI_RXRDY)
 			atmci_read_data_pio(host);
 		if (pending & ATMCI_TXRDY)
 			atmci_write_data_pio(host);
 
-		if (pending & ATMCI_CMDRDY)
-			atmci_cmd_interrupt(host, status);
+		if (pending & ATMCI_CMDRDY) {
+			dev_dbg(&host->pdev->dev, "IRQ: cmd ready\n");
+			atmci_writel(host, ATMCI_IDR, ATMCI_CMDRDY);
+			host->cmd_status = status;
+			smp_wmb();
+			dev_dbg(&host->pdev->dev, "set pending cmd rdy\n");
+			atmci_set_pending(host, EVENT_CMD_RDY);
+			tasklet_schedule(&host->tasklet);
+		}
 
 		if (pending & (ATMCI_SDIOIRQA | ATMCI_SDIOIRQB))
 			atmci_sdio_interrupt(host, status);
@@ -1869,6 +2141,13 @@
 	slot->sdc_reg = sdc_reg;
 	slot->sdio_irq = sdio_irq;
 
+	dev_dbg(&mmc->class_dev,
+	        "slot[%u]: bus_width=%u, detect_pin=%d, "
+		"detect_is_active_high=%s, wp_pin=%d\n",
+		id, slot_data->bus_width, slot_data->detect_pin,
+		slot_data->detect_is_active_high ? "true" : "false",
+		slot_data->wp_pin);
+
 	mmc->ops = &atmci_ops;
 	mmc->f_min = DIV_ROUND_UP(host->bus_hz, 512);
 	mmc->f_max = host->bus_hz / 2;
@@ -1877,13 +2156,26 @@
 		mmc->caps |= MMC_CAP_SDIO_IRQ;
 	if (host->caps.has_highspeed)
 		mmc->caps |= MMC_CAP_SD_HIGHSPEED;
-	if (slot_data->bus_width >= 4)
+	/*
+	 * Without the read/write proof capability, it is strongly suggested to
+	 * use only one bit for data to prevent fifo underruns and overruns
+	 * which will corrupt data.
+	 */
+	if ((slot_data->bus_width >= 4) && host->caps.has_rwproof)
 		mmc->caps |= MMC_CAP_4_BIT_DATA;
 
-	mmc->max_segs = 64;
-	mmc->max_req_size = 32768 * 512;
-	mmc->max_blk_size = 32768;
-	mmc->max_blk_count = 512;
+	if (atmci_get_version(host) < 0x200) {
+		mmc->max_segs = 256;
+		mmc->max_blk_size = 4095;
+		mmc->max_blk_count = 256;
+		mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count;
+		mmc->max_seg_size = mmc->max_blk_size * mmc->max_segs;
+	} else {
+		mmc->max_segs = 64;
+		mmc->max_req_size = 32768 * 512;
+		mmc->max_blk_size = 32768;
+		mmc->max_blk_count = 512;
+	}
 
 	/* Assume card is present initially */
 	set_bit(ATMCI_CARD_PRESENT, &slot->flags);
@@ -1958,10 +2250,15 @@
 	mmc_free_host(slot->mmc);
 }
 
-static bool atmci_filter(struct dma_chan *chan, void *slave)
+static bool atmci_filter(struct dma_chan *chan, void *pdata)
 {
-	struct mci_dma_data	*sl = slave;
+	struct mci_platform_data *sl_pdata = pdata;
+	struct mci_dma_data *sl;
 
+	if (!sl_pdata)
+		return false;
+
+	sl = sl_pdata->dma_slave;
 	if (sl && find_slave_dev(sl) == chan->device->dev) {
 		chan->private = slave_data_ptr(sl);
 		return true;
@@ -1973,21 +2270,18 @@
 static bool atmci_configure_dma(struct atmel_mci *host)
 {
 	struct mci_platform_data	*pdata;
+	dma_cap_mask_t mask;
 
 	if (host == NULL)
 		return false;
 
 	pdata = host->pdev->dev.platform_data;
 
-	if (pdata && find_slave_dev(pdata->dma_slave)) {
-		dma_cap_mask_t mask;
+	dma_cap_zero(mask);
+	dma_cap_set(DMA_SLAVE, mask);
 
-		/* Try to grab a DMA channel */
-		dma_cap_zero(mask);
-		dma_cap_set(DMA_SLAVE, mask);
-		host->dma.chan =
-			dma_request_channel(mask, atmci_filter, pdata->dma_slave);
-	}
+	host->dma.chan = dma_request_slave_channel_compat(mask, atmci_filter, pdata,
+							  &host->pdev->dev, "rxtx");
 	if (!host->dma.chan) {
 		dev_warn(&host->pdev->dev, "no DMA channel available\n");
 		return false;
@@ -2007,11 +2301,6 @@
 	}
 }
 
-static inline unsigned int atmci_get_version(struct atmel_mci *host)
-{
-	return atmci_readl(host, ATMCI_VERSION) & 0x00000fff;
-}
-
 /*
  * HSMCI (High Speed MCI) module is not fully compatible with MCI module.
  * HSMCI provides DMA support and a new config register but no more supports
@@ -2025,13 +2314,17 @@
 	dev_info(&host->pdev->dev,
 			"version: 0x%x\n", version);
 
-	host->caps.has_dma = 0;
-	host->caps.has_pdc = 1;
+	host->caps.has_dma_conf_reg = 0;
+	host->caps.has_pdc = ATMCI_PDC_CONNECTED;
 	host->caps.has_cfg_reg = 0;
 	host->caps.has_cstor_reg = 0;
 	host->caps.has_highspeed = 0;
 	host->caps.has_rwproof = 0;
 	host->caps.has_odd_clk_div = 0;
+	host->caps.has_bad_data_ordering = 1;
+	host->caps.need_reset_after_xfer = 1;
+	host->caps.need_blksz_mul_4 = 1;
+	host->caps.need_notbusy_for_read_ops = 0;
 
 	/* keep only major version number */
 	switch (version & 0xf00) {
@@ -2039,19 +2332,19 @@
 		host->caps.has_odd_clk_div = 1;
 	case 0x400:
 	case 0x300:
-#ifdef CONFIG_AT_HDMAC
-		host->caps.has_dma = 1;
-#else
-		dev_info(&host->pdev->dev,
-			"has dma capability but dma engine is not selected, then use pio\n");
-#endif
+		host->caps.has_dma_conf_reg = 1;
 		host->caps.has_pdc = 0;
 		host->caps.has_cfg_reg = 1;
 		host->caps.has_cstor_reg = 1;
 		host->caps.has_highspeed = 1;
 	case 0x200:
 		host->caps.has_rwproof = 1;
+		host->caps.need_blksz_mul_4 = 0;
+		host->caps.need_notbusy_for_read_ops = 1;
 	case 0x100:
+		host->caps.has_bad_data_ordering = 0;
+		host->caps.need_reset_after_xfer = 0;
+	case 0x0:
 		break;
 	default:
 		host->caps.has_pdc = 0;
@@ -2074,8 +2367,14 @@
 	if (!regs)
 		return -ENXIO;
 	pdata = pdev->dev.platform_data;
-	if (!pdata)
-		return -ENXIO;
+	if (!pdata) {
+		pdata = atmci_of_init(pdev);
+		if (IS_ERR(pdata)) {
+			dev_err(&pdev->dev, "platform data not available\n");
+			return PTR_ERR(pdata);
+		}
+	}
+
 	irq = platform_get_irq(pdev, 0);
 	if (irq < 0)
 		return irq;
@@ -2114,7 +2413,7 @@
 
 	/* Get MCI capabilities and set operations according to it */
 	atmci_get_cap(host);
-	if (host->caps.has_dma && atmci_configure_dma(host)) {
+	if (atmci_configure_dma(host)) {
 		host->prepare_data = &atmci_prepare_data_dma;
 		host->submit_data = &atmci_submit_data_dma;
 		host->stop_transfer = &atmci_stop_transfer_dma;
@@ -2132,20 +2431,28 @@
 
 	platform_set_drvdata(pdev, host);
 
+	setup_timer(&host->timer, atmci_timeout_timer, (unsigned long)host);
+
 	/* We need at least one slot to succeed */
 	nr_slots = 0;
 	ret = -ENODEV;
 	if (pdata->slot[0].bus_width) {
 		ret = atmci_init_slot(host, &pdata->slot[0],
 				0, ATMCI_SDCSEL_SLOT_A, ATMCI_SDIOIRQA);
-		if (!ret)
+		if (!ret) {
 			nr_slots++;
+			host->buf_size = host->slot[0]->mmc->max_req_size;
+		}
 	}
 	if (pdata->slot[1].bus_width) {
 		ret = atmci_init_slot(host, &pdata->slot[1],
 				1, ATMCI_SDCSEL_SLOT_B, ATMCI_SDIOIRQB);
-		if (!ret)
+		if (!ret) {
 			nr_slots++;
+			if (host->slot[1]->mmc->max_req_size > host->buf_size)
+				host->buf_size =
+					host->slot[1]->mmc->max_req_size;
+		}
 	}
 
 	if (!nr_slots) {
@@ -2153,6 +2460,17 @@
 		goto err_init_slot;
 	}
 
+	if (!host->caps.has_rwproof) {
+		host->buffer = dma_alloc_coherent(&pdev->dev, host->buf_size,
+		                                  &host->buf_phys_addr,
+						  GFP_KERNEL);
+		if (!host->buffer) {
+			ret = -ENOMEM;
+			dev_err(&pdev->dev, "buffer allocation failed\n");
+			goto err_init_slot;
+		}
+	}
+
 	dev_info(&pdev->dev,
 			"Atmel MCI controller at 0x%08lx irq %d, %u slots\n",
 			host->mapbase, irq, nr_slots);
@@ -2179,6 +2497,10 @@
 
 	platform_set_drvdata(pdev, NULL);
 
+	if (host->buffer)
+		dma_free_coherent(&pdev->dev, host->buf_size,
+		                  host->buffer, host->buf_phys_addr);
+
 	for (i = 0; i < ATMCI_MAX_NR_SLOTS; i++) {
 		if (host->slot[i])
 			atmci_cleanup_slot(host->slot[i], i);
@@ -2190,10 +2512,8 @@
 	atmci_readl(host, ATMCI_SR);
 	clk_disable(host->mck);
 
-#ifdef CONFIG_MMC_ATMELMCI_DMA
 	if (host->dma.chan)
 		dma_release_channel(host->dma.chan);
-#endif
 
 	free_irq(platform_get_irq(pdev, 0), host);
 	iounmap(host->regs);
@@ -2270,6 +2590,7 @@
 	.driver		= {
 		.name		= "atmel_mci",
 		.pm		= ATMCI_PM_OPS,
+		.of_match_table	= of_match_ptr(atmci_dt_ids),
 	},
 };
 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/atmel-mci-regs.h linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/atmel-mci-regs.h
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/atmel-mci-regs.h	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/atmel-mci-regs.h	2014-09-12 15:59:37.348052000 +0800
@@ -140,4 +140,25 @@
 #define atmci_writel(port,reg,value)			\
 	__raw_writel((value), (port)->regs + reg)
 
+/* On AVR chips the Peripheral DMA Controller is not connected to MCI. */
+#ifdef CONFIG_AVR32
+#	define ATMCI_PDC_CONNECTED	0
+#else
+#	define ATMCI_PDC_CONNECTED	1
+#endif
+
+/*
+ * Fix sconfig's burst size according to atmel MCI. We need to convert them as:
+ * 1 -> 0, 4 -> 1, 8 -> 2, 16 -> 3.
+ *
+ * This can be done by finding most significant bit set.
+ */
+static inline unsigned int atmci_convert_chksize(unsigned int maxburst)
+{
+	if (maxburst > 1)
+		return fls(maxburst) - 2;
+	else
+		return 0;
+}
+
 #endif /* __DRIVERS_MMC_ATMEL_MCI_H__ */
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/au1xmmc.c linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/au1xmmc.c
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/au1xmmc.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/au1xmmc.c	2014-09-12 15:59:37.348052000 +0800
@@ -943,7 +943,7 @@
 	.enable_sdio_irq = au1xmmc_enable_sdio_irq,
 };
 
-static int __devinit au1xmmc_probe(struct platform_device *pdev)
+static int au1xmmc_probe(struct platform_device *pdev)
 {
 	struct mmc_host *mmc;
 	struct au1xmmc_host *host;
@@ -1114,7 +1114,7 @@
 	return ret;
 }
 
-static int __devexit au1xmmc_remove(struct platform_device *pdev)
+static int au1xmmc_remove(struct platform_device *pdev)
 {
 	struct au1xmmc_host *host = platform_get_drvdata(pdev);
 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/bfin_sdh.c linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/bfin_sdh.c
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/bfin_sdh.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/bfin_sdh.c	2014-09-12 15:59:37.348052000 +0800
@@ -24,9 +24,7 @@
 #include <asm/portmux.h>
 #include <asm/bfin_sdh.h>
 
-#if defined(CONFIG_BF51x)
-#define bfin_read_SDH_PWR_CTL		bfin_read_RSI_PWR_CTL
-#define bfin_write_SDH_PWR_CTL		bfin_write_RSI_PWR_CTL
+#if defined(CONFIG_BF51x) || defined(__ADSPBF60x__)
 #define bfin_read_SDH_CLK_CTL		bfin_read_RSI_CLK_CTL
 #define bfin_write_SDH_CLK_CTL		bfin_write_RSI_CLK_CTL
 #define bfin_write_SDH_ARGUMENT		bfin_write_RSI_ARGUMENT
@@ -45,17 +43,18 @@
 #define bfin_write_SDH_E_STATUS		bfin_write_RSI_E_STATUS
 #define bfin_read_SDH_STATUS		bfin_read_RSI_STATUS
 #define bfin_write_SDH_MASK0		bfin_write_RSI_MASK0
+#define bfin_write_SDH_E_MASK		bfin_write_RSI_E_MASK
 #define bfin_read_SDH_CFG		bfin_read_RSI_CFG
 #define bfin_write_SDH_CFG		bfin_write_RSI_CFG
+# if defined(__ADSPBF60x__)
+#  define bfin_read_SDH_BLK_SIZE	bfin_read_RSI_BLKSZ
+#  define bfin_write_SDH_BLK_SIZE	bfin_write_RSI_BLKSZ
+# else
+#  define bfin_read_SDH_PWR_CTL		bfin_read_RSI_PWR_CTL
+#  define bfin_write_SDH_PWR_CTL	bfin_write_RSI_PWR_CTL
+# endif
 #endif
 
-struct dma_desc_array {
-	unsigned long	start_addr;
-	unsigned short	cfg;
-	unsigned short	x_count;
-	short		x_modify;
-} __packed;
-
 struct sdh_host {
 	struct mmc_host		*mmc;
 	spinlock_t		lock;
@@ -69,6 +68,7 @@
 	dma_addr_t		sg_dma;
 	int			dma_len;
 
+	unsigned long		sclk;
 	unsigned int		imask;
 	unsigned int		power_mode;
 	unsigned int		clk_div;
@@ -134,11 +134,15 @@
 	/* Only supports power-of-2 block size */
 	if (data->blksz & (data->blksz - 1))
 		return -EINVAL;
+#ifndef RSI_BLKSZ
 	data_ctl |= ((ffs(data->blksz) - 1) << 4);
+#else
+        bfin_write_SDH_BLK_SIZE(data->blksz);
+#endif
 
 	bfin_write_SDH_DATA_CTL(data_ctl);
 	/* the time of a host clock period in ns */
-	cycle_ns = 1000000000 / (get_sclk() / (2 * (host->clk_div + 1)));
+	cycle_ns = 1000000000 / (host->sclk / (2 * (host->clk_div + 1)));
 	timeout = data->timeout_ns / cycle_ns;
 	timeout += data->timeout_clks;
 	bfin_write_SDH_DATA_TIMER(timeout);
@@ -152,8 +156,13 @@
 
 	sdh_enable_stat_irq(host, (DAT_CRC_FAIL | DAT_TIME_OUT | DAT_END));
 	host->dma_len = dma_map_sg(mmc_dev(host->mmc), data->sg, data->sg_len, host->dma_dir);
-#if defined(CONFIG_BF54x)
-	dma_cfg |= DMAFLOW_ARRAY | NDSIZE_5 | RESTART | WDSIZE_32 | DMAEN;
+#if defined(CONFIG_BF54x) || defined(CONFIG_BF60x)
+	dma_cfg |= DMAFLOW_ARRAY | RESTART | WDSIZE_32 | DMAEN;
+# ifdef RSI_BLKSZ
+	dma_cfg |= PSIZE_32 | NDSIZE_3;
+# else
+	dma_cfg |= NDSIZE_5;
+# endif
 	{
 		struct scatterlist *sg;
 		int i;
@@ -163,7 +172,7 @@
 			host->sg_cpu[i].x_count = sg_dma_len(sg) / 4;
 			host->sg_cpu[i].x_modify = 4;
 			dev_dbg(mmc_dev(host->mmc), "%d: start_addr:0x%lx, "
-				"cfg:0x%x, x_count:0x%x, x_modify:0x%x\n",
+				"cfg:0x%lx, x_count:0x%lx, x_modify:0x%lx\n",
 				i, host->sg_cpu[i].start_addr,
 				host->sg_cpu[i].cfg, host->sg_cpu[i].x_count,
 				host->sg_cpu[i].x_modify);
@@ -179,6 +188,7 @@
 	set_dma_curr_desc_addr(host->dma_ch, (unsigned long *)host->sg_dma);
 	set_dma_x_count(host->dma_ch, 0);
 	set_dma_x_modify(host->dma_ch, 0);
+	SSYNC();
 	set_dma_config(host->dma_ch, dma_cfg);
 #elif defined(CONFIG_BF51x)
 	/* RSI DMA doesn't work in array mode */
@@ -186,6 +196,7 @@
 	set_dma_start_addr(host->dma_ch, sg_dma_address(&data->sg[0]));
 	set_dma_x_count(host->dma_ch, length / 4);
 	set_dma_x_modify(host->dma_ch, 4);
+	SSYNC();
 	set_dma_config(host->dma_ch, dma_cfg);
 #endif
 	bfin_write_SDH_DATA_CTL(bfin_read_SDH_DATA_CTL() | DTX_DMA_E | DTX_E);
@@ -303,7 +314,6 @@
 	else
 		data->bytes_xfered = 0;
 
-	sdh_disable_stat_irq(host, DAT_END | DAT_TIME_OUT | DAT_CRC_FAIL | RX_OVERRUN | TX_UNDERRUN);
 	bfin_write_SDH_STATUS_CLR(DAT_END_STAT | DAT_TIMEOUT_STAT | \
 			DAT_CRC_FAIL_STAT | DAT_BLK_END_STAT | RX_OVERRUN | TX_UNDERRUN);
 	bfin_write_SDH_DATA_CTL(0);
@@ -328,74 +338,115 @@
 	dev_dbg(mmc_dev(host->mmc), "%s enter, mrp:%p, cmd:%p\n", __func__, mrq, mrq->cmd);
 	WARN_ON(host->mrq != NULL);
 
+	spin_lock(&host->lock);
 	host->mrq = mrq;
 	host->data = mrq->data;
 
 	if (mrq->data && mrq->data->flags & MMC_DATA_READ) {
 		ret = sdh_setup_data(host, mrq->data);
 		if (ret)
-			return;
+			goto data_err;
 	}
 
 	sdh_start_cmd(host, mrq->cmd);
+data_err:
+	spin_unlock(&host->lock);
 }
 
 static void sdh_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 {
 	struct sdh_host *host;
-	unsigned long flags;
 	u16 clk_ctl = 0;
+#ifndef RSI_BLKSZ
 	u16 pwr_ctl = 0;
+#endif
 	u16 cfg;
 	host = mmc_priv(mmc);
 
-	spin_lock_irqsave(&host->lock, flags);
-	if (ios->clock) {
-		unsigned long  sys_clk, ios_clk;
-		unsigned char clk_div;
-		ios_clk = 2 * ios->clock;
-		sys_clk = get_sclk();
-		clk_div = sys_clk / ios_clk;
-		if (sys_clk % ios_clk == 0)
-			clk_div -= 1;
-		clk_div = min_t(unsigned char, clk_div, 0xFF);
-		clk_ctl |= clk_div;
-		clk_ctl |= CLK_E;
-		host->clk_div = clk_div;
-	} else
-		sdh_stop_clock(host);
-
-	if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN)
-#ifdef CONFIG_SDH_BFIN_MISSING_CMD_PULLUP_WORKAROUND
-		pwr_ctl |= ROD_CTL;
-#else
-		pwr_ctl |= SD_CMD_OD | ROD_CTL;
-#endif
+	spin_lock(&host->lock);
 
-	if (ios->bus_width == MMC_BUS_WIDTH_4) {
-		cfg = bfin_read_SDH_CFG();
+	cfg = bfin_read_SDH_CFG();
+	cfg |= MWE;
+	switch (ios->bus_width) {
+	case MMC_BUS_WIDTH_4:
+#ifndef RSI_BLKSZ
 		cfg &= ~PD_SDDAT3;
+#endif
 		cfg |= PUP_SDDAT3;
 		/* Enable 4 bit SDIO */
-		cfg |= (SD4E | MWE);
-		bfin_write_SDH_CFG(cfg);
-		clk_ctl |= WIDE_BUS;
-	} else {
-		cfg = bfin_read_SDH_CFG();
-		cfg |= MWE;
-		bfin_write_SDH_CFG(cfg);
+		cfg |= SD4E;
+		clk_ctl |= WIDE_BUS_4;
+		break;
+	case MMC_BUS_WIDTH_8:
+#ifndef RSI_BLKSZ
+		cfg &= ~PD_SDDAT3;
+#endif
+		cfg |= PUP_SDDAT3;
+		/* Disable 4 bit SDIO */
+		cfg &= ~SD4E;
+		clk_ctl |= BYTE_BUS_8;
+		break;
+	default:
+		cfg &= ~PUP_SDDAT3;
+		/* Disable 4 bit SDIO */
+		cfg &= ~SD4E;
 	}
 
-	bfin_write_SDH_CLK_CTL(clk_ctl);
-
 	host->power_mode = ios->power_mode;
-	if (ios->power_mode == MMC_POWER_ON)
+#ifndef RSI_BLKSZ
+	if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN) {
+		pwr_ctl |= ROD_CTL;
+# ifndef CONFIG_SDH_BFIN_MISSING_CMD_PULLUP_WORKAROUND
+		pwr_ctl |= SD_CMD_OD;
+# endif
+	}
+
+	if (ios->power_mode != MMC_POWER_OFF)
 		pwr_ctl |= PWR_ON;
+	else
+		pwr_ctl &= ~PWR_ON;
 
 	bfin_write_SDH_PWR_CTL(pwr_ctl);
+#else
+# ifndef CONFIG_SDH_BFIN_MISSING_CMD_PULLUP_WORKAROUND
+	if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN)
+		cfg |= SD_CMD_OD;
+	else
+		cfg &= ~SD_CMD_OD;
+# endif
+
+
+	if (ios->power_mode != MMC_POWER_OFF)
+		cfg |= PWR_ON;
+	else
+		cfg &= ~PWR_ON;
+
+	bfin_write_SDH_CFG(cfg);
+#endif
 	SSYNC();
 
-	spin_unlock_irqrestore(&host->lock, flags);
+	if (ios->power_mode == MMC_POWER_ON && ios->clock) {
+		unsigned char clk_div;
+		clk_div = (get_sclk() / ios->clock - 1) / 2;
+		clk_div = min_t(unsigned char, clk_div, 0xFF);
+		clk_ctl |= clk_div;
+		clk_ctl |= CLK_E;
+		host->clk_div = clk_div;
+		bfin_write_SDH_CLK_CTL(clk_ctl);
+
+	} else
+		sdh_stop_clock(host);
+
+	/* set up sdh interrupt mask*/
+	if (ios->power_mode == MMC_POWER_ON)
+		bfin_write_SDH_MASK0(DAT_END | DAT_TIME_OUT | DAT_CRC_FAIL |
+			RX_OVERRUN | TX_UNDERRUN | CMD_SENT | CMD_RESP_END |
+			CMD_TIME_OUT | CMD_CRC_FAIL);
+	else
+		bfin_write_SDH_MASK0(0);
+	SSYNC();
+
+	spin_unlock(&host->lock);
 
 	dev_dbg(mmc_dev(host->mmc), "SDH: clk_div = 0x%x actual clock:%ld expected clock:%d\n",
 		host->clk_div,
@@ -412,7 +463,7 @@
 {
 	struct sdh_host *host = devid;
 
-	dev_dbg(mmc_dev(host->mmc), "%s enter, irq_stat: 0x%04x\n", __func__,
+	dev_dbg(mmc_dev(host->mmc), "%s enter, irq_stat: 0x%04lx\n", __func__,
 		get_dma_curr_irqstat(host->dma_ch));
 	clear_dma_irqstat(host->dma_ch);
 	SSYNC();
@@ -427,6 +478,9 @@
 	int handled = 0;
 
 	dev_dbg(mmc_dev(host->mmc), "%s enter\n", __func__);
+
+	spin_lock(&host->lock);
+
 	status = bfin_read_SDH_E_STATUS();
 	if (status & SD_CARD_DET) {
 		mmc_detect_change(host->mmc, 0);
@@ -444,12 +498,31 @@
 	if (status & (DAT_END | DAT_TIME_OUT | DAT_CRC_FAIL | RX_OVERRUN | TX_UNDERRUN))
 		handled |= sdh_data_done(host, status);
 
+	spin_unlock(&host->lock);
+
 	dev_dbg(mmc_dev(host->mmc), "%s exit\n\n", __func__);
 
 	return IRQ_RETVAL(handled);
 }
 
-static int __devinit sdh_probe(struct platform_device *pdev)
+static void sdh_reset(void)
+{
+#if defined(CONFIG_BF54x)
+	/* Secure Digital Host shares DMA with Nand controller */
+	bfin_write_DMAC1_PERIMUX(bfin_read_DMAC1_PERIMUX() | 0x1);
+#endif
+
+	bfin_write_SDH_CFG(bfin_read_SDH_CFG() | CLKS_EN);
+	SSYNC();
+
+	/* Disable card inserting detection pin. set MMC_CAP_NEEDS_POLL, and
+	 * mmc stack will do the detection.
+	 */
+	bfin_write_SDH_CFG((bfin_read_SDH_CFG() & 0x1F) | (PUP_SDDAT | PUP_SDDAT3));
+	SSYNC();
+}
+
+static int sdh_probe(struct platform_device *pdev)
 {
 	struct mmc_host *mmc;
 	struct sdh_host *host;
@@ -469,8 +542,16 @@
 	}
 
 	mmc->ops = &sdh_ops;
-	mmc->max_segs = 32;
+#if defined(CONFIG_BF51x)
+	mmc->max_segs = 1;
+#else
+	mmc->max_segs = PAGE_SIZE / sizeof(struct dma_desc_array);
+#endif
+#ifdef RSI_BLKSZ
+	mmc->max_seg_size = -1;
+#else
 	mmc->max_seg_size = 1 << 16;
+#endif
 	mmc->max_blk_size = 1 << 11;
 	mmc->max_blk_count = 1 << 11;
 	mmc->max_req_size = PAGE_SIZE;
@@ -480,6 +561,7 @@
 	mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_NEEDS_POLL;
 	host = mmc_priv(mmc);
 	host->mmc = mmc;
+	host->sclk = get_sclk();
 
 	spin_lock_init(&host->lock);
 	host->irq = drv_data->irq_int0;
@@ -504,7 +586,6 @@
 	}
 
 	platform_set_drvdata(pdev, mmc);
-	mmc_add_host(mmc);
 
 	ret = request_irq(host->irq, sdh_stat_irq, 0, "SDH Status IRQ", host);
 	if (ret) {
@@ -517,20 +598,10 @@
 		dev_err(&pdev->dev, "unable to request peripheral pins\n");
 		goto out4;
 	}
-#if defined(CONFIG_BF54x)
-	/* Secure Digital Host shares DMA with Nand controller */
-	bfin_write_DMAC1_PERIMUX(bfin_read_DMAC1_PERIMUX() | 0x1);
-#endif
 
-	bfin_write_SDH_CFG(bfin_read_SDH_CFG() | CLKS_EN);
-	SSYNC();
-
-	/* Disable card inserting detection pin. set MMC_CAP_NEES_POLL, and
-	 * mmc stack will do the detection.
-	 */
-	bfin_write_SDH_CFG((bfin_read_SDH_CFG() & 0x1F) | (PUP_SDDAT | PUP_SDDAT3));
-	SSYNC();
+	sdh_reset();
 
+	mmc_add_host(mmc);
 	return 0;
 
 out4:
@@ -546,7 +617,7 @@
 	return ret;
 }
 
-static int __devexit sdh_remove(struct platform_device *pdev)
+static int sdh_remove(struct platform_device *pdev)
 {
 	struct mmc_host *mmc = platform_get_drvdata(pdev);
 
@@ -578,7 +649,6 @@
 	if (mmc)
 		ret = mmc_suspend_host(mmc);
 
-	bfin_write_SDH_PWR_CTL(bfin_read_SDH_PWR_CTL() & ~PWR_ON);
 	peripheral_free_list(drv_data->pin_req);
 
 	return ret;
@@ -596,16 +666,7 @@
 		return ret;
 	}
 
-	bfin_write_SDH_PWR_CTL(bfin_read_SDH_PWR_CTL() | PWR_ON);
-#if defined(CONFIG_BF54x)
-	/* Secure Digital Host shares DMA with Nand controller */
-	bfin_write_DMAC1_PERIMUX(bfin_read_DMAC1_PERIMUX() | 0x1);
-#endif
-	bfin_write_SDH_CFG(bfin_read_SDH_CFG() | CLKS_EN);
-	SSYNC();
-
-	bfin_write_SDH_CFG((bfin_read_SDH_CFG() & 0x1F) | (PUP_SDDAT | PUP_SDDAT3));
-	SSYNC();
+	sdh_reset();
 
 	if (mmc)
 		ret = mmc_resume_host(mmc);
@@ -619,7 +680,7 @@
 
 static struct platform_driver sdh_driver = {
 	.probe   = sdh_probe,
-	.remove  = __devexit_p(sdh_remove),
+	.remove  = sdh_remove,
 	.suspend = sdh_suspend,
 	.resume  = sdh_resume,
 	.driver  = {
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/cb710-mmc.c linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/cb710-mmc.c
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/cb710-mmc.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/cb710-mmc.c	2014-09-12 15:59:37.348052000 +0800
@@ -690,7 +690,7 @@
 
 #endif /* CONFIG_PM */
 
-static int __devinit cb710_mmc_init(struct platform_device *pdev)
+static int cb710_mmc_init(struct platform_device *pdev)
 {
 	struct cb710_slot *slot = cb710_pdev_to_slot(pdev);
 	struct cb710_chip *chip = cb710_slot_to_chip(slot);
@@ -746,7 +746,7 @@
 	return err;
 }
 
-static int __devexit cb710_mmc_exit(struct platform_device *pdev)
+static int cb710_mmc_exit(struct platform_device *pdev)
 {
 	struct cb710_slot *slot = cb710_pdev_to_slot(pdev);
 	struct mmc_host *mmc = cb710_slot_to_mmc(slot);
@@ -773,7 +773,7 @@
 static struct platform_driver cb710_mmc_driver = {
 	.driver.name = "cb710-mmc",
 	.probe = cb710_mmc_init,
-	.remove = __devexit_p(cb710_mmc_exit),
+	.remove = cb710_mmc_exit,
 #ifdef CONFIG_PM
 	.suspend = cb710_mmc_suspend,
 	.resume = cb710_mmc_resume,
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/davinci_mmc.c linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/davinci_mmc.c
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/davinci_mmc.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/davinci_mmc.c	2014-09-12 15:59:37.348052000 +0800
@@ -30,11 +30,14 @@
 #include <linux/io.h>
 #include <linux/irq.h>
 #include <linux/delay.h>
+#include <linux/dmaengine.h>
 #include <linux/dma-mapping.h>
+#include <linux/edma.h>
 #include <linux/mmc/mmc.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
 
-#include <mach/mmc.h>
-#include <mach/edma.h>
+#include <linux/platform_data/mmc-davinci.h>
 
 /*
  * Register Definitions
@@ -200,21 +203,13 @@
 	u32 bytes_left;
 
 	u32 rxdma, txdma;
+	struct dma_chan *dma_tx;
+	struct dma_chan *dma_rx;
 	bool use_dma;
 	bool do_dma;
 	bool sdio_int;
 	bool active_request;
 
-	/* Scatterlist DMA uses one or more parameter RAM entries:
-	 * the main one (associated with rxdma or txdma) plus zero or
-	 * more links.  The entries for a given transfer differ only
-	 * by memory buffer (address, length) and link field.
-	 */
-	struct edmacc_param	tx_template;
-	struct edmacc_param	rx_template;
-	unsigned		n_link;
-	u32			links[MAX_NR_SG - 1];
-
 	/* For PIO we walk scatterlists one segment at a time. */
 	unsigned int		sg_len;
 	struct scatterlist *sg;
@@ -410,153 +405,74 @@
 
 static void davinci_abort_dma(struct mmc_davinci_host *host)
 {
-	int sync_dev;
+	struct dma_chan *sync_dev;
 
 	if (host->data_dir == DAVINCI_MMC_DATADIR_READ)
-		sync_dev = host->rxdma;
+		sync_dev = host->dma_rx;
 	else
-		sync_dev = host->txdma;
-
-	edma_stop(sync_dev);
-	edma_clean_channel(sync_dev);
-}
-
-static void
-mmc_davinci_xfer_done(struct mmc_davinci_host *host, struct mmc_data *data);
-
-static void mmc_davinci_dma_cb(unsigned channel, u16 ch_status, void *data)
-{
-	if (DMA_COMPLETE != ch_status) {
-		struct mmc_davinci_host *host = data;
-
-		/* Currently means:  DMA Event Missed, or "null" transfer
-		 * request was seen.  In the future, TC errors (like bad
-		 * addresses) might be presented too.
-		 */
-		dev_warn(mmc_dev(host->mmc), "DMA %s error\n",
-			(host->data->flags & MMC_DATA_WRITE)
-				? "write" : "read");
-		host->data->error = -EIO;
-		mmc_davinci_xfer_done(host, host->data);
-	}
-}
-
-/* Set up tx or rx template, to be modified and updated later */
-static void __init mmc_davinci_dma_setup(struct mmc_davinci_host *host,
-		bool tx, struct edmacc_param *template)
-{
-	unsigned	sync_dev;
-	const u16	acnt = 4;
-	const u16	bcnt = rw_threshold >> 2;
-	const u16	ccnt = 0;
-	u32		src_port = 0;
-	u32		dst_port = 0;
-	s16		src_bidx, dst_bidx;
-	s16		src_cidx, dst_cidx;
-
-	/*
-	 * A-B Sync transfer:  each DMA request is for one "frame" of
-	 * rw_threshold bytes, broken into "acnt"-size chunks repeated
-	 * "bcnt" times.  Each segment needs "ccnt" such frames; since
-	 * we tell the block layer our mmc->max_seg_size limit, we can
-	 * trust (later) that it's within bounds.
-	 *
-	 * The FIFOs are read/written in 4-byte chunks (acnt == 4) and
-	 * EDMA will optimize memory operations to use larger bursts.
-	 */
-	if (tx) {
-		sync_dev = host->txdma;
-
-		/* src_prt, ccnt, and link to be set up later */
-		src_bidx = acnt;
-		src_cidx = acnt * bcnt;
-
-		dst_port = host->mem_res->start + DAVINCI_MMCDXR;
-		dst_bidx = 0;
-		dst_cidx = 0;
-	} else {
-		sync_dev = host->rxdma;
+		sync_dev = host->dma_tx;
 
-		src_port = host->mem_res->start + DAVINCI_MMCDRR;
-		src_bidx = 0;
-		src_cidx = 0;
-
-		/* dst_prt, ccnt, and link to be set up later */
-		dst_bidx = acnt;
-		dst_cidx = acnt * bcnt;
-	}
-
-	/*
-	 * We can't use FIFO mode for the FIFOs because MMC FIFO addresses
-	 * are not 256-bit (32-byte) aligned.  So we use INCR, and the W8BIT
-	 * parameter is ignored.
-	 */
-	edma_set_src(sync_dev, src_port, INCR, W8BIT);
-	edma_set_dest(sync_dev, dst_port, INCR, W8BIT);
-
-	edma_set_src_index(sync_dev, src_bidx, src_cidx);
-	edma_set_dest_index(sync_dev, dst_bidx, dst_cidx);
-
-	edma_set_transfer_params(sync_dev, acnt, bcnt, ccnt, 8, ABSYNC);
-
-	edma_read_slot(sync_dev, template);
-
-	/* don't bother with irqs or chaining */
-	template->opt |= EDMA_CHAN_SLOT(sync_dev) << 12;
+	dmaengine_terminate_all(sync_dev);
 }
 
-static void mmc_davinci_send_dma_request(struct mmc_davinci_host *host,
+static int mmc_davinci_send_dma_request(struct mmc_davinci_host *host,
 		struct mmc_data *data)
 {
-	struct edmacc_param	*template;
-	int			channel, slot;
-	unsigned		link;
-	struct scatterlist	*sg;
-	unsigned		sg_len;
-	unsigned		bytes_left = host->bytes_left;
-	const unsigned		shift = ffs(rw_threshold) - 1;
+	struct dma_chan *chan;
+	struct dma_async_tx_descriptor *desc;
+	int ret = 0;
 
 	if (host->data_dir == DAVINCI_MMC_DATADIR_WRITE) {
-		template = &host->tx_template;
-		channel = host->txdma;
+		struct dma_slave_config dma_tx_conf = {
+			.direction = DMA_MEM_TO_DEV,
+			.dst_addr = host->mem_res->start + DAVINCI_MMCDXR,
+			.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES,
+			.dst_maxburst =
+				rw_threshold / DMA_SLAVE_BUSWIDTH_4_BYTES,
+		};
+		chan = host->dma_tx;
+		dmaengine_slave_config(host->dma_tx, &dma_tx_conf);
+
+		desc = dmaengine_prep_slave_sg(host->dma_tx,
+				data->sg,
+				host->sg_len,
+				DMA_MEM_TO_DEV,
+				DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+		if (!desc) {
+			dev_dbg(mmc_dev(host->mmc),
+				"failed to allocate DMA TX descriptor");
+			ret = -1;
+			goto out;
+		}
 	} else {
-		template = &host->rx_template;
-		channel = host->rxdma;
-	}
-
-	/* We know sg_len and ccnt will never be out of range because
-	 * we told the mmc layer which in turn tells the block layer
-	 * to ensure that it only hands us one scatterlist segment
-	 * per EDMA PARAM entry.  Update the PARAM
-	 * entries needed for each segment of this scatterlist.
-	 */
-	for (slot = channel, link = 0, sg = data->sg, sg_len = host->sg_len;
-			sg_len-- != 0 && bytes_left;
-			sg = sg_next(sg), slot = host->links[link++]) {
-		u32		buf = sg_dma_address(sg);
-		unsigned	count = sg_dma_len(sg);
-
-		template->link_bcntrld = sg_len
-				? (EDMA_CHAN_SLOT(host->links[link]) << 5)
-				: 0xffff;
-
-		if (count > bytes_left)
-			count = bytes_left;
-		bytes_left -= count;
-
-		if (host->data_dir == DAVINCI_MMC_DATADIR_WRITE)
-			template->src = buf;
-		else
-			template->dst = buf;
-		template->ccnt = count >> shift;
-
-		edma_write_slot(slot, template);
+		struct dma_slave_config dma_rx_conf = {
+			.direction = DMA_DEV_TO_MEM,
+			.src_addr = host->mem_res->start + DAVINCI_MMCDRR,
+			.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES,
+			.src_maxburst =
+				rw_threshold / DMA_SLAVE_BUSWIDTH_4_BYTES,
+		};
+		chan = host->dma_rx;
+		dmaengine_slave_config(host->dma_rx, &dma_rx_conf);
+
+		desc = dmaengine_prep_slave_sg(host->dma_rx,
+				data->sg,
+				host->sg_len,
+				DMA_DEV_TO_MEM,
+				DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+		if (!desc) {
+			dev_dbg(mmc_dev(host->mmc),
+				"failed to allocate DMA RX descriptor");
+			ret = -1;
+			goto out;
+		}
 	}
 
-	if (host->version == MMC_CTLR_VERSION_2)
-		edma_clear_event(channel);
+	dmaengine_submit(desc);
+	dma_async_issue_pending(chan);
 
-	edma_start(channel);
+out:
+	return ret;
 }
 
 static int mmc_davinci_start_dma_transfer(struct mmc_davinci_host *host,
@@ -564,6 +480,7 @@
 {
 	int i;
 	int mask = rw_threshold - 1;
+	int ret = 0;
 
 	host->sg_len = dma_map_sg(mmc_dev(host->mmc), data->sg, data->sg_len,
 				((data->flags & MMC_DATA_WRITE)
@@ -583,70 +500,50 @@
 	}
 
 	host->do_dma = 1;
-	mmc_davinci_send_dma_request(host, data);
+	ret = mmc_davinci_send_dma_request(host, data);
 
-	return 0;
+	return ret;
 }
 
 static void __init_or_module
 davinci_release_dma_channels(struct mmc_davinci_host *host)
 {
-	unsigned	i;
-
 	if (!host->use_dma)
 		return;
 
-	for (i = 0; i < host->n_link; i++)
-		edma_free_slot(host->links[i]);
-
-	edma_free_channel(host->txdma);
-	edma_free_channel(host->rxdma);
+	dma_release_channel(host->dma_tx);
+	dma_release_channel(host->dma_rx);
 }
 
 static int __init davinci_acquire_dma_channels(struct mmc_davinci_host *host)
 {
-	u32 link_size;
-	int r, i;
+	int r;
+	dma_cap_mask_t mask;
 
-	/* Acquire master DMA write channel */
-	r = edma_alloc_channel(host->txdma, mmc_davinci_dma_cb, host,
-			EVENTQ_DEFAULT);
-	if (r < 0) {
-		dev_warn(mmc_dev(host->mmc), "alloc %s channel err %d\n",
-				"tx", r);
-		return r;
-	}
-	mmc_davinci_dma_setup(host, true, &host->tx_template);
-
-	/* Acquire master DMA read channel */
-	r = edma_alloc_channel(host->rxdma, mmc_davinci_dma_cb, host,
-			EVENTQ_DEFAULT);
-	if (r < 0) {
-		dev_warn(mmc_dev(host->mmc), "alloc %s channel err %d\n",
-				"rx", r);
-		goto free_master_write;
-	}
-	mmc_davinci_dma_setup(host, false, &host->rx_template);
+	dma_cap_zero(mask);
+	dma_cap_set(DMA_SLAVE, mask);
 
-	/* Allocate parameter RAM slots, which will later be bound to a
-	 * channel as needed to handle a scatterlist.
-	 */
-	link_size = min_t(unsigned, host->nr_sg, ARRAY_SIZE(host->links));
-	for (i = 0; i < link_size; i++) {
-		r = edma_alloc_slot(EDMA_CTLR(host->txdma), EDMA_SLOT_ANY);
-		if (r < 0) {
-			dev_dbg(mmc_dev(host->mmc), "dma PaRAM alloc --> %d\n",
-				r);
-			break;
-		}
-		host->links[i] = r;
+	host->dma_tx =
+		dma_request_slave_channel_compat(mask, edma_filter_fn,
+				&host->txdma, mmc_dev(host->mmc), "tx");
+	if (!host->dma_tx) {
+		dev_err(mmc_dev(host->mmc), "Can't get dma_tx channel\n");
+		return -ENODEV;
+	}
+
+	host->dma_rx =
+		dma_request_slave_channel_compat(mask, edma_filter_fn,
+				&host->rxdma, mmc_dev(host->mmc), "rx");
+	if (!host->dma_rx) {
+		dev_err(mmc_dev(host->mmc), "Can't get dma_rx channel\n");
+		r = -ENODEV;
+		goto free_master_write;
 	}
-	host->n_link = i;
 
 	return 0;
 
 free_master_write:
-	edma_free_channel(host->txdma);
+	dma_release_channel(host->dma_tx);
 
 	return r;
 }
@@ -1264,16 +1161,86 @@
 	mmc_davinci_reset_ctrl(host, 0);
 }
 
-static int __init davinci_mmcsd_probe(struct platform_device *pdev)
+static struct platform_device_id davinci_mmc_devtype[] = {
+	{
+		.name	= "dm6441-mmc",
+		.driver_data = MMC_CTLR_VERSION_1,
+	}, {
+		.name	= "da830-mmc",
+		.driver_data = MMC_CTLR_VERSION_2,
+	},
+	{},
+};
+MODULE_DEVICE_TABLE(platform, davinci_mmc_devtype);
+
+static const struct of_device_id davinci_mmc_dt_ids[] = {
+	{
+		.compatible = "ti,dm6441-mmc",
+		.data = &davinci_mmc_devtype[MMC_CTLR_VERSION_1],
+	},
+	{
+		.compatible = "ti,da830-mmc",
+		.data = &davinci_mmc_devtype[MMC_CTLR_VERSION_2],
+	},
+	{},
+};
+MODULE_DEVICE_TABLE(of, davinci_mmc_dt_ids);
+
+static struct davinci_mmc_config
+	*mmc_parse_pdata(struct platform_device *pdev)
 {
+	struct device_node *np;
 	struct davinci_mmc_config *pdata = pdev->dev.platform_data;
+	const struct of_device_id *match =
+		of_match_device(of_match_ptr(davinci_mmc_dt_ids), &pdev->dev);
+	u32 data;
+
+	np = pdev->dev.of_node;
+	if (!np)
+		return pdata;
+
+	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+	if (!pdata) {
+		dev_err(&pdev->dev, "Failed to allocate memory for struct davinci_mmc_config\n");
+		goto nodata;
+	}
+
+	if (match)
+		pdev->id_entry = match->data;
+
+	if (of_property_read_u32(np, "max-frequency", &pdata->max_freq))
+		dev_info(&pdev->dev, "'max-frequency' property not specified, defaulting to 25MHz\n");
+
+	of_property_read_u32(np, "bus-width", &data);
+	switch (data) {
+	case 1:
+	case 4:
+	case 8:
+		pdata->wires = data;
+		break;
+	default:
+		pdata->wires = 1;
+		dev_info(&pdev->dev, "Unsupported buswidth, defaulting to 1 bit\n");
+	}
+nodata:
+	return pdata;
+}
+
+static int __init davinci_mmcsd_probe(struct platform_device *pdev)
+{
+	struct davinci_mmc_config *pdata = NULL;
 	struct mmc_davinci_host *host = NULL;
 	struct mmc_host *mmc = NULL;
 	struct resource *r, *mem = NULL;
 	int ret = 0, irq = 0;
 	size_t mem_size;
+	const struct platform_device_id *id_entry;
 
-	/* REVISIT:  when we're fully converted, fail if pdata is NULL */
+	pdata = mmc_parse_pdata(pdev);
+	if (pdata == NULL) {
+		dev_err(&pdev->dev, "Couldn't get platform data\n");
+		return -ENOENT;
+	}
 
 	ret = -ENODEV;
 	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -1297,13 +1264,15 @@
 
 	r = platform_get_resource(pdev, IORESOURCE_DMA, 0);
 	if (!r)
-		goto out;
-	host->rxdma = r->start;
+		dev_warn(&pdev->dev, "RX DMA resource not specified\n");
+	else
+		host->rxdma = r->start;
 
 	r = platform_get_resource(pdev, IORESOURCE_DMA, 1);
 	if (!r)
-		goto out;
-	host->txdma = r->start;
+		dev_warn(&pdev->dev, "TX DMA resource not specified\n");
+	else
+		host->txdma = r->start;
 
 	host->mem_res = mem;
 	host->base = ioremap(mem->start, mem_size);
@@ -1344,7 +1313,9 @@
 	if (pdata && (pdata->wires == 8))
 		mmc->caps |= (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA);
 
-	host->version = pdata->version;
+	id_entry = platform_get_device_id(pdev);
+	if (id_entry)
+		host->version = id_entry->driver_data;
 
 	mmc->ops = &mmc_davinci_ops;
 	mmc->f_min = 312500;
@@ -1359,7 +1330,7 @@
 	 * Each hw_seg uses one EDMA parameter RAM slot, always one
 	 * channel and then usually some linked slots.
 	 */
-	mmc->max_segs		= 1 + host->n_link;
+	mmc->max_segs		= MAX_NR_SG;
 
 	/* EDMA limit per hw segment (one or two MBytes) */
 	mmc->max_seg_size	= MAX_CCNT * rw_threshold;
@@ -1513,24 +1484,16 @@
 		.name	= "davinci_mmc",
 		.owner	= THIS_MODULE,
 		.pm	= davinci_mmcsd_pm_ops,
+		.of_match_table = of_match_ptr(davinci_mmc_dt_ids),
 	},
 	.remove		= __exit_p(davinci_mmcsd_remove),
+	.id_table	= davinci_mmc_devtype,
 };
 
-static int __init davinci_mmcsd_init(void)
-{
-	return platform_driver_probe(&davinci_mmcsd_driver,
-				     davinci_mmcsd_probe);
-}
-module_init(davinci_mmcsd_init);
-
-static void __exit davinci_mmcsd_exit(void)
-{
-	platform_driver_unregister(&davinci_mmcsd_driver);
-}
-module_exit(davinci_mmcsd_exit);
+module_platform_driver_probe(davinci_mmcsd_driver, davinci_mmcsd_probe);
 
 MODULE_AUTHOR("Texas Instruments India");
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("MMC/SD driver for Davinci MMC controller");
+MODULE_ALIAS("platform:davinci_mmc");
 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/dw_mmc.c linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/dw_mmc.c
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/dw_mmc.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/dw_mmc.c	2014-10-28 15:38:13.363879000 +0800
@@ -29,21 +29,24 @@
 #include <linux/irq.h>
 #include <linux/mmc/host.h>
 #include <linux/mmc/mmc.h>
+#include <linux/mmc/sd.h>
 #include <linux/mmc/dw_mmc.h>
 #include <linux/bitops.h>
 #include <linux/regulator/consumer.h>
 #include <linux/workqueue.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
 
 #include "dw_mmc.h"
 
 /* Common flag combinations */
 #define DW_MCI_DATA_ERROR_FLAGS	(SDMMC_INT_DTO | SDMMC_INT_DCRC | \
-				 SDMMC_INT_HTO | SDMMC_INT_SBE  | \
+				 SDMMC_INT_HTO | SDMMC_INT_SBE | \
 				 SDMMC_INT_EBE)
 #define DW_MCI_CMD_ERROR_FLAGS	(SDMMC_INT_RTO | SDMMC_INT_RCRC | \
 				 SDMMC_INT_RESP_ERR)
 #define DW_MCI_ERROR_FLAGS	(DW_MCI_DATA_ERROR_FLAGS | \
-				 DW_MCI_CMD_ERROR_FLAGS  | SDMMC_INT_HLE)
+				 DW_MCI_CMD_ERROR_FLAGS)
 #define DW_MCI_SEND_STATUS	1
 #define DW_MCI_RECV_STATUS	2
 #define DW_MCI_DMA_THRESHOLD	16
@@ -73,6 +76,8 @@
  * struct dw_mci_slot - MMC slot state
  * @mmc: The mmc_host representing this slot.
  * @host: The MMC controller this slot is using.
+ * @quirks: Slot-level quirks (DW_MCI_SLOT_QUIRK_XXX)
+ * @wp_gpio: If gpio_is_valid() we'll use this to read write protect.
  * @ctype: Card type for this slot.
  * @mrq: mmc_request currently being processed or waiting to be
  *	processed, or NULL when the slot is idle.
@@ -87,6 +92,9 @@
 	struct mmc_host		*mmc;
 	struct dw_mci		*host;
 
+	int			quirks;
+	int			wp_gpio;
+
 	u32			ctype;
 
 	struct mmc_request	*mrq;
@@ -100,7 +108,16 @@
 	int			last_detect_state;
 };
 
-static struct workqueue_struct *dw_mci_card_workqueue;
+static const u8 tuning_blk_pattern_4bit[] = {
+	0xff, 0x0f, 0xff, 0x00, 0xff, 0xcc, 0xc3, 0xcc,
+	0xc3, 0x3c, 0xcc, 0xff, 0xfe, 0xff, 0xfe, 0xef,
+	0xff, 0xdf, 0xff, 0xdd, 0xff, 0xfb, 0xff, 0xfb,
+	0xbf, 0xff, 0x7f, 0xff, 0x77, 0xf7, 0xbd, 0xef,
+	0xff, 0xf0, 0xff, 0xf0, 0x0f, 0xfc, 0xcc, 0x3c,
+	0xcc, 0x33, 0xcc, 0xcf, 0xff, 0xef, 0xff, 0xee,
+	0xff, 0xfd, 0xff, 0xfd, 0xdf, 0xff, 0xbf, 0xff,
+	0xbb, 0xff, 0xf7, 0xff, 0xf7, 0x7f, 0x7b, 0xde,
+};
 
 #if defined(CONFIG_DEBUG_FS)
 static int dw_mci_req_show(struct seq_file *s, void *v)
@@ -232,16 +249,21 @@
 static u32 dw_mci_prepare_command(struct mmc_host *mmc, struct mmc_command *cmd)
 {
 	struct mmc_data	*data;
+	struct dw_mci_slot *slot = mmc_priv(mmc);
+	const struct dw_mci_drv_data *drv_data = slot->host->drv_data;
 	u32 cmdr;
 	cmd->error = -EINPROGRESS;
 
 	cmdr = cmd->opcode;
 
-	if (cmdr == MMC_STOP_TRANSMISSION)
+	if (cmd->opcode == MMC_STOP_TRANSMISSION)
 		cmdr |= SDMMC_CMD_STOP;
 	else
 		cmdr |= SDMMC_CMD_PRV_DAT_WAIT;
 
+	if (cmd->opcode == SD_SWITCH_VOLTAGE)
+		cmdr |= SDMMC_CMD_VOLT_SW;
+
 	if (cmd->flags & MMC_RSP_PRESENT) {
 		/* We expect a response, so set this bit */
 		cmdr |= SDMMC_CMD_RESP_EXP;
@@ -261,6 +283,9 @@
 			cmdr |= SDMMC_CMD_DAT_WR;
 	}
 
+	if (drv_data && drv_data->prepare_command)
+		drv_data->prepare_command(slot->host, &cmdr);
+
 	return cmdr;
 }
 
@@ -268,14 +293,14 @@
 				 struct mmc_command *cmd, u32 cmd_flags)
 {
 	host->cmd = cmd;
-	dev_vdbg(&host->dev,
+	dev_vdbg(host->dev,
 		 "start command: ARGR=0x%08x CMDR=0x%08x\n",
 		 cmd->arg, cmd_flags);
 
 	mci_writel(host, CMDARG, cmd->arg);
 	wmb();
 
-	mci_writel(host, CMD, cmd_flags | SDMMC_CMD_START);
+	mci_writel(host, CMD, cmd_flags | SDMMC_CMD_START | SDMMC_CMD_HOLD);
 }
 
 static void send_stop_cmd(struct dw_mci *host, struct mmc_data *data)
@@ -310,7 +335,7 @@
 
 	if (data)
 		if (!data->host_cookie)
-			dma_unmap_sg(&host->dev,
+			dma_unmap_sg(host->dev,
 				     data->sg,
 				     data->sg_len,
 				     dw_mci_get_dma_dir(data));
@@ -336,7 +361,7 @@
 {
 	struct mmc_data *data = host->data;
 
-	dev_vdbg(&host->dev, "DMA complete\n");
+	dev_vdbg(host->dev, "DMA complete\n");
 
 	host->dma_ops->cleanup(host);
 
@@ -420,6 +445,8 @@
 	p->des3 = host->sg_dma;
 	p->des0 = IDMAC_DES0_ER;
 
+	mci_writel(host, BMOD, SDMMC_IDMAC_SWRESET);
+
 	/* Mask out interrupts - get Tx & Rx complete only */
 	mci_writel(host, IDINTEN, SDMMC_IDMAC_INT_NI | SDMMC_IDMAC_INT_RI |
 		   SDMMC_IDMAC_INT_TI);
@@ -429,7 +456,7 @@
 	return 0;
 }
 
-static struct dw_mci_dma_ops dw_mci_idmac_ops = {
+static const struct dw_mci_dma_ops dw_mci_idmac_ops = {
 	.init = dw_mci_idmac_init,
 	.start = dw_mci_idmac_start_dma,
 	.stop = dw_mci_idmac_stop_dma,
@@ -464,7 +491,7 @@
 			return -EINVAL;
 	}
 
-	sg_len = dma_map_sg(&host->dev,
+	sg_len = dma_map_sg(host->dev,
 			    data->sg,
 			    data->sg_len,
 			    dw_mci_get_dma_dir(data));
@@ -507,7 +534,7 @@
 		return;
 
 	if (data->host_cookie)
-		dma_unmap_sg(&slot->host->dev,
+		dma_unmap_sg(slot->host->dev,
 			     data->sg,
 			     data->sg_len,
 			     dw_mci_get_dma_dir(data));
@@ -533,7 +560,7 @@
 
 	host->using_dma = 1;
 
-	dev_vdbg(&host->dev,
+	dev_vdbg(host->dev,
 		 "sd sg_cpu: %#lx sg_dma: %#lx sg_len: %d\n",
 		 (unsigned long)host->sg_cpu, (unsigned long)host->sg_dma,
 		 sg_len);
@@ -611,20 +638,22 @@
 		cmd, arg, cmd_status);
 }
 
-static void dw_mci_setup_bus(struct dw_mci_slot *slot)
+static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit)
 {
 	struct dw_mci *host = slot->host;
 	u32 div;
+	u32 clk_en_a;
 
-	if (slot->clock != host->current_speed) {
-		if (host->bus_hz % slot->clock)
+	if (slot->clock != host->current_speed || force_clkinit) {
+		div = host->bus_hz / slot->clock;
+		if (host->bus_hz % slot->clock && host->bus_hz > slot->clock)
 			/*
 			 * move the + 1 after the divide to prevent
 			 * over-clocking the card.
 			 */
-			div = ((host->bus_hz / slot->clock) >> 1) + 1;
-		else
-			div = (host->bus_hz  / slot->clock) >> 1;
+			div += 1;
+
+		div = (host->bus_hz != slot->clock) ? DIV_ROUND_UP(div, 2) : 0;
 
 		dev_info(&slot->mmc->class_dev,
 			 "Bus speed (slot %d) = %dHz (slot req %dHz, actual %dHZ"
@@ -646,9 +675,11 @@
 		mci_send_cmd(slot,
 			     SDMMC_CMD_UPD_CLK | SDMMC_CMD_PRV_DAT_WAIT, 0);
 
-		/* enable clock */
-		mci_writel(host, CLKENA, ((SDMMC_CLKEN_ENABLE |
-			   SDMMC_CLKEN_LOW_PWR) << slot->id));
+		/* enable clock; only low power if no SDIO */
+		clk_en_a = SDMMC_CLKEN_ENABLE << slot->id;
+		if (!(mci_readl(host, INTMASK) & SDMMC_INT_SDIO(slot->id)))
+			clk_en_a |= SDMMC_CLKEN_LOW_PWR << slot->id;
+		mci_writel(host, CLKENA, clk_en_a);
 
 		/* inform CIU */
 		mci_send_cmd(slot,
@@ -673,9 +704,6 @@
 	if (host->pdata->select_slot)
 		host->pdata->select_slot(slot->id);
 
-	/* Slot specific timing and width adjustment */
-	dw_mci_setup_bus(slot);
-
 	host->cur_slot = slot;
 	host->mrq = mrq;
 
@@ -763,30 +791,28 @@
 static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 {
 	struct dw_mci_slot *slot = mmc_priv(mmc);
+	const struct dw_mci_drv_data *drv_data = slot->host->drv_data;
 	u32 regs;
 
-	/* set default 1 bit mode */
-	slot->ctype = SDMMC_CTYPE_1BIT;
-
 	switch (ios->bus_width) {
-	case MMC_BUS_WIDTH_1:
-		slot->ctype = SDMMC_CTYPE_1BIT;
-		break;
 	case MMC_BUS_WIDTH_4:
 		slot->ctype = SDMMC_CTYPE_4BIT;
 		break;
 	case MMC_BUS_WIDTH_8:
 		slot->ctype = SDMMC_CTYPE_8BIT;
 		break;
+	default:
+		/* set default 1 bit mode */
+		slot->ctype = SDMMC_CTYPE_1BIT;
 	}
 
 	regs = mci_readl(slot->host, UHS_REG);
 
 	/* DDR mode set */
 	if (ios->timing == MMC_TIMING_UHS_DDR50)
-		regs |= (0x1 << slot->id) << 16;
+		regs |= ((0x1 << slot->id) << 16);
 	else
-		regs &= ~(0x1 << slot->id) << 16;
+		regs &= ~((0x1 << slot->id) << 16);
 
 	mci_writel(slot->host, UHS_REG, regs);
 
@@ -798,9 +824,29 @@
 		slot->clock = ios->clock;
 	}
 
+	if (drv_data && drv_data->set_ios)
+		drv_data->set_ios(slot->host, ios);
+
+	/* Slot specific timing and width adjustment */
+	dw_mci_setup_bus(slot, false);
+
 	switch (ios->power_mode) {
 	case MMC_POWER_UP:
 		set_bit(DW_MMC_CARD_NEED_INIT, &slot->flags);
+		/* Power up slot */
+		if (slot->host->pdata->setpower)
+			slot->host->pdata->setpower(slot->id, mmc->ocr_avail);
+		regs = mci_readl(slot->host, PWREN);
+		regs |= (1 << slot->id);
+		mci_writel(slot->host, PWREN, regs);
+		break;
+	case MMC_POWER_OFF:
+		/* Power down slot */
+		if (slot->host->pdata->setpower)
+			slot->host->pdata->setpower(slot->id, 0);
+		regs = mci_readl(slot->host, PWREN);
+		regs &= ~(1 << slot->id);
+		mci_writel(slot->host, PWREN, regs);
 		break;
 	default:
 		break;
@@ -814,8 +860,12 @@
 	struct dw_mci_board *brd = slot->host->pdata;
 
 	/* Use platform get_ro function, else try on board write protect */
-	if (brd->get_ro)
+	if (slot->quirks & DW_MCI_SLOT_QUIRK_NO_WRITE_PROTECT)
+		read_only = 0;
+	else if (brd->get_ro)
 		read_only = brd->get_ro(slot->id);
+	else if (gpio_is_valid(slot->wp_gpio))
+		read_only = gpio_get_value(slot->wp_gpio);
 	else
 		read_only =
 			mci_readl(slot->host, WRTPRT) & (1 << slot->id) ? 1 : 0;
@@ -823,7 +873,8 @@
 	dev_dbg(&mmc->class_dev, "card is %s\n",
 		read_only ? "read-only" : "read-write");
 
-	return read_only;
+	//return read_only;
+	return 0;
 }
 
 static int dw_mci_get_cd(struct mmc_host *mmc)
@@ -849,6 +900,30 @@
 	return present;
 }
 
+/*
+ * Disable lower power mode.
+ *
+ * Low power mode will stop the card clock when idle.  According to the
+ * description of the CLKENA register we should disable low power mode
+ * for SDIO cards if we need SDIO interrupts to work.
+ *
+ * This function is fast if low power mode is already disabled.
+ */
+static void dw_mci_disable_low_power(struct dw_mci_slot *slot)
+{
+	struct dw_mci *host = slot->host;
+	u32 clk_en_a;
+	const u32 clken_low_pwr = SDMMC_CLKEN_LOW_PWR << slot->id;
+
+	clk_en_a = mci_readl(host, CLKENA);
+
+	if (clk_en_a & clken_low_pwr) {
+		mci_writel(host, CLKENA, clk_en_a & ~clken_low_pwr);
+		mci_send_cmd(slot, SDMMC_CMD_UPD_CLK |
+			     SDMMC_CMD_PRV_DAT_WAIT, 0);
+	}
+}
+
 static void dw_mci_enable_sdio_irq(struct mmc_host *mmc, int enb)
 {
 	struct dw_mci_slot *slot = mmc_priv(mmc);
@@ -858,12 +933,112 @@
 	/* Enable/disable Slot Specific SDIO interrupt */
 	int_mask = mci_readl(host, INTMASK);
 	if (enb) {
+		/*
+		 * Turn off low power mode if it was enabled.  This is a bit of
+		 * a heavy operation and we disable / enable IRQs a lot, so
+		 * we'll leave low power mode disabled and it will get
+		 * re-enabled again in dw_mci_setup_bus().
+		 */
+		dw_mci_disable_low_power(slot);
+
 		mci_writel(host, INTMASK,
-			   (int_mask | (1 << SDMMC_INT_SDIO(slot->id))));
+			   (int_mask | SDMMC_INT_SDIO(slot->id)));
 	} else {
 		mci_writel(host, INTMASK,
-			   (int_mask & ~(1 << SDMMC_INT_SDIO(slot->id))));
+			   (int_mask & ~SDMMC_INT_SDIO(slot->id)));
+	}
+}
+
+static int dw_mci_start_signal_voltage_switch(struct mmc_host *mmc,
+	struct mmc_ios *ios)
+{
+	struct dw_mci_slot *slot = mmc_priv(mmc);
+	struct dw_mci *host = slot->host;
+	u32 regs;
+
+	regs = mci_readl(host, UHS_REG);
+
+	if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_180) {
+		mci_writel(host, CLKENA, 0);
+		mci_send_cmd(slot, SDMMC_CMD_UPD_CLK | SDMMC_CMD_VOLT_SW, 0);
+
+		mci_writel(host, GPIO, 0x33300);
+		mci_writel(host, UHS_REG, (regs | (1 << slot->id)));
+		mdelay(500);
+
+		mci_writel(host, CLKENA, (SDMMC_CLKEN_ENABLE << slot->id));
+		mci_send_cmd(slot, SDMMC_CMD_UPD_CLK | SDMMC_CMD_VOLT_SW, 0);
+		mdelay(50);
+	} else {
+		mci_writel(host, GPIO, 0);
+		mci_writel(host, UHS_REG, (regs & (~(1 << slot->id))));
+		mdelay(50);
+	}
+	return 0;
+}
+
+static int dw_mci_execute_tuning(struct mmc_host *mmc, u32 opcode)
+{
+	struct dw_mci_slot *slot = mmc_priv(mmc);
+	struct dw_mci *host = slot->host;
+	int blksz = sizeof(tuning_blk_pattern_4bit);
+	u8 *blk_test;
+	int smp, num, ok;
+	u32 reg;
+
+	blk_test = kmalloc(blksz, GFP_KERNEL);
+	if (!blk_test)
+		return -ENOMEM;
+
+	reg = mci_readl(host, UHS_REG_EXT) & 0xC380FFFF;
+
+	for (smp = 0, num = 0; smp < 8; smp++) {
+		struct mmc_request mrq = {NULL};
+		struct mmc_command cmd = {0};
+		struct mmc_command stop = {0};
+		struct mmc_data data = {0};
+		struct scatterlist sg;
+
+		cmd.opcode = opcode;
+		cmd.arg = 0;
+		cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
+
+		stop.opcode = MMC_STOP_TRANSMISSION;
+		stop.arg = 0;
+		stop.flags = MMC_RSP_R1B | MMC_CMD_AC;
+
+		data.blksz = blksz;
+		data.blocks = 1;
+		data.flags = MMC_DATA_READ;
+		data.sg = &sg;
+		data.sg_len = 1;
+
+		sg_init_one(&sg, blk_test, blksz);
+		mrq.cmd = &cmd;
+		mrq.stop = &stop;
+		mrq.data = &data;
+		host->mrq = &mrq;
+
+		mci_writel(host, UHS_REG_EXT, reg | (smp << SDMMC_UHS_EXT_SMP_SHIFT));
+		mci_writel(host, UHS_REG_EXT, reg | (smp << SDMMC_UHS_EXT_SMP_SHIFT) | SDMMC_UHS_EXT_CLK_EN);
+
+		mmc_wait_for_req(mmc, &mrq);
+
+		if (!cmd.error && !data.error &&
+			!memcmp(blk_test, tuning_blk_pattern_4bit, blksz)) {
+			ok = smp;
+			num ++;
+		}
+
+		if (num == 3) {
+			ok = smp - 1;
+			break;
+		}
 	}
+
+	mci_writel(host, UHS_REG_EXT, reg | (ok << SDMMC_UHS_EXT_SMP_SHIFT));
+	mci_writel(host, UHS_REG_EXT, reg | (ok << SDMMC_UHS_EXT_SMP_SHIFT) | SDMMC_UHS_EXT_CLK_EN);
+	return 0;
 }
 
 static const struct mmc_host_ops dw_mci_ops = {
@@ -874,6 +1049,8 @@
 	.get_ro			= dw_mci_get_ro,
 	.get_cd			= dw_mci_get_cd,
 	.enable_sdio_irq	= dw_mci_enable_sdio_irq,
+	.execute_tuning		= dw_mci_execute_tuning,
+	.start_signal_voltage_switch = dw_mci_start_signal_voltage_switch,
 };
 
 static void dw_mci_request_end(struct dw_mci *host, struct mmc_request *mrq)
@@ -891,12 +1068,12 @@
 		slot = list_entry(host->queue.next,
 				  struct dw_mci_slot, queue_node);
 		list_del(&slot->queue_node);
-		dev_vdbg(&host->dev, "list not empty: %s is next\n",
+		dev_vdbg(host->dev, "list not empty: %s is next\n",
 			 mmc_hostname(slot->mmc));
 		host->state = STATE_SENDING_CMD;
 		dw_mci_start_request(host, slot);
 	} else {
-		dev_vdbg(&host->dev, "list empty\n");
+		dev_vdbg(host->dev, "list empty\n");
 		host->state = STATE_IDLE;
 	}
 
@@ -941,8 +1118,8 @@
 			mdelay(20);
 
 		if (cmd->data) {
-			host->data = NULL;
 			dw_mci_stop_dma(host);
+			host->data = NULL;
 		}
 	}
 }
@@ -1035,7 +1212,7 @@
 					data->bytes_xfered = 0;
 					data->error = -ETIMEDOUT;
 				} else {
-					dev_err(&host->dev,
+					dev_err(host->dev,
 						"data FIFO error "
 						"(status=%08x)\n",
 						status);
@@ -1138,12 +1315,15 @@
 
 static void dw_mci_push_data16(struct dw_mci *host, void *buf, int cnt)
 {
+	struct mmc_data *data = host->data;
+	int init_cnt = cnt;
+
 	/* try and push anything in the part_buf */
 	if (unlikely(host->part_buf_count)) {
 		int len = dw_mci_push_part_bytes(host, buf, cnt);
 		buf += len;
 		cnt -= len;
-		if (!sg_next(host->sg) || host->part_buf_count == 2) {
+		if (host->part_buf_count == 2) {
 			mci_writew(host, DATA(host->data_offset),
 					host->part_buf16);
 			host->part_buf_count = 0;
@@ -1176,9 +1356,11 @@
 	/* put anything remaining in the part_buf */
 	if (cnt) {
 		dw_mci_set_part_bytes(host, buf, cnt);
-		if (!sg_next(host->sg))
+		 /* Push data if we have reached the expected data length */
+		if ((data->bytes_xfered + init_cnt) ==
+		    (data->blksz * data->blocks))
 			mci_writew(host, DATA(host->data_offset),
-					host->part_buf16);
+				   host->part_buf16);
 	}
 }
 
@@ -1216,12 +1398,15 @@
 
 static void dw_mci_push_data32(struct dw_mci *host, void *buf, int cnt)
 {
+	struct mmc_data *data = host->data;
+	int init_cnt = cnt;
+
 	/* try and push anything in the part_buf */
 	if (unlikely(host->part_buf_count)) {
 		int len = dw_mci_push_part_bytes(host, buf, cnt);
 		buf += len;
 		cnt -= len;
-		if (!sg_next(host->sg) || host->part_buf_count == 4) {
+		if (host->part_buf_count == 4) {
 			mci_writel(host, DATA(host->data_offset),
 					host->part_buf32);
 			host->part_buf_count = 0;
@@ -1254,9 +1439,11 @@
 	/* put anything remaining in the part_buf */
 	if (cnt) {
 		dw_mci_set_part_bytes(host, buf, cnt);
-		if (!sg_next(host->sg))
+		 /* Push data if we have reached the expected data length */
+		if ((data->bytes_xfered + init_cnt) ==
+		    (data->blksz * data->blocks))
 			mci_writel(host, DATA(host->data_offset),
-						host->part_buf32);
+				   host->part_buf32);
 	}
 }
 
@@ -1294,13 +1481,17 @@
 
 static void dw_mci_push_data64(struct dw_mci *host, void *buf, int cnt)
 {
+	struct mmc_data *data = host->data;
+	int init_cnt = cnt;
+
 	/* try and push anything in the part_buf */
 	if (unlikely(host->part_buf_count)) {
 		int len = dw_mci_push_part_bytes(host, buf, cnt);
 		buf += len;
 		cnt -= len;
-		if (!sg_next(host->sg) || host->part_buf_count == 8) {
-			mci_writew(host, DATA(host->data_offset),
+
+		if (host->part_buf_count == 8) {
+			mci_writeq(host, DATA(host->data_offset),
 					host->part_buf);
 			host->part_buf_count = 0;
 		}
@@ -1332,9 +1523,11 @@
 	/* put anything remaining in the part_buf */
 	if (cnt) {
 		dw_mci_set_part_bytes(host, buf, cnt);
-		if (!sg_next(host->sg))
+		/* Push data if we have reached the expected data length */
+		if ((data->bytes_xfered + init_cnt) ==
+		    (data->blksz * data->blocks))
 			mci_writeq(host, DATA(host->data_offset),
-					host->part_buf);
+				   host->part_buf);
 	}
 }
 
@@ -1385,7 +1578,7 @@
 	host->pull_data(host, buf, cnt);
 }
 
-static void dw_mci_read_data_pio(struct dw_mci *host)
+static void dw_mci_read_data_pio(struct dw_mci *host, bool dto)
 {
 	struct sg_mapping_iter *sg_miter = &host->sg_miter;
 	void *buf;
@@ -1393,14 +1586,14 @@
 	struct mmc_data	*data = host->data;
 	int shift = host->data_shift;
 	u32 status;
-	unsigned int nbytes = 0, len;
+	unsigned int len;
 	unsigned int remain, fcnt;
 
 	do {
 		if (!sg_miter_next(sg_miter))
 			goto done;
 
-		host->sg = sg_miter->__sg;
+		host->sg = sg_miter->piter.sg;
 		buf = sg_miter->addr;
 		remain = sg_miter->length;
 		offset = 0;
@@ -1412,28 +1605,17 @@
 			if (!len)
 				break;
 			dw_mci_pull_data(host, (void *)(buf + offset), len);
+			data->bytes_xfered += len;
 			offset += len;
-			nbytes += len;
 			remain -= len;
 		} while (remain);
-		sg_miter->consumed = offset;
 
+		sg_miter->consumed = offset;
 		status = mci_readl(host, MINTSTS);
 		mci_writel(host, RINTSTS, SDMMC_INT_RXDR);
-		if (status & DW_MCI_DATA_ERROR_FLAGS) {
-			host->data_status = status;
-			data->bytes_xfered += nbytes;
-			sg_miter_stop(sg_miter);
-			host->sg = NULL;
-			smp_wmb();
-
-			set_bit(EVENT_DATA_ERROR, &host->pending_events);
-
-			tasklet_schedule(&host->tasklet);
-			return;
-		}
-	} while (status & SDMMC_INT_RXDR); /*if the RXDR is ready read again*/
-	data->bytes_xfered += nbytes;
+	/* if the RXDR is ready read again */
+	} while ((status & SDMMC_INT_RXDR) ||
+		 (dto && SDMMC_GET_FCNT(mci_readl(host, STATUS))));
 
 	if (!remain) {
 		if (!sg_miter_next(sg_miter))
@@ -1444,7 +1626,6 @@
 	return;
 
 done:
-	data->bytes_xfered += nbytes;
 	sg_miter_stop(sg_miter);
 	host->sg = NULL;
 	smp_wmb();
@@ -1459,7 +1640,7 @@
 	struct mmc_data	*data = host->data;
 	int shift = host->data_shift;
 	u32 status;
-	unsigned int nbytes = 0, len;
+	unsigned int len;
 	unsigned int fifo_depth = host->fifo_depth;
 	unsigned int remain, fcnt;
 
@@ -1467,7 +1648,7 @@
 		if (!sg_miter_next(sg_miter))
 			goto done;
 
-		host->sg = sg_miter->__sg;
+		host->sg = sg_miter->piter.sg;
 		buf = sg_miter->addr;
 		remain = sg_miter->length;
 		offset = 0;
@@ -1480,29 +1661,15 @@
 			if (!len)
 				break;
 			host->push_data(host, (void *)(buf + offset), len);
+			data->bytes_xfered += len;
 			offset += len;
-			nbytes += len;
 			remain -= len;
 		} while (remain);
-		sg_miter->consumed = offset;
 
+		sg_miter->consumed = offset;
 		status = mci_readl(host, MINTSTS);
 		mci_writel(host, RINTSTS, SDMMC_INT_TXDR);
-		if (status & DW_MCI_DATA_ERROR_FLAGS) {
-			host->data_status = status;
-			data->bytes_xfered += nbytes;
-			sg_miter_stop(sg_miter);
-			host->sg = NULL;
-
-			smp_wmb();
-
-			set_bit(EVENT_DATA_ERROR, &host->pending_events);
-
-			tasklet_schedule(&host->tasklet);
-			return;
-		}
 	} while (status & SDMMC_INT_TXDR); /* if TXDR write again */
-	data->bytes_xfered += nbytes;
 
 	if (!remain) {
 		if (!sg_miter_next(sg_miter))
@@ -1513,7 +1680,6 @@
 	return;
 
 done:
-	data->bytes_xfered += nbytes;
 	sg_miter_stop(sg_miter);
 	host->sg = NULL;
 	smp_wmb();
@@ -1534,13 +1700,23 @@
 static irqreturn_t dw_mci_interrupt(int irq, void *dev_id)
 {
 	struct dw_mci *host = dev_id;
-	u32 status, pending;
-	unsigned int pass_count = 0;
+	u32 pending, cmd;
 	int i;
 
-	do {
-		status = mci_readl(host, RINTSTS);
-		pending = mci_readl(host, MINTSTS); /* read-only mask reg */
+	cmd = mci_readl(host, CMD);
+	if (cmd & SDMMC_CMD_VOLT_SW) {
+		pending = mci_readl(host, MINTSTS);
+
+		mci_writel(host, CMD, 0);
+		if (pending & SDMMC_INT_HTO) {
+			mci_writel(host, RINTSTS, SDMMC_INT_HTO);
+			dw_mci_cmd_interrupt(host, pending);
+		}
+	}
+
+	pending = mci_readl(host, MINTSTS); /* read-only mask reg */
+
+	if (pending) {
 
 		/*
 		 * DTO fix - version 2.10a and below, and only if internal DMA
@@ -1552,12 +1728,9 @@
 				pending |= SDMMC_INT_DATA_OVER;
 		}
 
-		if (!pending)
-			break;
-
 		if (pending & DW_MCI_CMD_ERROR_FLAGS) {
 			mci_writel(host, RINTSTS, DW_MCI_CMD_ERROR_FLAGS);
-			host->cmd_status = status;
+			host->cmd_status = pending;
 			smp_wmb();
 			set_bit(EVENT_CMD_COMPLETE, &host->pending_events);
 		}
@@ -1565,22 +1738,20 @@
 		if (pending & DW_MCI_DATA_ERROR_FLAGS) {
 			/* if there is an error report DATA_ERROR */
 			mci_writel(host, RINTSTS, DW_MCI_DATA_ERROR_FLAGS);
-			host->data_status = status;
+			host->data_status = pending;
 			smp_wmb();
 			set_bit(EVENT_DATA_ERROR, &host->pending_events);
-			if (!(pending & (SDMMC_INT_DTO | SDMMC_INT_DCRC |
-					 SDMMC_INT_SBE | SDMMC_INT_EBE)))
-				tasklet_schedule(&host->tasklet);
+			tasklet_schedule(&host->tasklet);
 		}
 
 		if (pending & SDMMC_INT_DATA_OVER) {
 			mci_writel(host, RINTSTS, SDMMC_INT_DATA_OVER);
 			if (!host->data_status)
-				host->data_status = status;
+				host->data_status = pending;
 			smp_wmb();
 			if (host->dir_status == DW_MCI_RECV_STATUS) {
 				if (host->sg != NULL)
-					dw_mci_read_data_pio(host);
+					dw_mci_read_data_pio(host, true);
 			}
 			set_bit(EVENT_DATA_COMPLETE, &host->pending_events);
 			tasklet_schedule(&host->tasklet);
@@ -1589,7 +1760,7 @@
 		if (pending & SDMMC_INT_RXDR) {
 			mci_writel(host, RINTSTS, SDMMC_INT_RXDR);
 			if (host->dir_status == DW_MCI_RECV_STATUS && host->sg)
-				dw_mci_read_data_pio(host);
+				dw_mci_read_data_pio(host, false);
 		}
 
 		if (pending & SDMMC_INT_TXDR) {
@@ -1600,12 +1771,12 @@
 
 		if (pending & SDMMC_INT_CMD_DONE) {
 			mci_writel(host, RINTSTS, SDMMC_INT_CMD_DONE);
-			dw_mci_cmd_interrupt(host, status);
+			dw_mci_cmd_interrupt(host, pending);
 		}
 
 		if (pending & SDMMC_INT_CD) {
 			mci_writel(host, RINTSTS, SDMMC_INT_CD);
-			queue_work(dw_mci_card_workqueue, &host->card_work);
+			queue_work(host->card_workqueue, &host->card_work);
 		}
 
 		/* Handle SDIO Interrupts */
@@ -1617,7 +1788,7 @@
 			}
 		}
 
-	} while (pass_count++ < 5);
+	}
 
 #ifdef CONFIG_MMC_DW_IDMAC
 	/* Handle DMA interrupts */
@@ -1625,7 +1796,6 @@
 	if (pending & (SDMMC_IDMAC_INT_TI | SDMMC_IDMAC_INT_RI)) {
 		mci_writel(host, IDSTS, SDMMC_IDMAC_INT_TI | SDMMC_IDMAC_INT_RI);
 		mci_writel(host, IDSTS, SDMMC_IDMAC_INT_NI);
-		set_bit(EVENT_DATA_COMPLETE, &host->pending_events);
 		host->dma_ops->complete(host);
 	}
 #endif
@@ -1650,10 +1820,6 @@
 			dev_dbg(&slot->mmc->class_dev, "card %s\n",
 				present ? "inserted" : "removed");
 
-			/* Power up slot (before spin_lock, may sleep) */
-			if (present != 0 && host->pdata->setpower)
-				host->pdata->setpower(slot->id, mmc->ocr_avail);
-
 			spin_lock_bh(&host->lock);
 
 			/* Card change detected */
@@ -1727,7 +1893,8 @@
 
 #ifdef CONFIG_MMC_DW_IDMAC
 				ctrl = mci_readl(host, BMOD);
-				ctrl |= 0x01; /* Software reset of DMA */
+				/* Software reset of DMA */
+				ctrl |= SDMMC_IDMAC_SWRESET;
 				mci_writel(host, BMOD, ctrl);
 #endif
 
@@ -1735,10 +1902,6 @@
 
 			spin_unlock_bh(&host->lock);
 
-			/* Power down slot (after spin_unlock, may sleep) */
-			if (present == 0 && host->pdata->setpower)
-				host->pdata->setpower(slot->id, 0);
-
 			present = dw_mci_get_cd(mmc);
 		}
 
@@ -1747,12 +1910,116 @@
 	}
 }
 
-static int __init dw_mci_init_slot(struct dw_mci *host, unsigned int id)
+#ifdef CONFIG_OF
+/* given a slot id, find out the device node representing that slot */
+static struct device_node *dw_mci_of_find_slot_node(struct device *dev, u8 slot)
+{
+	struct device_node *np;
+	const __be32 *addr;
+	int len;
+
+	if (!dev || !dev->of_node)
+		return NULL;
+
+	for_each_child_of_node(dev->of_node, np) {
+		addr = of_get_property(np, "reg", &len);
+		if (!addr || (len < sizeof(int)))
+			continue;
+		if (be32_to_cpup(addr) == slot)
+			return np;
+	}
+	return NULL;
+}
+
+static struct dw_mci_of_slot_quirks {
+	char *quirk;
+	int id;
+} of_slot_quirks[] = {
+	{
+		.quirk	= "disable-wp",
+		.id	= DW_MCI_SLOT_QUIRK_NO_WRITE_PROTECT,
+	},
+};
+
+static int dw_mci_of_get_slot_quirks(struct device *dev, u8 slot)
+{
+	struct device_node *np = dw_mci_of_find_slot_node(dev, slot);
+	int quirks = 0;
+	int idx;
+
+	/* get quirks */
+	for (idx = 0; idx < ARRAY_SIZE(of_slot_quirks); idx++)
+		if (of_get_property(np, of_slot_quirks[idx].quirk, NULL))
+			quirks |= of_slot_quirks[idx].id;
+
+	return quirks;
+}
+
+/* find out bus-width for a given slot */
+static u32 dw_mci_of_get_bus_wd(struct device *dev, u8 slot)
+{
+	struct device_node *np = dw_mci_of_find_slot_node(dev, slot);
+	u32 bus_wd = 1;
+
+	if (!np)
+		return 1;
+
+	if (of_property_read_u32(np, "bus-width", &bus_wd))
+		dev_err(dev, "bus-width property not found, assuming width"
+			       " as 1\n");
+	return bus_wd;
+}
+
+/* find the write protect gpio for a given slot; or -1 if none specified */
+static int dw_mci_of_get_wp_gpio(struct device *dev, u8 slot)
+{
+	struct device_node *np = dw_mci_of_find_slot_node(dev, slot);
+	int gpio;
+
+	if (!np)
+		return -EINVAL;
+
+	gpio = of_get_named_gpio(np, "wp-gpios", 0);
+
+	/* Having a missing entry is valid; return silently */
+	if (!gpio_is_valid(gpio))
+		return -EINVAL;
+
+	if (devm_gpio_request(dev, gpio, "dw-mci-wp")) {
+		dev_warn(dev, "gpio [%d] request failed\n", gpio);
+		return -EINVAL;
+	}
+
+	return gpio;
+}
+#else /* CONFIG_OF */
+static int dw_mci_of_get_slot_quirks(struct device *dev, u8 slot)
+{
+	return 0;
+}
+static u32 dw_mci_of_get_bus_wd(struct device *dev, u8 slot)
+{
+	return 1;
+}
+static struct device_node *dw_mci_of_find_slot_node(struct device *dev, u8 slot)
+{
+	return NULL;
+}
+static int dw_mci_of_get_wp_gpio(struct device *dev, u8 slot)
+{
+	return -EINVAL;
+}
+#endif /* CONFIG_OF */
+
+static int dw_mci_init_slot(struct dw_mci *host, unsigned int id)
 {
 	struct mmc_host *mmc;
 	struct dw_mci_slot *slot;
+	const struct dw_mci_drv_data *drv_data = host->drv_data;
+	int ctrl_id, ret;
+	u8 bus_width;
 
-	mmc = mmc_alloc_host(sizeof(struct dw_mci_slot), &host->dev);
+	mmc = mmc_alloc_host(sizeof(struct dw_mci_slot), host->dev);
 	if (!mmc)
 		return -ENOMEM;
 
@@ -1760,6 +2027,9 @@
 	slot->id = id;
 	slot->mmc = mmc;
 	slot->host = host;
+	host->slot[id] = slot;
+
+	slot->quirks = dw_mci_of_get_slot_quirks(host->dev, slot->id);
 
 	mmc->ops = &dw_mci_ops;
 	mmc->f_min = DIV_ROUND_UP(host->bus_hz, 510);
@@ -1780,21 +2050,39 @@
 	if (host->pdata->caps)
 		mmc->caps = host->pdata->caps;
 
+	if (host->pdata->pm_caps)
+		mmc->pm_caps = host->pdata->pm_caps;
+
+	if (host->dev->of_node) {
+		ctrl_id = of_alias_get_id(host->dev->of_node, "mshc");
+		if (ctrl_id < 0)
+			ctrl_id = 0;
+	} else {
+		ctrl_id = to_platform_device(host->dev)->id;
+	}
+	if (drv_data && drv_data->caps)
+		mmc->caps |= drv_data->caps[ctrl_id];
+
 	if (host->pdata->caps2)
 		mmc->caps2 = host->pdata->caps2;
 
 	if (host->pdata->get_bus_wd)
-		if (host->pdata->get_bus_wd(slot->id) >= 4)
-			mmc->caps |= MMC_CAP_4_BIT_DATA;
+		bus_width = host->pdata->get_bus_wd(slot->id);
+	else if (host->dev->of_node)
+		bus_width = dw_mci_of_get_bus_wd(host->dev, slot->id);
+	else
+		bus_width = 1;
+
+	switch (bus_width) {
+	case 8:
+		mmc->caps |= MMC_CAP_8_BIT_DATA;
+	case 4:
+		mmc->caps |= MMC_CAP_4_BIT_DATA;
+	}
 
 	if (host->pdata->quirks & DW_MCI_QUIRK_HIGHSPEED)
 		mmc->caps |= MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED;
 
-	if (mmc->caps2 & MMC_CAP2_POWEROFF_NOTIFY)
-		mmc->power_notify_type = MMC_HOST_PW_NOTIFY_SHORT;
-	else
-		mmc->power_notify_type = MMC_HOST_PW_NOTIFY_NONE;
-
 	if (host->pdata->blk_settings) {
 		mmc->max_segs = host->pdata->blk_settings->max_segs;
 		mmc->max_blk_size = host->pdata->blk_settings->max_blk_size;
@@ -1818,20 +2106,29 @@
 #endif /* CONFIG_MMC_DW_IDMAC */
 	}
 
-	host->vmmc = regulator_get(mmc_dev(mmc), "vmmc");
+	host->vmmc = devm_regulator_get(mmc_dev(mmc), "vmmc");
 	if (IS_ERR(host->vmmc)) {
 		pr_info("%s: no vmmc regulator found\n", mmc_hostname(mmc));
 		host->vmmc = NULL;
-	} else
-		regulator_enable(host->vmmc);
+	} else {
+		ret = regulator_enable(host->vmmc);
+		if (ret) {
+			dev_err(host->dev,
+				"failed to enable regulator: %d\n", ret);
+			goto err_setup_bus;
+		}
+	}
 
 	if (dw_mci_get_cd(mmc))
 		set_bit(DW_MMC_CARD_PRESENT, &slot->flags);
 	else
 		clear_bit(DW_MMC_CARD_PRESENT, &slot->flags);
 
-	host->slot[id] = slot;
-	mmc_add_host(mmc);
+	slot->wp_gpio = dw_mci_of_get_wp_gpio(host->dev, slot->id);
+
+	ret = mmc_add_host(mmc);
+	if (ret)
+		goto err_setup_bus;
 
 #if defined(CONFIG_DEBUG_FS)
 	dw_mci_init_debugfs(slot);
@@ -1844,9 +2141,13 @@
 	 * Card may have been plugged in prior to boot so we
 	 * need to run the detect tasklet
 	 */
-	queue_work(dw_mci_card_workqueue, &host->card_work);
+	queue_work(host->card_workqueue, &host->card_work);
 
 	return 0;
+
+err_setup_bus:
+	mmc_free_host(mmc);
+	return -EINVAL;
 }
 
 static void dw_mci_cleanup_slot(struct dw_mci_slot *slot, unsigned int id)
@@ -1864,10 +2165,10 @@
 static void dw_mci_init_dma(struct dw_mci *host)
 {
 	/* Alloc memory for sg translation */
-	host->sg_cpu = dma_alloc_coherent(&host->dev, PAGE_SIZE,
+	host->sg_cpu = dmam_alloc_coherent(host->dev, PAGE_SIZE,
 					  &host->sg_dma, GFP_KERNEL);
 	if (!host->sg_cpu) {
-		dev_err(&host->dev, "%s: could not alloc DMA memory\n",
+		dev_err(host->dev, "%s: could not alloc DMA memory\n",
 			__func__);
 		goto no_dma;
 	}
@@ -1875,7 +2176,7 @@
 	/* Determine which DMA interface to use */
 #ifdef CONFIG_MMC_DW_IDMAC
 	host->dma_ops = &dw_mci_idmac_ops;
-	dev_info(&host->dev, "Using internal DMA controller.\n");
+	dev_info(host->dev, "Using internal DMA controller.\n");
 #endif
 
 	if (!host->dma_ops)
@@ -1884,12 +2185,12 @@
 	if (host->dma_ops->init && host->dma_ops->start &&
 	    host->dma_ops->stop && host->dma_ops->cleanup) {
 		if (host->dma_ops->init(host)) {
-			dev_err(&host->dev, "%s: Unable to initialize "
+			dev_err(host->dev, "%s: Unable to initialize "
 				"DMA Controller.\n", __func__);
 			goto no_dma;
 		}
 	} else {
-		dev_err(&host->dev, "DMA initialization not found.\n");
+		dev_err(host->dev, "DMA initialization not found.\n");
 		goto no_dma;
 	}
 
@@ -1897,7 +2198,7 @@
 	return;
 
 no_dma:
-	dev_info(&host->dev, "Using PIO mode.\n");
+	dev_info(host->dev, "Using PIO mode.\n");
 	host->use_dma = 0;
 	return;
 }
@@ -1923,38 +2224,151 @@
 	return false;
 }
 
+#ifdef CONFIG_OF
+static struct dw_mci_of_quirks {
+	char *quirk;
+	int id;
+} of_quirks[] = {
+	{
+		.quirk	= "supports-highspeed",
+		.id	= DW_MCI_QUIRK_HIGHSPEED,
+	}, {
+		.quirk	= "broken-cd",
+		.id	= DW_MCI_QUIRK_BROKEN_CARD_DETECTION,
+	},
+};
+
+static struct dw_mci_board *dw_mci_parse_dt(struct dw_mci *host)
+{
+	struct dw_mci_board *pdata;
+	struct device *dev = host->dev;
+	struct device_node *np = dev->of_node;
+	const struct dw_mci_drv_data *drv_data = host->drv_data;
+	int idx, ret;
+
+	pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
+	if (!pdata) {
+		dev_err(dev, "could not allocate memory for pdata\n");
+		return ERR_PTR(-ENOMEM);
+	}
+
+	/* find out number of slots supported */
+	if (of_property_read_u32(dev->of_node, "num-slots",
+				&pdata->num_slots)) {
+		dev_info(dev, "num-slots property not found, "
+				"assuming 1 slot is available\n");
+		pdata->num_slots = 1;
+	}
+
+	/* get quirks */
+	for (idx = 0; idx < ARRAY_SIZE(of_quirks); idx++)
+		if (of_get_property(np, of_quirks[idx].quirk, NULL))
+			pdata->quirks |= of_quirks[idx].id;
+
+	if (of_property_read_u32(np, "fifo-depth", &pdata->fifo_depth))
+		dev_info(dev, "fifo-depth property not found, using "
+				"value of FIFOTH register as default\n");
+
+	of_property_read_u32(np, "card-detect-delay", &pdata->detect_delay_ms);
+
+	if (drv_data && drv_data->parse_dt) {
+		ret = drv_data->parse_dt(host);
+		if (ret)
+			return ERR_PTR(ret);
+	}
+
+	if (of_find_property(np, "keep-power-in-suspend", NULL))
+		pdata->pm_caps |= MMC_PM_KEEP_POWER;
+
+	if (of_find_property(np, "enable-sdio-wakeup", NULL))
+		pdata->pm_caps |= MMC_PM_WAKE_SDIO_IRQ;
+
+	return pdata;
+}
+
+#else /* CONFIG_OF */
+static struct dw_mci_board *dw_mci_parse_dt(struct dw_mci *host)
+{
+	return ERR_PTR(-EINVAL);
+}
+#endif /* CONFIG_OF */
+
 int dw_mci_probe(struct dw_mci *host)
 {
+	const struct dw_mci_drv_data *drv_data = host->drv_data;
 	int width, i, ret = 0;
 	u32 fifo_size;
+	int init_slots = 0;
 
-	if (!host->pdata || !host->pdata->init) {
-		dev_err(&host->dev,
-			"Platform data must supply init function\n");
-		return -ENODEV;
+	if (!host->pdata) {
+		host->pdata = dw_mci_parse_dt(host);
+		if (IS_ERR(host->pdata)) {
+			dev_err(host->dev, "platform data not available\n");
+			return -EINVAL;
+		}
 	}
 
 	if (!host->pdata->select_slot && host->pdata->num_slots > 1) {
-		dev_err(&host->dev,
+		dev_err(host->dev,
 			"Platform data must supply select_slot function\n");
 		return -ENODEV;
 	}
 
-	if (!host->pdata->bus_hz) {
-		dev_err(&host->dev,
+	host->biu_clk = clk_get(NULL, "biu");
+	if (IS_ERR(host->biu_clk)) {
+		dev_dbg(host->dev, "biu clock not available\n");
+	} else {
+		ret = clk_prepare_enable(host->biu_clk);
+		if (ret) {
+			dev_err(host->dev, "failed to enable biu clock\n");
+			return ret;
+		}
+	}
+
+	host->ciu_clk = clk_get(NULL, "ciu");
+	if (IS_ERR(host->ciu_clk)) {
+		dev_dbg(host->dev, "ciu clock not available\n");
+	} else {
+		ret = clk_prepare_enable(host->ciu_clk);
+		if (ret) {
+			dev_err(host->dev, "failed to enable ciu clock\n");
+			goto err_clk_biu;
+		}
+	}
+
+	if (IS_ERR(host->ciu_clk))
+		host->bus_hz = host->pdata->bus_hz;
+	else
+		host->bus_hz = clk_get_rate(host->ciu_clk);
+
+	if (drv_data && drv_data->setup_clock) {
+		ret = drv_data->setup_clock(host);
+		if (ret) {
+			dev_err(host->dev,
+				"implementation specific clock setup failed\n");
+			goto err_clk_ciu;
+		}
+	}
+
+	if (!host->bus_hz) {
+		dev_err(host->dev,
 			"Platform data must supply bus speed\n");
-		return -ENODEV;
+		ret = -ENODEV;
+		goto err_clk_ciu;
 	}
 
-	host->bus_hz = host->pdata->bus_hz;
 	host->quirks = host->pdata->quirks;
 
 	spin_lock_init(&host->lock);
 	INIT_LIST_HEAD(&host->queue);
 
-
-	host->dma_ops = host->pdata->dma_ops;
-	dw_mci_init_dma(host);
+	if (host->bus_hz > 90000000) {
+		mci_writel(host, UHS_REG_EXT, 0xC0000000 | (2 << SDMMC_UHS_EXT_DRV_SHIFT));
+		mci_writel(host, UHS_REG_EXT, 0xC0000000 | (2 << SDMMC_UHS_EXT_DRV_SHIFT) | SDMMC_UHS_EXT_CLK_EN);
+	} else {
+		mci_writel(host, UHS_REG_EXT, 0x80000000 | (6 << SDMMC_UHS_EXT_DRV_SHIFT) | (3 << SDMMC_UHS_EXT_SMP_SHIFT));
+		mci_writel(host, UHS_REG_EXT, 0x80000000 | (6 << SDMMC_UHS_EXT_DRV_SHIFT) | (3 << SDMMC_UHS_EXT_SMP_SHIFT) | SDMMC_UHS_EXT_CLK_EN);
+	}
 
 	/*
 	 * Get the host data width - this assumes that HCON has been set with
@@ -1983,10 +2397,11 @@
 	}
 
 	/* Reset all blocks */
-	if (!mci_wait_reset(&host->dev, host)) {
-		ret = -ENODEV;
-		goto err_dmaunmap;
-	}
+	if (!mci_wait_reset(host->dev, host))
+		return -ENODEV;
+
+	host->dma_ops = host->pdata->dma_ops;
+	dw_mci_init_dma(host);
 
 	/* Clear the interrupts for the host controller */
 	mci_writel(host, RINTSTS, 0xFFFFFFFF);
@@ -2020,13 +2435,26 @@
 	mci_writel(host, CLKENA, 0);
 	mci_writel(host, CLKSRC, 0);
 
+	/*
+	 * In 2.40a spec, Data offset is changed.
+	 * Need to check the version-id and set data-offset for DATA register.
+	 */
+	host->verid = SDMMC_GET_VERID(mci_readl(host, VERID));
+	dev_info(host->dev, "Version ID is %04x\n", host->verid);
+
+	if (host->verid < DW_MMC_240A)
+		host->data_offset = DATA_OFFSET;
+	else
+		host->data_offset = DATA_240A_OFFSET;
+
 	tasklet_init(&host->tasklet, dw_mci_tasklet_func, (unsigned long)host);
-	dw_mci_card_workqueue = alloc_workqueue("dw-mci-card",
+	host->card_workqueue = alloc_workqueue("dw-mci-card",
 			WQ_MEM_RECLAIM | WQ_NON_REENTRANT, 1);
-	if (!dw_mci_card_workqueue)
+	if (!host->card_workqueue)
 		goto err_dmaunmap;
 	INIT_WORK(&host->card_work, dw_mci_work_routine_card);
-	ret = request_irq(host->irq, dw_mci_interrupt, host->irq_flags, "dw-mci", host);
+	ret = devm_request_irq(host->dev, host->irq, dw_mci_interrupt,
+			       host->irq_flags, "dw-mci", host);
 	if (ret)
 		goto err_workqueue;
 
@@ -2035,27 +2463,6 @@
 	else
 		host->num_slots = ((mci_readl(host, HCON) >> 1) & 0x1F) + 1;
 
-	/* We need at least one slot to succeed */
-	for (i = 0; i < host->num_slots; i++) {
-		ret = dw_mci_init_slot(host, i);
-		if (ret) {
-			ret = -ENODEV;
-			goto err_init_slot;
-		}
-	}
-
-	/*
-	 * In 2.40a spec, Data offset is changed.
-	 * Need to check the version-id and set data-offset for DATA register.
-	 */
-	host->verid = SDMMC_GET_VERID(mci_readl(host, VERID));
-	dev_info(&host->dev, "Version ID is %04x\n", host->verid);
-
-	if (host->verid < DW_MMC_240A)
-		host->data_offset = DATA_OFFSET;
-	else
-		host->data_offset = DATA_240A_OFFSET;
-
 	/*
 	 * Enable interrupts for command done, data over, data empty, card det,
 	 * receive ready and error such as transmit, receive timeout, crc error
@@ -2066,37 +2473,51 @@
 		   DW_MCI_ERROR_FLAGS | SDMMC_INT_CD);
 	mci_writel(host, CTRL, SDMMC_CTRL_INT_ENABLE); /* Enable mci interrupt */
 
-	dev_info(&host->dev, "DW MMC controller at irq %d, "
+	dev_info(host->dev, "DW MMC controller at irq %d, "
 		 "%d bit host data width, "
 		 "%u deep fifo\n",
 		 host->irq, width, fifo_size);
-	if (host->quirks & DW_MCI_QUIRK_IDMAC_DTO)
-		dev_info(&host->dev, "Internal DMAC interrupt fix enabled.\n");
 
-	return 0;
+	/* We need at least one slot to succeed */
+	for (i = 0; i < host->num_slots; i++) {
+		ret = dw_mci_init_slot(host, i);
+		if (ret)
+			dev_dbg(host->dev, "slot %d init failed\n", i);
+		else
+			init_slots++;
+	}
 
-err_init_slot:
-	/* De-init any initialized slots */
-	while (i > 0) {
-		if (host->slot[i])
-			dw_mci_cleanup_slot(host->slot[i], i);
-		i--;
+	if (init_slots) {
+		dev_info(host->dev, "%d slots initialized\n", init_slots);
+	} else {
+		dev_dbg(host->dev, "attempted to initialize %d slots, "
+					"but failed on all\n", host->num_slots);
+		goto err_workqueue;
 	}
-	free_irq(host->irq, host);
+
+	if (host->quirks & DW_MCI_QUIRK_IDMAC_DTO)
+		dev_info(host->dev, "Internal DMAC interrupt fix enabled.\n");
+
+	return 0;
 
 err_workqueue:
-	destroy_workqueue(dw_mci_card_workqueue);
+	destroy_workqueue(host->card_workqueue);
 
 err_dmaunmap:
 	if (host->use_dma && host->dma_ops->exit)
 		host->dma_ops->exit(host);
-	dma_free_coherent(&host->dev, PAGE_SIZE,
-			  host->sg_cpu, host->sg_dma);
 
-	if (host->vmmc) {
+	if (host->vmmc)
 		regulator_disable(host->vmmc);
-		regulator_put(host->vmmc);
-	}
+
+err_clk_ciu:
+	if (!IS_ERR(host->ciu_clk))
+		clk_disable_unprepare(host->ciu_clk);
+
+err_clk_biu:
+	if (!IS_ERR(host->biu_clk))
+		clk_disable_unprepare(host->biu_clk);
+
 	return ret;
 }
 EXPORT_SYMBOL(dw_mci_probe);
@@ -2109,7 +2530,7 @@
 	mci_writel(host, INTMASK, 0); /* disable all mmc interrupt first */
 
 	for (i = 0; i < host->num_slots; i++) {
-		dev_dbg(&host->dev, "remove slot %d\n", i);
+		dev_dbg(host->dev, "remove slot %d\n", i);
 		if (host->slot[i])
 			dw_mci_cleanup_slot(host->slot[i], i);
 	}
@@ -2118,18 +2539,19 @@
 	mci_writel(host, CLKENA, 0);
 	mci_writel(host, CLKSRC, 0);
 
-	free_irq(host->irq, host);
-	destroy_workqueue(dw_mci_card_workqueue);
-	dma_free_coherent(&host->dev, PAGE_SIZE, host->sg_cpu, host->sg_dma);
+	destroy_workqueue(host->card_workqueue);
 
 	if (host->use_dma && host->dma_ops->exit)
 		host->dma_ops->exit(host);
 
-	if (host->vmmc) {
+	if (host->vmmc)
 		regulator_disable(host->vmmc);
-		regulator_put(host->vmmc);
-	}
 
+	if (!IS_ERR(host->ciu_clk))
+		clk_disable_unprepare(host->ciu_clk);
+
+	if (!IS_ERR(host->biu_clk))
+		clk_disable_unprepare(host->biu_clk);
 }
 EXPORT_SYMBOL(dw_mci_remove);
 
@@ -2169,17 +2591,23 @@
 {
 	int i, ret;
 
-	if (host->vmmc)
-		regulator_enable(host->vmmc);
-
-	if (host->dma_ops->init)
-		host->dma_ops->init(host);
+	if (host->vmmc) {
+		ret = regulator_enable(host->vmmc);
+		if (ret) {
+			dev_err(host->dev,
+				"failed to enable regulator: %d\n", ret);
+			return ret;
+		}
+	}
 
-	if (!mci_wait_reset(&host->dev, host)) {
+	if (!mci_wait_reset(host->dev, host)) {
 		ret = -ENODEV;
 		return ret;
 	}
 
+	if (host->use_dma && host->dma_ops->init)
+		host->dma_ops->init(host);
+
 	/* Restore the old value at FIFOTH register */
 	mci_writel(host, FIFOTH, host->fifoth_val);
 
@@ -2193,6 +2621,11 @@
 		struct dw_mci_slot *slot = host->slot[i];
 		if (!slot)
 			continue;
+		if (slot->mmc->pm_flags & MMC_PM_KEEP_POWER) {
+			dw_mci_set_ios(slot->mmc, &slot->mmc->ios);
+			dw_mci_setup_bus(slot, true);
+		}
+
 		ret = mmc_resume_host(host->slot[i]->mmc);
 		if (ret < 0)
 			return ret;
@@ -2204,7 +2637,7 @@
 
 static int __init dw_mci_init(void)
 {
-	printk(KERN_INFO "Synopsys Designware Multimedia Card Interface Driver");
+	pr_info("Synopsys Designware Multimedia Card Interface Driver\n");
 	return 0;
 }
 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/dw_mmc-exynos.c linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/dw_mmc-exynos.c
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/dw_mmc-exynos.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/dw_mmc-exynos.c	2014-09-12 15:59:37.348052000 +0800
@@ -0,0 +1,207 @@
+/*
+ * Exynos Specific Extensions for Synopsys DW Multimedia Card Interface driver
+ *
+ * Copyright (C) 2012, Samsung Electronics Co., Ltd.
+ *
+ * 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/platform_device.h>
+#include <linux/clk.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/dw_mmc.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+
+#include "dw_mmc.h"
+#include "dw_mmc-pltfm.h"
+
+#define NUM_PINS(x)			(x + 2)
+
+#define SDMMC_CLKSEL			0x09C
+#define SDMMC_CLKSEL_CCLK_SAMPLE(x)	(((x) & 7) << 0)
+#define SDMMC_CLKSEL_CCLK_DRIVE(x)	(((x) & 7) << 16)
+#define SDMMC_CLKSEL_CCLK_DIVIDER(x)	(((x) & 7) << 24)
+#define SDMMC_CLKSEL_GET_DRV_WD3(x)	(((x) >> 16) & 0x7)
+#define SDMMC_CLKSEL_TIMING(x, y, z)	(SDMMC_CLKSEL_CCLK_SAMPLE(x) |	\
+					SDMMC_CLKSEL_CCLK_DRIVE(y) |	\
+					SDMMC_CLKSEL_CCLK_DIVIDER(z))
+
+#define SDMMC_CMD_USE_HOLD_REG		BIT(29)
+
+#define EXYNOS4210_FIXED_CIU_CLK_DIV	2
+#define EXYNOS4412_FIXED_CIU_CLK_DIV	4
+
+/* Variations in Exynos specific dw-mshc controller */
+enum dw_mci_exynos_type {
+	DW_MCI_TYPE_EXYNOS4210,
+	DW_MCI_TYPE_EXYNOS4412,
+	DW_MCI_TYPE_EXYNOS5250,
+};
+
+/* Exynos implementation specific driver private data */
+struct dw_mci_exynos_priv_data {
+	enum dw_mci_exynos_type		ctrl_type;
+	u8				ciu_div;
+	u32				sdr_timing;
+	u32				ddr_timing;
+};
+
+static struct dw_mci_exynos_compatible {
+	char				*compatible;
+	enum dw_mci_exynos_type		ctrl_type;
+} exynos_compat[] = {
+	{
+		.compatible	= "samsung,exynos4210-dw-mshc",
+		.ctrl_type	= DW_MCI_TYPE_EXYNOS4210,
+	}, {
+		.compatible	= "samsung,exynos4412-dw-mshc",
+		.ctrl_type	= DW_MCI_TYPE_EXYNOS4412,
+	}, {
+		.compatible	= "samsung,exynos5250-dw-mshc",
+		.ctrl_type	= DW_MCI_TYPE_EXYNOS5250,
+	},
+};
+
+static int dw_mci_exynos_priv_init(struct dw_mci *host)
+{
+	struct dw_mci_exynos_priv_data *priv;
+	int idx;
+
+	priv = devm_kzalloc(host->dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv) {
+		dev_err(host->dev, "mem alloc failed for private data\n");
+		return -ENOMEM;
+	}
+
+	for (idx = 0; idx < ARRAY_SIZE(exynos_compat); idx++) {
+		if (of_device_is_compatible(host->dev->of_node,
+					exynos_compat[idx].compatible))
+			priv->ctrl_type = exynos_compat[idx].ctrl_type;
+	}
+
+	host->priv = priv;
+	return 0;
+}
+
+static int dw_mci_exynos_setup_clock(struct dw_mci *host)
+{
+	struct dw_mci_exynos_priv_data *priv = host->priv;
+
+	if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS5250)
+		host->bus_hz /= (priv->ciu_div + 1);
+	else if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS4412)
+		host->bus_hz /= EXYNOS4412_FIXED_CIU_CLK_DIV;
+	else if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS4210)
+		host->bus_hz /= EXYNOS4210_FIXED_CIU_CLK_DIV;
+
+	return 0;
+}
+
+static void dw_mci_exynos_prepare_command(struct dw_mci *host, u32 *cmdr)
+{
+	/*
+	 * Exynos4412 and Exynos5250 extends the use of CMD register with the
+	 * use of bit 29 (which is reserved on standard MSHC controllers) for
+	 * optionally bypassing the HOLD register for command and data. The
+	 * HOLD register should be bypassed in case there is no phase shift
+	 * applied on CMD/DATA that is sent to the card.
+	 */
+	if (SDMMC_CLKSEL_GET_DRV_WD3(mci_readl(host, CLKSEL)))
+		*cmdr |= SDMMC_CMD_USE_HOLD_REG;
+}
+
+static void dw_mci_exynos_set_ios(struct dw_mci *host, struct mmc_ios *ios)
+{
+	struct dw_mci_exynos_priv_data *priv = host->priv;
+
+	if (ios->timing == MMC_TIMING_UHS_DDR50)
+		mci_writel(host, CLKSEL, priv->ddr_timing);
+	else
+		mci_writel(host, CLKSEL, priv->sdr_timing);
+}
+
+static int dw_mci_exynos_parse_dt(struct dw_mci *host)
+{
+	struct dw_mci_exynos_priv_data *priv = host->priv;
+	struct device_node *np = host->dev->of_node;
+	u32 timing[2];
+	u32 div = 0;
+	int ret;
+
+	of_property_read_u32(np, "samsung,dw-mshc-ciu-div", &div);
+	priv->ciu_div = div;
+
+	ret = of_property_read_u32_array(np,
+			"samsung,dw-mshc-sdr-timing", timing, 2);
+	if (ret)
+		return ret;
+
+	priv->sdr_timing = SDMMC_CLKSEL_TIMING(timing[0], timing[1], div);
+
+	ret = of_property_read_u32_array(np,
+			"samsung,dw-mshc-ddr-timing", timing, 2);
+	if (ret)
+		return ret;
+
+	priv->ddr_timing = SDMMC_CLKSEL_TIMING(timing[0], timing[1], div);
+	return 0;
+}
+
+/* Common capabilities of Exynos4/Exynos5 SoC */
+static unsigned long exynos_dwmmc_caps[4] = {
+	MMC_CAP_UHS_DDR50 | MMC_CAP_1_8V_DDR |
+		MMC_CAP_8_BIT_DATA | MMC_CAP_CMD23,
+	MMC_CAP_CMD23,
+	MMC_CAP_CMD23,
+	MMC_CAP_CMD23,
+};
+
+static const struct dw_mci_drv_data exynos_drv_data = {
+	.caps			= exynos_dwmmc_caps,
+	.init			= dw_mci_exynos_priv_init,
+	.setup_clock		= dw_mci_exynos_setup_clock,
+	.prepare_command	= dw_mci_exynos_prepare_command,
+	.set_ios		= dw_mci_exynos_set_ios,
+	.parse_dt		= dw_mci_exynos_parse_dt,
+};
+
+static const struct of_device_id dw_mci_exynos_match[] = {
+	{ .compatible = "samsung,exynos4412-dw-mshc",
+			.data = &exynos_drv_data, },
+	{ .compatible = "samsung,exynos5250-dw-mshc",
+			.data = &exynos_drv_data, },
+	{},
+};
+MODULE_DEVICE_TABLE(of, dw_mci_exynos_match);
+
+static int dw_mci_exynos_probe(struct platform_device *pdev)
+{
+	const struct dw_mci_drv_data *drv_data;
+	const struct of_device_id *match;
+
+	match = of_match_node(dw_mci_exynos_match, pdev->dev.of_node);
+	drv_data = match->data;
+	return dw_mci_pltfm_register(pdev, drv_data);
+}
+
+static struct platform_driver dw_mci_exynos_pltfm_driver = {
+	.probe		= dw_mci_exynos_probe,
+	.remove		= __exit_p(dw_mci_pltfm_remove),
+	.driver		= {
+		.name		= "dwmmc_exynos",
+		.of_match_table	= dw_mci_exynos_match,
+		.pm		= &dw_mci_pltfm_pmops,
+	},
+};
+
+module_platform_driver(dw_mci_exynos_pltfm_driver);
+
+MODULE_DESCRIPTION("Samsung Specific DW-MSHC Driver Extension");
+MODULE_AUTHOR("Thomas Abraham <thomas.ab@samsung.com");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:dwmmc-exynos");
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/dw_mmc.h linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/dw_mmc.h
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/dw_mmc.h	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/dw_mmc.h	2014-10-23 16:48:47.693240000 +0800
@@ -53,6 +53,7 @@
 #define SDMMC_IDINTEN		0x090
 #define SDMMC_DSCADDR		0x094
 #define SDMMC_BUFADDR		0x098
+#define SDMMC_UHS_REG_EXT		0x108
 #define SDMMC_DATA(x)		(x)
 
 /*
@@ -111,6 +112,8 @@
 #define SDMMC_INT_ERROR			0xbfc2
 /* Command register defines */
 #define SDMMC_CMD_START			BIT(31)
+#define SDMMC_CMD_HOLD			BIT(29)
+#define SDMMC_CMD_VOLT_SW		BIT(28)
 #define SDMMC_CMD_CCS_EXP		BIT(23)
 #define SDMMC_CMD_CEATA_RD		BIT(22)
 #define SDMMC_CMD_UPD_CLK		BIT(21)
@@ -142,6 +145,10 @@
 /* Version ID register define */
 #define SDMMC_GET_VERID(x)		((x) & 0xFFFF)
 
+#define SDMMC_UHS_EXT_CLK_EN	BIT(29)
+#define SDMMC_UHS_EXT_DRV_SHIFT 23
+#define SDMMC_UHS_EXT_SMP_SHIFT 16
+
 /* Register access macros */
 #define mci_readl(dev, reg)			\
 	__raw_readl((dev)->regs + SDMMC_##reg)
@@ -182,4 +189,25 @@
 extern int dw_mci_resume(struct dw_mci *host);
 #endif
 
+/**
+ * dw_mci driver data - dw-mshc implementation specific driver data.
+ * @caps: mmc subsystem specified capabilities of the controller(s).
+ * @init: early implementation specific initialization.
+ * @setup_clock: implementation specific clock configuration.
+ * @prepare_command: handle CMD register extensions.
+ * @set_ios: handle bus specific extensions.
+ * @parse_dt: parse implementation specific device tree properties.
+ *
+ * Provide controller implementation specific extensions. The usage of this
+ * data structure is fully optional and usage of each member in this structure
+ * is optional as well.
+ */
+struct dw_mci_drv_data {
+	unsigned long	*caps;
+	int		(*init)(struct dw_mci *host);
+	int		(*setup_clock)(struct dw_mci *host);
+	void		(*prepare_command)(struct dw_mci *host, u32 *cmdr);
+	void		(*set_ios)(struct dw_mci *host, struct mmc_ios *ios);
+	int		(*parse_dt)(struct dw_mci *host);
+};
 #endif /* _DW_MMC_H_ */
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/dw_mmc-pci.c linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/dw_mmc-pci.c
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/dw_mmc-pci.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/dw_mmc-pci.c	2014-09-12 15:59:37.348052000 +0800
@@ -37,7 +37,7 @@
 	.fifo_depth			= 32,
 };
 
-static int __devinit dw_mci_pci_probe(struct pci_dev *pdev,
+static int dw_mci_pci_probe(struct pci_dev *pdev,
 				  const struct pci_device_id *entries)
 {
 	struct dw_mci *host;
@@ -59,7 +59,7 @@
 
 	host->irq = pdev->irq;
 	host->irq_flags = IRQF_SHARED;
-	host->dev = pdev->dev;
+	host->dev = &pdev->dev;
 	host->pdata = &pci_board_data;
 
 	host->regs = pci_iomap(pdev, PCI_BAR_NO, COMPLETE_BAR);
@@ -85,7 +85,7 @@
 	return ret;
 }
 
-static void __devexit dw_mci_pci_remove(struct pci_dev *pdev)
+static void dw_mci_pci_remove(struct pci_dev *pdev)
 {
 	struct dw_mci *host = pci_get_drvdata(pdev);
 
@@ -140,18 +140,7 @@
 	},
 };
 
-static int __init dw_mci_init(void)
-{
-	return pci_register_driver(&dw_mci_pci_driver);
-}
-
-static void __exit dw_mci_exit(void)
-{
-	pci_unregister_driver(&dw_mci_pci_driver);
-}
-
-module_init(dw_mci_init);
-module_exit(dw_mci_exit);
+module_pci_driver(dw_mci_pci_driver);
 
 MODULE_DESCRIPTION("DW Multimedia Card PCI Interface driver");
 MODULE_AUTHOR("Shashidhar Hiremath <shashidharh@vayavyalabs.com>");
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/dw_mmc-pltfm.c linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/dw_mmc-pltfm.c
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/dw_mmc-pltfm.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/dw_mmc-pltfm.c	2014-09-12 15:59:37.348052000 +0800
@@ -10,68 +10,92 @@
  * (at your option) any later version.
  */
 
+#include <linux/err.h>
 #include <linux/interrupt.h>
 #include <linux/module.h>
 #include <linux/io.h>
+#include <linux/clk.h>
 #include <linux/irq.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/mmc/host.h>
 #include <linux/mmc/mmc.h>
 #include <linux/mmc/dw_mmc.h>
+#include <linux/of.h>
+
 #include "dw_mmc.h"
+#include <mach/pinmux.h>
 
-static int dw_mci_pltfm_probe(struct platform_device *pdev)
+int dw_mci_pltfm_register(struct platform_device *pdev,
+				const struct dw_mci_drv_data *drv_data)
 {
 	struct dw_mci *host;
 	struct resource	*regs;
+	struct clk *clk;
 	int ret;
 
+	clk = clk_get(&pdev->dev, NULL);
+	if (IS_ERR(clk)) {
+		dev_err(&pdev->dev, "failed to get clock\n");
+		return PTR_ERR(clk);
+	}
+
+	clk_prepare(clk);
+	clk_enable(clk);
+
+#ifdef CONFIG_CELESTIAL_8BIT_MMC
+	pinmux_set_status_bit(PINMUX_SDIO, pdev->id + 1, 1);
+	pinmux_set_status_bit(PINMUX_SDIO, pdev->id + 2, 1);
+#endif
+
+	pinmux_set_status_bit(PINMUX_SDIO, pdev->id, 1);
+
 	host = kzalloc(sizeof(struct dw_mci), GFP_KERNEL);
 	if (!host)
 		return -ENOMEM;
 
 	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!regs) {
-		ret = -ENXIO;
-		goto err_free;
-	}
+	if (!regs)
+		return -ENXIO;
 
 	host->irq = platform_get_irq(pdev, 0);
-	if (host->irq < 0) {
-		ret = host->irq;
-		goto err_free;
-	}
+	if (host->irq < 0)
+		return host->irq;
 
-	host->dev = pdev->dev;
+	host->drv_data = drv_data;
+	host->dev = &pdev->dev;
 	host->irq_flags = 0;
 	host->pdata = pdev->dev.platform_data;
-	ret = -ENOMEM;
 	host->regs = ioremap(regs->start, resource_size(regs));
-	if (!host->regs)
-		goto err_free;
+	if (IS_ERR(host->regs))
+		return PTR_ERR(host->regs);
+
+	if (drv_data && drv_data->init) {
+		ret = drv_data->init(host);
+		if (ret)
+			return ret;
+	}
+
 	platform_set_drvdata(pdev, host);
 	ret = dw_mci_probe(host);
-	if (ret)
-		goto err_out;
-	return ret;
-err_out:
-	iounmap(host->regs);
-err_free:
-	kfree(host);
 	return ret;
 }
+EXPORT_SYMBOL_GPL(dw_mci_pltfm_register);
 
-static int __exit dw_mci_pltfm_remove(struct platform_device *pdev)
+static int dw_mci_pltfm_probe(struct platform_device *pdev)
+{
+	return dw_mci_pltfm_register(pdev, NULL);
+}
+
+static int dw_mci_pltfm_remove(struct platform_device *pdev)
 {
 	struct dw_mci *host = platform_get_drvdata(pdev);
 
 	platform_set_drvdata(pdev, NULL);
 	dw_mci_remove(host);
-	iounmap(host->regs);
-	kfree(host);
 	return 0;
 }
+EXPORT_SYMBOL_GPL(dw_mci_pltfm_remove);
 
 #ifdef CONFIG_PM_SLEEP
 /*
@@ -105,28 +129,26 @@
 #define dw_mci_pltfm_resume	NULL
 #endif /* CONFIG_PM_SLEEP */
 
-static SIMPLE_DEV_PM_OPS(dw_mci_pltfm_pmops, dw_mci_pltfm_suspend, dw_mci_pltfm_resume);
+SIMPLE_DEV_PM_OPS(dw_mci_pltfm_pmops, dw_mci_pltfm_suspend, dw_mci_pltfm_resume);
+EXPORT_SYMBOL_GPL(dw_mci_pltfm_pmops);
+
+static const struct of_device_id dw_mci_pltfm_match[] = {
+	{ .compatible = "snps,dw-mshc", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, dw_mci_pltfm_match);
 
 static struct platform_driver dw_mci_pltfm_driver = {
-	.remove		= __exit_p(dw_mci_pltfm_remove),
+	.probe		= dw_mci_pltfm_probe,
+	.remove		= dw_mci_pltfm_remove,
 	.driver		= {
 		.name		= "dw_mmc",
+		.of_match_table	= of_match_ptr(dw_mci_pltfm_match),
 		.pm		= &dw_mci_pltfm_pmops,
 	},
 };
 
-static int __init dw_mci_init(void)
-{
-	return platform_driver_probe(&dw_mci_pltfm_driver, dw_mci_pltfm_probe);
-}
-
-static void __exit dw_mci_exit(void)
-{
-	platform_driver_unregister(&dw_mci_pltfm_driver);
-}
-
-module_init(dw_mci_init);
-module_exit(dw_mci_exit);
+module_platform_driver(dw_mci_pltfm_driver);
 
 MODULE_DESCRIPTION("DW Multimedia Card Interface driver");
 MODULE_AUTHOR("NXP Semiconductor VietNam");
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/dw_mmc-pltfm.h linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/dw_mmc-pltfm.h
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/dw_mmc-pltfm.h	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/dw_mmc-pltfm.h	2014-09-12 15:59:37.348052000 +0800
@@ -0,0 +1,20 @@
+/*
+ * Synopsys DesignWare Multimedia Card Interface Platform driver
+ *
+ * Copyright (C) 2012, Samsung Electronics Co., Ltd.
+ *
+ * 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 _DW_MMC_PLTFM_H_
+#define _DW_MMC_PLTFM_H_
+
+extern int dw_mci_pltfm_register(struct platform_device *pdev,
+				const struct dw_mci_drv_data *drv_data);
+extern int dw_mci_pltfm_remove(struct platform_device *pdev);
+extern const struct dev_pm_ops dw_mci_pltfm_pmops;
+
+#endif /* _DW_MMC_PLTFM_H_ */
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/imxmmc.c linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/imxmmc.c
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/imxmmc.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/imxmmc.c	1970-01-01 08:00:00.000000000 +0800
@@ -1,1169 +0,0 @@
-/*
- *  linux/drivers/mmc/host/imxmmc.c - Motorola i.MX MMCI driver
- *
- *  Copyright (C) 2004 Sascha Hauer, Pengutronix <sascha@saschahauer.de>
- *  Copyright (C) 2006 Pavel Pisa, PiKRON <ppisa@pikron.com>
- *
- *  derived from pxamci.c by Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/ioport.h>
-#include <linux/platform_device.h>
-#include <linux/interrupt.h>
-#include <linux/blkdev.h>
-#include <linux/dma-mapping.h>
-#include <linux/mmc/host.h>
-#include <linux/mmc/card.h>
-#include <linux/delay.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-
-#include <asm/dma.h>
-#include <asm/irq.h>
-#include <asm/sizes.h>
-#include <mach/mmc.h>
-#include <mach/imx-dma.h>
-
-#include "imxmmc.h"
-
-#define DRIVER_NAME "imx-mmc"
-
-#define IMXMCI_INT_MASK_DEFAULT (INT_MASK_BUF_READY | INT_MASK_DATA_TRAN | \
-				 INT_MASK_WRITE_OP_DONE | INT_MASK_END_CMD_RES | \
-				 INT_MASK_AUTO_CARD_DETECT | INT_MASK_DAT0_EN | INT_MASK_SDIO)
-
-struct imxmci_host {
-	struct mmc_host		*mmc;
-	spinlock_t		lock;
-	struct resource		*res;
-	void __iomem		*base;
-	int			irq;
-	imx_dmach_t		dma;
-	volatile unsigned int	imask;
-	unsigned int		power_mode;
-	unsigned int		present;
-	struct imxmmc_platform_data *pdata;
-
-	struct mmc_request	*req;
-	struct mmc_command	*cmd;
-	struct mmc_data		*data;
-
-	struct timer_list	timer;
-	struct tasklet_struct	tasklet;
-	unsigned int		status_reg;
-	unsigned long		pending_events;
-	/* Next two fields are there for CPU driven transfers to overcome SDHC deficiencies */
-	u16			*data_ptr;
-	unsigned int		data_cnt;
-	atomic_t		stuck_timeout;
-
-	unsigned int		dma_nents;
-	unsigned int		dma_size;
-	unsigned int		dma_dir;
-	int			dma_allocated;
-
-	unsigned char		actual_bus_width;
-
-	int			prev_cmd_code;
-
-	struct clk		*clk;
-};
-
-#define IMXMCI_PEND_IRQ_b	0
-#define IMXMCI_PEND_DMA_END_b	1
-#define IMXMCI_PEND_DMA_ERR_b	2
-#define IMXMCI_PEND_WAIT_RESP_b	3
-#define IMXMCI_PEND_DMA_DATA_b	4
-#define IMXMCI_PEND_CPU_DATA_b	5
-#define IMXMCI_PEND_CARD_XCHG_b	6
-#define IMXMCI_PEND_SET_INIT_b	7
-#define IMXMCI_PEND_STARTED_b	8
-
-#define IMXMCI_PEND_IRQ_m	(1 << IMXMCI_PEND_IRQ_b)
-#define IMXMCI_PEND_DMA_END_m	(1 << IMXMCI_PEND_DMA_END_b)
-#define IMXMCI_PEND_DMA_ERR_m	(1 << IMXMCI_PEND_DMA_ERR_b)
-#define IMXMCI_PEND_WAIT_RESP_m	(1 << IMXMCI_PEND_WAIT_RESP_b)
-#define IMXMCI_PEND_DMA_DATA_m	(1 << IMXMCI_PEND_DMA_DATA_b)
-#define IMXMCI_PEND_CPU_DATA_m	(1 << IMXMCI_PEND_CPU_DATA_b)
-#define IMXMCI_PEND_CARD_XCHG_m	(1 << IMXMCI_PEND_CARD_XCHG_b)
-#define IMXMCI_PEND_SET_INIT_m	(1 << IMXMCI_PEND_SET_INIT_b)
-#define IMXMCI_PEND_STARTED_m	(1 << IMXMCI_PEND_STARTED_b)
-
-static void imxmci_stop_clock(struct imxmci_host *host)
-{
-	int i = 0;
-	u16 reg;
-
-	reg = readw(host->base + MMC_REG_STR_STP_CLK);
-	writew(reg & ~STR_STP_CLK_START_CLK, host->base + MMC_REG_STR_STP_CLK);
-	while (i < 0x1000) {
-		if (!(i & 0x7f)) {
-			reg = readw(host->base + MMC_REG_STR_STP_CLK);
-			writew(reg | STR_STP_CLK_STOP_CLK,
-					host->base + MMC_REG_STR_STP_CLK);
-		}
-
-		reg = readw(host->base + MMC_REG_STATUS);
-		if (!(reg & STATUS_CARD_BUS_CLK_RUN)) {
-			/* Check twice before cut */
-			reg = readw(host->base + MMC_REG_STATUS);
-			if (!(reg & STATUS_CARD_BUS_CLK_RUN))
-				return;
-		}
-
-		i++;
-	}
-	dev_dbg(mmc_dev(host->mmc), "imxmci_stop_clock blocked, no luck\n");
-}
-
-static int imxmci_start_clock(struct imxmci_host *host)
-{
-	unsigned int trials = 0;
-	unsigned int delay_limit = 128;
-	unsigned long flags;
-	u16 reg;
-
-	reg = readw(host->base + MMC_REG_STR_STP_CLK);
-	writew(reg & ~STR_STP_CLK_STOP_CLK, host->base + MMC_REG_STR_STP_CLK);
-
-	clear_bit(IMXMCI_PEND_STARTED_b, &host->pending_events);
-
-	/*
-	 * Command start of the clock, this usually succeeds in less
-	 * then 6 delay loops, but during card detection (low clockrate)
-	 * it takes up to 5000 delay loops and sometimes fails for the first time
-	 */
-	reg = readw(host->base + MMC_REG_STR_STP_CLK);
-	writew(reg | STR_STP_CLK_START_CLK, host->base + MMC_REG_STR_STP_CLK);
-
-	do {
-		unsigned int delay = delay_limit;
-
-		while (delay--) {
-			reg = readw(host->base + MMC_REG_STATUS);
-			if (reg & STATUS_CARD_BUS_CLK_RUN) {
-				/* Check twice before cut */
-				reg = readw(host->base + MMC_REG_STATUS);
-				if (reg & STATUS_CARD_BUS_CLK_RUN)
-					return 0;
-			}
-
-			if (test_bit(IMXMCI_PEND_STARTED_b, &host->pending_events))
-				return 0;
-		}
-
-		local_irq_save(flags);
-		/*
-		 * Ensure, that request is not doubled under all possible circumstances.
-		 * It is possible, that cock running state is missed, because some other
-		 * IRQ or schedule delays this function execution and the clocks has
-		 * been already stopped by other means (response processing, SDHC HW)
-		 */
-		if (!test_bit(IMXMCI_PEND_STARTED_b, &host->pending_events)) {
-			reg = readw(host->base + MMC_REG_STR_STP_CLK);
-			writew(reg | STR_STP_CLK_START_CLK,
-					host->base + MMC_REG_STR_STP_CLK);
-		}
-		local_irq_restore(flags);
-
-	} while (++trials < 256);
-
-	dev_err(mmc_dev(host->mmc), "imxmci_start_clock blocked, no luck\n");
-
-	return -1;
-}
-
-static void imxmci_softreset(struct imxmci_host *host)
-{
-	int i;
-
-	/* reset sequence */
-	writew(0x08, host->base + MMC_REG_STR_STP_CLK);
-	writew(0x0D, host->base + MMC_REG_STR_STP_CLK);
-
-	for (i = 0; i < 8; i++)
-		writew(0x05, host->base + MMC_REG_STR_STP_CLK);
-
-	writew(0xff, host->base + MMC_REG_RES_TO);
-	writew(512, host->base + MMC_REG_BLK_LEN);
-	writew(1, host->base + MMC_REG_NOB);
-}
-
-static int imxmci_busy_wait_for_status(struct imxmci_host *host,
-				       unsigned int *pstat, unsigned int stat_mask,
-				       int timeout, const char *where)
-{
-	int loops = 0;
-
-	while (!(*pstat & stat_mask)) {
-		loops += 2;
-		if (loops >= timeout) {
-			dev_dbg(mmc_dev(host->mmc), "busy wait timeout in %s, STATUS = 0x%x (0x%x)\n",
-				where, *pstat, stat_mask);
-			return -1;
-		}
-		udelay(2);
-		*pstat |= readw(host->base + MMC_REG_STATUS);
-	}
-	if (!loops)
-		return 0;
-
-	/* The busy-wait is expected there for clock <8MHz due to SDHC hardware flaws */
-	if (!(stat_mask & STATUS_END_CMD_RESP) || (host->mmc->ios.clock >= 8000000))
-		dev_info(mmc_dev(host->mmc), "busy wait for %d usec in %s, STATUS = 0x%x (0x%x)\n",
-			 loops, where, *pstat, stat_mask);
-	return loops;
-}
-
-static void imxmci_setup_data(struct imxmci_host *host, struct mmc_data *data)
-{
-	unsigned int nob = data->blocks;
-	unsigned int blksz = data->blksz;
-	unsigned int datasz = nob * blksz;
-	int i;
-
-	if (data->flags & MMC_DATA_STREAM)
-		nob = 0xffff;
-
-	host->data = data;
-	data->bytes_xfered = 0;
-
-	writew(nob, host->base + MMC_REG_NOB);
-	writew(blksz, host->base + MMC_REG_BLK_LEN);
-
-	/*
-	 * DMA cannot be used for small block sizes, we have to use CPU driven transfers otherwise.
-	 * We are in big troubles for non-512 byte transfers according to note in the paragraph
-	 * 20.6.7 of User Manual anyway, but we need to be able to transfer SCR at least.
-	 * The situation is even more complex in reality. The SDHC in not able to handle wll
-	 * partial FIFO fills and reads. The length has to be rounded up to burst size multiple.
-	 * This is required for SCR read at least.
-	 */
-	if (datasz < 512) {
-		host->dma_size = datasz;
-		if (data->flags & MMC_DATA_READ) {
-			host->dma_dir = DMA_FROM_DEVICE;
-
-			/* Hack to enable read SCR */
-			writew(1, host->base + MMC_REG_NOB);
-			writew(512, host->base + MMC_REG_BLK_LEN);
-		} else {
-			host->dma_dir = DMA_TO_DEVICE;
-		}
-
-		/* Convert back to virtual address */
-		host->data_ptr = (u16 *)sg_virt(data->sg);
-		host->data_cnt = 0;
-
-		clear_bit(IMXMCI_PEND_DMA_DATA_b, &host->pending_events);
-		set_bit(IMXMCI_PEND_CPU_DATA_b, &host->pending_events);
-
-		return;
-	}
-
-	if (data->flags & MMC_DATA_READ) {
-		host->dma_dir = DMA_FROM_DEVICE;
-		host->dma_nents = dma_map_sg(mmc_dev(host->mmc), data->sg,
-					     data->sg_len,  host->dma_dir);
-
-		imx_dma_setup_sg(host->dma, data->sg, data->sg_len, datasz,
-				 host->res->start + MMC_REG_BUFFER_ACCESS,
-				 DMA_MODE_READ);
-
-		/*imx_dma_setup_mem2dev_ccr(host->dma, DMA_MODE_READ, IMX_DMA_WIDTH_16, CCR_REN);*/
-		CCR(host->dma) = CCR_DMOD_LINEAR | CCR_DSIZ_32 | CCR_SMOD_FIFO | CCR_SSIZ_16 | CCR_REN;
-	} else {
-		host->dma_dir = DMA_TO_DEVICE;
-
-		host->dma_nents = dma_map_sg(mmc_dev(host->mmc), data->sg,
-					     data->sg_len,  host->dma_dir);
-
-		imx_dma_setup_sg(host->dma, data->sg, data->sg_len, datasz,
-				 host->res->start + MMC_REG_BUFFER_ACCESS,
-				 DMA_MODE_WRITE);
-
-		/*imx_dma_setup_mem2dev_ccr(host->dma, DMA_MODE_WRITE, IMX_DMA_WIDTH_16, CCR_REN);*/
-		CCR(host->dma) = CCR_SMOD_LINEAR | CCR_SSIZ_32 | CCR_DMOD_FIFO | CCR_DSIZ_16 | CCR_REN;
-	}
-
-#if 1	/* This code is there only for consistency checking and can be disabled in future */
-	host->dma_size = 0;
-	for (i = 0; i < host->dma_nents; i++)
-		host->dma_size += data->sg[i].length;
-
-	if (datasz > host->dma_size) {
-		dev_err(mmc_dev(host->mmc), "imxmci_setup_data datasz 0x%x > 0x%x dm_size\n",
-			datasz, host->dma_size);
-	}
-#endif
-
-	host->dma_size = datasz;
-
-	wmb();
-
-	set_bit(IMXMCI_PEND_DMA_DATA_b, &host->pending_events);
-	clear_bit(IMXMCI_PEND_CPU_DATA_b, &host->pending_events);
-
-	/* start DMA engine for read, write is delayed after initial response */
-	if (host->dma_dir == DMA_FROM_DEVICE)
-		imx_dma_enable(host->dma);
-}
-
-static void imxmci_start_cmd(struct imxmci_host *host, struct mmc_command *cmd, unsigned int cmdat)
-{
-	unsigned long flags;
-	u32 imask;
-
-	WARN_ON(host->cmd != NULL);
-	host->cmd = cmd;
-
-	/* Ensure, that clock are stopped else command programming and start fails */
-	imxmci_stop_clock(host);
-
-	if (cmd->flags & MMC_RSP_BUSY)
-		cmdat |= CMD_DAT_CONT_BUSY;
-
-	switch (mmc_resp_type(cmd)) {
-	case MMC_RSP_R1: /* short CRC, OPCODE */
-	case MMC_RSP_R1B:/* short CRC, OPCODE, BUSY */
-		cmdat |= CMD_DAT_CONT_RESPONSE_FORMAT_R1;
-		break;
-	case MMC_RSP_R2: /* long 136 bit + CRC */
-		cmdat |= CMD_DAT_CONT_RESPONSE_FORMAT_R2;
-		break;
-	case MMC_RSP_R3: /* short */
-		cmdat |= CMD_DAT_CONT_RESPONSE_FORMAT_R3;
-		break;
-	default:
-		break;
-	}
-
-	if (test_and_clear_bit(IMXMCI_PEND_SET_INIT_b, &host->pending_events))
-		cmdat |= CMD_DAT_CONT_INIT; /* This command needs init */
-
-	if (host->actual_bus_width == MMC_BUS_WIDTH_4)
-		cmdat |= CMD_DAT_CONT_BUS_WIDTH_4;
-
-	writew(cmd->opcode, host->base + MMC_REG_CMD);
-	writew(cmd->arg >> 16, host->base + MMC_REG_ARGH);
-	writew(cmd->arg & 0xffff, host->base + MMC_REG_ARGL);
-	writew(cmdat, host->base + MMC_REG_CMD_DAT_CONT);
-
-	atomic_set(&host->stuck_timeout, 0);
-	set_bit(IMXMCI_PEND_WAIT_RESP_b, &host->pending_events);
-
-
-	imask = IMXMCI_INT_MASK_DEFAULT;
-	imask &= ~INT_MASK_END_CMD_RES;
-	if (cmdat & CMD_DAT_CONT_DATA_ENABLE) {
-		/* imask &= ~INT_MASK_BUF_READY; */
-		imask &= ~INT_MASK_DATA_TRAN;
-		if (cmdat & CMD_DAT_CONT_WRITE)
-			imask &= ~INT_MASK_WRITE_OP_DONE;
-		if (test_bit(IMXMCI_PEND_CPU_DATA_b, &host->pending_events))
-			imask &= ~INT_MASK_BUF_READY;
-	}
-
-	spin_lock_irqsave(&host->lock, flags);
-	host->imask = imask;
-	writew(host->imask, host->base + MMC_REG_INT_MASK);
-	spin_unlock_irqrestore(&host->lock, flags);
-
-	dev_dbg(mmc_dev(host->mmc), "CMD%02d (0x%02x) mask set to 0x%04x\n",
-		cmd->opcode, cmd->opcode, imask);
-
-	imxmci_start_clock(host);
-}
-
-static void imxmci_finish_request(struct imxmci_host *host, struct mmc_request *req)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&host->lock, flags);
-
-	host->pending_events &= ~(IMXMCI_PEND_WAIT_RESP_m | IMXMCI_PEND_DMA_END_m |
-				  IMXMCI_PEND_DMA_DATA_m | IMXMCI_PEND_CPU_DATA_m);
-
-	host->imask = IMXMCI_INT_MASK_DEFAULT;
-	writew(host->imask, host->base + MMC_REG_INT_MASK);
-
-	spin_unlock_irqrestore(&host->lock, flags);
-
-	if (req && req->cmd)
-		host->prev_cmd_code = req->cmd->opcode;
-
-	host->req = NULL;
-	host->cmd = NULL;
-	host->data = NULL;
-	mmc_request_done(host->mmc, req);
-}
-
-static int imxmci_finish_data(struct imxmci_host *host, unsigned int stat)
-{
-	struct mmc_data *data = host->data;
-	int data_error;
-
-	if (test_and_clear_bit(IMXMCI_PEND_DMA_DATA_b, &host->pending_events)) {
-		imx_dma_disable(host->dma);
-		dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->dma_nents,
-			     host->dma_dir);
-	}
-
-	if (stat & STATUS_ERR_MASK) {
-		dev_dbg(mmc_dev(host->mmc), "request failed. status: 0x%08x\n", stat);
-		if (stat & (STATUS_CRC_READ_ERR | STATUS_CRC_WRITE_ERR))
-			data->error = -EILSEQ;
-		else if (stat & STATUS_TIME_OUT_READ)
-			data->error = -ETIMEDOUT;
-		else
-			data->error = -EIO;
-	} else {
-		data->bytes_xfered = host->dma_size;
-	}
-
-	data_error = data->error;
-
-	host->data = NULL;
-
-	return data_error;
-}
-
-static int imxmci_cmd_done(struct imxmci_host *host, unsigned int stat)
-{
-	struct mmc_command *cmd = host->cmd;
-	int i;
-	u32 a, b, c;
-	struct mmc_data *data = host->data;
-
-	if (!cmd)
-		return 0;
-
-	host->cmd = NULL;
-
-	if (stat & STATUS_TIME_OUT_RESP) {
-		dev_dbg(mmc_dev(host->mmc), "CMD TIMEOUT\n");
-		cmd->error = -ETIMEDOUT;
-	} else if (stat & STATUS_RESP_CRC_ERR && cmd->flags & MMC_RSP_CRC) {
-		dev_dbg(mmc_dev(host->mmc), "cmd crc error\n");
-		cmd->error = -EILSEQ;
-	}
-
-	if (cmd->flags & MMC_RSP_PRESENT) {
-		if (cmd->flags & MMC_RSP_136) {
-			for (i = 0; i < 4; i++) {
-				a = readw(host->base + MMC_REG_RES_FIFO);
-				b = readw(host->base + MMC_REG_RES_FIFO);
-				cmd->resp[i] = a << 16 | b;
-			}
-		} else {
-			a = readw(host->base + MMC_REG_RES_FIFO);
-			b = readw(host->base + MMC_REG_RES_FIFO);
-			c = readw(host->base + MMC_REG_RES_FIFO);
-			cmd->resp[0] = a << 24 | b << 8 | c >> 8;
-		}
-	}
-
-	dev_dbg(mmc_dev(host->mmc), "RESP 0x%08x, 0x%08x, 0x%08x, 0x%08x, error %d\n",
-		cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3], cmd->error);
-
-	if (data && !cmd->error && !(stat & STATUS_ERR_MASK)) {
-		if (host->req->data->flags & MMC_DATA_WRITE) {
-
-			/* Wait for FIFO to be empty before starting DMA write */
-
-			stat = readw(host->base + MMC_REG_STATUS);
-			if (imxmci_busy_wait_for_status(host, &stat,
-							STATUS_APPL_BUFF_FE,
-							40, "imxmci_cmd_done DMA WR") < 0) {
-				cmd->error = -EIO;
-				imxmci_finish_data(host, stat);
-				if (host->req)
-					imxmci_finish_request(host, host->req);
-				dev_warn(mmc_dev(host->mmc), "STATUS = 0x%04x\n",
-					 stat);
-				return 0;
-			}
-
-			if (test_bit(IMXMCI_PEND_DMA_DATA_b, &host->pending_events))
-				imx_dma_enable(host->dma);
-		}
-	} else {
-		struct mmc_request *req;
-		imxmci_stop_clock(host);
-		req = host->req;
-
-		if (data)
-			imxmci_finish_data(host, stat);
-
-		if (req)
-			imxmci_finish_request(host, req);
-		else
-			dev_warn(mmc_dev(host->mmc), "imxmci_cmd_done: no request to finish\n");
-	}
-
-	return 1;
-}
-
-static int imxmci_data_done(struct imxmci_host *host, unsigned int stat)
-{
-	struct mmc_data *data = host->data;
-	int data_error;
-
-	if (!data)
-		return 0;
-
-	data_error = imxmci_finish_data(host, stat);
-
-	if (host->req->stop) {
-		imxmci_stop_clock(host);
-		imxmci_start_cmd(host, host->req->stop, 0);
-	} else {
-		struct mmc_request *req;
-		req = host->req;
-		if (req)
-			imxmci_finish_request(host, req);
-		else
-			dev_warn(mmc_dev(host->mmc), "imxmci_data_done: no request to finish\n");
-	}
-
-	return 1;
-}
-
-static int imxmci_cpu_driven_data(struct imxmci_host *host, unsigned int *pstat)
-{
-	int i;
-	int burst_len;
-	int trans_done = 0;
-	unsigned int stat = *pstat;
-
-	if (host->actual_bus_width != MMC_BUS_WIDTH_4)
-		burst_len = 16;
-	else
-		burst_len = 64;
-
-	/* This is unfortunately required */
-	dev_dbg(mmc_dev(host->mmc), "imxmci_cpu_driven_data running STATUS = 0x%x\n",
-		stat);
-
-	udelay(20);	/* required for clocks < 8MHz*/
-
-	if (host->dma_dir == DMA_FROM_DEVICE) {
-		imxmci_busy_wait_for_status(host, &stat,
-					    STATUS_APPL_BUFF_FF | STATUS_DATA_TRANS_DONE |
-					    STATUS_TIME_OUT_READ,
-					    50, "imxmci_cpu_driven_data read");
-
-		while ((stat & (STATUS_APPL_BUFF_FF | STATUS_DATA_TRANS_DONE)) &&
-		       !(stat & STATUS_TIME_OUT_READ) &&
-		       (host->data_cnt < 512)) {
-
-			udelay(20);	/* required for clocks < 8MHz*/
-
-			for (i = burst_len; i >= 2 ; i -= 2) {
-				u16 data;
-				data = readw(host->base + MMC_REG_BUFFER_ACCESS);
-				udelay(10);	/* required for clocks < 8MHz*/
-				if (host->data_cnt+2 <= host->dma_size) {
-					*(host->data_ptr++) = data;
-				} else {
-					if (host->data_cnt < host->dma_size)
-						*(u8 *)(host->data_ptr) = data;
-				}
-				host->data_cnt += 2;
-			}
-
-			stat = readw(host->base + MMC_REG_STATUS);
-
-			dev_dbg(mmc_dev(host->mmc), "imxmci_cpu_driven_data read %d burst %d STATUS = 0x%x\n",
-				host->data_cnt, burst_len, stat);
-		}
-
-		if ((stat & STATUS_DATA_TRANS_DONE) && (host->data_cnt >= 512))
-			trans_done = 1;
-
-		if (host->dma_size & 0x1ff)
-			stat &= ~STATUS_CRC_READ_ERR;
-
-		if (stat & STATUS_TIME_OUT_READ) {
-			dev_dbg(mmc_dev(host->mmc), "imxmci_cpu_driven_data read timeout STATUS = 0x%x\n",
-				stat);
-			trans_done = -1;
-		}
-
-	} else {
-		imxmci_busy_wait_for_status(host, &stat,
-					    STATUS_APPL_BUFF_FE,
-					    20, "imxmci_cpu_driven_data write");
-
-		while ((stat & STATUS_APPL_BUFF_FE) &&
-		       (host->data_cnt < host->dma_size)) {
-			if (burst_len >= host->dma_size - host->data_cnt) {
-				burst_len = host->dma_size - host->data_cnt;
-				host->data_cnt = host->dma_size;
-				trans_done = 1;
-			} else {
-				host->data_cnt += burst_len;
-			}
-
-			for (i = burst_len; i > 0 ; i -= 2)
-				writew(*(host->data_ptr++), host->base + MMC_REG_BUFFER_ACCESS);
-
-			stat = readw(host->base + MMC_REG_STATUS);
-
-			dev_dbg(mmc_dev(host->mmc), "imxmci_cpu_driven_data write burst %d STATUS = 0x%x\n",
-				burst_len, stat);
-		}
-	}
-
-	*pstat = stat;
-
-	return trans_done;
-}
-
-static void imxmci_dma_irq(int dma, void *devid)
-{
-	struct imxmci_host *host = devid;
-	u32 stat = readw(host->base + MMC_REG_STATUS);
-
-	atomic_set(&host->stuck_timeout, 0);
-	host->status_reg = stat;
-	set_bit(IMXMCI_PEND_DMA_END_b, &host->pending_events);
-	tasklet_schedule(&host->tasklet);
-}
-
-static irqreturn_t imxmci_irq(int irq, void *devid)
-{
-	struct imxmci_host *host = devid;
-	u32 stat = readw(host->base + MMC_REG_STATUS);
-	int handled = 1;
-
-	writew(host->imask | INT_MASK_SDIO | INT_MASK_AUTO_CARD_DETECT,
-			host->base + MMC_REG_INT_MASK);
-
-	atomic_set(&host->stuck_timeout, 0);
-	host->status_reg = stat;
-	set_bit(IMXMCI_PEND_IRQ_b, &host->pending_events);
-	set_bit(IMXMCI_PEND_STARTED_b, &host->pending_events);
-	tasklet_schedule(&host->tasklet);
-
-	return IRQ_RETVAL(handled);
-}
-
-static void imxmci_tasklet_fnc(unsigned long data)
-{
-	struct imxmci_host *host = (struct imxmci_host *)data;
-	u32 stat;
-	unsigned int data_dir_mask = 0;	/* STATUS_WR_CRC_ERROR_CODE_MASK */
-	int timeout = 0;
-
-	if (atomic_read(&host->stuck_timeout) > 4) {
-		char *what;
-		timeout = 1;
-		stat = readw(host->base + MMC_REG_STATUS);
-		host->status_reg = stat;
-		if (test_bit(IMXMCI_PEND_WAIT_RESP_b, &host->pending_events))
-			if (test_bit(IMXMCI_PEND_DMA_DATA_b, &host->pending_events))
-				what = "RESP+DMA";
-			else
-				what = "RESP";
-		else
-			if (test_bit(IMXMCI_PEND_DMA_DATA_b, &host->pending_events))
-				if (test_bit(IMXMCI_PEND_DMA_END_b, &host->pending_events))
-					what = "DATA";
-				else
-					what = "DMA";
-			else
-				what = "???";
-
-		dev_err(mmc_dev(host->mmc),
-			"%s TIMEOUT, hardware stucked STATUS = 0x%04x IMASK = 0x%04x\n",
-			what, stat,
-			readw(host->base + MMC_REG_INT_MASK));
-		dev_err(mmc_dev(host->mmc),
-			"CMD_DAT_CONT = 0x%04x, MMC_BLK_LEN = 0x%04x, MMC_NOB = 0x%04x, DMA_CCR = 0x%08x\n",
-			readw(host->base + MMC_REG_CMD_DAT_CONT),
-			readw(host->base + MMC_REG_BLK_LEN),
-			readw(host->base + MMC_REG_NOB),
-			CCR(host->dma));
-		dev_err(mmc_dev(host->mmc), "CMD%d, prevCMD%d, bus %d-bit, dma_size = 0x%x\n",
-			host->cmd ? host->cmd->opcode : 0,
-			host->prev_cmd_code,
-			1 << host->actual_bus_width, host->dma_size);
-	}
-
-	if (!host->present || timeout)
-		host->status_reg = STATUS_TIME_OUT_RESP | STATUS_TIME_OUT_READ |
-			STATUS_CRC_READ_ERR | STATUS_CRC_WRITE_ERR;
-
-	if (test_bit(IMXMCI_PEND_IRQ_b, &host->pending_events) || timeout) {
-		clear_bit(IMXMCI_PEND_IRQ_b, &host->pending_events);
-
-		stat = readw(host->base + MMC_REG_STATUS);
-		/*
-		 * This is not required in theory, but there is chance to miss some flag
-		 * which clears automatically by mask write, FreeScale original code keeps
-		 * stat from IRQ time so do I
-		 */
-		stat |= host->status_reg;
-
-		if (test_bit(IMXMCI_PEND_CPU_DATA_b, &host->pending_events))
-			stat &= ~STATUS_CRC_READ_ERR;
-
-		if (test_bit(IMXMCI_PEND_WAIT_RESP_b, &host->pending_events)) {
-			imxmci_busy_wait_for_status(host, &stat,
-						    STATUS_END_CMD_RESP | STATUS_ERR_MASK,
-						    20, "imxmci_tasklet_fnc resp (ERRATUM #4)");
-		}
-
-		if (stat & (STATUS_END_CMD_RESP | STATUS_ERR_MASK)) {
-			if (test_and_clear_bit(IMXMCI_PEND_WAIT_RESP_b, &host->pending_events))
-				imxmci_cmd_done(host, stat);
-			if (host->data && (stat & STATUS_ERR_MASK))
-				imxmci_data_done(host, stat);
-		}
-
-		if (test_bit(IMXMCI_PEND_CPU_DATA_b, &host->pending_events)) {
-			stat |= readw(host->base + MMC_REG_STATUS);
-			if (imxmci_cpu_driven_data(host, &stat)) {
-				if (test_and_clear_bit(IMXMCI_PEND_WAIT_RESP_b, &host->pending_events))
-					imxmci_cmd_done(host, stat);
-				atomic_clear_mask(IMXMCI_PEND_IRQ_m|IMXMCI_PEND_CPU_DATA_m,
-						  &host->pending_events);
-				imxmci_data_done(host, stat);
-			}
-		}
-	}
-
-	if (test_bit(IMXMCI_PEND_DMA_END_b, &host->pending_events) &&
-	    !test_bit(IMXMCI_PEND_WAIT_RESP_b, &host->pending_events)) {
-
-		stat = readw(host->base + MMC_REG_STATUS);
-		/* Same as above */
-		stat |= host->status_reg;
-
-		if (host->dma_dir == DMA_TO_DEVICE)
-			data_dir_mask = STATUS_WRITE_OP_DONE;
-		else
-			data_dir_mask = STATUS_DATA_TRANS_DONE;
-
-		if (stat & data_dir_mask) {
-			clear_bit(IMXMCI_PEND_DMA_END_b, &host->pending_events);
-			imxmci_data_done(host, stat);
-		}
-	}
-
-	if (test_and_clear_bit(IMXMCI_PEND_CARD_XCHG_b, &host->pending_events)) {
-
-		if (host->cmd)
-			imxmci_cmd_done(host, STATUS_TIME_OUT_RESP);
-
-		if (host->data)
-			imxmci_data_done(host, STATUS_TIME_OUT_READ |
-					 STATUS_CRC_READ_ERR | STATUS_CRC_WRITE_ERR);
-
-		if (host->req)
-			imxmci_finish_request(host, host->req);
-
-		mmc_detect_change(host->mmc, msecs_to_jiffies(100));
-
-	}
-}
-
-static void imxmci_request(struct mmc_host *mmc, struct mmc_request *req)
-{
-	struct imxmci_host *host = mmc_priv(mmc);
-	unsigned int cmdat;
-
-	WARN_ON(host->req != NULL);
-
-	host->req = req;
-
-	cmdat = 0;
-
-	if (req->data) {
-		imxmci_setup_data(host, req->data);
-
-		cmdat |= CMD_DAT_CONT_DATA_ENABLE;
-
-		if (req->data->flags & MMC_DATA_WRITE)
-			cmdat |= CMD_DAT_CONT_WRITE;
-
-		if (req->data->flags & MMC_DATA_STREAM)
-			cmdat |= CMD_DAT_CONT_STREAM_BLOCK;
-	}
-
-	imxmci_start_cmd(host, req->cmd, cmdat);
-}
-
-#define CLK_RATE 19200000
-
-static void imxmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
-{
-	struct imxmci_host *host = mmc_priv(mmc);
-	int prescaler;
-
-	if (ios->bus_width == MMC_BUS_WIDTH_4) {
-		host->actual_bus_width = MMC_BUS_WIDTH_4;
-		imx_gpio_mode(PB11_PF_SD_DAT3);
-		BLR(host->dma) = 0;	/* burst 64 byte read/write */
-	} else {
-		host->actual_bus_width = MMC_BUS_WIDTH_1;
-		imx_gpio_mode(GPIO_PORTB | GPIO_IN | GPIO_PUEN | 11);
-		BLR(host->dma) = 16;	/* burst 16 byte read/write */
-	}
-
-	if (host->power_mode != ios->power_mode) {
-		switch (ios->power_mode) {
-		case MMC_POWER_OFF:
-			break;
-		case MMC_POWER_UP:
-			set_bit(IMXMCI_PEND_SET_INIT_b, &host->pending_events);
-			break;
-		case MMC_POWER_ON:
-			break;
-		}
-		host->power_mode = ios->power_mode;
-	}
-
-	if (ios->clock) {
-		unsigned int clk;
-		u16 reg;
-
-		/* The prescaler is 5 for PERCLK2 equal to 96MHz
-		 * then 96MHz / 5 = 19.2 MHz
-		 */
-		clk = clk_get_rate(host->clk);
-		prescaler = (clk + (CLK_RATE * 7) / 8) / CLK_RATE;
-		switch (prescaler) {
-		case 0:
-		case 1:	prescaler = 0;
-			break;
-		case 2:	prescaler = 1;
-			break;
-		case 3:	prescaler = 2;
-			break;
-		case 4:	prescaler = 4;
-			break;
-		default:
-		case 5:	prescaler = 5;
-			break;
-		}
-
-		dev_dbg(mmc_dev(host->mmc), "PERCLK2 %d MHz -> prescaler %d\n",
-			clk, prescaler);
-
-		for (clk = 0; clk < 8; clk++) {
-			int x;
-			x = CLK_RATE / (1 << clk);
-			if (x <= ios->clock)
-				break;
-		}
-
-		/* enable controller */
-		reg = readw(host->base + MMC_REG_STR_STP_CLK);
-		writew(reg | STR_STP_CLK_ENABLE,
-				host->base + MMC_REG_STR_STP_CLK);
-
-		imxmci_stop_clock(host);
-		writew((prescaler << 3) | clk, host->base + MMC_REG_CLK_RATE);
-		/*
-		 * Under my understanding, clock should not be started there, because it would
-		 * initiate SDHC sequencer and send last or random command into card
-		 */
-		/* imxmci_start_clock(host); */
-
-		dev_dbg(mmc_dev(host->mmc),
-			"MMC_CLK_RATE: 0x%08x\n",
-			readw(host->base + MMC_REG_CLK_RATE));
-	} else {
-		imxmci_stop_clock(host);
-	}
-}
-
-static int imxmci_get_ro(struct mmc_host *mmc)
-{
-	struct imxmci_host *host = mmc_priv(mmc);
-
-	if (host->pdata && host->pdata->get_ro)
-		return !!host->pdata->get_ro(mmc_dev(mmc));
-	/*
-	 * Board doesn't support read only detection; let the mmc core
-	 * decide what to do.
-	 */
-	return -ENOSYS;
-}
-
-
-static const struct mmc_host_ops imxmci_ops = {
-	.request	= imxmci_request,
-	.set_ios	= imxmci_set_ios,
-	.get_ro		= imxmci_get_ro,
-};
-
-static void imxmci_check_status(unsigned long data)
-{
-	struct imxmci_host *host = (struct imxmci_host *)data;
-
-	if (host->pdata && host->pdata->card_present &&
-	    host->pdata->card_present(mmc_dev(host->mmc)) != host->present) {
-		host->present ^= 1;
-		dev_info(mmc_dev(host->mmc), "card %s\n",
-		      host->present ? "inserted" : "removed");
-
-		set_bit(IMXMCI_PEND_CARD_XCHG_b, &host->pending_events);
-		tasklet_schedule(&host->tasklet);
-	}
-
-	if (test_bit(IMXMCI_PEND_WAIT_RESP_b, &host->pending_events) ||
-	    test_bit(IMXMCI_PEND_DMA_DATA_b, &host->pending_events)) {
-		atomic_inc(&host->stuck_timeout);
-		if (atomic_read(&host->stuck_timeout) > 4)
-			tasklet_schedule(&host->tasklet);
-	} else {
-		atomic_set(&host->stuck_timeout, 0);
-
-	}
-
-	mod_timer(&host->timer, jiffies + (HZ>>1));
-}
-
-static int __init imxmci_probe(struct platform_device *pdev)
-{
-	struct mmc_host *mmc;
-	struct imxmci_host *host = NULL;
-	struct resource *r;
-	int ret = 0, irq;
-	u16 rev_no;
-
-	pr_info("i.MX mmc driver\n");
-
-	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	irq = platform_get_irq(pdev, 0);
-	if (!r || irq < 0)
-		return -ENXIO;
-
-	r = request_mem_region(r->start, resource_size(r), pdev->name);
-	if (!r)
-		return -EBUSY;
-
-	mmc = mmc_alloc_host(sizeof(struct imxmci_host), &pdev->dev);
-	if (!mmc) {
-		ret = -ENOMEM;
-		goto out;
-	}
-
-	mmc->ops = &imxmci_ops;
-	mmc->f_min = 150000;
-	mmc->f_max = CLK_RATE/2;
-	mmc->ocr_avail = MMC_VDD_32_33;
-	mmc->caps = MMC_CAP_4_BIT_DATA;
-
-	/* MMC core transfer sizes tunable parameters */
-	mmc->max_segs = 64;
-	mmc->max_seg_size = 64*512;	/* default PAGE_CACHE_SIZE */
-	mmc->max_req_size = 64*512;	/* default PAGE_CACHE_SIZE */
-	mmc->max_blk_size = 2048;
-	mmc->max_blk_count = 65535;
-
-	host = mmc_priv(mmc);
-	host->base = ioremap(r->start, resource_size(r));
-	if (!host->base) {
-		ret = -ENOMEM;
-		goto out;
-	}
-
-	host->mmc = mmc;
-	host->dma_allocated = 0;
-	host->pdata = pdev->dev.platform_data;
-	if (!host->pdata)
-		dev_warn(&pdev->dev, "No platform data provided!\n");
-
-	spin_lock_init(&host->lock);
-	host->res = r;
-	host->irq = irq;
-
-	host->clk = clk_get(&pdev->dev, "perclk2");
-	if (IS_ERR(host->clk)) {
-		ret = PTR_ERR(host->clk);
-		goto out;
-	}
-	clk_enable(host->clk);
-
-	imx_gpio_mode(PB8_PF_SD_DAT0);
-	imx_gpio_mode(PB9_PF_SD_DAT1);
-	imx_gpio_mode(PB10_PF_SD_DAT2);
-	/* Configured as GPIO with pull-up to ensure right MCC card mode */
-	/* Switched to PB11_PF_SD_DAT3 if 4 bit bus is configured */
-	imx_gpio_mode(GPIO_PORTB | GPIO_IN | GPIO_PUEN | 11);
-	/* imx_gpio_mode(PB11_PF_SD_DAT3); */
-	imx_gpio_mode(PB12_PF_SD_CLK);
-	imx_gpio_mode(PB13_PF_SD_CMD);
-
-	imxmci_softreset(host);
-
-	rev_no = readw(host->base + MMC_REG_REV_NO);
-	if (rev_no != 0x390) {
-		dev_err(mmc_dev(host->mmc), "wrong rev.no. 0x%08x. aborting.\n",
-			readw(host->base + MMC_REG_REV_NO));
-		goto out;
-	}
-
-	/* recommended in data sheet */
-	writew(0x2db4, host->base + MMC_REG_READ_TO);
-
-	host->imask = IMXMCI_INT_MASK_DEFAULT;
-	writew(host->imask, host->base + MMC_REG_INT_MASK);
-
-	host->dma = imx_dma_request_by_prio(DRIVER_NAME, DMA_PRIO_LOW);
-	if(host->dma < 0) {
-		dev_err(mmc_dev(host->mmc), "imx_dma_request_by_prio failed\n");
-		ret = -EBUSY;
-		goto out;
-	}
-	host->dma_allocated = 1;
-	imx_dma_setup_handlers(host->dma, imxmci_dma_irq, NULL, host);
-	RSSR(host->dma) = DMA_REQ_SDHC;
-
-	tasklet_init(&host->tasklet, imxmci_tasklet_fnc, (unsigned long)host);
-	host->status_reg=0;
-	host->pending_events=0;
-
-	ret = request_irq(host->irq, imxmci_irq, 0, DRIVER_NAME, host);
-	if (ret)
-		goto out;
-
-	if (host->pdata && host->pdata->card_present)
-		host->present = host->pdata->card_present(mmc_dev(mmc));
-	else	/* if there is no way to detect assume that card is present */
-		host->present = 1;
-
-	init_timer(&host->timer);
-	host->timer.data = (unsigned long)host;
-	host->timer.function = imxmci_check_status;
-	add_timer(&host->timer);
-	mod_timer(&host->timer, jiffies + (HZ >> 1));
-
-	platform_set_drvdata(pdev, mmc);
-
-	mmc_add_host(mmc);
-
-	return 0;
-
-out:
-	if (host) {
-		if (host->dma_allocated) {
-			imx_dma_free(host->dma);
-			host->dma_allocated = 0;
-		}
-		if (host->clk) {
-			clk_disable(host->clk);
-			clk_put(host->clk);
-		}
-		if (host->base)
-			iounmap(host->base);
-	}
-	if (mmc)
-		mmc_free_host(mmc);
-	release_mem_region(r->start, resource_size(r));
-	return ret;
-}
-
-static int __exit imxmci_remove(struct platform_device *pdev)
-{
-	struct mmc_host *mmc = platform_get_drvdata(pdev);
-
-	platform_set_drvdata(pdev, NULL);
-
-	if (mmc) {
-		struct imxmci_host *host = mmc_priv(mmc);
-
-		tasklet_disable(&host->tasklet);
-
-		del_timer_sync(&host->timer);
-		mmc_remove_host(mmc);
-
-		free_irq(host->irq, host);
-		iounmap(host->base);
-		if (host->dma_allocated) {
-			imx_dma_free(host->dma);
-			host->dma_allocated = 0;
-		}
-
-		tasklet_kill(&host->tasklet);
-
-		clk_disable(host->clk);
-		clk_put(host->clk);
-
-		release_mem_region(host->res->start, resource_size(host->res));
-
-		mmc_free_host(mmc);
-	}
-	return 0;
-}
-
-#ifdef CONFIG_PM
-static int imxmci_suspend(struct platform_device *dev, pm_message_t state)
-{
-	struct mmc_host *mmc = platform_get_drvdata(dev);
-	int ret = 0;
-
-	if (mmc)
-		ret = mmc_suspend_host(mmc);
-
-	return ret;
-}
-
-static int imxmci_resume(struct platform_device *dev)
-{
-	struct mmc_host *mmc = platform_get_drvdata(dev);
-	struct imxmci_host *host;
-	int ret = 0;
-
-	if (mmc) {
-		host = mmc_priv(mmc);
-		if (host)
-			set_bit(IMXMCI_PEND_SET_INIT_b, &host->pending_events);
-		ret = mmc_resume_host(mmc);
-	}
-
-	return ret;
-}
-#else
-#define imxmci_suspend  NULL
-#define imxmci_resume   NULL
-#endif /* CONFIG_PM */
-
-static struct platform_driver imxmci_driver = {
-	.remove		= __exit_p(imxmci_remove),
-	.suspend	= imxmci_suspend,
-	.resume		= imxmci_resume,
-	.driver		= {
-		.name		= DRIVER_NAME,
-		.owner		= THIS_MODULE,
-	}
-};
-
-static int __init imxmci_init(void)
-{
-	return platform_driver_probe(&imxmci_driver, imxmci_probe);
-}
-
-static void __exit imxmci_exit(void)
-{
-	platform_driver_unregister(&imxmci_driver);
-}
-
-module_init(imxmci_init);
-module_exit(imxmci_exit);
-
-MODULE_DESCRIPTION("i.MX Multimedia Card Interface Driver");
-MODULE_AUTHOR("Sascha Hauer, Pengutronix");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:imx-mmc");
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/imxmmc.h linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/imxmmc.h
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/imxmmc.h	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/imxmmc.h	1970-01-01 08:00:00.000000000 +0800
@@ -1,64 +0,0 @@
-#define MMC_REG_STR_STP_CLK		0x00
-#define MMC_REG_STATUS			0x04
-#define MMC_REG_CLK_RATE		0x08
-#define MMC_REG_CMD_DAT_CONT		0x0C
-#define MMC_REG_RES_TO			0x10
-#define MMC_REG_READ_TO			0x14
-#define MMC_REG_BLK_LEN			0x18
-#define MMC_REG_NOB			0x1C
-#define MMC_REG_REV_NO			0x20
-#define MMC_REG_INT_MASK		0x24
-#define MMC_REG_CMD			0x28
-#define MMC_REG_ARGH			0x2C
-#define MMC_REG_ARGL			0x30
-#define MMC_REG_RES_FIFO		0x34
-#define MMC_REG_BUFFER_ACCESS		0x38
-
-#define STR_STP_CLK_IPG_CLK_GATE_DIS    (1<<15)
-#define STR_STP_CLK_IPG_PERCLK_GATE_DIS (1<<14)
-#define STR_STP_CLK_ENDIAN              (1<<5)
-#define STR_STP_CLK_RESET               (1<<3)
-#define STR_STP_CLK_ENABLE              (1<<2)
-#define STR_STP_CLK_START_CLK           (1<<1)
-#define STR_STP_CLK_STOP_CLK            (1<<0)
-#define STATUS_CARD_PRESENCE            (1<<15)
-#define STATUS_SDIO_INT_ACTIVE          (1<<14)
-#define STATUS_END_CMD_RESP             (1<<13)
-#define STATUS_WRITE_OP_DONE            (1<<12)
-#define STATUS_DATA_TRANS_DONE          (1<<11)
-#define STATUS_WR_CRC_ERROR_CODE_MASK   (3<<10)
-#define STATUS_CARD_BUS_CLK_RUN         (1<<8)
-#define STATUS_APPL_BUFF_FF             (1<<7)
-#define STATUS_APPL_BUFF_FE             (1<<6)
-#define STATUS_RESP_CRC_ERR             (1<<5)
-#define STATUS_CRC_READ_ERR             (1<<3)
-#define STATUS_CRC_WRITE_ERR            (1<<2)
-#define STATUS_TIME_OUT_RESP            (1<<1)
-#define STATUS_TIME_OUT_READ            (1<<0)
-#define STATUS_ERR_MASK                 0x2f
-#define CLK_RATE_PRESCALER(x)           ((x) & 0x7)
-#define CLK_RATE_CLK_RATE(x)            (((x) & 0x7) << 3)
-#define CMD_DAT_CONT_CMD_RESP_LONG_OFF  (1<<12)
-#define CMD_DAT_CONT_STOP_READWAIT      (1<<11)
-#define CMD_DAT_CONT_START_READWAIT     (1<<10)
-#define CMD_DAT_CONT_BUS_WIDTH_1        (0<<8)
-#define CMD_DAT_CONT_BUS_WIDTH_4        (2<<8)
-#define CMD_DAT_CONT_INIT               (1<<7)
-#define CMD_DAT_CONT_BUSY               (1<<6)
-#define CMD_DAT_CONT_STREAM_BLOCK       (1<<5)
-#define CMD_DAT_CONT_WRITE              (1<<4)
-#define CMD_DAT_CONT_DATA_ENABLE        (1<<3)
-#define CMD_DAT_CONT_RESPONSE_FORMAT_R1 (1)
-#define CMD_DAT_CONT_RESPONSE_FORMAT_R2 (2)
-#define CMD_DAT_CONT_RESPONSE_FORMAT_R3 (3)
-#define CMD_DAT_CONT_RESPONSE_FORMAT_R4 (4)
-#define CMD_DAT_CONT_RESPONSE_FORMAT_R5 (5)
-#define CMD_DAT_CONT_RESPONSE_FORMAT_R6 (6)
-#define INT_MASK_AUTO_CARD_DETECT       (1<<6)
-#define INT_MASK_DAT0_EN                (1<<5)
-#define INT_MASK_SDIO                   (1<<4)
-#define INT_MASK_BUF_READY              (1<<3)
-#define INT_MASK_END_CMD_RES            (1<<2)
-#define INT_MASK_WRITE_OP_DONE          (1<<1)
-#define INT_MASK_DATA_TRAN              (1<<0)
-#define INT_ALL                         (0x7f)
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/jz4740_mmc.c linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/jz4740_mmc.c
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/jz4740_mmc.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/jz4740_mmc.c	2014-09-12 15:59:37.348052000 +0800
@@ -702,7 +702,7 @@
 	JZ_GPIO_BULK_PIN(MSC_DATA3),
 };
 
-static int __devinit jz4740_mmc_request_gpio(struct device *dev, int gpio,
+static int jz4740_mmc_request_gpio(struct device *dev, int gpio,
 	const char *name, bool output, int value)
 {
 	int ret;
@@ -724,7 +724,7 @@
 	return 0;
 }
 
-static int __devinit jz4740_mmc_request_gpios(struct platform_device *pdev)
+static int jz4740_mmc_request_gpios(struct platform_device *pdev)
 {
 	int ret;
 	struct jz4740_mmc_platform_data *pdata = pdev->dev.platform_data;
@@ -759,7 +759,7 @@
 	return ret;
 }
 
-static int __devinit jz4740_mmc_request_cd_irq(struct platform_device *pdev,
+static int jz4740_mmc_request_cd_irq(struct platform_device *pdev,
 	struct jz4740_mmc_host *host)
 {
 	struct jz4740_mmc_platform_data *pdata = pdev->dev.platform_data;
@@ -802,7 +802,7 @@
 	return num_pins;
 }
 
-static int __devinit jz4740_mmc_probe(struct platform_device* pdev)
+static int jz4740_mmc_probe(struct platform_device* pdev)
 {
 	int ret;
 	struct mmc_host *mmc;
@@ -938,7 +938,7 @@
 	return ret;
 }
 
-static int __devexit jz4740_mmc_remove(struct platform_device *pdev)
+static int jz4740_mmc_remove(struct platform_device *pdev)
 {
 	struct jz4740_mmc_host *host = platform_get_drvdata(pdev);
 
@@ -1004,7 +1004,7 @@
 
 static struct platform_driver jz4740_mmc_driver = {
 	.probe = jz4740_mmc_probe,
-	.remove = __devexit_p(jz4740_mmc_remove),
+	.remove = jz4740_mmc_remove,
 	.driver = {
 		.name = "jz4740-mmc",
 		.owner = THIS_MODULE,
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/Kconfig linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/Kconfig
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/Kconfig	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/Kconfig	2014-09-12 15:59:37.348052000 +0800
@@ -69,7 +69,7 @@
 	  If unsure, say N.
 
 config MMC_RICOH_MMC
-	bool "Ricoh MMC Controller Disabler  (EXPERIMENTAL)"
+	bool "Ricoh MMC Controller Disabler"
 	depends on MMC_SDHCI_PCI
 	help
 	  This adds a pci quirk to disable Ricoh MMC Controller. This
@@ -81,6 +81,18 @@
 
 	  If unsure, say Y.
 
+config MMC_SDHCI_ACPI
+	tristate "SDHCI support for ACPI enumerated SDHCI controllers"
+	depends on MMC_SDHCI && ACPI
+	help
+	  This selects support for ACPI enumerated SDHCI controllers,
+	  identified by ACPI Compatibility ID PNP0D40 or specific
+	  ACPI Hardware IDs.
+
+	  If you have a controller with this interface, say Y or M here.
+
+	  If unsure, say N.
+
 config MMC_SDHCI_PLTFM
 	tristate "SDHCI platform and OF driver helper"
 	depends on MMC_SDHCI
@@ -174,8 +186,16 @@
 	  often referrered to as the HSMMC block in some of the Samsung S3C
 	  range of SoC.
 
-	  Note, due to the problems with DMA, the DMA support is only
-	  available with CONFIG_EXPERIMENTAL is selected.
+	  If you have a controller with this interface, say Y or M here.
+
+	  If unsure, say N.
+
+config MMC_SDHCI_SIRF
+	tristate "SDHCI support on CSR SiRFprimaII and SiRFmarco SoCs"
+	depends on ARCH_SIRF
+	depends on MMC_SDHCI_PLTFM
+	help
+	  This selects the SDHCI support for SiRF System-on-Chip devices.
 
 	  If you have a controller with this interface, say Y or M here.
 
@@ -221,7 +241,7 @@
 
 config MMC_SDHCI_S3C_DMA
 	bool "DMA support on S3C SDHCI"
-	depends on MMC_SDHCI_S3C && EXPERIMENTAL
+	depends on MMC_SDHCI_S3C
 	help
 	  Enable DMA support on the Samsung S3C SDHCI glue. The DMA
 	  has proved to be problematic if the controller encounters
@@ -229,6 +249,17 @@
 
 	  YMMV.
 
+config MMC_SDHCI_BCM2835
+	tristate "SDHCI platform support for the BCM2835 SD/MMC Controller"
+	depends on ARCH_BCM2835
+	depends on MMC_SDHCI_PLTFM
+	select MMC_SDHCI_IO_ACCESSORS
+	help
+	  This selects the BCM2835 SD/MMC controller. If you have a BCM2835
+	  platform with SD or MMC devices, say Y or M here.
+
+	  If unsure, say N.
+
 config MMC_OMAP
 	tristate "TI OMAP Multimedia Card Interface support"
 	depends on ARCH_OMAP
@@ -270,23 +301,8 @@
 
 	  If unsure, say N.
 
-choice
-	prompt "Atmel SD/MMC Driver"
-	depends on AVR32 || ARCH_AT91
-	default MMC_ATMELMCI if AVR32
-	help
-	  Choose which driver to use for the Atmel MCI Silicon
-
-config MMC_AT91
-	tristate "AT91 SD/MMC Card Interface support"
-	depends on ARCH_AT91
-	help
-	  This selects the AT91 MCI controller.
-
-	  If unsure, say N.
-
 config MMC_ATMELMCI
-	tristate "Atmel Multimedia Card Interface support"
+	tristate "Atmel SD/MMC Driver (Multimedia Card Interface)"
 	depends on AVR32 || ARCH_AT91
 	help
 	  This selects the Atmel Multimedia Card Interface driver. If
@@ -295,28 +311,6 @@
 
 	  If unsure, say N.
 
-endchoice
-
-config MMC_ATMELMCI_DMA
-	bool "Atmel MCI DMA support"
-	depends on MMC_ATMELMCI && (AVR32 || ARCH_AT91SAM9G45) && DMA_ENGINE
-	help
-	  Say Y here to have the Atmel MCI driver use a DMA engine to
-	  do data transfers and thus increase the throughput and
-	  reduce the CPU utilization.
-
-	  If unsure, say N.
-
-config MMC_IMX
-	tristate "Motorola i.MX Multimedia Card Interface support"
-	depends on ARCH_MX1
-	help
-	  This selects the Motorola i.MX Multimedia card Interface.
-	  If you have a i.MX platform with a Multimedia Card slot,
-	  say Y or M here.
-
-	  If unsure, say N.
-
 config MMC_MSM
 	tristate "Qualcomm SDCC Controller Support"
 	depends on MMC && ARCH_MSM
@@ -326,12 +320,12 @@
 	  support for SDIO devices.
 
 config MMC_MXC
-	tristate "Freescale i.MX21/27/31 Multimedia Card Interface support"
-	depends on ARCH_MXC
+	tristate "Freescale i.MX21/27/31 or MPC512x Multimedia Card support"
+	depends on ARCH_MXC || PPC_MPC512x
 	help
-	  This selects the Freescale i.MX21, i.MX27 and i.MX31 Multimedia card
-	  Interface. If you have a i.MX platform with a Multimedia Card slot,
-	  say Y or M here.
+	  This selects the Freescale i.MX21, i.MX27, i.MX31 or MPC512x
+	  Multimedia Card Interface. If you have an i.MX or MPC512x platform
+	  with a Multimedia Card slot, say Y or M here.
 
 	  If unsure, say N.
 
@@ -345,8 +339,8 @@
 	  If unsure, say N.
 
 config MMC_TIFM_SD
-	tristate "TI Flash Media MMC/SD Interface support  (EXPERIMENTAL)"
-	depends on EXPERIMENTAL && PCI
+	tristate "TI Flash Media MMC/SD Interface support"
+	depends on PCI
 	select TIFM_CORE
 	help
 	  Say Y here if you want to be able to access MMC/SD cards with
@@ -379,6 +373,13 @@
           If you have an DAVINCI board with a Multimedia Card slot,
           say Y or M here.  If unsure, say N.
 
+config MMC_GOLDFISH
+	tristate "goldfish qemu Multimedia Card Interface support"
+	depends on GOLDFISH
+	help
+	  This selects the Goldfish Multimedia card Interface emulation
+	  found on the Goldfish Android virtual device emulation.
+
 config MMC_SPI
 	tristate "MMC/SD/SDIO over SPI"
 	depends on SPI_MASTER && !HIGHMEM && HAS_DMA
@@ -425,8 +426,7 @@
 	  the S3C MCI driver.
 
 config MMC_S3C_DMA
-	bool "Use DMA transfers only (EXPERIMENTAL)"
-	depends on EXPERIMENTAL
+	bool "Use DMA transfers only"
 	help
 	  Use DMA to transfer data between memory and the hardare.
 
@@ -435,7 +435,7 @@
 	  option is useful.
 
 config MMC_S3C_PIODMA
-	bool "Support for both PIO and DMA (EXPERIMENTAL)"
+	bool "Support for both PIO and DMA"
 	help
 	  Compile both the PIO and DMA transfer routines into the
 	  driver and let the platform select at run-time which one
@@ -446,8 +446,8 @@
 endchoice
 
 config MMC_SDRICOH_CS
-	tristate "MMC/SD driver for Ricoh Bay1Controllers (EXPERIMENTAL)"
-	depends on EXPERIMENTAL && PCI && PCMCIA
+	tristate "MMC/SD driver for Ricoh Bay1Controllers"
+	depends on PCI && PCMCIA
 	help
 	  Say Y here if your Notebook reports a Ricoh Bay1Controller PCMCIA
 	  card whenever you insert a MMC or SD card into the card slot.
@@ -476,7 +476,7 @@
 
 config MMC_CB710
 	tristate "ENE CB710 MMC/SD Interface support"
-	depends on PCI
+	depends on PCI && GENERIC_HARDIRQS
 	select CB710_CORE
 	help
 	  This option enables support for MMC/SD part of ENE CB710/720 Flash
@@ -547,6 +547,15 @@
 
 	  If unsure, say Y.
 
+config MMC_DW_EXYNOS
+	tristate "Exynos specific extensions for Synopsys DW Memory Card Interface"
+	depends on MMC_DW
+	select MMC_DW_PLTFM
+	help
+	  This selects support for Samsung Exynos SoC specific extensions to the
+	  Synopsys DesignWare Memory Card Interface driver. Select this option
+	  for platforms based on Exynos4 and Exynos5 SoC's.
+
 config MMC_DW_PCI
 	tristate "Synopsys Designware MCI support on PCI bus"
 	depends on MMC_DW && PCI
@@ -619,3 +628,21 @@
 
 	  Note: These controllers only support SDIO cards and do not
 	  support MMC or SD memory cards.
+
+config MMC_WMT
+	tristate "Wondermedia SD/MMC Host Controller support"
+	depends on ARCH_VT8500
+	default y
+	help
+	  This selects support for the SD/MMC Host Controller on
+	  Wondermedia WM8505/WM8650 based SoCs.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called wmt-sdmmc.
+
+config MMC_REALTEK_PCI
+	tristate "Realtek PCI-E SD/MMC Card Interface Driver"
+	depends on MFD_RTSX_PCI
+	help
+	  Say Y here to include driver code to support SD/MMC card interface
+	  of Realtek PCI-E card reader
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/Makefile linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/Makefile
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/Makefile	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/Makefile	2014-09-12 15:59:37.348052000 +0800
@@ -4,26 +4,27 @@
 
 obj-$(CONFIG_MMC_ARMMMCI)	+= mmci.o
 obj-$(CONFIG_MMC_PXA)		+= pxamci.o
-obj-$(CONFIG_MMC_IMX)		+= imxmmc.o
 obj-$(CONFIG_MMC_MXC)		+= mxcmmc.o
 obj-$(CONFIG_MMC_MXS)		+= mxs-mmc.o
 obj-$(CONFIG_MMC_SDHCI)		+= sdhci.o
 obj-$(CONFIG_MMC_SDHCI_PCI)	+= sdhci-pci.o
 obj-$(subst m,y,$(CONFIG_MMC_SDHCI_PCI))	+= sdhci-pci-data.o
+obj-$(CONFIG_MMC_SDHCI_ACPI)	+= sdhci-acpi.o
 obj-$(CONFIG_MMC_SDHCI_PXAV3)	+= sdhci-pxav3.o
 obj-$(CONFIG_MMC_SDHCI_PXAV2)	+= sdhci-pxav2.o
 obj-$(CONFIG_MMC_SDHCI_S3C)	+= sdhci-s3c.o
+obj-$(CONFIG_MMC_SDHCI_SIRF)   	+= sdhci-sirf.o
 obj-$(CONFIG_MMC_SDHCI_SPEAR)	+= sdhci-spear.o
 obj-$(CONFIG_MMC_WBSD)		+= wbsd.o
 obj-$(CONFIG_MMC_AU1X)		+= au1xmmc.o
 obj-$(CONFIG_MMC_OMAP)		+= omap.o
 obj-$(CONFIG_MMC_OMAP_HS)	+= omap_hsmmc.o
-obj-$(CONFIG_MMC_AT91)		+= at91_mci.o
 obj-$(CONFIG_MMC_ATMELMCI)	+= atmel-mci.o
 obj-$(CONFIG_MMC_TIFM_SD)	+= tifm_sd.o
 obj-$(CONFIG_MMC_MSM)		+= msm_sdcc.o
 obj-$(CONFIG_MMC_MVSDIO)	+= mvsdio.o
 obj-$(CONFIG_MMC_DAVINCI)       += davinci_mmc.o
+obj-$(CONFIG_MMC_GOLDFISH)	+= android-goldfish.o
 obj-$(CONFIG_MMC_SPI)		+= mmc_spi.o
 ifeq ($(CONFIG_OF),y)
 obj-$(CONFIG_MMC_SPI)		+= of_mmc_spi.o
@@ -40,11 +41,17 @@
 obj-$(CONFIG_SDH_BFIN)		+= bfin_sdh.o
 obj-$(CONFIG_MMC_DW)		+= dw_mmc.o
 obj-$(CONFIG_MMC_DW_PLTFM)	+= dw_mmc-pltfm.o
+obj-$(CONFIG_MMC_DW_EXYNOS)	+= dw_mmc-exynos.o
 obj-$(CONFIG_MMC_DW_PCI)	+= dw_mmc-pci.o
 obj-$(CONFIG_MMC_SH_MMCIF)	+= sh_mmcif.o
 obj-$(CONFIG_MMC_JZ4740)	+= jz4740_mmc.o
 obj-$(CONFIG_MMC_VUB300)	+= vub300.o
 obj-$(CONFIG_MMC_USHC)		+= ushc.o
+obj-$(CONFIG_MMC_WMT)		+= wmt-sdmmc.o
+
+obj-$(CONFIG_MMC_REALTEK_PCI)	+= rtsx_pci_sdmmc.o
+
+obj-$(CONFIG_MMC_REALTEK_PCI)	+= rtsx_pci_sdmmc.o
 
 obj-$(CONFIG_MMC_SDHCI_PLTFM)		+= sdhci-pltfm.o
 obj-$(CONFIG_MMC_SDHCI_CNS3XXX)		+= sdhci-cns3xxx.o
@@ -53,6 +60,7 @@
 obj-$(CONFIG_MMC_SDHCI_TEGRA)		+= sdhci-tegra.o
 obj-$(CONFIG_MMC_SDHCI_OF_ESDHC)	+= sdhci-of-esdhc.o
 obj-$(CONFIG_MMC_SDHCI_OF_HLWD)		+= sdhci-of-hlwd.o
+obj-$(CONFIG_MMC_SDHCI_BCM2835)		+= sdhci-bcm2835.o
 
 ifeq ($(CONFIG_CB710_DEBUG),y)
 	CFLAGS-cb710-mmc	+= -DDEBUG
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/mmci.c linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/mmci.c
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/mmci.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/mmci.c	2014-09-12 15:59:37.348052000 +0800
@@ -15,22 +15,26 @@
 #include <linux/device.h>
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/err.h>
 #include <linux/highmem.h>
 #include <linux/log2.h>
+#include <linux/mmc/pm.h>
 #include <linux/mmc/host.h>
 #include <linux/mmc/card.h>
 #include <linux/amba/bus.h>
 #include <linux/clk.h>
 #include <linux/scatterlist.h>
 #include <linux/gpio.h>
+#include <linux/of_gpio.h>
 #include <linux/regulator/consumer.h>
 #include <linux/dmaengine.h>
 #include <linux/dma-mapping.h>
 #include <linux/amba/mmci.h>
 #include <linux/pm_runtime.h>
 #include <linux/types.h>
+#include <linux/pinctrl/consumer.h>
 
 #include <asm/div64.h>
 #include <asm/io.h>
@@ -56,6 +60,7 @@
  * @blksz_datactrl16: true if Block size is at b16..b30 position in datactrl register
  * @pwrreg_powerup: power up value for MMCIPOWER register
  * @signal_direction: input/out direction of bus signals can be indicated
+ * @pwrreg_clkgate: MMCIPOWER register must be used to gate the clock
  */
 struct variant_data {
 	unsigned int		clkreg;
@@ -68,6 +73,7 @@
 	bool			blksz_datactrl16;
 	u32			pwrreg_powerup;
 	bool			signal_direction;
+	bool			pwrreg_clkgate;
 };
 
 static struct variant_data variant_arm = {
@@ -84,6 +90,14 @@
 	.pwrreg_powerup		= MCI_PWR_UP,
 };
 
+static struct variant_data variant_arm_extended_fifo_hwfc = {
+	.fifosize		= 128 * 4,
+	.fifohalfsize		= 64 * 4,
+	.clkreg_enable		= MCI_ARM_HWFCEN,
+	.datalength_bits	= 16,
+	.pwrreg_powerup		= MCI_PWR_UP,
+};
+
 static struct variant_data variant_u300 = {
 	.fifosize		= 16 * 4,
 	.fifohalfsize		= 8 * 4,
@@ -92,6 +106,19 @@
 	.sdio			= true,
 	.pwrreg_powerup		= MCI_PWR_ON,
 	.signal_direction	= true,
+	.pwrreg_clkgate		= true,
+};
+
+static struct variant_data variant_nomadik = {
+	.fifosize		= 16 * 4,
+	.fifohalfsize		= 8 * 4,
+	.clkreg			= MCI_CLK_ENABLE,
+	.datalength_bits	= 24,
+	.sdio			= true,
+	.st_clkdiv		= true,
+	.pwrreg_powerup		= MCI_PWR_ON,
+	.signal_direction	= true,
+	.pwrreg_clkgate		= true,
 };
 
 static struct variant_data variant_ux500 = {
@@ -104,6 +131,7 @@
 	.st_clkdiv		= true,
 	.pwrreg_powerup		= MCI_PWR_ON,
 	.signal_direction	= true,
+	.pwrreg_clkgate		= true,
 };
 
 static struct variant_data variant_ux500v2 = {
@@ -117,9 +145,28 @@
 	.blksz_datactrl16	= true,
 	.pwrreg_powerup		= MCI_PWR_ON,
 	.signal_direction	= true,
+	.pwrreg_clkgate		= true,
 };
 
 /*
+ * Validate mmc prerequisites
+ */
+static int mmci_validate_data(struct mmci_host *host,
+			      struct mmc_data *data)
+{
+	if (!data)
+		return 0;
+
+	if (!is_power_of_2(data->blksz)) {
+		dev_err(mmc_dev(host->mmc),
+			"unsupported block size (%d bytes)\n", data->blksz);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/*
  * This must be called with host->lock held
  */
 static void mmci_write_clkreg(struct mmci_host *host, u32 clk)
@@ -188,6 +235,9 @@
 	if (host->mmc->ios.bus_width == MMC_BUS_WIDTH_8)
 		clk |= MCI_ST_8BIT_BUS;
 
+	if (host->mmc->ios.timing == MMC_TIMING_UHS_DDR50)
+		clk |= MCI_ST_UX500_NEG_EDGE;
+
 	mmci_write_clkreg(host, clk);
 }
 
@@ -248,7 +298,7 @@
  * no custom DMA interfaces are supported.
  */
 #ifdef CONFIG_DMA_ENGINE
-static void __devinit mmci_dma_setup(struct mmci_host *host)
+static void mmci_dma_setup(struct mmci_host *host)
 {
 	struct mmci_platform_data *plat = host->plat;
 	const char *rxname, *txname;
@@ -324,7 +374,7 @@
 }
 
 /*
- * This is used in __devinit or __devexit so inline it
+ * This is used in or so inline it
  * so it can be discarded.
  */
 static inline void mmci_dma_release(struct mmci_host *host)
@@ -338,10 +388,33 @@
 	host->dma_rx_channel = host->dma_tx_channel = NULL;
 }
 
+static void mmci_dma_data_error(struct mmci_host *host)
+{
+	dev_err(mmc_dev(host->mmc), "error during DMA transfer!\n");
+	dmaengine_terminate_all(host->dma_current);
+	host->dma_current = NULL;
+	host->dma_desc_current = NULL;
+	host->data->host_cookie = 0;
+}
+
 static void mmci_dma_unmap(struct mmci_host *host, struct mmc_data *data)
 {
-	struct dma_chan *chan = host->dma_current;
+	struct dma_chan *chan;
 	enum dma_data_direction dir;
+
+	if (data->flags & MMC_DATA_READ) {
+		dir = DMA_FROM_DEVICE;
+		chan = host->dma_rx_channel;
+	} else {
+		dir = DMA_TO_DEVICE;
+		chan = host->dma_tx_channel;
+	}
+
+	dma_unmap_sg(chan->device->dev, data->sg, data->sg_len, dir);
+}
+
+static void mmci_dma_finalize(struct mmci_host *host, struct mmc_data *data)
+{
 	u32 status;
 	int i;
 
@@ -360,19 +433,13 @@
 	 * contiguous buffers.  On TX, we'll get a FIFO underrun error.
 	 */
 	if (status & MCI_RXDATAAVLBLMASK) {
-		dmaengine_terminate_all(chan);
+		mmci_dma_data_error(host);
 		if (!data->error)
 			data->error = -EIO;
 	}
 
-	if (data->flags & MMC_DATA_WRITE) {
-		dir = DMA_TO_DEVICE;
-	} else {
-		dir = DMA_FROM_DEVICE;
-	}
-
 	if (!data->host_cookie)
-		dma_unmap_sg(chan->device->dev, data->sg, data->sg_len, dir);
+		mmci_dma_unmap(host, data);
 
 	/*
 	 * Use of DMA with scatter-gather is impossible.
@@ -382,16 +449,15 @@
 		dev_err(mmc_dev(host->mmc), "buggy DMA detected. Taking evasive action.\n");
 		mmci_dma_release(host);
 	}
-}
 
-static void mmci_dma_data_error(struct mmci_host *host)
-{
-	dev_err(mmc_dev(host->mmc), "error during DMA transfer!\n");
-	dmaengine_terminate_all(host->dma_current);
+	host->dma_current = NULL;
+	host->dma_desc_current = NULL;
 }
 
-static int mmci_dma_prep_data(struct mmci_host *host, struct mmc_data *data,
-			      struct mmci_host_next *next)
+/* prepares DMA channel and DMA descriptor, returns non-zero on failure */
+static int __mmci_dma_prep_data(struct mmci_host *host, struct mmc_data *data,
+				struct dma_chan **dma_chan,
+				struct dma_async_tx_descriptor **dma_desc)
 {
 	struct variant_data *variant = host->variant;
 	struct dma_slave_config conf = {
@@ -409,16 +475,6 @@
 	enum dma_data_direction buffer_dirn;
 	int nr_sg;
 
-	/* Check if next job is already prepared */
-	if (data->host_cookie && !next &&
-	    host->dma_current && host->dma_desc_current)
-		return 0;
-
-	if (!next) {
-		host->dma_current = NULL;
-		host->dma_desc_current = NULL;
-	}
-
 	if (data->flags & MMC_DATA_READ) {
 		conf.direction = DMA_DEV_TO_MEM;
 		buffer_dirn = DMA_FROM_DEVICE;
@@ -448,29 +504,41 @@
 	if (!desc)
 		goto unmap_exit;
 
-	if (next) {
-		next->dma_chan = chan;
-		next->dma_desc = desc;
-	} else {
-		host->dma_current = chan;
-		host->dma_desc_current = desc;
-	}
+	*dma_chan = chan;
+	*dma_desc = desc;
 
 	return 0;
 
  unmap_exit:
-	if (!next)
-		dmaengine_terminate_all(chan);
 	dma_unmap_sg(device->dev, data->sg, data->sg_len, buffer_dirn);
 	return -ENOMEM;
 }
 
+static inline int mmci_dma_prep_data(struct mmci_host *host,
+				     struct mmc_data *data)
+{
+	/* Check if next job is already prepared. */
+	if (host->dma_current && host->dma_desc_current)
+		return 0;
+
+	/* No job were prepared thus do it now. */
+	return __mmci_dma_prep_data(host, data, &host->dma_current,
+				    &host->dma_desc_current);
+}
+
+static inline int mmci_dma_prep_next(struct mmci_host *host,
+				     struct mmc_data *data)
+{
+	struct mmci_host_next *nd = &host->next_data;
+	return __mmci_dma_prep_data(host, data, &nd->dma_chan, &nd->dma_desc);
+}
+
 static int mmci_dma_start_data(struct mmci_host *host, unsigned int datactrl)
 {
 	int ret;
 	struct mmc_data *data = host->data;
 
-	ret = mmci_dma_prep_data(host, host->data, NULL);
+	ret = mmci_dma_prep_data(host, host->data);
 	if (ret)
 		return ret;
 
@@ -500,19 +568,11 @@
 {
 	struct mmci_host_next *next = &host->next_data;
 
-	if (data->host_cookie && data->host_cookie != next->cookie) {
-		pr_warning("[%s] invalid cookie: data->host_cookie %d"
-		       " host->next_data.cookie %d\n",
-		       __func__, data->host_cookie, host->next_data.cookie);
-		data->host_cookie = 0;
-	}
-
-	if (!data->host_cookie)
-		return;
+	WARN_ON(data->host_cookie && data->host_cookie != next->cookie);
+	WARN_ON(!data->host_cookie && (next->dma_desc || next->dma_chan));
 
 	host->dma_desc_current = next->dma_desc;
 	host->dma_current = next->dma_chan;
-
 	next->dma_desc = NULL;
 	next->dma_chan = NULL;
 }
@@ -527,19 +587,13 @@
 	if (!data)
 		return;
 
-	if (data->host_cookie) {
-		data->host_cookie = 0;
+	BUG_ON(data->host_cookie);
+
+	if (mmci_validate_data(host, data))
 		return;
-	}
 
-	/* if config for dma */
-	if (((data->flags & MMC_DATA_WRITE) && host->dma_tx_channel) ||
-	    ((data->flags & MMC_DATA_READ) && host->dma_rx_channel)) {
-		if (mmci_dma_prep_data(host, data, nd))
-			data->host_cookie = 0;
-		else
-			data->host_cookie = ++nd->cookie < 0 ? 1 : nd->cookie;
-	}
+	if (!mmci_dma_prep_next(host, data))
+		data->host_cookie = ++nd->cookie < 0 ? 1 : nd->cookie;
 }
 
 static void mmci_post_request(struct mmc_host *mmc, struct mmc_request *mrq,
@@ -547,29 +601,23 @@
 {
 	struct mmci_host *host = mmc_priv(mmc);
 	struct mmc_data *data = mrq->data;
-	struct dma_chan *chan;
-	enum dma_data_direction dir;
 
-	if (!data)
+	if (!data || !data->host_cookie)
 		return;
 
-	if (data->flags & MMC_DATA_READ) {
-		dir = DMA_FROM_DEVICE;
-		chan = host->dma_rx_channel;
-	} else {
-		dir = DMA_TO_DEVICE;
-		chan = host->dma_tx_channel;
-	}
+	mmci_dma_unmap(host, data);
 
+	if (err) {
+		struct mmci_host_next *next = &host->next_data;
+		struct dma_chan *chan;
+		if (data->flags & MMC_DATA_READ)
+			chan = host->dma_rx_channel;
+		else
+			chan = host->dma_tx_channel;
+		dmaengine_terminate_all(chan);
 
-	/* if config for dma */
-	if (chan) {
-		if (err)
-			dmaengine_terminate_all(chan);
-		if (data->host_cookie)
-			dma_unmap_sg(mmc_dev(host->mmc), data->sg,
-				     data->sg_len, dir);
-		mrq->data->host_cookie = 0;
+		next->dma_desc = NULL;
+		next->dma_chan = NULL;
 	}
 }
 
@@ -590,6 +638,11 @@
 {
 }
 
+static inline void mmci_dma_finalize(struct mmci_host *host,
+				     struct mmc_data *data)
+{
+}
+
 static inline void mmci_dma_data_error(struct mmci_host *host)
 {
 }
@@ -641,9 +694,34 @@
 
 	/* The ST Micro variants has a special bit to enable SDIO */
 	if (variant->sdio && host->mmc->card)
-		if (mmc_card_sdio(host->mmc->card))
+		if (mmc_card_sdio(host->mmc->card)) {
+			/*
+			 * The ST Micro variants has a special bit
+			 * to enable SDIO.
+			 */
+			u32 clk;
+
 			datactrl |= MCI_ST_DPSM_SDIOEN;
 
+			/*
+			 * The ST Micro variant for SDIO small write transfers
+			 * needs to have clock H/W flow control disabled,
+			 * otherwise the transfer will not start. The threshold
+			 * depends on the rate of MCLK.
+			 */
+			if (data->flags & MMC_DATA_WRITE &&
+			    (host->size < 8 ||
+			     (host->size <= 8 && host->mclk > 50000000)))
+				clk = host->clk_reg & ~variant->clkreg_enable;
+			else
+				clk = host->clk_reg | variant->clkreg_enable;
+
+			mmci_write_clkreg(host, clk);
+		}
+
+	if (host->mmc->ios.timing == MMC_TIMING_UHS_DDR50)
+		datactrl |= MCI_ST_DPSM_DDRMODE;
+
 	/*
 	 * Attempt to use DMA operation mode, if this
 	 * should fail, fall back to PIO mode
@@ -715,8 +793,10 @@
 		u32 remain, success;
 
 		/* Terminate the DMA transfer */
-		if (dma_inprogress(host))
+		if (dma_inprogress(host)) {
 			mmci_dma_data_error(host);
+			mmci_dma_unmap(host, data);
+		}
 
 		/*
 		 * Calculate how far we are into the transfer.  Note that
@@ -755,7 +835,7 @@
 
 	if (status & MCI_DATAEND || data->error) {
 		if (dma_inprogress(host))
-			mmci_dma_unmap(host, data);
+			mmci_dma_finalize(host, data);
 		mmci_stop_data(host);
 
 		if (!data->error)
@@ -792,8 +872,10 @@
 	if (!cmd->data || cmd->error) {
 		if (host->data) {
 			/* Terminate the DMA transfer */
-			if (dma_inprogress(host))
+			if (dma_inprogress(host)) {
 				mmci_dma_data_error(host);
+				mmci_dma_unmap(host, host->data);
+			}
 			mmci_stop_data(host);
 		}
 		mmci_request_end(host, cmd->mrq);
@@ -827,14 +909,14 @@
 		if (unlikely(count & 0x3)) {
 			if (count < 4) {
 				unsigned char buf[4];
-				readsl(base + MMCIFIFO, buf, 1);
+				ioread32_rep(base + MMCIFIFO, buf, 1);
 				memcpy(ptr, buf, count);
 			} else {
-				readsl(base + MMCIFIFO, ptr, count >> 2);
+				ioread32_rep(base + MMCIFIFO, ptr, count >> 2);
 				count &= ~0x3;
 			}
 		} else {
-			readsl(base + MMCIFIFO, ptr, count >> 2);
+			ioread32_rep(base + MMCIFIFO, ptr, count >> 2);
 		}
 
 		ptr += count;
@@ -864,22 +946,6 @@
 		count = min(remain, maxcnt);
 
 		/*
-		 * The ST Micro variant for SDIO transfer sizes
-		 * less then 8 bytes should have clock H/W flow
-		 * control disabled.
-		 */
-		if (variant->sdio &&
-		    mmc_card_sdio(host->mmc->card)) {
-			u32 clk;
-			if (count < 8)
-				clk = host->clk_reg & ~variant->clkreg_enable;
-			else
-				clk = host->clk_reg | variant->clkreg_enable;
-
-			mmci_write_clkreg(host, clk);
-		}
-
-		/*
 		 * SDIO especially may want to send something that is
 		 * not divisible by 4 (as opposed to card sectors
 		 * etc), and the FIFO only accept full 32-bit writes.
@@ -887,7 +953,7 @@
 		 * byte become a 32bit write, 7 bytes will be two
 		 * 32bit writes etc.
 		 */
-		writesl(base + MMCIFIFO, ptr, (count + 3) >> 2);
+		iowrite32_rep(base + MMCIFIFO, ptr, (count + 3) >> 2);
 
 		ptr += count;
 		remain -= count;
@@ -1035,10 +1101,8 @@
 
 	WARN_ON(host->mrq != NULL);
 
-	if (mrq->data && !is_power_of_2(mrq->data->blksz)) {
-		dev_err(mmc_dev(mmc), "unsupported block size (%d bytes)\n",
-			mrq->data->blksz);
-		mrq->cmd->error = -EINVAL;
+	mrq->cmd->error = mmci_validate_data(host, mrq->data);
+	if (mrq->cmd->error) {
 		mmc_request_done(mmc, mrq);
 		return;
 	}
@@ -1076,23 +1140,18 @@
 
 	switch (ios->power_mode) {
 	case MMC_POWER_OFF:
-		if (host->vcc)
-			ret = mmc_regulator_set_ocr(mmc, host->vcc, 0);
+		if (!IS_ERR(mmc->supply.vmmc))
+			mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, 0);
+
+		if (!IS_ERR(mmc->supply.vqmmc) &&
+		    regulator_is_enabled(mmc->supply.vqmmc))
+			regulator_disable(mmc->supply.vqmmc);
+
 		break;
 	case MMC_POWER_UP:
-		if (host->vcc) {
-			ret = mmc_regulator_set_ocr(mmc, host->vcc, ios->vdd);
-			if (ret) {
-				dev_err(mmc_dev(mmc), "unable to set OCR\n");
-				/*
-				 * The .set_ios() function in the mmc_host_ops
-				 * struct return void, and failing to set the
-				 * power should be rare so we print an error
-				 * and return here.
-				 */
-				goto out;
-			}
-		}
+		if (!IS_ERR(mmc->supply.vmmc))
+			mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, ios->vdd);
+
 		/*
 		 * The ST Micro variant doesn't have the PL180s MCI_PWR_UP
 		 * and instead uses MCI_PWR_ON so apply whatever value is
@@ -1102,6 +1161,14 @@
 
 		break;
 	case MMC_POWER_ON:
+		if (!IS_ERR(mmc->supply.vqmmc) &&
+		    !regulator_is_enabled(mmc->supply.vqmmc)) {
+			ret = regulator_enable(mmc->supply.vqmmc);
+			if (ret < 0)
+				dev_err(mmc_dev(mmc),
+					"failed to enable vqmmc regulator\n");
+		}
+
 		pwr |= MCI_PWR_ON;
 		break;
 	}
@@ -1134,6 +1201,13 @@
 		}
 	}
 
+	/*
+	 * If clock = 0 and the variant requires the MMCIPOWER to be used for
+	 * gating the clock, the MCI_PWR_ON bit is cleared.
+	 */
+	if (!ios->clock && variant->pwrreg_clkgate)
+		pwr &= ~MCI_PWR_ON;
+
 	spin_lock_irqsave(&host->lock, flags);
 
 	mmci_set_clkreg(host, ios->clock);
@@ -1141,7 +1215,6 @@
 
 	spin_unlock_irqrestore(&host->lock, flags);
 
- out:
 	pm_runtime_mark_last_busy(mmc_dev(mmc));
 	pm_runtime_put_autosuspend(mmc_dev(mmc));
 }
@@ -1196,21 +1269,77 @@
 	.get_cd		= mmci_get_cd,
 };
 
-static int __devinit mmci_probe(struct amba_device *dev,
+#ifdef CONFIG_OF
+static void mmci_dt_populate_generic_pdata(struct device_node *np,
+					struct mmci_platform_data *pdata)
+{
+	int bus_width = 0;
+
+	pdata->gpio_wp = of_get_named_gpio(np, "wp-gpios", 0);
+	pdata->gpio_cd = of_get_named_gpio(np, "cd-gpios", 0);
+
+	if (of_get_property(np, "cd-inverted", NULL))
+		pdata->cd_invert = true;
+	else
+		pdata->cd_invert = false;
+
+	of_property_read_u32(np, "max-frequency", &pdata->f_max);
+	if (!pdata->f_max)
+		pr_warn("%s has no 'max-frequency' property\n", np->full_name);
+
+	if (of_get_property(np, "mmc-cap-mmc-highspeed", NULL))
+		pdata->capabilities |= MMC_CAP_MMC_HIGHSPEED;
+	if (of_get_property(np, "mmc-cap-sd-highspeed", NULL))
+		pdata->capabilities |= MMC_CAP_SD_HIGHSPEED;
+
+	of_property_read_u32(np, "bus-width", &bus_width);
+	switch (bus_width) {
+	case 0 :
+		/* No bus-width supplied. */
+		break;
+	case 4 :
+		pdata->capabilities |= MMC_CAP_4_BIT_DATA;
+		break;
+	case 8 :
+		pdata->capabilities |= MMC_CAP_8_BIT_DATA;
+		break;
+	default :
+		pr_warn("%s: Unsupported bus width\n", np->full_name);
+	}
+}
+#else
+static void mmci_dt_populate_generic_pdata(struct device_node *np,
+					struct mmci_platform_data *pdata)
+{
+	return;
+}
+#endif
+
+static int mmci_probe(struct amba_device *dev,
 	const struct amba_id *id)
 {
 	struct mmci_platform_data *plat = dev->dev.platform_data;
+	struct device_node *np = dev->dev.of_node;
 	struct variant_data *variant = id->data;
 	struct mmci_host *host;
 	struct mmc_host *mmc;
 	int ret;
 
-	/* must have platform data */
+	/* Must have platform data or Device Tree. */
+	if (!plat && !np) {
+		dev_err(&dev->dev, "No plat data or DT found\n");
+		return -EINVAL;
+	}
+
 	if (!plat) {
-		ret = -EINVAL;
-		goto out;
+		plat = devm_kzalloc(&dev->dev, sizeof(*plat), GFP_KERNEL);
+		if (!plat)
+			return -ENOMEM;
 	}
 
+	if (np)
+		mmci_dt_populate_generic_pdata(np, plat);
+
 	ret = amba_request_regions(dev, DRIVER_NAME);
 	if (ret)
 		goto out;
@@ -1240,14 +1369,10 @@
 		goto host_free;
 	}
 
-	ret = clk_prepare(host->clk);
+	ret = clk_prepare_enable(host->clk);
 	if (ret)
 		goto clk_free;
 
-	ret = clk_enable(host->clk);
-	if (ret)
-		goto clk_unprep;
-
 	host->plat = plat;
 	host->variant = variant;
 	host->mclk = clk_get_rate(host->clk);
@@ -1295,32 +1420,36 @@
 		mmc->f_max = min(host->mclk, fmax);
 	dev_dbg(mmc_dev(mmc), "clocking block at %u Hz\n", mmc->f_max);
 
-#ifdef CONFIG_REGULATOR
-	/* If we're using the regulator framework, try to fetch a regulator */
-	host->vcc = regulator_get(&dev->dev, "vmmc");
-	if (IS_ERR(host->vcc))
-		host->vcc = NULL;
-	else {
-		int mask = mmc_regulator_get_ocrmask(host->vcc);
-
-		if (mask < 0)
-			dev_err(&dev->dev, "error getting OCR mask (%d)\n",
-				mask);
-		else {
-			host->mmc->ocr_avail = (u32) mask;
-			if (plat->ocr_mask)
-				dev_warn(&dev->dev,
-				 "Provided ocr_mask/setpower will not be used "
-				 "(using regulator instead)\n");
-		}
+	host->pinctrl = devm_pinctrl_get(&dev->dev);
+	if (IS_ERR(host->pinctrl)) {
+		ret = PTR_ERR(host->pinctrl);
+		goto clk_disable;
 	}
-#endif
-	/* Fall back to platform data if no regulator is found */
-	if (host->vcc == NULL)
+
+	host->pins_default = pinctrl_lookup_state(host->pinctrl,
+			PINCTRL_STATE_DEFAULT);
+
+	/* enable pins to be muxed in and configured */
+	if (!IS_ERR(host->pins_default)) {
+		ret = pinctrl_select_state(host->pinctrl, host->pins_default);
+		if (ret)
+			dev_warn(&dev->dev, "could not set default pins\n");
+	} else
+		dev_warn(&dev->dev, "could not get default pinstate\n");
+
+	/* Get regulators and the supported OCR mask */
+	mmc_regulator_get_supply(mmc);
+	if (!mmc->ocr_avail)
 		mmc->ocr_avail = plat->ocr_mask;
+	else if (plat->ocr_mask)
+		dev_warn(mmc_dev(mmc), "Platform OCR mask is ignored\n");
+
 	mmc->caps = plat->capabilities;
 	mmc->caps2 = plat->capabilities2;
 
+	/* We support these PM capabilities. */
+	mmc->pm_caps = MMC_PM_KEEP_POWER;
+
 	/*
 	 * We can do SGIO
 	 */
@@ -1356,6 +1485,10 @@
 	writel(0, host->base + MMCIMASK1);
 	writel(0xfff, host->base + MMCICLEAR);
 
+	if (plat->gpio_cd == -EPROBE_DEFER) {
+		ret = -EPROBE_DEFER;
+		goto err_gpio_cd;
+	}
 	if (gpio_is_valid(plat->gpio_cd)) {
 		ret = gpio_request(plat->gpio_cd, DRIVER_NAME " (cd)");
 		if (ret == 0)
@@ -1379,6 +1512,10 @@
 		if (ret >= 0)
 			host->gpio_cd_irq = gpio_to_irq(plat->gpio_cd);
 	}
+	if (plat->gpio_wp == -EPROBE_DEFER) {
+		ret = -EPROBE_DEFER;
+		goto err_gpio_wp;
+	}
 	if (gpio_is_valid(plat->gpio_wp)) {
 		ret = gpio_request(plat->gpio_wp, DRIVER_NAME " (wp)");
 		if (ret == 0)
@@ -1397,7 +1534,7 @@
 	if (ret)
 		goto unmap;
 
-	if (dev->irq[1] == NO_IRQ || !dev->irq[1])
+	if (!dev->irq[1])
 		host->singleirq = true;
 	else {
 		ret = request_irq(dev->irq[1], mmci_pio_irq, IRQF_SHARED,
@@ -1438,9 +1575,7 @@
  err_gpio_cd:
 	iounmap(host->base);
  clk_disable:
-	clk_disable(host->clk);
- clk_unprep:
-	clk_unprepare(host->clk);
+	clk_disable_unprepare(host->clk);
  clk_free:
 	clk_put(host->clk);
  host_free:
@@ -1451,7 +1586,7 @@
 	return ret;
 }
 
-static int __devexit mmci_remove(struct amba_device *dev)
+static int mmci_remove(struct amba_device *dev)
 {
 	struct mmc_host *mmc = amba_get_drvdata(dev);
 
@@ -1487,14 +1622,9 @@
 			gpio_free(host->gpio_cd);
 
 		iounmap(host->base);
-		clk_disable(host->clk);
-		clk_unprepare(host->clk);
+		clk_disable_unprepare(host->clk);
 		clk_put(host->clk);
 
-		if (host->vcc)
-			mmc_regulator_set_ocr(mmc, host->vcc, 0);
-		regulator_put(host->vcc);
-
 		mmc_free_host(mmc);
 
 		amba_release_regions(dev);
@@ -1542,8 +1672,37 @@
 }
 #endif
 
+#ifdef CONFIG_PM_RUNTIME
+static int mmci_runtime_suspend(struct device *dev)
+{
+	struct amba_device *adev = to_amba_device(dev);
+	struct mmc_host *mmc = amba_get_drvdata(adev);
+
+	if (mmc) {
+		struct mmci_host *host = mmc_priv(mmc);
+		clk_disable_unprepare(host->clk);
+	}
+
+	return 0;
+}
+
+static int mmci_runtime_resume(struct device *dev)
+{
+	struct amba_device *adev = to_amba_device(dev);
+	struct mmc_host *mmc = amba_get_drvdata(adev);
+
+	if (mmc) {
+		struct mmci_host *host = mmc_priv(mmc);
+		clk_prepare_enable(host->clk);
+	}
+
+	return 0;
+}
+#endif
+
 static const struct dev_pm_ops mmci_dev_pm_ops = {
 	SET_SYSTEM_SLEEP_PM_OPS(mmci_suspend, mmci_resume)
+	SET_RUNTIME_PM_OPS(mmci_runtime_suspend, mmci_runtime_resume, NULL)
 };
 
 static struct amba_id mmci_ids[] = {
@@ -1558,6 +1717,11 @@
 		.data	= &variant_arm_extended_fifo,
 	},
 	{
+		.id	= 0x02041180,
+		.mask	= 0xff0fffff,
+		.data	= &variant_arm_extended_fifo_hwfc,
+	},
+	{
 		.id	= 0x00041181,
 		.mask	= 0x000fffff,
 		.data	= &variant_arm,
@@ -1569,6 +1733,11 @@
 		.data	= &variant_u300,
 	},
 	{
+		.id     = 0x10180180,
+		.mask   = 0xf0ffffff,
+		.data	= &variant_nomadik,
+	},
+	{
 		.id     = 0x00280180,
 		.mask   = 0x00ffffff,
 		.data	= &variant_u300,
@@ -1594,7 +1763,7 @@
 		.pm	= &mmci_dev_pm_ops,
 	},
 	.probe		= mmci_probe,
-	.remove		= __devexit_p(mmci_remove),
+	.remove		= mmci_remove,
 	.id_table	= mmci_ids,
 };
 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/mmci.h linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/mmci.h
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/mmci.h	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/mmci.h	2014-09-12 15:59:37.348052000 +0800
@@ -28,6 +28,8 @@
 #define MCI_ST_UX500_NEG_EDGE	(1 << 13)
 #define MCI_ST_UX500_HWFCEN	(1 << 14)
 #define MCI_ST_UX500_CLK_INV	(1 << 15)
+/* Modified PL180 on Versatile Express platform */
+#define MCI_ARM_HWFCEN		(1 << 12)
 
 #define MMCIARGUMENT		0x008
 #define MMCICOMMAND		0x00c
@@ -193,7 +195,10 @@
 	/* pio stuff */
 	struct sg_mapping_iter	sg_miter;
 	unsigned int		size;
-	struct regulator	*vcc;
+
+	/* pinctrl handles */
+	struct pinctrl		*pinctrl;
+	struct pinctrl_state	*pins_default;
 
 #ifdef CONFIG_DMA_ENGINE
 	/* DMA stuff */
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/mmc_spi.c linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/mmc_spi.c
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/mmc_spi.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/mmc_spi.c	2014-09-12 15:59:37.348052000 +0800
@@ -1485,7 +1485,7 @@
 }
 
 
-static int __devexit mmc_spi_remove(struct spi_device *spi)
+static int mmc_spi_remove(struct spi_device *spi)
 {
 	struct mmc_host		*mmc = dev_get_drvdata(&spi->dev);
 	struct mmc_spi_host	*host;
@@ -1517,7 +1517,7 @@
 	return 0;
 }
 
-static struct of_device_id mmc_spi_of_match_table[] __devinitdata = {
+static struct of_device_id mmc_spi_of_match_table[] = {
 	{ .compatible = "mmc-spi-slot", },
 	{},
 };
@@ -1529,23 +1529,10 @@
 		.of_match_table = mmc_spi_of_match_table,
 	},
 	.probe =	mmc_spi_probe,
-	.remove =	__devexit_p(mmc_spi_remove),
+	.remove =	mmc_spi_remove,
 };
 
-
-static int __init mmc_spi_init(void)
-{
-	return spi_register_driver(&mmc_spi_driver);
-}
-module_init(mmc_spi_init);
-
-
-static void __exit mmc_spi_exit(void)
-{
-	spi_unregister_driver(&mmc_spi_driver);
-}
-module_exit(mmc_spi_exit);
-
+module_spi_driver(mmc_spi_driver);
 
 MODULE_AUTHOR("Mike Lavender, David Brownell, "
 		"Hans-Peter Nilsson, Jan Nikitenko");
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/msm_sdcc.c linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/msm_sdcc.c
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/msm_sdcc.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/msm_sdcc.c	2014-09-12 15:59:37.348052000 +0800
@@ -42,8 +42,7 @@
 #include <asm/div64.h>
 #include <asm/sizes.h>
 
-#include <mach/mmc.h>
-#include <mach/msm_iomap.h>
+#include <linux/platform_data/mmc-msm_sdcc.h>
 #include <mach/dma.h>
 #include <mach/clk.h>
 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/mvsdio.c linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/mvsdio.c
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/mvsdio.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/mvsdio.c	2014-09-12 15:59:37.348052000 +0800
@@ -19,12 +19,17 @@
 #include <linux/dma-mapping.h>
 #include <linux/scatterlist.h>
 #include <linux/irq.h>
+#include <linux/clk.h>
 #include <linux/gpio.h>
+#include <linux/of_gpio.h>
+#include <linux/of_irq.h>
 #include <linux/mmc/host.h>
+#include <linux/mmc/slot-gpio.h>
+#include <linux/pinctrl/consumer.h>
 
 #include <asm/sizes.h>
 #include <asm/unaligned.h>
-#include <plat/mvsdio.h>
+#include <linux/platform_data/mmc-mvsdio.h>
 
 #include "mvsdio.h"
 
@@ -49,10 +54,7 @@
 	struct timer_list timer;
 	struct mmc_host *mmc;
 	struct device *dev;
-	struct resource *res;
-	int irq;
-	int gpio_card_detect;
-	int gpio_write_protect;
+	struct clk *clk;
 };
 
 #define mvsd_write(offs, val)	writel(val, iobase + (offs))
@@ -117,10 +119,8 @@
 		host->pio_size = data->blocks * data->blksz;
 		host->pio_ptr = sg_virt(data->sg);
 		if (!nodma)
-			pr_debug("%s: fallback to PIO for data "
-					  "at 0x%p size %d\n",
-					  mmc_hostname(host->mmc),
-					  host->pio_ptr, host->pio_size);
+			dev_dbg(host->dev, "fallback to PIO for data at 0x%p size %d\n",
+				host->pio_ptr, host->pio_size);
 		return 1;
 	} else {
 		dma_addr_t phys_addr;
@@ -471,8 +471,8 @@
 		if (mrq->data)
 			err_status = mvsd_finish_data(host, mrq->data, err_status);
 		if (err_status) {
-			pr_err("%s: unhandled error status %#04x\n",
-					mmc_hostname(host->mmc), err_status);
+			dev_err(host->dev, "unhandled error status %#04x\n",
+				err_status);
 			cmd->error = -ENOMSG;
 		}
 
@@ -489,9 +489,8 @@
 	if (irq_handled)
 		return IRQ_HANDLED;
 
-	pr_err("%s: unhandled interrupt status=0x%04x en=0x%04x "
-			"pio=%d\n", mmc_hostname(host->mmc), intr_status,
-			host->intr_en, host->pio_size);
+	dev_err(host->dev, "unhandled interrupt status=0x%04x en=0x%04x pio=%d\n",
+		intr_status, host->intr_en, host->pio_size);
 	return IRQ_NONE;
 }
 
@@ -505,13 +504,11 @@
 	spin_lock_irqsave(&host->lock, flags);
 	mrq = host->mrq;
 	if (mrq) {
-		pr_err("%s: Timeout waiting for hardware interrupt.\n",
-				mmc_hostname(host->mmc));
-		pr_err("%s: hw_state=0x%04x, intr_status=0x%04x "
-				"intr_en=0x%04x\n", mmc_hostname(host->mmc),
-				mvsd_read(MVSD_HW_STATE),
-				mvsd_read(MVSD_NOR_INTR_STATUS),
-				mvsd_read(MVSD_NOR_INTR_EN));
+		dev_err(host->dev, "Timeout waiting for hardware interrupt.\n");
+		dev_err(host->dev, "hw_state=0x%04x, intr_status=0x%04x intr_en=0x%04x\n",
+			mvsd_read(MVSD_HW_STATE),
+			mvsd_read(MVSD_NOR_INTR_STATUS),
+			mvsd_read(MVSD_NOR_INTR_EN));
 
 		host->mrq = NULL;
 
@@ -538,13 +535,6 @@
 		mmc_request_done(host->mmc, mrq);
 }
 
-static irqreturn_t mvsd_card_detect_irq(int irq, void *dev)
-{
-	struct mvsd_host *host = dev;
-	mmc_detect_change(host->mmc, msecs_to_jiffies(100));
-	return IRQ_HANDLED;
-}
-
 static void mvsd_enable_sdio_irq(struct mmc_host *mmc, int enable)
 {
 	struct mvsd_host *host = mmc_priv(mmc);
@@ -564,20 +554,6 @@
 	spin_unlock_irqrestore(&host->lock, flags);
 }
 
-static int mvsd_get_ro(struct mmc_host *mmc)
-{
-	struct mvsd_host *host = mmc_priv(mmc);
-
-	if (host->gpio_write_protect)
-		return gpio_get_value(host->gpio_write_protect);
-
-	/*
-	 * Board doesn't support read only detection; let the mmc core
-	 * decide what to do.
-	 */
-	return -ENOSYS;
-}
-
 static void mvsd_power_up(struct mvsd_host *host)
 {
 	void __iomem *iobase = host->base;
@@ -674,7 +650,7 @@
 
 static const struct mmc_host_ops mvsd_ops = {
 	.request		= mvsd_request,
-	.get_ro			= mvsd_get_ro,
+	.get_ro			= mmc_gpio_get_ro,
 	.set_ios		= mvsd_set_ios,
 	.enable_sdio_irq	= mvsd_enable_sdio_irq,
 };
@@ -703,23 +679,20 @@
 
 static int __init mvsd_probe(struct platform_device *pdev)
 {
+	struct device_node *np = pdev->dev.of_node;
 	struct mmc_host *mmc = NULL;
 	struct mvsd_host *host = NULL;
-	const struct mvsdio_platform_data *mvsd_data;
 	const struct mbus_dram_target_info *dram;
 	struct resource *r;
 	int ret, irq;
+	int gpio_card_detect, gpio_write_protect;
+	struct pinctrl *pinctrl;
 
 	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	irq = platform_get_irq(pdev, 0);
-	mvsd_data = pdev->dev.platform_data;
-	if (!r || irq < 0 || !mvsd_data)
+	if (!r || irq < 0)
 		return -ENXIO;
 
-	r = request_mem_region(r->start, SZ_1K, DRIVER_NAME);
-	if (!r)
-		return -EBUSY;
-
 	mmc = mmc_alloc_host(sizeof(struct mvsd_host), &pdev->dev);
 	if (!mmc) {
 		ret = -ENOMEM;
@@ -729,8 +702,43 @@
 	host = mmc_priv(mmc);
 	host->mmc = mmc;
 	host->dev = &pdev->dev;
-	host->res = r;
-	host->base_clock = mvsd_data->clock / 2;
+
+	pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
+	if (IS_ERR(pinctrl))
+		dev_warn(&pdev->dev, "no pins associated\n");
+
+	/*
+	 * Some non-DT platforms do not pass a clock, and the clock
+	 * frequency is passed through platform_data. On DT platforms,
+	 * a clock must always be passed, even if there is no gatable
+	 * clock associated to the SDIO interface (it can simply be a
+	 * fixed rate clock).
+	 */
+	host->clk = devm_clk_get(&pdev->dev, NULL);
+	if (!IS_ERR(host->clk))
+		clk_prepare_enable(host->clk);
+
+	if (np) {
+		if (IS_ERR(host->clk)) {
+			dev_err(&pdev->dev, "DT platforms must have a clock associated\n");
+			ret = -EINVAL;
+			goto out;
+		}
+
+		host->base_clock = clk_get_rate(host->clk) / 2;
+		gpio_card_detect = of_get_named_gpio(np, "cd-gpios", 0);
+		gpio_write_protect = of_get_named_gpio(np, "wp-gpios", 0);
+	} else {
+		const struct mvsdio_platform_data *mvsd_data;
+		mvsd_data = pdev->dev.platform_data;
+		if (!mvsd_data) {
+			ret = -ENXIO;
+			goto out;
+		}
+		host->base_clock = mvsd_data->clock / 2;
+		gpio_card_detect = mvsd_data->gpio_card_detect ? : -EINVAL;
+		gpio_write_protect = mvsd_data->gpio_write_protect ? : -EINVAL;
+	}
 
 	mmc->ops = &mvsd_ops;
 
@@ -750,7 +758,7 @@
 
 	spin_lock_init(&host->lock);
 
-	host->base = ioremap(r->start, SZ_4K);
+	host->base = devm_request_and_ioremap(&pdev->dev, r);
 	if (!host->base) {
 		ret = -ENOMEM;
 		goto out;
@@ -763,41 +771,20 @@
 
 	mvsd_power_down(host);
 
-	ret = request_irq(irq, mvsd_irq, 0, DRIVER_NAME, host);
+	ret = devm_request_irq(&pdev->dev, irq, mvsd_irq, 0, DRIVER_NAME, host);
 	if (ret) {
-		pr_err("%s: cannot assign irq %d\n", DRIVER_NAME, irq);
+		dev_err(&pdev->dev, "cannot assign irq %d\n", irq);
 		goto out;
-	} else
-		host->irq = irq;
-
-	if (mvsd_data->gpio_card_detect) {
-		ret = gpio_request(mvsd_data->gpio_card_detect,
-				   DRIVER_NAME " cd");
-		if (ret == 0) {
-			gpio_direction_input(mvsd_data->gpio_card_detect);
-			irq = gpio_to_irq(mvsd_data->gpio_card_detect);
-			ret = request_irq(irq, mvsd_card_detect_irq,
-					  IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING,
-					  DRIVER_NAME " cd", host);
-			if (ret == 0)
-				host->gpio_card_detect =
-					mvsd_data->gpio_card_detect;
-			else
-				gpio_free(mvsd_data->gpio_card_detect);
-		}
 	}
-	if (!host->gpio_card_detect)
+
+	if (gpio_is_valid(gpio_card_detect)) {
+		ret = mmc_gpio_request_cd(mmc, gpio_card_detect);
+		if (ret)
+			goto out;
+	} else
 		mmc->caps |= MMC_CAP_NEEDS_POLL;
 
-	if (mvsd_data->gpio_write_protect) {
-		ret = gpio_request(mvsd_data->gpio_write_protect,
-				   DRIVER_NAME " wp");
-		if (ret == 0) {
-			gpio_direction_input(mvsd_data->gpio_write_protect);
-			host->gpio_write_protect =
-				mvsd_data->gpio_write_protect;
-		}
-	}
+	mmc_gpio_request_ro(mmc, gpio_write_protect);
 
 	setup_timer(&host->timer, mvsd_timeout_timer, (unsigned long)host);
 	platform_set_drvdata(pdev, mmc);
@@ -805,32 +792,21 @@
 	if (ret)
 		goto out;
 
-	pr_notice("%s: %s driver initialized, ",
-			   mmc_hostname(mmc), DRIVER_NAME);
-	if (host->gpio_card_detect)
-		printk("using GPIO %d for card detection\n",
-		       host->gpio_card_detect);
+	if (!(mmc->caps & MMC_CAP_NEEDS_POLL))
+		dev_notice(&pdev->dev, "using GPIO %d for card detection\n",
+			   gpio_card_detect);
 	else
-		printk("lacking card detect (fall back to polling)\n");
+		dev_notice(&pdev->dev, "lacking card detect (fall back to polling)\n");
 	return 0;
 
 out:
-	if (host) {
-		if (host->irq)
-			free_irq(host->irq, host);
-		if (host->gpio_card_detect) {
-			free_irq(gpio_to_irq(host->gpio_card_detect), host);
-			gpio_free(host->gpio_card_detect);
-		}
-		if (host->gpio_write_protect)
-			gpio_free(host->gpio_write_protect);
-		if (host->base)
-			iounmap(host->base);
-	}
-	if (r)
-		release_resource(r);
-	if (mmc)
+	if (mmc) {
+		mmc_gpio_free_cd(mmc);
+		mmc_gpio_free_ro(mmc);
+		if (!IS_ERR(host->clk))
+			clk_disable_unprepare(host->clk);
 		mmc_free_host(mmc);
+	}
 
 	return ret;
 }
@@ -839,23 +815,18 @@
 {
 	struct mmc_host *mmc = platform_get_drvdata(pdev);
 
-	if (mmc) {
-		struct mvsd_host *host = mmc_priv(mmc);
+	struct mvsd_host *host = mmc_priv(mmc);
+
+	mmc_gpio_free_cd(mmc);
+	mmc_gpio_free_ro(mmc);
+	mmc_remove_host(mmc);
+	del_timer_sync(&host->timer);
+	mvsd_power_down(host);
+
+	if (!IS_ERR(host->clk))
+		clk_disable_unprepare(host->clk);
+	mmc_free_host(mmc);
 
-		if (host->gpio_card_detect) {
-			free_irq(gpio_to_irq(host->gpio_card_detect), host);
-			gpio_free(host->gpio_card_detect);
-		}
-		mmc_remove_host(mmc);
-		free_irq(host->irq, host);
-		if (host->gpio_write_protect)
-			gpio_free(host->gpio_write_protect);
-		del_timer_sync(&host->timer);
-		mvsd_power_down(host);
-		iounmap(host->base);
-		release_resource(host->res);
-		mmc_free_host(mmc);
-	}
 	platform_set_drvdata(pdev, NULL);
 	return 0;
 }
@@ -887,27 +858,23 @@
 #define mvsd_resume	NULL
 #endif
 
+static const struct of_device_id mvsdio_dt_ids[] = {
+	{ .compatible = "marvell,orion-sdio" },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, mvsdio_dt_ids);
+
 static struct platform_driver mvsd_driver = {
 	.remove		= __exit_p(mvsd_remove),
 	.suspend	= mvsd_suspend,
 	.resume		= mvsd_resume,
 	.driver		= {
 		.name	= DRIVER_NAME,
+		.of_match_table = mvsdio_dt_ids,
 	},
 };
 
-static int __init mvsd_init(void)
-{
-	return platform_driver_probe(&mvsd_driver, mvsd_probe);
-}
-
-static void __exit mvsd_exit(void)
-{
-	platform_driver_unregister(&mvsd_driver);
-}
-
-module_init(mvsd_init);
-module_exit(mvsd_exit);
+module_platform_driver_probe(mvsd_driver, mvsd_probe);
 
 /* maximum card clock frequency (default 50MHz) */
 module_param(maxfreq, int, 0);
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/mxcmmc.c linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/mxcmmc.c
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/mxcmmc.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/mxcmmc.c	2014-09-12 15:59:37.348052000 +0800
@@ -34,16 +34,20 @@
 #include <linux/regulator/consumer.h>
 #include <linux/dmaengine.h>
 #include <linux/types.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_dma.h>
+#include <linux/of_gpio.h>
+#include <linux/mmc/slot-gpio.h>
 
 #include <asm/dma.h>
 #include <asm/irq.h>
-#include <asm/sizes.h>
-#include <mach/mmc.h>
+#include <linux/platform_data/mmc-mxcmmc.h>
 
-#include <mach/dma.h>
-#include <mach/hardware.h>
+#include <linux/platform_data/dma-imx.h>
 
 #define DRIVER_NAME "mxc-mmc"
+#define MXCMCI_TIMEOUT_MS 10000
 
 #define MMC_REG_STR_STP_CLK		0x00
 #define MMC_REG_STATUS			0x04
@@ -112,6 +116,12 @@
 #define INT_WRITE_OP_DONE_EN		(1 << 1)
 #define INT_READ_OP_EN			(1 << 0)
 
+enum mxcmci_type {
+	IMX21_MMC,
+	IMX31_MMC,
+	MPC512X_MMC,
+};
+
 struct mxcmci_host {
 	struct mmc_host		*mmc;
 	struct resource		*res;
@@ -136,7 +146,8 @@
 	u16			rev_no;
 	unsigned int		cmdat;
 
-	struct clk		*clk;
+	struct clk		*clk_ipg;
+	struct clk		*clk_per;
 
 	int			clock;
 
@@ -149,7 +160,84 @@
 	int			dmareq;
 	struct dma_slave_config dma_slave_config;
 	struct imx_dma_data	dma_data;
+
+	struct timer_list	watchdog;
+	enum mxcmci_type	devtype;
+};
+
+static const struct platform_device_id mxcmci_devtype[] = {
+	{
+		.name = "imx21-mmc",
+		.driver_data = IMX21_MMC,
+	}, {
+		.name = "imx31-mmc",
+		.driver_data = IMX31_MMC,
+	}, {
+		.name = "mpc512x-sdhc",
+		.driver_data = MPC512X_MMC,
+	}, {
+		/* sentinel */
+	}
+};
+MODULE_DEVICE_TABLE(platform, mxcmci_devtype);
+
+static const struct of_device_id mxcmci_of_match[] = {
+	{
+		.compatible = "fsl,imx21-mmc",
+		.data = &mxcmci_devtype[IMX21_MMC],
+	}, {
+		.compatible = "fsl,imx31-mmc",
+		.data = &mxcmci_devtype[IMX31_MMC],
+	}, {
+		.compatible = "fsl,mpc5121-sdhc",
+		.data = &mxcmci_devtype[MPC512X_MMC],
+	}, {
+		/* sentinel */
+	}
 };
+MODULE_DEVICE_TABLE(of, mxcmci_of_match);
+
+static inline int is_imx31_mmc(struct mxcmci_host *host)
+{
+	return host->devtype == IMX31_MMC;
+}
+
+static inline int is_mpc512x_mmc(struct mxcmci_host *host)
+{
+	return host->devtype == MPC512X_MMC;
+}
+
+static inline u32 mxcmci_readl(struct mxcmci_host *host, int reg)
+{
+	if (IS_ENABLED(CONFIG_PPC_MPC512x))
+		return ioread32be(host->base + reg);
+	else
+		return readl(host->base + reg);
+}
+
+static inline void mxcmci_writel(struct mxcmci_host *host, u32 val, int reg)
+{
+	if (IS_ENABLED(CONFIG_PPC_MPC512x))
+		iowrite32be(val, host->base + reg);
+	else
+		writel(val, host->base + reg);
+}
+
+static inline u16 mxcmci_readw(struct mxcmci_host *host, int reg)
+{
+	if (IS_ENABLED(CONFIG_PPC_MPC512x))
+		return ioread32be(host->base + reg);
+	else
+		return readw(host->base + reg);
+}
+
+static inline void mxcmci_writew(struct mxcmci_host *host, u16 val, int reg)
+{
+	if (IS_ENABLED(CONFIG_PPC_MPC512x))
+		iowrite32be(val, host->base + reg);
+	else
+		writew(val, host->base + reg);
+}
 
 static void mxcmci_set_clk_rate(struct mxcmci_host *host, unsigned int clk_ios);
 
@@ -202,17 +290,40 @@
 	dev_dbg(mmc_dev(host->mmc), "mxcmci_softreset\n");
 
 	/* reset sequence */
-	writew(STR_STP_CLK_RESET, host->base + MMC_REG_STR_STP_CLK);
-	writew(STR_STP_CLK_RESET | STR_STP_CLK_START_CLK,
-			host->base + MMC_REG_STR_STP_CLK);
+	mxcmci_writew(host, STR_STP_CLK_RESET, MMC_REG_STR_STP_CLK);
+	mxcmci_writew(host, STR_STP_CLK_RESET | STR_STP_CLK_START_CLK,
+			MMC_REG_STR_STP_CLK);
 
 	for (i = 0; i < 8; i++)
-		writew(STR_STP_CLK_START_CLK, host->base + MMC_REG_STR_STP_CLK);
+		mxcmci_writew(host, STR_STP_CLK_START_CLK, MMC_REG_STR_STP_CLK);
 
-	writew(0xff, host->base + MMC_REG_RES_TO);
+	mxcmci_writew(host, 0xff, MMC_REG_RES_TO);
 }
 static int mxcmci_setup_dma(struct mmc_host *mmc);
 
+#if IS_ENABLED(CONFIG_PPC_MPC512x)
+static inline void buffer_swap32(u32 *buf, int len)
+{
+	int i;
+
+	for (i = 0; i < ((len + 3) / 4); i++) {
+		st_le32(buf, *buf);
+		buf++;
+	}
+}
+
+static void mxcmci_swap_buffers(struct mmc_data *data)
+{
+	struct scatterlist *sg;
+	int i;
+
+	for_each_sg(data->sg, sg, data->sg_len, i)
+		buffer_swap32(sg_virt(sg), sg->length);
+}
+#else
+static inline void mxcmci_swap_buffers(struct mmc_data *data) {}
+#endif
+
 static int mxcmci_setup_data(struct mxcmci_host *host, struct mmc_data *data)
 {
 	unsigned int nob = data->blocks;
@@ -228,15 +339,15 @@
 	host->data = data;
 	data->bytes_xfered = 0;
 
-	writew(nob, host->base + MMC_REG_NOB);
-	writew(blksz, host->base + MMC_REG_BLK_LEN);
+	mxcmci_writew(host, nob, MMC_REG_NOB);
+	mxcmci_writew(host, blksz, MMC_REG_BLK_LEN);
 	host->datasize = datasize;
 
 	if (!mxcmci_use_dma(host))
 		return 0;
 
 	for_each_sg(data->sg, sg, data->sg_len, i) {
-		if (sg->offset & 3 || sg->length & 3) {
+		if (sg->offset & 3 || sg->length & 3 || sg->length < 512) {
 			host->do_dma = 0;
 			return 0;
 		}
@@ -248,6 +359,8 @@
 	} else {
 		host->dma_dir = DMA_TO_DEVICE;
 		slave_dirn = DMA_MEM_TO_DEV;
+
+		mxcmci_swap_buffers(data);
 	}
 
 	nents = dma_map_sg(host->dma->device->dev, data->sg,
@@ -270,9 +383,32 @@
 	dmaengine_submit(host->desc);
 	dma_async_issue_pending(host->dma);
 
+	mod_timer(&host->watchdog, jiffies + msecs_to_jiffies(MXCMCI_TIMEOUT_MS));
+
 	return 0;
 }
 
+static void mxcmci_cmd_done(struct mxcmci_host *host, unsigned int stat);
+static void mxcmci_data_done(struct mxcmci_host *host, unsigned int stat);
+
+static void mxcmci_dma_callback(void *data)
+{
+	struct mxcmci_host *host = data;
+	u32 stat;
+
+	del_timer(&host->watchdog);
+
+	stat = mxcmci_readl(host, MMC_REG_STATUS);
+	mxcmci_writel(host, stat & ~STATUS_DATA_TRANS_DONE, MMC_REG_STATUS);
+
+	dev_dbg(mmc_dev(host->mmc), "%s: 0x%08x\n", __func__, stat);
+
+	if (stat & STATUS_READ_OP_DONE)
+		mxcmci_writel(host, STATUS_READ_OP_DONE, MMC_REG_STATUS);
+
+	mxcmci_data_done(host, stat);
+}
+
 static int mxcmci_start_cmd(struct mxcmci_host *host, struct mmc_command *cmd,
 		unsigned int cmdat)
 {
@@ -304,18 +440,24 @@
 
 	int_cntr = INT_END_CMD_RES_EN;
 
-	if (mxcmci_use_dma(host))
-		int_cntr |= INT_READ_OP_EN | INT_WRITE_OP_DONE_EN;
+	if (mxcmci_use_dma(host)) {
+		if (host->dma_dir == DMA_FROM_DEVICE) {
+			host->desc->callback = mxcmci_dma_callback;
+			host->desc->callback_param = host;
+		} else {
+			int_cntr |= INT_WRITE_OP_DONE_EN;
+		}
+	}
 
 	spin_lock_irqsave(&host->lock, flags);
 	if (host->use_sdio)
 		int_cntr |= INT_SDIO_IRQ_EN;
-	writel(int_cntr, host->base + MMC_REG_INT_CNTR);
+	mxcmci_writel(host, int_cntr, MMC_REG_INT_CNTR);
 	spin_unlock_irqrestore(&host->lock, flags);
 
-	writew(cmd->opcode, host->base + MMC_REG_CMD);
-	writel(cmd->arg, host->base + MMC_REG_ARG);
-	writew(cmdat, host->base + MMC_REG_CMD_DAT_CONT);
+	mxcmci_writew(host, cmd->opcode, MMC_REG_CMD);
+	mxcmci_writel(host, cmd->arg, MMC_REG_ARG);
+	mxcmci_writew(host, cmdat, MMC_REG_CMD_DAT_CONT);
 
 	return 0;
 }
@@ -329,7 +471,7 @@
 	spin_lock_irqsave(&host->lock, flags);
 	if (host->use_sdio)
 		int_cntr |= INT_SDIO_IRQ_EN;
-	writel(int_cntr, host->base + MMC_REG_INT_CNTR);
+	mxcmci_writel(host, int_cntr, MMC_REG_INT_CNTR);
 	spin_unlock_irqrestore(&host->lock, flags);
 
 	host->req = NULL;
@@ -345,9 +487,9 @@
 	int data_error;
 
 	if (mxcmci_use_dma(host)) {
-		dmaengine_terminate_all(host->dma);
 		dma_unmap_sg(host->dma->device->dev, data->sg, data->sg_len,
 				host->dma_dir);
+		mxcmci_swap_buffers(data);
 	}
 
 	if (stat & STATUS_ERR_MASK) {
@@ -406,14 +548,14 @@
 	if (cmd->flags & MMC_RSP_PRESENT) {
 		if (cmd->flags & MMC_RSP_136) {
 			for (i = 0; i < 4; i++) {
-				a = readw(host->base + MMC_REG_RES_FIFO);
-				b = readw(host->base + MMC_REG_RES_FIFO);
+				a = mxcmci_readw(host, MMC_REG_RES_FIFO);
+				b = mxcmci_readw(host, MMC_REG_RES_FIFO);
 				cmd->resp[i] = a << 16 | b;
 			}
 		} else {
-			a = readw(host->base + MMC_REG_RES_FIFO);
-			b = readw(host->base + MMC_REG_RES_FIFO);
-			c = readw(host->base + MMC_REG_RES_FIFO);
+			a = mxcmci_readw(host, MMC_REG_RES_FIFO);
+			b = mxcmci_readw(host, MMC_REG_RES_FIFO);
+			c = mxcmci_readw(host, MMC_REG_RES_FIFO);
 			cmd->resp[0] = a << 24 | b << 8 | c >> 8;
 		}
 	}
@@ -425,7 +567,7 @@
 	unsigned long timeout = jiffies + HZ;
 
 	do {
-		stat = readl(host->base + MMC_REG_STATUS);
+		stat = mxcmci_readl(host, MMC_REG_STATUS);
 		if (stat & STATUS_ERR_MASK)
 			return stat;
 		if (time_after(jiffies, timeout)) {
@@ -449,7 +591,7 @@
 				STATUS_BUF_READ_RDY | STATUS_READ_OP_DONE);
 		if (stat)
 			return stat;
-		*buf++ = readl(host->base + MMC_REG_BUFFER_ACCESS);
+		*buf++ = cpu_to_le32(mxcmci_readl(host, MMC_REG_BUFFER_ACCESS));
 		bytes -= 4;
 	}
 
@@ -461,7 +603,7 @@
 				STATUS_BUF_READ_RDY | STATUS_READ_OP_DONE);
 		if (stat)
 			return stat;
-		tmp = readl(host->base + MMC_REG_BUFFER_ACCESS);
+		tmp = cpu_to_le32(mxcmci_readl(host, MMC_REG_BUFFER_ACCESS));
 		memcpy(b, &tmp, bytes);
 	}
 
@@ -477,7 +619,7 @@
 		stat = mxcmci_poll_status(host, STATUS_BUF_WRITE_RDY);
 		if (stat)
 			return stat;
-		writel(*buf++, host->base + MMC_REG_BUFFER_ACCESS);
+		mxcmci_writel(host, cpu_to_le32(*buf++), MMC_REG_BUFFER_ACCESS);
 		bytes -= 4;
 	}
 
@@ -490,7 +632,7 @@
 			return stat;
 
 		memcpy(&tmp, b, bytes);
-		writel(tmp, host->base + MMC_REG_BUFFER_ACCESS);
+		mxcmci_writel(host, cpu_to_le32(tmp), MMC_REG_BUFFER_ACCESS);
 	}
 
 	stat = mxcmci_poll_status(host, STATUS_BUF_WRITE_RDY);
@@ -536,8 +678,8 @@
 						  datawork);
 	int datastat = mxcmci_transfer_data(host);
 
-	writel(STATUS_READ_OP_DONE | STATUS_WRITE_OP_DONE,
-		host->base + MMC_REG_STATUS);
+	mxcmci_writel(host, STATUS_READ_OP_DONE | STATUS_WRITE_OP_DONE,
+		MMC_REG_STATUS);
 	mxcmci_finish_data(host, datastat);
 
 	if (host->req->stop) {
@@ -552,24 +694,40 @@
 
 static void mxcmci_data_done(struct mxcmci_host *host, unsigned int stat)
 {
-	struct mmc_data *data = host->data;
+	struct mmc_request *req;
 	int data_error;
+	unsigned long flags;
+
+	spin_lock_irqsave(&host->lock, flags);
 
-	if (!data)
+	if (!host->data) {
+		spin_unlock_irqrestore(&host->lock, flags);
 		return;
+	}
+
+	if (!host->req) {
+		spin_unlock_irqrestore(&host->lock, flags);
+		return;
+	}
+
+	req = host->req;
+	if (!req->stop)
+		host->req = NULL; /* we will handle finish req below */
 
 	data_error = mxcmci_finish_data(host, stat);
 
+	spin_unlock_irqrestore(&host->lock, flags);
+
 	mxcmci_read_response(host, stat);
 	host->cmd = NULL;
 
-	if (host->req->stop) {
-		if (mxcmci_start_cmd(host, host->req->stop, 0)) {
-			mxcmci_finish_request(host, host->req);
+	if (req->stop) {
+		if (mxcmci_start_cmd(host, req->stop, 0)) {
+			mxcmci_finish_request(host, req);
 			return;
 		}
 	} else {
-		mxcmci_finish_request(host, host->req);
+		mxcmci_finish_request(host, req);
 	}
 }
 
@@ -599,9 +757,11 @@
 	bool sdio_irq;
 	u32 stat;
 
-	stat = readl(host->base + MMC_REG_STATUS);
-	writel(stat & ~(STATUS_SDIO_INT_ACTIVE | STATUS_DATA_TRANS_DONE |
-			STATUS_WRITE_OP_DONE), host->base + MMC_REG_STATUS);
+	stat = mxcmci_readl(host, MMC_REG_STATUS);
+	mxcmci_writel(host,
+		stat & ~(STATUS_SDIO_INT_ACTIVE | STATUS_DATA_TRANS_DONE |
+			 STATUS_WRITE_OP_DONE),
+		MMC_REG_STATUS);
 
 	dev_dbg(mmc_dev(host->mmc), "%s: 0x%08x\n", __func__, stat);
 
@@ -611,11 +771,11 @@
 
 	if (mxcmci_use_dma(host) &&
 	    (stat & (STATUS_READ_OP_DONE | STATUS_WRITE_OP_DONE)))
-		writel(STATUS_READ_OP_DONE | STATUS_WRITE_OP_DONE,
-			host->base + MMC_REG_STATUS);
+		mxcmci_writel(host, STATUS_READ_OP_DONE | STATUS_WRITE_OP_DONE,
+			MMC_REG_STATUS);
 
 	if (sdio_irq) {
-		writel(STATUS_SDIO_INT_ACTIVE, host->base + MMC_REG_STATUS);
+		mxcmci_writel(host, STATUS_SDIO_INT_ACTIVE, MMC_REG_STATUS);
 		mmc_signal_sdio_irq(host->mmc);
 	}
 
@@ -623,8 +783,10 @@
 		mxcmci_cmd_done(host, stat);
 
 	if (mxcmci_use_dma(host) &&
-		  (stat & (STATUS_DATA_TRANS_DONE | STATUS_WRITE_OP_DONE)))
+		  (stat & (STATUS_DATA_TRANS_DONE | STATUS_WRITE_OP_DONE))) {
+		del_timer(&host->watchdog);
 		mxcmci_data_done(host, stat);
+	}
 
 	if (host->default_irq_mask &&
 		  (stat & (STATUS_CARD_INSERTION | STATUS_CARD_REMOVAL)))
@@ -672,7 +834,7 @@
 {
 	unsigned int divider;
 	int prescaler = 0;
-	unsigned int clk_in = clk_get_rate(host->clk);
+	unsigned int clk_in = clk_get_rate(host->clk_per);
 
 	while (prescaler <= 0x800) {
 		for (divider = 1; divider <= 0xF; divider++) {
@@ -695,7 +857,7 @@
 			prescaler <<= 1;
 	}
 
-	writew((prescaler << 4) | divider, host->base + MMC_REG_CLK_RATE);
+	mxcmci_writew(host, (prescaler << 4) | divider, MMC_REG_CLK_RATE);
 
 	dev_dbg(mmc_dev(host->mmc), "scaler: %d divider: %d in: %d out: %d\n",
 			prescaler, divider, clk_in, clk_ios);
@@ -758,9 +920,9 @@
 
 	if (ios->clock) {
 		mxcmci_set_clk_rate(host, ios->clock);
-		writew(STR_STP_CLK_START_CLK, host->base + MMC_REG_STR_STP_CLK);
+		mxcmci_writew(host, STR_STP_CLK_START_CLK, MMC_REG_STR_STP_CLK);
 	} else {
-		writew(STR_STP_CLK_STOP_CLK, host->base + MMC_REG_STR_STP_CLK);
+		mxcmci_writew(host, STR_STP_CLK_STOP_CLK, MMC_REG_STR_STP_CLK);
 	}
 
 	host->clock = ios->clock;
@@ -783,10 +945,11 @@
 	if (host->pdata && host->pdata->get_ro)
 		return !!host->pdata->get_ro(mmc_dev(mmc));
 	/*
-	 * Board doesn't support read only detection; let the mmc core
-	 * decide what to do.
+	 * If board doesn't support read only detection (no mmc_gpio
+	 * context or gpio is invalid), then let the mmc core decide
+	 * what to do.
 	 */
-	return -ENOSYS;
+	return mmc_gpio_get_ro(mmc);
 }
 
 static void mxcmci_enable_sdio_irq(struct mmc_host *mmc, int enable)
@@ -797,19 +960,21 @@
 
 	spin_lock_irqsave(&host->lock, flags);
 	host->use_sdio = enable;
-	int_cntr = readl(host->base + MMC_REG_INT_CNTR);
+	int_cntr = mxcmci_readl(host, MMC_REG_INT_CNTR);
 
 	if (enable)
 		int_cntr |= INT_SDIO_IRQ_EN;
 	else
 		int_cntr &= ~INT_SDIO_IRQ_EN;
 
-	writel(int_cntr, host->base + MMC_REG_INT_CNTR);
+	mxcmci_writel(host, int_cntr, MMC_REG_INT_CNTR);
 	spin_unlock_irqrestore(&host->lock, flags);
 }
 
 static void mxcmci_init_card(struct mmc_host *host, struct mmc_card *card)
 {
+	struct mxcmci_host *mxcmci = mmc_priv(host);
+
 	/*
 	 * MX3 SoCs have a silicon bug which corrupts CRC calculation of
 	 * multi-block transfers when connected SDIO peripheral doesn't
@@ -817,7 +982,7 @@
 	 * One way to prevent this is to only allow 1-bit transfers.
 	 */
 
-	if (cpu_is_mx3() && card->type == MMC_TYPE_SDIO)
+	if (is_imx31_mmc(mxcmci) && card->type == MMC_TYPE_SDIO)
 		host->caps &= ~MMC_CAP_4_BIT_DATA;
 	else
 		host->caps |= MMC_CAP_4_BIT_DATA;
@@ -835,6 +1000,35 @@
 	return true;
 }
 
+static void mxcmci_watchdog(unsigned long data)
+{
+	struct mmc_host *mmc = (struct mmc_host *)data;
+	struct mxcmci_host *host = mmc_priv(mmc);
+	struct mmc_request *req = host->req;
+	unsigned int stat = mxcmci_readl(host, MMC_REG_STATUS);
+
+	if (host->dma_dir == DMA_FROM_DEVICE) {
+		dmaengine_terminate_all(host->dma);
+		dev_err(mmc_dev(host->mmc),
+			"%s: read time out (status = 0x%08x)\n",
+			__func__, stat);
+	} else {
+		dev_err(mmc_dev(host->mmc),
+			"%s: write time out (status = 0x%08x)\n",
+			__func__, stat);
+		mxcmci_softreset(host);
+	}
+
+	/* Mark transfer as erroneus and inform the upper layers */
+
+	if (host->data)
+		host->data->error = -ETIMEDOUT;
+	host->req = NULL;
+	host->cmd = NULL;
+	host->data = NULL;
+	mmc_request_done(host->mmc, req);
+}
+
 static const struct mmc_host_ops mxcmci_ops = {
 	.request		= mxcmci_request,
 	.set_ios		= mxcmci_set_ios,
@@ -849,9 +1043,14 @@
 	struct mxcmci_host *host = NULL;
 	struct resource *iores, *r;
 	int ret = 0, irq;
+	bool dat3_card_detect = false;
 	dma_cap_mask_t mask;
+	const struct of_device_id *of_id;
+	struct imxmmc_platform_data *pdata = pdev->dev.platform_data;
+
+	pr_info("i.MX/MPC512x SDHC driver\n");
 
-	pr_info("i.MX SDHC driver\n");
+	of_id = of_match_device(mxcmci_of_match, &pdev->dev);
 
 	iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	irq = platform_get_irq(pdev, 0);
@@ -868,11 +1067,16 @@
 		goto out_release_mem;
 	}
 
+	mmc_of_parse(mmc);
 	mmc->ops = &mxcmci_ops;
-	mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ;
+
+	/* For devicetree parsing, the bus width is read from devicetree */
+	if (pdata)
+		mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ;
+	else
+		mmc->caps |= MMC_CAP_SDIO_IRQ;
 
 	/* MMC core transfer sizes tunable parameters */
-	mmc->max_segs = 64;
 	mmc->max_blk_size = 2048;
 	mmc->max_blk_count = 65535;
 	mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count;
@@ -885,13 +1089,30 @@
 		goto out_free;
 	}
 
+	if (of_id) {
+		const struct platform_device_id *id_entry = of_id->data;
+		host->devtype = id_entry->driver_data;
+	} else {
+		host->devtype = pdev->id_entry->driver_data;
+	}
+
+	/* adjust max_segs after devtype detection */
+	if (!is_mpc512x_mmc(host))
+		mmc->max_segs = 64;
+
 	host->mmc = mmc;
-	host->pdata = pdev->dev.platform_data;
+	host->pdata = pdata;
 	spin_lock_init(&host->lock);
 
+	if (pdata)
+		dat3_card_detect = pdata->dat3_card_detect;
+	else if (!(mmc->caps & MMC_CAP_NONREMOVABLE)
+			&& !of_property_read_bool(pdev->dev.of_node, "cd-gpios"))
+		dat3_card_detect = true;
+
 	mxcmci_init_ocr(host);
 
-	if (host->pdata && host->pdata->dat3_card_detect)
+	if (dat3_card_detect)
 		host->default_irq_mask =
 			INT_CARD_INSERTION_EN | INT_CARD_REMOVAL_EN;
 	else
@@ -900,16 +1121,24 @@
 	host->res = r;
 	host->irq = irq;
 
-	host->clk = clk_get(&pdev->dev, NULL);
-	if (IS_ERR(host->clk)) {
-		ret = PTR_ERR(host->clk);
+	host->clk_ipg = devm_clk_get(&pdev->dev, "ipg");
+	if (IS_ERR(host->clk_ipg)) {
+		ret = PTR_ERR(host->clk_ipg);
+		goto out_iounmap;
+	}
+
+	host->clk_per = devm_clk_get(&pdev->dev, "per");
+	if (IS_ERR(host->clk_per)) {
+		ret = PTR_ERR(host->clk_per);
 		goto out_iounmap;
 	}
-	clk_enable(host->clk);
+
+	clk_prepare_enable(host->clk_per);
+	clk_prepare_enable(host->clk_ipg);
 
 	mxcmci_softreset(host);
 
-	host->rev_no = readw(host->base + MMC_REG_REV_NO);
+	host->rev_no = mxcmci_readw(host, MMC_REG_REV_NO);
 	if (host->rev_no != 0x400) {
 		ret = -ENODEV;
 		dev_err(mmc_dev(host->mmc), "wrong rev.no. 0x%08x. aborting.\n",
@@ -917,29 +1146,32 @@
 		goto out_clk_put;
 	}
 
-	mmc->f_min = clk_get_rate(host->clk) >> 16;
-	mmc->f_max = clk_get_rate(host->clk) >> 1;
+	mmc->f_min = clk_get_rate(host->clk_per) >> 16;
+	mmc->f_max = clk_get_rate(host->clk_per) >> 1;
 
 	/* recommended in data sheet */
-	writew(0x2db4, host->base + MMC_REG_READ_TO);
+	mxcmci_writew(host, 0x2db4, MMC_REG_READ_TO);
 
-	writel(host->default_irq_mask, host->base + MMC_REG_INT_CNTR);
+	mxcmci_writel(host, host->default_irq_mask, MMC_REG_INT_CNTR);
 
-	r = platform_get_resource(pdev, IORESOURCE_DMA, 0);
-	if (r) {
-		host->dmareq = r->start;
-		host->dma_data.peripheral_type = IMX_DMATYPE_SDHC;
-		host->dma_data.priority = DMA_PRIO_LOW;
-		host->dma_data.dma_request = host->dmareq;
-		dma_cap_zero(mask);
-		dma_cap_set(DMA_SLAVE, mask);
-		host->dma = dma_request_channel(mask, filter, host);
-		if (host->dma)
-			mmc->max_seg_size = dma_get_max_seg_size(
-					host->dma->device->dev);
+	if (!host->pdata) {
+		host->dma = dma_request_slave_channel(&pdev->dev, "rx-tx");
+	} else {
+		r = platform_get_resource(pdev, IORESOURCE_DMA, 0);
+		if (r) {
+			host->dmareq = r->start;
+			host->dma_data.peripheral_type = IMX_DMATYPE_SDHC;
+			host->dma_data.priority = DMA_PRIO_LOW;
+			host->dma_data.dma_request = host->dmareq;
+			dma_cap_zero(mask);
+			dma_cap_set(DMA_SLAVE, mask);
+			host->dma = dma_request_channel(mask, filter, host);
+		}
 	}
-
-	if (!host->dma)
+	if (host->dma)
+		mmc->max_seg_size = dma_get_max_seg_size(
+				host->dma->device->dev);
+	else
 		dev_info(mmc_dev(host->mmc), "dma not available. Using PIO\n");
 
 	INIT_WORK(&host->datawork, mxcmci_datawork);
@@ -957,6 +1189,10 @@
 			goto out_free_irq;
 	}
 
+	init_timer(&host->watchdog);
+	host->watchdog.function = &mxcmci_watchdog;
+	host->watchdog.data = (unsigned long)mmc;
+
 	mmc_add_host(mmc);
 
 	return 0;
@@ -967,8 +1203,8 @@
 	if (host->dma)
 		dma_release_channel(host->dma);
 out_clk_put:
-	clk_disable(host->clk);
-	clk_put(host->clk);
+	clk_disable_unprepare(host->clk_per);
+	clk_disable_unprepare(host->clk_ipg);
 out_iounmap:
 	iounmap(host->base);
 out_free:
@@ -999,8 +1235,8 @@
 	if (host->dma)
 		dma_release_channel(host->dma);
 
-	clk_disable(host->clk);
-	clk_put(host->clk);
+	clk_disable_unprepare(host->clk_per);
+	clk_disable_unprepare(host->clk_ipg);
 
 	release_mem_region(host->res->start, resource_size(host->res));
 
@@ -1018,7 +1254,8 @@
 
 	if (mmc)
 		ret = mmc_suspend_host(mmc);
-	clk_disable(host->clk);
+	clk_disable_unprepare(host->clk_per);
+	clk_disable_unprepare(host->clk_ipg);
 
 	return ret;
 }
@@ -1029,7 +1266,8 @@
 	struct mxcmci_host *host = mmc_priv(mmc);
 	int ret = 0;
 
-	clk_enable(host->clk);
+	clk_prepare_enable(host->clk_per);
+	clk_prepare_enable(host->clk_ipg);
 	if (mmc)
 		ret = mmc_resume_host(mmc);
 
@@ -1045,12 +1283,14 @@
 static struct platform_driver mxcmci_driver = {
 	.probe		= mxcmci_probe,
 	.remove		= mxcmci_remove,
+	.id_table	= mxcmci_devtype,
 	.driver		= {
 		.name		= DRIVER_NAME,
 		.owner		= THIS_MODULE,
 #ifdef CONFIG_PM
 		.pm	= &mxcmci_pm_ops,
 #endif
+		.of_match_table	= mxcmci_of_match,
 	}
 };
 
@@ -1059,4 +1299,4 @@
 MODULE_DESCRIPTION("i.MX Multimedia Card Interface Driver");
 MODULE_AUTHOR("Sascha Hauer, Pengutronix");
 MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:imx-mmc");
+MODULE_ALIAS("platform:mxc-mmc");
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/mxs-mmc.c linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/mxs-mmc.c
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/mxs-mmc.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/mxs-mmc.c	2014-09-12 15:59:37.348052000 +0800
@@ -23,6 +23,9 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
 #include <linux/platform_device.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
@@ -38,95 +41,12 @@
 #include <linux/gpio.h>
 #include <linux/regulator/consumer.h>
 #include <linux/module.h>
-#include <linux/fsl/mxs-dma.h>
-
-#include <mach/mxs.h>
-#include <mach/common.h>
-#include <mach/mmc.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/stmp_device.h>
+#include <linux/spi/mxs-spi.h>
 
 #define DRIVER_NAME	"mxs-mmc"
 
-/* card detect polling timeout */
-#define MXS_MMC_DETECT_TIMEOUT			(HZ/2)
-
-#define SSP_VERSION_LATEST	4
-#define ssp_is_old()		(host->version < SSP_VERSION_LATEST)
-
-/* SSP registers */
-#define HW_SSP_CTRL0				0x000
-#define  BM_SSP_CTRL0_RUN			(1 << 29)
-#define  BM_SSP_CTRL0_SDIO_IRQ_CHECK		(1 << 28)
-#define  BM_SSP_CTRL0_IGNORE_CRC		(1 << 26)
-#define  BM_SSP_CTRL0_READ			(1 << 25)
-#define  BM_SSP_CTRL0_DATA_XFER			(1 << 24)
-#define  BP_SSP_CTRL0_BUS_WIDTH			(22)
-#define  BM_SSP_CTRL0_BUS_WIDTH			(0x3 << 22)
-#define  BM_SSP_CTRL0_WAIT_FOR_IRQ		(1 << 21)
-#define  BM_SSP_CTRL0_LONG_RESP			(1 << 19)
-#define  BM_SSP_CTRL0_GET_RESP			(1 << 17)
-#define  BM_SSP_CTRL0_ENABLE			(1 << 16)
-#define  BP_SSP_CTRL0_XFER_COUNT		(0)
-#define  BM_SSP_CTRL0_XFER_COUNT		(0xffff)
-#define HW_SSP_CMD0				0x010
-#define  BM_SSP_CMD0_DBL_DATA_RATE_EN		(1 << 25)
-#define  BM_SSP_CMD0_SLOW_CLKING_EN		(1 << 22)
-#define  BM_SSP_CMD0_CONT_CLKING_EN		(1 << 21)
-#define  BM_SSP_CMD0_APPEND_8CYC		(1 << 20)
-#define  BP_SSP_CMD0_BLOCK_SIZE			(16)
-#define  BM_SSP_CMD0_BLOCK_SIZE			(0xf << 16)
-#define  BP_SSP_CMD0_BLOCK_COUNT		(8)
-#define  BM_SSP_CMD0_BLOCK_COUNT		(0xff << 8)
-#define  BP_SSP_CMD0_CMD			(0)
-#define  BM_SSP_CMD0_CMD			(0xff)
-#define HW_SSP_CMD1				0x020
-#define HW_SSP_XFER_SIZE			0x030
-#define HW_SSP_BLOCK_SIZE			0x040
-#define  BP_SSP_BLOCK_SIZE_BLOCK_COUNT		(4)
-#define  BM_SSP_BLOCK_SIZE_BLOCK_COUNT		(0xffffff << 4)
-#define  BP_SSP_BLOCK_SIZE_BLOCK_SIZE		(0)
-#define  BM_SSP_BLOCK_SIZE_BLOCK_SIZE		(0xf)
-#define HW_SSP_TIMING				(ssp_is_old() ? 0x050 : 0x070)
-#define  BP_SSP_TIMING_TIMEOUT			(16)
-#define  BM_SSP_TIMING_TIMEOUT			(0xffff << 16)
-#define  BP_SSP_TIMING_CLOCK_DIVIDE		(8)
-#define  BM_SSP_TIMING_CLOCK_DIVIDE		(0xff << 8)
-#define  BP_SSP_TIMING_CLOCK_RATE		(0)
-#define  BM_SSP_TIMING_CLOCK_RATE		(0xff)
-#define HW_SSP_CTRL1				(ssp_is_old() ? 0x060 : 0x080)
-#define  BM_SSP_CTRL1_SDIO_IRQ			(1 << 31)
-#define  BM_SSP_CTRL1_SDIO_IRQ_EN		(1 << 30)
-#define  BM_SSP_CTRL1_RESP_ERR_IRQ		(1 << 29)
-#define  BM_SSP_CTRL1_RESP_ERR_IRQ_EN		(1 << 28)
-#define  BM_SSP_CTRL1_RESP_TIMEOUT_IRQ		(1 << 27)
-#define  BM_SSP_CTRL1_RESP_TIMEOUT_IRQ_EN	(1 << 26)
-#define  BM_SSP_CTRL1_DATA_TIMEOUT_IRQ		(1 << 25)
-#define  BM_SSP_CTRL1_DATA_TIMEOUT_IRQ_EN	(1 << 24)
-#define  BM_SSP_CTRL1_DATA_CRC_IRQ		(1 << 23)
-#define  BM_SSP_CTRL1_DATA_CRC_IRQ_EN		(1 << 22)
-#define  BM_SSP_CTRL1_FIFO_UNDERRUN_IRQ		(1 << 21)
-#define  BM_SSP_CTRL1_FIFO_UNDERRUN_IRQ_EN	(1 << 20)
-#define  BM_SSP_CTRL1_RECV_TIMEOUT_IRQ		(1 << 17)
-#define  BM_SSP_CTRL1_RECV_TIMEOUT_IRQ_EN	(1 << 16)
-#define  BM_SSP_CTRL1_FIFO_OVERRUN_IRQ		(1 << 15)
-#define  BM_SSP_CTRL1_FIFO_OVERRUN_IRQ_EN	(1 << 14)
-#define  BM_SSP_CTRL1_DMA_ENABLE		(1 << 13)
-#define  BM_SSP_CTRL1_POLARITY			(1 << 9)
-#define  BP_SSP_CTRL1_WORD_LENGTH		(4)
-#define  BM_SSP_CTRL1_WORD_LENGTH		(0xf << 4)
-#define  BP_SSP_CTRL1_SSP_MODE			(0)
-#define  BM_SSP_CTRL1_SSP_MODE			(0xf)
-#define HW_SSP_SDRESP0				(ssp_is_old() ? 0x080 : 0x0a0)
-#define HW_SSP_SDRESP1				(ssp_is_old() ? 0x090 : 0x0b0)
-#define HW_SSP_SDRESP2				(ssp_is_old() ? 0x0a0 : 0x0c0)
-#define HW_SSP_SDRESP3				(ssp_is_old() ? 0x0b0 : 0x0d0)
-#define HW_SSP_STATUS				(ssp_is_old() ? 0x0c0 : 0x100)
-#define  BM_SSP_STATUS_CARD_DETECT		(1 << 28)
-#define  BM_SSP_STATUS_SDIO_IRQ			(1 << 17)
-#define HW_SSP_VERSION				(cpu_is_mx23() ? 0x110 : 0x130)
-#define  BP_SSP_VERSION_MAJOR			(24)
-
-#define BF_SSP(value, field)	(((value) << BP_SSP_##field) & BM_SSP_##field)
-
 #define MXS_MMC_IRQ_BITS	(BM_SSP_CTRL1_SDIO_IRQ		| \
 				 BM_SSP_CTRL1_RESP_ERR_IRQ	| \
 				 BM_SSP_CTRL1_RESP_TIMEOUT_IRQ	| \
@@ -136,61 +56,59 @@
 				 BM_SSP_CTRL1_RECV_TIMEOUT_IRQ  | \
 				 BM_SSP_CTRL1_FIFO_OVERRUN_IRQ)
 
-#define SSP_PIO_NUM	3
+/* card detect polling timeout */
+#define MXS_MMC_DETECT_TIMEOUT			(HZ/2)
 
 struct mxs_mmc_host {
+	struct mxs_ssp			ssp;
+
 	struct mmc_host			*mmc;
 	struct mmc_request		*mrq;
 	struct mmc_command		*cmd;
 	struct mmc_data			*data;
 
-	void __iomem			*base;
-	int				irq;
-	struct resource			*res;
-	struct resource			*dma_res;
-	struct clk			*clk;
-	unsigned int			clk_rate;
-
-	struct dma_chan         	*dmach;
-	struct mxs_dma_data		dma_data;
-	unsigned int			dma_dir;
-	enum dma_transfer_direction	slave_dirn;
-	u32				ssp_pio_words[SSP_PIO_NUM];
-
-	unsigned int			version;
 	unsigned char			bus_width;
 	spinlock_t			lock;
 	int				sdio_irq_en;
+	int				wp_gpio;
+	bool				wp_inverted;
+	bool				cd_inverted;
+	bool				broken_cd;
+	bool				non_removable;
 };
 
 static int mxs_mmc_get_ro(struct mmc_host *mmc)
 {
 	struct mxs_mmc_host *host = mmc_priv(mmc);
-	struct mxs_mmc_platform_data *pdata =
-		mmc_dev(host->mmc)->platform_data;
-
-	if (!pdata)
-		return -EFAULT;
+	int ret;
 
-	if (!gpio_is_valid(pdata->wp_gpio))
+	if (!gpio_is_valid(host->wp_gpio))
 		return -EINVAL;
 
-	return gpio_get_value(pdata->wp_gpio);
+	ret = gpio_get_value(host->wp_gpio);
+
+	if (host->wp_inverted)
+		ret = !ret;
+
+	return ret;
 }
 
 static int mxs_mmc_get_cd(struct mmc_host *mmc)
 {
 	struct mxs_mmc_host *host = mmc_priv(mmc);
+	struct mxs_ssp *ssp = &host->ssp;
 
-	return !(readl(host->base + HW_SSP_STATUS) &
-		 BM_SSP_STATUS_CARD_DETECT);
+	return host->non_removable || host->broken_cd ||
+		!(readl(ssp->base + HW_SSP_STATUS(ssp)) &
+		  BM_SSP_STATUS_CARD_DETECT) ^ host->cd_inverted;
 }
 
 static void mxs_mmc_reset(struct mxs_mmc_host *host)
 {
+	struct mxs_ssp *ssp = &host->ssp;
 	u32 ctrl0, ctrl1;
 
-	mxs_reset_block(host->base);
+	stmp_reset_block(ssp->base);
 
 	ctrl0 = BM_SSP_CTRL0_IGNORE_CRC;
 	ctrl1 = BF_SSP(0x3, CTRL1_SSP_MODE) |
@@ -206,15 +124,15 @@
 	writel(BF_SSP(0xffff, TIMING_TIMEOUT) |
 	       BF_SSP(2, TIMING_CLOCK_DIVIDE) |
 	       BF_SSP(0, TIMING_CLOCK_RATE),
-	       host->base + HW_SSP_TIMING);
+	       ssp->base + HW_SSP_TIMING(ssp));
 
 	if (host->sdio_irq_en) {
 		ctrl0 |= BM_SSP_CTRL0_SDIO_IRQ_CHECK;
 		ctrl1 |= BM_SSP_CTRL1_SDIO_IRQ_EN;
 	}
 
-	writel(ctrl0, host->base + HW_SSP_CTRL0);
-	writel(ctrl1, host->base + HW_SSP_CTRL1);
+	writel(ctrl0, ssp->base + HW_SSP_CTRL0);
+	writel(ctrl1, ssp->base + HW_SSP_CTRL1(ssp));
 }
 
 static void mxs_mmc_start_cmd(struct mxs_mmc_host *host,
@@ -225,21 +143,22 @@
 	struct mmc_command *cmd = host->cmd;
 	struct mmc_data *data = host->data;
 	struct mmc_request *mrq = host->mrq;
+	struct mxs_ssp *ssp = &host->ssp;
 
 	if (mmc_resp_type(cmd) & MMC_RSP_PRESENT) {
 		if (mmc_resp_type(cmd) & MMC_RSP_136) {
-			cmd->resp[3] = readl(host->base + HW_SSP_SDRESP0);
-			cmd->resp[2] = readl(host->base + HW_SSP_SDRESP1);
-			cmd->resp[1] = readl(host->base + HW_SSP_SDRESP2);
-			cmd->resp[0] = readl(host->base + HW_SSP_SDRESP3);
+			cmd->resp[3] = readl(ssp->base + HW_SSP_SDRESP0(ssp));
+			cmd->resp[2] = readl(ssp->base + HW_SSP_SDRESP1(ssp));
+			cmd->resp[1] = readl(ssp->base + HW_SSP_SDRESP2(ssp));
+			cmd->resp[0] = readl(ssp->base + HW_SSP_SDRESP3(ssp));
 		} else {
-			cmd->resp[0] = readl(host->base + HW_SSP_SDRESP0);
+			cmd->resp[0] = readl(ssp->base + HW_SSP_SDRESP0(ssp));
 		}
 	}
 
 	if (data) {
 		dma_unmap_sg(mmc_dev(host->mmc), data->sg,
-			     data->sg_len, host->dma_dir);
+			     data->sg_len, ssp->dma_dir);
 		/*
 		 * If there was an error on any block, we mark all
 		 * data blocks as being in error.
@@ -272,19 +191,20 @@
 	struct mxs_mmc_host *host = dev_id;
 	struct mmc_command *cmd = host->cmd;
 	struct mmc_data *data = host->data;
+	struct mxs_ssp *ssp = &host->ssp;
 	u32 stat;
 
 	spin_lock(&host->lock);
 
-	stat = readl(host->base + HW_SSP_CTRL1);
+	stat = readl(ssp->base + HW_SSP_CTRL1(ssp));
 	writel(stat & MXS_MMC_IRQ_BITS,
-	       host->base + HW_SSP_CTRL1 + MXS_CLR_ADDR);
+	       ssp->base + HW_SSP_CTRL1(ssp) + STMP_OFFSET_REG_CLR);
+
+	spin_unlock(&host->lock);
 
 	if ((stat & BM_SSP_CTRL1_SDIO_IRQ) && (stat & BM_SSP_CTRL1_SDIO_IRQ_EN))
 		mmc_signal_sdio_irq(host->mmc);
 
-	spin_unlock(&host->lock);
-
 	if (stat & BM_SSP_CTRL1_RESP_TIMEOUT_IRQ)
 		cmd->error = -ETIMEDOUT;
 	else if (stat & BM_SSP_CTRL1_RESP_ERR_IRQ)
@@ -307,6 +227,7 @@
 static struct dma_async_tx_descriptor *mxs_mmc_prep_dma(
 	struct mxs_mmc_host *host, unsigned long flags)
 {
+	struct mxs_ssp *ssp = &host->ssp;
 	struct dma_async_tx_descriptor *desc;
 	struct mmc_data *data = host->data;
 	struct scatterlist * sgl;
@@ -315,24 +236,24 @@
 	if (data) {
 		/* data */
 		dma_map_sg(mmc_dev(host->mmc), data->sg,
-			   data->sg_len, host->dma_dir);
+			   data->sg_len, ssp->dma_dir);
 		sgl = data->sg;
 		sg_len = data->sg_len;
 	} else {
 		/* pio */
-		sgl = (struct scatterlist *) host->ssp_pio_words;
+		sgl = (struct scatterlist *) ssp->ssp_pio_words;
 		sg_len = SSP_PIO_NUM;
 	}
 
-	desc = dmaengine_prep_slave_sg(host->dmach,
-				sgl, sg_len, host->slave_dirn, flags);
+	desc = dmaengine_prep_slave_sg(ssp->dmach,
+				sgl, sg_len, ssp->slave_dirn, flags);
 	if (desc) {
 		desc->callback = mxs_mmc_dma_irq_callback;
 		desc->callback_param = host;
 	} else {
 		if (data)
 			dma_unmap_sg(mmc_dev(host->mmc), data->sg,
-				     data->sg_len, host->dma_dir);
+				     data->sg_len, ssp->dma_dir);
 	}
 
 	return desc;
@@ -340,6 +261,7 @@
 
 static void mxs_mmc_bc(struct mxs_mmc_host *host)
 {
+	struct mxs_ssp *ssp = &host->ssp;
 	struct mmc_command *cmd = host->cmd;
 	struct dma_async_tx_descriptor *desc;
 	u32 ctrl0, cmd0, cmd1;
@@ -353,17 +275,17 @@
 		cmd0 |= BM_SSP_CMD0_CONT_CLKING_EN | BM_SSP_CMD0_SLOW_CLKING_EN;
 	}
 
-	host->ssp_pio_words[0] = ctrl0;
-	host->ssp_pio_words[1] = cmd0;
-	host->ssp_pio_words[2] = cmd1;
-	host->dma_dir = DMA_NONE;
-	host->slave_dirn = DMA_TRANS_NONE;
+	ssp->ssp_pio_words[0] = ctrl0;
+	ssp->ssp_pio_words[1] = cmd0;
+	ssp->ssp_pio_words[2] = cmd1;
+	ssp->dma_dir = DMA_NONE;
+	ssp->slave_dirn = DMA_TRANS_NONE;
 	desc = mxs_mmc_prep_dma(host, DMA_CTRL_ACK);
 	if (!desc)
 		goto out;
 
 	dmaengine_submit(desc);
-	dma_async_issue_pending(host->dmach);
+	dma_async_issue_pending(ssp->dmach);
 	return;
 
 out:
@@ -373,6 +295,7 @@
 
 static void mxs_mmc_ac(struct mxs_mmc_host *host)
 {
+	struct mxs_ssp *ssp = &host->ssp;
 	struct mmc_command *cmd = host->cmd;
 	struct dma_async_tx_descriptor *desc;
 	u32 ignore_crc, get_resp, long_resp;
@@ -394,17 +317,17 @@
 		cmd0 |= BM_SSP_CMD0_CONT_CLKING_EN | BM_SSP_CMD0_SLOW_CLKING_EN;
 	}
 
-	host->ssp_pio_words[0] = ctrl0;
-	host->ssp_pio_words[1] = cmd0;
-	host->ssp_pio_words[2] = cmd1;
-	host->dma_dir = DMA_NONE;
-	host->slave_dirn = DMA_TRANS_NONE;
+	ssp->ssp_pio_words[0] = ctrl0;
+	ssp->ssp_pio_words[1] = cmd0;
+	ssp->ssp_pio_words[2] = cmd1;
+	ssp->dma_dir = DMA_NONE;
+	ssp->slave_dirn = DMA_TRANS_NONE;
 	desc = mxs_mmc_prep_dma(host, DMA_CTRL_ACK);
 	if (!desc)
 		goto out;
 
 	dmaengine_submit(desc);
-	dma_async_issue_pending(host->dmach);
+	dma_async_issue_pending(ssp->dmach);
 	return;
 
 out:
@@ -435,13 +358,15 @@
 	struct dma_async_tx_descriptor *desc;
 	struct scatterlist *sgl = data->sg, *sg;
 	unsigned int sg_len = data->sg_len;
-	int i;
+	unsigned int i;
 
 	unsigned short dma_data_dir, timeout;
 	enum dma_transfer_direction slave_dirn;
 	unsigned int data_size = 0, log2_blksz;
 	unsigned int blocks = data->blocks;
 
+	struct mxs_ssp *ssp = &host->ssp;
+
 	u32 ignore_crc, get_resp, long_resp, read;
 	u32 ctrl0, cmd0, cmd1, val;
 
@@ -484,15 +409,15 @@
 		blocks = 1;
 
 	/* xfer count, block size and count need to be set differently */
-	if (ssp_is_old()) {
+	if (ssp_is_old(ssp)) {
 		ctrl0 |= BF_SSP(data_size, CTRL0_XFER_COUNT);
 		cmd0 |= BF_SSP(log2_blksz, CMD0_BLOCK_SIZE) |
 			BF_SSP(blocks - 1, CMD0_BLOCK_COUNT);
 	} else {
-		writel(data_size, host->base + HW_SSP_XFER_SIZE);
+		writel(data_size, ssp->base + HW_SSP_XFER_SIZE);
 		writel(BF_SSP(log2_blksz, BLOCK_SIZE_BLOCK_SIZE) |
 		       BF_SSP(blocks - 1, BLOCK_SIZE_BLOCK_COUNT),
-		       host->base + HW_SSP_BLOCK_SIZE);
+		       ssp->base + HW_SSP_BLOCK_SIZE);
 	}
 
 	if ((cmd->opcode == MMC_STOP_TRANSMISSION) ||
@@ -507,18 +432,18 @@
 	}
 
 	/* set the timeout count */
-	timeout = mxs_ns_to_ssp_ticks(host->clk_rate, data->timeout_ns);
-	val = readl(host->base + HW_SSP_TIMING);
+	timeout = mxs_ns_to_ssp_ticks(ssp->clk_rate, data->timeout_ns);
+	val = readl(ssp->base + HW_SSP_TIMING(ssp));
 	val &= ~(BM_SSP_TIMING_TIMEOUT);
 	val |= BF_SSP(timeout, TIMING_TIMEOUT);
-	writel(val, host->base + HW_SSP_TIMING);
+	writel(val, ssp->base + HW_SSP_TIMING(ssp));
 
 	/* pio */
-	host->ssp_pio_words[0] = ctrl0;
-	host->ssp_pio_words[1] = cmd0;
-	host->ssp_pio_words[2] = cmd1;
-	host->dma_dir = DMA_NONE;
-	host->slave_dirn = DMA_TRANS_NONE;
+	ssp->ssp_pio_words[0] = ctrl0;
+	ssp->ssp_pio_words[1] = cmd0;
+	ssp->ssp_pio_words[2] = cmd1;
+	ssp->dma_dir = DMA_NONE;
+	ssp->slave_dirn = DMA_TRANS_NONE;
 	desc = mxs_mmc_prep_dma(host, 0);
 	if (!desc)
 		goto out;
@@ -526,14 +451,14 @@
 	/* append data sg */
 	WARN_ON(host->data != NULL);
 	host->data = data;
-	host->dma_dir = dma_data_dir;
-	host->slave_dirn = slave_dirn;
+	ssp->dma_dir = dma_data_dir;
+	ssp->slave_dirn = slave_dirn;
 	desc = mxs_mmc_prep_dma(host, DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
 	if (!desc)
 		goto out;
 
 	dmaengine_submit(desc);
-	dma_async_issue_pending(host->dmach);
+	dma_async_issue_pending(ssp->dmach);
 	return;
 out:
 	dev_warn(mmc_dev(host->mmc),
@@ -574,42 +499,6 @@
 	mxs_mmc_start_cmd(host, mrq->cmd);
 }
 
-static void mxs_mmc_set_clk_rate(struct mxs_mmc_host *host, unsigned int rate)
-{
-	unsigned int ssp_clk, ssp_sck;
-	u32 clock_divide, clock_rate;
-	u32 val;
-
-	ssp_clk = clk_get_rate(host->clk);
-
-	for (clock_divide = 2; clock_divide <= 254; clock_divide += 2) {
-		clock_rate = DIV_ROUND_UP(ssp_clk, rate * clock_divide);
-		clock_rate = (clock_rate > 0) ? clock_rate - 1 : 0;
-		if (clock_rate <= 255)
-			break;
-	}
-
-	if (clock_divide > 254) {
-		dev_err(mmc_dev(host->mmc),
-			"%s: cannot set clock to %d\n", __func__, rate);
-		return;
-	}
-
-	ssp_sck = ssp_clk / clock_divide / (1 + clock_rate);
-
-	val = readl(host->base + HW_SSP_TIMING);
-	val &= ~(BM_SSP_TIMING_CLOCK_DIVIDE | BM_SSP_TIMING_CLOCK_RATE);
-	val |= BF_SSP(clock_divide, TIMING_CLOCK_DIVIDE);
-	val |= BF_SSP(clock_rate, TIMING_CLOCK_RATE);
-	writel(val, host->base + HW_SSP_TIMING);
-
-	host->clk_rate = ssp_sck;
-
-	dev_dbg(mmc_dev(host->mmc),
-		"%s: clock_divide %d, clock_rate %d, ssp_clk %d, rate_actual %d, rate_requested %d\n",
-		__func__, clock_divide, clock_rate, ssp_clk, ssp_sck, rate);
-}
-
 static void mxs_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 {
 	struct mxs_mmc_host *host = mmc_priv(mmc);
@@ -622,12 +511,13 @@
 		host->bus_width = 0;
 
 	if (ios->clock)
-		mxs_mmc_set_clk_rate(host, ios->clock);
+		mxs_ssp_set_clk_rate(&host->ssp, ios->clock);
 }
 
 static void mxs_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable)
 {
 	struct mxs_mmc_host *host = mmc_priv(mmc);
+	struct mxs_ssp *ssp = &host->ssp;
 	unsigned long flags;
 
 	spin_lock_irqsave(&host->lock, flags);
@@ -636,21 +526,22 @@
 
 	if (enable) {
 		writel(BM_SSP_CTRL0_SDIO_IRQ_CHECK,
-		       host->base + HW_SSP_CTRL0 + MXS_SET_ADDR);
+		       ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET);
 		writel(BM_SSP_CTRL1_SDIO_IRQ_EN,
-		       host->base + HW_SSP_CTRL1 + MXS_SET_ADDR);
-
-		if (readl(host->base + HW_SSP_STATUS) & BM_SSP_STATUS_SDIO_IRQ)
-			mmc_signal_sdio_irq(host->mmc);
-
+		       ssp->base + HW_SSP_CTRL1(ssp) + STMP_OFFSET_REG_SET);
 	} else {
 		writel(BM_SSP_CTRL0_SDIO_IRQ_CHECK,
-		       host->base + HW_SSP_CTRL0 + MXS_CLR_ADDR);
+		       ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_CLR);
 		writel(BM_SSP_CTRL1_SDIO_IRQ_EN,
-		       host->base + HW_SSP_CTRL1 + MXS_CLR_ADDR);
+		       ssp->base + HW_SSP_CTRL1(ssp) + STMP_OFFSET_REG_CLR);
 	}
 
 	spin_unlock_irqrestore(&host->lock, flags);
+
+	if (enable && readl(ssp->base + HW_SSP_STATUS(ssp)) &
+			BM_SSP_STATUS_SDIO_IRQ)
+		mmc_signal_sdio_irq(host->mmc);
+
 }
 
 static const struct mmc_host_ops mxs_mmc_ops = {
@@ -661,78 +552,91 @@
 	.enable_sdio_irq = mxs_mmc_enable_sdio_irq,
 };
 
-static bool mxs_mmc_dma_filter(struct dma_chan *chan, void *param)
-{
-	struct mxs_mmc_host *host = param;
-
-	if (!mxs_dma_is_apbh(chan))
-		return false;
-
-	if (chan->chan_id != host->dma_res->start)
-		return false;
-
-	chan->private = &host->dma_data;
+static struct platform_device_id mxs_ssp_ids[] = {
+	{
+		.name = "imx23-mmc",
+		.driver_data = IMX23_SSP,
+	}, {
+		.name = "imx28-mmc",
+		.driver_data = IMX28_SSP,
+	}, {
+		/* sentinel */
+	}
+};
+MODULE_DEVICE_TABLE(platform, mxs_ssp_ids);
 
-	return true;
-}
+static const struct of_device_id mxs_mmc_dt_ids[] = {
+	{ .compatible = "fsl,imx23-mmc", .data = (void *) IMX23_SSP, },
+	{ .compatible = "fsl,imx28-mmc", .data = (void *) IMX28_SSP, },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, mxs_mmc_dt_ids);
 
 static int mxs_mmc_probe(struct platform_device *pdev)
 {
+	const struct of_device_id *of_id =
+			of_match_device(mxs_mmc_dt_ids, &pdev->dev);
+	struct device_node *np = pdev->dev.of_node;
 	struct mxs_mmc_host *host;
 	struct mmc_host *mmc;
-	struct resource *iores, *dmares, *r;
-	struct mxs_mmc_platform_data *pdata;
-	int ret = 0, irq_err, irq_dma;
-	dma_cap_mask_t mask;
+	struct resource *iores;
+	struct pinctrl *pinctrl;
+	int ret = 0, irq_err;
+	struct regulator *reg_vmmc;
+	enum of_gpio_flags flags;
+	struct mxs_ssp *ssp;
+	u32 bus_width = 0;
 
 	iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0);
 	irq_err = platform_get_irq(pdev, 0);
-	irq_dma = platform_get_irq(pdev, 1);
-	if (!iores || !dmares || irq_err < 0 || irq_dma < 0)
+	if (!iores || irq_err < 0)
 		return -EINVAL;
 
-	r = request_mem_region(iores->start, resource_size(iores), pdev->name);
-	if (!r)
-		return -EBUSY;
-
 	mmc = mmc_alloc_host(sizeof(struct mxs_mmc_host), &pdev->dev);
-	if (!mmc) {
-		ret = -ENOMEM;
-		goto out_release_mem;
-	}
+	if (!mmc)
+		return -ENOMEM;
 
 	host = mmc_priv(mmc);
-	host->base = ioremap(r->start, resource_size(r));
-	if (!host->base) {
-		ret = -ENOMEM;
+	ssp = &host->ssp;
+	ssp->dev = &pdev->dev;
+	ssp->base = devm_ioremap_resource(&pdev->dev, iores);
+	if (IS_ERR(ssp->base)) {
+		ret = PTR_ERR(ssp->base);
 		goto out_mmc_free;
 	}
 
-	/* only major verion does matter */
-	host->version = readl(host->base + HW_SSP_VERSION) >>
-			BP_SSP_VERSION_MAJOR;
+	ssp->devid = (enum mxs_ssp_id) of_id->data;
 
 	host->mmc = mmc;
-	host->res = r;
-	host->dma_res = dmares;
-	host->irq = irq_err;
 	host->sdio_irq_en = 0;
 
-	host->clk = clk_get(&pdev->dev, NULL);
-	if (IS_ERR(host->clk)) {
-		ret = PTR_ERR(host->clk);
-		goto out_iounmap;
+	reg_vmmc = devm_regulator_get(&pdev->dev, "vmmc");
+	if (!IS_ERR(reg_vmmc)) {
+		ret = regulator_enable(reg_vmmc);
+		if (ret) {
+			dev_err(&pdev->dev,
+				"Failed to enable vmmc regulator: %d\n", ret);
+			goto out_mmc_free;
+		}
+	}
+
+	pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
+	if (IS_ERR(pinctrl)) {
+		ret = PTR_ERR(pinctrl);
+		goto out_mmc_free;
 	}
-	clk_prepare_enable(host->clk);
+
+	ssp->clk = clk_get(&pdev->dev, NULL);
+	if (IS_ERR(ssp->clk)) {
+		ret = PTR_ERR(ssp->clk);
+		goto out_mmc_free;
+	}
+	clk_prepare_enable(ssp->clk);
 
 	mxs_mmc_reset(host);
 
-	dma_cap_zero(mask);
-	dma_cap_set(DMA_SLAVE, mask);
-	host->dma_data.chan_irq = irq_dma;
-	host->dmach = dma_request_channel(mask, mxs_mmc_dma_filter, host);
-	if (!host->dmach) {
+	ssp->dmach = dma_request_slave_channel(&pdev->dev, "rx-tx");
+	if (!ssp->dmach) {
 		dev_err(mmc_dev(host->mmc),
 			"%s: failed to request dma\n", __func__);
 		goto out_clk_put;
@@ -743,13 +647,20 @@
 	mmc->caps = MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED |
 		    MMC_CAP_SDIO_IRQ | MMC_CAP_NEEDS_POLL;
 
-	pdata =	mmc_dev(host->mmc)->platform_data;
-	if (pdata) {
-		if (pdata->flags & SLOTF_8_BIT_CAPABLE)
-			mmc->caps |= MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA;
-		if (pdata->flags & SLOTF_4_BIT_CAPABLE)
-			mmc->caps |= MMC_CAP_4_BIT_DATA;
-	}
+	of_property_read_u32(np, "bus-width", &bus_width);
+	if (bus_width == 4)
+		mmc->caps |= MMC_CAP_4_BIT_DATA;
+	else if (bus_width == 8)
+		mmc->caps |= MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA;
+	host->broken_cd = of_property_read_bool(np, "broken-cd");
+	host->non_removable = of_property_read_bool(np, "non-removable");
+	if (host->non_removable)
+		mmc->caps |= MMC_CAP_NONREMOVABLE;
+	host->wp_gpio = of_get_named_gpio_flags(np, "wp-gpios", 0, &flags);
+	if (flags & OF_GPIO_ACTIVE_LOW)
+		host->wp_inverted = 1;
+
+	host->cd_inverted = of_property_read_bool(np, "cd-inverted");
 
 	mmc->f_min = 400000;
 	mmc->f_max = 288000000;
@@ -757,13 +668,14 @@
 
 	mmc->max_segs = 52;
 	mmc->max_blk_size = 1 << 0xf;
-	mmc->max_blk_count = (ssp_is_old()) ? 0xff : 0xffffff;
-	mmc->max_req_size = (ssp_is_old()) ? 0xffff : 0xffffffff;
-	mmc->max_seg_size = dma_get_max_seg_size(host->dmach->device->dev);
+	mmc->max_blk_count = (ssp_is_old(ssp)) ? 0xff : 0xffffff;
+	mmc->max_req_size = (ssp_is_old(ssp)) ? 0xffff : 0xffffffff;
+	mmc->max_seg_size = dma_get_max_seg_size(ssp->dmach->device->dev);
 
 	platform_set_drvdata(pdev, mmc);
 
-	ret = request_irq(host->irq, mxs_mmc_irq_handler, 0, DRIVER_NAME, host);
+	ret = devm_request_irq(&pdev->dev, irq_err, mxs_mmc_irq_handler, 0,
+			       DRIVER_NAME, host);
 	if (ret)
 		goto out_free_dma;
 
@@ -771,26 +683,20 @@
 
 	ret = mmc_add_host(mmc);
 	if (ret)
-		goto out_free_irq;
+		goto out_free_dma;
 
 	dev_info(mmc_dev(host->mmc), "initialized\n");
 
 	return 0;
 
-out_free_irq:
-	free_irq(host->irq, host);
 out_free_dma:
-	if (host->dmach)
-		dma_release_channel(host->dmach);
+	if (ssp->dmach)
+		dma_release_channel(ssp->dmach);
 out_clk_put:
-	clk_disable_unprepare(host->clk);
-	clk_put(host->clk);
-out_iounmap:
-	iounmap(host->base);
+	clk_disable_unprepare(ssp->clk);
+	clk_put(ssp->clk);
 out_mmc_free:
 	mmc_free_host(mmc);
-out_release_mem:
-	release_mem_region(iores->start, resource_size(iores));
 	return ret;
 }
 
@@ -798,26 +704,20 @@
 {
 	struct mmc_host *mmc = platform_get_drvdata(pdev);
 	struct mxs_mmc_host *host = mmc_priv(mmc);
-	struct resource *res = host->res;
+	struct mxs_ssp *ssp = &host->ssp;
 
 	mmc_remove_host(mmc);
 
-	free_irq(host->irq, host);
-
 	platform_set_drvdata(pdev, NULL);
 
-	if (host->dmach)
-		dma_release_channel(host->dmach);
-
-	clk_disable_unprepare(host->clk);
-	clk_put(host->clk);
+	if (ssp->dmach)
+		dma_release_channel(ssp->dmach);
 
-	iounmap(host->base);
+	clk_disable_unprepare(ssp->clk);
+	clk_put(ssp->clk);
 
 	mmc_free_host(mmc);
 
-	release_mem_region(res->start, resource_size(res));
-
 	return 0;
 }
 
@@ -826,11 +726,12 @@
 {
 	struct mmc_host *mmc = dev_get_drvdata(dev);
 	struct mxs_mmc_host *host = mmc_priv(mmc);
+	struct mxs_ssp *ssp = &host->ssp;
 	int ret = 0;
 
 	ret = mmc_suspend_host(mmc);
 
-	clk_disable_unprepare(host->clk);
+	clk_disable_unprepare(ssp->clk);
 
 	return ret;
 }
@@ -839,9 +740,10 @@
 {
 	struct mmc_host *mmc = dev_get_drvdata(dev);
 	struct mxs_mmc_host *host = mmc_priv(mmc);
+	struct mxs_ssp *ssp = &host->ssp;
 	int ret = 0;
 
-	clk_prepare_enable(host->clk);
+	clk_prepare_enable(ssp->clk);
 
 	ret = mmc_resume_host(mmc);
 
@@ -857,12 +759,14 @@
 static struct platform_driver mxs_mmc_driver = {
 	.probe		= mxs_mmc_probe,
 	.remove		= mxs_mmc_remove,
+	.id_table	= mxs_ssp_ids,
 	.driver		= {
 		.name	= DRIVER_NAME,
 		.owner	= THIS_MODULE,
 #ifdef CONFIG_PM
 		.pm	= &mxs_mmc_pm_ops,
 #endif
+		.of_match_table = mxs_mmc_dt_ids,
 	},
 };
 
@@ -871,3 +775,4 @@
 MODULE_DESCRIPTION("FREESCALE MXS MMC peripheral");
 MODULE_AUTHOR("Freescale Semiconductor");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:" DRIVER_NAME);
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/of_mmc_spi.c linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/of_mmc_spi.c
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/of_mmc_spi.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/of_mmc_spi.c	2014-09-12 15:59:37.348052000 +0800
@@ -146,7 +146,7 @@
 		oms->pdata.get_ro = of_mmc_spi_get_ro;
 
 	oms->detect_irq = irq_of_parse_and_map(np, 0);
-	if (oms->detect_irq != NO_IRQ) {
+	if (oms->detect_irq != 0) {
 		oms->pdata.init = of_mmc_spi_init;
 		oms->pdata.exit = of_mmc_spi_exit;
 	} else {
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/omap.c linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/omap.c
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/omap.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/omap.c	2014-09-12 15:59:37.348052000 +0800
@@ -17,26 +17,19 @@
 #include <linux/ioport.h>
 #include <linux/platform_device.h>
 #include <linux/interrupt.h>
+#include <linux/dmaengine.h>
 #include <linux/dma-mapping.h>
 #include <linux/delay.h>
 #include <linux/spinlock.h>
 #include <linux/timer.h>
+#include <linux/omap-dma.h>
 #include <linux/mmc/host.h>
 #include <linux/mmc/card.h>
 #include <linux/clk.h>
 #include <linux/scatterlist.h>
-#include <linux/i2c/tps65010.h>
 #include <linux/slab.h>
+#include <linux/platform_data/mmc-omap.h>
 
-#include <asm/io.h>
-#include <asm/irq.h>
-
-#include <plat/board.h>
-#include <plat/mmc.h>
-#include <asm/gpio.h>
-#include <plat/dma.h>
-#include <plat/mux.h>
-#include <plat/fpga.h>
 
 #define	OMAP_MMC_REG_CMD	0x00
 #define	OMAP_MMC_REG_ARGL	0x01
@@ -78,6 +71,13 @@
 #define	OMAP_MMC_STAT_CARD_BUSY		(1 <<  2)
 #define	OMAP_MMC_STAT_END_OF_CMD	(1 <<  0)
 
+#define mmc_omap7xx()	(host->features & MMC_OMAP7XX)
+#define mmc_omap15xx()	(host->features & MMC_OMAP15XX)
+#define mmc_omap16xx()	(host->features & MMC_OMAP16XX)
+#define MMC_OMAP1_MASK	(MMC_OMAP7XX | MMC_OMAP15XX | MMC_OMAP16XX)
+#define mmc_omap1()	(host->features & MMC_OMAP1_MASK)
+#define mmc_omap2()	(!mmc_omap1())
+
 #define OMAP_MMC_REG(host, reg)		(OMAP_MMC_REG_##reg << (host)->reg_shift)
 #define OMAP_MMC_READ(host, reg)	__raw_readw((host)->virt_base + OMAP_MMC_REG(host, reg))
 #define OMAP_MMC_WRITE(host, reg, val)	__raw_writew((val), (host)->virt_base + OMAP_MMC_REG(host, reg))
@@ -90,6 +90,16 @@
 #define OMAP_MMC_CMDTYPE_AC	2
 #define OMAP_MMC_CMDTYPE_ADTC	3
 
+#define OMAP_DMA_MMC_TX		21
+#define OMAP_DMA_MMC_RX		22
+#define OMAP_DMA_MMC2_TX	54
+#define OMAP_DMA_MMC2_RX	55
+
+#define OMAP24XX_DMA_MMC2_TX	47
+#define OMAP24XX_DMA_MMC2_RX	48
+#define OMAP24XX_DMA_MMC1_TX	61
+#define OMAP24XX_DMA_MMC1_RX	62
+
 
 #define DRIVER_NAME "mmci-omap"
 
@@ -105,7 +115,6 @@
 	u16			saved_con;
 	u16			bus_mode;
 	unsigned int		fclk_freq;
-	unsigned		powered:1;
 
 	struct tasklet_struct	cover_tasklet;
 	struct timer_list       cover_timer;
@@ -128,12 +137,15 @@
 	unsigned char		id; /* 16xx chips have 2 MMC blocks */
 	struct clk *		iclk;
 	struct clk *		fclk;
+	struct dma_chan		*dma_rx;
+	u32			dma_rx_burst;
+	struct dma_chan		*dma_tx;
+	u32			dma_tx_burst;
 	struct resource		*mem_res;
 	void __iomem		*virt_base;
 	unsigned int		phys_base;
 	int			irq;
 	unsigned char		bus_mode;
-	unsigned char		hw_bus_mode;
 	unsigned int		reg_shift;
 
 	struct work_struct	cmd_abort_work;
@@ -151,14 +163,11 @@
 	u32			buffer_bytes_left;
 	u32			total_bytes_left;
 
+	unsigned		features;
 	unsigned		use_dma:1;
 	unsigned		brs_received:1, dma_done:1;
-	unsigned		dma_is_read:1;
 	unsigned		dma_in_use:1;
-	int			dma_ch;
 	spinlock_t		dma_lock;
-	struct timer_list	dma_timer;
-	unsigned		dma_len;
 
 	struct mmc_omap_slot    *slots[OMAP_MMC_MAX_SLOTS];
 	struct mmc_omap_slot    *current_slot;
@@ -169,11 +178,11 @@
 	struct timer_list       clk_timer;
 	spinlock_t		clk_lock;     /* for changing enabled state */
 	unsigned int            fclk_enabled:1;
+	struct workqueue_struct *mmc_omap_wq;
 
 	struct omap_mmc_platform_data *pdata;
 };
 
-static struct workqueue_struct *mmc_omap_wq;
 
 static void mmc_omap_fclk_offdelay(struct mmc_omap_slot *slot)
 {
@@ -291,7 +300,7 @@
 		host->next_slot = new_slot;
 		host->mmc = new_slot->mmc;
 		spin_unlock_irqrestore(&host->slot_lock, flags);
-		queue_work(mmc_omap_wq, &host->slot_release_work);
+		queue_work(host->mmc_omap_wq, &host->slot_release_work);
 		return;
 	}
 
@@ -406,18 +415,25 @@
 		     int abort)
 {
 	enum dma_data_direction dma_data_dir;
+	struct device *dev = mmc_dev(host->mmc);
+	struct dma_chan *c;
 
-	BUG_ON(host->dma_ch < 0);
-	if (data->error)
-		omap_stop_dma(host->dma_ch);
-	/* Release DMA channel lazily */
-	mod_timer(&host->dma_timer, jiffies + HZ);
-	if (data->flags & MMC_DATA_WRITE)
+	if (data->flags & MMC_DATA_WRITE) {
 		dma_data_dir = DMA_TO_DEVICE;
-	else
+		c = host->dma_tx;
+	} else {
 		dma_data_dir = DMA_FROM_DEVICE;
-	dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->sg_len,
-		     dma_data_dir);
+		c = host->dma_rx;
+	}
+	if (c) {
+		if (data->error) {
+			dmaengine_terminate_all(c);
+			/* Claim nothing transferred on error... */
+			data->bytes_xfered = 0;
+		}
+		dev = c->device->dev;
+	}
+	dma_unmap_sg(dev, data->sg, host->sg_len, dma_data_dir);
 }
 
 static void mmc_omap_send_stop_work(struct work_struct *work)
@@ -459,7 +475,7 @@
 	}
 
 	host->stop_data = data;
-	queue_work(mmc_omap_wq, &host->send_stop_work);
+	queue_work(host->mmc_omap_wq, &host->send_stop_work);
 }
 
 static void
@@ -525,16 +541,6 @@
 }
 
 static void
-mmc_omap_dma_timer(unsigned long data)
-{
-	struct mmc_omap_host *host = (struct mmc_omap_host *) data;
-
-	BUG_ON(host->dma_ch < 0);
-	omap_free_dma(host->dma_ch);
-	host->dma_ch = -1;
-}
-
-static void
 mmc_omap_dma_done(struct mmc_omap_host *host, struct mmc_data *data)
 {
 	unsigned long flags;
@@ -639,7 +645,7 @@
 		OMAP_MMC_WRITE(host, IE, 0);
 		disable_irq(host->irq);
 		host->abort = 1;
-		queue_work(mmc_omap_wq, &host->cmd_abort_work);
+		queue_work(host->mmc_omap_wq, &host->cmd_abort_work);
 	}
 	spin_unlock_irqrestore(&host->slot_lock, flags);
 }
@@ -669,7 +675,7 @@
 static void
 mmc_omap_xfer_data(struct mmc_omap_host *host, int write)
 {
-	int n;
+	int n, nwords;
 
 	if (host->buffer_bytes_left == 0) {
 		host->sg_idx++;
@@ -679,33 +685,48 @@
 	n = 64;
 	if (n > host->buffer_bytes_left)
 		n = host->buffer_bytes_left;
+
+	nwords = n / 2;
+	nwords += n & 1; /* handle odd number of bytes to transfer */
+
 	host->buffer_bytes_left -= n;
 	host->total_bytes_left -= n;
 	host->data->bytes_xfered += n;
 
 	if (write) {
-		__raw_writesw(host->virt_base + OMAP_MMC_REG(host, DATA), host->buffer, n);
+		__raw_writesw(host->virt_base + OMAP_MMC_REG(host, DATA),
+			      host->buffer, nwords);
 	} else {
-		__raw_readsw(host->virt_base + OMAP_MMC_REG(host, DATA), host->buffer, n);
+		__raw_readsw(host->virt_base + OMAP_MMC_REG(host, DATA),
+			     host->buffer, nwords);
 	}
+
+	host->buffer += nwords;
 }
 
-static inline void mmc_omap_report_irq(u16 status)
+#ifdef CONFIG_MMC_DEBUG
+static void mmc_omap_report_irq(struct mmc_omap_host *host, u16 status)
 {
 	static const char *mmc_omap_status_bits[] = {
 		"EOC", "CD", "CB", "BRS", "EOFB", "DTO", "DCRC", "CTO",
 		"CCRC", "CRW", "AF", "AE", "OCRB", "CIRQ", "CERR"
 	};
-	int i, c = 0;
+	int i;
+	char res[64], *buf = res;
+
+	buf += sprintf(buf, "MMC IRQ 0x%x:", status);
 
 	for (i = 0; i < ARRAY_SIZE(mmc_omap_status_bits); i++)
-		if (status & (1 << i)) {
-			if (c)
-				printk(" ");
-			printk("%s", mmc_omap_status_bits[i]);
-			c++;
-		}
+		if (status & (1 << i))
+			buf += sprintf(buf, " %s", mmc_omap_status_bits[i]);
+	dev_vdbg(mmc_dev(host->mmc), "%s\n", res);
 }
+#else
+static void mmc_omap_report_irq(struct mmc_omap_host *host, u16 status)
+{
+}
+#endif
+
 
 static irqreturn_t mmc_omap_irq(int irq, void *dev_id)
 {
@@ -739,12 +760,10 @@
 			cmd = host->cmd->opcode;
 		else
 			cmd = -1;
-#ifdef CONFIG_MMC_DEBUG
 		dev_dbg(mmc_dev(host->mmc), "MMC IRQ %04x (CMD %d): ",
 			status, cmd);
-		mmc_omap_report_irq(status);
-		printk("\n");
-#endif
+		mmc_omap_report_irq(host, status);
+
 		if (host->total_bytes_left) {
 			if ((status & OMAP_MMC_STAT_A_FULL) ||
 			    (status & OMAP_MMC_STAT_END_OF_DATA))
@@ -828,7 +847,7 @@
 		host->abort = 1;
 		OMAP_MMC_WRITE(host, IE, 0);
 		disable_irq_nosync(host->irq);
-		queue_work(mmc_omap_wq, &host->cmd_abort_work);
+		queue_work(host->mmc_omap_wq, &host->cmd_abort_work);
 		return IRQ_HANDLED;
 	}
 
@@ -891,159 +910,15 @@
 		  jiffies + msecs_to_jiffies(OMAP_MMC_COVER_POLL_DELAY));
 }
 
-/* Prepare to transfer the next segment of a scatterlist */
-static void
-mmc_omap_prepare_dma(struct mmc_omap_host *host, struct mmc_data *data)
+static void mmc_omap_dma_callback(void *priv)
 {
-	int dma_ch = host->dma_ch;
-	unsigned long data_addr;
-	u16 buf, frame;
-	u32 count;
-	struct scatterlist *sg = &data->sg[host->sg_idx];
-	int src_port = 0;
-	int dst_port = 0;
-	int sync_dev = 0;
-
-	data_addr = host->phys_base + OMAP_MMC_REG(host, DATA);
-	frame = data->blksz;
-	count = sg_dma_len(sg);
-
-	if ((data->blocks == 1) && (count > data->blksz))
-		count = frame;
-
-	host->dma_len = count;
-
-	/* FIFO is 16x2 bytes on 15xx, and 32x2 bytes on 16xx and 24xx.
-	 * Use 16 or 32 word frames when the blocksize is at least that large.
-	 * Blocksize is usually 512 bytes; but not for some SD reads.
-	 */
-	if (cpu_is_omap15xx() && frame > 32)
-		frame = 32;
-	else if (frame > 64)
-		frame = 64;
-	count /= frame;
-	frame >>= 1;
-
-	if (!(data->flags & MMC_DATA_WRITE)) {
-		buf = 0x800f | ((frame - 1) << 8);
-
-		if (cpu_class_is_omap1()) {
-			src_port = OMAP_DMA_PORT_TIPB;
-			dst_port = OMAP_DMA_PORT_EMIFF;
-		}
-		if (cpu_is_omap24xx())
-			sync_dev = OMAP24XX_DMA_MMC1_RX;
-
-		omap_set_dma_src_params(dma_ch, src_port,
-					OMAP_DMA_AMODE_CONSTANT,
-					data_addr, 0, 0);
-		omap_set_dma_dest_params(dma_ch, dst_port,
-					 OMAP_DMA_AMODE_POST_INC,
-					 sg_dma_address(sg), 0, 0);
-		omap_set_dma_dest_data_pack(dma_ch, 1);
-		omap_set_dma_dest_burst_mode(dma_ch, OMAP_DMA_DATA_BURST_4);
-	} else {
-		buf = 0x0f80 | ((frame - 1) << 0);
-
-		if (cpu_class_is_omap1()) {
-			src_port = OMAP_DMA_PORT_EMIFF;
-			dst_port = OMAP_DMA_PORT_TIPB;
-		}
-		if (cpu_is_omap24xx())
-			sync_dev = OMAP24XX_DMA_MMC1_TX;
+	struct mmc_omap_host *host = priv;
+	struct mmc_data *data = host->data;
 
-		omap_set_dma_dest_params(dma_ch, dst_port,
-					 OMAP_DMA_AMODE_CONSTANT,
-					 data_addr, 0, 0);
-		omap_set_dma_src_params(dma_ch, src_port,
-					OMAP_DMA_AMODE_POST_INC,
-					sg_dma_address(sg), 0, 0);
-		omap_set_dma_src_data_pack(dma_ch, 1);
-		omap_set_dma_src_burst_mode(dma_ch, OMAP_DMA_DATA_BURST_4);
-	}
-
-	/* Max limit for DMA frame count is 0xffff */
-	BUG_ON(count > 0xffff);
-
-	OMAP_MMC_WRITE(host, BUF, buf);
-	omap_set_dma_transfer_params(dma_ch, OMAP_DMA_DATA_TYPE_S16,
-				     frame, count, OMAP_DMA_SYNC_FRAME,
-				     sync_dev, 0);
-}
+	/* If we got to the end of DMA, assume everything went well */
+	data->bytes_xfered += data->blocks * data->blksz;
 
-/* A scatterlist segment completed */
-static void mmc_omap_dma_cb(int lch, u16 ch_status, void *data)
-{
-	struct mmc_omap_host *host = (struct mmc_omap_host *) data;
-	struct mmc_data *mmcdat = host->data;
-
-	if (unlikely(host->dma_ch < 0)) {
-		dev_err(mmc_dev(host->mmc),
-			"DMA callback while DMA not enabled\n");
-		return;
-	}
-	/* FIXME: We really should do something to _handle_ the errors */
-	if (ch_status & OMAP1_DMA_TOUT_IRQ) {
-		dev_err(mmc_dev(host->mmc),"DMA timeout\n");
-		return;
-	}
-	if (ch_status & OMAP_DMA_DROP_IRQ) {
-		dev_err(mmc_dev(host->mmc), "DMA sync error\n");
-		return;
-	}
-	if (!(ch_status & OMAP_DMA_BLOCK_IRQ)) {
-		return;
-	}
-	mmcdat->bytes_xfered += host->dma_len;
-	host->sg_idx++;
-	if (host->sg_idx < host->sg_len) {
-		mmc_omap_prepare_dma(host, host->data);
-		omap_start_dma(host->dma_ch);
-	} else
-		mmc_omap_dma_done(host, host->data);
-}
-
-static int mmc_omap_get_dma_channel(struct mmc_omap_host *host, struct mmc_data *data)
-{
-	const char *dma_dev_name;
-	int sync_dev, dma_ch, is_read, r;
-
-	is_read = !(data->flags & MMC_DATA_WRITE);
-	del_timer_sync(&host->dma_timer);
-	if (host->dma_ch >= 0) {
-		if (is_read == host->dma_is_read)
-			return 0;
-		omap_free_dma(host->dma_ch);
-		host->dma_ch = -1;
-	}
-
-	if (is_read) {
-		if (host->id == 0) {
-			sync_dev = OMAP_DMA_MMC_RX;
-			dma_dev_name = "MMC1 read";
-		} else {
-			sync_dev = OMAP_DMA_MMC2_RX;
-			dma_dev_name = "MMC2 read";
-		}
-	} else {
-		if (host->id == 0) {
-			sync_dev = OMAP_DMA_MMC_TX;
-			dma_dev_name = "MMC1 write";
-		} else {
-			sync_dev = OMAP_DMA_MMC2_TX;
-			dma_dev_name = "MMC2 write";
-		}
-	}
-	r = omap_request_dma(sync_dev, dma_dev_name, mmc_omap_dma_cb,
-			     host, &dma_ch);
-	if (r != 0) {
-		dev_dbg(mmc_dev(host->mmc), "omap_request_dma() failed with %d\n", r);
-		return r;
-	}
-	host->dma_ch = dma_ch;
-	host->dma_is_read = is_read;
-
-	return 0;
+	mmc_omap_dma_done(host, data);
 }
 
 static inline void set_cmd_timeout(struct mmc_omap_host *host, struct mmc_request *req)
@@ -1118,33 +993,85 @@
 
 	host->sg_idx = 0;
 	if (use_dma) {
-		if (mmc_omap_get_dma_channel(host, data) == 0) {
-			enum dma_data_direction dma_data_dir;
+		enum dma_data_direction dma_data_dir;
+		struct dma_async_tx_descriptor *tx;
+		struct dma_chan *c;
+		u32 burst, *bp;
+		u16 buf;
+
+		/*
+		 * FIFO is 16x2 bytes on 15xx, and 32x2 bytes on 16xx
+		 * and 24xx. Use 16 or 32 word frames when the
+		 * blocksize is at least that large. Blocksize is
+		 * usually 512 bytes; but not for some SD reads.
+		 */
+		burst = mmc_omap15xx() ? 32 : 64;
+		if (burst > data->blksz)
+			burst = data->blksz;
+
+		burst >>= 1;
+
+		if (data->flags & MMC_DATA_WRITE) {
+			c = host->dma_tx;
+			bp = &host->dma_tx_burst;
+			buf = 0x0f80 | (burst - 1) << 0;
+			dma_data_dir = DMA_TO_DEVICE;
+		} else {
+			c = host->dma_rx;
+			bp = &host->dma_rx_burst;
+			buf = 0x800f | (burst - 1) << 8;
+			dma_data_dir = DMA_FROM_DEVICE;
+		}
+
+		if (!c)
+			goto use_pio;
 
-			if (data->flags & MMC_DATA_WRITE)
-				dma_data_dir = DMA_TO_DEVICE;
-			else
-				dma_data_dir = DMA_FROM_DEVICE;
-
-			host->sg_len = dma_map_sg(mmc_dev(host->mmc), data->sg,
-						sg_len, dma_data_dir);
-			host->total_bytes_left = 0;
-			mmc_omap_prepare_dma(host, req->data);
-			host->brs_received = 0;
-			host->dma_done = 0;
-			host->dma_in_use = 1;
-		} else
-			use_dma = 0;
+		/* Only reconfigure if we have a different burst size */
+		if (*bp != burst) {
+			struct dma_slave_config cfg;
+
+			cfg.src_addr = host->phys_base + OMAP_MMC_REG(host, DATA);
+			cfg.dst_addr = host->phys_base + OMAP_MMC_REG(host, DATA);
+			cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
+			cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
+			cfg.src_maxburst = burst;
+			cfg.dst_maxburst = burst;
+
+			if (dmaengine_slave_config(c, &cfg))
+				goto use_pio;
+
+			*bp = burst;
+		}
+
+		host->sg_len = dma_map_sg(c->device->dev, data->sg, sg_len,
+					  dma_data_dir);
+		if (host->sg_len == 0)
+			goto use_pio;
+
+		tx = dmaengine_prep_slave_sg(c, data->sg, host->sg_len,
+			data->flags & MMC_DATA_WRITE ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM,
+			DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+		if (!tx)
+			goto use_pio;
+
+		OMAP_MMC_WRITE(host, BUF, buf);
+
+		tx->callback = mmc_omap_dma_callback;
+		tx->callback_param = host;
+		dmaengine_submit(tx);
+		host->brs_received = 0;
+		host->dma_done = 0;
+		host->dma_in_use = 1;
+		return;
 	}
+ use_pio:
 
 	/* Revert to PIO? */
-	if (!use_dma) {
-		OMAP_MMC_WRITE(host, BUF, 0x1f1f);
-		host->total_bytes_left = data->blocks * block_size;
-		host->sg_len = sg_len;
-		mmc_omap_sg_to_buf(host);
-		host->dma_in_use = 0;
-	}
+	OMAP_MMC_WRITE(host, BUF, 0x1f1f);
+	host->total_bytes_left = data->blocks * block_size;
+	host->sg_len = sg_len;
+	mmc_omap_sg_to_buf(host);
+	host->dma_in_use = 0;
 }
 
 static void mmc_omap_start_request(struct mmc_omap_host *host,
@@ -1157,8 +1084,12 @@
 	/* only touch fifo AFTER the controller readies it */
 	mmc_omap_prepare_data(host, req);
 	mmc_omap_start_command(host, req->cmd);
-	if (host->dma_in_use)
-		omap_start_dma(host->dma_ch);
+	if (host->dma_in_use) {
+		struct dma_chan *c = host->data->flags & MMC_DATA_WRITE ?
+				host->dma_tx : host->dma_rx;
+
+		dma_async_issue_pending(c);
+	}
 }
 
 static void mmc_omap_request(struct mmc_host *mmc, struct mmc_request *req)
@@ -1190,8 +1121,7 @@
 	if (slot->pdata->set_power != NULL)
 		slot->pdata->set_power(mmc_dev(slot->mmc), slot->id, power_on,
 					vdd);
-
-	if (cpu_is_omap24xx()) {
+	if (mmc_omap2()) {
 		u16 w;
 
 		if (power_on) {
@@ -1300,7 +1230,7 @@
 	.set_ios	= mmc_omap_set_ios,
 };
 
-static int __init mmc_omap_new_slot(struct mmc_omap_host *host, int id)
+static int mmc_omap_new_slot(struct mmc_omap_host *host, int id)
 {
 	struct mmc_omap_slot *slot = NULL;
 	struct mmc_host *mmc;
@@ -1325,7 +1255,7 @@
 	mmc->ops = &mmc_omap_ops;
 	mmc->f_min = 400000;
 
-	if (cpu_class_is_omap2())
+	if (mmc_omap2())
 		mmc->f_max = 48000000;
 	else
 		mmc->f_max = 24000000;
@@ -1389,17 +1319,19 @@
 
 	tasklet_kill(&slot->cover_tasklet);
 	del_timer_sync(&slot->cover_timer);
-	flush_workqueue(mmc_omap_wq);
+	flush_workqueue(slot->host->mmc_omap_wq);
 
 	mmc_remove_host(mmc);
 	mmc_free_host(mmc);
 }
 
-static int __init mmc_omap_probe(struct platform_device *pdev)
+static int mmc_omap_probe(struct platform_device *pdev)
 {
 	struct omap_mmc_platform_data *pdata = pdev->dev.platform_data;
 	struct mmc_omap_host *host = NULL;
 	struct resource *res;
+	dma_cap_mask_t mask;
+	unsigned sig;
 	int i, ret = 0;
 	int irq;
 
@@ -1439,22 +1371,18 @@
 	setup_timer(&host->clk_timer, mmc_omap_clk_timer, (unsigned long) host);
 
 	spin_lock_init(&host->dma_lock);
-	setup_timer(&host->dma_timer, mmc_omap_dma_timer, (unsigned long) host);
 	spin_lock_init(&host->slot_lock);
 	init_waitqueue_head(&host->slot_wq);
 
 	host->pdata = pdata;
+	host->features = host->pdata->slots[0].features;
 	host->dev = &pdev->dev;
 	platform_set_drvdata(pdev, host);
 
 	host->id = pdev->id;
 	host->mem_res = res;
 	host->irq = irq;
-
 	host->use_dma = 1;
-	host->dev->dma_mask = &pdata->dma_mask;
-	host->dma_ch = -1;
-
 	host->irq = irq;
 	host->phys_base = host->mem_res->start;
 	host->virt_base = ioremap(res->start, resource_size(res));
@@ -1474,9 +1402,48 @@
 		goto err_free_iclk;
 	}
 
+	dma_cap_zero(mask);
+	dma_cap_set(DMA_SLAVE, mask);
+
+	host->dma_tx_burst = -1;
+	host->dma_rx_burst = -1;
+
+	if (mmc_omap2())
+		sig = host->id == 0 ? OMAP24XX_DMA_MMC1_TX : OMAP24XX_DMA_MMC2_TX;
+	else
+		sig = host->id == 0 ? OMAP_DMA_MMC_TX : OMAP_DMA_MMC2_TX;
+	host->dma_tx = dma_request_channel(mask, omap_dma_filter_fn, &sig);
+#if 0
+	if (!host->dma_tx) {
+		dev_err(host->dev, "unable to obtain TX DMA engine channel %u\n",
+			sig);
+		goto err_dma;
+	}
+#else
+	if (!host->dma_tx)
+		dev_warn(host->dev, "unable to obtain TX DMA engine channel %u\n",
+			sig);
+#endif
+	if (mmc_omap2())
+		sig = host->id == 0 ? OMAP24XX_DMA_MMC1_RX : OMAP24XX_DMA_MMC2_RX;
+	else
+		sig = host->id == 0 ? OMAP_DMA_MMC_RX : OMAP_DMA_MMC2_RX;
+	host->dma_rx = dma_request_channel(mask, omap_dma_filter_fn, &sig);
+#if 0
+	if (!host->dma_rx) {
+		dev_err(host->dev, "unable to obtain RX DMA engine channel %u\n",
+			sig);
+		goto err_dma;
+	}
+#else
+	if (!host->dma_rx)
+		dev_warn(host->dev, "unable to obtain RX DMA engine channel %u\n",
+			sig);
+#endif
+
 	ret = request_irq(host->irq, mmc_omap_irq, 0, DRIVER_NAME, host);
 	if (ret)
-		goto err_free_fclk;
+		goto err_free_dma;
 
 	if (pdata->init != NULL) {
 		ret = pdata->init(&pdev->dev);
@@ -1485,26 +1452,36 @@
 	}
 
 	host->nr_slots = pdata->nr_slots;
+	host->reg_shift = (mmc_omap7xx() ? 1 : 2);
+
+	host->mmc_omap_wq = alloc_workqueue("mmc_omap", 0, 0);
+	if (!host->mmc_omap_wq)
+		goto err_plat_cleanup;
+
 	for (i = 0; i < pdata->nr_slots; i++) {
 		ret = mmc_omap_new_slot(host, i);
 		if (ret < 0) {
 			while (--i >= 0)
 				mmc_omap_remove_slot(host->slots[i]);
 
-			goto err_plat_cleanup;
+			goto err_destroy_wq;
 		}
 	}
 
-	host->reg_shift = (cpu_is_omap7xx() ? 1 : 2);
-
 	return 0;
 
+err_destroy_wq:
+	destroy_workqueue(host->mmc_omap_wq);
 err_plat_cleanup:
 	if (pdata->cleanup)
 		pdata->cleanup(&pdev->dev);
 err_free_irq:
 	free_irq(host->irq, host);
-err_free_fclk:
+err_free_dma:
+	if (host->dma_tx)
+		dma_release_channel(host->dma_tx);
+	if (host->dma_rx)
+		dma_release_channel(host->dma_rx);
 	clk_put(host->fclk);
 err_free_iclk:
 	clk_disable(host->iclk);
@@ -1539,9 +1516,15 @@
 	clk_disable(host->iclk);
 	clk_put(host->iclk);
 
+	if (host->dma_tx)
+		dma_release_channel(host->dma_tx);
+	if (host->dma_rx)
+		dma_release_channel(host->dma_rx);
+
 	iounmap(host->virt_base);
 	release_mem_region(pdev->resource[0].start,
 			   pdev->resource[0].end - pdev->resource[0].start + 1);
+	destroy_workqueue(host->mmc_omap_wq);
 
 	kfree(host);
 
@@ -1599,6 +1582,7 @@
 #endif
 
 static struct platform_driver mmc_omap_driver = {
+	.probe		= mmc_omap_probe,
 	.remove		= mmc_omap_remove,
 	.suspend	= mmc_omap_suspend,
 	.resume		= mmc_omap_resume,
@@ -1608,29 +1592,7 @@
 	},
 };
 
-static int __init mmc_omap_init(void)
-{
-	int ret;
-
-	mmc_omap_wq = alloc_workqueue("mmc_omap", 0, 0);
-	if (!mmc_omap_wq)
-		return -ENOMEM;
-
-	ret = platform_driver_probe(&mmc_omap_driver, mmc_omap_probe);
-	if (ret)
-		destroy_workqueue(mmc_omap_wq);
-	return ret;
-}
-
-static void __exit mmc_omap_exit(void)
-{
-	platform_driver_unregister(&mmc_omap_driver);
-	destroy_workqueue(mmc_omap_wq);
-}
-
-module_init(mmc_omap_init);
-module_exit(mmc_omap_exit);
-
+module_platform_driver(mmc_omap_driver);
 MODULE_DESCRIPTION("OMAP Multimedia Card driver");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("platform:" DRIVER_NAME);
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/omap_hsmmc.c linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/omap_hsmmc.c
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/omap_hsmmc.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/omap_hsmmc.c	2014-09-12 15:59:37.348052000 +0800
@@ -19,6 +19,7 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/debugfs.h>
+#include <linux/dmaengine.h>
 #include <linux/seq_file.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
@@ -29,22 +30,18 @@
 #include <linux/of.h>
 #include <linux/of_gpio.h>
 #include <linux/of_device.h>
+#include <linux/omap-dma.h>
 #include <linux/mmc/host.h>
 #include <linux/mmc/core.h>
 #include <linux/mmc/mmc.h>
 #include <linux/io.h>
-#include <linux/semaphore.h>
 #include <linux/gpio.h>
 #include <linux/regulator/consumer.h>
+#include <linux/pinctrl/consumer.h>
 #include <linux/pm_runtime.h>
-#include <plat/dma.h>
-#include <mach/hardware.h>
-#include <plat/board.h>
-#include <plat/mmc.h>
-#include <plat/cpu.h>
+#include <linux/platform_data/mmc-omap.h>
 
 /* OMAP HSMMC Host Controller Registers */
-#define OMAP_HSMMC_SYSCONFIG	0x0010
 #define OMAP_HSMMC_SYSSTATUS	0x0014
 #define OMAP_HSMMC_CON		0x002C
 #define OMAP_HSMMC_BLK		0x0104
@@ -64,6 +61,7 @@
 
 #define VS18			(1 << 26)
 #define VS30			(1 << 25)
+#define HSS			(1 << 21)
 #define SDVS18			(0x5 << 9)
 #define SDVS30			(0x6 << 9)
 #define SDVS33			(0x7 << 9)
@@ -80,27 +78,17 @@
 #define CLKD_SHIFT		6
 #define DTO_MASK		0x000F0000
 #define DTO_SHIFT		16
-#define INT_EN_MASK		0x307F0033
-#define BWR_ENABLE		(1 << 4)
-#define BRR_ENABLE		(1 << 5)
-#define DTO_ENABLE		(1 << 20)
 #define INIT_STREAM		(1 << 1)
 #define DP_SELECT		(1 << 21)
 #define DDIR			(1 << 4)
-#define DMA_EN			0x1
+#define DMAE			0x1
 #define MSBS			(1 << 5)
 #define BCE			(1 << 1)
 #define FOUR_BIT		(1 << 1)
+#define HSPE			(1 << 2)
+#define DDR			(1 << 19)
 #define DW8			(1 << 5)
-#define CC			0x1
-#define TC			0x02
 #define OD			0x1
-#define ERR			(1 << 15)
-#define CMD_TIMEOUT		(1 << 16)
-#define DATA_TIMEOUT		(1 << 20)
-#define CMD_CRC			(1 << 17)
-#define DATA_CRC		(1 << 21)
-#define CARD_ERR		(1 << 28)
 #define STAT_CLEAR		0xFFFFFFFF
 #define INIT_STREAM_CMD		0x00000000
 #define DUAL_VOLT_OCR_BIT	7
@@ -109,6 +97,26 @@
 #define SOFTRESET		(1 << 1)
 #define RESETDONE		(1 << 0)
 
+/* Interrupt masks for IE and ISE register */
+#define CC_EN			(1 << 0)
+#define TC_EN			(1 << 1)
+#define BWR_EN			(1 << 4)
+#define BRR_EN			(1 << 5)
+#define ERR_EN			(1 << 15)
+#define CTO_EN			(1 << 16)
+#define CCRC_EN			(1 << 17)
+#define CEB_EN			(1 << 18)
+#define CIE_EN			(1 << 19)
+#define DTO_EN			(1 << 20)
+#define DCRC_EN			(1 << 21)
+#define DEB_EN			(1 << 22)
+#define CERR_EN			(1 << 28)
+#define BADA_EN			(1 << 29)
+
+#define INT_EN_MASK		(BADA_EN | CERR_EN | DEB_EN | DCRC_EN |\
+		DTO_EN | CIE_EN | CEB_EN | CCRC_EN | CTO_EN | \
+		BRR_EN | BWR_EN | TC_EN | CC_EN)
+
 #define MMC_AUTOSUSPEND_DELAY	100
 #define MMC_TIMEOUT_MS		20
 #define OMAP_MMC_MIN_CLOCK	400000
@@ -153,6 +161,7 @@
 	 */
 	struct	regulator	*vcc;
 	struct	regulator	*vcc_aux;
+	int			pbias_disable;
 	void	__iomem		*base;
 	resource_size_t		mapbase;
 	spinlock_t		irq_lock; /* Prevent races with irq handler */
@@ -160,17 +169,14 @@
 	unsigned int		dma_sg_idx;
 	unsigned char		bus_mode;
 	unsigned char		power_mode;
-	u32			*buffer;
-	u32			bytesleft;
 	int			suspended;
 	int			irq;
 	int			use_dma, dma_ch;
-	int			dma_line_tx, dma_line_rx;
+	struct dma_chan		*tx_chan;
+	struct dma_chan		*rx_chan;
 	int			slot_id;
-	int			got_dbclk;
 	int			response_busy;
 	int			context_loss;
-	int			vdd;
 	int			protect_card;
 	int			reqs_blocked;
 	int			use_reg;
@@ -182,7 +188,8 @@
 
 static int omap_hsmmc_card_detect(struct device *dev, int slot)
 {
-	struct omap_mmc_platform_data *mmc = dev->platform_data;
+	struct omap_hsmmc_host *host = dev_get_drvdata(dev);
+	struct omap_mmc_platform_data *mmc = host->pdata;
 
 	/* NOTE: assumes card detect signal is active-low */
 	return !gpio_get_value_cansleep(mmc->slots[0].switch_pin);
@@ -190,7 +197,8 @@
 
 static int omap_hsmmc_get_wp(struct device *dev, int slot)
 {
-	struct omap_mmc_platform_data *mmc = dev->platform_data;
+	struct omap_hsmmc_host *host = dev_get_drvdata(dev);
+	struct omap_mmc_platform_data *mmc = host->pdata;
 
 	/* NOTE: assumes write protect signal is active-high */
 	return gpio_get_value_cansleep(mmc->slots[0].gpio_wp);
@@ -198,7 +206,8 @@
 
 static int omap_hsmmc_get_cover_state(struct device *dev, int slot)
 {
-	struct omap_mmc_platform_data *mmc = dev->platform_data;
+	struct omap_hsmmc_host *host = dev_get_drvdata(dev);
+	struct omap_mmc_platform_data *mmc = host->pdata;
 
 	/* NOTE: assumes card detect signal is active-low */
 	return !gpio_get_value_cansleep(mmc->slots[0].switch_pin);
@@ -208,7 +217,8 @@
 
 static int omap_hsmmc_suspend_cdirq(struct device *dev, int slot)
 {
-	struct omap_mmc_platform_data *mmc = dev->platform_data;
+	struct omap_hsmmc_host *host = dev_get_drvdata(dev);
+	struct omap_mmc_platform_data *mmc = host->pdata;
 
 	disable_irq(mmc->slots[0].card_detect_irq);
 	return 0;
@@ -216,7 +226,8 @@
 
 static int omap_hsmmc_resume_cdirq(struct device *dev, int slot)
 {
-	struct omap_mmc_platform_data *mmc = dev->platform_data;
+	struct omap_hsmmc_host *host = dev_get_drvdata(dev);
+	struct omap_mmc_platform_data *mmc = host->pdata;
 
 	enable_irq(mmc->slots[0].card_detect_irq);
 	return 0;
@@ -245,11 +256,11 @@
 	if (!host->vcc)
 		return 0;
 	/*
-	 * With DT, never turn OFF the regulator. This is because
+	 * With DT, never turn OFF the regulator for MMC1. This is because
 	 * the pbias cell programming support is still missing when
 	 * booting with Device tree
 	 */
-	if (dev->of_node && !vdd)
+	if (host->pbias_disable && !vdd)
 		return 0;
 
 	if (mmc_slot(host).before_set_reg)
@@ -299,12 +310,12 @@
 	struct regulator *reg;
 	int ocr_value = 0;
 
-	mmc_slot(host).set_power = omap_hsmmc_set_power;
-
 	reg = regulator_get(host->dev, "vmmc");
 	if (IS_ERR(reg)) {
-		dev_dbg(host->dev, "vmmc regulator missing\n");
+		dev_err(host->dev, "vmmc regulator missing\n");
+		return PTR_ERR(reg);
 	} else {
+		mmc_slot(host).set_power = omap_hsmmc_set_power;
 		host->vcc = reg;
 		ocr_value = mmc_regulator_get_ocrmask(reg);
 		if (!mmc_slot(host).ocr_mask) {
@@ -445,7 +456,7 @@
 	OMAP_HSMMC_WRITE(host->base, SYSCTL,
 		OMAP_HSMMC_READ(host->base, SYSCTL) & ~CEN);
 	if ((OMAP_HSMMC_READ(host->base, SYSCTL) & CEN) != 0x0)
-		dev_dbg(mmc_dev(host->mmc), "MMC Clock is not stoped\n");
+		dev_dbg(mmc_dev(host->mmc), "MMC Clock is not stopped\n");
 }
 
 static void omap_hsmmc_enable_irq(struct omap_hsmmc_host *host,
@@ -454,13 +465,13 @@
 	unsigned int irq_mask;
 
 	if (host->use_dma)
-		irq_mask = INT_EN_MASK & ~(BRR_ENABLE | BWR_ENABLE);
+		irq_mask = INT_EN_MASK & ~(BRR_EN | BWR_EN);
 	else
 		irq_mask = INT_EN_MASK;
 
 	/* Disable timeout for erases */
 	if (cmd->opcode == MMC_ERASE)
-		irq_mask &= ~DTO_ENABLE;
+		irq_mask &= ~DTO_EN;
 
 	OMAP_HSMMC_WRITE(host->base, STAT, STAT_CLEAR);
 	OMAP_HSMMC_WRITE(host->base, ISE, irq_mask);
@@ -493,14 +504,16 @@
 	struct mmc_ios *ios = &host->mmc->ios;
 	unsigned long regval;
 	unsigned long timeout;
+	unsigned long clkdiv;
 
-	dev_dbg(mmc_dev(host->mmc), "Set clock to %uHz\n", ios->clock);
+	dev_vdbg(mmc_dev(host->mmc), "Set clock to %uHz\n", ios->clock);
 
 	omap_hsmmc_stop_clock(host);
 
 	regval = OMAP_HSMMC_READ(host->base, SYSCTL);
 	regval = regval & ~(CLKD_MASK | DTO_MASK);
-	regval = regval | (calc_divisor(host, ios) << 6) | (DTO << 16);
+	clkdiv = calc_divisor(host, ios);
+	regval = regval | (clkdiv << 6) | (DTO << 16);
 	OMAP_HSMMC_WRITE(host->base, SYSCTL, regval);
 	OMAP_HSMMC_WRITE(host->base, SYSCTL,
 		OMAP_HSMMC_READ(host->base, SYSCTL) | ICE);
@@ -511,6 +524,27 @@
 		&& time_before(jiffies, timeout))
 		cpu_relax();
 
+	/*
+	 * Enable High-Speed Support
+	 * Pre-Requisites
+	 *	- Controller should support High-Speed-Enable Bit
+	 *	- Controller should not be using DDR Mode
+	 *	- Controller should advertise that it supports High Speed
+	 *	  in capabilities register
+	 *	- MMC/SD clock coming out of controller > 25MHz
+	 */
+	if ((mmc_slot(host).features & HSMMC_HAS_HSPE_SUPPORT) &&
+	    (ios->timing != MMC_TIMING_UHS_DDR50) &&
+	    ((OMAP_HSMMC_READ(host->base, CAPA) & HSS) == HSS)) {
+		regval = OMAP_HSMMC_READ(host->base, HCTL);
+		if (clkdiv && (clk_get_rate(host->fclk)/clkdiv) > 25000000)
+			regval |= HSPE;
+		else
+			regval &= ~HSPE;
+
+		OMAP_HSMMC_WRITE(host->base, HCTL, regval);
+	}
+
 	omap_hsmmc_start_clock(host);
 }
 
@@ -520,6 +554,10 @@
 	u32 con;
 
 	con = OMAP_HSMMC_READ(host->base, CON);
+	if (ios->timing == MMC_TIMING_UHS_DDR50)
+		con |= DDR;	/* configure in DDR mode */
+	else
+		con &= ~DDR;
 	switch (ios->bus_width) {
 	case MMC_BUS_WIDTH_8:
 		OMAP_HSMMC_WRITE(host->base, CON, con | DW8);
@@ -574,21 +612,8 @@
 	if (host->context_loss == context_loss)
 		return 1;
 
-	/* Wait for hardware reset */
-	timeout = jiffies + msecs_to_jiffies(MMC_TIMEOUT_MS);
-	while ((OMAP_HSMMC_READ(host->base, SYSSTATUS) & RESETDONE) != RESETDONE
-		&& time_before(jiffies, timeout))
-		;
-
-	/* Do software reset */
-	OMAP_HSMMC_WRITE(host->base, SYSCONFIG, SOFTRESET);
-	timeout = jiffies + msecs_to_jiffies(MMC_TIMEOUT_MS);
-	while ((OMAP_HSMMC_READ(host->base, SYSSTATUS) & RESETDONE) != RESETDONE
-		&& time_before(jiffies, timeout))
-		;
-
-	OMAP_HSMMC_WRITE(host->base, SYSCONFIG,
-			OMAP_HSMMC_READ(host->base, SYSCONFIG) | AUTOIDLE);
+	if (!OMAP_HSMMC_READ(host->base, SYSSTATUS) & RESETDONE)
+		return 1;
 
 	if (host->pdata->controller_flags & OMAP_HSMMC_SUPPORTS_DUAL_VOLT) {
 		if (host->power_mode != MMC_POWER_OFF &&
@@ -684,8 +709,8 @@
 	OMAP_HSMMC_WRITE(host->base, CMD, INIT_STREAM_CMD);
 
 	timeout = jiffies + msecs_to_jiffies(MMC_TIMEOUT_MS);
-	while ((reg != CC) && time_before(jiffies, timeout))
-		reg = OMAP_HSMMC_READ(host->base, STAT) & CC;
+	while ((reg != CC_EN) && time_before(jiffies, timeout))
+		reg = OMAP_HSMMC_READ(host->base, STAT) & CC_EN;
 
 	OMAP_HSMMC_WRITE(host->base, CON,
 		OMAP_HSMMC_READ(host->base, CON) & ~INIT_STREAM);
@@ -740,7 +765,7 @@
 {
 	int cmdreg = 0, resptype = 0, cmdtype = 0;
 
-	dev_dbg(mmc_dev(host->mmc), "%s: CMD%d, argument 0x%08x\n",
+	dev_vdbg(mmc_dev(host->mmc), "%s: CMD%d, argument 0x%08x\n",
 		mmc_hostname(host->mmc), cmd->opcode, cmd->arg);
 	host->cmd = cmd;
 
@@ -776,7 +801,7 @@
 	}
 
 	if (host->use_dma)
-		cmdreg |= DMA_EN;
+		cmdreg |= DMAE;
 
 	host->req_in_progress = 1;
 
@@ -793,14 +818,21 @@
 		return DMA_FROM_DEVICE;
 }
 
+static struct dma_chan *omap_hsmmc_get_dma_chan(struct omap_hsmmc_host *host,
+	struct mmc_data *data)
+{
+	return data->flags & MMC_DATA_WRITE ? host->tx_chan : host->rx_chan;
+}
+
 static void omap_hsmmc_request_done(struct omap_hsmmc_host *host, struct mmc_request *mrq)
 {
 	int dma_ch;
+	unsigned long flags;
 
-	spin_lock(&host->irq_lock);
+	spin_lock_irqsave(&host->irq_lock, flags);
 	host->req_in_progress = 0;
 	dma_ch = host->dma_ch;
-	spin_unlock(&host->irq_lock);
+	spin_unlock_irqrestore(&host->irq_lock, flags);
 
 	omap_hsmmc_disable_irq(host);
 	/* Do not complete the request if DMA is still in progress */
@@ -874,19 +906,23 @@
 static void omap_hsmmc_dma_cleanup(struct omap_hsmmc_host *host, int errno)
 {
 	int dma_ch;
+	unsigned long flags;
 
 	host->data->error = errno;
 
-	spin_lock(&host->irq_lock);
+	spin_lock_irqsave(&host->irq_lock, flags);
 	dma_ch = host->dma_ch;
 	host->dma_ch = -1;
-	spin_unlock(&host->irq_lock);
+	spin_unlock_irqrestore(&host->irq_lock, flags);
 
 	if (host->use_dma && dma_ch != -1) {
-		dma_unmap_sg(mmc_dev(host->mmc), host->data->sg,
-			host->data->sg_len,
+		struct dma_chan *chan = omap_hsmmc_get_dma_chan(host, host->data);
+
+		dmaengine_terminate_all(chan);
+		dma_unmap_sg(chan->device->dev,
+			host->data->sg, host->data->sg_len,
 			omap_hsmmc_get_dma_dir(host, host->data));
-		omap_free_dma(dma_ch);
+
 		host->data->host_cookie = 0;
 	}
 	host->data = NULL;
@@ -918,7 +954,7 @@
 			buf += len;
 		}
 
-	dev_dbg(mmc_dev(host->mmc), "%s\n", res);
+	dev_vdbg(mmc_dev(host->mmc), "%s\n", res);
 }
 #else
 static inline void omap_hsmmc_dbg_report_irq(struct omap_hsmmc_host *host,
@@ -965,75 +1001,49 @@
 			__func__);
 }
 
+static void hsmmc_command_incomplete(struct omap_hsmmc_host *host,
+					int err, int end_cmd)
+{
+	if (end_cmd) {
+		omap_hsmmc_reset_controller_fsm(host, SRC);
+		if (host->cmd)
+			host->cmd->error = err;
+	}
+
+	if (host->data) {
+		omap_hsmmc_reset_controller_fsm(host, SRD);
+		omap_hsmmc_dma_cleanup(host, err);
+	} else if (host->mrq && host->mrq->cmd)
+		host->mrq->cmd->error = err;
+}
+
 static void omap_hsmmc_do_irq(struct omap_hsmmc_host *host, int status)
 {
 	struct mmc_data *data;
 	int end_cmd = 0, end_trans = 0;
 
-	if (!host->req_in_progress) {
-		do {
-			OMAP_HSMMC_WRITE(host->base, STAT, status);
-			/* Flush posted write */
-			status = OMAP_HSMMC_READ(host->base, STAT);
-		} while (status & INT_EN_MASK);
-		return;
-	}
-
 	data = host->data;
-	dev_dbg(mmc_dev(host->mmc), "IRQ Status is %x\n", status);
+	dev_vdbg(mmc_dev(host->mmc), "IRQ Status is %x\n", status);
 
-	if (status & ERR) {
+	if (status & ERR_EN) {
 		omap_hsmmc_dbg_report_irq(host, status);
-		if ((status & CMD_TIMEOUT) ||
-			(status & CMD_CRC)) {
-			if (host->cmd) {
-				if (status & CMD_TIMEOUT) {
-					omap_hsmmc_reset_controller_fsm(host,
-									SRC);
-					host->cmd->error = -ETIMEDOUT;
-				} else {
-					host->cmd->error = -EILSEQ;
-				}
-				end_cmd = 1;
-			}
-			if (host->data || host->response_busy) {
-				if (host->data)
-					omap_hsmmc_dma_cleanup(host,
-								-ETIMEDOUT);
-				host->response_busy = 0;
-				omap_hsmmc_reset_controller_fsm(host, SRD);
-			}
-		}
-		if ((status & DATA_TIMEOUT) ||
-			(status & DATA_CRC)) {
-			if (host->data || host->response_busy) {
-				int err = (status & DATA_TIMEOUT) ?
-						-ETIMEDOUT : -EILSEQ;
-
-				if (host->data)
-					omap_hsmmc_dma_cleanup(host, err);
-				else
-					host->mrq->cmd->error = err;
-				host->response_busy = 0;
-				omap_hsmmc_reset_controller_fsm(host, SRD);
-				end_trans = 1;
-			}
-		}
-		if (status & CARD_ERR) {
-			dev_dbg(mmc_dev(host->mmc),
-				"Ignoring card err CMD%d\n", host->cmd->opcode);
-			if (host->cmd)
-				end_cmd = 1;
-			if (host->data)
-				end_trans = 1;
+
+		if (status & (CTO_EN | CCRC_EN))
+			end_cmd = 1;
+		if (status & (CTO_EN | DTO_EN))
+			hsmmc_command_incomplete(host, -ETIMEDOUT, end_cmd);
+		else if (status & (CCRC_EN | DCRC_EN))
+			hsmmc_command_incomplete(host, -EILSEQ, end_cmd);
+
+		if (host->data || host->response_busy) {
+			end_trans = !end_cmd;
+			host->response_busy = 0;
 		}
 	}
 
-	OMAP_HSMMC_WRITE(host->base, STAT, status);
-
-	if (end_cmd || ((status & CC) && host->cmd))
+	if (end_cmd || ((status & CC_EN) && host->cmd))
 		omap_hsmmc_cmd_done(host, host->cmd);
-	if ((end_trans || (status & TC)) && host->mrq)
+	if ((end_trans || (status & TC_EN)) && host->mrq)
 		omap_hsmmc_xfer_done(host, data);
 }
 
@@ -1046,11 +1056,13 @@
 	int status;
 
 	status = OMAP_HSMMC_READ(host->base, STAT);
-	do {
+	while (status & INT_EN_MASK && host->req_in_progress) {
 		omap_hsmmc_do_irq(host, status);
+
 		/* Flush posted write */
+		OMAP_HSMMC_WRITE(host->base, STAT, status);
 		status = OMAP_HSMMC_READ(host->base, STAT);
-	} while (status & INT_EN_MASK);
+	}
 
 	return IRQ_HANDLED;
 }
@@ -1082,8 +1094,8 @@
 
 	/* Disable the clocks */
 	pm_runtime_put_sync(host->dev);
-	if (host->got_dbclk)
-		clk_disable(host->dbclk);
+	if (host->dbclk)
+		clk_disable_unprepare(host->dbclk);
 
 	/* Turn the power off */
 	ret = mmc_slot(host).set_power(host->dev, host->slot_id, 0, 0);
@@ -1093,8 +1105,8 @@
 		ret = mmc_slot(host).set_power(host->dev, host->slot_id, 1,
 					       vdd);
 	pm_runtime_get_sync(host->dev);
-	if (host->got_dbclk)
-		clk_enable(host->dbclk);
+	if (host->dbclk)
+		clk_prepare_enable(host->dbclk);
 
 	if (ret != 0)
 		goto err;
@@ -1128,7 +1140,7 @@
 
 	return 0;
 err:
-	dev_dbg(mmc_dev(host->mmc), "Unable to switch operating voltage\n");
+	dev_err(mmc_dev(host->mmc), "Unable to switch operating voltage\n");
 	return ret;
 }
 
@@ -1184,89 +1196,29 @@
 	return IRQ_HANDLED;
 }
 
-static int omap_hsmmc_get_dma_sync_dev(struct omap_hsmmc_host *host,
-				     struct mmc_data *data)
-{
-	int sync_dev;
-
-	if (data->flags & MMC_DATA_WRITE)
-		sync_dev = host->dma_line_tx;
-	else
-		sync_dev = host->dma_line_rx;
-	return sync_dev;
-}
-
-static void omap_hsmmc_config_dma_params(struct omap_hsmmc_host *host,
-				       struct mmc_data *data,
-				       struct scatterlist *sgl)
-{
-	int blksz, nblk, dma_ch;
-
-	dma_ch = host->dma_ch;
-	if (data->flags & MMC_DATA_WRITE) {
-		omap_set_dma_dest_params(dma_ch, 0, OMAP_DMA_AMODE_CONSTANT,
-			(host->mapbase + OMAP_HSMMC_DATA), 0, 0);
-		omap_set_dma_src_params(dma_ch, 0, OMAP_DMA_AMODE_POST_INC,
-			sg_dma_address(sgl), 0, 0);
-	} else {
-		omap_set_dma_src_params(dma_ch, 0, OMAP_DMA_AMODE_CONSTANT,
-			(host->mapbase + OMAP_HSMMC_DATA), 0, 0);
-		omap_set_dma_dest_params(dma_ch, 0, OMAP_DMA_AMODE_POST_INC,
-			sg_dma_address(sgl), 0, 0);
-	}
-
-	blksz = host->data->blksz;
-	nblk = sg_dma_len(sgl) / blksz;
-
-	omap_set_dma_transfer_params(dma_ch, OMAP_DMA_DATA_TYPE_S32,
-			blksz / 4, nblk, OMAP_DMA_SYNC_FRAME,
-			omap_hsmmc_get_dma_sync_dev(host, data),
-			!(data->flags & MMC_DATA_WRITE));
-
-	omap_start_dma(dma_ch);
-}
-
-/*
- * DMA call back function
- */
-static void omap_hsmmc_dma_cb(int lch, u16 ch_status, void *cb_data)
+static void omap_hsmmc_dma_callback(void *param)
 {
-	struct omap_hsmmc_host *host = cb_data;
+	struct omap_hsmmc_host *host = param;
+	struct dma_chan *chan;
 	struct mmc_data *data;
-	int dma_ch, req_in_progress;
+	int req_in_progress;
 
-	if (!(ch_status & OMAP_DMA_BLOCK_IRQ)) {
-		dev_warn(mmc_dev(host->mmc), "unexpected dma status %x\n",
-			ch_status);
-		return;
-	}
-
-	spin_lock(&host->irq_lock);
+	spin_lock_irq(&host->irq_lock);
 	if (host->dma_ch < 0) {
-		spin_unlock(&host->irq_lock);
+		spin_unlock_irq(&host->irq_lock);
 		return;
 	}
 
 	data = host->mrq->data;
-	host->dma_sg_idx++;
-	if (host->dma_sg_idx < host->dma_len) {
-		/* Fire up the next transfer. */
-		omap_hsmmc_config_dma_params(host, data,
-					   data->sg + host->dma_sg_idx);
-		spin_unlock(&host->irq_lock);
-		return;
-	}
-
+	chan = omap_hsmmc_get_dma_chan(host, data);
 	if (!data->host_cookie)
-		dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len,
+		dma_unmap_sg(chan->device->dev,
+			     data->sg, data->sg_len,
 			     omap_hsmmc_get_dma_dir(host, data));
 
 	req_in_progress = host->req_in_progress;
-	dma_ch = host->dma_ch;
 	host->dma_ch = -1;
-	spin_unlock(&host->irq_lock);
-
-	omap_free_dma(dma_ch);
+	spin_unlock_irq(&host->irq_lock);
 
 	/* If DMA has finished after TC, complete the request */
 	if (!req_in_progress) {
@@ -1279,7 +1231,8 @@
 
 static int omap_hsmmc_pre_dma_transfer(struct omap_hsmmc_host *host,
 				       struct mmc_data *data,
-				       struct omap_hsmmc_next *next)
+				       struct omap_hsmmc_next *next,
+				       struct dma_chan *chan)
 {
 	int dma_len;
 
@@ -1294,8 +1247,7 @@
 	/* Check if next job is already prepared */
 	if (next ||
 	    (!next && data->host_cookie != host->next_data.cookie)) {
-		dma_len = dma_map_sg(mmc_dev(host->mmc), data->sg,
-				     data->sg_len,
+		dma_len = dma_map_sg(chan->device->dev, data->sg, data->sg_len,
 				     omap_hsmmc_get_dma_dir(host, data));
 
 	} else {
@@ -1322,8 +1274,11 @@
 static int omap_hsmmc_start_dma_transfer(struct omap_hsmmc_host *host,
 					struct mmc_request *req)
 {
-	int dma_ch = 0, ret = 0, i;
+	struct dma_slave_config cfg;
+	struct dma_async_tx_descriptor *tx;
+	int ret = 0, i;
 	struct mmc_data *data = req->data;
+	struct dma_chan *chan;
 
 	/* Sanity check: all the SG entries must be aligned by block size. */
 	for (i = 0; i < data->sg_len; i++) {
@@ -1341,22 +1296,41 @@
 
 	BUG_ON(host->dma_ch != -1);
 
-	ret = omap_request_dma(omap_hsmmc_get_dma_sync_dev(host, data),
-			       "MMC/SD", omap_hsmmc_dma_cb, host, &dma_ch);
-	if (ret != 0) {
-		dev_err(mmc_dev(host->mmc),
-			"%s: omap_request_dma() failed with %d\n",
-			mmc_hostname(host->mmc), ret);
+	chan = omap_hsmmc_get_dma_chan(host, data);
+
+	cfg.src_addr = host->mapbase + OMAP_HSMMC_DATA;
+	cfg.dst_addr = host->mapbase + OMAP_HSMMC_DATA;
+	cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+	cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+	cfg.src_maxburst = data->blksz / 4;
+	cfg.dst_maxburst = data->blksz / 4;
+
+	ret = dmaengine_slave_config(chan, &cfg);
+	if (ret)
 		return ret;
-	}
-	ret = omap_hsmmc_pre_dma_transfer(host, data, NULL);
+
+	ret = omap_hsmmc_pre_dma_transfer(host, data, NULL, chan);
 	if (ret)
 		return ret;
 
-	host->dma_ch = dma_ch;
-	host->dma_sg_idx = 0;
+	tx = dmaengine_prep_slave_sg(chan, data->sg, data->sg_len,
+		data->flags & MMC_DATA_WRITE ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM,
+		DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+	if (!tx) {
+		dev_err(mmc_dev(host->mmc), "prep_slave_sg() failed\n");
+		/* FIXME: cleanup */
+		return -1;
+	}
+
+	tx->callback = omap_hsmmc_dma_callback;
+	tx->callback_param = host;
+
+	/* Does not fail */
+	dmaengine_submit(tx);
 
-	omap_hsmmc_config_dma_params(host, data, data->sg);
+	host->dma_ch = 1;
+
+	dma_async_issue_pending(chan);
 
 	return 0;
 }
@@ -1425,7 +1399,7 @@
 	if (host->use_dma) {
 		ret = omap_hsmmc_start_dma_transfer(host, req);
 		if (ret != 0) {
-			dev_dbg(mmc_dev(host->mmc), "MMC start dma failure\n");
+			dev_err(mmc_dev(host->mmc), "MMC start dma failure\n");
 			return ret;
 		}
 	}
@@ -1438,11 +1412,11 @@
 	struct omap_hsmmc_host *host = mmc_priv(mmc);
 	struct mmc_data *data = mrq->data;
 
-	if (host->use_dma) {
-		if (data->host_cookie)
-			dma_unmap_sg(mmc_dev(host->mmc), data->sg,
-				     data->sg_len,
-				     omap_hsmmc_get_dma_dir(host, data));
+	if (host->use_dma && data->host_cookie) {
+		struct dma_chan *c = omap_hsmmc_get_dma_chan(host, data);
+
+		dma_unmap_sg(c->device->dev, data->sg, data->sg_len,
+			     omap_hsmmc_get_dma_dir(host, data));
 		data->host_cookie = 0;
 	}
 }
@@ -1457,10 +1431,13 @@
 		return ;
 	}
 
-	if (host->use_dma)
+	if (host->use_dma) {
+		struct dma_chan *c = omap_hsmmc_get_dma_chan(host, mrq->data);
+
 		if (omap_hsmmc_pre_dma_transfer(host, mrq->data,
-						&host->next_data))
+						&host->next_data, c))
 			mrq->data->host_cookie = 0;
+	}
 }
 
 /*
@@ -1520,12 +1497,10 @@
 		case MMC_POWER_OFF:
 			mmc_slot(host).set_power(host->dev, host->slot_id,
 						 0, 0);
-			host->vdd = 0;
 			break;
 		case MMC_POWER_UP:
 			mmc_slot(host).set_power(host->dev, host->slot_id,
 						 1, ios->vdd);
-			host->vdd = ios->vdd;
 			break;
 		case MMC_POWER_ON:
 			do_send_init_stream = 1;
@@ -1546,10 +1521,10 @@
 			(ios->vdd == DUAL_VOLT_OCR_BIT) &&
 			/*
 			 * With pbias cell programming missing, this
-			 * can't be allowed when booting with device
+			 * can't be allowed on MMC1 when booting with device
 			 * tree.
 			 */
-			!host->dev->of_node) {
+			!host->pbias_disable) {
 				/*
 				 * The mmc_select_voltage fn of the core does
 				 * not seem to set the power_mode to
@@ -1617,10 +1592,6 @@
 	value = OMAP_HSMMC_READ(host->base, CAPA);
 	OMAP_HSMMC_WRITE(host->base, CAPA, value | capa);
 
-	/* Set the controller to AUTO IDLE mode */
-	value = OMAP_HSMMC_READ(host->base, SYSCONFIG);
-	OMAP_HSMMC_WRITE(host->base, SYSCONFIG, value | AUTOIDLE);
-
 	/* Set SD bus power bit */
 	set_sd_bus_power(host);
 }
@@ -1678,8 +1649,6 @@
 
 	pm_runtime_get_sync(host->dev);
 
-	seq_printf(s, "SYSCONFIG:\t0x%08x\n",
-			OMAP_HSMMC_READ(host->base, SYSCONFIG));
 	seq_printf(s, "CON:\t\t0x%08x\n",
 			OMAP_HSMMC_READ(host->base, CON));
 	seq_printf(s, "HCTL:\t\t0x%08x\n",
@@ -1748,7 +1717,13 @@
 {
 	struct omap_mmc_platform_data *pdata;
 	struct device_node *np = dev->of_node;
-	u32 bus_width;
+	u32 bus_width, max_freq;
+	int cd_gpio, wp_gpio;
+
+	cd_gpio = of_get_named_gpio(np, "cd-gpios", 0);
+	wp_gpio = of_get_named_gpio(np, "wp-gpios", 0);
+	if (cd_gpio == -EPROBE_DEFER || wp_gpio == -EPROBE_DEFER)
+		return ERR_PTR(-EPROBE_DEFER);
 
 	pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
 	if (!pdata)
@@ -1759,14 +1734,14 @@
 
 	/* This driver only supports 1 slot */
 	pdata->nr_slots = 1;
-	pdata->slots[0].switch_pin = of_get_named_gpio(np, "cd-gpios", 0);
-	pdata->slots[0].gpio_wp = of_get_named_gpio(np, "wp-gpios", 0);
+	pdata->slots[0].switch_pin = cd_gpio;
+	pdata->slots[0].gpio_wp = wp_gpio;
 
 	if (of_find_property(np, "ti,non-removable", NULL)) {
 		pdata->slots[0].nonremovable = true;
 		pdata->slots[0].no_regulator_off_init = true;
 	}
-	of_property_read_u32(np, "ti,bus-width", &bus_width);
+	of_property_read_u32(np, "bus-width", &bus_width);
 	if (bus_width == 4)
 		pdata->slots[0].caps |= MMC_CAP_4_BIT_DATA;
 	else if (bus_width == 8)
@@ -1775,6 +1750,12 @@
 	if (of_find_property(np, "ti,needs-special-reset", NULL))
 		pdata->slots[0].features |= HSMMC_HAS_UPDATED_RESET;
 
+	if (!of_property_read_u32(np, "max-frequency", &max_freq))
+		pdata->max_freq = max_freq;
+
+	if (of_find_property(np, "ti,needs-special-hs-handling", NULL))
+		pdata->slots[0].features |= HSMMC_HAS_HSPE_SUPPORT;
+
 	return pdata;
 }
 #else
@@ -1785,7 +1766,7 @@
 }
 #endif
 
-static int __devinit omap_hsmmc_probe(struct platform_device *pdev)
+static int omap_hsmmc_probe(struct platform_device *pdev)
 {
 	struct omap_mmc_platform_data *pdata = pdev->dev.platform_data;
 	struct mmc_host *mmc;
@@ -1793,12 +1774,19 @@
 	struct resource *res;
 	int ret, irq;
 	const struct of_device_id *match;
+	dma_cap_mask_t mask;
+	unsigned tx_req, rx_req;
+	struct pinctrl *pinctrl;
 
 	match = of_match_device(of_match_ptr(omap_mmc_of_match), &pdev->dev);
 	if (match) {
 		pdata = of_get_hsmmc_pdata(&pdev->dev);
+
+		if (IS_ERR(pdata))
+			return PTR_ERR(pdata);
+
 		if (match->data) {
-			u16 *offsetp = match->data;
+			const u16 *offsetp = match->data;
 			pdata->reg_offset = *offsetp;
 		}
 	}
@@ -1837,13 +1825,12 @@
 	host->pdata	= pdata;
 	host->dev	= &pdev->dev;
 	host->use_dma	= 1;
-	host->dev->dma_mask = &pdata->dma_mask;
 	host->dma_ch	= -1;
 	host->irq	= irq;
 	host->slot_id	= 0;
 	host->mapbase	= res->start + pdata->reg_offset;
 	host->base	= ioremap(host->mapbase, SZ_4K);
-	host->power_mode = -1;
+	host->power_mode = MMC_POWER_OFF;
 	host->next_data.cookie = 1;
 
 	platform_set_drvdata(pdev, host);
@@ -1885,21 +1872,20 @@
 
 	omap_hsmmc_context_save(host);
 
-	if (cpu_is_omap2430()) {
-		host->dbclk = clk_get(&pdev->dev, "mmchsdb_fck");
-		/*
-		 * MMC can still work without debounce clock.
-		 */
-		if (IS_ERR(host->dbclk))
-			dev_warn(mmc_dev(host->mmc),
-				"Failed to get debounce clock\n");
-		else
-			host->got_dbclk = 1;
+	/* This can be removed once we support PBIAS with DT */
+	if (host->dev->of_node && host->mapbase == 0x4809c000)
+		host->pbias_disable = 1;
 
-		if (host->got_dbclk)
-			if (clk_enable(host->dbclk) != 0)
-				dev_dbg(mmc_dev(host->mmc), "Enabling debounce"
-							" clk failed\n");
+	host->dbclk = clk_get(&pdev->dev, "mmchsdb_fck");
+	/*
+	 * MMC can still work without debounce clock.
+	 */
+	if (IS_ERR(host->dbclk)) {
+		host->dbclk = NULL;
+	} else if (clk_prepare_enable(host->dbclk) != 0) {
+		dev_warn(mmc_dev(host->mmc), "Failed to enable debounce clk\n");
+		clk_put(host->dbclk);
+		host->dbclk = NULL;
 	}
 
 	/* Since we do only SG emulation, we can have as many segs
@@ -1925,31 +1911,58 @@
 
 	omap_hsmmc_conf_bus_power(host);
 
-	res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx");
-	if (!res) {
-		dev_err(mmc_dev(host->mmc), "cannot get DMA TX channel\n");
+	if (!pdev->dev.of_node) {
+		res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx");
+		if (!res) {
+			dev_err(mmc_dev(host->mmc), "cannot get DMA TX channel\n");
+			ret = -ENXIO;
+			goto err_irq;
+		}
+		tx_req = res->start;
+
+		res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx");
+		if (!res) {
+			dev_err(mmc_dev(host->mmc), "cannot get DMA RX channel\n");
+			ret = -ENXIO;
+			goto err_irq;
+		}
+		rx_req = res->start;
+	}
+
+	dma_cap_zero(mask);
+	dma_cap_set(DMA_SLAVE, mask);
+
+	host->rx_chan =
+		dma_request_slave_channel_compat(mask, omap_dma_filter_fn,
+						 &rx_req, &pdev->dev, "rx");
+
+	if (!host->rx_chan) {
+		dev_err(mmc_dev(host->mmc), "unable to obtain RX DMA engine channel %u\n", rx_req);
+		ret = -ENXIO;
 		goto err_irq;
 	}
-	host->dma_line_tx = res->start;
 
-	res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx");
-	if (!res) {
-		dev_err(mmc_dev(host->mmc), "cannot get DMA RX channel\n");
+	host->tx_chan =
+		dma_request_slave_channel_compat(mask, omap_dma_filter_fn,
+						 &tx_req, &pdev->dev, "tx");
+
+	if (!host->tx_chan) {
+		dev_err(mmc_dev(host->mmc), "unable to obtain TX DMA engine channel %u\n", tx_req);
+		ret = -ENXIO;
 		goto err_irq;
 	}
-	host->dma_line_rx = res->start;
 
 	/* Request IRQ for MMC operations */
 	ret = request_irq(host->irq, omap_hsmmc_irq, 0,
 			mmc_hostname(mmc), host);
 	if (ret) {
-		dev_dbg(mmc_dev(host->mmc), "Unable to grab HSMMC IRQ\n");
+		dev_err(mmc_dev(host->mmc), "Unable to grab HSMMC IRQ\n");
 		goto err_irq;
 	}
 
 	if (pdata->init != NULL) {
 		if (pdata->init(&pdev->dev) != 0) {
-			dev_dbg(mmc_dev(host->mmc),
+			dev_err(mmc_dev(host->mmc),
 				"Unable to configure MMC IRQs\n");
 			goto err_irq_cd_init;
 		}
@@ -1969,10 +1982,10 @@
 		ret = request_threaded_irq(mmc_slot(host).card_detect_irq,
 					   NULL,
 					   omap_hsmmc_detect,
-					   IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+					   IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
 					   mmc_hostname(mmc), host);
 		if (ret) {
-			dev_dbg(mmc_dev(host->mmc),
+			dev_err(mmc_dev(host->mmc),
 				"Unable to grab MMC CD IRQ\n");
 			goto err_irq_cd;
 		}
@@ -1982,6 +1995,11 @@
 
 	omap_hsmmc_disable_irq(host);
 
+	pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
+	if (IS_ERR(pinctrl))
+		dev_warn(&pdev->dev,
+			"pins are not configured from the driver\n");
+
 	omap_hsmmc_protect_card(host);
 
 	mmc_add_host(mmc);
@@ -2016,11 +2034,15 @@
 err_irq_cd_init:
 	free_irq(host->irq, host);
 err_irq:
+	if (host->tx_chan)
+		dma_release_channel(host->tx_chan);
+	if (host->rx_chan)
+		dma_release_channel(host->rx_chan);
 	pm_runtime_put_sync(host->dev);
 	pm_runtime_disable(host->dev);
 	clk_put(host->fclk);
-	if (host->got_dbclk) {
-		clk_disable(host->dbclk);
+	if (host->dbclk) {
+		clk_disable_unprepare(host->dbclk);
 		clk_put(host->dbclk);
 	}
 err1:
@@ -2030,11 +2052,13 @@
 err_alloc:
 	omap_hsmmc_gpio_free(pdata);
 err:
-	release_mem_region(res->start, resource_size(res));
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (res)
+		release_mem_region(res->start, resource_size(res));
 	return ret;
 }
 
-static int __devexit omap_hsmmc_remove(struct platform_device *pdev)
+static int omap_hsmmc_remove(struct platform_device *pdev)
 {
 	struct omap_hsmmc_host *host = platform_get_drvdata(pdev);
 	struct resource *res;
@@ -2049,17 +2073,22 @@
 	if (mmc_slot(host).card_detect_irq)
 		free_irq(mmc_slot(host).card_detect_irq, host);
 
+	if (host->tx_chan)
+		dma_release_channel(host->tx_chan);
+	if (host->rx_chan)
+		dma_release_channel(host->rx_chan);
+
 	pm_runtime_put_sync(host->dev);
 	pm_runtime_disable(host->dev);
 	clk_put(host->fclk);
-	if (host->got_dbclk) {
-		clk_disable(host->dbclk);
+	if (host->dbclk) {
+		clk_disable_unprepare(host->dbclk);
 		clk_put(host->dbclk);
 	}
 
-	mmc_free_host(host->mmc);
+	omap_hsmmc_gpio_free(host->pdata);
 	iounmap(host->base);
-	omap_hsmmc_gpio_free(pdev->dev.platform_data);
+	mmc_free_host(host->mmc);
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (res)
@@ -2070,6 +2099,25 @@
 }
 
 #ifdef CONFIG_PM
+static int omap_hsmmc_prepare(struct device *dev)
+{
+	struct omap_hsmmc_host *host = dev_get_drvdata(dev);
+
+	if (host->pdata->suspend)
+		return host->pdata->suspend(dev, host->slot_id);
+
+	return 0;
+}
+
+static void omap_hsmmc_complete(struct device *dev)
+{
+	struct omap_hsmmc_host *host = dev_get_drvdata(dev);
+
+	if (host->pdata->resume)
+		host->pdata->resume(dev, host->slot_id);
+
+}
+
 static int omap_hsmmc_suspend(struct device *dev)
 {
 	int ret = 0;
@@ -2083,24 +2131,10 @@
 
 	pm_runtime_get_sync(host->dev);
 	host->suspended = 1;
-	if (host->pdata->suspend) {
-		ret = host->pdata->suspend(dev, host->slot_id);
-		if (ret) {
-			dev_dbg(dev, "Unable to handle MMC board"
-					" level suspend\n");
-			host->suspended = 0;
-			return ret;
-		}
-	}
 	ret = mmc_suspend_host(host->mmc);
 
 	if (ret) {
 		host->suspended = 0;
-		if (host->pdata->resume) {
-			ret = host->pdata->resume(dev, host->slot_id);
-			if (ret)
-				dev_dbg(dev, "Unmask interrupt failed\n");
-		}
 		goto err;
 	}
 
@@ -2110,8 +2144,8 @@
 				OMAP_HSMMC_READ(host->base, HCTL) & ~SDBP);
 	}
 
-	if (host->got_dbclk)
-		clk_disable(host->dbclk);
+	if (host->dbclk)
+		clk_disable_unprepare(host->dbclk);
 err:
 	pm_runtime_put_sync(host->dev);
 	return ret;
@@ -2131,18 +2165,12 @@
 
 	pm_runtime_get_sync(host->dev);
 
-	if (host->got_dbclk)
-		clk_enable(host->dbclk);
+	if (host->dbclk)
+		clk_prepare_enable(host->dbclk);
 
 	if (!(host->mmc->pm_flags & MMC_PM_KEEP_POWER))
 		omap_hsmmc_conf_bus_power(host);
 
-	if (host->pdata->resume) {
-		ret = host->pdata->resume(dev, host->slot_id);
-		if (ret)
-			dev_dbg(dev, "Unmask interrupt failed\n");
-	}
-
 	omap_hsmmc_protect_card(host);
 
 	/* Notify the core to resume the host */
@@ -2158,8 +2186,10 @@
 }
 
 #else
+#define omap_hsmmc_prepare	NULL
+#define omap_hsmmc_complete	NULL
 #define omap_hsmmc_suspend	NULL
-#define omap_hsmmc_resume		NULL
+#define omap_hsmmc_resume	NULL
 #endif
 
 static int omap_hsmmc_runtime_suspend(struct device *dev)
@@ -2187,13 +2217,15 @@
 static struct dev_pm_ops omap_hsmmc_dev_pm_ops = {
 	.suspend	= omap_hsmmc_suspend,
 	.resume		= omap_hsmmc_resume,
+	.prepare	= omap_hsmmc_prepare,
+	.complete	= omap_hsmmc_complete,
 	.runtime_suspend = omap_hsmmc_runtime_suspend,
 	.runtime_resume = omap_hsmmc_runtime_resume,
 };
 
 static struct platform_driver omap_hsmmc_driver = {
 	.probe		= omap_hsmmc_probe,
-	.remove		= __devexit_p(omap_hsmmc_remove),
+	.remove		= omap_hsmmc_remove,
 	.driver		= {
 		.name = DRIVER_NAME,
 		.owner = THIS_MODULE,
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/pxamci.c linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/pxamci.c
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/pxamci.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/pxamci.c	2014-09-12 15:59:37.348052000 +0800
@@ -30,12 +30,15 @@
 #include <linux/regulator/consumer.h>
 #include <linux/gpio.h>
 #include <linux/gfp.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+#include <linux/of_device.h>
 
 #include <asm/sizes.h>
 
 #include <mach/hardware.h>
 #include <mach/dma.h>
-#include <mach/mmc.h>
+#include <linux/platform_data/mmc-pxamci.h>
 
 #include "pxamci.h"
 
@@ -573,6 +576,50 @@
 	return IRQ_HANDLED;
 }
 
+#ifdef CONFIG_OF
+static const struct of_device_id pxa_mmc_dt_ids[] = {
+        { .compatible = "marvell,pxa-mmc" },
+        { }
+};
+
+MODULE_DEVICE_TABLE(of, pxa_mmc_dt_ids);
+
+static int pxamci_of_init(struct platform_device *pdev)
+{
+        struct device_node *np = pdev->dev.of_node;
+        struct pxamci_platform_data *pdata;
+        u32 tmp;
+
+        if (!np)
+                return 0;
+
+        pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+        if (!pdata)
+                return -ENOMEM;
+
+	pdata->gpio_card_detect =
+		of_get_named_gpio(np, "cd-gpios", 0);
+	pdata->gpio_card_ro =
+		of_get_named_gpio(np, "wp-gpios", 0);
+
+	/* pxa-mmc specific */
+	pdata->gpio_power =
+		of_get_named_gpio(np, "pxa-mmc,gpio-power", 0);
+
+	if (of_property_read_u32(np, "pxa-mmc,detect-delay-ms", &tmp) == 0)
+		pdata->detect_delay_ms = tmp;
+
+        pdev->dev.platform_data = pdata;
+
+        return 0;
+}
+#else
+static int pxamci_of_init(struct platform_device *pdev)
+{
+        return 0;
+}
+#endif
+
 static int pxamci_probe(struct platform_device *pdev)
 {
 	struct mmc_host *mmc;
@@ -580,6 +627,10 @@
 	struct resource *r, *dmarx, *dmatx;
 	int ret, irq, gpio_cd = -1, gpio_ro = -1, gpio_power = -1;
 
+	ret = pxamci_of_init(pdev);
+	if (ret)
+		return ret;
+
 	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	irq = platform_get_irq(pdev, 0);
 	if (!r || irq < 0)
@@ -866,6 +917,7 @@
 	.driver		= {
 		.name	= DRIVER_NAME,
 		.owner	= THIS_MODULE,
+		.of_match_table = of_match_ptr(pxa_mmc_dt_ids),
 #ifdef CONFIG_PM
 		.pm	= &pxamci_pm_ops,
 #endif
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/rtsx_pci_sdmmc.c linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/rtsx_pci_sdmmc.c
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/rtsx_pci_sdmmc.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/rtsx_pci_sdmmc.c	2014-09-12 15:59:37.348052000 +0800
@@ -0,0 +1,1351 @@
+/* Realtek PCI-Express SD/MMC Card Interface driver
+ *
+ * Copyright(c) 2009 Realtek Semiconductor Corp. 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 as published by the
+ * Free Software Foundation; either version 2, 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author:
+ *   Wei WANG <wei_wang@realsil.com.cn>
+ *   No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/highmem.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/mmc.h>
+#include <linux/mmc/sd.h>
+#include <linux/mmc/card.h>
+#include <linux/mfd/rtsx_pci.h>
+#include <asm/unaligned.h>
+
+/* SD Tuning Data Structure
+ * Record continuous timing phase path
+ */
+struct timing_phase_path {
+	int start;
+	int end;
+	int mid;
+	int len;
+};
+
+struct realtek_pci_sdmmc {
+	struct platform_device	*pdev;
+	struct rtsx_pcr		*pcr;
+	struct mmc_host		*mmc;
+	struct mmc_request	*mrq;
+
+	struct mutex		host_mutex;
+
+	u8			ssc_depth;
+	unsigned int		clock;
+	bool			vpclk;
+	bool			double_clk;
+	bool			eject;
+	bool			initial_mode;
+	bool			ddr_mode;
+	int			power_state;
+#define SDMMC_POWER_ON		1
+#define SDMMC_POWER_OFF		0
+};
+
+static inline struct device *sdmmc_dev(struct realtek_pci_sdmmc *host)
+{
+	return &(host->pdev->dev);
+}
+
+static inline void sd_clear_error(struct realtek_pci_sdmmc *host)
+{
+	rtsx_pci_write_register(host->pcr, CARD_STOP,
+			SD_STOP | SD_CLR_ERR, SD_STOP | SD_CLR_ERR);
+}
+
+#ifdef DEBUG
+static void sd_print_debug_regs(struct realtek_pci_sdmmc *host)
+{
+	struct rtsx_pcr *pcr = host->pcr;
+	u16 i;
+	u8 *ptr;
+
+	/* Print SD host internal registers */
+	rtsx_pci_init_cmd(pcr);
+	for (i = 0xFDA0; i <= 0xFDAE; i++)
+		rtsx_pci_add_cmd(pcr, READ_REG_CMD, i, 0, 0);
+	for (i = 0xFD52; i <= 0xFD69; i++)
+		rtsx_pci_add_cmd(pcr, READ_REG_CMD, i, 0, 0);
+	rtsx_pci_send_cmd(pcr, 100);
+
+	ptr = rtsx_pci_get_cmd_data(pcr);
+	for (i = 0xFDA0; i <= 0xFDAE; i++)
+		dev_dbg(sdmmc_dev(host), "0x%04X: 0x%02x\n", i, *(ptr++));
+	for (i = 0xFD52; i <= 0xFD69; i++)
+		dev_dbg(sdmmc_dev(host), "0x%04X: 0x%02x\n", i, *(ptr++));
+}
+#else
+#define sd_print_debug_regs(host)
+#endif /* DEBUG */
+
+static int sd_read_data(struct realtek_pci_sdmmc *host, u8 *cmd, u16 byte_cnt,
+		u8 *buf, int buf_len, int timeout)
+{
+	struct rtsx_pcr *pcr = host->pcr;
+	int err, i;
+	u8 trans_mode;
+
+	dev_dbg(sdmmc_dev(host), "%s: SD/MMC CMD%d\n", __func__, cmd[0] - 0x40);
+
+	if (!buf)
+		buf_len = 0;
+
+	if ((cmd[0] & 0x3F) == MMC_SEND_TUNING_BLOCK)
+		trans_mode = SD_TM_AUTO_TUNING;
+	else
+		trans_mode = SD_TM_NORMAL_READ;
+
+	rtsx_pci_init_cmd(pcr);
+
+	for (i = 0; i < 5; i++)
+		rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CMD0 + i, 0xFF, cmd[i]);
+
+	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BYTE_CNT_L, 0xFF, (u8)byte_cnt);
+	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BYTE_CNT_H,
+			0xFF, (u8)(byte_cnt >> 8));
+	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BLOCK_CNT_L, 0xFF, 1);
+	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BLOCK_CNT_H, 0xFF, 0);
+
+	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CFG2, 0xFF,
+			SD_CALCULATE_CRC7 | SD_CHECK_CRC16 |
+			SD_NO_WAIT_BUSY_END | SD_CHECK_CRC7 | SD_RSP_LEN_6);
+	if (trans_mode != SD_TM_AUTO_TUNING)
+		rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
+				CARD_DATA_SOURCE, 0x01, PINGPONG_BUFFER);
+
+	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_TRANSFER,
+			0xFF, trans_mode | SD_TRANSFER_START);
+	rtsx_pci_add_cmd(pcr, CHECK_REG_CMD, SD_TRANSFER,
+			SD_TRANSFER_END, SD_TRANSFER_END);
+
+	err = rtsx_pci_send_cmd(pcr, timeout);
+	if (err < 0) {
+		sd_print_debug_regs(host);
+		dev_dbg(sdmmc_dev(host),
+			"rtsx_pci_send_cmd fail (err = %d)\n", err);
+		return err;
+	}
+
+	if (buf && buf_len) {
+		err = rtsx_pci_read_ppbuf(pcr, buf, buf_len);
+		if (err < 0) {
+			dev_dbg(sdmmc_dev(host),
+				"rtsx_pci_read_ppbuf fail (err = %d)\n", err);
+			return err;
+		}
+	}
+
+	return 0;
+}
+
+static int sd_write_data(struct realtek_pci_sdmmc *host, u8 *cmd, u16 byte_cnt,
+		u8 *buf, int buf_len, int timeout)
+{
+	struct rtsx_pcr *pcr = host->pcr;
+	int err, i;
+	u8 trans_mode;
+
+	if (!buf)
+		buf_len = 0;
+
+	if (buf && buf_len) {
+		err = rtsx_pci_write_ppbuf(pcr, buf, buf_len);
+		if (err < 0) {
+			dev_dbg(sdmmc_dev(host),
+				"rtsx_pci_write_ppbuf fail (err = %d)\n", err);
+			return err;
+		}
+	}
+
+	trans_mode = cmd ? SD_TM_AUTO_WRITE_2 : SD_TM_AUTO_WRITE_3;
+	rtsx_pci_init_cmd(pcr);
+
+	if (cmd) {
+		dev_dbg(sdmmc_dev(host), "%s: SD/MMC CMD %d\n", __func__,
+				cmd[0] - 0x40);
+
+		for (i = 0; i < 5; i++)
+			rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
+					SD_CMD0 + i, 0xFF, cmd[i]);
+	}
+
+	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BYTE_CNT_L, 0xFF, (u8)byte_cnt);
+	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BYTE_CNT_H,
+			0xFF, (u8)(byte_cnt >> 8));
+	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BLOCK_CNT_L, 0xFF, 1);
+	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BLOCK_CNT_H, 0xFF, 0);
+
+	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CFG2, 0xFF,
+		SD_CALCULATE_CRC7 | SD_CHECK_CRC16 |
+		SD_NO_WAIT_BUSY_END | SD_CHECK_CRC7 | SD_RSP_LEN_6);
+
+	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_TRANSFER, 0xFF,
+			trans_mode | SD_TRANSFER_START);
+	rtsx_pci_add_cmd(pcr, CHECK_REG_CMD, SD_TRANSFER,
+			SD_TRANSFER_END, SD_TRANSFER_END);
+
+	err = rtsx_pci_send_cmd(pcr, timeout);
+	if (err < 0) {
+		sd_print_debug_regs(host);
+		dev_dbg(sdmmc_dev(host),
+			"rtsx_pci_send_cmd fail (err = %d)\n", err);
+		return err;
+	}
+
+	return 0;
+}
+
+static void sd_send_cmd_get_rsp(struct realtek_pci_sdmmc *host,
+		struct mmc_command *cmd)
+{
+	struct rtsx_pcr *pcr = host->pcr;
+	u8 cmd_idx = (u8)cmd->opcode;
+	u32 arg = cmd->arg;
+	int err = 0;
+	int timeout = 100;
+	int i;
+	u8 *ptr;
+	int stat_idx = 0;
+	u8 rsp_type;
+	int rsp_len = 5;
+
+	dev_dbg(sdmmc_dev(host), "%s: SD/MMC CMD %d, arg = 0x%08x\n",
+			__func__, cmd_idx, arg);
+
+	/* Response type:
+	 * R0
+	 * R1, R5, R6, R7
+	 * R1b
+	 * R2
+	 * R3, R4
+	 */
+	switch (mmc_resp_type(cmd)) {
+	case MMC_RSP_NONE:
+		rsp_type = SD_RSP_TYPE_R0;
+		rsp_len = 0;
+		break;
+	case MMC_RSP_R1:
+		rsp_type = SD_RSP_TYPE_R1;
+		break;
+	case MMC_RSP_R1B:
+		rsp_type = SD_RSP_TYPE_R1b;
+		break;
+	case MMC_RSP_R2:
+		rsp_type = SD_RSP_TYPE_R2;
+		rsp_len = 16;
+		break;
+	case MMC_RSP_R3:
+		rsp_type = SD_RSP_TYPE_R3;
+		break;
+	default:
+		dev_dbg(sdmmc_dev(host), "cmd->flag is not valid\n");
+		err = -EINVAL;
+		goto out;
+	}
+
+	if (rsp_type == SD_RSP_TYPE_R1b)
+		timeout = 3000;
+
+	if (cmd->opcode == SD_SWITCH_VOLTAGE) {
+		err = rtsx_pci_write_register(pcr, SD_BUS_STAT,
+				0xFF, SD_CLK_TOGGLE_EN);
+		if (err < 0)
+			goto out;
+	}
+
+	rtsx_pci_init_cmd(pcr);
+
+	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CMD0, 0xFF, 0x40 | cmd_idx);
+	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CMD1, 0xFF, (u8)(arg >> 24));
+	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CMD2, 0xFF, (u8)(arg >> 16));
+	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CMD3, 0xFF, (u8)(arg >> 8));
+	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CMD4, 0xFF, (u8)arg);
+
+	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CFG2, 0xFF, rsp_type);
+	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_DATA_SOURCE,
+			0x01, PINGPONG_BUFFER);
+	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_TRANSFER,
+			0xFF, SD_TM_CMD_RSP | SD_TRANSFER_START);
+	rtsx_pci_add_cmd(pcr, CHECK_REG_CMD, SD_TRANSFER,
+		     SD_TRANSFER_END | SD_STAT_IDLE,
+		     SD_TRANSFER_END | SD_STAT_IDLE);
+
+	if (rsp_type == SD_RSP_TYPE_R2) {
+		/* Read data from ping-pong buffer */
+		for (i = PPBUF_BASE2; i < PPBUF_BASE2 + 16; i++)
+			rtsx_pci_add_cmd(pcr, READ_REG_CMD, (u16)i, 0, 0);
+		stat_idx = 16;
+	} else if (rsp_type != SD_RSP_TYPE_R0) {
+		/* Read data from SD_CMDx registers */
+		for (i = SD_CMD0; i <= SD_CMD4; i++)
+			rtsx_pci_add_cmd(pcr, READ_REG_CMD, (u16)i, 0, 0);
+		stat_idx = 5;
+	}
+
+	rtsx_pci_add_cmd(pcr, READ_REG_CMD, SD_STAT1, 0, 0);
+
+	err = rtsx_pci_send_cmd(pcr, timeout);
+	if (err < 0) {
+		sd_print_debug_regs(host);
+		sd_clear_error(host);
+		dev_dbg(sdmmc_dev(host),
+			"rtsx_pci_send_cmd error (err = %d)\n", err);
+		goto out;
+	}
+
+	if (rsp_type == SD_RSP_TYPE_R0) {
+		err = 0;
+		goto out;
+	}
+
+	/* Eliminate returned value of CHECK_REG_CMD */
+	ptr = rtsx_pci_get_cmd_data(pcr) + 1;
+
+	/* Check (Start,Transmission) bit of Response */
+	if ((ptr[0] & 0xC0) != 0) {
+		err = -EILSEQ;
+		dev_dbg(sdmmc_dev(host), "Invalid response bit\n");
+		goto out;
+	}
+
+	/* Check CRC7 */
+	if (!(rsp_type & SD_NO_CHECK_CRC7)) {
+		if (ptr[stat_idx] & SD_CRC7_ERR) {
+			err = -EILSEQ;
+			dev_dbg(sdmmc_dev(host), "CRC7 error\n");
+			goto out;
+		}
+	}
+
+	if (rsp_type == SD_RSP_TYPE_R2) {
+		for (i = 0; i < 4; i++) {
+			cmd->resp[i] = get_unaligned_be32(ptr + 1 + i * 4);
+			dev_dbg(sdmmc_dev(host), "cmd->resp[%d] = 0x%08x\n",
+					i, cmd->resp[i]);
+		}
+	} else {
+		cmd->resp[0] = get_unaligned_be32(ptr + 1);
+		dev_dbg(sdmmc_dev(host), "cmd->resp[0] = 0x%08x\n",
+				cmd->resp[0]);
+	}
+
+out:
+	cmd->error = err;
+}
+
+static int sd_rw_multi(struct realtek_pci_sdmmc *host, struct mmc_request *mrq)
+{
+	struct rtsx_pcr *pcr = host->pcr;
+	struct mmc_host *mmc = host->mmc;
+	struct mmc_card *card = mmc->card;
+	struct mmc_data *data = mrq->data;
+	int uhs = mmc_sd_card_uhs(card);
+	int read = (data->flags & MMC_DATA_READ) ? 1 : 0;
+	u8 cfg2, trans_mode;
+	int err;
+	size_t data_len = data->blksz * data->blocks;
+
+	if (read) {
+		cfg2 = SD_CALCULATE_CRC7 | SD_CHECK_CRC16 |
+			SD_NO_WAIT_BUSY_END | SD_CHECK_CRC7 | SD_RSP_LEN_0;
+		trans_mode = SD_TM_AUTO_READ_3;
+	} else {
+		cfg2 = SD_NO_CALCULATE_CRC7 | SD_CHECK_CRC16 |
+			SD_NO_WAIT_BUSY_END | SD_NO_CHECK_CRC7 | SD_RSP_LEN_0;
+		trans_mode = SD_TM_AUTO_WRITE_3;
+	}
+
+	if (!uhs)
+		cfg2 |= SD_NO_CHECK_WAIT_CRC_TO;
+
+	rtsx_pci_init_cmd(pcr);
+
+	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BYTE_CNT_L, 0xFF, 0x00);
+	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BYTE_CNT_H, 0xFF, 0x02);
+	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BLOCK_CNT_L,
+			0xFF, (u8)data->blocks);
+	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BLOCK_CNT_H,
+			0xFF, (u8)(data->blocks >> 8));
+
+	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, IRQSTAT0,
+			DMA_DONE_INT, DMA_DONE_INT);
+	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMATC3,
+			0xFF, (u8)(data_len >> 24));
+	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMATC2,
+			0xFF, (u8)(data_len >> 16));
+	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMATC1,
+			0xFF, (u8)(data_len >> 8));
+	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMATC0, 0xFF, (u8)data_len);
+	if (read) {
+		rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMACTL,
+				0x03 | DMA_PACK_SIZE_MASK,
+				DMA_DIR_FROM_CARD | DMA_EN | DMA_512);
+	} else {
+		rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMACTL,
+				0x03 | DMA_PACK_SIZE_MASK,
+				DMA_DIR_TO_CARD | DMA_EN | DMA_512);
+	}
+
+	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_DATA_SOURCE,
+			0x01, RING_BUFFER);
+
+	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CFG2, 0xFF, cfg2);
+	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_TRANSFER, 0xFF,
+			trans_mode | SD_TRANSFER_START);
+	rtsx_pci_add_cmd(pcr, CHECK_REG_CMD, SD_TRANSFER,
+			SD_TRANSFER_END, SD_TRANSFER_END);
+
+	rtsx_pci_send_cmd_no_wait(pcr);
+
+	err = rtsx_pci_transfer_data(pcr, data->sg, data->sg_len, read, 10000);
+	if (err < 0) {
+		sd_clear_error(host);
+		return err;
+	}
+
+	return 0;
+}
+
+static inline void sd_enable_initial_mode(struct realtek_pci_sdmmc *host)
+{
+	rtsx_pci_write_register(host->pcr, SD_CFG1,
+			SD_CLK_DIVIDE_MASK, SD_CLK_DIVIDE_128);
+}
+
+static inline void sd_disable_initial_mode(struct realtek_pci_sdmmc *host)
+{
+	rtsx_pci_write_register(host->pcr, SD_CFG1,
+			SD_CLK_DIVIDE_MASK, SD_CLK_DIVIDE_0);
+}
+
+static void sd_normal_rw(struct realtek_pci_sdmmc *host,
+		struct mmc_request *mrq)
+{
+	struct mmc_command *cmd = mrq->cmd;
+	struct mmc_data *data = mrq->data;
+	u8 _cmd[5], *buf;
+
+	_cmd[0] = 0x40 | (u8)cmd->opcode;
+	put_unaligned_be32(cmd->arg, (u32 *)(&_cmd[1]));
+
+	buf = kzalloc(data->blksz, GFP_NOIO);
+	if (!buf) {
+		cmd->error = -ENOMEM;
+		return;
+	}
+
+	if (data->flags & MMC_DATA_READ) {
+		if (host->initial_mode)
+			sd_disable_initial_mode(host);
+
+		cmd->error = sd_read_data(host, _cmd, (u16)data->blksz, buf,
+				data->blksz, 200);
+
+		if (host->initial_mode)
+			sd_enable_initial_mode(host);
+
+		sg_copy_from_buffer(data->sg, data->sg_len, buf, data->blksz);
+	} else {
+		sg_copy_to_buffer(data->sg, data->sg_len, buf, data->blksz);
+
+		cmd->error = sd_write_data(host, _cmd, (u16)data->blksz, buf,
+				data->blksz, 200);
+	}
+
+	kfree(buf);
+}
+
+static int sd_change_phase(struct realtek_pci_sdmmc *host, u8 sample_point)
+{
+	struct rtsx_pcr *pcr = host->pcr;
+	int err;
+
+	dev_dbg(sdmmc_dev(host), "%s: sample_point = %d\n",
+			__func__, sample_point);
+
+	rtsx_pci_init_cmd(pcr);
+
+	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CLK_CTL, CHANGE_CLK, CHANGE_CLK);
+	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_VPRX_CTL, 0x1F, sample_point);
+	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_VPCLK0_CTL, PHASE_NOT_RESET, 0);
+	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_VPCLK0_CTL,
+			PHASE_NOT_RESET, PHASE_NOT_RESET);
+	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CLK_CTL, CHANGE_CLK, 0);
+	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CFG1, SD_ASYNC_FIFO_NOT_RST, 0);
+
+	err = rtsx_pci_send_cmd(pcr, 100);
+	if (err < 0)
+		return err;
+
+	return 0;
+}
+
+static u8 sd_search_final_phase(struct realtek_pci_sdmmc *host, u32 phase_map)
+{
+	struct timing_phase_path path[MAX_PHASE + 1];
+	int i, j, cont_path_cnt;
+	int new_block, max_len, final_path_idx;
+	u8 final_phase = 0xFF;
+
+	/* Parse phase_map, take it as a bit-ring */
+	cont_path_cnt = 0;
+	new_block = 1;
+	j = 0;
+	for (i = 0; i < MAX_PHASE + 1; i++) {
+		if (phase_map & (1 << i)) {
+			if (new_block) {
+				new_block = 0;
+				j = cont_path_cnt++;
+				path[j].start = i;
+				path[j].end = i;
+			} else {
+				path[j].end = i;
+			}
+		} else {
+			new_block = 1;
+			if (cont_path_cnt) {
+				/* Calculate path length and middle point */
+				int idx = cont_path_cnt - 1;
+				path[idx].len =
+					path[idx].end - path[idx].start + 1;
+				path[idx].mid =
+					path[idx].start + path[idx].len / 2;
+			}
+		}
+	}
+
+	if (cont_path_cnt == 0) {
+		dev_dbg(sdmmc_dev(host), "No continuous phase path\n");
+		goto finish;
+	} else {
+		/* Calculate last continuous path length and middle point */
+		int idx = cont_path_cnt - 1;
+		path[idx].len = path[idx].end - path[idx].start + 1;
+		path[idx].mid = path[idx].start + path[idx].len / 2;
+	}
+
+	/* Connect the first and last continuous paths if they are adjacent */
+	if (!path[0].start && (path[cont_path_cnt - 1].end == MAX_PHASE)) {
+		/* Using negative index */
+		path[0].start = path[cont_path_cnt - 1].start - MAX_PHASE - 1;
+		path[0].len += path[cont_path_cnt - 1].len;
+		path[0].mid = path[0].start + path[0].len / 2;
+		/* Convert negative middle point index to positive one */
+		if (path[0].mid < 0)
+			path[0].mid += MAX_PHASE + 1;
+		cont_path_cnt--;
+	}
+
+	/* Choose the longest continuous phase path */
+	max_len = 0;
+	final_phase = 0;
+	final_path_idx = 0;
+	for (i = 0; i < cont_path_cnt; i++) {
+		if (path[i].len > max_len) {
+			max_len = path[i].len;
+			final_phase = (u8)path[i].mid;
+			final_path_idx = i;
+		}
+
+		dev_dbg(sdmmc_dev(host), "path[%d].start = %d\n",
+				i, path[i].start);
+		dev_dbg(sdmmc_dev(host), "path[%d].end = %d\n",
+				i, path[i].end);
+		dev_dbg(sdmmc_dev(host), "path[%d].len = %d\n",
+				i, path[i].len);
+		dev_dbg(sdmmc_dev(host), "path[%d].mid = %d\n",
+				i, path[i].mid);
+	}
+
+finish:
+	dev_dbg(sdmmc_dev(host), "Final chosen phase: %d\n", final_phase);
+	return final_phase;
+}
+
+static void sd_wait_data_idle(struct realtek_pci_sdmmc *host)
+{
+	int err, i;
+	u8 val = 0;
+
+	for (i = 0; i < 100; i++) {
+		err = rtsx_pci_read_register(host->pcr, SD_DATA_STATE, &val);
+		if (val & SD_DATA_IDLE)
+			return;
+
+		udelay(100);
+	}
+}
+
+static int sd_tuning_rx_cmd(struct realtek_pci_sdmmc *host,
+		u8 opcode, u8 sample_point)
+{
+	int err;
+	u8 cmd[5] = {0};
+
+	err = sd_change_phase(host, sample_point);
+	if (err < 0)
+		return err;
+
+	cmd[0] = 0x40 | opcode;
+	err = sd_read_data(host, cmd, 0x40, NULL, 0, 100);
+	if (err < 0) {
+		/* Wait till SD DATA IDLE */
+		sd_wait_data_idle(host);
+		sd_clear_error(host);
+		return err;
+	}
+
+	return 0;
+}
+
+static int sd_tuning_phase(struct realtek_pci_sdmmc *host,
+		u8 opcode, u32 *phase_map)
+{
+	int err, i;
+	u32 raw_phase_map = 0;
+
+	for (i = MAX_PHASE; i >= 0; i--) {
+		err = sd_tuning_rx_cmd(host, opcode, (u8)i);
+		if (err == 0)
+			raw_phase_map |= 1 << i;
+	}
+
+	if (phase_map)
+		*phase_map = raw_phase_map;
+
+	return 0;
+}
+
+static int sd_tuning_rx(struct realtek_pci_sdmmc *host, u8 opcode)
+{
+	int err, i;
+	u32 raw_phase_map[RX_TUNING_CNT] = {0}, phase_map;
+	u8 final_phase;
+
+	for (i = 0; i < RX_TUNING_CNT; i++) {
+		err = sd_tuning_phase(host, opcode, &(raw_phase_map[i]));
+		if (err < 0)
+			return err;
+
+		if (raw_phase_map[i] == 0)
+			break;
+	}
+
+	phase_map = 0xFFFFFFFF;
+	for (i = 0; i < RX_TUNING_CNT; i++) {
+		dev_dbg(sdmmc_dev(host), "RX raw_phase_map[%d] = 0x%08x\n",
+				i, raw_phase_map[i]);
+		phase_map &= raw_phase_map[i];
+	}
+	dev_dbg(sdmmc_dev(host), "RX phase_map = 0x%08x\n", phase_map);
+
+	if (phase_map) {
+		final_phase = sd_search_final_phase(host, phase_map);
+		if (final_phase == 0xFF)
+			return -EINVAL;
+
+		err = sd_change_phase(host, final_phase);
+		if (err < 0)
+			return err;
+	} else {
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static void sdmmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
+{
+	struct realtek_pci_sdmmc *host = mmc_priv(mmc);
+	struct rtsx_pcr *pcr = host->pcr;
+	struct mmc_command *cmd = mrq->cmd;
+	struct mmc_data *data = mrq->data;
+	unsigned int data_size = 0;
+	int err;
+
+	if (host->eject) {
+		cmd->error = -ENOMEDIUM;
+		goto finish;
+	}
+
+	err = rtsx_pci_card_exclusive_check(host->pcr, RTSX_SD_CARD);
+	if (err) {
+		cmd->error = err;
+		goto finish;
+	}
+
+	mutex_lock(&pcr->pcr_mutex);
+
+	rtsx_pci_start_run(pcr);
+
+	rtsx_pci_switch_clock(pcr, host->clock, host->ssc_depth,
+			host->initial_mode, host->double_clk, host->vpclk);
+	rtsx_pci_write_register(pcr, CARD_SELECT, 0x07, SD_MOD_SEL);
+	rtsx_pci_write_register(pcr, CARD_SHARE_MODE,
+			CARD_SHARE_MASK, CARD_SHARE_48_SD);
+
+	mutex_lock(&host->host_mutex);
+	host->mrq = mrq;
+	mutex_unlock(&host->host_mutex);
+
+	if (mrq->data)
+		data_size = data->blocks * data->blksz;
+
+	if (!data_size || mmc_op_multi(cmd->opcode) ||
+			(cmd->opcode == MMC_READ_SINGLE_BLOCK) ||
+			(cmd->opcode == MMC_WRITE_BLOCK)) {
+		sd_send_cmd_get_rsp(host, cmd);
+
+		if (!cmd->error && data_size) {
+			sd_rw_multi(host, mrq);
+
+			if (mmc_op_multi(cmd->opcode) && mrq->stop)
+				sd_send_cmd_get_rsp(host, mrq->stop);
+		}
+	} else {
+		sd_normal_rw(host, mrq);
+	}
+
+	if (mrq->data) {
+		if (cmd->error || data->error)
+			data->bytes_xfered = 0;
+		else
+			data->bytes_xfered = data->blocks * data->blksz;
+	}
+
+	mutex_unlock(&pcr->pcr_mutex);
+
+finish:
+	if (cmd->error)
+		dev_dbg(sdmmc_dev(host), "cmd->error = %d\n", cmd->error);
+
+	mutex_lock(&host->host_mutex);
+	host->mrq = NULL;
+	mutex_unlock(&host->host_mutex);
+
+	mmc_request_done(mmc, mrq);
+}
+
+static int sd_set_bus_width(struct realtek_pci_sdmmc *host,
+		unsigned char bus_width)
+{
+	int err = 0;
+	u8 width[] = {
+		[MMC_BUS_WIDTH_1] = SD_BUS_WIDTH_1BIT,
+		[MMC_BUS_WIDTH_4] = SD_BUS_WIDTH_4BIT,
+		[MMC_BUS_WIDTH_8] = SD_BUS_WIDTH_8BIT,
+	};
+
+	if (bus_width <= MMC_BUS_WIDTH_8)
+		err = rtsx_pci_write_register(host->pcr, SD_CFG1,
+				0x03, width[bus_width]);
+
+	return err;
+}
+
+static int sd_power_on(struct realtek_pci_sdmmc *host)
+{
+	struct rtsx_pcr *pcr = host->pcr;
+	int err;
+
+	if (host->power_state == SDMMC_POWER_ON)
+		return 0;
+
+	rtsx_pci_init_cmd(pcr);
+	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_SELECT, 0x07, SD_MOD_SEL);
+	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_SHARE_MODE,
+			CARD_SHARE_MASK, CARD_SHARE_48_SD);
+	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_CLK_EN,
+			SD_CLK_EN, SD_CLK_EN);
+	err = rtsx_pci_send_cmd(pcr, 100);
+	if (err < 0)
+		return err;
+
+	err = rtsx_pci_card_pull_ctl_enable(pcr, RTSX_SD_CARD);
+	if (err < 0)
+		return err;
+
+	err = rtsx_pci_card_power_on(pcr, RTSX_SD_CARD);
+	if (err < 0)
+		return err;
+
+	err = rtsx_pci_write_register(pcr, CARD_OE, SD_OUTPUT_EN, SD_OUTPUT_EN);
+	if (err < 0)
+		return err;
+
+	host->power_state = SDMMC_POWER_ON;
+	return 0;
+}
+
+static int sd_power_off(struct realtek_pci_sdmmc *host)
+{
+	struct rtsx_pcr *pcr = host->pcr;
+	int err;
+
+	host->power_state = SDMMC_POWER_OFF;
+
+	rtsx_pci_init_cmd(pcr);
+
+	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_CLK_EN, SD_CLK_EN, 0);
+	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_OE, SD_OUTPUT_EN, 0);
+
+	err = rtsx_pci_send_cmd(pcr, 100);
+	if (err < 0)
+		return err;
+
+	err = rtsx_pci_card_power_off(pcr, RTSX_SD_CARD);
+	if (err < 0)
+		return err;
+
+	return rtsx_pci_card_pull_ctl_disable(pcr, RTSX_SD_CARD);
+}
+
+static int sd_set_power_mode(struct realtek_pci_sdmmc *host,
+		unsigned char power_mode)
+{
+	int err;
+
+	if (power_mode == MMC_POWER_OFF)
+		err = sd_power_off(host);
+	else
+		err = sd_power_on(host);
+
+	return err;
+}
+
+static int sd_set_timing(struct realtek_pci_sdmmc *host,
+		unsigned char timing, bool *ddr_mode)
+{
+	struct rtsx_pcr *pcr = host->pcr;
+	int err = 0;
+
+	*ddr_mode = false;
+
+	rtsx_pci_init_cmd(pcr);
+
+	switch (timing) {
+	case MMC_TIMING_UHS_SDR104:
+	case MMC_TIMING_UHS_SDR50:
+		rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CFG1,
+				0x0C | SD_ASYNC_FIFO_NOT_RST,
+				SD_30_MODE | SD_ASYNC_FIFO_NOT_RST);
+		rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CLK_CTL,
+				CLK_LOW_FREQ, CLK_LOW_FREQ);
+		rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_CLK_SOURCE, 0xFF,
+				CRC_VAR_CLK0 | SD30_FIX_CLK | SAMPLE_VAR_CLK1);
+		rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CLK_CTL, CLK_LOW_FREQ, 0);
+		break;
+
+	case MMC_TIMING_UHS_DDR50:
+		*ddr_mode = true;
+
+		rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CFG1,
+				0x0C | SD_ASYNC_FIFO_NOT_RST,
+				SD_DDR_MODE | SD_ASYNC_FIFO_NOT_RST);
+		rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CLK_CTL,
+				CLK_LOW_FREQ, CLK_LOW_FREQ);
+		rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_CLK_SOURCE, 0xFF,
+				CRC_VAR_CLK0 | SD30_FIX_CLK | SAMPLE_VAR_CLK1);
+		rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CLK_CTL, CLK_LOW_FREQ, 0);
+		rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_PUSH_POINT_CTL,
+				DDR_VAR_TX_CMD_DAT, DDR_VAR_TX_CMD_DAT);
+		rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_SAMPLE_POINT_CTL,
+				DDR_VAR_RX_DAT | DDR_VAR_RX_CMD,
+				DDR_VAR_RX_DAT | DDR_VAR_RX_CMD);
+		break;
+
+	case MMC_TIMING_MMC_HS:
+	case MMC_TIMING_SD_HS:
+		rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CFG1,
+				0x0C, SD_20_MODE);
+		rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CLK_CTL,
+				CLK_LOW_FREQ, CLK_LOW_FREQ);
+		rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_CLK_SOURCE, 0xFF,
+				CRC_FIX_CLK | SD30_VAR_CLK0 | SAMPLE_VAR_CLK1);
+		rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CLK_CTL, CLK_LOW_FREQ, 0);
+		rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_PUSH_POINT_CTL,
+				SD20_TX_SEL_MASK, SD20_TX_14_AHEAD);
+		rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_SAMPLE_POINT_CTL,
+				SD20_RX_SEL_MASK, SD20_RX_14_DELAY);
+		break;
+
+	default:
+		rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
+				SD_CFG1, 0x0C, SD_20_MODE);
+		rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CLK_CTL,
+				CLK_LOW_FREQ, CLK_LOW_FREQ);
+		rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_CLK_SOURCE, 0xFF,
+				CRC_FIX_CLK | SD30_VAR_CLK0 | SAMPLE_VAR_CLK1);
+		rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CLK_CTL, CLK_LOW_FREQ, 0);
+		rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
+				SD_PUSH_POINT_CTL, 0xFF, 0);
+		rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_SAMPLE_POINT_CTL,
+				SD20_RX_SEL_MASK, SD20_RX_POS_EDGE);
+		break;
+	}
+
+	err = rtsx_pci_send_cmd(pcr, 100);
+
+	return err;
+}
+
+static void sdmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+{
+	struct realtek_pci_sdmmc *host = mmc_priv(mmc);
+	struct rtsx_pcr *pcr = host->pcr;
+
+	if (host->eject)
+		return;
+
+	if (rtsx_pci_card_exclusive_check(host->pcr, RTSX_SD_CARD))
+		return;
+
+	mutex_lock(&pcr->pcr_mutex);
+
+	rtsx_pci_start_run(pcr);
+
+	sd_set_bus_width(host, ios->bus_width);
+	sd_set_power_mode(host, ios->power_mode);
+	sd_set_timing(host, ios->timing, &host->ddr_mode);
+
+	host->vpclk = false;
+	host->double_clk = true;
+
+	switch (ios->timing) {
+	case MMC_TIMING_UHS_SDR104:
+	case MMC_TIMING_UHS_SDR50:
+		host->ssc_depth = RTSX_SSC_DEPTH_2M;
+		host->vpclk = true;
+		host->double_clk = false;
+		break;
+	case MMC_TIMING_UHS_DDR50:
+	case MMC_TIMING_UHS_SDR25:
+		host->ssc_depth = RTSX_SSC_DEPTH_1M;
+		break;
+	default:
+		host->ssc_depth = RTSX_SSC_DEPTH_500K;
+		break;
+	}
+
+	host->initial_mode = (ios->clock <= 1000000) ? true : false;
+
+	host->clock = ios->clock;
+	rtsx_pci_switch_clock(pcr, ios->clock, host->ssc_depth,
+			host->initial_mode, host->double_clk, host->vpclk);
+
+	mutex_unlock(&pcr->pcr_mutex);
+}
+
+static int sdmmc_get_ro(struct mmc_host *mmc)
+{
+	struct realtek_pci_sdmmc *host = mmc_priv(mmc);
+	struct rtsx_pcr *pcr = host->pcr;
+	int ro = 0;
+	u32 val;
+
+	if (host->eject)
+		return -ENOMEDIUM;
+
+	mutex_lock(&pcr->pcr_mutex);
+
+	rtsx_pci_start_run(pcr);
+
+	/* Check SD mechanical write-protect switch */
+	val = rtsx_pci_readl(pcr, RTSX_BIPR);
+	dev_dbg(sdmmc_dev(host), "%s: RTSX_BIPR = 0x%08x\n", __func__, val);
+	if (val & SD_WRITE_PROTECT)
+		ro = 1;
+
+	mutex_unlock(&pcr->pcr_mutex);
+
+	return ro;
+}
+
+static int sdmmc_get_cd(struct mmc_host *mmc)
+{
+	struct realtek_pci_sdmmc *host = mmc_priv(mmc);
+	struct rtsx_pcr *pcr = host->pcr;
+	int cd = 0;
+	u32 val;
+
+	if (host->eject)
+		return -ENOMEDIUM;
+
+	mutex_lock(&pcr->pcr_mutex);
+
+	rtsx_pci_start_run(pcr);
+
+	/* Check SD card detect */
+	val = rtsx_pci_card_exist(pcr);
+	dev_dbg(sdmmc_dev(host), "%s: RTSX_BIPR = 0x%08x\n", __func__, val);
+	if (val & SD_EXIST)
+		cd = 1;
+
+	mutex_unlock(&pcr->pcr_mutex);
+
+	return cd;
+}
+
+static int sd_wait_voltage_stable_1(struct realtek_pci_sdmmc *host)
+{
+	struct rtsx_pcr *pcr = host->pcr;
+	int err;
+	u8 stat;
+
+	/* Reference to Signal Voltage Switch Sequence in SD spec.
+	 * Wait for a period of time so that the card can drive SD_CMD and
+	 * SD_DAT[3:0] to low after sending back CMD11 response.
+	 */
+	mdelay(1);
+
+	/* SD_CMD, SD_DAT[3:0] should be driven to low by card;
+	 * If either one of SD_CMD,SD_DAT[3:0] is not low,
+	 * abort the voltage switch sequence;
+	 */
+	err = rtsx_pci_read_register(pcr, SD_BUS_STAT, &stat);
+	if (err < 0)
+		return err;
+
+	if (stat & (SD_CMD_STATUS | SD_DAT3_STATUS | SD_DAT2_STATUS |
+				SD_DAT1_STATUS | SD_DAT0_STATUS))
+		return -EINVAL;
+
+	/* Stop toggle SD clock */
+	err = rtsx_pci_write_register(pcr, SD_BUS_STAT,
+			0xFF, SD_CLK_FORCE_STOP);
+	if (err < 0)
+		return err;
+
+	return 0;
+}
+
+static int sd_wait_voltage_stable_2(struct realtek_pci_sdmmc *host)
+{
+	struct rtsx_pcr *pcr = host->pcr;
+	int err;
+	u8 stat, mask, val;
+
+	/* Wait 1.8V output of voltage regulator in card stable */
+	msleep(50);
+
+	/* Toggle SD clock again */
+	err = rtsx_pci_write_register(pcr, SD_BUS_STAT, 0xFF, SD_CLK_TOGGLE_EN);
+	if (err < 0)
+		return err;
+
+	/* Wait for a period of time so that the card can drive
+	 * SD_DAT[3:0] to high at 1.8V
+	 */
+	msleep(20);
+
+	/* SD_CMD, SD_DAT[3:0] should be pulled high by host */
+	err = rtsx_pci_read_register(pcr, SD_BUS_STAT, &stat);
+	if (err < 0)
+		return err;
+
+	mask = SD_CMD_STATUS | SD_DAT3_STATUS | SD_DAT2_STATUS |
+		SD_DAT1_STATUS | SD_DAT0_STATUS;
+	val = SD_CMD_STATUS | SD_DAT3_STATUS | SD_DAT2_STATUS |
+		SD_DAT1_STATUS | SD_DAT0_STATUS;
+	if ((stat & mask) != val) {
+		dev_dbg(sdmmc_dev(host),
+			"%s: SD_BUS_STAT = 0x%x\n", __func__, stat);
+		rtsx_pci_write_register(pcr, SD_BUS_STAT,
+				SD_CLK_TOGGLE_EN | SD_CLK_FORCE_STOP, 0);
+		rtsx_pci_write_register(pcr, CARD_CLK_EN, 0xFF, 0);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int sdmmc_switch_voltage(struct mmc_host *mmc, struct mmc_ios *ios)
+{
+	struct realtek_pci_sdmmc *host = mmc_priv(mmc);
+	struct rtsx_pcr *pcr = host->pcr;
+	int err = 0;
+	u8 voltage;
+
+	dev_dbg(sdmmc_dev(host), "%s: signal_voltage = %d\n",
+			__func__, ios->signal_voltage);
+
+	if (host->eject)
+		return -ENOMEDIUM;
+
+	err = rtsx_pci_card_exclusive_check(host->pcr, RTSX_SD_CARD);
+	if (err)
+		return err;
+
+	mutex_lock(&pcr->pcr_mutex);
+
+	rtsx_pci_start_run(pcr);
+
+	if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_330)
+		voltage = OUTPUT_3V3;
+	else
+		voltage = OUTPUT_1V8;
+
+	if (voltage == OUTPUT_1V8) {
+		err = sd_wait_voltage_stable_1(host);
+		if (err < 0)
+			goto out;
+	}
+
+	err = rtsx_pci_switch_output_voltage(pcr, voltage);
+	if (err < 0)
+		goto out;
+
+	if (voltage == OUTPUT_1V8) {
+		err = sd_wait_voltage_stable_2(host);
+		if (err < 0)
+			goto out;
+	}
+
+	/* Stop toggle SD clock in idle */
+	err = rtsx_pci_write_register(pcr, SD_BUS_STAT,
+			SD_CLK_TOGGLE_EN | SD_CLK_FORCE_STOP, 0);
+
+out:
+	mutex_unlock(&pcr->pcr_mutex);
+
+	return err;
+}
+
+static int sdmmc_execute_tuning(struct mmc_host *mmc, u32 opcode)
+{
+	struct realtek_pci_sdmmc *host = mmc_priv(mmc);
+	struct rtsx_pcr *pcr = host->pcr;
+	int err = 0;
+
+	if (host->eject)
+		return -ENOMEDIUM;
+
+	err = rtsx_pci_card_exclusive_check(host->pcr, RTSX_SD_CARD);
+	if (err)
+		return err;
+
+	mutex_lock(&pcr->pcr_mutex);
+
+	rtsx_pci_start_run(pcr);
+
+	if (!host->ddr_mode)
+		err = sd_tuning_rx(host, MMC_SEND_TUNING_BLOCK);
+
+	mutex_unlock(&pcr->pcr_mutex);
+
+	return err;
+}
+
+static const struct mmc_host_ops realtek_pci_sdmmc_ops = {
+	.request = sdmmc_request,
+	.set_ios = sdmmc_set_ios,
+	.get_ro = sdmmc_get_ro,
+	.get_cd = sdmmc_get_cd,
+	.start_signal_voltage_switch = sdmmc_switch_voltage,
+	.execute_tuning = sdmmc_execute_tuning,
+};
+
+#ifdef CONFIG_PM
+static int rtsx_pci_sdmmc_suspend(struct platform_device *pdev,
+		pm_message_t state)
+{
+	struct realtek_pci_sdmmc *host = platform_get_drvdata(pdev);
+	struct mmc_host *mmc = host->mmc;
+	int err;
+
+	dev_dbg(sdmmc_dev(host), "--> %s\n", __func__);
+
+	err = mmc_suspend_host(mmc);
+	if (err)
+		return err;
+
+	return 0;
+}
+
+static int rtsx_pci_sdmmc_resume(struct platform_device *pdev)
+{
+	struct realtek_pci_sdmmc *host = platform_get_drvdata(pdev);
+	struct mmc_host *mmc = host->mmc;
+
+	dev_dbg(sdmmc_dev(host), "--> %s\n", __func__);
+
+	return mmc_resume_host(mmc);
+}
+#else /* CONFIG_PM */
+#define rtsx_pci_sdmmc_suspend NULL
+#define rtsx_pci_sdmmc_resume NULL
+#endif /* CONFIG_PM */
+
+static void init_extra_caps(struct realtek_pci_sdmmc *host)
+{
+	struct mmc_host *mmc = host->mmc;
+	struct rtsx_pcr *pcr = host->pcr;
+
+	dev_dbg(sdmmc_dev(host), "pcr->extra_caps = 0x%x\n", pcr->extra_caps);
+
+	if (pcr->extra_caps & EXTRA_CAPS_SD_SDR50)
+		mmc->caps |= MMC_CAP_UHS_SDR50;
+	if (pcr->extra_caps & EXTRA_CAPS_SD_SDR104)
+		mmc->caps |= MMC_CAP_UHS_SDR104;
+	if (pcr->extra_caps & EXTRA_CAPS_SD_DDR50)
+		mmc->caps |= MMC_CAP_UHS_DDR50;
+	if (pcr->extra_caps & EXTRA_CAPS_MMC_HSDDR)
+		mmc->caps |= MMC_CAP_1_8V_DDR;
+	if (pcr->extra_caps & EXTRA_CAPS_MMC_8BIT)
+		mmc->caps |= MMC_CAP_8_BIT_DATA;
+}
+
+static void realtek_init_host(struct realtek_pci_sdmmc *host)
+{
+	struct mmc_host *mmc = host->mmc;
+
+	mmc->f_min = 250000;
+	mmc->f_max = 208000000;
+	mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
+	mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SD_HIGHSPEED |
+		MMC_CAP_MMC_HIGHSPEED | MMC_CAP_BUS_WIDTH_TEST |
+		MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25;
+	mmc->max_current_330 = 400;
+	mmc->max_current_180 = 800;
+	mmc->ops = &realtek_pci_sdmmc_ops;
+
+	init_extra_caps(host);
+
+	mmc->max_segs = 256;
+	mmc->max_seg_size = 65536;
+	mmc->max_blk_size = 512;
+	mmc->max_blk_count = 65535;
+	mmc->max_req_size = 524288;
+}
+
+static void rtsx_pci_sdmmc_card_event(struct platform_device *pdev)
+{
+	struct realtek_pci_sdmmc *host = platform_get_drvdata(pdev);
+
+	mmc_detect_change(host->mmc, 0);
+}
+
+static int rtsx_pci_sdmmc_drv_probe(struct platform_device *pdev)
+{
+	struct mmc_host *mmc;
+	struct realtek_pci_sdmmc *host;
+	struct rtsx_pcr *pcr;
+	struct pcr_handle *handle = pdev->dev.platform_data;
+
+	if (!handle)
+		return -ENXIO;
+
+	pcr = handle->pcr;
+	if (!pcr)
+		return -ENXIO;
+
+	dev_dbg(&(pdev->dev), ": Realtek PCI-E SDMMC controller found\n");
+
+	mmc = mmc_alloc_host(sizeof(*host), &pdev->dev);
+	if (!mmc)
+		return -ENOMEM;
+
+	host = mmc_priv(mmc);
+	host->pcr = pcr;
+	host->mmc = mmc;
+	host->pdev = pdev;
+	host->power_state = SDMMC_POWER_OFF;
+	platform_set_drvdata(pdev, host);
+	pcr->slots[RTSX_SD_CARD].p_dev = pdev;
+	pcr->slots[RTSX_SD_CARD].card_event = rtsx_pci_sdmmc_card_event;
+
+	mutex_init(&host->host_mutex);
+
+	realtek_init_host(host);
+
+	mmc_add_host(mmc);
+
+	return 0;
+}
+
+static int rtsx_pci_sdmmc_drv_remove(struct platform_device *pdev)
+{
+	struct realtek_pci_sdmmc *host = platform_get_drvdata(pdev);
+	struct rtsx_pcr *pcr;
+	struct mmc_host *mmc;
+
+	if (!host)
+		return 0;
+
+	pcr = host->pcr;
+	pcr->slots[RTSX_SD_CARD].p_dev = NULL;
+	pcr->slots[RTSX_SD_CARD].card_event = NULL;
+	mmc = host->mmc;
+	host->eject = true;
+
+	mutex_lock(&host->host_mutex);
+	if (host->mrq) {
+		dev_dbg(&(pdev->dev),
+			"%s: Controller removed during transfer\n",
+			mmc_hostname(mmc));
+
+		rtsx_pci_complete_unfinished_transfer(pcr);
+
+		host->mrq->cmd->error = -ENOMEDIUM;
+		if (host->mrq->stop)
+			host->mrq->stop->error = -ENOMEDIUM;
+		mmc_request_done(mmc, host->mrq);
+	}
+	mutex_unlock(&host->host_mutex);
+
+	mmc_remove_host(mmc);
+	mmc_free_host(mmc);
+
+	platform_set_drvdata(pdev, NULL);
+
+	dev_dbg(&(pdev->dev),
+		": Realtek PCI-E SDMMC controller has been removed\n");
+
+	return 0;
+}
+
+static struct platform_device_id rtsx_pci_sdmmc_ids[] = {
+	{
+		.name = DRV_NAME_RTSX_PCI_SDMMC,
+	}, {
+		/* sentinel */
+	}
+};
+MODULE_DEVICE_TABLE(platform, rtsx_pci_sdmmc_ids);
+
+static struct platform_driver rtsx_pci_sdmmc_driver = {
+	.probe		= rtsx_pci_sdmmc_drv_probe,
+	.remove		= rtsx_pci_sdmmc_drv_remove,
+	.id_table       = rtsx_pci_sdmmc_ids,
+	.suspend	= rtsx_pci_sdmmc_suspend,
+	.resume		= rtsx_pci_sdmmc_resume,
+	.driver		= {
+		.owner	= THIS_MODULE,
+		.name	= DRV_NAME_RTSX_PCI_SDMMC,
+	},
+};
+module_platform_driver(rtsx_pci_sdmmc_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Wei WANG <wei_wang@realsil.com.cn>");
+MODULE_DESCRIPTION("Realtek PCI-E SD/MMC Card Host Driver");
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/s3cmci.c linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/s3cmci.c
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/s3cmci.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/s3cmci.c	2014-09-12 15:59:37.348052000 +0800
@@ -25,15 +25,93 @@
 
 #include <mach/dma.h>
 
-#include <mach/regs-sdi.h>
-#include <mach/regs-gpio.h>
-
-#include <plat/mci.h>
+#include <linux/platform_data/mmc-s3cmci.h>
 
 #include "s3cmci.h"
 
 #define DRIVER_NAME "s3c-mci"
 
+#define S3C2410_SDICON			(0x00)
+#define S3C2410_SDIPRE			(0x04)
+#define S3C2410_SDICMDARG		(0x08)
+#define S3C2410_SDICMDCON		(0x0C)
+#define S3C2410_SDICMDSTAT		(0x10)
+#define S3C2410_SDIRSP0			(0x14)
+#define S3C2410_SDIRSP1			(0x18)
+#define S3C2410_SDIRSP2			(0x1C)
+#define S3C2410_SDIRSP3			(0x20)
+#define S3C2410_SDITIMER		(0x24)
+#define S3C2410_SDIBSIZE		(0x28)
+#define S3C2410_SDIDCON			(0x2C)
+#define S3C2410_SDIDCNT			(0x30)
+#define S3C2410_SDIDSTA			(0x34)
+#define S3C2410_SDIFSTA			(0x38)
+
+#define S3C2410_SDIDATA			(0x3C)
+#define S3C2410_SDIIMSK			(0x40)
+
+#define S3C2440_SDIDATA			(0x40)
+#define S3C2440_SDIIMSK			(0x3C)
+
+#define S3C2440_SDICON_SDRESET		(1 << 8)
+#define S3C2410_SDICON_SDIOIRQ		(1 << 3)
+#define S3C2410_SDICON_FIFORESET	(1 << 1)
+#define S3C2410_SDICON_CLOCKTYPE	(1 << 0)
+
+#define S3C2410_SDICMDCON_LONGRSP	(1 << 10)
+#define S3C2410_SDICMDCON_WAITRSP	(1 << 9)
+#define S3C2410_SDICMDCON_CMDSTART	(1 << 8)
+#define S3C2410_SDICMDCON_SENDERHOST	(1 << 6)
+#define S3C2410_SDICMDCON_INDEX		(0x3f)
+
+#define S3C2410_SDICMDSTAT_CRCFAIL	(1 << 12)
+#define S3C2410_SDICMDSTAT_CMDSENT	(1 << 11)
+#define S3C2410_SDICMDSTAT_CMDTIMEOUT	(1 << 10)
+#define S3C2410_SDICMDSTAT_RSPFIN	(1 << 9)
+
+#define S3C2440_SDIDCON_DS_WORD		(2 << 22)
+#define S3C2410_SDIDCON_TXAFTERRESP	(1 << 20)
+#define S3C2410_SDIDCON_RXAFTERCMD	(1 << 19)
+#define S3C2410_SDIDCON_BLOCKMODE	(1 << 17)
+#define S3C2410_SDIDCON_WIDEBUS		(1 << 16)
+#define S3C2410_SDIDCON_DMAEN		(1 << 15)
+#define S3C2410_SDIDCON_STOP		(1 << 14)
+#define S3C2440_SDIDCON_DATSTART	(1 << 14)
+
+#define S3C2410_SDIDCON_XFER_RXSTART	(2 << 12)
+#define S3C2410_SDIDCON_XFER_TXSTART	(3 << 12)
+
+#define S3C2410_SDIDCON_BLKNUM_MASK	(0xFFF)
+
+#define S3C2410_SDIDSTA_SDIOIRQDETECT	(1 << 9)
+#define S3C2410_SDIDSTA_FIFOFAIL	(1 << 8)
+#define S3C2410_SDIDSTA_CRCFAIL		(1 << 7)
+#define S3C2410_SDIDSTA_RXCRCFAIL	(1 << 6)
+#define S3C2410_SDIDSTA_DATATIMEOUT	(1 << 5)
+#define S3C2410_SDIDSTA_XFERFINISH	(1 << 4)
+#define S3C2410_SDIDSTA_TXDATAON	(1 << 1)
+#define S3C2410_SDIDSTA_RXDATAON	(1 << 0)
+
+#define S3C2440_SDIFSTA_FIFORESET	(1 << 16)
+#define S3C2440_SDIFSTA_FIFOFAIL	(3 << 14)
+#define S3C2410_SDIFSTA_TFDET		(1 << 13)
+#define S3C2410_SDIFSTA_RFDET		(1 << 12)
+#define S3C2410_SDIFSTA_COUNTMASK	(0x7f)
+
+#define S3C2410_SDIIMSK_RESPONSECRC	(1 << 17)
+#define S3C2410_SDIIMSK_CMDSENT		(1 << 16)
+#define S3C2410_SDIIMSK_CMDTIMEOUT	(1 << 15)
+#define S3C2410_SDIIMSK_RESPONSEND	(1 << 14)
+#define S3C2410_SDIIMSK_SDIOIRQ		(1 << 12)
+#define S3C2410_SDIIMSK_FIFOFAIL	(1 << 11)
+#define S3C2410_SDIIMSK_CRCSTATUS	(1 << 10)
+#define S3C2410_SDIIMSK_DATACRC		(1 << 9)
+#define S3C2410_SDIIMSK_DATATIMEOUT	(1 << 8)
+#define S3C2410_SDIIMSK_DATAFINISH	(1 << 7)
+#define S3C2410_SDIIMSK_TXFIFOHALF	(1 << 4)
+#define S3C2410_SDIIMSK_RXFIFOLAST	(1 << 2)
+#define S3C2410_SDIIMSK_RXFIFOHALF	(1 << 0)
+
 enum dbg_channels {
 	dbg_err   = (1 << 0),
 	dbg_debug = (1 << 1),
@@ -1237,12 +1315,9 @@
 	switch (ios->power_mode) {
 	case MMC_POWER_ON:
 	case MMC_POWER_UP:
-		s3c2410_gpio_cfgpin(S3C2410_GPE(5), S3C2410_GPE5_SDCLK);
-		s3c2410_gpio_cfgpin(S3C2410_GPE(6), S3C2410_GPE6_SDCMD);
-		s3c2410_gpio_cfgpin(S3C2410_GPE(7), S3C2410_GPE7_SDDAT0);
-		s3c2410_gpio_cfgpin(S3C2410_GPE(8), S3C2410_GPE8_SDDAT1);
-		s3c2410_gpio_cfgpin(S3C2410_GPE(9), S3C2410_GPE9_SDDAT2);
-		s3c2410_gpio_cfgpin(S3C2410_GPE(10), S3C2410_GPE10_SDDAT3);
+		/* Configure GPE5...GPE10 pins in SD mode */
+		s3c_gpio_cfgall_range(S3C2410_GPE(5), 6, S3C_GPIO_SFN(2),
+				      S3C_GPIO_PULL_NONE);
 
 		if (host->pdata->set_power)
 			host->pdata->set_power(ios->power_mode, ios->vdd);
@@ -1544,7 +1619,7 @@
 
 #endif /* CONFIG_DEBUG_FS */
 
-static int __devinit s3cmci_probe(struct platform_device *pdev)
+static int s3cmci_probe(struct platform_device *pdev)
 {
 	struct s3cmci_host *host;
 	struct mmc_host	*mmc;
@@ -1823,7 +1898,7 @@
 	clk_disable(host->clk);
 }
 
-static int __devexit s3cmci_remove(struct platform_device *pdev)
+static int s3cmci_remove(struct platform_device *pdev)
 {
 	struct mmc_host		*mmc  = platform_get_drvdata(pdev);
 	struct s3cmci_host	*host = mmc_priv(mmc);
@@ -1910,7 +1985,7 @@
 	},
 	.id_table	= s3cmci_driver_ids,
 	.probe		= s3cmci_probe,
-	.remove		= __devexit_p(s3cmci_remove),
+	.remove		= s3cmci_remove,
 	.shutdown	= s3cmci_shutdown,
 };
 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/sdhci-acpi.c linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/sdhci-acpi.c
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/sdhci-acpi.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/sdhci-acpi.c	2014-09-12 15:59:37.348052000 +0800
@@ -0,0 +1,365 @@
+/*
+ * Secure Digital Host Controller Interface ACPI driver.
+ *
+ * Copyright (c) 2012, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/export.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/ioport.h>
+#include <linux/io.h>
+#include <linux/dma-mapping.h>
+#include <linux/compiler.h>
+#include <linux/stddef.h>
+#include <linux/bitops.h>
+#include <linux/types.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/acpi.h>
+#include <linux/pm.h>
+#include <linux/pm_runtime.h>
+
+#include <linux/mmc/host.h>
+#include <linux/mmc/pm.h>
+#include <linux/mmc/sdhci.h>
+
+#include "sdhci.h"
+
+enum {
+	SDHCI_ACPI_SD_CD	= BIT(0),
+	SDHCI_ACPI_RUNTIME_PM	= BIT(1),
+};
+
+struct sdhci_acpi_chip {
+	const struct	sdhci_ops *ops;
+	unsigned int	quirks;
+	unsigned int	quirks2;
+	unsigned long	caps;
+	unsigned int	caps2;
+	mmc_pm_flag_t	pm_caps;
+};
+
+struct sdhci_acpi_slot {
+	const struct	sdhci_acpi_chip *chip;
+	unsigned int	quirks;
+	unsigned int	quirks2;
+	unsigned long	caps;
+	unsigned int	caps2;
+	mmc_pm_flag_t	pm_caps;
+	unsigned int	flags;
+};
+
+struct sdhci_acpi_host {
+	struct sdhci_host		*host;
+	const struct sdhci_acpi_slot	*slot;
+	struct platform_device		*pdev;
+	bool				use_runtime_pm;
+};
+
+static inline bool sdhci_acpi_flag(struct sdhci_acpi_host *c, unsigned int flag)
+{
+	return c->slot && (c->slot->flags & flag);
+}
+
+static int sdhci_acpi_enable_dma(struct sdhci_host *host)
+{
+	return 0;
+}
+
+static const struct sdhci_ops sdhci_acpi_ops_dflt = {
+	.enable_dma = sdhci_acpi_enable_dma,
+};
+
+static const struct sdhci_acpi_slot sdhci_acpi_slot_int_emmc = {
+	.caps    = MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE,
+	.caps2   = MMC_CAP2_HC_ERASE_SZ,
+	.flags   = SDHCI_ACPI_RUNTIME_PM,
+};
+
+static const struct sdhci_acpi_slot sdhci_acpi_slot_int_sdio = {
+	.quirks2 = SDHCI_QUIRK2_HOST_OFF_CARD_ON,
+	.caps    = MMC_CAP_NONREMOVABLE | MMC_CAP_POWER_OFF_CARD,
+	.flags   = SDHCI_ACPI_RUNTIME_PM,
+	.pm_caps = MMC_PM_KEEP_POWER,
+};
+
+static const struct sdhci_acpi_slot sdhci_acpi_slot_int_sd = {
+};
+
+struct sdhci_acpi_uid_slot {
+	const char *hid;
+	const char *uid;
+	const struct sdhci_acpi_slot *slot;
+};
+
+static const struct sdhci_acpi_uid_slot sdhci_acpi_uids[] = {
+	{ "80860F14" , "1" , &sdhci_acpi_slot_int_emmc },
+	{ "80860F14" , "3" , &sdhci_acpi_slot_int_sd   },
+	{ "INT33BB"  , "2" , &sdhci_acpi_slot_int_sdio },
+	{ "INT33C6"  , NULL, &sdhci_acpi_slot_int_sdio },
+	{ "PNP0D40"  },
+	{ },
+};
+
+static const struct acpi_device_id sdhci_acpi_ids[] = {
+	{ "80860F14" },
+	{ "INT33BB"  },
+	{ "INT33C6"  },
+	{ "PNP0D40"  },
+	{ },
+};
+MODULE_DEVICE_TABLE(acpi, sdhci_acpi_ids);
+
+static const struct sdhci_acpi_slot *sdhci_acpi_get_slot_by_ids(const char *hid,
+								const char *uid)
+{
+	const struct sdhci_acpi_uid_slot *u;
+
+	for (u = sdhci_acpi_uids; u->hid; u++) {
+		if (strcmp(u->hid, hid))
+			continue;
+		if (!u->uid)
+			return u->slot;
+		if (uid && !strcmp(u->uid, uid))
+			return u->slot;
+	}
+	return NULL;
+}
+
+static const struct sdhci_acpi_slot *sdhci_acpi_get_slot(acpi_handle handle,
+							 const char *hid)
+{
+	const struct sdhci_acpi_slot *slot;
+	struct acpi_device_info *info;
+	const char *uid = NULL;
+	acpi_status status;
+
+	status = acpi_get_object_info(handle, &info);
+	if (!ACPI_FAILURE(status) && (info->valid & ACPI_VALID_UID))
+		uid = info->unique_id.string;
+
+	slot = sdhci_acpi_get_slot_by_ids(hid, uid);
+
+	kfree(info);
+	return slot;
+}
+
+static int sdhci_acpi_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	acpi_handle handle = ACPI_HANDLE(dev);
+	struct acpi_device *device;
+	struct sdhci_acpi_host *c;
+	struct sdhci_host *host;
+	struct resource *iomem;
+	resource_size_t len;
+	const char *hid;
+	int err;
+
+	if (acpi_bus_get_device(handle, &device))
+		return -ENODEV;
+
+	if (acpi_bus_get_status(device) || !device->status.present)
+		return -ENODEV;
+
+	hid = acpi_device_hid(device);
+
+	iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!iomem)
+		return -ENOMEM;
+
+	len = resource_size(iomem);
+	if (len < 0x100)
+		dev_err(dev, "Invalid iomem size!\n");
+
+	if (!devm_request_mem_region(dev, iomem->start, len, dev_name(dev)))
+		return -ENOMEM;
+
+	host = sdhci_alloc_host(dev, sizeof(struct sdhci_acpi_host));
+	if (IS_ERR(host))
+		return PTR_ERR(host);
+
+	c = sdhci_priv(host);
+	c->host = host;
+	c->slot = sdhci_acpi_get_slot(handle, hid);
+	c->pdev = pdev;
+	c->use_runtime_pm = sdhci_acpi_flag(c, SDHCI_ACPI_RUNTIME_PM);
+
+	platform_set_drvdata(pdev, c);
+
+	host->hw_name	= "ACPI";
+	host->ops	= &sdhci_acpi_ops_dflt;
+	host->irq	= platform_get_irq(pdev, 0);
+
+	host->ioaddr = devm_ioremap_nocache(dev, iomem->start,
+					    resource_size(iomem));
+	if (host->ioaddr == NULL) {
+		err = -ENOMEM;
+		goto err_free;
+	}
+
+	if (!dev->dma_mask) {
+		u64 dma_mask;
+
+		if (sdhci_readl(host, SDHCI_CAPABILITIES) & SDHCI_CAN_64BIT) {
+			/* 64-bit DMA is not supported at present */
+			dma_mask = DMA_BIT_MASK(32);
+		} else {
+			dma_mask = DMA_BIT_MASK(32);
+		}
+
+		dev->dma_mask = &dev->coherent_dma_mask;
+		dev->coherent_dma_mask = dma_mask;
+	}
+
+	if (c->slot) {
+		if (c->slot->chip) {
+			host->ops            = c->slot->chip->ops;
+			host->quirks        |= c->slot->chip->quirks;
+			host->quirks2       |= c->slot->chip->quirks2;
+			host->mmc->caps     |= c->slot->chip->caps;
+			host->mmc->caps2    |= c->slot->chip->caps2;
+			host->mmc->pm_caps  |= c->slot->chip->pm_caps;
+		}
+		host->quirks        |= c->slot->quirks;
+		host->quirks2       |= c->slot->quirks2;
+		host->mmc->caps     |= c->slot->caps;
+		host->mmc->caps2    |= c->slot->caps2;
+		host->mmc->pm_caps  |= c->slot->pm_caps;
+	}
+
+	host->mmc->caps2 |= MMC_CAP2_NO_PRESCAN_POWERUP;
+
+	err = sdhci_add_host(host);
+	if (err)
+		goto err_free;
+
+	if (c->use_runtime_pm) {
+		pm_runtime_set_active(dev);
+		pm_suspend_ignore_children(dev, 1);
+		pm_runtime_set_autosuspend_delay(dev, 50);
+		pm_runtime_use_autosuspend(dev);
+		pm_runtime_enable(dev);
+	}
+
+	return 0;
+
+err_free:
+	platform_set_drvdata(pdev, NULL);
+	sdhci_free_host(c->host);
+	return err;
+}
+
+static int sdhci_acpi_remove(struct platform_device *pdev)
+{
+	struct sdhci_acpi_host *c = platform_get_drvdata(pdev);
+	struct device *dev = &pdev->dev;
+	int dead;
+
+	if (c->use_runtime_pm) {
+		pm_runtime_get_sync(dev);
+		pm_runtime_disable(dev);
+		pm_runtime_put_noidle(dev);
+	}
+
+	dead = (sdhci_readl(c->host, SDHCI_INT_STATUS) == ~0);
+	sdhci_remove_host(c->host, dead);
+	platform_set_drvdata(pdev, NULL);
+	sdhci_free_host(c->host);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+
+static int sdhci_acpi_suspend(struct device *dev)
+{
+	struct sdhci_acpi_host *c = dev_get_drvdata(dev);
+
+	return sdhci_suspend_host(c->host);
+}
+
+static int sdhci_acpi_resume(struct device *dev)
+{
+	struct sdhci_acpi_host *c = dev_get_drvdata(dev);
+
+	return sdhci_resume_host(c->host);
+}
+
+#else
+
+#define sdhci_acpi_suspend	NULL
+#define sdhci_acpi_resume	NULL
+
+#endif
+
+#ifdef CONFIG_PM_RUNTIME
+
+static int sdhci_acpi_runtime_suspend(struct device *dev)
+{
+	struct sdhci_acpi_host *c = dev_get_drvdata(dev);
+
+	return sdhci_runtime_suspend_host(c->host);
+}
+
+static int sdhci_acpi_runtime_resume(struct device *dev)
+{
+	struct sdhci_acpi_host *c = dev_get_drvdata(dev);
+
+	return sdhci_runtime_resume_host(c->host);
+}
+
+static int sdhci_acpi_runtime_idle(struct device *dev)
+{
+	return 0;
+}
+
+#else
+
+#define sdhci_acpi_runtime_suspend	NULL
+#define sdhci_acpi_runtime_resume	NULL
+#define sdhci_acpi_runtime_idle		NULL
+
+#endif
+
+static const struct dev_pm_ops sdhci_acpi_pm_ops = {
+	.suspend		= sdhci_acpi_suspend,
+	.resume			= sdhci_acpi_resume,
+	.runtime_suspend	= sdhci_acpi_runtime_suspend,
+	.runtime_resume		= sdhci_acpi_runtime_resume,
+	.runtime_idle		= sdhci_acpi_runtime_idle,
+};
+
+static struct platform_driver sdhci_acpi_driver = {
+	.driver = {
+		.name			= "sdhci-acpi",
+		.owner			= THIS_MODULE,
+		.acpi_match_table	= sdhci_acpi_ids,
+		.pm			= &sdhci_acpi_pm_ops,
+	},
+	.probe	= sdhci_acpi_probe,
+	.remove	= sdhci_acpi_remove,
+};
+
+module_platform_driver(sdhci_acpi_driver);
+
+MODULE_DESCRIPTION("Secure Digital Host Controller Interface ACPI driver");
+MODULE_AUTHOR("Adrian Hunter");
+MODULE_LICENSE("GPL v2");
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/sdhci-bcm2835.c linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/sdhci-bcm2835.c
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/sdhci-bcm2835.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/sdhci-bcm2835.c	2014-09-12 15:59:37.348052000 +0800
@@ -0,0 +1,210 @@
+/*
+ * BCM2835 SDHCI
+ * Copyright (C) 2012 Stephen Warren
+ * Based on U-Boot's MMC driver for the BCM2835 by Oleksandr Tymoshenko & me
+ * Portions of the code there were obviously based on the Linux kernel at:
+ * git://github.com/raspberrypi/linux.git rpi-3.6.y
+ * commit f5b930b "Main bcm2708 linux port" signed-off-by Dom Cobley.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/mmc/host.h>
+#include "sdhci-pltfm.h"
+
+/*
+ * 400KHz is max freq for card ID etc. Use that as min card clock. We need to
+ * know the min to enable static calculation of max BCM2835_SDHCI_WRITE_DELAY.
+ */
+#define MIN_FREQ 400000
+
+/*
+ * The Arasan has a bugette whereby it may lose the content of successive
+ * writes to registers that are within two SD-card clock cycles of each other
+ * (a clock domain crossing problem). It seems, however, that the data
+ * register does not have this problem, which is just as well - otherwise we'd
+ * have to nobble the DMA engine too.
+ *
+ * This should probably be dynamically calculated based on the actual card
+ * frequency. However, this is the longest we'll have to wait, and doesn't
+ * seem to slow access down too much, so the added complexity doesn't seem
+ * worth it for now.
+ *
+ * 1/MIN_FREQ is (max) time per tick of eMMC clock.
+ * 2/MIN_FREQ is time for two ticks.
+ * Multiply by 1000000 to get uS per two ticks.
+ * *1000000 for uSecs.
+ * +1 for hack rounding.
+ */
+#define BCM2835_SDHCI_WRITE_DELAY	(((2 * 1000000) / MIN_FREQ) + 1)
+
+struct bcm2835_sdhci {
+	u32 shadow;
+};
+
+static void bcm2835_sdhci_writel(struct sdhci_host *host, u32 val, int reg)
+{
+	writel(val, host->ioaddr + reg);
+
+	udelay(BCM2835_SDHCI_WRITE_DELAY);
+}
+
+static inline u32 bcm2835_sdhci_readl(struct sdhci_host *host, int reg)
+{
+	u32 val = readl(host->ioaddr + reg);
+
+	if (reg == SDHCI_CAPABILITIES)
+		val |= SDHCI_CAN_VDD_330;
+
+	return val;
+}
+
+static void bcm2835_sdhci_writew(struct sdhci_host *host, u16 val, int reg)
+{
+	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+	struct bcm2835_sdhci *bcm2835_host = pltfm_host->priv;
+	u32 oldval = (reg == SDHCI_COMMAND) ? bcm2835_host->shadow :
+		bcm2835_sdhci_readl(host, reg & ~3);
+	u32 word_num = (reg >> 1) & 1;
+	u32 word_shift = word_num * 16;
+	u32 mask = 0xffff << word_shift;
+	u32 newval = (oldval & ~mask) | (val << word_shift);
+
+	if (reg == SDHCI_TRANSFER_MODE)
+		bcm2835_host->shadow = newval;
+	else
+		bcm2835_sdhci_writel(host, newval, reg & ~3);
+}
+
+static u16 bcm2835_sdhci_readw(struct sdhci_host *host, int reg)
+{
+	u32 val = bcm2835_sdhci_readl(host, (reg & ~3));
+	u32 word_num = (reg >> 1) & 1;
+	u32 word_shift = word_num * 16;
+	u32 word = (val >> word_shift) & 0xffff;
+
+	return word;
+}
+
+static void bcm2835_sdhci_writeb(struct sdhci_host *host, u8 val, int reg)
+{
+	u32 oldval = bcm2835_sdhci_readl(host, reg & ~3);
+	u32 byte_num = reg & 3;
+	u32 byte_shift = byte_num * 8;
+	u32 mask = 0xff << byte_shift;
+	u32 newval = (oldval & ~mask) | (val << byte_shift);
+
+	bcm2835_sdhci_writel(host, newval, reg & ~3);
+}
+
+static u8 bcm2835_sdhci_readb(struct sdhci_host *host, int reg)
+{
+	u32 val = bcm2835_sdhci_readl(host, (reg & ~3));
+	u32 byte_num = reg & 3;
+	u32 byte_shift = byte_num * 8;
+	u32 byte = (val >> byte_shift) & 0xff;
+
+	return byte;
+}
+
+unsigned int bcm2835_sdhci_get_min_clock(struct sdhci_host *host)
+{
+	return MIN_FREQ;
+}
+
+static const struct sdhci_ops bcm2835_sdhci_ops = {
+	.write_l = bcm2835_sdhci_writel,
+	.write_w = bcm2835_sdhci_writew,
+	.write_b = bcm2835_sdhci_writeb,
+	.read_l = bcm2835_sdhci_readl,
+	.read_w = bcm2835_sdhci_readw,
+	.read_b = bcm2835_sdhci_readb,
+	.get_max_clock = sdhci_pltfm_clk_get_max_clock,
+	.get_min_clock = bcm2835_sdhci_get_min_clock,
+};
+
+static const struct sdhci_pltfm_data bcm2835_sdhci_pdata = {
+	.quirks = SDHCI_QUIRK_BROKEN_CARD_DETECTION |
+		  SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK,
+	.ops = &bcm2835_sdhci_ops,
+};
+
+static int bcm2835_sdhci_probe(struct platform_device *pdev)
+{
+	struct sdhci_host *host;
+	struct bcm2835_sdhci *bcm2835_host;
+	struct sdhci_pltfm_host *pltfm_host;
+	int ret;
+
+	host = sdhci_pltfm_init(pdev, &bcm2835_sdhci_pdata);
+	if (IS_ERR(host))
+		return PTR_ERR(host);
+
+	bcm2835_host = devm_kzalloc(&pdev->dev, sizeof(*bcm2835_host),
+					GFP_KERNEL);
+	if (!bcm2835_host) {
+		dev_err(mmc_dev(host->mmc),
+			"failed to allocate bcm2835_sdhci\n");
+		return -ENOMEM;
+	}
+
+	pltfm_host = sdhci_priv(host);
+	pltfm_host->priv = bcm2835_host;
+
+	pltfm_host->clk = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR(pltfm_host->clk)) {
+		ret = PTR_ERR(pltfm_host->clk);
+		goto err;
+	}
+
+	return sdhci_add_host(host);
+
+err:
+	sdhci_pltfm_free(pdev);
+	return ret;
+}
+
+static int bcm2835_sdhci_remove(struct platform_device *pdev)
+{
+	struct sdhci_host *host = platform_get_drvdata(pdev);
+	int dead = (readl(host->ioaddr + SDHCI_INT_STATUS) == 0xffffffff);
+
+	sdhci_remove_host(host, dead);
+	sdhci_pltfm_free(pdev);
+
+	return 0;
+}
+
+static const struct of_device_id bcm2835_sdhci_of_match[] = {
+	{ .compatible = "brcm,bcm2835-sdhci" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, bcm2835_sdhci_of_match);
+
+static struct platform_driver bcm2835_sdhci_driver = {
+	.driver = {
+		.name = "sdhci-bcm2835",
+		.owner = THIS_MODULE,
+		.of_match_table = bcm2835_sdhci_of_match,
+		.pm = SDHCI_PLTFM_PMOPS,
+	},
+	.probe = bcm2835_sdhci_probe,
+	.remove = bcm2835_sdhci_remove,
+};
+module_platform_driver(bcm2835_sdhci_driver);
+
+MODULE_DESCRIPTION("BCM2835 SDHCI driver");
+MODULE_AUTHOR("Stephen Warren");
+MODULE_LICENSE("GPL v2");
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/sdhci.c linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/sdhci.c
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/sdhci.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/sdhci.c	2014-09-12 15:59:37.348052000 +0800
@@ -27,6 +27,8 @@
 
 #include <linux/mmc/mmc.h>
 #include <linux/mmc/host.h>
+#include <linux/mmc/card.h>
+#include <linux/mmc/slot-gpio.h>
 
 #include "sdhci.h"
 
@@ -51,6 +53,7 @@
 static void sdhci_finish_command(struct sdhci_host *);
 static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode);
 static void sdhci_tuning_timer(unsigned long data);
+static void sdhci_enable_preset_value(struct sdhci_host *host, bool enable);
 
 #ifdef CONFIG_PM_RUNTIME
 static int sdhci_runtime_pm_get(struct sdhci_host *host);
@@ -244,6 +247,19 @@
 static void sdhci_reinit(struct sdhci_host *host)
 {
 	sdhci_init(host, 0);
+	/*
+	 * Retuning stuffs are affected by different cards inserted and only
+	 * applicable to UHS-I cards. So reset these fields to their initial
+	 * value when card is removed.
+	 */
+	if (host->flags & SDHCI_USING_RETUNING_TIMER) {
+		host->flags &= ~SDHCI_USING_RETUNING_TIMER;
+
+		del_timer_sync(&host->tuning_timer);
+		host->flags &= ~SDHCI_NEEDS_RETUNING;
+		host->mmc->max_blk_count =
+			(host->quirks & SDHCI_QUIRK_NO_MULTIBLOCK) ? 1 : 65535;
+	}
 	sdhci_enable_card_detection(host);
 }
 
@@ -679,8 +695,11 @@
 			break;
 	}
 
-	if (count >= 0xF)
+	if (count >= 0xF) {
+		DBG("%s: Too large timeout 0x%x requested for CMD%d!\n",
+		    mmc_hostname(host->mmc), count, cmd->opcode);
 		count = 0xE;
+	}
 
 	return count;
 }
@@ -1064,6 +1083,37 @@
 	}
 }
 
+static u16 sdhci_get_preset_value(struct sdhci_host *host)
+{
+	u16 ctrl, preset = 0;
+
+	ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
+
+	switch (ctrl & SDHCI_CTRL_UHS_MASK) {
+	case SDHCI_CTRL_UHS_SDR12:
+		preset = sdhci_readw(host, SDHCI_PRESET_FOR_SDR12);
+		break;
+	case SDHCI_CTRL_UHS_SDR25:
+		preset = sdhci_readw(host, SDHCI_PRESET_FOR_SDR25);
+		break;
+	case SDHCI_CTRL_UHS_SDR50:
+		preset = sdhci_readw(host, SDHCI_PRESET_FOR_SDR50);
+		break;
+	case SDHCI_CTRL_UHS_SDR104:
+		preset = sdhci_readw(host, SDHCI_PRESET_FOR_SDR104);
+		break;
+	case SDHCI_CTRL_UHS_DDR50:
+		preset = sdhci_readw(host, SDHCI_PRESET_FOR_DDR50);
+		break;
+	default:
+		pr_warn("%s: Invalid UHS-I mode selected\n",
+			mmc_hostname(host->mmc));
+		preset = sdhci_readw(host, SDHCI_PRESET_FOR_SDR12);
+		break;
+	}
+	return preset;
+}
+
 static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
 {
 	int div = 0; /* Initialized for compiler warning */
@@ -1088,35 +1138,43 @@
 		goto out;
 
 	if (host->version >= SDHCI_SPEC_300) {
+		if (sdhci_readw(host, SDHCI_HOST_CONTROL2) &
+			SDHCI_CTRL_PRESET_VAL_ENABLE) {
+			u16 pre_val;
+
+			clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
+			pre_val = sdhci_get_preset_value(host);
+			div = (pre_val & SDHCI_PRESET_SDCLK_FREQ_MASK)
+				>> SDHCI_PRESET_SDCLK_FREQ_SHIFT;
+			if (host->clk_mul &&
+				(pre_val & SDHCI_PRESET_CLKGEN_SEL_MASK)) {
+				clk = SDHCI_PROG_CLOCK_MODE;
+				real_div = div + 1;
+				clk_mul = host->clk_mul;
+			} else {
+				real_div = max_t(int, 1, div << 1);
+			}
+			goto clock_set;
+		}
+
 		/*
 		 * Check if the Host Controller supports Programmable Clock
 		 * Mode.
 		 */
 		if (host->clk_mul) {
-			u16 ctrl;
-
+			for (div = 1; div <= 1024; div++) {
+				if ((host->max_clk * host->clk_mul / div)
+					<= clock)
+					break;
+			}
 			/*
-			 * We need to figure out whether the Host Driver needs
-			 * to select Programmable Clock Mode, or the value can
-			 * be set automatically by the Host Controller based on
-			 * the Preset Value registers.
+			 * Set Programmable Clock Mode in the Clock
+			 * Control register.
 			 */
-			ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
-			if (!(ctrl & SDHCI_CTRL_PRESET_VAL_ENABLE)) {
-				for (div = 1; div <= 1024; div++) {
-					if (((host->max_clk * host->clk_mul) /
-					      div) <= clock)
-						break;
-				}
-				/*
-				 * Set Programmable Clock Mode in the Clock
-				 * Control register.
-				 */
-				clk = SDHCI_PROG_CLOCK_MODE;
-				real_div = div;
-				clk_mul = host->clk_mul;
-				div--;
-			}
+			clk = SDHCI_PROG_CLOCK_MODE;
+			real_div = div;
+			clk_mul = host->clk_mul;
+			div--;
 		} else {
 			/* Version 3.00 divisors must be a multiple of 2. */
 			if (host->max_clk <= clock)
@@ -1141,6 +1199,7 @@
 		div >>= 1;
 	}
 
+clock_set:
 	if (real_div)
 		host->mmc->actual_clock = (host->max_clk * clk_mul) / real_div;
 
@@ -1171,6 +1230,15 @@
 	host->clock = clock;
 }
 
+static inline void sdhci_update_clock(struct sdhci_host *host)
+{
+	unsigned int clock;
+
+	clock = host->clock;
+	host->clock = 0;
+	sdhci_set_clock(host, clock);
+}
+
 static int sdhci_set_power(struct sdhci_host *host, unsigned short power)
 {
 	u8 pwr = 0;
@@ -1240,8 +1308,9 @@
 static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
 {
 	struct sdhci_host *host;
-	bool present;
+	int present;
 	unsigned long flags;
+	u32 tuning_opcode;
 
 	host = mmc_priv(mmc);
 
@@ -1268,12 +1337,22 @@
 
 	host->mrq = mrq;
 
-	/* If polling, assume that the card is always present. */
-	if (host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION)
-		present = true;
-	else
-		present = sdhci_readl(host, SDHCI_PRESENT_STATE) &
-				SDHCI_CARD_PRESENT;
+	/*
+	 * Firstly check card presence from cd-gpio.  The return could
+	 * be one of the following possibilities:
+	 *     negative: cd-gpio is not available
+	 *     zero: cd-gpio is used, and card is removed
+	 *     one: cd-gpio is used, and card is present
+	 */
+	present = mmc_gpio_get_cd(host->mmc);
+	if (present < 0) {
+		/* If polling, assume that the card is always present. */
+		if (host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION)
+			present = 1;
+		else
+			present = sdhci_readl(host, SDHCI_PRESENT_STATE) &
+					SDHCI_CARD_PRESENT;
+	}
 
 	if (!present || host->flags & SDHCI_DEVICE_DEAD) {
 		host->mrq->cmd->error = -ENOMEDIUM;
@@ -1289,12 +1368,19 @@
 		 */
 		if ((host->flags & SDHCI_NEEDS_RETUNING) &&
 		    !(present_state & (SDHCI_DOING_WRITE | SDHCI_DOING_READ))) {
-			spin_unlock_irqrestore(&host->lock, flags);
-			sdhci_execute_tuning(mmc, mrq->cmd->opcode);
-			spin_lock_irqsave(&host->lock, flags);
+			if (mmc->card) {
+				/* eMMC uses cmd21 but sd and sdio use cmd19 */
+				tuning_opcode =
+					mmc->card->type == MMC_TYPE_MMC ?
+					MMC_SEND_TUNING_BLOCK_HS200 :
+					MMC_SEND_TUNING_BLOCK;
+				spin_unlock_irqrestore(&host->lock, flags);
+				sdhci_execute_tuning(mmc, tuning_opcode);
+				spin_lock_irqsave(&host->lock, flags);
 
-			/* Restore original mmc_request structure */
-			host->mrq = mrq;
+				/* Restore original mmc_request structure */
+				host->mrq = mrq;
+			}
 		}
 
 		if (mrq->sbc && !(host->flags & SDHCI_AUTO_CMD23))
@@ -1331,6 +1417,10 @@
 		sdhci_reinit(host);
 	}
 
+	if (host->version >= SDHCI_SPEC_300 &&
+		(ios->power_mode == MMC_POWER_UP))
+		sdhci_enable_preset_value(host, false);
+
 	sdhci_set_clock(host, ios->clock);
 
 	if (ios->power_mode == MMC_POWER_OFF)
@@ -1350,11 +1440,11 @@
 	/*
 	 * If your platform has 8-bit width support but is not a v3 controller,
 	 * or if it requires special setup code, you should implement that in
-	 * platform_8bit_width().
+	 * platform_bus_width().
 	 */
-	if (host->ops->platform_8bit_width)
-		host->ops->platform_8bit_width(host, ios->bus_width);
-	else {
+	if (host->ops->platform_bus_width) {
+		host->ops->platform_bus_width(host, ios->bus_width);
+	} else {
 		ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
 		if (ios->bus_width == MMC_BUS_WIDTH_8) {
 			ctrl &= ~SDHCI_CTRL_4BITBUS;
@@ -1382,7 +1472,6 @@
 
 	if (host->version >= SDHCI_SPEC_300) {
 		u16 clk, ctrl_2;
-		unsigned int clock;
 
 		/* In case of UHS-I modes, set High Speed Enable */
 		if ((ios->timing == MMC_TIMING_MMC_HS200) ||
@@ -1422,9 +1511,7 @@
 			sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
 
 			/* Re-enable SD Clock */
-			clock = host->clock;
-			host->clock = 0;
-			sdhci_set_clock(host, clock);
+			sdhci_update_clock(host);
 		}
 
 
@@ -1454,10 +1541,22 @@
 			sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2);
 		}
 
+		if (!(host->quirks2 & SDHCI_QUIRK2_PRESET_VALUE_BROKEN) &&
+				((ios->timing == MMC_TIMING_UHS_SDR12) ||
+				 (ios->timing == MMC_TIMING_UHS_SDR25) ||
+				 (ios->timing == MMC_TIMING_UHS_SDR50) ||
+				 (ios->timing == MMC_TIMING_UHS_SDR104) ||
+				 (ios->timing == MMC_TIMING_UHS_DDR50))) {
+			u16 preset;
+
+			sdhci_enable_preset_value(host, true);
+			preset = sdhci_get_preset_value(host);
+			ios->drv_type = (preset & SDHCI_PRESET_DRV_MASK)
+				>> SDHCI_PRESET_DRV_SHIFT;
+		}
+
 		/* Re-enable SD Clock */
-		clock = host->clock;
-		host->clock = 0;
-		sdhci_set_clock(host, clock);
+		sdhci_update_clock(host);
 	} else
 		sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
 
@@ -1482,6 +1581,37 @@
 	sdhci_runtime_pm_put(host);
 }
 
+static int sdhci_do_get_cd(struct sdhci_host *host)
+{
+	int gpio_cd = mmc_gpio_get_cd(host->mmc);
+
+	if (host->flags & SDHCI_DEVICE_DEAD)
+		return 0;
+
+	/* If polling/nonremovable, assume that the card is always present. */
+	if ((host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION) ||
+	    (host->mmc->caps & MMC_CAP_NONREMOVABLE))
+		return 1;
+
+	/* Try slot gpio detect */
+	if (!IS_ERR_VALUE(gpio_cd))
+		return !!gpio_cd;
+
+	/* Host native card detect */
+	return !!(sdhci_readl(host, SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT);
+}
+
+static int sdhci_get_cd(struct mmc_host *mmc)
+{
+	struct sdhci_host *host = mmc_priv(mmc);
+	int ret;
+
+	sdhci_runtime_pm_get(host);
+	ret = sdhci_do_get_cd(host);
+	sdhci_runtime_pm_put(host);
+	return ret;
+}
+
 static int sdhci_check_ro(struct sdhci_host *host)
 {
 	unsigned long flags;
@@ -1578,9 +1708,8 @@
 static int sdhci_do_start_signal_voltage_switch(struct sdhci_host *host,
 						struct mmc_ios *ios)
 {
-	u8 pwr;
-	u16 clk, ctrl;
-	u32 present_state;
+	u16 ctrl;
+	int ret;
 
 	/*
 	 * Signal Voltage Switching is only applicable for Host Controllers
@@ -1589,16 +1718,22 @@
 	if (host->version < SDHCI_SPEC_300)
 		return 0;
 
-	/*
-	 * We first check whether the request is to set signalling voltage
-	 * to 3.3V. If so, we change the voltage to 3.3V and return quickly.
-	 */
 	ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
-	if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_330) {
+
+	switch (ios->signal_voltage) {
+	case MMC_SIGNAL_VOLTAGE_330:
 		/* Set 1.8V Signal Enable in the Host Control2 register to 0 */
 		ctrl &= ~SDHCI_CTRL_VDD_180;
 		sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
 
+		if (host->vqmmc) {
+			ret = regulator_set_voltage(host->vqmmc, 2700000, 3600000);
+			if (ret) {
+				pr_warning("%s: Switching to 3.3V signalling voltage "
+						" failed\n", mmc_hostname(host->mmc));
+				return -EIO;
+			}
+		}
 		/* Wait for 5ms */
 		usleep_range(5000, 5500);
 
@@ -1606,72 +1741,55 @@
 		ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
 		if (!(ctrl & SDHCI_CTRL_VDD_180))
 			return 0;
-		else {
-			pr_info(DRIVER_NAME ": Switching to 3.3V "
-				"signalling voltage failed\n");
-			return -EIO;
-		}
-	} else if (!(ctrl & SDHCI_CTRL_VDD_180) &&
-		  (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_180)) {
-		/* Stop SDCLK */
-		clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
-		clk &= ~SDHCI_CLOCK_CARD_EN;
-		sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
-
-		/* Check whether DAT[3:0] is 0000 */
-		present_state = sdhci_readl(host, SDHCI_PRESENT_STATE);
-		if (!((present_state & SDHCI_DATA_LVL_MASK) >>
-		       SDHCI_DATA_LVL_SHIFT)) {
-			/*
-			 * Enable 1.8V Signal Enable in the Host Control2
-			 * register
-			 */
-			ctrl |= SDHCI_CTRL_VDD_180;
-			sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
 
-			/* Wait for 5ms */
-			usleep_range(5000, 5500);
-
-			ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
-			if (ctrl & SDHCI_CTRL_VDD_180) {
-				/* Provide SDCLK again and wait for 1ms*/
-				clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
-				clk |= SDHCI_CLOCK_CARD_EN;
-				sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
-				usleep_range(1000, 1500);
+		pr_warning("%s: 3.3V regulator output did not became stable\n",
+				mmc_hostname(host->mmc));
 
-				/*
-				 * If DAT[3:0] level is 1111b, then the card
-				 * was successfully switched to 1.8V signaling.
-				 */
-				present_state = sdhci_readl(host,
-							SDHCI_PRESENT_STATE);
-				if ((present_state & SDHCI_DATA_LVL_MASK) ==
-				     SDHCI_DATA_LVL_MASK)
-					return 0;
+		return -EAGAIN;
+	case MMC_SIGNAL_VOLTAGE_180:
+		if (host->vqmmc) {
+			ret = regulator_set_voltage(host->vqmmc,
+					1700000, 1950000);
+			if (ret) {
+				pr_warning("%s: Switching to 1.8V signalling voltage "
+						" failed\n", mmc_hostname(host->mmc));
+				return -EIO;
 			}
 		}
 
 		/*
-		 * If we are here, that means the switch to 1.8V signaling
-		 * failed. We power cycle the card, and retry initialization
-		 * sequence by setting S18R to 0.
+		 * Enable 1.8V Signal Enable in the Host Control2
+		 * register
 		 */
-		pwr = sdhci_readb(host, SDHCI_POWER_CONTROL);
-		pwr &= ~SDHCI_POWER_ON;
-		sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
+		ctrl |= SDHCI_CTRL_VDD_180;
+		sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
 
-		/* Wait for 1ms as per the spec */
-		usleep_range(1000, 1500);
-		pwr |= SDHCI_POWER_ON;
-		sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
+		/* Wait for 5ms */
+		usleep_range(5000, 5500);
+
+		/* 1.8V regulator output should be stable within 5 ms */
+		ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
+		if (ctrl & SDHCI_CTRL_VDD_180)
+			return 0;
+
+		pr_warning("%s: 1.8V regulator output did not became stable\n",
+				mmc_hostname(host->mmc));
 
-		pr_info(DRIVER_NAME ": Switching to 1.8V signalling "
-			"voltage failed, retrying with S18R set to 0\n");
 		return -EAGAIN;
-	} else
+	case MMC_SIGNAL_VOLTAGE_120:
+		if (host->vqmmc) {
+			ret = regulator_set_voltage(host->vqmmc, 1100000, 1300000);
+			if (ret) {
+				pr_warning("%s: Switching to 1.2V signalling voltage "
+						" failed\n", mmc_hostname(host->mmc));
+				return -EIO;
+			}
+		}
+		return 0;
+	default:
 		/* No signal voltage switch required */
 		return 0;
+	}
 }
 
 static int sdhci_start_signal_voltage_switch(struct mmc_host *mmc,
@@ -1688,6 +1806,19 @@
 	return err;
 }
 
+static int sdhci_card_busy(struct mmc_host *mmc)
+{
+	struct sdhci_host *host = mmc_priv(mmc);
+	u32 present_state;
+
+	sdhci_runtime_pm_get(host);
+	/* Check whether DAT[3:0] is 0000 */
+	present_state = sdhci_readl(host, SDHCI_PRESENT_STATE);
+	sdhci_runtime_pm_put(host);
+
+	return !(present_state & SDHCI_DATA_LVL_MASK);
+}
+
 static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
 {
 	struct sdhci_host *host;
@@ -1852,6 +1983,7 @@
 	 */
 	if (!(host->flags & SDHCI_NEEDS_RETUNING) && host->tuning_count &&
 	    (host->tuning_mode == SDHCI_TUNING_MODE_1)) {
+		host->flags |= SDHCI_USING_RETUNING_TIMER;
 		mod_timer(&host->tuning_timer, jiffies +
 			host->tuning_count * HZ);
 		/* Tuning mode 1 limits the maximum data length to 4MB */
@@ -1869,10 +2001,10 @@
 	 * try tuning again at a later time, when the re-tuning timer expires.
 	 * So for these controllers, we return 0. Since there might be other
 	 * controllers who do not have this capability, we return error for
-	 * them.
+	 * them. SDHCI_USING_RETUNING_TIMER means the host is currently using
+	 * a retuning timer to do the retuning for the card.
 	 */
-	if (err && host->tuning_count &&
-	    host->tuning_mode == SDHCI_TUNING_MODE_1)
+	if (err && (host->flags & SDHCI_USING_RETUNING_TIMER))
 		err = 0;
 
 	sdhci_clear_set_irqs(host, SDHCI_INT_DATA_AVAIL, ier);
@@ -1883,17 +2015,15 @@
 	return err;
 }
 
-static void sdhci_do_enable_preset_value(struct sdhci_host *host, bool enable)
+
+static void sdhci_enable_preset_value(struct sdhci_host *host, bool enable)
 {
 	u16 ctrl;
-	unsigned long flags;
 
 	/* Host Controller v3.00 defines preset value registers */
 	if (host->version < SDHCI_SPEC_300)
 		return;
 
-	spin_lock_irqsave(&host->lock, flags);
-
 	ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
 
 	/*
@@ -1909,28 +2039,44 @@
 		sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
 		host->flags &= ~SDHCI_PV_ENABLED;
 	}
-
-	spin_unlock_irqrestore(&host->lock, flags);
 }
 
-static void sdhci_enable_preset_value(struct mmc_host *mmc, bool enable)
+static void sdhci_card_event(struct mmc_host *mmc)
 {
 	struct sdhci_host *host = mmc_priv(mmc);
+	unsigned long flags;
 
-	sdhci_runtime_pm_get(host);
-	sdhci_do_enable_preset_value(host, enable);
-	sdhci_runtime_pm_put(host);
+	spin_lock_irqsave(&host->lock, flags);
+
+	/* Check host->mrq first in case we are runtime suspended */
+	if (host->mrq &&
+	    !(sdhci_readl(host, SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT)) {
+		pr_err("%s: Card removed during transfer!\n",
+			mmc_hostname(host->mmc));
+		pr_err("%s: Resetting controller.\n",
+			mmc_hostname(host->mmc));
+
+		sdhci_reset(host, SDHCI_RESET_CMD);
+		sdhci_reset(host, SDHCI_RESET_DATA);
+
+		host->mrq->cmd->error = -ENOMEDIUM;
+		tasklet_schedule(&host->finish_tasklet);
+	}
+
+	spin_unlock_irqrestore(&host->lock, flags);
 }
 
 static const struct mmc_host_ops sdhci_ops = {
 	.request	= sdhci_request,
 	.set_ios	= sdhci_set_ios,
+	.get_cd		= sdhci_get_cd,
 	.get_ro		= sdhci_get_ro,
 	.hw_reset	= sdhci_hw_reset,
 	.enable_sdio_irq = sdhci_enable_sdio_irq,
 	.start_signal_voltage_switch	= sdhci_start_signal_voltage_switch,
 	.execute_tuning			= sdhci_execute_tuning,
-	.enable_preset_value		= sdhci_enable_preset_value,
+	.card_event			= sdhci_card_event,
+	.card_busy	= sdhci_card_busy,
 };
 
 /*****************************************************************************\
@@ -1941,29 +2087,9 @@
 
 static void sdhci_tasklet_card(unsigned long param)
 {
-	struct sdhci_host *host;
-	unsigned long flags;
-
-	host = (struct sdhci_host*)param;
-
-	spin_lock_irqsave(&host->lock, flags);
-
-	/* Check host->mrq first in case we are runtime suspended */
-	if (host->mrq &&
-	    !(sdhci_readl(host, SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT)) {
-		pr_err("%s: Card removed during transfer!\n",
-			mmc_hostname(host->mmc));
-		pr_err("%s: Resetting controller.\n",
-			mmc_hostname(host->mmc));
-
-		sdhci_reset(host, SDHCI_RESET_CMD);
-		sdhci_reset(host, SDHCI_RESET_DATA);
-
-		host->mrq->cmd->error = -ENOMEDIUM;
-		tasklet_schedule(&host->finish_tasklet);
-	}
+	struct sdhci_host *host = (struct sdhci_host*)param;
 
-	spin_unlock_irqrestore(&host->lock, flags);
+	sdhci_card_event(host->mmc);
 
 	mmc_detect_change(host->mmc, msecs_to_jiffies(200));
 }
@@ -2002,14 +2128,9 @@
 		   (host->quirks & SDHCI_QUIRK_RESET_AFTER_REQUEST))) {
 
 		/* Some controllers need this kick or reset won't work here */
-		if (host->quirks & SDHCI_QUIRK_CLOCK_BEFORE_RESET) {
-			unsigned int clock;
-
+		if (host->quirks & SDHCI_QUIRK_CLOCK_BEFORE_RESET)
 			/* This is to force an update */
-			clock = host->clock;
-			host->clock = 0;
-			sdhci_set_clock(host, clock);
-		}
+			sdhci_update_clock(host);
 
 		/* Spec says we should do both at the same time, but Ricoh
 		   controllers do not like that. */
@@ -2210,6 +2331,8 @@
 		pr_err("%s: ADMA error\n", mmc_hostname(host->mmc));
 		sdhci_show_adma_error(host);
 		host->data->error = -EIO;
+		if (host->ops->adma_workaround)
+			host->ops->adma_workaround(host, intmask);
 	}
 
 	if (host->data->error)
@@ -2375,11 +2498,36 @@
 \*****************************************************************************/
 
 #ifdef CONFIG_PM
+void sdhci_enable_irq_wakeups(struct sdhci_host *host)
+{
+	u8 val;
+	u8 mask = SDHCI_WAKE_ON_INSERT | SDHCI_WAKE_ON_REMOVE
+			| SDHCI_WAKE_ON_INT;
+
+	val = sdhci_readb(host, SDHCI_WAKE_UP_CONTROL);
+	val |= mask ;
+	/* Avoid fake wake up */
+	if (host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION)
+		val &= ~(SDHCI_WAKE_ON_INSERT | SDHCI_WAKE_ON_REMOVE);
+	sdhci_writeb(host, val, SDHCI_WAKE_UP_CONTROL);
+}
+EXPORT_SYMBOL_GPL(sdhci_enable_irq_wakeups);
+
+void sdhci_disable_irq_wakeups(struct sdhci_host *host)
+{
+	u8 val;
+	u8 mask = SDHCI_WAKE_ON_INSERT | SDHCI_WAKE_ON_REMOVE
+			| SDHCI_WAKE_ON_INT;
+
+	val = sdhci_readb(host, SDHCI_WAKE_UP_CONTROL);
+	val &= ~mask;
+	sdhci_writeb(host, val, SDHCI_WAKE_UP_CONTROL);
+}
+EXPORT_SYMBOL_GPL(sdhci_disable_irq_wakeups);
 
 int sdhci_suspend_host(struct sdhci_host *host)
 {
 	int ret;
-	bool has_tuning_timer;
 
 	if (host->ops->platform_suspend)
 		host->ops->platform_suspend(host);
@@ -2387,16 +2535,14 @@
 	sdhci_disable_card_detection(host);
 
 	/* Disable tuning since we are suspending */
-	has_tuning_timer = host->version >= SDHCI_SPEC_300 &&
-		host->tuning_count && host->tuning_mode == SDHCI_TUNING_MODE_1;
-	if (has_tuning_timer) {
+	if (host->flags & SDHCI_USING_RETUNING_TIMER) {
 		del_timer_sync(&host->tuning_timer);
 		host->flags &= ~SDHCI_NEEDS_RETUNING;
 	}
 
 	ret = mmc_suspend_host(host->mmc);
 	if (ret) {
-		if (has_tuning_timer) {
+		if (host->flags & SDHCI_USING_RETUNING_TIMER) {
 			host->flags |= SDHCI_NEEDS_RETUNING;
 			mod_timer(&host->tuning_timer, jiffies +
 					host->tuning_count * HZ);
@@ -2407,8 +2553,13 @@
 		return ret;
 	}
 
-	free_irq(host->irq, host);
-
+	if (!device_may_wakeup(mmc_dev(host->mmc))) {
+		sdhci_mask_irqs(host, SDHCI_INT_ALL_MASK);
+		free_irq(host->irq, host);
+	} else {
+		sdhci_enable_irq_wakeups(host);
+		enable_irq_wake(host->irq);
+	}
 	return ret;
 }
 
@@ -2423,10 +2574,15 @@
 			host->ops->enable_dma(host);
 	}
 
-	ret = request_irq(host->irq, sdhci_irq, IRQF_SHARED,
-			  mmc_hostname(host->mmc), host);
-	if (ret)
-		return ret;
+	if (!device_may_wakeup(mmc_dev(host->mmc))) {
+		ret = request_irq(host->irq, sdhci_irq, IRQF_SHARED,
+				  mmc_hostname(host->mmc), host);
+		if (ret)
+			return ret;
+	} else {
+		sdhci_disable_irq_wakeups(host);
+		disable_irq_wake(host->irq);
+	}
 
 	if ((host->mmc->pm_flags & MMC_PM_KEEP_POWER) &&
 	    (host->quirks2 & SDHCI_QUIRK2_HOST_OFF_CARD_ON)) {
@@ -2447,25 +2603,13 @@
 		host->ops->platform_resume(host);
 
 	/* Set the re-tuning expiration flag */
-	if ((host->version >= SDHCI_SPEC_300) && host->tuning_count &&
-	    (host->tuning_mode == SDHCI_TUNING_MODE_1))
+	if (host->flags & SDHCI_USING_RETUNING_TIMER)
 		host->flags |= SDHCI_NEEDS_RETUNING;
 
 	return ret;
 }
 
 EXPORT_SYMBOL_GPL(sdhci_resume_host);
-
-void sdhci_enable_irq_wakeups(struct sdhci_host *host)
-{
-	u8 val;
-	val = sdhci_readb(host, SDHCI_WAKE_UP_CONTROL);
-	val |= SDHCI_WAKE_ON_INT;
-	sdhci_writeb(host, val, SDHCI_WAKE_UP_CONTROL);
-}
-
-EXPORT_SYMBOL_GPL(sdhci_enable_irq_wakeups);
-
 #endif /* CONFIG_PM */
 
 #ifdef CONFIG_PM_RUNTIME
@@ -2487,8 +2631,7 @@
 	int ret = 0;
 
 	/* Disable tuning since we are suspending */
-	if (host->version >= SDHCI_SPEC_300 &&
-	    host->tuning_mode == SDHCI_TUNING_MODE_1) {
+	if (host->flags & SDHCI_USING_RETUNING_TIMER) {
 		del_timer_sync(&host->tuning_timer);
 		host->flags &= ~SDHCI_NEEDS_RETUNING;
 	}
@@ -2525,12 +2668,15 @@
 	sdhci_do_set_ios(host, &host->mmc->ios);
 
 	sdhci_do_start_signal_voltage_switch(host, &host->mmc->ios);
-	if (host_flags & SDHCI_PV_ENABLED)
-		sdhci_do_enable_preset_value(host, true);
+	if ((host_flags & SDHCI_PV_ENABLED) &&
+		!(host->quirks2 & SDHCI_QUIRK2_PRESET_VALUE_BROKEN)) {
+		spin_lock_irqsave(&host->lock, flags);
+		sdhci_enable_preset_value(host, true);
+		spin_unlock_irqrestore(&host->lock, flags);
+	}
 
 	/* Set the re-tuning expiration flag */
-	if ((host->version >= SDHCI_SPEC_300) && host->tuning_count &&
-	    (host->tuning_mode == SDHCI_TUNING_MODE_1))
+	if (host->flags & SDHCI_USING_RETUNING_TIMER)
 		host->flags |= SDHCI_NEEDS_RETUNING;
 
 	spin_lock_irqsave(&host->lock, flags);
@@ -2581,7 +2727,7 @@
 int sdhci_add_host(struct sdhci_host *host)
 {
 	struct mmc_host *mmc;
-	u32 caps[2];
+	u32 caps[2] = {0, 0};
 	u32 max_current_caps;
 	unsigned int ocr_avail;
 	int ret;
@@ -2611,8 +2757,10 @@
 	caps[0] = (host->quirks & SDHCI_QUIRK_MISSING_CAPS) ? host->caps :
 		sdhci_readl(host, SDHCI_CAPABILITIES);
 
-	caps[1] = (host->version >= SDHCI_SPEC_300) ?
-		sdhci_readl(host, SDHCI_CAPABILITIES_1) : 0;
+	if (host->version >= SDHCI_SPEC_300)
+		caps[1] = (host->quirks & SDHCI_QUIRK_MISSING_CAPS) ?
+			host->caps1 :
+			sdhci_readl(host, SDHCI_CAPABILITIES_1);
 
 	if (host->quirks & SDHCI_QUIRK_FORCE_DMA)
 		host->flags |= SDHCI_USE_SDMA;
@@ -2747,11 +2895,7 @@
 
 	mmc->max_discard_to = (1 << 27) / host->timeout_clk;
 
-#if defined(CONFIG_MACH_ORIGEN) && defined(CONFIG_ATH6KL_POLL)
-	mmc->caps |= MMC_CAP_ERASE | MMC_CAP_CMD23;
-#else
 	mmc->caps |= MMC_CAP_SDIO_IRQ | MMC_CAP_ERASE | MMC_CAP_CMD23;
-#endif
 
 	if (host->quirks & SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12)
 		host->flags |= SDHCI_AUTO_CMD12;
@@ -2776,13 +2920,42 @@
 	if (!(host->quirks & SDHCI_QUIRK_FORCE_1_BIT_DATA))
 		mmc->caps |= MMC_CAP_4_BIT_DATA;
 
+	if (host->quirks2 & SDHCI_QUIRK2_HOST_NO_CMD23)
+		mmc->caps &= ~MMC_CAP_CMD23;
+
 	if (caps[0] & SDHCI_CAN_DO_HISPD)
 		mmc->caps |= MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED;
 
 	if ((host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION) &&
-	    mmc_card_is_removable(mmc))
+	    !(host->mmc->caps & MMC_CAP_NONREMOVABLE))
 		mmc->caps |= MMC_CAP_NEEDS_POLL;
 
+	/* If vqmmc regulator and no 1.8V signalling, then there's no UHS */
+	host->vqmmc = regulator_get(mmc_dev(mmc), "vqmmc");
+	if (IS_ERR_OR_NULL(host->vqmmc)) {
+		if (PTR_ERR(host->vqmmc) < 0) {
+			pr_info("%s: no vqmmc regulator found\n",
+				mmc_hostname(mmc));
+			host->vqmmc = NULL;
+		}
+	} else {
+		ret = regulator_enable(host->vqmmc);
+		if (!regulator_is_supported_voltage(host->vqmmc, 1700000,
+			1950000))
+			caps[1] &= ~(SDHCI_SUPPORT_SDR104 |
+					SDHCI_SUPPORT_SDR50 |
+					SDHCI_SUPPORT_DDR50);
+		if (ret) {
+			pr_warn("%s: Failed to enable vqmmc regulator: %d\n",
+				mmc_hostname(mmc), ret);
+			host->vqmmc = NULL;
+		}
+	}
+
+	if (host->quirks2 & SDHCI_QUIRK2_NO_1_8_V)
+		caps[1] &= ~(SDHCI_SUPPORT_SDR104 | SDHCI_SUPPORT_SDR50 |
+		       SDHCI_SUPPORT_DDR50);
+
 	/* Any UHS-I mode in caps implies SDR12 and SDR25 support. */
 	if (caps[1] & (SDHCI_SUPPORT_SDR104 | SDHCI_SUPPORT_SDR50 |
 		       SDHCI_SUPPORT_DDR50))
@@ -2813,15 +2986,6 @@
 	if (caps[1] & SDHCI_DRIVER_TYPE_D)
 		mmc->caps |= MMC_CAP_DRIVER_TYPE_D;
 
-	/*
-	 * If Power Off Notify capability is enabled by the host,
-	 * set notify to short power off notify timeout value.
-	 */
-	if (mmc->caps2 & MMC_CAP2_POWEROFF_NOTIFY)
-		mmc->power_notify_type = MMC_HOST_PW_NOTIFY_SHORT;
-	else
-		mmc->power_notify_type = MMC_HOST_PW_NOTIFY_NONE;
-
 	/* Initial value for re-tuning timer count */
 	host->tuning_count = (caps[1] & SDHCI_RETUNING_TIMER_COUNT_MASK) >>
 			      SDHCI_RETUNING_TIMER_COUNT_SHIFT;
@@ -2838,6 +3002,35 @@
 			     SDHCI_RETUNING_MODE_SHIFT;
 
 	ocr_avail = 0;
+
+	host->vmmc = regulator_get(mmc_dev(mmc), "vmmc");
+	if (IS_ERR_OR_NULL(host->vmmc)) {
+		if (PTR_ERR(host->vmmc) < 0) {
+			pr_info("%s: no vmmc regulator found\n",
+				mmc_hostname(mmc));
+			host->vmmc = NULL;
+		}
+	}
+
+#ifdef CONFIG_REGULATOR
+	/*
+	 * Voltage range check makes sense only if regulator reports
+	 * any voltage value.
+	 */
+	if (host->vmmc && regulator_get_voltage(host->vmmc) > 0) {
+		ret = regulator_is_supported_voltage(host->vmmc, 2700000,
+			3600000);
+		if ((ret <= 0) || (!(caps[0] & SDHCI_CAN_VDD_330)))
+			caps[0] &= ~SDHCI_CAN_VDD_330;
+		if ((ret <= 0) || (!(caps[0] & SDHCI_CAN_VDD_300)))
+			caps[0] &= ~SDHCI_CAN_VDD_300;
+		ret = regulator_is_supported_voltage(host->vmmc, 1700000,
+			1950000);
+		if ((ret <= 0) || (!(caps[0] & SDHCI_CAN_VDD_180)))
+			caps[0] &= ~SDHCI_CAN_VDD_180;
+	}
+#endif /* CONFIG_REGULATOR */
+
 	/*
 	 * According to SD Host Controller spec v3.00, if the Host System
 	 * can afford more than 150mA, Host Driver should set XPC to 1. Also
@@ -2846,55 +3039,45 @@
 	 * value.
 	 */
 	max_current_caps = sdhci_readl(host, SDHCI_MAX_CURRENT);
+	if (!max_current_caps && host->vmmc) {
+		u32 curr = regulator_get_current_limit(host->vmmc);
+		if (curr > 0) {
+
+			/* convert to SDHCI_MAX_CURRENT format */
+			curr = curr/1000;  /* convert to mA */
+			curr = curr/SDHCI_MAX_CURRENT_MULTIPLIER;
+
+			curr = min_t(u32, curr, SDHCI_MAX_CURRENT_LIMIT);
+			max_current_caps =
+				(curr << SDHCI_MAX_CURRENT_330_SHIFT) |
+				(curr << SDHCI_MAX_CURRENT_300_SHIFT) |
+				(curr << SDHCI_MAX_CURRENT_180_SHIFT);
+		}
+	}
 
 	if (caps[0] & SDHCI_CAN_VDD_330) {
-		int max_current_330;
-
 		ocr_avail |= MMC_VDD_32_33 | MMC_VDD_33_34;
 
-		max_current_330 = ((max_current_caps &
+		mmc->max_current_330 = ((max_current_caps &
 				   SDHCI_MAX_CURRENT_330_MASK) >>
 				   SDHCI_MAX_CURRENT_330_SHIFT) *
 				   SDHCI_MAX_CURRENT_MULTIPLIER;
-
-		if (max_current_330 > 150)
-			mmc->caps |= MMC_CAP_SET_XPC_330;
 	}
 	if (caps[0] & SDHCI_CAN_VDD_300) {
-		int max_current_300;
-
 		ocr_avail |= MMC_VDD_29_30 | MMC_VDD_30_31;
 
-		max_current_300 = ((max_current_caps &
+		mmc->max_current_300 = ((max_current_caps &
 				   SDHCI_MAX_CURRENT_300_MASK) >>
 				   SDHCI_MAX_CURRENT_300_SHIFT) *
 				   SDHCI_MAX_CURRENT_MULTIPLIER;
-
-		if (max_current_300 > 150)
-			mmc->caps |= MMC_CAP_SET_XPC_300;
 	}
 	if (caps[0] & SDHCI_CAN_VDD_180) {
-		int max_current_180;
-
 		ocr_avail |= MMC_VDD_165_195;
 
-		max_current_180 = ((max_current_caps &
+		mmc->max_current_180 = ((max_current_caps &
 				   SDHCI_MAX_CURRENT_180_MASK) >>
 				   SDHCI_MAX_CURRENT_180_SHIFT) *
 				   SDHCI_MAX_CURRENT_MULTIPLIER;
-
-		if (max_current_180 > 150)
-			mmc->caps |= MMC_CAP_SET_XPC_180;
-
-		/* Maximum current capabilities of the host at 1.8V */
-		if (max_current_180 >= 800)
-			mmc->caps |= MMC_CAP_MAX_CURRENT_800;
-		else if (max_current_180 >= 600)
-			mmc->caps |= MMC_CAP_MAX_CURRENT_600;
-		else if (max_current_180 >= 400)
-			mmc->caps |= MMC_CAP_MAX_CURRENT_400;
-		else
-			mmc->caps |= MMC_CAP_MAX_CURRENT_200;
 	}
 
 	mmc->ocr_avail = ocr_avail;
@@ -2993,13 +3176,10 @@
 
 	ret = request_irq(host->irq, sdhci_irq, IRQF_SHARED,
 		mmc_hostname(mmc), host);
-	if (ret)
+	if (ret) {
+		pr_err("%s: Failed to request IRQ %d: %d\n",
+		       mmc_hostname(mmc), host->irq, ret);
 		goto untasklet;
-
-	host->vmmc = regulator_get(mmc_dev(mmc), "vmmc");
-	if (IS_ERR(host->vmmc)) {
-		pr_info("%s: no vmmc regulator found\n", mmc_hostname(mmc));
-		host->vmmc = NULL;
 	}
 
 	sdhci_init(host, 0);
@@ -3017,8 +3197,11 @@
 	host->led.brightness_set = sdhci_led_control;
 
 	ret = led_classdev_register(mmc_dev(mmc), &host->led);
-	if (ret)
+	if (ret) {
+		pr_err("%s: Failed to register LED device: %d\n",
+		       mmc_hostname(mmc), ret);
 		goto reset;
+	}
 #endif
 
 	mmiowb();
@@ -3037,6 +3220,7 @@
 #ifdef SDHCI_USE_LEDS_CLASS
 reset:
 	sdhci_reset(host, SDHCI_RESET_ALL);
+	sdhci_mask_irqs(host, SDHCI_INT_ALL_MASK);
 	free_irq(host->irq, host);
 #endif
 untasklet:
@@ -3079,17 +3263,23 @@
 	if (!dead)
 		sdhci_reset(host, SDHCI_RESET_ALL);
 
+	sdhci_mask_irqs(host, SDHCI_INT_ALL_MASK);
 	free_irq(host->irq, host);
 
 	del_timer_sync(&host->timer);
-	if (host->version >= SDHCI_SPEC_300)
-		del_timer_sync(&host->tuning_timer);
 
 	tasklet_kill(&host->card_tasklet);
 	tasklet_kill(&host->finish_tasklet);
 
-	if (host->vmmc)
+	if (host->vmmc) {
+		regulator_disable(host->vmmc);
 		regulator_put(host->vmmc);
+	}
+
+	if (host->vqmmc) {
+		regulator_disable(host->vqmmc);
+		regulator_put(host->vqmmc);
+	}
 
 	kfree(host->adma_desc);
 	kfree(host->align_buffer);
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/sdhci-cns3xxx.c linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/sdhci-cns3xxx.c
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/sdhci-cns3xxx.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/sdhci-cns3xxx.c	2014-09-12 15:59:37.348052000 +0800
@@ -16,7 +16,6 @@
 #include <linux/device.h>
 #include <linux/mmc/host.h>
 #include <linux/module.h>
-#include <mach/cns3xxx.h>
 #include "sdhci-pltfm.h"
 
 static unsigned int sdhci_cns3xxx_get_max_clk(struct sdhci_host *host)
@@ -80,12 +79,12 @@
 	host->clock = clock;
 }
 
-static struct sdhci_ops sdhci_cns3xxx_ops = {
+static const struct sdhci_ops sdhci_cns3xxx_ops = {
 	.get_max_clock	= sdhci_cns3xxx_get_max_clk,
 	.set_clock	= sdhci_cns3xxx_set_clock,
 };
 
-static struct sdhci_pltfm_data sdhci_cns3xxx_pdata = {
+static const struct sdhci_pltfm_data sdhci_cns3xxx_pdata = {
 	.ops = &sdhci_cns3xxx_ops,
 	.quirks = SDHCI_QUIRK_BROKEN_DMA |
 		  SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK |
@@ -95,12 +94,12 @@
 		  SDHCI_QUIRK_NONSTANDARD_CLOCK,
 };
 
-static int __devinit sdhci_cns3xxx_probe(struct platform_device *pdev)
+static int sdhci_cns3xxx_probe(struct platform_device *pdev)
 {
 	return sdhci_pltfm_register(pdev, &sdhci_cns3xxx_pdata);
 }
 
-static int __devexit sdhci_cns3xxx_remove(struct platform_device *pdev)
+static int sdhci_cns3xxx_remove(struct platform_device *pdev)
 {
 	return sdhci_pltfm_unregister(pdev);
 }
@@ -112,7 +111,7 @@
 		.pm	= SDHCI_PLTFM_PMOPS,
 	},
 	.probe		= sdhci_cns3xxx_probe,
-	.remove		= __devexit_p(sdhci_cns3xxx_remove),
+	.remove		= sdhci_cns3xxx_remove,
 };
 
 module_platform_driver(sdhci_cns3xxx_driver);
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/sdhci-dove.c linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/sdhci-dove.c
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/sdhci-dove.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/sdhci-dove.c	2014-09-12 15:59:37.348052000 +0800
@@ -19,12 +19,30 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/gpio.h>
 #include <linux/io.h>
-#include <linux/module.h>
 #include <linux/mmc/host.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
 
 #include "sdhci-pltfm.h"
 
+struct sdhci_dove_priv {
+	struct clk *clk;
+	int gpio_cd;
+};
+
+static irqreturn_t sdhci_dove_carddetect_irq(int irq, void *data)
+{
+	struct sdhci_host *host = data;
+
+	tasklet_schedule(&host->card_tasklet);
+	return IRQ_HANDLED;
+}
+
 static u16 sdhci_dove_readw(struct sdhci_host *host, int reg)
 {
 	u16 ret;
@@ -42,51 +60,158 @@
 
 static u32 sdhci_dove_readl(struct sdhci_host *host, int reg)
 {
+	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+	struct sdhci_dove_priv *priv = pltfm_host->priv;
 	u32 ret;
 
+	ret = readl(host->ioaddr + reg);
+
 	switch (reg) {
 	case SDHCI_CAPABILITIES:
-		ret = readl(host->ioaddr + reg);
 		/* Mask the support for 3.0V */
 		ret &= ~SDHCI_CAN_VDD_300;
 		break;
-	default:
-		ret = readl(host->ioaddr + reg);
+	case SDHCI_PRESENT_STATE:
+		if (gpio_is_valid(priv->gpio_cd)) {
+			if (gpio_get_value(priv->gpio_cd) == 0)
+				ret |= SDHCI_CARD_PRESENT;
+			else
+				ret &= ~SDHCI_CARD_PRESENT;
+		}
+		break;
 	}
 	return ret;
 }
 
-static struct sdhci_ops sdhci_dove_ops = {
+static const struct sdhci_ops sdhci_dove_ops = {
 	.read_w	= sdhci_dove_readw,
 	.read_l	= sdhci_dove_readl,
 };
 
-static struct sdhci_pltfm_data sdhci_dove_pdata = {
+static const struct sdhci_pltfm_data sdhci_dove_pdata = {
 	.ops	= &sdhci_dove_ops,
 	.quirks	= SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER |
 		  SDHCI_QUIRK_NO_BUSY_IRQ |
 		  SDHCI_QUIRK_BROKEN_TIMEOUT_VAL |
-		  SDHCI_QUIRK_FORCE_DMA,
+		  SDHCI_QUIRK_FORCE_DMA |
+		  SDHCI_QUIRK_NO_HISPD_BIT,
 };
 
-static int __devinit sdhci_dove_probe(struct platform_device *pdev)
+static int sdhci_dove_probe(struct platform_device *pdev)
 {
-	return sdhci_pltfm_register(pdev, &sdhci_dove_pdata);
+	struct sdhci_host *host;
+	struct sdhci_pltfm_host *pltfm_host;
+	struct sdhci_dove_priv *priv;
+	int ret;
+
+	priv = devm_kzalloc(&pdev->dev, sizeof(struct sdhci_dove_priv),
+			    GFP_KERNEL);
+	if (!priv) {
+		dev_err(&pdev->dev, "unable to allocate private data");
+		return -ENOMEM;
+	}
+
+	priv->clk = devm_clk_get(&pdev->dev, NULL);
+
+	if (pdev->dev.of_node) {
+		priv->gpio_cd = of_get_named_gpio(pdev->dev.of_node,
+						  "cd-gpios", 0);
+	} else {
+		priv->gpio_cd = -EINVAL;
+	}
+
+	if (gpio_is_valid(priv->gpio_cd)) {
+		ret = gpio_request(priv->gpio_cd, "sdhci-cd");
+		if (ret) {
+			dev_err(&pdev->dev, "card detect gpio request failed: %d\n",
+				ret);
+			return ret;
+		}
+		gpio_direction_input(priv->gpio_cd);
+	}
+
+	host = sdhci_pltfm_init(pdev, &sdhci_dove_pdata);
+	if (IS_ERR(host)) {
+		ret = PTR_ERR(host);
+		goto err_sdhci_pltfm_init;
+	}
+
+	pltfm_host = sdhci_priv(host);
+	pltfm_host->priv = priv;
+
+	if (!IS_ERR(priv->clk))
+		clk_prepare_enable(priv->clk);
+
+	sdhci_get_of_property(pdev);
+
+	ret = sdhci_add_host(host);
+	if (ret)
+		goto err_sdhci_add;
+
+	/*
+	 * We must request the IRQ after sdhci_add_host(), as the tasklet only
+	 * gets setup in sdhci_add_host() and we oops.
+	 */
+	if (gpio_is_valid(priv->gpio_cd)) {
+		ret = request_irq(gpio_to_irq(priv->gpio_cd),
+				  sdhci_dove_carddetect_irq,
+				  IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
+				  mmc_hostname(host->mmc), host);
+		if (ret) {
+			dev_err(&pdev->dev, "card detect irq request failed: %d\n",
+				ret);
+			goto err_request_irq;
+		}
+	}
+
+	return 0;
+
+err_request_irq:
+	sdhci_remove_host(host, 0);
+err_sdhci_add:
+	if (!IS_ERR(priv->clk))
+		clk_disable_unprepare(priv->clk);
+	sdhci_pltfm_free(pdev);
+err_sdhci_pltfm_init:
+	if (gpio_is_valid(priv->gpio_cd))
+		gpio_free(priv->gpio_cd);
+	return ret;
 }
 
-static int __devexit sdhci_dove_remove(struct platform_device *pdev)
+static int sdhci_dove_remove(struct platform_device *pdev)
 {
-	return sdhci_pltfm_unregister(pdev);
+	struct sdhci_host *host = platform_get_drvdata(pdev);
+	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+	struct sdhci_dove_priv *priv = pltfm_host->priv;
+
+	sdhci_pltfm_unregister(pdev);
+
+	if (gpio_is_valid(priv->gpio_cd)) {
+		free_irq(gpio_to_irq(priv->gpio_cd), host);
+		gpio_free(priv->gpio_cd);
+	}
+
+	if (!IS_ERR(priv->clk))
+		clk_disable_unprepare(priv->clk);
+
+	return 0;
 }
 
+static const struct of_device_id sdhci_dove_of_match_table[] = {
+	{ .compatible = "marvell,dove-sdhci", },
+	{}
+};
+MODULE_DEVICE_TABLE(of, sdhci_dove_of_match_table);
+
 static struct platform_driver sdhci_dove_driver = {
 	.driver		= {
 		.name	= "sdhci-dove",
 		.owner	= THIS_MODULE,
 		.pm	= SDHCI_PLTFM_PMOPS,
+		.of_match_table = of_match_ptr(sdhci_dove_of_match_table),
 	},
 	.probe		= sdhci_dove_probe,
-	.remove		= __devexit_p(sdhci_dove_remove),
+	.remove		= sdhci_dove_remove,
 };
 
 module_platform_driver(sdhci_dove_driver);
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/sdhci-esdhc.h linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/sdhci-esdhc.h
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/sdhci-esdhc.h	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/sdhci-esdhc.h	2014-09-12 15:59:37.348052000 +0800
@@ -48,14 +48,14 @@
 	int div = 1;
 	u32 temp;
 
+	if (clock == 0)
+		goto out;
+
 	temp = sdhci_readl(host, ESDHC_SYSTEM_CONTROL);
 	temp &= ~(ESDHC_CLOCK_IPGEN | ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN
 		| ESDHC_CLOCK_MASK);
 	sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL);
 
-	if (clock == 0)
-		goto out;
-
 	while (host->max_clk / pre_div / 16 > clock && pre_div < 256)
 		pre_div *= 2;
 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/sdhci-esdhc-imx.c linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/sdhci-esdhc-imx.c
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/sdhci-esdhc-imx.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/sdhci-esdhc-imx.c	2014-09-12 15:59:37.348052000 +0800
@@ -21,19 +21,31 @@
 #include <linux/mmc/host.h>
 #include <linux/mmc/mmc.h>
 #include <linux/mmc/sdio.h>
+#include <linux/mmc/slot-gpio.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
 #include <linux/of_gpio.h>
-#include <mach/esdhc.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/platform_data/mmc-esdhc-imx.h>
 #include "sdhci-pltfm.h"
 #include "sdhci-esdhc.h"
 
-#define	SDHCI_CTRL_D3CD			0x08
+#define	ESDHC_CTRL_D3CD			0x08
 /* VENDOR SPEC register */
-#define SDHCI_VENDOR_SPEC		0xC0
-#define  SDHCI_VENDOR_SPEC_SDIO_QUIRK	0x00000002
-#define SDHCI_WTMK_LVL			0x44
-#define SDHCI_MIX_CTRL			0x48
+#define ESDHC_VENDOR_SPEC		0xc0
+#define  ESDHC_VENDOR_SPEC_SDIO_QUIRK	(1 << 1)
+#define ESDHC_WTMK_LVL			0x44
+#define ESDHC_MIX_CTRL			0x48
+#define  ESDHC_MIX_CTRL_AC23EN		(1 << 7)
+/* Bits 3 and 6 are not SDHCI standard definitions */
+#define  ESDHC_MIX_CTRL_SDHCI_MASK	0xb7
+
+/*
+ * Our interpretation of the SDHCI_HOST_CONTROL register
+ */
+#define ESDHC_CTRL_4BITBUS		(0x1 << 1)
+#define ESDHC_CTRL_8BITBUS		(0x2 << 1)
+#define ESDHC_CTRL_BUSWIDTH_MASK	(0x3 << 1)
 
 /*
  * There is an INT DMA ERR mis-match between eSDHC and STD SDHC SPEC:
@@ -41,7 +53,7 @@
  * but bit28 is used as the INT DMA ERR in fsl eSDHC design.
  * Define this macro DMA error INT for fsl eSDHC
  */
-#define SDHCI_INT_VENDOR_SPEC_DMA_ERR	0x10000000
+#define ESDHC_INT_VENDOR_SPEC_DMA_ERR	(1 << 28)
 
 /*
  * The CMDTYPE of the CMD register (offset 0xE) should be set to
@@ -68,7 +80,17 @@
 	int flags;
 	u32 scratchpad;
 	enum imx_esdhc_type devtype;
+	struct pinctrl *pinctrl;
 	struct esdhc_platform_data boarddata;
+	struct clk *clk_ipg;
+	struct clk *clk_ahb;
+	struct clk *clk_per;
+	enum {
+		NO_CMD_PENDING,      /* no multiblock command pending*/
+		MULTIBLK_IN_PROCESS, /* exact multiblock cmd in process */
+		WAIT_FOR_INT,        /* sent CMD12, waiting for response INT */
+	} multiblock_status;
+
 };
 
 static struct platform_device_id imx_esdhc_devtype[] = {
@@ -140,21 +162,8 @@
 {
 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
 	struct pltfm_imx_data *imx_data = pltfm_host->priv;
-	struct esdhc_platform_data *boarddata = &imx_data->boarddata;
-
-	/* fake CARD_PRESENT flag */
 	u32 val = readl(host->ioaddr + reg);
 
-	if (unlikely((reg == SDHCI_PRESENT_STATE)
-			&& gpio_is_valid(boarddata->cd_gpio))) {
-		if (gpio_get_value(boarddata->cd_gpio))
-			/* no card, if a valid gpio says so... */
-			val &= ~SDHCI_CARD_PRESENT;
-		else
-			/* ... in all other cases assume card is present */
-			val |= SDHCI_CARD_PRESENT;
-	}
-
 	if (unlikely(reg == SDHCI_CAPABILITIES)) {
 		/* In FSL esdhc IC module, only bit20 is used to indicate the
 		 * ADMA2 capability of esdhc, but this bit is messed up on
@@ -170,10 +179,22 @@
 	}
 
 	if (unlikely(reg == SDHCI_INT_STATUS)) {
-		if (val & SDHCI_INT_VENDOR_SPEC_DMA_ERR) {
-			val &= ~SDHCI_INT_VENDOR_SPEC_DMA_ERR;
+		if (val & ESDHC_INT_VENDOR_SPEC_DMA_ERR) {
+			val &= ~ESDHC_INT_VENDOR_SPEC_DMA_ERR;
 			val |= SDHCI_INT_ADMA_ERROR;
 		}
+
+		/*
+		 * mask off the interrupt we get in response to the manually
+		 * sent CMD12
+		 */
+		if ((imx_data->multiblock_status == WAIT_FOR_INT) &&
+		    ((val & SDHCI_INT_RESPONSE) == SDHCI_INT_RESPONSE)) {
+			val &= ~SDHCI_INT_RESPONSE;
+			writel(SDHCI_INT_RESPONSE, host->ioaddr +
+						   SDHCI_INT_STATUS);
+			imx_data->multiblock_status = NO_CMD_PENDING;
+		}
 	}
 
 	return val;
@@ -183,17 +204,9 @@
 {
 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
 	struct pltfm_imx_data *imx_data = pltfm_host->priv;
-	struct esdhc_platform_data *boarddata = &imx_data->boarddata;
 	u32 data;
 
 	if (unlikely(reg == SDHCI_INT_ENABLE || reg == SDHCI_SIGNAL_ENABLE)) {
-		if (boarddata->cd_type == ESDHC_CD_GPIO)
-			/*
-			 * These interrupts won't work with a custom
-			 * card_detect gpio (only applied to mx25/35)
-			 */
-			val &= ~(SDHCI_INT_CARD_REMOVE | SDHCI_INT_CARD_INSERT);
-
 		if (val & SDHCI_INT_CARD_INT) {
 			/*
 			 * Clear and then set D3CD bit to avoid missing the
@@ -204,9 +217,9 @@
 			 * re-sample it by the following steps.
 			 */
 			data = readl(host->ioaddr + SDHCI_HOST_CONTROL);
-			data &= ~SDHCI_CTRL_D3CD;
+			data &= ~ESDHC_CTRL_D3CD;
 			writel(data, host->ioaddr + SDHCI_HOST_CONTROL);
-			data |= SDHCI_CTRL_D3CD;
+			data |= ESDHC_CTRL_D3CD;
 			writel(data, host->ioaddr + SDHCI_HOST_CONTROL);
 		}
 	}
@@ -215,15 +228,24 @@
 				&& (reg == SDHCI_INT_STATUS)
 				&& (val & SDHCI_INT_DATA_END))) {
 			u32 v;
-			v = readl(host->ioaddr + SDHCI_VENDOR_SPEC);
-			v &= ~SDHCI_VENDOR_SPEC_SDIO_QUIRK;
-			writel(v, host->ioaddr + SDHCI_VENDOR_SPEC);
+			v = readl(host->ioaddr + ESDHC_VENDOR_SPEC);
+			v &= ~ESDHC_VENDOR_SPEC_SDIO_QUIRK;
+			writel(v, host->ioaddr + ESDHC_VENDOR_SPEC);
+
+			if (imx_data->multiblock_status == MULTIBLK_IN_PROCESS)
+			{
+				/* send a manual CMD12 with RESPTYP=none */
+				data = MMC_STOP_TRANSMISSION << 24 |
+				       SDHCI_CMD_ABORTCMD << 16;
+				writel(data, host->ioaddr + SDHCI_TRANSFER_MODE);
+				imx_data->multiblock_status = WAIT_FOR_INT;
+			}
 	}
 
 	if (unlikely(reg == SDHCI_INT_ENABLE || reg == SDHCI_SIGNAL_ENABLE)) {
 		if (val & SDHCI_INT_ADMA_ERROR) {
 			val &= ~SDHCI_INT_ADMA_ERROR;
-			val |= SDHCI_INT_VENDOR_SPEC_DMA_ERR;
+			val |= ESDHC_INT_VENDOR_SPEC_DMA_ERR;
 		}
 	}
 
@@ -232,15 +254,18 @@
 
 static u16 esdhc_readw_le(struct sdhci_host *host, int reg)
 {
+	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+	struct pltfm_imx_data *imx_data = pltfm_host->priv;
+
 	if (unlikely(reg == SDHCI_HOST_VERSION)) {
-		u16 val = readw(host->ioaddr + (reg ^ 2));
-		/*
-		 * uSDHC supports SDHCI v3.0, but it's encoded as value
-		 * 0x3 in host controller version register, which violates
-		 * SDHCI_SPEC_300 definition.  Work it around here.
-		 */
-		if ((val & SDHCI_SPEC_VER_MASK) == 3)
-			return --val;
+		reg ^= 2;
+		if (is_imx6q_usdhc(imx_data)) {
+			/*
+			 * The usdhc register returns a wrong host version.
+			 * Correct it here.
+			 */
+			return SDHCI_SPEC_300;
+		}
 	}
 
 	return readw(host->ioaddr + reg);
@@ -253,37 +278,47 @@
 
 	switch (reg) {
 	case SDHCI_TRANSFER_MODE:
-		/*
-		 * Postpone this write, we must do it together with a
-		 * command write that is down below.
-		 */
 		if ((imx_data->flags & ESDHC_FLAG_MULTIBLK_NO_INT)
 				&& (host->cmd->opcode == SD_IO_RW_EXTENDED)
 				&& (host->cmd->data->blocks > 1)
 				&& (host->cmd->data->flags & MMC_DATA_READ)) {
 			u32 v;
-			v = readl(host->ioaddr + SDHCI_VENDOR_SPEC);
-			v |= SDHCI_VENDOR_SPEC_SDIO_QUIRK;
-			writel(v, host->ioaddr + SDHCI_VENDOR_SPEC);
+			v = readl(host->ioaddr + ESDHC_VENDOR_SPEC);
+			v |= ESDHC_VENDOR_SPEC_SDIO_QUIRK;
+			writel(v, host->ioaddr + ESDHC_VENDOR_SPEC);
+		}
+
+		if (is_imx6q_usdhc(imx_data)) {
+			u32 m = readl(host->ioaddr + ESDHC_MIX_CTRL);
+			/* Swap AC23 bit */
+			if (val & SDHCI_TRNS_AUTO_CMD23) {
+				val &= ~SDHCI_TRNS_AUTO_CMD23;
+				val |= ESDHC_MIX_CTRL_AC23EN;
+			}
+			m = val | (m & ~ESDHC_MIX_CTRL_SDHCI_MASK);
+			writel(m, host->ioaddr + ESDHC_MIX_CTRL);
+		} else {
+			/*
+			 * Postpone this write, we must do it together with a
+			 * command write that is down below.
+			 */
+			imx_data->scratchpad = val;
 		}
-		imx_data->scratchpad = val;
 		return;
 	case SDHCI_COMMAND:
-		if ((host->cmd->opcode == MMC_STOP_TRANSMISSION ||
-		     host->cmd->opcode == MMC_SET_BLOCK_COUNT) &&
-	            (imx_data->flags & ESDHC_FLAG_MULTIBLK_NO_INT))
+		if (host->cmd->opcode == MMC_STOP_TRANSMISSION)
 			val |= SDHCI_CMD_ABORTCMD;
 
-		if (is_imx6q_usdhc(imx_data)) {
-			u32 m = readl(host->ioaddr + SDHCI_MIX_CTRL);
-			m = imx_data->scratchpad | (m & 0xffff0000);
-			writel(m, host->ioaddr + SDHCI_MIX_CTRL);
+		if ((host->cmd->opcode == MMC_SET_BLOCK_COUNT) &&
+		    (imx_data->flags & ESDHC_FLAG_MULTIBLK_NO_INT))
+			imx_data->multiblock_status = MULTIBLK_IN_PROCESS;
+
+		if (is_imx6q_usdhc(imx_data))
 			writel(val << 16,
 			       host->ioaddr + SDHCI_TRANSFER_MODE);
-		} else {
+		else
 			writel(val << 16 | imx_data->scratchpad,
 			       host->ioaddr + SDHCI_TRANSFER_MODE);
-		}
 		return;
 	case SDHCI_BLOCK_SIZE:
 		val &= ~SDHCI_MAKE_BLKSZ(0x7, 0);
@@ -294,7 +329,10 @@
 
 static void esdhc_writeb_le(struct sdhci_host *host, u8 val, int reg)
 {
+	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+	struct pltfm_imx_data *imx_data = pltfm_host->priv;
 	u32 new_val;
+	u32 mask;
 
 	switch (reg) {
 	case SDHCI_POWER_CONTROL:
@@ -304,16 +342,25 @@
 		 */
 		return;
 	case SDHCI_HOST_CONTROL:
-		/* FSL messed up here, so we can just keep those three */
-		new_val = val & (SDHCI_CTRL_LED | \
-				SDHCI_CTRL_4BITBUS | \
-				SDHCI_CTRL_D3CD);
-		/* ensure the endianess */
+		/* FSL messed up here, so we need to manually compose it. */
+		new_val = val & SDHCI_CTRL_LED;
+		/* ensure the endianness */
 		new_val |= ESDHC_HOST_CONTROL_LE;
-		/* DMA mode bits are shifted */
-		new_val |= (val & SDHCI_CTRL_DMA_MASK) << 5;
+		/* bits 8&9 are reserved on mx25 */
+		if (!is_imx25_esdhc(imx_data)) {
+			/* DMA mode bits are shifted */
+			new_val |= (val & SDHCI_CTRL_DMA_MASK) << 5;
+		}
 
-		esdhc_clrset_le(host, 0xffff, new_val, reg);
+		/*
+		 * Do not touch buswidth bits here. This is done in
+		 * esdhc_pltfm_bus_width.
+		 * Do not touch the D3CD bit either which is used for the
+		 * SDIO interrupt errata workaround.
+		 */
+		mask = 0xffff & ~(ESDHC_CTRL_BUSWIDTH_MASK | ESDHC_CTRL_D3CD);
+
+		esdhc_clrset_le(host, mask, new_val, reg);
 		return;
 	}
 	esdhc_clrset_le(host, 0xff, val, reg);
@@ -326,15 +373,15 @@
 	 * circuit relies on.  To work around it, we turn the clocks on back
 	 * to keep card detection circuit functional.
 	 */
-	if ((reg == SDHCI_SOFTWARE_RESET) && (val & 1))
+	if ((reg == SDHCI_SOFTWARE_RESET) && (val & 1)) {
 		esdhc_clrset_le(host, 0x7, 0x7, ESDHC_SYSTEM_CONTROL);
-}
-
-static unsigned int esdhc_pltfm_get_max_clock(struct sdhci_host *host)
-{
-	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
-
-	return clk_get_rate(pltfm_host->clk);
+		/*
+		 * The reset on usdhc fails to clear MIX_CTRL register.
+		 * Do it manually here.
+		 */
+		if (is_imx6q_usdhc(imx_data))
+			writel(0, host->ioaddr + ESDHC_MIX_CTRL);
+	}
 }
 
 static unsigned int esdhc_pltfm_get_min_clock(struct sdhci_host *host)
@@ -352,8 +399,7 @@
 
 	switch (boarddata->wp_type) {
 	case ESDHC_WP_GPIO:
-		if (gpio_is_valid(boarddata->wp_gpio))
-			return gpio_get_value(boarddata->wp_gpio);
+		return mmc_gpio_get_ro(host->mmc);
 	case ESDHC_WP_CONTROLLER:
 		return !(readl(host->ioaddr + SDHCI_PRESENT_STATE) &
 			       SDHCI_WRITE_PROTECT);
@@ -364,19 +410,42 @@
 	return -ENOSYS;
 }
 
-static struct sdhci_ops sdhci_esdhc_ops = {
+static int esdhc_pltfm_bus_width(struct sdhci_host *host, int width)
+{
+	u32 ctrl;
+
+	switch (width) {
+	case MMC_BUS_WIDTH_8:
+		ctrl = ESDHC_CTRL_8BITBUS;
+		break;
+	case MMC_BUS_WIDTH_4:
+		ctrl = ESDHC_CTRL_4BITBUS;
+		break;
+	default:
+		ctrl = 0;
+		break;
+	}
+
+	esdhc_clrset_le(host, ESDHC_CTRL_BUSWIDTH_MASK, ctrl,
+			SDHCI_HOST_CONTROL);
+
+	return 0;
+}
+
+static const struct sdhci_ops sdhci_esdhc_ops = {
 	.read_l = esdhc_readl_le,
 	.read_w = esdhc_readw_le,
 	.write_l = esdhc_writel_le,
 	.write_w = esdhc_writew_le,
 	.write_b = esdhc_writeb_le,
 	.set_clock = esdhc_set_clock,
-	.get_max_clock = esdhc_pltfm_get_max_clock,
+	.get_max_clock = sdhci_pltfm_clk_get_max_clock,
 	.get_min_clock = esdhc_pltfm_get_min_clock,
 	.get_ro = esdhc_pltfm_get_ro,
+	.platform_bus_width = esdhc_pltfm_bus_width,
 };
 
-static struct sdhci_pltfm_data sdhci_esdhc_imx_pdata = {
+static const struct sdhci_pltfm_data sdhci_esdhc_imx_pdata = {
 	.quirks = ESDHC_DEFAULT_QUIRKS | SDHCI_QUIRK_NO_HISPD_BIT
 			| SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC
 			| SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC
@@ -384,16 +453,8 @@
 	.ops = &sdhci_esdhc_ops,
 };
 
-static irqreturn_t cd_irq(int irq, void *data)
-{
-	struct sdhci_host *sdhost = (struct sdhci_host *)data;
-
-	tasklet_schedule(&sdhost->card_tasklet);
-	return IRQ_HANDLED;
-};
-
 #ifdef CONFIG_OF
-static int __devinit
+static int
 sdhci_esdhc_imx_probe_dt(struct platform_device *pdev,
 			 struct esdhc_platform_data *boarddata)
 {
@@ -402,7 +463,7 @@
 	if (!np)
 		return -ENODEV;
 
-	if (of_get_property(np, "fsl,card-wired", NULL))
+	if (of_get_property(np, "non-removable", NULL))
 		boarddata->cd_type = ESDHC_CD_PERMANENT;
 
 	if (of_get_property(np, "fsl,cd-controller", NULL))
@@ -419,6 +480,8 @@
 	if (gpio_is_valid(boarddata->wp_gpio))
 		boarddata->wp_type = ESDHC_WP_GPIO;
 
+	of_property_read_u32(np, "bus-width", &boarddata->max_bus_width);
+
 	return 0;
 }
 #else
@@ -430,14 +493,13 @@
 }
 #endif
 
-static int __devinit sdhci_esdhc_imx_probe(struct platform_device *pdev)
+static int sdhci_esdhc_imx_probe(struct platform_device *pdev)
 {
 	const struct of_device_id *of_id =
 			of_match_device(imx_esdhc_dt_ids, &pdev->dev);
 	struct sdhci_pltfm_host *pltfm_host;
 	struct sdhci_host *host;
 	struct esdhc_platform_data *boarddata;
-	struct clk *clk;
 	int err;
 	struct pltfm_imx_data *imx_data;
 
@@ -447,10 +509,10 @@
 
 	pltfm_host = sdhci_priv(host);
 
-	imx_data = kzalloc(sizeof(struct pltfm_imx_data), GFP_KERNEL);
+	imx_data = devm_kzalloc(&pdev->dev, sizeof(*imx_data), GFP_KERNEL);
 	if (!imx_data) {
 		err = -ENOMEM;
-		goto err_imx_data;
+		goto free_sdhci;
 	}
 
 	if (of_id)
@@ -458,14 +520,35 @@
 	imx_data->devtype = pdev->id_entry->driver_data;
 	pltfm_host->priv = imx_data;
 
-	clk = clk_get(mmc_dev(host->mmc), NULL);
-	if (IS_ERR(clk)) {
-		dev_err(mmc_dev(host->mmc), "clk err\n");
-		err = PTR_ERR(clk);
-		goto err_clk_get;
+	imx_data->clk_ipg = devm_clk_get(&pdev->dev, "ipg");
+	if (IS_ERR(imx_data->clk_ipg)) {
+		err = PTR_ERR(imx_data->clk_ipg);
+		goto free_sdhci;
+	}
+
+	imx_data->clk_ahb = devm_clk_get(&pdev->dev, "ahb");
+	if (IS_ERR(imx_data->clk_ahb)) {
+		err = PTR_ERR(imx_data->clk_ahb);
+		goto free_sdhci;
+	}
+
+	imx_data->clk_per = devm_clk_get(&pdev->dev, "per");
+	if (IS_ERR(imx_data->clk_per)) {
+		err = PTR_ERR(imx_data->clk_per);
+		goto free_sdhci;
+	}
+
+	pltfm_host->clk = imx_data->clk_per;
+
+	clk_prepare_enable(imx_data->clk_per);
+	clk_prepare_enable(imx_data->clk_ipg);
+	clk_prepare_enable(imx_data->clk_ahb);
+
+	imx_data->pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
+	if (IS_ERR(imx_data->pinctrl)) {
+		err = PTR_ERR(imx_data->pinctrl);
+		goto disable_clk;
 	}
-	clk_prepare_enable(clk);
-	pltfm_host->clk = clk;
 
 	host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL;
 
@@ -482,14 +565,14 @@
 	 * to something insane.  Change it back here.
 	 */
 	if (is_imx6q_usdhc(imx_data))
-		writel(0x08100810, host->ioaddr + SDHCI_WTMK_LVL);
+		writel(0x08100810, host->ioaddr + ESDHC_WTMK_LVL);
 
 	boarddata = &imx_data->boarddata;
 	if (sdhci_esdhc_imx_probe_dt(pdev, boarddata) < 0) {
 		if (!host->mmc->parent->platform_data) {
 			dev_err(mmc_dev(host->mmc), "no board data!\n");
 			err = -EINVAL;
-			goto no_board_data;
+			goto disable_clk;
 		}
 		imx_data->boarddata = *((struct esdhc_platform_data *)
 					host->mmc->parent->platform_data);
@@ -497,35 +580,23 @@
 
 	/* write_protect */
 	if (boarddata->wp_type == ESDHC_WP_GPIO) {
-		err = gpio_request_one(boarddata->wp_gpio, GPIOF_IN, "ESDHC_WP");
+		err = mmc_gpio_request_ro(host->mmc, boarddata->wp_gpio);
 		if (err) {
-			dev_warn(mmc_dev(host->mmc),
-				 "no write-protect pin available!\n");
-			boarddata->wp_gpio = -EINVAL;
+			dev_err(mmc_dev(host->mmc),
+				"failed to request write-protect gpio!\n");
+			goto disable_clk;
 		}
-	} else {
-		boarddata->wp_gpio = -EINVAL;
+		host->mmc->caps2 |= MMC_CAP2_RO_ACTIVE_HIGH;
 	}
 
 	/* card_detect */
-	if (boarddata->cd_type != ESDHC_CD_GPIO)
-		boarddata->cd_gpio = -EINVAL;
-
 	switch (boarddata->cd_type) {
 	case ESDHC_CD_GPIO:
-		err = gpio_request_one(boarddata->cd_gpio, GPIOF_IN, "ESDHC_CD");
+		err = mmc_gpio_request_cd(host->mmc, boarddata->cd_gpio);
 		if (err) {
 			dev_err(mmc_dev(host->mmc),
-				"no card-detect pin available!\n");
-			goto no_card_detect_pin;
-		}
-
-		err = request_irq(gpio_to_irq(boarddata->cd_gpio), cd_irq,
-				 IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
-				 mmc_hostname(host->mmc), host);
-		if (err) {
-			dev_err(mmc_dev(host->mmc), "request irq error\n");
-			goto no_card_detect_irq;
+				"failed to request card-detect gpio!\n");
+			goto disable_clk;
 		}
 		/* fall through */
 
@@ -542,52 +613,46 @@
 		break;
 	}
 
+	switch (boarddata->max_bus_width) {
+	case 8:
+		host->mmc->caps |= MMC_CAP_8_BIT_DATA | MMC_CAP_4_BIT_DATA;
+		break;
+	case 4:
+		host->mmc->caps |= MMC_CAP_4_BIT_DATA;
+		break;
+	case 1:
+	default:
+		host->quirks |= SDHCI_QUIRK_FORCE_1_BIT_DATA;
+		break;
+	}
+
 	err = sdhci_add_host(host);
 	if (err)
-		goto err_add_host;
+		goto disable_clk;
 
 	return 0;
 
-err_add_host:
-	if (gpio_is_valid(boarddata->cd_gpio))
-		free_irq(gpio_to_irq(boarddata->cd_gpio), host);
-no_card_detect_irq:
-	if (gpio_is_valid(boarddata->cd_gpio))
-		gpio_free(boarddata->cd_gpio);
-	if (gpio_is_valid(boarddata->wp_gpio))
-		gpio_free(boarddata->wp_gpio);
-no_card_detect_pin:
-no_board_data:
-	clk_disable_unprepare(pltfm_host->clk);
-	clk_put(pltfm_host->clk);
-err_clk_get:
-	kfree(imx_data);
-err_imx_data:
+disable_clk:
+	clk_disable_unprepare(imx_data->clk_per);
+	clk_disable_unprepare(imx_data->clk_ipg);
+	clk_disable_unprepare(imx_data->clk_ahb);
+free_sdhci:
 	sdhci_pltfm_free(pdev);
 	return err;
 }
 
-static int __devexit sdhci_esdhc_imx_remove(struct platform_device *pdev)
+static int sdhci_esdhc_imx_remove(struct platform_device *pdev)
 {
 	struct sdhci_host *host = platform_get_drvdata(pdev);
 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
 	struct pltfm_imx_data *imx_data = pltfm_host->priv;
-	struct esdhc_platform_data *boarddata = &imx_data->boarddata;
 	int dead = (readl(host->ioaddr + SDHCI_INT_STATUS) == 0xffffffff);
 
 	sdhci_remove_host(host, dead);
 
-	if (gpio_is_valid(boarddata->wp_gpio))
-		gpio_free(boarddata->wp_gpio);
-
-	if (gpio_is_valid(boarddata->cd_gpio)) {
-		free_irq(gpio_to_irq(boarddata->cd_gpio), host);
-		gpio_free(boarddata->cd_gpio);
-	}
-
-	clk_disable_unprepare(pltfm_host->clk);
-	clk_put(pltfm_host->clk);
-	kfree(imx_data);
+	clk_disable_unprepare(imx_data->clk_per);
+	clk_disable_unprepare(imx_data->clk_ipg);
+	clk_disable_unprepare(imx_data->clk_ahb);
 
 	sdhci_pltfm_free(pdev);
 
@@ -603,7 +668,7 @@
 	},
 	.id_table	= imx_esdhc_devtype,
 	.probe		= sdhci_esdhc_imx_probe,
-	.remove		= __devexit_p(sdhci_esdhc_imx_remove),
+	.remove		= sdhci_esdhc_imx_remove,
 };
 
 module_platform_driver(sdhci_esdhc_imx_driver);
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/sdhci.h linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/sdhci.h
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/sdhci.h	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/sdhci.h	2014-09-12 15:59:37.348052000 +0800
@@ -120,6 +120,7 @@
 #define SDHCI_SIGNAL_ENABLE	0x38
 #define  SDHCI_INT_RESPONSE	0x00000001
 #define  SDHCI_INT_DATA_END	0x00000002
+#define  SDHCI_INT_BLK_GAP	0x00000004
 #define  SDHCI_INT_DMA_END	0x00000008
 #define  SDHCI_INT_SPACE_AVAIL	0x00000010
 #define  SDHCI_INT_DATA_AVAIL	0x00000020
@@ -146,7 +147,8 @@
 #define  SDHCI_INT_DATA_MASK	(SDHCI_INT_DATA_END | SDHCI_INT_DMA_END | \
 		SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL | \
 		SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_DATA_CRC | \
-		SDHCI_INT_DATA_END_BIT | SDHCI_INT_ADMA_ERROR)
+		SDHCI_INT_DATA_END_BIT | SDHCI_INT_ADMA_ERROR | \
+		SDHCI_INT_BLK_GAP)
 #define SDHCI_INT_ALL_MASK	((unsigned int)-1)
 
 #define SDHCI_ACMD12_ERR	0x3C
@@ -205,6 +207,7 @@
 #define SDHCI_CAPABILITIES_1	0x44
 
 #define SDHCI_MAX_CURRENT		0x48
+#define  SDHCI_MAX_CURRENT_LIMIT	0xFF
 #define  SDHCI_MAX_CURRENT_330_MASK	0x0000FF
 #define  SDHCI_MAX_CURRENT_330_SHIFT	0
 #define  SDHCI_MAX_CURRENT_300_MASK	0x00FF00
@@ -226,6 +229,18 @@
 
 /* 60-FB reserved */
 
+#define SDHCI_PRESET_FOR_SDR12 0x66
+#define SDHCI_PRESET_FOR_SDR25 0x68
+#define SDHCI_PRESET_FOR_SDR50 0x6A
+#define SDHCI_PRESET_FOR_SDR104        0x6C
+#define SDHCI_PRESET_FOR_DDR50 0x6E
+#define SDHCI_PRESET_DRV_MASK  0xC000
+#define SDHCI_PRESET_DRV_SHIFT  14
+#define SDHCI_PRESET_CLKGEN_SEL_MASK   0x400
+#define SDHCI_PRESET_CLKGEN_SEL_SHIFT	10
+#define SDHCI_PRESET_SDCLK_FREQ_MASK   0x3FF
+#define SDHCI_PRESET_SDCLK_FREQ_SHIFT	0
+
 #define SDHCI_SLOT_INT_STATUS	0xFC
 
 #define SDHCI_HOST_VERSION	0xFE
@@ -266,7 +281,7 @@
 	unsigned int	(*get_max_clock)(struct sdhci_host *host);
 	unsigned int	(*get_min_clock)(struct sdhci_host *host);
 	unsigned int	(*get_timeout_clock)(struct sdhci_host *host);
-	int		(*platform_8bit_width)(struct sdhci_host *host,
+	int		(*platform_bus_width)(struct sdhci_host *host,
 					       int width);
 	void (*platform_send_init_74_clocks)(struct sdhci_host *host,
 					     u8 power_mode);
@@ -277,6 +292,8 @@
 	void	(*hw_reset)(struct sdhci_host *host);
 	void	(*platform_suspend)(struct sdhci_host *host);
 	void	(*platform_resume)(struct sdhci_host *host);
+	void    (*adma_workaround)(struct sdhci_host *host, u32 intmask);
+	void	(*platform_init)(struct sdhci_host *host);
 };
 
 #ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/sdhci-of-esdhc.c linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/sdhci-of-esdhc.c
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/sdhci-of-esdhc.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/sdhci-of-esdhc.c	2014-09-12 15:59:37.348052000 +0800
@@ -21,6 +21,33 @@
 #include "sdhci-pltfm.h"
 #include "sdhci-esdhc.h"
 
+#define VENDOR_V_22	0x12
+#define VENDOR_V_23	0x13
+static u32 esdhc_readl(struct sdhci_host *host, int reg)
+{
+	u32 ret;
+
+	ret = in_be32(host->ioaddr + reg);
+	/*
+	 * The bit of ADMA flag in eSDHC is not compatible with standard
+	 * SDHC register, so set fake flag SDHCI_CAN_DO_ADMA2 when ADMA is
+	 * supported by eSDHC.
+	 * And for many FSL eSDHC controller, the reset value of field
+	 * SDHCI_CAN_DO_ADMA1 is one, but some of them can't support ADMA,
+	 * only these vendor version is greater than 2.2/0x12 support ADMA.
+	 * For FSL eSDHC, must aligned 4-byte, so use 0xFC to read the
+	 * the verdor version number, oxFE is SDHCI_HOST_VERSION.
+	 */
+	if ((reg == SDHCI_CAPABILITIES) && (ret & SDHCI_CAN_DO_ADMA1)) {
+		u32 tmp = in_be32(host->ioaddr + SDHCI_SLOT_INT_STATUS);
+		tmp = (tmp & SDHCI_VENDOR_VER_MASK) >> SDHCI_VENDOR_VER_SHIFT;
+		if (tmp > VENDOR_V_22)
+			ret |= SDHCI_CAN_DO_ADMA2;
+	}
+
+	return ret;
+}
+
 static u16 esdhc_readw(struct sdhci_host *host, int reg)
 {
 	u16 ret;
@@ -59,6 +86,18 @@
 	return ret;
 }
 
+static void esdhc_writel(struct sdhci_host *host, u32 val, int reg)
+{
+	/*
+	 * Enable IRQSTATEN[BGESEN] is just to set IRQSTAT[BGE]
+	 * when SYSCTL[RSTD]) is set for some special operations.
+	 * No any impact other operation.
+	 */
+	if (reg == SDHCI_INT_ENABLE)
+		val |= SDHCI_INT_BLK_GAP;
+	sdhci_be32bs_writel(host, val, reg);
+}
+
 static void esdhc_writew(struct sdhci_host *host, u16 val, int reg)
 {
 	if (reg == SDHCI_BLOCK_SIZE) {
@@ -95,6 +134,41 @@
 	sdhci_be32bs_writeb(host, val, reg);
 }
 
+/*
+ * For Abort or Suspend after Stop at Block Gap, ignore the ADMA
+ * error(IRQSTAT[ADMAE]) if both Transfer Complete(IRQSTAT[TC])
+ * and Block Gap Event(IRQSTAT[BGE]) are also set.
+ * For Continue, apply soft reset for data(SYSCTL[RSTD]);
+ * and re-issue the entire read transaction from beginning.
+ */
+static void esdhci_of_adma_workaround(struct sdhci_host *host, u32 intmask)
+{
+	u32 tmp;
+	bool applicable;
+	dma_addr_t dmastart;
+	dma_addr_t dmanow;
+
+	tmp = in_be32(host->ioaddr + SDHCI_SLOT_INT_STATUS);
+	tmp = (tmp & SDHCI_VENDOR_VER_MASK) >> SDHCI_VENDOR_VER_SHIFT;
+
+	applicable = (intmask & SDHCI_INT_DATA_END) &&
+		(intmask & SDHCI_INT_BLK_GAP) &&
+		(tmp == VENDOR_V_23);
+	if (!applicable)
+		return;
+
+	host->data->error = 0;
+	dmastart = sg_dma_address(host->data->sg);
+	dmanow = dmastart + host->data->bytes_xfered;
+	/*
+	 * Force update to the next DMA block boundary.
+	 */
+	dmanow = (dmanow & ~(SDHCI_DEFAULT_BOUNDARY_SIZE - 1)) +
+		SDHCI_DEFAULT_BOUNDARY_SIZE;
+	host->data->bytes_xfered = dmanow - dmastart;
+	sdhci_writel(host, dmanow, SDHCI_DMA_ADDRESS);
+}
+
 static int esdhc_of_enable_dma(struct sdhci_host *host)
 {
 	setbits32(host->ioaddr + ESDHC_DMA_SYSCTL, ESDHC_DMA_SNOOP);
@@ -143,36 +217,55 @@
 }
 #endif
 
-static struct sdhci_ops sdhci_esdhc_ops = {
-	.read_l = sdhci_be32bs_readl,
+static void esdhc_of_platform_init(struct sdhci_host *host)
+{
+	u32 vvn;
+
+	vvn = in_be32(host->ioaddr + SDHCI_SLOT_INT_STATUS);
+	vvn = (vvn & SDHCI_VENDOR_VER_MASK) >> SDHCI_VENDOR_VER_SHIFT;
+	if (vvn == VENDOR_V_22)
+		host->quirks2 |= SDHCI_QUIRK2_HOST_NO_CMD23;
+
+	if (vvn > VENDOR_V_22)
+		host->quirks &= ~SDHCI_QUIRK_NO_BUSY_IRQ;
+}
+
+static const struct sdhci_ops sdhci_esdhc_ops = {
+	.read_l = esdhc_readl,
 	.read_w = esdhc_readw,
 	.read_b = esdhc_readb,
-	.write_l = sdhci_be32bs_writel,
+	.write_l = esdhc_writel,
 	.write_w = esdhc_writew,
 	.write_b = esdhc_writeb,
 	.set_clock = esdhc_of_set_clock,
 	.enable_dma = esdhc_of_enable_dma,
 	.get_max_clock = esdhc_of_get_max_clock,
 	.get_min_clock = esdhc_of_get_min_clock,
+	.platform_init = esdhc_of_platform_init,
 #ifdef CONFIG_PM
 	.platform_suspend = esdhc_of_suspend,
 	.platform_resume = esdhc_of_resume,
 #endif
+	.adma_workaround = esdhci_of_adma_workaround,
 };
 
-static struct sdhci_pltfm_data sdhci_esdhc_pdata = {
-	/* card detection could be handled via GPIO */
+static const struct sdhci_pltfm_data sdhci_esdhc_pdata = {
+	/*
+	 * card detection could be handled via GPIO
+	 * eSDHC cannot support End Attribute in NOP ADMA descriptor
+	 */
 	.quirks = ESDHC_DEFAULT_QUIRKS | SDHCI_QUIRK_BROKEN_CARD_DETECTION
-		| SDHCI_QUIRK_NO_CARD_NO_RESET,
+		| SDHCI_QUIRK_NO_CARD_NO_RESET
+		| SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC,
 	.ops = &sdhci_esdhc_ops,
 };
 
-static int __devinit sdhci_esdhc_probe(struct platform_device *pdev)
+static int sdhci_esdhc_probe(struct platform_device *pdev)
 {
 	return sdhci_pltfm_register(pdev, &sdhci_esdhc_pdata);
 }
 
-static int __devexit sdhci_esdhc_remove(struct platform_device *pdev)
+static int sdhci_esdhc_remove(struct platform_device *pdev)
 {
 	return sdhci_pltfm_unregister(pdev);
 }
@@ -193,7 +286,7 @@
 		.pm = SDHCI_PLTFM_PMOPS,
 	},
 	.probe = sdhci_esdhc_probe,
-	.remove = __devexit_p(sdhci_esdhc_remove),
+	.remove = sdhci_esdhc_remove,
 };
 
 module_platform_driver(sdhci_esdhc_driver);
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/sdhci-of-hlwd.c linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/sdhci-of-hlwd.c
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/sdhci-of-hlwd.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/sdhci-of-hlwd.c	2014-09-12 15:59:37.348052000 +0800
@@ -51,7 +51,7 @@
 	udelay(SDHCI_HLWD_WRITE_DELAY);
 }
 
-static struct sdhci_ops sdhci_hlwd_ops = {
+static const struct sdhci_ops sdhci_hlwd_ops = {
 	.read_l = sdhci_be32bs_readl,
 	.read_w = sdhci_be32bs_readw,
 	.read_b = sdhci_be32bs_readb,
@@ -60,18 +60,18 @@
 	.write_b = sdhci_hlwd_writeb,
 };
 
-static struct sdhci_pltfm_data sdhci_hlwd_pdata = {
+static const struct sdhci_pltfm_data sdhci_hlwd_pdata = {
 	.quirks = SDHCI_QUIRK_32BIT_DMA_ADDR |
 		  SDHCI_QUIRK_32BIT_DMA_SIZE,
 	.ops = &sdhci_hlwd_ops,
 };
 
-static int __devinit sdhci_hlwd_probe(struct platform_device *pdev)
+static int sdhci_hlwd_probe(struct platform_device *pdev)
 {
 	return sdhci_pltfm_register(pdev, &sdhci_hlwd_pdata);
 }
 
-static int __devexit sdhci_hlwd_remove(struct platform_device *pdev)
+static int sdhci_hlwd_remove(struct platform_device *pdev)
 {
 	return sdhci_pltfm_unregister(pdev);
 }
@@ -90,7 +90,7 @@
 		.pm = SDHCI_PLTFM_PMOPS,
 	},
 	.probe = sdhci_hlwd_probe,
-	.remove = __devexit_p(sdhci_hlwd_remove),
+	.remove = sdhci_hlwd_remove,
 };
 
 module_platform_driver(sdhci_hlwd_driver);
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/sdhci-pci.c linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/sdhci-pci.c
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/sdhci-pci.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/sdhci-pci.c	2014-09-12 15:59:37.348052000 +0800
@@ -33,6 +33,9 @@
  */
 #define PCI_DEVICE_ID_INTEL_PCH_SDIO0	0x8809
 #define PCI_DEVICE_ID_INTEL_PCH_SDIO1	0x880a
+#define PCI_DEVICE_ID_INTEL_BYT_EMMC	0x0f14
+#define PCI_DEVICE_ID_INTEL_BYT_SDIO	0x0f15
+#define PCI_DEVICE_ID_INTEL_BYT_SD	0x0f16
 
 /*
  * PCI registers
@@ -114,6 +117,7 @@
 
 		SDHCI_TIMEOUT_CLK_UNIT |
 		SDHCI_CAN_VDD_330 |
+		SDHCI_CAN_DO_HISPD |
 		SDHCI_CAN_DO_SDMA;
 	return 0;
 }
@@ -157,6 +161,7 @@
 static const struct sdhci_pci_fixes sdhci_cafe = {
 	.quirks		= SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER |
 			  SDHCI_QUIRK_NO_BUSY_IRQ |
+			  SDHCI_QUIRK_BROKEN_CARD_DETECTION |
 			  SDHCI_QUIRK_BROKEN_TIMEOUT_VAL,
 };
 
@@ -302,6 +307,33 @@
 	.probe_slot	= pch_hc_probe_slot,
 };
 
+static int byt_emmc_probe_slot(struct sdhci_pci_slot *slot)
+{
+	slot->host->mmc->caps |= MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE;
+	slot->host->mmc->caps2 |= MMC_CAP2_HC_ERASE_SZ;
+	return 0;
+}
+
+static int byt_sdio_probe_slot(struct sdhci_pci_slot *slot)
+{
+	slot->host->mmc->caps |= MMC_CAP_POWER_OFF_CARD | MMC_CAP_NONREMOVABLE;
+	return 0;
+}
+
+static const struct sdhci_pci_fixes sdhci_intel_byt_emmc = {
+	.allow_runtime_pm = true,
+	.probe_slot	= byt_emmc_probe_slot,
+};
+
+static const struct sdhci_pci_fixes sdhci_intel_byt_sdio = {
+	.quirks2	= SDHCI_QUIRK2_HOST_OFF_CARD_ON,
+	.allow_runtime_pm = true,
+	.probe_slot	= byt_sdio_probe_slot,
+};
+
+static const struct sdhci_pci_fixes sdhci_intel_byt_sd = {
+};
+
 /* O2Micro extra registers */
 #define O2_SD_LOCK_WP		0xD3
 #define O2_SD_MULTI_VCC3V	0xEE
@@ -652,7 +684,7 @@
 	.probe		= via_probe,
 };
 
-static const struct pci_device_id pci_ids[] __devinitdata = {
+static const struct pci_device_id pci_ids[] = {
 	{
 		.vendor		= PCI_VENDOR_ID_RICOH,
 		.device		= PCI_DEVICE_ID_RICOH_R5C822,
@@ -854,6 +886,30 @@
 	},
 
 	{
+		.vendor		= PCI_VENDOR_ID_INTEL,
+		.device		= PCI_DEVICE_ID_INTEL_BYT_EMMC,
+		.subvendor	= PCI_ANY_ID,
+		.subdevice	= PCI_ANY_ID,
+		.driver_data	= (kernel_ulong_t)&sdhci_intel_byt_emmc,
+	},
+
+	{
+		.vendor		= PCI_VENDOR_ID_INTEL,
+		.device		= PCI_DEVICE_ID_INTEL_BYT_SDIO,
+		.subvendor	= PCI_ANY_ID,
+		.subdevice	= PCI_ANY_ID,
+		.driver_data	= (kernel_ulong_t)&sdhci_intel_byt_sdio,
+	},
+
+	{
+		.vendor		= PCI_VENDOR_ID_INTEL,
+		.device		= PCI_DEVICE_ID_INTEL_BYT_SD,
+		.subvendor	= PCI_ANY_ID,
+		.subdevice	= PCI_ANY_ID,
+		.driver_data	= (kernel_ulong_t)&sdhci_intel_byt_sd,
+	},
+
+	{
 		.vendor		= PCI_VENDOR_ID_O2,
 		.device		= PCI_DEVICE_ID_O2_8120,
 		.subvendor	= PCI_ANY_ID,
@@ -933,7 +989,7 @@
 	return 0;
 }
 
-static int sdhci_pci_8bit_width(struct sdhci_host *host, int width)
+static int sdhci_pci_bus_width(struct sdhci_host *host, int width)
 {
 	u8 ctrl;
 
@@ -973,9 +1029,9 @@
 	usleep_range(300, 1000);
 }
 
-static struct sdhci_ops sdhci_pci_ops = {
+static const struct sdhci_ops sdhci_pci_ops = {
 	.enable_dma	= sdhci_pci_enable_dma,
-	.platform_8bit_width	= sdhci_pci_8bit_width,
+	.platform_bus_width	= sdhci_pci_bus_width,
 	.hw_reset		= sdhci_pci_hw_reset,
 };
 
@@ -1182,7 +1238,7 @@
  *                                                                           *
 \*****************************************************************************/
 
-static struct sdhci_pci_slot * __devinit sdhci_pci_probe_slot(
+static struct sdhci_pci_slot *sdhci_pci_probe_slot(
 	struct pci_dev *pdev, struct sdhci_pci_chip *chip, int first_bar,
 	int slotno)
 {
@@ -1195,7 +1251,7 @@
 		return ERR_PTR(-ENODEV);
 	}
 
-	if (pci_resource_len(pdev, bar) != 0x100) {
+	if (pci_resource_len(pdev, bar) < 0x100) {
 		dev_err(&pdev->dev, "Invalid iomem size. You may "
 			"experience problems.\n");
 	}
@@ -1277,6 +1333,8 @@
 	}
 
 	host->mmc->pm_caps = MMC_PM_KEEP_POWER | MMC_PM_WAKE_SDIO_IRQ;
+	host->mmc->slotno = slotno;
+	host->mmc->caps2 |= MMC_CAP2_NO_PRESCAN_POWERUP;
 
 	ret = sdhci_add_host(host);
 	if (ret)
@@ -1337,7 +1395,7 @@
 	sdhci_free_host(slot->host);
 }
 
-static void __devinit sdhci_pci_runtime_pm_allow(struct device *dev)
+static void sdhci_pci_runtime_pm_allow(struct device *dev)
 {
 	pm_runtime_put_noidle(dev);
 	pm_runtime_allow(dev);
@@ -1346,13 +1404,13 @@
 	pm_suspend_ignore_children(dev, 1);
 }
 
-static void __devexit sdhci_pci_runtime_pm_forbid(struct device *dev)
+static void sdhci_pci_runtime_pm_forbid(struct device *dev)
 {
 	pm_runtime_forbid(dev);
 	pm_runtime_get_noresume(dev);
 }
 
-static int __devinit sdhci_pci_probe(struct pci_dev *pdev,
+static int sdhci_pci_probe(struct pci_dev *pdev,
 				     const struct pci_device_id *ent)
 {
 	struct sdhci_pci_chip *chip;
@@ -1444,7 +1502,7 @@
 	return ret;
 }
 
-static void __devexit sdhci_pci_remove(struct pci_dev *pdev)
+static void sdhci_pci_remove(struct pci_dev *pdev)
 {
 	int i;
 	struct sdhci_pci_chip *chip;
@@ -1469,30 +1527,13 @@
 	.name =		"sdhci-pci",
 	.id_table =	pci_ids,
 	.probe =	sdhci_pci_probe,
-	.remove =	__devexit_p(sdhci_pci_remove),
+	.remove =	sdhci_pci_remove,
 	.driver =	{
 		.pm =   &sdhci_pci_pm_ops
 	},
 };
 
-/*****************************************************************************\
- *                                                                           *
- * Driver init/exit                                                          *
- *                                                                           *
-\*****************************************************************************/
-
-static int __init sdhci_drv_init(void)
-{
-	return pci_register_driver(&sdhci_driver);
-}
-
-static void __exit sdhci_drv_exit(void)
-{
-	pci_unregister_driver(&sdhci_driver);
-}
-
-module_init(sdhci_drv_init);
-module_exit(sdhci_drv_exit);
+module_pci_driver(sdhci_driver);
 
 MODULE_AUTHOR("Pierre Ossman <pierre@ossman.eu>");
 MODULE_DESCRIPTION("Secure Digital Host Controller Interface PCI driver");
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/sdhci-pltfm.c linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/sdhci-pltfm.c
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/sdhci-pltfm.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/sdhci-pltfm.c	2014-09-12 15:59:37.348052000 +0800
@@ -36,13 +36,22 @@
 #endif
 #include "sdhci-pltfm.h"
 
-static struct sdhci_ops sdhci_pltfm_ops = {
+unsigned int sdhci_pltfm_clk_get_max_clock(struct sdhci_host *host)
+{
+	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+
+	return clk_get_rate(pltfm_host->clk);
+}
+EXPORT_SYMBOL_GPL(sdhci_pltfm_clk_get_max_clock);
+
+static const struct sdhci_ops sdhci_pltfm_ops = {
 };
 
 #ifdef CONFIG_OF
 static bool sdhci_of_wp_inverted(struct device_node *np)
 {
-	if (of_get_property(np, "sdhci,wp-inverted", NULL))
+	if (of_get_property(np, "sdhci,wp-inverted", NULL) ||
+	    of_get_property(np, "wp-inverted", NULL))
 		return true;
 
 	/* Old device trees don't have the wp-inverted property. */
@@ -59,29 +68,45 @@
 	struct sdhci_host *host = platform_get_drvdata(pdev);
 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
 	const __be32 *clk;
+	u32 bus_width;
 	int size;
 
 	if (of_device_is_available(np)) {
 		if (of_get_property(np, "sdhci,auto-cmd12", NULL))
 			host->quirks |= SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12;
 
-		if (of_get_property(np, "sdhci,1-bit-only", NULL))
+		if (of_get_property(np, "sdhci,1-bit-only", NULL) ||
+		    (of_property_read_u32(np, "bus-width", &bus_width) == 0 &&
+		    bus_width == 1))
 			host->quirks |= SDHCI_QUIRK_FORCE_1_BIT_DATA;
 
 		if (sdhci_of_wp_inverted(np))
 			host->quirks |= SDHCI_QUIRK_INVERTED_WRITE_PROTECT;
 
+		if (of_get_property(np, "broken-cd", NULL))
+			host->quirks |= SDHCI_QUIRK_BROKEN_CARD_DETECTION;
+
+		if (of_get_property(np, "no-1-8-v", NULL))
+			host->quirks2 |= SDHCI_QUIRK2_NO_1_8_V;
+
 		if (of_device_is_compatible(np, "fsl,p2020-rev1-esdhc"))
 			host->quirks |= SDHCI_QUIRK_BROKEN_DMA;
 
 		if (of_device_is_compatible(np, "fsl,p2020-esdhc") ||
 		    of_device_is_compatible(np, "fsl,p1010-esdhc") ||
+		    of_device_is_compatible(np, "fsl,t4240-esdhc") ||
 		    of_device_is_compatible(np, "fsl,mpc8536-esdhc"))
 			host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL;
 
 		clk = of_get_property(np, "clock-frequency", &size);
 		if (clk && size == sizeof(*clk) && *clk)
 			pltfm_host->clock = be32_to_cpup(clk);
+
+		if (of_find_property(np, "keep-power-in-suspend", NULL))
+			host->mmc->pm_caps |= MMC_PM_KEEP_POWER;
+
+		if (of_find_property(np, "enable-sdio-wakeup", NULL))
+			host->mmc->pm_caps |= MMC_PM_WAKE_SDIO_IRQ;
 	}
 }
 #else
@@ -90,7 +115,7 @@
 EXPORT_SYMBOL_GPL(sdhci_get_of_property);
 
 struct sdhci_host *sdhci_pltfm_init(struct platform_device *pdev,
-				    struct sdhci_pltfm_data *pdata)
+				    const struct sdhci_pltfm_data *pdata)
 {
 	struct sdhci_host *host;
 	struct sdhci_pltfm_host *pltfm_host;
@@ -143,6 +168,13 @@
 		goto err_remap;
 	}
 
+	/*
+	 * Some platforms need to probe the controller to be able to
+	 * determine which caps should be used.
+	 */
+	if (host->ops && host->ops->platform_init)
+		host->ops->platform_init(host);
+
 	platform_set_drvdata(pdev, host);
 
 	return host;
@@ -170,7 +202,7 @@
 EXPORT_SYMBOL_GPL(sdhci_pltfm_free);
 
 int sdhci_pltfm_register(struct platform_device *pdev,
-			 struct sdhci_pltfm_data *pdata)
+			 const struct sdhci_pltfm_data *pdata)
 {
 	struct sdhci_host *host;
 	int ret = 0;
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/sdhci-pltfm.h linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/sdhci-pltfm.h
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/sdhci-pltfm.h	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/sdhci-pltfm.h	2014-09-12 15:59:37.348052000 +0800
@@ -16,7 +16,7 @@
 #include "sdhci.h"
 
 struct sdhci_pltfm_data {
-	struct sdhci_ops *ops;
+	const struct sdhci_ops *ops;
 	unsigned int quirks;
 };
 
@@ -91,13 +91,15 @@
 extern void sdhci_get_of_property(struct platform_device *pdev);
 
 extern struct sdhci_host *sdhci_pltfm_init(struct platform_device *pdev,
-					   struct sdhci_pltfm_data *pdata);
+					  const struct sdhci_pltfm_data *pdata);
 extern void sdhci_pltfm_free(struct platform_device *pdev);
 
 extern int sdhci_pltfm_register(struct platform_device *pdev,
-				struct sdhci_pltfm_data *pdata);
+				const struct sdhci_pltfm_data *pdata);
 extern int sdhci_pltfm_unregister(struct platform_device *pdev);
 
+extern unsigned int sdhci_pltfm_clk_get_max_clock(struct sdhci_host *host);
+
 #ifdef CONFIG_PM
 extern const struct dev_pm_ops sdhci_pltfm_pmops;
 #define SDHCI_PLTFM_PMOPS (&sdhci_pltfm_pmops)
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/sdhci-pxav2.c linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/sdhci-pxav2.c
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/sdhci-pxav2.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/sdhci-pxav2.c	2014-09-12 15:59:37.348052000 +0800
@@ -28,6 +28,9 @@
 #include <linux/mmc/host.h>
 #include <linux/platform_data/pxa_sdhci.h>
 #include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+
 #include "sdhci.h"
 #include "sdhci-pltfm.h"
 
@@ -108,26 +111,63 @@
 	return 0;
 }
 
-static u32 pxav2_get_max_clock(struct sdhci_host *host)
+static const struct sdhci_ops pxav2_sdhci_ops = {
+	.get_max_clock = sdhci_pltfm_clk_get_max_clock,
+	.platform_reset_exit = pxav2_set_private_registers,
+	.platform_bus_width = pxav2_mmc_set_width,
+};
+
+#ifdef CONFIG_OF
+static const struct of_device_id sdhci_pxav2_of_match[] = {
+	{
+		.compatible = "mrvl,pxav2-mmc",
+	},
+	{},
+};
+MODULE_DEVICE_TABLE(of, sdhci_pxav2_of_match);
+
+static struct sdhci_pxa_platdata *pxav2_get_mmc_pdata(struct device *dev)
 {
-	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+	struct sdhci_pxa_platdata *pdata;
+	struct device_node *np = dev->of_node;
+	u32 bus_width;
+	u32 clk_delay_cycles;
 
-	return clk_get_rate(pltfm_host->clk);
-}
+	pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
+	if (!pdata)
+		return NULL;
 
-static struct sdhci_ops pxav2_sdhci_ops = {
-	.get_max_clock = pxav2_get_max_clock,
-	.platform_reset_exit = pxav2_set_private_registers,
-	.platform_8bit_width = pxav2_mmc_set_width,
-};
+	if (of_find_property(np, "non-removable", NULL))
+		pdata->flags |= PXA_FLAG_CARD_PERMANENT;
+
+	of_property_read_u32(np, "bus-width", &bus_width);
+	if (bus_width == 8)
+		pdata->flags |= PXA_FLAG_SD_8_BIT_CAPABLE_SLOT;
+
+	of_property_read_u32(np, "mrvl,clk-delay-cycles", &clk_delay_cycles);
+	if (clk_delay_cycles > 0) {
+		pdata->clk_delay_sel = 1;
+		pdata->clk_delay_cycles = clk_delay_cycles;
+	}
+
+	return pdata;
+}
+#else
+static inline struct sdhci_pxa_platdata *pxav2_get_mmc_pdata(struct device *dev)
+{
+	return NULL;
+}
+#endif
 
-static int __devinit sdhci_pxav2_probe(struct platform_device *pdev)
+static int sdhci_pxav2_probe(struct platform_device *pdev)
 {
 	struct sdhci_pltfm_host *pltfm_host;
 	struct sdhci_pxa_platdata *pdata = pdev->dev.platform_data;
 	struct device *dev = &pdev->dev;
 	struct sdhci_host *host = NULL;
 	struct sdhci_pxa *pxa = NULL;
+	const struct of_device_id *match;
+
 	int ret;
 	struct clk *clk;
 
@@ -150,12 +190,16 @@
 		goto err_clk_get;
 	}
 	pltfm_host->clk = clk;
-	clk_enable(clk);
+	clk_prepare_enable(clk);
 
 	host->quirks = SDHCI_QUIRK_BROKEN_ADMA
 		| SDHCI_QUIRK_BROKEN_TIMEOUT_VAL
 		| SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN;
 
+	match = of_match_device(of_match_ptr(sdhci_pxav2_of_match), &pdev->dev);
+	if (match) {
+		pdata = pxav2_get_mmc_pdata(dev);
+	}
 	if (pdata) {
 		if (pdata->flags & PXA_FLAG_CARD_PERMANENT) {
 			/* on-chip device */
@@ -188,7 +232,7 @@
 	return 0;
 
 err_add_host:
-	clk_disable(clk);
+	clk_disable_unprepare(clk);
 	clk_put(clk);
 err_clk_get:
 	sdhci_pltfm_free(pdev);
@@ -196,7 +240,7 @@
 	return ret;
 }
 
-static int __devexit sdhci_pxav2_remove(struct platform_device *pdev)
+static int sdhci_pxav2_remove(struct platform_device *pdev)
 {
 	struct sdhci_host *host = platform_get_drvdata(pdev);
 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
@@ -204,7 +248,7 @@
 
 	sdhci_remove_host(host, 1);
 
-	clk_disable(pltfm_host->clk);
+	clk_disable_unprepare(pltfm_host->clk);
 	clk_put(pltfm_host->clk);
 	sdhci_pltfm_free(pdev);
 	kfree(pxa);
@@ -218,10 +262,13 @@
 	.driver		= {
 		.name	= "sdhci-pxav2",
 		.owner	= THIS_MODULE,
+#ifdef CONFIG_OF
+		.of_match_table = sdhci_pxav2_of_match,
+#endif
 		.pm	= SDHCI_PLTFM_PMOPS,
 	},
 	.probe		= sdhci_pxav2_probe,
-	.remove		= __devexit_p(sdhci_pxav2_remove),
+	.remove		= sdhci_pxav2_remove,
 };
 
 module_platform_driver(sdhci_pxav2_driver);
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/sdhci-pxav3.c linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/sdhci-pxav3.c
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/sdhci-pxav3.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/sdhci-pxav3.c	2014-09-12 15:59:37.348052000 +0800
@@ -24,13 +24,22 @@
 #include <linux/gpio.h>
 #include <linux/mmc/card.h>
 #include <linux/mmc/host.h>
+#include <linux/mmc/slot-gpio.h>
 #include <linux/platform_data/pxa_sdhci.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
+#include <linux/pm.h>
+#include <linux/pm_runtime.h>
+
 #include "sdhci.h"
 #include "sdhci-pltfm.h"
 
+#define PXAV3_RPM_DELAY_MS     50
+
 #define SD_CLOCK_BURST_SIZE_SETUP		0x10A
 #define SDCLK_SEL	0x100
 #define SDCLK_DELAY_SHIFT	9
@@ -158,19 +167,62 @@
 	return 0;
 }
 
-static struct sdhci_ops pxav3_sdhci_ops = {
+static const struct sdhci_ops pxav3_sdhci_ops = {
 	.platform_reset_exit = pxav3_set_private_registers,
 	.set_uhs_signaling = pxav3_set_uhs_signaling,
 	.platform_send_init_74_clocks = pxav3_gen_init_74_clocks,
+	.get_max_clock = sdhci_pltfm_clk_get_max_clock,
+};
+
+static struct sdhci_pltfm_data sdhci_pxav3_pdata = {
+	.quirks = SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK
+		| SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC
+		| SDHCI_QUIRK_32BIT_ADMA_SIZE
+		| SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN,
+	.ops = &pxav3_sdhci_ops,
+};
+
+#ifdef CONFIG_OF
+static const struct of_device_id sdhci_pxav3_of_match[] = {
+	{
+		.compatible = "mrvl,pxav3-mmc",
+	},
+	{},
 };
+MODULE_DEVICE_TABLE(of, sdhci_pxav3_of_match);
 
-static int __devinit sdhci_pxav3_probe(struct platform_device *pdev)
+static struct sdhci_pxa_platdata *pxav3_get_mmc_pdata(struct device *dev)
+{
+	struct sdhci_pxa_platdata *pdata;
+	struct device_node *np = dev->of_node;
+	u32 clk_delay_cycles;
+
+	pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
+	if (!pdata)
+		return NULL;
+
+	of_property_read_u32(np, "mrvl,clk-delay-cycles", &clk_delay_cycles);
+	if (clk_delay_cycles > 0)
+		pdata->clk_delay_cycles = clk_delay_cycles;
+
+	return pdata;
+}
+#else
+static inline struct sdhci_pxa_platdata *pxav3_get_mmc_pdata(struct device *dev)
+{
+	return NULL;
+}
+#endif
+
+static int sdhci_pxav3_probe(struct platform_device *pdev)
 {
 	struct sdhci_pltfm_host *pltfm_host;
 	struct sdhci_pxa_platdata *pdata = pdev->dev.platform_data;
 	struct device *dev = &pdev->dev;
 	struct sdhci_host *host = NULL;
 	struct sdhci_pxa *pxa = NULL;
+	const struct of_device_id *match;
+
 	int ret;
 	struct clk *clk;
 
@@ -178,7 +230,7 @@
 	if (!pxa)
 		return -ENOMEM;
 
-	host = sdhci_pltfm_init(pdev, NULL);
+	host = sdhci_pltfm_init(pdev, &sdhci_pxav3_pdata);
 	if (IS_ERR(host)) {
 		kfree(pxa);
 		return PTR_ERR(host);
@@ -186,28 +238,27 @@
 	pltfm_host = sdhci_priv(host);
 	pltfm_host->priv = pxa;
 
-	clk = clk_get(dev, "PXA-SDHCLK");
+	clk = clk_get(dev, NULL);
 	if (IS_ERR(clk)) {
 		dev_err(dev, "failed to get io clock\n");
 		ret = PTR_ERR(clk);
 		goto err_clk_get;
 	}
 	pltfm_host->clk = clk;
-	clk_enable(clk);
-
-	host->quirks = SDHCI_QUIRK_BROKEN_TIMEOUT_VAL
-		| SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC
-		| SDHCI_QUIRK_32BIT_ADMA_SIZE;
+	clk_prepare_enable(clk);
 
 	/* enable 1/8V DDR capable */
 	host->mmc->caps |= MMC_CAP_1_8V_DDR;
 
-	if (pdata) {
-		if (pdata->flags & PXA_FLAG_CARD_PERMANENT) {
-			/* on-chip device */
-			host->quirks |= SDHCI_QUIRK_BROKEN_CARD_DETECTION;
+	match = of_match_device(of_match_ptr(sdhci_pxav3_of_match), &pdev->dev);
+	if (match) {
+		mmc_of_parse(host->mmc);
+		sdhci_get_of_property(pdev);
+		pdata = pxav3_get_mmc_pdata(dev);
+	} else if (pdata) {
+		/* on-chip device */
+		if (pdata->flags & PXA_FLAG_CARD_PERMANENT)
 			host->mmc->caps |= MMC_CAP_NONREMOVABLE;
-		}
 
 		/* If slot design supports 8 bit data, indicate this to MMC. */
 		if (pdata->flags & PXA_FLAG_SD_8_BIT_CAPABLE_SLOT)
@@ -215,43 +266,76 @@
 
 		if (pdata->quirks)
 			host->quirks |= pdata->quirks;
+		if (pdata->quirks2)
+			host->quirks2 |= pdata->quirks2;
 		if (pdata->host_caps)
 			host->mmc->caps |= pdata->host_caps;
+		if (pdata->host_caps2)
+			host->mmc->caps2 |= pdata->host_caps2;
 		if (pdata->pm_caps)
 			host->mmc->pm_caps |= pdata->pm_caps;
+
+		if (gpio_is_valid(pdata->ext_cd_gpio)) {
+			ret = mmc_gpio_request_cd(host->mmc, pdata->ext_cd_gpio);
+			if (ret) {
+				dev_err(mmc_dev(host->mmc),
+					"failed to allocate card detect gpio\n");
+				goto err_cd_req;
+			}
+		}
 	}
 
-	host->ops = &pxav3_sdhci_ops;
+	pm_runtime_set_active(&pdev->dev);
+	pm_runtime_enable(&pdev->dev);
+	pm_runtime_set_autosuspend_delay(&pdev->dev, PXAV3_RPM_DELAY_MS);
+	pm_runtime_use_autosuspend(&pdev->dev);
+	pm_suspend_ignore_children(&pdev->dev, 1);
+	pm_runtime_get_noresume(&pdev->dev);
 
 	ret = sdhci_add_host(host);
 	if (ret) {
 		dev_err(&pdev->dev, "failed to add host\n");
+		pm_runtime_forbid(&pdev->dev);
+		pm_runtime_disable(&pdev->dev);
 		goto err_add_host;
 	}
 
 	platform_set_drvdata(pdev, host);
 
+	if (host->mmc->pm_caps & MMC_PM_KEEP_POWER) {
+		device_init_wakeup(&pdev->dev, 1);
+		host->mmc->pm_flags |= MMC_PM_WAKE_SDIO_IRQ;
+	} else {
+		device_init_wakeup(&pdev->dev, 0);
+	}
+
+	pm_runtime_put_autosuspend(&pdev->dev);
+
 	return 0;
 
 err_add_host:
-	clk_disable(clk);
+	clk_disable_unprepare(clk);
 	clk_put(clk);
+err_cd_req:
 err_clk_get:
 	sdhci_pltfm_free(pdev);
 	kfree(pxa);
 	return ret;
 }
 
-static int __devexit sdhci_pxav3_remove(struct platform_device *pdev)
+static int sdhci_pxav3_remove(struct platform_device *pdev)
 {
 	struct sdhci_host *host = platform_get_drvdata(pdev);
 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
 	struct sdhci_pxa *pxa = pltfm_host->priv;
 
+	pm_runtime_get_sync(&pdev->dev);
 	sdhci_remove_host(host, 1);
+	pm_runtime_disable(&pdev->dev);
 
-	clk_disable(pltfm_host->clk);
+	clk_disable_unprepare(pltfm_host->clk);
 	clk_put(pltfm_host->clk);
+
 	sdhci_pltfm_free(pdev);
 	kfree(pxa);
 
@@ -260,14 +344,94 @@
 	return 0;
 }
 
+#ifdef CONFIG_PM_SLEEP
+static int sdhci_pxav3_suspend(struct device *dev)
+{
+	int ret;
+	struct sdhci_host *host = dev_get_drvdata(dev);
+
+	pm_runtime_get_sync(dev);
+	ret = sdhci_suspend_host(host);
+	pm_runtime_mark_last_busy(dev);
+	pm_runtime_put_autosuspend(dev);
+
+	return ret;
+}
+
+static int sdhci_pxav3_resume(struct device *dev)
+{
+	int ret;
+	struct sdhci_host *host = dev_get_drvdata(dev);
+
+	pm_runtime_get_sync(dev);
+	ret = sdhci_resume_host(host);
+	pm_runtime_mark_last_busy(dev);
+	pm_runtime_put_autosuspend(dev);
+
+	return ret;
+}
+#endif
+
+#ifdef CONFIG_PM_RUNTIME
+static int sdhci_pxav3_runtime_suspend(struct device *dev)
+{
+	struct sdhci_host *host = dev_get_drvdata(dev);
+	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+	unsigned long flags;
+
+	if (pltfm_host->clk) {
+		spin_lock_irqsave(&host->lock, flags);
+		host->runtime_suspended = true;
+		spin_unlock_irqrestore(&host->lock, flags);
+
+		clk_disable_unprepare(pltfm_host->clk);
+	}
+
+	return 0;
+}
+
+static int sdhci_pxav3_runtime_resume(struct device *dev)
+{
+	struct sdhci_host *host = dev_get_drvdata(dev);
+	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+	unsigned long flags;
+
+	if (pltfm_host->clk) {
+		clk_prepare_enable(pltfm_host->clk);
+
+		spin_lock_irqsave(&host->lock, flags);
+		host->runtime_suspended = false;
+		spin_unlock_irqrestore(&host->lock, flags);
+	}
+
+	return 0;
+}
+#endif
+
+#ifdef CONFIG_PM
+static const struct dev_pm_ops sdhci_pxav3_pmops = {
+	SET_SYSTEM_SLEEP_PM_OPS(sdhci_pxav3_suspend, sdhci_pxav3_resume)
+	SET_RUNTIME_PM_OPS(sdhci_pxav3_runtime_suspend,
+		sdhci_pxav3_runtime_resume, NULL)
+};
+
+#define SDHCI_PXAV3_PMOPS (&sdhci_pxav3_pmops)
+
+#else
+#define SDHCI_PXAV3_PMOPS NULL
+#endif
+
 static struct platform_driver sdhci_pxav3_driver = {
 	.driver		= {
 		.name	= "sdhci-pxav3",
+#ifdef CONFIG_OF
+		.of_match_table = sdhci_pxav3_of_match,
+#endif
 		.owner	= THIS_MODULE,
-		.pm	= SDHCI_PLTFM_PMOPS,
+		.pm	= SDHCI_PXAV3_PMOPS,
 	},
 	.probe		= sdhci_pxav3_probe,
-	.remove		= __devexit_p(sdhci_pxav3_remove),
+	.remove		= sdhci_pxav3_remove,
 };
 
 module_platform_driver(sdhci_pxav3_driver);
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/sdhci-s3c.c linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/sdhci-s3c.c
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/sdhci-s3c.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/sdhci-s3c.c	2014-09-12 15:59:37.348052000 +0800
@@ -15,6 +15,7 @@
 #include <linux/delay.h>
 #include <linux/dma-mapping.h>
 #include <linux/platform_device.h>
+#include <linux/platform_data/mmc-sdhci-s3c.h>
 #include <linux/slab.h>
 #include <linux/clk.h>
 #include <linux/io.h>
@@ -27,12 +28,11 @@
 
 #include <linux/mmc/host.h>
 
-#include <plat/sdhci.h>
-#include <plat/regs-sdhci.h>
-
+#include "sdhci-s3c-regs.h"
 #include "sdhci.h"
 
 #define MAX_BUS_CLK	(4)
+
 /* Number of gpio's used is max data bus width + command and clock lines */
 #define NUM_GPIOS(x)	(x + 2)
 
@@ -43,7 +43,6 @@
  * @ioarea: The resource created when we claimed the IO area.
  * @pdata: The platform data for this controller.
  * @cur_clk: The index of the current bus clock.
- * @gpios: List of gpio numbers parsed from device tree.
  * @clk_io: The clock for the internal bus interface.
  * @clk_bus: The clocks that are available for the SD/MMC bus clock.
  */
@@ -55,7 +54,6 @@
 	unsigned int		cur_clk;
 	int			ext_cd_irq;
 	int			ext_cd_gpio;
-	int			*gpios;
 
 	struct clk		*clk_io;
 	struct clk		*clk_bus[MAX_BUS_CLK];
@@ -170,7 +168,7 @@
 	dev_dbg(&ourhost->pdev->dev, "clk %d: rate %ld, want %d, got %ld\n",
 		src, rate, wanted, rate / div);
 
-	return (wanted - (rate / div));
+	return wanted - (rate / div);
 }
 
 /**
@@ -207,10 +205,12 @@
 		 best_src, clock, best);
 
 	/* select the new clock source */
-
 	if (ourhost->cur_clk != best_src) {
 		struct clk *clk = ourhost->clk_bus[best_src];
 
+		clk_prepare_enable(clk);
+		clk_disable_unprepare(ourhost->clk_bus[ourhost->cur_clk]);
+
 		/* turn clock off to card before changing clock source */
 		writew(0, host->ioaddr + SDHCI_CLOCK_CONTROL);
 
@@ -292,6 +292,7 @@
 static void sdhci_cmu_set_clock(struct sdhci_host *host, unsigned int clock)
 {
 	struct sdhci_s3c *ourhost = to_s3c(host);
+	struct device *dev = &ourhost->pdev->dev;
 	unsigned long timeout;
 	u16 clk = 0;
 
@@ -313,8 +314,8 @@
 	while (!((clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL))
 		& SDHCI_CLOCK_INT_STABLE)) {
 		if (timeout == 0) {
-			printk(KERN_ERR "%s: Internal clock never "
-				"stabilised.\n", mmc_hostname(host->mmc));
+			dev_err(dev, "%s: Internal clock never stabilised.\n",
+				mmc_hostname(host->mmc));
 			return;
 		}
 		timeout--;
@@ -326,14 +327,14 @@
 }
 
 /**
- * sdhci_s3c_platform_8bit_width - support 8bit buswidth
+ * sdhci_s3c_platform_bus_width - support 8bit buswidth
  * @host: The SDHCI host being queried
  * @width: MMC_BUS_WIDTH_ macro for the bus width being requested
  *
  * We have 8-bit width support but is not a v3 controller.
- * So we add platform_8bit_width() and support 8bit width.
+ * So we add platform_bus_width() and support 8bit width.
  */
-static int sdhci_s3c_platform_8bit_width(struct sdhci_host *host, int width)
+static int sdhci_s3c_platform_bus_width(struct sdhci_host *host, int width)
 {
 	u8 ctrl;
 
@@ -363,24 +364,33 @@
 	.get_max_clock		= sdhci_s3c_get_max_clk,
 	.set_clock		= sdhci_s3c_set_clock,
 	.get_min_clock		= sdhci_s3c_get_min_clock,
-	.platform_8bit_width	= sdhci_s3c_platform_8bit_width,
+	.platform_bus_width	= sdhci_s3c_platform_bus_width,
 };
 
 static void sdhci_s3c_notify_change(struct platform_device *dev, int state)
 {
 	struct sdhci_host *host = platform_get_drvdata(dev);
+#ifdef CONFIG_PM_RUNTIME
+	struct sdhci_s3c *sc = sdhci_priv(host);
+#endif
 	unsigned long flags;
 
 	if (host) {
 		spin_lock_irqsave(&host->lock, flags);
 		if (state) {
 			dev_dbg(&dev->dev, "card inserted.\n");
+#ifdef CONFIG_PM_RUNTIME
+			clk_prepare_enable(sc->clk_io);
+#endif
 			host->flags &= ~SDHCI_DEVICE_DEAD;
 			host->quirks |= SDHCI_QUIRK_BROKEN_CARD_DETECTION;
 		} else {
 			dev_dbg(&dev->dev, "card removed.\n");
 			host->flags |= SDHCI_DEVICE_DEAD;
 			host->quirks &= ~SDHCI_QUIRK_BROKEN_CARD_DETECTION;
+#ifdef CONFIG_PM_RUNTIME
+			clk_disable_unprepare(sc->clk_io);
+#endif
 		}
 		tasklet_schedule(&host->card_tasklet);
 		spin_unlock_irqrestore(&host->lock, flags);
@@ -402,13 +412,15 @@
 	struct s3c_sdhci_platdata *pdata = sc->pdata;
 	struct device *dev = &sc->pdev->dev;
 
-	if (gpio_request(pdata->ext_cd_gpio, "SDHCI EXT CD") == 0) {
+	if (devm_gpio_request(dev, pdata->ext_cd_gpio, "SDHCI EXT CD") == 0) {
 		sc->ext_cd_gpio = pdata->ext_cd_gpio;
 		sc->ext_cd_irq = gpio_to_irq(pdata->ext_cd_gpio);
 		if (sc->ext_cd_irq &&
 		    request_threaded_irq(sc->ext_cd_irq, NULL,
 					 sdhci_s3c_gpio_card_detect_thread,
-					 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+					 IRQF_TRIGGER_RISING |
+					 IRQF_TRIGGER_FALLING |
+					 IRQF_ONESHOT,
 					 dev_name(dev), sc) == 0) {
 			int status = gpio_get_value(sc->ext_cd_gpio);
 			if (pdata->ext_cd_gpio_invert)
@@ -424,91 +436,49 @@
 }
 
 #ifdef CONFIG_OF
-static int __devinit sdhci_s3c_parse_dt(struct device *dev,
+static int sdhci_s3c_parse_dt(struct device *dev,
 		struct sdhci_host *host, struct s3c_sdhci_platdata *pdata)
 {
 	struct device_node *node = dev->of_node;
 	struct sdhci_s3c *ourhost = to_s3c(host);
 	u32 max_width;
-	int gpio, cnt, ret;
+	int gpio;
 
 	/* if the bus-width property is not specified, assume width as 1 */
-	if (of_property_read_u32(node, "samsung,sdhci-bus-width",
-				&max_width))
+	if (of_property_read_u32(node, "bus-width", &max_width))
 		max_width = 1;
 	pdata->max_width = max_width;
 
-	ourhost->gpios = devm_kzalloc(dev, NUM_GPIOS(pdata->max_width) *
-				sizeof(int), GFP_KERNEL);
-	if (!ourhost->gpios)
-		return -ENOMEM;
-
 	/* get the card detection method */
-	if (of_get_property(node, "samsung,sdhci-cd-internal", NULL))
-		pdata->cd_type = S3C_SDHCI_CD_INTERNAL;
-	else if (of_get_property(node, "samsung,sdhci-cd-gpio", NULL))
-		pdata->cd_type = S3C_SDHCI_CD_GPIO;
-	else if (of_get_property(node, "samsung,sdhci-cd-none", NULL))
-		pdata->cd_type = S3C_SDHCI_CD_NONE;
-	else if (of_get_property(node, "samsung,sdhci-cd-permanent", NULL))
-		pdata->cd_type = S3C_SDHCI_CD_PERMANENT;
-	else
+	if (of_get_property(node, "broken-cd", NULL)) {
 		pdata->cd_type = S3C_SDHCI_CD_NONE;
+		return 0;
+	}
 
-	/* get the gpio used for card detection */
-	if (pdata->cd_type == S3C_SDHCI_CD_GPIO ||
-			pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
-		gpio = of_get_named_gpio(node, "gpio-cd", 0);
-		if (!gpio_is_valid(gpio)) {
-			dev_err(dev, "invalid card detect gpio specified\n");
-			return -EINVAL;
-		}
+	if (of_get_property(node, "non-removable", NULL)) {
+		pdata->cd_type = S3C_SDHCI_CD_PERMANENT;
+		return 0;
 	}
 
-	if (pdata->cd_type == S3C_SDHCI_CD_GPIO) {
+	gpio = of_get_named_gpio(node, "cd-gpios", 0);
+	if (gpio_is_valid(gpio)) {
+		pdata->cd_type = S3C_SDHCI_CD_GPIO;
 		pdata->ext_cd_gpio = gpio;
-		ourhost->ext_cd_gpio = -1; /* invalid gpio number */
-		if (of_get_property(node, "samsung,cd-gpio-invert", NULL))
+		ourhost->ext_cd_gpio = -1;
+		if (of_get_property(node, "cd-inverted", NULL))
 			pdata->ext_cd_gpio_invert = 1;
-	} else if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
-		ret = gpio_request(gpio, "sdhci-cd");
-		if (ret) {
-			dev_err(dev, "card detect gpio request failed\n");
-			return -EINVAL;
-		}
-		ourhost->ext_cd_gpio = gpio;
-	}
-
-	/* get the gpios for command, clock and data lines */
-	for (cnt = 0; cnt < NUM_GPIOS(pdata->max_width); cnt++) {
-		gpio = of_get_gpio(node, cnt);
-		if (!gpio_is_valid(gpio)) {
-			dev_err(dev, "invalid gpio[%d]\n", cnt);
-			goto err_free_dt_cd_gpio;
-		}
-		ourhost->gpios[cnt] = gpio;
-	}
-
-	for (cnt = 0; cnt < NUM_GPIOS(pdata->max_width); cnt++) {
-		ret = gpio_request(ourhost->gpios[cnt], "sdhci-gpio");
-		if (ret) {
-			dev_err(dev, "gpio[%d] request failed\n", cnt);
-			goto err_free_dt_gpios;
-		}
+		return 0;
+	} else if (gpio != -ENOENT) {
+		dev_err(dev, "invalid card detect gpio specified\n");
+		return -EINVAL;
 	}
 
+	/* assuming internal card detect that will be configured by pinctrl */
+	pdata->cd_type = S3C_SDHCI_CD_INTERNAL;
 	return 0;
-
- err_free_dt_gpios:
-	while (--cnt >= 0)
-		gpio_free(ourhost->gpios[cnt]);
- err_free_dt_cd_gpio:
-	if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL)
-		gpio_free(ourhost->ext_cd_gpio);
-	return -EINVAL;
 }
 #else
-static int __devinit sdhci_s3c_parse_dt(struct device *dev,
+static int sdhci_s3c_parse_dt(struct device *dev,
 		struct sdhci_host *host, struct s3c_sdhci_platdata *pdata)
 {
 	return -EINVAL;
@@ -531,7 +501,7 @@
 			platform_get_device_id(pdev)->driver_data;
 }
 
-static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
+static int sdhci_s3c_probe(struct platform_device *pdev)
 {
 	struct s3c_sdhci_platdata *pdata;
 	struct sdhci_s3c_drv_data *drv_data;
@@ -562,13 +532,13 @@
 	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
 	if (!pdata) {
 		ret = -ENOMEM;
-		goto err_pdata;
+		goto err_pdata_io_clk;
 	}
 
 	if (pdev->dev.of_node) {
 		ret = sdhci_s3c_parse_dt(&pdev->dev, host, pdata);
 		if (ret)
-			goto err_pdata;
+			goto err_pdata_io_clk;
 	} else {
 		memcpy(pdata, pdev->dev.platform_data, sizeof(*pdata));
 		sc->ext_cd_gpio = -1; /* invalid gpio number */
@@ -582,25 +552,24 @@
 
 	platform_set_drvdata(pdev, host);
 
-	sc->clk_io = clk_get(dev, "hsmmc");
+	sc->clk_io = devm_clk_get(dev, "hsmmc");
 	if (IS_ERR(sc->clk_io)) {
 		dev_err(dev, "failed to get io clock\n");
 		ret = PTR_ERR(sc->clk_io);
-		goto err_io_clk;
+		goto err_pdata_io_clk;
 	}
 
 	/* enable the local io clock and keep it running for the moment. */
-	clk_enable(sc->clk_io);
+	clk_prepare_enable(sc->clk_io);
 
 	for (clks = 0, ptr = 0; ptr < MAX_BUS_CLK; ptr++) {
 		struct clk *clk;
 		char name[14];
 
 		snprintf(name, 14, "mmc_busclk.%d", ptr);
-		clk = clk_get(dev, name);
-		if (IS_ERR(clk)) {
+		clk = devm_clk_get(dev, name);
+		if (IS_ERR(clk))
 			continue;
-		}
 
 		clks++;
 		sc->clk_bus[ptr] = clk;
@@ -611,8 +580,6 @@
 		 */
 		sc->cur_clk = ptr;
 
-		clk_enable(clk);
-
 		dev_info(dev, "clock source %d: %s (%ld Hz)\n",
 			 ptr, name, clk_get_rate(clk));
 	}
@@ -623,11 +590,14 @@
 		goto err_no_busclks;
 	}
 
+#ifndef CONFIG_PM_RUNTIME
+	clk_prepare_enable(sc->clk_bus[sc->cur_clk]);
+#endif
+
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	host->ioaddr = devm_request_and_ioremap(&pdev->dev, res);
-	if (!host->ioaddr) {
-		dev_err(dev, "failed to map registers\n");
-		ret = -ENXIO;
+	host->ioaddr = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(host->ioaddr)) {
+		ret = PTR_ERR(host->ioaddr);
 		goto err_req_regs;
 	}
 
@@ -728,38 +698,31 @@
 	    gpio_is_valid(pdata->ext_cd_gpio))
 		sdhci_s3c_setup_card_detect_gpio(sc);
 
+#ifdef CONFIG_PM_RUNTIME
+	if (pdata->cd_type != S3C_SDHCI_CD_INTERNAL)
+		clk_disable_unprepare(sc->clk_io);
+#endif
 	return 0;
 
  err_req_regs:
-	for (ptr = 0; ptr < MAX_BUS_CLK; ptr++) {
-		if (sc->clk_bus[ptr]) {
-			clk_disable(sc->clk_bus[ptr]);
-			clk_put(sc->clk_bus[ptr]);
-		}
-	}
+#ifndef CONFIG_PM_RUNTIME
+	clk_disable_unprepare(sc->clk_bus[sc->cur_clk]);
+#endif
 
  err_no_busclks:
-	clk_disable(sc->clk_io);
-	clk_put(sc->clk_io);
+	clk_disable_unprepare(sc->clk_io);
 
- err_io_clk:
-	for (ptr = 0; ptr < NUM_GPIOS(sc->pdata->max_width); ptr++)
-		gpio_free(sc->gpios[ptr]);
-	if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL)
-		gpio_free(sc->ext_cd_gpio);
-
- err_pdata:
+ err_pdata_io_clk:
 	sdhci_free_host(host);
 
 	return ret;
 }
 
-static int __devexit sdhci_s3c_remove(struct platform_device *pdev)
+static int sdhci_s3c_remove(struct platform_device *pdev)
 {
 	struct sdhci_host *host =  platform_get_drvdata(pdev);
 	struct sdhci_s3c *sc = sdhci_priv(host);
 	struct s3c_sdhci_platdata *pdata = sc->pdata;
-	int ptr;
 
 	if (pdata->cd_type == S3C_SDHCI_CD_EXTERNAL && pdata->ext_cd_cleanup)
 		pdata->ext_cd_cleanup(&sdhci_s3c_notify_change);
@@ -767,30 +730,19 @@
 	if (sc->ext_cd_irq)
 		free_irq(sc->ext_cd_irq, sc);
 
-	if (gpio_is_valid(sc->ext_cd_gpio))
-		gpio_free(sc->ext_cd_gpio);
-
+#ifdef CONFIG_PM_RUNTIME
+	if (pdata->cd_type != S3C_SDHCI_CD_INTERNAL)
+		clk_prepare_enable(sc->clk_io);
+#endif
 	sdhci_remove_host(host, 1);
 
+	pm_runtime_dont_use_autosuspend(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
 
-	for (ptr = 0; ptr < 3; ptr++) {
-		if (sc->clk_bus[ptr]) {
-			clk_disable(sc->clk_bus[ptr]);
-			clk_put(sc->clk_bus[ptr]);
-		}
-	}
-	clk_disable(sc->clk_io);
-	clk_put(sc->clk_io);
-
-	iounmap(host->ioaddr);
-	release_resource(sc->ioarea);
-	kfree(sc->ioarea);
-
-	if (pdev->dev.of_node) {
-		for (ptr = 0; ptr < NUM_GPIOS(sc->pdata->max_width); ptr++)
-			gpio_free(sc->gpios[ptr]);
-	}
+#ifndef CONFIG_PM_RUNTIME
+	clk_disable_unprepare(sc->clk_bus[sc->cur_clk]);
+#endif
+	clk_disable_unprepare(sc->clk_io);
 
 	sdhci_free_host(host);
 	platform_set_drvdata(pdev, NULL);
@@ -818,15 +770,28 @@
 static int sdhci_s3c_runtime_suspend(struct device *dev)
 {
 	struct sdhci_host *host = dev_get_drvdata(dev);
+	struct sdhci_s3c *ourhost = to_s3c(host);
+	struct clk *busclk = ourhost->clk_io;
+	int ret;
+
+	ret = sdhci_runtime_suspend_host(host);
 
-	return sdhci_runtime_suspend_host(host);
+	clk_disable_unprepare(ourhost->clk_bus[ourhost->cur_clk]);
+	clk_disable_unprepare(busclk);
+	return ret;
 }
 
 static int sdhci_s3c_runtime_resume(struct device *dev)
 {
 	struct sdhci_host *host = dev_get_drvdata(dev);
+	struct sdhci_s3c *ourhost = to_s3c(host);
+	struct clk *busclk = ourhost->clk_io;
+	int ret;
 
-	return sdhci_runtime_resume_host(host);
+	clk_prepare_enable(busclk);
+	clk_prepare_enable(ourhost->clk_bus[ourhost->cur_clk]);
+	ret = sdhci_runtime_resume_host(host);
+	return ret;
 }
 #endif
 
@@ -868,7 +833,7 @@
 static const struct of_device_id sdhci_s3c_dt_match[] = {
 	{ .compatible = "samsung,s3c6410-sdhci", },
 	{ .compatible = "samsung,exynos4210-sdhci",
-		.data = &exynos4_sdhci_drv_data },
+		.data = (void *)EXYNOS4_SDHCI_DRV_DATA },
 	{},
 };
 MODULE_DEVICE_TABLE(of, sdhci_s3c_dt_match);
@@ -876,7 +841,7 @@
 
 static struct platform_driver sdhci_s3c_driver = {
 	.probe		= sdhci_s3c_probe,
-	.remove		= __devexit_p(sdhci_s3c_remove),
+	.remove		= sdhci_s3c_remove,
 	.id_table	= sdhci_s3c_driver_ids,
 	.driver		= {
 		.owner	= THIS_MODULE,
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/sdhci-s3c-regs.h linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/sdhci-s3c-regs.h
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/sdhci-s3c-regs.h	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/sdhci-s3c-regs.h	2014-09-12 15:59:37.348052000 +0800
@@ -0,0 +1,87 @@
+/* linux/arch/arm/plat-s3c/include/plat/regs-sdhci.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *	http://armlinux.simtec.co.uk/
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C Platform - SDHCI (HSMMC) register definitions
+ *
+ * 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 __PLAT_S3C_SDHCI_REGS_H
+#define __PLAT_S3C_SDHCI_REGS_H __FILE__
+
+#define S3C_SDHCI_CONTROL2			(0x80)
+#define S3C_SDHCI_CONTROL3			(0x84)
+#define S3C64XX_SDHCI_CONTROL4			(0x8C)
+
+#define S3C64XX_SDHCI_CTRL2_ENSTAASYNCCLR	(1 << 31)
+#define S3C64XX_SDHCI_CTRL2_ENCMDCNFMSK		(1 << 30)
+#define S3C_SDHCI_CTRL2_CDINVRXD3		(1 << 29)
+#define S3C_SDHCI_CTRL2_SLCARDOUT		(1 << 28)
+
+#define S3C_SDHCI_CTRL2_FLTCLKSEL_MASK		(0xf << 24)
+#define S3C_SDHCI_CTRL2_FLTCLKSEL_SHIFT		(24)
+#define S3C_SDHCI_CTRL2_FLTCLKSEL(_x)		((_x) << 24)
+
+#define S3C_SDHCI_CTRL2_LVLDAT_MASK		(0xff << 16)
+#define S3C_SDHCI_CTRL2_LVLDAT_SHIFT		(16)
+#define S3C_SDHCI_CTRL2_LVLDAT(_x)		((_x) << 16)
+
+#define S3C_SDHCI_CTRL2_ENFBCLKTX		(1 << 15)
+#define S3C_SDHCI_CTRL2_ENFBCLKRX		(1 << 14)
+#define S3C_SDHCI_CTRL2_SDCDSEL			(1 << 13)
+#define S3C_SDHCI_CTRL2_SDSIGPC			(1 << 12)
+#define S3C_SDHCI_CTRL2_ENBUSYCHKTXSTART	(1 << 11)
+
+#define S3C_SDHCI_CTRL2_DFCNT_MASK		(0x3 << 9)
+#define S3C_SDHCI_CTRL2_DFCNT_SHIFT		(9)
+#define S3C_SDHCI_CTRL2_DFCNT_NONE		(0x0 << 9)
+#define S3C_SDHCI_CTRL2_DFCNT_4SDCLK		(0x1 << 9)
+#define S3C_SDHCI_CTRL2_DFCNT_16SDCLK		(0x2 << 9)
+#define S3C_SDHCI_CTRL2_DFCNT_64SDCLK		(0x3 << 9)
+
+#define S3C_SDHCI_CTRL2_ENCLKOUTHOLD		(1 << 8)
+#define S3C_SDHCI_CTRL2_RWAITMODE		(1 << 7)
+#define S3C_SDHCI_CTRL2_DISBUFRD		(1 << 6)
+#define S3C_SDHCI_CTRL2_SELBASECLK_MASK		(0x3 << 4)
+#define S3C_SDHCI_CTRL2_SELBASECLK_SHIFT	(4)
+#define S3C_SDHCI_CTRL2_PWRSYNC			(1 << 3)
+#define S3C_SDHCI_CTRL2_ENCLKOUTMSKCON		(1 << 1)
+#define S3C_SDHCI_CTRL2_HWINITFIN		(1 << 0)
+
+#define S3C_SDHCI_CTRL3_FCSEL3			(1 << 31)
+#define S3C_SDHCI_CTRL3_FCSEL2			(1 << 23)
+#define S3C_SDHCI_CTRL3_FCSEL1			(1 << 15)
+#define S3C_SDHCI_CTRL3_FCSEL0			(1 << 7)
+
+#define S3C_SDHCI_CTRL3_FIA3_MASK		(0x7f << 24)
+#define S3C_SDHCI_CTRL3_FIA3_SHIFT		(24)
+#define S3C_SDHCI_CTRL3_FIA3(_x)		((_x) << 24)
+
+#define S3C_SDHCI_CTRL3_FIA2_MASK		(0x7f << 16)
+#define S3C_SDHCI_CTRL3_FIA2_SHIFT		(16)
+#define S3C_SDHCI_CTRL3_FIA2(_x)		((_x) << 16)
+
+#define S3C_SDHCI_CTRL3_FIA1_MASK		(0x7f << 8)
+#define S3C_SDHCI_CTRL3_FIA1_SHIFT		(8)
+#define S3C_SDHCI_CTRL3_FIA1(_x)		((_x) << 8)
+
+#define S3C_SDHCI_CTRL3_FIA0_MASK		(0x7f << 0)
+#define S3C_SDHCI_CTRL3_FIA0_SHIFT		(0)
+#define S3C_SDHCI_CTRL3_FIA0(_x)		((_x) << 0)
+
+#define S3C64XX_SDHCI_CONTROL4_DRIVE_MASK	(0x3 << 16)
+#define S3C64XX_SDHCI_CONTROL4_DRIVE_SHIFT	(16)
+#define S3C64XX_SDHCI_CONTROL4_DRIVE_2mA	(0x0 << 16)
+#define S3C64XX_SDHCI_CONTROL4_DRIVE_4mA	(0x1 << 16)
+#define S3C64XX_SDHCI_CONTROL4_DRIVE_7mA	(0x2 << 16)
+#define S3C64XX_SDHCI_CONTROL4_DRIVE_9mA	(0x3 << 16)
+
+#define S3C64XX_SDHCI_CONTROL4_BUSY		(1)
+
+#endif /* __PLAT_S3C_SDHCI_REGS_H */
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/sdhci-sirf.c linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/sdhci-sirf.c
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/sdhci-sirf.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/sdhci-sirf.c	2014-09-12 15:59:37.348052000 +0800
@@ -0,0 +1,193 @@
+/*
+ * SDHCI support for SiRF primaII and marco SoCs
+ *
+ * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/mmc/host.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+#include <linux/mmc/slot-gpio.h>
+#include <linux/pinctrl/consumer.h>
+#include "sdhci-pltfm.h"
+
+struct sdhci_sirf_priv {
+	struct clk *clk;
+	int gpio_cd;
+};
+
+static unsigned int sdhci_sirf_get_max_clk(struct sdhci_host *host)
+{
+	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+	struct sdhci_sirf_priv *priv = pltfm_host->priv;
+	return clk_get_rate(priv->clk);
+}
+
+static struct sdhci_ops sdhci_sirf_ops = {
+	.get_max_clock	= sdhci_sirf_get_max_clk,
+};
+
+static struct sdhci_pltfm_data sdhci_sirf_pdata = {
+	.ops = &sdhci_sirf_ops,
+	.quirks = SDHCI_QUIRK_BROKEN_TIMEOUT_VAL |
+		SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK |
+		SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN |
+		SDHCI_QUIRK_INVERTED_WRITE_PROTECT |
+		SDHCI_QUIRK_DELAY_AFTER_POWER,
+};
+
+static int sdhci_sirf_probe(struct platform_device *pdev)
+{
+	struct sdhci_host *host;
+	struct sdhci_pltfm_host *pltfm_host;
+	struct sdhci_sirf_priv *priv;
+	struct pinctrl *pinctrl;
+	int ret;
+
+	pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
+	if (IS_ERR(pinctrl)) {
+		dev_err(&pdev->dev, "unable to get pinmux");
+		return PTR_ERR(pinctrl);
+	}
+
+	priv = devm_kzalloc(&pdev->dev, sizeof(struct sdhci_sirf_priv),
+		GFP_KERNEL);
+	if (!priv) {
+		dev_err(&pdev->dev, "unable to allocate private data");
+		return -ENOMEM;
+	}
+
+	priv->clk = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR(priv->clk)) {
+		dev_err(&pdev->dev, "unable to get clock");
+		return PTR_ERR(priv->clk);
+	}
+
+	if (pdev->dev.of_node) {
+		priv->gpio_cd = of_get_named_gpio(pdev->dev.of_node,
+			"cd-gpios", 0);
+	} else {
+		priv->gpio_cd = -EINVAL;
+	}
+
+	host = sdhci_pltfm_init(pdev, &sdhci_sirf_pdata);
+	if (IS_ERR(host)) {
+		ret = PTR_ERR(host);
+		goto err_sdhci_pltfm_init;
+	}
+
+	pltfm_host = sdhci_priv(host);
+	pltfm_host->priv = priv;
+
+	sdhci_get_of_property(pdev);
+
+	clk_prepare_enable(priv->clk);
+
+	ret = sdhci_add_host(host);
+	if (ret)
+		goto err_sdhci_add;
+
+	/*
+	 * We must request the IRQ after sdhci_add_host(), as the tasklet only
+	 * gets setup in sdhci_add_host() and we oops.
+	 */
+	if (gpio_is_valid(priv->gpio_cd)) {
+		ret = mmc_gpio_request_cd(host->mmc, priv->gpio_cd);
+		if (ret) {
+			dev_err(&pdev->dev, "card detect irq request failed: %d\n",
+				ret);
+			goto err_request_cd;
+		}
+	}
+
+	return 0;
+
+err_request_cd:
+	sdhci_remove_host(host, 0);
+err_sdhci_add:
+	clk_disable_unprepare(priv->clk);
+	sdhci_pltfm_free(pdev);
+err_sdhci_pltfm_init:
+	return ret;
+}
+
+static int sdhci_sirf_remove(struct platform_device *pdev)
+{
+	struct sdhci_host *host = platform_get_drvdata(pdev);
+	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+	struct sdhci_sirf_priv *priv = pltfm_host->priv;
+
+	sdhci_pltfm_unregister(pdev);
+
+	if (gpio_is_valid(priv->gpio_cd))
+		mmc_gpio_free_cd(host->mmc);
+
+	clk_disable_unprepare(priv->clk);
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int sdhci_sirf_suspend(struct device *dev)
+{
+	struct sdhci_host *host = dev_get_drvdata(dev);
+	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+	struct sdhci_sirf_priv *priv = pltfm_host->priv;
+	int ret;
+
+	ret = sdhci_suspend_host(host);
+	if (ret)
+		return ret;
+
+	clk_disable(priv->clk);
+
+	return 0;
+}
+
+static int sdhci_sirf_resume(struct device *dev)
+{
+	struct sdhci_host *host = dev_get_drvdata(dev);
+	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+	struct sdhci_sirf_priv *priv = pltfm_host->priv;
+	int ret;
+
+	ret = clk_enable(priv->clk);
+	if (ret) {
+		dev_dbg(dev, "Resume: Error enabling clock\n");
+		return ret;
+	}
+
+	return sdhci_resume_host(host);
+}
+
+static SIMPLE_DEV_PM_OPS(sdhci_sirf_pm_ops, sdhci_sirf_suspend, sdhci_sirf_resume);
+#endif
+
+static const struct of_device_id sdhci_sirf_of_match[] = {
+	{ .compatible = "sirf,prima2-sdhc" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, sdhci_sirf_of_match);
+
+static struct platform_driver sdhci_sirf_driver = {
+	.driver		= {
+		.name	= "sdhci-sirf",
+		.owner	= THIS_MODULE,
+		.of_match_table = sdhci_sirf_of_match,
+#ifdef CONFIG_PM_SLEEP
+		.pm	= &sdhci_sirf_pm_ops,
+#endif
+	},
+	.probe		= sdhci_sirf_probe,
+	.remove		= sdhci_sirf_remove,
+};
+
+module_platform_driver(sdhci_sirf_driver);
+
+MODULE_DESCRIPTION("SDHCI driver for SiRFprimaII/SiRFmarco");
+MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
+MODULE_LICENSE("GPL v2");
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/sdhci-spear.c linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/sdhci-spear.c
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/sdhci-spear.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/sdhci-spear.c	2014-09-12 15:59:37.348052000 +0800
@@ -4,7 +4,7 @@
  * Support of SDHCI platform devices for spear soc family
  *
  * Copyright (C) 2010 ST Microelectronics
- * Viresh Kumar<viresh.kumar@st.com>
+ * Viresh Kumar <viresh.linux@gmail.com>
  *
  * Inspired by sdhci-pltfm.c
  *
@@ -20,6 +20,8 @@
 #include <linux/module.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
 #include <linux/platform_device.h>
 #include <linux/pm.h>
 #include <linux/slab.h>
@@ -34,7 +36,7 @@
 };
 
 /* sdhci ops */
-static struct sdhci_ops sdhci_pltfm_ops = {
+static const struct sdhci_ops sdhci_pltfm_ops = {
 	/* Nothing to do for now. */
 };
 
@@ -68,15 +70,45 @@
 	return IRQ_HANDLED;
 }
 
-static int __devinit sdhci_probe(struct platform_device *pdev)
+#ifdef CONFIG_OF
+static struct sdhci_plat_data *sdhci_probe_config_dt(struct platform_device *pdev)
 {
+	struct device_node *np = pdev->dev.of_node;
+	struct sdhci_plat_data *pdata = NULL;
+	int cd_gpio;
+
+	cd_gpio = of_get_named_gpio(np, "cd-gpios", 0);
+	if (!gpio_is_valid(cd_gpio))
+		cd_gpio = -1;
+
+	/* If pdata is required */
+	if (cd_gpio != -1) {
+		pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+		if (!pdata) {
+			dev_err(&pdev->dev, "DT: kzalloc failed\n");
+			return ERR_PTR(-ENOMEM);
+		}
+	}
+
+	pdata->card_int_gpio = cd_gpio;
+
+	return pdata;
+}
+#else
+static struct sdhci_plat_data *sdhci_probe_config_dt(struct platform_device *pdev)
+{
+	return ERR_PTR(-ENOSYS);
+}
+#endif
+
+static int sdhci_probe(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
 	struct sdhci_host *host;
 	struct resource *iomem;
 	struct spear_sdhci *sdhci;
 	int ret;
 
-	BUG_ON(pdev == NULL);
-
 	iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!iomem) {
 		ret = -ENOMEM;
@@ -84,18 +116,18 @@
 		goto err;
 	}
 
-	if (!request_mem_region(iomem->start, resource_size(iomem),
-				"spear-sdhci")) {
+	if (!devm_request_mem_region(&pdev->dev, iomem->start,
+				resource_size(iomem), "spear-sdhci")) {
 		ret = -EBUSY;
 		dev_dbg(&pdev->dev, "cannot request region\n");
 		goto err;
 	}
 
-	sdhci = kzalloc(sizeof(*sdhci), GFP_KERNEL);
+	sdhci = devm_kzalloc(&pdev->dev, sizeof(*sdhci), GFP_KERNEL);
 	if (!sdhci) {
 		ret = -ENOMEM;
 		dev_dbg(&pdev->dev, "cannot allocate memory for sdhci\n");
-		goto err_kzalloc;
+		goto err;
 	}
 
 	/* clk enable */
@@ -103,17 +135,30 @@
 	if (IS_ERR(sdhci->clk)) {
 		ret = PTR_ERR(sdhci->clk);
 		dev_dbg(&pdev->dev, "Error getting clock\n");
-		goto err_clk_get;
+		goto err;
 	}
 
-	ret = clk_enable(sdhci->clk);
+	ret = clk_prepare_enable(sdhci->clk);
 	if (ret) {
 		dev_dbg(&pdev->dev, "Error enabling clock\n");
-		goto err_clk_enb;
+		goto put_clk;
+	}
+
+	ret = clk_set_rate(sdhci->clk, 50000000);
+	if (ret)
+		dev_dbg(&pdev->dev, "Error setting desired clk, clk=%lu\n",
+				clk_get_rate(sdhci->clk));
+
+	if (np) {
+		sdhci->data = sdhci_probe_config_dt(pdev);
+		if (IS_ERR(sdhci->data)) {
+			dev_err(&pdev->dev, "DT: Failed to get pdata\n");
+			return -ENODEV;
+		}
+	} else {
+		sdhci->data = dev_get_platdata(&pdev->dev);
 	}
 
-	/* overwrite platform_data */
-	sdhci->data = dev_get_platdata(&pdev->dev);
 	pdev->dev.platform_data = sdhci;
 
 	if (pdev->dev.parent)
@@ -124,7 +169,7 @@
 	if (IS_ERR(host)) {
 		ret = PTR_ERR(host);
 		dev_dbg(&pdev->dev, "error allocating host\n");
-		goto err_alloc_host;
+		goto disable_clk;
 	}
 
 	host->hw_name = "sdhci";
@@ -132,17 +177,18 @@
 	host->irq = platform_get_irq(pdev, 0);
 	host->quirks = SDHCI_QUIRK_BROKEN_ADMA;
 
-	host->ioaddr = ioremap(iomem->start, resource_size(iomem));
+	host->ioaddr = devm_ioremap(&pdev->dev, iomem->start,
+			resource_size(iomem));
 	if (!host->ioaddr) {
 		ret = -ENOMEM;
 		dev_dbg(&pdev->dev, "failed to remap registers\n");
-		goto err_ioremap;
+		goto free_host;
 	}
 
 	ret = sdhci_add_host(host);
 	if (ret) {
 		dev_dbg(&pdev->dev, "error adding host\n");
-		goto err_add_host;
+		goto free_host;
 	}
 
 	platform_set_drvdata(pdev, host);
@@ -161,11 +207,12 @@
 	if (sdhci->data->card_power_gpio >= 0) {
 		int val = 0;
 
-		ret = gpio_request(sdhci->data->card_power_gpio, "sdhci");
+		ret = devm_gpio_request(&pdev->dev,
+				sdhci->data->card_power_gpio, "sdhci");
 		if (ret < 0) {
 			dev_dbg(&pdev->dev, "gpio request fail: %d\n",
 					sdhci->data->card_power_gpio);
-			goto err_pgpio_request;
+			goto set_drvdata;
 		}
 
 		if (sdhci->data->power_always_enb)
@@ -177,102 +224,74 @@
 		if (ret) {
 			dev_dbg(&pdev->dev, "gpio set direction fail: %d\n",
 					sdhci->data->card_power_gpio);
-			goto err_pgpio_direction;
+			goto set_drvdata;
 		}
 	}
 
 	if (sdhci->data->card_int_gpio >= 0) {
-		ret = gpio_request(sdhci->data->card_int_gpio, "sdhci");
+		ret = devm_gpio_request(&pdev->dev, sdhci->data->card_int_gpio,
+				"sdhci");
 		if (ret < 0) {
 			dev_dbg(&pdev->dev, "gpio request fail: %d\n",
 					sdhci->data->card_int_gpio);
-			goto err_igpio_request;
+			goto set_drvdata;
 		}
 
 		ret = gpio_direction_input(sdhci->data->card_int_gpio);
 		if (ret) {
 			dev_dbg(&pdev->dev, "gpio set direction fail: %d\n",
 					sdhci->data->card_int_gpio);
-			goto err_igpio_direction;
+			goto set_drvdata;
 		}
-		ret = request_irq(gpio_to_irq(sdhci->data->card_int_gpio),
+		ret = devm_request_irq(&pdev->dev,
+				gpio_to_irq(sdhci->data->card_int_gpio),
 				sdhci_gpio_irq, IRQF_TRIGGER_LOW,
 				mmc_hostname(host->mmc), pdev);
 		if (ret) {
 			dev_dbg(&pdev->dev, "gpio request irq fail: %d\n",
 					sdhci->data->card_int_gpio);
-			goto err_igpio_request_irq;
+			goto set_drvdata;
 		}
 
 	}
 
 	return 0;
 
-err_igpio_request_irq:
-err_igpio_direction:
-	if (sdhci->data->card_int_gpio >= 0)
-		gpio_free(sdhci->data->card_int_gpio);
-err_igpio_request:
-err_pgpio_direction:
-	if (sdhci->data->card_power_gpio >= 0)
-		gpio_free(sdhci->data->card_power_gpio);
-err_pgpio_request:
+set_drvdata:
 	platform_set_drvdata(pdev, NULL);
 	sdhci_remove_host(host, 1);
-err_add_host:
-	iounmap(host->ioaddr);
-err_ioremap:
+free_host:
 	sdhci_free_host(host);
-err_alloc_host:
-	clk_disable(sdhci->clk);
-err_clk_enb:
+disable_clk:
+	clk_disable_unprepare(sdhci->clk);
+put_clk:
 	clk_put(sdhci->clk);
-err_clk_get:
-	kfree(sdhci);
-err_kzalloc:
-	release_mem_region(iomem->start, resource_size(iomem));
 err:
 	dev_err(&pdev->dev, "spear-sdhci probe failed: %d\n", ret);
 	return ret;
 }
 
-static int __devexit sdhci_remove(struct platform_device *pdev)
+static int sdhci_remove(struct platform_device *pdev)
 {
 	struct sdhci_host *host = platform_get_drvdata(pdev);
-	struct resource *iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	struct spear_sdhci *sdhci = dev_get_platdata(&pdev->dev);
-	int dead;
+	int dead = 0;
 	u32 scratch;
 
-	if (sdhci->data) {
-		if (sdhci->data->card_int_gpio >= 0) {
-			free_irq(gpio_to_irq(sdhci->data->card_int_gpio), pdev);
-			gpio_free(sdhci->data->card_int_gpio);
-		}
-
-		if (sdhci->data->card_power_gpio >= 0)
-			gpio_free(sdhci->data->card_power_gpio);
-	}
-
 	platform_set_drvdata(pdev, NULL);
-	dead = 0;
 	scratch = readl(host->ioaddr + SDHCI_INT_STATUS);
 	if (scratch == (u32)-1)
 		dead = 1;
 
 	sdhci_remove_host(host, dead);
-	iounmap(host->ioaddr);
 	sdhci_free_host(host);
-	clk_disable(sdhci->clk);
+	clk_disable_unprepare(sdhci->clk);
 	clk_put(sdhci->clk);
-	kfree(sdhci);
-	if (iomem)
-		release_mem_region(iomem->start, resource_size(iomem));
 
 	return 0;
 }
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static int sdhci_suspend(struct device *dev)
 {
 	struct sdhci_host *host = dev_get_drvdata(dev);
@@ -304,18 +323,27 @@
 
 static SIMPLE_DEV_PM_OPS(sdhci_pm_ops, sdhci_suspend, sdhci_resume);
 
+#ifdef CONFIG_OF
+static const struct of_device_id sdhci_spear_id_table[] = {
+	{ .compatible = "st,spear300-sdhci" },
+	{}
+};
+MODULE_DEVICE_TABLE(of, sdhci_spear_id_table);
+#endif
+
 static struct platform_driver sdhci_driver = {
 	.driver = {
 		.name	= "sdhci",
 		.owner	= THIS_MODULE,
 		.pm	= &sdhci_pm_ops,
+		.of_match_table = of_match_ptr(sdhci_spear_id_table),
 	},
 	.probe		= sdhci_probe,
-	.remove		= __devexit_p(sdhci_remove),
+	.remove		= sdhci_remove,
 };
 
 module_platform_driver(sdhci_driver);
 
 MODULE_DESCRIPTION("SPEAr Secure Digital Host Controller Interface driver");
-MODULE_AUTHOR("Viresh Kumar <viresh.kumar@st.com>");
+MODULE_AUTHOR("Viresh Kumar <viresh.linux@gmail.com>");
 MODULE_LICENSE("GPL v2");
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/sdhci-tegra.c linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/sdhci-tegra.c
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/sdhci-tegra.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/sdhci-tegra.c	2014-09-12 15:59:37.348052000 +0800
@@ -24,25 +24,28 @@
 #include <linux/gpio.h>
 #include <linux/mmc/card.h>
 #include <linux/mmc/host.h>
+#include <linux/mmc/slot-gpio.h>
 
 #include <asm/gpio.h>
 
-#include <mach/gpio-tegra.h>
-#include <mach/sdhci.h>
-
 #include "sdhci-pltfm.h"
 
+/* Tegra SDHOST controller vendor register definitions */
+#define SDHCI_TEGRA_VENDOR_MISC_CTRL		0x120
+#define SDHCI_MISC_CTRL_ENABLE_SDHCI_SPEC_300	0x20
+
 #define NVQUIRK_FORCE_SDHCI_SPEC_200	BIT(0)
 #define NVQUIRK_ENABLE_BLOCK_GAP_DET	BIT(1)
+#define NVQUIRK_ENABLE_SDHCI_SPEC_300	BIT(2)
 
 struct sdhci_tegra_soc_data {
-	struct sdhci_pltfm_data *pdata;
+	const struct sdhci_pltfm_data *pdata;
 	u32 nvquirks;
 };
 
 struct sdhci_tegra {
-	const struct tegra_sdhci_platform_data *plat;
 	const struct sdhci_tegra_soc_data *soc_data;
+	int power_gpio;
 };
 
 static u32 tegra_sdhci_readl(struct sdhci_host *host, int reg)
@@ -102,33 +105,35 @@
 
 static unsigned int tegra_sdhci_get_ro(struct sdhci_host *host)
 {
+	return mmc_gpio_get_ro(host->mmc);
+}
+
+static void tegra_sdhci_reset_exit(struct sdhci_host *host, u8 mask)
+{
 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
 	struct sdhci_tegra *tegra_host = pltfm_host->priv;
-	const struct tegra_sdhci_platform_data *plat = tegra_host->plat;
+	const struct sdhci_tegra_soc_data *soc_data = tegra_host->soc_data;
 
-	if (!gpio_is_valid(plat->wp_gpio))
-		return -1;
+	if (!(mask & SDHCI_RESET_ALL))
+		return;
 
-	return gpio_get_value(plat->wp_gpio);
+	/* Erratum: Enable SDHCI spec v3.00 support */
+	if (soc_data->nvquirks & NVQUIRK_ENABLE_SDHCI_SPEC_300) {
+		u32 misc_ctrl;
+
+		misc_ctrl = sdhci_readb(host, SDHCI_TEGRA_VENDOR_MISC_CTRL);
+		misc_ctrl |= SDHCI_MISC_CTRL_ENABLE_SDHCI_SPEC_300;
+		sdhci_writeb(host, misc_ctrl, SDHCI_TEGRA_VENDOR_MISC_CTRL);
+	}
 }
 
-static irqreturn_t carddetect_irq(int irq, void *data)
+static int tegra_sdhci_buswidth(struct sdhci_host *host, int bus_width)
 {
-	struct sdhci_host *sdhost = (struct sdhci_host *)data;
-
-	tasklet_schedule(&sdhost->card_tasklet);
-	return IRQ_HANDLED;
-};
-
-static int tegra_sdhci_8bit(struct sdhci_host *host, int bus_width)
-{
-	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
-	struct sdhci_tegra *tegra_host = pltfm_host->priv;
-	const struct tegra_sdhci_platform_data *plat = tegra_host->plat;
 	u32 ctrl;
 
 	ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
-	if (plat->is_8bit && bus_width == MMC_BUS_WIDTH_8) {
+	if ((host->mmc->caps & MMC_CAP_8_BIT_DATA) &&
+	    (bus_width == MMC_BUS_WIDTH_8)) {
 		ctrl &= ~SDHCI_CTRL_4BITBUS;
 		ctrl |= SDHCI_CTRL_8BITBUS;
 	} else {
@@ -142,16 +147,16 @@
 	return 0;
 }
 
-static struct sdhci_ops tegra_sdhci_ops = {
+static const struct sdhci_ops tegra_sdhci_ops = {
 	.get_ro     = tegra_sdhci_get_ro,
 	.read_l     = tegra_sdhci_readl,
 	.read_w     = tegra_sdhci_readw,
 	.write_l    = tegra_sdhci_writel,
-	.platform_8bit_width = tegra_sdhci_8bit,
+	.platform_bus_width = tegra_sdhci_buswidth,
+	.platform_reset_exit = tegra_sdhci_reset_exit,
 };
 
-#ifdef CONFIG_ARCH_TEGRA_2x_SOC
-static struct sdhci_pltfm_data sdhci_tegra20_pdata = {
+static const struct sdhci_pltfm_data sdhci_tegra20_pdata = {
 	.quirks = SDHCI_QUIRK_BROKEN_TIMEOUT_VAL |
 		  SDHCI_QUIRK_SINGLE_POWER_WRITE |
 		  SDHCI_QUIRK_NO_HISPD_BIT |
@@ -164,10 +169,8 @@
 	.nvquirks = NVQUIRK_FORCE_SDHCI_SPEC_200 |
 		    NVQUIRK_ENABLE_BLOCK_GAP_DET,
 };
-#endif
 
-#ifdef CONFIG_ARCH_TEGRA_3x_SOC
-static struct sdhci_pltfm_data sdhci_tegra30_pdata = {
+static const struct sdhci_pltfm_data sdhci_tegra30_pdata = {
 	.quirks = SDHCI_QUIRK_BROKEN_TIMEOUT_VAL |
 		  SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK |
 		  SDHCI_QUIRK_SINGLE_POWER_WRITE |
@@ -178,131 +181,80 @@
 
 static struct sdhci_tegra_soc_data soc_data_tegra30 = {
 	.pdata = &sdhci_tegra30_pdata,
+	.nvquirks = NVQUIRK_ENABLE_SDHCI_SPEC_300,
+};
+
+static const struct sdhci_pltfm_data sdhci_tegra114_pdata = {
+	.quirks = SDHCI_QUIRK_BROKEN_TIMEOUT_VAL |
+		  SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK |
+		  SDHCI_QUIRK_SINGLE_POWER_WRITE |
+		  SDHCI_QUIRK_NO_HISPD_BIT |
+		  SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC,
+	.ops  = &tegra_sdhci_ops,
+};
+
+static struct sdhci_tegra_soc_data soc_data_tegra114 = {
+	.pdata = &sdhci_tegra114_pdata,
 };
-#endif
 
-static const struct of_device_id sdhci_tegra_dt_match[] __devinitdata = {
-#ifdef CONFIG_ARCH_TEGRA_3x_SOC
+static const struct of_device_id sdhci_tegra_dt_match[] = {
+	{ .compatible = "nvidia,tegra114-sdhci", .data = &soc_data_tegra114 },
 	{ .compatible = "nvidia,tegra30-sdhci", .data = &soc_data_tegra30 },
-#endif
-#ifdef CONFIG_ARCH_TEGRA_2x_SOC
 	{ .compatible = "nvidia,tegra20-sdhci", .data = &soc_data_tegra20 },
-#endif
 	{}
 };
-MODULE_DEVICE_TABLE(of, sdhci_dt_ids);
+MODULE_DEVICE_TABLE(of, sdhci_tegra_dt_match);
 
-static struct tegra_sdhci_platform_data * __devinit sdhci_tegra_dt_parse_pdata(
-						struct platform_device *pdev)
+static void sdhci_tegra_parse_dt(struct device *dev)
 {
-	struct tegra_sdhci_platform_data *plat;
-	struct device_node *np = pdev->dev.of_node;
-
-	if (!np)
-		return NULL;
-
-	plat = devm_kzalloc(&pdev->dev, sizeof(*plat), GFP_KERNEL);
-	if (!plat) {
-		dev_err(&pdev->dev, "Can't allocate platform data\n");
-		return NULL;
-	}
-
-	plat->cd_gpio = of_get_named_gpio(np, "cd-gpios", 0);
-	plat->wp_gpio = of_get_named_gpio(np, "wp-gpios", 0);
-	plat->power_gpio = of_get_named_gpio(np, "power-gpios", 0);
-	if (of_find_property(np, "support-8bit", NULL))
-		plat->is_8bit = 1;
+	struct device_node *np = dev->of_node;
+	struct sdhci_host *host = dev_get_drvdata(dev);
+	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+	struct sdhci_tegra *tegra_host = pltfm_host->priv;
 
-	return plat;
+	tegra_host->power_gpio = of_get_named_gpio(np, "power-gpios", 0);
+	mmc_of_parse(host->mmc);
 }
 
-static int __devinit sdhci_tegra_probe(struct platform_device *pdev)
+static int sdhci_tegra_probe(struct platform_device *pdev)
 {
 	const struct of_device_id *match;
 	const struct sdhci_tegra_soc_data *soc_data;
 	struct sdhci_host *host;
 	struct sdhci_pltfm_host *pltfm_host;
-	struct tegra_sdhci_platform_data *plat;
 	struct sdhci_tegra *tegra_host;
 	struct clk *clk;
 	int rc;
 
 	match = of_match_device(sdhci_tegra_dt_match, &pdev->dev);
-	if (match)
-		soc_data = match->data;
-	else
-		soc_data = &soc_data_tegra20;
+	if (!match)
+		return -EINVAL;
+	soc_data = match->data;
 
 	host = sdhci_pltfm_init(pdev, soc_data->pdata);
 	if (IS_ERR(host))
 		return PTR_ERR(host);
-
 	pltfm_host = sdhci_priv(host);
 
-	plat = pdev->dev.platform_data;
-
-	if (plat == NULL)
-		plat = sdhci_tegra_dt_parse_pdata(pdev);
-
-	if (plat == NULL) {
-		dev_err(mmc_dev(host->mmc), "missing platform data\n");
-		rc = -ENXIO;
-		goto err_no_plat;
-	}
-
 	tegra_host = devm_kzalloc(&pdev->dev, sizeof(*tegra_host), GFP_KERNEL);
 	if (!tegra_host) {
 		dev_err(mmc_dev(host->mmc), "failed to allocate tegra_host\n");
 		rc = -ENOMEM;
-		goto err_no_plat;
+		goto err_alloc_tegra_host;
 	}
-
-	tegra_host->plat = plat;
 	tegra_host->soc_data = soc_data;
-
 	pltfm_host->priv = tegra_host;
 
-	if (gpio_is_valid(plat->power_gpio)) {
-		rc = gpio_request(plat->power_gpio, "sdhci_power");
+	sdhci_tegra_parse_dt(&pdev->dev);
+
+	if (gpio_is_valid(tegra_host->power_gpio)) {
+		rc = gpio_request(tegra_host->power_gpio, "sdhci_power");
 		if (rc) {
 			dev_err(mmc_dev(host->mmc),
 				"failed to allocate power gpio\n");
 			goto err_power_req;
 		}
-		tegra_gpio_enable(plat->power_gpio);
-		gpio_direction_output(plat->power_gpio, 1);
-	}
-
-	if (gpio_is_valid(plat->cd_gpio)) {
-		rc = gpio_request(plat->cd_gpio, "sdhci_cd");
-		if (rc) {
-			dev_err(mmc_dev(host->mmc),
-				"failed to allocate cd gpio\n");
-			goto err_cd_req;
-		}
-		tegra_gpio_enable(plat->cd_gpio);
-		gpio_direction_input(plat->cd_gpio);
-
-		rc = request_irq(gpio_to_irq(plat->cd_gpio), carddetect_irq,
-				 IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
-				 mmc_hostname(host->mmc), host);
-
-		if (rc)	{
-			dev_err(mmc_dev(host->mmc), "request irq error\n");
-			goto err_cd_irq_req;
-		}
-
-	}
-
-	if (gpio_is_valid(plat->wp_gpio)) {
-		rc = gpio_request(plat->wp_gpio, "sdhci_wp");
-		if (rc) {
-			dev_err(mmc_dev(host->mmc),
-				"failed to allocate wp gpio\n");
-			goto err_wp_req;
-		}
-		tegra_gpio_enable(plat->wp_gpio);
-		gpio_direction_input(plat->wp_gpio);
+		gpio_direction_output(tegra_host->power_gpio, 1);
 	}
 
 	clk = clk_get(mmc_dev(host->mmc), NULL);
@@ -311,14 +263,9 @@
 		rc = PTR_ERR(clk);
 		goto err_clk_get;
 	}
-	clk_enable(clk);
+	clk_prepare_enable(clk);
 	pltfm_host->clk = clk;
 
-	host->mmc->pm_caps = plat->pm_flags;
-
-	if (plat->is_8bit)
-		host->mmc->caps |= MMC_CAP_8_BIT_DATA;
-
 	rc = sdhci_add_host(host);
 	if (rc)
 		goto err_add_host;
@@ -326,59 +273,30 @@
 	return 0;
 
 err_add_host:
-	clk_disable(pltfm_host->clk);
+	clk_disable_unprepare(pltfm_host->clk);
 	clk_put(pltfm_host->clk);
 err_clk_get:
-	if (gpio_is_valid(plat->wp_gpio)) {
-		tegra_gpio_disable(plat->wp_gpio);
-		gpio_free(plat->wp_gpio);
-	}
-err_wp_req:
-	if (gpio_is_valid(plat->cd_gpio))
-		free_irq(gpio_to_irq(plat->cd_gpio), host);
-err_cd_irq_req:
-	if (gpio_is_valid(plat->cd_gpio)) {
-		tegra_gpio_disable(plat->cd_gpio);
-		gpio_free(plat->cd_gpio);
-	}
-err_cd_req:
-	if (gpio_is_valid(plat->power_gpio)) {
-		tegra_gpio_disable(plat->power_gpio);
-		gpio_free(plat->power_gpio);
-	}
+	if (gpio_is_valid(tegra_host->power_gpio))
+		gpio_free(tegra_host->power_gpio);
 err_power_req:
-err_no_plat:
+err_alloc_tegra_host:
 	sdhci_pltfm_free(pdev);
 	return rc;
 }
 
-static int __devexit sdhci_tegra_remove(struct platform_device *pdev)
+static int sdhci_tegra_remove(struct platform_device *pdev)
 {
 	struct sdhci_host *host = platform_get_drvdata(pdev);
 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
 	struct sdhci_tegra *tegra_host = pltfm_host->priv;
-	const struct tegra_sdhci_platform_data *plat = tegra_host->plat;
 	int dead = (readl(host->ioaddr + SDHCI_INT_STATUS) == 0xffffffff);
 
 	sdhci_remove_host(host, dead);
 
-	if (gpio_is_valid(plat->wp_gpio)) {
-		tegra_gpio_disable(plat->wp_gpio);
-		gpio_free(plat->wp_gpio);
-	}
-
-	if (gpio_is_valid(plat->cd_gpio)) {
-		free_irq(gpio_to_irq(plat->cd_gpio), host);
-		tegra_gpio_disable(plat->cd_gpio);
-		gpio_free(plat->cd_gpio);
-	}
-
-	if (gpio_is_valid(plat->power_gpio)) {
-		tegra_gpio_disable(plat->power_gpio);
-		gpio_free(plat->power_gpio);
-	}
+	if (gpio_is_valid(tegra_host->power_gpio))
+		gpio_free(tegra_host->power_gpio);
 
-	clk_disable(pltfm_host->clk);
+	clk_disable_unprepare(pltfm_host->clk);
 	clk_put(pltfm_host->clk);
 
 	sdhci_pltfm_free(pdev);
@@ -394,7 +312,7 @@
 		.pm	= SDHCI_PLTFM_PMOPS,
 	},
 	.probe		= sdhci_tegra_probe,
-	.remove		= __devexit_p(sdhci_tegra_remove),
+	.remove		= sdhci_tegra_remove,
 };
 
 module_platform_driver(sdhci_tegra_driver);
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/sdricoh_cs.c linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/sdricoh_cs.c
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/sdricoh_cs.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/sdricoh_cs.c	2014-09-12 15:59:37.348052000 +0800
@@ -543,25 +543,7 @@
 	.suspend = sdricoh_pcmcia_suspend,
 	.resume = sdricoh_pcmcia_resume,
 };
-
-/*****************************************************************************\
- *                                                                           *
- * Driver init/exit                                                          *
- *                                                                           *
-\*****************************************************************************/
-
-static int __init sdricoh_drv_init(void)
-{
-	return pcmcia_register_driver(&sdricoh_driver);
-}
-
-static void __exit sdricoh_drv_exit(void)
-{
-	pcmcia_unregister_driver(&sdricoh_driver);
-}
-
-module_init(sdricoh_drv_init);
-module_exit(sdricoh_drv_exit);
+module_pcmcia_driver(sdricoh_driver);
 
 module_param(switchlocked, uint, 0444);
 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/sh_mmcif.c linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/sh_mmcif.c
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/sh_mmcif.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/sh_mmcif.c	2014-09-12 15:59:37.348052000 +0800
@@ -54,6 +54,9 @@
 #include <linux/mmc/mmc.h>
 #include <linux/mmc/sdio.h>
 #include <linux/mmc/sh_mmcif.h>
+#include <linux/mmc/slot-gpio.h>
+#include <linux/mod_devicetable.h>
+#include <linux/mutex.h>
 #include <linux/pagemap.h>
 #include <linux/platform_device.h>
 #include <linux/pm_qos.h>
@@ -86,6 +89,7 @@
 #define CMD_SET_TBIT		(1 << 7) /* 1: tran mission bit "Low" */
 #define CMD_SET_OPDM		(1 << 6) /* 1: open/drain */
 #define CMD_SET_CCSH		(1 << 5)
+#define CMD_SET_DARS		(1 << 2) /* Dual Data Rate */
 #define CMD_SET_DATW_1		((0 << 1) | (0 << 0)) /* 1bit */
 #define CMD_SET_DATW_4		((0 << 1) | (1 << 0)) /* 4bit */
 #define CMD_SET_DATW_8		((1 << 1) | (0 << 0)) /* 8bit */
@@ -125,6 +129,10 @@
 				 INT_CCSTO | INT_CRCSTO | INT_WDATTO |	  \
 				 INT_RDATTO | INT_RBSYTO | INT_RSPTO)
 
+#define INT_ALL			(INT_RBSYE | INT_CRSPE | INT_BUFREN |	 \
+				 INT_BUFWEN | INT_CMD12DRE | INT_BUFRE | \
+				 INT_DTRANE | INT_CMD12RBE | INT_CMD12CRE)
+
 /* CE_INT_MASK */
 #define MASK_ALL		0x00000000
 #define MASK_MCCSDE		(1 << 29)
@@ -156,6 +164,11 @@
 				 MASK_MCCSTO | MASK_MCRCSTO | MASK_MWDATTO | \
 				 MASK_MRDATTO | MASK_MRBSYTO | MASK_MRSPTO)
 
+#define MASK_CLEAN		(INT_ERR_STS | MASK_MRBSYE | MASK_MCRSPE |	\
+				 MASK_MBUFREN | MASK_MBUFWEN |			\
+				 MASK_MCMD12DRE | MASK_MBUFRE | MASK_MDTRANE |	\
+				 MASK_MCMD12RBE | MASK_MCMD12CRE)
+
 /* CE_HOST_STS1 */
 #define STS1_CMDSEQ		(1 << 31)
 
@@ -193,6 +206,7 @@
 	STATE_IDLE,
 	STATE_REQUEST,
 	STATE_IOS,
+	STATE_TIMEOUT,
 };
 
 enum mmcif_wait_for {
@@ -211,11 +225,10 @@
 	struct mmc_host *mmc;
 	struct mmc_request *mrq;
 	struct platform_device *pd;
-	struct sh_dmae_slave dma_slave_tx;
-	struct sh_dmae_slave dma_slave_rx;
 	struct clk *hclk;
 	unsigned int clk;
 	int bus_width;
+	unsigned char timing;
 	bool sd_error;
 	bool dying;
 	long timeout;
@@ -230,6 +243,7 @@
 	int sg_blkidx;
 	bool power;
 	bool card_present;
+	struct mutex thread_lock;
 
 	/* DMA support */
 	struct dma_chan		*chan_rx;
@@ -253,23 +267,14 @@
 static void mmcif_dma_complete(void *arg)
 {
 	struct sh_mmcif_host *host = arg;
-	struct mmc_data *data = host->mrq->data;
+	struct mmc_request *mrq = host->mrq;
 
 	dev_dbg(&host->pd->dev, "Command completed\n");
 
-	if (WARN(!data, "%s: NULL data in DMA completion!\n",
+	if (WARN(!mrq || !mrq->data, "%s: NULL data in DMA completion!\n",
 		 dev_name(&host->pd->dev)))
 		return;
 
-	if (data->flags & MMC_DATA_READ)
-		dma_unmap_sg(host->chan_rx->device->dev,
-			     data->sg, data->sg_len,
-			     DMA_FROM_DEVICE);
-	else
-		dma_unmap_sg(host->chan_tx->device->dev,
-			     data->sg, data->sg_len,
-			     DMA_TO_DEVICE);
-
 	complete(&host->dma_complete);
 }
 
@@ -371,56 +376,67 @@
 		desc, cookie);
 }
 
-static bool sh_mmcif_filter(struct dma_chan *chan, void *arg)
-{
-	dev_dbg(chan->device->dev, "%s: slave data %p\n", __func__, arg);
-	chan->private = arg;
-	return true;
-}
-
 static void sh_mmcif_request_dma(struct sh_mmcif_host *host,
 				 struct sh_mmcif_plat_data *pdata)
 {
-	struct sh_dmae_slave *tx, *rx;
+	struct resource *res = platform_get_resource(host->pd, IORESOURCE_MEM, 0);
+	struct dma_slave_config cfg;
+	dma_cap_mask_t mask;
+	int ret;
+
 	host->dma_active = false;
 
+	if (!pdata)
+		return;
+
+	if (pdata->slave_id_tx <= 0 || pdata->slave_id_rx <= 0)
+		return;
+
 	/* We can only either use DMA for both Tx and Rx or not use it at all */
-	if (pdata->dma) {
-		dev_warn(&host->pd->dev,
-			 "Update your platform to use embedded DMA slave IDs\n");
-		tx = &pdata->dma->chan_priv_tx;
-		rx = &pdata->dma->chan_priv_rx;
-	} else {
-		tx = &host->dma_slave_tx;
-		tx->slave_id = pdata->slave_id_tx;
-		rx = &host->dma_slave_rx;
-		rx->slave_id = pdata->slave_id_rx;
-	}
-	if (tx->slave_id > 0 && rx->slave_id > 0) {
-		dma_cap_mask_t mask;
-
-		dma_cap_zero(mask);
-		dma_cap_set(DMA_SLAVE, mask);
-
-		host->chan_tx = dma_request_channel(mask, sh_mmcif_filter, tx);
-		dev_dbg(&host->pd->dev, "%s: TX: got channel %p\n", __func__,
-			host->chan_tx);
-
-		if (!host->chan_tx)
-			return;
-
-		host->chan_rx = dma_request_channel(mask, sh_mmcif_filter, rx);
-		dev_dbg(&host->pd->dev, "%s: RX: got channel %p\n", __func__,
-			host->chan_rx);
+	dma_cap_zero(mask);
+	dma_cap_set(DMA_SLAVE, mask);
 
-		if (!host->chan_rx) {
-			dma_release_channel(host->chan_tx);
-			host->chan_tx = NULL;
-			return;
-		}
+	host->chan_tx = dma_request_channel(mask, shdma_chan_filter,
+					    (void *)pdata->slave_id_tx);
+	dev_dbg(&host->pd->dev, "%s: TX: got channel %p\n", __func__,
+		host->chan_tx);
 
-		init_completion(&host->dma_complete);
-	}
+	if (!host->chan_tx)
+		return;
+
+	cfg.slave_id = pdata->slave_id_tx;
+	cfg.direction = DMA_MEM_TO_DEV;
+	cfg.dst_addr = res->start + MMCIF_CE_DATA;
+	cfg.src_addr = 0;
+	ret = dmaengine_slave_config(host->chan_tx, &cfg);
+	if (ret < 0)
+		goto ecfgtx;
+
+	host->chan_rx = dma_request_channel(mask, shdma_chan_filter,
+					    (void *)pdata->slave_id_rx);
+	dev_dbg(&host->pd->dev, "%s: RX: got channel %p\n", __func__,
+		host->chan_rx);
+
+	if (!host->chan_rx)
+		goto erqrx;
+
+	cfg.slave_id = pdata->slave_id_rx;
+	cfg.direction = DMA_DEV_TO_MEM;
+	cfg.dst_addr = 0;
+	cfg.src_addr = res->start + MMCIF_CE_DATA;
+	ret = dmaengine_slave_config(host->chan_rx, &cfg);
+	if (ret < 0)
+		goto ecfgrx;
+
+	return;
+
+ecfgrx:
+	dma_release_channel(host->chan_rx);
+	host->chan_rx = NULL;
+erqrx:
+ecfgtx:
+	dma_release_channel(host->chan_tx);
+	host->chan_tx = NULL;
 }
 
 static void sh_mmcif_release_dma(struct sh_mmcif_host *host)
@@ -444,13 +460,14 @@
 static void sh_mmcif_clock_control(struct sh_mmcif_host *host, unsigned int clk)
 {
 	struct sh_mmcif_plat_data *p = host->pd->dev.platform_data;
+	bool sup_pclk = p ? p->sup_pclk : false;
 
 	sh_mmcif_bitclr(host, MMCIF_CE_CLK_CTRL, CLK_ENABLE);
 	sh_mmcif_bitclr(host, MMCIF_CE_CLK_CTRL, CLK_CLEAR);
 
 	if (!clk)
 		return;
-	if (p->sup_pclk && clk == host->clk)
+	if (sup_pclk && clk == host->clk)
 		sh_mmcif_bitset(host, MMCIF_CE_CLK_CTRL, CLK_SUP_PCLK);
 	else
 		sh_mmcif_bitset(host, MMCIF_CE_CLK_CTRL, CLK_CLEAR &
@@ -506,13 +523,16 @@
 	}
 
 	if (state2 & STS2_CRC_ERR) {
-		dev_dbg(&host->pd->dev, ": CRC error\n");
+		dev_err(&host->pd->dev, " CRC error: state %u, wait %u\n",
+			host->state, host->wait_for);
 		ret = -EIO;
 	} else if (state2 & STS2_TIMEOUT_ERR) {
-		dev_dbg(&host->pd->dev, ": Timeout\n");
+		dev_err(&host->pd->dev, " Timeout: state %u, wait %u\n",
+			host->state, host->wait_for);
 		ret = -ETIMEDOUT;
 	} else {
-		dev_dbg(&host->pd->dev, ": End/Index error\n");
+		dev_dbg(&host->pd->dev, " End/Index error: state %u, wait %u\n",
+			host->state, host->wait_for);
 		ret = -EIO;
 	}
 	return ret;
@@ -535,10 +555,7 @@
 		host->pio_ptr = p;
 	}
 
-	if (host->sg_idx == data->sg_len)
-		return false;
-
-	return true;
+	return host->sg_idx != data->sg_len;
 }
 
 static void sh_mmcif_single_read(struct sh_mmcif_host *host,
@@ -548,7 +565,6 @@
 			   BLOCK_SIZE_MASK) + 3;
 
 	host->wait_for = MMCIF_WAIT_FOR_READ;
-	schedule_delayed_work(&host->timeout_work, host->timeout);
 
 	/* buf read enable */
 	sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFREN);
@@ -562,6 +578,7 @@
 
 	if (host->sd_error) {
 		data->error = sh_mmcif_error_manage(host);
+		dev_dbg(&host->pd->dev, "%s(): %d\n", __func__, data->error);
 		return false;
 	}
 
@@ -590,7 +607,7 @@
 	host->sg_idx = 0;
 	host->sg_blkidx = 0;
 	host->pio_ptr = sg_virt(data->sg);
-	schedule_delayed_work(&host->timeout_work, host->timeout);
+
 	sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFREN);
 }
 
@@ -602,6 +619,7 @@
 
 	if (host->sd_error) {
 		data->error = sh_mmcif_error_manage(host);
+		dev_dbg(&host->pd->dev, "%s(): %d\n", __func__, data->error);
 		return false;
 	}
 
@@ -613,7 +631,6 @@
 	if (!sh_mmcif_next_block(host, p))
 		return false;
 
-	schedule_delayed_work(&host->timeout_work, host->timeout);
 	sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFREN);
 
 	return true;
@@ -626,7 +643,6 @@
 			   BLOCK_SIZE_MASK) + 3;
 
 	host->wait_for = MMCIF_WAIT_FOR_WRITE;
-	schedule_delayed_work(&host->timeout_work, host->timeout);
 
 	/* buf write enable */
 	sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFWEN);
@@ -640,6 +656,7 @@
 
 	if (host->sd_error) {
 		data->error = sh_mmcif_error_manage(host);
+		dev_dbg(&host->pd->dev, "%s(): %d\n", __func__, data->error);
 		return false;
 	}
 
@@ -668,7 +685,7 @@
 	host->sg_idx = 0;
 	host->sg_blkidx = 0;
 	host->pio_ptr = sg_virt(data->sg);
-	schedule_delayed_work(&host->timeout_work, host->timeout);
+
 	sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFWEN);
 }
 
@@ -680,6 +697,7 @@
 
 	if (host->sd_error) {
 		data->error = sh_mmcif_error_manage(host);
+		dev_dbg(&host->pd->dev, "%s(): %d\n", __func__, data->error);
 		return false;
 	}
 
@@ -691,7 +709,6 @@
 	if (!sh_mmcif_next_block(host, p))
 		return false;
 
-	schedule_delayed_work(&host->timeout_work, host->timeout);
 	sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFWEN);
 
 	return true;
@@ -742,6 +759,7 @@
 	}
 	switch (opc) {
 	/* RBSY */
+	case MMC_SLEEP_AWAKE:
 	case MMC_SWITCH:
 	case MMC_STOP_TRANSMISSION:
 	case MMC_SET_WRITE_PROT:
@@ -767,6 +785,17 @@
 			dev_err(&host->pd->dev, "Unsupported bus width.\n");
 			break;
 		}
+		switch (host->timing) {
+		case MMC_TIMING_UHS_DDR50:
+			/*
+			 * MMC core will only set this timing, if the host
+			 * advertises the MMC_CAP_UHS_DDR50 capability. MMCIF
+			 * implementations with this capability, e.g. sh73a0,
+			 * will have to set it in their platform data.
+			 */
+			tmp |= CMD_SET_DARS;
+			break;
+		}
 	}
 	/* DWEN */
 	if (opc == MMC_WRITE_BLOCK || opc == MMC_WRITE_MULTIPLE_BLOCK)
@@ -810,7 +839,7 @@
 		sh_mmcif_single_read(host, mrq);
 		return 0;
 	default:
-		dev_err(&host->pd->dev, "UNSUPPORTED CMD = d'%08d\n", opc);
+		dev_err(&host->pd->dev, "Unsupported CMD%d\n", opc);
 		return -EINVAL;
 	}
 }
@@ -824,6 +853,7 @@
 
 	switch (opc) {
 	/* response busy check */
+	case MMC_SLEEP_AWAKE:
 	case MMC_SWITCH:
 	case MMC_STOP_TRANSMISSION:
 	case MMC_SET_WRITE_PROT:
@@ -871,7 +901,6 @@
 	}
 
 	host->wait_for = MMCIF_WAIT_FOR_STOP;
-	schedule_delayed_work(&host->timeout_work, host->timeout);
 }
 
 static void sh_mmcif_request(struct mmc_host *mmc, struct mmc_request *mrq)
@@ -881,6 +910,7 @@
 
 	spin_lock_irqsave(&host->lock, flags);
 	if (host->state != STATE_IDLE) {
+		dev_dbg(&host->pd->dev, "%s() rejected, state %u\n", __func__, host->state);
 		spin_unlock_irqrestore(&host->lock, flags);
 		mrq->cmd->error = -EAGAIN;
 		mmc_request_done(mmc, mrq);
@@ -892,21 +922,16 @@
 
 	switch (mrq->cmd->opcode) {
 	/* MMCIF does not support SD/SDIO command */
-	case SD_IO_SEND_OP_COND:
+	case MMC_SLEEP_AWAKE: /* = SD_IO_SEND_OP_COND (5) */
+	case MMC_SEND_EXT_CSD: /* = SD_SEND_IF_COND (8) */
+		if ((mrq->cmd->flags & MMC_CMD_MASK) != MMC_CMD_BCR)
+			break;
 	case MMC_APP_CMD:
+	case SD_IO_RW_DIRECT:
 		host->state = STATE_IDLE;
 		mrq->cmd->error = -ETIMEDOUT;
 		mmc_request_done(mmc, mrq);
 		return;
-	case MMC_SEND_EXT_CSD: /* = SD_SEND_IF_COND (8) */
-		if (!mrq->data) {
-			/* send_if_cond cmd (not support) */
-			host->state = STATE_IDLE;
-			mrq->cmd->error = -ETIMEDOUT;
-			mmc_request_done(mmc, mrq);
-			return;
-		}
-		break;
 	default:
 		break;
 	}
@@ -916,14 +941,40 @@
 	sh_mmcif_start_cmd(host, mrq);
 }
 
+static int sh_mmcif_clk_update(struct sh_mmcif_host *host)
+{
+	int ret = clk_enable(host->hclk);
+
+	if (!ret) {
+		host->clk = clk_get_rate(host->hclk);
+		host->mmc->f_max = host->clk / 2;
+		host->mmc->f_min = host->clk / 512;
+	}
+
+	return ret;
+}
+
+static void sh_mmcif_set_power(struct sh_mmcif_host *host, struct mmc_ios *ios)
+{
+	struct sh_mmcif_plat_data *pd = host->pd->dev.platform_data;
+	struct mmc_host *mmc = host->mmc;
+
+	if (pd && pd->set_pwr)
+		pd->set_pwr(host->pd, ios->power_mode != MMC_POWER_OFF);
+	if (!IS_ERR(mmc->supply.vmmc))
+		/* Errors ignored... */
+		mmc_regulator_set_ocr(mmc, mmc->supply.vmmc,
+				      ios->power_mode ? ios->vdd : 0);
+}
+
 static void sh_mmcif_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 {
 	struct sh_mmcif_host *host = mmc_priv(mmc);
-	struct sh_mmcif_plat_data *p = host->pd->dev.platform_data;
 	unsigned long flags;
 
 	spin_lock_irqsave(&host->lock, flags);
 	if (host->state != STATE_IDLE) {
+		dev_dbg(&host->pd->dev, "%s() rejected, state %u\n", __func__, host->state);
 		spin_unlock_irqrestore(&host->lock, flags);
 		return;
 	}
@@ -937,6 +988,7 @@
 			sh_mmcif_request_dma(host, host->pd->dev.platform_data);
 			host->card_present = true;
 		}
+		sh_mmcif_set_power(host, ios);
 	} else if (ios->power_mode == MMC_POWER_OFF || !ios->clock) {
 		/* clock stop */
 		sh_mmcif_clock_control(host, 0);
@@ -947,10 +999,11 @@
 			}
 		}
 		if (host->power) {
-			pm_runtime_put(&host->pd->dev);
+			pm_runtime_put_sync(&host->pd->dev);
+			clk_disable(host->hclk);
 			host->power = false;
-			if (p->down_pwr && ios->power_mode == MMC_POWER_OFF)
-				p->down_pwr(host->pd);
+			if (ios->power_mode == MMC_POWER_OFF)
+				sh_mmcif_set_power(host, ios);
 		}
 		host->state = STATE_IDLE;
 		return;
@@ -958,8 +1011,7 @@
 
 	if (ios->clock) {
 		if (!host->power) {
-			if (p->set_pwr)
-				p->set_pwr(host->pd, ios->power_mode);
+			sh_mmcif_clk_update(host);
 			pm_runtime_get_sync(&host->pd->dev);
 			host->power = true;
 			sh_mmcif_sync_reset(host);
@@ -967,6 +1019,7 @@
 		sh_mmcif_clock_control(host, ios->clock);
 	}
 
+	host->timing = ios->timing;
 	host->bus_width = ios->bus_width;
 	host->state = STATE_IDLE;
 }
@@ -975,8 +1028,12 @@
 {
 	struct sh_mmcif_host *host = mmc_priv(mmc);
 	struct sh_mmcif_plat_data *p = host->pd->dev.platform_data;
+	int ret = mmc_gpio_get_cd(mmc);
+
+	if (ret >= 0)
+		return ret;
 
-	if (!p->get_cd)
+	if (!p || !p->get_cd)
 		return -ENOSYS;
 	else
 		return p->get_cd(host->pd);
@@ -1000,14 +1057,14 @@
 		case MMC_SELECT_CARD:
 		case MMC_APP_CMD:
 			cmd->error = -ETIMEDOUT;
-			host->sd_error = false;
 			break;
 		default:
 			cmd->error = sh_mmcif_error_manage(host);
-			dev_dbg(&host->pd->dev, "Cmd(d'%d) error %d\n",
-				cmd->opcode, cmd->error);
 			break;
 		}
+		dev_dbg(&host->pd->dev, "CMD%d error %d\n",
+			cmd->opcode, cmd->error);
+		host->sd_error = false;
 		return false;
 	}
 	if (!(cmd->flags & MMC_RSP_PRESENT)) {
@@ -1020,6 +1077,12 @@
 	if (!data)
 		return false;
 
+	/*
+	 * Completion can be signalled from DMA callback and error, so, have to
+	 * reset here, before setting .dma_active
+	 */
+	init_completion(&host->dma_complete);
+
 	if (data->flags & MMC_DATA_READ) {
 		if (host->chan_rx)
 			sh_mmcif_start_dma_rx(host);
@@ -1030,34 +1093,47 @@
 
 	if (!host->dma_active) {
 		data->error = sh_mmcif_data_trans(host, host->mrq, cmd->opcode);
-		if (!data->error)
-			return true;
-		return false;
+		return !data->error;
 	}
 
 	/* Running in the IRQ thread, can sleep */
 	time = wait_for_completion_interruptible_timeout(&host->dma_complete,
 							 host->timeout);
+
+	if (data->flags & MMC_DATA_READ)
+		dma_unmap_sg(host->chan_rx->device->dev,
+			     data->sg, data->sg_len,
+			     DMA_FROM_DEVICE);
+	else
+		dma_unmap_sg(host->chan_tx->device->dev,
+			     data->sg, data->sg_len,
+			     DMA_TO_DEVICE);
+
 	if (host->sd_error) {
 		dev_err(host->mmc->parent,
 			"Error IRQ while waiting for DMA completion!\n");
 		/* Woken up by an error IRQ: abort DMA */
-		if (data->flags & MMC_DATA_READ)
-			dmaengine_terminate_all(host->chan_rx);
-		else
-			dmaengine_terminate_all(host->chan_tx);
 		data->error = sh_mmcif_error_manage(host);
 	} else if (!time) {
+		dev_err(host->mmc->parent, "DMA timeout!\n");
 		data->error = -ETIMEDOUT;
 	} else if (time < 0) {
+		dev_err(host->mmc->parent,
+			"wait_for_completion_...() error %ld!\n", time);
 		data->error = time;
 	}
 	sh_mmcif_bitclr(host, MMCIF_CE_BUF_ACC,
 			BUF_ACC_DMAREN | BUF_ACC_DMAWEN);
 	host->dma_active = false;
 
-	if (data->error)
+	if (data->error) {
 		data->bytes_xfered = 0;
+		/* Abort DMA */
+		if (data->flags & MMC_DATA_READ)
+			dmaengine_terminate_all(host->chan_rx);
+		else
+			dmaengine_terminate_all(host->chan_tx);
+	}
 
 	return false;
 }
@@ -1065,11 +1141,21 @@
 static irqreturn_t sh_mmcif_irqt(int irq, void *dev_id)
 {
 	struct sh_mmcif_host *host = dev_id;
-	struct mmc_request *mrq = host->mrq;
-	struct mmc_data *data = mrq->data;
+	struct mmc_request *mrq;
+	bool wait = false;
 
 	cancel_delayed_work_sync(&host->timeout_work);
 
+	mutex_lock(&host->thread_lock);
+
+	mrq = host->mrq;
+	if (!mrq) {
+		dev_dbg(&host->pd->dev, "IRQ thread state %u, wait %u: NULL mrq!\n",
+			host->state, host->wait_for);
+		mutex_unlock(&host->thread_lock);
+		return IRQ_HANDLED;
+	}
+
 	/*
 	 * All handlers return true, if processing continues, and false, if the
 	 * request has to be completed - successfully or not
@@ -1077,35 +1163,32 @@
 	switch (host->wait_for) {
 	case MMCIF_WAIT_FOR_REQUEST:
 		/* We're too late, the timeout has already kicked in */
+		mutex_unlock(&host->thread_lock);
 		return IRQ_HANDLED;
 	case MMCIF_WAIT_FOR_CMD:
-		if (sh_mmcif_end_cmd(host))
-			/* Wait for data */
-			return IRQ_HANDLED;
+		/* Wait for data? */
+		wait = sh_mmcif_end_cmd(host);
 		break;
 	case MMCIF_WAIT_FOR_MREAD:
-		if (sh_mmcif_mread_block(host))
-			/* Wait for more data */
-			return IRQ_HANDLED;
+		/* Wait for more data? */
+		wait = sh_mmcif_mread_block(host);
 		break;
 	case MMCIF_WAIT_FOR_READ:
-		if (sh_mmcif_read_block(host))
-			/* Wait for data end */
-			return IRQ_HANDLED;
+		/* Wait for data end? */
+		wait = sh_mmcif_read_block(host);
 		break;
 	case MMCIF_WAIT_FOR_MWRITE:
-		if (sh_mmcif_mwrite_block(host))
-			/* Wait data to write */
-			return IRQ_HANDLED;
+		/* Wait data to write? */
+		wait = sh_mmcif_mwrite_block(host);
 		break;
 	case MMCIF_WAIT_FOR_WRITE:
-		if (sh_mmcif_write_block(host))
-			/* Wait for data end */
-			return IRQ_HANDLED;
+		/* Wait for data end? */
+		wait = sh_mmcif_write_block(host);
 		break;
 	case MMCIF_WAIT_FOR_STOP:
 		if (host->sd_error) {
 			mrq->stop->error = sh_mmcif_error_manage(host);
+			dev_dbg(&host->pd->dev, "%s(): %d\n", __func__, mrq->stop->error);
 			break;
 		}
 		sh_mmcif_get_cmd12response(host, mrq->stop);
@@ -1113,22 +1196,35 @@
 		break;
 	case MMCIF_WAIT_FOR_READ_END:
 	case MMCIF_WAIT_FOR_WRITE_END:
-		if (host->sd_error)
-			data->error = sh_mmcif_error_manage(host);
+		if (host->sd_error) {
+			mrq->data->error = sh_mmcif_error_manage(host);
+			dev_dbg(&host->pd->dev, "%s(): %d\n", __func__, mrq->data->error);
+		}
 		break;
 	default:
 		BUG();
 	}
 
+	if (wait) {
+		schedule_delayed_work(&host->timeout_work, host->timeout);
+		/* Wait for more data */
+		mutex_unlock(&host->thread_lock);
+		return IRQ_HANDLED;
+	}
+
 	if (host->wait_for != MMCIF_WAIT_FOR_STOP) {
+		struct mmc_data *data = mrq->data;
 		if (!mrq->cmd->error && data && !data->error)
 			data->bytes_xfered =
 				data->blocks * data->blksz;
 
 		if (mrq->stop && !mrq->cmd->error && (!data || !data->error)) {
 			sh_mmcif_stop_cmd(host, mrq);
-			if (!mrq->stop->error)
+			if (!mrq->stop->error) {
+				schedule_delayed_work(&host->timeout_work, host->timeout);
+				mutex_unlock(&host->thread_lock);
 				return IRQ_HANDLED;
+			}
 		}
 	}
 
@@ -1137,6 +1233,8 @@
 	host->mrq = NULL;
 	mmc_request_done(host->mmc, mrq);
 
+	mutex_unlock(&host->thread_lock);
+
 	return IRQ_HANDLED;
 }
 
@@ -1144,54 +1242,22 @@
 {
 	struct sh_mmcif_host *host = dev_id;
 	u32 state;
-	int err = 0;
 
 	state = sh_mmcif_readl(host->addr, MMCIF_CE_INT);
+	sh_mmcif_writel(host->addr, MMCIF_CE_INT, ~state);
+	sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, state & MASK_CLEAN);
 
-	if (state & INT_ERR_STS) {
-		/* error interrupts - process first */
-		sh_mmcif_writel(host->addr, MMCIF_CE_INT, ~state);
-		sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, state);
-		err = 1;
-	} else if (state & INT_RBSYE) {
-		sh_mmcif_writel(host->addr, MMCIF_CE_INT,
-				~(INT_RBSYE | INT_CRSPE));
-		sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MRBSYE);
-	} else if (state & INT_CRSPE) {
-		sh_mmcif_writel(host->addr, MMCIF_CE_INT, ~INT_CRSPE);
-		sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MCRSPE);
-	} else if (state & INT_BUFREN) {
-		sh_mmcif_writel(host->addr, MMCIF_CE_INT, ~INT_BUFREN);
-		sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MBUFREN);
-	} else if (state & INT_BUFWEN) {
-		sh_mmcif_writel(host->addr, MMCIF_CE_INT, ~INT_BUFWEN);
-		sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MBUFWEN);
-	} else if (state & INT_CMD12DRE) {
-		sh_mmcif_writel(host->addr, MMCIF_CE_INT,
-			~(INT_CMD12DRE | INT_CMD12RBE |
-			  INT_CMD12CRE | INT_BUFRE));
-		sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MCMD12DRE);
-	} else if (state & INT_BUFRE) {
-		sh_mmcif_writel(host->addr, MMCIF_CE_INT, ~INT_BUFRE);
-		sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MBUFRE);
-	} else if (state & INT_DTRANE) {
-		sh_mmcif_writel(host->addr, MMCIF_CE_INT, ~INT_DTRANE);
-		sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MDTRANE);
-	} else if (state & INT_CMD12RBE) {
-		sh_mmcif_writel(host->addr, MMCIF_CE_INT,
-				~(INT_CMD12RBE | INT_CMD12CRE));
-		sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MCMD12RBE);
-	} else {
-		dev_dbg(&host->pd->dev, "Unsupported interrupt: 0x%x\n", state);
-		sh_mmcif_writel(host->addr, MMCIF_CE_INT, ~state);
-		sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, state);
-		err = 1;
-	}
-	if (err) {
+	if (state & ~MASK_CLEAN)
+		dev_dbg(&host->pd->dev, "IRQ state = 0x%08x incompletely cleared\n",
+			state);
+
+	if (state & INT_ERR_STS || state & ~INT_ALL) {
 		host->sd_error = true;
-		dev_dbg(&host->pd->dev, "int err state = %08x\n", state);
+		dev_dbg(&host->pd->dev, "int err state = 0x%08x\n", state);
 	}
 	if (state & ~(INT_CMD12RBE | INT_CMD12CRE)) {
+		if (!host->mrq)
+			dev_dbg(&host->pd->dev, "NULL IRQ state = 0x%08x\n", state);
 		if (!host->dma_active)
 			return IRQ_WAKE_THREAD;
 		else if (host->sd_error)
@@ -1208,11 +1274,24 @@
 	struct delayed_work *d = container_of(work, struct delayed_work, work);
 	struct sh_mmcif_host *host = container_of(d, struct sh_mmcif_host, timeout_work);
 	struct mmc_request *mrq = host->mrq;
+	unsigned long flags;
 
 	if (host->dying)
 		/* Don't run after mmc_remove_host() */
 		return;
 
+	dev_err(&host->pd->dev, "Timeout waiting for %u on CMD%u\n",
+		host->wait_for, mrq->cmd->opcode);
+
+	spin_lock_irqsave(&host->lock, flags);
+	if (host->state == STATE_IDLE) {
+		spin_unlock_irqrestore(&host->lock, flags);
+		return;
+	}
+
+	host->state = STATE_TIMEOUT;
+	spin_unlock_irqrestore(&host->lock, flags);
+
 	/*
 	 * Handle races with cancel_delayed_work(), unless
 	 * cancel_delayed_work_sync() is used
@@ -1242,19 +1321,35 @@
 	mmc_request_done(host->mmc, mrq);
 }
 
-static int __devinit sh_mmcif_probe(struct platform_device *pdev)
+static void sh_mmcif_init_ocr(struct sh_mmcif_host *host)
+{
+	struct sh_mmcif_plat_data *pd = host->pd->dev.platform_data;
+	struct mmc_host *mmc = host->mmc;
+
+	mmc_regulator_get_supply(mmc);
+
+	if (!pd)
+		return;
+
+	if (!mmc->ocr_avail)
+		mmc->ocr_avail = pd->ocr;
+	else if (pd->ocr)
+		dev_warn(mmc_dev(mmc), "Platform OCR mask is ignored\n");
+}
+
+static int sh_mmcif_probe(struct platform_device *pdev)
 {
 	int ret = 0, irq[2];
 	struct mmc_host *mmc;
 	struct sh_mmcif_host *host;
-	struct sh_mmcif_plat_data *pd;
+	struct sh_mmcif_plat_data *pd = pdev->dev.platform_data;
 	struct resource *res;
 	void __iomem *reg;
-	char clk_name[8];
+	const char *name;
 
 	irq[0] = platform_get_irq(pdev, 0);
 	irq[1] = platform_get_irq(pdev, 1);
-	if (irq[0] < 0 || irq[1] < 0) {
+	if (irq[0] < 0) {
 		dev_err(&pdev->dev, "Get irq error\n");
 		return -ENXIO;
 	}
@@ -1268,42 +1363,27 @@
 		dev_err(&pdev->dev, "ioremap error.\n");
 		return -ENOMEM;
 	}
-	pd = pdev->dev.platform_data;
-	if (!pd) {
-		dev_err(&pdev->dev, "sh_mmcif plat data error.\n");
-		ret = -ENXIO;
-		goto clean_up;
-	}
+
 	mmc = mmc_alloc_host(sizeof(struct sh_mmcif_host), &pdev->dev);
 	if (!mmc) {
 		ret = -ENOMEM;
-		goto clean_up;
+		goto ealloch;
 	}
+	mmc_of_parse(mmc);
 	host		= mmc_priv(mmc);
 	host->mmc	= mmc;
 	host->addr	= reg;
-	host->timeout	= 1000;
+	host->timeout	= msecs_to_jiffies(1000);
 
-	snprintf(clk_name, sizeof(clk_name), "mmc%d", pdev->id);
-	host->hclk = clk_get(&pdev->dev, clk_name);
-	if (IS_ERR(host->hclk)) {
-		dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name);
-		ret = PTR_ERR(host->hclk);
-		goto clean_up1;
-	}
-	clk_enable(host->hclk);
-	host->clk = clk_get_rate(host->hclk);
 	host->pd = pdev;
 
 	spin_lock_init(&host->lock);
 
 	mmc->ops = &sh_mmcif_ops;
-	mmc->f_max = host->clk / 2;
-	mmc->f_min = host->clk / 512;
-	if (pd->ocr)
-		mmc->ocr_avail = pd->ocr;
-	mmc->caps = MMC_CAP_MMC_HIGHSPEED;
-	if (pd->caps)
+	sh_mmcif_init_ocr(host);
+
+	mmc->caps |= MMC_CAP_MMC_HIGHSPEED | MMC_CAP_WAIT_WHILE_BUSY;
+	if (pd && pd->caps)
 		mmc->caps |= pd->caps;
 	mmc->max_segs = 32;
 	mmc->max_blk_size = 512;
@@ -1311,34 +1391,57 @@
 	mmc->max_blk_count = mmc->max_req_size / mmc->max_blk_size;
 	mmc->max_seg_size = mmc->max_req_size;
 
-	sh_mmcif_sync_reset(host);
 	platform_set_drvdata(pdev, host);
 
 	pm_runtime_enable(&pdev->dev);
 	host->power = false;
 
+	host->hclk = clk_get(&pdev->dev, NULL);
+	if (IS_ERR(host->hclk)) {
+		ret = PTR_ERR(host->hclk);
+		dev_err(&pdev->dev, "cannot get clock: %d\n", ret);
+		goto eclkget;
+	}
+	ret = sh_mmcif_clk_update(host);
+	if (ret < 0)
+		goto eclkupdate;
+
 	ret = pm_runtime_resume(&pdev->dev);
 	if (ret < 0)
-		goto clean_up2;
+		goto eresume;
 
 	INIT_DELAYED_WORK(&host->timeout_work, mmcif_timeout_work);
 
+	sh_mmcif_sync_reset(host);
 	sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, MASK_ALL);
 
-	ret = request_threaded_irq(irq[0], sh_mmcif_intr, sh_mmcif_irqt, 0, "sh_mmc:error", host);
+	name = irq[1] < 0 ? dev_name(&pdev->dev) : "sh_mmc:error";
+	ret = request_threaded_irq(irq[0], sh_mmcif_intr, sh_mmcif_irqt, 0, name, host);
 	if (ret) {
-		dev_err(&pdev->dev, "request_irq error (sh_mmc:error)\n");
-		goto clean_up3;
+		dev_err(&pdev->dev, "request_irq error (%s)\n", name);
+		goto ereqirq0;
 	}
-	ret = request_threaded_irq(irq[1], sh_mmcif_intr, sh_mmcif_irqt, 0, "sh_mmc:int", host);
-	if (ret) {
-		dev_err(&pdev->dev, "request_irq error (sh_mmc:int)\n");
-		goto clean_up4;
+	if (irq[1] >= 0) {
+		ret = request_threaded_irq(irq[1], sh_mmcif_intr, sh_mmcif_irqt,
+					   0, "sh_mmc:int", host);
+		if (ret) {
+			dev_err(&pdev->dev, "request_irq error (sh_mmc:int)\n");
+			goto ereqirq1;
+		}
+	}
+
+	if (pd && pd->use_cd_gpio) {
+		ret = mmc_gpio_request_cd(mmc, pd->cd_gpio);
+		if (ret < 0)
+			goto erqcd;
 	}
 
+	mutex_init(&host->thread_lock);
+
+	clk_disable(host->hclk);
 	ret = mmc_add_host(mmc);
 	if (ret < 0)
-		goto clean_up5;
+		goto emmcaddh;
 
 	dev_pm_qos_expose_latency_limit(&pdev->dev, 100);
 
@@ -1347,29 +1450,33 @@
 		sh_mmcif_readl(host->addr, MMCIF_CE_VERSION) & 0x0000ffff);
 	return ret;
 
-clean_up5:
-	free_irq(irq[1], host);
-clean_up4:
+emmcaddh:
+erqcd:
+	if (irq[1] >= 0)
+		free_irq(irq[1], host);
+ereqirq1:
 	free_irq(irq[0], host);
-clean_up3:
+ereqirq0:
 	pm_runtime_suspend(&pdev->dev);
-clean_up2:
-	pm_runtime_disable(&pdev->dev);
+eresume:
 	clk_disable(host->hclk);
-clean_up1:
+eclkupdate:
+	clk_put(host->hclk);
+eclkget:
+	pm_runtime_disable(&pdev->dev);
 	mmc_free_host(mmc);
-clean_up:
-	if (reg)
-		iounmap(reg);
+ealloch:
+	iounmap(reg);
 	return ret;
 }
 
-static int __devexit sh_mmcif_remove(struct platform_device *pdev)
+static int sh_mmcif_remove(struct platform_device *pdev)
 {
 	struct sh_mmcif_host *host = platform_get_drvdata(pdev);
 	int irq[2];
 
 	host->dying = true;
+	clk_enable(host->hclk);
 	pm_runtime_get_sync(&pdev->dev);
 
 	dev_pm_qos_hide_latency_limit(&pdev->dev);
@@ -1391,7 +1498,8 @@
 	irq[1] = platform_get_irq(pdev, 1);
 
 	free_irq(irq[0], host);
-	free_irq(irq[1], host);
+	if (irq[1] >= 0)
+		free_irq(irq[1], host);
 
 	platform_set_drvdata(pdev, NULL);
 
@@ -1406,24 +1514,18 @@
 #ifdef CONFIG_PM
 static int sh_mmcif_suspend(struct device *dev)
 {
-	struct platform_device *pdev = to_platform_device(dev);
-	struct sh_mmcif_host *host = platform_get_drvdata(pdev);
+	struct sh_mmcif_host *host = dev_get_drvdata(dev);
 	int ret = mmc_suspend_host(host->mmc);
 
-	if (!ret) {
+	if (!ret)
 		sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, MASK_ALL);
-		clk_disable(host->hclk);
-	}
 
 	return ret;
 }
 
 static int sh_mmcif_resume(struct device *dev)
 {
-	struct platform_device *pdev = to_platform_device(dev);
-	struct sh_mmcif_host *host = platform_get_drvdata(pdev);
-
-	clk_enable(host->hclk);
+	struct sh_mmcif_host *host = dev_get_drvdata(dev);
 
 	return mmc_resume_host(host->mmc);
 }
@@ -1432,6 +1534,12 @@
 #define sh_mmcif_resume		NULL
 #endif	/* CONFIG_PM */
 
+static const struct of_device_id mmcif_of_match[] = {
+	{ .compatible = "renesas,sh-mmcif" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, mmcif_of_match);
+
 static const struct dev_pm_ops sh_mmcif_dev_pm_ops = {
 	.suspend = sh_mmcif_suspend,
 	.resume = sh_mmcif_resume,
@@ -1443,6 +1551,8 @@
 	.driver		= {
 		.name	= DRIVER_NAME,
 		.pm	= &sh_mmcif_dev_pm_ops,
+		.owner	= THIS_MODULE,
+		.of_match_table = mmcif_of_match,
 	},
 };
 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/sh_mobile_sdhi.c linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/sh_mobile_sdhi.c
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/sh_mobile_sdhi.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/sh_mobile_sdhi.c	2014-09-12 15:59:37.348052000 +0800
@@ -21,7 +21,9 @@
 #include <linux/kernel.h>
 #include <linux/clk.h>
 #include <linux/slab.h>
+#include <linux/mod_devicetable.h>
 #include <linux/module.h>
+#include <linux/of_device.h>
 #include <linux/platform_device.h>
 #include <linux/mmc/host.h>
 #include <linux/mmc/sh_mobile_sdhi.h>
@@ -31,6 +33,16 @@
 
 #include "tmio_mmc.h"
 
+struct sh_mobile_sdhi_of_data {
+	unsigned long tmio_flags;
+};
+
+static const struct sh_mobile_sdhi_of_data sh_mobile_sdhi_of_cfg[] = {
+	{
+		.tmio_flags = TMIO_MMC_HAS_IDLE_WAIT,
+	},
+};
+
 struct sh_mobile_sdhi {
 	struct clk *clk;
 	struct tmio_mmc_data mmc_data;
@@ -39,22 +51,39 @@
 	struct tmio_mmc_dma dma_priv;
 };
 
+static int sh_mobile_sdhi_clk_enable(struct platform_device *pdev, unsigned int *f)
+{
+	struct mmc_host *mmc = dev_get_drvdata(&pdev->dev);
+	struct tmio_mmc_host *host = mmc_priv(mmc);
+	struct sh_mobile_sdhi *priv = container_of(host->pdata, struct sh_mobile_sdhi, mmc_data);
+	int ret = clk_enable(priv->clk);
+	if (ret < 0)
+		return ret;
+
+	*f = clk_get_rate(priv->clk);
+	return 0;
+}
+
+static void sh_mobile_sdhi_clk_disable(struct platform_device *pdev)
+{
+	struct mmc_host *mmc = dev_get_drvdata(&pdev->dev);
+	struct tmio_mmc_host *host = mmc_priv(mmc);
+	struct sh_mobile_sdhi *priv = container_of(host->pdata, struct sh_mobile_sdhi, mmc_data);
+	clk_disable(priv->clk);
+}
+
 static void sh_mobile_sdhi_set_pwr(struct platform_device *pdev, int state)
 {
 	struct sh_mobile_sdhi_info *p = pdev->dev.platform_data;
 
-	if (p && p->set_pwr)
-		p->set_pwr(pdev, state);
+	p->set_pwr(pdev, state);
 }
 
 static int sh_mobile_sdhi_get_cd(struct platform_device *pdev)
 {
 	struct sh_mobile_sdhi_info *p = pdev->dev.platform_data;
 
-	if (p && p->get_cd)
-		return p->get_cd(pdev);
-	else
-		return -ENOSYS;
+	return p->get_cd(pdev);
 }
 
 static int sh_mobile_sdhi_wait_idle(struct tmio_mmc_host *host)
@@ -99,56 +128,68 @@
 	.cd_wakeup = sh_mobile_sdhi_cd_wakeup,
 };
 
-static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev)
+static const struct of_device_id sh_mobile_sdhi_of_match[] = {
+	{ .compatible = "renesas,shmobile-sdhi" },
+	{ .compatible = "renesas,sh7372-sdhi" },
+	{ .compatible = "renesas,r8a7740-sdhi", .data = &sh_mobile_sdhi_of_cfg[0], },
+	{},
+};
+MODULE_DEVICE_TABLE(of, sh_mobile_sdhi_of_match);
+
+static int sh_mobile_sdhi_probe(struct platform_device *pdev)
 {
+	const struct of_device_id *of_id =
+		of_match_device(sh_mobile_sdhi_of_match, &pdev->dev);
 	struct sh_mobile_sdhi *priv;
 	struct tmio_mmc_data *mmc_data;
 	struct sh_mobile_sdhi_info *p = pdev->dev.platform_data;
 	struct tmio_mmc_host *host;
-	char clk_name[8];
 	int irq, ret, i = 0;
 	bool multiplexed_isr = true;
 
-	priv = kzalloc(sizeof(struct sh_mobile_sdhi), GFP_KERNEL);
+	priv = devm_kzalloc(&pdev->dev, sizeof(struct sh_mobile_sdhi), GFP_KERNEL);
 	if (priv == NULL) {
 		dev_err(&pdev->dev, "kzalloc failed\n");
 		return -ENOMEM;
 	}
 
 	mmc_data = &priv->mmc_data;
-	p->pdata = mmc_data;
 
-	if (p->init) {
-		ret = p->init(pdev, &sdhi_ops);
-		if (ret)
-			goto einit;
+	if (p) {
+		if (p->init) {
+			ret = p->init(pdev, &sdhi_ops);
+			if (ret)
+				return ret;
+		}
 	}
 
-	snprintf(clk_name, sizeof(clk_name), "sdhi%d", pdev->id);
-	priv->clk = clk_get(&pdev->dev, clk_name);
+	priv->clk = devm_clk_get(&pdev->dev, NULL);
 	if (IS_ERR(priv->clk)) {
-		dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name);
 		ret = PTR_ERR(priv->clk);
+		dev_err(&pdev->dev, "cannot get clock: %d\n", ret);
 		goto eclkget;
 	}
 
-	mmc_data->hclk = clk_get_rate(priv->clk);
-	mmc_data->set_pwr = sh_mobile_sdhi_set_pwr;
-	mmc_data->get_cd = sh_mobile_sdhi_get_cd;
+	mmc_data->clk_enable = sh_mobile_sdhi_clk_enable;
+	mmc_data->clk_disable = sh_mobile_sdhi_clk_disable;
 	mmc_data->capabilities = MMC_CAP_MMC_HIGHSPEED;
+	mmc_data->write16_hook = sh_mobile_sdhi_write16_hook;
 	if (p) {
 		mmc_data->flags = p->tmio_flags;
-		if (mmc_data->flags & TMIO_MMC_HAS_IDLE_WAIT)
-			mmc_data->write16_hook = sh_mobile_sdhi_write16_hook;
 		mmc_data->ocr_mask = p->tmio_ocr_mask;
 		mmc_data->capabilities |= p->tmio_caps;
+		mmc_data->capabilities2 |= p->tmio_caps2;
 		mmc_data->cd_gpio = p->cd_gpio;
+		if (p->set_pwr)
+			mmc_data->set_pwr = sh_mobile_sdhi_set_pwr;
+		if (p->get_cd)
+			mmc_data->get_cd = sh_mobile_sdhi_get_cd;
 
 		if (p->dma_slave_tx > 0 && p->dma_slave_rx > 0) {
-			priv->param_tx.slave_id = p->dma_slave_tx;
-			priv->param_rx.slave_id = p->dma_slave_rx;
-			priv->dma_priv.chan_priv_tx = &priv->param_tx;
-			priv->dma_priv.chan_priv_rx = &priv->param_rx;
+			priv->param_tx.shdma_slave.slave_id = p->dma_slave_tx;
+			priv->param_rx.shdma_slave.slave_id = p->dma_slave_rx;
+			priv->dma_priv.chan_priv_tx = &priv->param_tx.shdma_slave;
+			priv->dma_priv.chan_priv_rx = &priv->param_rx.shdma_slave;
 			priv->dma_priv.alignment_shift = 1; /* 2-byte alignment */
 			mmc_data->dma = &priv->dma_priv;
 		}
@@ -165,6 +206,11 @@
 	 */
 	mmc_data->flags |= TMIO_MMC_SDIO_IRQ;
 
+	if (of_id && of_id->data) {
+		const struct sh_mobile_sdhi_of_data *of_data = of_id->data;
+		mmc_data->flags |= of_data->tmio_flags;
+	}
+
 	ret = tmio_mmc_host_probe(&host, pdev, mmc_data);
 	if (ret < 0)
 		goto eprobe;
@@ -177,33 +223,33 @@
 	irq = platform_get_irq_byname(pdev, SH_MOBILE_SDHI_IRQ_CARD_DETECT);
 	if (irq >= 0) {
 		multiplexed_isr = false;
-		ret = request_irq(irq, tmio_mmc_card_detect_irq, 0,
+		ret = devm_request_irq(&pdev->dev, irq, tmio_mmc_card_detect_irq, 0,
 				  dev_name(&pdev->dev), host);
 		if (ret)
-			goto eirq_card_detect;
+			goto eirq;
 	}
 
 	irq = platform_get_irq_byname(pdev, SH_MOBILE_SDHI_IRQ_SDIO);
 	if (irq >= 0) {
 		multiplexed_isr = false;
-		ret = request_irq(irq, tmio_mmc_sdio_irq, 0,
+		ret = devm_request_irq(&pdev->dev, irq, tmio_mmc_sdio_irq, 0,
 				  dev_name(&pdev->dev), host);
 		if (ret)
-			goto eirq_sdio;
+			goto eirq;
 	}
 
 	irq = platform_get_irq_byname(pdev, SH_MOBILE_SDHI_IRQ_SDCARD);
 	if (irq >= 0) {
 		multiplexed_isr = false;
-		ret = request_irq(irq, tmio_mmc_sdcard_irq, 0,
+		ret = devm_request_irq(&pdev->dev, irq, tmio_mmc_sdcard_irq, 0,
 				  dev_name(&pdev->dev), host);
 		if (ret)
-			goto eirq_sdcard;
+			goto eirq;
 	} else if (!multiplexed_isr) {
 		dev_err(&pdev->dev,
 			"Principal SD-card IRQ is missing among named interrupts\n");
 		ret = irq;
-		goto eirq_sdcard;
+		goto eirq;
 	}
 
 	if (multiplexed_isr) {
@@ -212,46 +258,30 @@
 			if (irq < 0)
 				break;
 			i++;
-			ret = request_irq(irq, tmio_mmc_irq, 0,
+			ret = devm_request_irq(&pdev->dev, irq, tmio_mmc_irq, 0,
 					  dev_name(&pdev->dev), host);
 			if (ret)
-				goto eirq_multiplexed;
+				goto eirq;
 		}
 
 		/* There must be at least one IRQ source */
 		if (!i)
-			goto eirq_multiplexed;
+			goto eirq;
 	}
 
 	dev_info(&pdev->dev, "%s base at 0x%08lx clock rate %u MHz\n",
 		 mmc_hostname(host->mmc), (unsigned long)
 		 (platform_get_resource(pdev, IORESOURCE_MEM, 0)->start),
-		 mmc_data->hclk / 1000000);
+		 host->mmc->f_max / 1000000);
 
 	return ret;
 
-eirq_multiplexed:
-	while (i--) {
-		irq = platform_get_irq(pdev, i);
-		free_irq(irq, host);
-	}
-eirq_sdcard:
-	irq = platform_get_irq_byname(pdev, SH_MOBILE_SDHI_IRQ_SDIO);
-	if (irq >= 0)
-		free_irq(irq, host);
-eirq_sdio:
-	irq = platform_get_irq_byname(pdev, SH_MOBILE_SDHI_IRQ_CARD_DETECT);
-	if (irq >= 0)
-		free_irq(irq, host);
-eirq_card_detect:
+eirq:
 	tmio_mmc_host_remove(host);
 eprobe:
-	clk_put(priv->clk);
 eclkget:
-	if (p->cleanup)
+	if (p && p->cleanup)
 		p->cleanup(pdev);
-einit:
-	kfree(priv);
 	return ret;
 }
 
@@ -259,28 +289,13 @@
 {
 	struct mmc_host *mmc = platform_get_drvdata(pdev);
 	struct tmio_mmc_host *host = mmc_priv(mmc);
-	struct sh_mobile_sdhi *priv = container_of(host->pdata, struct sh_mobile_sdhi, mmc_data);
 	struct sh_mobile_sdhi_info *p = pdev->dev.platform_data;
-	int i = 0, irq;
-
-	p->pdata = NULL;
 
 	tmio_mmc_host_remove(host);
 
-	while (1) {
-		irq = platform_get_irq(pdev, i++);
-		if (irq < 0)
-			break;
-		free_irq(irq, host);
-	}
-
-	clk_put(priv->clk);
-
-	if (p->cleanup)
+	if (p && p->cleanup)
 		p->cleanup(pdev);
 
-	kfree(priv);
-
 	return 0;
 }
 
@@ -296,9 +311,10 @@
 		.name	= "sh_mobile_sdhi",
 		.owner	= THIS_MODULE,
 		.pm	= &tmio_mmc_dev_pm_ops,
+		.of_match_table = sh_mobile_sdhi_of_match,
 	},
 	.probe		= sh_mobile_sdhi_probe,
-	.remove		= __devexit_p(sh_mobile_sdhi_remove),
+	.remove		= sh_mobile_sdhi_remove,
 };
 
 module_platform_driver(sh_mobile_sdhi_driver);
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/tmio_mmc.c linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/tmio_mmc.c
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/tmio_mmc.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/tmio_mmc.c	2014-09-12 15:59:37.348052000 +0800
@@ -57,7 +57,7 @@
 #define tmio_mmc_resume NULL
 #endif
 
-static int __devinit tmio_mmc_probe(struct platform_device *pdev)
+static int tmio_mmc_probe(struct platform_device *pdev)
 {
 	const struct mfd_cell *cell = mfd_get_cell(pdev);
 	struct tmio_mmc_data *pdata;
@@ -107,7 +107,7 @@
 	return ret;
 }
 
-static int __devexit tmio_mmc_remove(struct platform_device *pdev)
+static int tmio_mmc_remove(struct platform_device *pdev)
 {
 	const struct mfd_cell *cell = mfd_get_cell(pdev);
 	struct mmc_host *mmc = platform_get_drvdata(pdev);
@@ -133,7 +133,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe = tmio_mmc_probe,
-	.remove = __devexit_p(tmio_mmc_remove),
+	.remove = tmio_mmc_remove,
 	.suspend = tmio_mmc_suspend,
 	.resume = tmio_mmc_resume,
 };
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/tmio_mmc_dma.c linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/tmio_mmc_dma.c
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/tmio_mmc_dma.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/tmio_mmc_dma.c	2014-09-12 15:59:37.348052000 +0800
@@ -104,6 +104,7 @@
 pio:
 	if (!desc) {
 		/* DMA failed, fall back to PIO */
+		tmio_mmc_enable_dma(host, false);
 		if (ret >= 0)
 			ret = -EIO;
 		host->chan_rx = NULL;
@@ -116,7 +117,6 @@
 		}
 		dev_warn(&host->pdev->dev,
 			 "DMA failed: %d, falling back to PIO\n", ret);
-		tmio_mmc_enable_dma(host, false);
 	}
 
 	dev_dbg(&host->pdev->dev, "%s(): desc %p, cookie %d, sg[%d]\n", __func__,
@@ -185,6 +185,7 @@
 pio:
 	if (!desc) {
 		/* DMA failed, fall back to PIO */
+		tmio_mmc_enable_dma(host, false);
 		if (ret >= 0)
 			ret = -EIO;
 		host->chan_tx = NULL;
@@ -197,7 +198,6 @@
 		}
 		dev_warn(&host->pdev->dev,
 			 "DMA failed: %d, falling back to PIO\n", ret);
-		tmio_mmc_enable_dma(host, false);
 	}
 
 	dev_dbg(&host->pdev->dev, "%s(): desc %p, cookie %d\n", __func__,
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/tmio_mmc_pio.c linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/tmio_mmc_pio.c
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/tmio_mmc_pio.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/tmio_mmc_pio.c	2014-09-12 15:59:37.348052000 +0800
@@ -34,14 +34,16 @@
 #include <linux/io.h>
 #include <linux/irq.h>
 #include <linux/mfd/tmio.h>
-#include <linux/mmc/cd-gpio.h>
 #include <linux/mmc/host.h>
+#include <linux/mmc/mmc.h>
+#include <linux/mmc/slot-gpio.h>
 #include <linux/mmc/tmio.h>
 #include <linux/module.h>
 #include <linux/pagemap.h>
 #include <linux/platform_device.h>
 #include <linux/pm_qos.h>
 #include <linux/pm_runtime.h>
+#include <linux/regulator/consumer.h>
 #include <linux/scatterlist.h>
 #include <linux/spinlock.h>
 #include <linux/workqueue.h>
@@ -154,6 +156,7 @@
 		host->set_clk_div(host->pdev, (clk>>22) & 1);
 
 	sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, clk & 0x1ff);
+	msleep(10);
 }
 
 static void tmio_mmc_clk_stop(struct tmio_mmc_host *host)
@@ -305,8 +308,8 @@
 	int c = cmd->opcode;
 	u32 irq_mask = TMIO_MASK_CMD;
 
-	/* Command 12 is handled by hardware */
-	if (cmd->opcode == 12 && !cmd->arg) {
+	/* CMD12 is handled by hardware */
+	if (cmd->opcode == MMC_STOP_TRANSMISSION && !cmd->arg) {
 		sd_ctrl_write16(host, CTL_STOP_INTERNAL_ACTION, 0x001);
 		return 0;
 	}
@@ -449,7 +452,7 @@
 	}
 
 	if (stop) {
-		if (stop->opcode == 12 && !stop->arg)
+		if (stop->opcode == MMC_STOP_TRANSMISSION && !stop->arg)
 			sd_ctrl_write16(host, CTL_STOP_INTERNAL_ACTION, 0x000);
 		else
 			BUG();
@@ -751,6 +754,66 @@
 	mmc_request_done(mmc, mrq);
 }
 
+static int tmio_mmc_clk_update(struct mmc_host *mmc)
+{
+	struct tmio_mmc_host *host = mmc_priv(mmc);
+	struct tmio_mmc_data *pdata = host->pdata;
+	int ret;
+
+	if (!pdata->clk_enable)
+		return -ENOTSUPP;
+
+	ret = pdata->clk_enable(host->pdev, &mmc->f_max);
+	if (!ret)
+		mmc->f_min = mmc->f_max / 512;
+
+	return ret;
+}
+
+static void tmio_mmc_power_on(struct tmio_mmc_host *host, unsigned short vdd)
+{
+	struct mmc_host *mmc = host->mmc;
+	int ret = 0;
+
+	/* .set_ios() is returning void, so, no chance to report an error */
+
+	if (host->set_pwr)
+		host->set_pwr(host->pdev, 1);
+
+	if (!IS_ERR(mmc->supply.vmmc)) {
+		ret = mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, vdd);
+		/*
+		 * Attention: empiric value. With a b43 WiFi SDIO card this
+		 * delay proved necessary for reliable card-insertion probing.
+		 * 100us were not enough. Is this the same 140us delay, as in
+		 * tmio_mmc_set_ios()?
+		 */
+		udelay(200);
+	}
+	/*
+	 * It seems, VccQ should be switched on after Vcc, this is also what the
+	 * omap_hsmmc.c driver does.
+	 */
+	if (!IS_ERR(mmc->supply.vqmmc) && !ret) {
+		regulator_enable(mmc->supply.vqmmc);
+		udelay(200);
+	}
+}
+
+static void tmio_mmc_power_off(struct tmio_mmc_host *host)
+{
+	struct mmc_host *mmc = host->mmc;
+
+	if (!IS_ERR(mmc->supply.vqmmc))
+		regulator_disable(mmc->supply.vqmmc);
+
+	if (!IS_ERR(mmc->supply.vmmc))
+		mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, 0);
+
+	if (host->set_pwr)
+		host->set_pwr(host->pdev, 0);
+}
+
 /* Set MMC clock / power.
  * Note: This controller uses a simple divider scheme therefore it cannot
  * run a MMC card at full speed (20MHz). The max clock is 24MHz on SD, but as
@@ -797,32 +860,39 @@
 	 */
 	if (ios->power_mode == MMC_POWER_ON && ios->clock) {
 		if (!host->power) {
+			tmio_mmc_clk_update(mmc);
 			pm_runtime_get_sync(dev);
-			host->power = true;
 		}
 		tmio_mmc_set_clock(host, ios->clock);
-		/* power up SD bus */
-		if (host->set_pwr)
-			host->set_pwr(host->pdev, 1);
+		if (!host->power) {
+			/* power up SD card and the bus */
+			tmio_mmc_power_on(host, ios->vdd);
+			host->power = true;
+		}
 		/* start bus clock */
 		tmio_mmc_clk_start(host);
 	} else if (ios->power_mode != MMC_POWER_UP) {
-		if (host->set_pwr && ios->power_mode == MMC_POWER_OFF)
-			host->set_pwr(host->pdev, 0);
 		if (host->power) {
+			struct tmio_mmc_data *pdata = host->pdata;
+			if (ios->power_mode == MMC_POWER_OFF)
+				tmio_mmc_power_off(host);
+			tmio_mmc_clk_stop(host);
 			host->power = false;
 			pm_runtime_put(dev);
+			if (pdata->clk_disable)
+				pdata->clk_disable(host->pdev);
 		}
-		tmio_mmc_clk_stop(host);
 	}
 
-	switch (ios->bus_width) {
-	case MMC_BUS_WIDTH_1:
-		sd_ctrl_write16(host, CTL_SD_MEM_CARD_OPT, 0x80e0);
-	break;
-	case MMC_BUS_WIDTH_4:
-		sd_ctrl_write16(host, CTL_SD_MEM_CARD_OPT, 0x00e0);
-	break;
+	if (host->power) {
+		switch (ios->bus_width) {
+		case MMC_BUS_WIDTH_1:
+			sd_ctrl_write16(host, CTL_SD_MEM_CARD_OPT, 0x80e0);
+		break;
+		case MMC_BUS_WIDTH_4:
+			sd_ctrl_write16(host, CTL_SD_MEM_CARD_OPT, 0x00e0);
+		break;
+		}
 	}
 
 	/* Let things settle. delay taken from winCE driver */
@@ -841,6 +911,9 @@
 {
 	struct tmio_mmc_host *host = mmc_priv(mmc);
 	struct tmio_mmc_data *pdata = host->pdata;
+	int ret = mmc_gpio_get_ro(mmc);
+	if (ret >= 0)
+		return ret;
 
 	return !((pdata->flags & TMIO_MMC_WRPROTECT_DISABLE) ||
 		 (sd_ctrl_read32(host, CTL_STATUS) & TMIO_STAT_WRPROTECT));
@@ -850,6 +923,9 @@
 {
 	struct tmio_mmc_host *host = mmc_priv(mmc);
 	struct tmio_mmc_data *pdata = host->pdata;
+	int ret = mmc_gpio_get_cd(mmc);
+	if (ret >= 0)
+		return ret;
 
 	if (!pdata->get_cd)
 		return -ENOSYS;
@@ -865,7 +941,31 @@
 	.enable_sdio_irq = tmio_mmc_enable_sdio_irq,
 };
 
-int __devinit tmio_mmc_host_probe(struct tmio_mmc_host **host,
+static void tmio_mmc_init_ocr(struct tmio_mmc_host *host)
+{
+	struct tmio_mmc_data *pdata = host->pdata;
+	struct mmc_host *mmc = host->mmc;
+
+	mmc_regulator_get_supply(mmc);
+
+	if (!mmc->ocr_avail)
+		mmc->ocr_avail = pdata->ocr_mask ? : MMC_VDD_32_33 | MMC_VDD_33_34;
+	else if (pdata->ocr_mask)
+		dev_warn(mmc_dev(mmc), "Platform OCR mask is ignored\n");
+}
+
+static void tmio_mmc_of_parse(struct platform_device *pdev,
+			      struct tmio_mmc_data *pdata)
+{
+	const struct device_node *np = pdev->dev.of_node;
+	if (!np)
+		return;
+
+	if (of_get_property(np, "toshiba,mmc-wrprotect-disable", NULL))
+		pdata->flags |= TMIO_MMC_WRPROTECT_DISABLE;
+}
+
+int tmio_mmc_host_probe(struct tmio_mmc_host **host,
 				  struct platform_device *pdev,
 				  struct tmio_mmc_data *pdata)
 {
@@ -875,6 +975,11 @@
 	int ret;
 	u32 irq_mask = TMIO_MASK_CMD;
 
+	tmio_mmc_of_parse(pdev, pdata);
+
+	if (!(pdata->flags & TMIO_MMC_HAS_IDLE_WAIT))
+		pdata->write16_hook = NULL;
+
 	res_ctl = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!res_ctl)
 		return -EINVAL;
@@ -883,6 +988,8 @@
 	if (!mmc)
 		return -ENOMEM;
 
+	mmc_of_parse(mmc);
+
 	pdata->dev = &pdev->dev;
 	_host = mmc_priv(mmc);
 	_host->pdata = pdata;
@@ -903,23 +1010,20 @@
 	}
 
 	mmc->ops = &tmio_mmc_ops;
-	mmc->caps = MMC_CAP_4_BIT_DATA | pdata->capabilities;
-	mmc->f_max = pdata->hclk;
-	mmc->f_min = mmc->f_max / 512;
+	mmc->caps |= MMC_CAP_4_BIT_DATA | pdata->capabilities;
+	mmc->caps2 = pdata->capabilities2;
 	mmc->max_segs = 32;
 	mmc->max_blk_size = 512;
 	mmc->max_blk_count = (PAGE_CACHE_SIZE / mmc->max_blk_size) *
 		mmc->max_segs;
 	mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count;
 	mmc->max_seg_size = mmc->max_req_size;
-	if (pdata->ocr_mask)
-		mmc->ocr_avail = pdata->ocr_mask;
-	else
-		mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
+	tmio_mmc_init_ocr(_host);
 
 	_host->native_hotplug = !(pdata->flags & TMIO_MMC_USE_GPIO_CD ||
 				  mmc->caps & MMC_CAP_NEEDS_POLL ||
-				  mmc->caps & MMC_CAP_NONREMOVABLE);
+				  mmc->caps & MMC_CAP_NONREMOVABLE ||
+				  mmc->slot.cd_irq >= 0);
 
 	_host->power = false;
 	pm_runtime_enable(&pdev->dev);
@@ -927,6 +1031,11 @@
 	if (ret < 0)
 		goto pm_disable;
 
+	if (tmio_mmc_clk_update(mmc) < 0) {
+		mmc->f_max = pdata->hclk;
+		mmc->f_min = mmc->f_max / 512;
+	}
+
 	/*
 	 * There are 4 different scenarios for the card detection:
 	 *  1) an external gpio irq handles the cd (best for power savings)
@@ -937,7 +1046,6 @@
 	 *  While we increment the runtime PM counter for all scenarios when
 	 *  the mmc core activates us by calling an appropriate set_ios(), we
 	 *  must additionally ensure that in case 2) the tmio mmc hardware stays
-	 *  additionally ensure that in case 2) the tmio mmc hardware stays
 	 *  powered on during runtime for the card detection to work.
 	 */
 	if (_host->native_hotplug)
@@ -948,6 +1056,17 @@
 
 	_host->sdcard_irq_mask = sd_ctrl_read32(_host, CTL_IRQ_MASK);
 	tmio_mmc_disable_mmc_irqs(_host, TMIO_MASK_ALL);
+
+	/* Unmask the IRQs we want to know about */
+	if (!_host->chan_rx)
+		irq_mask |= TMIO_MASK_READOP;
+	if (!_host->chan_tx)
+		irq_mask |= TMIO_MASK_WRITEOP;
+	if (!_host->native_hotplug)
+		irq_mask &= ~(TMIO_STAT_CARD_REMOVE | TMIO_STAT_CARD_INSERT);
+
+	_host->sdcard_irq_mask &= ~irq_mask;
+
 	if (pdata->flags & TMIO_MMC_SDIO_IRQ)
 		tmio_mmc_enable_sdio_irq(mmc, 0);
 
@@ -961,22 +1080,18 @@
 	/* See if we also get DMA */
 	tmio_mmc_request_dma(_host, pdata);
 
-	mmc_add_host(mmc);
+	ret = mmc_add_host(mmc);
+	if (pdata->clk_disable)
+		pdata->clk_disable(pdev);
+	if (ret < 0) {
+		tmio_mmc_host_remove(_host);
+		return ret;
+	}
 
 	dev_pm_qos_expose_latency_limit(&pdev->dev, 100);
 
-	/* Unmask the IRQs we want to know about */
-	if (!_host->chan_rx)
-		irq_mask |= TMIO_MASK_READOP;
-	if (!_host->chan_tx)
-		irq_mask |= TMIO_MASK_WRITEOP;
-	if (!_host->native_hotplug)
-		irq_mask &= ~(TMIO_STAT_CARD_REMOVE | TMIO_STAT_CARD_INSERT);
-
-	tmio_mmc_enable_mmc_irqs(_host, irq_mask);
-
 	if (pdata->flags & TMIO_MMC_USE_GPIO_CD) {
-		ret = mmc_cd_gpio_request(mmc, pdata->cd_gpio);
+		ret = mmc_gpio_request_cd(mmc, pdata->cd_gpio);
 		if (ret < 0) {
 			tmio_mmc_host_remove(_host);
 			return ret;
@@ -1000,16 +1115,8 @@
 void tmio_mmc_host_remove(struct tmio_mmc_host *host)
 {
 	struct platform_device *pdev = host->pdev;
-	struct tmio_mmc_data *pdata = host->pdata;
 	struct mmc_host *mmc = host->mmc;
 
-	if (pdata->flags & TMIO_MMC_USE_GPIO_CD)
-		/*
-		 * This means we can miss a card-eject, but this is anyway
-		 * possible, because of delayed processing of hotplug events.
-		 */
-		mmc_cd_gpio_free(mmc);
-
 	if (!host->native_hotplug)
 		pm_runtime_get_sync(&pdev->dev);
 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/via-sdmmc.c linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/via-sdmmc.c
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/via-sdmmc.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/via-sdmmc.c	2014-09-12 15:59:37.348052000 +0800
@@ -1082,7 +1082,7 @@
 	msleep(1);
 }
 
-static int __devinit via_sd_probe(struct pci_dev *pcidev,
+static int via_sd_probe(struct pci_dev *pcidev,
 				    const struct pci_device_id *id)
 {
 	struct mmc_host *mmc;
@@ -1176,7 +1176,7 @@
 	return ret;
 }
 
-static void __devexit via_sd_remove(struct pci_dev *pcidev)
+static void via_sd_remove(struct pci_dev *pcidev)
 {
 	struct via_crdr_mmc_host *sdhost = pci_get_drvdata(pcidev);
 	unsigned long flags;
@@ -1332,26 +1332,12 @@
 	.name = DRV_NAME,
 	.id_table = via_ids,
 	.probe = via_sd_probe,
-	.remove = __devexit_p(via_sd_remove),
+	.remove = via_sd_remove,
 	.suspend = via_sd_suspend,
 	.resume = via_sd_resume,
 };
 
-static int __init via_sd_drv_init(void)
-{
-	pr_info(DRV_NAME ": VIA SD/MMC Card Reader driver "
-		"(C) 2008 VIA Technologies, Inc.\n");
-
-	return pci_register_driver(&via_sd_driver);
-}
-
-static void __exit via_sd_drv_exit(void)
-{
-	pci_unregister_driver(&via_sd_driver);
-}
-
-module_init(via_sd_drv_init);
-module_exit(via_sd_drv_exit);
+module_pci_driver(via_sd_driver);
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("VIA Technologies Inc.");
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/vub300.c linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/vub300.c
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/vub300.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/vub300.c	2014-09-12 15:59:37.348052000 +0800
@@ -806,7 +806,7 @@
 		 * we suspect a buggy USB host controller
 		 */
 	} else if (!vub300->data) {
-		/* this means that the command (typically CMD52) suceeded */
+		/* this means that the command (typically CMD52) succeeded */
 	} else if (vub300->resp.common.header_type != 0x02) {
 		/*
 		 * this is an error response from the VUB300 chip
@@ -2358,10 +2358,11 @@
 	 * which is contained at the end of struct mmc
 	 */
 error4:
-	usb_free_urb(command_out_urb);
-error1:
 	usb_free_urb(command_res_urb);
+error1:
+	usb_free_urb(command_out_urb);
 error0:
+	usb_put_dev(udev);
 	return retval;
 }
 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/wbsd.c linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/wbsd.c
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/wbsd.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/wbsd.c	2014-09-12 15:59:37.348052000 +0800
@@ -1196,7 +1196,7 @@
  * Allocate/free MMC structure.
  */
 
-static int __devinit wbsd_alloc_mmc(struct device *dev)
+static int wbsd_alloc_mmc(struct device *dev)
 {
 	struct mmc_host *mmc;
 	struct wbsd_host *host;
@@ -1288,7 +1288,7 @@
  * Scan for known chip id:s
  */
 
-static int __devinit wbsd_scan(struct wbsd_host *host)
+static int wbsd_scan(struct wbsd_host *host)
 {
 	int i, j, k;
 	int id;
@@ -1344,7 +1344,7 @@
  * Allocate/free io port ranges
  */
 
-static int __devinit wbsd_request_region(struct wbsd_host *host, int base)
+static int wbsd_request_region(struct wbsd_host *host, int base)
 {
 	if (base & 0x7)
 		return -EINVAL;
@@ -1374,7 +1374,7 @@
  * Allocate/free DMA port and buffer
  */
 
-static void __devinit wbsd_request_dma(struct wbsd_host *host, int dma)
+static void wbsd_request_dma(struct wbsd_host *host, int dma)
 {
 	if (dma < 0)
 		return;
@@ -1452,7 +1452,7 @@
  * Allocate/free IRQ.
  */
 
-static int __devinit wbsd_request_irq(struct wbsd_host *host, int irq)
+static int wbsd_request_irq(struct wbsd_host *host, int irq)
 {
 	int ret;
 
@@ -1502,7 +1502,7 @@
  * Allocate all resources for the host.
  */
 
-static int __devinit wbsd_request_resources(struct wbsd_host *host,
+static int wbsd_request_resources(struct wbsd_host *host,
 	int base, int irq, int dma)
 {
 	int ret;
@@ -1644,7 +1644,7 @@
  *                                                                           *
 \*****************************************************************************/
 
-static int __devinit wbsd_init(struct device *dev, int base, int irq, int dma,
+static int wbsd_init(struct device *dev, int base, int irq, int dma,
 	int pnp)
 {
 	struct wbsd_host *host = NULL;
@@ -1735,7 +1735,7 @@
 	return 0;
 }
 
-static void __devexit wbsd_shutdown(struct device *dev, int pnp)
+static void wbsd_shutdown(struct device *dev, int pnp)
 {
 	struct mmc_host *mmc = dev_get_drvdata(dev);
 	struct wbsd_host *host;
@@ -1762,13 +1762,13 @@
  * Non-PnP
  */
 
-static int __devinit wbsd_probe(struct platform_device *dev)
+static int wbsd_probe(struct platform_device *dev)
 {
 	/* Use the module parameters for resources */
 	return wbsd_init(&dev->dev, param_io, param_irq, param_dma, 0);
 }
 
-static int __devexit wbsd_remove(struct platform_device *dev)
+static int wbsd_remove(struct platform_device *dev)
 {
 	wbsd_shutdown(&dev->dev, 0);
 
@@ -1781,7 +1781,7 @@
 
 #ifdef CONFIG_PNP
 
-static int __devinit
+static int
 wbsd_pnp_probe(struct pnp_dev *pnpdev, const struct pnp_device_id *dev_id)
 {
 	int io, irq, dma;
@@ -1801,7 +1801,7 @@
 	return wbsd_init(&pnpdev->dev, io, irq, dma, 1);
 }
 
-static void __devexit wbsd_pnp_remove(struct pnp_dev *dev)
+static void wbsd_pnp_remove(struct pnp_dev *dev)
 {
 	wbsd_shutdown(&dev->dev, 1);
 }
@@ -1941,7 +1941,7 @@
 
 static struct platform_driver wbsd_driver = {
 	.probe		= wbsd_probe,
-	.remove		= __devexit_p(wbsd_remove),
+	.remove		= wbsd_remove,
 
 	.suspend	= wbsd_platform_suspend,
 	.resume		= wbsd_platform_resume,
@@ -1957,7 +1957,7 @@
 	.name		= DRIVER_NAME,
 	.id_table	= pnp_dev_table,
 	.probe		= wbsd_pnp_probe,
-	.remove		= __devexit_p(wbsd_pnp_remove),
+	.remove		= wbsd_pnp_remove,
 
 	.suspend	= wbsd_pnp_suspend,
 	.resume		= wbsd_pnp_resume,
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/wmt-sdmmc.c linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/wmt-sdmmc.c
--- linux-linaro-3.4-2012.05-1_original/drivers/mmc/host/wmt-sdmmc.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mmc/host/wmt-sdmmc.c	2014-09-12 15:59:37.348052000 +0800
@@ -0,0 +1,1027 @@
+/*
+ *  WM8505/WM8650 SD/MMC Host Controller
+ *
+ *  Copyright (C) 2010 Tony Prisk
+ *  Copyright (C) 2008 WonderMedia Technologies, Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/ioport.h>
+#include <linux/errno.h>
+#include <linux/dma-mapping.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/clk.h>
+#include <linux/gpio.h>
+
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of_device.h>
+
+#include <linux/mmc/host.h>
+#include <linux/mmc/mmc.h>
+#include <linux/mmc/sd.h>
+
+#include <asm/byteorder.h>
+
+
+#define DRIVER_NAME "wmt-sdhc"
+
+
+/* MMC/SD controller registers */
+#define SDMMC_CTLR			0x00
+#define SDMMC_CMD			0x01
+#define SDMMC_RSPTYPE			0x02
+#define SDMMC_ARG			0x04
+#define SDMMC_BUSMODE			0x08
+#define SDMMC_BLKLEN			0x0C
+#define SDMMC_BLKCNT			0x0E
+#define SDMMC_RSP			0x10
+#define SDMMC_CBCR			0x20
+#define SDMMC_INTMASK0			0x24
+#define SDMMC_INTMASK1			0x25
+#define SDMMC_STS0			0x28
+#define SDMMC_STS1			0x29
+#define SDMMC_STS2			0x2A
+#define SDMMC_STS3			0x2B
+#define SDMMC_RSPTIMEOUT		0x2C
+#define SDMMC_CLK			0x30	/* VT8500 only */
+#define SDMMC_EXTCTRL			0x34
+#define SDMMC_SBLKLEN			0x38
+#define SDMMC_DMATIMEOUT		0x3C
+
+
+/* SDMMC_CTLR bit fields */
+#define CTLR_CMD_START			0x01
+#define CTLR_CMD_WRITE			0x04
+#define CTLR_FIFO_RESET			0x08
+
+/* SDMMC_BUSMODE bit fields */
+#define BM_SPI_MODE			0x01
+#define BM_FOURBIT_MODE			0x02
+#define BM_EIGHTBIT_MODE		0x04
+#define BM_SD_OFF			0x10
+#define BM_SPI_CS			0x20
+#define BM_SD_POWER			0x40
+#define BM_SOFT_RESET			0x80
+#define BM_ONEBIT_MASK			0xFD
+
+/* SDMMC_BLKLEN bit fields */
+#define BLKL_CRCERR_ABORT		0x0800
+#define BLKL_CD_POL_HIGH		0x1000
+#define BLKL_GPI_CD			0x2000
+#define BLKL_DATA3_CD			0x4000
+#define BLKL_INT_ENABLE			0x8000
+
+/* SDMMC_INTMASK0 bit fields */
+#define INT0_MBLK_TRAN_DONE_INT_EN	0x10
+#define INT0_BLK_TRAN_DONE_INT_EN	0x20
+#define INT0_CD_INT_EN			0x40
+#define INT0_DI_INT_EN			0x80
+
+/* SDMMC_INTMASK1 bit fields */
+#define INT1_CMD_RES_TRAN_DONE_INT_EN	0x02
+#define INT1_CMD_RES_TOUT_INT_EN	0x04
+#define INT1_MBLK_AUTO_STOP_INT_EN	0x08
+#define INT1_DATA_TOUT_INT_EN		0x10
+#define INT1_RESCRC_ERR_INT_EN		0x20
+#define INT1_RCRC_ERR_INT_EN		0x40
+#define INT1_WCRC_ERR_INT_EN		0x80
+
+/* SDMMC_STS0 bit fields */
+#define STS0_WRITE_PROTECT		0x02
+#define STS0_CD_DATA3			0x04
+#define STS0_CD_GPI			0x08
+#define STS0_MBLK_DONE			0x10
+#define STS0_BLK_DONE			0x20
+#define STS0_CARD_DETECT		0x40
+#define STS0_DEVICE_INS			0x80
+
+/* SDMMC_STS1 bit fields */
+#define STS1_SDIO_INT			0x01
+#define STS1_CMDRSP_DONE		0x02
+#define STS1_RSP_TIMEOUT		0x04
+#define STS1_AUTOSTOP_DONE		0x08
+#define STS1_DATA_TIMEOUT		0x10
+#define STS1_RSP_CRC_ERR		0x20
+#define STS1_RCRC_ERR			0x40
+#define STS1_WCRC_ERR			0x80
+
+/* SDMMC_STS2 bit fields */
+#define STS2_CMD_RES_BUSY		0x10
+#define STS2_DATARSP_BUSY		0x20
+#define STS2_DIS_FORCECLK		0x80
+
+
+/* MMC/SD DMA Controller Registers */
+#define SDDMA_GCR			0x100
+#define SDDMA_IER			0x104
+#define SDDMA_ISR			0x108
+#define SDDMA_DESPR			0x10C
+#define SDDMA_RBR			0x110
+#define SDDMA_DAR			0x114
+#define SDDMA_BAR			0x118
+#define SDDMA_CPR			0x11C
+#define SDDMA_CCR			0x120
+
+
+/* SDDMA_GCR bit fields */
+#define DMA_GCR_DMA_EN			0x00000001
+#define DMA_GCR_SOFT_RESET		0x00000100
+
+/* SDDMA_IER bit fields */
+#define DMA_IER_INT_EN			0x00000001
+
+/* SDDMA_ISR bit fields */
+#define DMA_ISR_INT_STS			0x00000001
+
+/* SDDMA_RBR bit fields */
+#define DMA_RBR_FORMAT			0x40000000
+#define DMA_RBR_END			0x80000000
+
+/* SDDMA_CCR bit fields */
+#define DMA_CCR_RUN			0x00000080
+#define DMA_CCR_IF_TO_PERIPHERAL	0x00000000
+#define DMA_CCR_PERIPHERAL_TO_IF	0x00400000
+
+/* SDDMA_CCR event status */
+#define DMA_CCR_EVT_NO_STATUS		0x00000000
+#define DMA_CCR_EVT_UNDERRUN		0x00000001
+#define DMA_CCR_EVT_OVERRUN		0x00000002
+#define DMA_CCR_EVT_DESP_READ		0x00000003
+#define DMA_CCR_EVT_DATA_RW		0x00000004
+#define DMA_CCR_EVT_EARLY_END		0x00000005
+#define DMA_CCR_EVT_SUCCESS		0x0000000F
+
+#define PDMA_READ			0x00
+#define PDMA_WRITE			0x01
+
+#define WMT_SD_POWER_OFF		0
+#define WMT_SD_POWER_ON			1
+
+struct wmt_dma_descriptor {
+	u32 flags;
+	u32 data_buffer_addr;
+	u32 branch_addr;
+	u32 reserved1;
+};
+
+struct wmt_mci_caps {
+	unsigned int	f_min;
+	unsigned int	f_max;
+	u32		ocr_avail;
+	u32		caps;
+	u32		max_seg_size;
+	u32		max_segs;
+	u32		max_blk_size;
+};
+
+struct wmt_mci_priv {
+	struct mmc_host *mmc;
+	void __iomem *sdmmc_base;
+
+	int irq_regular;
+	int irq_dma;
+
+	void *dma_desc_buffer;
+	dma_addr_t dma_desc_device_addr;
+
+	struct completion cmdcomp;
+	struct completion datacomp;
+
+	struct completion *comp_cmd;
+	struct completion *comp_dma;
+
+	struct mmc_request *req;
+	struct mmc_command *cmd;
+
+	struct clk *clk_sdmmc;
+	struct device *dev;
+
+	u8 power_inverted;
+	u8 cd_inverted;
+};
+
+static void wmt_set_sd_power(struct wmt_mci_priv *priv, int enable)
+{
+	u32 reg_tmp;
+	if (enable) {
+		if (priv->power_inverted) {
+			reg_tmp = readb(priv->sdmmc_base + SDMMC_BUSMODE);
+			writeb(reg_tmp | BM_SD_OFF,
+			       priv->sdmmc_base + SDMMC_BUSMODE);
+		} else {
+			reg_tmp = readb(priv->sdmmc_base + SDMMC_BUSMODE);
+			writeb(reg_tmp & (~BM_SD_OFF),
+			       priv->sdmmc_base + SDMMC_BUSMODE);
+		}
+	} else {
+		if (priv->power_inverted) {
+			reg_tmp = readb(priv->sdmmc_base + SDMMC_BUSMODE);
+			writeb(reg_tmp & (~BM_SD_OFF),
+			       priv->sdmmc_base + SDMMC_BUSMODE);
+		} else {
+			reg_tmp = readb(priv->sdmmc_base + SDMMC_BUSMODE);
+			writeb(reg_tmp | BM_SD_OFF,
+			       priv->sdmmc_base + SDMMC_BUSMODE);
+		}
+	}
+}
+
+static void wmt_mci_read_response(struct mmc_host *mmc)
+{
+	struct wmt_mci_priv *priv;
+	int idx1, idx2;
+	u8 tmp_resp;
+	u32 response;
+
+	priv = mmc_priv(mmc);
+
+	for (idx1 = 0; idx1 < 4; idx1++) {
+		response = 0;
+		for (idx2 = 0; idx2 < 4; idx2++) {
+			if ((idx1 == 3) && (idx2 == 3))
+				tmp_resp = readb(priv->sdmmc_base + SDMMC_RSP);
+			else
+				tmp_resp = readb(priv->sdmmc_base + SDMMC_RSP +
+						 (idx1*4) + idx2 + 1);
+			response |= (tmp_resp << (idx2 * 8));
+		}
+		priv->cmd->resp[idx1] = cpu_to_be32(response);
+	}
+}
+
+static void wmt_mci_start_command(struct wmt_mci_priv *priv)
+{
+	u32 reg_tmp;
+
+	reg_tmp = readb(priv->sdmmc_base + SDMMC_CTLR);
+	writeb(reg_tmp | CTLR_CMD_START, priv->sdmmc_base + SDMMC_CTLR);
+}
+
+static int wmt_mci_send_command(struct mmc_host *mmc, u8 command, u8 cmdtype,
+				u32 arg, u8 rsptype)
+{
+	struct wmt_mci_priv *priv;
+	u32 reg_tmp;
+
+	priv = mmc_priv(mmc);
+
+	/* write command, arg, resptype registers */
+	writeb(command, priv->sdmmc_base + SDMMC_CMD);
+	writel(arg, priv->sdmmc_base + SDMMC_ARG);
+	writeb(rsptype, priv->sdmmc_base + SDMMC_RSPTYPE);
+
+	/* reset response FIFO */
+	reg_tmp = readb(priv->sdmmc_base + SDMMC_CTLR);
+	writeb(reg_tmp | CTLR_FIFO_RESET, priv->sdmmc_base + SDMMC_CTLR);
+
+	/* ensure clock enabled - VT3465 */
+	wmt_set_sd_power(priv, WMT_SD_POWER_ON);
+
+	/* clear status bits */
+	writeb(0xFF, priv->sdmmc_base + SDMMC_STS0);
+	writeb(0xFF, priv->sdmmc_base + SDMMC_STS1);
+	writeb(0xFF, priv->sdmmc_base + SDMMC_STS2);
+	writeb(0xFF, priv->sdmmc_base + SDMMC_STS3);
+
+	/* set command type */
+	reg_tmp = readb(priv->sdmmc_base + SDMMC_CTLR);
+	writeb((reg_tmp & 0x0F) | (cmdtype << 4),
+	       priv->sdmmc_base + SDMMC_CTLR);
+
+	return 0;
+}
+
+static void wmt_mci_disable_dma(struct wmt_mci_priv *priv)
+{
+	writel(DMA_ISR_INT_STS, priv->sdmmc_base + SDDMA_ISR);
+	writel(0, priv->sdmmc_base + SDDMA_IER);
+}
+
+static void wmt_complete_data_request(struct wmt_mci_priv *priv)
+{
+	struct mmc_request *req;
+	req = priv->req;
+
+	req->data->bytes_xfered = req->data->blksz * req->data->blocks;
+
+	/* unmap the DMA pages used for write data */
+	if (req->data->flags & MMC_DATA_WRITE)
+		dma_unmap_sg(mmc_dev(priv->mmc), req->data->sg,
+			     req->data->sg_len, DMA_TO_DEVICE);
+	else
+		dma_unmap_sg(mmc_dev(priv->mmc), req->data->sg,
+			     req->data->sg_len, DMA_FROM_DEVICE);
+
+	/* Check if the DMA ISR returned a data error */
+	if ((req->cmd->error) || (req->data->error))
+		mmc_request_done(priv->mmc, req);
+	else {
+		wmt_mci_read_response(priv->mmc);
+		if (!req->data->stop) {
+			/* single-block read/write requests end here */
+			mmc_request_done(priv->mmc, req);
+		} else {
+			/*
+			 * we change the priv->cmd variable so the response is
+			 * stored in the stop struct rather than the original
+			 * calling command struct
+			 */
+			priv->comp_cmd = &priv->cmdcomp;
+			init_completion(priv->comp_cmd);
+			priv->cmd = req->data->stop;
+			wmt_mci_send_command(priv->mmc, req->data->stop->opcode,
+					     7, req->data->stop->arg, 9);
+			wmt_mci_start_command(priv);
+		}
+	}
+}
+
+static irqreturn_t wmt_mci_dma_isr(int irq_num, void *data)
+{
+	struct wmt_mci_priv *priv;
+
+	int status;
+
+	priv = (struct wmt_mci_priv *)data;
+
+	status = readl(priv->sdmmc_base + SDDMA_CCR) & 0x0F;
+
+	if (status != DMA_CCR_EVT_SUCCESS) {
+		dev_err(priv->dev, "DMA Error: Status = %d\n", status);
+		priv->req->data->error = -ETIMEDOUT;
+		complete(priv->comp_dma);
+		return IRQ_HANDLED;
+	}
+
+	priv->req->data->error = 0;
+
+	wmt_mci_disable_dma(priv);
+
+	complete(priv->comp_dma);
+
+	if (priv->comp_cmd) {
+		if (completion_done(priv->comp_cmd)) {
+			/*
+			 * if the command (regular) interrupt has already
+			 * completed, finish off the request otherwise we wait
+			 * for the command interrupt and finish from there.
+			 */
+			wmt_complete_data_request(priv);
+		}
+	}
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t wmt_mci_regular_isr(int irq_num, void *data)
+{
+	struct wmt_mci_priv *priv;
+	u32 status0;
+	u32 status1;
+	u32 status2;
+	u32 reg_tmp;
+	int cmd_done;
+
+	priv = (struct wmt_mci_priv *)data;
+	cmd_done = 0;
+	status0 = readb(priv->sdmmc_base + SDMMC_STS0);
+	status1 = readb(priv->sdmmc_base + SDMMC_STS1);
+	status2 = readb(priv->sdmmc_base + SDMMC_STS2);
+
+	/* Check for card insertion */
+	reg_tmp = readb(priv->sdmmc_base + SDMMC_INTMASK0);
+	if ((reg_tmp & INT0_DI_INT_EN) && (status0 & STS0_DEVICE_INS)) {
+		mmc_detect_change(priv->mmc, 0);
+		if (priv->cmd)
+			priv->cmd->error = -ETIMEDOUT;
+		if (priv->comp_cmd)
+			complete(priv->comp_cmd);
+		if (priv->comp_dma) {
+			wmt_mci_disable_dma(priv);
+			complete(priv->comp_dma);
+		}
+		writeb(STS0_DEVICE_INS, priv->sdmmc_base + SDMMC_STS0);
+		return IRQ_HANDLED;
+	}
+
+	if ((!priv->req->data) ||
+	    ((priv->req->data->stop) && (priv->cmd == priv->req->data->stop))) {
+		/* handle non-data & stop_transmission requests */
+		if (status1 & STS1_CMDRSP_DONE) {
+			priv->cmd->error = 0;
+			cmd_done = 1;
+		} else if ((status1 & STS1_RSP_TIMEOUT) ||
+			   (status1 & STS1_DATA_TIMEOUT)) {
+			priv->cmd->error = -ETIMEDOUT;
+			cmd_done = 1;
+		}
+
+		if (cmd_done) {
+			priv->comp_cmd = NULL;
+
+			if (!priv->cmd->error)
+				wmt_mci_read_response(priv->mmc);
+
+			priv->cmd = NULL;
+
+			mmc_request_done(priv->mmc, priv->req);
+		}
+	} else {
+		/* handle data requests */
+		if (status1 & STS1_CMDRSP_DONE) {
+			if (priv->cmd)
+				priv->cmd->error = 0;
+			if (priv->comp_cmd)
+				complete(priv->comp_cmd);
+		}
+
+		if ((status1 & STS1_RSP_TIMEOUT) ||
+		    (status1 & STS1_DATA_TIMEOUT)) {
+			if (priv->cmd)
+				priv->cmd->error = -ETIMEDOUT;
+			if (priv->comp_cmd)
+				complete(priv->comp_cmd);
+			if (priv->comp_dma) {
+				wmt_mci_disable_dma(priv);
+				complete(priv->comp_dma);
+			}
+		}
+
+		if (priv->comp_dma) {
+			/*
+			 * If the dma interrupt has already completed, finish
+			 * off the request; otherwise we wait for the DMA
+			 * interrupt and finish from there.
+			 */
+			if (completion_done(priv->comp_dma))
+				wmt_complete_data_request(priv);
+		}
+	}
+
+	writeb(status0, priv->sdmmc_base + SDMMC_STS0);
+	writeb(status1, priv->sdmmc_base + SDMMC_STS1);
+	writeb(status2, priv->sdmmc_base + SDMMC_STS2);
+
+	return IRQ_HANDLED;
+}
+
+static void wmt_reset_hardware(struct mmc_host *mmc)
+{
+	struct wmt_mci_priv *priv;
+	u32 reg_tmp;
+
+	priv = mmc_priv(mmc);
+
+	/* reset controller */
+	reg_tmp = readb(priv->sdmmc_base + SDMMC_BUSMODE);
+	writeb(reg_tmp | BM_SOFT_RESET, priv->sdmmc_base + SDMMC_BUSMODE);
+
+	/* reset response FIFO */
+	reg_tmp = readb(priv->sdmmc_base + SDMMC_CTLR);
+	writeb(reg_tmp | CTLR_FIFO_RESET, priv->sdmmc_base + SDMMC_CTLR);
+
+	/* enable GPI pin to detect card */
+	writew(BLKL_INT_ENABLE | BLKL_GPI_CD, priv->sdmmc_base + SDMMC_BLKLEN);
+
+	/* clear interrupt status */
+	writeb(0xFF, priv->sdmmc_base + SDMMC_STS0);
+	writeb(0xFF, priv->sdmmc_base + SDMMC_STS1);
+
+	/* setup interrupts */
+	writeb(INT0_CD_INT_EN | INT0_DI_INT_EN, priv->sdmmc_base +
+	       SDMMC_INTMASK0);
+	writeb(INT1_DATA_TOUT_INT_EN | INT1_CMD_RES_TRAN_DONE_INT_EN |
+	       INT1_CMD_RES_TOUT_INT_EN, priv->sdmmc_base + SDMMC_INTMASK1);
+
+	/* set the DMA timeout */
+	writew(8191, priv->sdmmc_base + SDMMC_DMATIMEOUT);
+
+	/* auto clock freezing enable */
+	reg_tmp = readb(priv->sdmmc_base + SDMMC_STS2);
+	writeb(reg_tmp | STS2_DIS_FORCECLK, priv->sdmmc_base + SDMMC_STS2);
+
+	/* set a default clock speed of 400Khz */
+	clk_set_rate(priv->clk_sdmmc, 400000);
+}
+
+static int wmt_dma_init(struct mmc_host *mmc)
+{
+	struct wmt_mci_priv *priv;
+
+	priv = mmc_priv(mmc);
+
+	writel(DMA_GCR_SOFT_RESET, priv->sdmmc_base + SDDMA_GCR);
+	writel(DMA_GCR_DMA_EN, priv->sdmmc_base + SDDMA_GCR);
+	if ((readl(priv->sdmmc_base + SDDMA_GCR) & DMA_GCR_DMA_EN) != 0)
+		return 0;
+	else
+		return 1;
+}
+
+static void wmt_dma_init_descriptor(struct wmt_dma_descriptor *desc,
+		u16 req_count, u32 buffer_addr, u32 branch_addr, int end)
+{
+	desc->flags = 0x40000000 | req_count;
+	if (end)
+		desc->flags |= 0x80000000;
+	desc->data_buffer_addr = buffer_addr;
+	desc->branch_addr = branch_addr;
+}
+
+static void wmt_dma_config(struct mmc_host *mmc, u32 descaddr, u8 dir)
+{
+	struct wmt_mci_priv *priv;
+	u32 reg_tmp;
+
+	priv = mmc_priv(mmc);
+
+	/* Enable DMA Interrupts */
+	writel(DMA_IER_INT_EN, priv->sdmmc_base + SDDMA_IER);
+
+	/* Write DMA Descriptor Pointer Register */
+	writel(descaddr, priv->sdmmc_base + SDDMA_DESPR);
+
+	writel(0x00, priv->sdmmc_base + SDDMA_CCR);
+
+	if (dir == PDMA_WRITE) {
+		reg_tmp = readl(priv->sdmmc_base + SDDMA_CCR);
+		writel(reg_tmp & DMA_CCR_IF_TO_PERIPHERAL, priv->sdmmc_base +
+		       SDDMA_CCR);
+	} else {
+		reg_tmp = readl(priv->sdmmc_base + SDDMA_CCR);
+		writel(reg_tmp | DMA_CCR_PERIPHERAL_TO_IF, priv->sdmmc_base +
+		       SDDMA_CCR);
+	}
+}
+
+static void wmt_dma_start(struct wmt_mci_priv *priv)
+{
+	u32 reg_tmp;
+
+	reg_tmp = readl(priv->sdmmc_base + SDDMA_CCR);
+	writel(reg_tmp | DMA_CCR_RUN, priv->sdmmc_base + SDDMA_CCR);
+}
+
+static void wmt_mci_request(struct mmc_host *mmc, struct mmc_request *req)
+{
+	struct wmt_mci_priv *priv;
+	struct wmt_dma_descriptor *desc;
+	u8 command;
+	u8 cmdtype;
+	u32 arg;
+	u8 rsptype;
+	u32 reg_tmp;
+
+	struct scatterlist *sg;
+	int i;
+	int sg_cnt;
+	int offset;
+	u32 dma_address;
+	int desc_cnt;
+
+	priv = mmc_priv(mmc);
+	priv->req = req;
+
+	/*
+	 * Use the cmd variable to pass a pointer to the resp[] structure
+	 * This is required on multi-block requests to pass the pointer to the
+	 * stop command
+	 */
+	priv->cmd = req->cmd;
+
+	command = req->cmd->opcode;
+	arg = req->cmd->arg;
+	rsptype = mmc_resp_type(req->cmd);
+	cmdtype = 0;
+
+	/* rsptype=7 only valid for SPI commands - should be =2 for SD */
+	if (rsptype == 7)
+		rsptype = 2;
+	/* rsptype=21 is R1B, convert for controller */
+	if (rsptype == 21)
+		rsptype = 9;
+
+	if (!req->data) {
+		wmt_mci_send_command(mmc, command, cmdtype, arg, rsptype);
+		wmt_mci_start_command(priv);
+		/* completion is now handled in the regular_isr() */
+	}
+	if (req->data) {
+		priv->comp_cmd = &priv->cmdcomp;
+		init_completion(priv->comp_cmd);
+
+		wmt_dma_init(mmc);
+
+		/* set controller data length */
+		reg_tmp = readw(priv->sdmmc_base + SDMMC_BLKLEN);
+		writew((reg_tmp & 0xF800) | (req->data->blksz - 1),
+		       priv->sdmmc_base + SDMMC_BLKLEN);
+
+		/* set controller block count */
+		writew(req->data->blocks, priv->sdmmc_base + SDMMC_BLKCNT);
+
+		desc = (struct wmt_dma_descriptor *)priv->dma_desc_buffer;
+
+		if (req->data->flags & MMC_DATA_WRITE) {
+			sg_cnt = dma_map_sg(mmc_dev(mmc), req->data->sg,
+					    req->data->sg_len, DMA_TO_DEVICE);
+			cmdtype = 1;
+			if (req->data->blocks > 1)
+				cmdtype = 3;
+		} else {
+			sg_cnt = dma_map_sg(mmc_dev(mmc), req->data->sg,
+					    req->data->sg_len, DMA_FROM_DEVICE);
+			cmdtype = 2;
+			if (req->data->blocks > 1)
+				cmdtype = 4;
+		}
+
+		dma_address = priv->dma_desc_device_addr + 16;
+		desc_cnt = 0;
+
+		for_each_sg(req->data->sg, sg, sg_cnt, i) {
+			offset = 0;
+			while (offset < sg_dma_len(sg)) {
+				wmt_dma_init_descriptor(desc, req->data->blksz,
+						sg_dma_address(sg)+offset,
+						dma_address, 0);
+				desc++;
+				desc_cnt++;
+				offset += req->data->blksz;
+				dma_address += 16;
+				if (desc_cnt == req->data->blocks)
+					break;
+			}
+		}
+		desc--;
+		desc->flags |= 0x80000000;
+
+		if (req->data->flags & MMC_DATA_WRITE)
+			wmt_dma_config(mmc, priv->dma_desc_device_addr,
+				       PDMA_WRITE);
+		else
+			wmt_dma_config(mmc, priv->dma_desc_device_addr,
+				       PDMA_READ);
+
+		wmt_mci_send_command(mmc, command, cmdtype, arg, rsptype);
+
+		priv->comp_dma = &priv->datacomp;
+		init_completion(priv->comp_dma);
+
+		wmt_dma_start(priv);
+		wmt_mci_start_command(priv);
+	}
+}
+
+static void wmt_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+{
+	struct wmt_mci_priv *priv;
+	u32 reg_tmp;
+
+	priv = mmc_priv(mmc);
+
+	if (ios->power_mode == MMC_POWER_UP) {
+		wmt_reset_hardware(mmc);
+
+		wmt_set_sd_power(priv, WMT_SD_POWER_ON);
+	}
+	if (ios->power_mode == MMC_POWER_OFF)
+		wmt_set_sd_power(priv, WMT_SD_POWER_OFF);
+
+	if (ios->clock != 0)
+		clk_set_rate(priv->clk_sdmmc, ios->clock);
+
+	switch (ios->bus_width) {
+	case MMC_BUS_WIDTH_8:
+		reg_tmp = readb(priv->sdmmc_base + SDMMC_EXTCTRL);
+		writeb(reg_tmp | 0x04, priv->sdmmc_base + SDMMC_EXTCTRL);
+		break;
+	case MMC_BUS_WIDTH_4:
+		reg_tmp = readb(priv->sdmmc_base + SDMMC_BUSMODE);
+		writeb(reg_tmp | BM_FOURBIT_MODE, priv->sdmmc_base +
+		       SDMMC_BUSMODE);
+
+		reg_tmp = readb(priv->sdmmc_base + SDMMC_EXTCTRL);
+		writeb(reg_tmp & 0xFB, priv->sdmmc_base + SDMMC_EXTCTRL);
+		break;
+	case MMC_BUS_WIDTH_1:
+		reg_tmp = readb(priv->sdmmc_base + SDMMC_BUSMODE);
+		writeb(reg_tmp & BM_ONEBIT_MASK, priv->sdmmc_base +
+		       SDMMC_BUSMODE);
+
+		reg_tmp = readb(priv->sdmmc_base + SDMMC_EXTCTRL);
+		writeb(reg_tmp & 0xFB, priv->sdmmc_base + SDMMC_EXTCTRL);
+		break;
+	}
+}
+
+static int wmt_mci_get_ro(struct mmc_host *mmc)
+{
+	struct wmt_mci_priv *priv = mmc_priv(mmc);
+
+	return !(readb(priv->sdmmc_base + SDMMC_STS0) & STS0_WRITE_PROTECT);
+}
+
+static int wmt_mci_get_cd(struct mmc_host *mmc)
+{
+	struct wmt_mci_priv *priv = mmc_priv(mmc);
+	u32 cd = (readb(priv->sdmmc_base + SDMMC_STS0) & STS0_CD_GPI) >> 3;
+
+	return !(cd ^ priv->cd_inverted);
+}
+
+static struct mmc_host_ops wmt_mci_ops = {
+	.request = wmt_mci_request,
+	.set_ios = wmt_mci_set_ios,
+	.get_ro = wmt_mci_get_ro,
+	.get_cd = wmt_mci_get_cd,
+};
+
+/* Controller capabilities */
+static struct wmt_mci_caps wm8505_caps = {
+	.f_min = 390425,
+	.f_max = 50000000,
+	.ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34,
+	.caps = MMC_CAP_4_BIT_DATA | MMC_CAP_MMC_HIGHSPEED |
+		MMC_CAP_SD_HIGHSPEED,
+	.max_seg_size = 65024,
+	.max_segs = 128,
+	.max_blk_size = 2048,
+};
+
+static struct of_device_id wmt_mci_dt_ids[] = {
+	{ .compatible = "wm,wm8505-sdhc", .data = &wm8505_caps },
+	{ /* Sentinel */ },
+};
+
+static int wmt_mci_probe(struct platform_device *pdev)
+{
+	struct mmc_host *mmc;
+	struct wmt_mci_priv *priv;
+	struct device_node *np = pdev->dev.of_node;
+	const struct of_device_id *of_id =
+		of_match_device(wmt_mci_dt_ids, &pdev->dev);
+	const struct wmt_mci_caps *wmt_caps = of_id->data;
+	int ret;
+	int regular_irq, dma_irq;
+
+	if (!of_id || !of_id->data) {
+		dev_err(&pdev->dev, "Controller capabilities data missing\n");
+		return -EFAULT;
+	}
+
+	if (!np) {
+		dev_err(&pdev->dev, "Missing SDMMC description in devicetree\n");
+		return -EFAULT;
+	}
+
+	regular_irq = irq_of_parse_and_map(np, 0);
+	dma_irq = irq_of_parse_and_map(np, 1);
+
+	if (!regular_irq || !dma_irq) {
+		dev_err(&pdev->dev, "Getting IRQs failed!\n");
+		ret = -ENXIO;
+		goto fail1;
+	}
+
+	mmc = mmc_alloc_host(sizeof(struct wmt_mci_priv), &pdev->dev);
+	if (!mmc) {
+		dev_err(&pdev->dev, "Failed to allocate mmc_host\n");
+		ret = -ENOMEM;
+		goto fail1;
+	}
+
+	mmc->ops = &wmt_mci_ops;
+	mmc->f_min = wmt_caps->f_min;
+	mmc->f_max = wmt_caps->f_max;
+	mmc->ocr_avail = wmt_caps->ocr_avail;
+	mmc->caps = wmt_caps->caps;
+
+	mmc->max_seg_size = wmt_caps->max_seg_size;
+	mmc->max_segs = wmt_caps->max_segs;
+	mmc->max_blk_size = wmt_caps->max_blk_size;
+
+	mmc->max_req_size = (16*512*mmc->max_segs);
+	mmc->max_blk_count = mmc->max_req_size / 512;
+
+	priv = mmc_priv(mmc);
+	priv->mmc = mmc;
+	priv->dev = &pdev->dev;
+
+	priv->power_inverted = 0;
+	priv->cd_inverted = 0;
+
+	if (of_get_property(np, "sdon-inverted", NULL))
+		priv->power_inverted = 1;
+	if (of_get_property(np, "cd-inverted", NULL))
+		priv->cd_inverted = 1;
+
+	priv->sdmmc_base = of_iomap(np, 0);
+	if (!priv->sdmmc_base) {
+		dev_err(&pdev->dev, "Failed to map IO space\n");
+		ret = -ENOMEM;
+		goto fail2;
+	}
+
+	priv->irq_regular = regular_irq;
+	priv->irq_dma = dma_irq;
+
+	ret = request_irq(regular_irq, wmt_mci_regular_isr, 0, "sdmmc", priv);
+	if (ret) {
+		dev_err(&pdev->dev, "Register regular IRQ fail\n");
+		goto fail3;
+	}
+
+	ret = request_irq(dma_irq, wmt_mci_dma_isr, 32, "sdmmc", priv);
+	if (ret) {
+		dev_err(&pdev->dev, "Register DMA IRQ fail\n");
+		goto fail4;
+	}
+
+	/* alloc some DMA buffers for descriptors/transfers */
+	priv->dma_desc_buffer = dma_alloc_coherent(&pdev->dev,
+						   mmc->max_blk_count * 16,
+						   &priv->dma_desc_device_addr,
+						   208);
+	if (!priv->dma_desc_buffer) {
+		dev_err(&pdev->dev, "DMA alloc fail\n");
+		ret = -EPERM;
+		goto fail5;
+	}
+
+	platform_set_drvdata(pdev, mmc);
+
+	priv->clk_sdmmc = of_clk_get(np, 0);
+	if (IS_ERR(priv->clk_sdmmc)) {
+		dev_err(&pdev->dev, "Error getting clock\n");
+		ret = PTR_ERR(priv->clk_sdmmc);
+		goto fail5;
+	}
+
+	clk_prepare_enable(priv->clk_sdmmc);
+
+	/* configure the controller to a known 'ready' state */
+	wmt_reset_hardware(mmc);
+
+	mmc_add_host(mmc);
+
+	dev_info(&pdev->dev, "WMT SDHC Controller initialized\n");
+
+	return 0;
+fail5:
+	free_irq(dma_irq, priv);
+fail4:
+	free_irq(regular_irq, priv);
+fail3:
+	iounmap(priv->sdmmc_base);
+fail2:
+	mmc_free_host(mmc);
+fail1:
+	return ret;
+}
+
+static int wmt_mci_remove(struct platform_device *pdev)
+{
+	struct mmc_host *mmc;
+	struct wmt_mci_priv *priv;
+	struct resource *res;
+	u32 reg_tmp;
+
+	mmc = platform_get_drvdata(pdev);
+	priv = mmc_priv(mmc);
+
+	/* reset SD controller */
+	reg_tmp = readb(priv->sdmmc_base + SDMMC_BUSMODE);
+	writel(reg_tmp | BM_SOFT_RESET, priv->sdmmc_base + SDMMC_BUSMODE);
+	reg_tmp = readw(priv->sdmmc_base + SDMMC_BLKLEN);
+	writew(reg_tmp & ~(0xA000), priv->sdmmc_base + SDMMC_BLKLEN);
+	writeb(0xFF, priv->sdmmc_base + SDMMC_STS0);
+	writeb(0xFF, priv->sdmmc_base + SDMMC_STS1);
+
+	/* release the dma buffers */
+	dma_free_coherent(&pdev->dev, priv->mmc->max_blk_count * 16,
+			  priv->dma_desc_buffer, priv->dma_desc_device_addr);
+
+	mmc_remove_host(mmc);
+
+	free_irq(priv->irq_regular, priv);
+	free_irq(priv->irq_dma, priv);
+
+	iounmap(priv->sdmmc_base);
+
+	clk_disable_unprepare(priv->clk_sdmmc);
+	clk_put(priv->clk_sdmmc);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	release_mem_region(res->start, resource_size(res));
+
+	mmc_free_host(mmc);
+
+	platform_set_drvdata(pdev, NULL);
+
+	dev_info(&pdev->dev, "WMT MCI device removed\n");
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int wmt_mci_suspend(struct device *dev)
+{
+	u32 reg_tmp;
+	struct platform_device *pdev = to_platform_device(dev);
+	struct mmc_host *mmc = platform_get_drvdata(pdev);
+	struct wmt_mci_priv *priv;
+	int ret;
+
+	if (!mmc)
+		return 0;
+
+	priv = mmc_priv(mmc);
+	ret = mmc_suspend_host(mmc);
+
+	if (!ret) {
+		reg_tmp = readb(priv->sdmmc_base + SDMMC_BUSMODE);
+		writeb(reg_tmp | BM_SOFT_RESET, priv->sdmmc_base +
+		       SDMMC_BUSMODE);
+
+		reg_tmp = readw(priv->sdmmc_base + SDMMC_BLKLEN);
+		writew(reg_tmp & 0x5FFF, priv->sdmmc_base + SDMMC_BLKLEN);
+
+		writeb(0xFF, priv->sdmmc_base + SDMMC_STS0);
+		writeb(0xFF, priv->sdmmc_base + SDMMC_STS1);
+
+		clk_disable(priv->clk_sdmmc);
+	}
+	return ret;
+}
+
+static int wmt_mci_resume(struct device *dev)
+{
+	u32 reg_tmp;
+	struct platform_device *pdev = to_platform_device(dev);
+	struct mmc_host *mmc = platform_get_drvdata(pdev);
+	struct wmt_mci_priv *priv;
+	int ret = 0;
+
+	if (mmc) {
+		priv = mmc_priv(mmc);
+		clk_enable(priv->clk_sdmmc);
+
+		reg_tmp = readb(priv->sdmmc_base + SDMMC_BUSMODE);
+		writeb(reg_tmp | BM_SOFT_RESET, priv->sdmmc_base +
+		       SDMMC_BUSMODE);
+
+		reg_tmp = readw(priv->sdmmc_base + SDMMC_BLKLEN);
+		writew(reg_tmp | (BLKL_GPI_CD | BLKL_INT_ENABLE),
+		       priv->sdmmc_base + SDMMC_BLKLEN);
+
+		reg_tmp = readb(priv->sdmmc_base + SDMMC_INTMASK0);
+		writeb(reg_tmp | INT0_DI_INT_EN, priv->sdmmc_base +
+		       SDMMC_INTMASK0);
+
+		ret = mmc_resume_host(mmc);
+	}
+
+	return ret;
+}
+
+static const struct dev_pm_ops wmt_mci_pm = {
+	.suspend        = wmt_mci_suspend,
+	.resume         = wmt_mci_resume,
+};
+
+#define wmt_mci_pm_ops (&wmt_mci_pm)
+
+#else	/* !CONFIG_PM */
+
+#define wmt_mci_pm_ops NULL
+
+#endif
+
+static struct platform_driver wmt_mci_driver = {
+	.probe = wmt_mci_probe,
+	.remove = wmt_mci_remove,
+	.driver = {
+		.name = DRIVER_NAME,
+		.owner = THIS_MODULE,
+		.pm = wmt_mci_pm_ops,
+		.of_match_table = wmt_mci_dt_ids,
+	},
+};
+
+module_platform_driver(wmt_mci_driver);
+
+MODULE_DESCRIPTION("Wondermedia MMC/SD Driver");
+MODULE_AUTHOR("Tony Prisk");
+MODULE_LICENSE("GPL v2");
+MODULE_DEVICE_TABLE(of, wmt_mci_dt_ids);
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mtd/cmdlinepart.c linux-linaro-3.4-2012.05-1_cavium/drivers/mtd/cmdlinepart.c
--- linux-linaro-3.4-2012.05-1_original/drivers/mtd/cmdlinepart.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mtd/cmdlinepart.c	2014-10-23 20:22:19.978715000 +0800
@@ -71,7 +71,7 @@
 static struct cmdline_mtd_partition *partitions;
 
 /* the command line passed to mtdpart_setupd() */
-static char *cmdline;
+static char *mtdparts;
 static int cmdline_parsed = 0;
 
 /*
@@ -324,7 +324,7 @@
 
 	/* parse command line */
 	if (!cmdline_parsed)
-		mtdpart_setup_real(cmdline);
+		mtdpart_setup_real(mtdparts);
 
 	for(part = partitions; part; part = part->next)
 	{
@@ -367,14 +367,18 @@
  *
  * This function needs to be visible for bootloaders.
  */
+
 static int mtdpart_setup(char *s)
 {
-	cmdline = s;
+	mtdparts = s;
 	return 1;
 }
 
 __setup("mtdparts=", mtdpart_setup);
 
+module_param(mtdparts, charp, 0644);
+
+
 static struct mtd_part_parser cmdline_parser = {
 	.owner = THIS_MODULE,
 	.parse_fn = parse_cmdline_partitions,
@@ -386,7 +390,13 @@
 	return register_mtd_parser(&cmdline_parser);
 }
 
+static void __exit cmdline_parser_exit(void)
+{
+	deregister_mtd_parser(&cmdline_parser);
+}
+
 module_init(cmdline_parser_init);
+module_exit(cmdline_parser_exit);
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Marius Groeger <mag@sysgo.de>");
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mtd/devices/m25p80.c linux-linaro-3.4-2012.05-1_cavium/drivers/mtd/devices/m25p80.c
--- linux-linaro-3.4-2012.05-1_original/drivers/mtd/devices/m25p80.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mtd/devices/m25p80.c	2014-08-05 16:12:30.760330000 +0800
@@ -655,6 +655,8 @@
 	{ "mx25l25635e", INFO(0xc22019, 0, 64 * 1024, 512, 0) },
 	{ "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) },
 
+	{ "mx25u6435f",  INFO(0xc22537, 0, 64 * 1024, 128, 0) },
+
 	/* Spansion -- single (large) sector size only, at least
 	 * for the chips listed here (without boot sectors).
 	 */
@@ -723,11 +725,18 @@
 	{ "w25x20", INFO(0xef3012, 0, 64 * 1024,  4,  SECT_4K) },
 	{ "w25x40", INFO(0xef3013, 0, 64 * 1024,  8,  SECT_4K) },
 	{ "w25x80", INFO(0xef3014, 0, 64 * 1024,  16, SECT_4K) },
+	{ "w25q80", INFO(0xef4014, 0, 64 * 1024,  16, SECT_4K) },
 	{ "w25x16", INFO(0xef3015, 0, 64 * 1024,  32, SECT_4K) },
+	{ "w25q16", INFO(0xef4015, 0, 64 * 1024,  32, SECT_4K) },
 	{ "w25x32", INFO(0xef3016, 0, 64 * 1024,  64, SECT_4K) },
 	{ "w25q32", INFO(0xef4016, 0, 64 * 1024,  64, SECT_4K) },
 	{ "w25x64", INFO(0xef3017, 0, 64 * 1024, 128, SECT_4K) },
 	{ "w25q64", INFO(0xef4017, 0, 64 * 1024, 128, SECT_4K) },
+	{ "w25q128", INFO(0xef4018, 0, 64 * 1024, 256, SECT_4K) },
+
+	/* Giga Devices */
+	{ "gd25q80", INFO(0xc84014, 0, 64 * 1024, 16, SECT_4K) },
+	{ "qd25q64", INFO(0xc84017, 0, 64 * 1024, 128, SECT_4K) },
 
 	/* Catalyst / On Semiconductor -- non-JEDEC */
 	{ "cat25c11", CAT25_INFO(  16, 8, 16, 1) },
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mtd/devices/Makefile linux-linaro-3.4-2012.05-1_cavium/drivers/mtd/devices/Makefile
--- linux-linaro-3.4-2012.05-1_original/drivers/mtd/devices/Makefile	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mtd/devices/Makefile	2014-07-29 17:28:38.819972000 +0800
@@ -20,4 +20,4 @@
 obj-$(CONFIG_MTD_SPEAR_SMI)	+= spear_smi.o
 obj-$(CONFIG_MTD_SST25L)	+= sst25l.o
 
-CFLAGS_docg3.o			+= -I$(src)
\ No newline at end of file
+CFLAGS_docg3.o			+= -I$(src)
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mtd/devices/spidev_cnc18xx.c linux-linaro-3.4-2012.05-1_cavium/drivers/mtd/devices/spidev_cnc18xx.c
--- linux-linaro-3.4-2012.05-1_original/drivers/mtd/devices/spidev_cnc18xx.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mtd/devices/spidev_cnc18xx.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,2058 @@
+/*
+ * MTD SPI driver for ST M25Pxx (and similar) serial flash chips
+ *
+ * Author: Mike Lavender, mike@steroidmicros.com
+ *
+ * Copyright (c) 2005, Intec Automation Inc.
+ *
+ * Some parts are based on lart.c by Abraham Van Der Merwe
+ *
+ * Cleaned up and generalized based on mtd_dataflash.c
+ *
+ * This code 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/io.h>
+#include <linux/cdev.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/err.h>
+#include <linux/errno.h>
+#include <linux/fcntl.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/kernel.h>
+#include <linux/miscdevice.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/poll.h>
+#include <linux/preempt.h>
+#include <linux/proc_fs.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/spi/spi.h>
+#include <linux/types.h>
+#include <linux/version.h>
+#include <linux/workqueue.h>
+
+#include <linux/device.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/cacheflush.h>
+#include <linux/spi/cnc18xx_spi.h>
+
+/* #define DEBUG(n, args...) printk(KERN_ERR args); */
+
+#define CONFIG_SPI_DMA
+
+#define FLASH_PAGESIZE    256
+
+//#define SPI_PINMUX        0x4211000c
+
+/* Flash opcodes. */
+#define OPCODE_WREN       0x06       /* Write enable                     */
+#define OPCODE_RDSR       0x05       /* Read status register             */
+#define OPCODE_WRSR       0x01       /* Write status register 1 byte     */
+#define OPCODE_NORM_READ  0x03       /* Read data bytes (low frequency)  */
+#define OPCODE_FAST_READ  0x0b       /* Read data bytes (high frequency) */
+#define OPCODE_PP         0x02       /* Page program (up to 256 bytes)   */
+#define OPCODE_BE_4K      0x20       /* Erase 4KiB block                 */
+#define OPCODE_BE_32K     0x52       /* Erase 32KiB block                */
+#define OPCODE_CHIP_ERASE 0xc7       /* Erase whole flash chip           */
+#define OPCODE_SE         0xd8       /* Sector erase (usually 64KiB)     */
+#define OPCODE_RDID       0x9f       /* Read JEDEC ID                    */
+
+#define MAX_RCV_SZ        0x1000
+#define RD_SZ             MAX_RCV_SZ
+
+#define DEF_R_SPEED       0x8
+#define DEF_W_SPEED       0x8
+
+#define DEF_DMA_R_SPEED   0x4
+#define DEF_DMA_W_SPEED   0x2
+
+/* Status Register bits. */
+#define SR_WIP            1    /* Write in progress                */
+#define SR_WEL            2    /* Write enable latch               */
+/* meaning of other SR_* bits may differ between vendors */
+#define SR_BP0            4    /* Block protect 0                  */
+#define SR_BP1            8    /* Block protect 1                  */
+#define SR_BP2            0x10 /* Block protect 2                  */
+#define SR_SRWD           0x80 /* SR write protect                 */
+
+/* Define max times to check status register before we give up. */
+#define	MAX_READY_WAIT_JIFFIES	(40 * HZ)	/* M25P16 specs 40s max chip erase */
+#define	CMD_SIZE		4
+
+#ifdef CONFIG_M25PXX_USE_FAST_READ
+#define OPCODE_READ 	OPCODE_FAST_READ
+#define FAST_READ_DUMMY_BYTE 1
+#else
+#define OPCODE_READ 	OPCODE_NORM_READ
+#define FAST_READ_DUMMY_BYTE 0
+#endif
+
+typedef struct __SPI_REGS {
+		u32 ctrlr0;    /*0x00           */
+		u32 ctrlr1;    /*0x04           */
+		u32 ssienr;    /*0x08           */
+		u32 mwcr;      /*0x0C           */
+		u32 ser;       /*0x10           */
+		u32 baudr;     /*0x14           */
+		u32 txftlr;    /*0x18           */
+		u32 rxftlr;    /*0x1C           */
+		u32 txflr;     /*0x20           */
+		u32 rxflr;     /*0x24           */
+		u32 sr;        /*0x28           */
+		u32 imr;       /*0x2C           */
+		u32 isr;       /*0x30           */
+		u32 risr;      /*0x34           */
+		u32 txoicr;    /*0x38           */
+		u32 rxoicr;    /*0x3C           */
+		u32 rxuicr;    /*0x40           */
+		u32 msticr;    /*0x44           */
+		u32 icr;       /*0x48           */
+		u32 dmacr;     /*0x4c           */
+		u32 dmatdlr;   /*0x50           */
+		u32 dmardlr;   /*0x54           */
+		u32 rsv1;      /*0x58, reserved */
+		u32 rsv2;      /*0x5c, reserved */
+		u32 dr;        /*0x60           */
+} spi_regs_t;
+
+/*******************************************************************
+ * DMA */
+#define DW_REG(name)		u32 name; u32 __pad_##name
+/* Hardware register definitions. */
+struct dw_dma_chan_regs {
+    DW_REG(SAR);     /* Source Address Register      */
+    DW_REG(DAR);     /* Destination Address Register */
+    DW_REG(LLP);     /* Linked List Pointer          */
+    u32 CTL_LO;      /* Control Register Low         */
+    u32 CTL_HI;      /* Control Register High        */
+    DW_REG(SSTAT);
+    DW_REG(DSTAT);
+    DW_REG(SSTATAR);
+    DW_REG(DSTATAR);
+    u32 CFG_LO;      /* Configuration Register Low   */
+    u32 CFG_HI;      /* Configuration Register High  */
+	DW_REG(SGR);
+	DW_REG(DSR);
+};
+
+struct dw_dma_irq_regs {
+	DW_REG(XFER);
+	DW_REG(BLOCK);
+	DW_REG(SRC_TRAN);
+	DW_REG(DST_TRAN);
+	DW_REG(ERROR);
+};
+
+#define DW_DMA_MAX_NR_CHANNELS 8
+#define DW_SPI_REG_DMA         0x4000
+typedef struct dw_dma_regs {
+	/* per-channel registers */
+	struct dw_dma_chan_regs	CHAN[DW_DMA_MAX_NR_CHANNELS];
+
+	/* irq handling */
+	struct dw_dma_irq_regs	RAW;		/* r */
+	struct dw_dma_irq_regs	STATUS;		/* r (raw & mask) */
+	struct dw_dma_irq_regs	MASK;		/* rw (set = irq enabled) */
+	struct dw_dma_irq_regs	CLEAR;		/* w (ack, affects "raw") */
+
+	DW_REG(STATUS_INT);			/* r */
+
+	/* software handshaking */
+	DW_REG(REQ_SRC);
+	DW_REG(REQ_DST);
+	DW_REG(SGL_REQ_SRC);
+	DW_REG(SGL_REQ_DST);
+	DW_REG(LAST_SRC);
+	DW_REG(LAST_DST);
+
+	/* miscellaneous */
+	DW_REG(CFG);
+	DW_REG(CH_EN);
+	DW_REG(ID);
+	DW_REG(TEST);
+
+	/* optional encoded params, 0x3c8..0x3 */
+} dma_regs_t;
+
+struct dw_prd {
+        __le32      sar;
+        __le32      dar;
+	    __le32		llp;
+	    __le32		ctl_lo;
+	    __le32		ctl_hi;
+};
+
+#define DW_PRD_SZ          20
+#define DW_MAX_PRD         256
+#define DW_PRD_TBL_SZ      (DW_MAX_PRD * DW_PRD_SZ)
+
+
+/* DMA END *
+*******************************************************************/
+
+struct s25f {
+	int                    irq;
+	struct tasklet_struct  tasklet;
+
+	void __iomem          *spi;
+	struct mutex           lock;
+	spinlock_t             slock;
+	wait_queue_head_t      queue;
+	struct mtd_info        mtd;
+	unsigned               partitioned:1;
+	u8                     erase_opcode;
+	u8                     command[CMD_SIZE + FAST_READ_DUMMY_BYTE];
+
+
+    u8                     chardev; /* Config for char device  */
+
+	/* Dma */
+	void __iomem          *dma;
+	dma_addr_t             rx_dma;
+	dma_addr_t             tx_dma;
+    struct dw_prd         *prd;        /* our SG list     */
+    dma_addr_t             prd_phy;
+
+    int                    dma_inited;
+    int                    txdma_done;
+    int                    rxdma_done;
+
+    u8                    *dma_buf;    /* dma buf for r/w */
+	dma_addr_t             dma_buf_phy;
+};
+
+/* Register operation */
+#define spi_writeb(b,a,v) iowrite8(v, &b->a)
+#define spi_write(b,a,v)  iowrite16(v, &b->a)
+#define spi_writel(b,a,v) iowrite32(v, &b->a)
+
+#define spi_readb(b,a)    ioread8(&b->a)
+#define spi_read(b,a)     ioread16(&b->a)
+#define spi_readl(b,a)    ioread32(&b->a)
+
+#define dma_readl(dw, name)                     \
+    __raw_readl(&(dw->name))
+#define dma_writel(dw, name, val)               \
+    __raw_writel((val), &(dw->name))
+
+#define channel_set_bit(dw, reg, mask)          \
+    dma_writel(dw, reg, ((mask) << 8) | (mask))
+#define channel_clear_bit(dw, reg, mask)        \
+	dma_writel(dw, reg, ((mask) << 8) | 0)
+
+/* Reload func */
+#if defined(CONFIG_SPI_DMA) && !defined(CONFIG_SPI_CHARDEV)
+#	define              flash_read  dma_flash_read
+#	define              flash_write dma_flash_write
+#else
+#	define              flash_read  io_flash_read
+#	define              flash_write io_flash_write
+#endif
+
+static int SPI_DEBUG = 0;
+#ifdef CONFIG_SPI_DEBUG
+# ifdef __KERNEL__
+#  define SDEBUG(args...) printk(args)
+# else
+#  define SDEBUG(args...) printf(args)
+# endif
+#else
+# define SDEBUG(args...) \
+	if (SPI_DEBUG) printk(args)
+#endif
+
+/******************************************************************/
+/* Varable definiation */
+static struct s25f *flash = NULL;
+
+/******************************************************************/
+/* Function definiation */
+static int controller_init(spi_regs_t *spi)
+{
+	unsigned short  ctrl0 = 0;
+
+ //   writel(0x1, IO_ADDRESS(SPI_PINMUX)); /* Enable SPI */
+
+    spi_write(spi, ssienr, 0x0);
+
+	/* Config the CTRLR0 register */
+    ctrl0 = 0x0 << 12  | /* CFS          */
+            0x0 << 11  | /* SRL 0        */
+            0x0 << 10  | /* SLV_OE       */
+            0x0 << 8   | /* TMOD master  */
+            0x1 << 7   | /* SCPOL clock  */
+            0x1 << 6   | /* SCPH         */
+            0x0 << 4   | /* frame format */
+            0x7 << 0;    /* DFS          */
+
+    spi_write(spi, ctrlr0,  ctrl0          );
+    spi_write(spi, ctrlr1,  (MAX_RCV_SZ-1) ); /* only on EE mode             */
+    spi_write(spi, imr,     0x0            ); /* Disable all spi interrupts  */
+    spi_write(spi, baudr,   DEF_R_SPEED    ); /* rBAUDR 10M                  */
+    spi_write(spi, ser,     0x1            ); /* rSER, select the device     */
+    spi_write(spi, ssienr,  0x1            ); /* rSSIENR, enable the ssi bus */
+
+    return 0;
+}
+
+static inline void write_enable(void)
+{
+	spi_regs_t *spi = flash->spi;
+
+	/* Unprotect flash */
+	spi_write(spi, ssienr, 0x0     );
+	spi_write(spi, ctrlr0, 0x1c7   );
+	spi_write(spi, ssienr, 0x1     );
+	spi_write(spi, dr, OPCODE_WREN );
+	while ((spi_read(spi, sr) & 0x5) != 0x4);
+}
+
+static void wait_for_finished(void)
+{
+	unsigned int status;
+	spi_regs_t *spi = flash->spi;
+
+	spi_write(spi, ssienr, 0x0   );
+	spi_write(spi, ctrlr0, 0x3c7 );
+	spi_write(spi, ctrlr1, 0x0   );
+	spi_write(spi, ssienr, 0x1   );
+
+	do {
+		spi_write(spi, dr,  OPCODE_RDSR);
+		while(spi_read(spi, rxflr) != 1);
+		status = spi_read(spi, dr);
+	} while(status & SR_WIP);
+}
+
+
+/* flash read */
+static inline int io_flash_read(unsigned int caddr, unsigned char *buf, size_t len)
+{
+	unsigned long flags;
+	spi_regs_t *spi = flash->spi;
+	unsigned char *addr = (unsigned char *)&caddr;
+	size_t size = len;
+
+    //DEBUG(MTD_DEBUG_LEVEL2, "%s: flash offset: 0x%x, len: %u\n", __func__, caddr, len);
+	spin_lock_irqsave(&flash->slock, flags);
+
+	spi_write(spi, ssienr, 0x0);
+	spi_write(spi, ctrlr0, 0x3c7);
+	spi_write(spi, ctrlr1, (RD_SZ-1));
+	spi_write(spi, baudr,  DEF_R_SPEED);
+	spi_write(spi, ssienr, 0x1);
+
+
+	spi_write(spi, dr, OPCODE_READ);
+	spi_write(spi, dr, addr[2]);
+	spi_write(spi, dr, addr[1]);
+	spi_write(spi, dr, addr[0]);
+
+	while (size > 0) {
+		if (size >= 16) {
+			while (spi_read(spi, rxflr) < 16);
+			*buf++ =  spi_read(spi, dr);
+			*buf++ =  spi_read(spi, dr);
+			*buf++ =  spi_read(spi, dr);
+			*buf++ =  spi_read(spi, dr);
+			*buf++ =  spi_read(spi, dr);
+			*buf++ =  spi_read(spi, dr);
+			*buf++ =  spi_read(spi, dr);
+			*buf++ =  spi_read(spi, dr);
+			*buf++ =  spi_read(spi, dr);
+			*buf++ =  spi_read(spi, dr);
+			*buf++ =  spi_read(spi, dr);
+			*buf++ =  spi_read(spi, dr);
+			*buf++ =  spi_read(spi, dr);
+			*buf++ =  spi_read(spi, dr);
+			*buf++ =  spi_read(spi, dr);
+			*buf++ =  spi_read(spi, dr);
+			size   -= 16;
+		} else if (size >= 8) {
+			while (spi_read(spi, rxflr) < 8);
+			*buf++ =  spi_read(spi, dr);
+			*buf++ =  spi_read(spi, dr);
+			*buf++ =  spi_read(spi, dr);
+			*buf++ =  spi_read(spi, dr);
+			*buf++ =  spi_read(spi, dr);
+			*buf++ =  spi_read(spi, dr);
+			*buf++ =  spi_read(spi, dr);
+			*buf++ =  spi_read(spi, dr);
+			size   -= 8;
+		} else if (size >= 4) {
+			while (spi_read(spi, rxflr) < 4);
+			*buf++ =  spi_read(spi, dr);
+			*buf++ =  spi_read(spi, dr);
+			*buf++ =  spi_read(spi, dr);
+			*buf++ =  spi_read(spi, dr);
+			size   -= 4;
+		} else if (size >= 2) {
+			while (spi_read(spi, rxflr) < 2);
+			*buf++ =  spi_read(spi, dr);
+			*buf++ =  spi_read(spi, dr);
+			size   -= 2;
+		} else if (size > 0) {
+			while (spi_read(spi, rxflr) == 0);
+			*buf++ =  spi_read(spi, dr);
+			size   -= 1;
+		}
+	}
+
+	spin_unlock_irqrestore(&flash->slock, flags);
+
+	return (len - size);
+}
+
+static inline int io_flash_write(unsigned int caddr, const u_char *buf, size_t len)
+{
+	unsigned long flags;
+	spi_regs_t *spi = flash->spi;
+	unsigned char *addr = (unsigned char *)&caddr;
+	size_t size = len;
+
+    //DEBUG(MTD_DEBUG_LEVEL2, "%s: flash offset: 0x%x, len: %u\n", __func__, caddr, len);
+    //printk("%s: flash offset: 0x%x, len: %u\n", __func__, caddr, len);
+
+	spin_lock_irqsave(&flash->slock, flags);
+
+	/* Unprotect flash */
+	spi_write(spi, ssienr, 0x0);
+	spi_write(spi, ctrlr0, 0x1c7);
+	spi_write(spi, ssienr, 0x1);
+	spi_write(spi, dr, OPCODE_WREN);
+	while ((spi_read(spi, sr) & 0x5) != 0x4);
+
+	spi_write(spi, ssienr, 0x0);
+	spi_write(spi, ctrlr0, 0x1c7);
+	spi_write(spi, baudr,  DEF_W_SPEED);
+	spi_write(spi, ssienr, 0x1);
+
+
+	spi_write(spi, dr, OPCODE_PP);
+	spi_write(spi, dr, addr[2]);
+	spi_write(spi, dr, addr[1]);
+	spi_write(spi, dr, addr[0]);
+
+	while (size) {
+		if (size >= 16) {
+			spi_write(spi, dr, *buf++);
+			spi_write(spi, dr, *buf++);
+			spi_write(spi, dr, *buf++);
+			spi_write(spi, dr, *buf++);
+			spi_write(spi, dr, *buf++);
+			spi_write(spi, dr, *buf++);
+			spi_write(spi, dr, *buf++);
+			spi_write(spi, dr, *buf++);
+			spi_write(spi, dr, *buf++);
+			spi_write(spi, dr, *buf++);
+			spi_write(spi, dr, *buf++);
+			spi_write(spi, dr, *buf++);
+			spi_write(spi, dr, *buf++);
+			spi_write(spi, dr, *buf++);
+			spi_write(spi, dr, *buf++);
+			spi_write(spi, dr, *buf++);
+			while (spi_read(spi, txflr) > 8);
+			size -= 16;
+		} else if (size >= 8) {
+			spi_write(spi, dr, *buf++);
+			spi_write(spi, dr, *buf++);
+			spi_write(spi, dr, *buf++);
+			spi_write(spi, dr, *buf++);
+			spi_write(spi, dr, *buf++);
+			spi_write(spi, dr, *buf++);
+			spi_write(spi, dr, *buf++);
+			spi_write(spi, dr, *buf++);
+			while (spi_read(spi, txflr) > 8);
+			size -= 8;
+		} else if (size >= 4) {
+			spi_write(spi, dr, *buf++);
+			spi_write(spi, dr, *buf++);
+			spi_write(spi, dr, *buf++);
+			spi_write(spi, dr, *buf++);
+			while (spi_read(spi, txflr) > 8);
+			size -= 4;
+		} else if (size >= 2) {
+			spi_write(spi, dr, *buf++);
+			spi_write(spi, dr, *buf++);
+			while (spi_read(spi, txflr) > 8);
+			size -= 2;
+		} else if (size > 0) {
+			spi_write(spi, dr, *buf++);
+			while (spi_read(spi, txflr) > 8);
+			size -= 1;
+		}
+	}
+
+
+	while ((spi_read(spi, sr) & 0x5) != 0x4);
+	wait_for_finished ();
+	spin_unlock_irqrestore(&flash->slock, flags);
+
+	return (len - size);
+}
+
+static inline void dma_config_rx(unsigned char *buf, size_t len)
+{
+    unsigned int   ctl_lo;
+
+    dma_regs_t    *dma    = flash->dma;
+    struct dw_prd *prd    = flash->prd;
+
+    /* Gloabl Enable DMA */
+    dma_writel(dma, CFG,    0x1);
+
+    ctl_lo =  0x0             /* CTL[31:0]                    */
+              | (0x1  << 28)  /* LLP_SRC_EN                   */
+              | (0x1  << 27)  /* LLP_DST_EN                   */
+              | (0x0  << 25)  /* SRC Master                   */
+              | (0x1  << 23)  /* DST Master                   */
+              | (0x2  << 20)  /* P -> M, M as flow controller */
+              | (0x0  << 18)  /* DSCATTER_EN                  */
+              | (0x0  << 17)  /* SGATHER_EN                   */
+              | (0x1  << 14)  /* SMSIZE:  4 * 1B              */
+              | (0x3  << 11)  /* DMSIZE: 16 * 4B              */
+              | (0x2  <<  9)  /* SINC: no change              */
+              | (0x0  <<  7)  /* DINC: increment              */
+              | (0x0  <<  4)  /* SRC_TR_WIDTH:  8b            */
+              | (0x2  <<  1)  /* DST_TR_WIDTH: 32b            */
+              | (0x0  <<  0); /* INT_EN                       */
+
+    prd->sar    = PA_SPI_BASE + 0x60;                 /* SAR      */
+    prd->dar    = flash->dma_buf_phy;                 /* DAR      */
+    prd->llp    = (flash->prd_phy + DW_PRD_SZ) | 0x1; /* Next LLP */
+    prd->ctl_lo = ctl_lo;
+    prd->ctl_hi = (len > 2048)? 2048 : len;
+
+    if (len > 2048) {
+        prd++;
+        prd->sar    = PA_SPI_BASE + 0x60;        /* SAR      */
+        prd->dar    = flash->dma_buf_phy + 2048; /* DAR      */
+        prd->llp    = 0;                         /* Next LLP */
+        prd->ctl_lo = ctl_lo | 0x1;
+        prd->ctl_hi = len - 2048;
+    } else
+        prd->llp = 0;                                 /* Less than 2048, then no xfer */
+
+    dma_writel(dma,      CHAN[0].CTL_LO, 0x3 << 27 );            /* LLP_SRC_EN/LLP_DST_EN                           */
+    dma_writel(dma,      CHAN[0].CFG_HI, 0x1 <<  7 );            /* use RX handshaking signals for source periphral */
+    dma_writel(dma,      CHAN[0].CFG_LO, 0x1 << 10 );            /* HS_SEL_DST = 0 (HW) HS_SEL_DST = 1 (SW )        */
+    dma_writel(dma,      CHAN[0].LLP,    flash->prd_phy | 0x1 ); /* LMS = 1 external DRAM                           */
+    channel_set_bit(dma, CH_EN,          0x1       );            /* Enable the only channel                         */
+
+    dma_writel(dma,      CLEAR.XFER,     0x1       );
+    channel_set_bit(dma, MASK.XFER,      0x1       );
+}
+
+static inline void dma_config_tx(const u_char *buf, size_t len)
+{
+    unsigned int   ctl_lo;
+
+    dma_regs_t    *dma    = flash->dma;
+    struct dw_prd *prd    = flash->prd;
+
+    /* Gloabl Enable DMA */
+    dma_writel(dma, CFG,    0x1);
+
+    ctl_lo = 0x0               /* CTL[31:0]                    */
+             | ( 0x1  << 28 )  /* LLP_SRC_EN                   */
+             | ( 0x1  << 27 )  /* LLP_DST_EN                   */
+             | ( 0x1  << 25 )  /* SRC Master                   */
+             | ( 0x0  << 23 )  /* DST Master                   */
+             | ( 0x1  << 20 )  /* M -> P, M as flow controller */
+             | ( 0x0  << 18 )  /* DSCATTER_EN                  */
+             | ( 0x0  << 17 )  /* SGATHER_EN                   */
+             | ( 0x3  << 14 )  /* SMSIZE: 16 * 4B              */
+             | ( 0x1  << 11 )  /* DMSIZE:  4 * 1B              */
+             | ( 0x0  <<  9 )  /* SINC: increment              */
+             | ( 0x2  <<  7 )  /* DINC: no charge              */
+             | ( 0x2  <<  4 )  /* SRC_TR_WIDTH: 32b            */
+             | ( 0x0  <<  1 )  /* DST_TR_WIDTH:  8b            */
+             | ( 0x1  <<  0 ); /* INT_EN                       */
+
+    prd->sar    = flash->dma_buf_phy; /* SAR      */
+    prd->dar    = PA_SPI_BASE + 0x60; /* DAR      */
+    prd->llp    = 0;                  /* Next LLP */
+    prd->ctl_lo = ctl_lo;
+    prd->ctl_hi = (len + 4) / 4;
+
+    dma_writel(dma,      CHAN[0].CTL_LO, 0x3 << 27 );            /* LLP_SRC_EN/LLP_DST_EN                           */
+    dma_writel(dma,      CHAN[0].CFG_HI, 0x0 <<  7 );            /* use RX handshaking signals for source periphral */
+    dma_writel(dma,      CHAN[0].CFG_LO, 0x2 << 10 );            /* HS_SEL_DST = 0 (HW) HS_SEL_DST = 1 (SW )        */
+    dma_writel(dma,      CHAN[0].LLP,    flash->prd_phy | 0x1 ); /* LMS = 1 external DRAM                           */
+    channel_set_bit(dma, CH_EN,          0x1       );            /* Enable the only channel                         */
+
+    dma_writel(dma,      CLEAR.XFER,     0x1       );
+    channel_set_bit(dma, MASK.XFER,      0x1       );
+}
+
+static inline int dma_flash_read(unsigned int caddr, unsigned char *buf, size_t len)
+{
+    unsigned long  flags;
+    size_t         cnt;
+
+    spi_regs_t    *spi    = flash->spi;
+    dma_regs_t    *dma    = flash->dma;
+
+    //DEBUG(MTD_DEBUG_LEVEL2, "%s: flash offset: 0x%x, len: %u\n", __func__, caddr, len);
+
+    /* Force 4B align */
+    cnt = (len & 0x3) ? ((len + 4) >> 2) << 2: len;
+
+    /* Set Controller */
+    spi_write(spi, ssienr,  0x0     );
+    spi_write(spi, ctrlr0,  0x3c7   );
+    spi_write(spi, ctrlr1,  (cnt-1) );
+    spi_write(spi, baudr,   DEF_DMA_R_SPEED);
+    spi_write(spi, dmardlr, 3       );
+    spi_write(spi, dmacr,   1       );
+    spi_write(spi, ssienr,  0x3     );
+
+    /* Config DMA RX */
+    dma_config_rx(buf, cnt);
+
+    spi_write(spi, dr    , OPCODE_READ        );
+    spi_write(spi, dr    , (caddr>>16) & 0xff );
+    spi_write(spi, dr    , (caddr>>8)  & 0xff );
+    spi_write(spi, dr    , (caddr)     & 0xff );
+    spi_write(spi, ssienr, 0x1                );
+
+    while (dma_readl(dma, CH_EN));
+#if 0
+    {
+		u32 status_block;
+		u32 status_xfer;
+		u32 status_err;
+		u32 st;
+		st = dma_readl(dma, STATUS_INT);
+
+		status_block = dma_readl(dma, RAW.BLOCK);
+		status_xfer  = dma_readl(dma, RAW.XFER);
+		status_err   = dma_readl(dma, RAW.ERROR);
+		printk("block: %x, xfer: %x, err: %x, ctl_hi: %x -- st: %x -- len: %x\n",
+			   status_block, status_xfer, status_err, prd->ctl_hi, st, len);
+
+    }
+#endif
+    memcpy(buf, flash->dma_buf, len);
+
+    return (len);
+}
+
+static inline int dma_flash_write_aln(unsigned int caddr, const u_char *buf, size_t len)
+{
+    spi_regs_t    *spi    = flash->spi;
+    dma_regs_t    *dma    = flash->dma;
+
+    //DEBUG(MTD_DEBUG_LEVEL2, "%s: flash offset: 0x%x, len: %u\n", __func__, caddr, len);
+
+	if (len & 0x3)
+		return -EINVAL;
+
+    /* Write_Enable();*/
+    spi_write(spi, ssienr,  0x0         );
+    spi_write(spi, ctrlr0,  0x1c7       );
+    spi_write(spi, ssienr,  0x1         );
+    spi_write(spi, dr,      OPCODE_WREN );
+    while ((spi_read(spi, sr) & 0x5) != 0x4);
+
+    /* Reorganize Data */
+    flash->dma_buf[0] = OPCODE_PP;
+    flash->dma_buf[1] = (caddr>>16) & 0xff;
+    flash->dma_buf[2] = (caddr>>8)  & 0xff;
+    flash->dma_buf[3] = (caddr)     & 0xff;
+    memcpy(flash->dma_buf + 4, buf, len);
+
+    /* Set Controller */
+    spi_write(spi, ssienr,  0x0         );
+    spi_write(spi, ctrlr0,  0x1c7       ); /* Transmit Only                                                */
+    spi_write(spi, dmatdlr, 16          ); /* When FIFO half full, receive from DMA controller immediately */
+    spi_write(spi, dmacr,   0x2         ); /* Transmit FIFO DMA request enabled                            */
+    spi_write(spi, baudr,   DEF_DMA_W_SPEED);
+    spi_write(spi, ssienr,  0x1         );
+
+    /* Config DMA TX */
+    dma_config_tx(buf, len);
+
+    while (dma_readl(dma, CH_EN));
+	while((spi_read(spi, sr) & 0x5) != 0x4);
+    wait_for_finished();
+
+    return (len);
+}
+
+static inline int dma_flash_write(unsigned int caddr, const u_char *buf, size_t len)
+{
+	size_t remain;
+	size_t cnt;
+
+	if (len == 0 || len > FLASH_PAGESIZE) {
+		printk("%s: Write size is invalid, len: %u\n", __func__, len);
+		return -EINVAL;
+	}
+
+	remain = len % 4;
+	cnt = len - remain;
+
+	pr_debug("remain: %d, cnt: %d len: %d\n", remain, cnt, len);
+
+	while (cnt &&
+		   (cnt != dma_flash_write_aln(caddr, buf, cnt)))
+		printk("%s: DMA Write Error, Reread! ret: %d\n", __func__, cnt);
+
+	while (remain &&
+		   (remain != io_flash_write(caddr+cnt, buf+cnt, remain)))
+		printk("%s: IO Write Error, Reread! ret: %d\n", __func__, cnt);
+
+	return (len);
+}
+
+/*********************************************************************************/
+/*
+ * Erase the whole flash memory
+ *
+ * Returns 0 if successful, non-zero otherwise.
+ */
+static int erase_chip(void)
+{
+	spi_regs_t *spi = flash->spi;
+
+	pr_debug("%s: %s %lldKiB\n",
+		  "spi-flash", __func__,
+		  (long long)(flash->mtd.size >> 10));
+
+	/* Unprotect flash */
+	spi_write(spi, ssienr, 0x0         );
+	spi_write(spi, ctrlr0, 0x107       );
+	spi_write(spi, ssienr, 0x1         );
+	spi_write(spi, dr,     OPCODE_WREN );
+	while ((spi_read(spi, sr) & 0x5) != 0x4);
+
+	spi_write(spi, ssienr, 0x0         );
+	spi_write(spi, ctrlr0, 0x1c7       );
+	spi_write(spi, baudr,  DEF_R_SPEED );
+	spi_write(spi, ssienr, 0x1         );
+
+	spi_write(spi, dr, OPCODE_CHIP_ERASE);
+	while ((spi_read(spi, sr) & 0x5) != 0x4);
+
+	/* Wait until finished previous write command. */
+	wait_for_finished();
+
+	return 0;
+}
+
+/*
+ * Erase one sector of flash memory at offset ``offset'' which is any
+ * address within the sector which should be erased.
+ *
+ * Returns 0 if successful, non-zero otherwise.
+ */
+static int erase_sector(u32 offset)
+{
+	spi_regs_t *spi = flash->spi;
+	unsigned char *addr = (unsigned char *)&offset;
+
+	pr_debug("%s: %s %dKiB at 0x%08x\n",
+			"spi-flash", __func__,
+			flash->mtd.erasesize / 1024, offset);
+
+	spi_write(spi, ssienr, 0x0         );
+	spi_write(spi, ctrlr0, 0x107       );
+	spi_write(spi, ssienr, 0x1         );
+	spi_write(spi, dr,     OPCODE_WREN );
+	while ((spi_read(spi, sr) & 0x5) != 0x4);
+
+	spi_write(spi, ssienr, 0x0         );
+	spi_write(spi, ctrlr0, 0x1c7       );
+	spi_write(spi, baudr,  DEF_R_SPEED );
+	spi_write(spi, ssienr, 0x1         );
+
+	spi_write(spi, dr,     OPCODE_SE   );
+	spi_write(spi, dr,     addr[2]     );
+	spi_write(spi, dr,     addr[1]     );
+	spi_write(spi, dr,     addr[0]     );
+	while ((spi_read(spi, sr) & 0x5) != 0x4);
+
+	wait_for_finished();
+
+	return 0;
+}
+
+/****************************************************************************/
+
+/*
+ * MTD implementation
+ */
+
+/*
+ * Erase an address range on the flash chip.  The address range may extend
+ * one or more erase sectors.  Return an error is there is a problem erasing.
+ */
+static int s25f_erase(struct mtd_info *mtd, struct erase_info *instr)
+{
+	u32 addr,len;
+	uint32_t rem;
+
+	pr_debug("%s: %s %s 0x%llx, len %lld\n",
+	      "spi-flash", __func__, "at",
+	      (long long)instr->addr, (long long)instr->len);
+
+	/* sanity checks */
+	if (instr->addr + instr->len > flash->mtd.size)
+		return -EINVAL;
+
+	div_u64_rem(instr->len, mtd->erasesize, &rem);
+	if (rem)
+		return -EINVAL;
+
+	addr = instr->addr;
+	len = instr->len;
+
+	mutex_lock(&flash->lock);
+
+	/* whole-chip erase? */
+	if (len == flash->mtd.size) {
+		if (erase_chip()) {
+			instr->state = MTD_ERASE_FAILED;
+			mutex_unlock(&flash->lock);
+			return -EIO;
+		}
+
+	/* REVISIT in some cases we could speed up erasing large regions
+	 * by using OPCODE_SE instead of OPCODE_BE_4K.  We may have set up
+	 * to use "small sector erase", but that's not always optimal.
+	 */
+
+	/* "sector"-at-a-time erase */
+	} else {
+		while (len) {
+			if (erase_sector(addr)) {
+				instr->state = MTD_ERASE_FAILED;
+				mutex_unlock(&flash->lock);
+				return -EIO;
+			}
+
+			addr += mtd->erasesize;
+			len -= mtd->erasesize;
+		}
+	}
+
+	mutex_unlock(&flash->lock);
+
+	instr->state = MTD_ERASE_DONE;
+	mtd_erase_callback(instr);
+
+	return 0;
+}
+
+/*
+ * Read an address range from the flash chip.  The address range
+ * may be any size provided it is within the physical boundaries.
+ */
+static int s25f_read(struct mtd_info *mtd, loff_t from, size_t len,
+	size_t *retlen, u_char *buf)
+{
+	u_char *tbuf = buf;
+	size_t remain = len;
+	loff_t caddr = from;
+
+	int size;
+	int ret_cnt;
+
+	pr_debug("%s: %s %s 0x%08x, len %zd\n",
+			"spi-flash", __func__, "from",
+			(u32)from, len);
+
+	/* sanity checks */
+	if (!len)
+		return 0;
+
+	if (from + len > flash->mtd.size)
+		return -EINVAL;
+
+	/* Byte count starts at zero. */
+	if (retlen)
+		*retlen = 0;
+
+	mutex_lock(&flash->lock);
+
+	while (remain > 0) {
+		size = (remain >= RD_SZ) ? RD_SZ : remain;
+
+		ret_cnt = flash_read(caddr, tbuf, size);
+		if (ret_cnt != size) {
+			printk("SPI FLASH Read ERROR!!! Continue\n");
+			continue;
+		}
+
+		caddr  += size;
+		tbuf   += size;
+		remain -= size;
+	}
+
+	*retlen = len - remain;
+
+	mutex_unlock(&flash->lock);
+
+	return 0;
+}
+
+/*
+ * Write an address range to the flash chip.  Data must be written in
+ * FLASH_PAGESIZE chunks.  The address range may be any size provided
+ * it is within the physical boundaries.
+ */
+static int s25f_write(struct mtd_info *mtd, loff_t to, size_t len,
+	size_t *retlen, const u_char *buf)
+{
+	u32 page_offset, page_size;
+	int ret_cnt;
+
+	pr_debug("%s: %s %s 0x%08x, len %zd\n",
+			"spi-flash", __func__, "to",
+			(u32)to, len);
+
+	if (retlen)
+		*retlen = 0;
+
+	/* sanity checks */
+	if (!len)
+		return(0);
+
+	if (to + len > flash->mtd.size)
+		return -EINVAL;
+
+	mutex_lock(&flash->lock);
+
+	/* what page do we start with? */
+	page_offset = to % FLASH_PAGESIZE;
+
+	/* do all the bytes fit onto one page? */
+	if (page_offset + len <= FLASH_PAGESIZE) {
+
+		ret_cnt = flash_write(to, buf, len);
+		*retlen = ret_cnt;
+	} else {
+		u32 i;
+
+		/* the size of data remaining on the first page */
+		page_size = FLASH_PAGESIZE - page_offset;
+
+		ret_cnt = flash_write(to, buf, page_size);
+		*retlen = ret_cnt;
+
+		/* write everything in PAGESIZE chunks */
+		for (i = page_size; i < len; i += page_size) {
+			page_size = len - i;
+			if (page_size > FLASH_PAGESIZE)
+				page_size = FLASH_PAGESIZE;
+
+			/* write the next page to flash */
+				ret_cnt = flash_write((to+i), (buf+i), page_size);
+
+			if (retlen)
+				*retlen += ret_cnt;
+		}
+	}
+
+	mutex_unlock(&flash->lock);
+
+	return 0;
+}
+
+/****************************************************************************/
+/*
+ * SPI device driver setup and teardown
+ */
+
+struct flash_info {
+	char     *name;
+
+	/* JEDEC id zero means "no ID" (most older chips); otherwise it has
+	 * a high byte of zero plus three data bytes: the manufacturer id,
+	 * then a two byte device id.
+	 */
+	u32       jedec_id;
+	u16       ext_id;
+
+	/* The size listed here is what works with OPCODE_SE, which isn't
+	 * necessarily called a "sector" by the vendor.
+	 */
+	unsigned  sector_size;
+	u16       n_sectors;
+
+	u16       flags;
+#define	SECT_4K		0x01		/* OPCODE_BE_4K works uniformly */
+};
+
+/* NOTE: double check command sets and memory organization when you add
+ * more flash chips.  This current list focusses on newer chips, which
+ * have been converging on command sets which including JEDEC ID.
+ */
+static struct flash_info __devinitdata s25f_data [] = {
+	/* Atmel -- some are (confusingly) marketed as "DataFlash" */
+	{ "at25fs010" , 0x1f6601, 0, 32 * 1024, 4  , SECT_4K },
+	{ "at25fs040" , 0x1f6604, 0, 64 * 1024, 8  , SECT_4K },
+
+	{ "at25df041a", 0x1f4401, 0, 64 * 1024, 8  , SECT_4K },
+	{ "at25df641" , 0x1f4800, 0, 64 * 1024, 128, SECT_4K },
+
+	{ "at26f004"  , 0x1f0400, 0, 64 * 1024, 8  , SECT_4K },
+	{ "at26df081a", 0x1f4501, 0, 64 * 1024, 16 , SECT_4K },
+	{ "at26df161a", 0x1f4601, 0, 64 * 1024, 32 , SECT_4K },
+	{ "at26df321" , 0x1f4700, 0, 64 * 1024, 64 , SECT_4K },
+
+	/* EON -- en25xxx */
+	{ "en25f32", 0x1c3116, 0, 64 * 1024, 64 , SECT_4K },
+	{ "en25p32", 0x1c2016, 0, 64 * 1024, 64 , 0 }      ,
+	{ "en25p64", 0x1c2017, 0, 64 * 1024, 128, 0 }      ,
+
+	/* Intel/Numonyx -- xxxs33b */
+	{ "160s33b",  0x898911, 0, 64 * 1024,  32, 0 },
+	{ "320s33b",  0x898912, 0, 64 * 1024,  64, 0 },
+	{ "640s33b",  0x898913, 0, 64 * 1024, 128, 0 },
+
+	/* Macronix */
+        { "mx25l512e",   0xc22010, 0,  4 * 1024,  16, SECT_4K },
+	{ "mx25l4005a",  0xc22013, 0, 64 * 1024,   8, SECT_4K },
+	{ "mx25l8005",   0xc22014, 0, 64 * 1024,  16, 0 },
+	{ "mx25l1606e",  0xc22015, 0, 64 * 1024,  32, SECT_4K },
+	{ "mx25l3205d",  0xc22016, 0, 64 * 1024,  64, 0 },
+	{ "mx25l6405d",  0xc22017, 0, 64 * 1024, 128, SECT_4K },
+	{ "mx25l6445e",  0xc22017, 0, 64 * 1024, 128, SECT_4K },
+	{ "mx25l12805d", 0xc22018, 0, 64 * 1024, 256, 0 },
+	{ "mx25l12855e", 0xc22618, 0, 64 * 1024, 256, 0 },
+	{ "mx25l25635e", 0xc22019, 0, 64 * 1024, 512, 0 },
+	{ "mx25l25655e", 0xc22619, 0, 64 * 1024, 512, 0 },
+
+	/* Spansion -- single (large) sector size only, at least
+	 * for the chips listed here (without boot sectors).
+	 */
+	{ "s25sl004a",  0x010212,      0,  64 * 1024,   8, 0 },
+	{ "s25sl008a",  0x010213,      0,  64 * 1024,  16, 0 },
+	{ "s25sl016a",  0x010214,      0,  64 * 1024,  32, 0 },
+	{ "s25sl032a",  0x010215,      0,  64 * 1024,  64, 0 },
+	{ "s25sl032p",  0x010215, 0x4d00,  64 * 1024,  64, SECT_4K },
+	{ "s25sl064a",  0x010216,      0,  64 * 1024, 128, 0 },
+	{ "s25fl256s0", 0x010219, 0x4d00, 256 * 1024, 128, 0 },
+	{ "s25fl256s1", 0x010219, 0x4d01,  64 * 1024, 512, 0 },
+	{ "s25fl512s",  0x010220, 0x4d00, 256 * 1024, 256, 0 },
+	{ "s70fl01gs",  0x010221, 0x4d00, 256 * 1024, 256, 0 },
+	{ "s25sl12800", 0x012018, 0x0300, 256 * 1024,  64, 0 },
+	{ "s25sl12801", 0x012018, 0x0301,  64 * 1024, 256, 0 },
+	{ "s25fl129p0", 0x012018, 0x4d00, 256 * 1024,  64, 0 },
+	{ "s25fl129p1", 0x012018, 0x4d01,  64 * 1024, 256, 0 },
+	{ "s25fl016k",  0xef4015,      0,  64 * 1024,  32, SECT_4K },
+	{ "s25fl064k",  0xef4017,      0,  64 * 1024, 128, SECT_4K },
+
+	/* SST -- large erase sizes are "overlays", "sectors" are 4K */
+	{ "sst25vf040b", 0xbf258d, 0, 64 * 1024,  8, SECT_4K },
+	{ "sst25vf080b", 0xbf258e, 0, 64 * 1024, 16, SECT_4K },
+	{ "sst25vf016b", 0xbf2541, 0, 64 * 1024, 32, SECT_4K },
+	{ "sst25vf032b", 0xbf254a, 0, 64 * 1024, 64, SECT_4K },
+	{ "sst25wf512",  0xbf2501, 0, 64 * 1024,  1, SECT_4K },
+	{ "sst25wf010",  0xbf2502, 0, 64 * 1024,  2, SECT_4K },
+	{ "sst25wf020",  0xbf2503, 0, 64 * 1024,  4, SECT_4K },
+	{ "sst25wf040",  0xbf2504, 0, 64 * 1024,  8, SECT_4K },
+
+	/* ST Microelectronics -- newer production may have feature updates */
+	{ "m25p05",  0x202010,  0,  32 * 1024,   2, 0 },
+	{ "m25p10",  0x202011,  0,  32 * 1024,   4, 0 },
+	{ "m25p20",  0x202012,  0,  64 * 1024,   4, 0 },
+	{ "m25p40",  0x202013,  0,  64 * 1024,   8, 0 },
+	{ "m25p80",  0x202014,  0,  64 * 1024,  16, 0 },
+	{ "m25p16",  0x202015,  0,  64 * 1024,  32, 0 },
+	{ "m25p32",  0x202016,  0,  64 * 1024,  64, 0 },
+	{ "m25p64",  0x202017,  0,  64 * 1024, 128, 0 },
+	{ "m25p128", 0x202018,  0, 256 * 1024,  64, 0 },
+
+	{ "m25p05-nonjedec",  0, 0,  32 * 1024,   2, 0 },
+	{ "m25p10-nonjedec",  0, 0,  32 * 1024,   4, 0 },
+	{ "m25p20-nonjedec",  0, 0,  64 * 1024,   4, 0 },
+	{ "m25p40-nonjedec",  0, 0,  64 * 1024,   8, 0 },
+	{ "m25p80-nonjedec",  0, 0,  64 * 1024,  16, 0 },
+	{ "m25p16-nonjedec",  0, 0,  64 * 1024,  32, 0 },
+	{ "m25p32-nonjedec",  0, 0,  64 * 1024,  64, 0 },
+	{ "m25p64-nonjedec",  0, 0,  64 * 1024, 128, 0 },
+	{ "m25p128-nonjedec", 0, 0, 256 * 1024,  64, 0 },
+
+	{ "m45pe10", 0x204011,  0, 64 * 1024,    2, 0 },
+	{ "m45pe80", 0x204014,  0, 64 * 1024,   16, 0 },
+	{ "m45pe16", 0x204015,  0, 64 * 1024,   32, 0 },
+
+	{ "m25pe80", 0x208014,  0, 64 * 1024, 16,       0 },
+	{ "m25pe16", 0x208015,  0, 64 * 1024, 32, SECT_4K },
+
+	{ "m25px32",    0x207116,  0, 64 * 1024, 64, SECT_4K },
+	{ "m25px32-s0", 0x207316,  0, 64 * 1024, 64, SECT_4K },
+	{ "m25px32-s1", 0x206316,  0, 64 * 1024, 64, SECT_4K },
+	{ "m25px64",    0x207117,  0, 64 * 1024, 128, 0 },
+
+	/* Winbond -- w25x "blocks" are 64K, "sectors" are 4KiB */
+	{ "w25x10", 0xef3011, 0, 64 * 1024,  2,  SECT_4K },
+	{ "w25x20", 0xef3012, 0, 64 * 1024,  4,  SECT_4K },
+	{ "w25x40", 0xef3013, 0, 64 * 1024,  8,  SECT_4K },
+	{ "w25x80", 0xef3014, 0, 64 * 1024,  16, SECT_4K },
+	{ "w25x16", 0xef3015, 0, 64 * 1024,  32, SECT_4K },
+	{ "w25x32", 0xef3016, 0, 64 * 1024,  64, SECT_4K },
+	{ "w25q80", 0xef4014, 0, 64 * 1024,  16, SECT_4K },
+	{ "w25q16", 0xef4015, 0, 64 * 1024,  32, SECT_4K },
+	{ "w25q32", 0xef4016, 0, 64 * 1024,  64, SECT_4K },
+	{ "w25x64", 0xef3017, 0, 64 * 1024, 128, SECT_4K },
+	{ "w25q64", 0xef4017, 0, 64 * 1024, 128, SECT_4K },
+	{ "w25q64bv", 0xef4017 , 0, 64 * 1024 , 128, SECT_4K },
+	{ "w25q64-DIP8", 0x00ef4014, 0, 64 * 1024 , 128, SECT_4K },
+	{ "s25fl008a", 0x1c2017, 0, 64 * 1024, 128, },
+	{ "q0bb02b", 0x1c3017, 0, 64 * 1024, 128, },
+	{ "GD25Q80", 0xc84014, 0, 64 * 1024, 128, SECT_4K },
+};
+
+static int get_manufacture_id(unsigned char *buf, int size)
+{
+	spi_regs_t *spi = flash->spi;
+
+	spi_write(spi, ssienr, 0x0);
+	spi_write(spi, ctrlr0, 0x3c7);
+	spi_write(spi, ctrlr1, 0x4);
+	spi_write(spi, ssienr, 0x1);
+
+	spi_write(spi, dr, OPCODE_RDID);
+	while (spi_read(spi, rxflr) < 5);
+
+	*buf++ = spi_read(spi, dr);
+	*buf++ = spi_read(spi, dr);
+	*buf++ = spi_read(spi, dr);
+	*buf++ = spi_read(spi, dr);
+	*buf++ = spi_read(spi, dr);
+
+	return 0;
+}
+
+static struct flash_info *__devinit jedec_probe(void)
+{
+	int                tmp;
+	u8                 id[5];
+	u32                jedec;
+	u16                ext_jedec;
+	struct flash_info *info;
+
+	/* JEDEC also defines an optional "extended device information"
+	 * string for after vendor-specific data, after the three bytes
+	 * we use here.  Supporting some chips might require using it.
+	 */
+	tmp = get_manufacture_id(id, 5);
+	if (tmp < 0) {
+		pr_debug("%s: error %d reading JEDEC ID\n",
+			"spi-flash", tmp);
+		return NULL;
+	}
+	jedec = id[0];
+	jedec = jedec << 8;
+	jedec |= id[1];
+	jedec = jedec << 8;
+	jedec |= id[2];
+
+	ext_jedec = id[3] << 8 | id[4];
+
+ComingFromDefault:
+
+	for (tmp = 0, info = s25f_data; tmp < ARRAY_SIZE(s25f_data); tmp++, info++)
+    {
+		if (info->jedec_id == jedec)
+        {
+			if (info->ext_id != 0 && info->ext_id != ext_jedec)
+            {
+    			continue;
+            }
+			return info;
+		}
+	}
+	pr_debug("unrecognized JEDEC id %06x\n", jedec);
+
+    info=NULL;
+    jedec = 0x00ef4014 ;
+    ext_jedec = 0;
+    goto ComingFromDefault;
+
+	return info;
+}
+
+/***************************************************************************************************/
+
+#define NB_OF(x) (sizeof (x) / sizeof (x[0]))
+
+static struct mtd_erase_region_info erase_regions[] = {
+	/* parameter blocks */
+	{
+		.offset		= 0x00000000,
+		.erasesize	= 4 * 1024,
+		.numblocks	= 2,
+	},
+	/* main blocks */
+	{
+		.offset	 	= 0x00002000,
+		.erasesize	= 8 * 1024,
+		.numblocks	= 1,
+	},
+	{
+		.offset	 	= 0x00004000,
+		.erasesize	= 16 * 1024,
+		.numblocks	= 1,
+	},
+	{
+		.offset	 	= 0x00008000,
+		.erasesize	= 32 * 1024,
+		.numblocks	= 1,
+	},
+	{
+		.offset	 	= 0x00010000,
+		.erasesize	= 64 * 1024,
+		.numblocks	= 127,
+	}
+};
+
+//#ifdef CONFIG_MTD_PARTITIONS
+/*
+ * Define static partitions for flash device
+ */
+#define NUM_PARTITIONS 3
+static struct mtd_partition spi_partition_info[] = {
+    { .name   = "uboot",
+      .offset = 0x0,
+      .size   = 0xe0000 },
+
+    { .name   = "uboot-env",
+      .offset = 0xe0000,
+      .size   = 0x10000 },
+
+    { .name   = "spi spare",
+      .offset = 0xf0000,
+      .size   = 0x10000 }
+};
+//#endif
+
+#if 0
+static void do_dma_tasklet(unsigned long data)
+{
+	struct s25f *flash = (struct s25f *)data;
+/*    spi_regs_t * spi   = flash->spi;*/
+	dma_regs_t * dma   = flash->dma;
+
+	u32 status_block;
+	u32 status_xfer;
+	u32 status_err;
+
+	status_block = dma_readl(dma, RAW.BLOCK);
+	status_xfer  = dma_readl(dma, RAW.XFER);
+	status_err   = dma_readl(dma, RAW.ERROR);
+
+	printk("tasklet: status_block=%x status_err=%x\n",
+			status_block, status_err);
+
+	spin_lock(&flash->slock);
+
+	if (status_block) {
+		printk("block finished!\n");
+		write_enable();
+	} else if (status_xfer) {
+		printk("transfer finished!\n");
+/*        wake_up_interruptible();*/
+	} else if (status_err)
+		printk("XXXXXXXXXXXXXXX   SPI DMA TRANSFER ERROR!\n");
+
+	spin_unlock(&flash->slock);
+
+	/*
+	 * Re-enable interrupts. Block Complete interrupts are only
+	 * enabled if the INT_EN bit in the descriptor is set. This
+	 * will trigger a scan before the whole list is done.
+	 */
+}
+
+static irqreturn_t do_spi_irq(int irq, void *dev_id)
+{
+	u32 status;
+	u32 dma_cfg;
+	struct s25f *flash = dev_id;
+	spi_regs_t * spi = flash->spi;
+	dma_regs_t * dma = flash->dma;
+
+	printk("interrupt: status=0x%x\n", dma_readl(dma, STATUS_INT));
+
+	channel_clear_bit(dma, MASK.XFER,  1);
+	channel_clear_bit(dma, MASK.BLOCK, 1);
+	channel_clear_bit(dma, MASK.ERROR, 1);
+
+	status = dma_readl(dma, STATUS_INT);
+	if (status)
+		printk( "BUG: Unexpected interrupts pending: 0x%x\n", status);
+
+	u32 status_block;
+	u32 status_xfer;
+	u32 status_err;
+
+	status_block = dma_readl(dma, RAW.BLOCK);
+	status_xfer  = dma_readl(dma, RAW.XFER);
+	status_err   = dma_readl(dma, RAW.ERROR);
+
+	printk("tasklet: status_block=%x status_err=%x\n",
+			status_block, status_err);
+
+	if (status_block) {
+		printk("block finished!\n");
+		dma_cfg = dma_readl(dma, CHAN[0].CFG_LO);
+		dma_writel(dma, CHAN[0].CFG_LO, dma_cfg&(1<<8));
+		write_enable();
+		dma_writel(dma, CHAN[0].CFG_LO, dma_cfg);
+	}
+	else if (status_xfer) {
+		printk("transfer finished!\n");
+/*        wake_up_interruptible();*/
+	}
+	else if (status_err)
+		printk("XXXXXXXXXXXXXXX   SPI DMA TRANSFER ERROR!\n");
+
+	channel_set_bit(dma, MASK.XFER, 1);
+	channel_set_bit(dma, MASK.BLOCK, 1);
+	channel_set_bit(dma, MASK.ERROR, 1);
+
+	return IRQ_HANDLED;
+}
+#endif
+
+/*
+ * board specific setup should have ensured the SPI clock used here
+ * matches what the READ command supports, at least until this driver
+ * understands FAST_READ (for clocks over 25 MHz).
+ */
+
+static int spi_sys_register(struct platform_device *pdev);
+static void spi_sys_unregister(struct platform_device *pdev);
+
+static int __init s25f_probe(struct platform_device *pdev)
+{
+	struct flash_info *info;
+	unsigned           i;
+	int                ret;
+
+    /*
+     * System Register.
+     */
+    if ((ret = spi_sys_register(pdev)) < 0)
+        goto out;
+
+    /*
+     * If configed for char device, then skip the mtd branch.
+     */
+    if (ret > 0)
+        return 0;
+
+	info = jedec_probe();
+	if (!info) {
+		ret = -ENODEV;
+        goto out;
+    }
+
+	/*
+	 * Atmel serial flash tend to power up
+	 * with the software protection bits set
+	 */
+
+	if (info->jedec_id >> 16 == 0x1f) {
+        /*******************
+         * write_enable(); *
+         * write_sr(0);    *
+         *******************/
+		;
+	}
+
+	flash->mtd.name = "s25f";
+	flash->mtd.type = MTD_NORFLASH;
+	flash->mtd.writesize = 1;
+	flash->mtd.flags = MTD_CAP_NORFLASH;
+	flash->mtd.size = info->sector_size * info->n_sectors;
+
+	flash->mtd._erase = s25f_erase;
+	flash->mtd._read = s25f_read;
+	flash->mtd._write = s25f_write;
+
+#if 1
+	if (!strcmp(info->name, "s25fl008a")) {
+		flash->mtd.numeraseregions = NB_OF (erase_regions);
+		flash->mtd.eraseregions = erase_regions;
+	}
+#endif
+
+	/* prefer "small sector" erase if possible */
+	if (info->flags & SECT_4K) {
+		flash->erase_opcode = OPCODE_BE_4K;
+		flash->mtd.erasesize = 4096;
+	} else {
+		flash->erase_opcode = OPCODE_SE;
+		flash->mtd.erasesize = info->sector_size;
+	}
+
+	pr_debug("%s (%lld Kbytes)\n", info->name,
+			(long long)flash->mtd.size >> 10);
+
+	pr_debug("mtd .name = %s, .size = 0x%llx (%lldMiB) "
+			".erasesize = 0x%.8x (%uKiB) .numeraseregions = %d\n",
+		flash->mtd.name,
+		(long long)flash->mtd.size, (long long)(flash->mtd.size >> 20),
+		flash->mtd.erasesize, flash->mtd.erasesize / 1024,
+		flash->mtd.numeraseregions);
+
+	if (flash->mtd.numeraseregions)
+		for (i = 0; i < flash->mtd.numeraseregions; i++)
+			pr_debug("mtd.eraseregions[%d] = { .offset = 0x%llx, "
+				".erasesize = 0x%.8x (%uKiB), "
+				".numblocks = %d }\n",
+				i, (long long)flash->mtd.eraseregions[i].offset,
+				flash->mtd.eraseregions[i].erasesize,
+				flash->mtd.eraseregions[i].erasesize / 1024,
+				flash->mtd.eraseregions[i].numblocks);
+
+	return mtd_device_parse_register(&flash->mtd, NULL, NULL, spi_partition_info, NUM_PARTITIONS);
+out:
+    return ret;
+}
+
+static int __exit s25f_remove(struct platform_device *pdev)
+{
+	int status = 0;
+
+	if (flash == NULL) {
+		pr_debug("%s: flash resources already freed!\n", __func__);
+		return 0;
+	}
+
+    status = mtd_device_unregister(&flash->mtd);
+    spi_sys_unregister(pdev);
+
+	return status;
+}
+
+static struct platform_driver s25f_driver = {
+	.driver = {
+		.name	= "cnc18xx_spi",
+		.owner	= THIS_MODULE,
+	},
+	.remove		= __exit_p(s25f_remove),
+};
+
+static int __init s25f_init(void)
+{
+	return platform_driver_probe(&s25f_driver, s25f_probe);
+}
+
+static void __exit s25f_exit(void)
+{
+	platform_driver_unregister(&s25f_driver);
+}
+
+module_init(s25f_init);
+module_exit(s25f_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Sun He");
+MODULE_DESCRIPTION("MTD SPI driver for Winbond S25Fxxx flash chips");
+
+/* Ioctl */
+#define SPI_MAGIC      'S'
+
+#define SPI_SET_BUS    _IOW(SPI_MAGIC, 0, unsigned long)
+#define SPI_SET_CS     _IOW(SPI_MAGIC, 1, unsigned long)
+#define SPI_SET_BAUD   _IOW(SPI_MAGIC, 2, unsigned long)
+#define SPI_SET_TMOD   _IOW(SPI_MAGIC, 3, unsigned long)
+#define SPI_SET_POL    _IOW(SPI_MAGIC, 4, unsigned long)
+#define SPI_SET_PH     _IOW(SPI_MAGIC, 5, unsigned long)
+#define SPI_SET_TIMING _IOW(SPI_MAGIC, 6, unsigned long)
+#define SPI_SET_NDF    _IOW(SPI_MAGIC, 7, unsigned long)
+
+#define SPI_INTR_MASK  _IOW(SPI_MAGIC, 8, unsigned long)
+
+#define SPI_READ_BYTE  _IOW(SPI_MAGIC, 9, unsigned long)
+#define SPI_WRITE_BYTE _IOW(SPI_MAGIC, 10, unsigned long)
+
+/*
+ * Bus state choise
+ * @ enable
+ * @ disable
+ */
+typedef enum CSSPI_SPI_{
+	CSSPI_ENABLE = 0,
+	CSSPI_DISABLE } CSSPI_SPI;
+
+/*
+ * Slave select
+ * @ get cs
+ * @ drop cs
+ */
+typedef enum CSSPI_SLAVE_{
+	CSSPI_SENABLE = 0,
+	CSSPI_SDISABLE } CSSPI_SLAVE;
+
+typedef enum CSSPI_TIMING_ {
+	CSSPI_MODE0 = 0,
+	CSSPI_MODE1,
+	CSSPI_MODE2,
+	CSSPI_MODE3 } CSSPI_TIMING;
+
+/*
+ * Transfer mode
+ * @ trans and receive
+ * @ trans only
+ * @ receive only
+ * @ reservered
+ */
+typedef enum CSSPI_TMOD_ {
+	CSSPI_TXRX = 0,
+	CSSPI_TXO,
+	CSSPI_RXO,
+	CSSPI_EEPROM } CSSPI_TMOD;
+
+typedef enum CSSPI_SCPOL_ {
+	CSSPI_LOWPOL= 0,
+	CSSPI_HIGHPOL } CSSPI_SCPOL;
+
+typedef enum CSSPI_SCPH_ {
+	CSSPI_MIDDLE = 0,
+	CSSPI_START } CSSPI_SCPH;
+
+/*
+ * Baud rate
+ * @ 10MHz
+ * @ 12MHz
+ * @ 16MHz
+ * @ 23MHz
+ * @ 46MHz
+ */
+typedef enum CSSPI_SCBAUD_ {
+	CSSPI_10MH = 0xa,
+	CSSPI_12MH = 0x8,
+	CSSPI_16MH = 0x6,
+	CSSPI_23MH = 0x4,
+	CSSPI_46MH = 0x2 } CSSPI_SCBAUD;
+
+static void __spi_set_bus(CSSPI_SPI enable)
+{
+    spi_regs_t *spi = flash->spi;
+
+    spi_write(spi, ssienr, enable);
+}
+
+static void __spi_set_cs(CSSPI_SLAVE cs)
+{
+    spi_regs_t *spi = flash->spi;
+
+    /*
+     * Force minimal delay between two transfers - in case two transfers
+     * follow each other w/o delay, then we have to wait here in order for
+     * the peripheral device to detect cs transition from inactive to active.
+     */
+    spi_write(spi, ser, cs);
+
+    /* Give a wait time to ensure the state can be set */
+    udelay(1);
+}
+
+static void __spi_set_ndf(u32 ndf)
+{
+    spi_regs_t *spi = flash->spi;
+
+    spi_write(spi, ssienr, 0);
+    spi_write(spi, ctrlr1, ndf-1);
+    spi_write(spi, ssienr, 1);
+}
+
+static void __spi_set_baud(CSSPI_SCBAUD baud)
+{
+    spi_regs_t *spi = flash->spi;
+
+    spi_write(spi, ssienr, 0);
+    spi_write(spi, baudr, baud);
+    spi_write(spi, ssienr, 1);
+
+}
+
+static void __spi_set_tmod(CSSPI_TMOD tmod)
+{
+    spi_regs_t *spi = flash->spi;
+
+    u16 ctrl0 = spi_read(spi, ctrlr0);
+
+    ctrl0 &= ~(0x3<<8);
+    ctrl0 |= tmod << 8;
+
+    spi_write(spi, ssienr, 0);
+    spi_write(spi, ctrlr0, ctrl0);
+    spi_write(spi, ssienr, 1);
+}
+
+static void __spi_set_timing(CSSPI_TIMING mode)
+{
+    spi_regs_t *spi = flash->spi;
+
+    u16 ctrl0 = spi_read(spi, ctrlr0);
+
+    ctrl0 &= ~(0x3 << 6);
+    ctrl0 |= mode << 6;
+
+    spi_write(spi, ssienr, 0);
+    spi_write(spi, ctrlr0, ctrl0);
+    spi_write(spi, ssienr, 1);
+}
+
+/*
+ * The following two interface is used mainly for convenience
+ * for userspace
+ */
+static void __spi_set_phase(CSSPI_SCPH phase)
+{
+    spi_regs_t *spi = flash->spi;
+
+    u16 ctrl0 = spi_read(spi, ctrlr0);
+
+    ctrl0 &= ~(0x1 << 6);
+    ctrl0 |= (phase << 6);
+
+    spi_write(spi, ssienr, 0);
+    spi_write(spi, ctrlr0, ctrl0);
+    spi_write(spi, ssienr, 1);
+}
+
+static void __spi_set_polarity(CSSPI_SCPOL pol)
+{
+    spi_regs_t *spi = flash->spi;
+
+    u16 ctrl0 = spi_read(spi, ctrlr0);
+
+    ctrl0 &= ~(0x1 << 7);
+    ctrl0 |= (pol << 7);
+
+    spi_write(spi, ssienr, 0);
+    spi_write(spi, ctrlr0, ctrl0);
+    spi_write(spi, ssienr, 1);
+}
+
+static void __spi_intr_mask(u16 m)
+{
+    spi_regs_t *spi = flash->spi;
+
+    spi_write(spi, imr, m);
+}
+
+static int
+__proc_write(struct file *file, const char *buffer, unsigned long count, void *data)
+{
+	spi_regs_t *spi = flash->spi;
+
+    u32 addr;
+    u32 val;
+
+    if (strncmp("rw", buffer, 2) == 0) {
+        addr = simple_strtoul(&buffer[3], NULL, 16);
+        val = ioread16((unsigned char *)spi + addr);
+        printk(" readw [0x%04x] = 0x%08x \n", addr, val);
+    } else if (strncmp("ww", buffer, 2) == 0) {
+        addr = simple_strtoul(&buffer[3], NULL, 16);
+        val = simple_strtoul(&buffer[7], NULL, 16);
+        iowrite16((u16)val, (unsigned char *)spi + addr);
+        printk(" writew [0x%04x] = 0x%08x \n", addr, val);
+    }
+
+    return count;
+}
+
+static void do_dma_tasklet(unsigned long data)
+{
+}
+
+static irqreturn_t do_spi_irq(int irq, void *dev_id)
+{
+/*    spi_regs_t * spi = flash->spi;*/
+/*    dma_regs_t * dma = flash->dma;*/
+
+	return IRQ_HANDLED;
+}
+
+static int
+cnc18xx_spi_open(struct inode *inode, struct file *file)
+{
+    SDEBUG("cnc18xx spi device opened!\n");
+
+	nonseekable_open(inode, file);
+
+/*    file->private_data = (void *)spi;*/
+/*    cnc18xx_spi_t *spi = (cnc18xx_spi_t *)file->private_data;*/
+
+    return 0;
+}
+
+static int
+cnc18xx_spi_release(struct inode *inode, struct file *file)
+{
+    SDEBUG("Spi device closed!\n");
+
+    return 0;
+}
+
+static ssize_t
+cnc18xx_spi_read(struct file *file, char __user * buffer, size_t len, loff_t * f_pos)
+{
+/*    cnc18xx_spi_t *spi = (cnc18xx_spi_t *)file->private_data;*/
+
+/*    if (len > 4096) {*/
+/*        SDEBUG("%s: Read len should be less than 4096 (%d)!  \n", __func__, len);*/
+/*        return -EINVAL;*/
+/*    }*/
+
+/*    mutex_lock(&spi->q_sem);*/
+
+/*    do_dma_rx(spi->dma_buf, len);*/
+
+/*    if (!wait_event_interruptible_timeout(spi->wqueue, spi->dma_finished, 10*HZ)) {*/
+/*        SDEBUG("SPI read timeout! \n");*/
+/*        return -ETIME; */
+/*    }*/
+
+/*    if (unlikely(copy_to_user(buffer, spi->dma_buf, len)))*/
+/*        return -EFAULT;*/
+
+/*    mutex_unlock(&spi->q_sem);*/
+
+    return len;
+}
+
+static ssize_t
+cnc18xx_spi_write(struct file *file, const char __user * buffer, size_t len, loff_t * f_pos)
+{
+/*    cnc18xx_spi_t *spi = (cnc18xx_spi_t *)file->private_data;*/
+
+/*    if (len > 4096) {*/
+/*        SDEBUG("%s: Read len should be less than 4096 (%d)!  \n", __func__, len);*/
+/*        return -EINVAL;*/
+/*    }*/
+
+/*    mutex_lock(&spi->q_sem);*/
+
+/*    if (unlikely(copy_from_user(spi->dma_buf, buffer, len)))*/
+/*        return -EFAULT;*/
+
+/*    do_dma_tx(spi->dma_buf, len);*/
+
+/*    wait_event_interruptible(spi->wqueue, spi->dma_finished);*/
+
+/*    mutex_unlock(&spi->q_sem);*/
+
+    return len;
+}
+
+static loff_t
+cnc18xx_spi_lseek(struct file *file, loff_t offset, int orig)
+{
+#if 0
+    down_read(&file->f_dentry->d_inode->i_alloc_sem);
+
+    switch (orig) {
+    case 0: /* SEEK_SET */
+        file->f_pos = offset;
+        break;
+    case 1: /* SEEK_CUR */
+        file->f_pos += offset;
+        break;
+    case 2: /* SEEK_END */
+        break;
+    default:
+        SDEBUG("No such chioce!\n");
+    }
+
+    up_read(&file->f_dentry->d_inode->i_alloc_sem);
+#endif
+    return 0;
+}
+
+static unsigned int cnc18xx_spi_poll(struct file *filp, poll_table *wait)
+{
+    return 0;
+}
+
+static int
+cnc18xx_spi_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+{
+    spi_regs_t *spi = flash->spi;
+    unsigned long flags;
+
+    switch (cmd) {
+    case SPI_SET_BUS:
+        spin_lock_irqsave(&flash->slock, flags);
+        __spi_set_bus(arg);
+        spin_unlock_irqrestore(&flash->slock, flags);
+        break;
+    case SPI_SET_CS:
+        spin_lock_irqsave(&flash->slock, flags);
+        __spi_set_cs(arg);
+        spin_unlock_irqrestore(&flash->slock, flags);
+        break;
+    case SPI_SET_BAUD:
+        spin_lock_irqsave(&flash->slock, flags);
+        __spi_set_baud(arg);
+        spin_unlock_irqrestore(&flash->slock, flags);
+        break;
+    case SPI_SET_TMOD:
+        spin_lock_irqsave(&flash->slock, flags);
+        __spi_set_tmod(arg);
+        spin_unlock_irqrestore(&flash->slock, flags);
+        break;
+    case SPI_SET_POL:
+        spin_lock_irqsave(&flash->slock, flags);
+        __spi_set_polarity(arg);
+        spin_unlock_irqrestore(&flash->slock, flags);
+        break;
+    case SPI_SET_PH:
+        spin_lock_irqsave(&flash->slock, flags);
+        __spi_set_phase(arg);
+        spin_unlock_irqrestore(&flash->slock, flags);
+        break;
+    case SPI_SET_TIMING:
+        spin_lock_irqsave(&flash->slock, flags);
+        __spi_set_timing(arg);
+        spin_unlock_irqrestore(&flash->slock, flags);
+        break;
+    case SPI_SET_NDF:
+        spin_lock_irqsave(&flash->slock, flags);
+        __spi_set_ndf(arg);
+        spin_unlock_irqrestore(&flash->slock, flags);
+        break;
+
+        /* Mask switch */
+    case SPI_INTR_MASK:
+        spin_lock_irqsave(&flash->slock, flags);
+        __spi_intr_mask(arg);
+        spin_unlock_irqrestore(&flash->slock, flags);
+        break;
+
+        /* Simple interface */
+    case SPI_READ_BYTE:
+        spin_lock_irqsave(&flash->slock, flags);
+        return spi_read(spi, dr);
+        spin_unlock_irqrestore(&flash->slock, flags);
+        break;
+    case SPI_WRITE_BYTE:
+        spin_lock_irqsave(&flash->slock, flags);
+        spi_write(spi, dr, (unsigned char)arg);
+        spin_unlock_irqrestore(&flash->slock, flags);
+        break;
+
+         /* Read Secure Area */
+    case 12:
+        mutex_lock(&flash->lock);
+        {
+            int i;
+            spi_regs_t *spi = flash->spi;
+            struct {
+                char *addr;
+                char *buf;
+                int size;
+            } *msg = arg;
+
+            spi_write(spi, ssienr, 0);
+            spi_write(spi, ctrlr0, 0x0c7);
+            spi_write(spi, baudr, 0xa);
+            spi_write(spi, ssienr, 1);
+
+            /* ENSA */
+            spi_write(spi, dr, 0xb1);
+            udelay(1000);
+
+            /* Write read command */
+            spi_write(spi, dr, 0x3);
+            /* Write addr */
+            spi_write(spi, dr, msg->addr[2]);
+            spi_write(spi, dr, msg->addr[1]);
+            spi_write(spi, dr, msg->addr[0]);
+
+            #define DUMMY_CMD_SIZE 5
+            for (i = 0; i < DUMMY_CMD_SIZE; i++) {
+                spi_write(spi, dr, 0x0);
+                while (!spi_read(spi, rxflr));
+                spi_read(spi, dr);
+            }
+            i = 0;
+            while (i < msg->size) {
+                spi_write(spi, dr, 0x0);
+                while (!spi_read(spi, rxflr));
+                msg->buf[i++] = spi_read(spi, dr);
+            }
+
+            /* EXSA */
+            udelay(1000);
+            spi_write(spi, dr, 0xc1);
+        }
+        mutex_unlock(&flash->lock);
+
+        break;
+    default:
+        return -EINVAL;
+    }
+
+    return 0;
+}
+
+
+static struct proc_dir_entry *cnc18xx_spi_proc;
+static struct file_operations cnc18xx_spi_fops = {
+    .owner  = THIS_MODULE,
+    .open   = cnc18xx_spi_open,
+    .release= cnc18xx_spi_release,
+    .read   = cnc18xx_spi_read,
+    .write  = cnc18xx_spi_write,
+    .unlocked_ioctl  = cnc18xx_spi_ioctl,
+    .poll   = cnc18xx_spi_poll,
+    .llseek = cnc18xx_spi_lseek,
+};
+
+static struct miscdevice cnc18xx_spi_miscdev = {
+    MISC_DYNAMIC_MINOR,
+    "cnc18xx_spi",
+    &cnc18xx_spi_fops
+};
+
+static int spi_sys_register(struct platform_device *pdev)
+{
+	struct resource *r;
+    int ret = 0;
+
+	flash = kzalloc(sizeof *flash, GFP_KERNEL);
+	if (!flash) {
+		ret = -ENOMEM;
+        goto err0;
+	}
+
+	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!request_mem_region(r->start, (r->end - r->start) + 1,
+				dev_name(&pdev->dev))) {
+		ret = -EBUSY;
+        goto err1;
+	}
+	flash->spi = ioremap(r->start, (r->end - r->start) + 1);
+	flash->dma = flash->spi + DW_SPI_REG_DMA;
+
+	flash->prd =
+		dmam_alloc_coherent(&pdev->dev, DW_PRD_TBL_SZ, &flash->prd_phy, GFP_KERNEL);
+	if (!flash->prd) {
+		ret = -ENOMEM;
+        goto err2;
+    }
+	flash->dma_buf =
+		dmam_alloc_coherent(&pdev->dev, 4096, &flash->dma_buf_phy, GFP_KERNEL);
+	if (!flash->dma_buf) {
+		ret = -ENOMEM;
+        goto err3;
+    }
+
+	mutex_init(&flash->lock);
+	spin_lock_init(&flash->slock);
+
+    /* init controller */
+	controller_init(flash->spi);
+
+    #if defined(CONFIG_SPI_CHARDEV)
+    flash->chardev = 1;
+    #else
+        flash->chardev = 0;
+    #endif
+
+    if (flash->chardev) {
+        if (misc_register(&cnc18xx_spi_miscdev)) {
+            ret = -EBUSY;
+            goto err4;
+        }
+
+        cnc18xx_spi_proc = create_proc_entry("spi_io", 0, NULL);
+        if (!cnc18xx_spi_proc) {
+            ret = -EFAULT;
+            goto err5;
+        } else {
+            cnc18xx_spi_proc->write_proc = &__proc_write;
+        }
+
+        flash->irq = platform_get_irq(pdev, 0);
+        if (flash->irq < 0) {
+            ret = flash->irq;
+            goto err6;
+        }
+
+#if 0
+        request_irq(flash->irq, do_spi_irq, 0, dev_name(&pdev->dev), flash);
+        tasklet_init(&flash->tasklet, do_dma_tasklet, (unsigned long)flash);
+        init_waitqueue_head(&flash->queue);
+
+        /* Tell probe to skip mtd branch */
+        ret = 1;
+#endif
+    }
+
+    goto out;
+    goto err7;
+
+err7:
+    tasklet_kill(&flash->tasklet);
+	free_irq(flash->irq, flash);
+err6:
+    remove_proc_entry("spi_io", NULL);
+err5:
+    misc_deregister(&cnc18xx_spi_miscdev);
+err4:
+    dmam_free_coherent(&pdev->dev, 4096, &flash->dma_buf_phy, GFP_KERNEL);
+err3:
+    dmam_free_coherent(&pdev->dev, DW_PRD_TBL_SZ, &flash->prd_phy, GFP_KERNEL);
+err2:
+	iounmap((void *)flash->spi);
+	release_mem_region(r->start, (r->end - r->start) + 1);
+err1:
+    kfree(flash); flash = NULL;
+
+err0:
+out:
+    return ret;
+}
+
+static void spi_sys_unregister(struct platform_device *pdev)
+{
+	struct resource *r;
+
+    if (flash->chardev) {
+        tasklet_kill(&flash->tasklet);
+        free_irq(flash->irq, flash);
+        remove_proc_entry("spi_io", NULL);
+        misc_deregister(&cnc18xx_spi_miscdev);
+    }
+
+    dmam_free_coherent(&pdev->dev, 4096, &flash->dma_buf_phy, GFP_KERNEL);
+    dmam_free_coherent(&pdev->dev, DW_PRD_TBL_SZ, &flash->prd_phy, GFP_KERNEL);
+
+	iounmap((void *)flash->spi);
+	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	release_mem_region(r->start, (r->end - r->start) + 1);
+
+    kfree(flash); flash = NULL;
+}
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/mtd/Kconfig linux-linaro-3.4-2012.05-1_cavium/drivers/mtd/Kconfig
--- linux-linaro-3.4-2012.05-1_original/drivers/mtd/Kconfig	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/mtd/Kconfig	2014-10-23 20:22:19.978715000 +0800
@@ -74,7 +74,7 @@
 endif # MTD_REDBOOT_PARTS
 
 config MTD_CMDLINE_PARTS
-	bool "Command line partition table parsing"
+	tristate "Command line partition table parsing"
 	depends on MTD = "y"
 	---help---
 	  Allow generic configuration of the MTD partition tables via the kernel
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/net/loopback.c linux-linaro-3.4-2012.05-1_cavium/drivers/net/loopback.c
--- linux-linaro-3.4-2012.05-1_original/drivers/net/loopback.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/net/loopback.c	2014-07-29 17:28:38.819972000 +0800
@@ -79,6 +79,11 @@
 
 	skb->protocol = eth_type_trans(skb, dev);
 
+#ifdef CONFIG_PUREVU
+	skb->ip_summed = CHECKSUM_UNNECESSARY;
+	skb->pkt_type = PACKET_HOST;
+#endif
+
 	/* it's OK to use per_cpu_ptr() because BHs are off */
 	lb_stats = this_cpu_ptr(dev->lstats);
 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/spi/spi-dw.c linux-linaro-3.4-2012.05-1_cavium/drivers/spi/spi-dw.c
--- linux-linaro-3.4-2012.05-1_original/drivers/spi/spi-dw.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/spi/spi-dw.c	2014-07-29 17:28:38.819972000 +0800
@@ -18,6 +18,7 @@
  */
 
 #include <linux/dma-mapping.h>
+#include <linux/pm_runtime.h>
 #include <linux/interrupt.h>
 #include <linux/module.h>
 #include <linux/highmem.h>
@@ -27,6 +28,9 @@
 
 #include "spi-dw.h"
 
+#include <mach/nand.h>
+#include <mach/hardware.h>
+
 #ifdef CONFIG_DEBUG_FS
 #include <linux/debugfs.h>
 #endif
@@ -62,6 +66,28 @@
 	void (*cs_control)(u32 command);
 };
 
+static void cnc_spi_cs_control(u32 cmd)
+{
+	static void __iomem *regs = NULL;
+	u32 val;
+
+	if (!regs)
+		regs = ioremap_nocache(CNC1900_SMC, SZ_4K);
+
+	val = __raw_readl(regs + 0x0C);
+
+	switch (cmd) {
+	case MRST_SPI_ASSERT:
+		__raw_writel(val | FORCE_CE_LOW, regs + 0x0C);
+		break;
+	case MRST_SPI_DEASSERT:
+		__raw_writel(val & ~FORCE_CE_LOW, regs + 0x0C);
+		break;
+	default:
+		break;
+	}
+}
+
 #ifdef CONFIG_DEBUG_FS
 #define SPI_REGS_BUFSIZE	1024
 static ssize_t  spi_show_regs(struct file *file, char __user *user_buf,
@@ -158,31 +184,23 @@
 /* Return the max entries we can fill into tx fifo */
 static inline u32 tx_max(struct dw_spi *dws)
 {
-	u32 tx_left, tx_room, rxtx_gap;
+	u32 tx_left, tx_room;
 
-	tx_left = (dws->tx_end - dws->tx) / dws->n_bytes;
+	tx_left = ((dws->tx0_end - dws->tx0) + (dws->tx1_end - dws->tx1))
+			/ dws->cur_chip->n_bytes;
 	tx_room = dws->fifo_len - dw_readw(dws, DW_SPI_TXFLR);
-
-	/*
-	 * Another concern is about the tx/rx mismatch, we
-	 * though to use (dws->fifo_len - rxflr - txflr) as
-	 * one maximum value for tx, but it doesn't cover the
-	 * data which is out of tx/rx fifo and inside the
-	 * shift registers. So a control from sw point of
-	 * view is taken.
-	 */
-	rxtx_gap =  ((dws->rx_end - dws->rx) - (dws->tx_end - dws->tx))
-			/ dws->n_bytes;
-
-	return min3(tx_left, tx_room, (u32) (dws->fifo_len - rxtx_gap));
+	return min(tx_left, tx_room);
 }
 
 /* Return the max entries we should read out of rx fifo */
 static inline u32 rx_max(struct dw_spi *dws)
 {
-	u32 rx_left = (dws->rx_end - dws->rx) / dws->n_bytes;
+	u32 rx_left, rx_room;
 
-	return min(rx_left, (u32)dw_readw(dws, DW_SPI_RXFLR));
+	rx_left = ((dws->rx0_end - dws->rx0) + (dws->rx1_end - dws->rx1))
+			/ dws->cur_chip->n_bytes;
+	rx_room = dw_readw(dws, DW_SPI_RXFLR);
+	return min(rx_left, rx_room);
 }
 
 static void dw_writer(struct dw_spi *dws)
@@ -192,14 +210,27 @@
 
 	while (max--) {
 		/* Set the tx word if the transfer's original "tx" is not null */
-		if (dws->tx_end - dws->len) {
-			if (dws->n_bytes == 1)
-				txw = *(u8 *)(dws->tx);
-			else
-				txw = *(u16 *)(dws->tx);
+		if (dws->tx0 < dws->tx0_end) {
+			if (dws->tx0_end - dws->len0) {
+				if (dws->cur_chip->n_bytes == 1)
+					txw = *(u8 *)(dws->tx0);
+				else
+					txw = *(u16 *)(dws->tx0);
+			} else
+				txw = 0;
+			dw_writew(dws, DW_SPI_DR, txw);
+			dws->tx0 += dws->cur_chip->n_bytes;
+		} else {
+			if (dws->tx1_end - dws->len1) {
+				if (dws->cur_chip->n_bytes == 1)
+					txw = *(u8 *)(dws->tx1);
+				else
+					txw = *(u16 *)(dws->tx1);
+			} else
+				txw = 0;
+			dw_writew(dws, DW_SPI_DR, txw);
+			dws->tx1 += dws->cur_chip->n_bytes;
 		}
-		dw_writew(dws, DW_SPI_DR, txw);
-		dws->tx += dws->n_bytes;
 	}
 }
 
@@ -211,139 +242,26 @@
 	while (max--) {
 		rxw = dw_readw(dws, DW_SPI_DR);
 		/* Care rx only if the transfer's original "rx" is not null */
-		if (dws->rx_end - dws->len) {
-			if (dws->n_bytes == 1)
-				*(u8 *)(dws->rx) = rxw;
-			else
-				*(u16 *)(dws->rx) = rxw;
+		if (dws->rx0 < dws->rx0_end) {
+			if (dws->rx0_end - dws->len0) {
+				if (dws->cur_chip->n_bytes == 1)
+					*(u8 *)(dws->rx0) = rxw;
+				else
+					*(u16 *)(dws->rx0) = rxw;
+			}
+			dws->rx0 += dws->cur_chip->n_bytes;
+		} else {
+			if (dws->rx1_end - dws->len1) {
+				if (dws->cur_chip->n_bytes == 1)
+					*(u8 *)(dws->rx1) = rxw;
+				else
+					*(u16 *)(dws->rx1) = rxw;
+			}
+			dws->rx1 += dws->cur_chip->n_bytes;
 		}
-		dws->rx += dws->n_bytes;
 	}
 }
 
-static void *next_transfer(struct dw_spi *dws)
-{
-	struct spi_message *msg = dws->cur_msg;
-	struct spi_transfer *trans = dws->cur_transfer;
-
-	/* Move to next transfer */
-	if (trans->transfer_list.next != &msg->transfers) {
-		dws->cur_transfer =
-			list_entry(trans->transfer_list.next,
-					struct spi_transfer,
-					transfer_list);
-		return RUNNING_STATE;
-	} else
-		return DONE_STATE;
-}
-
-/*
- * Note: first step is the protocol driver prepares
- * a dma-capable memory, and this func just need translate
- * the virt addr to physical
- */
-static int map_dma_buffers(struct dw_spi *dws)
-{
-	if (!dws->cur_msg->is_dma_mapped
-		|| !dws->dma_inited
-		|| !dws->cur_chip->enable_dma
-		|| !dws->dma_ops)
-		return 0;
-
-	if (dws->cur_transfer->tx_dma)
-		dws->tx_dma = dws->cur_transfer->tx_dma;
-
-	if (dws->cur_transfer->rx_dma)
-		dws->rx_dma = dws->cur_transfer->rx_dma;
-
-	return 1;
-}
-
-/* Caller already set message->status; dma and pio irqs are blocked */
-static void giveback(struct dw_spi *dws)
-{
-	struct spi_transfer *last_transfer;
-	unsigned long flags;
-	struct spi_message *msg;
-
-	spin_lock_irqsave(&dws->lock, flags);
-	msg = dws->cur_msg;
-	dws->cur_msg = NULL;
-	dws->cur_transfer = NULL;
-	dws->prev_chip = dws->cur_chip;
-	dws->cur_chip = NULL;
-	dws->dma_mapped = 0;
-	queue_work(dws->workqueue, &dws->pump_messages);
-	spin_unlock_irqrestore(&dws->lock, flags);
-
-	last_transfer = list_entry(msg->transfers.prev,
-					struct spi_transfer,
-					transfer_list);
-
-	if (!last_transfer->cs_change && dws->cs_control)
-		dws->cs_control(MRST_SPI_DEASSERT);
-
-	msg->state = NULL;
-	if (msg->complete)
-		msg->complete(msg->context);
-}
-
-static void int_error_stop(struct dw_spi *dws, const char *msg)
-{
-	/* Stop the hw */
-	spi_enable_chip(dws, 0);
-
-	dev_err(&dws->master->dev, "%s\n", msg);
-	dws->cur_msg->state = ERROR_STATE;
-	tasklet_schedule(&dws->pump_transfers);
-}
-
-void dw_spi_xfer_done(struct dw_spi *dws)
-{
-	/* Update total byte transferred return count actual bytes read */
-	dws->cur_msg->actual_length += dws->len;
-
-	/* Move to next transfer */
-	dws->cur_msg->state = next_transfer(dws);
-
-	/* Handle end of message */
-	if (dws->cur_msg->state == DONE_STATE) {
-		dws->cur_msg->status = 0;
-		giveback(dws);
-	} else
-		tasklet_schedule(&dws->pump_transfers);
-}
-EXPORT_SYMBOL_GPL(dw_spi_xfer_done);
-
-static irqreturn_t interrupt_transfer(struct dw_spi *dws)
-{
-	u16 irq_status = dw_readw(dws, DW_SPI_ISR);
-
-	/* Error handling */
-	if (irq_status & (SPI_INT_TXOI | SPI_INT_RXOI | SPI_INT_RXUI)) {
-		dw_readw(dws, DW_SPI_TXOICR);
-		dw_readw(dws, DW_SPI_RXOICR);
-		dw_readw(dws, DW_SPI_RXUICR);
-		int_error_stop(dws, "interrupt_transfer: fifo overrun/underrun");
-		return IRQ_HANDLED;
-	}
-
-	dw_reader(dws);
-	if (dws->rx_end == dws->rx) {
-		spi_mask_intr(dws, SPI_INT_TXEI);
-		dw_spi_xfer_done(dws);
-		return IRQ_HANDLED;
-	}
-	if (irq_status & SPI_INT_TXEI) {
-		spi_mask_intr(dws, SPI_INT_TXEI);
-		dw_writer(dws);
-		/* Enable TX irq always, it will be disabled when RX finished */
-		spi_umask_intr(dws, SPI_INT_TXEI);
-	}
-
-	return IRQ_HANDLED;
-}
-
 static irqreturn_t dw_spi_irq(int irq, void *dev_id)
 {
 	struct dw_spi *dws = dev_id;
@@ -352,12 +270,16 @@
 	if (!irq_status)
 		return IRQ_NONE;
 
-	if (!dws->cur_msg) {
-		spi_mask_intr(dws, SPI_INT_TXEI);
-		return IRQ_HANDLED;
-	}
+	if (dws->transfer_handler)
+		dws->transfer_handler(dws);
+	return IRQ_HANDLED;
+}
 
-	return dws->transfer_handler(dws);
+void dw_spi_xfer_done(struct dw_spi *dws)
+{
+	dws->cur_chip = NULL;
+	if (dws->cs_control)
+		dws->cs_control(MRST_SPI_DEASSERT);
 }
 
 /* Must be called inside pump_transfers() */
@@ -367,259 +289,76 @@
 		dw_writer(dws);
 		dw_reader(dws);
 		cpu_relax();
-	} while (dws->rx_end > dws->rx);
+	} while ((dws->rx0_end > dws->rx0) || (dws->rx1_end > dws->rx1));
 
 	dw_spi_xfer_done(dws);
 }
 
-static void pump_transfers(unsigned long data)
+static int dw_spi_prepare_transfer_hardware(struct spi_master *master)
 {
-	struct dw_spi *dws = (struct dw_spi *)data;
-	struct spi_message *message = NULL;
-	struct spi_transfer *transfer = NULL;
-	struct spi_transfer *previous = NULL;
-	struct spi_device *spi = NULL;
-	struct chip_data *chip = NULL;
-	u8 bits = 0;
-	u8 imask = 0;
-	u8 cs_change = 0;
-	u16 txint_level = 0;
-	u16 clk_div = 0;
-	u32 speed = 0;
-	u32 cr0 = 0;
-
-	/* Get current state information */
-	message = dws->cur_msg;
-	transfer = dws->cur_transfer;
-	chip = dws->cur_chip;
-	spi = message->spi;
-
-	if (unlikely(!chip->clk_div))
-		chip->clk_div = dws->max_freq / chip->speed_hz;
-
-	if (message->state == ERROR_STATE) {
-		message->status = -EIO;
-		goto early_exit;
-	}
-
-	/* Handle end of message */
-	if (message->state == DONE_STATE) {
-		message->status = 0;
-		goto early_exit;
-	}
-
-	/* Delay if requested at end of transfer*/
-	if (message->state == RUNNING_STATE) {
-		previous = list_entry(transfer->transfer_list.prev,
-					struct spi_transfer,
-					transfer_list);
-		if (previous->delay_usecs)
-			udelay(previous->delay_usecs);
-	}
-
-	dws->n_bytes = chip->n_bytes;
-	dws->dma_width = chip->dma_width;
-	dws->cs_control = chip->cs_control;
-
-	dws->rx_dma = transfer->rx_dma;
-	dws->tx_dma = transfer->tx_dma;
-	dws->tx = (void *)transfer->tx_buf;
-	dws->tx_end = dws->tx + transfer->len;
-	dws->rx = transfer->rx_buf;
-	dws->rx_end = dws->rx + transfer->len;
-	dws->cs_change = transfer->cs_change;
-	dws->len = dws->cur_transfer->len;
-	if (chip != dws->prev_chip)
-		cs_change = 1;
-
-	cr0 = chip->cr0;
-
-	/* Handle per transfer options for bpw and speed */
-	if (transfer->speed_hz) {
-		speed = chip->speed_hz;
-
-		if (transfer->speed_hz != speed) {
-			speed = transfer->speed_hz;
-			if (speed > dws->max_freq) {
-				printk(KERN_ERR "MRST SPI0: unsupported"
-					"freq: %dHz\n", speed);
-				message->status = -EIO;
-				goto early_exit;
-			}
-
-			/* clk_div doesn't support odd number */
-			clk_div = dws->max_freq / speed;
-			clk_div = (clk_div + 1) & 0xfffe;
-
-			chip->speed_hz = speed;
-			chip->clk_div = clk_div;
-		}
-	}
-	if (transfer->bits_per_word) {
-		bits = transfer->bits_per_word;
-
-		switch (bits) {
-		case 8:
-		case 16:
-			dws->n_bytes = dws->dma_width = bits >> 3;
-			break;
-		default:
-			printk(KERN_ERR "MRST SPI0: unsupported bits:"
-				"%db\n", bits);
-			message->status = -EIO;
-			goto early_exit;
-		}
-
-		cr0 = (bits - 1)
-			| (chip->type << SPI_FRF_OFFSET)
-			| (spi->mode << SPI_MODE_OFFSET)
-			| (chip->tmode << SPI_TMOD_OFFSET);
-	}
-	message->state = RUNNING_STATE;
-
-	/*
-	 * Adjust transfer mode if necessary. Requires platform dependent
-	 * chipselect mechanism.
-	 */
-	if (dws->cs_control) {
-		if (dws->rx && dws->tx)
-			chip->tmode = SPI_TMOD_TR;
-		else if (dws->rx)
-			chip->tmode = SPI_TMOD_RO;
-		else
-			chip->tmode = SPI_TMOD_TO;
-
-		cr0 &= ~SPI_TMOD_MASK;
-		cr0 |= (chip->tmode << SPI_TMOD_OFFSET);
-	}
-
-	/* Check if current transfer is a DMA transaction */
-	dws->dma_mapped = map_dma_buffers(dws);
-
-	/*
-	 * Interrupt mode
-	 * we only need set the TXEI IRQ, as TX/RX always happen syncronizely
-	 */
-	if (!dws->dma_mapped && !chip->poll_mode) {
-		int templen = dws->len / dws->n_bytes;
-		txint_level = dws->fifo_len / 2;
-		txint_level = (templen > txint_level) ? txint_level : templen;
-
-		imask |= SPI_INT_TXEI | SPI_INT_TXOI | SPI_INT_RXUI | SPI_INT_RXOI;
-		dws->transfer_handler = interrupt_transfer;
-	}
-
-	/*
-	 * Reprogram registers only if
-	 *	1. chip select changes
-	 *	2. clk_div is changed
-	 *	3. control value changes
-	 */
-	if (dw_readw(dws, DW_SPI_CTRL0) != cr0 || cs_change || clk_div || imask) {
-		spi_enable_chip(dws, 0);
-
-		if (dw_readw(dws, DW_SPI_CTRL0) != cr0)
-			dw_writew(dws, DW_SPI_CTRL0, cr0);
-
-		spi_set_clk(dws, clk_div ? clk_div : chip->clk_div);
-		spi_chip_sel(dws, spi->chip_select);
-
-		/* Set the interrupt mask, for poll mode just disable all int */
-		spi_mask_intr(dws, 0xff);
-		if (imask)
-			spi_umask_intr(dws, imask);
-		if (txint_level)
-			dw_writew(dws, DW_SPI_TXFLTR, txint_level);
-
-		spi_enable_chip(dws, 1);
-		if (cs_change)
-			dws->prev_chip = chip;
-	}
-
-	if (dws->dma_mapped)
-		dws->dma_ops->dma_transfer(dws, cs_change);
-
-	if (chip->poll_mode)
-		poll_transfer(dws);
-
-	return;
-
-early_exit:
-	giveback(dws);
-	return;
+	pm_runtime_get_sync(&master->dev);
+	return 0;
 }
 
-static void pump_messages(struct work_struct *work)
+static int dw_spi_unprepare_transfer_hardware(struct spi_master *master)
 {
-	struct dw_spi *dws =
-		container_of(work, struct dw_spi, pump_messages);
-	unsigned long flags;
-
-	/* Lock queue and check for queue work */
-	spin_lock_irqsave(&dws->lock, flags);
-	if (list_empty(&dws->queue) || dws->run == QUEUE_STOPPED) {
-		dws->busy = 0;
-		spin_unlock_irqrestore(&dws->lock, flags);
-		return;
-	}
-
-	/* Make sure we are not already running a message */
-	if (dws->cur_msg) {
-		spin_unlock_irqrestore(&dws->lock, flags);
-		return;
-	}
-
-	/* Extract head of queue */
-	dws->cur_msg = list_entry(dws->queue.next, struct spi_message, queue);
-	list_del_init(&dws->cur_msg->queue);
-
-	/* Initial message state*/
-	dws->cur_msg->state = START_STATE;
-	dws->cur_transfer = list_entry(dws->cur_msg->transfers.next,
-						struct spi_transfer,
-						transfer_list);
-	dws->cur_chip = spi_get_ctldata(dws->cur_msg->spi);
-
-	/* Mark as busy and launch transfers */
-	tasklet_schedule(&dws->pump_transfers);
-
-	dws->busy = 1;
-	spin_unlock_irqrestore(&dws->lock, flags);
+	pm_runtime_put(&master->dev);
+	return 0;
 }
 
-/* spi_device use this to queue in their spi_msg */
-static int dw_spi_transfer(struct spi_device *spi, struct spi_message *msg)
+static void poll_transfer_setup(struct dw_spi *dws, struct spi_transfer *transfer)
 {
-	struct dw_spi *dws = spi_master_get_devdata(spi->master);
-	unsigned long flags;
-
-	spin_lock_irqsave(&dws->lock, flags);
-
-	if (dws->run == QUEUE_STOPPED) {
-		spin_unlock_irqrestore(&dws->lock, flags);
-		return -ESHUTDOWN;
-	}
-
-	msg->actual_length = 0;
-	msg->status = -EINPROGRESS;
-	msg->state = START_STATE;
-
-	list_add_tail(&msg->queue, &dws->queue);
+	spi_enable_chip(dws, 0);
 
-	if (dws->run == QUEUE_RUNNING && !dws->busy) {
+	spi_set_cr0(dws, dws->cur_chip->cr0);
+	spi_set_clk(dws, dws->max_freq / dws->cur_chip->speed_hz);
+	spi_chip_sel(dws, 0);
+	spi_mask_intr(dws, 0xff);
 
-		if (dws->cur_transfer || dws->cur_msg)
-			queue_work(dws->workqueue,
-					&dws->pump_messages);
-		else {
-			/* If no other data transaction in air, just go */
-			spin_unlock_irqrestore(&dws->lock, flags);
-			pump_messages(&dws->pump_messages);
-			return 0;
-		}
-	}
+	spi_enable_chip(dws, 1);
+}
 
-	spin_unlock_irqrestore(&dws->lock, flags);
+static int dw_spi_transfer_one_message(struct spi_master *master, struct spi_message *msg)
+{
+	struct dw_spi *dws = spi_master_get_devdata(master);
+	struct chip_data *chip = spi_get_ctldata(msg->spi);
+	struct spi_transfer *transfer = 
+		list_first_entry(&msg->transfers, struct spi_transfer, transfer_list);
+
+	if (dws->cur_chip != chip) {
+		dws->cur_chip = chip;
+		poll_transfer_setup(dws, transfer);
+		if (dws->cs_control)
+			dws->cs_control(MRST_SPI_ASSERT);
+	}
+
+	dws->tx0 = (void *)transfer->tx_buf;
+	dws->tx0_end = dws->tx0 + transfer->len;
+	dws->rx0 = transfer->rx_buf;
+	dws->rx0_end = dws->rx0 + transfer->len;
+	dws->len0 = transfer->len;
+
+	if (list_is_singular(&msg->transfers)) {
+		dws->tx1 = dws->rx1 = NULL;
+		dws->tx1_end = dws->rx1_end = NULL;
+		dws->len1 = 0;
+	} else {
+		struct spi_transfer *next_transfer = 
+			list_first_entry(&transfer->transfer_list, struct spi_transfer, transfer_list);
+		dws->tx1 = (void *)next_transfer->tx_buf;
+		dws->tx1_end = dws->tx1 + next_transfer->len;
+		dws->rx1 = next_transfer->rx_buf;
+		dws->rx1_end = dws->rx1 + next_transfer->len;
+		dws->len1 = next_transfer->len;
+	}
+
+	pr_debug("T0 %p %d T1 %p %d\n", dws->tx0, dws->len0, dws->tx1, dws->len1);
+	pr_debug("R0 %p %d R1 %p %d\n", dws->rx0, dws->len0, dws->rx1, dws->len1);
+	poll_transfer(dws);
+
+	msg->status = 0;
+	msg->actual_length = dws->len0 + dws->len1;
+	spi_finalize_current_message(master);
 	return 0;
 }
 
@@ -696,81 +435,6 @@
 	kfree(chip);
 }
 
-static int __devinit init_queue(struct dw_spi *dws)
-{
-	INIT_LIST_HEAD(&dws->queue);
-	spin_lock_init(&dws->lock);
-
-	dws->run = QUEUE_STOPPED;
-	dws->busy = 0;
-
-	tasklet_init(&dws->pump_transfers,
-			pump_transfers,	(unsigned long)dws);
-
-	INIT_WORK(&dws->pump_messages, pump_messages);
-	dws->workqueue = create_singlethread_workqueue(
-					dev_name(dws->master->dev.parent));
-	if (dws->workqueue == NULL)
-		return -EBUSY;
-
-	return 0;
-}
-
-static int start_queue(struct dw_spi *dws)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&dws->lock, flags);
-
-	if (dws->run == QUEUE_RUNNING || dws->busy) {
-		spin_unlock_irqrestore(&dws->lock, flags);
-		return -EBUSY;
-	}
-
-	dws->run = QUEUE_RUNNING;
-	dws->cur_msg = NULL;
-	dws->cur_transfer = NULL;
-	dws->cur_chip = NULL;
-	dws->prev_chip = NULL;
-	spin_unlock_irqrestore(&dws->lock, flags);
-
-	queue_work(dws->workqueue, &dws->pump_messages);
-
-	return 0;
-}
-
-static int stop_queue(struct dw_spi *dws)
-{
-	unsigned long flags;
-	unsigned limit = 50;
-	int status = 0;
-
-	spin_lock_irqsave(&dws->lock, flags);
-	dws->run = QUEUE_STOPPED;
-	while ((!list_empty(&dws->queue) || dws->busy) && limit--) {
-		spin_unlock_irqrestore(&dws->lock, flags);
-		msleep(10);
-		spin_lock_irqsave(&dws->lock, flags);
-	}
-
-	if (!list_empty(&dws->queue) || dws->busy)
-		status = -EBUSY;
-	spin_unlock_irqrestore(&dws->lock, flags);
-
-	return status;
-}
-
-static int destroy_queue(struct dw_spi *dws)
-{
-	int status;
-
-	status = stop_queue(dws);
-	if (status != 0)
-		return status;
-	destroy_workqueue(dws->workqueue);
-	return 0;
-}
-
 /* Restart the controller, disable all interrupts, clean rx fifo */
 static void spi_hw_init(struct dw_spi *dws)
 {
@@ -793,6 +457,8 @@
 		dws->fifo_len = (fifo == 257) ? 0 : fifo;
 		dw_writew(dws, DW_SPI_TXFLTR, 0);
 	}
+
+	dws->fifo_len /= 2;
 }
 
 int __devinit dw_spi_add_host(struct dw_spi *dws)
@@ -810,25 +476,22 @@
 
 	dws->master = master;
 	dws->type = SSI_MOTO_SPI;
-	dws->prev_chip = NULL;
+	dws->cur_chip = NULL;
 	dws->dma_inited = 0;
 	dws->dma_addr = (dma_addr_t)(dws->paddr + 0x60);
 	snprintf(dws->name, sizeof(dws->name), "dw_spi%d",
 			dws->bus_num);
 
-	ret = request_irq(dws->irq, dw_spi_irq, IRQF_SHARED,
-			dws->name, dws);
-	if (ret < 0) {
-		dev_err(&master->dev, "can not get IRQ\n");
-		goto err_free_master;
-	}
+	dws->cs_control = cnc_spi_cs_control;
 
 	master->mode_bits = SPI_CPOL | SPI_CPHA;
 	master->bus_num = dws->bus_num;
 	master->num_chipselect = dws->num_cs;
 	master->cleanup = dw_spi_cleanup;
 	master->setup = dw_spi_setup;
-	master->transfer = dw_spi_transfer;
+	master->prepare_transfer_hardware = dw_spi_prepare_transfer_hardware;
+	master->unprepare_transfer_hardware = dw_spi_unprepare_transfer_hardware;
+	master->transfer_one_message = dw_spi_transfer_one_message;
 
 	/* Basic HW init */
 	spi_hw_init(dws);
@@ -841,18 +504,13 @@
 		}
 	}
 
-	/* Initial and start queue */
-	ret = init_queue(dws);
-	if (ret) {
-		dev_err(&master->dev, "problem initializing queue\n");
-		goto err_diable_hw;
-	}
-	ret = start_queue(dws);
-	if (ret) {
-		dev_err(&master->dev, "problem starting queue\n");
-		goto err_diable_hw;
+/*	ret = request_irq(dws->irq, dw_spi_irq, IRQF_SHARED,
+			dws->name, dws);
+	if (ret < 0) {
+		dev_err(&master->dev, "can not get IRQ\n");
+		goto err_free_master;
 	}
-
+*/
 	spi_master_set_devdata(master, dws);
 	ret = spi_register_master(master);
 	if (ret) {
@@ -864,10 +522,8 @@
 	return 0;
 
 err_queue_alloc:
-	destroy_queue(dws);
 	if (dws->dma_ops && dws->dma_ops->dma_exit)
 		dws->dma_ops->dma_exit(dws);
-err_diable_hw:
 	spi_enable_chip(dws, 0);
 	free_irq(dws->irq, dws);
 err_free_master:
@@ -879,55 +535,19 @@
 
 void __devexit dw_spi_remove_host(struct dw_spi *dws)
 {
-	int status = 0;
-
 	if (!dws)
 		return;
 	mrst_spi_debugfs_remove(dws);
 
-	/* Remove the queue */
-	status = destroy_queue(dws);
-	if (status != 0)
-		dev_err(&dws->master->dev, "dw_spi_remove: workqueue will not "
-			"complete, message memory not freed\n");
-
 	if (dws->dma_ops && dws->dma_ops->dma_exit)
 		dws->dma_ops->dma_exit(dws);
 	spi_enable_chip(dws, 0);
 	/* Disable clk */
 	spi_set_clk(dws, 0);
 	free_irq(dws->irq, dws);
-
-	/* Disconnect from the SPI framework */
-	spi_unregister_master(dws->master);
 }
 EXPORT_SYMBOL_GPL(dw_spi_remove_host);
 
-int dw_spi_suspend_host(struct dw_spi *dws)
-{
-	int ret = 0;
-
-	ret = stop_queue(dws);
-	if (ret)
-		return ret;
-	spi_enable_chip(dws, 0);
-	spi_set_clk(dws, 0);
-	return ret;
-}
-EXPORT_SYMBOL_GPL(dw_spi_suspend_host);
-
-int dw_spi_resume_host(struct dw_spi *dws)
-{
-	int ret;
-
-	spi_hw_init(dws);
-	ret = start_queue(dws);
-	if (ret)
-		dev_err(&dws->master->dev, "fail to start queue (%d)\n", ret);
-	return ret;
-}
-EXPORT_SYMBOL_GPL(dw_spi_resume_host);
-
 MODULE_AUTHOR("Feng Tang <feng.tang@intel.com>");
 MODULE_DESCRIPTION("Driver for DesignWare SPI controller core");
 MODULE_LICENSE("GPL v2");
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/spi/spi-dw.h linux-linaro-3.4-2012.05-1_cavium/drivers/spi/spi-dw.h
--- linux-linaro-3.4-2012.05-1_original/drivers/spi/spi-dw.h	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/spi/spi-dw.h	2014-07-29 17:28:38.819972000 +0800
@@ -91,7 +91,6 @@
 
 struct dw_spi {
 	struct spi_master	*master;
-	struct spi_device	*cur_dev;
 	struct device		*parent_dev;
 	enum dw_ssi_type	type;
 	char			name[16];
@@ -106,33 +105,15 @@
 	u16			bus_num;
 	u16			num_cs;		/* supported slave numbers */
 
-	/* Driver message queue */
-	struct workqueue_struct	*workqueue;
-	struct work_struct	pump_messages;
-	spinlock_t		lock;
-	struct list_head	queue;
-	int			busy;
-	int			run;
-
-	/* Message Transfer pump */
-	struct tasklet_struct	pump_transfers;
-
 	/* Current message transfer state info */
-	struct spi_message	*cur_msg;
-	struct spi_transfer	*cur_transfer;
 	struct chip_data	*cur_chip;
-	struct chip_data	*prev_chip;
-	size_t			len;
-	void			*tx;
-	void			*tx_end;
-	void			*rx;
-	void			*rx_end;
-	int			dma_mapped;
-	dma_addr_t		rx_dma;
-	dma_addr_t		tx_dma;
-	size_t			rx_map_len;
-	size_t			tx_map_len;
-	u8			n_bytes;	/* current is a 1/2 bytes op */
+
+	size_t			len0, len1;
+	void			*tx0, *tx1;
+	void			*tx0_end, *tx1_end;
+	void			*rx0, *rx1;
+	void			*rx0_end, *rx1_end;
+
 	u8			max_bits_per_word;	/* maxim is 16b */
 	u32			dma_width;
 	int			cs_change;
@@ -149,8 +130,6 @@
 	struct device		*dma_dev;
 	dma_addr_t		dma_addr; /* phy address of the Data register */
 	struct dw_spi_dma_ops	*dma_ops;
-	void			*dma_priv; /* platform relate info */
-	struct pci_dev		*dmac;
 
 	/* Bus interface info */
 	void			*priv;
@@ -184,6 +163,11 @@
 	dw_writel(dws, DW_SPI_SSIENR, (enable ? 1 : 0));
 }
 
+static inline void spi_set_cr0(struct dw_spi *dws, u32 cr0)
+{
+	dw_writel(dws, DW_SPI_CTRL0, cr0);
+}
+
 static inline void spi_set_clk(struct dw_spi *dws, u16 div)
 {
 	dw_writel(dws, DW_SPI_BAUDR, div);
@@ -197,7 +181,7 @@
 	if (dws->cs_control)
 		dws->cs_control(1);
 
-	dw_writel(dws, DW_SPI_SER, 1 << cs);
+	//dw_writel(dws, DW_SPI_SER, 1 << cs);
 }
 
 /* Disable IRQ bits */
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/staging/android/logger.c linux-linaro-3.4-2012.05-1_cavium/drivers/staging/android/logger.c
--- linux-linaro-3.4-2012.05-1_original/drivers/staging/android/logger.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/staging/android/logger.c	2014-07-29 17:28:38.819972000 +0800
@@ -729,8 +729,8 @@
 };
 
 DEFINE_LOGGER_DEVICE(log_main, LOGGER_LOG_MAIN, 256*1024)
-DEFINE_LOGGER_DEVICE(log_events, LOGGER_LOG_EVENTS, 256*1024)
-DEFINE_LOGGER_DEVICE(log_radio, LOGGER_LOG_RADIO, 256*1024)
+DEFINE_LOGGER_DEVICE(log_events, LOGGER_LOG_EVENTS, 1024)
+DEFINE_LOGGER_DEVICE(log_radio, LOGGER_LOG_RADIO, 1024)
 DEFINE_LOGGER_DEVICE(log_system, LOGGER_LOG_SYSTEM, 256*1024)
 
 static struct logger_log *get_log_from_minor(int minor)
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/staging/android/lowmemorykiller.c linux-linaro-3.4-2012.05-1_cavium/drivers/staging/android/lowmemorykiller.c
--- linux-linaro-3.4-2012.05-1_original/drivers/staging/android/lowmemorykiller.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/staging/android/lowmemorykiller.c	2014-07-29 17:28:38.819972000 +0800
@@ -45,7 +45,7 @@
 	6,
 	12,
 };
-static int lowmem_adj_size = 4;
+static int lowmem_adj_size = 2;
 static int lowmem_minfree[6] = {
 	3 * 512,	/* 6MB */
 	2 * 1024,	/* 8MB */
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/staging/Kconfig linux-linaro-3.4-2012.05-1_cavium/drivers/staging/Kconfig
--- linux-linaro-3.4-2012.05-1_original/drivers/staging/Kconfig	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/staging/Kconfig	2014-11-28 12:39:00.572447000 +0800
@@ -134,4 +134,6 @@
 
 source "drivers/staging/alc5625/Kconfig"
 
+source "drivers/staging/mausb/Kconfig"
+
 endif # STAGING
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/staging/Makefile linux-linaro-3.4-2012.05-1_cavium/drivers/staging/Makefile
--- linux-linaro-3.4-2012.05-1_original/drivers/staging/Makefile	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/staging/Makefile	2014-11-28 12:39:00.572447000 +0800
@@ -58,3 +58,4 @@
 obj-$(CONFIG_RAMSTER)		+= ramster/
 obj-$(CONFIG_USB_WPAN_HCD)	+= ozwpan/
 obj-$(CONFIG_SND_SOC_ORIGEN_ALC5625)	+= alc5625/
+obj-$(CONFIG_MAUSB) += mausb/
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/drivers/Kconfig linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/drivers/Kconfig
--- linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/drivers/Kconfig	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/drivers/Kconfig	2014-11-28 12:39:00.572447000 +0800
@@ -0,0 +1,34 @@
+config MA_CORE 
+ tristate "MA USB core" 
+ ---help--- 
+ This builds ma_core module. 
+ 
+config MAUSB_HOST 
+ tristate "MA USB host" 
+ depends on MA_CORE 
+ ---help--- 
+ This builds MA USB host driver module. 
+ 
+config MAUSB_DEVICE 
+ tristate "MA USB device" 
+ depends on MA_CORE && USB_GADGET 
+ ---help--- 
+ This builds MA USB device driver module. 
+ 
+config MATCP_CORE 
+ tristate "MA USB tcp core" 
+ ---help--- 
+ This builds tcp_core module. 
+ 
+config MATCP_HOST 
+ tristate "MA USB host tcp" 
+ depends on MATCP_CORE && MAUSB_HOST
+ ---help--- 
+ This builds tcp_host module. 
+ 
+config MATCP_DEVICE 
+ tristate "MA USB device tcp" 
+ depends on MATCP_CORE && MAUSB_DEVICE
+ ---help--- 
+ This builds tcp_dev module. 
+ 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/drivers/Makefile linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/drivers/Makefile
--- linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/drivers/Makefile	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/drivers/Makefile	2014-11-28 12:39:00.572447000 +0800
@@ -0,0 +1,18 @@
+obj-$(CONFIG_MA_CORE) += ma_core.o 
+ma_core-y := mausb_pkt.o mausb_tx.o mausb_msapi.o mausb_mem.o mausb_mgmt.o 
+ 
+obj-$(CONFIG_MAUSB_HOST) += mausb.o 
+mausb-y := mausb_hcd.o mausb_hub.o mausb_tx-host.o mausb_mem-host.o 
+ 
+obj-$(CONFIG_MAUSB_DEVICE) += maudc.o 
+maudc-y := mausb_udc.o mausb_tx-device.o 
+ 
+obj-$(CONFIG_MATCP_HOST) += matcp_host.o 
+matcp_host-y := mausb_tcp-host.o 
+ 
+obj-$(CONFIG_MATCP_DEVICE) += matcp_dev.o 
+matcp_dev-y := mausb_tcp-device.o 
+ 
+obj-$(CONFIG_MATCP_CORE) += matcp_core.o 
+matcp_core-y := mausb_tcp.o mausb_ioctl.o 
+ 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/drivers/mausb_const.h linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/drivers/mausb_const.h
--- linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/drivers/mausb_const.h	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/drivers/mausb_const.h	2014-11-28 12:39:00.572447000 +0800
@@ -0,0 +1,109 @@
+/* Name: mausb_const.h 
+ * Description: This header describes the Media Agnostic USB constants 
+ * that must be known by the both the host and device side drivers. 
+ * 
+ * This file is provided under a dual BSD/GPLv2 license. When using or 
+ * redistributing this file, you may do so under either license. 
+ * 
+ * GPL LICENSE SUMMARY 
+ * 
+ * Copyright(c) 2014 Intel Corporation. 
+ * 
+ * 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. 
+ * 
+ * Contact Information: 
+ * Sean Stalley, sean.stalley [at] intel 
+ * Stephanie Wallick, stephanie.s.wallick [at] intel 
+ * 2111 NE 25th Avenue 
+ * Hillsboro, Oregon 97124 
+ * 
+ * BSD LICENSE 
+ * 
+ * Copyright(c) 2014 Intel Corporation. 
+ * 
+ * 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 of Intel Corporation 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. 
+ */ 
+ 
+#ifndef __MAUSB_CONST_H 
+#define __MAUSB_CONST_H 
+ 
+/* MA USB protocol constants per Table 68 of the MA USB Spec */ 
+#define MAUSB_DATA_CHANNEL_DELAY 400 /* temp value */ 
+#define MAUSB_MGMT_CHANNEL_DELAY ((100 * HZ)/1000 + 1) 
+#define MAUSB_MGMT_RESPONSE_DELAY ((5 * HZ)/1000 + 1) /* 5 msec */ 
+#define MAUSB_MGMT_RT_DELAY \ 
+ ((MAUSB_MGMT_RESPONSE_DELAY + (2 * MAUSB_MGMT_CHANNEL_DELAY))) 
+#define MAUSB_TRANSFER_RESPONSE_TIME 10 /* 10 msec */ 
+#define MAUSB_TRANSFER_TIMEOUT \ 
+ (MAUSB_TRANSFER_RESPONSE_TIME + (2 * MAUSB_DATA_CHANNEL_DELAY)) 
+#define MAUSB_TRANSFER_KEEP_ALIVE \ 
+ (MAUSB_TRANSFER_RESPONSE_TIME + MAUSB_DATA_CHANNEL_DELAY) 
+#define MAUSB_DEFAULT_KEEP_ALIVE 0 
+#define MAUSB_MAX_TRANSFER_LIFETIME 1000 /* 1 sec */ 
+#define MAUSB_TRANSFER_REPEAT_TIME 10 /* 10 msec */ 
+ 
+#define MAUSB_MAX_REQ_ID ((1 << 8) - 1) 
+#define MAUSB_MAX_SEQ_NUM ((1 << 24) - 1) 
+#define MAUSB_MAX_DIALOG_TOKEN ((1 << 10) - 1) 
+#define MAUSB_MIN_CONTROL_BUF_SIZE 4104 /* Bytes */ 
+ 
+ 
+/* MA USB protocol variables per Table 69 of the MA USB Spec */ 
+#define MAUSB_BULK_TRANSFER_RETRIES 10 /* min value is 5 */ 
+#define MAUSB_CONTROL_TRANSFER_RETRIES 10 /* min value is 5 */ 
+#define MAUSB_INTERRUPT_TRANSFER_RETRIES 10 /* min value is 3 */ 
+#define MAUSB_MGMT_TRANSFER_RETRIES 4 /* min value is 4 */ 
+#define MAUSB_TRANSFER_SETUP_RETRIES 4 /* min value is 4 */ 
+ 
+ 
+/* MA USB constants not explicitly defined in MA USB Spec */ 
+#define MAUSB_HALF_REQ_ID ((MAUSB_MAX_REQ_ID + 1) >> 2) 
+#define MAUSB_HALF_SEQ_NUM ((MAUSB_MAX_SEQ_NUM + 1) >> 2) 
+#define MAUSB_MAX_OUTSTANDING_SEQ_NUM (1 << 23) 
+ 
+/* Largest packet size (in bytes) that the medium can handle */ 
+#define MAUSB_MAX_PACKET_SIZE 300 
+ 
+/* Used to parse get_status control requests */ 
+#define EP_REQ (USB_TYPE_STANDARD | USB_RECIP_ENDPOINT) 
+#define EP_IN_REQ (USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_ENDPOINT) 
+#define DEV_IN_REQ (USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE) 
+#define INTF_IN_REQ (USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_INTERFACE) 
+ 
+/* Used for generating the mass_id for the device */ 
+#define MASS_ID_MIN 1 
+#define MASS_ID_MAX 254 
+ 
+ 
+#endif 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/drivers/mausb_hcd.c linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/drivers/mausb_hcd.c
--- linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/drivers/mausb_hcd.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/drivers/mausb_hcd.c	2014-11-28 12:39:00.572447000 +0800
@@ -0,0 +1,981 @@
+/* Name: mausb_hcd.c 
+ * Description: Creates and initializes a virtual USB host controller driver 
+ * for the Media Agnostic USB host driver. 
+ * 
+ * This file is provided under a dual BSD/GPLv2 license. When using or 
+ * redistributing this file, you may do so under either license. 
+ * 
+ * GPL LICENSE SUMMARY 
+ * 
+ * Copyright(c) 2014 Intel Corporation. 
+ * 
+ * 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. 
+ * 
+ * Contact Information: 
+ * Sean Stalley, sean.stalley [at] intel 
+ * Stephanie Wallick, stephanie.s.wallick [at] intel 
+ * 2111 NE 25th Avenue 
+ * Hillsboro, Oregon 97124 
+ * 
+ * BSD LICENSE 
+ * 
+ * Copyright(c) 2014 Intel Corporation. 
+ * 
+ * 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 of Intel Corporation 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/init.h> 
+#include <linux/wait.h> 
+#include <linux/module.h> 
+#include <linux/usb.h> 
+#include <linux/usb/hcd.h> 
+#include <linux/usb/ch11.h> 
+#include <linux/pm_runtime.h> 
+#include <linux/usb/gadget.h> 
+#include <linux/kthread.h> 
+#include <linux/random.h> 
+ 
+#include "mausb_hcd.h" 
+#include "mausb_hub.h" 
+#include "mausb_pkt.h" 
+#include "mausb_mem-host.h" 
+#include "mausb_msapi.h" 
+#include "mausb_mgmt.h" 
+#include "mausb_state.h" 
+#include "mausb_tx.h" 
+ 
+static int mausb_bus_match(struct device *dev, struct device_driver *drv) 
+{ 
+ if (strncmp(dev->bus->name, drv->name, strlen(drv->name))) 
+ return 0; /* no match */ 
+ else 
+ return 1; /* match */ 
+} 
+ 
+static int mausb_bus_probe(struct device *dev) 
+{ 
+ return mausb_probe(dev); 
+} 
+ 
+static int mausb_bus_remove(struct device *dev) 
+{ 
+ return mausb_remove(dev); 
+} 
+ 
+static void mausb_dev_release(struct device *dev) 
+{ 
+ /* TODO: if we dynamically allocate anything, free it here */ 
+} 
+ 
+static struct class *mausb_class; 
+ 
+static struct bus_type mausb_bus_type = { 
+ .name = MAUSB_NAME, 
+ .match = mausb_bus_match, 
+ .probe = mausb_bus_probe, 
+ .remove = mausb_bus_remove, 
+}; 
+ 
+static struct device_driver mhcd_driver = { 
+ .name = MAUSB_NAME, 
+ .bus = &mausb_bus_type, 
+ .owner = THIS_MODULE, 
+}; 
+ 
+static struct mausb_hcd mhcd; 
+ 
+struct api_context { 
+ struct completion done; 
+ int status; 
+}; 
+ 
+/* 
+ * pointer conversion functions 
+ */ 
+struct mausb_hcd *usb_hcd_to_mausb_hcd(struct usb_hcd *hcd) 
+{ 
+ if (usb_hcd_is_primary_hcd(hcd)) 
+ return *((struct mausb_hcd **) (hcd->hcd_priv)); 
+ else 
+ return *((struct mausb_hcd **) (hcd->primary_hcd->hcd_priv)); 
+} 
+ 
+struct usb_hcd *mausb_hcd_to_usb_hcd(struct mausb_hcd *mhcd) 
+{ 
+ if (mhcd->shared_hcd && !usb_hcd_is_primary_hcd(mhcd->shared_hcd)) 
+ return mhcd->shared_hcd; 
+ else 
+ return mhcd->usb_hcd; 
+} 
+ 
+struct device *mausb_hcd_to_dev(struct mausb_hcd *mhcd) 
+{ 
+ return mausb_hcd_to_usb_hcd(mhcd)->self.controller; 
+} 
+ 
+struct mausb_urb *usb_urb_to_mausb_urb(struct urb *urb) 
+{ 
+ return (struct mausb_urb *) urb->hcpriv; 
+} 
+/* ----------------------------------------------------------------- */ 
+ 
+/** 
+ * @maurb: Media agnostic structure with URB to release. 
+ * @status: Status for URB that is getting released. 
+ * 
+ * Removes an URB from the queue, deletes the media agnostic information in 
+ * the urb, and gives the URB back to the HCD. Caller must be holding the 
+ * driver's spinlock. 
+ */ 
+void mausb_unlink_giveback_urb(struct mausb_urb *maurb, int status) 
+{ 
+ struct urb *urb; 
+ struct usb_hcd *hcd; 
+ struct api_context *ctx = NULL; 
+ unsigned long irq_flags; 
+ 
+ hcd = mausb_hcd_to_usb_hcd(&mhcd); 
+ 
+ spin_lock_irqsave(&mhcd.giveback_lock, irq_flags); 
+ 
+ if (!maurb) { 
+ mausb_err(&mhcd, "%s: no maurb\n", __func__); 
+ spin_unlock_irqrestore(&mhcd.giveback_lock, irq_flags); 
+ return; 
+ } else { 
+ urb = maurb->urb; 
+ ctx = urb->context; 
+ } 
+ 
+ if (!urb) { 
+ mausb_err(&mhcd, "%s: no urb\n", __func__); 
+ mausb_internal_drop_maurb(maurb, &mhcd); 
+ spin_unlock_irqrestore(&mhcd.giveback_lock, irq_flags); 
+ return; 
+ } 
+ 
+ mausb_dbg(&mhcd, "%s: returning urb with status %i\n", __func__, status); 
+ 
+ usb_hcd_unlink_urb_from_ep(hcd, urb); 
+ usb_hcd_giveback_urb(hcd, urb, status); 
+ 
+ /* remove the mausb-specific data */ 
+ mausb_internal_drop_maurb(maurb, &mhcd); 
+ 
+ spin_unlock_irqrestore(&mhcd.giveback_lock, irq_flags); 
+} 
+ 
+/** 
+ * Adds an URB to the endpoint queue then calls the URB handler. URB is wrapped 
+ * in media agnostic structure before being enqueued. 
+ */ 
+static int mausb_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, 
+ gfp_t memflags) 
+{ 
+ int ret = 0; 
+ struct mausb_urb *maurb; 
+ struct mausb_host_ep *ep; 
+ unsigned long irq_flags; 
+ 
+ if (!hcd || !urb) { 
+ pr_err("%s: no %s\n", __func__, (hcd ? "urb" : "USB hcd")); 
+ } 
+ 
+ ep = usb_to_ma_endpoint(urb->ep); 
+ 
+ if (!ep) { 
+ mausb_err(&mhcd, "%s: no endpoint\n", __func__); 
+ return -EINVAL; 
+ } 
+ 
+ if (urb->status != -EINPROGRESS) { 
+ mausb_err(&mhcd, "%s: urb already unlinked, status is %i\n", 
+ __func__, urb->status); 
+ return urb->status; 
+ } 
+ 
+ /* If the endpoint isn't activated, we can't enqueue anything. */ 
+ if (MAUSB_EP_HANDLE_UNASSIGNED == ep->ep_handle_state) { 
+ mausb_err(&mhcd, "%s: endpoint handle unassigned\n", __func__); 
+ return -EPIPE; 
+ } 
+ 
+ if (USB_SPEED_FULL != urb->dev->speed) /* suppress checks */ 
+ ep->max_pkt = usb_endpoint_maxp(&urb->ep->desc); 
+ 
+ /* initialize the maurb */ 
+ maurb = mausb_alloc_maurb(ep, memflags); 
+ if (!maurb) { 
+ mausb_err(&mhcd, "could not allocate memory for MA USB urb\n"); 
+ return -ENOMEM; 
+ } 
+ 
+ /* set maurb member values */ 
+ maurb->urb = urb; 
+ urb->hcpriv = maurb; 
+ 
+ /* submit urb to hcd and add to endpoint queue */ 
+ ret = usb_hcd_link_urb_to_ep(hcd, urb); 
+ if (ret < 0) { 
+ mausb_err(&mhcd, "urb enqueue failed: error %d\n", ret); 
+ usb_hcd_unlink_urb_from_ep(hcd, urb); 
+ return ret; 
+ } 
+ 
+ /* get usb device and increment reference counter */ 
+ if (!mhcd.udev) { 
+ mhcd.udev = urb->dev; 
+ usb_get_dev(mhcd.udev); 
+ } 
+ 
+ /* add urb to queue list */ 
+ spin_lock_irqsave(&ep->ep_lock, irq_flags); 
+ list_add_tail(&maurb->urb_list, &ep->urb_list); 
+ spin_unlock_irqrestore(&ep->ep_lock, irq_flags); 
+ 
+ /* add urb to ma hcd urb list */ 
+ spin_lock_irqsave(&mhcd.urb_list_lock, irq_flags); 
+ list_add_tail(&maurb->ma_hcd_urb_list, &mhcd.enqueue_urb_list); 
+ spin_unlock_irqrestore(&mhcd.urb_list_lock, irq_flags); 
+ 
+ /* send to MA transfer process */ 
+ wake_up(&mhcd.waitq); 
+ 
+ return ret; 
+} 
+ 
+/** 
+ * Dequeues an URB. 
+ */ 
+static int mausb_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) 
+{ 
+ int ret = 0; 
+ struct mausb_host_ep *ep = usb_to_ma_endpoint(urb->ep); 
+ struct mausb_urb *maurb = usb_urb_to_mausb_urb(urb); 
+ unsigned long irq_flags; 
+ 
+ /* For debugging - we want to know who initiated URB dequeue. */ 
+ dump_stack(); 
+ 
+ if (ep->active_transfer == maurb) { 
+ ret = mausb_tx_dev_mgmt_req_ep(CancelTransferReq, 
+ &mhcd.ma_dev.mgmt, maurb->dev, true, ep); 
+ 
+ spin_lock_irqsave(&ep->ep_lock, irq_flags); 
+ ep->active_transfer = NULL; 
+ ep->state.tx_pending = 0; 
+ spin_unlock_irqrestore(&ep->ep_lock, irq_flags); 
+ } 
+ 
+ /* 
+ * Make sure urb hasn't been unlinked or already completed. 
+ * Dequeue must fail if usb_hcd_check_unlink_urb() fails. 
+ */ 
+ spin_lock_irqsave(&ep->ep_lock, irq_flags); 
+ ret = usb_hcd_check_unlink_urb(hcd, urb, status); 
+ 
+ if (ret < 0) { 
+ spin_unlock_irqrestore(&ep->ep_lock, irq_flags); 
+ mausb_err(&mhcd, "%s: urb already unlinked or completed, %d\n", 
+ __func__, ret); 
+ return ret; 
+ } 
+ 
+ /* check to make sure our urb queue is not empty */ 
+ if (list_empty(&ep->urb_list)) { 
+ spin_unlock_irqrestore(&ep->ep_lock, irq_flags); 
+ mausb_err(&mhcd, "%s: urb queue is empty\n", __func__); 
+ return -ENXIO; 
+ } 
+ 
+ spin_unlock_irqrestore(&ep->ep_lock, irq_flags); 
+ 
+ /* now we can give back URB */ 
+ spin_lock_irqsave(&mhcd.hcd_lock, irq_flags); 
+ mausb_unlink_giveback_urb(maurb, -EINPROGRESS); 
+ spin_unlock_irqrestore(&mhcd.hcd_lock, irq_flags); 
+ 
+ return ret; 
+} 
+ 
+/** 
+ * Called by usb core to suspend the bus. Once suspended, hcd waits in 
+ * that state until it is resumed by mausb_bus_resume(). 
+ * 
+ * Note: sections are commented out to accomidate devices that don't yet 
+ * support SleepReq packets. 
+ * 
+ * Always returns zero. 
+ */ 
+static int mausb_bus_suspend(struct usb_hcd *hcd) 
+{ 
+ struct mausb_root_hub *roothub = usb_hcd_to_roothub(hcd); 
+ 
+ /* stop polling */ 
+ clear_bit(HCD_FLAG_POLL_RH, &hcd->flags); 
+ 
+ /* 
+ * Avoid suspend/resume race condition by making sure there aren't any 
+ * devices in the middle of resuming. If a connected device is 
+ * resuming, suspend should fail. 
+ */ 
+ if (mhcd.resuming) { 
+ mausb_err(&mhcd, "%s: suspend failed, device is resuming\n", 
+ __func__); 
+ return -EBUSY; 
+ } 
+ 
+ mausb_dbg(&mhcd, "%s: suspending mausb driver\n", __func__); 
+ 
+ roothub->rh_state = MAUSB_RH_SUSPEND; 
+ hcd->state = HC_STATE_SUSPENDED; 
+ 
+ return 0; 
+} 
+ 
+/** 
+ * Called by usb core to resume hcd after bus suspension. 
+ * 
+ * Returns 0 if resume was successful, otherwise returns negative error 
+ * value. 
+ */ 
+static int mausb_bus_resume(struct usb_hcd *hcd) 
+{ 
+ int ret = 0; 
+ struct mausb_dev *top_dev = mhcd.ma_dev.top_dev; 
+ struct mausb_root_hub *roothub = usb_hcd_to_roothub(hcd); 
+ 
+ if (!HCD_HW_ACCESSIBLE(hcd)) { 
+ mausb_err(&mhcd, "%s: hcd not fully powered\n", __func__); 
+ return -ESHUTDOWN; 
+ } 
+ 
+ mausb_dbg(&mhcd, "%s: resuming mausb driver\n", __func__); 
+ 
+ hcd->state = HC_STATE_RUNNING; 
+ roothub->rh_state = MAUSB_RH_RUNNING; 
+ 
+ if (NULL != top_dev) { 
+ ret = mausb_tx_dev_mgmt_req(WakeReq, &mhcd.ma_dev.mgmt, 
+ top_dev, true); 
+ 
+ if (ret < 0) { 
+ mausb_err(&mhcd, "%s: WakeReq was unsuccessful" 
+ " (error %i)\n", __func__, ret); 
+ return ret; 
+ } 
+ } 
+ 
+ return 0; 
+} 
+ 
+/** 
+ * Returns the hardware-chosen device address. 
+ */ 
+static int mausb_address_device(struct usb_hcd *hcd, struct usb_device *udev) 
+{ 
+ int ret = 0; 
+ struct ma_dev *ma_dev; 
+ struct mausb_dev *mausb_dev; 
+ struct mausb_host_ep *ma_ep; 
+ 
+ ma_dev = &mhcd.ma_dev; 
+ if (NULL == ma_dev) 
+ return -EINVAL; 
+ 
+ mausb_dev = mausb_find_dev_host(ma_dev, udev); 
+ if (NULL == mausb_dev) 
+ return -ENODEV; 
+ 
+ ret = mausb_tx_dev_mgmt_req(USBDevHandleReq, &ma_dev->mgmt, 
+ mausb_dev, true); 
+ 
+ if (-ETIMEDOUT == ret) { 
+ mausb_err(&mhcd, "USBDevHandleReq timed out\n"); 
+ } else if (0 > ret) { 
+ mausb_err(&mhcd, "USBDevHandleReq failed with error %i\n", ret); 
+ } else { 
+ ret = mausb_tx_dev_mgmt_req(EPHandleReq, &ma_dev->mgmt, 
+ mausb_dev, true); 
+ 
+ if (-ETIMEDOUT == ret) { 
+ mausb_err(&mhcd, "EPHandleReq timed out\n"); 
+ } else if (0 > ret) { 
+ mausb_err(&mhcd, "EPHandleReq failed with error %i\n", 
+ ret); 
+ } else { 
+ ret = mausb_tx_dev_mgmt_req(SetUSBDevAddrReq, 
+ &ma_dev->mgmt, mausb_dev, true); 
+ 
+ if (-ETIMEDOUT == ret) { 
+ mausb_err(&mhcd, "SetUSBDevAddrReq timed out\n"); 
+ } else if (0 > ret) { 
+ mausb_err(&mhcd, "SetUSBDevAddrReq failed with" 
+ " error %i\n", ret); 
+ } else { 
+ ma_ep = mausb_find_ep_host(&udev->ep0, 
+ mausb_dev); 
+ ret = mausb_tx_dev_mgmt_req_ep(ModifyEP0Req, 
+ &ma_dev->mgmt, mausb_dev, true, ma_ep); 
+ } 
+ } 
+ } 
+ 
+ /* TODO: handle failed enumeration */ 
+ 
+ return 0; 
+} 
+ 
+/** 
+ * Resets everything to default values. Always returns zero. 
+ */ 
+static int mausb_reset(struct usb_hcd *hcd) 
+{ 
+ struct mausb_root_hub *roothub = usb_hcd_to_roothub(hcd); 
+ 
+ mausb_dbg(&mhcd, "%s: resetting MA USB host driver . . .\n", __func__); 
+ 
+ roothub->rh_state = MAUSB_RH_RESETTING; 
+ 
+ if (mausb_is_ss_hcd(hcd)) { 
+ hcd->speed = HCD_USB3; 
+ hcd->self.root_hub->speed = USB_SPEED_SUPER; 
+ } else { 
+ hcd->speed = HCD_USB2; 
+ hcd->self.root_hub->speed = USB_SPEED_HIGH; 
+ hcd->has_tt = 1; 
+ } 
+ 
+ hcd->uses_new_polling = 1; 
+ hcd->self.sg_tablesize = 0; 
+ 
+ mausb_init_port_status(&mhcd.root_hub); 
+ mausb_init_port_status(&mhcd.shared_root_hub); 
+ 
+ return 0; 
+} 
+ 
+int mausb_hcd_thread(void *data) 
+{ 
+ struct mausb_hcd *mhcd = (struct mausb_hcd *)data; 
+ struct mausb_urb *ma_urb, *next_ma_urb; 
+ struct mausb_host_ep *ma_ep; 
+ unsigned long irq_flags; 
+ 
+ while (!kthread_should_stop()) { 
+ spin_lock_irqsave(&mhcd->urb_list_lock, irq_flags); 
+ list_for_each_entry_safe(ma_urb, next_ma_urb, 
+ &mhcd->enqueue_urb_list, ma_hcd_urb_list) { 
+ 
+ list_move(&ma_urb->ma_hcd_urb_list, 
+ &mhcd->transfer_urb_list); 
+ 
+ spin_unlock_irqrestore(&mhcd->urb_list_lock, irq_flags); 
+ 
+ ma_ep = ma_urb->ep; 
+ start_ma_transfer(ma_ep, ma_urb, 
+ usb_pipein(ma_urb->urb->pipe)); 
+ 
+ spin_lock_irqsave(&mhcd->urb_list_lock, irq_flags); 
+ } 
+ spin_unlock_irqrestore(&mhcd->urb_list_lock, irq_flags); 
+ 
+ wait_event_interruptible(mhcd->waitq, 
+ !list_empty(&mhcd->enqueue_urb_list) || 
+ kthread_should_stop()); 
+ } 
+ 
+ do_exit(0); 
+ return 0; 
+} 
+ 
+/** 
+ * Tells the hcd to start running. Always returns zero. 
+ */ 
+static int mausb_start(struct usb_hcd *hcd) 
+{ 
+ struct mausb_root_hub *roothub = usb_hcd_to_roothub(hcd); 
+ 
+ mausb_dbg(&mhcd, "%s: starting MA USB driver . . .\n", __func__); 
+ 
+ hcd->state = HC_STATE_RUNNING; 
+ roothub->rh_state = MAUSB_RH_RUNNING; 
+ 
+ spin_lock_init(&mhcd.hcd_lock); 
+ INIT_LIST_HEAD(&mhcd.ma_dev.dev_list); 
+ INIT_LIST_HEAD(&mhcd.enqueue_urb_list); 
+ spin_lock_init(&mhcd.urb_list_lock); 
+ INIT_LIST_HEAD(&mhcd.transfer_urb_list); 
+ spin_lock_init(&mhcd.giveback_lock); 
+ init_waitqueue_head(&mhcd.waitq); 
+ mhcd.ma_hcd_task_data = (void *)&mhcd; 
+ mhcd.ma_hcd_task = kthread_run(mausb_hcd_thread, 
+ mhcd.ma_hcd_task_data, "mausb_hcd_thread"); 
+ 
+ return 0; 
+} 
+ 
+/** 
+ * Called when driver is removed (specifically during usb_remove_hcd). This is 
+ * where we tell the hcd to stop writing memory and doing I/O. 
+ */ 
+static void mausb_stop(struct usb_hcd *hcd) 
+{ 
+ if (mhcd.ma_hcd_task != NULL) { 
+ kthread_stop(mhcd.ma_hcd_task); 
+ mhcd.ma_hcd_task = NULL; 
+ } 
+ 
+ mausb_dbg(&mhcd, "%s: stopping mausb driver . . .\n", __func__); 
+} 
+ 
+static const struct hc_driver mausb_hc_driver = { 
+ .description = "mausb hcd", 
+ .product_desc = "mausb host controller", 
+ .hcd_priv_size = sizeof(struct mausb_hcd), 
+ .irq = NULL, 
+ .flags = HCD_USB3, 
+ .reset = &mausb_reset, 
+ .start = &mausb_start, 
+ .stop = &mausb_stop, 
+ .urb_enqueue = &mausb_urb_enqueue, 
+ .urb_dequeue = &mausb_urb_dequeue, 
+ .hub_status_data = &mausb_hub_status_data, 
+ .hub_control = &mausb_hub_control, 
+ .bus_suspend = &mausb_bus_suspend, 
+ .bus_resume = &mausb_bus_resume, 
+ .alloc_dev = &mausb_alloc_dev, 
+ .free_dev = &mausb_free_dev, 
+ .add_endpoint = &mausb_add_endpoint, 
+ .drop_endpoint = &mausb_drop_endpoint, 
+ .check_bandwidth = &mausb_check_bandwidth, 
+ .reset_bandwidth = &mausb_reset_bandwidth, 
+ .address_device = &mausb_address_device, 
+}; 
+ 
+/** 
+ * Sets the host_bos fields to the proper initial values per USB3 spec, 
+ * section 10.13.1. 
+ */ 
+static int mausb_set_host_bos(struct mausb_host_bos *host_bos) 
+{ 
+ /* BOS Descriptor */ 
+ host_bos->bos_des.bLength = USB_DT_BOS_SIZE; 
+ host_bos->bos_des.bDescriptorType = USB_DT_BOS; 
+ host_bos->bos_des.wTotalLength = sizeof(struct mausb_host_bos); 
+ host_bos->bos_des.bNumDeviceCaps = MAUSB_HOST_NUM_DEV_CAPS; 
+ 
+ /* SuperSpeed USB Device Capability */ 
+ host_bos->ss_cap_des.bLength = USB_DT_USB_SS_CAP_SIZE; 
+ host_bos->ss_cap_des.bDescriptorType = USB_DT_DEVICE_CAPABILITY; 
+ host_bos->ss_cap_des.bDevCapabilityType = USB_SS_CAP_TYPE; 
+ host_bos->ss_cap_des.bmAttributes = USB_LTM_SUPPORT; 
+ host_bos->ss_cap_des.wSpeedSupported = USB_5GBPS_OPERATION; 
+ host_bos->ss_cap_des.bFunctionalitySupport = MAUSB_SUPER_SPEED; 
+ host_bos->ss_cap_des.bU1devExitLat = MAUSB_HOST_U1_DEV_EXIT_LAT; 
+ host_bos->ss_cap_des.bU2DevExitLat = MAUSB_HOST_U2_DEV_EXIT_LAT; 
+ 
+ return 0; 
+} 
+ 
+/** 
+ * @req: The incoming MA USB management request packet to handle. 
+ * @resp: The MA USB management response packet to send out. 
+ * @mgmt: The MA USB HCD's management structure. 
+ * 
+ * This function handles management requests to the HCD. It parses the packet 
+ * and makes the necessary function calls into the system. 
+ * 
+ * Note: this function only completes the packet type, status and 
+ * request-specific data-fields. the remainder of the fields are set 
+ * by mausb_rx_mgmt_req 
+ */ 
+static int hcd_mgmt_req_switch(struct mausb_mgmt_pkt *req, 
+ struct mausb_mgmt_pkt *resp, struct mausb_mgmt *mgmt) 
+{ 
+ int ret = 0; 
+ 
+ switch (req->common.pkt_type) { 
+ 
+ /* TODO: handle unimplemented request types */ 
+ case RemoteWakeReq: 
+ case DevInitDisconnectReq: 
+ break; 
+ case PingReq: 
+ resp->common.pkt_type = PingResp; 
+ resp->common.pkt_status = NO_ERROR; 
+ break; 
+ /* invalid packet type */ 
+ default: 
+ ret = -EINVAL; 
+ break; 
+ } 
+ 
+ return ret; 
+} 
+ 
+static int mausb_transfer_mgmt_packet(struct ms_pkt *ms_pkt, void *context); 
+ 
+/** 
+ * Generates the mass_id used to initialize an MA USB device. Uses a random 
+ * number generator to choose a random id between 1 and 254. 
+ * 
+ * Returns the random id chosen. 
+ */ 
+static __u8 get_mass_id(void) 
+{ 
+ __u8 id; 
+ 
+ get_random_bytes(&id, sizeof(id)); 
+ 
+ /* Note: this function is twice as likely to pick 1 or 2 */ 
+ id = (id % (MASS_ID_MAX - MASS_ID_MIN + 1) + MASS_ID_MIN); 
+ 
+ return id; 
+} 
+ 
+/** 
+ * Initializes MA USB hcd roothub descriptors and ports. 
+ * 
+ * Always returns zero. 
+ */ 
+static int create_mausb_hcd(struct mausb_hcd *mausb_hcd) 
+{ 
+ if (mausb_hcd == NULL) 
+ return -ENOMEM; 
+ 
+ /* set the roothub descriptor to the proper initial values */ 
+ mausb_set_hub_descriptor(&mausb_hcd->root_hub.descriptor); 
+ mausb_set_ss_hub_descriptor(&mausb_hcd->shared_root_hub.descriptor); 
+ 
+ /* set the host_bos to the proper values */ 
+ mausb_set_host_bos(&mausb_hcd->host_bos); 
+ 
+ /* initialize port status values */ 
+ mausb_init_port_status(&mausb_hcd->root_hub); 
+ mausb_init_ss_port_status(&mausb_hcd->shared_root_hub); 
+ 
+ /* initialize the MA USB device structure */ 
+ mausb_init_ma_device(&mausb_hcd->ma_dev, MAUSB_DEV_ADDR, get_mass_id(), 
+ mausb_hcd, NULL, &hcd_mgmt_req_switch, &mausb_device_connect); 
+ 
+ return 0; 
+} 
+ 
+/** 
+ * probe function 
+ */ 
+int mausb_probe(struct device *dev) 
+{ 
+ int ret = 0; 
+ const char *bus_name = MAUSB_BUS; 
+ unsigned int mausb_irqnum = 0; 
+ struct usb_hcd *usb_hcd; 
+ 
+ /* create our USB 2.0 roothub */ 
+ usb_hcd = usb_create_hcd(&mausb_hc_driver, dev, bus_name); 
+ if (usb_hcd == NULL) { 
+ dev_err(dev, "%s: could not create USB HCD\n", __func__); 
+ return -ENOMEM; 
+ } 
+ 
+ /* create our data structure that holds MA USB data */ 
+ ret = create_mausb_hcd(&mhcd); 
+ if (ret < 0) { 
+ dev_err(dev, "%s: could not create MA USB HCD (error %i)\n", 
+ __func__, ret); 
+ 
+ return ret; 
+ } 
+ 
+ /* 
+ * Everyone exchanges pointers so we can move between data types with 
+ * minimal pointer juju. 
+ */ 
+ *((struct mausb_hcd **) usb_hcd->hcd_priv) = &mhcd; 
+ mhcd.usb_hcd = usb_hcd; 
+ 
+ /* 
+ * Finish initializing generic members of USB 2.0 HCD, register the bus, 
+ * request IRQ line, call driver's reset() and start() routines. 
+ */ 
+ ret = usb_add_hcd(usb_hcd, mausb_irqnum, IRQF_SHARED); 
+ if (ret) { 
+ dev_err(dev, "%s: could not add USB HCD (error %i)\n", 
+ __func__, ret); 
+ 
+ usb_remove_hcd(usb_hcd); 
+ 
+ return ret; 
+ } 
+ 
+ /* add our USB 3.0 roothub */ 
+ mhcd.shared_hcd = usb_create_shared_hcd(&mausb_hc_driver, dev, 
+ bus_name, usb_hcd); 
+ 
+ if (mhcd.shared_hcd == NULL) { 
+ dev_err(dev, "%s: could not create shared USB HCD\n", __func__); 
+ 
+ usb_remove_hcd(usb_hcd); 
+ 
+ return -ENOMEM; 
+ } 
+ 
+ ret = usb_add_hcd(mhcd.shared_hcd, mausb_irqnum, IRQF_SHARED); 
+ 
+ if (ret) { 
+ dev_err(dev, "%s: could not add shared USB HCD (error %i)\n", 
+ __func__, ret); 
+ 
+ usb_remove_hcd(usb_hcd); 
+ } 
+ 
+ return ret; 
+} 
+ 
+/** 
+ * remove function 
+ */ 
+int mausb_remove(struct device *dev) 
+{ 
+ int ret = 0; 
+ struct usb_hcd *hcd, *shared_hcd; 
+ 
+ hcd = mhcd.usb_hcd; 
+ shared_hcd = mhcd.shared_hcd; 
+ 
+ if (mhcd.shared_hcd) { 
+ usb_remove_hcd(mhcd.shared_hcd); 
+ usb_put_hcd(mhcd.shared_hcd); 
+ mhcd.shared_hcd = NULL; 
+ } 
+ 
+ usb_remove_hcd(hcd); 
+ usb_put_hcd(hcd); 
+ 
+ return ret; 
+} 
+ 
+/** 
+ * @pkt The incoming MA USB packet to parse. 
+ * @context The MA USB HCD's management structure. 
+ * 
+ * Used to transfer MA USB management packets to and from an MA USB device. 
+ */ 
+static int mausb_transfer_mgmt_packet(struct ms_pkt *ms_pkt, void *context) 
+{ 
+ int ret; 
+ struct mausb_mgmt *mgmt; 
+ struct mausb_pkt *pkt = mausb_pkt_from_ms_pkt_ma_dev(ms_pkt, 
+ &mhcd.ma_dev, GFP_ATOMIC); 
+ 
+ if ((NULL == context) || (NULL == pkt)) { 
+ mausb_err(&mhcd, "%s: received NULL input\n", __func__); 
+ return -EFAULT; 
+ } 
+ 
+ mgmt = (struct mausb_mgmt *) context; 
+ 
+ ret = mausb_rx_mgmt(pkt, mgmt); 
+ 
+ return ret; 
+} 
+ 
+/** 
+ * @drv: The media specific driver structure that provides an interface 
+ * for the media agnostic driver. 
+ * 
+ * Registers a media specific driver with the MA USB HCD. 
+ */ 
+struct mausb_ma_drv *mausb_register_ms_driver(struct mausb_ms_drv *drv) 
+{ 
+ unsigned long irq_flags; 
+ 
+ spin_lock_irqsave(&mhcd.hcd_lock, irq_flags); 
+ mhcd.ma_dev.ms_driver = drv; 
+ spin_unlock_irqrestore(&mhcd.hcd_lock, irq_flags); 
+ 
+ /* Open the management channel */ 
+ mausb_add_mgmt_channel(&mhcd.ma_dev.mgmt, drv, 
+ &mausb_transfer_mgmt_packet, &mausb_mgmt_pkt_sent); 
+ 
+ return &mhcd.ma_dev.ma_drv; 
+} 
+EXPORT_SYMBOL(mausb_register_ms_driver); 
+ 
+/** 
+ * Called by a media specific driver to indicate that an MA USB device has been 
+ * connected and is ready to receive MA USB packets. 
+ */ 
+int mausb_device_connect(int on) 
+{ 
+ int status = 0; 
+ /* TODO: don't want portnum hard coded when we add more ports */ 
+ int portnum = 0; 
+ 
+ /* connection event */ 
+ if (on) { 
+ /* reset MA USB device */ 
+ status = mausb_tx_dev_mgmt_req(DevResetReq, &mhcd.ma_dev.mgmt, 
+ NULL, true); 
+ 
+ if (status < 0) { 
+ mausb_err(&mhcd, "%s: cannot reset MA device," 
+ " error %i\n", __func__, status); 
+ return status; 
+ } 
+ 
+ /* send CapResp packet */ 
+ if (0 <= status) { 
+ status = mausb_tx_dev_mgmt_req(CapReq, 
+ &mhcd.ma_dev.mgmt, NULL, true); 
+ } 
+ 
+ if (status < 0) { 
+ mausb_err(&mhcd, "%s: cannot get device capabilities," 
+ " error %i\n", __func__, status); 
+ return status; 
+ } 
+ } 
+ 
+ status = mausb_connect(&mhcd, portnum, on); 
+ 
+ return status; 
+} 
+ 
+/** 
+ * MA USB device creation function 
+ */ 
+int mausb_create_dev(void) 
+{ 
+ int ret = 0; 
+ 
+ mhcd.dev = device_create(mausb_class, NULL, 
+ MKDEV(MAUSB_MAJOR, MAUSB_MINOR), NULL, MAUSB_NAME); 
+ if (IS_ERR(mhcd.dev)) { 
+ ret = PTR_ERR(mhcd.dev); 
+ pr_err("%s: device_create() failed with error %i\n", 
+ __func__, ret); 
+ } 
+ 
+ mhcd.dev->driver = &mhcd_driver; 
+ 
+ return ret; 
+} 
+ 
+/** 
+ * MA USB device registration function 
+ */ 
+int mausb_register_dev(struct device *dev) 
+{ 
+ int ret = 0; 
+ 
+ mhcd.dev->bus = &mausb_bus_type; 
+ mhcd.dev->release = mausb_dev_release; 
+ ret = device_register(dev); 
+ if (ret) { 
+ pr_err("%s: device_register() failed with error %i\n", 
+ __func__, ret); 
+ } 
+ 
+ return ret; 
+} 
+ 
+/** 
+ * initialization function 
+ */ 
+int mausb_hcd_init(void) 
+{ 
+ int ret; 
+ 
+ ret = bus_register(&mausb_bus_type); 
+ if(ret) { 
+ pr_err("%s: bus_register() failed with error %i\n", 
+ __func__, ret); 
+ return ret; 
+ } 
+ 
+ mausb_class = class_create(THIS_MODULE, MAUSB_NAME); 
+ if (IS_ERR(mausb_class)) { 
+ mausb_class = NULL; 
+ ret = PTR_ERR(mausb_class); 
+ pr_err("%s: class_create() failed with error %i\n", 
+ __func__, ret); 
+ goto class_err; 
+ } 
+ 
+ ret = driver_register(&mhcd_driver); 
+ if (ret) { 
+ pr_err("%s: could not register driver (error %i)\n", 
+ __func__, ret); 
+ goto driver_err; 
+ } 
+ 
+ ret = mausb_create_dev(); 
+ if (ret) 
+ goto dev_err; 
+ 
+ mausb_probe(mhcd.dev); 
+ 
+ return ret; 
+ 
+dev_err: 
+ driver_unregister(&mhcd_driver); 
+ 
+driver_err: 
+ class_destroy(mausb_class); 
+ mausb_class = NULL; 
+class_err: 
+ bus_unregister(&mausb_bus_type); 
+ 
+ return ret; 
+} 
+module_init(mausb_hcd_init); 
+ 
+/** 
+ * Exit function. 
+ */ 
+void mausb_hcd_exit(void) 
+{ 
+ mausb_remove(mhcd.dev); 
+ device_destroy(mausb_class, MKDEV(MAUSB_MAJOR, MAUSB_MINOR)); 
+ driver_unregister(&mhcd_driver); 
+ class_destroy(mausb_class); 
+ bus_unregister(&mausb_bus_type); 
+} 
+module_exit(mausb_hcd_exit); 
+ 
+MODULE_LICENSE("Dual BSD/GPL"); 
+MODULE_AUTHOR("Intel"); 
+MODULE_DESCRIPTION("MA USB driver"); 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/drivers/mausb_hcd.h linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/drivers/mausb_hcd.h
--- linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/drivers/mausb_hcd.h	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/drivers/mausb_hcd.h	2014-11-28 12:39:00.572447000 +0800
@@ -0,0 +1,184 @@
+/* Name: mausb_hcd.h 
+ * Description: header file for mausb_hcd.c 
+ * 
+ * This file is provided under a dual BSD/GPLv2 license. When using or 
+ * redistributing this file, you may do so under either license. 
+ * 
+ * GPL LICENSE SUMMARY 
+ * 
+ * Copyright(c) 2014 Intel Corporation. 
+ * 
+ * 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. 
+ * 
+ * Contact Information: 
+ * Sean Stalley, sean.stalley [at] intel 
+ * Stephanie Wallick, stephanie.s.wallick [at] intel 
+ * 2111 NE 25th Avenue 
+ * Hillsboro, Oregon 97124 
+ * 
+ * BSD LICENSE 
+ * 
+ * Copyright(c) 2014 Intel Corporation. 
+ * 
+ * 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 of Intel Corporation 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. 
+ */ 
+ 
+#ifndef __MAUSB_HCD_H 
+#define __MAUSB_HCD_H 
+ 
+#include <linux/spinlock.h> 
+ 
+#include "mausb_hub.h" 
+#include "mausb_pkt.h" 
+#include "mausb_mem.h" 
+#include "mausb_const.h" 
+ 
+#define MAUSB_NAME "mausb" 
+#define MAUSB_BUS "mausb" 
+ 
+#define mausb_info(mhcd, fmt, args...) \ 
+ dev_info(mausb_hcd_to_usb_hcd(mhcd)->self.controller , fmt , ## args) 
+#define mausb_dbg(mhcd, fmt, args...) \ 
+ dev_dbg(mausb_hcd_to_usb_hcd(mhcd)->self.controller , fmt , ## args) 
+#define mausb_warn(mhcd, fmt, args...) \ 
+ dev_warn(mausb_hcd_to_usb_hcd(mhcd)->self.controller , fmt , ## args) 
+#define mausb_err(mhcd, fmt, args...) \ 
+ dev_err(mausb_hcd_to_usb_hcd(mhcd)->self.controller , fmt , ## args) 
+ 
+/* Transfer directions */ 
+#define PIPE_DIR_OUT 0 
+#define PIPE_DIR_IN 1 
+ 
+/* Host BOS parameters */ 
+#define MAUSB_HOST_NUM_DEV_CAPS 1 
+#define MAUSB_HOST_U1_DEV_EXIT_LAT 0 
+#define MAUSB_HOST_U2_DEV_EXIT_LAT 0 
+ 
+/* TEMPORARY: the mausb device will have this handle */ 
+#define MAUSB_DEV_ADDR 0x54 
+#define MAUSB_MASS_ID 0x25 
+ 
+struct mausb_ms_drv; 
+ 
+/** 
+ * This structure holds the information set in a get bos descriptor request. 
+ * 
+ * @bos_des: Binary Object Store Descriptor, per USB2.0 Spec 
+ * @ss_cap_des: SuperSpeed Capability Descriptor, per USB3.0 Spec 
+ */ 
+struct __attribute__((__packed__)) mausb_host_bos { 
+ struct usb_bos_descriptor bos_des; 
+ struct usb_ss_cap_descriptor ss_cap_des; 
+}; 
+ 
+/** 
+ * This structure holds all of the MA USB-specific data. 
+ * 
+ * All data listed in this structure is protected by the hcd_lock. 
+ * if you want to use any of this data, you need to be in possession 
+ * of this lock. 
+ * 
+ * @root_hub: Contains all of the data for the USB 2.0 roothub. 
+ * This includes status, state and descriptors. 
+ * @shared_root_hub: Contains all of the data for the USB 3.0 roothub. 
+ * This includes status, state and descriptors 
+ * @host_bos: Stores the host's BOS descriptor 
+ * @udev: Pointer to the usb device we are currently sending 
+ * a packet to. 
+ * @shared_hcd: The second host controller structure for the MAUSB 
+ * driver. We need this because we do SuperSpeed, which 
+ * requires 2 root hubs. 
+ * @ma_dev: The connected MA USB device 
+ * @ma_hcd_task: Task for handling urb queue 
+ * @ma_hcd_task_data: Context for ma_hcd_task 
+ * @waitq: Event trigger for dequeue 
+ * @enqueue_urb_list: List of enqueued urbs from core 
+ * @transfer_urb_list: List of urbs awaiting ma transfer 
+ * @urb_list_lock: Lock for accessing urb lists 
+ * @hcd_lock: Lock for accessing data in this structure. note that 
+ * endpoints have their own locks. When accessing 
+ * endpoint data, this lock should NOT be held 
+ * @giveback_lock: spin lock to prevent preemption when give back an urb 
+ * @resuming: Set to 1 when HCD is resuming 
+ * @disabled: Set to 1 when hcd is disabled 
+ * @dev: Underlying device structure 
+ */ 
+struct __attribute__((__packed__)) mausb_hcd { 
+ struct mausb_root_hub root_hub; 
+ struct mausb_root_hub shared_root_hub; 
+ 
+ struct mausb_host_bos host_bos; 
+ 
+ struct usb_device *udev; 
+ 
+ struct usb_hcd *usb_hcd; 
+ struct usb_hcd *shared_hcd; 
+ 
+ struct ma_dev ma_dev; 
+ struct task_struct *ma_hcd_task; 
+ void *ma_hcd_task_data; 
+ wait_queue_head_t waitq; 
+ struct list_head enqueue_urb_list; 
+ struct list_head transfer_urb_list; 
+ spinlock_t urb_list_lock; 
+ spinlock_t hcd_lock; 
+ spinlock_t giveback_lock; 
+ unsigned int resuming:1; 
+ unsigned int disabled:1; 
+ 
+ struct device *dev; 
+}; 
+ 
+/* major and minor numbers for MA USB device */ 
+#define MAUSB_MAJOR 300 /* TODO: get real major number */ 
+#define MAUSB_MINOR 1 
+ 
+/* Pointer conversion functions */ 
+struct mausb_hcd *usb_hcd_to_mausb_hcd(struct usb_hcd *hcd); 
+struct usb_hcd *mausb_hcd_to_usb_hcd(struct mausb_hcd *mhcd); 
+struct device *mausb_hcd_to_dev(struct mausb_hcd *mhcd); 
+struct mausb_urb *usb_urb_to_mausb_urb(struct urb *urb); 
+ 
+/* URB handling functions */ 
+void mausb_unlink_giveback_urb(struct mausb_urb *maurb, int status); 
+ 
+/* Connection event function */ 
+int mausb_device_connect(int); 
+ 
+/* interfaces */ 
+int mausb_probe(struct device *dev); 
+int mausb_remove(struct device *dev); 
+ 
+ 
+#endif 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/drivers/mausb_hub.c linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/drivers/mausb_hub.c
--- linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/drivers/mausb_hub.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/drivers/mausb_hub.c	2014-11-28 12:39:00.572447000 +0800
@@ -0,0 +1,849 @@
+/* Name: mausb_hub.c 
+ * Description: mausb hub structures and functions 
+ * 
+ * This file is provided under a dual BSD/GPLv2 license. When using or 
+ * redistributing this file, you may do so under either license. 
+ * 
+ * GPL LICENSE SUMMARY 
+ * 
+ * Copyright(c) 2014 Intel Corporation. 
+ * 
+ * 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. 
+ * 
+ * Contact Information: 
+ * Sean Stalley, sean.stalley [at] intel 
+ * Stephanie Wallick, stephanie.s.wallick [at] intel 
+ * 2111 NE 25th Avenue 
+ * Hillsboro, Oregon 97124 
+ * 
+ * BSD LICENSE 
+ * 
+ * Copyright(c) 2014 Intel Corporation. 
+ * 
+ * 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 of Intel Corporation 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/init.h> 
+#include <linux/module.h> 
+#include <linux/usb.h> 
+#include <linux/usb/hcd.h> 
+#include <linux/platform_device.h> 
+#include <linux/usb/ch11.h> 
+#include <linux/usb/ch9.h> 
+ 
+#include "mausb_hub.h" 
+#include "mausb_hcd.h" 
+ 
+/** 
+ * Returns MA USB roothub data structure for a USB HCD. 
+ */ 
+struct mausb_root_hub *usb_hcd_to_roothub(struct usb_hcd *hcd) 
+{ 
+ struct mausb_hcd *mhcd = usb_hcd_to_mausb_hcd(hcd); 
+ 
+ if (usb_hcd_is_primary_hcd(hcd)) 
+ return &mhcd->root_hub; 
+ else 
+ return &mhcd->shared_root_hub; 
+} 
+ 
+/** 
+ * Returns true if the given is the superspeed HCD. Note: The primary HCD is 
+ * High Speed and the shared HCD is SuperSpeed. 
+ */ 
+bool mausb_is_ss_hcd(struct usb_hcd *hcd) 
+{ 
+ if (usb_hcd_is_primary_hcd(hcd)) 
+ return false; 
+ else 
+ return true; 
+} 
+ 
+/** 
+ * Sets downstream port link state. 
+ * 
+ * @mhcd: MA USB hcd that owns port. 
+ * @state: Link state to be set (see USB 3.0 spec for link state values). 
+ * @portnum: Port number of link state to be set. 
+ */ 
+void set_link_state(struct mausb_root_hub *roothub, int state, int portnum) 
+{ 
+ struct usb_port_status *port_stat; 
+ 
+ port_stat = &roothub->port_status[portnum]; 
+ 
+ port_stat->wPortStatus &= LINK_STATE_MASK; 
+ port_stat->wPortStatus |= state; 
+} 
+ 
+/** 
+ * Generates connect or disconnect event for a roothub. 
+ * 
+ * @hcd: HCD associated with roothub. 
+ * @do_connect: 1 for connect, 0 for disconnect. 
+ * @_portnum: Port number of connected device. 
+ * @is_SS: True if roothub is SuperSpeed or higher, otherwise false. 
+ */ 
+int port_connect(struct usb_hcd *hcd, int do_connect, int _portnum, bool is_SS) 
+{ 
+ int portnum = _portnum; 
+ struct usb_port_status *port_stat; 
+ struct mausb_hcd *mhcd = usb_hcd_to_mausb_hcd(hcd); 
+ struct mausb_root_hub *roothub = usb_hcd_to_roothub(hcd); 
+ 
+ if (portnum >= MAUSB_ROOTHUB_NUM_PORTS) { 
+ mausb_err(mhcd, "%s: port number %i is too large (max = %i)\n", 
+ __func__, portnum, MAUSB_ROOTHUB_NUM_PORTS); 
+ return -EINVAL; 
+ } 
+ 
+ /* if new connection, assign first empty port */ 
+ if (do_connect > 0) { 
+ portnum = 0; 
+ while (roothub->port_status[portnum].wPortStatus 
+ & USB_PORT_STAT_CONNECTION) { 
+ portnum++; 
+ } 
+ 
+ mausb_dbg(mhcd, "%s: assigned MA USB port number %d\n", 
+ __func__, portnum); 
+ } 
+ 
+ /* 
+ * If new connection, we assigned portnum above, otherwise use portnum 
+ * passed in. 
+ */ 
+ port_stat = &roothub->port_status[portnum]; 
+ 
+ /* 
+ * Make sure port is powered. If not, clear status and disable. 
+ * Note that POWER bit is different for USB 2.0 and 3.0 hubs. 
+ */ 
+ if (is_SS) { 
+ if ((port_stat->wPortStatus & USB_SS_PORT_STAT_POWER) == 0) { 
+ port_stat->wPortStatus = 0; 
+ port_stat->wPortChange = 0; 
+ set_link_state(roothub, USB_SS_PORT_LS_SS_DISABLED, 
+ portnum); 
+ 
+ goto update; 
+ } 
+ } else { 
+ if ((port_stat->wPortStatus & USB_PORT_STAT_POWER) == 0) { 
+ port_stat->wPortStatus = 0; 
+ port_stat->wPortChange = 0; 
+ 
+ goto update; 
+ } 
+ } 
+ 
+ /* disconnect if previously connected */ 
+ if (do_connect == 0 || mhcd->disabled) { 
+ if ((port_stat->wPortStatus & USB_PORT_STAT_CONNECTION) == 1) { 
+ port_stat->wPortStatus &= ~(USB_PORT_STAT_CONNECTION); 
+ port_stat->wPortStatus &= ~(USB_PORT_STAT_ENABLE); 
+ port_stat->wPortChange |= USB_PORT_STAT_C_CONNECTION; 
+ if (is_SS) 
+ set_link_state(roothub, 
+ USB_SS_PORT_LS_RX_DETECT, portnum); 
+ } 
+ } 
+ /* set bits for a new connection */ 
+ else if ((port_stat->wPortStatus & USB_PORT_STAT_CONNECTION) == 0) { 
+ port_stat->wPortStatus |= USB_PORT_STAT_ENABLE; 
+ port_stat->wPortStatus |= USB_PORT_STAT_CONNECTION; 
+ port_stat->wPortChange |= USB_PORT_STAT_C_CONNECTION; 
+ } 
+ 
+update: 
+ mausb_dbg(mhcd, "%s: port status is 0x%x port change is 0x%x\n", 
+ __func__, port_stat->wPortStatus, port_stat->wPortChange); 
+ 
+ /* let core know if there is a change in port status */ 
+ if (port_stat->wPortChange) { 
+ set_bit(HCD_FLAG_POLL_RH, &hcd->flags); 
+ usb_hcd_poll_rh_status(hcd); 
+ } 
+ 
+ return portnum; 
+} 
+ 
+/** 
+ * @mhcd: MA USB hcd with connect/disconnect event. 
+ * @portnum: MA USB port number with event. 
+ * @do_connect: Determines whether or not a connection is set or removed. 
+ * 
+ * Called to initiate either a device connect or disconnect event. A do_connect 
+ * value of 0 clears a connection. A do_connect value greater than 0 sets a 
+ * connection. A do_connect value less than 0 produces an error. 
+ * 
+ * Returns port number. If connection, port number is newly assigned port 
+ * number, otherwise it is the port number passed in as an argument. 
+ */ 
+int mausb_connect(struct mausb_hcd *mhcd, int portnum, int do_connect) 
+{ 
+ struct usb_hcd *hcd = container_of((void *)mhcd, 
+ struct usb_hcd, hcd_priv); 
+ struct usb_hcd *ss_hcd = mhcd->shared_hcd; 
+ 
+ if (!mhcd->ma_dev.ms_driver) { 
+ mausb_err(mhcd, "%s: no media specific driver\n", __func__); 
+ return -ENODEV; 
+ } 
+ 
+ if (do_connect < 0) { 
+ mausb_err(mhcd, "%s: invalid connection request %d\n", __func__, 
+ do_connect); 
+ return -EINVAL; 
+ } 
+ 
+ if (mhcd->ma_dev.ma_cap.dev_type > MAUSB_DEV_TYPE_SS_HUB) { 
+ mausb_err(mhcd, "%s: invalid MA USB device type %i\n", __func__, 
+ mhcd->ma_dev.ma_cap.dev_type); 
+ return -EINVAL; 
+ } 
+ 
+ /* 
+ * One connection event for MA devices. Connect SS and SS+ devices to 
+ * 3.0 root hub and non-SS devices to 2.0 root hub. 
+ */ 
+ else if (mhcd->ma_dev.ma_cap.dev_type == MAUSB_DEV_TYPE_INTEGRATED) { 
+ if (!mhcd->ma_dev.speed) { 
+ mausb_err(mhcd, "%s: Speed Capability Descriptor not" 
+ " found - non-hub MA USB devices require" 
+ " a Speed Capability Descriptor\n", __func__); 
+ return -EPROTO; 
+ } 
+ 
+ mausb_dbg(mhcd, "%s: %s MA USB device\n", __func__, 
+ do_connect ? "connecting" : "disconnecting"); 
+ 
+ if (mhcd->ma_dev.speed->speed == MAUSB_DEV_CAP_SPEED_SUPER || 
+ mhcd->ma_dev.speed->speed == MAUSB_DEV_CAP_SPEED_SS_PLUS) { 
+ portnum = port_connect(ss_hcd, do_connect, portnum, 
+ true); 
+ } else { 
+ portnum = port_connect(hcd, do_connect, portnum, false); 
+ } 
+ } 
+ 
+ /* 
+ * Hubs require two connection events - one for the integrated 
+ * USB 3.0 hub and one for the integrated USB 2.0 hub. 
+ */ 
+ else { 
+ mausb_dbg(mhcd, "%s: %s MA USB hub\n", __func__, 
+ do_connect ? "connecting" : "disconnecting"); 
+ 
+ portnum = port_connect(hcd, do_connect, portnum, false); 
+ portnum = port_connect(ss_hcd, do_connect, portnum, true); 
+ } 
+ 
+ return 0; 
+} 
+ 
+/** 
+ * Called by usb core when polling for a port status change. 
+ * 
+ * @hcd: USB HCD being polled. 
+ * @buf: Holds port status changes (if any). 
+ * 
+ * Returns zero if there is no status change, otherwise returns number of 
+ * bytes in buf. When there is a status change on a port, the bit indexed 
+ * at the port number + 1 (e.g. bit 2 for port 1) is set in the buffer. 
+ */ 
+int mausb_hub_status_data(struct usb_hcd *hcd, char *buf) 
+{ 
+ int i; 
+ u16 port_change = 0; 
+ u32 status = 0; 
+ int ret = 1; 
+ struct mausb_hcd *mhcd = usb_hcd_to_mausb_hcd(hcd); 
+ struct mausb_root_hub *roothub = usb_hcd_to_roothub(hcd); 
+ 
+ /* 
+ * Buf should never be more that 2 bytes. USB 3.0 hubs cannot have 
+ * more than 15 downstream ports. 
+ */ 
+ buf[0] = 0; 
+ if (MAUSB_ROOTHUB_NUM_PORTS > 7) { 
+ buf[1] = 0; 
+ ret++; 
+ } 
+ 
+ for (i = 0; i < MAUSB_ROOTHUB_NUM_PORTS; i++) { 
+ port_change = roothub->port_status[i].wPortChange; 
+ if (port_change) 
+ status |= (1 << (i + 1)); 
+ } 
+ 
+ mausb_dbg(mhcd, "%s: hub status is 0x%x\n", __func__, status); 
+ 
+ /* hcd might be suspended, resume if there is a status change */ 
+ if (mhcd->disabled == 0) { 
+ if ((hcd->state == HC_STATE_SUSPENDED) && status) 
+ usb_hcd_resume_root_hub(hcd); 
+ } 
+ 
+ memcpy(buf, (char *)&status, ret); 
+ 
+ return status ? ret : 0; 
+} 
+ 
+/** 
+ * Sets the bitfields in the hub descriptor of the 2.0 root hub. Always 
+ * returns zero. 
+ */ 
+int mausb_set_hub_descriptor(struct usb_hub_descriptor *hub_des) 
+{ 
+ /* set the values to the default */ 
+ hub_des->bDescLength = sizeof(struct usb_hub_descriptor); 
+ hub_des->bDescriptorType = USB_DT_HUB; 
+ hub_des->bNbrPorts = MAUSB_ROOTHUB_NUM_PORTS; 
+ hub_des->wHubCharacteristics = MAUSB_ROOTHUB_CHAR; 
+ hub_des->bPwrOn2PwrGood = MAUSB_ROOTHUB_PWR_ON_2_PWR_GOOD; 
+ hub_des->bHubContrCurrent = MAUSB_ROOTHUB_CONTR_CURRENT; 
+ 
+ return 0; 
+} 
+ 
+/** 
+ * Sets the bitfields in the hub descriptor of the 3.0 root hub. Always 
+ * returns zero. 
+ */ 
+int mausb_set_ss_hub_descriptor(struct usb_hub_descriptor *hub_des) 
+{ 
+ /* set the values to the default */ 
+ hub_des->bDescLength = sizeof(struct usb_hub_descriptor); 
+ hub_des->bDescriptorType = USB_DT_SS_HUB; 
+ hub_des->bNbrPorts = MAUSB_ROOTHUB_NUM_PORTS; 
+ hub_des->wHubCharacteristics = MAUSB_ROOTHUB_CHAR; 
+ hub_des->bPwrOn2PwrGood = MAUSB_ROOTHUB_PWR_ON_2_PWR_GOOD; 
+ hub_des->bHubContrCurrent = MAUSB_ROOTHUB_CONTR_CURRENT; 
+ 
+ /* USB3-specific parameters */ 
+ hub_des->u.ss.bHubHdrDecLat = MAUSB_ROOTHUB_HDR_DEC_LAT; 
+ hub_des->u.ss.wHubDelay = MAUSB_ROOTHUB_DELAY; 
+ hub_des->u.ss.DeviceRemovable = MAUSB_ALL_DEV_REMOVABLE; 
+ 
+ return 0; 
+} 
+ 
+/** 
+ * handles GetHubDescriptor requests to the root hub. 
+ * 
+ * @hcd: USB HCD that owns root hub. 
+ * @hub_des: Hub descriptor to be copied. 
+ * @wLength: Maximum length that can be copied without overflowing 
+ * the buffer. 
+ * 
+ * Returns length of what was actually copied into the mausb hcd root hub 
+ * descriptor. Note that this may be less than the total size of hub_des due 
+ * to buffer size contraints. 
+ */ 
+static int mausb_get_hub_descriptor(struct usb_hcd *hcd, 
+ struct usb_hub_descriptor *hub_des, u16 wLength) 
+{ 
+ struct mausb_hcd *mhcd = usb_hcd_to_mausb_hcd(hcd); 
+ 
+ /* Don't overflow the buffer, and don't read more than you have. */ 
+ unsigned int cpyLength = min_t(u16, wLength, 
+ sizeof(struct usb_hub_descriptor)); 
+ 
+ if (mausb_is_ss_hcd(hcd)) 
+ memcpy(hub_des, &(mhcd->shared_root_hub.descriptor), cpyLength); 
+ else 
+ memcpy(hub_des, &(mhcd->root_hub.descriptor), cpyLength); 
+ 
+ return cpyLength; 
+} 
+ 
+/** 
+ * Handles requests to hub for the BOS. 
+ * 
+ * @ma_hcd: MA USB HCD that owns hub. 
+ * @bos: MA USB BOS descriptor. 
+ * @wLength: Maximum length that can be copied without overflowing 
+ * the buffer. 
+ * 
+ * Returns length of what was actually copied into the MA USB hcd BOS 
+ * descriptor. Note that this may be less than the total size of the BOS due 
+ * to buffer size contraints. 
+ */ 
+static int mausb_get_bos(struct mausb_hcd *ma_hcd, 
+ struct mausb_host_bos *bos, u16 wLength) 
+{ 
+ /* Don't overflow the buffer, and don't read more than you have. */ 
+ unsigned int cpyLength = min_t(u16, wLength, 
+ sizeof(struct mausb_host_bos)); 
+ 
+ memcpy(bos, &(ma_hcd->host_bos), cpyLength); 
+ 
+ return cpyLength; 
+} 
+ 
+/** 
+ * Initializes FS root hub port status values for a given MA USB roothub. 
+ * 
+ * All ports are initally powered and put in link state rx.detect to wait for 
+ * a connection (or other event that changes link state). All other bits are 
+ * cleared. 
+ */ 
+int mausb_init_port_status(struct mausb_root_hub *mausb_rh) 
+{ 
+ int portnum = 0; 
+ 
+ while (portnum < MAUSB_ROOTHUB_NUM_PORTS) { 
+ 
+ /* set port power bit only */ 
+ mausb_rh->port_status[portnum].wPortStatus = 0x0; 
+ mausb_rh->port_status[portnum].wPortStatus |= 
+ USB_PORT_STAT_POWER; 
+ 
+ /* make sure to start with no status changes */ 
+ mausb_rh->port_status[portnum].wPortChange = 0x0; 
+ portnum++; 
+ } 
+ 
+ mausb_rh->rh_state = MAUSB_RH_RUNNING; 
+ 
+ return 0; 
+} 
+ 
+/** 
+ * Initializes SS root hub port status values for a given MA USb roothub. 
+ * 
+ * All ports are initally powered and put in link state rx.detect to wait for 
+ * a connection (or other event that changes link state). All other bits are 
+ * cleared. 
+ */ 
+int mausb_init_ss_port_status(struct mausb_root_hub *mausb_rh) 
+{ 
+ int portnum = 0; 
+ 
+ while (portnum < MAUSB_ROOTHUB_NUM_PORTS) { 
+ 
+ /* set port power bit and put in link state rx.detect */ 
+ mausb_rh->port_status[portnum].wPortStatus = 0x0; 
+ mausb_rh->port_status[portnum].wPortStatus |= 
+ USB_SS_PORT_STAT_POWER; 
+ mausb_rh->port_status[portnum].wPortStatus |= 
+ USB_SS_PORT_LS_RX_DETECT; 
+ 
+ /* make sure to start with no status changes */ 
+ mausb_rh->port_status[portnum].wPortChange = 0x0; 
+ portnum++; 
+ } 
+ 
+ mausb_rh->rh_state = MAUSB_RH_RUNNING; 
+ 
+ return 0; 
+} 
+ 
+/** 
+ * Handles GetHubStatus request to root hub. 
+ * 
+ * @mhcd: MA USB hcd that owns hub. 
+ * @data: Holds hub status to return to caller. 
+ * 
+ * Reads hub status from mhcd and gives it back to the caller via data. 
+ * Returns the number of bytes copied into data. 
+ */ 
+static int mausb_get_hub_status(struct usb_hcd *hcd, char *data) 
+{ 
+ struct usb_hub_status *hub_stat; 
+ struct mausb_hcd *mhcd = usb_hcd_to_mausb_hcd(hcd); 
+ struct mausb_root_hub *roothub = usb_hcd_to_roothub(hcd); 
+ 
+ hub_stat = &roothub->status; 
+ mausb_dbg(mhcd, "%s: hub status is 0x%x hub change is 0x%x\n", 
+ __func__, hub_stat->wHubStatus, hub_stat->wHubChange); 
+ 
+ ((u16 *)data)[0] = cpu_to_le16(hub_stat->wHubStatus); 
+ ((u16 *)data)[1] = cpu_to_le16(hub_stat->wHubChange); 
+ 
+ return sizeof(hub_stat->wHubStatus) + sizeof(hub_stat->wHubChange); 
+} 
+ 
+/** 
+ * Handles ClearHubFeature request to the root hub. 
+ * 
+ * @mhcd: MA USB hcd that owns hub. 
+ * @wValue: Value that determines which feature is being cleared (see USB 
+ * 3.0 spec for supported values). 
+ * 
+ * Returns 0 if sucessful, otherwise returns error to indicate invalid request. 
+ */ 
+static int mausb_clear_hub_feature(struct usb_hcd *hcd, u16 wValue) 
+{ 
+ int err = 0; 
+ struct usb_hub_status *hub_stat; 
+ struct mausb_hcd *mhcd = usb_hcd_to_mausb_hcd(hcd); 
+ struct mausb_root_hub *roothub = usb_hcd_to_roothub(hcd); 
+ 
+ hub_stat = &roothub->status; 
+ 
+ switch (wValue) { 
+ case C_HUB_LOCAL_POWER: 
+ mausb_dbg(mhcd, "clearing HUB_LOCAL_POWER\n"); 
+ hub_stat->wHubChange &= ~(HUB_STATUS_LOCAL_POWER); 
+ break; 
+ case C_HUB_OVER_CURRENT: 
+ mausb_dbg(mhcd, "clearing HUB_OVER_CURRENT\n"); 
+ hub_stat->wHubChange &= ~(HUB_STATUS_OVERCURRENT); 
+ break; 
+ default: 
+ err = -EINVAL; 
+ break; 
+ } 
+ 
+ return err; 
+} 
+ 
+/** 
+ * Handles GetPortStatus request to root hub. 
+ * 
+ * @mhcd: MA USB hcd that owns hub. 
+ * @portnum: Port number for which status is requested. 
+ * @data: Holds port status to return to caller. 
+ * 
+ * Reads port status from mhcd and returns it to caller via data. Also 
+ * completes a port reset. 
+ * 
+ * Returns the number of bytes copied into data. 
+ */ 
+static int mausb_get_port_status(struct usb_hcd *hcd, int portnum, char *data) 
+{ 
+ struct usb_port_status *port_stat; 
+ struct mausb_hcd *mhcd = usb_hcd_to_mausb_hcd(hcd); 
+ struct mausb_root_hub *roothub = usb_hcd_to_roothub(hcd); 
+ 
+ /* 
+ * Note: from USB core perspective ports are 1-indexed, mhcd uses 
+ * zero-indexing. 
+ */ 
+ port_stat = &roothub->port_status[portnum - 1]; 
+ 
+ /* 
+ * USB core sends a GetPortStatus request to complete a port reset. 
+ * After reset, port is enabled and link state is U0 (3.0 only). 
+ */ 
+ if (port_stat->wPortStatus & USB_PORT_STAT_RESET) { 
+ port_stat->wPortStatus &= ~(USB_PORT_STAT_RESET); 
+ port_stat->wPortStatus |= USB_PORT_STAT_ENABLE; 
+ 
+ if (mausb_is_ss_hcd(hcd)) 
+ set_link_state(roothub, USB_SS_PORT_LS_U0, portnum - 1); 
+ } 
+ 
+ ((u16 *)data)[0] = cpu_to_le16(port_stat->wPortStatus); 
+ ((u16 *)data)[1] = cpu_to_le16(port_stat->wPortChange); 
+ 
+ mausb_dbg(mhcd, "%s: Port status is 0x%x Port change is 0x%x\n", 
+ __func__, ((u16 *)data)[0], port_stat->wPortChange); 
+ 
+ return sizeof(port_stat->wPortStatus) + sizeof(port_stat->wPortChange); 
+} 
+ 
+/** 
+ * Handles SetPortFeature request to root hub. 
+ * 
+ * @mhcd: MA USB hcd that owns hub. 
+ * @portnum: Port number for which feature set is requested (port 
+ * number is from usb core perspective, i.e. not zero-indexed). 
+ * @wValue: Feature to be set (see USB 3.0 spec for supported values). 
+ * @wIndex: Contains link state to be set (ignored for requests other 
+ * than set link state). 
+ * 
+ * Sets the bit associated with a particular feature in the status bit field 
+ * of the port specified by portnum. Note that ports are zero indexed in the 
+ * hub, but indexed starting with one in the usb core (e.g. port 2 from the 
+ * core's perspective is port 1 to the hub). 
+ * 
+ * Returns zero for all supported requests. Returns an error value if a feature 
+ * is not supported. 
+ */ 
+static int mausb_set_port_feature(struct usb_hcd *hcd, int portnum, u16 wValue, 
+ u16 wIndex) 
+{ 
+ int err = 0; 
+ u8 link_state = 0; 
+ struct usb_port_status *port_stat; 
+ struct mausb_hcd *mhcd = usb_hcd_to_mausb_hcd(hcd); 
+ struct mausb_root_hub *roothub = usb_hcd_to_roothub(hcd); 
+ 
+ port_stat = &roothub->port_status[portnum - 1]; 
+ 
+ switch (wValue) { 
+ case USB_PORT_FEAT_RESET: 
+ mausb_dbg(mhcd, "setting PORT_RESET feature\n"); 
+ port_stat->wPortStatus |= USB_PORT_STAT_RESET; 
+ port_stat->wPortChange |= USB_PORT_STAT_C_RESET; 
+ break; 
+ case USB_PORT_FEAT_BH_PORT_RESET: 
+ mausb_dbg(mhcd, "setting BH_PORT_RESET\n"); 
+ break; 
+ case USB_PORT_FEAT_POWER: 
+ mausb_dbg(mhcd, "setting PORT_POWER feature\n"); 
+ port_stat->wPortStatus |= USB_SS_PORT_STAT_POWER; 
+ set_link_state(roothub, USB_SS_PORT_LS_RX_DETECT, portnum - 1); 
+ break; 
+ case USB_PORT_FEAT_U1_TIMEOUT: 
+ mausb_dbg(mhcd, "setting PORT_U1_TIMEOUT\n"); 
+ break; 
+ case USB_PORT_FEAT_U2_TIMEOUT: 
+ mausb_dbg(mhcd, "setting PORT_U2_TIMEOUT\n"); 
+ break; 
+ case USB_PORT_FEAT_LINK_STATE: 
+ link_state = wIndex >> 8; 
+ if (link_state == SS_DISABLED) { 
+ mausb_dbg(mhcd, "setting link state to ss.disabled\n"); 
+ mhcd->disabled = 1; 
+ clear_bit(HCD_FLAG_POLL_RH, &hcd->flags); 
+ set_link_state(roothub, USB_SS_PORT_LS_SS_DISABLED, 
+ portnum - 1); 
+ mausb_connect(mhcd, portnum - 1, 0); 
+ } 
+ 
+ else if (link_state == RX_DETECT) { 
+ mausb_dbg(mhcd, "setting link state to rx.detect\n"); 
+ mhcd->disabled = 0; 
+ set_link_state(roothub, USB_SS_PORT_LS_RX_DETECT, 
+ portnum - 1); 
+ } 
+ break; 
+ case USB_PORT_FEAT_REMOTE_WAKE_MASK: 
+ mausb_dbg(mhcd, "setting PORT_REMOTE_WAKE_MASK\n"); 
+ break; 
+ case USB_PORT_FEAT_FORCE_LINKPM_ACCEPT: 
+ mausb_dbg(mhcd, "setting FORCE_LINKPM_ACCEPT\n"); 
+ break; 
+ default: 
+ err = -EINVAL; 
+ break; 
+ } 
+ 
+ return err; 
+} 
+ 
+/** 
+ * Handles ClearPortFeature request to the root hub. 
+ * 
+ * @mhcd: MA USB hcd that owns hub. 
+ * @portnum: Port number for which feature clear is requested (port 
+ * number is from usb core perspective, i.e. not zero-indexed). 
+ * @wValue: Feature to clear (see USB 3.0 spec for supported values). 
+ * 
+ * Clears the bit associated with a particular feature in the status bit field 
+ * of the port specified by portnum. Note that ports are zero indexed in the 
+ * hub, but indexed starting with one in the usb core (e.g. port 2 from the 
+ * core's perspective is port 1 to the hub). 
+ * 
+ * Returns zero for all supported requests. Returns an error value if a feature 
+ * is not supported. 
+ */ 
+static int mausb_clear_port_feature(struct usb_hcd *hcd, int portnum, 
+ u16 wValue) 
+{ 
+ int err = 0; 
+ struct usb_port_status *port_stat; 
+ struct mausb_hcd *mhcd = usb_hcd_to_mausb_hcd(hcd); 
+ struct mausb_root_hub *roothub = usb_hcd_to_roothub(hcd); 
+ 
+ port_stat = &roothub->port_status[portnum - 1]; 
+ 
+ switch (wValue) { 
+ case USB_PORT_FEAT_POWER: 
+ mausb_dbg(mhcd, "clearing PORT_POWER feature\n"); 
+ port_stat->wPortStatus &= ~(USB_SS_PORT_STAT_POWER); 
+ break; 
+ case USB_PORT_FEAT_C_CONNECTION: 
+ mausb_dbg(mhcd, "clearing PORT_C_CONNECTION feature\n"); 
+ port_stat->wPortChange &= ~(USB_PORT_STAT_C_CONNECTION); 
+ break; 
+ case USB_PORT_FEAT_C_RESET: 
+ mausb_dbg(mhcd, "clearing PORT_RESET feature\n"); 
+ port_stat->wPortStatus &= ~(USB_PORT_STAT_RESET); 
+ port_stat->wPortChange &= ~(USB_PORT_STAT_C_RESET); 
+ /* prevent excessive polling after reset */ 
+ clear_bit(HCD_FLAG_POLL_RH, &hcd->flags); 
+ break; 
+ case USB_PORT_FEAT_C_OVER_CURRENT: 
+ mausb_dbg(mhcd, "clearing PORT_OVER_CURRENT feature\n"); 
+ port_stat->wPortChange &= ~(USB_PORT_STAT_C_OVERCURRENT); 
+ case USB_PORT_FEAT_C_PORT_LINK_STATE: 
+ case USB_PORT_FEAT_C_PORT_CONFIG_ERROR: 
+ case USB_PORT_FEAT_C_BH_PORT_RESET: 
+ break; 
+ default: 
+ err = -EINVAL; 
+ break; 
+ } 
+ 
+ return err; 
+} 
+ 
+/** 
+ * Handles getDescriptor requests to the roothub. 
+ * 
+ * @ma_hcd: MA USB hcd that owns hub. 
+ * @wValue: Contains descriptor type in upper byte (see USB 3.0 spec for 
+ * descriptor types). 
+ * @buf: Holds descriptor to return to caller. 
+ * @wLength: Expected descriptor length. 
+ * 
+ * If successful, returns actual length of descriptor in buf. Otherwise returns 
+ * error value. 
+ */ 
+static int mausb_get_descriptor(struct mausb_hcd *ma_hcd, u16 wValue, 
+ char *buf, u16 wLength) 
+{ 
+ int ret; 
+ 
+ /* 
+ * per USB spec, section 9.4.3, the DT is contained in the upper byte 
+ * of wValue 
+ */ 
+ u8 bDesType = (wValue >> 8); 
+ 
+ switch (bDesType) { 
+ case USB_DT_DEVICE: 
+ mausb_err(ma_hcd, "USB_DT_DEVICE not supported\n"); 
+ ret = -EPIPE; 
+ break; 
+ case USB_DT_CONFIG: 
+ ret = 0; 
+ break; 
+ case USB_DT_BOS: 
+ ret = mausb_get_bos(ma_hcd, (struct mausb_host_bos *) buf, 
+ wLength); 
+ mausb_dbg(ma_hcd, "%s: bos copied to buffer, wTotalLength %x\n", 
+ __func__, 
+ ((struct mausb_host_bos *) buf)->bos_des.wTotalLength); 
+ break; 
+ case USB_DT_STRING: 
+ ret = 0; 
+ break; 
+ default: /* invalid request */ 
+ ret = -EINVAL; 
+ break; 
+ } 
+ 
+ return ret; 
+} 
+ 
+/** 
+ * Handles requests from usb core to hub. 
+ * 
+ * @hcd: USB hcd that owns hub. 
+ * @typeReq: Request type (see USB 3.0 spec for request types). 
+ * @wValue: Feature selector for hub/port feature requests, 
+ * descriptor type and index for hub descriptor requests, 
+ * hub depth for hub depth requests,zero for all other requests. 
+ * @wIndex: Port number for port requests, zero or language id for hub 
+ * descriptor requests, zero for all other requests. 
+ * @buf: Buffer for requested descriptor or status (if applicable). 
+ * @wLength: Descriptor length for descriptor requests, otherwise zero. 
+ * 
+ * Called by the USB core to make a request to the root hub. mausb_hub_control 
+ * parses the request and routes it to the appropriate mausb helper function. 
+ * 
+ * If successful, returns descriptor length for descriptor request or zero for 
+ * other requests. Otherwise returns error value. 
+ */ 
+int mausb_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, 
+ u16 wIndex, char *buf, u16 wLength) 
+{ 
+ int err = 0; 
+ int portnum = (wIndex & 0xFF); 
+ struct mausb_hcd *mhcd = usb_hcd_to_mausb_hcd(hcd); 
+ 
+ if (portnum > MAUSB_ROOTHUB_NUM_PORTS) { 
+ mausb_err(mhcd, "port number %d is invalid\n", portnum); 
+ return -EINVAL; 
+ } 
+ 
+ switch (typeReq) { 
+ case MAUSB_REQ_GET_DES: 
+ err = mausb_get_descriptor(usb_hcd_to_mausb_hcd(hcd), 
+ wValue, buf, wLength); 
+ err = sizeof(struct mausb_host_bos); 
+ break; 
+ case ClearHubFeature: 
+ mausb_dbg(mhcd, "clearing hub feature %d\n", wValue); 
+ err = mausb_clear_hub_feature(hcd, wValue); 
+ break; 
+ case ClearPortFeature: 
+ mausb_dbg(mhcd, "clearing port %d feature %d\n", portnum, 
+ wValue); 
+ err = mausb_clear_port_feature(hcd, portnum, wValue); 
+ break; 
+ case GetHubDescriptor: 
+ err = mausb_get_hub_descriptor(hcd, 
+ (struct usb_hub_descriptor *) buf, wLength); 
+ break; 
+ case GetHubStatus: 
+ mausb_dbg(mhcd, "getting hub status\n"); 
+ err = mausb_get_hub_status(hcd, buf); 
+ break; 
+ case GetPortStatus: 
+ mausb_dbg(mhcd, "getting port %d status\n", portnum); 
+ err = mausb_get_port_status(hcd, portnum, buf); 
+ break; 
+ /* SetHubFeature support is optional (only used for diagnostics) */ 
+ case SetHubFeature: 
+ err = 0; 
+ break; 
+ case SetPortFeature: 
+ mausb_dbg(mhcd, "setting port %d feature %d\n", portnum, 
+ wValue); 
+ mausb_set_port_feature(hcd, portnum, wValue, wIndex); 
+ break; 
+ case SetHubDepth: 
+ err = 0; 
+ break; 
+ case GetPortErrorCount: 
+ err = 0; 
+ break; 
+ default: 
+ err = -EINVAL; 
+ break; 
+ } 
+ 
+ return err; 
+} 
+ 
+MODULE_LICENSE("Dual BSD/GPL"); 
+MODULE_AUTHOR("Intel"); 
+MODULE_DESCRIPTION("mausb driver"); 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/drivers/mausb_hub.h linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/drivers/mausb_hub.h
--- linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/drivers/mausb_hub.h	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/drivers/mausb_hub.h	2014-11-28 12:39:00.572447000 +0800
@@ -0,0 +1,128 @@
+/* name: mausb_hub.h 
+ * description: header file for mausb hub 
+ * 
+ * This file is provided under a dual BSD/GPLv2 license. When using or 
+ * redistributing this file, you may do so under either license. 
+ * 
+ * GPL LICENSE SUMMARY 
+ * 
+ * Copyright(c) 2014 Intel Corporation. 
+ * 
+ * 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. 
+ * 
+ * Contact Information: 
+ * Sean Stalley, sean.stalley [at] intel 
+ * Stephanie Wallick, stephanie.s.wallick [at] intel 
+ * 2111 NE 25th Avenue 
+ * Hillsboro, Oregon 97124 
+ * 
+ * BSD LICENSE 
+ * 
+ * Copyright(c) 2014 Intel Corporation. 
+ * 
+ * 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 of Intel Corporation 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. 
+ */ 
+ 
+#ifndef __MAUSB_HUB_H 
+#define __MAUSB_HUB_H 
+ 
+#include <linux/init.h> 
+#include <linux/module.h> 
+#include <linux/usb.h> 
+#include <linux/usb/hcd.h> 
+#include <linux/platform_device.h> 
+#include <linux/usb/ch11.h> 
+ 
+/* root hub Parameters */ 
+#define MAUSB_ROOTHUB_CHAR (HUB_CHAR_LPSM | HUB_CHAR_INDV_PORT_OCPM) 
+#define MAUSB_ROOTHUB_NUM_PORTS 1 
+#define MAUSB_ROOTHUB_PWR_ON_2_PWR_GOOD 0 
+#define MAUSB_ROOTHUB_CONTR_CURRENT 0 
+#define MAUSB_ROOTHUB_HDR_DEC_LAT 0 /* < 0 uS */ 
+#define MAUSB_ROOTHUB_DELAY 0 /* 0 nS */ 
+#define MAUSB_ALL_DEV_REMOVABLE 0x0000 /* All devices are removable */ 
+ 
+/* per USB3 spec, section 9.4.3 */ 
+#define MAUSB_REQ_GET_DES (0x8000 | USB_REQ_GET_DESCRIPTOR) 
+ 
+/* link state selectors for set_port_feature request to root hub */ 
+#define SS_DISABLED 4 
+#define RX_DETECT 5 
+ 
+/* mask used to clear port link state bits (bits 5-8) in wPortStatus */ 
+#define LINK_STATE_MASK 0xFE1F 
+ 
+/* forward declarations */ 
+struct mausb_root_hub; 
+struct mausb_hcd; 
+ 
+/* root hub states */ 
+enum mausb_rh_state { 
+ MAUSB_RH_RESETTING, 
+ MAUSB_RH_SUSPEND, 
+ MAUSB_RH_RUNNING 
+}; 
+ 
+/** 
+ * Contains all the structures required to emulate a root hub. One instance 
+ * exists per root hub. 
+ */ 
+struct __attribute__((__packed__)) mausb_root_hub { 
+ 
+ /* hub parameters */ 
+ struct usb_hub_descriptor descriptor; 
+ struct usb_hub_status status; 
+ 
+ /* port parameters*/ 
+ struct usb_port_status port_status[MAUSB_ROOTHUB_NUM_PORTS]; 
+ 
+ /* root hub state */ 
+ enum mausb_rh_state rh_state; 
+ 
+}; 
+ 
+/* function declarations */ 
+bool mausb_is_ss_hcd(struct usb_hcd *hcd); 
+int mausb_hub_status_data(struct usb_hcd *hcd, char *buf); 
+int mausb_set_hub_descriptor(struct usb_hub_descriptor *hub_des); 
+int mausb_set_ss_hub_descriptor(struct usb_hub_descriptor *hub_des); 
+int mausb_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, 
+ u16 wIndex, char *buf, u16 wLength); 
+int mausb_init_port_status(struct mausb_root_hub *mausb_rh); 
+int mausb_init_ss_port_status(struct mausb_root_hub *mausb_rh); 
+int mausb_connect(struct mausb_hcd *hcd, int portnum, int do_connect); 
+struct mausb_root_hub *usb_hcd_to_roothub(struct usb_hcd *hcd); 
+ 
+ 
+#endif 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/drivers/mausb_ioctl.c linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/drivers/mausb_ioctl.c
--- linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/drivers/mausb_ioctl.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/drivers/mausb_ioctl.c	2014-11-28 12:39:00.572447000 +0800
@@ -0,0 +1,256 @@
+/* Name: mausb_ioctl.c 
+ * Description: ioctl functions for MA USB media specific driver 
+ * 
+ * This file is provided under a dual BSD/GPLv2 license. When using or 
+ * redistributing this file, you may do so under either license. 
+ * 
+ * GPL LICENSE SUMMARY 
+ * 
+ * Copyright(c) 2014 Intel Corporation. 
+ * 
+ * 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. 
+ * 
+ * Contact Information: 
+ * Sean Stalley, sean.stalley [at] intel 
+ * Stephanie Wallick, stephanie.s.wallick [at] intel 
+ * 2111 NE 25th Avenue 
+ * Hillsboro, Oregon 97124 
+ * 
+ * BSD LICENSE 
+ * 
+ * Copyright(c) 2014 Intel Corporation. 
+ * 
+ * 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 of Intel Corporation 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/ioctl.h> 
+#include <linux/kernel.h> 
+#include <linux/fs.h> 
+#include <linux/kernel.h> 
+#include <linux/fs.h> 
+#include <linux/usb/gadget.h> 
+#include <linux/init.h> 
+#include <linux/module.h> 
+#include <asm/uaccess.h> 
+#include "mausb_hcd.h" 
+#include "mausb_udc.h" 
+#include "mausb_ioctl.h" 
+ 
+/* #define MAUSB_PRINT_IOCTL_MAGIC */ 
+#define DEBUG 
+ 
+static int ma_open; 
+ 
+/** 
+ * This function is used to open the device file in order to read/write 
+ * from/to it. 
+ * 
+ * @inode: Struct with various information that is passed in when this 
+ * function is called. We don't need to use it for our purposes. 
+ * @file: The file to be opened. 
+ */ 
+static int mausb_open(struct inode *inode, struct file *file) 
+{ 
+ if (ma_open) 
+ return -EBUSY; 
+ ma_open++; 
+ try_module_get(THIS_MODULE); 
+ 
+ return 0; 
+} 
+ 
+/** 
+ * This function is used to close the device file. 
+ * 
+ * @inode: Struct with various information that is passed in when this 
+ * function is called. We don't need to use it for our purposes. 
+ * @file: The file to be closed. 
+ */ 
+static int mausb_release(struct inode *inode, struct file *file) 
+{ 
+ ma_open--; 
+ module_put(THIS_MODULE); 
+ 
+ return 0; 
+} 
+ 
+ 
+/** 
+ * This function is used to execute ioctl commands, determined by ioctl_func. 
+ * 
+ * @file: The device file. We don't use it directly, but it's passed in. 
+ * @ioctl_func: This value determines which ioctl function will be used. 
+ * @ioctl_buffer: This buffer is used to transfer data to/from the device. 
+ */ 
+long mausb_ioctl(struct file *file, unsigned int ioctl_func, 
+ unsigned long ioctl_buffer) 
+{ 
+ char message[BUFFER]; 
+ int ret, value; 
+ unsigned long int long_value; 
+ char __user *msg = (char *)ioctl_buffer; 
+ char *response; 
+ 
+ switch (ioctl_func) { 
+ case IOCTL_GET_VRSN: 
+ ret = copy_to_user(msg, DRIVER_VERSION, strlen(DRIVER_VERSION)); 
+ break; 
+ case IOCTL_GET_NAME: 
+ ret = copy_to_user(msg, MAUSB_NAME, strlen(MAUSB_NAME)); 
+ break; 
+ case IOCTL_GADGET_C: 
+ ret = gadget_connection(1); 
+ if (ret >= 0) 
+ response = MAUSB_GADGET_C_SUCCESS; 
+ else 
+ response = MAUSB_GADGET_C_FAIL; 
+ 
+ ret = copy_to_user(msg, response, strlen(response)); 
+ break; 
+ case IOCTL_GADGET_D: 
+ ret = gadget_connection(0); 
+ if (ret >= 0) 
+ response = MAUSB_GADGET_D_SUCCESS; 
+ else 
+ response = MAUSB_GADGET_D_FAIL; 
+ 
+ ret = copy_to_user(msg, response, strlen(response)); 
+ break; 
+ case IOCTL_SET_PORT: 
+ ret = strncpy_from_user(message, msg, BUFFER); 
+ if (ret < 0) 
+ break; 
+ ret = kstrtoint(msg, 0, &value); 
+ if (ret != 0) 
+ break; 
+ 
+ ret = set_port_no(value); 
+ sprintf(message, "PORT NUMBER:%d, Returned %i\n", value, 
+ ret); 
+ ret = copy_to_user(msg, message, strlen(message)); 
+ break; 
+ case IOCTL_SET_IP: 
+ ret = strncpy_from_user(message, msg, BUFFER); 
+ if (ret < 0) 
+ break; 
+ ret = kstrtoul(message, 0, &long_value); 
+ if (ret != 0) 
+ break; 
+ 
+ ret = set_ip_addr(long_value); 
+ sprintf(message, "IP ADDRESS:%lx, returned %i\n", 
+ long_value, ret); 
+ ret = copy_to_user(msg, message, strlen(message)); 
+ break; 
+ case IOCTL_SET_MAC: 
+ { 
+ u8 mac[6]; 
+ int i; 
+ ret = copy_from_user(mac, msg, 6); 
+ if (ret) { 
+ pr_err("copy_from_user failed\n"); 
+ break; 
+ } 
+ for (i = 0; i < ETH_ALEN; i++) 
+ pr_info("mac[%d]=0x%x\n", i, mac[i]); 
+ ret = set_mac_addr(mac); 
+ if (ret) 
+ pr_err("unable to set MAC addr\n"); 
+ 
+ break; 
+ } 
+ } 
+ 
+ /* failure */ 
+ if (ret < 0) 
+ return ret; 
+ 
+ /* success */ 
+ return 0; 
+} 
+ 
+/** 
+ * This struct creates links with our implementations of various entry point 
+ * functions. 
+ */ 
+const struct file_operations fops = { 
+ .open = mausb_open, 
+ .release = mausb_release, 
+ .unlocked_ioctl = mausb_ioctl 
+}; 
+ 
+/** 
+ * Registers a character device using our device file. This function is called 
+ * in the mausb_hcd_init function. 
+ */ 
+int reg_chrdev() 
+{ 
+ int ret; 
+ 
+#ifdef MAUSB_PRINT_IOCTL_MAGIC 
+ 
+ printk(KERN_DEBUG "Printing IOCTL magic numbers:\n"); 
+ printk(KERN_DEBUG "IOCTL_SET_MSG = %u\n", IOCTL_SET_MSG); 
+ printk(KERN_DEBUG "IOCTL_GET_MSG = %u\n", IOCTL_GET_MSG); 
+ printk(KERN_DEBUG "IOCTL_GET_VRSN = %u\n", IOCTL_GET_VRSN); 
+ printk(KERN_DEBUG "IOCTL_GET_NAME = %u\n", IOCTL_GET_NAME); 
+ printk(KERN_DEBUG "IOCTL_GADGET_C = %u\n", IOCTL_GADGET_C); 
+ printk(KERN_DEBUG "IOCTL_GADGET_D = %u\n", IOCTL_GADGET_D); 
+ printk(KERN_DEBUG "IOCTL_MED_DELAY = %u\n", IOCTL_MED_DELAY); 
+ printk(KERN_DEBUG "IOCTL_SET_IP = %u\n", IOCTL_SET_IP); 
+ printk(KERN_DEBUG "IOCTL_SET_PORT = %u\n", IOCTL_SET_PORT); 
+ printk(KERN_DEBUG "IOCTL_SET_IP_DECIMAL = %u\n", IOCTL_SET_IP_DECIMAL); 
+ printk(KERN_DEBUG "IOCTL_SET_MAC = %u\n", IOCTL_SET_MAC); 
+ 
+#endif 
+ 
+ ret = register_chrdev(MAJOR_NUM, MAUSB_NAME, &fops); 
+ 
+ if (ret < 0) 
+ printk(KERN_ALERT "Registering mausb failed with %d\n", ret); 
+ else 
+ printk(KERN_INFO "%s registeration complete. Major device" 
+ " number %d.\n", MAUSB_NAME, MAJOR_NUM); 
+ 
+ return ret; 
+} 
+ 
+/** 
+ * Unregisters the character device when the hcd is unregistered. As hinted, 
+ * this function is called in the mausb_hcd_exit function. 
+ */ 
+void unreg_chrdev() 
+{ 
+ unregister_chrdev(MAJOR_NUM, MAUSB_NAME); 
+} 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/drivers/mausb_ioctl.h linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/drivers/mausb_ioctl.h
--- linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/drivers/mausb_ioctl.h	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/drivers/mausb_ioctl.h	2014-11-28 12:39:00.572447000 +0800
@@ -0,0 +1,101 @@
+/* Name: mausb_ioctl.h 
+ * Description: header file for MA USB ioctl functions 
+ * 
+ * This file is provided under a dual BSD/GPLv2 license. When using or 
+ * redistributing this file, you may do so under either license. 
+ * 
+ * GPL LICENSE SUMMARY 
+ * 
+ * Copyright(c) 2014 Intel Corporation. 
+ * 
+ * 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. 
+ * 
+ * Contact Information: 
+ * Sean Stalley, sean.stalley [at] intel 
+ * Stephanie Wallick, stephanie.s.wallick [at] intel 
+ * 2111 NE 25th Avenue 
+ * Hillsboro, Oregon 97124 
+ * 
+ * BSD LICENSE 
+ * 
+ * Copyright(c) 2014 Intel Corporation. 
+ * 
+ * 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 of Intel Corporation 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. 
+ */ 
+ 
+#ifndef MAUSB_IOCTL_H 
+#define MAUSB_IOCTL_H 
+ 
+#define BUFFER 80 
+#define DRIVER_VERSION "Alpha 0.0.25" 
+#define MAJOR_NUM 100 
+ 
+/* These define the ioctl functions that can be used. */ 
+#define IOCTL_GET_VRSN _IOR(MAJOR_NUM, 0, char *) 
+#define IOCTL_GET_NAME _IOR(MAJOR_NUM, 1, char *) 
+#define IOCTL_GADGET_C _IOR(MAJOR_NUM, 2, char *) 
+#define IOCTL_GADGET_D _IOR(MAJOR_NUM, 3, char *) 
+#define IOCTL_SET_IP _IOR(MAJOR_NUM, 4, char *) 
+#define IOCTL_SET_PORT _IOR(MAJOR_NUM, 5, char *) 
+#define IOCTL_SET_MAC _IOR(MAJOR_NUM, 6, char *) 
+ 
+/* This is the location where the device file will be created. It is used to 
+ * read/write to in order to communicate to and from the device. */ 
+#define DEVICE_FILE_NAME "/dev/mausb" 
+ 
+/* MAC address length */ 
+#define ETH_ALEN 6 
+ 
+/* Responses to IOCTL calls */ 
+#define MAUSB_GADGET_C_SUCCESS "gadget connect process complete" 
+#define MAUSB_GADGET_C_FAIL "gadget connect process failed" 
+#define MAUSB_GADGET_D_SUCCESS "gadget disconnect process complete" 
+#define MAUSB_GADGET_D_FAIL "gadget disconnect process failed" 
+ 
+/* forward declarations */ 
+struct mausb_udc; 
+struct mausb_hcd; 
+ 
+/* Functions for register/unregistering the character device */ 
+int reg_chrdev(void); 
+void unreg_chrdev(void); 
+ 
+/* Medium-defined functions */ 
+int set_medium_delay(int delay); 
+int set_ip_addr(unsigned long in_addr); 
+int set_port_no(int port_no); 
+int set_mac_addr(unsigned char mac_addr[ETH_ALEN]); 
+int gadget_connection(int on); 
+ 
+#endif 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/drivers/mausb_mem.c linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/drivers/mausb_mem.c
--- linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/drivers/mausb_mem.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/drivers/mausb_mem.c	2014-11-28 12:39:00.572447000 +0800
@@ -0,0 +1,842 @@
+/* Name: mausb_mem.c 
+ * Description: Handles all of the dynamic data structures for the host 
+ * controller, including any data that needs to exist 
+ * on a per-device, per-endpoint, or per-transfer basis. 
+ * 
+ * This file is provided under a dual BSD/GPLv2 license. When using or 
+ * redistributing this file, you may do so under either license. 
+ * 
+ * GPL LICENSE SUMMARY 
+ * 
+ * Copyright(c) 2014 Intel Corporation. 
+ * 
+ * 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. 
+ * 
+ * Contact Information: 
+ * Sean Stalley, sean.stalley [at] intel 
+ * Stephanie Wallick, stephanie.s.wallick [at] intel 
+ * 2111 NE 25th Avenue 
+ * Hillsboro, Oregon 97124 
+ * 
+ * BSD LICENSE 
+ * 
+ * Copyright(c) 2014 Intel Corporation. 
+ * 
+ * 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 of Intel Corporation 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/slab.h> 
+#include <linux/usb.h> 
+#include <linux/kthread.h> 
+ 
+#include "mausb_mem.h" 
+#include "mausb_mgmt.h" 
+#include "mausb_tx.h" 
+#include "mausb_pkt.h" 
+#include "mausb_const.h" 
+#include "mausb_hcd.h" 
+ 
+struct mausb_host_ep *mausb_state_to_ep(struct mausb_ep_state *state) 
+{ 
+ return container_of(state, struct mausb_host_ep, state); 
+} 
+EXPORT_SYMBOL(mausb_state_to_ep); 
+ 
+struct mausb_hcd *mausb_host_ep_to_mahcd(struct mausb_host_ep *ep) 
+{ 
+ return ep->mausb_dev->ma_dev->mhcd; 
+} 
+EXPORT_SYMBOL(mausb_host_ep_to_mahcd); 
+ 
+struct mausb_udc *mausb_host_ep_to_maudc(struct mausb_host_ep *ep) 
+{ 
+ return ep->mausb_dev->ma_dev->maudc; 
+} 
+EXPORT_SYMBOL(mausb_host_ep_to_maudc); 
+ 
+struct ma_dev *context_to_ma_dev(void *context) 
+{ 
+ return (struct ma_dev *) context; 
+} 
+ 
+/* 
+ * Finds the media-agnostic data for a given device. 
+ * 
+ * @ma_dev: The MA USB device the USB device is located behind. 
+ * @dev: The USB device to find. 
+ * @handle: The MA USB device handle of USB device to find. 
+ * @gadget: The USB gadget device to find. 
+ * 
+ * Returns a pointer to the media agnostic data for a USB device given one or 
+ * more parameters. Returns NULL if the device cannot be found. 
+ */ 
+struct mausb_dev *mausb_find_dev(struct ma_dev *ma_dev, 
+ struct usb_device *dev, unsigned long *handle, 
+ struct usb_gadget *gadget) 
+{ 
+ struct mausb_dev *mausb_dev; 
+ unsigned long irq_flags; 
+ 
+ spin_lock_irqsave(&ma_dev->ma_dev_lock, irq_flags); 
+ list_for_each_entry(mausb_dev, &ma_dev->dev_list, dev_list) { 
+ 
+ /* if found */ 
+ if ((NULL != dev && mausb_dev->dev == dev) || 
+ (NULL != gadget && mausb_dev->gadget == gadget) || 
+ (NULL != handle && mausb_dev->dev_handle == *handle)) { 
+ spin_unlock_irqrestore(&ma_dev->ma_dev_lock, irq_flags); 
+ return mausb_dev; 
+ } 
+ } 
+ spin_unlock_irqrestore(&ma_dev->ma_dev_lock, irq_flags); 
+ 
+ /* device not found */ 
+ return NULL; 
+} 
+ 
+struct mausb_dev *mausb_find_dev_host(struct ma_dev *ma_dev, 
+ struct usb_device *dev) 
+{ 
+ return mausb_find_dev(ma_dev, dev, NULL, NULL); 
+} 
+EXPORT_SYMBOL(mausb_find_dev_host); 
+ 
+/** 
+ * Returns true if usb_endpoint descriptors are the same. 
+ */ 
+static bool mausb_ep_desc_eq(const struct usb_endpoint_descriptor *desc1, 
+ const struct usb_endpoint_descriptor *desc2) 
+{ 
+ return ((desc1->bLength == desc2->bLength) 
+ && (desc1->bDescriptorType == desc2->bDescriptorType) 
+ && (desc1->bEndpointAddress == desc2->bEndpointAddress) 
+ && (desc1->bmAttributes == desc2->bmAttributes) 
+ && (desc1->wMaxPacketSize == desc2->wMaxPacketSize)); 
+} 
+ 
+/** 
+ * Finds the media agnostic data for an endpoint given one or more parameters. 
+ * 
+ * @ep: USB host endpoint to find MA USB endpoint for. 
+ * @dev_ep: USB device endpoint to find MA USB endpoint for. 
+ * @handle: Endpoint handle of MA USB endpoint. 
+ * @mausb_dev: The MA USB device the endpoint belongs to. 
+ * @ep_desc: endpoint descriptor for USB endpoint. 
+ * @address: MA USB endpoint address. 
+ * 
+ * Returns a pointer to the media agnostic data for the endpoint or NULL if 
+ * the device cannot be found. 
+ */ 
+static struct mausb_host_ep *mausb_find_ep(struct usb_host_endpoint *ep, 
+ struct usb_ep *dev_ep, struct mausb_ep_handle *handle, 
+ struct mausb_dev *mausb_dev, 
+ const struct usb_endpoint_descriptor *ep_desc, 
+ u8 address) 
+{ 
+ struct mausb_host_ep *ma_ep; 
+ unsigned long irq_flags; 
+ 
+ spin_lock_irqsave(&mausb_dev->dev_lock, irq_flags); 
+ list_for_each_entry(ma_ep, &mausb_dev->ep_list, ep_list) { 
+ 
+ /* if found */ 
+ if ((NULL != dev_ep && ma_ep->dev_ep == dev_ep) || 
+ (NULL != ep && ma_ep->ep == ep) || 
+ (NULL != handle 
+ && ma_ep->ep_handle_state != MAUSB_EP_HANDLE_UNASSIGNED 
+ && ma_ep->ep_handle.handle == handle->handle) || 
+ (NULL != ep_desc && NULL != ma_ep->ep 
+ && mausb_ep_desc_eq(ep_desc, &ma_ep->ep->desc)) || 
+ (NULL != ep_desc && NULL != ma_ep->dev_ep && 
+ NULL != ma_ep->dev_ep->desc 
+ && mausb_ep_desc_eq(ep_desc, ma_ep->dev_ep->desc)) || 
+ (address != 0 && NULL != ma_ep->dev_ep && 
+ address == ma_ep->dev_ep->address)) { 
+ 
+ spin_unlock_irqrestore(&mausb_dev->dev_lock, irq_flags); 
+ return ma_ep; 
+ } 
+ } 
+ 
+ spin_unlock_irqrestore(&mausb_dev->dev_lock, irq_flags); 
+ 
+ /* endpoint not found */ 
+ return NULL; 
+} 
+ 
+struct mausb_host_ep *mausb_find_ep_dev(struct usb_ep *dev_ep, 
+ struct mausb_dev *mausb_dev) 
+{ 
+ return mausb_find_ep(NULL, dev_ep, NULL, mausb_dev, NULL, 0); 
+} 
+EXPORT_SYMBOL(mausb_find_ep_dev); 
+ 
+struct mausb_host_ep *mausb_find_ep_host(struct usb_host_endpoint *ep, 
+ struct mausb_dev *mausb_dev) 
+{ 
+ return mausb_find_ep(ep, NULL, NULL, mausb_dev, NULL, 0); 
+} 
+EXPORT_SYMBOL(mausb_find_ep_host); 
+ 
+struct mausb_host_ep *mausb_find_ep_by_desc( 
+ const struct usb_endpoint_descriptor *ep_desc, 
+ struct mausb_dev *mausb_dev) 
+ 
+{ 
+ return mausb_find_ep(NULL, NULL, NULL, mausb_dev, ep_desc, 0); 
+} 
+EXPORT_SYMBOL(mausb_find_ep_by_desc); 
+ 
+struct mausb_host_ep *mausb_find_ep_by_handle(struct mausb_ep_handle *handle, 
+ struct mausb_dev *mausb_dev) 
+{ 
+ return mausb_find_ep(NULL, NULL, handle, mausb_dev, NULL, 0); 
+} 
+EXPORT_SYMBOL(mausb_find_ep_by_handle); 
+ 
+struct mausb_host_ep *mausb_find_ep_by_address(u8 address, 
+ struct mausb_dev *mausb_dev) 
+ 
+{ 
+ return mausb_find_ep(NULL, NULL, NULL, mausb_dev, NULL, address); 
+} 
+EXPORT_SYMBOL(mausb_find_ep_by_address); 
+ 
+struct mausb_host_ep *mausb_find_ep_from_handle(struct mausb_ep_handle handle, 
+ struct ma_dev *ma_dev) 
+{ 
+ struct mausb_host_ep *ma_ep; 
+ struct mausb_dev *mausb_dev; 
+ unsigned long irq_flags; 
+ 
+ spin_lock_irqsave(&ma_dev->ma_dev_lock, irq_flags); 
+ list_for_each_entry(mausb_dev, &ma_dev->dev_list, dev_list) { 
+ spin_unlock_irqrestore(&ma_dev->ma_dev_lock, irq_flags); 
+ 
+ ma_ep = mausb_find_ep_by_handle(&handle, mausb_dev); 
+ if (ma_ep != NULL) 
+ return ma_ep; 
+ 
+ spin_lock_irqsave(&ma_dev->ma_dev_lock, irq_flags); 
+ } 
+ spin_unlock_irqrestore(&ma_dev->ma_dev_lock, irq_flags); 
+ 
+ return NULL; 
+} 
+ 
+/** 
+ * Wrapper function to be used by devices when they want to generate an 
+ * ma packet. 
+ */ 
+struct mausb_pkt *mausb_pkt_from_ms_pkt_ma_dev(struct ms_pkt *ms_pkt, 
+ struct ma_dev *ma_dev, gfp_t mem_flags) 
+{ 
+ return mausb_pkt_from_ms_pkt(ms_pkt, 
+ ma_dev->ms_driver->ops->pkt_destructor, mem_flags); 
+} 
+EXPORT_SYMBOL(mausb_pkt_from_ms_pkt_ma_dev); 
+ 
+/** 
+ * Wrapper to be used by endpoints when they want to generate an ma packet. 
+ */ 
+struct mausb_pkt *mausb_pkt_from_ms_pkt_ep(struct ms_pkt *ms_pkt, 
+ struct mausb_host_ep *ep, gfp_t mem_flags) 
+{ 
+ return mausb_pkt_from_ms_pkt_ma_dev(ms_pkt, ep->mausb_dev->ma_dev, 
+ mem_flags); 
+} 
+EXPORT_SYMBOL(mausb_pkt_from_ms_pkt_ep); 
+ 
+const struct usb_endpoint_descriptor *mausb_get_ep_des( 
+ struct mausb_host_ep *ma_ep) 
+{ 
+ if ((NULL != ma_ep->ep && NULL != ma_ep->dev_ep) || 
+ (NULL == ma_ep->ep && NULL == ma_ep->dev_ep)) { 
+ 
+ mamem_err("%s: ERROR: ep = 0x%p, dev_ep = 0x%p " 
+ "(only one should be set)\n", __func__, 
+ ma_ep->ep, ma_ep->dev_ep); 
+ 
+ return NULL; 
+ } 
+ 
+ if (NULL != ma_ep->ep) 
+ return &ma_ep->ep->desc; 
+ 
+ if (NULL != ma_ep->dev_ep) 
+ return ma_ep->dev_ep->desc; 
+ 
+ /* We should never get here */ 
+ BUG(); 
+ return NULL; 
+} 
+EXPORT_SYMBOL(mausb_get_ep_des); 
+ 
+/** 
+ * Fills an MA USB packet header for the given maurb 
+ */ 
+static int fill_mausb_dph(struct mausb_dph *ma_pkt, struct mausb_urb *maurb, 
+ bool in, bool host) 
+{ 
+ const struct usb_endpoint_descriptor *ep_des; 
+ unsigned long irq_flags; 
+ 
+ /* set the version number */ 
+ ma_pkt->common.ver_flags = MAUSB_VERSION_1_0 & MAUSB_VERSION_MASK; 
+ 
+ /* set the host flag if from the host */ 
+ ma_pkt->common.ver_flags |= host ? MAUSB_PKT_FLAG_HOST : 0; 
+ 
+ /* set the device handle field */ 
+ spin_lock_irqsave(&maurb->ep->ep_lock, irq_flags); 
+ ma_pkt->common.ep_handle = maurb->ep->ep_handle; 
+ spin_unlock_irqrestore(&maurb->ep->ep_lock, irq_flags); 
+ 
+ ma_pkt->common.pkt_status = SUCCESS; 
+ 
+ ep_des = mausb_get_ep_des(maurb->ep); 
+ 
+ /* set transfer type in tflags field */ 
+ switch (usb_endpoint_type(ep_des)) { 
+ case USB_ENDPOINT_XFER_CONTROL: 
+ ma_pkt->eps_tflags |= MAUSB_PKT_TFLAG_TYPE_CTRL; 
+ break; 
+ case USB_ENDPOINT_XFER_ISOC: 
+ ma_pkt->eps_tflags |= MAUSB_PKT_TFLAG_TYPE_ISOC; 
+ break; 
+ case USB_ENDPOINT_XFER_BULK: 
+ ma_pkt->eps_tflags |= MAUSB_PKT_TFLAG_TYPE_BULK; 
+ break; 
+ case USB_ENDPOINT_XFER_INT: 
+ ma_pkt->eps_tflags |= MAUSB_PKT_TFLAG_TYPE_INT; 
+ break; 
+ default: 
+ mamem_err("%s: invalid transfer type\n", __func__); 
+ } 
+ 
+ return 0; 
+} 
+ 
+/** 
+ * Create a datapacket from a given URB. 
+ */ 
+struct mausb_pkt *mausb_create_dp(int *status, struct mausb_urb *maurb, 
+ bool in, bool host, gfp_t memflags) 
+{ 
+ struct mausb_pkt *pkt; 
+ int ret = 0; 
+ 
+ pkt = mausb_alloc_pkt(MAUSB_PKT_TYPE_DATA, status, memflags); 
+ if (NULL == pkt) { 
+ mamem_err("%s:failed to allocate memory for mausb packet\n", 
+ __func__); 
+ 
+ if (NULL != status) 
+ *status = -ENOMEM; 
+ 
+ return NULL; 
+ } 
+ 
+ ret = fill_mausb_dph(pkt->data, maurb, in, host); 
+ INIT_LIST_HEAD(&pkt->pkt_list); 
+ if (NULL != status) 
+ *status = ret; 
+ 
+ return pkt; 
+} 
+EXPORT_SYMBOL(mausb_create_dp); 
+ 
+struct mausb_urb *mausb_alloc_maurb(struct mausb_host_ep *ma_ep, gfp_t memflags) 
+{ 
+ struct mausb_urb *maurb; 
+ 
+ maurb = kzalloc(sizeof(struct mausb_urb), memflags); 
+ if (!maurb) 
+ return NULL; 
+ 
+ INIT_LIST_HEAD(&maurb->urb_list); 
+ maurb->ep = ma_ep; 
+ maurb->dev = ma_ep->mausb_dev; 
+ 
+ return maurb; 
+} 
+EXPORT_SYMBOL(mausb_alloc_maurb); 
+ 
+/** 
+ * Deletes the given maurb and removes all pointers to it from memory. 
+ */ 
+int mausb_internal_drop_maurb(struct mausb_urb *maurb, struct mausb_hcd *mhcd) 
+{ 
+ struct mausb_host_ep *ep = maurb->ep; 
+ unsigned long irq_flags; 
+ 
+ spin_lock_irqsave(&ep->ep_lock, irq_flags); 
+ 
+ list_del(&maurb->urb_list); 
+ if (maurb == ep->active_transfer) 
+ ep->active_transfer = NULL; 
+ 
+ spin_unlock_irqrestore(&ep->ep_lock, irq_flags); 
+ 
+ spin_lock_irqsave(&mhcd->urb_list_lock, irq_flags); 
+ list_del(&maurb->ma_hcd_urb_list); 
+ spin_unlock_irqrestore(&mhcd->urb_list_lock, irq_flags); 
+ 
+ /* 
+ * Nobody else should know this maurb exists, so it should be 
+ * safe to free 
+ */ 
+ kfree(maurb); 
+ 
+ return 0; 
+} 
+EXPORT_SYMBOL(mausb_internal_drop_maurb); 
+ 
+/** 
+ * Sets endpoint state to default. 
+ * 
+ * @state: State of endpoint to be configured. 
+ * @buf_size: The maximum number of Bytes the device-side buffer 
+ * can receive from the host. 
+ * 
+ * Called whenever an MA USB endpoint is configured and needs to be set 
+ * or reset to its initial state. 
+ */ 
+void init_ep_state(struct mausb_ep_state *state, u32 buf_size) 
+{ 
+ state->request_id = 0; 
+ state->active_request_id = 0; 
+ state->seq_number = 0; 
+ state->tx_pending = 0; 
+ state->earliest_request_id = 0; 
+ state->earliest_unacked = 0; 
+ state->occupancy = 0; 
+ state->rx_buf_size = buf_size; 
+ state->keep_alive_timer = MAUSB_TRANSFER_KEEP_ALIVE; 
+ state->retry_counter = MAUSB_BULK_TRANSFER_RETRIES; 
+ /* TODO: number of retries depends on transfer type, include 
+ * other transfer types (control and interrupt) */ 
+} 
+ 
+struct mausb_gadget_ep *usb_ep_to_mausb_gadget_ep(struct usb_ep *ep) 
+{ 
+ return container_of(ep, struct mausb_gadget_ep, dev_ep); 
+} 
+EXPORT_SYMBOL(usb_ep_to_mausb_gadget_ep); 
+ 
+/** 
+ * Links a Device-side endpoint to an MA USB endpoint 
+ */ 
+void mausb_link_ma_ep_to_usb_ep(struct mausb_host_ep *ma_ep, 
+ struct usb_ep *dev_ep) 
+{ 
+ struct mausb_gadget_ep *gadget_ep = usb_ep_to_mausb_gadget_ep(dev_ep); 
+ 
+ ma_ep->dev_ep = dev_ep; 
+ ma_ep->halted = 0; 
+ ma_ep->wedged = 0; 
+ 
+ ma_ep->usb_req_list = &gadget_ep->usb_req_list; 
+} 
+EXPORT_SYMBOL(mausb_link_ma_ep_to_usb_ep); 
+ 
+/* 
+ * Adds an endpoint to the specified device. 
+ * 
+ * @ma_dev: The usb device to add the endpoint to. 
+ * @ep/dev_ep: The usb struct for the endpoint being added. 
+ * Note: give only one of the endpoint pointers and 
+ * set the other to NULL. 
+ * @mausb_ep: The mausb_ep struct created by this function. 
+ * @transfer_timeout: The transfer timeout function. A thread will be 
+ * spawned with this function for handling timeouts. 
+ * 
+ * Adds the given endpoint to the given device. The difference between this 
+ * function and mausb_add_endpoint (which can be called from the usb core) 
+ * is that this uses the private ma-structs. Calling this function is 
+ * cheaper, and therefore preferred when possible, since mausb_add_endpoint 
+ * will have to find the internal structures. 
+ */ 
+int mausb_internal_add_ep(struct mausb_dev *ma_dev, 
+ struct usb_host_endpoint *ep, struct usb_ep *dev_ep, 
+ struct mausb_host_ep **mausb_ep, 
+ int (*transfer_timeout)(void *data), gfp_t memflags) 
+{ 
+ struct mausb_host_ep *ma_ep; 
+ unsigned long irq_flags; 
+ 
+ ma_ep = kzalloc(sizeof(struct mausb_host_ep), memflags); 
+ if (!ma_ep) 
+ return -ENOMEM; 
+ 
+ /* host operations */ 
+ if (ep != NULL) { 
+ ep->hcpriv = ma_ep; 
+ ma_ep->ep = ep; 
+ 
+ /* device operations */ 
+ } else if (dev_ep != NULL) 
+ mausb_link_ma_ep_to_usb_ep(ma_ep, dev_ep); 
+ 
+ ma_ep->mausb_dev = ma_dev; 
+ 
+ /* set initial EP State */ 
+ init_ep_state(&ma_ep->state, DEVICE_RX_BUF_SIZE); 
+ 
+ /* 
+ * only used by full speed devices to determine if the max packet 
+ * size has changed for EP0 
+ */ 
+ ma_ep->max_pkt = 8; 
+ 
+ /* initialize mausb_ep_handle */ 
+ ma_ep->ep_handle_state = MAUSB_EP_HANDLE_UNASSIGNED; 
+ 
+ INIT_LIST_HEAD(&ma_ep->urb_list); 
+ INIT_LIST_HEAD(&ma_ep->ep_list); 
+ INIT_LIST_HEAD(&ma_ep->req_list); 
+ INIT_LIST_HEAD(&ma_ep->resp_list); 
+ 
+ spin_lock_init(&ma_ep->ep_lock); 
+ ma_ep->tx_timed_out = false; 
+ 
+ /* initialize endpoint work queue */ 
+ init_waitqueue_head(&ma_ep->host_ep_wq); 
+ 
+ /* initialize endpoint timer */ 
+ setup_timer(&ma_ep->timer, wake_timeout_thread, (unsigned long) ma_ep); 
+ 
+ /* add the endpoint to the device */ 
+ spin_lock_irqsave(&ma_dev->dev_lock, irq_flags); 
+ list_add_tail(&ma_ep->ep_list, &ma_dev->ep_list); 
+ spin_unlock_irqrestore(&ma_dev->dev_lock, irq_flags); 
+ 
+ /* give a pointer to the ma_ep back to the caller */ 
+ if (NULL != mausb_ep) 
+ *mausb_ep = ma_ep; 
+ 
+ return 0; 
+} 
+EXPORT_SYMBOL(mausb_internal_add_ep); 
+ 
+/** 
+ * Drops the given endpoint from the given device. The difference between this 
+ * function and mausb_drop_endpoint (which can be called from the usb core) 
+ * is that this uses the private ma-structs. Calling this function is 
+ * cheaper, and therefore preferred when possible, since mausb_drop_endpoint 
+ * will have to find the internal endpoint structure. 
+ */ 
+int mausb_internal_drop_ep(struct mausb_host_ep *ma_ep) 
+{ 
+ struct mausb_dev *ma_dev; 
+ struct mausb_request *ma_request, *next_request; 
+ struct mausb_pkt *ma_pkt, *next_pkt; 
+ unsigned long irq_flags; 
+ unsigned long irq_flags2; 
+ 
+ if (NULL == ma_ep) 
+ return -EINVAL; 
+ 
+ /* drop all pending transfers */ 
+ spin_lock_irqsave(&ma_ep->ep_lock, irq_flags); 
+ ma_dev = ma_ep->mausb_dev; 
+ 
+ /* stop transfer timeout thread */ 
+ if (NULL != ma_ep->timeout_task) 
+ kthread_stop(ma_ep->timeout_task); 
+ 
+ /* drop all pending usb_requests (if there are any) */ 
+ if (NULL != ma_ep->usb_req_list) { 
+ list_for_each_entry_safe(ma_request, next_request, 
+ ma_ep->usb_req_list, usb_req_list) { 
+ list_del(&ma_request->usb_req_list); 
+ ma_request->req.status = -ESHUTDOWN; 
+ ma_request->req.complete(ma_ep->dev_ep, 
+ &ma_request->req); 
+ } 
+ } 
+ 
+ /* flush out all of the stored request/response packets */ 
+ list_for_each_entry_safe(ma_pkt, next_pkt, &ma_ep->req_list, pkt_list) { 
+ list_del(&ma_pkt->pkt_list); 
+ mausb_free_pkt(ma_pkt); 
+ } 
+ list_for_each_entry_safe(ma_pkt, next_pkt, 
+ &ma_ep->resp_list, pkt_list) { 
+ list_del(&ma_pkt->pkt_list); 
+ mausb_free_pkt(ma_pkt); 
+ } 
+ 
+ /* remove the endpoint from the list */ 
+ spin_lock_irqsave(&ma_dev->dev_lock, irq_flags2); 
+ list_del(&ma_ep->ep_list); 
+ spin_unlock_irqrestore(&ma_dev->dev_lock, irq_flags2); 
+ 
+ spin_unlock_irqrestore(&ma_ep->ep_lock, irq_flags); 
+ 
+ kfree(ma_ep); 
+ 
+ return 0; 
+} 
+EXPORT_SYMBOL(mausb_internal_drop_ep); 
+ 
+/** 
+ * Updates the state of an endpoint based on the mausb_ep_des. 
+ */ 
+int mausb_update_ep(struct mausb_host_ep *ma_ep, 
+ struct mausb_ep_des *ma_ep_des) 
+{ 
+ unsigned long irq_flags; 
+ 
+ spin_lock_irqsave(&ma_ep->ep_lock, irq_flags); 
+ 
+ if (!ma_ep_des->valid) { /* Valid bit: 0 means valid */ 
+ ma_ep->ep_handle.handle = ma_ep_des->ep_handle.handle; 
+ ma_ep->ep_handle_state = MAUSB_EP_HANDLE_ACTIVE; 
+ } 
+ 
+ if (ma_ep_des->dir == 0) { 
+ ma_ep->state.rx_buf_size = ma_ep_des->buffer_size; 
+ 
+ 
+ if (ma_ep_des->l_man) 
+ ma_ep->lman_support = true; 
+ else 
+ ma_ep->lman_support = false; 
+ } 
+ 
+ /*TODO: parse and use the remainder of the values in the packet */ 
+ 
+ spin_unlock_irqrestore(&ma_ep->ep_lock, irq_flags); 
+ 
+ return 0; 
+} 
+ 
+/** 
+ * Allocates private per-usb-device data. 
+ * 
+ * @ma_dev: The MA USB device to which the USB device belongs 
+ * @usb_dev: The host-side USB device struct to add. 
+ * @gadget: The device-side USB device struct to add. 
+ * 
+ * This function allocates a new device and adds it onto the MA USB device's 
+ * linked list of usb devices. It also allocates endpoint data for the control 
+ * endpoint (EP0). 
+ */ 
+struct mausb_dev *mausb_internal_alloc_dev(struct ma_dev *ma_dev, 
+ struct usb_device *dev, struct usb_gadget *gadget) 
+{ 
+ unsigned long irq_flags; 
+ struct mausb_dev *mausb_dev; 
+ 
+ mausb_dev = kzalloc(sizeof(struct mausb_dev), GFP_KERNEL); 
+ 
+ if (!mausb_dev) 
+ return NULL; 
+ 
+ if (NULL != dev) 
+ mausb_dev->dev = dev; 
+ if (NULL != gadget) 
+ mausb_dev->gadget = gadget; 
+ mausb_dev->ma_dev = ma_dev; 
+ INIT_LIST_HEAD(&mausb_dev->ep_list); 
+ INIT_LIST_HEAD(&mausb_dev->dev_list); 
+ spin_lock_init(&mausb_dev->dev_lock); 
+ 
+ spin_lock_irqsave(&ma_dev->ma_dev_lock, irq_flags); 
+ 
+ /* 
+ * If this is the first device to be allocated, then it should be the 
+ * most upstream. 
+ */ 
+ if (NULL == ma_dev->top_dev) 
+ ma_dev->top_dev = mausb_dev; 
+ 
+ list_add_tail(&mausb_dev->dev_list, &ma_dev->dev_list); 
+ spin_unlock_irqrestore(&ma_dev->ma_dev_lock, irq_flags); 
+ 
+ return mausb_dev; 
+} 
+EXPORT_SYMBOL(mausb_internal_alloc_dev); 
+ 
+/** 
+ * Frees private per-device data. 
+ * 
+ * @ma_dev: The MA USB device that the USB device beingfreed belongs to. 
+ * @mausb_dev: The MA USB data associated with the USB device being freed. 
+ * 
+ * This function removes a USB device from the MA USB hcd's linked list 
+ * and releases the device's media agnostic data structure. All endpoints 
+ * belonging to this device are also removed from the MA USB hcd and released 
+ * (including EP0). 
+ */ 
+int mausb_internal_free_dev(struct ma_dev *ma_dev, struct mausb_dev *mausb_dev) 
+{ 
+ int ret = 0; 
+ unsigned long irq_flags, irq_flags2; 
+ struct mausb_host_ep *ma_ep, *next; 
+ 
+ /* remove all the endpoints from the device */ 
+ spin_lock_irqsave(&mausb_dev->dev_lock, irq_flags); 
+ list_for_each_entry_safe(ma_ep, next, &mausb_dev->ep_list, ep_list) { 
+ spin_unlock_irqrestore(&mausb_dev->dev_lock, irq_flags); 
+ ret = mausb_internal_drop_ep(ma_ep); 
+ 
+ spin_lock_irqsave(&mausb_dev->dev_lock, irq_flags); 
+ } 
+ 
+ if (!list_empty(&mausb_dev->ep_list)) { 
+ spin_unlock_irqrestore(&mausb_dev->dev_lock, irq_flags); 
+ return ret; 
+ } 
+ 
+ /* remove the mausb device from the ma device */ 
+ spin_lock_irqsave(&ma_dev->ma_dev_lock, irq_flags2); 
+ list_del(&mausb_dev->dev_list); 
+ 
+ /* if the top device is being removed */ 
+ if (ma_dev->top_dev == mausb_dev) 
+ ma_dev->top_dev = NULL; 
+ 
+ spin_unlock_irqrestore(&ma_dev->ma_dev_lock, irq_flags2); 
+ 
+ spin_unlock_irqrestore(&mausb_dev->dev_lock, irq_flags); 
+ 
+ kfree(mausb_dev); 
+ 
+ return ret; 
+ 
+} 
+EXPORT_SYMBOL(mausb_internal_free_dev); 
+ 
+/** 
+ * Resets all the data in a ma_dev struct. This includes freeing all the MA 
+ * data for the usb devices and endpoints connected to this device. 
+ */ 
+int mausb_internal_reset_ma_dev(struct ma_dev *ma_dev, __u8 ma_dev_addr, 
+ __u8 mass_id, struct mausb_hcd *mhcd, struct mausb_udc *maudc) 
+{ 
+ int ret = -EINVAL; 
+ struct mausb_dev *mausb_dev, *mausb_next; 
+ int (*req_switch)(struct mausb_mgmt_pkt *req, 
+ struct mausb_mgmt_pkt *resp, 
+ struct mausb_mgmt *mgmt) 
+ = ma_dev->mgmt.req_switch; 
+ int (*device_connect)(int) = ma_dev->ma_drv.device_connect; 
+ unsigned long irq_flags; 
+ 
+ if (NULL != mhcd) 
+ ma_dev->mhcd = mhcd; 
+ 
+ if (NULL != maudc) 
+ ma_dev->maudc = maudc; 
+ 
+ spin_lock_irqsave(&ma_dev->ma_dev_lock, irq_flags); 
+ list_for_each_entry_safe(mausb_dev, mausb_next, &ma_dev->dev_list, 
+ dev_list) { 
+ spin_unlock_irqrestore(&ma_dev->ma_dev_lock, irq_flags); 
+ 
+ ret = mausb_internal_free_dev(ma_dev, mausb_dev); 
+ 
+ spin_lock_irqsave(&ma_dev->ma_dev_lock, irq_flags); 
+ } 
+ 
+ if (!list_empty(&ma_dev->dev_list)) { 
+ /* could not clear all the devices */ 
+ ret = -EAGAIN; 
+ } 
+ 
+ spin_unlock_irqrestore(&ma_dev->ma_dev_lock, irq_flags); 
+ 
+ /* TODO: make sure this doesn't break any locking rules */ 
+ mausb_init_ma_device(ma_dev, ma_dev_addr, mass_id, mhcd, 
+ maudc, req_switch, device_connect); 
+ 
+ return ret; 
+} 
+ 
+/** 
+ * Initializes the media agnostic management structure. 
+ */ 
+int mausb_init_mgmt(struct mausb_mgmt *mgmt, spinlock_t *ma_dev_lock, 
+ int (*req_switch)(struct mausb_mgmt_pkt *req, 
+ struct mausb_mgmt_pkt *resp, struct mausb_mgmt *mgmt)) 
+{ 
+ INIT_LIST_HEAD(&mgmt->req_list); 
+ mgmt->token = 0; 
+ mgmt->tx_pair.to_ms.context = NULL; 
+ mgmt->tx_pair.to_ms.transfer_packet = NULL; 
+ mgmt->tx_pair.to_ma.context = NULL; 
+ mgmt->tx_pair.to_ma.transfer_packet = NULL; 
+ mgmt->hub_dev_handle = 0; 
+ mgmt->ma_dev_lock = ma_dev_lock; 
+ mgmt->req_switch = req_switch; 
+ 
+ return 0; 
+} 
+ 
+static void mausb_init_pkt_dmux(struct mausb_pkt_transfer *pkt_dmux, 
+ void *context) 
+{ 
+ pkt_dmux->transfer_packet = &mausb_pkt_dmux; 
+ pkt_dmux->context = context; 
+} 
+ 
+/* 
+ * Initializes the data structure for an MA USB device. 
+ */ 
+int mausb_init_ma_device(struct ma_dev *ma_dev, __u8 ma_dev_addr, __u8 mass_id, 
+ struct mausb_hcd *mhcd, struct mausb_udc *maudc, 
+ int (*req_switch)(struct mausb_mgmt_pkt *req, 
+ struct mausb_mgmt_pkt *resp, struct mausb_mgmt *mgmt), 
+ int (*device_connect)(int)) 
+{ 
+ INIT_LIST_HEAD(&ma_dev->dev_list); 
+ ma_dev->top_dev = NULL; 
+ ma_dev->ma_dev_addr = ma_dev_addr; 
+ ma_dev->mass_id = mass_id; 
+ if (mhcd != NULL) 
+ ma_dev->mhcd = mhcd; 
+ if (maudc != NULL) 
+ ma_dev->maudc = maudc; 
+ spin_lock_init(&ma_dev->ma_dev_lock); 
+ ma_dev->ma_drv.device_connect = device_connect; 
+ mausb_init_pkt_dmux(&ma_dev->ma_drv.pkt_dmux, ma_dev); 
+ 
+ mausb_init_mgmt(&ma_dev->mgmt, &ma_dev->ma_dev_lock, req_switch); 
+ 
+ return 0; 
+} 
+EXPORT_SYMBOL(mausb_init_ma_device); 
+ 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/drivers/mausb_mem.h linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/drivers/mausb_mem.h
--- linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/drivers/mausb_mem.h	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/drivers/mausb_mem.h	2014-11-28 12:39:00.572447000 +0800
@@ -0,0 +1,509 @@
+/* Name: mausb_mem.h 
+ * Description: Header for mausb_mem.c. Needed do make calls to 
+ * functions defined in mausb_mem.c. 
+ * 
+ * This file is provided under a dual BSD/GPLv2 license. When using or 
+ * redistributing this file, you may do so under either license. 
+ * 
+ * GPL LICENSE SUMMARY 
+ * 
+ * Copyright(c) 2014 Intel Corporation. 
+ * 
+ * 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. 
+ * 
+ * Contact Information: 
+ * Sean Stalley, sean.stalley [at] intel 
+ * Stephanie Wallick, stephanie.s.wallick [at] intel 
+ * 2111 NE 25th Avenue 
+ * Hillsboro, Oregon 97124 
+ * 
+ * BSD LICENSE 
+ * 
+ * Copyright(c) 2014 Intel Corporation. 
+ * 
+ * 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 of Intel Corporation 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. 
+ */ 
+ 
+#ifndef __MAUSB_MEM_H 
+#define __MAUSB_MEM_H 
+ 
+#include "mausb_state.h" 
+#include "mausb_pkt.h" 
+#include "mausb_msapi.h" 
+ 
+#include <linux/usb.h> 
+#include <linux/usb/hcd.h> 
+#include <linux/usb/gadget.h> 
+#include <linux/timer.h> 
+ 
+#ifdef DEBUG 
+#define mamem_dbg(format, arg...) \ 
+ printk(KERN_DEBUG format, ##arg) 
+#else 
+#define mamem_dbg(format, arg...) 
+#endif 
+ 
+#define mamem_warn(format, arg...) \ 
+ printk(KERN_WARNING format, ##arg) 
+ 
+#define mamem_err(format, arg...) \ 
+ printk(KERN_ERR format, ##arg) 
+ 
+/* forward declarations */ 
+struct mausb_urb; 
+struct mausb_pkt; 
+struct mausb_host_ep; 
+ 
+/** 
+ * mausb_mgmt - MAUSB management datastrucure 
+ * 
+ * Contains all the data necessary to handle management packets. 
+ * 
+ * @req_list: List of all currently pending management requests for 
+ * this device. 
+ * @token: The value of the token field in the most recently sent 
+ * management request. 
+ * @tx_pair: Indicates where management packets should be sent. 
+ * 
+ * The following variables are to store common management packet fields: 
+ * 
+ * @hub_dev_handle: Device Handle of the MAUSB Dock hub. used for 
+ * USBDevHandleReq packets. 
+ * @ma_dev_lock: The spinlock which protects the management data in this 
+ * struct. 
+ * @req_switch: The host or devices request switch. It accepts an 
+ * incoming request, makes the necessary calls, and 
+ * returns a partially completed response (it fills the 
+ * response type, status & any data fields specific to 
+ * that response). the remainder of the fields are 
+ * completed by mausb_rx_mgmt_req. 
+ */ 
+struct mausb_mgmt { 
+ struct list_head req_list; 
+ __u16 token:10; 
+ struct mausb_transfer_pair tx_pair; 
+ __u16 hub_dev_handle; 
+ spinlock_t *ma_dev_lock; 
+ int (*req_switch)(struct mausb_mgmt_pkt *req, 
+ struct mausb_mgmt_pkt *resp, struct mausb_mgmt *mgmt); 
+}; 
+ 
+/** 
+ * mausb_mgmt_req_list - MAUSB management request list entry 
+ * 
+ * An entry in the mausb_mgmt request linked list. 
+ * 
+ * @req_list: Pointers to other entries in the list. 
+ * @mgmt_req: The request management packet. 
+ * @mgmt_resp: The response management packet, set to NULL until a response 
+ * is received. 
+ * @resp_rcvd: An event triggered when the response is received. 
+ */ 
+struct mausb_mgmt_req_list { 
+ struct list_head req_list; 
+ 
+ struct mausb_pkt *mgmt_req; 
+ struct mausb_pkt *mgmt_resp; 
+ 
+ struct completion resp_rcvd; 
+}; 
+ 
+/** 
+ * Media Agnostic Session State 
+ * 
+ * Defines the current state of the session between the host & device. 
+ * Per MAUSB spec, sections 7.1 & 8.1.1. 
+ */ 
+enum mausb_session_state { 
+ MAUSB_SESSION_DOWN, 
+ MAUSB_SESSION_CONNECTING, 
+ MAUSB_SESSION_ACITVE, 
+ MAUSB_SESSION_INACTIVE 
+}; 
+ 
+/** 
+ * stores information returned in a CapResp packet 
+ */ 
+struct ma_capability { 
+ __u16 num_ep; 
+ __u8 num_dev; 
+ __u8 num_stream:5; 
+ __u8 dev_type:3; 
+ __u16 max_tx_reqs; 
+ __u16 max_mgmt_reqs:12; 
+}; 
+ 
+/** 
+ * MA device data 
+ * 
+ * This structure is used to hold MA device-specific data 
+ * (i.e. one instance of this structure exists per MA device). 
+ * 
+ * @mgmt: Contains the data needed to keep track of the device's 
+ * management packets. 
+ * @dev_list: Stores a list of the devices connected to this HCD. 
+ * This includes any internal mausb data that exists on 
+ * a per-device, per-endpoint, or per-transfer basis. 
+ * @top_dev: The most upstream mausb device. Used to determine 
+ * where to send MA USB device management packets (such as 
+ * MAUSBDevSleepReq and MAUSBDevWakeReq). 
+ * @session_state: Defines the current state of the session between the 
+ * host and device. Per MAUSB spec, sections 7.1 & 8.1.1. 
+ * @ma_dev_addr: MA Device Address. Assigned by the host via a 
+ * MAUSBDevResetReq. 
+ * @mass_id: Media-Agnostic Service Set Identifier. Assigned by the 
+ * host via a MAUSBDevResetReq. 
+ * @ma_dev_lock: Spinlock for this device. This lock should be held 
+ * before accessing any data in this structure. 
+ * @ma_drv: Media agnostic driver interfaces. 
+ * @ms_drv: Media specific driver interfaces. 
+ * @ma_cap: Stores MA device info from CapResp packet fields. 
+ * @speed: Stores MA device info from speed capability descriptor. 
+ * @pout: Stores MA device info from P-managed OUT capability 
+ * descriptor. 
+ * @iso: Stores MA device info from isochronous capabilities 
+ * descriptor. 
+ * @synch: Stores MA device info from synchronization capabilities 
+ * descriptor. 
+ * @cont_id: Stores MA device info from container ID capability 
+ * descriptor. 
+ * @link_sleep: Stores MA device info from link sleep capability 
+ * descriptor. 
+ */ 
+struct ma_dev { 
+ struct mausb_mgmt mgmt; 
+ struct list_head dev_list; 
+ struct mausb_dev *top_dev; 
+ enum mausb_session_state session_state; 
+ __u8 ma_dev_addr:7; 
+ __u8 mass_id; 
+ spinlock_t ma_dev_lock; 
+ 
+ union { 
+ struct mausb_hcd *mhcd; 
+ struct mausb_udc *maudc; 
+ }; 
+ 
+ struct mausb_ma_drv ma_drv; 
+ struct mausb_ms_drv *ms_driver; 
+ 
+ struct ma_capability ma_cap; 
+ struct mausb_dev_cap_speed *speed; 
+ struct mausb_dev_cap_pout *pout; 
+ struct mausb_dev_cap_iso *iso; 
+ struct mausb_dev_cap_sync *sync; 
+ struct mausb_dev_cap_cont_id *cont_id; 
+ struct mausb_dev_cap_link_sleep *link_sleep; 
+}; 
+ 
+/** 
+ * MA USB device data 
+ * 
+ * This structure is used to hold device-pecific data 
+ * (i.e. one instance of this structure exists per usb device). 
+ * 
+ * @dev: A pointer to the kernel's usb device structure. Can be 
+ * used to uniquely identify a device. 
+ * @gadget: A pointer to the kernel's usb gadget structure. 
+ * @ma_dev: Pointer to parent ma_dev structure. 
+ * @ep_list: A linked list of all the endpoints for this device. 
+ * MAUSBDevHandleResp packet. 
+ * @dev_handle: MA USB device handle for this device 
+ * @dev_address: The usb device address. set by the ma_dev. 
+ * NOTE: this is not the same as the address given by 
+ * the kernel. 
+ * @dev_list: A linked list of all the devices in the HCD. 
+ * @dev_lock: Spinlock for this device. This lock should be held 
+ * before accessing any data in this structure. 
+ */ 
+struct mausb_dev { 
+ union { 
+ struct usb_device *dev; /* Host only */ 
+ struct usb_gadget *gadget; /* Device only */ 
+ }; 
+ struct ma_dev *ma_dev; 
+ struct list_head ep_list; 
+ __u16 dev_handle; 
+ __u8 dev_address; 
+ struct list_head dev_list; 
+ spinlock_t dev_lock; 
+}; 
+ 
+/** 
+ * MAUSB Endpoint Handle State Variables 
+ * 
+ * Defines the states for an MA USB Endpoint Handle. 
+ * 
+ * Per MAUSB spec, seciton 7.2 
+ * 
+ * Note: MAUSB_EP_HANDLE_DELETED is used to flag an endpoint for deletion 
+ * it is not per spec; endpoints in this state should not be used and 
+ * will be deleted in the next EPHandleDeleteReq. 
+ */ 
+enum mausb_ep_handle_state { 
+ MAUSB_EP_HANDLE_UNASSIGNED = 0, 
+ MAUSB_EP_HANDLE_ACTIVE, 
+ MAUSB_EP_HANDLE_INACTIVE, 
+ MAUSB_EP_HANDLE_HALTED, 
+ MAUSB_EP_HANDLE_DELETED 
+}; 
+ 
+/** 
+ * MA USB host-side endpoint data 
+ * 
+ * This structure is used to hold endpoint-specific data 
+ * (i.e. one instance of this structure exists per endpoint). 
+ * 
+ * The following data is protected by the devices's dev_lock: 
+ * 
+ * @ep: Used only by the host side. A pointer to the kernel's host-side 
+ * endpoint structure. Can be used to uniquely identify an 
+ * endpoint. Note: the HCD probably shouldn't read or write 
+ * anything from the usb_host_endpoint structure, since it belongs 
+ * to the kernel. 
+ * @dev_ep: Used only by the device side. A pointer to the kernel's 
+ * device-side endpoint structure. 
+ * @ep_list: A linked list of all the endpoints connected to the same 
+ * device. 
+ * 
+ * The following data is protected by the endpoint's ep_lock: 
+ * 
+ * @state: The MA USB state variables for this endpoint. Per 
+ * MA USB Spec, sections 5.4.1 and 5.5.2. 
+ * @active_transfer: Urb that maps to the transfer in progress. 
+ * @ep_handle: The endpoint handle to be used by packets for this 
+ * endpoint per MA USB Spec, section 6.2.1.5. 
+ * @ep_handle_state: Defines the states an Endpoint Handle can be in. 
+ * Per MA USB Spec, section 7.2. 
+ * @buffer: Buffer that holds data going to/from a host during 
+ * transfer. 
+ * @actual_length: Length of buffer. 
+ * @lman_support: For control or non-iso OUT endpoints. Indicates if 
+ * link-managed tranfers are supported. Not valid until 
+ * an EPHandleResp is received for this endpoint. 
+ * @control_dir: Control endpoints only; used to determine the direction 
+ * of the current transfer. 
+ * @ccu: The credit conumption unit, in bytes. Per MA USB Spec, 
+ * table 27. 
+ * @mausb_dev: The device the endpoint belongs to. 
+ * @urb_list: A linked list of all URBs pending for this endpoint. 
+ * URBs map one-to-one with MAUSB Transfers, so each entry 
+ * also represents an MA USB Transfer. 
+ * @usb_req_list: Only used on the device side. A linked list of all 
+ * usb_requests submitted to this endpoint. 
+ * @req_list: Head of list of created transferRequests and 
+ * transferAck packets. 
+ * @resp_list: Head of list of received transferResponses packets. 
+ * @ep_lock: Spinlock for this endpoint. This lock should be held 
+ * before accessing any data in this structure. 
+ * @timer: Endpoint timer structure, used to monitor transfer 
+ * timeouts. 
+ * @timeout_task: Thread used to perform packet resends after transfer 
+ * timeout. 
+ * @host_ep_wq: Work queue for timeout thread to wait on while sleeping. 
+ * @tx_timed_out: Used to flag when a timeout event has occured during 
+ * a transfer. 
+ * @tx_pair: Transfer pair for this endpoint. 
+ * @gadget: USB gadget associated with this endpoint. 
+ * @busy: True if this endpoint is busy, otherwise false. 
+ * @halted: 1 if endpoint is halted, otherwise 0. 
+ * @wedged: 1 if endpoint is wedged, otherwise 0. 
+ * @stream_en: 1 if streams are enabled for this endpoint, otherwise 0. 
+ * @max_pkt: Max packet size for this endpoint. 
+ */ 
+struct mausb_host_ep { 
+ 
+ struct usb_host_endpoint *ep; /* Host only */ 
+ struct usb_ep *dev_ep; /* Device only */ 
+ struct list_head ep_list; 
+ struct mausb_ep_state state; 
+ struct mausb_urb *active_transfer; 
+ struct mausb_ep_handle ep_handle; 
+ enum mausb_ep_handle_state ep_handle_state; 
+ void *buffer; 
+ u32 actual_length; 
+ bool lman_support; 
+ bool control_dir; 
+ u16 ccu; 
+ struct mausb_dev *mausb_dev; 
+ struct list_head urb_list; 
+ struct list_head *usb_req_list; 
+ struct list_head req_list; 
+ struct list_head resp_list; 
+ spinlock_t ep_lock; 
+ struct timer_list timer; 
+ struct task_struct *timeout_task; 
+ wait_queue_head_t host_ep_wq; 
+ bool tx_timed_out; 
+ struct mausb_transfer_pair tx_pair; 
+ struct usb_gadget *gadget; /* Device only */ 
+ bool busy; 
+ unsigned halted:1; 
+ unsigned wedged:1; 
+ unsigned stream_en:1; 
+ u16 max_pkt; 
+}; 
+ 
+/** 
+ * endpoint request structure - describes one I/O request 
+ * 
+ * @usb_ep: A device-side endpoint structure. 
+ * @queue: The list of all requests currently enqueued to this endpoint. 
+ */ 
+struct mausb_gadget_ep { 
+ struct usb_ep dev_ep; 
+ struct list_head usb_req_list; 
+}; 
+ 
+/** 
+ * MA USB urb structure 
+ * 
+ * Stores MAUSB-specific urb data. In our implementation, one urb from usb 
+ * core maps to exactly one MA USB transfer. When an urb is submitted, it 
+ * queues a new transfer. When a transfer is complete (or fails), the urb 
+ * is given back to the core. 
+ * 
+ * All data listed in this structure is protected by the ep_lock. 
+ * If you want to use any of this data, you need to be in posession 
+ * of this lock. 
+ * 
+ * @urb: Used only on the host side. The urb submitted to the 
+ * HCD by usbcore. 
+ * @usb_request_list: Used only on the device side. A pointer to the list of 
+ * msusb_requests for this endpoint. 
+ * @urb_list: Connects this mausb_urb with other mausb_urbs 
+ * queued to the same endpoint. 
+ * @ma_hcd_urb_list: Connects this urb to urbs queued to the same ma hcd. 
+ * @state: Current state of the transfer as defined in the 
+ * MA USB Spec. 
+ * @ep: The endpoint that the transfer belongs to. 
+ * @dev: The device that the transfer belongs to. 
+ * @transfer_size: Total number of bytes for transfer associated with urb. 
+ */ 
+struct mausb_urb { 
+ struct urb *urb; /* Host Only */ 
+ struct list_head *usb_request_list; /* Device Only */ 
+ struct list_head urb_list; 
+ struct list_head ma_hcd_urb_list; 
+ struct mausb_transfer_state state; 
+ struct mausb_host_ep *ep; 
+ struct mausb_dev *dev; 
+ unsigned int transfer_size; 
+}; 
+ 
+/** 
+ * endpoint request structure - describes one I/O request 
+ * 
+ * @req: The usb_request struct. Enqueuing a usb_request is 
+ * what triggers the creation of this struct. 
+ * @usb_req_list: List of all requests enqueued at this endpoint. 
+ */ 
+struct mausb_request { 
+ struct usb_request req; 
+ struct list_head usb_req_list; 
+}; 
+ 
+/* endpoint/device helper functions */ 
+struct mausb_host_ep *usb_to_ma_endpoint(struct usb_host_endpoint *ep); 
+int mausb_hcd_urb_count(struct mausb_hcd *mhcd); 
+ 
+#define MAUSB_ADD true 
+#define MAUSB_DEL false 
+#define MAUSB_DEV false 
+#define MAUSB_HOST true 
+#define MAUSB_OUT false 
+#define MAUSB_IN true 
+struct mausb_pkt *mausb_create_dp(int *status, struct mausb_urb *maurb, 
+ bool in, bool host, gfp_t memflags); 
+ 
+/* endpoint/device memory management functions */ 
+struct mausb_host_ep *mausb_state_to_ep(struct mausb_ep_state *state); 
+struct ma_dev *context_to_ma_dev(void *context); 
+struct mausb_hcd *mausb_host_ep_to_mahcd(struct mausb_host_ep *ep); 
+struct mausb_udc *mausb_host_ep_to_maudc(struct mausb_host_ep *ep); 
+struct mausb_dev *usb_dev_to_mausb_dev(struct usb_device *udev); 
+struct mausb_host_ep *mausb_find_ep_dev(struct usb_ep *dev_ep, 
+ struct mausb_dev *mausb_dev); 
+struct mausb_host_ep *mausb_find_ep_host(struct usb_host_endpoint *ep, 
+ struct mausb_dev *mausb_dev); 
+struct mausb_host_ep *mausb_find_ep_by_handle(struct mausb_ep_handle *handle, 
+ struct mausb_dev *mausb_dev); 
+struct mausb_host_ep *mausb_find_ep_from_handle(struct mausb_ep_handle handle, 
+ struct ma_dev *ma_dev); 
+struct mausb_pkt *mausb_pkt_from_ms_pkt_ma_dev(struct ms_pkt *ms_pkt, 
+ struct ma_dev *ma_dev, gfp_t mem_flags); 
+struct mausb_pkt *mausb_pkt_from_ms_pkt_ep(struct ms_pkt *ms_pkt, 
+ struct mausb_host_ep *ep, gfp_t mem_flags); 
+struct mausb_dev *mausb_find_dev(struct ma_dev *ma_dev, struct usb_device *dev, 
+ unsigned long *handle, struct usb_gadget *gadget); 
+struct mausb_dev *mausb_find_dev_host(struct ma_dev *ma_dev, 
+ struct usb_device *dev); 
+struct mausb_host_ep *mausb_find_ep_by_desc( 
+ const struct usb_endpoint_descriptor *ep_desc, 
+ struct mausb_dev *mausb_dev); 
+struct mausb_host_ep *mausb_find_ep_by_address(u8 address, 
+ struct mausb_dev *mausb_dev); 
+struct mausb_urb *mausb_alloc_maurb(struct mausb_host_ep *ma_ep, 
+ gfp_t memflags); 
+int mausb_internal_drop_maurb(struct mausb_urb *maurb, struct mausb_hcd *mhcd); 
+void init_ep_state(struct mausb_ep_state *state, u32 buf_size); 
+int mausb_activate_endpoints(struct mausb_dev *mausb_dev); 
+void mausb_link_ma_ep_to_usb_ep(struct mausb_host_ep *ma_ep, 
+ struct usb_ep *dev_ep); 
+struct mausb_gadget_ep *usb_ep_to_mausb_gadget_ep(struct usb_ep *ep); 
+int mausb_internal_add_ep(struct mausb_dev *ma_dev, 
+ struct usb_host_endpoint *ep, struct usb_ep *dev_ep, 
+ struct mausb_host_ep **mausb_ep, 
+ int (*transfer_timeout)(void *data), gfp_t memflags); 
+int mausb_internal_drop_ep(struct mausb_host_ep *ma_ep); 
+int mausb_update_ep(struct mausb_host_ep *ma_ep, 
+ struct mausb_ep_des *ma_ep_des); 
+struct mausb_dev *mausb_internal_alloc_dev(struct ma_dev *ma_dev, 
+ struct usb_device *dev, struct usb_gadget *gadget); 
+int mausb_internal_free_dev(struct ma_dev *ma_dev, 
+ struct mausb_dev *mausb_dev); 
+int mausb_internal_reset_ma_dev(struct ma_dev *ma_dev, __u8 ma_dev_addr, 
+ __u8 mass_id, struct mausb_hcd *mhcd, struct mausb_udc *maudc); 
+int mausb_init_ma_device(struct ma_dev *ma_dev, __u8 ma_dev_addr, __u8 mass_id, 
+ struct mausb_hcd *mhcd, struct mausb_udc *maudc, 
+ int (*req_switch)(struct mausb_mgmt_pkt *req, 
+ struct mausb_mgmt_pkt *resp, struct mausb_mgmt *mgmt), 
+ int (*device_connect)(int)); 
+int mausb_init_mgmt(struct mausb_mgmt *mgmt, spinlock_t *ma_dev_lock, 
+ int (*req_switch)(struct mausb_mgmt_pkt *req, 
+ struct mausb_mgmt_pkt *resp, struct mausb_mgmt *mgmt)); 
+const struct usb_endpoint_descriptor *mausb_get_ep_des( 
+ struct mausb_host_ep *ma_ep); 
+ 
+#endif 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/drivers/mausb_mem-host.c linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/drivers/mausb_mem-host.c
--- linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/drivers/mausb_mem-host.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/drivers/mausb_mem-host.c	2014-11-28 12:39:00.572447000 +0800
@@ -0,0 +1,402 @@
+/* Name: mausb_mem-host.c 
+ * Description: Contains hostside-specific memory functions, as well as 
+ * wrappers for functions in mausb_mem.c. 
+ * 
+ * This file is provided under a dual BSD/GPLv2 license. When using or 
+ * redistributing this file, you may do so under either license. 
+ * 
+ * GPL LICENSE SUMMARY 
+ * 
+ * Copyright(c) 2014 Intel Corporation. 
+ * 
+ * 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. 
+ * 
+ * Contact Information: 
+ * Sean Stalley, sean.stalley [at] intel 
+ * Stephanie Wallick, stephanie.s.wallick [at] intel 
+ * 2111 NE 25th Avenue 
+ * Hillsboro, Oregon 97124 
+ * 
+ * BSD LICENSE 
+ * 
+ * Copyright(c) 2014 Intel Corporation. 
+ * 
+ * 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 of Intel Corporation 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/usb.h> 
+#include <linux/usb/hcd.h> 
+ 
+#include <linux/kthread.h> 
+ 
+#include "mausb_hcd.h" 
+#include "mausb_mem-host.h" 
+#include "mausb_mem.h" 
+#include "mausb_tx.h" 
+#include "mausb_mgmt.h" 
+ 
+/** 
+ * Returns a pointer to the media agnostic data for a given endpoint. 
+ */ 
+struct mausb_host_ep *usb_to_ma_endpoint(struct usb_host_endpoint *ep) 
+{ 
+ return (struct mausb_host_ep *) ep->hcpriv; 
+} 
+ 
+/** 
+ * Returns the number of urbs currently in the MA USB HCD. Will return 0 if the 
+ * MA USB HCD is empty or a negative errno if an error occurs. 
+ */ 
+int mausb_hcd_urb_count(struct mausb_hcd *mhcd) 
+{ 
+ int count = 0; 
+ struct mausb_host_ep *ma_ep; 
+ struct mausb_dev *mausb_dev; 
+ struct mausb_urb *maurb; 
+ unsigned long irq_flags; 
+ 
+ /* for every device */ 
+ spin_lock_irqsave(&mhcd->hcd_lock, irq_flags); 
+ list_for_each_entry(mausb_dev, &mhcd->ma_dev.dev_list, dev_list) { 
+ spin_unlock_irqrestore(&mhcd->hcd_lock, irq_flags); 
+ 
+ /* for every endpoint */ 
+ spin_lock_irqsave(&mausb_dev->dev_lock, irq_flags); 
+ list_for_each_entry(ma_ep, &mausb_dev->ep_list, ep_list) { 
+ spin_unlock_irqrestore(&mausb_dev->dev_lock, irq_flags); 
+ 
+ /* for every urb */ 
+ spin_lock_irqsave(&ma_ep->ep_lock, irq_flags); 
+ list_for_each_entry(maurb, &ma_ep->urb_list, urb_list) { 
+ ++count; 
+ } 
+ 
+ spin_unlock_irqrestore(&ma_ep->ep_lock, irq_flags); 
+ spin_lock_irqsave(&mausb_dev->dev_lock, irq_flags); 
+ } 
+ 
+ spin_unlock_irqrestore(&mausb_dev->dev_lock, irq_flags); 
+ spin_lock_irqsave(&mhcd->hcd_lock, irq_flags); 
+ } 
+ 
+ spin_unlock_irqrestore(&mhcd->hcd_lock, irq_flags); 
+ 
+ return count; 
+} 
+ 
+/** 
+ * This function removes a device data from the hcd. All endpoints belonging 
+ * to this device are also removed from the hcd and released (including EP0). 
+ */ 
+void mausb_free_dev(struct usb_hcd *hcd, struct usb_device *dev) 
+{ 
+ struct mausb_hcd *mhcd = usb_hcd_to_mausb_hcd(hcd); 
+ struct ma_dev *ma_dev = &mhcd->ma_dev; 
+ struct mausb_dev *mausb_dev = mausb_find_dev_host(ma_dev, dev); 
+ struct mausb_host_ep *ep0 = list_first_entry(&mausb_dev->ep_list, 
+ struct mausb_host_ep, ep_list); 
+ 
+ if (NULL == mausb_dev) { 
+ mausb_err(mhcd, "%s: USB device #%i not found\n", 
+ __func__, dev->devnum); 
+ return; 
+ } 
+ 
+ ep0->ep_handle_state = MAUSB_EP_HANDLE_INACTIVE; 
+ 
+ /* inactivate EP0 handle */ 
+ mausb_tx_dev_mgmt_req_ep(EPInactivateReq, &mhcd->ma_dev.mgmt, 
+ mausb_dev, true, ep0); 
+ 
+ /* delete remaining EP Handles */ 
+ mausb_tx_dev_mgmt_req(EPHandleDeleteReq, &mhcd->ma_dev.mgmt, 
+ mausb_dev, MAUSB_HOST); 
+ 
+ mausb_tx_dev_mgmt_req(USBDevDisconnectReq, &ma_dev->mgmt, 
+ mausb_dev, MAUSB_HOST); 
+ 
+ mausb_internal_free_dev(ma_dev, mausb_dev); 
+ 
+ return; 
+} 
+ 
+/* 
+ * Adds an endpoint to the specified device. 
+ * 
+ * This function allocates private endpoint data and adds the given endpoint 
+ * to the given device. In the mausb_hcd, devices hold their endpoints in a 
+ * linked list. 
+ */ 
+int mausb_add_endpoint(struct usb_hcd *hcd, struct usb_device *dev, 
+ struct usb_host_endpoint *ep) 
+{ 
+ int status; 
+ char *ep_type; 
+ struct mausb_hcd *mhcd = usb_hcd_to_mausb_hcd(hcd); 
+ struct ma_dev *ma_dev = &mhcd->ma_dev; 
+ struct mausb_dev *mausb_dev; 
+ struct mausb_ms_drv *ms_driver = ma_dev->ms_driver; 
+ struct mausb_host_ep *ma_ep; 
+ 
+ /* don't need to do anything for root hub */ 
+ if ((NULL == dev->parent) && (&dev->ep0 != ep)) 
+ return 0; 
+ 
+ mausb_dev = mausb_find_dev_host(ma_dev, dev); 
+ if (NULL == mausb_dev) { 
+ mausb_err(mhcd, "unable to add endpoint: USB device #%i not" 
+ " found\n", dev->devnum); 
+ return -ENODEV; 
+ } 
+ 
+ status = mausb_internal_add_ep(mausb_dev, ep, NULL, &ma_ep, 
+ &host_transfer_timeout, GFP_KERNEL); 
+ 
+ if (status < 0) { 
+ mausb_err(mhcd, "could not add endpoint: error %i\n", status); 
+ return status; 
+ } 
+ 
+ /* need ms driver before adding endpoint */ 
+ if (NULL == ms_driver) 
+ return -ENODEV; 
+ 
+ /* for debug messages */ 
+ switch (usb_endpoint_type(&ep->desc)) { 
+ case USB_ENDPOINT_XFER_CONTROL: 
+ ep_type = "control"; 
+ break; 
+ case USB_ENDPOINT_XFER_BULK: 
+ ep_type = "bulk"; 
+ break; 
+ case USB_ENDPOINT_XFER_INT: 
+ ep_type = "interrupt"; 
+ break; 
+ case USB_ENDPOINT_XFER_ISOC: 
+ ep_type = "isochronous"; 
+ break; 
+ default: 
+ ep_type = "unknown"; 
+ } 
+ 
+ /* set up control endpoint data channel */ 
+ if (usb_endpoint_type(&ep->desc) == USB_ENDPOINT_XFER_CONTROL) { 
+ status = mausb_add_data_channel(ms_driver, ma_ep, 
+ &complete_control_transferRequest); 
+ } 
+ /* set up bulk IN endpoint data channel */ 
+ else if (usb_endpoint_type(&ep->desc) == USB_ENDPOINT_XFER_BULK 
+ && usb_endpoint_dir_in(&ep->desc)) { 
+ status = mausb_add_data_channel(ms_driver, ma_ep, 
+ &complete_IN_transferRequest); 
+ } 
+ /* set up bulk OUT endpoint data channel */ 
+ else if (usb_endpoint_type(&ep->desc) == USB_ENDPOINT_XFER_BULK 
+ && usb_endpoint_dir_out(&ep->desc)) { 
+ status = mausb_add_data_channel(ms_driver, ma_ep, 
+ &complete_OUT_transferRequest); 
+ } 
+ /* set up an interrupt IN endpoint data channel */ 
+ else if (usb_endpoint_type(&ep->desc) == USB_ENDPOINT_XFER_INT 
+ && usb_endpoint_dir_in(&ep->desc)) { 
+ status = mausb_add_data_channel(ms_driver, ma_ep, 
+ &complete_IN_transferRequest); 
+ } 
+ /* set up an interrupt OUT endpoint data channel */ 
+ else if (usb_endpoint_type(&ep->desc) == USB_ENDPOINT_XFER_INT 
+ && usb_endpoint_dir_out(&ep->desc)) { 
+ status = mausb_add_data_channel(ms_driver, ma_ep, 
+ &complete_OUT_transferRequest); 
+ } else { 
+ mausb_err(mhcd, 
+ "%s: attempted to add channel for ep %i of unsupported" 
+ " type\n", __func__, usb_endpoint_num(&ep->desc)); 
+ return -EOPNOTSUPP; 
+ } 
+ 
+ if (status < 0) { 
+ mausb_err(mhcd, "cannot add %s channel for ep %i: error %i\n", 
+ ep_type, usb_endpoint_num(&ep->desc), status); 
+ /* cleanup endpoint */ 
+ mausb_internal_drop_ep(ma_ep); 
+ } else { 
+ mausb_dbg(mhcd, "%s: added %s channel for ep %i\n", __func__, 
+ ep_type, usb_endpoint_num(&ep->desc)); 
+ } 
+ 
+ return status; 
+} 
+ 
+/* 
+ * Removes an endpoint from the specified device. 
+ * 
+ * This function removes the given endpoint from the given device and releases 
+ * private endpoint data. In the mausb_hcd, devices hold their endpoints in 
+ * a linked list. 
+ * 
+ * TODO: determine & implement proper behavior when endpoint is not 
+ * associated with given device (or is associated with a different 
+ * device) 
+ */ 
+int mausb_drop_endpoint(struct usb_hcd *hcd, struct usb_device *dev, 
+ struct usb_host_endpoint *ep) 
+{ 
+ int ret = 0; 
+ struct mausb_hcd *mhcd = usb_hcd_to_mausb_hcd(hcd); 
+ struct mausb_host_ep *ma_ep = usb_to_ma_endpoint(ep); 
+ struct mausb_dev *ma_dev; 
+ struct mausb_urb *ma_urb, *next_urb; 
+ unsigned long irq_flags; 
+ 
+ if (NULL == ma_ep) { 
+ mausb_err(mhcd, "%s: cannot find data for endpoint at %p\n", 
+ __func__, ep); 
+ return -ENODEV; 
+ } 
+ 
+ ma_dev = ma_ep->mausb_dev; 
+ 
+ mausb_dbg(mhcd, "dropping endpoint at %p to USB device #%i\n", ep, 
+ dev->devnum); 
+ 
+ ret = mausb_tx_dev_mgmt_req_ep(CancelTransferReq, &mhcd->ma_dev.mgmt, 
+ ma_dev, true, ma_ep); 
+ 
+ ma_ep->ep_handle_state = MAUSB_EP_HANDLE_INACTIVE; 
+ 
+ ret = mausb_tx_dev_mgmt_req_ep(EPInactivateReq, &mhcd->ma_dev.mgmt, 
+ ma_dev, true, ma_ep); 
+ 
+ spin_lock_irqsave(&ma_ep->ep_lock, irq_flags); 
+ list_for_each_entry_safe(ma_urb, next_urb, &ma_ep->urb_list, urb_list) { 
+ 
+ mausb_unlink_giveback_urb(ma_urb, -ECONNRESET); 
+ } 
+ 
+ if (!list_empty(&ma_ep->urb_list)) { 
+ mausb_err(mhcd, "%s: could not drop all urbs for ma_ep at %p\n", 
+ __func__, ma_ep->ep); 
+ } 
+ 
+ spin_unlock_irqrestore(&ma_ep->ep_lock, irq_flags); 
+ 
+ return 0; 
+} 
+ 
+/** 
+ * This function allocates a new device and adds it onto the MA device's linked 
+ * list of usb devices. It also allocates endpoint data for the control 
+ * endpoint (EP0). 
+ * 
+ * Returns 1 on success or 0 on failure. 
+ */ 
+int mausb_alloc_dev(struct usb_hcd *hcd, struct usb_device *dev) 
+{ 
+ int status = 0; 
+ struct mausb_hcd *mhcd = usb_hcd_to_mausb_hcd(hcd); 
+ struct ma_dev *ma_dev = &mhcd->ma_dev; 
+ struct mausb_dev *mausb_dev; 
+ 
+ mausb_dev = mausb_internal_alloc_dev(ma_dev, dev, NULL); 
+ if (NULL == mausb_dev) 
+ return 0; 
+ 
+ /* add EP0 */ 
+ mausb_dbg(mhcd, "%s: adding EP0 . . .\n", __func__); 
+ status = mausb_add_endpoint(hcd, dev, &dev->ep0); 
+ 
+ /* 
+ * Don't add send the EP Request yet, usbcore hasn't set 
+ * the ep0 descriptor. Wait until a datapacket is sent. 
+ */ 
+ 
+ if (status >= 0) 
+ return 1; 
+ 
+ /* TODO: drop endpoint here if failure */ 
+ mausb_free_dev(hcd, dev); 
+ mausb_err(mhcd, "%s: could not add EP0 %i\n", __func__, status); 
+ return 0; 
+} 
+ 
+/** 
+ * USB core calls the HCD's check_bandwidth function immediately after adding 
+ * or deleting endpoints. 
+ */ 
+int mausb_check_bandwidth(struct usb_hcd *hcd, struct usb_device *dev) 
+{ 
+ int status; 
+ struct mausb_hcd *mhcd = usb_hcd_to_mausb_hcd(hcd); 
+ struct ma_dev *ma_dev = &mhcd->ma_dev; 
+ struct mausb_dev *mausb_dev = mausb_find_dev_host(ma_dev, dev); 
+ 
+ /* don't do anything if roothub */ 
+ if (NULL == dev->parent) 
+ return 0; 
+ 
+ if (NULL == mausb_dev) { 
+ mausb_err(mhcd, "%s: could not find data for USB device #%i\n", 
+ __func__, dev->devnum); 
+ return -ENODEV; 
+ } 
+ 
+ /* delete the old endpoints (if applicable) */ 
+ status = mausb_tx_dev_mgmt_req(EPHandleDeleteReq, &ma_dev->mgmt, 
+ mausb_dev, MAUSB_HOST); 
+ 
+ /* TODO: error checking (suppose the EPHandleDelete fails...) */ 
+ 
+ /* add the new endpoints (if applicable) */ 
+ status = mausb_tx_dev_mgmt_req(EPHandleReq, &ma_dev->mgmt, mausb_dev, 
+ MAUSB_HOST); 
+ 
+ if (-ENODEV == status) /* no endpoints were applicable */ 
+ status = 0; 
+ 
+ return status; 
+} 
+ 
+/** 
+ * This function will be called if mausb_add_endpoint(), mausb_drop_ep(), 
+ * or mausb_check_bandwidth returns with an error. It is supposed to revert 
+ * a device to a previously good schedule. We assume any schedule will work, 
+ * so we should, in theory, never have to revert to a previous schedule. 
+ */ 
+void mausb_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *dev) 
+{ 
+ mausb_dbg(usb_hcd_to_mausb_hcd(hcd), 
+ "resetting bandwidth for USB edvice #%i\n", dev->devnum); 
+ return; 
+} 
+ 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/drivers/mausb_mem-host.h linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/drivers/mausb_mem-host.h
--- linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/drivers/mausb_mem-host.h	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/drivers/mausb_mem-host.h	2014-11-28 12:39:00.572447000 +0800
@@ -0,0 +1,74 @@
+/* Name: mausb_mem-host.h 
+ * Description: header for mausb_mem-host.c 
+ * 
+ * This file is provided under a dual BSD/GPLv2 license. When using or 
+ * redistributing this file, you may do so under either license. 
+ * 
+ * GPL LICENSE SUMMARY 
+ * 
+ * Copyright(c) 2014 Intel Corporation. 
+ * 
+ * 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. 
+ * 
+ * Contact Information: 
+ * Sean Stalley, sean.stalley [at] intel 
+ * Stephanie Wallick, stephanie.s.wallick [at] intel 
+ * 2111 NE 25th Avenue 
+ * Hillsboro, Oregon 97124 
+ * 
+ * BSD LICENSE 
+ * 
+ * Copyright(c) 2014 Intel Corporation. 
+ * 
+ * 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 of Intel Corporation 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. 
+ */ 
+ 
+#ifndef __MAUSB_MEM_HOST_H 
+#define __MAUSB_MEM_HOST_H 
+ 
+/* endpoint/device helper functions */ 
+struct mausb_host_ep *usb_to_ma_endpoint(struct usb_host_endpoint *ep); 
+int mausb_hcd_urb_count(struct mausb_hcd *mhcd); 
+ 
+/* USB core interfaces */ 
+int mausb_alloc_dev(struct usb_hcd *hcd, struct usb_device *dev); 
+void mausb_free_dev(struct usb_hcd *hcd, struct usb_device *dev); 
+int mausb_add_endpoint(struct usb_hcd *hcd, struct usb_device *dev, 
+ struct usb_host_endpoint *ep); 
+int mausb_drop_endpoint(struct usb_hcd *hcd, struct usb_device *dev, 
+ struct usb_host_endpoint *ep); 
+int mausb_check_bandwidth(struct usb_hcd *hcd, struct usb_device *dev); 
+void mausb_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *dev); 
+ 
+#endif 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/drivers/mausb_mgmt.c linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/drivers/mausb_mgmt.c
--- linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/drivers/mausb_mgmt.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/drivers/mausb_mgmt.c	2014-11-28 12:39:00.572447000 +0800
@@ -0,0 +1,888 @@
+/* name: mausb_mgmt.c 
+ * description: Handles management packet operations common to both 
+ * hosts and devices. This includes parsing incoming packets, 
+ * as well as creating outgoing packets. 
+ * 
+ * This file is provided under a dual BSD/GPLv2 license. When using or 
+ * redistributing this file, you may do so under either license. 
+ * 
+ * GPL LICENSE SUMMARY 
+ * 
+ * Copyright(c) 2014 Intel Corporation. 
+ * 
+ * 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. 
+ * 
+ * Contact Information: 
+ * Sean Stalley, sean.stalley [at] intel 
+ * Stephanie Wallick, stephanie.s.wallick [at] intel 
+ * 2111 NE 25th Avenue 
+ * Hillsboro, Oregon 97124 
+ * 
+ * BSD LICENSE 
+ * 
+ * Copyright(c) 2014 Intel Corporation. 
+ * 
+ * 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 of Intel Corporation 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/usb.h> 
+#include <linux/slab.h> 
+ 
+#include "mausb_pkt.h" 
+#include "mausb_mgmt.h" 
+#include "mausb_mem.h" 
+#include "mausb_msapi.h" 
+#include "mausb_const.h" 
+ 
+/** 
+ * Returns the ma_dev structure for a given device. 
+ */ 
+struct ma_dev *mausb_mgmt_to_ma_dev(struct mausb_mgmt *mgmt) 
+{ 
+ return container_of(mgmt, struct ma_dev, mgmt); 
+} 
+EXPORT_SYMBOL(mausb_mgmt_to_ma_dev); 
+ 
+/** 
+ * Opens a connection to the Media Specific driver to pass management packets 
+ * to a particular MA device. 
+ * 
+ * The caller should be holding the lock protecting the MA device's data. 
+ * 
+ * Returns 0 on success, or a negative errno on failure. 
+ * 
+ * @mgmt: The struct for the management channel to the MA device. 
+ * after this function 
+ * @drv: The specific medium we are communicating with 
+ * @transfer_pkt: A pointer to the function that should be called by the 
+ * MS driver to pass incoming management packets to the 
+ * MA driver. 
+ * @pkt_sent: Completion callback for outgoing management packets. 
+ * This function will be called by the MS driver once a 
+ * packet has been sent to the medium to indicate that 
+ * it is done with the packet. Note: the completion 
+ * callback can be disabled by setting this to NULL. 
+ */ 
+int mausb_add_mgmt_channel(struct mausb_mgmt *mgmt, struct mausb_ms_drv *drv, 
+ int (*transfer_pkt)(struct ms_pkt *pkt, void *context), 
+ void (*pkt_sent)(struct ms_pkt *pkt)) 
+{ 
+ int ret = 0; 
+ struct mausb_transfer_pair tx_pair; 
+ unsigned long irq_flags; 
+ 
+ tx_pair.to_ma.transfer_packet = transfer_pkt; 
+ tx_pair.pkt_sent = pkt_sent; 
+ tx_pair.to_ma.context = mgmt; 
+ tx_pair.handle = MAUSB_MGMT_HANDLE; 
+ 
+ ret = drv->ops->add_transfer_pair(&tx_pair); 
+ 
+ if (ret >= 0) { 
+ spin_lock_irqsave(mgmt->ma_dev_lock, irq_flags); 
+ mgmt->tx_pair = tx_pair; 
+ spin_unlock_irqrestore(mgmt->ma_dev_lock, irq_flags); 
+ } 
+ 
+ return ret; 
+} 
+EXPORT_SYMBOL(mausb_add_mgmt_channel); 
+ 
+/** 
+ * Fills the fields in an endpoint handle req. 
+ * 
+ * @dev: The device struct that contains the endpoints to open. 
+ * @req_flds: The req_flds to fill. 
+ * 
+ * Note: this function can only be used on the host side. 
+ */ 
+int mausb_fill_ep_handle_req_flds(struct mausb_dev *mausb_dev, 
+ struct mausb_mgmt_pkt *req, bool add) 
+{ 
+ int i = 0; 
+ struct mausb_host_ep *ma_ep; 
+ unsigned long irq_flags; 
+ struct mausb_ss_ep_req *ss_ep_des; 
+ struct mausb_ep_req *ep_des; 
+ struct mausb_EPHandleReq_flds *req_flds = &req->ep_handle_req; 
+ struct mausb_EPHandleDelete_flds *del_flds = &req->ep_handle_delete; 
+ 
+ req_flds->num_ep_des = 0; 
+ 
+ if (USB_SPEED_SUPER == mausb_dev->dev->speed) 
+ req_flds->size_ep_des = cpu_to_le32(MAUSB_SS_EP_REQ_SIZE); 
+ else 
+ req_flds->size_ep_des = cpu_to_le32(MAUSB_EP_REQ_SIZE); 
+ 
+ /* for every endpoint */ 
+ spin_lock_irqsave(&mausb_dev->dev_lock, irq_flags); 
+ list_for_each_entry(ma_ep, &mausb_dev->ep_list, ep_list) { 
+ spin_unlock_irqrestore(&mausb_dev->dev_lock, irq_flags); 
+ spin_lock_irqsave(&ma_ep->ep_lock, irq_flags); 
+ 
+ /* if we need to add this endpoint */ 
+ if (add && (MAUSB_EP_HANDLE_UNASSIGNED 
+ == ma_ep->ep_handle_state)) { 
+ 
+ if (USB_SPEED_SUPER == mausb_dev->dev->speed && 
+ ma_ep->ep->desc.bEndpointAddress != 0x00) { 
+ ss_ep_des = &req_flds->ss_ep_des[i]; 
+ 
+ memcpy(&ss_ep_des->ep_des, 
+ &ma_ep->ep->desc, 
+ USB_DT_ENDPOINT_SIZE); 
+ 
+ memcpy(&ss_ep_des->ss_ep_comp_des, 
+ &ma_ep->ep->ss_ep_comp, 
+ USB_DT_SS_EP_COMP_SIZE); 
+ } else { 
+ ep_des = &req_flds->ep_des[i]; 
+ 
+ memcpy(&ep_des->ep_des, 
+ &ma_ep->ep->desc, 
+ USB_DT_ENDPOINT_SIZE); 
+ } 
+ 
+ if (ma_ep->ep->desc.bEndpointAddress == 0x00) 
+ req_flds->size_ep_des = MAUSB_EP_REQ_SIZE; 
+ 
+ i++; 
+ req_flds->num_ep_des = i; 
+ 
+ /* if we need to delete this endpoint */ 
+ } else if (!add && 
+ (MAUSB_EP_HANDLE_DELETED == ma_ep->ep_handle_state)) { 
+ 
+ del_flds->ep_handle[i].handle = 
+ cpu_to_le16(ma_ep->ep_handle.handle); 
+ 
+ i++; 
+ req_flds->num_ep_des = i; 
+ } 
+ 
+ spin_unlock_irqrestore(&ma_ep->ep_lock, irq_flags); 
+ 
+ spin_lock_irqsave(&mausb_dev->dev_lock, irq_flags); 
+ } 
+ 
+ spin_unlock_irqrestore(&mausb_dev->dev_lock, irq_flags); 
+ 
+ if (i <= 0) 
+ return -ENODEV; 
+ 
+ return 0; 
+} 
+ 
+/** 
+ * Looks for inactive endpoints and fills EPInactivateReq packet fields 
+ * accordingly. 
+ */ 
+int mausb_fill_ep_inactivate_req_flds(struct mausb_dev *mausb_dev, 
+ struct mausb_mgmt_pkt *req) 
+{ 
+ int i = 0; 
+ struct mausb_host_ep *ma_ep; 
+ unsigned long irq_flags; 
+ struct mausb_EPInactivateReq_flds *req_flds = &req->ep_inactivate_req; 
+ 
+ /* 
+ * Grab any inactive endpoints. After EPInactivateReq is sent, inactive 
+ * endoints will be marked for deletion. 
+ */ 
+ spin_lock_irqsave(&mausb_dev->dev_lock, irq_flags); 
+ list_for_each_entry(ma_ep, &mausb_dev->ep_list, ep_list) { 
+ spin_unlock_irqrestore(&mausb_dev->dev_lock, irq_flags); 
+ spin_lock_irqsave(&ma_ep->ep_lock, irq_flags); 
+ 
+ /* If endpoint has been inactivated, include it in packet. */ 
+ if (ma_ep->ep_handle_state == MAUSB_EP_HANDLE_INACTIVE) { 
+ req_flds->ep_handle[i] = ma_ep->ep_handle; 
+ i++; 
+ req_flds->num_ep_handles = i; 
+ ma_ep->ep_handle_state = MAUSB_EP_HANDLE_DELETED; 
+ } 
+ 
+ spin_unlock_irqrestore(&ma_ep->ep_lock, irq_flags); 
+ spin_lock_irqsave(&mausb_dev->dev_lock, irq_flags); 
+ } 
+ 
+ /*TODO: set suspend flag when needed */ 
+ 
+ spin_unlock_irqrestore(&mausb_dev->dev_lock, irq_flags); 
+ 
+ return req_flds->num_ep_handles; 
+} 
+ 
+/** 
+ * Transmits a mausb management packet req and awaits a resp 
+ * 
+ * Caller should be holding the lock in the mausb_mgmt structure. 
+ * 
+ * This function transmits a MA USB management request packet and waits for a 
+ * response. If a response packet is received, this function will return 
+ * 0 with valid data in the resp. If the request timed out, will return 
+ * -ETIMEDOUT. 
+ * 
+ * Note: since the calling process sleeps, this function CANNOT be called 
+ * from an interrupt context. 
+ * 
+ * @req: A pointer to the MA USB transferRequest packet to be sent. 
+ * @resp: A pointer to the MA USB transferResponse packet received. 
+ * @ma_mgmt: The Ma USB device's management structure. 
+ */ 
+static int internal_mausb_tx_mgmt_req(struct mausb_pkt *req, 
+ struct mausb_pkt **resp, struct mausb_mgmt *ma_mgmt) 
+{ 
+ int retries = 0; 
+ int rem_time = 0; 
+ struct mausb_mgmt_req_list *req_entry; 
+ struct mausb_pkt_transfer *transfer; 
+ unsigned long irq_flags = 0; 
+ 
+ if (NULL == ma_mgmt->tx_pair.to_ms.transfer_packet) 
+ return -EPIPE; 
+ else 
+ transfer = &ma_mgmt->tx_pair.to_ms; 
+ 
+ req_entry = kzalloc(sizeof(struct mausb_mgmt_req_list), GFP_ATOMIC); 
+ if (!req_entry) 
+ return -ENOMEM; 
+ 
+ req_entry->mgmt_req = req; 
+ req_entry->mgmt_resp = NULL; 
+ init_completion(&req_entry->resp_rcvd); 
+ INIT_LIST_HEAD(&req_entry->req_list); 
+ 
+ list_add_tail(&req_entry->req_list, &ma_mgmt->req_list); 
+ 
+ req->common->length = cpu_to_le16(mausb_pkt_length(req)); 
+ 
+ ma_mgmt->token = (ma_mgmt->token % MAUSB_MGMT_MAX_TOKEN) + 1; 
+ req->mgmt->token = ma_mgmt->token; 
+ 
+ /* until we time out or complete */ 
+ for (retries = 0; (retries <= MAUSB_MGMT_TRANSFER_RETRIES) && 
+ (NULL == req_entry->mgmt_resp); retries++) { 
+ 
+ /* if this is a retry */ 
+ if (retries > 0) 
+ req->common->ver_flags |= MAUSB_PKT_FLAG_RETRY; 
+ 
+ spin_unlock_irqrestore(ma_mgmt->ma_dev_lock, irq_flags); 
+ 
+ mausb_pkt_fill_ms_pkt(req, GFP_ATOMIC); 
+ 
+ mamgmt_dbg("%s: sending %s packet\n", __func__, 
+ mausb_type_to_string(req->common->pkt_type)); 
+ transfer->transfer_packet(&req->pkt, transfer->context); 
+ 
+ rem_time = wait_for_completion_interruptible_timeout( 
+ &req_entry->resp_rcvd, MAUSB_MGMT_RT_DELAY); 
+ 
+ spin_lock_irqsave(ma_mgmt->ma_dev_lock, irq_flags); 
+ } 
+ 
+ list_del(&req_entry->req_list); 
+ *resp = req_entry->mgmt_resp; 
+ 
+ kfree(req_entry); 
+ 
+ if (rem_time == 0) /* if we timed out */ 
+ return -ETIMEDOUT; 
+ else if (rem_time < 0) /* if an error happened */ 
+ return rem_time; 
+ else /* return based on the status of the response */ 
+ return 0; 
+} 
+ 
+/** 
+ * Accepts the EPHandleResp and EPHandleReq Fields and updates 
+ * endpoint(s) state based on the Resp Fields. 
+ */ 
+static int mausb_handle_ep_resp(struct mausb_dev *mausb_dev, 
+ struct mausb_EPHandleReq_flds *req, 
+ struct mausb_EPHandleResp_flds *resp) 
+{ 
+ int i; 
+ int ret = -EINVAL; 
+ struct mausb_host_ep *ma_ep; 
+ struct usb_endpoint_descriptor *ep_des; 
+ 
+ if (le32_to_cpu(req->num_ep_des) != le32_to_cpu(resp->num_ep_des)) 
+ return -EINVAL; 
+ 
+ for (i = 0; i < resp->num_ep_des; ++i) { 
+ 
+ ep_des = mausb_ep_handle_req_get_ep_des(req, i); 
+ if (NULL != ep_des) { 
+ 
+ ma_ep = mausb_find_ep_by_desc(ep_des, mausb_dev); 
+ if (ma_ep != NULL) 
+ ret = mausb_update_ep(ma_ep, &resp->ep_des[i]); 
+ else { 
+ mamgmt_err("%s: could not find endpoint" 
+ " for handle #%i (%x)\n", __func__, i, 
+ le16_to_cpu(resp->ep_des[i].ep_handle.handle)); 
+ } 
+ } 
+ } 
+ 
+ return ret; 
+} 
+ 
+/** 
+ * Accepts the EPHandleDeleteReq and EPHandleDeleteResp Fields and updates 
+ * the endpoint(s) state based on the Resp Fields. 
+ */ 
+static int mausb_handle_ep_del_resp(struct mausb_dev *mausb_dev, 
+ struct mausb_EPHandleDelete_flds *req, 
+ struct mausb_EPHandleDelete_flds *resp) 
+{ 
+ int ret = 0; 
+ int i, j; 
+ bool drop_failed; 
+ struct mausb_host_ep *ma_ep; 
+ struct mausb_ep_handle *req_handle; 
+ struct mausb_ms_drv *ms_driver = mausb_dev->ma_dev->ms_driver; 
+ 
+ /* for every endpoint in the req */ 
+ for (i = 0; i < req->num_ep; ++i) { 
+ 
+ drop_failed = false; 
+ req_handle = &req->ep_handle[i]; 
+ 
+ for (j = 0; j < le32_to_cpu(resp->num_ep); ++j) { 
+ if (req_handle->handle == 
+ le16_to_cpu(resp->ep_handle[j].handle)) 
+ 
+ drop_failed = true; 
+ } 
+ 
+ if (false == drop_failed) { 
+ 
+ ma_ep = mausb_find_ep_by_handle(req_handle, mausb_dev); 
+ 
+ ret = ms_driver->ops->drop_transfer_pair( 
+ ma_ep->ep_handle.handle, 
+ ma_ep->tx_pair.to_ms.context); 
+ 
+ if (0 <= ret) { 
+ /* drop the endpoint locally */ 
+ ret = mausb_internal_drop_ep(ma_ep); 
+ } 
+ } 
+ } 
+ 
+ return ret; 
+} 
+ 
+/** 
+ * Determines the speed to report in the USBDevHandleReq. 
+ */ 
+static __u8 mausb_get_dev_speed(struct mausb_dev *dev) 
+{ 
+ switch (dev->dev->speed) { 
+ case USB_SPEED_LOW: 
+ return MAUSB_LOW_SPEED; 
+ case USB_SPEED_FULL: 
+ return MAUSB_FULL_SPEED; 
+ case USB_SPEED_HIGH: 
+ return MAUSB_HIGH_SPEED; 
+ case USB_SPEED_SUPER: 
+ return MAUSB_SUPER_SPEED; 
+ /* TODO: SUPER_SPEED_PLUS */ 
+ default: 
+ return MAUSB_INVALID_SPEED; 
+ } 
+} 
+ 
+/** 
+ * Parses all descriptors for a given CapResp packet and stores data in 
+ * corresponding device data structure. 
+ * 
+ * Returns number of descriptors read. 
+ */ 
+int parse_cap_desc(struct mausb_pkt *resp, struct ma_dev *ma_dev) 
+{ 
+ int ret = 0; 
+ int offset = 0; 
+ int desc_count = resp->mgmt->cap_resp.desc_count; 
+ struct mausb_dev_cap_desc *desc; 
+ 
+ offset = MAUSB_PKT_HEADER_SIZE + sizeof(struct mausb_CapResp_flds); 
+ desc = cap_desc_ptr_increment(resp->mgmt, offset); 
+ 
+ if (resp->common->pkt_type != CapResp) { 
+ mamgmt_err("%s: packet is type %i (not a CapResp)\n", __func__, 
+ resp->common->pkt_type); 
+ return -EINVAL; 
+ } 
+ 
+ while (desc_count) { 
+ if (desc == NULL) { 
+ mamgmt_err("%s: no descriptor to read\n", __func__); 
+ return ret; 
+ } 
+ 
+ ret++; 
+ 
+ switch (desc->cap_type) { 
+ case MAUSB_DEV_CAP_SPEED: 
+ ma_dev->speed = kzalloc( 
+ sizeof(struct mausb_dev_cap_speed), 
+ GFP_ATOMIC); 
+ ma_dev->speed->speed = desc->speed.speed; 
+ ma_dev->speed->lse = desc->speed.lse; 
+ ma_dev->speed->st = desc->speed.st; 
+ ma_dev->speed->lane_count = 
+ desc->speed.lane_count; 
+ ma_dev->speed->link_protocol = 
+ desc->speed.link_protocol; 
+ ma_dev->speed->lsm = desc->speed.lsm; 
+ break; 
+ case MAUSB_DEV_CAP_POUT: 
+ ma_dev->pout = kzalloc( 
+ sizeof(struct mausb_dev_cap_pout), 
+ GFP_ATOMIC); 
+ ma_dev->pout->elastic_buf_cap = 
+ desc->pout.elastic_buf_cap; 
+ ma_dev->pout->drop_notif = 
+ desc->pout.drop_notif; 
+ break; 
+ case MAUSB_DEV_CAP_ISO: 
+ ma_dev->pout = kzalloc( 
+ sizeof(struct mausb_dev_cap_iso), 
+ GFP_ATOMIC); 
+ ma_dev->iso->iso_alignment = 
+ desc->iso.iso_alignment; 
+ break; 
+ case MAUSB_DEV_CAP_SYNC: 
+ ma_dev->pout = kzalloc( 
+ sizeof(struct mausb_dev_cap_sync), 
+ GFP_ATOMIC); 
+ ma_dev->sync->media_time_avail = 
+ desc->sync.media_time_avail; 
+ ma_dev->sync->timestamp_req = 
+ desc->sync.timestamp_req; 
+ break; 
+ case MAUSB_DEV_CAP_CONT_ID: 
+ ma_dev->pout = kzalloc( 
+ sizeof(struct mausb_dev_cap_cont_id), 
+ GFP_ATOMIC); 
+ ma_dev->cont_id->cont_id_upper = 
+ desc->cont_id.cont_id_upper; 
+ ma_dev->cont_id->cont_id_lower = 
+ desc->cont_id.cont_id_lower; 
+ break; 
+ case MAUSB_DEV_CAP_LINK_SLEEP: 
+ ma_dev->link_sleep = kzalloc( 
+ sizeof(struct mausb_dev_cap_link_sleep), 
+ GFP_ATOMIC); 
+ ma_dev->link_sleep->link_sleep_cap = 
+ desc->link_sleep.link_sleep_cap; 
+ break; 
+ default: 
+ mamgmt_err("%s: unknown device capability descriptor" 
+ " type %i\n", __func__, desc->cap_type); 
+ ret--; 
+ break; 
+ } 
+ 
+ desc_count--; 
+ offset += desc->length; 
+ desc = cap_desc_ptr_increment(resp->mgmt, offset); 
+ } 
+ 
+ return ret; 
+} 
+ 
+/** 
+ * Transmits a management packet of the specified type for the given device. 
+ * 
+ * @type: The type of MA USB management request packet being sent. 
+ * @mgmt: The management data we need to send the packet. 
+ * @dev: The device this packet is associated with. Set to NULL if 
+ * there is no associated device (ex: for MAUSBDevReset). 
+ * @host: Set TRUE to indicate we are a host, set to FALSE if we are 
+ * a device. 
+ */ 
+int mausb_tx_dev_mgmt_req(enum mausb_pkt_type type, struct mausb_mgmt *mgmt, 
+ struct mausb_dev *dev, bool host) 
+{ 
+ return mausb_tx_dev_mgmt_req_ep(type, mgmt, dev, host, NULL); 
+} 
+EXPORT_SYMBOL(mausb_tx_dev_mgmt_req); 
+ 
+/** 
+ * Only necessary to call directly if you need to specify an EP, otherwise 
+ * mausb_tx_dev_mgmt_req will work. 
+ */ 
+int mausb_tx_dev_mgmt_req_ep(enum mausb_pkt_type type, struct mausb_mgmt *mgmt, 
+ struct mausb_dev *dev, bool host, struct mausb_host_ep *ma_ep) 
+{ 
+ int ret = 0; 
+ struct mausb_pkt *req; 
+ struct mausb_pkt *resp = NULL; 
+ struct ma_dev *ma_dev = mausb_mgmt_to_ma_dev(mgmt); 
+ struct mausb_dev *hub; 
+ unsigned long irq_flags; 
+ 
+ req = mausb_alloc_pkt(MAUSB_PKT_TYPE_MGMT, &ret, GFP_ATOMIC); 
+ if (!req) 
+ return -ENOMEM; 
+ 
+ spin_lock_irqsave(mgmt->ma_dev_lock, irq_flags); 
+ 
+ req->common->ver_flags |= MAUSB_VERSION_1_0; 
+ req->common->pkt_type = type; 
+ if (NULL != dev) 
+ req->common->dev_handle = cpu_to_le16(dev->dev_handle); 
+ 
+ req->common->ma_dev_addr = ma_dev->ma_dev_addr; 
+ req->common->mass_id = ma_dev->mass_id; 
+ req->common->pkt_status = NO_ERROR; 
+ 
+ if (host) 
+ req->common->ver_flags |= MAUSB_PKT_FLAG_HOST; 
+ 
+ switch (type) { 
+ case CapReq: 
+ req->mgmt->cap_req.max_mgmt_reqs = MAUSB_MGMT_MAX_TOKEN; 
+ ret = internal_mausb_tx_mgmt_req(req, &resp, mgmt); 
+ 
+ if (0 <= ret) { 
+ ma_dev->ma_cap.num_ep = resp->mgmt->cap_resp.num_ep; 
+ ma_dev->ma_cap.num_dev = resp->mgmt->cap_resp.num_dev; 
+ ma_dev->ma_cap.num_stream = 
+ resp->mgmt->cap_resp.num_stream; 
+ ma_dev->ma_cap.dev_type = resp->mgmt->cap_resp.dev_type; 
+ ma_dev->ma_cap.max_tx_reqs = 
+ resp->mgmt->cap_resp.max_tx_reqs; 
+ ma_dev->ma_cap.max_mgmt_reqs = 
+ resp->mgmt->cap_resp.max_mgmt_reqs; 
+ 
+ /* look for descriptors */ 
+ if (resp->mgmt->cap_resp.desc_count > 0) { 
+ ret = parse_cap_desc(resp, ma_dev); 
+ 
+ if (ret != resp->mgmt->cap_resp.desc_count) { 
+ mamgmt_err("%s: error reading" 
+ " capability descriptors\n", 
+ __func__); 
+ } 
+ } 
+ } 
+ break; 
+ 
+ case EPHandleReq: 
+ mausb_fill_ep_handle_req_flds(dev, req->mgmt, MAUSB_ADD); 
+ ret = internal_mausb_tx_mgmt_req(req, &resp, mgmt); 
+ if (0 <= ret) { 
+ ret = mausb_handle_ep_resp(dev, 
+ &req->mgmt->ep_handle_req, 
+ &resp->mgmt->ep_handle_resp); 
+ } 
+ break; 
+ case EPActivateReq: 
+ case EPInactivateReq: 
+ ret = mausb_fill_ep_inactivate_req_flds(dev, req->mgmt); 
+ if (ret > 0) 
+ ret = internal_mausb_tx_mgmt_req(req, &resp, mgmt); 
+ break; 
+ case EPResetReq: 
+ case EPClearTransferReq: 
+ break; 
+ case EPHandleDeleteReq: 
+ mausb_fill_ep_handle_req_flds(dev, req->mgmt, MAUSB_DEL); 
+ 
+ if (0 < le32_to_cpu(req->mgmt->ep_handle_delete.num_ep)) { 
+ ret = internal_mausb_tx_mgmt_req(req, &resp, mgmt); 
+ 
+ mausb_handle_ep_del_resp(dev, 
+ &req->mgmt->ep_handle_delete, 
+ &resp->mgmt->ep_handle_delete); 
+ } 
+ break; 
+ case USBDevHandleReq: 
+ req->mgmt->usb_dev_handle_req.dock_hub 
+ = cpu_to_le16(mgmt->hub_dev_handle); 
+ req->mgmt->usb_dev_handle_req.usb_rt_str 
+ = cpu_to_le32(dev->dev->route); 
+ req->mgmt->usb_dev_handle_req.speed = 
+ cpu_to_le32(mausb_get_dev_speed(dev)); 
+ req->common->dev_handle = 0; 
+ 
+ spin_unlock_irqrestore(mgmt->ma_dev_lock, irq_flags); 
+ hub = mausb_find_dev(ma_dev, dev->dev->parent, NULL, NULL); 
+ spin_lock_irqsave(mgmt->ma_dev_lock, irq_flags); 
+ 
+ if (NULL != hub) { 
+ /* This will work if the device is connected directly to 
+ * the dock, but not with a hub connected to the dock... 
+ * well... unless the hub in between is slower than high 
+ * speed. */ 
+ /* TODO: have the parent hub point to the proper hub for 
+ * all conditions */ 
+ req->mgmt->usb_dev_handle_req.parent_hub = 
+ hub->dev_handle; 
+ req->mgmt->usb_dev_handle_req.parent_hub_port = 
+ dev->dev->portnum; 
+ } else { 
+ /* parent_hub_port not set for SS */ 
+ mamgmt_dbg("%s: could not find parent hub at %p\n", 
+ __func__, dev->dev->parent); 
+ } 
+ 
+ /* TODO: all the remaining fields */ 
+ req->mgmt->usb_dev_handle_req.mtt = 0; 
+ 
+ ret = internal_mausb_tx_mgmt_req(req, &resp, mgmt); 
+ 
+ if (resp && (NULL != dev)) 
+ dev->dev_handle = 
+ le16_to_cpu(resp->mgmt->usb_dev_handle_resp); 
+ break; 
+ 
+ case DevResetReq: 
+ ret = internal_mausb_tx_mgmt_req(req, &resp, mgmt); 
+ break; 
+ case ModifyEP0Req: 
+ if (NULL == ma_ep) { 
+ mamgmt_err("%s: no ep0 for USB device at %p\n", 
+ __func__, dev); 
+ } else { 
+ req->mgmt->modify_ep0_req.ep_handle = ma_ep->ep_handle; 
+ req->mgmt->modify_ep0_req.max_pkt_size = 
+ usb_endpoint_maxp(&ma_ep->ep->desc); 
+ } 
+ 
+ ret = internal_mausb_tx_mgmt_req(req, &resp, mgmt); 
+ if (0 <= ret) { 
+ if (SUCCESS == resp->common->pkt_status) { 
+ if (resp->mgmt->modify_ep0_resp.ep_handle.handle) { 
+ ma_ep->ep_handle = resp->mgmt->modify_ep0_resp.ep_handle; 
+ } 
+ } else 
+ ret = -EIO; 
+ } 
+ break; 
+ case SetUSBDevAddrReq: 
+ /* TODO: verify timer value */ 
+ req->mgmt->set_dev_addr_req.resp_timeout = 
+ cpu_to_le16(MAUSB_MGMT_RT_DELAY * (1000/HZ)); 
+ 
+ ret = internal_mausb_tx_mgmt_req(req, &resp, mgmt); 
+ 
+ if (0 <= ret) { 
+ if (SUCCESS == resp->common->pkt_status) { 
+ dev->dev_address = 
+ le32_to_cpu( 
+ resp->mgmt->set_dev_addr_resp.dev_addr); 
+ } else 
+ ret = -EIO; 
+ } 
+ break; 
+ case UpdateDevReq: 
+ break; 
+ case USBDevDisconnectReq: 
+ ret = internal_mausb_tx_mgmt_req(req, &resp, mgmt); 
+ break; 
+ case DevDisconnectReq: 
+ req->common->dev_handle = 0; 
+ ret = internal_mausb_tx_mgmt_req(req, &resp, mgmt); 
+ break; 
+ case SleepReq: /* fallthrough */ 
+ case WakeReq: 
+ ret = internal_mausb_tx_mgmt_req(req, &resp, mgmt); 
+ /* not everyone supports power management yet */ 
+ /* if (SUCCESS != resp->common->pkt_status) 
+ ret = -EBUSY; */ 
+ break; 
+ case RemoteWakeReq: 
+ case PingReq: 
+ case DevInitDisconnectReq: 
+ case SyncReq: 
+ break; 
+ case CancelTransferReq: 
+ req->mgmt->cancel_transfer_req.ep_handle = ma_ep->ep_handle; 
+ /* TODO: stream IDs (where applicable) */ 
+ req->mgmt->cancel_transfer_req.req_id = 
+ ma_ep->state.active_request_id; 
+ ret = internal_mausb_tx_mgmt_req(req, &resp, mgmt); 
+ /* TODO: handle Responses */ 
+ break; 
+ case USBDevResetReq: 
+ case VendorSpecificReq: 
+ break; 
+ default: 
+ ret = -EINVAL; 
+ break; 
+ } 
+ 
+ if (resp != NULL) 
+ mausb_free_pkt(resp); 
+ 
+ spin_unlock_irqrestore(mgmt->ma_dev_lock, irq_flags); 
+ mausb_free_pkt(req); 
+ 
+ return ret; 
+} 
+EXPORT_SYMBOL(mausb_tx_dev_mgmt_req_ep); 
+ 
+/** 
+ * Parses an incoming management packet resp. 
+ * 
+ * This function parses an incoming response packet and connects it to 
+ * its associated request. 
+ * 
+ * @resp: A pointer to the MA USB management response packet received. 
+ * @ma_mgmt: The MA USB device's management structure. 
+ */ 
+int mausb_rx_mgmt_resp(struct mausb_pkt *resp, struct mausb_mgmt *ma_mgmt) 
+{ 
+ struct mausb_mgmt_req_list *ma_mgmt_req; 
+ unsigned long irq_flags; 
+ 
+ spin_lock_irqsave(ma_mgmt->ma_dev_lock, irq_flags); 
+ 
+ list_for_each_entry(ma_mgmt_req, &ma_mgmt->req_list, req_list) { 
+ 
+ /* if we found the request that triggered this response */ 
+ if (ma_mgmt_req->mgmt_req->mgmt->token == resp->mgmt->token) { 
+ ma_mgmt_req->mgmt_resp = resp; 
+ 
+ complete_all(&ma_mgmt_req->resp_rcvd); 
+ spin_unlock_irqrestore(ma_mgmt->ma_dev_lock, irq_flags); 
+ return 0; 
+ } 
+ } 
+ 
+ /* response given was not requested */ 
+ spin_unlock_irqrestore(ma_mgmt->ma_dev_lock, irq_flags); 
+ 
+ mausb_free_pkt(resp); 
+ 
+ return -EINVAL; 
+} 
+ 
+/** 
+ * This function parses an incoming request packet and generates the 
+ * appropriate response packet. 
+ * 
+ * @resp: A pointer to the MA USB management request packet received. 
+ * @ma_mgmt: The MA USB device's management structure. 
+ */ 
+int mausb_rx_mgmt_req(struct mausb_pkt *req, struct mausb_mgmt *mgmt) 
+{ 
+ int ret; 
+ struct mausb_pkt *resp; 
+ struct ma_dev *ma_dev = mausb_mgmt_to_ma_dev(mgmt); 
+ struct mausb_pkt_transfer *transfer = &mgmt->tx_pair.to_ms; 
+ unsigned long irq_flags; 
+ 
+ resp = mausb_alloc_pkt(MAUSB_PKT_TYPE_MGMT, &ret, GFP_ATOMIC); 
+ if (!resp) 
+ return -ENOMEM; 
+ 
+ spin_lock_irqsave(mgmt->ma_dev_lock, irq_flags); 
+ 
+ ret = mgmt->req_switch(req->mgmt, resp->mgmt, mgmt); 
+ 
+ if (ret >= 0) { 
+ /* set the values common to all response packets */ 
+ resp->common->ver_flags |= MAUSB_VERSION_1_0; 
+ /* type set above */ 
+ resp->common->length = cpu_to_le16(mausb_pkt_length(resp)); 
+ /* device handle set above */ 
+ resp->common->ma_dev_addr = ma_dev->ma_dev_addr; 
+ resp->common->mass_id = ma_dev->mass_id; 
+ /* pkt_status set above */ 
+ resp->mgmt->token = req->mgmt->token; 
+ 
+ mausb_pkt_fill_ms_pkt(resp, GFP_ATOMIC); 
+ mamgmt_dbg("%s: sending %s packet\n", __func__, 
+ mausb_type_to_string(resp->common->pkt_type)); 
+ 
+ spin_unlock_irqrestore(mgmt->ma_dev_lock, irq_flags); 
+ transfer->transfer_packet(&resp->pkt, transfer->context); 
+ spin_lock_irqsave(mgmt->ma_dev_lock, irq_flags); 
+ 
+ } else { 
+ /* we don't know how to handle this packet */ 
+ mamgmt_dbg("%s: packet type %s not supported\n", __func__, 
+ mausb_type_to_string(resp->common->pkt_type)); 
+ mausb_free_pkt(resp); 
+ } 
+ 
+ spin_unlock_irqrestore(mgmt->ma_dev_lock, irq_flags); 
+ return ret; 
+} 
+ 
+/** 
+ * This function parses an incoming management packet, determines 
+ * if it is a request or response, and passes the packet to the 
+ * proper handler. 
+ * 
+ * @mgmt_pkt: A pointer to the incoming MA USB management packet. 
+ * @ma_mgmt: The MA USB device's management structure. 
+ */ 
+int mausb_rx_mgmt(struct mausb_pkt *mgmt_pkt, struct mausb_mgmt *mgmt) 
+{ 
+ mamgmt_dbg("%s: %s packet received\n", __func__, 
+ mausb_type_to_string(mgmt_pkt->common->pkt_type)); 
+ 
+ if (mausb_pkt_resp(mgmt_pkt)) 
+ return mausb_rx_mgmt_resp(mgmt_pkt, mgmt); 
+ else 
+ return mausb_rx_mgmt_req(mgmt_pkt, mgmt); 
+} 
+EXPORT_SYMBOL(mausb_rx_mgmt); 
+ 
+/** 
+ * Handles sent callback for management packets. 
+ * 
+ * Request packets are held until a response is received and should not be 
+ * freed until then. Response packets can be freed as soon as they are sent out. 
+ */ 
+void mausb_mgmt_pkt_sent(struct ms_pkt *ms_pkt) 
+{ 
+ struct mausb_pkt *pkt; 
+ 
+ pkt = ms_pkt_to_mausb_pkt(ms_pkt); 
+ 
+ if (mausb_pkt_resp(pkt)) 
+ mausb_free_pkt(pkt); 
+} 
+EXPORT_SYMBOL(mausb_mgmt_pkt_sent); 
+ 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/drivers/mausb_mgmt.h linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/drivers/mausb_mgmt.h
--- linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/drivers/mausb_mgmt.h	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/drivers/mausb_mgmt.h	2014-11-28 12:39:00.572447000 +0800
@@ -0,0 +1,88 @@
+/* name: mausb_mgmt.h 
+ * description: Handles management packet structures and declarations common 
+ * to both hosts and devices. 
+ * 
+ * This file is provided under a dual BSD/GPLv2 license. When using or 
+ * redistributing this file, you may do so under either license. 
+ * 
+ * GPL LICENSE SUMMARY 
+ * 
+ * Copyright(c) 2014 Intel Corporation. 
+ * 
+ * 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. 
+ * 
+ * Contact Information: 
+ * Sean Stalley, sean.stalley [at] intel 
+ * Stephanie Wallick, stephanie.s.wallick [at] intel 
+ * 2111 NE 25th Avenue 
+ * Hillsboro, Oregon 97124 
+ * 
+ * BSD LICENSE 
+ * 
+ * Copyright(c) 2014 Intel Corporation. 
+ * 
+ * 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 of Intel Corporation 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. 
+ */ 
+ 
+#ifndef __MAUSB_MGMT_H 
+#define __MAUSB_MGMT_H 
+ 
+#include "mausb_mem.h" 
+#include "mausb_msapi.h" 
+ 
+#ifdef DEBUG 
+#define mamgmt_dbg(format, arg...) \ 
+ printk(KERN_DEBUG format, ##arg) 
+#else 
+#define mamgmt_dbg(format, arg...) 
+#endif 
+ 
+#define mamgmt_warn(format, arg...) \ 
+ printk(KERN_WARNING format, ##arg) 
+ 
+#define mamgmt_err(format, arg...) \ 
+ printk(KERN_ERR format, ##arg) 
+ 
+struct ma_dev *mausb_mgmt_to_ma_dev(struct mausb_mgmt *mgmt); 
+int mausb_tx_dev_mgmt_req(enum mausb_pkt_type type, struct mausb_mgmt *mgmt, 
+ struct mausb_dev *dev, bool host); 
+int mausb_tx_dev_mgmt_req_ep(enum mausb_pkt_type type, struct mausb_mgmt *mgmt, 
+ struct mausb_dev *dev, bool host, struct mausb_host_ep *ma_ep); 
+int mausb_rx_mgmt(struct mausb_pkt *mgmt_pkt, struct mausb_mgmt *mgmt); 
+void mausb_mgmt_pkt_sent(struct ms_pkt *pkt); 
+int mausb_add_mgmt_channel(struct mausb_mgmt *mgmt, struct mausb_ms_drv *drv, 
+ int (*transfer_pkt)(struct ms_pkt *pkt, void *context), 
+ void (*pkt_sent)(struct ms_pkt *pkt)); 
+ 
+#endif 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/drivers/mausb_msapi.c linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/drivers/mausb_msapi.c
--- linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/drivers/mausb_msapi.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/drivers/mausb_msapi.c	2014-11-28 12:39:00.572447000 +0800
@@ -0,0 +1,84 @@
+/* Name: mausb_msapi.c 
+ * Description: This file contains helper functions for using the msapi. 
+ * 
+ * This file is provided under a dual BSD/GPLv2 license. When using or 
+ * redistributing this file, you may do so under either license. 
+ * 
+ * GPL LICENSE SUMMARY 
+ * 
+ * Copyright(c) 2014 Intel Corporation. 
+ * 
+ * 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. 
+ * 
+ * Contact Information: 
+ * Sean Stalley, sean.stalley [at] intel 
+ * Stephanie Wallick, stephanie.s.wallick [at] intel 
+ * 2111 NE 25th Avenue 
+ * Hillsboro, Oregon 97124 
+ * 
+ * BSD LICENSE 
+ * 
+ * Copyright(c) 2014 Intel Corporation. 
+ * 
+ * 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 of Intel Corporation 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/slab.h> 
+#include <linux/uio.h> 
+#include "mausb_msapi.h" 
+ 
+int mausb_transfer_packet(struct ms_pkt *pkt, 
+ struct mausb_pkt_transfer *transfer) 
+{ 
+ return transfer->transfer_packet(pkt, transfer->context); 
+} 
+EXPORT_SYMBOL(mausb_transfer_packet); 
+ 
+/** 
+ * Calculates the total length of the data in a ms_pkt. Returns the total 
+ * length of the data in the ms_pkt, or a negative errno. 
+ */ 
+int mausb_ms_pkt_length(struct ms_pkt *pkt) 
+{ 
+ int i; 
+ int total_length = 0; 
+ 
+ for (i = 0; i < pkt->nents; ++i) 
+ total_length += pkt[i].kvec->iov_len; 
+ 
+ pr_debug("%s: total *kvec length: %i\n", __func__, total_length); 
+ 
+ return total_length; 
+} 
+
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/drivers/mausb_msapi.h linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/drivers/mausb_msapi.h
--- linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/drivers/mausb_msapi.h	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/drivers/mausb_msapi.h	2014-11-28 12:39:00.572447000 +0800
@@ -0,0 +1,231 @@
+/* Name: mausb_msapi.h 
+ * Description: This header describes how the media agnostic driver 
+ * interfaces with a media specific driver. 
+ * 
+ * This file is provided under a dual BSD/GPLv2 license. When using or 
+ * redistributing this file, you may do so under either license. 
+ * 
+ * GPL LICENSE SUMMARY 
+ * 
+ * Copyright(c) 2014 Intel Corporation. 
+ * 
+ * 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. 
+ * 
+ * Contact Information: 
+ * Sean Stalley, sean.stalley [at] intel 
+ * Stephanie Wallick, stephanie.s.wallick [at] intel 
+ * 2111 NE 25th Avenue 
+ * Hillsboro, Oregon 97124 
+ * 
+ * BSD LICENSE 
+ * 
+ * Copyright(c) 2014 Intel Corporation. 
+ * 
+ * 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 of Intel Corporation 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. 
+ */ 
+ 
+/********************** Initial MS Registration **********************/ 
+ 
+/* The MS driver must initially register with the MA driver to make the 
+ * inital connection. this is done via a call to mausb_register_ms_driver 
+ * (see mausb_hcd.c for details) 
+ */ 
+ 
+/************************ Packet Send/Recieve ************************/ 
+ 
+/* Packets are transferred between the MS and the MA driver via function 
+ * calls into each other. When the MA driver has a packet to send out, it 
+ * makes a function call into the MS driver with the packet it wishes to 
+ * send. Likewise, the MS driver calls into the MA driver if it needs to 
+ * pass it a packet. 
+ */ 
+ 
+/********************** Transfer Pair Add/Remove *********************/ 
+ 
+/* 
+ * The MA driver establishes a new transfer pair for every independant 
+ * connection (ie: one for every independant endpoint, as well as one 
+ * for every device). To establish a new connection, the MA driver 
+ * calls into the MS driver with an incomplete mausb_transfer_pair. 
+ * this incomplete pair includes only the data needed to call into 
+ * the MA driver. 
+ */ 
+ 
+#ifndef __MAUSB_MSAPI_H 
+#define __MAUSB_MSAPI_H 
+ 
+#include <linux/uio.h> 
+ 
+/** 
+ * Offset in Bytes of location of length field - streaming mediums need to 
+ * know where the length field is in a packet so they can determine where 
+ * packets begin and end in the stream. 
+ */ 
+#define MAUSB_PKT_LENGTH_OFFSET 2 
+ 
+/* the largest number of segments that will ever be in a mausb packet */ 
+#define MAUSB_PKT_MAX_NR_SEGS 3 
+ 
+/* This is a convenience structure for keeping the number of entries in 
+ * the kvec with its pointer. 
+ * 
+ * @kvec: The pointer to the ma_pkt kvec or iovec. 
+ * @nents: The number of entires in the ma_pkt kvec or iovec. 
+ */ 
+struct ms_pkt { 
+ union { 
+ struct kvec kvec[MAUSB_PKT_MAX_NR_SEGS]; 
+ struct iovec iovec[MAUSB_PKT_MAX_NR_SEGS]; 
+ }; 
+ int nents; 
+}; 
+ 
+ 
+/** 
+ * This struct defines a one way connection for passing packets from one 
+ * driver to the other. 
+ * 
+ * @transfer_packet: The function call to use when you want to transmit 
+ * a packet. 
+ * @context: The context to use in the function when calling the 
+ * transfer packet. 
+ */ 
+struct mausb_pkt_transfer { 
+ int (*transfer_packet)(struct ms_pkt *pkt, void *context); 
+ void *context; 
+}; 
+ 
+int mausb_transfer_packet(struct ms_pkt *pkt, 
+ struct mausb_pkt_transfer *transfer); 
+ 
+/** 
+ * This struct defines a pair of connections to and from an independant 
+ * endpoint or device. 
+ * 
+ * @to_ma: The transfer to use when passing a packet to the MA driver 
+ * from the MS driver. 
+ * @to_ms: The transfer to use when passing a packet to the MS driver 
+ * from the MA driver. 
+ * @pkt_sent: Packet completion routine. Called by the MS driver into 
+ * the MA driver after the packet has been put onto the medium. 
+ * @handle: A unique identifier for this particualar transfer pair. 
+ * In our implementation, we use the EP/Device Handle. 
+ * For the management channel, set handle to MAUSB_MGMT_HANDLE. 
+ */ 
+ 
+#define MAUSB_MGMT_HANDLE 0 
+ 
+struct mausb_transfer_pair { 
+ struct mausb_pkt_transfer to_ma; 
+ struct mausb_pkt_transfer to_ms; 
+ void (*pkt_sent)(struct ms_pkt *pkt); 
+ unsigned int handle; 
+}; 
+ 
+struct urb; 
+ 
+/** 
+ * This struct defines all the calls the MA USB-HCD Driver can make 
+ * to a media specific driver. 
+ * 
+ * @add_transfer_pair: Used to establish a new transfer pair. 
+ * @tx_pair [IN/OUT]: An incomplete transfer pair. The MA driver 
+ * completes the to_ma field and passes it to 
+ * the MA driver. The MS driver fills the 
+ * to_ma field and returns the pointer. 
+ * @drop_transfer_pair: Used to remove an existing transfer pair. 
+ * @handle [IN]: The unique identifier of the transfer pair 
+ * to remove. 
+ * @pkt_destructor: Used to destroy a packet that was received from 
+ * the medium. Acts as a hook to allow the medium to 
+ * free any media specific data for a packet. 
+ * @pkt [IN] The packet the MA driver wishes to free. 
+ */ 
+struct mausb_ms_ops { 
+ int (*add_transfer_pair)(struct mausb_transfer_pair *tx_pair); 
+ int (*drop_transfer_pair)(unsigned long handle, void *context); 
+ void (*pkt_destructor)(struct ms_pkt *pkt); 
+}; 
+ 
+/** 
+ * This struct defines all of the media-specific parameters needed by 
+ * the MA driver. 
+ * 
+ * TODO: add spec-defined and implementation-specific variables 
+ */ 
+struct mausb_ms_params { 
+ 
+ 
+}; 
+ 
+/** 
+ * This structure includes all of the data needed by the MA driver to 
+ * communicate with the Media Specific Driver. 
+ * 
+ * @ops: Contains function pointers to all of the functions the 
+ * MA driver will ever need to call. 
+ * @params: Contains all of the media-specific paramaters that the 
+ * MA driver needs. 
+ */ 
+struct mausb_ms_drv { 
+ struct mausb_ms_ops *ops; 
+ struct mausb_ms_params *params; 
+}; 
+ 
+/** 
+ * This structure includes all of the ways the Media Specific Driver 
+ * is capable of calling to the Media Agnostic Driver. 
+ * 
+ * @device_connect: Called to indicate that a device has been connected 
+ * and is ready to receive MA packets. 
+ * @pkt_dmux: Used for passing packets into the driver. It will 
+ * parse the packet to determine what endpoint/device 
+ * it belongs to. Used when the medium cannot keep 
+ * data channels seperate. 
+ * @pkt_sent: Used as a notification that a packet has been sent 
+ * out. 
+ */ 
+struct mausb_ma_drv { 
+ int (*device_connect)(int); 
+ struct mausb_pkt_transfer pkt_dmux; 
+ /* TODO: implement pkt_sent indicator */ 
+ /* void (*pkt_sent)(struct ms_pkt *pkt); */ 
+}; 
+ 
+/* function declarations */ 
+struct mausb_ma_drv *mausb_register_ms_driver(struct mausb_ms_drv *drv); 
+struct mausb_ma_drv *maudc_register_ms_driver(struct mausb_ms_drv *drv); 
+int mausb_ms_pkt_length(struct ms_pkt *pkt); 
+ 
+#endif 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/drivers/mausb_pkt.c linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/drivers/mausb_pkt.c
--- linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/drivers/mausb_pkt.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/drivers/mausb_pkt.c	2014-11-28 12:39:00.572447000 +0800
@@ -0,0 +1,1038 @@
+/* name: mausb_pkt.c 
+ * description: MA USB packet helper functions 
+ * 
+ * This file is provided under a dual BSD/GPLv2 license. When using or 
+ * redistributing this file, you may do so under either license. 
+ * 
+ * GPL LICENSE SUMMARY 
+ * 
+ * Copyright(c) 2014 Intel Corporation. 
+ * 
+ * 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. 
+ * 
+ * Contact Information: 
+ * Sean Stalley, sean.stalley [at] intel 
+ * Stephanie Wallick, stephanie.s.wallick [at] intel 
+ * 2111 NE 25th Avenue 
+ * Hillsboro, Oregon 97124 
+ * 
+ * BSD LICENSE 
+ * 
+ * Copyright(c) 2014 Intel Corporation. 
+ * 
+ * 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 of Intel Corporation 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/slab.h> 
+#include <linux/usb/ch9.h> 
+#include <linux/usb.h> 
+ 
+#include "mausb_mem.h" 
+#include "mausb_pkt.h" 
+#include "mausb_const.h" 
+ 
+/** 
+ * Translates numerical packet type into corresponding string (for printing). 
+ */ 
+const char *mausb_type_to_string(enum mausb_pkt_type type) 
+{ 
+ switch (type) { 
+ case CapReq: 
+ return "CapReq"; 
+ case CapResp: 
+ return "CapResp"; 
+ case USBDevHandleReq: 
+ return "USBDevHandleReq"; 
+ case USBDevHandleResp: 
+ return "USBDevHandleResp"; 
+ case EPHandleReq: 
+ return "EPHandleReq"; 
+ case EPHandleResp: 
+ return "EPHandleResp"; 
+ case EPActivateReq: 
+ return "EPActivateReq"; 
+ case EPActivateResp: 
+ return "EPActivateResp"; 
+ case EPInactivateReq: 
+ return "EPInactivateReq"; 
+ case EPInactivateResp: 
+ return "EPInactivateResp"; 
+ case EPResetReq: 
+ return "EPResetReq"; 
+ case EPResetResp: 
+ return "EPResetResp"; 
+ case EPClearTransferReq: 
+ return "EPClearTransferReq"; 
+ case EPClearTransferResp: 
+ return "EPClearTransferResp"; 
+ case EPHandleDeleteReq: 
+ return "EPHandleDeleteReq"; 
+ case EPHandleDeleteResp: 
+ return "EPHandleDeleteResp"; 
+ case DevResetReq: 
+ return "DevResetReq"; 
+ case DevResetResp: 
+ return "DevResetResp"; 
+ case ModifyEP0Req: 
+ return "ModifyEP0Req"; 
+ case ModifyEP0Resp: 
+ return "ModifyEP0Resp"; 
+ case SetUSBDevAddrReq: 
+ return "SetUSBDevAddrReq"; 
+ case SetUSBDevAddrResp: 
+ return "SetUSBDevAddrResp"; 
+ case UpdateDevReq: 
+ return "UpdateDevReq"; 
+ case UpdateDevResp: 
+ return "UpdateDevResp"; 
+ case USBDevDisconnectReq: 
+ return "USBDevDisconnectReq"; 
+ case USBDevDisconnectResp: 
+ return "USBDevDisconnectResp"; 
+ case USBSuspendReq: 
+ return "USBSuspendReq"; 
+ case USBSuspendResp: 
+ return "USBSuspendResp"; 
+ case USBResumeReq: 
+ return "USBResumeReq"; 
+ case USBResumeResp: 
+ return "USBResumeResp"; 
+ case RemoteWakeReq: 
+ return "RemoteWakeReq"; 
+ case RemoteWakeResp: 
+ return "RemoteWakeResp"; 
+ case PingReq: 
+ return "PingReq"; 
+ case PingResp: 
+ return "PingResp"; 
+ case DevDisconnectReq: 
+ return "DevDisconnectReq"; 
+ case DevDisconnectResp: 
+ return "DevDisconnectResp"; 
+ case DevInitDisconnectReq: 
+ return "DevInitDisconnectReq"; 
+ case DevInitDisconnectResp: 
+ return "DevInitDisconnectResp"; 
+ case SyncReq: 
+ return "SyncReq"; 
+ case SyncResp: 
+ return "SyncResp"; 
+ case CancelTransferReq: 
+ return "CancelTransferReq"; 
+ case CancelTransferResp: 
+ return "CancelTransferResp"; 
+ case EPOpenStreamReq: 
+ return "EPOpenStreamReq"; 
+ case EPOpenStreamResp: 
+ return "EPOpenStreamResp"; 
+ case EPCloseStreamReq: 
+ return "EPCloseStreamReq"; 
+ case EPCloseStreamResp: 
+ return "EPCloseStreamResp"; 
+ case USBDevResetReq: 
+ return "USBDevResetReq"; 
+ case USBDevResetResp: 
+ return "USBDevResetResp"; 
+ case DevNotificationReq: 
+ return "DevNotificationReq"; 
+ case DevNotificationResp: 
+ return "DevNotificationResp"; 
+ case EPSetKeepAliveReq: 
+ return "EPSetKeepAliveReq"; 
+ case EPSetKeepAliveResp: 
+ return "EPSetKeepAliveResp"; 
+ case GetPortBWReq: 
+ return "GetPortBWReq"; 
+ case GetPortBWResp: 
+ return "GetPortBWResp"; 
+ case SleepReq: 
+ return "SleepReq"; 
+ case SleepResp: 
+ return "SleepResp"; 
+ case WakeReq: 
+ return "WakeReq"; 
+ case WakeResp: 
+ return "WakeResp"; 
+ case VendorSpecificReq: 
+ return "VendorSpecificReq"; 
+ case VendorSpecificResp: 
+ return "VendorSpecificResp"; 
+ case TransferSetupReq: 
+ return "TransferSetupReq"; 
+ case TransferSetupResp: 
+ return "TransferSetupResp"; 
+ case TransferTearDownConf: 
+ return "TransferTearDownConf"; 
+ case TransferReq: 
+ return "TransferReq"; 
+ case TransferResp: 
+ return "TransferResp"; 
+ case TransferAck: 
+ return "TransferAck"; 
+ case IsochTransferReq: 
+ return "IsochTransferReq"; 
+ case IsochTransferResp: 
+ return "IsochTransferResp"; 
+ } 
+ 
+ return "unknown"; 
+} 
+EXPORT_SYMBOL(mausb_type_to_string); 
+ 
+/** 
+ * Translates a negative errno to a MAUSB status. Returns a packet status value. 
+ */ 
+enum mausb_pkt_status mausb_errno_to_ma_status(int errno) 
+{ 
+ switch (errno) { 
+ case 0: /* no error */ 
+ return SUCCESS; 
+ case -EINPROGRESS: 
+ return TRANSFER_PENDING; 
+ case -ESTRPIPE: 
+ return TRANSFER_EP_STALL; 
+ /* TODO: map all relevant ma status' */ 
+ default: 
+ return UNSUCCESSFUL; 
+ } /* end switch */ 
+ 
+} 
+EXPORT_SYMBOL(mausb_errno_to_ma_status); 
+ 
+/** 
+ * Translates an URB status to a MAUSB status 
+ */ 
+int mausb_to_urb_status(enum mausb_pkt_status pkt_status) 
+{ 
+ switch (pkt_status) { 
+ case SUCCESS: /* no error */ 
+ return 0; 
+ case TRANSFER_PENDING: 
+ return -EINPROGRESS; 
+ case TRANSFER_EP_STALL: 
+ return -ESTRPIPE; 
+ /* TODO: map all relevant urb statuses */ 
+ default: 
+ return -EIO; /* generic I/O error */ 
+ } /* end switch */ 
+ 
+} 
+EXPORT_SYMBOL(mausb_to_urb_status); 
+ 
+/** 
+ * Determines if the packet is a response packet. Returns true if the packet is 
+ * a response packet. Returns false otherwise. 
+ */ 
+bool mausb_pkt_resp(struct mausb_pkt *pkt) 
+{ 
+ return pkt->common->pkt_type & MAUSB_PKT_RESP_FLAG; 
+} 
+ 
+/** 
+ * Determines if a given packet is a management packet. 
+ */ 
+static bool mausb_pkt_is_mgmt(struct mausb_pkt_common *common) 
+{ 
+ if ((common->pkt_type & MAUSB_PKT_TYPE_MASK) == MAUSB_PKT_TYPE_MGMT) 
+ return true; 
+ else 
+ return false; 
+} 
+ 
+ 
+/** 
+ * Returns the sum of the sequnce number & the value added. Handles sequence 
+ * number wraparound. 
+ */ 
+u32 mausb_seq_num_add(u32 seq_num, int val) 
+{ 
+ return (seq_num + val) % (MAUSB_MAX_SEQ_NUM + 1); 
+} 
+EXPORT_SYMBOL(mausb_seq_num_add); 
+ 
+/** 
+ * Increments a sequence number value by one. 
+ */ 
+void mausb_increment_seq_num(u32 *seq_num) 
+{ 
+ *seq_num = mausb_seq_num_add(*seq_num, 1); 
+} 
+ 
+/** 
+ * Compares two sequence numbers. Returns true if a is less than b. 
+ * Handles sequence number wraparound. 
+ */ 
+bool mausb_seq_num_lt(u32 a, u32 b) 
+{ 
+ 
+ if (a > MAUSB_MAX_SEQ_NUM || b > MAUSB_MAX_SEQ_NUM) { 
+ mapkt_warn("%s: input out of range\n", __func__); 
+ return false; 
+ } 
+ 
+ if (b < MAUSB_HALF_SEQ_NUM) { /* b is in the lower half */ 
+ 
+ if ((b > a) || ((b + MAUSB_HALF_SEQ_NUM) < a)) 
+ return true; 
+ else 
+ return false; 
+ 
+ } else { /* b is in the upper half */ 
+ 
+ if ((b > a) && (b - MAUSB_HALF_SEQ_NUM) < a) 
+ return true; 
+ else 
+ return false; 
+ } 
+ 
+ /* we should never get here */ 
+ BUG(); 
+ return false; 
+} 
+EXPORT_SYMBOL(mausb_seq_num_lt); 
+ 
+/** 
+ * Sequence number less than or equal to. 
+ */ 
+bool mausb_seq_num_lt_eq(u32 a, u32 b) 
+{ 
+ return mausb_seq_num_lt(b, a) ? false : true; 
+} 
+ 
+/** 
+ * Sequence number greater than or equal to. 
+ */ 
+bool mausb_seq_num_gt_eq(u32 a, u32 b) 
+{ 
+ return mausb_seq_num_lt(a, b) ? false : true; 
+} 
+ 
+/** 
+ * Sequence number greater than. 
+ */ 
+bool mausb_seq_num_gt(u32 a, u32 b) 
+{ 
+ return mausb_seq_num_lt(b, a); 
+} 
+EXPORT_SYMBOL(mausb_seq_num_gt); 
+ 
+/** 
+ * Returns the sum of the request id and the value added. Handles request id 
+ * wraparound. 
+ */ 
+u8 mausb_req_id_add(u8 req_id, int val) 
+{ 
+ return (req_id + val) % (MAUSB_MAX_REQ_ID + 1); 
+} 
+EXPORT_SYMBOL(mausb_req_id_add); 
+ 
+/** 
+ * Compares 2 request IDs. Returns true if a is less than b. Handles request id 
+ * wraparound. 
+ */ 
+bool mausb_req_id_lt(u8 a, u8 b) 
+{ 
+ 
+ if (a > MAUSB_MAX_REQ_ID || b > MAUSB_MAX_REQ_ID) { 
+ mapkt_warn("%s: input out of range\n", __func__); 
+ return false; 
+ } 
+ 
+ if (b < MAUSB_HALF_REQ_ID) { /* b is in the lower half */ 
+ 
+ if ((b > a) || ((b + MAUSB_HALF_REQ_ID) < a)) 
+ return true; 
+ else 
+ return false; 
+ 
+ } else { /* b is in the upper half */ 
+ 
+ if ((b > a) && (b - MAUSB_HALF_REQ_ID) < a) 
+ return true; 
+ else 
+ return false; 
+ } 
+ 
+ /* we should never get here */ 
+ BUG(); 
+ return false; 
+} 
+EXPORT_SYMBOL(mausb_req_id_lt); 
+ 
+bool mausb_req_id_gt(u8 a, u8 b) 
+{ 
+ return mausb_req_id_lt(b, a); 
+} 
+ 
+bool mausb_req_id_gt_eq(u8 a, u8 b) 
+{ 
+ return mausb_req_id_lt(a, b) ? false : true; 
+} 
+EXPORT_SYMBOL(mausb_req_id_gt_eq); 
+ 
+/** 
+ * Finds an endpoint descriptor inside of an endpoint handle request 
+ */ 
+struct usb_endpoint_descriptor *mausb_ep_handle_req_get_ep_des( 
+ struct mausb_EPHandleReq_flds *req, int i) 
+{ 
+ 
+ if (i >= le32_to_cpu(req->num_ep_des)) { 
+ mapkt_warn("%s: endpoint descriptor not in packet\n", __func__); 
+ return NULL; 
+ } 
+ 
+ if (MAUSB_EP_REQ_SIZE == le32_to_cpu(req->size_ep_des)) { 
+ return (struct usb_endpoint_descriptor *) 
+ &req->ep_des[i].ep_des; 
+ 
+ } else if (MAUSB_SS_EP_REQ_SIZE == le32_to_cpu(req->size_ep_des)) { 
+ return (struct usb_endpoint_descriptor *) 
+ &req->ss_ep_des[i].ep_des; 
+ 
+ } else { 
+ mapkt_err("%s: unsupported size_ep_des value (%u)\n", 
+ __func__, le32_to_cpu(req->size_ep_des)); 
+ } 
+ 
+ return NULL; 
+} 
+EXPORT_SYMBOL(mausb_ep_handle_req_get_ep_des); 
+ 
+static struct mausb_pkt_common *mausb_header_from_ms_pkt(struct ms_pkt *pkt) 
+{ 
+ struct mausb_pkt_common *header; 
+ 
+ if (pkt->kvec[0].iov_len < sizeof(*header)) { 
+ mapkt_err("%s: first entry too small for header\n", __func__); 
+ header = NULL; 
+ } else 
+ header = pkt->kvec[0].iov_base; 
+ 
+ return header; 
+} 
+ 
+/** 
+ * Accepts an MA USB packet for the MA device and forwards it to the correct 
+ * handler based on packet type and endpoint/device handle. 
+ */ 
+int mausb_pkt_dmux(struct ms_pkt *pkt, void *context) 
+{ 
+ int ret = -EINVAL; 
+ struct mausb_pkt_common *header = mausb_header_from_ms_pkt(pkt); 
+ struct ma_dev *ma_dev = context_to_ma_dev(context); 
+ struct mausb_host_ep *ma_ep = NULL; 
+ struct mausb_pkt_transfer *transfer = NULL; 
+ 
+ if (mausb_pkt_is_mgmt(header)) { 
+ transfer = &ma_dev->mgmt.tx_pair.to_ma; 
+ 
+ } else { 
+ /* otherwise, find the endpoint it belongs to */ 
+ ma_ep = mausb_find_ep_from_handle(header->ep_handle, 
+ ma_dev); 
+ 
+ if (NULL != ma_ep) 
+ transfer = &ma_ep->tx_pair.to_ma; 
+ } 
+ 
+ if (NULL != transfer) 
+ ret = transfer->transfer_packet(pkt, transfer->context); 
+ 
+ return ret; 
+} 
+ 
+/** 
+ * Packet destructor for packets generated by the MA driver. For packets that we 
+ * have created, we want to free the header but not the data buffers (since the 
+ * buffers belong to the URB). 
+ */ 
+static void mausb_pkt_destructor(struct ms_pkt *ms_pkt) 
+{ 
+ struct mausb_pkt *ma_pkt = ms_pkt_to_mausb_pkt(ms_pkt); 
+ 
+ kfree(ma_pkt->common); 
+ 
+ return; 
+} 
+ 
+/** 
+ * Allocates space for given packet type. 
+ */ 
+struct mausb_pkt *mausb_alloc_pkt(enum mausb_pkt_type pkt_type, int *status, 
+ gfp_t memflags) 
+{ 
+ int size; 
+ int ret = 0; 
+ struct mausb_pkt *pkt; 
+ 
+ /* determine header length */ 
+ switch (pkt_type & MAUSB_PKT_TYPE_MASK) { 
+ 
+ case MAUSB_PKT_TYPE_MGMT: 
+ size = sizeof(struct mausb_mgmt_pkt); 
+ break; 
+ case MAUSB_PKT_TYPE_CTRL: 
+ size = sizeof(struct mausb_ctrl_pkt); 
+ break; 
+ case MAUSB_PKT_TYPE_DATA: 
+ size = sizeof(struct mausb_iso_dph); 
+ break; 
+ default: 
+ mapkt_err("%s: could not determine packet type\n", __func__); 
+ if (NULL != status) 
+ *status = -EINVAL; 
+ return NULL; 
+ } 
+ 
+ pkt = kzalloc(sizeof(struct mausb_pkt), memflags); 
+ if (NULL == pkt) { 
+ ret = -ENOMEM; 
+ pkt = NULL; 
+ } else { 
+ pkt->common = kzalloc(size, memflags); 
+ if (NULL == pkt->common) { 
+ mapkt_err("could not allocate memory for MA USB" 
+ " packet header of length %i\n", size); 
+ kfree(pkt); 
+ ret = -ENOMEM; 
+ pkt = NULL; 
+ } 
+ 
+ pkt->ms_pkt_destructor = &mausb_pkt_destructor; 
+ pkt->orig_pkt = &pkt->pkt; 
+ } 
+ 
+ if (NULL != status) 
+ *status = ret; 
+ 
+ return pkt; 
+} 
+ 
+/** 
+ * Deletes the given data packet 
+ */ 
+void mausb_free_pkt(struct mausb_pkt *pkt) 
+{ 
+ /* kill the buffers (when necessary) */ 
+ pkt->ms_pkt_destructor(pkt->orig_pkt); 
+ kfree(pkt); 
+} 
+EXPORT_SYMBOL(mausb_free_pkt); 
+ 
+/** 
+ * Returns the length of the header or a negative errno. 
+ */ 
+int mausb_pkt_header_length(struct mausb_pkt_common *header) 
+{ 
+ int length; 
+ 
+ switch (header->pkt_type & MAUSB_PKT_TYPE_MASK) { 
+ 
+ case MAUSB_PKT_TYPE_MGMT: 
+ case MAUSB_PKT_TYPE_CTRL: 
+ length = le16_to_cpu(header->length); 
+ break; 
+ case MAUSB_PKT_TYPE_DATA: 
+ length = sizeof(struct mausb_dph); 
+ break; 
+ default: 
+ mapkt_err("%s:invalid packet type\n", __func__); 
+ length = -EINVAL; 
+ break; 
+ } 
+ 
+ return length; 
+} 
+EXPORT_SYMBOL(mausb_pkt_header_length); 
+ 
+/** 
+ * Returns a pointer to a buffer of specified length that is 
+ * found offset a given number of bytes into the ms_pkt. 
+ * 
+ * If a contigious buffer can be found, this function returns 
+ * the virtual address of this buffer. otherwise, it returns null 
+ */ 
+static void *mausb_get_buf_from_ms_pkt(struct ms_pkt *pkt, 
+ int offset, int buf_length) 
+{ 
+ int i; 
+ int page_offset = offset; 
+ char *ret = NULL; 
+ struct kvec *current_kvec; 
+ 
+ for (i = 0; i < pkt->nents; ++i) { 
+ current_kvec = &pkt->kvec[i]; 
+ 
+ /* if the buffer is in this kvec entry */ 
+ if (page_offset < current_kvec->iov_len) { 
+ 
+ /* and the whole buffer is in current_kvec */ 
+ if (page_offset + buf_length <= current_kvec->iov_len) { 
+ ret = (char *) current_kvec->iov_base; 
+ ret += page_offset; 
+ } 
+ 
+ return ret; 
+ } 
+ 
+ page_offset -= current_kvec->iov_len; 
+ } 
+ 
+ if (0 != page_offset) { 
+ mapkt_err("%s: offset of %i Bytes is greater than packet" 
+ " length\n", __func__, page_offset); 
+ } 
+ return NULL; 
+} 
+ 
+bool mausb_pkt_has_setup_data(struct mausb_dph *header) 
+{ 
+ /* 
+ * Only control transfer requests with sequence number 0 should have 
+ * setup data - nothing else should ever carry setup data. 
+ */ 
+ if (header->common.pkt_type == TransferReq) { 
+ if ((header->eps_tflags & MAUSB_PKT_TFLAG_TYPE_MASK) 
+ == MAUSB_PKT_TFLAG_TYPE_CTRL 
+ && le32_to_cpu(header->seq_num) == 0) 
+ return true; 
+ } 
+ 
+ return false; 
+} 
+EXPORT_SYMBOL(mausb_pkt_has_setup_data); 
+ 
+/** 
+ * Gets an mausb_pkt structure from a given ms_pkt structure. 
+ * 
+ * can only be used if this driver created the packet i.e. if you just received 
+ * an ms_pkt from another machine, it will not be part of a mausb_pkt. 
+ */ 
+struct mausb_pkt *ms_pkt_to_mausb_pkt(struct ms_pkt *ms_pkt) 
+{ 
+ return container_of(ms_pkt, struct mausb_pkt, pkt); 
+} 
+ 
+/** 
+ * Creates a mausb_pkt structure from a given ms_pkt structure. Used for parsing 
+ * incoming packets. 
+ */ 
+struct mausb_pkt *mausb_pkt_from_ms_pkt(struct ms_pkt *ms_pkt, 
+ void (*ms_pkt_destructor)(struct ms_pkt *ms_pkt), gfp_t mem_flags) 
+{ 
+ struct mausb_pkt *pkt; 
+ int current_offset; 
+ int packet_length; 
+ 
+ pkt = kzalloc(sizeof(struct mausb_pkt), mem_flags); 
+ if (NULL == pkt) 
+ return NULL; 
+ 
+ pkt->pkt = *ms_pkt; 
+ pkt->orig_pkt = ms_pkt; 
+ pkt->ms_pkt_destructor = ms_pkt_destructor; 
+ 
+ /* the first portion is always the header */ 
+ pkt->common = mausb_header_from_ms_pkt(ms_pkt); 
+ current_offset = mausb_pkt_header_length(pkt->common); 
+ packet_length = pkt->common->length; 
+ 
+ /* checks to see if header is contigious */ 
+ if (NULL == mausb_get_buf_from_ms_pkt(ms_pkt, 0, current_offset)) { 
+ 
+ mapkt_err("%s: packet header bigger than entry (header is %i" 
+ " bytes)\n", __func__, current_offset); 
+ kfree(pkt); 
+ return NULL; 
+ } 
+ 
+ /* 
+ * NOTE: Currently control and management packets must be contigious. 
+ * data packet headers must also be contigious. 
+ * (ie: the data must all be in 1 ms_pkt entry). 
+ * 
+ * TODO: handle when a control/management is in more than 1 
+ * kvec entry 
+ */ 
+ 
+ if (MAUSB_PKT_TYPE_DATA == 
+ (pkt->common->pkt_type & MAUSB_PKT_TYPE_MASK)) { 
+ 
+ if (mausb_pkt_has_setup_data(pkt->data)) { 
+ pkt->setup = mausb_get_buf_from_ms_pkt(ms_pkt, 
+ current_offset, sizeof(*pkt->setup)); 
+ 
+ if (NULL == pkt->setup) { 
+ mapkt_err("%s: could not get setup data\n", 
+ __func__); 
+ } else { 
+ current_offset += sizeof(*pkt->setup); 
+ } 
+ } 
+ 
+ if (packet_length > current_offset) { 
+ pkt->buffer = mausb_get_buf_from_ms_pkt(ms_pkt, 
+ current_offset, packet_length - current_offset); 
+ 
+ /* 
+ * if the remaining data was contigious, treat it as a 
+ * buffer 
+ */ 
+ if (NULL != pkt->buffer) { 
+ pkt->buffer_length = 
+ packet_length - current_offset; 
+ current_offset += pkt->buffer_length; 
+ } 
+ 
+ } else if (packet_length < current_offset) { 
+ mapkt_dbg("%s: packet_length:%i, current_offset:%i\n", 
+ __func__, packet_length, current_offset); 
+ } 
+ } 
+ 
+ /* checks to see if there is data after packet */ 
+ if (NULL != mausb_get_buf_from_ms_pkt(ms_pkt, current_offset, 0)) 
+ mapkt_warn("%s: Warning: data exists after packet\n", __func__); 
+ 
+ return pkt; 
+ 
+} 
+EXPORT_SYMBOL(mausb_pkt_from_ms_pkt); 
+ 
+/** 
+ * Fills the ms_pkt of a given mausb_pkt based on fields in the mausb_pkt struct. 
+ */ 
+int mausb_pkt_fill_ms_pkt(struct mausb_pkt *pkt, gfp_t mem_flags) 
+{ 
+ struct ms_pkt *ms_pkt = &pkt->pkt; 
+ unsigned int ent_length; 
+ 
+ ms_pkt->nents = 0; 
+ 
+ if (NULL != pkt->common) { 
+ /* add the header */ 
+ ent_length = mausb_pkt_header_length(pkt->common); 
+ if (0 >= ent_length) { 
+ return -EINVAL; 
+ } 
+ 
+ } else { /* We should ALWAYS have a header, and we dont... */ 
+ mapkt_err("%s: header not found\n", __func__); 
+ return -EINVAL; 
+ } 
+ 
+ ms_pkt->kvec[ms_pkt->nents].iov_base = pkt->common; 
+ ms_pkt->kvec[ms_pkt->nents].iov_len = ent_length; 
+ ms_pkt->nents += 1; 
+ 
+ /* If this packet should have data, send it */ 
+ if (pkt->common->pkt_type == TransferReq || 
+ pkt->common->pkt_type == TransferResp){ 
+ 
+ /* add the setup field */ 
+ if (mausb_pkt_has_setup_data(pkt->data)) { 
+ ms_pkt->kvec[ms_pkt->nents].iov_base = pkt->setup; 
+ ms_pkt->kvec[ms_pkt->nents].iov_len = 
+ sizeof(*pkt->setup); 
+ ms_pkt->nents += 1; 
+ 
+ } else if (NULL != pkt->setup) { 
+ mapkt_warn("%s: Warning: packet has Setup field, but " 
+ "flags in header are not set\n", __func__); 
+ } 
+ 
+ if (NULL != pkt->buffer && pkt->nents > 0) { 
+ mapkt_err("%s: packet has scatterlist and databuffer\n" 
+ , __func__); 
+ return -EINVAL; 
+ } 
+ 
+ /* add the data buffer */ 
+ if (NULL != pkt->buffer) { 
+ ms_pkt->kvec[ms_pkt->nents].iov_base = pkt->buffer; 
+ ms_pkt->kvec[ms_pkt->nents].iov_len = 
+ pkt->buffer_length; 
+ ms_pkt->nents += 1; 
+ } 
+ } 
+ 
+ mapkt_dbg("%s: pkt filled with %i entries\n", __func__, ms_pkt->nents); 
+ 
+ return 0; 
+} 
+ 
+/** 
+ * Calculates the total length of data contained in an ms_pkt (in bytes). 
+ * Returns the length of the kvec, or 0 on an error. 
+ */ 
+static int mausb_ms_data_length(struct ms_pkt *pkt) 
+{ 
+ int i; 
+ int total_length; 
+ struct kvec *current_kvec; 
+ 
+ for (i = 0; i < pkt->nents; ++i) { 
+ current_kvec = &pkt->kvec[i]; 
+ if (NULL == current_kvec) 
+ return -EINVAL; 
+ else 
+ total_length += current_kvec->iov_len; 
+ } 
+ 
+ return total_length; 
+} 
+ 
+/** 
+ * Calculates the length of the datafield in a given datapacket. 
+ */ 
+static int mausb_pkt_datafield_length(struct mausb_pkt *pkt) 
+{ 
+ int length = 0; 
+ 
+ if (NULL != pkt->buffer) 
+ length += pkt->buffer_length; 
+ if (0 != pkt->nents) 
+ length += mausb_ms_data_length(&pkt->pkt); 
+ 
+ return length; 
+} 
+ 
+/** 
+ * Parses the packet fields to determine how long the packet is. Returns the 
+ * packet length on sucess, or a negative errno on error. 
+ */ 
+int mausb_pkt_length(struct mausb_pkt *pkt) 
+{ 
+ int length; 
+ 
+ /* all packets have this field */ 
+ switch (pkt->common->pkt_type & MAUSB_PKT_TYPE_MASK) { 
+ 
+ /* Management packets */ 
+ case MAUSB_PKT_TYPE_MGMT: 
+ length = sizeof(*pkt->common); 
+ length += MAUSB_MGMT_TOKEN_PAD_LEN; 
+ 
+ /* subtypes without additional data */ 
+ switch (pkt->common->pkt_type) { 
+ case DevResetReq: 
+ case DevResetResp: 
+ case UpdateDevResp: 
+ case DevDisconnectReq: 
+ case DevDisconnectResp: 
+ case USBDevDisconnectReq: 
+ case USBDevDisconnectResp: 
+ case SleepReq: 
+ case SleepResp: 
+ case WakeReq: 
+ case WakeResp: 
+ case RemoteWakeReq: 
+ case RemoteWakeResp: 
+ case PingReq: 
+ case PingResp: 
+ case DevInitDisconnectReq: 
+ case DevInitDisconnectResp: 
+ case SyncResp: 
+ break; 
+ 
+ /* subtypes with constant length additional data */ 
+ case CapReq: 
+ length += sizeof(pkt->mgmt->cap_req); 
+ break; 
+ case CapResp: 
+ length += sizeof(pkt->mgmt->cap_resp); 
+ /* also include length of any descriptors */ 
+ length += pkt->mgmt->cap_resp.desc_length; 
+ break; 
+ case USBDevHandleReq: 
+ length += sizeof(pkt->mgmt->usb_dev_handle_req); 
+ break; 
+ case USBDevHandleResp: 
+ length += sizeof(pkt->mgmt->usb_dev_handle_resp); 
+ break; 
+ case ModifyEP0Req: 
+ length += sizeof(pkt->mgmt->modify_ep0_req); 
+ break; 
+ case ModifyEP0Resp: 
+ length += sizeof(pkt->mgmt->modify_ep0_resp); 
+ break; 
+ case SetUSBDevAddrReq: 
+ length += sizeof(pkt->mgmt->set_dev_addr_req); 
+ break; 
+ case SetUSBDevAddrResp: 
+ length += sizeof(pkt->mgmt->set_dev_addr_resp); 
+ break; 
+ case UpdateDevReq: 
+ length += sizeof(pkt->mgmt->update_dev_req); 
+ break; 
+ case SyncReq: 
+ length += sizeof(pkt->mgmt->synch_req); 
+ break; 
+ case EPCloseStreamReq: 
+ length += sizeof(pkt->mgmt->ep_close_stream_req); 
+ break; 
+ case CancelTransferReq: 
+ length += sizeof(pkt->mgmt->cancel_transfer_req); 
+ break; 
+ case CancelTransferResp: 
+ length += sizeof(pkt->mgmt->cancel_transfer_resp); 
+ break; 
+ case EPOpenStreamReq: 
+ length += sizeof(pkt->mgmt->ep_open_stream_req); 
+ break; 
+ /* subtypes with variable length additional data */ 
+ case EPHandleReq: 
+ length += sizeof(__u32); 
+ length += pkt->mgmt->ep_handle_req.num_ep_des * 
+ pkt->mgmt->ep_handle_req.size_ep_des; 
+ break; 
+ case EPHandleResp: 
+ length += sizeof(__u32); 
+ length += pkt->mgmt->ep_handle_resp.num_ep_des * 
+ sizeof(struct mausb_ep_des); 
+ break; 
+ case EPActivateReq: 
+ case EPActivateResp: 
+ case EPInactivateReq: 
+ case EPInactivateResp: 
+ case EPResetReq: 
+ case EPResetResp: 
+ case EPClearTransferReq: 
+ case EPClearTransferResp: 
+ case EPHandleDeleteReq: /* FALLTHROUGH */ 
+ case EPHandleDeleteResp: 
+ length += sizeof(__u32); 
+ length += pkt->mgmt->ep_handle_delete.num_ep 
+ * sizeof(struct mausb_ep_handle); 
+ break; 
+ case EPCloseStreamResp: 
+ case USBDevResetReq: 
+ case USBDevResetResp: 
+ case EPOpenStreamResp: 
+ case VendorSpecificReq: 
+ case VendorSpecificResp: 
+ mapkt_err("%s: cannot determine length of %s packet -" 
+ " packet type not yet handled\n", __func__, 
+ mausb_type_to_string(pkt->common->pkt_type)); 
+ BUG(); 
+ break; 
+ default: 
+ mapkt_err("%s: invalid management packet type %x\n", 
+ __func__, pkt->common->pkt_type); 
+ BUG(); 
+ break; 
+ } 
+ 
+ break; 
+ 
+ /* Control Packets */ 
+ case MAUSB_PKT_TYPE_CTRL: 
+ length = sizeof(struct mausb_ctrl_pkt); 
+ switch (pkt->common->pkt_type) { 
+ case TransferSetupReq: 
+ length += sizeof(struct mausb_TransferSetupReq_flds); 
+ break; 
+ case TransferSetupResp: 
+ break; 
+ case TransferTearDownConf: 
+ break; 
+ default: 
+ mapkt_err("%s: invalid control packet type %x\n", 
+ __func__, pkt->common->pkt_type); 
+ BUG(); 
+ break; 
+ } 
+ break; 
+ 
+ /* Data Packets */ 
+ case MAUSB_PKT_TYPE_DATA: 
+ 
+ length = sizeof(struct mausb_dph); 
+ 
+ switch (pkt->common->pkt_type) { 
+ case TransferReq: 
+ case TransferResp: /* FALLTHROUGH */ 
+ if (mausb_pkt_has_setup_data(pkt->data)) 
+ length += sizeof(*pkt->setup); 
+ 
+ length += mausb_pkt_datafield_length(pkt); 
+ break; 
+ case TransferAck: 
+ break; 
+ case IsochTransferReq: 
+ case IsochTransferResp: /* FALLTHROUGH */ 
+ length = sizeof(struct mausb_iso_dph); 
+ length += mausb_pkt_datafield_length(pkt); 
+ 
+ break; 
+ default: 
+ mapkt_err("%s: invalid data packet type %x\n", __func__, 
+ pkt->common->pkt_type); 
+ BUG(); 
+ break; 
+ } 
+ break; 
+ 
+ default: 
+ mapkt_err("%s: invalid packet type %x\n", __func__, 
+ pkt->common->pkt_type); 
+ BUG(); 
+ break; 
+ } 
+ 
+ return length; 
+} 
+EXPORT_SYMBOL(mausb_pkt_length); 
+ 
+/** 
+ * Finds and returns the memory location offset a number of bytes from a 
+ * CapResp packet. Used to find or place device capability descriptors in 
+ * a CapResp packet. 
+ */ 
+struct mausb_dev_cap_desc *cap_desc_ptr_increment(struct mausb_mgmt_pkt *resp, 
+ int offset) 
+{ 
+ struct mausb_dev_cap_desc *desc; 
+ char *temp; 
+ 
+ temp = (char *) resp; 
+ temp += offset; 
+ 
+ desc = (struct mausb_dev_cap_desc *) (temp); 
+ 
+ return desc; 
+} 
+EXPORT_SYMBOL(cap_desc_ptr_increment); 
+ 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/drivers/mausb_pkt.h linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/drivers/mausb_pkt.h
--- linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/drivers/mausb_pkt.h	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/drivers/mausb_pkt.h	2014-11-28 12:39:00.572447000 +0800
@@ -0,0 +1,914 @@
+/* name: mausb_pkt.h 
+ * description: library of MA USB packet structures 
+ * 
+ * This file is provided under a dual BSD/GPLv2 license. When using or 
+ * redistributing this file, you may do so under either license. 
+ * 
+ * GPL LICENSE SUMMARY 
+ * 
+ * Copyright(c) 2014 Intel Corporation. 
+ * 
+ * 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. 
+ * 
+ * Contact Information: 
+ * Sean Stalley, sean.stalley [at] intel 
+ * Stephanie Wallick, stephanie.s.wallick [at] intel 
+ * 2111 NE 25th Avenue 
+ * Hillsboro, Oregon 97124 
+ * 
+ * BSD LICENSE 
+ * 
+ * Copyright(c) 2014 Intel Corporation. 
+ * 
+ * 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 of Intel Corporation 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. 
+ */ 
+ 
+#ifndef __MAUSB_PKT_H__ 
+#define __MAUSB_PKT_H__ 
+ 
+#include <linux/usb/ch9.h> 
+#include "mausb_msapi.h" 
+ 
+#ifdef DEBUG 
+#define mapkt_dbg(format, arg...) \ 
+ printk(KERN_DEBUG format, ##arg) 
+#else 
+#define mapkt_dbg(format, arg...) 
+#endif 
+ 
+#define mapkt_warn(format, arg...) \ 
+ printk(KERN_WARNING format, ##arg) 
+ 
+#define mapkt_err(format, arg...) \ 
+ printk(KERN_ERR format, ##arg) 
+ 
+/* protocol Version, per section 6.2.1.1 */ 
+#define MAUSB_VERSION_1_0 0x0 
+#define MAUSB_VERSION_MASK 0x0F 
+ 
+/* packet Flags, per section 6.2.1.2 */ 
+#define MAUSB_PKT_FLAG_MASK 0xF0 
+#define MAUSB_PKT_FLAG_HOST (1 << 4) 
+#define MAUSB_PKT_FLAG_RETRY (1 << 5) 
+#define MAUSB_PKT_FLAG_TIMESTAMP (1 << 6) 
+ 
+/* packet Types, per section 6.2.1.3 */ 
+#define MAUSB_PKT_TYPE_MASK 0xC0 
+#define MAUSB_PKT_TYPE_MGMT (0 << 6) 
+#define MAUSB_PKT_TYPE_CTRL (1 << 6) 
+#define MAUSB_PKT_TYPE_DATA (2 << 6) 
+ 
+/* packet Subtypes, section 6.2.1.3 */ 
+#define MAUSB_SUBTYPE_MASK 0x3F 
+ 
+enum mausb_pkt_type { 
+ /* Management packets */ 
+ CapReq = 0x00 | MAUSB_PKT_TYPE_MGMT, 
+ CapResp , /* 1 */ 
+ USBDevHandleReq , /* 2 */ 
+ USBDevHandleResp , /* 3 */ 
+ 
+ EPHandleReq , /* 4 */ 
+ EPHandleResp , /* 5 */ 
+ EPActivateReq , /* 6 */ 
+ EPActivateResp , /* 7 */ 
+ EPInactivateReq , /* 8 */ 
+ EPInactivateResp , /* 9 */ 
+ EPResetReq , /* 10 */ 
+ EPResetResp , /* 11 */ 
+ EPClearTransferReq , /* 12 */ 
+ EPClearTransferResp , /* 13 */ 
+ EPHandleDeleteReq , /* 14 */ 
+ EPHandleDeleteResp , /* 15 */ 
+ 
+ DevResetReq , /* 16 */ 
+ DevResetResp , /* 17 */ 
+ ModifyEP0Req , /* 18 */ 
+ ModifyEP0Resp , /* 19 */ 
+ SetUSBDevAddrReq , /* 20 */ 
+ SetUSBDevAddrResp , /* 21 */ 
+ UpdateDevReq , /* 22 */ 
+ UpdateDevResp , /* 23 */ 
+ USBDevDisconnectReq , /* 24 */ 
+ USBDevDisconnectResp , /* 25 */ 
+ 
+ USBSuspendReq , /* 26 */ 
+ USBSuspendResp , /* 27 */ 
+ USBResumeReq , /* 28 */ 
+ USBResumeResp , /* 29 */ 
+ RemoteWakeReq , /* 30 */ 
+ RemoteWakeResp , /* 31 */ 
+ PingReq , /* 32 */ 
+ PingResp , /* 33 */ 
+ DevDisconnectReq , /* 34 */ 
+ DevDisconnectResp , /* 35 */ 
+ DevInitDisconnectReq , /* 36 */ 
+ DevInitDisconnectResp , /* 37 */ 
+ SyncReq , /* 38 */ 
+ SyncResp , /* 39 */ 
+ CancelTransferReq , /* 40 */ 
+ CancelTransferResp , /* 41 */ 
+ EPOpenStreamReq , /* 42 */ 
+ EPOpenStreamResp , /* 43 */ 
+ EPCloseStreamReq , /* 44 */ 
+ EPCloseStreamResp , /* 45 */ 
+ USBDevResetReq , /* 46 */ 
+ USBDevResetResp , /* 47 */ 
+ 
+ DevNotificationReq , /* 48 */ 
+ DevNotificationResp , /* 49 */ 
+ EPSetKeepAliveReq , /* 50 */ 
+ EPSetKeepAliveResp , /* 51 */ 
+ GetPortBWReq , /* 52 */ 
+ GetPortBWResp , /* 53 */ 
+ SleepReq , /* 54 */ 
+ SleepResp , /* 55 */ 
+ WakeReq , /* 56 */ 
+ WakeResp , /* 57 */ 
+ 
+ /* Vendor-Specific Management Packets */ 
+ VendorSpecificReq = 0x3E | MAUSB_PKT_TYPE_MGMT, 
+ VendorSpecificResp , 
+ 
+ /* Control Packets */ 
+ TransferSetupReq = 0x00 | MAUSB_PKT_TYPE_CTRL, 
+ TransferSetupResp , 
+ TransferTearDownConf , 
+ 
+ /* Data Packets */ 
+ TransferReq = 0x00 | MAUSB_PKT_TYPE_DATA, 
+ TransferResp = 0x01 | MAUSB_PKT_TYPE_DATA, 
+ TransferAck , 
+ IsochTransferReq , 
+ IsochTransferResp 
+}; 
+ 
+/* Endpoint Handle Fields, per section 6.2.1.5 */ 
+struct __packed mausb_ep_handle { 
+ union { 
+ struct { 
+#ifdef __LITTLE_ENDIAN_BITFIELD 
+ __le16 dir:1; /**< Direction Field */ 
+ __le16 ep_num:4; /**< Endpoint Number */ 
+ __le16 dev_addr:7; /**< USB Device Address */ 
+ __le16 bus_num:4; /**< Bus Number */ 
+#else 
+ __le16 bus_num:4; /**< Bus Number */ 
+ __le16 dev_addr:7; /**< USB Device Address */ 
+ __le16 ep_num:4; /**< Endpoint Number */ 
+ __le16 dir:1; /**< Direction Field */ 
+#endif 
+ }; 
+ __u16 handle; 
+ }; 
+}; 
+ 
+#define MAUSB_VIRTUAL_BUS_NUM 15 
+ 
+/* The least significant bit of the packet is only set to 1 in */ 
+/* response packets. */ 
+#define MAUSB_PKT_RESP_FLAG 0x01 
+ 
+/** Status Code Values, per section 6.2.1.8, Table 6 */ 
+enum mausb_pkt_status { 
+ SUCCESS = 0, 
+ UNSUCCESSFUL = 128, 
+ INVALID_MA_USB_SESSION_STATE, 
+ INVALID_DEVICE_HANDLE, 
+ INVALID_EP_HANDLE, 
+ INVALID_EP_HANDLE_STATE, 
+ INVALID_REQUEST, 
+ MISSING_SEQUENCE_NUMBER, 
+ TRANSFER_PENDING, 
+ TRANSFER_EP_STALL, 
+ TRANSFER_SIZE_ERROR, 
+ TRANSFER_DATA_BUFFER_ERROR, 
+ TRANSFER_BABBLE_DETECTED, 
+ TRANSFER_TRANSACTION_ERROR, 
+ TRANSFER_SHORT_TRANSFER, 
+ TRANSFER_CANCELLED, 
+ INSUFFICENT_RESOURCES, 
+ NOT_SUFFICENT_BANDWIDTH, 
+ INTERNAL_ERROR, 
+ DATA_OVERRUN, 
+ DEVICE_NOT_ACCESSED, 
+ BUFFER_OVERRUN, 
+ BUSY, 
+ DROPPED_PACKET, 
+ ISOC_TIME_EXPIRED, 
+ ISOCH_TIME_INVALID, 
+ NO_USB_PING_RESPONSE, 
+ NOT_SUPPORTED, 
+ REQUEST_DENIED 
+}; 
+ 
+/* Status codes NO_ERROR and SUCCESS are interchangeable. */ 
+#define NO_ERROR SUCCESS 
+ 
+/* MA USB packet header size, per 6.2.1 */ 
+#define MAUSB_PKT_HEADER_SIZE 12 
+ 
+/** common header fields, per section 6.2.1 */ 
+struct __packed mausb_pkt_common { 
+ /* DWORD 0 */ 
+ __u8 ver_flags; /**< MA USB version & Flags */ 
+ enum mausb_pkt_type pkt_type:8; /**< type and subtype */ 
+ __le16 length; /**< length (in bytes) */ 
+ /* DWORD 1 */ 
+ union { 
+ struct mausb_ep_handle ep_handle; /**< Endpoint Handle */ 
+ __le16 dev_handle;/**< Device Handle */ 
+ }; 
+ __u8 ma_dev_addr;/**< MA USB Device Address */ 
+ __u8 mass_id; /**< MA USB Service Set (MSS) id*/ 
+ /* DWORD 2 */ 
+ enum mausb_pkt_status pkt_status:8; /**< packet status code */ 
+}; 
+ 
+/** MA USB Global Time, per section 6.6.1 */ 
+struct __packed mausb_time { 
+#ifdef __LITTLE_ENDIAN_BITFIELD 
+ /** value of delta field in ITP, defined in USB 3.1 spec. */ 
+ __le32 delta:13; 
+ /** nominal bus interval, Indicates USB microframe number */ 
+ __le32 nom_bus_itvl:19; 
+#else 
+ __le32 nom_bus_itvl:19; 
+ __le32 delta:13; 
+#endif 
+}; 
+ 
+#define MAUSB_PKT_WSE_NO_DOCK 0 
+#define MAUSB_PKT_WSE_DOCK_2_0 1 
+#define MAUSB_PKT_WSE_DOCK_3_0 2 
+ 
+/** 
+ * MAUSB Device Functionality Support Speed 
+ * 
+ * mausb_dev_bfs_speed are used for the bFunctionalitySupport field. 
+ * Note that they are different values than usb_device_speed. 
+ */ 
+enum mausb_dev_bfs_speed { 
+ MAUSB_LOW_SPEED = 0, 
+ MAUSB_FULL_SPEED, 
+ MAUSB_HIGH_SPEED, 
+ MAUSB_SUPER_SPEED, 
+ MAUSB_SUPER_SPEED_PLUS, 
+ MAUSB_INVALID_SPEED 
+}; 
+ 
+/* MA USB Capability Request fields, per 6.3.2, table 7 */ 
+struct __packed mausb_CapReq_flds { 
+#ifdef __LITTLE_ENDIAN_BITFIELD 
+ __le32 max_mgmt_reqs:12; /**< max # of outstanding mgmt reqs to host */ 
+ __le32 rsvd:20; /**< reserved */ 
+#else 
+ __le32 rsvd:20; /**< reserved */ 
+ __le32 max_mgmt_reqs:12; /**< max # of outstanding mgmt reqs to host */ 
+#endif 
+}; 
+ 
+#define MAUSB_DEV_TYPE_INTEGRATED 0 
+#define MAUSB_DEV_TYPE_HS_HUB 1 
+#define MAUSB_DEV_TYPE_SS_HUB 2 
+ 
+/** MA USB Capability Response fields, per 6.3.3, table 12 */ 
+struct __packed mausb_CapResp_flds { 
+ __le16 num_ep; /**< number of endpoints */ 
+ __u8 num_dev; /**< number of devices */ 
+#ifdef __LITTLE_ENDIAN_BITFIELD 
+ __u8 num_stream:5; /**< 2^this value = max streams supported */ 
+ __u8 dev_type:3; /**< 0 = not a hub, 1 = 2.0 hub, 2 = 3.1 hub */ 
+#else 
+ __u8 dev_type:3; /**< 0 = not a hub, 1 = 2.0 hub, 2 = 3.1 hub */ 
+ __u8 num_stream:5; /**< 2^this value = max streams supported */ 
+#endif 
+ 
+#ifdef __LITTLE_ENDIAN_BITFIELD 
+ __le32 desc_count:8; /**< descriptors count */ 
+ __le32 desc_length:24; /**< total length of descriptors */ 
+#else 
+ __le32 desc_length:24; /**< total length of descriptors */ 
+ __le32 desc_count:8; /**< descriptors count */ 
+#endif 
+ 
+ __le16 max_tx_reqs; /**< max # of outstanding transfer reqs */ 
+ 
+#ifdef __LITTLE_ENDIAN_BITFIELD 
+ __le16 max_mgmt_reqs:12;/**< max # of outstanding management reqs */ 
+ __le16 rsvd:4; /**< reserved */ 
+#else 
+ __le16 rsvd:4; /**< reserved */ 
+ __le16 max_mgmt_reqs:12;/**< max # of outstanding management reqs */ 
+#endif 
+}; 
+ 
+/** MA USB Device Capability Type Values, per 6.3.3, table 14 */ 
+enum mausb_dev_cap_type { 
+ MAUSB_DEV_CAP_SPEED = 0, 
+ MAUSB_DEV_CAP_POUT, 
+ MAUSB_DEV_CAP_ISO, 
+ MAUSB_DEV_CAP_SYNC, 
+ MAUSB_DEV_CAP_CONT_ID, 
+ MAUSB_DEV_CAP_LINK_SLEEP 
+}; 
+ 
+/** Speed Capability Speed Enumeration, per 6.3.3.1 */ 
+enum mausb_dev_cap_speed_speed { 
+ MAUSB_DEV_CAP_SPEED_LOW = 0, 
+ MAUSB_DEV_CAP_SPEED_FULL, 
+ MAUSB_DEV_CAP_SPEED_HIGH, 
+ MAUSB_DEV_CAP_SPEED_SUPER, 
+ MAUSB_DEV_CAP_SPEED_SS_PLUS 
+}; 
+ 
+/** Speed Capability Descriptor, per 6.3.3.1 */ 
+struct __packed mausb_dev_cap_speed { 
+ /* DWORD n+0 */ 
+ __u8 rsvd_0:4; /**< Reserved */ 
+ enum mausb_dev_cap_speed_speed speed:4; /**< USB Device Speed */ 
+ __u8 rsvd_1:4; /**< Reserved */ 
+ __u8 lse:2; /**< Lane Speed Exponent */ 
+ __u8 st:2; /**< Sublink Type */ 
+ 
+ /* DWORD n+1 */ 
+ __u8 rsvd_2:2; /**< Reserved */ 
+ __u8 lane_count:4; /**< Lane Count */ 
+ __u8 link_protocol:2; /**< Link Protocol */ 
+ __le16 lsm; /**< Lane Speed Mantissa */ 
+}; 
+ 
+#define MAUSB_DEV_CAP_SPEED_LENGTH 7 
+ 
+/** P-Managed OUT Capabilities Descriptor, per 6.3.3.2 */ 
+struct __packed mausb_dev_cap_pout { 
+ __u8 elastic_buf_cap:1; /**< Elastic Buffer Capability */ 
+ __u8 drop_notif:1; /**< Drop Notification */ 
+ __u8 rsvd:6; /**< Reserved */ 
+ 
+}; 
+ 
+#define MAUSB_DEV_CAP_POUT_LENGTH 3 
+ 
+/** Isochronous Capabilities Descriptor, per 6.3.3.3 */ 
+struct __packed mausb_dev_cap_iso { 
+ __u8 iso_alignment:1; /**< Isochronous Payload Alignment */ 
+ __u8 rsvd:7; /**< Reserved */ 
+}; 
+ 
+#define MAUSB_DEV_CAP_ISO_LENGTH 3 
+ 
+/** Synchronization Capabilities Descriptor, per 6.3.3.4 */ 
+struct __packed mausb_dev_cap_sync { 
+ __u8 media_time_avail:1; /**< Media Time Available */ 
+ __u8 timestamp_req:1; /**< Timestamp Request */ 
+ __u8 rsvd:6; /**< Reserved */ 
+}; 
+ 
+#define MAUSB_DEV_CAP_SYNCH_LENGTH 3 
+ 
+/** Container ID Capability Descriptor, per 6.3.3.5 */ 
+struct __packed mausb_dev_cap_cont_id { 
+ long long int cont_id_upper; /**< 64 msb of Container ID */ 
+ long long int cont_id_lower; /**< 64 lsb of Container ID */ 
+}; 
+ 
+#define MAUSB_DEV_CAP_CONT_ID_LENGTH 18 
+ 
+/** Link Sleeo Capability Descriptor, per 6.3.3.6 */ 
+struct __packed mausb_dev_cap_link_sleep { 
+ __u8 link_sleep_cap:1; /**< Link Sleep Capable */ 
+ __u8 rsvd:7; /**< Reserved */ 
+}; 
+ 
+#define MAUSB_DEV_CAP_LINK_SLEEP_LENGTH 3 
+ 
+/** MA Device Capability Descriptor */ 
+struct __packed mausb_dev_cap_desc { 
+ /* common descriptor fields */ 
+ __u8 length; /**< Descriptor length */ 
+ enum mausb_dev_cap_type cap_type:8; /**< Capability type */ 
+ 
+ /* Descriptor-specific format */ 
+ union { 
+ struct mausb_dev_cap_speed speed; 
+ struct mausb_dev_cap_pout pout; 
+ struct mausb_dev_cap_iso iso; 
+ struct mausb_dev_cap_sync sync; 
+ struct mausb_dev_cap_cont_id cont_id; 
+ struct mausb_dev_cap_link_sleep link_sleep; 
+ }; 
+}; 
+ 
+/** USB Device Handle Request fields, per 6.3.4, table 8 */ 
+struct __packed mausb_USBDevHandleReq_flds { 
+#ifdef __LITTLE_ENDIAN_BITFIELD 
+ __le32 usb_rt_str:20; /**< USB Route String, per USB3.0 Spec */ 
+ __le32 speed:4; /**< USB Device Speed */ 
+ __le32 rsvd_0:8; /**< reserved */ 
+ __le16 dock_hub; /**< dock hub device handle */ 
+ __le16 rsvd_1; /**< reserved */ 
+ __le16 parent_hub; /**< parent hub handle (if LS or HS) */ 
+ __u8 parent_hub_port:4; /**< parent hub port (if LS or HS) */ 
+ __u8 mtt:1; /**< multiple transaction translators */ 
+ __le16 rsvd_2:15; /**< reserved */ 
+ __u8 lse:2; /**< lane speed exponent */ 
+ __u8 st:2; /**< sublink type */ 
+ __u8 rsvd_3:2; /**< reserved */ 
+ __u8 lane_count:2; /**< lane count */ 
+ __u8 link_protocol:2; /**< link protocol */ 
+ __le16 lsm; /**< lane speed mantissa */ 
+ 
+#else 
+ __le16 lsm; /**< lane speed mantissa */ 
+ __u8 link_protocol:2; /**< link protocol */ 
+ __u8 lane_count:2; /**< lane count */ 
+ __u8 rsvd_3:2; /**< reserved */ 
+ __u8 st:2; /**< sublink type */ 
+ __u8 lse:2; /**< lane speed exponent */ 
+ __le16 rsvd_2:15; /**< reserved */ 
+ __u8 mtt:1; /**< multiple transaction translators */ 
+ __u8 parent_hub_port:4; /**< parent hub port (if LS or HS) */ 
+ __le16 parent_hub; /**< parent hub handle (if LS or HS) */ 
+ __le16 rsvd_1; /**< reserved */ 
+ __le16 dock_hub; /**< dock hub device handle */ 
+ __le32 rsvd_0:8; /**< reserved */ 
+ __le32 speed:4; /**< USB Device Speed */ 
+ __le32 usb_rt_str:20; /**< USB Route String, per USB3.0 Spec */ 
+#endif 
+}; 
+ 
+/* maximum number of EPs in a packet array */ 
+#define MAUSB_PKT_MAX_NUM_EP 31 
+ 
+/* EPHandleReq constants, per section 6.3.6 */ 
+#define MAUSB_EP_REQ_SIZE 8 
+#define MAUSB_EP_REQ_PADDING (MAUSB_EP_REQ_SIZE - USB_DT_ENDPOINT_SIZE) 
+#define MAUSB_SS_EP_REQ_SIZE 16 
+#define MAUSB_SS_EP_REQ_PADDING (MAUSB_SS_EP_REQ_SIZE - \ 
+ (USB_DT_ENDPOINT_SIZE + USB_DT_SS_EP_COMP_SIZE)) 
+ 
+/** packed USB endpoint descriptor */ 
+struct __packed mausb_ep_req { 
+ unsigned char ep_des[USB_DT_ENDPOINT_SIZE]; 
+ unsigned char padding[MAUSB_EP_REQ_PADDING]; 
+}; 
+ 
+/** packed SuperSpeed USB endpoint descriptor */ 
+struct __packed mausb_ss_ep_req { 
+ unsigned char ep_des[USB_DT_ENDPOINT_SIZE]; 
+ unsigned char ss_ep_comp_des[USB_DT_SS_EP_COMP_SIZE]; 
+ unsigned char padding[MAUSB_SS_EP_REQ_PADDING]; 
+}; 
+ 
+/** Endpoint Handle Request fields, per 6.3.6, Tables 10 & 11 */ 
+struct __packed mausb_EPHandleReq_flds { 
+#ifdef __LITTLE_ENDIAN_BITFIELD 
+ __le32 num_ep_des:5; /**< number of EP descriptors in the packet */ 
+ __le32 size_ep_des:6; /**< size of EP descriptors (in bytes) */ 
+ __le32 rsvd:21; /**< reserved */ 
+#else 
+ __le32 rsvd:21; 
+ __le32 size_ep_des:6; 
+ __le32 num_ep_des:5; 
+#endif 
+ /** array of endpoint descriptors (Standard or SuperSpeed) */ 
+ union { 
+ struct mausb_ep_req ep_des[MAUSB_PKT_MAX_NUM_EP] 
+ __aligned(4); 
+ struct mausb_ss_ep_req ss_ep_des[MAUSB_PKT_MAX_NUM_EP] 
+ __aligned(4); 
+ /* TODO: structure for USB 3.1 devices with ISO endpoints */ 
+ }; 
+}; 
+ 
+ 
+/** WEP Descriptor format, per 6.3.7, table 13 */ 
+struct __packed mausb_ep_des { 
+ struct mausb_ep_handle ep_handle; /**< requested endpoint handle */ 
+#ifdef __LITTLE_ENDIAN_BITFIELD 
+ __le16 dir:1; /**< direction */ 
+ __le16 iso:1; /**< isochronous */ 
+ __le16 l_man:1; /**< L-managed transfers */ 
+ __le16 valid:1; /**< valid handle bit */ 
+ __le16 rsvd_0:12; /**< reserved */ 
+#else 
+ __le16 rsvd_0:12; /**< reserved */ 
+ __le16 valid:1; /**< valid handle bit */ 
+ __le16 l_man:1; /**< L-managed transfers */ 
+ __le16 iso:1; /**< isochronous */ 
+ __le16 dir:1; /**< direction */ 
+#endif 
+ __le16 ccu; /**< credit consumption unit */ 
+ __le16 rsvd_1; /**< reserved */ 
+ __le32 buffer_size; /**< buffer size (in bytes) */ 
+ __le16 iso_prog_dly; /**< max iso programming delay (in uSec) */ 
+ __le16 iso_resp_dly; /**< max iso response delay (in uSec) */ 
+}; 
+ 
+/** Endpoint Handle Response fields, per 6.3.7, Tables 12 & 13 */ 
+struct __packed mausb_EPHandleResp_flds { 
+#ifdef __LITTLE_ENDIAN_BITFIELD 
+ __le32 num_ep_des:5; /**< number of EP descriptors in this packet */ 
+ __le32 rsvd:27; /**< reserved */ 
+#else 
+ __le32 rsvd:27; /**< reserved */ 
+ __le32 num_ep_des:5; /**< number of EP descriptors in this packet */ 
+#endif 
+ struct mausb_ep_des ep_des[MAUSB_PKT_MAX_NUM_EP]; 
+}; 
+ 
+/** Endpoint Handle Delete fields, per 6.3.16 & 6.3.17, Tables 37 & 38 */ 
+/* 
+ * Note: both the request and response packets are in the same format. 
+ * The the request contains all the handles to delete, and the 
+ * response indicates how many were deleted. 
+ */ 
+struct __packed mausb_EPHandleDelete_flds { 
+#ifdef __LITTLE_ENDIAN_BITFIELD 
+ __le32 num_ep:5; /**< number of EP descriptors */ 
+ __le32 rsvd:27; /**< reserved */ 
+#else 
+ __le32 rsvd:27; /**< reserved */ 
+ __le32 num_ep:5; /**< number of EP descriptors */ 
+#endif 
+ struct mausb_ep_handle ep_handle[MAUSB_PKT_MAX_NUM_EP]; 
+}; 
+ 
+/** Modify EP0 Request and Response fields, per 6.3.20-21, table 39 & 40 */ 
+struct __packed mausb_ModifyEP0_flds { 
+ /** Endpoint 0 handle for the device */ 
+ struct mausb_ep_handle ep_handle; 
+ union { 
+ __le16 max_pkt_size; /**< Maximum packet size for EP0 */ 
+ __le16 rsvd; /**< reserved */ 
+ }; 
+}; 
+ 
+/** Set USB Device Address Request fields, per 6.3.22, table 41 */ 
+struct __packed mausb_SetDevAddrReq_flds { 
+ __le16 resp_timeout; /**< time the device has to respond (in ms) */ 
+ __le16 rsvd; 
+}; 
+ 
+/** Set USB Device Address Response fields, per 6.3.23, table 42 */ 
+struct __packed mausb_SetDevAddrResp_flds { 
+#ifdef __LITTLE_ENDIAN_BITFIELD 
+ __le32 dev_addr:7; /**< USB Device Address from request */ 
+ __le32 rsvd:25; 
+#else 
+ __le32 rsvd:25; 
+ __le32 dev_addr:7; /**< USB Device Address from request */ 
+#endif 
+}; 
+ 
+/** Update Device Request fields, per 6.3.24, Table 28 */ 
+struct __packed mausb_UpdateDevReq_flds { 
+ __le16 max_exit_lat; /**< Max Exit Latency */ 
+#ifdef __LITTLE_ENDIAN_BITFIELD 
+ __u8 hub:1; /**< Hub flag, set to 1 if hub */ 
+ __u8 num_ports:4; /**< hub only, number of downward-facing ports */ 
+ __u8 mtt:1; /**< HS hub only, Multiple Transaction Translator */ 
+ __u8 ttt:2; /**< HS hub only, Transaction Think Time */ 
+ /**< 0 = at most 8 FS bit times */ 
+ /**< 1 = at most 16 FS bit times */ 
+ /**< 2 = at most 24 FS bit times */ 
+ /**< 3 = at most 32 FS bit times */ 
+#else 
+ __u8 ttt:2; 
+ __u8 mtt:1; 
+ __u8 num_ports:4; 
+ __u8 hub:1; 
+#endif 
+}; 
+ 
+/** MAUSB Synchronization Request fields, per 6.3.40, Table 30 */ 
+struct __packed mausb_SynchReq_flds { 
+#ifdef __LITTLE_ENDIAN_BITFIELD 
+ __le16 td_valid:1; /**< Transmission Delay field valid */ 
+ __le16 rsvd:15; /**< reserved */ 
+#else 
+ __le16 rsvd:15; /**< reserved */ 
+ __le16 td_valid:1; /**< Transmission Delay field valid */ 
+#endif 
+ struct mausb_time timestamp; /**< MA USB Timestamp, per 6.5.1.11 */ 
+ __le32 tx_dly; /**< Transmission delay, per 6.5.1.12 */ 
+}; 
+ 
+/** Cancel Transfer Request fields, per 6.3.42, Table 31 */ 
+struct __packed mausb_CancelTransferReq_flds { 
+ struct mausb_ep_handle ep_handle; /**< Target Endpoint Handle */ 
+ __le16 stream_id; /**< Target stream ID */ 
+#ifdef __LITTLE_ENDIAN_BITFIELD 
+ __le32 req_id:8; /**< Target request ID */ 
+ __le32 rsvd:24; /**< reserved */ 
+#else 
+ __u32 rsvd:24; /**< reserved */ 
+ __u32 req_id:8; /**< Target request ID */ 
+#endif 
+}; 
+ 
+/** Cancel Transfer Response fields, per 6.3.43, Table 32 */ 
+struct __packed mausb_CancelTransferResp_flds { 
+ struct mausb_ep_handle ep_handle; 
+ __u16 stream_id; 
+ /** Cancellation status */ 
+ /** 0 = Cancel Error */ 
+ /** 1 = Cancel Sucess before any data was moved */ 
+ /** 2 = Cancel Sucess after some data was moved */ 
+ /** 3 = Transfer not found */ 
+ 
+#ifdef __LITTLE_ENDIAN_BITFIELD 
+ __le32 req_id:8; 
+ __le32 cancel_status:2; 
+ __le32 rsvd_0:22; 
+#else 
+ __le32 rsvd_0:22; 
+ __le32 cancel_status:2; 
+ __le32 req_id:8; 
+#endif 
+ /** Delivered Sequence Number */ 
+ /** For OUT Transfers only. Only valid if cancel_status = 2 */ 
+ /** Indicates last sequence number delivered to the device. */ 
+#ifdef __LITTLE_ENDIAN_BITFIELD 
+ __le32 deliv_seq_num:24; 
+ __le32 rsvd_1:8; 
+#else 
+ __le32 deliv_seq_num:24; 
+ __le32 rsvd_1:8; 
+#endif 
+ /** Delivered Byte Offset. Only valid if cancel_status = 2 */ 
+ __le32 deliv_byte_offset; 
+}; 
+ 
+/** Enpoint Open Stream Request fields, per 6.3.44, Table 33 */ 
+struct __packed mausb_EPOpenStreamReq_flds { 
+ struct mausb_ep_handle ep_handle; /**< Target bulk endpoint */ 
+ __le32 num_streams:17; /**< number of streams to be opened */ 
+ __le32 rsvd:7; 
+}; 
+ 
+/** Enpoint Inactivate Request fields, per 6.3.10, Table 30 */ 
+struct __packed mausb_EPInactivateReq_flds { 
+ __u8 num_ep_handles:5; /** number of ep handles included packet */ 
+ __u8 suspend_flg:1; /** indicates if issued due to suspension of */ 
+ /** included endpoints */ 
+ /** 0 = endpoints not suspended */ 
+ /** 1 = endpoints suspended */ 
+ __u32 rsvd:26; 
+ 
+ /** list of EP handles MA USB host is requesting to inactivate */ 
+ struct mausb_ep_handle ep_handle[MAUSB_PKT_MAX_NUM_EP]; 
+}; 
+ 
+/** Enpoint Inactivate Response fields, per 6.3.11, Table 33 */ 
+struct __packed mausb_EPInactivateResp_flds { 
+ __u8 num_ep_with_error:5; /** number of EP handles with */ 
+ /** unsuccessful inactivation */ 
+ /** should only be non-zero if */ 
+ /** packet status is not SUCCESS */ 
+ __u32 rsvd:27; 
+ 
+ /** list of EP handles whose inactivation failed */ 
+ struct mausb_ep_handle ep_handle[MAUSB_PKT_MAX_NUM_EP]; 
+}; 
+ 
+#define MAUSB_MGMT_MAX_TOKEN ((1 << 10) - 1) 
+#define MAUSB_MGMT_TOKEN_PAD_LEN 3 /* token + pad to DWORD */ 
+ 
+/** Management Packet fields, per 6.3.1 */ 
+struct __packed mausb_mgmt_pkt { 
+ struct mausb_pkt_common common; 
+#ifdef __LITTLE_ENDIAN_BITFIELD 
+ __le16 token:10; 
+ __le16 padding:6; /* for DWORD alignment */ 
+#else 
+ __le16 padding:6; /* for DWORD alignment */ 
+ __le16 token:10; 
+#endif 
+ __u8 padding_2; 
+ union { 
+ struct mausb_CapReq_flds cap_req; 
+ struct mausb_CapResp_flds cap_resp; 
+ struct mausb_USBDevHandleReq_flds usb_dev_handle_req; 
+ __le16 usb_dev_handle_resp; 
+ struct mausb_EPHandleReq_flds ep_handle_req; 
+ struct mausb_EPHandleResp_flds ep_handle_resp; 
+ struct mausb_EPHandleDelete_flds ep_handle_delete; 
+ struct mausb_ModifyEP0_flds modify_ep0_req; 
+ struct mausb_ModifyEP0_flds modify_ep0_resp; 
+ struct mausb_SetDevAddrReq_flds set_dev_addr_req; 
+ struct mausb_SetDevAddrResp_flds set_dev_addr_resp; 
+ struct mausb_UpdateDevReq_flds update_dev_req; 
+ struct mausb_SynchReq_flds synch_req; 
+ __le16 ep_close_stream_req; 
+ struct mausb_CancelTransferReq_flds cancel_transfer_req; 
+ struct mausb_CancelTransferResp_flds cancel_transfer_resp; 
+ struct mausb_EPOpenStreamReq_flds ep_open_stream_req; 
+ struct mausb_EPInactivateReq_flds ep_inactivate_req; 
+ struct mausb_EPInactivateResp_flds ep_inactivate_resp; 
+ 
+ /* TODO: add remaining management packet data */ 
+ 
+ }; 
+}; 
+ 
+/** Transfer Setup Request fields, per 6.4.1, Table 38 */ 
+struct __packed mausb_TransferSetupReq_flds { 
+ /** Identifies link type */ 
+ /** 0 = Reserved */ 
+ /** 1 = IEEE 802.11 link */ 
+ /** 2-255 = Reserved */ 
+ __u8 link_type; 
+ /** Connection ID data is dependant on Link Type */ 
+ union { 
+ /** for 802.11 links (link_type == 1) */ 
+ struct __packed { 
+ __u8 tid:4; /**< Traffic Identifier */ 
+ __u8 rsvd:4; 
+ } connection_id; 
+ }; 
+}; 
+ 
+/** Control Packet fields, per 6.4 */ 
+struct __packed mausb_ctrl_pkt { 
+ struct mausb_pkt_common common; 
+ struct mausb_TransferSetupReq_flds transfer_setup_req; 
+ __u8 padding; /* for header DWORD alignment */ 
+}; 
+ 
+#define MAUSB_PKT_EPS_UNASSIGNED 0 
+#define MAUSB_PKT_EPS_ACTIVE 1 
+#define MAUSB_PKT_EPS_INACTIVE 2 
+#define MAUSB_PKT_EPS_HALTED 3 
+ 
+#define MAUSB_PKT_TFLAG_ARQ (1 << 2) 
+#define MAUSB_PKT_TFLAG_NEG (1 << 3) 
+#define MAUSB_PKT_TFLAG_EOT (1 << 4) 
+#define MAUSB_PKT_TFLAG_TYPE_CTRL (0 << 5) 
+#define MAUSB_PKT_TFLAG_TYPE_ISOC (1 << 5) 
+#define MAUSB_PKT_TFLAG_TYPE_BULK (2 << 5) 
+#define MAUSB_PKT_TFLAG_TYPE_INT (3 << 5) 
+#define MAUSB_PKT_TFLAG_TYPE_MASK 0x60 
+ 
+#define MAUSB_PKT_SEQ_NUM_MASK 0x00FFFFFF 
+ 
+/** Fields common to all datapackets, per 6.5 */ 
+struct __packed mausb_dph { 
+ struct mausb_pkt_common common; 
+ __u8 eps_tflags; /**< EPS & T-Flags */ 
+#ifdef __LITTLE_ENDIAN_BITFIELD 
+ __le16 num_seg:12; 
+ __le16 iflags:4; 
+#else 
+ __le16 iflags:4; 
+ __le16 num_seg:12; 
+#endif 
+#ifdef __LITTLE_ENDIAN_BITFIELD 
+ __le32 seq_num:24; /**< Sequence Number */ 
+ __le32 req_id:8; /**< request ID */ 
+#else 
+ __le32 req_id:8; /**< request ID */ 
+ __le32 seq_num:24; /**< Sequence Number */ 
+#endif 
+ union { 
+ __le32 remaining_size_credit; 
+ __le32 present_time; 
+ }; 
+}; 
+ 
+/** Fields exclusive to isochronous data packets, per 6.5 */ 
+struct __packed mausb_iso_dph { 
+ struct mausb_dph data; 
+ __le32 wse_ts; /**< WSE Timestamp */ 
+ __le32 tx_dly; /**< Transmission Delay */ 
+}; 
+ 
+ 
+/* unless the urb contains scattergather buffers, a packet will 
+ * need at most 3 entries: 
+ * - 1 for the header 
+ * - 1 for the setup data 
+ * - 1 for the data buffer 
+ * 
+ */ 
+#define MAUSB_MS_PKT_ORIG_NENTS 4 
+ 
+/** 
+ * mausb_pkt structure 
+ * 
+ * Can be used to parse any type of MAUSB packet, regardless of contents. 
+ * If the packet type is known, this structure shouldn't be used. Instead, 
+ * a type-specific structure (ie: mausb_XXXX_pkt) should be used. 
+ * 
+ * @setup: setup data (control packets only) 
+ * @buffer: data buffer 
+ * @buffer_length: length of data buffer 
+ * @pkt_list: connects packet to other packets in a linked list 
+ * @kvec_list: kvec list 
+ * @nents: number of kvecs 
+ * @pkt: A compilation of all the buffers needed to be sent 
+ * across the medium. Used to pass packet to medium. 
+ * @orig_pkt: Original ms_pkt for this packet. Used for destructor. 
+ * If this packet originated from the MA driver, it will 
+ * point to the ms_pkt of this ma_pkt. If it came in from 
+ * the MS driver, it will point at the ms_pkt it sent 
+ * us. This is used by the ms_pkt_destructor, so we can 
+ * make sure we are pointing to the right ms_pkt. 
+ */ 
+struct mausb_pkt { 
+ union { 
+ struct mausb_pkt_common *common; 
+ struct mausb_mgmt_pkt *mgmt; 
+ struct mausb_ctrl_pkt *ctrl; 
+ struct mausb_dph *data; 
+ struct mausb_iso_dph *iso_data; 
+ }; 
+ 
+ struct usb_ctrlrequest *setup; 
+ void *buffer; 
+ u32 buffer_length; 
+ struct list_head pkt_list; 
+ struct kvec *kvec_list; 
+ int nents; 
+ struct ms_pkt pkt; 
+ struct ms_pkt *orig_pkt; 
+ void (*ms_pkt_destructor)(struct ms_pkt *pkt); 
+}; 
+ 
+enum mausb_pkt_buf_copy_dir { 
+ MAUSB_PKT_BUF_COPY_TO_KVEC = 0, 
+ MAUSB_PKT_BUF_COPY_FROM_KVEC 
+}; 
+ 
+void mausb_pkt_buf_copy_kvec(struct mausb_pkt *pkt, int buf_length, int offset, 
+ struct kvec *kv, int nents, 
+ enum mausb_pkt_buf_copy_dir dir); 
+ 
+/* function declarations */ 
+const char *mausb_type_to_string(enum mausb_pkt_type type); 
+int mausb_pkt_fill_ms_pkt(struct mausb_pkt *pkt, gfp_t mem_flags); 
+int mausb_pkt_header_length(struct mausb_pkt_common *header); 
+enum mausb_pkt_status mausb_errno_to_ma_status(int errno); 
+int mausb_to_urb_status(enum mausb_pkt_status pkt_status); 
+struct usb_endpoint_descriptor *mausb_ep_handle_req_get_ep_des( 
+ struct mausb_EPHandleReq_flds *req, int i); 
+int mausb_pkt_length(struct mausb_pkt *pkt); 
+struct mausb_pkt *mausb_alloc_pkt(enum mausb_pkt_type pkt_type, int *status, 
+ gfp_t memflags); 
+int mausb_generate_ms_pkt(struct mausb_pkt *pkt); 
+bool mausb_pkt_has_setup_data(struct mausb_dph *header); 
+struct mausb_pkt *ms_pkt_to_mausb_pkt(struct ms_pkt *ms_pkt); 
+struct mausb_pkt *mausb_pkt_from_ms_pkt(struct ms_pkt *ms_pkt, 
+ void (*ms_pkt_destructor)(struct ms_pkt *ms_pkt), 
+ gfp_t mem_flags); 
+int mausb_pkt_dmux(struct ms_pkt *ms_pkt, void *context); 
+void mausb_free_pkt(struct mausb_pkt *pkt); 
+bool mausb_pkt_resp(struct mausb_pkt *pkt); 
+struct mausb_dev_cap_desc *cap_desc_ptr_increment(struct mausb_mgmt_pkt *resp, 
+ int offset); 
+ 
+/* Helper functions for sequence number and request id wraparound */ 
+u32 mausb_seq_num_add(u32 seq_num, int val); 
+void mausb_increment_seq_num(u32 *seq_num); 
+bool mausb_seq_num_lt(u32 a, u32 b); 
+bool mausb_seq_num_lt_eq(u32 a, u32 b); 
+bool mausb_seq_num_gt_eq(u32 a, u32 b); 
+bool mausb_seq_num_gt(u32 a, u32 b); 
+u8 mausb_req_id_add(u8 req_id, int val); 
+bool mausb_req_id_lt(u8 a, u8 b); 
+bool mausb_req_id_gt(u8 a, u8 b); 
+bool mausb_req_id_gt_eq(u8 a, u8 b); 
+ 
+#endif 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/drivers/mausb_state.h linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/drivers/mausb_state.h
--- linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/drivers/mausb_state.h	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/drivers/mausb_state.h	2014-11-28 12:39:00.572447000 +0800
@@ -0,0 +1,184 @@
+/* Name: mausb_state.h 
+ * Description: Contains all of the state variables for hosts and devices as 
+ * defined by the MAUSB spec. 
+ * 
+ * This file is provided under a dual BSD/GPLv2 license. When using or 
+ * redistributing this file, you may do so under either license. 
+ * 
+ * GPL LICENSE SUMMARY 
+ * 
+ * Copyright(c) 2014 Intel Corporation. 
+ * 
+ * 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. 
+ * 
+ * Contact Information: 
+ * Sean Stalley, sean.stalley [at] intel 
+ * Stephanie Wallick, stephanie.s.wallick [at] intel 
+ * 2111 NE 25th Avenue 
+ * Hillsboro, Oregon 97124 
+ * 
+ * BSD LICENSE 
+ * 
+ * Copyright(c) 2014 Intel Corporation. 
+ * 
+ * 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 of Intel Corporation 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. 
+ */ 
+ 
+#ifndef __MAUSB_STATE_H 
+#define __MAUSB_STATE_H 
+ 
+/** 
+ * MAUSB endpoint state variables, per MA USB Spec sections 5.4.1 & 5.5.2. 
+ * 
+ * Note: this struct contains the fields necessary to store the state on both 
+ * the host and device side. 
+ * 
+ * @seq_number: For a sender, this field contains the sequence number 
+ * that should be placed in the next outgoing packet. 
+ * For a receiver, this field contains the sequence number 
+ * expected in the next incoming packet. 
+ * @keep_alive_timer: Timeout counter. Set to aMausbTransferKeepAlive 
+ * upon a new transfer initialization. To be decremented 
+ * every aMAUSBTransferTimeTick interval. If the timer 
+ * reaches 0, A retry is triggered. 
+ * @retry_counter: Indicates how many more times the 
+ * transfer will be attempted. Decremented upon a timeout 
+ * (see keep_alive_timer for details). If this counter 
+ * reaches 0, the transfer fails due to a timeout. 
+ * @request_id: Request ID number. for IN transfers, all 
+ * transfer_request packets currently being sent or 
+ * received should have this request ID number. for OUT 
+ * transfers, All transfer_request and transfer_ack 
+ * packets currently being sent or received should have 
+ * this request ID number. 
+ * @active_request_id: Active Request ID number. used by IN transfers only. 
+ * All transfer_ack packets being sent/received should 
+ * contain this number. 
+ * @earliest_unacked: Stores the sequence number of the most recent packet 
+ * that has been sent out but has not been acknowledged 
+ * by the receiver. 
+ * @rx_buf_size: Receiver Buffer Size. Used for OUT transfers only. 
+ * Indicates the available buffer space for packets in the 
+ * device (in bytes). 
+ * Note: this value is signed for the host and 
+ * unsigned for the receiver. A negative number 
+ * indicates a buffer overflow. 
+ * Note: defined in spec as a 25-bit signed int 
+ * for a host and a 32-bit unsigned for a device. 
+ * @occupancy: Size (in bytes) of the payload accepted into the receive 
+ * buffer. Used only on the device side for OUT transfers. 
+ * @earliest_request_id:Request ID of earliest transferReq whose state 
+ * needs to be tracked (host IN). 
+ * @transfer_retries: Reload value for retry_counter. Should be set to 
+ * a ControlTransferRetries, aBulkTransferRetries, 
+ * or aInterruptTransferRetries depending on transfer 
+ * type. 
+ * @delayed: Set to true if the interval between two sucessive 
+ * transferResp packets exceeds aTransferRepeatTime. 
+ * @tx_pending: Set to 1 when a transfer is in progress, otherwise it 
+ * should be zero. A new transfer cannot be started until 
+ * this flag is cleared. 
+ */ 
+struct mausb_ep_state { /* HOST | DEVICE */ 
+ 
+ unsigned int seq_number:24; /* IN | OUT | IN | OUT */ 
+ int keep_alive_timer; /* IN | OUT | IN | OUT */ 
+ unsigned int retry_counter; /* IN | OUT | IN | OUT */ 
+ __u8 request_id; /* IN | OUT | IN | OUT */ 
+ __u8 active_request_id; /* IN | OUT | IN | */ 
+ unsigned int earliest_unacked:24; /* | OUT | IN | OUT */ 
+ __u32 rx_buf_size; /* | OUT | | OUT */ 
+ unsigned int occupancy; /* | | | OUT */ 
+ u8 earliest_request_id; /* IN | OUT | IN | OUT */ 
+ unsigned int transfer_retries; /* IN | OUT | IN | OUT */ 
+ bool delayed; /* | | IN | */ 
+ 
+ /* TODO: add response_timer (device IN and OUT/host OUT) */ 
+ 
+ unsigned int tx_pending:1; /* beyond spec */ 
+}; 
+ 
+/** 
+ * MA USB transfer state variables, per section 5.4.1 & 5.5.2. 
+ * 
+ * In our implementation, URBs and MAUSB transfers map one-to-one, 
+ * so the transfer state and the urb state are one in the same. 
+ * 
+ * @rem_size: The remaining transfer size (in bytes). This value is 
+ * set at the beginning of a transfer and is decremented 
+ * as data is received. 
+ * @payload_size: Payload size for out transfer (in bytes). For MA USB 
+ * host, it indicates the overall transfered OUT payload 
+ * size for the current urb. For MA USB device, It 
+ * indicates the received OUT payload size for the 
+ * current MA USB OUT request. 
+ * @transfer_error: A boolean which is only set to TRUE when a 
+ * non-recoverable error is detected in the transfer. 
+ * @transfer_complete: A boolean which is only set to TRUE when a transfer 
+ * is evaluated to be complete. (ie. the final ACK has 
+ * has been sent/received). 
+ * @eot_detected: A boolean which is only set to TRUE when a transfer 
+ * is complete (ie: all the data has been transferred). 
+ * Note: eot_detected & transfer_complete differ in when 
+ * they are set. eot_detected is sent after the last data 
+ * packet received, transfer_complete is set after the 
+ * final ACK. 
+ * @last_transfer_sn: Last Transfer Sequence Number. Stores the sequence 
+ * number of the final packet of this transfer. 
+ * @transfer_acked: Set to true when a transferReq or transferAck packet is 
+ * released to the data channel acknowledging the last 
+ * transferResp belonging to a transfer. 
+ * @k: A transfer-dependent multiplicative factor used to 
+ * reload keep_alive_timer when a transfer has a status 
+ * of TRANSFER_PENDING. 
+ * @ack_transfer_sn: The value of the sequence number in the last 
+ * transferReq packet that belongs to the transfer and 
+ * has the ARQ field set to 1. 
+ */ 
+struct mausb_transfer_state { /* HOST | DEVICE */ 
+ 
+ __u32 rem_size; /* IN | OUT | IN | OUT */ 
+ __u32 payload_size; /* IN | OUT | IN | OUT */ 
+ bool transfer_error; /* IN | OUT | IN | OUT */ 
+ bool transfer_complete; /* IN | OUT | IN | OUT */ 
+ bool eot_detected; /* IN | | IN | OUT */ 
+ unsigned int last_transfer_sn:24; /* IN | | IN | */ 
+ bool transfer_acked; /* IN | OUT | | */ 
+ unsigned int k; /* IN | | | */ 
+ unsigned int ack_transfer_sn:24; /* | OUT | | */ 
+ 
+ /*TODO: add transfer_completion_timer (host IN) */ 
+}; 
+ 
+#endif 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/drivers/mausb_tcp.c linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/drivers/mausb_tcp.c
--- linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/drivers/mausb_tcp.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/drivers/mausb_tcp.c	2014-11-28 12:39:00.572447000 +0800
@@ -0,0 +1,458 @@
+/* Name: mausb_tcp.c 
+ * Description: This is a driver used to connect an MA USB driver to a tcp 
+ * socket. 
+ * 
+ * This file is provided under a dual BSD/GPLv2 license. When using or 
+ * redistributing this file, you may do so under either license. 
+ * 
+ * GPL LICENSE SUMMARY 
+ * 
+ * Copyright(c) 2014 Intel Corporation. 
+ * 
+ * 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. 
+ * 
+ * Contact Information: 
+ * Sean Stalley, sean.stalley [at] intel 
+ * Stephanie Wallick, stephanie.s.wallick [at] intel 
+ * 2111 NE 25th Avenue 
+ * Hillsboro, Oregon 97124 
+ * 
+ * BSD LICENSE 
+ * 
+ * Copyright(c) 2014 Intel Corporation. 
+ * 
+ * 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 of Intel Corporation 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/module.h> 
+#include <linux/uio.h> 
+#include <linux/delay.h> 
+ 
+#include "mausb_ioctl.h" 
+#include "mausb_tcp.h" 
+ 
+struct mausb_tcp_medium *tcp_medium[MAUSB_TCP_NUM_MODS]; 
+ 
+static int gadget_connect_thread(void *data_p) 
+{ 
+ struct mausb_connect_data *data = data_p; 
+ int ret; 
+ 
+ pr_debug("%s: Running thread #%i\n", __func__, data->i); 
+ 
+ ret = tcp_medium[data->i]->connect(data->on); 
+ 
+ pr_debug("%s: Thread #%i complete, returing with value %i\n", 
+ __func__, data->i, ret); 
+ 
+ kfree(data); 
+ 
+ return ret; 
+} 
+ 
+/* for IOCTL */ 
+int gadget_connection(int on) 
+{ 
+ int i; 
+ 
+ struct mausb_connect_data *data; 
+ 
+ /* make all the calls */ 
+ for (i = 0; i < MAUSB_TCP_NUM_MODS; ++i) { 
+ 
+ if (NULL != tcp_medium[i] && 
+ NULL != tcp_medium[i]->ma_driver) { 
+ 
+ data = kzalloc(sizeof(*data), GFP_KERNEL); 
+ if (NULL == data) 
+ return -ENOMEM; 
+ 
+ data->task = NULL; 
+ data->on = on; 
+ data->i = i; 
+ 
+ pr_debug("%s: spawning thread #%i\n", __func__, i); 
+ 
+ data->task = kthread_run(gadget_connect_thread, 
+ data, "mausb_connect_thread_%i", i); 
+ } 
+ } 
+ 
+ return 0; 
+} 
+ 
+/* for IOCTL */ 
+int set_medium_delay(int delay) 
+{ 
+ pr_err("%s: ERROR: cannot set latency of real medium\n", __func__); 
+ return -EINVAL; 
+} 
+ 
+int set_port_no(int port) 
+{ 
+ int ret = -EINVAL; 
+ int i; 
+ 
+ for (i = 0; i < MAUSB_TCP_NUM_MODS; ++i) { 
+ if (NULL != tcp_medium[i]) { 
+ tcp_medium[i]->addr_in.sin_port = htons(port); 
+ ret = port; 
+ } 
+ } 
+ 
+ return ret; 
+} 
+ 
+int set_ip_addr(unsigned long in_addr) 
+{ 
+ int ret = -EINVAL; 
+ int i; 
+ struct in_addr addr; 
+ 
+ addr.s_addr = htonl(in_addr); 
+ 
+ for (i = 0; i < MAUSB_TCP_NUM_MODS; ++i) { 
+ if (NULL != tcp_medium[i]) { 
+ tcp_medium[i]->addr_in.sin_addr = addr; 
+ ret = 0; 
+ } 
+ } 
+ 
+ return ret; 
+} 
+ 
+int set_mac_addr(unsigned char mac_addr[ETH_ALEN]) 
+{ 
+ pr_err("%s: ERROR: cannot set mac address for TCP\n", __func__); 
+ return -EINVAL; 
+} 
+ 
+inline void *mausb_tcp_to_context(struct mausb_tcp_medium *medium) 
+{ 
+ return (void *) medium; 
+} 
+EXPORT_SYMBOL(mausb_tcp_to_context); 
+ 
+inline struct mausb_tcp_medium *mausb_context_to_tcp(void *context) 
+{ 
+ return (struct mausb_tcp_medium *) context; 
+} 
+EXPORT_SYMBOL(mausb_context_to_tcp); 
+ 
+static void mausb_tcp_init_msg(struct msghdr *msg) 
+{ 
+ msg->msg_name = NULL; 
+ msg->msg_namelen = 0; 
+ msg->msg_control = NULL; 
+ msg->msg_controllen = 0; 
+ msg->msg_flags = 0; 
+} 
+ 
+static int mausb_tcp_enqueue(struct ms_pkt *pkt, void *context) 
+{ 
+ struct msghdr msg; 
+ struct mausb_tcp_medium *tcp_medium; 
+ int total_length = 0; 
+ int ret = 0; 
+ int i; 
+ 
+ mausb_tcp_init_msg(&msg); 
+ 
+ if (NULL == context) { 
+ pr_err("%s: ERROR: null context\n", __func__); 
+ return -EINVAL; 
+ } 
+ tcp_medium = mausb_context_to_tcp(context); 
+ 
+ if (NULL == tcp_medium->socket) { 
+ pr_err("%s: ERROR: no socket for packet\n", __func__); 
+ return -ENOTCONN; 
+ } 
+ 
+ for (i = 0; i < pkt->nents; ++i) { 
+ total_length += pkt->kvec[i].iov_len; 
+ } 
+ 
+ ret = kernel_sendmsg(tcp_medium->socket, &msg, pkt->kvec, pkt->nents, 
+ total_length); 
+ 
+ pr_debug("%s: sent %i bytes\n", __func__, ret); 
+ 
+ /* 
+ * TODO: implement completion (pkt_sent) callback 
+ * if (NULL != tcp_medium->tx_pair.pkt_sent && 0 < ret) 
+ * tcp_pair->tx_pair.pkt_sent(pkt); 
+ */ 
+ 
+ return ret; 
+} 
+ 
+static int mausb_tcp_receive_packet(struct mausb_tcp_medium *tcp_medium, 
+ struct msghdr *msg, struct ms_pkt *pkt) 
+{ 
+ struct kvec kvec; 
+ int data_rcvd; 
+ int total_rcvd = 0; 
+ __u16 length; 
+ void *buf; 
+ 
+ buf = kmalloc(MAUSB_TCP_BUF_SIZE, GFP_KERNEL); 
+ if (NULL == buf) 
+ return -ENOMEM; 
+ 
+ kvec.iov_base = buf; 
+ kvec.iov_len = MAUSB_TCP_BUF_SIZE; 
+ 
+ /* receive the first DWORD to determine length */ 
+ data_rcvd = kernel_recvmsg(tcp_medium->socket, msg, &kvec, 1, 
+ sizeof(__u32), MSG_DONTWAIT); 
+ 
+ while (data_rcvd == -EAGAIN && !kthread_should_stop()) { 
+ /* sleep to prevent excessive polling */ 
+ msleep(10); 
+ 
+ /* receive the first DWORD to determine length */ 
+ data_rcvd = kernel_recvmsg(tcp_medium->socket, msg, &kvec, 
+ 1, sizeof(__u32), MSG_DONTWAIT); 
+ } 
+ 
+ if (0 > data_rcvd) { 
+ pr_err("%s: ERROR: Could not read packet length" 
+ " (error #%i)\n", __func__, data_rcvd); 
+ kfree(buf); 
+ return data_rcvd; 
+ } 
+ 
+ /* the data is invalid */ 
+ if (sizeof(__u32) > data_rcvd) { 
+ pr_err("%s: ERROR: did not read enough data to get length" 
+ " (received %i bytes)\n", __func__, data_rcvd); 
+ kfree(buf); 
+ return -EINVAL; 
+ } 
+ 
+ length = le16_to_cpu(*((__le16 *)(buf + MAUSB_PKT_LENGTH_OFFSET))); 
+ total_rcvd += data_rcvd; 
+ 
+ /* make sure length is valid */ 
+ if (length < sizeof(__u32)) { 
+ pr_err("%s: ERROR: length field too small (%u)\n", 
+ __func__, length); 
+ kfree(buf); 
+ return -EINVAL; 
+ } 
+ 
+ /* receive the remainder of the packet */ 
+ while (total_rcvd < length && total_rcvd >= 0 && 
+ !kthread_should_stop()) { 
+ 
+ data_rcvd = kernel_recvmsg(tcp_medium->socket, msg, &kvec, 
+ 1, length - total_rcvd, 0); 
+ 
+ if (0 < data_rcvd) { 
+ total_rcvd += data_rcvd; 
+ 
+ } else if (0 > data_rcvd) { 
+ pr_err("%s: ERROR: while receiving packet " 
+ "(err #%i)\n", __func__, data_rcvd); 
+ kfree(buf); 
+ return data_rcvd; 
+ } 
+ } 
+ 
+ if (total_rcvd != length) { 
+ pr_warn("%s: Warning: did not receive enough data " 
+ "(length:%u, received:%i)\n", __func__, 
+ length, total_rcvd); 
+ } 
+ 
+ 
+ pkt->nents = 1; 
+ pkt->kvec[0].iov_base = buf; 
+ pkt->kvec[0].iov_len = total_rcvd; 
+ 
+ return total_rcvd; 
+} 
+ 
+int mausb_tcp_receive_loop(struct mausb_tcp_medium *tcp_medium) 
+{ 
+ struct msghdr msg; 
+ struct ms_pkt *pkt; 
+ int data_rcvd = 0; 
+ 
+ mausb_tcp_init_msg(&msg); 
+ 
+ while (!kthread_should_stop()) { 
+ 
+ pkt = kzalloc(sizeof(struct ms_pkt), GFP_KERNEL); 
+ 
+ pr_debug("%s: preparing to receive data\n", __func__); 
+ 
+ data_rcvd = mausb_tcp_receive_packet(tcp_medium, &msg, pkt); 
+ 
+ if (0 >= data_rcvd) { 
+ pr_err("%s: received no data (err %i)\n", __func__, 
+ data_rcvd); 
+ 
+ sock_release(tcp_medium->socket); 
+ return data_rcvd; 
+ 
+ } else { 
+ pr_debug("%s: received %i bytes\n", __func__, 
+ data_rcvd); 
+ } 
+ 
+ if (data_rcvd > 0) { 
+ mausb_transfer_packet(pkt, 
+ &tcp_medium->ma_driver->pkt_dmux); 
+ } 
+ 
+ data_rcvd = 0; 
+ } 
+ 
+ sock_release(tcp_medium->socket); 
+ 
+ return 0; 
+} 
+EXPORT_SYMBOL(mausb_tcp_receive_loop); 
+ 
+int mausb_tcp_add_tx_pair(struct mausb_transfer_pair *ma_pair, 
+ struct mausb_tcp_medium *medium) 
+{ 
+ ma_pair->to_ms.transfer_packet = &mausb_tcp_enqueue; 
+ ma_pair->to_ms.context = mausb_tcp_to_context(medium); 
+ 
+ return 0; 
+} 
+EXPORT_SYMBOL(mausb_tcp_add_tx_pair); 
+ 
+int mausb_tcp_drop_tx_pair(unsigned long handle, void *context) 
+{ 
+ /* TODO: something here */ 
+ 
+ return 0; 
+} 
+EXPORT_SYMBOL(mausb_tcp_drop_tx_pair); 
+
+/** 
+ * Frees the given ms_pkt and associated buffers. This function is not 
+ * necessary to use the API, but could be useful on both sides of the interface. 
+ */ 
+void mausb_free_ms_pkt(struct ms_pkt *pkt) 
+{ 
+ int i; 
+ void *current_buf; 
+ 
+ for (i = 0; i < pkt->nents; ++i) { 
+ current_buf = pkt->kvec[i].iov_base; 
+ if (NULL != current_buf) { 
+ kfree(current_buf); 
+ } else { 
+ pr_debug("%s: cannot find buffer for kvec #%i in" 
+ " ms_pkt at %p\n", __func__, i, pkt->kvec); 
+ } 
+ } 
+ 
+ kfree(pkt); 
+} 
+EXPORT_SYMBOL(mausb_free_ms_pkt); 
+ 
+/** 
+ * initialization function 
+ */ 
+struct mausb_tcp_medium *alloc_init_mausb_tcp_medium( 
+ enum mausb_tcp_module_type type) 
+{ 
+ struct mausb_tcp_medium *medium; 
+ int ret; 
+ 
+ medium = kzalloc(sizeof(struct mausb_tcp_medium), GFP_KERNEL); 
+ if (NULL == medium) 
+ return NULL; 
+ 
+ ret = sock_create(PF_INET, SOCK_STREAM, IPPROTO_TCP, 
+ &medium->setup_socket); 
+ 
+ medium->addr_in.sin_family = AF_INET; 
+ medium->addr_in.sin_port = htons(MAUSB_TCP_PORT_HOST); 
+ 
+ spin_lock_init(&medium->lock); 
+ 
+ tcp_medium[type] = medium; 
+ 
+ return medium; 
+} 
+EXPORT_SYMBOL(alloc_init_mausb_tcp_medium); 
+ 
+/** 
+ * exit function 
+ */ 
+void free_mausb_tcp_medium(struct mausb_tcp_medium *medium, 
+ enum mausb_tcp_module_type type) 
+{ 
+ if (medium->recv_task) 
+ kthread_stop(medium->recv_task); 
+ 
+ if (medium->setup_socket) 
+ sock_release(medium->setup_socket); 
+ 
+ tcp_medium[type] = NULL; 
+ 
+ kfree(medium); 
+} 
+EXPORT_SYMBOL(free_mausb_tcp_medium); 
+ 
+int mausb_tcp_core_init(void) 
+{ 
+ int ret; 
+ 
+ ret = reg_chrdev(); 
+ if (0 > ret) { 
+ pr_err("%s: reg_chrdev() failed\n", __func__); 
+ } 
+ 
+ return ret; 
+ 
+} 
+module_init(mausb_tcp_core_init); 
+ 
+void mausb_tcp_core_exit(void) 
+{ 
+ unreg_chrdev(); 
+} 
+module_exit(mausb_tcp_core_exit); 
+ 
+MODULE_LICENSE("Dual BSD/GPL"); 
+MODULE_AUTHOR("Intel"); 
+MODULE_DESCRIPTION("mausb_tcp_core"); 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/drivers/mausb_tcp-device.c linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/drivers/mausb_tcp-device.c
--- linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/drivers/mausb_tcp-device.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/drivers/mausb_tcp-device.c	2014-11-28 12:39:00.572447000 +0800
@@ -0,0 +1,147 @@
+/* Name: mausb_tcp-device.c 
+ * Description: The device side media specific driver to allow media agnostic 
+ * packets over tcp/ip. 
+ * 
+ * This file is provided under a dual BSD/GPLv2 license. When using or 
+ * redistributing this file, you may do so under either license. 
+ * 
+ * GPL LICENSE SUMMARY 
+ * 
+ * Copyright(c) 2014 Intel Corporation. 
+ * 
+ * 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. 
+ * 
+ * Contact Information: 
+ * Sean Stalley, sean.stalley [at] intel 
+ * Stephanie Wallick, stephanie.s.wallick [at] intel 
+ * 2111 NE 25th Avenue 
+ * Hillsboro, Oregon 97124 
+ * 
+ * BSD LICENSE 
+ * 
+ * Copyright(c) 2014 Intel Corporation. 
+ * 
+ * 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 of Intel Corporation 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/module.h> 
+#include <linux/init.h> 
+ 
+#include "mausb_tcp.h" 
+#include "mausb_ioctl.h" 
+ 
+struct mausb_tcp_medium *dev_tcp_medium; 
+ 
+int mausb_tcp_device_thread(void *data) 
+{ 
+ return mausb_tcp_receive_loop(dev_tcp_medium); 
+} 
+ 
+int mausb_tcp_device_add_tx_pair(struct mausb_transfer_pair *ma_pair) 
+{ 
+ return mausb_tcp_add_tx_pair(ma_pair, dev_tcp_medium); 
+} 
+ 
+static struct mausb_ms_ops ms_ops = { 
+ .add_transfer_pair = &mausb_tcp_device_add_tx_pair, 
+ .drop_transfer_pair = &mausb_tcp_drop_tx_pair, 
+ .pkt_destructor = &mausb_free_ms_pkt 
+}; 
+ 
+static struct mausb_ms_drv ms_driver = { 
+ .ops = &ms_ops 
+}; 
+ 
+static int mausb_tcp_device_connect(int on) 
+{ 
+ int ret; 
+ 
+ if (on && dev_tcp_medium->socket == NULL) { 
+ ret = sock_create(PF_INET, SOCK_STREAM, IPPROTO_TCP, 
+ &dev_tcp_medium->socket); 
+ 
+ if (0 > ret) /* TODO: real errorchecking */ 
+ return ret; 
+ 
+ do { 
+ ret = kernel_connect(dev_tcp_medium->socket, 
+ &dev_tcp_medium->addr, 
+ sizeof(dev_tcp_medium->addr_in), O_RDWR); 
+ pr_debug("%s:kernel_connect returned %i\n", 
+ __func__, ret); 
+ 
+ if (0 > ret) { 
+ /* poll until we can connect sucessfully */ 
+ msleep(MAUSB_TCP_DEV_CONNECT_POLL_MS); 
+ } 
+ 
+ 
+ } while (0 > ret); 
+ 
+ /*spawn off a listening thread */ 
+ dev_tcp_medium->recv_task = kthread_run(mausb_tcp_device_thread, 
+ NULL, "mausb_tcp_device_thread"); 
+ } 
+ 
+ ret = dev_tcp_medium->ma_driver->device_connect(on); 
+ 
+ return ret; 
+} 
+ 
+int mausb_tcp_device_init(void) 
+{ 
+ dev_tcp_medium = alloc_init_mausb_tcp_medium(MAUSB_TCP_DEV); 
+ if (NULL == dev_tcp_medium) 
+ return -ENOMEM; 
+ 
+ dev_tcp_medium->addr_in.sin_addr.s_addr = htonl(INADDR_LOOPBACK); 
+ 
+ dev_tcp_medium->connect = &mausb_tcp_device_connect; 
+ 
+ dev_tcp_medium->ma_driver = maudc_register_ms_driver(&ms_driver); 
+ 
+ 
+ return 0; 
+} 
+module_init(mausb_tcp_device_init); 
+ 
+void mausb_tcp_device_exit(void) 
+{ 
+ free_mausb_tcp_medium(dev_tcp_medium, MAUSB_TCP_DEV); 
+} 
+module_exit(mausb_tcp_device_exit); 
+ 
+MODULE_LICENSE("Dual BSD/GPL"); 
+MODULE_AUTHOR("Intel"); 
+MODULE_DESCRIPTION("mausb_tcp_device"); 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/drivers/mausb_tcp.h linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/drivers/mausb_tcp.h
--- linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/drivers/mausb_tcp.h	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/drivers/mausb_tcp.h	2014-11-28 12:39:00.572447000 +0800
@@ -0,0 +1,130 @@
+/* Name: mausb_tcp.h 
+ * Description: header file for mausb_tcp.c 
+ * 
+ * This file is provided under a dual BSD/GPLv2 license. When using or 
+ * redistributing this file, you may do so under either license. 
+ * 
+ * GPL LICENSE SUMMARY 
+ * 
+ * Copyright(c) 2014 Intel Corporation. 
+ * 
+ * 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. 
+ * 
+ * Contact Information: 
+ * Sean Stalley, sean.stalley [at] intel 
+ * Stephanie Wallick, stephanie.s.wallick [at] intel 
+ * 2111 NE 25th Avenue 
+ * Hillsboro, Oregon 97124 
+ * 
+ * BSD LICENSE 
+ * 
+ * Copyright(c) 2014 Intel Corporation. 
+ * 
+ * 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 of Intel Corporation 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. 
+ */ 
+ 
+#ifndef __MAUSB_TCP_H 
+#define __MAUSB_TCP_H 
+ 
+#include <linux/net.h> 
+#include <linux/kthread.h> 
+#include <linux/tcp.h> 
+#include <linux/in.h> 
+ 
+#include "mausb_msapi.h" 
+ 
+#define MAUSB_TCP_PORT_HOST 9001 
+ 
+/* used to determine how many times we have to listen */ 
+#define MAUSB_TCP_MAX_NUM_CHANNELS 1 
+ 
+/* how often the device should poll while connecting */ 
+#define MAUSB_TCP_DEV_CONNECT_POLL_MS 100 
+ 
+/* how often to poll the port to check for a new message */ 
+#define MAUSB_TCP_POLL_PORT_MS 5 
+ 
+#define MAUSB_TCP_BUF_SIZE PAGE_SIZE 
+ 
+#define MAUSB_MAX_NAME_LEN 50 
+ 
+#define MAUSB_TCP_RECV_POLL 1 /* in ms */ 
+ 
+#define MAUSB_DWORD_LENGTH 4 /* DWORD = 4 bytes */ 
+ 
+enum mausb_tcp_module_type { 
+ MAUSB_TCP_DEV = 0, 
+ MAUSB_TCP_HOST, 
+ MAUSB_TCP_NUM_MODS 
+}; 
+ 
+struct mausb_tcp_medium { 
+ struct socket *setup_socket; 
+ union { 
+ struct sockaddr_in addr_in; 
+ struct sockaddr addr; 
+ }; 
+ spinlock_t lock; 
+ struct mausb_ma_drv *ma_driver; 
+ 
+ struct socket *socket; 
+ struct task_struct *recv_task; 
+ 
+ /* function call for when a device connect/disconnect is made */ 
+ int (*connect)(int on); 
+}; 
+ 
+/* Used so that host and device side connect functions can run simultaniously. 
+ * See gadget_connection() & gadget_connect_thread() for details. */ 
+struct mausb_connect_data { 
+ struct task_struct *task; 
+ int i; 
+ int on; 
+}; 
+ 
+/* function declarations */ 
+struct mausb_tcp_medium *mausb_tcp_get_medium(void); 
+void *mausb_tcp_to_context(struct mausb_tcp_medium *medium); 
+struct mausb_tcp_medium *mausb_context_to_tcp(void *context); 
+int mausb_tcp_receive_loop(struct mausb_tcp_medium *medium); 
+int mausb_tcp_add_tx_pair(struct mausb_transfer_pair *ma_pair, 
+ struct mausb_tcp_medium *medium); 
+int mausb_tcp_drop_tx_pair(unsigned long handle, void *context); 
+void mausb_free_ms_pkt(struct ms_pkt *pkt); 
+struct mausb_tcp_medium *alloc_init_mausb_tcp_medium( 
+ enum mausb_tcp_module_type type); 
+void free_mausb_tcp_medium(struct mausb_tcp_medium *medium, 
+ enum mausb_tcp_module_type type); 
+ 
+#endif 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/drivers/mausb_tcp-host.c linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/drivers/mausb_tcp-host.c
--- linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/drivers/mausb_tcp-host.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/drivers/mausb_tcp-host.c	2014-11-28 12:39:00.572447000 +0800
@@ -0,0 +1,162 @@
+/* Name: mausb_tcp-host.c 
+ * Description: The host side media specific driver to allow media agnostic 
+ * packets over tcp/ip. 
+ * 
+ * This file is provided under a dual BSD/GPLv2 license. When using or 
+ * redistributing this file, you may do so under either license. 
+ * 
+ * GPL LICENSE SUMMARY 
+ * 
+ * Copyright(c) 2014 Intel Corporation. 
+ * 
+ * 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. 
+ * 
+ * Contact Information: 
+ * Sean Stalley, sean.stalley [at] intel 
+ * Stephanie Wallick, stephanie.s.wallick [at] intel 
+ * 2111 NE 25th Avenue 
+ * Hillsboro, Oregon 97124 
+ * 
+ * BSD LICENSE 
+ * 
+ * Copyright(c) 2014 Intel Corporation. 
+ * 
+ * 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 of Intel Corporation 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/module.h> 
+#include <linux/init.h> 
+ 
+#include "mausb_tcp.h" 
+/*
+void mausb_free_ms_pkt(struct ms_pkt *pkt) 
+{ 
+ int i; 
+ void *current_buf; 
+ 
+ for (i = 0; i < pkt->nents; ++i) { 
+ current_buf = pkt->kvec[i].iov_base; 
+ if (NULL != current_buf) { 
+ kfree(current_buf); 
+ } else { 
+ pr_debug("%s: cannot find buffer for kvec #%i in" 
+ " ms_pkt at %p\n", __func__, i, pkt->kvec); 
+ } 
+ } 
+ 
+ kfree(pkt); 
+ 
+ return; 
+} */
+ 
+struct mausb_tcp_medium *host_tcp_medium; 
+ 
+int mausb_tcp_host_thread(void *data) 
+{ 
+ return mausb_tcp_receive_loop(host_tcp_medium); 
+} 
+ 
+int mausb_tcp_host_add_tx_pair(struct mausb_transfer_pair *ma_pair) 
+{ 
+ return mausb_tcp_add_tx_pair(ma_pair, host_tcp_medium); 
+} 
+ 
+static struct mausb_ms_ops ms_ops = { 
+ .add_transfer_pair = &mausb_tcp_host_add_tx_pair, 
+ .drop_transfer_pair = &mausb_tcp_drop_tx_pair, 
+ .pkt_destructor = &mausb_free_ms_pkt 
+}; 
+ 
+static struct mausb_ms_drv ms_driver = { 
+ .ops = &ms_ops 
+}; 
+ 
+static int mausb_tcp_host_connect(int on) 
+{ 
+ int ret; 
+ 
+ if (on) { 
+ ret = kernel_bind(host_tcp_medium->setup_socket, 
+ &host_tcp_medium->addr, 
+ sizeof(host_tcp_medium->addr_in)); 
+ 
+ ret = kernel_listen(host_tcp_medium->setup_socket, 
+ MAUSB_TCP_MAX_NUM_CHANNELS); 
+ pr_debug("%s: kernel_listen returned %i\n", __func__, ret); 
+ 
+ ret = kernel_accept(host_tcp_medium->setup_socket, 
+ &host_tcp_medium->socket, 0); 
+ pr_debug("%s:kernel_accept returned %i\n", __func__, ret); 
+ 
+ if (0 > ret) 
+ return ret; 
+ 
+ if (NULL == host_tcp_medium->recv_task) { 
+ host_tcp_medium->recv_task = kthread_run( 
+ mausb_tcp_host_thread, NULL, 
+ "mausb_tcp_host_thread"); 
+ } 
+ } 
+ 
+ ret = host_tcp_medium->ma_driver->device_connect(on); 
+ 
+ return ret; 
+} 
+ 
+int mausb_tcp_host_init(void) 
+{ 
+ host_tcp_medium = alloc_init_mausb_tcp_medium(MAUSB_TCP_HOST); 
+ if (NULL == host_tcp_medium) 
+ return -ENOMEM; 
+ 
+ host_tcp_medium->addr_in.sin_addr.s_addr = htonl(0); 
+ 
+ host_tcp_medium->connect = &mausb_tcp_host_connect; 
+ 
+ host_tcp_medium->ma_driver = mausb_register_ms_driver(&ms_driver); 
+ 
+ return 0; 
+ 
+} 
+module_init(mausb_tcp_host_init); 
+ 
+void mausb_tcp_host_exit(void) 
+{ 
+ free_mausb_tcp_medium(host_tcp_medium, MAUSB_TCP_HOST); 
+} 
+module_exit(mausb_tcp_host_exit); 
+ 
+MODULE_LICENSE("Dual BSD/GPL"); 
+MODULE_AUTHOR("Intel"); 
+MODULE_DESCRIPTION("mausb_tcp_host"); 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/drivers/mausb_tx.c linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/drivers/mausb_tx.c
--- linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/drivers/mausb_tx.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/drivers/mausb_tx.c	2014-11-28 12:39:00.572447000 +0800
@@ -0,0 +1,316 @@
+/* Name: mausb_tx.c 
+ * Description: Common functions for both host and device media agnostic 
+ * transfers. 
+ * 
+ * This file is provided under a dual BSD/GPLv2 license. When using or 
+ * redistributing this file, you may do so under either license. 
+ * 
+ * GPL LICENSE SUMMARY 
+ * 
+ * Copyright(c) 2014 Intel Corporation. 
+ * 
+ * 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. 
+ * 
+ * Contact Information: 
+ * Sean Stalley, sean.stalley [at] intel 
+ * Stephanie Wallick, stephanie.s.wallick [at] intel 
+ * 2111 NE 25th Avenue 
+ * Hillsboro, Oregon 97124 
+ * 
+ * BSD LICENSE 
+ * 
+ * Copyright(c) 2014 Intel Corporation. 
+ * 
+ * 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 of Intel Corporation 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 "mausb_pkt.h" 
+#include "mausb_tx.h" 
+#include "mausb_const.h" 
+ 
+int mausb_transfer_data_pkt(struct mausb_pkt *pkt, struct mausb_host_ep *ep, 
+ gfp_t mem_flags) 
+{ 
+ int ret; 
+ 
+ ret = mausb_pkt_fill_ms_pkt(pkt, mem_flags); 
+ if (0 > ret) 
+ return ret; 
+ 
+ return mausb_transfer_packet(&pkt->pkt, &ep->tx_pair.to_ms); 
+ 
+} 
+EXPORT_SYMBOL(mausb_transfer_data_pkt); 
+ 
+/** 
+ * Opens an endpoint-specific connection between the media specific and media 
+ * agnostic drivers in order to send and receive MA USB data packets. 
+ * 
+ * @drv: Media specific driver to establish connection with. 
+ * @ep: Host endpoint to be associated with this channel. 
+ * @transfer_pkt: The call the MS driver should make when a packet is received. 
+ */ 
+int mausb_add_data_channel(struct mausb_ms_drv *drv, struct mausb_host_ep *ep, 
+ int (*transfer_pkt)(struct ms_pkt *pkt, void *context)) 
+{ 
+ int ret = 0; 
+ struct mausb_transfer_pair tx_pair; 
+ 
+ matx_dbg("%s: adding channel for ep with handle %x\n", __func__, 
+ ep->ep_handle.handle); 
+ 
+ tx_pair.to_ma.transfer_packet = transfer_pkt; 
+ tx_pair.to_ma.context = ep; 
+ tx_pair.pkt_sent = NULL; 
+ tx_pair.handle = ep->ep_handle.handle; 
+ 
+ ret = drv->ops->add_transfer_pair(&tx_pair); 
+ 
+ if (ret >= 0) 
+ ep->tx_pair = tx_pair; 
+ 
+ return ret; 
+} 
+EXPORT_SYMBOL(mausb_add_data_channel); 
+ 
+/** 
+ * Determines if conditions are met to complete a data transfer. 
+ * 
+ * @tx_state: State of transfer to be checked. 
+ * @seq_num: Sequence number to be compared to last sequence number in the 
+ * transfer. 
+ * 
+ * Returns true if a transfer can be considered complete or false otherwise. 
+ * Note that this does not differentiate between transfers that complete 
+ * with and without an error. 
+ */ 
+bool mausb_transfer_is_complete(struct mausb_transfer_state *tx_state, 
+ u8 seq_num) 
+{ 
+ bool complete = false; 
+ 
+ if (!tx_state->transfer_error && tx_state->last_transfer_sn <= seq_num) 
+ complete = true; 
+ 
+ if (tx_state->transfer_error) { 
+ matx_err("%s: transfer ending with error\n", __func__); 
+ complete = true; 
+ } 
+ 
+ return complete; 
+} 
+EXPORT_SYMBOL(mausb_transfer_is_complete); 
+ 
+/** 
+ * Deletes packet from endpoint list and frees memory. 
+ * 
+ * @ep: Endpoint associated with packet to be dropped. 
+ * @pkt: Packet to be dropped. 
+ */ 
+void mausb_drop_packet(struct mausb_host_ep *ep, struct mausb_pkt *pkt) 
+{ 
+ if (ep == NULL || pkt == NULL) 
+ return; 
+ 
+ list_del(&pkt->pkt_list); 
+ mausb_free_pkt(pkt); 
+ 
+ if (list_empty(&ep->req_list)) 
+ INIT_LIST_HEAD(&ep->req_list); 
+ 
+ if (list_empty(&ep->resp_list)) 
+ INIT_LIST_HEAD(&ep->resp_list); 
+} 
+EXPORT_SYMBOL(mausb_drop_packet); 
+ 
+/** 
+ * Deletes all of the packets based on the sequence number. 
+ * 
+ * @ep: Endpoint associated with transfer. 
+ * @seq_num: The sequence number of the packets to delete. This will 
+ * delete all the packets with sequence numbers up to 
+ * (but not including) seq_num. 
+ * @req_id: The request ID of the packets to delete. This will 
+ * delete all the packets with request IDs up to 
+ * (but not including) req_id. 
+ */ 
+void mausb_cleanup_ma_packets(struct mausb_host_ep *ep, u32 seq_num, u8 req_id) 
+{ 
+ struct mausb_pkt *active, *next; 
+ 
+ list_for_each_entry_safe(active, next, &ep->req_list, pkt_list) { 
+ if (mausb_seq_num_lt(active->data->seq_num, seq_num) || 
+ mausb_req_id_lt(active->data->req_id, req_id)) 
+ mausb_drop_packet(ep, active); 
+ } 
+ 
+ list_for_each_entry_safe(active, next, &ep->resp_list, pkt_list) { 
+ if (mausb_seq_num_lt(active->data->seq_num, seq_num) || 
+ mausb_req_id_lt(active->data->req_id, req_id)) 
+ 
+ mausb_drop_packet(ep, active); 
+ } 
+} 
+EXPORT_SYMBOL(mausb_cleanup_ma_packets); 
+ 
+/** 
+ * Resend all packets starting from a given sequence number. 
+ * 
+ * @ep: Endpoint associated with packets. 
+ * @pkt_list: Head of list of packets to search. 
+ * @seq_num: Sequence number of first packet to be sent. 
+ * 
+ * Returns 0 if at least one packet is sent, otherwise returns non-zero value. 
+ * Note: the caller should be holding the endpoint's spinlock. 
+ */ 
+int mausb_resend_multi_packets(struct mausb_host_ep *ep, 
+ struct list_head *pkt_list, 
+ u32 seq_num, unsigned long irq_flags) 
+{ 
+ int ret = -EINVAL; 
+ struct mausb_pkt *pkt; 
+ int i = 0; 
+ 
+ list_for_each_entry(pkt, pkt_list, pkt_list) { 
+ 
+ i++; 
+ if (mausb_seq_num_gt_eq(pkt->data->seq_num, seq_num)) { 
+ matx_dbg("%s: resending pkt %i\n", __func__, 
+ pkt->data->seq_num); 
+ pkt->common->ver_flags |= MAUSB_PKT_FLAG_RETRY; 
+ ret = 0; 
+ mausb_transfer_data_pkt(pkt, ep, GFP_ATOMIC); 
+ } 
+ } 
+ 
+ return ret; 
+} 
+EXPORT_SYMBOL(mausb_resend_multi_packets); 
+ 
+/** 
+ * Checks to see if a received packet is a retry and resends response packets 
+ * (if found). 
+ * 
+ * @ep: Endpoint associated with transfer. 
+ * @pkt_list: List of packets previously sent. 
+ * @pkt: Received packet. 
+ * 
+ * Returns true if received packet has the Retry flag set AND at least one 
+ * response packet was found and sent. Returns false if the Retry flag not 
+ * set or the Retry flag is set but no corresponding packets have been found. 
+ */ 
+bool mausb_is_a_retry(struct mausb_host_ep *ep, struct list_head *pkt_list, 
+ struct mausb_pkt *pkt) 
+{ 
+ int err = 0; 
+ unsigned long irq_flags; 
+ 
+ spin_lock_irqsave(&ep->ep_lock, irq_flags); 
+ if (pkt->common->ver_flags & MAUSB_PKT_FLAG_RETRY) { 
+ matx_dbg("%s: packet is a retry\n", __func__); 
+ 
+ /* 
+ * If received packet is a retry, look to see if we've 
+ * already generated the corresponding packets. 
+ */ 
+ err = mausb_resend_multi_packets(ep, pkt_list, 
+ pkt->data->seq_num, 
+ irq_flags); 
+ 
+ /* 
+ * Only return true if packet is found, otherwise we might 
+ * miss responding to a packet we never received. 
+ */ 
+ if (err == 0) 
+ return true; 
+ } 
+ spin_unlock_irqrestore(&ep->ep_lock, irq_flags); 
+ 
+ return false; 
+} 
+EXPORT_SYMBOL(mausb_is_a_retry); 
+ 
+/** 
+ * Called by timeout timer to start thread that handles error handling and 
+ * packet resends. 
+ * 
+ * Used to avoid passing packets to a medium while in an interrupt context, 
+ * which can be problematic for some mediums. 
+ */ 
+void wake_timeout_thread(unsigned long _ep) 
+{ 
+ struct mausb_host_ep *ep = (struct mausb_host_ep *) _ep; 
+ unsigned long irq_flags; 
+ 
+ matx_dbg("%s: timeout occurred!!!\n", __func__); 
+ 
+ spin_lock_irqsave(&ep->ep_lock, irq_flags); 
+ ep->tx_timed_out = true; 
+ spin_unlock_irqrestore(&ep->ep_lock, irq_flags); 
+ wake_up_interruptible(&ep->host_ep_wq); 
+} 
+ 
+/** 
+ * Fills packet fields based on the given EP. Also fills device fields. 
+ */ 
+void mausb_fill_pkt_ep(struct mausb_pkt *pkt, struct mausb_host_ep *ma_ep) 
+{ 
+ struct mausb_dev *mausb_dev; 
+ struct ma_dev *ma_dev; 
+ unsigned long irq_flags; 
+ 
+ spin_lock_irqsave(&ma_ep->ep_lock, irq_flags); 
+ 
+ if (MAUSB_EP_HANDLE_ACTIVE != ma_ep->ep_handle_state) { 
+ matx_warn("%s: endpoint handle not active\n", __func__); 
+ } 
+ 
+ pkt->common->ep_handle = ma_ep->ep_handle; 
+ pkt->data->eps_tflags |= ma_ep->ep_handle_state; 
+ /* TODO: set transfer Type */ 
+ 
+ mausb_dev = ma_ep->mausb_dev; 
+ spin_unlock_irqrestore(&ma_ep->ep_lock, irq_flags); 
+ 
+ 
+ spin_lock_irqsave(&mausb_dev->dev_lock, irq_flags); 
+ ma_dev = mausb_dev->ma_dev; 
+ spin_unlock_irqrestore(&mausb_dev->dev_lock, irq_flags); 
+ 
+ 
+ spin_lock_irqsave(&ma_dev->ma_dev_lock, irq_flags); 
+ pkt->common->ma_dev_addr = ma_dev->ma_dev_addr; 
+ pkt->common->mass_id = ma_dev->mass_id; 
+ spin_unlock_irqrestore(&ma_dev->ma_dev_lock, irq_flags); 
+} 
+EXPORT_SYMBOL(mausb_fill_pkt_ep); 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/drivers/mausb_tx-device.c linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/drivers/mausb_tx-device.c
--- linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/drivers/mausb_tx-device.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/drivers/mausb_tx-device.c	2014-11-28 12:39:00.572447000 +0800
@@ -0,0 +1,845 @@
+/* Name: mausb_tx_device.c 
+ * Description: implements MA USB transfers on device side 
+ * 
+ * This file is provided under a dual BSD/GPLv2 license. When using or 
+ * redistributing this file, you may do so under either license. 
+ * 
+ * GPL LICENSE SUMMARY 
+ * 
+ * Copyright(c) 2014 Intel Corporation. 
+ * 
+ * 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. 
+ * 
+ * Contact Information: 
+ * Sean Stalley, sean.stalley [at] intel 
+ * Stephanie Wallick, stephanie.s.wallick [at] intel 
+ * 2111 NE 25th Avenue 
+ * Hillsboro, Oregon 97124 
+ * 
+ * BSD LICENSE 
+ * 
+ * Copyright(c) 2014 Intel Corporation. 
+ * 
+ * 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 of Intel Corporation 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 "mausb_hcd.h" 
+#include "mausb_udc.h" 
+#include "mausb_pkt.h" 
+#include "mausb_tx.h" 
+ 
+#include <linux/kthread.h> 
+ 
+int device_transfer_timeout(void *data) 
+{ 
+ struct mausb_host_ep *ep = (struct mausb_host_ep *) data; 
+ struct mausb_udc *udc = mausb_host_ep_to_maudc(ep); 
+ 
+ while (!kthread_should_stop()) { 
+ /* 
+ * make sure actual transfer timeout (i.e. not thread 
+ * setup) 
+ */ 
+ if (ep->tx_timed_out) { 
+ if (ep->state.retry_counter > 0) { 
+ maudc_dbg(udc, "%s: device timed out," 
+ " resending packet %i\n", 
+ __func__, ep->state.seq_number); 
+ 
+ device_OUT_send_txResp( 
+ &ep->active_transfer->state, 
+ &ep->state, 
+ ep->state.active_request_id, 
+ ep->state.seq_number, 
+ SUCCESS, 
+ false, false, false); 
+ 
+ ep->state.retry_counter--; 
+ } else { 
+ /* 
+ * TODO: start ping protocol per 5.2.2, if 
+ * successful reset timer and retries. For now 
+ * we just treat as if failed. 
+ */ 
+ ep->active_transfer->state.transfer_error = 
+ true; 
+ return -ETIMEDOUT; 
+ } 
+ 
+ ep->tx_timed_out = false; 
+ } 
+ 
+ /* put thread to sleep to wait for next timeout event */ 
+ wait_event_interruptible(ep->host_ep_wq, 
+ kthread_should_stop() || ep->tx_timed_out); 
+ } 
+ 
+ return 0; 
+} 
+ 
+ 
+/*-------------------------IN transfer ------------------------*/ 
+ 
+/** 
+ * Device-side IN transfer initialization process. 
+ * 
+ * @ tx_state: Transfer state to be initialized. 
+ * @ ep_state: Endpoint state to be initialized. 
+ * @ tx_req: TransferReq packet from host that intiated transfer. 
+ * 
+ * Called every time a transferReq packet is received. Initializes transfer 
+ * management variables. 
+ */ 
+void device_init_IN_transfer(struct mausb_transfer_state *tx_state, 
+ struct mausb_ep_state *ep_state, struct mausb_pkt *tx_req) 
+{ 
+ struct mausb_host_ep *ep = mausb_state_to_ep(ep_state); 
+ 
+ tx_state->transfer_error = false; 
+ tx_state->transfer_complete = false; 
+ tx_state->rem_size = le32_to_cpu(tx_req->data->remaining_size_credit); 
+ 
+ ep_state->keep_alive_timer = MAUSB_TRANSFER_KEEP_ALIVE; 
+ ep_state->retry_counter = MAUSB_BULK_TRANSFER_RETRIES; 
+ ep_state->earliest_unacked = le32_to_cpu(tx_req->data->seq_num); 
+ ep_state->active_request_id = tx_req->data->req_id; 
+ ep_state->request_id++; 
+ 
+ ep->actual_length = 0; 
+ 
+ /* free old buffer if not previously freed */ 
+ if (ep->buffer) 
+ kfree(ep->buffer); 
+ 
+ /* alocate new buffer for this transfer */ 
+ ep->buffer = kzalloc(tx_state->rem_size, GFP_ATOMIC); 
+} 
+ 
+/* Determines if packet request id or sequence number is outside of the 
+ * acceptable range 
+ * 
+ * Returns true if the packet sequence number or request id is invalid, 
+ * otherwise returns false. 
+ */ 
+bool is_invalid_IN_request(struct mausb_ep_state *ep_state, 
+ struct mausb_pkt *tx_req) 
+{ 
+ u8 r = tx_req->data->req_id; 
+ u32 SN = le32_to_cpu(tx_req->data->seq_num); 
+ bool invalid = false; 
+ struct mausb_udc *udc = mausb_host_ep_to_maudc( 
+ mausb_state_to_ep(ep_state)); 
+ 
+ if ((ep_state->earliest_request_id - MAUSB_HALF_REQ_ID) <= r) { 
+ if (r < ep_state->earliest_request_id) { 
+ maudc_err(udc, "%s: too many outstanding requests\n", 
+ __func__); 
+ invalid = true; 
+ } 
+ } 
+ 
+ if ((ep_state->earliest_unacked - MAUSB_HALF_SEQ_NUM) <= SN) { 
+ if (SN < ep_state->earliest_unacked) { 
+ maudc_err(udc, "%s: too many unacknowledged packets\n", 
+ __func__); 
+ invalid = true; 
+ } 
+ } 
+ 
+ if (ep_state->seq_number < SN) { 
+ if (SN < (ep_state->seq_number + MAUSB_HALF_SEQ_NUM)) { 
+ maudc_err(udc, "%s: too many outstanding sequence" 
+ " numbers\n", __func__); 
+ invalid = true; 
+ } 
+ 
+ } 
+ 
+ return invalid; 
+} 
+ 
+/* 
+ * transferReq reception process outlined in MA USB spec. 
+ */ 
+int device_IN_rcvd_txReq(struct mausb_ep_state *ep_state, 
+ struct mausb_transfer_state *tx_state, 
+ struct mausb_pkt *tx_req) 
+{ 
+ u8 r = tx_req->data->req_id; 
+ u32 SN = le32_to_cpu(tx_req->data->seq_num); 
+ struct mausb_host_ep *ep = mausb_state_to_ep(ep_state); 
+ struct mausb_udc *udc = mausb_host_ep_to_maudc(ep); 
+ 
+ if (is_invalid_IN_request(ep_state, tx_req)) { 
+ mausb_drop_packet(ep, tx_req); 
+ device_IN_send_null_txResp(ep, ep_state->request_id, 
+ INVALID_REQUEST); 
+ } 
+ 
+ ep_state->earliest_unacked = SN; 
+ 
+ if (tx_state->eot_detected && !tx_state->transfer_error) { 
+ if (tx_state->last_transfer_sn < SN) 
+ tx_state->transfer_complete = true; 
+ else 
+ ep_state->earliest_request_id = r; 
+ } 
+ 
+ if (r == ep_state->active_request_id && ep_state->delayed) { 
+ maudc_dbg(udc, "%s: transfer %i is delayed, sending txResp with" 
+ " status = TRANSFER_PENDING\n", __func__, r); 
+ device_IN_send_null_txResp(ep, r, TRANSFER_PENDING); 
+ } 
+ 
+ if (r == ep_state->request_id) 
+ device_init_IN_transfer(tx_state, ep_state, tx_req); 
+ 
+ return 0; 
+} 
+ 
+/* transferAck packet reception process for device side. 
+ * 
+ * @tx_state: Transfer state variables for associated transfer. 
+ * @ep_state: Endpoint state variables for associated transfer. 
+ * @tx_ack: TransferAck packet being received. 
+ * 
+ * Called when device side driver receives a transferAck packet. Caller should 
+ * verify that the request_id in the transferAck packet is valid before 
+ * calling this function. 
+ */ 
+int device_IN_ack_rcvd(struct mausb_transfer_state *tx_state, 
+ struct mausb_ep_state *ep_state, struct mausb_pkt *tx_ack) 
+{ 
+ int ret = 0; 
+ u8 r = tx_ack->data->req_id; 
+ u8 u = ep_state->active_request_id; 
+ u32 SN = le32_to_cpu(tx_ack->data->seq_num); 
+ struct mausb_host_ep *ep = mausb_state_to_ep(ep_state); 
+ struct mausb_udc *udc = mausb_host_ep_to_maudc(ep); 
+ bool tx_complete = (!tx_state->transfer_error) 
+ && (tx_state->last_transfer_sn < SN); 
+ bool tx_complete_with_error = 
+ (tx_state->transfer_error) && (u == r); 
+ unsigned long irq_flags = 0; 
+ 
+ if (is_invalid_IN_request(ep_state, tx_ack)) 
+ tx_ack->data->common.pkt_status = DROPPED_PACKET; 
+ 
+ switch (tx_ack->data->common.pkt_status) { 
+ case DROPPED_PACKET: 
+ maudc_dbg(udc, "%s: status = DROPPED_PACKET\n", __func__); 
+ mausb_drop_packet(ep, tx_ack); 
+ break; 
+ case TRANSFER_PENDING: 
+ maudc_dbg(udc, "%s: status = TRANSFER_PENDING\n", __func__); 
+ if (r != ep_state->active_request_id) 
+ mausb_drop_packet(ep, tx_ack); 
+ /* else can start power saving measures */ 
+ break; 
+ case MISSING_SEQUENCE_NUMBER: 
+ maudc_dbg(udc, "%s: status = MISSING_SEQUENCE_NUMBER\n", 
+ __func__); 
+ mausb_resend_multi_packets(ep, &ep->resp_list, 
+ le32_to_cpu(tx_ack->data->seq_num), irq_flags); 
+ break; 
+ case SUCCESS: 
+ maudc_dbg(udc, "%s: status = SUCCESS\n", __func__); 
+ ep_state->earliest_unacked = SN + 1; 
+ 
+ if (tx_state->eot_detected) { 
+ if (tx_complete || tx_complete_with_error) 
+ tx_state->transfer_complete = true; 
+ else 
+ ep_state->earliest_request_id = u; 
+ 
+ mausb_cleanup_ma_packets(ep, 
+ le32_to_cpu(tx_ack->data->seq_num), 
+ tx_ack->data->req_id); 
+ kfree(ep->buffer); 
+ } 
+ break; 
+ default: 
+ break; 
+ } 
+ 
+ return ret; 
+} 
+ 
+/* Submit a transferResp packet to host with no payload (used for errors). 
+ * 
+ * Per spec, sequence number field in a null transferResp packet is always 
+ * reserved and set to 0 
+ */ 
+int device_IN_send_null_txResp(struct mausb_host_ep *ep, u8 req_id, int status) 
+{ 
+ struct mausb_pkt *tx_resp; 
+ struct mausb_transfer_state *tx_state = &ep->active_transfer->state; 
+ 
+ tx_resp = mausb_create_dp(NULL, ep->active_transfer, MAUSB_IN, 
+ MAUSB_DEV, GFP_ATOMIC); 
+ 
+ if (!tx_resp) 
+ return -ENOMEM; 
+ 
+ list_add_tail(&tx_resp->pkt_list, &ep->resp_list); 
+ 
+ mausb_fill_pkt_ep(tx_resp, ep); 
+ 
+ tx_resp->data->common.pkt_type = TransferResp; 
+ tx_resp->data->req_id = req_id; 
+ tx_resp->data->seq_num = 0; 
+ tx_resp->buffer_length = 0; 
+ tx_resp->data->remaining_size_credit = cpu_to_le32(tx_state->rem_size); 
+ tx_resp->data->common.pkt_status = status; 
+ tx_resp->common->length = cpu_to_le32(mausb_pkt_length(tx_resp)); 
+ 
+ mausb_transfer_data_pkt(tx_resp, ep, GFP_ATOMIC); 
+ 
+ return 0; 
+} 
+ 
+/** 
+ * Submit a transferResp packet with payload to host (normal data transfer). 
+ */ 
+int device_IN_send_txResp_with_payload(struct mausb_host_ep *ep) 
+{ 
+ int payload = 0; 
+ int max_buffer_length = 0; 
+ int ep_rem_size = ep->actual_length; 
+ struct mausb_ep_state *ep_state = &ep->state; 
+ struct mausb_transfer_state *tx_state = &ep->active_transfer->state; 
+ struct mausb_pkt *tx_resp; 
+ struct mausb_udc *udc = mausb_host_ep_to_maudc(ep); 
+ 
+ while (ep_rem_size > 0 || ep_state->seq_number == 0) { 
+ 
+ tx_resp = mausb_create_dp(NULL, ep->active_transfer, MAUSB_IN, 
+ MAUSB_DEV, GFP_ATOMIC); 
+ 
+ if (!tx_resp) 
+ return -ENOMEM; 
+ 
+ list_add_tail(&tx_resp->pkt_list, &ep->resp_list); 
+ 
+ mausb_fill_pkt_ep(tx_resp, ep); 
+ 
+ tx_resp->data->common.pkt_type = TransferResp; 
+ tx_resp->data->req_id = ep_state->active_request_id; 
+ tx_resp->data->seq_num = cpu_to_le32(ep_state->seq_number); 
+ tx_resp->data->remaining_size_credit = 
+ cpu_to_le32(tx_state->rem_size); 
+ 
+ max_buffer_length = 
+ MAUSB_MAX_PACKET_SIZE - sizeof(tx_resp->data); 
+ 
+ if (max_buffer_length <= 0) { 
+ maudc_err(udc, "%s: packet buffer error: length" 
+ " = %i\n", __func__, max_buffer_length); 
+ } else if (tx_state->rem_size <= 0) { 
+ maudc_err(udc, "%s: packet buffer error: rem_size" 
+ " = %i\n", __func__, tx_state->rem_size); 
+ ep->buffer = NULL; 
+ } else { 
+ payload = min_t(int, max_buffer_length, 
+ ep_rem_size); 
+ } 
+ 
+ tx_resp->buffer = ep->buffer; 
+ tx_resp->buffer_length = payload; 
+ tx_resp->common->length = cpu_to_le16(mausb_pkt_length(tx_resp)); 
+ 
+ /* note: setting ARQ flag for error is optional */ 
+ if (tx_state->transfer_error) { 
+ maudc_err(udc, "%s: transfer error with %i bytes " 
+ "remaining\n", __func__, tx_state->rem_size); 
+ 
+ tx_resp->data->eps_tflags |= MAUSB_PKT_TFLAG_EOT; 
+ tx_resp->data->eps_tflags |= MAUSB_PKT_TFLAG_ARQ; 
+ tx_resp->data->common.pkt_status = UNSUCCESSFUL; 
+ 
+ /* 
+ * TODO: take corrective action - e.g. clear all 
+ * transfers and restart endpoint 
+ */ 
+ } 
+ 
+ tx_state->rem_size -= payload; 
+ ep_rem_size -= payload; 
+ /* note: setting ARQ flag for completion is optional */ 
+ if (tx_state->rem_size == 0 || ep_rem_size == 0) { 
+ tx_resp->data->eps_tflags |= MAUSB_PKT_TFLAG_EOT; 
+ tx_resp->data->eps_tflags |= MAUSB_PKT_TFLAG_ARQ; 
+ tx_resp->data->common.pkt_status = SUCCESS; 
+ 
+ ep_state->active_request_id++; 
+ } 
+ 
+ maudc_dbg(udc, "%s: sending transferResp packet with sequence" 
+ " number %i for tranfer %i with %i bytes\n", __func__, 
+ le32_to_cpu(tx_resp->data->seq_num), 
+ le32_to_cpu(tx_resp->data->req_id), payload); 
+ 
+ mausb_transfer_data_pkt(tx_resp, ep, GFP_ATOMIC); 
+ 
+ ep_state->seq_number++; 
+ 
+ } 
+ 
+ return 0; 
+} 
+ 
+/*------------------ protocol-managed OUT transfer --------------------*/ 
+ 
+bool should_drop_OUT_txReq(struct mausb_ep_state *ep_state, 
+ struct mausb_transfer_state *tx_state, struct mausb_pkt *tx_req) 
+{ 
+ u8 r = tx_req->data->req_id; 
+ u32 SN = le32_to_cpu(tx_req->data->seq_num); 
+ int payload_size = tx_req->buffer_length; 
+ int status = SUCCESS; 
+ bool drop = false; 
+ struct mausb_host_ep *ep = mausb_state_to_ep(ep_state); 
+ struct mausb_udc *udc = mausb_host_ep_to_maudc(ep); 
+ 
+ if (SN > ep_state->seq_number) { 
+ maudc_err(udc, "%s: sequence number %i is too large " 
+ "(expected < %i)\n", __func__, SN, 
+ ep_state->seq_number); 
+ drop = true; 
+ status = MISSING_SEQUENCE_NUMBER; 
+ } else if (SN < ep_state->seq_number) { 
+ /* per spec, don't have to send response for this case */ 
+ maudc_err(udc, "%s: sequence number %i is too small " 
+ "(expected >= %i)\n", __func__, SN, 
+ ep_state->seq_number); 
+ drop = true; 
+ } else if (r < ep_state->earliest_request_id) { 
+ maudc_err(udc, "%s: request ID %i is too small " 
+ "(expected > %i)\n", __func__, r, 
+ ep_state->earliest_request_id); 
+ drop = true; 
+ status = INVALID_REQUEST; 
+ } else if (r > ep_state->request_id) { 
+ /* account for wraparound */ 
+ if (ep_state->request_id != 0 && r != MAUSB_MAX_REQ_ID) { 
+ maudc_err(udc, "%s: request ID %i is too large " 
+ "(expected < %i)\n", __func__, r, 
+ ep_state->request_id); 
+ drop = true; 
+ status = INVALID_REQUEST; 
+ } 
+ } else if ((payload_size + ep_state->occupancy) 
+ > ep_state->rx_buf_size) { 
+ maudc_err(udc, "%s: payload (%i bytes) is too large for buffer" 
+ " (%i bytes)\n", __func__, payload_size, 
+ ep_state->occupancy); 
+ drop = true; 
+ status = TRANSFER_DATA_BUFFER_ERROR; 
+ } 
+ 
+ /* 
+ * send txResp to host with appropriate status if txReq is going to 
+ * get dropped 
+ */ 
+ if (status) { 
+ device_OUT_send_txResp(tx_state, ep_state, 
+ ep_state->request_id, ep_state->seq_number, status, 
+ false, false, false); 
+ } 
+ 
+ return drop; 
+} 
+ 
+/** 
+ * Handles receipt of a transferRequest packet. 
+ * 
+ * @tx_state: State variables for associated transfer. 
+ * @ep_state: State variables for associated device endpoint. 
+ * @tx_req: TransferRequest packet being received. 
+ */ 
+int device_OUT_txReq_rcvd(struct mausb_transfer_state *tx_state, 
+ struct mausb_ep_state *ep_state, struct mausb_pkt *tx_req) 
+{ 
+ u8 req_id = tx_req->data->req_id; 
+ u32 SN = le32_to_cpu(tx_req->data->seq_num); 
+ int ret = 0; 
+ int payload_size = tx_req->buffer_length; 
+ struct mausb_host_ep *ep = mausb_state_to_ep(ep_state); 
+ struct mausb_udc *udc = mausb_host_ep_to_maudc(ep); 
+ 
+ maudc_dbg(udc, "%s: received transferReq packet %i for transfer %i\n", 
+ __func__, SN, req_id); 
+ 
+ if (should_drop_OUT_txReq(ep_state, tx_state, tx_req)) { 
+ maudc_err(udc, "%s: dropping packet %i\n", __func__, SN); 
+ mausb_drop_packet(ep, tx_req); 
+ return 0; 
+ } 
+ 
+ /* start new transfer */ 
+ if (req_id == (ep_state->request_id)) { 
+ tx_state->transfer_error = false; 
+ tx_state->transfer_complete = false; 
+ tx_state->eot_detected = false; 
+ tx_state->rem_size = 
+ le32_to_cpu(tx_req->data->remaining_size_credit); 
+ tx_state->payload_size = 0; 
+ ep->active_transfer->transfer_size = tx_state->rem_size; 
+ ep_state->active_request_id = req_id; 
+ INIT_LIST_HEAD(&ep->req_list); 
+ INIT_LIST_HEAD(&ep->resp_list); 
+ 
+ ep->actual_length = 0; 
+ 
+ ep_state->request_id = 
+ mausb_req_id_add(ep_state->request_id, 1); 
+ } 
+ 
+ ep->buffer = tx_req->buffer; 
+ ep_state->occupancy += payload_size; 
+ ret = device_OUT_deliver_payload(tx_req, ep_state, tx_state); 
+ ep_state->occupancy -= payload_size; 
+ 
+ ep_state->seq_number++; 
+ 
+ return 0; 
+} 
+ 
+/** 
+ * Transmits a transferReq or transferAck packet. 
+ */ 
+int device_OUT_send_txResp(struct mausb_transfer_state *tx_state, 
+ struct mausb_ep_state *ep_state, u32 req_id, u32 seq_num, 
+ int status, bool retry, bool eot, bool arq) 
+{ 
+ struct mausb_host_ep *ep = mausb_state_to_ep(ep_state); 
+ struct mausb_pkt *tx_resp = mausb_create_dp(NULL, ep->active_transfer, 
+ MAUSB_OUT, MAUSB_DEV, GFP_ATOMIC); 
+ struct mausb_udc *udc = mausb_host_ep_to_maudc(ep); 
+ 
+ if (!tx_resp) 
+ return -ENOMEM; 
+ 
+ mausb_fill_pkt_ep(tx_resp, ep); 
+ 
+ tx_resp->data->common.pkt_type = TransferResp; 
+ tx_resp->data->req_id = req_id; 
+ tx_resp->data->seq_num = cpu_to_le32(seq_num); 
+ tx_resp->data->common.pkt_status = status; 
+ tx_resp->data->remaining_size_credit = 
+ cpu_to_le32(ep_state->rx_buf_size - ep_state->occupancy); 
+ 
+ list_add_tail(&tx_resp->pkt_list, &ep->resp_list); 
+ 
+ 
+ tx_resp->common->length = cpu_to_le16(mausb_pkt_length(tx_resp)); 
+ 
+ if (retry) 
+ tx_resp->common->ver_flags |= MAUSB_PKT_FLAG_RETRY; 
+ 
+ if (eot) 
+ tx_resp->data->eps_tflags |= MAUSB_PKT_TFLAG_EOT; 
+ 
+ if (arq) 
+ tx_resp->data->eps_tflags |= MAUSB_PKT_TFLAG_ARQ; 
+ 
+ maudc_dbg(udc, "%s: sending transferResp packet %i for transfer %i\n", 
+ __func__, le32_to_cpu(tx_resp->data->seq_num), 
+ tx_resp->data->req_id); 
+ 
+ /* send transferResp packet to host */ 
+ mausb_transfer_data_pkt(tx_resp, ep, GFP_ATOMIC); 
+ 
+ return 0; 
+} 
+ 
+/** 
+ * Handles receipt of a transferAck packet. 
+ * 
+ * Caller should ensure that transfer complete and error flags are not set. 
+ * Note that what to do isn't defined in spec - we are on our own for this one! 
+ */ 
+void device_OUT_ack_rcvd(struct mausb_transfer_state *tx_state, 
+ struct mausb_ep_state *ep_state, 
+ struct mausb_pkt *tx_ack) 
+{ 
+ struct mausb_host_ep *ep = mausb_state_to_ep(ep_state); 
+ struct mausb_udc *udc = mausb_host_ep_to_maudc(ep); 
+ 
+ maudc_dbg(udc, "%s: received transferAck packet for transfer %i\n", 
+ __func__, tx_ack->data->req_id); 
+ 
+ ep_state->occupancy = 0; 
+ mausb_cleanup_ma_packets(ep, le32_to_cpu(tx_ack->data->seq_num), 
+ tx_ack->data->req_id); 
+} 
+ 
+/* 
+ * Copy payload from transferRequest into device buffer. 
+ * 
+ * @tx_req: TransferRequest with payload to be delivered. 
+ * @ep_state: State variables for associated device endpoint. 
+ * @tx_state: State variables for associated transfer. 
+ * 
+ * Caller should ensure that transfer complete and error flags are not set. 
+ * This function also includes payload delivery process outlined in spec. 
+ */ 
+int device_OUT_deliver_payload(struct mausb_pkt *tx_req, 
+ struct mausb_ep_state *ep_state, 
+ struct mausb_transfer_state *tx_state) 
+{ 
+ u32 req_sn = le32_to_cpu(tx_req->data->seq_num); 
+ int payload_size; 
+ struct mausb_host_ep *ep = mausb_state_to_ep(ep_state); 
+ struct mausb_udc *udc = mausb_host_ep_to_maudc(ep); 
+ 
+ /* payload delivery process */ 
+ payload_size = do_ma_transfer(ep, tx_req, MAUSB_OUT); 
+ 
+ /* payload delivery confirmation process */ 
+ if (payload_size < 0) { 
+ maudc_err(udc, "%s: transfer error %i\n", __func__, 
+ payload_size); 
+ 
+ device_OUT_send_txResp(tx_state, ep_state, tx_req->data->req_id, 
+ le32_to_cpu(tx_req->data->seq_num), UNSUCCESSFUL, 
+ false, true, false); 
+ } 
+ 
+ else { 
+ ep_state->earliest_unacked = req_sn + 1; 
+ tx_state->payload_size = payload_size - tx_state->payload_size; 
+ tx_state->rem_size = 
+ le32_to_cpu(tx_req->data->remaining_size_credit); 
+ tx_state->payload_size = payload_size; 
+ 
+ maudc_dbg(udc, "%s: delivered %i bytes with %i remaining\n", 
+ __func__, payload_size, tx_state->rem_size); 
+ 
+ /* control response packet */ 
+ if (tx_req->setup) { 
+ device_OUT_send_txResp(tx_state, ep_state, 
+ tx_req->data->req_id, 
+ le32_to_cpu(tx_req->data->seq_num), 
+ SUCCESS, false, true, true); 
+ 
+ /* end of transfer response packet */ 
+ } else if (tx_state->rem_size == 0) { 
+ tx_state->last_transfer_sn = req_sn; 
+ 
+ device_OUT_send_txResp(tx_state, ep_state, 
+ tx_req->data->req_id, 
+ le32_to_cpu(tx_req->data->seq_num), 
+ SUCCESS, false, true, true); 
+ } else if (tx_req->data->eps_tflags & MAUSB_PKT_TFLAG_ARQ) { 
+ device_OUT_send_txResp(tx_state, ep_state, 
+ tx_req->data->req_id, 
+ le32_to_cpu(tx_req->data->seq_num), 
+ SUCCESS, false, false, true); 
+ } 
+ } 
+ 
+ return 0; 
+} 
+ 
+/*------------------ transfer interfaces ----------------------------*/ 
+ 
+/** 
+ * Called to receive both transferRequest and transferAck packets. 
+ * For transferRequests, a new transfer is initiated - transfer state values 
+ * are initialized and a request is send to the device to get data. For 
+ * transferAcks, a transfer is ended (either successfully or with error, 
+ * depending on transferAck packet status). 
+ */ 
+int receive_ma_packet_IN(struct ms_pkt *ms_pkt, void *context) 
+{ 
+ int ret = 0; 
+ struct mausb_host_ep *ep; 
+ struct mausb_pkt *pkt; 
+ struct mausb_udc *udc; 
+ 
+ if ((NULL == context) || (NULL == ms_pkt)) { 
+ pr_err("%s: received NULL %s\n", __func__, 
+ context ? "packet" : "context"); 
+ return -EFAULT; 
+ } 
+ 
+ ep = (struct mausb_host_ep *) context; 
+ del_timer(&ep->timer); 
+ 
+ pkt = mausb_pkt_from_ms_pkt_ep(ms_pkt, ep, GFP_ATOMIC); 
+ list_add_tail(&pkt->pkt_list, &ep->req_list); 
+ 
+ udc = mausb_host_ep_to_maudc(ep); 
+ 
+ if (mausb_is_a_retry(ep, &ep->resp_list, pkt)) 
+ return 0; 
+ 
+ switch (pkt->data->common.pkt_type) { 
+ case TransferReq: 
+ maudc_dbg(udc, "%s: received transferReq %i for transfer %i\n", 
+ __func__, le32_to_cpu(pkt->data->seq_num), 
+ pkt->data->req_id); 
+ device_IN_rcvd_txReq(&ep->state, &ep->active_transfer->state, 
+ pkt); 
+ ret = do_ma_transfer(ep, pkt, MAUSB_IN); 
+ ret = device_IN_send_txResp_with_payload(ep); 
+ break; 
+ case TransferAck: 
+ maudc_dbg(udc, "%s: received transferAck for transfer %i\n", 
+ __func__, pkt->data->req_id); 
+ ret = device_IN_ack_rcvd(&ep->active_transfer->state, 
+ &ep->state, pkt); 
+ break; 
+ default: 
+ maudc_err(udc, "%s: invalid packet type/subtype %i\n", 
+ __func__, pkt->data->common.pkt_type); 
+ ret = -EINVAL; 
+ } 
+ 
+ return ret; 
+} 
+ 
+/** 
+ * Receives both transferReq and transferAck packets for OUT transfers. When a 
+ * packet is received, it is put on a list for handling. If the endpoint is not 
+ * already handling a packet, it starts iterating through the list of received 
+ * packets. 
+ */ 
+int receive_ma_packet_OUT(struct ms_pkt *ms_pkt, void *context) 
+{ 
+ int ret = 0; 
+ struct mausb_host_ep *ep; 
+ struct mausb_pkt *pkt; 
+ struct mausb_udc *udc; 
+ 
+ if ((NULL == context) || (NULL == ms_pkt)) { 
+ pr_err("%s: received NULL %s\n", __func__, 
+ context ? "packet" : "context"); 
+ return -EFAULT; 
+ } 
+ 
+ ep = (struct mausb_host_ep *) context; 
+ del_timer(&ep->timer); 
+ 
+ pkt = mausb_pkt_from_ms_pkt_ep(ms_pkt, ep, GFP_ATOMIC); 
+ list_add_tail(&pkt->pkt_list, &ep->req_list); 
+ 
+ udc = mausb_host_ep_to_maudc(ep); 
+ 
+ if (mausb_is_a_retry(ep, &ep->resp_list, pkt)) 
+ return 0; 
+ 
+ /* determine if packet is a transferRequest */ 
+ if (pkt->data->common.pkt_type == TransferReq) { 
+ maudc_dbg(udc, "%s: received transferReq %i for transfer %i\n", 
+ __func__, le32_to_cpu(pkt->data->seq_num), 
+ pkt->data->req_id); 
+ ret = device_OUT_txReq_rcvd(&ep->active_transfer->state, 
+ &ep->state, pkt); 
+ 
+ /* if not a transferReq, it should be a transferAck */ 
+ } else if (pkt->data->common.pkt_type == TransferAck) { 
+ maudc_dbg(udc, "%s: received transferAck for transfer %i\n", 
+ __func__, pkt->data->req_id); 
+ device_OUT_ack_rcvd(&ep->active_transfer->state, &ep->state, 
+ pkt); 
+ } else { 
+ /* TODO: deal with invalid packet type */ 
+ } 
+ 
+ return ret; 
+} 
+ 
+/** 
+ * Called when a transferReq is received on a control endpoint. 
+ * 
+ * @ms_pkt: Packet being received. 
+ * @context: Device endpoint associated with transfer (this should always 
+ * be ep0). 
+ */ 
+int receive_ma_packet_control(struct ms_pkt *ms_pkt, void *context) 
+{ 
+ int ret = 0; 
+ struct mausb_host_ep *ep; 
+ struct mausb_pkt *pkt; 
+ struct mausb_udc *udc; 
+ 
+ if ((NULL == context) || (NULL == ms_pkt)) { 
+ pr_err("%s: received NULL %s\n", __func__, 
+ context ? "packet" : "context"); 
+ return -EFAULT; 
+ } 
+ 
+ ep = (struct mausb_host_ep *) context; 
+ del_timer(&ep->timer); 
+ 
+ pkt = mausb_pkt_from_ms_pkt_ep(ms_pkt, ep, GFP_ATOMIC); 
+ udc = mausb_host_ep_to_maudc(ep); 
+ 
+ /* 
+ * A new control transfer begins with a transfer request carrying setup 
+ * data and sequence number 0. 
+ */ 
+ if (pkt->setup) { 
+ ep->state.seq_number = 0; 
+ ep->actual_length = 0; 
+ ep->active_transfer->state.rem_size = 
+ le32_to_cpu(pkt->data->remaining_size_credit); 
+ 
+ /* 
+ * Determine if this is a control IN or OUT - if there is data 
+ * in the packet, or the host is requesting no data, we are 
+ * an OUT. 
+ */ 
+ if (0 != pkt->buffer_length || 
+ 0 == le32_to_cpu(pkt->data->remaining_size_credit)) { 
+ 
+ ep->control_dir = MAUSB_OUT; 
+ 
+ } else 
+ ep->control_dir = MAUSB_IN; 
+ } 
+ 
+ kfree(pkt); 
+ pkt = NULL; 
+ 
+ if (MAUSB_IN == ep->control_dir) 
+ ret = receive_ma_packet_IN(ms_pkt, context); 
+ else 
+ ret = receive_ma_packet_OUT(ms_pkt, context); 
+ 
+ return ret; 
+} 
+ 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/drivers/mausb_tx.h linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/drivers/mausb_tx.h
--- linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/drivers/mausb_tx.h	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/drivers/mausb_tx.h	2014-11-28 12:39:00.572447000 +0800
@@ -0,0 +1,127 @@
+/* Name: mausb_tx.h 
+ * Description: header file for mausb_tx-device.c and mausb_tx-host.c 
+ * 
+ * This file is provided under a dual BSD/GPLv2 license. When using or 
+ * redistributing this file, you may do so under either license. 
+ * 
+ * GPL LICENSE SUMMARY 
+ * 
+ * Copyright(c) 2014 Intel Corporation. 
+ * 
+ * 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. 
+ * 
+ * Contact Information: 
+ * Sean Stalley, sean.stalley [at] intel 
+ * Stephanie Wallick, stephanie.s.wallick [at] intel 
+ * 2111 NE 25th Avenue 
+ * Hillsboro, Oregon 97124 
+ * 
+ * BSD LICENSE 
+ * 
+ * Copyright(c) 2014 Intel Corporation. 
+ * 
+ * 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 of Intel Corporation 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. 
+ */ 
+ 
+#ifndef __MAUSB_TX_H 
+#define __MAUSB_TX_H 
+ 
+#include "mausb_mem.h" 
+#include "mausb_pkt.h" 
+ 
+#ifdef DEBUG 
+#define matx_dbg(format, arg...) \ 
+ printk(KERN_DEBUG format, ##arg) 
+#else 
+#define matx_dbg(format, arg...) 
+#endif 
+ 
+#define matx_warn(format, arg...) \ 
+ printk(KERN_WARNING format, ##arg) 
+ 
+#define matx_err(format, arg...) \ 
+ printk(KERN_ERR format, ##arg) 
+ 
+/* TODO: for now this is set to match gadget zero's buffer size, but 
+ * eventually we need to get this value from the device instead of 
+ * predefining it. */ 
+# define DEVICE_RX_BUF_SIZE 4096 
+ 
+#define MAUSB_WAIT_GADGET_BUFFER_FREE_TIMEOUT 3000 
+ 
+/* functions common to both host and device */ 
+int mausb_add_data_channel(struct mausb_ms_drv *drv, struct mausb_host_ep *ep, 
+ int (*transfer_pkt)(struct ms_pkt *pkt, void *context)); 
+ 
+int mausb_transfer_data_pkt(struct mausb_pkt *pkt, struct mausb_host_ep *ep, 
+ gfp_t mem_flags); 
+bool mausb_transfer_is_complete(struct mausb_transfer_state *tx_state, 
+ u8 seq_num); 
+void mausb_drop_packet(struct mausb_host_ep *ep, struct mausb_pkt *pkt); 
+void mausb_cleanup_ma_packets(struct mausb_host_ep *ep, u32 seq_num, 
+ u8 req_id); 
+bool mausb_is_a_retry(struct mausb_host_ep *ep, struct list_head *pkt_list, 
+ struct mausb_pkt *pkt); 
+int mausb_resend_multi_packets(struct mausb_host_ep *ep, 
+ struct list_head *pkt_list, u32 seq_num, 
+ unsigned long irq_flags); 
+void mausb_fill_pkt_ep(struct mausb_pkt *pkt, struct mausb_host_ep *ma_ep); 
+ 
+/* transfer interface function declarations */ 
+int complete_control_transferRequest(struct ms_pkt *pkt, void *context); 
+int complete_IN_transferRequest(struct ms_pkt *pkt, void *context); 
+int complete_OUT_transferRequest(struct ms_pkt *pkt, void *context); 
+int receive_ma_packet_control(struct ms_pkt *ms_pkt, void *context); 
+int receive_ma_packet_IN(struct ms_pkt *ms_pkt, void *context); 
+int receive_ma_packet_OUT(struct ms_pkt *ms_pkt, void *context); 
+int start_ma_transfer(struct mausb_host_ep *ep, struct mausb_urb *maurb, 
+ int dir_in); 
+ 
+/* transfer state fucntion declarations */ 
+int device_OUT_deliver_payload(struct mausb_pkt *tx_req, 
+ struct mausb_ep_state *ep_state, 
+ struct mausb_transfer_state *tx_state); 
+int device_OUT_send_txResp(struct mausb_transfer_state *tx_state, 
+ struct mausb_ep_state *ep_state, u32 req_id, 
+ u32 seq_num, int status, bool retry, bool eot, bool arq); 
+void host_IN_txReq_transmit(struct mausb_pkt *tx_req, struct mausb_host_ep *ep, 
+ struct mausb_transfer_state *tx_state); 
+int device_IN_send_null_txResp(struct mausb_host_ep *ep, u8 req_id, int status); 
+ 
+/* transfer timeout function declarations */ 
+void wake_timeout_thread(unsigned long _ep); 
+int host_transfer_timeout(void *data); 
+int device_transfer_timeout(void *data); 
+ 
+#endif 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/drivers/mausb_tx-host.c linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/drivers/mausb_tx-host.c
--- linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/drivers/mausb_tx-host.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/drivers/mausb_tx-host.c	2014-11-28 12:39:00.572447000 +0800
@@ -0,0 +1,1209 @@
+/* Name: mausb_tx-host.c 
+ * Description: implement host-side Ma USB transfers 
+ * 
+ * This file is provided under a dual BSD/GPLv2 license. When using or 
+ * redistributing this file, you may do so under either license. 
+ * 
+ * GPL LICENSE SUMMARY 
+ * 
+ * Copyright(c) 2014 Intel Corporation. 
+ * 
+ * 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. 
+ * 
+ * Contact Information: 
+ * Sean Stalley, sean.stalley [at] intel 
+ * Stephanie Wallick, stephanie.s.wallick [at] intel 
+ * 2111 NE 25th Avenue 
+ * Hillsboro, Oregon 97124 
+ * 
+ * BSD LICENSE 
+ * 
+ * Copyright(c) 2014 Intel Corporation. 
+ * 
+ * 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 of Intel Corporation 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/kthread.h> 
+ 
+#include "mausb_hcd.h" 
+#include "mausb_pkt.h" 
+#include "mausb_tx.h" 
+ 
+/** 
+ * Handles a data transfer timeout event, then sleeps until the next 
+ * timeout event. Timeout events that wish to use this thread should 
+ * set the ep->tx_timed_out flag to true to ensure that the thread 
+ * is woken. 
+ */ 
+int host_transfer_timeout(void *data) 
+{ 
+ int err = 0; 
+ int dir_in = 0; 
+ int seq_num = 0; 
+ struct mausb_host_ep *ep = (struct mausb_host_ep *) data; 
+ struct mausb_ep_state *ep_state = &ep->state; 
+ struct mausb_transfer_state *tx_state; 
+ struct mausb_pkt *tx_req; 
+ unsigned long irq_flags; 
+ struct mausb_hcd *mhcd = mausb_host_ep_to_mahcd(ep); 
+ 
+ while (!kthread_should_stop()) { 
+ 
+ spin_lock_irqsave(&ep->ep_lock, irq_flags); 
+ /* 
+ * make sure there is an active transfer for timeout 
+ * to handle (i.e. not thread creation/initialization) 
+ */ 
+ if (ep->active_transfer && ep->active_transfer->urb) { 
+ tx_state = &ep->active_transfer->state; 
+ dir_in = usb_pipein(ep->active_transfer->urb->pipe); 
+ 
+ seq_num = ep_state->earliest_unacked; 
+ 
+ if (ep_state->retry_counter > 0) { 
+ mausb_dbg(mhcd, "%s: host timed out waiting" 
+ " for pkt %i\n", __func__, seq_num); 
+ 
+ /* see if we have corresponding request */ 
+ err = mausb_resend_multi_packets(ep, 
+ &ep->req_list, seq_num, irq_flags); 
+ 
+ /* if not, send new req */ 
+ if (err != 0) { 
+ spin_unlock_irqrestore(&ep->ep_lock, 
+ irq_flags); 
+ 
+ tx_req = mausb_create_dp(NULL, 
+ ep->active_transfer, 
+ MAUSB_IN, MAUSB_HOST, 
+ GFP_ATOMIC); 
+ 
+ tx_req->data->common.pkt_type = 
+ TransferReq; 
+ tx_req->data->seq_num = seq_num; 
+ tx_req->data->common.pkt_status = 
+ SUCCESS; 
+ tx_req->data->req_id = 
+ ep_state->active_request_id; 
+ tx_req->common->ver_flags 
+ |= MAUSB_PKT_FLAG_RETRY; 
+ tx_req->common->length = 
+ mausb_pkt_length(tx_req); 
+ 
+ /* submit packet for transport */ 
+ mausb_transfer_data_pkt(tx_req, ep, 
+ GFP_ATOMIC); 
+ 
+ spin_lock_irqsave(&ep->ep_lock, 
+ irq_flags); 
+ 
+ list_add_tail(&tx_req->pkt_list, 
+ &ep->req_list); 
+ } 
+ 
+ ep_state->retry_counter--; 
+ } else { 
+ /* 
+ * Can optionally initiate ping process in sec 
+ * 5.2.3 of spec. For now we just treat as if 
+ * ping protocol failed. */ 
+ tx_state->transfer_error = true; 
+ 
+ spin_unlock_irqrestore(&ep->ep_lock, irq_flags); 
+ mausb_unlink_giveback_urb(ep->active_transfer, 
+ -ETIMEDOUT); 
+ spin_lock_irqsave(&ep->ep_lock, irq_flags); 
+ } 
+ } 
+ 
+ ep->tx_timed_out = false; 
+ 
+ spin_unlock_irqrestore(&ep->ep_lock, irq_flags); 
+ 
+ /* put thread to sleep to wait for next timeout event */ 
+ wait_event_interruptible(ep->host_ep_wq, 
+ kthread_should_stop() || ep->tx_timed_out); 
+ } 
+ 
+ return 0; 
+} 
+ 
+/* Initialize transfer state, for beginning a new transfer */ 
+static void mausb_host_init_tx_state(struct mausb_transfer_state *tx_state, 
+ u32 tx_size) 
+{ 
+ tx_state->transfer_error = false; 
+ tx_state->transfer_complete = false; 
+ tx_state->eot_detected = false; 
+ tx_state->transfer_acked = false; 
+ tx_state->rem_size = tx_size; 
+ tx_state->payload_size = 0; 
+} 
+ 
+/*--------------------- IN transfers ------------------------------*/ 
+ 
+/** 
+ * Host-side IN transfer initialization process. 
+ * 
+ * @tx_state: Transfer state to be initialized. 
+ * @ep_state: Endpoint state to be initialized. 
+ * @maurb: maurb associated with transfer. 
+ * 
+ * Called whenever a new IN transfer is initiated by the host. 
+ * Initializes transfer state variables, resets timers, then submits a 
+ * transferReq packet to the device side driver. After successful submission 
+ * of a transferReq packet, the transfer request id is incremented by one 
+ * for the next transfer. When transfer request id reaches its max value, 
+ * it wraps back around to zero (per mausb spec requirements). 
+ */ 
+void host_init_IN_transfer(struct mausb_transfer_state *tx_state, 
+ struct mausb_host_ep *ep, struct mausb_urb *maurb) 
+{ 
+ int status = SUCCESS; 
+ u32 tx_size = maurb->urb->transfer_buffer_length; 
+ unsigned long irq_flags; 
+ struct mausb_ep_state *ep_state = &ep->state; 
+ struct mausb_pkt *tx_req = mausb_create_dp(&status, maurb, 
+ MAUSB_IN, MAUSB_HOST, GFP_ATOMIC); 
+ 
+ if (!tx_req) 
+ return; 
+ 
+ mausb_fill_pkt_ep(tx_req, ep); 
+ 
+ spin_lock_irqsave(&ep->ep_lock, irq_flags); 
+ 
+ /* fill the transfer request */ 
+ tx_req->data->common.pkt_type = TransferReq; 
+ tx_req->data->remaining_size_credit = 
+ maurb->urb->transfer_buffer_length; 
+ tx_req->data->req_id = ep_state->request_id; 
+ tx_req->data->seq_num = cpu_to_le32(ep_state->seq_number); 
+ 
+ if (mausb_pkt_has_setup_data(tx_req->data)) { 
+ tx_req->setup = 
+ (struct usb_ctrlrequest *) maurb->urb->setup_packet; 
+ } 
+ 
+ tx_req->common->length = mausb_pkt_length(tx_req); 
+ 
+ /* set the transfer state */ 
+ mausb_host_init_tx_state(tx_state, tx_size); 
+ 
+ /* set the endpoint state */ 
+ ep->tx_timed_out = false; 
+ ep_state->active_request_id = ep_state->request_id; 
+ ep_state->keep_alive_timer = MAUSB_TRANSFER_TIMEOUT; 
+ ep_state->retry_counter = MAUSB_BULK_TRANSFER_RETRIES; 
+ ep_state->request_id = mausb_req_id_add(ep_state->request_id, 1); 
+ 
+ /* send the packet */ 
+ spin_unlock_irqrestore(&ep->ep_lock, irq_flags); 
+ host_IN_txReq_transmit(tx_req, ep, tx_state); 
+ spin_lock_irqsave(&ep->ep_lock, irq_flags); 
+ 
+ /* start timeout timer */ 
+ mod_timer(&ep->timer, 
+ jiffies + msecs_to_jiffies(ep_state->keep_alive_timer)); 
+ 
+ /* add the packet to the endpoint */ 
+ list_add_tail(&tx_req->pkt_list, &ep->req_list); 
+ spin_unlock_irqrestore(&ep->ep_lock, irq_flags); 
+} 
+ 
+/** 
+* Releases an MA USB packet to the data channel and updates state. 
+*/ 
+void host_IN_txReq_transmit(struct mausb_pkt *tx_req, struct mausb_host_ep *ep, 
+ struct mausb_transfer_state *tx_state) 
+{ 
+ int ret; 
+ struct mausb_hcd *mhcd = mausb_host_ep_to_mahcd(ep); 
+ 
+ mausb_dbg(mhcd, "%s: sending pkt %i for request %i\n", __func__, 
+ le32_to_cpu(tx_req->data->seq_num), tx_req->data->req_id); 
+ 
+ /* submit packet for transport */ 
+ ret = mausb_transfer_data_pkt(tx_req, ep, GFP_ATOMIC); 
+ 
+ if (tx_state->eot_detected && !tx_state->transfer_error) 
+ if (tx_state->last_transfer_sn 
+ < le32_to_cpu(tx_req->data->seq_num)) { 
+ tx_state->transfer_acked = true; 
+ /* TODO:transfer_completion_timer = aMaxTransferLifetime */ 
+ } 
+} 
+ 
+/** 
+ * Transmits a TransferAck packet. 
+ * 
+ * @tx_state: State information associated with this transfer. 
+ * @in: Set to true for an IN transfer. 
+ * @ep_state: State information associated with transfer endpoint. 
+ * @status: Status to fill transferAck packet status field. 
+ * Note: unless otherwise specified in spec, should be SUCCESS. 
+ * @seq_num: Sequence number to fill transferAck packet sequence number field. 
+ * Note: should be the greatest sequence number of the packets to 
+ * be acked. 
+ * 
+ * Called to acknowledge end of transfer or when a packet that otherwise 
+ * requires acknowledgement (i.e. ARQ flag is set) is received. 
+ */ 
+int host_send_ack(struct mausb_transfer_state *tx_state, bool in, 
+ struct mausb_ep_state *ep_state, int status, u32 seq_num) 
+{ 
+ struct mausb_urb *maurb = container_of(tx_state, 
+ struct mausb_urb, state); 
+ struct mausb_host_ep *ep = mausb_state_to_ep(ep_state); 
+ struct mausb_pkt *tx_ack = mausb_create_dp(NULL, maurb, in, 
+ MAUSB_HOST, GFP_ATOMIC); 
+ struct mausb_hcd *mhcd = mausb_host_ep_to_mahcd(ep); 
+ unsigned long irq_flags; 
+ 
+ if (tx_ack == NULL) 
+ return -ENOMEM; 
+ 
+ mausb_fill_pkt_ep(tx_ack, ep); 
+ 
+ tx_ack->data->common.pkt_type = TransferAck; 
+ tx_ack->data->seq_num = cpu_to_le32(seq_num); 
+ tx_ack->data->common.pkt_status = status; 
+ tx_ack->data->req_id = ep_state->active_request_id; 
+ tx_ack->common->length = cpu_to_le16(mausb_pkt_length(tx_ack)); 
+ 
+ mausb_dbg(mhcd, "%s: sending ack for transfer %i\n", 
+ __func__, ep_state->active_request_id); 
+ 
+ if (in && tx_state->eot_detected) { 
+ if (mausb_transfer_is_complete(tx_state, seq_num)) { 
+ tx_state->transfer_acked = true; 
+ /* TODO: set completion timer */ 
+ } 
+ 
+ /* since we're done, clear out packet lists and free memory */ 
+ mausb_cleanup_ma_packets(ep, seq_num, 
+ ep_state->earliest_request_id); 
+ 
+ } else if (!in) { 
+ tx_state->transfer_acked = true; 
+ /* TODO: set transfer completion timer = aMaxTransferLifetime */ 
+ } 
+ 
+ /* submit packet for transport */ 
+ mausb_transfer_data_pkt(tx_ack, ep, GFP_ATOMIC); 
+ 
+ spin_lock_irqsave(&ep->ep_lock, irq_flags); 
+ list_add_tail(&tx_ack->pkt_list, &ep->req_list); 
+ spin_unlock_irqrestore(&ep->ep_lock, irq_flags); 
+ 
+ return 0; 
+} 
+ 
+/** 
+ * Deliver payload from transferResp to target urb. 
+ * 
+ * @tx_resp: transferResponse packet with data to be transfered. 
+ * @maurb: urb associated with transfer. 
+ * 
+ * Must ensure that transfer has not been completed (transfer_complete is 
+ * false) and there are no transfer errors (transfer_error is false) before 
+ * calling. 
+ * 
+ * Returns length in bytes of data delivered. 
+ */ 
+int host_IN_deliver_payload(struct mausb_pkt *tx_resp, struct mausb_urb *maurb) 
+{ 
+ int offset; 
+ int length = tx_resp->buffer_length; 
+ struct mausb_hcd *mhcd = mausb_host_ep_to_mahcd(maurb->ep); 
+ 
+ if (length == 0) { 
+ mausb_err(mhcd, "%s: no payload (length = 0)\n", __func__); 
+ return length; 
+ } 
+ 
+ if (!maurb || !maurb->urb || !maurb->urb->transfer_buffer) { 
+ mausb_err(mhcd, "%s: urb not found\n", __func__); 
+ return -EINVAL; 
+ } 
+ 
+ if (!tx_resp || !tx_resp->buffer) { 
+ mausb_err(mhcd, "%s: no transferResponse buffer\n", __func__); 
+ return -EINVAL; 
+ } 
+ 
+ offset = maurb->urb->transfer_buffer_length - maurb->state.rem_size; 
+ 
+ memcpy(maurb->urb->transfer_buffer + offset, tx_resp->buffer, length); 
+ 
+ maurb->urb->actual_length += length; 
+ 
+ return length; 
+} 
+ 
+/** 
+ * Determines if a received transfer response should be dropped 
+ * due to invalid request or sequence number. Note: this fuction does not 
+ * actually drop any packets. 
+ * 
+ * The caller should be holding the endpoints spinlock. 
+ * 
+ * Returns true if packet should be dropped, otherwise returns false. 
+ */ 
+bool should_drop_txResp(struct mausb_ep_state *ep_state, 
+ struct mausb_transfer_state *tx_state, 
+ struct mausb_pkt *tx_resp, bool in) 
+{ 
+ bool drop = false; 
+ u8 r = tx_resp->data->req_id; 
+ u32 SN = le32_to_cpu(tx_resp->data->seq_num); 
+ struct mausb_host_ep *ep = mausb_state_to_ep(ep_state); 
+ struct mausb_hcd *mhcd = mausb_host_ep_to_mahcd(ep); 
+ 
+ /* transfer is complete or error flag is set */ 
+ if (tx_state->transfer_complete || tx_state->transfer_error) { 
+ mausb_err(mhcd, "%s: transfer %i already completed %s error\n", 
+ __func__, r, 
+ (tx_state->transfer_error ? "with" : "without:")); 
+ drop = true; 
+ } 
+ 
+ /* request id is invalid */ 
+ if (mausb_req_id_lt(r, ep_state->earliest_request_id) || 
+ (mausb_req_id_gt_eq(r, ep_state->request_id))) { 
+ 
+ mausb_err(mhcd, "%s: request ID %i is invalid\n", __func__, r); 
+ 
+ host_send_ack(tx_state, MAUSB_IN, ep_state, 
+ INVALID_REQUEST, SN); 
+ drop = true; 
+ } 
+ 
+ /* 
+ * Sequence number is reserved for TRANSFER_PENDING, 
+ * so skip sequence number checks. 
+ */ 
+ if (TRANSFER_PENDING == tx_resp->common->pkt_status) 
+ return drop; 
+ 
+ /* sequence number is larger than expected */ 
+ if (mausb_seq_num_gt(SN, ep_state->seq_number)) { 
+ 
+ mausb_err(mhcd, "%s: missing sequence number - expected %i but" 
+ " received %i\n", __func__, ep_state->seq_number, SN); 
+ 
+ drop = true; 
+ host_send_ack(tx_state, MAUSB_IN, ep_state, 
+ MISSING_SEQUENCE_NUMBER, ep_state->seq_number); 
+ } 
+ 
+ /* sequence number is invalid */ 
+ if ((!in && mausb_seq_num_lt(SN, ep_state->earliest_unacked)) || 
+ (in && mausb_seq_num_lt(SN, ep_state->seq_number))) { 
+ 
+ mausb_err(mhcd, "%s: invalid sequence number %i for %s" 
+ " transfer\n", __func__, SN, (in ? "IN" : "OUT")); 
+ drop = true; 
+ } 
+ 
+ return drop; 
+} 
+ 
+/** 
+ * Handles receipt of transferResp. 
+ * 
+ * @ep_state: State information associated with transfer endpoint. 
+ * @tx_state: State information associated with transfer. 
+ * @tx_resp: transferResponse packet being received. 
+ * 
+ * Called when host receives a transferResp packet from a device during an IN 
+ * transfer. Updates host-side transfer and endpoint states and checks for 
+ * packet errors. 
+ * 
+ * Returns length of payload copied into host buffer. If nothing was copied 
+ * returns 0 or errno if error. 
+ */ 
+int host_IN_txResp_rcvd(struct mausb_ep_state *ep_state, 
+ struct mausb_transfer_state *tx_state, 
+ struct mausb_pkt *tx_resp) 
+{ 
+ int length = 0; 
+ u8 r = tx_resp->data->req_id; 
+ u8 eps_flags = tx_resp->data->eps_tflags; 
+ u32 payload_size = tx_resp->buffer_length; 
+ u32 SN = le32_to_cpu(tx_resp->data->seq_num); 
+ struct mausb_host_ep *ep = mausb_state_to_ep(ep_state); 
+ struct mausb_hcd *mhcd = mausb_host_ep_to_mahcd(ep); 
+ 
+ /* look for sequence number and request ID errors */ 
+ if (should_drop_txResp(ep_state, tx_state, tx_resp, MAUSB_IN)) { 
+ mausb_drop_packet(ep, tx_resp); 
+ return length; 
+ } 
+ 
+ switch (tx_resp->data->common.pkt_status) { 
+ case DROPPED_PACKET: 
+ mausb_dbg(mhcd, "%s: status = DROPPED_PACKET\n", __func__); 
+ mausb_drop_packet(ep, tx_resp); 
+ break; 
+ case INVALID_REQUEST: /* same as MISSING_REQUEST_ID in spec */ 
+ mausb_dbg(mhcd, "%s: status = INVALID_REQUEST\n", __func__); 
+ /* 
+ * TODO: invalidate all outstanding transferReqs with req id 
+ * from r to ep_state->request_id - 1 
+ */ 
+ ep_state->request_id = r; 
+ break; 
+ case TRANSFER_PENDING: 
+ mausb_dbg(mhcd, "%s: status = TRANSFER_PENDING\n", __func__); 
+ ep_state->keep_alive_timer = 
+ (tx_state->k * MAUSB_TRANSFER_KEEP_ALIVE); 
+ ep_state->retry_counter = ep_state->transfer_retries; 
+ if (eps_flags & MAUSB_PKT_TFLAG_ARQ) { 
+ /* 
+ * NOTE: per spec, the sequence number in the ack packet 
+ * is reserved and set to 0. 
+ */ 
+ host_send_ack(tx_state, MAUSB_IN, ep_state, 
+ TRANSFER_PENDING, 0); 
+ } 
+ break; 
+ case TRANSFER_EP_STALL: 
+ mausb_dbg(mhcd, "%s: status = TRANSFER_EP_STALL\n", __func__); 
+ if (eps_flags & MAUSB_PKT_TFLAG_EOT) { 
+ host_send_ack(tx_state, MAUSB_IN, ep_state, 
+ TRANSFER_EP_STALL, SN); 
+ 
+ tx_state->eot_detected = true; 
+ } 
+ break; 
+ case SUCCESS: 
+ ep_state->keep_alive_timer = MAUSB_TRANSFER_KEEP_ALIVE; 
+ ep_state->transfer_retries = MAUSB_BULK_TRANSFER_RETRIES; 
+ 
+ if (SN == ep_state->seq_number) { 
+ if (tx_state->rem_size >= payload_size) { 
+ length = host_IN_deliver_payload(tx_resp, 
+ container_of(tx_state, 
+ struct mausb_urb, state)); 
+ 
+ ep_state->seq_number++; 
+ tx_state->rem_size -= length; 
+ 
+ if (eps_flags & MAUSB_PKT_TFLAG_ARQ || 
+ eps_flags & MAUSB_PKT_TFLAG_EOT) { 
+ host_send_ack(tx_state, MAUSB_IN, 
+ ep_state, SUCCESS, SN); 
+ } 
+ 
+ if (eps_flags & MAUSB_PKT_TFLAG_EOT) { 
+ tx_state->eot_detected = true; 
+ tx_state->last_transfer_sn = SN; 
+ ep_state->earliest_request_id = 
+ mausb_req_id_add( 
+ ep_state->earliest_request_id, 
+ 1); 
+ ep_state->active_request_id = 
+ mausb_req_id_add( 
+ ep_state->active_request_id, 1); 
+ 
+ /* 
+ * Can optionally send ack here. 
+ * If don't send ack, next txReq 
+ * serves as ack. 
+ */ 
+ 
+ if (tx_state->rem_size > 0) { 
+ tx_state->transfer_error = true; 
+ mausb_dbg(mhcd, "%s: end of " 
+ "transfer with %i bytes left\n", 
+ __func__, tx_state->rem_size); 
+ } 
+ } 
+ } else { 
+ /* 
+ * For now just drop packet, but can also 
+ * optionally admit up to rem_size of payload 
+ * into buffer. 
+ */ 
+ tx_state->transfer_error = true; 
+ mausb_drop_packet(ep, tx_resp); 
+ host_send_ack(tx_state, MAUSB_IN, ep_state, 
+ TRANSFER_SIZE_ERROR, SN); 
+ } 
+ } 
+ break; 
+ default: 
+ mausb_dbg(mhcd, "%s: status = %i, dropping packet\n", 
+ __func__, tx_resp->data->common.pkt_status); 
+ mausb_drop_packet(ep, tx_resp); 
+ break; 
+ } 
+ 
+ return length; 
+} 
+ 
+ 
+/*------------------ protocol-managed OUT transfers -----------------*/ 
+ 
+/** 
+ * @ tx_state: Transfer state to be initialized. 
+ * @ ep: Endpoint associated with transfer. 
+ * @ tx_size: Transfer size in bytes. 
+ * 
+ * Called every time a new OUT transfer is initiated. Initializes transfer 
+ * state variables. 
+ */ 
+void host_init_OUT_transfer(struct mausb_transfer_state *tx_state, 
+ struct mausb_host_ep *ep, u32 tx_size) 
+{ 
+ unsigned long irq_flags; 
+ 
+ mausb_host_init_tx_state(tx_state, tx_size); 
+ 
+ spin_lock_irqsave(&ep->ep_lock, irq_flags); 
+ 
+ ep->tx_timed_out = false; 
+ 
+ ep->state.active_request_id = ep->state.request_id; 
+ 
+ /* 
+ * Increment request id for new transfer (or go back to zero 
+ * if max sequence number is reached. 
+ */ 
+ ep->state.request_id = mausb_req_id_add(ep->state.request_id, 1); 
+ spin_unlock_irqrestore(&ep->ep_lock, irq_flags); 
+} 
+ 
+/** 
+ * Send a transferReq packet to a device. 
+ * 
+ * @tx_state: State variables for transfer. 
+ * @ep_state: State variables for endpoint associated with transfer. 
+ * @tx_req; MA USB transferReq packet to be sent out. 
+ */ 
+int host_OUT_send_txReq(struct mausb_transfer_state *tx_state, 
+ struct mausb_ep_state *ep_state, struct mausb_pkt *tx_req) 
+{ 
+ int i = 0; 
+ int payload_size = tx_req->buffer_length; 
+ int mausb_pkt_head_size; 
+ struct mausb_host_ep *ep = mausb_state_to_ep(ep_state); 
+ struct mausb_hcd *mhcd = mausb_host_ep_to_mahcd(ep); 
+ unsigned long irq_flags; 
+ 
+ mausb_pkt_head_size = mausb_pkt_header_length(tx_req->common); 
+ 
+ if (payload_size > ep_state->rx_buf_size) { 
+ mausb_dbg(mhcd, "%s: payload of %i bytes is too big - device " 
+ "can only receive %i bytes\n", __func__, payload_size, 
+ ep_state->rx_buf_size); 
+ while (payload_size > ep_state->rx_buf_size && 
+ i <= MAUSB_WAIT_GADGET_BUFFER_FREE_TIMEOUT) { 
+ msleep(1); 
+ i++; 
+ } 
+ if (i > MAUSB_WAIT_GADGET_BUFFER_FREE_TIMEOUT) { 
+ mausb_dbg(mhcd, 
+ "wait gadget receive buffer free time out\n"); 
+ return -ETIMEDOUT; 
+ } 
+ } 
+ 
+ spin_lock_irqsave(&ep->ep_lock, irq_flags); 
+ 
+ if (mausb_seq_num_lt(ep_state->seq_number, 
+ ep_state->earliest_unacked)) { 
+ 
+ mausb_err(mhcd, "%s: too many outstanding packets\n", 
+ __func__); 
+ /* TODO: transmit packet at later time (flow control) */ 
+ } 
+ 
+ if (payload_size <= ep_state->rx_buf_size) { 
+ /* 
+ * Credit remains less than 1 max_packet_payload, 
+ * and there are more than 1 max_packet_payload data to 
+ * transfer. Ask device to update credit. 
+ */ 
+ if (ep_state->rx_buf_size - payload_size < 
+ MAUSB_MAX_PACKET_SIZE - mausb_pkt_head_size && 
+ tx_state->rem_size > ep_state->rx_buf_size - payload_size) { 
+ mausb_dbg(mhcd, "request ARQ, payload_size: %d," 
+ " rx_buf_size: %d\n", payload_size, 
+ ep_state->rx_buf_size); 
+ tx_req->data->eps_tflags |= MAUSB_PKT_TFLAG_ARQ; 
+ } 
+ /* look for end of transfer */ 
+ if (tx_state->rem_size == 0) { 
+ tx_req->data->eps_tflags |= MAUSB_PKT_TFLAG_EOT; 
+ tx_req->data->eps_tflags |= MAUSB_PKT_TFLAG_ARQ; 
+ } 
+ 
+ /* set timer if expecting a response */ 
+ if (tx_req->data->eps_tflags & MAUSB_PKT_TFLAG_ARQ && 
+ le32_to_cpu(tx_req->data->seq_num) != 0) { 
+ tx_state->ack_transfer_sn = 
+ le32_to_cpu(tx_req->data->seq_num); 
+ mod_timer(&ep->timer, jiffies + 
+ msecs_to_jiffies(MAUSB_TRANSFER_TIMEOUT)); 
+ } 
+ 
+ spin_unlock_irqrestore(&ep->ep_lock, irq_flags); 
+ 
+ tx_req->common->length = cpu_to_le16(mausb_pkt_length(tx_req)); 
+ 
+ mausb_dbg(mhcd, "%s: sending transferRequest with sequence" 
+ " number %i for request %i with %i bytes of payload\n", 
+ __func__, le32_to_cpu(tx_req->data->seq_num), 
+ le32_to_cpu(tx_req->data->req_id), 
+ tx_req->buffer_length); 
+ 
+ tx_state->payload_size += payload_size; 
+ 
+ /* submit packet for transport */ 
+ mausb_transfer_data_pkt(tx_req, ep, GFP_ATOMIC); 
+ 
+ spin_lock_irqsave(&ep->ep_lock, irq_flags); 
+ 
+ ep_state->rx_buf_size -= payload_size; 
+ } 
+ spin_unlock_irqrestore(&ep->ep_lock, irq_flags); 
+ 
+ return 0; 
+} 
+ 
+/** 
+ * Determines if this urb is a for a control transfer. For host side only 
+ * (device doesn't have urbs). 
+ */ 
+static bool mausb_control_xfer(struct mausb_urb *maurb) 
+{ 
+ return (usb_endpoint_type(&maurb->urb->ep->desc) == 
+ USB_ENDPOINT_XFER_CONTROL && maurb->urb->setup_packet); 
+} 
+ 
+/** 
+ * Create and send OUT transferRequest packets for a given transfer. 
+ * 
+ * @tx_state: State associated with transfer. 
+ * @ep_state: State associated with transfer endpoint. 
+ * @maurb: MA USB urb associated with transfer. 
+ */ 
+int host_OUT_generate_txReqs(struct mausb_transfer_state *tx_state, 
+ struct mausb_ep_state *ep_state, struct mausb_urb *maurb) 
+{ 
+ int offset = 0; 
+ int pkt_length = 0; 
+ int payload_size = 0; 
+ int max_buffer_length = 0; 
+ struct mausb_pkt *tx_req; 
+ struct mausb_host_ep *ep = mausb_state_to_ep(ep_state); 
+ struct mausb_hcd *mhcd = mausb_host_ep_to_mahcd(ep); 
+ unsigned long irq_flags; 
+ 
+ /* 
+ * Always generate at least one OUT transferReq (OUT control 
+ * transfers may only contain setup data). 
+ */ 
+ do { 
+ /* create transferReq and set packet field values */ 
+ tx_req = mausb_create_dp(SUCCESS, maurb, MAUSB_OUT, 
+ MAUSB_HOST, GFP_ATOMIC); 
+ 
+ if (!tx_req) 
+ return -ENOMEM; 
+ 
+ mausb_fill_pkt_ep(tx_req, ep); 
+ tx_req->data->common.pkt_type = TransferReq; 
+ tx_req->data->req_id = ep_state->active_request_id; 
+ tx_req->data->seq_num = cpu_to_le32(ep_state->seq_number); 
+ tx_req->data->remaining_size_credit = 
+ cpu_to_le32(tx_state->rem_size); 
+ tx_req->buffer_length = 0; 
+ tx_req->nents = 0; 
+ 
+ /* add setup data (If necessary) */ 
+ if (mausb_pkt_has_setup_data(tx_req->data)) { 
+ tx_req->setup = (struct usb_ctrlrequest *) 
+ maurb->urb->setup_packet; 
+ } 
+ 
+ /* calculate max packet buffer size */ 
+ pkt_length = mausb_pkt_length(tx_req); 
+ max_buffer_length = MAUSB_MAX_PACKET_SIZE - pkt_length; 
+ payload_size = min_t(int, max_buffer_length, 
+ tx_state->rem_size); 
+ 
+ /* a control transfer can be empty, but nothing else */ 
+ if (payload_size <= 0 && 
+ !mausb_pkt_has_setup_data(tx_req->data)) { 
+ mausb_err(mhcd, "%s: packet error - no room for " 
+ "payload (buffer size is %i)\n", __func__, 
+ payload_size); 
+ return -ENOBUFS; 
+ } else if (payload_size > 0) { 
+ 
+ if (!maurb->urb->transfer_buffer) { 
+ mausb_err(mhcd, "%s: no transfer buffer\n", 
+ __func__); 
+ } 
+ 
+ /* create packet buffer and fill */ 
+ tx_req->buffer = maurb->urb->transfer_buffer + offset; 
+ if (!tx_req->buffer) { 
+ mausb_free_pkt(tx_req); 
+ return -ENOMEM; 
+ } 
+ 
+ tx_req->buffer_length = payload_size; 
+ } 
+ 
+ /* update state variables */ 
+ offset += payload_size; 
+ tx_state->rem_size -= payload_size; 
+ tx_req->data->remaining_size_credit = tx_state->rem_size; 
+ 
+ /* send transferReq packet to device */ 
+ host_OUT_send_txReq(tx_state, ep_state, tx_req); 
+ 
+ spin_lock_irqsave(&ep->ep_lock, irq_flags); 
+ ep_state->seq_number = 
+ mausb_seq_num_add(ep_state->seq_number, 1); 
+ list_add_tail(&tx_req->pkt_list, &ep->req_list); 
+ 
+ spin_unlock_irqrestore(&ep->ep_lock, irq_flags); 
+ 
+ } while (tx_state->rem_size > 0); 
+ 
+ return 0; 
+} 
+ 
+/** 
+ * Updates transfer and endpoint states after a transferResp is received. 
+ * 
+ * @ep_state: State information for enpoint associated with transfer. 
+ * @tx_state: State information for transfer in progress. 
+ * @tx_resp: transferResponse packet that has been received. 
+ * 
+ * Called whenever a transferResp packet is received. Returns size in bytes 
+ * of payload transferred. 
+ */ 
+int host_OUT_txResp_rcvd(struct mausb_ep_state *ep_state, 
+ struct mausb_transfer_state *tx_state, 
+ struct mausb_pkt *tx_resp) 
+{ 
+ int payload_size = 0; 
+ u8 status = tx_resp->common->pkt_status; 
+ u8 ep_flags = tx_resp->data->eps_tflags; 
+ u32 SN = le32_to_cpu(tx_resp->data->seq_num); 
+ u32 credit = le32_to_cpu( 
+ tx_resp->data->remaining_size_credit); 
+ struct mausb_host_ep *ep = mausb_state_to_ep(ep_state); 
+ struct mausb_urb *maurb = container_of(tx_state, 
+ struct mausb_urb, state); 
+ struct mausb_hcd *mhcd = mausb_host_ep_to_mahcd(ep); 
+ unsigned long irq_flags; 
+ 
+ mausb_dbg(mhcd, "%s: received transferResponse with sequence number %i" 
+ " for transfer %i\n", __func__, SN, tx_resp->data->req_id); 
+ 
+ spin_lock_irqsave(&ep->ep_lock, irq_flags); 
+ /* look for sequence number and/or request ID errors */ 
+ if (should_drop_txResp(ep_state, tx_state, tx_resp, MAUSB_OUT)) { 
+ mausb_drop_packet(ep, tx_resp); 
+ spin_unlock_irqrestore(&ep->ep_lock, irq_flags); 
+ return payload_size; 
+ } 
+ 
+ switch (status) { 
+ case SUCCESS: 
+ /* look for and acknowledge end of transfer */ 
+ if (ep_flags & MAUSB_PKT_TFLAG_EOT) { 
+ 
+ spin_unlock_irqrestore(&ep->ep_lock, irq_flags); 
+ host_send_ack(tx_state, MAUSB_OUT, ep_state, 
+ SUCCESS, SN); 
+ spin_lock_irqsave(&ep->ep_lock, irq_flags); 
+ 
+ ep_state->earliest_request_id = 
+ mausb_req_id_add( 
+ ep_state->earliest_request_id, 1); 
+ ep_state->active_request_id = 
+ mausb_req_id_add( 
+ ep_state->active_request_id, 1); 
+ 
+ tx_state->eot_detected = true; 
+ tx_state->last_transfer_sn = SN; 
+ maurb->urb->actual_length += tx_state->payload_size; 
+ } 
+ 
+ ep_state->earliest_unacked = SN + 1; 
+ ep_state->rx_buf_size = credit - payload_size; 
+ break; 
+ case INVALID_REQUEST: 
+ mausb_dbg(mhcd, "%s: status = INVALID_REQUEST\n", __func__); 
+ /* TODO: start over with request number in packet */ 
+ break; 
+ case DROPPED_PACKET: 
+ mausb_dbg(mhcd, "%s: status = DROPPED_PACKET\n", __func__); 
+ /* fallthrough, same as MISSING_SEQUENCE_NUMBER */ 
+ case MISSING_SEQUENCE_NUMBER: 
+ mausb_dbg(mhcd, "%s: status = MISSING_SEQUENCE_NUMBER\n", 
+ __func__); 
+ mausb_resend_multi_packets(ep, &ep->req_list, 
+ le32_to_cpu(tx_resp->data->seq_num), irq_flags); 
+ break; 
+ case TRANSFER_PENDING: 
+ mausb_dbg(mhcd, "%s: status = TRANSFER_PENDING\n", __func__); 
+ /* TODO: reset transmission counter */ 
+ break; 
+ case TRANSFER_EP_STALL: 
+ mausb_dbg(mhcd, "%s: status = TRANSFER_EP_STALL\n", __func__); 
+ if (ep_flags & MAUSB_PKT_TFLAG_EOT) { 
+ spin_unlock_irqrestore(&ep->ep_lock, irq_flags); 
+ host_send_ack(tx_state, MAUSB_OUT, ep_state, 
+ TRANSFER_EP_STALL, SN); 
+ spin_lock_irqsave(&ep->ep_lock, irq_flags); 
+ 
+ tx_state->eot_detected = true; 
+ } 
+ break; 
+ case TRANSFER_CANCELLED: 
+ mausb_dbg(mhcd, "%s: status = TRANSFER_CANCELLED\n", 
+ __func__); 
+ break; 
+ case TRANSFER_DATA_BUFFER_ERROR: 
+ mausb_dbg(mhcd, "%s: status = TRANSFER_DATA_BUFFER_ERROR\n", 
+ __func__); 
+ break; 
+ default: 
+ tx_state->transfer_error = true; 
+ mausb_drop_packet(ep, tx_resp); 
+ break; 
+ } 
+ 
+ spin_unlock_irqrestore(&ep->ep_lock, irq_flags); 
+ 
+ return payload_size; 
+} 
+ 
+ 
+/* --------------------- Transfer interfaces ----------------------*/ 
+ 
+/** 
+ * Interface called to initiate an IN or OUT transfer. 
+ * 
+ * @ep: Host endpoint associated with transfer. 
+ * @maurb: maurb with payload to transfer. 
+ * NOTE: one maurb maps to one transfer. 
+ * @dir_in: Transfer direction. Set to one if IN (to host) or zero if OUT. 
+ * 
+ * Only one transfer can be in progress at a time for a particular endpoint. 
+ * When a transfer is in progress, the tx_pending flag for that endpoint is set 
+ * indicating that the endpoint is busy. 
+ */ 
+int start_ma_transfer(struct mausb_host_ep *ep, struct mausb_urb *maurb, 
+ int dir_in) 
+{ 
+ int tx_size; 
+ unsigned long irq_flags; 
+ char *tx_type; 
+ struct mausb_hcd *mhcd = mausb_host_ep_to_mahcd(ep); 
+ const struct usb_endpoint_descriptor *ep_desc; 
+ 
+ ep_desc = mausb_get_ep_des(ep); 
+ 
+ switch (usb_endpoint_type(ep_desc)) { 
+ case USB_ENDPOINT_XFER_CONTROL: 
+ tx_type = "control"; 
+ break; 
+ case USB_ENDPOINT_XFER_ISOC: 
+ tx_type = "isochronous"; 
+ break; 
+ case USB_ENDPOINT_XFER_BULK: 
+ tx_type = "bulk"; 
+ break; 
+ case USB_ENDPOINT_XFER_INT: 
+ tx_type = "interrupt"; 
+ break; 
+ default: 
+ tx_type = "unknown"; 
+ } 
+ 
+ spin_lock_irqsave(&ep->ep_lock, irq_flags); 
+ 
+ /* start a new transfer if there isn't one already in progress. */ 
+ if (ep->state.tx_pending == 0) { 
+ 
+ ep->state.tx_pending = 1; 
+ tx_size = maurb->urb->transfer_buffer_length; 
+ 
+ /* 
+ * Set this transfer as active transfer for endpoint - this 
+ * is how we will get active transfer info when we receive 
+ * transferRequests. 
+ */ 
+ ep->active_transfer = maurb; 
+ 
+ /* check to see if setup phase of control transfer */ 
+ if (mausb_control_xfer(maurb)) { 
+ ep->state.seq_number = 0; 
+ ep->state.earliest_unacked = 0; 
+ } 
+ 
+ spin_unlock_irqrestore(&ep->ep_lock, irq_flags); 
+ 
+ /* initiate transfer by direction */ 
+ if (dir_in) { 
+ mausb_dbg(mhcd, "%s: starting %s IN transfer for" 
+ " endpoint %u\n", __func__, tx_type, 
+ ep->ep_handle.ep_num); 
+ 
+ host_init_IN_transfer(&maurb->state, ep, maurb); 
+ 
+ } else { 
+ mausb_dbg(mhcd, "%s: starting %s OUT transfer for" 
+ " endpoint %u\n", __func__, tx_type, 
+ ep->ep_handle.ep_num); 
+ 
+ host_init_OUT_transfer(&maurb->state, ep, tx_size); 
+ host_OUT_generate_txReqs(&maurb->state, &ep->state, 
+ maurb); 
+ } 
+ spin_lock_irqsave(&ep->ep_lock, irq_flags); 
+ } 
+ spin_unlock_irqrestore(&ep->ep_lock, irq_flags); 
+ 
+ return -EINPROGRESS; 
+} 
+ 
+/** 
+ * Interface called to give a transferResp to the host for IN transfers. 
+ * 
+ * @pkt: transferResponse packet being received. 
+ * @context: Host endpoint associated with transfer. 
+ * 
+ * After an IN transfer is initiated, the host waits to receive transferResponse 
+ * packets from the device-side endpoint. When a transferResponse is received, 
+ * the host updates its transfer and endpoint states and copies the packet 
+ * payload into the maurb buffer associated with the tranfer. If the device 
+ * requests a transferAck packet, one is sent. 
+ */ 
+int complete_IN_transferRequest(struct ms_pkt *pkt, void *context) 
+{ 
+ int urb_stat; 
+ int length = 0; 
+ struct mausb_host_ep *ep; 
+ struct mausb_pkt *tx_resp; 
+ struct mausb_urb *maurb; 
+ struct mausb_transfer_state *tx_state; 
+ struct mausb_hcd *mhcd; 
+ 
+ if ((NULL == context) || (NULL == pkt)) { 
+ pr_err("%s: received NULL %s\n", __func__, 
+ context ? "packet" : "context"); 
+ return -EFAULT; 
+ } 
+ 
+ ep = (struct mausb_host_ep *) context; 
+ 
+ /* stop timeout timer */ 
+ del_timer(&ep->timer); 
+ 
+ tx_resp = mausb_pkt_from_ms_pkt_ep(pkt, ep, GFP_ATOMIC); 
+ list_add_tail(&tx_resp->pkt_list, &ep->resp_list); 
+ 
+ mhcd = mausb_host_ep_to_mahcd(ep); 
+ maurb = ep->active_transfer; 
+ 
+ if (NULL == maurb) { 
+ mausb_err(mhcd, "%s: no active transfer for endpoint at %p\n", 
+ __func__, ep); 
+ return -EINVAL; 
+ } 
+ 
+ tx_state = &maurb->state; 
+ length = host_IN_txResp_rcvd(&ep->state, tx_state, tx_resp); 
+ 
+ /* something went wrong in receiving the transferResp packet */ 
+ if (length < 0) { 
+ mausb_err(mhcd, "%s: returning error %i\n", __func__, length); 
+ return length; 
+ } 
+ 
+ /* look for end of transfer */ 
+ if (tx_state->eot_detected) { 
+ ep->state.tx_pending = 0; 
+ 
+ urb_stat = mausb_to_urb_status(tx_resp->data->common.pkt_status); 
+ if (NULL != maurb) 
+ mausb_unlink_giveback_urb(maurb, urb_stat); 
+ } 
+ 
+ /* if not end of transfer, set timer between packets */ 
+ else { 
+ mod_timer(&ep->timer, 
+ jiffies + msecs_to_jiffies(MAUSB_TRANSFER_KEEP_ALIVE)); 
+ } 
+ 
+ return length; 
+} 
+ 
+/** 
+ * Interface called to give the host a transferResp packet. 
+ * 
+ * @pkt: transferResponse packet being received. 
+ * @context: Host endpoint associated with transfer. 
+ * 
+ * For OUT transfers the host sends a series of transferRequest packets. A 
+ * transferResponse packet is only sent by the device when a transferAck packet 
+ * is requested by the host or the end of the transfer is reached. 
+ */ 
+int complete_OUT_transferRequest(struct ms_pkt *pkt, void *context) 
+{ 
+ int urb_stat; 
+ int ret = 0; 
+ struct mausb_host_ep *ep; 
+ struct mausb_pkt *tx_resp; 
+ struct mausb_urb *maurb; 
+ struct mausb_transfer_state *tx_state; 
+ struct mausb_hcd *mhcd; 
+ 
+ if ((NULL == context) || (NULL == pkt)) { 
+ pr_err("%s: received NULL %s\n", __func__, 
+ context ? "packet" : "context"); 
+ return -EFAULT; 
+ } 
+ 
+ ep = (struct mausb_host_ep *) context; 
+ 
+ /* stop timeout timer */ 
+ del_timer(&ep->timer); 
+ 
+ tx_resp = mausb_pkt_from_ms_pkt_ep(pkt, ep, GFP_ATOMIC); 
+ list_add_tail(&tx_resp->pkt_list, &ep->resp_list); 
+ 
+ mhcd = mausb_host_ep_to_mahcd(ep); 
+ maurb = ep->active_transfer; 
+ 
+ if (NULL == maurb) { 
+ mausb_err(mhcd, "%s: no active transfer for endpoint at %p\n", 
+ __func__, ep); 
+ return -EFAULT; 
+ } 
+ 
+ tx_state = &maurb->state; 
+ 
+ /* 
+ * Look for Retry flag in packet and resend requested packets 
+ * if we have them. Otherwise, pass packet on to receiving process. 
+ */ 
+ if (mausb_is_a_retry(ep, &ep->req_list, tx_resp) == false) 
+ ret = host_OUT_txResp_rcvd(&ep->state, tx_state, tx_resp); 
+ 
+ /* make sure we still have an active transfer */ 
+ if (!ep->active_transfer) { 
+ mausb_cleanup_ma_packets(ep, 
+ le32_to_cpu(tx_resp->data->seq_num), 
+ tx_resp->data->req_id); 
+ mausb_unlink_giveback_urb(maurb, -EINVAL); 
+ return ret; 
+ } 
+ 
+ /* handle end of transfer */ 
+ if (tx_state->eot_detected) { 
+ ep->state.tx_pending = 0; 
+ mausb_cleanup_ma_packets(ep, 
+ le32_to_cpu(tx_resp->data->seq_num), 
+ tx_resp->data->req_id); 
+ urb_stat = mausb_to_urb_status( 
+ tx_resp->data->common.pkt_status); 
+ mausb_unlink_giveback_urb(maurb, urb_stat); 
+ } 
+ 
+ return ret; 
+} 
+ 
+/* 
+ * Receives transferRequest packets for control endpoint (ep0). 
+ * 
+ * @pkt: transferResponse packet being received. 
+ * @context: Host endpoint associated with transfer. This should always be 
+ * control endpoint (ep0). 
+ * 
+ * Control transfers can be either IN or OUT. Transfer direction is parsed 
+ * from the urb associated with the transfer, then the appropriate completion 
+ * function is called. 
+ */ 
+int complete_control_transferRequest(struct ms_pkt *pkt, void *context) 
+{ 
+ int dir_in = 0; 
+ struct mausb_host_ep *ep; 
+ struct mausb_hcd *mhcd; 
+ 
+ if ((NULL == context) || (NULL == pkt)) { 
+ pr_err("%s: received NULL %s\n", __func__, 
+ context ? "packet" : "context"); 
+ return -EFAULT; 
+ } 
+ 
+ ep = (struct mausb_host_ep *) context; 
+ mhcd = mausb_host_ep_to_mahcd(ep); 
+ 
+ if (NULL == mhcd) { 
+ pr_err("%s: could not find MA USB HCD for endpoint" 
+ " at 0x%p\n", __func__, ep); 
+ return -EFAULT; 
+ } 
+ 
+ if (NULL == ep->active_transfer || NULL == ep->active_transfer->urb) { 
+ mausb_err(mhcd, "%s: no active transfer for endpoint at %p\n", 
+ __func__, ep); 
+ return -EFAULT; 
+ } 
+ 
+ /* stop timeout timer */ 
+ del_timer(&ep->timer); 
+ 
+ dir_in = usb_pipein(ep->active_transfer->urb->pipe); 
+ 
+ if (dir_in) 
+ complete_IN_transferRequest(pkt, context); 
+ else 
+ complete_OUT_transferRequest(pkt, context); 
+ 
+ return 0; 
+} 
+ 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/drivers/mausb_udc.c linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/drivers/mausb_udc.c
--- linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/drivers/mausb_udc.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/drivers/mausb_udc.c	2014-11-28 12:39:00.572447000 +0800
@@ -0,0 +1,1489 @@
+/* name: mausb_udc.c 
+ * description: Implements a USB device controller(UDC) for interfacing with 
+ * gadget drivers. The gadget driver uses this interface to return 
+ * descriptors and to implement configuration and data transfer 
+ * protocols with the pHCD. The UDC also allocates and initializes 
+ * endpoints to support gadget/pHCD interfacing. 
+ * 
+ * This file is provided under a dual BSD/GPLv2 license. When using or 
+ * redistributing this file, you may do so under either license. 
+ * 
+ * GPL LICENSE SUMMARY 
+ * 
+ * Copyright(c) 2014 Intel Corporation. 
+ * 
+ * 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. 
+ * 
+ * Contact Information: 
+ * Sean Stalley, sean.o.stalley [at] intel 
+ * Stephanie Wallick, stephanie.s.wallick [at] intel 
+ * 2111 NE 25th Avenue 
+ * Hillsboro, Oregon 97124 
+ * 
+ * BSD LICENSE 
+ * 
+ * Copyright(c) 2014 Intel Corporation. 
+ * 
+ * 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 of Intel Corporation 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/init.h> 
+#include <linux/module.h> 
+#include <linux/usb.h> 
+#include <linux/usb/hcd.h> 
+#include <linux/platform_device.h> 
+#include <linux/usb/ch11.h> 
+#include <linux/usb/gadget.h> 
+#include <linux/device.h> 
+#include <linux/usb/composite.h> 
+#include <linux/spinlock.h> 
+ 
+#include "mausb_udc.h" 
+#include "mausb_mgmt.h" 
+#include "mausb_mem.h" 
+#include "mausb_msapi.h" 
+#include "mausb_tx.h" 
+ 
+static const char ep0[] = "ep0"; 
+static const char *const ep_name[] = {ep0, "ep1", "ep2"}; 
+ 
+static struct platform_device udc_pdev; 
+ 
+void udc_dev_release(struct device *dev) 
+{ 
+ /* free any dynamically allocated structures here */ 
+} 
+ 
+static inline struct mausb_udc *gadget_to_udc(struct usb_gadget *gadget) 
+{ 
+ return container_of(gadget, struct mausb_udc, gadget); 
+} 
+ 
+static inline struct mausb_udc *gadget_dev_to_mausb_udc(struct device *dev) 
+{ 
+ return container_of(dev, struct mausb_udc, gadget.dev); 
+} 
+ 
+static inline struct mausb_request *usb_req_to_mausb_req( 
+ struct usb_request *req) 
+{ 
+ return container_of(req, struct mausb_request, req); 
+} 
+ 
+static inline struct mausb_udc *mausb_ma_dev_to_udc(struct ma_dev *ma_dev) 
+{ 
+ return container_of(ma_dev, struct mausb_udc, ma_dev); 
+} 
+ 
+/* 
+ * forward declarations 
+ */ 
+static int set_or_clear_gadget_feature(struct usb_ctrlrequest *ctrlreq, 
+ struct mausb_udc *udc, int set); 
+static int get_gadget_status(struct usb_ctrlrequest *ctrlreq, 
+ struct mausb_udc *udc); 
+ 
+/** 
+ * Finds a matching endpoint for a given address. 
+ */ 
+static struct usb_ep *get_ep(struct mausb_udc *udc, u8 address) 
+{ 
+ int i; 
+ struct usb_ep *ep; 
+ 
+ /* address is 0 (ignore direction bit flag) */ 
+ if ((address & ~USB_DIR_IN) == 0) 
+ return &udc->usb_ep[0].dev_ep; 
+ 
+ /* otherwise look for match */ 
+ for (i = 1; i < MAUDC_MAX_NUM_EP; i++) { 
+ 
+ ep = &udc->usb_ep[i].dev_ep; 
+ 
+ if (ep->address == address) 
+ return ep; 
+ } 
+ 
+ maudc_dbg(udc, "%s: no endpoint found for address 0x%x\n", 
+ __func__, address); 
+ 
+ return NULL; 
+} 
+ 
+/** 
+ * Called by gadget driver to enable endpoint. 
+ */ 
+static int mausb_ep_enable(struct usb_ep *ep, 
+ const struct usb_endpoint_descriptor *desc) 
+{ 
+ struct mausb_udc *udc = platform_get_drvdata(&udc_pdev); 
+ struct mausb_host_ep *ma_ep = mausb_find_ep_by_desc(desc, 
+ udc->mausb_dev); 
+ 
+ maudc_dbg(udc, "%s: enabling gadget endpoint %s\n", 
+ __func__, ep->name); 
+ 
+ /* ep0 is control endpoint, don't try and configure it */ 
+ if (ep->name == ep0) { 
+ maudc_err(udc, "%s: cannot configure ep0\n", __func__); 
+ return -EINVAL; 
+ } 
+ 
+ /* 
+ * Get maximum packet size from descriptor and set for ep. 
+ * Bits 0->10 of wMaxPacketSize = maximum packet size for HS and 
+ * FS devices maximum packet size for SS devices = 1024. 
+ */ 
+ ep->maxpacket = EP_MAX_PACKET; 
+ 
+ if (NULL != ma_ep) 
+ mausb_link_ma_ep_to_usb_ep(ma_ep, ep); 
+ 
+ return 0; 
+} 
+ 
+/** 
+ * Called by gadget driver to disable endpoint. 
+ */ 
+static int mausb_ep_disable(struct usb_ep *ep) 
+{ 
+ struct mausb_udc *udc = platform_get_drvdata(&udc_pdev); 
+ 
+ if (!ep) { 
+ maudc_dbg(udc, "%s: no endpoint\n", __func__); 
+ return -EINVAL; 
+ } 
+ 
+ maudc_dbg(udc, "%s: disabling gadget endpoint %s\n", 
+ __func__, ep->name); 
+ 
+ return 0; 
+} 
+ 
+/** 
+ * Called by gadget driver to allocate a request packet. 
+ */ 
+static struct usb_request *mausb_ep_alloc_request(struct usb_ep *ep, 
+ gfp_t mem_flags) 
+{ 
+ struct mausb_request *req; 
+ 
+ if (!ep) 
+ return NULL; 
+ 
+ req = kzalloc(sizeof(*req), mem_flags); 
+ if (!req) 
+ return NULL; 
+ 
+ INIT_LIST_HEAD(&req->usb_req_list); 
+ 
+ return &req->req; 
+} 
+ 
+/** 
+ * Called by gadget driver to free a request packet. 
+ */ 
+static void mausb_ep_free_request(struct usb_ep *ep, struct usb_request *req) 
+{ 
+ struct mausb_request *mreq; 
+ 
+ if (!ep || !req) 
+ return; 
+ 
+ mreq = usb_req_to_mausb_req(req); 
+ kfree(mreq); 
+} 
+ 
+/** 
+ * Called by gadget driver to queue a request. 
+ */ 
+static int mausb_ep_queue(struct usb_ep *ep, struct usb_request *req, 
+ gfp_t mem_flags) 
+{ 
+ struct mausb_udc *udc = platform_get_drvdata(&udc_pdev); 
+ struct mausb_request *ma_req; 
+ struct mausb_gadget_ep *gadget_ep; 
+ 
+ if (!ep) { 
+ maudc_err(udc, "%s: no endpoint\n", __func__); 
+ return -EINVAL; 
+ } 
+ 
+ if (!req) { 
+ maudc_err(udc, "%s: no USB request\n", __func__); 
+ return -EINVAL; 
+ } 
+ 
+ ma_req = usb_req_to_mausb_req(req); 
+ gadget_ep = usb_ep_to_mausb_gadget_ep(ep); 
+ 
+ req->status = -EINPROGRESS; 
+ req->actual = 0; 
+ 
+ maudc_dbg(udc, "%s: queueing request to ep %i at 0x%p with data at " 
+ "0x%p\n", __func__, usb_endpoint_num(ep->desc), ep, req->buf); 
+ 
+ list_add_tail(&ma_req->usb_req_list, &gadget_ep->usb_req_list); 
+ 
+ return 0; 
+} 
+ 
+/** 
+ * Called by gadget driver to dequeue a request. 
+ */ 
+static int mausb_ep_dequeue(struct usb_ep *ep, struct usb_request *req) 
+{ 
+ struct mausb_udc *udc = platform_get_drvdata(&udc_pdev); 
+ struct mausb_request *ma_req; 
+ 
+ if (!ep) { 
+ maudc_err(udc, "%s: no endpoint\n", __func__); 
+ return -EINVAL; 
+ } 
+ 
+ if (!req) { 
+ maudc_err(udc, "%s: no USB request\n", __func__); 
+ return -EINVAL; 
+ } 
+ 
+ ma_req = usb_req_to_mausb_req(req); 
+ 
+ list_del(&ma_req->usb_req_list); 
+ 
+ maudc_dbg(udc, "%s: dequeueing request\n", __func__); 
+ 
+ return 0; 
+} 
+ 
+/** 
+ * Halts or clears a halt of an endpoint. 
+ */ 
+static int mausb_ep_set_halt(struct usb_ep *ep, int value) 
+{ 
+ struct mausb_udc *udc = platform_get_drvdata(&udc_pdev); 
+ struct mausb_host_ep *ma_ep = mausb_find_ep_dev(ep, udc->mausb_dev); 
+ 
+ if (NULL == ma_ep) { 
+ maudc_err(udc, "%s: no MA USB endpoint\n", __func__); 
+ return -EINVAL; 
+ } 
+ 
+ /* probably don't want to halt default control ep */ 
+ if (ma_ep->dev_ep->name == ep0) { 
+ maudc_err(udc, "%s: cannot halt ep0!\n", __func__); 
+ return -EINVAL; 
+ } 
+ 
+ if (value) { 
+ maudc_dbg(udc, "%s: halting ep\n", __func__); 
+ ma_ep->halted = 1; 
+ } 
+ 
+ else { 
+ maudc_dbg(udc, "%s: clearing ep halt\n", __func__); 
+ ma_ep->halted = 0; 
+ } 
+ 
+ return 0; 
+} 
+ 
+/** 
+ * Wedges an endpoint; wedge causes request to clear halt from host to be 
+ * ignored. 
+ */ 
+static int mausb_ep_set_wedge(struct usb_ep *ep) 
+{ 
+ struct mausb_udc *udc = platform_get_drvdata(&udc_pdev); 
+ struct mausb_host_ep *ma_ep = mausb_find_ep_dev(ep, udc->mausb_dev); 
+ 
+ if (NULL == ma_ep) { 
+ maudc_err(udc, "%s: no MA USB endpoint\n", __func__); 
+ return -EINVAL; 
+ } 
+ 
+ /* wedging default control ep is probably bad */ 
+ if (ma_ep->dev_ep->name == ep0) { 
+ maudc_dbg(udc, "%s: cannot wedge ep0\n", __func__); 
+ return -EINVAL; 
+ } 
+ 
+ ma_ep->halted = 1; 
+ ma_ep->wedged = 1; 
+ 
+ return 0; 
+} 
+ 
+static struct usb_ep_ops mausb_ep_ops = { 
+ .enable = mausb_ep_enable, 
+ .disable = mausb_ep_disable, 
+ .alloc_request = mausb_ep_alloc_request, 
+ .free_request = mausb_ep_free_request, 
+ .queue = mausb_ep_queue, 
+ .dequeue = mausb_ep_dequeue, 
+ .set_halt = mausb_ep_set_halt, 
+ .set_wedge = mausb_ep_set_wedge 
+}; 
+ 
+/*---------------------- transfer operations ------------------------------*/ 
+ 
+/** 
+ * Handles control requests from usb core. Returns 0 if request is fully 
+ * handled, otherwise returns the length of the transfer 
+ */ 
+static int handle_ma_control_request(struct mausb_host_ep *ep, 
+ struct usb_ctrlrequest *ctrlreq) 
+{ 
+ int ret = 0; 
+ struct mausb_udc *udc = platform_get_drvdata(&udc_pdev); 
+ 
+ if (!ctrlreq) { 
+ maudc_err(udc, "%s: no control request\n", __func__); 
+ return -EINVAL; 
+ } 
+ 
+ /* 
+ * UDC handles set/clear feature, get status, and set address 
+ * requests, anything else is passed to gadget driver. 
+ */ 
+ switch (ctrlreq->bRequest) { 
+ case USB_REQ_CLEAR_FEATURE: 
+ maudc_dbg(udc, "USB_REQ: clearing feature\n"); 
+ ret = set_or_clear_gadget_feature(ctrlreq, udc, 0); 
+ break; 
+ 
+ case USB_REQ_GET_STATUS: 
+ maudc_dbg(udc, "USB_REQ: getting status\n"); 
+ ret = get_gadget_status(ctrlreq, udc); 
+ break; 
+ 
+ case USB_REQ_SET_FEATURE: 
+ maudc_dbg(udc, "USB_REQ: setting feature\n"); 
+ ret = set_or_clear_gadget_feature(ctrlreq, udc, 1); 
+ break; 
+ 
+ default: /* pass the request to the gadget driver */ 
+ maudc_dbg(udc, "USB_REQ: forwarding REQ #%i to gadget driver\n", 
+ ctrlreq->bRequest); 
+ if (NULL != udc->driver) 
+ ret = udc->driver->setup(&udc->gadget, ctrlreq); 
+ else 
+ maudc_err(udc, "gadget driver not found\n"); 
+ 
+ if (ret >= 0) 
+ ret = ctrlreq->wLength; 
+ break; 
+ } 
+ 
+ return ret; 
+} 
+ 
+/** 
+ * Transfers contents of request and endpoint buffers. 
+ */ 
+int do_ma_transfer(struct mausb_host_ep *ep, struct mausb_pkt *tx_req, 
+ bool dir_in) 
+{ 
+ int i = 0; 
+ int out_copy_length = 0; 
+ int ret, host_len, device_len; 
+ int status = -EINPROGRESS; 
+ int length = 0; 
+ struct mausb_transfer_state *tx_state = &ep->active_transfer->state; 
+ struct mausb_request *req, *next; 
+ struct mausb_udc *udc = platform_get_drvdata(&udc_pdev); 
+ void *epbuf, *rbuf; 
+ 
+ /* look for setup data */ 
+ if (tx_req->setup) 
+ ret = handle_ma_control_request(ep, tx_req->setup); 
+ 
+ if (NULL == ep->usb_req_list) 
+ return -ENOTCONN; 
+ 
+ if (list_empty(ep->usb_req_list) && !in_interrupt()) { 
+ maudc_dbg(udc, "wait gadget function driver submit request\n"); 
+ while (list_empty(ep->usb_req_list) && 
+ i <= MAUSB_GADGET_TIMEOUT) { 
+ msleep(1); 
+ i++; 
+ } 
+ } 
+ if (i > MAUSB_GADGET_TIMEOUT) { 
+ maudc_dbg(udc, "Wait gadget request time out\n"); 
+ return -ETIMEDOUT; 
+ } 
+ 
+ loop_request_queue: 
+ /* take care of each request in request queue */ 
+ list_for_each_entry_safe(req, next, ep->usb_req_list, usb_req_list) { 
+ 
+ if (dir_in) 
+ host_len = tx_state->rem_size - ep->actual_length; 
+ else 
+ host_len = tx_req->buffer_length - out_copy_length; 
+ device_len = req->req.length - req->req.actual; 
+ length = min(host_len, device_len); 
+ 
+ /* there is something to transfer so do transfer */ 
+ if (length > 0) { 
+ 
+ rbuf = req->req.buf + req->req.actual; 
+ 
+ /* 
+ * If IN transfer, copy req buffer contents into 
+ * ep buffer. Vice versa for OUT transfer. 
+ */ 
+ if (dir_in) { 
+ epbuf = ep->buffer + ep->actual_length; 
+ if (epbuf) 
+ memcpy(epbuf, rbuf, length); 
+ else 
+ maudc_err(udc, "%s: no ep buffer\n", 
+ __func__); 
+ } else { 
+ /* 
+ * For bulk OUT, we can't use ep->actual_length 
+ * as indicator because ep->buffer for every 
+ * transfer request is only "rx_buf_size" bytes 
+ * length. 
+ */ 
+ epbuf = ep->buffer + out_copy_length; 
+ memcpy(rbuf, epbuf, length); 
+ out_copy_length += length; 
+ } 
+ ep->actual_length += length; 
+ req->req.actual += length; 
+ } 
+ /* zero length packet ends a read */ 
+ else { 
+ req->req.status = 0; 
+ status = 0; 
+ } 
+ 
+ /* 
+ * A transfer usually ends when buffer contents are completely 
+ * transferred. But, look out for for the zero packet transfer 
+ * flag. If flag is set, bulk OUT transfers need to wait for 
+ * zero length packet (short packet) for completion. 
+ */ 
+ if ((req->req.length == req->req.actual) || 
+ /* bulk IN short packet */ 
+ (dir_in && (req->req.actual % ep->dev_ep->maxpacket)) || 
+ /* bulk OUT transfer all data requested by host urb*/ 
+ (!dir_in && ep->active_transfer->transfer_size 
+ == ep->actual_length) || 
+ /* bulk OUT last request */ 
+ (!dir_in && req->req.zero)) { 
+ req->req.status = 0; 
+ /* device completion */ 
+ list_del_init(&req->usb_req_list); 
+ req->req.complete(ep->dev_ep, &req->req); 
+ } 
+ 
+ if (tx_state->rem_size == 0) 
+ status = 0; 
+ 
+ /* 
+ * Host completion - end when nothing left to read/write, 
+ * otherwise keep going through queue. 
+ */ 
+ if (status != -EINPROGRESS) 
+ break; 
+ /* bulk IN/OUT transfers last request serves for one host urb */ 
+ if (tx_state->rem_size == req->req.actual) { 
+ maudc_dbg(udc, "bulk IN/OUT last request return\n"); 
+ break; 
+ } 
+ /* bulk IN short packet */ 
+ if (dir_in && (req->req.actual % ep->dev_ep->maxpacket)) { 
+ maudc_dbg(udc, "bulk IN short packet return\n"); 
+ break; 
+ } 
+ /* 
+ * Bulk OUT transfer contains multiple bulk OUT MA requests. 
+ * So for bulk out MA request just return to serve subsequent 
+ * bulk out MA request. 
+ */ 
+ if (!dir_in && host_len == length) { 
+ maudc_dbg(udc, "normal bulk OUT MA request return\n"); 
+ break; 
+ } 
+ /* 
+ * Gadget driver should transfer more data to 
+ * serve bulk IN transfer, then wait for more requests. 
+ */ 
+ if (dir_in && (req->req.actual % ep->dev_ep->maxpacket == 0) && 
+ (tx_state->rem_size - ep->actual_length > 0) 
+ && !req->req.zero) { 
+ if (list_empty(ep->usb_req_list)) { 
+ maudc_dbg(udc, "bulk IN: gadget request queue" 
+ " is empty - waiting . . .\n"); 
+ while (list_empty(ep->usb_req_list)) 
+ msleep(1); 
+ } 
+ goto loop_request_queue; 
+ } 
+ /* 
+ * Doesn't copy all data in MA USB bulk OUT request. 
+ * Wait for additional gadget requests 
+ * to serve this MA USB bulk OUT request. 
+ */ 
+ if (!dir_in && (host_len > length)) { 
+ if (list_empty(ep->usb_req_list)) { 
+ maudc_dbg(udc, "bulk OUT: gadget request" 
+ " is queue empty - waiting . . .\n"); 
+ while (list_empty(ep->usb_req_list)) 
+ msleep(1); 
+ } 
+ goto loop_request_queue; 
+ } 
+ } 
+ 
+ return ep->actual_length; 
+} 
+ 
+ 
+/*------------------------- gadget operations -------------------------*/ 
+ 
+/** 
+ * Handles control request to get device status. 
+ */ 
+static int get_gadget_status(struct usb_ctrlrequest *ctrlreq, 
+ struct mausb_udc *udc) 
+{ 
+ int ret = 0; 
+ char *buf; 
+ unsigned int address = le16_to_cpu(ctrlreq->wIndex); 
+ struct usb_ep *usb_ep = get_ep(udc, address); 
+ struct mausb_host_ep *ma_ep = mausb_find_ep_dev(usb_ep, 
+ udc->mausb_dev); 
+ 
+ if (!ma_ep) { 
+ maudc_err(udc, "%s: cannot find endpoint\n", __func__); 
+ return -EINVAL; 
+ } 
+ 
+ buf = (char *)ma_ep->buffer; 
+ 
+ maudc_dbg(udc, "%s: responding to request type %i\n", 
+ __func__, ctrlreq->bRequestType); 
+ 
+ /* requesting device status */ 
+ switch (ctrlreq->bRequestType) { 
+ case DEV_IN_REQ: 
+ buf[0] = udc->dev_status; 
+ ma_ep->actual_length = 1; 
+ break; 
+ 
+ /* requesting an endpoint status */ 
+ case EP_IN_REQ: 
+ buf[0] = ma_ep->halted; 
+ ma_ep->actual_length = 1; 
+ break; 
+ 
+ /* requesting interface status */ 
+ case INTF_IN_REQ: 
+ buf[0] = 0; 
+ break; 
+ 
+ default: 
+ maudc_dbg(udc, "%s: invalid request type %i\n", 
+ __func__, ctrlreq->bRequestType); 
+ ret = -EOPNOTSUPP; 
+ break; 
+ } 
+ 
+ return ret; 
+} 
+ 
+/** 
+ * Handles control request to set a gadget device feature. 
+ */ 
+static int set_or_clear_gadget_feature(struct usb_ctrlrequest *ctrlreq, 
+ struct mausb_udc *udc, int set) 
+{ 
+ int ret = 0; 
+ unsigned int address = le16_to_cpu(ctrlreq->wIndex); 
+ struct usb_ep *usb_ep = get_ep(udc, address); 
+ struct mausb_host_ep *ma_ep = mausb_find_ep_dev(usb_ep, 
+ udc->mausb_dev); 
+ 
+ if (ctrlreq->bRequestType == EP_REQ) { 
+ 
+ if (!ma_ep) 
+ ret = -EINVAL; 
+ else if (ma_ep->dev_ep->name == udc->gadget.ep0->name) { 
+ maudc_err(udc, "%s: cannot halt ep0!\n", __func__); 
+ ret = -EINVAL; 
+ } else { 
+ ma_ep->halted = set; 
+ maudc_dbg(udc, "%s: %s halt %s\n", __func__, 
+ ma_ep->dev_ep->name, set ? "set" : "cleared"); 
+ } 
+ } 
+ 
+ return ret; 
+} 
+ 
+/** 
+ * Handles incoming management packets. Used to pass an MA USB management 
+ * packet to the device. 
+ */ 
+static int maudc_transfer_mgmt_packet(struct ms_pkt *ms_pkt, void *context) 
+{ 
+ int ret; 
+ struct mausb_pkt *pkt; 
+ struct mausb_udc *udc = platform_get_drvdata(&udc_pdev); 
+ struct mausb_mgmt *mgmt; 
+ 
+ if ((NULL == context) || (NULL == ms_pkt)) { 
+ maudc_err(udc, "%s: received NULL %s\n", __func__, 
+ context ? "packet" : "context"); 
+ return -EFAULT; 
+ } 
+ 
+ mgmt = (struct mausb_mgmt *) context; 
+ 
+ pkt = mausb_pkt_from_ms_pkt(ms_pkt, 
+ udc->ma_dev.ms_driver->ops->pkt_destructor, GFP_ATOMIC); 
+ 
+ maudc_dbg(udc, "%s: received %s packet\n", __func__, 
+ mausb_type_to_string(pkt->common->pkt_type)); 
+ 
+ ret = mausb_rx_mgmt(pkt, mgmt); 
+ 
+ return ret; 
+} 
+ 
+/** 
+ * Suspends gadget..Called when a MAUSBDeviceSleepReq management packet is 
+ * received. 
+ */ 
+static void mausb_device_suspend(void) 
+{ 
+ struct mausb_udc *udc = platform_get_drvdata(&udc_pdev); 
+ 
+ if (udc->driver) 
+ udc->driver->suspend(&udc->gadget); 
+} 
+ 
+/** 
+ * Resumes gadget. Called by mausb_bus_resume in hcd to resume a connected 
+ * device. 
+ */ 
+static void mausb_device_resume(void) 
+{ 
+ struct mausb_udc *udc = platform_get_drvdata(&udc_pdev); 
+ 
+ if (udc->driver) 
+ udc->driver->resume(&udc->gadget); 
+} 
+ 
+/** 
+ * Manages USB device connection to host. Called for connect and disconnect 
+ * events. 
+ */ 
+static int mausb_udc_pullup(struct usb_gadget *gadget, int is_on) 
+{ 
+ struct mausb_udc *udc = gadget_to_udc(gadget); 
+ 
+ udc->usb_ep[0].dev_ep.maxpacket = 64; 
+ udc->gadget.speed = udc->driver->max_speed; 
+ udc->pullup = is_on; 
+ 
+ return 0; 
+} 
+ 
+/** 
+ * Assigns an MA USB ep handle to the given endpoint. 
+ */ 
+static void maudc_assign_ep_handle(struct mausb_host_ep *ma_ep, 
+ struct usb_endpoint_descriptor *ep_des) 
+{ 
+ struct mausb_ep_handle *handle = &ma_ep->ep_handle; 
+ 
+ handle->dir = usb_endpoint_dir_in(ep_des) ? 1 : 0; 
+ handle->ep_num = usb_endpoint_num(ep_des); 
+ handle->dev_addr = MAUDC_DEV_ADDR; 
+ handle->bus_num = MAUSB_VIRTUAL_BUS_NUM; 
+ 
+ ma_ep->ep_handle_state = MAUSB_EP_HANDLE_ACTIVE; 
+} 
+ 
+/** 
+ * Adds a media-agnostic endpoint datastructure to the UDC for the given 
+ * endpoint. 
+ */ 
+static int maudc_add_ma_ep(struct usb_endpoint_descriptor *ep_des, 
+ struct mausb_dev *mausb_dev, struct mausb_host_ep **mausb_ep) 
+{ 
+ int ret = -EINVAL; 
+ struct mausb_host_ep *ma_ep; 
+ struct mausb_ms_drv *drv = mausb_dev->ma_dev->ms_driver; 
+ struct mausb_udc *udc = platform_get_drvdata(&udc_pdev); 
+ struct usb_ep *usb_ep = get_ep(udc, ep_des->bEndpointAddress); 
+ unsigned long irq_flags; 
+ int (*transfer_pkt)(struct ms_pkt *pkt, void *context); 
+ 
+ if (USB_ENDPOINT_XFER_CONTROL == usb_endpoint_type(ep_des)) { 
+ 
+ maudc_dbg(udc, "%s: adding control endpoint %i...\n", 
+ __func__, usb_endpoint_num(ep_des)); 
+ transfer_pkt = &receive_ma_packet_control; 
+ 
+ } else if (usb_endpoint_dir_in(ep_des)) { 
+ maudc_dbg(udc, "%s: adding IN endpoint %i...\n", 
+ __func__, usb_endpoint_num(ep_des)); 
+ transfer_pkt = &receive_ma_packet_IN; 
+ 
+ } else if (usb_endpoint_dir_out(ep_des)) { 
+ maudc_dbg(udc, "%s: adding OUT endpoint %i...\n", 
+ __func__, usb_endpoint_num(ep_des)); 
+ transfer_pkt = &receive_ma_packet_OUT; 
+ 
+ } else { 
+ maudc_dbg(udc, "%s: unknown endpoint type\n", __func__); 
+ return -EINVAL; 
+ } 
+ 
+ mausb_internal_add_ep(mausb_dev, NULL, usb_ep, &ma_ep, 
+ &device_transfer_timeout, GFP_ATOMIC); 
+ 
+ if (NULL == ma_ep) 
+ return -ENOMEM; 
+ 
+ maudc_dbg(udc, "%s: added endpoint at 0x%p\n", __func__, ma_ep); 
+ 
+ spin_lock_irqsave(&ma_ep->ep_lock, irq_flags); 
+ 
+ maudc_assign_ep_handle(ma_ep, ep_des); 
+ ret = mausb_add_data_channel(drv, ma_ep, transfer_pkt); 
+ 
+ ma_ep->gadget = mausb_dev->gadget; 
+ 
+ /* 
+ * Note: The UDC uses a single MA URB to track the transfer 
+ * State variables for the active transfer. 
+ */ 
+ ma_ep->active_transfer = mausb_alloc_maurb(ma_ep, GFP_ATOMIC); 
+ 
+ if (NULL != mausb_ep) 
+ *mausb_ep = ma_ep; 
+ 
+ spin_unlock_irqrestore(&ma_ep->ep_lock, irq_flags); 
+ 
+ return ret; 
+} 
+ 
+/** 
+ * Registers a media specific driver with the media agnostic driver. 
+ */ 
+struct mausb_ma_drv *maudc_register_ms_driver(struct mausb_ms_drv *drv) 
+{ 
+ struct mausb_udc *udc = platform_get_drvdata(&udc_pdev); 
+ unsigned long irq_flags; 
+ 
+ spin_lock_irqsave(&udc->udc_lock, irq_flags); 
+ udc->ma_dev.ms_driver = drv; 
+ spin_unlock_irqrestore(&udc->udc_lock, irq_flags); 
+ 
+ /* open the management channel */ 
+ maudc_dbg(udc, "%s: adding Managment channel...\n", __func__); 
+ mausb_add_mgmt_channel(&udc->ma_dev.mgmt, drv, 
+ &maudc_transfer_mgmt_packet, &mausb_mgmt_pkt_sent); 
+ 
+ return &udc->ma_dev.ma_drv; 
+} 
+EXPORT_SYMBOL(maudc_register_ms_driver); 
+ 
+int check_for_device(int dont_use) 
+{ 
+ struct mausb_udc *udc = platform_get_drvdata(&udc_pdev); 
+ 
+ if (udc->driver != NULL) 
+ return 1; 
+ 
+ return 0; 
+} 
+ 
+static int mausb_udc_start(struct usb_gadget *gadget, 
+ struct usb_gadget_driver *driver) 
+{ 
+ struct mausb_udc *udc = gadget_to_udc(gadget); 
+ 
+ maudc_dbg(udc, "%s: binding gadget '%s' driver\n", 
+ __func__, driver->driver.name); 
+ 
+ udc->driver = driver; 
+ 
+ return 0; 
+} 
+ 
+static int mausb_udc_stop(struct usb_gadget *gadget, 
+ struct usb_gadget_driver *driver) 
+{ 
+ struct mausb_udc *udc = gadget_to_udc(gadget); 
+ 
+ maudc_dbg(udc, "%s: stopping udc\n", __func__); 
+ 
+ udc->driver = NULL; 
+ 
+ return 0; 
+} 
+ 
+/** 
+ * API to UDC operations that do not involve endpoints or i/o. 
+ */ 
+static struct usb_gadget_ops mudc_ops = { 
+ .pullup = &mausb_udc_pullup, 
+ .udc_start = &mausb_udc_start, 
+ .udc_stop = &mausb_udc_stop 
+}; 
+ 
+/** 
+ * Appends a Capabilities Descriptor to the end of a CapResp packet. 
+ * 
+ * @resp: CapResp to that will carry descriptor. 
+ * @type: Descriptor type to add. 
+ * Note: make sure to use values from MA USB Spec, Table 14. 
+ * @offset: Total length of other Device Capability Descriptors 
+ * in resp. 
+ * 
+ * Returns length of added descriptor. 
+ */ 
+static int add_cap_desc(struct mausb_mgmt_pkt *resp, int type, int offset) 
+{ 
+ int ret = 0; 
+ int ttl_offset; 
+ struct mausb_dev_cap_desc *desc; 
+ struct mausb_udc *udc = platform_get_drvdata(&udc_pdev); 
+ 
+ ttl_offset = MAUSB_PKT_HEADER_SIZE + 
+ sizeof(struct mausb_CapResp_flds) + offset; 
+ desc = cap_desc_ptr_increment(resp, ttl_offset); 
+ 
+ switch (type) { 
+ case MAUSB_DEV_CAP_SPEED: 
+ desc->length = MAUSB_DEV_CAP_SPEED_LENGTH; 
+ desc->cap_type = MAUSB_DEV_CAP_SPEED; 
+ desc->speed.speed = MAUSB_DEV_CAP_SPEED_SUPER; 
+ /* TODO: assign speed fields meaningful values */ 
+ desc->speed.lse = 1; 
+ desc->speed.st = 2; 
+ desc->speed.lane_count = 3; 
+ desc->speed.link_protocol = 3; 
+ desc->speed.lsm = 234; 
+ ret = desc->length; 
+ break; 
+ case MAUSB_DEV_CAP_POUT: 
+ break; 
+ case MAUSB_DEV_CAP_ISO: 
+ break; 
+ case MAUSB_DEV_CAP_SYNC: 
+ break; 
+ case MAUSB_DEV_CAP_CONT_ID: 
+ break; 
+ case MAUSB_DEV_CAP_LINK_SLEEP: 
+ desc->length = MAUSB_DEV_CAP_LINK_SLEEP_LENGTH; 
+ desc->cap_type = MAUSB_DEV_CAP_LINK_SLEEP; 
+ desc->link_sleep.link_sleep_cap = 0; 
+ ret = desc->length; 
+ break; 
+ default: 
+ maudc_err(udc, "%s: invalid Device Capability Type %i\n", 
+ __func__, type); 
+ break; 
+ } 
+ 
+ return ret; 
+} 
+ 
+/** 
+ * Finds an MA USB endpoint descriptor inside of an endpoint handle response. 
+ */ 
+static void maudc_fill_ma_ep_desc(struct mausb_ep_des *ma_ep_des, 
+ struct usb_endpoint_descriptor *ep_des, 
+ struct mausb_host_ep *ma_ep) 
+{ 
+ ma_ep_des->ep_handle.handle = ma_ep->ep_handle.handle; 
+ ma_ep_des->dir = usb_endpoint_dir_in(ep_des) ? 1 : 0; 
+ ma_ep_des->iso = usb_endpoint_xfer_isoc(ep_des) ? 1 : 0; 
+ ma_ep_des->l_man = 0; 
+ ma_ep_des->valid = 0; 
+ ma_ep_des->rsvd_0 = 0; 
+ 
+ if ((usb_endpoint_dir_out(ep_des) && !usb_endpoint_xfer_isoc(ep_des)) 
+ || usb_endpoint_xfer_control(ep_des)) { 
+ ma_ep_des->ccu = 1; 
+ } else 
+ ma_ep_des->ccu = 0; 
+ 
+ ma_ep_des->rsvd_1 = 0; 
+ 
+ if (usb_endpoint_dir_out(ep_des) || usb_endpoint_xfer_control(ep_des)) 
+ ma_ep_des->buffer_size = ma_ep->state.rx_buf_size; 
+ else 
+ ma_ep_des->buffer_size = 0; 
+ 
+ if (usb_endpoint_xfer_isoc(ep_des)) { 
+ /* TODO: iso transfers */ 
+ /* ma_ep_des->iso_prog_dly = 0; */ 
+ /* ma_ep_des->iso_resp_dly = 0; */ 
+ } else { 
+ ma_ep_des->iso_prog_dly = 0; 
+ ma_ep_des->iso_resp_dly = 0; 
+ } 
+} 
+ 
+/** 
+ * Handles incoming EPHandleReq packets and fills EPHandleResp fields. 
+ */ 
+static enum mausb_pkt_status maudc_handle_ep_req(struct mausb_dev *mausb_dev, 
+ struct mausb_EPHandleReq_flds *req, 
+ struct mausb_EPHandleResp_flds *resp) 
+{ 
+ int i; 
+ enum mausb_pkt_status status = UNSUCCESSFUL; 
+ struct mausb_udc *udc = platform_get_drvdata(&udc_pdev); 
+ struct usb_endpoint_descriptor *ep_des; 
+ struct usb_ep *usb_ep; 
+ struct mausb_host_ep *ma_ep; 
+ 
+ resp->num_ep_des = req->num_ep_des; 
+ 
+ /* TODO: Sanity check; make sure we dont look past end of packet */ 
+ for (i = 0; i < req->num_ep_des; ++i) { 
+ 
+ ep_des = mausb_ep_handle_req_get_ep_des(req, i); 
+ 
+ if (NULL != ep_des) { 
+ 
+ ma_ep = mausb_find_ep_by_address( 
+ ep_des->bEndpointAddress, mausb_dev); 
+ 
+ if (NULL != ma_ep) { 
+ maudc_warn(udc, "%s: endpoint already exists" 
+ " resetting . . .\n", __func__); 
+ mausb_internal_drop_ep(ma_ep); 
+ } 
+ 
+ maudc_add_ma_ep(ep_des, mausb_dev, &ma_ep); 
+ 
+ if (NULL == ma_ep) { 
+ maudc_err(udc, "%s: failed to add endpoint" 
+ " for entry %i\n", __func__, i); 
+ } 
+ 
+ maudc_fill_ma_ep_desc(&resp->ep_des[i], ep_des, ma_ep); 
+ 
+ usb_ep = get_ep(udc, ep_des->bEndpointAddress); 
+ 
+ if (NULL != usb_ep) 
+ mausb_link_ma_ep_to_usb_ep(ma_ep, usb_ep); 
+ 
+ /* Per spec, if at least 1 endpoint assignment 
+ * is sucessful, the packet returns success. 
+ */ 
+ status = SUCCESS; 
+ } 
+ } 
+ 
+ return status; 
+} 
+ 
+/** 
+ * Handles incoming EPHandleDeleteReq packets and fills EPHandleDeleteResp 
+ * fields. 
+ */ 
+static enum mausb_pkt_status maudc_handle_ep_del_req( 
+ struct mausb_dev *mausb_dev, 
+ struct mausb_EPHandleDelete_flds *req, 
+ struct mausb_EPHandleDelete_flds *resp) 
+{ 
+ int i; 
+ int ret = 0; 
+ enum mausb_pkt_status status = UNSUCCESSFUL; 
+ struct mausb_udc *udc = platform_get_drvdata(&udc_pdev); 
+ struct mausb_host_ep *ma_ep = NULL; 
+ struct mausb_ep_handle *req_handle; 
+ 
+ resp->num_ep = 0; 
+ 
+ /* TODO: Sanity check; make sure we dont look past end of packet */ 
+ for (i = 0; i < req->num_ep; ++i) { 
+ req_handle = &req->ep_handle[i]; 
+ 
+ ma_ep = mausb_find_ep_by_handle(req_handle, mausb_dev); 
+ 
+ ret = mausb_internal_drop_ep(ma_ep); 
+ 
+ if (0 <= ret) { 
+ /* 
+ * per spec, the packet returns sucess if it can 
+ * delete at least 1 endpoint 
+ */ 
+ status = SUCCESS; 
+ 
+ } else { 
+ resp->ep_handle[resp->num_ep].handle 
+ = req_handle->handle; 
+ resp->num_ep++; 
+ 
+ maudc_err(udc, "%s: could not delete endpoint with" 
+ " handle %x\n", __func__, req_handle->handle); 
+ } 
+ } 
+ 
+ return status; 
+} 
+ 
+/** 
+ * Inactivate endpoints in EPInactivateReq packet and fill 
+ * EPInactivateResp fields. 
+ */ 
+static enum mausb_pkt_status maudc_handle_ep_inactivate( 
+ struct mausb_EPInactivateReq_flds *req, 
+ struct mausb_EPInactivateResp_flds *resp, 
+ struct mausb_dev *dev) 
+{ 
+ int i = 0; 
+ int failures = 0; 
+ enum mausb_pkt_status status = SUCCESS; 
+ struct mausb_host_ep *ma_ep = NULL; 
+ struct mausb_ep_handle *req_handle; 
+ 
+ for (i = 0; i < req->num_ep_handles; ++i) { 
+ req_handle = &req->ep_handle[i]; 
+ ma_ep = mausb_find_ep_by_handle(req_handle, dev); 
+ 
+ if (!ma_ep) { 
+ resp->ep_handle[failures] = *req_handle; 
+ status = UNSUCCESSFUL; 
+ failures++; 
+ } else 
+ ma_ep->ep_handle_state = MAUSB_EP_HANDLE_INACTIVE; 
+ } 
+ 
+ resp->num_ep_with_error = failures; 
+ 
+ return status; 
+} 
+ 
+/** 
+ * This function handles management requests to the UDC. It parses the packet 
+ * and makes the necessary function calls into the system. 
+ * 
+ * @req: The incoming request to handle. 
+ * @resp: The response packet to send out. 
+ * @mgmt: The MA USB management structure associated with transfer. 
+ * 
+ * Note: this function only fills the packet type, status and 
+ * request-specific data-fields. The remainder of the fields are set by 
+ * mausb_rx_mgmt_req. 
+ */ 
+static int udc_mgmt_req_switch(struct mausb_mgmt_pkt *req, 
+ struct mausb_mgmt_pkt *resp, struct mausb_mgmt *mgmt) 
+{ 
+ int ret = -EINVAL; 
+ int desc_count = 0; 
+ int offset = 0; 
+ struct ma_dev *ma_dev = mausb_mgmt_to_ma_dev(mgmt); 
+ struct mausb_udc *udc = mausb_ma_dev_to_udc(ma_dev); 
+ 
+ /* always set the device handle */ 
+ req->common.dev_handle = udc->mausb_dev->dev_handle; 
+ 
+ switch (req->common.pkt_type) { 
+ 
+ case CapReq: 
+ /* non-hub devices require a Speed Capability Descriptor */ 
+ ret = add_cap_desc(resp, MAUSB_DEV_CAP_SPEED, offset); 
+ if (ret <= 0) { 
+ maudc_err(udc, "%s: could not add speed capability " 
+ "descriptor\n", __func__); 
+ } else { 
+ desc_count++; 
+ offset += ret; 
+ } 
+ 
+ ret = add_cap_desc(resp, MAUSB_DEV_CAP_LINK_SLEEP, offset); 
+ if (ret <= 0) { 
+ maudc_err(udc, "%s; could not add link sleep" 
+ " capability descriptor\n", __func__); 
+ } else { 
+ desc_count++; 
+ offset += ret; 
+ } 
+ 
+ /* 
+ * TODO: if want to add more device cap descriptors, this would 
+ * be a good place to do it. 
+ */ 
+ 
+ resp->common.pkt_type = CapResp; 
+ resp->common.pkt_status = NO_ERROR; 
+ resp->cap_resp.num_ep = CAP_MAX_EP_NUM; 
+ resp->cap_resp.num_dev = CAP_MAX_DEV_NUM; 
+ resp->cap_resp.num_stream = EP_MAX_STREAMS; 
+ resp->cap_resp.dev_type = CAP_DEV_TYPE; 
+ resp->cap_resp.desc_count = desc_count; 
+ resp->cap_resp.desc_length = offset; 
+ resp->cap_resp.max_tx_reqs = CAP_MAX_TX_REQS; 
+ resp->cap_resp.max_mgmt_reqs = CAP_MAX_MGMT_REQS; 
+ 
+ ret = 0; 
+ break; 
+ case USBDevHandleReq: 
+ udc->mausb_dev->dev_handle = MAUDC_DEV_HANDLE; 
+ 
+ resp->common.pkt_type = USBDevHandleResp; 
+ resp->common.pkt_status = NO_ERROR; 
+ resp->usb_dev_handle_resp = MAUDC_DEV_HANDLE; 
+ 
+ ret = 0; 
+ break; 
+ case EPHandleReq: 
+ resp->common.pkt_type = EPHandleResp; 
+ resp->usb_dev_handle_resp = udc->mausb_dev->dev_handle; 
+ resp->common.pkt_status = maudc_handle_ep_req(udc->mausb_dev, 
+ &req->ep_handle_req, &resp->ep_handle_resp); 
+ ret = 0; 
+ break; 
+ case EPActivateReq: 
+ break; 
+ case EPInactivateReq: 
+ resp->common.pkt_type = EPInactivateResp; 
+ resp->common.pkt_status = maudc_handle_ep_inactivate( 
+ &req->ep_inactivate_req, 
+ &resp->ep_inactivate_resp, 
+ udc->mausb_dev); 
+ ret = 0; 
+ break; 
+ case EPResetReq: 
+ break; 
+ case EPClearTransferReq: 
+ break; 
+ case EPHandleDeleteReq: 
+ resp->common.pkt_type = EPHandleDeleteResp; 
+ 
+ resp->common.pkt_status = maudc_handle_ep_del_req( 
+ udc->mausb_dev, &req->ep_handle_delete, 
+ &resp->ep_handle_delete); 
+ ret = 0; 
+ break; 
+ case DevResetReq: 
+ resp->common.pkt_type = DevResetResp; 
+ 
+ ma_dev->ma_dev_addr = req->common.ma_dev_addr; 
+ ma_dev->mass_id = req->common.mass_id; 
+ 
+ ret = 0; 
+ 
+ if (0 == ret) { 
+ resp->common.pkt_status = NO_ERROR; 
+ } else { 
+ resp->common.pkt_status = 
+ mausb_errno_to_ma_status(ret); 
+ } 
+ break; 
+ case ModifyEP0Req: 
+ resp->common.pkt_type = ModifyEP0Resp; 
+ resp->common.pkt_status = SUCCESS; 
+ 
+ /* 
+ * TODO: fix so to spec - for now we don't track USB device 
+ * state and can't do proper checks. 
+ */ 
+ if (req->modify_ep0_req.ep_handle.dev_addr == 0) { 
+ /* && USB device is in addressed state) { */ 
+ resp->modify_ep0_resp.ep_handle.handle = 
+ req->modify_ep0_req.ep_handle.handle 
+ | (MAUDC_DEV_ADDR << 5); 
+ } else { 
+ resp->modify_ep0_resp.ep_handle.handle = 0; 
+ } 
+ 
+ ret = 0; 
+ break; 
+ case SetUSBDevAddrReq: 
+ resp->common.pkt_type = SetUSBDevAddrResp; 
+ resp->common.pkt_status = NO_ERROR; 
+ udc->mausb_dev->dev_address = MAUDC_DEV_ADDR; 
+ 
+ resp->set_dev_addr_resp.dev_addr = udc->mausb_dev->dev_address; 
+ ret = 0; 
+ break; 
+ case UpdateDevReq: 
+ break; 
+ case USBDevDisconnectReq: 
+ resp->common.pkt_type = USBDevDisconnectResp; 
+ resp->common.dev_handle = req->common.dev_handle; 
+ resp->common.pkt_status = NO_ERROR; 
+ ret = 0; 
+ break; 
+ case DevDisconnectReq: 
+ resp->common.pkt_type = DevDisconnectResp; 
+ resp->common.dev_handle = 0; 
+ resp->common.pkt_status = NO_ERROR; 
+ ret = 0; 
+ break; 
+ case SleepReq: 
+ resp->common.pkt_type = SleepResp; 
+ resp->common.pkt_status = NO_ERROR; 
+ mausb_device_suspend(); 
+ ret = 0; 
+ break; 
+ case WakeReq: 
+ resp->common.pkt_type = WakeResp; 
+ resp->common.pkt_status = NO_ERROR; 
+ mausb_device_resume(); 
+ ret = 0; 
+ break; 
+ case PingReq: 
+ break; 
+ case SyncReq: 
+ break; 
+ case CancelTransferReq: 
+ resp->common.pkt_type = CancelTransferResp; 
+ resp->common.pkt_status = NO_ERROR; 
+ resp->cancel_transfer_resp.ep_handle = 
+ req->cancel_transfer_req.ep_handle; 
+ resp->cancel_transfer_resp.stream_id = 
+ req->cancel_transfer_req.stream_id; 
+ resp->cancel_transfer_resp.req_id = 
+ req->cancel_transfer_req.req_id; 
+ /* TODO: cancel transfer and set fields below accordingly */ 
+ resp->cancel_transfer_resp.cancel_status = 1; 
+ resp->cancel_transfer_resp.deliv_seq_num = 0; 
+ resp->cancel_transfer_resp.deliv_byte_offset = 0; 
+ ret = 0; 
+ break; 
+ case EPOpenStreamReq: 
+ break; 
+ case EPCloseStreamReq: 
+ break; 
+ case USBDevResetReq: 
+ break; 
+ case VendorSpecificReq: 
+ break; 
+ 
+ /* Invalid packet type */ 
+ default: 
+ maudc_err(udc, "%s: invalid packet type\n", __func__); 
+ ret = -EBADMSG; 
+ break; 
+ } 
+ 
+ return ret; 
+} 
+ 
+/** 
+ * MA USB ep0 endpoint descriptor for a super speed endpoint 
+ * per spec section 7.3.2.2. 
+ */ 
+static struct usb_endpoint_descriptor mausb_ep0_desc = { 
+ 
+ .bLength = USB_DT_ENDPOINT_SIZE, 
+ .bDescriptorType = USB_DT_ENDPOINT, 
+ .bEndpointAddress = 0x00, 
+ .bmAttributes = USB_ENDPOINT_XFER_CONTROL, 
+ .wMaxPacketSize = 512, 
+ .bInterval = 0 
+}; 
+ 
+/** 
+ * UDC probe function 
+ */ 
+int mausb_udc_probe(struct platform_device *pdev) 
+{ 
+ int ret = 0; 
+ int i; 
+ struct mausb_udc *udc; 
+ struct usb_ep *usb_ep; 
+ 
+ udc = kzalloc(sizeof(*udc), GFP_KERNEL); 
+ if (!udc) 
+ return -ENOMEM; 
+ 
+ udc->udc_lock = __SPIN_LOCK_UNLOCKED(udc->udc_lock); 
+ /* initialize gadget structure */ 
+ udc->gadget.name = UDC_NAME; 
+ udc->gadget.ops = &mudc_ops; 
+ udc->gadget.speed = USB_SPEED_UNKNOWN; 
+ udc->gadget.max_speed = USB_SPEED_SUPER; 
+ udc->gadget.dev.parent = &pdev->dev; 
+
+ dev_set_name(&udc->gadget.dev, "%s", "gadget"); 
+ ret = device_register(&udc->gadget.dev); 
+ 
+ /* set head for list of gadget endpoints */ 
+ INIT_LIST_HEAD(&udc->gadget.ep_list); 
+ 
+ /* initalize the ma_dev structure */ 
+ mausb_init_ma_device(&udc->ma_dev, 0, 0, 
+ NULL, udc, &udc_mgmt_req_switch, &check_for_device); 
+ 
+ udc->mausb_dev = mausb_internal_alloc_dev(&udc->ma_dev, NULL, 
+ &udc->gadget); 
+ 
+ for (i = 0; i < MAUDC_MAX_NUM_EP; i++) { 
+ usb_ep = &udc->usb_ep[i].dev_ep; 
+ 
+ usb_ep->name = ep_name[i]; 
+ usb_ep->ops = &mausb_ep_ops; 
+ usb_ep->maxpacket = EP_MAX_PACKET; 
+ usb_ep->max_streams = EP_MAX_STREAMS; 
+ 
+ list_add_tail(&usb_ep->ep_list, &udc->gadget.ep_list); 
+ 
+ INIT_LIST_HEAD(&udc->usb_ep[i].usb_req_list); 
+ } 
+ 
+ /* give gadget driver ep0 then remove from list*/ 
+ udc->usb_ep[0].dev_ep.desc = &mausb_ep0_desc; 
+ udc->gadget.ep0 = &udc->usb_ep[0].dev_ep; 
+ list_del_init(&udc->usb_ep[0].dev_ep.ep_list); 
+ 
+ /* add a new gadget to the udc class driver list */ 
+ ret = usb_add_gadget_udc(&pdev->dev, &udc->gadget); 
+ if (ret < 0) { 
+ dev_err(&pdev->dev, "%s: could not add gadget UDC, error %d\n", 
+ __func__, ret); 
+ } else 
+ platform_set_drvdata(pdev, udc); 
+
+ return ret; 
+} 
+ 
+int mausb_udc_remove(struct platform_device *pdev) 
+{ 
+ struct mausb_udc *udc = platform_get_drvdata(pdev); 
+ 
+ dev_dbg(&pdev->dev, "%s: removing udc\n", __func__); 
+ 
+ usb_del_gadget_udc(&udc->gadget); 
+ 
+ return 0; 
+} 
+ 
+int mausb_udc_suspend(struct platform_device *pdev, pm_message_t state) 
+{ 
+ struct mausb_udc *udc = platform_get_drvdata(pdev); 
+ 
+ dev_dbg(&pdev->dev, "%s: suspending udc\n", __func__); 
+ 
+ udc->suspended = 1; 
+ 
+ return 0; 
+} 
+ 
+int mausb_udc_resume(struct platform_device *pdev) 
+{ 
+ struct mausb_udc *udc = platform_get_drvdata(pdev); 
+ 
+ dev_dbg(&pdev->dev, "%s: resuming udc\n", __func__); 
+ 
+ udc->suspended = 0; 
+ 
+ return 0; 
+} 
+ 
+/** 
+ * platform structures for USB Device Controller (UDC) 
+ */ 
+static struct platform_device udc_pdev = { 
+ .name = UDC_NAME, 
+ .id = -1, 
+}; 
+ 
+static struct platform_driver udc_driver = { 
+ .probe = mausb_udc_probe, 
+ .remove = mausb_udc_remove, 
+ .suspend = mausb_udc_suspend, 
+ .resume = mausb_udc_resume, 
+ .driver = { 
+ .name = UDC_NAME, 
+ .owner = THIS_MODULE 
+ } 
+}; 
+ 
+/** 
+ * initialization function 
+ * 
+ * TODO: get rid of platform device and replace with "virtual" device 
+ */ 
+static int mausb_udc_init(void) 
+{ 
+ int ret; 
+ 
+ pr_debug("loading MA USB UDC . . .\n"); 
+ 
+ /* register UDC driver */ 
+ ret = platform_driver_register(&udc_driver); 
+ if (ret < 0) { 
+ pr_err("failed to register UDC driver: err %d\n", ret); 
+ } else { 
+ /* register UDC device */ 
+ ret = platform_device_register(&udc_pdev); 
+ if (ret < 0) { 
+ pr_err("failed to register UDC device: err %d\n", ret); 
+ platform_driver_unregister(&udc_driver); 
+ 
+ } else { 
+ /* direct the release function (for exiting) */ 
+ udc_pdev.dev.release = &udc_dev_release; 
+ } 
+ } 
+
+ return ret; 
+} 
+module_init(mausb_udc_init); 
+ 
+/** 
+ * exit function 
+ */ 
+static void mausb_udc_exit(void) 
+{ 
+ /* deregister UDC device */ 
+ platform_device_unregister(&udc_pdev); 
+ 
+ /* deregister UDC driver */ 
+ platform_driver_unregister(&udc_driver); 
+ 
+} 
+module_exit(mausb_udc_exit); 
+ 
+MODULE_LICENSE("Dual BSD/GPL"); 
+MODULE_AUTHOR("Intel"); 
+MODULE_DESCRIPTION("mausb_udc"); 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/drivers/mausb_udc.h linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/drivers/mausb_udc.h
--- linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/drivers/mausb_udc.h	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/drivers/mausb_udc.h	2014-11-28 12:39:00.572447000 +0800
@@ -0,0 +1,147 @@
+/* name: mausb_udc.h 
+ * description: header file for mausb_udc.h 
+ * 
+ * This file is provided under a dual BSD/GPLv2 license. When using or 
+ * redistributing this file, you may do so under either license. 
+ * 
+ * GPL LICENSE SUMMARY 
+ * 
+ * Copyright(c) 2014 Intel Corporation. 
+ * 
+ * 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. 
+ * 
+ * Contact Information: 
+ * Sean Stalley, sean.o.stalley [at] intel 
+ * Stephanie Wallick, stephanie.s.wallick [at] intel 
+ * 2111 NE 25th Avenue 
+ * Hillsboro, Oregon 97124 
+ * 
+ * BSD LICENSE 
+ * 
+ * Copyright(c) 2014 Intel Corporation. 
+ * 
+ * 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 of Intel Corporation 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. 
+ */ 
+ 
+#ifndef __MAUSB_UDC_H 
+#define __MAUSB_UDC_H 
+ 
+#include <linux/timer.h> 
+#include <linux/usb/gadget.h> 
+#include "mausb_state.h" 
+#include "mausb_pkt.h" 
+#include "mausb_msapi.h" 
+#include "mausb_mem.h" /* for mgmt structure */ 
+#include "mausb_const.h" 
+ 
+#define UDC_NAME "mausb udc" 
+#define MAUDC_MAX_NUM_EP 3 
+#define EP_MAX_PACKET 64 /* max number of packets ep can handle */ 
+#define EP_MAX_STREAMS 16 /* max number of streams ep can handle */ 
+#define REQ_BUF_SIZE 64 
+#define CAP_MAX_EP_NUM 3 /* max number of endpoints state can be tracked for */ 
+#define CAP_MAX_DEV_NUM 1 /* max number of devices that can be managed 
+ * note this is 1 because only hubs can have >1 */ 
+#define CAP_DEV_TYPE 0 /* device type: 0 = not an MA USB hub 
+ * 1 = USB 2.0 hub 
+ * 2 = USB 3.1 hub */ 
+#define CAP_MAX_TX_REQS 0x01FF /* max number of outstanding transfer requests 
+ * device can track - arbitrarily chosen */ 
+#define CAP_MAX_MGMT_REQS 0x01F /* max number of outstanding management requests 
+ * device can track - arbitrarily chosen */ 
+ 
+#define MAUDC_DEV_HANDLE 0x1359 /* MA Device handle for the USB device */ 
+ 
+#define MAUDC_DEV_ADDR 0x7D /* USB Device address for the USB device */ 
+ /* Note: MAUDC_DEV_ADDR is arbitrary */ 
+ 
+#define MAUDC_BUS_NUM 0xD /* Bus number to be used in the endpoint handle */ 
+ 
+#define MAUSB_GADGET_TIMEOUT 3 /* time out for gadget driver enqueue request */ 
+ 
+#define maudc_info(udc, fmt, args...) \ 
+ dev_info(udc->gadget.dev.parent , fmt , ## args) 
+#define maudc_dbg(udc, fmt, args...) \ 
+ dev_dbg(udc->gadget.dev.parent , fmt , ## args) 
+#define maudc_warn(udc, fmt, args...) \ 
+ dev_warn(udc->gadget.dev.parent , fmt , ## args) 
+#define maudc_err(udc, fmt, args...) \ 
+ dev_err(udc->gadget.dev.parent , fmt , ## args) 
+ 
+/* function declarations */ 
+void udc_dev_release(struct device *dev); 
+int mausb_udc_probe(struct platform_device *pdev); 
+int mausb_udc_remove(struct platform_device *pdev); 
+int mausb_udc_suspend(struct platform_device *pdev, pm_message_t state); 
+int mausb_udc_resume(struct platform_device *pdev); 
+int check_for_device(int dont_use); 
+ 
+ 
+/* function declarations */ 
+int do_ma_transfer(struct mausb_host_ep *ep, struct mausb_pkt *tx_req, 
+ bool dir_in); 
+/** 
+ * UDC structure 
+ * 
+ * The UDC structure holds all of the per-device data. This includes both the 
+ * media agnostic device data as well as the USB device data. The USB device 
+ * connected to the UDC is considered an integrated USB Device. 
+ * 
+ * @mausb_gadget_ep: An array of all the endpoints for this device. 
+ * @usb_gadget: The device's gadget structure. 
+ * @usb_gadget_driver: the device's driver. 
+ * @ma_dev: The media agnostic device structure. Holds all the 
+ * data common to all media agnostic devices. 
+ * @mausb_dev: Holds media agnostic data that represents a USB device. 
+ * @ms_driver: The MAUSB driver's interface with the media specific 
+ * driver. 
+ * @udc_lock: The 'big' lock. Used to protect this structure's data 
+ * from concurrent access. 
+ * @dev_status: Holds USB device status. 
+ * @suspended: 1 when UDC is suspended, otherwise 0. 
+ * @pullup: 1 when a USB device is connecting to UDC, otherwise 0. 
+ */ 
+struct mausb_udc { 
+ struct mausb_gadget_ep usb_ep[MAUDC_MAX_NUM_EP]; 
+ struct usb_gadget gadget; 
+ struct usb_gadget_driver *driver; 
+ struct ma_dev ma_dev; 
+ struct mausb_dev *mausb_dev; 
+ spinlock_t udc_lock; 
+ u16 dev_status; 
+ unsigned suspended:1; 
+ unsigned pullup:1; 
+}; 
+ 
+#endif 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/Kconfig linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/Kconfig
--- linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/Kconfig	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/Kconfig	2014-11-28 12:39:00.572447000 +0800
@@ -0,0 +1,16 @@
+ 
+menuconfig MAUSB 
+ bool "MA USB drivers" 
+ depends on USB 
+ ---help--- 
+ This option allows you to select from the various MA USB 
+ drivers. Note that a media-specific driver (e.g. tcp or SNAP) 
+ is needed in addition to the media agnostic host or device driver. 
+ 
+ 
+if MAUSB 
+ 
+source "drivers/staging/mausb/drivers/Kconfig" 
+ 
+endif 
+ 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/Makefile linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/Makefile
--- linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/Makefile	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/Makefile	2014-11-28 12:39:00.572447000 +0800
@@ -0,0 +1,2 @@
+obj-y += drivers/ 
+ 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/mausb-util/Android.mk linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/mausb-util/Android.mk
--- linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/mausb-util/Android.mk	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/mausb-util/Android.mk	2014-11-28 12:39:00.572447000 +0800
@@ -0,0 +1,3 @@
+LOCAL_PATH := $(call my-dir) 
+ 
+include $(call all-subdir-makefiles) 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/mausb-util/AUTHORS linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/mausb-util/AUTHORS
--- linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/mausb-util/AUTHORS	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/mausb-util/AUTHORS	2014-11-28 12:39:00.572447000 +0800
@@ -0,0 +1,2 @@
+Sean O. Stalley <sean.stalley [at] intel> 
+Aymen Zayet <aymen.zayet [at] intel> 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/mausb-util/config.mk linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/mausb-util/config.mk
--- linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/mausb-util/config.mk	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/mausb-util/config.mk	2014-11-28 12:39:00.572447000 +0800
@@ -0,0 +1,19 @@
+CROSS_COMPILE ?= arm-none-linux-gnueabi-
+
+SRCDIR = $(shell pwd) 
+DESTDIR = /usr/local/bin 
+ 
+CC = $(CROSS_COMPILE)gcc 
+CFLAGS = -g -ggdb -D __DEBUG 
+LDFLAGS = 
+SHELL = /bin/sh 
+#CFLAGS = -O2 -fomit-frame-pointer 
+ 
+PROJECT_NAME = mausb 
+PROJECT_VERSION = 0.1 
+ 
+BINARY_NAME = $(PROJECT_NAME) 
+ 
+SOURCE_FILES = utils.c connect.c mausb.c 
+ 
+OBJECT_FILES = $(SOURCE_FILES:.c=.o) 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/mausb-util/Makefile linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/mausb-util/Makefile
--- linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/mausb-util/Makefile	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/mausb-util/Makefile	2014-11-28 12:39:00.572447000 +0800
@@ -0,0 +1,14 @@
+include config.mk 
+ 
+.PHONY: $(BINARY_NAME) all clean 
+ 
+all: $(BINARY_NAME) 
+ 
+$(BINARY_NAME): 
+	$(MAKE) -C src/ 
+	cp -rf src/$(BINARY_NAME) . 
+ 
+ 
+clean: 
+	$(MAKE) -C src/ clean 
+	rm -rf $(BINARY_NAME) *~ 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/mausb-util/README linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/mausb-util/README
--- linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/mausb-util/README	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/mausb-util/README	2014-11-28 12:39:00.572447000 +0800
@@ -0,0 +1,68 @@
+# # ## # # #### ##### # # ##### # # # ##### # # 
+## ## # # # # # # # # # # # # # # # # 
+# ## # # # # # #### ##### # # # # # # # # 
+# # ###### # # # # # # # # # # # # # 
+# # # # # # # # # # # # # # # # # # 
+# # # # #### #### ##### #### # # ###### # # # 
+ 
+ 
+Author: Aymen Zayet 
+License: GPL2 
+Version: 0.1 
+ 
+1. Description 
+-------------- 
+This tool includes many commands that help to test / debug the MAUSB devices. 
+mausb bin provides to the host a way to connect and disconnect from the MAUSB device 
+by selecting the mode (ip or llc). 
+ 
+2. Usage 
+-------- 
+(*) The following steps can be used to test the connection between two Moorefield based devices : 
+ 
+>> adb devices 
+List of devices attached 
+INV140200379 device 
+INV140200169 device 
+ 
+for device INV140200379: 
+>>adb -s INV140200379 shell busybox ifconfig wlan0 
+wlan0 Link encap:Ethernet HWaddr 78:FF:57:00:6D:7A 
+ inet addr:192.168.2.100 Bcast:192.168.2.255 Mask:255.255.255.0 
+ inet6 addr: fe80::7aff:57ff:fe00:6d7a/64 Scope:Link 
+ UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 
+ RX packets:264 errors:0 dropped:0 overruns:0 frame:0 
+ TX packets:287 errors:0 dropped:0 overruns:0 carrier:0 
+ collisions:0 txqueuelen:1000 
+ RX bytes:29906 (29.2 KiB) TX bytes:29267 (28.5 KiB) 
+ 
+for device INV140200169: 
+>> adb -s INV140200169 shell busybox ifconfig wlan0 
+wlan0 Link encap:Ethernet HWaddr 78:FF:57:00:6C:A8 
+ inet addr:192.168.2.113 Bcast:192.168.2.255 Mask:255.255.255.0 
+ inet6 addr: fe80::7aff:57ff:fe00:6ca8/64 Scope:Link 
+ UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 
+ RX packets:268 errors:0 dropped:0 overruns:0 frame:0 
+ TX packets:290 errors:0 dropped:0 overruns:0 carrier:0 
+ collisions:0 txqueuelen:1000 
+ RX bytes:31168 (30.4 KiB) TX bytes:30413 (29.7 KiB) 
+ 
+run INV140200379 as a MAUSB host: 
+>> adb -s INV140200379 shell load_mausb_android-host.sh 
+mausb load process complete 
+ 
+then run INV140200169 as MAUSB device: 
+>>adb -s INV140200169 shell load_mausb_android-dev.sh 
+mausb load process complete 
+ 
+now on the device side , run : 
+>> mausb --mode llc --connect --addr 78:FF:57:00:6D:7A 
+ 
+then from the host side, run : 
+>> mausb --mode llc --connect --addr 78:FF:57:00:6C:A8 
+ 
+3. Documentation 
+---------------- 
+ 
+4. Miscellaneous 
+---------------- 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/mausb-util/src/Android.mk linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/mausb-util/src/Android.mk
--- linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/mausb-util/src/Android.mk	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/mausb-util/src/Android.mk	2014-11-28 12:39:00.572447000 +0800
@@ -0,0 +1,13 @@
+LOCAL_PATH := $(call my-dir) 
+include $(CLEAR_VARS) 
+LOCAL_CFLAGS += -Wall -g 
+LOCAL_LDFLAGS += 
+LOCAL_LDLIBS += -lpthread -lm -ldl 
+LOCAL_SRC_FILES:= \ 
+ mausb.c \ 
+ utils.c \ 
+ connect.c 
+LOCAL_C_INCLUDES += linux/modules/ma-usb/drivers 
+LOCAL_MODULE := mausb 
+LOCAL_MODULE_TAGS := optional 
+include $(BUILD_EXECUTABLE) 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/mausb-util/src/connect.c linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/mausb-util/src/connect.c
--- linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/mausb-util/src/connect.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/mausb-util/src/connect.c	2014-11-28 12:39:00.572447000 +0800
@@ -0,0 +1,69 @@
+/* 
+ (c) Aymen Zayet (aymen.zayet [at] intel) 
+ 
+ This file is part of mausb utility. 
+ 
+ mausb 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. 
+ 
+ mausb 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 mausb. If not, see <http://www.gnu.org/licenses/>. 
+*/ 
+#include "mausb.h" 
+ 
+int set_ipv4_addr(mausb_t *config) 
+{ 
+ char buf[128] = {0}; 
+ printf("%s: setting ip address\n", __func__); 
+ sprintf(buf, "%u", config->ip); 
+ if (0 <= ioctl(config->device, IOCTL_SET_IP, buf)) 
+ return 0; 
+ return errno; 
+} 
+ 
+int set_mac_addr(mausb_t *config) 
+{ 
+ char buf[128] = {0}; 
+ printf("%s: setting mac address\n", __func__); 
+ memcpy(buf, config->mac, 6); 
+ if (0 <= ioctl(config->device, IOCTL_SET_MAC, buf)) { 
+ printf("Msg from kernel space : mac %s set successfully\n", 
+ (char *)buf); 
+ return 0; 
+ } 
+ return errno; 
+} 
+int set_port(mausb_t *config) 
+{ 
+ char buf[128] = {0}; 
+ printf("%s: setting port\n", __func__); 
+ sprintf(buf, "%u", config->port); 
+ if (0 <= ioctl(config->device, IOCTL_SET_PORT, buf)) 
+ return 0; 
+ return errno; 
+} 
+ 
+int connect_device(mausb_t *config) 
+{ 
+ char buf[128] = {0}; 
+ printf("%s: connecting device\n", __func__); 
+ if (0 <= ioctl(config->device, IOCTL_GADGET_C, buf)) 
+ return 0; 
+ return errno; 
+} 
+ 
+int disconnect_device(mausb_t *config) 
+{ 
+ char buf[128] = {0}; 
+ printf("%s: disconnecting device\n", __func__); 
+ if (0 <= ioctl(config->device, IOCTL_GADGET_D, buf)) 
+ return 0; 
+ return errno; 
+} 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/mausb-util/src/connect.h linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/mausb-util/src/connect.h
--- linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/mausb-util/src/connect.h	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/mausb-util/src/connect.h	2014-11-28 12:39:00.572447000 +0800
@@ -0,0 +1,22 @@
+/* 
+ (c) Aymen Zayet (aymen.zayet [at] intel) 
+ 
+ This file is part of mausb utility. 
+ 
+ mausb 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. 
+ 
+ mausb 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 mausb. If not, see <http://www.gnu.org/licenses/>. 
+*/ 
+#ifndef CONNECT_H_ 
+#define CONNECT_H_ 
+ 
+#endif /* CONNECT_H_ */ 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/mausb-util/src/Makefile linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/mausb-util/src/Makefile
--- linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/mausb-util/src/Makefile	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/mausb-util/src/Makefile	2014-11-28 12:39:00.572447000 +0800
@@ -0,0 +1,17 @@
+include ../config.mk 
+ 
+all: $(BINARY_NAME) 
+ 
+$(BINARY_NAME): $(OBJECT_FILES) 
+	@echo -n "(LD)" $@ " " 
+	@$(CC) $(LDFLAGS) $(CFLAGS) $^ -o $@ 
+	@echo OK 
+ 
+%.o: %.c 
+	@echo -n "(CC)" $@ " " 
+	@$(CC) $(CFLAGS) -c $< -o $@ 
+	@echo OK 
+ 
+clean: 
+	rm -rf *.[oas] .*.flags *.ko .*.cmd .*.d .*.tmp *.mod.c .tmp_versions Module*.symvers 
+	rm -f $(BINARY_NAME) *~ 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/mausb-util/src/mausb.c linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/mausb-util/src/mausb.c
--- linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/mausb-util/src/mausb.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/mausb-util/src/mausb.c	2014-11-28 12:39:00.572447000 +0800
@@ -0,0 +1,201 @@
+/* 
+ (c) Aymen Zayet (aymen.zayet [at] intel) 
+ 
+ This file is part of mausb utility. 
+ 
+ mausb 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. 
+ 
+ mausb 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 mausb. If not, see <http://www.gnu.org/licenses/>. 
+*/ 
+ 
+#include "mausb.h" 
+ 
+ 
+ 
+static struct option l_opts[] = { 
+ /* no_argument options */ 
+ {"help", no_argument, 0, 'h'}, 
+ {"verbose", no_argument, 0, 'v'}, 
+ {"connect", no_argument, 0, 'c'}, 
+ {"disconnect", no_argument, 0, 'd'}, 
+ 
+ /* required_argument options */ 
+ {"addr", required_argument, 0, 'a'}, 
+ {"port", required_argument, 0, 'p'}, 
+ {"mode", required_argument, 0, 'm'}, 
+ 
+ /* end */ 
+ {0, 0, 0, 0}, 
+}; 
+ 
+static void usage(const char *this) 
+{ 
+ fprintf(stderr, 
+ "Usage: " 
+ "\t%s [[options]] command" 
+ "\n\t\t [--help/-h] show this help" 
+ "\n\t\t [--verbose/-h] Add more trace about what's going on" 
+ "\n\t\t [--mode/-m] mausb mode to be used : ip (default) or llc" 
+ "\n\t\t [--connect/-c] connect to mausb device" 
+ "\n\t\t [--disconnect/-d] disconnect from mausb device" 
+ "\n\t\t [--port/-p] set the port number in case of tcp connection" 
+ "\n\t\t [--addr/-a] ip or mac address depending on the given mode" 
+ "\n", this); 
+ return ; 
+} 
+ 
+static int check_config(void) 
+{ 
+ int ret; 
+ 
+ if (config.cmd == disconnect) 
+ return 0; 
+ 
+ switch (config.mode) { 
+ case ip: 
+ ret = !config.port; 
+ break; 
+ case llc: 
+ ret = !config.mac; 
+ break; 
+ default: 
+ ret = !! config.mode; 
+ } 
+ 
+ return ((config.cmd > max_command) || 
+ (config.mode > supported_mode) || 
+ ret); 
+} 
+ 
+static void print_config(void) 
+{ 
+ return ; 
+} 
+ 
+static int process_options(int argc, char **argv) 
+{ 
+ int option; 
+ 
+ memset(&config, 0, sizeof(mausb_t)); 
+ config.mode = ip; 
+ while ((option = getopt_long(argc, argv, "hfp:a:cdvm:", l_opts, NULL)) != EOF) { 
+ switch(option) { 
+ case 'h': // help 
+ usage(argv[0]); 
+ exit(0); 
+ break; 
+ 
+ case 'v': // verbose 
+ config.verbose = 1; 
+ break; 
+ 
+ case 'c': // connect 
+ config.cmd = connect; 
+ break; 
+ 
+ case 'd': // disconnect 
+ config.cmd = disconnect; 
+ break; 
+ 
+ case 'm': // mode 
+ if (strlen(optarg) == 3 && !strncmp(optarg, "llc", 3)) 
+ config.mode = llc; 
+ else if (strlen(optarg) == 2 && !strncmp(optarg, "ip", 2)) 
+ config.mode = ip; 
+ else { 
+ fprintf(stderr, "could not determine mode\n"); 
+ goto err_options; 
+ } 
+ break; 
+ 
+ case 'a': // addr 
+ if (config.mode == llc) { 
+ if (MACADDR_STR_SIZE != strlen(optarg)) 
+ goto err_options; 
+ if (get_mac_address(optarg, config.mac)) 
+ goto err_options; 
+ } else { 
+ if (strlen(optarg) >= IPADDR_MAX) 
+ goto err_options; 
+ if (convert_ipv4_to_uint32(optarg, &config.ip)) 
+ goto err_options; 
+ strcpy(config.ip_addr, optarg); 
+ } 
+ break; 
+ 
+ case 'p': // port 
+ config.port = atoi(optarg); 
+ break; 
+ 
+ default: 
+ fprintf(stderr, "invalid option %c\n", option); 
+ goto err_options; 
+ break; 
+ } 
+ } 
+ 
+ if (check_config()) { 
+ fprintf(stderr, "check_config() failed\n"); 
+ goto err_options; 
+ } 
+ 
+ if (config.verbose) 
+ print_config(); 
+ 
+ return 0; 
+ 
+err_options: 
+ usage(argv[0]); 
+ return -1; 
+} 
+ 
+int main(int argc, char **argv) 
+{ 
+ int ret; 
+ 
+ if (ret = process_options(argc, argv)) 
+ goto error; 
+ 
+ printf("progran terminated successfully ip %x %s %d\n", config.ip, 
+ config.ip_addr, config.port); 
+ 
+ ret = config.device = open(MAUSB_DEVICE, 0); 
+ if (ret < 0) { 
+ fprintf(stderr, "cannot open device %d\n", ret); 
+ goto error; 
+ } 
+ 
+ switch(config.cmd) { 
+ case connect: 
+ if (config.verbose) 
+ printf("connecting to %s port %u\n", config.ip_addr, config.port); 
+ if (config.mode == llc) { 
+ if (ret = set_mac_addr(&config)) 
+ goto close_device; 
+ } else { 
+ if (ret = set_ipv4_addr(&config)) 
+ goto close_device; 
+ if (ret = set_port(&config)) 
+ goto close_device; 
+ } 
+ if (ret = connect_device(&config)) 
+ goto close_device; 
+ break; 
+ case disconnect: 
+ disconnect_device(&config); 
+ break; 
+ } 
+close_device: 
+ close(config.device); 
+error: 
+ return ret; 
+} 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/mausb-util/src/mausb.h linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/mausb-util/src/mausb.h
--- linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/mausb-util/src/mausb.h	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/mausb-util/src/mausb.h	2014-11-28 12:39:00.572447000 +0800
@@ -0,0 +1,64 @@
+/* 
+ (c) Aymen Zayet (aymen.zayet [at] intel) 
+ 
+ This file is part of mausb utility. 
+ 
+ mausb 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. 
+ 
+ mausb 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 mausb. If not, see <http://www.gnu.org/licenses/>. 
+*/ 
+#ifndef MAUSB_H_ 
+#define MAUSB_H_ 
+ 
+#include <unistd.h> 
+#include <stdlib.h> 
+#include <string.h> 
+#include <errno.h> 
+#include <stdint.h> 
+#include <stdio.h> 
+#include <getopt.h> 
+#include <sys/ioctl.h> 
+#include "connect.h" 
+#include "mausb_ioctl.h" 
+ 
+#define MAUSB_DEVICE "/dev/mausb" 
+#define IPADDR_MAX 16 
+#define MACADDR_STR_SIZE 17 /* excluding null termination char */ 
+ 
+typedef enum { 
+ connect, 
+ disconnect, 
+ max_command, 
+} mausb_cmd; 
+ 
+typedef enum { 
+ ip, 
+ llc, 
+ supported_mode, 
+} mausb_mode; 
+ 
+typedef struct { 
+ int device; // file descriptor of the mausb device 
+ char verbose; // is verbose mode enabled 
+ mausb_cmd cmd; // keep the requested command to execute 
+ uint32_t ip; // ip address of the device in case of ip mode 
+ char ip_addr[IPADDR_MAX]; // ip address given in cmdline (x.x.x.x) 
+ uint8_t mac[6]; // mac address (aa:bb:cc:dd:ee:ff) 
+ uint32_t port; // ip port number in case of ip mode 
+ mausb_mode mode; // default is ip 
+} mausb_t; 
+ 
+mausb_t config; 
+int convert_ipv4_to_uint32(char *, uint32_t *); 
+ 
+int get_mac_address(char *, uint8_t *); 
+#endif /* MAUSB_H_ */ 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/mausb-util/src/mausb_ioctl.h linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/mausb-util/src/mausb_ioctl.h
--- linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/mausb-util/src/mausb_ioctl.h	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/mausb-util/src/mausb_ioctl.h	2014-11-28 12:39:00.572447000 +0800
@@ -0,0 +1,24 @@
+#ifndef MAUSB_IOCTL_H 
+#define MAUSB_IOCTL_H 
+ 
+#define BUFFER 80 
+#define DRIVER_VERSION "Alpha 0.0.25" 
+#define MAJOR_NUM 100 
+ 
+/* These define the ioctl functions that can be used */ 
+#define IOCTL_GET_VRSN _IOR(MAJOR_NUM, 0, char *) 
+#define IOCTL_GET_NAME _IOR(MAJOR_NUM, 1, char *) 
+#define IOCTL_GADGET_C _IOR(MAJOR_NUM, 2, char *) 
+#define IOCTL_GADGET_D _IOR(MAJOR_NUM, 3, char *) 
+#define IOCTL_SET_IP _IOR(MAJOR_NUM, 4, char *) 
+#define IOCTL_SET_PORT _IOR(MAJOR_NUM, 5, char *) 
+#define IOCTL_SET_MAC _IOR(MAJOR_NUM, 6, char *) 
+ 
+ 
+/* This is the location where the device file will be created. It is used to 
+ * read/write to in order to communicate to and from the device */ 
+#define DEVICE_FILE_NAME "/dev/mausb" 
+ 
+#define ETH_ALEN 6 
+ 
+#endif 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/mausb-util/src/utils.c linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/mausb-util/src/utils.c
--- linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/mausb-util/src/utils.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/mausb-util/src/utils.c	2014-11-28 12:39:00.572447000 +0800
@@ -0,0 +1,94 @@
+/* 
+ (c) Aymen Zayet (aymen.zayet [at] intel) 
+ 
+ This file is part of mausb utility. 
+ 
+ mausb 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. 
+ 
+ mausb 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 mausb. If not, see <http://www.gnu.org/licenses/>. 
+*/ 
+#include "mausb.h" 
+ 
+int convert_ipv4_to_uint32(char *addr, uint32_t *ipnum) 
+{ 
+ uint8_t digits[4]; 
+ int i, j = 0; 
+ char ip[64]; 
+ 
+ if (addr == NULL) 
+ goto input_err; 
+ 
+ strncpy(ip, addr, strlen(addr)+1); 
+ i = strlen(ip); 
+ memset(digits, 0, 4); 
+ 
+ if (IPADDR_MAX < strlen(ip)) 
+ goto input_err; 
+ 
+again: 
+ while (i-1 && ip[--i - 1] != '.'); 
+ if (i-1) { 
+ ip[i-1] = '\0'; 
+ digits[j++] = atoi(ip+i); 
+ goto again; 
+ } else 
+ digits[j++] = atoi(ip); 
+ 
+ *ipnum = digits[3] << 24 | 
+ digits[2] << 16 | 
+ digits[1] << 8 | 
+ digits[0] << 0; 
+ 
+ return 0; 
+ 
+input_err: 
+ return -1; 
+} 
+ 
+ 
+int get_mac_address(char *addr, uint8_t *out) 
+{ 
+ 
+ uint8_t digits[6]; 
+ int i, j = 0; 
+ char mac[64]; 
+ 
+ if (addr == NULL) 
+ goto input_err; 
+ 
+ strncpy(mac, addr, strlen(addr)+1); 
+ i = strlen(mac); 
+ memset(digits, 0, 6); 
+ 
+ if (MACADDR_STR_SIZE != strlen(mac)) 
+ goto input_err; 
+ 
+again: 
+ while (i-1 && mac[--i - 1] != ':'); 
+ if (i-1) { 
+ mac[i-1] = '\0'; 
+ digits[j++] = strtol(mac+i, NULL, 16); 
+ goto again; 
+ } else 
+ digits[j++] = strtol(mac, NULL, 16); 
+ 
+ for (i = 0; i < 6; i++) { 
+ printf("[%d]=0x%x ", i, digits[i]); 
+ out[5-i] = digits[i]; 
+ } 
+ 
+ printf("\n"); 
+ return 0; 
+ 
+input_err: 
+ return -1; 
+} 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/scripts/Android.mk linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/scripts/Android.mk
--- linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/scripts/Android.mk	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/scripts/Android.mk	2014-11-28 12:39:00.572447000 +0800
@@ -0,0 +1,38 @@
+LOCAL_PATH := $(call my-dir) 
+ 
+include $(CLEAR_VARS) 
+LOCAL_MODULE := load_mausb_android.sh 
+LOCAL_MODULE_TAGS := optional 
+LOCAL_SRC_FILES := $(LOCAL_MODULE) 
+LOCAL_MODULE_CLASS := EXECUTABLE 
+ 
+ifeq ($(TARGET_OUT_EXECUTABLE),) 
+TARGET_OUT_EXECUTABLE := $(TARGET_OUT)/bin 
+endif 
+ 
+include $(BUILD_PREBUILT) 
+ 
+include $(CLEAR_VARS) 
+ 
+LOCAL_MODULE := load_mausb_android-host.sh 
+LOCAL_MODULE_TAGS := optional 
+LOCAL_SRC_FILES := $(LOCAL_MODULE) 
+LOCAL_MODULE_CLASS := EXECUTABLE 
+ 
+ifeq ($(TARGET_OUT_EXECUTABLE),) 
+TARGET_OUT_EXECUTABLE := $(TARGET_OUT)/bin 
+endif 
+ 
+include $(BUILD_PREBUILT) 
+ 
+include $(CLEAR_VARS) 
+LOCAL_MODULE := load_mausb_android-dev.sh 
+LOCAL_MODULE_TAGS := optional 
+LOCAL_SRC_FILES := $(LOCAL_MODULE) 
+LOCAL_MODULE_CLASS := EXECUTABLE 
+ 
+ifeq ($(TARGET_OUT_EXECUTABLE),) 
+TARGET_OUT_EXECUTABLE := $(TARGET_OUT)/bin 
+endif 
+ 
+include $(BUILD_PREBUILT) 
\ No newline at end of file
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/scripts/build_load_connect.sh linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/scripts/build_load_connect.sh
--- linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/scripts/build_load_connect.sh	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/scripts/build_load_connect.sh	2014-11-28 12:39:00.572447000 +0800
@@ -0,0 +1,69 @@
+#!/bin/bash 
+ 
+side="invalid" 
+mode="invalid" 
+addr="invalid" 
+ 
+while getopts "hdbtsa:" opt; do 
+ case "$opt" in 
+ h) side="-h" 
+ ;; 
+ d) side="-d" 
+ ;; 
+ b) side="-b" 
+ ;; 
+ t) mode="-t" 
+ ;; 
+ s) mode="-s" 
+ ;; 
+ a) addr=$OPTARG 
+ ;; 
+ esac 
+done 
+ 
+ 
+if [ "$side" == "invalid" ] 
+then 
+ echo $side 
+ echo "please choose host (-h) or device (-d)" 
+ exit 
+fi 
+ 
+if [ "$mode" == "invalid" ] 
+then 
+ echo $mode 
+ echo "please choose tcp (-t) or snap (-s)" 
+ exit 
+fi 
+ 
+if [ "$addr" == "invalid" ] 
+then 
+ echo $addr 
+ echo "please enter a valid address (-a 1.2.3.4, -a 01:23:45:67:89:0a)" 
+ exit 
+fi 
+ 
+ 
+cd ../ 
+# make clean && make 
+make -j8 
+cd drivers/ 
+ 
+wireshark -k -i eth0 & 
+ 
+sudo ../scripts/load_script.sh $side $mode 
+ 
+sudo cat /proc/modules | grep ma 
+ 
+if [ "$mode" == "-s" ] 
+then 
+ echo "connecting mausb" 
+ ../tools/mausb-util/mausb -c -m llc -a $addr 
+fi 
+ 
+if [ "$mode" == "-t" ] 
+then 
+ echo "connecting mausb" 
+ ../tools/mausb-util/mausb -c -m ip -p 9001 -a $addr 
+fi 
+ 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/scripts/load_gzero.sh linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/scripts/load_gzero.sh
--- linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/scripts/load_gzero.sh	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/scripts/load_gzero.sh	2014-11-28 12:39:00.572447000 +0800
@@ -0,0 +1,5 @@
+#!/bin/bash 
+ 
+modprobe g_zero 
+ 
+echo g_zero load process complete 
\ No newline at end of file
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/scripts/load_mausb_android-dev.sh linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/scripts/load_mausb_android-dev.sh
--- linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/scripts/load_mausb_android-dev.sh	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/scripts/load_mausb_android-dev.sh	2014-11-28 12:39:00.572447000 +0800
@@ -0,0 +1,31 @@
+#!/system/xbin/ash 
+ 
+# For Android targets, insmod shall be used since 
+# the ueventd take care of the dependencies. 
+ 
+GREEN="\\033[.1;32m" 
+NORMAL="\\033[.0;39m" 
+RED="\\033[.1;31m" 
+ 
+load_module() 
+{ 
+ insmod $1 
+ if [ $? -ne 0 ]; then 
+ echo -e $RED 
+ echo "unable to insmod $1 (err : $?)" 
+ echo -e $NORMAL 
+ exit $? 
+ fi 
+} 
+ 
+ 
+load_module /lib/modules/matcp_core.ko 
+load_module /lib/modules/maudc.ko 
+#load_module /lib/modules/mamed.ko 
+load_module /lib/modules/matcp_dev.ko 
+ 
+mknod /dev/mausb c 100 0 
+ 
+echo -e $GREEN 
+echo "mausb load process complete" 
+echo -e $NORMAL 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/scripts/load_mausb_android-host.sh linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/scripts/load_mausb_android-host.sh
--- linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/scripts/load_mausb_android-host.sh	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/scripts/load_mausb_android-host.sh	2014-11-28 12:39:00.572447000 +0800
@@ -0,0 +1,31 @@
+#!/system/xbin/ash 
+ 
+# For Android targets, insmod shall be used since 
+# the ueventd take care of the dependencies. 
+ 
+GREEN="\\033[.1;32m" 
+NORMAL="\\033[.0;39m" 
+RED="\\033[.1;31m" 
+ 
+load_module() 
+{ 
+ insmod $1 
+ if [ $? -ne 0 ]; then 
+ echo -e $RED 
+ echo "unable to insmod $1 (err : $?)" 
+ echo -e $NORMAL 
+ exit $? 
+ fi 
+} 
+ 
+ 
+load_module /lib/modules/matcp_core.ko 
+load_module /lib/modules/mausb.ko 
+#load_module /lib/modules/mamed.ko 
+load_module /lib/modules/matcp_host.ko 
+ 
+mknod /dev/mausb c 100 0 
+ 
+echo -e $GREEN 
+echo "mausb load process complete" 
+echo -e $NORMAL 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/scripts/load_mausb_android.sh linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/scripts/load_mausb_android.sh
--- linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/scripts/load_mausb_android.sh	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/scripts/load_mausb_android.sh	2014-11-28 12:39:00.572447000 +0800
@@ -0,0 +1,33 @@
+#!/system/xbin/ash 
+ 
+# For Android targets, insmod shall be used since 
+# the ueventd take care of the dependencies. 
+ 
+GREEN="\\033[.1;32m" 
+NORMAL="\\033[.0;39m" 
+RED="\\033[.1;31m" 
+ 
+load_module() 
+{ 
+ insmod $1 
+ if [ $? -ne 0 ]; then 
+ echo -e $RED 
+ echo "unable to insmod $1 (err : $?)" 
+ echo -e $NORMAL 
+ exit $? 
+ fi 
+} 
+ 
+ 
+load_module /lib/modules/matcp_core.ko 
+load_module /lib/modules/mausb.ko 
+load_module /lib/modules/maudc.ko 
+#load_module /lib/modules/mamed.ko 
+load_module /lib/modules/matcp_host.ko 
+load_module /lib/modules/matcp_dev.ko 
+ 
+mknod /dev/mausb c 100 0 
+ 
+echo -e $GREEN 
+echo "mausb load process complete" 
+echo -e $NORMAL 
\ No newline at end of file
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/scripts/load_script.sh linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/scripts/load_script.sh
--- linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/scripts/load_script.sh	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/scripts/load_script.sh	2014-11-28 12:39:00.572447000 +0800
@@ -0,0 +1,125 @@
+#!/bin/bash 
+# This script is used for loading & unloading the mausb_driver 
+ 
+# note: this script must be run with root priviledge (for the modprobes) 
+ 
+side="invalid" 
+mode="invalid" 
+load="load" 
+ 
+# Determine weather to load a host or device in TCP mode or snap mode 
+while getopts "hdbtslu" opt; do 
+ case "$opt" in 
+ h) side="host" 
+ ;; 
+ d) side="device" 
+ ;; 
+ b) side="both" 
+ ;; 
+ t) mode="tcp" 
+ ;; 
+ s) mode="snap" 
+ ;; 
+ l) load="load" 
+ ;; 
+ u) load="unload" 
+ ;; 
+ esac 
+done 
+ 
+if [ "$side" == "invalid" ] 
+then 
+ echo $side 
+ echo "please choose host (-h) or device (-d)" 
+ exit 
+fi 
+ 
+if [ "$mode" == "invalid" ] 
+then 
+ echo $mode 
+ echo "please choose a tcp (-t) or snap (-s)" 
+ exit 
+fi 
+ 
+ 
+ 
+if [ "$load" == "load" ] 
+then 
+ # copy the LKM into the module library 
+ pushd $(dirname $0) 
+ cp ../drivers/*.ko /lib/modules/$(uname -r)/kernel/drivers/usb/ 
+ popd 
+ 
+ # depmod so the kernel can figure out its dependacies 
+ depmod -A 
+ 
+ # open the file for ioctl calls 
+ mknod /dev/mausb c 100 0 
+ 
+ modprobe_flags="" 
+ 
+elif [ "$load" == "unload" ] 
+then 
+ # unload the drivers instead of loading them 
+ modprobe_flags="-r" 
+ 
+fi 
+ 
+ 
+ 
+# load the drivers 
+ 
+if [ "$mode" == "tcp" ] && [ "$load" == "load" ] 
+then 
+ modprobe $modprobe_flags matcp_core 
+ 
+elif [ "$mode" == "snap" ] 
+then 
+ modprobe $modprobe_flags masnap_core 
+fi 
+ 
+ 
+if [ "$side" == "device" ] || [ "$side" == "both" ] 
+then 
+ if [ "$load" == "load" ] 
+ then 
+ modprobe $modprobe_flags maudc 
+ fi 
+ 
+ modprobe $modprobe_flags g_zero 
+ 
+ if [ "$mode" == "tcp" ] 
+ then 
+ modprobe $modprobe_flags matcp_dev 
+ 
+ elif [ "$mode" == "snap" ] 
+ then 
+ modprobe $modprobe_flags masnap_dev 
+ fi 
+fi 
+ 
+if [ "$side" == "host" ] || [ "$side" == "both" ] 
+then 
+ if [ "$load" == "load" ] 
+ then 
+ modprobe $modprobe_flags mausb 
+ fi 
+ 
+ if [ "$mode" == "tcp" ] 
+ then 
+ modprobe $modprobe_flags matcp_host 
+ 
+ elif [ "$mode" == "snap" ] 
+ then 
+ modprobe $modprobe_flags masnap_host 
+ fi 
+ 
+fi 
+ 
+if [ "$load" == "unload" ] 
+then 
+ modprobe $modprobe_flags maudc 
+ modprobe $modprobe_flags mausb 
+fi 
+ 
+echo "$load mausb $side $mode driver complete" 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/scripts/modprobify.sh linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/scripts/modprobify.sh
--- linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/scripts/modprobify.sh	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/scripts/modprobify.sh	2014-11-28 12:39:00.572447000 +0800
@@ -0,0 +1,10 @@
+#!/bin/bash 
+ 
+ 
+# note: this scripted needs to be run as a superuser to work 
+ 
+# copy the LKM into the module library 
+cp ./*.ko /lib/modules/$(uname -r)/kernel/drivers/usb/ 
+ 
+# depmod so the kernel can figure out its dependacies 
+depmod -A 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/scripts/unload_gzero.sh linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/scripts/unload_gzero.sh
--- linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/scripts/unload_gzero.sh	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/scripts/unload_gzero.sh	2014-11-28 12:39:00.572447000 +0800
@@ -0,0 +1,5 @@
+#!/bin/bash 
+ 
+modprobe -r g_zero 
+ 
+echo g_zero unload process complete 
\ No newline at end of file
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/TODO linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/TODO
--- linux-linaro-3.4-2012.05-1_original/drivers/staging/mausb/TODO	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/staging/mausb/TODO	2014-11-28 12:39:00.572447000 +0800
@@ -0,0 +1,5 @@
+TODO: 
+ - checkpatch.pl cleanups 
+ - address miscellaneous "TODO" statements in code 
+ - add support for multiple media agnostic (MA) devices 
+ - add/improve support for unimplemented packet types 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/tty/serial/8250/8250.c linux-linaro-3.4-2012.05-1_cavium/drivers/tty/serial/8250/8250.c
--- linux-linaro-3.4-2012.05-1_original/drivers/tty/serial/8250/8250.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/tty/serial/8250/8250.c	2014-07-29 17:28:38.819972000 +0800
@@ -47,6 +47,15 @@
 
 #include "8250.h"
 
+
+
+/* Offset for the DesignWare's UART Status Register. */
+#define UART_USR	0x1f
+
+struct dw8250_data {
+	int	last_lcr;
+	int	line;
+};
 /*
  * Configuration:
  *   share_irqs - whether we pass IRQF_SHARED to request_irq().  This option
@@ -394,14 +403,20 @@
 
 static void mem32_serial_out(struct uart_port *p, int offset, int value)
 {
+	struct dw8250_data *d = p->private_data;
+
+	if (offset == UART_LCR)
+		d->last_lcr = value;
+
 	offset = map_8250_out_reg(p, offset) << p->regshift;
-	writel(value, p->membase + offset);
+	writew(value, p->membase + offset);
 }
 
 static unsigned int mem32_serial_in(struct uart_port *p, int offset)
 {
-	offset = map_8250_in_reg(p, offset) << p->regshift;
-	return readl(p->membase + offset);
+	int test = 0;
+	test = map_8250_in_reg(p, offset) << p->regshift;
+	return readw(p->membase + test);
 }
 
 static unsigned int au_serial_in(struct uart_port *p, int offset)
@@ -1517,6 +1532,7 @@
 	struct uart_8250_port *up =
 		container_of(port, struct uart_8250_port, port);
 
+	//printk("serial8250_handle_irq 111\n");
 	if (iir & UART_IIR_NO_INT)
 		return 0;
 
@@ -1534,14 +1550,31 @@
 
 	spin_unlock_irqrestore(&port->lock, flags);
 	return 1;
+	//printk("serial8250_handle_irq 222\n");
 }
 EXPORT_SYMBOL_GPL(serial8250_handle_irq);
 
 static int serial8250_default_handle_irq(struct uart_port *port)
 {
+	struct dw8250_data *d = port->private_data;
+
+//	printk("serial8250_default_handle_irq : port = 0x%x\n",port);
 	unsigned int iir = serial_port_in(port, UART_IIR);
+//	printk("iir = 0x%x, UART_IIR = 0x%x\n",iir, UART_IIR);
+#if 1
+	if (serial8250_handle_irq(port, iir)) {
+		return 1;
+	} else if ((iir & UART_IIR_BUSY) == UART_IIR_BUSY) {
+		/* Clear the USR and write the LCR again. */
+		port->serial_in(port, UART_USR);
+		port->serial_out(port, UART_LCR, d->last_lcr);
+		return 0;
+	}
 
+	return 0;
+#else
 	return serial8250_handle_irq(port, iir);
+#endif
 }
 
 /*
@@ -1565,7 +1598,7 @@
 	int pass_counter = 0, handled = 0;
 
 	DEBUG_INTR("serial8250_interrupt(%d)...", irq);
-
+//printk("serial8250_interrupt(%d)...", irq);
 	spin_lock(&i->lock);
 
 	l = i->head;
@@ -1576,26 +1609,28 @@
 		up = list_entry(l, struct uart_8250_port, list);
 		port = &up->port;
 
+		//printk("serial8250_interrupt: irq = %d, handle_irq = 0x%x\n",port->irq,port->handle_irq);
 		if (port->handle_irq(port)) {
+			//printk("aaa\n");
 			handled = 1;
 			end = NULL;
-		} else if (end == NULL)
+		} else if (end == NULL){
 			end = l;
-
+			//printk("bbb\n");
+		}
 		l = l->next;
-
+		//printk("pass_counter = %d\n",pass_counter);
 		if (l == i->head && pass_counter++ > PASS_LIMIT) {
 			/* If we hit this, we're dead. */
-			printk_ratelimited(KERN_ERR
-				"serial8250: too much work for irq%d\n", irq);
+			printk("serial8250: too much work for irq%d\n", irq);
 			break;
 		}
 	} while (l != end);
 
 	spin_unlock(&i->lock);
 
-	DEBUG_INTR("end.\n");
-
+//	DEBUG_INTR("end.\n");
+//printk("end.\n");
 	return IRQ_RETVAL(handled);
 }
 
@@ -1633,6 +1668,7 @@
 	struct irq_info *i;
 	int ret, irq_flags = up->port.flags & UPF_SHARE_IRQ ? IRQF_SHARED : 0;
 
+//printk("%s : %s in line %d\n",__FILE__,__FUNCTION__,__LINE__);
 	mutex_lock(&hash_mutex);
 
 	h = &irq_lists[up->port.irq % NR_IRQ_HASH];
@@ -1667,8 +1703,11 @@
 		i->head = &up->list;
 		spin_unlock_irq(&i->lock);
 		irq_flags |= up->port.irqflags;
+		//printk("%s : %s in line %d\n",__FILE__,__FUNCTION__,__LINE__);
+		//printk("up->port.irq = %d\n",up->port.irq);
 		ret = request_irq(up->port.irq, serial8250_interrupt,
 				  irq_flags, "serial", i);
+		//printk("ret = %d\n",ret);
 		if (ret < 0)
 			serial_do_unlink(i, up);
 	}
@@ -2941,7 +2980,7 @@
 
 	if (port->line >= ARRAY_SIZE(serial8250_ports))
 		return -ENODEV;
-
+//printk("%s : %s in line %d\n",__FILE__,__FUNCTION__,__LINE__);
 	serial8250_isa_init_ports();
 	p = &serial8250_ports[port->line].port;
 	p->iobase       = port->iobase;
@@ -3015,7 +3054,11 @@
 	struct plat_serial8250_port *p = dev->dev.platform_data;
 	struct uart_port port;
 	int ret, i, irqflag = 0;
+	struct dw8250_data *data = devm_kzalloc(&dev->dev, sizeof(*data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
 
+	port.private_data = data;
 	memset(&port, 0, sizeof(struct uart_port));
 
 	if (share_irqs)
@@ -3041,6 +3084,12 @@
 		port.pm			= p->pm;
 		port.dev		= &dev->dev;
 		port.irqflags		|= irqflag;
+{
+		struct dw8250_data *data = devm_kzalloc(&dev->dev, sizeof(*data), GFP_KERNEL);
+		if (!data)
+			return -ENOMEM;
+		port.private_data = data;
+}
 		ret = serial8250_register_port(&port);
 		if (ret < 0) {
 			dev_err(&dev->dev, "unable to register port at index %d "
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/usb/core/generic.c linux-linaro-3.4-2012.05-1_cavium/drivers/usb/core/generic.c
--- linux-linaro-3.4-2012.05-1_original/drivers/usb/core/generic.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/usb/core/generic.c	2014-07-29 17:28:38.819972000 +0800
@@ -149,6 +149,7 @@
 		dev_warn(&udev->dev,
 			"no configuration chosen from %d choice%s\n",
 			num_configs, plural(num_configs));
+		dev_warn(&udev->dev, "Not support over %dmA\n", udev->bus_mA);
 	}
 	return i;
 }
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/usb/core/hcd.c linux-linaro-3.4-2012.05-1_cavium/drivers/usb/core/hcd.c
--- linux-linaro-3.4-2012.05-1_original/drivers/usb/core/hcd.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/usb/core/hcd.c	2014-07-29 17:28:38.819972000 +0800
@@ -615,6 +615,9 @@
 		case DeviceRequest | USB_REQ_GET_DESCRIPTOR:
 			/* len is returned by hub_control */
 			break;
+		case SetandTestPortFeature:
+			len = 1;
+			break;
 		}
 		status = hcd->driver->hub_control (hcd,
 			typeReq, wValue, wIndex,
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/usb/core/hub.c linux-linaro-3.4-2012.05-1_cavium/drivers/usb/core/hub.c
--- linux-linaro-3.4-2012.05-1_original/drivers/usb/core/hub.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/usb/core/hub.c	2014-07-29 17:28:38.819972000 +0800
@@ -1669,6 +1669,14 @@
 	struct usb_device	*udev = *pdev;
 	int			i;
 
+#ifdef	CONFIG_USB_SNPS_DWC_OTG2
+	if (work_pending(&udev->hnp_poll_work.work)) {
+		while (!cancel_delayed_work(&udev->hnp_poll_work)) {
+			msleep(10);
+		}
+	}
+#endif
+
 	/* mark the device as inactive, so any further urb submissions for
 	 * this device (and any of its children) will fail immediately.
 	 * this quiesces everything except pending urbs.
@@ -1744,7 +1752,65 @@
 #endif
 
 #ifdef	CONFIG_USB_OTG
+static int enable_whitelist = 0;
+module_param(enable_whitelist, bool, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(enable_whitelist,
+                 "only recognize devices in OTG whitelist if true");
+
 #include "otg_whitelist.h"
+
+#ifdef CONFIG_USB_SNPS_DWC_OTG2
+int usb_port_suspend(struct usb_device *udev, pm_message_t msg);
+static void hnp_poll_timeout(struct work_struct* w)
+{
+	struct usb_device *udev = container_of(w, struct usb_device, hnp_poll_work.work);
+	uint8_t otgstatus;
+	int ret;
+	int err;
+	
+	ret = usb_control_msg(udev, 
+			usb_rcvctrlpipe(udev, 0),
+			USB_REQ_GET_STATUS,
+			USB_DIR_IN | USB_RECIP_DEVICE,
+			0,
+			0xF000,
+			&otgstatus,
+			sizeof(otgstatus),
+			USB_CTRL_GET_TIMEOUT);
+
+	printk("otgstatus - 0x%4X\n", otgstatus);
+	
+	if(ret == sizeof(otgstatus) && (otgstatus & 0x1)){
+	    /* enable HNP before suspend, it's simpler */
+	    if (udev->portnum == udev->bus->otg_port) 
+			udev->bus->b_hnp_enable = 1;
+			err = usb_control_msg(udev,
+				usb_sndctrlpipe(udev, 0),
+				USB_REQ_SET_FEATURE, 0,
+				udev->bus->b_hnp_enable
+				? USB_DEVICE_B_HNP_ENABLE
+				: USB_DEVICE_A_ALT_HNP_SUPPORT,
+				0, NULL, 0, USB_CTRL_SET_TIMEOUT);
+
+		printk("SET FEATURE B_HNP_ENABLE %d\n",err);
+		
+	    if (err < 0) {
+		/* OTG MESSAGE: report errors here,
+ * 		 * customize to match your product.
+ * 		 		 */
+			dev_info(&udev->dev, "can't set HNP mode; %d\n", err);
+			dev_printk(KERN_CRIT, &udev->dev, 
+						"Device Not Connected/Responding\n");
+			udev->bus->b_hnp_enable = 0;
+	    }
+	    if (usb_port_suspend(udev, PMSG_SUSPEND) < 0) {
+			dev_dbg(&udev->dev, "HNP fail, %d\n", err);
+	    }
+	} else {
+	    schedule_delayed_work(&udev->hnp_poll_work, 1*HZ);
+	}
+}
+#endif
 #endif
 
 /**
@@ -1773,14 +1839,29 @@
 		if (__usb_get_extra_descriptor (udev->rawdescriptors[0],
 					le16_to_cpu(udev->config[0].desc.wTotalLength),
 					USB_DT_OTG, (void **) &desc) == 0) {
+			/* Check if the device supports HNP and start HNP polling if needed */
 			if (desc->bmAttributes & USB_OTG_HNP) {
 				unsigned		port1 = udev->portnum;
+#ifdef CONFIG_USB_SNPS_DWC_OTG2			
+				/* Start HNP Polling for OTG 2.0. */
+				if ((desc->bcdOTG >= 0x0200) &&
+					(bus->otg_version >= 0x0200)) {
 
 				dev_info(&udev->dev,
-					"Dual-Role OTG device on %sHNP port\n",
+					"Dual-Role OTG 2.0 device on %sHNP port\n",
+					(port1 == bus->otg_port)
+						? "" : "non-");
+					if (port1 == bus->otg_port) {
+						INIT_DELAYED_WORK(&udev->hnp_poll_work, hnp_poll_timeout);
+						schedule_delayed_work(&udev->hnp_poll_work, HZ);
+					}
+					goto done_hnp;
+				}
+#endif
+				dev_info(&udev->dev,
+					"Dual-Role OTG 1.3 device on %sHNP port\n",
 					(port1 == bus->otg_port)
 						? "" : "non-");
-
 				/* enable HNP before suspend, it's simpler */
 				if (port1 == bus->otg_port)
 					bus->b_hnp_enable = 1;
@@ -1798,23 +1879,42 @@
 					dev_info(&udev->dev,
 						"can't set HNP mode: %d\n",
 						err);
+					dev_printk(KERN_CRIT, &udev->dev, 
+						"Device Not Connected/Responding\n");
 					bus->b_hnp_enable = 0;
-				}
+				} else 
+					dev_info(&udev->dev, "HNP Not Supported\n");
 			}
 		}
 	}
-
+#ifdef CONFIG_USB_SNPS_DWC_OTG2
+done_hnp:
+#endif
 	if (!is_targeted(udev)) {
 
 		/* Maybe it can talk to us, though we can't talk to it.
 		 * (Includes HNP test device.)
 		 */
-		if (udev->bus->b_hnp_enable || udev->bus->is_b_host) {
+		if (udev->bus->b_hnp_enable || udev->bus->is_b_host ||
+                    udev->descriptor.idVendor == 0x1a0a) {
 			err = usb_port_suspend(udev, PMSG_SUSPEND);
 			if (err < 0)
 				dev_dbg(&udev->dev, "HNP fail, %d\n", err);
+			else {
+				/* Return Connection Refused(ECONNREFUSED)
+				* instead of Not Supported(ENOTSUPP) so that the
+ 				* retry loop in hub_port_connect_change() is
+				* exited without disabling the port
+				*/
+			    err = -ECONNREFUSED;
+			    goto fail;
+			}
 		}
-		err = -ENOTSUPP;
+		/* Return Not Connected (ENOTCONN) instead of Not 
+		 * Supported(ENOTSUPP) so that the retry loop in 
+ 		 * hub_port_connect_change() is exited
+ 		 */
+		err = -ENOTCONN;
 		goto fail;
 	}
 fail:
@@ -3530,14 +3630,15 @@
 		return;
 
 loop_disable:
+		if(status != -ECONNREFUSED)
 		hub_port_disable(hub, port1, 1);
 loop:
 		usb_ep0_reinit(udev);
 		release_devnum(udev);
 		hub_free_dev(udev);
 		usb_put_dev(udev);
-		if ((status == -ENOTCONN) || (status == -ENOTSUPP))
-			break;
+		if (status == -ENOTCONN || status == -ECONNREFUSED)
+			return;
 	}
 	if (hub->hdev->parent ||
 			!hcd->driver->port_handed_over ||
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/usb/core/message.c linux-linaro-3.4-2012.05-1_cavium/drivers/usb/core/message.c
--- linux-linaro-3.4-2012.05-1_original/drivers/usb/core/message.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/usb/core/message.c	2014-07-29 17:28:38.819972000 +0800
@@ -1838,6 +1838,86 @@
 			!(dev->quirks & USB_QUIRK_CONFIG_INTF_STRINGS))
 		cp->string = usb_cache_string(dev, cp->desc.iConfiguration);
 
+/* Uncomment this define to enable the HS Electrical Test support */
+#define DWC_HS_ELECT_TST 1
+#ifdef DWC_HS_ELECT_TST
+	/* Here we implement the HS Electrical Test support. The
+	 * tester uses a vendor ID of 0x1A0A to indicate we should
+	 * run a special test sequence. The product ID tells us
+	 * which sequence to run. We invoke the test sequence by
+	 * sending a non-standard SetFeature command to our root
+	 * hub port. Our dwc_otg_hcd_hub_control() routine will
+	 * recognize the command and perform the desired test
+	 * sequence.
+	 */
+	if (dev->descriptor.idVendor == 0x1A0A) {
+		/* HSOTG Electrical Test */
+		dev_warn(&dev->dev, "VID from HSOTG Electrical Test Fixture\n");
+
+		if (dev->bus && dev->bus->root_hub) {
+			struct usb_device *hdev = dev->bus->root_hub;
+			dev_warn(&dev->dev, "Got PID 0x%x\n", dev->descriptor.idProduct);
+
+			switch (dev->descriptor.idProduct) {
+			case 0x0101:	/* TEST_SE0_NAK */
+				dev_warn(&dev->dev, "TEST_SE0_NAK\n");
+				usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0),
+					USB_REQ_SET_FEATURE, USB_RT_PORT,
+					USB_PORT_FEAT_TEST, 0x300, NULL, 0, HZ);
+				break;
+
+			case 0x0102:	/* TEST_J */
+				dev_warn(&dev->dev, "TEST_J\n");
+				usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0),
+					USB_REQ_SET_FEATURE, USB_RT_PORT,
+					USB_PORT_FEAT_TEST, 0x100, NULL, 0, HZ);
+				break;
+
+			case 0x0103:	/* TEST_K */
+				dev_warn(&dev->dev, "TEST_K\n");
+				usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0),
+					USB_REQ_SET_FEATURE, USB_RT_PORT,
+					USB_PORT_FEAT_TEST, 0x200, NULL, 0, HZ);
+				break;
+
+			case 0x0104:	/* TEST_PACKET */
+				dev_warn(&dev->dev, "TEST_PACKET\n");
+				usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0),
+					USB_REQ_SET_FEATURE, USB_RT_PORT,
+					USB_PORT_FEAT_TEST, 0x400, NULL, 0, HZ);
+				break;
+
+			case 0x0105:	/* TEST_FORCE_ENABLE */
+				dev_warn(&dev->dev, "TEST_FORCE_ENABLE\n");
+				usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0),
+					USB_REQ_SET_FEATURE, USB_RT_PORT,
+					USB_PORT_FEAT_TEST, 0x500, NULL, 0, HZ);
+				break;
+
+			case 0x0106:	/* HS_HOST_PORT_SUSPEND_RESUME */
+				dev_warn(&dev->dev, "HS_HOST_PORT_SUSPEND_RESUME\n");
+				usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0),
+					USB_REQ_SET_FEATURE, USB_RT_PORT,
+					USB_PORT_FEAT_TEST, 0x600, NULL, 0, 40 * HZ);
+				break;
+
+			case 0x0107:	/* SINGLE_STEP_GET_DEVICE_DESCRIPTOR setup */
+				dev_warn(&dev->dev, "SINGLE_STEP_GET_DEVICE_DESCRIPTOR setup\n");
+				usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0),
+					USB_REQ_SET_FEATURE, USB_RT_PORT,
+					USB_PORT_FEAT_TEST, 0x700, NULL, 0, 40 * HZ);
+				break;
+
+			case 0x0108:	/* SINGLE_STEP_GET_DEVICE_DESCRIPTOR execute */
+				dev_warn(&dev->dev, "SINGLE_STEP_GET_DEVICE_DESCRIPTOR execute\n");
+				usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0),
+					USB_REQ_SET_FEATURE, USB_RT_PORT,
+					USB_PORT_FEAT_TEST, 0x800, NULL, 0, 40 * HZ);
+				}
+			}
+		}
+#endif /* DWC_HS_ELECT_TST */
+
 	/* Now that all the interfaces are set up, register them
 	 * to trigger binding of drivers to interfaces.  probe()
 	 * routines may install different altsettings and may
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/usb/core/otg_whitelist.h linux-linaro-3.4-2012.05-1_cavium/drivers/usb/core/otg_whitelist.h
--- linux-linaro-3.4-2012.05-1_original/drivers/usb/core/otg_whitelist.h	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/usb/core/otg_whitelist.h	2014-07-29 17:28:38.819972000 +0800
@@ -19,33 +19,67 @@
 static struct usb_device_id whitelist_table [] = {
 
 /* hubs are optional in OTG, but very handy ... */
+#define CERT_WITHOUT_HUBS
+#if defined(CERT_WITHOUT_HUBS)
+{ USB_DEVICE( 0x0000, 0x0000 ), }, /* Root HUB Only*/
+/* 
+ * These are for root hub and should be recognised always, 
+ * so correct it according to your system...
+ */
+{ USB_DEVICE( 0x1d6b, 0x0001 ), }, /* Root HUB Only*/
+{ USB_DEVICE( 0x1d6b, 0x0002 ), }, /* Root HUB Only*/
+#else
 { USB_DEVICE_INFO(USB_CLASS_HUB, 0, 0), },
 { USB_DEVICE_INFO(USB_CLASS_HUB, 0, 1), },
+{ USB_DEVICE_INFO(USB_CLASS_HUB, 0, 2), },
+#endif
 
 #ifdef	CONFIG_USB_PRINTER		/* ignoring nonstatic linkage! */
 /* FIXME actually, printers are NOT supposed to use device classes;
  * they're supposed to use interface classes...
  */
-{ USB_DEVICE_INFO(7, 1, 1) },
-{ USB_DEVICE_INFO(7, 1, 2) },
-{ USB_DEVICE_INFO(7, 1, 3) },
+//{ USB_DEVICE_INFO(7, 1, 1) },
+//{ USB_DEVICE_INFO(7, 1, 2) },
+//{ USB_DEVICE_INFO(7, 1, 3) },
 #endif
 
 #ifdef	CONFIG_USB_NET_CDCETHER
 /* Linux-USB CDC Ethernet gadget */
-{ USB_DEVICE(0x0525, 0xa4a1), },
+//{ USB_DEVICE(0x0525, 0xa4a1), },
 /* Linux-USB CDC Ethernet + RNDIS gadget */
-{ USB_DEVICE(0x0525, 0xa4a2), },
+//{ USB_DEVICE(0x0525, 0xa4a2), },
 #endif
 
 #if	defined(CONFIG_USB_TEST) || defined(CONFIG_USB_TEST_MODULE)
 /* gadget zero, for testing */
-{ USB_DEVICE(0x0525, 0xa4a0), },
+//{ USB_DEVICE(0x0525, 0xa4a0), },
 #endif
 
+{ USB_DEVICE( 0x1a0a, 0x0101 ), }, /* TEST_SE0_NAK */
+{ USB_DEVICE( 0x1a0a, 0x0102 ), }, /* Test_J */
+{ USB_DEVICE( 0x1a0a, 0x0103 ), }, /* Test_K */
+{ USB_DEVICE( 0x1a0a, 0x0104 ), }, /* Test_PACKET */
+{ USB_DEVICE( 0x1a0a, 0x0105 ), }, /* Test_FORCE_ENABLE */
+{ USB_DEVICE( 0x1a0a, 0x0106 ), }, /* HS_PORT_SUSPEND_RESUME  */
+{ USB_DEVICE( 0x1a0a, 0x0107 ), }, /* SINGLE_STEP_GET_DESCRIPTOR setup */
+{ USB_DEVICE( 0x1a0a, 0x0108 ), }, /* SINGLE_STEP_GET_DESCRIPTOR execute */
+{ USB_DEVICE_VER(0x054c,0x0010,0x0410, 0x0500), },
+{ USB_DEVICE( 0x0EA0, 0x2168 ), }, /* Ours Technology Inc. (BUFFALO ClipDrive)*/
 { }	/* Terminating entry */
 };
 
+static inline void report_errors(struct usb_device *dev)
+{
+	dev_info(&dev->dev, "device Vendor:%04x Product:%04x is not supported\n",
+		 le16_to_cpu(dev->descriptor.idVendor),
+		 le16_to_cpu(dev->descriptor.idProduct));
+        if (USB_CLASS_HUB == dev->descriptor.bDeviceClass){
+                dev_printk(KERN_CRIT, &dev->dev, "Unsupported Hub Topology\n");
+        } else {        
+                dev_printk(KERN_CRIT, &dev->dev, "Attached Device is not Supported\n");
+        }
+}
+
 static int is_targeted(struct usb_device *dev)
 {
 	struct usb_device_id	*id = whitelist_table;
@@ -56,13 +90,33 @@
 
 	/* HNP test device is _never_ targeted (see OTG spec 6.6.6) */
 	if ((le16_to_cpu(dev->descriptor.idVendor) == 0x1a0a &&
-	     le16_to_cpu(dev->descriptor.idProduct) == 0xbadd))
+	     le16_to_cpu(dev->descriptor.idProduct) == 0xbadd)) {
 		return 0;
+	} else if (!enable_whitelist) {
+		return 1;
+        } else {
+#ifdef DEBUG
+                dev_dbg(&dev->dev, "device V:%04x P:%04x DC:%04x SC:%04x PR:%04x \n",
+                        dev->descriptor.idVendor,
+                        dev->descriptor.idProduct,
+                        dev->descriptor.bDeviceClass,
+                        dev->descriptor.bDeviceSubClass,
+                        dev->descriptor.bDeviceProtocol);
+#endif
 
 	/* NOTE: can't use usb_match_id() since interface caches
 	 * aren't set up yet. this is cut/paste from that code.
 	 */
 	for (id = whitelist_table; id->match_flags; id++) {
+#ifdef DEBUG
+		dev_dbg(&dev->dev, 
+			"ID: V:%04x P:%04x DC:%04x SC:%04x PR:%04x \n",
+			id->idVendor,
+			id->idProduct,
+			id->bDeviceClass,
+			id->bDeviceSubClass,
+			id->bDeviceProtocol);
+#endif
 		if ((id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) &&
 		    id->idVendor != le16_to_cpu(dev->descriptor.idVendor))
 			continue;
@@ -95,6 +149,7 @@
 
 		return 1;
 	}
+	}
 
 	/* add other match criteria here ... */
 
@@ -104,9 +159,15 @@
 		le16_to_cpu(dev->descriptor.idVendor),
 		le16_to_cpu(dev->descriptor.idProduct));
 #ifdef	CONFIG_USB_OTG_WHITELIST
+	report_errors(dev);
 	return 0;
 #else
-	return 1;
+	if (enable_whitelist) {
+		report_errors(dev);
+		return 0;
+	} else {
+		return 1;
+	}
 #endif
 }
 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/usb/gadget/f_hid.c linux-linaro-3.4-2012.05-1_cavium/drivers/usb/gadget/f_hid.c
--- linux-linaro-3.4-2012.05-1_original/drivers/usb/gadget/f_hid.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/usb/gadget/f_hid.c	2014-07-29 17:28:38.819972000 +0800
@@ -34,6 +34,9 @@
 	char				*report_desc;
 	unsigned short			report_length;
 
+	char                            feature_report[10][257];
+	unsigned short                  feature_report_length[10];
+
 	/* recv report */
 	char				*set_report_buff;
 	unsigned short			set_report_length;
@@ -50,6 +53,7 @@
 	struct cdev			cdev;
 	struct usb_function		func;
 	struct usb_ep			*in_ep;
+    unsigned char           config_status;
 };
 
 static inline struct f_hidg *func_to_hidg(struct usb_function *f)
@@ -90,7 +94,7 @@
 	.bEndpointAddress	= USB_DIR_IN,
 	.bmAttributes		= USB_ENDPOINT_XFER_INT,
 	/*.wMaxPacketSize	= DYNAMIC */
-	.bInterval		= 4, /* FIXME: Add this field in the
+	.bInterval		= 1, /* FIXME: Add this field in the
 				      * HID gadget configuration?
 				      * (struct hidg_func_descriptor)
 				      */
@@ -200,13 +204,18 @@
 
 	/* write queue */
 	while (!WRITE_COND) {
+                long wait_return;
+
 		mutex_unlock(&hidg->lock);
 		if (file->f_flags & O_NONBLOCK)
 			return -EAGAIN;
-
-		if (wait_event_interruptible_exclusive(
-				hidg->write_queue, WRITE_COND))
+		
+                wait_return = wait_event_interruptible_timeout(hidg->write_queue, WRITE_COND, 10/*ms*/);
+               
+                if (wait_return == -ERESTARTSYS)
 			return -ERESTARTSYS;
+                else if (wait_return == 0)
+                        return -EAGAIN;
 
 		mutex_lock(&hidg->lock);
 	}
@@ -278,6 +287,31 @@
 
 	return 0;
 }
+static long f_hidg_ioctl(struct file *fd, unsigned int code, unsigned long arg)
+{
+    struct f_hidg   *hidg  = fd->private_data;
+    unsigned long       flags;
+    int         status = 0;
+    
+    //printk("f_hidg_ioctl: cmd=0x%4.4x, arg=%lu\n", code, arg);
+    
+    /* handle ioctls */
+    spin_lock_irqsave(&hidg->spinlock, flags);
+    
+    switch (code) {
+        case GET_GADGET_HID_DEVICE_CONFIG_STATUS:
+            printk(KERN_DEBUG "\nhidg->config_status : %d\n", hidg->config_status);
+            copy_to_user((void __user *)arg, (const void *)&hidg->config_status, sizeof(hidg->config_status));
+            break;
+        default:
+            /* could not handle ioctl */
+            printk("f_hidg_ioctl: ERROR cmd=0x%4.4xis not supported\n", code);
+            status = -ENOTTY;
+    }
+    
+    spin_unlock_irqrestore(&hidg->spinlock, flags);
+    return status;
+}
 
 /*-------------------------------------------------------------------------*/
 /*                                usb_function                             */
@@ -328,9 +362,22 @@
 		  | HID_REQ_GET_REPORT):
 		VDBG(cdev, "get_report\n");
 
+#ifdef CONFIG_USB_G_HID_MULTITOUCH
+		if (hidg->feature_report_length[value & 0xff]) {
+                        length = min_t(unsigned, length, hidg->feature_report_length[value & 0xff]);
+                        VDBG(cdev,"Found feature report of length %d for report id %d\n", hidg->feature_report_length[value & 0xff], value&0xff);
+                        memcpy(req->buf, &hidg->feature_report[value & 0xff], length);
+                } else {
+                        VDBG(cdev,"Couldn't find a feature report for %d of length <= %d\n", value & 0xff, length);
+                        /* send an empty report */
+                        length = min_t(unsigned, length, hidg->report_length);
+                        memset(req->buf, 0x0, length);
+                }
+#else
 		/* send an empty report */
 		length = min_t(unsigned, length, hidg->report_length);
 		memset(req->buf, 0x0, length);
+#endif
 
 		goto respond;
 		break;
@@ -344,6 +391,12 @@
 	case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8
 		  | HID_REQ_SET_REPORT):
 		VDBG(cdev, "set_report | wLenght=%d\n", ctrl->wLength);
+
+                length = min_t(unsigned, length, sizeof(hidg->feature_report[value & 0xff]));
+                VDBG(cdev,"Received feature report of length %d for report id %d\n", length, value&0xff);
+                memcpy(&hidg->feature_report[value & 0xff], req->buf, length);
+                hidg->feature_report_length[value & 0xff] = length;
+
 		req->context  = hidg;
 		req->complete = hidg_set_report_complete;
 		goto respond;
@@ -381,9 +434,20 @@
 		}
 		break;
 
+	case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8
+		  | USB_REQ_GET_INTERFACE):
+        VDBG(cdev,"USB_REQ_GET_INTERFACE : Assuming Request for Interface Number\n");
+        //VDBG(cdev,"Requested Length : %d\n", length);
+        *(u8 *)req->buf = hidg->minor; 
+        /* Under the assumption that Interface Detail Request comes from Host at end of setup process
+         * Marking Configuration Status as Done. 
+         * TODO : Need to come up with better mechanism to detect setup/configuration completion   
+         */ 
+        hidg->config_status =  CONFIG_DONE;
+        goto respond;
+        break;
 	default:
-		VDBG(cdev, "Unknown request 0x%x\n",
-			 ctrl->bRequest);
+		printk("Unknown Request Type : 0x%2x or Request 0x%2x\n", (ctrl->bRequestType << 8), ctrl->bRequest);
 		goto stall;
 		break;
 	}
@@ -446,6 +510,7 @@
 	.read		= f_hidg_read,
 	.poll		= f_hidg_poll,
 	.llseek		= noop_llseek,
+    .unlocked_ioctl = f_hidg_ioctl,
 };
 
 static int __init hidg_bind(struct usb_configuration *c, struct usb_function *f)
@@ -616,6 +681,9 @@
 		return -ENOMEM;
 	}
 
+        memcpy(hidg->feature_report_length, fdesc->feature_report_length, sizeof(hidg->feature_report_length));
+        memcpy(hidg->feature_report, fdesc->feature_report, sizeof(hidg->feature_report));
+
 	hidg->func.name    = "hid";
 	hidg->func.strings = ct_func_strings;
 	hidg->func.bind    = hidg_bind;
@@ -623,10 +691,13 @@
 	hidg->func.set_alt = hidg_set_alt;
 	hidg->func.disable = hidg_disable;
 	hidg->func.setup   = hidg_setup;
+    hidg->config_status =  CONFIG_NOT_DONE;
 
 	status = usb_add_function(c, &hidg->func);
-	if (status)
+	if (status) {
+		kfree(hidg->report_desc);
 		kfree(hidg);
+        }
 
 	return status;
 }
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/usb/gadget/file_storage.c linux-linaro-3.4-2012.05-1_cavium/drivers/usb/gadget/file_storage.c
--- linux-linaro-3.4-2012.05-1_original/drivers/usb/gadget/file_storage.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/usb/gadget/file_storage.c	2014-07-29 17:28:38.819972000 +0800
@@ -572,9 +572,47 @@
 	.bConfigurationValue =	CONFIG_VALUE,
 	.iConfiguration =	FSG_STRING_CONFIG,
 	.bmAttributes =		USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
-	.bMaxPower =		CONFIG_USB_GADGET_VBUS_DRAW / 2,
+//	.bMaxPower =		CONFIG_USB_GADGET_VBUS_DRAW / 2,
+	.bMaxPower =		0,	// self-powered
 };
 
+#ifdef CONFIG_USB_DWC_OTG_LPM
+
+/* USB_DT_BOS:  group of wireless capabilities */
+struct bos_desc {
+	__u8  bLength;
+	__u8  bDescriptorType;
+
+	__le16 wTotalLength;
+	__u8  bNumDeviceCaps;
+} __attribute__ ((__packed__));
+
+struct usb20_ext_cap_desc {
+            __u8 bLength;
+            __u8 bDescriptorType;
+            __u8 bDevCapabilityType;
+            __le32 bmAttributes;
+} __attribute__ ((__packed__));
+
+/** The BOS Descriptor */
+#define USB_CAP_20_EXT		0x02
+#define USB_20_EXT_LPM		0x02
+
+static struct usb20_ext_cap_desc cap_lpm = {
+            .bLength = sizeof(struct usb20_ext_cap_desc),
+            .bDescriptorType = USB_DT_DEVICE_CAPABILITY,
+            .bDevCapabilityType = USB_CAP_20_EXT,
+            .bmAttributes = cpu_to_le32(USB_20_EXT_LPM),
+};
+
+static struct bos_desc bos = {
+            .bLength = sizeof(struct bos_desc),
+            .bDescriptorType = USB_DT_BOS,
+            .wTotalLength = cpu_to_le16(sizeof(struct bos_desc) + sizeof(cap_lpm)),
+            .bNumDeviceCaps = 1,
+};
+ 
+#endif
 
 static struct usb_qualifier_descriptor
 dev_qualifier = {
@@ -943,6 +981,17 @@
 		case USB_DT_DEVICE:
 			VDBG(fsg, "get device descriptor\n");
 			device_desc.bMaxPacketSize0 = fsg->ep0->maxpacket;
+#ifdef CONFIG_USB_DWC_OTG_LPM
+                        /* Set the bcdUSB to 0201H to indicate support
+                        * for the BOS Descriptor. */
+                        if (usb_gadget_test_lpm_support(fsg->gadget)) {
+                                VDBG(fsg, "set bcdUSB to 0201h\n");
+                                device_desc.bcdUSB = 0x201;
+                        } else {
+                                VDBG(fsg, "set bcdUSB to 0200h\n");
+                                 device_desc.bcdUSB = 0x200;
+                        }
+#endif
 			value = sizeof device_desc;
 			memcpy(req->buf, &device_desc, value);
 			break;
@@ -956,6 +1005,18 @@
 			 * speeds
 			 */
 			dev_qualifier.bMaxPacketSize0 = fsg->ep0->maxpacket;
+#ifdef CONFIG_USB_DWC_OTG_LPM
+                        /* Set the bcdUSB to 0201H to indicate support
+                        * for the BOS Descriptor. */
+                        if (usb_gadget_test_lpm_support(fsg->gadget)) {
+                                VDBG(fsg, "set bcdUSB to 0201h\n");
+                                dev_qualifier.bcdUSB = 0x201;
+                        } else {
+                                VDBG(fsg, "set bcdUSB to 0200h\n");
+                                 dev_qualifier.bcdUSB = 0x200;
+                        }
+#endif
+
 			value = sizeof dev_qualifier;
 			memcpy(req->buf, &dev_qualifier, value);
 			break;
@@ -989,6 +1050,20 @@
 			if (gadget_is_superspeed(fsg->gadget))
 				value = populate_bos(fsg, req->buf);
 			break;
+#ifdef CONFIG_USB_DWC_OTG_LPM
+		case USB_DT_BOS:
+			if (usb_gadget_test_lpm_support(fsg->gadget)) {
+			        VDBG(fsg, "LPM support enabled in DWC UDC PCD\n");
+                                cap_lpm.bmAttributes |= USB_20_EXT_LPM;
+                        	__u8 *buf = req->buf;
+				VDBG(fsg, "get bos descriptor\n");
+				memcpy(buf, &bos, sizeof bos);
+				buf += sizeof bos;
+				memcpy(buf, &cap_lpm, sizeof cap_lpm);
+				value = sizeof bos + sizeof cap_lpm;
+				break;
+			}
+#endif
 		}
 
 		break;
@@ -3232,7 +3307,13 @@
 		gcnum = usb_gadget_controller_number(fsg->gadget);
 		if (gcnum >= 0)
 			mod_data.release = 0x0300 + gcnum;
-		else {
+		else if (gadget_is_dwc_otg(fsg->gadget)) {
+			mod_data.release = __constant_cpu_to_le16 (0x0200);
+			mod_data.vendor  = __constant_cpu_to_le16 (0x053f);
+			if (mod_data.product == FSG_PRODUCT_ID) {
+				mod_data.product  = __constant_cpu_to_le16 (0x0000);
+			}
+		} else {
 			WARNING(fsg, "controller '%s' not recognized\n",
 				fsg->gadget->name);
 			mod_data.release = 0x0399;
@@ -3493,6 +3574,14 @@
 
 	rc = -ENOMEM;
 
+#ifdef CONFIG_USB_DWC_OTG_LPM
+	/* When LPM is enabled, Inform the host that the remote wake
+ 	 * up capability is supported. */
+	if (usb_gadget_test_lpm_support(fsg->gadget)) {
+		config_desc.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
+	}
+#endif
+
 	/* Allocate the request and buffer for endpoint 0 */
 	fsg->ep0req = req = usb_ep_alloc_request(fsg->ep0, GFP_KERNEL);
 	if (!req)
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/usb/gadget/gadget_chips.h linux-linaro-3.4-2012.05-1_cavium/drivers/usb/gadget/gadget_chips.h
--- linux-linaro-3.4-2012.05-1_original/drivers/usb/gadget/gadget_chips.h	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/usb/gadget/gadget_chips.h	2014-07-29 17:28:38.819972000 +0800
@@ -122,6 +122,11 @@
 	return -ENOENT;
 }
 
+#ifdef CONFIG_USB_GADGET_SNPS_DWC_OTG
+#define        gadget_is_dwc_otg(g)    !strcmp("dwc_otg_pcd", (g)->name)
+#else
+#define        gadget_is_dwc_otg(g)    0
+#endif
 
 /**
  * gadget_supports_altsettings - return true if altsettings work
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/usb/gadget/hid.c linux-linaro-3.4-2012.05-1_cavium/drivers/usb/gadget/hid.c
--- linux-linaro-3.4-2012.05-1_original/drivers/usb/gadget/hid.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/usb/gadget/hid.c	2015-04-29 14:37:06.741752000 +0800
@@ -15,15 +15,14 @@
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
 #include <linux/list.h>
+#include <linux/timex.h>
 
 #define DRIVER_DESC		"HID Gadget"
-#define DRIVER_VERSION		"2010/03/16"
+#define DRIVER_VERSION		"2013/10/11"
 
 /*-------------------------------------------------------------------------*/
-
-#define HIDG_VENDOR_NUM		0x0525	/* XXX NetChip */
+#define HIDG_VENDOR_NUM		0x0525	/* XXX NetChip */ /* TODO: Need to change Vendor Number */
 #define HIDG_PRODUCT_NUM	0xa4ac	/* Linux-USB HID gadget */
-
 /*-------------------------------------------------------------------------*/
 
 /*
@@ -190,6 +189,9 @@
 	strings_dev[STRING_PRODUCT_IDX].id = status;
 	device_desc.iProduct = status;
 
+	device_desc.idVendor = (jiffies >> 16) & 0xFFFF;
+	device_desc.idProduct = (jiffies >> 0) & 0xFFFF;
+
 	/* register our configuration */
 	status = usb_add_config(cdev, &config_driver, do_config);
 	if (status < 0)
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/usb/gadget/Kconfig linux-linaro-3.4-2012.05-1_cavium/drivers/usb/gadget/Kconfig
--- linux-linaro-3.4-2012.05-1_original/drivers/usb/gadget/Kconfig	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/usb/gadget/Kconfig	2014-07-29 17:28:38.819972000 +0800
@@ -943,6 +943,47 @@
 	  Say "y" to link the driver statically, or "m" to build a
 	  dynamically linked module called "g_hid".
 
+config USB_G_HID_KEYBOARD
+        bool "Emulates Generic Keyboard"
+        depends on USB_G_HID
+        default n
+        help
+          This option will add Keyboard to the list of devices 
+          supported through USB back-channel.
+
+config USB_G_HID_MOUSE
+        bool "Emulates Generic Mouse"
+        depends on USB_G_HID
+        default n
+        help
+          This option will add Mouse to the list of devices 
+          supported through USB back-channel.
+
+config USB_G_HID_JOYSTICK
+        bool "Emulates Generic Joystick"
+        depends on USB_G_HID
+        default n
+        help
+          This option will add Joystick to the list of devices 
+          supported through USB back-channel.
+config USB_G_HID_MCU
+        bool "Emulate 1900_FJ_RX's MCU"
+        depends on USB_G_HID
+        default n
+        help
+          This option will add MCU to the list of devices 
+          supported through USB back-channel for Fujitsu's 
+          WILL PC.
+
+config USB_G_HID_MULTITOUCH
+        bool "Emulate 1900_FJ_RX's HID multi-touch"
+        depends on USB_G_HID
+        default n
+        help
+          This option will add eGalax multi-touch panel 
+          to the list of devices supported through USB 
+          back-channel for Fujitsu's WILL PC.
+
 config USB_G_DBGP
 	tristate "EHCI Debug Device Gadget"
 	help
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/usb/gadget/printer.c linux-linaro-3.4-2012.05-1_cavium/drivers/usb/gadget/printer.c
--- linux-linaro-3.4-2012.05-1_original/drivers/usb/gadget/printer.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/usb/gadget/printer.c	2014-07-29 17:28:38.819972000 +0800
@@ -1556,14 +1556,12 @@
 init(void)
 {
 	int status;
-
 	usb_gadget_class = class_create(THIS_MODULE, "usb_printer_gadget");
 	if (IS_ERR(usb_gadget_class)) {
 		status = PTR_ERR(usb_gadget_class);
 		ERROR(dev, "unable to create usb_gadget class %d\n", status);
 		return status;
 	}
-
 	status = alloc_chrdev_region(&g_printer_devno, 0, 1,
 			"USB printer gadget");
 	if (status) {
@@ -1571,14 +1569,12 @@
 		class_destroy(usb_gadget_class);
 		return status;
 	}
-
 	status = usb_gadget_probe_driver(&printer_driver, printer_bind);
 	if (status) {
 		class_destroy(usb_gadget_class);
 		unregister_chrdev_region(g_printer_devno, 1);
 		DBG(dev, "usb_gadget_probe_driver %x\n", status);
 	}
-
 	return status;
 }
 module_init(init);
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/usb/gadget/storage_common.c linux-linaro-3.4-2012.05-1_cavium/drivers/usb/gadget/storage_common.c
--- linux-linaro-3.4-2012.05-1_original/drivers/usb/gadget/storage_common.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/usb/gadget/storage_common.c	2014-07-29 17:28:38.819972000 +0800
@@ -335,6 +335,9 @@
 	.bDescriptorType =	USB_DT_OTG,
 
 	.bmAttributes =		USB_OTG_SRP,
+#ifdef CONFIG_USB_SNPS_DWC_OTG2
+	.bcdOTG =	0x200,
+#endif
 };
 #endif
 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/usb/gadget/udc-core.c linux-linaro-3.4-2012.05-1_cavium/drivers/usb/gadget/udc-core.c
--- linux-linaro-3.4-2012.05-1_original/drivers/usb/gadget/udc-core.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/usb/gadget/udc-core.c	2014-07-29 17:28:38.819972000 +0800
@@ -326,12 +326,12 @@
 		if (!udc->driver)
 			goto found;
 	}
-
 	pr_debug("couldn't find an available UDC\n");
 	mutex_unlock(&udc_lock);
 	return -ENODEV;
 
 found:
+
 	dev_dbg(&udc->dev, "registering UDC driver [%s]\n",
 			driver->function);
 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/usb/host/ehci-platform.c linux-linaro-3.4-2012.05-1_cavium/drivers/usb/host/ehci-platform.c
--- linux-linaro-3.4-2012.05-1_original/drivers/usb/host/ehci-platform.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/usb/host/ehci-platform.c	2014-07-29 17:28:38.819972000 +0800
@@ -18,6 +18,7 @@
  *
  * Licensed under the GNU/GPL. See COPYING for details.
  */
+#include <linux/clk.h>
 #include <linux/platform_device.h>
 #include <linux/usb/ehci_pdriver.h>
 
@@ -75,8 +76,6 @@
 	.relinquish_port	= ehci_relinquish_port,
 	.port_handed_over	= ehci_port_handed_over,
 
-	.update_device		= ehci_update_device,
-
 	.clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
 };
 
@@ -84,6 +83,7 @@
 {
 	struct usb_hcd *hcd;
 	struct resource *res_mem;
+	struct clk *clk;
 	int irq;
 	int err = -ENOMEM;
 
@@ -92,6 +92,15 @@
 	if (usb_disabled())
 		return -ENODEV;
 
+	clk = clk_get(&dev->dev, NULL);
+	if (IS_ERR(clk)) {
+		dev_err(&dev->dev, "failed to get clock\n");
+		return PTR_ERR(clk);
+	}
+
+	clk_prepare(clk);
+	clk_enable(clk);
+
 	irq = platform_get_irq(dev, 0);
 	if (irq < 0) {
 		pr_err("no irq provieded");
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/usb/host/ohci-hcd.c linux-linaro-3.4-2012.05-1_cavium/drivers/usb/host/ohci-hcd.c
--- linux-linaro-3.4-2012.05-1_original/drivers/usb/host/ohci-hcd.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/usb/host/ohci-hcd.c	2014-07-29 17:28:38.819972000 +0800
@@ -1120,6 +1120,7 @@
 #define PLATFORM_DRIVER		ohci_platform_driver
 #endif
 
+
 #if	!defined(PCI_DRIVER) &&		\
 	!defined(PLATFORM_DRIVER) &&	\
 	!defined(OMAP1_PLATFORM_DRIVER) &&	\
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/usb/Kconfig linux-linaro-3.4-2012.05-1_cavium/drivers/usb/Kconfig
--- linux-linaro-3.4-2012.05-1_original/drivers/usb/Kconfig	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/usb/Kconfig	2014-07-29 17:28:38.819972000 +0800
@@ -20,6 +20,8 @@
 	default y if ARCH_CNS3XXX
 	default y if PLAT_SPEAR
 	default y if ARCH_EXYNOS
+	default y if ARCH_CELESTIAL
+
 	# PPC:
 	default y if STB03xxx
 	default y if PPC_MPC52xx
@@ -48,6 +50,7 @@
 	default y if SPARC_LEON
 	default y if ARCH_MMP
 	default y if MACH_LOONGSON1
+	default y if ARCH_CELESTIAL
 	default PCI
 
 # some non-PCI HCDs implement xHCI
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/video/celestial/cnc1900_fb_hw.c linux-linaro-3.4-2012.05-1_cavium/drivers/video/celestial/cnc1900_fb_hw.c
--- linux-linaro-3.4-2012.05-1_original/drivers/video/celestial/cnc1900_fb_hw.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/video/celestial/cnc1900_fb_hw.c	2014-12-04 11:15:33.692449000 +0800
@@ -0,0 +1,559 @@
+
+/*
+ *  linux/drivers/video/celestial/cnc1800l_fb_hw.c -- Cavium celestial frame buffer device
+ *
+ *  Copyright (C) 2011 Cavium
+ *  Author: Xiaodong Fan
+ *
+ *  This file is subject to the terms and conditions of the GNU General Public
+ *  License. See the file COPYING in the main directory of this archive for
+ *  more details.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <asm/uaccess.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+
+#include "cncfb.h"
+#include <mach/cnc1900_df.h>
+//#include <mach/df_reg_def_1900.h>
+//#include <mach/df_reg_fmt_1900.h>
+#include <mach/cnc1900_vpp_reg_def.h>
+#include "cnc19xx_fb_hw.h"
+#include <mach/cnc1900_power_clk.h>
+
+//#define FB_DEBUG
+#ifdef FB_DEBUG
+#define DEBUG(args...) 		\
+ 	do {						\
+        printk(KERN_INFO args); \
+	} while(0)
+#else
+#define DEBUG(args...) do { } while(0)
+#endif
+
+extern CNC_FB_INTERRUPT cncdf_1800_vblank_int[2];
+extern int __Is_TV;
+extern df_reg_para dfreg;
+extern int Get_Outif_Id(int gfx_id);
+extern void __df_update_start(void);
+extern void __df_update_end(void);
+
+extern unsigned int DF_Read(unsigned int addr);
+
+extern void DF_Write(unsigned int addr, unsigned int data);
+extern void DFGfxSetEndian(int GfxId, unsigned int GfxEndian);
+extern void DFGfxEna(int GfxId, int IsEna, int IsRGB2YUVEna);
+extern void DFGfxSetAlpha(int GfxId, unsigned short DefaultAlpha, unsigned short ARGB1555Alpha0, unsigned short ARGB1555Alpha1);
+extern void DFGfxGetAlpha(int GfxId, unsigned short *DefaultAlpha, unsigned short *ARGB1555Alpha0, unsigned short *ARGB1555Alpha1);
+extern void DFGfxColorKeyEna(int GfxId,int IsEna);
+extern void DFGfxSetColorKey(int GfxId, unsigned char KeyRMin, unsigned char KeyRMax, unsigned char KeyGMin, unsigned char KeyGMax, unsigned char KeyBMin, unsigned char KeyBMax);
+extern void DFSetZOrder(int OutIFId, int Gfx1ZOrder, int Gfx2ZOrder, int Video1ZOrder, int Video2ZOrder);
+extern void DFSetBackGroud(int OutIFId, unsigned char BGY, unsigned char BGU, unsigned char BGV);
+extern void DFGfxScalorCoef(void);
+extern void DFGfxOpaqueOnOff(int GfxId,int OnOff);
+extern void DFGfxConfigDistrect(int GfxId, unsigned int startx, unsigned int starty, unsigned int endx, unsigned int endy);
+
+//#define DF_GFX_Read(addr) (printk("df gfx addr=0x%x\n", addr),DF_Read(addr))
+#define DF_GFX_Read(addr) (DF_Read(addr))
+
+typedef enum _DF_GFX_COLOR_FORMAT_
+{
+	DF_GFX_CLUT4     = 0,
+	DF_GFX_CLUT8     = 1,
+	DF_GFX_RGB565    = 2,
+	DF_GFX_ARGB4444  = 3,
+	DF_GFX_A0        = 4,
+	DF_GFX_ARGB1555  = 5,
+	DF_GFX_ARGB8888  = 6,
+	DF_GFX_XRGB8888  = 7,
+	DF_GFX_FORMA_MAX,
+
+} DF_GFX_COLOR_FORMAT;
+#if 0
+static int dfreg_gfx[2][13] =
+{
+	{DISP_GFX1_CTRL,	//=0
+	DISP_GFX1_FORMAT,	//=1
+	DISP_GFX1_ALPHA_CTRL,	//=2
+	DISP_GFX1_KEY_RED,	//=3
+	DISP_GFX1_KEY_BLUE,	//=4
+	DISP_GFX1_KEY_GREEN,	//=5
+	DISP_GFX1_BUF_START,	//=6
+	DISP_GFX1_LINE_PITCH,	//=7
+	DISP_GFX1_X_POSITON,	//=8
+	DISP_GFX1_Y_POSITON,	//=9
+	},
+	{DISP_GFX2_CTRL,
+	DISP_GFX2_FORMAT,
+	DISP_GFX2_ALPHA_CTRL,
+	DISP_GFX2_KEY_RED,
+	DISP_GFX2_KEY_BLUE,
+	DISP_GFX2_KEY_GREEN,
+	DISP_GFX2_BUF_START,
+	DISP_GFX2_LINE_PITCH,
+	DISP_GFX2_X_POSITON,
+	DISP_GFX2_Y_POSITON,
+	},
+};
+#endif
+static int dfreg_gfx[2][14] =
+{
+	{
+	VPP_REG_GFX_UI1_CTRL,    //0
+	VPP_REG_GFX_UI1_ALPHA_CTRL,   // 1
+	VPP_REG_GFX_UI1_SIZE,   // 2
+	VPP_REG_GFX_UI1_KEY_RED,  // 3
+	VPP_REG_GFX_UI1_KEY_BLUE,  // 4
+	VPP_REG_GFX_UI1_KEY_GREEN,  // 5
+	VPP_REG_GFX_UI1_BUF_START,   // 6
+	VPP_REG_GFX_UI1_LINE_PITCH,   // 7
+	VPP_REG_GFX_UI1_X_POSITON,   // 8
+	VPP_REG_GFX_UI1_Y_POSITON,   // 9
+	VPP_REG_GFX_UI1_BUF_START_3D,  // 10
+	VPP_REG_GFX_UI1_A8,    // 11
+	VPP_REG_GFX_UI1_PHASE,   // 12
+	VPP_REG_GFX_UI1_COEFF_GID,   // 13
+	},
+	{
+	VPP_REG_GFX_UI2_CTRL,
+	VPP_REG_GFX_UI2_ALPHA_CTRL,
+	VPP_REG_GFX_UI2_SIZE,
+	VPP_REG_GFX_UI2_KEY_RED,
+	VPP_REG_GFX_UI2_KEY_BLUE,
+	VPP_REG_GFX_UI2_KEY_GREEN,
+	VPP_REG_GFX_UI2_BUF_START,
+	VPP_REG_GFX_UI2_LINE_PITCH,
+	VPP_REG_GFX_UI2_X_POSITON,
+	VPP_REG_GFX_UI2_Y_POSITON,
+	VPP_REG_GFX_UI2_BUF_START_3D,
+	VPP_REG_GFX_UI2_A8,
+	VPP_REG_GFX_UI2_PHASE,
+	VPP_REG_GFX_UI2_COEFF_GID,
+	},
+};
+
+
+
+/************************************* FUNCTION *****************************************/
+static unsigned int coefffirst=1;
+#ifdef CONFIG_ANDROID_FB0_ONLY
+unsigned int firsttime=1;
+#endif
+int update_gfx_layer(struct fb_info *info, int init, struct cnc_info * cncfbinfo)
+{
+	unsigned int outif_id = 0;
+	int i_node = info->node;
+	unsigned int tmp;
+	//printk(KERN_INFO"#### info->node=%d\n\r",info->node);
+        if (i_node > 1) i_node -= 2;
+
+
+	//DEBUG("node=%d: update gfx register!\n", info->node);
+	__df_update_start();
+
+	/* if info->node > 1,  only update gfx color format */
+	if (info->node == 2 || info->node == 3) {
+
+		dfreg.Gfx[info->node -2].reg_gfx_ui_ctrl.val=DF_GFX_Read(dfreg_gfx[info->node -2][0]);
+		dfreg.Gfx[info->node -2].reg_gfx_ui_line_pitch.val=DF_GFX_Read(dfreg_gfx[info->node -2][7]);
+
+		dfreg.Gfx[info->node - 2].reg_gfx_ui_ctrl.bits.gfx_ui_format=
+			(info->var.bits_per_pixel == 4) ? DF_GFX_CLUT4 :
+			(info->var.bits_per_pixel == 8) ? DF_GFX_CLUT8 :
+			(info->var.transp.length  == 0) ? DF_GFX_RGB565 :
+			(info->var.transp.length  == 1) ? DF_GFX_ARGB1555 :
+			(info->var.transp.length  == 4) ? DF_GFX_ARGB4444 :
+			(info->var.transp.length  == 8) ? DF_GFX_ARGB8888 :
+			(info->var.transp.length  == 32) ? DF_GFX_A0 :
+			dfreg.Gfx[info->node - 2].reg_gfx_ui_ctrl.bits.gfx_ui_format;
+
+
+		DF_Write((dfreg_gfx[info->node -2][0]), dfreg.Gfx[info->node -2].reg_gfx_ui_ctrl.val);
+        __df_update_end();
+        return 0;
+    }
+
+	dfreg.Gfx[info->node].reg_gfx_ui_ctrl.val = DF_GFX_Read(dfreg_gfx[info->node][0]);
+	dfreg.Gfx[info->node].reg_gfx_ui_buf_start.val = DF_GFX_Read(dfreg_gfx[info->node][6]);
+	dfreg.Gfx[info->node].reg_gfx_ui_line_pitch.val = DF_GFX_Read(dfreg_gfx[info->node][7]);
+	dfreg.Gfx[info->node].reg_gfx_ui_x_position.val = DF_GFX_Read(dfreg_gfx[info->node][8]);
+	dfreg.Gfx[info->node].reg_gfx_ui_y_position.val = DF_GFX_Read(dfreg_gfx[info->node][9]);
+
+
+	dfreg.Gfx[info->node ].reg_gfx_ui_ctrl.bits.gfx_ui_format=
+		(info->var.bits_per_pixel == 4) ? DF_GFX_CLUT4 :
+		(info->var.bits_per_pixel == 8) ? DF_GFX_CLUT8 :
+		(info->var.transp.length == 0) ? DF_GFX_RGB565 :
+		(info->var.transp.length == 1) ? DF_GFX_ARGB1555 :
+		(info->var.transp.length == 4) ? DF_GFX_ARGB4444 :
+		(info->var.transp.length == 8) ? DF_GFX_ARGB8888 :
+		(info->var.transp.length == 32) ? DF_GFX_A0 :
+
+		dfreg.Gfx[info->node ].reg_gfx_ui_ctrl.bits.gfx_ui_format;
+
+	dfreg.Gfx[info->node ].reg_gfx_ui_ctrl.bits.ui_tg1_en=1;
+
+
+	dfreg.Gfx[info->node].reg_gfx_ui_buf_start.val=
+        (info->fix.smem_start +
+         info->fix.line_length * info->var.yoffset +
+         info->var.xoffset * info->var.bits_per_pixel / 8);
+
+	dfreg.Gfx[info->node].reg_gfx_ui_line_pitch.val =  info->fix.line_length;
+#ifdef CONFIG_ANDROID_FB0_ONLY
+    if(firsttime)
+		{
+	          dfreg.Gfx[info->node].reg_gfx_ui_x_position.bits.gfx_ui_dst_x_start = info->var.left_margin;
+	          dfreg.Gfx[info->node].reg_gfx_ui_x_position.bits.gfx_ui_dst_x_end = (info->var.left_margin + info->var.xres) - 1;
+	          dfreg.Gfx[info->node].reg_gfx_ui_y_position.bits.gfx_ui_dst_y_start	=info->var.upper_margin;
+
+	           dfreg.Gfx[info->node].reg_gfx_ui_y_position.bits.gfx_ui_dst_y_end =info->var.upper_margin + info->var.yres;
+			firsttime=0;
+		}
+#else
+	dfreg.Gfx[info->node].reg_gfx_ui_x_position.bits.gfx_ui_dst_x_start = info->var.left_margin;
+	dfreg.Gfx[info->node].reg_gfx_ui_x_position.bits.gfx_ui_dst_x_end = (info->var.left_margin + info->var.xres) - 1;
+	dfreg.Gfx[info->node].reg_gfx_ui_y_position.bits.gfx_ui_dst_y_start	=info->var.upper_margin;
+
+	dfreg.Gfx[info->node].reg_gfx_ui_y_position.bits.gfx_ui_dst_y_end =info->var.upper_margin + info->var.yres;
+#endif
+
+
+	if(init) {
+		DFGfxSetAlpha(info->node, 0xff, 0, 0);
+		DFGfxEna(info->node, 1, __Is_TV);
+		DFGfxSetColorKey(info->node, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
+		DFGfxColorKeyEna(info->node, 1);
+		DFGfxOpaqueOnOff(info->node, 0);
+	}
+
+	 // dfreg.Gfx[info->node].reg_gfx_ui_ctrl.bits.gfx_ui_ena                       = 1;
+   // dfreg.Gfx[info->node].reg_gfx_ui_ctrl.bits.gfx_ui_format                    = UiFormat; // rgb32
+   // dfreg.Gfx[info->node].reg_gfx_ui_ctrl.bits.gfx_ui_endian                    = 0;
+   // dfreg.Gfx[info->node].reg_gfx_ui_ctrl.bits.gfx_ui_opaque                    = 0;
+   // dfreg.Gfx[info->node].reg_gfx_ui_ctrl.bits.gfx_ui_color_keying_en           = 0;
+   // dfreg.Gfx[info->node].reg_gfx_ui_ctrl.bits.gfx_ui_color_keying_en           = 1;
+    dfreg.Gfx[info->node].reg_gfx_ui_ctrl.bits.gfx_ui_ena_premul                = 0;
+    dfreg.Gfx[info->node].reg_gfx_ui_ctrl.bits.gfx_ui_af_sc_dis                 = 0;//scaler
+
+        dfreg.Gfx[info->node].reg_gfx_ui_ctrl.bits.gfx_ui_antiflicker_en_a          = 1;
+        dfreg.Gfx[info->node].reg_gfx_ui_ctrl.bits.gfx_ui_antiflicker_en_c          = 1;
+
+    dfreg.Gfx[info->node].reg_gfx_ui_ctrl.bits.gfx_ui_ena_demul                 = 0;
+    //dfreg.Gfx[info->node].reg_gfx_ui_ctrl.bits.gfx_ui_yuv_conv_ena              = 1;
+    dfreg.Gfx[info->node].reg_gfx_ui_ctrl.bits.gfx_ui_bw_limit                  = 0;
+    dfreg.Gfx[info->node].reg_gfx_ui_ctrl.bits.ui_tg1_en                        = 1; // ui1,ui2 using tg1 switch
+
+
+    dfreg.Gfx[info->node].reg_gfx_ui_size.bits.gfx_ui_src_width                 = info->var.xres;//1920;//ui1_src_width ;
+#ifdef CONFIG_ANDROID_FB0_ONLY
+    dfreg.Gfx[info->node].reg_gfx_ui_size.bits.gfx_ui_src_height                = info->var.yres;
+#else
+    tmp=dfreg.Gfx[info->node].reg_gfx_ui_y_position.bits.gfx_ui_dst_y_end-dfreg.Gfx[info->node].reg_gfx_ui_y_position.bits.gfx_ui_dst_y_start;
+    dfreg.Gfx[info->node].reg_gfx_ui_size.bits.gfx_ui_src_height                =tmp;//1080;//ui1_src_height;
+#endif
+
+    //ui.reg_gfx_ui_alpha_ctrl.bits.gfx_ui_default_alpha       = 200;
+    //dfreg.Gfx[info->node].reg_gfx_ui_alpha_ctrl.bits.gfx_ui_default_alpha       = 255;
+    //dfreg.Gfx[info->node].reg_gfx_ui_alpha_ctrl.bits.gfx_ui_argb1555_a0         = 100;
+    //dfreg.Gfx[info->node].reg_gfx_ui_alpha_ctrl.bits.gfx_ui_argb1555_a1         = 100;
+
+    /*dfreg.Gfx[info->node].reg_gfx_ui_key_red.bits.gfx_ui_r_min                  = 10;
+    dfreg.Gfx[info->node].reg_gfx_ui_key_red.bits.gfx_ui_r_max                  = 200;
+
+    dfreg.Gfx[info->node].reg_gfx_ui_key_green.bits.gfx_ui_g_min                = 10;
+    dfreg.Gfx[info->node].reg_gfx_ui_key_green.bits.gfx_ui_g_max                = 200;
+
+    dfreg.Gfx[info->node].reg_gfx_ui_key_blue.bits.gfx_ui_b_min                 = 10;
+    dfreg.Gfx[info->node].reg_gfx_ui_key_blue.bits.gfx_ui_b_max                 = 200;*/
+
+   //dfreg.Gfx[info->node].reg_gfx_ui_buf_start.bits.gfx_ui_buf_start            = Addr;
+    dfreg.Gfx[info->node].reg_gfx_ui_buf_start_3d.bits.gfx_ui_buf_start_3d      = dfreg.Gfx[info->node].reg_gfx_ui_buf_start.bits.gfx_ui_buf_start ;
+
+    //dfreg.Gfx[info->node].reg_gfx_ui_line_pitch.bits.gfx_ui_line_pitch          = LinePitch; //1920*4; // ????//bytes per line
+
+    //dfreg.Gfx[info->node].reg_gfx_ui_x_position.bits.gfx_ui_dst_x_start         =DesStartPosX;// SrcDstParam.DesStartX;//ui1_dst_x_start; // 10;
+   // dfreg.Gfx[info->node].reg_gfx_ui_x_position.bits.gfx_ui_dst_x_end           = DesEndPosX;//SrcDstParam.DesEndX;//ui1_dst_x_end  ; // 1024-10;
+
+    //dfreg.Gfx[info->node].reg_gfx_ui_y_position.bits.gfx_ui_dst_y_start         = DesStartPosY;//SrcDstParam.DesStartY;//ui1_dst_y_start; // 10;
+    //dfreg.Gfx[info->node].reg_gfx_ui_y_position.bits.gfx_ui_dst_y_end           = DesEndPosY;//SrcDstParam.DesEndY;//ui1_dst_y_end  ; // 720-10;
+
+    dfreg.Gfx[info->node].reg_gfx_ui_a8.bits.gfx_ui_a8_r                        = 100;
+    dfreg.Gfx[info->node].reg_gfx_ui_a8.bits.gfx_ui_a8_g                        = 100;
+    dfreg.Gfx[info->node].reg_gfx_ui_a8.bits.gfx_ui_a8_b                        = 100;
+
+    dfreg.Gfx[info->node].reg_gfx_ui_phase.bits.gfx_ui_hphase                   = 0;
+    dfreg.Gfx[info->node].reg_gfx_ui_phase.bits.gfx_ui_vphase                   = 32;
+
+    dfreg.Gfx[info->node].reg_gfx_ui_coeff_gid.bits.gfx_ui_hcoeff_gid           = 15;
+    dfreg.Gfx[info->node].reg_gfx_ui_coeff_gid.bits.gfx_ui_vcoeff_gid           = 15;
+
+
+	DF_Write((dfreg_gfx[info->node][0]), dfreg.Gfx[info->node].reg_gfx_ui_ctrl.val);
+	DF_Write((dfreg_gfx[info->node][1]), dfreg.Gfx[info->node].reg_gfx_ui_alpha_ctrl.val);
+	DF_Write((dfreg_gfx[info->node][2]), dfreg.Gfx[info->node].reg_gfx_ui_size.val);
+	DF_Write((dfreg_gfx[info->node][3]), dfreg.Gfx[info->node].reg_gfx_ui_key_red.val);
+	DF_Write((dfreg_gfx[info->node][4]), dfreg.Gfx[info->node].reg_gfx_ui_key_blue.val);
+	DF_Write((dfreg_gfx[info->node][5]), dfreg.Gfx[info->node].reg_gfx_ui_key_green.val);
+	DF_Write((dfreg_gfx[info->node][6]), dfreg.Gfx[info->node].reg_gfx_ui_buf_start.val);
+	DF_Write((dfreg_gfx[info->node][7]), dfreg.Gfx[info->node].reg_gfx_ui_line_pitch.val);
+	DF_Write((dfreg_gfx[info->node][8]), dfreg.Gfx[info->node].reg_gfx_ui_x_position.val);
+	DF_Write((dfreg_gfx[info->node][9]), dfreg.Gfx[info->node].reg_gfx_ui_y_position.val);
+	DF_Write((dfreg_gfx[info->node][10]), dfreg.Gfx[info->node].reg_gfx_ui_buf_start_3d.val);
+	DF_Write((dfreg_gfx[info->node][11]), dfreg.Gfx[info->node].reg_gfx_ui_a8.val);
+	DF_Write((dfreg_gfx[info->node][12]), dfreg.Gfx[info->node].reg_gfx_ui_phase.val);
+	//DF_Write((dfreg_gfx[info->node][13]), dfreg.Gfx[info->node].reg_gfx_ui_coeff_gid.val);
+
+        if(coefffirst)
+        {
+	DF_Write((dfreg_gfx[info->node][13]), dfreg.Gfx[info->node].reg_gfx_ui_coeff_gid.val);
+	coefffirst=0;
+        }
+
+	__df_update_end();
+
+	if (i_node > 1) i_node -= 2;
+	outif_id = Get_Outif_Id(i_node);
+
+	if(cncdf_1800_vblank_int[outif_id].is_display == 1){
+		wait_event_interruptible(cncdf_1800_vblank_int[outif_id].wait, cncdf_1800_vblank_int[outif_id].is_display == 0);
+	}
+
+
+	DFGfxScalorCoef();
+	return 0;
+}
+
+int cncfb_hw_init(struct fb_info *info, int en_flags, struct cnc_info * cncfbinfo)
+{
+	int i_node = info->node;
+	if (i_node > 1) i_node -= 2;
+
+	/*clock_gfx_clockena(_clock_enable);temp removed*/
+	clock_gpu_enaclock(_clock_enable);
+	clock_gfx_reset(_do_reset);
+	msleep(5);
+	clock_gfx_reset(_do_set);
+
+	init_waitqueue_head(&cncdf_1800_vblank_int[i_node].wait);
+	cncdf_1800_vblank_int[i_node].is_display = 0;
+	cncdf_1800_vblank_int[i_node].count = 0;
+	cncdf_1800_vblank_int[i_node].cur_fb_info = info;
+
+	if(en_flags){
+		update_gfx_layer(info, en_flags, cncfbinfo);
+	}
+	return 0;
+}
+
+void cncfb_show_logo(struct fb_info *info,struct cnc_info * cncfbinfo)
+{
+	int i_node = info->node;
+	if (i_node > 1) i_node -= 2;
+
+	__df_update_start();
+	DFGfxScalorCoef();
+	DF_Write((dfreg_gfx[i_node][13]),DF_GFX_Read(dfreg_gfx[i_node][13]&0xffffff00)|0xff);
+	 printk(KERN_INFO" ####### set gid to 00000 #########\n");
+	 msleep(1);
+       DF_Write((dfreg_gfx[i_node][13]),DF_GFX_Read(dfreg_gfx[i_node][13]&0xffffff00));
+
+	dfreg.Gfx[info->node].reg_gfx_ui_buf_start.val=
+        (info->fix.smem_start +
+         info->fix.line_length * info->var.yoffset +
+         info->var.xoffset * info->var.bits_per_pixel / 8);
+	DF_Write((dfreg_gfx[info->node][6]), dfreg.Gfx[info->node].reg_gfx_ui_buf_start.val);
+	   __df_update_end();
+}
+
+
+void cncfb_hw_exit(void)
+{
+	return ;
+}
+
+int cncfb_hw_gfx_on(struct fb_info *info, unsigned int arg, struct cnc_info * cncfbinfo)
+{
+	int i_node = info->node;
+	if (i_node > 1) i_node -= 2;
+
+    __df_update_start();
+	DFGfxEna(i_node, arg, __Is_TV);
+	cncfbinfo->fbs_lst[i_node].onoff = arg;
+	if(arg)
+		{
+		DF_Write((dfreg_gfx[i_node][13]),DF_GFX_Read(dfreg_gfx[i_node][13]&0xffffff00)|0xff);
+		 printk(KERN_INFO" ####### set gid to 00000 #########\n");
+                DF_Write((dfreg_gfx[i_node][13]),DF_GFX_Read(dfreg_gfx[i_node][13]&0xffffff00));
+		}
+
+    __df_update_end();
+
+	return 0;
+}
+
+int cncfb_hw_gfx_alpha(struct fb_info *info, unsigned int arg,struct cnc_info * cncfbinfo)
+{
+	int i_node = info->node;
+	if (i_node > 1) i_node -= 2;
+
+	arg &= 0x3ff;
+
+	__df_update_start();
+
+	DFGfxSetAlpha(i_node, arg, 0, 0);
+
+	__df_update_end();
+
+	return 0;
+}
+
+int cncfb_hw_colorkey_on(struct fb_info *info, unsigned int arg, struct cnc_info * cncfbinfo)
+{
+	int i_node = info->node;
+	if (i_node > 1) i_node -= 2;
+
+	__df_update_start();
+
+	DFGfxColorKeyEna(i_node, arg);
+
+	__df_update_end();
+
+	return 0;
+}
+
+
+int cncfb_hw_opaque_onoff(struct fb_info *info, unsigned long arg)
+{
+	int i_node = info->node;
+	if (i_node > 1) i_node -= 2;
+
+	__df_update_start();
+
+	DFGfxOpaqueOnOff(i_node, arg);
+
+	__df_update_end();
+
+	return 0;
+}
+
+int cncfb_hw_config_distrect(struct fb_info *info, gfx_rect *arg)
+{
+	int i_node = info->node;
+	if (i_node > 1) i_node -= 2;
+
+	__df_update_start();
+
+	DFGfxConfigDistrect(i_node, arg->startx, arg->starty, arg->endx, arg->endy);
+
+	__df_update_end();
+
+	return 0;
+}
+
+int cncfb_hw_colorkey_val(struct fb_info *info, gfx_colorkey *col_key, struct cnc_info * cncfbinfo)
+{
+	int i_node = info->node;
+	if (i_node > 1) i_node -= 2;
+
+	__df_update_start();
+
+	DFGfxSetColorKey(i_node, col_key->r_min, col_key->r_max, col_key->g_min, col_key->g_max, col_key->b_min, col_key->b_max);
+
+	__df_update_end();
+
+	return 0;
+}
+
+int cncfb_hw_z_order(struct fb_info *info, unsigned int arg)
+{
+	int Video1ZOrder = (arg >>  0) & 0x3;
+	int Video2ZOrder = (arg >>  4) & 0x3;
+	int Gfx1ZOrder = (arg >> 8) & 0x3;
+	int Gfx2ZOrder = (arg >> 12) & 0x3;
+	int i_node = info->node;
+	if (i_node > 1) i_node -= 2;
+
+	__df_update_start();
+	DFSetZOrder(i_node, Gfx1ZOrder, Gfx2ZOrder, Video1ZOrder, Video2ZOrder);
+	__df_update_end();
+
+	return 0;
+}
+
+int cncfb_hw_set_par(struct fb_info *info, struct cnc_info * cncfbinfo)
+{
+	return update_gfx_layer(info, 0, cncfbinfo);
+}
+
+int cncfb_hw_pan_display(struct fb_info *info, struct cnc_info * cncfbinfo)
+{
+	return update_gfx_layer(info, 0, cncfbinfo);
+}
+
+int cncfb_hw_waitforvsync(struct fb_info *info)
+{
+	unsigned int outif_id = 0;
+	int i_node = info->node;
+
+	if (i_node > 1) i_node -= 2;
+	outif_id = Get_Outif_Id(i_node);
+
+	cncdf_1800_vblank_int[outif_id].is_display = 1;
+
+	return 0;
+}
+
+int cncfb_hw_setbgcolor(struct fb_info *info, unsigned int arg)
+{
+	int i_node = info->node;
+	if (i_node > 1) i_node -= 2;
+	__df_update_start();
+	DFSetBackGroud(i_node, (arg>>16)&0xff,  (arg>>8)&0xff, arg&0xff);
+	__df_update_end();
+	return 0;
+}
+
+int cncfb_hw_setendian(struct fb_info *info, unsigned int arg)
+{
+	int i_node = info->node;
+	if (i_node > 1) i_node -= 2;
+	__df_update_start();
+	DFGfxSetEndian(i_node, arg);
+	__df_update_end();
+	return 0;
+}
+
+int cncfb_hw_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+                         u_int transp, struct fb_info *info, struct cnc_info * cncfbinfo)
+{
+	/* TODO: implement CLUT table updating */
+	return 0;
+}
+
+int cncfb_hw_blank(int blank)
+{
+	/* TODO: to call an external functions from TVE modules */
+	return 0;
+}
+
+void df_writel(int addr, int val)
+{
+	DF_Write(addr, val);
+}
+
+int df_readl(int addr)
+{
+	return DF_GFX_Read(addr);
+}
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/video/celestial/cnc19xx_fb_hw.h linux-linaro-3.4-2012.05-1_cavium/drivers/video/celestial/cnc19xx_fb_hw.h
--- linux-linaro-3.4-2012.05-1_original/drivers/video/celestial/cnc19xx_fb_hw.h	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/video/celestial/cnc19xx_fb_hw.h	2014-12-04 11:15:33.692449000 +0800
@@ -0,0 +1,36 @@
+#ifndef __CNCFB_HW_H__
+#define __CNCFB_HW_H__
+
+void df_writel(int addr, int val);
+int df_readl(int addr);
+
+int cncfb_hw_init(struct fb_info *info, int en_flags, struct cnc_info *);
+void cncfb_hw_exit(void);
+
+int cncfb_hw_set_par(struct fb_info *info, struct cnc_info *);
+int cncfb_hw_pan_display(struct fb_info *info, struct cnc_info *);
+int cncfb_hw_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+                       u_int transp, struct fb_info *info, struct cnc_info *);
+
+int cncfb_hw_blank(int blank);
+int cncfb_hw_waitforvsync(struct fb_info *info);
+
+int cncfb_hw_gfx_on(struct fb_info *info, unsigned int args, struct cnc_info *);
+int cncfb_hw_gfx_alpha(struct fb_info *info, unsigned int args, struct cnc_info *);
+
+int cncfb_hw_z_order(struct fb_info *info,unsigned int arg);
+
+int cncfb_hw_colorkey_val(struct fb_info *info, gfx_colorkey *col_key, struct cnc_info *);
+int cncfb_hw_colorkey_on(struct fb_info *info, unsigned int arg, struct cnc_info *);
+
+
+int cncfb_hw_setbgcolor(struct fb_info *info, unsigned int arg);
+int cncfb_hw_waitforvsync(struct fb_info *info);
+
+int cncfb_hw_opaque_onoff(struct fb_info *info, unsigned long arg);
+int cncfb_hw_config_distrect(struct fb_info * info, gfx_rect * arg);
+
+int cncfb_hw_setendian(struct fb_info *info, unsigned int arg);
+
+void cncfb_show_logo(struct fb_info *info,struct cnc_info * cncfbinfo);
+#endif /* __CNCFB_HW_H__ */
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/video/celestial/cnc_2d.c linux-linaro-3.4-2012.05-1_cavium/drivers/video/celestial/cnc_2d.c
--- linux-linaro-3.4-2012.05-1_original/drivers/video/celestial/cnc_2d.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/video/celestial/cnc_2d.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,2421 @@
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <asm/uaccess.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/proc_fs.h>
+#include <mach/hardware.h>
+
+
+/* color format */
+typedef enum
+{
+	GFX_CF_RGB565      = 0,
+	GFX_CF_ARGB4444    = 1,
+	GFX_CF_A0          = 2,
+	GFX_CF_ARGB1555    = 3,
+	GFX_CF_CLUT4       = 4,
+	GFX_CF_CLUT8       = 5,
+	GFX_CF_ARGB8888    = 6,
+
+	GFX_CF_XRGB        = 7,
+}GFX_COLOR_FORMAT;
+
+/* RGB8888 */
+typedef struct _GFX_ARGB_COLOR_
+{
+	u8  Alpha;
+	u8  Red;
+	u8  Green;
+	u8  Blue;
+
+}GFX_ARGB_COLOR;
+
+/* ARGB8565 */
+typedef enum 
+{
+	GFX_ALPHA_BIT_WIDTH = 8,
+	GFX_RED_BIT_WIDTH   = 5,
+	GFX_GREEN_BIT_WIDTH = 6,
+	GFX_BLUE_BIT_WIDTH  = 5,
+}GFX_COLOR_BIT_WIDTH;
+
+/* color const */
+typedef enum 
+{
+	CLUT4_TABLE_LEN  = 16,
+	CLUT8_TABLE_LEN  = 256,
+}CLUT_CONST;
+
+typedef enum
+{
+	BYTE_BIG_ENDIAN    = 0,
+	BYTE_LITTLE_ENDIAN = 1,
+
+}GFX_MEM_BYTE_ENDIAN;
+
+typedef enum
+{
+	NIBBLE_BIG_ENDIAN     = 0,
+	NIBBLE_LITTLE_ENDIAN  = 1,
+
+}GFX_MEM_NIBBLE_ENDIAN;
+
+typedef enum
+{
+	TWO_BYTES_BIG_ENDIAN     = 0,
+	TWO_BYTES_LITTLE_ENDIAN  = 1,
+
+}GFX_16BIT_ENDIAN;
+
+
+typedef enum
+{
+	CMD_STARTUP            = 0x00 ,
+	CMD_S0_ADDR_INFO       = 0x04 ,
+	CMD_S0_ADDR_INFO_L     = 0x05 ,
+	CMD_S0_FORMAT          = 0x06 ,
+	CMD_S0_FORMAT_L        = 0x07 ,
+	CMD_S0_COLOR_KEY_MIN   = 0x08 ,
+	CMD_S0_COLOR_KEY_MAX   = 0x0A ,
+	CMD_S1_ADDR_INFO       = 0x0C ,
+	CMD_S1_ADDR_INFO_L     = 0x0D ,
+	CMD_S1_FORMAT          = 0x0E ,
+	CMD_S1_FORMAT_L        = 0x0F ,
+	CMD_S1_COLOR_KEY_MIN   = 0x10 ,
+	CMD_S1_COLOR_KEY_MAX   = 0x12 ,
+	CMD_D_ADDR_INFO        = 0x14 ,
+	CMD_D_ADDR_INFO_L      = 0x15 ,
+	CMD_D_FORMAT           = 0x16 ,
+	CMD_PIXEL_NUM_PER_LINE = 0x18,
+	CMD_TOTAL_LINE_NUM     = 0x19,    
+
+	CMD_ENDIAN_CTRL        = 0x1A ,
+	CMD_CLUT4_TAB          = 0x1C ,
+	CMD_CLUT4_IDX          = 0x1D ,
+	CMD_CLUT8_TAB          = 0x1E ,
+	CMD_CLUT8_IDX          = 0x1F ,
+
+	/* scalor related */
+	CMD_SCALOR_S_PIXEL_NUM_PER_LINE = 0x30,
+	CMD_SCALOR_S_TOTAL_LINE_NUM     = 0x31,
+	CMD_SCALOR_INITIAL_PHASE        = 0x38,
+	CMD_HFIR_COEFFICIETN_DATA       = 0x3B,
+	CMD_VFIR_COEFFICIETN_DATA       = 0x3D,
+	CMD_VALID_MAX,
+
+}GFX_COMMAND_INDEX;
+
+typedef enum
+{
+	GFX_STATUS_BIT     = 0,
+	GFX_INT_STATUS_BIT = 1,
+	GFX_ERR_BIT        = 2,
+	GFX_AHB_ERR_BIT    = 3, 
+}_GFX_REG_STATUS;
+
+typedef enum 
+{
+	GFX_REG_CMDQUE_EMPTY_CNT_LSB   = 0,
+	GFX_REG_CMDQUE_EMPTY_CNT_WIDTH = 9,	
+}GFX_REG_CMDQUE_EMPTY_CNT_FORMAT;
+
+typedef enum
+{
+	COMPOSITOR_ENABLE_BIT  = 3,
+	ROP_ENABLE_BIT         = 3,
+	S0_ON_TOP_S1_BIT       = 0,
+}COMPOSITOR_OPT_FORMAT;
+
+typedef enum
+{
+	S_ENABLE_BIT          = 3,
+	S_COLORKEY_ENABLE_BIT = 2,
+	S_CLUT_ENABLE_BIT     = 1,
+	S_FETCH_DATA_BIT      = 0,	
+}S_OPT_FORMAT;
+
+typedef enum 
+{
+	S0_REVERSE_SCAN_BIT   = 0,
+	S1_REVERSE_SCAN_BIT   = 1,
+	D_REVERSE_SCAN_BIT    = 2,
+}S_SCAN_CTRL_FORMAT;
+
+typedef enum
+{
+	ENDIAN_ENABLE_BIT   =  3,
+	TWO_BYTE_ENDIAN_BIT =  2,
+	NIBBLE_ENDIAN_BIT   =  1,
+	BYTE_ENDIAN_BIT     =  0,	
+}ENDIAN_CTRL_FORMAT;
+
+typedef enum
+{
+	REG_INFO_CMD_CNT_WIDTH   =  4,
+	REG_INFO_CMD_CNT_LSB     = 28,
+
+	REG_ENDIAN_CTRL_D_WIDTH  =  3,
+	REG_ENDIAN_CTRL_D_LSB    =  0,
+	REG_ENDIAN_CTRL_S1_WIDTH =  3,
+	REG_ENDIAN_CTRL_S1_LSB   =  3,
+	REG_ENDIAN_CTRL_S0_WIDTH =  3,
+	REG_ENDIAN_CTRL_S0_LSB   =  6,		
+
+}GFX_REG_FORMAT;
+
+typedef enum
+{
+	/* all */
+	CMD_IDX_WIDTH =  8,
+	CMD_IDX_LSB   = 24, /* Start up Bit */
+
+	/* CMD_STARTUP */
+	SCAN_CTRL_WIDTH  =  4,
+	SCAN_CTRL_LSB    = 20,
+	S0_SCAL_ENA_BIT  = 17, 
+	INT_ENABLE_WIDTH =  1,
+	INT_ENABLE_LSB   = 16,
+	ROP_ALPHA_CTRL_WIDTH = 2,
+	ROP_ALPHA_CTRL_LSB   = 18,
+	ROP_VAL_WIDTH    =  4,
+	ROP_VAL_LSB      = 12,
+	CMP_OPT_WIDTH    =  4, /* Compositor Operation */
+	CMP_OPT_LSB      =  8,
+	S1_OPT_WIDTH     =  4,
+	S1_OPT_LSB       =  4,
+	S0_OPT_WIDTH     =  4,
+	S0_OPT_LSB       =  0, 
+
+	/* CMD_XX_FORMAT  */
+	CMD_FORMAT_WIDTH        =  4,
+	CMD_FORMAT_LSB          =  0,
+	CMD_FORMAT_ALPHA0_LSB   =  8,
+	CMD_FORMAT_ALPHA0_WIDTH =  8,
+	CMD_FORMAT_ALPHA1_LSB   = 16,
+	CMD_FORMAT_ALPHA1_WIDTH =  8,
+
+	CMD_FORMAT_ALPHA0_MIN_LSB   =  8,
+	CMD_FORMAT_ALPHA0_MIN_WIDTH =  8,
+	CMD_FORMAT_ALPHA0_MAX_LSB   = 16,
+	CMD_FORMAT_ALPHA0_MAX_WIDTH =  8,
+
+
+	/* CMD_XX_ADDR_INFO */
+	CMD_SKIP_PIXEL_WIDTH =  1,
+	CMD_SKIP_PIXEL_LSB   = 16,
+	CMD_PITCH_WIDTH      = 16,
+	CMD_PITCH_LSB        =  0,
+
+	CMD_ALPHA_WIDTH     =  8,
+	CMD_ALPHA_LSB       = 24,
+	CMD_RED_WIDTH       =  8,
+	CMD_RED_LSB         = 16,
+	CMD_GREEN_WIDTH     =  8,
+	CMD_GREEN_LSB       =  8,
+	CMD_BLUE_WIDTH      =  8,
+	CMD_BLUE_LSB        =  0,
+
+	/* CMD_PIXEL_MAP */
+	CMD_LPIXEL_NUM_WIDTH = 16,
+	CMD_LPIXEL_NUM_LSB   = 0,
+	CMD_LINE_NUM_WIDTH   = 16,
+	CMD_LINE_NUM_LSB     =  0,
+
+	/* CMD_CLUT4_IDX */
+	CMD_CLUT4_IDX_WIDTH  =  4,
+	CMD_CLUT4_IDX_LSB    =  0,
+
+	/* CMD_CLUT8_IDX */
+	CMD_CLUT8_IDX_WIDTH  =  8,
+	CMD_CLUT8_IDX_LSB    =  0,
+
+	/* CMD_ENDIAN_CTRL */
+	CMD_GLOBAL_ENDIAN_WIDTH   =  3,
+	CMD_GLOBAL_ENDIAN_LSB     =  0,
+
+	CMD_S0_ENDIAN_WIDTH       =  4,
+	CMD_S0_ENDIAN_LSB         =  4,
+
+	CMD_S1_ENDIAN_WIDTH       =  4,
+	CMD_S1_ENDIAN_LSB         =  8,
+
+	CMD_D_ENDIAN_WIDTH        =  4,
+	CMD_D_ENDIAN_LSB          = 12,
+
+	/* CMD_SCALOR_INITIAL_PHASE */
+	CMD_SCALOR_V_INIT_PHASE_WIDTH = 3,
+	CMD_SCALOR_V_INIT_PHASE_LSB   = 8,
+	CMD_SCALOR_H_INIT_PHASE_WIDTH = 3,
+	CMD_SCALOR_H_INIT_PHASE_LSB   = 0,
+
+	CMD_FIR_COEFF_PHASE_IDX_WIDTH =  3,
+	CMD_FIR_COEFF_PHASE_IDX_LSB   = 20,
+	CMD_FIR_COEFF_TAP_IDX_WIDTH   =  2,
+	CMD_FIR_COEFF_TAP_IDX_LSB     = 16,
+	CMD_FIR_COEFF_VALUE_WIDTH     = 16,
+	CMD_FIR_COEFF_VALUE_LSB       =  0,
+} GFX_CMD_FORMAT;
+
+
+#define SCALOR_FIR_COEFF_RED_REG_AVAILABLE (0)
+
+/* 2D-BLTer Register Map */
+typedef enum
+{	
+	GFX_REG_CMD_QUE                = 0x000000,
+	GFX_REG_STATUS                 = 0x000001,
+	GFX_REG_CMDQUE_EMPTY_CNT       = 0x000002,
+	GFX_REG_CMD_INFO               = 0x000003,
+	GFX_REG_CLUT_IDX               = 0x000004,
+	GFX_REG_CLUT_ENTRY             = 0x000005,
+	GFX_REG_S0_ADDR                = 0x000008,
+	GFX_REG_S0_LINE_PITCH          = 0x000009,
+	GFX_REG_S0_SKIP_PIXEL          = 0x00000A,
+	GFX_REG_S0_COLOR_FORMAT        = 0x00000B,
+	GFX_REG_S0_COLOR_KEY_MIN       = 0x00000C,
+	GFX_REG_S0_COLOR_KEY_MAX       = 0x00000D,
+	GFX_REG_S0_DEFAULT_COLOR       = 0x00000E,
+	GFX_REG_S1_ADDR                = 0x00000F,
+	GFX_REG_S1_LINE_PITCH          = 0x000010,
+	GFX_REG_S1_SKIP_PIXEL          = 0x000011,
+	GFX_REG_S1_COLOR_FORMAT        = 0x000012,
+	GFX_REG_S1_COLOR_KEY_MIN       = 0x000013,
+	GFX_REG_S1_COLOR_KEY_MAX       = 0x000014,
+	GFX_REG_S1_DEFAULT_COLOR       = 0x000015,
+	GFX_REG_D_ADDR                 = 0x000016,
+	GFX_REG_D_LINE_PITCH           = 0x000017,
+	GFX_REG_D_SKIP_PIXEL           = 0x000018,
+	GFX_REG_D_COLOR_FORMAT         = 0x000019,
+	GFX_REG_PIXEL_NUM_PER_LINE     = 0x00001A,
+	GFX_REG_TOTAL_LINE_NUM         = 0x00001B,
+	GFX_REG_ENDIAN_CTRL            = 0x00001C,
+	GFX_REG_INT_CLEAR              = 0x00001D,
+	GFX_REG_SW_RESET               = 0x00001E,
+
+	/* alor Related Register */
+	GFX_REG_S0_PIXEL_NUM_PER_LINE  = 0x000020,
+	GFX_REG_S0_TOTAL_LINE_NUM      = 0x000021,
+
+	GFX_REG_SCALOR_HORIZONTAL_INITIAL_PHASE
+		= 0x000022,
+	GFX_REG_SCALOR_VERTICAL_INITIAL_PHASE
+		= 0x000023,
+
+#if SCALOR_FIR_COEFF_RED_REG_AVAILABLE                                 
+	/*r Orion 1.4 Version SCalor FIR Coefficient Read not available in HW GfxCore */
+	GFX_REG_SCALER_HORIZONTAL_FIR_COEFFICIENT
+		= 0x000024,
+	GFX_REG_SCALER_VERTICAL_FIR_COEFFICIENT
+		= 0x000025,
+#endif
+} GFX_REG_ADDR_DEF;
+
+typedef enum
+{
+	GFX_COLOR_REG_MASK = ~((((1 << (CMD_ALPHA_WIDTH - GFX_ALPHA_BIT_WIDTH)) - 1) << CMD_ALPHA_LSB) |
+			(((1 << (CMD_RED_WIDTH   - GFX_RED_BIT_WIDTH  )) - 1) << CMD_RED_LSB  ) |
+			(((1 << (CMD_GREEN_WIDTH - GFX_GREEN_BIT_WIDTH)) - 1) << CMD_GREEN_LSB) |
+			(((1 << (CMD_BLUE_WIDTH  - GFX_BLUE_BIT_WIDTH )) - 1) << CMD_BLUE_LSB ) ),
+}GFX_REG_MASk;
+
+/* ROP Type Define */
+typedef enum
+{
+	ROP_R2_BLACK       = 0  ,
+	ROP_R2_NOTMERGEPEN = 1  ,
+	ROP_R2_MASKNOTPEN  = 2  ,
+	ROP_R2_NOTCOPYPEN  = 3  ,
+	ROP_R2_MASKPENNOT  = 4  ,
+	ROP_R2_NOT         = 5  ,
+	ROP_R2_XORPEN      = 6  ,
+	ROP_R2_NOTMASKPEN  = 7  ,
+	ROP_R2_MASKPEN     = 8  ,
+	ROP_R2_NOTXORPEN   = 9  ,
+	ROP_R2_NOP         = 10 ,
+	ROP_R2_MERGENOTPEN = 11 ,
+	ROP_R2_COPYPEN     = 12 ,
+	ROP_R2_MERGEPENNOT = 13 ,
+	ROP_R2_MERGEPEN    = 14 ,
+	ROP_R2_WHITE       = 15
+}ROP_OPT;
+
+
+typedef enum
+{
+	SCALOR_H_FIR_TAP_NUM            = 4,/* Max >=2 */
+	SCALOR_V_FIR_TAP_NUM            = 2,
+	SCALOR_COEFF_FRACTION_BIT_WIDTH = 10,
+	SCALOR_COEFF_INTREGER_BIT_WIDTH = 1,
+	SCALOR_COEFF_POLARITY_BIT       = 15,
+
+	SCALOR_PAHSE_BIT_WIDTH          = 3,
+	SCALOR_PAHSE_NUM                = (1 << SCALOR_PAHSE_BIT_WIDTH),
+	SCALOR_STEP_FRACTION_BIT_WIDTH  = 13,
+
+	SCALOR_HFIR_DATA_BUF_LEN = SCALOR_H_FIR_TAP_NUM,
+
+} GFX_SCALOR_CONST;
+
+typedef enum
+{
+	SCALOR_HORIZON_FIR  = 0,
+	SCALOR_VERTICAL_FIR = 1,
+
+}GFX_SCALOR_FIR_IDX;
+
+/* 
+ * the implementation of orionfb_2d.c 
+ */
+typedef struct _COLOR_IMG_
+{
+	u32 StartAddress;
+	u32 PixelWidth; 
+	u32 PixelHeight;
+	u32 LinePitch;
+
+	GFX_COLOR_FORMAT ColorFormat;
+	GFX_ARGB_COLOR DefaultColor;
+
+	u32 InitialType; /* 0 Stable, 1 Zero Increase, 2,Do not Initial */
+
+#if defined(CONFIG_MACH_CELESTIAL_CNC1800H)
+
+	GFX_MEM_BYTE_ENDIAN	ByteEndian;
+	GFX_MEM_NIBBLE_ENDIAN NibbleEndian;
+	GFX_16BIT_ENDIAN TwoBytesEndian;
+#endif
+	signed int IsMemAllocated;
+}COLOR_IMG;
+
+typedef struct tagRECT
+{
+	u32 left;
+	u32 top;
+	u32 right;
+	u32 bottom;
+} RECT;
+
+typedef enum
+{
+	GFX_DC_S0_COLOR_FORMAT   = (1 << 0),
+	GFX_DC_S0_DEFAULT_COLOR  = (1 << 1),
+	GFX_DC_S0_COLORKEY_PARA  = (1 << 2),
+	GFX_DC_S0_DRAM_PARA      = (1 << 3),
+
+	GFX_DC_S1_COLOR_FORMAT   = (1 << 4),
+	GFX_DC_S1_DEFAULT_COLOR  = (1 << 5),
+	GFX_DC_S1_COLORKEY_PARA  = (1 << 6),
+	GFX_DC_S1_DRAM_PARA      = (1 << 7),
+
+	GFX_DC_D_COLOR_FORMAT    = (1 << 8),
+	GFX_DC_D_DRAM_PARA       = (1 << 9),
+
+	GFX_DC_CLUT4_TABLE       = (1 << 10),
+	GFX_DC_CLUT8_TABLE       = (1 << 11),
+	//Scalor
+	GFX_DC_SCALOR_HFIR_COFF  = (1 << 12),
+	GFX_DC_SCALOR_VFIR_COFF  = (1 << 13),
+	GFX_DC_SCALOR_INIT_PHASE = (1 << 14),
+	GFX_DC_CTRL              = (1 << 31),	
+	GFX_DC_ALL               = (~0x0),
+
+}GFX_DC_UPDATE_TYPE;
+
+typedef struct _GFX_DEVICE_CONTEXT_
+{
+	/* Run Time Info */
+	signed int GfxIdelStatus;
+	signed int AHBErrStatus;
+	signed int GfxErrStatus;
+	signed int InterruptStatus;
+	u32 CMDCnt;
+
+	/* Clut Table: */
+	signed int UpdateClut4Table;
+	signed int UpdateClut4TableMode;
+	u32 Clut4TableIdx;
+	u32 Clut4Table[CLUT4_TABLE_LEN];
+	signed int UpdateClut8Table;
+	signed int UpdateClut8TableMode;
+	u32 Clut8TableIdx;
+	u32 Clut8Table[CLUT8_TABLE_LEN];
+
+	/* RunTimeControl */
+	signed int InterruptEnable;
+
+	/* S0 Control */
+	signed int S0Enable;
+	signed int S0VReverseScan;
+	signed int S0FetchDram;
+
+	GFX_COLOR_FORMAT S0ColorFormat;
+	u32 S0Alpha0;
+	u32 S0Alpha1;
+	GFX_ARGB_COLOR S0DefaultColor;
+	u32 S0BaseAddr;
+	u32 S0LinePitch;
+	u32 S0SkipPixelLine;
+	u32 S0PixelNumOneLine;
+	u32 S0TotalLineNum;
+
+#if defined(CONFIG_MACH_CELESTIAL_CNC1800H)
+
+	GFX_MEM_BYTE_ENDIAN S0ByteEndian;
+	GFX_MEM_NIBBLE_ENDIAN S0NibbleEndian;
+	GFX_16BIT_ENDIAN S016BitEndian;
+#endif
+	
+	signed int S0ClutEnable;
+	signed int S0ColorKeyEnable;
+	GFX_ARGB_COLOR S0ColorKeyMin;
+	GFX_ARGB_COLOR S0ColorKeyMax;
+
+	/* S1 Control */
+	signed int S1Enable;
+	signed int S1VReverseScan;
+	signed int S1FetchDram;
+	GFX_COLOR_FORMAT S1ColorFormat;
+	u32 S1Alpha0;
+	u32 S1Alpha1;
+
+	GFX_ARGB_COLOR S1DefaultColor;
+	u32 S1BaseAddr;
+	u32 S1LinePitch;
+	u32 S1SkipPixelLine;
+	u32 S1PixelNumOneLine;
+	u32 S1TotalLineNum;	
+	
+#if defined(CONFIG_MACH_CELESTIAL_CNC1800H)
+    GFX_MEM_BYTE_ENDIAN S1ByteEndian;
+	GFX_MEM_NIBBLE_ENDIAN S1NibbleEndian;
+	GFX_16BIT_ENDIAN S116BitEndian;
+#endif
+	signed int S1ClutEnable;
+	signed int S1ColorKeyEnable;
+	GFX_ARGB_COLOR S1ColorKeyMin;
+	GFX_ARGB_COLOR S1ColorKeyMax;
+
+	/* ROP and Compositor */
+	signed int CompositorEnable;
+	u32 ROPAlphaCtrl;
+	ROP_OPT RopValue;
+	signed int S0OnTopS1;
+
+	/* D Dram Para */
+	signed int DVReverseScan;
+	u32 DBaseAddr;
+	u32 DLinePitch;
+	u32 DSkipPixelLine;
+	u32 DPixelNumOneLine;
+	u32 DTotalLineNum;
+	GFX_COLOR_FORMAT DColorFormat;
+	u32 DAlpha0Min;
+	u32 DAlpha0Max;
+
+#if defined(CONFIG_MACH_CELESTIAL_CNC1800H)
+
+	GFX_MEM_BYTE_ENDIAN DByteEndian;
+	GFX_MEM_NIBBLE_ENDIAN DNibbleEndian;	
+	GFX_16BIT_ENDIAN D16BitEndian;
+
+	/* Endian Ctrl */
+	signed int IsUsingSDSpecificEndian;
+#endif
+	/* Scalor Control */
+	u32 S0ScalorEnable;
+	u32 HInitialPhase;
+	u32 VInitialPhase;
+	signed int UpdateHFIRCoeff;
+	signed int UpdateVFIRCoeff;
+	u32 HFIRCoeffTable[SCALOR_PAHSE_NUM][SCALOR_H_FIR_TAP_NUM];
+	u32 VFIRCoeffTable[SCALOR_PAHSE_NUM][SCALOR_V_FIR_TAP_NUM];
+	GFX_DC_UPDATE_TYPE GfxDCType;
+}GFX_DEVICE_CONTEXT;
+
+static u32 sGfxCMDGroupCnt = 0;
+static u32 sGfxCMDQueueDepth = 0x100; /* 0x100 is a HW Reset Value means not initial */
+static volatile u32 *sGfxBaseAddr = NULL;
+
+static GFX_DEVICE_CONTEXT Gfx_DC;
+
+static  u32 _GfxCLUT8Pal[CLUT8_TABLE_LEN] = 
+{
+	0xff000000,  //  000
+	0xff000033,  //  001
+	0xff000066,  //  002
+	0xff000099,  //  003
+	0xff0000cc,  //  004
+	0xff0000ff,  //  005
+	0xff003300,  //  006
+	0xff003333,  //  007
+	0xff003366,  //  008
+	0xff003399,  //  009
+	0xff0033cc,  //  010
+	0xff0033ff,  //  011
+	0xff006600,  //  012
+	0xff006633,  //  013
+	0xff006666,  //  014
+	0xff006699,  //  015
+	0xff0066cc,  //  016
+	0xff0066ff,  //  017
+	0xff009900,  //  018
+	0xff009933,  //  019
+	0xff009966,  //  020
+	0xff009999,  //  021
+	0xff0099cc,  //  022
+	0xff0099ff,  //  023
+	0xff00cc00,  //  024
+	0xff00cc33,  //  025
+	0xff00cc66,  //  026
+	0xff00cc99,  //  027
+	0xff00cccc,  //  028
+	0xff00ccff,  //  029
+	0xff00ff00,  //  030
+	0xff00ff33,  //  031
+	0xff00ff66,  //  032
+	0xff00ff99,  //  033
+	0xff00ffcc,  //  034
+	0xff00ffff,  //  035
+	0xff330000,  //  036
+	0xff330033,  //  037
+	0xff330066,  //  038
+	0xff330099,  //  039
+	0xff3300cc,  //  040
+	0xff3300ff,  //  041
+	0xff333300,  //  042
+	0xff333333,  //  043
+	0xff333366,  //  044
+	0xff333399,  //  045
+	0xff3333cc,  //  046
+	0xff3333ff,  //  047
+	0xff336600,  //  048
+	0xff336633,  //  049
+	0xff336666,  //  050
+	0xff336699,  //  051
+	0xff3366cc,  //  052
+	0xff3366ff,  //  053
+	0xff339900,  //  054
+	0xff339933,  //  055
+	0xff339966,  //  056
+	0xff339999,  //  057
+	0xff3399cc,  //  058
+	0xff3399ff,  //  059
+	0xff33cc00,  //  060
+	0xff33cc33,  //  061
+	0xff33cc66,  //  062
+	0xff33cc99,  //  063
+	0xff33cccc,  //  064
+	0xff33ccff,  //  065
+	0xff33ff00,  //  066
+	0xff33ff33,  //  067
+	0xff33ff66,  //  068
+	0xff33ff99,  //  069
+	0xff33ffcc,  //  070
+	0xff33ffff,  //  071
+	0xff660000,  //  072
+	0xff660033,  //  073
+	0xff660066,  //  074
+	0xff660099,  //  075
+	0xff6600cc,  //  076
+	0xff6600ff,  //  077
+	0xff663300,  //  078
+	0xff663333,  //  079
+	0xff663366,  //  080
+	0xff663399,  //  081
+	0xff6633cc,  //  082
+	0xff6633ff,  //  083
+	0xff666600,  //  084
+	0xff666633,  //  085
+	0xff666666,  //  086
+	0xff666699,  //  087
+	0xff6666cc,  //  088
+	0xff6666ff,  //  089
+	0xff669900,  //  090
+	0xff669933,  //  091
+	0xff669966,  //  092
+	0xff669999,  //  093
+	0xff6699cc,  //  094
+	0xff6699ff,  //  095
+	0xff66cc00,  //  096
+	0xff66cc33,  //  097
+	0xff66cc66,  //  098
+	0xff66cc99,  //  099
+	0xff66cccc,  //  100
+	0xff66ccff,  //  101
+	0xff66ff00,  //  102
+	0xff66ff33,  //  103
+	0xff66ff66,  //  104
+	0xff66ff99,  //  105
+	0xff66ffcc,  //  106
+	0xff66ffff,  //  107
+	0xff990000,  //  108
+	0xff990033,  //  109
+	0xff990066,  //  110
+	0xff990099,  //  111
+	0xff9900cc,  //  112
+	0xff9900ff,  //  113
+	0xff993300,  //  114
+	0xff993333,  //  115
+	0xff993366,  //  116
+	0xff993399,  //  117
+	0xff9933cc,  //  118
+	0xff9933ff,  //  119
+	0xff996600,  //  120
+	0xff996633,  //  121
+	0xff996666,  //  122
+	0xff996699,  //  123
+	0xff9966cc,  //  124
+	0xff9966ff,  //  125
+	0xff999900,  //  126
+	0xff999933,  //  127
+	0xff999966,  //  128
+	0xff999999,  //  129
+	0xff9999cc,  //  130
+	0xff9999ff,  //  131
+	0xff99cc00,  //  132
+	0xff99cc33,  //  133
+	0xff99cc66,  //  134
+	0xff99cc99,  //  135
+	0xff99cccc,  //  136
+	0xff99ccff,  //  137
+	0xff99ff00,  //  138
+	0xff99ff33,  //  139
+	0xff99ff66,  //  140
+	0xff99ff99,  //  141
+	0xff99ffcc,  //  142
+	0xff99ffff,  //  143
+	0xffcc0000,  //  144
+	0xffcc0033,  //  145
+	0xffcc0066,  //  146
+	0xffcc0099,  //  147
+	0xffcc00cc,  //  148
+	0xffcc00ff,  //  149
+	0xffcc3300,  //  150
+	0xffcc3333,  //  151
+	0xffcc3366,  //  152
+	0xffcc3399,  //  153
+	0xffcc33cc,  //  154
+	0xffcc33ff,  //  155
+	0xffcc6600,  //  156
+	0xffcc6633,  //  157
+	0xffcc6666,  //  158
+	0xffcc6699,  //  159
+	0xffcc66cc,  //  160
+	0xffcc66ff,  //  161
+	0xffcc9900,  //  162
+	0xffcc9933,  //  163
+	0xffcc9966,  //  164
+	0xffcc9999,  //  165
+	0xffcc99cc,  //  166
+	0xffcc99ff,  //  167
+	0xffcccc00,  //  168
+	0xffcccc33,  //  169
+	0xffcccc66,  //  170
+	0xffcccc99,  //  171
+	0xffcccccc,  //  172
+	0xffccccff,  //  173
+	0xffccff00,  //  174
+	0xffccff33,  //  175
+	0xffccff66,  //  176
+	0xffccff99,  //  177
+	0xffccffcc,  //  178
+	0xffccffff,  //  179
+	0xffff0000,  //  180
+	0xffff0033,  //  181
+	0xffff0066,  //  182
+	0xffff0099,  //  183
+	0xffff00cc,  //  184
+	0xffff00ff,  //  185
+	0xffff3300,  //  186
+	0xffff3333,  //  187
+	0xffff3366,  //  188
+	0xffff3399,  //  189
+	0xffff33cc,  //  190
+	0xffff33ff,  //  191
+	0xffff6600,  //  192
+	0xffff6633,  //  193
+	0xffff6666,  //  194
+	0xffff6699,  //  195
+	0xffff66cc,  //  196
+	0xffff66ff,  //  197
+	0xffff9900,  //  198
+	0xffff9933,  //  199
+	0xffff9966,  //  200
+	0xffff9999,  //  201
+	0xffff99cc,  //  202
+	0xffff99ff,  //  203
+	0xffffcc00,  //  204
+	0xffffcc33,  //  205
+	0xffffcc66,  //  206
+	0xffffcc99,  //  207
+	0xffffcccc,  //  208
+	0xffffccff,  //  209
+	0xffffff00,  //  210
+	0xffffff33,  //  211
+	0xffffff66,  //  212
+	0xffffff99,  //  213
+	0xffffffcc,  //  214
+	0xffffffff,  //  215
+
+	/*  from 2 o 248,  32 level grey scale */
+	0xff000000,  //  216
+	0xff080808,  //  217
+	0xff101010,  //  218
+	0xff181818,  //  219
+	0xff202020,  //  220
+	0xff282828,  //  221
+	0xff303030,  //  222
+	0xff383838,  //  223
+	0xff404040,  //  224
+	0xff484848,  //  225
+	0xff505050,  //  226
+	0xff585858,  //  227
+	0xff606060,  //  228
+	0xff686868,  //  229
+	0xff707070,  //  230
+	0xff787878,  //  231
+	0xff808080,  //  232
+	0xff888888,  //  233
+	0xff909090,  //  234
+	0xff989898,  //  235
+	0xffa0a0a0,  //  236
+	0xffa8a8a8,  //  237
+	0xffb0b0b0,  //  238
+	0xffb8b8b8,  //  239
+	0xffc0c0c0,  //  240
+	0xffc8c8c8,  //  241
+	0xffd0d0d0,  //  242
+	0xffd8d8d8,  //  243
+	0xffe0e0e0,  //  244
+	0xffe8e8e8,  //  245
+	0xfff0f0f0,  //  246
+	0xfff8f8f8,  //  247
+	0xffffffff,  //  248
+
+	/* from 24t 255, 7 color rainbow */
+	0xff0000ff,  //  249
+	0xff00ff00,  //  250
+	0xff00ffff,  //  251
+	0xffff0000,  //  252
+	0xffff00ff,  //  253
+	0xffffff00,  //  254
+	0xffffffff,  //  255
+};    
+
+static inline void Gfx_WriteRegs(int offset, int val);
+static inline u32 Gfx_ReadRegs(int offset);
+static void Calc_DramPara(
+		COLOR_IMG *DesImg, 
+		RECT      *DesRect,	
+		signed int        IsVReverse,
+		u32       *pBaseAddr,
+		u32       *pLinePitch,
+		u32       *pSkipPixelLine);
+static int Is_RectValid(COLOR_IMG *Img, RECT *Rect);
+static signed int Gfx_ActiveDeviceContext(GFX_DEVICE_CONTEXT *hGfxDeviceContext, GFX_DC_UPDATE_TYPE GfxDCType);
+static signed int Gfx_Send2DCmd(u32 GfxCMD);
+static unsigned int Gfx_WaitForIdle(GFX_DEVICE_CONTEXT *hGfxDeviceContext);
+static void Gfx_2DReset(void);
+static void Gfx_SetCMDQueueDepth(u32 GfxCMDQueueDepth);
+static void Gfx_CMDGroupCntSyncHW(void);
+static int Gfx_SetDefaultScalorHFIRCoeff(GFX_DEVICE_CONTEXT *hGfxDC);
+static u32 *Gfx_GetDefaultScalorHFIRCoeff(void);
+static int Gfx_InitScalorHFIRCoeff(GFX_DEVICE_CONTEXT *hGfxDC, u32 *HFIRCoeff);
+static int Gfx_SetDefaultScalorVFIRCoeff(GFX_DEVICE_CONTEXT *hGfxDC);
+static u32 *Gfx_GetDefaultScalorVFIRCoeff(void);
+static int Gfx_InitScalorVFIRCoeff(GFX_DEVICE_CONTEXT *hGfxDC, u32 *VFIRCoeff);
+static u32 SCALOR_COEFF( u32 SignBit, u32 Nmerator, u32 denominator) ;
+static u32 *Gfx_GetDefaultClut8Table(void);
+static int Gfx_InitClut8Tab( GFX_DEVICE_CONTEXT * hGfxDC, u32 *Clut8Table);
+static int Gfx_SetDefaultClut8Table(GFX_DEVICE_CONTEXT * hGfxDC);
+
+int Gfx_2DInit(void);
+static int Gfx_2DScalor( 
+		GFX_DEVICE_CONTEXT  *hGfxDC, 
+		COLOR_IMG           *SrcImg, 
+		RECT                *SrcRect, 
+		signed int           SrcVReverse,
+		COLOR_IMG           *DesImg, 
+		RECT                *DesRect, 
+		signed int           DesVReverse,
+		ROP_OPT              RopValue, 
+		u32                  VInitialPhase, 
+		u32                  HInitialPhase);
+
+static inline u32 Gfx_ReadRegs(int offset)
+{
+	return *((volatile u32*)(sGfxBaseAddr + offset));
+}
+
+static inline void Gfx_WriteRegs(int offset, int val)
+{
+	*((volatile u32*)(sGfxBaseAddr + offset)) = (val);
+	udelay(3);
+}
+
+static int Is_RectValid(COLOR_IMG *Img, RECT *Rect)
+{
+	if (Img == NULL || Rect == NULL) 
+	{
+		return 0;
+	}
+	else if (Rect->left   < 0 || Rect->left   > Img->PixelWidth  ||
+			Rect->top    < 0 || Rect->top    > Img->PixelHeight ||
+			Rect->right  < 0 || Rect->right  > Img->PixelWidth  ||
+			Rect->bottom < 0 || Rect->bottom > Img->PixelHeight)
+	{
+		return 0;
+	}
+	else if (!(Rect->left  <= Rect->right) || 
+			!(Rect->top   <= Rect->bottom))
+	{
+		return 0;
+	}
+
+	return 1;
+}
+
+static int CmpRect( RECT *Rect0, RECT *Rect1) 
+{
+	if (!(Rect0->left <= Rect0->right) || !(Rect0->top <= Rect0->bottom) )
+	{
+		return 0;
+	}
+	else if (!(Rect1->left <= Rect1->right) || !(Rect1->top <= Rect1->bottom) )
+	{
+		return 0;
+	}
+	else if ( ((Rect0->right - Rect0->left) != (Rect1->right - Rect1->left)) || 
+			((Rect0->bottom - Rect0->top) != (Rect1->bottom - Rect1->top)) )
+	{
+		return 0;
+	}
+	else
+	{
+		return 1;
+	}
+}
+
+static void Calc_DramPara(
+		COLOR_IMG *DesImg, 
+		RECT      *DesRect,	
+		signed int        IsVReverse,
+		u32       *pBaseAddr,
+		u32       *pLinePitch,
+		u32       *pSkipPixelLine)
+{
+	u32 PixelBitWidth = 0;
+	u32 BaseAddr      = 0;
+	u32 LinePitch     = 0;
+	u32 SkipPixelLine = 0;
+
+	switch (DesImg->ColorFormat)
+	{
+		case GFX_CF_XRGB:
+		case GFX_CF_ARGB8888:
+			PixelBitWidth = 32;
+			break;
+
+		case GFX_CF_RGB565:			
+		case GFX_CF_ARGB4444:
+		case GFX_CF_ARGB1555:
+		case GFX_CF_A0:
+			PixelBitWidth = 16;
+			break;
+
+		case GFX_CF_CLUT8:
+			PixelBitWidth =  8;
+			break;
+
+		case GFX_CF_CLUT4:
+			PixelBitWidth =  4;
+			break;
+
+		default:
+			PixelBitWidth =  0;
+			break;
+	}
+
+	if (PixelBitWidth == 0) return;
+
+	/* if Clut4 and Width is odd, the Line width should be Bytes Aligned */
+	LinePitch = DesImg->LinePitch;
+	if (LinePitch < (DesImg->PixelWidth * PixelBitWidth + 8 - 1) / 8)
+	{
+		/* Warning, DesImg LinePitch(%d) < DesImg Width(%d) in Format(%d)\n */
+	}
+
+	if (!IsVReverse)
+	{
+		BaseAddr = DesImg->StartAddress + 
+			DesRect->top * LinePitch +                
+			(DesRect->left * PixelBitWidth) / 8;
+	}
+	else
+	{
+		u32 LineIdx = 0;
+		LineIdx  = DesRect->bottom;
+
+		if (LineIdx > 0) LineIdx--;
+
+		BaseAddr = DesImg->StartAddress + 
+			LineIdx* LinePitch +                
+			(DesRect->left * PixelBitWidth) / 8;
+	}
+
+	SkipPixelLine   = ((DesRect->left * PixelBitWidth) % 8) / PixelBitWidth;
+	*pBaseAddr      = BaseAddr;
+	*pLinePitch     = LinePitch;
+	*pSkipPixelLine = SkipPixelLine;
+
+	return;
+}
+
+static void Gfx_CMDGroupCntSyncHW(void)
+{
+	sGfxCMDGroupCnt = (Gfx_ReadRegs( GFX_REG_CMD_INFO ) >> REG_INFO_CMD_CNT_LSB) & 
+		((1 << REG_INFO_CMD_CNT_WIDTH) -1 );
+}
+
+static void Gfx_SetCMDQueueDepth(u32 GfxCMDQueueDepth)
+{
+	sGfxCMDQueueDepth = GfxCMDQueueDepth;
+}
+
+static void Gfx_2DReset(void)
+{
+	u32 GfxCMDQueueDepth = 0;
+
+	Gfx_WriteRegs(GFX_REG_SW_RESET, 1);
+
+	Gfx_WaitForIdle(NULL); /* To Ensure Reset is Stable, must Wait for the Idel */
+
+	Gfx_WriteRegs(GFX_REG_SW_RESET, 0);
+
+	GfxCMDQueueDepth = (Gfx_ReadRegs(GFX_REG_CMDQUE_EMPTY_CNT) 
+			>> GFX_REG_CMDQUE_EMPTY_CNT_LSB) 
+		& ((1 << GFX_REG_CMDQUE_EMPTY_CNT_WIDTH) - 1);
+
+	Gfx_SetCMDQueueDepth(GfxCMDQueueDepth);
+
+	Gfx_CMDGroupCntSyncHW();
+}
+
+static unsigned int Gfx_WaitForIdle(GFX_DEVICE_CONTEXT *hGfxDeviceContext)
+{
+	/* Run Time Info */
+	signed int hResult = 1;
+	signed int GfxIdelStatus   = 0;
+	signed int AHBErrStatus    = 0;
+	signed int GfxErrStatus    = 0;
+	signed int InterruptStatus = 0; 
+	u32 GfxCMDQueuSpace = 0;
+
+	signed int InterruptEnable = 0;
+
+	u32 TimeCnt = 0;
+	u32 TimeOut = 0;
+
+	u32 GfxStatusRegValue = 0;
+	u32 GfxInfoRegValue   = 0;
+
+	if (hGfxDeviceContext == NULL)
+	{
+		TimeOut = 0; /* no time out */
+	}
+	else
+	{
+		u32 MaxWidth  = 0;
+		u32 MaxHeight = 0;
+
+		MaxWidth  = hGfxDeviceContext->S0PixelNumOneLine > hGfxDeviceContext->S1PixelNumOneLine ?
+			hGfxDeviceContext->S0PixelNumOneLine : hGfxDeviceContext->S1PixelNumOneLine ;
+		MaxWidth  = MaxWidth > hGfxDeviceContext->DPixelNumOneLine ?
+			MaxWidth : hGfxDeviceContext->DPixelNumOneLine ;
+		MaxHeight = hGfxDeviceContext->S0TotalLineNum > hGfxDeviceContext->S1TotalLineNum ?
+			hGfxDeviceContext->S0TotalLineNum : hGfxDeviceContext->S1TotalLineNum ;
+		MaxHeight = MaxHeight > hGfxDeviceContext->DTotalLineNum ?
+			MaxHeight : hGfxDeviceContext->DTotalLineNum ;
+
+		TimeOut = MaxWidth * MaxHeight *10; /* One Circle One Pixel, for Scalor 3 Circle/pixel, so *10 is Enough */
+		if (TimeOut < 100) TimeOut = 100;
+	}
+
+	do 
+	{
+		GfxInfoRegValue   = Gfx_ReadRegs(GFX_REG_CMD_INFO);
+		InterruptEnable   = (GfxInfoRegValue >> INT_ENABLE_LSB) &((1 << INT_ENABLE_WIDTH) -1); 
+
+		GfxStatusRegValue = Gfx_ReadRegs(GFX_REG_STATUS);
+		GfxIdelStatus     = (GfxStatusRegValue >> GFX_STATUS_BIT ) &(1);
+		AHBErrStatus      = (GfxStatusRegValue >> GFX_AHB_ERR_BIT) &(1);
+		GfxErrStatus      = (GfxStatusRegValue >> GFX_ERR_BIT    ) &(1);
+		InterruptStatus   = (GfxStatusRegValue >> GFX_INT_STATUS_BIT) &(1);
+		GfxCMDQueuSpace   = (Gfx_ReadRegs(GFX_REG_CMDQUE_EMPTY_CNT) 
+				>> GFX_REG_CMDQUE_EMPTY_CNT_LSB) 
+			& ((1 << GFX_REG_CMDQUE_EMPTY_CNT_WIDTH) - 1);
+		if (AHBErrStatus) 
+		{
+			Gfx_2DReset();
+			continue;
+		}
+
+		if (GfxErrStatus)
+		{
+			hResult = 0;
+		}
+
+		if (InterruptEnable || GfxErrStatus)
+		{
+			if (InterruptStatus == 1)
+			{
+				/* Clear Interrupt */
+				Gfx_WriteRegs(GFX_REG_INT_CLEAR, 1); /* Write Any Value */
+			}
+		}
+		TimeCnt++;
+	}while(!GfxIdelStatus && (TimeCnt < TimeOut || TimeOut == 0));
+
+	if(hGfxDeviceContext != NULL)
+	{
+		hGfxDeviceContext->GfxIdelStatus   = GfxIdelStatus;
+		hGfxDeviceContext->AHBErrStatus    = AHBErrStatus;
+		hGfxDeviceContext->GfxErrStatus    = GfxErrStatus;
+		hGfxDeviceContext->InterruptStatus = InterruptStatus; 
+		hGfxDeviceContext->CMDCnt          = GfxCMDQueuSpace;
+	}
+	if (TimeCnt >= TimeOut && TimeOut > 0)
+	{
+		int i = 0;
+		Gfx_WriteRegs(GFX_REG_SW_RESET, 1);
+		for (i =0; i < 10; i++)
+		{
+			GfxStatusRegValue = Gfx_ReadRegs(GFX_REG_STATUS);
+			GfxIdelStatus     = (GfxStatusRegValue >> GFX_STATUS_BIT ) &(1);		
+			if (GfxIdelStatus)
+			{
+				break;
+			}
+		}		
+		AHBErrStatus      = (GfxStatusRegValue >> GFX_AHB_ERR_BIT) &(1);
+		GfxErrStatus      = (GfxStatusRegValue >> GFX_ERR_BIT    ) &(1);
+		InterruptStatus   = (GfxStatusRegValue >> GFX_INT_STATUS_BIT) &(1);
+		if (!GfxIdelStatus || AHBErrStatus || GfxErrStatus || InterruptStatus)
+		{
+		}
+		Gfx_WriteRegs(GFX_REG_SW_RESET, 0);
+
+		Gfx_CMDGroupCntSyncHW();
+
+		hResult = 0;
+	}
+	else
+	{
+		/* do nothing here... */
+	}
+	if(AHBErrStatus)
+	{
+		hResult = 0;
+	}
+	if (GfxErrStatus)
+	{
+		hResult = 0;
+	}
+
+	return hResult;
+}
+
+static signed int Gfx_Send2DCmd(u32 GfxCMD)
+{
+	/* Check Available Space */
+	u32 GfxCMDQueuSpace = 0;
+
+	do
+	{
+		GfxCMDQueuSpace = (Gfx_ReadRegs(GFX_REG_CMDQUE_EMPTY_CNT) >> GFX_REG_CMDQUE_EMPTY_CNT_LSB) &
+			((1 << GFX_REG_CMDQUE_EMPTY_CNT_WIDTH) - 1);
+		if (GfxCMDQueuSpace <= 0)
+		{
+			u32 GfxStatusRegValue = 0;
+			signed int AHBErrStatus    = 0;
+			signed int GfxErrStatus    = 0;
+			signed int InterruptStatus = 0; 
+			signed int InterruptEnable = 0;
+
+			/* Clear Interrupt and ERR */
+			GfxStatusRegValue = Gfx_ReadRegs(GFX_REG_STATUS);
+			AHBErrStatus = (GfxStatusRegValue >> GFX_AHB_ERR_BIT) &(1);
+			GfxErrStatus = (GfxStatusRegValue >> GFX_ERR_BIT) &(1);
+			InterruptStatus = (GfxStatusRegValue >> GFX_INT_STATUS_BIT) &(1);
+
+			if (AHBErrStatus) 
+			{
+				Gfx_2DReset();
+				continue;
+			}
+
+			if (GfxErrStatus)
+			{
+				/* ... ... */
+			}
+
+			if (InterruptEnable || GfxErrStatus)
+			{
+				if (InterruptStatus == 1)
+				{
+					Gfx_WriteRegs(GFX_REG_INT_CLEAR, 1); /* Write Any Value */
+				}
+			}
+		}
+
+		schedule();
+		if(0){
+			int i = 0;
+			for(i = 0; i < 10; i++){
+				udelay(1000);
+			}
+		}
+	}while(GfxCMDQueuSpace <= 0);
+
+	if (GfxCMDQueuSpace > 0)
+	{
+		Gfx_WriteRegs(GFX_REG_CMD_QUE, GfxCMD);
+	}
+
+	return GfxCMDQueuSpace;
+}
+
+static signed int Gfx_ActiveDeviceContext(GFX_DEVICE_CONTEXT *hGfxDeviceContext, GFX_DC_UPDATE_TYPE GfxDCType)
+{
+	/* Send S0 Related Command */
+	u32 GfxCMD   = 0;
+	u32 GfxCMDQueSpace = 0;
+	u32 CompositorOperation = 0;
+
+	u32 S0Operation     = 0;
+	u32 S1Operation     = 0;
+	u32 ScanCtrl        = 0;
+#if defined(CONFIG_MACH_CELESTIAL_CNC1800H)
+
+	u32 S0EndianCtrl    = 0;
+	u32 S1EndianCtrl    = 0;
+	u32 DEndianCtrl     = 0;
+	u32 GlobalEndianCtrl  = 0;
+#endif
+	if (hGfxDeviceContext == NULL)
+	{
+		return -1;
+	}
+	else  /* Check Command Queue */
+	{
+		/* Check Available Space */
+		u32 GfxCMDQueuSpace = 0;
+		u32 GfxStatusRegValue = 0;
+		signed int AHBErrStatus    = 0;
+		signed int GfxErrStatus    = 0;
+		signed int InterruptStatus = 0; 
+		signed int InterruptEnable = 0;
+
+		do
+		{
+			/* Clear Interrupt and ERR */
+			GfxStatusRegValue = Gfx_ReadRegs(GFX_REG_STATUS);
+			AHBErrStatus      = (GfxStatusRegValue >> GFX_AHB_ERR_BIT) &(1);
+			GfxErrStatus      = (GfxStatusRegValue >> GFX_ERR_BIT) &(1);
+			InterruptStatus   = (GfxStatusRegValue >> GFX_INT_STATUS_BIT) &(1);
+
+			if (AHBErrStatus) 
+			{
+				Gfx_2DReset();
+				continue;
+			}
+
+			if (InterruptEnable || GfxErrStatus)
+			{
+				if (InterruptStatus == 1)
+				{
+					/* Clear Interrupt */
+					signed int IsGfxGenINTToHost = 0;
+
+					IsGfxGenINTToHost = 1; /* FIXME@zhongkai's code */
+
+					Gfx_WriteRegs(GFX_REG_INT_CLEAR, 1); /* Write Any Value */
+				}
+			}
+
+			GfxCMDQueuSpace = (Gfx_ReadRegs(GFX_REG_CMDQUE_EMPTY_CNT) >> 
+					GFX_REG_CMDQUE_EMPTY_CNT_LSB) &
+				((1 << GFX_REG_CMDQUE_EMPTY_CNT_WIDTH) - 1);
+			if (GfxCMDQueuSpace < 32)
+			{
+				/* Gfx Command Queue Space Less than 32, Waiting... */
+				schedule();
+			}		
+		}while(GfxCMDQueuSpace < 32);
+	}
+
+	if (!Gfx_WaitForIdle(NULL)) return -1;
+
+	if (hGfxDeviceContext->S0Enable || hGfxDeviceContext->S0ScalorEnable)
+	{
+		if ((hGfxDeviceContext->S0FetchDram || hGfxDeviceContext->S0ScalorEnable)&& 
+				(GfxDCType & GFX_DC_S0_DRAM_PARA))
+		{			
+			/* Dram Access Para */
+			GfxCMD = ((CMD_S0_ADDR_INFO_L & ((1 << CMD_IDX_WIDTH) -1)) << CMD_IDX_LSB) |
+				((hGfxDeviceContext->S0SkipPixelLine & 
+				  ((1 << CMD_SKIP_PIXEL_WIDTH) -1)) << CMD_SKIP_PIXEL_LSB) |
+				((hGfxDeviceContext->S0LinePitch & 
+				  ((1 << CMD_PITCH_WIDTH) -1)) << CMD_PITCH_LSB);
+
+			GfxCMDQueSpace = Gfx_Send2DCmd(GfxCMD);
+			GfxCMDQueSpace = Gfx_Send2DCmd(hGfxDeviceContext->S0BaseAddr);
+#if defined(CONFIG_MACH_CELESTIAL_CNC1800H)
+
+			if (hGfxDeviceContext->IsUsingSDSpecificEndian)
+			{				
+				S0EndianCtrl = ((hGfxDeviceContext->S0ByteEndian   & 0x1) << BYTE_ENDIAN_BIT  )|
+					((hGfxDeviceContext->S0NibbleEndian & 0x1) << NIBBLE_ENDIAN_BIT)|
+					((hGfxDeviceContext->S016BitEndian  & 0x1) << TWO_BYTE_ENDIAN_BIT)|
+					((1 & 0x1) << ENDIAN_ENABLE_BIT);
+			}
+#endif
+			GfxCMD = ((CMD_SCALOR_S_PIXEL_NUM_PER_LINE & 
+						((1 << CMD_IDX_WIDTH) -1)) << CMD_IDX_LSB) |
+				((hGfxDeviceContext->S0PixelNumOneLine & 
+				  ((1 << CMD_LPIXEL_NUM_WIDTH) -1)) << CMD_LPIXEL_NUM_LSB);
+
+			GfxCMDQueSpace = Gfx_Send2DCmd(GfxCMD);
+
+			GfxCMD = ((CMD_SCALOR_S_TOTAL_LINE_NUM & ((1 << CMD_IDX_WIDTH) -1)) << CMD_IDX_LSB) |
+				((hGfxDeviceContext->S0TotalLineNum & ((1 << CMD_LINE_NUM_WIDTH) -1)) << CMD_LINE_NUM_LSB);
+
+			GfxCMDQueSpace = Gfx_Send2DCmd(GfxCMD);
+		}
+
+		/* Color Info */
+		if (GfxDCType & (GFX_DC_S0_COLOR_FORMAT))
+		{
+			if (GfxDCType & GFX_DC_S0_DEFAULT_COLOR)
+			{
+				u8 Alpha = 0;
+
+				if (hGfxDeviceContext->S0ColorFormat != GFX_CF_ARGB1555)
+				{
+					GfxCMD = ((CMD_S0_FORMAT_L & ((1 << CMD_IDX_WIDTH) -1)) << CMD_IDX_LSB) |
+						((hGfxDeviceContext->S0ColorFormat &
+						  ((1 << CMD_FORMAT_WIDTH) -1)) << CMD_FORMAT_LSB);
+				}
+				else
+				{
+					hGfxDeviceContext->S0Alpha0 = 0;
+					hGfxDeviceContext->S0Alpha1 = 0xff;
+					GfxCMD = ((CMD_S0_FORMAT_L & ((1 << CMD_IDX_WIDTH) -1)) << CMD_IDX_LSB) |
+						((hGfxDeviceContext->S0ColorFormat & ((1 << CMD_FORMAT_WIDTH) -1)) << CMD_FORMAT_LSB)|
+						((hGfxDeviceContext->S0Alpha0 & ((1 << CMD_FORMAT_ALPHA0_WIDTH) -1)) << CMD_FORMAT_ALPHA0_LSB)|
+						((hGfxDeviceContext->S0Alpha1 & ((1 << CMD_FORMAT_ALPHA1_WIDTH) -1)) << CMD_FORMAT_ALPHA1_LSB);
+				}
+
+				GfxCMDQueSpace = Gfx_Send2DCmd(GfxCMD);
+
+				Alpha = hGfxDeviceContext->S0DefaultColor.Alpha;
+
+				GfxCMD = (((Alpha >> (8-8)) & ((1 << CMD_ALPHA_WIDTH) -1)) << CMD_ALPHA_LSB)|
+					(((hGfxDeviceContext->S0DefaultColor.Red >> (8-8)) &
+					  ((1 << CMD_RED_WIDTH) -1)) << CMD_RED_LSB)|
+					(((hGfxDeviceContext->S0DefaultColor.Green >> (8-8)) &
+					  ((1 << CMD_GREEN_WIDTH) -1)) << CMD_GREEN_LSB)|
+					(((hGfxDeviceContext->S0DefaultColor.Blue >> (8-8)) &
+					  ((1 << CMD_BLUE_WIDTH) -1)) << CMD_BLUE_LSB);
+
+				GfxCMDQueSpace = Gfx_Send2DCmd(GfxCMD);
+			}
+			else
+			{
+				if (hGfxDeviceContext->S0ColorFormat != GFX_CF_ARGB1555)
+				{
+					GfxCMD = ((CMD_S0_FORMAT & ((1 << CMD_IDX_WIDTH) -1)) << CMD_IDX_LSB) |
+						((hGfxDeviceContext->S0ColorFormat & ((1 << CMD_FORMAT_WIDTH) -1)) << CMD_FORMAT_LSB);
+				}
+				else
+				{
+					GfxCMD = ((CMD_S0_FORMAT & ((1 << CMD_IDX_WIDTH) -1)) << CMD_IDX_LSB) |
+						((hGfxDeviceContext->S0ColorFormat & ((1 << CMD_FORMAT_WIDTH) -1)) << CMD_FORMAT_LSB)|
+						((hGfxDeviceContext->S0Alpha0 & ((1 << CMD_FORMAT_ALPHA0_WIDTH) -1)) << CMD_FORMAT_ALPHA0_LSB)|
+						((hGfxDeviceContext->S0Alpha1 & ((1 << CMD_FORMAT_ALPHA1_WIDTH) -1)) << CMD_FORMAT_ALPHA1_LSB);
+				}
+
+				GfxCMDQueSpace = Gfx_Send2DCmd(GfxCMD);
+			}
+		}
+
+		/* ColorKey ARGB8888 */
+		if (hGfxDeviceContext->S0ColorKeyEnable && (GfxDCType & GFX_DC_S0_COLORKEY_PARA))
+		{
+			GfxCMD = ((CMD_S0_COLOR_KEY_MIN & ((1 << CMD_IDX_WIDTH) -1)) << CMD_IDX_LSB) |
+				((hGfxDeviceContext->S0ColorKeyMin.Red & 
+				  ((1 << CMD_RED_WIDTH) -1)) << CMD_RED_LSB) |
+				((hGfxDeviceContext->S0ColorKeyMin.Green &
+				  ((1 << CMD_GREEN_WIDTH) -1)) << CMD_GREEN_LSB)|
+				((hGfxDeviceContext->S0ColorKeyMin.Blue &
+				  ((1 << CMD_BLUE_WIDTH) -1))  << CMD_BLUE_LSB);
+
+			GfxCMDQueSpace = Gfx_Send2DCmd(GfxCMD);
+
+			GfxCMD = ((CMD_S0_COLOR_KEY_MAX & ((1 << CMD_IDX_WIDTH) -1)) << CMD_IDX_LSB) |
+				((hGfxDeviceContext->S0ColorKeyMax.Red &
+				  ((1 << CMD_RED_WIDTH) -1)) << CMD_RED_LSB) |
+				((hGfxDeviceContext->S0ColorKeyMax.Green &
+				  ((1 << CMD_GREEN_WIDTH) -1)) << CMD_GREEN_LSB)|
+				((hGfxDeviceContext->S0ColorKeyMax.Blue & 
+				  ((1 << CMD_BLUE_WIDTH) -1)) << CMD_BLUE_LSB);
+
+			GfxCMDQueSpace = Gfx_Send2DCmd(GfxCMD);		
+		}		
+	}
+
+	/* Send S1 Related Command */
+	if (hGfxDeviceContext->S1Enable)
+	{
+		if (hGfxDeviceContext->S1FetchDram && (GfxDCType & GFX_DC_S1_DRAM_PARA))
+		{
+
+			/* Dram Access Para */
+			GfxCMD = ((CMD_S1_ADDR_INFO_L & ((1 << CMD_IDX_WIDTH) -1)) << CMD_IDX_LSB) |
+				((hGfxDeviceContext->S1SkipPixelLine &
+				  ((1 << CMD_SKIP_PIXEL_WIDTH) -1)) << CMD_SKIP_PIXEL_LSB) |
+				((hGfxDeviceContext->S1LinePitch & 
+				  ((1 << CMD_PITCH_WIDTH) -1)) << CMD_PITCH_LSB);
+
+			GfxCMDQueSpace = Gfx_Send2DCmd(GfxCMD);
+			GfxCMDQueSpace = Gfx_Send2DCmd(hGfxDeviceContext->S1BaseAddr);
+
+#if defined(CONFIG_MACH_CELESTIAL_CNC1800H)
+
+			if (hGfxDeviceContext->IsUsingSDSpecificEndian)
+			{				
+				S1EndianCtrl = ((hGfxDeviceContext->S1ByteEndian & 0x1) << BYTE_ENDIAN_BIT  )|
+					((hGfxDeviceContext->S1NibbleEndian & 0x1) << NIBBLE_ENDIAN_BIT)|
+					((hGfxDeviceContext->S116BitEndian & 0x1) << TWO_BYTE_ENDIAN_BIT)|
+					((1 & 0x1) << ENDIAN_ENABLE_BIT);
+			}
+#endif
+			GfxCMD = ((CMD_PIXEL_NUM_PER_LINE & ((1 << CMD_IDX_WIDTH) -1)) << CMD_IDX_LSB) |
+				((hGfxDeviceContext->S1PixelNumOneLine &
+				  ((1 << CMD_LPIXEL_NUM_WIDTH) -1)) << CMD_LPIXEL_NUM_LSB);
+
+			GfxCMDQueSpace = Gfx_Send2DCmd(GfxCMD);
+
+			GfxCMD = ((CMD_TOTAL_LINE_NUM & ((1 << CMD_IDX_WIDTH) -1)) << CMD_IDX_LSB) |
+				((hGfxDeviceContext->S1TotalLineNum &
+				  ((1 << CMD_LINE_NUM_WIDTH) -1)) << CMD_LINE_NUM_LSB);
+
+			GfxCMDQueSpace = Gfx_Send2DCmd(GfxCMD);
+		}
+
+		/* Color Info */
+		if (GfxDCType & GFX_DC_S1_COLOR_FORMAT)
+		{
+			if (GfxDCType & GFX_DC_S1_DEFAULT_COLOR)
+			{
+				u8 Alpha;
+
+				if (hGfxDeviceContext->S1ColorFormat != GFX_CF_ARGB1555)
+				{
+					GfxCMD = ((CMD_S1_FORMAT_L & ((1 << CMD_IDX_WIDTH) -1)) << CMD_IDX_LSB) |
+						((hGfxDeviceContext->S1ColorFormat &
+						  ((1 << CMD_FORMAT_WIDTH) -1)) << CMD_FORMAT_LSB);
+				}
+				else
+				{
+					hGfxDeviceContext->S1Alpha0 = 0;
+					hGfxDeviceContext->S1Alpha1 = 0xff;
+					GfxCMD = ((CMD_S1_FORMAT_L & ((1 << CMD_IDX_WIDTH) -1)) << CMD_IDX_LSB) |
+						((hGfxDeviceContext->S1ColorFormat &
+						  ((1 << CMD_FORMAT_WIDTH) -1)) << CMD_FORMAT_LSB) |
+						((hGfxDeviceContext->S1Alpha0 &
+						  ((1 << CMD_FORMAT_ALPHA0_WIDTH) -1)) << CMD_FORMAT_ALPHA0_LSB)|
+						((hGfxDeviceContext->S1Alpha1 &
+						  ((1 << CMD_FORMAT_ALPHA1_WIDTH) -1)) << CMD_FORMAT_ALPHA1_LSB);
+				}
+
+				Alpha = hGfxDeviceContext->S1DefaultColor.Alpha;
+
+				GfxCMDQueSpace = Gfx_Send2DCmd(GfxCMD);
+				GfxCMD = (((Alpha >> (8-8)) & ((1 << CMD_ALPHA_WIDTH) -1)) << CMD_ALPHA_LSB)|
+					(((hGfxDeviceContext->S1DefaultColor.Red >> (8-8)) &
+					  ((1 << CMD_RED_WIDTH) -1)) << CMD_RED_LSB) |
+					(((hGfxDeviceContext->S1DefaultColor.Green >> (8-8)) &
+					  ((1 << CMD_GREEN_WIDTH) -1)) << CMD_GREEN_LSB) |
+					(((hGfxDeviceContext->S1DefaultColor.Blue >> (8-8)) &
+					  ((1 << CMD_BLUE_WIDTH) -1)) << CMD_BLUE_LSB);
+
+				GfxCMDQueSpace = Gfx_Send2DCmd(GfxCMD);
+			}
+			else
+			{
+				if (hGfxDeviceContext->S1ColorFormat != GFX_CF_ARGB1555)
+				{
+					GfxCMD = ((CMD_S1_FORMAT & ((1 << CMD_IDX_WIDTH) -1)) << CMD_IDX_LSB) |
+						((hGfxDeviceContext->S1ColorFormat & 
+						  ((1 << CMD_FORMAT_WIDTH) -1)) << CMD_FORMAT_LSB);
+				}
+				else
+				{
+					GfxCMD = ((CMD_S1_FORMAT & ((1 << CMD_IDX_WIDTH) -1)) << CMD_IDX_LSB) |
+						((hGfxDeviceContext->S1ColorFormat &
+						  ((1 << CMD_FORMAT_WIDTH) -1)) << CMD_FORMAT_LSB)|
+						((hGfxDeviceContext->S1Alpha0 &
+						  ((1 << CMD_FORMAT_ALPHA0_WIDTH) -1)) << CMD_FORMAT_ALPHA0_LSB)|
+						((hGfxDeviceContext->S1Alpha1 &
+						  ((1 << CMD_FORMAT_ALPHA1_WIDTH) -1)) << CMD_FORMAT_ALPHA1_LSB);
+				}
+
+				GfxCMDQueSpace = Gfx_Send2DCmd(GfxCMD);				
+			}
+		}
+
+		//ColorKey
+		if (hGfxDeviceContext->S1ColorKeyEnable && (GfxDCType & GFX_DC_S1_COLORKEY_PARA))
+		{
+			GfxCMD = ((CMD_S1_COLOR_KEY_MIN & ((1 << CMD_IDX_WIDTH) -1)) << CMD_IDX_LSB) |
+				((hGfxDeviceContext->S1ColorKeyMin.Red &
+				  ((1 << CMD_RED_WIDTH) -1)) << CMD_RED_LSB) |
+				((hGfxDeviceContext->S1ColorKeyMin.Green &
+				  ((1 << CMD_GREEN_WIDTH) -1)) << CMD_GREEN_LSB) |
+				((hGfxDeviceContext->S1ColorKeyMin.Blue &
+				  ((1 << CMD_BLUE_WIDTH) -1)) << CMD_BLUE_LSB);
+
+			GfxCMDQueSpace = Gfx_Send2DCmd(GfxCMD);
+
+			GfxCMD = ((CMD_S1_COLOR_KEY_MAX & ((1 << CMD_IDX_WIDTH) -1)) << CMD_IDX_LSB) |
+				((hGfxDeviceContext->S1ColorKeyMax.Red &
+				  ((1 << CMD_RED_WIDTH) -1)) << CMD_RED_LSB) |
+				((hGfxDeviceContext->S1ColorKeyMax.Green &
+				  ((1 << CMD_GREEN_WIDTH) -1)) << CMD_GREEN_LSB)|
+				((hGfxDeviceContext->S1ColorKeyMax.Blue &
+				  ((1 << CMD_BLUE_WIDTH) -1))  << CMD_BLUE_LSB);
+
+			GfxCMDQueSpace = Gfx_Send2DCmd(GfxCMD);		
+		}		
+	}
+
+	/* Clut Table Update */
+	/* Clut4 */
+	if (hGfxDeviceContext->UpdateClut4Table && (GfxDCType & GFX_DC_CLUT4_TABLE))
+	{
+		if (hGfxDeviceContext->UpdateClut4TableMode)
+		{
+			u32 Clut4TableIdx = 0;
+
+			Clut4TableIdx = (hGfxDeviceContext->Clut4TableIdx & ((1 << CMD_CLUT4_IDX_WIDTH) -1));
+			GfxCMD =((CMD_CLUT4_IDX & ((1 << CMD_IDX_WIDTH) -1)) << CMD_IDX_LSB) | 
+				( Clut4TableIdx << CMD_CLUT4_IDX_LSB);
+
+			GfxCMDQueSpace = Gfx_Send2DCmd(GfxCMD);
+			/* Send Clut4 Entry */
+			GfxCMDQueSpace = Gfx_Send2DCmd(hGfxDeviceContext->Clut4Table[Clut4TableIdx]);
+		}
+		else
+		{
+			u32 i = 0;
+
+			GfxCMD =((CMD_CLUT4_TAB & ((1 << CMD_IDX_WIDTH) -1)) << CMD_IDX_LSB);
+			GfxCMDQueSpace = Gfx_Send2DCmd(GfxCMD);
+
+			for (i = 0; i < CLUT4_TABLE_LEN; i++)
+			{
+				GfxCMDQueSpace = Gfx_Send2DCmd(hGfxDeviceContext->Clut4Table[i]);
+			}
+		}
+
+		/* add something here, to check clut4 table registers */
+	}
+
+	/* Clut8 */
+	if (hGfxDeviceContext->UpdateClut8Table && (GfxDCType & GFX_DC_CLUT8_TABLE))
+	{
+		if (hGfxDeviceContext->UpdateClut8TableMode)
+		{
+			u32 Clut8TableIdx = 0;
+
+			Clut8TableIdx = (hGfxDeviceContext->Clut8TableIdx & ((1 << CMD_CLUT8_IDX_WIDTH) -1));
+
+			GfxCMD =((CMD_CLUT8_IDX & ((1 << CMD_IDX_WIDTH) -1)) << CMD_IDX_LSB) | 
+				( Clut8TableIdx << CMD_CLUT8_IDX_LSB);
+
+			GfxCMDQueSpace = Gfx_Send2DCmd(GfxCMD);
+
+			/* Send Clut8 Entry */
+			GfxCMDQueSpace = Gfx_Send2DCmd(hGfxDeviceContext->Clut8Table[Clut8TableIdx]);
+		}
+		else
+		{
+			u32 i = 0;
+
+			GfxCMD =((CMD_CLUT8_TAB & ((1 << CMD_IDX_WIDTH) -1)) << CMD_IDX_LSB);
+			GfxCMDQueSpace = Gfx_Send2DCmd(GfxCMD);
+
+			for (i = 0; i < CLUT8_TABLE_LEN; i++)
+			{
+				GfxCMDQueSpace = Gfx_Send2DCmd(hGfxDeviceContext->Clut8Table[i]);
+			}
+		}
+
+		/* do something here, to check clut8 table registers */
+	}
+
+	/* Send D Related Command */
+
+	/* D Dram Para */
+	if ((GfxDCType & GFX_DC_D_DRAM_PARA))
+	{
+		GfxCMD = ((CMD_D_ADDR_INFO_L & ((1 << CMD_IDX_WIDTH) -1)) << CMD_IDX_LSB) |
+			((hGfxDeviceContext->DSkipPixelLine & 
+			  ((1 << CMD_SKIP_PIXEL_WIDTH) -1)) << CMD_SKIP_PIXEL_LSB) |
+			((hGfxDeviceContext->DLinePitch &
+			  ((1 << CMD_PITCH_WIDTH) -1)) << CMD_PITCH_LSB);
+
+		GfxCMDQueSpace = Gfx_Send2DCmd(GfxCMD);
+		GfxCMDQueSpace = Gfx_Send2DCmd(hGfxDeviceContext->DBaseAddr);
+
+#if defined(CONFIG_MACH_CELESTIAL_CNC1800H)
+	if (hGfxDeviceContext->IsUsingSDSpecificEndian)
+		{				
+			DEndianCtrl = ((hGfxDeviceContext->DByteEndian   & 0x1)    << BYTE_ENDIAN_BIT  )|
+				((hGfxDeviceContext->DNibbleEndian & 0x1)    << NIBBLE_ENDIAN_BIT)|
+				((hGfxDeviceContext->D16BitEndian  & 0x1)    << TWO_BYTE_ENDIAN_BIT)|
+				((1 & 0x1) << ENDIAN_ENABLE_BIT);
+		}
+#endif
+		GfxCMD = ((CMD_PIXEL_NUM_PER_LINE & ((1 << CMD_IDX_WIDTH) -1)) << CMD_IDX_LSB) |
+			((hGfxDeviceContext->DPixelNumOneLine &
+			  ((1 << CMD_LPIXEL_NUM_WIDTH) -1)) << CMD_LPIXEL_NUM_LSB);
+		GfxCMDQueSpace = Gfx_Send2DCmd(GfxCMD);
+
+		GfxCMD = ((CMD_TOTAL_LINE_NUM & ((1 << CMD_IDX_WIDTH) -1)) << CMD_IDX_LSB) |
+			((hGfxDeviceContext->DTotalLineNum &
+			  ((1 << CMD_LINE_NUM_WIDTH) -1)) << CMD_LINE_NUM_LSB) ;
+		GfxCMDQueSpace = Gfx_Send2DCmd(GfxCMD);
+	}
+
+	/* D Color Info should not be A0, no Default Color */
+	if ((GfxDCType & GFX_DC_D_COLOR_FORMAT))
+	{
+		if (hGfxDeviceContext->DColorFormat != GFX_CF_ARGB1555)
+		{
+			GfxCMD = ((CMD_D_FORMAT & ((1 << CMD_IDX_WIDTH) -1)) << CMD_IDX_LSB) |
+				((hGfxDeviceContext->DColorFormat & ((1 << CMD_FORMAT_WIDTH) -1)) << CMD_FORMAT_LSB);
+		}
+		else
+		{
+			hGfxDeviceContext->DAlpha0Min = 0;
+			hGfxDeviceContext->DAlpha0Max = 0;
+			GfxCMD = ((CMD_D_FORMAT & ((1 << CMD_IDX_WIDTH) -1)) << CMD_IDX_LSB) |
+				((hGfxDeviceContext->DColorFormat & ((1 << CMD_FORMAT_WIDTH) -1)) << CMD_FORMAT_LSB)|
+				((hGfxDeviceContext->DAlpha0Min & ((1 << CMD_FORMAT_ALPHA0_MIN_WIDTH) -1)) << CMD_FORMAT_ALPHA0_MIN_LSB)|
+				((hGfxDeviceContext->DAlpha0Max & ((1 << CMD_FORMAT_ALPHA0_MAX_WIDTH) -1)) << CMD_FORMAT_ALPHA0_MAX_LSB);
+		}	
+		GfxCMDQueSpace = Gfx_Send2DCmd(GfxCMD);
+	}
+
+	/* Set Gfx Interrupt Mode and Pipeline Enable */
+	/* Send Scalor Command */
+	/* Update VFIR Coeff */
+	if ( (hGfxDeviceContext->UpdateHFIRCoeff) && (GfxDCType & GFX_DC_SCALOR_HFIR_COFF))
+	{
+		u32 Phase = 0, Tap = 0;
+
+		for (Phase = 0; Phase < SCALOR_PAHSE_NUM; Phase++)
+		{
+			for (Tap =0; Tap < SCALOR_H_FIR_TAP_NUM; Tap++)
+			{
+				GfxCMD = ((CMD_HFIR_COEFFICIETN_DATA & ((1 << CMD_IDX_WIDTH) -1)) << CMD_IDX_LSB) |
+					((Phase & ((1 << CMD_FIR_COEFF_PHASE_IDX_WIDTH) -1)) << CMD_FIR_COEFF_PHASE_IDX_LSB)|
+					((Tap & ((1 << CMD_FIR_COEFF_TAP_IDX_WIDTH) -1)) << CMD_FIR_COEFF_TAP_IDX_LSB)|
+					((hGfxDeviceContext->HFIRCoeffTable[Phase][Tap] & 
+					  ((1 << CMD_FIR_COEFF_VALUE_WIDTH) -1)) << CMD_FIR_COEFF_VALUE_LSB);
+
+				GfxCMDQueSpace = Gfx_Send2DCmd(GfxCMD);
+			}
+		}
+	}
+
+	/* Update HFIR Coeff */
+	if ((hGfxDeviceContext->UpdateVFIRCoeff) && (GfxDCType & GFX_DC_SCALOR_VFIR_COFF))
+	{
+		u32 Phase = 0;
+		u32 Tap   = 0;
+		for (Phase = 0; Phase < SCALOR_PAHSE_NUM; Phase++)
+		{
+			for (Tap =0; Tap < SCALOR_V_FIR_TAP_NUM; Tap++)
+			{
+				GfxCMD = ((CMD_VFIR_COEFFICIETN_DATA & ((1 << CMD_IDX_WIDTH) -1)) << CMD_IDX_LSB) |
+					((Phase & ((1 << CMD_FIR_COEFF_PHASE_IDX_WIDTH) -1)) << CMD_FIR_COEFF_PHASE_IDX_LSB)|
+					((Tap & ((1 << CMD_FIR_COEFF_TAP_IDX_WIDTH) -1)) << CMD_FIR_COEFF_TAP_IDX_LSB)|
+					((hGfxDeviceContext->VFIRCoeffTable[Phase][Tap] &
+					  ((1 << CMD_FIR_COEFF_VALUE_WIDTH) -1)) << CMD_FIR_COEFF_VALUE_LSB);
+
+				GfxCMDQueSpace = Gfx_Send2DCmd(GfxCMD);
+			}
+		}
+	}
+
+	if (hGfxDeviceContext->S0ScalorEnable)
+	{
+		/* Scalor Source Pixel Map */
+		/* Send InitialPhase */
+		if ((GfxDCType & GFX_DC_SCALOR_INIT_PHASE))
+		{
+			GfxCMD = ((CMD_SCALOR_INITIAL_PHASE & ((1 << CMD_IDX_WIDTH) -1)) << CMD_IDX_LSB) |
+				((hGfxDeviceContext->HInitialPhase & ((1 << CMD_SCALOR_H_INIT_PHASE_WIDTH) -1)) << CMD_SCALOR_H_INIT_PHASE_LSB)|
+				((hGfxDeviceContext->VInitialPhase & ((1 << CMD_SCALOR_V_INIT_PHASE_WIDTH) -1)) << CMD_SCALOR_V_INIT_PHASE_LSB);
+
+			GfxCMDQueSpace = Gfx_Send2DCmd(GfxCMD);
+		}
+	}
+
+	/* Send Startup Command */
+	if ((GfxDCType & GFX_DC_CTRL))
+	{
+#if defined(CONFIG_MACH_CELESTIAL_CNC1800H)
+
+		//Send Endian Mode		
+		GlobalEndianCtrl = ((hGfxDeviceContext->DByteEndian   & 0x1) << BYTE_ENDIAN_BIT  )|
+			((hGfxDeviceContext->DNibbleEndian & 0x1) << NIBBLE_ENDIAN_BIT)|
+			((hGfxDeviceContext->D16BitEndian  & 0x1) << TWO_BYTE_ENDIAN_BIT);
+
+		GfxCMD = ((CMD_ENDIAN_CTRL & ((1 << CMD_IDX_WIDTH) -1)) << CMD_IDX_LSB)|
+			((S0EndianCtrl & ((1 << CMD_S0_ENDIAN_WIDTH) -1)) << CMD_S0_ENDIAN_LSB)|
+			((S1EndianCtrl & ((1 << CMD_S1_ENDIAN_WIDTH) -1)) << CMD_S1_ENDIAN_LSB)|
+			((DEndianCtrl & ((1 << CMD_D_ENDIAN_WIDTH) -1)) << CMD_D_ENDIAN_LSB )|
+			((GlobalEndianCtrl & ((1 << CMD_GLOBAL_ENDIAN_WIDTH) -1)) << CMD_GLOBAL_ENDIAN_LSB); 
+
+		GfxCMDQueSpace = Gfx_Send2DCmd(GfxCMD);
+#endif
+		/* Send Ctrl and Startup Cmd */
+		ScanCtrl = ((hGfxDeviceContext->S0VReverseScan & (1)) << S0_REVERSE_SCAN_BIT) |
+			((hGfxDeviceContext->S1VReverseScan & (1)) << S1_REVERSE_SCAN_BIT)  |
+			((hGfxDeviceContext->DVReverseScan & (1)) << D_REVERSE_SCAN_BIT);
+
+		CompositorOperation = ((hGfxDeviceContext->CompositorEnable & (1)) << COMPOSITOR_ENABLE_BIT)|
+			((hGfxDeviceContext->S0OnTopS1 & (1)) << S0_ON_TOP_S1_BIT);
+
+		S1Operation = ((hGfxDeviceContext->S1Enable & (1)) << S_ENABLE_BIT)|
+			((hGfxDeviceContext->S1ColorKeyEnable & (1)) << S_COLORKEY_ENABLE_BIT)|
+			((hGfxDeviceContext->S1ClutEnable & (1)) << S_CLUT_ENABLE_BIT) |
+			((hGfxDeviceContext->S1FetchDram & (1)) << S_FETCH_DATA_BIT);
+
+		S0Operation = ((hGfxDeviceContext->S0Enable & (1)) << S_ENABLE_BIT) |
+			((hGfxDeviceContext->S0ColorKeyEnable & (1)) << S_COLORKEY_ENABLE_BIT)|
+			((hGfxDeviceContext->S0ClutEnable & (1)) << S_CLUT_ENABLE_BIT)    |
+			((hGfxDeviceContext->S0FetchDram  & (1)) << S_FETCH_DATA_BIT);
+
+		GfxCMD = ((CMD_STARTUP  & ((1 << CMD_IDX_WIDTH) -1)) << CMD_IDX_LSB) |
+			((ScanCtrl & ((1 << SCAN_CTRL_WIDTH) -1)) << SCAN_CTRL_LSB) |
+			((hGfxDeviceContext->S0ScalorEnable & (0x1)) << S0_SCAL_ENA_BIT) |
+			((hGfxDeviceContext->InterruptEnable & ((1 << INT_ENABLE_WIDTH) -1)) << INT_ENABLE_LSB) |
+			((hGfxDeviceContext->ROPAlphaCtrl & ((1 << ROP_ALPHA_CTRL_WIDTH) -1)) << ROP_ALPHA_CTRL_LSB) |
+			((hGfxDeviceContext->RopValue & ((1 << ROP_VAL_WIDTH) -1)) << ROP_VAL_LSB) |
+			((CompositorOperation & ((1 << CMP_OPT_WIDTH) -1)) << CMP_OPT_LSB) |
+			((S1Operation  & ((1 << S1_OPT_WIDTH) -1)) << S1_OPT_LSB) |
+			((S0Operation  & ((1 << S0_OPT_WIDTH) -1)) << S0_OPT_LSB);
+
+		GfxCMDQueSpace = Gfx_Send2DCmd(GfxCMD);
+	}
+
+	hGfxDeviceContext->GfxDCType = GfxDCType;
+
+	return 0;
+}
+
+static int Gfx_2DComposite
+(
+    GFX_DEVICE_CONTEXT  	*hGfxDC, 
+    COLOR_IMG           	*Src0Img, 
+    RECT                	*Src0Rect, 
+    COLOR_IMG           	*Src1Img, 
+    RECT                	*Src1Rect, 
+    COLOR_IMG           	*DesImg, 
+    RECT                	*DesRect, 
+    ROP_OPT              	RopValue, 
+    u32 			BlendEnable, 
+    u32 			IsS0OnTopS1, 	
+    u32 			ROPAlphaCtrl
+)
+{
+    if (hGfxDC == NULL || Src0Img == NULL || Src1Img == NULL || \
+	    Src0Rect == NULL || Src1Rect == NULL || DesImg == NULL)
+    {
+	return -1;
+    }
+    else if ( ((Src0Img->ColorFormat != GFX_CF_ARGB1555) &&
+		(Src0Img->ColorFormat != GFX_CF_RGB565) &&
+		(Src0Img->ColorFormat != GFX_CF_ARGB4444) &&
+		(Src0Img->ColorFormat != GFX_CF_ARGB8888)) ||
+	    ((Src1Img->ColorFormat != GFX_CF_ARGB1555) &&
+	     (Src1Img->ColorFormat != GFX_CF_RGB565) &&
+	     (Src1Img->ColorFormat != GFX_CF_ARGB4444) && 
+	     (Src1Img->ColorFormat != GFX_CF_ARGB8888)) ||
+	    ((DesImg->ColorFormat != GFX_CF_ARGB1555) &&
+	     (DesImg->ColorFormat != GFX_CF_RGB565) &&
+	     (DesImg->ColorFormat != GFX_CF_ARGB4444) && 
+	     (DesImg->ColorFormat != GFX_CF_ARGB8888)) )
+    {
+	return -2; /* unsuported color format */
+    }
+    else if ( !Is_RectValid(Src0Img, Src0Rect) || 
+	    !Is_RectValid(Src1Img, Src1Rect) || 
+	    !Is_RectValid(DesImg, DesRect) )
+    {
+	return -3; /* invalid rectangle */
+    }
+    else if (!CmpRect(Src0Rect, Src1Rect)) // || !CmpRect(Src0Rect, DesRect))
+    {
+	return -4;
+    }
+
+    //S0 Control
+    {
+	hGfxDC->S0Enable       = 1;
+	hGfxDC->S0VReverseScan = 0; 		//don't use reverse scan
+	hGfxDC->S0FetchDram    = 1;          // 1 Fetch, 0 do not Fetch Using Default Color in ARGB
+
+	// if S0 Using Default Color then S0ColorType should be ARGB565 or A0
+	hGfxDC->S0ColorFormat  = Src0Img->ColorFormat; //Must
+	hGfxDC->S0DefaultColor.Alpha = Src0Img->DefaultColor.Alpha;
+
+	Calc_DramPara
+	    (
+	     Src0Img, 
+	     Src0Rect,	
+	     hGfxDC->S0VReverseScan,
+	     &hGfxDC->S0BaseAddr,              //Bytes Addr
+	     &hGfxDC->S0LinePitch,             //Bytes Addr
+	     &hGfxDC->S0SkipPixelLine         //Valid Only When Clut4
+	    );
+
+	hGfxDC->S0PixelNumOneLine    = Src0Rect->right  - Src0Rect->left;;
+	hGfxDC->S0TotalLineNum       = Src0Rect->bottom - Src0Rect->top;
+
+#if defined(CONFIG_MACH_CELESTIAL_CNC1800H)
+
+	hGfxDC->S0ByteEndian   = Src0Img->ByteEndian;
+	hGfxDC->S0NibbleEndian = Src0Img->NibbleEndian;
+	hGfxDC->S016BitEndian  = Src0Img->TwoBytesEndian;
+#endif
+
+	hGfxDC->S0ClutEnable   = 0;
+	hGfxDC->S0ColorKeyEnable= 0; 
+    }
+
+    //S1 Control
+    {
+	hGfxDC->S1Enable       = 1;
+	hGfxDC->S1VReverseScan = 0;
+	hGfxDC->S1FetchDram    = 1;          // 1 Fetch, 0 do not Fetch Using Default Color in ARGB
+
+	// if S1 Using Default Color then S1ColorType should be ARGB565 or A0
+	hGfxDC->S1ColorFormat  = Src1Img->ColorFormat; //Must
+	hGfxDC->S1DefaultColor.Alpha = Src1Img->DefaultColor.Alpha;
+
+	Calc_DramPara
+	    (
+	     Src1Img, 
+	     Src1Rect,	
+	     hGfxDC->S1VReverseScan,
+	     &hGfxDC->S1BaseAddr,              //Bytes Addr
+	     &hGfxDC->S1LinePitch,             //Bytes Addr
+	     &hGfxDC->S1SkipPixelLine         //Valid Only When Clut4
+	    );
+
+	hGfxDC->S1PixelNumOneLine    = Src1Rect->right  - Src1Rect->left;;
+	hGfxDC->S1TotalLineNum       = Src1Rect->bottom - Src1Rect->top;
+
+#if defined(CONFIG_MACH_CELESTIAL_CNC1800H)
+
+	hGfxDC->S1ByteEndian   = Src1Img->ByteEndian;
+	hGfxDC->S1NibbleEndian = Src1Img->NibbleEndian;
+	hGfxDC->S116BitEndian  = Src1Img->TwoBytesEndian;
+#endif
+
+
+	hGfxDC->S1ClutEnable   = 0;
+	hGfxDC->S1ColorKeyEnable= 0; 
+    }
+
+    /* ROP and Compositor */
+    hGfxDC->CompositorEnable   = BlendEnable;
+    hGfxDC->ROPAlphaCtrl       = ROPAlphaCtrl;
+    hGfxDC->RopValue           = RopValue;
+    hGfxDC->S0OnTopS1          = IsS0OnTopS1;             /* 1 S0 On Top S1 */
+
+    /* D Dram Para */
+    Calc_DramPara
+	(
+	 DesImg, 
+	 DesRect,	
+	 hGfxDC->DVReverseScan = 0,
+	 &hGfxDC->DBaseAddr,              //Bytes Addr
+	 &hGfxDC->DLinePitch,             //Bytes Addr
+	 &hGfxDC->DSkipPixelLine          //Valid Only When Clut4
+	);
+    hGfxDC->DPixelNumOneLine    = DesRect->right  - DesRect->left;
+    hGfxDC->DTotalLineNum       = DesRect->bottom - DesRect->top;
+    hGfxDC->DColorFormat        = DesImg->ColorFormat;
+
+#if defined(CONFIG_MACH_CELESTIAL_CNC1800H)
+
+	hGfxDC->DByteEndian         = DesImg->ByteEndian;
+    hGfxDC->DNibbleEndian       = DesImg->NibbleEndian;		
+    hGfxDC->D16BitEndian        = DesImg->TwoBytesEndian;
+#endif
+    //Scalor Control
+    hGfxDC->S0ScalorEnable   = 0;
+    hGfxDC->UpdateHFIRCoeff  = 0;
+    hGfxDC->UpdateVFIRCoeff  = 0;
+
+    //Clut para
+    hGfxDC->UpdateClut4Table = 0;
+    hGfxDC->UpdateClut8Table = 0;
+
+    /* RunTimeControl */
+    hGfxDC->InterruptEnable  = 0;
+
+    /* active DC */
+    Gfx_WaitForIdle(NULL);
+
+    if (0 != Gfx_ActiveDeviceContext(hGfxDC, GFX_DC_ALL))
+    {
+	return -5; /* failed to active device context */
+    }
+
+    return 0;
+}
+
+typedef struct _2d_comp_params{
+	RECT src0_rect;
+	u32 src0_width;
+	u32 src0_height;
+	int src0_color_format;
+	u32 src0_pitch_line;
+	u32 src0_bits_pixel;
+	u32 src0_phy_addr;
+
+	RECT src1_rect;
+	u32 src1_width;
+	u32 src1_height;
+	int src1_color_format;
+	u32 src1_pitch_line;
+	u32 src1_bits_pixel;
+	u32 src1_phy_addr;
+
+	RECT dst_rect;
+	u32 dst_width;
+	u32 dst_height;
+	int dst_color_format;
+	u32 dst_pitch_line;
+	u32 dst_bits_pixel;
+	u32 dst_phy_addr;
+} gfx2d_comp_params;
+
+int DFB_2DComposite(gfx2d_comp_params *params)
+{
+    COLOR_IMG Src0Img, Src1Img, DstImg;
+
+    memset(&Src0Img, 0, sizeof(Src0Img));
+    memset(&Src1Img, 0, sizeof(Src1Img));
+    memset(&DstImg, 0, sizeof(DstImg));
+
+#if defined(CONFIG_MACH_CELESTIAL_CNC1800H)
+    Src0Img.ByteEndian     = 1;
+    Src0Img.NibbleEndian   = 0;
+    Src1Img.ByteEndian     = 1;
+    Src1Img.NibbleEndian   = 0;
+
+    Src0Img.TwoBytesEndian = 1;
+    Src1Img.TwoBytesEndian = 1;
+    if (GFX_CF_ARGB8888 == params->src0_color_format)
+    {
+    	Src0Img.TwoBytesEndian = 0;
+    	Src1Img.TwoBytesEndian = 0;
+    }
+
+    DstImg.ByteEndian = Src0Img.ByteEndian;
+    DstImg.NibbleEndian = Src0Img.NibbleEndian;
+    DstImg.TwoBytesEndian = Src0Img.TwoBytesEndian;
+#endif
+	DstImg.ColorFormat = Src1Img.ColorFormat = Src0Img.ColorFormat = params->src0_color_format; /* GFX_CF_...*/
+
+    /* the default color for fill or draw */
+    //DstImg.DefaultColor.Alpha = Src1Img.DefaultColor.Alpha = Src0Img.DefaultColor.Alpha = 0x80;
+    Src0Img.DefaultColor.Alpha = 0x80;
+    Src1Img.DefaultColor.Alpha = 0xff;
+    DstImg.DefaultColor.Alpha = 0xff;
+    DstImg.DefaultColor.Red   = Src1Img.DefaultColor.Red  = Src0Img.DefaultColor.Red = 0xff;
+    DstImg.DefaultColor.Green = Src1Img.DefaultColor.Green = Src0Img.DefaultColor.Green = 0xff;
+    DstImg.DefaultColor.Blue  = Src1Img.DefaultColor.Blue = Src0Img.DefaultColor.Blue = 0xff;
+
+    Src0Img.PixelWidth = params->src0_width;
+    Src0Img.PixelHeight = params->src0_height;
+    Src0Img.LinePitch = params->src0_pitch_line;		
+    Src0Img.StartAddress = params->src0_phy_addr; 
+
+    Src1Img.PixelWidth = params->src1_width;
+    Src1Img.PixelHeight = params->src1_height;
+    Src1Img.LinePitch = params->src1_pitch_line;		
+    Src1Img.StartAddress = params->src1_phy_addr; 
+
+    DstImg.PixelWidth = params->dst_width;
+    DstImg.PixelHeight = params->dst_height;
+    DstImg.LinePitch = params->dst_pitch_line;
+    DstImg.StartAddress = params->dst_phy_addr;
+
+    return Gfx_2DComposite
+	(
+	 &Gfx_DC,
+	 &Src0Img, 
+	 &params->src0_rect, 
+	 &Src1Img, 
+	 &params->src1_rect, 
+	 &DstImg, 
+	 &params->dst_rect, 
+	 ROP_R2_COPYPEN, 
+	 1, 1, 	1
+	);
+}
+
+
+typedef struct _2d_scalor_params{
+	RECT src_rect;
+	u32 src_width;
+	u32 src_height;
+	int src_color_format;
+	u32 src_pitch_line;
+	u32 src_bits_pixel;
+	u32 src_phy_addr;
+
+	RECT dst_rect;
+	u32 dst_width;
+	u32 dst_height;
+	int dst_color_format;
+	u32 dst_pitch_line;
+	u32 dst_bits_pixel;
+	u32 dst_phy_addr;
+
+}gfx2d_scalor_params;
+
+int DFB_2DScalor(gfx2d_scalor_params *params)
+{
+	int hResult = -1;
+
+	unsigned int VInitialPhase = 4;
+	unsigned int HInitialPhase = 0;
+	signed int SrcVReverse = 0;
+	signed int DesVReverse = 0;
+
+	COLOR_IMG SrcImg, DstImg;
+
+	memset(&SrcImg, 0, sizeof(SrcImg));
+	memset(&DstImg, 0, sizeof(DstImg));
+
+#if defined(CONFIG_MACH_CELESTIAL_CNC1800H)
+
+	SrcImg.ByteEndian     = 1;
+	SrcImg.NibbleEndian   = 0;
+	SrcImg.TwoBytesEndian = 1;
+    
+	if (GFX_CF_ARGB8888 == params->src_color_format)
+    	{
+    		SrcImg.TwoBytesEndian = 0;
+    	}
+   
+	DstImg.ByteEndian = SrcImg.ByteEndian;
+	DstImg.NibbleEndian = SrcImg.NibbleEndian;
+	DstImg.TwoBytesEndian = SrcImg.TwoBytesEndian;
+#endif
+	DstImg.ColorFormat = SrcImg.ColorFormat = params->src_color_format; /* GFX_CF_...*/
+
+	/* the default color for fill or draw */
+	DstImg.DefaultColor.Alpha =  SrcImg.DefaultColor.Alpha = 0xff;
+	DstImg.DefaultColor.Red   = SrcImg.DefaultColor.Red = 0xff;
+	DstImg.DefaultColor.Green = SrcImg.DefaultColor.Green = 0xff;
+	DstImg.DefaultColor.Blue  = SrcImg.DefaultColor.Blue = 0xff;
+
+	SrcImg.PixelWidth = params->src_width;
+	SrcImg.PixelHeight = params->src_height;
+	SrcImg.LinePitch = params->src_pitch_line;		
+	SrcImg.StartAddress = params->src_phy_addr; 
+
+	DstImg.PixelWidth = params->dst_width;
+	DstImg.PixelHeight = params->dst_height;
+	DstImg.LinePitch = params->dst_pitch_line;
+	DstImg.StartAddress = params->dst_phy_addr;
+
+	hResult = Gfx_2DScalor(&Gfx_DC,
+			&SrcImg,
+			&params->src_rect,
+			SrcVReverse,
+			&DstImg,
+			&params->dst_rect,
+			DesVReverse,
+			12, /* copy pen */
+			VInitialPhase,
+			HInitialPhase);
+
+	return hResult;
+}
+
+static int Gfx_2DScalor( 
+		GFX_DEVICE_CONTEXT  *hGfxDC, 
+		COLOR_IMG           *SrcImg, 
+		RECT                *SrcRect, 
+		signed int           SrcVReverse,
+		COLOR_IMG           *DesImg, 
+		RECT                *DesRect, 
+		signed int           DesVReverse,
+		ROP_OPT              RopValue, 
+		u32                  VInitialPhase, 
+		u32                  HInitialPhase)
+{
+	if (SrcImg  == NULL ||
+			SrcRect == NULL ||
+			DesImg  == NULL ||
+			DesRect == NULL)
+	{
+		return -1; /* invalid parameters */
+	}
+	else if ((SrcImg->ColorFormat != GFX_CF_ARGB1555) &&
+			(SrcImg->ColorFormat != GFX_CF_RGB565) &&
+			(SrcImg->ColorFormat != GFX_CF_ARGB4444) &&
+			(SrcImg->ColorFormat != GFX_CF_ARGB8888))
+	{
+		return -2; /* unsuported color format */
+	}
+	else if ((DesImg->ColorFormat != GFX_CF_ARGB1555) &&
+			(DesImg->ColorFormat != GFX_CF_RGB565) &&
+			(DesImg->ColorFormat != GFX_CF_ARGB4444) &&
+			(DesImg->ColorFormat != GFX_CF_ARGB8888))
+	{
+		return -2; /* unsupported color format */
+	}
+	else if (!Is_RectValid(SrcImg, SrcRect))
+	{
+		return -3; /* invalid rectangle */
+	}
+	else if (!Is_RectValid(DesImg, DesRect))
+	{
+		return -4; /* invalid dst rectangle */
+	}
+
+	/* S0 Control */
+	{
+		hGfxDC->S0Enable       = 1;
+		hGfxDC->S0VReverseScan = SrcVReverse;
+		hGfxDC->S0FetchDram    = 1;
+		hGfxDC->S0ColorFormat  = SrcImg->ColorFormat;
+		hGfxDC->S0DefaultColor.Alpha = SrcImg->DefaultColor.Alpha;
+
+		Calc_DramPara(SrcImg, SrcRect,	
+				hGfxDC->S0VReverseScan,
+				&hGfxDC->S0BaseAddr,
+				&hGfxDC->S0LinePitch,
+				&hGfxDC->S0SkipPixelLine);
+
+		hGfxDC->S0PixelNumOneLine= SrcRect->right  - SrcRect->left;;
+		hGfxDC->S0TotalLineNum = SrcRect->bottom - SrcRect->top;
+
+#if defined(CONFIG_MACH_CELESTIAL_CNC1800H)
+
+		hGfxDC->S0ByteEndian   = SrcImg->ByteEndian;
+		hGfxDC->S0NibbleEndian = SrcImg->NibbleEndian;
+		hGfxDC->S016BitEndian  = SrcImg->TwoBytesEndian;
+#endif
+		hGfxDC->S0ClutEnable   = 0;
+		hGfxDC->S0ColorKeyEnable= 0; 
+	}
+
+	/* S1 Control */
+	{
+		hGfxDC->S1Enable = 0;
+		hGfxDC->S1FetchDram = 0;
+	}
+
+	/* ROP and Compositor */
+	hGfxDC->CompositorEnable = 0;
+	hGfxDC->ROPAlphaCtrl = 1;
+	hGfxDC->RopValue = RopValue;
+
+	/* S0 On Top S1 */
+
+	/* Dram Para */	
+	Calc_DramPara(DesImg,DesRect,
+			hGfxDC->DVReverseScan = DesVReverse,
+			&hGfxDC->DBaseAddr,
+			&hGfxDC->DLinePitch,
+			&hGfxDC->DSkipPixelLine);
+
+	hGfxDC->DPixelNumOneLine    = DesRect->right  - DesRect->left;;
+	hGfxDC->DTotalLineNum       = DesRect->bottom - DesRect->top;
+
+	hGfxDC->DColorFormat        = DesImg->ColorFormat;
+#if defined(CONFIG_MACH_CELESTIAL_CNC1800H)
+
+	hGfxDC->DByteEndian         = DesImg->ByteEndian;
+	hGfxDC->DNibbleEndian       = DesImg->NibbleEndian;		
+	hGfxDC->D16BitEndian        = DesImg->TwoBytesEndian;
+#endif
+	/* Scalor Control */
+	hGfxDC->S0ScalorEnable   = 1;
+	hGfxDC->HInitialPhase    = HInitialPhase;
+	hGfxDC->VInitialPhase    = VInitialPhase;
+	hGfxDC->UpdateHFIRCoeff  = 0;
+	hGfxDC->UpdateVFIRCoeff  = 0;
+
+	/* Clut para */
+	hGfxDC->UpdateClut4Table = 0;
+	hGfxDC->UpdateClut8Table = 0;
+
+	/* RunTimeControl */
+	hGfxDC->InterruptEnable  = 0;
+
+	/* active DC */
+	Gfx_WaitForIdle(NULL);
+
+	if (0 != Gfx_ActiveDeviceContext(hGfxDC, GFX_DC_ALL))
+	{
+		return -5; /* failed to active device context */
+	}
+
+	return 0;
+}
+
+int Gfx_2DInit(void)
+{
+	sGfxBaseAddr = (u32 *) VA_IO_GRAPHICS_BASE;
+	memset(&Gfx_DC, 0, sizeof(Gfx_DC));
+	Gfx_CMDGroupCntSyncHW();
+	
+	Gfx_2DReset();
+
+	Gfx_SetDefaultClut8Table(&Gfx_DC);
+
+	Gfx_SetDefaultScalorHFIRCoeff(&Gfx_DC);
+	Gfx_SetDefaultScalorVFIRCoeff(&Gfx_DC);
+
+	return 0;
+
+}
+
+static int Gfx_SetDefaultClut8Table(GFX_DEVICE_CONTEXT * hGfxDC)
+{
+	int hResult = -1;
+	u32 *Clut8Table = NULL;
+
+	if (hGfxDC == NULL) return hResult;
+
+	Clut8Table = Gfx_GetDefaultClut8Table();
+	if (Clut8Table == NULL)
+	{
+		return -2;
+	}
+
+	hResult = Gfx_InitClut8Tab(hGfxDC, Clut8Table);
+
+	return hResult;	
+}
+
+static int Gfx_InitClut8Tab( GFX_DEVICE_CONTEXT * hGfxDC, u32 *Clut8Table)
+{
+	if (hGfxDC == NULL || Clut8Table == NULL) return -1;
+
+	{
+		u32 *p = NULL;
+		for (p = hGfxDC->Clut8Table; p < hGfxDC->Clut8Table + CLUT8_TABLE_LEN; p++)
+		{
+			*p = *Clut8Table++;
+		}
+	}
+
+	/* Send CMD to Gfx HW */
+	hGfxDC->UpdateClut8Table = 1;
+	hGfxDC->UpdateClut8TableMode = 0;
+
+	if (0 != Gfx_ActiveDeviceContext(hGfxDC, GFX_DC_CLUT8_TABLE))
+	{
+		return -2;
+	}
+	hGfxDC->UpdateClut8Table = 0;
+	hGfxDC->UpdateClut8TableMode = 0;
+
+	return 0;
+}
+
+static u32 *Gfx_GetDefaultClut8Table(void)
+{
+	return _GfxCLUT8Pal;
+}
+
+static u32 SCALOR_COEFF( u32 SignBit, u32 Nmerator, u32 denominator) 
+{
+	return (((SignBit) << SCALOR_COEFF_POLARITY_BIT)  | \
+			((((Nmerator)) << SCALOR_COEFF_FRACTION_BIT_WIDTH ) / \
+			 (denominator)));
+}
+
+static int Gfx_InitScalorVFIRCoeff(GFX_DEVICE_CONTEXT *hGfxDC, u32 *VFIRCoeff)
+{
+	int hResult = -1;
+
+	if (hGfxDC == NULL || VFIRCoeff == NULL) 
+	{
+		return hResult;
+	}
+	else
+	{
+		u32 *p = NULL;
+
+		for (p = hGfxDC->VFIRCoeffTable[0];
+				p < hGfxDC->VFIRCoeffTable[0] + SCALOR_PAHSE_NUM * SCALOR_V_FIR_TAP_NUM;
+				p++)
+		{
+			*p = *VFIRCoeff++;
+		}
+
+		hGfxDC->UpdateVFIRCoeff = 1;
+
+		if (0 != Gfx_ActiveDeviceContext(hGfxDC, GFX_DC_SCALOR_VFIR_COFF))
+		{
+			hResult = -2;
+		}
+		else
+		{	
+			hResult = 0;
+		}
+
+		hGfxDC->UpdateVFIRCoeff = 0;
+
+		return hResult;
+	}	
+}
+
+static u32 *Gfx_GetDefaultScalorVFIRCoeff(void)
+{
+	static u32 VFIRCoeffTable[SCALOR_PAHSE_NUM][SCALOR_V_FIR_TAP_NUM];
+	u32 Phase = 0;
+
+	for (Phase = 0 ; Phase < SCALOR_PAHSE_NUM; Phase++)
+	{
+		VFIRCoeffTable[Phase][0] = SCALOR_COEFF( 0, (SCALOR_PAHSE_NUM - Phase), SCALOR_PAHSE_NUM);
+		VFIRCoeffTable[Phase][1] = SCALOR_COEFF( 0, (Phase), SCALOR_PAHSE_NUM);
+	}
+	return VFIRCoeffTable[0];	
+}
+
+static int Gfx_SetDefaultScalorVFIRCoeff(GFX_DEVICE_CONTEXT *hGfxDC)
+{	
+	if (hGfxDC == NULL)
+	{
+		return -1;
+	}
+	else /* Scalor Coeffecient Setting */
+	{
+		int hResult = -1;
+		u32 *VFIRCoeff = NULL;
+
+		VFIRCoeff = Gfx_GetDefaultScalorVFIRCoeff();
+
+		if (VFIRCoeff == NULL)
+		{
+			return hResult;
+		}
+
+		hResult = Gfx_InitScalorVFIRCoeff(hGfxDC, VFIRCoeff);
+
+		return hResult;
+	}
+}
+
+static int Gfx_InitScalorHFIRCoeff(GFX_DEVICE_CONTEXT *hGfxDC, u32 *HFIRCoeff)
+{
+	if (hGfxDC == NULL || HFIRCoeff == NULL) 
+	{
+		return -1;
+	}
+	else
+	{
+		int hResult = -1;
+		u32 *p = NULL;
+
+		for (p = hGfxDC->HFIRCoeffTable[0];
+				p < hGfxDC->HFIRCoeffTable[0] + SCALOR_PAHSE_NUM * SCALOR_H_FIR_TAP_NUM;
+				p++)
+		{
+			*p = *HFIRCoeff++;
+		}
+
+		hGfxDC->UpdateHFIRCoeff = 1;
+		if (0 != Gfx_ActiveDeviceContext(hGfxDC, GFX_DC_SCALOR_HFIR_COFF))
+		{
+			hResult = -2;
+		}
+		else
+		{	
+			hResult = 0;
+		}
+
+		hGfxDC->UpdateHFIRCoeff = 0;
+
+		return hResult;
+	}
+}
+
+static u32 *Gfx_GetDefaultScalorHFIRCoeff(void)
+{
+	u32 Phase = 0;
+	static u32 HFIRCoeffTable[SCALOR_PAHSE_NUM][SCALOR_H_FIR_TAP_NUM];
+
+	for (Phase = 0 ; Phase < SCALOR_PAHSE_NUM; Phase++)
+	{
+		HFIRCoeffTable[Phase][0] = 0;
+		HFIRCoeffTable[Phase][1] = SCALOR_COEFF( 0, (SCALOR_PAHSE_NUM - Phase), SCALOR_PAHSE_NUM);
+		HFIRCoeffTable[Phase][2] = SCALOR_COEFF( 0, (Phase), SCALOR_PAHSE_NUM);
+		HFIRCoeffTable[Phase][3] = 0;
+	}
+
+	return HFIRCoeffTable[0];
+}
+
+static int Gfx_SetDefaultScalorHFIRCoeff(GFX_DEVICE_CONTEXT *hGfxDC)
+{
+	if (hGfxDC == NULL)
+	{
+		return -1;
+	}
+	else /* Scalor Coeffecient Setting */
+	{
+		int hResult = -1;
+		u32 *HFIRCoeff = NULL;
+
+		HFIRCoeff = Gfx_GetDefaultScalorHFIRCoeff();
+
+		if (HFIRCoeff == NULL)
+		{
+			return hResult;
+		}
+
+		hResult = Gfx_InitScalorHFIRCoeff(hGfxDC, HFIRCoeff);
+
+		return hResult;
+	}
+}
+
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/video/celestial/cncfb.c linux-linaro-3.4-2012.05-1_cavium/drivers/video/celestial/cncfb.c
--- linux-linaro-3.4-2012.05-1_original/drivers/video/celestial/cncfb.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/video/celestial/cncfb.c	2015-07-29 17:02:43.002027000 +0800
@@ -0,0 +1,1248 @@
+/*
+ *  linux/drivers/video/celestial/cncfb.c -- Cavium celestial frame buffer device
+ *
+ *  Copyright (C) 2010 Celestial Semiconductor
+ *  Copyright (C) 2011 Cavium
+ *
+ *  This file is subject to the terms and conditions of the GNU General Public
+ *  License. See the file COPYING in the main directory of this archive for
+ *  more details.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <asm/uaccess.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <mach/hardware.h>
+#include <mach/mem_define.h>
+#include <mach/cnc1900_df.h>
+#include "cncfb.h"
+
+#include "cnc19xx_fb_hw.h"
+
+#include "cnc_2d.c"
+
+#define FB_ACCEL_CNC_2DGFX	0xff
+
+#define DEVICE_NAME 	"cncfb"
+
+/* There are FB_NUMS framebuffers, each represented by an fb_info. */
+#define GFX0_FBNAME	"gfx0"
+#define GFX1_FBNAME	"gfx1"
+#define GFX2_FBNAME	"gfx2"
+#define GFX3_FBNAME	"gfx3"
+
+int outputmode = -1;
+int colorformat = -1;
+EXPORT_SYMBOL(outputmode);
+static int __init root_outputmode_setup(char *str)
+{
+	outputmode = simple_strtoul(str, NULL, 0);
+	return 1;
+}
+
+static int __init root_colorformat_setup(char *str)
+{
+	colorformat = simple_strtoul(str, NULL, 0);
+	return 1;
+}
+
+__setup("outputmode=", root_outputmode_setup);
+__setup("colorformat=", root_colorformat_setup);
+
+//#define FB_DEBUG
+#ifdef FB_DEBUG
+#define DEBUG(args...) 		\
+	do {						\
+		printk(KERN_INFO args); \
+	} while(0)
+#else
+#define DEBUG(args...) do { } while(0)
+#endif
+
+struct cnc_info cncfb_static;
+struct cnc_info *cncfbinfo = &cncfb_static;
+
+struct fb_var_screeninfo cncfb_default = {
+	.xres =         1280,
+	.yres =         720,
+	.xres_virtual = 1280,
+	.yres_virtual = 720,
+	.bits_per_pixel = 32,
+
+#ifdef CONFIG_CELESTIAL_GFX_ARGB_MODE
+
+	.transp =		{ 24, 8, 0 },
+	.red =          { 16, 8, 0 },
+	.green =        {  8, 8, 0 },
+	.blue =         {  0, 8, 0 },
+
+#else
+
+	.transp =		{ 0, 8, 0 },
+	.red =          { 8, 8, 0 },
+	.green =        {  16, 8, 0 },
+	.blue =         {  24, 8, 0 },
+
+#endif
+
+	.height =       -1,
+	.width =        -1,
+	.pixclock =     74074,
+	.left_margin =  0,
+	.right_margin = 0,
+	.upper_margin = 0,
+	.lower_margin = 0,
+	.hsync_len =    144,
+	.vsync_len =    49,
+	.vmode =        FB_VMODE_NONINTERLACED,
+	.activate =     FB_ACTIVATE_NOW,
+};
+
+static struct fb_fix_screeninfo cncfb_fix __devinitdata = {
+	.id =           DEVICE_NAME,
+	.smem_start =   FB0_REGION,
+	.smem_len   =   FB0_SIZE,
+	.type =         FB_TYPE_PACKED_PIXELS,
+	.visual =       FB_VISUAL_TRUECOLOR,
+	.xpanstep =     32,
+	.ypanstep =     1,
+	.ywrapstep =    0,
+	.line_length =  5120,
+	.mmio_start  =  PA_IO_GRAPHICS_BASE,
+	.mmio_len    =  IO_GRAPHICS_SIZE,
+	.accel =        FB_ACCEL_CNC_2DGFX,
+};
+
+static struct fb_fix_screeninfo cncfb_fix2 __devinitdata = {
+	.id =           DEVICE_NAME,
+	.smem_start =   FB1_REGION,
+	.smem_len   =   FB1_SIZE,
+	.type =         FB_TYPE_PACKED_PIXELS,
+	.visual =       FB_VISUAL_TRUECOLOR,
+	.xpanstep =     32,
+	.ypanstep =     1,
+	.ywrapstep =    0,
+	.line_length =  5120,
+	.mmio_start  =  PA_IO_GRAPHICS_BASE,
+	.mmio_len    =  IO_GRAPHICS_SIZE,
+	.accel =        FB_ACCEL_CNC_2DGFX,
+};
+
+static struct fb_fix_screeninfo cncfb_fix3 __devinitdata = {
+	.id =           DEVICE_NAME,
+	.smem_start =   FB2_REGION,
+	.smem_len   =   FB2_SIZE,
+	.type =         FB_TYPE_PACKED_PIXELS,
+	.visual =       FB_VISUAL_TRUECOLOR,
+	.xpanstep =     32,
+	.ypanstep =     1,
+	.ywrapstep =    0,
+	.line_length =  5120,
+	.mmio_start  =  PA_IO_GRAPHICS_BASE,
+	.mmio_len    =  IO_GRAPHICS_SIZE,
+	.accel =        FB_ACCEL_CNC_2DGFX,
+};
+
+static struct fb_fix_screeninfo cncfb_fix4 __devinitdata = {
+	.id =           DEVICE_NAME,
+	.smem_start =   FB3_REGION,
+	.smem_len   =   FB3_SIZE,
+	.type =         FB_TYPE_PACKED_PIXELS,
+	.visual =       FB_VISUAL_TRUECOLOR,
+	.xpanstep =     32,
+	.ypanstep =     1,
+	.ywrapstep =    0,
+	.line_length =  5120,
+	.mmio_start  =  PA_IO_GRAPHICS_BASE,
+	.mmio_len    =  IO_GRAPHICS_SIZE,
+	.accel =        FB_ACCEL_CNC_2DGFX,
+};
+
+static struct res_i {
+	u_long xres;
+	u_long yres;
+} res_t[] = {
+	{720,	576},
+	{720,	480},
+	{1280,	720},
+	{1920,	1080},
+	{640,	480},
+	{800,	600},
+	{1024,	768},
+	{1280,	1024},
+	{1600,	1000},
+	{848,	480},
+	{800,	480},
+	{1440,	900},
+	{1360,	768},
+	{1366,	768},
+	{1600,     1200}};
+
+static int cncfb_check_var(struct fb_var_screeninfo *var,
+		struct fb_info *info);
+static int cncfb_set_par(struct fb_info *info);
+static int cncfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+		u_int transp, struct fb_info *info);
+static int cncfb_pan_display(struct fb_var_screeninfo *var,
+		struct fb_info *info);
+static int cncfb_blank(int blank, struct fb_info *info);
+static int cncfb_ioctl(struct fb_info* info, u_int cmd, u_long arg);
+static int cncfb_open(struct fb_info *info, int user);
+static int cncfb_release(struct fb_info *info, int user);
+
+static struct fb_ops cncfb_ops = {
+	.fb_open        = cncfb_open,
+	.fb_release     = cncfb_release,
+	.fb_check_var   = cncfb_check_var,
+	.fb_set_par     = cncfb_set_par,
+	.fb_setcolreg   = cncfb_setcolreg,
+	.fb_pan_display = cncfb_pan_display,
+	.fb_blank       = cncfb_blank,
+	.fb_ioctl       = cncfb_ioctl,
+	.fb_fillrect    = cfb_fillrect,
+	.fb_copyarea    = cfb_copyarea,
+	.fb_imageblit   = cfb_imageblit
+		//	.fb_cursor      = soft_cursor
+};
+
+/*
+ * Internal routines
+ */
+static u_long get_line_length(int xres_virtual, int bpp)
+{
+	u_long length;
+
+	length = xres_virtual * bpp;
+#ifdef __ASM_ARCH_CNC1800L_H
+	length = (length + 15) & ~15;
+#else
+	length = (length + 127) & ~127;
+#endif
+	length >>= 3;
+
+	return length;
+}
+
+
+/* open fb device,  empty to do somthing in the future */
+static int cncfb_open(struct fb_info *info, int user)
+{
+	//	Gfx_2DInit();
+	DEBUG("framebuff open!\n");
+	return 0;
+}
+
+/* close fb device, empty to do somthing in the future */
+static int cncfb_release(struct fb_info *info, int user)
+{
+	return 0;
+}
+
+
+/*
+ * Setting the video mode has been split into two parts.
+ * First part, xxxfb_check_var, must not write anything
+ * to hardware, it should only verify and adjust var.
+ * This means it doesn't alter par but it does use hardware
+ * data from it to check this var.
+ */
+static int cncfb_check_var(struct fb_var_screeninfo *var,
+		struct fb_info *info)
+{
+	u_long i;
+	u_long line_length;
+	u_long valid_res = 0;
+
+	if (var == NULL || info == NULL ) {
+		DEBUG("CNCFB: %s failed! Bad parameters\n", __FUNCTION__);
+		return -EINVAL;
+	}
+	/*
+	 *  FB_VMODE_CONUPDATE and FB_VMODE_SMOOTH_XPAN are equal!
+	 *  as FB_VMODE_SMOOTH_XPAN is only used internally
+	 */
+	DEBUG("[checkvar-node:%d] var.activate=%d, info.var.activate=%d\n",info->node, var->activate, info->var.activate);
+	if (var->vmode & FB_VMODE_CONUPDATE) {
+		var->vmode |= FB_VMODE_YWRAP;
+		var->xoffset = info->var.xoffset;
+		var->yoffset = info->var.yoffset;
+	}
+
+	/* minimal resolution */
+	if (!var->xres)
+		var->xres = 32;
+	if (!var->yres)
+		var->yres = 2;
+
+	/* validate resolutions */
+	for(i = 0; i < sizeof(res_t)/sizeof(struct res_i); i++) {
+		if(res_t[i].yres == (var->upper_margin + var->yres + var->lower_margin) &&
+				res_t[i].xres == (var->left_margin  + var->xres + var->right_margin )) {
+			valid_res = 1;
+			break;
+		}
+	}
+
+	if(!valid_res)
+	{
+		DEBUG("CNCFB: %s failed! no validate resolution\n", __FUNCTION__);
+		return -EINVAL;
+	}
+
+	if (var->xres > var->xres_virtual)
+		var->xres_virtual = var->xres;
+	if (var->yres > var->yres_virtual)
+		var->yres_virtual = var->yres;
+	if (var->bits_per_pixel <= 4)
+		var->bits_per_pixel = 4;
+	else if (var->bits_per_pixel <= 8)
+		var->bits_per_pixel = 8;
+	else if (var->bits_per_pixel <= 16)
+		var->bits_per_pixel = 16;
+	else if (var->bits_per_pixel <= 32)
+		var->bits_per_pixel = 32;
+	else
+	{
+		DEBUG("CNCFB: %s failed! no validate bits_per_pixel\n", __FUNCTION__);
+		return -EINVAL;
+	}
+
+	/* width must be 16byte aligned */
+#if 0//ndef __ASM_ARCH_CNC1800L_H //majia add this.
+	if(var->xres % (16 * 8 / var->bits_per_pixel) != 0)
+	{
+		return -EINVAL;
+	}
+#endif
+
+	if (var->xres_virtual < var->xoffset + var->xres)
+		var->xres_virtual = var->xoffset + var->xres;
+	if (var->yres_virtual < var->yoffset + var->yres)
+		var->yres_virtual = var->yoffset + var->yres;
+
+	/*
+	 *  Memory limit
+	 */
+	line_length = get_line_length(var->xres_virtual, var->bits_per_pixel);
+	if (line_length * var->yres_virtual > info->fix.smem_len)
+	{
+		return -ENOMEM;
+	}
+
+	/*
+	 * Now that we checked it we alter var. The reason being is that the video
+	 * mode passed in might not work but slight changes to it might make it
+	 * work. This way we let the user know what is acceptable.
+	 */
+	switch (var->bits_per_pixel)
+	{
+		case 8:
+			var->red.offset = 0;
+			var->red.length = 8;
+			var->green.offset = 0;
+			var->green.length = 8;
+			var->blue.offset = 0;
+			var->blue.length = 8;
+			var->transp.offset = 0;
+			var->transp.length = 0;
+			break;
+
+		case 16:
+			if (var->transp.length == 4) {    /* ARGB4444 */
+				var->red.offset = 8;
+				var->red.length = 4;
+				var->green.offset = 4;
+				var->green.length = 4;
+				var->blue.offset = 0;
+				var->blue.length = 4;
+				var->transp.offset = 12;
+				var->transp.length = 4;
+			} else if(var->transp.length) {   /* ARGB1555 */
+				var->red.offset = 10;
+				var->red.length = 5;
+				var->green.offset = 5;
+				var->green.length = 5;
+				var->blue.offset = 0;
+				var->blue.length = 5;
+				var->transp.offset = 15;
+				var->transp.length = 1;
+			} else {        		  /* RGB 565 */
+				var->red.offset = 11;
+				var->red.length = 5;
+				var->green.offset = 5;
+				var->green.length = 6;
+				var->blue.offset = 0;
+				var->blue.length = 5;
+				var->transp.offset = 0;
+				var->transp.length = 0;
+			}
+			break;
+		case 32:
+
+#ifdef CONFIG_CELESTIAL_GFX_ARGB_MODE /* default for CNC1800L */
+			var->red.offset = 16;
+			var->red.length = 8;
+			var->green.offset = 8;
+			var->green.length = 8;
+			var->blue.offset = 0;
+			var->blue.length = 8;
+			var->transp.offset = 24;
+			var->transp.length = 8;
+
+#else /*BGRA default for CNC1800H */
+			var->transp.offset = 0;
+			var->transp.length = 8;
+			var->red.offset = 8;
+			var->red.length = 8;
+			var->green.offset = 16;
+			var->green.length = 8;
+			var->blue.offset = 24;
+			var->blue.length = 8;
+#endif
+
+			break;
+	}
+
+	var->red.msb_right = 0;
+	var->green.msb_right = 0;
+	var->blue.msb_right = 0;
+	var->transp.msb_right = 0;
+	//    var->activate = FB_ACTIVATE_FORCE;
+	return 0;
+}
+
+/* This routine actually sets the video mode. It's in here where we
+ * the hardware state info->par and fix which can be affected by the
+ * change in par. For this driver it doesn't do much.
+ */
+static int cncfb_set_par(struct fb_info *info)
+{
+	if (info == NULL ) {
+		printk("CNCFB: set par error! info==NULL!\n");
+		return -EINVAL;
+	}
+	if (cncfbinfo->fbs_lst[info->node].info == NULL)
+		return -EINVAL;
+
+	DEBUG("[setpar-node:%d]var:bits_per_pixel=%d, var:xres=%d, var:yres=%d, var:xres_virtual=%d, var.vmode=%d(0:non, 1:laced)\n",
+			info->node, info->var.bits_per_pixel, info->var.xres, info->var.yres, info->var.xres_virtual, info->var.vmode);
+
+
+	if(info->node >1 ){
+
+		if (cncfbinfo->fbs_lst[info->node -2].info == NULL ) {
+			return 0;
+		}else {
+
+			cncfbinfo->fbs_lst[info->node -2].info->fix.line_length    = get_line_length(cncfbinfo->fbs_lst[info->node -2].info->var.xres_virtual, info->var.bits_per_pixel);
+
+			cncfbinfo->fbs_lst[info->node -2].info->var.bits_per_pixel   = info->var.bits_per_pixel;
+			cncfbinfo->fbs_lst[info->node -2].info->var.transp.offset    = info->var.transp.offset;
+			cncfbinfo->fbs_lst[info->node -2].info->var.transp.length    = info->var.transp.length;
+			cncfbinfo->fbs_lst[info->node -2].info->var.transp.msb_right = info->var.transp.msb_right;
+			cncfbinfo->fbs_lst[info->node -2].info->var.red.offset       = info->var.red.offset;
+			cncfbinfo->fbs_lst[info->node -2].info->var.red.length       = info->var.red.length;
+			cncfbinfo->fbs_lst[info->node -2].info->var.red.msb_right    = info->var.red.msb_right;
+			cncfbinfo->fbs_lst[info->node -2].info->var.green.offset     = info->var.green.offset;
+			cncfbinfo->fbs_lst[info->node -2].info->var.green.length     = info->var.green.length;
+			cncfbinfo->fbs_lst[info->node -2].info->var.green.msb_right  = info->var.green.msb_right;
+			cncfbinfo->fbs_lst[info->node -2].info->var.blue.offset      = info->var.blue.offset;
+			cncfbinfo->fbs_lst[info->node -2].info->var.blue.length      = info->var.blue.length;
+			cncfbinfo->fbs_lst[info->node -2].info->var.blue.msb_right   = info->var.blue.msb_right;
+			cncfbinfo->fbs_lst[info->node -2].info->var.yres_virtual     = cncfbinfo->fbs_lst[info->node -2].info->fix.smem_len / cncfbinfo->fbs_lst[info->node -2].info->fix.line_length ;
+			//cncfbinfo->fbs_lst[info->node -2].info->var.vmode   = info->var.vmode;
+		}
+	} else {
+		cncfbinfo->fbs_lst[info->node ].info->fix.line_length    = get_line_length(info->var.xres_virtual, info->var.bits_per_pixel);
+		memcpy(&(cncfbinfo->fbs_lst[info->node ].info->var), &(info->var), sizeof(struct fb_var_screeninfo));
+		cncfbinfo->fbs_lst[info->node].info->var.yres_virtual     = info->fix.smem_len / cncfbinfo->fbs_lst[info->node].info->fix.line_length ;
+	}
+	info->fix.visual = (info->var.bits_per_pixel <= 8) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
+	if (info->var.bits_per_pixel != 0) {
+		info->fix.line_length = get_line_length(info->var.xres_virtual, info->var.bits_per_pixel);
+		info->var.yres_virtual = info->fix.smem_len / info->fix.line_length;
+		DEBUG("[set_par]fix.line_length=0x%x, var.activate=%d\n", info->fix.line_length, info->var.activate);
+	}
+
+	return cncfb_hw_set_par(info, cncfbinfo);
+
+}
+
+/*
+ * Set a single color register. The values supplied are already
+ * rounded down to the hardware's capabilities (according to the
+ * entries in the var structure). Return != 0 for invalid regno.
+ */
+static int cncfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+		u_int transp, struct fb_info *info)
+{
+	if (info == NULL ) {
+		DEBUG("CNCFB: %s failed!\n", __FUNCTION__);
+		return -EINVAL;
+
+	}
+	if (regno >= 256) return 1; /* no. of hw registers */
+	/*
+	 * Program hardware... do anything you want with transp
+	 */
+
+	/* grayscale works only partially under directcolor */
+	if (info->var.grayscale) {
+		/* grayscale = 0.30*R + 0.59*G + 0.11*B */
+		red = green = blue =
+			(red * 77 + green * 151 + blue * 28) >> 8;
+	}
+
+	return cncfb_hw_setcolreg(regno, red, green, blue, transp, info, cncfbinfo);
+}
+
+/*
+ * Pan or Wrap the Display
+ *
+ * This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
+ */
+static int cncfb_pan_display(struct fb_var_screeninfo *var,
+		struct fb_info *info)
+{
+	if (var== NULL || info == NULL)
+		return -EINVAL;
+
+	if (var->vmode & FB_VMODE_YWRAP) {
+		return -EINVAL;
+	} else {
+		if (var->xoffset + var->xres > info->var.xres_virtual ||
+				var->yoffset + var->yres > info->var.yres_virtual)
+			return -EINVAL;
+	}
+
+	info->var.xoffset = var->xoffset;
+	info->var.yoffset = var->yoffset;
+
+	return cncfb_hw_pan_display(info, cncfbinfo);
+}
+
+/*
+ * Blank (disable) the Graphics Layer
+ *
+ */
+static int cncfb_blank(int blank, struct fb_info *info)
+{
+	if (info == NULL ){
+		DEBUG("CNCFB: %s failed!\n", __FUNCTION__);
+		return -EINVAL;
+	}
+	DEBUG("CNCFB: %s in!\n", __FUNCTION__);
+	return cncfb_hw_blank(blank);
+}
+
+
+static int USE2D_COMP_NOTSCALOR = 1; /* 2D scalor or comp while 576i ? 0:scalor, 1:comp*/
+static int cncfb_ioctl(struct fb_info* info, unsigned int cmd, unsigned long arg)
+{
+
+	if (info == NULL )
+		return -EINVAL;
+	if (cncfbinfo->fbs_lst[info->node].info == NULL)
+		return -EINVAL;
+#if !defined(CONFIG_FORCE_TWO_OSD_LAYER) && !defined(CONFIG_TWO_OSD_LAYER_SUPPORT)
+	if (cncfbinfo->fbs_lst[0].info != NULL) {
+		if ( cncfbinfo->fbs_lst[0].info->var.bits_per_pixel == 32 &&
+				(info->node == 1 || info->node == 3))
+			return 0;
+	}
+#endif
+	switch(cmd) {
+		case FBIO_WAITFORVSYNC:
+			return cncfb_hw_waitforvsync(info);
+
+        case FBIO_GFX_SET_UI_ENDIAN:
+            return cncfb_hw_setendian(info, arg);
+
+		case FBIO_GFX_ON:
+			return cncfb_hw_gfx_on(info, arg, cncfbinfo);
+
+		case FBIO_GFX_ALPHA:
+			return cncfb_hw_gfx_alpha(info, arg, cncfbinfo);
+
+		case FBIO_GFX_BGCOLOR:
+
+			return cncfb_hw_setbgcolor(info,arg);
+
+
+		case FBIO_Z_ORDER:
+			return cncfb_hw_z_order(info, arg);
+
+		case FBIO_GFX_COLORKEY_ON:
+			return cncfb_hw_colorkey_on(info, arg, cncfbinfo);
+
+		case FBIO_GFX_COLORKEY_VAL:
+			{
+				gfx_colorkey col_key = {
+					0x00, 0x00, 0x00,
+					0x00, 0x00, 0x00
+				};
+
+				if (NULL != (void *)arg)
+					if (copy_from_user(&col_key, (void*)arg, sizeof(col_key))) return -EFAULT;
+
+				return cncfb_hw_colorkey_val(info, &col_key, cncfbinfo);
+			}
+		case FBIO_GFX_OPAQUE_ONOFF:
+			{
+				return cncfb_hw_opaque_onoff(info, arg);
+			}
+		case FBIO_GFX_CONFIG_DISTRECT:
+			{
+				gfx_rect rect;
+				printk(KERN_INFO"FBIO_GFX_CONFIG_DISTRECT\n");
+				if (NULL != (void *)arg) {
+					if (copy_from_user(&rect, (void*)arg, sizeof(gfx_rect)))
+						return -EFAULT;
+					}
+				printk(KERN_INFO"sx=%d, sy=%d, ex=%d, ey=%d\n",rect.startx,rect.starty,rect.endx,rect.endy);
+				return cncfb_hw_config_distrect(info, &rect);
+			}
+
+		case FBIO_GFX_FLIP:
+			{
+				gfx2d_scalor_params blit_conf, blit_conf2;
+
+				if (info->node < 2) return -EINVAL; /* FIXME@zhongkai's ugly code. */
+
+				blit_conf.src_rect.left = 0;
+				blit_conf.src_rect.top = 0;
+				blit_conf.src_rect.right = info->var.xres;
+				blit_conf.src_rect.bottom = info->var.yres;
+				blit_conf.src_width = info->var.xres;
+				blit_conf.src_height = info->var.yres;
+				blit_conf.src_color_format = (info->var.bits_per_pixel == 32) ? 6 /* GFX_FMT_ARGB8888 */
+					: (info->var.bits_per_pixel == 8) ? 5 /* GFX_FMT_CLUT8 */
+					: (info->var.transp.length == 0)  ? 0 /* GFX_FMT_RGB565 */
+					: (info->var.transp.length == 1)  ? 3 /* GFX_FMT_ARGB1555 */
+					: (info->var.transp.length == 4)  ? 1 /* GFX_FMT_ARGB4444 */
+					: 4; /* GFX_FMT_CLUT4 */
+				blit_conf.src_pitch_line = info->fix.line_length;
+				blit_conf.src_bits_pixel = info->var.bits_per_pixel;
+				blit_conf.src_phy_addr = info->fix.smem_start;
+
+				blit_conf.dst_rect.left = 0;
+				blit_conf.dst_rect.top = 0;
+				blit_conf.dst_rect.right = cncfbinfo->fbs_lst[info->node-2].info->var.xres;
+				blit_conf.dst_rect.bottom = cncfbinfo->fbs_lst[info->node-2].info->var.yres;
+				blit_conf.dst_width = cncfbinfo->fbs_lst[info->node-2].info->var.xres;
+				blit_conf.dst_height = cncfbinfo->fbs_lst[info->node-2].info->var.yres;
+				blit_conf.dst_color_format = blit_conf.src_color_format;
+				blit_conf.dst_pitch_line = cncfbinfo->fbs_lst[info->node-2].info->fix.line_length;
+				blit_conf.dst_bits_pixel = cncfbinfo->fbs_lst[info->node-2].info->var.bits_per_pixel;
+				//				blit_conf.dst_phy_addr = cncfbinfo->fbs_lst[info->node-2].info->fix.smem_start;
+				blit_conf.dst_phy_addr = (cncfbinfo->fbs_lst[info->node-2].info->fix.smem_start +
+						cncfbinfo->fbs_lst[info->node-2].info->fix.line_length * cncfbinfo->fbs_lst[info->node-2].info->var.yoffset +
+						cncfbinfo->fbs_lst[info->node-2].info->var.xoffset * cncfbinfo->fbs_lst[info->node-2].info->var.bits_per_pixel / 8);
+				//				printk("blit_conf.dst_phy_addr = 0x%x, info->var.yoffset  = %d\n",blit_conf.dst_phy_addr, cncfbinfo->fbs_lst[info->node-2].info->var.yoffset );
+
+				if (NULL != (void *)arg) {
+					if (copy_from_user(&blit_conf2, (void*)arg, sizeof(blit_conf)))
+						return -EFAULT;
+
+					blit_conf.src_rect.left = blit_conf2.src_rect.left;
+					blit_conf.src_rect.top = blit_conf2.src_rect.top;
+					blit_conf.src_rect.right = blit_conf2.src_rect.right;
+					blit_conf.src_rect.bottom = blit_conf2.src_rect.bottom;
+
+					blit_conf.dst_rect.left = blit_conf2.dst_rect.left;
+					blit_conf.dst_rect.top = blit_conf2.dst_rect.top;
+					blit_conf.dst_rect.right = blit_conf2.dst_rect.right;
+					blit_conf.dst_rect.bottom = blit_conf2.dst_rect.bottom;
+
+					goto do_scaler;
+				}
+
+				/* for 576&480 */
+				if (((blit_conf.src_rect.top-blit_conf.src_rect.bottom) !=
+							(blit_conf.dst_rect.top-blit_conf.dst_rect.bottom)) ||
+						((blit_conf.src_rect.right-blit_conf.src_rect.left) !=
+						 (blit_conf.dst_rect.right-blit_conf.dst_rect.left)))
+
+					goto do_scaler;
+
+				if ((cncfbinfo->fbs_lst[info->node-2].info->var.yres) <= 576 &&
+						(1 == cncfbinfo->fbs_lst[info->node-2].info->var.vmode)) {
+
+					if(USE2D_COMP_NOTSCALOR == 0) { /* force 2D scalor */
+						blit_conf.src_rect.left = 1;
+						blit_conf.src_rect.top = 1;
+						blit_conf.src_rect.right = info->var.xres - 1;
+						blit_conf.src_rect.bottom = info->var.yres - 1;
+
+					} else if(USE2D_COMP_NOTSCALOR == 1) { /* 2D comp */
+						gfx2d_comp_params comp_param;
+						comp_param.src1_rect.left = comp_param.src0_rect.left = blit_conf.src_rect.left;
+						comp_param.src1_rect.top = comp_param.src0_rect.top = blit_conf.src_rect.top;
+						comp_param.src1_rect.right = comp_param.src0_rect.right = blit_conf.src_rect.right;
+						comp_param.src1_rect.bottom = comp_param.src0_rect.bottom = blit_conf.src_rect.bottom;
+						comp_param.src1_width = comp_param.src0_width =
+							blit_conf.src_rect.right - blit_conf.src_rect.left;// info->var.xres;
+						comp_param.src1_height = comp_param.src0_height =
+							blit_conf.src_rect.bottom - blit_conf.src_rect.top;//info->var.yres;
+						comp_param.src1_color_format = comp_param.src0_color_format =
+							(info->var.bits_per_pixel == 32)  ? 6 /* GFX_FMT_ARGB8888 */
+							: (info->var.bits_per_pixel == 8) ? 5 /* GFX_FMT_CLUT8 */
+							: (info->var.transp.length == 0)  ? 0 /* GFX_FMT_RGB565 */
+							: (info->var.transp.length == 1)  ? 3 /* GFX_FMT_ARGB1555 */
+							: (info->var.transp.length == 4)  ? 1 /* GFX_FMT_ARGB4444 */
+							: 4; /* GFX_FMT_CLUT4 */
+						comp_param.src1_pitch_line = comp_param.src0_pitch_line = info->fix.line_length;
+						comp_param.src1_bits_pixel = comp_param.src0_bits_pixel = info->var.bits_per_pixel;
+						comp_param.src0_phy_addr = info->fix.smem_start;
+						comp_param.src1_phy_addr = info->fix.smem_start + comp_param.src1_pitch_line;
+
+						comp_param.dst_rect.left = blit_conf.dst_rect.left;
+						comp_param.dst_rect.top = blit_conf.dst_rect.top;
+						comp_param.dst_rect.right = blit_conf.dst_rect.right;
+						comp_param.dst_rect.bottom = blit_conf.dst_rect.bottom;
+						comp_param.dst_width =
+							blit_conf.dst_rect.right - blit_conf.dst_rect.left;// cncfbinfo->fbs_lst[info->node-2].info->var.xres;
+						comp_param.dst_height =
+							blit_conf.dst_rect.bottom - blit_conf.dst_rect.top;// cncfbinfo->fbs_lst[info->node-2].info->var.yres;
+						comp_param.dst_color_format = comp_param.src0_color_format;
+						comp_param.dst_pitch_line = cncfbinfo->fbs_lst[info->node-2].info->fix.line_length;
+						comp_param.dst_bits_pixel = cncfbinfo->fbs_lst[info->node-2].info->var.bits_per_pixel;
+						comp_param.dst_phy_addr = cncfbinfo->fbs_lst[info->node-2].info->fix.smem_start;
+
+						//DFB_2DComposite(&comp_param);
+
+						return 0;
+					}
+				}
+do_scaler:
+				//DFB_2DScalor(&blit_conf);
+				break;
+			}
+		default:
+			return -EINVAL;
+	}
+
+	return 0;
+}
+
+/*
+ * Initialisation
+ */
+static void cncfb_platform_release(struct device *device)
+{
+	/* This is called when the reference count goes to zero. */
+}
+
+struct fb_info *gfx = NULL, *gfx2 = NULL, *gfx3 = NULL, *gfx4=NULL;
+static struct proc_dir_entry *fb_proc_entry = NULL;
+
+static int fb_proc_write(struct file *file, const char *buffer, unsigned long count, void *data)
+{
+	u32 addr;
+	u32 val;
+
+	const char *cmd_line = buffer;;
+
+	if (strncmp("rl", cmd_line, 2) == 0) {
+		addr = simple_strtol(&cmd_line[3], NULL, 16);
+		val = df_readl(addr);
+		printk(" readw [0x%04x] = 0x%08x \n", addr, val);
+	}
+	else if (strncmp("wl", cmd_line, 2) == 0) {
+		addr = simple_strtol(&cmd_line[3], NULL, 16);
+		val = simple_strtol(&cmd_line[7], NULL, 16);
+		df_writel(addr, val);
+	}
+	else if (strncmp("2dst", cmd_line, 4) == 0) {
+		int i;
+		for (i = 0; i <= 0x8c; i+=4) {
+			val = Gfx_ReadRegs(i/4);
+			printk(" 2d status [0x%04x] = 0x%08x \n", i, val);
+		}
+	}
+	else if (strncmp("0", cmd_line, 1) == 0) {
+		USE2D_COMP_NOTSCALOR = 0;
+	}
+	else if (strncmp("1", cmd_line, 1) == 0) {
+		USE2D_COMP_NOTSCALOR = 1;
+	}
+
+	return count;
+}
+
+void __devinit fix_cncfb_default_and_fix(int mode, int color_format)
+{
+	switch(mode){
+		case TVOUT_MODE_576I:
+		case TVOUT_MODE_PAL_N:
+		case TVOUT_MODE_PAL_CN:
+		case TVOUT_MODE_SECAM:
+			cncfb_default.xres = 720;
+			cncfb_default.yres = 576;
+			cncfb_default.xres_virtual = 720;
+			cncfb_default.yres_virtual = 576;
+			cncfb_default.vmode = FB_VMODE_INTERLACED;
+			cncfb_fix.line_length = 1440;
+			break;
+		case TVOUT_MODE_576P:
+			cncfb_default.xres = 720;
+			cncfb_default.yres = 576;
+			cncfb_default.xres_virtual = 720;
+			cncfb_default.yres_virtual = 576;
+			cncfb_fix.line_length = 1440;
+			break;
+		case TVOUT_MODE_480I:
+		case TVOUT_MODE_PAL_M:
+			cncfb_default.xres = 720;
+			cncfb_default.yres = 480;
+			cncfb_default.xres_virtual = 720;
+			cncfb_default.yres_virtual = 480;
+			cncfb_default.vmode = FB_VMODE_INTERLACED;
+			cncfb_fix.line_length = 1440;
+			break;
+		case TVOUT_MODE_480P:
+			cncfb_default.xres = 720;
+			cncfb_default.yres = 480;
+			cncfb_default.xres_virtual = 720;
+			cncfb_default.yres_virtual = 480;
+			cncfb_fix.line_length = 1440;
+			break;
+		case TVOUT_MODE_720P50:
+		case TVOUT_MODE_720P60:
+		case TVOUT_RGB_1280X720_60FPS:
+			cncfb_default.xres = 1280;
+			cncfb_default.yres = 720;
+			cncfb_default.xres_virtual = 1280;
+			cncfb_default.yres_virtual = 720;
+			cncfb_fix.line_length = 2560;
+			break;
+		case TVOUT_MODE_1080I25:
+		case TVOUT_MODE_1080I30:
+			cncfb_default.xres = 1920;
+			cncfb_default.yres = 1080;
+			cncfb_default.xres_virtual = 1920;
+			cncfb_default.yres_virtual = 1080;
+			cncfb_default.vmode = FB_VMODE_INTERLACED;
+			cncfb_fix.line_length = 3840;
+			break;
+		case TVOUT_MODE_1080P24:
+		case TVOUT_MODE_1080P25:
+		case TVOUT_MODE_1080P30:
+		case TVOUT_MODE_1080P50:
+		case TVOUT_MODE_1080P60:
+		case TVOUT_RGB_1920X1080I30:
+		case TVOUT_RGB_1920X1080P60:
+		case TVOUT_RGB_1920X1080P30:
+			cncfb_default.xres = 1920;
+			cncfb_default.yres = 1080;
+			cncfb_default.xres_virtual = 1920;
+			cncfb_default.yres_virtual = 1080;
+			cncfb_fix.line_length = 3840;
+			break;
+		case TVOUT_RGB_640X480_60FPS:
+			cncfb_default.xres = 640;
+			cncfb_default.yres = 480;
+			cncfb_default.xres_virtual = 640;
+			cncfb_default.yres_virtual = 480;
+			cncfb_fix.line_length = 1280;
+			break;
+		case TVOUT_RGB_800X600_60FPS:
+			cncfb_default.xres = 800;
+			cncfb_default.yres = 600;
+			cncfb_default.xres_virtual = 800;
+			cncfb_default.yres_virtual = 600;
+			cncfb_fix.line_length = 1600;
+			break;
+		case TVOUT_RGB_1024X768_60FPS:
+			cncfb_default.xres = 1024;
+			cncfb_default.yres = 768;
+			cncfb_default.xres_virtual = 1024;
+			cncfb_default.yres_virtual = 768;
+			cncfb_fix.line_length = 2048;
+			break;
+		case TVOUT_RGB_1280X1024_60FPS:
+			cncfb_default.xres = 1280;
+			cncfb_default.yres = 1024;
+			cncfb_default.xres_virtual = 1280;
+			cncfb_default.yres_virtual = 1024;
+			cncfb_fix.line_length = 3560;
+			break;
+		case TVOUT_RGB_1360X768_60FPS:
+			cncfb_default.xres = 1360;
+			cncfb_default.yres = 768;
+			cncfb_default.xres_virtual = 1360;
+			cncfb_default.yres_virtual = 768;
+			cncfb_fix.line_length = 3720;
+			break;
+		case TVOUT_RGB_1366X768_60FPS:
+			cncfb_default.xres = 1366;
+			cncfb_default.yres = 768;
+			cncfb_default.xres_virtual = 1366;
+			cncfb_default.yres_virtual = 768;
+			cncfb_fix.line_length = 3732;
+			break;
+		case TVOUT_RGB_1440X900_60FPS:
+			cncfb_default.xres = 1440;
+			cncfb_default.yres = 900;
+			cncfb_default.xres_virtual = 1440;
+			cncfb_default.yres_virtual = 900;
+			cncfb_fix.line_length = 2880;
+			break;
+		default:
+			cncfb_default.xres = 1280;
+			cncfb_default.yres = 720;
+			cncfb_default.xres_virtual = 1280;
+			cncfb_default.yres_virtual = 720;
+			cncfb_fix.line_length = 2560;
+			break;
+	}
+
+	switch (color_format){
+		case 2:
+			cncfb_default.bits_per_pixel = 16;
+			cncfb_default.red.offset = 11;
+			cncfb_default.red.length = 5;
+			cncfb_default.green.offset = 5;
+			cncfb_default.green.length = 6;
+			cncfb_default.blue.offset = 0;
+			cncfb_default.blue.length = 5;
+			cncfb_default.transp.offset = 0;
+			cncfb_default.transp.length = 0;
+			break;
+		case 6:
+			cncfb_default.bits_per_pixel = 32;
+			cncfb_default.red.offset = 16;
+			cncfb_default.red.length = 8;
+			cncfb_default.green.offset = 8;
+			cncfb_default.green.length = 8;
+			cncfb_default.blue.offset = 0;
+			cncfb_default.blue.length = 8;
+			cncfb_default.transp.offset = 24;
+			cncfb_default.transp.length = 8;
+			cncfb_fix.line_length = cncfb_fix.line_length*2;
+			break;
+		default:
+#ifdef CONFIG_ANDROID
+			cncfb_default.bits_per_pixel = 16;
+			cncfb_default.red.offset = 11;
+			cncfb_default.red.length = 5;
+			cncfb_default.green.offset = 5;
+			cncfb_default.green.length = 6;
+			cncfb_default.blue.offset = 0;
+			cncfb_default.blue.length = 5;
+			cncfb_default.transp.offset = 0;
+			cncfb_default.transp.length = 0;
+#else
+			cncfb_default.bits_per_pixel = 32;
+			cncfb_default.red.offset = 16;
+			cncfb_default.red.length = 8;
+			cncfb_default.green.offset = 8;
+			cncfb_default.green.length = 8;
+			cncfb_default.blue.offset = 0;
+			cncfb_default.blue.length = 8;
+			cncfb_default.transp.offset = 24;
+			cncfb_default.transp.length = 8;
+			cncfb_fix.line_length = cncfb_fix.line_length*2;
+#endif
+			break;
+	}
+}
+
+static int __devinit cncfb_probe(struct platform_device *device)
+{
+	int retval = -ENOMEM;
+
+	if (cncfb_fix.smem_len >0) {
+		gfx = framebuffer_alloc(sizeof(unsigned int) * 256, &(device->dev));
+		if (NULL == gfx)
+			goto GFX_ERR;
+
+		if (NULL == (gfx->screen_base = ioremap(cncfb_fix.smem_start, cncfb_fix.smem_len)))
+			goto MMAP_ERR;
+
+		fb_proc_entry = create_proc_entry("fb_io", 0, NULL);
+		if (NULL != fb_proc_entry) {
+			fb_proc_entry->write_proc = &fb_proc_write;
+		}
+
+		fix_cncfb_default_and_fix(outputmode, colorformat);
+
+		gfx->fbops = &cncfb_ops;
+		gfx->var = cncfb_default;
+		gfx->fix = cncfb_fix;
+		gfx->pseudo_palette = gfx->par;
+		gfx->par = NULL;
+		gfx->flags = FBINFO_FLAG_DEFAULT;
+		/* update default xres_virtual and yres_virtual following fix screen info */
+		//        gfx->var.xres_virtual = gfx->var.xres; /* we don't enable now x pan display */
+
+		gfx->fix.line_length =  get_line_length(gfx->var.xres_virtual, gfx->var.bits_per_pixel);
+		gfx->var.yres_virtual = gfx->fix.smem_len / gfx->fix.line_length;
+		if (fb_alloc_cmap(&gfx->cmap, 256, 0) < 0) goto CMAP_ERR;
+		if (register_framebuffer(gfx) < 0) goto RF_ERR;
+
+		cncfbinfo->fbs_lst[0].onoff = 0;
+
+		cncfbinfo->fbs_lst[0].info = gfx;
+
+		if(-1 == outputmode)
+			memset(gfx->screen_base, 0, FB0_SIZE);
+
+		printk(KERN_INFO "fb%d: CNC frame buffer @[0x%lx, 0x%lx] size 0x%lx\n",
+				gfx->node, gfx->fix.smem_start, (u_long)gfx->screen_base, (u_long)gfx->fix.smem_len);
+		//Gfx_2DInit();
+	}
+	else {
+		gfx = NULL;
+		cncfbinfo->fbs_lst[0].info = gfx;
+		cncfbinfo->fbs_lst[0].onoff = 0;
+	}
+
+	/* to register the second framebuffer */
+	if ( gfx != NULL) {
+		if (NULL == (gfx2 = framebuffer_alloc(sizeof(u32) * 256, &device->dev)))
+			goto GFX2_ERR;
+		if (cncfb_fix2.smem_len > 0) {
+			if (NULL == (gfx2->screen_base = ioremap(cncfb_fix2.smem_start, cncfb_fix2.smem_len)))
+				goto MMAP2_ERR;
+			//         memset(gfx2->screen_base, 0, FB1_SIZE);
+			//          gfx2->fix = cncfb_fix2;
+		} else {
+			gfx2->screen_base = gfx->screen_base;  // if fb1 buffer size is 0, then it pointe fb0
+			gfx2->fix = cncfb_fix;
+		}
+
+		gfx2->fbops = &cncfb_ops;
+		gfx2->var = cncfb_default;
+		/* update default xres_virtual and yres_virtual following fix screen info */
+		//        gfx->var.xres_virtual = gfx->var.xres; /* we don't enable now x pan display */
+
+		gfx2->fix.line_length =  get_line_length(gfx2->var.xres_virtual, gfx2->var.bits_per_pixel);
+		gfx2->var.yres_virtual = gfx2->fix.smem_len / gfx2->fix.line_length;
+		gfx2->pseudo_palette = gfx2->par;
+		gfx2->par = NULL;
+		gfx2->flags = FBINFO_FLAG_DEFAULT;
+
+		if (fb_alloc_cmap(&gfx2->cmap, 256, 0) < 0) goto CMAP2_ERR;
+		if (register_framebuffer(gfx2) < 0) goto RF2_ERR;
+
+		cncfbinfo->fbs_lst[1].info = gfx2;
+		cncfbinfo->fbs_lst[1].onoff = 0;
+
+		printk(KERN_INFO "fb%d: CNC frame buffer @[0x%lx, 0x%lx] size 0x%lx\n",
+				gfx2->node, gfx2->fix.smem_start, (u_long)gfx2->screen_base, (u_long)gfx2->fix.smem_len);
+	}
+	else {
+		gfx2 = NULL;
+		cncfbinfo->fbs_lst[1].info = gfx2;
+		cncfbinfo->fbs_lst[1].onoff = 0;
+	}
+
+	/* to register the third framebuffer */
+	if (cncfb_fix3.smem_len >0 && gfx!= NULL) {
+		if (NULL == (gfx3 = framebuffer_alloc(sizeof(u32) * 256, &device->dev))) goto GFX3_ERR;
+		if (NULL == (gfx3->screen_base = ioremap(cncfb_fix3.smem_start, cncfb_fix3.smem_len))) goto MMAP3_ERR;
+
+		gfx3->fbops = &cncfb_ops;
+		gfx3->var = cncfb_default;
+		gfx3->fix = cncfb_fix3;
+		gfx3->pseudo_palette = gfx3->par;
+		gfx3->par = NULL;
+		gfx3->flags = FBINFO_FLAG_DEFAULT;
+		/* update default xres_virtual and yres_virtual following fix screen info */
+		//        gfx->var.xres_virtual = gfx->var.xres; /* we don't enable now x pan display */
+
+		gfx3->fix.line_length =  get_line_length(gfx3->var.xres_virtual, gfx3->var.bits_per_pixel);
+		gfx3->var.yres_virtual = gfx3->fix.smem_len / gfx3->fix.line_length;
+		if (fb_alloc_cmap(&gfx3->cmap, 256, 0) < 0) goto CMAP3_ERR;
+		if (register_framebuffer(gfx3) < 0) goto RF3_ERR;
+
+		cncfbinfo->fbs_lst[2].onoff = 0;
+		cncfbinfo->fbs_lst[2].info = gfx3;
+
+		if(-1 == outputmode)
+			memset(gfx3->screen_base, 0, cncfb_fix3.smem_len);
+
+		printk(KERN_INFO "fb%d: CNC frame buffer @[0x%lx, 0x%lx] size 0x%lx\n",
+				gfx3->node, gfx3->fix.smem_start, (u_long)gfx3->screen_base, (u_long)gfx3->fix.smem_len);
+	}
+	else {
+		gfx3= NULL;
+		cncfbinfo->fbs_lst[2].info = gfx3;
+		cncfbinfo->fbs_lst[2].onoff = 0;
+	}
+
+	/* to register the 4th framebuffer */
+	if (cncfb_fix4.smem_len >0 && gfx2 != NULL) {
+		if (NULL == (gfx4 = framebuffer_alloc(sizeof(u32) * 256, &device->dev))) goto GFX4_ERR;
+		if (NULL == (gfx4->screen_base = ioremap(cncfb_fix4.smem_start, cncfb_fix4.smem_len))) goto MMAP4_ERR;
+
+		gfx4->fbops = &cncfb_ops;
+		gfx4->var = cncfb_default;
+		gfx4->fix = cncfb_fix4;
+		gfx4->pseudo_palette = gfx4->par;
+		gfx4->par = NULL;
+		gfx4->flags = FBINFO_FLAG_DEFAULT;
+		cncfbinfo->fbs_lst[3].onoff = 0;
+		/* update default xres_virtual and yres_virtual following fix screen info */
+		//        gfx->var.xres_virtual = gfx->var.xres; /* we don't enable now x pan display */
+		gfx4->var.yres_virtual = gfx4->fix.smem_len / (gfx4->var.xres_virtual * (gfx4->var.bits_per_pixel / 8 ));
+
+		gfx4->fix.line_length =  get_line_length(gfx4->var.xres_virtual, gfx4->var.bits_per_pixel);
+		gfx4->var.yres_virtual = gfx4->fix.smem_len / gfx4->fix.line_length;
+		if (fb_alloc_cmap(&gfx4->cmap, 256, 0) < 0) goto CMAP4_ERR;
+		if (register_framebuffer(gfx4) < 0) goto RF4_ERR;
+
+		cncfbinfo->fbs_lst[3].info = gfx4;
+
+		if(-1 == outputmode)
+			memset(gfx4->screen_base, 0, cncfb_fix4.smem_len);
+	}
+	else {
+		gfx4= NULL;
+		cncfbinfo->fbs_lst[3].info = gfx4;
+		cncfbinfo->fbs_lst[3].onoff = 0;
+	}
+
+	/* to initialize the first framebuffer */
+	if (gfx != NULL){
+		cncfb_hw_init(gfx, 0, cncfbinfo);
+	}
+	if (gfx2 != NULL)
+		cncfb_hw_init(gfx2, 0, cncfbinfo);
+#if defined(CONFIG_LOGO)
+	if(-1 != outputmode)
+		{
+			memset(gfx->screen_base, 0, FB0_SIZE);
+			msleep(20);
+			printk(KERN_INFO"### Enable Logo ###\n");
+			if (fb_prepare_logo(gfx, FB_ROTATE_UR)) {
+						printk(KERN_INFO"Start display and show logo on boot........\n");
+						/* Start display and show logo on boot */
+						fb_set_cmap(&gfx->cmap, gfx);
+						fb_show_logo(gfx, FB_ROTATE_UR);
+					}
+			cncfb_show_logo(gfx,cncfbinfo);
+		}
+#endif
+	return 0;
+
+RF4_ERR:
+CMAP4_ERR:
+MMAP4_ERR:
+GFX4_ERR:
+	/* do something here. */
+	printk("Init framebuffer 4 failed!\n");
+RF3_ERR:
+CMAP3_ERR:
+MMAP3_ERR:
+GFX3_ERR:
+	/* do something here. */
+	printk("Init framebuffer 3 failed!\n");
+RF2_ERR:
+	if (gfx2 != NULL)
+		fb_dealloc_cmap(&gfx2->cmap);
+CMAP2_ERR:
+	if (gfx2 != NULL)
+		iounmap(gfx2->screen_base);
+MMAP2_ERR:
+
+GFX2_ERR:
+	if (gfx != NULL)
+		framebuffer_release(gfx);
+RF_ERR:
+	if (gfx != NULL)
+		fb_dealloc_cmap(&gfx->cmap);
+CMAP_ERR:
+	if (gfx != NULL)
+		iounmap(gfx->screen_base);
+MMAP_ERR:
+GFX_ERR:
+	return retval;
+}
+
+static int cncfb_remove(struct platform_device *device)
+{
+	int i;
+	struct fb_info *info;
+
+	for (i = 0; i < FB_NUMS; i++) {
+		info = cncfbinfo->fbs_lst[i].info;
+		if (info) {
+			unregister_framebuffer(info);
+			iounmap(info->screen_base);
+			framebuffer_release(info);
+		}
+	}
+
+	return 0;
+}
+
+static struct platform_driver cncfb_driver = {
+	.probe  = cncfb_probe,
+	.remove = cncfb_remove,
+	.driver = {
+		.name   = "cncfb",
+		.owner  = THIS_MODULE,
+	}
+};
+
+static struct platform_device cncfb_device = {
+	.name   = "cncfb",
+	.id     = 0,
+	// .dev    = {
+	//     //    .dma_mask = ~(u32)0;
+
+	// }
+	.num_resources = 0,
+};
+
+static int __init cncfb_init(void)
+{
+	int ret = 0;
+
+	ret = platform_driver_register(&cncfb_driver);
+	if (ret) {
+		printk(KERN_ERR "failed to register cnc framebuffer driver\n");
+		return -ENODEV;
+	}
+
+	if (!ret) {
+		ret = platform_device_register(&cncfb_device);
+		if (ret) {
+			platform_driver_unregister(&cncfb_driver);
+			printk(KERN_ERR "failed to register cnc framebuffer device\n");
+		}
+	}
+
+	return ret;
+}
+
+module_init(cncfb_init);
+
+#ifdef MODULE
+static void __exit cncfb_exit(void)
+{
+	cncfb_hw_exit();
+
+	platform_device_unregister(&cncfb_device);
+	platform_driver_unregister(&cncfb_driver);
+}
+
+module_exit(cncfb_exit);
+
+MODULE_LICENSE("GPL");
+
+#endif /* MODULE */
+
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/video/celestial/cncfb.h linux-linaro-3.4-2012.05-1_cavium/drivers/video/celestial/cncfb.h
--- linux-linaro-3.4-2012.05-1_original/drivers/video/celestial/cncfb.h	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/video/celestial/cncfb.h	2014-12-04 11:15:33.692449000 +0800
@@ -0,0 +1,83 @@
+/*
+ *  linux/drivers/video/celestial/cncfb.h -- celestial frame buffer device
+ *
+ *  Copyright (C) 2010 Celestial Semiconductor
+ *  Copyright (C) 2011 Cavium
+ *
+ *  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.
+ */
+
+
+#ifndef __CSMFB_DEV_H__
+#define __CSMFB_DEV_H__
+
+typedef struct _gfx_colorkey {
+	char r_min;
+	char r_max;
+
+	char g_min;
+	char g_max;
+
+	char b_min;
+	char b_max;
+}gfx_colorkey;
+
+
+#define FB_NUMS		4
+
+typedef struct cnc_info
+{
+	struct {
+		struct fb_info *info;
+
+		/* framebuffer area */
+		unsigned long fb_base_phys;
+		unsigned long fb_base;
+		unsigned long fb_size;
+
+		/* to map the registers */
+		dma_addr_t    mmio_base_phys;
+		unsigned long mmio_base;
+		unsigned long mmio_size;
+		unsigned int  onoff;
+	} fbs_lst[FB_NUMS];
+
+	wait_queue_head_t vsync_wait;
+	unsigned long     vsync_cnt;
+	int timeout;
+	struct device *dev;
+}cncinfo;
+
+typedef struct _gfx_rect
+{
+	unsigned int startx;
+	unsigned int starty;
+	unsigned int endx;
+	unsigned int endy;
+}gfx_rect;
+
+/*
+ * Z-Order numbers are from hardware, don't redefine them!
+ */
+#define Z_ORDER_V0_V1_G         0x0123
+#define Z_ORDER_V0_G_V1         0x0213
+#define Z_ORDER_V1_V0_G         0x1023
+#define Z_ORDER_V1_G_V0         0x2013
+#define Z_ORDER_G_V0_V1         0x1203
+#define Z_ORDER_G_V1_V0         0x2103
+
+#define FBIO_GFX_ON             _IOW('F', 0x21, u_int32_t)
+#define FBIO_GFX_ALPHA          _IOW('F', 0x22, u_int32_t)
+#define FBIO_Z_ORDER            _IOW('F', 0x50, u_int32_t)
+#define FBIO_GFX_FLIP		    _IOW('F', 0x51, gfx2d_scalor_params)
+#define FBIO_GFX_COLORKEY_ON	_IOW('F', 0x52, u_int32_t)
+#define FBIO_GFX_COLORKEY_VAL	_IOW('F', 0x53, gfx_colorkey)
+#define FBIO_GFX_BGCOLOR	    _IOW('F', 0x54, u_int32_t)
+
+#define FBIO_GFX_OPAQUE_ONOFF    _IOW('F', 0x55, int)
+#define FBIO_GFX_CONFIG_DISTRECT    _IOW('F', 0x56, gfx_rect)
+#define FBIO_GFX_SET_UI_ENDIAN   _IOW('F', 0x57, u_int32_t)
+
+#endif
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/video/celestial/Kconfig linux-linaro-3.4-2012.05-1_cavium/drivers/video/celestial/Kconfig
--- linux-linaro-3.4-2012.05-1_original/drivers/video/celestial/Kconfig	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/video/celestial/Kconfig	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,49 @@
+
+config FB_CELESTIAL
+	tristate "Celestial CNC platform framebuffer support"
+	depends on FB && ARCH_CELESTIAL
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  Frame buffer driver for the celestial platform.
+
+config FB0_SIZE
+	hex "Default size of frame buffer 0"
+	depends on FB_CELESTIAL
+	range 0x0 0x4000000
+	default "0x1000000"
+	help
+	    size of frame buffer 0, which is used for OSD Layer 0, frame buffer 2 is included in this buffer. range from 0x800000 to 0x1000000
+
+config FB2_SIZE
+	hex "Default size of frame buffer 2"
+	depends on FB_CELESTIAL
+	range 0x0 0x4000000
+	default "0x800000"
+	help
+	    size of frame buffer 2, it's included in frame buffer 0, set to half size of fb 0 is recommended. range from 0x400000 to 0x800000
+
+config FB1_SIZE
+	hex "Default size of frame buffer 1"
+	depends on FB_CELESTIAL
+	range 0x0 0x4000000
+	default "0x1000000"
+	help
+	    size of frame buffer 1, which is used for OSD Layer 1, frame buffer 3 is included in this buffer. range from 0x800000 to 0x1000000.
+
+config FB3_SIZE
+	hex "Default size of frame buffer 3"
+	depends on FB_CELESTIAL
+	range 0x0 0x4000000
+	default "0x800000"
+	help
+	    size of frame buffer 3, it's included in frame buffer 1, set to half size of fb 1 is recommended. range from 0x400000 to 0x800000.
+
+config ANDROID_FB0_ONLY
+       bool "android fb0 config"
+       depends on FB_CELESTIAL
+       default n
+       help
+          if this config been selected, will use another register configuration for ui1
+
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/video/celestial/Makefile linux-linaro-3.4-2012.05-1_cavium/drivers/video/celestial/Makefile
--- linux-linaro-3.4-2012.05-1_original/drivers/video/celestial/Makefile	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/video/celestial/Makefile	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,23 @@
+#
+# Makefile for the Cavium Celestial SoC framebuffer device driver
+#
+
+
+
+
+ifdef CONFIG_ARCH_CELESTIAL 
+obj-y += cncfb.o 
+endif
+
+ifdef CONFIG_MACH_CELESTIAL_CNC1900
+obj-y +=cnc1900_fb_hw.o 
+endif
+
+ifdef CONFIG_MACH_CELESTIAL_CNC1800H
+obj-y +=cnc1800h_fb_hw.o 
+endif
+
+
+ifdef CONFIG_MACH_CELESTIAL_CNC1800L
+obj-y +=cnc1800l_fb_hw.o 
+endif
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/video/fbmem.c linux-linaro-3.4-2012.05-1_cavium/drivers/video/fbmem.c
--- linux-linaro-3.4-2012.05-1_original/drivers/video/fbmem.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/video/fbmem.c	2014-07-29 17:28:38.819972000 +0800
@@ -420,10 +420,16 @@
 {
 	unsigned int x;
 
+	unsigned int xoff,yoff;
+	xoff=(info->var.xres-num*(fb_logo.logo->width+8))>>1;
+	yoff=(info->var.yres-num*(fb_logo.logo->height+8))>>1;
 	if (rotate == FB_ROTATE_UR) {
 		for (x = 0;
 		     x < num && image->dx + image->width <= info->var.xres;
 		     x++) {
+                   image->dx=xoff;
+		     image->dy=yoff;
+				
 			info->fbops->fb_imageblit(info, image);
 			image->dx += image->width + 8;
 		}
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/video/Kconfig linux-linaro-3.4-2012.05-1_cavium/drivers/video/Kconfig
--- linux-linaro-3.4-2012.05-1_original/drivers/video/Kconfig	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/video/Kconfig	2014-07-29 17:28:38.819972000 +0800
@@ -2374,6 +2374,7 @@
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
+	default y
 
 config FB_MX3
 	tristate "MX3 Framebuffer support"
@@ -2434,6 +2435,7 @@
 source "drivers/video/omap2/Kconfig"
 source "drivers/video/exynos/Kconfig"
 source "drivers/video/backlight/Kconfig"
+source "drivers/video/celestial/Kconfig"
 
 if VT
 	source "drivers/video/console/Kconfig"
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/video/Makefile linux-linaro-3.4-2012.05-1_cavium/drivers/video/Makefile
--- linux-linaro-3.4-2012.05-1_original/drivers/video/Makefile	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/video/Makefile	2014-07-29 17:28:38.819972000 +0800
@@ -147,7 +147,7 @@
 obj-$(CONFIG_FB_NUC900)           += nuc900fb.o
 obj-$(CONFIG_FB_JZ4740)		  += jz4740_fb.o
 obj-$(CONFIG_FB_PUV3_UNIGFX)      += fb-puv3.o
-
+obj-$(CONFIG_FB_CELESTIAL)        += celestial/
 # Platform or fallback drivers go here
 obj-$(CONFIG_FB_UVESA)            += uvesafb.o
 obj-$(CONFIG_FB_VESA)             += vesafb.o
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/drivers/watchdog/mpcore_wdt.c linux-linaro-3.4-2012.05-1_cavium/drivers/watchdog/mpcore_wdt.c
--- linux-linaro-3.4-2012.05-1_original/drivers/watchdog/mpcore_wdt.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/drivers/watchdog/mpcore_wdt.c	2014-07-29 17:28:38.819972000 +0800
@@ -38,6 +38,8 @@
 
 #include <asm/smp_twd.h>
 
+extern unsigned long twd_timer_rate;
+
 struct mpcore_wdt {
 	unsigned long	timer_alive;
 	struct device	*dev;
@@ -102,11 +104,8 @@
 
 	spin_lock(&wdt_lock);
 	/* Assume prescale is set to 256 */
-	count =  __raw_readl(wdt->base + TWD_WDOG_COUNTER);
-	count = (0xFFFFFFFFU - count) * (HZ / 5);
-	count = (count / 256) * mpcore_margin;
+	count = (twd_timer_rate / 256) * mpcore_margin;
 
-	/* Reload the counter */
 	writel(count + wdt->perturb, wdt->base + TWD_WDOG_LOAD);
 	wdt->perturb = wdt->perturb ? 0 : 1;
 	spin_unlock(&wdt_lock);
@@ -348,7 +347,7 @@
 	wdt->dev = &pdev->dev;
 	wdt->irq = platform_get_irq(pdev, 0);
 	if (wdt->irq >= 0) {
-		ret = devm_request_irq(wdt->dev, wdt->irq, mpcore_wdt_fire, 0,
+		ret = request_percpu_irq(wdt->irq, mpcore_wdt_fire,
 				"mpcore_wdt", wdt);
 		if (ret) {
 			dev_printk(KERN_ERR, wdt->dev,
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/fs/exec.c linux-linaro-3.4-2012.05-1_cavium/fs/exec.c
--- linux-linaro-3.4-2012.05-1_original/fs/exec.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/fs/exec.c	2014-07-29 17:28:38.819972000 +0800
@@ -787,7 +787,7 @@
 
 	fsnotify_open(file);
 
-	trace_open_exec(name);
+	trace_open_exec((char *)name);
 
 	err = deny_write_access(file);
 	if (err)
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/fs/jffs2/erase.c linux-linaro-3.4-2012.05-1_cavium/fs/jffs2/erase.c
--- linux-linaro-3.4-2012.05-1_original/fs/jffs2/erase.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/fs/jffs2/erase.c	2015-04-02 14:55:34.597802000 +0800
@@ -186,7 +186,12 @@
 {
 	/* For NAND, if the failure did not occur at the device level for a
 	   specific physical page, don't bother updating the bad block table. */
+
+#ifdef CONFIG_JFFS2_NO_CLEANMARKER
+    if ((c->mtd->type == MTD_NANDFLASH) && (bad_offset != (uint32_t)MTD_FAIL_ADDR_UNKNOWN)) {
+#else
 	if (jffs2_cleanmarker_oob(c) && (bad_offset != (uint32_t)MTD_FAIL_ADDR_UNKNOWN)) {
+#endif
 		/* We had a device-level failure to erase.  Let's see if we've
 		   failed too many times. */
 		if (!jffs2_write_nand_badblock(c, jeb, bad_offset)) {
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/fs/jffs2/fs.c linux-linaro-3.4-2012.05-1_cavium/fs/jffs2/fs.c
--- linux-linaro-3.4-2012.05-1_original/fs/jffs2/fs.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/fs/jffs2/fs.c	2015-04-02 14:55:34.597802000 +0800
@@ -702,7 +702,11 @@
 static int jffs2_flash_setup(struct jffs2_sb_info *c) {
 	int ret = 0;
 
-	if (jffs2_cleanmarker_oob(c)) {
+#ifdef CONFIG_JFFS2_NO_CLEANMARKER
+    if (c->mtd->type == MTD_NANDFLASH) {
+#else
+    if (jffs2_cleanmarker_oob(c)) {
+#endif
 		/* NAND flash... do setup accordingly */
 		ret = jffs2_nand_flash_setup(c);
 		if (ret)
@@ -735,7 +739,11 @@
 
 void jffs2_flash_cleanup(struct jffs2_sb_info *c) {
 
+#ifdef CONFIG_JFFS2_NO_CLEANMARKER
+    if (c->mtd->type ==MTD_NANDFLASH) {
+#else
 	if (jffs2_cleanmarker_oob(c)) {
+#endif
 		jffs2_nand_flash_cleanup(c);
 	}
 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/fs/jffs2/Kconfig linux-linaro-3.4-2012.05-1_cavium/fs/jffs2/Kconfig
--- linux-linaro-3.4-2012.05-1_original/fs/jffs2/Kconfig	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/fs/jffs2/Kconfig	2015-04-02 14:55:34.597802000 +0800
@@ -41,6 +41,13 @@
 	    - NOR flash with transparent ECC
 	    - DataFlash
 
+config JFFS2_NO_CLEANMARKER
+	bool "JFFS2 cleanmarker disabled (for BENAND or NAND with ECC builtin)"
+	depends on JFFS2_FS && JFFS2_FS_WRITEBUFFER
+	default n
+	help
+	  This disables the cleanmarker originally in the OOB area.
+
 config JFFS2_FS_WBUF_VERIFY
 	bool "Verify JFFS2 write-buffer reads"
 	depends on JFFS2_FS_WRITEBUFFER
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/fs/jffs2/os-linux.h linux-linaro-3.4-2012.05-1_cavium/fs/jffs2/os-linux.h
--- linux-linaro-3.4-2012.05-1_original/fs/jffs2/os-linux.h	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/fs/jffs2/os-linux.h	2015-04-02 14:55:34.597802000 +0800
@@ -106,7 +106,11 @@
 #define jffs2_can_mark_obsolete(c) (c->mtd->flags & (MTD_BIT_WRITEABLE))
 #endif
 
+#ifdef CONFIG_JFFS2_NO_CLEANMARKER
+#define jffs2_cleanmarker_oob(c) (0)
+#else
 #define jffs2_cleanmarker_oob(c) (c->mtd->type == MTD_NANDFLASH)
+#endif
 
 #define jffs2_wbuf_dirty(c) (!!(c)->wbuf_len)
 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/fs/jffs2/scan.c linux-linaro-3.4-2012.05-1_cavium/fs/jffs2/scan.c
--- linux-linaro-3.4-2012.05-1_original/fs/jffs2/scan.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/fs/jffs2/scan.c	2015-07-27 18:42:10.799681000 +0800
@@ -113,7 +113,11 @@
 	if (!flashbuf) {
 		/* For NAND it's quicker to read a whole eraseblock at a time,
 		   apparently */
+#ifdef CONFIG_JFFS2_NO_CLEANMARKER
+		if (c->mtd->type == MTD_NANDFLASH)
+#else
 		if (jffs2_cleanmarker_oob(c))
+#endif
 			try_size = c->sector_size;
 		else
 			try_size = PAGE_SIZE;
@@ -459,7 +463,11 @@
 	jffs2_dbg(1, "%s(): Scanning block at 0x%x\n", __func__, ofs);
 
 #ifdef CONFIG_JFFS2_FS_WRITEBUFFER
-	if (jffs2_cleanmarker_oob(c)) {
+#ifdef CONFIG_JFFS2_NO_CLEANMARKER
+		if (c->mtd->type == MTD_NANDFLASH) {
+#else
+		if (jffs2_cleanmarker_oob(c)) {
+#endif
 		int ret;
 
 		if (mtd_block_isbad(c->mtd, jeb->offset))
@@ -565,7 +573,11 @@
 
 	if (ofs == max_ofs) {
 #ifdef CONFIG_JFFS2_FS_WRITEBUFFER
+#ifdef CONFIG_JFFS2_NO_CLEANMARKER
+		if (c->mtd->type == MTD_NANDFLASH) {
+#else
 		if (jffs2_cleanmarker_oob(c)) {
+#endif
 			/* scan oob, take care of cleanmarker */
 			int ret = jffs2_check_oob_empty(c, jeb, cleanmarkerfound);
 			jffs2_dbg(2, "jffs2_check_oob_empty returned %d\n",
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/fs/jffs2/wbuf.c linux-linaro-3.4-2012.05-1_cavium/fs/jffs2/wbuf.c
--- linux-linaro-3.4-2012.05-1_original/fs/jffs2/wbuf.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/fs/jffs2/wbuf.c	2015-07-28 17:17:26.969575000 +0800
@@ -1076,7 +1076,11 @@
 				 struct jffs2_eraseblock *jeb)
 {
 	struct mtd_oob_ops ops;
+#ifdef CONFIG_JFFS2_NO_CLEANMARKER
+	int i, ret, cmlen = min_t(int, c->oobavail, OOB_CM_SIZE);
+#else
 	int ret, cmlen = min_t(int, c->oobavail, OOB_CM_SIZE);
+#endif
 
 	ops.mode = MTD_OPS_AUTO_OOB;
 	ops.ooblen = cmlen;
@@ -1092,8 +1096,24 @@
 			ret = -EIO;
 		return ret;
 	}
-
+#ifdef CONFIG_JFFS2_NO_CLEANMARKER
+	if (jffs2_cleanmarker_oob(c))
+		return !!memcmp(&oob_cleanmarker, c->oobbuf, cmlen);
+	else
+	{
+		for(i = 0; i < cmlen; i++) {
+			if (ops.oobbuf[i] != 0xFF) {
+				jffs2_dbg(2, "Found dirty data %02x at %x in OOB for "
+					"%08x\n", ops.oobbuf[i], i, jeb->offset);
+				return 1;
+			}
+		}
+		return 0;
+	}
+#else
 	return !!memcmp(&oob_cleanmarker, c->oobbuf, cmlen);
+#endif
+
 }
 
 int jffs2_write_nand_cleanmarker(struct jffs2_sb_info *c,
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/fs/seq_file.c linux-linaro-3.4-2012.05-1_cavium/fs/seq_file.c
--- linux-linaro-3.4-2012.05-1_original/fs/seq_file.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/fs/seq_file.c	2014-07-29 17:28:38.819972000 +0800
@@ -78,6 +78,29 @@
 }
 EXPORT_SYMBOL(seq_open);
 
+#ifdef CONFIG_PUREVU
+/*
+ * A single seq_printf(), seq_puts(), ... can't be bigger than SEQ_GUARDBAND
+ * for this to prevent overflow 
+ */
+#define SEQ_GUARDBAND (PAGE_SIZE>>2)
+static void attempt_to_prevent_overflow(struct seq_file *m)
+{
+	/* Attempt to prevent overflow, unless it is too late (count==size) */
+	if ((m->count != m->size) && (m->count + SEQ_GUARDBAND >= m->size)) {
+		char *bigger_buf = kmalloc(m->size << 1, GFP_KERNEL);
+		if (bigger_buf) {
+			memcpy(bigger_buf, m->buf, m->size);
+			kfree(m->buf);
+			m->buf = bigger_buf;
+			m->size <<= 1;
+		}
+	/* NOTE: even if we can't get the bigger buf, just keep trying
+	 * with the smaller one */
+	}
+}
+#endif
+
 static int traverse(struct seq_file *m, loff_t offset)
 {
 	loff_t pos = 0, index;
@@ -390,6 +413,9 @@
 	va_list args;
 	int len;
 
+#ifdef CONFIG_PUREVU
+	attempt_to_prevent_overflow(m);
+#endif
 	if (m->count < m->size) {
 		va_start(args, f);
 		len = vsnprintf(m->buf + m->count, m->size - m->count, f, args);
@@ -639,6 +665,9 @@
 
 int seq_putc(struct seq_file *m, char c)
 {
+#ifdef CONFIG_PUREVU
+	attempt_to_prevent_overflow(m);
+#endif
 	if (m->count < m->size) {
 		m->buf[m->count++] = c;
 		return 0;
@@ -650,6 +679,9 @@
 int seq_puts(struct seq_file *m, const char *s)
 {
 	int len = strlen(s);
+#ifdef CONFIG_PUREVU
+	attempt_to_prevent_overflow(m);
+#endif
 	if (m->count + len < m->size) {
 		memcpy(m->buf + m->count, s, len);
 		m->count += len;
@@ -722,6 +754,9 @@
  */
 int seq_write(struct seq_file *seq, const void *data, size_t len)
 {
+#ifdef CONFIG_PUREVU
+	attempt_to_prevent_overflow(seq);
+#endif
 	if (seq->count + len < seq->size) {
 		memcpy(seq->buf + seq->count, data, len);
 		seq->count += len;
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/fs/yaffs2/Kconfig linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/Kconfig
--- linux-linaro-3.4-2012.05-1_original/fs/yaffs2/Kconfig	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/Kconfig	2014-07-29 17:28:38.819972000 +0800
@@ -1,161 +1,30 @@
 #
-# YAFFS file system configurations
+# yaffs file system configurations
 #
 
 config YAFFS_FS
-	tristate "YAFFS2 file system support"
+	tristate "yaffs2 file system support"
 	default n
 	depends on MTD_BLOCK
 	select YAFFS_YAFFS1
 	select YAFFS_YAFFS2
 	help
-	  YAFFS2, or Yet Another Flash Filing System, is a filing system
+	  yaffs2, or Yet Another Flash File System, is a file system
 	  optimised for NAND Flash chips.
 
-	  To compile the YAFFS2 file system support as a module, choose M
+	  To compile the yaffs2 file system support as a module, choose M
 	  here: the module will be called yaffs2.
 
 	  If unsure, say N.
 
-	  Further information on YAFFS2 is available at
+	  Further information on yaffs2 is available at
 	  <http://www.aleph1.co.uk/yaffs/>.
 
-config YAFFS_YAFFS1
-	bool "512 byte / page devices"
-	depends on YAFFS_FS
-	default y
-	help
-	  Enable YAFFS1 support -- yaffs for 512 byte / page devices
-
-	  Not needed for 2K-page devices.
-
-	  If unsure, say Y.
-
-config YAFFS_9BYTE_TAGS
-	bool "Use older-style on-NAND data format with pageStatus byte"
-	depends on YAFFS_YAFFS1
-	default n
-	help
-
-	  Older-style on-NAND data format has a "pageStatus" byte to record
-	  chunk/page state.  This byte is zero when the page is discarded.
-	  Choose this option if you have existing on-NAND data using this
-	  format that you need to continue to support.  New data written
-	  also uses the older-style format.  Note: Use of this option
-	  generally requires that MTD's oob layout be adjusted to use the
-	  older-style format.  See notes on tags formats and MTD versions
-	  in yaffs_mtdif1.c.
-
-	  If unsure, say N.
-
-config YAFFS_DOES_ECC
-	bool "Lets Yaffs do its own ECC"
-	depends on YAFFS_FS && YAFFS_YAFFS1 && !YAFFS_9BYTE_TAGS
-	default n
-	help
-	  This enables Yaffs to use its own ECC functions instead of using
-	  the ones from the generic MTD-NAND driver.
-
-	  If unsure, say N.
-
-config YAFFS_ECC_WRONG_ORDER
-	bool "Use the same ecc byte order as Steven Hill's nand_ecc.c"
-	depends on YAFFS_FS && YAFFS_DOES_ECC && !YAFFS_9BYTE_TAGS
-	default n
-	help
-	  This makes yaffs_ecc.c use the same ecc byte order as Steven
-	  Hill's nand_ecc.c. If not set, then you get the same ecc byte
-	  order as SmartMedia.
-
-	  If unsure, say N.
-
-config YAFFS_YAFFS2
-	bool "2048 byte (or larger) / page devices"
-	depends on YAFFS_FS
-	default y
-	help
-	  Enable YAFFS2 support -- yaffs for >= 2K bytes per page devices
-
-	  If unsure, say Y.
-
-config YAFFS_AUTO_YAFFS2
-	bool "Autoselect yaffs2 format"
-	depends on YAFFS_YAFFS2
-	default y
-	help
-	  Without this, you need to explicitely use yaffs2 as the file
-	  system type. With this, you can say "yaffs" and yaffs or yaffs2
-	  will be used depending on the device page size (yaffs on
-	  512-byte page devices, yaffs2 on 2K page devices).
-
-	  If unsure, say Y.
-
-config YAFFS_DISABLE_TAGS_ECC
-	bool "Disable YAFFS from doing ECC on tags by default"
-	depends on YAFFS_FS && YAFFS_YAFFS2
-	default n
-	help
-	  This defaults Yaffs to using its own ECC calculations on tags instead of
-	  just relying on the MTD.
-	  This behavior can also be overridden with tags_ecc_on and
-	  tags_ecc_off mount options.
-
-	  If unsure, say N.
-
-config YAFFS_ALWAYS_CHECK_CHUNK_ERASED
-	bool "Force chunk erase check"
-	depends on YAFFS_FS
-	default n
-	help
-          Normally YAFFS only checks chunks before writing until an erased
-	  chunk is found. This helps to detect any partially written
-	  chunks that might have happened due to power loss.
-
-	  Enabling this forces on the test that chunks are erased in flash
-	  before writing to them. This takes more time but is potentially
-	  a bit more secure.
-
-	  Suggest setting Y during development and ironing out driver
-	  issues etc. Suggest setting to N if you want faster writing.
-
-	  If unsure, say Y.
-
-config YAFFS_EMPTY_LOST_AND_FOUND
-	bool "Empty lost and found on boot"
-	depends on YAFFS_FS
-	default n
-	help
-	  If this is enabled then the contents of lost and found is
-	  automatically dumped at mount.
-
-	  If unsure, say N.
-
-config YAFFS_DISABLE_BLOCK_REFRESHING
-	bool "Disable yaffs2 block refreshing"
+config YAFFS_DEBUG
+	bool "Enable yaffs debugging"
 	depends on YAFFS_FS
 	default n
 	help
-	 If this is set, then block refreshing is disabled.
-	 Block refreshing infrequently refreshes the oldest block in
-	 a yaffs2 file system. This mechanism helps to refresh flash to
-	 mitigate against data loss. This is particularly useful for MLC.
+	  Enable the yaffs debugging tracing.
 
 	  If unsure, say N.
-
-config YAFFS_DISABLE_BACKGROUND
-	bool "Disable yaffs2 background processing"
-	depends on YAFFS_FS
-	default n
-	help
-	 If this is set, then background processing is disabled.
-	 Background processing makes many foreground activities faster.
-
-	 If unsure, say N.
-
-config YAFFS_XATTR
-	bool "Enable yaffs2 xattr support"
-	depends on YAFFS_FS
-	default y
-	help
-	 If this is set then yaffs2 will provide xattr support.
-	 If unsure, say Y.
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/fs/yaffs2/Makefile linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/Makefile
--- linux-linaro-3.4-2012.05-1_original/fs/yaffs2/Makefile	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/Makefile	2014-07-29 17:28:38.819972000 +0800
@@ -6,12 +6,13 @@
 
 yaffs-y := yaffs_ecc.o yaffs_vfs.o yaffs_guts.o yaffs_checkptrw.o
 yaffs-y += yaffs_packedtags1.o yaffs_packedtags2.o yaffs_nand.o
-yaffs-y += yaffs_tagscompat.o yaffs_tagsvalidity.o
+yaffs-y += yaffs_tagscompat.o
 yaffs-y += yaffs_mtdif.o yaffs_mtdif1.o yaffs_mtdif2.o
 yaffs-y += yaffs_nameval.o yaffs_attribs.o
 yaffs-y += yaffs_allocator.o
 yaffs-y += yaffs_yaffs1.o
 yaffs-y += yaffs_yaffs2.o
 yaffs-y += yaffs_bitmap.o
+yaffs-y += yaffs_summary.o
 yaffs-y += yaffs_verify.o
 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_allocator.c linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_allocator.c
--- linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_allocator.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_allocator.c	2014-07-29 17:28:38.819972000 +0800
@@ -1,7 +1,7 @@
 /*
  * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
  *
- * Copyright (C) 2002-2010 Aleph One Ltd.
+ * Copyright (C) 2002-2011 Aleph One Ltd.
  *   for Toby Churchill Ltd and Brightstar Engineering
  *
  * Created by Charles Manning <charles@aleph1.co.uk>
@@ -16,53 +16,19 @@
 #include "yaffs_trace.h"
 #include "yportenv.h"
 
-#ifdef CONFIG_YAFFS_KMALLOC_ALLOCATOR
-
-void yaffs_deinit_raw_tnodes_and_objs(struct yaffs_dev *dev)
-{
-	dev = dev;
-}
-
-void yaffs_init_raw_tnodes_and_objs(struct yaffs_dev *dev)
-{
-	dev = dev;
-}
-
-struct yaffs_tnode *yaffs_alloc_raw_tnode(struct yaffs_dev *dev)
-{
-	return (struct yaffs_tnode *)kmalloc(dev->tnode_size, GFP_NOFS);
-}
-
-void yaffs_free_raw_tnode(struct yaffs_dev *dev, struct yaffs_tnode *tn)
-{
-	dev = dev;
-	kfree(tn);
-}
-
-void yaffs_init_raw_objs(struct yaffs_dev *dev)
-{
-	dev = dev;
-}
-
-void yaffs_deinit_raw_objs(struct yaffs_dev *dev)
-{
-	dev = dev;
-}
-
-struct yaffs_obj *yaffs_alloc_raw_obj(struct yaffs_dev *dev)
-{
-	dev = dev;
-	return (struct yaffs_obj *)kmalloc(sizeof(struct yaffs_obj));
-}
-
-void yaffs_free_raw_obj(struct yaffs_dev *dev, struct yaffs_obj *obj)
-{
-
-	dev = dev;
-	kfree(obj);
-}
-
-#else
+/*
+ * Each entry in yaffs_tnode_list and yaffs_obj_list hold blocks
+ * of approx 100 objects that are themn allocated singly.
+ * This is basically a simplified slab allocator.
+ *
+ * We don't use the Linux slab allocator because slab does not allow
+ * us to dump all the objects in one hit when we do a umount and tear
+ * down  all the tnodes and objects. slab requires that we first free
+ * the individual objects.
+ *
+ * Once yaffs has been mainlined I shall try to motivate for a change
+ * to slab to provide the extra features we need here.
+ */
 
 struct yaffs_tnode_list {
 	struct yaffs_tnode_list *next;
@@ -81,7 +47,7 @@
 	struct yaffs_tnode_list *alloc_tnode_list;
 
 	int n_obj_created;
-	struct yaffs_obj *free_objs;
+	struct list_head free_objs;
 	int n_free_objects;
 
 	struct yaffs_obj_list *allocated_obj_list;
@@ -89,14 +55,12 @@
 
 static void yaffs_deinit_raw_tnodes(struct yaffs_dev *dev)
 {
-
 	struct yaffs_allocator *allocator =
 	    (struct yaffs_allocator *)dev->allocator;
-
 	struct yaffs_tnode_list *tmp;
 
 	if (!allocator) {
-		YBUG();
+		BUG();
 		return;
 	}
 
@@ -106,7 +70,6 @@
 		kfree(allocator->alloc_tnode_list->tnodes);
 		kfree(allocator->alloc_tnode_list);
 		allocator->alloc_tnode_list = tmp;
-
 	}
 
 	allocator->free_tnodes = NULL;
@@ -118,14 +81,15 @@
 {
 	struct yaffs_allocator *allocator = dev->allocator;
 
-	if (allocator) {
-		allocator->alloc_tnode_list = NULL;
-		allocator->free_tnodes = NULL;
-		allocator->n_free_tnodes = 0;
-		allocator->n_tnodes_created = 0;
-	} else {
-		YBUG();
+	if (!allocator) {
+		BUG();
+		return;
 	}
+
+	allocator->alloc_tnode_list = NULL;
+	allocator->free_tnodes = NULL;
+	allocator->n_free_tnodes = 0;
+	allocator->n_tnodes_created = 0;
 }
 
 static int yaffs_create_tnodes(struct yaffs_dev *dev, int n_tnodes)
@@ -140,7 +104,7 @@
 	struct yaffs_tnode_list *tnl;
 
 	if (!allocator) {
-		YBUG();
+		BUG();
 		return YAFFS_FAIL;
 	}
 
@@ -148,7 +112,6 @@
 		return YAFFS_OK;
 
 	/* make these things */
-
 	new_tnodes = kmalloc(n_tnodes * dev->tnode_size, GFP_NOFS);
 	mem = (u8 *) new_tnodes;
 
@@ -176,7 +139,6 @@
 	 * NB If we can't add this to the management list it isn't fatal
 	 * but it just means we can't free this bunch of tnodes later.
 	 */
-
 	tnl = kmalloc(sizeof(struct yaffs_tnode_list), GFP_NOFS);
 	if (!tnl) {
 		yaffs_trace(YAFFS_TRACE_ERROR,
@@ -188,7 +150,7 @@
 		allocator->alloc_tnode_list = tnl;
 	}
 
-	yaffs_trace(YAFFS_TRACE_ALLOCATE,"Tnodes added");
+	yaffs_trace(YAFFS_TRACE_ALLOCATE, "Tnodes added");
 
 	return YAFFS_OK;
 }
@@ -200,7 +162,7 @@
 	struct yaffs_tnode *tn = NULL;
 
 	if (!allocator) {
-		YBUG();
+		BUG();
 		return NULL;
 	}
 
@@ -223,7 +185,7 @@
 	struct yaffs_allocator *allocator = dev->allocator;
 
 	if (!allocator) {
-		YBUG();
+		BUG();
 		return;
 	}
 
@@ -235,17 +197,24 @@
 	dev->checkpoint_blocks_required = 0;	/* force recalculation */
 }
 
+/*--------------- yaffs_obj alloaction ------------------------
+ *
+ * Free yaffs_objs are stored in a list using obj->siblings.
+ * The blocks of allocated objects are stored in a linked list.
+ */
+
 static void yaffs_init_raw_objs(struct yaffs_dev *dev)
 {
 	struct yaffs_allocator *allocator = dev->allocator;
 
-	if (allocator) {
-		allocator->allocated_obj_list = NULL;
-		allocator->free_objs = NULL;
-		allocator->n_free_objects = 0;
-	} else {
-		YBUG();
+	if (!allocator) {
+		BUG();
+		return;
 	}
+
+	allocator->allocated_obj_list = NULL;
+	INIT_LIST_HEAD(&allocator->free_objs);
+	allocator->n_free_objects = 0;
 }
 
 static void yaffs_deinit_raw_objs(struct yaffs_dev *dev)
@@ -254,7 +223,7 @@
 	struct yaffs_obj_list *tmp;
 
 	if (!allocator) {
-		YBUG();
+		BUG();
 		return;
 	}
 
@@ -262,11 +231,10 @@
 		tmp = allocator->allocated_obj_list->next;
 		kfree(allocator->allocated_obj_list->objects);
 		kfree(allocator->allocated_obj_list);
-
 		allocator->allocated_obj_list = tmp;
 	}
 
-	allocator->free_objs = NULL;
+	INIT_LIST_HEAD(&allocator->free_objs);
 	allocator->n_free_objects = 0;
 	allocator->n_obj_created = 0;
 }
@@ -274,13 +242,12 @@
 static int yaffs_create_free_objs(struct yaffs_dev *dev, int n_obj)
 {
 	struct yaffs_allocator *allocator = dev->allocator;
-
 	int i;
 	struct yaffs_obj *new_objs;
 	struct yaffs_obj_list *list;
 
 	if (!allocator) {
-		YBUG();
+		BUG();
 		return YAFFS_FAIL;
 	}
 
@@ -292,27 +259,19 @@
 	list = kmalloc(sizeof(struct yaffs_obj_list), GFP_NOFS);
 
 	if (!new_objs || !list) {
-		if (new_objs) {
-			kfree(new_objs);
-			new_objs = NULL;
-		}
-		if (list) {
-			kfree(list);
-			list = NULL;
-		}
+		kfree(new_objs);
+		new_objs = NULL;
+		kfree(list);
+		list = NULL;
 		yaffs_trace(YAFFS_TRACE_ALLOCATE,
 			"Could not allocate more objects");
 		return YAFFS_FAIL;
 	}
 
 	/* Hook them into the free list */
-	for (i = 0; i < n_obj - 1; i++) {
-		new_objs[i].siblings.next =
-		    (struct list_head *)(&new_objs[i + 1]);
-	}
+	for (i = 0; i < n_obj; i++)
+		list_add(&new_objs[i].siblings, &allocator->free_objs);
 
-	new_objs[n_obj - 1].siblings.next = (void *)allocator->free_objs;
-	allocator->free_objs = new_objs;
 	allocator->n_free_objects += n_obj;
 	allocator->n_obj_created += n_obj;
 
@@ -328,21 +287,22 @@
 struct yaffs_obj *yaffs_alloc_raw_obj(struct yaffs_dev *dev)
 {
 	struct yaffs_obj *obj = NULL;
+	struct list_head *lh;
 	struct yaffs_allocator *allocator = dev->allocator;
 
 	if (!allocator) {
-		YBUG();
+		BUG();
 		return obj;
 	}
 
 	/* If there are none left make more */
-	if (!allocator->free_objs)
+	if (list_empty(&allocator->free_objs))
 		yaffs_create_free_objs(dev, YAFFS_ALLOCATION_NOBJECTS);
 
-	if (allocator->free_objs) {
-		obj = allocator->free_objs;
-		allocator->free_objs =
-		    (struct yaffs_obj *)(allocator->free_objs->siblings.next);
+	if (!list_empty(&allocator->free_objs)) {
+		lh = allocator->free_objs.next;
+		obj = list_entry(lh, struct yaffs_obj, siblings);
+		list_del_init(lh);
 		allocator->n_free_objects--;
 	}
 
@@ -354,43 +314,44 @@
 
 	struct yaffs_allocator *allocator = dev->allocator;
 
-	if (!allocator)
-		YBUG();
-	else {
-		/* Link into the free list. */
-		obj->siblings.next = (struct list_head *)(allocator->free_objs);
-		allocator->free_objs = obj;
-		allocator->n_free_objects++;
+	if (!allocator) {
+		BUG();
+		return;
 	}
+
+	/* Link into the free list. */
+	list_add(&obj->siblings, &allocator->free_objs);
+	allocator->n_free_objects++;
 }
 
 void yaffs_deinit_raw_tnodes_and_objs(struct yaffs_dev *dev)
 {
-	if (dev->allocator) {
-		yaffs_deinit_raw_tnodes(dev);
-		yaffs_deinit_raw_objs(dev);
 
-		kfree(dev->allocator);
-		dev->allocator = NULL;
-	} else {
-		YBUG();
+	if (!dev->allocator) {
+		BUG();
+		return;
 	}
+
+	yaffs_deinit_raw_tnodes(dev);
+	yaffs_deinit_raw_objs(dev);
+	kfree(dev->allocator);
+	dev->allocator = NULL;
 }
 
 void yaffs_init_raw_tnodes_and_objs(struct yaffs_dev *dev)
 {
 	struct yaffs_allocator *allocator;
 
-	if (!dev->allocator) {
-		allocator = kmalloc(sizeof(struct yaffs_allocator), GFP_NOFS);
-		if (allocator) {
-			dev->allocator = allocator;
-			yaffs_init_raw_tnodes(dev);
-			yaffs_init_raw_objs(dev);
-		}
-	} else {
-		YBUG();
+	if (dev->allocator) {
+		BUG();
+		return;
+	}
+
+	allocator = kmalloc(sizeof(struct yaffs_allocator), GFP_NOFS);
+	if (allocator) {
+		dev->allocator = allocator;
+		yaffs_init_raw_tnodes(dev);
+		yaffs_init_raw_objs(dev);
 	}
 }
 
-#endif
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_allocator.h linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_allocator.h
--- linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_allocator.h	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_allocator.h	2014-07-29 17:28:38.819972000 +0800
@@ -1,7 +1,7 @@
 /*
  * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
  *
- * Copyright (C) 2002-2010 Aleph One Ltd.
+ * Copyright (C) 2002-2011 Aleph One Ltd.
  *   for Toby Churchill Ltd and Brightstar Engineering
  *
  * Created by Charles Manning <charles@aleph1.co.uk>
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_attribs.c linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_attribs.c
--- linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_attribs.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_attribs.c	2014-07-29 17:28:38.819972000 +0800
@@ -1,7 +1,7 @@
 /*
  * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
  *
- * Copyright (C) 2002-2010 Aleph One Ltd.
+ * Copyright (C) 2002-2011 Aleph One Ltd.
  *   for Toby Churchill Ltd and Brightstar Engineering
  *
  * Created by Charles Manning <charles@aleph1.co.uk>
@@ -52,7 +52,7 @@
 	obj->yst_gid = gid;
 }
 
-loff_t yaffs_get_file_size(struct yaffs_obj *obj)
+static loff_t yaffs_get_file_size(struct yaffs_obj *obj)
 {
 	YCHAR *alias = NULL;
 	obj = yaffs_get_equivalent_obj(obj);
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_attribs.h linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_attribs.h
--- linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_attribs.h	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_attribs.h	2014-07-29 17:28:38.819972000 +0800
@@ -1,7 +1,7 @@
 /*
  * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
  *
- * Copyright (C) 2002-2010 Aleph One Ltd.
+ * Copyright (C) 2002-2011 Aleph One Ltd.
  *   for Toby Churchill Ltd and Brightstar Engineering
  *
  * Created by Charles Manning <charles@aleph1.co.uk>
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_bitmap.c linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_bitmap.c
--- linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_bitmap.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_bitmap.c	2014-07-29 17:28:38.819972000 +0800
@@ -1,7 +1,7 @@
 /*
  * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
  *
- * Copyright (C) 2002-2010 Aleph One Ltd.
+ * Copyright (C) 2002-2011 Aleph One Ltd.
  *   for Toby Churchill Ltd and Brightstar Engineering
  *
  * Created by Charles Manning <charles@aleph1.co.uk>
@@ -23,7 +23,7 @@
 		yaffs_trace(YAFFS_TRACE_ERROR,
 			"BlockBits block %d is not valid",
 			blk);
-		YBUG();
+		BUG();
 	}
 	return dev->chunk_bits +
 	    (dev->chunk_bit_stride * (blk - dev->internal_start_block));
@@ -36,7 +36,7 @@
 		yaffs_trace(YAFFS_TRACE_ERROR,
 			"Chunk Id (%d:%d) invalid",
 			blk, chunk);
-		YBUG();
+		BUG();
 	}
 }
 
@@ -52,7 +52,6 @@
 	u8 *blk_bits = yaffs_block_bits(dev, blk);
 
 	yaffs_verify_chunk_bit_id(dev, blk, chunk);
-
 	blk_bits[chunk / 8] &= ~(1 << (chunk & 7));
 }
 
@@ -61,15 +60,14 @@
 	u8 *blk_bits = yaffs_block_bits(dev, blk);
 
 	yaffs_verify_chunk_bit_id(dev, blk, chunk);
-
 	blk_bits[chunk / 8] |= (1 << (chunk & 7));
 }
 
 int yaffs_check_chunk_bit(struct yaffs_dev *dev, int blk, int chunk)
 {
 	u8 *blk_bits = yaffs_block_bits(dev, blk);
-	yaffs_verify_chunk_bit_id(dev, blk, chunk);
 
+	yaffs_verify_chunk_bit_id(dev, blk, chunk);
 	return (blk_bits[chunk / 8] & (1 << (chunk & 7))) ? 1 : 0;
 }
 
@@ -77,6 +75,7 @@
 {
 	u8 *blk_bits = yaffs_block_bits(dev, blk);
 	int i;
+
 	for (i = 0; i < dev->chunk_bit_stride; i++) {
 		if (*blk_bits)
 			return 1;
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_bitmap.h linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_bitmap.h
--- linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_bitmap.h	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_bitmap.h	2014-07-29 17:28:38.819972000 +0800
@@ -1,7 +1,7 @@
 /*
  * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
  *
- * Copyright (C) 2002-2010 Aleph One Ltd.
+ * Copyright (C) 2002-2011 Aleph One Ltd.
  *   for Toby Churchill Ltd and Brightstar Engineering
  *
  * Created by Charles Manning <charles@aleph1.co.uk>
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_checkptrw.c linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_checkptrw.c
--- linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_checkptrw.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_checkptrw.c	2014-07-29 17:28:38.819972000 +0800
@@ -1,7 +1,7 @@
 /*
  * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
  *
- * Copyright (C) 2002-2010 Aleph One Ltd.
+ * Copyright (C) 2002-2011 Aleph One Ltd.
  *   for Toby Churchill Ltd and Brightstar Engineering
  *
  * Created by Charles Manning <charles@aleph1.co.uk>
@@ -14,6 +14,52 @@
 #include "yaffs_checkptrw.h"
 #include "yaffs_getblockinfo.h"
 
+struct yaffs_checkpt_chunk_hdr {
+	int version;
+	int seq;
+	u32 sum;
+	u32 xor;
+} ;
+
+
+static int apply_chunk_offset(struct yaffs_dev *dev, int chunk)
+{
+	return chunk - dev->chunk_offset;
+}
+
+static int apply_block_offset(struct yaffs_dev *dev, int block)
+{
+	return block - dev->block_offset;
+}
+
+static void yaffs2_checkpt_init_chunk_hdr(struct yaffs_dev *dev)
+{
+	struct yaffs_checkpt_chunk_hdr hdr;
+
+	hdr.version = YAFFS_CHECKPOINT_VERSION;
+	hdr.seq = dev->checkpt_page_seq;
+	hdr.sum = dev->checkpt_sum;
+	hdr.xor = dev->checkpt_xor;
+
+	dev->checkpt_byte_offs = sizeof(hdr);
+
+	memcpy(dev->checkpt_buffer, &hdr, sizeof(hdr));
+}
+
+static int yaffs2_checkpt_check_chunk_hdr(struct yaffs_dev *dev)
+{
+	struct yaffs_checkpt_chunk_hdr hdr;
+
+	memcpy(&hdr, dev->checkpt_buffer, sizeof(hdr));
+
+	dev->checkpt_byte_offs = sizeof(hdr);
+
+	return hdr.version == YAFFS_CHECKPOINT_VERSION &&
+		hdr.seq == dev->checkpt_page_seq &&
+		hdr.sum == dev->checkpt_sum &&
+		hdr.xor == dev->checkpt_xor;
+}
+
 static int yaffs2_checkpt_space_ok(struct yaffs_dev *dev)
 {
 	int blocks_avail = dev->n_erased_blocks - dev->param.n_reserved_blocks;
@@ -36,21 +82,23 @@
 
 	for (i = dev->internal_start_block; i <= dev->internal_end_block; i++) {
 		struct yaffs_block_info *bi = yaffs_get_block_info(dev, i);
+		int offset_i = apply_block_offset(dev, i);
+		int result;
+
 		if (bi->block_state == YAFFS_BLOCK_STATE_CHECKPOINT) {
 			yaffs_trace(YAFFS_TRACE_CHECKPOINT,
 			"erasing checkpt block %d", i);
 
 			dev->n_erasures++;
 
-			if (dev->param.
-			    erase_fn(dev,
-				     i - dev->block_offset /* realign */ )) {
+			result = dev->param.erase_fn(dev, offset_i);
+			if(result) {
 				bi->block_state = YAFFS_BLOCK_STATE_EMPTY;
 				dev->n_erased_blocks++;
 				dev->n_free_chunks +=
 				    dev->param.chunks_per_block;
 			} else {
-				dev->param.bad_block_fn(dev, i);
+				dev->param.bad_block_fn(dev, offset_i);
 				bi->block_state = YAFFS_BLOCK_STATE_DEAD;
 			}
 		}
@@ -65,6 +113,7 @@
 {
 	int i;
 	int blocks_avail = dev->n_erased_blocks - dev->param.n_reserved_blocks;
+
 	yaffs_trace(YAFFS_TRACE_CHECKPOINT,
 		"allocating checkpt block: erased %d reserved %d avail %d next %d ",
 		dev->n_erased_blocks, dev->param.n_reserved_blocks,
@@ -76,8 +125,9 @@
 
 		for (i = dev->checkpt_next_block; i <= dev->internal_end_block;
 		     i++) {
-			struct yaffs_block_info *bi =
-			    yaffs_get_block_info(dev, i);
+			struct yaffs_block_info *bi;
+
+			bi = yaffs_get_block_info(dev, i);
 			if (bi->block_state == YAFFS_BLOCK_STATE_EMPTY) {
 				dev->checkpt_next_block = i + 1;
 				dev->checkpt_cur_block = i;
@@ -106,26 +156,35 @@
 		for (i = dev->checkpt_next_block; i <= dev->internal_end_block;
 		     i++) {
 			int chunk = i * dev->param.chunks_per_block;
-			int realigned_chunk = chunk - dev->chunk_offset;
+			enum yaffs_block_state state;
+			u32 seq;
 
-			dev->param.read_chunk_tags_fn(dev, realigned_chunk,
-						      NULL, &tags);
+			dev->param.read_chunk_tags_fn(dev,
+					apply_chunk_offset(dev, chunk),
+					NULL, &tags);
 			yaffs_trace(YAFFS_TRACE_CHECKPOINT,
-				"find next checkpt block: search: block %d oid %d seq %d eccr %d",
-				i, tags.obj_id, tags.seq_number,
+				"find next checkpt block: search: block %d state %d oid %d seq %d eccr %d",
+				i, (int) state,
+				tags.obj_id, tags.seq_number,
 				tags.ecc_result);
 
-			if (tags.seq_number == YAFFS_SEQUENCE_CHECKPOINT_DATA) {
-				/* Right kind of block */
-				dev->checkpt_next_block = tags.obj_id;
-				dev->checkpt_cur_block = i;
-				dev->checkpt_block_list[dev->
-							blocks_in_checkpt] = i;
-				dev->blocks_in_checkpt++;
-				yaffs_trace(YAFFS_TRACE_CHECKPOINT,
-					"found checkpt block %d", i);
-				return;
-			}
+			if (tags.seq_number != YAFFS_SEQUENCE_CHECKPOINT_DATA)
+				continue;
+
+			dev->param.query_block_fn(dev,
+						apply_block_offset(dev, i),
+						&state, &seq);
+			if (state == YAFFS_BLOCK_STATE_DEAD)
+				continue;
+
+			/* Right kind of block */
+			dev->checkpt_next_block = tags.obj_id;
+			dev->checkpt_cur_block = i;
+			dev->checkpt_block_list[dev->blocks_in_checkpt] = i;
+			dev->blocks_in_checkpt++;
+			yaffs_trace(YAFFS_TRACE_CHECKPOINT,
+				"found checkpt block %d", i);
+			return;
 		}
 
 	yaffs_trace(YAFFS_TRACE_CHECKPOINT, "found no more checkpt blocks");
@@ -136,6 +195,7 @@
 
 int yaffs2_checkpt_open(struct yaffs_dev *dev, int writing)
 {
+	int i;
 
 	dev->checkpt_open_write = writing;
 
@@ -162,37 +222,37 @@
 	dev->checkpt_cur_chunk = -1;
 	dev->checkpt_next_block = dev->internal_start_block;
 
-	/* Erase all the blocks in the checkpoint area */
 	if (writing) {
 		memset(dev->checkpt_buffer, 0, dev->data_bytes_per_chunk);
-		dev->checkpt_byte_offs = 0;
+		yaffs2_checkpt_init_chunk_hdr(dev);
 		return yaffs_checkpt_erase(dev);
-	} else {
-		int i;
-		/* Set to a value that will kick off a read */
-		dev->checkpt_byte_offs = dev->data_bytes_per_chunk;
-		/* A checkpoint block list of 1 checkpoint block per 16 block is (hopefully)
-		 * going to be way more than we need */
-		dev->blocks_in_checkpt = 0;
-		dev->checkpt_max_blocks =
-		    (dev->internal_end_block - dev->internal_start_block) / 16 +
-		    2;
-		dev->checkpt_block_list =
-		    kmalloc(sizeof(int) * dev->checkpt_max_blocks, GFP_NOFS);
-		if (!dev->checkpt_block_list)
-			return 0;
-
-		for (i = 0; i < dev->checkpt_max_blocks; i++)
-			dev->checkpt_block_list[i] = -1;
 	}
 
+	/* Opening for a read */
+	/* Set to a value that will kick off a read */
+	dev->checkpt_byte_offs = dev->data_bytes_per_chunk;
+	/* A checkpoint block list of 1 checkpoint block per 16 block is
+	 * (hopefully) going to be way more than we need */
+	dev->blocks_in_checkpt = 0;
+	dev->checkpt_max_blocks =
+	    (dev->internal_end_block - dev->internal_start_block) / 16 + 2;
+	dev->checkpt_block_list =
+	    kmalloc(sizeof(int) * dev->checkpt_max_blocks, GFP_NOFS);
+
+	if (!dev->checkpt_block_list)
+		return 0;
+
+	for (i = 0; i < dev->checkpt_max_blocks; i++)
+		dev->checkpt_block_list[i] = -1;
+
 	return 1;
 }
 
 int yaffs2_get_checkpt_sum(struct yaffs_dev *dev, u32 * sum)
 {
 	u32 composite_sum;
-	composite_sum = (dev->checkpt_sum << 8) | (dev->checkpt_xor & 0xFF);
+
+	composite_sum = (dev->checkpt_sum << 8) | (dev->checkpt_xor & 0xff);
 	*sum = composite_sum;
 	return 1;
 }
@@ -200,8 +260,7 @@
 static int yaffs2_checkpt_flush_buffer(struct yaffs_dev *dev)
 {
 	int chunk;
-	int realigned_chunk;
-
+	int offset_chunk;
 	struct yaffs_ext_tags tags;
 
 	if (dev->checkpt_cur_block < 0) {
@@ -235,13 +294,12 @@
 		chunk, dev->checkpt_cur_block, dev->checkpt_cur_chunk,
 		tags.obj_id, tags.chunk_id);
 
-	realigned_chunk = chunk - dev->chunk_offset;
+	offset_chunk = apply_chunk_offset(dev, chunk);
 
 	dev->n_page_writes++;
 
-	dev->param.write_chunk_tags_fn(dev, realigned_chunk,
+	dev->param.write_chunk_tags_fn(dev, offset_chunk,
 				       dev->checkpt_buffer, &tags);
-	dev->checkpt_byte_offs = 0;
 	dev->checkpt_page_seq++;
 	dev->checkpt_cur_chunk++;
 	if (dev->checkpt_cur_chunk >= dev->param.chunks_per_block) {
@@ -250,6 +308,9 @@
 	}
 	memset(dev->checkpt_buffer, 0, dev->data_bytes_per_chunk);
 
+	yaffs2_checkpt_init_chunk_hdr(dev);
+
+
 	return 1;
 }
 
@@ -257,7 +318,6 @@
 {
 	int i = 0;
 	int ok = 1;
-
 	u8 *data_bytes = (u8 *) data;
 
 	if (!dev->checkpt_buffer)
@@ -289,10 +349,8 @@
 	int i = 0;
 	int ok = 1;
 	struct yaffs_ext_tags tags;
-
 	int chunk;
-	int realigned_chunk;
-
+	int offset_chunk;
 	u8 *data_bytes = (u8 *) data;
 
 	if (!dev->checkpt_buffer)
@@ -311,50 +369,51 @@
 				dev->checkpt_cur_chunk = 0;
 			}
 
-			if (dev->checkpt_cur_block < 0)
+			if (dev->checkpt_cur_block < 0) {
 				ok = 0;
-			else {
-				chunk = dev->checkpt_cur_block *
-				    dev->param.chunks_per_block +
-				    dev->checkpt_cur_chunk;
-
-				realigned_chunk = chunk - dev->chunk_offset;
-
-				dev->n_page_reads++;
-
-				/* read in the next chunk */
-				dev->param.read_chunk_tags_fn(dev,
-							      realigned_chunk,
-							      dev->
-							      checkpt_buffer,
-							      &tags);
-
-				if (tags.chunk_id != (dev->checkpt_page_seq + 1)
-				    || tags.ecc_result > YAFFS_ECC_RESULT_FIXED
-				    || tags.seq_number !=
-				    YAFFS_SEQUENCE_CHECKPOINT_DATA)
-					ok = 0;
-
-				dev->checkpt_byte_offs = 0;
-				dev->checkpt_page_seq++;
-				dev->checkpt_cur_chunk++;
-
-				if (dev->checkpt_cur_chunk >=
-				    dev->param.chunks_per_block)
-					dev->checkpt_cur_block = -1;
+				break;
 			}
-		}
 
-		if (ok) {
-			*data_bytes =
-			    dev->checkpt_buffer[dev->checkpt_byte_offs];
-			dev->checkpt_sum += *data_bytes;
-			dev->checkpt_xor ^= *data_bytes;
-			dev->checkpt_byte_offs++;
-			i++;
-			data_bytes++;
-			dev->checkpt_byte_count++;
+			chunk = dev->checkpt_cur_block *
+			    dev->param.chunks_per_block +
+			    dev->checkpt_cur_chunk;
+
+			offset_chunk = apply_chunk_offset(dev, chunk);
+			dev->n_page_reads++;
+
+			/* read in the next chunk */
+			dev->param.read_chunk_tags_fn(dev,
+						offset_chunk,
+						dev->checkpt_buffer,
+						&tags);
+
+			if (tags.chunk_id != (dev->checkpt_page_seq + 1) ||
+			    tags.ecc_result > YAFFS_ECC_RESULT_FIXED ||
+			    tags.seq_number != YAFFS_SEQUENCE_CHECKPOINT_DATA) {
+				ok = 0;
+				break;
+			}
+			if(!yaffs2_checkpt_check_chunk_hdr(dev)) {
+				ok = 0;
+				break;
+			}
+
+			dev->checkpt_page_seq++;
+			dev->checkpt_cur_chunk++;
+
+			if (dev->checkpt_cur_chunk >=
+					dev->param.chunks_per_block)
+				dev->checkpt_cur_block = -1;
+
 		}
+
+		*data_bytes = dev->checkpt_buffer[dev->checkpt_byte_offs];
+		dev->checkpt_sum += *data_bytes;
+		dev->checkpt_xor ^= *data_bytes;
+		dev->checkpt_byte_offs++;
+		i++;
+		data_bytes++;
+		dev->checkpt_byte_count++;
 	}
 
 	return i;
@@ -362,35 +421,34 @@
 
 int yaffs_checkpt_close(struct yaffs_dev *dev)
 {
+	int i;
 
 	if (dev->checkpt_open_write) {
-		if (dev->checkpt_byte_offs != 0)
+		if (dev->checkpt_byte_offs !=
+			sizeof(sizeof(struct yaffs_checkpt_chunk_hdr)))
 			yaffs2_checkpt_flush_buffer(dev);
 	} else if (dev->checkpt_block_list) {
-		int i;
 		for (i = 0;
-		     i < dev->blocks_in_checkpt
-		     && dev->checkpt_block_list[i] >= 0; i++) {
+		     i < dev->blocks_in_checkpt &&
+		     dev->checkpt_block_list[i] >= 0; i++) {
 			int blk = dev->checkpt_block_list[i];
 			struct yaffs_block_info *bi = NULL;
-			if (dev->internal_start_block <= blk
-			    && blk <= dev->internal_end_block)
+
+			if (dev->internal_start_block <= blk &&
+			    blk <= dev->internal_end_block)
 				bi = yaffs_get_block_info(dev, blk);
 			if (bi && bi->block_state == YAFFS_BLOCK_STATE_EMPTY)
 				bi->block_state = YAFFS_BLOCK_STATE_CHECKPOINT;
-			else {
-				/* Todo this looks odd... */
-			}
 		}
 		kfree(dev->checkpt_block_list);
 		dev->checkpt_block_list = NULL;
 	}
 
 	dev->n_free_chunks -=
-	    dev->blocks_in_checkpt * dev->param.chunks_per_block;
+		dev->blocks_in_checkpt * dev->param.chunks_per_block;
 	dev->n_erased_blocks -= dev->blocks_in_checkpt;
 
-	yaffs_trace(YAFFS_TRACE_CHECKPOINT,"checkpoint byte count %d",
+	yaffs_trace(YAFFS_TRACE_CHECKPOINT, "checkpoint byte count %d",
 		dev->checkpt_byte_count);
 
 	if (dev->checkpt_buffer) {
@@ -400,7 +458,7 @@
 		return 1;
 	} else {
 		return 0;
-        }
+	}
 }
 
 int yaffs2_checkpt_invalidate_stream(struct yaffs_dev *dev)
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_checkptrw.h linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_checkptrw.h
--- linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_checkptrw.h	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_checkptrw.h	2014-07-29 17:28:38.819972000 +0800
@@ -1,7 +1,7 @@
 /*
  * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
  *
- * Copyright (C) 2002-2010 Aleph One Ltd.
+ * Copyright (C) 2002-2011 Aleph One Ltd.
  *   for Toby Churchill Ltd and Brightstar Engineering
  *
  * Created by Charles Manning <charles@aleph1.co.uk>
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_ecc.c linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_ecc.c
--- linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_ecc.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_ecc.c	2014-07-29 17:28:38.819972000 +0800
@@ -1,7 +1,7 @@
 /*
  * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
  *
- * Copyright (C) 2002-2010 Aleph One Ltd.
+ * Copyright (C) 2002-2011 Aleph One Ltd.
  *   for Toby Churchill Ltd and Brightstar Engineering
  *
  * Created by Charles Manning <charles@aleph1.co.uk>
@@ -16,22 +16,22 @@
  *
  * The ECC comprises 22 bits of parity information and is stuffed into 3 bytes.
  * The two unused bit are set to 1.
- * The ECC can correct single bit errors in a 256-byte page of data. Thus, two such ECC
- * blocks are used on a 512-byte NAND page.
+ * The ECC can correct single bit errors in a 256-byte page of data. Thus, two
+ * such ECC blocks are used on a 512-byte NAND page.
  *
  */
 
+#include "yportenv.h"
+
+#include "yaffs_ecc.h"
+
 /* Table generated by gen-ecc.c
  * Using a table means we do not have to calculate p1..p4 and p1'..p4'
  * for each byte of data. These are instead provided in a table in bits7..2.
- * Bit 0 of each entry indicates whether the entry has an odd or even parity, and therefore
- * this bytes influence on the line parity.
+ * Bit 0 of each entry indicates whether the entry has an odd or even parity,
+ * and therefore this bytes influence on the line parity.
  */
 
-#include "yportenv.h"
-
-#include "yaffs_ecc.h"
-
 static const unsigned char column_parity_table[] = {
 	0x00, 0x55, 0x59, 0x0c, 0x65, 0x30, 0x3c, 0x69,
 	0x69, 0x3c, 0x30, 0x65, 0x0c, 0x59, 0x55, 0x00,
@@ -69,10 +69,9 @@
 
 
 /* Calculate the ECC for a 256-byte block of data */
-void yaffs_ecc_cacl(const unsigned char *data, unsigned char *ecc)
+void yaffs_ecc_calc(const unsigned char *data, unsigned char *ecc)
 {
 	unsigned int i;
-
 	unsigned char col_parity = 0;
 	unsigned char line_parity = 0;
 	unsigned char line_parity_prime = 0;
@@ -129,12 +128,6 @@
 		t |= 0x01;
 	ecc[0] = ~t;
 
-#ifdef CONFIG_YAFFS_ECC_WRONG_ORDER
-	/* Swap the bytes into the wrong order */
-	t = ecc[0];
-	ecc[0] = ecc[1];
-	ecc[1] = t;
-#endif
 }
 
 /* Correct the ECC on a 256 byte block of data */
@@ -159,15 +152,6 @@
 		unsigned byte;
 		unsigned bit;
 
-#ifdef CONFIG_YAFFS_ECC_WRONG_ORDER
-		/* swap the bytes to correct for the wrong order */
-		unsigned char t;
-
-		t = d0;
-		d0 = d1;
-		d1 = t;
-#endif
-
 		bit = byte = 0;
 
 		if (d1 & 0x80)
@@ -222,7 +206,6 @@
 			  struct yaffs_ecc_other *ecc_other)
 {
 	unsigned int i;
-
 	unsigned char col_parity = 0;
 	unsigned line_parity = 0;
 	unsigned line_parity_prime = 0;
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_ecc.h linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_ecc.h
--- linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_ecc.h	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_ecc.h	2014-07-29 17:28:38.819972000 +0800
@@ -1,7 +1,7 @@
 /*
  * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
  *
- * Copyright (C) 2002-2010 Aleph One Ltd.
+ * Copyright (C) 2002-2011 Aleph One Ltd.
  *   for Toby Churchill Ltd and Brightstar Engineering
  *
  * Created by Charles Manning <charles@aleph1.co.uk>
@@ -18,8 +18,8 @@
  *
  * The ECC comprises 22 bits of parity information and is stuffed into 3 bytes.
  * The two unused bit are set to 1.
- * The ECC can correct single bit errors in a 256-byte page of data. Thus, two such ECC
- * blocks are used on a 512-byte NAND page.
+ * The ECC can correct single bit errors in a 256-byte page of data.
+ * Thus, two such ECC blocks are used on a 512-byte NAND page.
  *
  */
 
@@ -32,7 +32,7 @@
 	unsigned line_parity_prime;
 };
 
-void yaffs_ecc_cacl(const unsigned char *data, unsigned char *ecc);
+void yaffs_ecc_calc(const unsigned char *data, unsigned char *ecc);
 int yaffs_ecc_correct(unsigned char *data, unsigned char *read_ecc,
 		      const unsigned char *test_ecc);
 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_getblockinfo.h linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_getblockinfo.h
--- linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_getblockinfo.h	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_getblockinfo.h	2014-07-29 17:28:38.819972000 +0800
@@ -1,7 +1,7 @@
 /*
  * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
  *
- * Copyright (C) 2002-2010 Aleph One Ltd.
+ * Copyright (C) 2002-2011 Aleph One Ltd.
  *   for Toby Churchill Ltd and Brightstar Engineering
  *
  * Created by Charles Manning <charles@aleph1.co.uk>
@@ -27,7 +27,7 @@
 		yaffs_trace(YAFFS_TRACE_ERROR,
 			"**>> yaffs: get_block_info block %d is not valid",
 			blk);
-		YBUG();
+		BUG();
 	}
 	return &dev->block_info[blk - dev->internal_start_block];
 }
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_guts.c linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_guts.c
--- linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_guts.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_guts.c	2014-07-29 17:28:38.819972000 +0800
@@ -1,7 +1,7 @@
 /*
  * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
  *
- * Copyright (C) 2002-2010 Aleph One Ltd.
+ * Copyright (C) 2002-2011 Aleph One Ltd.
  *   for Toby Churchill Ltd and Brightstar Engineering
  *
  * Created by Charles Manning <charles@aleph1.co.uk>
@@ -15,25 +15,19 @@
 #include "yaffs_trace.h"
 
 #include "yaffs_guts.h"
-#include "yaffs_tagsvalidity.h"
 #include "yaffs_getblockinfo.h"
-
 #include "yaffs_tagscompat.h"
-
 #include "yaffs_nand.h"
-
 #include "yaffs_yaffs1.h"
 #include "yaffs_yaffs2.h"
 #include "yaffs_bitmap.h"
 #include "yaffs_verify.h"
-
 #include "yaffs_nand.h"
 #include "yaffs_packedtags2.h"
-
 #include "yaffs_nameval.h"
 #include "yaffs_allocator.h"
-
 #include "yaffs_attribs.h"
+#include "yaffs_summary.h"
 
 /* Note YAFFS_GC_GOOD_ENOUGH must be <= YAFFS_GC_PASSIVE_THRESHOLD */
 #define YAFFS_GC_GOOD_ENOUGH 2
@@ -44,14 +38,15 @@
 /* Forward declarations */
 
 static int yaffs_wr_data_obj(struct yaffs_obj *in, int inode_chunk,
-			     const u8 * buffer, int n_bytes, int use_reserve);
-
+			     const u8 *buffer, int n_bytes, int use_reserve);
 
+static void yaffs_fix_null_name(struct yaffs_obj *obj, YCHAR *name,
+				int buffer_size);
 
 /* Function to calculate chunk and offset */
 
-static void yaffs_addr_to_chunk(struct yaffs_dev *dev, loff_t addr,
-				int *chunk_out, u32 * offset_out)
+void yaffs_addr_to_chunk(struct yaffs_dev *dev, loff_t addr,
+				int *chunk_out, u32 *offset_out)
 {
 	int chunk;
 	u32 offset;
@@ -82,7 +77,7 @@
  * be hellishly efficient.
  */
 
-static u32 calc_shifts_ceiling(u32 x)
+static inline u32 calc_shifts_ceiling(u32 x)
 {
 	int extra_bits;
 	int shifts;
@@ -105,7 +100,7 @@
 /* Function to return the number of shifts to get a 1 in bit 0
  */
 
-static u32 calc_shifts(u32 x)
+static inline u32 calc_shifts(u32 x)
 {
 	u32 shifts;
 
@@ -134,42 +129,30 @@
 	memset(dev->temp_buffer, 0, sizeof(dev->temp_buffer));
 
 	for (i = 0; buf && i < YAFFS_N_TEMP_BUFFERS; i++) {
-		dev->temp_buffer[i].line = 0;	/* not in use */
-		dev->temp_buffer[i].buffer = buf =
-		    kmalloc(dev->param.total_bytes_per_chunk, GFP_NOFS);
+		dev->temp_buffer[i].in_use = 0;
+		buf = kmalloc(dev->param.total_bytes_per_chunk, GFP_NOFS);
+		dev->temp_buffer[i].buffer = buf;
 	}
 
 	return buf ? YAFFS_OK : YAFFS_FAIL;
 }
 
-u8 *yaffs_get_temp_buffer(struct yaffs_dev * dev, int line_no)
+u8 *yaffs_get_temp_buffer(struct yaffs_dev * dev)
 {
-	int i, j;
+	int i;
 
 	dev->temp_in_use++;
 	if (dev->temp_in_use > dev->max_temp)
 		dev->max_temp = dev->temp_in_use;
 
 	for (i = 0; i < YAFFS_N_TEMP_BUFFERS; i++) {
-		if (dev->temp_buffer[i].line == 0) {
-			dev->temp_buffer[i].line = line_no;
-			if ((i + 1) > dev->max_temp) {
-				dev->max_temp = i + 1;
-				for (j = 0; j <= i; j++)
-					dev->temp_buffer[j].max_line =
-					    dev->temp_buffer[j].line;
-			}
-
+		if (dev->temp_buffer[i].in_use == 0) {
+			dev->temp_buffer[i].in_use = 1;
 			return dev->temp_buffer[i].buffer;
 		}
 	}
 
-	yaffs_trace(YAFFS_TRACE_BUFFERS,
-		"Out of temp buffers at line %d, other held by lines:",
-		line_no);
-	for (i = 0; i < YAFFS_N_TEMP_BUFFERS; i++)
-		yaffs_trace(YAFFS_TRACE_BUFFERS," %d", dev->temp_buffer[i].line);
-
+	yaffs_trace(YAFFS_TRACE_BUFFERS, "Out of temp buffers");
 	/*
 	 * If we got here then we have to allocate an unmanaged one
 	 * This is not good.
@@ -180,7 +163,7 @@
 
 }
 
-void yaffs_release_temp_buffer(struct yaffs_dev *dev, u8 * buffer, int line_no)
+void yaffs_release_temp_buffer(struct yaffs_dev *dev, u8 *buffer)
 {
 	int i;
 
@@ -188,7 +171,7 @@
 
 	for (i = 0; i < YAFFS_N_TEMP_BUFFERS; i++) {
 		if (dev->temp_buffer[i].buffer == buffer) {
-			dev->temp_buffer[i].line = 0;
+			dev->temp_buffer[i].in_use = 0;
 			return;
 		}
 	}
@@ -196,8 +179,7 @@
 	if (buffer) {
 		/* assume it is an unmanaged one. */
 		yaffs_trace(YAFFS_TRACE_BUFFERS,
-		  "Releasing unmanaged temp buffer in line %d",
-		   line_no);
+			"Releasing unmanaged temp buffer");
 		kfree(buffer);
 		dev->unmanaged_buffer_deallocs++;
 	}
@@ -205,51 +187,26 @@
 }
 
 /*
- * Determine if we have a managed buffer.
- */
-int yaffs_is_managed_tmp_buffer(struct yaffs_dev *dev, const u8 * buffer)
-{
-	int i;
-
-	for (i = 0; i < YAFFS_N_TEMP_BUFFERS; i++) {
-		if (dev->temp_buffer[i].buffer == buffer)
-			return 1;
-	}
-
-	for (i = 0; i < dev->param.n_caches; i++) {
-		if (dev->cache[i].data == buffer)
-			return 1;
-	}
-
-	if (buffer == dev->checkpt_buffer)
-		return 1;
-
-	yaffs_trace(YAFFS_TRACE_ALWAYS,
-	  "yaffs: unmaged buffer detected.");
-	return 0;
-}
-
-/*
  * Functions for robustisizing TODO
  *
  */
 
 static void yaffs_handle_chunk_wr_ok(struct yaffs_dev *dev, int nand_chunk,
-				     const u8 * data,
+				     const u8 *data,
 				     const struct yaffs_ext_tags *tags)
 {
-	dev = dev;
-	nand_chunk = nand_chunk;
-	data = data;
-	tags = tags;
+	(void) dev;
+	(void) nand_chunk;
+	(void) data;
+	(void) tags;
 }
 
 static void yaffs_handle_chunk_update(struct yaffs_dev *dev, int nand_chunk,
 				      const struct yaffs_ext_tags *tags)
 {
-	dev = dev;
-	nand_chunk = nand_chunk;
-	tags = tags;
+	(void) dev;
+	(void) nand_chunk;
+	(void) tags;
 }
 
 void yaffs_handle_chunk_error(struct yaffs_dev *dev,
@@ -261,8 +218,9 @@
 		bi->chunk_error_strikes++;
 
 		if (bi->chunk_error_strikes > 3) {
-			bi->needs_retiring = 1;	/* Too many stikes, so retire this */
-			yaffs_trace(YAFFS_TRACE_ALWAYS, "yaffs: Block struck out");
+			bi->needs_retiring = 1;	/* Too many stikes, so retire */
+			yaffs_trace(YAFFS_TRACE_ALWAYS,
+				"yaffs: Block struck out");
 
 		}
 	}
@@ -277,7 +235,8 @@
 	yaffs_handle_chunk_error(dev, bi);
 
 	if (erased_ok) {
-		/* Was an actual write failure, so mark the block for retirement  */
+		/* Was an actual write failure,
+		 * so mark the block for retirement.*/
 		bi->needs_retiring = 1;
 		yaffs_trace(YAFFS_TRACE_ERROR | YAFFS_TRACE_BAD_BLOCKS,
 		  "**>> Block %d needs retiring", flash_block);
@@ -298,7 +257,8 @@
 
 static inline int yaffs_hash_fn(int n)
 {
-	n = abs(n);
+	if (n < 0)
+		n = -n;
 	return n % YAFFS_NOBJECT_BUCKETS;
 }
 
@@ -321,11 +281,11 @@
  *  Erased NAND checking functions
  */
 
-int yaffs_check_ff(u8 * buffer, int n_bytes)
+int yaffs_check_ff(u8 *buffer, int n_bytes)
 {
 	/* Horrible, slow implementation */
 	while (n_bytes--) {
-		if (*buffer != 0xFF)
+		if (*buffer != 0xff)
 			return 0;
 		buffer++;
 	}
@@ -335,7 +295,7 @@
 static int yaffs_check_chunk_erased(struct yaffs_dev *dev, int nand_chunk)
 {
 	int retval = YAFFS_OK;
-	u8 *data = yaffs_get_temp_buffer(dev, __LINE__);
+	u8 *data = yaffs_get_temp_buffer(dev);
 	struct yaffs_ext_tags tags;
 	int result;
 
@@ -346,11 +306,12 @@
 
 	if (!yaffs_check_ff(data, dev->data_bytes_per_chunk) ||
 		tags.chunk_used) {
-		yaffs_trace(YAFFS_TRACE_NANDACCESS, "Chunk %d not erased", nand_chunk);
+		yaffs_trace(YAFFS_TRACE_NANDACCESS,
+			"Chunk %d not erased", nand_chunk);
 		retval = YAFFS_FAIL;
 	}
 
-	yaffs_release_temp_buffer(dev, data, __LINE__);
+	yaffs_release_temp_buffer(dev, data);
 
 	return retval;
 
@@ -358,12 +319,12 @@
 
 static int yaffs_verify_chunk_written(struct yaffs_dev *dev,
 				      int nand_chunk,
-				      const u8 * data,
+				      const u8 *data,
 				      struct yaffs_ext_tags *tags)
 {
 	int retval = YAFFS_OK;
 	struct yaffs_ext_tags temp_tags;
-	u8 *buffer = yaffs_get_temp_buffer(dev, __LINE__);
+	u8 *buffer = yaffs_get_temp_buffer(dev);
 	int result;
 
 	result = yaffs_rd_chunk_tags_nand(dev, nand_chunk, buffer, &temp_tags);
@@ -373,7 +334,7 @@
 	    temp_tags.n_bytes != tags->n_bytes)
 		retval = YAFFS_FAIL;
 
-	yaffs_release_temp_buffer(dev, buffer, __LINE__);
+	yaffs_release_temp_buffer(dev, buffer);
 
 	return retval;
 }
@@ -388,7 +349,7 @@
 	checkpt_blocks = yaffs_calc_checkpt_blocks_required(dev);
 
 	reserved_chunks =
-	    ((reserved_blocks + checkpt_blocks) * dev->param.chunks_per_block);
+	    (reserved_blocks + checkpt_blocks) * dev->param.chunks_per_block;
 
 	return (dev->n_free_chunks > (reserved_chunks + n_chunks));
 }
@@ -396,7 +357,6 @@
 static int yaffs_find_alloc_block(struct yaffs_dev *dev)
 {
 	int i;
-
 	struct yaffs_block_info *bi;
 
 	if (dev->n_erased_blocks < 1) {
@@ -404,7 +364,7 @@
 		 * Can't get space to gc
 		 */
 		yaffs_trace(YAFFS_TRACE_ERROR,
-		  "yaffs tragedy: no more erased blocks" );
+		  "yaffs tragedy: no more erased blocks");
 
 		return -1;
 	}
@@ -453,7 +413,7 @@
 	}
 
 	if (!use_reserver && !yaffs_check_alloc_available(dev, 1)) {
-		/* Not enough space to allocate unless we're allowed to use the reserve. */
+		/* No space unless we're allowed to use the reserve. */
 		return -1;
 	}
 
@@ -486,7 +446,8 @@
 		return ret_val;
 	}
 
-	yaffs_trace(YAFFS_TRACE_ERROR, "!!!!!!!!! Allocator out !!!!!!!!!!!!!!!!!" );
+	yaffs_trace(YAFFS_TRACE_ERROR,
+		"!!!!!!!!! Allocator out !!!!!!!!!!!!!!!!!");
 
 	return -1;
 }
@@ -510,9 +471,10 @@
  */
 void yaffs_skip_rest_of_block(struct yaffs_dev *dev)
 {
+	struct yaffs_block_info *bi;
+
 	if (dev->alloc_block > 0) {
-		struct yaffs_block_info *bi =
-		    yaffs_get_block_info(dev, dev->alloc_block);
+		bi = yaffs_get_block_info(dev, dev->alloc_block);
 		if (bi->block_state == YAFFS_BLOCK_STATE_ALLOCATING) {
 			bi->block_state = YAFFS_BLOCK_STATE_FULL;
 			dev->alloc_block = -1;
@@ -521,7 +483,7 @@
 }
 
 static int yaffs_write_new_chunk(struct yaffs_dev *dev,
-				 const u8 * data,
+				 const u8 *data,
 				 struct yaffs_ext_tags *tags, int use_reserver)
 {
 	int attempts = 0;
@@ -560,7 +522,7 @@
 		 * lot of checks that are most likely not needed.
 		 *
 		 * Mods to the above
-		 * If an erase check fails or the write fails we skip the 
+		 * If an erase check fails or the write fails we skip the
 		 * rest of the block.
 		 */
 
@@ -614,7 +576,7 @@
 		yaffs_trace(YAFFS_TRACE_ERROR,
 			"**>> yaffs write required %d attempts",
 			attempts);
-		dev->n_retired_writes += (attempts - 1);
+		dev->n_retried_writes += (attempts - 1);
 	}
 
 	return chunk;
@@ -642,10 +604,10 @@
 			int chunk_id =
 			    flash_block * dev->param.chunks_per_block;
 
-			u8 *buffer = yaffs_get_temp_buffer(dev, __LINE__);
+			u8 *buffer = yaffs_get_temp_buffer(dev);
 
 			memset(buffer, 0xff, dev->data_bytes_per_chunk);
-			yaffs_init_tags(&tags);
+			memset(&tags, 0, sizeof(tags));
 			tags.seq_number = YAFFS_SEQUENCE_BAD_BLOCK;
 			if (dev->param.write_chunk_tags_fn(dev, chunk_id -
 							   dev->chunk_offset,
@@ -655,7 +617,7 @@
 					"yaffs: Failed to write bad block marker to block %d",
 					flash_block);
 
-			yaffs_release_temp_buffer(dev, buffer, __LINE__);
+			yaffs_release_temp_buffer(dev, buffer);
 		}
 	}
 
@@ -668,35 +630,39 @@
 
 /*---------------- Name handling functions ------------*/
 
-static u16 yaffs_calc_name_sum(const YCHAR * name)
+static u16 yaffs_calc_name_sum(const YCHAR *name)
 {
 	u16 sum = 0;
 	u16 i = 1;
 
-	const YUCHAR *bname = (const YUCHAR *)name;
-	if (bname) {
-		while ((*bname) && (i < (YAFFS_MAX_NAME_LENGTH / 2))) {
-
-			/* 0x1f mask is case insensitive */
-			sum += ((*bname) & 0x1f) * i;
-			i++;
-			bname++;
-		}
+	if (!name)
+		return 0;
+
+	while ((*name) && i < (YAFFS_MAX_NAME_LENGTH / 2)) {
+
+		/* 0x1f mask is case insensitive */
+		sum += ((*name) & 0x1f) * i;
+		i++;
+		name++;
 	}
 	return sum;
 }
 
+
 void yaffs_set_obj_name(struct yaffs_obj *obj, const YCHAR * name)
 {
-#ifndef CONFIG_YAFFS_NO_SHORT_NAMES
 	memset(obj->short_name, 0, sizeof(obj->short_name));
-	if (name && 
-	        strnlen(name, YAFFS_SHORT_NAME_LENGTH + 1) <=
-	    YAFFS_SHORT_NAME_LENGTH)
+
+	if (name && !name[0]) {
+		yaffs_fix_null_name(obj, obj->short_name,
+				YAFFS_SHORT_NAME_LENGTH);
+		name = obj->short_name;
+	} else if (name &&
+		strnlen(name, YAFFS_SHORT_NAME_LENGTH + 1) <=
+		YAFFS_SHORT_NAME_LENGTH)  {
 		strcpy(obj->short_name, name);
-	else
-		obj->short_name[0] = _Y('\0');
-#endif
+	}
+
 	obj->sum = yaffs_calc_name_sum(name);
 }
 
@@ -714,6 +680,14 @@
 #endif
 }
 
+loff_t yaffs_max_file_size(struct yaffs_dev *dev)
+{
+	if(sizeof(loff_t) < 8)
+		return YAFFS_MAX_FILE_SIZE_32;
+	else
+		return ((loff_t) YAFFS_MAX_CHUNK_ID) * dev->data_bytes_per_chunk;
+}
+
 /*-------------------- TNODES -------------------
 
  * List of spare tnodes
@@ -724,6 +698,7 @@
 struct yaffs_tnode *yaffs_get_tnode(struct yaffs_dev *dev)
 {
 	struct yaffs_tnode *tn = yaffs_alloc_raw_tnode(dev);
+
 	if (tn) {
 		memset(tn, 0, dev->tnode_size);
 		dev->n_tnodes++;
@@ -749,7 +724,7 @@
 	dev->n_tnodes = 0;
 }
 
-void yaffs_load_tnode_0(struct yaffs_dev *dev, struct yaffs_tnode *tn,
+static void yaffs_load_tnode_0(struct yaffs_dev *dev, struct yaffs_tnode *tn,
 			unsigned pos, unsigned val)
 {
 	u32 *map = (u32 *) tn;
@@ -772,9 +747,9 @@
 
 	if (dev->tnode_width > (32 - bit_in_word)) {
 		bit_in_word = (32 - bit_in_word);
-		word_in_map++;;
+		word_in_map++;
 		mask =
-		    dev->tnode_mask >> ( /*dev->tnode_width - */ bit_in_word);
+		    dev->tnode_mask >> bit_in_word;
 		map[word_in_map] &= ~mask;
 		map[word_in_map] |= (mask & (val >> bit_in_word));
 	}
@@ -799,7 +774,7 @@
 
 	if (dev->tnode_width > (32 - bit_in_word)) {
 		bit_in_word = (32 - bit_in_word);
-		word_in_map++;;
+		word_in_map++;
 		val |= (map[word_in_map] << bit_in_word);
 	}
 
@@ -826,7 +801,7 @@
 	int required_depth;
 	int level = file_struct->top_level;
 
-	dev = dev;
+	(void) dev;
 
 	/* Check sane level and chunk Id */
 	if (level < 0 || level > YAFFS_TNODES_MAX_LEVEL)
@@ -860,15 +835,16 @@
 	return tn;
 }
 
-/* AddOrFindLevel0Tnode finds the level 0 tnode if it exists, otherwise first expands the tree.
+/* add_find_tnode_0 finds the level 0 tnode if it exists,
+ * otherwise first expands the tree.
  * This happens in two steps:
  *  1. If the tree isn't tall enough, then make it taller.
  *  2. Scan down the tree towards the level 0 tnode adding tnodes if required.
  *
  * Used when modifying the tree.
  *
- *  If the tn argument is NULL, then a fresh tnode will be added otherwise the specified tn will
- *  be plugged into the ttree.
+ *  If the tn argument is NULL, then a fresh tnode will be added otherwise the
+ *  specified tn will be plugged into the ttree.
  */
 
 struct yaffs_tnode *yaffs_add_find_tnode_0(struct yaffs_dev *dev,
@@ -880,12 +856,11 @@
 	int i;
 	int l;
 	struct yaffs_tnode *tn;
-
 	u32 x;
 
 	/* Check sane level and page Id */
-	if (file_struct->top_level < 0
-	    || file_struct->top_level > YAFFS_TNODES_MAX_LEVEL)
+	if (file_struct->top_level < 0 ||
+	    file_struct->top_level > YAFFS_TNODES_MAX_LEVEL)
 		return NULL;
 
 	if (chunk_id > YAFFS_MAX_CHUNK_ID)
@@ -911,7 +886,8 @@
 				file_struct->top = tn;
 				file_struct->top_level++;
 			} else {
-				yaffs_trace(YAFFS_TRACE_ERROR, "yaffs: no more tnodes");
+				yaffs_trace(YAFFS_TRACE_ERROR,
+					"yaffs: no more tnodes");
 				return NULL;
 			}
 		}
@@ -937,11 +913,10 @@
 			} else if (l == 1) {
 				/* Looking from level 1 at level 0 */
 				if (passed_tn) {
-					/* If we already have one, then release it. */
+					/* If we already have one, release it */
 					if (tn->internal[x])
 						yaffs_free_tnode(dev,
-								 tn->
-								 internal[x]);
+							tn->internal[x]);
 					tn->internal[x] = passed_tn;
 
 				} else if (!tn->internal[x]) {
@@ -971,13 +946,14 @@
 			    int chunk_obj)
 {
 	return (tags->chunk_id == chunk_obj &&
-		tags->obj_id == obj_id && !tags->is_deleted) ? 1 : 0;
+		tags->obj_id == obj_id &&
+		!tags->is_deleted) ? 1 : 0;
 
 }
 
 static int yaffs_find_chunk_in_group(struct yaffs_dev *dev, int the_chunk,
-				     struct yaffs_ext_tags *tags, int obj_id,
-				     int inode_chunk)
+					struct yaffs_ext_tags *tags, int obj_id,
+					int inode_chunk)
 {
 	int j;
 
@@ -991,7 +967,8 @@
 			else {
 				yaffs_rd_chunk_tags_nand(dev, the_chunk, NULL,
 							 tags);
-				if (yaffs_tags_match(tags, obj_id, inode_chunk)) {
+				if (yaffs_tags_match(tags,
+							obj_id, inode_chunk)) {
 					/* found it; */
 					return the_chunk;
 				}
@@ -1010,7 +987,6 @@
 	int the_chunk = -1;
 	struct yaffs_ext_tags local_tags;
 	int ret_val = -1;
-
 	struct yaffs_dev *dev = in->my_dev;
 
 	if (!tags) {
@@ -1020,13 +996,13 @@
 
 	tn = yaffs_find_tnode_0(dev, &in->variant.file_variant, inode_chunk);
 
-	if (tn) {
-		the_chunk = yaffs_get_group_base(dev, tn, inode_chunk);
+	if (!tn)
+		return ret_val;
 
-		ret_val =
-		    yaffs_find_chunk_in_group(dev, the_chunk, tags, in->obj_id,
+	the_chunk = yaffs_get_group_base(dev, tn, inode_chunk);
+
+	ret_val = yaffs_find_chunk_in_group(dev, the_chunk, tags, in->obj_id,
 					      inode_chunk);
-	}
 	return ret_val;
 }
 
@@ -1037,7 +1013,6 @@
 	struct yaffs_tnode *tn;
 	int the_chunk = -1;
 	struct yaffs_ext_tags local_tags;
-
 	struct yaffs_dev *dev = in->my_dev;
 	int ret_val = -1;
 
@@ -1048,18 +1023,17 @@
 
 	tn = yaffs_find_tnode_0(dev, &in->variant.file_variant, inode_chunk);
 
-	if (tn) {
+	if (!tn)
+		return ret_val;
 
-		the_chunk = yaffs_get_group_base(dev, tn, inode_chunk);
+	the_chunk = yaffs_get_group_base(dev, tn, inode_chunk);
 
-		ret_val =
-		    yaffs_find_chunk_in_group(dev, the_chunk, tags, in->obj_id,
+	ret_val = yaffs_find_chunk_in_group(dev, the_chunk, tags, in->obj_id,
 					      inode_chunk);
 
-		/* Delete the entry in the filestructure (if found) */
-		if (ret_val != -1)
-			yaffs_load_tnode_0(dev, tn, inode_chunk, 0);
-	}
+	/* Delete the entry in the filestructure (if found) */
+	if (ret_val != -1)
+		yaffs_load_tnode_0(dev, tn, inode_chunk, 0);
 
 	return ret_val;
 }
@@ -1082,14 +1056,15 @@
 	unsigned existing_serial, new_serial;
 
 	if (in->variant_type != YAFFS_OBJECT_TYPE_FILE) {
-		/* Just ignore an attempt at putting a chunk into a non-file during scanning
+		/* Just ignore an attempt at putting a chunk into a non-file
+		 * during scanning.
 		 * If it is not during Scanning then something went wrong!
 		 */
 		if (!in_scan) {
 			yaffs_trace(YAFFS_TRACE_ERROR,
 				"yaffs tragedy:attempt to put data chunk into a non-file"
 				);
-			YBUG();
+			BUG();
 		}
 
 		yaffs_chunk_del(dev, nand_chunk, 1, __LINE__);
@@ -1110,23 +1085,29 @@
 
 	if (in_scan != 0) {
 		/* If we're scanning then we need to test for duplicates
-		 * NB This does not need to be efficient since it should only ever
+		 * NB This does not need to be efficient since it should only
 		 * happen when the power fails during a write, then only one
 		 * chunk should ever be affected.
 		 *
-		 * Correction for YAFFS2: This could happen quite a lot and we need to think about efficiency! TODO
-		 * Update: For backward scanning we don't need to re-read tags so this is quite cheap.
+		 * Correction for YAFFS2: This could happen quite a lot and we
+		 * need to think about efficiency! TODO
+		 * Update: For backward scanning we don't need to re-read tags
+		 * so this is quite cheap.
 		 */
 
 		if (existing_cunk > 0) {
-			/* NB Right now existing chunk will not be real chunk_id if the chunk group size > 1
-			 *    thus we have to do a FindChunkInFile to get the real chunk id.
+			/* NB Right now existing chunk will not be real
+			 * chunk_id if the chunk group size > 1
+			 * thus we have to do a FindChunkInFile to get the
+			 * real chunk id.
 			 *
-			 * We have a duplicate now we need to decide which one to use:
+			 * We have a duplicate now we need to decide which
+			 * one to use:
 			 *
-			 * Backwards scanning YAFFS2: The old one is what we use, dump the new one.
-			 * Forward scanning YAFFS2: The new one is what we use, dump the old one.
-			 * YAFFS1: Get both sets of tags and compare serial numbers.
+			 * Backwards scanning YAFFS2: The old one is what
+			 * we use, dump the new one.
+			 * YAFFS1: Get both sets of tags and compare serial
+			 * numbers.
 			 */
 
 			if (in_scan > 0) {
@@ -1150,8 +1131,8 @@
 
 			}
 
-			/* NB The deleted flags should be false, otherwise the chunks will
-			 * not be loaded during a scan
+			/* NB The deleted flags should be false, otherwise
+			 * the chunks will not be loaded during a scan
 			 */
 
 			if (in_scan > 0) {
@@ -1164,14 +1145,16 @@
 			     ((existing_serial + 1) & 3) == new_serial)) {
 				/* Forward scanning.
 				 * Use new
-				 * Delete the old one and drop through to update the tnode
+				 * Delete the old one and drop through to
+				 * update the tnode
 				 */
 				yaffs_chunk_del(dev, existing_cunk, 1,
 						__LINE__);
 			} else {
-				/* Backward scanning or we want to use the existing one
-				 * Use existing.
-				 * Delete the new one and return early so that the tnode isn't changed
+				/* Backward scanning or we want to use the
+				 * existing one
+				 * Delete the new one and return early so that
+				 * the tnode isn't changed
 				 */
 				yaffs_chunk_del(dev, nand_chunk, 1, __LINE__);
 				return YAFFS_OK;
@@ -1204,10 +1187,12 @@
 	}
 }
 
-/* SoftDeleteWorker scans backwards through the tnode tree and soft deletes all the chunks in the file.
- * All soft deleting does is increment the block's softdelete count and pulls the chunk out
- * of the tnode.
- * Thus, essentially this is the same as DeleteWorker except that the chunks are soft deleted.
+/* SoftDeleteWorker scans backwards through the tnode tree and soft deletes all
+ * the chunks in the file.
+ * All soft deleting does is increment the block's softdelete count and pulls
+ * the chunk out of the tnode.
+ * Thus, essentially this is the same as DeleteWorker except that the chunks
+ * are soft deleted.
  */
 
 static int yaffs_soft_del_worker(struct yaffs_obj *in, struct yaffs_tnode *tn,
@@ -1218,54 +1203,42 @@
 	int all_done = 1;
 	struct yaffs_dev *dev = in->my_dev;
 
-	if (tn) {
-		if (level > 0) {
-
-			for (i = YAFFS_NTNODES_INTERNAL - 1; all_done && i >= 0;
-			     i--) {
-				if (tn->internal[i]) {
-					all_done =
-					    yaffs_soft_del_worker(in,
-								  tn->internal
-								  [i],
-								  level - 1,
-								  (chunk_offset
-								   <<
-								   YAFFS_TNODES_INTERNAL_BITS)
-								  + i);
-					if (all_done) {
-						yaffs_free_tnode(dev,
-								 tn->internal
-								 [i]);
-						tn->internal[i] = NULL;
-					} else {
-						/* Hoosterman... how could this happen? */
-					}
-				}
-			}
-			return (all_done) ? 1 : 0;
-		} else if (level == 0) {
+	if (!tn)
+		return 1;
 
-			for (i = YAFFS_NTNODES_LEVEL0 - 1; i >= 0; i--) {
-				the_chunk = yaffs_get_group_base(dev, tn, i);
-				if (the_chunk) {
-					/* Note this does not find the real chunk, only the chunk group.
-					 * We make an assumption that a chunk group is not larger than
-					 * a block.
-					 */
-					yaffs_soft_del_chunk(dev, the_chunk);
-					yaffs_load_tnode_0(dev, tn, i, 0);
+	if (level > 0) {
+		for (i = YAFFS_NTNODES_INTERNAL - 1;
+			all_done && i >= 0;
+			i--) {
+			if (tn->internal[i]) {
+				all_done =
+				    yaffs_soft_del_worker(in,
+					tn->internal[i],
+					level - 1,
+					(chunk_offset <<
+					YAFFS_TNODES_INTERNAL_BITS)
+					+ i);
+				if (all_done) {
+					yaffs_free_tnode(dev,
+						tn->internal[i]);
+					tn->internal[i] = NULL;
+				} else {
+					/* Can this happen? */
 				}
-
 			}
-			return 1;
-
 		}
-
+		return (all_done) ? 1 : 0;
 	}
 
+	/* level 0 */
+	 for (i = YAFFS_NTNODES_LEVEL0 - 1; i >= 0; i--) {
+		the_chunk = yaffs_get_group_base(dev, tn, i);
+		if (the_chunk) {
+			yaffs_soft_del_chunk(dev, the_chunk);
+			yaffs_load_tnode_0(dev, tn, i, 0);
+		}
+	}
 	return 1;
-
 }
 
 static void yaffs_remove_obj_from_dir(struct yaffs_obj *obj)
@@ -1293,19 +1266,19 @@
 		yaffs_trace(YAFFS_TRACE_ALWAYS,
 			"tragedy: Trying to add an object to a null pointer directory"
 			);
-		YBUG();
+		BUG();
 		return;
 	}
 	if (directory->variant_type != YAFFS_OBJECT_TYPE_DIRECTORY) {
 		yaffs_trace(YAFFS_TRACE_ALWAYS,
 			"tragedy: Trying to add an object to a non-directory"
 			);
-		YBUG();
+		BUG();
 	}
 
 	if (obj->siblings.prev == NULL) {
 		/* Not initialised */
-		YBUG();
+		BUG();
 	}
 
 	yaffs_verify_dir(directory);
@@ -1329,11 +1302,10 @@
 
 static int yaffs_change_obj_name(struct yaffs_obj *obj,
 				 struct yaffs_obj *new_dir,
-				 const YCHAR * new_name, int force, int shadows)
+				 const YCHAR *new_name, int force, int shadows)
 {
 	int unlink_op;
 	int del_op;
-
 	struct yaffs_obj *existing_target;
 
 	if (new_dir == NULL)
@@ -1343,58 +1315,48 @@
 		yaffs_trace(YAFFS_TRACE_ALWAYS,
 			"tragedy: yaffs_change_obj_name: new_dir is not a directory"
 			);
-		YBUG();
+		BUG();
 	}
 
-	/* TODO: Do we need this different handling for YAFFS2 and YAFFS1?? */
-	if (obj->my_dev->param.is_yaffs2)
-		unlink_op = (new_dir == obj->my_dev->unlinked_dir);
-	else
-		unlink_op = (new_dir == obj->my_dev->unlinked_dir
-			     && obj->variant_type == YAFFS_OBJECT_TYPE_FILE);
-
+	unlink_op = (new_dir == obj->my_dev->unlinked_dir);
 	del_op = (new_dir == obj->my_dev->del_dir);
 
 	existing_target = yaffs_find_by_name(new_dir, new_name);
 
 	/* If the object is a file going into the unlinked directory,
-	 *   then it is OK to just stuff it in since duplicate names are allowed.
-	 *   else only proceed if the new name does not exist and if we're putting
+	 *   then it is OK to just stuff it in since duplicate names are OK.
+	 *   else only proceed if the new name does not exist and we're putting
 	 *   it into a directory.
 	 */
-	if ((unlink_op ||
-	     del_op ||
-	     force ||
-	     (shadows > 0) ||
-	     !existing_target) &&
-	    new_dir->variant_type == YAFFS_OBJECT_TYPE_DIRECTORY) {
-		yaffs_set_obj_name(obj, new_name);
-		obj->dirty = 1;
-
-		yaffs_add_obj_to_dir(new_dir, obj);
-
-		if (unlink_op)
-			obj->unlinked = 1;
-
-		/* If it is a deletion then we mark it as a shrink for gc purposes. */
-		if (yaffs_update_oh(obj, new_name, 0, del_op, shadows, NULL) >=
-		    0)
-			return YAFFS_OK;
-	}
+	if (!(unlink_op || del_op || force ||
+	      shadows > 0 || !existing_target) ||
+	      new_dir->variant_type != YAFFS_OBJECT_TYPE_DIRECTORY)
+		return YAFFS_FAIL;
+
+	yaffs_set_obj_name(obj, new_name);
+	obj->dirty = 1;
+	yaffs_add_obj_to_dir(new_dir, obj);
+
+	if (unlink_op)
+		obj->unlinked = 1;
+
+	/* If it is a deletion then we mark it as a shrink for gc  */
+	if (yaffs_update_oh(obj, new_name, 0, del_op, shadows, NULL) >= 0)
+		return YAFFS_OK;
 
 	return YAFFS_FAIL;
 }
 
-/*------------------------ Short Operations Cache ----------------------------------------
+/*------------------------ Short Operations Cache ------------------------------
  *   In many situations where there is no high level buffering  a lot of
  *   reads might be short sequential reads, and a lot of writes may be short
  *   sequential writes. eg. scanning/writing a jpeg file.
  *   In these cases, a short read/write cache can provide a huge perfomance
  *   benefit with dumb-as-a-rock code.
- *   In Linux, the page cache provides read buffering and the short op cache 
+ *   In Linux, the page cache provides read buffering and the short op cache
  *   provides write buffering.
  *
- *   There are a limited number (~10) of cache chunks per device so that we don't
+ *   There are a small number (~10) of cache chunks per device so that we don't
  *   need a very intelligent search.
  */
 
@@ -1423,44 +1385,39 @@
 	int chunk_written = 0;
 	int n_caches = obj->my_dev->param.n_caches;
 
-	if (n_caches > 0) {
-		do {
-			cache = NULL;
-
-			/* Find the dirty cache for this object with the lowest chunk id. */
-			for (i = 0; i < n_caches; i++) {
-				if (dev->cache[i].object == obj &&
-				    dev->cache[i].dirty) {
-					if (!cache
-					    || dev->cache[i].chunk_id <
-					    lowest) {
-						cache = &dev->cache[i];
-						lowest = cache->chunk_id;
-					}
-				}
-			}
-
-			if (cache && !cache->locked) {
-				/* Write it out and free it up */
+	if (n_caches < 1)
+		return;
+	do {
+		cache = NULL;
 
-				chunk_written =
-				    yaffs_wr_data_obj(cache->object,
-						      cache->chunk_id,
-						      cache->data,
-						      cache->n_bytes, 1);
-				cache->dirty = 0;
-				cache->object = NULL;
+		/* Find the lowest dirty chunk for this object */
+		for (i = 0; i < n_caches; i++) {
+			if (dev->cache[i].object == obj &&
+			    dev->cache[i].dirty) {
+				if (!cache ||
+				    dev->cache[i].chunk_id < lowest) {
+					cache = &dev->cache[i];
+					lowest = cache->chunk_id;
+				}
 			}
+		}
 
-		} while (cache && chunk_written > 0);
-
-		if (cache)
-			/* Hoosterman, disk full while writing cache out. */
-			yaffs_trace(YAFFS_TRACE_ERROR,
-				"yaffs tragedy: no space during cache write");
-
-	}
+		if (cache && !cache->locked) {
+			/* Write it out and free it up */
+			chunk_written =
+			    yaffs_wr_data_obj(cache->object,
+					      cache->chunk_id,
+					      cache->data,
+					      cache->n_bytes, 1);
+			cache->dirty = 0;
+			cache->object = NULL;
+		}
+	} while (cache && chunk_written > 0);
 
+	if (cache)
+		/* Hoosterman, disk full while writing cache out. */
+		yaffs_trace(YAFFS_TRACE_ERROR,
+			"yaffs tragedy: no space during cache write");
 }
 
 /*yaffs_flush_whole_cache(dev)
@@ -1482,11 +1439,9 @@
 		for (i = 0; i < n_caches && !obj; i++) {
 			if (dev->cache[i].object && dev->cache[i].dirty)
 				obj = dev->cache[i].object;
-
 		}
 		if (obj)
 			yaffs_flush_file_cache(obj);
-
 	} while (obj);
 
 }
@@ -1506,7 +1461,6 @@
 				return &dev->cache[i];
 		}
 	}
-
 	return NULL;
 }
 
@@ -1518,48 +1472,46 @@
 	int i;
 	int pushout;
 
-	if (dev->param.n_caches > 0) {
-		/* Try find a non-dirty one... */
+	if (dev->param.n_caches < 1)
+		return NULL;
 
-		cache = yaffs_grab_chunk_worker(dev);
+	/* Try find a non-dirty one... */
 
-		if (!cache) {
-			/* They were all dirty, find the last recently used object and flush
-			 * its cache, then  find again.
-			 * NB what's here is not very accurate, we actually flush the object
-			 * the last recently used page.
-			 */
+	cache = yaffs_grab_chunk_worker(dev);
 
-			/* With locking we can't assume we can use entry zero */
-
-			the_obj = NULL;
-			usage = -1;
-			cache = NULL;
-			pushout = -1;
+	if (!cache) {
+		/* They were all dirty, find the LRU object and flush
+		 * its cache, then  find again.
+		 * NB what's here is not very accurate,
+		 * we actually flush the object with the LRU chunk.
+		 */
 
-			for (i = 0; i < dev->param.n_caches; i++) {
-				if (dev->cache[i].object &&
-				    !dev->cache[i].locked &&
-				    (dev->cache[i].last_use < usage
-				     || !cache)) {
-					usage = dev->cache[i].last_use;
-					the_obj = dev->cache[i].object;
-					cache = &dev->cache[i];
-					pushout = i;
-				}
-			}
+		/* With locking we can't assume we can use entry zero,
+		 * Set the_obj to a valid pointer for Coverity. */
+		the_obj = dev->cache[0].object;
+		usage = -1;
+		cache = NULL;
+		pushout = -1;
 
-			if (!cache || cache->dirty) {
-				/* Flush and try again */
-				yaffs_flush_file_cache(the_obj);
-				cache = yaffs_grab_chunk_worker(dev);
+		for (i = 0; i < dev->param.n_caches; i++) {
+			if (dev->cache[i].object &&
+			    !dev->cache[i].locked &&
+			    (dev->cache[i].last_use < usage ||
+			    !cache)) {
+				usage = dev->cache[i].last_use;
+				the_obj = dev->cache[i].object;
+				cache = &dev->cache[i];
+				pushout = i;
 			}
+		}
 
+		if (!cache || cache->dirty) {
+			/* Flush and try again */
+			yaffs_flush_file_cache(the_obj);
+			cache = yaffs_grab_chunk_worker(dev);
 		}
-		return cache;
-	} else {
-		return NULL;
-        }
+	}
+	return cache;
 }
 
 /* Find a cached chunk */
@@ -1568,14 +1520,16 @@
 {
 	struct yaffs_dev *dev = obj->my_dev;
 	int i;
-	if (dev->param.n_caches > 0) {
-		for (i = 0; i < dev->param.n_caches; i++) {
-			if (dev->cache[i].object == obj &&
-			    dev->cache[i].chunk_id == chunk_id) {
-				dev->cache_hits++;
 
-				return &dev->cache[i];
-			}
+	if (dev->param.n_caches < 1)
+		return NULL;
+
+	for (i = 0; i < dev->param.n_caches; i++) {
+		if (dev->cache[i].object == obj &&
+		    dev->cache[i].chunk_id == chunk_id) {
+			dev->cache_hits++;
+
+			return &dev->cache[i];
 		}
 	}
 	return NULL;
@@ -1585,24 +1539,24 @@
 static void yaffs_use_cache(struct yaffs_dev *dev, struct yaffs_cache *cache,
 			    int is_write)
 {
+	int i;
 
-	if (dev->param.n_caches > 0) {
-		if (dev->cache_last_use < 0 || dev->cache_last_use > 100000000) {
-			/* Reset the cache usages */
-			int i;
-			for (i = 1; i < dev->param.n_caches; i++)
-				dev->cache[i].last_use = 0;
-
-			dev->cache_last_use = 0;
-		}
-
-		dev->cache_last_use++;
+	if (dev->param.n_caches < 1)
+		return;
 
-		cache->last_use = dev->cache_last_use;
+	if (dev->cache_last_use < 0 ||
+		dev->cache_last_use > 100000000) {
+		/* Reset the cache usages */
+		for (i = 1; i < dev->param.n_caches; i++)
+			dev->cache[i].last_use = 0;
 
-		if (is_write)
-			cache->dirty = 1;
+		dev->cache_last_use = 0;
 	}
+	dev->cache_last_use++;
+	cache->last_use = dev->cache_last_use;
+
+	if (is_write)
+		cache->dirty = 1;
 }
 
 /* Invalidate a single cache page.
@@ -1611,9 +1565,10 @@
  */
 static void yaffs_invalidate_chunk_cache(struct yaffs_obj *object, int chunk_id)
 {
+	struct yaffs_cache *cache;
+
 	if (object->my_dev->param.n_caches > 0) {
-		struct yaffs_cache *cache =
-		    yaffs_find_chunk_cache(object, chunk_id);
+		cache = yaffs_find_chunk_cache(object, chunk_id);
 
 		if (cache)
 			cache->object = NULL;
@@ -1653,17 +1608,19 @@
 /*  FreeObject frees up a Object and puts it back on the free list */
 static void yaffs_free_obj(struct yaffs_obj *obj)
 {
-	struct yaffs_dev *dev = obj->my_dev;
+	struct yaffs_dev *dev;
 
+	if (!obj) {
+		BUG();
+		return;
+	}
+	dev = obj->my_dev;
 	yaffs_trace(YAFFS_TRACE_OS, "FreeObject %p inode %p",
 		obj, obj->my_inode);
-
-	if (!obj)
-		YBUG();
 	if (obj->parent)
-		YBUG();
+		BUG();
 	if (!list_empty(&obj->siblings))
-		YBUG();
+		BUG();
 
 	if (obj->my_inode) {
 		/* We're still hooked up to a cached inode.
@@ -1688,15 +1645,13 @@
 
 static int yaffs_generic_obj_del(struct yaffs_obj *in)
 {
-
-	/* First off, invalidate the file's data in the cache, without flushing. */
+	/* Iinvalidate the file's data in the cache, without flushing. */
 	yaffs_invalidate_whole_cache(in);
 
-	if (in->my_dev->param.is_yaffs2 && (in->parent != in->my_dev->del_dir)) {
-		/* Move to the unlinked directory so we have a record that it was deleted. */
+	if (in->my_dev->param.is_yaffs2 && in->parent != in->my_dev->del_dir) {
+		/* Move to unlinked directory so we have a deletion record */
 		yaffs_change_obj_name(in, in->my_dev->del_dir, _Y("deleted"), 0,
 				      0);
-
 	}
 
 	yaffs_remove_obj_from_dir(in);
@@ -1710,25 +1665,26 @@
 
 static void yaffs_soft_del_file(struct yaffs_obj *obj)
 {
-	if (obj->deleted &&
-	    obj->variant_type == YAFFS_OBJECT_TYPE_FILE && !obj->soft_del) {
-		if (obj->n_data_chunks <= 0) {
-			/* Empty file with no duplicate object headers,
-			 * just delete it immediately */
-			yaffs_free_tnode(obj->my_dev,
-					 obj->variant.file_variant.top);
-			obj->variant.file_variant.top = NULL;
-			yaffs_trace(YAFFS_TRACE_TRACING,
-				"yaffs: Deleting empty file %d",
-				obj->obj_id);
-			yaffs_generic_obj_del(obj);
-		} else {
-			yaffs_soft_del_worker(obj,
-					      obj->variant.file_variant.top,
-					      obj->variant.
-					      file_variant.top_level, 0);
-			obj->soft_del = 1;
-		}
+	if (!obj->deleted ||
+	    obj->variant_type != YAFFS_OBJECT_TYPE_FILE ||
+	    obj->soft_del)
+		return;
+
+	if (obj->n_data_chunks <= 0) {
+		/* Empty file with no duplicate object headers,
+		 * just delete it immediately */
+		yaffs_free_tnode(obj->my_dev, obj->variant.file_variant.top);
+		obj->variant.file_variant.top = NULL;
+		yaffs_trace(YAFFS_TRACE_TRACING,
+			"yaffs: Deleting empty file %d",
+			obj->obj_id);
+		yaffs_generic_obj_del(obj);
+	} else {
+		yaffs_soft_del_worker(obj,
+				      obj->variant.file_variant.top,
+				      obj->variant.
+				      file_variant.top_level, 0);
+		obj->soft_del = 1;
 	}
 }
 
@@ -1754,44 +1710,40 @@
 	int i;
 	int has_data;
 
-	if (tn) {
-		has_data = 0;
+	if (!tn)
+		return tn;
 
-		if (level > 0) {
-			for (i = 0; i < YAFFS_NTNODES_INTERNAL; i++) {
-				if (tn->internal[i]) {
-					tn->internal[i] =
-					    yaffs_prune_worker(dev,
-							       tn->internal[i],
-							       level - 1,
-							       (i ==
-								0) ? del0 : 1);
-				}
+	has_data = 0;
 
-				if (tn->internal[i])
-					has_data++;
+	if (level > 0) {
+		for (i = 0; i < YAFFS_NTNODES_INTERNAL; i++) {
+			if (tn->internal[i]) {
+				tn->internal[i] =
+				    yaffs_prune_worker(dev,
+						tn->internal[i],
+						level - 1,
+						(i == 0) ? del0 : 1);
 			}
-		} else {
-			int tnode_size_u32 = dev->tnode_size / sizeof(u32);
-			u32 *map = (u32 *) tn;
 
-			for (i = 0; !has_data && i < tnode_size_u32; i++) {
-				if (map[i])
-					has_data++;
-			}
+			if (tn->internal[i])
+				has_data++;
 		}
+	} else {
+		int tnode_size_u32 = dev->tnode_size / sizeof(u32);
+		u32 *map = (u32 *) tn;
 
-		if (has_data == 0 && del0) {
-			/* Free and return NULL */
-
-			yaffs_free_tnode(dev, tn);
-			tn = NULL;
+		for (i = 0; !has_data && i < tnode_size_u32; i++) {
+			if (map[i])
+				has_data++;
 		}
-
 	}
 
+	if (has_data == 0 && del0) {
+		/* Free and return NULL */
+		yaffs_free_tnode(dev, tn);
+		tn = NULL;
+	}
 	return tn;
-
 }
 
 static int yaffs_prune_tree(struct yaffs_dev *dev,
@@ -1802,34 +1754,34 @@
 	int done = 0;
 	struct yaffs_tnode *tn;
 
-	if (file_struct->top_level > 0) {
-		file_struct->top =
-		    yaffs_prune_worker(dev, file_struct->top,
-				       file_struct->top_level, 0);
-
-		/* Now we have a tree with all the non-zero branches NULL but the height
-		 * is the same as it was.
-		 * Let's see if we can trim internal tnodes to shorten the tree.
-		 * We can do this if only the 0th element in the tnode is in use
-		 * (ie all the non-zero are NULL)
-		 */
+	if (file_struct->top_level < 1)
+		return YAFFS_OK;
 
-		while (file_struct->top_level && !done) {
-			tn = file_struct->top;
+	file_struct->top =
+	   yaffs_prune_worker(dev, file_struct->top, file_struct->top_level, 0);
 
-			has_data = 0;
-			for (i = 1; i < YAFFS_NTNODES_INTERNAL; i++) {
-				if (tn->internal[i])
-					has_data++;
-			}
+	/* Now we have a tree with all the non-zero branches NULL but
+	 * the height is the same as it was.
+	 * Let's see if we can trim internal tnodes to shorten the tree.
+	 * We can do this if only the 0th element in the tnode is in use
+	 * (ie all the non-zero are NULL)
+	 */
 
-			if (!has_data) {
-				file_struct->top = tn->internal[0];
-				file_struct->top_level--;
-				yaffs_free_tnode(dev, tn);
-			} else {
-				done = 1;
-			}
+	while (file_struct->top_level && !done) {
+		tn = file_struct->top;
+
+		has_data = 0;
+		for (i = 1; i < YAFFS_NTNODES_INTERNAL; i++) {
+			if (tn->internal[i])
+				has_data++;
+		}
+
+		if (!has_data) {
+			file_struct->top = tn->internal[0];
+			file_struct->top_level--;
+			yaffs_free_tnode(dev, tn);
+		} else {
+			done = 1;
 		}
 	}
 
@@ -1838,43 +1790,44 @@
 
 /*-------------------- End of File Structure functions.-------------------*/
 
-/* AllocateEmptyObject gets us a clean Object. Tries to make allocate more if we run out */
+/* alloc_empty_obj gets us a clean Object.*/
 static struct yaffs_obj *yaffs_alloc_empty_obj(struct yaffs_dev *dev)
 {
 	struct yaffs_obj *obj = yaffs_alloc_raw_obj(dev);
 
-	if (obj) {
-		dev->n_obj++;
+	if (!obj)
+		return obj;
 
-		/* Now sweeten it up... */
+	dev->n_obj++;
 
-		memset(obj, 0, sizeof(struct yaffs_obj));
-		obj->being_created = 1;
+	/* Now sweeten it up... */
 
-		obj->my_dev = dev;
-		obj->hdr_chunk = 0;
-		obj->variant_type = YAFFS_OBJECT_TYPE_UNKNOWN;
-		INIT_LIST_HEAD(&(obj->hard_links));
-		INIT_LIST_HEAD(&(obj->hash_link));
-		INIT_LIST_HEAD(&obj->siblings);
-
-		/* Now make the directory sane */
-		if (dev->root_dir) {
-			obj->parent = dev->root_dir;
-			list_add(&(obj->siblings),
-				 &dev->root_dir->variant.dir_variant.children);
-		}
-
-		/* Add it to the lost and found directory.
-		 * NB Can't put root or lost-n-found in lost-n-found so
-		 * check if lost-n-found exists first
-		 */
-		if (dev->lost_n_found)
-			yaffs_add_obj_to_dir(dev->lost_n_found, obj);
+	memset(obj, 0, sizeof(struct yaffs_obj));
+	obj->being_created = 1;
 
-		obj->being_created = 0;
+	obj->my_dev = dev;
+	obj->hdr_chunk = 0;
+	obj->variant_type = YAFFS_OBJECT_TYPE_UNKNOWN;
+	INIT_LIST_HEAD(&(obj->hard_links));
+	INIT_LIST_HEAD(&(obj->hash_link));
+	INIT_LIST_HEAD(&obj->siblings);
+
+	/* Now make the directory sane */
+	if (dev->root_dir) {
+		obj->parent = dev->root_dir;
+		list_add(&(obj->siblings),
+			 &dev->root_dir->variant.dir_variant.children);
 	}
 
+	/* Add it to the lost and found directory.
+	 * NB Can't put root or lost-n-found in lost-n-found so
+	 * check if lost-n-found exists first
+	 */
+	if (dev->lost_n_found)
+		yaffs_add_obj_to_dir(dev->lost_n_found, obj);
+
+	obj->being_created = 0;
+
 	dev->checkpoint_blocks_required = 0;	/* force recalculation */
 
 	return obj;
@@ -1897,7 +1850,6 @@
 			lowest = dev->obj_bucket[dev->bucket_finder].count;
 			l = dev->bucket_finder;
 		}
-
 	}
 
 	return l;
@@ -1906,17 +1858,13 @@
 static int yaffs_new_obj_id(struct yaffs_dev *dev)
 {
 	int bucket = yaffs_find_nice_bucket(dev);
-
-	/* Now find an object value that has not already been taken
-	 * by scanning the list.
-	 */
-
 	int found = 0;
 	struct list_head *i;
-
 	u32 n = (u32) bucket;
 
-	/* yaffs_check_obj_hash_sane();  */
+	/* Now find an object value that has not already been taken
+	 * by scanning the list.
+	 */
 
 	while (!found) {
 		found = 1;
@@ -1931,7 +1879,6 @@
 			}
 		}
 	}
-
 	return n;
 }
 
@@ -1952,23 +1899,19 @@
 
 	list_for_each(i, &dev->obj_bucket[bucket].list) {
 		/* Look if it is in the list */
-		if (i) {
-			in = list_entry(i, struct yaffs_obj, hash_link);
-			if (in->obj_id == number) {
-
-				/* Don't tell the VFS about this one if it is defered free */
-				if (in->defered_free)
-					return NULL;
-
-				return in;
-			}
+		in = list_entry(i, struct yaffs_obj, hash_link);
+		if (in->obj_id == number) {
+			/* Don't show if it is defered free */
+			if (in->defered_free)
+				return NULL;
+			return in;
 		}
 	}
 
 	return NULL;
 }
 
-struct yaffs_obj *yaffs_new_obj(struct yaffs_dev *dev, int number,
+static struct yaffs_obj *yaffs_new_obj(struct yaffs_dev *dev, int number,
 				enum yaffs_obj_type type)
 {
 	struct yaffs_obj *the_obj = NULL;
@@ -1990,38 +1933,36 @@
 		return NULL;
 	}
 
-	if (the_obj) {
-		the_obj->fake = 0;
-		the_obj->rename_allowed = 1;
-		the_obj->unlink_allowed = 1;
-		the_obj->obj_id = number;
-		yaffs_hash_obj(the_obj);
-		the_obj->variant_type = type;
-		yaffs_load_current_time(the_obj, 1, 1);
+	the_obj->fake = 0;
+	the_obj->rename_allowed = 1;
+	the_obj->unlink_allowed = 1;
+	the_obj->obj_id = number;
+	yaffs_hash_obj(the_obj);
+	the_obj->variant_type = type;
+	yaffs_load_current_time(the_obj, 1, 1);
 
-		switch (type) {
-		case YAFFS_OBJECT_TYPE_FILE:
-			the_obj->variant.file_variant.file_size = 0;
-			the_obj->variant.file_variant.scanned_size = 0;
-			the_obj->variant.file_variant.shrink_size = ~0;	/* max */
-			the_obj->variant.file_variant.top_level = 0;
-			the_obj->variant.file_variant.top = tn;
-			break;
-		case YAFFS_OBJECT_TYPE_DIRECTORY:
-			INIT_LIST_HEAD(&the_obj->variant.dir_variant.children);
-			INIT_LIST_HEAD(&the_obj->variant.dir_variant.dirty);
-			break;
-		case YAFFS_OBJECT_TYPE_SYMLINK:
-		case YAFFS_OBJECT_TYPE_HARDLINK:
-		case YAFFS_OBJECT_TYPE_SPECIAL:
-			/* No action required */
-			break;
-		case YAFFS_OBJECT_TYPE_UNKNOWN:
-			/* todo this should not happen */
-			break;
-		}
+	switch (type) {
+	case YAFFS_OBJECT_TYPE_FILE:
+		the_obj->variant.file_variant.file_size = 0;
+		the_obj->variant.file_variant.scanned_size = 0;
+		the_obj->variant.file_variant.shrink_size =
+						yaffs_max_file_size(dev);
+		the_obj->variant.file_variant.top_level = 0;
+		the_obj->variant.file_variant.top = tn;
+		break;
+	case YAFFS_OBJECT_TYPE_DIRECTORY:
+		INIT_LIST_HEAD(&the_obj->variant.dir_variant.children);
+		INIT_LIST_HEAD(&the_obj->variant.dir_variant.dirty);
+		break;
+	case YAFFS_OBJECT_TYPE_SYMLINK:
+	case YAFFS_OBJECT_TYPE_HARDLINK:
+	case YAFFS_OBJECT_TYPE_SPECIAL:
+		/* No action required */
+		break;
+	case YAFFS_OBJECT_TYPE_UNKNOWN:
+		/* todo this should not happen */
+		break;
 	}
-
 	return the_obj;
 }
 
@@ -2031,17 +1972,18 @@
 
 	struct yaffs_obj *obj =
 	    yaffs_new_obj(dev, number, YAFFS_OBJECT_TYPE_DIRECTORY);
-	if (obj) {
-		obj->fake = 1;	/* it is fake so it might have no NAND presence... */
-		obj->rename_allowed = 0;	/* ... and we're not allowed to rename it... */
-		obj->unlink_allowed = 0;	/* ... or unlink it */
-		obj->deleted = 0;
-		obj->unlinked = 0;
-		obj->yst_mode = mode;
-		obj->my_dev = dev;
-		obj->hdr_chunk = 0;	/* Not a valid chunk. */
-	}
 
+	if (!obj)
+		return NULL;
+
+	obj->fake = 1;	/* it is fake so it might not use NAND */
+	obj->rename_allowed = 0;
+	obj->unlink_allowed = 0;
+	obj->deleted = 0;
+	obj->unlinked = 0;
+	obj->yst_mode = mode;
+	obj->my_dev = dev;
+	obj->hdr_chunk = 0;	/* Not a valid chunk. */
 	return obj;
 
 }
@@ -2053,7 +1995,6 @@
 
 	dev->n_obj = 0;
 	dev->n_tnodes = 0;
-
 	yaffs_init_raw_tnodes_and_objs(dev);
 
 	for (i = 0; i < YAFFS_NOBJECT_BUCKETS; i++) {
@@ -2078,7 +2019,7 @@
 
 }
 
-YCHAR *yaffs_clone_str(const YCHAR * str)
+YCHAR *yaffs_clone_str(const YCHAR *str)
 {
 	YCHAR *new_str = NULL;
 	int len;
@@ -2114,6 +2055,7 @@
 static void yaffs_update_parent(struct yaffs_obj *obj)
 {
 	struct yaffs_dev *dev;
+
 	if (!obj)
 		return;
 	dev = obj->my_dev;
@@ -2131,7 +2073,7 @@
 
 	} else {
 		yaffs_update_oh(obj, NULL, 0, 0, 0, NULL);
-        }
+	}
 }
 
 void yaffs_update_dirty_dirs(struct yaffs_dev *dev)
@@ -2168,19 +2110,19 @@
 
 static struct yaffs_obj *yaffs_create_obj(enum yaffs_obj_type type,
 					  struct yaffs_obj *parent,
-					  const YCHAR * name,
+					  const YCHAR *name,
 					  u32 mode,
 					  u32 uid,
 					  u32 gid,
 					  struct yaffs_obj *equiv_obj,
-					  const YCHAR * alias_str, u32 rdev)
+					  const YCHAR *alias_str, u32 rdev)
 {
 	struct yaffs_obj *in;
 	YCHAR *str = NULL;
-
 	struct yaffs_dev *dev = parent->my_dev;
 
-	/* Check if the entry exists. If it does then fail the call since we don't want a dup. */
+	/* Check if the entry exists.
+	 * If it does then fail the call since we don't want a dup. */
 	if (yaffs_find_by_name(parent, name))
 		return NULL;
 
@@ -2193,68 +2135,65 @@
 	in = yaffs_new_obj(dev, -1, type);
 
 	if (!in) {
-		if (str)
-			kfree(str);
+		kfree(str);
 		return NULL;
 	}
 
-	if (in) {
-		in->hdr_chunk = 0;
-		in->valid = 1;
-		in->variant_type = type;
+	in->hdr_chunk = 0;
+	in->valid = 1;
+	in->variant_type = type;
 
-		in->yst_mode = mode;
+	in->yst_mode = mode;
 
-		yaffs_attribs_init(in, gid, uid, rdev);
+	yaffs_attribs_init(in, gid, uid, rdev);
 
-		in->n_data_chunks = 0;
+	in->n_data_chunks = 0;
 
-		yaffs_set_obj_name(in, name);
-		in->dirty = 1;
+	yaffs_set_obj_name(in, name);
+	in->dirty = 1;
 
-		yaffs_add_obj_to_dir(parent, in);
+	yaffs_add_obj_to_dir(parent, in);
 
-		in->my_dev = parent->my_dev;
+	in->my_dev = parent->my_dev;
 
-		switch (type) {
-		case YAFFS_OBJECT_TYPE_SYMLINK:
-			in->variant.symlink_variant.alias = str;
-			break;
-		case YAFFS_OBJECT_TYPE_HARDLINK:
-			in->variant.hardlink_variant.equiv_obj = equiv_obj;
-			in->variant.hardlink_variant.equiv_id =
-			    equiv_obj->obj_id;
-			list_add(&in->hard_links, &equiv_obj->hard_links);
-			break;
-		case YAFFS_OBJECT_TYPE_FILE:
-		case YAFFS_OBJECT_TYPE_DIRECTORY:
-		case YAFFS_OBJECT_TYPE_SPECIAL:
-		case YAFFS_OBJECT_TYPE_UNKNOWN:
-			/* do nothing */
-			break;
-		}
+	switch (type) {
+	case YAFFS_OBJECT_TYPE_SYMLINK:
+		in->variant.symlink_variant.alias = str;
+		break;
+	case YAFFS_OBJECT_TYPE_HARDLINK:
+		in->variant.hardlink_variant.equiv_obj = equiv_obj;
+		in->variant.hardlink_variant.equiv_id = equiv_obj->obj_id;
+		list_add(&in->hard_links, &equiv_obj->hard_links);
+		break;
+	case YAFFS_OBJECT_TYPE_FILE:
+	case YAFFS_OBJECT_TYPE_DIRECTORY:
+	case YAFFS_OBJECT_TYPE_SPECIAL:
+	case YAFFS_OBJECT_TYPE_UNKNOWN:
+		/* do nothing */
+		break;
+	}
 
-		if (yaffs_update_oh(in, name, 0, 0, 0, NULL) < 0) {
-			/* Could not create the object header, fail the creation */
-			yaffs_del_obj(in);
-			in = NULL;
-		}
+	if (yaffs_update_oh(in, name, 0, 0, 0, NULL) < 0) {
+		/* Could not create the object header, fail */
+		yaffs_del_obj(in);
+		in = NULL;
+	}
 
+	if (in)
 		yaffs_update_parent(parent);
-	}
 
 	return in;
 }
 
 struct yaffs_obj *yaffs_create_file(struct yaffs_obj *parent,
-				    const YCHAR * name, u32 mode, u32 uid,
+				    const YCHAR *name, u32 mode, u32 uid,
 				    u32 gid)
 {
 	return yaffs_create_obj(YAFFS_OBJECT_TYPE_FILE, parent, name, mode,
 				uid, gid, NULL, NULL, 0);
 }
 
-struct yaffs_obj *yaffs_create_dir(struct yaffs_obj *parent, const YCHAR * name,
+struct yaffs_obj *yaffs_create_dir(struct yaffs_obj *parent, const YCHAR *name,
 				   u32 mode, u32 uid, u32 gid)
 {
 	return yaffs_create_obj(YAFFS_OBJECT_TYPE_DIRECTORY, parent, name,
@@ -2262,7 +2201,7 @@
 }
 
 struct yaffs_obj *yaffs_create_special(struct yaffs_obj *parent,
-				       const YCHAR * name, u32 mode, u32 uid,
+				       const YCHAR *name, u32 mode, u32 uid,
 				       u32 gid, u32 rdev)
 {
 	return yaffs_create_obj(YAFFS_OBJECT_TYPE_SPECIAL, parent, name, mode,
@@ -2270,8 +2209,8 @@
 }
 
 struct yaffs_obj *yaffs_create_symlink(struct yaffs_obj *parent,
-				       const YCHAR * name, u32 mode, u32 uid,
-				       u32 gid, const YCHAR * alias)
+				       const YCHAR *name, u32 mode, u32 uid,
+				       u32 gid, const YCHAR *alias)
 {
 	return yaffs_create_obj(YAFFS_OBJECT_TYPE_SYMLINK, parent, name, mode,
 				uid, gid, NULL, alias, 0);
@@ -2281,22 +2220,40 @@
 struct yaffs_obj *yaffs_link_obj(struct yaffs_obj *parent, const YCHAR * name,
 				 struct yaffs_obj *equiv_obj)
 {
-	/* Get the real object in case we were fed a hard link as an equivalent object */
+	/* Get the real object in case we were fed a hard link obj */
 	equiv_obj = yaffs_get_equivalent_obj(equiv_obj);
 
-	if (yaffs_create_obj
-	    (YAFFS_OBJECT_TYPE_HARDLINK, parent, name, 0, 0, 0,
-	     equiv_obj, NULL, 0)) {
+	if (yaffs_create_obj(YAFFS_OBJECT_TYPE_HARDLINK,
+			parent, name, 0, 0, 0,
+			equiv_obj, NULL, 0))
 		return equiv_obj;
-	} else {
-		return NULL;
-	}
+
+	return NULL;
 
 }
 
 
 
-/*------------------------- Block Management and Page Allocation ----------------*/
+/*---------------------- Block Management and Page Allocation -------------*/
+
+static void yaffs_deinit_blocks(struct yaffs_dev *dev)
+{
+	if (dev->block_info_alt && dev->block_info)
+		vfree(dev->block_info);
+	else
+		kfree(dev->block_info);
+
+	dev->block_info_alt = 0;
+
+	dev->block_info = NULL;
+
+	if (dev->chunk_bits_alt && dev->chunk_bits)
+		vfree(dev->chunk_bits);
+	else
+		kfree(dev->chunk_bits);
+	dev->chunk_bits_alt = 0;
+	dev->chunk_bits = NULL;
+}
 
 static int yaffs_init_blocks(struct yaffs_dev *dev)
 {
@@ -2304,7 +2261,6 @@
 
 	dev->block_info = NULL;
 	dev->chunk_bits = NULL;
-
 	dev->alloc_block = -1;	/* force it to get a new one */
 
 	/* If the first allocation strategy fails, thry the alternate one */
@@ -2316,56 +2272,41 @@
 		dev->block_info_alt = 1;
 	} else {
 		dev->block_info_alt = 0;
-        }
+	}
+
+	if (!dev->block_info)
+		goto alloc_error;
 
-	if (dev->block_info) {
-		/* Set up dynamic blockinfo stuff. Round up bytes. */
-		dev->chunk_bit_stride = (dev->param.chunks_per_block + 7) / 8;
+	/* Set up dynamic blockinfo stuff. Round up bytes. */
+	dev->chunk_bit_stride = (dev->param.chunks_per_block + 7) / 8;
+	dev->chunk_bits =
+		kmalloc(dev->chunk_bit_stride * n_blocks, GFP_NOFS);
+	if (!dev->chunk_bits) {
 		dev->chunk_bits =
-			kmalloc(dev->chunk_bit_stride * n_blocks, GFP_NOFS);
-		if (!dev->chunk_bits) {
-			dev->chunk_bits =
-			    vmalloc(dev->chunk_bit_stride * n_blocks);
-			dev->chunk_bits_alt = 1;
-		} else {
-			dev->chunk_bits_alt = 0;
-                }
+		    vmalloc(dev->chunk_bit_stride * n_blocks);
+		dev->chunk_bits_alt = 1;
+	} else {
+		dev->chunk_bits_alt = 0;
 	}
+	if (!dev->chunk_bits)
+		goto alloc_error;
 
-	if (dev->block_info && dev->chunk_bits) {
-		memset(dev->block_info, 0,
-		       n_blocks * sizeof(struct yaffs_block_info));
-		memset(dev->chunk_bits, 0, dev->chunk_bit_stride * n_blocks);
-		return YAFFS_OK;
-	}
 
+	memset(dev->block_info, 0, n_blocks * sizeof(struct yaffs_block_info));
+	memset(dev->chunk_bits, 0, dev->chunk_bit_stride * n_blocks);
+	return YAFFS_OK;
+
+alloc_error:
+	yaffs_deinit_blocks(dev);
 	return YAFFS_FAIL;
 }
 
-static void yaffs_deinit_blocks(struct yaffs_dev *dev)
-{
-	if (dev->block_info_alt && dev->block_info)
-		vfree(dev->block_info);
-	else if (dev->block_info)
-		kfree(dev->block_info);
-
-	dev->block_info_alt = 0;
-
-	dev->block_info = NULL;
-
-	if (dev->chunk_bits_alt && dev->chunk_bits)
-		vfree(dev->chunk_bits);
-	else if (dev->chunk_bits)
-		kfree(dev->chunk_bits);
-	dev->chunk_bits_alt = 0;
-	dev->chunk_bits = NULL;
-}
 
 void yaffs_block_became_dirty(struct yaffs_dev *dev, int block_no)
 {
 	struct yaffs_block_info *bi = yaffs_get_block_info(dev, block_no);
-
 	int erased_ok = 0;
+	int i;
 
 	/* If the block is still healthy erase it and mark as clean.
 	 * If the block has had a data failure, then retire it.
@@ -2380,11 +2321,12 @@
 
 	bi->block_state = YAFFS_BLOCK_STATE_DIRTY;
 
-	/* If this is the block being garbage collected then stop gc'ing this block */
+	/* If this is the block being garbage collected then stop gc'ing */
 	if (block_no == dev->gc_block)
 		dev->gc_block = 0;
 
-	/* If this block is currently the best candidate for gc then drop as a candidate */
+	/* If this block is currently the best candidate for gc
+	 * then drop as a candidate */
 	if (block_no == dev->gc_dirtiest) {
 		dev->gc_dirtiest = 0;
 		dev->gc_pages_in_use = 0;
@@ -2400,13 +2342,13 @@
 		}
 	}
 
+	/* Verify erasure if needed */
 	if (erased_ok &&
-	    ((yaffs_trace_mask & YAFFS_TRACE_ERASE)
-	     || !yaffs_skip_verification(dev))) {
-		int i;
+	    ((yaffs_trace_mask & YAFFS_TRACE_ERASE) ||
+	     !yaffs_skip_verification(dev))) {
 		for (i = 0; i < dev->param.chunks_per_block; i++) {
-			if (!yaffs_check_chunk_erased
-			    (dev, block_no * dev->param.chunks_per_block + i)) {
+			if (!yaffs_check_chunk_erased(dev,
+				block_no * dev->param.chunks_per_block + i)) {
 				yaffs_trace(YAFFS_TRACE_ERROR,
 					">>Block %d erasure supposedly OK, but chunk %d not erased",
 					block_no, i);
@@ -2414,51 +2356,186 @@
 		}
 	}
 
-	if (erased_ok) {
-		/* Clean it up... */
-		bi->block_state = YAFFS_BLOCK_STATE_EMPTY;
-		bi->seq_number = 0;
-		dev->n_erased_blocks++;
-		bi->pages_in_use = 0;
-		bi->soft_del_pages = 0;
-		bi->has_shrink_hdr = 0;
-		bi->skip_erased_check = 1;	/* Clean, so no need to check */
-		bi->gc_prioritise = 0;
-		yaffs_clear_chunk_bits(dev, block_no);
-
-		yaffs_trace(YAFFS_TRACE_ERASE,
-			"Erased block %d", block_no);
-	} else {
+	if (!erased_ok) {
 		/* We lost a block of free space */
 		dev->n_free_chunks -= dev->param.chunks_per_block;
 		yaffs_retire_block(dev, block_no);
 		yaffs_trace(YAFFS_TRACE_ERROR | YAFFS_TRACE_BAD_BLOCKS,
 			"**>> Block %d retired", block_no);
+		return;
 	}
+
+	/* Clean it up... */
+	bi->block_state = YAFFS_BLOCK_STATE_EMPTY;
+	bi->seq_number = 0;
+	dev->n_erased_blocks++;
+	bi->pages_in_use = 0;
+	bi->soft_del_pages = 0;
+	bi->has_shrink_hdr = 0;
+	bi->skip_erased_check = 1;	/* Clean, so no need to check */
+	bi->gc_prioritise = 0;
+	bi->has_summary = 0;
+
+	yaffs_clear_chunk_bits(dev, block_no);
+
+	yaffs_trace(YAFFS_TRACE_ERASE, "Erased block %d", block_no);
 }
 
+static inline int yaffs_gc_process_chunk(struct yaffs_dev *dev,
+					struct yaffs_block_info *bi,
+					int old_chunk, u8 *buffer)
+{
+	int new_chunk;
+	int mark_flash = 1;
+	struct yaffs_ext_tags tags;
+	struct yaffs_obj *object;
+	int matching_chunk;
+	int ret_val = YAFFS_OK;
+
+	memset(&tags, 0, sizeof(tags));
+	yaffs_rd_chunk_tags_nand(dev, old_chunk,
+				 buffer, &tags);
+	object = yaffs_find_by_number(dev, tags.obj_id);
+
+	yaffs_trace(YAFFS_TRACE_GC_DETAIL,
+		"Collecting chunk in block %d, %d %d %d ",
+		dev->gc_chunk, tags.obj_id,
+		tags.chunk_id, tags.n_bytes);
+
+	if (object && !yaffs_skip_verification(dev)) {
+		if (tags.chunk_id == 0)
+			matching_chunk =
+			    object->hdr_chunk;
+		else if (object->soft_del)
+			/* Defeat the test */
+			matching_chunk = old_chunk;
+		else
+			matching_chunk =
+			    yaffs_find_chunk_in_file
+			    (object, tags.chunk_id,
+			     NULL);
+
+		if (old_chunk != matching_chunk)
+			yaffs_trace(YAFFS_TRACE_ERROR,
+				"gc: page in gc mismatch: %d %d %d %d",
+				old_chunk,
+				matching_chunk,
+				tags.obj_id,
+				tags.chunk_id);
+	}
+
+	if (!object) {
+		yaffs_trace(YAFFS_TRACE_ERROR,
+			"page %d in gc has no object: %d %d %d ",
+			old_chunk,
+			tags.obj_id, tags.chunk_id,
+			tags.n_bytes);
+	}
+
+	if (object &&
+	    object->deleted &&
+	    object->soft_del && tags.chunk_id != 0) {
+		/* Data chunk in a soft deleted file,
+		 * throw it away.
+		 * It's a soft deleted data chunk,
+		 * No need to copy this, just forget
+		 * about it and fix up the object.
+		 */
+
+		/* Free chunks already includes
+		 * softdeleted chunks, how ever this
+		 * chunk is going to soon be really
+		 * deleted which will increment free
+		 * chunks. We have to decrement free
+		 * chunks so this works out properly.
+		 */
+		dev->n_free_chunks--;
+		bi->soft_del_pages--;
+
+		object->n_data_chunks--;
+		if (object->n_data_chunks <= 0) {
+			/* remeber to clean up obj */
+			dev->gc_cleanup_list[dev->n_clean_ups] = tags.obj_id;
+			dev->n_clean_ups++;
+		}
+		mark_flash = 0;
+	} else if (object) {
+		/* It's either a data chunk in a live
+		 * file or an ObjectHeader, so we're
+		 * interested in it.
+		 * NB Need to keep the ObjectHeaders of
+		 * deleted files until the whole file
+		 * has been deleted off
+		 */
+		tags.serial_number++;
+		dev->n_gc_copies++;
+
+		if (tags.chunk_id == 0) {
+			/* It is an object Id,
+			 * We need to nuke the
+			 * shrinkheader flags since its
+			 * work is done.
+			 * Also need to clean up
+			 * shadowing.
+			 */
+			struct yaffs_obj_hdr *oh;
+			oh = (struct yaffs_obj_hdr *) buffer;
 
+			oh->is_shrink = 0;
+			tags.extra_is_shrink = 0;
+			oh->shadows_obj = 0;
+			oh->inband_shadowed_obj_id = 0;
+			tags.extra_shadows = 0;
+
+			/* Update file size */
+			if (object->variant_type == YAFFS_OBJECT_TYPE_FILE) {
+				yaffs_oh_size_load(oh,
+				    object->variant.file_variant.file_size);
+				tags.extra_file_size =
+				    object->variant.file_variant.file_size;
+			}
+
+			yaffs_verify_oh(object, oh, &tags, 1);
+			new_chunk =
+			    yaffs_write_new_chunk(dev, (u8 *) oh, &tags, 1);
+		} else {
+			new_chunk =
+			    yaffs_write_new_chunk(dev, buffer, &tags, 1);
+		}
+
+		if (new_chunk < 0) {
+			ret_val = YAFFS_FAIL;
+		} else {
+
+			/* Now fix up the Tnodes etc. */
+
+			if (tags.chunk_id == 0) {
+				/* It's a header */
+				object->hdr_chunk = new_chunk;
+				object->serial = tags.serial_number;
+			} else {
+				/* It's a data chunk */
+				yaffs_put_chunk_in_file(object, tags.chunk_id,
+							new_chunk, 0);
+			}
+		}
+	}
+	if (ret_val == YAFFS_OK)
+		yaffs_chunk_del(dev, old_chunk, mark_flash, __LINE__);
+	return ret_val;
+}
 
 static int yaffs_gc_block(struct yaffs_dev *dev, int block, int whole_block)
 {
 	int old_chunk;
-	int new_chunk;
-	int mark_flash;
 	int ret_val = YAFFS_OK;
 	int i;
 	int is_checkpt_block;
-	int matching_chunk;
 	int max_copies;
-
 	int chunks_before = yaffs_get_erased_chunks(dev);
 	int chunks_after;
-
-	struct yaffs_ext_tags tags;
-
 	struct yaffs_block_info *bi = yaffs_get_block_info(dev, block);
 
-	struct yaffs_obj *object;
-
 	is_checkpt_block = (bi->block_state == YAFFS_BLOCK_STATE_CHECKPOINT);
 
 	yaffs_trace(YAFFS_TRACE_TRACING,
@@ -2475,200 +2552,36 @@
 
 	dev->gc_disable = 1;
 
+	yaffs_summary_gc(dev, block);
+
 	if (is_checkpt_block || !yaffs_still_some_chunks(dev, block)) {
 		yaffs_trace(YAFFS_TRACE_TRACING,
 			"Collecting block %d that has no chunks in use",
-		   	block);
-		yaffs_block_became_dirty(dev, block);
-	} else {
-
-		u8 *buffer = yaffs_get_temp_buffer(dev, __LINE__);
-
-		yaffs_verify_blk(dev, bi, block);
-
-		max_copies = (whole_block) ? dev->param.chunks_per_block : 5;
-		old_chunk = block * dev->param.chunks_per_block + dev->gc_chunk;
-
-		for ( /* init already done */ ;
-		     ret_val == YAFFS_OK &&
-		     dev->gc_chunk < dev->param.chunks_per_block &&
-		     (bi->block_state == YAFFS_BLOCK_STATE_COLLECTING) &&
-		     max_copies > 0; dev->gc_chunk++, old_chunk++) {
-			if (yaffs_check_chunk_bit(dev, block, dev->gc_chunk)) {
-
-				/* This page is in use and might need to be copied off */
-
-				max_copies--;
-
-				mark_flash = 1;
-
-				yaffs_init_tags(&tags);
-
-				yaffs_rd_chunk_tags_nand(dev, old_chunk,
-							 buffer, &tags);
-
-				object = yaffs_find_by_number(dev, tags.obj_id);
-
-				yaffs_trace(YAFFS_TRACE_GC_DETAIL,
-					"Collecting chunk in block %d, %d %d %d ",
-					dev->gc_chunk, tags.obj_id,
-					tags.chunk_id, tags.n_bytes);
-
-				if (object && !yaffs_skip_verification(dev)) {
-					if (tags.chunk_id == 0)
-						matching_chunk =
-						    object->hdr_chunk;
-					else if (object->soft_del)
-						matching_chunk = old_chunk;	/* Defeat the test */
-					else
-						matching_chunk =
-						    yaffs_find_chunk_in_file
-						    (object, tags.chunk_id,
-						     NULL);
-
-					if (old_chunk != matching_chunk)
-						yaffs_trace(YAFFS_TRACE_ERROR,
-							"gc: page in gc mismatch: %d %d %d %d",
-							old_chunk,
-							matching_chunk,
-							tags.obj_id,
-						   	tags.chunk_id);
-
-				}
-
-				if (!object) {
-					yaffs_trace(YAFFS_TRACE_ERROR,
-						"page %d in gc has no object: %d %d %d ",
-						old_chunk,
-						tags.obj_id, tags.chunk_id,
-						tags.n_bytes);
-				}
-
-				if (object &&
-				    object->deleted &&
-				    object->soft_del && tags.chunk_id != 0) {
-					/* Data chunk in a soft deleted file, throw it away
-					 * It's a soft deleted data chunk,
-					 * No need to copy this, just forget about it and
-					 * fix up the object.
-					 */
-
-					/* Free chunks already includes softdeleted chunks.
-					 * How ever this chunk is going to soon be really deleted
-					 * which will increment free chunks.
-					 * We have to decrement free chunks so this works out properly.
-					 */
-					dev->n_free_chunks--;
-					bi->soft_del_pages--;
-
-					object->n_data_chunks--;
-
-					if (object->n_data_chunks <= 0) {
-						/* remeber to clean up the object */
-						dev->gc_cleanup_list[dev->
-								     n_clean_ups]
-						    = tags.obj_id;
-						dev->n_clean_ups++;
-					}
-					mark_flash = 0;
-				} else if (0) {
-					/* Todo object && object->deleted && object->n_data_chunks == 0 */
-					/* Deleted object header with no data chunks.
-					 * Can be discarded and the file deleted.
-					 */
-					object->hdr_chunk = 0;
-					yaffs_free_tnode(object->my_dev,
-							 object->
-							 variant.file_variant.
-							 top);
-					object->variant.file_variant.top = NULL;
-					yaffs_generic_obj_del(object);
-
-				} else if (object) {
-					/* It's either a data chunk in a live file or
-					 * an ObjectHeader, so we're interested in it.
-					 * NB Need to keep the ObjectHeaders of deleted files
-					 * until the whole file has been deleted off
-					 */
-					tags.serial_number++;
+			block);
+		yaffs_block_became_dirty(dev, block);
+	} else {
 
-					dev->n_gc_copies++;
+		u8 *buffer = yaffs_get_temp_buffer(dev);
 
-					if (tags.chunk_id == 0) {
-						/* It is an object Id,
-						 * We need to nuke the shrinkheader flags first
-						 * Also need to clean up shadowing.
-						 * We no longer want the shrink_header flag since its work is done
-						 * and if it is left in place it will mess up scanning.
-						 */
-
-						struct yaffs_obj_hdr *oh;
-						oh = (struct yaffs_obj_hdr *)
-						    buffer;
-
-						oh->is_shrink = 0;
-						tags.extra_is_shrink = 0;
-
-						oh->shadows_obj = 0;
-						oh->inband_shadowed_obj_id = 0;
-						tags.extra_shadows = 0;
-
-						/* Update file size */
-						if (object->variant_type ==
-						    YAFFS_OBJECT_TYPE_FILE) {
-							oh->file_size =
-							    object->variant.
-							    file_variant.
-							    file_size;
-							tags.extra_length =
-							    oh->file_size;
-						}
-
-						yaffs_verify_oh(object, oh,
-								&tags, 1);
-						new_chunk =
-						    yaffs_write_new_chunk(dev,
-									  (u8 *)
-									  oh,
-									  &tags,
-									  1);
-					} else {
-						new_chunk =
-						    yaffs_write_new_chunk(dev,
-									  buffer,
-									  &tags,
-									  1);
-                                        }
-
-					if (new_chunk < 0) {
-						ret_val = YAFFS_FAIL;
-					} else {
-
-						/* Ok, now fix up the Tnodes etc. */
-
-						if (tags.chunk_id == 0) {
-							/* It's a header */
-							object->hdr_chunk =
-							    new_chunk;
-							object->serial =
-							    tags.serial_number;
-						} else {
-							/* It's a data chunk */
-							int ok;
-							ok = yaffs_put_chunk_in_file(object, tags.chunk_id, new_chunk, 0);
-						}
-					}
-				}
+		yaffs_verify_blk(dev, bi, block);
 
-				if (ret_val == YAFFS_OK)
-					yaffs_chunk_del(dev, old_chunk,
-							mark_flash, __LINE__);
+		max_copies = (whole_block) ? dev->param.chunks_per_block : 5;
+		old_chunk = block * dev->param.chunks_per_block + dev->gc_chunk;
 
+		for (/* init already done */ ;
+		     ret_val == YAFFS_OK &&
+		     dev->gc_chunk < dev->param.chunks_per_block &&
+		     (bi->block_state == YAFFS_BLOCK_STATE_COLLECTING) &&
+		     max_copies > 0;
+		     dev->gc_chunk++, old_chunk++) {
+			if (yaffs_check_chunk_bit(dev, block, dev->gc_chunk)) {
+				/* Page is in use and might need to be copied */
+				max_copies--;
+				ret_val = yaffs_gc_process_chunk(dev, bi,
+							old_chunk, buffer);
 			}
 		}
-
-		yaffs_release_temp_buffer(dev, buffer, __LINE__);
-
+		yaffs_release_temp_buffer(dev, buffer);
 	}
 
 	yaffs_verify_collected_blk(dev, bi, block);
@@ -2684,12 +2597,11 @@
 		/* Do any required cleanups */
 		for (i = 0; i < dev->n_clean_ups; i++) {
 			/* Time to delete the file too */
-			object =
+			struct yaffs_obj *object =
 			    yaffs_find_by_number(dev, dev->gc_cleanup_list[i]);
 			if (object) {
 				yaffs_free_tnode(dev,
-						 object->variant.
-						 file_variant.top);
+					  object->variant.file_variant.top);
 				object->variant.file_variant.top = NULL;
 				yaffs_trace(YAFFS_TRACE_GC,
 					"yaffs: About to finally delete object %d",
@@ -2699,7 +2611,6 @@
 			}
 
 		}
-
 		chunks_after = yaffs_get_erased_chunks(dev);
 		if (chunks_before >= chunks_after)
 			yaffs_trace(YAFFS_TRACE_GC,
@@ -2716,7 +2627,7 @@
 }
 
 /*
- * FindBlockForgarbageCollection is used to select the dirtiest block (or close enough)
+ * find_gc_block() selects the dirtiest block (or close enough)
  * for garbage collection.
  */
 
@@ -2751,8 +2662,8 @@
 
 		/*
 		 * If there is a prioritised block and none was selected then
-		 * this happened because there is at least one old dirty block gumming
-		 * up the works. Let's gc the oldest dirty block.
+		 * this happened because there is at least one old dirty block
+		 * gumming up the works. Let's gc the oldest dirty block.
 		 */
 
 		if (prioritised_exist &&
@@ -2763,9 +2674,9 @@
 			dev->has_pending_prioritised_gc = 0;
 	}
 
-	/* If we're doing aggressive GC then we are happy to take a less-dirty block, and
-	 * search harder.
-	 * else (we're doing a leasurely gc), then we only bother to do this if the
+	/* If we're doing aggressive GC then we are happy to take a less-dirty
+	 * block, and search harder.
+	 * else (leasurely gc), then we only bother to do this if the
 	 * block has only a few pages in use.
 	 */
 
@@ -2801,7 +2712,8 @@
 		for (i = 0;
 		     i < iterations &&
 		     (dev->gc_dirtiest < 1 ||
-		      dev->gc_pages_in_use > YAFFS_GC_GOOD_ENOUGH); i++) {
+		      dev->gc_pages_in_use > YAFFS_GC_GOOD_ENOUGH);
+		     i++) {
 			dev->gc_block_finder++;
 			if (dev->gc_block_finder < dev->internal_start_block ||
 			    dev->gc_block_finder > dev->internal_end_block)
@@ -2814,9 +2726,9 @@
 
 			if (bi->block_state == YAFFS_BLOCK_STATE_FULL &&
 			    pages_used < dev->param.chunks_per_block &&
-			    (dev->gc_dirtiest < 1
-			     || pages_used < dev->gc_pages_in_use)
-			    && yaffs_block_ok_for_gc(dev, bi)) {
+			    (dev->gc_dirtiest < 1 ||
+			     pages_used < dev->gc_pages_in_use) &&
+			    yaffs_block_ok_for_gc(dev, bi)) {
 				dev->gc_dirtiest = dev->gc_block_finder;
 				dev->gc_pages_in_use = pages_used;
 			}
@@ -2827,7 +2739,7 @@
 	}
 
 	/*
-	 * If nothing has been selected for a while, try selecting the oldest dirty
+	 * If nothing has been selected for a while, try the oldest dirty
 	 * because that's gumming up the works.
 	 */
 
@@ -2843,7 +2755,7 @@
 			    bi->pages_in_use - bi->soft_del_pages;
 		} else {
 			dev->gc_not_done = 0;
-                }
+		}
 	}
 
 	if (selected) {
@@ -2878,7 +2790,7 @@
  * If we're very low on erased blocks then we do aggressive garbage collection
  * otherwise we do "leasurely" garbage collection.
  * Aggressive gc looks further (whole array) and will accept less dirty blocks.
- * Passive gc only inspects smaller areas and will only accept more dirty blocks.
+ * Passive gc only inspects smaller areas and only accepts more dirty blocks.
  *
  * The idea is to help clear out space in a more spread-out manner.
  * Dunno if it really does anything useful.
@@ -2895,13 +2807,12 @@
 	if (dev->param.gc_control && (dev->param.gc_control(dev) & 1) == 0)
 		return YAFFS_OK;
 
-	if (dev->gc_disable) {
+	if (dev->gc_disable)
 		/* Bail out so we don't get recursive gc */
 		return YAFFS_OK;
-	}
 
 	/* This loop should pass the first time.
-	 * We'll only see looping here if the collection does not increase space.
+	 * Only loops here if the collection does not increase space.
 	 */
 
 	do {
@@ -2935,7 +2846,8 @@
 
 		dev->gc_skip = 5;
 
-		/* If we don't already have a block being gc'd then see if we should start another */
+		/* If we don't already have a block being gc'd then see if we
+		 * should start another */
 
 		if (dev->gc_block < 1 && !aggressive) {
 			dev->gc_block = yaffs2_find_refresh_block(dev);
@@ -2961,8 +2873,8 @@
 			gc_ok = yaffs_gc_block(dev, dev->gc_block, aggressive);
 		}
 
-		if (dev->n_erased_blocks < (dev->param.n_reserved_blocks)
-		    && dev->gc_block > 0) {
+		if (dev->n_erased_blocks < (dev->param.n_reserved_blocks) &&
+		    dev->gc_block > 0) {
 			yaffs_trace(YAFFS_TRACE_GC,
 				"yaffs: GC !!!no reclaim!!! n_erased_blocks %d after try %d block %d",
 				dev->n_erased_blocks, max_tries,
@@ -3039,10 +2951,8 @@
 	if (!dev->param.is_yaffs2 && mark_flash &&
 	    bi->block_state != YAFFS_BLOCK_STATE_COLLECTING) {
 
-		yaffs_init_tags(&tags);
-
+		memset(&tags, 0, sizeof(tags));
 		tags.is_deleted = 1;
-
 		yaffs_wr_chunk_tags_nand(dev, chunk_id, NULL, &tags);
 		yaffs_handle_chunk_update(dev, chunk_id, &tags);
 	} else {
@@ -3054,27 +2964,23 @@
 	 */
 	if (bi->block_state == YAFFS_BLOCK_STATE_ALLOCATING ||
 	    bi->block_state == YAFFS_BLOCK_STATE_FULL ||
-	    bi->block_state == YAFFS_BLOCK_STATE_NEEDS_SCANNING ||
+	    bi->block_state == YAFFS_BLOCK_STATE_NEEDS_SCAN ||
 	    bi->block_state == YAFFS_BLOCK_STATE_COLLECTING) {
 		dev->n_free_chunks++;
-
 		yaffs_clear_chunk_bit(dev, block, page);
-
 		bi->pages_in_use--;
 
 		if (bi->pages_in_use == 0 &&
 		    !bi->has_shrink_hdr &&
 		    bi->block_state != YAFFS_BLOCK_STATE_ALLOCATING &&
-		    bi->block_state != YAFFS_BLOCK_STATE_NEEDS_SCANNING) {
+		    bi->block_state != YAFFS_BLOCK_STATE_NEEDS_SCAN) {
 			yaffs_block_became_dirty(dev, block);
 		}
-
 	}
-
 }
 
 static int yaffs_wr_data_obj(struct yaffs_obj *in, int inode_chunk,
-			     const u8 * buffer, int n_bytes, int use_reserve)
+			     const u8 *buffer, int n_bytes, int use_reserve)
 {
 	/* Find old chunk Need to do this to get serial number
 	 * Write new one and patch into tree.
@@ -3083,10 +2989,8 @@
 
 	int prev_chunk_id;
 	struct yaffs_ext_tags prev_tags;
-
 	int new_chunk_id;
 	struct yaffs_ext_tags new_tags;
-
 	struct yaffs_dev *dev = in->my_dev;
 
 	yaffs_check_gc(dev, 0);
@@ -3101,7 +3005,7 @@
 		return 0;
 
 	/* Set up new tags */
-	yaffs_init_tags(&new_tags);
+	memset(&new_tags, 0, sizeof(new_tags));
 
 	new_tags.chunk_id = inode_chunk;
 	new_tags.obj_id = in->obj_id;
@@ -3113,7 +3017,7 @@
 		yaffs_trace(YAFFS_TRACE_ERROR,
 		  "Writing %d bytes to chunk!!!!!!!!!",
 		   n_bytes);
-		YBUG();
+		BUG();
 	}
 
 	new_chunk_id =
@@ -3134,11 +3038,10 @@
 
 
 static int yaffs_do_xattrib_mod(struct yaffs_obj *obj, int set,
-				const YCHAR * name, const void *value, int size,
+				const YCHAR *name, const void *value, int size,
 				int flags)
 {
 	struct yaffs_xattr_mod xmod;
-
 	int result;
 
 	xmod.set = set;
@@ -3163,7 +3066,6 @@
 	int x_offs = sizeof(struct yaffs_obj_hdr);
 	struct yaffs_dev *dev = obj->my_dev;
 	int x_size = dev->data_bytes_per_chunk - sizeof(struct yaffs_obj_hdr);
-
 	char *x_buffer = buffer + x_offs;
 
 	if (xmod->set)
@@ -3175,13 +3077,12 @@
 
 	obj->has_xattr = nval_hasvalues(x_buffer, x_size);
 	obj->xattr_known = 1;
-
 	xmod->result = retval;
 
 	return retval;
 }
 
-static int yaffs_do_xattrib_fetch(struct yaffs_obj *obj, const YCHAR * name,
+static int yaffs_do_xattrib_fetch(struct yaffs_obj *obj, const YCHAR *name,
 				  void *value, int size)
 {
 	char *buffer = NULL;
@@ -3190,9 +3091,7 @@
 	struct yaffs_dev *dev = obj->my_dev;
 	int x_offs = sizeof(struct yaffs_obj_hdr);
 	int x_size = dev->data_bytes_per_chunk - sizeof(struct yaffs_obj_hdr);
-
 	char *x_buffer;
-
 	int retval = 0;
 
 	if (obj->hdr_chunk < 1)
@@ -3208,7 +3107,7 @@
 			return 0;
 	}
 
-	buffer = (char *)yaffs_get_temp_buffer(dev, __LINE__);
+	buffer = (char *)yaffs_get_temp_buffer(dev);
 	if (!buffer)
 		return -ENOMEM;
 
@@ -3230,7 +3129,7 @@
 		else
 			retval = nval_list(x_buffer, x_size, value, size);
 	}
-	yaffs_release_temp_buffer(dev, (u8 *) buffer, __LINE__);
+	yaffs_release_temp_buffer(dev, (u8 *) buffer);
 	return retval;
 }
 
@@ -3258,44 +3157,38 @@
 
 static void yaffs_check_obj_details_loaded(struct yaffs_obj *in)
 {
-	u8 *chunk_data;
+	u8 *buf;
 	struct yaffs_obj_hdr *oh;
 	struct yaffs_dev *dev;
 	struct yaffs_ext_tags tags;
 	int result;
 	int alloc_failed = 0;
 
-	if (!in)
+	if (!in || !in->lazy_loaded || in->hdr_chunk < 1)
 		return;
 
 	dev = in->my_dev;
+	in->lazy_loaded = 0;
+	buf = yaffs_get_temp_buffer(dev);
 
-	if (in->lazy_loaded && in->hdr_chunk > 0) {
-		in->lazy_loaded = 0;
-		chunk_data = yaffs_get_temp_buffer(dev, __LINE__);
-
-		result =
-		    yaffs_rd_chunk_tags_nand(dev, in->hdr_chunk, chunk_data,
-					     &tags);
-		oh = (struct yaffs_obj_hdr *)chunk_data;
-
-		in->yst_mode = oh->yst_mode;
-		yaffs_load_attribs(in, oh);
-		yaffs_set_obj_name_from_oh(in, oh);
+	result = yaffs_rd_chunk_tags_nand(dev, in->hdr_chunk, buf, &tags);
+	oh = (struct yaffs_obj_hdr *)buf;
 
-		if (in->variant_type == YAFFS_OBJECT_TYPE_SYMLINK) {
-			in->variant.symlink_variant.alias =
-			    yaffs_clone_str(oh->alias);
-			if (!in->variant.symlink_variant.alias)
-				alloc_failed = 1;	/* Not returned to caller */
-		}
+	in->yst_mode = oh->yst_mode;
+	yaffs_load_attribs(in, oh);
+	yaffs_set_obj_name_from_oh(in, oh);
 
-		yaffs_release_temp_buffer(dev, chunk_data, __LINE__);
+	if (in->variant_type == YAFFS_OBJECT_TYPE_SYMLINK) {
+		in->variant.symlink_variant.alias =
+		    yaffs_clone_str(oh->alias);
+		if (!in->variant.symlink_variant.alias)
+			alloc_failed = 1;	/* Not returned */
 	}
+	yaffs_release_temp_buffer(dev, buf);
 }
 
-static void yaffs_load_name_from_oh(struct yaffs_dev *dev, YCHAR * name,
-				    const YCHAR * oh_name, int buff_size)
+static void yaffs_load_name_from_oh(struct yaffs_dev *dev, YCHAR *name,
+				    const YCHAR *oh_name, int buff_size)
 {
 #ifdef CONFIG_YAFFS_AUTO_UNICODE
 	if (dev->param.auto_unicode) {
@@ -3312,17 +3205,18 @@
 			}
 		} else {
 			strncpy(name, oh_name + 1, buff_size - 1);
-                }
+		}
 	} else {
 #else
-        {
+	(void) dev;
+	{
 #endif
 		strncpy(name, oh_name, buff_size - 1);
-        }
+	}
 }
 
-static void yaffs_load_oh_from_name(struct yaffs_dev *dev, YCHAR * oh_name,
-				    const YCHAR * name)
+static void yaffs_load_oh_from_name(struct yaffs_dev *dev, YCHAR *oh_name,
+				    const YCHAR *name)
 {
 #ifdef CONFIG_YAFFS_AUTO_UNICODE
 
@@ -3342,7 +3236,7 @@
 		}
 
 		if (is_ascii) {
-			/* It is an ASCII name, so do a unicode to ascii conversion */
+			/* It is an ASCII name, so convert unicode to ascii */
 			char *ascii_oh_name = (char *)oh_name;
 			int n = YAFFS_MAX_NAME_LENGTH - 1;
 			while (n > 0 && *name) {
@@ -3352,180 +3246,165 @@
 				n--;
 			}
 		} else {
-			/* It is a unicode name, so save starting at the second YCHAR */
+			/* Unicode name, so save starting at the second YCHAR */
 			*oh_name = 0;
-			strncpy(oh_name + 1, name,
-				      YAFFS_MAX_NAME_LENGTH - 2);
+			strncpy(oh_name + 1, name, YAFFS_MAX_NAME_LENGTH - 2);
 		}
 	} else {
 #else
-        {
+	dev = dev;
+	{
 #endif
 		strncpy(oh_name, name, YAFFS_MAX_NAME_LENGTH - 1);
-        }
-
+	}
 }
 
 /* UpdateObjectHeader updates the header on NAND for an object.
  * If name is not NULL, then that new name is used.
  */
-int yaffs_update_oh(struct yaffs_obj *in, const YCHAR * name, int force,
+int yaffs_update_oh(struct yaffs_obj *in, const YCHAR *name, int force,
 		    int is_shrink, int shadows, struct yaffs_xattr_mod *xmod)
 {
 
 	struct yaffs_block_info *bi;
-
 	struct yaffs_dev *dev = in->my_dev;
-
 	int prev_chunk_id;
 	int ret_val = 0;
 	int result = 0;
-
 	int new_chunk_id;
 	struct yaffs_ext_tags new_tags;
 	struct yaffs_ext_tags old_tags;
 	const YCHAR *alias = NULL;
-
 	u8 *buffer = NULL;
 	YCHAR old_name[YAFFS_MAX_NAME_LENGTH + 1];
-
 	struct yaffs_obj_hdr *oh = NULL;
+	loff_t file_size = 0;
 
 	strcpy(old_name, _Y("silly old name"));
 
-	if (!in->fake || in == dev->root_dir ||
-	    force || xmod) {
-
-		yaffs_check_gc(dev, 0);
-		yaffs_check_obj_details_loaded(in);
-
-		buffer = yaffs_get_temp_buffer(in->my_dev, __LINE__);
-		oh = (struct yaffs_obj_hdr *)buffer;
-
-		prev_chunk_id = in->hdr_chunk;
+	if (in->fake && in != dev->root_dir && !force && !xmod)
+		return ret_val;
 
-		if (prev_chunk_id > 0) {
-			result = yaffs_rd_chunk_tags_nand(dev, prev_chunk_id,
-							  buffer, &old_tags);
+	yaffs_check_gc(dev, 0);
+	yaffs_check_obj_details_loaded(in);
 
-			yaffs_verify_oh(in, oh, &old_tags, 0);
+	buffer = yaffs_get_temp_buffer(in->my_dev);
+	oh = (struct yaffs_obj_hdr *)buffer;
 
-			memcpy(old_name, oh->name, sizeof(oh->name));
-			memset(buffer, 0xFF, sizeof(struct yaffs_obj_hdr));
-		} else {
-			memset(buffer, 0xFF, dev->data_bytes_per_chunk);
-                }
+	prev_chunk_id = in->hdr_chunk;
 
-		oh->type = in->variant_type;
-		oh->yst_mode = in->yst_mode;
-		oh->shadows_obj = oh->inband_shadowed_obj_id = shadows;
+	if (prev_chunk_id > 0) {
+		result = yaffs_rd_chunk_tags_nand(dev, prev_chunk_id,
+						  buffer, &old_tags);
 
-		yaffs_load_attribs_oh(oh, in);
+		yaffs_verify_oh(in, oh, &old_tags, 0);
+		memcpy(old_name, oh->name, sizeof(oh->name));
+		memset(buffer, 0xff, sizeof(struct yaffs_obj_hdr));
+	} else {
+		memset(buffer, 0xff, dev->data_bytes_per_chunk);
+	}
 
-		if (in->parent)
-			oh->parent_obj_id = in->parent->obj_id;
-		else
-			oh->parent_obj_id = 0;
+	oh->type = in->variant_type;
+	oh->yst_mode = in->yst_mode;
+	oh->shadows_obj = oh->inband_shadowed_obj_id = shadows;
 
-		if (name && *name) {
-			memset(oh->name, 0, sizeof(oh->name));
-			yaffs_load_oh_from_name(dev, oh->name, name);
-		} else if (prev_chunk_id > 0) {
-			memcpy(oh->name, old_name, sizeof(oh->name));
-		} else {
-			memset(oh->name, 0, sizeof(oh->name));
-                }
+	yaffs_load_attribs_oh(oh, in);
 
-		oh->is_shrink = is_shrink;
+	if (in->parent)
+		oh->parent_obj_id = in->parent->obj_id;
+	else
+		oh->parent_obj_id = 0;
 
-		switch (in->variant_type) {
-		case YAFFS_OBJECT_TYPE_UNKNOWN:
-			/* Should not happen */
-			break;
-		case YAFFS_OBJECT_TYPE_FILE:
-			oh->file_size =
-			    (oh->parent_obj_id == YAFFS_OBJECTID_DELETED
-			     || oh->parent_obj_id ==
-			     YAFFS_OBJECTID_UNLINKED) ? 0 : in->
-			    variant.file_variant.file_size;
-			break;
-		case YAFFS_OBJECT_TYPE_HARDLINK:
-			oh->equiv_id = in->variant.hardlink_variant.equiv_id;
-			break;
-		case YAFFS_OBJECT_TYPE_SPECIAL:
-			/* Do nothing */
-			break;
-		case YAFFS_OBJECT_TYPE_DIRECTORY:
-			/* Do nothing */
-			break;
-		case YAFFS_OBJECT_TYPE_SYMLINK:
-			alias = in->variant.symlink_variant.alias;
-			if (!alias)
-				alias = _Y("no alias");
-			strncpy(oh->alias, alias, YAFFS_MAX_ALIAS_LENGTH);
-			oh->alias[YAFFS_MAX_ALIAS_LENGTH] = 0;
-			break;
-		}
+	if (name && *name) {
+		memset(oh->name, 0, sizeof(oh->name));
+		yaffs_load_oh_from_name(dev, oh->name, name);
+	} else if (prev_chunk_id > 0) {
+		memcpy(oh->name, old_name, sizeof(oh->name));
+	} else {
+		memset(oh->name, 0, sizeof(oh->name));
+	}
 
-		/* process any xattrib modifications */
-		if (xmod)
-			yaffs_apply_xattrib_mod(in, (char *)buffer, xmod);
-
-		/* Tags */
-		yaffs_init_tags(&new_tags);
-		in->serial++;
-		new_tags.chunk_id = 0;
-		new_tags.obj_id = in->obj_id;
-		new_tags.serial_number = in->serial;
-
-		/* Add extra info for file header */
-
-		new_tags.extra_available = 1;
-		new_tags.extra_parent_id = oh->parent_obj_id;
-		new_tags.extra_length = oh->file_size;
-		new_tags.extra_is_shrink = oh->is_shrink;
-		new_tags.extra_equiv_id = oh->equiv_id;
-		new_tags.extra_shadows = (oh->shadows_obj > 0) ? 1 : 0;
-		new_tags.extra_obj_type = in->variant_type;
-
-		yaffs_verify_oh(in, oh, &new_tags, 1);
-
-		/* Create new chunk in NAND */
-		new_chunk_id =
-		    yaffs_write_new_chunk(dev, buffer, &new_tags,
-					  (prev_chunk_id > 0) ? 1 : 0);
+	oh->is_shrink = is_shrink;
 
-		if (new_chunk_id >= 0) {
+	switch (in->variant_type) {
+	case YAFFS_OBJECT_TYPE_UNKNOWN:
+		/* Should not happen */
+		break;
+	case YAFFS_OBJECT_TYPE_FILE:
+		if (oh->parent_obj_id != YAFFS_OBJECTID_DELETED &&
+		    oh->parent_obj_id != YAFFS_OBJECTID_UNLINKED)
+			file_size = in->variant.file_variant.file_size;
+		yaffs_oh_size_load(oh, file_size);
+		break;
+	case YAFFS_OBJECT_TYPE_HARDLINK:
+		oh->equiv_id = in->variant.hardlink_variant.equiv_id;
+		break;
+	case YAFFS_OBJECT_TYPE_SPECIAL:
+		/* Do nothing */
+		break;
+	case YAFFS_OBJECT_TYPE_DIRECTORY:
+		/* Do nothing */
+		break;
+	case YAFFS_OBJECT_TYPE_SYMLINK:
+		alias = in->variant.symlink_variant.alias;
+		if (!alias)
+			alias = _Y("no alias");
+		strncpy(oh->alias, alias, YAFFS_MAX_ALIAS_LENGTH);
+		oh->alias[YAFFS_MAX_ALIAS_LENGTH] = 0;
+		break;
+	}
 
-			in->hdr_chunk = new_chunk_id;
+	/* process any xattrib modifications */
+	if (xmod)
+		yaffs_apply_xattrib_mod(in, (char *)buffer, xmod);
+
+	/* Tags */
+	memset(&new_tags, 0, sizeof(new_tags));
+	in->serial++;
+	new_tags.chunk_id = 0;
+	new_tags.obj_id = in->obj_id;
+	new_tags.serial_number = in->serial;
 
-			if (prev_chunk_id > 0) {
-				yaffs_chunk_del(dev, prev_chunk_id, 1,
-						__LINE__);
-			}
+	/* Add extra info for file header */
+	new_tags.extra_available = 1;
+	new_tags.extra_parent_id = oh->parent_obj_id;
+	new_tags.extra_file_size = file_size;
+	new_tags.extra_is_shrink = oh->is_shrink;
+	new_tags.extra_equiv_id = oh->equiv_id;
+	new_tags.extra_shadows = (oh->shadows_obj > 0) ? 1 : 0;
+	new_tags.extra_obj_type = in->variant_type;
+	yaffs_verify_oh(in, oh, &new_tags, 1);
 
-			if (!yaffs_obj_cache_dirty(in))
-				in->dirty = 0;
+	/* Create new chunk in NAND */
+	new_chunk_id =
+	    yaffs_write_new_chunk(dev, buffer, &new_tags,
+				  (prev_chunk_id > 0) ? 1 : 0);
 
-			/* If this was a shrink, then mark the block that the chunk lives on */
-			if (is_shrink) {
-				bi = yaffs_get_block_info(in->my_dev,
-							  new_chunk_id /
-							  in->my_dev->param.
-							  chunks_per_block);
-				bi->has_shrink_hdr = 1;
-			}
+	if (buffer)
+		yaffs_release_temp_buffer(dev, buffer);
 
-		}
+	if (new_chunk_id < 0)
+		return new_chunk_id;
 
-		ret_val = new_chunk_id;
+	in->hdr_chunk = new_chunk_id;
 
+	if (prev_chunk_id > 0)
+		yaffs_chunk_del(dev, prev_chunk_id, 1, __LINE__);
+
+	if (!yaffs_obj_cache_dirty(in))
+		in->dirty = 0;
+
+	/* If this was a shrink, then mark the block
+	 * that the chunk lives on */
+	if (is_shrink) {
+		bi = yaffs_get_block_info(in->my_dev,
+					  new_chunk_id /
+					  in->my_dev->param.chunks_per_block);
+		bi->has_shrink_hdr = 1;
 	}
 
-	if (buffer)
-		yaffs_release_temp_buffer(dev, buffer, __LINE__);
 
-	return ret_val;
+	return new_chunk_id;
 }
 
 /*--------------------- File read/write ------------------------
@@ -3540,21 +3419,17 @@
 
 int yaffs_file_rd(struct yaffs_obj *in, u8 * buffer, loff_t offset, int n_bytes)
 {
-
 	int chunk;
 	u32 start;
 	int n_copy;
 	int n = n_bytes;
 	int n_done = 0;
 	struct yaffs_cache *cache;
-
 	struct yaffs_dev *dev;
 
 	dev = in->my_dev;
 
 	while (n > 0) {
-		/* chunk = offset / dev->data_bytes_per_chunk + 1; */
-		/* start = offset % dev->data_bytes_per_chunk; */
 		yaffs_addr_to_chunk(dev, offset, &chunk, &start);
 		chunk++;
 
@@ -3568,15 +3443,16 @@
 
 		cache = yaffs_find_chunk_cache(in, chunk);
 
-		/* If the chunk is already in the cache or it is less than a whole chunk
-		 * or we're using inband tags then use the cache (if there is caching)
-		 * else bypass the cache.
+		/* If the chunk is already in the cache or it is less than
+		 * a whole chunk or we're using inband tags then use the cache
+		 * (if there is caching) else bypass the cache.
 		 */
-		if (cache || n_copy != dev->data_bytes_per_chunk
-		    || dev->param.inband_tags) {
+		if (cache || n_copy != dev->data_bytes_per_chunk ||
+		    dev->param.inband_tags) {
 			if (dev->param.n_caches > 0) {
 
-				/* If we can't find the data in the cache, then load it up. */
+				/* If we can't find the data in the cache,
+				 * then load it up. */
 
 				if (!cache) {
 					cache =
@@ -3601,34 +3477,27 @@
 				/* Read into the local buffer then copy.. */
 
 				u8 *local_buffer =
-				    yaffs_get_temp_buffer(dev, __LINE__);
+				    yaffs_get_temp_buffer(dev);
 				yaffs_rd_data_obj(in, chunk, local_buffer);
 
 				memcpy(buffer, &local_buffer[start], n_copy);
 
-				yaffs_release_temp_buffer(dev, local_buffer,
-							  __LINE__);
+				yaffs_release_temp_buffer(dev, local_buffer);
 			}
-
 		} else {
-
-			/* A full chunk. Read directly into the supplied buffer. */
+			/* A full chunk. Read directly into the buffer. */
 			yaffs_rd_data_obj(in, chunk, buffer);
-
 		}
-
 		n -= n_copy;
 		offset += n_copy;
 		buffer += n_copy;
 		n_done += n_copy;
-
 	}
-
 	return n_done;
 }
 
-int yaffs_do_file_wr(struct yaffs_obj *in, const u8 * buffer, loff_t offset,
-		     int n_bytes, int write_trhrough)
+int yaffs_do_file_wr(struct yaffs_obj *in, const u8 *buffer, loff_t offset,
+		     int n_bytes, int write_through)
 {
 
 	int chunk;
@@ -3637,11 +3506,10 @@
 	int n = n_bytes;
 	int n_done = 0;
 	int n_writeback;
-	int start_write = offset;
+	loff_t start_write = offset;
 	int chunk_written = 0;
 	u32 n_bytes_read;
-	u32 chunk_start;
-
+	loff_t chunk_start;
 	struct yaffs_dev *dev;
 
 	dev = in->my_dev;
@@ -3649,11 +3517,12 @@
 	while (n > 0 && chunk_written >= 0) {
 		yaffs_addr_to_chunk(dev, offset, &chunk, &start);
 
-		if (chunk * dev->data_bytes_per_chunk + start != offset ||
+		if (((loff_t)chunk) *
+		    dev->data_bytes_per_chunk + start != offset ||
 		    start >= dev->data_bytes_per_chunk) {
 			yaffs_trace(YAFFS_TRACE_ERROR,
-				"AddrToChunk of offset %d gives chunk %d start %d",
-				(int)offset, chunk, start);
+				"AddrToChunk of offset %lld gives chunk %d start %d",
+				offset, chunk, start);
 		}
 		chunk++;	/* File pos to chunk in file offset */
 
@@ -3664,12 +3533,14 @@
 		if ((start + n) < dev->data_bytes_per_chunk) {
 			n_copy = n;
 
-			/* Now folks, to calculate how many bytes to write back....
-			 * If we're overwriting and not writing to then end of file then
-			 * we need to write back as much as was there before.
+			/* Now calculate how many bytes to write back....
+			 * If we're overwriting and not writing to then end of
+			 * file then we need to write back as much as was there
+			 * before.
 			 */
 
-			chunk_start = ((chunk - 1) * dev->data_bytes_per_chunk);
+			chunk_start = (((loff_t)(chunk - 1)) *
+					dev->data_bytes_per_chunk);
 
 			if (chunk_start > in->variant.file_variant.file_size)
 				n_bytes_read = 0;	/* Past end of file */
@@ -3685,27 +3556,30 @@
 			    (n_bytes_read >
 			     (start + n)) ? n_bytes_read : (start + n);
 
-			if (n_writeback < 0
-			    || n_writeback > dev->data_bytes_per_chunk)
-				YBUG();
+			if (n_writeback < 0 ||
+			    n_writeback > dev->data_bytes_per_chunk)
+				BUG();
 
 		} else {
 			n_copy = dev->data_bytes_per_chunk - start;
 			n_writeback = dev->data_bytes_per_chunk;
 		}
 
-		if (n_copy != dev->data_bytes_per_chunk
-		    || dev->param.inband_tags) {
-			/* An incomplete start or end chunk (or maybe both start and end chunk),
-			 * or we're using inband tags, so we want to use the cache buffers.
+		if (n_copy != dev->data_bytes_per_chunk ||
+		    dev->param.inband_tags) {
+			/* An incomplete start or end chunk (or maybe both
+			 * start and end chunk), or we're using inband tags,
+			 * so we want to use the cache buffers.
 			 */
 			if (dev->param.n_caches > 0) {
 				struct yaffs_cache *cache;
-				/* If we can't find the data in the cache, then load the cache */
+
+				/* If we can't find the data in the cache, then
+				 * load the cache */
 				cache = yaffs_find_chunk_cache(in, chunk);
 
-				if (!cache
-				    && yaffs_check_alloc_available(dev, 1)) {
+				if (!cache &&
+				    yaffs_check_alloc_available(dev, 1)) {
 					cache = yaffs_grab_chunk_cache(dev);
 					cache->object = in;
 					cache->chunk_id = chunk;
@@ -3717,8 +3591,9 @@
 					   !cache->dirty &&
 					   !yaffs_check_alloc_available(dev,
 									1)) {
-					/* Drop the cache if it was a read cache item and
-					 * no space check has been made for it.
+					/* Drop the cache if it was a read cache
+					 * item and no space check has been made
+					 * for it.
 					 */
 					cache = NULL;
 				}
@@ -3733,7 +3608,7 @@
 					cache->locked = 0;
 					cache->n_bytes = n_writeback;
 
-					if (write_trhrough) {
+					if (write_through) {
 						chunk_written =
 						    yaffs_wr_data_obj
 						    (cache->object,
@@ -3742,20 +3617,18 @@
 						     cache->n_bytes, 1);
 						cache->dirty = 0;
 					}
-
 				} else {
-					chunk_written = -1;	/* fail the write */
+					chunk_written = -1;	/* fail write */
 				}
 			} else {
-				/* An incomplete start or end chunk (or maybe both start and end chunk)
-				 * Read into the local buffer then copy, then copy over and write back.
+				/* An incomplete start or end chunk (or maybe
+				 * both start and end chunk). Read into the
+				 * local buffer then copy over and write back.
 				 */
 
-				u8 *local_buffer =
-				    yaffs_get_temp_buffer(dev, __LINE__);
+				u8 *local_buffer = yaffs_get_temp_buffer(dev);
 
 				yaffs_rd_data_obj(in, chunk, local_buffer);
-
 				memcpy(&local_buffer[start], buffer, n_copy);
 
 				chunk_written =
@@ -3763,19 +3636,17 @@
 						      local_buffer,
 						      n_writeback, 0);
 
-				yaffs_release_temp_buffer(dev, local_buffer,
-							  __LINE__);
-
+				yaffs_release_temp_buffer(dev, local_buffer);
 			}
-
 		} else {
-			/* A full chunk. Write directly from the supplied buffer. */
+			/* A full chunk. Write directly from the buffer. */
 
 			chunk_written =
 			    yaffs_wr_data_obj(in, chunk, buffer,
 					      dev->data_bytes_per_chunk, 0);
 
-			/* Since we've overwritten the cached data, we better invalidate it. */
+			/* Since we've overwritten the cached data,
+			 * we better invalidate it. */
 			yaffs_invalidate_chunk_cache(in, chunk);
 		}
 
@@ -3785,7 +3656,6 @@
 			buffer += n_copy;
 			n_done += n_copy;
 		}
-
 	}
 
 	/* Update file object */
@@ -3794,31 +3664,38 @@
 		in->variant.file_variant.file_size = (start_write + n_done);
 
 	in->dirty = 1;
-
 	return n_done;
 }
 
-int yaffs_wr_file(struct yaffs_obj *in, const u8 * buffer, loff_t offset,
-		  int n_bytes, int write_trhrough)
+int yaffs_wr_file(struct yaffs_obj *in, const u8 *buffer, loff_t offset,
+		  int n_bytes, int write_through)
 {
 	yaffs2_handle_hole(in, offset);
-	return yaffs_do_file_wr(in, buffer, offset, n_bytes, write_trhrough);
+	return yaffs_do_file_wr(in, buffer, offset, n_bytes, write_through);
 }
 
 /* ---------------------- File resizing stuff ------------------ */
 
-static void yaffs_prune_chunks(struct yaffs_obj *in, int new_size)
+static void yaffs_prune_chunks(struct yaffs_obj *in, loff_t new_size)
 {
 
 	struct yaffs_dev *dev = in->my_dev;
-	int old_size = in->variant.file_variant.file_size;
-
-	int last_del = 1 + (old_size - 1) / dev->data_bytes_per_chunk;
-
-	int start_del = 1 + (new_size + dev->data_bytes_per_chunk - 1) /
-	    dev->data_bytes_per_chunk;
+	loff_t old_size = in->variant.file_variant.file_size;
 	int i;
 	int chunk_id;
+	u32 dummy;
+	int last_del;
+	int start_del;
+
+	if (old_size > 0)
+		yaffs_addr_to_chunk(dev, old_size - 1, &last_del, &dummy);
+	else
+		last_del = 0;
+
+	yaffs_addr_to_chunk(dev, new_size + dev->data_bytes_per_chunk - 1,
+				&start_del, &dummy);
+	last_del++;
+	start_del++;
 
 	/* Delete backwards so that we don't end up with holes if
 	 * power is lost part-way through the operation.
@@ -3830,23 +3707,23 @@
 		 */
 
 		chunk_id = yaffs_find_del_file_chunk(in, i, NULL);
-		if (chunk_id > 0) {
-			if (chunk_id <
-			    (dev->internal_start_block *
-			     dev->param.chunks_per_block)
-			    || chunk_id >=
-			    ((dev->internal_end_block +
-			      1) * dev->param.chunks_per_block)) {
-				yaffs_trace(YAFFS_TRACE_ALWAYS,
-					"Found daft chunk_id %d for %d",
-					chunk_id, i);
-			} else {
-				in->n_data_chunks--;
-				yaffs_chunk_del(dev, chunk_id, 1, __LINE__);
-			}
+
+		if (chunk_id < 1)
+			continue;
+
+		if (chunk_id <
+		    (dev->internal_start_block * dev->param.chunks_per_block) ||
+		    chunk_id >=
+		    ((dev->internal_end_block + 1) *
+		      dev->param.chunks_per_block)) {
+			yaffs_trace(YAFFS_TRACE_ALWAYS,
+				"Found daft chunk_id %d for %d",
+				chunk_id, i);
+		} else {
+			in->n_data_chunks--;
+			yaffs_chunk_del(dev, chunk_id, 1, __LINE__);
 		}
 	}
-
 }
 
 void yaffs_resize_file_down(struct yaffs_obj *obj, loff_t new_size)
@@ -3861,7 +3738,7 @@
 
 	if (new_partial != 0) {
 		int last_chunk = 1 + new_full;
-		u8 *local_buffer = yaffs_get_temp_buffer(dev, __LINE__);
+		u8 *local_buffer = yaffs_get_temp_buffer(dev);
 
 		/* Rewrite the last chunk with its new size and zero pad */
 		yaffs_rd_data_obj(obj, last_chunk, local_buffer);
@@ -3871,7 +3748,7 @@
 		yaffs_wr_data_obj(obj, last_chunk, local_buffer,
 				  new_partial, 1);
 
-		yaffs_release_temp_buffer(dev, local_buffer, __LINE__);
+		yaffs_release_temp_buffer(dev, local_buffer);
 	}
 
 	obj->variant.file_variant.file_size = new_size;
@@ -3882,7 +3759,7 @@
 int yaffs_resize_file(struct yaffs_obj *in, loff_t new_size)
 {
 	struct yaffs_dev *dev = in->my_dev;
-	int old_size = in->variant.file_variant.file_size;
+	loff_t old_size = in->variant.file_variant.file_size;
 
 	yaffs_flush_file_cache(in);
 	yaffs_invalidate_whole_cache(in);
@@ -3919,24 +3796,19 @@
 
 int yaffs_flush_file(struct yaffs_obj *in, int update_time, int data_sync)
 {
-	int ret_val;
-	if (in->dirty) {
-		yaffs_flush_file_cache(in);
-		if (data_sync)	/* Only sync data */
-			ret_val = YAFFS_OK;
-		else {
-			if (update_time)
-				yaffs_load_current_time(in, 0, 0);
+	if (!in->dirty)
+		return YAFFS_OK;
 
-			ret_val = (yaffs_update_oh(in, NULL, 0, 0, 0, NULL) >=
-				   0) ? YAFFS_OK : YAFFS_FAIL;
-		}
-	} else {
-		ret_val = YAFFS_OK;
-	}
+	yaffs_flush_file_cache(in);
 
-	return ret_val;
+	if (data_sync)
+		return YAFFS_OK;
 
+	if (update_time)
+		yaffs_load_current_time(in, 0, 0);
+
+	return (yaffs_update_oh(in, NULL, 0, 0, 0, NULL) >= 0) ?
+				YAFFS_OK : YAFFS_FAIL;
 }
 
 
@@ -3946,7 +3818,6 @@
  */
 static int yaffs_unlink_file_if_needed(struct yaffs_obj *in)
 {
-
 	int ret_val;
 	int del_now = 0;
 	struct yaffs_dev *dev = in->my_dev;
@@ -3971,14 +3842,13 @@
 		    yaffs_change_obj_name(in, in->my_dev->unlinked_dir,
 					  _Y("unlinked"), 0, 0);
 	}
-
 	return ret_val;
 }
 
-int yaffs_del_file(struct yaffs_obj *in)
+static int yaffs_del_file(struct yaffs_obj *in)
 {
 	int ret_val = YAFFS_OK;
-	int deleted;		/* Need to cache value on stack if in is freed */
+	int deleted;	/* Need to cache value on stack if in is freed */
 	struct yaffs_dev *dev = in->my_dev;
 
 	if (dev->param.disable_soft_del || dev->param.is_yaffs2)
@@ -4013,8 +3883,8 @@
 int yaffs_is_non_empty_dir(struct yaffs_obj *obj)
 {
 	return (obj &&
-	        obj->variant_type == YAFFS_OBJECT_TYPE_DIRECTORY) &&
-	        !(list_empty(&obj->variant.dir_variant.children));
+		obj->variant_type == YAFFS_OBJECT_TYPE_DIRECTORY) &&
+		!(list_empty(&obj->variant.dir_variant.children));
 }
 
 static int yaffs_del_dir(struct yaffs_obj *obj)
@@ -4028,8 +3898,7 @@
 
 static int yaffs_del_symlink(struct yaffs_obj *in)
 {
-	if (in->variant.symlink_variant.alias)
-		kfree(in->variant.symlink_variant.alias);
+	kfree(in->variant.symlink_variant.alias);
 	in->variant.symlink_variant.alias = NULL;
 
 	return yaffs_generic_obj_del(in);
@@ -4037,7 +3906,7 @@
 
 static int yaffs_del_link(struct yaffs_obj *in)
 {
-	/* remove this hardlink from the list assocaited with the equivalent
+	/* remove this hardlink from the list associated with the equivalent
 	 * object
 	 */
 	list_del_init(&in->hard_links);
@@ -4047,6 +3916,7 @@
 int yaffs_del_obj(struct yaffs_obj *obj)
 {
 	int ret_val = -1;
+
 	switch (obj->variant_type) {
 	case YAFFS_OBJECT_TYPE_FILE:
 		ret_val = yaffs_del_file(obj);
@@ -4073,20 +3943,20 @@
 		ret_val = 0;
 		break;		/* should not happen. */
 	}
-
 	return ret_val;
 }
 
 static int yaffs_unlink_worker(struct yaffs_obj *obj)
 {
-
 	int del_now = 0;
 
+	if (!obj)
+		return YAFFS_FAIL;
+
 	if (!obj->my_inode)
 		del_now = 1;
 
-	if (obj)
-		yaffs_update_parent(obj->parent);
+	yaffs_update_parent(obj->parent);
 
 	if (obj->variant_type == YAFFS_OBJECT_TYPE_HARDLINK) {
 		return yaffs_del_link(obj);
@@ -4100,7 +3970,7 @@
 		 * Instead, we do the following:
 		 * - Select a hardlink.
 		 * - Unhook it from the hard links
-		 * - Move it from its parent directory (so that the rename can work)
+		 * - Move it from its parent directory so that the rename works.
 		 * - Rename the object to the hardlink's name.
 		 * - Delete the hardlink
 		 */
@@ -4151,21 +4021,19 @@
 		return YAFFS_FAIL;
 	} else {
 		return yaffs_change_obj_name(obj, obj->my_dev->unlinked_dir,
-					     _Y("unlinked"), 0, 0);
-        }
+						_Y("unlinked"), 0, 0);
+	}
 }
 
 static int yaffs_unlink_obj(struct yaffs_obj *obj)
 {
-
 	if (obj && obj->unlink_allowed)
 		return yaffs_unlink_worker(obj);
 
 	return YAFFS_FAIL;
-
 }
 
-int yaffs_unlinker(struct yaffs_obj *dir, const YCHAR * name)
+int yaffs_unlinker(struct yaffs_obj *dir, const YCHAR *name)
 {
 	struct yaffs_obj *obj;
 
@@ -4176,8 +4044,8 @@
 /* Note:
  * If old_name is NULL then we take old_dir as the object to be renamed.
  */
-int yaffs_rename_obj(struct yaffs_obj *old_dir, const YCHAR * old_name,
-		     struct yaffs_obj *new_dir, const YCHAR * new_name)
+int yaffs_rename_obj(struct yaffs_obj *old_dir, const YCHAR *old_name,
+		     struct yaffs_obj *new_dir, const YCHAR *new_name)
 {
 	struct yaffs_obj *obj = NULL;
 	struct yaffs_obj *existing_target = NULL;
@@ -4185,10 +4053,14 @@
 	int result;
 	struct yaffs_dev *dev;
 
-	if (!old_dir || old_dir->variant_type != YAFFS_OBJECT_TYPE_DIRECTORY)
-		YBUG();
-	if (!new_dir || new_dir->variant_type != YAFFS_OBJECT_TYPE_DIRECTORY)
-		YBUG();
+	if (!old_dir || old_dir->variant_type != YAFFS_OBJECT_TYPE_DIRECTORY) {
+		BUG();
+		return YAFFS_FAIL;
+	}
+	if (!new_dir || new_dir->variant_type != YAFFS_OBJECT_TYPE_DIRECTORY) {
+		BUG();
+		return YAFFS_FAIL;
+	}
 
 	dev = old_dir->my_dev;
 
@@ -4197,8 +4069,8 @@
 	 * While look-up is case insensitive, the name isn't.
 	 * Therefore we might want to change x.txt to X.txt
 	 */
-	if (old_dir == new_dir && 
-		old_name && new_name && 
+	if (old_dir == new_dir &&
+		old_name && new_name &&
 		strcmp(old_name, new_name) == 0)
 		force = 1;
 #endif
@@ -4208,26 +4080,24 @@
 		/* ENAMETOOLONG */
 		return YAFFS_FAIL;
 
-	if(old_name)
+	if (old_name)
 		obj = yaffs_find_by_name(old_dir, old_name);
 	else{
 		obj = old_dir;
 		old_dir = obj->parent;
 	}
 
-
 	if (obj && obj->rename_allowed) {
-
-		/* Now do the handling for an existing target, if there is one */
-
+		/* Now handle an existing target, if there is one */
 		existing_target = yaffs_find_by_name(new_dir, new_name);
-		if (yaffs_is_non_empty_dir(existing_target)){
+		if (yaffs_is_non_empty_dir(existing_target)) {
 			return YAFFS_FAIL;	/* ENOTEMPTY */
 		} else if (existing_target && existing_target != obj) {
 			/* Nuke the target first, using shadowing,
 			 * but only if it isn't the same object.
 			 *
-			 * Note we must disable gc otherwise it can mess up the shadowing.
+			 * Note we must disable gc here otherwise it can mess
+			 * up the shadowing.
 			 *
 			 */
 			dev->gc_disable = 1;
@@ -4256,12 +4126,7 @@
 {
 	struct yaffs_obj *obj;
 
-	if (!backward_scanning) {
-		/* Handle YAFFS1 forward scanning case
-		 * For YAFFS1 we always do the deletion
-		 */
-
-	} else {
+	if (backward_scanning) {
 		/* Handle YAFFS2 case (backward scanning)
 		 * If the shadowed object exists then ignore.
 		 */
@@ -4270,7 +4135,8 @@
 			return;
 	}
 
-	/* Let's create it (if it does not exist) assuming it is a file so that it can do shrinking etc.
+	/* Let's create it (if it does not exist) assuming it is a file so that
+	 * it can do shrinking etc.
 	 * We put it in unlinked dir to be cleaned up after the scanning
 	 */
 	obj =
@@ -4280,22 +4146,20 @@
 	obj->is_shadowed = 1;
 	yaffs_add_obj_to_dir(dev->unlinked_dir, obj);
 	obj->variant.file_variant.shrink_size = 0;
-	obj->valid = 1;		/* So that we don't read any other info for this file */
-
+	obj->valid = 1;		/* So that we don't read any other info. */
 }
 
-void yaffs_link_fixup(struct yaffs_dev *dev, struct yaffs_obj *hard_list)
+void yaffs_link_fixup(struct yaffs_dev *dev, struct list_head *hard_list)
 {
+	struct list_head *lh;
+	struct list_head *save;
 	struct yaffs_obj *hl;
 	struct yaffs_obj *in;
 
-	while (hard_list) {
-		hl = hard_list;
-		hard_list = (struct yaffs_obj *)(hard_list->hard_links.next);
-
+	list_for_each_safe(lh, save, hard_list) {
+		hl = list_entry(lh, struct yaffs_obj, hard_links);
 		in = yaffs_find_by_number(dev,
-					  hl->variant.
-					  hardlink_variant.equiv_id);
+					hl->variant.hardlink_variant.equiv_id);
 
 		if (in) {
 			/* Add the hardlink pointers */
@@ -4307,7 +4171,6 @@
 			 */
 			hl->variant.hardlink_variant.equiv_obj = NULL;
 			INIT_LIST_HEAD(&hl->hard_links);
-
 		}
 	}
 }
@@ -4327,19 +4190,14 @@
 	/* Soft delete all the unlinked files */
 	list_for_each_safe(i, n,
 			   &dev->unlinked_dir->variant.dir_variant.children) {
-		if (i) {
-			l = list_entry(i, struct yaffs_obj, siblings);
-			yaffs_del_obj(l);
-		}
+		l = list_entry(i, struct yaffs_obj, siblings);
+		yaffs_del_obj(l);
 	}
 
 	list_for_each_safe(i, n, &dev->del_dir->variant.dir_variant.children) {
-		if (i) {
-			l = list_entry(i, struct yaffs_obj, siblings);
-			yaffs_del_obj(l);
-		}
+		l = list_entry(i, struct yaffs_obj, siblings);
+		yaffs_del_obj(l);
 	}
-
 }
 
 /*
@@ -4350,13 +4208,14 @@
  * - Directly or indirectly under root.
  *
  * Note:
- *  This code assumes that we don't ever change the current relationships between
- *  directories:
+ *  This code assumes that we don't ever change the current relationships
+ *  between directories:
  *   root_dir->parent == unlinked_dir->parent == del_dir->parent == NULL
  *   lost-n-found->parent == root_dir
  *
- * This fixes the problem where directories might have inadvertently been deleted
- * leaving the object "hanging" without being rooted in the directory tree.
+ * This fixes the problem where directories might have inadvertently been
+ * deleted leaving the object "hanging" without being rooted in the
+ * directory tree.
  */
 
 static int yaffs_has_null_parent(struct yaffs_dev *dev, struct yaffs_obj *obj)
@@ -4385,45 +4244,42 @@
 
 	for (i = 0; i < YAFFS_NOBJECT_BUCKETS; i++) {
 		list_for_each_safe(lh, n, &dev->obj_bucket[i].list) {
-			if (lh) {
-				obj =
-				    list_entry(lh, struct yaffs_obj, hash_link);
-				parent = obj->parent;
-
-				if (yaffs_has_null_parent(dev, obj)) {
-					/* These directories are not hanging */
-					hanging = 0;
-				} else if (!parent
-					   || parent->variant_type !=
-					   YAFFS_OBJECT_TYPE_DIRECTORY) {
-					hanging = 1;
-				} else if (yaffs_has_null_parent(dev, parent)) {
-					hanging = 0;
-				} else {
-					/*
-					 * Need to follow the parent chain to see if it is hanging.
-					 */
-					hanging = 0;
-					depth_limit = 100;
+			obj = list_entry(lh, struct yaffs_obj, hash_link);
+			parent = obj->parent;
 
-					while (parent != dev->root_dir &&
-					       parent->parent &&
-					       parent->parent->variant_type ==
-					       YAFFS_OBJECT_TYPE_DIRECTORY
-					       && depth_limit > 0) {
-						parent = parent->parent;
-						depth_limit--;
-					}
-					if (parent != dev->root_dir)
-						hanging = 1;
-				}
-				if (hanging) {
-					yaffs_trace(YAFFS_TRACE_SCAN,
-						"Hanging object %d moved to lost and found",
-						obj->obj_id);
-					yaffs_add_obj_to_dir(dev->lost_n_found,
-							     obj);
+			if (yaffs_has_null_parent(dev, obj)) {
+				/* These directories are not hanging */
+				hanging = 0;
+			} else if (!parent ||
+				   parent->variant_type !=
+				   YAFFS_OBJECT_TYPE_DIRECTORY) {
+				hanging = 1;
+			} else if (yaffs_has_null_parent(dev, parent)) {
+				hanging = 0;
+			} else {
+				/*
+				 * Need to follow the parent chain to
+				 * see if it is hanging.
+				 */
+				hanging = 0;
+				depth_limit = 100;
+
+				while (parent != dev->root_dir &&
+				       parent->parent &&
+				       parent->parent->variant_type ==
+				       YAFFS_OBJECT_TYPE_DIRECTORY &&
+				       depth_limit > 0) {
+					parent = parent->parent;
+					depth_limit--;
 				}
+				if (parent != dev->root_dir)
+					hanging = 1;
+			}
+			if (hanging) {
+				yaffs_trace(YAFFS_TRACE_SCAN,
+					"Hanging object %d moved to lost and found",
+					obj->obj_id);
+				yaffs_add_obj_to_dir(dev->lost_n_found, obj);
 			}
 		}
 	}
@@ -4439,25 +4295,17 @@
 	struct list_head *n;
 
 	if (dir->variant_type != YAFFS_OBJECT_TYPE_DIRECTORY)
-		YBUG();
+		BUG();
 
 	list_for_each_safe(lh, n, &dir->variant.dir_variant.children) {
-		if (lh) {
-			obj = list_entry(lh, struct yaffs_obj, siblings);
-			if (obj->variant_type == YAFFS_OBJECT_TYPE_DIRECTORY)
-				yaffs_del_dir_contents(obj);
-
-			yaffs_trace(YAFFS_TRACE_SCAN,
-				"Deleting lost_found object %d",
-				obj->obj_id);
-
-			/* Need to use UnlinkObject since Delete would not handle
-			 * hardlinked objects correctly.
-			 */
-			yaffs_unlink_obj(obj);
-		}
+		obj = list_entry(lh, struct yaffs_obj, siblings);
+		if (obj->variant_type == YAFFS_OBJECT_TYPE_DIRECTORY)
+			yaffs_del_dir_contents(obj);
+		yaffs_trace(YAFFS_TRACE_SCAN,
+			"Deleting lost_found object %d",
+			obj->obj_id);
+		yaffs_unlink_obj(obj);
 	}
-
 }
 
 static void yaffs_empty_l_n_f(struct yaffs_dev *dev)
@@ -4467,13 +4315,11 @@
 
 
 struct yaffs_obj *yaffs_find_by_name(struct yaffs_obj *directory,
-				     const YCHAR * name)
+				     const YCHAR *name)
 {
 	int sum;
-
 	struct list_head *i;
 	YCHAR buffer[YAFFS_MAX_NAME_LENGTH + 1];
-
 	struct yaffs_obj *l;
 
 	if (!name)
@@ -4483,45 +4329,40 @@
 		yaffs_trace(YAFFS_TRACE_ALWAYS,
 			"tragedy: yaffs_find_by_name: null pointer directory"
 			);
-		YBUG();
+		BUG();
 		return NULL;
 	}
 	if (directory->variant_type != YAFFS_OBJECT_TYPE_DIRECTORY) {
 		yaffs_trace(YAFFS_TRACE_ALWAYS,
 			"tragedy: yaffs_find_by_name: non-directory"
 			);
-		YBUG();
+		BUG();
 	}
 
 	sum = yaffs_calc_name_sum(name);
 
 	list_for_each(i, &directory->variant.dir_variant.children) {
-		if (i) {
-			l = list_entry(i, struct yaffs_obj, siblings);
+		l = list_entry(i, struct yaffs_obj, siblings);
 
-			if (l->parent != directory)
-				YBUG();
+		if (l->parent != directory)
+			BUG();
 
-			yaffs_check_obj_details_loaded(l);
+		yaffs_check_obj_details_loaded(l);
 
-			/* Special case for lost-n-found */
-			if (l->obj_id == YAFFS_OBJECTID_LOSTNFOUND) {
-				if (!strcmp(name, YAFFS_LOSTNFOUND_NAME))
-					return l;
-			} else if (l->sum == sum
-				   || l->hdr_chunk <= 0) {
-				/* LostnFound chunk called Objxxx
-				 * Do a real check
-				 */
-				yaffs_get_obj_name(l, buffer,
-						   YAFFS_MAX_NAME_LENGTH + 1);
-				if (strncmp
-				    (name, buffer, YAFFS_MAX_NAME_LENGTH) == 0)
-					return l;
-			}
+		/* Special case for lost-n-found */
+		if (l->obj_id == YAFFS_OBJECTID_LOSTNFOUND) {
+			if (!strcmp(name, YAFFS_LOSTNFOUND_NAME))
+				return l;
+		} else if (l->sum == sum || l->hdr_chunk <= 0) {
+			/* LostnFound chunk called Objxxx
+			 * Do a real check
+			 */
+			yaffs_get_obj_name(l, buffer,
+				YAFFS_MAX_NAME_LENGTH + 1);
+			if (!strncmp(name, buffer, YAFFS_MAX_NAME_LENGTH))
+				return l;
 		}
 	}
-
 	return NULL;
 }
 
@@ -4532,7 +4373,6 @@
 struct yaffs_obj *yaffs_get_equivalent_obj(struct yaffs_obj *obj)
 {
 	if (obj && obj->variant_type == YAFFS_OBJECT_TYPE_HARDLINK) {
-		/* We want the object id of the equivalent object, not this one */
 		obj = obj->variant.hardlink_variant.equiv_obj;
 		yaffs_check_obj_details_loaded(obj);
 	}
@@ -4552,13 +4392,13 @@
  * system to share files.
  *
  * These automatic unicode are stored slightly differently...
- *  - If the name can fit in the ASCII character space then they are saved as 
+ *  - If the name can fit in the ASCII character space then they are saved as
  *    ascii names as per above.
  *  - If the name needs Unicode then the name is saved in Unicode
  *    starting at oh->name[1].
 
  */
-static void yaffs_fix_null_name(struct yaffs_obj *obj, YCHAR * name,
+static void yaffs_fix_null_name(struct yaffs_obj *obj, YCHAR *name,
 				int buffer_size)
 {
 	/* Create an object name if we could not find one. */
@@ -4580,23 +4420,17 @@
 	}
 }
 
-int yaffs_get_obj_name(struct yaffs_obj *obj, YCHAR * name, int buffer_size)
+int yaffs_get_obj_name(struct yaffs_obj *obj, YCHAR *name, int buffer_size)
 {
 	memset(name, 0, buffer_size * sizeof(YCHAR));
-
 	yaffs_check_obj_details_loaded(obj);
-
 	if (obj->obj_id == YAFFS_OBJECTID_LOSTNFOUND) {
 		strncpy(name, YAFFS_LOSTNFOUND_NAME, buffer_size - 1);
-	}
-#ifndef CONFIG_YAFFS_NO_SHORT_NAMES
-	else if (obj->short_name[0]) {
+	} else if (obj->short_name[0]) {
 		strcpy(name, obj->short_name);
-	}
-#endif
-	else if (obj->hdr_chunk > 0) {
+	} else if (obj->hdr_chunk > 0) {
 		int result;
-		u8 *buffer = yaffs_get_temp_buffer(obj->my_dev, __LINE__);
+		u8 *buffer = yaffs_get_temp_buffer(obj->my_dev);
 
 		struct yaffs_obj_hdr *oh = (struct yaffs_obj_hdr *)buffer;
 
@@ -4610,7 +4444,7 @@
 		yaffs_load_name_from_oh(obj->my_dev, name, oh->name,
 					buffer_size);
 
-		yaffs_release_temp_buffer(obj->my_dev, buffer, __LINE__);
+		yaffs_release_temp_buffer(obj->my_dev, buffer);
 	}
 
 	yaffs_fix_null_name(obj, name, buffer_size);
@@ -4618,7 +4452,7 @@
 	return strnlen(name, YAFFS_MAX_NAME_LENGTH);
 }
 
-int yaffs_get_obj_length(struct yaffs_obj *obj)
+loff_t yaffs_get_obj_length(struct yaffs_obj *obj)
 {
 	/* Dereference any hard linking */
 	obj = yaffs_get_equivalent_obj(obj);
@@ -4683,6 +4517,8 @@
 			return DT_BLK;
 		if (S_ISSOCK(obj->yst_mode))
 			return DT_SOCK;
+		return DT_REG;
+		break;
 	default:
 		return DT_REG;
 		break;
@@ -4702,13 +4538,10 @@
 
 static int yaffs_check_dev_fns(const struct yaffs_dev *dev)
 {
-
 	/* Common functions, gotta have */
 	if (!dev->param.erase_fn || !dev->param.initialise_flash_fn)
 		return 0;
 
-#ifdef CONFIG_YAFFS_YAFFS2
-
 	/* Can use the "with tags" style interface for yaffs1 or yaffs2 */
 	if (dev->param.write_chunk_tags_fn &&
 	    dev->param.read_chunk_tags_fn &&
@@ -4716,7 +4549,6 @@
 	    !dev->param.read_chunk_fn &&
 	    dev->param.bad_block_fn && dev->param.query_block_fn)
 		return 1;
-#endif
 
 	/* Can use the "spare" style interface for yaffs1 */
 	if (!dev->param.is_yaffs2 &&
@@ -4732,17 +4564,13 @@
 
 static int yaffs_create_initial_dir(struct yaffs_dev *dev)
 {
-	/* Initialise the unlinked, deleted, root and lost and found directories */
-
+	/* Initialise the unlinked, deleted, root and lost+found directories */
 	dev->lost_n_found = dev->root_dir = NULL;
 	dev->unlinked_dir = dev->del_dir = NULL;
-
 	dev->unlinked_dir =
 	    yaffs_create_fake_dir(dev, YAFFS_OBJECTID_UNLINKED, S_IFDIR);
-
 	dev->del_dir =
 	    yaffs_create_fake_dir(dev, YAFFS_OBJECTID_DELETED, S_IFDIR);
-
 	dev->root_dir =
 	    yaffs_create_fake_dir(dev, YAFFS_OBJECTID_ROOT,
 				  YAFFS_ROOT_MODE | S_IFDIR);
@@ -4755,7 +4583,6 @@
 		yaffs_add_obj_to_dir(dev->root_dir, dev->lost_n_found);
 		return YAFFS_OK;
 	}
-
 	return YAFFS_FAIL;
 }
 
@@ -4765,7 +4592,7 @@
 	unsigned x;
 	int bits;
 
-	yaffs_trace(YAFFS_TRACE_TRACING, "yaffs: yaffs_guts_initialise()" );
+	yaffs_trace(YAFFS_TRACE_TRACING, "yaffs: yaffs_guts_initialise()");
 
 	/* Check stuff that must be set */
 
@@ -4776,6 +4603,11 @@
 		return YAFFS_FAIL;
 	}
 
+	if (dev->is_mounted) {
+		yaffs_trace(YAFFS_TRACE_ALWAYS, "device already mounted");
+		return YAFFS_FAIL;
+	}
+
 	dev->internal_start_block = dev->param.start_block;
 	dev->internal_end_block = dev->param.end_block;
 	dev->block_offset = 0;
@@ -4800,9 +4632,9 @@
 		(dev->param.inband_tags && !dev->param.is_yaffs2) ||
 		 dev->param.chunks_per_block < 2 ||
 		 dev->param.n_reserved_blocks < 2 ||
-		dev->internal_start_block <= 0 || 
-		dev->internal_end_block <= 0 || 
-		dev->internal_end_block <= 
+		dev->internal_start_block <= 0 ||
+		dev->internal_end_block <= 0 ||
+		dev->internal_end_block <=
 		(dev->internal_start_block + dev->param.n_reserved_blocks + 2)
 		) {
 		/* otherwise it is too small */
@@ -4836,12 +4668,7 @@
 		return YAFFS_FAIL;
 	}
 
-	if (dev->is_mounted) {
-		yaffs_trace(YAFFS_TRACE_ALWAYS, "device already mounted");
-		return YAFFS_FAIL;
-	}
-
-	/* Finished with most checks. One or two more checks happen later on too. */
+	/* Finished with most checks. Further checks happen later on too. */
 
 	dev->is_mounted = 1;
 
@@ -4878,7 +4705,7 @@
 			dev->tnode_width = bits;
 	} else {
 		dev->tnode_width = 16;
-        }
+	}
 
 	dev->tnode_mask = (1 << dev->tnode_width) - 1;
 
@@ -4909,7 +4736,7 @@
 		return YAFFS_FAIL;
 	}
 
-	/* OK, we've finished verifying the device, lets continue with initialisation */
+	/* Finished verifying the device, continue with initialisation */
 
 	/* More device initialisation */
 	dev->all_gcs = 0;
@@ -4929,7 +4756,8 @@
 	dev->n_erase_failures = 0;
 	dev->n_erased_blocks = 0;
 	dev->gc_disable = 0;
-	dev->has_pending_prioritised_gc = 1;	/* Assume the worst for now, will get fixed on first GC */
+	dev->has_pending_prioritised_gc = 1;
+		/* Assume the worst for now, will get fixed on first GC */
 	INIT_LIST_HEAD(&dev->dirty_dirs);
 	dev->oldest_dirty_seq = 0;
 	dev->oldest_dirty_block = 0;
@@ -4991,18 +4819,24 @@
 	if (!init_failed && !yaffs_create_initial_dir(dev))
 		init_failed = 1;
 
+	if (!init_failed && dev->param.is_yaffs2 &&
+		!dev->param.disable_summary &&
+		!yaffs_summary_init(dev))
+		init_failed = 1;
+
 	if (!init_failed) {
 		/* Now scan the flash. */
 		if (dev->param.is_yaffs2) {
 			if (yaffs2_checkpt_restore(dev)) {
 				yaffs_check_obj_details_loaded(dev->root_dir);
-				yaffs_trace(YAFFS_TRACE_CHECKPOINT | YAFFS_TRACE_MOUNT,
+				yaffs_trace(YAFFS_TRACE_CHECKPOINT |
+					YAFFS_TRACE_MOUNT,
 					"yaffs: restored from checkpoint"
 					);
 			} else {
 
-				/* Clean up the mess caused by an aborted checkpoint load
-				 * and scan backwards.
+				/* Clean up the mess caused by an aborted
+				 * checkpoint load then scan backwards.
 				 */
 				yaffs_deinit_blocks(dev);
 
@@ -5030,7 +4864,7 @@
 			}
 		} else if (!yaffs1_scan(dev)) {
 			init_failed = 1;
-                }
+		}
 
 		yaffs_strip_deleted_objs(dev);
 		yaffs_fix_hanging_objs(dev);
@@ -5052,7 +4886,7 @@
 	dev->n_page_writes = 0;
 	dev->n_erasures = 0;
 	dev->n_gc_copies = 0;
-	dev->n_retired_writes = 0;
+	dev->n_retried_writes = 0;
 
 	dev->n_retired_blocks = 0;
 
@@ -5066,7 +4900,6 @@
 	yaffs_trace(YAFFS_TRACE_TRACING,
 	  "yaffs: yaffs_guts_initialise() done.");
 	return YAFFS_OK;
-
 }
 
 void yaffs_deinitialise(struct yaffs_dev *dev)
@@ -5076,11 +4909,12 @@
 
 		yaffs_deinit_blocks(dev);
 		yaffs_deinit_tnodes_and_objs(dev);
+		yaffs_summary_deinit(dev);
+
 		if (dev->param.n_caches > 0 && dev->cache) {
 
 			for (i = 0; i < dev->param.n_caches; i++) {
-				if (dev->cache[i].data)
-					kfree(dev->cache[i].data);
+				kfree(dev->cache[i].data);
 				dev->cache[i].data = NULL;
 			}
 
@@ -5104,7 +4938,6 @@
 {
 	int n_free = 0;
 	int b;
-
 	struct yaffs_block_info *blk;
 
 	blk = dev->block_info;
@@ -5123,14 +4956,12 @@
 		}
 		blk++;
 	}
-
 	return n_free;
 }
 
 int yaffs_get_n_free_chunks(struct yaffs_dev *dev)
 {
 	/* This is what we report to the outside world */
-
 	int n_free;
 	int n_dirty_caches;
 	int blocks_for_checkpt;
@@ -5139,7 +4970,7 @@
 	n_free = dev->n_free_chunks;
 	n_free += dev->n_deleted_files;
 
-	/* Now count the number of dirty chunks in the cache and subtract those */
+	/* Now count and subtract the number of dirty chunks in the cache. */
 
 	for (n_dirty_caches = 0, i = 0; i < dev->param.n_caches; i++) {
 		if (dev->cache[i].dirty)
@@ -5151,7 +4982,7 @@
 	n_free -=
 	    ((dev->param.n_reserved_blocks + 1) * dev->param.chunks_per_block);
 
-	/* Now we figure out how much to reserve for the checkpoint and report that... */
+	/* Now figure checkpoint space and report that... */
 	blocks_for_checkpt = yaffs_calc_checkpt_blocks_required(dev);
 
 	n_free -= (blocks_for_checkpt * dev->param.chunks_per_block);
@@ -5160,5 +4991,63 @@
 		n_free = 0;
 
 	return n_free;
+}
+
+
+int yaffs_format_dev(struct yaffs_dev *dev)
+{
+	int i;
+	enum yaffs_block_state state;
+	u32 dummy;
 
+	if(dev->is_mounted)
+		return YAFFS_FAIL;
+
+	/*
+	* The runtime variables might not have been set up,
+	* so set up what we need.
+	*/
+	dev->internal_start_block = dev->param.start_block;
+	dev->internal_end_block = dev->param.end_block;
+	dev->block_offset = 0;
+	dev->chunk_offset = 0;
+
+	if (dev->param.start_block == 0) {
+		dev->internal_start_block = dev->param.start_block + 1;
+		dev->internal_end_block = dev->param.end_block + 1;
+		dev->block_offset = 1;
+		dev->chunk_offset = dev->param.chunks_per_block;
+	}
+
+	for (i = dev->internal_start_block; i <= dev->internal_end_block; i++) {
+		yaffs_query_init_block_state(dev, i, &state, &dummy);
+		if (state != YAFFS_BLOCK_STATE_DEAD)
+			yaffs_erase_block(dev, i);
+	}
+
+	return YAFFS_OK;
+}
+
+
+/*
+ * Marshalling functions to get loff_t file sizes into and out of
+ * object headers.
+ */
+void yaffs_oh_size_load(struct yaffs_obj_hdr *oh, loff_t fsize)
+{
+	oh->file_size_low = (fsize & 0xFFFFFFFF);
+	oh->file_size_high = ((fsize >> 32) & 0xFFFFFFFF);
+}
+
+loff_t yaffs_oh_to_size(struct yaffs_obj_hdr *oh)
+{
+	loff_t retval;
+
+	if (sizeof(loff_t) >= 8 && ~(oh->file_size_high))
+		retval = (((loff_t) oh->file_size_high) << 32) |
+			(((loff_t) oh->file_size_low) & 0xFFFFFFFF);
+	else
+		retval = (loff_t) oh->file_size_low;
+
+	return retval;
 }
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_guts.h linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_guts.h
--- linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_guts.h	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_guts.h	2014-07-29 17:28:38.819972000 +0800
@@ -1,7 +1,7 @@
 /*
  * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
  *
- * Copyright (C) 2002-2010 Aleph One Ltd.
+ * Copyright (C) 2002-2011 Aleph One Ltd.
  *   for Toby Churchill Ltd and Brightstar Engineering
  *
  * Created by Charles Manning <charles@aleph1.co.uk>
@@ -23,33 +23,50 @@
 
 /* Give us a  Y=0x59,
  * Give us an A=0x41,
- * Give us an FF=0xFF
+ * Give us an FF=0xff
  * Give us an S=0x53
  * And what have we got...
  */
-#define YAFFS_MAGIC			0x5941FF53
+#define YAFFS_MAGIC			0x5941ff53
 
-#define YAFFS_NTNODES_LEVEL0	  	16
+/*
+ * Tnodes form a tree with the tnodes in "levels"
+ * Levels greater than 0 hold 8 slots which point to other tnodes.
+ * Those at level 0 hold 16 slots which point to chunks in NAND.
+ *
+ * A maximum level of 8 thust supports files of size up to:
+ *
+ * 2^(3*MAX_LEVEL+4)
+ *
+ * Thus a max level of 8 supports files with up to 2^^28 chunks which gives
+ * a maximum file size of arounf 51Gbytees with 2k chunks.
+ */
+#define YAFFS_NTNODES_LEVEL0		16
 #define YAFFS_TNODES_LEVEL0_BITS	4
 #define YAFFS_TNODES_LEVEL0_MASK	0xf
 
-#define YAFFS_NTNODES_INTERNAL 		(YAFFS_NTNODES_LEVEL0 / 2)
-#define YAFFS_TNODES_INTERNAL_BITS 	(YAFFS_TNODES_LEVEL0_BITS - 1)
+#define YAFFS_NTNODES_INTERNAL		(YAFFS_NTNODES_LEVEL0 / 2)
+#define YAFFS_TNODES_INTERNAL_BITS	(YAFFS_TNODES_LEVEL0_BITS - 1)
 #define YAFFS_TNODES_INTERNAL_MASK	0x7
-#define YAFFS_TNODES_MAX_LEVEL		6
+#define YAFFS_TNODES_MAX_LEVEL		8
+#define YAFFS_TNODES_MAX_BITS		(YAFFS_TNODES_LEVEL0_BITS + \
+					YAFFS_TNODES_INTERNAL_BITS * \
+					YAFFS_TNODES_MAX_LEVEL)
+#define YAFFS_MAX_CHUNK_ID		((1 << YAFFS_TNODES_MAX_BITS) - 1)
+
+#define YAFFS_MAX_FILE_SIZE_32		0x7fffffff
 
-#ifndef CONFIG_YAFFS_NO_YAFFS1
+/* Constants for YAFFS1 mode */
 #define YAFFS_BYTES_PER_SPARE		16
 #define YAFFS_BYTES_PER_CHUNK		512
 #define YAFFS_CHUNK_SIZE_SHIFT		9
 #define YAFFS_CHUNKS_PER_BLOCK		32
-#define YAFFS_BYTES_PER_BLOCK		(YAFFS_CHUNKS_PER_BLOCK*YAFFS_BYTES_PER_CHUNK)
-#endif
+#define YAFFS_BYTES_PER_BLOCK	(YAFFS_CHUNKS_PER_BLOCK*YAFFS_BYTES_PER_CHUNK)
 
-#define YAFFS_MIN_YAFFS2_CHUNK_SIZE 	1024
+#define YAFFS_MIN_YAFFS2_CHUNK_SIZE	1024
 #define YAFFS_MIN_YAFFS2_SPARE_SIZE	32
 
-#define YAFFS_MAX_CHUNK_ID		0x000FFFFF
+
 
 #define YAFFS_ALLOCATION_NOBJECTS	100
 #define YAFFS_ALLOCATION_NTNODES	100
@@ -58,9 +75,11 @@
 #define YAFFS_NOBJECT_BUCKETS		256
 
 #define YAFFS_OBJECT_SPACE		0x40000
-#define YAFFS_MAX_OBJECT_ID		(YAFFS_OBJECT_SPACE -1)
+#define YAFFS_MAX_OBJECT_ID		(YAFFS_OBJECT_SPACE - 1)
 
-#define YAFFS_CHECKPOINT_VERSION 	4
+/* Binary data version stamps */
+#define YAFFS_SUMMARY_VERSION		1
+#define YAFFS_CHECKPOINT_VERSION	7
 
 #ifdef CONFIG_YAFFS_UNICODE
 #define YAFFS_MAX_NAME_LENGTH		127
@@ -78,10 +97,12 @@
 #define YAFFS_OBJECTID_UNLINKED		3
 #define YAFFS_OBJECTID_DELETED		4
 
+/* Fake object Id for summary data */
+#define YAFFS_OBJECTID_SUMMARY		0x10
+
 /* Pseudo object ids for checkpointing */
-#define YAFFS_OBJECTID_SB_HEADER	0x10
 #define YAFFS_OBJECTID_CHECKPOINT_DATA	0x20
-#define YAFFS_SEQUENCE_CHECKPOINT_DATA  0x21
+#define YAFFS_SEQUENCE_CHECKPOINT_DATA	0x21
 
 #define YAFFS_MAX_SHORT_OP_CACHES	20
 
@@ -97,14 +118,14 @@
  * The range is limited slightly to help distinguish bad numbers from good.
  * This also allows us to perhaps in the future use special numbers for
  * special purposes.
- * EFFFFF00 allows the allocation of 8 blocks per second (~1Mbytes) for 15 years,
+ * EFFFFF00 allows the allocation of 8 blocks/second (~1Mbytes) for 15 years,
  * and is a larger number than the lifetime of a 2GB device.
  */
 #define YAFFS_LOWEST_SEQUENCE_NUMBER	0x00001000
-#define YAFFS_HIGHEST_SEQUENCE_NUMBER	0xEFFFFF00
+#define YAFFS_HIGHEST_SEQUENCE_NUMBER	0xefffff00
 
 /* Special sequence number for bad block that failed to be marked bad */
-#define YAFFS_SEQUENCE_BAD_BLOCK	0xFFFF0000
+#define YAFFS_SEQUENCE_BAD_BLOCK	0xffff0000
 
 /* ChunkCache is used for short read/write operations.*/
 struct yaffs_cache {
@@ -117,12 +138,11 @@
 	u8 *data;
 };
 
-/* Tags structures in RAM
- * NB This uses bitfield. Bitfields should not straddle a u32 boundary otherwise
- * the structure size will get blown out.
+/* yaffs1 tags structures in RAM
+ * NB This uses bitfield. Bitfields should not straddle a u32 boundary
+ * otherwise the structure size will get blown out.
  */
 
-#ifndef CONFIG_YAFFS_NO_YAFFS1
 struct yaffs_tags {
 	unsigned chunk_id:20;
 	unsigned serial_number:2;
@@ -137,7 +157,6 @@
 	u8 as_bytes[8];
 };
 
-#endif
 
 /* Stuff used for extended tags in YAFFS2 */
 
@@ -160,11 +179,9 @@
 #define YAFFS_OBJECT_TYPE_MAX YAFFS_OBJECT_TYPE_SPECIAL
 
 struct yaffs_ext_tags {
-
-	unsigned validity0;
 	unsigned chunk_used;	/*  Status of the chunk: used or unused */
-	unsigned obj_id;	/* If 0 then this is not part of an object (unused) */
-	unsigned chunk_id;	/* If 0 then this is a header, else a data chunk */
+	unsigned obj_id;	/* If 0 this is not used */
+	unsigned chunk_id;	/* If 0 this is a header, else a data chunk */
 	unsigned n_bytes;	/* Only valid for data chunks */
 
 	/* The following stuff only has meaning when we read */
@@ -180,18 +197,15 @@
 
 	/* Extra info if this is an object header (YAFFS2 only) */
 
-	unsigned extra_available;	/* There is extra info available if this is not zero */
+	unsigned extra_available;	/* Extra info available if not zero */
 	unsigned extra_parent_id;	/* The parent object */
 	unsigned extra_is_shrink;	/* Is it a shrink header? */
 	unsigned extra_shadows;	/* Does this shadow another object? */
 
 	enum yaffs_obj_type extra_obj_type;	/* What object type? */
 
-	unsigned extra_length;	/* Length if it is a file */
-	unsigned extra_equiv_id;	/* Equivalent object Id if it is a hard link */
-
-	unsigned validity1;
-
+	loff_t extra_file_size;		/* Length if it is a file */
+	unsigned extra_equiv_id;	/* Equivalent object for a hard link */
 };
 
 /* Spare structure for YAFFS1 */
@@ -225,12 +239,15 @@
 	YAFFS_BLOCK_STATE_SCANNING,
 	/* Being scanned */
 
-	YAFFS_BLOCK_STATE_NEEDS_SCANNING,
-	/* The block might have something on it (ie it is allocating or full, perhaps empty)
-	 * but it needs to be scanned to determine its true state.
+	YAFFS_BLOCK_STATE_NEEDS_SCAN,
+	/* The block might have something on it (ie it is allocating or full,
+	 * perhaps empty) but it needs to be scanned to determine its true
+	 * state.
 	 * This state is only valid during scanning.
-	 * NB We tolerate empty because the pre-scanner might be incapable of deciding
-	 * However, if this state is returned on a YAFFS2 device, then we expect a sequence number
+	 * NB We tolerate empty because the pre-scanner might be incapable of
+	 * deciding
+	 * However, if this state is returned on a YAFFS2 device,
+	 * then we expect a sequence number
 	 */
 
 	YAFFS_BLOCK_STATE_EMPTY,
@@ -241,7 +258,8 @@
 	 * At least one page holds valid data.
 	 * This is the one currently being used for page
 	 * allocation. Should never be more than one of these.
-	 * If a block is only partially allocated at mount it is treated as full.
+	 * If a block is only partially allocated at mount it is treated as
+	 * full.
 	 */
 
 	YAFFS_BLOCK_STATE_FULL,
@@ -271,18 +289,20 @@
 
 	int soft_del_pages:10;	/* number of soft deleted pages */
 	int pages_in_use:10;	/* number of pages in use */
-	unsigned block_state:4;	/* One of the above block states. NB use unsigned because enum is sometimes an int */
-	u32 needs_retiring:1;	/* Data has failed on this block, need to get valid data off */
-	/* and retire the block. */
-	u32 skip_erased_check:1;	/* If this is set we can skip the erased check on this block */
-	u32 gc_prioritise:1;	/* An ECC check or blank check has failed on this block.
-				   It should be prioritised for GC */
-	u32 chunk_error_strikes:3;	/* How many times we've had ecc etc failures on this block and tried to reuse it */
+	unsigned block_state:4;	/* One of the above block states. */
+				/* NB use unsigned because enum is sometimes
+				 * an int */
+	u32 needs_retiring:1;	/* Data has failed on this block, */
+				/*need to get valid data off and retire*/
+	u32 skip_erased_check:1;/* Skip the erased check on this block */
+	u32 gc_prioritise:1;	/* An ECC check or blank check has failed.
+				   Block should be prioritised for GC */
+	u32 chunk_error_strikes:3;	/* How many times we've had ecc etc
+				failures on this block and tried to reuse it */
+	u32 has_summary:1;	/* The block has a summary */
 
-#ifdef CONFIG_YAFFS_YAFFS2
-	u32 has_shrink_hdr:1;	/* This block has at least one shrink object header */
+	u32 has_shrink_hdr:1;	/* This block has at least one shrink header */
 	u32 seq_number;		/* block sequence number for yaffs2 */
-#endif
 
 };
 
@@ -297,7 +317,7 @@
 	u16 sum_no_longer_used;	/* checksum of name. No longer used */
 	YCHAR name[YAFFS_MAX_NAME_LENGTH + 1];
 
-	/* The following apply to directories, files, symlinks - not hard links */
+	/* The following apply to all object types except for hard links */
 	u32 yst_mode;		/* protection */
 
 	u32 yst_uid;
@@ -307,7 +327,7 @@
 	u32 yst_ctime;
 
 	/* File size  applies to files only */
-	int file_size;
+	u32 file_size_low;
 
 	/* Equivalent object id applies to hard links only. */
 	int equiv_id;
@@ -315,7 +335,7 @@
 	/* Alias is for symlinks only. */
 	YCHAR alias[YAFFS_MAX_ALIAS_LENGTH + 1];
 
-	u32 yst_rdev;		/* device stuff for block and char devices (major/min) */
+	u32 yst_rdev;	/* stuff for block and char devices (major/min) */
 
 	u32 win_ctime[2];
 	u32 win_atime[2];
@@ -324,10 +344,12 @@
 	u32 inband_shadowed_obj_id;
 	u32 inband_is_shrink;
 
-	u32 reserved[2];
-	int shadows_obj;	/* This object header shadows the specified object if > 0 */
+	u32 file_size_high;
+	u32 reserved[1];
+	int shadows_obj;	/* This object header shadows the
+				specified object if > 0 */
 
-	/* is_shrink applies to object headers written when we shrink the file (ie resize) */
+	/* is_shrink applies to object headers written when wemake a hole. */
 	u32 is_shrink;
 
 };
@@ -347,9 +369,9 @@
  */
 
 struct yaffs_file_var {
-	u32 file_size;
-	u32 scanned_size;
-	u32 shrink_size;
+	loff_t file_size;
+	loff_t scanned_size;
+	loff_t shrink_size;
 	int top_level;
 	struct yaffs_tnode *top;
 };
@@ -378,35 +400,43 @@
 struct yaffs_obj {
 	u8 deleted:1;		/* This should only apply to unlinked files. */
 	u8 soft_del:1;		/* it has also been soft deleted */
-	u8 unlinked:1;		/* An unlinked file. The file should be in the unlinked directory. */
+	u8 unlinked:1;		/* An unlinked file.*/
 	u8 fake:1;		/* A fake object has no presence on NAND. */
-	u8 rename_allowed:1;	/* Some objects are not allowed to be renamed. */
+	u8 rename_allowed:1;	/* Some objects cannot be renamed. */
 	u8 unlink_allowed:1;
 	u8 dirty:1;		/* the object needs to be written to flash */
 	u8 valid:1;		/* When the file system is being loaded up, this
 				 * object might be created before the data
-				 * is available (ie. file data records appear before the header).
+				 * is available
+				 * ie. file data chunks encountered before
+				* the header.
 				 */
-	u8 lazy_loaded:1;	/* This object has been lazy loaded and is missing some detail */
+	u8 lazy_loaded:1;	/* This object has been lazy loaded and
+				 * is missing some detail */
 
-	u8 defered_free:1;	/* For Linux kernel. Object is removed from NAND, but is
-				 * still in the inode cache. Free of object is defered.
+	u8 defered_free:1;	/* Object is removed from NAND, but is
+				 * still in the inode cache.
+				 * Free of object is defered.
 				 * until the inode is released.
 				 */
-	u8 being_created:1;	/* This object is still being created so skip some checks. */
-	u8 is_shadowed:1;	/* This object is shadowed on the way to being renamed. */
+	u8 being_created:1;	/* This object is still being created
+				 * so skip some verification checks. */
+	u8 is_shadowed:1;	/* This object is shadowed on the way
+				 * to being renamed. */
+
+	u8 xattr_known:1;	/* We know if this has object has xattribs
+				 * or not. */
+	u8 has_xattr:1;		/* This object has xattribs.
+				 * Only valid if xattr_known. */
 
-	u8 xattr_known:1;	/* We know if this has object has xattribs or not. */
-	u8 has_xattr:1;		/* This object has xattribs. Valid if xattr_known. */
-
-	u8 serial;		/* serial number of chunk in NAND. Cached here */
+	u8 serial;		/* serial number of chunk in NAND.*/
 	u16 sum;		/* sum of the name to speed searching */
 
 	struct yaffs_dev *my_dev;	/* The device I'm on */
 
-	struct list_head hash_link;	/* list of objects in this hash bucket */
+	struct list_head hash_link;	/* list of objects in hash bucket */
 
-	struct list_head hard_links;	/* all the equivalent hard linked objects */
+	struct list_head hard_links;	/* hard linked object chain*/
 
 	/* directory structure stuff */
 	/* also used for linking up the free list */
@@ -416,15 +446,13 @@
 	/* Where's my object header in NAND? */
 	int hdr_chunk;
 
-	int n_data_chunks;	/* Number of data chunks attached to the file. */
+	int n_data_chunks;	/* Number of data chunks for this file. */
 
 	u32 obj_id;		/* the object id value */
 
 	u32 yst_mode;
 
-#ifndef CONFIG_YAFFS_NO_SHORT_NAMES
 	YCHAR short_name[YAFFS_SHORT_NAME_LENGTH + 1];
-#endif
 
 #ifdef CONFIG_YAFFS_WINCE
 	u32 win_ctime[2];
@@ -471,18 +499,17 @@
 	u8 unlink_allowed:1;
 	u8 serial;
 	int n_data_chunks;
-	u32 size_or_equiv_obj;
+	loff_t size_or_equiv_obj;
 };
 
 /*--------------------- Temporary buffers ----------------
  *
- * These are chunk-sized working buffers. Each device has a few
+ * These are chunk-sized working buffers. Each device has a few.
  */
 
 struct yaffs_buffer {
 	u8 *buffer;
-	int line;		/* track from whence this buffer was allocated */
-	int max_line;
+	int in_use;
 };
 
 /*----------------- Device ---------------------------------*/
@@ -497,26 +524,29 @@
 	 */
 
 	int inband_tags;	/* Use unband tags */
-	u32 total_bytes_per_chunk;	/* Should be >= 512, does not need to be a power of 2 */
+	u32 total_bytes_per_chunk;	/* Should be >= 512, does not need to
+					 be a power of 2 */
 	int chunks_per_block;	/* does not need to be a power of 2 */
 	int spare_bytes_per_chunk;	/* spare area size */
 	int start_block;	/* Start block we're allowed to use */
 	int end_block;		/* End block we're allowed to use */
-	int n_reserved_blocks;	/* We want this tuneable so that we can reduce */
-	/* reserved blocks on NOR and RAM. */
+	int n_reserved_blocks;	/* Tuneable so that we can reduce
+				 * reserved blocks on NOR and RAM. */
 
-	int n_caches;		/* If <= 0, then short op caching is disabled, else
-				 * the number of short op caches (don't use too many).
-				 * 10 to 20 is a good bet.
+	int n_caches;		/* If <= 0, then short op caching is disabled,
+				 * else the number of short op caches.
 				 */
-	int use_nand_ecc;	/* Flag to decide whether or not to use NANDECC on data (yaffs1) */
-	int no_tags_ecc;	/* Flag to decide whether or not to do ECC on packed tags (yaffs2) */
+	int use_nand_ecc;	/* Flag to decide whether or not to use
+				 * NAND driver ECC on data (yaffs1) */
+	int tags_9bytes;	/* Use 9 byte tags */
+	int no_tags_ecc;	/* Flag to decide whether or not to do ECC
+				 * on packed tags (yaffs2) */
 
 	int is_yaffs2;		/* Use yaffs2 mode on this device */
 
 	int empty_lost_n_found;	/* Auto-empty lost+found directory on mount */
 
-	int refresh_period;	/* How often we should check to do a block refresh */
+	int refresh_period;	/* How often to check for a block refresh */
 
 	/* Checkpoint control. Can be set before or after initialisation */
 	u8 skip_checkpt_rd;
@@ -526,47 +556,48 @@
 
 	/* NAND access functions (Must be set before calling YAFFS) */
 
-	int (*write_chunk_fn) (struct yaffs_dev * dev,
-			       int nand_chunk, const u8 * data,
-			       const struct yaffs_spare * spare);
-	int (*read_chunk_fn) (struct yaffs_dev * dev,
-			      int nand_chunk, u8 * data,
-			      struct yaffs_spare * spare);
-	int (*erase_fn) (struct yaffs_dev * dev, int flash_block);
-	int (*initialise_flash_fn) (struct yaffs_dev * dev);
-	int (*deinitialise_flash_fn) (struct yaffs_dev * dev);
-
-#ifdef CONFIG_YAFFS_YAFFS2
-	int (*write_chunk_tags_fn) (struct yaffs_dev * dev,
-				    int nand_chunk, const u8 * data,
-				    const struct yaffs_ext_tags * tags);
-	int (*read_chunk_tags_fn) (struct yaffs_dev * dev,
-				   int nand_chunk, u8 * data,
-				   struct yaffs_ext_tags * tags);
-	int (*bad_block_fn) (struct yaffs_dev * dev, int block_no);
-	int (*query_block_fn) (struct yaffs_dev * dev, int block_no,
-			       enum yaffs_block_state * state,
-			       u32 * seq_number);
-#endif
+	int (*write_chunk_fn) (struct yaffs_dev *dev,
+			       int nand_chunk, const u8 *data,
+			       const struct yaffs_spare *spare);
+	int (*read_chunk_fn) (struct yaffs_dev *dev,
+			      int nand_chunk, u8 *data,
+			      struct yaffs_spare *spare);
+	int (*erase_fn) (struct yaffs_dev *dev, int flash_block);
+	int (*initialise_flash_fn) (struct yaffs_dev *dev);
+	int (*deinitialise_flash_fn) (struct yaffs_dev *dev);
+
+	/* yaffs2 mode functions */
+	int (*write_chunk_tags_fn) (struct yaffs_dev *dev,
+				    int nand_chunk, const u8 *data,
+				    const struct yaffs_ext_tags *tags);
+	int (*read_chunk_tags_fn) (struct yaffs_dev *dev,
+				   int nand_chunk, u8 *data,
+				   struct yaffs_ext_tags *tags);
+	int (*bad_block_fn) (struct yaffs_dev *dev, int block_no);
+	int (*query_block_fn) (struct yaffs_dev *dev, int block_no,
+			       enum yaffs_block_state *state,
+			       u32 *seq_number);
 
 	/* The remove_obj_fn function must be supplied by OS flavours that
 	 * need it.
 	 * yaffs direct uses it to implement the faster readdir.
 	 * Linux uses it to protect the directory during unlocking.
 	 */
-	void (*remove_obj_fn) (struct yaffs_obj * obj);
+	void (*remove_obj_fn) (struct yaffs_obj *obj);
 
 	/* Callback to mark the superblock dirty */
-	void (*sb_dirty_fn) (struct yaffs_dev * dev);
+	void (*sb_dirty_fn) (struct yaffs_dev *dev);
 
 	/*  Callback to control garbage collection. */
-	unsigned (*gc_control) (struct yaffs_dev * dev);
+	unsigned (*gc_control) (struct yaffs_dev *dev);
 
 	/* Debug control flags. Don't use unless you know what you're doing */
-	int use_header_file_size;	/* Flag to determine if we should use file sizes from the header */
+	int use_header_file_size;	/* Flag to determine if we should use
+					 * file sizes from the header */
 	int disable_lazy_load;	/* Disable lazy loading on this device */
 	int wide_tnodes_disabled;	/* Set to disable wide tnodes */
-	int disable_soft_del;	/* yaffs 1 only: Set to disable the use of softdeletion. */
+	int disable_soft_del;	/* yaffs 1 only: Set to disable the use of
+				 * softdeletion. */
 
 	int defered_dir_update;	/* Set to defer directory updates */
 
@@ -574,6 +605,13 @@
 	int auto_unicode;
 #endif
 	int always_check_erased;	/* Force chunk erased check always on */
+
+	int disable_summary;
+
+	int max_objects;	/*
+				 * Set to limit the number of objects created.
+				 * 0 = no limit.
+				*/
 };
 
 struct yaffs_dev {
@@ -602,7 +640,7 @@
 
 	/* Stuff for figuring out file offset to chunk conversions */
 	u32 chunk_shift;	/* Shift value */
-	u32 chunk_div;		/* Divisor after shifting: 1 for power-of-2 sizes */
+	u32 chunk_div;		/* Divisor after shifting: 1 for 2^n sizes */
 	u32 chunk_mask;		/* Mask to use for power-of-2 case */
 
 	int is_mounted;
@@ -616,7 +654,7 @@
 	int chunk_offset;
 
 	/* Runtime checkpointing stuff */
-	int checkpt_page_seq;	/* running sequence number of checkpoint pages */
+	int checkpt_page_seq;	/* running sequence number of checkpt pages */
 	int checkpt_byte_count;
 	int checkpt_byte_offs;
 	u8 *checkpt_buffer;
@@ -630,13 +668,14 @@
 	u32 checkpt_sum;
 	u32 checkpt_xor;
 
-	int checkpoint_blocks_required;	/* Number of blocks needed to store current checkpoint set */
+	int checkpoint_blocks_required;	/* Number of blocks needed to store
+					 * current checkpoint set */
 
 	/* Block Info */
 	struct yaffs_block_info *block_info;
 	u8 *chunk_bits;		/* bitmap of chunks in use */
-	unsigned block_info_alt:1;	/* was allocated using alternative strategy */
-	unsigned chunk_bits_alt:1;	/* was allocated using alternative strategy */
+	unsigned block_info_alt:1;	/* allocated using alternative alloc */
+	unsigned chunk_bits_alt:1;	/* allocated using alternative alloc */
 	int chunk_bit_stride;	/* Number of bytes of chunk_bits per block.
 				 * Must be consistent with chunks_per_block.
 				 */
@@ -662,7 +701,8 @@
 	u32 *gc_cleanup_list;	/* objects to delete at the end of a GC. */
 	u32 n_clean_ups;
 
-	unsigned has_pending_prioritised_gc;	/* We think this device might have pending prioritised gcs */
+	unsigned has_pending_prioritised_gc;	/* We think this device might
+						have pending prioritised gcs */
 	unsigned gc_disable;
 	unsigned gc_block_finder;
 	unsigned gc_dirtiest;
@@ -671,16 +711,12 @@
 	unsigned gc_block;
 	unsigned gc_chunk;
 	unsigned gc_skip;
+	struct yaffs_summary_tags *gc_sum_tags;
 
 	/* Special directories */
 	struct yaffs_obj *root_dir;
 	struct yaffs_obj *lost_n_found;
 
-	/* Buffer areas for storing data to recover from write failures TODO
-	 *      u8            buffered_data[YAFFS_CHUNKS_PER_BLOCK][YAFFS_BYTES_PER_CHUNK];
-	 *      struct yaffs_spare buffered_spare[YAFFS_CHUNKS_PER_BLOCK];
-	 */
-
 	int buffered_block;	/* Which block is buffered here? */
 	int doing_buffered_block_rewrite;
 
@@ -688,9 +724,12 @@
 	int cache_last_use;
 
 	/* Stuff for background deletion and unlinked files. */
-	struct yaffs_obj *unlinked_dir;	/* Directory where unlinked and deleted files live. */
-	struct yaffs_obj *del_dir;	/* Directory where deleted objects are sent to disappear. */
-	struct yaffs_obj *unlinked_deletion;	/* Current file being background deleted. */
+	struct yaffs_obj *unlinked_dir;	/* Directory where unlinked and deleted
+					 files live. */
+	struct yaffs_obj *del_dir;	/* Directory where deleted objects are
+					sent to disappear. */
+	struct yaffs_obj *unlinked_deletion;	/* Current file being
+							background deleted. */
 	int n_deleted_files;	/* Count of files awaiting deletion; */
 	int n_unlinked_files;	/* Count of unlinked files. */
 	int n_bg_deletions;	/* Count of background deletions. */
@@ -703,17 +742,23 @@
 	int unmanaged_buffer_deallocs;
 
 	/* yaffs2 runtime stuff */
-	unsigned seq_number;	/* Sequence number of currently allocating block */
+	unsigned seq_number;	/* Sequence number of currently
+					allocating block */
 	unsigned oldest_dirty_seq;
 	unsigned oldest_dirty_block;
 
 	/* Block refreshing */
-	int refresh_skip;	/* A skip down counter. Refresh happens when this gets to zero. */
+	int refresh_skip;	/* A skip down counter.
+				 * Refresh happens when this gets to zero. */
 
 	/* Dirty directory handling */
 	struct list_head dirty_dirs;	/* List of dirty directories */
 
-	/* Statistcs */
+	/* Summary */
+	int chunks_per_summary;
+	struct yaffs_summary_tags *sum_tags;
+
+	/* Statistics */
 	u32 n_page_writes;
 	u32 n_page_reads;
 	u32 n_erasures;
@@ -724,7 +769,7 @@
 	u32 oldest_dirty_gc_count;
 	u32 n_gc_blocks;
 	u32 bg_gcs;
-	u32 n_retired_writes;
+	u32 n_retried_writes;
 	u32 n_retired_blocks;
 	u32 n_ecc_fixed;
 	u32 n_ecc_unfixed;
@@ -734,11 +779,13 @@
 	u32 n_unmarked_deletions;
 	u32 refresh_count;
 	u32 cache_hits;
+	u32 tags_used;
+	u32 summary_used;
 
 };
 
-/* The CheckpointDevice structure holds the device information that changes at runtime and
- * must be preserved over unmount/mount cycles.
+/* The CheckpointDevice structure holds the device information that changes
+ *at runtime and must be preserved over unmount/mount cycles.
  */
 struct yaffs_checkpt_dev {
 	int struct_type;
@@ -752,7 +799,8 @@
 	int n_bg_deletions;	/* Count of background deletions. */
 
 	/* yaffs2 runtime stuff */
-	unsigned seq_number;	/* Sequence number of currently allocating block */
+	unsigned seq_number;	/* Sequence number of currently
+				 * allocating block */
 
 };
 
@@ -793,7 +841,7 @@
 int yaffs_del_obj(struct yaffs_obj *obj);
 
 int yaffs_get_obj_name(struct yaffs_obj *obj, YCHAR * name, int buffer_size);
-int yaffs_get_obj_length(struct yaffs_obj *obj);
+loff_t yaffs_get_obj_length(struct yaffs_obj *obj);
 int yaffs_get_obj_inode(struct yaffs_obj *obj);
 unsigned yaffs_get_obj_type(struct yaffs_obj *obj);
 int yaffs_get_obj_link_count(struct yaffs_obj *obj);
@@ -806,7 +854,7 @@
 int yaffs_resize_file(struct yaffs_obj *obj, loff_t new_size);
 
 struct yaffs_obj *yaffs_create_file(struct yaffs_obj *parent,
-				    const YCHAR * name, u32 mode, u32 uid,
+				    const YCHAR *name, u32 mode, u32 uid,
 				    u32 gid);
 
 int yaffs_flush_file(struct yaffs_obj *obj, int update_time, int data_sync);
@@ -818,35 +866,35 @@
 int yaffs_checkpoint_restore(struct yaffs_dev *dev);
 
 /* Directory operations */
-struct yaffs_obj *yaffs_create_dir(struct yaffs_obj *parent, const YCHAR * name,
+struct yaffs_obj *yaffs_create_dir(struct yaffs_obj *parent, const YCHAR *name,
 				   u32 mode, u32 uid, u32 gid);
 struct yaffs_obj *yaffs_find_by_name(struct yaffs_obj *the_dir,
-				     const YCHAR * name);
+				     const YCHAR *name);
 struct yaffs_obj *yaffs_find_by_number(struct yaffs_dev *dev, u32 number);
 
 /* Link operations */
-struct yaffs_obj *yaffs_link_obj(struct yaffs_obj *parent, const YCHAR * name,
+struct yaffs_obj *yaffs_link_obj(struct yaffs_obj *parent, const YCHAR *name,
 				 struct yaffs_obj *equiv_obj);
 
 struct yaffs_obj *yaffs_get_equivalent_obj(struct yaffs_obj *obj);
 
 /* Symlink operations */
 struct yaffs_obj *yaffs_create_symlink(struct yaffs_obj *parent,
-				       const YCHAR * name, u32 mode, u32 uid,
-				       u32 gid, const YCHAR * alias);
+				       const YCHAR *name, u32 mode, u32 uid,
+				       u32 gid, const YCHAR *alias);
 YCHAR *yaffs_get_symlink_alias(struct yaffs_obj *obj);
 
 /* Special inodes (fifos, sockets and devices) */
 struct yaffs_obj *yaffs_create_special(struct yaffs_obj *parent,
-				       const YCHAR * name, u32 mode, u32 uid,
+				       const YCHAR *name, u32 mode, u32 uid,
 				       u32 gid, u32 rdev);
 
-int yaffs_set_xattrib(struct yaffs_obj *obj, const YCHAR * name,
+int yaffs_set_xattrib(struct yaffs_obj *obj, const YCHAR *name,
 		      const void *value, int size, int flags);
-int yaffs_get_xattrib(struct yaffs_obj *obj, const YCHAR * name, void *value,
+int yaffs_get_xattrib(struct yaffs_obj *obj, const YCHAR *name, void *value,
 		      int size);
 int yaffs_list_xattrib(struct yaffs_obj *obj, char *buffer, int size);
-int yaffs_remove_xattrib(struct yaffs_obj *obj, const YCHAR * name);
+int yaffs_remove_xattrib(struct yaffs_obj *obj, const YCHAR *name);
 
 /* Special directories */
 struct yaffs_obj *yaffs_root(struct yaffs_dev *dev);
@@ -866,26 +914,26 @@
 /* A few useful functions to be used within the core files*/
 void yaffs_chunk_del(struct yaffs_dev *dev, int chunk_id, int mark_flash,
 		     int lyn);
-int yaffs_check_ff(u8 * buffer, int n_bytes);
+int yaffs_check_ff(u8 *buffer, int n_bytes);
 void yaffs_handle_chunk_error(struct yaffs_dev *dev,
 			      struct yaffs_block_info *bi);
 
-u8 *yaffs_get_temp_buffer(struct yaffs_dev *dev, int line_no);
-void yaffs_release_temp_buffer(struct yaffs_dev *dev, u8 * buffer, int line_no);
+u8 *yaffs_get_temp_buffer(struct yaffs_dev *dev);
+void yaffs_release_temp_buffer(struct yaffs_dev *dev, u8 *buffer);
 
 struct yaffs_obj *yaffs_find_or_create_by_number(struct yaffs_dev *dev,
 						 int number,
 						 enum yaffs_obj_type type);
 int yaffs_put_chunk_in_file(struct yaffs_obj *in, int inode_chunk,
 			    int nand_chunk, int in_scan);
-void yaffs_set_obj_name(struct yaffs_obj *obj, const YCHAR * name);
+void yaffs_set_obj_name(struct yaffs_obj *obj, const YCHAR *name);
 void yaffs_set_obj_name_from_oh(struct yaffs_obj *obj,
 				const struct yaffs_obj_hdr *oh);
 void yaffs_add_obj_to_dir(struct yaffs_obj *directory, struct yaffs_obj *obj);
-YCHAR *yaffs_clone_str(const YCHAR * str);
-void yaffs_link_fixup(struct yaffs_dev *dev, struct yaffs_obj *hard_list);
+YCHAR *yaffs_clone_str(const YCHAR *str);
+void yaffs_link_fixup(struct yaffs_dev *dev, struct list_head *hard_list);
 void yaffs_block_became_dirty(struct yaffs_dev *dev, int block_no);
-int yaffs_update_oh(struct yaffs_obj *in, const YCHAR * name,
+int yaffs_update_oh(struct yaffs_obj *in, const YCHAR *name,
 		    int force, int is_shrink, int shadows,
 		    struct yaffs_xattr_mod *xop);
 void yaffs_handle_shadowed_obj(struct yaffs_dev *dev, int obj_id,
@@ -897,7 +945,7 @@
 					   u32 chunk_id,
 					   struct yaffs_tnode *passed_tn);
 
-int yaffs_do_file_wr(struct yaffs_obj *in, const u8 * buffer, loff_t offset,
+int yaffs_do_file_wr(struct yaffs_obj *in, const u8 *buffer, loff_t offset,
 		     int n_bytes, int write_trhrough);
 void yaffs_resize_file_down(struct yaffs_obj *obj, loff_t new_size);
 void yaffs_skip_rest_of_block(struct yaffs_dev *dev);
@@ -912,4 +960,18 @@
 			 unsigned pos);
 
 int yaffs_is_non_empty_dir(struct yaffs_obj *obj);
+
+int yaffs_format_dev(struct yaffs_dev *dev);
+
+void yaffs_addr_to_chunk(struct yaffs_dev *dev, loff_t addr,
+				int *chunk_out, u32 *offset_out);
+/*
+ * Marshalling functions to get loff_t file sizes into aand out of
+ * object headers.
+ */
+void yaffs_oh_size_load(struct yaffs_obj_hdr *oh, loff_t fsize);
+loff_t yaffs_oh_to_size(struct yaffs_obj_hdr *oh);
+loff_t yaffs_max_file_size(struct yaffs_dev *dev);
+
+
 #endif
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_linux.h linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_linux.h
--- linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_linux.h	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_linux.h	2014-07-29 17:28:38.819972000 +0800
@@ -1,7 +1,7 @@
 /*
  * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
  *
- * Copyright (C) 2002-2010 Aleph One Ltd.
+ * Copyright (C) 2002-2011 Aleph One Ltd.
  *   for Toby Churchill Ltd and Brightstar Engineering
  *
  * Created by Charles Manning <charles@aleph1.co.uk>
@@ -25,11 +25,11 @@
 	struct task_struct *bg_thread;	/* Background thread for this device */
 	int bg_running;
 	struct mutex gross_lock;	/* Gross locking mutex*/
-	u8 *spare_buffer;	/* For mtdif2 use. Don't know the size of the buffer
+	u8 *spare_buffer;	/* For mtdif2 use. Don't know the buffer size
 				 * at compile time so we have to allocate it.
 				 */
 	struct list_head search_contexts;
-	void (*put_super_fn) (struct super_block * sb);
+	void (*put_super_fn) (struct super_block *sb);
 
 	struct task_struct *readdir_process;
 	unsigned mount_id;
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_mtdif1.c linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_mtdif1.c
--- linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_mtdif1.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_mtdif1.c	2014-07-29 17:28:38.819972000 +0800
@@ -1,7 +1,7 @@
 /*
  * YAFFS: Yet another FFS. A NAND-flash specific file system.
  *
- * Copyright (C) 2002-2010 Aleph One Ltd.
+ * Copyright (C) 2002-2011 Aleph One Ltd.
  *   for Toby Churchill Ltd and Brightstar Engineering
  *
  * Created by Charles Manning <charles@aleph1.co.uk>
@@ -30,18 +30,11 @@
 #include "yaffs_packedtags1.h"
 #include "yaffs_tagscompat.h"	/* for yaffs_calc_tags_ecc */
 #include "yaffs_linux.h"
-
 #include "linux/kernel.h"
 #include "linux/version.h"
 #include "linux/types.h"
 #include "linux/mtd/mtd.h"
 
-#ifndef CONFIG_YAFFS_9BYTE_TAGS
-# define YTAG1_SIZE 8
-#else
-# define YTAG1_SIZE 9
-#endif
-
 /* Write a chunk (page) of data to NAND.
  *
  * Caller always provides ExtendedTags data which are converted to a more
@@ -64,7 +57,7 @@
  * Returns YAFFS_OK or YAFFS_FAIL.
  */
 int nandmtd1_write_chunk_tags(struct yaffs_dev *dev,
-			      int nand_chunk, const u8 * data,
+			      int nand_chunk, const u8 *data,
 			      const struct yaffs_ext_tags *etags)
 {
 	struct mtd_info *mtd = yaffs_dev_to_mtd(dev);
@@ -87,29 +80,30 @@
 	 * that only zeroed-bits stick and set tag bytes to all-ones and
 	 * zero just the (not) deleted bit.
 	 */
-#ifndef CONFIG_YAFFS_9BYTE_TAGS
-	if (etags->is_deleted) {
-		memset(&pt1, 0xff, 8);
-		/* clear delete status bit to indicate deleted */
-		pt1.deleted = 0;
-	}
-#else
-	((u8 *) & pt1)[8] = 0xff;
-	if (etags->is_deleted) {
-		memset(&pt1, 0xff, 8);
-		/* zero page_status byte to indicate deleted */
-		((u8 *) & pt1)[8] = 0;
+
+	if (dev->param.tags_9bytes) {
+		((u8 *) &pt1)[8] = 0xff;
+		if (etags->is_deleted) {
+			memset(&pt1, 0xff, 8);
+			/* zero page_status byte to indicate deleted */
+			((u8 *) &pt1)[8] = 0;
+		}
+	} else {
+		if (etags->is_deleted) {
+			memset(&pt1, 0xff, 8);
+			/* clear delete status bit to indicate deleted */
+			pt1.deleted = 0;
+		}
 	}
-#endif
 
 	memset(&ops, 0, sizeof(ops));
-	ops.mode = MTD_OOB_AUTO;
+	ops.mode = MTD_OPS_AUTO_OOB;
 	ops.len = (data) ? chunk_bytes : 0;
-	ops.ooblen = YTAG1_SIZE;
+	ops.ooblen = dev->param.tags_9bytes ? 9 : 8;
 	ops.datbuf = (u8 *) data;
-	ops.oobbuf = (u8 *) & pt1;
+	ops.oobbuf = (u8 *) &pt1;
 
-	retval = mtd->write_oob(mtd, addr, &ops);
+	retval = mtd->_write_oob(mtd, addr, &ops);
 	if (retval) {
 		yaffs_trace(YAFFS_TRACE_MTD,
 			"write_oob failed, chunk %d, mtd error %d",
@@ -143,7 +137,7 @@
  * Returns YAFFS_OK or YAFFS_FAIL.
  */
 int nandmtd1_read_chunk_tags(struct yaffs_dev *dev,
-			     int nand_chunk, u8 * data,
+			     int nand_chunk, u8 *data,
 			     struct yaffs_ext_tags *etags)
 {
 	struct mtd_info *mtd = yaffs_dev_to_mtd(dev);
@@ -156,16 +150,16 @@
 	int deleted;
 
 	memset(&ops, 0, sizeof(ops));
-	ops.mode = MTD_OOB_AUTO;
+	ops.mode = MTD_OPS_AUTO_OOB;
 	ops.len = (data) ? chunk_bytes : 0;
-	ops.ooblen = YTAG1_SIZE;
+	ops.ooblen =  dev->param.tags_9bytes ? 9 : 8;
 	ops.datbuf = data;
-	ops.oobbuf = (u8 *) & pt1;
+	ops.oobbuf = (u8 *) &pt1;
 
 	/* Read page and oob using MTD.
 	 * Check status and determine ECC result.
 	 */
-	retval = mtd->read_oob(mtd, addr, &ops);
+	retval = mtd->_read_oob(mtd, addr, &ops);
 	if (retval) {
 		yaffs_trace(YAFFS_TRACE_MTD,
 			"read_oob failed, chunk %d, mtd error %d",
@@ -189,13 +183,13 @@
 		/* fall into... */
 	default:
 		rettags(etags, YAFFS_ECC_RESULT_UNFIXED, 0);
-		etags->block_bad = (mtd->block_isbad) (mtd, addr);
+		etags->block_bad = mtd->_block_isbad(mtd, addr);
 		return YAFFS_FAIL;
 	}
 
 	/* Check for a blank/erased chunk.
 	 */
-	if (yaffs_check_ff((u8 *) & pt1, 8)) {
+	if (yaffs_check_ff((u8 *) &pt1, 8)) {
 		/* when blank, upper layers want ecc_result to be <= NO_ERROR */
 		return rettags(etags, YAFFS_ECC_RESULT_NO_ERROR, YAFFS_OK);
 	}
@@ -207,7 +201,7 @@
 	deleted = !pt1.deleted;
 	pt1.deleted = 1;
 #else
-	deleted = (yaffs_count_bits(((u8 *) & pt1)[8]) < 7);
+	deleted = (hweight8(((u8 *) &pt1)[8]) < 7);
 #endif
 
 	/* Check the packed tags mini-ECC and correct if necessary/possible.
@@ -232,7 +226,7 @@
 	/* Unpack the tags to extended form and set ECC result.
 	 * [set should_be_ff just to keep yaffs_unpack_tags1 happy]
 	 */
-	pt1.should_be_ff = 0xFFFFFFFF;
+	pt1.should_be_ff = 0xffffffff;
 	yaffs_unpack_tags1(etags, &pt1);
 	etags->ecc_result = eccres;
 
@@ -257,7 +251,7 @@
 	yaffs_trace(YAFFS_TRACE_BAD_BLOCKS,
 		"marking block %d bad", block_no);
 
-	retval = mtd->block_markbad(mtd, (loff_t) blocksize * block_no);
+	retval = mtd->_block_markbad(mtd, (loff_t) blocksize * block_no);
 	return (retval) ? YAFFS_FAIL : YAFFS_OK;
 }
 
@@ -265,16 +259,17 @@
  *
  * Returns YAFFS_OK or YAFFS_FAIL.
  */
-static int nandmtd1_test_prerequists(struct mtd_info *mtd)
+static int nandmtd1_test_prerequists(struct yaffs_dev *dev,
+					struct mtd_info *mtd)
 {
 	/* 2.6.18 has mtd->ecclayout->oobavail */
 	/* 2.6.21 has mtd->ecclayout->oobavail and mtd->oobavail */
 	int oobavail = mtd->ecclayout->oobavail;
 
-	if (oobavail < YTAG1_SIZE) {
+	if (oobavail < (dev->param.tags_9bytes ? 9 : 8)) {
 		yaffs_trace(YAFFS_TRACE_ERROR,
 			"mtd device has only %d bytes for tags, need %d",
-			oobavail, YTAG1_SIZE);
+			oobavail, (dev->param.tags_9bytes ? 9 : 8));
 		return YAFFS_FAIL;
 	}
 	return YAFFS_OK;
@@ -284,7 +279,7 @@
  *
  * Examine the tags of the first chunk of the block and return the state:
  *  - YAFFS_BLOCK_STATE_DEAD, the block is marked bad
- *  - YAFFS_BLOCK_STATE_NEEDS_SCANNING, the block is in use
+ *  - YAFFS_BLOCK_STATE_NEEDS_SCAN, the block is in use
  *  - YAFFS_BLOCK_STATE_EMPTY, the block is clean
  *
  * Always returns YAFFS_OK.
@@ -303,20 +298,20 @@
 	/* We don't yet have a good place to test for MTD config prerequists.
 	 * Do it here as we are called during the initial scan.
 	 */
-	if (nandmtd1_test_prerequists(mtd) != YAFFS_OK)
+	if (nandmtd1_test_prerequists(dev, mtd) != YAFFS_OK)
 		return YAFFS_FAIL;
 
 	retval = nandmtd1_read_chunk_tags(dev, chunk_num, NULL, &etags);
-	etags.block_bad = (mtd->block_isbad) (mtd, addr);
+	etags.block_bad = mtd->_block_isbad(mtd, addr);
 	if (etags.block_bad) {
 		yaffs_trace(YAFFS_TRACE_BAD_BLOCKS,
 			"block %d is marked bad", block_no);
 		state = YAFFS_BLOCK_STATE_DEAD;
 	} else if (etags.ecc_result != YAFFS_ECC_RESULT_NO_ERROR) {
 		/* bad tags, need to look more closely */
-		state = YAFFS_BLOCK_STATE_NEEDS_SCANNING;
+		state = YAFFS_BLOCK_STATE_NEEDS_SCAN;
 	} else if (etags.chunk_used) {
-		state = YAFFS_BLOCK_STATE_NEEDS_SCANNING;
+		state = YAFFS_BLOCK_STATE_NEEDS_SCAN;
 		seqnum = etags.seq_number;
 	} else {
 		state = YAFFS_BLOCK_STATE_EMPTY;
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_mtdif1.h linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_mtdif1.h
--- linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_mtdif1.h	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_mtdif1.h	2014-07-29 17:28:38.819972000 +0800
@@ -1,7 +1,7 @@
 /*
  * YAFFS: Yet another Flash File System. A NAND-flash specific file system.
  *
- * Copyright (C) 2002-2010 Aleph One Ltd.
+ * Copyright (C) 2002-2011 Aleph One Ltd.
  *   for Toby Churchill Ltd and Brightstar Engineering
  *
  * This program is free software; you can redistribute it and/or modify
@@ -15,15 +15,15 @@
 #define __YAFFS_MTDIF1_H__
 
 int nandmtd1_write_chunk_tags(struct yaffs_dev *dev, int nand_chunk,
-			      const u8 * data,
+			      const u8 *data,
 			      const struct yaffs_ext_tags *tags);
 
 int nandmtd1_read_chunk_tags(struct yaffs_dev *dev, int nand_chunk,
-			     u8 * data, struct yaffs_ext_tags *tags);
+			     u8 *data, struct yaffs_ext_tags *tags);
 
 int nandmtd1_mark_block_bad(struct yaffs_dev *dev, int block_no);
 
 int nandmtd1_query_block(struct yaffs_dev *dev, int block_no,
-			 enum yaffs_block_state *state, u32 * seq_number);
+			 enum yaffs_block_state *state, u32 *seq_number);
 
 #endif
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_mtdif2.c linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_mtdif2.c
--- linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_mtdif2.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_mtdif2.c	2014-07-29 17:28:38.819972000 +0800
@@ -1,7 +1,7 @@
 /*
  * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
  *
- * Copyright (C) 2002-2010 Aleph One Ltd.
+ * Copyright (C) 2002-2011 Aleph One Ltd.
  *   for Toby Churchill Ltd and Brightstar Engineering
  *
  * Created by Charles Manning <charles@aleph1.co.uk>
@@ -15,33 +15,28 @@
 
 #include "yportenv.h"
 #include "yaffs_trace.h"
-
 #include "yaffs_mtdif2.h"
-
+#include "yaffs_packedtags2.h"
+#include "yaffs_linux.h"
 #include "linux/mtd/mtd.h"
 #include "linux/types.h"
 #include "linux/time.h"
+#include "mtd/mtd-abi.h"
 
-#include "yaffs_packedtags2.h"
-
-#include "yaffs_linux.h"
 
 /* NB For use with inband tags....
- * We assume that the data buffer is of size total_bytes_per_chunk so that we can also
- * use it to load the tags.
+ * We assume that the data buffer is of size total_bytes_per_chunk so that
+ * we can also use it to load the tags.
  */
 int nandmtd2_write_chunk_tags(struct yaffs_dev *dev, int nand_chunk,
-			      const u8 * data,
+			      const u8 *data,
 			      const struct yaffs_ext_tags *tags)
 {
 	struct mtd_info *mtd = yaffs_dev_to_mtd(dev);
 	struct mtd_oob_ops ops;
 	int retval = 0;
-
 	loff_t addr;
-
 	struct yaffs_packed_tags2 pt;
-
 	int packed_tags_size =
 	    dev->param.no_tags_ecc ? sizeof(pt.t) : sizeof(pt);
 	void *packed_tags_ptr =
@@ -61,43 +56,39 @@
 		BUG();
 	else if (dev->param.inband_tags) {
 		struct yaffs_packed_tags2_tags_only *pt2tp;
+
 		pt2tp =
-		    (struct yaffs_packed_tags2_tags_only *)(data +
-							    dev->
-							    data_bytes_per_chunk);
+		    (struct yaffs_packed_tags2_tags_only *)
+			(data + dev->data_bytes_per_chunk);
 		yaffs_pack_tags2_tags_only(pt2tp, tags);
 	} else {
 		yaffs_pack_tags2(&pt, tags, !dev->param.no_tags_ecc);
-        }
+	}
 
-	ops.mode = MTD_OOB_AUTO;
+	ops.mode = MTD_OPS_AUTO_OOB;
 	ops.ooblen = (dev->param.inband_tags) ? 0 : packed_tags_size;
 	ops.len = dev->param.total_bytes_per_chunk;
 	ops.ooboffs = 0;
 	ops.datbuf = (u8 *) data;
 	ops.oobbuf = (dev->param.inband_tags) ? NULL : packed_tags_ptr;
-	retval = mtd->write_oob(mtd, addr, &ops);
+	retval = mtd->_write_oob(mtd, addr, &ops);
 
 	if (retval == 0)
 		return YAFFS_OK;
-	else
-		return YAFFS_FAIL;
+
+	return YAFFS_FAIL;
 }
 
 int nandmtd2_read_chunk_tags(struct yaffs_dev *dev, int nand_chunk,
-			     u8 * data, struct yaffs_ext_tags *tags)
+			     u8 *data, struct yaffs_ext_tags *tags)
 {
 	struct mtd_info *mtd = yaffs_dev_to_mtd(dev);
 	struct mtd_oob_ops ops;
-
 	size_t dummy;
 	int retval = 0;
 	int local_data = 0;
-
 	loff_t addr = ((loff_t) nand_chunk) * dev->param.total_bytes_per_chunk;
-
 	struct yaffs_packed_tags2 pt;
-
 	int packed_tags_size =
 	    dev->param.no_tags_ecc ? sizeof(pt.t) : sizeof(pt);
 	void *packed_tags_ptr =
@@ -107,81 +98,75 @@
 		"nandmtd2_read_chunk_tags chunk %d data %p tags %p",
 		nand_chunk, data, tags);
 
-	if (dev->param.inband_tags) {
-
-		if (!data) {
-			local_data = 1;
-			data = yaffs_get_temp_buffer(dev, __LINE__);
-		}
-
+	if (dev->param.inband_tags && !data) {
+		local_data = 1;
+		data = yaffs_get_temp_buffer(dev);
 	}
 
-	if (dev->param.inband_tags || (data && !tags))
-		retval = mtd->read(mtd, addr, dev->param.total_bytes_per_chunk,
+	if (dev->param.inband_tags || (data && !tags)) {
+		retval = mtd->_read(mtd, addr, dev->param.total_bytes_per_chunk,
 				   &dummy, data);
-	else if (tags) {
-		ops.mode = MTD_OOB_AUTO;
+	} else if (tags) {
+		ops.mode = MTD_OPS_AUTO_OOB;
 		ops.ooblen = packed_tags_size;
 		ops.len = data ? dev->data_bytes_per_chunk : packed_tags_size;
 		ops.ooboffs = 0;
 		ops.datbuf = data;
 		ops.oobbuf = yaffs_dev_to_lc(dev)->spare_buffer;
-		retval = mtd->read_oob(mtd, addr, &ops);
+		retval = mtd->_read_oob(mtd, addr, &ops);
 	}
 
-	if (dev->param.inband_tags) {
-		if (tags) {
-			struct yaffs_packed_tags2_tags_only *pt2tp;
-			pt2tp =
-			    (struct yaffs_packed_tags2_tags_only *)&data[dev->
-									 data_bytes_per_chunk];
-			yaffs_unpack_tags2_tags_only(tags, pt2tp);
-		}
-	} else {
-		if (tags) {
-			memcpy(packed_tags_ptr,
-			       yaffs_dev_to_lc(dev)->spare_buffer,
-			       packed_tags_size);
-			yaffs_unpack_tags2(tags, &pt, !dev->param.no_tags_ecc);
-		}
+	if (dev->param.inband_tags && tags) {
+		struct yaffs_packed_tags2_tags_only *pt2tp;
+
+		pt2tp =
+			(struct yaffs_packed_tags2_tags_only *)
+				&data[dev->data_bytes_per_chunk];
+		yaffs_unpack_tags2_tags_only(tags, pt2tp);
+	} else if (tags) {
+		memcpy(packed_tags_ptr,
+		       yaffs_dev_to_lc(dev)->spare_buffer,
+		       packed_tags_size);
+		yaffs_unpack_tags2(tags, &pt, !dev->param.no_tags_ecc);
 	}
 
 	if (local_data)
-		yaffs_release_temp_buffer(dev, data, __LINE__);
+		yaffs_release_temp_buffer(dev, data);
 
-	if (tags && retval == -EBADMSG
-	    && tags->ecc_result == YAFFS_ECC_RESULT_NO_ERROR) {
+	if (tags && retval == -EBADMSG &&
+	    tags->ecc_result == YAFFS_ECC_RESULT_NO_ERROR) {
 		tags->ecc_result = YAFFS_ECC_RESULT_UNFIXED;
 		dev->n_ecc_unfixed++;
 	}
-	if (tags && retval == -EUCLEAN
-	    && tags->ecc_result == YAFFS_ECC_RESULT_NO_ERROR) {
+	if (tags && retval == -EUCLEAN &&
+	    tags->ecc_result == YAFFS_ECC_RESULT_NO_ERROR) {
 		tags->ecc_result = YAFFS_ECC_RESULT_FIXED;
 		dev->n_ecc_fixed++;
 	}
+
 	if (retval == 0)
 		return YAFFS_OK;
-	else
-		return YAFFS_FAIL;
+
+	return YAFFS_FAIL;
 }
 
 int nandmtd2_mark_block_bad(struct yaffs_dev *dev, int block_no)
 {
 	struct mtd_info *mtd = yaffs_dev_to_mtd(dev);
 	int retval;
+
 	yaffs_trace(YAFFS_TRACE_MTD,
 		"nandmtd2_mark_block_bad %d", block_no);
 
 	retval =
-	    mtd->block_markbad(mtd,
+	    mtd->_block_markbad(mtd,
 			       block_no * dev->param.chunks_per_block *
 			       dev->param.total_bytes_per_chunk);
 
 	if (retval == 0)
 		return YAFFS_OK;
-	else
-		return YAFFS_FAIL;
 
+	return YAFFS_FAIL;
 }
 
 int nandmtd2_query_block(struct yaffs_dev *dev, int block_no,
@@ -192,7 +177,7 @@
 
 	yaffs_trace(YAFFS_TRACE_MTD, "nandmtd2_query_block %d", block_no);
 	retval =
-	    mtd->block_isbad(mtd,
+	    mtd->_block_isbad(mtd,
 			     block_no * dev->param.chunks_per_block *
 			     dev->param.total_bytes_per_chunk);
 
@@ -203,12 +188,13 @@
 		*seq_number = 0;
 	} else {
 		struct yaffs_ext_tags t;
+
 		nandmtd2_read_chunk_tags(dev, block_no *
 					 dev->param.chunks_per_block, NULL, &t);
 
 		if (t.chunk_used) {
 			*seq_number = t.seq_number;
-			*state = YAFFS_BLOCK_STATE_NEEDS_SCANNING;
+			*state = YAFFS_BLOCK_STATE_NEEDS_SCAN;
 		} else {
 			*seq_number = 0;
 			*state = YAFFS_BLOCK_STATE_EMPTY;
@@ -219,7 +205,6 @@
 
 	if (retval == 0)
 		return YAFFS_OK;
-	else
-		return YAFFS_FAIL;
-}
 
+	return YAFFS_FAIL;
+}
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_mtdif2.h linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_mtdif2.h
--- linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_mtdif2.h	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_mtdif2.h	2014-07-29 17:28:38.819972000 +0800
@@ -1,7 +1,7 @@
 /*
  * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
  *
- * Copyright (C) 2002-2010 Aleph One Ltd.
+ * Copyright (C) 2002-2011 Aleph One Ltd.
  *   for Toby Churchill Ltd and Brightstar Engineering
  *
  * Created by Charles Manning <charles@aleph1.co.uk>
@@ -18,12 +18,12 @@
 
 #include "yaffs_guts.h"
 int nandmtd2_write_chunk_tags(struct yaffs_dev *dev, int nand_chunk,
-			      const u8 * data,
+			      const u8 *data,
 			      const struct yaffs_ext_tags *tags);
 int nandmtd2_read_chunk_tags(struct yaffs_dev *dev, int nand_chunk,
-			     u8 * data, struct yaffs_ext_tags *tags);
+			     u8 *data, struct yaffs_ext_tags *tags);
 int nandmtd2_mark_block_bad(struct yaffs_dev *dev, int block_no);
 int nandmtd2_query_block(struct yaffs_dev *dev, int block_no,
-			 enum yaffs_block_state *state, u32 * seq_number);
+			 enum yaffs_block_state *state, u32 *seq_number);
 
 #endif
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_mtdif.c linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_mtdif.c
--- linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_mtdif.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_mtdif.c	2014-07-29 17:28:38.819972000 +0800
@@ -1,7 +1,7 @@
 /*
  * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
  *
- * Copyright (C) 2002-2010 Aleph One Ltd.
+ * Copyright (C) 2002-2011 Aleph One Ltd.
  *   for Toby Churchill Ltd and Brightstar Engineering
  *
  * Created by Charles Manning <charles@aleph1.co.uk>
@@ -26,10 +26,9 @@
 {
 	struct mtd_info *mtd = yaffs_dev_to_mtd(dev);
 	u32 addr =
-	    ((loff_t) block_no) * dev->param.total_bytes_per_chunk
-	    * dev->param.chunks_per_block;
+	    ((loff_t) block_no) * dev->param.total_bytes_per_chunk *
+	    dev->param.chunks_per_block;
 	struct erase_info ei;
-
 	int retval = 0;
 
 	ei.mtd = mtd;
@@ -40,12 +39,12 @@
 	ei.callback = NULL;
 	ei.priv = (u_long) dev;
 
-	retval = mtd->erase(mtd, &ei);
+	retval = mtd->_erase(mtd, &ei);
 
 	if (retval == 0)
 		return YAFFS_OK;
-	else
-		return YAFFS_FAIL;
+
+	return YAFFS_FAIL;
 }
 
 int nandmtd_initialise(struct yaffs_dev *dev)
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_mtdif.h linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_mtdif.h
--- linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_mtdif.h	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_mtdif.h	2014-07-29 17:28:38.819972000 +0800
@@ -1,7 +1,7 @@
 /*
  * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
  *
- * Copyright (C) 2002-2010 Aleph One Ltd.
+ * Copyright (C) 2002-2011 Aleph One Ltd.
  *   for Toby Churchill Ltd and Brightstar Engineering
  *
  * Created by Charles Manning <charles@aleph1.co.uk>
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_nameval.c linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_nameval.c
--- linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_nameval.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_nameval.c	2014-07-29 17:28:38.819972000 +0800
@@ -1,7 +1,7 @@
 /*
  * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
  *
- * Copyright (C) 2002-2010 Aleph One Ltd.
+ * Copyright (C) 2002-2011 Aleph One Ltd.
  *   for Toby Churchill Ltd and Brightstar Engineering
  *
  * Created by Charles Manning <charles@aleph1.co.uk>
@@ -12,15 +12,15 @@
  */
 
 /*
- * This simple implementation of a name-value store assumes a small number of values and fits
- * into a small finite buffer.
+ * This simple implementation of a name-value store assumes a small number of
+* values and fits into a small finite buffer.
  *
  * Each attribute is stored as a record:
  *  sizeof(int) bytes   record size.
  *  strnlen+1 bytes name null terminated.
  *  nbytes    value.
  *  ----------
- *  total size  stored in record size 
+ *  total size  stored in record size
  *
  * This code has not been tested with unicode yet.
  */
@@ -29,7 +29,7 @@
 
 #include "yportenv.h"
 
-static int nval_find(const char *xb, int xb_size, const YCHAR * name,
+static int nval_find(const char *xb, int xb_size, const YCHAR *name,
 		     int *exist_size)
 {
 	int pos = 0;
@@ -37,8 +37,8 @@
 
 	memcpy(&size, xb, sizeof(int));
 	while (size > 0 && (size < xb_size) && (pos + size < xb_size)) {
-		if (strncmp
-		    ((YCHAR *) (xb + pos + sizeof(int)), name, size) == 0) {
+		if (!strncmp((YCHAR *) (xb + pos + sizeof(int)),
+				name, size)) {
 			if (exist_size)
 				*exist_size = size;
 			return pos;
@@ -51,7 +51,7 @@
 	}
 	if (exist_size)
 		*exist_size = 0;
-	return -1;
+	return -ENODATA;
 }
 
 static int nval_used(const char *xb, int xb_size)
@@ -70,24 +70,24 @@
 	return pos;
 }
 
-int nval_del(char *xb, int xb_size, const YCHAR * name)
+int nval_del(char *xb, int xb_size, const YCHAR *name)
 {
 	int pos = nval_find(xb, xb_size, name, NULL);
 	int size;
 
-	if (pos >= 0 && pos < xb_size) {
-		/* Find size, shift rest over this record, then zero out the rest of buffer */
-		memcpy(&size, xb + pos, sizeof(int));
-		memcpy(xb + pos, xb + pos + size, xb_size - (pos + size));
-		memset(xb + (xb_size - size), 0, size);
-		return 0;
-	} else {
+	if (pos < 0 || pos >= xb_size)
 		return -ENODATA;
-        }
+
+	/* Find size, shift rest over this record,
+	 * then zero out the rest of buffer */
+	memcpy(&size, xb + pos, sizeof(int));
+	memcpy(xb + pos, xb + pos + size, xb_size - (pos + size));
+	memset(xb + (xb_size - size), 0, size);
+	return 0;
 }
 
-int nval_set(char *xb, int xb_size, const YCHAR * name, const char *buf,
-	     int bsize, int flags)
+int nval_set(char *xb, int xb_size, const YCHAR *name, const char *buf,
+		int bsize, int flags)
 {
 	int pos;
 	int namelen = strnlen(name, xb_size);
@@ -147,16 +147,21 @@
 		pos++;
 		size--;
 
+		/* If bsize is zero then this is a size query.
+		 * Return the size, but don't copy.
+		 */
+		if (!bsize)
+			return size;
+
 		if (size <= bsize) {
 			memcpy(buf, xb + pos, size);
 			return size;
 		}
-
 	}
 	if (pos >= 0)
 		return -ERANGE;
-	else
-		return -ENODATA;
+
+	return -ENODATA;
 }
 
 int nval_list(const char *xb, int xb_size, char *buf, int bsize)
@@ -168,8 +173,10 @@
 	int filled = 0;
 
 	memcpy(&size, xb + pos, sizeof(int));
-	while (size > sizeof(int) && size <= xb_size && (pos + size) < xb_size
-	       && !filled) {
+	while (size > sizeof(int) &&
+		size <= xb_size &&
+		(pos + size) < xb_size &&
+		!filled) {
 		pos += sizeof(int);
 		size -= sizeof(int);
 		name_len = strnlen((YCHAR *) (xb + pos), size);
@@ -185,7 +192,7 @@
 			ncopied += (name_len + 1);
 		} else {
 			filled = 1;
-                }
+		}
 		pos += size;
 		if (pos < xb_size - sizeof(int))
 			memcpy(&size, xb + pos, sizeof(int));
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_nameval.h linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_nameval.h
--- linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_nameval.h	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_nameval.h	2014-07-29 17:28:38.819972000 +0800
@@ -1,7 +1,7 @@
 /*
  * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
  *
- * Copyright (C) 2002-2010 Aleph One Ltd.
+ * Copyright (C) 2002-2011 Aleph One Ltd.
  *   for Toby Churchill Ltd and Brightstar Engineering
  *
  * Created by Charles Manning <charles@aleph1.co.uk>
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_nand.c linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_nand.c
--- linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_nand.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_nand.c	2014-07-29 17:28:38.819972000 +0800
@@ -1,7 +1,7 @@
 /*
  * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
  *
- * Copyright (C) 2002-2010 Aleph One Ltd.
+ * Copyright (C) 2002-2011 Aleph One Ltd.
  *   for Toby Churchill Ltd and Brightstar Engineering
  *
  * Created by Charles Manning <charles@aleph1.co.uk>
@@ -13,31 +13,30 @@
 
 #include "yaffs_nand.h"
 #include "yaffs_tagscompat.h"
-#include "yaffs_tagsvalidity.h"
 
 #include "yaffs_getblockinfo.h"
+#include "yaffs_summary.h"
 
 int yaffs_rd_chunk_tags_nand(struct yaffs_dev *dev, int nand_chunk,
-			     u8 * buffer, struct yaffs_ext_tags *tags)
+			     u8 *buffer, struct yaffs_ext_tags *tags)
 {
 	int result;
 	struct yaffs_ext_tags local_tags;
-
-	int realigned_chunk = nand_chunk - dev->chunk_offset;
+	int flash_chunk = nand_chunk - dev->chunk_offset;
 
 	dev->n_page_reads++;
 
-	/* If there are no tags provided, use local tags to get prioritised gc working */
+	/* If there are no tags provided use local tags. */
 	if (!tags)
 		tags = &local_tags;
 
 	if (dev->param.read_chunk_tags_fn)
 		result =
-		    dev->param.read_chunk_tags_fn(dev, realigned_chunk, buffer,
+		    dev->param.read_chunk_tags_fn(dev, flash_chunk, buffer,
 						  tags);
 	else
 		result = yaffs_tags_compat_rd(dev,
-					      realigned_chunk, buffer, tags);
+					      flash_chunk, buffer, tags);
 	if (tags && tags->ecc_result > YAFFS_ECC_RESULT_NO_ERROR) {
 
 		struct yaffs_block_info *bi;
@@ -46,64 +45,61 @@
 					  dev->param.chunks_per_block);
 		yaffs_handle_chunk_error(dev, bi);
 	}
-
 	return result;
 }
 
 int yaffs_wr_chunk_tags_nand(struct yaffs_dev *dev,
-			     int nand_chunk,
-			     const u8 * buffer, struct yaffs_ext_tags *tags)
+				int nand_chunk,
+				const u8 *buffer, struct yaffs_ext_tags *tags)
 {
+	int result;
+	int flash_chunk = nand_chunk - dev->chunk_offset;
 
 	dev->n_page_writes++;
 
-	nand_chunk -= dev->chunk_offset;
-
 	if (tags) {
 		tags->seq_number = dev->seq_number;
 		tags->chunk_used = 1;
-		if (!yaffs_validate_tags(tags)) {
-			yaffs_trace(YAFFS_TRACE_ERROR, "Writing uninitialised tags");
-			YBUG();
-		}
 		yaffs_trace(YAFFS_TRACE_WRITE,
 			"Writing chunk %d tags %d %d",
 			nand_chunk, tags->obj_id, tags->chunk_id);
 	} else {
 		yaffs_trace(YAFFS_TRACE_ERROR, "Writing with no tags");
-		YBUG();
+		BUG();
+		return YAFFS_FAIL;
 	}
 
 	if (dev->param.write_chunk_tags_fn)
-		return dev->param.write_chunk_tags_fn(dev, nand_chunk, buffer,
-						      tags);
+		result = dev->param.write_chunk_tags_fn(dev, flash_chunk,
+							buffer, tags);
 	else
-		return yaffs_tags_compat_wr(dev, nand_chunk, buffer, tags);
+		result = yaffs_tags_compat_wr(dev, flash_chunk, buffer, tags);
+
+	yaffs_summary_add(dev, tags, nand_chunk);
+
+	return result;
 }
 
 int yaffs_mark_bad(struct yaffs_dev *dev, int block_no)
 {
 	block_no -= dev->block_offset;
-
 	if (dev->param.bad_block_fn)
 		return dev->param.bad_block_fn(dev, block_no);
-	else
-		return yaffs_tags_compat_mark_bad(dev, block_no);
+
+	return yaffs_tags_compat_mark_bad(dev, block_no);
 }
 
 int yaffs_query_init_block_state(struct yaffs_dev *dev,
 				 int block_no,
 				 enum yaffs_block_state *state,
-				 u32 * seq_number)
+				 u32 *seq_number)
 {
 	block_no -= dev->block_offset;
-
 	if (dev->param.query_block_fn)
 		return dev->param.query_block_fn(dev, block_no, state,
 						 seq_number);
-	else
-		return yaffs_tags_compat_query_block(dev, block_no,
-						     state, seq_number);
+
+	return yaffs_tags_compat_query_block(dev, block_no, state, seq_number);
 }
 
 int yaffs_erase_block(struct yaffs_dev *dev, int flash_block)
@@ -111,11 +107,8 @@
 	int result;
 
 	flash_block -= dev->block_offset;
-
 	dev->n_erasures++;
-
 	result = dev->param.erase_fn(dev, flash_block);
-
 	return result;
 }
 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_nand.h linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_nand.h
--- linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_nand.h	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_nand.h	2014-07-29 17:28:38.819972000 +0800
@@ -1,7 +1,7 @@
 /*
  * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
  *
- * Copyright (C) 2002-2010 Aleph One Ltd.
+ * Copyright (C) 2002-2011 Aleph One Ltd.
  *   for Toby Churchill Ltd and Brightstar Engineering
  *
  * Created by Charles Manning <charles@aleph1.co.uk>
@@ -18,11 +18,11 @@
 #include "yaffs_guts.h"
 
 int yaffs_rd_chunk_tags_nand(struct yaffs_dev *dev, int nand_chunk,
-			     u8 * buffer, struct yaffs_ext_tags *tags);
+			     u8 *buffer, struct yaffs_ext_tags *tags);
 
 int yaffs_wr_chunk_tags_nand(struct yaffs_dev *dev,
 			     int nand_chunk,
-			     const u8 * buffer, struct yaffs_ext_tags *tags);
+			     const u8 *buffer, struct yaffs_ext_tags *tags);
 
 int yaffs_mark_bad(struct yaffs_dev *dev, int block_no);
 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_packedtags1.c linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_packedtags1.c
--- linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_packedtags1.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_packedtags1.c	2014-07-29 17:28:38.819972000 +0800
@@ -1,7 +1,7 @@
 /*
  * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
  *
- * Copyright (C) 2002-2010 Aleph One Ltd.
+ * Copyright (C) 2002-2011 Aleph One Ltd.
  *   for Toby Churchill Ltd and Brightstar Engineering
  *
  * Created by Charles Manning <charles@aleph1.co.uk>
@@ -14,6 +14,14 @@
 #include "yaffs_packedtags1.h"
 #include "yportenv.h"
 
+static const u8 all_ff[20] = {
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff
+};
+
 void yaffs_pack_tags1(struct yaffs_packed_tags1 *pt,
 		      const struct yaffs_ext_tags *t)
 {
@@ -24,21 +32,16 @@
 	pt->ecc = 0;
 	pt->deleted = (t->is_deleted) ? 0 : 1;
 	pt->unused_stuff = 0;
-	pt->should_be_ff = 0xFFFFFFFF;
-
+	pt->should_be_ff = 0xffffffff;
 }
 
 void yaffs_unpack_tags1(struct yaffs_ext_tags *t,
 			const struct yaffs_packed_tags1 *pt)
 {
-	static const u8 all_ff[] =
-	    { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-		0xff
-	};
 
 	if (memcmp(all_ff, pt, sizeof(struct yaffs_packed_tags1))) {
 		t->block_bad = 0;
-		if (pt->should_be_ff != 0xFFFFFFFF)
+		if (pt->should_be_ff != 0xffffffff)
 			t->block_bad = 1;
 		t->chunk_used = 1;
 		t->obj_id = pt->obj_id;
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_packedtags1.h linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_packedtags1.h
--- linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_packedtags1.h	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_packedtags1.h	2014-07-29 17:28:38.819972000 +0800
@@ -1,7 +1,7 @@
 /*
  * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
  *
- * Copyright (C) 2002-2010 Aleph One Ltd.
+ * Copyright (C) 2002-2011 Aleph One Ltd.
  *   for Toby Churchill Ltd and Brightstar Engineering
  *
  * Created by Charles Manning <charles@aleph1.co.uk>
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_packedtags2.c linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_packedtags2.c
--- linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_packedtags2.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_packedtags2.c	2014-07-29 17:28:38.819972000 +0800
@@ -1,7 +1,7 @@
 /*
  * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
  *
- * Copyright (C) 2002-2010 Aleph One Ltd.
+ * Copyright (C) 2002-2011 Aleph One Ltd.
  *   for Toby Churchill Ltd and Brightstar Engineering
  *
  * Created by Charles Manning <charles@aleph1.co.uk>
@@ -14,7 +14,6 @@
 #include "yaffs_packedtags2.h"
 #include "yportenv.h"
 #include "yaffs_trace.h"
-#include "yaffs_tagsvalidity.h"
 
 /* This code packs a set of extended tags into a binary structure for
  * NAND storage
@@ -32,14 +31,14 @@
 #define EXTRA_SHADOWS_FLAG	0x20000000
 #define EXTRA_SPARE_FLAGS	0x10000000
 
-#define ALL_EXTRA_FLAGS		0xF0000000
+#define ALL_EXTRA_FLAGS		0xf0000000
 
 /* Also, the top 4 bits of the object Id are set to the object type. */
 #define EXTRA_OBJECT_TYPE_SHIFT (28)
-#define EXTRA_OBJECT_TYPE_MASK  ((0x0F) << EXTRA_OBJECT_TYPE_SHIFT)
+#define EXTRA_OBJECT_TYPE_MASK  ((0x0f) << EXTRA_OBJECT_TYPE_SHIFT)
 
-static void yaffs_dump_packed_tags2_tags_only(const struct
-					      yaffs_packed_tags2_tags_only *ptt)
+static void yaffs_dump_packed_tags2_tags_only(
+				const struct yaffs_packed_tags2_tags_only *ptt)
 {
 	yaffs_trace(YAFFS_TRACE_MTD,
 		"packed tags obj %d chunk %d byte %d seq %d",
@@ -61,6 +60,18 @@
 
 }
 
+static int yaffs_check_tags_extra_packable(const struct yaffs_ext_tags *t)
+{
+	if (t->chunk_id != 0 || !t->extra_available)
+		return 0;
+
+	/* Check if the file size is too long to store */
+	if (t->extra_obj_type == YAFFS_OBJECT_TYPE_FILE &&
+	    (t->extra_file_size >> 31) != 0)
+		return 0;
+	return 1;
+}
+
 void yaffs_pack_tags2_tags_only(struct yaffs_packed_tags2_tags_only *ptt,
 				const struct yaffs_ext_tags *t)
 {
@@ -69,7 +80,11 @@
 	ptt->n_bytes = t->n_bytes;
 	ptt->obj_id = t->obj_id;
 
-	if (t->chunk_id == 0 && t->extra_available) {
+	/* Only store extra tags for object headers.
+	 * If it is a file then only store  if the file size is short\
+	 * enough to fit.
+	 */
+	if (yaffs_check_tags_extra_packable(t)) {
 		/* Store the extra header info instead */
 		/* We save the parent object in the chunk_id */
 		ptt->chunk_id = EXTRA_HEADER_INFO_FLAG | t->extra_parent_id;
@@ -84,7 +99,7 @@
 		if (t->extra_obj_type == YAFFS_OBJECT_TYPE_HARDLINK)
 			ptt->n_bytes = t->extra_equiv_id;
 		else if (t->extra_obj_type == YAFFS_OBJECT_TYPE_FILE)
-			ptt->n_bytes = t->extra_length;
+			ptt->n_bytes = (unsigned) t->extra_file_size;
 		else
 			ptt->n_bytes = 0;
 	}
@@ -100,78 +115,65 @@
 
 	if (tags_ecc)
 		yaffs_ecc_calc_other((unsigned char *)&pt->t,
-				     sizeof(struct
-					    yaffs_packed_tags2_tags_only),
-				     &pt->ecc);
+				    sizeof(struct yaffs_packed_tags2_tags_only),
+				    &pt->ecc);
 }
 
 void yaffs_unpack_tags2_tags_only(struct yaffs_ext_tags *t,
 				  struct yaffs_packed_tags2_tags_only *ptt)
 {
-
 	memset(t, 0, sizeof(struct yaffs_ext_tags));
 
-	yaffs_init_tags(t);
+	if (ptt->seq_number == 0xffffffff)
+		return;
 
-	if (ptt->seq_number != 0xFFFFFFFF) {
-		t->block_bad = 0;
-		t->chunk_used = 1;
-		t->obj_id = ptt->obj_id;
-		t->chunk_id = ptt->chunk_id;
-		t->n_bytes = ptt->n_bytes;
-		t->is_deleted = 0;
-		t->serial_number = 0;
-		t->seq_number = ptt->seq_number;
-
-		/* Do extra header info stuff */
-
-		if (ptt->chunk_id & EXTRA_HEADER_INFO_FLAG) {
-			t->chunk_id = 0;
-			t->n_bytes = 0;
-
-			t->extra_available = 1;
-			t->extra_parent_id =
-			    ptt->chunk_id & (~(ALL_EXTRA_FLAGS));
-			t->extra_is_shrink =
-			    (ptt->chunk_id & EXTRA_SHRINK_FLAG) ? 1 : 0;
-			t->extra_shadows =
-			    (ptt->chunk_id & EXTRA_SHADOWS_FLAG) ? 1 : 0;
-			t->extra_obj_type =
-			    ptt->obj_id >> EXTRA_OBJECT_TYPE_SHIFT;
-			t->obj_id &= ~EXTRA_OBJECT_TYPE_MASK;
-
-			if (t->extra_obj_type == YAFFS_OBJECT_TYPE_HARDLINK)
-				t->extra_equiv_id = ptt->n_bytes;
-			else
-				t->extra_length = ptt->n_bytes;
-		}
-	}
+	t->block_bad = 0;
+	t->chunk_used = 1;
+	t->obj_id = ptt->obj_id;
+	t->chunk_id = ptt->chunk_id;
+	t->n_bytes = ptt->n_bytes;
+	t->is_deleted = 0;
+	t->serial_number = 0;
+	t->seq_number = ptt->seq_number;
+
+	/* Do extra header info stuff */
+	if (ptt->chunk_id & EXTRA_HEADER_INFO_FLAG) {
+		t->chunk_id = 0;
+		t->n_bytes = 0;
+
+		t->extra_available = 1;
+		t->extra_parent_id = ptt->chunk_id & (~(ALL_EXTRA_FLAGS));
+		t->extra_is_shrink = ptt->chunk_id & EXTRA_SHRINK_FLAG ? 1 : 0;
+		t->extra_shadows = ptt->chunk_id & EXTRA_SHADOWS_FLAG ? 1 : 0;
+		t->extra_obj_type = ptt->obj_id >> EXTRA_OBJECT_TYPE_SHIFT;
+		t->obj_id &= ~EXTRA_OBJECT_TYPE_MASK;
 
+		if (t->extra_obj_type == YAFFS_OBJECT_TYPE_HARDLINK)
+			t->extra_equiv_id = ptt->n_bytes;
+		else
+			t->extra_file_size = ptt->n_bytes;
+	}
 	yaffs_dump_packed_tags2_tags_only(ptt);
 	yaffs_dump_tags2(t);
-
 }
 
 void yaffs_unpack_tags2(struct yaffs_ext_tags *t, struct yaffs_packed_tags2 *pt,
 			int tags_ecc)
 {
-
 	enum yaffs_ecc_result ecc_result = YAFFS_ECC_RESULT_NO_ERROR;
 
-	if (pt->t.seq_number != 0xFFFFFFFF && tags_ecc) {
+	if (pt->t.seq_number != 0xffffffff && tags_ecc) {
 		/* Chunk is in use and we need to do ECC */
 
 		struct yaffs_ecc_other ecc;
 		int result;
 		yaffs_ecc_calc_other((unsigned char *)&pt->t,
-				     sizeof(struct
-					    yaffs_packed_tags2_tags_only),
-				     &ecc);
+				sizeof(struct yaffs_packed_tags2_tags_only),
+				&ecc);
 		result =
 		    yaffs_ecc_correct_other((unsigned char *)&pt->t,
-					    sizeof(struct
-						   yaffs_packed_tags2_tags_only),
-					    &pt->ecc, &ecc);
+				sizeof(struct yaffs_packed_tags2_tags_only),
+				&pt->ecc, &ecc);
 		switch (result) {
 		case 0:
 			ecc_result = YAFFS_ECC_RESULT_NO_ERROR;
@@ -186,7 +188,6 @@
 			ecc_result = YAFFS_ECC_RESULT_UNKNOWN;
 		}
 	}
-
 	yaffs_unpack_tags2_tags_only(t, &pt->t);
 
 	t->ecc_result = ecc_result;
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_packedtags2.h linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_packedtags2.h
--- linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_packedtags2.h	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_packedtags2.h	2014-07-29 17:28:38.819972000 +0800
@@ -1,7 +1,7 @@
 /*
  * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
  *
- * Copyright (C) 2002-2010 Aleph One Ltd.
+ * Copyright (C) 2002-2011 Aleph One Ltd.
  *   for Toby Churchill Ltd and Brightstar Engineering
  *
  * Created by Charles Manning <charles@aleph1.co.uk>
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_summary.c linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_summary.c
--- linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_summary.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_summary.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,313 @@
+/*
+ * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
+ *
+ * Copyright (C) 2002-2011 Aleph One Ltd.
+ *   for Toby Churchill Ltd and Brightstar Engineering
+ *
+ * Created by Charles Manning <charles@aleph1.co.uk>
+ *
+ * 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.
+ */
+
+/* Summaries write the useful part of the tags for the chunks in a block into an
+ * an array which is written to the last n chunks of the block.
+ * Reading the summaries gives all the tags for the block in one read. Much
+ * faster.
+ *
+ * Chunks holding summaries are marked with tags making it look like
+ * they are part of a fake file.
+ *
+ * The summary could also be used during gc.
+ *
+ */
+
+#include "yaffs_summary.h"
+#include "yaffs_packedtags2.h"
+#include "yaffs_nand.h"
+#include "yaffs_getblockinfo.h"
+#include "yaffs_bitmap.h"
+
+/*
+ * The summary is built up in an array of summary tags.
+ * This gets written to the last one or two (maybe more) chunks in a block.
+ * A summary header is written as the first part of each chunk of summary data.
+ * The summary header must match or the summary is rejected.
+ */
+
+/* Summary tags don't need the sequence number because that is redundant. */
+struct yaffs_summary_tags {
+	unsigned obj_id;
+	unsigned chunk_id;
+	unsigned n_bytes;
+};
+
+/* Summary header */
+struct yaffs_summary_header {
+	unsigned version;	/* Must match current version */
+	unsigned block;		/* Must be this block */
+	unsigned seq;		/* Must be this sequence number */
+	unsigned sum;		/* Just add up all the bytes in the tags */
+};
+
+
+static void yaffs_summary_clear(struct yaffs_dev *dev)
+{
+	if (!dev->sum_tags)
+		return;
+	memset(dev->sum_tags, 0, dev->chunks_per_summary *
+		sizeof(struct yaffs_summary_tags));
+}
+
+
+void yaffs_summary_deinit(struct yaffs_dev *dev)
+{
+	kfree(dev->sum_tags);
+	dev->sum_tags = NULL;
+	kfree(dev->gc_sum_tags);
+	dev->gc_sum_tags = NULL;
+	dev->chunks_per_summary = 0;
+}
+
+int yaffs_summary_init(struct yaffs_dev *dev)
+{
+	int sum_bytes;
+	int chunks_used; /* Number of chunks used by summary */
+	int sum_tags_bytes;
+
+	sum_bytes = dev->param.chunks_per_block *
+			sizeof(struct yaffs_summary_tags);
+
+	chunks_used = (sum_bytes + dev->data_bytes_per_chunk - 1)/
+			(dev->data_bytes_per_chunk -
+				sizeof(struct yaffs_summary_header));
+
+	dev->chunks_per_summary = dev->param.chunks_per_block - chunks_used;
+	sum_tags_bytes = sizeof(struct yaffs_summary_tags) *
+				dev->chunks_per_summary;
+	dev->sum_tags = kmalloc(sum_tags_bytes, GFP_NOFS);
+	dev->gc_sum_tags = kmalloc(sum_tags_bytes, GFP_NOFS);
+	if (!dev->sum_tags || !dev->gc_sum_tags) {
+		yaffs_summary_deinit(dev);
+		return YAFFS_FAIL;
+	}
+
+	yaffs_summary_clear(dev);
+
+	return YAFFS_OK;
+}
+
+static unsigned yaffs_summary_sum(struct yaffs_dev *dev)
+{
+	u8 *sum_buffer = (u8 *)dev->sum_tags;
+	int i;
+	unsigned sum = 0;
+
+	i = sizeof(struct yaffs_summary_tags) *
+				dev->chunks_per_summary;
+	while (i > 0) {
+		sum += *sum_buffer;
+		sum_buffer++;
+		i--;
+	}
+
+	return sum;
+}
+
+static int yaffs_summary_write(struct yaffs_dev *dev, int blk)
+{
+	struct yaffs_ext_tags tags;
+	u8 *buffer;
+	u8 *sum_buffer = (u8 *)dev->sum_tags;
+	int n_bytes;
+	int chunk_in_nand;
+	int chunk_in_block;
+	int result;
+	int this_tx;
+	struct yaffs_summary_header hdr;
+	int sum_bytes_per_chunk = dev->data_bytes_per_chunk - sizeof(hdr);
+	struct yaffs_block_info *bi = yaffs_get_block_info(dev, blk);
+
+	buffer = yaffs_get_temp_buffer(dev);
+	n_bytes = sizeof(struct yaffs_summary_tags) *
+				dev->chunks_per_summary;
+	memset(&tags, 0, sizeof(struct yaffs_ext_tags));
+	tags.obj_id = YAFFS_OBJECTID_SUMMARY;
+	tags.chunk_id = 1;
+	chunk_in_block = dev->chunks_per_summary;
+	chunk_in_nand = dev->alloc_block * dev->param.chunks_per_block +
+						dev->chunks_per_summary;
+	hdr.version = YAFFS_SUMMARY_VERSION;
+	hdr.block = blk;
+	hdr.seq = bi->seq_number;
+	hdr.sum = yaffs_summary_sum(dev);
+
+	do {
+		this_tx = n_bytes;
+		if (this_tx > sum_bytes_per_chunk)
+			this_tx = sum_bytes_per_chunk;
+		memcpy(buffer, &hdr, sizeof(hdr));
+		memcpy(buffer + sizeof(hdr), sum_buffer, this_tx);
+		tags.n_bytes = this_tx + sizeof(hdr);
+		result = yaffs_wr_chunk_tags_nand(dev, chunk_in_nand,
+						buffer, &tags);
+
+		if (result != YAFFS_OK)
+			break;
+		yaffs_set_chunk_bit(dev, blk, chunk_in_block);
+		bi->pages_in_use++;
+		dev->n_free_chunks--;
+
+		n_bytes -= this_tx;
+		sum_buffer += this_tx;
+		chunk_in_nand++;
+		chunk_in_block++;
+		tags.chunk_id++;
+	} while (result == YAFFS_OK && n_bytes > 0);
+	yaffs_release_temp_buffer(dev, buffer);
+
+
+	if (result == YAFFS_OK)
+		bi->has_summary = 1;
+
+
+	return result;
+}
+
+int yaffs_summary_read(struct yaffs_dev *dev,
+			struct yaffs_summary_tags *st,
+			int blk)
+{
+	struct yaffs_ext_tags tags;
+	u8 *buffer;
+	u8 *sum_buffer = (u8 *)st;
+	int n_bytes;
+	int chunk_id;
+	int chunk_in_nand;
+	int chunk_in_block;
+	int result;
+	int this_tx;
+	struct yaffs_summary_header hdr;
+	struct yaffs_block_info *bi = yaffs_get_block_info(dev, blk);
+	int sum_bytes_per_chunk = dev->data_bytes_per_chunk - sizeof(hdr);
+	int sum_tags_bytes;
+
+	sum_tags_bytes = sizeof(struct yaffs_summary_tags) *
+				dev->chunks_per_summary;
+	buffer = yaffs_get_temp_buffer(dev);
+	n_bytes = sizeof(struct yaffs_summary_tags) * dev->chunks_per_summary;
+	chunk_in_block = dev->chunks_per_summary;
+	chunk_in_nand = blk * dev->param.chunks_per_block +
+							dev->chunks_per_summary;
+	chunk_id = 1;
+	do {
+		this_tx = n_bytes;
+		if (this_tx > sum_bytes_per_chunk)
+			this_tx = sum_bytes_per_chunk;
+		result = yaffs_rd_chunk_tags_nand(dev, chunk_in_nand,
+						buffer, &tags);
+
+		if (tags.chunk_id != chunk_id ||
+			tags.obj_id != YAFFS_OBJECTID_SUMMARY ||
+			tags.chunk_used == 0 ||
+			tags.ecc_result > YAFFS_ECC_RESULT_FIXED ||
+			tags.n_bytes != (this_tx + sizeof(hdr)))
+				result = YAFFS_FAIL;
+		if (result != YAFFS_OK)
+			break;
+
+		if (st == dev->sum_tags) {
+			/* If we're scanning then update the block info */
+			yaffs_set_chunk_bit(dev, blk, chunk_in_block);
+			bi->pages_in_use++;
+		}
+		memcpy(&hdr, buffer, sizeof(hdr));
+		memcpy(sum_buffer, buffer + sizeof(hdr), this_tx);
+		n_bytes -= this_tx;
+		sum_buffer += this_tx;
+		chunk_in_nand++;
+		chunk_in_block++;
+		chunk_id++;
+	} while (result == YAFFS_OK && n_bytes > 0);
+	yaffs_release_temp_buffer(dev, buffer);
+
+	if (result == YAFFS_OK) {
+		/* Verify header */
+		if (hdr.version != YAFFS_SUMMARY_VERSION ||
+		    hdr.block != blk ||
+		    hdr.seq != bi->seq_number ||
+		    hdr.sum != yaffs_summary_sum(dev))
+			result = YAFFS_FAIL;
+	}
+
+	if (st == dev->sum_tags && result == YAFFS_OK)
+		bi->has_summary = 1;
+
+	return result;
+}
+
+int yaffs_summary_add(struct yaffs_dev *dev,
+			struct yaffs_ext_tags *tags,
+			int chunk_in_nand)
+{
+	struct yaffs_packed_tags2_tags_only tags_only;
+	struct yaffs_summary_tags *sum_tags;
+	int block_in_nand = chunk_in_nand / dev->param.chunks_per_block;
+	int chunk_in_block = chunk_in_nand % dev->param.chunks_per_block;
+
+	if (!dev->sum_tags)
+		return YAFFS_OK;
+
+	if (chunk_in_block >= 0 && chunk_in_block < dev->chunks_per_summary) {
+		yaffs_pack_tags2_tags_only(&tags_only, tags);
+		sum_tags = &dev->sum_tags[chunk_in_block];
+		sum_tags->chunk_id = tags_only.chunk_id;
+		sum_tags->n_bytes = tags_only.n_bytes;
+		sum_tags->obj_id = tags_only.obj_id;
+
+		if (chunk_in_block == dev->chunks_per_summary - 1) {
+			/* Time to write out the summary */
+			yaffs_summary_write(dev, block_in_nand);
+			yaffs_summary_clear(dev);
+			yaffs_skip_rest_of_block(dev);
+		}
+	}
+	return YAFFS_OK;
+}
+
+int yaffs_summary_fetch(struct yaffs_dev *dev,
+			struct yaffs_ext_tags *tags,
+			int chunk_in_block)
+{
+	struct yaffs_packed_tags2_tags_only tags_only;
+	struct yaffs_summary_tags *sum_tags;
+	if (chunk_in_block >= 0 && chunk_in_block < dev->chunks_per_summary) {
+		sum_tags = &dev->sum_tags[chunk_in_block];
+		tags_only.chunk_id = sum_tags->chunk_id;
+		tags_only.n_bytes = sum_tags->n_bytes;
+		tags_only.obj_id = sum_tags->obj_id;
+		yaffs_unpack_tags2_tags_only(tags, &tags_only);
+		return YAFFS_OK;
+	}
+	return YAFFS_FAIL;
+}
+
+void yaffs_summary_gc(struct yaffs_dev *dev, int blk)
+{
+	struct yaffs_block_info *bi = yaffs_get_block_info(dev, blk);
+	int i;
+
+	if (!bi->has_summary)
+		return;
+
+	for (i = dev->chunks_per_summary;
+	     i < dev->param.chunks_per_block;
+	     i++) {
+		if (yaffs_check_chunk_bit(dev, blk, i)) {
+			yaffs_clear_chunk_bit(dev, blk, i);
+			bi->pages_in_use--;
+			dev->n_free_chunks++;
+		}
+	}
+}
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_summary.h linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_summary.h
--- linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_summary.h	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_summary.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,37 @@
+/*
+ * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
+ *
+ * Copyright (C) 2002-2011 Aleph One Ltd.
+ *   for Toby Churchill Ltd and Brightstar Engineering
+ *
+ * Created by Charles Manning <charles@aleph1.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 2.1 as
+ * published by the Free Software Foundation.
+ *
+ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL.
+ */
+
+#ifndef __YAFFS_SUMMARY_H__
+#define __YAFFS_SUMMARY_H__
+
+#include "yaffs_packedtags2.h"
+
+
+int yaffs_summary_init(struct yaffs_dev *dev);
+void yaffs_summary_deinit(struct yaffs_dev *dev);
+
+int yaffs_summary_add(struct yaffs_dev *dev,
+			struct yaffs_ext_tags *tags,
+			int chunk_in_block);
+int yaffs_summary_fetch(struct yaffs_dev *dev,
+			struct yaffs_ext_tags *tags,
+			int chunk_in_block);
+int yaffs_summary_read(struct yaffs_dev *dev,
+			struct yaffs_summary_tags *st,
+			int blk);
+void yaffs_summary_gc(struct yaffs_dev *dev, int blk);
+
+
+#endif
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_tagscompat.c linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_tagscompat.c
--- linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_tagscompat.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_tagscompat.c	2014-07-29 17:28:38.819972000 +0800
@@ -1,7 +1,7 @@
 /*
  * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
  *
- * Copyright (C) 2002-2010 Aleph One Ltd.
+ * Copyright (C) 2002-2011 Aleph One Ltd.
  *   for Toby Churchill Ltd and Brightstar Engineering
  *
  * Created by Charles Manning <charles@aleph1.co.uk>
@@ -22,16 +22,15 @@
 
 /********** Tags ECC calculations  *********/
 
-void yaffs_calc_ecc(const u8 * data, struct yaffs_spare *spare)
+static void yaffs_calc_ecc(const u8 *data, struct yaffs_spare *spare)
 {
-	yaffs_ecc_cacl(data, spare->ecc1);
-	yaffs_ecc_cacl(&data[256], spare->ecc2);
+	yaffs_ecc_calc(data, spare->ecc1);
+	yaffs_ecc_calc(&data[256], spare->ecc2);
 }
 
 void yaffs_calc_tags_ecc(struct yaffs_tags *tags)
 {
 	/* Calculate an ecc */
-
 	unsigned char *b = ((union yaffs_tags_union *)tags)->as_bytes;
 	unsigned i, j;
 	unsigned ecc = 0;
@@ -46,9 +45,7 @@
 				ecc ^= bit;
 		}
 	}
-
 	tags->ecc = ecc;
-
 }
 
 int yaffs_check_tags_ecc(struct yaffs_tags *tags)
@@ -76,7 +73,6 @@
 		/* TODO Need to do somethiong here */
 		return -1;	/* unrecovered error */
 	}
-
 	return 0;
 }
 
@@ -124,11 +120,11 @@
 
 static void yaffs_spare_init(struct yaffs_spare *spare)
 {
-	memset(spare, 0xFF, sizeof(struct yaffs_spare));
+	memset(spare, 0xff, sizeof(struct yaffs_spare));
 }
 
 static int yaffs_wr_nand(struct yaffs_dev *dev,
-			 int nand_chunk, const u8 * data,
+			 int nand_chunk, const u8 *data,
 			 struct yaffs_spare *spare)
 {
 	if (nand_chunk < dev->param.start_block * dev->param.chunks_per_block) {
@@ -143,7 +139,7 @@
 
 static int yaffs_rd_chunk_nand(struct yaffs_dev *dev,
 			       int nand_chunk,
-			       u8 * data,
+			       u8 *data,
 			       struct yaffs_spare *spare,
 			       enum yaffs_ecc_result *ecc_result,
 			       int correct_errors)
@@ -151,7 +147,7 @@
 	int ret_val;
 	struct yaffs_spare local_spare;
 
-	if (!spare && data) {
+	if (!spare) {
 		/* If we don't have a real spare, then we use a local one. */
 		/* Need this for the calculation of the ecc */
 		spare = &local_spare;
@@ -166,10 +162,10 @@
 			int ecc_result1, ecc_result2;
 			u8 calc_ecc[3];
 
-			yaffs_ecc_cacl(data, calc_ecc);
+			yaffs_ecc_calc(data, calc_ecc);
 			ecc_result1 =
 			    yaffs_ecc_correct(data, spare->ecc1, calc_ecc);
-			yaffs_ecc_cacl(&data[256], calc_ecc);
+			yaffs_ecc_calc(&data[256], calc_ecc);
 			ecc_result2 =
 			    yaffs_ecc_correct(&data[256], spare->ecc2,
 					      calc_ecc);
@@ -268,9 +264,8 @@
 	int flash_block = nand_chunk / dev->param.chunks_per_block;
 
 	/* Mark the block for retirement */
-	yaffs_get_block_info(dev,
-			     flash_block + dev->block_offset)->needs_retiring =
-	    1;
+	yaffs_get_block_info(dev, flash_block + dev->block_offset)->
+		needs_retiring = 1;
 	yaffs_trace(YAFFS_TRACE_ERROR | YAFFS_TRACE_BAD_BLOCKS,
 		"**>>Block %d marked for retirement",
 		flash_block);
@@ -284,7 +279,7 @@
 
 int yaffs_tags_compat_wr(struct yaffs_dev *dev,
 			 int nand_chunk,
-			 const u8 * data, const struct yaffs_ext_tags *ext_tags)
+			 const u8 *data, const struct yaffs_ext_tags *ext_tags)
 {
 	struct yaffs_spare spare;
 	struct yaffs_tags tags;
@@ -297,7 +292,7 @@
 		tags.obj_id = ext_tags->obj_id;
 		tags.chunk_id = ext_tags->chunk_id;
 
-		tags.n_bytes_lsb = ext_tags->n_bytes & 0x3ff;
+		tags.n_bytes_lsb = ext_tags->n_bytes & (1024 - 1);
 
 		if (dev->data_bytes_per_chunk >= 1024)
 			tags.n_bytes_msb = (ext_tags->n_bytes >> 10) & 3;
@@ -310,69 +305,61 @@
 			yaffs_calc_ecc(data, &spare);
 
 		yaffs_load_tags_to_spare(&spare, &tags);
-
 	}
-
 	return yaffs_wr_nand(dev, nand_chunk, data, &spare);
 }
 
 int yaffs_tags_compat_rd(struct yaffs_dev *dev,
 			 int nand_chunk,
-			 u8 * data, struct yaffs_ext_tags *ext_tags)
+			 u8 *data, struct yaffs_ext_tags *ext_tags)
 {
-
 	struct yaffs_spare spare;
 	struct yaffs_tags tags;
 	enum yaffs_ecc_result ecc_result = YAFFS_ECC_RESULT_UNKNOWN;
-
 	static struct yaffs_spare spare_ff;
 	static int init;
+	int deleted;
 
 	if (!init) {
-		memset(&spare_ff, 0xFF, sizeof(spare_ff));
+		memset(&spare_ff, 0xff, sizeof(spare_ff));
 		init = 1;
 	}
 
-	if (yaffs_rd_chunk_nand(dev, nand_chunk, data, &spare, &ecc_result, 1)) {
-		/* ext_tags may be NULL */
-		if (ext_tags) {
-
-			int deleted =
-			    (hweight8(spare.page_status) < 7) ? 1 : 0;
-
-			ext_tags->is_deleted = deleted;
-			ext_tags->ecc_result = ecc_result;
-			ext_tags->block_bad = 0;	/* We're reading it */
-			/* therefore it is not a bad block */
-			ext_tags->chunk_used =
-			    (memcmp(&spare_ff, &spare, sizeof(spare_ff)) !=
-			     0) ? 1 : 0;
-
-			if (ext_tags->chunk_used) {
-				yaffs_get_tags_from_spare(dev, &spare, &tags);
-
-				ext_tags->obj_id = tags.obj_id;
-				ext_tags->chunk_id = tags.chunk_id;
-				ext_tags->n_bytes = tags.n_bytes_lsb;
-
-				if (dev->data_bytes_per_chunk >= 1024)
-					ext_tags->n_bytes |=
-					    (((unsigned)tags.
-					      n_bytes_msb) << 10);
-
-				ext_tags->serial_number = tags.serial_number;
-			}
-		}
+	if (!yaffs_rd_chunk_nand(dev, nand_chunk,
+					data, &spare, &ecc_result, 1))
+		return YAFFS_FAIL;
 
+	/* ext_tags may be NULL */
+	if (!ext_tags)
 		return YAFFS_OK;
-	} else {
-		return YAFFS_FAIL;
+
+	deleted = (hweight8(spare.page_status) < 7) ? 1 : 0;
+
+	ext_tags->is_deleted = deleted;
+	ext_tags->ecc_result = ecc_result;
+	ext_tags->block_bad = 0;	/* We're reading it */
+	/* therefore it is not a bad block */
+	ext_tags->chunk_used =
+		memcmp(&spare_ff, &spare, sizeof(spare_ff)) ? 1 : 0;
+
+	if (ext_tags->chunk_used) {
+		yaffs_get_tags_from_spare(dev, &spare, &tags);
+		ext_tags->obj_id = tags.obj_id;
+		ext_tags->chunk_id = tags.chunk_id;
+		ext_tags->n_bytes = tags.n_bytes_lsb;
+
+		if (dev->data_bytes_per_chunk >= 1024)
+			ext_tags->n_bytes |=
+				(((unsigned)tags.n_bytes_msb) << 10);
+
+		ext_tags->serial_number = tags.serial_number;
 	}
+
+	return YAFFS_OK;
 }
 
 int yaffs_tags_compat_mark_bad(struct yaffs_dev *dev, int flash_block)
 {
-
 	struct yaffs_spare spare;
 
 	memset(&spare, 0xff, sizeof(struct yaffs_spare));
@@ -385,22 +372,20 @@
 		      NULL, &spare);
 
 	return YAFFS_OK;
-
 }
 
 int yaffs_tags_compat_query_block(struct yaffs_dev *dev,
 				  int block_no,
 				  enum yaffs_block_state *state,
-				  u32 * seq_number)
+				  u32 *seq_number)
 {
-
 	struct yaffs_spare spare0, spare1;
 	static struct yaffs_spare spare_ff;
 	static int init;
 	enum yaffs_ecc_result dummy;
 
 	if (!init) {
-		memset(&spare_ff, 0xFF, sizeof(spare_ff));
+		memset(&spare_ff, 0xff, sizeof(spare_ff));
 		init = 1;
 	}
 
@@ -416,7 +401,7 @@
 	else if (memcmp(&spare_ff, &spare0, sizeof(spare_ff)) == 0)
 		*state = YAFFS_BLOCK_STATE_EMPTY;
 	else
-		*state = YAFFS_BLOCK_STATE_NEEDS_SCANNING;
+		*state = YAFFS_BLOCK_STATE_NEEDS_SCAN;
 
 	return YAFFS_OK;
 }
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_tagscompat.h linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_tagscompat.h
--- linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_tagscompat.h	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_tagscompat.h	2014-07-29 17:28:38.819972000 +0800
@@ -1,7 +1,7 @@
 /*
  * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
  *
- * Copyright (C) 2002-2010 Aleph One Ltd.
+ * Copyright (C) 2002-2011 Aleph One Ltd.
  *   for Toby Churchill Ltd and Brightstar Engineering
  *
  * Created by Charles Manning <charles@aleph1.co.uk>
@@ -19,15 +19,15 @@
 #include "yaffs_guts.h"
 int yaffs_tags_compat_wr(struct yaffs_dev *dev,
 			 int nand_chunk,
-			 const u8 * data, const struct yaffs_ext_tags *tags);
+			 const u8 *data, const struct yaffs_ext_tags *tags);
 int yaffs_tags_compat_rd(struct yaffs_dev *dev,
 			 int nand_chunk,
-			 u8 * data, struct yaffs_ext_tags *tags);
+			 u8 *data, struct yaffs_ext_tags *tags);
 int yaffs_tags_compat_mark_bad(struct yaffs_dev *dev, int block_no);
 int yaffs_tags_compat_query_block(struct yaffs_dev *dev,
 				  int block_no,
 				  enum yaffs_block_state *state,
-				  u32 * seq_number);
+				  u32 *seq_number);
 
 void yaffs_calc_tags_ecc(struct yaffs_tags *tags);
 int yaffs_check_tags_ecc(struct yaffs_tags *tags);
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_tagsvalidity.c linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_tagsvalidity.c
--- linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_tagsvalidity.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_tagsvalidity.c	1970-01-01 08:00:00.000000000 +0800
@@ -1,27 +0,0 @@
-/*
- * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
- *
- * Copyright (C) 2002-2010 Aleph One Ltd.
- *   for Toby Churchill Ltd and Brightstar Engineering
- *
- * Created by Charles Manning <charles@aleph1.co.uk>
- *
- * 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 "yaffs_tagsvalidity.h"
-
-void yaffs_init_tags(struct yaffs_ext_tags *tags)
-{
-	memset(tags, 0, sizeof(struct yaffs_ext_tags));
-	tags->validity0 = 0xAAAAAAAA;
-	tags->validity1 = 0x55555555;
-}
-
-int yaffs_validate_tags(struct yaffs_ext_tags *tags)
-{
-	return (tags->validity0 == 0xAAAAAAAA && tags->validity1 == 0x55555555);
-
-}
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_tagsvalidity.h linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_tagsvalidity.h
--- linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_tagsvalidity.h	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_tagsvalidity.h	1970-01-01 08:00:00.000000000 +0800
@@ -1,23 +0,0 @@
-/*
- * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
- *
- * Copyright (C) 2002-2010 Aleph One Ltd.
- *   for Toby Churchill Ltd and Brightstar Engineering
- *
- * Created by Charles Manning <charles@aleph1.co.uk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License version 2.1 as
- * published by the Free Software Foundation.
- *
- * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL.
- */
-
-#ifndef __YAFFS_TAGS_VALIDITY_H__
-#define __YAFFS_TAGS_VALIDITY_H__
-
-#include "yaffs_guts.h"
-
-void yaffs_init_tags(struct yaffs_ext_tags *tags);
-int yaffs_validate_tags(struct yaffs_ext_tags *tags);
-#endif
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_trace.h linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_trace.h
--- linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_trace.h	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_trace.h	2014-07-29 17:28:38.819972000 +0800
@@ -1,7 +1,7 @@
 /*
  * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
  *
- * Copyright (C) 2002-2010 Aleph One Ltd.
+ * Copyright (C) 2002-2011 Aleph One Ltd.
  *   for Toby Churchill Ltd and Brightstar Engineering
  *
  * Created by Charles Manning <charles@aleph1.co.uk>
@@ -43,7 +43,7 @@
 #define YAFFS_TRACE_VERIFY		0x00010000
 #define YAFFS_TRACE_VERIFY_NAND		0x00020000
 #define YAFFS_TRACE_VERIFY_FULL		0x00040000
-#define YAFFS_TRACE_VERIFY_ALL		0x000F0000
+#define YAFFS_TRACE_VERIFY_ALL		0x000f0000
 
 #define YAFFS_TRACE_SYNC		0x00100000
 #define YAFFS_TRACE_BACKGROUND		0x00200000
@@ -52,6 +52,6 @@
 
 #define YAFFS_TRACE_ERROR		0x40000000
 #define YAFFS_TRACE_BUG			0x80000000
-#define YAFFS_TRACE_ALWAYS		0xF0000000
+#define YAFFS_TRACE_ALWAYS		0xf0000000
 
 #endif
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_verify.c linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_verify.c
--- linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_verify.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_verify.c	2014-07-29 17:28:38.819972000 +0800
@@ -1,7 +1,7 @@
 /*
  * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
  *
- * Copyright (C) 2002-2010 Aleph One Ltd.
+ * Copyright (C) 2002-2011 Aleph One Ltd.
  *   for Toby Churchill Ltd and Brightstar Engineering
  *
  * Created by Charles Manning <charles@aleph1.co.uk>
@@ -19,26 +19,26 @@
 
 int yaffs_skip_verification(struct yaffs_dev *dev)
 {
-	dev = dev;
+	(void) dev;
 	return !(yaffs_trace_mask &
 		 (YAFFS_TRACE_VERIFY | YAFFS_TRACE_VERIFY_FULL));
 }
 
 static int yaffs_skip_full_verification(struct yaffs_dev *dev)
 {
-	dev = dev;
+	(void) dev;
 	return !(yaffs_trace_mask & (YAFFS_TRACE_VERIFY_FULL));
 }
 
 static int yaffs_skip_nand_verification(struct yaffs_dev *dev)
 {
-	dev = dev;
+	(void) dev;
 	return !(yaffs_trace_mask & (YAFFS_TRACE_VERIFY_NAND));
 }
 
-static const char *block_state_name[] = {
+static const char * const block_state_name[] = {
 	"Unknown",
-	"Needs scanning",
+	"Needs scan",
 	"Scanning",
 	"Empty",
 	"Allocating",
@@ -66,7 +66,7 @@
 	switch (bi->block_state) {
 	case YAFFS_BLOCK_STATE_UNKNOWN:
 	case YAFFS_BLOCK_STATE_SCANNING:
-	case YAFFS_BLOCK_STATE_NEEDS_SCANNING:
+	case YAFFS_BLOCK_STATE_NEEDS_SCAN:
 		yaffs_trace(YAFFS_TRACE_VERIFY,
 			"Block %d has bad run-state %s",
 			n, block_state_name[bi->block_state]);
@@ -76,11 +76,11 @@
 
 	actually_used = bi->pages_in_use - bi->soft_del_pages;
 
-	if (bi->pages_in_use < 0
-	    || bi->pages_in_use > dev->param.chunks_per_block
-	    || bi->soft_del_pages < 0
-	    || bi->soft_del_pages > dev->param.chunks_per_block
-	    || actually_used < 0 || actually_used > dev->param.chunks_per_block)
+	if (bi->pages_in_use < 0 ||
+	    bi->pages_in_use > dev->param.chunks_per_block ||
+	    bi->soft_del_pages < 0 ||
+	    bi->soft_del_pages > dev->param.chunks_per_block ||
+	    actually_used < 0 || actually_used > dev->param.chunks_per_block)
 		yaffs_trace(YAFFS_TRACE_VERIFY,
 			"Block %d has illegal values pages_in_used %d soft_del_pages %d",
 			n, bi->pages_in_use, bi->soft_del_pages);
@@ -91,7 +91,6 @@
 		yaffs_trace(YAFFS_TRACE_VERIFY,
 			"Block %d has inconsistent values pages_in_use %d counted chunk bits %d",
 			n, bi->pages_in_use, in_use);
-
 }
 
 void yaffs_verify_collected_blk(struct yaffs_dev *dev,
@@ -163,8 +162,8 @@
 }
 
 /*
- * Verify the object header. oh must be valid, but obj and tags may be NULL in which
- * case those tests will not be performed.
+ * Verify the object header. oh must be valid, but obj and tags may be NULL in
+ * which case those tests will not be performed.
  */
 void yaffs_verify_oh(struct yaffs_obj *obj, struct yaffs_obj_hdr *oh,
 		     struct yaffs_ext_tags *tags, int parent_check)
@@ -215,18 +214,21 @@
 			"Obj %d header name is NULL",
 			obj->obj_id);
 
-	if (tags->obj_id > 1 && ((u8) (oh->name[0])) == 0xff)	/* Trashed name */
+	if (tags->obj_id > 1 && ((u8) (oh->name[0])) == 0xff)	/* Junk name */
 		yaffs_trace(YAFFS_TRACE_VERIFY,
-			"Obj %d header name is 0xFF",
+			"Obj %d header name is 0xff",
 			obj->obj_id);
 }
 
 void yaffs_verify_file(struct yaffs_obj *obj)
 {
+	u32 x;
 	int required_depth;
 	int actual_depth;
-	u32 last_chunk;
-	u32 x;
+	int last_chunk;
+	u32 offset_in_chunk;
+	u32 the_chunk;
+
 	u32 i;
 	struct yaffs_dev *dev;
 	struct yaffs_ext_tags tags;
@@ -242,9 +244,11 @@
 	dev = obj->my_dev;
 	obj_id = obj->obj_id;
 
+
 	/* Check file size is consistent with tnode depth */
-	last_chunk =
-	    obj->variant.file_variant.file_size / dev->data_bytes_per_chunk + 1;
+	yaffs_addr_to_chunk(dev, obj->variant.file_variant.file_size,
+				&last_chunk, &offset_in_chunk);
+	last_chunk++;
 	x = last_chunk >> YAFFS_TNODES_LEVEL0_BITS;
 	required_depth = 0;
 	while (x > 0) {
@@ -265,17 +269,18 @@
 	for (i = 1; i <= last_chunk; i++) {
 		tn = yaffs_find_tnode_0(dev, &obj->variant.file_variant, i);
 
-		if (tn) {
-			u32 the_chunk = yaffs_get_group_base(dev, tn, i);
-			if (the_chunk > 0) {
-				yaffs_rd_chunk_tags_nand(dev, the_chunk, NULL,
-							 &tags);
-				if (tags.obj_id != obj_id || tags.chunk_id != i)
+		if (!tn)
+			continue;
+
+		the_chunk = yaffs_get_group_base(dev, tn, i);
+		if (the_chunk > 0) {
+			yaffs_rd_chunk_tags_nand(dev, the_chunk, NULL,
+						 &tags);
+			if (tags.obj_id != obj_id || tags.chunk_id != i)
 				yaffs_trace(YAFFS_TRACE_VERIFY,
 					"Object %d chunk_id %d NAND mismatch chunk %d tags (%d:%d)",
-					 obj_id, i, the_chunk,
-					 tags.obj_id, tags.chunk_id);
-			}
+					obj_id, i, the_chunk,
+					tags.obj_id, tags.chunk_id);
 		}
 	}
 }
@@ -305,10 +310,8 @@
 void yaffs_verify_obj(struct yaffs_obj *obj)
 {
 	struct yaffs_dev *dev;
-
 	u32 chunk_min;
 	u32 chunk_max;
-
 	u32 chunk_id_ok;
 	u32 chunk_in_range;
 	u32 chunk_wrongly_deleted;
@@ -350,7 +353,7 @@
 	if (chunk_valid && !yaffs_skip_nand_verification(dev)) {
 		struct yaffs_ext_tags tags;
 		struct yaffs_obj_hdr *oh;
-		u8 *buffer = yaffs_get_temp_buffer(dev, __LINE__);
+		u8 *buffer = yaffs_get_temp_buffer(dev);
 
 		oh = (struct yaffs_obj_hdr *)buffer;
 
@@ -358,7 +361,7 @@
 
 		yaffs_verify_oh(obj, oh, &tags, 1);
 
-		yaffs_release_temp_buffer(dev, buffer, __LINE__);
+		yaffs_release_temp_buffer(dev, buffer);
 	}
 
 	/* Verify it has a parent */
@@ -369,8 +372,8 @@
 	}
 
 	/* Verify parent is a directory */
-	if (obj->parent
-	    && obj->parent->variant_type != YAFFS_OBJECT_TYPE_DIRECTORY) {
+	if (obj->parent &&
+	    obj->parent->variant_type != YAFFS_OBJECT_TYPE_DIRECTORY) {
 		yaffs_trace(YAFFS_TRACE_VERIFY,
 			"Obj %d's parent is not a directory (type %d)",
 			obj->obj_id, obj->parent->variant_type);
@@ -414,11 +417,8 @@
 
 	for (i = 0; i < YAFFS_NOBJECT_BUCKETS; i++) {
 		list_for_each(lh, &dev->obj_bucket[i].list) {
-			if (lh) {
-				obj =
-				    list_entry(lh, struct yaffs_obj, hash_link);
-				yaffs_verify_obj(obj);
-			}
+			obj = list_entry(lh, struct yaffs_obj, hash_link);
+			yaffs_verify_obj(obj);
 		}
 	}
 }
@@ -427,12 +427,11 @@
 {
 	struct list_head *lh;
 	struct yaffs_obj *list_obj;
-
 	int count = 0;
 
 	if (!obj) {
 		yaffs_trace(YAFFS_TRACE_ALWAYS, "No object to verify");
-		YBUG();
+		BUG();
 		return;
 	}
 
@@ -440,32 +439,30 @@
 		return;
 
 	if (!obj->parent) {
-		yaffs_trace(YAFFS_TRACE_ALWAYS, "Object does not have parent" );
-		YBUG();
+		yaffs_trace(YAFFS_TRACE_ALWAYS, "Object does not have parent");
+		BUG();
 		return;
 	}
 
 	if (obj->parent->variant_type != YAFFS_OBJECT_TYPE_DIRECTORY) {
 		yaffs_trace(YAFFS_TRACE_ALWAYS, "Parent is not directory");
-		YBUG();
+		BUG();
 	}
 
 	/* Iterate through the objects in each hash entry */
 
 	list_for_each(lh, &obj->parent->variant.dir_variant.children) {
-		if (lh) {
-			list_obj = list_entry(lh, struct yaffs_obj, siblings);
-			yaffs_verify_obj(list_obj);
-			if (obj == list_obj)
-				count++;
-		}
+		list_obj = list_entry(lh, struct yaffs_obj, siblings);
+		yaffs_verify_obj(list_obj);
+		if (obj == list_obj)
+			count++;
 	}
 
 	if (count != 1) {
 		yaffs_trace(YAFFS_TRACE_ALWAYS,
 			"Object in directory %d times",
 			count);
-		YBUG();
+		BUG();
 	}
 }
 
@@ -475,7 +472,7 @@
 	struct yaffs_obj *list_obj;
 
 	if (!directory) {
-		YBUG();
+		BUG();
 		return;
 	}
 
@@ -486,22 +483,20 @@
 		yaffs_trace(YAFFS_TRACE_ALWAYS,
 			"Directory has wrong type: %d",
 			directory->variant_type);
-		YBUG();
+		BUG();
 	}
 
 	/* Iterate through the objects in each hash entry */
 
 	list_for_each(lh, &directory->variant.dir_variant.children) {
-		if (lh) {
-			list_obj = list_entry(lh, struct yaffs_obj, siblings);
-			if (list_obj->parent != directory) {
-				yaffs_trace(YAFFS_TRACE_ALWAYS,
-					"Object in directory list has wrong parent %p",
-					list_obj->parent);
-				YBUG();
-			}
-			yaffs_verify_obj_in_dir(list_obj);
+		list_obj = list_entry(lh, struct yaffs_obj, siblings);
+		if (list_obj->parent != directory) {
+			yaffs_trace(YAFFS_TRACE_ALWAYS,
+				"Object in directory list has wrong parent %p",
+				list_obj->parent);
+			BUG();
 		}
+		yaffs_verify_obj_in_dir(list_obj);
 	}
 }
 
@@ -521,7 +516,7 @@
 
 	if (difference) {
 		yaffs_trace(YAFFS_TRACE_ALWAYS,
-		 	"Freechunks verification failure %d %d %d",
+			"Freechunks verification failure %d %d %d",
 			dev->n_free_chunks, counted, difference);
 		yaffs_free_verification_failures++;
 	}
@@ -529,7 +524,6 @@
 
 int yaffs_verify_file_sane(struct yaffs_obj *in)
 {
-	in = in;
+	(void) in;
 	return YAFFS_OK;
 }
-
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_verify.h linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_verify.h
--- linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_verify.h	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_verify.h	2014-07-29 17:28:38.819972000 +0800
@@ -1,7 +1,7 @@
 /*
  * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
  *
- * Copyright (C) 2002-2010 Aleph One Ltd.
+ * Copyright (C) 2002-2011 Aleph One Ltd.
  *   for Toby Churchill Ltd and Brightstar Engineering
  *
  * Created by Charles Manning <charles@aleph1.co.uk>
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_vfs.c linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_vfs.c
--- linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_vfs.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_vfs.c	2014-07-29 17:28:38.819972000 +0800
@@ -1,7 +1,7 @@
 /*
  * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
  *
- * Copyright (C) 2002-2010 Aleph One Ltd.
+ * Copyright (C) 2002-2011 Aleph One Ltd.
  *   for Toby Churchill Ltd and Brightstar Engineering
  *
  * Created by Charles Manning <charles@aleph1.co.uk>
@@ -36,14 +36,12 @@
  * a single version and should not include any multi-version code.
  */
 #include <linux/version.h>
-
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/fs.h>
 #include <linux/proc_fs.h>
-#include <linux/smp_lock.h>
 #include <linux/pagemap.h>
 #include <linux/mtd/mtd.h>
 #include <linux/interrupt.h>
@@ -54,30 +52,8 @@
 #include <linux/kthread.h>
 #include <linux/delay.h>
 #include <linux/freezer.h>
-
 #include <asm/div64.h>
-
 #include <linux/statfs.h>
-
-#define UnlockPage(p) unlock_page(p)
-#define Page_Uptodate(page)	test_bit(PG_uptodate, &(page)->flags)
-
-#define yaffs_devname(sb, buf)	bdevname(sb->s_bdev, buf)
-
-#define YPROC_ROOT  NULL
-
-#define Y_INIT_TIMER(a)	init_timer_on_stack(a)
-
-#define WRITE_SIZE_STR "writesize"
-#define WRITE_SIZE(mtd) ((mtd)->writesize)
-
-static uint32_t YCALCBLOCKS(uint64_t partition_size, uint32_t block_size)
-{
-	uint64_t result = partition_size;
-	do_div(result, block_size);
-	return (uint32_t) result;
-}
-
 #include <linux/uaccess.h>
 #include <linux/mtd/mtd.h>
 
@@ -85,9 +61,7 @@
 #include "yaffs_trace.h"
 #include "yaffs_guts.h"
 #include "yaffs_attribs.h"
-
 #include "yaffs_linux.h"
-
 #include "yaffs_mtdif.h"
 #include "yaffs_mtdif1.h"
 #include "yaffs_mtdif2.h"
@@ -97,6 +71,7 @@
 unsigned int yaffs_auto_checkpoint = 1;
 unsigned int yaffs_gc_control = 1;
 unsigned int yaffs_bg_enable = 1;
+unsigned int yaffs_auto_select = 1;
 
 /* Module Parameters */
 module_param(yaffs_trace_mask, uint, 0644);
@@ -104,16 +79,27 @@
 module_param(yaffs_auto_checkpoint, uint, 0644);
 module_param(yaffs_gc_control, uint, 0644);
 module_param(yaffs_bg_enable, uint, 0644);
+module_param(yaffs_auto_select, uint, 0644);
+
+#define yaffs_devname(sb, buf)	bdevname(sb->s_bdev, buf)
 
+static uint32_t YCALCBLOCKS(uint64_t partition_size, uint32_t block_size)
+{
+	uint64_t result = partition_size;
+
+	do_div(result, block_size);
+	return (uint32_t) result;
+}
 
 #define yaffs_inode_to_obj_lv(iptr) ((iptr)->i_private)
-#define yaffs_inode_to_obj(iptr) ((struct yaffs_obj *)(yaffs_inode_to_obj_lv(iptr)))
+#define yaffs_inode_to_obj(iptr)\
+	((struct yaffs_obj *)(yaffs_inode_to_obj_lv(iptr)))
 #define yaffs_dentry_to_obj(dptr) yaffs_inode_to_obj((dptr)->d_inode)
 #define yaffs_super_to_dev(sb)	((struct yaffs_dev *)sb->s_fs_info)
 
 #define update_dir_time(dir) do {\
 			(dir)->i_ctime = (dir)->i_mtime = CURRENT_TIME; \
-		} while(0)
+		} while (0)
 
 
 static unsigned yaffs_gc_control_callback(struct yaffs_dev *dev)
@@ -159,7 +145,6 @@
 	yaffs_gross_lock(dev);
 
 	obj = yaffs_find_by_number(dev, inode->i_ino);
-
 	yaffs_fill_inode_from_obj(inode, obj);
 
 	yaffs_gross_unlock(dev);
@@ -202,17 +187,14 @@
 	return inode;
 }
 
-static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode,
+static int yaffs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
 		       dev_t rdev)
 {
 	struct inode *inode;
-
 	struct yaffs_obj *obj = NULL;
 	struct yaffs_dev *dev;
-
 	struct yaffs_obj *parent = yaffs_inode_to_obj(dir);
-
-	int error = -ENOSPC;
+	int error;
 	uid_t uid = current->cred->fsuid;
 	gid_t gid =
 	    (dir->i_mode & S_ISGID) ? dir->i_gid : current->cred->fsgid;
@@ -220,17 +202,17 @@
 	if ((dir->i_mode & S_ISGID) && S_ISDIR(mode))
 		mode |= S_ISGID;
 
-	if (parent) {
-		yaffs_trace(YAFFS_TRACE_OS,
-			"yaffs_mknod: parent object %d type %d",
-			parent->obj_id, parent->variant_type);
-	} else {
+	if (!parent) {
 		yaffs_trace(YAFFS_TRACE_OS,
 			"yaffs_mknod: could not get parent object");
 		return -EPERM;
 	}
 
 	yaffs_trace(YAFFS_TRACE_OS,
+			"yaffs_mknod: parent object %d type %d",
+			parent->obj_id, parent->variant_type);
+
+	yaffs_trace(YAFFS_TRACE_OS,
 		"yaffs_mknod: making oject for %s, mode %x dev %x",
 		dentry->d_name.name, mode, rdev);
 
@@ -238,6 +220,11 @@
 
 	yaffs_gross_lock(dev);
 
+	if (yaffs_get_n_free_chunks(dev) < 1) {
+		error = -ENOSPC;
+		goto err_out;
+	}
+
 	switch (mode & S_IFMT) {
 	default:
 		/* Special (socket, fifo, device...) */
@@ -262,32 +249,37 @@
 		break;
 	}
 
+	if (!obj) {
+		error = -ENOMEM;
+		goto err_out;
+	}
+
 	/* Can not call yaffs_get_inode() with gross lock held */
 	yaffs_gross_unlock(dev);
 
-	if (obj) {
-		inode = yaffs_get_inode(dir->i_sb, mode, rdev, obj);
-		d_instantiate(dentry, inode);
-		update_dir_time(dir);
-		yaffs_trace(YAFFS_TRACE_OS,
-			"yaffs_mknod created object %d count = %d",
-			obj->obj_id, atomic_read(&inode->i_count));
-		error = 0;
-		yaffs_fill_inode_from_obj(dir, parent);
-	} else {
-		yaffs_trace(YAFFS_TRACE_OS, "yaffs_mknod failed making object");
-		error = -ENOMEM;
-	}
 
+	inode = yaffs_get_inode(dir->i_sb, mode, rdev, obj);
+	d_instantiate(dentry, inode);
+	update_dir_time(dir);
+	yaffs_trace(YAFFS_TRACE_OS,
+		"yaffs_mknod created object %d count = %d",
+		obj->obj_id, atomic_read(&inode->i_count));
+	yaffs_fill_inode_from_obj(dir, parent);
+	return 0;
+
+err_out:
+	yaffs_gross_unlock(dev);
+	yaffs_trace(YAFFS_TRACE_OS, "yaffs_mknod error %d", error);
 	return error;
+
 }
 
-static int yaffs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
+static int yaffs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
 {
 	return yaffs_mknod(dir, dentry, mode | S_IFDIR, 0);
 }
 
-static int yaffs_create(struct inode *dir, struct dentry *dentry, int mode,
+static int yaffs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
 			struct nameidata *n)
 {
 	return yaffs_mknod(dir, dentry, mode | S_IFREG, 0);
@@ -314,7 +306,7 @@
 				   obj);
 
 	if (link) {
-		old_dentry->d_inode->i_nlink = yaffs_get_obj_link_count(obj);
+		set_nlink(old_dentry->d_inode, yaffs_get_obj_link_count(obj));
 		d_instantiate(dentry, old_dentry->d_inode);
 		atomic_inc(&old_dentry->d_inode->i_count);
 		yaffs_trace(YAFFS_TRACE_OS,
@@ -338,31 +330,38 @@
 {
 	struct yaffs_obj *obj;
 	struct yaffs_dev *dev;
+	struct inode *inode;
 	uid_t uid = current->cred->fsuid;
 	gid_t gid =
 	    (dir->i_mode & S_ISGID) ? dir->i_gid : current->cred->fsgid;
 
 	yaffs_trace(YAFFS_TRACE_OS, "yaffs_symlink");
 
+	if (strnlen(dentry->d_name.name, YAFFS_MAX_NAME_LENGTH + 1) >
+				YAFFS_MAX_NAME_LENGTH)
+		return -ENAMETOOLONG;
+
+	if (strnlen(symname, YAFFS_MAX_ALIAS_LENGTH + 1) >
+				YAFFS_MAX_ALIAS_LENGTH)
+		return -ENAMETOOLONG;
+
 	dev = yaffs_inode_to_obj(dir)->my_dev;
 	yaffs_gross_lock(dev);
 	obj = yaffs_create_symlink(yaffs_inode_to_obj(dir), dentry->d_name.name,
 				   S_IFLNK | S_IRWXUGO, uid, gid, symname);
 	yaffs_gross_unlock(dev);
 
-	if (obj) {
-		struct inode *inode;
-
-		inode = yaffs_get_inode(dir->i_sb, obj->yst_mode, 0, obj);
-		d_instantiate(dentry, inode);
-		update_dir_time(dir);
-		yaffs_trace(YAFFS_TRACE_OS, "symlink created OK");
-		return 0;
-	} else {
+	if (!obj) {
 		yaffs_trace(YAFFS_TRACE_OS, "symlink not created");
+		return -ENOMEM;
 	}
 
-	return -ENOMEM;
+	inode = yaffs_get_inode(dir->i_sb, obj->yst_mode, 0, obj);
+	d_instantiate(dentry, inode);
+	update_dir_time(dir);
+	yaffs_trace(YAFFS_TRACE_OS, "symlink created OK");
+
+	return 0;
 }
 
 static struct dentry *yaffs_lookup(struct inode *dir, struct dentry *dentry,
@@ -370,7 +369,6 @@
 {
 	struct yaffs_obj *obj;
 	struct inode *inode = NULL;
-
 	struct yaffs_dev *dev = yaffs_inode_to_obj(dir)->my_dev;
 
 	if (current != yaffs_dev_to_lc(dev)->readdir_process)
@@ -414,7 +412,6 @@
 static int yaffs_unlink(struct inode *dir, struct dentry *dentry)
 {
 	int ret_val;
-
 	struct yaffs_dev *dev;
 	struct yaffs_obj *obj;
 
@@ -429,10 +426,9 @@
 	ret_val = yaffs_unlinker(obj, dentry->d_name.name);
 
 	if (ret_val == YAFFS_OK) {
-		dentry->d_inode->i_nlink--;
+		inode_dec_link_count(dentry->d_inode);
 		dir->i_version++;
 		yaffs_gross_unlock(dev);
-		mark_inode_dirty(dentry->d_inode);
 		update_dir_time(dir);
 		return 0;
 	}
@@ -440,7 +436,8 @@
 	return -ENOTEMPTY;
 }
 
-static int yaffs_sync_object(struct file *file, int datasync)
+static int yaffs_sync_object(struct file *file,
+				loff_t start, loff_t end, int datasync)
 {
 
 	struct yaffs_obj *obj;
@@ -496,10 +493,8 @@
 	yaffs_gross_unlock(dev);
 
 	if (ret_val == YAFFS_OK) {
-		if (target) {
-			new_dentry->d_inode->i_nlink--;
-			mark_inode_dirty(new_dentry->d_inode);
-		}
+		if (target)
+			inode_dec_link_count(new_dentry->d_inode);
 
 		update_dir_time(old_dir);
 		if (old_dir != new_dir)
@@ -515,6 +510,7 @@
 	struct inode *inode = dentry->d_inode;
 	int error = 0;
 	struct yaffs_dev *dev;
+	int result;
 
 	yaffs_trace(YAFFS_TRACE_OS,
 		"yaffs_setattr of object %d",
@@ -524,17 +520,15 @@
 	if (attr->ia_valid & ATTR_SIZE && (attr->ia_size >> 31))
 		error = -EINVAL;
 
-	if (error == 0)
+	if (!error)
 		error = inode_change_ok(inode, attr);
-	if (error == 0) {
-		int result;
-		if (!error) {
-			setattr_copy(inode, attr);
-			yaffs_trace(YAFFS_TRACE_OS, "inode_setattr called");
-			if (attr->ia_valid & ATTR_SIZE) {
-				truncate_setsize(inode, attr->ia_size);
-				inode->i_blocks = (inode->i_size + 511) >> 9;
-			}
+
+	if (!error) {
+		setattr_copy(inode, attr);
+		yaffs_trace(YAFFS_TRACE_OS, "inode_setattr called");
+		if (attr->ia_valid & ATTR_SIZE) {
+			truncate_setsize(inode, attr->ia_size);
+			inode->i_blocks = (inode->i_size + 511) >> 9;
 		}
 		dev = yaffs_inode_to_obj(inode)->my_dev;
 		if (attr->ia_valid & ATTR_SIZE) {
@@ -542,15 +536,12 @@
 					   (int)(attr->ia_size),
 					   (int)(attr->ia_size));
 		}
+
 		yaffs_gross_lock(dev);
 		result = yaffs_set_attribs(yaffs_inode_to_obj(inode), attr);
-		if (result == YAFFS_OK) {
-			error = 0;
-		} else {
+		if (result != YAFFS_OK)
 			error = -EPERM;
-		}
 		yaffs_gross_unlock(dev);
-
 	}
 
 	yaffs_trace(YAFFS_TRACE_OS, "yaffs_setattr done returning %d", error);
@@ -558,39 +549,31 @@
 	return error;
 }
 
-#ifdef CONFIG_YAFFS_XATTR
 static int yaffs_setxattr(struct dentry *dentry, const char *name,
 		   const void *value, size_t size, int flags)
 {
 	struct inode *inode = dentry->d_inode;
-	int error = 0;
+	int error;
 	struct yaffs_dev *dev;
 	struct yaffs_obj *obj = yaffs_inode_to_obj(inode);
 
 	yaffs_trace(YAFFS_TRACE_OS, "yaffs_setxattr of object %d", obj->obj_id);
 
-	if (error == 0) {
-		int result;
-		dev = obj->my_dev;
-		yaffs_gross_lock(dev);
-		result = yaffs_set_xattrib(obj, name, value, size, flags);
-		if (result == YAFFS_OK)
-			error = 0;
-		else if (result < 0)
-			error = result;
-		yaffs_gross_unlock(dev);
+	dev = obj->my_dev;
+	yaffs_gross_lock(dev);
+	error = yaffs_set_xattrib(obj, name, value, size, flags);
+	yaffs_gross_unlock(dev);
 
-	}
 	yaffs_trace(YAFFS_TRACE_OS, "yaffs_setxattr done returning %d", error);
 
 	return error;
 }
 
-static ssize_t yaffs_getxattr(struct dentry * dentry, const char *name, void *buff,
-		       size_t size)
+static ssize_t yaffs_getxattr(struct dentry *dentry, const char *name,
+				void *buff, size_t size)
 {
 	struct inode *inode = dentry->d_inode;
-	int error = 0;
+	int error;
 	struct yaffs_dev *dev;
 	struct yaffs_obj *obj = yaffs_inode_to_obj(inode);
 
@@ -598,13 +581,11 @@
 		"yaffs_getxattr \"%s\" from object %d",
 		name, obj->obj_id);
 
-	if (error == 0) {
-		dev = obj->my_dev;
-		yaffs_gross_lock(dev);
-		error = yaffs_get_xattrib(obj, name, buff, size);
-		yaffs_gross_unlock(dev);
+	dev = obj->my_dev;
+	yaffs_gross_lock(dev);
+	error = yaffs_get_xattrib(obj, name, buff, size);
+	yaffs_gross_unlock(dev);
 
-	}
 	yaffs_trace(YAFFS_TRACE_OS, "yaffs_getxattr done returning %d", error);
 
 	return error;
@@ -613,56 +594,45 @@
 static int yaffs_removexattr(struct dentry *dentry, const char *name)
 {
 	struct inode *inode = dentry->d_inode;
-	int error = 0;
+	int error;
 	struct yaffs_dev *dev;
 	struct yaffs_obj *obj = yaffs_inode_to_obj(inode);
 
 	yaffs_trace(YAFFS_TRACE_OS,
 		"yaffs_removexattr of object %d", obj->obj_id);
 
-	if (error == 0) {
-		int result;
-		dev = obj->my_dev;
-		yaffs_gross_lock(dev);
-		result = yaffs_remove_xattrib(obj, name);
-		if (result == YAFFS_OK)
-			error = 0;
-		else if (result < 0)
-			error = result;
-		yaffs_gross_unlock(dev);
+	dev = obj->my_dev;
+	yaffs_gross_lock(dev);
+	error = yaffs_remove_xattrib(obj, name);
+	yaffs_gross_unlock(dev);
 
-	}
 	yaffs_trace(YAFFS_TRACE_OS,
 		"yaffs_removexattr done returning %d", error);
 
 	return error;
 }
 
-static ssize_t yaffs_listxattr(struct dentry * dentry, char *buff, size_t size)
+static ssize_t yaffs_listxattr(struct dentry *dentry, char *buff, size_t size)
 {
 	struct inode *inode = dentry->d_inode;
-	int error = 0;
+	int error;
 	struct yaffs_dev *dev;
 	struct yaffs_obj *obj = yaffs_inode_to_obj(inode);
 
 	yaffs_trace(YAFFS_TRACE_OS,
 		"yaffs_listxattr of object %d", obj->obj_id);
 
-	if (error == 0) {
-		dev = obj->my_dev;
-		yaffs_gross_lock(dev);
-		error = yaffs_list_xattrib(obj, buff, size);
-		yaffs_gross_unlock(dev);
+	dev = obj->my_dev;
+	yaffs_gross_lock(dev);
+	error = yaffs_list_xattrib(obj, buff, size);
+	yaffs_gross_unlock(dev);
 
-	}
 	yaffs_trace(YAFFS_TRACE_OS,
 		"yaffs_listxattr done returning %d", error);
 
 	return error;
 }
 
-#endif
-
 static const struct inode_operations yaffs_dir_inode_operations = {
 	.create = yaffs_create,
 	.lookup = yaffs_lookup,
@@ -674,12 +644,10 @@
 	.mknod = yaffs_mknod,
 	.rename = yaffs_rename,
 	.setattr = yaffs_setattr,
-#ifdef CONFIG_YAFFS_XATTR
 	.setxattr = yaffs_setxattr,
 	.getxattr = yaffs_getxattr,
 	.listxattr = yaffs_listxattr,
 	.removexattr = yaffs_removexattr,
-#endif
 };
 /*-----------------------------------------------------------------*/
 /* Directory search context allows us to unlock access to yaffs during
@@ -718,18 +686,21 @@
 	struct yaffs_dev *dev = dir->my_dev;
 	struct yaffs_search_context *sc =
 	    kmalloc(sizeof(struct yaffs_search_context), GFP_NOFS);
-	if (sc) {
-		sc->dir_obj = dir;
-		sc->dev = dev;
-		if (list_empty(&sc->dir_obj->variant.dir_variant.children))
-			sc->next_return = NULL;
-		else
-			sc->next_return =
-			    list_entry(dir->variant.dir_variant.children.next,
-				       struct yaffs_obj, siblings);
-		INIT_LIST_HEAD(&sc->others);
-		list_add(&sc->others, &(yaffs_dev_to_lc(dev)->search_contexts));
-	}
+
+	if (!sc)
+		return NULL;
+
+	sc->dir_obj = dir;
+	sc->dev = dev;
+	if (list_empty(&sc->dir_obj->variant.dir_variant.children))
+		sc->next_return = NULL;
+	else
+		sc->next_return =
+		    list_entry(dir->variant.dir_variant.children.next,
+			       struct yaffs_obj, siblings);
+	INIT_LIST_HEAD(&sc->others);
+	list_add(&sc->others, &(yaffs_dev_to_lc(dev)->search_contexts));
+
 	return sc;
 }
 
@@ -786,11 +757,9 @@
 	 * the search context to the next object to prevent a hanging pointer.
 	 */
 	list_for_each(i, search_contexts) {
-		if (i) {
-			sc = list_entry(i, struct yaffs_search_context, others);
-			if (sc->next_return == obj)
-				yaffs_search_advance(sc);
-		}
+		sc = list_entry(i, struct yaffs_search_context, others);
+		if (sc->next_return == obj)
+			yaffs_search_advance(sc);
 	}
 
 }
@@ -804,7 +773,6 @@
 	unsigned long offset, curoffs;
 	struct yaffs_obj *l;
 	int ret_val = 0;
-
 	char name[YAFFS_MAX_NAME_LENGTH + 1];
 
 	obj = yaffs_dentry_to_obj(f->f_dentry);
@@ -914,11 +882,10 @@
 static int yaffs_file_flush(struct file *file, fl_owner_t id)
 {
 	struct yaffs_obj *obj = yaffs_dentry_to_obj(file->f_dentry);
-
 	struct yaffs_dev *dev = obj->my_dev;
 
 	yaffs_trace(YAFFS_TRACE_OS,
-	  	"yaffs_file_flush object %d (%s)",
+		"yaffs_file_flush object %d (%s)",
 		obj->obj_id, obj->dirty ? "dirty" : "clean");
 
 	yaffs_gross_lock(dev);
@@ -996,7 +963,6 @@
 			}
 		}
 	}
-
 	return parent;
 }
 
@@ -1018,7 +984,6 @@
 {
 	unsigned char *alias;
 	int ret;
-
 	struct yaffs_dev *dev = yaffs_dentry_to_obj(dentry)->my_dev;
 
 	yaffs_gross_lock(dev);
@@ -1132,14 +1097,15 @@
 	struct yaffs_obj *obj;
 	unsigned char *pg_buf;
 	int ret;
-
 	struct yaffs_dev *dev;
+	loff_t pos = ((loff_t) pg->index) << PAGE_CACHE_SHIFT;
 
 	yaffs_trace(YAFFS_TRACE_OS,
-		"yaffs_readpage_nolock at %08x, size %08x",
-		(unsigned)(pg->index << PAGE_CACHE_SHIFT),
+		"yaffs_readpage_nolock at %lld, size %08x",
+		(long long)pos,
 		(unsigned)PAGE_CACHE_SIZE);
 
+
 	obj = yaffs_dentry_to_obj(f->f_dentry);
 
 	dev = obj->my_dev;
@@ -1151,8 +1117,7 @@
 
 	yaffs_gross_lock(dev);
 
-	ret = yaffs_file_rd(obj, pg_buf,
-			    pg->index << PAGE_CACHE_SHIFT, PAGE_CACHE_SIZE);
+	ret = yaffs_file_rd(obj, pg_buf, pos, PAGE_CACHE_SIZE);
 
 	yaffs_gross_unlock(dev);
 
@@ -1177,7 +1142,8 @@
 static int yaffs_readpage_unlock(struct file *f, struct page *pg)
 {
 	int ret = yaffs_readpage_nolock(f, pg);
-	UnlockPage(pg);
+
+	unlock_page(pg);
 	return ret;
 }
 
@@ -1254,7 +1220,8 @@
 		(int)obj->variant.file_variant.file_size, (int)inode->i_size);
 
 	n_written = yaffs_wr_file(obj, buffer,
-				  page->index << PAGE_CACHE_SHIFT, n_bytes, 0);
+				  ((loff_t)page->index) << PAGE_CACHE_SHIFT,
+				  n_bytes, 0);
 
 	yaffs_touch_super(dev);
 
@@ -1273,18 +1240,17 @@
 	return (n_written == n_bytes) ? 0 : -ENOSPC;
 }
 
-/* Space holding and freeing is done to ensure we have space available for 
+/* Space holding and freeing is done to ensure we have space available for
  * write_begin/end.
  * For now we just assume few parallel writes and check against a small
  * number.
- * Todo: need to do this with a counter to handle parallel reads better.
+ * Todo: need to do this with a counter to handle parallel reads better
  */
 
 static ssize_t yaffs_hold_space(struct file *f)
 {
 	struct yaffs_obj *obj;
 	struct yaffs_dev *dev;
-
 	int n_free_chunks;
 
 	obj = yaffs_dentry_to_obj(f->f_dentry);
@@ -1320,7 +1286,6 @@
 {
 	struct page *pg = NULL;
 	pgoff_t index = pos >> PAGE_CACHE_SHIFT;
-
 	int ret = 0;
 	int space_held = 0;
 
@@ -1334,7 +1299,7 @@
 	}
 	yaffs_trace(YAFFS_TRACE_OS,
 		"start yaffs_write_begin index %d(%x) uptodate %d",
-		(int)index, (int)index, Page_Uptodate(pg) ? 1 : 0);
+		(int)index, (int)index, PageUptodate(pg) ? 1 : 0);
 
 	/* Get fs space */
 	space_held = yaffs_hold_space(filp);
@@ -1346,7 +1311,7 @@
 
 	/* Update page if required */
 
-	if (!Page_Uptodate(pg))
+	if (!PageUptodate(pg))
 		ret = yaffs_readpage_nolock(filp, pg);
 
 	if (ret)
@@ -1370,7 +1335,7 @@
 }
 
 static ssize_t yaffs_file_write(struct file *f, const char *buf, size_t n,
-				loff_t * pos)
+				loff_t *pos)
 {
 	struct yaffs_obj *obj;
 	int n_written, ipos;
@@ -1379,6 +1344,13 @@
 
 	obj = yaffs_dentry_to_obj(f->f_dentry);
 
+	if (!obj) {
+		/* This should not happen */
+		yaffs_trace(YAFFS_TRACE_OS,
+			"yaffs_file_write: hey obj is null!");
+		return -EINVAL;
+	}
+
 	dev = obj->my_dev;
 
 	yaffs_gross_lock(dev);
@@ -1390,13 +1362,9 @@
 	else
 		ipos = *pos;
 
-	if (!obj)
-		yaffs_trace(YAFFS_TRACE_OS,
-			"yaffs_file_write: hey obj is null!");
-	else
-		yaffs_trace(YAFFS_TRACE_OS,
-			"yaffs_file_write about to write writing %u(%x) bytes to object %d at %d(%x)",
-			(unsigned)n, (unsigned)n, obj->obj_id, ipos, ipos);
+	yaffs_trace(YAFFS_TRACE_OS,
+		"yaffs_file_write about to write writing %u(%x) bytes to object %d at %d(%x)",
+		(unsigned)n, (unsigned)n, obj->obj_id, ipos, ipos);
 
 	n_written = yaffs_wr_file(obj, buf, ipos, n, 0);
 
@@ -1417,7 +1385,6 @@
 				"yaffs_file_write size updated to %d bytes, %d blocks",
 				ipos, (int)(inode->i_blocks));
 		}
-
 	}
 	yaffs_gross_unlock(dev);
 	return (n_written == 0) && (n > 0) ? -ENOSPC : n_written;
@@ -1476,11 +1443,12 @@
 
 		bytes_in_dev =
 		    ((uint64_t)
-		     ((dev->param.end_block - dev->param.start_block +
-		       1))) * ((uint64_t) (dev->param.chunks_per_block *
+		     ((dev->param.end_block - dev->param.start_block + 1))) *
+		     ((uint64_t) (dev->param.chunks_per_block *
 					   dev->data_bytes_per_chunk));
 
-		do_div(bytes_in_dev, sb->s_blocksize);	/* bytes_in_dev becomes the number of blocks */
+		do_div(bytes_in_dev, sb->s_blocksize);
+			/* bytes_in_dev becomes the number of blocks */
 		buf->f_blocks = bytes_in_dev;
 
 		bytes_free = ((uint64_t) (yaffs_get_n_free_chunks(dev))) *
@@ -1536,6 +1504,7 @@
 static void yaffs_flush_super(struct super_block *sb, int do_checkpoint)
 {
 	struct yaffs_dev *dev = yaffs_super_to_dev(sb);
+
 	if (!dev)
 		return;
 
@@ -1604,7 +1573,7 @@
  * yaffs_bg_start() launches the background thread.
  * yaffs_bg_stop() cleans up the background thread.
  *
- * NB: 
+ * NB:
  * The thread should only run after the yaffs is initialised
  * The thread should be stopped before yaffs is unmounted.
  * The thread should not do any writing while the fs is in read only.
@@ -1624,7 +1593,6 @@
 	unsigned long next_gc = now;
 	unsigned long expires;
 	unsigned int urgency;
-
 	int gc_result;
 	struct timer_list timer;
 
@@ -1661,12 +1629,12 @@
 				else
 					next_gc = now + HZ * 2;
 			} else	{
-			        /*
+				/*
 				 * gc not running so set to next_dir_update
 				 * to cut down on wake ups
 				 */
 				next_gc = next_dir_update;
-                        }
+			}
 		}
 		yaffs_gross_unlock(dev);
 		expires = next_dir_update;
@@ -1675,7 +1643,7 @@
 		if (time_before(expires, now))
 			expires = now + HZ;
 
-		Y_INIT_TIMER(&timer);
+		init_timer_on_stack(&timer);
 		timer.expires = expires + 1;
 		timer.data = (unsigned long)current;
 		timer.function = yaffs_background_waker;
@@ -1747,12 +1715,9 @@
 	return 0;
 }
 
-
 static LIST_HEAD(yaffs_context_list);
 struct mutex yaffs_context_lock;
 
-
-
 struct yaffs_options {
 	int inband_tags;
 	int skip_checkpoint_read;
@@ -1768,7 +1733,7 @@
 
 #define MAX_OPT_LEN 30
 static int yaffs_parse_options(struct yaffs_options *options,
-			       const char *options_str)
+				const char *options_str)
 {
 	char cur_opt[MAX_OPT_LEN + 1];
 	int p;
@@ -1826,11 +1791,10 @@
 			error = 1;
 		}
 	}
-
 	return error;
 }
 
-static struct address_space_operations yaffs_file_address_operations = {
+static const struct address_space_operations yaffs_file_address_operations = {
 	.readpage = yaffs_readpage,
 	.writepage = yaffs_writepage,
 	.write_begin = yaffs_write_begin,
@@ -1841,12 +1805,10 @@
 
 static const struct inode_operations yaffs_file_inode_operations = {
 	.setattr = yaffs_setattr,
-#ifdef CONFIG_YAFFS_XATTR
 	.setxattr = yaffs_setxattr,
 	.getxattr = yaffs_getxattr,
 	.listxattr = yaffs_listxattr,
 	.removexattr = yaffs_removexattr,
-#endif
 };
 
 static const struct inode_operations yaffs_symlink_inode_operations = {
@@ -1854,104 +1816,97 @@
 	.follow_link = yaffs_follow_link,
 	.put_link = yaffs_put_link,
 	.setattr = yaffs_setattr,
-#ifdef CONFIG_YAFFS_XATTR
 	.setxattr = yaffs_setxattr,
 	.getxattr = yaffs_getxattr,
 	.listxattr = yaffs_listxattr,
 	.removexattr = yaffs_removexattr,
-#endif
 };
 
 static void yaffs_fill_inode_from_obj(struct inode *inode,
 				      struct yaffs_obj *obj)
 {
-	if (inode && obj) {
-
-		/* Check mode against the variant type and attempt to repair if broken. */
-		u32 mode = obj->yst_mode;
-		switch (obj->variant_type) {
-		case YAFFS_OBJECT_TYPE_FILE:
-			if (!S_ISREG(mode)) {
-				obj->yst_mode &= ~S_IFMT;
-				obj->yst_mode |= S_IFREG;
-			}
+	u32 mode;
 
-			break;
-		case YAFFS_OBJECT_TYPE_SYMLINK:
-			if (!S_ISLNK(mode)) {
-				obj->yst_mode &= ~S_IFMT;
-				obj->yst_mode |= S_IFLNK;
-			}
-
-			break;
-		case YAFFS_OBJECT_TYPE_DIRECTORY:
-			if (!S_ISDIR(mode)) {
-				obj->yst_mode &= ~S_IFMT;
-				obj->yst_mode |= S_IFDIR;
-			}
+	if (!inode || !obj)  {
+		yaffs_trace(YAFFS_TRACE_OS,
+			"yaffs_fill_inode invalid parameters");
+		return;
+	}
 
-			break;
-		case YAFFS_OBJECT_TYPE_UNKNOWN:
-		case YAFFS_OBJECT_TYPE_HARDLINK:
-		case YAFFS_OBJECT_TYPE_SPECIAL:
-		default:
-			/* TODO? */
-			break;
+	/* Check mode against the variant type
+	 * and attempt to repair if broken. */
+	mode = obj->yst_mode;
+
+	switch (obj->variant_type) {
+	case YAFFS_OBJECT_TYPE_FILE:
+		if (!S_ISREG(mode)) {
+			obj->yst_mode &= ~S_IFMT;
+			obj->yst_mode |= S_IFREG;
 		}
-
-		inode->i_flags |= S_NOATIME;
-
-		inode->i_ino = obj->obj_id;
-		inode->i_mode = obj->yst_mode;
-		inode->i_uid = obj->yst_uid;
-		inode->i_gid = obj->yst_gid;
-
-		inode->i_rdev = old_decode_dev(obj->yst_rdev);
-
-		inode->i_atime.tv_sec = (time_t) (obj->yst_atime);
-		inode->i_atime.tv_nsec = 0;
-		inode->i_mtime.tv_sec = (time_t) obj->yst_mtime;
-		inode->i_mtime.tv_nsec = 0;
-		inode->i_ctime.tv_sec = (time_t) obj->yst_ctime;
-		inode->i_ctime.tv_nsec = 0;
-		inode->i_size = yaffs_get_obj_length(obj);
-		inode->i_blocks = (inode->i_size + 511) >> 9;
-
-		inode->i_nlink = yaffs_get_obj_link_count(obj);
-
-		yaffs_trace(YAFFS_TRACE_OS,
-			"yaffs_fill_inode mode %x uid %d gid %d size %d count %d",
-			inode->i_mode, inode->i_uid, inode->i_gid,
-			(int)inode->i_size, atomic_read(&inode->i_count));
-
-		switch (obj->yst_mode & S_IFMT) {
-		default:	/* fifo, device or socket */
-			init_special_inode(inode, obj->yst_mode,
-					   old_decode_dev(obj->yst_rdev));
-			break;
-		case S_IFREG:	/* file */
-			inode->i_op = &yaffs_file_inode_operations;
-			inode->i_fop = &yaffs_file_operations;
-			inode->i_mapping->a_ops =
-			    &yaffs_file_address_operations;
-			break;
-		case S_IFDIR:	/* directory */
-			inode->i_op = &yaffs_dir_inode_operations;
-			inode->i_fop = &yaffs_dir_operations;
-			break;
-		case S_IFLNK:	/* symlink */
-			inode->i_op = &yaffs_symlink_inode_operations;
-			break;
+		break;
+	case YAFFS_OBJECT_TYPE_SYMLINK:
+		if (!S_ISLNK(mode)) {
+			obj->yst_mode &= ~S_IFMT;
+			obj->yst_mode |= S_IFLNK;
 		}
+		break;
+	case YAFFS_OBJECT_TYPE_DIRECTORY:
+		if (!S_ISDIR(mode)) {
+			obj->yst_mode &= ~S_IFMT;
+			obj->yst_mode |= S_IFDIR;
+		}
+		break;
+	case YAFFS_OBJECT_TYPE_UNKNOWN:
+	case YAFFS_OBJECT_TYPE_HARDLINK:
+	case YAFFS_OBJECT_TYPE_SPECIAL:
+	default:
+		/* TODO? */
+		break;
+	}
 
-		yaffs_inode_to_obj_lv(inode) = obj;
-
-		obj->my_inode = inode;
-
-	} else {
-		yaffs_trace(YAFFS_TRACE_OS,
-			"yaffs_fill_inode invalid parameters");
+	inode->i_flags |= S_NOATIME;
+	inode->i_ino = obj->obj_id;
+	inode->i_mode = obj->yst_mode;
+	inode->i_uid = obj->yst_uid;
+	inode->i_gid = obj->yst_gid;
+
+	inode->i_rdev = old_decode_dev(obj->yst_rdev);
+
+	inode->i_atime.tv_sec = (time_t) (obj->yst_atime);
+	inode->i_atime.tv_nsec = 0;
+	inode->i_mtime.tv_sec = (time_t) obj->yst_mtime;
+	inode->i_mtime.tv_nsec = 0;
+	inode->i_ctime.tv_sec = (time_t) obj->yst_ctime;
+	inode->i_ctime.tv_nsec = 0;
+	inode->i_size = yaffs_get_obj_length(obj);
+	inode->i_blocks = (inode->i_size + 511) >> 9;
+	set_nlink(inode, yaffs_get_obj_link_count(obj));
+	yaffs_trace(YAFFS_TRACE_OS,
+		"yaffs_fill_inode mode %x uid %d gid %d size %d count %d",
+		inode->i_mode, inode->i_uid, inode->i_gid,
+		(int)inode->i_size, atomic_read(&inode->i_count));
+
+	switch (obj->yst_mode & S_IFMT) {
+	default:	/* fifo, device or socket */
+		init_special_inode(inode, obj->yst_mode,
+				   old_decode_dev(obj->yst_rdev));
+		break;
+	case S_IFREG:	/* file */
+		inode->i_op = &yaffs_file_inode_operations;
+		inode->i_fop = &yaffs_file_operations;
+		inode->i_mapping->a_ops = &yaffs_file_address_operations;
+		break;
+	case S_IFDIR:	/* directory */
+		inode->i_op = &yaffs_dir_inode_operations;
+		inode->i_fop = &yaffs_dir_operations;
+		break;
+	case S_IFLNK:	/* symlink */
+		inode->i_op = &yaffs_symlink_inode_operations;
+		break;
 	}
+
+	yaffs_inode_to_obj_lv(inode) = obj;
+	obj->my_inode = inode;
 }
 
 static void yaffs_put_super(struct super_block *sb)
@@ -1992,8 +1947,8 @@
 {
 	struct mtd_info *mtd = yaffs_dev_to_mtd(yaffs_super_to_dev(sb));
 
-	if (mtd->sync)
-		mtd->sync(mtd);
+	if (mtd->_sync)
+		mtd->_sync(mtd);
 
 	put_mtd_device(mtd);
 }
@@ -2020,16 +1975,18 @@
 	char *data_str = (char *)data;
 	struct yaffs_linux_context *context = NULL;
 	struct yaffs_param *param;
-
 	int read_only = 0;
-
 	struct yaffs_options options;
-
 	unsigned mount_id;
 	int found;
 	struct yaffs_linux_context *context_iterator;
 	struct list_head *l;
 
+	if (!sb) {
+		printk(KERN_INFO "yaffs: sb is NULL\n");
+		return NULL;
+	}
+
 	sb->s_magic = YAFFS_MAGIC;
 	sb->s_op = &yaffs_super_ops;
 	sb->s_flags |= MS_NOATIME;
@@ -2038,9 +1995,7 @@
 
 	sb->s_export_op = &yaffs_export_ops;
 
-	if (!sb)
-		printk(KERN_INFO "yaffs: sb is NULL\n");
-	else if (!sb->s_dev)
+	if (!sb->s_dev)
 		printk(KERN_INFO "yaffs: sb->s_dev is NULL\n");
 	else if (!yaffs_devname(sb, devname_buf))
 		printk(KERN_INFO "yaffs: devname is NULL\n");
@@ -2056,10 +2011,9 @@
 
 	memset(&options, 0, sizeof(options));
 
-	if (yaffs_parse_options(&options, data_str)) {
+	if (yaffs_parse_options(&options, data_str))
 		/* Option parsing failed */
 		return NULL;
-	}
 
 	sb->s_blocksize = PAGE_CACHE_SIZE;
 	sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
@@ -2101,39 +2055,35 @@
 	yaffs_trace(YAFFS_TRACE_OS, " writeoob %p", mtd->write_oob);
 	yaffs_trace(YAFFS_TRACE_OS, " block_isbad %p", mtd->block_isbad);
 	yaffs_trace(YAFFS_TRACE_OS, " block_markbad %p", mtd->block_markbad);
-	yaffs_trace(YAFFS_TRACE_OS, " %s %d", WRITE_SIZE_STR, WRITE_SIZE(mtd));
+	yaffs_trace(YAFFS_TRACE_OS, " writesize %d", mtd->writesize);
 	yaffs_trace(YAFFS_TRACE_OS, " oobsize %d", mtd->oobsize);
 	yaffs_trace(YAFFS_TRACE_OS, " erasesize %d", mtd->erasesize);
 	yaffs_trace(YAFFS_TRACE_OS, " size %lld", mtd->size);
 
-#ifdef CONFIG_YAFFS_AUTO_YAFFS2
-
-	if (yaffs_version == 1 && WRITE_SIZE(mtd) >= 2048) {
+	if (yaffs_auto_select && yaffs_version == 1 && mtd->writesize >= 2048) {
 		yaffs_trace(YAFFS_TRACE_ALWAYS, "auto selecting yaffs2");
 		yaffs_version = 2;
 	}
 
-	/* Added NCB 26/5/2006 for completeness */
-	if (yaffs_version == 2 && !options.inband_tags
-	    && WRITE_SIZE(mtd) == 512) {
+	if (yaffs_auto_select && yaffs_version == 2 && !options.inband_tags &&
+		mtd->writesize == 512) {
 		yaffs_trace(YAFFS_TRACE_ALWAYS, "auto selecting yaffs1");
 		yaffs_version = 1;
 	}
-#endif
 
 	if (yaffs_version == 2) {
 		/* Check for version 2 style functions */
-		if (!mtd->erase ||
-		    !mtd->block_isbad ||
-		    !mtd->block_markbad ||
-		    !mtd->read ||
-		    !mtd->write || !mtd->read_oob || !mtd->write_oob) {
+		if (!mtd->_erase ||
+		    !mtd->_block_isbad ||
+		    !mtd->_block_markbad ||
+		    !mtd->_read ||
+		    !mtd->_write || !mtd->_read_oob || !mtd->_write_oob) {
 			yaffs_trace(YAFFS_TRACE_ALWAYS,
 				"MTD device does not support required functions");
 			return NULL;
 		}
 
-		if ((WRITE_SIZE(mtd) < YAFFS_MIN_YAFFS2_CHUNK_SIZE ||
+		if ((mtd->writesize < YAFFS_MIN_YAFFS2_CHUNK_SIZE ||
 		     mtd->oobsize < YAFFS_MIN_YAFFS2_SPARE_SIZE) &&
 		    !options.inband_tags) {
 			yaffs_trace(YAFFS_TRACE_ALWAYS,
@@ -2142,15 +2092,15 @@
 		}
 	} else {
 		/* Check for V1 style functions */
-		if (!mtd->erase ||
-		    !mtd->read ||
-		    !mtd->write || !mtd->read_oob || !mtd->write_oob) {
+		if (!mtd->_erase ||
+		    !mtd->_read ||
+		    !mtd->_write || !mtd->_read_oob || !mtd->_write_oob) {
 			yaffs_trace(YAFFS_TRACE_ALWAYS,
 				"MTD device does not support required functions");
 			return NULL;
 		}
 
-		if (WRITE_SIZE(mtd) < YAFFS_BYTES_PER_CHUNK ||
+		if (mtd->writesize < YAFFS_BYTES_PER_CHUNK ||
 		    mtd->oobsize != YAFFS_BYTES_PER_SPARE) {
 			yaffs_trace(YAFFS_TRACE_ALWAYS,
 				"MTD device does not support have the right page sizes");
@@ -2174,10 +2124,8 @@
 	context = kmalloc(sizeof(struct yaffs_linux_context), GFP_KERNEL);
 
 	if (!dev || !context) {
-		if (dev)
-			kfree(dev);
-		if (context)
-			kfree(context);
+		kfree(dev);
+		kfree(context);
 		dev = NULL;
 		context = NULL;
 	}
@@ -2218,40 +2166,19 @@
 	param->n_caches = (options.no_cache) ? 0 : 10;
 	param->inband_tags = options.inband_tags;
 
-#ifdef CONFIG_YAFFS_DISABLE_LAZY_LOAD
 	param->disable_lazy_load = 1;
-#endif
-#ifdef CONFIG_YAFFS_XATTR
 	param->enable_xattr = 1;
-#endif
 	if (options.lazy_loading_overridden)
 		param->disable_lazy_load = !options.lazy_loading_enabled;
 
-#ifdef CONFIG_YAFFS_DISABLE_TAGS_ECC
-	param->no_tags_ecc = 1;
-#endif
-
-#ifdef CONFIG_YAFFS_DISABLE_BACKGROUND
-#else
 	param->defered_dir_update = 1;
-#endif
 
 	if (options.tags_ecc_overridden)
 		param->no_tags_ecc = !options.tags_ecc_on;
 
-#ifdef CONFIG_YAFFS_EMPTY_LOST_AND_FOUND
 	param->empty_lost_n_found = 1;
-#endif
 
-#ifdef CONFIG_YAFFS_DISABLE_BLOCK_REFRESHING
-	param->refresh_period = 0;
-#else
 	param->refresh_period = 500;
-#endif
-
-#ifdef CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED
-	param->always_check_erased = 1;
-#endif
 
 	if (options.empty_lost_and_found_overridden)
 		param->empty_lost_n_found = options.empty_lost_and_found;
@@ -2262,8 +2189,8 @@
 		param->read_chunk_tags_fn = nandmtd2_read_chunk_tags;
 		param->bad_block_fn = nandmtd2_mark_block_bad;
 		param->query_block_fn = nandmtd2_query_block;
-		yaffs_dev_to_lc(dev)->spare_buffer = 
-		                kmalloc(mtd->oobsize, GFP_NOFS);
+		yaffs_dev_to_lc(dev)->spare_buffer =
+				kmalloc(mtd->oobsize, GFP_NOFS);
 		param->is_yaffs2 = 1;
 		param->total_bytes_per_chunk = mtd->writesize;
 		param->chunks_per_block = mtd->erasesize / mtd->writesize;
@@ -2290,22 +2217,19 @@
 
 	yaffs_dev_to_lc(dev)->super = sb;
 
-#ifndef CONFIG_YAFFS_DOES_ECC
 	param->use_nand_ecc = 1;
-#endif
 
 	param->skip_checkpt_rd = options.skip_checkpoint_read;
 	param->skip_checkpt_wr = options.skip_checkpoint_write;
 
 	mutex_lock(&yaffs_context_lock);
 	/* Get a mount id */
-	found = 0;
-	for (mount_id = 0; !found; mount_id++) {
+	for (mount_id = 0, found = 0; !found; mount_id++) {
 		found = 1;
 		list_for_each(l, &yaffs_context_list) {
 			context_iterator =
-			    list_entry(l, struct yaffs_linux_context,
-				       context_list);
+				list_entry(l, struct yaffs_linux_context,
+					context_list);
 			if (context_iterator->mount_id == mount_id)
 				found = 0;
 		}
@@ -2336,6 +2260,8 @@
 	if (!context->bg_thread)
 		param->defered_dir_update = 0;
 
+	sb->s_maxbytes = yaffs_max_file_size(dev);
+
 	/* Release lock before yaffs_get_inode() */
 	yaffs_gross_unlock(dev);
 
@@ -2351,7 +2277,7 @@
 
 	yaffs_trace(YAFFS_TRACE_OS, "yaffs_read_super: got root inode");
 
-	root = d_alloc_root(inode);
+	root = d_make_root(inode);
 
 	yaffs_trace(YAFFS_TRACE_OS, "yaffs_read_super: d_alloc_root done");
 
@@ -2375,53 +2301,50 @@
 	return yaffs_internal_read_super(1, sb, data, silent) ? 0 : -EINVAL;
 }
 
-static int yaffs_read_super(struct file_system_type *fs,
+static struct dentry *yaffs_mount(struct file_system_type *fs,
 			    int flags, const char *dev_name,
-			    void *data, struct vfsmount *mnt)
+			    void *data)
 {
-
-	return get_sb_bdev(fs, flags, dev_name, data,
-			   yaffs_internal_read_super_mtd, mnt);
+	return mount_bdev(fs, flags, dev_name, data,
+			   yaffs_internal_read_super_mtd);
 }
 
 static struct file_system_type yaffs_fs_type = {
 	.owner = THIS_MODULE,
 	.name = "yaffs",
-	.get_sb = yaffs_read_super,
+	.mount = yaffs_mount,
 	.kill_sb = kill_block_super,
 	.fs_flags = FS_REQUIRES_DEV,
 };
 
-#ifdef CONFIG_YAFFS_YAFFS2
-
 static int yaffs2_internal_read_super_mtd(struct super_block *sb, void *data,
 					  int silent)
 {
 	return yaffs_internal_read_super(2, sb, data, silent) ? 0 : -EINVAL;
 }
 
-static int yaffs2_read_super(struct file_system_type *fs,
-			     int flags, const char *dev_name, void *data,
-			     struct vfsmount *mnt)
+static struct dentry *yaffs2_mount(struct file_system_type *fs,
+			     int flags, const char *dev_name, void *data)
 {
-	return get_sb_bdev(fs, flags, dev_name, data,
-			   yaffs2_internal_read_super_mtd, mnt);
+	return mount_bdev(fs, flags, dev_name, data,
+			   yaffs2_internal_read_super_mtd);
 }
 
 static struct file_system_type yaffs2_fs_type = {
 	.owner = THIS_MODULE,
 	.name = "yaffs2",
-	.get_sb = yaffs2_read_super,
+	.mount = yaffs2_mount,
 	.kill_sb = kill_block_super,
 	.fs_flags = FS_REQUIRES_DEV,
 };
-#endif /* CONFIG_YAFFS_YAFFS2 */
+
 
 static struct proc_dir_entry *my_proc_entry;
 
 static char *yaffs_dump_dev_part0(char *buf, struct yaffs_dev *dev)
 {
 	struct yaffs_param *param = &dev->param;
+
 	buf += sprintf(buf, "start_block........... %d\n", param->start_block);
 	buf += sprintf(buf, "end_block............. %d\n", param->end_block);
 	buf += sprintf(buf, "total_bytes_per_chunk. %d\n",
@@ -2448,9 +2371,10 @@
 
 static char *yaffs_dump_dev_part1(char *buf, struct yaffs_dev *dev)
 {
-	buf +=
-	    sprintf(buf, "data_bytes_per_chunk.. %d\n",
-		    dev->data_bytes_per_chunk);
+	buf += sprintf(buf, "max file size......... %lld\n",
+			(long long) yaffs_max_file_size(dev));
+	buf += sprintf(buf, "data_bytes_per_chunk.. %d\n",
+			dev->data_bytes_per_chunk);
 	buf += sprintf(buf, "chunk_grp_bits........ %d\n", dev->chunk_grp_bits);
 	buf += sprintf(buf, "chunk_grp_size........ %d\n", dev->chunk_grp_size);
 	buf +=
@@ -2475,7 +2399,7 @@
 	buf += sprintf(buf, "n_gc_blocks........... %u\n", dev->n_gc_blocks);
 	buf += sprintf(buf, "bg_gcs................ %u\n", dev->bg_gcs);
 	buf +=
-	    sprintf(buf, "n_retired_writes...... %u\n", dev->n_retired_writes);
+	    sprintf(buf, "n_retried_writes...... %u\n", dev->n_retried_writes);
 	buf +=
 	    sprintf(buf, "n_retired_blocks...... %u\n", dev->n_retired_blocks);
 	buf += sprintf(buf, "n_ecc_fixed........... %u\n", dev->n_ecc_fixed);
@@ -2523,7 +2447,8 @@
 
 		mutex_lock(&yaffs_context_lock);
 
-		/* Locate and print the Nth entry.  Order N-squared but N is small. */
+		/* Locate and print the Nth entry.
+		 * Order N-squared but N is small. */
 		list_for_each(item, &yaffs_context_list) {
 			struct yaffs_linux_context *dc =
 			    list_entry(item, struct yaffs_linux_context,
@@ -2541,7 +2466,7 @@
 				buf = yaffs_dump_dev_part0(buf, dev);
 			} else {
 				buf = yaffs_dump_dev_part1(buf, dev);
-                        }
+			}
 
 			break;
 		}
@@ -2552,149 +2477,6 @@
 }
 
 
-/**
- * Set the verbosity of the warnings and error messages.
- *
- * Note that the names can only be a..z or _ with the current code.
- */
-
-static struct {
-	char *mask_name;
-	unsigned mask_bitfield;
-} mask_flags[] = {
-	{"allocate", YAFFS_TRACE_ALLOCATE}, 
-	{"always", YAFFS_TRACE_ALWAYS},
-	{"background", YAFFS_TRACE_BACKGROUND},
-	{"bad_blocks", YAFFS_TRACE_BAD_BLOCKS},
-	{"buffers", YAFFS_TRACE_BUFFERS},
-	{"bug", YAFFS_TRACE_BUG},
-	{"checkpt", YAFFS_TRACE_CHECKPOINT},
-	{"deletion", YAFFS_TRACE_DELETION},
-	{"erase", YAFFS_TRACE_ERASE},
-	{"error", YAFFS_TRACE_ERROR},
-	{"gc_detail", YAFFS_TRACE_GC_DETAIL},
-	{"gc", YAFFS_TRACE_GC},
-	{"lock", YAFFS_TRACE_LOCK},
-	{"mtd", YAFFS_TRACE_MTD},
-	{"nandaccess", YAFFS_TRACE_NANDACCESS},
-	{"os", YAFFS_TRACE_OS},
-	{"scan_debug", YAFFS_TRACE_SCAN_DEBUG},
-	{"scan", YAFFS_TRACE_SCAN},
-	{"mount", YAFFS_TRACE_MOUNT},
-	{"tracing", YAFFS_TRACE_TRACING},
-	{"sync", YAFFS_TRACE_SYNC},
-	{"write", YAFFS_TRACE_WRITE},
-	{"verify", YAFFS_TRACE_VERIFY},
-	{"verify_nand", YAFFS_TRACE_VERIFY_NAND},
-	{"verify_full", YAFFS_TRACE_VERIFY_FULL},
-	{"verify_all", YAFFS_TRACE_VERIFY_ALL},
-	{"all", 0xffffffff},
-	{"none", 0},
-	{NULL, 0},
-};
-
-#define MAX_MASK_NAME_LENGTH 40
-static int yaffs_proc_write_trace_options(struct file *file, const char *buf,
-					  unsigned long count, void *data)
-{
-	unsigned rg = 0, mask_bitfield;
-	char *end;
-	char *mask_name;
-	const char *x;
-	char substring[MAX_MASK_NAME_LENGTH + 1];
-	int i;
-	int done = 0;
-	int add, len = 0;
-	int pos = 0;
-
-	rg = yaffs_trace_mask;
-
-	while (!done && (pos < count)) {
-		done = 1;
-		while ((pos < count) && isspace(buf[pos]))
-			pos++;
-
-		switch (buf[pos]) {
-		case '+':
-		case '-':
-		case '=':
-			add = buf[pos];
-			pos++;
-			break;
-
-		default:
-			add = ' ';
-			break;
-		}
-		mask_name = NULL;
-
-		mask_bitfield = simple_strtoul(buf + pos, &end, 0);
-
-		if (end > buf + pos) {
-			mask_name = "numeral";
-			len = end - (buf + pos);
-			pos += len;
-			done = 0;
-		} else {
-			for (x = buf + pos, i = 0;
-			     (*x == '_' || (*x >= 'a' && *x <= 'z')) &&
-			     i < MAX_MASK_NAME_LENGTH; x++, i++, pos++)
-				substring[i] = *x;
-			substring[i] = '\0';
-
-			for (i = 0; mask_flags[i].mask_name != NULL; i++) {
-				if (strcmp(substring, mask_flags[i].mask_name)
-				    == 0) {
-					mask_name = mask_flags[i].mask_name;
-					mask_bitfield =
-					    mask_flags[i].mask_bitfield;
-					done = 0;
-					break;
-				}
-			}
-		}
-
-		if (mask_name != NULL) {
-			done = 0;
-			switch (add) {
-			case '-':
-				rg &= ~mask_bitfield;
-				break;
-			case '+':
-				rg |= mask_bitfield;
-				break;
-			case '=':
-				rg = mask_bitfield;
-				break;
-			default:
-				rg |= mask_bitfield;
-				break;
-			}
-		}
-	}
-
-	yaffs_trace_mask = rg | YAFFS_TRACE_ALWAYS;
-
-	printk(KERN_DEBUG "new trace = 0x%08X\n", yaffs_trace_mask);
-
-	if (rg & YAFFS_TRACE_ALWAYS) {
-		for (i = 0; mask_flags[i].mask_name != NULL; i++) {
-			char flag;
-			flag = ((rg & mask_flags[i].mask_bitfield) ==
-				mask_flags[i].mask_bitfield) ? '+' : '-';
-			printk(KERN_DEBUG "%c%s\n", flag,
-			       mask_flags[i].mask_name);
-		}
-	}
-
-	return count;
-}
-
-static int yaffs_proc_write(struct file *file, const char *buf,
-			    unsigned long count, void *data)
-{
-	return yaffs_proc_write_trace_options(file, buf, count, data);
-}
 
 /* Stuff to handle installation of file systems */
 struct file_system_to_install {
@@ -2716,24 +2498,19 @@
 	yaffs_trace(YAFFS_TRACE_ALWAYS,
 		"yaffs built " __DATE__ " " __TIME__ " Installing.");
 
-#ifdef CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED
-	yaffs_trace(YAFFS_TRACE_ALWAYS,
-		"\n\nYAFFS-WARNING CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED selected.\n\n\n");
-#endif
-
 	mutex_init(&yaffs_context_lock);
 
 	/* Install the proc_fs entries */
 	my_proc_entry = create_proc_entry("yaffs",
-					  S_IRUGO | S_IFREG, YPROC_ROOT);
+					  S_IRUGO | S_IFREG, NULL);
 
 	if (my_proc_entry) {
-		my_proc_entry->write_proc = yaffs_proc_write;
+		my_proc_entry->write_proc = NULL;
 		my_proc_entry->read_proc = yaffs_proc_read;
 		my_proc_entry->data = NULL;
 	} else {
 		return -ENOMEM;
-        }
+	}
 
 
 	/* Now add the file system entries */
@@ -2771,7 +2548,7 @@
 	yaffs_trace(YAFFS_TRACE_ALWAYS,
 		"yaffs built " __DATE__ " " __TIME__ " removing.");
 
-	remove_proc_entry("yaffs", YPROC_ROOT);
+	remove_proc_entry("yaffs", NULL);
 
 	fsinst = fs_to_install;
 
@@ -2785,8 +2562,8 @@
 }
 
 module_init(init_yaffs_fs)
-    module_exit(exit_yaffs_fs)
+module_exit(exit_yaffs_fs)
 
-    MODULE_DESCRIPTION("YAFFS2 - a NAND specific flash file system");
-MODULE_AUTHOR("Charles Manning, Aleph One Ltd., 2002-2010");
+MODULE_DESCRIPTION("YAFFS2 - a NAND specific flash file system");
+MODULE_AUTHOR("Charles Manning, Aleph One Ltd., 2002-2011");
 MODULE_LICENSE("GPL");
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_yaffs1.c linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_yaffs1.c
--- linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_yaffs1.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_yaffs1.c	2014-07-29 17:28:38.819972000 +0800
@@ -1,7 +1,7 @@
 /*
  * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
  *
- * Copyright (C) 2002-2010 Aleph One Ltd.
+ * Copyright (C) 2002-2011 Aleph One Ltd.
  *   for Toby Churchill Ltd and Brightstar Engineering
  *
  * Created by Charles Manning <charles@aleph1.co.uk>
@@ -24,29 +24,25 @@
 	struct yaffs_ext_tags tags;
 	int blk;
 	int result;
-
 	int chunk;
 	int c;
 	int deleted;
 	enum yaffs_block_state state;
-	struct yaffs_obj *hard_list = NULL;
+	LIST_HEAD(hard_list);
 	struct yaffs_block_info *bi;
 	u32 seq_number;
 	struct yaffs_obj_hdr *oh;
 	struct yaffs_obj *in;
 	struct yaffs_obj *parent;
-
 	int alloc_failed = 0;
-
 	struct yaffs_shadow_fixer *shadow_fixers = NULL;
-
 	u8 *chunk_data;
 
 	yaffs_trace(YAFFS_TRACE_SCAN,
 		"yaffs1_scan starts  intstartblk %d intendblk %d...",
 		dev->internal_start_block, dev->internal_end_block);
 
-	chunk_data = yaffs_get_temp_buffer(dev, __LINE__);
+	chunk_data = yaffs_get_temp_buffer(dev);
 
 	dev->seq_number = YAFFS_LOWEST_SEQUENCE_NUMBER;
 
@@ -93,8 +89,9 @@
 		deleted = 0;
 
 		/* For each chunk in each block that needs scanning.... */
-		for (c = 0; !alloc_failed && c < dev->param.chunks_per_block &&
-		     state == YAFFS_BLOCK_STATE_NEEDS_SCANNING; c++) {
+		for (c = 0;
+			!alloc_failed && c < dev->param.chunks_per_block &&
+			state == YAFFS_BLOCK_STATE_NEEDS_SCAN; c++) {
 			/* Read the tags and decide what to do */
 			chunk = blk * dev->param.chunks_per_block + c;
 
@@ -103,14 +100,13 @@
 
 			/* Let's have a good look at this chunk... */
 
-			if (tags.ecc_result == YAFFS_ECC_RESULT_UNFIXED
-			    || tags.is_deleted) {
+			if (tags.ecc_result == YAFFS_ECC_RESULT_UNFIXED ||
+			    tags.is_deleted) {
 				/* YAFFS1 only...
 				 * A deleted chunk
 				 */
 				deleted++;
 				dev->n_free_chunks++;
-				/*T((" %d %d deleted\n",blk,c)); */
 			} else if (!tags.chunk_used) {
 				/* An unassigned chunk in the block
 				 * This means that either the block is empty or
@@ -118,11 +114,12 @@
 				 */
 
 				if (c == 0) {
-					/* We're looking at the first chunk in the block so the block is unused */
+					/* We're looking at the first chunk in
+					 *the block so the block is unused */
 					state = YAFFS_BLOCK_STATE_EMPTY;
 					dev->n_erased_blocks++;
 				} else {
-					/* this is the block being allocated from */
+					/* this is the block being allocated */
 					yaffs_trace(YAFFS_TRACE_SCAN,
 						" Allocating from %d %d",
 						blk, c);
@@ -130,7 +127,6 @@
 					dev->alloc_block = blk;
 					dev->alloc_page = c;
 					dev->alloc_block_finder = blk;
-					/* Set block finder here to encourage the allocator to go forth from here. */
 
 				}
 
@@ -144,10 +140,10 @@
 				bi->pages_in_use++;
 
 				in = yaffs_find_or_create_by_number(dev,
-								    tags.obj_id,
-								    YAFFS_OBJECT_TYPE_FILE);
-				/* PutChunkIntoFile checks for a clash (two data chunks with
-				 * the same chunk_id).
+							tags.obj_id,
+							YAFFS_OBJECT_TYPE_FILE);
+				/* PutChunkIntoFile checks for a clash
+				 * (two data chunks with the same chunk_id).
 				 */
 
 				if (!in)
@@ -160,14 +156,14 @@
 				}
 
 				endpos =
-				    (tags.chunk_id -
-				     1) * dev->data_bytes_per_chunk +
+				    (tags.chunk_id - 1) *
+				    dev->data_bytes_per_chunk +
 				    tags.n_bytes;
-				if (in
-				    && in->variant_type ==
-				    YAFFS_OBJECT_TYPE_FILE
-				    && in->variant.file_variant.scanned_size <
-				    endpos) {
+				if (in &&
+				    in->variant_type ==
+				     YAFFS_OBJECT_TYPE_FILE &&
+				    in->variant.file_variant.scanned_size <
+				      endpos) {
 					in->variant.file_variant.scanned_size =
 					    endpos;
 					if (!dev->param.use_header_file_size) {
@@ -178,10 +174,9 @@
 					}
 
 				}
-				/* T((" %d %d data %d %d\n",blk,c,tags.obj_id,tags.chunk_id));   */
 			} else {
 				/* chunk_id == 0, so it is an ObjectHeader.
-				 * Thus, we read in the object header and make the object
+				 * Make the object
 				 */
 				yaffs_set_chunk_bit(dev, blk, c);
 				bi->pages_in_use++;
@@ -195,18 +190,19 @@
 				in = yaffs_find_by_number(dev, tags.obj_id);
 				if (in && in->variant_type != oh->type) {
 					/* This should not happen, but somehow
-					 * Wev'e ended up with an obj_id that has been reused but not yet
-					 * deleted, and worse still it has changed type. Delete the old object.
+					 * Wev'e ended up with an obj_id that
+					 * has been reused but not yet deleted,
+					 * and worse still it has changed type.
+					 * Delete the old object.
 					 */
 
 					yaffs_del_obj(in);
-
-					in = 0;
+					in = NULL;
 				}
 
 				in = yaffs_find_or_create_by_number(dev,
-								    tags.obj_id,
-								    oh->type);
+								tags.obj_id,
+								oh->type);
 
 				if (!in)
 					alloc_failed = 1;
@@ -234,7 +230,9 @@
 				}
 
 				if (in && in->valid) {
-					/* We have already filled this one. We have a duplicate and need to resolve it. */
+					/* We have already filled this one.
+					 * We have a duplicate and need to
+					 * resolve it. */
 
 					unsigned existing_serial = in->serial;
 					unsigned new_serial =
@@ -242,13 +240,15 @@
 
 					if (((existing_serial + 1) & 3) ==
 					    new_serial) {
-						/* Use new one - destroy the exisiting one */
+						/* Use new one - destroy the
+						 * exisiting one */
 						yaffs_chunk_del(dev,
 								in->hdr_chunk,
 								1, __LINE__);
 						in->valid = 0;
 					} else {
-						/* Use existing - destroy this one. */
+						/* Use existing - destroy
+						 * this one. */
 						yaffs_chunk_del(dev, chunk, 1,
 								__LINE__);
 					}
@@ -258,7 +258,8 @@
 				    (tags.obj_id == YAFFS_OBJECTID_ROOT ||
 				     tags.obj_id ==
 				     YAFFS_OBJECTID_LOSTNFOUND)) {
-					/* We only load some info, don't fiddle with directory structure */
+					/* We only load some info, don't fiddle
+					 * with directory structure */
 					in->valid = 1;
 					in->variant_type = oh->type;
 
@@ -297,12 +298,14 @@
 						parent->variant_type =
 						    YAFFS_OBJECT_TYPE_DIRECTORY;
 						INIT_LIST_HEAD(&parent->
-							       variant.dir_variant.children);
-					} else if (!parent
-						   || parent->variant_type !=
-						   YAFFS_OBJECT_TYPE_DIRECTORY) {
-						/* Hoosterman, another problem....
-						 * We're trying to use a non-directory as a directory
+							variant.dir_variant.
+							children);
+					} else if (!parent ||
+						parent->variant_type !=
+						YAFFS_OBJECT_TYPE_DIRECTORY) {
+						/* Hoosterman, a problem....
+						 * We're trying to use a
+						 * non-directory as a directory
 						 */
 
 						yaffs_trace(YAFFS_TRACE_ERROR,
@@ -313,19 +316,6 @@
 
 					yaffs_add_obj_to_dir(parent, in);
 
-					if (0 && (parent == dev->del_dir ||
-						  parent ==
-						  dev->unlinked_dir)) {
-						in->deleted = 1;	/* If it is unlinked at start up then it wants deleting */
-						dev->n_deleted_files++;
-					}
-					/* Note re hardlinks.
-					 * Since we might scan a hardlink before its equivalent object is scanned
-					 * we put them all in a list.
-					 * After scanning is complete, we should have all the objects, so we run through this
-					 * list and fix up all the chains.
-					 */
-
 					switch (in->variant_type) {
 					case YAFFS_OBJECT_TYPE_UNKNOWN:
 						/* Todo got a problem */
@@ -333,20 +323,16 @@
 					case YAFFS_OBJECT_TYPE_FILE:
 						if (dev->param.
 						    use_header_file_size)
-
 							in->variant.
-							    file_variant.file_size
-							    = oh->file_size;
-
+							file_variant.file_size
+							= yaffs_oh_to_size(oh);
 						break;
 					case YAFFS_OBJECT_TYPE_HARDLINK:
 						in->variant.
 						    hardlink_variant.equiv_id =
 						    oh->equiv_id;
-						in->hard_links.next =
-						    (struct list_head *)
-						    hard_list;
-						hard_list = in;
+						list_add(&in->hard_links,
+								&hard_list);
 						break;
 					case YAFFS_OBJECT_TYPE_DIRECTORY:
 						/* Do nothing */
@@ -363,18 +349,19 @@
 							alloc_failed = 1;
 						break;
 					}
-
 				}
 			}
 		}
 
-		if (state == YAFFS_BLOCK_STATE_NEEDS_SCANNING) {
-			/* If we got this far while scanning, then the block is fully allocated. */
+		if (state == YAFFS_BLOCK_STATE_NEEDS_SCAN) {
+			/* If we got this far while scanning,
+			 * then the block is fully allocated. */
 			state = YAFFS_BLOCK_STATE_FULL;
 		}
 
 		if (state == YAFFS_BLOCK_STATE_ALLOCATING) {
-			/* If the block was partially allocated then treat it as fully allocated. */
+			/* If the block was partially allocated then
+			 * treat it as fully allocated. */
 			state = YAFFS_BLOCK_STATE_FULL;
 			dev->alloc_block = -1;
 		}
@@ -384,21 +371,22 @@
 		/* Now let's see if it was dirty */
 		if (bi->pages_in_use == 0 &&
 		    !bi->has_shrink_hdr &&
-		    bi->block_state == YAFFS_BLOCK_STATE_FULL) {
+		    bi->block_state == YAFFS_BLOCK_STATE_FULL)
 			yaffs_block_became_dirty(dev, blk);
-		}
-
 	}
 
 	/* Ok, we've done all the scanning.
 	 * Fix up the hard link chains.
-	 * We should now have scanned all the objects, now it's time to add these
-	 * hardlinks.
+	 * We should now have scanned all the objects, now it's time to add
+	 * these hardlinks.
 	 */
 
-	yaffs_link_fixup(dev, hard_list);
+	yaffs_link_fixup(dev, &hard_list);
 
-	/* Fix up any shadowed objects */
+	/*
+	 * Fix up any shadowed objects.
+	 * There should not be more than one of these.
+	 */
 	{
 		struct yaffs_shadow_fixer *fixer;
 		struct yaffs_obj *obj;
@@ -406,8 +394,9 @@
 		while (shadow_fixers) {
 			fixer = shadow_fixers;
 			shadow_fixers = fixer->next;
-			/* Complete the rename transaction by deleting the shadowed object
-			 * then setting the object header to unshadowed.
+			/* Complete the rename transaction by deleting the
+			 * shadowed object then setting the object header
+			 to unshadowed.
 			 */
 			obj = yaffs_find_by_number(dev, fixer->shadowed_id);
 			if (obj)
@@ -422,7 +411,7 @@
 		}
 	}
 
-	yaffs_release_temp_buffer(dev, chunk_data, __LINE__);
+	yaffs_release_temp_buffer(dev, chunk_data);
 
 	if (alloc_failed)
 		return YAFFS_FAIL;
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_yaffs1.h linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_yaffs1.h
--- linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_yaffs1.h	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_yaffs1.h	2014-07-29 17:28:38.819972000 +0800
@@ -1,7 +1,7 @@
 /*
  * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
  *
- * Copyright (C) 2002-2010 Aleph One Ltd.
+ * Copyright (C) 2002-2011 Aleph One Ltd.
  *   for Toby Churchill Ltd and Brightstar Engineering
  *
  * Created by Charles Manning <charles@aleph1.co.uk>
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_yaffs2.c linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_yaffs2.c
--- linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_yaffs2.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_yaffs2.c	2014-07-29 17:28:38.819972000 +0800
@@ -1,7 +1,7 @@
 /*
  * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
  *
- * Copyright (C) 2002-2010 Aleph One Ltd.
+ * Copyright (C) 2002-2011 Aleph One Ltd.
  *   for Toby Churchill Ltd and Brightstar Engineering
  *
  * Created by Charles Manning <charles@aleph1.co.uk>
@@ -20,6 +20,7 @@
 #include "yaffs_getblockinfo.h"
 #include "yaffs_verify.h"
 #include "yaffs_attribs.h"
+#include "yaffs_summary.h"
 
 /*
  * Checkpoints are really no benefit on very small partitions.
@@ -28,7 +29,6 @@
  * the partition is at least this big.
  */
 #define YAFFS_CHECKPOINT_MIN_BLOCKS 60
-
 #define YAFFS_SMALL_HOLE_THRESHOLD 4
 
 /*
@@ -55,7 +55,8 @@
 	for (i = dev->internal_start_block; i <= dev->internal_end_block; i++) {
 		if (b->block_state == YAFFS_BLOCK_STATE_FULL &&
 		    (b->pages_in_use - b->soft_del_pages) <
-		    dev->param.chunks_per_block && b->seq_number < seq) {
+		    dev->param.chunks_per_block &&
+		    b->seq_number < seq) {
 			seq = b->seq_number;
 			block_no = i;
 		}
@@ -66,7 +67,6 @@
 		dev->oldest_dirty_seq = seq;
 		dev->oldest_dirty_block = block_no;
 	}
-
 }
 
 void yaffs2_find_oldest_dirty_seq(struct yaffs_dev *dev)
@@ -81,7 +81,7 @@
 /*
  * yaffs_clear_oldest_dirty_seq()
  * Called when a block is erased or marked bad. (ie. when its seq_number
- * becomes invalid). If the value matches the oldest then we clear 
+ * becomes invalid). If the value matches the oldest then we clear
  * dev->oldest_dirty_seq to force its recomputation.
  */
 void yaffs2_clear_oldest_dirty_seq(struct yaffs_dev *dev,
@@ -127,8 +127,8 @@
 
 	yaffs2_find_oldest_dirty_seq(dev);
 
-	/* Can't do gc of this block if there are any blocks older than this one that have
-	 * discarded pages.
+	/* Can't do gc of this block if there are any blocks older than this
+	 * one that have discarded pages.
 	 */
 	return (bi->seq_number <= dev->oldest_dirty_seq);
 }
@@ -138,13 +138,11 @@
  * periodically finds the oldest full block by sequence number for refreshing.
  * Only for yaffs2.
  */
-u32 yaffs2_find_refresh_block(struct yaffs_dev * dev)
+u32 yaffs2_find_refresh_block(struct yaffs_dev *dev)
 {
 	u32 b;
-
 	u32 oldest = 0;
 	u32 oldest_seq = 0;
-
 	struct yaffs_block_info *bi;
 
 	if (!dev->param.is_yaffs2)
@@ -210,29 +208,29 @@
 int yaffs_calc_checkpt_blocks_required(struct yaffs_dev *dev)
 {
 	int retval;
+	int n_bytes = 0;
+	int n_blocks;
+	int dev_blocks;
 
 	if (!dev->param.is_yaffs2)
 		return 0;
 
 	if (!dev->checkpoint_blocks_required && yaffs2_checkpt_required(dev)) {
 		/* Not a valid value so recalculate */
-		int n_bytes = 0;
-		int n_blocks;
-		int dev_blocks =
-		    (dev->param.end_block - dev->param.start_block + 1);
-
+		dev_blocks = dev->param.end_block - dev->param.start_block + 1;
 		n_bytes += sizeof(struct yaffs_checkpt_validity);
 		n_bytes += sizeof(struct yaffs_checkpt_dev);
 		n_bytes += dev_blocks * sizeof(struct yaffs_block_info);
 		n_bytes += dev_blocks * dev->chunk_bit_stride;
 		n_bytes +=
-		    (sizeof(struct yaffs_checkpt_obj) +
-		     sizeof(u32)) * (dev->n_obj);
-		n_bytes += (dev->tnode_size + sizeof(u32)) * (dev->n_tnodes);
+		    (sizeof(struct yaffs_checkpt_obj) + sizeof(u32)) *
+		    dev->n_obj;
+		n_bytes += (dev->tnode_size + sizeof(u32)) * dev->n_tnodes;
 		n_bytes += sizeof(struct yaffs_checkpt_validity);
 		n_bytes += sizeof(u32);	/* checksum */
 
-		/* Round up and add 2 blocks to allow for some bad blocks, so add 3 */
+		/* Round up and add 2 blocks to allow for some bad blocks,
+		 * so add 3 */
 
 		n_blocks =
 		    (n_bytes /
@@ -312,9 +310,7 @@
 {
 	struct yaffs_checkpt_dev cp;
 	u32 n_bytes;
-	u32 n_blocks =
-	    (dev->internal_end_block - dev->internal_start_block + 1);
-
+	u32 n_blocks = dev->internal_end_block - dev->internal_start_block + 1;
 	int ok;
 
 	/* Write device runtime values */
@@ -322,22 +318,20 @@
 	cp.struct_type = sizeof(cp);
 
 	ok = (yaffs2_checkpt_wr(dev, &cp, sizeof(cp)) == sizeof(cp));
+	if (!ok)
+		return 0;
 
 	/* Write block info */
-	if (ok) {
-		n_bytes = n_blocks * sizeof(struct yaffs_block_info);
-		ok = (yaffs2_checkpt_wr(dev, dev->block_info, n_bytes) ==
-		      n_bytes);
-	}
+	n_bytes = n_blocks * sizeof(struct yaffs_block_info);
+	ok = (yaffs2_checkpt_wr(dev, dev->block_info, n_bytes) == n_bytes);
+	if (!ok)
+		return 0;
 
 	/* Write chunk bits */
-	if (ok) {
-		n_bytes = n_blocks * dev->chunk_bit_stride;
-		ok = (yaffs2_checkpt_wr(dev, dev->chunk_bits, n_bytes) ==
-		      n_bytes);
-	}
-	return ok ? 1 : 0;
+	n_bytes = n_blocks * dev->chunk_bit_stride;
+	ok = (yaffs2_checkpt_wr(dev, dev->chunk_bits, n_bytes) == n_bytes);
 
+	return ok ? 1 : 0;
 }
 
 static int yaffs2_rd_checkpt_dev(struct yaffs_dev *dev)
@@ -346,7 +340,6 @@
 	u32 n_bytes;
 	u32 n_blocks =
 	    (dev->internal_end_block - dev->internal_start_block + 1);
-
 	int ok;
 
 	ok = (yaffs2_checkpt_rd(dev, &cp, sizeof(cp)) == sizeof(cp));
@@ -364,6 +357,7 @@
 
 	if (!ok)
 		return 0;
+
 	n_bytes = n_blocks * dev->chunk_bit_stride;
 
 	ok = (yaffs2_checkpt_rd(dev, dev->chunk_bits, n_bytes) == n_bytes);
@@ -374,7 +368,6 @@
 static void yaffs2_obj_checkpt_obj(struct yaffs_checkpt_obj *cp,
 				   struct yaffs_obj *obj)
 {
-
 	cp->obj_id = obj->obj_id;
 	cp->parent_id = (obj->parent) ? obj->parent->obj_id : 0;
 	cp->hdr_chunk = obj->hdr_chunk;
@@ -394,10 +387,9 @@
 		cp->size_or_equiv_obj = obj->variant.hardlink_variant.equiv_id;
 }
 
-static int taffs2_checkpt_obj_to_obj(struct yaffs_obj *obj,
+static int yaffs2_checkpt_obj_to_obj(struct yaffs_obj *obj,
 				     struct yaffs_checkpt_obj *cp)
 {
-
 	struct yaffs_obj *parent;
 
 	if (obj->variant_type != cp->variant_type) {
@@ -412,8 +404,8 @@
 
 	if (cp->parent_id)
 		parent = yaffs_find_or_create_by_number(obj->my_dev,
-							cp->parent_id,
-							YAFFS_OBJECT_TYPE_DIRECTORY);
+						cp->parent_id,
+						YAFFS_OBJECT_TYPE_DIRECTORY);
 	else
 		parent = NULL;
 
@@ -457,39 +449,33 @@
 	int i;
 	struct yaffs_dev *dev = in->my_dev;
 	int ok = 1;
+	u32 base_offset;
 
-	if (tn) {
-		if (level > 0) {
+	if (!tn)
+		return 1;
 
-			for (i = 0; i < YAFFS_NTNODES_INTERNAL && ok; i++) {
-				if (tn->internal[i]) {
-					ok = yaffs2_checkpt_tnode_worker(in,
-									 tn->
-									 internal
-									 [i],
-									 level -
-									 1,
-									 (chunk_offset
-									  <<
-									  YAFFS_TNODES_INTERNAL_BITS)
-									 + i);
-				}
-			}
-		} else if (level == 0) {
-			u32 base_offset =
-			    chunk_offset << YAFFS_TNODES_LEVEL0_BITS;
-			ok = (yaffs2_checkpt_wr
-			      (dev, &base_offset,
-			       sizeof(base_offset)) == sizeof(base_offset));
-			if (ok)
-				ok = (yaffs2_checkpt_wr
-				      (dev, tn,
-				       dev->tnode_size) == dev->tnode_size);
+	if (level > 0) {
+		for (i = 0; i < YAFFS_NTNODES_INTERNAL && ok; i++) {
+			if (!tn->internal[i])
+				continue;
+			ok = yaffs2_checkpt_tnode_worker(in,
+				 tn->internal[i],
+				 level - 1,
+				 (chunk_offset <<
+				  YAFFS_TNODES_INTERNAL_BITS) + i);
 		}
+		return ok;
 	}
 
-	return ok;
+	/* Level 0 tnode */
+	base_offset = chunk_offset << YAFFS_TNODES_LEVEL0_BITS;
+	ok = (yaffs2_checkpt_wr(dev, &base_offset, sizeof(base_offset)) ==
+			sizeof(base_offset));
+	if (ok)
+		ok = (yaffs2_checkpt_wr(dev, tn, dev->tnode_size) ==
+			dev->tnode_size);
 
+	return ok;
 }
 
 static int yaffs2_wr_checkpt_tnodes(struct yaffs_obj *obj)
@@ -497,16 +483,16 @@
 	u32 end_marker = ~0;
 	int ok = 1;
 
-	if (obj->variant_type == YAFFS_OBJECT_TYPE_FILE) {
-		ok = yaffs2_checkpt_tnode_worker(obj,
-						 obj->variant.file_variant.top,
-						 obj->variant.file_variant.
-						 top_level, 0);
-		if (ok)
-			ok = (yaffs2_checkpt_wr
-			      (obj->my_dev, &end_marker,
-			       sizeof(end_marker)) == sizeof(end_marker));
-	}
+	if (obj->variant_type != YAFFS_OBJECT_TYPE_FILE)
+		return ok;
+
+	ok = yaffs2_checkpt_tnode_worker(obj,
+					 obj->variant.file_variant.top,
+					 obj->variant.file_variant.
+					 top_level, 0);
+	if (ok)
+		ok = (yaffs2_checkpt_wr(obj->my_dev, &end_marker,
+				sizeof(end_marker)) == sizeof(end_marker));
 
 	return ok ? 1 : 0;
 }
@@ -528,12 +514,11 @@
 		/* Read level 0 tnode */
 
 		tn = yaffs_get_tnode(dev);
-		if (tn) {
+		if (tn)
 			ok = (yaffs2_checkpt_rd(dev, tn, dev->tnode_size) ==
-			      dev->tnode_size);
-		} else {
+				dev->tnode_size);
+		else
 			ok = 0;
-                }
 
 		if (tn && ok)
 			ok = yaffs_add_find_tnode_0(dev,
@@ -544,7 +529,6 @@
 			ok = (yaffs2_checkpt_rd
 			      (dev, &base_chunk,
 			       sizeof(base_chunk)) == sizeof(base_chunk));
-
 	}
 
 	yaffs_trace(YAFFS_TRACE_CHECKPOINT,
@@ -568,34 +552,29 @@
 
 	for (i = 0; ok && i < YAFFS_NOBJECT_BUCKETS; i++) {
 		list_for_each(lh, &dev->obj_bucket[i].list) {
-			if (lh) {
-				obj =
-				    list_entry(lh, struct yaffs_obj, hash_link);
-				if (!obj->defered_free) {
-					yaffs2_obj_checkpt_obj(&cp, obj);
-					cp.struct_type = sizeof(cp);
-
-					yaffs_trace(YAFFS_TRACE_CHECKPOINT,
-						"Checkpoint write object %d parent %d type %d chunk %d obj addr %p",
-						cp.obj_id, cp.parent_id,
-						cp.variant_type, cp.hdr_chunk, obj);
-
-					ok = (yaffs2_checkpt_wr
-					      (dev, &cp,
-					       sizeof(cp)) == sizeof(cp));
-
-					if (ok
-					    && obj->variant_type ==
-					    YAFFS_OBJECT_TYPE_FILE)
-						ok = yaffs2_wr_checkpt_tnodes
-						    (obj);
-				}
+			obj = list_entry(lh, struct yaffs_obj, hash_link);
+			if (!obj->defered_free) {
+				yaffs2_obj_checkpt_obj(&cp, obj);
+				cp.struct_type = sizeof(cp);
+
+				yaffs_trace(YAFFS_TRACE_CHECKPOINT,
+					"Checkpoint write object %d parent %d type %d chunk %d obj addr %p",
+					cp.obj_id, cp.parent_id,
+					cp.variant_type, cp.hdr_chunk, obj);
+
+				ok = (yaffs2_checkpt_wr(dev, &cp,
+						sizeof(cp)) == sizeof(cp));
+
+				if (ok &&
+					obj->variant_type ==
+					YAFFS_OBJECT_TYPE_FILE)
+					ok = yaffs2_wr_checkpt_tnodes(obj);
 			}
 		}
 	}
 
 	/* Dump end of list */
-	memset(&cp, 0xFF, sizeof(struct yaffs_checkpt_obj));
+	memset(&cp, 0xff, sizeof(struct yaffs_checkpt_obj));
 	cp.struct_type = sizeof(cp);
 
 	if (ok)
@@ -610,7 +589,8 @@
 	struct yaffs_checkpt_obj cp;
 	int ok = 1;
 	int done = 0;
-	struct yaffs_obj *hard_list = NULL;
+	LIST_HEAD(hard_list);
+
 
 	while (ok && !done) {
 		ok = (yaffs2_checkpt_rd(dev, &cp, sizeof(cp)) == sizeof(cp));
@@ -633,25 +613,24 @@
 			    yaffs_find_or_create_by_number(dev, cp.obj_id,
 							   cp.variant_type);
 			if (obj) {
-				ok = taffs2_checkpt_obj_to_obj(obj, &cp);
+				ok = yaffs2_checkpt_obj_to_obj(obj, &cp);
 				if (!ok)
 					break;
-				if (obj->variant_type == YAFFS_OBJECT_TYPE_FILE) {
+				if (obj->variant_type ==
+					YAFFS_OBJECT_TYPE_FILE) {
 					ok = yaffs2_rd_checkpt_tnodes(obj);
 				} else if (obj->variant_type ==
-					   YAFFS_OBJECT_TYPE_HARDLINK) {
-					obj->hard_links.next =
-					    (struct list_head *)hard_list;
-					hard_list = obj;
+					YAFFS_OBJECT_TYPE_HARDLINK) {
+					list_add(&obj->hard_links, &hard_list);
 				}
 			} else {
 				ok = 0;
-                        }
+			}
 		}
 	}
 
 	if (ok)
-		yaffs_link_fixup(dev, hard_list);
+		yaffs_link_fixup(dev, &hard_list);
 
 	return ok ? 1 : 0;
 }
@@ -664,7 +643,7 @@
 	yaffs2_get_checkpt_sum(dev, &checkpt_sum);
 
 	ok = (yaffs2_checkpt_wr(dev, &checkpt_sum, sizeof(checkpt_sum)) ==
-	      sizeof(checkpt_sum));
+		sizeof(checkpt_sum));
 
 	if (!ok)
 		return 0;
@@ -681,7 +660,7 @@
 	yaffs2_get_checkpt_sum(dev, &checkpt_sum0);
 
 	ok = (yaffs2_checkpt_rd(dev, &checkpt_sum1, sizeof(checkpt_sum1)) ==
-	      sizeof(checkpt_sum1));
+		sizeof(checkpt_sum1));
 
 	if (!ok)
 		return 0;
@@ -792,7 +771,6 @@
 		dev->is_checkpointed = 0;
 
 	return ok ? 1 : 0;
-
 }
 
 void yaffs2_checkpt_invalidate(struct yaffs_dev *dev)
@@ -807,7 +785,6 @@
 
 int yaffs_checkpoint_save(struct yaffs_dev *dev)
 {
-
 	yaffs_trace(YAFFS_TRACE_CHECKPOINT,
 		"save entry: is_checkpointed %d",
 		dev->is_checkpointed);
@@ -831,6 +808,7 @@
 int yaffs2_checkpt_restore(struct yaffs_dev *dev)
 {
 	int retval;
+
 	yaffs_trace(YAFFS_TRACE_CHECKPOINT,
 		"restore entry: is_checkpointed %d",
 		dev->is_checkpointed);
@@ -854,17 +832,15 @@
 {
 	/* if new_size > old_file_size.
 	 * We're going to be writing a hole.
-	 * If the hole is small then write zeros otherwise write a start of hole marker.
+	 * If the hole is small then write zeros otherwise write a start
+	 * of hole marker.
 	 */
-
 	loff_t old_file_size;
-	int increase;
+	loff_t increase;
 	int small_hole;
 	int result = YAFFS_OK;
 	struct yaffs_dev *dev = NULL;
-
 	u8 *local_buffer = NULL;
-
 	int small_increase_ok = 0;
 
 	if (!obj)
@@ -893,11 +869,11 @@
 		small_hole = 0;
 
 	if (small_hole)
-		local_buffer = yaffs_get_temp_buffer(dev, __LINE__);
+		local_buffer = yaffs_get_temp_buffer(dev);
 
 	if (local_buffer) {
 		/* fill hole with zero bytes */
-		int pos = old_file_size;
+		loff_t pos = old_file_size;
 		int this_write;
 		int written;
 		memset(local_buffer, 0, dev->data_bytes_per_chunk);
@@ -915,12 +891,12 @@
 				increase -= this_write;
 			} else {
 				small_increase_ok = 0;
-                        }
+			}
 		}
 
-		yaffs_release_temp_buffer(dev, local_buffer, __LINE__);
+		yaffs_release_temp_buffer(dev, local_buffer);
 
-		/* If we were out of space then reverse any chunks we've added */
+		/* If out of space then reverse any chunks we've added */
 		if (!small_increase_ok)
 			yaffs_resize_file_down(obj, old_file_size);
 	}
@@ -934,7 +910,6 @@
 	}
 
 	return result;
-
 }
 
 struct yaffs_block_index {
@@ -948,44 +923,443 @@
 	int bseq = ((struct yaffs_block_index *)b)->seq;
 	int ablock = ((struct yaffs_block_index *)a)->block;
 	int bblock = ((struct yaffs_block_index *)b)->block;
+
 	if (aseq == bseq)
 		return ablock - bblock;
-	else
-		return aseq - bseq;
+
+	return aseq - bseq;
 }
 
-int yaffs2_scan_backwards(struct yaffs_dev *dev)
+static inline int yaffs2_scan_chunk(struct yaffs_dev *dev,
+		struct yaffs_block_info *bi,
+		int blk, int chunk_in_block,
+		int *found_chunks,
+		u8 *chunk_data,
+		struct list_head *hard_list,
+		int summary_available)
 {
+	struct yaffs_obj_hdr *oh;
+	struct yaffs_obj *in;
+	struct yaffs_obj *parent;
+	int equiv_id;
+	loff_t file_size;
+	int is_shrink;
+	int is_unlinked;
 	struct yaffs_ext_tags tags;
+	int result;
+	int alloc_failed = 0;
+	int chunk = blk * dev->param.chunks_per_block + chunk_in_block;
+	struct yaffs_file_var *file_var;
+	struct yaffs_hardlink_var *hl_var;
+	struct yaffs_symlink_var *sl_var;
+
+	if (summary_available) {
+		result = yaffs_summary_fetch(dev, &tags, chunk_in_block);
+		tags.seq_number = bi->seq_number;
+	}
+
+	if (!summary_available || tags.obj_id == 0) {
+		result = yaffs_rd_chunk_tags_nand(dev, chunk, NULL, &tags);
+		dev->tags_used++;
+	} else {
+		dev->summary_used++;
+	}
+
+	/* Let's have a good look at this chunk... */
+
+	if (!tags.chunk_used) {
+		/* An unassigned chunk in the block.
+		 * If there are used chunks after this one, then
+		 * it is a chunk that was skipped due to failing
+		 * the erased check. Just skip it so that it can
+		 * be deleted.
+		 * But, more typically, We get here when this is
+		 * an unallocated chunk and his means that
+		 * either the block is empty or this is the one
+		 * being allocated from
+		 */
+
+		if (*found_chunks) {
+			/* This is a chunk that was skipped due
+			 * to failing the erased check */
+		} else if (chunk_in_block == 0) {
+			/* We're looking at the first chunk in
+			 * the block so the block is unused */
+			bi->block_state = YAFFS_BLOCK_STATE_EMPTY;
+			dev->n_erased_blocks++;
+		} else {
+			if (bi->block_state == YAFFS_BLOCK_STATE_NEEDS_SCAN ||
+			    bi->block_state == YAFFS_BLOCK_STATE_ALLOCATING) {
+				if (dev->seq_number == bi->seq_number) {
+					/* Allocating from this block*/
+					yaffs_trace(YAFFS_TRACE_SCAN,
+					    " Allocating from %d %d",
+					    blk, chunk_in_block);
+
+					bi->block_state =
+						YAFFS_BLOCK_STATE_ALLOCATING;
+					dev->alloc_block = blk;
+					dev->alloc_page = chunk_in_block;
+					dev->alloc_block_finder = blk;
+				} else {
+					/* This is a partially written block
+					 * that is not the current
+					 * allocation block.
+					 */
+					yaffs_trace(YAFFS_TRACE_SCAN,
+						"Partially written block %d detected. gc will fix this.",
+						blk);
+				}
+			}
+		}
+
+		dev->n_free_chunks++;
+
+	} else if (tags.ecc_result ==
+		YAFFS_ECC_RESULT_UNFIXED) {
+		yaffs_trace(YAFFS_TRACE_SCAN,
+			" Unfixed ECC in chunk(%d:%d), chunk ignored",
+			blk, chunk_in_block);
+			dev->n_free_chunks++;
+	} else if (tags.obj_id > YAFFS_MAX_OBJECT_ID ||
+		   tags.chunk_id > YAFFS_MAX_CHUNK_ID ||
+		   tags.obj_id == YAFFS_OBJECTID_SUMMARY ||
+		   (tags.chunk_id > 0 &&
+		     tags.n_bytes > dev->data_bytes_per_chunk) ||
+		   tags.seq_number != bi->seq_number) {
+		yaffs_trace(YAFFS_TRACE_SCAN,
+			"Chunk (%d:%d) with bad tags:obj = %d, chunk_id = %d, n_bytes = %d, ignored",
+			blk, chunk_in_block, tags.obj_id,
+			tags.chunk_id, tags.n_bytes);
+		dev->n_free_chunks++;
+	} else if (tags.chunk_id > 0) {
+		/* chunk_id > 0 so it is a data chunk... */
+		loff_t endpos;
+		loff_t chunk_base = (tags.chunk_id - 1) *
+					dev->data_bytes_per_chunk;
+
+		*found_chunks = 1;
+
+		yaffs_set_chunk_bit(dev, blk, chunk_in_block);
+		bi->pages_in_use++;
+
+		in = yaffs_find_or_create_by_number(dev,
+					tags.obj_id,
+					YAFFS_OBJECT_TYPE_FILE);
+		if (!in)
+			/* Out of memory */
+			alloc_failed = 1;
+
+		if (in &&
+		    in->variant_type == YAFFS_OBJECT_TYPE_FILE &&
+		    chunk_base < in->variant.file_variant.shrink_size) {
+			/* This has not been invalidated by
+			 * a resize */
+			if (!yaffs_put_chunk_in_file(in, tags.chunk_id,
+								chunk, -1))
+				alloc_failed = 1;
+
+			/* File size is calculated by looking at
+			 * the data chunks if we have not
+			 * seen an object header yet.
+			 * Stop this practice once we find an
+			 * object header.
+			 */
+			endpos = chunk_base + tags.n_bytes;
+
+			if (!in->valid &&
+			    in->variant.file_variant.scanned_size < endpos) {
+				in->variant.file_variant.
+				    scanned_size = endpos;
+				in->variant.file_variant.
+				    file_size = endpos;
+			}
+		} else if (in) {
+			/* This chunk has been invalidated by a
+			 * resize, or a past file deletion
+			 * so delete the chunk*/
+			yaffs_chunk_del(dev, chunk, 1, __LINE__);
+		}
+	} else {
+		/* chunk_id == 0, so it is an ObjectHeader.
+		 * Thus, we read in the object header and make
+		 * the object
+		 */
+		*found_chunks = 1;
+
+		yaffs_set_chunk_bit(dev, blk, chunk_in_block);
+		bi->pages_in_use++;
+
+		oh = NULL;
+		in = NULL;
+
+		if (tags.extra_available) {
+			in = yaffs_find_or_create_by_number(dev,
+					tags.obj_id,
+					tags.extra_obj_type);
+			if (!in)
+				alloc_failed = 1;
+		}
+
+		if (!in ||
+		    (!in->valid && dev->param.disable_lazy_load) ||
+		    tags.extra_shadows ||
+		    (!in->valid && (tags.obj_id == YAFFS_OBJECTID_ROOT ||
+				 tags.obj_id == YAFFS_OBJECTID_LOSTNFOUND))) {
+
+			/* If we don't have  valid info then we
+			 * need to read the chunk
+			 * TODO In future we can probably defer
+			 * reading the chunk and living with
+			 * invalid data until needed.
+			 */
+
+			result = yaffs_rd_chunk_tags_nand(dev,
+						  chunk,
+						  chunk_data,
+						  NULL);
+
+			oh = (struct yaffs_obj_hdr *)chunk_data;
+
+			if (dev->param.inband_tags) {
+				/* Fix up the header if they got
+				 * corrupted by inband tags */
+				oh->shadows_obj =
+				    oh->inband_shadowed_obj_id;
+				oh->is_shrink =
+				    oh->inband_is_shrink;
+			}
+
+			if (!in) {
+				in = yaffs_find_or_create_by_number(dev,
+							tags.obj_id, oh->type);
+				if (!in)
+					alloc_failed = 1;
+			}
+		}
+
+		if (!in) {
+			/* TODO Hoosterman we have a problem! */
+			yaffs_trace(YAFFS_TRACE_ERROR,
+				"yaffs tragedy: Could not make object for object  %d at chunk %d during scan",
+				tags.obj_id, chunk);
+			return YAFFS_FAIL;
+		}
+
+		if (in->valid) {
+			/* We have already filled this one.
+			 * We have a duplicate that will be
+			 * discarded, but we first have to suck
+			 * out resize info if it is a file.
+			 */
+			if ((in->variant_type == YAFFS_OBJECT_TYPE_FILE) &&
+				((oh && oh->type == YAFFS_OBJECT_TYPE_FILE) ||
+				 (tags.extra_available &&
+				  tags.extra_obj_type == YAFFS_OBJECT_TYPE_FILE)
+				)) {
+				loff_t this_size = (oh) ?
+					yaffs_oh_to_size(oh) :
+					tags.extra_file_size;
+				u32 parent_obj_id = (oh) ?
+					oh->parent_obj_id :
+					tags.extra_parent_id;
+
+				is_shrink = (oh) ?
+					oh->is_shrink :
+					tags.extra_is_shrink;
+
+				/* If it is deleted (unlinked
+				 * at start also means deleted)
+				 * we treat the file size as
+				 * being zeroed at this point.
+				 */
+				if (parent_obj_id == YAFFS_OBJECTID_DELETED ||
+				    parent_obj_id == YAFFS_OBJECTID_UNLINKED) {
+					this_size = 0;
+					is_shrink = 1;
+				}
+
+				if (is_shrink &&
+				    in->variant.file_variant.shrink_size >
+				    this_size)
+					in->variant.file_variant.shrink_size =
+					this_size;
+
+				if (is_shrink)
+					bi->has_shrink_hdr = 1;
+			}
+			/* Use existing - destroy this one. */
+			yaffs_chunk_del(dev, chunk, 1, __LINE__);
+		}
+
+		if (!in->valid && in->variant_type !=
+		    (oh ? oh->type : tags.extra_obj_type))
+			yaffs_trace(YAFFS_TRACE_ERROR,
+				"yaffs tragedy: Bad object type, %d != %d, for object %d at chunk %d during scan",
+				oh ? oh->type : tags.extra_obj_type,
+				in->variant_type, tags.obj_id,
+				chunk);
+
+		if (!in->valid &&
+		    (tags.obj_id == YAFFS_OBJECTID_ROOT ||
+		     tags.obj_id == YAFFS_OBJECTID_LOSTNFOUND)) {
+			/* We only load some info, don't fiddle
+			 * with directory structure */
+			in->valid = 1;
+
+			if (oh) {
+				in->yst_mode = oh->yst_mode;
+				yaffs_load_attribs(in, oh);
+				in->lazy_loaded = 0;
+			} else {
+				in->lazy_loaded = 1;
+			}
+			in->hdr_chunk = chunk;
+
+		} else if (!in->valid) {
+			/* we need to load this info */
+			in->valid = 1;
+			in->hdr_chunk = chunk;
+			if (oh) {
+				in->variant_type = oh->type;
+				in->yst_mode = oh->yst_mode;
+				yaffs_load_attribs(in, oh);
+
+				if (oh->shadows_obj > 0)
+					yaffs_handle_shadowed_obj(dev,
+					     oh->shadows_obj, 1);
+
+				yaffs_set_obj_name_from_oh(in, oh);
+				parent = yaffs_find_or_create_by_number(dev,
+						oh->parent_obj_id,
+						YAFFS_OBJECT_TYPE_DIRECTORY);
+				file_size = yaffs_oh_to_size(oh);
+				is_shrink = oh->is_shrink;
+				equiv_id = oh->equiv_id;
+			} else {
+				in->variant_type = tags.extra_obj_type;
+				parent = yaffs_find_or_create_by_number(dev,
+						tags.extra_parent_id,
+						YAFFS_OBJECT_TYPE_DIRECTORY);
+				file_size = tags.extra_file_size;
+				is_shrink = tags.extra_is_shrink;
+				equiv_id = tags.extra_equiv_id;
+				in->lazy_loaded = 1;
+			}
+			in->dirty = 0;
+
+			if (!parent)
+				alloc_failed = 1;
+
+			/* directory stuff...
+			 * hook up to parent
+			 */
+
+			if (parent &&
+			    parent->variant_type == YAFFS_OBJECT_TYPE_UNKNOWN) {
+				/* Set up as a directory */
+				parent->variant_type =
+					YAFFS_OBJECT_TYPE_DIRECTORY;
+				INIT_LIST_HEAD(&parent->
+						variant.dir_variant.children);
+			} else if (!parent ||
+				   parent->variant_type !=
+					YAFFS_OBJECT_TYPE_DIRECTORY) {
+				/* Hoosterman, another problem....
+				 * Trying to use a non-directory as a directory
+				 */
+
+				yaffs_trace(YAFFS_TRACE_ERROR,
+					"yaffs tragedy: attempting to use non-directory as a directory in scan. Put in lost+found."
+					);
+				parent = dev->lost_n_found;
+			}
+			yaffs_add_obj_to_dir(parent, in);
+
+			is_unlinked = (parent == dev->del_dir) ||
+					(parent == dev->unlinked_dir);
+
+			if (is_shrink)
+				/* Mark the block */
+				bi->has_shrink_hdr = 1;
+
+			/* Note re hardlinks.
+			 * Since we might scan a hardlink before its equivalent
+			 * object is scanned we put them all in a list.
+			 * After scanning is complete, we should have all the
+			 * objects, so we run through this list and fix up all
+			 * the chains.
+			 */
+
+			switch (in->variant_type) {
+			case YAFFS_OBJECT_TYPE_UNKNOWN:
+				/* Todo got a problem */
+				break;
+			case YAFFS_OBJECT_TYPE_FILE:
+				file_var = &in->variant.file_variant;
+				if (file_var->scanned_size < file_size) {
+					/* This covers the case where the file
+					 * size is greater than the data held.
+					 * This will happen if the file is
+					 * resized to be larger than its
+					 * current data extents.
+					 */
+					file_var->file_size = file_size;
+					file_var->scanned_size = file_size;
+				}
+
+				if (file_var->shrink_size > file_size)
+					file_var->shrink_size = file_size;
+
+				break;
+			case YAFFS_OBJECT_TYPE_HARDLINK:
+				hl_var = &in->variant.hardlink_variant;
+				if (!is_unlinked) {
+					hl_var->equiv_id = equiv_id;
+					list_add(&in->hard_links, hard_list);
+				}
+				break;
+			case YAFFS_OBJECT_TYPE_DIRECTORY:
+				/* Do nothing */
+				break;
+			case YAFFS_OBJECT_TYPE_SPECIAL:
+				/* Do nothing */
+				break;
+			case YAFFS_OBJECT_TYPE_SYMLINK:
+				sl_var = &in->variant.symlink_variant;
+				if (oh) {
+					sl_var->alias =
+					    yaffs_clone_str(oh->alias);
+					if (!sl_var->alias)
+						alloc_failed = 1;
+				}
+				break;
+			}
+		}
+	}
+	return alloc_failed ? YAFFS_FAIL : YAFFS_OK;
+}
+
+int yaffs2_scan_backwards(struct yaffs_dev *dev)
+{
 	int blk;
 	int block_iter;
 	int start_iter;
 	int end_iter;
 	int n_to_scan = 0;
-
-	int chunk;
-	int result;
+	enum yaffs_block_state state;
 	int c;
 	int deleted;
-	enum yaffs_block_state state;
-	struct yaffs_obj *hard_list = NULL;
+	LIST_HEAD(hard_list);
 	struct yaffs_block_info *bi;
 	u32 seq_number;
-	struct yaffs_obj_hdr *oh;
-	struct yaffs_obj *in;
-	struct yaffs_obj *parent;
 	int n_blocks = dev->internal_end_block - dev->internal_start_block + 1;
-	int is_unlinked;
 	u8 *chunk_data;
-
-	int file_size;
-	int is_shrink;
 	int found_chunks;
-	int equiv_id;
 	int alloc_failed = 0;
-
 	struct yaffs_block_index *block_index = NULL;
 	int alt_block_index = 0;
+	int summary_available;
 
 	yaffs_trace(YAFFS_TRACE_SCAN,
 		"yaffs2_scan_backwards starts  intstartblk %d intendblk %d...",
@@ -993,8 +1367,8 @@
 
 	dev->seq_number = YAFFS_LOWEST_SEQUENCE_NUMBER;
 
-	block_index = kmalloc(n_blocks * sizeof(struct yaffs_block_index),
-			GFP_NOFS);
+	block_index =
+		kmalloc(n_blocks * sizeof(struct yaffs_block_index), GFP_NOFS);
 
 	if (!block_index) {
 		block_index =
@@ -1011,7 +1385,7 @@
 
 	dev->blocks_in_checkpt = 0;
 
-	chunk_data = yaffs_get_temp_buffer(dev, __LINE__);
+	chunk_data = yaffs_get_temp_buffer(dev);
 
 	/* Scan all the blocks to determine their state */
 	bi = dev->block_info;
@@ -1027,35 +1401,32 @@
 		bi->seq_number = seq_number;
 
 		if (bi->seq_number == YAFFS_SEQUENCE_CHECKPOINT_DATA)
-			bi->block_state = state = YAFFS_BLOCK_STATE_CHECKPOINT;
+			bi->block_state = YAFFS_BLOCK_STATE_CHECKPOINT;
 		if (bi->seq_number == YAFFS_SEQUENCE_BAD_BLOCK)
-			bi->block_state = state = YAFFS_BLOCK_STATE_DEAD;
+			bi->block_state = YAFFS_BLOCK_STATE_DEAD;
 
 		yaffs_trace(YAFFS_TRACE_SCAN_DEBUG,
 			"Block scanning block %d state %d seq %d",
-			blk, state, seq_number);
+			blk, bi->block_state, seq_number);
 
-		if (state == YAFFS_BLOCK_STATE_CHECKPOINT) {
+		if (bi->block_state == YAFFS_BLOCK_STATE_CHECKPOINT) {
 			dev->blocks_in_checkpt++;
 
-		} else if (state == YAFFS_BLOCK_STATE_DEAD) {
+		} else if (bi->block_state == YAFFS_BLOCK_STATE_DEAD) {
 			yaffs_trace(YAFFS_TRACE_BAD_BLOCKS,
 				"block %d is bad", blk);
-		} else if (state == YAFFS_BLOCK_STATE_EMPTY) {
+		} else if (bi->block_state == YAFFS_BLOCK_STATE_EMPTY) {
 			yaffs_trace(YAFFS_TRACE_SCAN_DEBUG, "Block empty ");
 			dev->n_erased_blocks++;
 			dev->n_free_chunks += dev->param.chunks_per_block;
-		} else if (state == YAFFS_BLOCK_STATE_NEEDS_SCANNING) {
-
+		} else if (bi->block_state ==
+				YAFFS_BLOCK_STATE_NEEDS_SCAN) {
 			/* Determine the highest sequence number */
 			if (seq_number >= YAFFS_LOWEST_SEQUENCE_NUMBER &&
 			    seq_number < YAFFS_HIGHEST_SEQUENCE_NUMBER) {
-
 				block_index[n_to_scan].seq = seq_number;
 				block_index[n_to_scan].block = blk;
-
 				n_to_scan++;
-
 				if (seq_number >= dev->seq_number)
 					dev->seq_number = seq_number;
 			} else {
@@ -1063,7 +1434,6 @@
 				yaffs_trace(YAFFS_TRACE_SCAN,
 					"Block scanning block %d has bad sequence number %d",
 					blk, seq_number);
-
 			}
 		}
 		bi++;
@@ -1087,7 +1457,8 @@
 	yaffs_trace(YAFFS_TRACE_SCAN_DEBUG, "%d blocks to scan", n_to_scan);
 
 	/* For each block.... backwards */
-	for (block_iter = end_iter; !alloc_failed && block_iter >= start_iter;
+	for (block_iter = end_iter;
+	     !alloc_failed && block_iter >= start_iter;
 	     block_iter--) {
 		/* Cooperative multitasking! This loop can run for so
 		   long that watchdog timers expire. */
@@ -1095,474 +1466,38 @@
 
 		/* get the block to scan in the correct order */
 		blk = block_index[block_iter].block;
-
 		bi = yaffs_get_block_info(dev, blk);
-
-		state = bi->block_state;
-
 		deleted = 0;
 
+		summary_available = yaffs_summary_read(dev, dev->sum_tags, blk);
+
 		/* For each chunk in each block that needs scanning.... */
 		found_chunks = 0;
-		for (c = dev->param.chunks_per_block - 1;
+		if (summary_available)
+			c = dev->chunks_per_summary - 1;
+		else
+			c = dev->param.chunks_per_block - 1;
+
+		for (/* c is already initialised */;
 		     !alloc_failed && c >= 0 &&
-		     (state == YAFFS_BLOCK_STATE_NEEDS_SCANNING ||
-		      state == YAFFS_BLOCK_STATE_ALLOCATING); c--) {
+		     (bi->block_state == YAFFS_BLOCK_STATE_NEEDS_SCAN ||
+		      bi->block_state == YAFFS_BLOCK_STATE_ALLOCATING);
+		      c--) {
 			/* Scan backwards...
 			 * Read the tags and decide what to do
 			 */
-
-			chunk = blk * dev->param.chunks_per_block + c;
-
-			result = yaffs_rd_chunk_tags_nand(dev, chunk, NULL,
-							  &tags);
-
-			/* Let's have a good look at this chunk... */
-
-			if (!tags.chunk_used) {
-				/* An unassigned chunk in the block.
-				 * If there are used chunks after this one, then
-				 * it is a chunk that was skipped due to failing the erased
-				 * check. Just skip it so that it can be deleted.
-				 * But, more typically, We get here when this is an unallocated
-				 * chunk and his means that either the block is empty or
-				 * this is the one being allocated from
-				 */
-
-				if (found_chunks) {
-					/* This is a chunk that was skipped due to failing the erased check */
-				} else if (c == 0) {
-					/* We're looking at the first chunk in the block so the block is unused */
-					state = YAFFS_BLOCK_STATE_EMPTY;
-					dev->n_erased_blocks++;
-				} else {
-					if (state ==
-					    YAFFS_BLOCK_STATE_NEEDS_SCANNING
-					    || state ==
-					    YAFFS_BLOCK_STATE_ALLOCATING) {
-						if (dev->seq_number ==
-						    bi->seq_number) {
-							/* this is the block being allocated from */
-
-							yaffs_trace(YAFFS_TRACE_SCAN,
-								" Allocating from %d %d",
-								blk, c);
-
-							state =
-							    YAFFS_BLOCK_STATE_ALLOCATING;
-							dev->alloc_block = blk;
-							dev->alloc_page = c;
-							dev->
-							    alloc_block_finder =
-							    blk;
-						} else {
-							/* This is a partially written block that is not
-							 * the current allocation block.
-							 */
-
-							yaffs_trace(YAFFS_TRACE_SCAN,
-								"Partially written block %d detected",
-								blk);
-						}
-					}
-				}
-
-				dev->n_free_chunks++;
-
-			} else if (tags.ecc_result == YAFFS_ECC_RESULT_UNFIXED) {
-				yaffs_trace(YAFFS_TRACE_SCAN,
-					" Unfixed ECC in chunk(%d:%d), chunk ignored",
-					blk, c);
-
-				dev->n_free_chunks++;
-
-			} else if (tags.obj_id > YAFFS_MAX_OBJECT_ID ||
-				   tags.chunk_id > YAFFS_MAX_CHUNK_ID ||
-				   (tags.chunk_id > 0
-				    && tags.n_bytes > dev->data_bytes_per_chunk)
-				   || tags.seq_number != bi->seq_number) {
-				yaffs_trace(YAFFS_TRACE_SCAN,
-					"Chunk (%d:%d) with bad tags:obj = %d, chunk_id = %d, n_bytes = %d, ignored",
-					blk, c, tags.obj_id,
-					tags.chunk_id, tags.n_bytes);
-
-				dev->n_free_chunks++;
-
-			} else if (tags.chunk_id > 0) {
-				/* chunk_id > 0 so it is a data chunk... */
-				unsigned int endpos;
-				u32 chunk_base =
-				    (tags.chunk_id -
-				     1) * dev->data_bytes_per_chunk;
-
-				found_chunks = 1;
-
-				yaffs_set_chunk_bit(dev, blk, c);
-				bi->pages_in_use++;
-
-				in = yaffs_find_or_create_by_number(dev,
-								    tags.obj_id,
-								    YAFFS_OBJECT_TYPE_FILE);
-				if (!in) {
-					/* Out of memory */
-					alloc_failed = 1;
-				}
-
-				if (in &&
-				    in->variant_type == YAFFS_OBJECT_TYPE_FILE
-				    && chunk_base <
-				    in->variant.file_variant.shrink_size) {
-					/* This has not been invalidated by a resize */
-					if (!yaffs_put_chunk_in_file
-					    (in, tags.chunk_id, chunk, -1)) {
-						alloc_failed = 1;
-					}
-
-					/* File size is calculated by looking at the data chunks if we have not
-					 * seen an object header yet. Stop this practice once we find an object header.
-					 */
-					endpos = chunk_base + tags.n_bytes;
-
-					if (!in->valid &&	/* have not got an object header yet */
-					    in->variant.file_variant.
-					    scanned_size < endpos) {
-						in->variant.file_variant.
-						    scanned_size = endpos;
-						in->variant.file_variant.
-						    file_size = endpos;
-					}
-
-				} else if (in) {
-					/* This chunk has been invalidated by a resize, or a past file deletion
-					 * so delete the chunk*/
-					yaffs_chunk_del(dev, chunk, 1,
-							__LINE__);
-
-				}
-			} else {
-				/* chunk_id == 0, so it is an ObjectHeader.
-				 * Thus, we read in the object header and make the object
-				 */
-				found_chunks = 1;
-
-				yaffs_set_chunk_bit(dev, blk, c);
-				bi->pages_in_use++;
-
-				oh = NULL;
-				in = NULL;
-
-				if (tags.extra_available) {
-					in = yaffs_find_or_create_by_number(dev,
-									    tags.
-									    obj_id,
-									    tags.
-									    extra_obj_type);
-					if (!in)
-						alloc_failed = 1;
-				}
-
-				if (!in ||
-				    (!in->valid && dev->param.disable_lazy_load)
-				    || tags.extra_shadows || (!in->valid
-							      && (tags.obj_id ==
-								  YAFFS_OBJECTID_ROOT
-								  || tags.
-								  obj_id ==
-								  YAFFS_OBJECTID_LOSTNFOUND)))
-				{
-
-					/* If we don't have  valid info then we need to read the chunk
-					 * TODO In future we can probably defer reading the chunk and
-					 * living with invalid data until needed.
-					 */
-
-					result = yaffs_rd_chunk_tags_nand(dev,
-									  chunk,
-									  chunk_data,
-									  NULL);
-
-					oh = (struct yaffs_obj_hdr *)chunk_data;
-
-					if (dev->param.inband_tags) {
-						/* Fix up the header if they got corrupted by inband tags */
-						oh->shadows_obj =
-						    oh->inband_shadowed_obj_id;
-						oh->is_shrink =
-						    oh->inband_is_shrink;
-					}
-
-					if (!in) {
-						in = yaffs_find_or_create_by_number(dev, tags.obj_id, oh->type);
-						if (!in)
-							alloc_failed = 1;
-					}
-
-				}
-
-				if (!in) {
-					/* TODO Hoosterman we have a problem! */
-					yaffs_trace(YAFFS_TRACE_ERROR,
-						"yaffs tragedy: Could not make object for object  %d at chunk %d during scan",
-						tags.obj_id, chunk);
-					continue;
-				}
-
-				if (in->valid) {
-					/* We have already filled this one.
-					 * We have a duplicate that will be discarded, but
-					 * we first have to suck out resize info if it is a file.
-					 */
-
-					if ((in->variant_type ==
-					     YAFFS_OBJECT_TYPE_FILE) && ((oh
-									  &&
-									  oh->
-									  type
-									  ==
-									  YAFFS_OBJECT_TYPE_FILE)
-									 ||
-									 (tags.
-									  extra_available
-									  &&
-									  tags.
-									  extra_obj_type
-									  ==
-									  YAFFS_OBJECT_TYPE_FILE)))
-					{
-						u32 this_size =
-						    (oh) ? oh->
-						    file_size :
-						    tags.extra_length;
-						u32 parent_obj_id =
-						    (oh) ? oh->parent_obj_id :
-						    tags.extra_parent_id;
-
-						is_shrink =
-						    (oh) ? oh->
-						    is_shrink :
-						    tags.extra_is_shrink;
-
-						/* If it is deleted (unlinked at start also means deleted)
-						 * we treat the file size as being zeroed at this point.
-						 */
-						if (parent_obj_id ==
-						    YAFFS_OBJECTID_DELETED
-						    || parent_obj_id ==
-						    YAFFS_OBJECTID_UNLINKED) {
-							this_size = 0;
-							is_shrink = 1;
-						}
-
-						if (is_shrink
-						    && in->variant.file_variant.
-						    shrink_size > this_size)
-							in->variant.
-							    file_variant.
-							    shrink_size =
-							    this_size;
-
-						if (is_shrink)
-							bi->has_shrink_hdr = 1;
-
-					}
-					/* Use existing - destroy this one. */
-					yaffs_chunk_del(dev, chunk, 1,
-							__LINE__);
-
-				}
-
-				if (!in->valid && in->variant_type !=
-				    (oh ? oh->type : tags.extra_obj_type))
-					yaffs_trace(YAFFS_TRACE_ERROR,
-						"yaffs tragedy: Bad object type, %d != %d, for object %d at chunk %d during scan",
-						oh ?
-						oh->type : tags.extra_obj_type,
-						in->variant_type, tags.obj_id,
-						chunk);
-
-				if (!in->valid &&
-				    (tags.obj_id == YAFFS_OBJECTID_ROOT ||
-				     tags.obj_id ==
-				     YAFFS_OBJECTID_LOSTNFOUND)) {
-					/* We only load some info, don't fiddle with directory structure */
-					in->valid = 1;
-
-					if (oh) {
-
-						in->yst_mode = oh->yst_mode;
-						yaffs_load_attribs(in, oh);
-						in->lazy_loaded = 0;
-					} else {
-						in->lazy_loaded = 1;
-                                        }
-					in->hdr_chunk = chunk;
-
-				} else if (!in->valid) {
-					/* we need to load this info */
-
-					in->valid = 1;
-					in->hdr_chunk = chunk;
-
-					if (oh) {
-						in->variant_type = oh->type;
-
-						in->yst_mode = oh->yst_mode;
-						yaffs_load_attribs(in, oh);
-
-						if (oh->shadows_obj > 0)
-							yaffs_handle_shadowed_obj
-							    (dev,
-							     oh->shadows_obj,
-							     1);
-
-						yaffs_set_obj_name_from_oh(in,
-									   oh);
-						parent =
-						    yaffs_find_or_create_by_number
-						    (dev, oh->parent_obj_id,
-						     YAFFS_OBJECT_TYPE_DIRECTORY);
-
-						file_size = oh->file_size;
-						is_shrink = oh->is_shrink;
-						equiv_id = oh->equiv_id;
-
-					} else {
-						in->variant_type =
-						    tags.extra_obj_type;
-						parent =
-						    yaffs_find_or_create_by_number
-						    (dev, tags.extra_parent_id,
-						     YAFFS_OBJECT_TYPE_DIRECTORY);
-						file_size = tags.extra_length;
-						is_shrink =
-						    tags.extra_is_shrink;
-						equiv_id = tags.extra_equiv_id;
-						in->lazy_loaded = 1;
-
-					}
-					in->dirty = 0;
-
-					if (!parent)
-						alloc_failed = 1;
-
-					/* directory stuff...
-					 * hook up to parent
-					 */
-
-					if (parent && parent->variant_type ==
-					    YAFFS_OBJECT_TYPE_UNKNOWN) {
-						/* Set up as a directory */
-						parent->variant_type =
-						    YAFFS_OBJECT_TYPE_DIRECTORY;
-						INIT_LIST_HEAD(&parent->
-							       variant.dir_variant.children);
-					} else if (!parent
-						   || parent->variant_type !=
-						   YAFFS_OBJECT_TYPE_DIRECTORY) {
-						/* Hoosterman, another problem....
-						 * We're trying to use a non-directory as a directory
-						 */
-
-						yaffs_trace(YAFFS_TRACE_ERROR,
-							"yaffs tragedy: attempting to use non-directory as a directory in scan. Put in lost+found."
-							);
-						parent = dev->lost_n_found;
-					}
-
-					yaffs_add_obj_to_dir(parent, in);
-
-					is_unlinked = (parent == dev->del_dir)
-					    || (parent == dev->unlinked_dir);
-
-					if (is_shrink) {
-						/* Mark the block as having a shrink header */
-						bi->has_shrink_hdr = 1;
-					}
-
-					/* Note re hardlinks.
-					 * Since we might scan a hardlink before its equivalent object is scanned
-					 * we put them all in a list.
-					 * After scanning is complete, we should have all the objects, so we run
-					 * through this list and fix up all the chains.
-					 */
-
-					switch (in->variant_type) {
-					case YAFFS_OBJECT_TYPE_UNKNOWN:
-						/* Todo got a problem */
-						break;
-					case YAFFS_OBJECT_TYPE_FILE:
-
-						if (in->variant.
-						    file_variant.scanned_size <
-						    file_size) {
-							/* This covers the case where the file size is greater
-							 * than where the data is
-							 * This will happen if the file is resized to be larger
-							 * than its current data extents.
-							 */
-							in->variant.
-							    file_variant.
-							    file_size =
-							    file_size;
-							in->variant.
-							    file_variant.
-							    scanned_size =
-							    file_size;
-						}
-
-						if (in->variant.file_variant.
-						    shrink_size > file_size)
-							in->variant.
-							    file_variant.
-							    shrink_size =
-							    file_size;
-
-						break;
-					case YAFFS_OBJECT_TYPE_HARDLINK:
-						if (!is_unlinked) {
-							in->variant.
-							    hardlink_variant.
-							    equiv_id = equiv_id;
-							in->hard_links.next =
-							    (struct list_head *)
-							    hard_list;
-							hard_list = in;
-						}
-						break;
-					case YAFFS_OBJECT_TYPE_DIRECTORY:
-						/* Do nothing */
-						break;
-					case YAFFS_OBJECT_TYPE_SPECIAL:
-						/* Do nothing */
-						break;
-					case YAFFS_OBJECT_TYPE_SYMLINK:
-						if (oh) {
-							in->variant.
-							    symlink_variant.
-							    alias =
-							    yaffs_clone_str(oh->
-									    alias);
-							if (!in->variant.
-							    symlink_variant.
-							    alias)
-								alloc_failed =
-								    1;
-						}
-						break;
-					}
-
-				}
-
-			}
-
-		}		/* End of scanning for each chunk */
-
-		if (state == YAFFS_BLOCK_STATE_NEEDS_SCANNING) {
-			/* If we got this far while scanning, then the block is fully allocated. */
-			state = YAFFS_BLOCK_STATE_FULL;
+			if (yaffs2_scan_chunk(dev, bi, blk, c,
+					&found_chunks, chunk_data,
+					&hard_list, summary_available) ==
+					YAFFS_FAIL)
+				alloc_failed = 1;
 		}
 
-		bi->block_state = state;
+		if (bi->block_state == YAFFS_BLOCK_STATE_NEEDS_SCAN) {
+			/* If we got this far while scanning, then the block
+			 * is fully allocated. */
+			bi->block_state = YAFFS_BLOCK_STATE_FULL;
+		}
 
 		/* Now let's see if it was dirty */
 		if (bi->pages_in_use == 0 &&
@@ -1570,7 +1505,6 @@
 		    bi->block_state == YAFFS_BLOCK_STATE_FULL) {
 			yaffs_block_became_dirty(dev, blk);
 		}
-
 	}
 
 	yaffs_skip_rest_of_block(dev);
@@ -1582,12 +1516,12 @@
 
 	/* Ok, we've done all the scanning.
 	 * Fix up the hard link chains.
-	 * We should now have scanned all the objects, now it's time to add these
+	 * We have scanned all the objects, now it's time to add these
 	 * hardlinks.
 	 */
-	yaffs_link_fixup(dev, hard_list);
+	yaffs_link_fixup(dev, &hard_list);
 
-	yaffs_release_temp_buffer(dev, chunk_data, __LINE__);
+	yaffs_release_temp_buffer(dev, chunk_data);
 
 	if (alloc_failed)
 		return YAFFS_FAIL;
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_yaffs2.h linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_yaffs2.h
--- linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yaffs_yaffs2.h	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yaffs_yaffs2.h	2014-07-29 17:28:38.819972000 +0800
@@ -1,7 +1,7 @@
 /*
  * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
  *
- * Copyright (C) 2002-2010 Aleph One Ltd.
+ * Copyright (C) 2002-2011 Aleph One Ltd.
  *   for Toby Churchill Ltd and Brightstar Engineering
  *
  * Created by Charles Manning <charles@aleph1.co.uk>
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yportenv.h linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yportenv.h
--- linux-linaro-3.4-2012.05-1_original/fs/yaffs2/yportenv.h	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/fs/yaffs2/yportenv.h	2014-07-29 17:28:38.819972000 +0800
@@ -1,7 +1,7 @@
 /*
  * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
  *
- * Copyright (C) 2002-2010 Aleph One Ltd.
+ * Copyright (C) 2002-2011 Aleph One Ltd.
  *   for Toby Churchill Ltd and Brightstar Engineering
  *
  * Created by Charles Manning <charles@aleph1.co.uk>
@@ -31,6 +31,7 @@
 #include <linux/sort.h>
 #include <linux/bitops.h>
 
+/*  These type wrappings are used to support Unicode names in WinCE. */
 #define YCHAR char
 #define YUCHAR unsigned char
 #define _Y(x)     x
@@ -48,22 +49,13 @@
 #define compile_time_assertion(assertion) \
 	({ int x = __builtin_choose_expr(assertion, 0, (void)0); (void) x; })
 
-
-#ifndef Y_DUMP_STACK
-#define Y_DUMP_STACK() dump_stack()
-#endif
-
+#ifdef CONFIG_YAFFS_DEBUG
 #define yaffs_trace(msk, fmt, ...) do { \
-	if(yaffs_trace_mask & (msk)) \
+	if (yaffs_trace_mask & (msk)) \
 		printk(KERN_DEBUG "yaffs: " fmt "\n", ##__VA_ARGS__); \
-} while(0)
-
-#ifndef YBUG
-#define YBUG() do {\
-	yaffs_trace(YAFFS_TRACE_BUG,\
-		"bug " __FILE__ " %d",\
-		__LINE__);\
-	Y_DUMP_STACK();\
+} while (0)
+#else
+#define yaffs_trace(msk, fmt, ...) do { \
 } while (0)
 #endif
 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/include/linux/acpi.h linux-linaro-3.4-2012.05-1_cavium/include/linux/acpi.h
--- linux-linaro-3.4-2012.05-1_original/include/linux/acpi.h	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/include/linux/acpi.h	2014-09-12 15:59:37.348052000 +0800
@@ -25,7 +25,9 @@
 #ifndef _LINUX_ACPI_H
 #define _LINUX_ACPI_H
 
+#include <linux/errno.h>
 #include <linux/ioport.h>	/* for struct resource */
+#include <linux/device.h>
 
 #ifdef	CONFIG_ACPI
 
@@ -72,9 +74,18 @@
 
 /* Table Handlers */
 
-typedef int (*acpi_table_handler) (struct acpi_table_header *table);
+typedef int (*acpi_tbl_table_handler)(struct acpi_table_header *table);
 
-typedef int (*acpi_table_entry_handler) (struct acpi_subtable_header *header, const unsigned long end);
+typedef int (*acpi_tbl_entry_handler)(struct acpi_subtable_header *header,
+				      const unsigned long end);
+
+#ifdef CONFIG_ACPI_INITRD_TABLE_OVERRIDE
+void acpi_initrd_override(void *data, size_t size);
+#else
+static inline void acpi_initrd_override(void *data, size_t size)
+{
+}
+#endif
 
 char * __acpi_map_table (unsigned long phys_addr, unsigned long size);
 void __acpi_unmap_table(char *map, unsigned long size);
@@ -85,10 +96,14 @@
 int acpi_numa_init (void);
 
 int acpi_table_init (void);
-int acpi_table_parse (char *id, acpi_table_handler handler);
+int acpi_table_parse(char *id, acpi_tbl_table_handler handler);
 int __init acpi_table_parse_entries(char *id, unsigned long table_size,
-	int entry_id, acpi_table_entry_handler handler, unsigned int max_entries);
-int acpi_table_parse_madt (enum acpi_madt_type id, acpi_table_entry_handler handler, unsigned int max_entries);
+				    int entry_id,
+				    acpi_tbl_entry_handler handler,
+				    unsigned int max_entries);
+int acpi_table_parse_madt(enum acpi_madt_type id,
+			  acpi_tbl_entry_handler handler,
+			  unsigned int max_entries);
 int acpi_parse_mcfg (struct acpi_table_header *header);
 void acpi_table_print_madt_entry (struct acpi_subtable_header *madt);
 
@@ -96,7 +111,7 @@
 void acpi_numa_slit_init (struct acpi_table_slit *slit);
 void acpi_numa_processor_affinity_init (struct acpi_srat_cpu_affinity *pa);
 void acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa);
-void acpi_numa_memory_affinity_init (struct acpi_srat_mem_affinity *ma);
+int acpi_numa_memory_affinity_init (struct acpi_srat_mem_affinity *ma);
 void acpi_numa_arch_fixup(void);
 
 #ifdef CONFIG_ACPI_HOTPLUG_CPU
@@ -137,15 +152,6 @@
 
 void acpi_pci_irq_disable (struct pci_dev *dev);
 
-struct acpi_pci_driver {
-	struct acpi_pci_driver *next;
-	int (*add)(acpi_handle handle);
-	void (*remove)(acpi_handle handle);
-};
-
-int acpi_pci_register_driver(struct acpi_pci_driver *driver);
-void acpi_pci_unregister_driver(struct acpi_pci_driver *driver);
-
 extern int ec_read(u8 addr, u8 *val);
 extern int ec_write(u8 addr, u8 val);
 extern int ec_transaction(u8 command,
@@ -189,7 +195,9 @@
 #if defined(CONFIG_ACPI_VIDEO) || defined(CONFIG_ACPI_VIDEO_MODULE)
 
 extern long acpi_video_get_capabilities(acpi_handle graphics_dev_handle);
-extern long acpi_is_video_device(struct acpi_device *device);
+extern long acpi_is_video_device(acpi_handle handle);
+extern void acpi_video_dmi_promote_vendor(void);
+extern void acpi_video_dmi_demote_vendor(void);
 extern int acpi_video_backlight_support(void);
 extern int acpi_video_display_switch_support(void);
 
@@ -200,11 +208,19 @@
 	return 0;
 }
 
-static inline long acpi_is_video_device(struct acpi_device *device)
+static inline long acpi_is_video_device(acpi_handle handle)
 {
 	return 0;
 }
 
+static inline void acpi_video_dmi_promote_vendor(void)
+{
+}
+
+static inline void acpi_video_dmi_demote_vendor(void)
+{
+}
+
 static inline int acpi_video_backlight_support(void)
 {
 	return 0;
@@ -240,6 +256,26 @@
 
 #define PXM_INVAL	(-1)
 
+bool acpi_dev_resource_memory(struct acpi_resource *ares, struct resource *res);
+bool acpi_dev_resource_io(struct acpi_resource *ares, struct resource *res);
+bool acpi_dev_resource_address_space(struct acpi_resource *ares,
+				     struct resource *res);
+bool acpi_dev_resource_ext_address_space(struct acpi_resource *ares,
+					 struct resource *res);
+unsigned long acpi_dev_irq_flags(u8 triggering, u8 polarity, u8 shareable);
+bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index,
+				 struct resource *res);
+
+struct resource_list_entry {
+	struct list_head node;
+	struct resource res;
+};
+
+void acpi_dev_free_resource_list(struct list_head *list);
+int acpi_dev_get_resources(struct acpi_device *adev, struct list_head *list,
+			   int (*preproc)(struct acpi_resource *, void *),
+			   void *preproc_data);
+
 int acpi_check_resource_conflict(const struct resource *res);
 
 int acpi_check_region(resource_size_t start, resource_size_t n,
@@ -247,10 +283,14 @@
 
 int acpi_resources_are_enforced(void);
 
-#ifdef CONFIG_PM_SLEEP
+#ifdef CONFIG_HIBERNATION
 void __init acpi_no_s4_hw_signature(void);
+#endif
+
+#ifdef CONFIG_PM_SLEEP
 void __init acpi_old_suspend_ordering(void);
 void __init acpi_nvs_nosave(void);
+void __init acpi_nvs_nosave_s3(void);
 #endif /* CONFIG_PM_SLEEP */
 
 struct acpi_osc_context {
@@ -277,7 +317,7 @@
 #define OSC_SB_PAD_SUPPORT		1
 #define OSC_SB_PPC_OST_SUPPORT		2
 #define OSC_SB_PR3_SUPPORT		4
-#define OSC_SB_CPUHP_OST_SUPPORT	8
+#define OSC_SB_HOTPLUG_OST_SUPPORT	8
 #define OSC_SB_APEI_SUPPORT		16
 
 extern bool osc_sb_apei_support_acked;
@@ -309,6 +349,43 @@
 
 extern acpi_status acpi_pci_osc_control_set(acpi_handle handle,
 					     u32 *mask, u32 req);
+
+/* Enable _OST when all relevant hotplug operations are enabled */
+#if defined(CONFIG_ACPI_HOTPLUG_CPU) &&			\
+	(defined(CONFIG_ACPI_HOTPLUG_MEMORY) ||		\
+	 defined(CONFIG_ACPI_HOTPLUG_MEMORY_MODULE)) &&	\
+	defined(CONFIG_ACPI_CONTAINER)
+#define ACPI_HOTPLUG_OST
+#endif
+
+/* _OST Source Event Code (OSPM Action) */
+#define ACPI_OST_EC_OSPM_SHUTDOWN		0x100
+#define ACPI_OST_EC_OSPM_EJECT			0x103
+#define ACPI_OST_EC_OSPM_INSERTION		0x200
+
+/* _OST General Processing Status Code */
+#define ACPI_OST_SC_SUCCESS			0x0
+#define ACPI_OST_SC_NON_SPECIFIC_FAILURE	0x1
+#define ACPI_OST_SC_UNRECOGNIZED_NOTIFY		0x2
+
+/* _OST OS Shutdown Processing (0x100) Status Code */
+#define ACPI_OST_SC_OS_SHUTDOWN_DENIED		0x80
+#define ACPI_OST_SC_OS_SHUTDOWN_IN_PROGRESS	0x81
+#define ACPI_OST_SC_OS_SHUTDOWN_COMPLETED	0x82
+#define ACPI_OST_SC_OS_SHUTDOWN_NOT_SUPPORTED	0x83
+
+/* _OST Ejection Request (0x3, 0x103) Status Code */
+#define ACPI_OST_SC_EJECT_NOT_SUPPORTED		0x80
+#define ACPI_OST_SC_DEVICE_IN_USE		0x81
+#define ACPI_OST_SC_DEVICE_BUSY			0x82
+#define ACPI_OST_SC_EJECT_DEPENDENCY_BUSY	0x83
+#define ACPI_OST_SC_EJECT_IN_PROGRESS		0x84
+
+/* _OST Insertion Request (0x200) Status Code */
+#define ACPI_OST_SC_INSERT_IN_PROGRESS		0x80
+#define ACPI_OST_SC_DRIVER_LOAD_FAILURE		0x81
+#define ACPI_OST_SC_INSERT_NOT_SUPPORTED	0x82
+
 extern void acpi_early_init(void);
 
 extern int acpi_nvs_register(__u64 start, __u64 size);
@@ -316,6 +393,17 @@
 extern int acpi_nvs_for_each_region(int (*func)(__u64, __u64, void *),
 				    void *data);
 
+const struct acpi_device_id *acpi_match_device(const struct acpi_device_id *ids,
+					       const struct device *dev);
+
+static inline bool acpi_driver_match_device(struct device *dev,
+					    const struct device_driver *drv)
+{
+	return !!acpi_match_device(drv->acpi_match_table, dev);
+}
+
+#define ACPI_PTR(_ptr)	(_ptr)
+
 #else	/* !CONFIG_ACPI */
 
 #define acpi_disabled 1
@@ -370,6 +458,22 @@
 	return 0;
 }
 
+struct acpi_device_id;
+
+static inline const struct acpi_device_id *acpi_match_device(
+	const struct acpi_device_id *ids, const struct device *dev)
+{
+	return NULL;
+}
+
+static inline bool acpi_driver_match_device(struct device *dev,
+					    const struct device_driver *drv)
+{
+	return false;
+}
+
+#define ACPI_PTR(_ptr)	(NULL)
+
 #endif	/* !CONFIG_ACPI */
 
 #ifdef CONFIG_ACPI
@@ -378,8 +482,101 @@
 
 acpi_status acpi_os_prepare_sleep(u8 sleep_state,
 				  u32 pm1a_control, u32 pm1b_control);
+#ifdef CONFIG_X86
+void arch_reserve_mem_area(acpi_physical_address addr, size_t size);
+#else
+static inline void arch_reserve_mem_area(acpi_physical_address addr,
+					  size_t size)
+{
+}
+#endif /* CONFIG_X86 */
 #else
 #define acpi_os_set_prepare_sleep(func, pm1a_ctrl, pm1b_ctrl) do { } while (0)
 #endif
 
+#if defined(CONFIG_ACPI) && defined(CONFIG_PM_RUNTIME)
+int acpi_dev_runtime_suspend(struct device *dev);
+int acpi_dev_runtime_resume(struct device *dev);
+int acpi_subsys_runtime_suspend(struct device *dev);
+int acpi_subsys_runtime_resume(struct device *dev);
+#else
+static inline int acpi_dev_runtime_suspend(struct device *dev) { return 0; }
+static inline int acpi_dev_runtime_resume(struct device *dev) { return 0; }
+static inline int acpi_subsys_runtime_suspend(struct device *dev) { return 0; }
+static inline int acpi_subsys_runtime_resume(struct device *dev) { return 0; }
+#endif
+
+#if defined(CONFIG_ACPI) && defined(CONFIG_PM_SLEEP)
+int acpi_dev_suspend_late(struct device *dev);
+int acpi_dev_resume_early(struct device *dev);
+int acpi_subsys_prepare(struct device *dev);
+int acpi_subsys_suspend_late(struct device *dev);
+int acpi_subsys_resume_early(struct device *dev);
+#else
+static inline int acpi_dev_suspend_late(struct device *dev) { return 0; }
+static inline int acpi_dev_resume_early(struct device *dev) { return 0; }
+static inline int acpi_subsys_prepare(struct device *dev) { return 0; }
+static inline int acpi_subsys_suspend_late(struct device *dev) { return 0; }
+static inline int acpi_subsys_resume_early(struct device *dev) { return 0; }
+#endif
+
+#if defined(CONFIG_ACPI) && defined(CONFIG_PM)
+struct acpi_device *acpi_dev_pm_get_node(struct device *dev);
+int acpi_dev_pm_attach(struct device *dev, bool power_on);
+void acpi_dev_pm_detach(struct device *dev, bool power_off);
+#else
+static inline struct acpi_device *acpi_dev_pm_get_node(struct device *dev)
+{
+	return NULL;
+}
+static inline int acpi_dev_pm_attach(struct device *dev, bool power_on)
+{
+	return -ENODEV;
+}
+static inline void acpi_dev_pm_detach(struct device *dev, bool power_off) {}
+#endif
+
+#ifdef CONFIG_ACPI
+__printf(3, 4)
+void acpi_handle_printk(const char *level, acpi_handle handle,
+			const char *fmt, ...);
+#else	/* !CONFIG_ACPI */
+static inline __printf(3, 4) void
+acpi_handle_printk(const char *level, void *handle, const char *fmt, ...) {}
+#endif	/* !CONFIG_ACPI */
+
+/*
+ * acpi_handle_<level>: Print message with ACPI prefix and object path
+ *
+ * These interfaces acquire the global namespace mutex to obtain an object
+ * path.  In interrupt context, it shows the object path as <n/a>.
+ */
+#define acpi_handle_emerg(handle, fmt, ...)				\
+	acpi_handle_printk(KERN_EMERG, handle, fmt, ##__VA_ARGS__)
+#define acpi_handle_alert(handle, fmt, ...)				\
+	acpi_handle_printk(KERN_ALERT, handle, fmt, ##__VA_ARGS__)
+#define acpi_handle_crit(handle, fmt, ...)				\
+	acpi_handle_printk(KERN_CRIT, handle, fmt, ##__VA_ARGS__)
+#define acpi_handle_err(handle, fmt, ...)				\
+	acpi_handle_printk(KERN_ERR, handle, fmt, ##__VA_ARGS__)
+#define acpi_handle_warn(handle, fmt, ...)				\
+	acpi_handle_printk(KERN_WARNING, handle, fmt, ##__VA_ARGS__)
+#define acpi_handle_notice(handle, fmt, ...)				\
+	acpi_handle_printk(KERN_NOTICE, handle, fmt, ##__VA_ARGS__)
+#define acpi_handle_info(handle, fmt, ...)				\
+	acpi_handle_printk(KERN_INFO, handle, fmt, ##__VA_ARGS__)
+
+/* REVISIT: Support CONFIG_DYNAMIC_DEBUG when necessary */
+#if defined(DEBUG) || defined(CONFIG_DYNAMIC_DEBUG)
+#define acpi_handle_debug(handle, fmt, ...)				\
+	acpi_handle_printk(KERN_DEBUG, handle, fmt, ##__VA_ARGS__)
+#else
+#define acpi_handle_debug(handle, fmt, ...)				\
+({									\
+	if (0)								\
+		acpi_handle_printk(KERN_DEBUG, handle, fmt, ##__VA_ARGS__); \
+	0;								\
+})
+#endif
+
 #endif	/*_LINUX_ACPI_H*/
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/include/linux/android_pmem.h linux-linaro-3.4-2012.05-1_cavium/include/linux/android_pmem.h
--- linux-linaro-3.4-2012.05-1_original/include/linux/android_pmem.h	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/include/linux/android_pmem.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,94 @@
+/* include/linux/android_pmem.h
+ *
+ * Copyright (C) 2007 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ *
+ */
+
+#ifndef _ANDROID_PMEM_H_
+#define _ANDROID_PMEM_H_
+
+#define PMEM_IOCTL_MAGIC 'p'
+#define PMEM_GET_PHYS           _IOW(PMEM_IOCTL_MAGIC, 1, unsigned int)
+#define PMEM_MAP                _IOW(PMEM_IOCTL_MAGIC, 2, unsigned int)
+#define PMEM_GET_SIZE           _IOW(PMEM_IOCTL_MAGIC, 3, unsigned int)
+#define PMEM_UNMAP              _IOW(PMEM_IOCTL_MAGIC, 4, unsigned int)
+/* This ioctl will allocate pmem space, backing the file, it will fail
+ * if the file already has an allocation, pass it the len as the argument
+ * to the ioctl */
+#define PMEM_ALLOCATE           _IOW(PMEM_IOCTL_MAGIC, 5, unsigned int)
+/* This will connect a one pmem file to another, pass the file that is already
+ * backed in memory as the argument to the ioctl
+ */
+#define PMEM_CONNECT            _IOW(PMEM_IOCTL_MAGIC, 6, unsigned int)
+/* Returns the total size of the pmem region it is sent to as a pmem_region
+ * struct (with offset set to 0).
+ */
+#define PMEM_GET_TOTAL_SIZE     _IOW(PMEM_IOCTL_MAGIC, 7, unsigned int)
+#define PMEM_CACHE_FLUSH        _IOW(PMEM_IOCTL_MAGIC, 8, unsigned int)
+
+
+
+struct android_pmem_platform_data
+{
+    const char* name;
+    /* starting physical address of memory region */
+    unsigned long start;
+    /* size of memory region */
+    unsigned long size;
+    /* set to indicate the region should not be managed with an allocator */
+    unsigned no_allocator;
+    /* set to indicate maps of this region should be cached, if a mix of
+     * cached and uncached is desired, set this and open the device with
+     * O_SYNC to get an uncached region */
+    unsigned cached;
+    /* The MSM7k has bits to enable a write buffer in the bus controller*/
+    unsigned buffered;
+};
+
+struct pmem_region {
+    unsigned long offset;
+    unsigned long len;
+};
+
+#ifdef CONFIG_ANDROID_PMEM
+int is_pmem_file(struct file *file);
+int get_pmem_file(int fd, unsigned long *start, unsigned long *vstart,
+        unsigned long *end, struct file **filp);
+int get_pmem_user_addr(struct file *file, unsigned long *start,
+        unsigned long *end);
+void put_pmem_file(struct file* file);
+void flush_pmem_file(struct file *file, unsigned long start, unsigned long len);
+int pmem_setup(struct android_pmem_platform_data *pdata,
+        long (*ioctl)(struct file *, unsigned int, unsigned long),
+        int (*release)(struct inode *, struct file *));
+int pmem_remap(struct pmem_region *region, struct file *file,
+        unsigned operation);
+
+#else
+static inline int is_pmem_file(struct file *file) { return 0; }
+static inline int get_pmem_file(int fd, unsigned long *start,
+        unsigned long *vstart, unsigned long *end,
+        struct file **filp) { return -ENOSYS; }
+static inline int get_pmem_user_addr(struct file *file, unsigned long *start,
+        unsigned long *end) { return -ENOSYS; }
+static inline void put_pmem_file(struct file* file) { return; }
+static inline void flush_pmem_file(struct file *file, unsigned long start,
+        unsigned long len) { return; }
+static inline int pmem_setup(struct android_pmem_platform_data *pdata,
+        long (*ioctl)(struct file *, unsigned int, unsigned long),
+        int (*release)(struct inode *, struct file *)) { return -ENOSYS; }
+
+static inline int pmem_remap(struct pmem_region *region, struct file *file,
+        unsigned operation) { return -ENOSYS; }
+#endif
+
+#endif //_ANDROID_PPP_H_
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/include/linux/idr.h linux-linaro-3.4-2012.05-1_cavium/include/linux/idr.h
--- linux-linaro-3.4-2012.05-1_original/include/linux/idr.h	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/include/linux/idr.h	2014-09-12 15:59:37.348052000 +0800
@@ -17,24 +17,13 @@
 #include <linux/init.h>
 #include <linux/rcupdate.h>
 
-#if BITS_PER_LONG == 32
-# define IDR_BITS 5
-# define IDR_FULL 0xfffffffful
-/* We can only use two of the bits in the top level because there is
-   only one possible bit in the top level (5 bits * 7 levels = 35
-   bits, but you only use 31 bits in the id). */
-# define TOP_LEVEL_FULL (IDR_FULL >> 30)
-#elif BITS_PER_LONG == 64
-# define IDR_BITS 6
-# define IDR_FULL 0xfffffffffffffffful
-/* We can only use two of the bits in the top level because there is
-   only one possible bit in the top level (6 bits * 6 levels = 36
-   bits, but you only use 31 bits in the id). */
-# define TOP_LEVEL_FULL (IDR_FULL >> 62)
-#else
-# error "BITS_PER_LONG is not 32 or 64"
-#endif
-
+/*
+ * We want shallower trees and thus more bits covered at each layer.  8
+ * bits gives us large enough first layer for most use cases and maximum
+ * tree depth of 4.  Each idr_layer is slightly larger than 2k on 64bit and
+ * 1k on 32bit.
+ */
+#define IDR_BITS 8
 #define IDR_SIZE (1 << IDR_BITS)
 #define IDR_MASK ((1 << IDR_BITS)-1)
 
@@ -42,44 +31,31 @@
 #define MAX_ID_BIT (1U << MAX_ID_SHIFT)
 #define MAX_ID_MASK (MAX_ID_BIT - 1)
 
-/* Leave the possibility of an incomplete final layer */
-#define MAX_LEVEL (MAX_ID_SHIFT + IDR_BITS - 1) / IDR_BITS
-
-/* Number of id_layer structs to leave in free list */
-#define IDR_FREE_MAX MAX_LEVEL + MAX_LEVEL
-
 struct idr_layer {
-	unsigned long		 bitmap; /* A zero bit means "space here" */
+	int			prefix;	/* the ID prefix of this idr_layer */
+	DECLARE_BITMAP(bitmap, IDR_SIZE); /* A zero bit means "space here" */
 	struct idr_layer __rcu	*ary[1<<IDR_BITS];
-	int			 count;	 /* When zero, we can release it */
-	int			 layer;	 /* distance from leaf */
-	struct rcu_head		 rcu_head;
+	int			count;	/* When zero, we can release it */
+	int			layer;	/* distance from leaf */
+	struct rcu_head		rcu_head;
 };
 
 struct idr {
-	struct idr_layer __rcu *top;
-	struct idr_layer *id_free;
-	int		  layers; /* only valid without concurrent changes */
-	int		  id_free_cnt;
-	spinlock_t	  lock;
+	struct idr_layer __rcu	*hint;	/* the last layer allocated from */
+	struct idr_layer __rcu	*top;
+	struct idr_layer	*id_free;
+	int			layers;	/* only valid w/o concurrent changes */
+	int			id_free_cnt;
+	int			cur;	/* current pos for cyclic allocation */
+	spinlock_t		lock;
 };
 
-#define IDR_INIT(name)						\
-{								\
-	.top		= NULL,					\
-	.id_free	= NULL,					\
-	.layers 	= 0,					\
-	.id_free_cnt	= 0,					\
-	.lock		= __SPIN_LOCK_UNLOCKED(name.lock),	\
+#define IDR_INIT(name)							\
+{									\
+	.lock			= __SPIN_LOCK_UNLOCKED(name.lock),	\
 }
 #define DEFINE_IDR(name)	struct idr name = IDR_INIT(name)
 
-/* Actions to be taken after a call to _idr_sub_alloc */
-#define IDR_NEED_TO_GROW -2
-#define IDR_NOMORE_SPACE -3
-
-#define _idr_rc_to_errno(rc) ((rc) == -1 ? -EAGAIN : -ENOSPC)
-
 /**
  * DOC: idr sync
  * idr synchronization (stolen from radix-tree.h)
@@ -101,19 +77,127 @@
  * This is what we export.
  */
 
-void *idr_find(struct idr *idp, int id);
-int idr_pre_get(struct idr *idp, gfp_t gfp_mask);
-int idr_get_new(struct idr *idp, void *ptr, int *id);
-int idr_get_new_above(struct idr *idp, void *ptr, int starting_id, int *id);
+void *idr_find_slowpath(struct idr *idp, int id);
+void idr_preload(gfp_t gfp_mask);
+int idr_alloc(struct idr *idp, void *ptr, int start, int end, gfp_t gfp_mask);
+int idr_alloc_cyclic(struct idr *idr, void *ptr, int start, int end, gfp_t gfp_mask);
 int idr_for_each(struct idr *idp,
 		 int (*fn)(int id, void *p, void *data), void *data);
 void *idr_get_next(struct idr *idp, int *nextid);
 void *idr_replace(struct idr *idp, void *ptr, int id);
 void idr_remove(struct idr *idp, int id);
-void idr_remove_all(struct idr *idp);
+void idr_free(struct idr *idp, int id);
 void idr_destroy(struct idr *idp);
 void idr_init(struct idr *idp);
 
+/**
+ * idr_preload_end - end preload section started with idr_preload()
+ *
+ * Each idr_preload() should be matched with an invocation of this
+ * function.  See idr_preload() for details.
+ */
+static inline void idr_preload_end(void)
+{
+	preempt_enable();
+}
+
+/**
+ * idr_find - return pointer for given id
+ * @idr: idr handle
+ * @id: lookup key
+ *
+ * Return the pointer given the id it has been registered with.  A %NULL
+ * return indicates that @id is not valid or you passed %NULL in
+ * idr_get_new().
+ *
+ * This function can be called under rcu_read_lock(), given that the leaf
+ * pointers lifetimes are correctly managed.
+ */
+static inline void *idr_find(struct idr *idr, int id)
+{
+	struct idr_layer *hint = rcu_dereference_raw(idr->hint);
+
+	if (hint && (id & ~IDR_MASK) == hint->prefix)
+		return rcu_dereference_raw(hint->ary[id & IDR_MASK]);
+
+	return idr_find_slowpath(idr, id);
+}
+
+/**
+ * idr_for_each_entry - iterate over an idr's elements of a given type
+ * @idp:     idr handle
+ * @entry:   the type * to use as cursor
+ * @id:      id entry's key
+ *
+ * @entry and @id do not need to be initialized before the loop, and
+ * after normal terminatinon @entry is left with the value NULL.  This
+ * is convenient for a "not found" value.
+ */
+#define idr_for_each_entry(idp, entry, id)			\
+	for (id = 0; ((entry) = idr_get_next(idp, &(id))) != NULL; ++id)
+
+/*
+ * Don't use the following functions.  These exist only to suppress
+ * deprecated warnings on EXPORT_SYMBOL()s.
+ */
+int __idr_pre_get(struct idr *idp, gfp_t gfp_mask);
+int __idr_get_new_above(struct idr *idp, void *ptr, int starting_id, int *id);
+void __idr_remove_all(struct idr *idp);
+
+/**
+ * idr_pre_get - reserve resources for idr allocation
+ * @idp:	idr handle
+ * @gfp_mask:	memory allocation flags
+ *
+ * Part of old alloc interface.  This is going away.  Use
+ * idr_preload[_end]() and idr_alloc() instead.
+ */
+static inline int __deprecated idr_pre_get(struct idr *idp, gfp_t gfp_mask)
+{
+	return __idr_pre_get(idp, gfp_mask);
+}
+
+/**
+ * idr_get_new_above - allocate new idr entry above or equal to a start id
+ * @idp: idr handle
+ * @ptr: pointer you want associated with the id
+ * @starting_id: id to start search at
+ * @id: pointer to the allocated handle
+ *
+ * Part of old alloc interface.  This is going away.  Use
+ * idr_preload[_end]() and idr_alloc() instead.
+ */
+static inline int __deprecated idr_get_new_above(struct idr *idp, void *ptr,
+						 int starting_id, int *id)
+{
+	return __idr_get_new_above(idp, ptr, starting_id, id);
+}
+
+/**
+ * idr_get_new - allocate new idr entry
+ * @idp: idr handle
+ * @ptr: pointer you want associated with the id
+ * @id: pointer to the allocated handle
+ *
+ * Part of old alloc interface.  This is going away.  Use
+ * idr_preload[_end]() and idr_alloc() instead.
+ */
+static inline int __deprecated idr_get_new(struct idr *idp, void *ptr, int *id)
+{
+	return __idr_get_new_above(idp, ptr, 0, id);
+}
+
+/**
+ * idr_remove_all - remove all ids from the given idr tree
+ * @idp: idr handle
+ *
+ * If you're trying to destroy @idp, calling idr_destroy() is enough.
+ * This is going away.  Don't use.
+ */
+static inline void __deprecated idr_remove_all(struct idr *idp)
+{
+	__idr_remove_all(idp);
+}
 
 /*
  * IDA - IDR based id allocator, use when translation from id to
@@ -136,12 +220,11 @@
 	struct ida_bitmap	*free_bitmap;
 };
 
-#define IDA_INIT(name)		{ .idr = IDR_INIT(name), .free_bitmap = NULL, }
+#define IDA_INIT(name)		{ .idr = IDR_INIT((name).idr), .free_bitmap = NULL, }
 #define DEFINE_IDA(name)	struct ida name = IDA_INIT(name)
 
 int ida_pre_get(struct ida *ida, gfp_t gfp_mask);
 int ida_get_new_above(struct ida *ida, int starting_id, int *p_id);
-int ida_get_new(struct ida *ida, int *p_id);
 void ida_remove(struct ida *ida, int id);
 void ida_destroy(struct ida *ida);
 void ida_init(struct ida *ida);
@@ -150,6 +233,18 @@
 		   gfp_t gfp_mask);
 void ida_simple_remove(struct ida *ida, unsigned int id);
 
+/**
+ * ida_get_new - allocate new ID
+ * @ida:	idr handle
+ * @p_id:	pointer to the allocated handle
+ *
+ * Simple wrapper around ida_get_new_above() w/ @starting_id of zero.
+ */
+static inline int ida_get_new(struct ida *ida, int *p_id)
+{
+	return ida_get_new_above(ida, 0, p_id);
+}
+
 void __init idr_init_cache(void);
 
 #endif /* __IDR_H__ */
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/include/linux/jiffies.h linux-linaro-3.4-2012.05-1_cavium/include/linux/jiffies.h
--- linux-linaro-3.4-2012.05-1_original/include/linux/jiffies.h	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/include/linux/jiffies.h	2014-07-29 17:28:38.819972000 +0800
@@ -160,11 +160,21 @@
 /* time_is_after_eq_jiffies(a) return true if a is after or equal to jiffies*/
 #define time_is_after_eq_jiffies(a) time_before_eq(jiffies, a)
 
+
+#ifdef CONFIG_PUREVU
+/* Unfortunately the ARM port at least with our toolchain seems to have a wrap bug,
+ * so we set INITIAL_JIFFIES to zero to maximize the time until wrap.
+ * For our current HZ=100 setting, the wrap will happen in:
+ *    (1<<32)/100/3600/24 =~ 497.1 days 
+ */
+#define INITIAL_JIFFIES ((unsigned long)(unsigned int) (0))
+#else
 /*
  * Have the 32 bit jiffies value wrap 5 minutes after boot
  * so jiffies wrap bugs show up earlier.
  */
 #define INITIAL_JIFFIES ((unsigned long)(unsigned int) (-300*HZ))
+#endif
 
 /*
  * Change timeval to jiffies, trying to avoid the
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/include/linux/mmc/card.h linux-linaro-3.4-2012.05-1_cavium/include/linux/mmc/card.h
--- linux-linaro-3.4-2012.05-1_original/include/linux/mmc/card.h	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/include/linux/mmc/card.h	2014-09-12 15:59:37.348052000 +0800
@@ -17,6 +17,7 @@
 struct mmc_cid {
 	unsigned int		manfid;
 	char			prod_name[8];
+	unsigned char		prv;
 	unsigned int		serial;
 	unsigned short		oemid;
 	unsigned short		year;
@@ -53,11 +54,19 @@
 	u8			part_config;
 	u8			cache_ctrl;
 	u8			rst_n_function;
+	u8			max_packed_writes;
+	u8			max_packed_reads;
+	u8			packed_event_en;
 	unsigned int		part_time;		/* Units: ms */
 	unsigned int		sa_timeout;		/* Units: 100ns */
 	unsigned int		generic_cmd6_time;	/* Units: 10ms */
 	unsigned int            power_off_longtime;     /* Units: ms */
+	u8			power_off_notification;	/* state */
 	unsigned int		hs_max_dtr;
+#define MMC_HIGH_26_MAX_DTR	26000000
+#define MMC_HIGH_52_MAX_DTR	52000000
+#define MMC_HIGH_DDR_MAX_DTR	52000000
+#define MMC_HS200_MAX_DTR	200000000
 	unsigned int		sectors;
 	unsigned int		card_type;
 	unsigned int		hc_erase_size;		/* In sectors */
@@ -72,11 +81,15 @@
 	bool			hpi_en;			/* HPI enablebit */
 	bool			hpi;			/* HPI support bit */
 	unsigned int		hpi_cmd;		/* cmd used as HPI */
+	bool			bkops;		/* background support bit */
+	bool			bkops_en;	/* background enable bit */
 	unsigned int            data_sector_size;       /* 512 bytes or 4KB */
 	unsigned int            data_tag_unit_size;     /* DATA TAG UNIT size */
 	unsigned int		boot_ro_lock;		/* ro lock support */
 	bool			boot_ro_lockable;
+	u8			raw_exception_status;	/* 54 */
 	u8			raw_partition_support;	/* 160 */
+	u8			raw_rpmb_size_mult;	/* 168 */
 	u8			raw_erased_mem_count;	/* 181 */
 	u8			raw_ext_csd_structure;	/* 194 */
 	u8			raw_card_type;		/* 196 */
@@ -89,6 +102,7 @@
 	u8			raw_sec_erase_mult;	/* 230 */
 	u8			raw_sec_feature_support;/* 231 */
 	u8			raw_trim_mult;		/* 232 */
+	u8			raw_bkops_status;	/* 246 */
 	u8			raw_sectors[4];		/* 212 - 4 bytes */
 
 	unsigned int            feature_support;
@@ -145,6 +159,7 @@
 #define SD_SET_CURRENT_LIMIT_400	1
 #define SD_SET_CURRENT_LIMIT_600	2
 #define SD_SET_CURRENT_LIMIT_800	3
+#define SD_SET_CURRENT_NO_CHANGE	(-1)
 
 #define SD_MAX_CURRENT_200	(1 << SD_SET_CURRENT_LIMIT_200)
 #define SD_MAX_CURRENT_400	(1 << SD_SET_CURRENT_LIMIT_400)
@@ -176,6 +191,18 @@
 
 #define SDIO_MAX_FUNCS		7
 
+enum mmc_blk_status {
+	MMC_BLK_SUCCESS = 0,
+	MMC_BLK_PARTIAL,
+	MMC_BLK_CMD_ERR,
+	MMC_BLK_RETRY,
+	MMC_BLK_ABORT,
+	MMC_BLK_DATA_ERR,
+	MMC_BLK_ECC_ERR,
+	MMC_BLK_NOMEDIUM,
+	MMC_BLK_NEW_REQUEST,
+};
+
 /* The number of MMC physical partitions.  These consist of:
  * boot partitions (2), general purpose partitions (4) in MMC v4.4.
  */
@@ -196,6 +223,7 @@
 #define MMC_BLK_DATA_AREA_MAIN	(1<<0)
 #define MMC_BLK_DATA_AREA_BOOT	(1<<1)
 #define MMC_BLK_DATA_AREA_GP	(1<<2)
+#define MMC_BLK_DATA_AREA_RPMB	(1<<3)
 };
 
 /*
@@ -220,7 +248,7 @@
 #define MMC_CARD_SDXC		(1<<6)		/* card is SDXC */
 #define MMC_CARD_REMOVED	(1<<7)		/* card has been removed */
 #define MMC_STATE_HIGHSPEED_200	(1<<8)		/* card is in HS200 mode */
-#define MMC_STATE_SLEEP		(1<<9)		/* card is in sleep state */
+#define MMC_STATE_DOING_BKOPS	(1<<10)		/* card is doing BKOPS */
 	unsigned int		quirks; 	/* card quirks */
 #define MMC_QUIRK_LENIENT_FN0	(1<<0)		/* allow SDIO FN0 writes outside of the VS CCCR range */
 #define MMC_QUIRK_BLKSZ_FOR_BYTE_MODE (1<<1)	/* use func->cur_blksize */
@@ -234,12 +262,8 @@
 #define MMC_QUIRK_BLK_NO_CMD23	(1<<7)		/* Avoid CMD23 for regular multiblock */
 #define MMC_QUIRK_BROKEN_BYTE_MODE_512 (1<<8)	/* Avoid sending 512 bytes in */
 #define MMC_QUIRK_LONG_READ_TIME (1<<9)		/* Data read time > CSD says */
+#define MMC_QUIRK_SEC_ERASE_TRIM_BROKEN (1<<10)	/* Skip secure for erase/trim */
 						/* byte mode */
-	unsigned int    poweroff_notify_state;	/* eMMC4.5 notify feature */
-#define MMC_NO_POWER_NOTIFICATION	0
-#define MMC_POWERED_ON			1
-#define MMC_POWEROFF_SHORT		2
-#define MMC_POWEROFF_LONG		3
 
 	unsigned int		erase_size;	/* erase size in sectors */
  	unsigned int		erase_shift;	/* if erase unit is power 2 */
@@ -287,6 +311,11 @@
 	card->nr_parts++;
 }
 
+static inline bool mmc_large_sector(struct mmc_card *card)
+{
+	return card->ext_csd.data_sector_size == 4096;
+}
+
 /*
  *  The world is not perfect and supplies us with broken mmc/sdio devices.
  *  For at least some of these bugs we need a work-around.
@@ -386,7 +415,7 @@
 #define mmc_sd_card_uhs(c)	((c)->state & MMC_STATE_ULTRAHIGHSPEED)
 #define mmc_card_ext_capacity(c) ((c)->state & MMC_CARD_SDXC)
 #define mmc_card_removed(c)	((c) && ((c)->state & MMC_CARD_REMOVED))
-#define mmc_card_is_sleep(c)	((c)->state & MMC_STATE_SLEEP)
+#define mmc_card_doing_bkops(c)	((c)->state & MMC_STATE_DOING_BKOPS)
 
 #define mmc_card_set_present(c)	((c)->state |= MMC_STATE_PRESENT)
 #define mmc_card_set_readonly(c) ((c)->state |= MMC_STATE_READONLY)
@@ -398,9 +427,9 @@
 #define mmc_sd_card_set_uhs(c) ((c)->state |= MMC_STATE_ULTRAHIGHSPEED)
 #define mmc_card_set_ext_capacity(c) ((c)->state |= MMC_CARD_SDXC)
 #define mmc_card_set_removed(c) ((c)->state |= MMC_CARD_REMOVED)
-#define mmc_card_set_sleep(c)	((c)->state |= MMC_STATE_SLEEP)
+#define mmc_card_set_doing_bkops(c)	((c)->state |= MMC_STATE_DOING_BKOPS)
+#define mmc_card_clr_doing_bkops(c)	((c)->state &= ~MMC_STATE_DOING_BKOPS)
 
-#define mmc_card_clr_sleep(c)	((c)->state &= ~MMC_STATE_SLEEP)
 /*
  * Quirk add/remove for MMC products.
  */
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/include/linux/mmc/cd-gpio.h linux-linaro-3.4-2012.05-1_cavium/include/linux/mmc/cd-gpio.h
--- linux-linaro-3.4-2012.05-1_original/include/linux/mmc/cd-gpio.h	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/include/linux/mmc/cd-gpio.h	1970-01-01 08:00:00.000000000 +0800
@@ -1,18 +0,0 @@
-/*
- * Generic GPIO card-detect helper header
- *
- * Copyright (C) 2011, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
- *
- * 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 MMC_CD_GPIO_H
-#define MMC_CD_GPIO_H
-
-struct mmc_host;
-int mmc_cd_gpio_request(struct mmc_host *host, unsigned int gpio);
-void mmc_cd_gpio_free(struct mmc_host *host);
-
-#endif
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/include/linux/mmc/core.h linux-linaro-3.4-2012.05-1_cavium/include/linux/mmc/core.h
--- linux-linaro-3.4-2012.05-1_original/include/linux/mmc/core.h	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/include/linux/mmc/core.h	2014-09-12 15:59:37.348052000 +0800
@@ -18,6 +18,9 @@
 struct mmc_command {
 	u32			opcode;
 	u32			arg;
+#define MMC_CMD23_ARG_REL_WR	(1 << 31)
+#define MMC_CMD23_ARG_PACKED	((0 << 31) | (1 << 30))
+#define MMC_CMD23_ARG_TAG_REQ	(1 << 29)
 	u32			resp[4];
 	unsigned int		flags;		/* expected response type */
 #define MMC_RSP_PRESENT	(1 << 0)
@@ -120,6 +123,7 @@
 	s32			host_cookie;	/* host private data */
 };
 
+struct mmc_host;
 struct mmc_request {
 	struct mmc_command	*sbc;		/* SET_BLOCK_COUNT for multiblock */
 	struct mmc_command	*cmd;
@@ -128,12 +132,14 @@
 
 	struct completion	completion;
 	void			(*done)(struct mmc_request *);/* completion function */
+	struct mmc_host		*host;
 };
 
-struct mmc_host;
 struct mmc_card;
 struct mmc_async_req;
 
+extern int mmc_stop_bkops(struct mmc_card *);
+extern int mmc_read_bkops_status(struct mmc_card *);
 extern struct mmc_async_req *mmc_start_req(struct mmc_host *,
 					   struct mmc_async_req *, int *);
 extern int mmc_interrupt_hpi(struct mmc_card *);
@@ -142,7 +148,10 @@
 extern int mmc_app_cmd(struct mmc_host *, struct mmc_card *);
 extern int mmc_wait_for_app_cmd(struct mmc_host *, struct mmc_card *,
 	struct mmc_command *, int);
+extern void mmc_start_bkops(struct mmc_card *card, bool from_exception);
+extern int __mmc_switch(struct mmc_card *, u8, u8, u8, unsigned int, bool);
 extern int mmc_switch(struct mmc_card *, u8, u8, u8, unsigned int);
+extern int mmc_send_ext_csd(struct mmc_card *card, u8 *ext_csd);
 
 #define MMC_ERASE_ARG		0x00000000
 #define MMC_SECURE_ERASE_ARG	0x80000000
@@ -166,6 +175,8 @@
 extern unsigned int mmc_calc_max_discard(struct mmc_card *card);
 
 extern int mmc_set_blocklen(struct mmc_card *card, unsigned int blocklen);
+extern int mmc_set_blockcount(struct mmc_card *card, unsigned int blockcount,
+			      bool is_rel_write);
 extern int mmc_hw_reset(struct mmc_host *host);
 extern int mmc_hw_reset_check(struct mmc_host *host);
 extern int mmc_can_reset(struct mmc_card *card);
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/include/linux/mmc/dw_mmc.h linux-linaro-3.4-2012.05-1_cavium/include/linux/mmc/dw_mmc.h
--- linux-linaro-3.4-2012.05-1_original/include/linux/mmc/dw_mmc.h	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/include/linux/mmc/dw_mmc.h	2014-09-12 15:59:37.348052000 +0800
@@ -78,6 +78,10 @@
  * @data_offset: Set the offset of DATA register according to VERID.
  * @dev: Device associated with the MMC controller.
  * @pdata: Platform data associated with the MMC controller.
+ * @drv_data: Driver specific data for identified variant of the controller
+ * @priv: Implementation defined private data.
+ * @biu_clk: Pointer to bus interface unit clock instance.
+ * @ciu_clk: Pointer to card interface unit clock instance.
  * @slot: Slots sharing this MMC controller.
  * @fifo_depth: depth of FIFO.
  * @data_shift: log2 of FIFO item size.
@@ -125,6 +129,7 @@
 	struct mmc_request	*mrq;
 	struct mmc_command	*cmd;
 	struct mmc_data		*data;
+	struct workqueue_struct	*card_workqueue;
 
 	/* DMA interface members*/
 	int			use_dma;
@@ -132,7 +137,7 @@
 
 	dma_addr_t		sg_dma;
 	void			*sg_cpu;
-	struct dw_mci_dma_ops	*dma_ops;
+	const struct dw_mci_dma_ops	*dma_ops;
 #ifdef CONFIG_MMC_DW_IDMAC
 	unsigned int		ring_size;
 #else
@@ -155,8 +160,12 @@
 	u32			fifoth_val;
 	u16			verid;
 	u16			data_offset;
-	struct device		dev;
+	struct device		*dev;
 	struct dw_mci_board	*pdata;
+	const struct dw_mci_drv_data	*drv_data;
+	void			*priv;
+	struct clk		*biu_clk;
+	struct clk		*ciu_clk;
 	struct dw_mci_slot	*slot[MAX_MCI_SLOTS];
 
 	/* FIFO push and pull */
@@ -177,7 +186,7 @@
 
 	struct regulator	*vmmc;	/* Power regulator */
 	unsigned long		irq_flags; /* IRQ flags */
-	unsigned int		irq;
+	int			irq;
 };
 
 /* DMA ops for Internal/External DMAC interface */
@@ -201,6 +210,9 @@
 /* Unreliable card detection */
 #define DW_MCI_QUIRK_BROKEN_CARD_DETECTION	BIT(3)
 
+/* Slot level quirks */
+/* This slot has no write protect */
+#define DW_MCI_SLOT_QUIRK_NO_WRITE_PROTECT	BIT(0)
 
 struct dma_pdata;
 
@@ -217,10 +229,11 @@
 	u32 num_slots;
 
 	u32 quirks; /* Workaround / Quirk flags */
-	unsigned int bus_hz; /* Bus speed */
+	unsigned int bus_hz; /* Clock speed at the cclk_in pad */
 
-	unsigned int caps;	/* Capabilities */
-	unsigned int caps2;	/* More capabilities */
+	u32 caps;	/* Capabilities */
+	u32 caps2;	/* More capabilities */
+	u32 pm_caps;	/* PM capabilities */
 	/*
 	 * Override fifo depth. If 0, autodetect it from the FIFOTH register,
 	 * but note that this may not be reliable after a bootloader has used
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/include/linux/mmc/host.h linux-linaro-3.4-2012.05-1_cavium/include/linux/mmc/host.h
--- linux-linaro-3.4-2012.05-1_original/include/linux/mmc/host.h	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/include/linux/mmc/host.h	2014-09-12 15:59:37.348052000 +0800
@@ -11,10 +11,10 @@
 #define LINUX_MMC_HOST_H
 
 #include <linux/leds.h>
+#include <linux/mutex.h>
 #include <linux/sched.h>
 #include <linux/device.h>
 #include <linux/fault-inject.h>
-#include <linux/wakelock.h>
 
 #include <linux/mmc/core.h>
 #include <linux/mmc/pm.h>
@@ -53,12 +53,12 @@
 #define MMC_TIMING_LEGACY	0
 #define MMC_TIMING_MMC_HS	1
 #define MMC_TIMING_SD_HS	2
-#define MMC_TIMING_UHS_SDR12	MMC_TIMING_LEGACY
-#define MMC_TIMING_UHS_SDR25	MMC_TIMING_SD_HS
-#define MMC_TIMING_UHS_SDR50	3
-#define MMC_TIMING_UHS_SDR104	4
-#define MMC_TIMING_UHS_DDR50	5
-#define MMC_TIMING_MMC_HS200	6
+#define MMC_TIMING_UHS_SDR12	3
+#define MMC_TIMING_UHS_SDR25	4
+#define MMC_TIMING_UHS_SDR50	5
+#define MMC_TIMING_UHS_SDR104	6
+#define MMC_TIMING_UHS_DDR50	7
+#define MMC_TIMING_MMC_HS200	8
 
 #define MMC_SDR_MODE		0
 #define MMC_1_2V_DDR_MODE	1
@@ -131,11 +131,14 @@
 
 	int	(*start_signal_voltage_switch)(struct mmc_host *host, struct mmc_ios *ios);
 
+	/* Check if the card is pulling dat[0:3] low */
+	int	(*card_busy)(struct mmc_host *host);
+
 	/* The tuning command opcode value is different for SD and eMMC cards */
 	int	(*execute_tuning)(struct mmc_host *host, u32 opcode);
-	void	(*enable_preset_value)(struct mmc_host *host, bool enable);
 	int	(*select_drive_strength)(unsigned int max_dtr, int host_drv, int card_drv);
 	void	(*hw_reset)(struct mmc_host *host);
+	void	(*card_event)(struct mmc_host *host);
 };
 
 struct mmc_card;
@@ -151,11 +154,47 @@
 	int (*err_check) (struct mmc_card *, struct mmc_async_req *);
 };
 
-struct mmc_hotplug {
-	unsigned int irq;
+/**
+ * struct mmc_slot - MMC slot functions
+ *
+ * @cd_irq:		MMC/SD-card slot hotplug detection IRQ or -EINVAL
+ * @lock:		protect the @handler_priv pointer
+ * @handler_priv:	MMC/SD-card slot context
+ *
+ * Some MMC/SD host controllers implement slot-functions like card and
+ * write-protect detection natively. However, a large number of controllers
+ * leave these functions to the CPU. This struct provides a hook to attach
+ * such slot-function drivers.
+ */
+struct mmc_slot {
+	int cd_irq;
+	struct mutex lock;
 	void *handler_priv;
 };
 
+/**
+ * mmc_context_info - synchronization details for mmc context
+ * @is_done_rcv		wake up reason was done request
+ * @is_new_req		wake up reason was new request
+ * @is_waiting_last_req	mmc context waiting for single running request
+ * @wait		wait queue
+ * @lock		lock to protect data fields
+ */
+struct mmc_context_info {
+	bool			is_done_rcv;
+	bool			is_new_req;
+	bool			is_waiting_last_req;
+	wait_queue_head_t	wait;
+	spinlock_t		lock;
+};
+
+struct regulator;
+
+struct mmc_supply {
+	struct regulator *vmmc;		/* Card power supply */
+	struct regulator *vqmmc;	/* Optional Vccq supply */
+};
+
 struct mmc_host {
 	struct device		*parent;
 	struct device		class_dev;
@@ -169,6 +208,9 @@
 	u32			ocr_avail_sd;	/* SD-specific OCR */
 	u32			ocr_avail_mmc;	/* MMC-specific OCR */
 	struct notifier_block	pm_notify;
+	u32			max_current_330;
+	u32			max_current_300;
+	u32			max_current_180;
 
 #define MMC_VDD_165_195		0x00000080	/* VDD voltage 1.65 - 1.95 */
 #define MMC_VDD_20_21		0x00000100	/* VDD voltage 2.0 ~ 2.1 */
@@ -188,7 +230,7 @@
 #define MMC_VDD_34_35		0x00400000	/* VDD voltage 3.4 ~ 3.5 */
 #define MMC_VDD_35_36		0x00800000	/* VDD voltage 3.5 ~ 3.6 */
 
-	unsigned long		caps;		/* Host capabilities */
+	u32			caps;		/* Host capabilities */
 
 #define MMC_CAP_4_BIT_DATA	(1 << 0)	/* Can the host do 4 bit transfers */
 #define MMC_CAP_MMC_HIGHSPEED	(1 << 1)	/* Can do MMC high-speed timing */
@@ -212,20 +254,13 @@
 #define MMC_CAP_UHS_SDR50	(1 << 17)	/* Host supports UHS SDR50 mode */
 #define MMC_CAP_UHS_SDR104	(1 << 18)	/* Host supports UHS SDR104 mode */
 #define MMC_CAP_UHS_DDR50	(1 << 19)	/* Host supports UHS DDR50 mode */
-#define MMC_CAP_SET_XPC_330	(1 << 20)	/* Host supports >150mA current at 3.3V */
-#define MMC_CAP_SET_XPC_300	(1 << 21)	/* Host supports >150mA current at 3.0V */
-#define MMC_CAP_SET_XPC_180	(1 << 22)	/* Host supports >150mA current at 1.8V */
 #define MMC_CAP_DRIVER_TYPE_A	(1 << 23)	/* Host supports Driver Type A */
 #define MMC_CAP_DRIVER_TYPE_C	(1 << 24)	/* Host supports Driver Type C */
 #define MMC_CAP_DRIVER_TYPE_D	(1 << 25)	/* Host supports Driver Type D */
-#define MMC_CAP_MAX_CURRENT_200	(1 << 26)	/* Host max current limit is 200mA */
-#define MMC_CAP_MAX_CURRENT_400	(1 << 27)	/* Host max current limit is 400mA */
-#define MMC_CAP_MAX_CURRENT_600	(1 << 28)	/* Host max current limit is 600mA */
-#define MMC_CAP_MAX_CURRENT_800	(1 << 29)	/* Host max current limit is 800mA */
 #define MMC_CAP_CMD23		(1 << 30)	/* CMD23 supported. */
 #define MMC_CAP_HW_RESET	(1 << 31)	/* Hardware reset */
 
-	unsigned int		caps2;		/* More host capabilities */
+	u32			caps2;		/* More host capabilities */
 
 #define MMC_CAP2_BOOTPART_NOACC	(1 << 0)	/* Boot partition no access */
 #define MMC_CAP2_CACHE_CTRL	(1 << 1)	/* Allow cache control */
@@ -239,12 +274,15 @@
 #define MMC_CAP2_BROKEN_VOLTAGE	(1 << 7)	/* Use the broken voltage */
 #define MMC_CAP2_DETECT_ON_ERR	(1 << 8)	/* On I/O err check card removal */
 #define MMC_CAP2_HC_ERASE_SZ	(1 << 9)	/* High-capacity erase size */
+#define MMC_CAP2_CD_ACTIVE_HIGH	(1 << 10)	/* Card-detect signal active high */
+#define MMC_CAP2_RO_ACTIVE_HIGH	(1 << 11)	/* Write-protect signal active high */
+#define MMC_CAP2_PACKED_RD	(1 << 12)	/* Allow packed read */
+#define MMC_CAP2_PACKED_WR	(1 << 13)	/* Allow packed write */
+#define MMC_CAP2_PACKED_CMD	(MMC_CAP2_PACKED_RD | \
+				 MMC_CAP2_PACKED_WR)
+#define MMC_CAP2_NO_PRESCAN_POWERUP (1 << 14)	/* Don't power up before scan */
 
 	mmc_pm_flag_t		pm_caps;	/* supported pm features */
-	unsigned int        power_notify_type;
-#define MMC_HOST_PW_NOTIFY_NONE		0
-#define MMC_HOST_PW_NOTIFY_SHORT	1
-#define MMC_HOST_PW_NOTIFY_LONG		2
 
 #ifdef CONFIG_MMC_CLKGATE
 	int			clk_requests;	/* internal reference counter */
@@ -260,6 +298,8 @@
 
 	/* host specific block data */
 	unsigned int		max_seg_size;	/* see blk_queue_max_segment_size */
+    unsigned short      max_hw_segs;    /* see blk_queue_max_hw_segments */
+    unsigned short      max_phys_segs;  /* see blk_queue_max_phys_segments */
 	unsigned short		max_segs;	/* see blk_queue_max_segments */
 	unsigned short		unused;
 	unsigned int		max_req_size;	/* maximum number of bytes in one req */
@@ -282,6 +322,7 @@
 #endif
 
 	int			rescan_disable;	/* disable card detection */
+	int			rescan_entered;	/* used with nonremovable devices */
 
 	struct mmc_card		*card;		/* device attached to this host */
 
@@ -290,34 +331,30 @@
 	int			claim_cnt;	/* "claim" nesting count */
 
 	struct delayed_work	detect;
-	struct wake_lock	detect_wake_lock;
 	int			detect_change;	/* card detect flag */
-	struct mmc_hotplug	hotplug;
+	struct mmc_slot		slot;
 
 	const struct mmc_bus_ops *bus_ops;	/* current bus driver */
 	unsigned int		bus_refs;	/* reference counter */
 
-	unsigned int		bus_resume_flags;
-#define MMC_BUSRESUME_MANUAL_RESUME	(1 << 0)
-#define MMC_BUSRESUME_NEEDS_RESUME	(1 << 1)
-
 	unsigned int		sdio_irqs;
 	struct task_struct	*sdio_irq_thread;
+	bool			sdio_irq_pending;
 	atomic_t		sdio_irq_thread_abort;
 
 	mmc_pm_flag_t		pm_flags;	/* requested pm features */
 
-#ifdef CONFIG_LEDS_TRIGGERS
 	struct led_trigger	*led;		/* activity led */
-#endif
 
 #ifdef CONFIG_REGULATOR
 	bool			regulator_enabled; /* regulator state */
 #endif
+	struct mmc_supply	supply;
 
 	struct dentry		*debugfs_root;
 
 	struct mmc_async_req	*areq;		/* active async req */
+	struct mmc_context_info	context_info;	/* async synchronization info */
 
 #ifdef CONFIG_FAIL_MMC_REQUEST
 	struct fault_attr	fail_mmc_request;
@@ -325,30 +362,16 @@
 
 	unsigned int		actual_clock;	/* Actual HC clock rate */
 
-#ifdef CONFIG_MMC_EMBEDDED_SDIO
-	struct {
-		struct sdio_cis			*cis;
-		struct sdio_cccr		*cccr;
-		struct sdio_embedded_func	*funcs;
-		int				num_funcs;
-	} embedded_sdio_data;
-#endif
+	unsigned int		slotno;	/* used for sdio acpi binding */
 
 	unsigned long		private[0] ____cacheline_aligned;
 };
 
-extern struct mmc_host *mmc_alloc_host(int extra, struct device *);
-extern int mmc_add_host(struct mmc_host *);
-extern void mmc_remove_host(struct mmc_host *);
-extern void mmc_free_host(struct mmc_host *);
-
-#ifdef CONFIG_MMC_EMBEDDED_SDIO
-extern void mmc_set_embedded_sdio_data(struct mmc_host *host,
-				       struct sdio_cis *cis,
-				       struct sdio_cccr *cccr,
-				       struct sdio_embedded_func *funcs,
-				       int num_funcs);
-#endif
+struct mmc_host *mmc_alloc_host(int extra, struct device *);
+int mmc_add_host(struct mmc_host *);
+void mmc_remove_host(struct mmc_host *);
+void mmc_free_host(struct mmc_host *);
+void mmc_of_parse(struct mmc_host *host);
 
 static inline void *mmc_priv(struct mmc_host *host)
 {
@@ -360,43 +383,31 @@
 #define mmc_dev(x)	((x)->parent)
 #define mmc_classdev(x)	(&(x)->class_dev)
 #define mmc_hostname(x)	(dev_name(&(x)->class_dev))
-#define mmc_bus_needs_resume(host) ((host)->bus_resume_flags & MMC_BUSRESUME_NEEDS_RESUME)
-#define mmc_bus_manual_resume(host) ((host)->bus_resume_flags & MMC_BUSRESUME_MANUAL_RESUME)
-
-static inline void mmc_set_bus_resume_policy(struct mmc_host *host, int manual)
-{
-	if (manual)
-		host->bus_resume_flags |= MMC_BUSRESUME_MANUAL_RESUME;
-	else
-		host->bus_resume_flags &= ~MMC_BUSRESUME_MANUAL_RESUME;
-}
 
-extern int mmc_resume_bus(struct mmc_host *host);
+int mmc_suspend_host(struct mmc_host *);
+int mmc_resume_host(struct mmc_host *);
 
-extern int mmc_suspend_host(struct mmc_host *);
-extern int mmc_resume_host(struct mmc_host *);
+int mmc_power_save_host(struct mmc_host *host);
+int mmc_power_restore_host(struct mmc_host *host);
 
-extern int mmc_power_save_host(struct mmc_host *host);
-extern int mmc_power_restore_host(struct mmc_host *host);
+void mmc_detect_change(struct mmc_host *, unsigned long delay);
+void mmc_request_done(struct mmc_host *, struct mmc_request *);
 
-extern void mmc_detect_change(struct mmc_host *, unsigned long delay);
-extern void mmc_request_done(struct mmc_host *, struct mmc_request *);
-
-extern int mmc_cache_ctrl(struct mmc_host *, u8);
+int mmc_cache_ctrl(struct mmc_host *, u8);
 
 static inline void mmc_signal_sdio_irq(struct mmc_host *host)
 {
 	host->ops->enable_sdio_irq(host, 0);
+	host->sdio_irq_pending = true;
 	wake_up_process(host->sdio_irq_thread);
 }
 
-struct regulator;
-
 #ifdef CONFIG_REGULATOR
 int mmc_regulator_get_ocrmask(struct regulator *supply);
 int mmc_regulator_set_ocr(struct mmc_host *mmc,
 			struct regulator *supply,
 			unsigned short vdd_bit);
+int mmc_regulator_get_supply(struct mmc_host *mmc);
 #else
 static inline int mmc_regulator_get_ocrmask(struct regulator *supply)
 {
@@ -409,6 +420,11 @@
 {
 	return 0;
 }
+
+static inline int mmc_regulator_get_supply(struct mmc_host *mmc)
+{
+	return 0;
+}
 #endif
 
 int mmc_card_awake(struct mmc_host *host);
@@ -445,6 +461,19 @@
 	return !(host->caps2 & MMC_CAP2_BOOTPART_NOACC);
 }
 
+static inline int mmc_host_uhs(struct mmc_host *host)
+{
+	return host->caps &
+		(MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 |
+		 MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104 |
+		 MMC_CAP_UHS_DDR50);
+}
+
+static inline int mmc_host_packed_wr(struct mmc_host *host)
+{
+	return host->caps2 & MMC_CAP2_PACKED_WR;
+}
+
 #ifdef CONFIG_MMC_CLKGATE
 void mmc_host_clk_hold(struct mmc_host *host);
 void mmc_host_clk_release(struct mmc_host *host);
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/include/linux/mmc/mmc.h linux-linaro-3.4-2012.05-1_cavium/include/linux/mmc/mmc.h
--- linux-linaro-3.4-2012.05-1_original/include/linux/mmc/mmc.h	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/include/linux/mmc/mmc.h	2014-09-12 15:59:37.348052000 +0800
@@ -139,6 +139,7 @@
 #define R1_CURRENT_STATE(x)	((x & 0x00001E00) >> 9)	/* sx, b (4 bits) */
 #define R1_READY_FOR_DATA	(1 << 8)	/* sx, a */
 #define R1_SWITCH_ERROR		(1 << 7)	/* sx, c */
+#define R1_EXCEPTION_EVENT	(1 << 6)	/* sr, a */
 #define R1_APP_CMD		(1 << 5)	/* sr, c */
 
 #define R1_STATE_IDLE	0
@@ -274,14 +275,21 @@
 #define EXT_CSD_FLUSH_CACHE		32      /* W */
 #define EXT_CSD_CACHE_CTRL		33      /* R/W */
 #define EXT_CSD_POWER_OFF_NOTIFICATION	34	/* R/W */
+#define EXT_CSD_PACKED_FAILURE_INDEX	35	/* RO */
+#define EXT_CSD_PACKED_CMD_STATUS	36	/* RO */
+#define EXT_CSD_EXP_EVENTS_STATUS	54	/* RO, 2 bytes */
+#define EXT_CSD_EXP_EVENTS_CTRL		56	/* R/W, 2 bytes */
 #define EXT_CSD_DATA_SECTOR_SIZE	61	/* R */
 #define EXT_CSD_GP_SIZE_MULT		143	/* R/W */
 #define EXT_CSD_PARTITION_ATTRIBUTE	156	/* R/W */
 #define EXT_CSD_PARTITION_SUPPORT	160	/* RO */
 #define EXT_CSD_HPI_MGMT		161	/* R/W */
 #define EXT_CSD_RST_N_FUNCTION		162	/* R/W */
+#define EXT_CSD_BKOPS_EN		163	/* R/W */
+#define EXT_CSD_BKOPS_START		164	/* W */
 #define EXT_CSD_SANITIZE_START		165     /* W */
 #define EXT_CSD_WR_REL_PARAM		166	/* RO */
+#define EXT_CSD_RPMB_MULT		168	/* RO */
 #define EXT_CSD_BOOT_WP			173	/* R/W */
 #define EXT_CSD_ERASE_GROUP_DEF		175	/* R/W */
 #define EXT_CSD_PART_CONFIG		179	/* R/W */
@@ -313,11 +321,15 @@
 #define EXT_CSD_PWR_CL_200_360		237	/* RO */
 #define EXT_CSD_PWR_CL_DDR_52_195	238	/* RO */
 #define EXT_CSD_PWR_CL_DDR_52_360	239	/* RO */
+#define EXT_CSD_BKOPS_STATUS		246	/* RO */
 #define EXT_CSD_POWER_OFF_LONG_TIME	247	/* RO */
 #define EXT_CSD_GENERIC_CMD6_TIME	248	/* RO */
 #define EXT_CSD_CACHE_SIZE		249	/* RO, 4 bytes */
 #define EXT_CSD_TAG_UNIT_SIZE		498	/* RO */
 #define EXT_CSD_DATA_TAG_SUPPORT	499	/* RO */
+#define EXT_CSD_MAX_PACKED_WRITES	500	/* RO */
+#define EXT_CSD_MAX_PACKED_READS	501	/* RO */
+#define EXT_CSD_BKOPS_SUPPORT		502	/* RO */
 #define EXT_CSD_HPI_FEATURES		503	/* RO */
 
 /*
@@ -333,6 +345,7 @@
 
 #define EXT_CSD_PART_CONFIG_ACC_MASK	(0x7)
 #define EXT_CSD_PART_CONFIG_ACC_BOOT0	(0x1)
+#define EXT_CSD_PART_CONFIG_ACC_RPMB	(0x3)
 #define EXT_CSD_PART_CONFIG_ACC_GP0	(0x4)
 
 #define EXT_CSD_PART_SUPPORT_PART_EN	(0x1)
@@ -354,66 +367,6 @@
 #define EXT_CSD_CARD_TYPE_SDR_1_2V	(1<<5)	/* Card can run at 200MHz */
 						/* SDR mode @1.2V I/O */
 
-#define EXT_CSD_CARD_TYPE_SDR_200	(EXT_CSD_CARD_TYPE_SDR_1_8V | \
-					 EXT_CSD_CARD_TYPE_SDR_1_2V)
-
-#define EXT_CSD_CARD_TYPE_SDR_ALL	(EXT_CSD_CARD_TYPE_SDR_200 | \
-					 EXT_CSD_CARD_TYPE_52 | \
-					 EXT_CSD_CARD_TYPE_26)
-
-#define	EXT_CSD_CARD_TYPE_SDR_1_2V_ALL	(EXT_CSD_CARD_TYPE_SDR_1_2V | \
-					 EXT_CSD_CARD_TYPE_52 | \
-					 EXT_CSD_CARD_TYPE_26)
-
-#define	EXT_CSD_CARD_TYPE_SDR_1_8V_ALL	(EXT_CSD_CARD_TYPE_SDR_1_8V | \
-					 EXT_CSD_CARD_TYPE_52 | \
-					 EXT_CSD_CARD_TYPE_26)
-
-#define EXT_CSD_CARD_TYPE_SDR_1_2V_DDR_1_8V	(EXT_CSD_CARD_TYPE_SDR_1_2V | \
-						 EXT_CSD_CARD_TYPE_DDR_1_8V | \
-						 EXT_CSD_CARD_TYPE_52 | \
-						 EXT_CSD_CARD_TYPE_26)
-
-#define EXT_CSD_CARD_TYPE_SDR_1_8V_DDR_1_8V	(EXT_CSD_CARD_TYPE_SDR_1_8V | \
-						 EXT_CSD_CARD_TYPE_DDR_1_8V | \
-						 EXT_CSD_CARD_TYPE_52 | \
-						 EXT_CSD_CARD_TYPE_26)
-
-#define EXT_CSD_CARD_TYPE_SDR_1_2V_DDR_1_2V	(EXT_CSD_CARD_TYPE_SDR_1_2V | \
-						 EXT_CSD_CARD_TYPE_DDR_1_2V | \
-						 EXT_CSD_CARD_TYPE_52 | \
-						 EXT_CSD_CARD_TYPE_26)
-
-#define EXT_CSD_CARD_TYPE_SDR_1_8V_DDR_1_2V	(EXT_CSD_CARD_TYPE_SDR_1_8V | \
-						 EXT_CSD_CARD_TYPE_DDR_1_2V | \
-						 EXT_CSD_CARD_TYPE_52 | \
-						 EXT_CSD_CARD_TYPE_26)
-
-#define EXT_CSD_CARD_TYPE_SDR_1_2V_DDR_52	(EXT_CSD_CARD_TYPE_SDR_1_2V | \
-						 EXT_CSD_CARD_TYPE_DDR_52 | \
-						 EXT_CSD_CARD_TYPE_52 | \
-						 EXT_CSD_CARD_TYPE_26)
-
-#define EXT_CSD_CARD_TYPE_SDR_1_8V_DDR_52	(EXT_CSD_CARD_TYPE_SDR_1_8V | \
-						 EXT_CSD_CARD_TYPE_DDR_52 | \
-						 EXT_CSD_CARD_TYPE_52 | \
-						 EXT_CSD_CARD_TYPE_26)
-
-#define EXT_CSD_CARD_TYPE_SDR_ALL_DDR_1_8V	(EXT_CSD_CARD_TYPE_SDR_200 | \
-						 EXT_CSD_CARD_TYPE_DDR_1_8V | \
-						 EXT_CSD_CARD_TYPE_52 | \
-						 EXT_CSD_CARD_TYPE_26)
-
-#define EXT_CSD_CARD_TYPE_SDR_ALL_DDR_1_2V	(EXT_CSD_CARD_TYPE_SDR_200 | \
-						 EXT_CSD_CARD_TYPE_DDR_1_2V | \
-						 EXT_CSD_CARD_TYPE_52 | \
-						 EXT_CSD_CARD_TYPE_26)
-
-#define EXT_CSD_CARD_TYPE_SDR_ALL_DDR_52	(EXT_CSD_CARD_TYPE_SDR_200 | \
-						 EXT_CSD_CARD_TYPE_DDR_52 | \
-						 EXT_CSD_CARD_TYPE_52 | \
-						 EXT_CSD_CARD_TYPE_26)
-
 #define EXT_CSD_BUS_WIDTH_1	0	/* Card is in 1 bit mode */
 #define EXT_CSD_BUS_WIDTH_4	1	/* Card is in 4 bit mode */
 #define EXT_CSD_BUS_WIDTH_8	2	/* Card is in 8 bit mode */
@@ -437,6 +390,25 @@
 #define EXT_CSD_PWR_CL_4BIT_MASK	0x0F	/* 8 bit PWR CLS */
 #define EXT_CSD_PWR_CL_8BIT_SHIFT	4
 #define EXT_CSD_PWR_CL_4BIT_SHIFT	0
+
+#define EXT_CSD_PACKED_EVENT_EN	BIT(3)
+
+/*
+ * EXCEPTION_EVENT_STATUS field
+ */
+#define EXT_CSD_URGENT_BKOPS		BIT(0)
+#define EXT_CSD_DYNCAP_NEEDED		BIT(1)
+#define EXT_CSD_SYSPOOL_EXHAUSTED	BIT(2)
+#define EXT_CSD_PACKED_FAILURE		BIT(3)
+
+#define EXT_CSD_PACKED_GENERIC_ERROR	BIT(0)
+#define EXT_CSD_PACKED_INDEXED_ERROR	BIT(1)
+
+/*
+ * BKOPS status level
+ */
+#define EXT_CSD_BKOPS_LEVEL_2		0x2
+
 /*
  * MMC_SWITCH access modes
  */
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/include/linux/mmc/pm.h linux-linaro-3.4-2012.05-1_cavium/include/linux/mmc/pm.h
--- linux-linaro-3.4-2012.05-1_original/include/linux/mmc/pm.h	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/include/linux/mmc/pm.h	2014-09-12 15:59:37.348052000 +0800
@@ -26,6 +26,5 @@
 
 #define MMC_PM_KEEP_POWER	(1 << 0)	/* preserve card power during suspend */
 #define MMC_PM_WAKE_SDIO_IRQ	(1 << 1)	/* wake up host system on SDIO IRQ assertion */
-#define MMC_PM_IGNORE_PM_NOTIFY	(1 << 2)	/* ignore mmc pm notify */
 
 #endif /* LINUX_MMC_PM_H */
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/include/linux/mmc/sdhci.h linux-linaro-3.4-2012.05-1_cavium/include/linux/mmc/sdhci.h
--- linux-linaro-3.4-2012.05-1_original/include/linux/mmc/sdhci.h	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/include/linux/mmc/sdhci.h	2014-09-12 15:59:37.348052000 +0800
@@ -91,13 +91,18 @@
 	unsigned int quirks2;	/* More deviations from spec. */
 
 #define SDHCI_QUIRK2_HOST_OFF_CARD_ON			(1<<0)
+#define SDHCI_QUIRK2_HOST_NO_CMD23			(1<<1)
+/* The system physically doesn't support 1.8v, even if the host does */
+#define SDHCI_QUIRK2_NO_1_8_V				(1<<2)
+#define SDHCI_QUIRK2_PRESET_VALUE_BROKEN		(1<<3)
 
 	int irq;		/* Device IRQ */
 	void __iomem *ioaddr;	/* Mapped address */
 
 	const struct sdhci_ops *ops;	/* Low level hw interface */
 
-	struct regulator *vmmc;	/* Power regulator */
+	struct regulator *vmmc;		/* Power regulator (vmmc) */
+	struct regulator *vqmmc;	/* Signaling regulator (vccq) */
 
 	/* Internal data */
 	struct mmc_host *mmc;	/* MMC structure */
@@ -122,6 +127,7 @@
 #define SDHCI_PV_ENABLED	(1<<8)	/* Preset value enabled */
 #define SDHCI_SDIO_IRQ_ENABLED	(1<<9)	/* SDIO irq enabled */
 #define SDHCI_HS200_NEEDS_TUNING (1<<10)	/* HS200 needs tuning */
+#define SDHCI_USING_RETUNING_TIMER (1<<11)	/* Host is using a retuning timer for the card */
 
 	unsigned int version;	/* SDHCI spec. version */
 
@@ -155,7 +161,8 @@
 
 	struct timer_list timer;	/* Timer for timeouts */
 
-	unsigned int caps;	/* Alternative capabilities */
+	u32 caps;		/* Alternative CAPABILITY_0 */
+	u32 caps1;		/* Alternative CAPABILITY_1 */
 
 	unsigned int            ocr_avail_sdio;	/* OCR bit masks */
 	unsigned int            ocr_avail_sd;
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/include/linux/mmc/sdhci-spear.h linux-linaro-3.4-2012.05-1_cavium/include/linux/mmc/sdhci-spear.h
--- linux-linaro-3.4-2012.05-1_original/include/linux/mmc/sdhci-spear.h	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/include/linux/mmc/sdhci-spear.h	2014-09-12 15:59:37.348052000 +0800
@@ -4,7 +4,7 @@
  * SDHCI declarations specific to ST SPEAr platform
  *
  * Copyright (C) 2010 ST Microelectronics
- * Viresh Kumar<viresh.kumar@st.com>
+ * Viresh Kumar <viresh.linux@gmail.com>
  *
  * This file is licensed under the terms of the GNU General Public
  * License version 2. This program is licensed "as is" without any
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/include/linux/mmc/sdio_func.h linux-linaro-3.4-2012.05-1_cavium/include/linux/mmc/sdio_func.h
--- linux-linaro-3.4-2012.05-1_original/include/linux/mmc/sdio_func.h	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/include/linux/mmc/sdio_func.h	2014-09-12 15:59:37.348052000 +0800
@@ -23,14 +23,6 @@
 typedef void (sdio_irq_handler_t)(struct sdio_func *);
 
 /*
- * Structure used to hold embedded SDIO device data from platform layer
- */
-struct sdio_embedded_func {
-	uint8_t f_class;
-	uint32_t f_maxblksize;
-};
-
-/*
  * SDIO function CIS tuple (unknown to the core)
  */
 struct sdio_func_tuple {
@@ -138,8 +130,6 @@
 extern unsigned int sdio_align_size(struct sdio_func *func, unsigned int sz);
 
 extern u8 sdio_readb(struct sdio_func *func, unsigned int addr, int *err_ret);
-extern u8 sdio_readb_ext(struct sdio_func *func, unsigned int addr, int *err_ret,
-	unsigned in);
 extern u16 sdio_readw(struct sdio_func *func, unsigned int addr, int *err_ret);
 extern u32 sdio_readl(struct sdio_func *func, unsigned int addr, int *err_ret);
 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/include/linux/mmc/sdio.h linux-linaro-3.4-2012.05-1_cavium/include/linux/mmc/sdio.h
--- linux-linaro-3.4-2012.05-1_original/include/linux/mmc/sdio.h	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/include/linux/mmc/sdio.h	2014-09-12 15:59:37.348052000 +0800
@@ -98,7 +98,9 @@
 
 #define SDIO_CCCR_IF		0x07	/* bus interface controls */
 
+#define  SDIO_BUS_WIDTH_MASK	0x03	/* data bus width setting */
 #define  SDIO_BUS_WIDTH_1BIT	0x00
+#define  SDIO_BUS_WIDTH_RESERVED 0x01
 #define  SDIO_BUS_WIDTH_4BIT	0x02
 #define  SDIO_BUS_ECSI		0x20	/* Enable continuous SPI interrupt */
 #define  SDIO_BUS_SCSI		0x40	/* Support continuous SPI interrupt */
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/include/linux/mmc/sh_mmcif.h linux-linaro-3.4-2012.05-1_cavium/include/linux/mmc/sh_mmcif.h
--- linux-linaro-3.4-2012.05-1_original/include/linux/mmc/sh_mmcif.h	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/include/linux/mmc/sh_mmcif.h	2014-09-12 15:59:37.348052000 +0800
@@ -32,18 +32,14 @@
  * 1111 : Peripheral clock (sup_pclk set '1')
  */
 
-struct sh_mmcif_dma {
-	struct sh_dmae_slave chan_priv_tx;
-	struct sh_dmae_slave chan_priv_rx;
-};
-
 struct sh_mmcif_plat_data {
 	void (*set_pwr)(struct platform_device *pdev, int state);
 	void (*down_pwr)(struct platform_device *pdev);
 	int (*get_cd)(struct platform_device *pdef);
-	struct sh_mmcif_dma	*dma;		/* Deprecated. Instead */
-	unsigned int		slave_id_tx;	/* use embedded slave_id_[tr]x */
+	unsigned int		slave_id_tx;	/* embedded slave_id_[tr]x */
 	unsigned int		slave_id_rx;
+	bool			use_cd_gpio : 1;
+	unsigned int		cd_gpio;
 	u8			sup_pclk;	/* 1 :SH7757, 0: SH7724/SH7372 */
 	unsigned long		caps;
 	u32			ocr;
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/include/linux/mmc/sh_mobile_sdhi.h linux-linaro-3.4-2012.05-1_cavium/include/linux/mmc/sh_mobile_sdhi.h
--- linux-linaro-3.4-2012.05-1_original/include/linux/mmc/sh_mobile_sdhi.h	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/include/linux/mmc/sh_mobile_sdhi.h	2014-09-12 15:59:37.348052000 +0800
@@ -4,7 +4,6 @@
 #include <linux/types.h>
 
 struct platform_device;
-struct tmio_mmc_data;
 
 #define SH_MOBILE_SDHI_IRQ_CARD_DETECT	"card_detect"
 #define SH_MOBILE_SDHI_IRQ_SDCARD	"sdcard"
@@ -23,9 +22,9 @@
 	int dma_slave_rx;
 	unsigned long tmio_flags;
 	unsigned long tmio_caps;
+	unsigned long tmio_caps2;
 	u32 tmio_ocr_mask;	/* available MMC voltages */
 	unsigned int cd_gpio;
-	struct tmio_mmc_data *pdata;
 	void (*set_pwr)(struct platform_device *pdev, int state);
 	int (*get_cd)(struct platform_device *pdev);
 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/include/linux/mmc/slot-gpio.h linux-linaro-3.4-2012.05-1_cavium/include/linux/mmc/slot-gpio.h
--- linux-linaro-3.4-2012.05-1_original/include/linux/mmc/slot-gpio.h	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/include/linux/mmc/slot-gpio.h	2014-09-12 15:59:37.348052000 +0800
@@ -0,0 +1,24 @@
+/*
+ * Generic GPIO card-detect helper header
+ *
+ * Copyright (C) 2011, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+ *
+ * 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 MMC_SLOT_GPIO_H
+#define MMC_SLOT_GPIO_H
+
+struct mmc_host;
+
+int mmc_gpio_get_ro(struct mmc_host *host);
+int mmc_gpio_request_ro(struct mmc_host *host, unsigned int gpio);
+void mmc_gpio_free_ro(struct mmc_host *host);
+
+int mmc_gpio_get_cd(struct mmc_host *host);
+int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio);
+void mmc_gpio_free_cd(struct mmc_host *host);
+
+#endif
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/include/linux/mod_devicetable.h linux-linaro-3.4-2012.05-1_cavium/include/linux/mod_devicetable.h
--- linux-linaro-3.4-2012.05-1_original/include/linux/mod_devicetable.h	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/include/linux/mod_devicetable.h	2014-07-29 17:28:38.819972000 +0800
@@ -132,6 +132,7 @@
 #define USB_DEVICE_ID_MATCH_INT_PROTOCOL	0x0200
 
 #define HID_ANY_ID				(~0)
+#define HID_BUS_ANY				0xffff
 
 struct hid_device_id {
 	__u16 bus;
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/include/linux/notify_hypervisor.h linux-linaro-3.4-2012.05-1_cavium/include/linux/notify_hypervisor.h
--- linux-linaro-3.4-2012.05-1_original/include/linux/notify_hypervisor.h	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/include/linux/notify_hypervisor.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,9 @@
+#ifndef __NOTIFY_HYPERVISOR_H__
+#define __NOTIFY_HYPERVISOR_H__
+
+void invoke_hypercall(int cmd_id, int param1, int param2, int param3);
+
+void notify_hypervisor(int cmd_id, int param1, int param2, int param3);
+
+#endif
+
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/include/linux/scatterlist.h linux-linaro-3.4-2012.05-1_cavium/include/linux/scatterlist.h
--- linux-linaro-3.4-2012.05-1_original/include/linux/scatterlist.h	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/include/linux/scatterlist.h	2014-09-12 15:59:37.348052000 +0800
@@ -111,6 +111,9 @@
 static inline void sg_set_buf(struct scatterlist *sg, const void *buf,
 			      unsigned int buflen)
 {
+#ifdef CONFIG_DEBUG_SG
+	BUG_ON(!virt_addr_valid(buf));
+#endif
 	sg_set_page(sg, virt_to_page(buf), buflen, offset_in_page(buf));
 }
 
@@ -172,6 +175,22 @@
 }
 
 /**
+ * sg_unmark_end - Undo setting the end of the scatterlist
+ * @sg:		 SG entryScatterlist
+ *
+ * Description:
+ *   Removes the termination marker from the given entry of the scatterlist.
+ *
+ **/
+static inline void sg_unmark_end(struct scatterlist *sg)
+{
+#ifdef CONFIG_DEBUG_SG
+	BUG_ON(sg->sg_magic != SG_MAGIC);
+#endif
+	sg->page_link &= ~0x02;
+}
+
+/**
  * sg_phys - Return physical address of an sg entry
  * @sg:	     SG entry
  *
@@ -201,6 +220,7 @@
 	return page_address(sg_page(sg)) + sg->offset;
 }
 
+int sg_nents(struct scatterlist *sg);
 struct scatterlist *sg_next(struct scatterlist *);
 struct scatterlist *sg_last(struct scatterlist *s, unsigned int);
 void sg_init_table(struct scatterlist *, unsigned int);
@@ -214,6 +234,10 @@
 int __sg_alloc_table(struct sg_table *, unsigned int, unsigned int, gfp_t,
 		     sg_alloc_fn *);
 int sg_alloc_table(struct sg_table *, unsigned int, gfp_t);
+int sg_alloc_table_from_pages(struct sg_table *sgt,
+	struct page **pages, unsigned int n_pages,
+	unsigned long offset, unsigned long size,
+	gfp_t gfp_mask);
 
 size_t sg_copy_from_buffer(struct scatterlist *sgl, unsigned int nents,
 			   void *buf, size_t buflen);
@@ -226,6 +250,59 @@
  */
 #define SG_MAX_SINGLE_ALLOC		(PAGE_SIZE / sizeof(struct scatterlist))
 
+/*
+ * sg page iterator
+ *
+ * Iterates over sg entries page-by-page.  On each successful iteration,
+ * you can call sg_page_iter_page(@piter) and sg_page_iter_dma_address(@piter)
+ * to get the current page and its dma address. @piter->sg will point to the
+ * sg holding this page and @piter->sg_pgoffset to the page's page offset
+ * within the sg. The iteration will stop either when a maximum number of sg
+ * entries was reached or a terminating sg (sg_last(sg) == true) was reached.
+ */
+struct sg_page_iter {
+	struct scatterlist	*sg;		/* sg holding the page */
+	unsigned int		sg_pgoffset;	/* page offset within the sg */
+
+	/* these are internal states, keep away */
+	unsigned int		__nents;	/* remaining sg entries */
+	int			__pg_advance;	/* nr pages to advance at the
+						 * next step */
+};
+
+bool __sg_page_iter_next(struct sg_page_iter *piter);
+void __sg_page_iter_start(struct sg_page_iter *piter,
+			  struct scatterlist *sglist, unsigned int nents,
+			  unsigned long pgoffset);
+/**
+ * sg_page_iter_page - get the current page held by the page iterator
+ * @piter:	page iterator holding the page
+ */
+static inline struct page *sg_page_iter_page(struct sg_page_iter *piter)
+{
+	return nth_page(sg_page(piter->sg), piter->sg_pgoffset);
+}
+
+/**
+ * sg_page_iter_dma_address - get the dma address of the current page held by
+ * the page iterator.
+ * @piter:	page iterator holding the page
+ */
+static inline dma_addr_t sg_page_iter_dma_address(struct sg_page_iter *piter)
+{
+	return sg_dma_address(piter->sg) + (piter->sg_pgoffset << PAGE_SHIFT);
+}
+
+/**
+ * for_each_sg_page - iterate over the pages of the given sg list
+ * @sglist:	sglist to iterate over
+ * @piter:	page iterator to hold current page, sg, sg_pgoffset
+ * @nents:	maximum number of sg entries to iterate over
+ * @pgoffset:	starting page offset
+ */
+#define for_each_sg_page(sglist, piter, nents, pgoffset)		   \
+	for (__sg_page_iter_start((piter), (sglist), (nents), (pgoffset)); \
+	     __sg_page_iter_next(piter);)
 
 /*
  * Mapping sg iterator
@@ -253,11 +330,11 @@
 	void			*addr;		/* pointer to the mapped area */
 	size_t			length;		/* length of the mapped area */
 	size_t			consumed;	/* number of consumed bytes */
+	struct sg_page_iter	piter;		/* page iterator */
 
 	/* these are internal states, keep away */
-	struct scatterlist	*__sg;		/* current entry */
-	unsigned int		__nents;	/* nr of remaining entries */
-	unsigned int		__offset;	/* offset within sg */
+	unsigned int		__offset;	/* offset within page */
+	unsigned int		__remaining;	/* remaining bytes on page */
 	unsigned int		__flags;
 };
 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/include/linux/skbuff.h linux-linaro-3.4-2012.05-1_cavium/include/linux/skbuff.h
--- linux-linaro-3.4-2012.05-1_original/include/linux/skbuff.h	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/include/linux/skbuff.h	2014-07-29 17:28:38.819972000 +0800
@@ -1587,8 +1587,12 @@
  * NET_IP_ALIGN(2) + ethernet_header(14) + IP_header(20/40) + ports(8)
  */
 #ifndef NET_SKB_PAD
+#ifdef CONFIG_PUREVU
+#define NET_SKB_PAD	max(64, L1_CACHE_BYTES)
+#else 
 #define NET_SKB_PAD	max(32, L1_CACHE_BYTES)
 #endif
+#endif
 
 extern int ___pskb_trim(struct sk_buff *skb, unsigned int len);
 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/include/linux/spi/cnc18xx_spi.h linux-linaro-3.4-2012.05-1_cavium/include/linux/spi/cnc18xx_spi.h
--- linux-linaro-3.4-2012.05-1_original/include/linux/spi/cnc18xx_spi.h	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/include/linux/spi/cnc18xx_spi.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,19 @@
+/*
+ * orion_spi.h
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __LINUX_SPI_CNC18XX_SPI_H
+#define __LINUX_SPI_CNC18XX_SPI_H
+
+struct cnc18xx_spi_info {
+	u32	tclk;		/* no <linux/clk.h> support yet */
+	u32	enable_clock_fix;
+	u32 max_rcv_sz;
+};
+
+
+#endif
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/include/linux/sw_ipi.h linux-linaro-3.4-2012.05-1_cavium/include/linux/sw_ipi.h
--- linux-linaro-3.4-2012.05-1_original/include/linux/sw_ipi.h	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/include/linux/sw_ipi.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,24 @@
+#ifndef __SW_IPI_H_
+#define __SW_IPI_H_
+#include <linux/workqueue.h>
+#include <linux/interrupt.h>
+
+u32 sw_send_smc(u32 cmd, u32 arg1, u32 arg2, u32 arg3);
+
+int sw_register_ipi_handler(int ipi_num, int irq_num, void* func, void *data);
+
+void sw_unregister_ipi_handler(int ipi_num);
+
+void vm_interrupt_wrapper(struct work_struct *new_work);
+
+int hyp_notify_handler(unsigned int irq, void (*handler)(struct work_struct *),
+		unsigned long irqflags, const char *devname, void *dev_id);
+
+struct sw_ipi_info{
+	struct work_struct work;
+	int irq_num;	
+	char* pri_data;
+};
+
+#endif
+
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/include/linux/usb/ch11.h linux-linaro-3.4-2012.05-1_cavium/include/linux/usb/ch11.h
--- linux-linaro-3.4-2012.05-1_original/include/linux/usb/ch11.h	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/include/linux/usb/ch11.h	2014-07-29 17:28:38.819972000 +0800
@@ -33,6 +33,7 @@
  */
 #define HUB_SET_DEPTH		12
 #define HUB_GET_PORT_ERR_COUNT	13
+#define HUB_SET_AND_TEST        14
 
 /*
  * Hub Class feature numbers
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/include/linux/usb/gadget.h linux-linaro-3.4-2012.05-1_cavium/include/linux/usb/gadget.h
--- linux-linaro-3.4-2012.05-1_original/include/linux/usb/gadget.h	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/include/linux/usb/gadget.h	2014-07-29 17:28:38.819972000 +0800
@@ -26,6 +26,39 @@
 
 struct usb_ep;
 
+#ifdef DWC_UTE_PER_IO
+
+struct dwc_ute_iso_packet_descriptor {
+        uint32_t offset;
+        uint32_t length;                /* expected length */
+        uint32_t actual_length;
+        uint32_t status;
+};
+
+struct dwc_ute_iso_req_ext {
+        /** transfer/submission flag */
+        uint32_t tr_sub_flags;
+/** Start the request ASAP */
+#define DWC_UTE_TF_ASAP         0x00000002
+/** Just enqueue the request w/o initiating a transfer */
+#define DWC_UTE_TF_ENQUEUE      0x00000004
+
+        /** 
+ *  *          * Count of ISO packet descriptors attached to this request - shall 
+ *   *                   * not exceed the pio_alloc_pkt_count 
+ *    *                            */
+        uint32_t pio_pkt_count;
+        /** count of ISO packet descriptors allocated for this request */
+        uint32_t pio_alloc_pkt_count;
+        /** number of ISO packet errors */
+        uint32_t error_count;
+        /** reserved for future extension */
+        uint32_t res;
+        /** Will be allocated and freed in the UTE gadget and based on the CFC value */
+        struct dwc_ute_iso_packet_descriptor *per_io_frame_descs;
+};
+#endif
+
 /**
  * struct usb_request - describes one i/o request
  * @buf: Buffer used for data.  Always provide this; some controllers
@@ -108,6 +141,12 @@
 
 	int			status;
 	unsigned		actual;
+
+/* The SNPS UTE specific extension for the periodic transfers */
+#ifdef DWC_UTE_PER_IO
+        struct dwc_ute_iso_req_ext ext_req;
+#endif
+
 };
 
 /*-------------------------------------------------------------------------*/
@@ -466,6 +505,7 @@
 	int	(*pullup) (struct usb_gadget *, int is_on);
 	int	(*ioctl)(struct usb_gadget *,
 				unsigned code, unsigned long param);
+        int     (*lpm_support) (struct usb_gadget *);
 	void	(*get_config_params)(struct usb_dcd_config_params *);
 	int	(*udc_start)(struct usb_gadget *,
 			struct usb_gadget_driver *);
@@ -764,6 +804,19 @@
 	return gadget->ops->pullup(gadget, 0);
 }
 
+/**
+ * usb_gadget_test_lpm_support - Is LPM (Linked Power Menegment) supported.
+ * @gadget:the device to check for LPM support
+ *
+ * Returns 1 if LPM is supported 0 otherwise
+ */
+static inline int
+usb_gadget_test_lpm_support (struct usb_gadget *gadget)
+{
+	if (!gadget->ops->lpm_support)
+		return -EOPNOTSUPP;
+	return gadget->ops->lpm_support (gadget);
+}
 
 /*-------------------------------------------------------------------------*/
 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/include/linux/usb/g_hid.h linux-linaro-3.4-2012.05-1_cavium/include/linux/usb/g_hid.h
--- linux-linaro-3.4-2012.05-1_original/include/linux/usb/g_hid.h	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/include/linux/usb/g_hid.h	2014-07-29 17:28:38.819972000 +0800
@@ -21,12 +21,28 @@
 #ifndef __LINUX_USB_G_HID_H
 #define __LINUX_USB_G_HID_H
 
+#define CONFIG_NOT_DONE                 (0)
+#define CONFIG_DONE                     (1)
+
+#define HIDG_MAX_REPORT_DESC_SIZE         (1024)      /* TODO: Verify this size would be sufficeint for all type of Gadget devices */
+
 struct hidg_func_descriptor {
 	unsigned char		subclass;
 	unsigned char		protocol;
+    unsigned char       feature_report[10][257];
+    unsigned short      feature_report_length[10];
 	unsigned short		report_length;
 	unsigned short		report_desc_length;
-	unsigned char		report_desc[];
+	unsigned char		report_desc[HIDG_MAX_REPORT_DESC_SIZE];
 };
 
+/* ioctl interface */
+
+/* The 'g' code is also used by gadgetfs ioctl requests.
+ * Don't add any colliding codes to either driver, and keep
+ * them in unique ranges (size 0x20 for now).
+ */
+
+#define GET_GADGET_HID_DEVICE_CONFIG_STATUS    _IOR('g', 0x41, unsigned char)
+
 #endif /* __LINUX_USB_G_HID_H */
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/include/linux/usb/hcd.h linux-linaro-3.4-2012.05-1_cavium/include/linux/usb/hcd.h
--- linux-linaro-3.4-2012.05-1_original/include/linux/usb/hcd.h	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/include/linux/usb/hcd.h	2014-07-29 17:28:38.819972000 +0800
@@ -501,6 +501,7 @@
 #define GetPortStatus		(0xa300 | USB_REQ_GET_STATUS)
 #define SetHubFeature		(0x2000 | USB_REQ_SET_FEATURE)
 #define SetPortFeature		(0x2300 | USB_REQ_SET_FEATURE)
+#define SetandTestPortFeature   (0xa300 | HUB_SET_AND_TEST)
 
 
 /*-------------------------------------------------------------------------*/
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/include/linux/usb.h linux-linaro-3.4-2012.05-1_cavium/include/linux/usb.h
--- linux-linaro-3.4-2012.05-1_original/include/linux/usb.h	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/include/linux/usb.h	2014-07-29 17:28:38.819972000 +0800
@@ -329,6 +329,9 @@
 					 * for control transfers?
 					 */
 	u8 otg_port;			/* 0, or number of OTG/HNP port */
+#ifdef CONFIG_USB_OTG
+	u16 otg_version;		/* OTG version supported by HCD - SNPS*/	
+#endif
 	unsigned is_b_host:1;		/* true during some HNP roleswitches */
 	unsigned b_hnp_enable:1;	/* OTG: did A-Host enable HNP? */
 	unsigned sg_tablesize;		/* 0 or largest number of sg list entries */
@@ -516,6 +519,9 @@
 #endif
 	struct wusb_dev *wusb_dev;
 	int slot_id;
+#ifdef CONFIG_USB_SNPS_DWC_OTG2
+        struct delayed_work hnp_poll_work;  /* Drives HNP polling */
+#endif
 	enum usb_device_removable removable;
 };
 #define	to_usb_device(d) container_of(d, struct usb_device, dev)
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/init/initramfs.c linux-linaro-3.4-2012.05-1_cavium/init/initramfs.c
--- linux-linaro-3.4-2012.05-1_original/init/initramfs.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/init/initramfs.c	2014-07-29 17:28:38.819972000 +0800
@@ -579,7 +579,7 @@
 }
 EXPORT_SYMBOL(populate_rootfs_wait);
 
-static void __init async_populate_rootfs(void)
+static void __init async_populate_rootfs(void *data, async_cookie_t cookie)
 {
 	char *err = unpack_to_rootfs(__initramfs_start, __initramfs_size);
 	if (err)
@@ -628,12 +628,14 @@
 		async_schedule_domain(async_populate_rootfs, NULL,
 						&populate_rootfs_domain);
 	}
+	return 0;
 }
 static int __init populate_rootfs(void)
 {
 	if (!rootfs_populated)
 		async_schedule_domain(async_populate_rootfs, NULL,
 						&populate_rootfs_domain);
+	return 0;
 }
 
 earlyrootfs_initcall(populate_rootfs_early);
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/init/main.c linux-linaro-3.4-2012.05-1_cavium/init/main.c
--- linux-linaro-3.4-2012.05-1_original/init/main.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/init/main.c	2014-07-29 17:28:38.819972000 +0800
@@ -90,7 +90,9 @@
 #ifndef CONFIG_DEBUG_RODATA
 static inline void mark_rodata_ro(void) { }
 #endif
-
+#ifdef CONFIG_SW_SUPPORT
+extern void sw_ipi_handler_init(void);
+#endif
 #ifdef CONFIG_TC
 extern void tc_init(void);
 #endif
@@ -231,7 +233,7 @@
 early_param("loglevel", loglevel);
 
 /* Change NUL term back to "=", to make "param" the whole string. */
-static int __init repair_env_string(char *param, char *val)
+static int __init repair_env_string(char *param, char *val, int known)
 {
 	if (val) {
 		/* param=val or param="val"? */
@@ -254,7 +256,7 @@
  */
 static int __init pass_bootoption(char *param, char *val, int all)
 {
-	repair_env_string(param, val);
+	repair_env_string(param, val, all);
 
 	/* Handle obsolete-style parameters */
 	if (obsolete_checksetup(param) && !all)
@@ -621,6 +623,9 @@
 		late_time_init();
 	sched_clock_init();
 	calibrate_delay();
+#ifdef CONFIG_SW_SUPPORT
+	sw_ipi_handler_init();
+#endif
 	pidmap_init();
 	anon_vma_init();
 #ifdef CONFIG_X86
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/kernel/power/main.c linux-linaro-3.4-2012.05-1_cavium/kernel/power/main.c
--- linux-linaro-3.4-2012.05-1_original/kernel/power/main.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/kernel/power/main.c	2014-07-29 17:28:38.819972000 +0800
@@ -20,6 +20,16 @@
 
 DEFINE_MUTEX(pm_mutex);
 
+#ifdef CONFIG_ARCH_CELESTIAL
+uint32_t irq_list_length = 0;
+uint32_t gpio_wakeup_list = 0xffffffff;
+uint32_t irq_mask_list[MAX_MASKABLE_IRQS];
+uint32_t irq_mask_temp[MAX_MASKABLE_IRQS];
+EXPORT_SYMBOL(irq_list_length);
+EXPORT_SYMBOL(irq_mask_list);
+EXPORT_SYMBOL(gpio_wakeup_list);
+#endif
+
 #ifdef CONFIG_PM_SLEEP
 
 /* Routines for PM-transition notifications */
@@ -405,6 +415,150 @@
 power_attr(wake_unlock);
 #endif
 
+#ifdef CONFIG_ARCH_CELESTIAL
+static ssize_t irqs_to_mask_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
+{
+    ssize_t rv = 0, cnt = 0;
+    uint32_t ix = 0;
+    char *bp = buf;
+
+    if (irq_list_length == 0) {
+        *bp++ = '\n';
+        *bp = '\0';
+        return 1;
+    }
+    cnt = sprintf(bp, "%u", irq_mask_list[0]);
+    bp += cnt;
+    rv += cnt;
+    for (ix = 1; ix < irq_list_length; ++ix) {
+        cnt = sprintf(bp, " %u", irq_mask_list[ix]);
+        bp += cnt;
+        rv += cnt;
+    }
+    *bp++ = '\n';
+    ++rv;
+    *bp = '\0';
+    return rv;
+}
+
+static ssize_t gpio_wakeup_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
+{
+    uint32_t v = gpio_wakeup_list;
+    char *p = buf;
+    int cnt = 0, first_bit = 1; unsigned bitno = 0;
+
+    for (bitno = 0; bitno < 32; ++bitno) {
+        if ((v & 1) == 0) {
+            if (!first_bit) {
+                *p++ = ' ';
+            } else {
+                first_bit = 0;
+            }
+            cnt = sprintf(p, "%u", bitno);
+            p += cnt;
+        }
+        v >>= 1;
+    }
+    *p++ = '\n';
+    *p = '\0';
+    return (ssize_t)(p - buf);
+}
+
+static ssize_t irqs_to_mask_store(struct kobject *kobj,
+                                  struct kobj_attribute *attr,
+                                  const char *buf, size_t sz)
+{
+    const char *ptr = buf;
+    uint32_t irqno = 0, ix = 0;
+
+    if (*ptr == '\n' || *ptr == '\0') {
+        return sz;
+    }
+
+    /* We keep a temporary array to store parsed IRQ #s, so that if the
+       string turns out to be invalid, we can discard the list and still keep
+       the existing one. */
+    while (1 == 1) {
+        /* Decimal #s only right now. */
+        while (*ptr >= '0' && *ptr <= '9') {
+            irqno = irqno*10 + (*ptr - '0');
+            if (irqno >= MAX_MASKABLE_IRQS) {
+                return -EINVAL; /* Disallow overflow or too large irq # */
+            }
+            ++ptr;
+        }
+        if (!(*ptr == ' ' || *ptr == '\t' || *ptr == '\n' || *ptr == '\0')) {
+            return -EINVAL;
+        }
+        irq_mask_temp[ix++] = irqno;
+        irqno = 0;
+        if (*ptr == '\n' || *ptr == '\0') {
+            break;
+        }
+        do {
+            ++ptr;
+        } while (*ptr == ' ' || *ptr == '\t');
+        if (*ptr == '\n' || *ptr == '\0') {
+            break;
+        }
+    }
+
+    irq_list_length = ix;
+    for (ix = 0; ix < irq_list_length; ++ix) {
+        irq_mask_list[ix] = irq_mask_temp[ix];
+    }
+
+    return (ssize_t)sz;
+}
+
+static ssize_t gpio_wakeup_store(struct kobject *kobj,
+                                  struct kobj_attribute *attr,
+                                  const char *buf, size_t sz)
+{
+    const char *ptr = buf;
+    uint32_t pin_num = 0;
+    uint32_t temp = (uint32_t)(-1);
+
+    if (*ptr == '\n' || *ptr == '\0') {
+        return sz;
+    }
+
+    /* We keep a temporary array to store parsed pin #s, so that if the
+       string turns out to be invalid, we can discard the list and still keep
+       the existing one. */
+    while (1 == 1) {
+        /* Decimal #s only right now. */
+        while (*ptr >= '0' && *ptr <= '9') {
+            pin_num = pin_num*10 + (*ptr - '0');
+            if (pin_num >= 32) {
+                return -EINVAL; /* Disallow overflow or too large pin # */
+            }
+            ++ptr;
+        }
+        if (!(*ptr == ' ' || *ptr == '\t' || *ptr == '\n' || *ptr == '\0')) {
+            return -EINVAL;
+        }
+        temp &= ~(1 << pin_num);
+        pin_num = 0;
+        if (*ptr == '\n' || *ptr == '\0') {
+            break;
+        }
+        do {
+            ++ptr;
+        } while (*ptr == ' ' || *ptr == '\t');
+        if (*ptr == '\n' || *ptr == '\0') {
+            break;
+        }
+    }
+
+    gpio_wakeup_list = temp;
+    return (ssize_t)sz;
+}
+
+power_attr(irqs_to_mask);
+power_attr(gpio_wakeup);
+#endif
+
 static struct attribute * g[] = {
 	&state_attr.attr,
 #ifdef CONFIG_PM_TRACE
@@ -422,6 +576,10 @@
 	&wake_unlock_attr.attr,
 #endif
 #endif
+#ifdef CONFIG_ARCH_CELESTIAL
+    &irqs_to_mask_attr.attr,
+    &gpio_wakeup_attr.attr,
+#endif
 	NULL,
 };
 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/kernel/power/power.h linux-linaro-3.4-2012.05-1_cavium/kernel/power/power.h
--- linux-linaro-3.4-2012.05-1_original/kernel/power/power.h	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/kernel/power/power.h	2014-07-29 17:28:38.819972000 +0800
@@ -3,6 +3,10 @@
 #include <linux/utsname.h>
 #include <linux/freezer.h>
 
+#ifdef CONFIG_ARCH_CELESTIAL
+#define MAX_MASKABLE_IRQS (96)
+#endif
+
 struct swsusp_info {
 	struct new_utsname	uts;
 	u32			version_code;
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/kernel/power/suspend.c linux-linaro-3.4-2012.05-1_cavium/kernel/power/suspend.c
--- linux-linaro-3.4-2012.05-1_original/kernel/power/suspend.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/kernel/power/suspend.c	2014-07-29 17:28:38.819972000 +0800
@@ -20,14 +20,23 @@
 #include <linux/kernel.h>
 #include <linux/list.h>
 #include <linux/mm.h>
+#include <linux/mman.h>
 #include <linux/slab.h>
 #include <linux/export.h>
+#include <linux/interrupt.h>
 #include <linux/suspend.h>
 #include <linux/syscore_ops.h>
 #include <trace/events/power.h>
+#include <linux/err.h>
 
 #include "power.h"
 
+#ifdef CONFIG_ARCH_CELESTIAL
+extern uint32_t irq_list_length;
+extern uint32_t irq_mask_list[MAX_MASKABLE_IRQS];
+
+typedef int (*my_funcptr)(uint32_t, uint32_t *, uint32_t);
+#endif
 const char *const pm_states[PM_SUSPEND_MAX] = {
 	[PM_SUSPEND_STANDBY]	= "standby",
 	[PM_SUSPEND_MEM]	= "mem",
@@ -257,6 +266,78 @@
 	pm_restore_console();
 }
 
+#ifdef CONFIG_ARCH_CELESTIAL
+#define GPIO8_NO_IE                 (-1)
+#define DEV_MEM_OPEN_FAILURE        (-2)
+#define MMAP_FAILURE                (-3)
+#define LINE_BUFFER_FUNCTION_FAIL   (-4)
+
+static int cnc1900_go_to_sleep(void)
+{
+    extern uint32_t gpio_wakeup_list;
+    void *line_buffer_addr = NULL;
+    struct file *fp;
+    my_funcptr line_buffer_function = NULL;
+    int status = 42, rv = -1;
+    unsigned long mapped_address, ma__UL;
+    uint32_t contents = 0;
+    volatile uint32_t *gpio_va = NULL, *idscs_va = NULL;
+
+    gpio_va = ioremap_nocache(0x80260000, 0x10000);
+    idscs_va = ioremap_nocache(0xb2100000, 0x10000);
+    contents = gpio_va[10];
+
+    /* Normally, one does not wish to open a file in kernel space. However,
+       we need a file structure for the do_mmap() call, and the "file" in
+       this case is really system memory.  */
+    fp = filp_open("/dev/mem", O_RDWR, 0666);
+    if (IS_ERR(fp)) {
+        printk(KERN_ERR "%s: could not open /dev/mem\n", __func__);
+        return DEV_MEM_OPEN_FAILURE;
+    } else {
+        printk(KERN_DEBUG "%s: opened /dev/mem\n", __func__);
+    }
+
+    /* Assign line buffer address. We can't simply use ioremap and friends
+       because we need the pages to be executable. After all, we'ere going to
+       jump here and run code. */
+    down_write(&(current->mm->mmap_sem));
+    ma__UL = mapped_address = do_mmap(fp, 0, 0x10000, PROT_READ|PROT_EXEC, MAP_PRIVATE,
+                             0x80000000);
+    up_write(&(current->mm->mmap_sem));
+    filp_close(fp, NULL);
+
+    ma__UL += 4096ul;
+    if (ma__UL >= 1ul && ma__UL < 4096) {
+        printk(KERN_ERR "%s: mapping failure: do_mmap returned -%lu\n", __func__,
+               ma__UL);
+        return MMAP_FAILURE;
+    } else {
+        printk(KERN_DEBUG "%s: mapped address of line buffer: %08lx\n",
+               __func__, mapped_address);
+    }
+    contents = idscs_va[80];
+    printk(KERN_DEBUG "%s: clock enable register (b2100140) is %08x\n", __func__, contents);
+    mdelay(100);
+    /* 0x40 allows 16 words for a stack frame. */
+    line_buffer_addr = (void *)(mapped_address + 0x40);
+    line_buffer_function = (my_funcptr)line_buffer_addr;
+
+    /* Jump to the line buffer */
+    status = line_buffer_function(irq_list_length, &irq_mask_list[0], gpio_wakeup_list);
+    if (status != 0) {
+        printk(KERN_ERR "%s: line_buffer_function returned 0x%08x\n", __func__, status);
+        rv = LINE_BUFFER_FUNCTION_FAIL;
+    } else {
+        rv = 0;
+    }
+    printk(KERN_INFO "%s: finished waking up.\n", __func__);
+
+    /* Continue on as if nothing happened. */
+    return rv;
+}
+#endif
+
 /**
  * enter_state - Do common work needed to enter system sleep state.
  * @state: System sleep state to enter.
@@ -267,7 +348,7 @@
  */
 static int enter_state(suspend_state_t state)
 {
-	int error;
+	int error, res = -1;
 
 	if (!valid_state(state))
 		return -ENODEV;
@@ -275,29 +356,51 @@
 	if (!mutex_trylock(&pm_mutex))
 		return -EBUSY;
 
-	printk(KERN_INFO "PM: Syncing filesystems ... ");
-	sys_sync();
-	printk("done.\n");
-
-	pr_debug("PM: Preparing system for %s sleep\n", pm_states[state]);
-	error = suspend_prepare();
-	if (error)
-		goto Unlock;
-
-	if (suspend_test(TEST_FREEZER))
-		goto Finish;
+#ifdef CONFIG_ARCH_CELESTIAL
+	if (state == PM_SUSPEND_MEM) {
 
-	pr_debug("PM: Entering %s sleep\n", pm_states[state]);
-	pm_restrict_gfp_mask();
-	error = suspend_devices_and_enter(state);
-	pm_restore_gfp_mask();
+        // Disable interrupts, jump to line buffer, etc. Hack, hack...
+        printk(KERN_DEBUG "entering cnc1900_go_to_sleep() from enter_state(%d)\n", state);
+        res = cnc1900_go_to_sleep();
+
+		mutex_unlock(&pm_mutex);
+        if (res != 0) {
+            printk(KERN_ERR "Failed to execute STR: cnc1900_go_to_sleep() returned with an error\n");
+            return -ENODEV;
+        }
+        return 0;
+
+	} else {
+#endif
+
+        printk(KERN_INFO "PM: Syncing filesystems ... ");
+        sys_sync();
+        printk("done.\n");
+
+        pr_debug("PM: Preparing system for %s sleep\n", pm_states[state]);
+        error = suspend_prepare();
+        if (error)
+            goto Unlock;
+
+        if (suspend_test(TEST_FREEZER))
+            goto Finish;
+
+        pr_debug("PM: Entering %s sleep\n", pm_states[state]);
+        pm_restrict_gfp_mask();
+        error = suspend_devices_and_enter(state);
+        pm_restore_gfp_mask();
 
  Finish:
-	pr_debug("PM: Finishing wakeup.\n");
-	suspend_finish();
+        pr_debug("PM: Finishing wakeup.\n");
+        suspend_finish();
  Unlock:
-	mutex_unlock(&pm_mutex);
-	return error;
+        mutex_unlock(&pm_mutex);
+        return error;
+
+#ifdef CONFIG_ARCH_CELESTIAL
+    }
+#endif
+
 }
 
 /**
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/kernel/softirq.c linux-linaro-3.4-2012.05-1_cavium/kernel/softirq.c
--- linux-linaro-3.4-2012.05-1_original/kernel/softirq.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/kernel/softirq.c	2014-07-29 17:28:38.819972000 +0800
@@ -156,7 +156,9 @@
 
 static inline void _local_bh_enable_ip(unsigned long ip)
 {
+#ifndef CONFIG_PUREVU /* skip this warning if PUREVU, since this is in the standard send path */
 	WARN_ON_ONCE(in_irq() || irqs_disabled());
+#endif
 #ifdef CONFIG_TRACE_IRQFLAGS
 	local_irq_disable();
 #endif
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/kernel/trace/trace.c linux-linaro-3.4-2012.05-1_cavium/kernel/trace/trace.c
--- linux-linaro-3.4-2012.05-1_original/kernel/trace/trace.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/kernel/trace/trace.c	2014-07-29 17:28:38.819972000 +0800
@@ -3751,8 +3751,7 @@
 	struct page *pages[2];
 	int nr_pages = 1;
 	ssize_t written;
-	void *page1;
-	void *page2;
+	void *page1, *page2 = NULL;
 	int offset;
 	int size;
 	int len;
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/lib/idr.c linux-linaro-3.4-2012.05-1_cavium/lib/idr.c
--- linux-linaro-3.4-2012.05-1_original/lib/idr.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/lib/idr.c	2014-09-12 15:59:37.348052000 +0800
@@ -20,7 +20,7 @@
  * that id to this code and it returns your pointer.
 
  * You can release ids at any time. When all ids are released, most of
- * the memory is returned (we keep IDR_FREE_MAX) in a local pool so we
+ * the memory is returned (we keep MAX_IDR_FREE) in a local pool so we
  * don't need to go to the memory "store" during an id allocate, just
  * so you don't need to be too concerned about locking and conflicts
  * with the slab allocator.
@@ -35,10 +35,41 @@
 #include <linux/string.h>
 #include <linux/idr.h>
 #include <linux/spinlock.h>
+#include <linux/percpu.h>
+#include <linux/hardirq.h>
+
+#define MAX_IDR_SHIFT		(sizeof(int) * 8 - 1)
+#define MAX_IDR_BIT		(1U << MAX_IDR_SHIFT)
+
+/* Leave the possibility of an incomplete final layer */
+#define MAX_IDR_LEVEL ((MAX_IDR_SHIFT + IDR_BITS - 1) / IDR_BITS)
+
+/* Number of id_layer structs to leave in free list */
+#define MAX_IDR_FREE (MAX_IDR_LEVEL * 2)
 
 static struct kmem_cache *idr_layer_cache;
+static DEFINE_PER_CPU(struct idr_layer *, idr_preload_head);
+static DEFINE_PER_CPU(int, idr_preload_cnt);
 static DEFINE_SPINLOCK(simple_ida_lock);
 
+/* the maximum ID which can be allocated given idr->layers */
+static int idr_max(int layers)
+{
+	int bits = min_t(int, layers * IDR_BITS, MAX_IDR_SHIFT);
+
+	return (1 << bits) - 1;
+}
+
+/*
+ * Prefix mask for an idr_layer at @layer.  For layer 0, the prefix mask is
+ * all bits except for the lower IDR_BITS.  For layer 1, 2 * IDR_BITS, and
+ * so on.
+ */
+static int idr_layer_prefix_mask(int layer)
+{
+	return ~idr_max(layer + 1);
+}
+
 static struct idr_layer *get_from_free_list(struct idr *idp)
 {
 	struct idr_layer *p;
@@ -54,6 +85,62 @@
 	return(p);
 }
 
+/**
+ * idr_layer_alloc - allocate a new idr_layer
+ * @gfp_mask: allocation mask
+ * @layer_idr: optional idr to allocate from
+ *
+ * If @layer_idr is %NULL, directly allocate one using @gfp_mask or fetch
+ * one from the per-cpu preload buffer.  If @layer_idr is not %NULL, fetch
+ * an idr_layer from @idr->id_free.
+ *
+ * @layer_idr is to maintain backward compatibility with the old alloc
+ * interface - idr_pre_get() and idr_get_new*() - and will be removed
+ * together with per-pool preload buffer.
+ */
+static struct idr_layer *idr_layer_alloc(gfp_t gfp_mask, struct idr *layer_idr)
+{
+	struct idr_layer *new;
+
+	/* this is the old path, bypass to get_from_free_list() */
+	if (layer_idr)
+		return get_from_free_list(layer_idr);
+
+	/*
+	 * Try to allocate directly from kmem_cache.  We want to try this
+	 * before preload buffer; otherwise, non-preloading idr_alloc()
+	 * users will end up taking advantage of preloading ones.  As the
+	 * following is allowed to fail for preloaded cases, suppress
+	 * warning this time.
+	 */
+	new = kmem_cache_zalloc(idr_layer_cache, gfp_mask | __GFP_NOWARN);
+	if (new)
+		return new;
+
+	/*
+	 * Try to fetch one from the per-cpu preload buffer if in process
+	 * context.  See idr_preload() for details.
+	 */
+	if (!in_interrupt()) {
+		preempt_disable();
+		new = __this_cpu_read(idr_preload_head);
+		if (new) {
+			__this_cpu_write(idr_preload_head, new->ary[0]);
+			__this_cpu_dec(idr_preload_cnt);
+			new->ary[0] = NULL;
+		}
+		preempt_enable();
+		if (new)
+			return new;
+	}
+
+	/*
+	 * Both failed.  Try kmem_cache again w/o adding __GFP_NOWARN so
+	 * that memory allocation failure warning is printed as intended.
+	 */
+	return kmem_cache_zalloc(idr_layer_cache, gfp_mask);
+}
+
 static void idr_layer_rcu_free(struct rcu_head *head)
 {
 	struct idr_layer *layer;
@@ -62,8 +149,10 @@
 	kmem_cache_free(idr_layer_cache, layer);
 }
 
-static inline void free_layer(struct idr_layer *p)
+static inline void free_layer(struct idr *idr, struct idr_layer *p)
 {
+	if (idr->hint && idr->hint == p)
+		RCU_INIT_POINTER(idr->hint, NULL);
 	call_rcu(&p->rcu_head, idr_layer_rcu_free);
 }
 
@@ -92,37 +181,24 @@
 	struct idr_layer *p = pa[0];
 	int l = 0;
 
-	__set_bit(id & IDR_MASK, &p->bitmap);
+	__set_bit(id & IDR_MASK, p->bitmap);
 	/*
 	 * If this layer is full mark the bit in the layer above to
 	 * show that this part of the radix tree is full.  This may
 	 * complete the layer above and require walking up the radix
 	 * tree.
 	 */
-	while (p->bitmap == IDR_FULL) {
+	while (bitmap_full(p->bitmap, IDR_SIZE)) {
 		if (!(p = pa[++l]))
 			break;
 		id = id >> IDR_BITS;
-		__set_bit((id & IDR_MASK), &p->bitmap);
+		__set_bit((id & IDR_MASK), p->bitmap);
 	}
 }
 
-/**
- * idr_pre_get - reserve resources for idr allocation
- * @idp:	idr handle
- * @gfp_mask:	memory allocation flags
- *
- * This function should be called prior to calling the idr_get_new* functions.
- * It preallocates enough memory to satisfy the worst possible allocation. The
- * caller should pass in GFP_KERNEL if possible.  This of course requires that
- * no spinning locks be held.
- *
- * If the system is REALLY out of memory this function returns %0,
- * otherwise %1.
- */
-int idr_pre_get(struct idr *idp, gfp_t gfp_mask)
+int __idr_pre_get(struct idr *idp, gfp_t gfp_mask)
 {
-	while (idp->id_free_cnt < IDR_FREE_MAX) {
+	while (idp->id_free_cnt < MAX_IDR_FREE) {
 		struct idr_layer *new;
 		new = kmem_cache_zalloc(idr_layer_cache, gfp_mask);
 		if (new == NULL)
@@ -131,14 +207,30 @@
 	}
 	return 1;
 }
-EXPORT_SYMBOL(idr_pre_get);
+EXPORT_SYMBOL(__idr_pre_get);
 
-static int sub_alloc(struct idr *idp, int *starting_id, struct idr_layer **pa)
+/**
+ * sub_alloc - try to allocate an id without growing the tree depth
+ * @idp: idr handle
+ * @starting_id: id to start search at
+ * @pa: idr_layer[MAX_IDR_LEVEL] used as backtrack buffer
+ * @gfp_mask: allocation mask for idr_layer_alloc()
+ * @layer_idr: optional idr passed to idr_layer_alloc()
+ *
+ * Allocate an id in range [@starting_id, INT_MAX] from @idp without
+ * growing its depth.  Returns
+ *
+ *  the allocated id >= 0 if successful,
+ *  -EAGAIN if the tree needs to grow for allocation to succeed,
+ *  -ENOSPC if the id space is exhausted,
+ *  -ENOMEM if more idr_layers need to be allocated.
+ */
+static int sub_alloc(struct idr *idp, int *starting_id, struct idr_layer **pa,
+		     gfp_t gfp_mask, struct idr *layer_idr)
 {
 	int n, m, sh;
 	struct idr_layer *p, *new;
 	int l, id, oid;
-	unsigned long bm;
 
 	id = *starting_id;
  restart:
@@ -150,8 +242,7 @@
 		 * We run around this while until we reach the leaf node...
 		 */
 		n = (id >> (IDR_BITS*l)) & IDR_MASK;
-		bm = ~p->bitmap;
-		m = find_next_bit(&bm, IDR_SIZE, n);
+		m = find_next_zero_bit(p->bitmap, IDR_SIZE, n);
 		if (m == IDR_SIZE) {
 			/* no space available go back to previous layer. */
 			l++;
@@ -161,7 +252,7 @@
 			/* if already at the top layer, we need to grow */
 			if (id >= 1 << (idp->layers * IDR_BITS)) {
 				*starting_id = id;
-				return IDR_NEED_TO_GROW;
+				return -EAGAIN;
 			}
 			p = pa[l];
 			BUG_ON(!p);
@@ -179,18 +270,19 @@
 			sh = IDR_BITS*l;
 			id = ((id >> sh) ^ n ^ m) << sh;
 		}
-		if ((id >= MAX_ID_BIT) || (id < 0))
-			return IDR_NOMORE_SPACE;
+		if ((id >= MAX_IDR_BIT) || (id < 0))
+			return -ENOSPC;
 		if (l == 0)
 			break;
 		/*
 		 * Create the layer below if it is missing.
 		 */
 		if (!p->ary[m]) {
-			new = get_from_free_list(idp);
+			new = idr_layer_alloc(gfp_mask, layer_idr);
 			if (!new)
-				return -1;
+				return -ENOMEM;
 			new->layer = l-1;
+			new->prefix = id & idr_layer_prefix_mask(new->layer);
 			rcu_assign_pointer(p->ary[m], new);
 			p->count++;
 		}
@@ -203,7 +295,8 @@
 }
 
 static int idr_get_empty_slot(struct idr *idp, int starting_id,
-			      struct idr_layer **pa)
+			      struct idr_layer **pa, gfp_t gfp_mask,
+			      struct idr *layer_idr)
 {
 	struct idr_layer *p, *new;
 	int layers, v, id;
@@ -214,8 +307,8 @@
 	p = idp->top;
 	layers = idp->layers;
 	if (unlikely(!p)) {
-		if (!(p = get_from_free_list(idp)))
-			return -1;
+		if (!(p = idr_layer_alloc(gfp_mask, layer_idr)))
+			return -ENOMEM;
 		p->layer = 0;
 		layers = 1;
 	}
@@ -223,7 +316,7 @@
 	 * Add a new layer to the top of the tree if the requested
 	 * id is larger than the currently allocated space.
 	 */
-	while ((layers < (MAX_LEVEL - 1)) && (id >= (1 << (layers*IDR_BITS)))) {
+	while (id > idr_max(layers)) {
 		layers++;
 		if (!p->count) {
 			/* special case: if the tree is currently empty,
@@ -231,9 +324,10 @@
 			 * upwards.
 			 */
 			p->layer++;
+			WARN_ON_ONCE(p->prefix);
 			continue;
 		}
-		if (!(new = get_from_free_list(idp))) {
+		if (!(new = idr_layer_alloc(gfp_mask, layer_idr))) {
 			/*
 			 * The allocation failed.  If we built part of
 			 * the structure tear it down.
@@ -242,110 +336,191 @@
 			for (new = p; p && p != idp->top; new = p) {
 				p = p->ary[0];
 				new->ary[0] = NULL;
-				new->bitmap = new->count = 0;
+				new->count = 0;
+				bitmap_clear(new->bitmap, 0, IDR_SIZE);
 				__move_to_free_list(idp, new);
 			}
 			spin_unlock_irqrestore(&idp->lock, flags);
-			return -1;
+			return -ENOMEM;
 		}
 		new->ary[0] = p;
 		new->count = 1;
 		new->layer = layers-1;
-		if (p->bitmap == IDR_FULL)
-			__set_bit(0, &new->bitmap);
+		new->prefix = id & idr_layer_prefix_mask(new->layer);
+		if (bitmap_full(p->bitmap, IDR_SIZE))
+			__set_bit(0, new->bitmap);
 		p = new;
 	}
 	rcu_assign_pointer(idp->top, p);
 	idp->layers = layers;
-	v = sub_alloc(idp, &id, pa);
-	if (v == IDR_NEED_TO_GROW)
+	v = sub_alloc(idp, &id, pa, gfp_mask, layer_idr);
+	if (v == -EAGAIN)
 		goto build_up;
 	return(v);
 }
 
-static int idr_get_new_above_int(struct idr *idp, void *ptr, int starting_id)
+/*
+ * @id and @pa are from a successful allocation from idr_get_empty_slot().
+ * Install the user pointer @ptr and mark the slot full.
+ */
+static void idr_fill_slot(struct idr *idr, void *ptr, int id,
+			  struct idr_layer **pa)
 {
-	struct idr_layer *pa[MAX_LEVEL];
-	int id;
+	/* update hint used for lookup, cleared from free_layer() */
+	rcu_assign_pointer(idr->hint, pa[0]);
 
-	id = idr_get_empty_slot(idp, starting_id, pa);
-	if (id >= 0) {
-		/*
-		 * Successfully found an empty slot.  Install the user
-		 * pointer and mark the slot full.
-		 */
-		rcu_assign_pointer(pa[0]->ary[id & IDR_MASK],
-				(struct idr_layer *)ptr);
-		pa[0]->count++;
-		idr_mark_full(pa, id);
-	}
-
-	return id;
+	rcu_assign_pointer(pa[0]->ary[id & IDR_MASK], (struct idr_layer *)ptr);
+	pa[0]->count++;
+	idr_mark_full(pa, id);
 }
 
-/**
- * idr_get_new_above - allocate new idr entry above or equal to a start id
- * @idp: idr handle
- * @ptr: pointer you want associated with the id
- * @starting_id: id to start search at
- * @id: pointer to the allocated handle
- *
- * This is the allocate id function.  It should be called with any
- * required locks.
- *
- * If allocation from IDR's private freelist fails, idr_get_new_above() will
- * return %-EAGAIN.  The caller should retry the idr_pre_get() call to refill
- * IDR's preallocation and then retry the idr_get_new_above() call.
- *
- * If the idr is full idr_get_new_above() will return %-ENOSPC.
- *
- * @id returns a value in the range @starting_id ... %0x7fffffff
- */
-int idr_get_new_above(struct idr *idp, void *ptr, int starting_id, int *id)
+int __idr_get_new_above(struct idr *idp, void *ptr, int starting_id, int *id)
 {
+	struct idr_layer *pa[MAX_IDR_LEVEL + 1];
 	int rv;
 
-	rv = idr_get_new_above_int(idp, ptr, starting_id);
-	/*
-	 * This is a cheap hack until the IDR code can be fixed to
-	 * return proper error values.
-	 */
+	rv = idr_get_empty_slot(idp, starting_id, pa, 0, idp);
 	if (rv < 0)
-		return _idr_rc_to_errno(rv);
+		return rv == -ENOMEM ? -EAGAIN : rv;
+
+	idr_fill_slot(idp, ptr, rv, pa);
 	*id = rv;
 	return 0;
 }
-EXPORT_SYMBOL(idr_get_new_above);
+EXPORT_SYMBOL(__idr_get_new_above);
 
 /**
- * idr_get_new - allocate new idr entry
- * @idp: idr handle
- * @ptr: pointer you want associated with the id
- * @id: pointer to the allocated handle
+ * idr_preload - preload for idr_alloc()
+ * @gfp_mask: allocation mask to use for preloading
+ *
+ * Preload per-cpu layer buffer for idr_alloc().  Can only be used from
+ * process context and each idr_preload() invocation should be matched with
+ * idr_preload_end().  Note that preemption is disabled while preloaded.
+ *
+ * The first idr_alloc() in the preloaded section can be treated as if it
+ * were invoked with @gfp_mask used for preloading.  This allows using more
+ * permissive allocation masks for idrs protected by spinlocks.
  *
- * If allocation from IDR's private freelist fails, idr_get_new_above() will
- * return %-EAGAIN.  The caller should retry the idr_pre_get() call to refill
- * IDR's preallocation and then retry the idr_get_new_above() call.
+ * For example, if idr_alloc() below fails, the failure can be treated as
+ * if idr_alloc() were called with GFP_KERNEL rather than GFP_NOWAIT.
  *
- * If the idr is full idr_get_new_above() will return %-ENOSPC.
+ *	idr_preload(GFP_KERNEL);
+ *	spin_lock(lock);
  *
- * @id returns a value in the range %0 ... %0x7fffffff
+ *	id = idr_alloc(idr, ptr, start, end, GFP_NOWAIT);
+ *
+ *	spin_unlock(lock);
+ *	idr_preload_end();
+ *	if (id < 0)
+ *		error;
  */
-int idr_get_new(struct idr *idp, void *ptr, int *id)
+void idr_preload(gfp_t gfp_mask)
 {
-	int rv;
+	/*
+	 * Consuming preload buffer from non-process context breaks preload
+	 * allocation guarantee.  Disallow usage from those contexts.
+	 */
+	WARN_ON_ONCE(in_interrupt());
+	might_sleep_if(gfp_mask & __GFP_WAIT);
+
+	preempt_disable();
 
-	rv = idr_get_new_above_int(idp, ptr, 0);
 	/*
-	 * This is a cheap hack until the IDR code can be fixed to
-	 * return proper error values.
+	 * idr_alloc() is likely to succeed w/o full idr_layer buffer and
+	 * return value from idr_alloc() needs to be checked for failure
+	 * anyway.  Silently give up if allocation fails.  The caller can
+	 * treat failures from idr_alloc() as if idr_alloc() were called
+	 * with @gfp_mask which should be enough.
 	 */
-	if (rv < 0)
-		return _idr_rc_to_errno(rv);
-	*id = rv;
-	return 0;
+	while (__this_cpu_read(idr_preload_cnt) < MAX_IDR_FREE) {
+		struct idr_layer *new;
+
+		preempt_enable();
+		new = kmem_cache_zalloc(idr_layer_cache, gfp_mask);
+		preempt_disable();
+		if (!new)
+			break;
+
+		/* link the new one to per-cpu preload list */
+		new->ary[0] = __this_cpu_read(idr_preload_head);
+		__this_cpu_write(idr_preload_head, new);
+		__this_cpu_inc(idr_preload_cnt);
+	}
+}
+EXPORT_SYMBOL(idr_preload);
+
+/**
+ * idr_alloc - allocate new idr entry
+ * @idr: the (initialized) idr
+ * @ptr: pointer to be associated with the new id
+ * @start: the minimum id (inclusive)
+ * @end: the maximum id (exclusive, <= 0 for max)
+ * @gfp_mask: memory allocation flags
+ *
+ * Allocate an id in [start, end) and associate it with @ptr.  If no ID is
+ * available in the specified range, returns -ENOSPC.  On memory allocation
+ * failure, returns -ENOMEM.
+ *
+ * Note that @end is treated as max when <= 0.  This is to always allow
+ * using @start + N as @end as long as N is inside integer range.
+ *
+ * The user is responsible for exclusively synchronizing all operations
+ * which may modify @idr.  However, read-only accesses such as idr_find()
+ * or iteration can be performed under RCU read lock provided the user
+ * destroys @ptr in RCU-safe way after removal from idr.
+ */
+int idr_alloc(struct idr *idr, void *ptr, int start, int end, gfp_t gfp_mask)
+{
+	int max = end > 0 ? end - 1 : INT_MAX;	/* inclusive upper limit */
+	struct idr_layer *pa[MAX_IDR_LEVEL + 1];
+	int id;
+
+	might_sleep_if(gfp_mask & __GFP_WAIT);
+
+	/* sanity checks */
+	if (WARN_ON_ONCE(start < 0))
+		return -EINVAL;
+	if (unlikely(max < start))
+		return -ENOSPC;
+
+	/* allocate id */
+	id = idr_get_empty_slot(idr, start, pa, gfp_mask, NULL);
+	if (unlikely(id < 0))
+		return id;
+	if (unlikely(id > max))
+		return -ENOSPC;
+
+	idr_fill_slot(idr, ptr, id, pa);
+	return id;
 }
-EXPORT_SYMBOL(idr_get_new);
+EXPORT_SYMBOL_GPL(idr_alloc);
+
+/**
+ * idr_alloc_cyclic - allocate new idr entry in a cyclical fashion
+ * @idr: the (initialized) idr
+ * @ptr: pointer to be associated with the new id
+ * @start: the minimum id (inclusive)
+ * @end: the maximum id (exclusive, <= 0 for max)
+ * @gfp_mask: memory allocation flags
+ *
+ * Essentially the same as idr_alloc, but prefers to allocate progressively
+ * higher ids if it can. If the "cur" counter wraps, then it will start again
+ * at the "start" end of the range and allocate one that has already been used.
+ */
+int idr_alloc_cyclic(struct idr *idr, void *ptr, int start, int end,
+			gfp_t gfp_mask)
+{
+	int id;
+
+	id = idr_alloc(idr, ptr, max(start, idr->cur), end, gfp_mask);
+	if (id == -ENOSPC)
+		id = idr_alloc(idr, ptr, start, end, gfp_mask);
+
+	if (likely(id >= 0))
+		idr->cur = id + 1;
+	return id;
+}
+EXPORT_SYMBOL(idr_alloc_cyclic);
 
 static void idr_remove_warning(int id)
 {
@@ -357,7 +532,7 @@
 static void sub_remove(struct idr *idp, int shift, int id)
 {
 	struct idr_layer *p = idp->top;
-	struct idr_layer **pa[MAX_LEVEL];
+	struct idr_layer **pa[MAX_IDR_LEVEL + 1];
 	struct idr_layer ***paa = &pa[0];
 	struct idr_layer *to_free;
 	int n;
@@ -367,26 +542,26 @@
 
 	while ((shift > 0) && p) {
 		n = (id >> shift) & IDR_MASK;
-		__clear_bit(n, &p->bitmap);
+		__clear_bit(n, p->bitmap);
 		*++paa = &p->ary[n];
 		p = p->ary[n];
 		shift -= IDR_BITS;
 	}
 	n = id & IDR_MASK;
-	if (likely(p != NULL && test_bit(n, &p->bitmap))){
-		__clear_bit(n, &p->bitmap);
+	if (likely(p != NULL && test_bit(n, p->bitmap))) {
+		__clear_bit(n, p->bitmap);
 		rcu_assign_pointer(p->ary[n], NULL);
 		to_free = NULL;
 		while(*paa && ! --((**paa)->count)){
 			if (to_free)
-				free_layer(to_free);
+				free_layer(idp, to_free);
 			to_free = **paa;
 			**paa-- = NULL;
 		}
 		if (!*paa)
 			idp->layers = 0;
 		if (to_free)
-			free_layer(to_free);
+			free_layer(idp, to_free);
 	} else
 		idr_remove_warning(id);
 }
@@ -401,8 +576,8 @@
 	struct idr_layer *p;
 	struct idr_layer *to_free;
 
-	/* Mask off upper bits we don't use for the search. */
-	id &= MAX_ID_MASK;
+	if (id < 0)
+		return;
 
 	sub_remove(idp, (idp->layers - 1) * IDR_BITS, id);
 	if (idp->top && idp->top->count == 1 && (idp->layers > 1) &&
@@ -417,10 +592,11 @@
 		p = idp->top->ary[0];
 		rcu_assign_pointer(idp->top, p);
 		--idp->layers;
-		to_free->bitmap = to_free->count = 0;
-		free_layer(to_free);
+		to_free->count = 0;
+		bitmap_clear(to_free->bitmap, 0, IDR_SIZE);
+		free_layer(idp, to_free);
 	}
-	while (idp->id_free_cnt >= IDR_FREE_MAX) {
+	while (idp->id_free_cnt >= MAX_IDR_FREE) {
 		p = get_from_free_list(idp);
 		/*
 		 * Note: we don't call the rcu callback here, since the only
@@ -433,34 +609,21 @@
 }
 EXPORT_SYMBOL(idr_remove);
 
-/**
- * idr_remove_all - remove all ids from the given idr tree
- * @idp: idr handle
- *
- * idr_destroy() only frees up unused, cached idp_layers, but this
- * function will remove all id mappings and leave all idp_layers
- * unused.
- *
- * A typical clean-up sequence for objects stored in an idr tree will
- * use idr_for_each() to free all objects, if necessay, then
- * idr_remove_all() to remove all ids, and idr_destroy() to free
- * up the cached idr_layers.
- */
-void idr_remove_all(struct idr *idp)
+void __idr_remove_all(struct idr *idp)
 {
 	int n, id, max;
 	int bt_mask;
 	struct idr_layer *p;
-	struct idr_layer *pa[MAX_LEVEL];
+	struct idr_layer *pa[MAX_IDR_LEVEL + 1];
 	struct idr_layer **paa = &pa[0];
 
 	n = idp->layers * IDR_BITS;
 	p = idp->top;
 	rcu_assign_pointer(idp->top, NULL);
-	max = 1 << n;
+	max = idr_max(idp->layers);
 
 	id = 0;
-	while (id < max) {
+	while (id >= 0 && id <= max) {
 		while (n > IDR_BITS && p) {
 			n -= IDR_BITS;
 			*paa++ = p;
@@ -472,21 +635,32 @@
 		/* Get the highest bit that the above add changed from 0->1. */
 		while (n < fls(id ^ bt_mask)) {
 			if (p)
-				free_layer(p);
+				free_layer(idp, p);
 			n += IDR_BITS;
 			p = *--paa;
 		}
 	}
 	idp->layers = 0;
 }
-EXPORT_SYMBOL(idr_remove_all);
+EXPORT_SYMBOL(__idr_remove_all);
 
 /**
  * idr_destroy - release all cached layers within an idr tree
  * @idp: idr handle
+ *
+ * Free all id mappings and all idp_layers.  After this function, @idp is
+ * completely unused and can be freed / recycled.  The caller is
+ * responsible for ensuring that no one else accesses @idp during or after
+ * idr_destroy().
+ *
+ * A typical clean-up sequence for objects stored in an idr tree will use
+ * idr_for_each() to free all objects, if necessay, then idr_destroy() to
+ * free up the id mappings and cached idr_layers.
  */
 void idr_destroy(struct idr *idp)
 {
+	__idr_remove_all(idp);
+
 	while (idp->id_free_cnt) {
 		struct idr_layer *p = get_from_free_list(idp);
 		kmem_cache_free(idr_layer_cache, p);
@@ -494,32 +668,20 @@
 }
 EXPORT_SYMBOL(idr_destroy);
 
-/**
- * idr_find - return pointer for given id
- * @idp: idr handle
- * @id: lookup key
- *
- * Return the pointer given the id it has been registered with.  A %NULL
- * return indicates that @id is not valid or you passed %NULL in
- * idr_get_new().
- *
- * This function can be called under rcu_read_lock(), given that the leaf
- * pointers lifetimes are correctly managed.
- */
-void *idr_find(struct idr *idp, int id)
+void *idr_find_slowpath(struct idr *idp, int id)
 {
 	int n;
 	struct idr_layer *p;
 
+	if (id < 0)
+		return NULL;
+
 	p = rcu_dereference_raw(idp->top);
 	if (!p)
 		return NULL;
 	n = (p->layer+1) * IDR_BITS;
 
-	/* Mask off upper bits we don't use for the search. */
-	id &= MAX_ID_MASK;
-
-	if (id >= (1 << n))
+	if (id > idr_max(p->layer + 1))
 		return NULL;
 	BUG_ON(n == 0);
 
@@ -530,7 +692,7 @@
 	}
 	return((void *)p);
 }
-EXPORT_SYMBOL(idr_find);
+EXPORT_SYMBOL(idr_find_slowpath);
 
 /**
  * idr_for_each - iterate through all stored pointers
@@ -555,15 +717,15 @@
 {
 	int n, id, max, error = 0;
 	struct idr_layer *p;
-	struct idr_layer *pa[MAX_LEVEL];
+	struct idr_layer *pa[MAX_IDR_LEVEL + 1];
 	struct idr_layer **paa = &pa[0];
 
 	n = idp->layers * IDR_BITS;
 	p = rcu_dereference_raw(idp->top);
-	max = 1 << n;
+	max = idr_max(idp->layers);
 
 	id = 0;
-	while (id < max) {
+	while (id >= 0 && id <= max) {
 		while (n > 0 && p) {
 			n -= IDR_BITS;
 			*paa++ = p;
@@ -601,7 +763,7 @@
  */
 void *idr_get_next(struct idr *idp, int *nextidp)
 {
-	struct idr_layer *p, *pa[MAX_LEVEL];
+	struct idr_layer *p, *pa[MAX_IDR_LEVEL + 1];
 	struct idr_layer **paa = &pa[0];
 	int id = *nextidp;
 	int n, max;
@@ -611,9 +773,9 @@
 	if (!p)
 		return NULL;
 	n = (p->layer + 1) * IDR_BITS;
-	max = 1 << n;
+	max = idr_max(p->layer + 1);
 
-	while (id < max) {
+	while (id >= 0 && id <= max) {
 		while (n > 0 && p) {
 			n -= IDR_BITS;
 			*paa++ = p;
@@ -625,7 +787,14 @@
 			return p;
 		}
 
-		id += 1 << n;
+		/*
+		 * Proceed to the next layer at the current level.  Unlike
+		 * idr_for_each(), @id isn't guaranteed to be aligned to
+		 * layer boundary at this point and adding 1 << n may
+		 * incorrectly skip IDs.  Make sure we jump to the
+		 * beginning of the next layer using round_up().
+		 */
+		id = round_up(id + 1, 1 << n);
 		while (n < fls(id)) {
 			n += IDR_BITS;
 			p = *--paa;
@@ -653,14 +822,15 @@
 	int n;
 	struct idr_layer *p, *old_p;
 
+	if (id < 0)
+		return ERR_PTR(-EINVAL);
+
 	p = idp->top;
 	if (!p)
 		return ERR_PTR(-EINVAL);
 
 	n = (p->layer+1) * IDR_BITS;
 
-	id &= MAX_ID_MASK;
-
 	if (id >= (1 << n))
 		return ERR_PTR(-EINVAL);
 
@@ -671,7 +841,7 @@
 	}
 
 	n = id & IDR_MASK;
-	if (unlikely(p == NULL || !test_bit(n, &p->bitmap)))
+	if (unlikely(p == NULL || !test_bit(n, p->bitmap)))
 		return ERR_PTR(-ENOENT);
 
 	old_p = p->ary[n];
@@ -745,7 +915,7 @@
 int ida_pre_get(struct ida *ida, gfp_t gfp_mask)
 {
 	/* allocate idr_layers */
-	if (!idr_pre_get(&ida->idr, gfp_mask))
+	if (!__idr_pre_get(&ida->idr, gfp_mask))
 		return 0;
 
 	/* allocate free_bitmap */
@@ -780,7 +950,7 @@
  */
 int ida_get_new_above(struct ida *ida, int starting_id, int *p_id)
 {
-	struct idr_layer *pa[MAX_LEVEL];
+	struct idr_layer *pa[MAX_IDR_LEVEL + 1];
 	struct ida_bitmap *bitmap;
 	unsigned long flags;
 	int idr_id = starting_id / IDA_BITMAP_BITS;
@@ -789,11 +959,11 @@
 
  restart:
 	/* get vacant slot */
-	t = idr_get_empty_slot(&ida->idr, idr_id, pa);
+	t = idr_get_empty_slot(&ida->idr, idr_id, pa, 0, &ida->idr);
 	if (t < 0)
-		return _idr_rc_to_errno(t);
+		return t == -ENOMEM ? -EAGAIN : t;
 
-	if (t * IDA_BITMAP_BITS >= MAX_ID_BIT)
+	if (t * IDA_BITMAP_BITS >= MAX_IDR_BIT)
 		return -ENOSPC;
 
 	if (t != idr_id)
@@ -827,7 +997,7 @@
 	}
 
 	id = idr_id * IDA_BITMAP_BITS + t;
-	if (id >= MAX_ID_BIT)
+	if (id >= MAX_IDR_BIT)
 		return -ENOSPC;
 
 	__set_bit(t, bitmap->bitmap);
@@ -852,25 +1022,6 @@
 EXPORT_SYMBOL(ida_get_new_above);
 
 /**
- * ida_get_new - allocate new ID
- * @ida:	idr handle
- * @p_id:	pointer to the allocated handle
- *
- * Allocate new ID.  It should be called with any required locks.
- *
- * If memory is required, it will return %-EAGAIN, you should unlock
- * and go back to the idr_pre_get() call.  If the idr is full, it will
- * return %-ENOSPC.
- *
- * @p_id returns a value in the range %0 ... %0x7fffffff.
- */
-int ida_get_new(struct ida *ida, int *p_id)
-{
-	return ida_get_new_above(ida, 0, p_id);
-}
-EXPORT_SYMBOL(ida_get_new);
-
-/**
  * ida_remove - remove the given ID
  * @ida:	ida handle
  * @id:		ID to free
@@ -887,7 +1038,7 @@
 	/* clear full bits while looking up the leaf idr_layer */
 	while ((shift > 0) && p) {
 		n = (idr_id >> shift) & IDR_MASK;
-		__clear_bit(n, &p->bitmap);
+		__clear_bit(n, p->bitmap);
 		p = p->ary[n];
 		shift -= IDR_BITS;
 	}
@@ -896,7 +1047,7 @@
 		goto err;
 
 	n = idr_id & IDR_MASK;
-	__clear_bit(n, &p->bitmap);
+	__clear_bit(n, p->bitmap);
 
 	bitmap = (void *)p->ary[n];
 	if (!test_bit(offset, bitmap->bitmap))
@@ -905,7 +1056,7 @@
 	/* update bitmap and remove it if empty */
 	__clear_bit(offset, bitmap->bitmap);
 	if (--bitmap->nr_busy == 0) {
-		__set_bit(n, &p->bitmap);	/* to please idr_remove() */
+		__set_bit(n, p->bitmap);	/* to please idr_remove() */
 		idr_remove(&ida->idr, idr_id);
 		free_bitmap(ida, bitmap);
 	}
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/lib/kobject.c linux-linaro-3.4-2012.05-1_cavium/lib/kobject.c
--- linux-linaro-3.4-2012.05-1_original/lib/kobject.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/lib/kobject.c	2015-04-21 14:24:43.374116000 +0800
@@ -589,10 +589,10 @@
 void kobject_put(struct kobject *kobj)
 {
 	if (kobj) {
-		if (!kobj->state_initialized)
+		/*if (!kobj->state_initialized)
 			WARN(1, KERN_WARNING "kobject: '%s' (%p): is not "
 			       "initialized, yet kobject_put() is being "
-			       "called.\n", kobject_name(kobj), kobj);
+			       "called.\n", kobject_name(kobj), kobj);*/
 		kref_put(&kobj->kref, kobject_release);
 	}
 }
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/lib/scatterlist.c linux-linaro-3.4-2012.05-1_cavium/lib/scatterlist.c
--- linux-linaro-3.4-2012.05-1_original/lib/scatterlist.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/lib/scatterlist.c	2014-09-12 15:59:37.348052000 +0800
@@ -39,6 +39,25 @@
 EXPORT_SYMBOL(sg_next);
 
 /**
+ * sg_nents - return total count of entries in scatterlist
+ * @sg:		The scatterlist
+ *
+ * Description:
+ * Allows to know how many entries are in sg, taking into acount
+ * chaining as well
+ *
+ **/
+int sg_nents(struct scatterlist *sg)
+{
+	int nents;
+	for (nents = 0; sg; sg = sg_next(sg))
+		nents++;
+	return nents;
+}
+EXPORT_SYMBOL(sg_nents);
+
+
+/**
  * sg_last - return the last scatterlist entry in a list
  * @sgl:	First entry in the scatterlist
  * @nents:	Number of entries in the scatterlist
@@ -229,7 +248,8 @@
 	unsigned int left;
 
 #ifndef ARCH_HAS_SG_CHAIN
-	BUG_ON(nents > max_ents);
+	if (WARN_ON_ONCE(nents > max_ents))
+		return -EINVAL;
 #endif
 
 	memset(table, 0, sizeof(*table));
@@ -279,14 +299,6 @@
 		if (!left)
 			sg_mark_end(&sg[sg_size - 1]);
 
-		/*
-		 * only really needed for mempool backed sg allocations (like
-		 * SCSI), a possible improvement here would be to pass the
-		 * table pointer into the allocator and let that clear these
-		 * flags
-		 */
-		gfp_mask &= ~__GFP_WAIT;
-		gfp_mask |= __GFP_HIGH;
 		prv = sg;
 	} while (left);
 
@@ -319,6 +331,106 @@
 EXPORT_SYMBOL(sg_alloc_table);
 
 /**
+ * sg_alloc_table_from_pages - Allocate and initialize an sg table from
+ *			       an array of pages
+ * @sgt:	The sg table header to use
+ * @pages:	Pointer to an array of page pointers
+ * @n_pages:	Number of pages in the pages array
+ * @offset:     Offset from start of the first page to the start of a buffer
+ * @size:       Number of valid bytes in the buffer (after offset)
+ * @gfp_mask:	GFP allocation mask
+ *
+ *  Description:
+ *    Allocate and initialize an sg table from a list of pages. Contiguous
+ *    ranges of the pages are squashed into a single scatterlist node. A user
+ *    may provide an offset at a start and a size of valid data in a buffer
+ *    specified by the page array. The returned sg table is released by
+ *    sg_free_table.
+ *
+ * Returns:
+ *   0 on success, negative error on failure
+ */
+int sg_alloc_table_from_pages(struct sg_table *sgt,
+	struct page **pages, unsigned int n_pages,
+	unsigned long offset, unsigned long size,
+	gfp_t gfp_mask)
+{
+	unsigned int chunks;
+	unsigned int i;
+	unsigned int cur_page;
+	int ret;
+	struct scatterlist *s;
+
+	/* compute number of contiguous chunks */
+	chunks = 1;
+	for (i = 1; i < n_pages; ++i)
+		if (page_to_pfn(pages[i]) != page_to_pfn(pages[i - 1]) + 1)
+			++chunks;
+
+	ret = sg_alloc_table(sgt, chunks, gfp_mask);
+	if (unlikely(ret))
+		return ret;
+
+	/* merging chunks and putting them into the scatterlist */
+	cur_page = 0;
+	for_each_sg(sgt->sgl, s, sgt->orig_nents, i) {
+		unsigned long chunk_size;
+		unsigned int j;
+
+		/* look for the end of the current chunk */
+		for (j = cur_page + 1; j < n_pages; ++j)
+			if (page_to_pfn(pages[j]) !=
+			    page_to_pfn(pages[j - 1]) + 1)
+				break;
+
+		chunk_size = ((j - cur_page) << PAGE_SHIFT) - offset;
+		sg_set_page(s, pages[cur_page], min(size, chunk_size), offset);
+		size -= chunk_size;
+		offset = 0;
+		cur_page = j;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(sg_alloc_table_from_pages);
+
+void __sg_page_iter_start(struct sg_page_iter *piter,
+			  struct scatterlist *sglist, unsigned int nents,
+			  unsigned long pgoffset)
+{
+	piter->__pg_advance = 0;
+	piter->__nents = nents;
+
+	piter->sg = sglist;
+	piter->sg_pgoffset = pgoffset;
+}
+EXPORT_SYMBOL(__sg_page_iter_start);
+
+static int sg_page_count(struct scatterlist *sg)
+{
+	return PAGE_ALIGN(sg->offset + sg->length) >> PAGE_SHIFT;
+}
+
+bool __sg_page_iter_next(struct sg_page_iter *piter)
+{
+	if (!piter->__nents || !piter->sg)
+		return false;
+
+	piter->sg_pgoffset += piter->__pg_advance;
+	piter->__pg_advance = 1;
+
+	while (piter->sg_pgoffset >= sg_page_count(piter->sg)) {
+		piter->sg_pgoffset -= sg_page_count(piter->sg);
+		piter->sg = sg_next(piter->sg);
+		if (!--piter->__nents || !piter->sg)
+			return false;
+	}
+
+	return true;
+}
+EXPORT_SYMBOL(__sg_page_iter_next);
+
+/**
  * sg_miter_start - start mapping iteration over a sg list
  * @miter: sg mapping iter to be started
  * @sgl: sg list to iterate over
@@ -335,9 +447,7 @@
 {
 	memset(miter, 0, sizeof(struct sg_mapping_iter));
 
-	miter->__sg = sgl;
-	miter->__nents = nents;
-	miter->__offset = 0;
+	__sg_page_iter_start(&miter->piter, sgl, nents, 0);
 	WARN_ON(!(flags & (SG_MITER_TO_SG | SG_MITER_FROM_SG)));
 	miter->__flags = flags;
 }
@@ -348,14 +458,13 @@
  * @miter: sg mapping iter to proceed
  *
  * Description:
- *   Proceeds @miter@ to the next mapping.  @miter@ should have been
- *   started using sg_miter_start().  On successful return,
- *   @miter@->page, @miter@->addr and @miter@->length point to the
- *   current mapping.
+ *   Proceeds @miter to the next mapping.  @miter should have been started
+ *   using sg_miter_start().  On successful return, @miter->page,
+ *   @miter->addr and @miter->length point to the current mapping.
  *
  * Context:
- *   IRQ disabled if SG_MITER_ATOMIC.  IRQ must stay disabled till
- *   @miter@ is stopped.  May sleep if !SG_MITER_ATOMIC.
+ *   Preemption disabled if SG_MITER_ATOMIC.  Preemption must stay disabled
+ *   till @miter is stopped.  May sleep if !SG_MITER_ATOMIC.
  *
  * Returns:
  *   true if @miter contains the next mapping.  false if end of sg
@@ -363,36 +472,35 @@
  */
 bool sg_miter_next(struct sg_mapping_iter *miter)
 {
-	unsigned int off, len;
-
-	/* check for end and drop resources from the last iteration */
-	if (!miter->__nents)
-		return false;
-
 	sg_miter_stop(miter);
 
-	/* get to the next sg if necessary.  __offset is adjusted by stop */
-	while (miter->__offset == miter->__sg->length) {
-		if (--miter->__nents) {
-			miter->__sg = sg_next(miter->__sg);
-			miter->__offset = 0;
-		} else
+	/*
+	 * Get to the next page if necessary.
+	 * __remaining, __offset is adjusted by sg_miter_stop
+	 */
+	if (!miter->__remaining) {
+		struct scatterlist *sg;
+		unsigned long pgoffset;
+
+		if (!__sg_page_iter_next(&miter->piter))
 			return false;
-	}
 
-	/* map the next page */
-	off = miter->__sg->offset + miter->__offset;
-	len = miter->__sg->length - miter->__offset;
-
-	miter->page = nth_page(sg_page(miter->__sg), off >> PAGE_SHIFT);
-	off &= ~PAGE_MASK;
-	miter->length = min_t(unsigned int, len, PAGE_SIZE - off);
-	miter->consumed = miter->length;
+		sg = miter->piter.sg;
+		pgoffset = miter->piter.sg_pgoffset;
+
+		miter->__offset = pgoffset ? 0 : sg->offset;
+		miter->__remaining = sg->offset + sg->length -
+				(pgoffset << PAGE_SHIFT) - miter->__offset;
+		miter->__remaining = min_t(unsigned long, miter->__remaining,
+					   PAGE_SIZE - miter->__offset);
+	}
+	miter->page = sg_page_iter_page(&miter->piter);
+	miter->consumed = miter->length = miter->__remaining;
 
 	if (miter->__flags & SG_MITER_ATOMIC)
-		miter->addr = kmap_atomic(miter->page) + off;
+		miter->addr = kmap_atomic(miter->page) + miter->__offset;
 	else
-		miter->addr = kmap(miter->page) + off;
+		miter->addr = kmap(miter->page) + miter->__offset;
 
 	return true;
 }
@@ -409,7 +517,8 @@
  *   resources (kmap) need to be released during iteration.
  *
  * Context:
- *   IRQ disabled if the SG_MITER_ATOMIC is set.  Don't care otherwise.
+ *   Preemption disabled if the SG_MITER_ATOMIC is set.  Don't care
+ *   otherwise.
  */
 void sg_miter_stop(struct sg_mapping_iter *miter)
 {
@@ -418,12 +527,14 @@
 	/* drop resources from the last iteration */
 	if (miter->addr) {
 		miter->__offset += miter->consumed;
+		miter->__remaining -= miter->consumed;
 
-		if (miter->__flags & SG_MITER_TO_SG)
+		if ((miter->__flags & SG_MITER_TO_SG) &&
+		    !PageSlab(miter->page))
 			flush_kernel_dcache_page(miter->page);
 
 		if (miter->__flags & SG_MITER_ATOMIC) {
-			WARN_ON(!irqs_disabled());
+			WARN_ON_ONCE(preemptible());
 			kunmap_atomic(miter->addr);
 		} else
 			kunmap(miter->page);
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/Makefile linux-linaro-3.4-2012.05-1_cavium/Makefile
--- linux-linaro-3.4-2012.05-1_original/Makefile	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/Makefile	2014-11-28 13:55:40.396822000 +0800
@@ -192,8 +192,8 @@
 # Default value for CROSS_COMPILE is not to prefix executables
 # Note: Some architectures assign CROSS_COMPILE in their arch/*/Makefile
 export KBUILD_BUILDHOST := $(SUBARCH)
-ARCH		?= $(SUBARCH)
-CROSS_COMPILE	?= $(CONFIG_CROSS_COMPILE:"%"=%)
+ARCH		?= arm
+CROSS_COMPILE	?= arm-linux-gnueabihf-
 
 # Architecture as present in compile.h
 UTS_MACHINE 	:= $(ARCH)
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/net/core/dev.c linux-linaro-3.4-2012.05-1_cavium/net/core/dev.c
--- linux-linaro-3.4-2012.05-1_original/net/core/dev.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/net/core/dev.c	2014-07-29 17:28:38.819972000 +0800
@@ -281,6 +281,10 @@
 DEFINE_PER_CPU_ALIGNED(struct softnet_data, softnet_data);
 EXPORT_PER_CPU_SYMBOL(softnet_data);
 
+#ifdef CONFIG_PUREVU
+uint32_t (*cvm_netHD_rx_hook)(struct sk_buff *) = NULL;
+#endif
+
 #ifdef CONFIG_LOCKDEP
 /*
  * register_netdevice() inits txq->_xmit_lock and sets lockdep class
@@ -2922,6 +2926,13 @@
 {
 	int ret;
 
+#ifdef CONFIG_PUREVU
+	if (cvm_netHD_rx_hook) {
+	    if (!cvm_netHD_rx_hook(skb))
+		return NET_RX_SUCCESS;
+	}
+#endif
+
 	/* if netpoll wants it, pretend we never saw it */
 	if (netpoll_rx(skb))
 		return NET_RX_DROP;
@@ -3288,6 +3299,13 @@
  */
 int netif_receive_skb(struct sk_buff *skb)
 {
+#ifdef CONFIG_PUREVU
+	if (cvm_netHD_rx_hook) {
+	    if (!cvm_netHD_rx_hook(skb))
+		return NET_RX_SUCCESS;
+	}
+#endif
+
 	net_timestamp_check(netdev_tstamp_prequeue, skb);
 
 	if (skb_defer_rx_timestamp(skb))
@@ -3313,6 +3331,9 @@
 	return __netif_receive_skb(skb);
 }
 EXPORT_SYMBOL(netif_receive_skb);
+#ifdef CONFIG_PUREVU
+EXPORT_SYMBOL(cvm_netHD_rx_hook);
+#endif
 
 /* Network device is going away, flush any packets still pending
  * Called with irqs disabled.
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/net/ipv4/route.c linux-linaro-3.4-2012.05-1_cavium/net/ipv4/route.c
--- linux-linaro-3.4-2012.05-1_original/net/ipv4/route.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/net/ipv4/route.c	2014-07-29 17:28:38.819972000 +0800
@@ -2268,6 +2268,13 @@
 	if (!in_dev)
 		goto out;
 
+#ifdef CONFIG_PUREVU
+	/* Locally deliver looped back packets. */
+
+	if (ipv4_is_loopback(daddr))
+		goto local_input;
+#endif
+
 	/* Check for the most weird martians, which can be not detected
 	   by fib_lookup.
 	 */
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/scripts/Makefile.lib linux-linaro-3.4-2012.05-1_cavium/scripts/Makefile.lib
--- linux-linaro-3.4-2012.05-1_original/scripts/Makefile.lib	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/scripts/Makefile.lib	2014-07-29 17:28:38.819972000 +0800
@@ -308,7 +308,7 @@
 # ---------------------------------------------------------------------------
 
 MKIMAGE := $(srctree)/scripts/mkuboot.sh
-
+SVN_VER=$(shell svnversion -n)
 # SRCARCH just happens to match slightly more than ARCH (on sparc), so reduces
 # the number of overrides in arch makefiles
 UIMAGE_ARCH ?= $(SRCARCH)
@@ -317,7 +317,7 @@
 UIMAGE_TYPE ?= kernel
 UIMAGE_LOADADDR ?= arch_must_set_this
 UIMAGE_ENTRYADDR ?= $(UIMAGE_LOADADDR)
-UIMAGE_NAME ?= 'Linux-$(KERNELRELEASE)'
+UIMAGE_NAME ?= 'Linux-$(KERNELRELEASE)-svn-r$(SVN_VER)'
 UIMAGE_IN ?= $<
 UIMAGE_OUT ?= $@
 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/security/apparmor/apparmorfs.c linux-linaro-3.4-2012.05-1_cavium/security/apparmor/apparmorfs.c
--- linux-linaro-3.4-2012.05-1_original/security/apparmor/apparmorfs.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/security/apparmor/apparmorfs.c	2014-07-29 17:28:38.819972000 +0800
@@ -438,6 +438,7 @@
 static struct aa_fs_entry aa_fs_entry_features[] = {
 	AA_FS_DIR("domain",			aa_fs_entry_domain),
 	AA_FS_DIR("file",			aa_fs_entry_file),
+	AA_FS_DIR("network",			aa_fs_entry_network),
 	AA_FS_DIR("mount",			aa_fs_entry_mount),
 	AA_FS_DIR("namespaces",			aa_fs_entry_namespaces),
 	AA_FS_FILE_U64("capability",		VFS_CAP_FLAGS_MASK),
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/security/apparmor/.gitignore linux-linaro-3.4-2012.05-1_cavium/security/apparmor/.gitignore
--- linux-linaro-3.4-2012.05-1_original/security/apparmor/.gitignore	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/security/apparmor/.gitignore	2014-07-29 17:28:38.819972000 +0800
@@ -1,6 +1,6 @@
 #
 # Generated include files
 #
-af_names.h
+net_names.h
 capability_names.h
 rlim_names.h
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/security/apparmor/include/audit.h linux-linaro-3.4-2012.05-1_cavium/security/apparmor/include/audit.h
--- linux-linaro-3.4-2012.05-1_original/security/apparmor/include/audit.h	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/security/apparmor/include/audit.h	2014-07-29 17:28:38.819972000 +0800
@@ -137,6 +137,10 @@
 			u32 denied;
 			uid_t ouid;
 		} fs;
+		struct {
+			int type, protocol;
+			struct sock *sk;
+		} net;
 	};
 };
 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/security/apparmor/include/net.h linux-linaro-3.4-2012.05-1_cavium/security/apparmor/include/net.h
--- linux-linaro-3.4-2012.05-1_original/security/apparmor/include/net.h	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/security/apparmor/include/net.h	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,44 @@
+/*
+ * AppArmor security module
+ *
+ * This file contains AppArmor network mediation definitions.
+ *
+ * Copyright (C) 1998-2008 Novell/SUSE
+ * Copyright 2009-2012 Canonical Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ */
+
+#ifndef __AA_NET_H
+#define __AA_NET_H
+
+#include <net/sock.h>
+
+#include "apparmorfs.h"
+
+/* struct aa_net - network confinement data
+ * @allowed: basic network families permissions
+ * @audit_network: which network permissions to force audit
+ * @quiet_network: which network permissions to quiet rejects
+ */
+struct aa_net {
+	u16 allow[AF_MAX];
+	u16 audit[AF_MAX];
+	u16 quiet[AF_MAX];
+};
+
+extern struct aa_fs_entry aa_fs_entry_network[];
+
+extern int aa_net_perm(int op, struct aa_profile *profile, u16 family,
+		       int type, int protocol, struct sock *sk);
+extern int aa_revalidate_sk(int op, struct sock *sk);
+
+static inline void aa_free_net_rules(struct aa_net *new)
+{
+	/* NOP */
+}
+
+#endif /* __AA_NET_H */
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/security/apparmor/include/policy.h linux-linaro-3.4-2012.05-1_cavium/security/apparmor/include/policy.h
--- linux-linaro-3.4-2012.05-1_original/security/apparmor/include/policy.h	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/security/apparmor/include/policy.h	2014-07-29 17:28:38.819972000 +0800
@@ -27,6 +27,7 @@
 #include "capability.h"
 #include "domain.h"
 #include "file.h"
+#include "net.h"
 #include "resource.h"
 
 extern const char *const profile_mode_names[];
@@ -157,6 +158,7 @@
  * @policy: general match rules governing policy
  * @file: The set of rules governing basic file access and domain transitions
  * @caps: capabilities for the profile
+ * @net: network controls for the profile
  * @rlimits: rlimits for the profile
  *
  * The AppArmor profile contains the basic confinement data.  Each profile
@@ -194,6 +196,7 @@
 	struct aa_policydb policy;
 	struct aa_file_rules file;
 	struct aa_caps caps;
+	struct aa_net net;
 	struct aa_rlimit rlimits;
 };
 
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/security/apparmor/lsm.c linux-linaro-3.4-2012.05-1_cavium/security/apparmor/lsm.c
--- linux-linaro-3.4-2012.05-1_original/security/apparmor/lsm.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/security/apparmor/lsm.c	2014-07-29 17:28:38.819972000 +0800
@@ -32,6 +32,7 @@
 #include "include/context.h"
 #include "include/file.h"
 #include "include/ipc.h"
+#include "include/net.h"
 #include "include/path.h"
 #include "include/policy.h"
 #include "include/procattr.h"
@@ -677,6 +678,104 @@
 	return error;
 }
 
+static int apparmor_socket_create(int family, int type, int protocol, int kern)
+{
+	struct aa_profile *profile;
+	int error = 0;
+
+	if (kern)
+		return 0;
+
+	profile = __aa_current_profile();
+	if (!unconfined(profile))
+		error = aa_net_perm(OP_CREATE, profile, family, type, protocol,
+				    NULL);
+	return error;
+}
+
+static int apparmor_socket_bind(struct socket *sock,
+				struct sockaddr *address, int addrlen)
+{
+	struct sock *sk = sock->sk;
+
+	return aa_revalidate_sk(OP_BIND, sk);
+}
+
+static int apparmor_socket_connect(struct socket *sock,
+				   struct sockaddr *address, int addrlen)
+{
+	struct sock *sk = sock->sk;
+
+	return aa_revalidate_sk(OP_CONNECT, sk);
+}
+
+static int apparmor_socket_listen(struct socket *sock, int backlog)
+{
+	struct sock *sk = sock->sk;
+
+	return aa_revalidate_sk(OP_LISTEN, sk);
+}
+
+static int apparmor_socket_accept(struct socket *sock, struct socket *newsock)
+{
+	struct sock *sk = sock->sk;
+
+	return aa_revalidate_sk(OP_ACCEPT, sk);
+}
+
+static int apparmor_socket_sendmsg(struct socket *sock,
+				   struct msghdr *msg, int size)
+{
+	struct sock *sk = sock->sk;
+
+	return aa_revalidate_sk(OP_SENDMSG, sk);
+}
+
+static int apparmor_socket_recvmsg(struct socket *sock,
+				   struct msghdr *msg, int size, int flags)
+{
+	struct sock *sk = sock->sk;
+
+	return aa_revalidate_sk(OP_RECVMSG, sk);
+}
+
+static int apparmor_socket_getsockname(struct socket *sock)
+{
+	struct sock *sk = sock->sk;
+
+	return aa_revalidate_sk(OP_GETSOCKNAME, sk);
+}
+
+static int apparmor_socket_getpeername(struct socket *sock)
+{
+	struct sock *sk = sock->sk;
+
+	return aa_revalidate_sk(OP_GETPEERNAME, sk);
+}
+
+static int apparmor_socket_getsockopt(struct socket *sock, int level,
+				      int optname)
+{
+	struct sock *sk = sock->sk;
+
+	return aa_revalidate_sk(OP_GETSOCKOPT, sk);
+}
+
+static int apparmor_socket_setsockopt(struct socket *sock, int level,
+				      int optname)
+{
+	struct sock *sk = sock->sk;
+
+	return aa_revalidate_sk(OP_SETSOCKOPT, sk);
+}
+
+static int apparmor_socket_shutdown(struct socket *sock, int how)
+{
+	struct sock *sk = sock->sk;
+
+	return aa_revalidate_sk(OP_SOCK_SHUTDOWN, sk);
+}
+
 static struct security_operations apparmor_ops = {
 	.name =				"apparmor",
 
@@ -712,6 +811,19 @@
 	.getprocattr =			apparmor_getprocattr,
 	.setprocattr =			apparmor_setprocattr,
 
+	.socket_create =		apparmor_socket_create,
+	.socket_bind =			apparmor_socket_bind,
+	.socket_connect =		apparmor_socket_connect,
+	.socket_listen =		apparmor_socket_listen,
+	.socket_accept =		apparmor_socket_accept,
+	.socket_sendmsg =		apparmor_socket_sendmsg,
+	.socket_recvmsg =		apparmor_socket_recvmsg,
+	.socket_getsockname =		apparmor_socket_getsockname,
+	.socket_getpeername =		apparmor_socket_getpeername,
+	.socket_getsockopt =		apparmor_socket_getsockopt,
+	.socket_setsockopt =		apparmor_socket_setsockopt,
+	.socket_shutdown =		apparmor_socket_shutdown,
+
 	.cred_alloc_blank =		apparmor_cred_alloc_blank,
 	.cred_free =			apparmor_cred_free,
 	.cred_prepare =			apparmor_cred_prepare,
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/security/apparmor/Makefile linux-linaro-3.4-2012.05-1_cavium/security/apparmor/Makefile
--- linux-linaro-3.4-2012.05-1_original/security/apparmor/Makefile	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/security/apparmor/Makefile	2014-07-29 17:28:38.819972000 +0800
@@ -4,7 +4,7 @@
 
 apparmor-y := apparmorfs.o audit.o capability.o context.o ipc.o lib.o match.o \
               path.o domain.o policy.o policy_unpack.o procattr.o lsm.o \
-              resource.o sid.o file.o mount.o
+              resource.o sid.o file.o net.o mount.o
 
 clean-files := capability_names.h rlim_names.h
 
@@ -19,6 +19,38 @@
 	-e 's/^\#define[ \t]+CAP_([A-Z0-9_]+)[ \t]+([0-9]+)/[\2] = "\L\1",/p';\
 	echo "};" >> $@
 
+# Build a lower case string table of address family names
+# Transform lines from
+#    define AF_LOCAL	1	/* POSIX name for AF_UNIX	*/
+#    #define AF_INET		2	/* Internet IP Protocol 	*/
+# to
+#    [1] = "local",
+#    [2] = "inet",
+#
+# and build the securityfs entries for the mapping.
+# Transforms lines from
+#    #define AF_INET		2	/* Internet IP Protocol 	*/
+# to
+#    #define AA_FS_AF_MASK "local inet"
+quiet_cmd_make-af = GEN     $@
+cmd_make-af = echo "static const char *address_family_names[] = {" > $@ ;\
+	sed $< >>$@ -r -n -e "/AF_MAX/d" -e "/AF_LOCAL/d" -e \
+	 's/^\#define[ \t]+AF_([A-Z0-9_]+)[ \t]+([0-9]+)(.*)/[\2] = "\L\1",/p';\
+	echo "};" >> $@ ;\
+	echo -n '\#define AA_FS_AF_MASK "' >> $@ ;\
+	sed -r -n 's/^\#define[ \t]+AF_([A-Z0-9_]+)[ \t]+([0-9]+)(.*)/\L\1/p'\
+	 $< | tr '\n' ' ' | sed -e 's/ $$/"\n/' >> $@
+
+# Build a lower case string table of sock type names
+# Transform lines from
+#    SOCK_STREAM	= 1,
+# to
+#    [1] = "stream",
+quiet_cmd_make-sock = GEN     $@
+cmd_make-sock = echo "static const char *sock_type_names[] = {" >> $@ ;\
+	sed $^ >>$@ -r -n \
+	-e 's/^\tSOCK_([A-Z0-9_]+)[\t]+=[ \t]+([0-9]+)(.*)/[\2] = "\L\1",/p';\
+	echo "};" >> $@
 
 # Build a lower case string table of rlimit names.
 # Transforms lines from
@@ -55,6 +87,7 @@
 	    tr '\n' ' ' | sed -e 's/ $$/"\n/' >> $@
 
 $(obj)/capability.o : $(obj)/capability_names.h
+$(obj)/net.o : $(obj)/net_names.h
 $(obj)/resource.o : $(obj)/rlim_names.h
 $(obj)/capability_names.h : $(srctree)/include/linux/capability.h \
 			    $(src)/Makefile
@@ -62,3 +95,8 @@
 $(obj)/rlim_names.h : $(srctree)/include/asm-generic/resource.h \
 		      $(src)/Makefile
 	$(call cmd,make-rlim)
+$(obj)/net_names.h : $(srctree)/include/linux/socket.h \
+		     $(srctree)/include/linux/net.h \
+		     $(src)/Makefile
+	$(call cmd,make-af)
+	$(call cmd,make-sock)
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/security/apparmor/net.c linux-linaro-3.4-2012.05-1_cavium/security/apparmor/net.c
--- linux-linaro-3.4-2012.05-1_original/security/apparmor/net.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/security/apparmor/net.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,162 @@
+/*
+ * AppArmor security module
+ *
+ * This file contains AppArmor network mediation
+ *
+ * Copyright (C) 1998-2008 Novell/SUSE
+ * Copyright 2009-2012 Canonical Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ */
+
+#include "include/apparmor.h"
+#include "include/audit.h"
+#include "include/context.h"
+#include "include/net.h"
+#include "include/policy.h"
+
+#include "net_names.h"
+
+struct aa_fs_entry aa_fs_entry_network[] = {
+	AA_FS_FILE_STRING("af_mask", AA_FS_AF_MASK),
+	{ }
+};
+
+/* audit callback for net specific fields */
+static void audit_cb(struct audit_buffer *ab, void *va)
+{
+	struct common_audit_data *sa = va;
+
+	audit_log_format(ab, " family=");
+	if (address_family_names[sa->u.net->family]) {
+		audit_log_string(ab, address_family_names[sa->u.net->family]);
+	} else {
+		audit_log_format(ab, "\"unknown(%d)\"", sa->u.net->family);
+	}
+	audit_log_format(ab, " sock_type=");
+	if (sock_type_names[sa->aad->net.type]) {
+		audit_log_string(ab, sock_type_names[sa->aad->net.type]);
+	} else {
+		audit_log_format(ab, "\"unknown(%d)\"", sa->aad->net.type);
+	}
+	audit_log_format(ab, " protocol=%d", sa->aad->net.protocol);
+}
+
+/**
+ * audit_net - audit network access
+ * @profile: profile being enforced  (NOT NULL)
+ * @op: operation being checked
+ * @family: network family
+ * @type:   network type
+ * @protocol: network protocol
+ * @sk: socket auditing is being applied to
+ * @error: error code for failure else 0
+ *
+ * Returns: %0 or sa->error else other errorcode on failure
+ */
+static int audit_net(struct aa_profile *profile, int op, u16 family, int type,
+		     int protocol, struct sock *sk, int error)
+{
+	int audit_type = AUDIT_APPARMOR_AUTO;
+	struct common_audit_data sa;
+	struct apparmor_audit_data aad = { };
+	struct lsm_network_audit net = { };
+	if (sk) {
+		COMMON_AUDIT_DATA_INIT(&sa, NET);
+	} else {
+		COMMON_AUDIT_DATA_INIT(&sa, NONE);
+	}
+	/* todo fill in socket addr info */
+	sa.aad = &aad;
+	sa.u.net = &net;
+	sa.aad->op = op,
+	sa.u.net->family = family;
+	sa.u.net->sk = sk;
+	sa.aad->net.type = type;
+	sa.aad->net.protocol = protocol;
+	sa.aad->error = error;
+
+	if (likely(!sa.aad->error)) {
+		u16 audit_mask = profile->net.audit[sa.u.net->family];
+		if (likely((AUDIT_MODE(profile) != AUDIT_ALL) &&
+			   !(1 << sa.aad->net.type & audit_mask)))
+			return 0;
+		audit_type = AUDIT_APPARMOR_AUDIT;
+	} else {
+		u16 quiet_mask = profile->net.quiet[sa.u.net->family];
+		u16 kill_mask = 0;
+		u16 denied = (1 << sa.aad->net.type) & ~quiet_mask;
+
+		if (denied & kill_mask)
+			audit_type = AUDIT_APPARMOR_KILL;
+
+		if ((denied & quiet_mask) &&
+		    AUDIT_MODE(profile) != AUDIT_NOQUIET &&
+		    AUDIT_MODE(profile) != AUDIT_ALL)
+			return COMPLAIN_MODE(profile) ? 0 : sa.aad->error;
+	}
+
+	return aa_audit(audit_type, profile, GFP_KERNEL, &sa, audit_cb);
+}
+
+/**
+ * aa_net_perm - very course network access check
+ * @op: operation being checked
+ * @profile: profile being enforced  (NOT NULL)
+ * @family: network family
+ * @type:   network type
+ * @protocol: network protocol
+ *
+ * Returns: %0 else error if permission denied
+ */
+int aa_net_perm(int op, struct aa_profile *profile, u16 family, int type,
+		int protocol, struct sock *sk)
+{
+	u16 family_mask;
+	int error;
+
+	if ((family < 0) || (family >= AF_MAX))
+		return -EINVAL;
+
+	if ((type < 0) || (type >= SOCK_MAX))
+		return -EINVAL;
+
+	/* unix domain and netlink sockets are handled by ipc */
+	if (family == AF_UNIX || family == AF_NETLINK)
+		return 0;
+
+	family_mask = profile->net.allow[family];
+
+	error = (family_mask & (1 << type)) ? 0 : -EACCES;
+
+	return audit_net(profile, op, family, type, protocol, sk, error);
+}
+
+/**
+ * aa_revalidate_sk - Revalidate access to a sock
+ * @op: operation being checked
+ * @sk: sock being revalidated  (NOT NULL)
+ *
+ * Returns: %0 else error if permission denied
+ */
+int aa_revalidate_sk(int op, struct sock *sk)
+{
+	struct aa_profile *profile;
+	int error = 0;
+
+	/* aa_revalidate_sk should not be called from interrupt context
+	 * don't mediate these calls as they are not task related
+	 */
+	if (in_interrupt())
+		return 0;
+
+	profile = __aa_current_profile();
+	if (!unconfined(profile))
+		error = aa_net_perm(op, profile, sk->sk_family, sk->sk_type,
+				    sk->sk_protocol, sk);
+
+	return error;
+}
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/security/apparmor/policy.c linux-linaro-3.4-2012.05-1_cavium/security/apparmor/policy.c
--- linux-linaro-3.4-2012.05-1_original/security/apparmor/policy.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/security/apparmor/policy.c	2014-07-29 17:28:38.819972000 +0800
@@ -745,6 +745,7 @@
 
 	aa_free_file_rules(&profile->file);
 	aa_free_cap_rules(&profile->caps);
+	aa_free_net_rules(&profile->net);
 	aa_free_rlimit_rules(&profile->rlimits);
 
 	aa_free_sid(profile->sid);
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/security/apparmor/policy_unpack.c linux-linaro-3.4-2012.05-1_cavium/security/apparmor/policy_unpack.c
--- linux-linaro-3.4-2012.05-1_original/security/apparmor/policy_unpack.c	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/security/apparmor/policy_unpack.c	2014-07-29 17:28:38.819972000 +0800
@@ -193,6 +193,19 @@
 	return 0;
 }
 
+static bool unpack_u16(struct aa_ext *e, u16 *data, const char *name)
+{
+	if (unpack_nameX(e, AA_U16, name)) {
+		if (!inbounds(e, sizeof(u16)))
+			return 0;
+		if (data)
+			*data = le16_to_cpu(get_unaligned((u16 *) e->pos));
+		e->pos += sizeof(u16);
+		return 1;
+	}
+	return 0;
+}
+
 static bool unpack_u32(struct aa_ext *e, u32 *data, const char *name)
 {
 	if (unpack_nameX(e, AA_U32, name)) {
@@ -471,6 +484,7 @@
 {
 	struct aa_profile *profile = NULL;
 	const char *name = NULL;
+	size_t size = 0;
 	int i, error = -EPROTO;
 	kernel_cap_t tmpcap;
 	u32 tmp;
@@ -564,6 +578,38 @@
 	if (!unpack_rlimits(e, profile))
 		goto fail;
 
+	size = unpack_array(e, "net_allowed_af");
+	if (size) {
+
+		for (i = 0; i < size; i++) {
+			/* discard extraneous rules that this kernel will
+			 * never request
+			 */
+			if (i >= AF_MAX) {
+				u16 tmp;
+				if (!unpack_u16(e, &tmp, NULL) ||
+				    !unpack_u16(e, &tmp, NULL) ||
+				    !unpack_u16(e, &tmp, NULL))
+					goto fail;
+				continue;
+			}
+			if (!unpack_u16(e, &profile->net.allow[i], NULL))
+				goto fail;
+			if (!unpack_u16(e, &profile->net.audit[i], NULL))
+				goto fail;
+			if (!unpack_u16(e, &profile->net.quiet[i], NULL))
+				goto fail;
+		}
+		if (!unpack_nameX(e, AA_ARRAYEND, NULL))
+			goto fail;
+	}
+	/*
+	 * allow unix domain and netlink sockets they are handled
+	 * by IPC
+	 */
+	profile->net.allow[AF_UNIX] = 0xffff;
+	profile->net.allow[AF_NETLINK] = 0xffff;
+
 	if (unpack_nameX(e, AA_STRUCT, "policydb")) {
 		/* generic policy dfa - optional and may be NULL */
 		profile->policy.dfa = unpack_dfa(e);
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/sound/soc/celestial/cnc-machine.c linux-linaro-3.4-2012.05-1_cavium/sound/soc/celestial/cnc-machine.c
--- linux-linaro-3.4-2012.05-1_original/sound/soc/celestial/cnc-machine.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/sound/soc/celestial/cnc-machine.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,66 @@
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <sound/soc.h>
+
+static struct platform_device_id machine_pids[] = {
+	{
+		.name = "cnc-snd-i2s",
+		.driver_data = 0,
+	}, {
+		.name = "cnc-snd-spdif",
+		.driver_data = 1,
+	}, {
+	},
+};
+
+static struct snd_soc_dai_link links[] = {
+	{
+		.name = "I2S-HDMI",
+		.codec_dai_name	= "hdmi-i2s-hifi",
+		.codec_name	    = "hdmi-i2s-codec",
+		.cpu_dai_name	= "cnc-pcm-i2s",
+		.platform_name	= "cnc-pcm-i2s",
+	},
+};
+
+static struct snd_soc_card cards[] = {
+	{
+		.name		= "CRAD-I2S",
+		.owner		= THIS_MODULE,
+		.dai_link	= links,
+		.num_links	= ARRAY_SIZE(links),
+	},
+};
+
+static int __devinit snd_machine_probe(struct platform_device *pdev)
+{
+	const struct platform_device_id *pid = platform_get_device_id(pdev);
+	struct snd_soc_card *card;
+
+	card = &cards[pid->driver_data];
+	card->dev = &pdev->dev;
+	return snd_soc_register_card(card);
+}
+
+static int __devexit snd_machine_remove(struct platform_device *pdev)
+{
+	struct snd_soc_card *card = platform_get_drvdata(pdev);
+	snd_soc_unregister_card(card);
+	return 0;
+}
+
+static struct platform_driver snd_machine_driver = {
+	.driver	= {
+		.name	= "cnc-snd",
+		.owner	= THIS_MODULE,
+		.pm	= &snd_soc_pm_ops,
+	},
+	.id_table	= machine_pids,
+	.probe		= snd_machine_probe,
+	.remove		= __devexit_p(snd_machine_remove),
+};
+
+module_platform_driver(snd_machine_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("ASOC Machine Driver");
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/sound/soc/celestial/codec-hdmi-i2s.c linux-linaro-3.4-2012.05-1_cavium/sound/soc/celestial/codec-hdmi-i2s.c
--- linux-linaro-3.4-2012.05-1_original/sound/soc/celestial/codec-hdmi-i2s.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/sound/soc/celestial/codec-hdmi-i2s.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,90 @@
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+
+#include <sound/soc.h>
+#include <sound/tlv.h>
+
+struct cnc_hdmi_data {
+	void __iomem *mmio;
+};
+
+static int cnc_hdmi_i2s_hw_params(struct snd_pcm_substream *substream,
+				 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
+{
+//	int rate = params_rate(params);
+	return 0;
+}
+
+static struct snd_soc_dai_ops dai_i2s_ops = {
+	.hw_params = cnc_hdmi_i2s_hw_params,
+};
+
+static struct snd_soc_dai_driver snd_codec_i2s_dai = {
+	.name = "hdmi-i2s-hifi",
+	.playback = {
+		.stream_name = "Playback",
+		.channels_min = 1,
+		.channels_max = 8,
+		.rates = SNDRV_PCM_RATE_8000_192000,
+		.formats = SNDRV_PCM_FMTBIT_S16 | SNDRV_PCM_FMTBIT_S24_3LE,
+	},
+	.ops = &dai_i2s_ops,
+};
+
+static int cnc_hdmi_probe(struct snd_soc_codec *codec)
+{
+	return 0;
+}
+
+static const struct snd_kcontrol_new cnc_hdmi_controls[] = {
+};
+
+static struct snd_soc_codec_driver soc_codec_hdmi = {
+	.probe	= cnc_hdmi_probe,
+	.controls = cnc_hdmi_controls,
+	.num_controls = ARRAY_SIZE(cnc_hdmi_controls),
+};
+
+static int __devinit hdmi_i2s_probe(struct platform_device *pdev)
+{
+	struct cnc_hdmi_data *data;
+	struct resource *iores;
+
+	data = kzalloc(sizeof(struct cnc_hdmi_data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!iores)
+		return -ENODEV;
+
+	data->mmio = ioremap(iores->start, resource_size(iores));
+	if (!data->mmio)
+		return -EBUSY;
+
+	platform_set_drvdata(pdev, data);
+
+	return snd_soc_register_codec(&pdev->dev,
+			&soc_codec_hdmi, &snd_codec_i2s_dai, 1);
+}
+
+static int __devexit hdmi_i2s_remove(struct platform_device *pdev)
+{
+	snd_soc_unregister_codec(&pdev->dev);
+	return 0;
+}
+
+static struct platform_driver codec_hdmi_i2s_driver = {
+	.driver = {
+		.name = "hdmi-i2s-codec",
+		.owner = THIS_MODULE,
+	},
+	.probe = hdmi_i2s_probe,
+	.remove = __devexit_p(hdmi_i2s_remove),
+};
+
+module_platform_driver(codec_hdmi_i2s_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("ALSA Codec Driver for HDMI I2S");
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/sound/soc/celestial/Makefile linux-linaro-3.4-2012.05-1_cavium/sound/soc/celestial/Makefile
--- linux-linaro-3.4-2012.05-1_original/sound/soc/celestial/Makefile	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/sound/soc/celestial/Makefile	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1 @@
+obj-y := cnc-machine.o platform-i2s.o codec-hdmi-i2s.o
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/sound/soc/celestial/platform-i2s.c linux-linaro-3.4-2012.05-1_cavium/sound/soc/celestial/platform-i2s.c
--- linux-linaro-3.4-2012.05-1_original/sound/soc/celestial/platform-i2s.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/sound/soc/celestial/platform-i2s.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,380 @@
+#include <linux/module.h>
+#include <linux/dma-mapping.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+
+#include <sound/soc.h>
+#include <sound/tlv.h>
+
+#define AUDIO_I2S0_SHIFT 0x0000
+#define AUDIO_I2S0_CNTL  0x0004
+#define AUDIO_I2S0_RP0   0x0100
+#define AUDIO_I2S0_WP0   0x0104
+#define AUDIO_I2S0_UP0   0x0108
+#define AUDIO_I2S0_LOW0  0x010c
+#define AUDIO_I2S0_SCAL0 0x0110
+#define AUDIO_I2S0_RP1   0x0114
+#define AUDIO_I2S0_WP1   0x0118
+#define AUDIO_I2S0_UP1   0x011c
+#define AUDIO_I2S0_LOW1  0x0120
+#define AUDIO_I2S0_SCAL1 0x0124
+
+#define AUDIO_I2S_TOGGLE 0x80000000
+#define AUDIO_I2S_BYTES  0x7FFFFFF8
+#define AUDIO_I2S_SCAL_MAX 0x01000000
+
+#include <mach/cnc1900_power_clk.h>
+
+struct cnc_snd_data {
+	void __iomem *mmio;
+	size_t size;
+
+	struct timer_list timer;
+};
+
+static const DECLARE_TLV_DB_LINEAR(volume_tlv, 0, 100);
+
+static int cnc_i2s_get_value(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
+	struct cnc_snd_data *data = snd_soc_platform_get_drvdata(dai->card->rtd->platform);
+	struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value;
+	unsigned int val;
+
+	val = __raw_readl(data->mmio + mc->reg);
+	ucontrol->value.integer.value[0] = val / (AUDIO_I2S_SCAL_MAX / 100);
+	return 0;
+}
+
+static int cnc_i2s_set_value(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
+	struct cnc_snd_data *data = snd_soc_platform_get_drvdata(dai->card->rtd->platform);
+	struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value;
+	unsigned int val;
+
+	val = ucontrol->value.integer.value[0] * (AUDIO_I2S_SCAL_MAX / 100);
+	__raw_writel(val, data->mmio + mc->reg);
+	return 1;
+}
+
+static const struct snd_kcontrol_new cnc_i2s_hw_controls[] = {
+	SOC_SINGLE_EXT_TLV("I2S Volume", AUDIO_I2S0_SCAL0, 0, 100, 0,
+		cnc_i2s_get_value, cnc_i2s_set_value, volume_tlv),
+};
+
+static int cnc_dai_probe(struct snd_soc_dai *dai)
+{
+	return snd_soc_add_dai_controls(dai, cnc_i2s_hw_controls,
+		ARRAY_SIZE(cnc_i2s_hw_controls));
+}
+
+static int cnc_i2s_hw_params(struct snd_pcm_substream *substream,
+				 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
+{
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	//struct cnc_snd_data *data = snd_soc_platform_get_drvdata(rtd->platform);
+	int rate = params_rate(params);
+
+extern void clock_alsa_setclock(int rate);
+	clock_alsa_setclock(rate);
+	return 0;
+}
+
+static int cnc_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
+				struct snd_soc_dai *dai)
+{
+	struct snd_pcm_runtime *run = substream->runtime;
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct cnc_snd_data *data = snd_soc_platform_get_drvdata(rtd->platform);
+	unsigned int scale = __raw_readl(data->mmio + AUDIO_I2S0_SCAL0);
+	int shift = 32 - snd_pcm_format_width(run->format);
+
+	if (strstr(dai->card->name, "HDMI"))
+		shift = 1;
+
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+	case SNDRV_PCM_TRIGGER_RESUME:
+		if (!scale)
+			__raw_writel(0x01000000, data->mmio + AUDIO_I2S0_SCAL0);
+
+		__raw_writel(shift, data->mmio + AUDIO_I2S0_SHIFT);
+		__raw_writel(0x0100, data->mmio + AUDIO_I2S0_CNTL);
+		break;
+	case SNDRV_PCM_TRIGGER_STOP:
+	case SNDRV_PCM_TRIGGER_SUSPEND:
+		__raw_writel(0x0000, data->mmio + AUDIO_I2S0_CNTL);
+		break;
+	}
+	return 0;
+}
+
+static void cnc_i2s_timer_func(unsigned long timer_data)
+{
+	struct snd_pcm_substream *substream = (struct snd_pcm_substream *)timer_data;
+	struct snd_pcm_runtime *run = substream->runtime;
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct cnc_snd_data *data = snd_soc_platform_get_drvdata(rtd->platform);
+	int ms = 1000 * run->control->avail_min / run->rate;
+
+	snd_pcm_period_elapsed(substream);
+	mod_timer(&data->timer, jiffies + msecs_to_jiffies(ms));
+}
+
+static int cnc_i2s_prepare(struct snd_pcm_substream *substream,
+				struct snd_soc_dai *dai)
+{
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct cnc_snd_data *data = snd_soc_platform_get_drvdata(rtd->platform);
+
+	init_timer(&data->timer);
+	data->timer.function = cnc_i2s_timer_func;
+	data->timer.data = (unsigned long)substream;
+
+	data->timer.function(data->timer.data);
+	return 0;
+}
+
+static void cnc_i2s_shutdown(struct snd_pcm_substream *substream,
+				struct snd_soc_dai *dai)
+{
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct cnc_snd_data *data = snd_soc_platform_get_drvdata(rtd->platform);
+
+	del_timer(&data->timer);
+}
+
+static struct snd_soc_dai_ops dai_i2s_ops = {
+	.hw_params = cnc_i2s_hw_params,
+	.trigger = cnc_i2s_trigger,
+	.prepare = cnc_i2s_prepare,
+	.shutdown = cnc_i2s_shutdown,
+};
+
+static struct snd_soc_dai_driver snd_soc_i2s_dai = {
+	.name  = "cnc-pcm-i2s",
+	.playback = {
+		.rates   = SNDRV_PCM_RATE_CONTINUOUS,
+		.formats = SNDRV_PCM_FMTBIT_S16 | SNDRV_PCM_FMTBIT_S24_3LE,
+		.channels_min = 1,
+		.channels_max = 8,
+	},
+	.ops = &dai_i2s_ops,
+	.probe = cnc_dai_probe,
+};
+
+static const struct snd_pcm_hardware cnc_pcm_hardware = {
+	.info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_RESUME,
+	.formats = SNDRV_PCM_FMTBIT_S16 | SNDRV_PCM_FMTBIT_S24_3LE,
+	.periods_min = 2,
+	.periods_max = 32,
+	.period_bytes_min = 8,
+	.period_bytes_max = SZ_16K,
+	.buffer_bytes_max = SZ_32K,
+};
+
+static int cnc_pcm_open(struct snd_pcm_substream *substream)
+{
+	return snd_soc_set_runtime_hwparams(substream, &cnc_pcm_hardware);
+}
+
+static inline snd_pcm_sframes_t dmabytes_to_frames(ssize_t size)
+{
+	return size >> 3;
+}
+
+static inline ssize_t frames_to_dmabytes(snd_pcm_sframes_t size)
+{
+	return size << 3;
+}
+
+static int cnc_pcm_hw_params(struct snd_pcm_substream *substream,
+				 struct snd_pcm_hw_params *params)
+{
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct cnc_snd_data *data = snd_soc_platform_get_drvdata(rtd->platform);
+
+	// 32 BITS 2 CHANNELS
+	data->size = frames_to_dmabytes(params_buffer_size(params));
+	return snd_pcm_lib_malloc_pages(substream, data->size);
+}
+
+static int cnc_pcm_hw_free(struct snd_pcm_substream *substream)
+{
+	return snd_pcm_lib_free_pages(substream);
+}
+
+static int cnc_pcm_prepare(struct snd_pcm_substream *substream)
+{
+	struct snd_pcm_runtime *run = substream->runtime;
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct cnc_snd_data *data = snd_soc_platform_get_drvdata(rtd->platform);
+
+	__raw_writel(run->dma_addr, data->mmio + AUDIO_I2S0_RP0);
+	__raw_writel(run->dma_addr, data->mmio + AUDIO_I2S0_WP0);
+	__raw_writel(run->dma_addr, data->mmio + AUDIO_I2S0_LOW0);
+	__raw_writel(run->dma_addr + data->size, data->mmio + AUDIO_I2S0_UP0);
+	return 0;
+}
+
+static snd_pcm_uframes_t cnc_pcm_pointer(struct snd_pcm_substream *substream)
+{
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct cnc_snd_data *data = snd_soc_platform_get_drvdata(rtd->platform);
+	unsigned int rptr;
+
+	rptr = (__raw_readl(data->mmio + AUDIO_I2S0_RP0) & AUDIO_I2S_BYTES)
+			- __raw_readl(data->mmio + AUDIO_I2S0_LOW0);
+
+	return dmabytes_to_frames(rptr);
+}
+
+static void cnc_update_wrptr(struct snd_pcm_substream *substream, int pos)
+{
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct cnc_snd_data *data = snd_soc_platform_get_drvdata(rtd->platform);
+	unsigned int wptr;
+
+	wptr = __raw_readl(data->mmio + AUDIO_I2S0_LOW0) + frames_to_dmabytes(pos);
+	if (wptr > data->size)
+		wptr = (wptr - data->size) | AUDIO_I2S_TOGGLE;
+
+	__raw_writel(wptr, data->mmio + AUDIO_I2S0_WP0);
+}
+
+static unsigned char buf[SZ_256K] = { 0 };
+
+static int cnc_pcm_copy(struct snd_pcm_substream *substream, int channel,
+			     snd_pcm_uframes_t pos, void __user *src, snd_pcm_uframes_t count)
+{
+	struct snd_pcm_runtime *run = substream->runtime;
+	unsigned char *wptr = run->dma_area + frames_to_dmabytes(pos);
+	int zero_bytes = 4 - snd_pcm_format_width(run->format) / 8;
+	int i, j, k;
+
+	if (copy_from_user(buf, src, frames_to_bytes(run, count)))
+		return -EFAULT;
+
+	for (i = 0, k = 0; i < count << 1; i++) {
+		if (i % 2) {
+			if (run->channels > 1)
+				k += (4 - zero_bytes) * (run->channels - 2);
+			else
+				k -= (4 - zero_bytes);
+		}
+
+		for (j = 0; j < zero_bytes; j++)
+			*wptr++ = 0;
+		for (j = zero_bytes; j < 4; j++)
+			*wptr++ = buf[k++];
+	}
+
+	dsb();
+	cnc_update_wrptr(substream, pos + count);
+	return count;
+}
+
+static int cnc_pcm_silence(struct snd_pcm_substream *substream, int channel,
+			     snd_pcm_uframes_t pos, snd_pcm_uframes_t count)
+{
+	struct snd_pcm_runtime *run = substream->runtime;
+	unsigned char *wptr = run->dma_area + frames_to_dmabytes(pos);
+	int i, j;
+
+	for (i = 0; i < count << 1; i++) {
+		for (j = 0; j < 4; j++)
+			*wptr++ = 0;
+	}
+
+	dsb();
+	cnc_update_wrptr(substream, pos + count);
+	return count;	
+}
+
+static struct snd_pcm_ops pcm_i2s_ops = {
+	.open  = cnc_pcm_open,
+	.hw_params = cnc_pcm_hw_params,
+	.hw_free = cnc_pcm_hw_free,
+	.prepare = cnc_pcm_prepare,
+	.pointer = cnc_pcm_pointer,
+	.copy = cnc_pcm_copy,
+	.silence = cnc_pcm_silence,
+	.ioctl = snd_pcm_lib_ioctl,
+};
+
+static u64 dma_mask = DMA_BIT_MASK(32);
+
+static int cnc_pcm_new(struct snd_soc_pcm_runtime *rtd)
+{
+	struct snd_card *card = rtd->card->snd_card;
+	struct snd_pcm *pcm = rtd->pcm;
+
+	if (!card->dev->dma_mask)
+		card->dev->dma_mask = &dma_mask;
+	if (!card->dev->coherent_dma_mask)
+		card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
+
+	snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
+		card->dev, SZ_256K, SZ_256K);
+	return 0;
+}
+
+static void cnc_pcm_free(struct snd_pcm *pcm)
+{
+	snd_pcm_lib_preallocate_free_for_all(pcm);
+}
+
+static struct snd_soc_platform_driver snd_soc_i2s_platform = {
+	.ops		= &pcm_i2s_ops,
+	.pcm_new	= cnc_pcm_new,
+	.pcm_free	= cnc_pcm_free,
+};
+
+static int __devinit snd_platform_i2s_probe(struct platform_device *pdev)
+{
+	struct cnc_snd_data *data;
+	struct resource *iores;
+
+	clock_audio_enaclock(_clock_enable);
+	clock_audiopll_enaclock(_clock_enable);
+
+	data = kzalloc(sizeof(struct cnc_snd_data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!iores)
+		return -ENODEV;
+
+	data->mmio = ioremap(iores->start, resource_size(iores));
+	if (!data->mmio)
+		return -EBUSY;
+
+	platform_set_drvdata(pdev, data);
+
+	snd_soc_register_platform(&pdev->dev, &snd_soc_i2s_platform);
+	snd_soc_register_dai(&pdev->dev, &snd_soc_i2s_dai);
+	return 0;
+}
+
+static int __devexit snd_platform_i2s_remove(struct platform_device *pdev)
+{
+	snd_soc_unregister_dai(&pdev->dev);
+	snd_soc_unregister_platform(&pdev->dev);
+	return 0;
+}
+
+static struct platform_driver snd_platform_i2s_driver = {
+	.driver	= {
+		.name  = "cnc-pcm-i2s",
+		.owner = THIS_MODULE,
+	},
+	.probe	= snd_platform_i2s_probe,
+	.remove	= __devexit_p(snd_platform_i2s_remove),
+};
+
+module_platform_driver(snd_platform_i2s_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("ALSA Platfrom Driver for DMA & I2S");
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/sound/soc/Makefile linux-linaro-3.4-2012.05-1_cavium/sound/soc/Makefile
--- linux-linaro-3.4-2012.05-1_original/sound/soc/Makefile	2012-05-23 00:39:37.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/sound/soc/Makefile	2014-07-29 17:28:38.819972000 +0800
@@ -25,3 +25,4 @@
 obj-$(CONFIG_SND_SOC)	+= sh/
 obj-$(CONFIG_SND_SOC)	+= tegra/
 obj-$(CONFIG_SND_SOC)	+= txx9/
+obj-$(CONFIG_SND_SOC)	+= celestial/
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/tests/Makefile linux-linaro-3.4-2012.05-1_cavium/tests/Makefile
--- linux-linaro-3.4-2012.05-1_original/tests/Makefile	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/tests/Makefile	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,12 @@
+src_files := $(shell ls *.c)
+elf_files := $(strip $(patsubst %.c, test.%, $(src_files)))
+
+all: $(elf_files)
+
+CFLAGS := -I$(shell pwd)/../include -D__EXPORTED_HEADERS__
+
+$(elf_files): test.%: %.c
+	$(CROSS_COMPILE)gcc $(CFLAGS) $< -o $@
+
+clean:
+	rm -f $(elf_files)
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/tests/mtd.c linux-linaro-3.4-2012.05-1_cavium/tests/mtd.c
--- linux-linaro-3.4-2012.05-1_original/tests/mtd.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/tests/mtd.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,120 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+
+#include <mtd/mtd-abi.h>
+
+static int mtd_read(int fd, int from, int len)
+{
+	int rdlen = ((len + 7) / 8) * 8;
+	char *buf = calloc(1, rdlen);
+	int ret = lseek(fd, from, SEEK_SET);
+
+	if (ret == from && buf) {
+		ret = read(fd, buf, rdlen);
+		if (ret == rdlen) {
+			int i = 0;
+			for (; i < rdlen / 8; i++)
+				printf("%02x %02x %02x %02x %02x %02x %02x %02x\n",
+					buf[i * 8 + 0], buf[i * 8 + 1], buf[i * 8 + 2], buf[i * 8 + 3],
+					buf[i * 8 + 4], buf[i * 8 + 5], buf[i * 8 + 6], buf[i * 8 + 7]);
+		}
+	}
+	return 0;
+}
+
+static int mtd_write(int fd, int from, int len)
+{
+	char *buf = calloc(1, len);
+	int ret = lseek(fd, from, SEEK_SET);
+
+	if (ret == from && buf) {
+		int i = 0;
+		for (; i < len; i++)
+			buf[i] = i;
+
+		ret = write(fd, buf, len);
+		if (ret == len)
+			printf("Write @%x[%d] done.\n", from, len);
+	}
+	return 0;
+}
+
+static int mtd_erase(int fd, int from, int len)
+{
+	struct erase_info_user cmd = { from, len };
+	int ret = ioctl(fd, MEMERASE, &cmd);
+	if (ret == 0)
+		printf("Erase @%x[%d] done.\n", from, len);
+	return 0;
+}
+
+int main(int argc, char **argv)
+{
+	int from = 0, len = 0, fd, c;
+	int ret = 0;
+	char ops = 0;
+	char *mtd;
+
+	while ((c = getopt(argc, argv, "rwef:l:")) != -1) {
+		switch (c) {
+			case 'r': 
+			case 'w': 
+			case 'e': 
+				ops = c;
+				mtd = optarg;
+				break;
+			case 'f':
+				from = strtol(optarg, NULL, 0);
+				break;
+			case 'l':
+				len  = strtol(optarg, NULL, 0);
+				break;
+			default:
+				ret = -EINVAL;
+				break;
+		}
+	}
+
+	if (optind < argc)
+		mtd = argv[optind];
+	else
+		ret = -EINVAL;
+
+	if (ret < 0)
+		goto usage;
+
+	fd = open(mtd, O_RDWR);
+	if (fd < 0) {
+		printf("Open %s ERROR!\n", mtd);
+		return -ENODEV;
+	}
+
+	switch (ops) {
+		case 'r':
+			ret = mtd_read (fd, from, len);
+			break;
+		case 'w':
+			ret = mtd_write(fd, from, len);
+			break;
+		case 'e':
+			ret = mtd_erase(fd, from, len);
+			break;
+		default:
+			ret = -EINVAL;
+			break;
+	}
+
+	return 0;
+
+usage:
+	printf("Usage: test.mtd -r|w|e [-f <from>] [-l <len>] /dev/mtdN\n");
+	printf("       Test SPI & NAND Flash\n");
+	return ret;
+}
diff '--exclude=.svn' -Naur linux-linaro-3.4-2012.05-1_original/tests/tty.c linux-linaro-3.4-2012.05-1_cavium/tests/tty.c
--- linux-linaro-3.4-2012.05-1_original/tests/tty.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-linaro-3.4-2012.05-1_cavium/tests/tty.c	2014-07-29 17:28:38.819972000 +0800
@@ -0,0 +1,67 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include <fcntl.h>
+#include <termios.h>
+
+tcflag_t rate_map[][2] = {
+	{ 9600,   B9600 },
+	{ 115200, B115200 },
+};
+
+int main(int argc, char **argv)
+{
+	int rate = 115200, fd, c;
+	int ret = 0, i;
+	struct termios ios;
+	tcflag_t flag = 0;
+	char *tty;
+
+	while ((c = getopt(argc, argv, "as:")) != -1) {
+		switch (c) {
+			case 'a': 
+				flag = CRTSCTS;
+				break;
+			case 's': 
+				rate = strtol(optarg, NULL, 0);
+				break;
+			default:
+				ret = -EINVAL;
+				break;
+		}
+	}
+	
+	if (optind < argc)
+		tty = argv[optind];
+	else
+		ret = -EINVAL;
+
+	if (ret < 0)
+		goto usage;
+
+	fd = open(tty, O_RDWR|O_NOCTTY);
+	if (fd < 0) {
+		printf("Open %s ERROR!\n", tty);
+		return -ENODEV;
+	}
+
+	for (i = 0; i < sizeof(rate_map)/sizeof(tcflag_t)/2; i++) {
+		if (rate_map[i][0] == rate)
+			flag |= rate_map[i][1];
+	}
+
+	tcgetattr(fd, &ios);
+	ios.c_cflag &= ~(CBAUD | CRTSCTS);
+	ios.c_cflag |= flag;
+	tcsetattr(fd, TCSANOW, &ios);
+
+	printf("Set Termios %x\n", flag);
+	return 0;
+
+usage:
+	printf("Usage: test.tty [-a] [-s <rate>] /dev/ttySN\n");
+	printf("       Test ttyS Console\n");
+	return ret;
+}
