]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 18 Mar 2011 13:31:43 +0000 (06:31 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 18 Mar 2011 13:31:43 +0000 (06:31 -0700)
* 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc: (62 commits)
  powerpc/85xx: Fix signedness bug in cache-sram
  powerpc/fsl: 85xx: document cache sram bindings
  powerpc/fsl: define binding for fsl mpic interrupt controllers
  powerpc/fsl_msi: Handle msi-available-ranges better
  drivers/serial/ucc_uart.c: Add of_node_put to avoid memory leak
  powerpc/85xx: Fix SPE float to integer conversion failure
  powerpc/85xx: Update sata controller compatible for p1022ds board
  ATA: Add FSL sata v2 controller support
  powerpc/mpc8xxx_gpio: simplify searching for 'fsl, qoriq-gpio' compatiable
  powerpc/8xx: remove obsolete mgsuvd board
  powerpc/82xx: rename and update mgcoge board support
  powerpc/83xx: rename and update kmeter1
  powerpc/85xx: Workaroudn e500 CPU erratum A005
  powerpc/fsl_pci: Add support for FSL PCIe controllers v2.x
  powerpc/85xx: Fix writing to spin table 'cpu-release-addr' on ppc64e
  powerpc/pseries: Disable MSI using new interface if possible
  powerpc: Enable GENERIC_HARDIRQS_NO_DEPRECATED.
  powerpc: core irq_data conversion.
  powerpc: sysdev/xilinx_intc irq_data conversion.
  powerpc: sysdev/uic irq_data conversion.
  ...

Fix up conflicts in arch/powerpc/sysdev/fsl_msi.c (due to getting rid of
of_platform_driver in arch/powerpc)

1  2 
Documentation/kernel-parameters.txt
arch/powerpc/kernel/machine_kexec.c
arch/powerpc/platforms/52xx/mpc52xx_gpt.c
arch/powerpc/platforms/cell/axon_msi.c
arch/powerpc/sysdev/fsl_85xx_l2ctlr.c
arch/powerpc/sysdev/fsl_msi.c
drivers/ata/sata_fsl.c
drivers/tty/serial/ucc_uart.c

index 534dbaf9d618f7a9e268bc00652a3dc32853de65,b245ce61ecb8a46065e18c9a65dd77ed346cfb6f..d18a9e12152a701bb2729afdb65288ad6da2fccf
@@@ -626,6 -626,10 +626,10 @@@ bytes respectively. Such letter suffixe
        disable=        [IPV6]
                        See Documentation/networking/ipv6.txt.
  
+       disable_ddw     [PPC/PSERIES]
+                       Disable Dynamic DMA Window support. Use this if
+                       to workaround buggy firmware.
        disable_ipv6=   [IPV6]
                        See Documentation/networking/ipv6.txt.
  
                        of returning the full 64-bit number.
                        The default is to return 64-bit inode numbers.
  
 +      nfs.nfs4_disable_idmapping=
 +                      [NFSv4] When set, this option disables the NFSv4
 +                      idmapper on the client, but only if the mount
 +                      is using the 'sec=sys' security flavour. This may
 +                      make migration from legacy NFSv2/v3 systems easier
 +                      provided that the server has the appropriate support.
 +                      The default is to always enable NFSv4 idmapping.
 +
        nmi_debug=      [KNL,AVR32,SH] Specify one or more actions to take
                        when a NMI is triggered.
                        Format: [state][,regs][,debounce][,die]
                        <deci-seconds>: poll all this frequency
                        0: no polling (default)
  
 +      threadirqs      [KNL]
 +                      Force threading of all interrupt handlers except those
 +                      marked explicitely IRQF_NO_THREAD.
 +
        topology=       [S390]
                        Format: {off | on}
                        Specify if the kernel should make use of the cpu
index a5f8672eeff37d593c219ac7ac68a6296587b7f4,976de37fe5b304b63baa5ddd9998ae761a960072..bd1e1ff17b2d585ec60a4fcdec0d6b8a08e43a52
@@@ -26,20 -26,23 +26,23 @@@ void machine_kexec_mask_interrupts(void
  
        for_each_irq(i) {
                struct irq_desc *desc = irq_to_desc(i);
+               struct irq_chip *chip;
  
-               if (!desc || !desc->chip)
+               if (!desc)
                        continue;
  
-               if (desc->chip->eoi &&
-                   desc->status & IRQ_INPROGRESS)
-                       desc->chip->eoi(i);
+               chip = get_irq_desc_chip(desc);
+               if (!chip)
+                       continue;
+               if (chip->irq_eoi && desc->status & IRQ_INPROGRESS)
+                       chip->irq_eoi(&desc->irq_data);
  
-               if (desc->chip->mask)
-                       desc->chip->mask(i);
+               if (chip->irq_mask)
+                       chip->irq_mask(&desc->irq_data);
  
-               if (desc->chip->disable &&
-                   !(desc->status & IRQ_DISABLED))
-                       desc->chip->disable(i);
+               if (chip->irq_disable && !(desc->status & IRQ_DISABLED))
+                       chip->irq_disable(&desc->irq_data);
        }
  }
  
@@@ -87,10 -90,7 +90,10 @@@ void machine_kexec(struct kimage *image
  
        save_ftrace_enabled = __ftrace_enabled_save();
  
 -      default_machine_kexec(image);
 +      if (ppc_md.machine_kexec)
 +              ppc_md.machine_kexec(image);
 +      else
 +              default_machine_kexec(image);
  
        __ftrace_enabled_restore(save_ftrace_enabled);
  
index 859abf1c6d4bf8b32b90da11021075798ce2fc88,c9290d8289d508a45ee21faeadb97f395ef380bd..6da44f0f2934a8f3e4fd252768ba8a0bab8326e8
@@@ -135,9 -135,9 +135,9 @@@ DEFINE_MUTEX(mpc52xx_gpt_list_mutex)
   * Cascaded interrupt controller hooks
   */
  
- static void mpc52xx_gpt_irq_unmask(unsigned int virq)
+ static void mpc52xx_gpt_irq_unmask(struct irq_data *d)
  {
-       struct mpc52xx_gpt_priv *gpt = get_irq_chip_data(virq);
+       struct mpc52xx_gpt_priv *gpt = irq_data_get_irq_chip_data(d);
        unsigned long flags;
  
        spin_lock_irqsave(&gpt->lock, flags);
        spin_unlock_irqrestore(&gpt->lock, flags);
  }
  
- static void mpc52xx_gpt_irq_mask(unsigned int virq)
+ static void mpc52xx_gpt_irq_mask(struct irq_data *d)
  {
-       struct mpc52xx_gpt_priv *gpt = get_irq_chip_data(virq);
+       struct mpc52xx_gpt_priv *gpt = irq_data_get_irq_chip_data(d);
        unsigned long flags;
  
        spin_lock_irqsave(&gpt->lock, flags);
        spin_unlock_irqrestore(&gpt->lock, flags);
  }
  
- static void mpc52xx_gpt_irq_ack(unsigned int virq)
+ static void mpc52xx_gpt_irq_ack(struct irq_data *d)
  {
-       struct mpc52xx_gpt_priv *gpt = get_irq_chip_data(virq);
+       struct mpc52xx_gpt_priv *gpt = irq_data_get_irq_chip_data(d);
  
        out_be32(&gpt->regs->status, MPC52xx_GPT_STATUS_IRQMASK);
  }
  
- static int mpc52xx_gpt_irq_set_type(unsigned int virq, unsigned int flow_type)
+ static int mpc52xx_gpt_irq_set_type(struct irq_data *d, unsigned int flow_type)
  {
-       struct mpc52xx_gpt_priv *gpt = get_irq_chip_data(virq);
+       struct mpc52xx_gpt_priv *gpt = irq_data_get_irq_chip_data(d);
        unsigned long flags;
        u32 reg;
  
-       dev_dbg(gpt->dev, "%s: virq=%i type=%x\n", __func__, virq, flow_type);
+       dev_dbg(gpt->dev, "%s: virq=%i type=%x\n", __func__, d->irq, flow_type);
  
        spin_lock_irqsave(&gpt->lock, flags);
        reg = in_be32(&gpt->regs->mode) & ~MPC52xx_GPT_MODE_ICT_MASK;
  
  static struct irq_chip mpc52xx_gpt_irq_chip = {
        .name = "MPC52xx GPT",
-       .unmask = mpc52xx_gpt_irq_unmask,
-       .mask = mpc52xx_gpt_irq_mask,
-       .ack = mpc52xx_gpt_irq_ack,
-       .set_type = mpc52xx_gpt_irq_set_type,
+       .irq_unmask = mpc52xx_gpt_irq_unmask,
+       .irq_mask = mpc52xx_gpt_irq_mask,
+       .irq_ack = mpc52xx_gpt_irq_ack,
+       .irq_set_type = mpc52xx_gpt_irq_set_type,
  };
  
  void mpc52xx_gpt_irq_cascade(unsigned int virq, struct irq_desc *desc)
@@@ -721,7 -721,8 +721,7 @@@ static inline int mpc52xx_gpt_wdt_setup
  /* ---------------------------------------------------------------------
   * of_platform bus binding code
   */
 -static int __devinit mpc52xx_gpt_probe(struct platform_device *ofdev,
 -                                     const struct of_device_id *match)
 +static int __devinit mpc52xx_gpt_probe(struct platform_device *ofdev)
  {
        struct mpc52xx_gpt_priv *gpt;
  
@@@ -780,7 -781,7 +780,7 @@@ static const struct of_device_id mpc52x
        {}
  };
  
 -static struct of_platform_driver mpc52xx_gpt_driver = {
 +static struct platform_driver mpc52xx_gpt_driver = {
        .driver = {
                .name = "mpc52xx-gpt",
                .owner = THIS_MODULE,
  
  static int __init mpc52xx_gpt_init(void)
  {
 -      if (of_register_platform_driver(&mpc52xx_gpt_driver))
 -              pr_err("error registering MPC52xx GPT driver\n");
 -
 -      return 0;
 +      return platform_driver_register(&mpc52xx_gpt_driver);
  }
  
  /* Make sure GPIOs and IRQs get set up before anyone tries to use them */
index c35099af340e868f9ba7416a7e57b082bcd08fe3,c07930f16e6cf9d8ceb8031a77424339c4b1676f..c48b66a67e42ab7e1144d9f6c2ee90d3b617dbff
@@@ -93,6 -93,7 +93,7 @@@ static void msic_dcr_write(struct axon_
  
  static void axon_msi_cascade(unsigned int irq, struct irq_desc *desc)
  {
+       struct irq_chip *chip = get_irq_desc_chip(desc);
        struct axon_msic *msic = get_irq_data(irq);
        u32 write_offset, msi;
        int idx;
                msic->read_offset &= MSIC_FIFO_SIZE_MASK;
        }
  
-       desc->chip->eoi(irq);
+       chip->irq_eoi(&desc->irq_data);
  }
  
  static struct axon_msic *find_msi_translator(struct pci_dev *dev)
@@@ -328,7 -329,7 +329,7 @@@ static struct irq_host_ops msic_host_op
        .map    = msic_host_map,
  };
  
 -static int axon_msi_shutdown(struct platform_device *device)
 +static void axon_msi_shutdown(struct platform_device *device)
  {
        struct axon_msic *msic = dev_get_drvdata(&device->dev);
        u32 tmp;
        tmp  = dcr_read(msic->dcr_host, MSIC_CTRL_REG);
        tmp &= ~MSIC_CTRL_ENABLE & ~MSIC_CTRL_IRQ_ENABLE;
        msic_dcr_write(msic, MSIC_CTRL_REG, tmp);
 -
 -      return 0;
  }
  
 -static int axon_msi_probe(struct platform_device *device,
 -                        const struct of_device_id *device_id)
 +static int axon_msi_probe(struct platform_device *device)
  {
        struct device_node *dn = device->dev.of_node;
        struct axon_msic *msic;
@@@ -443,7 -447,7 +444,7 @@@ static const struct of_device_id axon_m
        {}
  };
  
 -static struct of_platform_driver axon_msi_driver = {
 +static struct platform_driver axon_msi_driver = {
        .probe          = axon_msi_probe,
        .shutdown       = axon_msi_shutdown,
        .driver = {
  
  static int __init axon_msi_init(void)
  {
 -      return of_register_platform_driver(&axon_msi_driver);
 +      return platform_driver_register(&axon_msi_driver);
  }
  subsys_initcall(axon_msi_init);
  
index 2b9f0c925326d115b25f879ce9087b2893c5527b,23b85ac9fc562e6df3b853ac66b3f343b9dd2e86..5f88797dce73cecc191312a81b27b7f97b67043e
@@@ -71,7 -71,8 +71,7 @@@ static int __init get_offset_from_cmdli
  __setup("cache-sram-size=", get_size_from_cmdline);
  __setup("cache-sram-offset=", get_offset_from_cmdline);
  
 -static int __devinit mpc85xx_l2ctlr_of_probe(struct platform_device *dev,
 -                                        const struct of_device_id *match)
 +static int __devinit mpc85xx_l2ctlr_of_probe(struct platform_device *dev)
  {
        long rval;
        unsigned int rem;
        l2cache_size = *prop;
  
        sram_params.sram_size  = get_cache_sram_size();
-       if (sram_params.sram_size <= 0) {
+       if ((int)sram_params.sram_size <= 0) {
                dev_err(&dev->dev,
                        "Entire L2 as cache, Aborting Cache-SRAM stuff\n");
                return -EINVAL;
        }
  
        sram_params.sram_offset  = get_cache_sram_offset();
-       if (sram_params.sram_offset <= 0) {
+       if ((int64_t)sram_params.sram_offset <= 0) {
                dev_err(&dev->dev,
                        "Entire L2 as cache, provide a valid sram offset\n");
                return -EINVAL;
@@@ -203,7 -204,7 +203,7 @@@ static struct of_device_id mpc85xx_l2ct
        {},
  };
  
 -static struct of_platform_driver mpc85xx_l2ctlr_of_platform_driver = {
 +static struct platform_driver mpc85xx_l2ctlr_of_platform_driver = {
        .driver = {
                .name           = "fsl-l2ctlr",
                .owner          = THIS_MODULE,
  
  static __init int mpc85xx_l2ctlr_of_init(void)
  {
 -      return of_register_platform_driver(&mpc85xx_l2ctlr_of_platform_driver);
 +      return platform_driver_register(&mpc85xx_l2ctlr_of_platform_driver);
  }
  
  static void __exit mpc85xx_l2ctlr_of_exit(void)
  {
 -      of_unregister_platform_driver(&mpc85xx_l2ctlr_of_platform_driver);
 +      platform_driver_unregister(&mpc85xx_l2ctlr_of_platform_driver);
  }
  
  subsys_initcall(mpc85xx_l2ctlr_of_init);
index ee6a8a52ac716b0f6e74dae2e1e0963a1435817f,8d6b074bb3e9b45521799db21dca76611a49b620..58e09b2833f2ce8111673de016a32e44e7cf8063
@@@ -1,5 -1,5 +1,5 @@@
  /*
-  * Copyright (C) 2007-2010 Freescale Semiconductor, Inc.
+  * Copyright (C) 2007-2011 Freescale Semiconductor, Inc.
   *
   * Author: Tony Li <tony.li@freescale.com>
   *       Jason Jin <Jason.jin@freescale.com>
@@@ -47,14 -47,14 +47,14 @@@ static inline u32 fsl_msi_read(u32 __io
   * We do not need this actually. The MSIR register has been read once
   * in the cascade interrupt. So, this MSI interrupt has been acked
  */
- static void fsl_msi_end_irq(unsigned int virq)
+ static void fsl_msi_end_irq(struct irq_data *d)
  {
  }
  
  static struct irq_chip fsl_msi_chip = {
        .irq_mask       = mask_msi_irq,
        .irq_unmask     = unmask_msi_irq,
-       .ack            = fsl_msi_end_irq,
+       .irq_ack        = fsl_msi_end_irq,
        .name           = "FSL-MSI",
  };
  
@@@ -183,6 -183,7 +183,7 @@@ out_free
  
  static void fsl_msi_cascade(unsigned int irq, struct irq_desc *desc)
  {
+       struct irq_chip *chip = get_irq_desc_chip(desc);
        unsigned int cascade_irq;
        struct fsl_msi *msi_data;
        int msir_index = -1;
  
        raw_spin_lock(&desc->lock);
        if ((msi_data->feature &  FSL_PIC_IP_MASK) == FSL_PIC_IP_IPIC) {
-               if (desc->chip->mask_ack)
-                       desc->chip->mask_ack(irq);
+               if (chip->irq_mask_ack)
+                       chip->irq_mask_ack(&desc->irq_data);
                else {
-                       desc->chip->mask(irq);
-                       desc->chip->ack(irq);
+                       chip->irq_mask(&desc->irq_data);
+                       chip->irq_ack(&desc->irq_data);
                }
        }
  
  
        switch (msi_data->feature & FSL_PIC_IP_MASK) {
        case FSL_PIC_IP_MPIC:
-               desc->chip->eoi(irq);
+               chip->irq_eoi(&desc->irq_data);
                break;
        case FSL_PIC_IP_IPIC:
-               if (!(desc->status & IRQ_DISABLED) && desc->chip->unmask)
-                       desc->chip->unmask(irq);
+               if (!(desc->status & IRQ_DISABLED) && chip->irq_unmask)
+                       chip->irq_unmask(&desc->irq_data);
                break;
        }
  unlock:
@@@ -273,23 -274,48 +274,51 @@@ static int fsl_of_msi_remove(struct pla
        return 0;
  }
  
 -static int __devinit fsl_of_msi_probe(struct platform_device *dev,
 -                              const struct of_device_id *match)
+ static int __devinit fsl_msi_setup_hwirq(struct fsl_msi *msi,
+                                        struct platform_device *dev,
+                                        int offset, int irq_index)
+ {
+       struct fsl_msi_cascade_data *cascade_data = NULL;
+       int virt_msir;
+       virt_msir = irq_of_parse_and_map(dev->dev.of_node, irq_index);
+       if (virt_msir == NO_IRQ) {
+               dev_err(&dev->dev, "%s: Cannot translate IRQ index %d\n",
+                       __func__, irq_index);
+               return 0;
+       }
+       cascade_data = kzalloc(sizeof(struct fsl_msi_cascade_data), GFP_KERNEL);
+       if (!cascade_data) {
+               dev_err(&dev->dev, "No memory for MSI cascade data\n");
+               return -ENOMEM;
+       }
+       msi->msi_virqs[irq_index] = virt_msir;
+       cascade_data->index = offset + irq_index;
+       cascade_data->msi_data = msi;
+       set_irq_data(virt_msir, cascade_data);
+       set_irq_chained_handler(virt_msir, fsl_msi_cascade);
+       return 0;
+ }
 +static int __devinit fsl_of_msi_probe(struct platform_device *dev)
  {
        struct fsl_msi *msi;
        struct resource res;
-       int err, i, count;
+       int err, i, j, irq_index, count;
        int rc;
-       int virt_msir;
        const u32 *p;
 -      struct fsl_msi_feature *features = match->data;
 +      struct fsl_msi_feature *features;
-       struct fsl_msi_cascade_data *cascade_data = NULL;
        int len;
        u32 offset;
+       static const u32 all_avail[] = { 0, NR_MSI_IRQS };
  
 +      if (!dev->dev.of_match)
 +              return -EINVAL;
 +      features = dev->dev.of_match->data;
 +
        printk(KERN_DEBUG "Setting up Freescale MSI support\n");
  
        msi = kzalloc(sizeof(struct fsl_msi), GFP_KERNEL);
                goto error_out;
        }
  
-       p = of_get_property(dev->dev.of_node, "interrupts", &count);
-       if (!p) {
-               dev_err(&dev->dev, "no interrupts property found on %s\n",
-                               dev->dev.of_node->full_name);
-               err = -ENODEV;
-               goto error_out;
-       }
-       if (count % 8 != 0) {
-               dev_err(&dev->dev, "Malformed interrupts property on %s\n",
-                               dev->dev.of_node->full_name);
+       p = of_get_property(dev->dev.of_node, "msi-available-ranges", &len);
+       if (p && len % (2 * sizeof(u32)) != 0) {
+               dev_err(&dev->dev, "%s: Malformed msi-available-ranges property\n",
+                       __func__);
                err = -EINVAL;
                goto error_out;
        }
-       offset = 0;
-       p = of_get_property(dev->dev.of_node, "msi-available-ranges", &len);
-       if (p)
-               offset = *p / IRQS_PER_MSI_REG;
-       count /= sizeof(u32);
-       for (i = 0; i < min(count / 2, NR_MSI_REG); i++) {
-               virt_msir = irq_of_parse_and_map(dev->dev.of_node, i);
-               if (virt_msir != NO_IRQ) {
-                       cascade_data = kzalloc(
-                                       sizeof(struct fsl_msi_cascade_data),
-                                       GFP_KERNEL);
-                       if (!cascade_data) {
-                               dev_err(&dev->dev,
-                                       "No memory for MSI cascade data\n");
-                               err = -ENOMEM;
+       if (!p)
+               p = all_avail;
+       for (irq_index = 0, i = 0; i < len / (2 * sizeof(u32)); i++) {
+               if (p[i * 2] % IRQS_PER_MSI_REG ||
+                   p[i * 2 + 1] % IRQS_PER_MSI_REG) {
+                       printk(KERN_WARNING "%s: %s: msi available range of %u at %u is not IRQ-aligned\n",
+                              __func__, dev->dev.of_node->full_name,
+                              p[i * 2 + 1], p[i * 2]);
+                       err = -EINVAL;
+                       goto error_out;
+               }
+               offset = p[i * 2] / IRQS_PER_MSI_REG;
+               count = p[i * 2 + 1] / IRQS_PER_MSI_REG;
+               for (j = 0; j < count; j++, irq_index++) {
+                       err = fsl_msi_setup_hwirq(msi, dev, offset, irq_index);
+                       if (err)
                                goto error_out;
-                       }
-                       msi->msi_virqs[i] = virt_msir;
-                       cascade_data->index = i + offset;
-                       cascade_data->msi_data = msi;
-                       set_irq_data(virt_msir, (void *)cascade_data);
-                       set_irq_chained_handler(virt_msir, fsl_msi_cascade);
                }
        }
  
@@@ -414,7 -432,7 +435,7 @@@ static const struct of_device_id fsl_of
        {}
  };
  
 -static struct of_platform_driver fsl_of_msi_driver = {
 +static struct platform_driver fsl_of_msi_driver = {
        .driver = {
                .name = "fsl-msi",
                .owner = THIS_MODULE,
  
  static __init int fsl_of_msi_init(void)
  {
 -      return of_register_platform_driver(&fsl_of_msi_driver);
 +      return platform_driver_register(&fsl_of_msi_driver);
  }
  
  subsys_initcall(fsl_of_msi_init);
diff --combined drivers/ata/sata_fsl.c
index ef3ce26bb1f0217c3e6b7d55ae5b0f6426f526b4,01a5400bd7c533dc3f44f0dc4ce1da4804758a61..0f91e583892e19a4578501407d0b816584bac83e
@@@ -6,7 -6,7 +6,7 @@@
   * Author: Ashish Kalra <ashish.kalra@freescale.com>
   * Li Yang <leoli@freescale.com>
   *
-  * Copyright (c) 2006-2007 Freescale Semiconductor, Inc.
+  * Copyright (c) 2006-2007, 2011 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
@@@ -33,7 -33,8 +33,7 @@@ enum 
        SATA_FSL_MAX_PRD_USABLE = SATA_FSL_MAX_PRD - 1,
        SATA_FSL_MAX_PRD_DIRECT = 16,   /* Direct PRDT entries */
  
 -      SATA_FSL_HOST_FLAGS     = (ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
 -                              ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
 +      SATA_FSL_HOST_FLAGS     = (ATA_FLAG_SATA | ATA_FLAG_PIO_DMA |
                                ATA_FLAG_PMP | ATA_FLAG_NCQ | ATA_FLAG_AN),
  
        SATA_FSL_MAX_CMDS       = SATA_FSL_QUEUE_DEPTH,
@@@ -157,7 -158,8 +157,8 @@@ enum 
            IE_ON_SINGL_DEVICE_ERR | IE_ON_CMD_COMPLETE,
  
        EXT_INDIRECT_SEG_PRD_FLAG = (1 << 31),
-       DATA_SNOOP_ENABLE = (1 << 22),
+       DATA_SNOOP_ENABLE_V1 = (1 << 22),
+       DATA_SNOOP_ENABLE_V2 = (1 << 28),
  };
  
  /*
@@@ -185,11 -187,6 +186,11 @@@ enum 
        COMMANDSTAT = 0x20,
  };
  
 +/* TRANSCFG (transport-layer) configuration control */
 +enum {
 +      TRANSCFG_RX_WATER_MARK = (1 << 4),
 +};
 +
  /* PHY (link-layer) configuration control */
  enum {
        PHY_BIST_ENABLE = 0x01,
@@@ -260,6 -257,7 +261,7 @@@ struct sata_fsl_host_priv 
        void __iomem *ssr_base;
        void __iomem *csr_base;
        int irq;
+       int data_snoop;
  };
  
  static inline unsigned int sata_fsl_tag(unsigned int tag,
@@@ -312,7 -310,8 +314,8 @@@ static void sata_fsl_setup_cmd_hdr_entr
  }
  
  static unsigned int sata_fsl_fill_sg(struct ata_queued_cmd *qc, void *cmd_desc,
-                                    u32 *ttl, dma_addr_t cmd_desc_paddr)
+                                    u32 *ttl, dma_addr_t cmd_desc_paddr,
+                                    int data_snoop)
  {
        struct scatterlist *sg;
        unsigned int num_prde = 0;
  
                ttl_dwords += sg_len;
                prd->dba = cpu_to_le32(sg_addr);
-               prd->ddc_and_ext =
-                   cpu_to_le32(DATA_SNOOP_ENABLE | (sg_len & ~0x03));
+               prd->ddc_and_ext = cpu_to_le32(data_snoop | (sg_len & ~0x03));
  
                VPRINTK("sg_fill, ttl=%d, dba=0x%x, ddc=0x%x\n",
                        ttl_dwords, prd->dba, prd->ddc_and_ext);
                /* set indirect extension flag along with indirect ext. size */
                prd_ptr_to_indirect_ext->ddc_and_ext =
                    cpu_to_le32((EXT_INDIRECT_SEG_PRD_FLAG |
-                                DATA_SNOOP_ENABLE |
+                                data_snoop |
                                 (indirect_ext_segment_sz & ~0x03)));
        }
  
@@@ -421,7 -419,8 +423,8 @@@ static void sata_fsl_qc_prep(struct ata
  
        if (qc->flags & ATA_QCFLAG_DMAMAP)
                num_prde = sata_fsl_fill_sg(qc, (void *)cd,
-                                           &ttl_dwords, cd_paddr);
+                                           &ttl_dwords, cd_paddr,
+                                           host_priv->data_snoop);
  
        if (qc->tf.protocol == ATA_PROT_NCQ)
                desc_info |= FPDMA_QUEUED_CMD;
@@@ -1044,15 -1043,12 +1047,15 @@@ static void sata_fsl_error_intr(struct 
  
                /* find out the offending link and qc */
                if (ap->nr_pmp_links) {
 +                      unsigned int dev_num;
 +
                        dereg = ioread32(hcr_base + DE);
                        iowrite32(dereg, hcr_base + DE);
                        iowrite32(cereg, hcr_base + CE);
  
 -                      if (dereg < ap->nr_pmp_links) {
 -                              link = &ap->pmp_link[dereg];
 +                      dev_num = ffs(dereg) - 1;
 +                      if (dev_num < ap->nr_pmp_links && dereg != 0) {
 +                              link = &ap->pmp_link[dev_num];
                                ehi = &link->eh_info;
                                qc = ata_qc_from_tag(ap, link->active_tag);
                                /*
@@@ -1300,7 -1296,8 +1303,7 @@@ static const struct ata_port_info sata_
         },
  };
  
 -static int sata_fsl_probe(struct platform_device *ofdev,
 -                      const struct of_device_id *match)
 +static int sata_fsl_probe(struct platform_device *ofdev)
  {
        int retval = -ENXIO;
        void __iomem *hcr_base = NULL;
        struct sata_fsl_host_priv *host_priv = NULL;
        int irq;
        struct ata_host *host;
 +      u32 temp;
  
        struct ata_port_info pi = sata_fsl_port_info[0];
        const struct ata_port_info *ppi[] = { &pi, NULL };
        ssr_base = hcr_base + 0x100;
        csr_base = hcr_base + 0x140;
  
 +      if (!of_device_is_compatible(ofdev->dev.of_node, "fsl,mpc8315-sata")) {
 +              temp = ioread32(csr_base + TRANSCFG);
 +              temp = temp & 0xffffffe0;
 +              iowrite32(temp | TRANSCFG_RX_WATER_MARK, csr_base + TRANSCFG);
 +      }
 +
        DPRINTK("@reset i/o = 0x%x\n", ioread32(csr_base + TRANSCFG));
        DPRINTK("sizeof(cmd_desc) = %d\n", sizeof(struct command_desc));
        DPRINTK("sizeof(#define cmd_desc) = %d\n", SATA_FSL_CMD_DESC_SIZE);
        }
        host_priv->irq = irq;
  
+       if (of_device_is_compatible(ofdev->dev.of_node, "fsl,pq-sata-v2"))
+               host_priv->data_snoop = DATA_SNOOP_ENABLE_V2;
+       else
+               host_priv->data_snoop = DATA_SNOOP_ENABLE_V1;
        /* allocate host structure */
        host = ata_host_alloc_pinfo(&ofdev->dev, ppi, SATA_FSL_MAX_PORTS);
  
@@@ -1431,12 -1426,15 +1439,15 @@@ static struct of_device_id fsl_sata_mat
        {
                .compatible = "fsl,pq-sata",
        },
+       {
+               .compatible = "fsl,pq-sata-v2",
+       },
        {},
  };
  
  MODULE_DEVICE_TABLE(of, fsl_sata_match);
  
 -static struct of_platform_driver fsl_sata_driver = {
 +static struct platform_driver fsl_sata_driver = {
        .driver = {
                .name = "fsl-sata",
                .owner = THIS_MODULE,
  
  static int __init sata_fsl_init(void)
  {
 -      of_register_platform_driver(&fsl_sata_driver);
 +      platform_driver_register(&fsl_sata_driver);
        return 0;
  }
  
  static void __exit sata_fsl_exit(void)
  {
 -      of_unregister_platform_driver(&fsl_sata_driver);
 +      platform_driver_unregister(&fsl_sata_driver);
  }
  
  MODULE_LICENSE("GPL");
index ff51dae1df0c2bb8b27cce63379569dfd560e791,38a5ef0ae394422ce844c7215d9377441c7f28f0..c327218cad44c91ab680cf0dc46fcd4933cc8347
@@@ -1194,7 -1194,8 +1194,7 @@@ static void uart_firmware_cont(const st
        release_firmware(fw);
  }
  
 -static int ucc_uart_probe(struct platform_device *ofdev,
 -      const struct of_device_id *match)
 +static int ucc_uart_probe(struct platform_device *ofdev)
  {
        struct device_node *np = ofdev->dev.of_node;
        const unsigned int *iprop;      /* Integer OF properties */
        ret = of_address_to_resource(np, 0, &res);
        if (ret) {
                dev_err(&ofdev->dev, "missing 'reg' property in device tree\n");
-               kfree(qe_port);
-               return ret;
+               goto out_free;
        }
        if (!res.start) {
                dev_err(&ofdev->dev, "invalid 'reg' property in device tree\n");
-               kfree(qe_port);
-               return -EINVAL;
+               ret = -EINVAL;
+               goto out_free;
        }
        qe_port->port.mapbase = res.start;
  
        if (!iprop) {
                iprop = of_get_property(np, "device-id", NULL);
                if (!iprop) {
-                       kfree(qe_port);
                        dev_err(&ofdev->dev, "UCC is unspecified in "
                                "device tree\n");
-                       return -EINVAL;
+                       ret = -EINVAL;
+                       goto out_free;
                }
        }
  
        if ((*iprop < 1) || (*iprop > UCC_MAX_NUM)) {
                dev_err(&ofdev->dev, "no support for UCC%u\n", *iprop);
-               kfree(qe_port);
-               return -ENODEV;
+               ret = -ENODEV;
+               goto out_free;
        }
        qe_port->ucc_num = *iprop - 1;
  
        sprop = of_get_property(np, "rx-clock-name", NULL);
        if (!sprop) {
                dev_err(&ofdev->dev, "missing rx-clock-name in device tree\n");
-               kfree(qe_port);
-               return -ENODEV;
+               ret = -ENODEV;
+               goto out_free;
        }
  
        qe_port->us_info.rx_clock = qe_clock_source(sprop);
        if ((qe_port->us_info.rx_clock < QE_BRG1) ||
            (qe_port->us_info.rx_clock > QE_BRG16)) {
                dev_err(&ofdev->dev, "rx-clock-name must be a BRG for UART\n");
-               kfree(qe_port);
-               return -ENODEV;
+               ret = -ENODEV;
+               goto out_free;
        }
  
  #ifdef LOOPBACK
        sprop = of_get_property(np, "tx-clock-name", NULL);
        if (!sprop) {
                dev_err(&ofdev->dev, "missing tx-clock-name in device tree\n");
-               kfree(qe_port);
-               return -ENODEV;
+               ret = -ENODEV;
+               goto out_free;
        }
        qe_port->us_info.tx_clock = qe_clock_source(sprop);
  #endif
        if ((qe_port->us_info.tx_clock < QE_BRG1) ||
            (qe_port->us_info.tx_clock > QE_BRG16)) {
                dev_err(&ofdev->dev, "tx-clock-name must be a BRG for UART\n");
-               kfree(qe_port);
-               return -ENODEV;
+               ret = -ENODEV;
+               goto out_free;
        }
  
        /* Get the port number, numbered 0-3 */
        iprop = of_get_property(np, "port-number", NULL);
        if (!iprop) {
                dev_err(&ofdev->dev, "missing port-number in device tree\n");
-               kfree(qe_port);
-               return -EINVAL;
+               ret = -EINVAL;
+               goto out_free;
        }
        qe_port->port.line = *iprop;
        if (qe_port->port.line >= UCC_MAX_UART) {
                dev_err(&ofdev->dev, "port-number must be 0-%u\n",
                        UCC_MAX_UART - 1);
-               kfree(qe_port);
-               return -EINVAL;
+               ret = -EINVAL;
+               goto out_free;
        }
  
        qe_port->port.irq = irq_of_parse_and_map(np, 0);
        if (qe_port->port.irq == NO_IRQ) {
                dev_err(&ofdev->dev, "could not map IRQ for UCC%u\n",
                       qe_port->ucc_num + 1);
-               kfree(qe_port);
-               return -EINVAL;
+               ret = -EINVAL;
+               goto out_free;
        }
  
        /*
                np = of_find_node_by_type(NULL, "qe");
                if (!np) {
                        dev_err(&ofdev->dev, "could not find 'qe' node\n");
-                       kfree(qe_port);
-                       return -EINVAL;
+                       ret = -EINVAL;
+                       goto out_free;
                }
        }
  
        if (!iprop) {
                dev_err(&ofdev->dev,
                       "missing brg-frequency in device tree\n");
-               kfree(qe_port);
-               return -EINVAL;
+               ret = -EINVAL;
+               goto out_np;
        }
  
        if (*iprop)
                if (!iprop) {
                        dev_err(&ofdev->dev,
                                "missing QE bus-frequency in device tree\n");
-                       kfree(qe_port);
-                       return -EINVAL;
+                       ret = -EINVAL;
+                       goto out_np;
                }
                if (*iprop)
                        qe_port->port.uartclk = *iprop / 2;
                else {
                        dev_err(&ofdev->dev,
                                "invalid QE bus-frequency in device tree\n");
-                       kfree(qe_port);
-                       return -EINVAL;
+                       ret = -EINVAL;
+                       goto out_np;
                }
        }
  
        if (ret) {
                dev_err(&ofdev->dev, "could not add /dev/ttyQE%u\n",
                       qe_port->port.line);
-               kfree(qe_port);
-               return ret;
+               goto out_np;
        }
  
        dev_set_drvdata(&ofdev->dev, qe_port);
               SERIAL_QE_MINOR + qe_port->port.line);
  
        return 0;
+ out_np:
+       of_node_put(np);
+ out_free:
+       kfree(qe_port);
+       return ret;
  }
  
  static int ucc_uart_remove(struct platform_device *ofdev)
@@@ -1484,7 -1488,7 +1487,7 @@@ static struct of_device_id ucc_uart_mat
  };
  MODULE_DEVICE_TABLE(of, ucc_uart_match);
  
 -static struct of_platform_driver ucc_uart_of_driver = {
 +static struct platform_driver ucc_uart_of_driver = {
        .driver = {
                .name = "ucc_uart",
                .owner = THIS_MODULE,
@@@ -1509,7 -1513,7 +1512,7 @@@ static int __init ucc_uart_init(void
                return ret;
        }
  
 -      ret = of_register_platform_driver(&ucc_uart_of_driver);
 +      ret = platform_driver_register(&ucc_uart_of_driver);
        if (ret)
                printk(KERN_ERR
                       "ucc-uart: could not register platform driver\n");
@@@ -1522,7 -1526,7 +1525,7 @@@ static void __exit ucc_uart_exit(void
        printk(KERN_INFO
               "Freescale QUICC Engine UART device driver unloading\n");
  
 -      of_unregister_platform_driver(&ucc_uart_of_driver);
 +      platform_driver_unregister(&ucc_uart_of_driver);
        uart_unregister_driver(&ucc_uart_driver);
  }