Merge branch 'upstream-greg' of gregkh@master.kernel.org:/pub/scm/linux/kernel/git...
authorGreg Kroah-Hartman <gregkh@suse.de>
Thu, 24 Aug 2006 04:58:48 +0000 (21:58 -0700)
committerGreg Kroah-Hartman <gregkh@suse.de>
Thu, 24 Aug 2006 04:58:48 +0000 (21:58 -0700)
76 files changed:
Documentation/input/joystick.txt
MAINTAINERS
arch/arm/common/dmabounce.c
arch/arm/kernel/entry-armv.S
arch/arm/kernel/head.S
arch/arm/mach-s3c2410/Makefile
arch/arm/mach-s3c2410/dma.c
arch/arm/mach-versatile/core.c
arch/i386/kernel/acpi/boot.c
arch/i386/kernel/acpi/wakeup.S
arch/ia64/kernel/acpi.c
arch/powerpc/boot/dts/mpc8540ads.dts [new file with mode: 0644]
arch/powerpc/boot/dts/mpc8541cds.dts [new file with mode: 0644]
arch/powerpc/boot/dts/mpc8548cds.dts [new file with mode: 0644]
arch/powerpc/boot/dts/mpc8555cds.dts [new file with mode: 0644]
arch/powerpc/kernel/legacy_serial.c
arch/powerpc/kernel/prom_parse.c
arch/powerpc/kernel/time.c
arch/powerpc/kernel/traps.c
arch/powerpc/mm/hugetlbpage.c
arch/powerpc/platforms/85xx/Kconfig
arch/powerpc/platforms/85xx/mpc85xx_ads.c
arch/powerpc/platforms/85xx/mpc85xx_cds.c
arch/powerpc/platforms/86xx/mpc8641_hpcn.h
arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c
arch/powerpc/platforms/powermac/bootx_init.c
arch/powerpc/sysdev/fsl_soc.c
arch/powerpc/sysdev/tsi108_dev.c
arch/powerpc/sysdev/tsi108_pci.c
block/cfq-iosched.c
block/elevator.c
block/ll_rw_blk.c
drivers/acpi/ac.c
drivers/acpi/acpi_memhotplug.c
drivers/acpi/battery.c
drivers/acpi/bus.c
drivers/acpi/hotkey.c
drivers/acpi/i2c_ec.c
drivers/acpi/osl.c
drivers/acpi/sbs.c
drivers/acpi/scan.c
drivers/acpi/utils.c
drivers/infiniband/core/cache.c
drivers/infiniband/core/sa_query.c
drivers/infiniband/hw/mthca/mthca_main.c
drivers/infiniband/hw/mthca/mthca_provider.c
drivers/infiniband/hw/mthca/mthca_provider.h
drivers/infiniband/hw/mthca/mthca_qp.c
drivers/input/keyboard/atkbd.c
drivers/input/misc/wistron_btns.c
drivers/input/mouse/psmouse-base.c
drivers/pci/hotplug/Kconfig
drivers/pci/quirks.c
drivers/scsi/esp.c
drivers/serial/sunsab.c
drivers/serial/sunzilog.c
fs/ioprio.c
fs/udf/super.c
fs/udf/truncate.c
include/asm-arm/arch-s3c2410/dma.h
include/asm-arm/procinfo.h
include/asm-powerpc/pgalloc.h
include/asm-powerpc/system.h
include/asm-powerpc/tsi108.h
include/asm-powerpc/tsi108_irq.h [new file with mode: 0644]
include/asm-sparc64/pgtable.h
include/linux/ioprio.h
include/net/sctp/sctp.h
include/net/sctp/sm.h
lib/ts_bm.c
net/ipv4/netfilter/arp_tables.c
net/ipv4/tcp_output.c
net/sctp/sm_make_chunk.c
net/sctp/sm_statefuns.c
net/sctp/socket.c

index d53b857..841c353 100644 (file)
@@ -39,7 +39,6 @@ them. Bug reports and success stories are also welcome.
 
   The input project website is at:
 
-       http://www.suse.cz/development/input/
        http://atrey.karlin.mff.cuni.cz/~vojtech/input/
 
   There is also a mailing list for the driver at:
index 21116cc..3bab239 100644 (file)
@@ -889,6 +889,12 @@ M: rdunlap@xenotime.net
 T:     git http://tali.admingilde.org/git/linux-docbook.git
 S:     Maintained
 
+DOCKING STATION DRIVER
+P:     Kristen Carlson Accardi
+M:     kristen.c.accardi@intel.com
+L:     linux-acpi@vger.kernel.org
+S:     Maintained
+
 DOUBLETALK DRIVER
 P:     James R. Van Zandt
 M:     jrv@vanzandt.mv.com
index 5b7c263..028bdc9 100644 (file)
@@ -179,17 +179,19 @@ alloc_safe_buffer(struct dmabounce_device_info *device_info, void *ptr,
 static inline struct safe_buffer *
 find_safe_buffer(struct dmabounce_device_info *device_info, dma_addr_t safe_dma_addr)
 {
-       struct safe_buffer *b = NULL;
+       struct safe_buffer *b, *rb = NULL;
        unsigned long flags;
 
        read_lock_irqsave(&device_info->lock, flags);
 
        list_for_each_entry(b, &device_info->safe_buffers, node)
-               if (b->safe_dma_addr == safe_dma_addr)
+               if (b->safe_dma_addr == safe_dma_addr) {
+                       rb = b;
                        break;
+               }
 
        read_unlock_irqrestore(&device_info->lock, flags);
-       return b;
+       return rb;
 }
 
 static inline void
index 7ea5f01..de4e331 100644 (file)
@@ -634,6 +634,14 @@ ENTRY(__switch_to)
  * purpose.
  */
 
+       .macro  usr_ret, reg
+#ifdef CONFIG_ARM_THUMB
+       bx      \reg
+#else
+       mov     pc, \reg
+#endif
+       .endm
+
        .align  5
        .globl  __kuser_helper_start
 __kuser_helper_start:
@@ -675,7 +683,7 @@ __kuser_memory_barrier:                             @ 0xffff0fa0
 #if __LINUX_ARM_ARCH__ >= 6 && defined(CONFIG_SMP)
        mcr     p15, 0, r0, c7, c10, 5  @ dmb
 #endif
-       mov     pc, lr
+       usr_ret lr
 
        .align  5
 
@@ -778,7 +786,7 @@ __kuser_cmpxchg:                            @ 0xffff0fc0
        mov     r0, #-1
        adds    r0, r0, #0
 #endif
-       mov     pc, lr
+       usr_ret lr
 
 #else
 
@@ -792,7 +800,7 @@ __kuser_cmpxchg:                            @ 0xffff0fc0
 #ifdef CONFIG_SMP
        mcr     p15, 0, r0, c7, c10, 5  @ dmb
 #endif
-       mov     pc, lr
+       usr_ret lr
 
 #endif
 
@@ -834,16 +842,11 @@ __kuser_cmpxchg:                          @ 0xffff0fc0
 __kuser_get_tls:                               @ 0xffff0fe0
 
 #if !defined(CONFIG_HAS_TLS_REG) && !defined(CONFIG_TLS_REG_EMUL)
-
        ldr     r0, [pc, #(16 - 8)]             @ TLS stored at 0xffff0ff0
-       mov     pc, lr
-
 #else
-
        mrc     p15, 0, r0, c13, c0, 3          @ read TLS register
-       mov     pc, lr
-
 #endif
+       usr_ret lr
 
        .rep    5
        .word   0                       @ pad up to __kuser_helper_version
index 4fe386e..5365d4e 100644 (file)
@@ -118,7 +118,7 @@ ENTRY(secondary_startup)
        sub     r4, r4, r5                      @ mmu has been enabled
        ldr     r4, [r7, r4]                    @ get secondary_data.pgdir
        adr     lr, __enable_mmu                @ return address
-       add     pc, r10, #12                    @ initialise processor
+       add     pc, r10, #PROCINFO_INITFUNC     @ initialise processor
                                                @ (return control reg)
 
        /*
index 0c79386..273e05f 100644 (file)
@@ -10,45 +10,47 @@ obj-m                       :=
 obj-n                  :=
 obj-                   :=
 
+# DMA
+obj-$(CONFIG_S3C2410_DMA)      += dma.o
+
 # S3C2400 support files
-obj-$(CONFIG_CPU_S3C2400)  += s3c2400-gpio.o
+obj-$(CONFIG_CPU_S3C2400)      += s3c2400-gpio.o
 
 # S3C2410 support files
 
-obj-$(CONFIG_CPU_S3C2410)  += s3c2410.o
-obj-$(CONFIG_CPU_S3C2410)  += s3c2410-gpio.o
-obj-$(CONFIG_S3C2410_DMA)  += dma.o
+obj-$(CONFIG_CPU_S3C2410)      += s3c2410.o
+obj-$(CONFIG_CPU_S3C2410)      += s3c2410-gpio.o
 
 # Power Management support
 
-obj-$(CONFIG_PM)          += pm.o sleep.o
-obj-$(CONFIG_PM_SIMTEC)           += pm-simtec.o
+obj-$(CONFIG_PM)               += pm.o sleep.o
+obj-$(CONFIG_PM_SIMTEC)                += pm-simtec.o
 
 # S3C2412 support
-obj-$(CONFIG_CPU_S3C2412)  += s3c2412.o
-obj-$(CONFIG_CPU_S3C2412)  += s3c2412-clock.o
+obj-$(CONFIG_CPU_S3C2412)      += s3c2412.o
+obj-$(CONFIG_CPU_S3C2412)      += s3c2412-clock.o
 
 #
 # S3C244X support
 
-obj-$(CONFIG_CPU_S3C244X)  += s3c244x.o
-obj-$(CONFIG_CPU_S3C244X)  += s3c244x-irq.o
+obj-$(CONFIG_CPU_S3C244X)      += s3c244x.o
+obj-$(CONFIG_CPU_S3C244X)      += s3c244x-irq.o
 
 # Clock control
 
-obj-$(CONFIG_S3C2410_CLOCK) += s3c2410-clock.o
+obj-$(CONFIG_S3C2410_CLOCK)    += s3c2410-clock.o
 
 # S3C2440 support
 
-obj-$(CONFIG_CPU_S3C2440)  += s3c2440.o s3c2440-dsc.o
-obj-$(CONFIG_CPU_S3C2440)  += s3c2440-irq.o
-obj-$(CONFIG_CPU_S3C2440)  += s3c2440-clock.o
-obj-$(CONFIG_CPU_S3C2440)  += s3c2410-gpio.o
+obj-$(CONFIG_CPU_S3C2440)      += s3c2440.o s3c2440-dsc.o
+obj-$(CONFIG_CPU_S3C2440)      += s3c2440-irq.o
+obj-$(CONFIG_CPU_S3C2440)      += s3c2440-clock.o
+obj-$(CONFIG_CPU_S3C2440)      += s3c2410-gpio.o
 
 # S3C2442 support
 
-obj-$(CONFIG_CPU_S3C2442)  += s3c2442.o
-obj-$(CONFIG_CPU_S3C2442)  += s3c2442-clock.o
+obj-$(CONFIG_CPU_S3C2442)      += s3c2442.o
+obj-$(CONFIG_CPU_S3C2442)      += s3c2442-clock.o
 
 # bast extras
 
index 094cc52..2585545 100644 (file)
@@ -112,7 +112,7 @@ dmadbg_capture(s3c2410_dma_chan_t *chan, struct s3c2410_dma_regstate *regs)
 }
 
 static void
-dmadbg_showregs(const char *fname, int line, s3c2410_dma_chan_t *chan,
+dmadbg_dumpregs(const char *fname, int line, s3c2410_dma_chan_t *chan,
                 struct s3c2410_dma_regstate *regs)
 {
        printk(KERN_DEBUG "dma%d: %s:%d: DCSRC=%08lx, DISRC=%08lx, DSTAT=%08lx DMT=%02lx, DCON=%08lx\n",
@@ -132,7 +132,16 @@ dmadbg_showchan(const char *fname, int line, s3c2410_dma_chan_t *chan)
               chan->number, fname, line, chan->load_state,
               chan->curr, chan->next, chan->end);
 
-       dmadbg_showregs(fname, line, chan, &state);
+       dmadbg_dumpregs(fname, line, chan, &state);
+}
+
+static void
+dmadbg_showregs(const char *fname, int line, s3c2410_dma_chan_t *chan)
+{
+       struct s3c2410_dma_regstate state;
+
+       dmadbg_capture(chan, &state);
+       dmadbg_dumpregs(fname, line, chan, &state);
 }
 
 #define dbg_showregs(chan) dmadbg_showregs(__FUNCTION__, __LINE__, (chan))
@@ -253,10 +262,14 @@ s3c2410_dma_loadbuffer(s3c2410_dma_chan_t *chan,
                         buf->next);
                reload = (buf->next == NULL) ? S3C2410_DCON_NORELOAD : 0;
        } else {
-               pr_debug("load_state is %d => autoreload\n", chan->load_state);
+               //pr_debug("load_state is %d => autoreload\n", chan->load_state);
                reload = S3C2410_DCON_AUTORELOAD;
        }
 
+       if ((buf->data & 0xf0000000) != 0x30000000) {
+               dmawarn("dmaload: buffer is %p\n", (void *)buf->data);
+       }
+
        writel(buf->data, chan->addr_reg);
 
        dma_wrreg(chan, S3C2410_DMA_DCON,
@@ -370,7 +383,7 @@ static int s3c2410_dma_start(s3c2410_dma_chan_t *chan)
        tmp |= S3C2410_DMASKTRIG_ON;
        dma_wrreg(chan, S3C2410_DMA_DMASKTRIG, tmp);
 
-       pr_debug("wrote %08lx to DMASKTRIG\n", tmp);
+       pr_debug("dma%d: %08lx to DMASKTRIG\n", chan->number, tmp);
 
 #if 0
        /* the dma buffer loads should take care of clearing the AUTO
@@ -384,7 +397,30 @@ static int s3c2410_dma_start(s3c2410_dma_chan_t *chan)
 
        dbg_showchan(chan);
 
+       /* if we've only loaded one buffer onto the channel, then chec
+        * to see if we have another, and if so, try and load it so when
+        * the first buffer is finished, the new one will be loaded onto
+        * the channel */
+
+       if (chan->next != NULL) {
+               if (chan->load_state == S3C2410_DMALOAD_1LOADED) {
+
+                       if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {
+                               pr_debug("%s: buff not yet loaded, no more todo\n",
+                                        __FUNCTION__);
+                       } else {
+                               chan->load_state = S3C2410_DMALOAD_1RUNNING;
+                               s3c2410_dma_loadbuffer(chan, chan->next);
+                       }
+
+               } else if (chan->load_state == S3C2410_DMALOAD_1RUNNING) {
+                       s3c2410_dma_loadbuffer(chan, chan->next);
+               }
+       }
+
+
        local_irq_restore(flags);
+
        return 0;
 }
 
@@ -436,12 +472,11 @@ int s3c2410_dma_enqueue(unsigned int channel, void *id,
        buf = kmem_cache_alloc(dma_kmem, GFP_ATOMIC);
        if (buf == NULL) {
                pr_debug("%s: out of memory (%ld alloc)\n",
-                        __FUNCTION__, sizeof(*buf));
+                        __FUNCTION__, (long)sizeof(*buf));
                return -ENOMEM;
        }
 
-       pr_debug("%s: new buffer %p\n", __FUNCTION__, buf);
-
+       //pr_debug("%s: new buffer %p\n", __FUNCTION__, buf);
        //dbg_showchan(chan);
 
        buf->next  = NULL;
@@ -537,14 +572,20 @@ s3c2410_dma_lastxfer(s3c2410_dma_chan_t *chan)
        case S3C2410_DMALOAD_1LOADED:
                if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {
                                /* flag error? */
-                       printk(KERN_ERR "dma%d: timeout waiting for load\n",
-                              chan->number);
+                       printk(KERN_ERR "dma%d: timeout waiting for load (%s)\n",
+                              chan->number, __FUNCTION__);
                        return;
                }
                break;
 
+       case S3C2410_DMALOAD_1LOADED_1RUNNING:
+               /* I belive in this case we do not have anything to do
+                * until the next buffer comes along, and we turn off the
+                * reload */
+               return;
+
        default:
-               pr_debug("dma%d: lastxfer: unhandled load_state %d with no next",
+               pr_debug("dma%d: lastxfer: unhandled load_state %d with no next\n",
                         chan->number, chan->load_state);
                return;
 
@@ -629,7 +670,14 @@ s3c2410_dma_irq(int irq, void *devpw, struct pt_regs *regs)
        } else {
        }
 
-       if (chan->next != NULL) {
+       /* only reload if the channel is still running... our buffer done
+        * routine may have altered the state by requesting the dma channel
+        * to stop or shutdown... */
+
+       /* todo: check that when the channel is shut-down from inside this
+        * function, we cope with unsetting reload, etc */
+
+       if (chan->next != NULL && chan->state != S3C2410_DMA_IDLE) {
                unsigned long flags;
 
                switch (chan->load_state) {
@@ -644,8 +692,8 @@ s3c2410_dma_irq(int irq, void *devpw, struct pt_regs *regs)
                case S3C2410_DMALOAD_1LOADED:
                        if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {
                                /* flag error? */
-                               printk(KERN_ERR "dma%d: timeout waiting for load\n",
-                                      chan->number);
+                               printk(KERN_ERR "dma%d: timeout waiting for load (%s)\n",
+                                      chan->number, __FUNCTION__);
                                return IRQ_HANDLED;
                        }
 
@@ -678,8 +726,6 @@ s3c2410_dma_irq(int irq, void *devpw, struct pt_regs *regs)
        return IRQ_HANDLED;
 }
 
-
-
 /* s3c2410_request_dma
  *
  * get control of an dma channel
@@ -718,11 +764,17 @@ int s3c2410_dma_request(unsigned int channel, s3c2410_dma_client_t *client,
                pr_debug("dma%d: %s : requesting irq %d\n",
                         channel, __FUNCTION__, chan->irq);
 
+               chan->irq_claimed = 1;
+               local_irq_restore(flags);
+
                err = request_irq(chan->irq, s3c2410_dma_irq, IRQF_DISABLED,
                                  client->name, (void *)chan);
 
+               local_irq_save(flags);
+
                if (err) {
                        chan->in_use = 0;
+                       chan->irq_claimed = 0;
                        local_irq_restore(flags);
 
                        printk(KERN_ERR "%s: cannot get IRQ %d for DMA %d\n",
@@ -730,7 +782,6 @@ int s3c2410_dma_request(unsigned int channel, s3c2410_dma_client_t *client,
                        return err;
                }
 
-               chan->irq_claimed = 1;
                chan->irq_enabled = 1;
        }
 
@@ -810,6 +861,7 @@ static int s3c2410_dma_dostop(s3c2410_dma_chan_t *chan)
 
        tmp = dma_rdreg(chan, S3C2410_DMA_DMASKTRIG);
        tmp |= S3C2410_DMASKTRIG_STOP;
+       //tmp &= ~S3C2410_DMASKTRIG_ON;
        dma_wrreg(chan, S3C2410_DMA_DMASKTRIG, tmp);
 
 #if 0
@@ -819,6 +871,7 @@ static int s3c2410_dma_dostop(s3c2410_dma_chan_t *chan)
        dma_wrreg(chan, S3C2410_DMA_DCON, tmp);
 #endif
 
+       /* should stop do this, or should we wait for flush? */
        chan->state      = S3C2410_DMA_IDLE;
        chan->load_state = S3C2410_DMALOAD_NONE;
 
@@ -827,6 +880,22 @@ static int s3c2410_dma_dostop(s3c2410_dma_chan_t *chan)
        return 0;
 }
 
+void s3c2410_dma_waitforstop(s3c2410_dma_chan_t *chan)
+{
+       unsigned long tmp;
+       unsigned int timeout = 0x10000;
+
+       while (timeout-- > 0) {
+               tmp = dma_rdreg(chan, S3C2410_DMA_DMASKTRIG);
+
+               if (!(tmp & S3C2410_DMASKTRIG_ON))
+                       return;
+       }
+
+       pr_debug("dma%d: failed to stop?\n", chan->number);
+}
+
+
 /* s3c2410_dma_flush
  *
  * stop the channel, and remove all current and pending transfers
@@ -837,7 +906,9 @@ static int s3c2410_dma_flush(s3c2410_dma_chan_t *chan)
        s3c2410_dma_buf_t *buf, *next;
        unsigned long flags;
 
-       pr_debug("%s:\n", __FUNCTION__);
+       pr_debug("%s: chan %p (%d)\n", __FUNCTION__, chan, chan->number);
+
+       dbg_showchan(chan);
 
        local_irq_save(flags);
 
@@ -864,11 +935,64 @@ static int s3c2410_dma_flush(s3c2410_dma_chan_t *chan)
                }
        }
 
+       dbg_showregs(chan);
+
+       s3c2410_dma_waitforstop(chan);
+
+#if 0
+       /* should also clear interrupts, according to WinCE BSP */
+       {
+               unsigned long tmp;
+
+               tmp = dma_rdreg(chan, S3C2410_DMA_DCON);
+               tmp |= S3C2410_DCON_NORELOAD;
+               dma_wrreg(chan, S3C2410_DMA_DCON, tmp);
+       }
+#endif
+
+       dbg_showregs(chan);
+
        local_irq_restore(flags);
 
        return 0;
 }
 
+int
+s3c2410_dma_started(s3c2410_dma_chan_t *chan)
+{
+       unsigned long flags;
+
+       local_irq_save(flags);
+
+       dbg_showchan(chan);
+
+       /* if we've only loaded one buffer onto the channel, then chec
+        * to see if we have another, and if so, try and load it so when
+        * the first buffer is finished, the new one will be loaded onto
+        * the channel */
+
+       if (chan->next != NULL) {
+               if (chan->load_state == S3C2410_DMALOAD_1LOADED) {
+
+                       if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {
+                               pr_debug("%s: buff not yet loaded, no more todo\n",
+                                        __FUNCTION__);
+                       } else {
+                               chan->load_state = S3C2410_DMALOAD_1RUNNING;
+                               s3c2410_dma_loadbuffer(chan, chan->next);
+                       }
+
+               } else if (chan->load_state == S3C2410_DMALOAD_1RUNNING) {
+                       s3c2410_dma_loadbuffer(chan, chan->next);
+               }
+       }
+
+
+       local_irq_restore(flags);
+
+       return 0;
+
+}
 
 int
 s3c2410_dma_ctrl(dmach_t channel, s3c2410_chan_op_t op)
@@ -885,14 +1009,15 @@ s3c2410_dma_ctrl(dmach_t channel, s3c2410_chan_op_t op)
                return s3c2410_dma_dostop(chan);
 
        case S3C2410_DMAOP_PAUSE:
-               return -ENOENT;
-
        case S3C2410_DMAOP_RESUME:
                return -ENOENT;
 
        case S3C2410_DMAOP_FLUSH:
                return s3c2410_dma_flush(chan);
 
+       case S3C2410_DMAOP_STARTED:
+               return s3c2410_dma_started(chan);
+
        case S3C2410_DMAOP_TIMEOUT:
                return 0;
 
index c4e3f8c..f2bbef0 100644 (file)
@@ -285,7 +285,7 @@ static struct flash_platform_data versatile_flash_data = {
 
 static struct resource versatile_flash_resource = {
        .start                  = VERSATILE_FLASH_BASE,
-       .end                    = VERSATILE_FLASH_BASE + VERSATILE_FLASH_SIZE,
+       .end                    = VERSATILE_FLASH_BASE + VERSATILE_FLASH_SIZE - 1,
        .flags                  = IORESOURCE_MEM,
 };
 
index 0db6387..ee003bc 100644 (file)
@@ -59,7 +59,7 @@ static inline int gsi_irq_sharing(int gsi) { return gsi; }
 
 #define BAD_MADT_ENTRY(entry, end) (                                       \
                (!entry) || (unsigned long)entry + sizeof(*entry) > end ||  \
-               ((acpi_table_entry_header *)entry)->length != sizeof(*entry))
+               ((acpi_table_entry_header *)entry)->length < sizeof(*entry))
 
 #define PREFIX                 "ACPI: "
 
index 9f408ee..b781b38 100644 (file)
@@ -292,7 +292,10 @@ ENTRY(do_suspend_lowlevel)
        pushl   $3
        call    acpi_enter_sleep_state
        addl    $4, %esp
-       ret
+
+#      In case of S3 failure, we'll emerge here.  Jump
+#      to ret_point to recover
+       jmp     ret_point
        .p2align 4,,7
 ret_point:
        call    restore_registers
index 99761b8..0176556 100644 (file)
@@ -55,7 +55,7 @@
 
 #define BAD_MADT_ENTRY(entry, end) (                                        \
                (!entry) || (unsigned long)entry + sizeof(*entry) > end ||  \
-               ((acpi_table_entry_header *)entry)->length != sizeof(*entry))
+               ((acpi_table_entry_header *)entry)->length < sizeof(*entry))
 
 #define PREFIX                 "ACPI: "
 
diff --git a/arch/powerpc/boot/dts/mpc8540ads.dts b/arch/powerpc/boot/dts/mpc8540ads.dts
new file mode 100644 (file)
index 0000000..5f41c1f
--- /dev/null
@@ -0,0 +1,257 @@
+/*
+ * MPC8540 ADS Device Tree Source
+ *
+ * Copyright 2006 Freescale Semiconductor Inc.
+ *
+ * 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.
+ */
+
+
+/ {
+       model = "MPC8540ADS";
+       compatible = "MPC85xxADS";
+       #address-cells = <1>;
+       #size-cells = <1>;
+       linux,phandle = <100>;
+
+       cpus {
+               #cpus = <1>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               linux,phandle = <200>;
+
+               PowerPC,8540@0 {
+                       device_type = "cpu";
+                       reg = <0>;
+                       d-cache-line-size = <20>;       // 32 bytes
+                       i-cache-line-size = <20>;       // 32 bytes
+                       d-cache-size = <8000>;          // L1, 32K
+                       i-cache-size = <8000>;          // L1, 32K
+                       timebase-frequency = <0>;       //  33 MHz, from uboot
+                       bus-frequency = <0>;    // 166 MHz
+                       clock-frequency = <0>;  // 825 MHz, from uboot
+                       32-bit;
+                       linux,phandle = <201>;
+               };
+       };
+
+       memory {
+               device_type = "memory";
+               linux,phandle = <300>;
+               reg = <00000000 08000000>;      // 128M at 0x0
+       };
+
+       soc8540@e0000000 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               #interrupt-cells = <2>;
+               device_type = "soc";
+               ranges = <0 e0000000 00100000>;
+               reg = <e0000000 00100000>;      // CCSRBAR 1M
+               bus-frequency = <0>;
+
+               i2c@3000 {
+                       device_type = "i2c";
+                       compatible = "fsl-i2c";
+                       reg = <3000 100>;
+                       interrupts = <1b 2>;
+                       interrupt-parent = <40000>;
+                       dfsrr;
+               };
+
+               mdio@24520 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       device_type = "mdio";
+                       compatible = "gianfar";
+                       reg = <24520 20>;
+                       linux,phandle = <24520>;
+                       ethernet-phy@0 {
+                               linux,phandle = <2452000>;
+                               interrupt-parent = <40000>;
+                               interrupts = <35 1>;
+                               reg = <0>;
+                               device_type = "ethernet-phy";
+                       };
+                       ethernet-phy@1 {
+                               linux,phandle = <2452001>;
+                               interrupt-parent = <40000>;
+                               interrupts = <35 1>;
+                               reg = <1>;
+                               device_type = "ethernet-phy";
+                       };
+                       ethernet-phy@3 {
+                               linux,phandle = <2452003>;
+                               interrupt-parent = <40000>;
+                               interrupts = <37 1>;
+                               reg = <3>;
+                               device_type = "ethernet-phy";
+                       };
+               };
+
+               ethernet@24000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       device_type = "network";
+                       model = "TSEC";
+                       compatible = "gianfar";
+                       reg = <24000 1000>;
+                       address = [ 00 E0 0C 00 73 00 ];
+                       local-mac-address = [ 00 E0 0C 00 73 00 ];
+                       interrupts = <d 2 e 2 12 2>;
+                       interrupt-parent = <40000>;
+                       phy-handle = <2452000>;
+               };
+
+               ethernet@25000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       device_type = "network";
+                       model = "TSEC";
+                       compatible = "gianfar";
+                       reg = <25000 1000>;
+                       address = [ 00 E0 0C 00 73 01 ];
+                       local-mac-address = [ 00 E0 0C 00 73 01 ];
+                       interrupts = <13 2 14 2 18 2>;
+                       interrupt-parent = <40000>;
+                       phy-handle = <2452001>;
+               };
+
+               ethernet@26000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       device_type = "network";
+                       model = "FEC";
+                       compatible = "gianfar";
+                       reg = <26000 1000>;
+                       address = [ 00 E0 0C 00 73 02 ];
+                       local-mac-address = [ 00 E0 0C 00 73 02 ];
+                       interrupts = <19 2>;
+                       interrupt-parent = <40000>;
+                       phy-handle = <2452003>;
+               };
+
+               serial@4500 {
+                       device_type = "serial";
+                       compatible = "ns16550";
+                       reg = <4500 100>;       // reg base, size
+                       clock-frequency = <0>;  // should we fill in in uboot?
+                       interrupts = <1a 2>;
+                       interrupt-parent = <40000>;
+               };
+
+               serial@4600 {
+                       device_type = "serial";
+                       compatible = "ns16550";
+                       reg = <4600 100>;       // reg base, size
+                       clock-frequency = <0>;  // should we fill in in uboot?
+                       interrupts = <1a 2>;
+                       interrupt-parent = <40000>;
+               };
+               pci@8000 {
+                       linux,phandle = <8000>;
+                       interrupt-map-mask = <f800 0 0 7>;
+                       interrupt-map = <
+
+                               /* IDSEL 0x02 */
+                               1000 0 0 1 40000 31 1
+                               1000 0 0 2 40000 32 1
+                               1000 0 0 3 40000 33 1
+                               1000 0 0 4 40000 34 1
+
+                               /* IDSEL 0x03 */
+                               1800 0 0 1 40000 34 1
+                               1800 0 0 2 40000 31 1
+                               1800 0 0 3 40000 32 1
+                               1800 0 0 4 40000 33 1
+
+                               /* IDSEL 0x04 */
+                               2000 0 0 1 40000 33 1
+                               2000 0 0 2 40000 34 1
+                               2000 0 0 3 40000 31 1
+                               2000 0 0 4 40000 32 1
+
+                               /* IDSEL 0x05 */
+                               2800 0 0 1 40000 32 1
+                               2800 0 0 2 40000 33 1
+                               2800 0 0 3 40000 34 1
+                               2800 0 0 4 40000 31 1
+
+                               /* IDSEL 0x0c */
+                               6000 0 0 1 40000 31 1
+                               6000 0 0 2 40000 32 1
+                               6000 0 0 3 40000 33 1
+                               6000 0 0 4 40000 34 1
+
+                               /* IDSEL 0x0d */
+                               6800 0 0 1 40000 34 1
+                               6800 0 0 2 40000 31 1
+                               6800 0 0 3 40000 32 1
+                               6800 0 0 4 40000 33 1
+
+                               /* IDSEL 0x0e */
+                               7000 0 0 1 40000 33 1
+                               7000 0 0 2 40000 34 1
+                               7000 0 0 3 40000 31 1
+                               7000 0 0 4 40000 32 1
+
+                               /* IDSEL 0x0f */
+                               7800 0 0 1 40000 32 1
+                               7800 0 0 2 40000 33 1
+                               7800 0 0 3 40000 34 1
+                               7800 0 0 4 40000 31 1
+
+                               /* IDSEL 0x12 */
+                               9000 0 0 1 40000 31 1
+                               9000 0 0 2 40000 32 1
+                               9000 0 0 3 40000 33 1
+                               9000 0 0 4 40000 34 1
+
+                               /* IDSEL 0x13 */
+                               9800 0 0 1 40000 34 1
+                               9800 0 0 2 40000 31 1
+                               9800 0 0 3 40000 32 1
+                               9800 0 0 4 40000 33 1
+
+                               /* IDSEL 0x14 */
+                               a000 0 0 1 40000 33 1
+                               a000 0 0 2 40000 34 1
+                               a000 0 0 3 40000 31 1
+                               a000 0 0 4 40000 32 1
+
+                               /* IDSEL 0x15 */
+                               a800 0 0 1 40000 32 1
+                               a800 0 0 2 40000 33 1
+                               a800 0 0 3 40000 34 1
+                               a800 0 0 4 40000 31 1>;
+                       interrupt-parent = <40000>;
+                       interrupts = <08 2>;
+                       bus-range = <0 0>;
+                       ranges = <02000000 0 80000000 80000000 0 20000000
+                                 01000000 0 00000000 e2000000 0 00100000>;
+                       clock-frequency = <3f940aa>;
+                       #interrupt-cells = <1>;
+                       #size-cells = <2>;
+                       #address-cells = <3>;
+                       reg = <8000 1000>;
+                       compatible = "85xx";
+                       device_type = "pci";
+               };
+
+               pic@40000 {
+                       linux,phandle = <40000>;
+                       clock-frequency = <0>;
+                       interrupt-controller;
+                       #address-cells = <0>;
+                       #interrupt-cells = <2>;
+                       reg = <40000 40000>;
+                       built-in;
+                       compatible = "chrp,open-pic";
+                       device_type = "open-pic";
+                       big-endian;
+               };
+       };
+};
diff --git a/arch/powerpc/boot/dts/mpc8541cds.dts b/arch/powerpc/boot/dts/mpc8541cds.dts
new file mode 100644 (file)
index 0000000..7be0bc6
--- /dev/null
@@ -0,0 +1,244 @@
+/*
+ * MPC8541 CDS Device Tree Source
+ *
+ * Copyright 2006 Freescale Semiconductor Inc.
+ *
+ * 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.
+ */
+
+
+/ {
+       model = "MPC8541CDS";
+       compatible = "MPC85xxCDS";
+       #address-cells = <1>;
+       #size-cells = <1>;
+       linux,phandle = <100>;
+
+       cpus {
+               #cpus = <1>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               linux,phandle = <200>;
+
+               PowerPC,8541@0 {
+                       device_type = "cpu";
+                       reg = <0>;
+                       d-cache-line-size = <20>;       // 32 bytes
+                       i-cache-line-size = <20>;       // 32 bytes
+                       d-cache-size = <8000>;          // L1, 32K
+                       i-cache-size = <8000>;          // L1, 32K
+                       timebase-frequency = <0>;       //  33 MHz, from uboot
+                       bus-frequency = <0>;    // 166 MHz
+                       clock-frequency = <0>;  // 825 MHz, from uboot
+                       32-bit;
+                       linux,phandle = <201>;
+               };
+       };
+
+       memory {
+               device_type = "memory";
+               linux,phandle = <300>;
+               reg = <00000000 08000000>;      // 128M at 0x0
+       };
+
+       soc8541@e0000000 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               #interrupt-cells = <2>;
+               device_type = "soc";
+               ranges = <0 e0000000 00100000>;
+               reg = <e0000000 00100000>;      // CCSRBAR 1M
+               bus-frequency = <0>;
+
+               i2c@3000 {
+                       device_type = "i2c";
+                       compatible = "fsl-i2c";
+                       reg = <3000 100>;
+                       interrupts = <1b 2>;
+                       interrupt-parent = <40000>;
+                       dfsrr;
+               };
+
+               mdio@24520 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       device_type = "mdio";
+                       compatible = "gianfar";
+                       reg = <24520 20>;
+                       linux,phandle = <24520>;
+                       ethernet-phy@0 {
+                               linux,phandle = <2452000>;
+                               interrupt-parent = <40000>;
+                               interrupts = <35 0>;
+                               reg = <0>;
+                               device_type = "ethernet-phy";
+                       };
+                       ethernet-phy@1 {
+                               linux,phandle = <2452001>;
+                               interrupt-parent = <40000>;
+                               interrupts = <35 0>;
+                               reg = <1>;
+                               device_type = "ethernet-phy";
+                       };
+               };
+
+               ethernet@24000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       device_type = "network";
+                       model = "TSEC";
+                       compatible = "gianfar";
+                       reg = <24000 1000>;
+                       local-mac-address = [ 00 E0 0C 00 73 00 ];
+                       interrupts = <d 2 e 2 12 2>;
+                       interrupt-parent = <40000>;
+                       phy-handle = <2452000>;
+               };
+
+               ethernet@25000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       device_type = "network";
+                       model = "TSEC";
+                       compatible = "gianfar";
+                       reg = <25000 1000>;
+                       local-mac-address = [ 00 E0 0C 00 73 01 ];
+                       interrupts = <13 2 14 2 18 2>;
+                       interrupt-parent = <40000>;
+                       phy-handle = <2452001>;
+               };
+
+               serial@4500 {
+                       device_type = "serial";
+                       compatible = "ns16550";
+                       reg = <4500 100>;       // reg base, size
+                       clock-frequency = <0>;  // should we fill in in uboot?
+                       interrupts = <1a 2>;
+                       interrupt-parent = <40000>;
+               };
+
+               serial@4600 {
+                       device_type = "serial";
+                       compatible = "ns16550";
+                       reg = <4600 100>;       // reg base, size
+                       clock-frequency = <0>;  // should we fill in in uboot?
+                       interrupts = <1a 2>;
+                       interrupt-parent = <40000>;
+               };
+
+               pci@8000 {
+                       linux,phandle = <8000>;
+                       interrupt-map-mask = <1f800 0 0 7>;
+                       interrupt-map = <
+
+                               /* IDSEL 0x10 */
+                               08000 0 0 1 40000 30 1
+                               08000 0 0 2 40000 31 1
+                               08000 0 0 3 40000 32 1
+                               08000 0 0 4 40000 33 1
+
+                               /* IDSEL 0x11 */
+                               08800 0 0 1 40000 30 1
+                               08800 0 0 2 40000 31 1
+                               08800 0 0 3 40000 32 1
+                               08800 0 0 4 40000 33 1
+
+                               /* IDSEL 0x12 (Slot 1) */
+                               09000 0 0 1 40000 30 1
+                               09000 0 0 2 40000 31 1
+                               09000 0 0 3 40000 32 1
+                               09000 0 0 4 40000 33 1
+
+                               /* IDSEL 0x13 (Slot 2) */
+                               09800 0 0 1 40000 31 1
+                               09800 0 0 2 40000 32 1
+                               09800 0 0 3 40000 33 1
+                               09800 0 0 4 40000 30 1
+
+                               /* IDSEL 0x14 (Slot 3) */
+                               0a000 0 0 1 40000 32 1
+                               0a000 0 0 2 40000 33 1
+                               0a000 0 0 3 40000 30 1
+                               0a000 0 0 4 40000 31 1
+
+                               /* IDSEL 0x15 (Slot 4) */
+                               0a800 0 0 1 40000 33 1
+                               0a800 0 0 2 40000 30 1
+                               0a800 0 0 3 40000 31 1
+                               0a800 0 0 4 40000 32 1
+
+                               /* Bus 1 (Tundra Bridge) */
+                               /* IDSEL 0x12 (ISA bridge) */
+                               19000 0 0 1 40000 30 1
+                               19000 0 0 2 40000 31 1
+                               19000 0 0 3 40000 32 1
+                               19000 0 0 4 40000 33 1>;
+                       interrupt-parent = <40000>;
+                       interrupts = <08 2>;
+                       bus-range = <0 0>;
+                       ranges = <02000000 0 80000000 80000000 0 20000000
+                                 01000000 0 00000000 e2000000 0 00100000>;
+                       clock-frequency = <3f940aa>;
+                       #interrupt-cells = <1>;
+                       #size-cells = <2>;
+                       #address-cells = <3>;
+                       reg = <8000 1000>;
+                       compatible = "85xx";
+                       device_type = "pci";
+
+                       i8259@19000 {
+                               clock-frequency = <0>;
+                               interrupt-controller;
+                               device_type = "interrupt-controller";
+                               reg = <19000 0 0 0 1>;
+                               #address-cells = <0>;
+                               #interrupt-cells = <2>;
+                               built-in;
+                               compatible = "chrp,iic";
+                               big-endian;
+                               interrupts = <1>;
+                               interrupt-parent = <8000>;
+                       };
+               };
+
+               pci@9000 {
+                       linux,phandle = <9000>;
+                       interrupt-map-mask = <f800 0 0 7>;
+                       interrupt-map = <
+
+                               /* IDSEL 0x15 */
+                               a800 0 0 1 40000 3b 1
+                               a800 0 0 2 40000 3b 1
+                               a800 0 0 3 40000 3b 1
+                               a800 0 0 4 40000 3b 1>;
+                       interrupt-parent = <40000>;
+                       interrupts = <09 2>;
+                       bus-range = <0 0>;
+                       ranges = <02000000 0 a0000000 a0000000 0 20000000
+                                 01000000 0 00000000 e3000000 0 00100000>;
+                       clock-frequency = <3f940aa>;
+                       #interrupt-cells = <1>;
+                       #size-cells = <2>;
+                       #address-cells = <3>;
+                       reg = <9000 1000>;
+                       compatible = "85xx";
+                       device_type = "pci";
+               };
+
+               pic@40000 {
+                       linux,phandle = <40000>;
+                       clock-frequency = <0>;
+                       interrupt-controller;
+                       #address-cells = <0>;
+                       #interrupt-cells = <2>;
+                       reg = <40000 40000>;
+                       built-in;
+                       compatible = "chrp,open-pic";
+                       device_type = "open-pic";
+                        big-endian;
+               };
+       };
+};
diff --git a/arch/powerpc/boot/dts/mpc8548cds.dts b/arch/powerpc/boot/dts/mpc8548cds.dts
new file mode 100644 (file)
index 0000000..893d795
--- /dev/null
@@ -0,0 +1,287 @@
+/*
+ * MPC8555 CDS Device Tree Source
+ *
+ * Copyright 2006 Freescale Semiconductor Inc.
+ *
+ * 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.
+ */
+
+
+/ {
+       model = "MPC8548CDS";
+       compatible = "MPC85xxCDS";
+       #address-cells = <1>;
+       #size-cells = <1>;
+       linux,phandle = <100>;
+
+       cpus {
+               #cpus = <1>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               linux,phandle = <200>;
+
+               PowerPC,8548@0 {
+                       device_type = "cpu";
+                       reg = <0>;
+                       d-cache-line-size = <20>;       // 32 bytes
+                       i-cache-line-size = <20>;       // 32 bytes
+                       d-cache-size = <8000>;          // L1, 32K
+                       i-cache-size = <8000>;          // L1, 32K
+                       timebase-frequency = <0>;       //  33 MHz, from uboot
+                       bus-frequency = <0>;    // 166 MHz
+                       clock-frequency = <0>;  // 825 MHz, from uboot
+                       32-bit;
+                       linux,phandle = <201>;
+               };
+       };
+
+       memory {
+               device_type = "memory";
+               linux,phandle = <300>;
+               reg = <00000000 08000000>;      // 128M at 0x0
+       };
+
+       soc8548@e0000000 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               #interrupt-cells = <2>;
+               device_type = "soc";
+               ranges = <0 e0000000 00100000>;
+               reg = <e0000000 00100000>;      // CCSRBAR 1M
+               bus-frequency = <0>;
+
+               i2c@3000 {
+                       device_type = "i2c";
+                       compatible = "fsl-i2c";
+                       reg = <3000 100>;
+                       interrupts = <1b 2>;
+                       interrupt-parent = <40000>;
+                       dfsrr;
+               };
+
+               mdio@24520 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       device_type = "mdio";
+                       compatible = "gianfar";
+                       reg = <24520 20>;
+                       linux,phandle = <24520>;
+                       ethernet-phy@0 {
+                               linux,phandle = <2452000>;
+                               interrupt-parent = <40000>;
+                               interrupts = <35 0>;
+                               reg = <0>;
+                               device_type = "ethernet-phy";
+                       };
+                       ethernet-phy@1 {
+                               linux,phandle = <2452001>;
+                               interrupt-parent = <40000>;
+                               interrupts = <35 0>;
+                               reg = <1>;
+                               device_type = "ethernet-phy";
+                       };
+
+                       ethernet-phy@2 {
+                               linux,phandle = <2452002>;
+                               interrupt-parent = <40000>;
+                               interrupts = <35 0>;
+                               reg = <2>;
+                               device_type = "ethernet-phy";
+                       };
+                       ethernet-phy@3 {
+                               linux,phandle = <2452003>;
+                               interrupt-parent = <40000>;
+                               interrupts = <35 0>;
+                               reg = <3>;
+                               device_type = "ethernet-phy";
+                       };
+               };
+
+               ethernet@24000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       device_type = "network";
+                       model = "eTSEC";
+                       compatible = "gianfar";
+                       reg = <24000 1000>;
+                       local-mac-address = [ 00 E0 0C 00 73 00 ];
+                       interrupts = <d 2 e 2 12 2>;
+                       interrupt-parent = <40000>;
+                       phy-handle = <2452000>;
+               };
+
+               ethernet@25000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       device_type = "network";
+                       model = "eTSEC";
+                       compatible = "gianfar";
+                       reg = <25000 1000>;
+                       local-mac-address = [ 00 E0 0C 00 73 01 ];
+                       interrupts = <13 2 14 2 18 2>;
+                       interrupt-parent = <40000>;
+                       phy-handle = <2452001>;
+               };
+
+               ethernet@26000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       device_type = "network";
+                       model = "eTSEC";
+                       compatible = "gianfar";
+                       reg = <26000 1000>;
+                       local-mac-address = [ 00 E0 0C 00 73 02 ];
+                       interrupts = <f 2 10 2 11 2>;
+                       interrupt-parent = <40000>;
+                       phy-handle = <2452001>;
+               };
+
+/* eTSEC 4 is currently broken
+               ethernet@27000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       device_type = "network";
+                       model = "eTSEC";
+                       compatible = "gianfar";
+                       reg = <27000 1000>;
+                       local-mac-address = [ 00 E0 0C 00 73 03 ];
+                       interrupts = <15 2 16 2 17 2>;
+                       interrupt-parent = <40000>;
+                       phy-handle = <2452001>;
+               };
+ */
+
+               serial@4500 {
+                       device_type = "serial";
+                       compatible = "ns16550";
+                       reg = <4500 100>;       // reg base, size
+                       clock-frequency = <0>;  // should we fill in in uboot?
+                       interrupts = <1a 2>;
+                       interrupt-parent = <40000>;
+               };
+
+               serial@4600 {
+                       device_type = "serial";
+                       compatible = "ns16550";
+                       reg = <4600 100>;       // reg base, size
+                       clock-frequency = <0>;  // should we fill in in uboot?
+                       interrupts = <1a 2>;
+                       interrupt-parent = <40000>;
+               };
+
+               pci@8000 {
+                       linux,phandle = <8000>;
+                       interrupt-map-mask = <1f800 0 0 7>;
+                       interrupt-map = <
+
+                               /* IDSEL 0x10 */
+                               08000 0 0 1 40000 30 1
+                               08000 0 0 2 40000 31 1
+                               08000 0 0 3 40000 32 1
+                               08000 0 0 4 40000 33 1
+
+                               /* IDSEL 0x11 */
+                               08800 0 0 1 40000 30 1
+                               08800 0 0 2 40000 31 1
+                               08800 0 0 3 40000 32 1
+                               08800 0 0 4 40000 33 1
+
+                               /* IDSEL 0x12 (Slot 1) */
+                               09000 0 0 1 40000 30 1
+                               09000 0 0 2 40000 31 1
+                               09000 0 0 3 40000 32 1
+                               09000 0 0 4 40000 33 1
+
+                               /* IDSEL 0x13 (Slot 2) */
+                               09800 0 0 1 40000 31 1
+                               09800 0 0 2 40000 32 1
+                               09800 0 0 3 40000 33 1
+                               09800 0 0 4 40000 30 1
+
+                               /* IDSEL 0x14 (Slot 3) */
+                               0a000 0 0 1 40000 32 1
+                               0a000 0 0 2 40000 33 1
+                               0a000 0 0 3 40000 30 1
+                               0a000 0 0 4 40000 31 1
+
+                               /* IDSEL 0x15 (Slot 4) */
+                               0a800 0 0 1 40000 33 1
+                               0a800 0 0 2 40000 30 1
+                               0a800 0 0 3 40000 31 1
+                               0a800 0 0 4 40000 32 1
+
+                               /* Bus 1 (Tundra Bridge) */
+                               /* IDSEL 0x12 (ISA bridge) */
+                               19000 0 0 1 40000 30 1
+                               19000 0 0 2 40000 31 1
+                               19000 0 0 3 40000 32 1
+                               19000 0 0 4 40000 33 1>;
+                       interrupt-parent = <40000>;
+                       interrupts = <08 2>;
+                       bus-range = <0 0>;
+                       ranges = <02000000 0 80000000 80000000 0 20000000
+                                 01000000 0 00000000 e2000000 0 00100000>;
+                       clock-frequency = <3f940aa>;
+                       #interrupt-cells = <1>;
+                       #size-cells = <2>;
+                       #address-cells = <3>;
+                       reg = <8000 1000>;
+                       compatible = "85xx";
+                       device_type = "pci";
+
+                       i8259@19000 {
+                               clock-frequency = <0>;
+                               interrupt-controller;
+                               device_type = "interrupt-controller";
+                               reg = <19000 0 0 0 1>;
+                               #address-cells = <0>;
+                               #interrupt-cells = <2>;
+                               built-in;
+                               compatible = "chrp,iic";
+                               big-endian;
+                               interrupts = <1>;
+                               interrupt-parent = <8000>;
+                       };
+               };
+
+               pci@9000 {
+                       linux,phandle = <9000>;
+                       interrupt-map-mask = <f800 0 0 7>;
+                       interrupt-map = <
+
+                               /* IDSEL 0x15 */
+                               a800 0 0 1 40000 3b 1
+                               a800 0 0 2 40000 3b 1
+                               a800 0 0 3 40000 3b 1
+                               a800 0 0 4 40000 3b 1>;
+                       interrupt-parent = <40000>;
+                       interrupts = <09 2>;
+                       bus-range = <0 0>;
+                       ranges = <02000000 0 a0000000 a0000000 0 20000000
+                                 01000000 0 00000000 e3000000 0 00100000>;
+                       clock-frequency = <3f940aa>;
+                       #interrupt-cells = <1>;
+                       #size-cells = <2>;
+                       #address-cells = <3>;
+                       reg = <9000 1000>;
+                       compatible = "85xx";
+                       device_type = "pci";
+               };
+
+               pic@40000 {
+                       linux,phandle = <40000>;
+                       clock-frequency = <0>;
+                       interrupt-controller;
+                       #address-cells = <0>;
+                       #interrupt-cells = <2>;
+                       reg = <40000 40000>;
+                       built-in;
+                       compatible = "chrp,open-pic";
+                       device_type = "open-pic";
+                        big-endian;
+               };
+       };
+};
diff --git a/arch/powerpc/boot/dts/mpc8555cds.dts b/arch/powerpc/boot/dts/mpc8555cds.dts
new file mode 100644 (file)
index 0000000..118f5a8
--- /dev/null
@@ -0,0 +1,244 @@
+/*
+ * MPC8555 CDS Device Tree Source
+ *
+ * Copyright 2006 Freescale Semiconductor Inc.
+ *
+ * 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.
+ */
+
+
+/ {
+       model = "MPC8555CDS";
+       compatible = "MPC85xxCDS";
+       #address-cells = <1>;
+       #size-cells = <1>;
+       linux,phandle = <100>;
+
+       cpus {
+               #cpus = <1>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               linux,phandle = <200>;
+
+               PowerPC,8555@0 {
+                       device_type = "cpu";
+                       reg = <0>;
+                       d-cache-line-size = <20>;       // 32 bytes
+                       i-cache-line-size = <20>;       // 32 bytes
+                       d-cache-size = <8000>;          // L1, 32K
+                       i-cache-size = <8000>;          // L1, 32K
+                       timebase-frequency = <0>;       //  33 MHz, from uboot
+                       bus-frequency = <0>;    // 166 MHz
+                       clock-frequency = <0>;  // 825 MHz, from uboot
+                       32-bit;
+                       linux,phandle = <201>;
+               };
+       };
+
+       memory {
+               device_type = "memory";
+               linux,phandle = <300>;
+               reg = <00000000 08000000>;      // 128M at 0x0
+       };
+
+       soc8555@e0000000 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               #interrupt-cells = <2>;
+               device_type = "soc";
+               ranges = <0 e0000000 00100000>;
+               reg = <e0000000 00100000>;      // CCSRBAR 1M
+               bus-frequency = <0>;
+
+               i2c@3000 {
+                       device_type = "i2c";
+                       compatible = "fsl-i2c";
+                       reg = <3000 100>;
+                       interrupts = <1b 2>;
+                       interrupt-parent = <40000>;
+                       dfsrr;
+               };
+
+               mdio@24520 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       device_type = "mdio";
+                       compatible = "gianfar";
+                       reg = <24520 20>;
+                       linux,phandle = <24520>;
+                       ethernet-phy@0 {
+                               linux,phandle = <2452000>;
+                               interrupt-parent = <40000>;
+                               interrupts = <35 0>;
+                               reg = <0>;
+                               device_type = "ethernet-phy";
+                       };
+                       ethernet-phy@1 {
+                               linux,phandle = <2452001>;
+                               interrupt-parent = <40000>;
+                               interrupts = <35 0>;
+                               reg = <1>;
+                               device_type = "ethernet-phy";
+                       };
+               };
+
+               ethernet@24000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       device_type = "network";
+                       model = "TSEC";
+                       compatible = "gianfar";
+                       reg = <24000 1000>;
+                       local-mac-address = [ 00 E0 0C 00 73 00 ];
+                       interrupts = <0d 2 0e 2 12 2>;
+                       interrupt-parent = <40000>;
+                       phy-handle = <2452000>;
+               };
+
+               ethernet@25000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       device_type = "network";
+                       model = "TSEC";
+                       compatible = "gianfar";
+                       reg = <25000 1000>;
+                       local-mac-address = [ 00 E0 0C 00 73 01 ];
+                       interrupts = <13 2 14 2 18 2>;
+                       interrupt-parent = <40000>;
+                       phy-handle = <2452001>;
+               };
+
+               serial@4500 {
+                       device_type = "serial";
+                       compatible = "ns16550";
+                       reg = <4500 100>;       // reg base, size
+                       clock-frequency = <0>;  // should we fill in in uboot?
+                       interrupts = <1a 2>;
+                       interrupt-parent = <40000>;
+               };
+
+               serial@4600 {
+                       device_type = "serial";
+                       compatible = "ns16550";
+                       reg = <4600 100>;       // reg base, size
+                       clock-frequency = <0>;  // should we fill in in uboot?
+                       interrupts = <1a 2>;
+                       interrupt-parent = <40000>;
+               };
+
+               pci@8000 {
+                       linux,phandle = <8000>;
+                       interrupt-map-mask = <1f800 0 0 7>;
+                       interrupt-map = <
+
+                               /* IDSEL 0x10 */
+                               08000 0 0 1 40000 30 1
+                               08000 0 0 2 40000 31 1
+                               08000 0 0 3 40000 32 1
+                               08000 0 0 4 40000 33 1
+
+                               /* IDSEL 0x11 */
+                               08800 0 0 1 40000 30 1
+                               08800 0 0 2 40000 31 1
+                               08800 0 0 3 40000 32 1
+                               08800 0 0 4 40000 33 1
+
+                               /* IDSEL 0x12 (Slot 1) */
+                               09000 0 0 1 40000 30 1
+                               09000 0 0 2 40000 31 1
+                               09000 0 0 3 40000 32 1
+                               09000 0 0 4 40000 33 1
+
+                               /* IDSEL 0x13 (Slot 2) */
+                               09800 0 0 1 40000 31 1
+                               09800 0 0 2 40000 32 1
+                               09800 0 0 3 40000 33 1
+                               09800 0 0 4 40000 30 1
+
+                               /* IDSEL 0x14 (Slot 3) */
+                               0a000 0 0 1 40000 32 1
+                               0a000 0 0 2 40000 33 1
+                               0a000 0 0 3 40000 30 1
+                               0a000 0 0 4 40000 31 1
+
+                               /* IDSEL 0x15 (Slot 4) */
+                               0a800 0 0 1 40000 33 1
+                               0a800 0 0 2 40000 30 1
+                               0a800 0 0 3 40000 31 1
+                               0a800 0 0 4 40000 32 1
+
+                               /* Bus 1 (Tundra Bridge) */
+                               /* IDSEL 0x12 (ISA bridge) */
+                               19000 0 0 1 40000 30 1
+                               19000 0 0 2 40000 31 1
+                               19000 0 0 3 40000 32 1
+                               19000 0 0 4 40000 33 1>;
+                       interrupt-parent = <40000>;
+                       interrupts = <08 2>;
+                       bus-range = <0 0>;
+                       ranges = <02000000 0 80000000 80000000 0 20000000
+                                 01000000 0 00000000 e2000000 0 00100000>;
+                       clock-frequency = <3f940aa>;
+                       #interrupt-cells = <1>;
+                       #size-cells = <2>;
+                       #address-cells = <3>;
+                       reg = <8000 1000>;
+                       compatible = "85xx";
+                       device_type = "pci";
+
+                       i8259@19000 {
+                               clock-frequency = <0>;
+                               interrupt-controller;
+                               device_type = "interrupt-controller";
+                               reg = <19000 0 0 0 1>;
+                               #address-cells = <0>;
+                               #interrupt-cells = <2>;
+                               built-in;
+                               compatible = "chrp,iic";
+                               big-endian;
+                               interrupts = <1>;
+                               interrupt-parent = <8000>;
+                       };
+               };
+
+               pci@9000 {
+                       linux,phandle = <9000>;
+                       interrupt-map-mask = <f800 0 0 7>;
+                       interrupt-map = <
+
+                               /* IDSEL 0x15 */
+                               a800 0 0 1 40000 3b 1
+                               a800 0 0 2 40000 3b 1
+                               a800 0 0 3 40000 3b 1
+                               a800 0 0 4 40000 3b 1>;
+                       interrupt-parent = <40000>;
+                       interrupts = <09 2>;
+                       bus-range = <0 0>;
+                       ranges = <02000000 0 a0000000 a0000000 0 20000000
+                                 01000000 0 00000000 e3000000 0 00100000>;
+                       clock-frequency = <3f940aa>;
+                       #interrupt-cells = <1>;
+                       #size-cells = <2>;
+                       #address-cells = <3>;
+                       reg = <9000 1000>;
+                       compatible = "85xx";
+                       device_type = "pci";
+               };
+
+               pic@40000 {
+                       linux,phandle = <40000>;
+                       clock-frequency = <0>;
+                       interrupt-controller;
+                       #address-cells = <0>;
+                       #interrupt-cells = <2>;
+                       reg = <40000 40000>;
+                       built-in;
+                       compatible = "chrp,open-pic";
+                       device_type = "open-pic";
+                        big-endian;
+               };
+       };
+};
index 359ab89..40a3929 100644 (file)
@@ -115,6 +115,7 @@ static int __init add_legacy_soc_port(struct device_node *np,
        u64 addr;
        u32 *addrp;
        upf_t flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ;
+       struct device_node *tsi = of_get_parent(np);
 
        /* We only support ports that have a clock frequency properly
         * encoded in the device-tree.
@@ -134,7 +135,10 @@ static int __init add_legacy_soc_port(struct device_node *np,
        /* Add port, irq will be dealt with later. We passed a translated
         * IO port value. It will be fixed up later along with the irq
         */
-       return add_legacy_port(np, -1, UPIO_MEM, addr, addr, NO_IRQ, flags, 0);
+       if (tsi && !strcmp(tsi->type, "tsi-bridge"))
+               return add_legacy_port(np, -1, UPIO_TSI, addr, addr, NO_IRQ, flags, 0);
+       else
+               return add_legacy_port(np, -1, UPIO_MEM, addr, addr, NO_IRQ, flags, 0);
 }
 
 static int __init add_legacy_isa_port(struct device_node *np,
@@ -464,7 +468,7 @@ static int __init serial_dev_init(void)
                        fixup_port_irq(i, np, port);
                if (port->iotype == UPIO_PORT)
                        fixup_port_pio(i, np, port);
-               if (port->iotype == UPIO_MEM)
+               if ((port->iotype == UPIO_MEM) || (port->iotype == UPIO_TSI))
                        fixup_port_mmio(i, np, port);
        }
 
index 6a7e997..11052c2 100644 (file)
@@ -598,11 +598,6 @@ static struct device_node *of_irq_find_parent(struct device_node *child)
        return p;
 }
 
-static u8 of_irq_pci_swizzle(u8 slot, u8 pin)
-{
-       return (((pin - 1) + slot) % 4) + 1;
-}
-
 /* This doesn't need to be called if you don't have any special workaround
  * flags to pass
  */
@@ -891,6 +886,12 @@ int of_irq_map_one(struct device_node *device, int index, struct of_irq *out_irq
 }
 EXPORT_SYMBOL_GPL(of_irq_map_one);
 
+#ifdef CONFIG_PCI
+static u8 of_irq_pci_swizzle(u8 slot, u8 pin)
+{
+       return (((pin - 1) + slot) % 4) + 1;
+}
+
 int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq)
 {
        struct device_node *dn, *ppnode;
@@ -967,4 +968,4 @@ int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq)
        return of_irq_map_raw(ppnode, &lspec, laddr, out_irq);
 }
 EXPORT_SYMBOL_GPL(of_irq_map_pci);
-
+#endif /* CONFIG_PCI */
index 774c0a3..18e59e4 100644 (file)
@@ -417,7 +417,7 @@ static __inline__ void timer_check_rtc(void)
 /*
  * This version of gettimeofday has microsecond resolution.
  */
-static inline void __do_gettimeofday(struct timeval *tv, u64 tb_val)
+static inline void __do_gettimeofday(struct timeval *tv)
 {
        unsigned long sec, usec;
        u64 tb_ticks, xsec;
@@ -431,7 +431,12 @@ static inline void __do_gettimeofday(struct timeval *tv, u64 tb_val)
         * without a divide (and in fact, without a multiply)
         */
        temp_varp = do_gtod.varp;
-       tb_ticks = tb_val - temp_varp->tb_orig_stamp;
+
+       /* Sampling the time base must be done after loading
+        * do_gtod.varp in order to avoid racing with update_gtod.
+        */
+       data_barrier(temp_varp);
+       tb_ticks = get_tb() - temp_varp->tb_orig_stamp;
        temp_tb_to_xs = temp_varp->tb_to_xs;
        temp_stamp_xsec = temp_varp->stamp_xsec;
        xsec = temp_stamp_xsec + mulhdu(tb_ticks, temp_tb_to_xs);
@@ -464,7 +469,7 @@ void do_gettimeofday(struct timeval *tv)
                tv->tv_usec = usec;
                return;
        }
-       __do_gettimeofday(tv, get_tb());
+       __do_gettimeofday(tv);
 }
 
 EXPORT_SYMBOL(do_gettimeofday);
@@ -650,6 +655,7 @@ void timer_interrupt(struct pt_regs * regs)
        int next_dec;
        int cpu = smp_processor_id();
        unsigned long ticks;
+       u64 tb_next_jiffy;
 
 #ifdef CONFIG_PPC32
        if (atomic_read(&ppc_n_lost_interrupts) != 0)
@@ -691,11 +697,14 @@ void timer_interrupt(struct pt_regs * regs)
                        continue;
 
                write_seqlock(&xtime_lock);
-               tb_last_jiffy += tb_ticks_per_jiffy;
-               tb_last_stamp = per_cpu(last_jiffy, cpu);
-               do_timer(regs);
-               timer_recalc_offset(tb_last_jiffy);
-               timer_check_rtc();
+               tb_next_jiffy = tb_last_jiffy + tb_ticks_per_jiffy;
+               if (per_cpu(last_jiffy, cpu) >= tb_next_jiffy) {
+                       tb_last_jiffy = tb_next_jiffy;
+                       tb_last_stamp = per_cpu(last_jiffy, cpu);
+                       do_timer(regs);
+                       timer_recalc_offset(tb_last_jiffy);
+                       timer_check_rtc();
+               }
                write_sequnlock(&xtime_lock);
        }
        
index e4d1713..9b352bd 100644 (file)
@@ -585,14 +585,14 @@ static void parse_fpe(struct pt_regs *regs)
 #define INST_MFSPR_PVR_MASK    0xfc1fffff
 
 #define INST_DCBA              0x7c0005ec
-#define INST_DCBA_MASK         0x7c0007fe
+#define INST_DCBA_MASK         0xfc0007fe
 
 #define INST_MCRXR             0x7c000400
-#define INST_MCRXR_MASK                0x7c0007fe
+#define INST_MCRXR_MASK                0xfc0007fe
 
 #define INST_STRING            0x7c00042a
-#define INST_STRING_MASK       0x7c0007fe
-#define INST_STRING_GEN_MASK   0x7c00067e
+#define INST_STRING_MASK       0xfc0007fe
+#define INST_STRING_GEN_MASK   0xfc00067e
 #define INST_LSWI              0x7c0004aa
 #define INST_LSWX              0x7c00042a
 #define INST_STSWI             0x7c0005aa
index 266b8b2..5615acc 100644 (file)
@@ -153,7 +153,7 @@ static void free_hugepte_range(struct mmu_gather *tlb, hugepd_t *hpdp)
        hpdp->pd = 0;
        tlb->need_flush = 1;
        pgtable_free_tlb(tlb, pgtable_free_cache(hugepte, HUGEPTE_CACHE_NUM,
-                                                HUGEPTE_TABLE_SIZE-1));
+                                                PGF_CACHENUM_MASK));
 }
 
 #ifdef CONFIG_PPC_64K_PAGES
index 454fc53..c3268d9 100644 (file)
@@ -14,7 +14,6 @@ config MPC8540_ADS
 config MPC85xx_CDS
        bool "Freescale MPC85xx CDS"
        select DEFAULT_UIMAGE
-       select PPC_I8259 if PCI
        help
          This option enables support for the MPC85xx CDS board
 
index 06a4976..9d2acfb 100644 (file)
@@ -37,79 +37,7 @@ unsigned long isa_io_base = 0;
 unsigned long isa_mem_base = 0;
 #endif
 
-/*
- * Internal interrupts are all Level Sensitive, and Positive Polarity
- *
- * Note:  Likely, this table and the following function should be
- *        obtained and derived from the OF Device Tree.
- */
-static u_char mpc85xx_ads_openpic_initsenses[] __initdata = {
-       MPC85XX_INTERNAL_IRQ_SENSES,
-       0x0,                    /* External  0: */
-#if defined(CONFIG_PCI)
-       (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),      /* Ext 1: PCI slot 0 */
-       (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),      /* Ext 2: PCI slot 1 */
-       (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),      /* Ext 3: PCI slot 2 */
-       (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),      /* Ext 4: PCI slot 3 */
-#else
-       0x0,                    /* External  1: */
-       0x0,                    /* External  2: */
-       0x0,                    /* External  3: */
-       0x0,                    /* External  4: */
-#endif
-       (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),      /* External 5: PHY */
-       0x0,                    /* External  6: */
-       (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),      /* External 7: PHY */
-       0x0,                    /* External  8: */
-       0x0,                    /* External  9: */
-       0x0,                    /* External 10: */
-       0x0,                    /* External 11: */
-};
-
 #ifdef CONFIG_PCI
-/*
- * interrupt routing
- */
-
-int
-mpc85xx_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
-{
-       static char pci_irq_table[][4] =
-           /*
-            * This is little evil, but works around the fact
-            * that revA boards have IDSEL starting at 18
-            * and others boards (older) start at 12
-            *
-            *      PCI IDSEL/INTPIN->INTLINE
-            *       A      B      C      D
-            */
-       {
-               {PIRQA, PIRQB, PIRQC, PIRQD},   /* IDSEL 2 */
-               {PIRQD, PIRQA, PIRQB, PIRQC},
-               {PIRQC, PIRQD, PIRQA, PIRQB},
-               {PIRQB, PIRQC, PIRQD, PIRQA},   /* IDSEL 5 */
-               {0, 0, 0, 0},   /* -- */
-               {0, 0, 0, 0},   /* -- */
-               {0, 0, 0, 0},   /* -- */
-               {0, 0, 0, 0},   /* -- */
-               {0, 0, 0, 0},   /* -- */
-               {0, 0, 0, 0},   /* -- */
-               {PIRQA, PIRQB, PIRQC, PIRQD},   /* IDSEL 12 */
-               {PIRQD, PIRQA, PIRQB, PIRQC},
-               {PIRQC, PIRQD, PIRQA, PIRQB},
-               {PIRQB, PIRQC, PIRQD, PIRQA},   /* IDSEL 15 */
-               {0, 0, 0, 0},   /* -- */
-               {0, 0, 0, 0},   /* -- */
-               {PIRQA, PIRQB, PIRQC, PIRQD},   /* IDSEL 18 */
-               {PIRQD, PIRQA, PIRQB, PIRQC},
-               {PIRQC, PIRQD, PIRQA, PIRQB},
-               {PIRQB, PIRQC, PIRQD, PIRQA},   /* IDSEL 21 */
-       };
-
-       const long min_idsel = 2, max_idsel = 21, irqs_per_slot = 4;
-       return PCI_IRQ_TABLE_LOOKUP;
-}
-
 int
 mpc85xx_exclude_device(u_char bus, u_char devfn)
 {
@@ -119,44 +47,63 @@ mpc85xx_exclude_device(u_char bus, u_char devfn)
                return PCIBIOS_SUCCESSFUL;
 }
 
+void __init
+mpc85xx_pcibios_fixup(void)
+{
+       struct pci_dev *dev = NULL;
+
+       for_each_pci_dev(dev)
+               pci_read_irq_line(dev);
+}
 #endif /* CONFIG_PCI */
 
 
 void __init mpc85xx_ads_pic_init(void)
 {
-       struct mpic *mpic1;
-       phys_addr_t OpenPIC_PAddr;
-
-       /* Determine the Physical Address of the OpenPIC regs */
-       OpenPIC_PAddr = get_immrbase() + MPC85xx_OPENPIC_OFFSET;
-
-       mpic1 = mpic_alloc(OpenPIC_PAddr,
-                          MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN,
-                          4, MPC85xx_OPENPIC_IRQ_OFFSET, 0, 250,
-                          mpc85xx_ads_openpic_initsenses,
-                          sizeof(mpc85xx_ads_openpic_initsenses),
-                          " OpenPIC  ");
-       BUG_ON(mpic1 == NULL);
-       mpic_assign_isu(mpic1, 0, OpenPIC_PAddr + 0x10200);
-       mpic_assign_isu(mpic1, 1, OpenPIC_PAddr + 0x10280);
-       mpic_assign_isu(mpic1, 2, OpenPIC_PAddr + 0x10300);
-       mpic_assign_isu(mpic1, 3, OpenPIC_PAddr + 0x10380);
-       mpic_assign_isu(mpic1, 4, OpenPIC_PAddr + 0x10400);
-       mpic_assign_isu(mpic1, 5, OpenPIC_PAddr + 0x10480);
-       mpic_assign_isu(mpic1, 6, OpenPIC_PAddr + 0x10500);
-       mpic_assign_isu(mpic1, 7, OpenPIC_PAddr + 0x10580);
-
-       /* dummy mappings to get to 48 */
-       mpic_assign_isu(mpic1, 8, OpenPIC_PAddr + 0x10600);
-       mpic_assign_isu(mpic1, 9, OpenPIC_PAddr + 0x10680);
-       mpic_assign_isu(mpic1, 10, OpenPIC_PAddr + 0x10700);
-       mpic_assign_isu(mpic1, 11, OpenPIC_PAddr + 0x10780);
-
-       /* External ints */
-       mpic_assign_isu(mpic1, 12, OpenPIC_PAddr + 0x10000);
-       mpic_assign_isu(mpic1, 13, OpenPIC_PAddr + 0x10080);
-       mpic_assign_isu(mpic1, 14, OpenPIC_PAddr + 0x10100);
-       mpic_init(mpic1);
+       struct mpic *mpic;
+       struct resource r;
+       struct device_node *np = NULL;
+
+       np = of_find_node_by_type(np, "open-pic");
+
+       if (np == NULL) {
+               printk(KERN_ERR "Could not find open-pic node\n");
+               return;
+       }
+
+       if(of_address_to_resource(np, 0, &r)) {
+               printk(KERN_ERR "Could not map mpic register space\n");
+               of_node_put(np);
+               return;
+       }
+
+       mpic = mpic_alloc(np, r.start,
+                       MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN,
+                       4, 0, " OpenPIC  ");
+       BUG_ON(mpic == NULL);
+       of_node_put(np);
+
+       mpic_assign_isu(mpic, 0, r.start + 0x10200);
+       mpic_assign_isu(mpic, 1, r.start + 0x10280);
+       mpic_assign_isu(mpic, 2, r.start + 0x10300);
+       mpic_assign_isu(mpic, 3, r.start + 0x10380);
+       mpic_assign_isu(mpic, 4, r.start + 0x10400);
+       mpic_assign_isu(mpic, 5, r.start + 0x10480);
+       mpic_assign_isu(mpic, 6, r.start + 0x10500);
+       mpic_assign_isu(mpic, 7, r.start + 0x10580);
+
+       /* Unused on this platform (leave room for 8548) */
+       mpic_assign_isu(mpic, 8, r.start + 0x10600);
+       mpic_assign_isu(mpic, 9, r.start + 0x10680);
+       mpic_assign_isu(mpic, 10, r.start + 0x10700);
+       mpic_assign_isu(mpic, 11, r.start + 0x10780);
+
+       /* External Interrupts */
+       mpic_assign_isu(mpic, 12, r.start + 0x10000);
+       mpic_assign_isu(mpic, 13, r.start + 0x10080);
+       mpic_assign_isu(mpic, 14, r.start + 0x10100);
+
+       mpic_init(mpic);
 }
 
 /*
@@ -165,7 +112,9 @@ void __init mpc85xx_ads_pic_init(void)
 static void __init mpc85xx_ads_setup_arch(void)
 {
        struct device_node *cpu;
+#ifdef CONFIG_PCI
        struct device_node *np;
+#endif
 
        if (ppc_md.progress)
                ppc_md.progress("mpc85xx_ads_setup_arch()", 0);
@@ -186,8 +135,7 @@ static void __init mpc85xx_ads_setup_arch(void)
        for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
                add_bridge(np);
 
-       ppc_md.pci_swizzle = common_swizzle;
-       ppc_md.pci_map_irq = mpc85xx_map_irq;
+       ppc_md.pcibios_fixup = mpc85xx_pcibios_fixup;
        ppc_md.pci_exclude_device = mpc85xx_exclude_device;
 #endif
 
index 18e6e11..1d357d3 100644 (file)
@@ -57,94 +57,8 @@ unsigned long isa_mem_base = 0;
 static int cds_pci_slot = 2;
 static volatile u8 *cadmus;
 
-/*
- * Internal interrupts are all Level Sensitive, and Positive Polarity
- *
- * Note:  Likely, this table and the following function should be
- *        obtained and derived from the OF Device Tree.
- */
-static u_char mpc85xx_cds_openpic_initsenses[] __initdata = {
-       MPC85XX_INTERNAL_IRQ_SENSES,
-#if defined(CONFIG_PCI)
-       (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),      /* Ext 0: PCI slot 0 */
-       (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),      /* Ext 1: PCI slot 1 */
-       (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),      /* Ext 2: PCI slot 2 */
-       (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),      /* Ext 3: PCI slot 3 */
-#else
-       0x0,                            /* External  0: */
-       0x0,                            /* External  1: */
-       0x0,                            /* External  2: */
-       0x0,                            /* External  3: */
-#endif
-       (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),      /* External 5: PHY */
-       0x0,                            /* External  6: */
-       0x0,                            /* External  7: */
-       0x0,                            /* External  8: */
-       0x0,                            /* External  9: */
-       0x0,                            /* External 10: */
-#ifdef CONFIG_PCI
-       (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),    /* Ext 11: PCI2 slot 0 */
-#else
-       0x0,                            /* External 11: */
-#endif
-};
-
 
 #ifdef CONFIG_PCI
-/*
- * interrupt routing
- */
-int
-mpc85xx_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
-{
-       struct pci_controller *hose = pci_bus_to_hose(dev->bus->number);
-
-       if (!hose->index)
-       {
-               /* Handle PCI1 interrupts */
-               char pci_irq_table[][4] =
-                       /*
-                        *      PCI IDSEL/INTPIN->INTLINE
-                        *        A      B      C      D
-                        */
-
-                       /* Note IRQ assignment for slots is based on which slot the elysium is
-                        * in -- in this setup elysium is in slot #2 (this PIRQA as first
-                        * interrupt on slot */
-               {
-                       { 0, 1, 2, 3 }, /* 16 - PMC */
-                       { 0, 1, 2, 3 }, /* 17 P2P (Tsi320) */
-                       { 0, 1, 2, 3 }, /* 18 - Slot 1 */
-                       { 1, 2, 3, 0 }, /* 19 - Slot 2 */
-                       { 2, 3, 0, 1 }, /* 20 - Slot 3 */
-                       { 3, 0, 1, 2 }, /* 21 - Slot 4 */
-               };
-
-               const long min_idsel = 16, max_idsel = 21, irqs_per_slot = 4;
-               int i, j;
-
-               for (i = 0; i < 6; i++)
-                       for (j = 0; j < 4; j++)
-                               pci_irq_table[i][j] =
-                                       ((pci_irq_table[i][j] + 5 -
-                                         cds_pci_slot) & 0x3) + PIRQ0A;
-
-               return PCI_IRQ_TABLE_LOOKUP;
-       } else {
-               /* Handle PCI2 interrupts (if we have one) */
-               char pci_irq_table[][4] =
-               {
-                       /*
-                        * We only have one slot and one interrupt
-                        * going to PIRQA - PIRQD */
-                       { PIRQ1A, PIRQ1A, PIRQ1A, PIRQ1A }, /* 21 - slot 0 */
-               };
-
-               const long min_idsel = 21, max_idsel = 21, irqs_per_slot = 4;
-
-               return PCI_IRQ_TABLE_LOOKUP;
-       }
-}
 
 #define ARCADIA_HOST_BRIDGE_IDSEL      17
 #define ARCADIA_2ND_BRIDGE_IDSEL       3
@@ -210,50 +124,104 @@ mpc85xx_cds_pcibios_fixup(void)
                pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 11);
                pci_dev_put(dev);
        }
+
+       /* Now map all the PCI irqs */
+       dev = NULL;
+       for_each_pci_dev(dev)
+               pci_read_irq_line(dev);
+}
+
+#ifdef CONFIG_PPC_I8259
+#warning The i8259 PIC support is currently broken
+static void mpc85xx_8259_cascade(unsigned int irq, struct
+               irq_desc *desc, struct pt_regs *regs)
+{
+       unsigned int cascade_irq = i8259_irq(regs);
+
+       if (cascade_irq != NO_IRQ)
+               generic_handle_irq(cascade_irq, regs);
+
+       desc->chip->eoi(irq);
 }
+#endif /* PPC_I8259 */
 #endif /* CONFIG_PCI */
 
 void __init mpc85xx_cds_pic_init(void)
 {
-       struct mpic *mpic1;
-       phys_addr_t OpenPIC_PAddr;
+       struct mpic *mpic;
+       struct resource r;
+       struct device_node *np = NULL;
+       struct device_node *cascade_node = NULL;
+       int cascade_irq;
 
-       /* Determine the Physical Address of the OpenPIC regs */
-       OpenPIC_PAddr = get_immrbase() + MPC85xx_OPENPIC_OFFSET;
+       np = of_find_node_by_type(np, "open-pic");
+
+       if (np == NULL) {
+               printk(KERN_ERR "Could not find open-pic node\n");
+               return;
+       }
 
-       mpic1 = mpic_alloc(OpenPIC_PAddr,
+       if (of_address_to_resource(np, 0, &r)) {
+               printk(KERN_ERR "Failed to map mpic register space\n");
+               of_node_put(np);
+               return;
+       }
+
+       mpic = mpic_alloc(np, r.start,
                        MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN,
-                       4, MPC85xx_OPENPIC_IRQ_OFFSET, 0, 250,
-                       mpc85xx_cds_openpic_initsenses,
-                       sizeof(mpc85xx_cds_openpic_initsenses), " OpenPIC  ");
-       BUG_ON(mpic1 == NULL);
-       mpic_assign_isu(mpic1, 0, OpenPIC_PAddr + 0x10200);
-       mpic_assign_isu(mpic1, 1, OpenPIC_PAddr + 0x10280);
-       mpic_assign_isu(mpic1, 2, OpenPIC_PAddr + 0x10300);
-       mpic_assign_isu(mpic1, 3, OpenPIC_PAddr + 0x10380);
-       mpic_assign_isu(mpic1, 4, OpenPIC_PAddr + 0x10400);
-       mpic_assign_isu(mpic1, 5, OpenPIC_PAddr + 0x10480);
-       mpic_assign_isu(mpic1, 6, OpenPIC_PAddr + 0x10500);
-       mpic_assign_isu(mpic1, 7, OpenPIC_PAddr + 0x10580);
-
-       /* dummy mappings to get to 48 */
-       mpic_assign_isu(mpic1, 8, OpenPIC_PAddr + 0x10600);
-       mpic_assign_isu(mpic1, 9, OpenPIC_PAddr + 0x10680);
-       mpic_assign_isu(mpic1, 10, OpenPIC_PAddr + 0x10700);
-       mpic_assign_isu(mpic1, 11, OpenPIC_PAddr + 0x10780);
-
-       /* External ints */
-       mpic_assign_isu(mpic1, 12, OpenPIC_PAddr + 0x10000);
-       mpic_assign_isu(mpic1, 13, OpenPIC_PAddr + 0x10080);
-       mpic_assign_isu(mpic1, 14, OpenPIC_PAddr + 0x10100);
-
-       mpic_init(mpic1);
+                       4, 0, " OpenPIC  ");
+       BUG_ON(mpic == NULL);
+
+       /* Return the mpic node */
+       of_node_put(np);
+
+       mpic_assign_isu(mpic, 0, r.start + 0x10200);
+       mpic_assign_isu(mpic, 1, r.start + 0x10280);
+       mpic_assign_isu(mpic, 2, r.start + 0x10300);
+       mpic_assign_isu(mpic, 3, r.start + 0x10380);
+       mpic_assign_isu(mpic, 4, r.start + 0x10400);
+       mpic_assign_isu(mpic, 5, r.start + 0x10480);
+       mpic_assign_isu(mpic, 6, r.start + 0x10500);
+       mpic_assign_isu(mpic, 7, r.start + 0x10580);
+
+       /* Used only for 8548 so far, but no harm in
+        * allocating them for everyone */
+       mpic_assign_isu(mpic, 8, r.start + 0x10600);
+       mpic_assign_isu(mpic, 9, r.start + 0x10680);
+       mpic_assign_isu(mpic, 10, r.start + 0x10700);
+       mpic_assign_isu(mpic, 11, r.start + 0x10780);
+
+       /* External Interrupts */
+       mpic_assign_isu(mpic, 12, r.start + 0x10000);
+       mpic_assign_isu(mpic, 13, r.start + 0x10080);
+       mpic_assign_isu(mpic, 14, r.start + 0x10100);
+
+       mpic_init(mpic);
+
+#ifdef CONFIG_PPC_I8259
+       /* Initialize the i8259 controller */
+       for_each_node_by_type(np, "interrupt-controller")
+               if (device_is_compatible(np, "chrp,iic")) {
+                       cascade_node = np;
+                       break;
+               }
+
+       if (cascade_node == NULL) {
+               printk(KERN_DEBUG "Could not find i8259 PIC\n");
+               return;
+       }
 
-#ifdef CONFIG_PCI
-       mpic_setup_cascade(PIRQ0A, i8259_irq_cascade, NULL);
+       cascade_irq = irq_of_parse_and_map(cascade_node, 0);
+       if (cascade_irq == NO_IRQ) {
+               printk(KERN_ERR "Failed to map cascade interrupt\n");
+               return;
+       }
 
-       i8259_init(0,0);
-#endif
+       i8259_init(cascade_node, 0);
+       of_node_put(cascade_node);
+
+       set_irq_chained_handler(cascade_irq, mpc85xx_8259_cascade);
+#endif /* CONFIG_PPC_I8259 */
 }
 
 
@@ -298,8 +266,6 @@ mpc85xx_cds_setup_arch(void)
                add_bridge(np);
 
        ppc_md.pcibios_fixup = mpc85xx_cds_pcibios_fixup;
-       ppc_md.pci_swizzle = common_swizzle;
-       ppc_md.pci_map_irq = mpc85xx_map_irq;
        ppc_md.pci_exclude_device = mpc85xx_exclude_device;
 #endif
 
index 5d2bcf7..41e554c 100644 (file)
 
 #include <linux/init.h>
 
-/* PCI interrupt controller */
-#define PIRQA          3
-#define PIRQB          4
-#define PIRQC          5
-#define PIRQD          6
-#define PIRQ7          7
-#define PIRQE          9
-#define PIRQF          10
-#define PIRQG          11
-#define PIRQH          12
-
-/* PCI-Express memory map */
-#define MPC86XX_PCIE_LOWER_IO        0x00000000
-#define MPC86XX_PCIE_UPPER_IO        0x00ffffff
-
-#define MPC86XX_PCIE_LOWER_MEM       0x80000000
-#define MPC86XX_PCIE_UPPER_MEM       0x9fffffff
-
-#define MPC86XX_PCIE_IO_BASE         0xe2000000
-#define MPC86XX_PCIE_MEM_OFFSET      0x00000000
-
-#define MPC86XX_PCIE_IO_SIZE         0x01000000
-
-#define PCIE1_CFG_ADDR_OFFSET    (0x8000)
-#define PCIE1_CFG_DATA_OFFSET    (0x8004)
-
-#define PCIE2_CFG_ADDR_OFFSET    (0x9000)
-#define PCIE2_CFG_DATA_OFFSET    (0x9004)
-
-#define MPC86xx_PCIE_OFFSET PCIE1_CFG_ADDR_OFFSET
-#define MPC86xx_PCIE_SIZE      (0x1000)
-
 #define MPC86XX_RSTCR_OFFSET   (0xe00b0)       /* Reset Control Register */
 
 #endif /* __MPC8641_HPCN_H__ */
index ebae73e..146da30 100644 (file)
 #include "mpc86xx.h"
 #include "mpc8641_hpcn.h"
 
+#undef DEBUG
+
+#ifdef DEBUG
+#define DBG(fmt...) do { printk(KERN_ERR fmt); } while(0)
+#else
+#define DBG(fmt...) do { } while(0)
+#endif
+
 #ifndef CONFIG_PCI
 unsigned long isa_io_base = 0;
 unsigned long isa_mem_base = 0;
@@ -44,205 +52,215 @@ unsigned long pci_dram_offset = 0;
 #endif
 
 
-/*
- * Internal interrupts are all Level Sensitive, and Positive Polarity
- */
-
-static u_char mpc86xx_hpcn_openpic_initsenses[] __initdata = {
-       (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),      /* Internal  0: Reserved */
-       (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),      /* Internal  1: MCM */
-       (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),      /* Internal  2: DDR DRAM */
-       (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),      /* Internal  3: LBIU */
-       (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),      /* Internal  4: DMA 0 */
-       (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),      /* Internal  5: DMA 1 */
-       (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),      /* Internal  6: DMA 2 */
-       (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),      /* Internal  7: DMA 3 */
-       (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),      /* Internal  8: PCIE1 */
-       (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),      /* Internal  9: PCIE2 */
-       (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),      /* Internal 10: Reserved */
-       (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),      /* Internal 11: Reserved */
-       (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),      /* Internal 12: DUART2 */
-       (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),      /* Internal 13: TSEC 1 Transmit */
-       (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),      /* Internal 14: TSEC 1 Receive */
-       (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),      /* Internal 15: TSEC 3 transmit */
-       (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),      /* Internal 16: TSEC 3 receive */
-       (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),      /* Internal 17: TSEC 3 error */
-       (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),      /* Internal 18: TSEC 1 Receive/Transmit Error */
-       (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),      /* Internal 19: TSEC 2 Transmit */
-       (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),      /* Internal 20: TSEC 2 Receive */
-       (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),      /* Internal 21: TSEC 4 transmit */
-       (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),      /* Internal 22: TSEC 4 receive */
-       (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),      /* Internal 23: TSEC 4 error */
-       (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),      /* Internal 24: TSEC 2 Receive/Transmit Error */
-       (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),      /* Internal 25: Unused */
-       (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),      /* Internal 26: DUART1 */
-       (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),      /* Internal 27: I2C */
-       (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),      /* Internal 28: Performance Monitor */
-       (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),      /* Internal 29: Unused */
-       (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),      /* Internal 30: Unused */
-       (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),      /* Internal 31: Unused */
-       (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),      /* Internal 32: SRIO error/write-port unit */
-       (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),      /* Internal 33: SRIO outbound doorbell */
-       (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),      /* Internal 34: SRIO inbound doorbell */
-       (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),      /* Internal 35: Unused */
-       (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),      /* Internal 36: Unused */
-       (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),      /* Internal 37: SRIO outbound message unit 1 */
-       (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),      /* Internal 38: SRIO inbound message unit 1 */
-       (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),      /* Internal 39: SRIO outbound message unit 2 */
-       (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),      /* Internal 40: SRIO inbound message unit 2 */
-       (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),      /* Internal 41: Unused */
-       (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),      /* Internal 42: Unused */
-       (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),      /* Internal 43: Unused */
-       (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),      /* Internal 44: Unused */
-       (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),      /* Internal 45: Unused */
-       (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),      /* Internal 46: Unused */
-       (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),      /* Internal 47: Unused */
-       0x0,                                            /* External  0: */
-       0x0,                                            /* External  1: */
-       0x0,                                            /* External  2: */
-       0x0,                                            /* External  3: */
-       0x0,                                            /* External  4: */
-       0x0,                                            /* External  5: */
-       0x0,                                            /* External  6: */
-       0x0,                                            /* External  7: */
-       (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),      /* External  8: Pixis FPGA */
-       (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),      /* External  9: ULI 8259 INTR Cascade */
-       (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),      /* External 10: Quad ETH PHY */
-       0x0,                                            /* External 11: */
-       0x0,
-       0x0,
-       0x0,
-       0x0,
-};
-
+static void mpc86xx_8259_cascade(unsigned int irq, struct irq_desc *desc,
+                                struct pt_regs *regs)
+{
+       unsigned int cascade_irq = i8259_irq(regs);
+       if (cascade_irq != NO_IRQ)
+               generic_handle_irq(cascade_irq, regs);
+       desc->chip->eoi(irq);
+}
 
 void __init
 mpc86xx_hpcn_init_irq(void)
 {
        struct mpic *mpic1;
+       struct device_node *np, *cascade_node = NULL;
+       int cascade_irq;
        phys_addr_t openpic_paddr;
 
+       np = of_find_node_by_type(NULL, "open-pic");
+       if (np == NULL)
+               return;
+
        /* Determine the Physical Address of the OpenPIC regs */
        openpic_paddr = get_immrbase() + MPC86xx_OPENPIC_OFFSET;
 
        /* Alloc mpic structure and per isu has 16 INT entries. */
-       mpic1 = mpic_alloc(openpic_paddr,
+       mpic1 = mpic_alloc(np, openpic_paddr,
                        MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN,
-                       16, MPC86xx_OPENPIC_IRQ_OFFSET, 0, 250,
-                       mpc86xx_hpcn_openpic_initsenses,
-                       sizeof(mpc86xx_hpcn_openpic_initsenses),
+                       16, NR_IRQS - 4,
                        " MPIC     ");
        BUG_ON(mpic1 == NULL);
 
+       mpic_assign_isu(mpic1, 0, openpic_paddr + 0x10000);
+
        /* 48 Internal Interrupts */
-       mpic_assign_isu(mpic1, 0, openpic_paddr + 0x10200);
-       mpic_assign_isu(mpic1, 1, openpic_paddr + 0x10400);
-       mpic_assign_isu(mpic1, 2, openpic_paddr + 0x10600);
+       mpic_assign_isu(mpic1, 1, openpic_paddr + 0x10200);
+       mpic_assign_isu(mpic1, 2, openpic_paddr + 0x10400);
+       mpic_assign_isu(mpic1, 3, openpic_paddr + 0x10600);
 
-       /* 16 External interrupts */
-       mpic_assign_isu(mpic1, 3, openpic_paddr + 0x10000);
+       /* 16 External interrupts
+        * Moving them from [0 - 15] to [64 - 79]
+        */
+       mpic_assign_isu(mpic1, 4, openpic_paddr + 0x10000);
 
        mpic_init(mpic1);
 
 #ifdef CONFIG_PCI
-       mpic_setup_cascade(MPC86xx_IRQ_EXT9, i8259_irq_cascade, NULL);
-       i8259_init(0, I8259_OFFSET);
-#endif
-}
+       /* Initialize i8259 controller */
+       for_each_node_by_type(np, "interrupt-controller")
+               if (device_is_compatible(np, "chrp,iic")) {
+                       cascade_node = np;
+                       break;
+               }
+       if (cascade_node == NULL) {
+               printk(KERN_DEBUG "mpc86xxhpcn: no ISA interrupt controller\n");
+               return;
+       }
 
+       cascade_irq = irq_of_parse_and_map(cascade_node, 0);
+       if (cascade_irq == NO_IRQ) {
+               printk(KERN_ERR "mpc86xxhpcn: failed to map cascade interrupt");
+               return;
+       }
+       DBG("mpc86xxhpcn: cascade mapped to irq %d\n", cascade_irq);
 
+       i8259_init(cascade_node, 0);
+       set_irq_chained_handler(cascade_irq, mpc86xx_8259_cascade);
+#endif
+}
 
 #ifdef CONFIG_PCI
-/*
- * interrupt routing
- */
 
-int
-mpc86xx_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
+enum pirq{PIRQA = 8, PIRQB, PIRQC, PIRQD, PIRQE, PIRQF, PIRQG, PIRQH};
+const unsigned char uli1575_irq_route_table[16] = {
+       0,      /* 0: Reserved */
+       0x8,    /* 1: 0b1000 */
+       0,      /* 2: Reserved */
+       0x2,    /* 3: 0b0010 */
+       0x4,    /* 4: 0b0100 */
+       0x5,    /* 5: 0b0101 */
+       0x7,    /* 6: 0b0111 */
+       0x6,    /* 7: 0b0110 */
+       0,      /* 8: Reserved */
+       0x1,    /* 9: 0b0001 */
+       0x3,    /* 10: 0b0011 */
+       0x9,    /* 11: 0b1001 */
+       0xb,    /* 12: 0b1011 */
+       0,      /* 13: Reserved */
+       0xd,    /* 14, 0b1101 */
+       0xf,    /* 15, 0b1111 */
+};
+
+static int __devinit
+get_pci_irq_from_of(struct pci_controller *hose, int slot, int pin)
 {
-       static char pci_irq_table[][4] = {
-               /*
-                *      PCI IDSEL/INTPIN->INTLINE
-                *       A      B      C      D
-                */
-               {PIRQA, PIRQB, PIRQC, PIRQD},   /* IDSEL 17 -- PCI Slot 1 */
-               {PIRQB, PIRQC, PIRQD, PIRQA},   /* IDSEL 18 -- PCI Slot 2 */
-               {0, 0, 0, 0},                   /* IDSEL 19 */
-               {0, 0, 0, 0},                   /* IDSEL 20 */
-               {0, 0, 0, 0},                   /* IDSEL 21 */
-               {0, 0, 0, 0},                   /* IDSEL 22 */
-               {0, 0, 0, 0},                   /* IDSEL 23 */
-               {0, 0, 0, 0},                   /* IDSEL 24 */
-               {0, 0, 0, 0},                   /* IDSEL 25 */
-               {PIRQD, PIRQA, PIRQB, PIRQC},   /* IDSEL 26 -- PCI Bridge*/
-               {PIRQC, 0, 0, 0},               /* IDSEL 27 -- LAN */
-               {PIRQE, PIRQF, PIRQH, PIRQ7},   /* IDSEL 28 -- USB 1.1 */
-               {PIRQE, PIRQF, PIRQG, 0},       /* IDSEL 29 -- Audio & Modem */
-               {PIRQH, 0, 0, 0},               /* IDSEL 30 -- LPC & PMU*/
-               {PIRQD, 0, 0, 0},               /* IDSEL 31 -- ATA */
-       };
-
-       const long min_idsel = 17, max_idsel = 31, irqs_per_slot = 4;
-       return PCI_IRQ_TABLE_LOOKUP + I8259_OFFSET;
+       struct of_irq oirq;
+       u32 laddr[3];
+       struct device_node *hosenode = hose ? hose->arch_data : NULL;
+
+       if (!hosenode) return -EINVAL;
+
+       laddr[0] = (hose->first_busno << 16) | (PCI_DEVFN(slot, 0) << 8);
+       laddr[1] = laddr[2] = 0;
+       of_irq_map_raw(hosenode, &pin, laddr, &oirq);
+       DBG("mpc86xx_hpcn: pci irq addr %x, slot %d, pin %d, irq %d\n",
+                       laddr[0], slot, pin, oirq.specifier[0]);
+       return oirq.specifier[0];
 }
 
-static void __devinit quirk_ali1575(struct pci_dev *dev)
+static void __devinit quirk_uli1575(struct pci_dev *dev)
 {
        unsigned short temp;
+       struct pci_controller *hose = pci_bus_to_host(dev->bus);
+       unsigned char irq2pin[16];
+       unsigned long pirq_map_word = 0;
+       u32 irq;
+       int i;
 
        /*
-        * ALI1575 interrupts route table setup:
+        * ULI1575 interrupts route setup
+        */
+       memset(irq2pin, 0, 16); /* Initialize default value 0 */
+
+       /*
+        * PIRQA -> PIRQD mapping read from OF-tree
+        *
+        * interrupts for PCI slot0 -- PIRQA / PIRQB / PIRQC / PIRQD
+        *                PCI slot1 -- PIRQB / PIRQC / PIRQD / PIRQA
+        */
+       for (i = 0; i < 4; i++){
+               irq = get_pci_irq_from_of(hose, 17, i + 1);
+               if (irq > 0 && irq < 16)
+                       irq2pin[irq] = PIRQA + i;
+               else
+                       printk(KERN_WARNING "ULI1575 device"
+                           "(slot %d, pin %d) irq %d is invalid.\n",
+                           17, i, irq);
+       }
+
+       /*
+        * PIRQE -> PIRQF mapping set manually
         *
         * IRQ pin   IRQ#
-        * PIRQA ---- 3
-        * PIRQB ---- 4
-        * PIRQC ---- 5
-        * PIRQD ---- 6
         * PIRQE ---- 9
         * PIRQF ---- 10
         * PIRQG ---- 11
         * PIRQH ---- 12
-        *
-        * interrupts for PCI slot0 -- PIRQA / PIRQB / PIRQC / PIRQD
-        *                PCI slot1 -- PIRQB / PIRQC / PIRQD / PIRQA
         */
-       pci_write_config_dword(dev, 0x48, 0xb9317542);
+       for (i = 0; i < 4; i++) irq2pin[i + 9] = PIRQE + i;
+
+       /* Set IRQ-PIRQ Mapping to ULI1575 */
+       for (i = 0; i < 16; i++)
+               if (irq2pin[i])
+                       pirq_map_word |= (uli1575_irq_route_table[i] & 0xf)
+                               << ((irq2pin[i] - PIRQA) * 4);
 
-       /* USB 1.1 OHCI controller 1, interrupt: PIRQE */
-       pci_write_config_byte(dev, 0x86, 0x0c);
+       /* ULI1575 IRQ mapping conf register default value is 0xb9317542 */
+       DBG("Setup ULI1575 IRQ mapping configuration register value = 0x%x\n",
+                       pirq_map_word);
+       pci_write_config_dword(dev, 0x48, pirq_map_word);
 
-       /* USB 1.1 OHCI controller 2, interrupt: PIRQF */
-       pci_write_config_byte(dev, 0x87, 0x0d);
+#define ULI1575_SET_DEV_IRQ(slot, pin, reg)                            \
+       do {                                                            \
+               int irq;                                                \
+               irq = get_pci_irq_from_of(hose, slot, pin);             \
+               if (irq > 0 && irq < 16)                                \
+                       pci_write_config_byte(dev, reg, irq2pin[irq]);  \
+               else                                                    \
+                       printk(KERN_WARNING "ULI1575 device"            \
+                           "(slot %d, pin %d) irq %d is invalid.\n",   \
+                           slot, pin, irq);                            \
+       } while(0)
 
-       /* USB 1.1 OHCI controller 3, interrupt: PIRQH */
-       pci_write_config_byte(dev, 0x88, 0x0f);
+       /* USB 1.1 OHCI controller 1, slot 28, pin 1 */
+       ULI1575_SET_DEV_IRQ(28, 1, 0x86);
 
-       /* USB 2.0 controller, interrupt: PIRQ7 */
-       pci_write_config_byte(dev, 0x74, 0x06);
+       /* USB 1.1 OHCI controller 2, slot 28, pin 2 */
+       ULI1575_SET_DEV_IRQ(28, 2, 0x87);
 
-       /* Audio controller, interrupt: PIRQE */
-       pci_write_config_byte(dev, 0x8a, 0x0c);
+       /* USB 1.1 OHCI controller 3, slot 28, pin 3 */
+       ULI1575_SET_DEV_IRQ(28, 3, 0x88);
 
-       /* Modem controller, interrupt: PIRQF */
-       pci_write_config_byte(dev, 0x8b, 0x0d);
+       /* USB 2.0 controller, slot 28, pin 4 */
+       irq = get_pci_irq_from_of(hose, 28, 4);
+       if (irq >= 0 && irq <=15)
+               pci_write_config_dword(dev, 0x74, uli1575_irq_route_table[irq]);
 
-       /* HD audio controller, interrupt: PIRQG */
-       pci_write_config_byte(dev, 0x8c, 0x0e);
+       /* Audio controller, slot 29, pin 1 */
+       ULI1575_SET_DEV_IRQ(29, 1, 0x8a);
 
-       /* Serial ATA interrupt: PIRQD */
-       pci_write_config_byte(dev, 0x8d, 0x0b);
+       /* Modem controller, slot 29, pin 2 */
+       ULI1575_SET_DEV_IRQ(29, 2, 0x8b);
 
-       /* SMB interrupt: PIRQH */
-       pci_write_config_byte(dev, 0x8e, 0x0f);
+       /* HD audio controller, slot 29, pin 3 */
+       ULI1575_SET_DEV_IRQ(29, 3, 0x8c);
 
-       /* PMU ACPI SCI interrupt: PIRQH */
-       pci_write_config_byte(dev, 0x8f, 0x0f);
+       /* SMB interrupt: slot 30, pin 1 */
+       ULI1575_SET_DEV_IRQ(30, 1, 0x8e);
+
+       /* PMU ACPI SCI interrupt: slot 30, pin 2 */
+       ULI1575_SET_DEV_IRQ(30, 2, 0x8f);
+
+       /* Serial ATA interrupt: slot 31, pin 1 */
+       ULI1575_SET_DEV_IRQ(31, 1, 0x8d);
 
        /* Primary PATA IDE IRQ: 14
         * Secondary PATA IDE IRQ: 15
         */
-       pci_write_config_byte(dev, 0x44, 0x3d);
-       pci_write_config_byte(dev, 0x75, 0x0f);
+       pci_write_config_byte(dev, 0x44, 0x30 | uli1575_irq_route_table[14]);
+       pci_write_config_byte(dev, 0x75, uli1575_irq_route_table[15]);
 
        /* Set IRQ14 and IRQ15 to legacy IRQs */
        pci_read_config_word(dev, 0x46, &temp);
@@ -264,6 +282,8 @@ static void __devinit quirk_ali1575(struct pci_dev *dev)
         */
        outb(0xfa, 0x4d0);
        outb(0x1e, 0x4d1);
+
+#undef ULI1575_SET_DEV_IRQ
 }
 
 static void __devinit quirk_uli5288(struct pci_dev *dev)
@@ -306,7 +326,7 @@ static void __devinit early_uli5249(struct pci_dev *dev)
        dev->class |= 0x1;
 }
 
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x1575, quirk_ali1575);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x1575, quirk_uli1575);
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x5288, quirk_uli5288);
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x5229, quirk_uli5229);
 DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_AL, 0x5249, early_uli5249);
@@ -337,8 +357,6 @@ mpc86xx_hpcn_setup_arch(void)
        for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
                add_bridge(np);
 
-       ppc_md.pci_swizzle = common_swizzle;
-       ppc_md.pci_map_irq = mpc86xx_map_irq;
        ppc_md.pci_exclude_device = mpc86xx_exclude_device;
 #endif
 
@@ -377,6 +395,15 @@ mpc86xx_hpcn_show_cpuinfo(struct seq_file *m)
 }
 
 
+void __init mpc86xx_hpcn_pcibios_fixup(void)
+{
+       struct pci_dev *dev = NULL;
+
+       for_each_pci_dev(dev)
+               pci_read_irq_line(dev);
+}
+
+
 /*
  * Called very early, device-tree isn't unflattened
  */
@@ -431,6 +458,7 @@ define_machine(mpc86xx_hpcn) {
        .setup_arch             = mpc86xx_hpcn_setup_arch,
        .init_IRQ               = mpc86xx_hpcn_init_irq,
        .show_cpuinfo           = mpc86xx_hpcn_show_cpuinfo,
+       .pcibios_fixup          = mpc86xx_hpcn_pcibios_fixup,
        .get_irq                = mpic_get_irq,
        .restart                = mpc86xx_restart,
        .time_init              = mpc86xx_time_init,
index d7a4fc7..ed00ed2 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * mpc7448_hpc2.c
  *
- * Board setup routines for the Freescale Taiga platform
+ * Board setup routines for the Freescale mpc7448hpc2(taiga) platform
  *
  * Author: Jacob Pan
  *      jacob.pan@freescale.com
  *
  * Copyright 2004-2006 Freescale Semiconductor, Inc.
  *
- * 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.
+ * 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/config.h>
@@ -62,43 +62,8 @@ pci_dram_offset = MPC7448_HPC2_PCI_MEM_OFFSET;
 extern int tsi108_setup_pci(struct device_node *dev);
 extern void _nmask_and_or_msr(unsigned long nmask, unsigned long or_val);
 extern void tsi108_pci_int_init(void);
-extern int tsi108_irq_cascade(struct pt_regs *regs, void *unused);
-
-/*
- * Define all of the IRQ senses and polarities.  Taken from the
- * mpc7448hpc  manual.
- * Note:  Likely, this table and the following function should be
- *        obtained and derived from the OF Device Tree.
- */
-
-static u_char mpc7448_hpc2_pic_initsenses[] __initdata = {
-       /* External on-board sources */
-       (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),      /* INT[0] XINT0 from FPGA */
-       (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),      /* INT[1] XINT1 from FPGA */
-       (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),      /* INT[2] PHY_INT from both GIGE */
-       (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),      /* INT[3] RESERVED */
-       /* Internal Tsi108/109 interrupt sources */
-       (IRQ_SENSE_EDGE  | IRQ_POLARITY_POSITIVE),      /* Reserved IRQ */
-       (IRQ_SENSE_EDGE  | IRQ_POLARITY_POSITIVE),      /* Reserved IRQ */
-       (IRQ_SENSE_EDGE  | IRQ_POLARITY_POSITIVE),      /* Reserved IRQ */
-       (IRQ_SENSE_EDGE  | IRQ_POLARITY_POSITIVE),      /* Reserved IRQ */
-       (IRQ_SENSE_EDGE  | IRQ_POLARITY_POSITIVE),      /* DMA0 */
-       (IRQ_SENSE_EDGE  | IRQ_POLARITY_POSITIVE),      /* DMA1 */
-       (IRQ_SENSE_EDGE  | IRQ_POLARITY_POSITIVE),      /* DMA2 */
-       (IRQ_SENSE_EDGE  | IRQ_POLARITY_POSITIVE),      /* DMA3 */
-       (IRQ_SENSE_EDGE  | IRQ_POLARITY_POSITIVE),      /* UART0 */
-       (IRQ_SENSE_EDGE  | IRQ_POLARITY_POSITIVE),      /* UART1 */
-       (IRQ_SENSE_EDGE  | IRQ_POLARITY_POSITIVE),      /* I2C */
-       (IRQ_SENSE_EDGE  | IRQ_POLARITY_POSITIVE),      /* GPIO */
-       (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),      /* GIGE0 */
-       (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),      /* GIGE1 */
-       (IRQ_SENSE_EDGE  | IRQ_POLARITY_POSITIVE),      /* Reserved IRQ */
-       (IRQ_SENSE_EDGE  | IRQ_POLARITY_POSITIVE),      /* HLP */
-       (IRQ_SENSE_EDGE  | IRQ_POLARITY_POSITIVE),      /* SDC */
-       (IRQ_SENSE_EDGE  | IRQ_POLARITY_POSITIVE),      /* Processor IF */
-       (IRQ_SENSE_EDGE  | IRQ_POLARITY_POSITIVE),      /* Reserved IRQ */
-       (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),      /* PCI/X block */
-};
+extern void tsi108_irq_cascade(unsigned int irq, struct irq_desc *desc,
+                           struct pt_regs *regs);
 
 int mpc7448_hpc2_exclude_device(u_char bus, u_char devfn)
 {
@@ -229,6 +194,8 @@ static void __init mpc7448_hpc2_init_IRQ(void)
 {
        struct mpic *mpic;
        phys_addr_t mpic_paddr = 0;
+       unsigned int cascade_pci_irq;
+       struct device_node *tsi_pci;
        struct device_node *tsi_pic;
 
        tsi_pic = of_find_node_by_type(NULL, "open-pic");
@@ -246,24 +213,31 @@ static void __init mpc7448_hpc2_init_IRQ(void)
        DBG("%s: tsi108pic phys_addr = 0x%x\n", __FUNCTION__,
            (u32) mpic_paddr);
 
-       mpic = mpic_alloc(mpic_paddr,
+       mpic = mpic_alloc(tsi_pic, mpic_paddr,
                        MPIC_PRIMARY | MPIC_BIG_ENDIAN | MPIC_WANTS_RESET |
                        MPIC_SPV_EOI | MPIC_MOD_ID(MPIC_ID_TSI108),
                        0, /* num_sources used */
-                       TSI108_IRQ_BASE,
                        0, /* num_sources used */
-                       NR_IRQS - 4 /* XXXX */,
-                       mpc7448_hpc2_pic_initsenses,
-                       sizeof(mpc7448_hpc2_pic_initsenses), "Tsi108_PIC");
+                       "Tsi108_PIC");
 
        BUG_ON(mpic == NULL); /* XXXX */
-
        mpic_init(mpic);
-       mpic_setup_cascade(IRQ_TSI108_PCI, tsi108_irq_cascade, mpic);
+
+       tsi_pci = of_find_node_by_type(NULL, "pci");
+       if (tsi_pci == 0) {
+               printk("%s: No tsi108 pci node found !\n", __FUNCTION__);
+               return;
+       }
+
+       cascade_pci_irq = irq_of_parse_and_map(tsi_pci, 0);
+       set_irq_data(cascade_pci_irq, mpic);
+       set_irq_chained_handler(cascade_pci_irq, tsi108_irq_cascade);
+
        tsi108_pci_int_init();
 
        /* Configure MPIC outputs to CPU0 */
        tsi108_write_reg(TSI108_MPIC_OFFSET + 0x30c, 0);
+       of_node_put(tsi_pic);
 }
 
 void mpc7448_hpc2_show_cpuinfo(struct seq_file *m)
@@ -320,6 +294,7 @@ static int mpc7448_machine_check_exception(struct pt_regs *regs)
        return 0;
 
 }
+
 define_machine(mpc7448_hpc2){
        .name                   = "MPC7448 HPC2",
        .probe                  = mpc7448_hpc2_probe,
index 6a026c7..9d73d02 100644 (file)
@@ -411,8 +411,15 @@ static unsigned long __init bootx_flatten_dt(unsigned long start)
        DBG("End of boot params: %x\n", mem_end);
        rsvmap[0] = mem_start;
        rsvmap[1] = mem_end;
-       rsvmap[2] = 0;
-       rsvmap[3] = 0;
+       if (bootx_info->ramDisk) {
+               rsvmap[2] = ((unsigned long)bootx_info) + bootx_info->ramDisk;
+               rsvmap[3] = rsvmap[2] + bootx_info->ramDiskSize;
+               rsvmap[4] = 0;
+               rsvmap[5] = 0;
+       } else {
+               rsvmap[2] = 0;
+               rsvmap[3] = 0;
+       }
 
        return (unsigned long)hdr;
 }
@@ -543,12 +550,12 @@ void __init bootx_init(unsigned long r3, unsigned long r4)
         */
        if (bi->version < 5) {
                space = bi->deviceTreeOffset + bi->deviceTreeSize;
-               if (bi->ramDisk)
+               if (bi->ramDisk >= space)
                        space = bi->ramDisk + bi->ramDiskSize;
        } else
                space = bi->totalParamsSize;
 
-       bootx_printf("Total space used by parameters & ramdisk: %x \n", space);
+       bootx_printf("Total space used by parameters & ramdisk: 0x%x \n", space);
 
        /* New BootX will have flushed all TLBs and enters kernel with
         * MMU switched OFF, so this should not be useful anymore.
index 12b6560..ef10bcf 100644 (file)
@@ -85,11 +85,8 @@ static int __init gfar_mdio_of_init(void)
                        mdio_data.irq[k] = -1;
 
                while ((child = of_get_next_child(np, child)) != NULL) {
-                       if (child->n_intrs) {
-                               u32 *id =
-                                   (u32 *) get_property(child, "reg", NULL);
-                               mdio_data.irq[*id] = child->intrs[0].line;
-                       }
+                       u32 *id = get_property(child, "reg", NULL);
+                       mdio_data.irq[*id] = irq_of_parse_and_map(child, 0);
                }
 
                ret =
@@ -131,6 +128,7 @@ static int __init gfar_of_init(void)
                char *model;
                void *mac_addr;
                phandle *ph;
+               int n_res = 1;
 
                memset(r, 0, sizeof(r));
                memset(&gfar_data, 0, sizeof(gfar_data));
@@ -139,8 +137,7 @@ static int __init gfar_of_init(void)
                if (ret)
                        goto err;
 
-               r[1].start = np->intrs[0].line;
-               r[1].end = np->intrs[0].line;
+               r[1].start = r[1].end = irq_of_parse_and_map(np, 0);
                r[1].flags = IORESOURCE_IRQ;
 
                model = get_property(np, "model", NULL);
@@ -150,19 +147,19 @@ static int __init gfar_of_init(void)
                        r[1].name = gfar_tx_intr;
 
                        r[2].name = gfar_rx_intr;
-                       r[2].start = np->intrs[1].line;
-                       r[2].end = np->intrs[1].line;
+                       r[2].start = r[2].end = irq_of_parse_and_map(np, 1);
                        r[2].flags = IORESOURCE_IRQ;
 
                        r[3].name = gfar_err_intr;
-                       r[3].start = np->intrs[2].line;
-                       r[3].end = np->intrs[2].line;
+                       r[3].start = r[3].end = irq_of_parse_and_map(np, 2);
                        r[3].flags = IORESOURCE_IRQ;
+
+                       n_res += 2;
                }
 
                gfar_dev =
                    platform_device_register_simple("fsl-gianfar", i, &r[0],
-                                                   np->n_intrs + 1);
+                                                   n_res + 1);
 
                if (IS_ERR(gfar_dev)) {
                        ret = PTR_ERR(gfar_dev);
@@ -259,8 +256,7 @@ static int __init fsl_i2c_of_init(void)
                if (ret)
                        goto err;
 
-               r[1].start = np->intrs[0].line;
-               r[1].end = np->intrs[0].line;
+               r[1].start = r[1].end = irq_of_parse_and_map(np, 0);
                r[1].flags = IORESOURCE_IRQ;
 
                i2c_dev = platform_device_register_simple("fsl-i2c", i, r, 2);
@@ -396,8 +392,7 @@ static int __init fsl_usb_of_init(void)
                if (ret)
                        goto err;
 
-               r[1].start = np->intrs[0].line;
-               r[1].end = np->intrs[0].line;
+               r[1].start = r[1].end = irq_of_parse_and_map(np, 0);
                r[1].flags = IORESOURCE_IRQ;
 
                usb_dev_mph =
@@ -445,8 +440,7 @@ static int __init fsl_usb_of_init(void)
                if (ret)
                        goto unreg_mph;
 
-               r[1].start = np->intrs[0].line;
-               r[1].end = np->intrs[0].line;
+               r[1].start = r[1].end = irq_of_parse_and_map(np, 0);
                r[1].flags = IORESOURCE_IRQ;
 
                usb_dev_dr =
index 26a0cc8..f303846 100644 (file)
@@ -93,13 +93,15 @@ static int __init tsi108_eth_of_init(void)
                        goto err;
 
                r[1].name = "tx";
-               r[1].start = np->intrs[0].line;
-               r[1].end = np->intrs[0].line;
+               r[1].start = irq_of_parse_and_map(np, 0);
+               r[1].end = irq_of_parse_and_map(np, 0);
                r[1].flags = IORESOURCE_IRQ;
+               DBG("%s: name:start->end = %s:0x%lx-> 0x%lx\n",
+                       __FUNCTION__,r[1].name, r[1].start, r[1].end);
 
                tsi_eth_dev =
                    platform_device_register_simple("tsi-ethernet", i, &r[0],
-                                                   np->n_intrs + 1);
+                                                   1);
 
                if (IS_ERR(tsi_eth_dev)) {
                        ret = PTR_ERR(tsi_eth_dev);
@@ -127,7 +129,7 @@ static int __init tsi108_eth_of_init(void)
                tsi_eth_data.regs = r[0].start;
                tsi_eth_data.phyregs = res.start;
                tsi_eth_data.phy = *phy_id;
-               tsi_eth_data.irq_num = np->intrs[0].line;
+               tsi_eth_data.irq_num = irq_of_parse_and_map(np, 0);
                of_node_put(phy);
                ret =
                    platform_device_add_data(tsi_eth_dev, &tsi_eth_data,
index 3265d54..2ab06ed 100644 (file)
@@ -26,7 +26,6 @@
 #include <linux/irq.h>
 #include <linux/interrupt.h>
 
-
 #include <asm/byteorder.h>
 #include <asm/io.h>
 #include <asm/irq.h>
@@ -228,7 +227,7 @@ int __init tsi108_setup_pci(struct device_node *dev)
 
        (hose)->ops = &tsi108_direct_pci_ops;
 
-       printk(KERN_INFO "Found tsi108 PCI host bridge at 0x%08lx. "
+       printk(KERN_INFO "Found tsi108 PCI host bridge at 0x%08x. "
               "Firmware bus number: %d->%d\n",
               rsrc.start, hose->first_busno, hose->last_busno);
 
@@ -278,7 +277,7 @@ static void init_pci_source(void)
        mb();
 }
 
-static inline int get_pci_source(void)
+static inline unsigned int get_pci_source(void)
 {
        u_int temp = 0;
        int irq = -1;
@@ -371,12 +370,12 @@ static void tsi108_pci_irq_end(u_int irq)
  * Interrupt controller descriptor for cascaded PCI interrupt controller.
  */
 
-struct hw_interrupt_type tsi108_pci_irq = {
+static struct irq_chip tsi108_pci_irq = {
        .typename = "tsi108_PCI_int",
-       .enable = tsi108_pci_irq_enable,
-       .disable = tsi108_pci_irq_disable,
+       .mask = tsi108_pci_irq_disable,
        .ack = tsi108_pci_irq_ack,
        .end = tsi108_pci_irq_end,
+       .unmask = tsi108_pci_irq_enable,
 };
 
 /*
@@ -399,14 +398,18 @@ void __init tsi108_pci_int_init(void)
        DBG("Tsi108_pci_int_init: initializing PCI interrupts\n");
 
        for (i = 0; i < NUM_PCI_IRQS; i++) {
-               irq_desc[i + IRQ_PCI_INTAD_BASE].handler = &tsi108_pci_irq;
+               irq_desc[i + IRQ_PCI_INTAD_BASE].chip = &tsi108_pci_irq;
                irq_desc[i + IRQ_PCI_INTAD_BASE].status |= IRQ_LEVEL;
        }
 
        init_pci_source();
 }
 
-int tsi108_irq_cascade(struct pt_regs *regs, void *unused)
+void tsi108_irq_cascade(unsigned int irq, struct irq_desc *desc,
+                           struct pt_regs *regs)
 {
-       return get_pci_source();
+       unsigned int cascade_irq = get_pci_source();
+       if (cascade_irq != NO_IRQ)
+               generic_handle_irq(cascade_irq, regs);
+       desc->chip->eoi(irq);
 }
index aae3123..3a3aee0 100644 (file)
@@ -1561,7 +1561,7 @@ restart:
                /* ->key must be copied to avoid race with cfq_exit_queue() */
                k = __cic->key;
                if (unlikely(!k)) {
-                       cfq_drop_dead_cic(ioc, cic);
+                       cfq_drop_dead_cic(ioc, __cic);
                        goto restart;
                }
 
index bc7baee..9b72dc7 100644 (file)
@@ -765,7 +765,8 @@ void elv_unregister(struct elevator_type *e)
                read_lock(&tasklist_lock);
                do_each_thread(g, p) {
                        task_lock(p);
-                       e->ops.trim(p->io_context);
+                       if (p->io_context)
+                               e->ops.trim(p->io_context);
                        task_unlock(p);
                } while_each_thread(g, p);
                read_unlock(&tasklist_lock);
index 61d6b3c..ddd9253 100644 (file)
@@ -3628,6 +3628,8 @@ struct io_context *current_io_context(gfp_t gfp_flags)
                ret->nr_batch_requests = 0; /* because this is 0 */
                ret->aic = NULL;
                ret->cic_root.rb_node = NULL;
+               /* make sure set_task_ioprio() sees the settings above */
+               smp_wmb();
                tsk->io_context = ret;
        }
 
index 96309b9..11abc7b 100644 (file)
@@ -285,6 +285,8 @@ static int __init acpi_ac_init(void)
 {
        int result;
 
+       if (acpi_disabled)
+               return -ENODEV;
 
        acpi_ac_dir = acpi_lock_ac_dir();
        if (!acpi_ac_dir)
index b0d4b14..1dda370 100644 (file)
@@ -484,10 +484,8 @@ acpi_memory_register_notify_handler(acpi_handle handle,
 
 
        status = is_memory_device(handle);
-       if (ACPI_FAILURE(status)){
-               ACPI_EXCEPTION((AE_INFO, status, "handle is no memory device"));
+       if (ACPI_FAILURE(status))
                return AE_OK;   /* continue */
-       }
 
        status = acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
                                             acpi_memory_device_notify, NULL);
@@ -503,10 +501,8 @@ acpi_memory_deregister_notify_handler(acpi_handle handle,
 
 
        status = is_memory_device(handle);
-       if (ACPI_FAILURE(status)){
-               ACPI_EXCEPTION((AE_INFO, status, "handle is no memory device"));
+       if (ACPI_FAILURE(status))
                return AE_OK;   /* continue */
-       }
 
        status = acpi_remove_notify_handler(handle,
                                            ACPI_SYSTEM_NOTIFY,
index 6e52217..9810e2a 100644 (file)
@@ -757,6 +757,9 @@ static int __init acpi_battery_init(void)
 {
        int result;
 
+       if (acpi_disabled)
+               return -ENODEV;
+
        acpi_battery_dir = acpi_lock_battery_dir();
        if (!acpi_battery_dir)
                return -ENODEV;
index b297769..279c4ba 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
+#include <linux/kernel.h>
 #include <linux/list.h>
 #include <linux/sched.h>
 #include <linux/pm.h>
@@ -68,7 +69,8 @@ int acpi_bus_get_device(acpi_handle handle, struct acpi_device **device)
 
        status = acpi_get_data(handle, acpi_bus_data_handler, (void **)device);
        if (ACPI_FAILURE(status) || !*device) {
-               ACPI_EXCEPTION((AE_INFO, status, "No context for object [%p]", handle));
+               ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No context for object [%p]\n",
+                                 handle));
                return -ENODEV;
        }
 
@@ -192,7 +194,7 @@ int acpi_bus_set_power(acpi_handle handle, int state)
        /* Make sure this is a valid target state */
 
        if (!device->flags.power_manageable) {
-               ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device `[%s]' is not power manageable",
+               ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device `[%s]' is not power manageable\n",
                                device->kobj.name));
                return -ENODEV;
        }
@@ -738,7 +740,10 @@ static int __init acpi_init(void)
                return -ENODEV;
        }
 
-       firmware_register(&acpi_subsys);
+       result = firmware_register(&acpi_subsys);
+       if (result < 0)
+               printk(KERN_WARNING "%s: firmware_register error: %d\n",
+                       __FUNCTION__, result);
 
        result = acpi_bus_init();
 
index 32c9d88..1ba2db6 100644 (file)
@@ -91,6 +91,14 @@ enum {
        HK_EVENT_ENTERRING_S5,
 };
 
+enum conf_entry_enum {
+       bus_handle = 0,
+       bus_method = 1,
+       action_handle = 2,
+       method = 3,
+       LAST_CONF_ENTRY
+};
+
 /*  procdir we use */
 static struct proc_dir_entry *hotkey_proc_dir;
 static struct proc_dir_entry *hotkey_config;
@@ -244,19 +252,15 @@ static int hotkey_info_open_fs(struct inode *inode, struct file *file)
 
 static char *format_result(union acpi_object *object)
 {
-       char *buf = NULL;
-
-       buf = (char *)kmalloc(RESULT_STR_LEN, GFP_KERNEL);
-       if (buf)
-               memset(buf, 0, RESULT_STR_LEN);
-       else
-               goto do_fail;
+       char *buf;
 
+       buf = kzalloc(RESULT_STR_LEN, GFP_KERNEL);
+       if (!buf)
+               return NULL;
        /* Now, just support integer type */
        if (object->type == ACPI_TYPE_INTEGER)
                sprintf(buf, "%d\n", (u32) object->integer.value);
-      do_fail:
-       return (buf);
+       return buf;
 }
 
 static int hotkey_polling_seq_show(struct seq_file *seq, void *offset)
@@ -486,98 +490,102 @@ static void free_hotkey_device(union acpi_hotkey *key)
 
 static void free_hotkey_buffer(union acpi_hotkey *key)
 {
+       /* key would never be null, action method could be */
        kfree(key->event_hotkey.action_method);
 }
 
 static void free_poll_hotkey_buffer(union acpi_hotkey *key)
 {
+       /* key would never be null, others could be*/
        kfree(key->poll_hotkey.action_method);
        kfree(key->poll_hotkey.poll_method);
        kfree(key->poll_hotkey.poll_result);
 }
 static int
-init_hotkey_device(union acpi_hotkey *key, char *bus_str, char *action_str,
-                  char *method, int std_num, int external_num)
+init_hotkey_device(union acpi_hotkey *key, char **config_entry,
+                  int std_num, int external_num)
 {
        acpi_handle tmp_handle;
        acpi_status status = AE_OK;
 
-
        if (std_num < 0 || IS_POLL(std_num) || !key)
                goto do_fail;
 
-       if (!bus_str || !action_str || !method)
+       if (!config_entry[bus_handle] || !config_entry[action_handle]
+                       || !config_entry[method])
                goto do_fail;
 
        key->link.hotkey_type = ACPI_HOTKEY_EVENT;
        key->link.hotkey_standard_num = std_num;
        key->event_hotkey.flag = 0;
-       key->event_hotkey.action_method = method;
+       key->event_hotkey.action_method = config_entry[method];
 
-       status =
-           acpi_get_handle(NULL, bus_str, &(key->event_hotkey.bus_handle));
+       status = acpi_get_handle(NULL, config_entry[bus_handle],
+                          &(key->event_hotkey.bus_handle));
        if (ACPI_FAILURE(status))
-               goto do_fail;
+               goto do_fail_zero;
        key->event_hotkey.external_hotkey_num = external_num;
-       status =
-           acpi_get_handle(NULL, action_str,
+       status = acpi_get_handle(NULL, config_entry[action_handle],
                            &(key->event_hotkey.action_handle));
        if (ACPI_FAILURE(status))
-               goto do_fail;
+               goto do_fail_zero;
        status = acpi_get_handle(key->event_hotkey.action_handle,
-                                method, &tmp_handle);
+                                config_entry[method], &tmp_handle);
        if (ACPI_FAILURE(status))
-               goto do_fail;
+               goto do_fail_zero;
        return AE_OK;
-      do_fail:
+do_fail_zero:
+       key->event_hotkey.action_method = NULL;
+do_fail:
        return -ENODEV;
 }
 
 static int
-init_poll_hotkey_device(union acpi_hotkey *key,
-                       char *poll_str,
-                       char *poll_method,
-                       char *action_str, char *action_method, int std_num)
+init_poll_hotkey_device(union acpi_hotkey *key, char **config_entry,
+                       int std_num)
 {
        acpi_status status = AE_OK;
        acpi_handle tmp_handle;
 
-
        if (std_num < 0 || IS_EVENT(std_num) || !key)
                goto do_fail;
-
-       if (!poll_str || !poll_method || !action_str || !action_method)
+       if (!config_entry[bus_handle] ||!config_entry[bus_method] ||
+               !config_entry[action_handle] || !config_entry[method])
                goto do_fail;
 
        key->link.hotkey_type = ACPI_HOTKEY_POLLING;
        key->link.hotkey_standard_num = std_num;
        key->poll_hotkey.flag = 0;
-       key->poll_hotkey.poll_method = poll_method;
-       key->poll_hotkey.action_method = action_method;
+       key->poll_hotkey.poll_method = config_entry[bus_method];
+       key->poll_hotkey.action_method = config_entry[method];
 
-       status =
-           acpi_get_handle(NULL, poll_str, &(key->poll_hotkey.poll_handle));
+       status = acpi_get_handle(NULL, config_entry[bus_handle],
+                     &(key->poll_hotkey.poll_handle));
        if (ACPI_FAILURE(status))
-               goto do_fail;
+               goto do_fail_zero;
        status = acpi_get_handle(key->poll_hotkey.poll_handle,
-                                poll_method, &tmp_handle);
+                                config_entry[bus_method], &tmp_handle);
        if (ACPI_FAILURE(status))
-               goto do_fail;
+               goto do_fail_zero;
        status =
-           acpi_get_handle(NULL, action_str,
+           acpi_get_handle(NULL, config_entry[action_handle],
                            &(key->poll_hotkey.action_handle));
        if (ACPI_FAILURE(status))
-               goto do_fail;
+               goto do_fail_zero;
        status = acpi_get_handle(key->poll_hotkey.action_handle,
-                                action_method, &tmp_handle);
+                                config_entry[method], &tmp_handle);
        if (ACPI_FAILURE(status))
-               goto do_fail;
+               goto do_fail_zero;
        key->poll_hotkey.poll_result =
            (union acpi_object *)kmalloc(sizeof(union acpi_object), GFP_KERNEL);
        if (!key->poll_hotkey.poll_result)
-               goto do_fail;
+               goto do_fail_zero;
        return AE_OK;
-      do_fail:
+
+do_fail_zero:
+       key->poll_hotkey.poll_method = NULL;
+       key->poll_hotkey.action_method = NULL;
+do_fail:
        return -ENODEV;
 }
 
@@ -652,17 +660,18 @@ static int hotkey_poll_config_seq_show(struct seq_file *seq, void *offset)
 }
 
 static int
-get_parms(char *config_record,
-         int *cmd,
-         char **bus_handle,
-         char **bus_method,
-         char **action_handle,
-         char **method, int *internal_event_num, int *external_event_num)
+get_parms(char *config_record, int *cmd, char **config_entry,
+              int *internal_event_num, int *external_event_num)
 {
+/* the format of *config_record =
+ * "1:\d+:*" : "cmd:internal_event_num"
+ * "\d+:\w+:\w+:\w+:\w+:\d+:\d+" :
+ * "cmd:bus_handle:bus_method:action_handle:method:internal_event_num:external_event_num"
+ */
        char *tmp, *tmp1, count;
+       int i;
 
        sscanf(config_record, "%d", cmd);
-
        if (*cmd == 1) {
                if (sscanf(config_record, "%d:%d", cmd, internal_event_num) !=
                    2)
@@ -674,59 +683,27 @@ get_parms(char *config_record,
        if (!tmp)
                goto do_fail;
        tmp++;
-       tmp1 = strchr(tmp, ':');
-       if (!tmp1)
-               goto do_fail;
-
-       count = tmp1 - tmp;
-       *bus_handle = (char *)kmalloc(count + 1, GFP_KERNEL);
-       if (!*bus_handle)
-               goto do_fail;
-       strncpy(*bus_handle, tmp, count);
-       *(*bus_handle + count) = 0;
-
-       tmp = tmp1;
-       tmp++;
-       tmp1 = strchr(tmp, ':');
-       if (!tmp1)
-               goto do_fail;
-       count = tmp1 - tmp;
-       *bus_method = (char *)kmalloc(count + 1, GFP_KERNEL);
-       if (!*bus_method)
-               goto do_fail;
-       strncpy(*bus_method, tmp, count);
-       *(*bus_method + count) = 0;
-
-       tmp = tmp1;
-       tmp++;
-       tmp1 = strchr(tmp, ':');
-       if (!tmp1)
-               goto do_fail;
-       count = tmp1 - tmp;
-       *action_handle = (char *)kmalloc(count + 1, GFP_KERNEL);
-       if (!*action_handle)
-               goto do_fail;
-       strncpy(*action_handle, tmp, count);
-       *(*action_handle + count) = 0;
-
-       tmp = tmp1;
-       tmp++;
-       tmp1 = strchr(tmp, ':');
-       if (!tmp1)
-               goto do_fail;
-       count = tmp1 - tmp;
-       *method = (char *)kmalloc(count + 1, GFP_KERNEL);
-       if (!*method)
-               goto do_fail;
-       strncpy(*method, tmp, count);
-       *(*method + count) = 0;
-
-       if (sscanf(tmp1 + 1, "%d:%d", internal_event_num, external_event_num) <=
-           0)
-               goto do_fail;
-
-       return 6;
-      do_fail:
+       for (i = 0; i < LAST_CONF_ENTRY; i++) {
+               tmp1 = strchr(tmp, ':');
+               if (!tmp1) {
+                       goto do_fail;
+               }
+               count = tmp1 - tmp;
+               config_entry[i] = kzalloc(count + 1, GFP_KERNEL);
+               if (!config_entry[i])
+                       goto handle_failure;
+               strncpy(config_entry[i], tmp, count);
+               tmp = tmp1 + 1;
+       }
+       if (sscanf(tmp, "%d:%d", internal_event_num, external_event_num) <= 0)
+               goto handle_failure;
+       if (!IS_OTHERS(*internal_event_num)) {
+               return 6;
+       }
+handle_failure:
+       while (i-- > 0)
+               kfree(config_entry[i]);
+do_fail:
        return -1;
 }
 
@@ -736,50 +713,34 @@ static ssize_t hotkey_write_config(struct file *file,
                                   size_t count, loff_t * data)
 {
        char *config_record = NULL;
-       char *bus_handle = NULL;
-       char *bus_method = NULL;
-       char *action_handle = NULL;
-       char *method = NULL;
+       char *config_entry[LAST_CONF_ENTRY];
        int cmd, internal_event_num, external_event_num;
        int ret = 0;
-       union acpi_hotkey *key = NULL;
+       union acpi_hotkey *key = kzalloc(sizeof(union acpi_hotkey), GFP_KERNEL);
 
+       if (!key)
+               return -ENOMEM;
 
-       config_record = (char *)kmalloc(count + 1, GFP_KERNEL);
-       if (!config_record)
+       config_record = kzalloc(count + 1, GFP_KERNEL);
+       if (!config_record) {
+               kfree(key);
                return -ENOMEM;
+       }
 
        if (copy_from_user(config_record, buffer, count)) {
                kfree(config_record);
+               kfree(key);
                printk(KERN_ERR PREFIX "Invalid data\n");
                return -EINVAL;
        }
-       config_record[count] = 0;
-
-       ret = get_parms(config_record,
-                       &cmd,
-                       &bus_handle,
-                       &bus_method,
-                       &action_handle,
-                       &method, &internal_event_num, &external_event_num);
-
+       ret = get_parms(config_record, &cmd, config_entry,
+                      &internal_event_num, &external_event_num);
        kfree(config_record);
-       if (IS_OTHERS(internal_event_num))
-               goto do_fail;
        if (ret != 6) {
-             do_fail:
-               kfree(bus_handle);
-               kfree(bus_method);
-               kfree(action_handle);
-               kfree(method);
                printk(KERN_ERR PREFIX "Invalid data format ret=%d\n", ret);
                return -EINVAL;
        }
 
-       key = kmalloc(sizeof(union acpi_hotkey), GFP_KERNEL);
-       if (!key)
-               goto do_fail;
-       memset(key, 0, sizeof(union acpi_hotkey));
        if (cmd == 1) {
                union acpi_hotkey *tmp = NULL;
                tmp = get_hotkey_by_event(&global_hotkey_list,
@@ -791,34 +752,19 @@ static ssize_t hotkey_write_config(struct file *file,
                goto cont_cmd;
        }
        if (IS_EVENT(internal_event_num)) {
-               kfree(bus_method);
-               ret = init_hotkey_device(key, bus_handle, action_handle, method,
-                                        internal_event_num,
-                                        external_event_num);
-       } else
-               ret = init_poll_hotkey_device(key, bus_handle, bus_method,
-                                             action_handle, method,
-                                             internal_event_num);
-       if (ret) {
-               kfree(bus_handle);
-               kfree(action_handle);
-               if (IS_EVENT(internal_event_num))
-                       free_hotkey_buffer(key);
-               else
-                       free_poll_hotkey_buffer(key);
-               kfree(key);
-               printk(KERN_ERR PREFIX "Invalid hotkey\n");
-               return -EINVAL;
+               if (init_hotkey_device(key, config_entry,
+                       internal_event_num, external_event_num))
+                       goto init_hotkey_fail;
+       } else {
+               if (init_poll_hotkey_device(key, config_entry,
+                              internal_event_num))
+                       goto init_poll_hotkey_fail;
        }
-
-      cont_cmd:
-       kfree(bus_handle);
-       kfree(action_handle);
-
+cont_cmd:
        switch (cmd) {
        case 0:
-               if (get_hotkey_by_event
-                   (&global_hotkey_list, key->link.hotkey_standard_num))
+               if (get_hotkey_by_event(&global_hotkey_list,
+                               key->link.hotkey_standard_num))
                        goto fail_out;
                else
                        hotkey_add(key);
@@ -827,6 +773,7 @@ static ssize_t hotkey_write_config(struct file *file,
                hotkey_remove(key);
                break;
        case 2:
+               /* key is kfree()ed if matched*/
                if (hotkey_update(key))
                        goto fail_out;
                break;
@@ -835,11 +782,22 @@ static ssize_t hotkey_write_config(struct file *file,
                break;
        }
        return count;
-      fail_out:
-       if (IS_EVENT(internal_event_num))
-               free_hotkey_buffer(key);
-       else
-               free_poll_hotkey_buffer(key);
+
+init_poll_hotkey_fail:         /* failed init_poll_hotkey_device */
+       kfree(config_entry[bus_method]);
+       config_entry[bus_method] = NULL;
+init_hotkey_fail:              /* failed init_hotkey_device */
+       kfree(config_entry[method]);
+fail_out:
+       kfree(config_entry[bus_handle]);
+       kfree(config_entry[action_handle]);
+       /* No double free since elements =NULL for error cases */
+       if (IS_EVENT(internal_event_num)) {
+               if (config_entry[bus_method])
+                       kfree(config_entry[bus_method]);
+               free_hotkey_buffer(key);        /* frees [method] */
+       } else
+               free_poll_hotkey_buffer(key);  /* frees [bus_method]+[method] */
        kfree(key);
        printk(KERN_ERR PREFIX "invalid key\n");
        return -EINVAL;
@@ -923,10 +881,9 @@ static ssize_t hotkey_execute_aml_method(struct file *file,
        union acpi_hotkey *key;
 
 
-       arg = (char *)kmalloc(count + 1, GFP_KERNEL);
+       arg = kzalloc(count + 1, GFP_KERNEL);
        if (!arg)
                return -ENOMEM;
-       arg[count] = 0;
 
        if (copy_from_user(arg, buffer, count)) {
                kfree(arg);
index 84239d5..6809c28 100644 (file)
@@ -330,7 +330,7 @@ static int acpi_ec_hc_add(struct acpi_device *device)
        status = acpi_evaluate_integer(ec_hc->handle, "_EC", NULL, &val);
        if (ACPI_FAILURE(status)) {
                ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Error obtaining _EC\n"));
-               kfree(ec_hc->smbus);
+               kfree(ec_hc);
                kfree(smbus);
                return -EIO;
        }
index b7d1514..507f051 100644 (file)
@@ -746,6 +746,16 @@ acpi_status acpi_os_wait_semaphore(acpi_handle handle, u32 units, u16 timeout)
        ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Waiting for semaphore[%p|%d|%d]\n",
                          handle, units, timeout));
 
+       /*
+        * This can be called during resume with interrupts off.
+        * Like boot-time, we should be single threaded and will
+        * always get the lock if we try -- timeout or not.
+        * If this doesn't succeed, then we will oops courtesy of
+        * might_sleep() in down().
+        */
+       if (!down_trylock(sem))
+               return AE_OK;
+
        switch (timeout) {
                /*
                 * No Wait:
index db7b350..62bef0b 100644 (file)
@@ -1714,6 +1714,9 @@ static int __init acpi_sbs_init(void)
 {
        int result = 0;
 
+       if (acpi_disabled)
+               return -ENODEV;
+
        init_MUTEX(&sbs_sem);
 
        if (capacity_mode != DEF_CAPACITY_UNIT
index 5fcb50c..698a154 100644 (file)
@@ -4,6 +4,7 @@
 
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/kernel.h>
 #include <linux/acpi.h>
 
 #include <acpi/acpi_drivers.h>
@@ -113,6 +114,8 @@ static struct kset acpi_namespace_kset = {
 static void acpi_device_register(struct acpi_device *device,
                                 struct acpi_device *parent)
 {
+       int err;
+
        /*
         * Linkage
         * -------
@@ -138,7 +141,10 @@ static void acpi_device_register(struct acpi_device *device,
                device->kobj.parent = &parent->kobj;
        device->kobj.ktype = &ktype_acpi_ns;
        device->kobj.kset = &acpi_namespace_kset;
-       kobject_register(&device->kobj);
+       err = kobject_register(&device->kobj);
+       if (err < 0)
+               printk(KERN_WARNING "%s: kobject_register error: %d\n",
+                       __FUNCTION__, err);
        create_sysfs_device_files(device);
 }
 
@@ -1450,7 +1456,9 @@ static int __init acpi_scan_init(void)
        if (acpi_disabled)
                return 0;
 
-       kset_register(&acpi_namespace_kset);
+       result = kset_register(&acpi_namespace_kset);
+       if (result < 0)
+               printk(KERN_ERR PREFIX "kset_register error: %d\n", result);
 
        result = bus_register(&acpi_bus_type);
        if (result) {
index f48227f..d0d84c4 100644 (file)
@@ -262,7 +262,7 @@ acpi_evaluate_integer(acpi_handle handle,
        if (!data)
                return AE_BAD_PARAMETER;
 
-       element = kmalloc(sizeof(union acpi_object), GFP_KERNEL);
+       element = kmalloc(sizeof(union acpi_object), irqs_disabled() ? GFP_ATOMIC: GFP_KERNEL);
        if (!element)
                return AE_NO_MEMORY;
 
index e05ca2c..75313ad 100644 (file)
@@ -301,7 +301,8 @@ static void ib_cache_event(struct ib_event_handler *handler,
            event->event == IB_EVENT_PORT_ACTIVE ||
            event->event == IB_EVENT_LID_CHANGE  ||
            event->event == IB_EVENT_PKEY_CHANGE ||
-           event->event == IB_EVENT_SM_CHANGE) {
+           event->event == IB_EVENT_SM_CHANGE   ||
+           event->event == IB_EVENT_CLIENT_REREGISTER) {
                work = kmalloc(sizeof *work, GFP_ATOMIC);
                if (work) {
                        INIT_WORK(&work->work, ib_cache_task, work);
index aeda484..d6b8422 100644 (file)
@@ -405,7 +405,8 @@ static void ib_sa_event(struct ib_event_handler *handler, struct ib_event *event
            event->event == IB_EVENT_PORT_ACTIVE ||
            event->event == IB_EVENT_LID_CHANGE  ||
            event->event == IB_EVENT_PKEY_CHANGE ||
-           event->event == IB_EVENT_SM_CHANGE) {
+           event->event == IB_EVENT_SM_CHANGE   ||
+           event->event == IB_EVENT_CLIENT_REREGISTER) {
                struct ib_sa_device *sa_dev;
                sa_dev = container_of(handler, typeof(*sa_dev), event_handler);
 
index 557cde3..7b82c19 100644 (file)
@@ -967,12 +967,12 @@ static struct {
 } mthca_hca_table[] = {
        [TAVOR]        = { .latest_fw = MTHCA_FW_VER(3, 4, 0),
                           .flags     = 0 },
-       [ARBEL_COMPAT] = { .latest_fw = MTHCA_FW_VER(4, 7, 400),
+       [ARBEL_COMPAT] = { .latest_fw = MTHCA_FW_VER(4, 7, 600),
                           .flags     = MTHCA_FLAG_PCIE },
-       [ARBEL_NATIVE] = { .latest_fw = MTHCA_FW_VER(5, 1, 0),
+       [ARBEL_NATIVE] = { .latest_fw = MTHCA_FW_VER(5, 1, 400),
                           .flags     = MTHCA_FLAG_MEMFREE |
                                        MTHCA_FLAG_PCIE },
-       [SINAI]        = { .latest_fw = MTHCA_FW_VER(1, 0, 800),
+       [SINAI]        = { .latest_fw = MTHCA_FW_VER(1, 1, 0),
                           .flags     = MTHCA_FLAG_MEMFREE |
                                        MTHCA_FLAG_PCIE    |
                                        MTHCA_FLAG_SINAI_OPT }
index 230ae21..265b1d1 100644 (file)
@@ -1287,11 +1287,7 @@ int mthca_register_device(struct mthca_dev *dev)
                (1ull << IB_USER_VERBS_CMD_MODIFY_QP)           |
                (1ull << IB_USER_VERBS_CMD_DESTROY_QP)          |
                (1ull << IB_USER_VERBS_CMD_ATTACH_MCAST)        |
-               (1ull << IB_USER_VERBS_CMD_DETACH_MCAST)        |
-               (1ull << IB_USER_VERBS_CMD_CREATE_SRQ)          |
-               (1ull << IB_USER_VERBS_CMD_MODIFY_SRQ)          |
-               (1ull << IB_USER_VERBS_CMD_QUERY_SRQ)           |
-               (1ull << IB_USER_VERBS_CMD_DESTROY_SRQ);
+               (1ull << IB_USER_VERBS_CMD_DETACH_MCAST);
        dev->ib_dev.node_type            = IB_NODE_CA;
        dev->ib_dev.phys_port_cnt        = dev->limits.num_ports;
        dev->ib_dev.dma_device           = &dev->pdev->dev;
@@ -1316,6 +1312,11 @@ int mthca_register_device(struct mthca_dev *dev)
                dev->ib_dev.modify_srq           = mthca_modify_srq;
                dev->ib_dev.query_srq            = mthca_query_srq;
                dev->ib_dev.destroy_srq          = mthca_destroy_srq;
+               dev->ib_dev.uverbs_cmd_mask     |=
+                       (1ull << IB_USER_VERBS_CMD_CREATE_SRQ)          |
+                       (1ull << IB_USER_VERBS_CMD_MODIFY_SRQ)          |
+                       (1ull << IB_USER_VERBS_CMD_QUERY_SRQ)           |
+                       (1ull << IB_USER_VERBS_CMD_DESTROY_SRQ);
 
                if (mthca_is_memfree(dev))
                        dev->ib_dev.post_srq_recv = mthca_arbel_post_srq_recv;
index 8de2887..9a5bece 100644 (file)
@@ -136,8 +136,8 @@ struct mthca_ah {
  * We have one global lock that protects dev->cq/qp_table.  Each
  * struct mthca_cq/qp also has its own lock.  An individual qp lock
  * may be taken inside of an individual cq lock.  Both cqs attached to
- * a qp may be locked, with the send cq locked first.  No other
- * nesting should be done.
+ * a qp may be locked, with the cq with the lower cqn locked first.
+ * No other nesting should be done.
  *
  * Each struct mthca_cq/qp also has an ref count, protected by the
  * corresponding table lock.  The pointer from the cq/qp_table to the
index cd8b672..2e8f6f3 100644 (file)
@@ -99,6 +99,10 @@ enum {
        MTHCA_QP_BIT_RSC = 1 <<  3
 };
 
+enum {
+       MTHCA_SEND_DOORBELL_FENCE = 1 << 5
+};
+
 struct mthca_qp_path {
        __be32 port_pkey;
        u8     rnr_retry;
@@ -1259,6 +1263,32 @@ int mthca_alloc_qp(struct mthca_dev *dev,
        return 0;
 }
 
+static void mthca_lock_cqs(struct mthca_cq *send_cq, struct mthca_cq *recv_cq)
+{
+       if (send_cq == recv_cq)
+               spin_lock_irq(&send_cq->lock);
+       else if (send_cq->cqn < recv_cq->cqn) {
+               spin_lock_irq(&send_cq->lock);
+               spin_lock_nested(&recv_cq->lock, SINGLE_DEPTH_NESTING);
+       } else {
+               spin_lock_irq(&recv_cq->lock);
+               spin_lock_nested(&send_cq->lock, SINGLE_DEPTH_NESTING);
+       }
+}
+
+static void mthca_unlock_cqs(struct mthca_cq *send_cq, struct mthca_cq *recv_cq)
+{
+       if (send_cq == recv_cq)
+               spin_unlock_irq(&send_cq->lock);
+       else if (send_cq->cqn < recv_cq->cqn) {
+               spin_unlock(&recv_cq->lock);
+               spin_unlock_irq(&send_cq->lock);
+       } else {
+               spin_unlock(&send_cq->lock);
+               spin_unlock_irq(&recv_cq->lock);
+       }
+}
+
 int mthca_alloc_sqp(struct mthca_dev *dev,
                    struct mthca_pd *pd,
                    struct mthca_cq *send_cq,
@@ -1311,17 +1341,13 @@ int mthca_alloc_sqp(struct mthca_dev *dev,
         * Lock CQs here, so that CQ polling code can do QP lookup
         * without taking a lock.
         */
-       spin_lock_irq(&send_cq->lock);
-       if (send_cq != recv_cq)
-               spin_lock(&recv_cq->lock);
+       mthca_lock_cqs(send_cq, recv_cq);
 
        spin_lock(&dev->qp_table.lock);
        mthca_array_clear(&dev->qp_table.qp, mqpn);
        spin_unlock(&dev->qp_table.lock);
 
-       if (send_cq != recv_cq)
-               spin_unlock(&recv_cq->lock);
-       spin_unlock_irq(&send_cq->lock);
+       mthca_unlock_cqs(send_cq, recv_cq);
 
  err_out:
        dma_free_coherent(&dev->pdev->dev, sqp->header_buf_size,
@@ -1355,9 +1381,7 @@ void mthca_free_qp(struct mthca_dev *dev,
         * Lock CQs here, so that CQ polling code can do QP lookup
         * without taking a lock.
         */
-       spin_lock_irq(&send_cq->lock);
-       if (send_cq != recv_cq)
-               spin_lock(&recv_cq->lock);
+       mthca_lock_cqs(send_cq, recv_cq);
 
        spin_lock(&dev->qp_table.lock);
        mthca_array_clear(&dev->qp_table.qp,
@@ -1365,9 +1389,7 @@ void mthca_free_qp(struct mthca_dev *dev,
        --qp->refcount;
        spin_unlock(&dev->qp_table.lock);
 
-       if (send_cq != recv_cq)
-               spin_unlock(&recv_cq->lock);
-       spin_unlock_irq(&send_cq->lock);
+       mthca_unlock_cqs(send_cq, recv_cq);
 
        wait_event(qp->wait, !get_qp_refcount(dev, qp));
 
@@ -1502,7 +1524,7 @@ int mthca_tavor_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
        int i;
        int size;
        int size0 = 0;
-       u32 f0 = 0;
+       u32 f0;
        int ind;
        u8 op0 = 0;
 
@@ -1686,6 +1708,8 @@ int mthca_tavor_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
                if (!size0) {
                        size0 = size;
                        op0   = mthca_opcode[wr->opcode];
+                       f0    = wr->send_flags & IB_SEND_FENCE ?
+                               MTHCA_SEND_DOORBELL_FENCE : 0;
                }
 
                ++ind;
@@ -1843,7 +1867,7 @@ int mthca_arbel_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
        int i;
        int size;
        int size0 = 0;
-       u32 f0 = 0;
+       u32 f0;
        int ind;
        u8 op0 = 0;
 
@@ -2051,6 +2075,8 @@ int mthca_arbel_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
                if (!size0) {
                        size0 = size;
                        op0   = mthca_opcode[wr->opcode];
+                       f0    = wr->send_flags & IB_SEND_FENCE ?
+                               MTHCA_SEND_DOORBELL_FENCE : 0;
                }
 
                ++ind;
index 6bfa0cf..a86afd0 100644 (file)
@@ -498,7 +498,7 @@ static int atkbd_set_repeat_rate(struct atkbd *atkbd)
                i++;
        dev->rep[REP_PERIOD] = period[i];
 
-       while (j < ARRAY_SIZE(period) - 1 && delay[j] < dev->rep[REP_DELAY])
+       while (j < ARRAY_SIZE(delay) - 1 && delay[j] < dev->rep[REP_DELAY])
                j++;
        dev->rep[REP_DELAY] = delay[j];
 
index a8efc1a..de0f46d 100644 (file)
@@ -259,11 +259,11 @@ static int __init dmi_matched(struct dmi_system_id *dmi)
        return 1;
 }
 
-static struct key_entry keymap_empty[] __initdata = {
+static struct key_entry keymap_empty[] = {
        { KE_END, 0 }
 };
 
-static struct key_entry keymap_fs_amilo_pro_v2000[] __initdata = {
+static struct key_entry keymap_fs_amilo_pro_v2000[] = {
        { KE_KEY,  0x01, KEY_HELP },
        { KE_KEY,  0x11, KEY_PROG1 },
        { KE_KEY,  0x12, KEY_PROG2 },
@@ -273,7 +273,7 @@ static struct key_entry keymap_fs_amilo_pro_v2000[] __initdata = {
        { KE_END,  0 }
 };
 
-static struct key_entry keymap_fujitsu_n3510[] __initdata = {
+static struct key_entry keymap_fujitsu_n3510[] = {
        { KE_KEY, 0x11, KEY_PROG1 },
        { KE_KEY, 0x12, KEY_PROG2 },
        { KE_KEY, 0x36, KEY_WWW },
@@ -285,7 +285,7 @@ static struct key_entry keymap_fujitsu_n3510[] __initdata = {
        { KE_END, 0 }
 };
 
-static struct key_entry keymap_wistron_ms2111[] __initdata = {
+static struct key_entry keymap_wistron_ms2111[] = {
        { KE_KEY,  0x11, KEY_PROG1 },
        { KE_KEY,  0x12, KEY_PROG2 },
        { KE_KEY,  0x13, KEY_PROG3 },
@@ -294,7 +294,7 @@ static struct key_entry keymap_wistron_ms2111[] __initdata = {
        { KE_END,  0 }
 };
 
-static struct key_entry keymap_wistron_ms2141[] __initdata = {
+static struct key_entry keymap_wistron_ms2141[] = {
        { KE_KEY,  0x11, KEY_PROG1 },
        { KE_KEY,  0x12, KEY_PROG2 },
        { KE_WIFI, 0x30, 0 },
@@ -307,7 +307,7 @@ static struct key_entry keymap_wistron_ms2141[] __initdata = {
        { KE_END,  0 }
 };
 
-static struct key_entry keymap_acer_aspire_1500[] __initdata = {
+static struct key_entry keymap_acer_aspire_1500[] = {
        { KE_KEY, 0x11, KEY_PROG1 },
        { KE_KEY, 0x12, KEY_PROG2 },
        { KE_WIFI, 0x30, 0 },
@@ -317,7 +317,7 @@ static struct key_entry keymap_acer_aspire_1500[] __initdata = {
        { KE_END, 0 }
 };
 
-static struct key_entry keymap_acer_travelmate_240[] __initdata = {
+static struct key_entry keymap_acer_travelmate_240[] = {
        { KE_KEY, 0x31, KEY_MAIL },
        { KE_KEY, 0x36, KEY_WWW },
        { KE_KEY, 0x11, KEY_PROG1 },
@@ -327,7 +327,7 @@ static struct key_entry keymap_acer_travelmate_240[] __initdata = {
        { KE_END, 0 }
 };
 
-static struct key_entry keymap_aopen_1559as[] __initdata = {
+static struct key_entry keymap_aopen_1559as[] = {
        { KE_KEY,  0x01, KEY_HELP },
        { KE_KEY,  0x06, KEY_PROG3 },
        { KE_KEY,  0x11, KEY_PROG1 },
index 8bc9f51..343afa3 100644 (file)
@@ -485,13 +485,6 @@ static int im_explorer_detect(struct psmouse *psmouse, int set_properties)
        param[0] =  40;
        ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);
 
-       param[0] = 200;
-       ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);
-       param[0] = 200;
-       ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);
-       param[0] =  60;
-       ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);
-
        if (set_properties) {
                set_bit(BTN_MIDDLE, psmouse->dev->keybit);
                set_bit(REL_WHEEL, psmouse->dev->relbit);
index 3c148ea..8a60f39 100644 (file)
@@ -76,7 +76,7 @@ config HOTPLUG_PCI_IBM
 
 config HOTPLUG_PCI_ACPI
        tristate "ACPI PCI Hotplug driver"
-       depends on ACPI_DOCK && HOTPLUG_PCI
+       depends on (!ACPI_DOCK && ACPI && HOTPLUG_PCI) || (ACPI_DOCK && HOTPLUG_PCI)
        help
          Say Y here if you have a system that supports PCI Hotplug using
          ACPI.
index fb08bc9..04618d4 100644 (file)
@@ -1518,6 +1518,63 @@ static void __devinit quirk_netmos(struct pci_dev *dev)
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NETMOS, PCI_ANY_ID, quirk_netmos);
 
+static void __devinit quirk_e100_interrupt(struct pci_dev *dev)
+{
+       u16 command;
+       u32 bar;
+       u8 __iomem *csr;
+       u8 cmd_hi;
+
+       switch (dev->device) {
+       /* PCI IDs taken from drivers/net/e100.c */
+       case 0x1029:
+       case 0x1030 ... 0x1034:
+       case 0x1038 ... 0x103E:
+       case 0x1050 ... 0x1057:
+       case 0x1059:
+       case 0x1064 ... 0x106B:
+       case 0x1091 ... 0x1095:
+       case 0x1209:
+       case 0x1229:
+       case 0x2449:
+       case 0x2459:
+       case 0x245D:
+       case 0x27DC:
+               break;
+       default:
+               return;
+       }
+
+       /*
+        * Some firmware hands off the e100 with interrupts enabled,
+        * which can cause a flood of interrupts if packets are
+        * received before the driver attaches to the device.  So
+        * disable all e100 interrupts here.  The driver will
+        * re-enable them when it's ready.
+        */
+       pci_read_config_word(dev, PCI_COMMAND, &command);
+       pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &bar);
+
+       if (!(command & PCI_COMMAND_MEMORY) || !bar)
+               return;
+
+       csr = ioremap(bar, 8);
+       if (!csr) {
+               printk(KERN_WARNING "PCI: Can't map %s e100 registers\n",
+                       pci_name(dev));
+               return;
+       }
+
+       cmd_hi = readb(csr + 3);
+       if (cmd_hi == 0) {
+               printk(KERN_WARNING "PCI: Firmware left %s e100 interrupts "
+                       "enabled, disabling\n", pci_name(dev));
+               writeb(1, csr + 3);
+       }
+
+       iounmap(csr);
+}
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, quirk_e100_interrupt);
 
 static void __devinit fixup_rev1_53c810(struct pci_dev* dev)
 {
index 98bd227..5630868 100644 (file)
@@ -1146,7 +1146,7 @@ static struct sbus_dev sun4_esp_dev;
 static int __init esp_sun4_probe(struct scsi_host_template *tpnt)
 {
        if (sun4_esp_physaddr) {
-               memset(&sun4_esp_dev, 0, sizeof(esp_dev));
+               memset(&sun4_esp_dev, 0, sizeof(sun4_esp_dev));
                sun4_esp_dev.reg_addrs[0].phys_addr = sun4_esp_physaddr;
                sun4_esp_dev.irqs[0] = 4;
                sun4_esp_dev.resource[0].start = sun4_esp_physaddr;
@@ -1162,6 +1162,7 @@ static int __init esp_sun4_probe(struct scsi_host_template *tpnt)
 
 static int __devexit esp_sun4_remove(void)
 {
+       struct of_device *dev = &sun4_esp_dev.ofdev;
        struct esp *esp = dev_get_drvdata(&dev->dev);
 
        return esp_remove_common(esp);
index dc673e1..cfe20f7 100644 (file)
@@ -886,6 +886,15 @@ static int sunsab_console_setup(struct console *con, char *options)
        unsigned long flags;
        unsigned int baud, quot;
 
+       /*
+        * The console framework calls us for each and every port
+        * registered. Defer the console setup until the requested
+        * port has been properly discovered. A bit of a hack,
+        * though...
+        */
+       if (up->port.type != PORT_SUNSAB)
+               return -1;
+
        printk("Console: ttyS%d (SAB82532)\n",
               (sunsab_reg.minor - 64) + con->index);
 
index 47bc3d5..d34f336 100644 (file)
@@ -1146,6 +1146,9 @@ static int __init sunzilog_console_setup(struct console *con, char *options)
        unsigned long flags;
        int baud, brg;
 
+       if (up->port.type != PORT_SUNZILOG)
+               return -1;
+
        printk(KERN_INFO "Console: ttyS%d (SunZilog zs%d)\n",
               (sunzilog_reg.minor - 64) + con->index, con->index);
 
index 93aa571..78b1dea 100644 (file)
@@ -44,6 +44,9 @@ static int set_task_ioprio(struct task_struct *task, int ioprio)
        task->ioprio = ioprio;
 
        ioc = task->io_context;
+       /* see wmb() in current_io_context() */
+       smp_read_barrier_depends();
+
        if (ioc && ioc->set_ioprio)
                ioc->set_ioprio(ioc, ioprio);
 
@@ -111,9 +114,9 @@ asmlinkage long sys_ioprio_set(int which, int who, int ioprio)
                                        continue;
                                ret = set_task_ioprio(p, ioprio);
                                if (ret)
-                                       break;
+                                       goto free_uid;
                        } while_each_thread(g, p);
-
+free_uid:
                        if (who)
                                free_uid(user);
                        break;
@@ -137,6 +140,29 @@ out:
        return ret;
 }
 
+int ioprio_best(unsigned short aprio, unsigned short bprio)
+{
+       unsigned short aclass = IOPRIO_PRIO_CLASS(aprio);
+       unsigned short bclass = IOPRIO_PRIO_CLASS(bprio);
+
+       if (!ioprio_valid(aprio))
+               return bprio;
+       if (!ioprio_valid(bprio))
+               return aprio;
+
+       if (aclass == IOPRIO_CLASS_NONE)
+               aclass = IOPRIO_CLASS_BE;
+       if (bclass == IOPRIO_CLASS_NONE)
+               bclass = IOPRIO_CLASS_BE;
+
+       if (aclass == bclass)
+               return min(aprio, bprio);
+       if (aclass > bclass)
+               return bprio;
+       else
+               return aprio;
+}
+
 asmlinkage long sys_ioprio_get(int which, int who)
 {
        struct task_struct *g, *p;
index 7de172e..fcce1a2 100644 (file)
@@ -1659,7 +1659,7 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
                iput(inode);
                goto error_out;
        }
-       sb->s_maxbytes = MAX_LFS_FILESIZE;
+       sb->s_maxbytes = 1<<30;
        return 0;
 
 error_out:
index e1b0e8c..0abd66c 100644 (file)
@@ -239,37 +239,51 @@ void udf_truncate_extents(struct inode * inode)
        {
                if (offset)
                {
-                       extoffset -= adsize;
-                       etype = udf_next_aext(inode, &bloc, &extoffset, &eloc, &elen, &bh, 1);
-                       if (etype == (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30))
-                       {
-                               extoffset -= adsize;
-                               elen = EXT_NOT_RECORDED_NOT_ALLOCATED | (elen + offset);
-                               udf_write_aext(inode, bloc, &extoffset, eloc, elen, bh, 0);
+                       /*
+                        *  OK, there is not extent covering inode->i_size and
+                        *  no extent above inode->i_size => truncate is
+                        *  extending the file by 'offset'.
+                        */
+                       if ((!bh && extoffset == udf_file_entry_alloc_offset(inode)) ||
+                           (bh && extoffset == sizeof(struct allocExtDesc))) {
+                               /* File has no extents at all! */
+                               memset(&eloc, 0x00, sizeof(kernel_lb_addr));
+                               elen = EXT_NOT_RECORDED_NOT_ALLOCATED | offset;
+                               udf_add_aext(inode, &bloc, &extoffset, eloc, elen, &bh, 1);
                        }
-                       else if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30))
-                       {
-                               kernel_lb_addr neloc = { 0, 0 };
+                       else {
                                extoffset -= adsize;
-                               nelen = EXT_NOT_RECORDED_NOT_ALLOCATED |
-                                       ((elen + offset + inode->i_sb->s_blocksize - 1) &
-                                       ~(inode->i_sb->s_blocksize - 1));
-                               udf_write_aext(inode, bloc, &extoffset, neloc, nelen, bh, 1);
-                               udf_add_aext(inode, &bloc, &extoffset, eloc, (etype << 30) | elen, &bh, 1);
-                       }
-                       else
-                       {
-                               if (elen & (inode->i_sb->s_blocksize - 1))
+                               etype = udf_next_aext(inode, &bloc, &extoffset, &eloc, &elen, &bh, 1);
+                               if (etype == (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30))
+                               {
+                                       extoffset -= adsize;
+                                       elen = EXT_NOT_RECORDED_NOT_ALLOCATED | (elen + offset);
+                                       udf_write_aext(inode, bloc, &extoffset, eloc, elen, bh, 0);
+                               }
+                               else if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30))
                                {
+                                       kernel_lb_addr neloc = { 0, 0 };
                                        extoffset -= adsize;
-                                       elen = EXT_RECORDED_ALLOCATED |
-                                               ((elen + inode->i_sb->s_blocksize - 1) &
+                                       nelen = EXT_NOT_RECORDED_NOT_ALLOCATED |
+                                               ((elen + offset + inode->i_sb->s_blocksize - 1) &
                                                ~(inode->i_sb->s_blocksize - 1));
-                                       udf_write_aext(inode, bloc, &extoffset, eloc, elen, bh, 1);
+                                       udf_write_aext(inode, bloc, &extoffset, neloc, nelen, bh, 1);
+                                       udf_add_aext(inode, &bloc, &extoffset, eloc, (etype << 30) | elen, &bh, 1);
+                               }
+                               else
+                               {
+                                       if (elen & (inode->i_sb->s_blocksize - 1))
+                                       {
+                                               extoffset -= adsize;
+                                               elen = EXT_RECORDED_ALLOCATED |
+                                                       ((elen + inode->i_sb->s_blocksize - 1) &
+                                                       ~(inode->i_sb->s_blocksize - 1));
+                                               udf_write_aext(inode, bloc, &extoffset, eloc, elen, bh, 1);
+                                       }
+                                       memset(&eloc, 0x00, sizeof(kernel_lb_addr));
+                                       elen = EXT_NOT_RECORDED_NOT_ALLOCATED | offset;
+                                       udf_add_aext(inode, &bloc, &extoffset, eloc, elen, &bh, 1);
                                }
-                               memset(&eloc, 0x00, sizeof(kernel_lb_addr));
-                               elen = EXT_NOT_RECORDED_NOT_ALLOCATED | offset;
-                               udf_add_aext(inode, &bloc, &extoffset, eloc, elen, &bh, 1);
                        }
                }
        }
index 72964f9..7463fd5 100644 (file)
@@ -104,6 +104,7 @@ enum s3c2410_chan_op_e {
        S3C2410_DMAOP_RESUME,
        S3C2410_DMAOP_FLUSH,
        S3C2410_DMAOP_TIMEOUT,           /* internal signal to handler */
+       S3C2410_DMAOP_STARTED,          /* indicate channel started */
 };
 
 typedef enum s3c2410_chan_op_e s3c2410_chan_op_t;
index edb7b65..91a31ad 100644 (file)
@@ -55,5 +55,6 @@ extern unsigned int elf_hwcap;
 #define HWCAP_VFP      64
 #define HWCAP_EDSP     128
 #define HWCAP_JAVA     256
+#define HWCAP_IWMMXT   512
 
 #endif
index 9f0917c..ae63db7 100644 (file)
@@ -117,7 +117,7 @@ static inline void pte_free(struct page *ptepage)
        pte_free_kernel(page_address(ptepage));
 }
 
-#define PGF_CACHENUM_MASK      0xf
+#define PGF_CACHENUM_MASK      0x3
 
 typedef struct pgtable_free {
        unsigned long val;
index 7307aa7..4c9f522 100644 (file)
 #define smp_read_barrier_depends()     do { } while(0)
 #endif /* CONFIG_SMP */
 
+/*
+ * This is a barrier which prevents following instructions from being
+ * started until the value of the argument x is known.  For example, if
+ * x is a variable loaded from memory, this prevents following
+ * instructions from being executed until the load has been performed.
+ */
+#define data_barrier(x)        \
+       asm volatile("twi 0,%0,0; isync" : : "r" (x) : "memory");
+
 struct task_struct;
 struct pt_regs;
 
index c4c278d..2c702d3 100644 (file)
@@ -1,16 +1,18 @@
 /*
- * include/asm-ppc/tsi108.h
- *
  * common routine and memory layout for Tundra TSI108(Grendel) host bridge
  * memory controller.
  *
  * Author: Jacob Pan (jacob.pan@freescale.com)
  *        Alex Bounine (alexandreb@tundra.com)
- * 2004 (c) Freescale Semiconductor Inc.  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.
+ *
+ * Copyright 2004-2006 Freescale Semiconductor, Inc.
+ *
+ * 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 __PPC_KERNEL_TSI108_H
 #define __PPC_KERNEL_TSI108_H
 
diff --git a/include/asm-powerpc/tsi108_irq.h b/include/asm-powerpc/tsi108_irq.h
new file mode 100644 (file)
index 0000000..3e4d04e
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+ * (C) Copyright 2005 Tundra Semiconductor Corp.
+ * Alex Bounine, <alexandreb at tundra.com).
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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
+ */
+
+/*
+ * definitions for interrupt controller initialization and external interrupt
+ * demultiplexing on TSI108EMU/SVB boards.
+ */
+
+#ifndef _ASM_PPC_TSI108_IRQ_H
+#define _ASM_PPC_TSI108_IRQ_H
+
+/*
+ * Tsi108 interrupts
+ */
+#ifndef TSI108_IRQ_REG_BASE
+#define TSI108_IRQ_REG_BASE            0
+#endif
+
+#define TSI108_IRQ(x)          (TSI108_IRQ_REG_BASE + (x))
+
+#define TSI108_MAX_VECTORS     (36 + 4)        /* 36 sources + PCI INT demux */
+#define MAX_TASK_PRIO  0xF
+
+#define TSI108_IRQ_SPURIOUS    (TSI108_MAX_VECTORS)
+
+#define DEFAULT_PRIO_LVL       10      /* initial priority level */
+
+/* Interrupt vectors assignment to external and internal
+ * sources of requests. */
+
+/* EXTERNAL INTERRUPT SOURCES */
+
+#define IRQ_TSI108_EXT_INT0    TSI108_IRQ(0)   /* External Source at INT[0] */
+#define IRQ_TSI108_EXT_INT1    TSI108_IRQ(1)   /* External Source at INT[1] */
+#define IRQ_TSI108_EXT_INT2    TSI108_IRQ(2)   /* External Source at INT[2] */
+#define IRQ_TSI108_EXT_INT3    TSI108_IRQ(3)   /* External Source at INT[3] */
+
+/* INTERNAL INTERRUPT SOURCES */
+
+#define IRQ_TSI108_RESERVED0   TSI108_IRQ(4)   /* Reserved IRQ */
+#define IRQ_TSI108_RESERVED1   TSI108_IRQ(5)   /* Reserved IRQ */
+#define IRQ_TSI108_RESERVED2   TSI108_IRQ(6)   /* Reserved IRQ */
+#define IRQ_TSI108_RESERVED3   TSI108_IRQ(7)   /* Reserved IRQ */
+#define IRQ_TSI108_DMA0                TSI108_IRQ(8)   /* DMA0 */
+#define IRQ_TSI108_DMA1                TSI108_IRQ(9)   /* DMA1 */
+#define IRQ_TSI108_DMA2                TSI108_IRQ(10)  /* DMA2 */
+#define IRQ_TSI108_DMA3                TSI108_IRQ(11)  /* DMA3 */
+#define IRQ_TSI108_UART0       TSI108_IRQ(12)  /* UART0 */
+#define IRQ_TSI108_UART1       TSI108_IRQ(13)  /* UART1 */
+#define IRQ_TSI108_I2C         TSI108_IRQ(14)  /* I2C */
+#define IRQ_TSI108_GPIO                TSI108_IRQ(15)  /* GPIO */
+#define IRQ_TSI108_GIGE0       TSI108_IRQ(16)  /* GIGE0 */
+#define IRQ_TSI108_GIGE1       TSI108_IRQ(17)  /* GIGE1 */
+#define IRQ_TSI108_RESERVED4   TSI108_IRQ(18)  /* Reserved IRQ */
+#define IRQ_TSI108_HLP         TSI108_IRQ(19)  /* HLP */
+#define IRQ_TSI108_SDRAM       TSI108_IRQ(20)  /* SDC */
+#define IRQ_TSI108_PROC_IF     TSI108_IRQ(21)  /* Processor IF */
+#define IRQ_TSI108_RESERVED5   TSI108_IRQ(22)  /* Reserved IRQ */
+#define IRQ_TSI108_PCI         TSI108_IRQ(23)  /* PCI/X block */
+
+#define IRQ_TSI108_MBOX0       TSI108_IRQ(24)  /* Mailbox 0 register */
+#define IRQ_TSI108_MBOX1       TSI108_IRQ(25)  /* Mailbox 1 register */
+#define IRQ_TSI108_MBOX2       TSI108_IRQ(26)  /* Mailbox 2 register */
+#define IRQ_TSI108_MBOX3       TSI108_IRQ(27)  /* Mailbox 3 register */
+
+#define IRQ_TSI108_DBELL0      TSI108_IRQ(28)  /* Doorbell 0 */
+#define IRQ_TSI108_DBELL1      TSI108_IRQ(29)  /* Doorbell 1 */
+#define IRQ_TSI108_DBELL2      TSI108_IRQ(30)  /* Doorbell 2 */
+#define IRQ_TSI108_DBELL3      TSI108_IRQ(31)  /* Doorbell 3 */
+
+#define IRQ_TSI108_TIMER0      TSI108_IRQ(32)  /* Global Timer 0 */
+#define IRQ_TSI108_TIMER1      TSI108_IRQ(33)  /* Global Timer 1 */
+#define IRQ_TSI108_TIMER2      TSI108_IRQ(34)  /* Global Timer 2 */
+#define IRQ_TSI108_TIMER3      TSI108_IRQ(35)  /* Global Timer 3 */
+
+/*
+ * PCI bus INTA# - INTD# lines demultiplexor
+ */
+#define IRQ_PCI_INTAD_BASE     TSI108_IRQ(36)
+#define IRQ_PCI_INTA           (IRQ_PCI_INTAD_BASE + 0)
+#define IRQ_PCI_INTB           (IRQ_PCI_INTAD_BASE + 1)
+#define IRQ_PCI_INTC           (IRQ_PCI_INTAD_BASE + 2)
+#define IRQ_PCI_INTD           (IRQ_PCI_INTAD_BASE + 3)
+#define NUM_PCI_IRQS           (4)
+
+/* number of entries in vector dispatch table */
+#define IRQ_TSI108_TAB_SIZE    (TSI108_MAX_VECTORS + 1)
+
+/* Mapping of MPIC outputs to processors' interrupt pins */
+
+#define IDIR_INT_OUT0          0x1
+#define IDIR_INT_OUT1          0x2
+#define IDIR_INT_OUT2          0x4
+#define IDIR_INT_OUT3          0x8
+
+/*---------------------------------------------------------------
+ * IRQ line configuration parameters */
+
+/* Interrupt delivery modes */
+typedef enum {
+       TSI108_IRQ_DIRECTED,
+       TSI108_IRQ_DISTRIBUTED,
+} TSI108_IRQ_MODE;
+#endif                         /*  _ASM_PPC_TSI108_IRQ_H */
index 1ba19eb..ebfe395 100644 (file)
@@ -234,7 +234,7 @@ static inline pte_t pfn_pte(unsigned long pfn, pgprot_t prot)
        sz_bits = 0UL;
        if (_PAGE_SZBITS_4U != 0UL || _PAGE_SZBITS_4V != 0UL) {
                __asm__ __volatile__(
-               "\n661: sethi           %uhi(%1), %0\n"
+               "\n661: sethi           %%uhi(%1), %0\n"
                "       sllx            %0, 32, %0\n"
                "       .section        .sun4v_2insn_patch, \"ax\"\n"
                "       .word           661b\n"
index 88d5961..8e2042b 100644 (file)
@@ -59,27 +59,6 @@ static inline int task_nice_ioprio(struct task_struct *task)
 /*
  * For inheritance, return the highest of the two given priorities
  */
-static inline int ioprio_best(unsigned short aprio, unsigned short bprio)
-{
-       unsigned short aclass = IOPRIO_PRIO_CLASS(aprio);
-       unsigned short bclass = IOPRIO_PRIO_CLASS(bprio);
-
-       if (!ioprio_valid(aprio))
-               return bprio;
-       if (!ioprio_valid(bprio))
-               return aprio;
-
-       if (aclass == IOPRIO_CLASS_NONE)
-               aclass = IOPRIO_CLASS_BE;
-       if (bclass == IOPRIO_CLASS_NONE)
-               bclass = IOPRIO_CLASS_BE;
-
-       if (aclass == bclass)
-               return min(aprio, bprio);
-       if (aclass > bclass)
-               return bprio;
-       else
-               return aprio;
-}
+extern int ioprio_best(unsigned short aprio, unsigned short bprio);
 
 #endif
index a9663b4..92eae0e 100644 (file)
@@ -404,19 +404,6 @@ static inline int sctp_list_single_entry(struct list_head *head)
        return ((head->next != head) && (head->next == head->prev));
 }
 
-/* Calculate the size (in bytes) occupied by the data of an iovec.  */
-static inline size_t get_user_iov_size(struct iovec *iov, int iovlen)
-{
-       size_t retval = 0;
-
-       for (; iovlen > 0; --iovlen) {
-               retval += iov->iov_len;
-               iov++;
-       }
-
-       return retval;
-}
-
 /* Generate a random jitter in the range of -50% ~ +50% of input RTO. */
 static inline __s32 sctp_jitter(__u32 rto)
 {
index 1eac3d0..de313de 100644 (file)
@@ -221,8 +221,7 @@ struct sctp_chunk *sctp_make_abort_no_data(const struct sctp_association *,
                                      const struct sctp_chunk *,
                                      __u32 tsn);
 struct sctp_chunk *sctp_make_abort_user(const struct sctp_association *,
-                                  const struct sctp_chunk *,
-                                  const struct msghdr *);
+                                       const struct msghdr *, size_t msg_len);
 struct sctp_chunk *sctp_make_abort_violation(const struct sctp_association *,
                                   const struct sctp_chunk *,
                                   const __u8 *,
index 0110e44..d90822c 100644 (file)
@@ -111,15 +111,14 @@ static int subpattern(u8 *pattern, int i, int j, int g)
        return ret;
 }
 
-static void compute_prefix_tbl(struct ts_bm *bm, const u8 *pattern,
-                              unsigned int len)
+static void compute_prefix_tbl(struct ts_bm *bm)
 {
        int i, j, g;
 
        for (i = 0; i < ASIZE; i++)
-               bm->bad_shift[i] = len;
-       for (i = 0; i < len - 1; i++)
-               bm->bad_shift[pattern[i]] = len - 1 - i;
+               bm->bad_shift[i] = bm->patlen;
+       for (i = 0; i < bm->patlen - 1; i++)
+               bm->bad_shift[bm->pattern[i]] = bm->patlen - 1 - i;
 
        /* Compute the good shift array, used to match reocurrences 
         * of a subpattern */
@@ -150,8 +149,8 @@ static struct ts_config *bm_init(const void *pattern, unsigned int len,
        bm = ts_config_priv(conf);
        bm->patlen = len;
        bm->pattern = (u8 *) bm->good_shift + prefix_tbl_len;
-       compute_prefix_tbl(bm, pattern, len);
        memcpy(bm->pattern, pattern, len);
+       compute_prefix_tbl(bm);
 
        return conf;
 }
index df4854c..8d1d7a6 100644 (file)
@@ -236,7 +236,7 @@ unsigned int arpt_do_table(struct sk_buff **pskb,
        struct arpt_entry *e, *back;
        const char *indev, *outdev;
        void *table_base;
-       struct xt_table_info *private = table->private;
+       struct xt_table_info *private;
 
        /* ARP header, plus 2 device addresses, plus 2 IP addresses.  */
        if (!pskb_may_pull((*pskb), (sizeof(struct arphdr) +
@@ -248,6 +248,7 @@ unsigned int arpt_do_table(struct sk_buff **pskb,
        outdev = out ? out->name : nulldevname;
 
        read_lock_bh(&table->lock);
+       private = table->private;
        table_base = (void *)private->entries[smp_processor_id()];
        e = get_entry(table_base, private->hook_entry[hook]);
        back = get_entry(table_base, private->underflow[hook]);
index 507adef..b4f3ffe 100644 (file)
@@ -201,6 +201,7 @@ void tcp_select_initial_window(int __space, __u32 mss,
                 * See RFC1323 for an explanation of the limit to 14 
                 */
                space = max_t(u32, sysctl_tcp_rmem[2], sysctl_rmem_max);
+               space = min_t(u32, space, *window_clamp);
                while (space > 65535 && (*rcv_wscale) < 14) {
                        space >>= 1;
                        (*rcv_wscale)++;
index 4f11f58..17b5092 100644 (file)
@@ -806,38 +806,26 @@ no_mem:
 
 /* Helper to create ABORT with a SCTP_ERROR_USER_ABORT error.  */
 struct sctp_chunk *sctp_make_abort_user(const struct sctp_association *asoc,
-                                  const struct sctp_chunk *chunk,
-                                  const struct msghdr *msg)
+                                       const struct msghdr *msg,
+                                       size_t paylen)
 {
        struct sctp_chunk *retval;
-       void *payload = NULL, *payoff;
-       size_t paylen = 0;
-       struct iovec *iov = NULL;
-       int iovlen = 0;
-
-       if (msg) {
-               iov = msg->msg_iov;
-               iovlen = msg->msg_iovlen;
-               paylen = get_user_iov_size(iov, iovlen);
-       }
+       void *payload = NULL;
+       int err;
 
-       retval = sctp_make_abort(asoc, chunk, sizeof(sctp_errhdr_t) + paylen);
+       retval = sctp_make_abort(asoc, NULL, sizeof(sctp_errhdr_t) + paylen);
        if (!retval)
                goto err_chunk;
 
        if (paylen) {
                /* Put the msg_iov together into payload.  */
-               payload = kmalloc(paylen, GFP_ATOMIC);
+               payload = kmalloc(paylen, GFP_KERNEL);
                if (!payload)
                        goto err_payload;
-               payoff = payload;
 
-               for (; iovlen > 0; --iovlen) {
-                       if (copy_from_user(payoff, iov->iov_base,iov->iov_len))
-                               goto err_copy;
-                       payoff += iov->iov_len;
-                       iov++;
-               }
+               err = memcpy_fromiovec(payload, msg->msg_iov, paylen);
+               if (err < 0)
+                       goto err_copy;
        }
 
        sctp_init_cause(retval, SCTP_ERROR_USER_ABORT, payload, paylen);
index ead3f1b..5b5ae79 100644 (file)
@@ -4031,18 +4031,12 @@ sctp_disposition_t sctp_sf_do_9_1_prm_abort(
         * from its upper layer, but retransmits data to the far end
         * if necessary to fill gaps.
         */
-       struct msghdr *msg = arg;
-       struct sctp_chunk *abort;
+       struct sctp_chunk *abort = arg;
        sctp_disposition_t retval;
 
        retval = SCTP_DISPOSITION_CONSUME;
 
-       /* Generate ABORT chunk to send the peer.  */
-       abort = sctp_make_abort_user(asoc, NULL, msg);
-       if (!abort)
-               retval = SCTP_DISPOSITION_NOMEM;
-       else
-               sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort));
+       sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort));
 
        /* Even if we can't send the ABORT due to low memory delete the
         * TCB.  This is a departure from our typical NOMEM handling.
@@ -4166,8 +4160,7 @@ sctp_disposition_t sctp_sf_cookie_wait_prm_abort(
        void *arg,
        sctp_cmd_seq_t *commands)
 {
-       struct msghdr *msg = arg;
-       struct sctp_chunk *abort;
+       struct sctp_chunk *abort = arg;
        sctp_disposition_t retval;
 
        /* Stop T1-init timer */
@@ -4175,12 +4168,7 @@ sctp_disposition_t sctp_sf_cookie_wait_prm_abort(
                        SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT));
        retval = SCTP_DISPOSITION_CONSUME;
 
-       /* Generate ABORT chunk to send the peer */
-       abort = sctp_make_abort_user(asoc, NULL, msg);
-       if (!abort)
-               retval = SCTP_DISPOSITION_NOMEM;
-       else
-               sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort));
+       sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort));
 
        sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
                        SCTP_STATE(SCTP_STATE_CLOSED));
index 54722e6..fde3f55 100644 (file)
@@ -1520,8 +1520,16 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
                        goto out_unlock;
                }
                if (sinfo_flags & SCTP_ABORT) {
+                       struct sctp_chunk *chunk;
+
+                       chunk = sctp_make_abort_user(asoc, msg, msg_len);
+                       if (!chunk) {
+                               err = -ENOMEM;
+                               goto out_unlock;
+                       }
+
                        SCTP_DEBUG_PRINTK("Aborting association: %p\n", asoc);
-                       sctp_primitive_ABORT(asoc, msg);
+                       sctp_primitive_ABORT(asoc, chunk);
                        err = 0;
                        goto out_unlock;
                }