Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=588ef7693574cfbcb228f48d5478c2b39a9b0c9f
Commit:     588ef7693574cfbcb228f48d5478c2b39a9b0c9f
Parent:     dfc544c7216b276c1e9c0c753299692df4068c44
Author:     Dan Williams <[EMAIL PROTECTED]>
AuthorDate: Tue Feb 13 17:12:04 2007 +0100
Committer:  Russell King <[EMAIL PROTECTED]>
CommitDate: Wed Feb 14 15:21:24 2007 +0000

    [ARM] 4184/1: iop: cp6 access handler (undef_hook)
    
    Enable svc access to cp6 via an undefined instruction hook.  Do not enable
    access for usr code.
    
    This patch also makes iop13xx select PLAT_IOP, this requires a small change
    to drivers/i2c/busses/i2c-iop3xx.c.
    
    Per Lennert Buytenhek's note, the cp6 trap routine is moved to 
arch/arm/plat-iop
    Per Nicolas Pitre's note, the cp_wait is skipped since the latency to
    return to the faulting function is longer than cp_wait.
    
    Signed-off-by: Dan Williams <[EMAIL PROTECTED]>
    Signed-off-by: Russell King <[EMAIL PROTECTED]>
---
 arch/arm/Kconfig                  |    2 +
 arch/arm/mach-iop13xx/irq.c       |    3 ++
 arch/arm/mach-iop32x/irq.c        |    2 +
 arch/arm/mach-iop33x/irq.c        |    2 +
 arch/arm/plat-iop/Makefile        |   30 +++++++++++++++++++---
 arch/arm/plat-iop/cp6.c           |   50 +++++++++++++++++++++++++++++++++++++
 drivers/i2c/busses/i2c-iop3xx.c   |    2 +-
 include/asm-arm/hardware/iop3xx.h |    1 +
 8 files changed, 87 insertions(+), 5 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 6783c2e..3f48e35 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -233,6 +233,8 @@ config ARCH_IOP33X
 
 config ARCH_IOP13XX
        bool "IOP13xx-based"
+       depends on MMU
+       select PLAT_IOP
        select PCI
        help
          Support for Intel's IOP13XX (XScale) family of processors.
diff --git a/arch/arm/mach-iop13xx/irq.c b/arch/arm/mach-iop13xx/irq.c
index dbbc07c..162b932 100644
--- a/arch/arm/mach-iop13xx/irq.c
+++ b/arch/arm/mach-iop13xx/irq.c
@@ -250,11 +250,14 @@ static struct irq_chip iop13xx_irqchip4 = {
        .unmask = iop13xx_irq_unmask3,
 };
 
+extern void iop_init_cp6_handler(void);
+
 void __init iop13xx_init_irq(void)
 {
        unsigned int i;
 
        u32 cp_flags = iop13xx_cp6_save();
+       iop_init_cp6_handler();
 
        /* disable all interrupts */
        write_intctl_0(0);
diff --git a/arch/arm/mach-iop32x/irq.c b/arch/arm/mach-iop32x/irq.c
index 3ec1cd5..8b0ac55 100644
--- a/arch/arm/mach-iop32x/irq.c
+++ b/arch/arm/mach-iop32x/irq.c
@@ -60,6 +60,8 @@ void __init iop32x_init_irq(void)
 {
        int i;
 
+       iop_init_cp6_handler();
+
        intctl_write(0);
        intstr_write(0);
        if (machine_is_glantank() ||
diff --git a/arch/arm/mach-iop33x/irq.c b/arch/arm/mach-iop33x/irq.c
index 00b37f3..effbe6b 100644
--- a/arch/arm/mach-iop33x/irq.c
+++ b/arch/arm/mach-iop33x/irq.c
@@ -110,6 +110,8 @@ void __init iop33x_init_irq(void)
 {
        int i;
 
+       iop_init_cp6_handler();
+
        intctl0_write(0);
        intctl1_write(0);
        intstr0_write(0);
diff --git a/arch/arm/plat-iop/Makefile b/arch/arm/plat-iop/Makefile
index ed91463..3250d73 100644
--- a/arch/arm/plat-iop/Makefile
+++ b/arch/arm/plat-iop/Makefile
@@ -2,7 +2,29 @@
 # Makefile for the linux kernel.
 #
 
-obj-y                  := gpio.o i2c.o pci.o setup.o time.o io.o
-obj-m                  :=
-obj-n                  :=
-obj-                   :=
+obj-y :=
+
+# IOP32X
+obj-$(CONFIG_ARCH_IOP32X) += gpio.o
+obj-$(CONFIG_ARCH_IOP32X) += i2c.o
+obj-$(CONFIG_ARCH_IOP32X) += pci.o
+obj-$(CONFIG_ARCH_IOP32X) += setup.o
+obj-$(CONFIG_ARCH_IOP32X) += time.o
+obj-$(CONFIG_ARCH_IOP32X) += io.o
+obj-$(CONFIG_ARCH_IOP32X) += cp6.o
+
+# IOP33X
+obj-$(CONFIG_ARCH_IOP33X) += gpio.o
+obj-$(CONFIG_ARCH_IOP33X) += i2c.o
+obj-$(CONFIG_ARCH_IOP33X) += pci.o
+obj-$(CONFIG_ARCH_IOP33X) += setup.o
+obj-$(CONFIG_ARCH_IOP33X) += time.o
+obj-$(CONFIG_ARCH_IOP33X) += io.o
+obj-$(CONFIG_ARCH_IOP33X) += cp6.o
+
+# IOP13XX
+obj-$(CONFIG_ARCH_IOP13XX) += cp6.o
+
+obj-m                  :=
+obj-n                  :=
+obj-                   :=
diff --git a/arch/arm/plat-iop/cp6.c b/arch/arm/plat-iop/cp6.c
new file mode 100644
index 0000000..9612a87
--- /dev/null
+++ b/arch/arm/plat-iop/cp6.c
@@ -0,0 +1,50 @@
+/*
+ * IOP Coprocessor-6 access handler
+ * Copyright (c) 2006, 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., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ *
+ */
+#include <linux/init.h>
+#include <asm/traps.h>
+
+static int cp6_trap(struct pt_regs *regs, unsigned int instr)
+{
+       u32 temp;
+
+        /* enable cp6 access */
+        asm volatile (
+               "mrc    p15, 0, %0, c15, c1, 0\n\t"
+               "orr    %0, %0, #(1 << 6)\n\t"
+               "mcr    p15, 0, %0, c15, c1, 0\n\t"
+               : "=r"(temp));
+
+       return 0;
+}
+
+/* permit kernel space cp6 access
+ * deny user space cp6 access
+ */
+static struct undef_hook cp6_hook = {
+       .instr_mask     = 0x0f000ff0,
+       .instr_val      = 0x0e000610,
+       .cpsr_mask      = MODE_MASK,
+       .cpsr_val       = SVC_MODE,
+       .fn             = cp6_trap,
+};
+
+void __init iop_init_cp6_handler(void)
+{
+       register_undef_hook(&cp6_hook);
+}
diff --git a/drivers/i2c/busses/i2c-iop3xx.c b/drivers/i2c/busses/i2c-iop3xx.c
index d108ab4..b70a7f7 100644
--- a/drivers/i2c/busses/i2c-iop3xx.c
+++ b/drivers/i2c/busses/i2c-iop3xx.c
@@ -84,7 +84,7 @@ iop3xx_i2c_enable(struct i2c_algo_iop3xx_data *iop3xx_adap)
         * Every time unit enable is asserted, GPOD needs to be cleared
         * on IOP3XX to avoid data corruption on the bus.
         */
-#ifdef CONFIG_PLAT_IOP
+#if defined(CONFIG_ARCH_IOP32X) || defined(CONFIG_ARCH_IOP33X)
        if (iop3xx_adap->id == 0) {
                gpio_line_set(IOP3XX_GPIO_LINE(7), GPIO_LOW);
                gpio_line_set(IOP3XX_GPIO_LINE(6), GPIO_LOW);
diff --git a/include/asm-arm/hardware/iop3xx.h 
b/include/asm-arm/hardware/iop3xx.h
index adb96c7..c91b546 100644
--- a/include/asm-arm/hardware/iop3xx.h
+++ b/include/asm-arm/hardware/iop3xx.h
@@ -278,6 +278,7 @@ extern void gpio_line_set(int line, int value);
 void iop3xx_map_io(void);
 void iop3xx_init_time(unsigned long);
 unsigned long iop3xx_gettimeoffset(void);
+void iop_init_cp6_handler(void);
 
 extern struct platform_device iop3xx_i2c0_device;
 extern struct platform_device iop3xx_i2c1_device;
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to