Merge branch 'devel' of master.kernel.org:/home/rmk/linux-2.6-arm
Linus Torvalds [Tue, 3 Aug 2010 21:31:24 +0000 (14:31 -0700)]
* 'devel' of master.kernel.org:/home/rmk/linux-2.6-arm: (291 commits)
  ARM: AMBA: Add pclk support to AMBA bus infrastructure
  ARM: 6278/2: fix regression in RealView after the introduction of pclk
  ARM: 6277/1: mach-shmobile: Allow users to select HZ, default to 128
  ARM: 6276/1: mach-shmobile: remove duplicate NR_IRQS_LEGACY
  ARM: 6246/1: mmci: support larger MMCIDATALENGTH register
  ARM: 6245/1: mmci: enable hardware flow control on Ux500 variants
  ARM: 6244/1: mmci: add variant data and default MCICLOCK support
  ARM: 6243/1: mmci: pass power_mode to the translate_vdd callback
  ARM: 6274/1: add global control registers definition header file for nuc900
  mx2_camera: fix type of dma buffer virtual address pointer
  mx2_camera: Add soc_camera support for i.MX25/i.MX27
  arm/imx/gpio: add spinlock protection
  ARM: Add support for the LPC32XX arch
  ARM: LPC32XX: Arch config menu supoport and makefiles
  ARM: LPC32XX: Phytec 3250 platform support
  ARM: LPC32XX: Misc support functions
  ARM: LPC32XX: Serial support code
  ARM: LPC32XX: System suspend support
  ARM: LPC32XX: GPIO, timer, and IRQ drivers
  ARM: LPC32XX: Clock driver
  ...

1  2 
arch/arm/boot/compressed/Makefile
arch/arm/common/sa1111.c
arch/arm/mach-realview/core.c
arch/arm/mach-vexpress/v2m.c
drivers/mmc/host/mmci.c

@@@ -4,6 -4,7 +4,7 @@@
  # create a compressed vmlinuz image from the original vmlinux
  #
  
+ AFLAGS_head.o += -DTEXT_OFFSET=$(TEXT_OFFSET)
  HEAD  = head.o
  OBJS  = misc.o decompress.o
  FONTC = $(srctree)/drivers/video/console/font_acorn_8x8.c
@@@ -19,10 -20,6 +20,6 @@@ ifeq ($(CONFIG_ARCH_SHARK),y
  OBJS          += head-shark.o ofw-shark.o
  endif
  
- ifeq ($(CONFIG_ARCH_L7200),y)
- OBJS          += head-l7200.o
- endif
  ifeq ($(CONFIG_ARCH_P720T),y)
  # Borrow this code from SA1100
  OBJS          += head-sa1100.o
@@@ -71,9 -68,6 +68,9 @@@ targets       := vmlinux vmlinux.lds 
                 piggy.$(suffix_y) piggy.$(suffix_y).o \
                 font.o font.c head.o misc.o $(OBJS)
  
 +# Make sure files are removed during clean
 +extra-y       += piggy.gzip piggy.lzo piggy.lzma lib1funcs.S
 +
  ifeq ($(CONFIG_FUNCTION_TRACER),y)
  ORIG_CFLAGS := $(KBUILD_CFLAGS)
  KBUILD_CFLAGS = $(subst -pg, , $(ORIG_CFLAGS))
@@@ -82,19 -76,9 +79,9 @@@ endi
  EXTRA_CFLAGS  := -fpic -fno-builtin
  EXTRA_AFLAGS  := -Wa,-march=all
  
  ifeq ($(CONFIG_CPU_ENDIAN_BE8),y)
  LDFLAGS_vmlinux += --be8
  endif
- ifneq ($(INITRD_PHYS),)
- LDFLAGS_vmlinux += --defsym initrd_phys=$(INITRD_PHYS)
- endif
- ifneq ($(PARAMS_PHYS),)
- LDFLAGS_vmlinux += --defsym params_phys=$(PARAMS_PHYS)
- endif
  # ?
  LDFLAGS_vmlinux += -p
  # Report unresolved symbol references
diff --combined arch/arm/common/sa1111.c
@@@ -185,13 -185,10 +185,10 @@@ static struct sa1111_dev_info sa1111_de
        },
  };
  
- void __init sa1111_adjust_zones(int node, unsigned long *size, unsigned long *holes)
+ void __init sa1111_adjust_zones(unsigned long *size, unsigned long *holes)
  {
        unsigned int sz = SZ_1M >> PAGE_SHIFT;
  
-       if (node != 0)
-               sz = 0;
        size[1] = size[0] - sz;
        size[0] = sz;
  }
@@@ -1028,12 -1025,13 +1025,12 @@@ static int sa1111_remove(struct platfor
        struct sa1111 *sachip = platform_get_drvdata(pdev);
  
        if (sachip) {
 -              __sa1111_remove(sachip);
 -              platform_set_drvdata(pdev, NULL);
 -
  #ifdef CONFIG_PM
                kfree(sachip->saved_state);
                sachip->saved_state = NULL;
  #endif
 +              __sa1111_remove(sachip);
 +              platform_set_drvdata(pdev, NULL);
        }
  
        return 0;
@@@ -61,12 -61,11 +61,11 @@@ void __iomem *gic_cpu_base_addr
  /*
   * Adjust the zones if there are restrictions for DMA access.
   */
- void __init realview_adjust_zones(int node, unsigned long *size,
-                                 unsigned long *hole)
+ void __init realview_adjust_zones(unsigned long *size, unsigned long *hole)
  {
        unsigned long dma_size = SZ_256M >> PAGE_SHIFT;
  
-       if (!machine_is_realview_pbx() || node || (size[0] <= dma_size))
+       if (!machine_is_realview_pbx() || size[0] <= dma_size)
                return;
  
        size[ZONE_NORMAL] = size[0] - dma_size;
@@@ -232,12 -231,27 +231,27 @@@ static unsigned int realview_mmc_status
        struct amba_device *adev = container_of(dev, struct amba_device, dev);
        u32 mask;
  
+       if (machine_is_realview_pb1176()) {
+               static bool inserted = false;
+               /*
+                * The PB1176 does not have the status register,
+                * assume it is inserted at startup, then invert
+                * for each call so card insertion/removal will
+                * be detected anyway. This will not be called if
+                * GPIO on PL061 is active, which is the proper
+                * way to do this on the PB1176.
+                */
+               inserted = !inserted;
+               return inserted ? 0 : 1;
+       }
        if (adev->res.start == REALVIEW_MMCI0_BASE)
                mask = 1;
        else
                mask = 2;
  
 -      return !(readl(REALVIEW_SYSMCI) & mask);
 +      return readl(REALVIEW_SYSMCI) & mask;
  }
  
  struct mmci_platform_data realview_mmc0_plat_data = {
@@@ -300,8 -314,13 +314,13 @@@ static struct clk ref24_clk = 
        .rate   = 24000000,
  };
  
+ static struct clk dummy_apb_pclk;
  static struct clk_lookup lookups[] = {
-       {       /* UART0 */
+       {       /* Bus clock */
+               .con_id         = "apb_pclk",
+               .clk            = &dummy_apb_pclk,
+       }, {    /* UART0 */
                .dev_id         = "dev:uart0",
                .clk            = &ref24_clk,
        }, {    /* UART1 */
        }, {    /* UART3 */
                .dev_id         = "fpga:uart3",
                .clk            = &ref24_clk,
+       }, {    /* UART3 is on the dev chip in PB1176 */
+               .dev_id         = "dev:uart3",
+               .clk            = &ref24_clk,
+       }, {    /* UART4 only exists in PB1176 */
+               .dev_id         = "fpga:uart4",
+               .clk            = &ref24_clk,
        }, {    /* KMI0 */
                .dev_id         = "fpga:kmi0",
                .clk            = &ref24_clk,
        }, {    /* MMC0 */
                .dev_id         = "fpga:mmc0",
                .clk            = &ref24_clk,
-       }, {    /* EB:CLCD */
+       }, {    /* CLCD is in the PB1176 and EB DevChip */
                .dev_id         = "dev:clcd",
                .clk            = &oscvco_clk,
        }, {    /* PB:CLCD */
                .dev_id         = "issp:clcd",
                .clk            = &oscvco_clk,
+       }, {    /* SSP */
+               .dev_id         = "dev:ssp0",
+               .clk            = &ref24_clk,
        }
  };
  
@@@ -342,7 -370,7 +370,7 @@@ static int __init clk_init(void
  
        return 0;
  }
- arch_initcall(clk_init);
+ core_initcall(clk_init);
  
  /*
   * CLCD support.
@@@ -241,7 -241,7 +241,7 @@@ static struct platform_device v2m_flash
  
  static unsigned int v2m_mmci_status(struct device *dev)
  {
 -      return !(readl(MMIO_P2V(V2M_SYS_MCI)) & (1 << 0));
 +      return readl(MMIO_P2V(V2M_SYS_MCI)) & (1 << 0);
  }
  
  static struct mmci_platform_data v2m_mmci_data = {
@@@ -298,8 -298,13 +298,13 @@@ static struct clk osc2_clk = 
        .rate   = 24000000,
  };
  
+ static struct clk dummy_apb_pclk;
  static struct clk_lookup v2m_lookups[] = {
-       {       /* UART0 */
+       {       /* AMBA bus clock */
+               .con_id         = "apb_pclk",
+               .clk            = &dummy_apb_pclk,
+       }, {    /* UART0 */
                .dev_id         = "mb:uart0",
                .clk            = &osc2_clk,
        }, {    /* UART1 */
diff --combined drivers/mmc/host/mmci.c
@@@ -26,7 -26,6 +26,6 @@@
  #include <linux/amba/mmci.h>
  #include <linux/regulator/consumer.h>
  
- #include <asm/cacheflush.h>
  #include <asm/div64.h>
  #include <asm/io.h>
  #include <asm/sizes.h>
  
  static unsigned int fmax = 515633;
  
+ /**
+  * struct variant_data - MMCI variant-specific quirks
+  * @clkreg: default value for MCICLOCK register
+  * @clkreg_enable: enable value for MMCICLOCK register
+  * @datalength_bits: number of bits in the MMCIDATALENGTH register
+  */
+ struct variant_data {
+       unsigned int            clkreg;
+       unsigned int            clkreg_enable;
+       unsigned int            datalength_bits;
+ };
+ static struct variant_data variant_arm = {
+       .datalength_bits        = 16,
+ };
+ static struct variant_data variant_u300 = {
+       .clkreg_enable          = 1 << 13, /* HWFCEN */
+       .datalength_bits        = 16,
+ };
+ static struct variant_data variant_ux500 = {
+       .clkreg                 = MCI_CLK_ENABLE,
+       .clkreg_enable          = 1 << 14, /* HWFCEN */
+       .datalength_bits        = 24,
+ };
  /*
   * This must be called with host->lock held
   */
  static void mmci_set_clkreg(struct mmci_host *host, unsigned int desired)
  {
-       u32 clk = 0;
+       struct variant_data *variant = host->variant;
+       u32 clk = variant->clkreg;
  
        if (desired) {
                if (desired >= host->mclk) {
@@@ -54,8 -80,8 +80,8 @@@
                                clk = 255;
                        host->cclk = host->mclk / (2 * (clk + 1));
                }
-               if (host->hw_designer == AMBA_VENDOR_ST)
-                       clk |= MCI_ST_FCEN; /* Bug fix in ST IP block */
+               clk |= variant->clkreg_enable;
                clk |= MCI_CLK_ENABLE;
                /* This hasn't proven to be worthwhile */
                /* clk |= MCI_CLK_PWRSAVE; */
@@@ -98,6 -124,18 +124,18 @@@ static void mmci_stop_data(struct mmci_
        host->data = NULL;
  }
  
+ static void mmci_init_sg(struct mmci_host *host, struct mmc_data *data)
+ {
+       unsigned int flags = SG_MITER_ATOMIC;
+       if (data->flags & MMC_DATA_READ)
+               flags |= SG_MITER_TO_SG;
+       else
+               flags |= SG_MITER_FROM_SG;
+       sg_miter_start(&host->sg_miter, data->sg, data->sg_len, flags);
+ }
  static void mmci_start_data(struct mmci_host *host, struct mmc_data *data)
  {
        unsigned int datactrl, timeout, irqmask;
                data->blksz, data->blocks, data->flags);
  
        host->data = data;
-       host->size = data->blksz;
+       host->size = data->blksz * data->blocks;
        host->data_xfered = 0;
  
        mmci_init_sg(host, data);
@@@ -210,8 -248,17 +248,17 @@@ mmci_data_irq(struct mmci_host *host, s
                 * We hit an error condition.  Ensure that any data
                 * partially written to a page is properly coherent.
                 */
-               if (host->sg_len && data->flags & MMC_DATA_READ)
-                       flush_dcache_page(sg_page(host->sg_ptr));
+               if (data->flags & MMC_DATA_READ) {
+                       struct sg_mapping_iter *sg_miter = &host->sg_miter;
+                       unsigned long flags;
+                       local_irq_save(flags);
+                       if (sg_miter_next(sg_miter)) {
+                               flush_dcache_page(sg_miter->page);
+                               sg_miter_stop(sg_miter);
+                       }
+                       local_irq_restore(flags);
+               }
        }
        if (status & MCI_DATAEND) {
                mmci_stop_data(host);
@@@ -314,15 -361,18 +361,18 @@@ static int mmci_pio_write(struct mmci_h
  static irqreturn_t mmci_pio_irq(int irq, void *dev_id)
  {
        struct mmci_host *host = dev_id;
+       struct sg_mapping_iter *sg_miter = &host->sg_miter;
        void __iomem *base = host->base;
+       unsigned long flags;
        u32 status;
  
        status = readl(base + MMCISTATUS);
  
        dev_dbg(mmc_dev(host->mmc), "irq1 (pio) %08x\n", status);
  
+       local_irq_save(flags);
        do {
-               unsigned long flags;
                unsigned int remain, len;
                char *buffer;
  
                if (!(status & (MCI_TXFIFOHALFEMPTY|MCI_RXDATAAVLBL)))
                        break;
  
-               /*
-                * Map the current scatter buffer.
-                */
-               buffer = mmci_kmap_atomic(host, &flags) + host->sg_off;
-               remain = host->sg_ptr->length - host->sg_off;
+               if (!sg_miter_next(sg_miter))
+                       break;
+               buffer = sg_miter->addr;
+               remain = sg_miter->length;
  
                len = 0;
                if (status & MCI_RXACTIVE)
                if (status & MCI_TXACTIVE)
                        len = mmci_pio_write(host, buffer, remain, status);
  
-               /*
-                * Unmap the buffer.
-                */
-               mmci_kunmap_atomic(host, buffer, &flags);
+               sg_miter->consumed = len;
  
-               host->sg_off += len;
                host->size -= len;
                remain -= len;
  
                if (remain)
                        break;
  
-               /*
-                * If we were reading, and we have completed this
-                * page, ensure that the data cache is coherent.
-                */
                if (status & MCI_RXACTIVE)
-                       flush_dcache_page(sg_page(host->sg_ptr));
-               if (!mmci_next_sg(host))
-                       break;
+                       flush_dcache_page(sg_miter->page);
  
                status = readl(base + MMCISTATUS);
        } while (1);
  
+       sg_miter_stop(sg_miter);
+       local_irq_restore(flags);
        /*
         * If we're nearing the end of the read, switch to
         * "any data available" mode.
@@@ -477,16 -520,9 +520,9 @@@ static void mmci_set_ios(struct mmc_hos
                        /* This implicitly enables the regulator */
                        mmc_regulator_set_ocr(host->vcc, ios->vdd);
  #endif
-               /*
-                * The translate_vdd function is not used if you have
-                * an external regulator, or your design is really weird.
-                * Using it would mean sending in power control BOTH using
-                * a regulator AND the 4 MMCIPWR bits. If we don't have
-                * a regulator, we might have some other platform specific
-                * power control behind this translate function.
-                */
-               if (!host->vcc && host->plat->translate_vdd)
-                       pwr |= host->plat->translate_vdd(mmc_dev(mmc), ios->vdd);
+               if (host->plat->vdd_handler)
+                       pwr |= host->plat->vdd_handler(mmc_dev(mmc), ios->vdd,
+                                                      ios->power_mode);
                /* The ST version does not have this, fall through to POWER_ON */
                if (host->hw_designer != AMBA_VENDOR_ST) {
                        pwr |= MCI_PWR_UP;
@@@ -539,13 -575,9 +575,13 @@@ static int mmci_get_cd(struct mmc_host 
        if (host->gpio_cd == -ENOSYS)
                status = host->plat->status(mmc_dev(host->mmc));
        else
 -              status = gpio_get_value(host->gpio_cd);
 +              status = !gpio_get_value(host->gpio_cd);
  
 -      return !status;
 +      /*
 +       * Use positive logic throughout - status is zero for no card,
 +       * non-zero for card inserted.
 +       */
 +      return status;
  }
  
  static const struct mmc_host_ops mmci_ops = {
        .get_cd         = mmci_get_cd,
  };
  
  static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id)
  {
        struct mmci_platform_data *plat = dev->dev.platform_data;
+       struct variant_data *variant = id->data;
        struct mmci_host *host;
        struct mmc_host *mmc;
        int ret;
                goto clk_free;
  
        host->plat = plat;
+       host->variant = variant;
        host->mclk = clk_get_rate(host->clk);
        /*
         * According to the spec, mclk is max 100 MHz,
        if (host->vcc == NULL)
                mmc->ocr_avail = plat->ocr_mask;
        mmc->caps = plat->capabilities;
+       mmc->caps |= MMC_CAP_NEEDS_POLL;
  
        /*
         * We can do SGIO
        mmc->max_phys_segs = NR_SG;
  
        /*
-        * Since we only have a 16-bit data length register, we must
-        * ensure that we don't exceed 2^16-1 bytes in a single request.
+        * Since only a certain number of bits are valid in the data length
+        * register, we must ensure that we don't exceed 2^num-1 bytes in a
+        * single request.
         */
-       mmc->max_req_size = 65535;
+       mmc->max_req_size = (1 << variant->datalength_bits) - 1;
  
        /*
         * Set the maximum segment size.  Since we aren't doing DMA
        writel(MCI_IRQENABLE, host->base + MMCIMASK0);
  
        amba_set_drvdata(dev, mmc);
-       host->oldstat = mmci_get_cd(host->mmc);
  
        mmc_add_host(mmc);
  
                mmc_hostname(mmc), amba_rev(dev), amba_config(dev),
                (unsigned long long)dev->res.start, dev->irq[0], dev->irq[1]);
  
-       init_timer(&host->timer);
-       host->timer.data = (unsigned long)host;
-       host->timer.function = mmci_check_status;
-       host->timer.expires = jiffies + HZ;
-       add_timer(&host->timer);
        return 0;
  
   irq0_free:
@@@ -785,8 -802,6 +806,6 @@@ static int __devexit mmci_remove(struc
        if (mmc) {
                struct mmci_host *host = mmc_priv(mmc);
  
-               del_timer_sync(&host->timer);
                mmc_remove_host(mmc);
  
                writel(0, host->base + MMCIMASK0);
@@@ -860,19 -875,28 +879,28 @@@ static struct amba_id mmci_ids[] = 
        {
                .id     = 0x00041180,
                .mask   = 0x000fffff,
+               .data   = &variant_arm,
        },
        {
                .id     = 0x00041181,
                .mask   = 0x000fffff,
+               .data   = &variant_arm,
        },
        /* ST Micro variants */
        {
                .id     = 0x00180180,
                .mask   = 0x00ffffff,
+               .data   = &variant_u300,
        },
        {
                .id     = 0x00280180,
                .mask   = 0x00ffffff,
+               .data   = &variant_u300,
+       },
+       {
+               .id     = 0x00480180,
+               .mask   = 0x00ffffff,
+               .data   = &variant_ux500,
        },
        { 0, 0 },
  };