Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 1 Apr 2011 15:54:14 +0000 (08:54 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 1 Apr 2011 15:54:14 +0000 (08:54 -0700)
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6:
  sparc32: Pass task_struct to schedule_tail() in ret_from_fork
  apbuart: Depend upon sparc.
  sparc64: Fix section mis-match errors.
  sparc32,leon: Fixed APBUART frequency detection
  sparc32, leon: APBUART driver must use archdata to get IRQ number
  sparc: Hook up syncfs system call.

219 files changed:
arch/alpha/Kconfig
arch/arm/Kconfig
arch/arm/boot/compressed/head.S
arch/arm/boot/compressed/misc.c
arch/arm/include/asm/mach/udc_pxa2xx.h
arch/arm/kernel/debug.S
arch/arm/kernel/etm.c
arch/arm/kernel/kprobes-decode.c
arch/arm/kernel/perf_event.c
arch/arm/kernel/perf_event_v6.c
arch/arm/kernel/perf_event_v7.c
arch/arm/kernel/perf_event_xscale.c
arch/arm/kernel/sleep.S
arch/arm/mach-imx/Kconfig
arch/arm/mach-imx/eukrea_mbimxsd25-baseboard.c
arch/arm/mach-kirkwood/sheevaplug-setup.c
arch/arm/mach-mx3/eukrea_mbimxsd-baseboard.c
arch/arm/mach-mx3/mach-pcm043.c
arch/arm/mach-mx5/Kconfig
arch/arm/mach-mx5/Makefile
arch/arm/mach-mx5/board-mx51_babbage.c
arch/arm/mach-mx5/board-mx53_evk.c
arch/arm/mach-mx5/board-mx53_loco.c
arch/arm/mach-mx5/clock-mx51-mx53.c
arch/arm/mach-mx5/cpu.c
arch/arm/mach-mx5/eukrea_mbimxsd-baseboard.c
arch/arm/mach-mx5/mx51_efika.c
arch/arm/mach-mx5/system.c [new file with mode: 0644]
arch/arm/mach-mxs/Kconfig
arch/arm/mach-mxs/clock-mx23.c
arch/arm/mach-mxs/clock-mx28.c
arch/arm/mach-mxs/devices-mx23.h
arch/arm/mach-mxs/devices-mx28.h
arch/arm/mach-mxs/devices/Kconfig
arch/arm/mach-mxs/devices/Makefile
arch/arm/mach-mxs/devices/platform-mxs-mmc.c [new file with mode: 0644]
arch/arm/mach-mxs/include/mach/devices-common.h
arch/arm/mach-mxs/mach-mx23evk.c
arch/arm/mach-mxs/mach-mx28evk.c
arch/arm/mach-mxs/module-tx28.c
arch/arm/mach-mxs/module-tx28.h
arch/arm/mach-orion5x/ts78xx-setup.c
arch/arm/mach-pxa/am200epd.c
arch/arm/mach-pxa/am300epd.c
arch/arm/mach-pxa/balloon3.c
arch/arm/mach-pxa/cm-x2xx.c
arch/arm/mach-pxa/cm-x300.c
arch/arm/mach-pxa/colibri-pxa270-income.c
arch/arm/mach-pxa/colibri-pxa3xx.c
arch/arm/mach-pxa/corgi.c
arch/arm/mach-pxa/devices.c
arch/arm/mach-pxa/em-x270.c
arch/arm/mach-pxa/eseries.c
arch/arm/mach-pxa/ezx.c
arch/arm/mach-pxa/gumstix.c
arch/arm/mach-pxa/idp.c
arch/arm/mach-pxa/include/mach/palmz72.h
arch/arm/mach-pxa/include/mach/pxafb.h
arch/arm/mach-pxa/include/mach/z2.h
arch/arm/mach-pxa/littleton.c
arch/arm/mach-pxa/lpd270.c
arch/arm/mach-pxa/lubbock.c
arch/arm/mach-pxa/magician.c
arch/arm/mach-pxa/mainstone.c
arch/arm/mach-pxa/mioa701.c
arch/arm/mach-pxa/palm27x.c
arch/arm/mach-pxa/palmtc.c
arch/arm/mach-pxa/palmte2.c
arch/arm/mach-pxa/palmz72.c
arch/arm/mach-pxa/pcm990-baseboard.c
arch/arm/mach-pxa/poodle.c
arch/arm/mach-pxa/raumfeld.c
arch/arm/mach-pxa/saar.c
arch/arm/mach-pxa/spitz.c
arch/arm/mach-pxa/tavorevb.c
arch/arm/mach-pxa/time.c
arch/arm/mach-pxa/tosa.c
arch/arm/mach-pxa/trizeps4.c
arch/arm/mach-pxa/viper.c
arch/arm/mach-pxa/vpac270.c
arch/arm/mach-pxa/z2.c
arch/arm/mach-pxa/zeus.c
arch/arm/mach-pxa/zylonite.c
arch/arm/mach-realview/realview_eb.c
arch/arm/mach-versatile/core.c
arch/arm/plat-mxc/devices/platform-fec.c
arch/arm/plat-mxc/devices/platform-imxdi_rtc.c
arch/arm/plat-mxc/include/mach/audmux.h
arch/arm/plat-mxc/include/mach/iomux-mx2x.h
arch/arm/plat-mxc/include/mach/mx50.h
arch/arm/plat-mxc/include/mach/mx51.h
arch/arm/plat-mxc/include/mach/mxc.h
arch/arm/plat-mxc/include/mach/system.h
arch/arm/plat-mxc/time.c
arch/avr32/Kconfig
arch/avr32/mach-at32ap/pio.c
arch/blackfin/Kconfig
arch/blackfin/configs/BF527-AD7160-EVAL_defconfig
arch/blackfin/configs/BF538-EZKIT_defconfig
arch/blackfin/configs/BF561-ACVILON_defconfig
arch/blackfin/configs/BlackStamp_defconfig
arch/blackfin/configs/CM-BF527_defconfig
arch/blackfin/configs/CM-BF533_defconfig
arch/blackfin/configs/CM-BF548_defconfig
arch/blackfin/configs/DNP5370_defconfig
arch/blackfin/configs/H8606_defconfig
arch/blackfin/configs/SRV1_defconfig
arch/blackfin/include/asm/bitops.h
arch/blackfin/kernel/module.c
arch/cris/Kconfig
arch/frv/Kconfig
arch/h8300/Kconfig
arch/ia64/sn/kernel/sn2/sn_proc_fs.c
arch/m32r/Kconfig
arch/m68k/Kconfig
arch/microblaze/Kconfig
arch/mn10300/Kconfig
arch/parisc/Kconfig
arch/powerpc/Kconfig
arch/powerpc/configs/44x/warp_defconfig
arch/powerpc/configs/52xx/motionpro_defconfig
arch/powerpc/configs/86xx/gef_ppc9a_defconfig
arch/powerpc/configs/86xx/gef_sbc310_defconfig
arch/powerpc/configs/86xx/gef_sbc610_defconfig
arch/powerpc/configs/86xx/mpc8641_hpcn_defconfig
arch/powerpc/configs/e55xx_smp_defconfig
arch/powerpc/configs/linkstation_defconfig
arch/powerpc/configs/mpc512x_defconfig
arch/powerpc/configs/mpc5200_defconfig
arch/powerpc/configs/mpc85xx_defconfig
arch/powerpc/configs/mpc85xx_smp_defconfig
arch/powerpc/configs/mpc86xx_defconfig
arch/powerpc/configs/pasemi_defconfig
arch/powerpc/configs/ppc6xx_defconfig
arch/powerpc/configs/pseries_defconfig
arch/powerpc/include/asm/dma-mapping.h
arch/powerpc/include/asm/mmu-hash64.h
arch/powerpc/include/asm/page.h
arch/powerpc/include/asm/qe_ic.h
arch/powerpc/include/asm/reg_booke.h
arch/powerpc/include/asm/systbl.h
arch/powerpc/include/asm/unistd.h
arch/powerpc/kernel/dma.c
arch/powerpc/kernel/exceptions-64s.S
arch/powerpc/kernel/time.c
arch/powerpc/mm/dma-noncoherent.c
arch/powerpc/platforms/cell/interrupt.c
arch/powerpc/platforms/pseries/nvram.c
arch/powerpc/platforms/pseries/smp.c
arch/powerpc/platforms/pseries/xics.c
arch/powerpc/sysdev/mpc8xx_pic.c
arch/score/Kconfig
arch/sh/Kconfig
arch/sparc/Kconfig
arch/tile/Kconfig
arch/um/Kconfig.common
arch/unicore32/Kconfig
arch/x86/kernel/apb_timer.c
arch/xtensa/Kconfig
drivers/ata/pata_palmld.c
drivers/atm/solos-pci.c
drivers/connector/cn_queue.c
drivers/connector/connector.c
drivers/net/atlx/atl2.c
drivers/net/bonding/bond_alb.h
drivers/net/irda/via-ircc.c
drivers/net/mlx4/eq.c
drivers/net/mlx4/mcg.c
drivers/net/phy/phy_device.c
drivers/net/usb/Kconfig
drivers/net/usb/Makefile
drivers/net/usb/cdc_ether.c
drivers/net/usb/lg-vl600.c [new file with mode: 0644]
drivers/net/usb/usbnet.c
drivers/pcmcia/pxa2xx_colibri.c
drivers/pcmcia/pxa2xx_palmld.c
drivers/pcmcia/pxa2xx_palmtc.c
drivers/pcmcia/pxa2xx_palmtx.c
drivers/pcmcia/pxa2xx_vpac270.c
drivers/sh/intc/internals.h
drivers/usb/gadget/pxa25x_udc.c
drivers/video/pxafb.c
drivers/video/pxafb.h
fs/ceph/mds_client.c
fs/ceph/super.c
fs/nilfs2/file.c
fs/nilfs2/nilfs.h
fs/nilfs2/page.c
include/keys/ceph-type.h [new file with mode: 0644]
include/linux/atmdev.h
include/linux/ceph/auth.h
include/linux/ceph/libceph.h
include/linux/connector.h
include/linux/interrupt.h
include/linux/irq.h
include/linux/skbuff.h
include/linux/usb/usbnet.h
include/net/if_inet6.h
include/net/ip.h
kernel/irq/Kconfig
kernel/irq/chip.c
net/appletalk/ddp.c
net/atm/common.c
net/bridge/br_multicast.c
net/bridge/br_stp_if.c
net/ceph/Kconfig
net/ceph/auth.c
net/ceph/auth_x.c
net/ceph/ceph_common.c
net/ceph/crypto.c
net/ceph/crypto.h
net/ceph/mon_client.c
net/ceph/osd_client.c
net/core/dev.c
net/ipv4/arp.c
net/ipv4/fib_frontend.c
net/ipv6/ndisc.c
net/sctp/protocol.c
sound/soc/soc-jack.c

index bd4160c..9808998 100644 (file)
@@ -12,7 +12,6 @@ config ALPHA
        select GENERIC_IRQ_PROBE
        select AUTO_IRQ_AFFINITY if SMP
        select GENERIC_IRQ_SHOW
-       select GENERIC_HARDIRQS_NO_DEPRECATED
        help
          The Alpha is a 64-bit general-purpose processor designed and
          marketed by the Digital Equipment Corporation of blessed memory,
index 7c0effb..5b9f78b 100644 (file)
@@ -366,6 +366,7 @@ config ARCH_MXC
        select GENERIC_CLOCKEVENTS
        select ARCH_REQUIRE_GPIOLIB
        select CLKDEV_LOOKUP
+       select HAVE_SCHED_CLOCK
        help
          Support for Freescale MXC/iMX-based family of processors
 
index 84ac4d6..adf583c 100644 (file)
 
 #if defined(CONFIG_DEBUG_ICEDCC)
 
-#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K)
+#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K) || defined(CONFIG_CPU_V7)
                .macro  loadsp, rb, tmp
                .endm
                .macro  writeb, ch, rb
                mcr     p14, 0, \ch, c0, c5, 0
                .endm
-#elif defined(CONFIG_CPU_V7)
-               .macro  loadsp, rb, tmp
-               .endm
-               .macro  writeb, ch, rb
-wait:          mrc     p14, 0, pc, c0, c1, 0
-               bcs     wait
-               mcr     p14, 0, \ch, c0, c5, 0
-               .endm
 #elif defined(CONFIG_CPU_XSCALE)
                .macro  loadsp, rb, tmp
                .endm
index 4657e87..2df3826 100644 (file)
@@ -36,7 +36,7 @@ extern void error(char *x);
 
 #ifdef CONFIG_DEBUG_ICEDCC
 
-#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K)
+#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K) || defined(CONFIG_CPU_V7)
 
 static void icedcc_putc(int ch)
 {
@@ -52,16 +52,6 @@ static void icedcc_putc(int ch)
        asm("mcr p14, 0, %0, c0, c5, 0" : : "r" (ch));
 }
 
-#elif defined(CONFIG_CPU_V7)
-
-static void icedcc_putc(int ch)
-{
-       asm(
-       "wait:  mrc     p14, 0, pc, c0, c1, 0                   \n\
-               bcs     wait                                    \n\
-               mcr     p14, 0, %0, c0, c5, 0                   "
-       : : "r" (ch));
-}
 
 #elif defined(CONFIG_CPU_XSCALE)
 
index 833306e..ea297ac 100644 (file)
@@ -20,8 +20,6 @@ struct pxa2xx_udc_mach_info {
         * VBUS IRQ and omit the methods above.  Store the GPIO number
         * here.  Note that sometimes the signals go through inverters...
         */
-       bool    gpio_vbus_inverted;
-       int     gpio_vbus;                      /* high == vbus present */
        bool    gpio_pullup_inverted;
        int     gpio_pullup;                    /* high == pullup activated */
 };
index d2d983b..bcd66e0 100644 (file)
@@ -25,7 +25,7 @@
                .macro  addruart, rp, rv
                .endm
 
-#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K)
+#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K) || defined(CONFIG_CPU_V7)
 
                .macro  senduart, rd, rx
                mcr     p14, 0, \rd, c0, c5, 0
 1002:
                .endm
 
-#elif defined(CONFIG_CPU_V7)
-
-               .macro  senduart, rd, rx
-               mcr     p14, 0, \rd, c0, c5, 0
-               .endm
-
-               .macro  busyuart, rd, rx
-busy:          mrc     p14, 0, pc, c0, c1, 0
-               bcs     busy
-               .endm
-
-               .macro  waituart, rd, rx
-wait:          mrc     p14, 0, pc, c0, c1, 0
-               bcs     wait
-
-               .endm
-
 #elif defined(CONFIG_CPU_XSCALE)
 
                .macro  senduart, rd, rx
index 052b509..1bec8b5 100644 (file)
@@ -338,7 +338,7 @@ static struct miscdevice etb_miscdev = {
        .fops = &etb_fops,
 };
 
-static int __init etb_probe(struct amba_device *dev, const struct amba_id *id)
+static int __devinit etb_probe(struct amba_device *dev, const struct amba_id *id)
 {
        struct tracectx *t = &tracer;
        int ret = 0;
@@ -530,7 +530,7 @@ static ssize_t trace_mode_store(struct kobject *kobj,
 static struct kobj_attribute trace_mode_attr =
        __ATTR(trace_mode, 0644, trace_mode_show, trace_mode_store);
 
-static int __init etm_probe(struct amba_device *dev, const struct amba_id *id)
+static int __devinit etm_probe(struct amba_device *dev, const struct amba_id *id)
 {
        struct tracectx *t = &tracer;
        int ret = 0;
index 8f6ed43..2389131 100644 (file)
@@ -594,7 +594,8 @@ static void __kprobes emulate_ldr(struct kprobe *p, struct pt_regs *regs)
        long cpsr = regs->ARM_cpsr;
 
        fnr.dr = insnslot_llret_3arg_rflags(rnv, 0, rmv, cpsr, i_fn);
-       regs->uregs[rn] = fnr.r0;  /* Save Rn in case of writeback. */
+       if (rn != 15)
+               regs->uregs[rn] = fnr.r0;  /* Save Rn in case of writeback. */
        rdv = fnr.r1;
 
        if (rd == 15) {
@@ -622,10 +623,11 @@ static void __kprobes emulate_str(struct kprobe *p, struct pt_regs *regs)
        long rdv = (rd == 15) ? iaddr + str_pc_offset : regs->uregs[rd];
        long rnv = (rn == 15) ? iaddr +  8 : regs->uregs[rn];
        long rmv = regs->uregs[rm];  /* rm/rmv may be invalid, don't care. */
+       long rnv_wb;
 
-       /* Save Rn in case of writeback. */
-       regs->uregs[rn] =
-               insnslot_3arg_rflags(rnv, rdv, rmv, regs->ARM_cpsr, i_fn);
+       rnv_wb = insnslot_3arg_rflags(rnv, rdv, rmv, regs->ARM_cpsr, i_fn);
+       if (rn != 15)
+               regs->uregs[rn] = rnv_wb;  /* Save Rn in case of writeback. */
 }
 
 static void __kprobes emulate_mrrc(struct kprobe *p, struct pt_regs *regs)
index 22e194e..69cfee0 100644 (file)
@@ -79,6 +79,7 @@ struct arm_pmu {
        void            (*write_counter)(int idx, u32 val);
        void            (*start)(void);
        void            (*stop)(void);
+       void            (*reset)(void *);
        const unsigned  (*cache_map)[PERF_COUNT_HW_CACHE_MAX]
                                    [PERF_COUNT_HW_CACHE_OP_MAX]
                                    [PERF_COUNT_HW_CACHE_RESULT_MAX];
@@ -204,11 +205,9 @@ armpmu_event_set_period(struct perf_event *event,
 static u64
 armpmu_event_update(struct perf_event *event,
                    struct hw_perf_event *hwc,
-                   int idx)
+                   int idx, int overflow)
 {
-       int shift = 64 - 32;
-       s64 prev_raw_count, new_raw_count;
-       u64 delta;
+       u64 delta, prev_raw_count, new_raw_count;
 
 again:
        prev_raw_count = local64_read(&hwc->prev_count);
@@ -218,8 +217,13 @@ again:
                             new_raw_count) != prev_raw_count)
                goto again;
 
-       delta = (new_raw_count << shift) - (prev_raw_count << shift);
-       delta >>= shift;
+       new_raw_count &= armpmu->max_period;
+       prev_raw_count &= armpmu->max_period;
+
+       if (overflow)
+               delta = armpmu->max_period - prev_raw_count + new_raw_count;
+       else
+               delta = new_raw_count - prev_raw_count;
 
        local64_add(delta, &event->count);
        local64_sub(delta, &hwc->period_left);
@@ -236,7 +240,7 @@ armpmu_read(struct perf_event *event)
        if (hwc->idx < 0)
                return;
 
-       armpmu_event_update(event, hwc, hwc->idx);
+       armpmu_event_update(event, hwc, hwc->idx, 0);
 }
 
 static void
@@ -254,7 +258,7 @@ armpmu_stop(struct perf_event *event, int flags)
        if (!(hwc->state & PERF_HES_STOPPED)) {
                armpmu->disable(hwc, hwc->idx);
                barrier(); /* why? */
-               armpmu_event_update(event, hwc, hwc->idx);
+               armpmu_event_update(event, hwc, hwc->idx, 0);
                hwc->state |= PERF_HES_STOPPED | PERF_HES_UPTODATE;
        }
 }
@@ -624,6 +628,19 @@ static struct pmu pmu = {
 #include "perf_event_v6.c"
 #include "perf_event_v7.c"
 
+/*
+ * Ensure the PMU has sane values out of reset.
+ * This requires SMP to be available, so exists as a separate initcall.
+ */
+static int __init
+armpmu_reset(void)
+{
+       if (armpmu && armpmu->reset)
+               return on_each_cpu(armpmu->reset, NULL, 1);
+       return 0;
+}
+arch_initcall(armpmu_reset);
+
 static int __init
 init_hw_perf_events(void)
 {
index 6fc2d22..f1e8dd9 100644 (file)
@@ -474,7 +474,7 @@ armv6pmu_handle_irq(int irq_num,
                        continue;
 
                hwc = &event->hw;
-               armpmu_event_update(event, hwc, idx);
+               armpmu_event_update(event, hwc, idx, 1);
                data.period = event->hw.last_period;
                if (!armpmu_event_set_period(event, hwc, idx))
                        continue;
index 2e14025..4960686 100644 (file)
@@ -466,6 +466,7 @@ static inline unsigned long armv7_pmnc_read(void)
 static inline void armv7_pmnc_write(unsigned long val)
 {
        val &= ARMV7_PMNC_MASK;
+       isb();
        asm volatile("mcr p15, 0, %0, c9, c12, 0" : : "r"(val));
 }
 
@@ -502,6 +503,7 @@ static inline int armv7_pmnc_select_counter(unsigned int idx)
 
        val = (idx - ARMV7_EVENT_CNT_TO_CNTx) & ARMV7_SELECT_MASK;
        asm volatile("mcr p15, 0, %0, c9, c12, 5" : : "r" (val));
+       isb();
 
        return idx;
 }
@@ -780,7 +782,7 @@ static irqreturn_t armv7pmu_handle_irq(int irq_num, void *dev)
                        continue;
 
                hwc = &event->hw;
-               armpmu_event_update(event, hwc, idx);
+               armpmu_event_update(event, hwc, idx, 1);
                data.period = event->hw.last_period;
                if (!armpmu_event_set_period(event, hwc, idx))
                        continue;
@@ -847,6 +849,18 @@ static int armv7pmu_get_event_idx(struct cpu_hw_events *cpuc,
        }
 }
 
+static void armv7pmu_reset(void *info)
+{
+       u32 idx, nb_cnt = armpmu->num_events;
+
+       /* The counter and interrupt enable registers are unknown at reset. */
+       for (idx = 1; idx < nb_cnt; ++idx)
+               armv7pmu_disable_event(NULL, idx);
+
+       /* Initialize & Reset PMNC: C and P bits */
+       armv7_pmnc_write(ARMV7_PMNC_P | ARMV7_PMNC_C);
+}
+
 static struct arm_pmu armv7pmu = {
        .handle_irq             = armv7pmu_handle_irq,
        .enable                 = armv7pmu_enable_event,
@@ -856,17 +870,15 @@ static struct arm_pmu armv7pmu = {
        .get_event_idx          = armv7pmu_get_event_idx,
        .start                  = armv7pmu_start,
        .stop                   = armv7pmu_stop,
+       .reset                  = armv7pmu_reset,
        .raw_event_mask         = 0xFF,
        .max_period             = (1LLU << 32) - 1,
 };
 
-static u32 __init armv7_reset_read_pmnc(void)
+static u32 __init armv7_read_num_pmnc_events(void)
 {
        u32 nb_cnt;
 
-       /* Initialize & Reset PMNC: C and P bits */
-       armv7_pmnc_write(ARMV7_PMNC_P | ARMV7_PMNC_C);
-
        /* Read the nb of CNTx counters supported from PMNC */
        nb_cnt = (armv7_pmnc_read() >> ARMV7_PMNC_N_SHIFT) & ARMV7_PMNC_N_MASK;
 
@@ -880,7 +892,7 @@ static const struct arm_pmu *__init armv7_a8_pmu_init(void)
        armv7pmu.name           = "ARMv7 Cortex-A8";
        armv7pmu.cache_map      = &armv7_a8_perf_cache_map;
        armv7pmu.event_map      = &armv7_a8_perf_map;
-       armv7pmu.num_events     = armv7_reset_read_pmnc();
+       armv7pmu.num_events     = armv7_read_num_pmnc_events();
        return &armv7pmu;
 }
 
@@ -890,7 +902,7 @@ static const struct arm_pmu *__init armv7_a9_pmu_init(void)
        armv7pmu.name           = "ARMv7 Cortex-A9";
        armv7pmu.cache_map      = &armv7_a9_perf_cache_map;
        armv7pmu.event_map      = &armv7_a9_perf_map;
-       armv7pmu.num_events     = armv7_reset_read_pmnc();
+       armv7pmu.num_events     = armv7_read_num_pmnc_events();
        return &armv7pmu;
 }
 #else
index 28cd3b0..39affbe 100644 (file)
@@ -246,7 +246,7 @@ xscale1pmu_handle_irq(int irq_num, void *dev)
                        continue;
 
                hwc = &event->hw;
-               armpmu_event_update(event, hwc, idx);
+               armpmu_event_update(event, hwc, idx, 1);
                data.period = event->hw.last_period;
                if (!armpmu_event_set_period(event, hwc, idx))
                        continue;
@@ -578,7 +578,7 @@ xscale2pmu_handle_irq(int irq_num, void *dev)
                        continue;
 
                hwc = &event->hw;
-               armpmu_event_update(event, hwc, idx);
+               armpmu_event_update(event, hwc, idx, 1);
                data.period = event->hw.last_period;
                if (!armpmu_event_set_period(event, hwc, idx))
                        continue;
index bfad698..6398ead 100644 (file)
@@ -119,11 +119,19 @@ ENTRY(cpu_resume)
 #else
        ldr     r0, sleep_save_sp       @ stack phys addr
 #endif
-       msr     cpsr_c, #PSR_I_BIT | PSR_F_BIT | SVC_MODE @ set SVC, irqs off
+       setmode PSR_I_BIT | PSR_F_BIT | SVC_MODE, r1  @ set SVC, irqs off
 #ifdef MULTI_CPU
-       ldmia   r0!, {r1, sp, lr, pc}   @ load v:p, stack, return fn, resume fn
+       @ load v:p, stack, return fn, resume fn
+  ARM( ldmia   r0!, {r1, sp, lr, pc}   )
+THUMB( ldmia   r0!, {r1, r2, r3, r4}   )
+THUMB( mov     sp, r2                  )
+THUMB( mov     lr, r3                  )
+THUMB( bx      r4                      )
 #else
-       ldmia   r0!, {r1, sp, lr}       @ load v:p, stack, return fn
+       @ load v:p, stack, return fn
+  ARM( ldmia   r0!, {r1, sp, lr}       )
+THUMB( ldmia   r0!, {r1, r2, lr}       )
+THUMB( mov     sp, r2                  )
        b       cpu_do_resume
 #endif
 ENDPROC(cpu_resume)
index 5eec099..56b930a 100644 (file)
@@ -255,6 +255,7 @@ config MACH_IMX27_VISSTRIM_M10
        bool "Vista Silicon i.MX27 Visstrim_m10"
        select SOC_IMX27
        select IMX_HAVE_PLATFORM_IMX_I2C
+       select IMX_HAVE_PLATFORM_IMX_SSI
        select IMX_HAVE_PLATFORM_IMX_UART
        select IMX_HAVE_PLATFORM_MXC_MMC
        select IMX_HAVE_PLATFORM_MXC_EHCI
index cb705c2..6269053 100644 (file)
@@ -34,6 +34,7 @@
 #include <mach/mx25.h>
 #include <mach/imx-uart.h>
 #include <mach/audmux.h>
+#include <mach/esdhc.h>
 
 #include "devices-imx25.h"
 
@@ -242,6 +243,11 @@ struct imx_ssi_platform_data eukrea_mbimxsd_ssi_pdata __initconst = {
        .flags = IMX_SSI_SYN | IMX_SSI_NET | IMX_SSI_USE_I2S_SLAVE,
 };
 
+static struct esdhc_platform_data sd1_pdata = {
+       .cd_gpio = GPIO_SD1CD,
+       .wp_gpio = -EINVAL,
+};
+
 /*
  * system init for baseboard usage. Will be called by cpuimx25 init.
  *
@@ -275,7 +281,7 @@ void __init eukrea_mbimxsd25_baseboard_init(void)
        imx25_add_imx_ssi(0, &eukrea_mbimxsd_ssi_pdata);
 
        imx25_add_flexcan1(NULL);
-       imx25_add_sdhci_esdhc_imx(0, NULL);
+       imx25_add_sdhci_esdhc_imx(0, &sd1_pdata);
 
        gpio_request(GPIO_LED1, "LED1");
        gpio_direction_output(GPIO_LED1, 1);
index 0a95063..17de0bf 100644 (file)
@@ -57,6 +57,12 @@ static struct mvsdio_platform_data sheeva_esata_mvsdio_data = {
 };
 
 static struct gpio_led sheevaplug_led_pins[] = {
+       {
+               .name                   = "plug:red:misc",
+               .default_trigger        = "none",
+               .gpio                   = 46,
+               .active_low             = 1,
+       },
        {
                .name                   = "plug:green:health",
                .default_trigger        = "default-on",
@@ -80,6 +86,7 @@ static struct platform_device sheevaplug_leds = {
 
 static unsigned int sheevaplug_mpp_config[] __initdata = {
        MPP29_GPIO,     /* USB Power Enable */
+       MPP46_GPIO,     /* LED Red */
        MPP49_GPIO,     /* LED */
        0
 };
index 8076147..2e288b3 100644 (file)
@@ -43,6 +43,7 @@
 #include <mach/ipu.h>
 #include <mach/mx3fb.h>
 #include <mach/audmux.h>
+#include <mach/esdhc.h>
 
 #include "devices-imx35.h"
 #include "devices.h"
@@ -163,11 +164,14 @@ static iomux_v3_cfg_t eukrea_mbimxsd_pads[] = {
        MX35_PAD_SD1_DATA1__ESDHC1_DAT1,
        MX35_PAD_SD1_DATA2__ESDHC1_DAT2,
        MX35_PAD_SD1_DATA3__ESDHC1_DAT3,
+       /* SD1 CD */
+       MX35_PAD_LD18__GPIO3_24,
 };
 
 #define GPIO_LED1      IMX_GPIO_NR(3, 29)
 #define GPIO_SWITCH1   IMX_GPIO_NR(3, 25)
-#define GPIO_LCDPWR    (4)
+#define GPIO_LCDPWR    IMX_GPIO_NR(1, 4)
+#define GPIO_SD1CD     IMX_GPIO_NR(3, 24)
 
 static void eukrea_mbimxsd_lcd_power_set(struct plat_lcd_data *pd,
                                   unsigned int power)
@@ -254,6 +258,11 @@ struct imx_ssi_platform_data eukrea_mbimxsd_ssi_pdata __initconst = {
        .flags = IMX_SSI_SYN | IMX_SSI_NET | IMX_SSI_USE_I2S_SLAVE,
 };
 
+static struct esdhc_platform_data sd1_pdata = {
+       .cd_gpio = GPIO_SD1CD,
+       .wp_gpio = -EINVAL,
+};
+
 /*
  * system init for baseboard usage. Will be called by cpuimx35 init.
  *
@@ -289,7 +298,7 @@ void __init eukrea_mbimxsd35_baseboard_init(void)
        imx35_add_imx_ssi(0, &eukrea_mbimxsd_ssi_pdata);
 
        imx35_add_flexcan1(NULL);
-       imx35_add_sdhci_esdhc_imx(0, NULL);
+       imx35_add_sdhci_esdhc_imx(0, &sd1_pdata);
 
        gpio_request(GPIO_LED1, "LED1");
        gpio_direction_output(GPIO_LED1, 1);
@@ -301,7 +310,6 @@ void __init eukrea_mbimxsd35_baseboard_init(void)
 
        gpio_request(GPIO_LCDPWR, "LCDPWR");
        gpio_direction_output(GPIO_LCDPWR, 1);
-       gpio_free(GPIO_LCDPWR);
 
        i2c_register_board_info(0, eukrea_mbimxsd_i2c_devices,
                                ARRAY_SIZE(eukrea_mbimxsd_i2c_devices));
index b3ecfb2..036ba1a 100644 (file)
@@ -40,6 +40,7 @@
 #include <mach/mx3fb.h>
 #include <mach/ulpi.h>
 #include <mach/audmux.h>
+#include <mach/esdhc.h>
 
 #include "devices-imx35.h"
 #include "devices.h"
@@ -217,11 +218,15 @@ static iomux_v3_cfg_t pcm043_pads[] = {
        MX35_PAD_SD1_DATA1__ESDHC1_DAT1,
        MX35_PAD_SD1_DATA2__ESDHC1_DAT2,
        MX35_PAD_SD1_DATA3__ESDHC1_DAT3,
+       MX35_PAD_ATA_DATA10__GPIO2_23, /* WriteProtect */
+       MX35_PAD_ATA_DATA11__GPIO2_24, /* CardDetect */
 };
 
 #define AC97_GPIO_TXFS IMX_GPIO_NR(2, 31)
 #define AC97_GPIO_TXD  IMX_GPIO_NR(2, 28)
 #define AC97_GPIO_RESET        IMX_GPIO_NR(2, 0)
+#define SD1_GPIO_WP    IMX_GPIO_NR(2, 23)
+#define SD1_GPIO_CD    IMX_GPIO_NR(2, 24)
 
 static void pcm043_ac97_warm_reset(struct snd_ac97 *ac97)
 {
@@ -346,6 +351,11 @@ static int __init pcm043_otg_mode(char *options)
 }
 __setup("otg_mode=", pcm043_otg_mode);
 
+static struct esdhc_platform_data sd1_pdata = {
+       .wp_gpio = SD1_GPIO_WP,
+       .cd_gpio = SD1_GPIO_CD,
+};
+
 /*
  * Board specific initialization.
  */
@@ -395,7 +405,7 @@ static void __init pcm043_init(void)
                imx35_add_fsl_usb2_udc(&otg_device_pdata);
 
        imx35_add_flexcan1(NULL);
-       imx35_add_sdhci_esdhc_imx(0, NULL);
+       imx35_add_sdhci_esdhc_imx(0, &sd1_pdata);
 }
 
 static void __init pcm043_timer_init(void)
index 83ee088..159340d 100644 (file)
@@ -165,6 +165,7 @@ config MACH_MX53_LOCO
        select IMX_HAVE_PLATFORM_IMX_I2C
        select IMX_HAVE_PLATFORM_IMX_UART
        select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
+       select IMX_HAVE_PLATFORM_GPIO_KEYS
        help
          Include support for MX53 LOCO platform. This includes specific
          configurations for the board and its peripherals.
index 4f63048..0b9338c 100644 (file)
@@ -3,7 +3,7 @@
 #
 
 # Object file lists.
-obj-y   := cpu.o mm.o clock-mx51-mx53.o devices.o ehci.o
+obj-y   := cpu.o mm.o clock-mx51-mx53.o devices.o ehci.o system.o
 obj-$(CONFIG_SOC_IMX50) += mm-mx50.o
 
 obj-$(CONFIG_CPU_FREQ_IMX)    += cpu_op-mx51.o
index b2ecd19..bea4e41 100644 (file)
@@ -228,13 +228,12 @@ static inline void babbage_fec_reset(void)
        int ret;
 
        /* reset FEC PHY */
-       ret = gpio_request(BABBAGE_FEC_PHY_RESET, "fec-phy-reset");
+       ret = gpio_request_one(BABBAGE_FEC_PHY_RESET,
+                                       GPIOF_OUT_INIT_LOW, "fec-phy-reset");
        if (ret) {
                printk(KERN_ERR"failed to get GPIO_FEC_PHY_RESET: %d\n", ret);
                return;
        }
-       gpio_direction_output(BABBAGE_FEC_PHY_RESET, 0);
-       gpio_set_value(BABBAGE_FEC_PHY_RESET, 0);
        msleep(1);
        gpio_set_value(BABBAGE_FEC_PHY_RESET, 1);
 }
index 7b5735c..2af3f43 100644 (file)
@@ -34,7 +34,7 @@
 #include <mach/imx-uart.h>
 #include <mach/iomux-mx53.h>
 
-#define SMD_FEC_PHY_RST                IMX_GPIO_NR(7, 6)
+#define MX53_EVK_FEC_PHY_RST   IMX_GPIO_NR(7, 6)
 #define EVK_ECSPI1_CS0         IMX_GPIO_NR(2, 30)
 #define EVK_ECSPI1_CS1         IMX_GPIO_NR(3, 19)
 
@@ -82,15 +82,14 @@ static inline void mx53_evk_fec_reset(void)
        int ret;
 
        /* reset FEC PHY */
-       ret = gpio_request(SMD_FEC_PHY_RST, "fec-phy-reset");
+       ret = gpio_request_one(MX53_EVK_FEC_PHY_RST, GPIOF_OUT_INIT_LOW,
+                                                       "fec-phy-reset");
        if (ret) {
                printk(KERN_ERR"failed to get GPIO_FEC_PHY_RESET: %d\n", ret);
                return;
        }
-       gpio_direction_output(SMD_FEC_PHY_RST, 0);
-       gpio_set_value(SMD_FEC_PHY_RST, 0);
        msleep(1);
-       gpio_set_value(SMD_FEC_PHY_RST, 1);
+       gpio_set_value(MX53_EVK_FEC_PHY_RST, 1);
 }
 
 static struct fec_platform_data mx53_evk_fec_pdata = {
index 0a18f8d..10a1bea 100644 (file)
@@ -36,6 +36,9 @@
 #include "crm_regs.h"
 #include "devices-imx53.h"
 
+#define MX53_LOCO_POWER                        IMX_GPIO_NR(1, 8)
+#define MX53_LOCO_UI1                  IMX_GPIO_NR(2, 14)
+#define MX53_LOCO_UI2                  IMX_GPIO_NR(2, 15)
 #define LOCO_FEC_PHY_RST               IMX_GPIO_NR(7, 6)
 
 static iomux_v3_cfg_t mx53_loco_pads[] = {
@@ -180,6 +183,27 @@ static iomux_v3_cfg_t mx53_loco_pads[] = {
        MX53_PAD_GPIO_8__GPIO1_8,
 };
 
+#define GPIO_BUTTON(gpio_num, ev_code, act_low, descr, wake)   \
+{                                                              \
+       .gpio           = gpio_num,                             \
+       .type           = EV_KEY,                               \
+       .code           = ev_code,                              \
+       .active_low     = act_low,                              \
+       .desc           = "btn " descr,                         \
+       .wakeup         = wake,                                 \
+}
+
+static const struct gpio_keys_button loco_buttons[] __initconst = {
+       GPIO_BUTTON(MX53_LOCO_POWER, KEY_POWER, 1, "power", 0),
+       GPIO_BUTTON(MX53_LOCO_UI1, KEY_VOLUMEUP, 1, "volume-up", 0),
+       GPIO_BUTTON(MX53_LOCO_UI2, KEY_VOLUMEDOWN, 1, "volume-down", 0),
+};
+
+static const struct gpio_keys_platform_data loco_button_data __initconst = {
+       .buttons        = loco_buttons,
+       .nbuttons       = ARRAY_SIZE(loco_buttons),
+};
+
 static inline void mx53_loco_fec_reset(void)
 {
        int ret;
@@ -215,6 +239,7 @@ static void __init mx53_loco_board_init(void)
        imx53_add_imx_i2c(1, &mx53_loco_i2c_data);
        imx53_add_sdhci_esdhc_imx(0, NULL);
        imx53_add_sdhci_esdhc_imx(2, NULL);
+       imx_add_gpio_keys(&loco_button_data);
 }
 
 static void __init mx53_loco_timer_init(void)
index 652ace4..fdbc05e 100644 (file)
@@ -865,6 +865,13 @@ static struct clk aips_tz2_clk = {
        .disable = _clk_ccgr_disable_inwait,
 };
 
+static struct clk gpc_dvfs_clk = {
+       .enable_reg = MXC_CCM_CCGR5,
+       .enable_shift = MXC_CCM_CCGRx_CG12_OFFSET,
+       .enable = _clk_ccgr_enable,
+       .disable = _clk_ccgr_disable,
+};
+
 static struct clk gpt_32k_clk = {
        .id = 0,
        .parent = &ckil_clk,
@@ -1448,6 +1455,7 @@ static struct clk_lookup mx51_lookups[] = {
        _REGISTER_CLOCK("imx-ipuv3", NULL, ipu_clk)
        _REGISTER_CLOCK("imx-ipuv3", "di0", ipu_di0_clk)
        _REGISTER_CLOCK("imx-ipuv3", "di1", ipu_di1_clk)
+       _REGISTER_CLOCK(NULL, "gpc_dvfs", gpc_dvfs_clk)
 };
 
 static struct clk_lookup mx53_lookups[] = {
@@ -1511,6 +1519,7 @@ int __init mx51_clocks_init(unsigned long ckil, unsigned long osc,
        clk_enable(&iim_clk);
        mx51_revision();
        clk_disable(&iim_clk);
+       mx51_display_revision();
 
        /* move usb_phy_clk to 24MHz */
        clk_set_parent(&usb_phy1_clk, &osc_clk);
index df46b5e..472bdfa 100644 (file)
@@ -21,6 +21,7 @@
 static int cpu_silicon_rev = -1;
 
 #define IIM_SREV 0x24
+#define MX50_HW_ADADIG_DIGPROG 0xB0
 
 static int get_mx51_srev(void)
 {
@@ -51,6 +52,26 @@ int mx51_revision(void)
 }
 EXPORT_SYMBOL(mx51_revision);
 
+void mx51_display_revision(void)
+{
+       int rev;
+       char *srev;
+       rev = mx51_revision();
+
+       switch (rev) {
+       case IMX_CHIP_REVISION_2_0:
+               srev = IMX_CHIP_REVISION_2_0_STRING;
+               break;
+       case IMX_CHIP_REVISION_3_0:
+               srev = IMX_CHIP_REVISION_3_0_STRING;
+               break;
+       default:
+               srev = IMX_CHIP_REVISION_UNKNOWN_STRING;
+       }
+       printk(KERN_INFO "CPU identified as i.MX51, silicon rev %s\n", srev);
+}
+EXPORT_SYMBOL(mx51_display_revision);
+
 #ifdef CONFIG_NEON
 
 /*
@@ -107,6 +128,44 @@ int mx53_revision(void)
 }
 EXPORT_SYMBOL(mx53_revision);
 
+static int get_mx50_srev(void)
+{
+       void __iomem *anatop = ioremap(MX50_ANATOP_BASE_ADDR, SZ_8K);
+       u32 rev;
+
+       if (!anatop) {
+               cpu_silicon_rev = -EINVAL;
+               return 0;
+       }
+
+       rev = readl(anatop + MX50_HW_ADADIG_DIGPROG);
+       rev &= 0xff;
+
+       iounmap(anatop);
+       if (rev == 0x0)
+               return IMX_CHIP_REVISION_1_0;
+       else if (rev == 0x1)
+               return IMX_CHIP_REVISION_1_1;
+       return 0;
+}
+
+/*
+ * Returns:
+ *     the silicon revision of the cpu
+ *     -EINVAL - not a mx50
+ */
+int mx50_revision(void)
+{
+       if (!cpu_is_mx50())
+               return -EINVAL;
+
+       if (cpu_silicon_rev == -1)
+               cpu_silicon_rev = get_mx50_srev();
+
+       return cpu_silicon_rev;
+}
+EXPORT_SYMBOL(mx50_revision);
+
 static int __init post_cpu_init(void)
 {
        unsigned int reg;
index c372a43..e6c1119 100644 (file)
@@ -67,6 +67,10 @@ static iomux_v3_cfg_t eukrea_mbimxsd_pads[] = {
        MX51_PAD_SD1_DATA1__SD1_DATA1,
        MX51_PAD_SD1_DATA2__SD1_DATA2,
        MX51_PAD_SD1_DATA3__SD1_DATA3,
+       /* SD1 CD */
+       _MX51_PAD_GPIO1_0__SD1_CD | MUX_PAD_CTRL(PAD_CTL_PUS_22K_UP |
+                       PAD_CTL_PKE | PAD_CTL_SRE_FAST |
+                       PAD_CTL_DSE_HIGH | PAD_CTL_PUE | PAD_CTL_HYS),
 };
 
 #define GPIO_LED1      IMX_GPIO_NR(3, 30)
index 868af8f..d0c7075 100644 (file)
@@ -42,7 +42,6 @@
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/time.h>
-#include <asm/mach-types.h>
 
 #include "devices-imx51.h"
 #include "devices.h"
diff --git a/arch/arm/mach-mx5/system.c b/arch/arm/mach-mx5/system.c
new file mode 100644 (file)
index 0000000..76ae8dc
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <mach/hardware.h>
+#include "crm_regs.h"
+
+/* set cpu low power mode before WFI instruction. This function is called
+  * mx5 because it can be used for mx50, mx51, and mx53.*/
+void mx5_cpu_lp_set(enum mxc_cpu_pwr_mode mode)
+{
+       u32 plat_lpc, arm_srpgcr, ccm_clpcr;
+       u32 empgc0, empgc1;
+       int stop_mode = 0;
+
+       /* always allow platform to issue a deep sleep mode request */
+       plat_lpc = __raw_readl(MXC_CORTEXA8_PLAT_LPC) &
+           ~(MXC_CORTEXA8_PLAT_LPC_DSM);
+       ccm_clpcr = __raw_readl(MXC_CCM_CLPCR) & ~(MXC_CCM_CLPCR_LPM_MASK);
+       arm_srpgcr = __raw_readl(MXC_SRPG_ARM_SRPGCR) & ~(MXC_SRPGCR_PCR);
+       empgc0 = __raw_readl(MXC_SRPG_EMPGC0_SRPGCR) & ~(MXC_SRPGCR_PCR);
+       empgc1 = __raw_readl(MXC_SRPG_EMPGC1_SRPGCR) & ~(MXC_SRPGCR_PCR);
+
+       switch (mode) {
+       case WAIT_CLOCKED:
+               break;
+       case WAIT_UNCLOCKED:
+               ccm_clpcr |= 0x1 << MXC_CCM_CLPCR_LPM_OFFSET;
+               break;
+       case WAIT_UNCLOCKED_POWER_OFF:
+       case STOP_POWER_OFF:
+               plat_lpc |= MXC_CORTEXA8_PLAT_LPC_DSM
+                           | MXC_CORTEXA8_PLAT_LPC_DBG_DSM;
+               if (mode == WAIT_UNCLOCKED_POWER_OFF) {
+                       ccm_clpcr |= 0x1 << MXC_CCM_CLPCR_LPM_OFFSET;
+                       ccm_clpcr &= ~MXC_CCM_CLPCR_VSTBY;
+                       ccm_clpcr &= ~MXC_CCM_CLPCR_SBYOS;
+                       stop_mode = 0;
+               } else {
+                       ccm_clpcr |= 0x2 << MXC_CCM_CLPCR_LPM_OFFSET;
+                       ccm_clpcr |= 0x3 << MXC_CCM_CLPCR_STBY_COUNT_OFFSET;
+                       ccm_clpcr |= MXC_CCM_CLPCR_VSTBY;
+                       ccm_clpcr |= MXC_CCM_CLPCR_SBYOS;
+                       stop_mode = 1;
+               }
+               arm_srpgcr |= MXC_SRPGCR_PCR;
+
+               if (tzic_enable_wake(1) != 0)
+                       return;
+               break;
+       case STOP_POWER_ON:
+               ccm_clpcr |= 0x2 << MXC_CCM_CLPCR_LPM_OFFSET;
+               break;
+       default:
+               printk(KERN_WARNING "UNKNOWN cpu power mode: %d\n", mode);
+               return;
+       }
+
+       __raw_writel(plat_lpc, MXC_CORTEXA8_PLAT_LPC);
+       __raw_writel(ccm_clpcr, MXC_CCM_CLPCR);
+       __raw_writel(arm_srpgcr, MXC_SRPG_ARM_SRPGCR);
+
+       /* Enable NEON SRPG for all but MX50TO1.0. */
+       if (mx50_revision() != IMX_CHIP_REVISION_1_0)
+               __raw_writel(arm_srpgcr, MXC_SRPG_NEON_SRPGCR);
+
+       if (stop_mode) {
+               empgc0 |= MXC_SRPGCR_PCR;
+               empgc1 |= MXC_SRPGCR_PCR;
+
+               __raw_writel(empgc0, MXC_SRPG_EMPGC0_SRPGCR);
+               __raw_writel(empgc1, MXC_SRPG_EMPGC1_SRPGCR);
+       }
+}
index 4f6f174..4522fbb 100644 (file)
@@ -22,6 +22,7 @@ config MACH_MX23EVK
        select SOC_IMX23
        select MXS_HAVE_AMBA_DUART
        select MXS_HAVE_PLATFORM_AUART
+       select MXS_HAVE_PLATFORM_MXS_MMC
        select MXS_HAVE_PLATFORM_MXSFB
        default y
        help
@@ -35,6 +36,7 @@ config MACH_MX28EVK
        select MXS_HAVE_PLATFORM_AUART
        select MXS_HAVE_PLATFORM_FEC
        select MXS_HAVE_PLATFORM_FLEXCAN
+       select MXS_HAVE_PLATFORM_MXS_MMC
        select MXS_HAVE_PLATFORM_MXSFB
        select MXS_OCOTP
        default y
index d133c7f..c3577ea 100644 (file)
@@ -521,6 +521,15 @@ static int clk_misc_init(void)
        __raw_writel(BM_CLKCTRL_CPU_INTERRUPT_WAIT,
                        CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_SET);
 
+       /*
+        * 480 MHz seems too high to be ssp clock source directly,
+        * so set frac to get a 288 MHz ref_io.
+        */
+       reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC);
+       reg &= ~BM_CLKCTRL_FRAC_IOFRAC;
+       reg |= 30 << BP_CLKCTRL_FRAC_IOFRAC;
+       __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC);
+
        return 0;
 }
 
@@ -528,6 +537,12 @@ int __init mx23_clocks_init(void)
 {
        clk_misc_init();
 
+       /*
+        * source ssp clock from ref_io than ref_xtal,
+        * as ref_xtal only provides 24 MHz as maximum.
+        */
+       clk_set_parent(&ssp_clk, &ref_io_clk);
+
        clk_enable(&cpu_clk);
        clk_enable(&hbus_clk);
        clk_enable(&xbus_clk);
index 5e489a2..1ad97fe 100644 (file)
@@ -618,6 +618,8 @@ static struct clk_lookup lookups[] = {
        _REGISTER_CLOCK("pll2", NULL, pll2_clk)
        _REGISTER_CLOCK("mxs-dma-apbh", NULL, hbus_clk)
        _REGISTER_CLOCK("mxs-dma-apbx", NULL, xbus_clk)
+       _REGISTER_CLOCK("mxs-mmc.0", NULL, ssp0_clk)
+       _REGISTER_CLOCK("mxs-mmc.1", NULL, ssp1_clk)
        _REGISTER_CLOCK("flexcan.0", NULL, can0_clk)
        _REGISTER_CLOCK("flexcan.1", NULL, can1_clk)
        _REGISTER_CLOCK(NULL, "usb0", usb0_clk)
@@ -737,6 +739,15 @@ static int clk_misc_init(void)
        reg |= BM_CLKCTRL_ENET_CLK_OUT_EN;
        __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_ENET);
 
+       /*
+        * 480 MHz seems too high to be ssp clock source directly,
+        * so set frac0 to get a 288 MHz ref_io0.
+        */
+       reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC0);
+       reg &= ~BM_CLKCTRL_FRAC0_IO0FRAC;
+       reg |= 30 << BP_CLKCTRL_FRAC0_IO0FRAC;
+       __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC0);
+
        return 0;
 }
 
@@ -744,6 +755,13 @@ int __init mx28_clocks_init(void)
 {
        clk_misc_init();
 
+       /*
+        * source ssp clock from ref_io0 than ref_xtal,
+        * as ref_xtal only provides 24 MHz as maximum.
+        */
+       clk_set_parent(&ssp0_clk, &ref_io0_clk);
+       clk_set_parent(&ssp1_clk, &ref_io0_clk);
+
        clk_enable(&cpu_clk);
        clk_enable(&hbus_clk);
        clk_enable(&xbus_clk);
index c7e14f4..c6f345f 100644 (file)
@@ -21,6 +21,10 @@ extern const struct mxs_auart_data mx23_auart_data[] __initconst;
 #define mx23_add_auart0()              mx23_add_auart(0)
 #define mx23_add_auart1()              mx23_add_auart(1)
 
+extern const struct mxs_mxs_mmc_data mx23_mxs_mmc_data[] __initconst;
+#define mx23_add_mxs_mmc(id, pdata) \
+       mxs_add_mxs_mmc(&mx23_mxs_mmc_data[id], pdata)
+
 #define mx23_add_mxs_pwm(id)           mxs_add_mxs_pwm(MX23_PWM_BASE_ADDR, id)
 
 struct platform_device *__init mx23_add_mxsfb(
index 9d08555..c473edd 100644 (file)
@@ -37,6 +37,10 @@ extern const struct mxs_flexcan_data mx28_flexcan_data[] __initconst;
 extern const struct mxs_i2c_data mx28_mxs_i2c_data[] __initconst;
 #define mx28_add_mxs_i2c(id)           mxs_add_mxs_i2c(&mx28_mxs_i2c_data[id])
 
+extern const struct mxs_mxs_mmc_data mx28_mxs_mmc_data[] __initconst;
+#define mx28_add_mxs_mmc(id, pdata) \
+       mxs_add_mxs_mmc(&mx28_mxs_mmc_data[id], pdata)
+
 #define mx28_add_mxs_pwm(id)           mxs_add_mxs_pwm(MX28_PWM_BASE_ADDR, id)
 
 struct platform_device *__init mx28_add_mxsfb(
index 1451ad0..acf9eea 100644 (file)
@@ -15,6 +15,9 @@ config MXS_HAVE_PLATFORM_FLEXCAN
 config MXS_HAVE_PLATFORM_MXS_I2C
        bool
 
+config MXS_HAVE_PLATFORM_MXS_MMC
+       bool
+
 config MXS_HAVE_PLATFORM_MXS_PWM
        bool
 
index 0d9bea3..324f282 100644 (file)
@@ -4,5 +4,6 @@ obj-y += platform-dma.o
 obj-$(CONFIG_MXS_HAVE_PLATFORM_FEC) += platform-fec.o
 obj-$(CONFIG_MXS_HAVE_PLATFORM_FLEXCAN) += platform-flexcan.o
 obj-$(CONFIG_MXS_HAVE_PLATFORM_MXS_I2C) += platform-mxs-i2c.o
+obj-$(CONFIG_MXS_HAVE_PLATFORM_MXS_MMC) += platform-mxs-mmc.o
 obj-$(CONFIG_MXS_HAVE_PLATFORM_MXS_PWM) += platform-mxs-pwm.o
 obj-$(CONFIG_MXS_HAVE_PLATFORM_MXSFB) += platform-mxsfb.o
diff --git a/arch/arm/mach-mxs/devices/platform-mxs-mmc.c b/arch/arm/mach-mxs/devices/platform-mxs-mmc.c
new file mode 100644 (file)
index 0000000..382dacb
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * Copyright 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+
+#include <linux/compiler.h>
+#include <linux/err.h>
+#include <linux/init.h>
+
+#include <mach/mx23.h>
+#include <mach/mx28.h>
+#include <mach/devices-common.h>
+
+#define mxs_mxs_mmc_data_entry_single(soc, _id, hwid)                  \
+       {                                                               \
+               .id = _id,                                              \
+               .iobase = soc ## _SSP ## hwid ## _BASE_ADDR,            \
+               .dma = soc ## _DMA_SSP ## hwid,                         \
+               .irq_err = soc ## _INT_SSP ## hwid ## _ERROR,           \
+               .irq_dma = soc ## _INT_SSP ## hwid ## _DMA,             \
+       }
+
+#define mxs_mxs_mmc_data_entry(soc, _id, hwid)                         \
+       [_id] = mxs_mxs_mmc_data_entry_single(soc, _id, hwid)
+
+
+#ifdef CONFIG_SOC_IMX23
+const struct mxs_mxs_mmc_data mx23_mxs_mmc_data[] __initconst = {
+       mxs_mxs_mmc_data_entry(MX23, 0, 1),
+       mxs_mxs_mmc_data_entry(MX23, 1, 2),
+};
+#endif
+
+#ifdef CONFIG_SOC_IMX28
+const struct mxs_mxs_mmc_data mx28_mxs_mmc_data[] __initconst = {
+       mxs_mxs_mmc_data_entry(MX28, 0, 0),
+       mxs_mxs_mmc_data_entry(MX28, 1, 1),
+};
+#endif
+
+struct platform_device *__init mxs_add_mxs_mmc(
+               const struct mxs_mxs_mmc_data *data,
+               const struct mxs_mmc_platform_data *pdata)
+{
+       struct resource res[] = {
+               {
+                       .start  = data->iobase,
+                       .end    = data->iobase + SZ_8K - 1,
+                       .flags  = IORESOURCE_MEM,
+               }, {
+                       .start  = data->dma,
+                       .end    = data->dma,
+                       .flags  = IORESOURCE_DMA,
+               }, {
+                       .start  = data->irq_err,
+                       .end    = data->irq_err,
+                       .flags  = IORESOURCE_IRQ,
+               }, {
+                       .start  = data->irq_dma,
+                       .end    = data->irq_dma,
+                       .flags  = IORESOURCE_IRQ,
+               },
+       };
+
+       return mxs_add_platform_device("mxs-mmc", data->id,
+                       res, ARRAY_SIZE(res), pdata, sizeof(*pdata));
+}
index 71f2448..c5137f1 100644 (file)
@@ -73,6 +73,19 @@ struct mxs_i2c_data {
 };
 struct platform_device * __init mxs_add_mxs_i2c(const struct mxs_i2c_data *data);
 
+/* mmc */
+#include <mach/mmc.h>
+struct mxs_mxs_mmc_data {
+       int id;
+       resource_size_t iobase;
+       resource_size_t dma;
+       resource_size_t irq_err;
+       resource_size_t irq_dma;
+};
+struct platform_device *__init mxs_add_mxs_mmc(
+               const struct mxs_mxs_mmc_data *data,
+               const struct mxs_mmc_platform_data *pdata);
+
 /* pwm */
 struct platform_device *__init mxs_add_mxs_pwm(
                resource_size_t iobase, int id);
index a66994f..214e5b6 100644 (file)
@@ -28,6 +28,8 @@
 
 #define MX23EVK_LCD_ENABLE     MXS_GPIO_NR(1, 18)
 #define MX23EVK_BL_ENABLE      MXS_GPIO_NR(1, 28)
+#define MX23EVK_MMC0_WRITE_PROTECT     MXS_GPIO_NR(1, 30)
+#define MX23EVK_MMC0_SLOT_POWER                MXS_GPIO_NR(1, 29)
 
 static const iomux_cfg_t mx23evk_pads[] __initconst = {
        /* duart */
@@ -73,6 +75,36 @@ static const iomux_cfg_t mx23evk_pads[] __initconst = {
        MX23_PAD_LCD_RESET__GPIO_1_18 | MXS_PAD_CTRL,
        /* backlight control */
        MX23_PAD_PWM2__GPIO_1_28 | MXS_PAD_CTRL,
+
+       /* mmc */
+       MX23_PAD_SSP1_DATA0__SSP1_DATA0 |
+               (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+       MX23_PAD_SSP1_DATA1__SSP1_DATA1 |
+               (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+       MX23_PAD_SSP1_DATA2__SSP1_DATA2 |
+               (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+       MX23_PAD_SSP1_DATA3__SSP1_DATA3 |
+               (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+       MX23_PAD_GPMI_D08__SSP1_DATA4 |
+               (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+       MX23_PAD_GPMI_D09__SSP1_DATA5 |
+               (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+       MX23_PAD_GPMI_D10__SSP1_DATA6 |
+               (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+       MX23_PAD_GPMI_D11__SSP1_DATA7 |
+               (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+       MX23_PAD_SSP1_CMD__SSP1_CMD |
+               (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+       MX23_PAD_SSP1_DETECT__SSP1_DETECT |
+               (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+       MX23_PAD_SSP1_SCK__SSP1_SCK |
+               (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+       /* write protect */
+       MX23_PAD_PWM4__GPIO_1_30 |
+               (MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+       /* slot power enable */
+       MX23_PAD_PWM3__GPIO_1_29 |
+               (MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
 };
 
 /* mxsfb (lcdif) */
@@ -101,6 +133,11 @@ static const struct mxsfb_platform_data mx23evk_mxsfb_pdata __initconst = {
        .ld_intf_width  = STMLCDIF_24BIT,
 };
 
+static struct mxs_mmc_platform_data mx23evk_mmc_pdata __initdata = {
+       .wp_gpio = MX23EVK_MMC0_WRITE_PROTECT,
+       .flags = SLOTF_8_BIT_CAPABLE,
+};
+
 static void __init mx23evk_init(void)
 {
        int ret;
@@ -110,6 +147,13 @@ static void __init mx23evk_init(void)
        mx23_add_duart();
        mx23_add_auart0();
 
+       /* power on mmc slot by writing 0 to the gpio */
+       ret = gpio_request_one(MX23EVK_MMC0_SLOT_POWER, GPIOF_DIR_OUT,
+                              "mmc0-slot-power");
+       if (ret)
+               pr_warn("failed to request gpio mmc0-slot-power: %d\n", ret);
+       mx23_add_mxs_mmc(0, &mx23evk_mmc_pdata);
+
        ret = gpio_request_one(MX23EVK_LCD_ENABLE, GPIOF_DIR_OUT, "lcd-enable");
        if (ret)
                pr_warn("failed to request gpio lcd-enable: %d\n", ret);
index 08002d0..bb329b9 100644 (file)
 #define MX28EVK_LCD_ENABLE     MXS_GPIO_NR(3, 30)
 #define MX28EVK_FEC_PHY_RESET  MXS_GPIO_NR(4, 13)
 
+#define MX28EVK_MMC0_WRITE_PROTECT     MXS_GPIO_NR(2, 12)
+#define MX28EVK_MMC1_WRITE_PROTECT     MXS_GPIO_NR(0, 28)
+#define MX28EVK_MMC0_SLOT_POWER                MXS_GPIO_NR(3, 28)
+#define MX28EVK_MMC1_SLOT_POWER                MXS_GPIO_NR(3, 29)
+
 static const iomux_cfg_t mx28evk_pads[] __initconst = {
        /* duart */
        MX28_PAD_PWM0__DUART_RX | MXS_PAD_CTRL,
@@ -115,6 +120,65 @@ static const iomux_cfg_t mx28evk_pads[] __initconst = {
        MX28_PAD_LCD_RESET__GPIO_3_30 | MXS_PAD_CTRL,
        /* backlight control */
        MX28_PAD_PWM2__GPIO_3_18 | MXS_PAD_CTRL,
+       /* mmc0 */
+       MX28_PAD_SSP0_DATA0__SSP0_D0 |
+               (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+       MX28_PAD_SSP0_DATA1__SSP0_D1 |
+               (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+       MX28_PAD_SSP0_DATA2__SSP0_D2 |
+               (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+       MX28_PAD_SSP0_DATA3__SSP0_D3 |
+               (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+       MX28_PAD_SSP0_DATA4__SSP0_D4 |
+               (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+       MX28_PAD_SSP0_DATA5__SSP0_D5 |
+               (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+       MX28_PAD_SSP0_DATA6__SSP0_D6 |
+               (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+       MX28_PAD_SSP0_DATA7__SSP0_D7 |
+               (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+       MX28_PAD_SSP0_CMD__SSP0_CMD |
+               (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+       MX28_PAD_SSP0_DETECT__SSP0_CARD_DETECT |
+               (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+       MX28_PAD_SSP0_SCK__SSP0_SCK |
+               (MXS_PAD_12MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+       /* write protect */
+       MX28_PAD_SSP1_SCK__GPIO_2_12 |
+               (MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+       /* slot power enable */
+       MX28_PAD_PWM3__GPIO_3_28 |
+               (MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+
+       /* mmc1 */
+       MX28_PAD_GPMI_D00__SSP1_D0 |
+               (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+       MX28_PAD_GPMI_D01__SSP1_D1 |
+               (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+       MX28_PAD_GPMI_D02__SSP1_D2 |
+               (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+       MX28_PAD_GPMI_D03__SSP1_D3 |
+               (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+       MX28_PAD_GPMI_D04__SSP1_D4 |
+               (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+       MX28_PAD_GPMI_D05__SSP1_D5 |
+               (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+       MX28_PAD_GPMI_D06__SSP1_D6 |
+               (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+       MX28_PAD_GPMI_D07__SSP1_D7 |
+               (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+       MX28_PAD_GPMI_RDY1__SSP1_CMD |
+               (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+       MX28_PAD_GPMI_RDY0__SSP1_CARD_DETECT |
+               (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+       MX28_PAD_GPMI_WRN__SSP1_SCK |
+               (MXS_PAD_12MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+       /* write protect */
+       MX28_PAD_GPMI_RESETN__GPIO_0_28 |
+               (MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+       /* slot power enable */
+       MX28_PAD_PWM4__GPIO_3_29 |
+               (MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
 };
 
 /* fec */
@@ -258,6 +322,18 @@ static const struct mxsfb_platform_data mx28evk_mxsfb_pdata __initconst = {
        .ld_intf_width  = STMLCDIF_24BIT,
 };
 
+static struct mxs_mmc_platform_data mx28evk_mmc_pdata[] __initdata = {
+       {
+               /* mmc0 */
+               .wp_gpio = MX28EVK_MMC0_WRITE_PROTECT,
+               .flags = SLOTF_8_BIT_CAPABLE,
+       }, {
+               /* mmc1 */
+               .wp_gpio = MX28EVK_MMC1_WRITE_PROTECT,
+               .flags = SLOTF_8_BIT_CAPABLE,
+       },
+};
+
 static void __init mx28evk_init(void)
 {
        int ret;
@@ -297,6 +373,19 @@ static void __init mx28evk_init(void)
                gpio_set_value(MX28EVK_BL_ENABLE, 1);
 
        mx28_add_mxsfb(&mx28evk_mxsfb_pdata);
+
+       /* power on mmc slot by writing 0 to the gpio */
+       ret = gpio_request_one(MX28EVK_MMC0_SLOT_POWER, GPIOF_DIR_OUT,
+                              "mmc0-slot-power");
+       if (ret)
+               pr_warn("failed to request gpio mmc0-slot-power: %d\n", ret);
+       mx28_add_mxs_mmc(0, &mx28evk_mmc_pdata[0]);
+
+       ret = gpio_request_one(MX28EVK_MMC1_SLOT_POWER, GPIOF_DIR_OUT,
+                              "mmc1-slot-power");
+       if (ret)
+               pr_warn("failed to request gpio mmc1-slot-power: %d\n", ret);
+       mx28_add_mxs_mmc(1, &mx28evk_mmc_pdata[1]);
 }
 
 static void __init mx28evk_timer_init(void)
index fa0b154..0fcff47 100644 (file)
@@ -45,7 +45,7 @@ static const iomux_cfg_t tx28_fec_gpio_pads[] __initconst = {
 };
 
 #define FEC_MODE (MXS_PAD_8MA | MXS_PAD_PULLUP | MXS_PAD_3V3)
-static const iomux_cfg_t tx28_fec_pads[] __initconst = {
+static const iomux_cfg_t tx28_fec0_pads[] __initconst = {
        MX28_PAD_ENET0_MDC__ENET0_MDC | FEC_MODE,
        MX28_PAD_ENET0_MDIO__ENET0_MDIO | FEC_MODE,
        MX28_PAD_ENET0_RX_EN__ENET0_RX_EN | FEC_MODE,
@@ -57,7 +57,20 @@ static const iomux_cfg_t tx28_fec_pads[] __initconst = {
        MX28_PAD_ENET_CLK__CLKCTRL_ENET | FEC_MODE,
 };
 
-static const struct fec_platform_data tx28_fec_data __initconst = {
+static const iomux_cfg_t tx28_fec1_pads[] __initconst = {
+       MX28_PAD_ENET0_RXD2__ENET1_RXD0,
+       MX28_PAD_ENET0_RXD3__ENET1_RXD1,
+       MX28_PAD_ENET0_TXD2__ENET1_TXD0,
+       MX28_PAD_ENET0_TXD3__ENET1_TXD1,
+       MX28_PAD_ENET0_COL__ENET1_TX_EN,
+       MX28_PAD_ENET0_CRS__ENET1_RX_EN,
+};
+
+static struct fec_platform_data tx28_fec0_data = {
+       .phy = PHY_INTERFACE_MODE_RMII,
+};
+
+static struct fec_platform_data tx28_fec1_data = {
        .phy = PHY_INTERFACE_MODE_RMII,
 };
 
@@ -108,15 +121,15 @@ int __init tx28_add_fec0(void)
        pr_debug("%s: Deasserting FEC PHY RESET\n", __func__);
        gpio_set_value(TX28_FEC_PHY_RESET, 1);
 
-       ret = mxs_iomux_setup_multiple_pads(tx28_fec_pads,
-                       ARRAY_SIZE(tx28_fec_pads));
+       ret = mxs_iomux_setup_multiple_pads(tx28_fec0_pads,
+                       ARRAY_SIZE(tx28_fec0_pads));
        if (ret) {
                pr_debug("%s: mxs_iomux_setup_multiple_pads() failed with rc: %d\n",
                                __func__, ret);
                goto free_gpios;
        }
-       pr_debug("%s: Registering FEC device\n", __func__);
-       mx28_add_fec(0, &tx28_fec_data);
+       pr_debug("%s: Registering FEC0 device\n", __func__);
+       mx28_add_fec(0, &tx28_fec0_data);
        return 0;
 
 free_gpios:
@@ -129,3 +142,19 @@ free_gpios:
 
        return ret;
 }
+
+int __init tx28_add_fec1(void)
+{
+       int ret;
+
+       ret = mxs_iomux_setup_multiple_pads(tx28_fec1_pads,
+                       ARRAY_SIZE(tx28_fec1_pads));
+       if (ret) {
+               pr_debug("%s: mxs_iomux_setup_multiple_pads() failed with rc: %d\n",
+                               __func__, ret);
+               return ret;
+       }
+       pr_debug("%s: Registering FEC1 device\n", __func__);
+       mx28_add_fec(1, &tx28_fec1_data);
+       return 0;
+}
index df9e1b6..8ed4254 100644 (file)
@@ -7,3 +7,4 @@
  * Free Software Foundation.
  */
 int __init tx28_add_fec0(void);
+int __init tx28_add_fec1(void);
index 8554707..edb1dd2 100644 (file)
@@ -402,7 +402,7 @@ static void ts78xx_fpga_supports(void)
                /* enable devices if magic matches */
                switch ((ts78xx_fpga.id >> 8) & 0xffffff) {
                case TS7800_FPGA_MAGIC:
-                       printk(KERN_WARNING "TS-7800 FPGA: unrecognized revision 0x%.2x\n",
+                       pr_warning("TS-7800 FPGA: unrecognized revision 0x%.2x\n",
                                        ts78xx_fpga.id & 0xff);
                        ts78xx_fpga.supports.ts_rtc.present = 1;
                        ts78xx_fpga.supports.ts_nand.present = 1;
@@ -423,7 +423,7 @@ static int ts78xx_fpga_load_devices(void)
        if (ts78xx_fpga.supports.ts_rtc.present == 1) {
                tmp = ts78xx_ts_rtc_load();
                if (tmp) {
-                       printk(KERN_INFO "TS-78xx: RTC not registered\n");
+                       pr_info("TS-78xx: RTC not registered\n");
                        ts78xx_fpga.supports.ts_rtc.present = 0;
                }
                ret |= tmp;
@@ -431,7 +431,7 @@ static int ts78xx_fpga_load_devices(void)
        if (ts78xx_fpga.supports.ts_nand.present == 1) {
                tmp = ts78xx_ts_nand_load();
                if (tmp) {
-                       printk(KERN_INFO "TS-78xx: NAND not registered\n");
+                       pr_info("TS-78xx: NAND not registered\n");
                        ts78xx_fpga.supports.ts_nand.present = 0;
                }
                ret |= tmp;
@@ -439,7 +439,7 @@ static int ts78xx_fpga_load_devices(void)
        if (ts78xx_fpga.supports.ts_rng.present == 1) {
                tmp = ts78xx_ts_rng_load();
                if (tmp) {
-                       printk(KERN_INFO "TS-78xx: RNG not registered\n");
+                       pr_info("TS-78xx: RNG not registered\n");
                        ts78xx_fpga.supports.ts_rng.present = 0;
                }
                ret |= tmp;
@@ -466,7 +466,7 @@ static int ts78xx_fpga_load(void)
 {
        ts78xx_fpga.id = readl(TS78XX_FPGA_REGS_VIRT_BASE);
 
-       printk(KERN_INFO "TS-78xx FPGA: magic=0x%.6x, rev=0x%.2x\n",
+       pr_info("TS-78xx FPGA: magic=0x%.6x, rev=0x%.2x\n",
                        (ts78xx_fpga.id >> 8) & 0xffffff,
                        ts78xx_fpga.id & 0xff);
 
@@ -494,7 +494,7 @@ static int ts78xx_fpga_unload(void)
         * UrJTAG SVN since r1381 can be used to reprogram the FPGA
         */
        if (ts78xx_fpga.id != fpga_id) {
-               printk(KERN_ERR "TS-78xx FPGA: magic/rev mismatch\n"
+               pr_err("TS-78xx FPGA: magic/rev mismatch\n"
                        "TS-78xx FPGA: was 0x%.6x/%.2x but now 0x%.6x/%.2x\n",
                        (ts78xx_fpga.id >> 8) & 0xffffff, ts78xx_fpga.id & 0xff,
                        (fpga_id >> 8) & 0xffffff, fpga_id & 0xff);
@@ -525,7 +525,7 @@ static ssize_t ts78xx_fpga_store(struct kobject *kobj,
        int value, ret;
 
        if (ts78xx_fpga.state < 0) {
-               printk(KERN_ERR "TS-78xx FPGA: borked, you must powercycle asap\n");
+               pr_err("TS-78xx FPGA: borked, you must powercycle asap\n");
                return -EBUSY;
        }
 
@@ -534,7 +534,7 @@ static ssize_t ts78xx_fpga_store(struct kobject *kobj,
        else if (strncmp(buf, "offline", sizeof("offline") - 1) == 0)
                value = 0;
        else {
-               printk(KERN_ERR "ts78xx_fpga_store: Invalid value\n");
+               pr_err("ts78xx_fpga_store: Invalid value\n");
                return -EINVAL;
        }
 
@@ -616,7 +616,7 @@ static void __init ts78xx_init(void)
        ret = ts78xx_fpga_load();
        ret = sysfs_create_file(power_kobj, &ts78xx_fpga_attr.attr);
        if (ret)
-               printk(KERN_ERR "sysfs_create_file failed: %d\n", ret);
+               pr_err("sysfs_create_file failed: %d\n", ret);
 }
 
 MACHINE_START(TS78XX, "Technologic Systems TS-78xx SBC")
index 3499fad..4cb069f 100644 (file)
@@ -128,8 +128,8 @@ static int am200_init_gpio_regs(struct metronomefb_par *par)
        return 0;
 
 err_req_gpio:
-       while (i > 0)
-               gpio_free(gpios[i--]);
+       while (--i >= 0)
+               gpio_free(gpios[i]);
 
        return err;
 }
@@ -194,7 +194,7 @@ static struct notifier_block am200_fb_notif = {
 };
 
 /* this gets called as part of our init. these steps must be done now so
- * that we can use set_pxa_fb_info */
+ * that we can use pxa_set_fb_info */
 static void __init am200_presetup_fb(void)
 {
        int fw;
@@ -249,7 +249,7 @@ static void __init am200_presetup_fb(void)
        /* we divide since we told the LCD controller we're 16bpp */
        am200_fb_info.modes->xres /= 2;
 
-       set_pxa_fb_info(&am200_fb_info);
+       pxa_set_fb_info(NULL, &am200_fb_info);
 
 }
 
index 993d75e..fa8bad2 100644 (file)
@@ -125,10 +125,7 @@ static int am300_init_gpio_regs(struct broadsheetfb_par *par)
                if (err) {
                        dev_err(&am300_device->dev, "failed requesting "
                                "gpio %d, err=%d\n", i, err);
-                       while (i >= DB0_GPIO_PIN)
-                               gpio_free(i--);
-                       i = ARRAY_SIZE(gpios) - 1;
-                       goto err_req_gpio;
+                       goto err_req_gpio2;
                }
        }
 
@@ -159,9 +156,13 @@ static int am300_init_gpio_regs(struct broadsheetfb_par *par)
 
        return 0;
 
+err_req_gpio2:
+       while (--i >= DB0_GPIO_PIN)
+               gpio_free(i);
+       i = ARRAY_SIZE(gpios);
 err_req_gpio:
-       while (i > 0)
-               gpio_free(gpios[i--]);
+       while (--i >= 0)
+               gpio_free(gpios[i]);
 
        return err;
 }
index 38dea05..bfbecec 100644 (file)
@@ -263,7 +263,7 @@ static void __init balloon3_lcd_init(void)
        }
 
        balloon3_lcd_screen.pxafb_backlight_power = balloon3_backlight_power;
-       set_pxa_fb_info(&balloon3_lcd_screen);
+       pxa_set_fb_info(NULL, &balloon3_lcd_screen);
        return;
 
 err2:
index b734d84..8225e2e 100644 (file)
@@ -379,7 +379,7 @@ __setup("monitor=", cmx2xx_set_display);
 
 static void __init cmx2xx_init_display(void)
 {
-       set_pxa_fb_info(cmx2xx_display);
+       pxa_set_fb_info(NULL, cmx2xx_display);
 }
 #else
 static inline void cmx2xx_init_display(void) {}
index 06d0a03..b2248e7 100644 (file)
@@ -296,7 +296,7 @@ static struct pxafb_mach_info cm_x300_lcd = {
 
 static void __init cm_x300_init_lcd(void)
 {
-       set_pxa_fb_info(&cm_x300_lcd);
+       pxa_set_fb_info(NULL, &cm_x300_lcd);
 }
 #else
 static inline void cm_x300_init_lcd(void) {}
index ee79739..44c1b77 100644 (file)
@@ -175,7 +175,7 @@ static struct pxafb_mach_info income_lcd_screen = {
 
 static void __init income_lcd_init(void)
 {
-       set_pxa_fb_info(&income_lcd_screen);
+       pxa_set_fb_info(NULL, &income_lcd_screen);
 }
 #else
 static inline void income_lcd_init(void) {}
index 96b2d9f..3f9be41 100644 (file)
@@ -105,7 +105,7 @@ void __init colibri_pxa3xx_init_lcd(int bl_pin)
        lcd_bl_pin = bl_pin;
        gpio_request(bl_pin, "lcd backlight");
        gpio_direction_output(bl_pin, 0);
-       set_pxa_fb_info(&sharp_lq43_info);
+       pxa_set_fb_info(NULL, &sharp_lq43_info);
 }
 #endif
 
index d4e705c..3a5507e 100644 (file)
@@ -462,7 +462,6 @@ static struct pxaficp_platform_data corgi_ficp_platform_data = {
  * USB Device Controller
  */
 static struct pxa2xx_udc_mach_info udc_info __initdata = {
-       .gpio_vbus              = -1,
        /* no connect GPIO; corgi can't tell connection status */
        .gpio_pullup            = CORGI_GPIO_USB_PULLUP,
 };
index c4bf08b..2e04254 100644 (file)
@@ -90,7 +90,6 @@ void __init pxa_set_mci_info(struct pxamci_platform_data *info)
 
 static struct pxa2xx_udc_mach_info pxa_udc_info = {
        .gpio_pullup = -1,
-       .gpio_vbus   = -1,
 };
 
 void __init pxa_set_udc_info(struct pxa2xx_udc_mach_info *info)
@@ -188,16 +187,12 @@ struct platform_device pxa_device_fb = {
        .resource       = pxafb_resources,
 };
 
-void __init set_pxa_fb_info(struct pxafb_mach_info *info)
+void __init pxa_set_fb_info(struct device *parent, struct pxafb_mach_info *info)
 {
+       pxa_device_fb.dev.parent = parent;
        pxa_register_device(&pxa_device_fb, info);
 }
 
-void __init set_pxa_fb_parent(struct device *parent_dev)
-{
-       pxa_device_fb.dev.parent = parent_dev;
-}
-
 static struct resource pxa_resource_ffuart[] = {
        {
                .start  = 0x40100000,
index b411d7c..f8a6e9d 100644 (file)
@@ -689,7 +689,7 @@ static struct pxafb_mach_info em_x270_lcd = {
 
 static void __init em_x270_init_lcd(void)
 {
-       set_pxa_fb_info(&em_x270_lcd);
+       pxa_set_fb_info(NULL, &em_x270_lcd);
 }
 #else
 static inline void em_x270_init_lcd(void) {}
index edca0a0..2e3970f 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/mfd/t7l66xb.h>
 #include <linux/mtd/nand.h>
 #include <linux/mtd/partitions.h>
+#include <linux/usb/gpio_vbus.h>
 
 #include <video/w100fb.h>
 
@@ -51,12 +52,20 @@ void __init eseries_fixup(struct machine_desc *desc,
                mi->bank[0].size = (64*1024*1024);
 }
 
-struct pxa2xx_udc_mach_info e7xx_udc_mach_info = {
+struct gpio_vbus_mach_info e7xx_udc_info = {
        .gpio_vbus   = GPIO_E7XX_USB_DISC,
        .gpio_pullup = GPIO_E7XX_USB_PULLUP,
        .gpio_pullup_inverted = 1
 };
 
+static struct platform_device e7xx_gpio_vbus = {
+       .name   = "gpio-vbus",
+       .id     = -1,
+       .dev    = {
+               .platform_data  = &e7xx_udc_info,
+       },
+};
+
 struct pxaficp_platform_data e7xx_ficp_platform_data = {
        .gpio_pwdown            = GPIO_E7XX_IR_OFF,
        .transceiver_cap        = IR_SIRMODE | IR_OFF,
@@ -165,6 +174,7 @@ static struct platform_device e330_tc6387xb_device = {
 
 static struct platform_device *e330_devices[] __initdata = {
        &e330_tc6387xb_device,
+       &e7xx_gpio_vbus,
 };
 
 static void __init e330_init(void)
@@ -175,7 +185,6 @@ static void __init e330_init(void)
        eseries_register_clks();
        eseries_get_tmio_gpios();
        platform_add_devices(ARRAY_AND_SIZE(e330_devices));
-       pxa_set_udc_info(&e7xx_udc_mach_info);
 }
 
 MACHINE_START(E330, "Toshiba e330")
@@ -214,6 +223,7 @@ static struct platform_device e350_t7l66xb_device = {
 
 static struct platform_device *e350_devices[] __initdata = {
        &e350_t7l66xb_device,
+       &e7xx_gpio_vbus,
 };
 
 static void __init e350_init(void)
@@ -224,7 +234,6 @@ static void __init e350_init(void)
        eseries_register_clks();
        eseries_get_tmio_gpios();
        platform_add_devices(ARRAY_AND_SIZE(e350_devices));
-       pxa_set_udc_info(&e7xx_udc_mach_info);
 }
 
 MACHINE_START(E350, "Toshiba e350")
@@ -333,6 +342,7 @@ static struct platform_device e400_t7l66xb_device = {
 
 static struct platform_device *e400_devices[] __initdata = {
        &e400_t7l66xb_device,
+       &e7xx_gpio_vbus,
 };
 
 static void __init e400_init(void)
@@ -344,9 +354,8 @@ static void __init e400_init(void)
        /* Fixme - e400 may have a switched clock */
        eseries_register_clks();
        eseries_get_tmio_gpios();
-       set_pxa_fb_info(&e400_pxafb_mach_info);
+       pxa_set_fb_info(NULL, &e400_pxafb_mach_info);
        platform_add_devices(ARRAY_AND_SIZE(e400_devices));
-       pxa_set_udc_info(&e7xx_udc_mach_info);
 }
 
 MACHINE_START(E400, "Toshiba e400")
@@ -519,6 +528,7 @@ static struct platform_device e740_t7l66xb_device = {
 static struct platform_device *e740_devices[] __initdata = {
        &e740_fb_device,
        &e740_t7l66xb_device,
+       &e7xx_gpio_vbus,
 };
 
 static void __init e740_init(void)
@@ -532,7 +542,6 @@ static void __init e740_init(void)
                        "UDCCLK", &pxa25x_device_udc.dev),
        eseries_get_tmio_gpios();
        platform_add_devices(ARRAY_AND_SIZE(e740_devices));
-       pxa_set_udc_info(&e7xx_udc_mach_info);
        pxa_set_ac97_info(NULL);
        pxa_set_ficp_info(&e7xx_ficp_platform_data);
 }
@@ -711,6 +720,7 @@ static struct platform_device e750_tc6393xb_device = {
 static struct platform_device *e750_devices[] __initdata = {
        &e750_fb_device,
        &e750_tc6393xb_device,
+       &e7xx_gpio_vbus,
 };
 
 static void __init e750_init(void)
@@ -723,7 +733,6 @@ static void __init e750_init(void)
                        "GPIO11_CLK", NULL),
        eseries_get_tmio_gpios();
        platform_add_devices(ARRAY_AND_SIZE(e750_devices));
-       pxa_set_udc_info(&e7xx_udc_mach_info);
        pxa_set_ac97_info(NULL);
        pxa_set_ficp_info(&e7xx_ficp_platform_data);
 }
@@ -873,12 +882,21 @@ static struct platform_device e800_fb_device = {
 
 /* --------------------------- UDC definitions --------------------------- */
 
-static struct pxa2xx_udc_mach_info e800_udc_mach_info = {
+static struct gpio_vbus_mach_info e800_udc_info = {
        .gpio_vbus   = GPIO_E800_USB_DISC,
        .gpio_pullup = GPIO_E800_USB_PULLUP,
        .gpio_pullup_inverted = 1
 };
 
+static struct platform_device e800_gpio_vbus = {
+       .name   = "gpio-vbus",
+       .id     = -1,
+       .dev    = {
+               .platform_data  = &e800_udc_info,
+       },
+};
+
+
 /* ----------------- e800 tc6393xb parameters ------------------ */
 
 static struct tc6393xb_platform_data e800_tc6393xb_info = {
@@ -907,6 +925,7 @@ static struct platform_device e800_tc6393xb_device = {
 static struct platform_device *e800_devices[] __initdata = {
        &e800_fb_device,
        &e800_tc6393xb_device,
+       &e800_gpio_vbus,
 };
 
 static void __init e800_init(void)
@@ -919,7 +938,6 @@ static void __init e800_init(void)
                        "GPIO11_CLK", NULL),
        eseries_get_tmio_gpios();
        platform_add_devices(ARRAY_AND_SIZE(e800_devices));
-       pxa_set_udc_info(&e800_udc_mach_info);
        pxa_set_ac97_info(NULL);
 }
 
index 93f05e0..d88aed8 100644 (file)
@@ -783,7 +783,7 @@ static void __init a780_init(void)
 
        pxa_set_i2c_info(NULL);
 
-       set_pxa_fb_info(&ezx_fb_info_1);
+       pxa_set_fb_info(NULL, &ezx_fb_info_1);
 
        pxa_set_keypad_info(&a780_keypad_platform_data);
 
@@ -853,7 +853,7 @@ static void __init e680_init(void)
        pxa_set_i2c_info(NULL);
        i2c_register_board_info(0, ARRAY_AND_SIZE(e680_i2c_board_info));
 
-       set_pxa_fb_info(&ezx_fb_info_1);
+       pxa_set_fb_info(NULL, &ezx_fb_info_1);
 
        pxa_set_keypad_info(&e680_keypad_platform_data);
 
@@ -918,7 +918,7 @@ static void __init a1200_init(void)
        pxa_set_i2c_info(NULL);
        i2c_register_board_info(0, ARRAY_AND_SIZE(a1200_i2c_board_info));
 
-       set_pxa_fb_info(&ezx_fb_info_2);
+       pxa_set_fb_info(NULL, &ezx_fb_info_2);
 
        pxa_set_keypad_info(&a1200_keypad_platform_data);
 
@@ -1103,7 +1103,7 @@ static void __init a910_init(void)
        pxa_set_i2c_info(NULL);
        i2c_register_board_info(0, ARRAY_AND_SIZE(a910_i2c_board_info));
 
-       set_pxa_fb_info(&ezx_fb_info_2);
+       pxa_set_fb_info(NULL, &ezx_fb_info_2);
 
        pxa_set_keypad_info(&a910_keypad_platform_data);
 
@@ -1173,7 +1173,7 @@ static void __init e6_init(void)
        pxa_set_i2c_info(NULL);
        i2c_register_board_info(0, ARRAY_AND_SIZE(e6_i2c_board_info));
 
-       set_pxa_fb_info(&ezx_fb_info_2);
+       pxa_set_fb_info(NULL, &ezx_fb_info_2);
 
        pxa_set_keypad_info(&e6_keypad_platform_data);
 
@@ -1212,7 +1212,7 @@ static void __init e2_init(void)
        pxa_set_i2c_info(NULL);
        i2c_register_board_info(0, ARRAY_AND_SIZE(e2_i2c_board_info));
 
-       set_pxa_fb_info(&ezx_fb_info_2);
+       pxa_set_fb_info(NULL, &ezx_fb_info_2);
 
        pxa_set_keypad_info(&e2_keypad_platform_data);
 
index 6fd319e..d65e4bd 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/gpio.h>
 #include <linux/err.h>
 #include <linux/clk.h>
+#include <linux/usb/gpio_vbus.h>
 
 #include <asm/setup.h>
 #include <asm/memory.h>
@@ -106,14 +107,22 @@ static void __init gumstix_mmc_init(void)
 #endif
 
 #ifdef CONFIG_USB_GADGET_PXA25X
-static struct pxa2xx_udc_mach_info gumstix_udc_info __initdata = {
+static struct gpio_vbus_mach_info gumstix_udc_info = {
        .gpio_vbus              = GPIO_GUMSTIX_USB_GPIOn,
        .gpio_pullup            = GPIO_GUMSTIX_USB_GPIOx,
 };
 
+static struct platform_device gumstix_gpio_vbus = {
+       .name   = "gpio-vbus",
+       .id     = -1,
+       .dev    = {
+               .platform_data  = &gumstix_udc_info,
+       },
+};
+
 static void __init gumstix_udc_init(void)
 {
-       pxa_set_udc_info(&gumstix_udc_info);
+       platform_device_register(&gumstix_gpio_vbus);
 }
 #else
 static void gumstix_udc_init(void)
index dd40e4a..f7fb64f 100644 (file)
@@ -167,7 +167,7 @@ static void __init idp_init(void)
 
        platform_device_register(&smc91x_device);
        //platform_device_register(&mst_audio_device);
-       set_pxa_fb_info(&sharp_lm8v31);
+       pxa_set_fb_info(NULL, &sharp_lm8v31);
        pxa_set_mci_info(&idp_mci_platform_data);
 }
 
index 2bbcf70..0d4700a 100644 (file)
 #define GPIO_NR_PALMZ72_BT_POWER               17
 #define GPIO_NR_PALMZ72_BT_RESET               83
 
+/* Camera */
+#define GPIO_NR_PALMZ72_CAM_PWDN               56
+#define GPIO_NR_PALMZ72_CAM_RESET              57
+#define GPIO_NR_PALMZ72_CAM_POWER              91
+
 /** Initial values **/
 
 /* Battery */
index 160ec83..01a45ac 100644 (file)
@@ -154,8 +154,8 @@ struct pxafb_mach_info {
        void (*pxafb_lcd_power)(int, struct fb_var_screeninfo *);
        void (*smart_update)(struct fb_info *);
 };
-void set_pxa_fb_info(struct pxafb_mach_info *hard_pxa_fb_info);
-void set_pxa_fb_parent(struct device *parent_dev);
+
+void pxa_set_fb_info(struct device *, struct pxafb_mach_info *);
 unsigned long pxafb_get_hsync_time(struct device *dev);
 
 extern int pxafb_smart_queue(struct fb_info *info, uint16_t *cmds, int);
index 8835c16..7b0f71e 100644 (file)
@@ -25,8 +25,7 @@
 #define        GPIO98_ZIPITZ2_LID_BUTTON       98
 
 /* Libertas GSPI8686 WiFi */
-#define        GPIO14_ZIPITZ2_WIFI_RESET       14
-#define        GPIO15_ZIPITZ2_WIFI_POWER       15
+#define        GPIO14_ZIPITZ2_WIFI_POWER       14
 #define        GPIO24_ZIPITZ2_WIFI_CS          24
 #define        GPIO36_ZIPITZ2_WIFI_IRQ         36
 
index 87c1ed9..e5e326d 100644 (file)
@@ -185,7 +185,7 @@ static struct pxafb_mach_info littleton_lcd_info = {
 
 static void littleton_init_lcd(void)
 {
-       set_pxa_fb_info(&littleton_lcd_info);
+       pxa_set_fb_info(NULL, &littleton_lcd_info);
 }
 #else
 static inline void littleton_init_lcd(void) {};
index 6307f70..f5de541 100644 (file)
@@ -480,7 +480,7 @@ static void __init lpd270_init(void)
        pxa_set_ac97_info(NULL);
 
        if (lpd270_lcd_to_use != NULL)
-               set_pxa_fb_info(lpd270_lcd_to_use);
+               pxa_set_fb_info(NULL, lpd270_lcd_to_use);
 
        pxa_set_ohci_info(&lpd270_ohci_platform_data);
 }
index 0fea945..3ede978 100644 (file)
@@ -521,7 +521,7 @@ static void __init lubbock_init(void)
 
        clk_add_alias("SA1111_CLK", NULL, "GPIO11_CLK", NULL);
        pxa_set_udc_info(&udc_info);
-       set_pxa_fb_info(&sharp_lm8v31);
+       pxa_set_fb_info(NULL, &sharp_lm8v31);
        pxa_set_mci_info(&lubbock_mci_platform_data);
        pxa_set_ficp_info(&lubbock_ficp_platform_data);
        pxa_set_ac97_info(NULL);
index 5535991..a72993d 100644 (file)
@@ -757,7 +757,7 @@ static void __init magician_init(void)
                gpio_direction_output(GPIO104_MAGICIAN_LCD_POWER_1, 0);
                gpio_direction_output(GPIO105_MAGICIAN_LCD_POWER_2, 0);
                gpio_direction_output(GPIO106_MAGICIAN_LCD_POWER_3, 0);
-               set_pxa_fb_info(lcd_select ? &samsung_info : &toppoly_info);
+               pxa_set_fb_info(NULL, lcd_select ? &samsung_info : &toppoly_info);
        } else
                pr_err("LCD detection: CPLD mapping failed\n");
 }
index 29b6e7a..95163ba 100644 (file)
@@ -592,7 +592,7 @@ static void __init mainstone_init(void)
        else
                mainstone_pxafb_info.modes = &toshiba_ltm035a776c_mode;
 
-       set_pxa_fb_info(&mainstone_pxafb_info);
+       pxa_set_fb_info(NULL, &mainstone_pxafb_info);
        mainstone_backlight_register();
 
        pxa_set_mci_info(&mainstone_mci_platform_data);
index 78d98a8..dd13bb6 100644 (file)
@@ -795,7 +795,7 @@ static void __init mioa701_machine_init(void)
        pxa_set_stuart_info(NULL);
        mio_gpio_request(ARRAY_AND_SIZE(global_gpios));
        bootstrap_init();
-       set_pxa_fb_info(&mioa701_pxafb_info);
+       pxa_set_fb_info(NULL, &mioa701_pxafb_info);
        pxa_set_mci_info(&mioa701_mci_info);
        pxa_set_keypad_info(&mioa701_keypad_info);
        pxa_set_udc_info(&mioa701_udc_info);
index 72adb3a..325c245 100644 (file)
@@ -1,8 +1,7 @@
 /*
  * Common code for Palm LD, T5, TX, Z72
  *
- * Copyright (C) 2010
- * Marek Vasut <marek.vasut@gmail.com>
+ * Copyright (C) 2010-2011 Marek Vasut <marek.vasut@gmail.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -158,7 +157,7 @@ void __init palm27x_lcd_init(int power, struct pxafb_mode_info *mode)
                palm27x_lcd_screen.pxafb_lcd_power = palm27x_lcd_ctl;
        }
 
-       set_pxa_fb_info(&palm27x_lcd_screen);
+       pxa_set_fb_info(NULL, &palm27x_lcd_screen);
 }
 #endif
 
index a09a237..fb06bd0 100644 (file)
@@ -507,7 +507,7 @@ static struct pxafb_mach_info palmtc_lcd_screen = {
 
 static void __init palmtc_lcd_init(void)
 {
-       set_pxa_fb_info(&palmtc_lcd_screen);
+       pxa_set_fb_info(NULL, &palmtc_lcd_screen);
 }
 #else
 static inline void palmtc_lcd_init(void) {}
index 3f25014..726f5b9 100644 (file)
@@ -136,30 +136,14 @@ static struct platform_device palmte2_pxa_keys = {
 /******************************************************************************
  * Backlight
  ******************************************************************************/
+static struct gpio palmte_bl_gpios[] = {
+       { GPIO_NR_PALMTE2_BL_POWER, GPIOF_INIT_LOW, "Backlight power" },
+       { GPIO_NR_PALMTE2_LCD_POWER, GPIOF_INIT_LOW, "LCD power" },
+};
+
 static int palmte2_backlight_init(struct device *dev)
 {
-       int ret;
-
-       ret = gpio_request(GPIO_NR_PALMTE2_BL_POWER, "BL POWER");
-       if (ret)
-               goto err;
-       ret = gpio_direction_output(GPIO_NR_PALMTE2_BL_POWER, 0);
-       if (ret)
-               goto err2;
-       ret = gpio_request(GPIO_NR_PALMTE2_LCD_POWER, "LCD POWER");
-       if (ret)
-               goto err2;
-       ret = gpio_direction_output(GPIO_NR_PALMTE2_LCD_POWER, 0);
-       if (ret)
-               goto err3;
-
-       return 0;
-err3:
-       gpio_free(GPIO_NR_PALMTE2_LCD_POWER);
-err2:
-       gpio_free(GPIO_NR_PALMTE2_BL_POWER);
-err:
-       return ret;
+       return gpio_request_array(ARRAY_AND_SIZE(palmte_bl_gpios));
 }
 
 static int palmte2_backlight_notify(struct device *dev, int brightness)
@@ -171,8 +155,7 @@ static int palmte2_backlight_notify(struct device *dev, int brightness)
 
 static void palmte2_backlight_exit(struct device *dev)
 {
-       gpio_free(GPIO_NR_PALMTE2_BL_POWER);
-       gpio_free(GPIO_NR_PALMTE2_LCD_POWER);
+       gpio_free_array(ARRAY_AND_SIZE(palmte_bl_gpios));
 }
 
 static struct platform_pwm_backlight_data palmte2_backlight_data = {
@@ -363,7 +346,7 @@ static void __init palmte2_init(void)
        pxa_set_btuart_info(NULL);
        pxa_set_stuart_info(NULL);
 
-       set_pxa_fb_info(&palmte2_lcd_screen);
+       pxa_set_fb_info(NULL, &palmte2_lcd_screen);
        pxa_set_mci_info(&palmte2_mci_platform_data);
        palmte2_udc_init();
        pxa_set_ac97_info(&palmte2_ac97_pdata);
index 3010193..3b8a4f3 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/wm97xx.h>
 #include <linux/power_supply.h>
 #include <linux/usb/gpio_vbus.h>
+#include <linux/i2c-gpio.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
@@ -47,6 +48,9 @@
 #include <mach/palm27x.h>
 
 #include <mach/pm.h>
+#include <mach/camera.h>
+
+#include <media/soc_camera.h>
 
 #include "generic.h"
 #include "devices.h"
@@ -103,6 +107,28 @@ static unsigned long palmz72_pin_config[] __initdata = {
        GPIO22_GPIO,    /* LCD border color */
        GPIO96_GPIO,    /* lcd power */
 
+       /* PXA Camera */
+       GPIO81_CIF_DD_0,
+       GPIO48_CIF_DD_5,
+       GPIO50_CIF_DD_3,
+       GPIO51_CIF_DD_2,
+       GPIO52_CIF_DD_4,
+       GPIO53_CIF_MCLK,
+       GPIO54_CIF_PCLK,
+       GPIO55_CIF_DD_1,
+       GPIO84_CIF_FV,
+       GPIO85_CIF_LV,
+       GPIO93_CIF_DD_6,
+       GPIO108_CIF_DD_7,
+
+       GPIO56_GPIO,    /* OV9640 Powerdown */
+       GPIO57_GPIO,    /* OV9640 Reset */
+       GPIO91_GPIO,    /* OV9640 Power */
+
+       /* I2C */
+       GPIO117_GPIO,   /* I2C_SCL */
+       GPIO118_GPIO,   /* I2C_SDA */
+
        /* Misc. */
        GPIO0_GPIO      | WAKEUP_ON_LEVEL_HIGH, /* power detect */
        GPIO88_GPIO,                            /* green led */
@@ -253,6 +279,106 @@ static int __init palmz72_pm_init(void)
 device_initcall(palmz72_pm_init);
 #endif
 
+/******************************************************************************
+ * SoC Camera
+ ******************************************************************************/
+#if defined(CONFIG_SOC_CAMERA_OV9640) || \
+       defined(CONFIG_SOC_CAMERA_OV9640_MODULE)
+static struct pxacamera_platform_data palmz72_pxacamera_platform_data = {
+       .flags          = PXA_CAMERA_MASTER | PXA_CAMERA_DATAWIDTH_8 |
+                       PXA_CAMERA_PCLK_EN | PXA_CAMERA_MCLK_EN,
+       .mclk_10khz     = 2600,
+};
+
+/* Board I2C devices. */
+static struct i2c_board_info palmz72_i2c_device[] = {
+       {
+               I2C_BOARD_INFO("ov9640", 0x30),
+       }
+};
+
+static int palmz72_camera_power(struct device *dev, int power)
+{
+       gpio_set_value(GPIO_NR_PALMZ72_CAM_PWDN, !power);
+       mdelay(50);
+       return 0;
+}
+
+static int palmz72_camera_reset(struct device *dev)
+{
+       gpio_set_value(GPIO_NR_PALMZ72_CAM_RESET, 1);
+       mdelay(50);
+       gpio_set_value(GPIO_NR_PALMZ72_CAM_RESET, 0);
+       mdelay(50);
+       return 0;
+}
+
+static struct soc_camera_link palmz72_iclink = {
+       .bus_id         = 0, /* Match id in pxa27x_device_camera in device.c */
+       .board_info     = &palmz72_i2c_device[0],
+       .i2c_adapter_id = 0,
+       .module_name    = "ov96xx",
+       .power          = &palmz72_camera_power,
+       .reset          = &palmz72_camera_reset,
+       .flags          = SOCAM_DATAWIDTH_8,
+};
+
+static struct i2c_gpio_platform_data palmz72_i2c_bus_data = {
+       .sda_pin        = 118,
+       .scl_pin        = 117,
+       .udelay         = 10,
+       .timeout        = 100,
+};
+
+static struct platform_device palmz72_i2c_bus_device = {
+       .name           = "i2c-gpio",
+       .id             = 0, /* we use this as a replacement for i2c-pxa */
+       .dev            = {
+               .platform_data  = &palmz72_i2c_bus_data,
+       }
+};
+
+static struct platform_device palmz72_camera = {
+       .name   = "soc-camera-pdrv",
+       .id     = -1,
+       .dev    = {
+               .platform_data  = &palmz72_iclink,
+       },
+};
+
+/* Here we request the camera GPIOs and configure them. We power up the camera
+ * module, deassert the reset pin, but put it into powerdown (low to no power
+ * consumption) mode. This allows us to later bring the module up fast. */
+static struct gpio palmz72_camera_gpios[] = {
+       { GPIO_NR_PALMZ72_CAM_POWER,    GPIOF_INIT_HIGH,"Camera DVDD" },
+       { GPIO_NR_PALMZ72_CAM_RESET,    GPIOF_INIT_LOW, "Camera RESET" },
+       { GPIO_NR_PALMZ72_CAM_PWDN,     GPIOF_INIT_LOW, "Camera PWDN" },
+};
+
+static inline void __init palmz72_cam_gpio_init(void)
+{
+       int ret;
+
+       ret = gpio_request_array(ARRAY_AND_SIZE(palmz72_camera_gpios));
+       if (!ret)
+               gpio_free_array(ARRAY_AND_SIZE(palmz72_camera_gpios));
+       else
+               printk(KERN_ERR "Camera GPIO init failed!\n");
+
+       return;
+}
+
+static void __init palmz72_camera_init(void)
+{
+       palmz72_cam_gpio_init();
+       pxa_set_camera_info(&palmz72_pxacamera_platform_data);
+       platform_device_register(&palmz72_i2c_bus_device);
+       platform_device_register(&palmz72_camera);
+}
+#else
+static inline void palmz72_camera_init(void) {}
+#endif
+
 /******************************************************************************
  * Machine init
  ******************************************************************************/
@@ -276,6 +402,7 @@ static void __init palmz72_init(void)
        palm27x_pmic_init();
        palmz72_kpc_init();
        palmz72_leds_init();
+       palmz72_camera_init();
 }
 
 MACHINE_START(PALMZ72, "Palm Zire72")
index 4d01205..6d5b7e0 100644 (file)
@@ -515,7 +515,7 @@ void __init pcm990_baseboard_init(void)
        pcm990_init_irq();
 
 #ifndef CONFIG_PCM990_DISPLAY_NONE
-       set_pxa_fb_info(&pcm990_fbinfo);
+       pxa_set_fb_info(NULL, &pcm990_fbinfo);
 #endif
        platform_device_register(&pcm990_backlight_device);
 
index 35353af..16d14fd 100644 (file)
@@ -445,8 +445,7 @@ static void __init poodle_init(void)
        if (ret)
                pr_warning("poodle: Unable to register LoCoMo device\n");
 
-       set_pxa_fb_parent(&poodle_locomo_device.dev);
-       set_pxa_fb_info(&poodle_fb_info);
+       pxa_set_fb_info(&poodle_locomo_device.dev, &poodle_fb_info);
        pxa_set_udc_info(&udc_info);
        pxa_set_mci_info(&poodle_mci_platform_data);
        pxa_set_ficp_info(&poodle_ficp_platform_data);
index 4709418..cd18613 100644 (file)
@@ -597,7 +597,7 @@ static void __init raumfeld_lcd_init(void)
 {
        int ret;
 
-       set_pxa_fb_info(&raumfeld_sharp_lcd_info);
+       pxa_set_fb_info(NULL, &raumfeld_sharp_lcd_info);
 
        /* Earlier devices had the backlight regulator controlled
         * via PWM, later versions use another controller for that */
index eb83c89..fee97a9 100644 (file)
@@ -473,7 +473,7 @@ static struct pxafb_mach_info saar_lcd_info = {
 
 static void __init saar_init_lcd(void)
 {
-       set_pxa_fb_info(&saar_lcd_info);
+       pxa_set_fb_info(NULL, &saar_lcd_info);
 }
 #else
 static inline void saar_init_lcd(void) {}
index 38e2c09..01c5769 100644 (file)
@@ -724,7 +724,7 @@ static struct pxafb_mach_info spitz_pxafb_info = {
 
 static void __init spitz_lcd_init(void)
 {
-       set_pxa_fb_info(&spitz_pxafb_info);
+       pxa_set_fb_info(NULL, &spitz_pxafb_info);
 }
 #else
 static inline void spitz_lcd_init(void) {}
index 9cecf83..53d4a47 100644 (file)
@@ -466,7 +466,7 @@ static void __init tavorevb_init_lcd(void)
 {
        platform_device_register(&tavorevb_backlight_devices[0]);
        platform_device_register(&tavorevb_backlight_devices[1]);
-       set_pxa_fb_info(&tavorevb_lcd_info);
+       pxa_set_fb_info(NULL, &tavorevb_lcd_info);
 }
 #else
 static inline void tavorevb_init_lcd(void) {}
index e7f64d9..428da3f 100644 (file)
@@ -100,7 +100,6 @@ pxa_osmr0_set_mode(enum clock_event_mode mode, struct clock_event_device *dev)
 static struct clock_event_device ckevt_pxa_osmr0 = {
        .name           = "osmr0",
        .features       = CLOCK_EVT_FEAT_ONESHOT,
-       .shift          = 32,
        .rating         = 200,
        .set_next_event = pxa_osmr0_set_next_event,
        .set_mode       = pxa_osmr0_set_mode,
@@ -135,8 +134,8 @@ static void __init pxa_timer_init(void)
 
        init_sched_clock(&cd, pxa_update_sched_clock, 32, clock_tick_rate);
 
-       ckevt_pxa_osmr0.mult =
-               div_sc(clock_tick_rate, NSEC_PER_SEC, ckevt_pxa_osmr0.shift);
+       clocksource_calc_mult_shift(&cksrc_pxa_oscr0, clock_tick_rate, 4);
+       clockevents_calc_mult_shift(&ckevt_pxa_osmr0, clock_tick_rate, 4);
        ckevt_pxa_osmr0.max_delta_ns =
                clockevent_delta2ns(0x7fffffff, &ckevt_pxa_osmr0);
        ckevt_pxa_osmr0.min_delta_ns =
index 5ad3807..5fa1457 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/spi/pxa2xx_spi.h>
 #include <linux/input/matrix_keypad.h>
 #include <linux/i2c/pxa-i2c.h>
+#include <linux/usb/gpio_vbus.h>
 
 #include <asm/setup.h>
 #include <asm/mach-types.h>
@@ -240,12 +241,20 @@ static struct scoop_pcmcia_config tosa_pcmcia_config = {
 /*
  * USB Device Controller
  */
-static struct pxa2xx_udc_mach_info udc_info __initdata = {
+static struct gpio_vbus_mach_info tosa_udc_info = {
        .gpio_pullup            = TOSA_GPIO_USB_PULLUP,
        .gpio_vbus              = TOSA_GPIO_USB_IN,
        .gpio_vbus_inverted     = 1,
 };
 
+static struct platform_device tosa_gpio_vbus = {
+       .name   = "gpio-vbus",
+       .id     = -1,
+       .dev    = {
+               .platform_data  = &tosa_udc_info,
+       },
+};
+
 /*
  * MMC/SD Device
  */
@@ -891,6 +900,7 @@ static struct platform_device *devices[] __initdata = {
        &tosa_bt_device,
        &sharpsl_rom_device,
        &wm9712_device,
+       &tosa_gpio_vbus,
 };
 
 static void tosa_poweroff(void)
@@ -937,7 +947,6 @@ static void __init tosa_init(void)
        dummy = gpiochip_reserve(TOSA_TC6393XB_GPIO_BASE, 16);
 
        pxa_set_mci_info(&tosa_mci_platform_data);
-       pxa_set_udc_info(&udc_info);
        pxa_set_ficp_info(&tosa_ficp_platform_data);
        pxa_set_i2c_info(NULL);
        pxa_set_ac97_info(NULL);
index 857bb2e..b9cfbeb 100644 (file)
@@ -516,9 +516,9 @@ static void __init trizeps4_init(void)
        pxa_set_stuart_info(NULL);
 
        if (0)  /* dont know how to determine LCD */
-               set_pxa_fb_info(&sharp_lcd);
+               pxa_set_fb_info(NULL, &sharp_lcd);
        else
-               set_pxa_fb_info(&toshiba_lcd);
+               pxa_set_fb_info(NULL, &toshiba_lcd);
 
        pxa_set_mci_info(&trizeps4_mci_platform_data);
 #ifndef STATUS_LEDS_ON_STUART_PINS
index aa70331..b523f11 100644 (file)
@@ -932,7 +932,7 @@ static void __init viper_init(void)
        /* Wake-up serial console */
        viper_init_serial_gpio();
 
-       set_pxa_fb_info(&fb_info);
+       pxa_set_fb_info(NULL, &fb_info);
 
        /* v1 hardware cannot use the datacs line */
        version = viper_hw_version();
index e709fd4..f71d377 100644 (file)
@@ -572,7 +572,7 @@ static void __init vpac270_lcd_init(void)
        }
 
        vpac270_lcd_screen.pxafb_lcd_power = vpac270_lcd_power;
-       set_pxa_fb_info(&vpac270_lcd_screen);
+       pxa_set_fb_info(NULL, &vpac270_lcd_screen);
        return;
 
 err2:
index aaf8837..fbe9e02 100644 (file)
@@ -91,13 +91,13 @@ static unsigned long z2_pin_config[] = {
        GPIO47_STUART_TXD,
 
        /* Keypad */
-       GPIO100_KP_MKIN_0       | WAKEUP_ON_LEVEL_HIGH,
-       GPIO101_KP_MKIN_1       | WAKEUP_ON_LEVEL_HIGH,
-       GPIO102_KP_MKIN_2       | WAKEUP_ON_LEVEL_HIGH,
-       GPIO34_KP_MKIN_3        | WAKEUP_ON_LEVEL_HIGH,
-       GPIO38_KP_MKIN_4        | WAKEUP_ON_LEVEL_HIGH,
-       GPIO16_KP_MKIN_5        | WAKEUP_ON_LEVEL_HIGH,
-       GPIO17_KP_MKIN_6        | WAKEUP_ON_LEVEL_HIGH,
+       GPIO100_KP_MKIN_0,
+       GPIO101_KP_MKIN_1,
+       GPIO102_KP_MKIN_2,
+       GPIO34_KP_MKIN_3,
+       GPIO38_KP_MKIN_4,
+       GPIO16_KP_MKIN_5,
+       GPIO17_KP_MKIN_6,
        GPIO103_KP_MKOUT_0,
        GPIO104_KP_MKOUT_1,
        GPIO105_KP_MKOUT_2,
@@ -138,8 +138,7 @@ static unsigned long z2_pin_config[] = {
        GPIO1_GPIO,             /* Power button */
        GPIO37_GPIO,            /* Headphone detect */
        GPIO98_GPIO,            /* Lid switch */
-       GPIO14_GPIO,            /* WiFi Reset */
-       GPIO15_GPIO,            /* WiFi Power */
+       GPIO14_GPIO,            /* WiFi Power */
        GPIO24_GPIO,            /* WiFi CS */
        GPIO36_GPIO,            /* WiFi IRQ */
        GPIO88_GPIO,            /* LCD CS */
@@ -204,7 +203,7 @@ static struct platform_pwm_backlight_data z2_backlight_data[] = {
                /* Keypad Backlight */
                .pwm_id         = 1,
                .max_brightness = 1023,
-               .dft_brightness = 512,
+               .dft_brightness = 0,
                .pwm_period_ns  = 1260320,
        },
        [1] = {
@@ -271,7 +270,7 @@ static struct pxafb_mach_info z2_lcd_screen = {
 
 static void __init z2_lcd_init(void)
 {
-       set_pxa_fb_info(&z2_lcd_screen);
+       pxa_set_fb_info(NULL, &z2_lcd_screen);
 }
 #else
 static inline void z2_lcd_init(void) {}
@@ -309,12 +308,12 @@ struct gpio_led z2_gpio_leds[] = {
        .active_low             = 1,
 }, {
        .name                   = "z2:green:charged",
-       .default_trigger        = "none",
+       .default_trigger        = "mmc0",
        .gpio                   = GPIO85_ZIPITZ2_LED_CHARGED,
        .active_low             = 1,
 }, {
        .name                   = "z2:amber:charging",
-       .default_trigger        = "none",
+       .default_trigger        = "Z2-charging-or-full",
        .gpio                   = GPIO83_ZIPITZ2_LED_CHARGING,
        .active_low             = 1,
 },
@@ -427,8 +426,22 @@ static inline void z2_mkp_init(void) {}
  ******************************************************************************/
 #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
 static struct gpio_keys_button z2_pxa_buttons[] = {
-       {KEY_POWER, GPIO1_ZIPITZ2_POWER_BUTTON, 0, "Power Button" },
-       {KEY_CLOSE, GPIO98_ZIPITZ2_LID_BUTTON, 0, "Lid Button" },
+       {
+               .code           = KEY_POWER,
+               .gpio           = GPIO1_ZIPITZ2_POWER_BUTTON,
+               .active_low     = 0,
+               .desc           = "Power Button",
+               .wakeup         = 1,
+               .type           = EV_KEY,
+       },
+       {
+               .code           = SW_LID,
+               .gpio           = GPIO98_ZIPITZ2_LID_BUTTON,
+               .active_low     = 1,
+               .desc           = "Lid Switch",
+               .wakeup         = 0,
+               .type           = EV_SW,
+       },
 };
 
 static struct gpio_keys_platform_data z2_pxa_keys_data = {
@@ -461,9 +474,9 @@ static struct z2_battery_info batt_chip_info = {
        .batt_I2C_addr  = 0x55,
        .batt_I2C_reg   = 2,
        .charge_gpio    = GPIO0_ZIPITZ2_AC_DETECT,
-       .min_voltage    = 2400000,
-       .max_voltage    = 3700000,
-       .batt_div       = 69,
+       .min_voltage    = 3475000,
+       .max_voltage    = 4190000,
+       .batt_div       = 59,
        .batt_mult      = 1000000,
        .batt_tech      = POWER_SUPPLY_TECHNOLOGY_LION,
        .batt_name      = "Z2",
@@ -497,26 +510,16 @@ static int z2_lbs_spi_setup(struct spi_device *spi)
 {
        int ret = 0;
 
-       ret = gpio_request(GPIO15_ZIPITZ2_WIFI_POWER, "WiFi Power");
+       ret = gpio_request(GPIO14_ZIPITZ2_WIFI_POWER, "WiFi Power");
        if (ret)
                goto err;
 
-       ret = gpio_direction_output(GPIO15_ZIPITZ2_WIFI_POWER, 1);
+       ret = gpio_direction_output(GPIO14_ZIPITZ2_WIFI_POWER, 1);
        if (ret)
                goto err2;
 
-       ret = gpio_request(GPIO14_ZIPITZ2_WIFI_RESET, "WiFi Reset");
-       if (ret)
-               goto err2;
-
-       ret = gpio_direction_output(GPIO14_ZIPITZ2_WIFI_RESET, 0);
-       if (ret)
-               goto err3;
-
-       /* Reset the card */
+       /* Wait until card is powered on */
        mdelay(180);
-       gpio_set_value(GPIO14_ZIPITZ2_WIFI_RESET, 1);
-       mdelay(20);
 
        spi->bits_per_word = 16;
        spi->mode = SPI_MODE_2,
@@ -525,22 +528,18 @@ static int z2_lbs_spi_setup(struct spi_device *spi)
 
        return 0;
 
-err3:
-       gpio_free(GPIO14_ZIPITZ2_WIFI_RESET);
 err2:
-       gpio_free(GPIO15_ZIPITZ2_WIFI_POWER);
+       gpio_free(GPIO14_ZIPITZ2_WIFI_POWER);
 err:
        return ret;
 };
 
 static int z2_lbs_spi_teardown(struct spi_device *spi)
 {
-       gpio_set_value(GPIO14_ZIPITZ2_WIFI_RESET, 0);
-       gpio_set_value(GPIO15_ZIPITZ2_WIFI_POWER, 0);
-       gpio_free(GPIO14_ZIPITZ2_WIFI_RESET);
-       gpio_free(GPIO15_ZIPITZ2_WIFI_POWER);
-       return 0;
+       gpio_set_value(GPIO14_ZIPITZ2_WIFI_POWER, 0);
+       gpio_free(GPIO14_ZIPITZ2_WIFI_POWER);
 
+       return 0;
 };
 
 static struct pxa2xx_spi_chip z2_lbs_chip_info = {
index 139aa7f..00363c7 100644 (file)
@@ -847,7 +847,7 @@ static void __init zeus_init(void)
        if (zeus_setup_fb_gpios())
                pr_err("Failed to setup fb gpios\n");
        else
-               set_pxa_fb_info(&zeus_fb_info);
+               pxa_set_fb_info(NULL, &zeus_fb_info);
 
        pxa_set_mci_info(&zeus_mci_platform_data);
        pxa_set_udc_info(&zeus_udc_info);
index a4c784a..5821185 100644 (file)
@@ -208,7 +208,7 @@ static void __init zylonite_init_lcd(void)
        platform_device_register(&zylonite_backlight_device);
 
        if (lcd_id & 0x20) {
-               set_pxa_fb_info(&zylonite_sharp_lcd_info);
+               pxa_set_fb_info(NULL, &zylonite_sharp_lcd_info);
                return;
        }
 
@@ -220,7 +220,7 @@ static void __init zylonite_init_lcd(void)
        else
                zylonite_toshiba_lcd_info.modes = &toshiba_ltm04c380k_mode;
 
-       set_pxa_fb_info(&zylonite_toshiba_lcd_info);
+       pxa_set_fb_info(NULL, &zylonite_toshiba_lcd_info);
 }
 #else
 static inline void zylonite_init_lcd(void) {}
index 2ecc1d9..10e75fa 100644 (file)
@@ -348,7 +348,7 @@ static void __init gic_init_irq(void)
 
 #ifndef CONFIG_REALVIEW_EB_ARM11MP_REVB
                /* board GIC, secondary */
-               gic_init(1, 64, __io_address(REALVIEW_EB_GIC_DIST_BASE),
+               gic_init(1, 96, __io_address(REALVIEW_EB_GIC_DIST_BASE),
                         __io_address(REALVIEW_EB_GIC_CPU_BASE));
                gic_cascade_irq(1, IRQ_EB11MP_EB_IRQ1);
 #endif
index 96e59e3..eb7ffa0 100644 (file)
@@ -314,7 +314,7 @@ static struct mmci_platform_data mmc0_plat_data = {
        .gpio_cd        = -1,
 };
 
-static struct resource chalcd_resources[] = {
+static struct resource char_lcd_resources[] = {
        {
                .start = VERSATILE_CHAR_LCD_BASE,
                .end   = (VERSATILE_CHAR_LCD_BASE + SZ_4K - 1),
index 6561c9d..ccc789e 100644 (file)
@@ -53,7 +53,7 @@ struct platform_device *__init imx_add_fec(
        struct resource res[] = {
                {
                        .start = data->iobase,
-                       .end = data->iobase + SZ_4K,
+                       .end = data->iobase + SZ_4K - 1,
                        .flags = IORESOURCE_MEM,
                }, {
                        .start = data->irq,
index 10653cc..805336f 100644 (file)
@@ -27,7 +27,7 @@ struct platform_device *__init imx_add_imxdi_rtc(
        struct resource res[] = {
                {
                        .start = data->iobase,
-                       .end = data->iobase + SZ_16K,
+                       .end = data->iobase + SZ_16K - 1,
                        .flags = IORESOURCE_MEM,
                }, {
                        .start = data->irq,
index 5cd6466..6fda788 100644 (file)
 #define MX31_AUDMUX_PORT5_SSI_PINS_5   4
 #define MX31_AUDMUX_PORT6_SSI_PINS_6   5
 
+#define MX51_AUDMUX_PORT1_SSI0         0
+#define MX51_AUDMUX_PORT2_SSI1         1
+#define MX51_AUDMUX_PORT3              2
+#define MX51_AUDMUX_PORT4              3
+#define MX51_AUDMUX_PORT5              4
+#define MX51_AUDMUX_PORT6              5
+#define MX51_AUDMUX_PORT7              6
+
 /* Register definitions for the i.MX21/27 Digital Audio Multiplexer */
 #define MXC_AUDMUX_V1_PCR_INMMASK(x)   ((x) & 0xff)
 #define MXC_AUDMUX_V1_PCR_INMEN                (1 << 8)
@@ -28,7 +36,7 @@
 #define MXC_AUDMUX_V1_PCR_TCLKDIR      (1 << 30)
 #define MXC_AUDMUX_V1_PCR_TFSDIR       (1 << 31)
 
-/* Register definitions for the i.MX25/31/35 Digital Audio Multiplexer */
+/* Register definitions for the i.MX25/31/35/51 Digital Audio Multiplexer */
 #define MXC_AUDMUX_V2_PTCR_TFSDIR      (1 << 31)
 #define MXC_AUDMUX_V2_PTCR_TFSEL(x)    (((x) & 0xf) << 27)
 #define MXC_AUDMUX_V2_PTCR_TCLKDIR     (1 << 26)
index c4f116d..7a9b20a 100644 (file)
 #define PC31_PF_SSI3_CLK       (GPIO_PORTC | GPIO_PF | GPIO_IN | 31)
 #define PD17_PF_I2C_DATA       (GPIO_PORTD | GPIO_PF | GPIO_OUT | 17)
 #define PD18_PF_I2C_CLK                (GPIO_PORTD | GPIO_PF | GPIO_OUT | 18)
-#define PD19_PF_CSPI2_SS2      (GPIO_PORTD | GPIO_PF | 19)
-#define PD20_PF_CSPI2_SS1      (GPIO_PORTD | GPIO_PF | 20)
-#define PD21_PF_CSPI2_SS0      (GPIO_PORTD | GPIO_PF | 21)
-#define PD22_PF_CSPI2_SCLK     (GPIO_PORTD | GPIO_PF | 22)
-#define PD23_PF_CSPI2_MISO     (GPIO_PORTD | GPIO_PF | 23)
-#define PD24_PF_CSPI2_MOSI     (GPIO_PORTD | GPIO_PF | 24)
+#define PD19_PF_CSPI2_SS2      (GPIO_PORTD | GPIO_PF | GPIO_OUT | 19)
+#define PD20_PF_CSPI2_SS1      (GPIO_PORTD | GPIO_PF | GPIO_OUT | 20)
+#define PD21_PF_CSPI2_SS0      (GPIO_PORTD | GPIO_PF | GPIO_OUT | 21)
+#define PD22_PF_CSPI2_SCLK     (GPIO_PORTD | GPIO_PF | GPIO_OUT | 22)
+#define PD23_PF_CSPI2_MISO     (GPIO_PORTD | GPIO_PF | GPIO_IN | 23)
+#define PD24_PF_CSPI2_MOSI     (GPIO_PORTD | GPIO_PF | GPIO_OUT | 24)
 #define PD25_PF_CSPI1_RDY      (GPIO_PORTD | GPIO_PF | GPIO_OUT | 25)
 #define PD26_PF_CSPI1_SS2      (GPIO_PORTD | GPIO_PF | GPIO_OUT | 26)
 #define PD27_PF_CSPI1_SS1      (GPIO_PORTD | GPIO_PF | GPIO_OUT | 27)
index aaec2a6..5f2da75 100644 (file)
 #define MX50_INT_APBHDMA_CHAN6 116
 #define MX50_INT_APBHDMA_CHAN7 117
 
+#if !defined(__ASSEMBLY__) && !defined(__MXC_BOOT_UNCOMPRESS)
+extern int mx50_revision(void);
+#endif
+
 #endif /* ifndef __MACH_MX50_H__ */
index 1eb339e..dede19a 100644 (file)
 
 #if !defined(__ASSEMBLY__) && !defined(__MXC_BOOT_UNCOMPRESS)
 extern int mx51_revision(void);
+extern void mx51_display_revision(void);
 #endif
 
 /* tape-out 1 defines */
index 7e07263..1aea818 100644 (file)
 #define IMX_CHIP_REVISION_3_3          0x33
 #define IMX_CHIP_REVISION_UNKNOWN      0xff
 
+#define IMX_CHIP_REVISION_1_0_STRING           "1.0"
+#define IMX_CHIP_REVISION_1_1_STRING           "1.1"
+#define IMX_CHIP_REVISION_1_2_STRING           "1.2"
+#define IMX_CHIP_REVISION_1_3_STRING           "1.3"
+#define IMX_CHIP_REVISION_2_0_STRING           "2.0"
+#define IMX_CHIP_REVISION_2_1_STRING           "2.1"
+#define IMX_CHIP_REVISION_2_2_STRING           "2.2"
+#define IMX_CHIP_REVISION_2_3_STRING           "2.3"
+#define IMX_CHIP_REVISION_3_0_STRING           "3.0"
+#define IMX_CHIP_REVISION_3_1_STRING           "3.1"
+#define IMX_CHIP_REVISION_3_2_STRING           "3.2"
+#define IMX_CHIP_REVISION_3_3_STRING           "3.3"
+#define IMX_CHIP_REVISION_UNKNOWN_STRING       "unknown"
+
 #ifndef __ASSEMBLY__
 extern unsigned int __mxc_cpu_type;
 #endif
@@ -181,6 +195,15 @@ struct cpu_op {
        u32 cpu_rate;
 };
 
+int tzic_enable_wake(int is_idle);
+enum mxc_cpu_pwr_mode {
+       WAIT_CLOCKED,           /* wfi only */
+       WAIT_UNCLOCKED,         /* WAIT */
+       WAIT_UNCLOCKED_POWER_OFF,       /* WAIT + SRPG */
+       STOP_POWER_ON,          /* just STOP */
+       STOP_POWER_OFF,         /* STOP + SRPG */
+};
+
 extern struct cpu_op *(*get_cpu_op)(int *op);
 #endif
 
index 95be51b..0417da9 100644 (file)
@@ -20,6 +20,8 @@
 #include <mach/hardware.h>
 #include <mach/common.h>
 
+extern void mx5_cpu_lp_set(enum mxc_cpu_pwr_mode mode);
+
 static inline void arch_idle(void)
 {
 #ifdef CONFIG_ARCH_MXC91231
@@ -54,7 +56,9 @@ static inline void arch_idle(void)
                        "orr %0, %0, #0x00000004\n"
                        "mcr p15, 0, %0, c1, c0, 0\n"
                        : "=r" (reg));
-       } else
+       } else if (cpu_is_mx51())
+               mx5_cpu_lp_set(WAIT_UNCLOCKED_POWER_OFF);
+       else
                cpu_do_idle();
 }
 
index 9f0c261..2237ff8 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/clk.h>
 
 #include <mach/hardware.h>
+#include <asm/sched_clock.h>
 #include <asm/mach/time.h>
 #include <mach/common.h>
 
@@ -105,6 +106,11 @@ static void gpt_irq_acknowledge(void)
                __raw_writel(V2_TSTAT_OF1, timer_base + V2_TSTAT);
 }
 
+static cycle_t dummy_get_cycles(struct clocksource *cs)
+{
+       return 0;
+}
+
 static cycle_t mx1_2_get_cycles(struct clocksource *cs)
 {
        return __raw_readl(timer_base + MX1_2_TCN);
@@ -118,18 +124,35 @@ static cycle_t v2_get_cycles(struct clocksource *cs)
 static struct clocksource clocksource_mxc = {
        .name           = "mxc_timer1",
        .rating         = 200,
-       .read           = mx1_2_get_cycles,
+       .read           = dummy_get_cycles,
        .mask           = CLOCKSOURCE_MASK(32),
        .flags          = CLOCK_SOURCE_IS_CONTINUOUS,
 };
 
+static DEFINE_CLOCK_DATA(cd);
+unsigned long long notrace sched_clock(void)
+{
+       cycle_t cyc = clocksource_mxc.read(&clocksource_mxc);
+
+       return cyc_to_sched_clock(&cd, cyc, (u32)~0);
+}
+
+static void notrace mxc_update_sched_clock(void)
+{
+       cycle_t cyc = clocksource_mxc.read(&clocksource_mxc);
+       update_sched_clock(&cd, cyc, (u32)~0);
+}
+
 static int __init mxc_clocksource_init(struct clk *timer_clk)
 {
        unsigned int c = clk_get_rate(timer_clk);
 
        if (timer_is_v2())
                clocksource_mxc.read = v2_get_cycles;
+       else
+               clocksource_mxc.read = mx1_2_get_cycles;
 
+       init_sched_clock(&cd, mxc_update_sched_clock, 32, c);
        clocksource_register_hz(&clocksource_mxc, c);
 
        return 0;
index 49642b5..e9d689b 100644 (file)
@@ -10,7 +10,6 @@ config AVR32
        select GENERIC_IRQ_PROBE
        select HARDIRQS_SW_RESEND
        select GENERIC_IRQ_SHOW
-       select GENERIC_HARDIRQS_NO_DEPRECATED
        help
          AVR32 is a high-performance 32-bit RISC microprocessor core,
          designed for cost-sensitive embedded applications, with particular
index 3753410..f308e1d 100644 (file)
@@ -282,7 +282,7 @@ static struct irq_chip gpio_irqchip = {
 
 static void gpio_irq_handler(unsigned irq, struct irq_desc *desc)
 {
-       struct pio_device       *pio = get_irq_desc_chip_data(desc);
+       struct pio_device       *pio = irq_desc_get_chip_data(desc);
        unsigned                gpio_irq;
 
        gpio_irq = (unsigned) irq_get_handler_data(irq);
index 672c216..8addb12 100644 (file)
@@ -34,7 +34,6 @@ config BLACKFIN
        select GENERIC_ATOMIC64
        select GENERIC_IRQ_PROBE
        select IRQ_PER_CPU if SMP
-       select GENERIC_HARDIRQS_NO_DEPRECATED
 
 config GENERIC_CSUM
        def_bool y
index 362f59d..ad0881b 100644 (file)
@@ -46,7 +46,6 @@ CONFIG_UNIX=y
 # CONFIG_WIRELESS is not set
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_RAM=y
-# CONFIG_MISC_DEVICES is not set
 # CONFIG_INPUT_MOUSEDEV is not set
 CONFIG_INPUT_EVDEV=y
 # CONFIG_INPUT_KEYBOARD is not set
index 6883803..580bf42 100644 (file)
@@ -70,7 +70,6 @@ CONFIG_MTD_ROM=m
 CONFIG_MTD_PHYSMAP=m
 CONFIG_MTD_NAND=m
 CONFIG_BLK_DEV_RAM=y
-# CONFIG_MISC_DEVICES is not set
 CONFIG_NETDEVICES=y
 CONFIG_PHYLIB=y
 CONFIG_SMSC_PHY=y
index b7c8451..77a27e3 100644 (file)
@@ -63,7 +63,6 @@ CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=2
 CONFIG_BLK_DEV_RAM_SIZE=16384
-# CONFIG_MISC_DEVICES is not set
 CONFIG_SCSI=y
 # CONFIG_SCSI_PROC_FS is not set
 CONFIG_BLK_DEV_SD=y
index 97ebe09..8501431 100644 (file)
@@ -58,6 +58,7 @@ CONFIG_MTD_M25P80=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_NBD=y
 CONFIG_BLK_DEV_RAM=y
+CONFIG_MISC_DEVICES=y
 CONFIG_EEPROM_AT25=y
 CONFIG_NETDEVICES=y
 CONFIG_NET_ETHERNET=y
index c245754..dbf750c 100644 (file)
@@ -64,7 +64,6 @@ CONFIG_MTD_ROM=m
 CONFIG_MTD_COMPLEX_MAPPINGS=y
 CONFIG_MTD_GPIO_ADDR=y
 CONFIG_BLK_DEV_RAM=y
-# CONFIG_MISC_DEVICES is not set
 CONFIG_SCSI=y
 CONFIG_BLK_DEV_SD=y
 # CONFIG_SCSI_LOWLEVEL is not set
index baf1c15..07ffbda 100644 (file)
@@ -44,7 +44,6 @@ CONFIG_MTD_CFI=y
 CONFIG_MTD_CFI_INTELEXT=y
 CONFIG_MTD_RAM=y
 CONFIG_MTD_PHYSMAP=y
-# CONFIG_MISC_DEVICES is not set
 CONFIG_NETDEVICES=y
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
index df26758..31d9542 100644 (file)
@@ -63,7 +63,6 @@ CONFIG_MTD_RAM=y
 CONFIG_MTD_COMPLEX_MAPPINGS=y
 CONFIG_MTD_PHYSMAP=y
 CONFIG_BLK_DEV_RAM=y
-# CONFIG_MISC_DEVICES is not set
 CONFIG_SCSI=m
 CONFIG_BLK_DEV_SD=m
 # CONFIG_SCSI_LOWLEVEL is not set
index f503136..b192acf 100644 (file)
@@ -55,7 +55,6 @@ CONFIG_MTD_NAND=y
 CONFIG_MTD_NAND_PLATFORM=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_RAM=y
-# CONFIG_MISC_DEVICES is not set
 CONFIG_NETDEVICES=y
 CONFIG_DAVICOM_PHY=y
 CONFIG_NET_ETHERNET=y
index 7450127..06e9f49 100644 (file)
@@ -45,6 +45,7 @@ CONFIG_MTD_COMPLEX_MAPPINGS=y
 CONFIG_MTD_M25P80=y
 # CONFIG_M25PXX_USE_FAST_READ is not set
 CONFIG_BLK_DEV_RAM=y
+CONFIG_MISC_DEVICES=y
 CONFIG_EEPROM_AT25=y
 CONFIG_NETDEVICES=y
 CONFIG_NET_ETHERNET=y
index 8538095..12e66cd 100644 (file)
@@ -48,6 +48,7 @@ CONFIG_MTD_COMPLEX_MAPPINGS=y
 CONFIG_MTD_UCLINUX=y
 CONFIG_MTD_NAND=m
 CONFIG_BLK_DEV_RAM=y
+CONFIG_MISC_DEVICES=y
 CONFIG_EEPROM_AT25=m
 CONFIG_NETDEVICES=y
 # CONFIG_NETDEV_1000 is not set
index 49762c6..8a0fed1 100644 (file)
@@ -25,7 +25,6 @@
 #include <asm-generic/bitops/const_hweight.h>
 #include <asm-generic/bitops/lock.h>
 
-#include <asm-generic/bitops/le.h>
 #include <asm-generic/bitops/ext2-atomic.h>
 
 #ifndef CONFIG_SMP
@@ -113,6 +112,9 @@ static inline int test_and_change_bit(int nr, volatile unsigned long *addr)
 
 #endif /* CONFIG_SMP */
 
+/* Needs to be after test_bit and friends */
+#include <asm-generic/bitops/le.h>
+
 /*
  * hweightN: returns the hamming weight (i.e. the number
  * of bits set) of a N-bit word
index a6dfa6b..35e350c 100644 (file)
@@ -4,7 +4,7 @@
  * Licensed under the GPL-2 or later
  */
 
-#define pr_fmt(fmt) "module %s: " fmt
+#define pr_fmt(fmt) "module %s: " fmt, mod->name
 
 #include <linux/moduleloader.h>
 #include <linux/elf.h>
@@ -57,8 +57,7 @@ module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
                        dest = l1_inst_sram_alloc(s->sh_size);
                        mod->arch.text_l1 = dest;
                        if (dest == NULL) {
-                               pr_err("L1 inst memory allocation failed\n",
-                                       mod->name);
+                               pr_err("L1 inst memory allocation failed\n");
                                return -1;
                        }
                        dma_memcpy(dest, (void *)s->sh_addr, s->sh_size);
@@ -70,8 +69,7 @@ module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
                        dest = l1_data_sram_alloc(s->sh_size);
                        mod->arch.data_a_l1 = dest;
                        if (dest == NULL) {
-                               pr_err("L1 data memory allocation failed\n",
-                                       mod->name);
+                               pr_err("L1 data memory allocation failed\n");
                                return -1;
                        }
                        memcpy(dest, (void *)s->sh_addr, s->sh_size);
@@ -83,8 +81,7 @@ module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
                        dest = l1_data_sram_zalloc(s->sh_size);
                        mod->arch.bss_a_l1 = dest;
                        if (dest == NULL) {
-                               pr_err("L1 data memory allocation failed\n",
-                                       mod->name);
+                               pr_err("L1 data memory allocation failed\n");
                                return -1;
                        }
 
@@ -93,8 +90,7 @@ module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
                        dest = l1_data_B_sram_alloc(s->sh_size);
                        mod->arch.data_b_l1 = dest;
                        if (dest == NULL) {
-                               pr_err("L1 data memory allocation failed\n",
-                                       mod->name);
+                               pr_err("L1 data memory allocation failed\n");
                                return -1;
                        }
                        memcpy(dest, (void *)s->sh_addr, s->sh_size);
@@ -104,8 +100,7 @@ module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
                        dest = l1_data_B_sram_alloc(s->sh_size);
                        mod->arch.bss_b_l1 = dest;
                        if (dest == NULL) {
-                               pr_err("L1 data memory allocation failed\n",
-                                       mod->name);
+                               pr_err("L1 data memory allocation failed\n");
                                return -1;
                        }
                        memset(dest, 0, s->sh_size);
@@ -117,8 +112,7 @@ module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
                        dest = l2_sram_alloc(s->sh_size);
                        mod->arch.text_l2 = dest;
                        if (dest == NULL) {
-                               pr_err("L2 SRAM allocation failed\n",
-                                       mod->name);
+                               pr_err("L2 SRAM allocation failed\n");
                                return -1;
                        }
                        memcpy(dest, (void *)s->sh_addr, s->sh_size);
@@ -130,8 +124,7 @@ module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
                        dest = l2_sram_alloc(s->sh_size);
                        mod->arch.data_l2 = dest;
                        if (dest == NULL) {
-                               pr_err("L2 SRAM allocation failed\n",
-                                       mod->name);
+                               pr_err("L2 SRAM allocation failed\n");
                                return -1;
                        }
                        memcpy(dest, (void *)s->sh_addr, s->sh_size);
@@ -143,8 +136,7 @@ module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
                        dest = l2_sram_zalloc(s->sh_size);
                        mod->arch.bss_l2 = dest;
                        if (dest == NULL) {
-                               pr_err("L2 SRAM allocation failed\n",
-                                       mod->name);
+                               pr_err("L2 SRAM allocation failed\n");
                                return -1;
                        }
 
@@ -160,9 +152,9 @@ module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
 
 int
 apply_relocate(Elf_Shdr * sechdrs, const char *strtab,
-              unsigned int symindex, unsigned int relsec, struct module *me)
+              unsigned int symindex, unsigned int relsec, struct module *mod)
 {
-       pr_err(".rel unsupported\n", me->name);
+       pr_err(".rel unsupported\n");
        return -ENOEXEC;
 }
 
@@ -186,7 +178,7 @@ apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab,
        Elf32_Sym *sym;
        unsigned long location, value, size;
 
-       pr_debug("applying relocate section %u to %u\n", mod->name,
+       pr_debug("applying relocate section %u to %u\n",
                relsec, sechdrs[relsec].sh_info);
 
        for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
@@ -203,14 +195,14 @@ apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab,
 
 #ifdef CONFIG_SMP
                if (location >= COREB_L1_DATA_A_START) {
-                       pr_err("cannot relocate in L1: %u (SMP kernel)",
-                               mod->name, ELF32_R_TYPE(rel[i].r_info));
+                       pr_err("cannot relocate in L1: %u (SMP kernel)\n",
+                               ELF32_R_TYPE(rel[i].r_info));
                        return -ENOEXEC;
                }
 #endif
 
                pr_debug("location is %lx, value is %lx type is %d\n",
-                       mod->name, location, value, ELF32_R_TYPE(rel[i].r_info));
+                       location, value, ELF32_R_TYPE(rel[i].r_info));
 
                switch (ELF32_R_TYPE(rel[i].r_info)) {
 
@@ -230,11 +222,11 @@ apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab,
                case R_BFIN_PCREL12_JUMP_S:
                case R_BFIN_PCREL10:
                        pr_err("unsupported relocation: %u (no -mlong-calls?)\n",
-                               mod->name, ELF32_R_TYPE(rel[i].r_info));
+                               ELF32_R_TYPE(rel[i].r_info));
                        return -ENOEXEC;
 
                default:
-                       pr_err("unknown relocation: %u\n", mod->name,
+                       pr_err("unknown relocation: %u\n",
                                ELF32_R_TYPE(rel[i].r_info));
                        return -ENOEXEC;
                }
@@ -251,8 +243,7 @@ apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab,
                        isram_memcpy((void *)location, &value, size);
                        break;
                default:
-                       pr_err("invalid relocation for %#lx\n",
-                               mod->name, location);
+                       pr_err("invalid relocation for %#lx\n", location);
                        return -ENOEXEC;
                }
        }
index 617925d..a6d0306 100644 (file)
@@ -55,7 +55,6 @@ config CRIS
        default y
        select HAVE_IDE
        select HAVE_GENERIC_HARDIRQS
-       select GENERIC_HARDIRQS_NO_DEPRECATED
        select GENERIC_IRQ_SHOW
 
 config HZ
index 6db8aea..064f621 100644 (file)
@@ -7,7 +7,6 @@ config FRV
        select HAVE_PERF_EVENTS
        select HAVE_GENERIC_HARDIRQS
        select GENERIC_IRQ_SHOW
-       select GENERIC_HARDIRQS_NO_DEPRECATED
 
 config ZONE_DMA
        bool
index 931a1ac..e20322f 100644 (file)
@@ -3,7 +3,6 @@ config H8300
        default y
        select HAVE_IDE
        select HAVE_GENERIC_HARDIRQS
-       select GENERIC_HARDIRQS_NO_DEPRECATED
        select GENERIC_IRQ_SHOW
 
 config SYMBOL_PREFIX
index c76d8dc..7aab87f 100644 (file)
@@ -45,38 +45,6 @@ static int licenseID_open(struct inode *inode, struct file *file)
        return single_open(file, licenseID_show, NULL);
 }
 
-/*
- * Enable forced interrupt by default.
- * When set, the sn interrupt handler writes the force interrupt register on
- * the bridge chip.  The hardware will then send an interrupt message if the
- * interrupt line is active.  This mimics a level sensitive interrupt.
- */
-extern int sn_force_interrupt_flag;
-
-static int sn_force_interrupt_show(struct seq_file *s, void *p)
-{
-       seq_printf(s, "Force interrupt is %s\n",
-               sn_force_interrupt_flag ? "enabled" : "disabled");
-       return 0;
-}
-
-static ssize_t sn_force_interrupt_write_proc(struct file *file,
-               const char __user *buffer, size_t count, loff_t *data)
-{
-       char val;
-
-       if (copy_from_user(&val, buffer, 1))
-               return -EFAULT;
-
-       sn_force_interrupt_flag = (val == '0') ? 0 : 1;
-       return count;
-}
-
-static int sn_force_interrupt_open(struct inode *inode, struct file *file)
-{
-       return single_open(file, sn_force_interrupt_show, NULL);
-}
-
 static int coherence_id_show(struct seq_file *s, void *p)
 {
        seq_printf(s, "%d\n", partition_coherence_id());
@@ -114,14 +82,6 @@ static const struct file_operations proc_license_id_fops = {
        .release        = single_release,
 };
 
-static const struct file_operations proc_sn_force_intr_fops = {
-       .open           = sn_force_interrupt_open,
-       .read           = seq_read,
-       .write          = sn_force_interrupt_write_proc,
-       .llseek         = seq_lseek,
-       .release        = single_release,
-};
-
 static const struct file_operations proc_coherence_id_fops = {
        .open           = coherence_id_open,
        .read           = seq_read,
@@ -149,8 +109,6 @@ void register_sn_procfs(void)
        proc_create("system_serial_number", 0444, sgi_proc_dir,
                    &proc_system_sn_fops);
        proc_create("licenseID", 0444, sgi_proc_dir, &proc_license_id_fops);
-       proc_create("sn_force_interrupt", 0644, sgi_proc_dir,
-                   &proc_sn_force_intr_fops);
        proc_create("coherence_id", 0444, sgi_proc_dir,
                    &proc_coherence_id_fops);
        proc_create("sn_topology", 0444, sgi_proc_dir, &proc_sn_topo_fops);
index b28d090..736b808 100644 (file)
@@ -8,7 +8,6 @@ config M32R
        select HAVE_KERNEL_BZIP2
        select HAVE_KERNEL_LZMA
        select HAVE_GENERIC_HARDIRQS
-       select GENERIC_HARDIRQS_NO_DEPRECATED
        select GENERIC_IRQ_PROBE
        select GENERIC_IRQ_SHOW
 
index 6e056d3..75531da 100644 (file)
@@ -5,7 +5,6 @@ config M68K
        select HAVE_AOUT if MMU
        select GENERIC_ATOMIC64 if MMU
        select HAVE_GENERIC_HARDIRQS if !MMU
-       select GENERIC_HARDIRQS_NO_DEPRECATED if !MMU
 
 config RWSEM_GENERIC_SPINLOCK
        bool
index c49c326..851b3bf 100644 (file)
@@ -17,7 +17,6 @@ config MICROBLAZE
        select OF_EARLY_FLATTREE
        select HAVE_GENERIC_HARDIRQS
        select GENERIC_IRQ_PROBE
-       select GENERIC_HARDIRQS_NO_DEPRECATED
        select GENERIC_IRQ_SHOW
 
 config SWAP
index a523c94..feaf09c 100644 (file)
@@ -2,7 +2,6 @@ config MN10300
        def_bool y
        select HAVE_OPROFILE
        select HAVE_GENERIC_HARDIRQS
-       select GENERIC_HARDIRQS_NO_DEPRECATED
        select GENERIC_IRQ_SHOW
        select HAVE_ARCH_TRACEHOOK
        select HAVE_ARCH_KGDB
index 9b1f427..69ff049 100644 (file)
@@ -15,7 +15,6 @@ config PARISC
        select HAVE_GENERIC_HARDIRQS
        select GENERIC_IRQ_PROBE
        select IRQ_PER_CPU
-       select GENERIC_HARDIRQS_NO_DEPRECATED
 
        help
          The PA-RISC microprocessor is designed by Hewlett-Packard and used
index d0e8a1d..b6ff882 100644 (file)
@@ -138,7 +138,6 @@ config PPC
        select HAVE_GENERIC_HARDIRQS
        select HAVE_SPARSE_IRQ
        select IRQ_PER_CPU
-       select GENERIC_HARDIRQS_NO_DEPRECATED
        select GENERIC_IRQ_SHOW
        select GENERIC_IRQ_SHOW_LEVEL
 
index 6cf9d66..abf74dc 100644 (file)
@@ -47,6 +47,7 @@ CONFIG_MTD_NAND_NDFC=y
 CONFIG_MTD_UBI=y
 CONFIG_PROC_DEVICETREE=y
 CONFIG_BLK_DEV_RAM=y
+CONFIG_MISC_DEVICES=y
 CONFIG_EEPROM_AT24=y
 CONFIG_SCSI=y
 CONFIG_BLK_DEV_SD=y
index 6828eda..0c7de96 100644 (file)
@@ -43,6 +43,7 @@ CONFIG_PROC_DEVICETREE=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=32768
+CONFIG_MISC_DEVICES=y
 CONFIG_EEPROM_LEGACY=y
 CONFIG_SCSI_TGT=y
 CONFIG_BLK_DEV_SD=y
index 4b24412..d41857a 100644 (file)
@@ -85,6 +85,7 @@ CONFIG_BLK_DEV_CRYPTOLOOP=m
 CONFIG_BLK_DEV_NBD=m
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=131072
+CONFIG_MISC_DEVICES=y
 CONFIG_DS1682=y
 CONFIG_IDE=y
 CONFIG_BLK_DEV_IDECS=y
index a360ba4..38303ec 100644 (file)
@@ -85,6 +85,7 @@ CONFIG_BLK_DEV_CRYPTOLOOP=m
 CONFIG_BLK_DEV_NBD=m
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=131072
+CONFIG_MISC_DEVICES=y
 CONFIG_DS1682=y
 CONFIG_IDE=y
 CONFIG_BLK_DEV_IDECS=y
index be2829d..9853397 100644 (file)
@@ -138,6 +138,7 @@ CONFIG_BLK_DEV_CRYPTOLOOP=m
 CONFIG_BLK_DEV_NBD=m
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=131072
+CONFIG_MISC_DEVICES=y
 CONFIG_DS1682=y
 CONFIG_BLK_DEV_SD=y
 CONFIG_CHR_DEV_ST=y
index 0c9c7ed..b614508 100644 (file)
@@ -63,6 +63,7 @@ CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_NBD=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=131072
+CONFIG_MISC_DEVICES=y
 CONFIG_EEPROM_LEGACY=y
 CONFIG_BLK_DEV_SD=y
 CONFIG_CHR_DEV_ST=y
index 06f9549..9fa1613 100644 (file)
@@ -32,6 +32,7 @@ CONFIG_PROC_DEVICETREE=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=131072
+CONFIG_MISC_DEVICES=y
 CONFIG_EEPROM_LEGACY=y
 CONFIG_INPUT_FF_MEMLESS=m
 # CONFIG_INPUT_MOUSEDEV is not set
index f39d0cf..8a874b9 100644 (file)
@@ -78,6 +78,7 @@ CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=2
 CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_MISC_DEVICES=y
 CONFIG_EEPROM_LEGACY=m
 CONFIG_BLK_DEV_SD=y
 CONFIG_CHR_DEV_SG=y
index 62db8a3..c02bbb2 100644 (file)
@@ -61,6 +61,7 @@ CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=1
 CONFIG_BLK_DEV_RAM_SIZE=8192
 CONFIG_BLK_DEV_XIP=y
+CONFIG_MISC_DEVICES=y
 CONFIG_EEPROM_AT24=y
 CONFIG_SCSI=y
 # CONFIG_SCSI_PROC_FS is not set
index 7376e27..e63f537 100644 (file)
@@ -52,6 +52,7 @@ CONFIG_PROC_DEVICETREE=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=32768
+CONFIG_MISC_DEVICES=y
 CONFIG_EEPROM_AT24=y
 CONFIG_SCSI_TGT=y
 CONFIG_BLK_DEV_SD=y
index 99a19d1..c06a86c 100644 (file)
@@ -82,6 +82,7 @@ CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_NBD=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=131072
+CONFIG_MISC_DEVICES=y
 CONFIG_EEPROM_LEGACY=y
 CONFIG_BLK_DEV_SD=y
 CONFIG_CHR_DEV_ST=y
index c636f23..942ced9 100644 (file)
@@ -84,6 +84,7 @@ CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_NBD=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=131072
+CONFIG_MISC_DEVICES=y
 CONFIG_EEPROM_LEGACY=y
 CONFIG_BLK_DEV_SD=y
 CONFIG_CHR_DEV_ST=y
index 55b5431..038a308 100644 (file)
@@ -66,6 +66,7 @@ CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_NBD=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=131072
+CONFIG_MISC_DEVICES=y
 CONFIG_EEPROM_LEGACY=y
 CONFIG_BLK_DEV_SD=y
 CONFIG_CHR_DEV_ST=y
index edd2d54..f4deb0b 100644 (file)
@@ -59,6 +59,7 @@ CONFIG_PROC_DEVICETREE=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=16384
+CONFIG_MISC_DEVICES=y
 CONFIG_EEPROM_LEGACY=y
 CONFIG_IDE=y
 CONFIG_BLK_DEV_IDECD=y
index 9d64a68..0a10fb0 100644 (file)
@@ -398,6 +398,7 @@ CONFIG_BLK_DEV_RAM_SIZE=16384
 CONFIG_CDROM_PKTCDVD=m
 CONFIG_VIRTIO_BLK=m
 CONFIG_BLK_DEV_HD=y
+CONFIG_MISC_DEVICES=y
 CONFIG_ENCLOSURE_SERVICES=m
 CONFIG_SENSORS_TSL2550=m
 CONFIG_EEPROM_AT24=m
index 9c3f22c..249ddd0 100644 (file)
@@ -189,6 +189,7 @@ CONFIG_TIGON3=y
 CONFIG_BNX2=m
 CONFIG_CHELSIO_T1=m
 CONFIG_CHELSIO_T3=m
+CONFIG_CHELSIO_T4=m
 CONFIG_EHEA=y
 CONFIG_IXGBE=m
 CONFIG_IXGB=m
@@ -255,6 +256,8 @@ CONFIG_INFINIBAND_USER_MAD=m
 CONFIG_INFINIBAND_USER_ACCESS=m
 CONFIG_INFINIBAND_MTHCA=m
 CONFIG_INFINIBAND_EHCA=m
+CONFIG_INFINIBAND_CXGB3=m
+CONFIG_INFINIBAND_CXGB4=m
 CONFIG_MLX4_INFINIBAND=m
 CONFIG_INFINIBAND_IPOIB=m
 CONFIG_INFINIBAND_IPOIB_CM=y
index 6d2416a..dd70fac 100644 (file)
@@ -42,6 +42,7 @@ extern void __dma_free_coherent(size_t size, void *vaddr);
 extern void __dma_sync(void *vaddr, size_t size, int direction);
 extern void __dma_sync_page(struct page *page, unsigned long offset,
                                 size_t size, int direction);
+extern unsigned long __dma_get_coherent_pfn(unsigned long cpu_addr);
 
 #else /* ! CONFIG_NOT_COHERENT_CACHE */
 /*
@@ -198,6 +199,11 @@ static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr)
 #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
 #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
 
+extern int dma_mmap_coherent(struct device *, struct vm_area_struct *,
+                            void *, dma_addr_t, size_t);
+#define ARCH_HAS_DMA_MMAP_COHERENT
+
+
 static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
                enum dma_data_direction direction)
 {
index acac35d..ae7b3ef 100644 (file)
@@ -27,7 +27,7 @@
 #define STE_VSID_SHIFT 12
 
 /* Location of cpu0's segment table */
-#define STAB0_PAGE     0x6
+#define STAB0_PAGE     0x8
 #define STAB0_OFFSET   (STAB0_PAGE << 12)
 #define STAB0_PHYS_ADDR        (STAB0_OFFSET + PHYSICAL_START)
 
index da4b200..2cd664e 100644 (file)
@@ -100,7 +100,7 @@ extern phys_addr_t kernstart_addr;
 #endif
 
 #ifdef CONFIG_FLATMEM
-#define ARCH_PFN_OFFSET                (MEMORY_START >> PAGE_SHIFT)
+#define ARCH_PFN_OFFSET                ((unsigned long)(MEMORY_START >> PAGE_SHIFT))
 #define pfn_valid(pfn)         ((pfn) >= ARCH_PFN_OFFSET && (pfn) < max_mapnr)
 #endif
 
index 9e2cb20..f706164 100644 (file)
@@ -81,7 +81,7 @@ int qe_ic_set_high_priority(unsigned int virq, unsigned int priority, int high);
 static inline void qe_ic_cascade_low_ipic(unsigned int irq,
                                          struct irq_desc *desc)
 {
-       struct qe_ic *qe_ic = get_irq_desc_data(desc);
+       struct qe_ic *qe_ic = irq_desc_get_handler_data(desc);
        unsigned int cascade_irq = qe_ic_get_low_irq(qe_ic);
 
        if (cascade_irq != NO_IRQ)
@@ -91,7 +91,7 @@ static inline void qe_ic_cascade_low_ipic(unsigned int irq,
 static inline void qe_ic_cascade_high_ipic(unsigned int irq,
                                           struct irq_desc *desc)
 {
-       struct qe_ic *qe_ic = get_irq_desc_data(desc);
+       struct qe_ic *qe_ic = irq_desc_get_handler_data(desc);
        unsigned int cascade_irq = qe_ic_get_high_irq(qe_ic);
 
        if (cascade_irq != NO_IRQ)
@@ -101,9 +101,9 @@ static inline void qe_ic_cascade_high_ipic(unsigned int irq,
 static inline void qe_ic_cascade_low_mpic(unsigned int irq,
                                          struct irq_desc *desc)
 {
-       struct qe_ic *qe_ic = get_irq_desc_data(desc);
+       struct qe_ic *qe_ic = irq_desc_get_handler_data(desc);
        unsigned int cascade_irq = qe_ic_get_low_irq(qe_ic);
-       struct irq_chip *chip = get_irq_desc_chip(desc);
+       struct irq_chip *chip = irq_desc_get_chip(desc);
 
        if (cascade_irq != NO_IRQ)
                generic_handle_irq(cascade_irq);
@@ -114,9 +114,9 @@ static inline void qe_ic_cascade_low_mpic(unsigned int irq,
 static inline void qe_ic_cascade_high_mpic(unsigned int irq,
                                           struct irq_desc *desc)
 {
-       struct qe_ic *qe_ic = get_irq_desc_data(desc);
+       struct qe_ic *qe_ic = irq_desc_get_handler_data(desc);
        unsigned int cascade_irq = qe_ic_get_high_irq(qe_ic);
-       struct irq_chip *chip = get_irq_desc_chip(desc);
+       struct irq_chip *chip = irq_desc_get_chip(desc);
 
        if (cascade_irq != NO_IRQ)
                generic_handle_irq(cascade_irq);
@@ -127,9 +127,9 @@ static inline void qe_ic_cascade_high_mpic(unsigned int irq,
 static inline void qe_ic_cascade_muxed_mpic(unsigned int irq,
                                            struct irq_desc *desc)
 {
-       struct qe_ic *qe_ic = get_irq_desc_data(desc);
+       struct qe_ic *qe_ic = irq_desc_get_handler_data(desc);
        unsigned int cascade_irq;
-       struct irq_chip *chip = get_irq_desc_chip(desc);
+       struct irq_chip *chip = irq_desc_get_chip(desc);
 
        cascade_irq = qe_ic_get_high_irq(qe_ic);
        if (cascade_irq == NO_IRQ)
index 86ad812..3b1a9b7 100644 (file)
 #define SPRN_MAS2      0x272   /* MMU Assist Register 2 */
 #define SPRN_MAS3      0x273   /* MMU Assist Register 3 */
 #define SPRN_MAS4      0x274   /* MMU Assist Register 4 */
-#define SPRN_MAS5      0x275   /* MMU Assist Register 5 */
+#define SPRN_MAS5      0x153   /* MMU Assist Register 5 */
 #define SPRN_MAS6      0x276   /* MMU Assist Register 6 */
 #define SPRN_PID1      0x279   /* Process ID Register 1 */
 #define SPRN_PID2      0x27A   /* Process ID Register 2 */
index aa0f1eb..60f64b1 100644 (file)
@@ -348,3 +348,7 @@ COMPAT_SYS_SPU(sendmsg)
 COMPAT_SYS_SPU(recvmsg)
 COMPAT_SYS_SPU(recvmmsg)
 SYSCALL_SPU(accept4)
+SYSCALL_SPU(name_to_handle_at)
+COMPAT_SYS_SPU(open_by_handle_at)
+COMPAT_SYS_SPU(clock_adjtime)
+SYSCALL_SPU(syncfs)
index 6151937..3c21564 100644 (file)
 #define __NR_recvmsg           342
 #define __NR_recvmmsg          343
 #define __NR_accept4           344
+#define __NR_name_to_handle_at 345
+#define __NR_open_by_handle_at 346
+#define __NR_clock_adjtime     347
+#define __NR_syncfs            348
 
 #ifdef __KERNEL__
 
-#define __NR_syscalls          345
+#define __NR_syscalls          349
 
 #define __NR__exit __NR_exit
 #define NR_syscalls    __NR_syscalls
index cf02cad..d238c08 100644 (file)
@@ -179,3 +179,21 @@ static int __init dma_init(void)
        return 0;
 }
 fs_initcall(dma_init);
+
+int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+                     void *cpu_addr, dma_addr_t handle, size_t size)
+{
+       unsigned long pfn;
+
+#ifdef CONFIG_NOT_COHERENT_CACHE
+       vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+       pfn = __dma_get_coherent_pfn((unsigned long)cpu_addr);
+#else
+       pfn = page_to_pfn(virt_to_page(cpu_addr));
+#endif
+       return remap_pfn_range(vma, vma->vm_start,
+                              pfn + vma->vm_pgoff,
+                              vma->vm_end - vma->vm_start,
+                              vma->vm_page_prot);
+}
+EXPORT_SYMBOL_GPL(dma_mmap_coherent);
index 8a81799..c532cb2 100644 (file)
@@ -977,20 +977,6 @@ _GLOBAL(do_stab_bolted)
        rfid
        b       .       /* prevent speculative execution */
 
-/*
- * Space for CPU0's segment table.
- *
- * On iSeries, the hypervisor must fill in at least one entry before
- * we get control (with relocate on).  The address is given to the hv
- * as a page number (see xLparMap below), so this must be at a
- * fixed address (the linker can't compute (u64)&initial_stab >>
- * PAGE_SHIFT).
- */
-       . = STAB0_OFFSET        /* 0x6000 */
-       .globl initial_stab
-initial_stab:
-       .space  4096
-
 #ifdef CONFIG_PPC_PSERIES
 /*
  * Data area reserved for FWNMI option.
@@ -1027,3 +1013,17 @@ xLparMap:
 #ifdef CONFIG_PPC_PSERIES
         . = 0x8000
 #endif /* CONFIG_PPC_PSERIES */
+
+/*
+ * Space for CPU0's segment table.
+ *
+ * On iSeries, the hypervisor must fill in at least one entry before
+ * we get control (with relocate on).  The address is given to the hv
+ * as a page number (see xLparMap above), so this must be at a
+ * fixed address (the linker can't compute (u64)&initial_stab >>
+ * PAGE_SHIFT).
+ */
+       . = STAB0_OFFSET        /* 0x8000 */
+       .globl initial_stab
+initial_stab:
+       .space  4096
index 09d31db..aa92696 100644 (file)
@@ -356,7 +356,7 @@ void account_system_vtime(struct task_struct *tsk)
        }
        get_paca()->user_time_scaled += user_scaled;
 
-       if (in_irq() || idle_task(smp_processor_id()) != tsk) {
+       if (in_interrupt() || idle_task(smp_processor_id()) != tsk) {
                account_system_time(tsk, 0, delta, sys_scaled);
                if (stolen)
                        account_steal_time(stolen);
index 757c0be..b42f76c 100644 (file)
@@ -399,3 +399,23 @@ void __dma_sync_page(struct page *page, unsigned long offset,
 #endif
 }
 EXPORT_SYMBOL(__dma_sync_page);
+
+/*
+ * Return the PFN for a given cpu virtual address returned by
+ * __dma_alloc_coherent. This is used by dma_mmap_coherent()
+ */
+unsigned long __dma_get_coherent_pfn(unsigned long cpu_addr)
+{
+       /* This should always be populated, so we don't test every
+        * level. If that fails, we'll have a nice crash which
+        * will be as good as a BUG_ON()
+        */
+       pgd_t *pgd = pgd_offset_k(cpu_addr);
+       pud_t *pud = pud_offset(pgd, cpu_addr);
+       pmd_t *pmd = pmd_offset(pud, cpu_addr);
+       pte_t *ptep = pte_offset_kernel(pmd, cpu_addr);
+
+       if (pte_none(*ptep) || !pte_present(*ptep))
+               return 0;
+       return pte_pfn(*ptep);
+}
index a19bec0..44cfd1b 100644 (file)
@@ -244,7 +244,7 @@ static int iic_host_map(struct irq_host *h, unsigned int virq,
                break;
        case IIC_IRQ_TYPE_IOEXC:
                irq_set_chip_and_handler(virq, &iic_ioexc_chip,
-                                        handle_iic_irq);
+                                        handle_edge_eoi_irq);
                break;
        default:
                irq_set_chip_and_handler(virq, &iic_chip, handle_edge_eoi_irq);
index 419707b..00cc3a0 100644 (file)
@@ -480,8 +480,32 @@ static void oops_to_nvram(struct kmsg_dumper *dumper,
                const char *new_msgs, unsigned long new_len)
 {
        static unsigned int oops_count = 0;
+       static bool panicking = false;
        size_t text_len;
 
+       switch (reason) {
+       case KMSG_DUMP_RESTART:
+       case KMSG_DUMP_HALT:
+       case KMSG_DUMP_POWEROFF:
+               /* These are almost always orderly shutdowns. */
+               return;
+       case KMSG_DUMP_OOPS:
+       case KMSG_DUMP_KEXEC:
+               break;
+       case KMSG_DUMP_PANIC:
+               panicking = true;
+               break;
+       case KMSG_DUMP_EMERG:
+               if (panicking)
+                       /* Panic report already captured. */
+                       return;
+               break;
+       default:
+               pr_err("%s: ignoring unrecognized KMSG_DUMP_* reason %d\n",
+                                               __FUNCTION__, (int) reason);
+               return;
+       }
+
        if (clobbering_unread_rtas_event())
                return;
 
index 0317cce..d6479f9 100644 (file)
@@ -64,8 +64,8 @@ int smp_query_cpu_stopped(unsigned int pcpu)
        int qcss_tok = rtas_token("query-cpu-stopped-state");
 
        if (qcss_tok == RTAS_UNKNOWN_SERVICE) {
-               printk(KERN_INFO "Firmware doesn't support "
-                               "query-cpu-stopped-state\n");
+               printk_once(KERN_INFO
+                       "Firmware doesn't support query-cpu-stopped-state\n");
                return QCSS_HARDWARE_ERROR;
        }
 
index 6c1e638..ec8fe22 100644 (file)
@@ -204,33 +204,33 @@ static int get_irq_server(unsigned int virq, const struct cpumask *cpumask,
 
 static void xics_unmask_irq(struct irq_data *d)
 {
-       unsigned int irq;
+       unsigned int hwirq;
        int call_status;
        int server;
 
        pr_devel("xics: unmask virq %d\n", d->irq);
 
-       irq = (unsigned int)irq_map[d->irq].hwirq;
-       pr_devel(" -> map to hwirq 0x%x\n", irq);
-       if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS)
+       hwirq = (unsigned int)irq_map[d->irq].hwirq;
+       pr_devel(" -> map to hwirq 0x%x\n", hwirq);
+       if (hwirq == XICS_IPI || hwirq == XICS_IRQ_SPURIOUS)
                return;
 
        server = get_irq_server(d->irq, d->affinity, 0);
 
-       call_status = rtas_call(ibm_set_xive, 3, 1, NULL, irq, server,
+       call_status = rtas_call(ibm_set_xive, 3, 1, NULL, hwirq, server,
                                DEFAULT_PRIORITY);
        if (call_status != 0) {
                printk(KERN_ERR
                        "%s: ibm_set_xive irq %u server %x returned %d\n",
-                       __func__, irq, server, call_status);
+                       __func__, hwirq, server, call_status);
                return;
        }
 
        /* Now unmask the interrupt (often a no-op) */
-       call_status = rtas_call(ibm_int_on, 1, 1, NULL, irq);
+       call_status = rtas_call(ibm_int_on, 1, 1, NULL, hwirq);
        if (call_status != 0) {
                printk(KERN_ERR "%s: ibm_int_on irq=%u returned %d\n",
-                       __func__, irq, call_status);
+                       __func__, hwirq, call_status);
                return;
        }
 }
@@ -250,46 +250,46 @@ static unsigned int xics_startup(struct irq_data *d)
        return 0;
 }
 
-static void xics_mask_real_irq(struct irq_data *d)
+static void xics_mask_real_irq(unsigned int hwirq)
 {
        int call_status;
 
-       if (d->irq == XICS_IPI)
+       if (hwirq == XICS_IPI)
                return;
 
-       call_status = rtas_call(ibm_int_off, 1, 1, NULL, d->irq);
+       call_status = rtas_call(ibm_int_off, 1, 1, NULL, hwirq);
        if (call_status != 0) {
                printk(KERN_ERR "%s: ibm_int_off irq=%u returned %d\n",
-                       __func__, d->irq, call_status);
+                       __func__, hwirq, call_status);
                return;
        }
 
        /* Have to set XIVE to 0xff to be able to remove a slot */
-       call_status = rtas_call(ibm_set_xive, 3, 1, NULL, d->irq,
+       call_status = rtas_call(ibm_set_xive, 3, 1, NULL, hwirq,
                                default_server, 0xff);
        if (call_status != 0) {
                printk(KERN_ERR "%s: ibm_set_xive(0xff) irq=%u returned %d\n",
-                       __func__, d->irq, call_status);
+                       __func__, hwirq, call_status);
                return;
        }
 }
 
 static void xics_mask_irq(struct irq_data *d)
 {
-       unsigned int irq;
+       unsigned int hwirq;
 
        pr_devel("xics: mask virq %d\n", d->irq);
 
-       irq = (unsigned int)irq_map[d->irq].hwirq;
-       if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS)
+       hwirq = (unsigned int)irq_map[d->irq].hwirq;
+       if (hwirq == XICS_IPI || hwirq == XICS_IRQ_SPURIOUS)
                return;
-       xics_mask_real_irq(d);
+       xics_mask_real_irq(hwirq);
 }
 
 static void xics_mask_unknown_vec(unsigned int vec)
 {
        printk(KERN_ERR "Interrupt %u (real) is invalid, disabling it.\n", vec);
-       xics_mask_real_irq(irq_get_irq_data(vec));
+       xics_mask_real_irq(vec);
 }
 
 static inline unsigned int xics_xirr_vector(unsigned int xirr)
@@ -373,37 +373,37 @@ static unsigned char pop_cppr(void)
 
 static void xics_eoi_direct(struct irq_data *d)
 {
-       unsigned int irq = (unsigned int)irq_map[d->irq].hwirq;
+       unsigned int hwirq = (unsigned int)irq_map[d->irq].hwirq;
 
        iosync();
-       direct_xirr_info_set((pop_cppr() << 24) | irq);
+       direct_xirr_info_set((pop_cppr() << 24) | hwirq);
 }
 
 static void xics_eoi_lpar(struct irq_data *d)
 {
-       unsigned int irq = (unsigned int)irq_map[d->irq].hwirq;
+       unsigned int hwirq = (unsigned int)irq_map[d->irq].hwirq;
 
        iosync();
-       lpar_xirr_info_set((pop_cppr() << 24) | irq);
+       lpar_xirr_info_set((pop_cppr() << 24) | hwirq);
 }
 
 static int
 xics_set_affinity(struct irq_data *d, const struct cpumask *cpumask, bool force)
 {
-       unsigned int irq;
+       unsigned int hwirq;
        int status;
        int xics_status[2];
        int irq_server;
 
-       irq = (unsigned int)irq_map[d->irq].hwirq;
-       if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS)
+       hwirq = (unsigned int)irq_map[d->irq].hwirq;
+       if (hwirq == XICS_IPI || hwirq == XICS_IRQ_SPURIOUS)
                return -1;
 
-       status = rtas_call(ibm_get_xive, 1, 3, xics_status, irq);
+       status = rtas_call(ibm_get_xive, 1, 3, xics_status, hwirq);
 
        if (status) {
                printk(KERN_ERR "%s: ibm,get-xive irq=%u returns %d\n",
-                       __func__, irq, status);
+                       __func__, hwirq, status);
                return -1;
        }
 
@@ -418,11 +418,11 @@ xics_set_affinity(struct irq_data *d, const struct cpumask *cpumask, bool force)
        }
 
        status = rtas_call(ibm_set_xive, 3, 1, NULL,
-                               irq, irq_server, xics_status[1]);
+                               hwirq, irq_server, xics_status[1]);
 
        if (status) {
                printk(KERN_ERR "%s: ibm,set-xive irq=%u returns %d\n",
-                       __func__, irq, status);
+                       __func__, hwirq, status);
                return -1;
        }
 
@@ -874,7 +874,7 @@ void xics_kexec_teardown_cpu(int secondary)
 void xics_migrate_irqs_away(void)
 {
        int cpu = smp_processor_id(), hw_cpu = hard_smp_processor_id();
-       unsigned int irq, virq;
+       int virq;
 
        /* If we used to be the default server, move to the new "boot_cpuid" */
        if (hw_cpu == default_server)
@@ -892,6 +892,7 @@ void xics_migrate_irqs_away(void)
        for_each_irq(virq) {
                struct irq_desc *desc;
                struct irq_chip *chip;
+               unsigned int hwirq;
                int xics_status[2];
                int status;
                unsigned long flags;
@@ -901,9 +902,9 @@ void xics_migrate_irqs_away(void)
                        continue;
                if (irq_map[virq].host != xics_host)
                        continue;
-               irq = (unsigned int)irq_map[virq].hwirq;
+               hwirq = (unsigned int)irq_map[virq].hwirq;
                /* We need to get IPIs still. */
-               if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS)
+               if (hwirq == XICS_IPI || hwirq == XICS_IRQ_SPURIOUS)
                        continue;
 
                desc = irq_to_desc(virq);
@@ -918,10 +919,10 @@ void xics_migrate_irqs_away(void)
 
                raw_spin_lock_irqsave(&desc->lock, flags);
 
-               status = rtas_call(ibm_get_xive, 1, 3, xics_status, irq);
+               status = rtas_call(ibm_get_xive, 1, 3, xics_status, hwirq);
                if (status) {
                        printk(KERN_ERR "%s: ibm,get-xive irq=%u returns %d\n",
-                                       __func__, irq, status);
+                                       __func__, hwirq, status);
                        goto unlock;
                }
 
index f550e23..a88800f 100644 (file)
@@ -80,7 +80,7 @@ static int mpc8xx_set_irq_type(struct irq_data *d, unsigned int flow_type)
                if ((hw & 1) == 0) {
                        siel |= (0x80000000 >> hw);
                        out_be32(&siu_reg->sc_siel, siel);
-                       __irq_set_handler_locked(irq, handle_edge_irq);
+                       __irq_set_handler_locked(d->irq, handle_edge_irq);
                }
        }
        return 0;
index 4278bbc..e73bc78 100644 (file)
@@ -3,7 +3,6 @@ menu "Machine selection"
 config SCORE
        def_bool y
        select HAVE_GENERIC_HARDIRQS
-       select GENERIC_HARDIRQS_NO_DEPRECATED
        select GENERIC_IRQ_SHOW
 
 choice
index 9af3c8d..bc439de 100644 (file)
@@ -23,7 +23,6 @@ config SUPERH
        select HAVE_SPARSE_IRQ
        select RTC_LIB
        select GENERIC_ATOMIC64
-       select GENERIC_HARDIRQS_NO_DEPRECATED
        select GENERIC_IRQ_SHOW
        help
          The SuperH is a RISC processor targeted for use in embedded systems
index 14b2346..e560d10 100644 (file)
@@ -51,7 +51,6 @@ config SPARC64
        select HAVE_PERF_EVENTS
        select PERF_USE_VMALLOC
        select HAVE_GENERIC_HARDIRQS
-       select GENERIC_HARDIRQS_NO_DEPRECATED
        select GENERIC_IRQ_SHOW
        select IRQ_PREFLOW_FASTEOI
 
index 5e34a9f..6e2cdd5 100644 (file)
@@ -11,7 +11,6 @@ config TILE
        select HAVE_GENERIC_HARDIRQS
        select GENERIC_IRQ_PROBE
        select GENERIC_PENDING_IRQ if SMP
-       select GENERIC_HARDIRQS_NO_DEPRECATED
        select GENERIC_IRQ_SHOW
 
 # FIXME: investigate whether we need/want these options.
index 109ddc0..a923483 100644 (file)
@@ -7,7 +7,6 @@ config UML
        bool
        default y
        select HAVE_GENERIC_HARDIRQS
-       select GENERIC_HARDIRQS_NO_DEPRECATED
        select GENERIC_IRQ_SHOW
 
 config MMU
index 04e0249..d3a3032 100644 (file)
@@ -10,7 +10,6 @@ config UNICORE32
        select HAVE_KERNEL_LZMA
        select GENERIC_FIND_FIRST_BIT
        select GENERIC_IRQ_PROBE
-       select GENERIC_HARDIRQS_NO_DEPRECATED
        select GENERIC_IRQ_SHOW
        select ARCH_WANT_FRAME_POINTERS
        help
index 1293c70..cd1ffed 100644 (file)
@@ -316,7 +316,7 @@ static void apbt_setup_irq(struct apbt_dev *adev)
        irq_modify_status(adev->irq, 0, IRQ_MOVE_PCNTXT);
        irq_set_affinity(adev->irq, cpumask_of(adev->cpu));
        /* APB timer irqs are set up as mp_irqs, timer is edge type */
-       __set_irq_handler(adev->irq, handle_edge_irq, 0, "edge");
+       __irq_set_handler(adev->irq, handle_edge_irq, 0, "edge");
 
        if (system_state == SYSTEM_BOOTING) {
                if (request_irq(adev->irq, apbt_interrupt_handler,
index 1d730b5..7c275f5 100644 (file)
@@ -9,7 +9,6 @@ config XTENSA
        select HAVE_IDE
        select HAVE_GENERIC_HARDIRQS
        select GENERIC_IRQ_SHOW
-       select GENERIC_HARDIRQS_NO_DEPRECATED
        help
          Xtensa processors are 32-bit RISC machines designed by Tensilica
          primarily for embedded systems.  These processors are both
index a2a73d9..b86d7e2 100644 (file)
 
 #define DRV_NAME "pata_palmld"
 
+static struct gpio palmld_hdd_gpios[] = {
+       { GPIO_NR_PALMLD_IDE_PWEN,      GPIOF_INIT_HIGH,        "HDD Power" },
+       { GPIO_NR_PALMLD_IDE_RESET,     GPIOF_INIT_LOW,         "HDD Reset" },
+};
+
 static struct scsi_host_template palmld_sht = {
        ATA_PIO_SHT(DRV_NAME),
 };
@@ -52,28 +57,23 @@ static __devinit int palmld_pata_probe(struct platform_device *pdev)
 
        /* allocate host */
        host = ata_host_alloc(&pdev->dev, 1);
-       if (!host)
-               return -ENOMEM;
+       if (!host) {
+               ret = -ENOMEM;
+               goto err1;
+       }
 
        /* remap drive's physical memory address */
        mem = devm_ioremap(&pdev->dev, PALMLD_IDE_PHYS, 0x1000);
-       if (!mem)
-               return -ENOMEM;
+       if (!mem) {
+               ret = -ENOMEM;
+               goto err1;
+       }
 
        /* request and activate power GPIO, IRQ GPIO */
-       ret = gpio_request(GPIO_NR_PALMLD_IDE_PWEN, "HDD PWR");
+       ret = gpio_request_array(palmld_hdd_gpios,
+                               ARRAY_SIZE(palmld_hdd_gpios));
        if (ret)
                goto err1;
-       ret = gpio_direction_output(GPIO_NR_PALMLD_IDE_PWEN, 1);
-       if (ret)
-               goto err2;
-
-       ret = gpio_request(GPIO_NR_PALMLD_IDE_RESET, "HDD RST");
-       if (ret)
-               goto err2;
-       ret = gpio_direction_output(GPIO_NR_PALMLD_IDE_RESET, 0);
-       if (ret)
-               goto err3;
 
        /* reset the drive */
        gpio_set_value(GPIO_NR_PALMLD_IDE_RESET, 0);
@@ -96,13 +96,15 @@ static __devinit int palmld_pata_probe(struct platform_device *pdev)
        ata_sff_std_ports(&ap->ioaddr);
 
        /* activate host */
-       return ata_host_activate(host, 0, NULL, IRQF_TRIGGER_RISING,
+       ret = ata_host_activate(host, 0, NULL, IRQF_TRIGGER_RISING,
                                        &palmld_sht);
+       if (ret)
+               goto err2;
+
+       return ret;
 
-err3:
-       gpio_free(GPIO_NR_PALMLD_IDE_RESET);
 err2:
-       gpio_free(GPIO_NR_PALMLD_IDE_PWEN);
+       gpio_free_array(palmld_hdd_gpios, ARRAY_SIZE(palmld_hdd_gpios));
 err1:
        return ret;
 }
@@ -116,8 +118,7 @@ static __devexit int palmld_pata_remove(struct platform_device *dev)
        /* power down the HDD */
        gpio_set_value(GPIO_NR_PALMLD_IDE_PWEN, 0);
 
-       gpio_free(GPIO_NR_PALMLD_IDE_RESET);
-       gpio_free(GPIO_NR_PALMLD_IDE_PWEN);
+       gpio_free_array(palmld_hdd_gpios, ARRAY_SIZE(palmld_hdd_gpios));
 
        return 0;
 }
index 25ef1a4..cd0ff66 100644 (file)
@@ -165,7 +165,6 @@ static uint32_t fpga_tx(struct solos_card *);
 static irqreturn_t solos_irq(int irq, void *dev_id);
 static struct atm_vcc* find_vcc(struct atm_dev *dev, short vpi, int vci);
 static int list_vccs(int vci);
-static void release_vccs(struct atm_dev *dev);
 static int atm_init(struct solos_card *, struct device *);
 static void atm_remove(struct solos_card *);
 static int send_command(struct solos_card *card, int dev, const char *buf, size_t size);
@@ -384,7 +383,6 @@ static int process_status(struct solos_card *card, int port, struct sk_buff *skb
        /* Anything but 'Showtime' is down */
        if (strcmp(state_str, "Showtime")) {
                atm_dev_signal_change(card->atmdev[port], ATM_PHY_SIG_LOST);
-               release_vccs(card->atmdev[port]);
                dev_info(&card->dev->dev, "Port %d: %s\n", port, state_str);
                return 0;
        }
@@ -697,7 +695,7 @@ void solos_bh(unsigned long card_arg)
                                              size);
                        }
                        if (atmdebug) {
-                               dev_info(&card->dev->dev, "Received: device %d\n", port);
+                               dev_info(&card->dev->dev, "Received: port %d\n", port);
                                dev_info(&card->dev->dev, "size: %d VPI: %d VCI: %d\n",
                                         size, le16_to_cpu(header->vpi),
                                         le16_to_cpu(header->vci));
@@ -710,8 +708,8 @@ void solos_bh(unsigned long card_arg)
                                               le16_to_cpu(header->vci));
                                if (!vcc) {
                                        if (net_ratelimit())
-                                               dev_warn(&card->dev->dev, "Received packet for unknown VCI.VPI %d.%d on port %d\n",
-                                                        le16_to_cpu(header->vci), le16_to_cpu(header->vpi),
+                                               dev_warn(&card->dev->dev, "Received packet for unknown VPI.VCI %d.%d on port %d\n",
+                                                        le16_to_cpu(header->vpi), le16_to_cpu(header->vci),
                                                         port);
                                        continue;
                                }
@@ -830,28 +828,6 @@ static int list_vccs(int vci)
        return num_found;
 }
 
-static void release_vccs(struct atm_dev *dev)
-{
-        int i;
-
-        write_lock_irq(&vcc_sklist_lock);
-        for (i = 0; i < VCC_HTABLE_SIZE; i++) {
-                struct hlist_head *head = &vcc_hash[i];
-                struct hlist_node *node, *tmp;
-                struct sock *s;
-                struct atm_vcc *vcc;
-
-                sk_for_each_safe(s, node, tmp, head) {
-                        vcc = atm_sk(s);
-                        if (vcc->dev == dev) {
-                                vcc_release_async(vcc, -EPIPE);
-                                sk_del_node_init(s);
-                        }
-                }
-        }
-        write_unlock_irq(&vcc_sklist_lock);
-}
-
 
 static int popen(struct atm_vcc *vcc)
 {
@@ -1018,8 +994,15 @@ static uint32_t fpga_tx(struct solos_card *card)
 
                        /* Clean up and free oldskb now it's gone */
                        if (atmdebug) {
+                               struct pkt_hdr *header = (void *)oldskb->data;
+                               int size = le16_to_cpu(header->size);
+
+                               skb_pull(oldskb, sizeof(*header));
                                dev_info(&card->dev->dev, "Transmitted: port %d\n",
                                         port);
+                               dev_info(&card->dev->dev, "size: %d VPI: %d VCI: %d\n",
+                                        size, le16_to_cpu(header->vpi),
+                                        le16_to_cpu(header->vci));
                                print_buffer(oldskb);
                        }
 
@@ -1262,7 +1245,7 @@ static int atm_init(struct solos_card *card, struct device *parent)
                card->atmdev[i]->ci_range.vci_bits = 16;
                card->atmdev[i]->dev_data = card;
                card->atmdev[i]->phy_data = (void *)(unsigned long)i;
-               atm_dev_signal_change(card->atmdev[i], ATM_PHY_SIG_UNKNOWN);
+               atm_dev_signal_change(card->atmdev[i], ATM_PHY_SIG_FOUND);
 
                skb = alloc_skb(sizeof(*header), GFP_ATOMIC);
                if (!skb) {
index 55653ab..c42c9d5 100644 (file)
 #include <linux/connector.h>
 #include <linux/delay.h>
 
-void cn_queue_wrapper(struct work_struct *work)
-{
-       struct cn_callback_entry *cbq =
-               container_of(work, struct cn_callback_entry, work);
-       struct cn_callback_data *d = &cbq->data;
-       struct cn_msg *msg = NLMSG_DATA(nlmsg_hdr(d->skb));
-       struct netlink_skb_parms *nsp = &NETLINK_CB(d->skb);
-
-       d->callback(msg, nsp);
-
-       kfree_skb(d->skb);
-       d->skb = NULL;
-
-       kfree(d->free);
-}
-
 static struct cn_callback_entry *
-cn_queue_alloc_callback_entry(const char *name, struct cb_id *id,
+cn_queue_alloc_callback_entry(struct cn_queue_dev *dev, const char *name,
+                             struct cb_id *id,
                              void (*callback)(struct cn_msg *, struct netlink_skb_parms *))
 {
        struct cn_callback_entry *cbq;
@@ -59,17 +44,23 @@ cn_queue_alloc_callback_entry(const char *name, struct cb_id *id,
                return NULL;
        }
 
+       atomic_set(&cbq->refcnt, 1);
+
+       atomic_inc(&dev->refcnt);
+       cbq->pdev = dev;
+
        snprintf(cbq->id.name, sizeof(cbq->id.name), "%s", name);
        memcpy(&cbq->id.id, id, sizeof(struct cb_id));
-       cbq->data.callback = callback;
-
-       INIT_WORK(&cbq->work, &cn_queue_wrapper);
+       cbq->callback = callback;
        return cbq;
 }
 
-static void cn_queue_free_callback(struct cn_callback_entry *cbq)
+void cn_queue_release_callback(struct cn_callback_entry *cbq)
 {
-       flush_workqueue(cbq->pdev->cn_queue);
+       if (!atomic_dec_and_test(&cbq->refcnt))
+               return;
+
+       atomic_dec(&cbq->pdev->refcnt);
        kfree(cbq);
 }
 
@@ -85,13 +76,10 @@ int cn_queue_add_callback(struct cn_queue_dev *dev, const char *name,
        struct cn_callback_entry *cbq, *__cbq;
        int found = 0;
 
-       cbq = cn_queue_alloc_callback_entry(name, id, callback);
+       cbq = cn_queue_alloc_callback_entry(dev, name, id, callback);
        if (!cbq)
                return -ENOMEM;
 
-       atomic_inc(&dev->refcnt);
-       cbq->pdev = dev;
-
        spin_lock_bh(&dev->queue_lock);
        list_for_each_entry(__cbq, &dev->queue_list, callback_entry) {
                if (cn_cb_equal(&__cbq->id.id, id)) {
@@ -104,8 +92,7 @@ int cn_queue_add_callback(struct cn_queue_dev *dev, const char *name,
        spin_unlock_bh(&dev->queue_lock);
 
        if (found) {
-               cn_queue_free_callback(cbq);
-               atomic_dec(&dev->refcnt);
+               cn_queue_release_callback(cbq);
                return -EINVAL;
        }
 
@@ -130,10 +117,8 @@ void cn_queue_del_callback(struct cn_queue_dev *dev, struct cb_id *id)
        }
        spin_unlock_bh(&dev->queue_lock);
 
-       if (found) {
-               cn_queue_free_callback(cbq);
-               atomic_dec(&dev->refcnt);
-       }
+       if (found)
+               cn_queue_release_callback(cbq);
 }
 
 struct cn_queue_dev *cn_queue_alloc_dev(const char *name, struct sock *nls)
@@ -151,12 +136,6 @@ struct cn_queue_dev *cn_queue_alloc_dev(const char *name, struct sock *nls)
 
        dev->nls = nls;
 
-       dev->cn_queue = alloc_ordered_workqueue(dev->name, 0);
-       if (!dev->cn_queue) {
-               kfree(dev);
-               return NULL;
-       }
-
        return dev;
 }
 
@@ -164,9 +143,6 @@ void cn_queue_free_dev(struct cn_queue_dev *dev)
 {
        struct cn_callback_entry *cbq, *n;
 
-       flush_workqueue(dev->cn_queue);
-       destroy_workqueue(dev->cn_queue);
-
        spin_lock_bh(&dev->queue_lock);
        list_for_each_entry_safe(cbq, n, &dev->queue_list, callback_entry)
                list_del(&cbq->callback_entry);
index f7554de..d770058 100644 (file)
@@ -122,51 +122,28 @@ EXPORT_SYMBOL_GPL(cn_netlink_send);
  */
 static int cn_call_callback(struct sk_buff *skb)
 {
-       struct cn_callback_entry *__cbq, *__new_cbq;
+       struct cn_callback_entry *i, *cbq = NULL;
        struct cn_dev *dev = &cdev;
        struct cn_msg *msg = NLMSG_DATA(nlmsg_hdr(skb));
+       struct netlink_skb_parms *nsp = &NETLINK_CB(skb);
        int err = -ENODEV;
 
        spin_lock_bh(&dev->cbdev->queue_lock);
-       list_for_each_entry(__cbq, &dev->cbdev->queue_list, callback_entry) {
-               if (cn_cb_equal(&__cbq->id.id, &msg->id)) {
-                       if (likely(!work_pending(&__cbq->work) &&
-                                       __cbq->data.skb == NULL)) {
-                               __cbq->data.skb = skb;
-
-                               if (queue_work(dev->cbdev->cn_queue,
-                                              &__cbq->work))
-                                       err = 0;
-                               else
-                                       err = -EINVAL;
-                       } else {
-                               struct cn_callback_data *d;
-
-                               err = -ENOMEM;
-                               __new_cbq = kzalloc(sizeof(struct cn_callback_entry), GFP_ATOMIC);
-                               if (__new_cbq) {
-                                       d = &__new_cbq->data;
-                                       d->skb = skb;
-                                       d->callback = __cbq->data.callback;
-                                       d->free = __new_cbq;
-
-                                       INIT_WORK(&__new_cbq->work,
-                                                       &cn_queue_wrapper);
-
-                                       if (queue_work(dev->cbdev->cn_queue,
-                                                      &__new_cbq->work))
-                                               err = 0;
-                                       else {
-                                               kfree(__new_cbq);
-                                               err = -EINVAL;
-                                       }
-                               }
-                       }
+       list_for_each_entry(i, &dev->cbdev->queue_list, callback_entry) {
+               if (cn_cb_equal(&i->id.id, &msg->id)) {
+                       atomic_inc(&i->refcnt);
+                       cbq = i;
                        break;
                }
        }
        spin_unlock_bh(&dev->cbdev->queue_lock);
 
+       if (cbq != NULL) {
+               cbq->callback(msg, nsp);
+               kfree_skb(skb);
+               cn_queue_release_callback(cbq);
+       }
+
        return err;
 }
 
index e637e9f..937ef1a 100644 (file)
@@ -1996,13 +1996,15 @@ static int atl2_set_eeprom(struct net_device *netdev,
        if (!eeprom_buff)
                return -ENOMEM;
 
-       ptr = (u32 *)eeprom_buff;
+       ptr = eeprom_buff;
 
        if (eeprom->offset & 3) {
                /* need read/modify/write of first changed EEPROM word */
                /* only the second byte of the word is being modified */
-               if (!atl2_read_eeprom(hw, first_dword*4, &(eeprom_buff[0])))
-                       return -EIO;
+               if (!atl2_read_eeprom(hw, first_dword*4, &(eeprom_buff[0]))) {
+                       ret_val = -EIO;
+                       goto out;
+               }
                ptr++;
        }
        if (((eeprom->offset + eeprom->len) & 3)) {
@@ -2011,18 +2013,22 @@ static int atl2_set_eeprom(struct net_device *netdev,
                 * only the first byte of the word is being modified
                 */
                if (!atl2_read_eeprom(hw, last_dword * 4,
-                       &(eeprom_buff[last_dword - first_dword])))
-                       return -EIO;
+                                       &(eeprom_buff[last_dword - first_dword]))) {
+                       ret_val = -EIO;
+                       goto out;
+               }
        }
 
        /* Device's eeprom is always little-endian, word addressable */
        memcpy(ptr, bytes, eeprom->len);
 
        for (i = 0; i < last_dword - first_dword + 1; i++) {
-               if (!atl2_write_eeprom(hw, ((first_dword+i)*4), eeprom_buff[i]))
-                       return -EIO;
+               if (!atl2_write_eeprom(hw, ((first_dword+i)*4), eeprom_buff[i])) {
+                       ret_val = -EIO;
+                       goto out;
+               }
        }
-
+ out:
        kfree(eeprom_buff);
        return ret_val;
 }
index 118c28a..4b3e358 100644 (file)
@@ -74,7 +74,7 @@ struct tlb_client_info {
                                 * packets to a Client that the Hash function
                                 * gave this entry index.
                                 */
-       u32 tx_bytes;           /* Each Client acumulates the BytesTx that
+       u32 tx_bytes;           /* Each Client accumulates the BytesTx that
                                 * were tranmitted to it, and after each
                                 * CallBack the LoadHistory is devided
                                 * by the balance interval
index 67c0ad4..186cd28 100644 (file)
@@ -75,15 +75,9 @@ static int dongle_id = 0;    /* default: probe */
 /* We can't guess the type of connected dongle, user *must* supply it. */
 module_param(dongle_id, int, 0);
 
-/* FIXME : we should not need this, because instances should be automatically
- * managed by the PCI layer. Especially that we seem to only be using the
- * first entry. Jean II */
-/* Max 4 instances for now */
-static struct via_ircc_cb *dev_self[] = { NULL, NULL, NULL, NULL };
-
 /* Some prototypes */
-static int via_ircc_open(int i, chipio_t * info, unsigned int id);
-static int via_ircc_close(struct via_ircc_cb *self);
+static int via_ircc_open(struct pci_dev *pdev, chipio_t * info,
+                        unsigned int id);
 static int via_ircc_dma_receive(struct via_ircc_cb *self);
 static int via_ircc_dma_receive_complete(struct via_ircc_cb *self,
                                         int iobase);
@@ -215,7 +209,7 @@ static int __devinit via_init_one (struct pci_dev *pcidev, const struct pci_devi
                        pci_write_config_byte(pcidev,0x42,(bTmp | 0xf0));
                        pci_write_config_byte(pcidev,0x5a,0xc0);
                        WriteLPCReg(0x28, 0x70 );
-                       if (via_ircc_open(0, &info,0x3076) == 0)
+                       if (via_ircc_open(pcidev, &info, 0x3076) == 0)
                                rc=0;
                } else
                        rc = -ENODEV; //IR not turn on   
@@ -254,7 +248,7 @@ static int __devinit via_init_one (struct pci_dev *pcidev, const struct pci_devi
                        info.irq=FirIRQ;
                        info.dma=FirDRQ1;
                        info.dma2=FirDRQ0;
-                       if (via_ircc_open(0, &info,0x3096) == 0)
+                       if (via_ircc_open(pcidev, &info, 0x3096) == 0)
                                rc=0;
                } else
                        rc = -ENODEV; //IR not turn on !!!!!
@@ -264,48 +258,10 @@ static int __devinit via_init_one (struct pci_dev *pcidev, const struct pci_devi
        return rc;
 }
 
-/*
- * Function via_ircc_clean ()
- *
- *    Close all configured chips
- *
- */
-static void via_ircc_clean(void)
-{
-       int i;
-
-       IRDA_DEBUG(3, "%s()\n", __func__);
-
-       for (i=0; i < ARRAY_SIZE(dev_self); i++) {
-               if (dev_self[i])
-                       via_ircc_close(dev_self[i]);
-       }
-}
-
-static void __devexit via_remove_one (struct pci_dev *pdev)
-{
-       IRDA_DEBUG(3, "%s()\n", __func__);
-
-       /* FIXME : This is ugly. We should use pci_get_drvdata(pdev);
-        * to get our driver instance and call directly via_ircc_close().
-        * See vlsi_ir for details...
-        * Jean II */
-       via_ircc_clean();
-
-       /* FIXME : This should be in via_ircc_close(), because here we may
-        * theoritically disable still configured devices :-( - Jean II */
-       pci_disable_device(pdev);
-}
-
 static void __exit via_ircc_cleanup(void)
 {
        IRDA_DEBUG(3, "%s()\n", __func__);
 
-       /* FIXME : This should be redundant, as pci_unregister_driver()
-        * should call via_remove_one() on each device.
-        * Jean II */
-       via_ircc_clean();
-
        /* Cleanup all instances of the driver */
        pci_unregister_driver (&via_driver); 
 }
@@ -324,12 +280,13 @@ static const struct net_device_ops via_ircc_fir_ops = {
 };
 
 /*
- * Function via_ircc_open (iobase, irq)
+ * Function via_ircc_open(pdev, iobase, irq)
  *
  *    Open driver instance
  *
  */
-static __devinit int via_ircc_open(int i, chipio_t * info, unsigned int id)
+static __devinit int via_ircc_open(struct pci_dev *pdev, chipio_t * info,
+                                  unsigned int id)
 {
        struct net_device *dev;
        struct via_ircc_cb *self;
@@ -337,9 +294,6 @@ static __devinit int via_ircc_open(int i, chipio_t * info, unsigned int id)
 
        IRDA_DEBUG(3, "%s()\n", __func__);
 
-       if (i >= ARRAY_SIZE(dev_self))
-               return -ENOMEM;
-
        /* Allocate new instance of the driver */
        dev = alloc_irdadev(sizeof(struct via_ircc_cb));
        if (dev == NULL) 
@@ -349,13 +303,8 @@ static __devinit int via_ircc_open(int i, chipio_t * info, unsigned int id)
        self->netdev = dev;
        spin_lock_init(&self->lock);
 
-       /* FIXME : We should store our driver instance in the PCI layer,
-        * using pci_set_drvdata(), not in this array.
-        * See vlsi_ir for details... - Jean II */
-       /* FIXME : 'i' is always 0 (see via_init_one()) :-( - Jean II */
-       /* Need to store self somewhere */
-       dev_self[i] = self;
-       self->index = i;
+       pci_set_drvdata(pdev, self);
+
        /* Initialize Resource */
        self->io.cfg_base = info->cfg_base;
        self->io.fir_base = info->fir_base;
@@ -414,7 +363,7 @@ static __devinit int via_ircc_open(int i, chipio_t * info, unsigned int id)
 
        /* Allocate memory if needed */
        self->rx_buff.head =
-               dma_alloc_coherent(NULL, self->rx_buff.truesize,
+               dma_alloc_coherent(&pdev->dev, self->rx_buff.truesize,
                                   &self->rx_buff_dma, GFP_KERNEL);
        if (self->rx_buff.head == NULL) {
                err = -ENOMEM;
@@ -423,7 +372,7 @@ static __devinit int via_ircc_open(int i, chipio_t * info, unsigned int id)
        memset(self->rx_buff.head, 0, self->rx_buff.truesize);
 
        self->tx_buff.head =
-               dma_alloc_coherent(NULL, self->tx_buff.truesize,
+               dma_alloc_coherent(&pdev->dev, self->tx_buff.truesize,
                                   &self->tx_buff_dma, GFP_KERNEL);
        if (self->tx_buff.head == NULL) {
                err = -ENOMEM;
@@ -455,33 +404,32 @@ static __devinit int via_ircc_open(int i, chipio_t * info, unsigned int id)
        via_hw_init(self);
        return 0;
  err_out4:
-       dma_free_coherent(NULL, self->tx_buff.truesize,
+       dma_free_coherent(&pdev->dev, self->tx_buff.truesize,
                          self->tx_buff.head, self->tx_buff_dma);
  err_out3:
-       dma_free_coherent(NULL, self->rx_buff.truesize,
+       dma_free_coherent(&pdev->dev, self->rx_buff.truesize,
                          self->rx_buff.head, self->rx_buff_dma);
  err_out2:
        release_region(self->io.fir_base, self->io.fir_ext);
  err_out1:
+       pci_set_drvdata(pdev, NULL);
        free_netdev(dev);
-       dev_self[i] = NULL;
        return err;
 }
 
 /*
- * Function via_ircc_close (self)
+ * Function via_remove_one(pdev)
  *
  *    Close driver instance
  *
  */
-static int via_ircc_close(struct via_ircc_cb *self)
+static void __devexit via_remove_one(struct pci_dev *pdev)
 {
+       struct via_ircc_cb *self = pci_get_drvdata(pdev);
        int iobase;
 
        IRDA_DEBUG(3, "%s()\n", __func__);
 
-       IRDA_ASSERT(self != NULL, return -1;);
-
        iobase = self->io.fir_base;
 
        ResetChip(iobase, 5);   //hardware reset.
@@ -493,16 +441,16 @@ static int via_ircc_close(struct via_ircc_cb *self)
                   __func__, self->io.fir_base);
        release_region(self->io.fir_base, self->io.fir_ext);
        if (self->tx_buff.head)
-               dma_free_coherent(NULL, self->tx_buff.truesize,
+               dma_free_coherent(&pdev->dev, self->tx_buff.truesize,
                                  self->tx_buff.head, self->tx_buff_dma);
        if (self->rx_buff.head)
-               dma_free_coherent(NULL, self->rx_buff.truesize,
+               dma_free_coherent(&pdev->dev, self->rx_buff.truesize,
                                  self->rx_buff.head, self->rx_buff_dma);
-       dev_self[self->index] = NULL;
+       pci_set_drvdata(pdev, NULL);
 
        free_netdev(self->netdev);
 
-       return 0;
+       pci_disable_device(pdev);
 }
 
 /*
index 506cfd0..1ad1f60 100644 (file)
@@ -603,7 +603,9 @@ int mlx4_init_eq_table(struct mlx4_dev *dev)
        }
 
        for (i = 0; i < dev->caps.num_comp_vectors; ++i) {
-               err = mlx4_create_eq(dev, dev->caps.num_cqs + MLX4_NUM_SPARE_EQE,
+               err = mlx4_create_eq(dev, dev->caps.num_cqs -
+                                         dev->caps.reserved_cqs +
+                                         MLX4_NUM_SPARE_EQE,
                                     (dev->flags & MLX4_FLAG_MSI_X) ? i : 0,
                                     &priv->eq_table.eq[i]);
                if (err) {
index e71372a..37150b2 100644 (file)
@@ -469,7 +469,6 @@ static int remove_promisc_qp(struct mlx4_dev *dev, u8 vep_num, u8 port,
 
        /*remove from list of promisc qps */
        list_del(&pqp->list);
-       kfree(pqp);
 
        /* set the default entry not to include the removed one */
        mailbox = mlx4_alloc_cmd_mailbox(dev);
@@ -528,6 +527,8 @@ out_mailbox:
 out_list:
        if (back_to_list)
                list_add_tail(&pqp->list, &s_steer->promisc_qps[steer]);
+       else
+               kfree(pqp);
 out_mutex:
        mutex_unlock(&priv->mcg_table.mutex);
        return err;
index 993c52c..e870c06 100644 (file)
@@ -442,11 +442,11 @@ static int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,
                             u32 flags, phy_interface_t interface)
 {
        struct device *d = &phydev->dev;
+       int err;
 
        /* Assume that if there is no driver, that it doesn't
         * exist, and we should use the genphy driver. */
        if (NULL == d->driver) {
-               int err;
                d->driver = &genphy_driver.driver;
 
                err = d->driver->probe(d);
@@ -474,7 +474,11 @@ static int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,
        /* Do initial configuration here, now that
         * we have certain key parameters
         * (dev_flags and interface) */
-       return phy_init_hw(phydev);
+       err = phy_init_hw(phydev);
+       if (err)
+               phy_detach(phydev);
+
+       return err;
 }
 
 /**
index 6f600cc..3ec22c3 100644 (file)
@@ -433,4 +433,19 @@ config USB_SIERRA_NET
          To compile this driver as a module, choose M here: the
          module will be called sierra_net.
 
+config USB_VL600
+       tristate "LG VL600 modem dongle"
+       depends on USB_NET_CDCETHER
+       select USB_ACM
+       help
+         Select this if you want to use an LG Electronics 4G/LTE usb modem
+         called VL600.  This driver only handles the ethernet
+         interface exposed by the modem firmware.  To establish a connection
+         you will first need a userspace program that sends the right
+         command to the modem through its CDC ACM port, and most
+         likely also a DHCP client.  See this thread about using the
+         4G modem from Verizon:
+
+         http://ubuntuforums.org/showpost.php?p=10589647&postcount=17
+
 endmenu
index cac1703..c7ec8a5 100644 (file)
@@ -27,4 +27,5 @@ obj-$(CONFIG_USB_IPHETH)      += ipheth.o
 obj-$(CONFIG_USB_SIERRA_NET)   += sierra_net.o
 obj-$(CONFIG_USB_NET_CX82310_ETH)      += cx82310_eth.o
 obj-$(CONFIG_USB_NET_CDC_NCM)  += cdc_ncm.o
+obj-$(CONFIG_USB_VL600)                += lg-vl600.o
 
index 9a60e41..51c259b 100644 (file)
@@ -378,7 +378,7 @@ static void dumpspeed(struct usbnet *dev, __le32 *speeds)
                   __le32_to_cpu(speeds[1]) / 1000);
 }
 
-static void cdc_status(struct usbnet *dev, struct urb *urb)
+void usbnet_cdc_status(struct usbnet *dev, struct urb *urb)
 {
        struct usb_cdc_notification     *event;
 
@@ -418,8 +418,9 @@ static void cdc_status(struct usbnet *dev, struct urb *urb)
                break;
        }
 }
+EXPORT_SYMBOL_GPL(usbnet_cdc_status);
 
-static int cdc_bind(struct usbnet *dev, struct usb_interface *intf)
+int usbnet_cdc_bind(struct usbnet *dev, struct usb_interface *intf)
 {
        int                             status;
        struct cdc_state                *info = (void *) &dev->data;
@@ -441,6 +442,7 @@ static int cdc_bind(struct usbnet *dev, struct usb_interface *intf)
         */
        return 0;
 }
+EXPORT_SYMBOL_GPL(usbnet_cdc_bind);
 
 static int cdc_manage_power(struct usbnet *dev, int on)
 {
@@ -452,18 +454,18 @@ static const struct driver_info   cdc_info = {
        .description =  "CDC Ethernet Device",
        .flags =        FLAG_ETHER,
        // .check_connect = cdc_check_connect,
-       .bind =         cdc_bind,
+       .bind =         usbnet_cdc_bind,
        .unbind =       usbnet_cdc_unbind,
-       .status =       cdc_status,
+       .status =       usbnet_cdc_status,
        .manage_power = cdc_manage_power,
 };
 
 static const struct driver_info mbm_info = {
        .description =  "Mobile Broadband Network Device",
        .flags =        FLAG_WWAN,
-       .bind =         cdc_bind,
+       .bind =         usbnet_cdc_bind,
        .unbind =       usbnet_cdc_unbind,
-       .status =       cdc_status,
+       .status =       usbnet_cdc_status,
        .manage_power = cdc_manage_power,
 };
 
@@ -560,6 +562,13 @@ static const struct usb_device_id  products [] = {
        .driver_info            = 0,
 },
 
+/* LG Electronics VL600 wants additional headers on every frame */
+{
+       USB_DEVICE_AND_INTERFACE_INFO(0x1004, 0x61aa, USB_CLASS_COMM,
+                       USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
+       .driver_info            = 0,
+},
+
 /*
  * WHITELIST!!!
  *
diff --git a/drivers/net/usb/lg-vl600.c b/drivers/net/usb/lg-vl600.c
new file mode 100644 (file)
index 0000000..1d83ccf
--- /dev/null
@@ -0,0 +1,346 @@
+/*
+ * Ethernet interface part of the LG VL600 LTE modem (4G dongle)
+ *
+ * Copyright (C) 2011 Intel Corporation
+ * Author: Andrzej Zaborowski <balrogg@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/mii.h>
+#include <linux/usb.h>
+#include <linux/usb/cdc.h>
+#include <linux/usb/usbnet.h>
+#include <linux/if_ether.h>
+#include <linux/if_arp.h>
+#include <linux/inetdevice.h>
+
+/*
+ * The device has a CDC ACM port for modem control (it claims to be
+ * CDC ACM anyway) and a CDC Ethernet port for actual network data.
+ * It will however ignore data on both ports that is not encapsulated
+ * in a specific way, any data returned is also encapsulated the same
+ * way.  The headers don't seem to follow any popular standard.
+ *
+ * This driver adds and strips these headers from the ethernet frames
+ * sent/received from the CDC Ethernet port.  The proprietary header
+ * replaces the standard ethernet header in a packet so only actual
+ * ethernet frames are allowed.  The headers allow some form of
+ * multiplexing by using non standard values of the .h_proto field.
+ * Windows/Mac drivers do send a couple of such frames to the device
+ * during initialisation, with protocol set to 0x0906 or 0x0b06 and (what
+ * seems to be) a flag in the .dummy_flags.  This doesn't seem necessary
+ * for modem operation but can possibly be used for GPS or other funcitons.
+ */
+
+struct vl600_frame_hdr {
+       __le32 len;
+       __le32 serial;
+       __le32 pkt_cnt;
+       __le32 dummy_flags;
+       __le32 dummy;
+       __le32 magic;
+} __attribute__((packed));
+
+struct vl600_pkt_hdr {
+       __le32 dummy[2];
+       __le32 len;
+       __be16 h_proto;
+} __attribute__((packed));
+
+struct vl600_state {
+       struct sk_buff *current_rx_buf;
+};
+
+static int vl600_bind(struct usbnet *dev, struct usb_interface *intf)
+{
+       int ret;
+       struct vl600_state *s = kzalloc(sizeof(struct vl600_state), GFP_KERNEL);
+
+       if (!s)
+               return -ENOMEM;
+
+       ret = usbnet_cdc_bind(dev, intf);
+       if (ret) {
+               kfree(s);
+               return ret;
+       }
+
+       dev->driver_priv = s;
+
+       /* ARP packets don't go through, but they're also of no use.  The
+        * subnet has only two hosts anyway: us and the gateway / DHCP
+        * server (probably simulated by modem firmware or network operator)
+        * whose address changes everytime we connect to the intarwebz and
+        * who doesn't bother answering ARP requests either.  So hardware
+        * addresses have no meaning, the destination and the source of every
+        * packet depend only on whether it is on the IN or OUT endpoint.  */
+       dev->net->flags |= IFF_NOARP;
+
+       return ret;
+}
+
+static void vl600_unbind(struct usbnet *dev, struct usb_interface *intf)
+{
+       struct vl600_state *s = dev->driver_priv;
+
+       if (s->current_rx_buf)
+               dev_kfree_skb(s->current_rx_buf);
+
+       kfree(s);
+
+       return usbnet_cdc_unbind(dev, intf);
+}
+
+static int vl600_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
+{
+       struct vl600_frame_hdr *frame;
+       struct vl600_pkt_hdr *packet;
+       struct ethhdr *ethhdr;
+       int packet_len, count;
+       struct sk_buff *buf = skb;
+       struct sk_buff *clone;
+       struct vl600_state *s = dev->driver_priv;
+
+       /* Frame lengths are generally 4B multiplies but every couple of
+        * hours there's an odd number of bytes sized yet correct frame,
+        * so don't require this.  */
+
+       /* Allow a packet (or multiple packets batched together) to be
+        * split across many frames.  We don't allow a new batch to
+        * begin in the same frame another one is ending however, and no
+        * leading or trailing pad bytes.  */
+       if (s->current_rx_buf) {
+               frame = (struct vl600_frame_hdr *) s->current_rx_buf->data;
+               if (skb->len + s->current_rx_buf->len >
+                               le32_to_cpup(&frame->len)) {
+                       netif_err(dev, ifup, dev->net, "Fragment too long\n");
+                       dev->net->stats.rx_length_errors++;
+                       goto error;
+               }
+
+               buf = s->current_rx_buf;
+               memcpy(skb_put(buf, skb->len), skb->data, skb->len);
+       } else if (skb->len < 4) {
+               netif_err(dev, ifup, dev->net, "Frame too short\n");
+               dev->net->stats.rx_length_errors++;
+               goto error;
+       }
+
+       frame = (struct vl600_frame_hdr *) buf->data;
+       /* NOTE: Should check that frame->magic == 0x53544448?
+        * Otherwise if we receive garbage at the beginning of the frame
+        * we may end up allocating a huge buffer and saving all the
+        * future incoming data into it.  */
+
+       if (buf->len < sizeof(*frame) ||
+                       buf->len != le32_to_cpup(&frame->len)) {
+               /* Save this fragment for later assembly */
+               if (s->current_rx_buf)
+                       return 0;
+
+               s->current_rx_buf = skb_copy_expand(skb, 0,
+                               le32_to_cpup(&frame->len), GFP_ATOMIC);
+               if (!s->current_rx_buf) {
+                       netif_err(dev, ifup, dev->net, "Reserving %i bytes "
+                                       "for packet assembly failed.\n",
+                                       le32_to_cpup(&frame->len));
+                       dev->net->stats.rx_errors++;
+               }
+
+               return 0;
+       }
+
+       count = le32_to_cpup(&frame->pkt_cnt);
+
+       skb_pull(buf, sizeof(*frame));
+
+       while (count--) {
+               if (buf->len < sizeof(*packet)) {
+                       netif_err(dev, ifup, dev->net, "Packet too short\n");
+                       goto error;
+               }
+
+               packet = (struct vl600_pkt_hdr *) buf->data;
+               packet_len = sizeof(*packet) + le32_to_cpup(&packet->len);
+               if (packet_len > buf->len) {
+                       netif_err(dev, ifup, dev->net,
+                                       "Bad packet length stored in header\n");
+                       goto error;
+               }
+
+               /* Packet header is same size as the ethernet header
+                * (sizeof(*packet) == sizeof(*ethhdr)), additionally
+                * the h_proto field is in the same place so we just leave it
+                * alone and fill in the remaining fields.
+                */
+               ethhdr = (struct ethhdr *) skb->data;
+               if (be16_to_cpup(&ethhdr->h_proto) == ETH_P_ARP &&
+                               buf->len > 0x26) {
+                       /* Copy the addresses from packet contents */
+                       memcpy(ethhdr->h_source,
+                                       &buf->data[sizeof(*ethhdr) + 0x8],
+                                       ETH_ALEN);
+                       memcpy(ethhdr->h_dest,
+                                       &buf->data[sizeof(*ethhdr) + 0x12],
+                                       ETH_ALEN);
+               } else {
+                       memset(ethhdr->h_source, 0, ETH_ALEN);
+                       memcpy(ethhdr->h_dest, dev->net->dev_addr, ETH_ALEN);
+               }
+
+               if (count) {
+                       /* Not the last packet in this batch */
+                       clone = skb_clone(buf, GFP_ATOMIC);
+                       if (!clone)
+                               goto error;
+
+                       skb_trim(clone, packet_len);
+                       usbnet_skb_return(dev, clone);
+
+                       skb_pull(buf, (packet_len + 3) & ~3);
+               } else {
+                       skb_trim(buf, packet_len);
+
+                       if (s->current_rx_buf) {
+                               usbnet_skb_return(dev, buf);
+                               s->current_rx_buf = NULL;
+                               return 0;
+                       }
+
+                       return 1;
+               }
+       }
+
+error:
+       if (s->current_rx_buf) {
+               dev_kfree_skb_any(s->current_rx_buf);
+               s->current_rx_buf = NULL;
+       }
+       dev->net->stats.rx_errors++;
+       return 0;
+}
+
+static struct sk_buff *vl600_tx_fixup(struct usbnet *dev,
+               struct sk_buff *skb, gfp_t flags)
+{
+       struct sk_buff *ret;
+       struct vl600_frame_hdr *frame;
+       struct vl600_pkt_hdr *packet;
+       static uint32_t serial = 1;
+       int orig_len = skb->len - sizeof(struct ethhdr);
+       int full_len = (skb->len + sizeof(struct vl600_frame_hdr) + 3) & ~3;
+
+       frame = (struct vl600_frame_hdr *) skb->data;
+       if (skb->len > sizeof(*frame) && skb->len == le32_to_cpup(&frame->len))
+               return skb; /* Already encapsulated? */
+
+       if (skb->len < sizeof(struct ethhdr))
+               /* Drop, device can only deal with ethernet packets */
+               return NULL;
+
+       if (!skb_cloned(skb)) {
+               int headroom = skb_headroom(skb);
+               int tailroom = skb_tailroom(skb);
+
+               if (tailroom >= full_len - skb->len - sizeof(*frame) &&
+                               headroom >= sizeof(*frame))
+                       /* There's enough head and tail room */
+                       goto encapsulate;
+
+               if (headroom + tailroom + skb->len >= full_len) {
+                       /* There's enough total room, just readjust */
+                       skb->data = memmove(skb->head + sizeof(*frame),
+                                       skb->data, skb->len);
+                       skb_set_tail_pointer(skb, skb->len);
+                       goto encapsulate;
+               }
+       }
+
+       /* Alloc a new skb with the required size */
+       ret = skb_copy_expand(skb, sizeof(struct vl600_frame_hdr), full_len -
+                       skb->len - sizeof(struct vl600_frame_hdr), flags);
+       dev_kfree_skb_any(skb);
+       if (!ret)
+               return ret;
+       skb = ret;
+
+encapsulate:
+       /* Packet header is same size as ethernet packet header
+        * (sizeof(*packet) == sizeof(struct ethhdr)), additionally the
+        * h_proto field is in the same place so we just leave it alone and
+        * overwrite the remaining fields.
+        */
+       packet = (struct vl600_pkt_hdr *) skb->data;
+       memset(&packet->dummy, 0, sizeof(packet->dummy));
+       packet->len = cpu_to_le32(orig_len);
+
+       frame = (struct vl600_frame_hdr *) skb_push(skb, sizeof(*frame));
+       memset(frame, 0, sizeof(*frame));
+       frame->len = cpu_to_le32(full_len);
+       frame->serial = cpu_to_le32(serial++);
+       frame->pkt_cnt = cpu_to_le32(1);
+
+       if (skb->len < full_len) /* Pad */
+               skb_put(skb, full_len - skb->len);
+
+       return skb;
+}
+
+static const struct driver_info        vl600_info = {
+       .description    = "LG VL600 modem",
+       .flags          = FLAG_ETHER | FLAG_RX_ASSEMBLE,
+       .bind           = vl600_bind,
+       .unbind         = vl600_unbind,
+       .status         = usbnet_cdc_status,
+       .rx_fixup       = vl600_rx_fixup,
+       .tx_fixup       = vl600_tx_fixup,
+};
+
+static const struct usb_device_id products[] = {
+       {
+               USB_DEVICE_AND_INTERFACE_INFO(0x1004, 0x61aa, USB_CLASS_COMM,
+                               USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
+               .driver_info    = (unsigned long) &vl600_info,
+       },
+       {},     /* End */
+};
+MODULE_DEVICE_TABLE(usb, products);
+
+static struct usb_driver lg_vl600_driver = {
+       .name           = "lg-vl600",
+       .id_table       = products,
+       .probe          = usbnet_probe,
+       .disconnect     = usbnet_disconnect,
+       .suspend        = usbnet_suspend,
+       .resume         = usbnet_resume,
+};
+
+static int __init vl600_init(void)
+{
+       return usb_register(&lg_vl600_driver);
+}
+module_init(vl600_init);
+
+static void __exit vl600_exit(void)
+{
+       usb_deregister(&lg_vl600_driver);
+}
+module_exit(vl600_exit);
+
+MODULE_AUTHOR("Anrzej Zaborowski");
+MODULE_DESCRIPTION("LG-VL600 modem's ethernet link");
+MODULE_LICENSE("GPL");
index 95c41d5..cf58b76 100644 (file)
@@ -387,8 +387,12 @@ static int rx_submit (struct usbnet *dev, struct urb *urb, gfp_t flags)
 static inline void rx_process (struct usbnet *dev, struct sk_buff *skb)
 {
        if (dev->driver_info->rx_fixup &&
-           !dev->driver_info->rx_fixup (dev, skb))
-               goto error;
+           !dev->driver_info->rx_fixup (dev, skb)) {
+               /* With RX_ASSEMBLE, rx_fixup() must update counters */
+               if (!(dev->driver_info->flags & FLAG_RX_ASSEMBLE))
+                       dev->net->stats.rx_errors++;
+               goto done;
+       }
        // else network stack removes extra byte if we forced a short packet
 
        if (skb->len) {
@@ -401,8 +405,8 @@ static inline void rx_process (struct usbnet *dev, struct sk_buff *skb)
        }
 
        netif_dbg(dev, rx_err, dev->net, "drop\n");
-error:
        dev->net->stats.rx_errors++;
+done:
        skb_queue_tail(&dev->done, skb);
 }
 
index a520395..443cb7f 100644 (file)
 #define        COLIBRI320_DETECT_GPIO  81
 #define        COLIBRI320_READY_GPIO   29
 
-static struct {
-       int     reset_gpio;
-       int     ppen_gpio;
-       int     bvd1_gpio;
-       int     bvd2_gpio;
-       int     detect_gpio;
-       int     ready_gpio;
-} colibri_pcmcia_gpio;
+enum {
+       DETECT = 0,
+       READY = 1,
+       BVD1 = 2,
+       BVD2 = 3,
+       PPEN = 4,
+       RESET = 5,
+};
+
+/* Contents of this array are configured on-the-fly in init function */
+static struct gpio colibri_pcmcia_gpios[] = {
+       { 0,    GPIOF_IN,       "PCMCIA Detect" },
+       { 0,    GPIOF_IN,       "PCMCIA Ready" },
+       { 0,    GPIOF_IN,       "PCMCIA BVD1" },
+       { 0,    GPIOF_IN,       "PCMCIA BVD2" },
+       { 0,    GPIOF_INIT_LOW, "PCMCIA PPEN" },
+       { 0,    GPIOF_INIT_HIGH,"PCMCIA Reset" },
+};
 
 static struct pcmcia_irqs colibri_irqs[] = {
        {
@@ -54,88 +64,42 @@ static int colibri_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 {
        int ret;
 
-       ret = gpio_request(colibri_pcmcia_gpio.detect_gpio, "DETECT");
+       ret = gpio_request_array(colibri_pcmcia_gpios,
+                               ARRAY_SIZE(colibri_pcmcia_gpios));
        if (ret)
                goto err1;
-       ret = gpio_direction_input(colibri_pcmcia_gpio.detect_gpio);
-       if (ret)
-               goto err2;
-
-       ret = gpio_request(colibri_pcmcia_gpio.ready_gpio, "READY");
-       if (ret)
-               goto err2;
-       ret = gpio_direction_input(colibri_pcmcia_gpio.ready_gpio);
-       if (ret)
-               goto err3;
 
-       ret = gpio_request(colibri_pcmcia_gpio.bvd1_gpio, "BVD1");
-       if (ret)
-               goto err3;
-       ret = gpio_direction_input(colibri_pcmcia_gpio.bvd1_gpio);
-       if (ret)
-               goto err4;
+       colibri_irqs[0].irq = gpio_to_irq(colibri_pcmcia_gpios[DETECT].gpio);
+       skt->socket.pci_irq = gpio_to_irq(colibri_pcmcia_gpios[READY].gpio);
 
-       ret = gpio_request(colibri_pcmcia_gpio.bvd2_gpio, "BVD2");
-       if (ret)
-               goto err4;
-       ret = gpio_direction_input(colibri_pcmcia_gpio.bvd2_gpio);
-       if (ret)
-               goto err5;
-
-       ret = gpio_request(colibri_pcmcia_gpio.ppen_gpio, "PPEN");
-       if (ret)
-               goto err5;
-       ret = gpio_direction_output(colibri_pcmcia_gpio.ppen_gpio, 0);
-       if (ret)
-               goto err6;
-
-       ret = gpio_request(colibri_pcmcia_gpio.reset_gpio, "RESET");
-       if (ret)
-               goto err6;
-       ret = gpio_direction_output(colibri_pcmcia_gpio.reset_gpio, 1);
+       ret = soc_pcmcia_request_irqs(skt, colibri_irqs,
+                                       ARRAY_SIZE(colibri_irqs));
        if (ret)
-               goto err7;
-
-       colibri_irqs[0].irq = gpio_to_irq(colibri_pcmcia_gpio.detect_gpio);
-       skt->socket.pci_irq = gpio_to_irq(colibri_pcmcia_gpio.ready_gpio);
+               goto err2;
 
-       return soc_pcmcia_request_irqs(skt, colibri_irqs,
-                                       ARRAY_SIZE(colibri_irqs));
+       return ret;
 
-err7:
-       gpio_free(colibri_pcmcia_gpio.detect_gpio);
-err6:
-       gpio_free(colibri_pcmcia_gpio.ready_gpio);
-err5:
-       gpio_free(colibri_pcmcia_gpio.bvd1_gpio);
-err4:
-       gpio_free(colibri_pcmcia_gpio.bvd2_gpio);
-err3:
-       gpio_free(colibri_pcmcia_gpio.reset_gpio);
 err2:
-       gpio_free(colibri_pcmcia_gpio.ppen_gpio);
+       gpio_free_array(colibri_pcmcia_gpios,
+                       ARRAY_SIZE(colibri_pcmcia_gpios));
 err1:
        return ret;
 }
 
 static void colibri_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
 {
-       gpio_free(colibri_pcmcia_gpio.detect_gpio);
-       gpio_free(colibri_pcmcia_gpio.ready_gpio);
-       gpio_free(colibri_pcmcia_gpio.bvd1_gpio);
-       gpio_free(colibri_pcmcia_gpio.bvd2_gpio);
-       gpio_free(colibri_pcmcia_gpio.reset_gpio);
-       gpio_free(colibri_pcmcia_gpio.ppen_gpio);
+       gpio_free_array(colibri_pcmcia_gpios,
+                       ARRAY_SIZE(colibri_pcmcia_gpios));
 }
 
 static void colibri_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
                                        struct pcmcia_state *state)
 {
 
-       state->detect = !!gpio_get_value(colibri_pcmcia_gpio.detect_gpio);
-       state->ready  = !!gpio_get_value(colibri_pcmcia_gpio.ready_gpio);
-       state->bvd1   = !!gpio_get_value(colibri_pcmcia_gpio.bvd1_gpio);
-       state->bvd2   = !!gpio_get_value(colibri_pcmcia_gpio.bvd2_gpio);
+       state->detect = !!gpio_get_value(colibri_pcmcia_gpios[DETECT].gpio);
+       state->ready  = !!gpio_get_value(colibri_pcmcia_gpios[READY].gpio);
+       state->bvd1   = !!gpio_get_value(colibri_pcmcia_gpios[BVD1].gpio);
+       state->bvd2   = !!gpio_get_value(colibri_pcmcia_gpios[BVD2].gpio);
        state->wrprot = 0;
        state->vs_3v  = 1;
        state->vs_Xv  = 0;
@@ -145,9 +109,10 @@ static int
 colibri_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
                                const socket_state_t *state)
 {
-       gpio_set_value(colibri_pcmcia_gpio.ppen_gpio,
+       gpio_set_value(colibri_pcmcia_gpios[PPEN].gpio,
                        !(state->Vcc == 33 && state->Vpp < 50));
-       gpio_set_value(colibri_pcmcia_gpio.reset_gpio, state->flags & SS_RESET);
+       gpio_set_value(colibri_pcmcia_gpios[RESET].gpio,
+                       state->flags & SS_RESET);
        return 0;
 }
 
@@ -190,20 +155,20 @@ static int __init colibri_pcmcia_init(void)
 
        /* Colibri PXA270 */
        if (machine_is_colibri()) {
-               colibri_pcmcia_gpio.reset_gpio  = COLIBRI270_RESET_GPIO;
-               colibri_pcmcia_gpio.ppen_gpio   = COLIBRI270_PPEN_GPIO;
-               colibri_pcmcia_gpio.bvd1_gpio   = COLIBRI270_BVD1_GPIO;
-               colibri_pcmcia_gpio.bvd2_gpio   = COLIBRI270_BVD2_GPIO;
-               colibri_pcmcia_gpio.detect_gpio = COLIBRI270_DETECT_GPIO;
-               colibri_pcmcia_gpio.ready_gpio  = COLIBRI270_READY_GPIO;
+               colibri_pcmcia_gpios[RESET].gpio        = COLIBRI270_RESET_GPIO;
+               colibri_pcmcia_gpios[PPEN].gpio         = COLIBRI270_PPEN_GPIO;
+               colibri_pcmcia_gpios[BVD1].gpio         = COLIBRI270_BVD1_GPIO;
+               colibri_pcmcia_gpios[BVD2].gpio         = COLIBRI270_BVD2_GPIO;
+               colibri_pcmcia_gpios[DETECT].gpio       = COLIBRI270_DETECT_GPIO;
+               colibri_pcmcia_gpios[READY].gpio        = COLIBRI270_READY_GPIO;
        /* Colibri PXA320 */
        } else if (machine_is_colibri320()) {
-               colibri_pcmcia_gpio.reset_gpio  = COLIBRI320_RESET_GPIO;
-               colibri_pcmcia_gpio.ppen_gpio   = COLIBRI320_PPEN_GPIO;
-               colibri_pcmcia_gpio.bvd1_gpio   = COLIBRI320_BVD1_GPIO;
-               colibri_pcmcia_gpio.bvd2_gpio   = COLIBRI320_BVD2_GPIO;
-               colibri_pcmcia_gpio.detect_gpio = COLIBRI320_DETECT_GPIO;
-               colibri_pcmcia_gpio.ready_gpio  = COLIBRI320_READY_GPIO;
+               colibri_pcmcia_gpios[RESET].gpio        = COLIBRI320_RESET_GPIO;
+               colibri_pcmcia_gpios[PPEN].gpio         = COLIBRI320_PPEN_GPIO;
+               colibri_pcmcia_gpios[BVD1].gpio         = COLIBRI320_BVD1_GPIO;
+               colibri_pcmcia_gpios[BVD2].gpio         = COLIBRI320_BVD2_GPIO;
+               colibri_pcmcia_gpios[DETECT].gpio       = COLIBRI320_DETECT_GPIO;
+               colibri_pcmcia_gpios[READY].gpio        = COLIBRI320_READY_GPIO;
        }
 
        ret = platform_device_add_data(colibri_pcmcia_device,
index 6fb6f7f..69f7367 100644 (file)
@@ -4,7 +4,7 @@
  * Driver for Palm LifeDrive PCMCIA
  *
  * Copyright (C) 2006 Alex Osborne <ato@meshy.org>
- * Copyright (C) 2007-2008 Marek Vasut <marek.vasut@gmail.com>
+ * Copyright (C) 2007-2011 Marek Vasut <marek.vasut@gmail.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
 #include <mach/palmld.h>
 #include "soc_common.h"
 
+static struct gpio palmld_pcmcia_gpios[] = {
+       { GPIO_NR_PALMLD_PCMCIA_POWER,  GPIOF_INIT_LOW, "PCMCIA Power" },
+       { GPIO_NR_PALMLD_PCMCIA_RESET,  GPIOF_INIT_HIGH,"PCMCIA Reset" },
+       { GPIO_NR_PALMLD_PCMCIA_READY,  GPIOF_IN,       "PCMCIA Ready" },
+};
+
 static int palmld_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 {
        int ret;
 
-       ret = gpio_request(GPIO_NR_PALMLD_PCMCIA_POWER, "PCMCIA PWR");
-       if (ret)
-               goto err1;
-       ret = gpio_direction_output(GPIO_NR_PALMLD_PCMCIA_POWER, 0);
-       if (ret)
-               goto err2;
-
-       ret = gpio_request(GPIO_NR_PALMLD_PCMCIA_RESET, "PCMCIA RST");
-       if (ret)
-               goto err2;
-       ret = gpio_direction_output(GPIO_NR_PALMLD_PCMCIA_RESET, 1);
-       if (ret)
-               goto err3;
-
-       ret = gpio_request(GPIO_NR_PALMLD_PCMCIA_READY, "PCMCIA RDY");
-       if (ret)
-               goto err3;
-       ret = gpio_direction_input(GPIO_NR_PALMLD_PCMCIA_READY);
-       if (ret)
-               goto err4;
+       ret = gpio_request_array(palmld_pcmcia_gpios,
+                               ARRAY_SIZE(palmld_pcmcia_gpios));
 
        skt->socket.pci_irq = IRQ_GPIO(GPIO_NR_PALMLD_PCMCIA_READY);
-       return 0;
 
-err4:
-       gpio_free(GPIO_NR_PALMLD_PCMCIA_READY);
-err3:
-       gpio_free(GPIO_NR_PALMLD_PCMCIA_RESET);
-err2:
-       gpio_free(GPIO_NR_PALMLD_PCMCIA_POWER);
-err1:
        return ret;
 }
 
 static void palmld_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
 {
-       gpio_free(GPIO_NR_PALMLD_PCMCIA_READY);
-       gpio_free(GPIO_NR_PALMLD_PCMCIA_RESET);
-       gpio_free(GPIO_NR_PALMLD_PCMCIA_POWER);
+       gpio_free_array(palmld_pcmcia_gpios, ARRAY_SIZE(palmld_pcmcia_gpios));
 }
 
 static void palmld_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
index 459a232..d0ad6a7 100644 (file)
@@ -4,7 +4,7 @@
  * Driver for Palm Tungsten|C PCMCIA
  *
  * Copyright (C) 2008 Alex Osborne <ato@meshy.org>
- * Copyright (C) 2009 Marek Vasut <marek.vasut@gmail.com>
+ * Copyright (C) 2009-2011 Marek Vasut <marek.vasut@gmail.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
 #include <mach/palmtc.h>
 #include "soc_common.h"
 
+static struct gpio palmtc_pcmcia_gpios[] = {
+       { GPIO_NR_PALMTC_PCMCIA_POWER1, GPIOF_INIT_LOW, "PCMCIA Power 1" },
+       { GPIO_NR_PALMTC_PCMCIA_POWER2, GPIOF_INIT_LOW, "PCMCIA Power 2" },
+       { GPIO_NR_PALMTC_PCMCIA_POWER3, GPIOF_INIT_LOW, "PCMCIA Power 3" },
+       { GPIO_NR_PALMTC_PCMCIA_RESET,  GPIOF_INIT_HIGH,"PCMCIA Reset" },
+       { GPIO_NR_PALMTC_PCMCIA_READY,  GPIOF_IN,       "PCMCIA Ready" },
+       { GPIO_NR_PALMTC_PCMCIA_PWRREADY, GPIOF_IN,     "PCMCIA Power Ready" },
+};
+
 static int palmtc_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 {
        int ret;
 
-       ret = gpio_request(GPIO_NR_PALMTC_PCMCIA_POWER1, "PCMCIA PWR1");
-       if (ret)
-               goto err1;
-       ret = gpio_direction_output(GPIO_NR_PALMTC_PCMCIA_POWER1, 0);
-       if (ret)
-               goto err2;
-
-       ret = gpio_request(GPIO_NR_PALMTC_PCMCIA_POWER2, "PCMCIA PWR2");
-       if (ret)
-               goto err2;
-       ret = gpio_direction_output(GPIO_NR_PALMTC_PCMCIA_POWER2, 0);
-       if (ret)
-               goto err3;
-
-       ret = gpio_request(GPIO_NR_PALMTC_PCMCIA_POWER3, "PCMCIA PWR3");
-       if (ret)
-               goto err3;
-       ret = gpio_direction_output(GPIO_NR_PALMTC_PCMCIA_POWER3, 0);
-       if (ret)
-               goto err4;
-
-       ret = gpio_request(GPIO_NR_PALMTC_PCMCIA_RESET, "PCMCIA RST");
-       if (ret)
-               goto err4;
-       ret = gpio_direction_output(GPIO_NR_PALMTC_PCMCIA_RESET, 1);
-       if (ret)
-               goto err5;
-
-       ret = gpio_request(GPIO_NR_PALMTC_PCMCIA_READY, "PCMCIA RDY");
-       if (ret)
-               goto err5;
-       ret = gpio_direction_input(GPIO_NR_PALMTC_PCMCIA_READY);
-       if (ret)
-               goto err6;
-
-       ret = gpio_request(GPIO_NR_PALMTC_PCMCIA_PWRREADY, "PCMCIA PWRRDY");
-       if (ret)
-               goto err6;
-       ret = gpio_direction_input(GPIO_NR_PALMTC_PCMCIA_PWRREADY);
-       if (ret)
-               goto err7;
+       ret = gpio_request_array(palmtc_pcmcia_gpios,
+                               ARRAY_SIZE(palmtc_pcmcia_gpios));
 
        skt->socket.pci_irq = IRQ_GPIO(GPIO_NR_PALMTC_PCMCIA_READY);
-       return 0;
 
-err7:
-       gpio_free(GPIO_NR_PALMTC_PCMCIA_PWRREADY);
-err6:
-       gpio_free(GPIO_NR_PALMTC_PCMCIA_READY);
-err5:
-       gpio_free(GPIO_NR_PALMTC_PCMCIA_RESET);
-err4:
-       gpio_free(GPIO_NR_PALMTC_PCMCIA_POWER3);
-err3:
-       gpio_free(GPIO_NR_PALMTC_PCMCIA_POWER2);
-err2:
-       gpio_free(GPIO_NR_PALMTC_PCMCIA_POWER1);
-err1:
        return ret;
 }
 
 static void palmtc_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
 {
-       gpio_free(GPIO_NR_PALMTC_PCMCIA_PWRREADY);
-       gpio_free(GPIO_NR_PALMTC_PCMCIA_READY);
-       gpio_free(GPIO_NR_PALMTC_PCMCIA_RESET);
-       gpio_free(GPIO_NR_PALMTC_PCMCIA_POWER3);
-       gpio_free(GPIO_NR_PALMTC_PCMCIA_POWER2);
-       gpio_free(GPIO_NR_PALMTC_PCMCIA_POWER1);
+       gpio_free_array(palmtc_pcmcia_gpios, ARRAY_SIZE(palmtc_pcmcia_gpios));
 }
 
 static void palmtc_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
index b07b247..1a25804 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Driver for Palm T|X PCMCIA
  *
- * Copyright (C) 2007-2008 Marek Vasut <marek.vasut@gmail.com>
+ * Copyright (C) 2007-2011 Marek Vasut <marek.vasut@gmail.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
 
 #include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/gpio.h>
 
 #include <asm/mach-types.h>
-
-#include <mach/gpio.h>
 #include <mach/palmtx.h>
-
 #include "soc_common.h"
 
+static struct gpio palmtx_pcmcia_gpios[] = {
+       { GPIO_NR_PALMTX_PCMCIA_POWER1, GPIOF_INIT_LOW, "PCMCIA Power 1" },
+       { GPIO_NR_PALMTX_PCMCIA_POWER2, GPIOF_INIT_LOW, "PCMCIA Power 2" },
+       { GPIO_NR_PALMTX_PCMCIA_RESET,  GPIOF_INIT_HIGH,"PCMCIA Reset" },
+       { GPIO_NR_PALMTX_PCMCIA_READY,  GPIOF_IN,       "PCMCIA Ready" },
+};
+
 static int palmtx_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 {
        int ret;
 
-       ret = gpio_request(GPIO_NR_PALMTX_PCMCIA_POWER1, "PCMCIA PWR1");
-       if (ret)
-               goto err1;
-       ret = gpio_direction_output(GPIO_NR_PALMTX_PCMCIA_POWER1, 0);
-       if (ret)
-               goto err2;
-
-       ret = gpio_request(GPIO_NR_PALMTX_PCMCIA_POWER2, "PCMCIA PWR2");
-       if (ret)
-               goto err2;
-       ret = gpio_direction_output(GPIO_NR_PALMTX_PCMCIA_POWER2, 0);
-       if (ret)
-               goto err3;
-
-       ret = gpio_request(GPIO_NR_PALMTX_PCMCIA_RESET, "PCMCIA RST");
-       if (ret)
-               goto err3;
-       ret = gpio_direction_output(GPIO_NR_PALMTX_PCMCIA_RESET, 1);
-       if (ret)
-               goto err4;
-
-       ret = gpio_request(GPIO_NR_PALMTX_PCMCIA_READY, "PCMCIA RDY");
-       if (ret)
-               goto err4;
-       ret = gpio_direction_input(GPIO_NR_PALMTX_PCMCIA_READY);
-       if (ret)
-               goto err5;
+       ret = gpio_request_array(palmtx_pcmcia_gpios,
+                               ARRAY_SIZE(palmtx_pcmcia_gpios));
 
        skt->socket.pci_irq = gpio_to_irq(GPIO_NR_PALMTX_PCMCIA_READY);
-       return 0;
 
-err5:
-       gpio_free(GPIO_NR_PALMTX_PCMCIA_READY);
-err4:
-       gpio_free(GPIO_NR_PALMTX_PCMCIA_RESET);
-err3:
-       gpio_free(GPIO_NR_PALMTX_PCMCIA_POWER2);
-err2:
-       gpio_free(GPIO_NR_PALMTX_PCMCIA_POWER1);
-err1:
        return ret;
 }
 
 static void palmtx_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
 {
-       gpio_free(GPIO_NR_PALMTX_PCMCIA_READY);
-       gpio_free(GPIO_NR_PALMTX_PCMCIA_RESET);
-       gpio_free(GPIO_NR_PALMTX_PCMCIA_POWER2);
-       gpio_free(GPIO_NR_PALMTX_PCMCIA_POWER1);
+       gpio_free_array(palmtx_pcmcia_gpios, ARRAY_SIZE(palmtx_pcmcia_gpios));
 }
 
 static void palmtx_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
index 55627ec..435002d 100644 (file)
@@ -3,8 +3,7 @@
  *
  * Driver for Voipac PXA270 PCMCIA and CF sockets
  *
- * Copyright (C) 2010
- * Marek Vasut <marek.vasut@gmail.com>
+ * Copyright (C) 2010-2011 Marek Vasut <marek.vasut@gmail.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
 
 #include "soc_common.h"
 
+static struct gpio vpac270_pcmcia_gpios[] = {
+       { GPIO84_VPAC270_PCMCIA_CD,     GPIOF_IN,       "PCMCIA Card Detect" },
+       { GPIO35_VPAC270_PCMCIA_RDY,    GPIOF_IN,       "PCMCIA Ready" },
+       { GPIO107_VPAC270_PCMCIA_PPEN,  GPIOF_INIT_LOW, "PCMCIA PPEN" },
+       { GPIO11_VPAC270_PCMCIA_RESET,  GPIOF_INIT_LOW, "PCMCIA Reset" },
+};
+
+static struct gpio vpac270_cf_gpios[] = {
+       { GPIO17_VPAC270_CF_CD,         GPIOF_IN,       "CF Card Detect" },
+       { GPIO12_VPAC270_CF_RDY,        GPIOF_IN,       "CF Ready" },
+       { GPIO16_VPAC270_CF_RESET,      GPIOF_INIT_LOW, "CF Reset" },
+};
+
 static struct pcmcia_irqs cd_irqs[] = {
        {
                .sock = 0,
@@ -40,96 +52,34 @@ static int vpac270_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
        int ret;
 
        if (skt->nr == 0) {
-               ret = gpio_request(GPIO84_VPAC270_PCMCIA_CD, "PCMCIA CD");
-               if (ret)
-                       goto err1;
-               ret = gpio_direction_input(GPIO84_VPAC270_PCMCIA_CD);
-               if (ret)
-                       goto err2;
-
-               ret = gpio_request(GPIO35_VPAC270_PCMCIA_RDY, "PCMCIA RDY");
-               if (ret)
-                       goto err2;
-               ret = gpio_direction_input(GPIO35_VPAC270_PCMCIA_RDY);
-               if (ret)
-                       goto err3;
-
-               ret = gpio_request(GPIO107_VPAC270_PCMCIA_PPEN, "PCMCIA PPEN");
-               if (ret)
-                       goto err3;
-               ret = gpio_direction_output(GPIO107_VPAC270_PCMCIA_PPEN, 0);
-               if (ret)
-                       goto err4;
-
-               ret = gpio_request(GPIO11_VPAC270_PCMCIA_RESET, "PCMCIA RESET");
-               if (ret)
-                       goto err4;
-               ret = gpio_direction_output(GPIO11_VPAC270_PCMCIA_RESET, 0);
-               if (ret)
-                       goto err5;
+               ret = gpio_request_array(vpac270_pcmcia_gpios,
+                               ARRAY_SIZE(vpac270_pcmcia_gpios));
 
                skt->socket.pci_irq = gpio_to_irq(GPIO35_VPAC270_PCMCIA_RDY);
 
-               return soc_pcmcia_request_irqs(skt, &cd_irqs[0], 1);
-
-err5:
-               gpio_free(GPIO11_VPAC270_PCMCIA_RESET);
-err4:
-               gpio_free(GPIO107_VPAC270_PCMCIA_PPEN);
-err3:
-               gpio_free(GPIO35_VPAC270_PCMCIA_RDY);
-err2:
-               gpio_free(GPIO84_VPAC270_PCMCIA_CD);
-err1:
-               return ret;
-
+               if (!ret)
+                       ret = soc_pcmcia_request_irqs(skt, &cd_irqs[0], 1);
        } else {
-               ret = gpio_request(GPIO17_VPAC270_CF_CD, "CF CD");
-               if (ret)
-                       goto err6;
-               ret = gpio_direction_input(GPIO17_VPAC270_CF_CD);
-               if (ret)
-                       goto err7;
-
-               ret = gpio_request(GPIO12_VPAC270_CF_RDY, "CF RDY");
-               if (ret)
-                       goto err7;
-               ret = gpio_direction_input(GPIO12_VPAC270_CF_RDY);
-               if (ret)
-                       goto err8;
-
-               ret = gpio_request(GPIO16_VPAC270_CF_RESET, "CF RESET");
-               if (ret)
-                       goto err8;
-               ret = gpio_direction_output(GPIO16_VPAC270_CF_RESET, 0);
-               if (ret)
-                       goto err9;
+               ret = gpio_request_array(vpac270_cf_gpios,
+                               ARRAY_SIZE(vpac270_cf_gpios));
 
                skt->socket.pci_irq = gpio_to_irq(GPIO12_VPAC270_CF_RDY);
 
-               return soc_pcmcia_request_irqs(skt, &cd_irqs[1], 1);
-
-err9:
-               gpio_free(GPIO16_VPAC270_CF_RESET);
-err8:
-               gpio_free(GPIO12_VPAC270_CF_RDY);
-err7:
-               gpio_free(GPIO17_VPAC270_CF_CD);
-err6:
-               return ret;
-
+               if (!ret)
+                       ret = soc_pcmcia_request_irqs(skt, &cd_irqs[1], 1);
        }
+
+       return ret;
 }
 
 static void vpac270_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
 {
-       gpio_free(GPIO11_VPAC270_PCMCIA_RESET);
-       gpio_free(GPIO107_VPAC270_PCMCIA_PPEN);
-       gpio_free(GPIO35_VPAC270_PCMCIA_RDY);
-       gpio_free(GPIO84_VPAC270_PCMCIA_CD);
-       gpio_free(GPIO16_VPAC270_CF_RESET);
-       gpio_free(GPIO12_VPAC270_CF_RDY);
-       gpio_free(GPIO17_VPAC270_CF_CD);
+       if (skt->nr == 0)
+               gpio_request_array(vpac270_pcmcia_gpios,
+                                       ARRAY_SIZE(vpac270_pcmcia_gpios));
+       else
+               gpio_request_array(vpac270_cf_gpios,
+                                       ARRAY_SIZE(vpac270_cf_gpios));
 }
 
 static void vpac270_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
index df36a42..5b93485 100644 (file)
@@ -86,7 +86,7 @@ enum {        MODE_ENABLE_REG = 0, /* Bit(s) set -> interrupt enabled */
 
 static inline struct intc_desc_int *get_intc_desc(unsigned int irq)
 {
-       struct irq_chip *chip = get_irq_chip(irq);
+       struct irq_chip *chip = irq_get_chip(irq);
 
        return container_of(chip, struct intc_desc_int, chip);
 }
@@ -103,7 +103,7 @@ static inline void activate_irq(int irq)
        set_irq_flags(irq, IRQF_VALID);
 #else
        /* same effect on other architectures */
-       set_irq_noprobe(irq);
+       irq_set_noprobe(irq);
 #endif
 }
 
index b37f92c..444b60a 100644 (file)
@@ -139,24 +139,6 @@ static const char ep0name [] = "ep0";
 static void pxa25x_ep_fifo_flush (struct usb_ep *ep);
 static void nuke (struct pxa25x_ep *, int status);
 
-/* one GPIO should be used to detect VBUS from the host */
-static int is_vbus_present(void)
-{
-       struct pxa2xx_udc_mach_info             *mach = the_controller->mach;
-
-       if (gpio_is_valid(mach->gpio_vbus)) {
-               int value = gpio_get_value(mach->gpio_vbus);
-
-               if (mach->gpio_vbus_inverted)
-                       return !value;
-               else
-                       return !!value;
-       }
-       if (mach->udc_is_connected)
-               return mach->udc_is_connected();
-       return 1;
-}
-
 /* one GPIO should control a D+ pullup, so host sees this device (or not) */
 static void pullup_off(void)
 {
@@ -1055,7 +1037,7 @@ udc_seq_show(struct seq_file *m, void *_d)
                "%s version: %s\nGadget driver: %s\nHost %s\n\n",
                driver_name, DRIVER_VERSION SIZE_STR "(pio)",
                dev->driver ? dev->driver->driver.name : "(none)",
-               is_vbus_present() ? "full speed" : "disconnected");
+               dev->gadget.speed == USB_SPEED_FULL ? "full speed" : "disconnected");
 
        /* registers for device and ep0 */
        seq_printf(m,
@@ -1094,7 +1076,7 @@ udc_seq_show(struct seq_file *m, void *_d)
                        (tmp & UDCCFR_ACM) ? " acm" : "");
        }
 
-       if (!is_vbus_present() || !dev->driver)
+       if (dev->gadget.speed != USB_SPEED_FULL || !dev->driver)
                goto done;
 
        seq_printf(m, "ep0 IN %lu/%lu, OUT %lu/%lu\nirqs %lu\n\n",
@@ -1435,14 +1417,6 @@ lubbock_vbus_irq(int irq, void *_dev)
 
 #endif
 
-static irqreturn_t udc_vbus_irq(int irq, void *_dev)
-{
-       struct pxa25x_udc       *dev = _dev;
-
-       pxa25x_udc_vbus_session(&dev->gadget, is_vbus_present());
-       return IRQ_HANDLED;
-}
-
 
 /*-------------------------------------------------------------------------*/
 
@@ -1766,12 +1740,9 @@ pxa25x_udc_irq(int irq, void *_dev)
                if (unlikely(udccr & UDCCR_SUSIR)) {
                        udc_ack_int_UDCCR(UDCCR_SUSIR);
                        handled = 1;
-                       DBG(DBG_VERBOSE, "USB suspend%s\n", is_vbus_present()
-                               ? "" : "+disconnect");
+                       DBG(DBG_VERBOSE, "USB suspend\n");
 
-                       if (!is_vbus_present())
-                               stop_activity(dev, dev->driver);
-                       else if (dev->gadget.speed != USB_SPEED_UNKNOWN
+                       if (dev->gadget.speed != USB_SPEED_UNKNOWN
                                        && dev->driver
                                        && dev->driver->suspend)
                                dev->driver->suspend(&dev->gadget);
@@ -1786,8 +1757,7 @@ pxa25x_udc_irq(int irq, void *_dev)
 
                        if (dev->gadget.speed != USB_SPEED_UNKNOWN
                                        && dev->driver
-                                       && dev->driver->resume
-                                       && is_vbus_present())
+                                       && dev->driver->resume)
                                dev->driver->resume(&dev->gadget);
                }
 
@@ -2137,7 +2107,7 @@ static struct pxa25x_udc memory = {
 static int __init pxa25x_udc_probe(struct platform_device *pdev)
 {
        struct pxa25x_udc *dev = &memory;
-       int retval, vbus_irq, irq;
+       int retval, irq;
        u32 chiprev;
 
        /* insist on Intel/ARM/XScale */
@@ -2199,19 +2169,6 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev)
 
        dev->transceiver = otg_get_transceiver();
 
-       if (gpio_is_valid(dev->mach->gpio_vbus)) {
-               if ((retval = gpio_request(dev->mach->gpio_vbus,
-                               "pxa25x_udc GPIO VBUS"))) {
-                       dev_dbg(&pdev->dev,
-                               "can't get vbus gpio %d, err: %d\n",
-                               dev->mach->gpio_vbus, retval);
-                       goto err_gpio_vbus;
-               }
-               gpio_direction_input(dev->mach->gpio_vbus);
-               vbus_irq = gpio_to_irq(dev->mach->gpio_vbus);
-       } else
-               vbus_irq = 0;
-
        if (gpio_is_valid(dev->mach->gpio_pullup)) {
                if ((retval = gpio_request(dev->mach->gpio_pullup,
                                "pca25x_udc GPIO PULLUP"))) {
@@ -2237,7 +2194,7 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev)
        udc_disable(dev);
        udc_reinit(dev);
 
-       dev->vbus = !!is_vbus_present();
+       dev->vbus = 0;
 
        /* irq setup after old hardware state is cleaned up */
        retval = request_irq(irq, pxa25x_udc_irq,
@@ -2273,22 +2230,10 @@ lubbock_fail0:
                }
        } else
 #endif
-       if (vbus_irq) {
-               retval = request_irq(vbus_irq, udc_vbus_irq,
-                               IRQF_DISABLED | IRQF_SAMPLE_RANDOM |
-                               IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
-                               driver_name, dev);
-               if (retval != 0) {
-                       pr_err("%s: can't get irq %i, err %d\n",
-                               driver_name, vbus_irq, retval);
-                       goto err_vbus_irq;
-               }
-       }
        create_debug_files(dev);
 
        return 0;
 
- err_vbus_irq:
 #ifdef CONFIG_ARCH_LUBBOCK
        free_irq(LUBBOCK_USB_DISC_IRQ, dev);
  err_irq_lub:
@@ -2298,9 +2243,6 @@ lubbock_fail0:
        if (gpio_is_valid(dev->mach->gpio_pullup))
                gpio_free(dev->mach->gpio_pullup);
  err_gpio_pullup:
-       if (gpio_is_valid(dev->mach->gpio_vbus))
-               gpio_free(dev->mach->gpio_vbus);
- err_gpio_vbus:
        if (dev->transceiver) {
                otg_put_transceiver(dev->transceiver);
                dev->transceiver = NULL;
@@ -2337,10 +2279,6 @@ static int __exit pxa25x_udc_remove(struct platform_device *pdev)
                free_irq(LUBBOCK_USB_IRQ, dev);
        }
 #endif
-       if (gpio_is_valid(dev->mach->gpio_vbus)) {
-               free_irq(gpio_to_irq(dev->mach->gpio_vbus), dev);
-               gpio_free(dev->mach->gpio_vbus);
-       }
        if (gpio_is_valid(dev->mach->gpio_pullup))
                gpio_free(dev->mach->gpio_pullup);
 
index 825b665..a2e5b51 100644 (file)
@@ -627,7 +627,12 @@ static void overlay1fb_enable(struct pxafb_layer *ofb)
 
 static void overlay1fb_disable(struct pxafb_layer *ofb)
 {
-       uint32_t lccr5 = lcd_readl(ofb->fbi, LCCR5);
+       uint32_t lccr5;
+
+       if (!(lcd_readl(ofb->fbi, OVL1C1) & OVLxC1_OEN))
+               return;
+
+       lccr5 = lcd_readl(ofb->fbi, LCCR5);
 
        lcd_writel(ofb->fbi, OVL1C1, ofb->control[0] & ~OVLxC1_OEN);
 
@@ -685,7 +690,12 @@ static void overlay2fb_enable(struct pxafb_layer *ofb)
 
 static void overlay2fb_disable(struct pxafb_layer *ofb)
 {
-       uint32_t lccr5 = lcd_readl(ofb->fbi, LCCR5);
+       uint32_t lccr5;
+
+       if (!(lcd_readl(ofb->fbi, OVL2C1) & OVLxC1_OEN))
+               return;
+
+       lccr5 = lcd_readl(ofb->fbi, LCCR5);
 
        lcd_writel(ofb->fbi, OVL2C1, ofb->control[0] & ~OVLxC1_OEN);
 
@@ -720,12 +730,10 @@ static int overlayfb_open(struct fb_info *info, int user)
        if (user == 0)
                return -ENODEV;
 
-       /* allow only one user at a time */
-       if (atomic_inc_and_test(&ofb->usage))
-               return -EBUSY;
+       if (ofb->usage++ == 0)
+               /* unblank the base framebuffer */
+               fb_blank(&ofb->fbi->fb, FB_BLANK_UNBLANK);
 
-       /* unblank the base framebuffer */
-       fb_blank(&ofb->fbi->fb, FB_BLANK_UNBLANK);
        return 0;
 }
 
@@ -733,12 +741,15 @@ static int overlayfb_release(struct fb_info *info, int user)
 {
        struct pxafb_layer *ofb = (struct pxafb_layer*) info;
 
-       atomic_dec(&ofb->usage);
-       ofb->ops->disable(ofb);
+       if (ofb->usage == 1) {
+               ofb->ops->disable(ofb);
+               ofb->fb.var.height      = -1;
+               ofb->fb.var.width       = -1;
+               ofb->fb.var.xres = ofb->fb.var.xres_virtual = 0;
+               ofb->fb.var.yres = ofb->fb.var.yres_virtual = 0;
 
-       free_pages_exact(ofb->video_mem, ofb->video_mem_size);
-       ofb->video_mem = NULL;
-       ofb->video_mem_size = 0;
+               ofb->usage--;
+       }
        return 0;
 }
 
@@ -750,7 +761,7 @@ static int overlayfb_check_var(struct fb_var_screeninfo *var,
        int xpos, ypos, pfor, bpp;
 
        xpos = NONSTD_TO_XPOS(var->nonstd);
-       ypos = NONSTD_TO_XPOS(var->nonstd);
+       ypos = NONSTD_TO_YPOS(var->nonstd);
        pfor = NONSTD_TO_PFOR(var->nonstd);
 
        bpp = pxafb_var_to_bpp(var);
@@ -794,7 +805,7 @@ static int overlayfb_check_var(struct fb_var_screeninfo *var,
        return 0;
 }
 
-static int overlayfb_map_video_memory(struct pxafb_layer *ofb)
+static int overlayfb_check_video_memory(struct pxafb_layer *ofb)
 {
        struct fb_var_screeninfo *var = &ofb->fb.var;
        int pfor = NONSTD_TO_PFOR(var->nonstd);
@@ -812,27 +823,11 @@ static int overlayfb_map_video_memory(struct pxafb_layer *ofb)
 
        size = PAGE_ALIGN(ofb->fb.fix.line_length * var->yres_virtual);
 
-       /* don't re-allocate if the original video memory is enough */
        if (ofb->video_mem) {
                if (ofb->video_mem_size >= size)
                        return 0;
-
-               free_pages_exact(ofb->video_mem, ofb->video_mem_size);
        }
-
-       ofb->video_mem = alloc_pages_exact(size, GFP_KERNEL | __GFP_ZERO);
-       if (ofb->video_mem == NULL)
-               return -ENOMEM;
-
-       ofb->video_mem_phys = virt_to_phys(ofb->video_mem);
-       ofb->video_mem_size = size;
-
-       mutex_lock(&ofb->fb.mm_lock);
-       ofb->fb.fix.smem_start  = ofb->video_mem_phys;
-       ofb->fb.fix.smem_len    = ofb->fb.fix.line_length * var->yres_virtual;
-       mutex_unlock(&ofb->fb.mm_lock);
-       ofb->fb.screen_base     = ofb->video_mem;
-       return 0;
+       return -EINVAL;
 }
 
 static int overlayfb_set_par(struct fb_info *info)
@@ -841,13 +836,13 @@ static int overlayfb_set_par(struct fb_info *info)
        struct fb_var_screeninfo *var = &info->var;
        int xpos, ypos, pfor, bpp, ret;
 
-       ret = overlayfb_map_video_memory(ofb);
+       ret = overlayfb_check_video_memory(ofb);
        if (ret)
                return ret;
 
        bpp  = pxafb_var_to_bpp(var);
        xpos = NONSTD_TO_XPOS(var->nonstd);
-       ypos = NONSTD_TO_XPOS(var->nonstd);
+       ypos = NONSTD_TO_YPOS(var->nonstd);
        pfor = NONSTD_TO_PFOR(var->nonstd);
 
        ofb->control[0] = OVLxC1_PPL(var->xres) | OVLxC1_LPO(var->yres) |
@@ -891,7 +886,7 @@ static void __devinit init_pxafb_overlay(struct pxafb_info *fbi,
 
        ofb->id = id;
        ofb->ops = &ofb_ops[id];
-       atomic_set(&ofb->usage, 0);
+       ofb->usage = 0;
        ofb->fbi = fbi;
        init_completion(&ofb->branch_done);
 }
@@ -904,29 +899,60 @@ static inline int pxafb_overlay_supported(void)
        return 0;
 }
 
-static int __devinit pxafb_overlay_init(struct pxafb_info *fbi)
+static int __devinit pxafb_overlay_map_video_memory(struct pxafb_info *pxafb,
+       struct pxafb_layer *ofb)
+{
+       /* We assume that user will use at most video_mem_size for overlay fb,
+        * anyway, it's useless to use 16bpp main plane and 24bpp overlay
+        */
+       ofb->video_mem = alloc_pages_exact(PAGE_ALIGN(pxafb->video_mem_size),
+               GFP_KERNEL | __GFP_ZERO);
+       if (ofb->video_mem == NULL)
+               return -ENOMEM;
+
+       ofb->video_mem_phys = virt_to_phys(ofb->video_mem);
+       ofb->video_mem_size = PAGE_ALIGN(pxafb->video_mem_size);
+
+       mutex_lock(&ofb->fb.mm_lock);
+       ofb->fb.fix.smem_start  = ofb->video_mem_phys;
+       ofb->fb.fix.smem_len    = pxafb->video_mem_size;
+       mutex_unlock(&ofb->fb.mm_lock);
+
+       ofb->fb.screen_base     = ofb->video_mem;
+
+       return 0;
+}
+
+static void __devinit pxafb_overlay_init(struct pxafb_info *fbi)
 {
        int i, ret;
 
        if (!pxafb_overlay_supported())
-               return 0;
+               return;
 
        for (i = 0; i < 2; i++) {
-               init_pxafb_overlay(fbi, &fbi->overlay[i], i);
-               ret = register_framebuffer(&fbi->overlay[i].fb);
+               struct pxafb_layer *ofb = &fbi->overlay[i];
+               init_pxafb_overlay(fbi, ofb, i);
+               ret = register_framebuffer(&ofb->fb);
                if (ret) {
                        dev_err(fbi->dev, "failed to register overlay %d\n", i);
-                       return ret;
+                       continue;
                }
+               ret = pxafb_overlay_map_video_memory(fbi, ofb);
+               if (ret) {
+                       dev_err(fbi->dev,
+                               "failed to map video memory for overlay %d\n",
+                               i);
+                       unregister_framebuffer(&ofb->fb);
+                       continue;
+               }
+               ofb->registered = 1;
        }
 
        /* mask all IU/BS/EOF/SOF interrupts */
        lcd_writel(fbi, LCCR5, ~0);
 
-       /* place overlay(s) on top of base */
-       fbi->lccr0 |= LCCR0_OUC;
        pr_info("PXA Overlay driver loaded successfully!\n");
-       return 0;
 }
 
 static void __devexit pxafb_overlay_exit(struct pxafb_info *fbi)
@@ -936,8 +962,15 @@ static void __devexit pxafb_overlay_exit(struct pxafb_info *fbi)
        if (!pxafb_overlay_supported())
                return;
 
-       for (i = 0; i < 2; i++)
-               unregister_framebuffer(&fbi->overlay[i].fb);
+       for (i = 0; i < 2; i++) {
+               struct pxafb_layer *ofb = &fbi->overlay[i];
+               if (ofb->registered) {
+                       if (ofb->video_mem)
+                               free_pages_exact(ofb->video_mem,
+                                       ofb->video_mem_size);
+                       unregister_framebuffer(&ofb->fb);
+               }
+       }
 }
 #else
 static inline void pxafb_overlay_init(struct pxafb_info *fbi) {}
@@ -1368,7 +1401,8 @@ static int pxafb_activate_var(struct fb_var_screeninfo *var,
            (lcd_readl(fbi, LCCR3) != fbi->reg_lccr3) ||
            (lcd_readl(fbi, LCCR4) != fbi->reg_lccr4) ||
            (lcd_readl(fbi, FDADR0) != fbi->fdadr[0]) ||
-           (lcd_readl(fbi, FDADR1) != fbi->fdadr[1]))
+           ((fbi->lccr0 & LCCR0_SDS) &&
+           (lcd_readl(fbi, FDADR1) != fbi->fdadr[1])))
                pxafb_schedule_work(fbi, C_REENABLE);
 
        return 0;
@@ -1420,7 +1454,8 @@ static void pxafb_enable_controller(struct pxafb_info *fbi)
        lcd_writel(fbi, LCCR0, fbi->reg_lccr0 & ~LCCR0_ENB);
 
        lcd_writel(fbi, FDADR0, fbi->fdadr[0]);
-       lcd_writel(fbi, FDADR1, fbi->fdadr[1]);
+       if (fbi->lccr0 & LCCR0_SDS)
+               lcd_writel(fbi, FDADR1, fbi->fdadr[1]);
        lcd_writel(fbi, LCCR0, fbi->reg_lccr0 | LCCR0_ENB);
 }
 
@@ -1613,7 +1648,8 @@ pxafb_freq_transition(struct notifier_block *nb, unsigned long val, void *data)
 
        switch (val) {
        case CPUFREQ_PRECHANGE:
-               set_ctrlr_state(fbi, C_DISABLE_CLKCHANGE);
+               if (!fbi->overlay[0].usage && !fbi->overlay[1].usage)
+                       set_ctrlr_state(fbi, C_DISABLE_CLKCHANGE);
                break;
 
        case CPUFREQ_POSTCHANGE:
@@ -1806,6 +1842,12 @@ static struct pxafb_info * __devinit pxafb_init_fbinfo(struct device *dev)
 
        pxafb_decode_mach_info(fbi, inf);
 
+#ifdef CONFIG_FB_PXA_OVERLAY
+       /* place overlay(s) on top of base */
+       if (pxafb_overlay_supported())
+               fbi->lccr0 |= LCCR0_OUC;
+#endif
+
        init_waitqueue_head(&fbi->ctrlr_wait);
        INIT_WORK(&fbi->task, pxafb_task);
        mutex_init(&fbi->ctrlr_lock);
index 2353521..26ba9fa 100644 (file)
@@ -92,7 +92,8 @@ struct pxafb_layer_ops {
 struct pxafb_layer {
        struct fb_info          fb;
        int                     id;
-       atomic_t                usage;
+       int                     registered;
+       uint32_t                usage;
        uint32_t                control[2];
 
        struct pxafb_layer_ops  *ops;
index a1ee8fa..f60b07b 100644 (file)
@@ -3215,9 +3215,15 @@ void ceph_mdsc_destroy(struct ceph_fs_client *fsc)
 {
        struct ceph_mds_client *mdsc = fsc->mdsc;
 
+       dout("mdsc_destroy %p\n", mdsc);
        ceph_mdsc_stop(mdsc);
+
+       /* flush out any connection work with references to us */
+       ceph_msgr_flush();
+
        fsc->mdsc = NULL;
        kfree(mdsc);
+       dout("mdsc_destroy %p done\n", mdsc);
 }
 
 
index a9e78b4..f2f77fd 100644 (file)
@@ -353,7 +353,7 @@ static int ceph_show_options(struct seq_file *m, struct vfsmount *mnt)
 
        if (opt->name)
                seq_printf(m, ",name=%s", opt->name);
-       if (opt->secret)
+       if (opt->key)
                seq_puts(m, ",secret=<hidden>");
 
        if (opt->mount_timeout != CEPH_MOUNT_TIMEOUT_DEFAULT)
index 93589fc..397e732 100644 (file)
@@ -72,10 +72,9 @@ static int nilfs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
        /*
         * check to see if the page is mapped already (no holes)
         */
-       if (PageMappedToDisk(page)) {
-               unlock_page(page);
+       if (PageMappedToDisk(page))
                goto mapped;
-       }
+
        if (page_has_buffers(page)) {
                struct buffer_head *bh, *head;
                int fully_mapped = 1;
@@ -90,7 +89,6 @@ static int nilfs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
 
                if (fully_mapped) {
                        SetPageMappedToDisk(page);
-                       unlock_page(page);
                        goto mapped;
                }
        }
@@ -105,16 +103,17 @@ static int nilfs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
                return VM_FAULT_SIGBUS;
 
        ret = block_page_mkwrite(vma, vmf, nilfs_get_block);
-       if (unlikely(ret)) {
+       if (ret != VM_FAULT_LOCKED) {
                nilfs_transaction_abort(inode->i_sb);
                return ret;
        }
+       nilfs_set_file_dirty(inode, 1 << (PAGE_SHIFT - inode->i_blkbits));
        nilfs_transaction_commit(inode->i_sb);
 
  mapped:
        SetPageChecked(page);
        wait_on_page_writeback(page);
-       return 0;
+       return VM_FAULT_LOCKED;
 }
 
 static const struct vm_operations_struct nilfs_file_vm_ops = {
index 856e8e4..a8dd344 100644 (file)
@@ -114,19 +114,19 @@ enum {
  * Macros to check inode numbers
  */
 #define NILFS_MDT_INO_BITS   \
-  ((unsigned int)(1 << NILFS_DAT_INO | 1 << NILFS_CPFILE_INO |         \
-                 1 << NILFS_SUFILE_INO | 1 << NILFS_IFILE_INO |        \
-                 1 << NILFS_ATIME_INO | 1 << NILFS_SKETCH_INO))
+       ((unsigned int)(1 << NILFS_DAT_INO | 1 << NILFS_CPFILE_INO |    \
+                       1 << NILFS_SUFILE_INO | 1 << NILFS_IFILE_INO |  \
+                       1 << NILFS_ATIME_INO | 1 << NILFS_SKETCH_INO))
 
 #define NILFS_SYS_INO_BITS   \
-  ((unsigned int)(1 << NILFS_ROOT_INO) | NILFS_MDT_INO_BITS)
+       ((unsigned int)(1 << NILFS_ROOT_INO) | NILFS_MDT_INO_BITS)
 
 #define NILFS_FIRST_INO(sb) (((struct the_nilfs *)sb->s_fs_info)->ns_first_ino)
 
 #define NILFS_MDT_INODE(sb, ino) \
-  ((ino) < NILFS_FIRST_INO(sb) && (NILFS_MDT_INO_BITS & (1 << (ino))))
+       ((ino) < NILFS_FIRST_INO(sb) && (NILFS_MDT_INO_BITS & (1 << (ino))))
 #define NILFS_VALID_INODE(sb, ino) \
-  ((ino) >= NILFS_FIRST_INO(sb) || (NILFS_SYS_INO_BITS & (1 << (ino))))
+       ((ino) >= NILFS_FIRST_INO(sb) || (NILFS_SYS_INO_BITS & (1 << (ino))))
 
 /**
  * struct nilfs_transaction_info: context information for synchronization
@@ -285,7 +285,7 @@ extern void nilfs_destroy_inode(struct inode *);
 extern void nilfs_error(struct super_block *, const char *, const char *, ...)
        __attribute__ ((format (printf, 3, 4)));
 extern void nilfs_warning(struct super_block *, const char *, const char *, ...)
-       __attribute__ ((format (printf, 3, 4)));
+       __attribute__ ((format (printf, 3, 4)));
 extern struct nilfs_super_block *
 nilfs_read_super_block(struct super_block *, u64, int, struct buffer_head **);
 extern int nilfs_store_magic_and_option(struct super_block *,
index 4d2a1ee..9d2dc6b 100644 (file)
@@ -495,12 +495,14 @@ unsigned nilfs_page_count_clean_buffers(struct page *page,
 void nilfs_mapping_init(struct address_space *mapping,
                        struct backing_dev_info *bdi)
 {
+       static const struct address_space_operations empty_aops;
+
        mapping->host = NULL;
        mapping->flags = 0;
        mapping_set_gfp_mask(mapping, GFP_NOFS);
        mapping->assoc_mapping = NULL;
        mapping->backing_dev_info = bdi;
-       mapping->a_ops = NULL;
+       mapping->a_ops = &empty_aops;
 }
 
 /*
diff --git a/include/keys/ceph-type.h b/include/keys/ceph-type.h
new file mode 100644 (file)
index 0000000..f69c4ac
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef _KEYS_CEPH_TYPE_H
+#define _KEYS_CEPH_TYPE_H
+
+#include <linux/key.h>
+
+extern struct key_type key_type_ceph;
+
+#endif
index 475f8c4..381f4ce 100644 (file)
@@ -443,6 +443,7 @@ void atm_dev_signal_change(struct atm_dev *dev, char signal);
 
 void vcc_insert_socket(struct sock *sk);
 
+void atm_dev_release_vccs(struct atm_dev *dev);
 
 /*
  * This is approximately the algorithm used by alloc_skb.
index 7fff521..aa13392 100644 (file)
@@ -67,12 +67,12 @@ struct ceph_auth_client {
        bool negotiating;       /* true if negotiating protocol */
        const char *name;       /* entity name */
        u64 global_id;          /* our unique id in system */
-       const char *secret;     /* our secret key */
+       const struct ceph_crypto_key *key;     /* our secret key */
        unsigned want_keys;     /* which services we want */
 };
 
 extern struct ceph_auth_client *ceph_auth_init(const char *name,
-                                              const char *secret);
+                                              const struct ceph_crypto_key *key);
 extern void ceph_auth_destroy(struct ceph_auth_client *ac);
 
 extern void ceph_auth_reset(struct ceph_auth_client *ac);
index 0d2e0ff..6365f04 100644 (file)
@@ -61,7 +61,7 @@ struct ceph_options {
                                              pointer type of args */
        int num_mon;
        char *name;
-       char *secret;
+       struct ceph_crypto_key *key;
 };
 
 /*
index bcafc94..7c60d09 100644 (file)
@@ -88,8 +88,6 @@ struct cn_queue_dev {
        atomic_t refcnt;
        unsigned char name[CN_CBQ_NAMELEN];
 
-       struct workqueue_struct *cn_queue;
-
        struct list_head queue_list;
        spinlock_t queue_lock;
 
@@ -101,20 +99,13 @@ struct cn_callback_id {
        struct cb_id id;
 };
 
-struct cn_callback_data {
-       struct sk_buff *skb;
-       void (*callback) (struct cn_msg *, struct netlink_skb_parms *);
-
-       void *free;
-};
-
 struct cn_callback_entry {
        struct list_head callback_entry;
-       struct work_struct work;
+       atomic_t refcnt;
        struct cn_queue_dev *pdev;
 
        struct cn_callback_id id;
-       struct cn_callback_data data;
+       void (*callback) (struct cn_msg *, struct netlink_skb_parms *);
 
        u32 seq, group;
 };
@@ -138,13 +129,12 @@ int cn_queue_add_callback(struct cn_queue_dev *dev, const char *name,
                          struct cb_id *id,
                          void (*callback)(struct cn_msg *, struct netlink_skb_parms *));
 void cn_queue_del_callback(struct cn_queue_dev *dev, struct cb_id *id);
+void cn_queue_release_callback(struct cn_callback_entry *);
 
 struct cn_queue_dev *cn_queue_alloc_dev(const char *name, struct sock *);
 void cn_queue_free_dev(struct cn_queue_dev *dev);
 
 int cn_cb_equal(struct cb_id *, struct cb_id *);
 
-void cn_queue_wrapper(struct work_struct *work);
-
 #endif                         /* __KERNEL__ */
 #endif                         /* __CONNECTOR_H */
index 59b72ca..943c9b5 100644 (file)
@@ -338,14 +338,6 @@ static inline void enable_irq_lockdep_irqrestore(unsigned int irq, unsigned long
 /* IRQ wakeup (PM) control: */
 extern int irq_set_irq_wake(unsigned int irq, unsigned int on);
 
-#ifndef CONFIG_GENERIC_HARDIRQS_NO_COMPAT
-/* Please do not use: Use the replacement functions instead */
-static inline int set_irq_wake(unsigned int irq, unsigned int on)
-{
-       return irq_set_irq_wake(irq, on);
-}
-#endif
-
 static inline int enable_irq_wake(unsigned int irq)
 {
        return irq_set_irq_wake(irq, 1);
index 2a375a7..09a3080 100644 (file)
@@ -64,13 +64,6 @@ typedef      void (*irq_preflow_handler_t)(struct irq_data *data);
  * IRQ_NO_BALANCING            - Interrupt cannot be balanced (affinity set)
  * IRQ_MOVE_PCNTXT             - Interrupt can be migrated from process context
  * IRQ_NESTED_TRHEAD           - Interrupt nests into another thread
- *
- * Deprecated bits. They are kept updated as long as
- * CONFIG_GENERIC_HARDIRQS_NO_COMPAT is not set. Will go away soon. These bits
- * are internal state of the core code and if you really need to acces
- * them then talk to the genirq maintainer instead of hacking
- * something weird.
- *
  */
 enum {
        IRQ_TYPE_NONE           = 0x00000000,
index 239083b..d9e52fa 100644 (file)
@@ -126,7 +126,7 @@ struct sk_buff;
  * GRO uses frags we allocate at least 16 regardless of page size.
  */
 #if (65536/PAGE_SIZE + 2) < 16
-#define MAX_SKB_FRAGS 16
+#define MAX_SKB_FRAGS 16UL
 #else
 #define MAX_SKB_FRAGS (65536/PAGE_SIZE + 2)
 #endif
index 44842c8..201f222 100644 (file)
@@ -102,6 +102,7 @@ struct driver_info {
  * Affects statistic (counters) and short packet handling.
  */
 #define FLAG_MULTI_PACKET      0x1000
+#define FLAG_RX_ASSEMBLE       0x2000  /* rx packets may span >1 frames */
 
        /* init device ... can sleep, or cause probe() failure */
        int     (*bind)(struct usbnet *, struct usb_interface *);
@@ -172,7 +173,9 @@ struct cdc_state {
 };
 
 extern int usbnet_generic_cdc_bind(struct usbnet *, struct usb_interface *);
+extern int usbnet_cdc_bind(struct usbnet *, struct usb_interface *);
 extern void usbnet_cdc_unbind(struct usbnet *, struct usb_interface *);
+extern void usbnet_cdc_status(struct usbnet *, struct urb *);
 
 /* CDC and RNDIS support the same host-chosen packet filters for IN transfers */
 #define        DEFAULT_FILTER  (USB_CDC_PACKET_TYPE_BROADCAST \
index 04977ee..fccc218 100644 (file)
@@ -286,5 +286,21 @@ static inline void ipv6_ib_mc_map(const struct in6_addr *addr,
        buf[9]  = broadcast[9];
        memcpy(buf + 10, addr->s6_addr + 6, 10);
 }
+
+static inline int ipv6_ipgre_mc_map(const struct in6_addr *addr,
+                                   const unsigned char *broadcast, char *buf)
+{
+       if ((broadcast[0] | broadcast[1] | broadcast[2] | broadcast[3]) != 0) {
+               memcpy(buf, broadcast, 4);
+       } else {
+               /* v4mapped? */
+               if ((addr->s6_addr32[0] | addr->s6_addr32[1] |
+                    (addr->s6_addr32[2] ^ htonl(0x0000ffff))) != 0)
+                       return -EINVAL;
+               memcpy(buf, &addr->s6_addr32[3], 4);
+       }
+       return 0;
+}
+
 #endif
 #endif
index a4f6311..7c41658 100644 (file)
@@ -339,6 +339,14 @@ static inline void ip_ib_mc_map(__be32 naddr, const unsigned char *broadcast, ch
        buf[16] = addr & 0x0f;
 }
 
+static inline void ip_ipgre_mc_map(__be32 naddr, const unsigned char *broadcast, char *buf)
+{
+       if ((broadcast[0] | broadcast[1] | broadcast[2] | broadcast[3]) != 0)
+               memcpy(buf, broadcast, 4);
+       else
+               memcpy(buf, &naddr, sizeof(naddr));
+}
+
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 #include <linux/ipv6.h>
 #endif
index a69c333..c574f9a 100644 (file)
@@ -10,9 +10,6 @@ menu "IRQ subsystem"
 config GENERIC_HARDIRQS
        def_bool y
 
-config GENERIC_HARDIRQS_NO_COMPAT
-       bool
-
 # Options selectable by the architecture code
 
 # Make sparse irq Kconfig switch below available
index 616ec1c..1dafc86 100644 (file)
@@ -514,7 +514,7 @@ void handle_edge_eoi_irq(unsigned int irq, struct irq_desc *desc)
        } while ((desc->istate & IRQS_PENDING) &&
                 !irqd_irq_disabled(&desc->irq_data));
 
-out_unlock:
+out_eoi:
        chip->irq_eoi(&desc->irq_data);
        raw_spin_unlock(&desc->lock);
 }
index 206e771..956a530 100644 (file)
@@ -1051,16 +1051,17 @@ static int atalk_release(struct socket *sock)
 {
        struct sock *sk = sock->sk;
 
-       sock_hold(sk);
-       lock_sock(sk);
        if (sk) {
+               sock_hold(sk);
+               lock_sock(sk);
+
                sock_orphan(sk);
                sock->sk = NULL;
                atalk_destroy_socket(sk);
-       }
-       release_sock(sk);
-       sock_put(sk);
 
+               release_sock(sk);
+               sock_put(sk);
+       }
        return 0;
 }
 
index 1b9c52a..22b963d 100644 (file)
@@ -252,6 +252,7 @@ void atm_dev_release_vccs(struct atm_dev *dev)
        }
        write_unlock_irq(&vcc_sklist_lock);
 }
+EXPORT_SYMBOL(atm_dev_release_vccs);
 
 static int adjust_tp(struct atm_trafprm *tp, unsigned char aal)
 {
index f61eb2e..59660c9 100644 (file)
@@ -1475,7 +1475,7 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br,
            ip6h->payload_len == 0)
                return 0;
 
-       len = ntohs(ip6h->payload_len);
+       len = ntohs(ip6h->payload_len) + sizeof(*ip6h);
        if (skb->len < len)
                return -EINVAL;
 
index 5593f5a..9b61d09 100644 (file)
@@ -213,7 +213,7 @@ bool br_stp_recalculate_bridge_id(struct net_bridge *br)
 
        /* user has chosen a value so keep it */
        if (br->flags & BR_SET_MAC_ADDR)
-               return;
+               return false;
 
        list_for_each_entry(p, &br->port_list, list) {
                if (addr == br_mac_zero ||
index ad42404..be683f2 100644 (file)
@@ -4,6 +4,7 @@ config CEPH_LIB
        select LIBCRC32C
        select CRYPTO_AES
        select CRYPTO
+       select KEYS
        default n
        help
          Choose Y or M here to include cephlib, which provides the
index 549c1f4..b4bf4ac 100644 (file)
@@ -35,12 +35,12 @@ static int ceph_auth_init_protocol(struct ceph_auth_client *ac, int protocol)
 /*
  * setup, teardown.
  */
-struct ceph_auth_client *ceph_auth_init(const char *name, const char *secret)
+struct ceph_auth_client *ceph_auth_init(const char *name, const struct ceph_crypto_key *key)
 {
        struct ceph_auth_client *ac;
        int ret;
 
-       dout("auth_init name '%s' secret '%s'\n", name, secret);
+       dout("auth_init name '%s'\n", name);
 
        ret = -ENOMEM;
        ac = kzalloc(sizeof(*ac), GFP_NOFS);
@@ -52,8 +52,8 @@ struct ceph_auth_client *ceph_auth_init(const char *name, const char *secret)
                ac->name = name;
        else
                ac->name = CEPH_AUTH_NAME_DEFAULT;
-       dout("auth_init name %s secret %s\n", ac->name, secret);
-       ac->secret = secret;
+       dout("auth_init name %s\n", ac->name);
+       ac->key = key;
        return ac;
 
 out:
index 7fd5dfc..1587dc6 100644 (file)
@@ -662,14 +662,16 @@ int ceph_x_init(struct ceph_auth_client *ac)
                goto out;
 
        ret = -EINVAL;
-       if (!ac->secret) {
+       if (!ac->key) {
                pr_err("no secret set (for auth_x protocol)\n");
                goto out_nomem;
        }
 
-       ret = ceph_crypto_key_unarmor(&xi->secret, ac->secret);
-       if (ret)
+       ret = ceph_crypto_key_clone(&xi->secret, ac->key);
+       if (ret < 0) {
+               pr_err("cannot clone key: %d\n", ret);
                goto out_nomem;
+       }
 
        xi->starting = true;
        xi->ticket_handlers = RB_ROOT;
index 95f96ab..132963a 100644 (file)
@@ -5,6 +5,8 @@
 #include <linux/fs.h>
 #include <linux/inet.h>
 #include <linux/in6.h>
+#include <linux/key.h>
+#include <keys/ceph-type.h>
 #include <linux/module.h>
 #include <linux/mount.h>
 #include <linux/parser.h>
@@ -20,6 +22,7 @@
 #include <linux/ceph/decode.h>
 #include <linux/ceph/mon_client.h>
 #include <linux/ceph/auth.h>
+#include "crypto.h"
 
 
 
@@ -117,9 +120,29 @@ int ceph_compare_options(struct ceph_options *new_opt,
        if (ret)
                return ret;
 
-       ret = strcmp_null(opt1->secret, opt2->secret);
-       if (ret)
-               return ret;
+       if (opt1->key && !opt2->key)
+               return -1;
+       if (!opt1->key && opt2->key)
+               return 1;
+       if (opt1->key && opt2->key) {
+               if (opt1->key->type != opt2->key->type)
+                       return -1;
+               if (opt1->key->created.tv_sec != opt2->key->created.tv_sec)
+                       return -1;
+               if (opt1->key->created.tv_nsec != opt2->key->created.tv_nsec)
+                       return -1;
+               if (opt1->key->len != opt2->key->len)
+                       return -1;
+               if (opt1->key->key && !opt2->key->key)
+                       return -1;
+               if (!opt1->key->key && opt2->key->key)
+                       return 1;
+               if (opt1->key->key && opt2->key->key) {
+                       ret = memcmp(opt1->key->key, opt2->key->key, opt1->key->len);
+                       if (ret)
+                               return ret;
+               }
+       }
 
        /* any matching mon ip implies a match */
        for (i = 0; i < opt1->num_mon; i++) {
@@ -176,6 +199,7 @@ enum {
        Opt_fsid,
        Opt_name,
        Opt_secret,
+       Opt_key,
        Opt_ip,
        Opt_last_string,
        /* string args above */
@@ -192,6 +216,7 @@ static match_table_t opt_tokens = {
        {Opt_fsid, "fsid=%s"},
        {Opt_name, "name=%s"},
        {Opt_secret, "secret=%s"},
+       {Opt_key, "key=%s"},
        {Opt_ip, "ip=%s"},
        /* string args above */
        {Opt_noshare, "noshare"},
@@ -203,11 +228,56 @@ void ceph_destroy_options(struct ceph_options *opt)
 {
        dout("destroy_options %p\n", opt);
        kfree(opt->name);
-       kfree(opt->secret);
+       if (opt->key) {
+               ceph_crypto_key_destroy(opt->key);
+               kfree(opt->key);
+       }
        kfree(opt);
 }
 EXPORT_SYMBOL(ceph_destroy_options);
 
+/* get secret from key store */
+static int get_secret(struct ceph_crypto_key *dst, const char *name) {
+       struct key *ukey;
+       int key_err;
+       int err = 0;
+       struct ceph_crypto_key *ckey;
+
+       ukey = request_key(&key_type_ceph, name, NULL);
+       if (!ukey || IS_ERR(ukey)) {
+               /* request_key errors don't map nicely to mount(2)
+                  errors; don't even try, but still printk */
+               key_err = PTR_ERR(ukey);
+               switch (key_err) {
+               case -ENOKEY:
+                       pr_warning("ceph: Mount failed due to key not found: %s\n", name);
+                       break;
+               case -EKEYEXPIRED:
+                       pr_warning("ceph: Mount failed due to expired key: %s\n", name);
+                       break;
+               case -EKEYREVOKED:
+                       pr_warning("ceph: Mount failed due to revoked key: %s\n", name);
+                       break;
+               default:
+                       pr_warning("ceph: Mount failed due to unknown key error"
+                              " %d: %s\n", key_err, name);
+               }
+               err = -EPERM;
+               goto out;
+       }
+
+       ckey = ukey->payload.data;
+       err = ceph_crypto_key_clone(dst, ckey);
+       if (err)
+               goto out_key;
+       /* pass through, err is 0 */
+
+out_key:
+       key_put(ukey);
+out:
+       return err;
+}
+
 int ceph_parse_options(struct ceph_options **popt, char *options,
                       const char *dev_name, const char *dev_name_end,
                       int (*parse_extra_token)(char *c, void *private),
@@ -295,9 +365,24 @@ int ceph_parse_options(struct ceph_options **popt, char *options,
                                              GFP_KERNEL);
                        break;
                case Opt_secret:
-                       opt->secret = kstrndup(argstr[0].from,
-                                               argstr[0].to-argstr[0].from,
-                                               GFP_KERNEL);
+                       opt->key = kzalloc(sizeof(*opt->key), GFP_KERNEL);
+                       if (!opt->key) {
+                               err = -ENOMEM;
+                               goto out;
+                       }
+                       err = ceph_crypto_key_unarmor(opt->key, argstr[0].from);
+                       if (err < 0)
+                               goto out;
+                       break;
+               case Opt_key:
+                       opt->key = kzalloc(sizeof(*opt->key), GFP_KERNEL);
+                       if (!opt->key) {
+                               err = -ENOMEM;
+                               goto out;
+                       }
+                       err = get_secret(opt->key, argstr[0].from);
+                       if (err < 0)
+                               goto out;
                        break;
 
                        /* misc */
@@ -394,8 +479,8 @@ void ceph_destroy_client(struct ceph_client *client)
        ceph_osdc_stop(&client->osdc);
 
        /*
-        * make sure mds and osd connections close out before destroying
-        * the auth module, which is needed to free those connections'
+        * make sure osd connections close out before destroying the
+        * auth module, which is needed to free those connections'
         * ceph_authorizers.
         */
        ceph_msgr_flush();
@@ -496,10 +581,14 @@ static int __init init_ceph_lib(void)
        if (ret < 0)
                goto out;
 
-       ret = ceph_msgr_init();
+       ret = ceph_crypto_init();
        if (ret < 0)
                goto out_debugfs;
 
+       ret = ceph_msgr_init();
+       if (ret < 0)
+               goto out_crypto;
+
        pr_info("loaded (mon/osd proto %d/%d, osdmap %d/%d %d/%d)\n",
                CEPH_MONC_PROTOCOL, CEPH_OSDC_PROTOCOL,
                CEPH_OSDMAP_VERSION, CEPH_OSDMAP_VERSION_EXT,
@@ -507,6 +596,8 @@ static int __init init_ceph_lib(void)
 
        return 0;
 
+out_crypto:
+       ceph_crypto_shutdown();
 out_debugfs:
        ceph_debugfs_cleanup();
 out:
@@ -517,6 +608,7 @@ static void __exit exit_ceph_lib(void)
 {
        dout("exit_ceph_lib\n");
        ceph_msgr_exit();
+       ceph_crypto_shutdown();
        ceph_debugfs_cleanup();
 }
 
index 7b505b0..5a8009c 100644 (file)
@@ -5,10 +5,23 @@
 #include <linux/scatterlist.h>
 #include <linux/slab.h>
 #include <crypto/hash.h>
+#include <linux/key-type.h>
 
+#include <keys/ceph-type.h>
 #include <linux/ceph/decode.h>
 #include "crypto.h"
 
+int ceph_crypto_key_clone(struct ceph_crypto_key *dst,
+                         const struct ceph_crypto_key *src)
+{
+       memcpy(dst, src, sizeof(struct ceph_crypto_key));
+       dst->key = kmalloc(src->len, GFP_NOFS);
+       if (!dst->key)
+               return -ENOMEM;
+       memcpy(dst->key, src->key, src->len);
+       return 0;
+}
+
 int ceph_crypto_key_encode(struct ceph_crypto_key *key, void **p, void *end)
 {
        if (*p + sizeof(u16) + sizeof(key->created) +
@@ -410,3 +423,63 @@ int ceph_encrypt2(struct ceph_crypto_key *secret, void *dst, size_t *dst_len,
                return -EINVAL;
        }
 }
+
+int ceph_key_instantiate(struct key *key, const void *data, size_t datalen)
+{
+       struct ceph_crypto_key *ckey;
+       int ret;
+       void *p;
+
+       ret = -EINVAL;
+       if (datalen <= 0 || datalen > 32767 || !data)
+               goto err;
+
+       ret = key_payload_reserve(key, datalen);
+       if (ret < 0)
+               goto err;
+
+       ret = -ENOMEM;
+       ckey = kmalloc(sizeof(*ckey), GFP_KERNEL);
+       if (!ckey)
+               goto err;
+
+       /* TODO ceph_crypto_key_decode should really take const input */
+       p = (void*)data;
+       ret = ceph_crypto_key_decode(ckey, &p, (char*)data+datalen);
+       if (ret < 0)
+               goto err_ckey;
+
+       key->payload.data = ckey;
+       return 0;
+
+err_ckey:
+       kfree(ckey);
+err:
+       return ret;
+}
+
+int ceph_key_match(const struct key *key, const void *description)
+{
+       return strcmp(key->description, description) == 0;
+}
+
+void ceph_key_destroy(struct key *key) {
+       struct ceph_crypto_key *ckey = key->payload.data;
+
+       ceph_crypto_key_destroy(ckey);
+}
+
+struct key_type key_type_ceph = {
+       .name           = "ceph",
+       .instantiate    = ceph_key_instantiate,
+       .match          = ceph_key_match,
+       .destroy        = ceph_key_destroy,
+};
+
+int ceph_crypto_init(void) {
+       return register_key_type(&key_type_ceph);
+}
+
+void ceph_crypto_shutdown(void) {
+       unregister_key_type(&key_type_ceph);
+}
index f9eccac..1919d15 100644 (file)
@@ -19,6 +19,8 @@ static inline void ceph_crypto_key_destroy(struct ceph_crypto_key *key)
        kfree(key->key);
 }
 
+extern int ceph_crypto_key_clone(struct ceph_crypto_key *dst,
+                                const struct ceph_crypto_key *src);
 extern int ceph_crypto_key_encode(struct ceph_crypto_key *key,
                                  void **p, void *end);
 extern int ceph_crypto_key_decode(struct ceph_crypto_key *key,
@@ -40,6 +42,8 @@ extern int ceph_encrypt2(struct ceph_crypto_key *secret,
                         void *dst, size_t *dst_len,
                         const void *src1, size_t src1_len,
                         const void *src2, size_t src2_len);
+extern int ceph_crypto_init(void);
+extern void ceph_crypto_shutdown(void);
 
 /* armor.c */
 extern int ceph_armor(char *dst, const char *src, const char *end);
index 8a07939..cbe31fa 100644 (file)
@@ -759,7 +759,7 @@ int ceph_monc_init(struct ceph_mon_client *monc, struct ceph_client *cl)
 
        /* authentication */
        monc->auth = ceph_auth_init(cl->options->name,
-                                   cl->options->secret);
+                                   cl->options->key);
        if (IS_ERR(monc->auth))
                return PTR_ERR(monc->auth);
        monc->auth->want_keys =
index 02212ed..3b91d65 100644 (file)
@@ -837,8 +837,7 @@ static void __unregister_request(struct ceph_osd_client *osdc,
                        dout("moving osd to %p lru\n", req->r_osd);
                        __move_osd_to_lru(osdc, req->r_osd);
                }
-               if (list_empty(&req->r_osd_item) &&
-                   list_empty(&req->r_linger_item))
+               if (list_empty(&req->r_linger_item))
                        req->r_osd = NULL;
        }
 
@@ -883,7 +882,8 @@ static void __unregister_linger_request(struct ceph_osd_client *osdc,
                        dout("moving osd to %p lru\n", req->r_osd);
                        __move_osd_to_lru(osdc, req->r_osd);
                }
-               req->r_osd = NULL;
+               if (list_empty(&req->r_osd_item))
+                       req->r_osd = NULL;
        }
 }
 
@@ -1602,11 +1602,11 @@ void handle_watch_notify(struct ceph_osd_client *osdc, struct ceph_msg *msg)
             cookie, ver, event);
        if (event) {
                event_work = kmalloc(sizeof(*event_work), GFP_NOIO);
-               INIT_WORK(&event_work->work, do_event_work);
                if (!event_work) {
                        dout("ERROR: could not allocate event_work\n");
                        goto done_err;
                }
+               INIT_WORK(&event_work->work, do_event_work);
                event_work->event = event;
                event_work->ver = ver;
                event_work->notify_id = notify_id;
@@ -1672,7 +1672,7 @@ int ceph_osdc_start_request(struct ceph_osd_client *osdc,
        if (req->r_sent == 0) {
                rc = __map_request(osdc, req);
                if (rc < 0)
-                       return rc;
+                       goto out_unlock;
                if (req->r_osd == NULL) {
                        dout("send_request %p no up osds in pg\n", req);
                        ceph_monc_request_next_osdmap(&osdc->client->monc);
@@ -1689,6 +1689,8 @@ int ceph_osdc_start_request(struct ceph_osd_client *osdc,
                        }
                }
        }
+
+out_unlock:
        mutex_unlock(&osdc->request_mutex);
        up_read(&osdc->map_sem);
        return rc;
index 563ddc2..3da9fb0 100644 (file)
@@ -1454,6 +1454,27 @@ static inline void net_timestamp_check(struct sk_buff *skb)
                __net_timestamp(skb);
 }
 
+static inline bool is_skb_forwardable(struct net_device *dev,
+                                     struct sk_buff *skb)
+{
+       unsigned int len;
+
+       if (!(dev->flags & IFF_UP))
+               return false;
+
+       len = dev->mtu + dev->hard_header_len + VLAN_HLEN;
+       if (skb->len <= len)
+               return true;
+
+       /* if TSO is enabled, we don't care about the length as the packet
+        * could be forwarded without being segmented before
+        */
+       if (skb_is_gso(skb))
+               return true;
+
+       return false;
+}
+
 /**
  * dev_forward_skb - loopback an skb to another netif
  *
@@ -1477,8 +1498,7 @@ int dev_forward_skb(struct net_device *dev, struct sk_buff *skb)
        skb_orphan(skb);
        nf_reset(skb);
 
-       if (unlikely(!(dev->flags & IFF_UP) ||
-                    (skb->len > (dev->mtu + dev->hard_header_len + VLAN_HLEN)))) {
+       if (unlikely(!is_skb_forwardable(dev, skb))) {
                atomic_long_inc(&dev->rx_dropped);
                kfree_skb(skb);
                return NET_RX_DROP;
index 090d273..1b74d3b 100644 (file)
@@ -215,6 +215,9 @@ int arp_mc_map(__be32 addr, u8 *haddr, struct net_device *dev, int dir)
        case ARPHRD_INFINIBAND:
                ip_ib_mc_map(addr, dev->broadcast, haddr);
                return 0;
+       case ARPHRD_IPGRE:
+               ip_ipgre_mc_map(addr, dev->broadcast, haddr);
+               return 0;
        default:
                if (dir) {
                        memcpy(haddr, dev->broadcast, dev->addr_len);
index f116ce8..4510883 100644 (file)
@@ -1068,6 +1068,7 @@ static void ip_fib_net_exit(struct net *net)
        fib4_rules_exit(net);
 #endif
 
+       rtnl_lock();
        for (i = 0; i < FIB_TABLE_HASHSZ; i++) {
                struct fib_table *tb;
                struct hlist_head *head;
@@ -1080,6 +1081,7 @@ static void ip_fib_net_exit(struct net *net)
                        fib_free_table(tb);
                }
        }
+       rtnl_unlock();
        kfree(net->ipv4.fib_table_hash);
 }
 
index 0e49c9d..92f952d 100644 (file)
@@ -341,6 +341,8 @@ int ndisc_mc_map(struct in6_addr *addr, char *buf, struct net_device *dev, int d
        case ARPHRD_INFINIBAND:
                ipv6_ib_mc_map(addr, dev->broadcast, buf);
                return 0;
+       case ARPHRD_IPGRE:
+               return ipv6_ipgre_mc_map(addr, dev->broadcast, buf);
        default:
                if (dir) {
                        memcpy(buf, dev->broadcast, dev->addr_len);
index 152976e..d5bf91d 100644 (file)
@@ -1205,7 +1205,7 @@ SCTP_STATIC __init int sctp_init(void)
                if ((sctp_assoc_hashsize > (64 * 1024)) && order > 0)
                        continue;
                sctp_assoc_hashtable = (struct sctp_hashbucket *)
-                                       __get_free_pages(GFP_ATOMIC, order);
+                       __get_free_pages(GFP_ATOMIC|__GFP_NOWARN, order);
        } while (!sctp_assoc_hashtable && --order > 0);
        if (!sctp_assoc_hashtable) {
                pr_err("Failed association hash alloc\n");
@@ -1238,7 +1238,7 @@ SCTP_STATIC __init int sctp_init(void)
                if ((sctp_port_hashsize > (64 * 1024)) && order > 0)
                        continue;
                sctp_port_hashtable = (struct sctp_bind_hashbucket *)
-                                       __get_free_pages(GFP_ATOMIC, order);
+                       __get_free_pages(GFP_ATOMIC|__GFP_NOWARN, order);
        } while (!sctp_port_hashtable && --order > 0);
        if (!sctp_port_hashtable) {
                pr_err("Failed bind hash alloc\n");
index fcab80b..fc017c0 100644 (file)
@@ -331,7 +331,7 @@ int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count,
                        goto err;
 
                if (gpios[i].wake) {
-                       ret = set_irq_wake(gpio_to_irq(gpios[i].gpio), 1);
+                       ret = irq_set_irq_wake(gpio_to_irq(gpios[i].gpio), 1);
                        if (ret != 0)
                                printk(KERN_ERR
                                  "Failed to mark GPIO %d as wake source: %d\n",