Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/geert/linux...
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 3 Apr 2012 17:07:13 +0000 (10:07 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 3 Apr 2012 17:07:13 +0000 (10:07 -0700)
Pull m68k fixes from Geert Uytterhoeven:
 "Here are a few fixes for the m68k architecture.  Nothing fancy this
  time, just a build fix for the asm/system.h disintegration, and two
  fixes for missing platform checks (one got in during last merge
  window), which can cause crashes in multi-platform kernels."

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/geert/linux-m68k:
  m68k/q40: Add missing platform check before registering platform devices
  m68k/mac: Add missing platform check before registering platform devices
  m68k: include asm/cmpxchg.h in our m68k atomic.h

174 files changed:
Documentation/DocBook/device-drivers.tmpl
Documentation/cgroups/cpusets.txt
Documentation/cpu-hotplug.txt
Documentation/ioctl/ioctl-number.txt
MAINTAINERS
arch/alpha/kernel/smp.c
arch/arm/kernel/kprobes.c
arch/arm/kernel/smp.c
arch/arm/mach-msm/include/mach/uncompress.h
arch/avr32/mach-at32ap/include/mach/board.h
arch/blackfin/include/asm/cmpxchg.h
arch/frv/mb93090-mb00/pci-dma.c
arch/hexagon/kernel/smp.c
arch/ia64/kernel/acpi.c
arch/mips/cavium-octeon/smp.c
arch/mips/kernel/mips-mt-fpaff.c
arch/mips/kernel/proc.c
arch/mips/kernel/smp-bmips.c
arch/mips/kernel/smp.c
arch/mips/kernel/smtc.c
arch/mips/mm/c-octeon.c
arch/mips/netlogic/common/smp.c
arch/mips/pmc-sierra/yosemite/smp.c
arch/mips/sgi-ip27/ip27-smp.c
arch/mips/sibyte/bcm1480/smp.c
arch/mips/sibyte/sb1250/smp.c
arch/parisc/include/asm/atomic.h
arch/parisc/include/asm/cmpxchg.h [new file with mode: 0644]
arch/powerpc/boot/dts/p1020mbg-pc.dtsi [new file with mode: 0644]
arch/powerpc/boot/dts/p1020mbg-pc_32b.dts [new file with mode: 0644]
arch/powerpc/boot/dts/p1020mbg-pc_36b.dts [new file with mode: 0644]
arch/powerpc/boot/dts/p1020utm-pc.dtsi [new file with mode: 0644]
arch/powerpc/boot/dts/p1020utm-pc_32b.dts [new file with mode: 0644]
arch/powerpc/boot/dts/p1020utm-pc_36b.dts [new file with mode: 0644]
arch/powerpc/boot/dts/p2041rdb.dts
arch/powerpc/boot/dts/p3041ds.dts
arch/powerpc/boot/dts/p3060qds.dts
arch/powerpc/boot/dts/p4080ds.dts
arch/powerpc/boot/dts/p5020ds.dts
arch/powerpc/configs/corenet32_smp_defconfig
arch/powerpc/configs/corenet64_smp_defconfig
arch/powerpc/configs/mpc85xx_defconfig
arch/powerpc/configs/mpc85xx_smp_defconfig
arch/powerpc/include/asm/epapr_hcalls.h
arch/powerpc/include/asm/fsl_guts.h
arch/powerpc/kernel/fadump.c
arch/powerpc/kernel/kgdb.c
arch/powerpc/kvm/book3s_emulate.c
arch/powerpc/kvm/book3s_paired_singles.c
arch/powerpc/kvm/book3s_pr.c
arch/powerpc/platforms/52xx/mpc52xx_pci.c
arch/powerpc/platforms/85xx/mpc85xx_mds.c
arch/powerpc/platforms/85xx/mpc85xx_rdb.c
arch/powerpc/platforms/85xx/p1022_ds.c
arch/powerpc/platforms/86xx/mpc8610_hpcd.c
arch/powerpc/platforms/cell/qpace_setup.c
arch/powerpc/platforms/cell/setup.c
arch/powerpc/platforms/pseries/eeh_event.c
arch/powerpc/sysdev/qe_lib/qe.c
arch/sparc/kernel/leon_kernel.c
arch/tile/kernel/setup.c
arch/um/kernel/skas/process.c
arch/um/kernel/smp.c
arch/x86/net/bpf_jit_comp.c
arch/x86/xen/enlighten.c
crypto/ablkcipher.c
crypto/aead.c
crypto/crypto_user.c
crypto/pcrypt.c
drivers/Kconfig
drivers/Makefile
drivers/cpufreq/db8500-cpufreq.c
drivers/gpu/drm/Kconfig
drivers/gpu/drm/Makefile
drivers/gpu/drm/drm_drv.c
drivers/gpu/drm/drm_fops.c
drivers/gpu/drm/drm_gem.c
drivers/gpu/drm/drm_prime.c [new file with mode: 0644]
drivers/hsi/Kconfig [new file with mode: 0644]
drivers/hsi/Makefile [new file with mode: 0644]
drivers/hsi/clients/Kconfig [new file with mode: 0644]
drivers/hsi/clients/Makefile [new file with mode: 0644]
drivers/hsi/clients/hsi_char.c [new file with mode: 0644]
drivers/hsi/hsi.c [new file with mode: 0644]
drivers/hsi/hsi_boardinfo.c [new file with mode: 0644]
drivers/hsi/hsi_core.h [new file with mode: 0644]
drivers/isdn/hardware/mISDN/avmfritz.c
drivers/isdn/hardware/mISDN/hfcpci.c
drivers/isdn/hardware/mISDN/hfcsusb.c
drivers/isdn/hardware/mISDN/mISDNipac.c
drivers/isdn/hardware/mISDN/mISDNisar.c
drivers/isdn/hardware/mISDN/netjet.c
drivers/isdn/hardware/mISDN/w6692.c
drivers/net/bonding/bond_main.c
drivers/net/eql.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h
drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h
drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h
drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c
drivers/net/ethernet/broadcom/tg3.c
drivers/net/ethernet/freescale/fsl_pq_mdio.c
drivers/net/ethernet/freescale/ucc_geth.c
drivers/net/ethernet/intel/e1000/e1000_main.c
drivers/net/ethernet/intel/e1000e/netdev.c
drivers/net/ethernet/intel/igb/igb_main.c
drivers/net/ethernet/intel/igbvf/netdev.c
drivers/net/ethernet/intel/ixgb/ixgb_main.c
drivers/net/ethernet/intel/ixgbe/ixgbe.h
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
drivers/net/ethernet/marvell/sky2.c
drivers/net/ethernet/nxp/lpc_eth.c
drivers/net/ethernet/renesas/Kconfig
drivers/net/ethernet/renesas/sh_eth.c
drivers/net/ethernet/renesas/sh_eth.h
drivers/net/ethernet/via/via-rhine.c
drivers/net/rionet.c
drivers/net/usb/cdc-phonet.c
drivers/net/usb/cdc_eem.c
drivers/net/usb/rtl8150.c
drivers/net/usb/zaurus.c
drivers/net/virtio_net.c
drivers/net/wimax/i2400m/netdev.c
drivers/net/wimax/i2400m/usb.c
drivers/net/wireless/ath/ath9k/calib.c
drivers/net/wireless/ath/ath9k/init.c
drivers/net/wireless/ath/ath9k/main.c
drivers/net/wireless/ath/ath9k/recv.c
drivers/net/wireless/ipw2x00/ipw2200.c
drivers/net/wireless/iwlegacy/3945-mac.c
drivers/net/wireless/iwlegacy/4965-mac.c
drivers/net/wireless/iwlegacy/common.c
drivers/net/wireless/orinoco/main.c
drivers/net/wireless/rt2x00/rt2800usb.c
drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c
drivers/net/wireless/rtlwifi/rtl8192de/phy.c
drivers/usb/gadget/f_phonet.c
include/asm-generic/cmpxchg.h
include/crypto/internal/aead.h
include/crypto/internal/skcipher.h
include/drm/drm.h
include/drm/drmP.h
include/linux/Kbuild
include/linux/cpumask.h
include/linux/cryptouser.h
include/linux/firewire.h
include/linux/hsi/Kbuild [new file with mode: 0644]
include/linux/hsi/hsi.h [new file with mode: 0644]
include/linux/hsi/hsi_char.h [new file with mode: 0644]
include/linux/if_eql.h
include/linux/platform_data/atmel.h
include/net/cfg80211.h
init/Kconfig
kernel/cpuset.c
kernel/irq_work.c
kernel/padata.c
net/802/garp.c
net/core/dev.c
net/ipv4/route.c
net/ipv6/route.c
net/mac80211/agg-rx.c
net/mac80211/main.c
net/mac80211/scan.c
net/netfilter/nfnetlink_acct.c
net/rose/rose_dev.c
net/wireless/nl80211.c
scripts/tags.sh
sound/soc/fsl/mpc8610_hpcd.c
sound/soc/fsl/p1022_ds.c

index 9c27e51..7514dbf 100644 (file)
@@ -446,4 +446,21 @@ X!Idrivers/video/console/fonts.c
 !Edrivers/i2c/i2c-core.c
   </chapter>
 
+  <chapter id="hsi">
+     <title>High Speed Synchronous Serial Interface (HSI)</title>
+
+     <para>
+       High Speed Synchronous Serial Interface (HSI) is a
+       serial interface mainly used for connecting application
+       engines (APE) with cellular modem engines (CMT) in cellular
+       handsets.
+
+       HSI provides multiplexing for up to 16 logical channels,
+       low-latency and full duplex communication.
+     </para>
+
+!Iinclude/linux/hsi/hsi.h
+!Edrivers/hsi/hsi.c
+  </chapter>
+
 </book>
index 5c51ed4..cefd3d8 100644 (file)
@@ -217,7 +217,7 @@ and name space for cpusets, with a minimum of additional kernel code.
 
 The cpus and mems files in the root (top_cpuset) cpuset are
 read-only.  The cpus file automatically tracks the value of
-cpu_online_map using a CPU hotplug notifier, and the mems file
+cpu_online_mask using a CPU hotplug notifier, and the mems file
 automatically tracks the value of node_states[N_HIGH_MEMORY]--i.e.,
 nodes with memory--using the cpuset_track_online_nodes() hook.
 
index a20bfd4..66ef8f3 100644 (file)
@@ -47,7 +47,7 @@ maxcpus=n    Restrict boot time cpus to n. Say if you have 4 cpus, using
              other cpus later online, read FAQ's for more info.
 
 additional_cpus=n (*)  Use this to limit hotpluggable cpus. This option sets
-                       cpu_possible_map = cpu_present_map + additional_cpus
+                       cpu_possible_mask = cpu_present_mask + additional_cpus
 
 cede_offline={"off","on"}  Use this option to disable/enable putting offlined
                            processors to an extended H_CEDE state on
@@ -64,11 +64,11 @@ should only rely on this to count the # of cpus, but *MUST* not rely
 on the apicid values in those tables for disabled apics. In the event
 BIOS doesn't mark such hot-pluggable cpus as disabled entries, one could
 use this parameter "additional_cpus=x" to represent those cpus in the
-cpu_possible_map.
+cpu_possible_mask.
 
 possible_cpus=n                [s390,x86_64] use this to set hotpluggable cpus.
                        This option sets possible_cpus bits in
-                       cpu_possible_map. Thus keeping the numbers of bits set
+                       cpu_possible_mask. Thus keeping the numbers of bits set
                        constant even if the machine gets rebooted.
 
 CPU maps and such
@@ -76,7 +76,7 @@ CPU maps and such
 [More on cpumaps and primitive to manipulate, please check
 include/linux/cpumask.h that has more descriptive text.]
 
-cpu_possible_map: Bitmap of possible CPUs that can ever be available in the
+cpu_possible_mask: Bitmap of possible CPUs that can ever be available in the
 system. This is used to allocate some boot time memory for per_cpu variables
 that aren't designed to grow/shrink as CPUs are made available or removed.
 Once set during boot time discovery phase, the map is static, i.e no bits
@@ -84,13 +84,13 @@ are added or removed anytime.  Trimming it accurately for your system needs
 upfront can save some boot time memory. See below for how we use heuristics
 in x86_64 case to keep this under check.
 
-cpu_online_map: Bitmap of all CPUs currently online. Its set in __cpu_up()
+cpu_online_mask: Bitmap of all CPUs currently online. Its set in __cpu_up()
 after a cpu is available for kernel scheduling and ready to receive
 interrupts from devices. Its cleared when a cpu is brought down using
 __cpu_disable(), before which all OS services including interrupts are
 migrated to another target CPU.
 
-cpu_present_map: Bitmap of CPUs currently present in the system. Not all
+cpu_present_mask: Bitmap of CPUs currently present in the system. Not all
 of them may be online. When physical hotplug is processed by the relevant
 subsystem (e.g ACPI) can change and new bit either be added or removed
 from the map depending on the event is hot-add/hot-remove. There are currently
@@ -99,22 +99,22 @@ at which time hotplug is disabled.
 
 You really dont need to manipulate any of the system cpu maps. They should
 be read-only for most use. When setting up per-cpu resources almost always use
-cpu_possible_map/for_each_possible_cpu() to iterate.
+cpu_possible_mask/for_each_possible_cpu() to iterate.
 
 Never use anything other than cpumask_t to represent bitmap of CPUs.
 
        #include <linux/cpumask.h>
 
-       for_each_possible_cpu     - Iterate over cpu_possible_map
-       for_each_online_cpu       - Iterate over cpu_online_map
-       for_each_present_cpu      - Iterate over cpu_present_map
+       for_each_possible_cpu     - Iterate over cpu_possible_mask
+       for_each_online_cpu       - Iterate over cpu_online_mask
+       for_each_present_cpu      - Iterate over cpu_present_mask
        for_each_cpu_mask(x,mask) - Iterate over some random collection of cpu mask.
 
        #include <linux/cpu.h>
        get_online_cpus() and put_online_cpus():
 
 The above calls are used to inhibit cpu hotplug operations. While the
-cpu_hotplug.refcount is non zero, the cpu_online_map will not change.
+cpu_hotplug.refcount is non zero, the cpu_online_mask will not change.
 If you merely need to avoid cpus going away, you could also use
 preempt_disable() and preempt_enable() for those sections.
 Just remember the critical section cannot call any
index 3b7488f..e34b531 100644 (file)
@@ -225,6 +225,7 @@ Code  Seq#(hex)     Include File            Comments
 'j'    00-3F   linux/joystick.h
 'k'    00-0F   linux/spi/spidev.h      conflict!
 'k'    00-05   video/kyro.h            conflict!
+'k'    10-17   linux/hsi/hsi_char.h    HSI character device
 'l'    00-3F   linux/tcfs_fs.h         transparent cryptographic file system
                                        <http://web.archive.org/web/*/http://mikonos.dia.unisa.it/tcfs>
 'l'    40-7F   linux/udf_fs_i.h        in development:
index eecf344..962232d 100644 (file)
@@ -1251,7 +1251,6 @@ ATHEROS ATH5K WIRELESS DRIVER
 M:     Jiri Slaby <jirislaby@gmail.com>
 M:     Nick Kossifidis <mickflemm@gmail.com>
 M:     "Luis R. Rodriguez" <mcgrof@qca.qualcomm.com>
-M:     Bob Copeland <me@bobcopeland.com>
 L:     linux-wireless@vger.kernel.org
 L:     ath5k-devel@lists.ath5k.org
 W:     http://wireless.kernel.org/en/users/Drivers/ath5k
@@ -3557,17 +3556,13 @@ L:      linux-pm@vger.kernel.org
 S:     Supported
 F:     arch/x86/platform/mrst/pmu.*
 
-INTEL PRO/WIRELESS 2100 NETWORK CONNECTION SUPPORT
+INTEL PRO/WIRELESS 2100, 2200BG, 2915ABG NETWORK CONNECTION SUPPORT
+M:     Stanislav Yakovlev <stas.yakovlev@gmail.com>
 L:     linux-wireless@vger.kernel.org
-S:     Orphan
+S:     Maintained
 F:     Documentation/networking/README.ipw2100
-F:     drivers/net/wireless/ipw2x00/ipw2100.*
-
-INTEL PRO/WIRELESS 2915ABG NETWORK CONNECTION SUPPORT
-L:     linux-wireless@vger.kernel.org
-S:     Orphan
 F:     Documentation/networking/README.ipw2200
-F:     drivers/net/wireless/ipw2x00/ipw2200.*
+F:     drivers/net/wireless/ipw2x00/
 
 INTEL(R) TRUSTED EXECUTION TECHNOLOGY (TXT)
 M:     Joseph Cihula <joseph.cihula@intel.com>
index 4087a56..50d438d 100644 (file)
@@ -450,7 +450,7 @@ setup_smp(void)
                smp_num_probed = 1;
        }
 
-       printk(KERN_INFO "SMP: %d CPUs probed -- cpu_present_map = %lx\n",
+       printk(KERN_INFO "SMP: %d CPUs probed -- cpu_present_mask = %lx\n",
               smp_num_probed, cpumask_bits(cpu_present_mask)[0]);
 }
 
index ab1869d..4dd41fc 100644 (file)
@@ -152,7 +152,7 @@ int __kprobes __arch_disarm_kprobe(void *p)
 
 void __kprobes arch_disarm_kprobe(struct kprobe *p)
 {
-       stop_machine(__arch_disarm_kprobe, p, &cpu_online_map);
+       stop_machine(__arch_disarm_kprobe, p, cpu_online_mask);
 }
 
 void __kprobes arch_remove_kprobe(struct kprobe *p)
index 2cee7d1..addbbe8 100644 (file)
@@ -349,7 +349,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
                 * re-initialize the map in platform_smp_prepare_cpus() if
                 * present != possible (e.g. physical hotplug).
                 */
-               init_cpu_present(&cpu_possible_map);
+               init_cpu_present(cpu_possible_mask);
 
                /*
                 * Initialise the SCU if there are more than one CPU
@@ -581,8 +581,9 @@ void smp_send_stop(void)
        unsigned long timeout;
 
        if (num_online_cpus() > 1) {
-               cpumask_t mask = cpu_online_map;
-               cpu_clear(smp_processor_id(), mask);
+               struct cpumask mask;
+               cpumask_copy(&mask, cpu_online_mask);
+               cpumask_clear_cpu(smp_processor_id(), &mask);
 
                smp_cross_call(&mask, IPI_CPU_STOP);
        }
index 169a840..c14011f 100644 (file)
@@ -16,6 +16,7 @@
 #ifndef __ASM_ARCH_MSM_UNCOMPRESS_H
 #define __ASM_ARCH_MSM_UNCOMPRESS_H
 
+#include <asm/barrier.h>
 #include <asm/processor.h>
 #include <mach/msm_iomap.h>
 
index 7173386..70742ec 100644 (file)
@@ -7,7 +7,7 @@
 #include <linux/types.h>
 #include <linux/serial.h>
 #include <linux/platform_data/macb.h>
-#include <linux/platform_data/atmel_nand.h>
+#include <linux/platform_data/atmel.h>
 
 #define GPIO_PIN_NONE  (-1)
 
index ba2484f..c05868c 100644 (file)
@@ -122,7 +122,8 @@ static inline unsigned long __xchg(unsigned long x, volatile void *ptr,
                        (unsigned long)(n), sizeof(*(ptr))))
 #define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n))
 
-#include <asm-generic/cmpxchg.h>
+#define cmpxchg(ptr, o, n)     cmpxchg_local((ptr), (o), (n))
+#define cmpxchg64(ptr, o, n)   cmpxchg64_local((ptr), (o), (n))
 
 #endif /* !CONFIG_SMP */
 
index 41098a3..4f8d8bc 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/list.h>
 #include <linux/pci.h>
+#include <linux/export.h>
 #include <linux/highmem.h>
 #include <linux/scatterlist.h>
 #include <asm/io.h>
index 15d1fd2..9b44a9e 100644 (file)
@@ -35,7 +35,7 @@
 #define BASE_IPI_IRQ 26
 
 /*
- * cpu_possible_map needs to be filled out prior to setup_per_cpu_areas
+ * cpu_possible_mask needs to be filled out prior to setup_per_cpu_areas
  * (which is prior to any of our smp_prepare_cpu crap), in order to set
  * up the...  per_cpu areas.
  */
@@ -208,7 +208,7 @@ int __cpuinit __cpu_up(unsigned int cpu)
        stack_start =  ((void *) thread) + THREAD_SIZE;
        __vmstart(start_secondary, stack_start);
 
-       while (!cpu_isset(cpu, cpu_online_map))
+       while (!cpu_online(cpu))
                barrier();
 
        return 0;
@@ -229,7 +229,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
 
        /*  Right now, let's just fake it. */
        for (i = 0; i < max_cpus; i++)
-               cpu_set(i, cpu_present_map);
+               set_cpu_present(i, true);
 
        /*  Also need to register the interrupts for IPI  */
        if (max_cpus > 1)
@@ -269,5 +269,5 @@ void smp_start_cpus(void)
        int i;
 
        for (i = 0; i < NR_CPUS; i++)
-               cpu_set(i, cpu_possible_map);
+               set_cpu_possible(i, true);
 }
index ac795d3..6f38b61 100644 (file)
@@ -839,7 +839,7 @@ static __init int setup_additional_cpus(char *s)
 early_param("additional_cpus", setup_additional_cpus);
 
 /*
- * cpu_possible_map should be static, it cannot change as CPUs
+ * cpu_possible_mask should be static, it cannot change as CPUs
  * are onlined, or offlined. The reason is per-cpu data-structures
  * are allocated by some modules at init time, and dont expect to
  * do this dynamically on cpu arrival/departure.
index c3e2b85..97e7ce9 100644 (file)
@@ -78,7 +78,7 @@ static inline void octeon_send_ipi_mask(const struct cpumask *mask,
 }
 
 /**
- * Detect available CPUs, populate cpu_possible_map
+ * Detect available CPUs, populate cpu_possible_mask
  */
 static void octeon_smp_hotplug_setup(void)
 {
@@ -268,7 +268,7 @@ static int octeon_cpu_disable(void)
 
        spin_lock(&smp_reserve_lock);
 
-       cpu_clear(cpu, cpu_online_map);
+       set_cpu_online(cpu, false);
        cpu_clear(cpu, cpu_callin_map);
        local_irq_disable();
        fixup_irqs();
index 802e616..33f63ba 100644 (file)
@@ -173,7 +173,7 @@ asmlinkage long mipsmt_sys_sched_getaffinity(pid_t pid, unsigned int len,
        if (retval)
                goto out_unlock;
 
-       cpus_and(mask, p->thread.user_cpus_allowed, cpu_possible_map);
+       cpumask_and(&mask, &p->thread.user_cpus_allowed, cpu_possible_mask);
 
 out_unlock:
        read_unlock(&tasklist_lock);
index e309665..f8b2c59 100644 (file)
@@ -25,7 +25,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
        int i;
 
 #ifdef CONFIG_SMP
-       if (!cpu_isset(n, cpu_online_map))
+       if (!cpu_online(n))
                return 0;
 #endif
 
index ca67356..3046e29 100644 (file)
@@ -317,7 +317,7 @@ static int bmips_cpu_disable(void)
 
        pr_info("SMP: CPU%d is offline\n", cpu);
 
-       cpu_clear(cpu, cpu_online_map);
+       set_cpu_online(cpu, false);
        cpu_clear(cpu, cpu_callin_map);
 
        local_flush_tlb_all();
index 9c1cce9..ba9376b 100644 (file)
@@ -148,7 +148,7 @@ static void stop_this_cpu(void *dummy)
        /*
         * Remove this CPU:
         */
-       cpu_clear(smp_processor_id(), cpu_online_map);
+       set_cpu_online(smp_processor_id(), false);
        for (;;) {
                if (cpu_wait)
                        (*cpu_wait)();          /* Wait if available. */
@@ -174,7 +174,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
        mp_ops->prepare_cpus(max_cpus);
        set_cpu_sibling_map(0);
 #ifndef CONFIG_HOTPLUG_CPU
-       init_cpu_present(&cpu_possible_map);
+       init_cpu_present(cpu_possible_mask);
 #endif
 }
 
@@ -248,7 +248,7 @@ int __cpuinit __cpu_up(unsigned int cpu)
        while (!cpu_isset(cpu, cpu_callin_map))
                udelay(100);
 
-       cpu_set(cpu, cpu_online_map);
+       set_cpu_online(cpu, true);
 
        return 0;
 }
@@ -320,13 +320,12 @@ void flush_tlb_mm(struct mm_struct *mm)
        if ((atomic_read(&mm->mm_users) != 1) || (current->mm != mm)) {
                smp_on_other_tlbs(flush_tlb_mm_ipi, mm);
        } else {
-               cpumask_t mask = cpu_online_map;
                unsigned int cpu;
 
-               cpu_clear(smp_processor_id(), mask);
-               for_each_cpu_mask(cpu, mask)
-                       if (cpu_context(cpu, mm))
+               for_each_online_cpu(cpu) {
+                       if (cpu != smp_processor_id() && cpu_context(cpu, mm))
                                cpu_context(cpu, mm) = 0;
+               }
        }
        local_flush_tlb_mm(mm);
 
@@ -360,13 +359,12 @@ void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned l
 
                smp_on_other_tlbs(flush_tlb_range_ipi, &fd);
        } else {
-               cpumask_t mask = cpu_online_map;
                unsigned int cpu;
 
-               cpu_clear(smp_processor_id(), mask);
-               for_each_cpu_mask(cpu, mask)
-                       if (cpu_context(cpu, mm))
+               for_each_online_cpu(cpu) {
+                       if (cpu != smp_processor_id() && cpu_context(cpu, mm))
                                cpu_context(cpu, mm) = 0;
+               }
        }
        local_flush_tlb_range(vma, start, end);
        preempt_enable();
@@ -407,13 +405,12 @@ void flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
 
                smp_on_other_tlbs(flush_tlb_page_ipi, &fd);
        } else {
-               cpumask_t mask = cpu_online_map;
                unsigned int cpu;
 
-               cpu_clear(smp_processor_id(), mask);
-               for_each_cpu_mask(cpu, mask)
-                       if (cpu_context(cpu, vma->vm_mm))
+               for_each_online_cpu(cpu) {
+                       if (cpu != smp_processor_id() && cpu_context(cpu, vma->vm_mm))
                                cpu_context(cpu, vma->vm_mm) = 0;
+               }
        }
        local_flush_tlb_page(vma, page);
        preempt_enable();
index c4f75bb..f5dd38f 100644 (file)
@@ -291,7 +291,7 @@ static void smtc_configure_tlb(void)
  * possibly leave some TCs/VPEs as "slave" processors.
  *
  * Use c0_MVPConf0 to find out how many TCs are available, setting up
- * cpu_possible_map and the logical/physical mappings.
+ * cpu_possible_mask and the logical/physical mappings.
  */
 
 int __init smtc_build_cpu_map(int start_cpu_slot)
index 1f9ca07..47037ec 100644 (file)
@@ -80,9 +80,9 @@ static void octeon_flush_icache_all_cores(struct vm_area_struct *vma)
        if (vma)
                mask = *mm_cpumask(vma->vm_mm);
        else
-               mask = cpu_online_map;
-       cpu_clear(cpu, mask);
-       for_each_cpu_mask(cpu, mask)
+               mask = *cpu_online_mask;
+       cpumask_clear_cpu(cpu, &mask);
+       for_each_cpu(cpu, &mask)
                octeon_send_ipi_single(cpu, SMP_ICACHE_FLUSH);
 
        preempt_enable();
index db17f49..fab316d 100644 (file)
@@ -165,7 +165,7 @@ void __init nlm_smp_setup(void)
        cpu_set(boot_cpu, phys_cpu_present_map);
        __cpu_number_map[boot_cpu] = 0;
        __cpu_logical_map[0] = boot_cpu;
-       cpu_set(0, cpu_possible_map);
+       set_cpu_possible(0, true);
 
        num_cpus = 1;
        for (i = 0; i < NR_CPUS; i++) {
@@ -177,14 +177,14 @@ void __init nlm_smp_setup(void)
                        cpu_set(i, phys_cpu_present_map);
                        __cpu_number_map[i] = num_cpus;
                        __cpu_logical_map[num_cpus] = i;
-                       cpu_set(num_cpus, cpu_possible_map);
+                       set_cpu_possible(num_cpus, true);
                        ++num_cpus;
                }
        }
 
        pr_info("Phys CPU present map: %lx, possible map %lx\n",
                (unsigned long)phys_cpu_present_map.bits[0],
-               (unsigned long)cpu_possible_map.bits[0]);
+               (unsigned long)cpumask_bits(cpu_possible_mask)[0]);
 
        pr_info("Detected %i Slave CPU(s)\n", num_cpus);
        nlm_set_nmi_handler(nlm_boot_secondary_cpus);
index 2608752..b71fae2 100644 (file)
@@ -146,7 +146,7 @@ static void __cpuinit yos_boot_secondary(int cpu, struct task_struct *idle)
 }
 
 /*
- * Detect available CPUs, populate cpu_possible_map before smp_init
+ * Detect available CPUs, populate cpu_possible_mask before smp_init
  *
  * We don't want to start the secondary CPU yet nor do we have a nice probing
  * feature in PMON so we just assume presence of the secondary core.
@@ -155,10 +155,10 @@ static void __init yos_smp_setup(void)
 {
        int i;
 
-       cpus_clear(cpu_possible_map);
+       init_cpu_possible(cpu_none_mask);
 
        for (i = 0; i < 2; i++) {
-               cpu_set(i, cpu_possible_map);
+               set_cpu_possible(i, true);
                __cpu_number_map[i]     = i;
                __cpu_logical_map[i]    = i;
        }
@@ -169,7 +169,7 @@ static void __init yos_prepare_cpus(unsigned int max_cpus)
        /*
         * Be paranoid.  Enable the IPI only if we're really about to go SMP.
         */
-       if (cpus_weight(cpu_possible_map))
+       if (num_possible_cpus())
                set_c0_status(STATUSF_IP5);
 }
 
index c6851df..735b43b 100644 (file)
@@ -76,7 +76,7 @@ static int do_cpumask(cnodeid_t cnode, nasid_t nasid, int highest)
                        /* Only let it join in if it's marked enabled */
                        if ((acpu->cpu_info.flags & KLINFO_ENABLE) &&
                            (tot_cpus_found != NR_CPUS)) {
-                               cpu_set(cpuid, cpu_possible_map);
+                               set_cpu_possible(cpuid, true);
                                alloc_cpupda(cpuid, tot_cpus_found);
                                cpus_found++;
                                tot_cpus_found++;
index d667875..de88e22 100644 (file)
@@ -138,7 +138,7 @@ static void __cpuinit bcm1480_boot_secondary(int cpu, struct task_struct *idle)
 
 /*
  * Use CFE to find out how many CPUs are available, setting up
- * cpu_possible_map and the logical/physical mappings.
+ * cpu_possible_mask and the logical/physical mappings.
  * XXXKW will the boot CPU ever not be physical 0?
  *
  * Common setup before any secondaries are started
@@ -147,14 +147,13 @@ static void __init bcm1480_smp_setup(void)
 {
        int i, num;
 
-       cpus_clear(cpu_possible_map);
-       cpu_set(0, cpu_possible_map);
+       init_cpu_possible(cpumask_of(0));
        __cpu_number_map[0] = 0;
        __cpu_logical_map[0] = 0;
 
        for (i = 1, num = 0; i < NR_CPUS; i++) {
                if (cfe_cpu_stop(i) == 0) {
-                       cpu_set(i, cpu_possible_map);
+                       set_cpu_possible(i, true);
                        __cpu_number_map[i] = ++num;
                        __cpu_logical_map[num] = i;
                }
index 38e7f6b..285cfef 100644 (file)
@@ -126,7 +126,7 @@ static void __cpuinit sb1250_boot_secondary(int cpu, struct task_struct *idle)
 
 /*
  * Use CFE to find out how many CPUs are available, setting up
- * cpu_possible_map and the logical/physical mappings.
+ * cpu_possible_mask and the logical/physical mappings.
  * XXXKW will the boot CPU ever not be physical 0?
  *
  * Common setup before any secondaries are started
@@ -135,14 +135,13 @@ static void __init sb1250_smp_setup(void)
 {
        int i, num;
 
-       cpus_clear(cpu_possible_map);
-       cpu_set(0, cpu_possible_map);
+       init_cpu_possible(cpumask_of(0));
        __cpu_number_map[0] = 0;
        __cpu_logical_map[0] = 0;
 
        for (i = 1, num = 0; i < NR_CPUS; i++) {
                if (cfe_cpu_stop(i) == 0) {
-                       cpu_set(i, cpu_possible_map);
+                       set_cpu_possible(i, true);
                        __cpu_number_map[i] = ++num;
                        __cpu_logical_map[num] = i;
                }
index 3ae5607..6c6defc 100644 (file)
@@ -6,6 +6,7 @@
 #define _ASM_PARISC_ATOMIC_H_
 
 #include <linux/types.h>
+#include <asm/cmpxchg.h>
 
 /*
  * Atomic operations that C can't guarantee us.  Useful for
@@ -48,112 +49,6 @@ extern arch_spinlock_t __atomic_hash[ATOMIC_HASH_SIZE] __lock_aligned;
 #  define _atomic_spin_unlock_irqrestore(l,f) do { local_irq_restore(f); } while (0)
 #endif
 
-/* This should get optimized out since it's never called.
-** Or get a link error if xchg is used "wrong".
-*/
-extern void __xchg_called_with_bad_pointer(void);
-
-
-/* __xchg32/64 defined in arch/parisc/lib/bitops.c */
-extern unsigned long __xchg8(char, char *);
-extern unsigned long __xchg32(int, int *);
-#ifdef CONFIG_64BIT
-extern unsigned long __xchg64(unsigned long, unsigned long *);
-#endif
-
-/* optimizer better get rid of switch since size is a constant */
-static __inline__ unsigned long
-__xchg(unsigned long x, __volatile__ void * ptr, int size)
-{
-       switch(size) {
-#ifdef CONFIG_64BIT
-       case 8: return __xchg64(x,(unsigned long *) ptr);
-#endif
-       case 4: return __xchg32((int) x, (int *) ptr);
-       case 1: return __xchg8((char) x, (char *) ptr);
-       }
-       __xchg_called_with_bad_pointer();
-       return x;
-}
-
-
-/*
-** REVISIT - Abandoned use of LDCW in xchg() for now:
-** o need to test sizeof(*ptr) to avoid clearing adjacent bytes
-** o and while we are at it, could CONFIG_64BIT code use LDCD too?
-**
-**     if (__builtin_constant_p(x) && (x == NULL))
-**             if (((unsigned long)p & 0xf) == 0)
-**                     return __ldcw(p);
-*/
-#define xchg(ptr,x) \
-       ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
-
-
-#define __HAVE_ARCH_CMPXCHG    1
-
-/* bug catcher for when unsupported size is used - won't link */
-extern void __cmpxchg_called_with_bad_pointer(void);
-
-/* __cmpxchg_u32/u64 defined in arch/parisc/lib/bitops.c */
-extern unsigned long __cmpxchg_u32(volatile unsigned int *m, unsigned int old, unsigned int new_);
-extern unsigned long __cmpxchg_u64(volatile unsigned long *ptr, unsigned long old, unsigned long new_);
-
-/* don't worry...optimizer will get rid of most of this */
-static __inline__ unsigned long
-__cmpxchg(volatile void *ptr, unsigned long old, unsigned long new_, int size)
-{
-       switch(size) {
-#ifdef CONFIG_64BIT
-       case 8: return __cmpxchg_u64((unsigned long *)ptr, old, new_);
-#endif
-       case 4: return __cmpxchg_u32((unsigned int *)ptr, (unsigned int) old, (unsigned int) new_);
-       }
-       __cmpxchg_called_with_bad_pointer();
-       return old;
-}
-
-#define cmpxchg(ptr,o,n)                                                \
-  ({                                                                    \
-     __typeof__(*(ptr)) _o_ = (o);                                      \
-     __typeof__(*(ptr)) _n_ = (n);                                      \
-     (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_,          \
-                                   (unsigned long)_n_, sizeof(*(ptr))); \
-  })
-
-#include <asm-generic/cmpxchg-local.h>
-
-static inline unsigned long __cmpxchg_local(volatile void *ptr,
-                                     unsigned long old,
-                                     unsigned long new_, int size)
-{
-       switch (size) {
-#ifdef CONFIG_64BIT
-       case 8: return __cmpxchg_u64((unsigned long *)ptr, old, new_);
-#endif
-       case 4: return __cmpxchg_u32(ptr, old, new_);
-       default:
-               return __cmpxchg_local_generic(ptr, old, new_, size);
-       }
-}
-
-/*
- * cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make
- * them available.
- */
-#define cmpxchg_local(ptr, o, n)                                       \
-       ((__typeof__(*(ptr)))__cmpxchg_local((ptr), (unsigned long)(o), \
-                       (unsigned long)(n), sizeof(*(ptr))))
-#ifdef CONFIG_64BIT
-#define cmpxchg64_local(ptr, o, n)                                     \
-  ({                                                                   \
-       BUILD_BUG_ON(sizeof(*(ptr)) != 8);                              \
-       cmpxchg_local((ptr), (o), (n));                                 \
-  })
-#else
-#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n))
-#endif
-
 /*
  * Note that we need not lock read accesses - aligned word writes/reads
  * are atomic, so a reader never sees inconsistent values.
diff --git a/arch/parisc/include/asm/cmpxchg.h b/arch/parisc/include/asm/cmpxchg.h
new file mode 100644 (file)
index 0000000..dbd1335
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ * forked from parisc asm/atomic.h which was:
+ *     Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
+ *     Copyright (C) 2006 Kyle McMartin <kyle@parisc-linux.org>
+ */
+
+#ifndef _ASM_PARISC_CMPXCHG_H_
+#define _ASM_PARISC_CMPXCHG_H_
+
+/* This should get optimized out since it's never called.
+** Or get a link error if xchg is used "wrong".
+*/
+extern void __xchg_called_with_bad_pointer(void);
+
+/* __xchg32/64 defined in arch/parisc/lib/bitops.c */
+extern unsigned long __xchg8(char, char *);
+extern unsigned long __xchg32(int, int *);
+#ifdef CONFIG_64BIT
+extern unsigned long __xchg64(unsigned long, unsigned long *);
+#endif
+
+/* optimizer better get rid of switch since size is a constant */
+static inline unsigned long
+__xchg(unsigned long x, __volatile__ void *ptr, int size)
+{
+       switch (size) {
+#ifdef CONFIG_64BIT
+       case 8: return __xchg64(x, (unsigned long *) ptr);
+#endif
+       case 4: return __xchg32((int) x, (int *) ptr);
+       case 1: return __xchg8((char) x, (char *) ptr);
+       }
+       __xchg_called_with_bad_pointer();
+       return x;
+}
+
+/*
+** REVISIT - Abandoned use of LDCW in xchg() for now:
+** o need to test sizeof(*ptr) to avoid clearing adjacent bytes
+** o and while we are at it, could CONFIG_64BIT code use LDCD too?
+**
+**     if (__builtin_constant_p(x) && (x == NULL))
+**             if (((unsigned long)p & 0xf) == 0)
+**                     return __ldcw(p);
+*/
+#define xchg(ptr, x) \
+       ((__typeof__(*(ptr)))__xchg((unsigned long)(x), (ptr), sizeof(*(ptr))))
+
+#define __HAVE_ARCH_CMPXCHG    1
+
+/* bug catcher for when unsupported size is used - won't link */
+extern void __cmpxchg_called_with_bad_pointer(void);
+
+/* __cmpxchg_u32/u64 defined in arch/parisc/lib/bitops.c */
+extern unsigned long __cmpxchg_u32(volatile unsigned int *m, unsigned int old,
+                                  unsigned int new_);
+extern unsigned long __cmpxchg_u64(volatile unsigned long *ptr,
+                                  unsigned long old, unsigned long new_);
+
+/* don't worry...optimizer will get rid of most of this */
+static inline unsigned long
+__cmpxchg(volatile void *ptr, unsigned long old, unsigned long new_, int size)
+{
+       switch (size) {
+#ifdef CONFIG_64BIT
+       case 8: return __cmpxchg_u64((unsigned long *)ptr, old, new_);
+#endif
+       case 4: return __cmpxchg_u32((unsigned int *)ptr,
+                                    (unsigned int)old, (unsigned int)new_);
+       }
+       __cmpxchg_called_with_bad_pointer();
+       return old;
+}
+
+#define cmpxchg(ptr, o, n)                                              \
+({                                                                      \
+       __typeof__(*(ptr)) _o_ = (o);                                    \
+       __typeof__(*(ptr)) _n_ = (n);                                    \
+       (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_,        \
+                                   (unsigned long)_n_, sizeof(*(ptr))); \
+})
+
+#include <asm-generic/cmpxchg-local.h>
+
+static inline unsigned long __cmpxchg_local(volatile void *ptr,
+                                     unsigned long old,
+                                     unsigned long new_, int size)
+{
+       switch (size) {
+#ifdef CONFIG_64BIT
+       case 8: return __cmpxchg_u64((unsigned long *)ptr, old, new_);
+#endif
+       case 4: return __cmpxchg_u32(ptr, old, new_);
+       default:
+               return __cmpxchg_local_generic(ptr, old, new_, size);
+       }
+}
+
+/*
+ * cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make
+ * them available.
+ */
+#define cmpxchg_local(ptr, o, n)                                       \
+       ((__typeof__(*(ptr)))__cmpxchg_local((ptr), (unsigned long)(o), \
+                       (unsigned long)(n), sizeof(*(ptr))))
+#ifdef CONFIG_64BIT
+#define cmpxchg64_local(ptr, o, n)                                     \
+({                                                                     \
+       BUILD_BUG_ON(sizeof(*(ptr)) != 8);                              \
+       cmpxchg_local((ptr), (o), (n));                                 \
+})
+#else
+#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n))
+#endif
+
+#endif /* _ASM_PARISC_CMPXCHG_H_ */
diff --git a/arch/powerpc/boot/dts/p1020mbg-pc.dtsi b/arch/powerpc/boot/dts/p1020mbg-pc.dtsi
new file mode 100644 (file)
index 0000000..a24699c
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+ * P1020 MBG-PC Device Tree Source stub (no addresses or top-level ranges)
+ *
+ * Copyright 2012 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of Freescale Semiconductor nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+&lbc {
+       nor@0,0 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "cfi-flash";
+               reg = <0x0 0x0 0x4000000>;
+               bank-width = <2>;
+               device-width = <1>;
+
+               partition@0 {
+                       /* 128KB for DTB Image */
+                       reg = <0x0 0x00020000>;
+                       label = "NOR DTB Image";
+               };
+
+               partition@20000 {
+                       /* 3.875 MB for Linux Kernel Image */
+                       reg = <0x00020000 0x003e0000>;
+                       label = "NOR Linux Kernel Image";
+               };
+
+               partition@400000 {
+                       /* 58MB for Root file System */
+                       reg = <0x00400000 0x03a00000>;
+                       label = "NOR Root File System";
+               };
+
+               partition@3e00000 {
+                       /* This location must not be altered  */
+                       /* 1M for Vitesse 7385 Switch firmware */
+                       reg = <0x3e00000 0x00100000>;
+                       label = "NOR Vitesse-7385 Firmware";
+                       read-only;
+               };
+
+               partition@3f00000 {
+                       /* This location must not be altered  */
+                       /* 512KB for u-boot Bootloader Image */
+                       /* 512KB for u-boot Environment Variables */
+                       reg = <0x03f00000 0x00100000>;
+                       label = "NOR U-Boot Image";
+                       read-only;
+               };
+       };
+
+       L2switch@2,0 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "vitesse-7385";
+               reg = <0x2 0x0 0x20000>;
+       };
+};
+
+&soc {
+       i2c@3000 {
+               rtc@68 {
+                       compatible = "dallas,ds1339";
+                       reg = <0x68>;
+               };
+       };
+
+       mdio@24000 {
+               phy0: ethernet-phy@0 {
+                       interrupts = <3 1 0 0>;
+                       reg = <0x0>;
+               };
+               phy1: ethernet-phy@1 {
+                       interrupts = <2 1 0 0>;
+                       reg = <0x1>;
+               };
+       };
+
+       mdio@25000 {
+               tbi1: tbi-phy@11 {
+                       reg = <0x11>;
+                       device_type = "tbi-phy";
+               };
+       };
+
+       mdio@26000 {
+               tbi2: tbi-phy@11 {
+                       reg = <0x11>;
+                       device_type = "tbi-phy";
+               };
+       };
+
+       enet0: ethernet@b0000 {
+               fixed-link = <1 1 1000 0 0>;
+               phy-connection-type = "rgmii-id";
+       };
+
+       enet1: ethernet@b1000 {
+               phy-handle = <&phy0>;
+               tbi-handle = <&tbi1>;
+               phy-connection-type = "sgmii";
+       };
+
+       enet2: ethernet@b2000 {
+               phy-handle = <&phy1>;
+               phy-connection-type = "rgmii-id";
+       };
+
+       usb@22000 {
+               phy_type = "ulpi";
+       };
+
+       /* USB2 is shared with localbus, so it must be disabled
+          by default. We can't put 'status = "disabled";' here
+          since U-Boot doesn't clear the status property when
+          it enables USB2. OTOH, U-Boot does create a new node
+          when there isn't any. So, just comment it out.
+       */
+       usb@23000 {
+               status = "disabled";
+               phy_type = "ulpi";
+       };
+};
diff --git a/arch/powerpc/boot/dts/p1020mbg-pc_32b.dts b/arch/powerpc/boot/dts/p1020mbg-pc_32b.dts
new file mode 100644 (file)
index 0000000..ab8f076
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * P1020 MBG-PC Device Tree Source (32-bit address map)
+ *
+ * Copyright 2012 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of Freescale Semiconductor nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/include/ "fsl/p1020si-pre.dtsi"
+/ {
+       model = "fsl,P1020MBG-PC";
+       compatible = "fsl,P1020MBG-PC";
+
+       memory {
+               device_type = "memory";
+       };
+
+       lbc: localbus@ffe05000 {
+               reg = <0x0 0xffe05000 0x0 0x1000>;
+
+               /* NOR and L2 switch */
+               ranges = <0x0 0x0 0x0 0xec000000 0x04000000
+                         0x1 0x0 0x0 0xffa00000 0x00040000
+                         0x2 0x0 0x0 0xffb00000 0x00020000>;
+       };
+
+       soc: soc@ffe00000 {
+               ranges = <0x0 0x0 0xffe00000 0x100000>;
+       };
+
+       pci0: pcie@ffe09000 {
+               reg = <0x0 0xffe09000 0x0 0x1000>;
+               ranges = <0x2000000 0x0 0xe0000000 0x0 0xa0000000 0x0 0x20000000
+                         0x1000000 0x0 0x00000000 0x0 0xffc10000 0x0 0x10000>;
+               pcie@0 {
+                       ranges = <0x2000000 0x0 0xe0000000
+                                 0x2000000 0x0 0xe0000000
+                                 0x0 0x20000000
+
+                                 0x1000000 0x0 0x0
+                                 0x1000000 0x0 0x0
+                                 0x0 0x100000>;
+               };
+       };
+
+       pci1: pcie@ffe0a000 {
+               reg = <0x0 0xffe0a000 0x0 0x1000>;
+               ranges = <0x2000000 0x0 0xe0000000 0x0 0x80000000 0x0 0x20000000
+                         0x1000000 0x0 0x00000000 0x0 0xffc00000 0x0 0x10000>;
+               pcie@0 {
+                       ranges = <0x2000000 0x0 0xe0000000
+                                 0x2000000 0x0 0xe0000000
+                                 0x0 0x20000000
+
+                                 0x1000000 0x0 0x0
+                                 0x1000000 0x0 0x0
+                                 0x0 0x100000>;
+               };
+       };
+};
+
+/include/ "p1020mbg-pc.dtsi"
+/include/ "fsl/p1020si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/p1020mbg-pc_36b.dts b/arch/powerpc/boot/dts/p1020mbg-pc_36b.dts
new file mode 100644 (file)
index 0000000..9e9f401
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * P1020 MBG-PC Device Tree Source (36-bit address map)
+ *
+ * Copyright 2012 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of Freescale Semiconductor nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/include/ "fsl/p1020si-pre.dtsi"
+/ {
+       model = "fsl,P1020MBG-PC";
+       compatible = "fsl,P1020MBG-PC";
+
+       memory {
+               device_type = "memory";
+       };
+
+       lbc: localbus@fffe05000 {
+               reg = <0xf 0xffe05000 0x0 0x1000>;
+
+               /* NOR and L2 switch */
+               ranges = <0x0 0x0 0xf 0xec000000 0x04000000
+                         0x1 0x0 0xf 0xffa00000 0x00040000
+                         0x2 0x0 0xf 0xffb00000 0x00020000>;
+       };
+
+       soc: soc@fffe00000 {
+               ranges = <0x0 0xf 0xffe00000 0x100000>;
+       };
+
+       pci0: pcie@fffe09000 {
+               reg = <0xf 0xffe09000 0x0 0x1000>;
+               ranges = <0x2000000 0x0 0xe0000000 0xc 0x20000000 0x0 0x20000000
+                         0x1000000 0x0 0x00000000 0xf 0xffc10000 0x0 0x10000>;
+               pcie@0 {
+                       ranges = <0x2000000 0x0 0xe0000000
+                                 0x2000000 0x0 0xe0000000
+                                 0x0 0x20000000
+
+                                 0x1000000 0x0 0x0
+                                 0x1000000 0x0 0x0
+                                 0x0 0x100000>;
+               };
+       };
+
+       pci1: pcie@fffe0a000 {
+               reg = <0xf 0xffe0a000 0 0x1000>;
+               ranges = <0x2000000 0x0 0xe0000000 0xc 0x00000000 0x0 0x20000000
+                         0x1000000 0x0 0x00000000 0xf 0xffc00000 0x0 0x10000>;
+               pcie@0 {
+                       ranges = <0x2000000 0x0 0xe0000000
+                                 0x2000000 0x0 0xe0000000
+                                 0x0 0x20000000
+
+                                 0x1000000 0x0 0x0
+                                 0x1000000 0x0 0x0
+                                 0x0 0x100000>;
+               };
+       };
+};
+
+/include/ "p1020mbg-pc.dtsi"
+/include/ "fsl/p1020si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/p1020utm-pc.dtsi b/arch/powerpc/boot/dts/p1020utm-pc.dtsi
new file mode 100644 (file)
index 0000000..7ea85ea
--- /dev/null
@@ -0,0 +1,140 @@
+/*
+ * P1020 UTM-PC Device Tree Source stub (no addresses or top-level ranges)
+ *
+ * Copyright 2012 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of Freescale Semiconductor nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+&lbc {
+       nor@0,0 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "cfi-flash";
+               reg = <0x0 0x0 0x2000000>;
+               bank-width = <2>;
+               device-width = <1>;
+
+               partition@0 {
+                       /* 256KB for DTB Image */
+                       reg = <0x0 0x00040000>;
+                       label = "NOR DTB Image";
+               };
+
+               partition@40000 {
+                       /* 3.75 MB for Linux Kernel Image */
+                       reg = <0x00040000 0x003c0000>;
+                       label = "NOR Linux Kernel Image";
+               };
+
+               partition@400000 {
+                       /* 27MB for Root file System */
+                       reg = <0x00400000 0x01b00000>;
+                       label = "NOR Root File System";
+               };
+
+               partition@1f00000 {
+                       /* This location must not be altered  */
+                       /* 512KB for u-boot Bootloader Image */
+                       /* 512KB for u-boot Environment Variables */
+                       reg = <0x01f00000 0x00100000>;
+                       label = "NOR U-Boot Image";
+                       read-only;
+               };
+       };
+};
+
+&soc {
+       i2c@3000 {
+               rtc@68 {
+                       compatible = "dallas,ds1339";
+                       reg = <0x68>;
+               };
+       };
+
+       mdio@24000 {
+               phy0: ethernet-phy@0 {
+                       interrupts = <3 1 0 0>;
+                       reg = <0x0>;
+               };
+               phy1: ethernet-phy@1 {
+                       interrupts = <2 1 0 0>;
+                       reg = <0x1>;
+               };
+               phy2: ethernet-phy@2 {
+                       interrupts = <1 1 0 0>;
+                       reg = <0x2>;
+               };
+       };
+
+       mdio@25000 {
+               tbi1: tbi-phy@11 {
+                       reg = <0x11>;
+                       device_type = "tbi-phy";
+               };
+       };
+
+       mdio@26000 {
+               tbi2: tbi-phy@11 {
+                       reg = <0x11>;
+                       device_type = "tbi-phy";
+               };
+       };
+
+       enet0: ethernet@b0000 {
+               phy-handle = <&phy2>;
+               phy-connection-type = "rgmii-id";
+       };
+
+       enet1: ethernet@b1000 {
+               phy-handle = <&phy0>;
+               tbi-handle = <&tbi1>;
+               phy-connection-type = "sgmii";
+       };
+
+       enet2: ethernet@b2000 {
+               phy-handle = <&phy1>;
+               phy-connection-type = "rgmii-id";
+       };
+
+       usb@22000 {
+               phy_type = "ulpi";
+       };
+
+       /* USB2 is shared with localbus, so it must be disabled
+          by default. We can't put 'status = "disabled";' here
+          since U-Boot doesn't clear the status property when
+          it enables USB2. OTOH, U-Boot does create a new node
+          when there isn't any. So, just comment it out.
+       */
+       usb@23000 {
+               status = "disabled";
+               phy_type = "ulpi";
+       };
+};
diff --git a/arch/powerpc/boot/dts/p1020utm-pc_32b.dts b/arch/powerpc/boot/dts/p1020utm-pc_32b.dts
new file mode 100644 (file)
index 0000000..4bfdd89
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * P1020 UTM-PC Device Tree Source (32-bit address map)
+ *
+ * Copyright 2012 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of Freescale Semiconductor nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/include/ "fsl/p1020si-pre.dtsi"
+/ {
+       model = "fsl,P1020UTM-PC";
+       compatible = "fsl,P1020UTM-PC";
+
+       memory {
+               device_type = "memory";
+       };
+
+       lbc: localbus@ffe05000 {
+               reg = <0x0 0xffe05000 0x0 0x1000>;
+
+               /* NOR */
+               ranges = <0x0 0x0 0x0 0xec000000 0x02000000
+                         0x1 0x0 0x0 0xffa00000 0x00040000
+                         0x2 0x0 0x0 0xffb00000 0x00020000>;
+       };
+
+       soc: soc@ffe00000 {
+               ranges = <0x0 0x0 0xffe00000 0x100000>;
+       };
+
+       pci0: pcie@ffe09000 {
+               reg = <0x0 0xffe09000 0x0 0x1000>;
+               ranges = <0x2000000 0x0 0xe0000000 0x0 0xa0000000 0x0 0x20000000
+                         0x1000000 0x0 0x00000000 0x0 0xffc10000 0x0 0x10000>;
+               pcie@0 {
+                       ranges = <0x2000000 0x0 0xe0000000
+                                 0x2000000 0x0 0xe0000000
+                                 0x0 0x20000000
+
+                                 0x1000000 0x0 0x0
+                                 0x1000000 0x0 0x0
+                                 0x0 0x100000>;
+               };
+       };
+
+       pci1: pcie@ffe0a000 {
+               reg = <0x0 0xffe0a000 0x0 0x1000>;
+               ranges = <0x2000000 0x0 0xe0000000 0x0 0x80000000 0x0 0x20000000
+                         0x1000000 0x0 0x00000000 0x0 0xffc00000 0x0 0x10000>;
+               pcie@0 {
+                       ranges = <0x2000000 0x0 0xe0000000
+                                 0x2000000 0x0 0xe0000000
+                                 0x0 0x20000000
+
+                                 0x1000000 0x0 0x0
+                                 0x1000000 0x0 0x0
+                                 0x0 0x100000>;
+               };
+       };
+};
+
+/include/ "p1020utm-pc.dtsi"
+/include/ "fsl/p1020si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/p1020utm-pc_36b.dts b/arch/powerpc/boot/dts/p1020utm-pc_36b.dts
new file mode 100644 (file)
index 0000000..abec535
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * P1020 UTM-PC Device Tree Source (36-bit address map)
+ *
+ * Copyright 2012 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of Freescale Semiconductor nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/include/ "fsl/p1020si-pre.dtsi"
+/ {
+       model = "fsl,P1020UTM-PC";
+       compatible = "fsl,P1020UTM-PC";
+
+       memory {
+               device_type = "memory";
+       };
+
+       lbc: localbus@fffe05000 {
+               reg = <0xf 0xffe05000 0x0 0x1000>;
+
+               /* NOR */
+               ranges = <0x0 0x0 0xf 0xec000000 0x02000000
+                         0x1 0x0 0xf 0xffa00000 0x00040000
+                         0x2 0x0 0xf 0xffb00000 0x00020000>;
+       };
+
+       soc: soc@fffe00000 {
+               ranges = <0x0 0xf 0xffe00000 0x100000>;
+       };
+
+       pci0: pcie@fffe09000 {
+               reg = <0xf 0xffe09000 0x0 0x1000>;
+               ranges = <0x2000000 0x0 0xe0000000 0xc 0x20000000 0x0 0x20000000
+                         0x1000000 0x0 0x00000000 0xf 0xffc10000 0x0 0x10000>;
+               pcie@0 {
+                       ranges = <0x2000000 0x0 0xe0000000
+                                 0x2000000 0x0 0xe0000000
+                                 0x0 0x20000000
+
+                                 0x1000000 0x0 0x0
+                                 0x1000000 0x0 0x0
+                                 0x0 0x100000>;
+               };
+       };
+
+       pci1: pcie@fffe0a000 {
+               reg = <0xf 0xffe0a000 0 0x1000>;
+               ranges = <0x2000000 0x0 0xe0000000 0xc 0x00000000 0x0 0x20000000
+                         0x1000000 0x0 0x00000000 0xf 0xffc00000 0x0 0x10000>;
+               pcie@0 {
+                       ranges = <0x2000000 0x0 0xe0000000
+                                 0x2000000 0x0 0xe0000000
+                                 0x0 0x20000000
+
+                                 0x1000000 0x0 0x0
+                                 0x1000000 0x0 0x0
+                                 0x0 0x100000>;
+               };
+       };
+};
+
+/include/ "p1020utm-pc.dtsi"
+/include/ "fsl/p1020si-post.dtsi"
index 4f957db..2852139 100644 (file)
                reg = <0xf 0xfe200000 0 0x1000>;
                ranges = <0x02000000 0 0xe0000000 0xc 0x00000000 0x0 0x20000000
                          0x01000000 0 0x00000000 0xf 0xf8000000 0x0 0x00010000>;
-               fsl,msi = <&msi0>;
                pcie@0 {
                        ranges = <0x02000000 0 0xe0000000
                                  0x02000000 0 0xe0000000
                reg = <0xf 0xfe201000 0 0x1000>;
                ranges = <0x02000000 0x0 0xe0000000 0xc 0x20000000 0x0 0x20000000
                          0x01000000 0x0 0x00000000 0xf 0xf8010000 0x0 0x00010000>;
-               fsl,msi = <&msi1>;
                pcie@0 {
                        ranges = <0x02000000 0 0xe0000000
                                  0x02000000 0 0xe0000000
                reg = <0xf 0xfe202000 0 0x1000>;
                ranges = <0x02000000 0 0xe0000000 0xc 0x40000000 0 0x20000000
                          0x01000000 0 0x00000000 0xf 0xf8020000 0 0x00010000>;
-               fsl,msi = <&msi2>;
                pcie@0 {
                        ranges = <0x02000000 0 0xe0000000
                                  0x02000000 0 0xe0000000
index f469145..22a215e 100644 (file)
                reg = <0xf 0xfe200000 0 0x1000>;
                ranges = <0x02000000 0 0xe0000000 0xc 0x00000000 0x0 0x20000000
                          0x01000000 0 0x00000000 0xf 0xf8000000 0x0 0x00010000>;
-               fsl,msi = <&msi0>;
                pcie@0 {
                        ranges = <0x02000000 0 0xe0000000
                                  0x02000000 0 0xe0000000
                reg = <0xf 0xfe201000 0 0x1000>;
                ranges = <0x02000000 0x0 0xe0000000 0xc 0x20000000 0x0 0x20000000
                          0x01000000 0x0 0x00000000 0xf 0xf8010000 0x0 0x00010000>;
-               fsl,msi = <&msi1>;
                pcie@0 {
                        ranges = <0x02000000 0 0xe0000000
                                  0x02000000 0 0xe0000000
                reg = <0xf 0xfe202000 0 0x1000>;
                ranges = <0x02000000 0 0xe0000000 0xc 0x40000000 0 0x20000000
                          0x01000000 0 0x00000000 0xf 0xf8020000 0 0x00010000>;
-               fsl,msi = <&msi2>;
                pcie@0 {
                        ranges = <0x02000000 0 0xe0000000
                                  0x02000000 0 0xe0000000
                reg = <0xf 0xfe203000 0 0x1000>;
                ranges = <0x02000000 0 0xe0000000 0xc 0x60000000 0 0x20000000
                          0x01000000 0 0x00000000 0xf 0xf8030000 0 0x00010000>;
-               fsl,msi = <&msi2>;
                pcie@0 {
                        ranges = <0x02000000 0 0xe0000000
                                  0x02000000 0 0xe0000000
index 529042e..9ae875c 100644 (file)
                reg = <0xf 0xfe200000 0 0x1000>;
                ranges = <0x02000000 0 0xe0000000 0xc 0x00000000 0x0 0x20000000
                          0x01000000 0 0x00000000 0xf 0xf8000000 0x0 0x00010000>;
-               fsl,msi = <&msi0>;
                pcie@0 {
                        ranges = <0x02000000 0 0xe0000000
                                  0x02000000 0 0xe0000000
                reg = <0xf 0xfe201000 0 0x1000>;
                ranges = <0x02000000 0x0 0xe0000000 0xc 0x20000000 0x0 0x20000000
                          0x01000000 0x0 0x00000000 0xf 0xf8010000 0x0 0x00010000>;
-               fsl,msi = <&msi1>;
                pcie@0 {
                        ranges = <0x02000000 0 0xe0000000
                                  0x02000000 0 0xe0000000
index 6d60e54..3e20460 100644 (file)
                reg = <0xf 0xfe200000 0 0x1000>;
                ranges = <0x02000000 0 0xe0000000 0xc 0x00000000 0x0 0x20000000
                          0x01000000 0 0x00000000 0xf 0xf8000000 0x0 0x00010000>;
-               fsl,msi = <&msi0>;
                pcie@0 {
                        ranges = <0x02000000 0 0xe0000000
                                  0x02000000 0 0xe0000000
                reg = <0xf 0xfe201000 0 0x1000>;
                ranges = <0x02000000 0x0 0xe0000000 0xc 0x20000000 0x0 0x20000000
                          0x01000000 0x0 0x00000000 0xf 0xf8010000 0x0 0x00010000>;
-               fsl,msi = <&msi1>;
                pcie@0 {
                        ranges = <0x02000000 0 0xe0000000
                                  0x02000000 0 0xe0000000
                reg = <0xf 0xfe202000 0 0x1000>;
                ranges = <0x02000000 0 0xe0000000 0xc 0x40000000 0 0x20000000
                          0x01000000 0 0x00000000 0xf 0xf8020000 0 0x00010000>;
-               fsl,msi = <&msi2>;
                pcie@0 {
                        ranges = <0x02000000 0 0xe0000000
                                  0x02000000 0 0xe0000000
index 1c25068..27c07ed 100644 (file)
                reg = <0xf 0xfe200000 0 0x1000>;
                ranges = <0x02000000 0 0xe0000000 0xc 0x00000000 0x0 0x20000000
                          0x01000000 0 0x00000000 0xf 0xf8000000 0x0 0x00010000>;
-               fsl,msi = <&msi0>;
                pcie@0 {
                        ranges = <0x02000000 0 0xe0000000
                                  0x02000000 0 0xe0000000
                reg = <0xf 0xfe201000 0 0x1000>;
                ranges = <0x02000000 0x0 0xe0000000 0xc 0x20000000 0x0 0x20000000
                          0x01000000 0x0 0x00000000 0xf 0xf8010000 0x0 0x00010000>;
-               fsl,msi = <&msi1>;
                pcie@0 {
                        ranges = <0x02000000 0 0xe0000000
                                  0x02000000 0 0xe0000000
                reg = <0xf 0xfe202000 0 0x1000>;
                ranges = <0x02000000 0 0xe0000000 0xc 0x40000000 0 0x20000000
                          0x01000000 0 0x00000000 0xf 0xf8020000 0 0x00010000>;
-               fsl,msi = <&msi2>;
                pcie@0 {
                        ranges = <0x02000000 0 0xe0000000
                                  0x02000000 0 0xe0000000
                reg = <0xf 0xfe203000 0 0x1000>;
                ranges = <0x02000000 0 0xe0000000 0xc 0x60000000 0 0x20000000
                          0x01000000 0 0x00000000 0xf 0xf8030000 0 0x00010000>;
-               fsl,msi = <&msi2>;
                pcie@0 {
                        ranges = <0x02000000 0 0xe0000000
                                  0x02000000 0 0xe0000000
index f8aef20..91db656 100644 (file)
@@ -116,6 +116,7 @@ CONFIG_SERIAL_8250_RSA=y
 CONFIG_HW_RANDOM=y
 CONFIG_NVRAM=y
 CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
 CONFIG_I2C_MPC=y
 CONFIG_SPI=y
 CONFIG_SPI_GPIO=y
index 82b13bf..6798343 100644 (file)
@@ -71,6 +71,8 @@ CONFIG_SERIAL_8250_MANY_PORTS=y
 CONFIG_SERIAL_8250_DETECT_IRQ=y
 CONFIG_SERIAL_8250_RSA=y
 CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_MPC=y
 # CONFIG_HWMON is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=y
 # CONFIG_HID_SUPPORT is not set
index cc87a84..d6b6df5 100644 (file)
@@ -117,6 +117,7 @@ CONFIG_SERIAL_8250_RSA=y
 CONFIG_SERIAL_QE=m
 CONFIG_NVRAM=y
 CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
 CONFIG_I2C_CPM=m
 CONFIG_I2C_MPC=y
 CONFIG_SPI=y
index 48d6682..5b0e292 100644 (file)
@@ -119,6 +119,7 @@ CONFIG_SERIAL_8250_RSA=y
 CONFIG_SERIAL_QE=m
 CONFIG_NVRAM=y
 CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
 CONFIG_I2C_CPM=m
 CONFIG_I2C_MPC=y
 CONFIG_SPI=y
index f3b0c2c..976835d 100644 (file)
  * whether they will be clobbered.
  *
  * Note that r11 can be used as an output parameter.
+ *
+ * The "memory" clobber is only necessary for hcalls where the Hypervisor
+ * will read or write guest memory. However, we add it to all hcalls because
+ * the impact is minimal, and we want to ensure that it's present for the
+ * hcalls that need it.
 */
 
 /* List of common clobbered registers.  Do not use this macro. */
-#define EV_HCALL_CLOBBERS "r0", "r12", "xer", "ctr", "lr", "cc"
+#define EV_HCALL_CLOBBERS "r0", "r12", "xer", "ctr", "lr", "cc", "memory"
 
 #define EV_HCALL_CLOBBERS8 EV_HCALL_CLOBBERS
 #define EV_HCALL_CLOBBERS7 EV_HCALL_CLOBBERS8, "r10"
index ce04530..aa4c488 100644 (file)
 #define __ASM_POWERPC_FSL_GUTS_H__
 #ifdef __KERNEL__
 
-/*
- * These #ifdefs are safe because it's not possible to build a kernel that
- * runs on e500 and e600 cores.
- */
-
-#if !defined(CONFIG_PPC_85xx) && !defined(CONFIG_PPC_86xx)
-#error Only 85xx and 86xx SOCs are supported
-#endif
-
 /**
  * Global Utility Registers.
  *
  * different names.  In these cases, one name is chosen to avoid extraneous
  * #ifdefs.
  */
-#ifdef CONFIG_PPC_85xx
-struct ccsr_guts_85xx {
-#else
-struct ccsr_guts_86xx {
-#endif
+struct ccsr_guts {
        __be32  porpllsr;       /* 0x.0000 - POR PLL Ratio Status Register */
        __be32  porbmsr;        /* 0x.0004 - POR Boot Mode Status Register */
        __be32  porimpscr;      /* 0x.0008 - POR I/O Impedance Status and Control Register */
@@ -77,11 +64,8 @@ struct ccsr_guts_86xx {
        u8      res0a8[0xb0 - 0xa8];
        __be32  rstcr;          /* 0x.00b0 - Reset Control Register */
        u8      res0b4[0xc0 - 0xb4];
-#ifdef CONFIG_PPC_85xx
-       __be32  iovselsr;       /* 0x.00c0 - I/O voltage select status register */
-#else
-       __be32  elbcvselcr;     /* 0x.00c0 - eLBC Voltage Select Ctrl Reg */
-#endif
+       __be32  iovselsr;       /* 0x.00c0 - I/O voltage select status register
+                                            Called 'elbcvselcr' on 86xx SOCs */
        u8      res0c4[0x224 - 0xc4];
        __be32  iodelay1;       /* 0x.0224 - IO delay control register 1 */
        __be32  iodelay2;       /* 0x.0228 - IO delay control register 2 */
@@ -136,7 +120,7 @@ struct ccsr_guts_86xx {
  * ch: The channel on the DMA controller (0, 1, 2, or 3)
  * device: The device to set as the source (CCSR_GUTS_DMACR_DEV_xx)
  */
-static inline void guts_set_dmacr(struct ccsr_guts_86xx __iomem *guts,
+static inline void guts_set_dmacr(struct ccsr_guts __iomem *guts,
        unsigned int co, unsigned int ch, unsigned int device)
 {
        unsigned int shift = 16 + (8 * (1 - co) + 2 * (3 - ch));
@@ -172,7 +156,7 @@ static inline void guts_set_dmacr(struct ccsr_guts_86xx __iomem *guts,
  * ch: The channel on the DMA controller (0, 1, 2, or 3)
  * value: the new value for the bit (0 or 1)
  */
-static inline void guts_set_pmuxcr_dma(struct ccsr_guts_86xx __iomem *guts,
+static inline void guts_set_pmuxcr_dma(struct ccsr_guts __iomem *guts,
        unsigned int co, unsigned int ch, unsigned int value)
 {
        if ((ch == 0) || (ch == 3)) {
index cfe7a38..18bdf74 100644 (file)
@@ -40,6 +40,8 @@
 #include <asm/prom.h>
 #include <asm/rtas.h>
 #include <asm/fadump.h>
+#include <asm/debug.h>
+#include <asm/setup.h>
 
 static struct fw_dump fw_dump;
 static struct fadump_mem_struct fdm;
index 76a6e40..782bd0a 100644 (file)
@@ -24,6 +24,7 @@
 #include <asm/current.h>
 #include <asm/processor.h>
 #include <asm/machdep.h>
+#include <asm/debug.h>
 
 /*
  * This table contains the mapping between PowerPC hardware trap types, and
index f1950d1..135663a 100644 (file)
@@ -21,6 +21,7 @@
 #include <asm/disassemble.h>
 #include <asm/kvm_book3s.h>
 #include <asm/reg.h>
+#include <asm/switch_to.h>
 
 #define OP_19_XOP_RFID         18
 #define OP_19_XOP_RFI          50
index e70ef2d..a59a25a 100644 (file)
@@ -24,6 +24,7 @@
 #include <asm/kvm_fpu.h>
 #include <asm/reg.h>
 #include <asm/cacheflush.h>
+#include <asm/switch_to.h>
 #include <linux/vmalloc.h>
 
 /* #define DEBUG */
index 7340e10..642d885 100644 (file)
@@ -33,6 +33,7 @@
 #include <asm/kvm_ppc.h>
 #include <asm/kvm_book3s.h>
 #include <asm/mmu_context.h>
+#include <asm/switch_to.h>
 #include <linux/gfp.h>
 #include <linux/sched.h>
 #include <linux/vmalloc.h>
index bfb11e0..e2d401a 100644 (file)
@@ -93,7 +93,7 @@ struct mpc52xx_pci {
 };
 
 /* MPC5200 device tree match tables */
-const struct of_device_id mpc52xx_pci_ids[] __initdata = {
+const struct of_device_id mpc52xx_pci_ids[] __initconst = {
        { .type = "pci", .compatible = "fsl,mpc5200-pci", },
        { .type = "pci", .compatible = "mpc5200-pci", },
        {}
index 3754ddc..9a6f044 100644 (file)
@@ -270,7 +270,7 @@ static void __init mpc85xx_mds_qe_init(void)
 
        if (machine_is(p1021_mds)) {
 
-               struct ccsr_guts_85xx __iomem *guts;
+               struct ccsr_guts __iomem *guts;
 
                np = of_find_node_by_name(NULL, "global-utilities");
                if (np) {
index 9848f9e..313fce4 100644 (file)
@@ -127,7 +127,7 @@ static void __init mpc85xx_rdb_setup_arch(void)
 #if defined(CONFIG_UCC_GETH) || defined(CONFIG_SERIAL_QE)
        if (machine_is(p1025_rdb)) {
 
-               struct ccsr_guts_85xx __iomem *guts;
+               struct ccsr_guts __iomem *guts;
 
                np = of_find_node_by_name(NULL, "global-utilities");
                if (np) {
index 0fe88e3..e74b7cd 100644 (file)
@@ -150,7 +150,7 @@ static void p1022ds_set_monitor_port(enum fsl_diu_monitor_port port)
 {
        struct device_node *guts_node;
        struct device_node *indirect_node = NULL;
-       struct ccsr_guts_85xx __iomem *guts;
+       struct ccsr_guts __iomem *guts;
        u8 __iomem *lbc_lcs0_ba = NULL;
        u8 __iomem *lbc_lcs1_ba = NULL;
        u8 b;
@@ -269,7 +269,7 @@ exit:
 void p1022ds_set_pixel_clock(unsigned int pixclock)
 {
        struct device_node *guts_np = NULL;
-       struct ccsr_guts_85xx __iomem *guts;
+       struct ccsr_guts __iomem *guts;
        unsigned long freq;
        u64 temp;
        u32 pxclk;
index bbc6152..62cd3c5 100644 (file)
@@ -225,7 +225,7 @@ void mpc8610hpcd_set_monitor_port(enum fsl_diu_monitor_port port)
 void mpc8610hpcd_set_pixel_clock(unsigned int pixclock)
 {
        struct device_node *guts_np = NULL;
-       struct ccsr_guts_86xx __iomem *guts;
+       struct ccsr_guts __iomem *guts;
        unsigned long freq;
        u64 temp;
        u32 pxclk;
index 7f9b674..6e3409d 100644 (file)
@@ -61,7 +61,7 @@ static void qpace_progress(char *s, unsigned short hex)
        printk("*** %04x : %s\n", hex, s ? s : "");
 }
 
-static const struct of_device_id qpace_bus_ids[] __initdata = {
+static const struct of_device_id qpace_bus_ids[] __initconst = {
        { .type = "soc", },
        { .compatible = "soc", },
        { .type = "spider", },
index fa3e294..4ab0876 100644 (file)
@@ -140,7 +140,7 @@ static int __devinit cell_setup_phb(struct pci_controller *phb)
        return 0;
 }
 
-static const struct of_device_id cell_bus_ids[] __initdata = {
+static const struct of_device_id cell_bus_ids[] __initconst = {
        { .type = "soc", },
        { .compatible = "soc", },
        { .type = "spider", },
index 4a47525..4cb375c 100644 (file)
@@ -59,8 +59,7 @@ static int eeh_event_handler(void * dummy)
        struct eeh_event *event;
        struct eeh_dev *edev;
 
-       daemonize("eehd");
-       set_current_state(TASK_INTERRUPTIBLE);
+       set_task_comm(current, "eehd");
 
        spin_lock_irqsave(&eeh_eventlist_lock, flags);
        event = NULL;
@@ -83,6 +82,7 @@ static int eeh_event_handler(void * dummy)
        printk(KERN_INFO "EEH: Detected PCI bus error on device %s\n",
               eeh_pci_name(edev->pdev));
 
+       set_current_state(TASK_INTERRUPTIBLE);  /* Don't add to load average */
        edev = handle_eeh_events(event);
 
        eeh_clear_slot(eeh_dev_to_of_node(edev), EEH_MODE_RECOVERING);
index ceb09cb..818e763 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006 Freescale Semicondutor, Inc. All rights reserved.
+ * Copyright (C) 2006-2010 Freescale Semicondutor, Inc. All rights reserved.
  *
  * Authors:    Shlomi Gridish <gridish@freescale.com>
  *             Li Yang <leoli@freescale.com>
@@ -266,7 +266,19 @@ EXPORT_SYMBOL(qe_clock_source);
 static void qe_snums_init(void)
 {
        int i;
-       static const u8 snum_init[] = {
+       static const u8 snum_init_76[] = {
+               0x04, 0x05, 0x0C, 0x0D, 0x14, 0x15, 0x1C, 0x1D,
+               0x24, 0x25, 0x2C, 0x2D, 0x34, 0x35, 0x88, 0x89,
+               0x98, 0x99, 0xA8, 0xA9, 0xB8, 0xB9, 0xC8, 0xC9,
+               0xD8, 0xD9, 0xE8, 0xE9, 0x44, 0x45, 0x4C, 0x4D,
+               0x54, 0x55, 0x5C, 0x5D, 0x64, 0x65, 0x6C, 0x6D,
+               0x74, 0x75, 0x7C, 0x7D, 0x84, 0x85, 0x8C, 0x8D,
+               0x94, 0x95, 0x9C, 0x9D, 0xA4, 0xA5, 0xAC, 0xAD,
+               0xB4, 0xB5, 0xBC, 0xBD, 0xC4, 0xC5, 0xCC, 0xCD,
+               0xD4, 0xD5, 0xDC, 0xDD, 0xE4, 0xE5, 0xEC, 0xED,
+               0xF4, 0xF5, 0xFC, 0xFD,
+       };
+       static const u8 snum_init_46[] = {
                0x04, 0x05, 0x0C, 0x0D, 0x14, 0x15, 0x1C, 0x1D,
                0x24, 0x25, 0x2C, 0x2D, 0x34, 0x35, 0x88, 0x89,
                0x98, 0x99, 0xA8, 0xA9, 0xB8, 0xB9, 0xC8, 0xC9,
@@ -274,9 +286,15 @@ static void qe_snums_init(void)
                0x28, 0x29, 0x38, 0x39, 0x48, 0x49, 0x58, 0x59,
                0x68, 0x69, 0x78, 0x79, 0x80, 0x81,
        };
+       static const u8 *snum_init;
 
        qe_num_of_snum = qe_get_num_of_snums();
 
+       if (qe_num_of_snum == 76)
+               snum_init = snum_init_76;
+       else
+               snum_init = snum_init_46;
+
        for (i = 0; i < qe_num_of_snum; i++) {
                snums[i].num = snum_init[i];
                snums[i].state = QE_SNUM_STATE_FREE;
index a19c8a0..35e4367 100644 (file)
@@ -104,11 +104,11 @@ static int irq_choose_cpu(const struct cpumask *affinity)
 {
        cpumask_t mask;
 
-       cpus_and(mask, cpu_online_map, *affinity);
-       if (cpus_equal(mask, cpu_online_map) || cpus_empty(mask))
+       cpumask_and(&mask, cpu_online_mask, affinity);
+       if (cpumask_equal(&mask, cpu_online_mask) || cpumask_empty(&mask))
                return boot_cpu_id;
        else
-               return first_cpu(mask);
+               return cpumask_first(&mask);
 }
 #else
 #define irq_choose_cpu(affinity) boot_cpu_id
index 5f85d8b..92a94f4 100644 (file)
@@ -1100,7 +1100,7 @@ EXPORT_SYMBOL(hash_for_home_map);
 
 /*
  * cpu_cacheable_map lists all the cpus whose caches the hypervisor can
- * flush on our behalf.  It is set to cpu_possible_map OR'ed with
+ * flush on our behalf.  It is set to cpu_possible_mask OR'ed with
  * hash_for_home_map, and it is what should be passed to
  * hv_flush_remote() to flush all caches.  Note that if there are
  * dedicated hypervisor driver tiles that have authorized use of their
@@ -1186,7 +1186,7 @@ static void __init setup_cpu_maps(void)
                              sizeof(cpu_lotar_map));
        if (rc < 0) {
                pr_err("warning: no HV_INQ_TILES_LOTAR; using AVAIL\n");
-               cpu_lotar_map = cpu_possible_map;
+               cpu_lotar_map = *cpu_possible_mask;
        }
 
 #if CHIP_HAS_CBOX_HOME_MAP()
@@ -1196,9 +1196,9 @@ static void __init setup_cpu_maps(void)
                              sizeof(hash_for_home_map));
        if (rc < 0)
                early_panic("hv_inquire_tiles(HFH_CACHE) failed: rc %d\n", rc);
-       cpumask_or(&cpu_cacheable_map, &cpu_possible_map, &hash_for_home_map);
+       cpumask_or(&cpu_cacheable_map, cpu_possible_mask, &hash_for_home_map);
 #else
-       cpu_cacheable_map = cpu_possible_map;
+       cpu_cacheable_map = *cpu_possible_mask;
 #endif
 }
 
index 2e9852c..0a9e57e 100644 (file)
@@ -41,7 +41,7 @@ static int __init start_kernel_proc(void *unused)
        cpu_tasks[0].pid = pid;
        cpu_tasks[0].task = current;
 #ifdef CONFIG_SMP
-       cpu_online_map = cpumask_of_cpu(0);
+       init_cpu_online(get_cpu_mask(0));
 #endif
        start_kernel();
        return 0;
index 155206a..6f588e1 100644 (file)
@@ -76,7 +76,7 @@ static int idle_proc(void *cpup)
                cpu_relax();
 
        notify_cpu_starting(cpu);
-       cpu_set(cpu, cpu_online_map);
+       set_cpu_online(cpu, true);
        default_idle();
        return 0;
 }
@@ -110,8 +110,7 @@ void smp_prepare_cpus(unsigned int maxcpus)
        for (i = 0; i < ncpus; ++i)
                set_cpu_possible(i, true);
 
-       cpu_clear(me, cpu_online_map);
-       cpu_set(me, cpu_online_map);
+       set_cpu_online(me, true);
        cpu_set(me, cpu_callin_map);
 
        err = os_pipe(cpu_data[me].ipi_pipe, 1, 1);
@@ -138,13 +137,13 @@ void smp_prepare_cpus(unsigned int maxcpus)
 
 void smp_prepare_boot_cpu(void)
 {
-       cpu_set(smp_processor_id(), cpu_online_map);
+       set_cpu_online(smp_processor_id(), true);
 }
 
 int __cpu_up(unsigned int cpu)
 {
        cpu_set(cpu, smp_commenced_mask);
-       while (!cpu_isset(cpu, cpu_online_map))
+       while (!cpu_online(cpu))
                mb();
        return 0;
 }
index 5671752..5a5b6e4 100644 (file)
@@ -289,7 +289,7 @@ void bpf_jit_compile(struct sk_filter *fp)
                                        EMIT2(0x24, K & 0xFF); /* and imm8,%al */
                                } else if (K >= 0xFFFF0000) {
                                        EMIT2(0x66, 0x25);      /* and imm16,%ax */
-                                       EMIT2(K, 2);
+                                       EMIT(K, 2);
                                } else {
                                        EMIT1_off32(0x25, K);   /* and imm32,%eax */
                                }
index b132ade..4f51beb 100644 (file)
@@ -967,7 +967,7 @@ void xen_setup_shared_info(void)
        xen_setup_mfn_list_list();
 }
 
-/* This is called once we have the cpu_possible_map */
+/* This is called once we have the cpu_possible_mask */
 void xen_setup_vcpu_info_placement(void)
 {
        int cpu;
index a0f768c..8d3a056 100644 (file)
@@ -613,8 +613,7 @@ out:
        return err;
 }
 
-static struct crypto_alg *crypto_lookup_skcipher(const char *name, u32 type,
-                                                u32 mask)
+struct crypto_alg *crypto_lookup_skcipher(const char *name, u32 type, u32 mask)
 {
        struct crypto_alg *alg;
 
@@ -652,6 +651,7 @@ static struct crypto_alg *crypto_lookup_skcipher(const char *name, u32 type,
 
        return ERR_PTR(crypto_givcipher_default(alg, type, mask));
 }
+EXPORT_SYMBOL_GPL(crypto_lookup_skcipher);
 
 int crypto_grab_skcipher(struct crypto_skcipher_spawn *spawn, const char *name,
                         u32 type, u32 mask)
index 04add3d..e4cb351 100644 (file)
@@ -470,8 +470,7 @@ out:
        return err;
 }
 
-static struct crypto_alg *crypto_lookup_aead(const char *name, u32 type,
-                                            u32 mask)
+struct crypto_alg *crypto_lookup_aead(const char *name, u32 type, u32 mask)
 {
        struct crypto_alg *alg;
 
@@ -503,6 +502,7 @@ static struct crypto_alg *crypto_lookup_aead(const char *name, u32 type,
 
        return ERR_PTR(crypto_nivaead_default(alg, type, mask));
 }
+EXPORT_SYMBOL_GPL(crypto_lookup_aead);
 
 int crypto_grab_aead(struct crypto_aead_spawn *spawn, const char *name,
                     u32 type, u32 mask)
index f76e42b..f1ea0a0 100644 (file)
 #include <linux/module.h>
 #include <linux/crypto.h>
 #include <linux/cryptouser.h>
+#include <linux/sched.h>
 #include <net/netlink.h>
 #include <linux/security.h>
 #include <net/net_namespace.h>
+#include <crypto/internal/aead.h>
+#include <crypto/internal/skcipher.h>
+
 #include "internal.h"
 
 DEFINE_MUTEX(crypto_cfg_mutex);
@@ -301,6 +305,60 @@ static int crypto_del_alg(struct sk_buff *skb, struct nlmsghdr *nlh,
        return crypto_unregister_instance(alg);
 }
 
+static struct crypto_alg *crypto_user_skcipher_alg(const char *name, u32 type,
+                                                  u32 mask)
+{
+       int err;
+       struct crypto_alg *alg;
+
+       type = crypto_skcipher_type(type);
+       mask = crypto_skcipher_mask(mask);
+
+       for (;;) {
+               alg = crypto_lookup_skcipher(name,  type, mask);
+               if (!IS_ERR(alg))
+                       return alg;
+
+               err = PTR_ERR(alg);
+               if (err != -EAGAIN)
+                       break;
+               if (signal_pending(current)) {
+                       err = -EINTR;
+                       break;
+               }
+       }
+
+       return ERR_PTR(err);
+}
+
+static struct crypto_alg *crypto_user_aead_alg(const char *name, u32 type,
+                                              u32 mask)
+{
+       int err;
+       struct crypto_alg *alg;
+
+       type &= ~(CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_GENIV);
+       type |= CRYPTO_ALG_TYPE_AEAD;
+       mask &= ~(CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_GENIV);
+       mask |= CRYPTO_ALG_TYPE_MASK;
+
+       for (;;) {
+               alg = crypto_lookup_aead(name,  type, mask);
+               if (!IS_ERR(alg))
+                       return alg;
+
+               err = PTR_ERR(alg);
+               if (err != -EAGAIN)
+                       break;
+               if (signal_pending(current)) {
+                       err = -EINTR;
+                       break;
+               }
+       }
+
+       return ERR_PTR(err);
+}
+
 static int crypto_add_alg(struct sk_buff *skb, struct nlmsghdr *nlh,
                          struct nlattr **attrs)
 {
@@ -325,7 +383,19 @@ static int crypto_add_alg(struct sk_buff *skb, struct nlmsghdr *nlh,
        else
                name = p->cru_name;
 
-       alg = crypto_alg_mod_lookup(name, p->cru_type, p->cru_mask);
+       switch (p->cru_type & p->cru_mask & CRYPTO_ALG_TYPE_MASK) {
+       case CRYPTO_ALG_TYPE_AEAD:
+               alg = crypto_user_aead_alg(name, p->cru_type, p->cru_mask);
+               break;
+       case CRYPTO_ALG_TYPE_GIVCIPHER:
+       case CRYPTO_ALG_TYPE_BLKCIPHER:
+       case CRYPTO_ALG_TYPE_ABLKCIPHER:
+               alg = crypto_user_skcipher_alg(name, p->cru_type, p->cru_mask);
+               break;
+       default:
+               alg = crypto_alg_mod_lookup(name, p->cru_type, p->cru_mask);
+       }
+
        if (IS_ERR(alg))
                return PTR_ERR(alg);
 
@@ -387,12 +457,20 @@ static int crypto_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
 
        if ((type == (CRYPTO_MSG_GETALG - CRYPTO_MSG_BASE) &&
            (nlh->nlmsg_flags & NLM_F_DUMP))) {
+               struct crypto_alg *alg;
+               u16 dump_alloc = 0;
+
                if (link->dump == NULL)
                        return -EINVAL;
+
+               list_for_each_entry(alg, &crypto_alg_list, cra_list)
+                       dump_alloc += CRYPTO_REPORT_MAXSIZE;
+
                {
                        struct netlink_dump_control c = {
                                .dump = link->dump,
                                .done = link->done,
+                               .min_dump_alloc = dump_alloc,
                        };
                        return netlink_dump_start(crypto_nlsk, skb, nlh, &c);
                }
index 29a89da..b2c99dc 100644 (file)
@@ -280,11 +280,11 @@ static int pcrypt_aead_init_tfm(struct crypto_tfm *tfm)
 
        ictx->tfm_count++;
 
-       cpu_index = ictx->tfm_count % cpumask_weight(cpu_active_mask);
+       cpu_index = ictx->tfm_count % cpumask_weight(cpu_online_mask);
 
-       ctx->cb_cpu = cpumask_first(cpu_active_mask);
+       ctx->cb_cpu = cpumask_first(cpu_online_mask);
        for (cpu = 0; cpu < cpu_index; cpu++)
-               ctx->cb_cpu = cpumask_next(ctx->cb_cpu, cpu_active_mask);
+               ctx->cb_cpu = cpumask_next(ctx->cb_cpu, cpu_online_mask);
 
        cipher = crypto_spawn_aead(crypto_instance_ctx(inst));
 
@@ -472,7 +472,7 @@ static int pcrypt_init_padata(struct padata_pcrypt *pcrypt,
                goto err_free_padata;
        }
 
-       cpumask_and(mask->mask, cpu_possible_mask, cpu_active_mask);
+       cpumask_and(mask->mask, cpu_possible_mask, cpu_online_mask);
        rcu_assign_pointer(pcrypt->cb_cpumask, mask);
 
        pcrypt->nblock.notifier_call = pcrypt_cpumask_change_notify;
index 6f0459c..d236aef 100644 (file)
@@ -50,6 +50,8 @@ source "drivers/i2c/Kconfig"
 
 source "drivers/spi/Kconfig"
 
+source "drivers/hsi/Kconfig"
+
 source "drivers/pps/Kconfig"
 
 source "drivers/ptp/Kconfig"
index 262b19d..95952c8 100644 (file)
@@ -53,6 +53,7 @@ obj-$(CONFIG_ATA)             += ata/
 obj-$(CONFIG_TARGET_CORE)      += target/
 obj-$(CONFIG_MTD)              += mtd/
 obj-$(CONFIG_SPI)              += spi/
+obj-y                          += hsi/
 obj-y                          += net/
 obj-$(CONFIG_ATM)              += atm/
 obj-$(CONFIG_FUSION)           += message/
index a22ffa5..0bf1b89 100644 (file)
@@ -142,7 +142,7 @@ static int __cpuinit db8500_cpufreq_init(struct cpufreq_policy *policy)
        policy->cpuinfo.transition_latency = 20 * 1000; /* in ns */
 
        /* policy sharing between dual CPUs */
-       cpumask_copy(policy->cpus, &cpu_present_map);
+       cpumask_copy(policy->cpus, cpu_present_mask);
 
        policy->shared_type = CPUFREQ_SHARED_TYPE_ALL;
 
index cc11488..e354bc0 100644 (file)
@@ -9,6 +9,7 @@ menuconfig DRM
        depends on (AGP || AGP=n) && !EMULATED_CMPXCHG && MMU
        select I2C
        select I2C_ALGOBIT
+       select DMA_SHARED_BUFFER
        help
          Kernel-level support for the Direct Rendering Infrastructure (DRI)
          introduced in XFree86 4.0. If you say Y here, you need to select
index a858532..c20da5b 100644 (file)
@@ -12,7 +12,7 @@ drm-y       :=        drm_auth.o drm_buffer.o drm_bufs.o drm_cache.o \
                drm_platform.o drm_sysfs.o drm_hashtab.o drm_mm.o \
                drm_crtc.o drm_modes.o drm_edid.o \
                drm_info.o drm_debugfs.o drm_encoder_slave.o \
-               drm_trace_points.o drm_global.o
+               drm_trace_points.o drm_global.o drm_prime.o
 
 drm-$(CONFIG_COMPAT) += drm_ioc32.o
 
index 0b65fbc..6116e3b 100644 (file)
@@ -136,6 +136,10 @@ static struct drm_ioctl_desc drm_ioctls[] = {
        DRM_IOCTL_DEF(DRM_IOCTL_GEM_OPEN, drm_gem_open_ioctl, DRM_AUTH|DRM_UNLOCKED),
 
        DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETRESOURCES, drm_mode_getresources, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+
+       DRM_IOCTL_DEF(DRM_IOCTL_PRIME_HANDLE_TO_FD, drm_prime_handle_to_fd_ioctl, DRM_AUTH|DRM_UNLOCKED),
+       DRM_IOCTL_DEF(DRM_IOCTL_PRIME_FD_TO_HANDLE, drm_prime_fd_to_handle_ioctl, DRM_AUTH|DRM_UNLOCKED),
+
        DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANERESOURCES, drm_mode_getplane_res, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
        DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCRTC, drm_mode_getcrtc, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
        DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETCRTC, drm_mode_setcrtc, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
index 7348a3d..cdfbf27 100644 (file)
@@ -271,6 +271,9 @@ static int drm_open_helper(struct inode *inode, struct file *filp,
        if (dev->driver->driver_features & DRIVER_GEM)
                drm_gem_open(dev, priv);
 
+       if (drm_core_check_feature(dev, DRIVER_PRIME))
+               drm_prime_init_file_private(&priv->prime);
+
        if (dev->driver->open) {
                ret = dev->driver->open(dev, priv);
                if (ret < 0)
@@ -571,6 +574,10 @@ int drm_release(struct inode *inode, struct file *filp)
 
        if (dev->driver->postclose)
                dev->driver->postclose(dev, file_priv);
+
+       if (drm_core_check_feature(dev, DRIVER_PRIME))
+               drm_prime_destroy_file_private(&file_priv->prime);
+
        kfree(file_priv);
 
        /* ========================================================
index 0ef358e..83114b5 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/mman.h>
 #include <linux/pagemap.h>
 #include <linux/shmem_fs.h>
+#include <linux/dma-buf.h>
 #include "drmP.h"
 
 /** @file drm_gem.c
@@ -232,6 +233,10 @@ drm_gem_handle_delete(struct drm_file *filp, u32 handle)
        idr_remove(&filp->object_idr, handle);
        spin_unlock(&filp->table_lock);
 
+       if (obj->import_attach)
+               drm_prime_remove_imported_buf_handle(&filp->prime,
+                               obj->import_attach->dmabuf);
+
        if (dev->driver->gem_close_object)
                dev->driver->gem_close_object(obj, filp);
        drm_gem_object_handle_unreference_unlocked(obj);
@@ -527,6 +532,10 @@ drm_gem_object_release_handle(int id, void *ptr, void *data)
        struct drm_gem_object *obj = ptr;
        struct drm_device *dev = obj->dev;
 
+       if (obj->import_attach)
+               drm_prime_remove_imported_buf_handle(&file_priv->prime,
+                               obj->import_attach->dmabuf);
+
        if (dev->driver->gem_close_object)
                dev->driver->gem_close_object(obj, file_priv);
 
diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
new file mode 100644 (file)
index 0000000..1bdf2b5
--- /dev/null
@@ -0,0 +1,304 @@
+/*
+ * Copyright Â© 2012 Red Hat
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ *      Dave Airlie <airlied@redhat.com>
+ *      Rob Clark <rob.clark@linaro.org>
+ *
+ */
+
+#include <linux/export.h>
+#include <linux/dma-buf.h>
+#include "drmP.h"
+
+/*
+ * DMA-BUF/GEM Object references and lifetime overview:
+ *
+ * On the export the dma_buf holds a reference to the exporting GEM
+ * object. It takes this reference in handle_to_fd_ioctl, when it
+ * first calls .prime_export and stores the exporting GEM object in
+ * the dma_buf priv. This reference is released when the dma_buf
+ * object goes away in the driver .release function.
+ *
+ * On the import the importing GEM object holds a reference to the
+ * dma_buf (which in turn holds a ref to the exporting GEM object).
+ * It takes that reference in the fd_to_handle ioctl.
+ * It calls dma_buf_get, creates an attachment to it and stores the
+ * attachment in the GEM object. When this attachment is destroyed
+ * when the imported object is destroyed, we remove the attachment
+ * and drop the reference to the dma_buf.
+ *
+ * Thus the chain of references always flows in one direction
+ * (avoiding loops): importing_gem -> dmabuf -> exporting_gem
+ *
+ * Self-importing: if userspace is using PRIME as a replacement for flink
+ * then it will get a fd->handle request for a GEM object that it created.
+ * Drivers should detect this situation and return back the gem object
+ * from the dma-buf private.
+ */
+
+struct drm_prime_member {
+       struct list_head entry;
+       struct dma_buf *dma_buf;
+       uint32_t handle;
+};
+
+int drm_gem_prime_handle_to_fd(struct drm_device *dev,
+               struct drm_file *file_priv, uint32_t handle, uint32_t flags,
+               int *prime_fd)
+{
+       struct drm_gem_object *obj;
+       void *buf;
+
+       obj = drm_gem_object_lookup(dev, file_priv, handle);
+       if (!obj)
+               return -ENOENT;
+
+       mutex_lock(&file_priv->prime.lock);
+       /* re-export the original imported object */
+       if (obj->import_attach) {
+               get_dma_buf(obj->import_attach->dmabuf);
+               *prime_fd = dma_buf_fd(obj->import_attach->dmabuf, flags);
+               drm_gem_object_unreference_unlocked(obj);
+               mutex_unlock(&file_priv->prime.lock);
+               return 0;
+       }
+
+       if (obj->export_dma_buf) {
+               get_dma_buf(obj->export_dma_buf);
+               *prime_fd = dma_buf_fd(obj->export_dma_buf, flags);
+               drm_gem_object_unreference_unlocked(obj);
+       } else {
+               buf = dev->driver->gem_prime_export(dev, obj, flags);
+               if (IS_ERR(buf)) {
+                       /* normally the created dma-buf takes ownership of the ref,
+                        * but if that fails then drop the ref
+                        */
+                       drm_gem_object_unreference_unlocked(obj);
+                       mutex_unlock(&file_priv->prime.lock);
+                       return PTR_ERR(buf);
+               }
+               obj->export_dma_buf = buf;
+               *prime_fd = dma_buf_fd(buf, flags);
+       }
+       mutex_unlock(&file_priv->prime.lock);
+       return 0;
+}
+EXPORT_SYMBOL(drm_gem_prime_handle_to_fd);
+
+int drm_gem_prime_fd_to_handle(struct drm_device *dev,
+               struct drm_file *file_priv, int prime_fd, uint32_t *handle)
+{
+       struct dma_buf *dma_buf;
+       struct drm_gem_object *obj;
+       int ret;
+
+       dma_buf = dma_buf_get(prime_fd);
+       if (IS_ERR(dma_buf))
+               return PTR_ERR(dma_buf);
+
+       mutex_lock(&file_priv->prime.lock);
+
+       ret = drm_prime_lookup_imported_buf_handle(&file_priv->prime,
+                       dma_buf, handle);
+       if (!ret) {
+               ret = 0;
+               goto out_put;
+       }
+
+       /* never seen this one, need to import */
+       obj = dev->driver->gem_prime_import(dev, dma_buf);
+       if (IS_ERR(obj)) {
+               ret = PTR_ERR(obj);
+               goto out_put;
+       }
+
+       ret = drm_gem_handle_create(file_priv, obj, handle);
+       drm_gem_object_unreference_unlocked(obj);
+       if (ret)
+               goto out_put;
+
+       ret = drm_prime_add_imported_buf_handle(&file_priv->prime,
+                       dma_buf, *handle);
+       if (ret)
+               goto fail;
+
+       mutex_unlock(&file_priv->prime.lock);
+       return 0;
+
+fail:
+       /* hmm, if driver attached, we are relying on the free-object path
+        * to detach.. which seems ok..
+        */
+       drm_gem_object_handle_unreference_unlocked(obj);
+out_put:
+       dma_buf_put(dma_buf);
+       mutex_unlock(&file_priv->prime.lock);
+       return ret;
+}
+EXPORT_SYMBOL(drm_gem_prime_fd_to_handle);
+
+int drm_prime_handle_to_fd_ioctl(struct drm_device *dev, void *data,
+                                struct drm_file *file_priv)
+{
+       struct drm_prime_handle *args = data;
+       uint32_t flags;
+
+       if (!drm_core_check_feature(dev, DRIVER_PRIME))
+               return -EINVAL;
+
+       if (!dev->driver->prime_handle_to_fd)
+               return -ENOSYS;
+
+       /* check flags are valid */
+       if (args->flags & ~DRM_CLOEXEC)
+               return -EINVAL;
+
+       /* we only want to pass DRM_CLOEXEC which is == O_CLOEXEC */
+       flags = args->flags & DRM_CLOEXEC;
+
+       return dev->driver->prime_handle_to_fd(dev, file_priv,
+                       args->handle, flags, &args->fd);
+}
+
+int drm_prime_fd_to_handle_ioctl(struct drm_device *dev, void *data,
+                                struct drm_file *file_priv)
+{
+       struct drm_prime_handle *args = data;
+
+       if (!drm_core_check_feature(dev, DRIVER_PRIME))
+               return -EINVAL;
+
+       if (!dev->driver->prime_fd_to_handle)
+               return -ENOSYS;
+
+       return dev->driver->prime_fd_to_handle(dev, file_priv,
+                       args->fd, &args->handle);
+}
+
+/*
+ * drm_prime_pages_to_sg
+ *
+ * this helper creates an sg table object from a set of pages
+ * the driver is responsible for mapping the pages into the
+ * importers address space
+ */
+struct sg_table *drm_prime_pages_to_sg(struct page **pages, int nr_pages)
+{
+       struct sg_table *sg = NULL;
+       struct scatterlist *iter;
+       int i;
+       int ret;
+
+       sg = kmalloc(sizeof(struct sg_table), GFP_KERNEL);
+       if (!sg)
+               goto out;
+
+       ret = sg_alloc_table(sg, nr_pages, GFP_KERNEL);
+       if (ret)
+               goto out;
+
+       for_each_sg(sg->sgl, iter, nr_pages, i)
+               sg_set_page(iter, pages[i], PAGE_SIZE, 0);
+
+       return sg;
+out:
+       kfree(sg);
+       return NULL;
+}
+EXPORT_SYMBOL(drm_prime_pages_to_sg);
+
+/* helper function to cleanup a GEM/prime object */
+void drm_prime_gem_destroy(struct drm_gem_object *obj, struct sg_table *sg)
+{
+       struct dma_buf_attachment *attach;
+       struct dma_buf *dma_buf;
+       attach = obj->import_attach;
+       if (sg)
+               dma_buf_unmap_attachment(attach, sg, DMA_BIDIRECTIONAL);
+       dma_buf = attach->dmabuf;
+       dma_buf_detach(attach->dmabuf, attach);
+       /* remove the reference */
+       dma_buf_put(dma_buf);
+}
+EXPORT_SYMBOL(drm_prime_gem_destroy);
+
+void drm_prime_init_file_private(struct drm_prime_file_private *prime_fpriv)
+{
+       INIT_LIST_HEAD(&prime_fpriv->head);
+       mutex_init(&prime_fpriv->lock);
+}
+EXPORT_SYMBOL(drm_prime_init_file_private);
+
+void drm_prime_destroy_file_private(struct drm_prime_file_private *prime_fpriv)
+{
+       struct drm_prime_member *member, *safe;
+       list_for_each_entry_safe(member, safe, &prime_fpriv->head, entry) {
+               list_del(&member->entry);
+               kfree(member);
+       }
+}
+EXPORT_SYMBOL(drm_prime_destroy_file_private);
+
+int drm_prime_add_imported_buf_handle(struct drm_prime_file_private *prime_fpriv, struct dma_buf *dma_buf, uint32_t handle)
+{
+       struct drm_prime_member *member;
+
+       member = kmalloc(sizeof(*member), GFP_KERNEL);
+       if (!member)
+               return -ENOMEM;
+
+       member->dma_buf = dma_buf;
+       member->handle = handle;
+       list_add(&member->entry, &prime_fpriv->head);
+       return 0;
+}
+EXPORT_SYMBOL(drm_prime_add_imported_buf_handle);
+
+int drm_prime_lookup_imported_buf_handle(struct drm_prime_file_private *prime_fpriv, struct dma_buf *dma_buf, uint32_t *handle)
+{
+       struct drm_prime_member *member;
+
+       list_for_each_entry(member, &prime_fpriv->head, entry) {
+               if (member->dma_buf == dma_buf) {
+                       *handle = member->handle;
+                       return 0;
+               }
+       }
+       return -ENOENT;
+}
+EXPORT_SYMBOL(drm_prime_lookup_imported_buf_handle);
+
+void drm_prime_remove_imported_buf_handle(struct drm_prime_file_private *prime_fpriv, struct dma_buf *dma_buf)
+{
+       struct drm_prime_member *member, *safe;
+
+       mutex_lock(&prime_fpriv->lock);
+       list_for_each_entry_safe(member, safe, &prime_fpriv->head, entry) {
+               if (member->dma_buf == dma_buf) {
+                       list_del(&member->entry);
+                       kfree(member);
+               }
+       }
+       mutex_unlock(&prime_fpriv->lock);
+}
+EXPORT_SYMBOL(drm_prime_remove_imported_buf_handle);
diff --git a/drivers/hsi/Kconfig b/drivers/hsi/Kconfig
new file mode 100644 (file)
index 0000000..d94e38d
--- /dev/null
@@ -0,0 +1,19 @@
+#
+# HSI driver configuration
+#
+menuconfig HSI
+       tristate "HSI support"
+       ---help---
+         The "High speed synchronous Serial Interface" is
+         synchronous serial interface used mainly to connect
+         application engines and cellular modems.
+
+if HSI
+
+config HSI_BOARDINFO
+       bool
+       default y
+
+source "drivers/hsi/clients/Kconfig"
+
+endif # HSI
diff --git a/drivers/hsi/Makefile b/drivers/hsi/Makefile
new file mode 100644 (file)
index 0000000..9d5d33f
--- /dev/null
@@ -0,0 +1,6 @@
+#
+# Makefile for HSI
+#
+obj-$(CONFIG_HSI_BOARDINFO)    += hsi_boardinfo.o
+obj-$(CONFIG_HSI)              += hsi.o
+obj-y                          += clients/
diff --git a/drivers/hsi/clients/Kconfig b/drivers/hsi/clients/Kconfig
new file mode 100644 (file)
index 0000000..3bacd27
--- /dev/null
@@ -0,0 +1,13 @@
+#
+# HSI clients configuration
+#
+
+comment "HSI clients"
+
+config HSI_CHAR
+       tristate "HSI/SSI character driver"
+       depends on HSI
+       ---help---
+         If you say Y here, you will enable the HSI/SSI character driver.
+         This driver provides a simple character device interface for
+         serial communication with the cellular modem over HSI/SSI bus.
diff --git a/drivers/hsi/clients/Makefile b/drivers/hsi/clients/Makefile
new file mode 100644 (file)
index 0000000..327c0e2
--- /dev/null
@@ -0,0 +1,5 @@
+#
+# Makefile for HSI clients
+#
+
+obj-$(CONFIG_HSI_CHAR) += hsi_char.o
diff --git a/drivers/hsi/clients/hsi_char.c b/drivers/hsi/clients/hsi_char.c
new file mode 100644 (file)
index 0000000..88a050d
--- /dev/null
@@ -0,0 +1,802 @@
+/*
+ * HSI character device driver, implements the character device
+ * interface.
+ *
+ * Copyright (C) 2010 Nokia Corporation. All rights reserved.
+ *
+ * Contact: Andras Domokos <andras.domokos@nokia.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 published by the Free Software Foundation.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/atomic.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/list.h>
+#include <linux/slab.h>
+#include <linux/kmemleak.h>
+#include <linux/ioctl.h>
+#include <linux/wait.h>
+#include <linux/fs.h>
+#include <linux/sched.h>
+#include <linux/device.h>
+#include <linux/cdev.h>
+#include <linux/uaccess.h>
+#include <linux/scatterlist.h>
+#include <linux/stat.h>
+#include <linux/hsi/hsi.h>
+#include <linux/hsi/hsi_char.h>
+
+#define HSC_DEVS               16 /* Num of channels */
+#define HSC_MSGS               4
+
+#define HSC_RXBREAK            0
+
+#define HSC_ID_BITS            6
+#define HSC_PORT_ID_BITS       4
+#define HSC_ID_MASK            3
+#define HSC_PORT_ID_MASK       3
+#define HSC_CH_MASK            0xf
+
+/*
+ * We support up to 4 controllers that can have up to 4
+ * ports, which should currently be more than enough.
+ */
+#define HSC_BASEMINOR(id, port_id) \
+               ((((id) & HSC_ID_MASK) << HSC_ID_BITS) | \
+               (((port_id) & HSC_PORT_ID_MASK) << HSC_PORT_ID_BITS))
+
+enum {
+       HSC_CH_OPEN,
+       HSC_CH_READ,
+       HSC_CH_WRITE,
+       HSC_CH_WLINE,
+};
+
+enum {
+       HSC_RX,
+       HSC_TX,
+};
+
+struct hsc_client_data;
+/**
+ * struct hsc_channel - hsi_char internal channel data
+ * @ch: channel number
+ * @flags: Keeps state of the channel (open/close, reading, writing)
+ * @free_msgs_list: List of free HSI messages/requests
+ * @rx_msgs_queue: List of pending RX requests
+ * @tx_msgs_queue: List of pending TX requests
+ * @lock: Serialize access to the lists
+ * @cl: reference to the associated hsi_client
+ * @cl_data: reference to the client data that this channels belongs to
+ * @rx_wait: RX requests wait queue
+ * @tx_wait: TX requests wait queue
+ */
+struct hsc_channel {
+       unsigned int            ch;
+       unsigned long           flags;
+       struct list_head        free_msgs_list;
+       struct list_head        rx_msgs_queue;
+       struct list_head        tx_msgs_queue;
+       spinlock_t              lock;
+       struct hsi_client       *cl;
+       struct hsc_client_data *cl_data;
+       wait_queue_head_t       rx_wait;
+       wait_queue_head_t       tx_wait;
+};
+
+/**
+ * struct hsc_client_data - hsi_char internal client data
+ * @cdev: Characther device associated to the hsi_client
+ * @lock: Lock to serialize open/close access
+ * @flags: Keeps track of port state (rx hwbreak armed)
+ * @usecnt: Use count for claiming the HSI port (mutex protected)
+ * @cl: Referece to the HSI client
+ * @channels: Array of channels accessible by the client
+ */
+struct hsc_client_data {
+       struct cdev             cdev;
+       struct mutex            lock;
+       unsigned long           flags;
+       unsigned int            usecnt;
+       struct hsi_client       *cl;
+       struct hsc_channel      channels[HSC_DEVS];
+};
+
+/* Stores the major number dynamically allocated for hsi_char */
+static unsigned int hsc_major;
+/* Maximum buffer size that hsi_char will accept from userspace */
+static unsigned int max_data_size = 0x1000;
+module_param(max_data_size, uint, S_IRUSR | S_IWUSR);
+MODULE_PARM_DESC(max_data_size, "max read/write data size [4,8..65536] (^2)");
+
+static void hsc_add_tail(struct hsc_channel *channel, struct hsi_msg *msg,
+                                                       struct list_head *queue)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&channel->lock, flags);
+       list_add_tail(&msg->link, queue);
+       spin_unlock_irqrestore(&channel->lock, flags);
+}
+
+static struct hsi_msg *hsc_get_first_msg(struct hsc_channel *channel,
+                                                       struct list_head *queue)
+{
+       struct hsi_msg *msg = NULL;
+       unsigned long flags;
+
+       spin_lock_irqsave(&channel->lock, flags);
+
+       if (list_empty(queue))
+               goto out;
+
+       msg = list_first_entry(queue, struct hsi_msg, link);
+       list_del(&msg->link);
+out:
+       spin_unlock_irqrestore(&channel->lock, flags);
+
+       return msg;
+}
+
+static inline void hsc_msg_free(struct hsi_msg *msg)
+{
+       kfree(sg_virt(msg->sgt.sgl));
+       hsi_free_msg(msg);
+}
+
+static void hsc_free_list(struct list_head *list)
+{
+       struct hsi_msg *msg, *tmp;
+
+       list_for_each_entry_safe(msg, tmp, list, link) {
+               list_del(&msg->link);
+               hsc_msg_free(msg);
+       }
+}
+
+static void hsc_reset_list(struct hsc_channel *channel, struct list_head *l)
+{
+       unsigned long flags;
+       LIST_HEAD(list);
+
+       spin_lock_irqsave(&channel->lock, flags);
+       list_splice_init(l, &list);
+       spin_unlock_irqrestore(&channel->lock, flags);
+
+       hsc_free_list(&list);
+}
+
+static inline struct hsi_msg *hsc_msg_alloc(unsigned int alloc_size)
+{
+       struct hsi_msg *msg;
+       void *buf;
+
+       msg = hsi_alloc_msg(1, GFP_KERNEL);
+       if (!msg)
+               goto out;
+       buf = kmalloc(alloc_size, GFP_KERNEL);
+       if (!buf) {
+               hsi_free_msg(msg);
+               goto out;
+       }
+       sg_init_one(msg->sgt.sgl, buf, alloc_size);
+       /* Ignore false positive, due to sg pointer handling */
+       kmemleak_ignore(buf);
+
+       return msg;
+out:
+       return NULL;
+}
+
+static inline int hsc_msgs_alloc(struct hsc_channel *channel)
+{
+       struct hsi_msg *msg;
+       int i;
+
+       for (i = 0; i < HSC_MSGS; i++) {
+               msg = hsc_msg_alloc(max_data_size);
+               if (!msg)
+                       goto out;
+               msg->channel = channel->ch;
+               list_add_tail(&msg->link, &channel->free_msgs_list);
+       }
+
+       return 0;
+out:
+       hsc_free_list(&channel->free_msgs_list);
+
+       return -ENOMEM;
+}
+
+static inline unsigned int hsc_msg_len_get(struct hsi_msg *msg)
+{
+       return msg->sgt.sgl->length;
+}
+
+static inline void hsc_msg_len_set(struct hsi_msg *msg, unsigned int len)
+{
+       msg->sgt.sgl->length = len;
+}
+
+static void hsc_rx_completed(struct hsi_msg *msg)
+{
+       struct hsc_client_data *cl_data = hsi_client_drvdata(msg->cl);
+       struct hsc_channel *channel = cl_data->channels + msg->channel;
+
+       if (test_bit(HSC_CH_READ, &channel->flags)) {
+               hsc_add_tail(channel, msg, &channel->rx_msgs_queue);
+               wake_up(&channel->rx_wait);
+       } else {
+               hsc_add_tail(channel, msg, &channel->free_msgs_list);
+       }
+}
+
+static void hsc_rx_msg_destructor(struct hsi_msg *msg)
+{
+       msg->status = HSI_STATUS_ERROR;
+       hsc_msg_len_set(msg, 0);
+       hsc_rx_completed(msg);
+}
+
+static void hsc_tx_completed(struct hsi_msg *msg)
+{
+       struct hsc_client_data *cl_data = hsi_client_drvdata(msg->cl);
+       struct hsc_channel *channel = cl_data->channels + msg->channel;
+
+       if (test_bit(HSC_CH_WRITE, &channel->flags)) {
+               hsc_add_tail(channel, msg, &channel->tx_msgs_queue);
+               wake_up(&channel->tx_wait);
+       } else {
+               hsc_add_tail(channel, msg, &channel->free_msgs_list);
+       }
+}
+
+static void hsc_tx_msg_destructor(struct hsi_msg *msg)
+{
+       msg->status = HSI_STATUS_ERROR;
+       hsc_msg_len_set(msg, 0);
+       hsc_tx_completed(msg);
+}
+
+static void hsc_break_req_destructor(struct hsi_msg *msg)
+{
+       struct hsc_client_data *cl_data = hsi_client_drvdata(msg->cl);
+
+       hsi_free_msg(msg);
+       clear_bit(HSC_RXBREAK, &cl_data->flags);
+}
+
+static void hsc_break_received(struct hsi_msg *msg)
+{
+       struct hsc_client_data *cl_data = hsi_client_drvdata(msg->cl);
+       struct hsc_channel *channel = cl_data->channels;
+       int i, ret;
+
+       /* Broadcast HWBREAK on all channels */
+       for (i = 0; i < HSC_DEVS; i++, channel++) {
+               struct hsi_msg *msg2;
+
+               if (!test_bit(HSC_CH_READ, &channel->flags))
+                       continue;
+               msg2 = hsc_get_first_msg(channel, &channel->free_msgs_list);
+               if (!msg2)
+                       continue;
+               clear_bit(HSC_CH_READ, &channel->flags);
+               hsc_msg_len_set(msg2, 0);
+               msg2->status = HSI_STATUS_COMPLETED;
+               hsc_add_tail(channel, msg2, &channel->rx_msgs_queue);
+               wake_up(&channel->rx_wait);
+       }
+       hsi_flush(msg->cl);
+       ret = hsi_async_read(msg->cl, msg);
+       if (ret < 0)
+               hsc_break_req_destructor(msg);
+}
+
+static int hsc_break_request(struct hsi_client *cl)
+{
+       struct hsc_client_data *cl_data = hsi_client_drvdata(cl);
+       struct hsi_msg *msg;
+       int ret;
+
+       if (test_and_set_bit(HSC_RXBREAK, &cl_data->flags))
+               return -EBUSY;
+
+       msg = hsi_alloc_msg(0, GFP_KERNEL);
+       if (!msg) {
+               clear_bit(HSC_RXBREAK, &cl_data->flags);
+               return -ENOMEM;
+       }
+       msg->break_frame = 1;
+       msg->complete = hsc_break_received;
+       msg->destructor = hsc_break_req_destructor;
+       ret = hsi_async_read(cl, msg);
+       if (ret < 0)
+               hsc_break_req_destructor(msg);
+
+       return ret;
+}
+
+static int hsc_break_send(struct hsi_client *cl)
+{
+       struct hsi_msg *msg;
+       int ret;
+
+       msg = hsi_alloc_msg(0, GFP_ATOMIC);
+       if (!msg)
+               return -ENOMEM;
+       msg->break_frame = 1;
+       msg->complete = hsi_free_msg;
+       msg->destructor = hsi_free_msg;
+       ret = hsi_async_write(cl, msg);
+       if (ret < 0)
+               hsi_free_msg(msg);
+
+       return ret;
+}
+
+static int hsc_rx_set(struct hsi_client *cl, struct hsc_rx_config *rxc)
+{
+       struct hsi_config tmp;
+       int ret;
+
+       if ((rxc->mode != HSI_MODE_STREAM) && (rxc->mode != HSI_MODE_FRAME))
+               return -EINVAL;
+       if ((rxc->channels == 0) || (rxc->channels > HSC_DEVS))
+               return -EINVAL;
+       if (rxc->channels & (rxc->channels - 1))
+               return -EINVAL;
+       if ((rxc->flow != HSI_FLOW_SYNC) && (rxc->flow != HSI_FLOW_PIPE))
+               return -EINVAL;
+       tmp = cl->rx_cfg;
+       cl->rx_cfg.mode = rxc->mode;
+       cl->rx_cfg.channels = rxc->channels;
+       cl->rx_cfg.flow = rxc->flow;
+       ret = hsi_setup(cl);
+       if (ret < 0) {
+               cl->rx_cfg = tmp;
+               return ret;
+       }
+       if (rxc->mode == HSI_MODE_FRAME)
+               hsc_break_request(cl);
+
+       return ret;
+}
+
+static inline void hsc_rx_get(struct hsi_client *cl, struct hsc_rx_config *rxc)
+{
+       rxc->mode = cl->rx_cfg.mode;
+       rxc->channels = cl->rx_cfg.channels;
+       rxc->flow = cl->rx_cfg.flow;
+}
+
+static int hsc_tx_set(struct hsi_client *cl, struct hsc_tx_config *txc)
+{
+       struct hsi_config tmp;
+       int ret;
+
+       if ((txc->mode != HSI_MODE_STREAM) && (txc->mode != HSI_MODE_FRAME))
+               return -EINVAL;
+       if ((txc->channels == 0) || (txc->channels > HSC_DEVS))
+               return -EINVAL;
+       if (txc->channels & (txc->channels - 1))
+               return -EINVAL;
+       if ((txc->arb_mode != HSI_ARB_RR) && (txc->arb_mode != HSI_ARB_PRIO))
+               return -EINVAL;
+       tmp = cl->tx_cfg;
+       cl->tx_cfg.mode = txc->mode;
+       cl->tx_cfg.channels = txc->channels;
+       cl->tx_cfg.speed = txc->speed;
+       cl->tx_cfg.arb_mode = txc->arb_mode;
+       ret = hsi_setup(cl);
+       if (ret < 0) {
+               cl->tx_cfg = tmp;
+               return ret;
+       }
+
+       return ret;
+}
+
+static inline void hsc_tx_get(struct hsi_client *cl, struct hsc_tx_config *txc)
+{
+       txc->mode = cl->tx_cfg.mode;
+       txc->channels = cl->tx_cfg.channels;
+       txc->speed = cl->tx_cfg.speed;
+       txc->arb_mode = cl->tx_cfg.arb_mode;
+}
+
+static ssize_t hsc_read(struct file *file, char __user *buf, size_t len,
+                                               loff_t *ppos __maybe_unused)
+{
+       struct hsc_channel *channel = file->private_data;
+       struct hsi_msg *msg;
+       ssize_t ret;
+
+       if (len == 0)
+               return 0;
+       if (!IS_ALIGNED(len, sizeof(u32)))
+               return -EINVAL;
+       if (len > max_data_size)
+               len = max_data_size;
+       if (channel->ch >= channel->cl->rx_cfg.channels)
+               return -ECHRNG;
+       if (test_and_set_bit(HSC_CH_READ, &channel->flags))
+               return -EBUSY;
+       msg = hsc_get_first_msg(channel, &channel->free_msgs_list);
+       if (!msg) {
+               ret = -ENOSPC;
+               goto out;
+       }
+       hsc_msg_len_set(msg, len);
+       msg->complete = hsc_rx_completed;
+       msg->destructor = hsc_rx_msg_destructor;
+       ret = hsi_async_read(channel->cl, msg);
+       if (ret < 0) {
+               hsc_add_tail(channel, msg, &channel->free_msgs_list);
+               goto out;
+       }
+
+       ret = wait_event_interruptible(channel->rx_wait,
+                                       !list_empty(&channel->rx_msgs_queue));
+       if (ret < 0) {
+               clear_bit(HSC_CH_READ, &channel->flags);
+               hsi_flush(channel->cl);
+               return -EINTR;
+       }
+
+       msg = hsc_get_first_msg(channel, &channel->rx_msgs_queue);
+       if (msg) {
+               if (msg->status != HSI_STATUS_ERROR) {
+                       ret = copy_to_user((void __user *)buf,
+                       sg_virt(msg->sgt.sgl), hsc_msg_len_get(msg));
+                       if (ret)
+                               ret = -EFAULT;
+                       else
+                               ret = hsc_msg_len_get(msg);
+               } else {
+                       ret = -EIO;
+               }
+               hsc_add_tail(channel, msg, &channel->free_msgs_list);
+       }
+out:
+       clear_bit(HSC_CH_READ, &channel->flags);
+
+       return ret;
+}
+
+static ssize_t hsc_write(struct file *file, const char __user *buf, size_t len,
+                                               loff_t *ppos __maybe_unused)
+{
+       struct hsc_channel *channel = file->private_data;
+       struct hsi_msg *msg;
+       ssize_t ret;
+
+       if ((len == 0) || !IS_ALIGNED(len, sizeof(u32)))
+               return -EINVAL;
+       if (len > max_data_size)
+               len = max_data_size;
+       if (channel->ch >= channel->cl->tx_cfg.channels)
+               return -ECHRNG;
+       if (test_and_set_bit(HSC_CH_WRITE, &channel->flags))
+               return -EBUSY;
+       msg = hsc_get_first_msg(channel, &channel->free_msgs_list);
+       if (!msg) {
+               clear_bit(HSC_CH_WRITE, &channel->flags);
+               return -ENOSPC;
+       }
+       if (copy_from_user(sg_virt(msg->sgt.sgl), (void __user *)buf, len)) {
+               ret = -EFAULT;
+               goto out;
+       }
+       hsc_msg_len_set(msg, len);
+       msg->complete = hsc_tx_completed;
+       msg->destructor = hsc_tx_msg_destructor;
+       ret = hsi_async_write(channel->cl, msg);
+       if (ret < 0)
+               goto out;
+
+       ret = wait_event_interruptible(channel->tx_wait,
+                                       !list_empty(&channel->tx_msgs_queue));
+       if (ret < 0) {
+               clear_bit(HSC_CH_WRITE, &channel->flags);
+               hsi_flush(channel->cl);
+               return -EINTR;
+       }
+
+       msg = hsc_get_first_msg(channel, &channel->tx_msgs_queue);
+       if (msg) {
+               if (msg->status == HSI_STATUS_ERROR)
+                       ret = -EIO;
+               else
+                       ret = hsc_msg_len_get(msg);
+
+               hsc_add_tail(channel, msg, &channel->free_msgs_list);
+       }
+out:
+       clear_bit(HSC_CH_WRITE, &channel->flags);
+
+       return ret;
+}
+
+static long hsc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+       struct hsc_channel *channel = file->private_data;
+       unsigned int state;
+       struct hsc_rx_config rxc;
+       struct hsc_tx_config txc;
+       long ret = 0;
+
+       switch (cmd) {
+       case HSC_RESET:
+               hsi_flush(channel->cl);
+               break;
+       case HSC_SET_PM:
+               if (copy_from_user(&state, (void __user *)arg, sizeof(state)))
+                       return -EFAULT;
+               if (state == HSC_PM_DISABLE) {
+                       if (test_and_set_bit(HSC_CH_WLINE, &channel->flags))
+                               return -EINVAL;
+                       ret = hsi_start_tx(channel->cl);
+               } else if (state == HSC_PM_ENABLE) {
+                       if (!test_and_clear_bit(HSC_CH_WLINE, &channel->flags))
+                               return -EINVAL;
+                       ret = hsi_stop_tx(channel->cl);
+               } else {
+                       ret = -EINVAL;
+               }
+               break;
+       case HSC_SEND_BREAK:
+               return hsc_break_send(channel->cl);
+       case HSC_SET_RX:
+               if (copy_from_user(&rxc, (void __user *)arg, sizeof(rxc)))
+                       return -EFAULT;
+               return hsc_rx_set(channel->cl, &rxc);
+       case HSC_GET_RX:
+               hsc_rx_get(channel->cl, &rxc);
+               if (copy_to_user((void __user *)arg, &rxc, sizeof(rxc)))
+                       return -EFAULT;
+               break;
+       case HSC_SET_TX:
+               if (copy_from_user(&txc, (void __user *)arg, sizeof(txc)))
+                       return -EFAULT;
+               return hsc_tx_set(channel->cl, &txc);
+       case HSC_GET_TX:
+               hsc_tx_get(channel->cl, &txc);
+               if (copy_to_user((void __user *)arg, &txc, sizeof(txc)))
+                       return -EFAULT;
+               break;
+       default:
+               return -ENOIOCTLCMD;
+       }
+
+       return ret;
+}
+
+static inline void __hsc_port_release(struct hsc_client_data *cl_data)
+{
+       BUG_ON(cl_data->usecnt == 0);
+
+       if (--cl_data->usecnt == 0) {
+               hsi_flush(cl_data->cl);
+               hsi_release_port(cl_data->cl);
+       }
+}
+
+static int hsc_open(struct inode *inode, struct file *file)
+{
+       struct hsc_client_data *cl_data;
+       struct hsc_channel *channel;
+       int ret = 0;
+
+       pr_debug("open, minor = %d\n", iminor(inode));
+
+       cl_data = container_of(inode->i_cdev, struct hsc_client_data, cdev);
+       mutex_lock(&cl_data->lock);
+       channel = cl_data->channels + (iminor(inode) & HSC_CH_MASK);
+
+       if (test_and_set_bit(HSC_CH_OPEN, &channel->flags)) {
+               ret = -EBUSY;
+               goto out;
+       }
+       /*
+        * Check if we have already claimed the port associated to the HSI
+        * client. If not then try to claim it, else increase its refcount
+        */
+       if (cl_data->usecnt == 0) {
+               ret = hsi_claim_port(cl_data->cl, 0);
+               if (ret < 0)
+                       goto out;
+               hsi_setup(cl_data->cl);
+       }
+       cl_data->usecnt++;
+
+       ret = hsc_msgs_alloc(channel);
+       if (ret < 0) {
+               __hsc_port_release(cl_data);
+               goto out;
+       }
+
+       file->private_data = channel;
+       mutex_unlock(&cl_data->lock);
+
+       return ret;
+out:
+       mutex_unlock(&cl_data->lock);
+
+       return ret;
+}
+
+static int hsc_release(struct inode *inode __maybe_unused, struct file *file)
+{
+       struct hsc_channel *channel = file->private_data;
+       struct hsc_client_data *cl_data = channel->cl_data;
+
+       mutex_lock(&cl_data->lock);
+       file->private_data = NULL;
+       if (test_and_clear_bit(HSC_CH_WLINE, &channel->flags))
+               hsi_stop_tx(channel->cl);
+       __hsc_port_release(cl_data);
+       hsc_reset_list(channel, &channel->rx_msgs_queue);
+       hsc_reset_list(channel, &channel->tx_msgs_queue);
+       hsc_reset_list(channel, &channel->free_msgs_list);
+       clear_bit(HSC_CH_READ, &channel->flags);
+       clear_bit(HSC_CH_WRITE, &channel->flags);
+       clear_bit(HSC_CH_OPEN, &channel->flags);
+       wake_up(&channel->rx_wait);
+       wake_up(&channel->tx_wait);
+       mutex_unlock(&cl_data->lock);
+
+       return 0;
+}
+
+static const struct file_operations hsc_fops = {
+       .owner          = THIS_MODULE,
+       .read           = hsc_read,
+       .write          = hsc_write,
+       .unlocked_ioctl = hsc_ioctl,
+       .open           = hsc_open,
+       .release        = hsc_release,
+};
+
+static void __devinit hsc_channel_init(struct hsc_channel *channel)
+{
+       init_waitqueue_head(&channel->rx_wait);
+       init_waitqueue_head(&channel->tx_wait);
+       spin_lock_init(&channel->lock);
+       INIT_LIST_HEAD(&channel->free_msgs_list);
+       INIT_LIST_HEAD(&channel->rx_msgs_queue);
+       INIT_LIST_HEAD(&channel->tx_msgs_queue);
+}
+
+static int __devinit hsc_probe(struct device *dev)
+{
+       const char devname[] = "hsi_char";
+       struct hsc_client_data *cl_data;
+       struct hsc_channel *channel;
+       struct hsi_client *cl = to_hsi_client(dev);
+       unsigned int hsc_baseminor;
+       dev_t hsc_dev;
+       int ret;
+       int i;
+
+       cl_data = kzalloc(sizeof(*cl_data), GFP_KERNEL);
+       if (!cl_data) {
+               dev_err(dev, "Could not allocate hsc_client_data\n");
+               return -ENOMEM;
+       }
+       hsc_baseminor = HSC_BASEMINOR(hsi_id(cl), hsi_port_id(cl));
+       if (!hsc_major) {
+               ret = alloc_chrdev_region(&hsc_dev, hsc_baseminor,
+                                               HSC_DEVS, devname);
+               if (ret > 0)
+                       hsc_major = MAJOR(hsc_dev);
+       } else {
+               hsc_dev = MKDEV(hsc_major, hsc_baseminor);
+               ret = register_chrdev_region(hsc_dev, HSC_DEVS, devname);
+       }
+       if (ret < 0) {
+               dev_err(dev, "Device %s allocation failed %d\n",
+                                       hsc_major ? "minor" : "major", ret);
+               goto out1;
+       }
+       mutex_init(&cl_data->lock);
+       hsi_client_set_drvdata(cl, cl_data);
+       cdev_init(&cl_data->cdev, &hsc_fops);
+       cl_data->cdev.owner = THIS_MODULE;
+       cl_data->cl = cl;
+       for (i = 0, channel = cl_data->channels; i < HSC_DEVS; i++, channel++) {
+               hsc_channel_init(channel);
+               channel->ch = i;
+               channel->cl = cl;
+               channel->cl_data = cl_data;
+       }
+
+       /* 1 hsi client -> N char devices (one for each channel) */
+       ret = cdev_add(&cl_data->cdev, hsc_dev, HSC_DEVS);
+       if (ret) {
+               dev_err(dev, "Could not add char device %d\n", ret);
+               goto out2;
+       }
+
+       return 0;
+out2:
+       unregister_chrdev_region(hsc_dev, HSC_DEVS);
+out1:
+       kfree(cl_data);
+
+       return ret;
+}
+
+static int __devexit hsc_remove(struct device *dev)
+{
+       struct hsi_client *cl = to_hsi_client(dev);
+       struct hsc_client_data *cl_data = hsi_client_drvdata(cl);
+       dev_t hsc_dev = cl_data->cdev.dev;
+
+       cdev_del(&cl_data->cdev);
+       unregister_chrdev_region(hsc_dev, HSC_DEVS);
+       hsi_client_set_drvdata(cl, NULL);
+       kfree(cl_data);
+
+       return 0;
+}
+
+static struct hsi_client_driver hsc_driver = {
+       .driver = {
+               .name   = "hsi_char",
+               .owner  = THIS_MODULE,
+               .probe  = hsc_probe,
+               .remove = __devexit_p(hsc_remove),
+       },
+};
+
+static int __init hsc_init(void)
+{
+       int ret;
+
+       if ((max_data_size < 4) || (max_data_size > 0x10000) ||
+               (max_data_size & (max_data_size - 1))) {
+               pr_err("Invalid max read/write data size");
+               return -EINVAL;
+       }
+
+       ret = hsi_register_client_driver(&hsc_driver);
+       if (ret) {
+               pr_err("Error while registering HSI/SSI driver %d", ret);
+               return ret;
+       }
+
+       pr_info("HSI/SSI char device loaded\n");
+
+       return 0;
+}
+module_init(hsc_init);
+
+static void __exit hsc_exit(void)
+{
+       hsi_unregister_client_driver(&hsc_driver);
+       pr_info("HSI char device removed\n");
+}
+module_exit(hsc_exit);
+
+MODULE_AUTHOR("Andras Domokos <andras.domokos@nokia.com>");
+MODULE_ALIAS("hsi:hsi_char");
+MODULE_DESCRIPTION("HSI character device");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/hsi/hsi.c b/drivers/hsi/hsi.c
new file mode 100644 (file)
index 0000000..4e2d79b
--- /dev/null
@@ -0,0 +1,494 @@
+/*
+ * HSI core.
+ *
+ * Copyright (C) 2010 Nokia Corporation. All rights reserved.
+ *
+ * Contact: Carlos Chinea <carlos.chinea@nokia.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 published by the Free Software Foundation.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+#include <linux/hsi/hsi.h>
+#include <linux/compiler.h>
+#include <linux/rwsem.h>
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <linux/kobject.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include "hsi_core.h"
+
+static struct device_type hsi_ctrl = {
+       .name   = "hsi_controller",
+};
+
+static struct device_type hsi_cl = {
+       .name   = "hsi_client",
+};
+
+static struct device_type hsi_port = {
+       .name   = "hsi_port",
+};
+
+static ssize_t modalias_show(struct device *dev,
+                       struct device_attribute *a __maybe_unused, char *buf)
+{
+       return sprintf(buf, "hsi:%s\n", dev_name(dev));
+}
+
+static struct device_attribute hsi_bus_dev_attrs[] = {
+       __ATTR_RO(modalias),
+       __ATTR_NULL,
+};
+
+static int hsi_bus_uevent(struct device *dev, struct kobj_uevent_env *env)
+{
+       if (dev->type == &hsi_cl)
+               add_uevent_var(env, "MODALIAS=hsi:%s", dev_name(dev));
+
+       return 0;
+}
+
+static int hsi_bus_match(struct device *dev, struct device_driver *driver)
+{
+       return strcmp(dev_name(dev), driver->name) == 0;
+}
+
+static struct bus_type hsi_bus_type = {
+       .name           = "hsi",
+       .dev_attrs      = hsi_bus_dev_attrs,
+       .match          = hsi_bus_match,
+       .uevent         = hsi_bus_uevent,
+};
+
+static void hsi_client_release(struct device *dev)
+{
+       kfree(to_hsi_client(dev));
+}
+
+static void hsi_new_client(struct hsi_port *port, struct hsi_board_info *info)
+{
+       struct hsi_client *cl;
+       unsigned long flags;
+
+       cl = kzalloc(sizeof(*cl), GFP_KERNEL);
+       if (!cl)
+               return;
+       cl->device.type = &hsi_cl;
+       cl->tx_cfg = info->tx_cfg;
+       cl->rx_cfg = info->rx_cfg;
+       cl->device.bus = &hsi_bus_type;
+       cl->device.parent = &port->device;
+       cl->device.release = hsi_client_release;
+       dev_set_name(&cl->device, info->name);
+       cl->device.platform_data = info->platform_data;
+       spin_lock_irqsave(&port->clock, flags);
+       list_add_tail(&cl->link, &port->clients);
+       spin_unlock_irqrestore(&port->clock, flags);
+       if (info->archdata)
+               cl->device.archdata = *info->archdata;
+       if (device_register(&cl->device) < 0) {
+               pr_err("hsi: failed to register client: %s\n", info->name);
+               kfree(cl);
+       }
+}
+
+static void hsi_scan_board_info(struct hsi_controller *hsi)
+{
+       struct hsi_cl_info *cl_info;
+       struct hsi_port *p;
+
+       list_for_each_entry(cl_info, &hsi_board_list, list)
+               if (cl_info->info.hsi_id == hsi->id) {
+                       p = hsi_find_port_num(hsi, cl_info->info.port);
+                       if (!p)
+                               continue;
+                       hsi_new_client(p, &cl_info->info);
+               }
+}
+
+static int hsi_remove_client(struct device *dev, void *data __maybe_unused)
+{
+       struct hsi_client *cl = to_hsi_client(dev);
+       struct hsi_port *port = to_hsi_port(dev->parent);
+       unsigned long flags;
+
+       spin_lock_irqsave(&port->clock, flags);
+       list_del(&cl->link);
+       spin_unlock_irqrestore(&port->clock, flags);
+       device_unregister(dev);
+
+       return 0;
+}
+
+static int hsi_remove_port(struct device *dev, void *data __maybe_unused)
+{
+       device_for_each_child(dev, NULL, hsi_remove_client);
+       device_unregister(dev);
+
+       return 0;
+}
+
+static void hsi_controller_release(struct device *dev __maybe_unused)
+{
+}
+
+static void hsi_port_release(struct device *dev __maybe_unused)
+{
+}
+
+/**
+ * hsi_unregister_controller - Unregister an HSI controller
+ * @hsi: The HSI controller to register
+ */
+void hsi_unregister_controller(struct hsi_controller *hsi)
+{
+       device_for_each_child(&hsi->device, NULL, hsi_remove_port);
+       device_unregister(&hsi->device);
+}
+EXPORT_SYMBOL_GPL(hsi_unregister_controller);
+
+/**
+ * hsi_register_controller - Register an HSI controller and its ports
+ * @hsi: The HSI controller to register
+ *
+ * Returns -errno on failure, 0 on success.
+ */
+int hsi_register_controller(struct hsi_controller *hsi)
+{
+       unsigned int i;
+       int err;
+
+       hsi->device.type = &hsi_ctrl;
+       hsi->device.bus = &hsi_bus_type;
+       hsi->device.release = hsi_controller_release;
+       err = device_register(&hsi->device);
+       if (err < 0)
+               return err;
+       for (i = 0; i < hsi->num_ports; i++) {
+               hsi->port[i].device.parent = &hsi->device;
+               hsi->port[i].device.bus = &hsi_bus_type;
+               hsi->port[i].device.release = hsi_port_release;
+               hsi->port[i].device.type = &hsi_port;
+               INIT_LIST_HEAD(&hsi->port[i].clients);
+               spin_lock_init(&hsi->port[i].clock);
+               err = device_register(&hsi->port[i].device);
+               if (err < 0)
+                       goto out;
+       }
+       /* Populate HSI bus with HSI clients */
+       hsi_scan_board_info(hsi);
+
+       return 0;
+out:
+       hsi_unregister_controller(hsi);
+
+       return err;
+}
+EXPORT_SYMBOL_GPL(hsi_register_controller);
+
+/**
+ * hsi_register_client_driver - Register an HSI client to the HSI bus
+ * @drv: HSI client driver to register
+ *
+ * Returns -errno on failure, 0 on success.
+ */
+int hsi_register_client_driver(struct hsi_client_driver *drv)
+{
+       drv->driver.bus = &hsi_bus_type;
+
+       return driver_register(&drv->driver);
+}
+EXPORT_SYMBOL_GPL(hsi_register_client_driver);
+
+static inline int hsi_dummy_msg(struct hsi_msg *msg __maybe_unused)
+{
+       return 0;
+}
+
+static inline int hsi_dummy_cl(struct hsi_client *cl __maybe_unused)
+{
+       return 0;
+}
+
+/**
+ * hsi_alloc_controller - Allocate an HSI controller and its ports
+ * @n_ports: Number of ports on the HSI controller
+ * @flags: Kernel allocation flags
+ *
+ * Return NULL on failure or a pointer to an hsi_controller on success.
+ */
+struct hsi_controller *hsi_alloc_controller(unsigned int n_ports, gfp_t flags)
+{
+       struct hsi_controller   *hsi;
+       struct hsi_port         *port;
+       unsigned int            i;
+
+       if (!n_ports)
+               return NULL;
+
+       port = kzalloc(sizeof(*port)*n_ports, flags);
+       if (!port)
+               return NULL;
+       hsi = kzalloc(sizeof(*hsi), flags);
+       if (!hsi)
+               goto out;
+       for (i = 0; i < n_ports; i++) {
+               dev_set_name(&port[i].device, "port%d", i);
+               port[i].num = i;
+               port[i].async = hsi_dummy_msg;
+               port[i].setup = hsi_dummy_cl;
+               port[i].flush = hsi_dummy_cl;
+               port[i].start_tx = hsi_dummy_cl;
+               port[i].stop_tx = hsi_dummy_cl;
+               port[i].release = hsi_dummy_cl;
+               mutex_init(&port[i].lock);
+       }
+       hsi->num_ports = n_ports;
+       hsi->port = port;
+
+       return hsi;
+out:
+       kfree(port);
+
+       return NULL;
+}
+EXPORT_SYMBOL_GPL(hsi_alloc_controller);
+
+/**
+ * hsi_free_controller - Free an HSI controller
+ * @hsi: Pointer to HSI controller
+ */
+void hsi_free_controller(struct hsi_controller *hsi)
+{
+       if (!hsi)
+               return;
+
+       kfree(hsi->port);
+       kfree(hsi);
+}
+EXPORT_SYMBOL_GPL(hsi_free_controller);
+
+/**
+ * hsi_free_msg - Free an HSI message
+ * @msg: Pointer to the HSI message
+ *
+ * Client is responsible to free the buffers pointed by the scatterlists.
+ */
+void hsi_free_msg(struct hsi_msg *msg)
+{
+       if (!msg)
+               return;
+       sg_free_table(&msg->sgt);
+       kfree(msg);
+}
+EXPORT_SYMBOL_GPL(hsi_free_msg);
+
+/**
+ * hsi_alloc_msg - Allocate an HSI message
+ * @nents: Number of memory entries
+ * @flags: Kernel allocation flags
+ *
+ * nents can be 0. This mainly makes sense for read transfer.
+ * In that case, HSI drivers will call the complete callback when
+ * there is data to be read without consuming it.
+ *
+ * Return NULL on failure or a pointer to an hsi_msg on success.
+ */
+struct hsi_msg *hsi_alloc_msg(unsigned int nents, gfp_t flags)
+{
+       struct hsi_msg *msg;
+       int err;
+
+       msg = kzalloc(sizeof(*msg), flags);
+       if (!msg)
+               return NULL;
+
+       if (!nents)
+               return msg;
+
+       err = sg_alloc_table(&msg->sgt, nents, flags);
+       if (unlikely(err)) {
+               kfree(msg);
+               msg = NULL;
+       }
+
+       return msg;
+}
+EXPORT_SYMBOL_GPL(hsi_alloc_msg);
+
+/**
+ * hsi_async - Submit an HSI transfer to the controller
+ * @cl: HSI client sending the transfer
+ * @msg: The HSI transfer passed to controller
+ *
+ * The HSI message must have the channel, ttype, complete and destructor
+ * fields set beforehand. If nents > 0 then the client has to initialize
+ * also the scatterlists to point to the buffers to write to or read from.
+ *
+ * HSI controllers relay on pre-allocated buffers from their clients and they
+ * do not allocate buffers on their own.
+ *
+ * Once the HSI message transfer finishes, the HSI controller calls the
+ * complete callback with the status and actual_len fields of the HSI message
+ * updated. The complete callback can be called before returning from
+ * hsi_async.
+ *
+ * Returns -errno on failure or 0 on success
+ */
+int hsi_async(struct hsi_client *cl, struct hsi_msg *msg)
+{
+       struct hsi_port *port = hsi_get_port(cl);
+
+       if (!hsi_port_claimed(cl))
+               return -EACCES;
+
+       WARN_ON_ONCE(!msg->destructor || !msg->complete);
+       msg->cl = cl;
+
+       return port->async(msg);
+}
+EXPORT_SYMBOL_GPL(hsi_async);
+
+/**
+ * hsi_claim_port - Claim the HSI client's port
+ * @cl: HSI client that wants to claim its port
+ * @share: Flag to indicate if the client wants to share the port or not.
+ *
+ * Returns -errno on failure, 0 on success.
+ */
+int hsi_claim_port(struct hsi_client *cl, unsigned int share)
+{
+       struct hsi_port *port = hsi_get_port(cl);
+       int err = 0;
+
+       mutex_lock(&port->lock);
+       if ((port->claimed) && (!port->shared || !share)) {
+               err = -EBUSY;
+               goto out;
+       }
+       if (!try_module_get(to_hsi_controller(port->device.parent)->owner)) {
+               err = -ENODEV;
+               goto out;
+       }
+       port->claimed++;
+       port->shared = !!share;
+       cl->pclaimed = 1;
+out:
+       mutex_unlock(&port->lock);
+
+       return err;
+}
+EXPORT_SYMBOL_GPL(hsi_claim_port);
+
+/**
+ * hsi_release_port - Release the HSI client's port
+ * @cl: HSI client which previously claimed its port
+ */
+void hsi_release_port(struct hsi_client *cl)
+{
+       struct hsi_port *port = hsi_get_port(cl);
+
+       mutex_lock(&port->lock);
+       /* Allow HW driver to do some cleanup */
+       port->release(cl);
+       if (cl->pclaimed)
+               port->claimed--;
+       BUG_ON(port->claimed < 0);
+       cl->pclaimed = 0;
+       if (!port->claimed)
+               port->shared = 0;
+       module_put(to_hsi_controller(port->device.parent)->owner);
+       mutex_unlock(&port->lock);
+}
+EXPORT_SYMBOL_GPL(hsi_release_port);
+
+static int hsi_start_rx(struct hsi_client *cl, void *data __maybe_unused)
+{
+       if (cl->hsi_start_rx)
+               (*cl->hsi_start_rx)(cl);
+
+       return 0;
+}
+
+static int hsi_stop_rx(struct hsi_client *cl, void *data __maybe_unused)
+{
+       if (cl->hsi_stop_rx)
+               (*cl->hsi_stop_rx)(cl);
+
+       return 0;
+}
+
+static int hsi_port_for_each_client(struct hsi_port *port, void *data,
+                               int (*fn)(struct hsi_client *cl, void *data))
+{
+       struct hsi_client *cl;
+
+       spin_lock(&port->clock);
+       list_for_each_entry(cl, &port->clients, link) {
+               spin_unlock(&port->clock);
+               (*fn)(cl, data);
+               spin_lock(&port->clock);
+       }
+       spin_unlock(&port->clock);
+
+       return 0;
+}
+
+/**
+ * hsi_event -Notifies clients about port events
+ * @port: Port where the event occurred
+ * @event: The event type
+ *
+ * Clients should not be concerned about wake line behavior. However, due
+ * to a race condition in HSI HW protocol, clients need to be notified
+ * about wake line changes, so they can implement a workaround for it.
+ *
+ * Events:
+ * HSI_EVENT_START_RX - Incoming wake line high
+ * HSI_EVENT_STOP_RX - Incoming wake line down
+ */
+void hsi_event(struct hsi_port *port, unsigned int event)
+{
+       int (*fn)(struct hsi_client *cl, void *data);
+
+       switch (event) {
+       case HSI_EVENT_START_RX:
+               fn = hsi_start_rx;
+               break;
+       case HSI_EVENT_STOP_RX:
+               fn = hsi_stop_rx;
+               break;
+       default:
+               return;
+       }
+       hsi_port_for_each_client(port, NULL, fn);
+}
+EXPORT_SYMBOL_GPL(hsi_event);
+
+static int __init hsi_init(void)
+{
+       return bus_register(&hsi_bus_type);
+}
+postcore_initcall(hsi_init);
+
+static void __exit hsi_exit(void)
+{
+       bus_unregister(&hsi_bus_type);
+}
+module_exit(hsi_exit);
+
+MODULE_AUTHOR("Carlos Chinea <carlos.chinea@nokia.com>");
+MODULE_DESCRIPTION("High-speed Synchronous Serial Interface (HSI) framework");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/hsi/hsi_boardinfo.c b/drivers/hsi/hsi_boardinfo.c
new file mode 100644 (file)
index 0000000..e56bc6d
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * HSI clients registration interface
+ *
+ * Copyright (C) 2010 Nokia Corporation. All rights reserved.
+ *
+ * Contact: Carlos Chinea <carlos.chinea@nokia.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 published by the Free Software Foundation.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+#include <linux/hsi/hsi.h>
+#include <linux/list.h>
+#include <linux/slab.h>
+#include "hsi_core.h"
+
+/*
+ * hsi_board_list is only used internally by the HSI framework.
+ * No one else is allowed to make use of it.
+ */
+LIST_HEAD(hsi_board_list);
+EXPORT_SYMBOL_GPL(hsi_board_list);
+
+/**
+ * hsi_register_board_info - Register HSI clients information
+ * @info: Array of HSI clients on the board
+ * @len: Length of the array
+ *
+ * HSI clients are statically declared and registered on board files.
+ *
+ * HSI clients will be automatically registered to the HSI bus once the
+ * controller and the port where the clients wishes to attach are registered
+ * to it.
+ *
+ * Return -errno on failure, 0 on success.
+ */
+int __init hsi_register_board_info(struct hsi_board_info const *info,
+                                                       unsigned int len)
+{
+       struct hsi_cl_info *cl_info;
+
+       cl_info = kzalloc(sizeof(*cl_info) * len, GFP_KERNEL);
+       if (!cl_info)
+               return -ENOMEM;
+
+       for (; len; len--, info++, cl_info++) {
+               cl_info->info = *info;
+               list_add_tail(&cl_info->list, &hsi_board_list);
+       }
+
+       return 0;
+}
diff --git a/drivers/hsi/hsi_core.h b/drivers/hsi/hsi_core.h
new file mode 100644 (file)
index 0000000..ab5c2fb
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * HSI framework internal interfaces,
+ *
+ * Copyright (C) 2010 Nokia Corporation. All rights reserved.
+ *
+ * Contact: Carlos Chinea <carlos.chinea@nokia.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 published by the Free Software Foundation.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#ifndef __LINUX_HSI_CORE_H__
+#define __LINUX_HSI_CORE_H__
+
+#include <linux/hsi/hsi.h>
+
+struct hsi_cl_info {
+       struct list_head        list;
+       struct hsi_board_info   info;
+};
+
+extern struct list_head hsi_board_list;
+
+#endif /* __LINUX_HSI_CORE_H__ */
index 05ed4d0..c0b8c96 100644 (file)
@@ -891,7 +891,7 @@ open_bchannel(struct fritzcard *fc, struct channel_req *rq)
 {
        struct bchannel         *bch;
 
-       if (rq->adr.channel > 2)
+       if (rq->adr.channel == 0 || rq->adr.channel > 2)
                return -EINVAL;
        if (rq->protocol == ISDN_P_NONE)
                return -EINVAL;
index d055ae7..e2c83a2 100644 (file)
@@ -1962,7 +1962,7 @@ open_bchannel(struct hfc_pci *hc, struct channel_req *rq)
 {
        struct bchannel         *bch;
 
-       if (rq->adr.channel > 2)
+       if (rq->adr.channel == 0 || rq->adr.channel > 2)
                return -EINVAL;
        if (rq->protocol == ISDN_P_NONE)
                return -EINVAL;
index 6023387..8cde2a0 100644 (file)
@@ -486,7 +486,7 @@ open_bchannel(struct hfcsusb *hw, struct channel_req *rq)
 {
        struct bchannel         *bch;
 
-       if (rq->adr.channel > 2)
+       if (rq->adr.channel == 0 || rq->adr.channel > 2)
                return -EINVAL;
        if (rq->protocol == ISDN_P_NONE)
                return -EINVAL;
index b47e9be..884369f 100644 (file)
@@ -1506,7 +1506,7 @@ open_bchannel(struct ipac_hw *ipac, struct channel_req *rq)
 {
        struct bchannel         *bch;
 
-       if (rq->adr.channel > 2)
+       if (rq->adr.channel == 0 || rq->adr.channel > 2)
                return -EINVAL;
        if (rq->protocol == ISDN_P_NONE)
                return -EINVAL;
index 10446ab..9a6da6e 100644 (file)
@@ -1670,7 +1670,7 @@ isar_open(struct isar_hw *isar, struct channel_req *rq)
 {
        struct bchannel         *bch;
 
-       if (rq->adr.channel > 2)
+       if (rq->adr.channel == 0 || rq->adr.channel > 2)
                return -EINVAL;
        if (rq->protocol == ISDN_P_NONE)
                return -EINVAL;
index dd6de9f..c726e09 100644 (file)
@@ -860,7 +860,7 @@ open_bchannel(struct tiger_hw *card, struct channel_req *rq)
 {
        struct bchannel *bch;
 
-       if (rq->adr.channel > 2)
+       if (rq->adr.channel == 0 || rq->adr.channel > 2)
                return -EINVAL;
        if (rq->protocol == ISDN_P_NONE)
                return -EINVAL;
index 7f1e7ba..2183357 100644 (file)
@@ -1015,7 +1015,7 @@ open_bchannel(struct w6692_hw *card, struct channel_req *rq)
 {
        struct bchannel *bch;
 
-       if (rq->adr.channel > 2)
+       if (rq->adr.channel == 0 || rq->adr.channel > 2)
                return -EINVAL;
        if (rq->protocol == ISDN_P_NONE)
                return -EINVAL;
index 0c76186..941b4e1 100644 (file)
@@ -891,9 +891,15 @@ static void bond_do_fail_over_mac(struct bonding *bond,
 
        switch (bond->params.fail_over_mac) {
        case BOND_FOM_ACTIVE:
-               if (new_active)
+               if (new_active) {
                        memcpy(bond->dev->dev_addr,  new_active->dev->dev_addr,
                               new_active->dev->addr_len);
+                       write_unlock_bh(&bond->curr_slave_lock);
+                       read_unlock(&bond->lock);
+                       call_netdevice_notifiers(NETDEV_CHANGEADDR, bond->dev);
+                       read_lock(&bond->lock);
+                       write_lock_bh(&bond->curr_slave_lock);
+               }
                break;
        case BOND_FOM_FOLLOW:
                /*
index a59cf96..f219d38 100644 (file)
 #include <linux/if.h>
 #include <linux/if_arp.h>
 #include <linux/if_eql.h>
+#include <linux/pkt_sched.h>
 
 #include <asm/uaccess.h>
 
@@ -143,7 +144,7 @@ static void eql_timer(unsigned long param)
        equalizer_t *eql = (equalizer_t *) param;
        struct list_head *this, *tmp, *head;
 
-       spin_lock_bh(&eql->queue.lock);
+       spin_lock(&eql->queue.lock);
        head = &eql->queue.all_slaves;
        list_for_each_safe(this, tmp, head) {
                slave_t *slave = list_entry(this, slave_t, list);
@@ -157,7 +158,7 @@ static void eql_timer(unsigned long param)
                }
 
        }
-       spin_unlock_bh(&eql->queue.lock);
+       spin_unlock(&eql->queue.lock);
 
        eql->timer.expires = jiffies + EQL_DEFAULT_RESCHED_IVAL;
        add_timer(&eql->timer);
@@ -341,7 +342,7 @@ static netdev_tx_t eql_slave_xmit(struct sk_buff *skb, struct net_device *dev)
                struct net_device *slave_dev = slave->dev;
 
                skb->dev = slave_dev;
-               skb->priority = 1;
+               skb->priority = TC_PRIO_FILLER;
                slave->bytes_queued += skb->len;
                dev_queue_xmit(skb);
                dev->stats.tx_packets++;
index e37161f..2c9ee55 100644 (file)
@@ -1173,6 +1173,13 @@ enum {
 };
 
 
+struct bnx2x_prev_path_list {
+       u8 bus;
+       u8 slot;
+       u8 path;
+       struct list_head list;
+};
+
 struct bnx2x {
        /* Fields used in the tx and intr/napi performance paths
         * are grouped together in the beginning of the structure
index f1f3ca6..44556b7 100644 (file)
@@ -1721,6 +1721,29 @@ static void bnx2x_squeeze_objects(struct bnx2x *bp)
        } while (0)
 #endif
 
+bool bnx2x_test_firmware_version(struct bnx2x *bp, bool is_err)
+{
+       /* build FW version dword */
+       u32 my_fw = (BCM_5710_FW_MAJOR_VERSION) +
+                   (BCM_5710_FW_MINOR_VERSION << 8) +
+                   (BCM_5710_FW_REVISION_VERSION << 16) +
+                   (BCM_5710_FW_ENGINEERING_VERSION << 24);
+
+       /* read loaded FW from chip */
+       u32 loaded_fw = REG_RD(bp, XSEM_REG_PRAM);
+
+       DP(NETIF_MSG_IFUP, "loaded fw %x, my fw %x\n", loaded_fw, my_fw);
+
+       if (loaded_fw != my_fw) {
+               if (is_err)
+                       BNX2X_ERR("bnx2x with FW %x was already loaded, which mismatches my %x FW. aborting\n",
+                                 loaded_fw, my_fw);
+               return false;
+       }
+
+       return true;
+}
+
 /* must be called with rtnl_lock */
 int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
 {
@@ -1815,23 +1838,8 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
                }
                if (load_code != FW_MSG_CODE_DRV_LOAD_COMMON_CHIP &&
                    load_code != FW_MSG_CODE_DRV_LOAD_COMMON) {
-                       /* build FW version dword */
-                       u32 my_fw = (BCM_5710_FW_MAJOR_VERSION) +
-                                       (BCM_5710_FW_MINOR_VERSION << 8) +
-                                       (BCM_5710_FW_REVISION_VERSION << 16) +
-                                       (BCM_5710_FW_ENGINEERING_VERSION << 24);
-
-                       /* read loaded FW from chip */
-                       u32 loaded_fw = REG_RD(bp, XSEM_REG_PRAM);
-
-                       DP(BNX2X_MSG_SP, "loaded fw %x, my fw %x",
-                          loaded_fw, my_fw);
-
                        /* abort nic load if version mismatch */
-                       if (my_fw != loaded_fw) {
-                               BNX2X_ERR("bnx2x with FW %x already loaded, "
-                                         "which mismatches my %x FW. aborting",
-                                         loaded_fw, my_fw);
+                       if (!bnx2x_test_firmware_version(bp, true)) {
                                rc = -EBUSY;
                                LOAD_ERROR_EXIT(bp, load_error2);
                        }
index 8b16338..5c27454 100644 (file)
@@ -431,6 +431,9 @@ void bnx2x_panic_dump(struct bnx2x *bp);
 
 void bnx2x_fw_dump_lvl(struct bnx2x *bp, const char *lvl);
 
+/* validate currect fw is loaded */
+bool bnx2x_test_firmware_version(struct bnx2x *bp, bool is_err);
+
 /* dev_close main block */
 int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode);
 
index 5d71b7d..dbff591 100644 (file)
@@ -1251,6 +1251,9 @@ struct drv_func_mb {
 
        #define DRV_MSG_CODE_LINK_STATUS_CHANGED        0x01000000
 
+       #define DRV_MSG_CODE_INITIATE_FLR               0x02000000
+       #define REQ_BC_VER_4_INITIATE_FLR               0x00070213
+
        #define BIOS_MSG_CODE_LIC_CHALLENGE             0xff010000
        #define BIOS_MSG_CODE_LIC_RESPONSE              0xff020000
        #define BIOS_MSG_CODE_VIRT_MAC_PRIM             0xff030000
index beb4cdb..efa557b 100644 (file)
@@ -35,7 +35,6 @@
 #define ETH_MAX_PACKET_SIZE            1500
 #define ETH_MAX_JUMBO_PACKET_SIZE      9600
 #define MDIO_ACCESS_TIMEOUT            1000
-#define BMAC_CONTROL_RX_ENABLE         2
 #define WC_LANE_MAX                    4
 #define I2C_SWITCH_WIDTH               2
 #define I2C_BSC0                       0
index 7ba557a..763535e 100644 (file)
@@ -89,6 +89,8 @@
 #define PFC_BRB_FULL_LB_XON_THRESHOLD                          250
 
 #define MAXVAL(a, b) (((a) > (b)) ? (a) : (b))
+
+#define BMAC_CONTROL_RX_ENABLE         2
 /***********************************************************/
 /*                         Structs                         */
 /***********************************************************/
index f7f9aa8..e077d25 100644 (file)
@@ -52,6 +52,7 @@
 #include <linux/prefetch.h>
 #include <linux/zlib.h>
 #include <linux/io.h>
+#include <linux/semaphore.h>
 #include <linux/stringify.h>
 #include <linux/vmalloc.h>
 
@@ -211,6 +212,10 @@ static DEFINE_PCI_DEVICE_TABLE(bnx2x_pci_tbl) = {
 
 MODULE_DEVICE_TABLE(pci, bnx2x_pci_tbl);
 
+/* Global resources for unloading a previously loaded device */
+#define BNX2X_PREV_WAIT_NEEDED 1
+static DEFINE_SEMAPHORE(bnx2x_prev_sem);
+static LIST_HEAD(bnx2x_prev_list);
 /****************************************************************************
 * General service functions
 ****************************************************************************/
@@ -8812,109 +8817,371 @@ static inline void bnx2x_undi_int_disable(struct bnx2x *bp)
                bnx2x_undi_int_disable_e1h(bp);
 }
 
-static void __devinit bnx2x_undi_unload(struct bnx2x *bp)
+static void __devinit bnx2x_prev_unload_close_mac(struct bnx2x *bp)
 {
-       u32 val;
+       u32 val, base_addr, offset, mask, reset_reg;
+       bool mac_stopped = false;
+       u8 port = BP_PORT(bp);
 
-       /* possibly another driver is trying to reset the chip */
-       bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_RESET);
+       reset_reg = REG_RD(bp, MISC_REG_RESET_REG_2);
 
-       /* check if doorbell queue is reset */
-       if (REG_RD(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET)
-           & MISC_REGISTERS_RESET_REG_1_RST_DORQ) {
+       if (!CHIP_IS_E3(bp)) {
+               val = REG_RD(bp, NIG_REG_BMAC0_REGS_OUT_EN + port * 4);
+               mask = MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port;
+               if ((mask & reset_reg) && val) {
+                       u32 wb_data[2];
+                       BNX2X_DEV_INFO("Disable bmac Rx\n");
+                       base_addr = BP_PORT(bp) ? NIG_REG_INGRESS_BMAC1_MEM
+                                               : NIG_REG_INGRESS_BMAC0_MEM;
+                       offset = CHIP_IS_E2(bp) ? BIGMAC2_REGISTER_BMAC_CONTROL
+                                               : BIGMAC_REGISTER_BMAC_CONTROL;
 
-               /*
-                * Check if it is the UNDI driver
+                       /*
+                        * use rd/wr since we cannot use dmae. This is safe
+                        * since MCP won't access the bus due to the request
+                        * to unload, and no function on the path can be
+                        * loaded at this time.
+                        */
+                       wb_data[0] = REG_RD(bp, base_addr + offset);
+                       wb_data[1] = REG_RD(bp, base_addr + offset + 0x4);
+                       wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE;
+                       REG_WR(bp, base_addr + offset, wb_data[0]);
+                       REG_WR(bp, base_addr + offset + 0x4, wb_data[1]);
+
+               }
+               BNX2X_DEV_INFO("Disable emac Rx\n");
+               REG_WR(bp, NIG_REG_NIG_EMAC0_EN + BP_PORT(bp)*4, 0);
+
+               mac_stopped = true;
+       } else {
+               if (reset_reg & MISC_REGISTERS_RESET_REG_2_XMAC) {
+                       BNX2X_DEV_INFO("Disable xmac Rx\n");
+                       base_addr = BP_PORT(bp) ? GRCBASE_XMAC1 : GRCBASE_XMAC0;
+                       val = REG_RD(bp, base_addr + XMAC_REG_PFC_CTRL_HI);
+                       REG_WR(bp, base_addr + XMAC_REG_PFC_CTRL_HI,
+                              val & ~(1 << 1));
+                       REG_WR(bp, base_addr + XMAC_REG_PFC_CTRL_HI,
+                              val | (1 << 1));
+                       REG_WR(bp, base_addr + XMAC_REG_CTRL, 0);
+                       mac_stopped = true;
+               }
+               mask = MISC_REGISTERS_RESET_REG_2_UMAC0 << port;
+               if (mask & reset_reg) {
+                       BNX2X_DEV_INFO("Disable umac Rx\n");
+                       base_addr = BP_PORT(bp) ? GRCBASE_UMAC1 : GRCBASE_UMAC0;
+                       REG_WR(bp, base_addr + UMAC_REG_COMMAND_CONFIG, 0);
+                       mac_stopped = true;
+               }
+       }
+
+       if (mac_stopped)
+               msleep(20);
+
+}
+
+#define BNX2X_PREV_UNDI_PROD_ADDR(p) (BAR_TSTRORM_INTMEM + 0x1508 + ((p) << 4))
+#define BNX2X_PREV_UNDI_RCQ(val)       ((val) & 0xffff)
+#define BNX2X_PREV_UNDI_BD(val)                ((val) >> 16 & 0xffff)
+#define BNX2X_PREV_UNDI_PROD(rcq, bd)  ((bd) << 16 | (rcq))
+
+static void __devinit bnx2x_prev_unload_undi_inc(struct bnx2x *bp, u8 port,
+                                                u8 inc)
+{
+       u16 rcq, bd;
+       u32 tmp_reg = REG_RD(bp, BNX2X_PREV_UNDI_PROD_ADDR(port));
+
+       rcq = BNX2X_PREV_UNDI_RCQ(tmp_reg) + inc;
+       bd = BNX2X_PREV_UNDI_BD(tmp_reg) + inc;
+
+       tmp_reg = BNX2X_PREV_UNDI_PROD(rcq, bd);
+       REG_WR(bp, BNX2X_PREV_UNDI_PROD_ADDR(port), tmp_reg);
+
+       BNX2X_DEV_INFO("UNDI producer [%d] rings bd -> 0x%04x, rcq -> 0x%04x\n",
+                      port, bd, rcq);
+}
+
+static int __devinit bnx2x_prev_mcp_done(struct bnx2x *bp)
+{
+       u32 rc = bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE, 0);
+       if (!rc) {
+               BNX2X_ERR("MCP response failure, aborting\n");
+               return -EBUSY;
+       }
+
+       return 0;
+}
+
+static bool __devinit bnx2x_prev_is_path_marked(struct bnx2x *bp)
+{
+       struct bnx2x_prev_path_list *tmp_list;
+       int rc = false;
+
+       if (down_trylock(&bnx2x_prev_sem))
+               return false;
+
+       list_for_each_entry(tmp_list, &bnx2x_prev_list, list) {
+               if (PCI_SLOT(bp->pdev->devfn) == tmp_list->slot &&
+                   bp->pdev->bus->number == tmp_list->bus &&
+                   BP_PATH(bp) == tmp_list->path) {
+                       rc = true;
+                       BNX2X_DEV_INFO("Path %d was already cleaned from previous drivers\n",
+                                      BP_PATH(bp));
+                       break;
+               }
+       }
+
+       up(&bnx2x_prev_sem);
+
+       return rc;
+}
+
+static int __devinit bnx2x_prev_mark_path(struct bnx2x *bp)
+{
+       struct bnx2x_prev_path_list *tmp_list;
+       int rc;
+
+       tmp_list = (struct bnx2x_prev_path_list *)
+                   kmalloc(sizeof(struct bnx2x_prev_path_list), GFP_KERNEL);
+       if (!tmp_list) {
+               BNX2X_ERR("Failed to allocate 'bnx2x_prev_path_list'\n");
+               return -ENOMEM;
+       }
+
+       tmp_list->bus = bp->pdev->bus->number;
+       tmp_list->slot = PCI_SLOT(bp->pdev->devfn);
+       tmp_list->path = BP_PATH(bp);
+
+       rc = down_interruptible(&bnx2x_prev_sem);
+       if (rc) {
+               BNX2X_ERR("Received %d when tried to take lock\n", rc);
+               kfree(tmp_list);
+       } else {
+               BNX2X_DEV_INFO("Marked path [%d] - finished previous unload\n",
+                               BP_PATH(bp));
+               list_add(&tmp_list->list, &bnx2x_prev_list);
+               up(&bnx2x_prev_sem);
+       }
+
+       return rc;
+}
+
+static bool __devinit bnx2x_can_flr(struct bnx2x *bp)
+{
+       int pos;
+       u32 cap;
+       struct pci_dev *dev = bp->pdev;
+
+       pos = pci_pcie_cap(dev);
+       if (!pos)
+               return false;
+
+       pci_read_config_dword(dev, pos + PCI_EXP_DEVCAP, &cap);
+       if (!(cap & PCI_EXP_DEVCAP_FLR))
+               return false;
+
+       return true;
+}
+
+static int __devinit bnx2x_do_flr(struct bnx2x *bp)
+{
+       int i, pos;
+       u16 status;
+       struct pci_dev *dev = bp->pdev;
+
+       /* probe the capability first */
+       if (bnx2x_can_flr(bp))
+               return -ENOTTY;
+
+       pos = pci_pcie_cap(dev);
+       if (!pos)
+               return -ENOTTY;
+
+       /* Wait for Transaction Pending bit clean */
+       for (i = 0; i < 4; i++) {
+               if (i)
+                       msleep((1 << (i - 1)) * 100);
+
+               pci_read_config_word(dev, pos + PCI_EXP_DEVSTA, &status);
+               if (!(status & PCI_EXP_DEVSTA_TRPND))
+                       goto clear;
+       }
+
+       dev_err(&dev->dev,
+               "transaction is not cleared; proceeding with reset anyway\n");
+
+clear:
+       if (bp->common.bc_ver < REQ_BC_VER_4_INITIATE_FLR) {
+               BNX2X_ERR("FLR not supported by BC_VER: 0x%x\n",
+                         bp->common.bc_ver);
+               return -EINVAL;
+       }
+
+       bnx2x_fw_command(bp, DRV_MSG_CODE_INITIATE_FLR, 0);
+
+       return 0;
+}
+
+static int __devinit bnx2x_prev_unload_uncommon(struct bnx2x *bp)
+{
+       int rc;
+
+       BNX2X_DEV_INFO("Uncommon unload Flow\n");
+
+       /* Test if previous unload process was already finished for this path */
+       if (bnx2x_prev_is_path_marked(bp))
+               return bnx2x_prev_mcp_done(bp);
+
+       /* If function has FLR capabilities, and existing FW version matches
+        * the one required, then FLR will be sufficient to clean any residue
+        * left by previous driver
+        */
+       if (bnx2x_test_firmware_version(bp, false) && bnx2x_can_flr(bp))
+               return bnx2x_do_flr(bp);
+
+       /* Close the MCP request, return failure*/
+       rc = bnx2x_prev_mcp_done(bp);
+       if (!rc)
+               rc = BNX2X_PREV_WAIT_NEEDED;
+
+       return rc;
+}
+
+static int __devinit bnx2x_prev_unload_common(struct bnx2x *bp)
+{
+       u32 reset_reg, tmp_reg = 0, rc;
+       /* It is possible a previous function received 'common' answer,
+        * but hasn't loaded yet, therefore creating a scenario of
+        * multiple functions receiving 'common' on the same path.
+        */
+       BNX2X_DEV_INFO("Common unload Flow\n");
+
+       if (bnx2x_prev_is_path_marked(bp))
+               return bnx2x_prev_mcp_done(bp);
+
+       reset_reg = REG_RD(bp, MISC_REG_RESET_REG_1);
+
+       /* Reset should be performed after BRB is emptied */
+       if (reset_reg & MISC_REGISTERS_RESET_REG_1_RST_BRB1) {
+               u32 timer_count = 1000;
+               bool prev_undi = false;
+
+               /* Close the MAC Rx to prevent BRB from filling up */
+               bnx2x_prev_unload_close_mac(bp);
+
+               /* Check if the UNDI driver was previously loaded
                 * UNDI driver initializes CID offset for normal bell to 0x7
                 */
-               val = REG_RD(bp, DORQ_REG_NORM_CID_OFST);
-               if (val == 0x7) {
-                       u32 reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS;
-                       /* save our pf_num */
-                       int orig_pf_num = bp->pf_num;
-                       int port;
-                       u32 swap_en, swap_val, value;
-
-                       /* clear the UNDI indication */
-                       REG_WR(bp, DORQ_REG_NORM_CID_OFST, 0);
-
-                       BNX2X_DEV_INFO("UNDI is active! reset device\n");
-
-                       /* try unload UNDI on port 0 */
-                       bp->pf_num = 0;
-                       bp->fw_seq =
-                             (SHMEM_RD(bp, func_mb[bp->pf_num].drv_mb_header) &
-                               DRV_MSG_SEQ_NUMBER_MASK);
-                       reset_code = bnx2x_fw_command(bp, reset_code, 0);
-
-                       /* if UNDI is loaded on the other port */
-                       if (reset_code != FW_MSG_CODE_DRV_UNLOAD_COMMON) {
-
-                               /* send "DONE" for previous unload */
-                               bnx2x_fw_command(bp,
-                                                DRV_MSG_CODE_UNLOAD_DONE, 0);
-
-                               /* unload UNDI on port 1 */
-                               bp->pf_num = 1;
-                               bp->fw_seq =
-                             (SHMEM_RD(bp, func_mb[bp->pf_num].drv_mb_header) &
-                                       DRV_MSG_SEQ_NUMBER_MASK);
-                               reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS;
-
-                               bnx2x_fw_command(bp, reset_code, 0);
+               reset_reg = REG_RD(bp, MISC_REG_RESET_REG_1);
+               if (reset_reg & MISC_REGISTERS_RESET_REG_1_RST_DORQ) {
+                       tmp_reg = REG_RD(bp, DORQ_REG_NORM_CID_OFST);
+                       if (tmp_reg == 0x7) {
+                               BNX2X_DEV_INFO("UNDI previously loaded\n");
+                               prev_undi = true;
+                               /* clear the UNDI indication */
+                               REG_WR(bp, DORQ_REG_NORM_CID_OFST, 0);
                        }
+               }
+               /* wait until BRB is empty */
+               tmp_reg = REG_RD(bp, BRB1_REG_NUM_OF_FULL_BLOCKS);
+               while (timer_count) {
+                       u32 prev_brb = tmp_reg;
 
-                       bnx2x_undi_int_disable(bp);
-                       port = BP_PORT(bp);
-
-                       /* close input traffic and wait for it */
-                       /* Do not rcv packets to BRB */
-                       REG_WR(bp, (port ? NIG_REG_LLH1_BRB1_DRV_MASK :
-                                          NIG_REG_LLH0_BRB1_DRV_MASK), 0x0);
-                       /* Do not direct rcv packets that are not for MCP to
-                        * the BRB */
-                       REG_WR(bp, (port ? NIG_REG_LLH1_BRB1_NOT_MCP :
-                                          NIG_REG_LLH0_BRB1_NOT_MCP), 0x0);
-                       /* clear AEU */
-                       REG_WR(bp, (port ? MISC_REG_AEU_MASK_ATTN_FUNC_1 :
-                                          MISC_REG_AEU_MASK_ATTN_FUNC_0), 0);
-                       msleep(10);
-
-                       /* save NIG port swap info */
-                       swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
-                       swap_en = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
-                       /* reset device */
-                       REG_WR(bp,
-                              GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_CLEAR,
-                              0xd3ffffff);
-
-                       value = 0x1400;
-                       if (CHIP_IS_E3(bp)) {
-                               value |= MISC_REGISTERS_RESET_REG_2_MSTAT0;
-                               value |= MISC_REGISTERS_RESET_REG_2_MSTAT1;
-                       }
+                       tmp_reg = REG_RD(bp, BRB1_REG_NUM_OF_FULL_BLOCKS);
+                       if (!tmp_reg)
+                               break;
 
-                       REG_WR(bp,
-                              GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
-                              value);
+                       BNX2X_DEV_INFO("BRB still has 0x%08x\n", tmp_reg);
 
-                       /* take the NIG out of reset and restore swap values */
-                       REG_WR(bp,
-                              GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET,
-                              MISC_REGISTERS_RESET_REG_1_RST_NIG);
-                       REG_WR(bp, NIG_REG_PORT_SWAP, swap_val);
-                       REG_WR(bp, NIG_REG_STRAP_OVERRIDE, swap_en);
+                       /* reset timer as long as BRB actually gets emptied */
+                       if (prev_brb > tmp_reg)
+                               timer_count = 1000;
+                       else
+                               timer_count--;
 
-                       /* send unload done to the MCP */
-                       bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE, 0);
+                       /* If UNDI resides in memory, manually increment it */
+                       if (prev_undi)
+                               bnx2x_prev_unload_undi_inc(bp, BP_PORT(bp), 1);
 
-                       /* restore our func and fw_seq */
-                       bp->pf_num = orig_pf_num;
+                       udelay(10);
                }
+
+               if (!timer_count)
+                       BNX2X_ERR("Failed to empty BRB, hope for the best\n");
+
        }
 
-       /* now it's safe to release the lock */
-       bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_RESET);
+       /* No packets are in the pipeline, path is ready for reset */
+       bnx2x_reset_common(bp);
+
+       rc = bnx2x_prev_mark_path(bp);
+       if (rc) {
+               bnx2x_prev_mcp_done(bp);
+               return rc;
+       }
+
+       return bnx2x_prev_mcp_done(bp);
+}
+
+static int __devinit bnx2x_prev_unload(struct bnx2x *bp)
+{
+       int time_counter = 10;
+       u32 rc, fw, hw_lock_reg, hw_lock_val;
+       BNX2X_DEV_INFO("Entering Previous Unload Flow\n");
+
+       /* Release previously held locks */
+       hw_lock_reg = (BP_FUNC(bp) <= 5) ?
+                     (MISC_REG_DRIVER_CONTROL_1 + BP_FUNC(bp) * 8) :
+                     (MISC_REG_DRIVER_CONTROL_7 + (BP_FUNC(bp) - 6) * 8);
+
+       hw_lock_val = (REG_RD(bp, hw_lock_reg));
+       if (hw_lock_val) {
+               if (hw_lock_val & HW_LOCK_RESOURCE_NVRAM) {
+                       BNX2X_DEV_INFO("Release Previously held NVRAM lock\n");
+                       REG_WR(bp, MCP_REG_MCPR_NVM_SW_ARB,
+                              (MCPR_NVM_SW_ARB_ARB_REQ_CLR1 << BP_PORT(bp)));
+               }
+
+               BNX2X_DEV_INFO("Release Previously held hw lock\n");
+               REG_WR(bp, hw_lock_reg, 0xffffffff);
+       } else
+               BNX2X_DEV_INFO("No need to release hw/nvram locks\n");
+
+       if (MCPR_ACCESS_LOCK_LOCK & REG_RD(bp, MCP_REG_MCPR_ACCESS_LOCK)) {
+               BNX2X_DEV_INFO("Release previously held alr\n");
+               REG_WR(bp, MCP_REG_MCPR_ACCESS_LOCK, 0);
+       }
+
+
+       do {
+               /* Lock MCP using an unload request */
+               fw = bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS, 0);
+               if (!fw) {
+                       BNX2X_ERR("MCP response failure, aborting\n");
+                       rc = -EBUSY;
+                       break;
+               }
+
+               if (fw == FW_MSG_CODE_DRV_UNLOAD_COMMON) {
+                       rc = bnx2x_prev_unload_common(bp);
+                       break;
+               }
+
+               /* non-common reply from MCP night require looping */
+               rc = bnx2x_prev_unload_uncommon(bp);
+               if (rc != BNX2X_PREV_WAIT_NEEDED)
+                       break;
+
+               msleep(20);
+       } while (--time_counter);
+
+       if (!time_counter || rc) {
+               BNX2X_ERR("Failed unloading previous driver, aborting\n");
+               rc = -EBUSY;
+       }
+
+       BNX2X_DEV_INFO("Finished Previous Unload Flow [%d]\n", rc);
+
+       return rc;
 }
 
 static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp)
@@ -10100,8 +10367,16 @@ static int __devinit bnx2x_init_bp(struct bnx2x *bp)
        func = BP_FUNC(bp);
 
        /* need to reset chip if undi was active */
-       if (!BP_NOMCP(bp))
-               bnx2x_undi_unload(bp);
+       if (!BP_NOMCP(bp)) {
+               /* init fw_seq */
+               bp->fw_seq =
+                       SHMEM_RD(bp, func_mb[BP_FW_MB_IDX(bp)].drv_mb_header) &
+                                                       DRV_MSG_SEQ_NUMBER_MASK;
+               BNX2X_DEV_INFO("fw_seq 0x%08x\n", bp->fw_seq);
+
+               bnx2x_prev_unload(bp);
+       }
+
 
        if (CHIP_REV_IS_FPGA(bp))
                dev_err(&bp->pdev->dev, "FPGA detected\n");
@@ -11431,9 +11706,18 @@ static int __init bnx2x_init(void)
 
 static void __exit bnx2x_cleanup(void)
 {
+       struct list_head *pos, *q;
        pci_unregister_driver(&bnx2x_pci_driver);
 
        destroy_workqueue(bnx2x_wq);
+
+       /* Free globablly allocated resources */
+       list_for_each_safe(pos, q, &bnx2x_prev_list) {
+               struct bnx2x_prev_path_list *tmp =
+                       list_entry(pos, struct bnx2x_prev_path_list, list);
+               list_del(pos);
+               kfree(tmp);
+       }
 }
 
 void bnx2x_notify_link_changed(struct bnx2x *bp)
index fd7fb45..ab0a250 100644 (file)
  * clear; 1 = set. Data valid only in addresses 0-4. all the rest are zero. */
 #define IGU_REG_WRITE_DONE_PENDING                              0x130480
 #define MCP_A_REG_MCPR_SCRATCH                                  0x3a0000
+#define MCP_REG_MCPR_ACCESS_LOCK                                0x8009c
 #define MCP_REG_MCPR_CPU_PROGRAM_COUNTER                        0x8501c
 #define MCP_REG_MCPR_GP_INPUTS                                  0x800c0
 #define MCP_REG_MCPR_GP_OENABLE                                         0x800c8
    [10] rst_dbg; [11] rst_misc_core; [12] rst_dbue (UART); [13]
    Pci_resetmdio_n; [14] rst_emac0_hard_core; [15] rst_emac1_hard_core; 16]
    rst_pxp_rq_rd_wr; 31:17] reserved */
+#define MISC_REG_RESET_REG_1                                    0xa580
 #define MISC_REG_RESET_REG_2                                    0xa590
 /* [RW 20] 20 bit GRC address where the scratch-pad of the MCP that is
    shared with the driver resides */
 /* [RC 32] Parity register #0 read clear */
 #define XSEM_REG_XSEM_PRTY_STS_CLR_0                            0x280128
 #define XSEM_REG_XSEM_PRTY_STS_CLR_1                            0x280138
+#define MCPR_ACCESS_LOCK_LOCK                                   (1L<<31)
 #define MCPR_NVM_ACCESS_ENABLE_EN                               (1L<<0)
 #define MCPR_NVM_ACCESS_ENABLE_WR_EN                            (1L<<1)
 #define MCPR_NVM_ADDR_NVM_ADDR_VALUE                            (0xffffffL<<0)
 #define MISC_REGISTERS_GPIO_PORT_SHIFT                          4
 #define MISC_REGISTERS_GPIO_SET_POS                             8
 #define MISC_REGISTERS_RESET_REG_1_CLEAR                        0x588
+#define MISC_REGISTERS_RESET_REG_1_RST_BRB1                     (0x1<<0)
 #define MISC_REGISTERS_RESET_REG_1_RST_DORQ                     (0x1<<19)
 #define MISC_REGISTERS_RESET_REG_1_RST_HC                       (0x1<<29)
 #define MISC_REGISTERS_RESET_REG_1_RST_NIG                      (0x1<<7)
index 3f52fad..5135733 100644 (file)
@@ -3847,7 +3847,7 @@ static bool bnx2x_credit_pool_get_entry(
                        continue;
 
                /* If we've got here we are going to find a free entry */
-               for (idx = vec * BNX2X_POOL_VEC_SIZE, i = 0;
+               for (idx = vec * BIT_VEC64_ELEM_SZ, i = 0;
                      i < BIT_VEC64_ELEM_SZ; idx++, i++)
 
                        if (BIT_VEC64_TEST_BIT(o->pool_mirror, idx)) {
index 4e4bb38..062ac33 100644 (file)
@@ -2778,7 +2778,9 @@ static void tg3_power_down_phy(struct tg3 *tp, bool do_low_power)
        if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 ||
            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 ||
            (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780 &&
-            (tp->phy_flags & TG3_PHYFLG_MII_SERDES)))
+            (tp->phy_flags & TG3_PHYFLG_MII_SERDES)) ||
+           (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 &&
+            !tp->pci_fn))
                return;
 
        if (GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5784_AX ||
index 9eb8159..f7f0bf5 100644 (file)
@@ -356,13 +356,13 @@ static int fsl_pq_mdio_probe(struct platform_device *ofdev)
 
                if (prop)
                        tbiaddr = *prop;
-       }
 
-       if (tbiaddr == -1) {
-               err = -EBUSY;
-               goto err_free_irqs;
-       } else {
-               out_be32(tbipa, tbiaddr);
+               if (tbiaddr == -1) {
+                       err = -EBUSY;
+                       goto err_free_irqs;
+               } else {
+                       out_be32(tbipa, tbiaddr);
+               }
        }
 
        err = of_mdiobus_register(new_bus, np);
index 4e3cd2f..17a46e7 100644 (file)
@@ -3945,6 +3945,8 @@ static int ucc_geth_probe(struct platform_device* ofdev)
                }
 
        if (max_speed == SPEED_1000) {
+               unsigned int snums = qe_get_num_of_snums();
+
                /* configure muram FIFOs for gigabit operation */
                ug_info->uf_info.urfs = UCC_GETH_URFS_GIGA_INIT;
                ug_info->uf_info.urfet = UCC_GETH_URFET_GIGA_INIT;
@@ -3954,11 +3956,11 @@ static int ucc_geth_probe(struct platform_device* ofdev)
                ug_info->uf_info.utftt = UCC_GETH_UTFTT_GIGA_INIT;
                ug_info->numThreadsTx = UCC_GETH_NUM_OF_THREADS_4;
 
-               /* If QE's snum number is 46 which means we need to support
+               /* If QE's snum number is 46/76 which means we need to support
                 * 4 UECs at 1000Base-T simultaneously, we need to allocate
                 * more Threads to Rx.
                 */
-               if (qe_get_num_of_snums() == 46)
+               if ((snums == 76) || (snums == 46))
                        ug_info->numThreadsRx = UCC_GETH_NUM_OF_THREADS_6;
                else
                        ug_info->numThreadsRx = UCC_GETH_NUM_OF_THREADS_4;
index 0e9aec8..4348b6f 100644 (file)
@@ -164,6 +164,8 @@ static int e1000_82547_fifo_workaround(struct e1000_adapter *adapter,
 static bool e1000_vlan_used(struct e1000_adapter *adapter);
 static void e1000_vlan_mode(struct net_device *netdev,
                            netdev_features_t features);
+static void e1000_vlan_filter_on_off(struct e1000_adapter *adapter,
+                                    bool filter_on);
 static int e1000_vlan_rx_add_vid(struct net_device *netdev, u16 vid);
 static int e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid);
 static void e1000_restore_vlan(struct e1000_adapter *adapter);
@@ -215,7 +217,8 @@ MODULE_DESCRIPTION("Intel(R) PRO/1000 Network Driver");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_VERSION);
 
-static int debug = NETIF_MSG_DRV | NETIF_MSG_PROBE;
+#define DEFAULT_MSG_ENABLE (NETIF_MSG_DRV|NETIF_MSG_PROBE|NETIF_MSG_LINK)
+static int debug = -1;
 module_param(debug, int, 0);
 MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
 
@@ -979,7 +982,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
        adapter = netdev_priv(netdev);
        adapter->netdev = netdev;
        adapter->pdev = pdev;
-       adapter->msg_enable = (1 << debug) - 1;
+       adapter->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE);
        adapter->bars = bars;
        adapter->need_ioport = need_ioport;
 
@@ -1214,7 +1217,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
        if (err)
                goto err_register;
 
-       e1000_vlan_mode(netdev, netdev->features);
+       e1000_vlan_filter_on_off(adapter, false);
 
        /* print bus type/speed/width info */
        e_info(probe, "(PCI%s:%dMHz:%d-bit) %pM\n",
@@ -4770,6 +4773,22 @@ static bool e1000_vlan_used(struct e1000_adapter *adapter)
        return false;
 }
 
+static void __e1000_vlan_mode(struct e1000_adapter *adapter,
+                             netdev_features_t features)
+{
+       struct e1000_hw *hw = &adapter->hw;
+       u32 ctrl;
+
+       ctrl = er32(CTRL);
+       if (features & NETIF_F_HW_VLAN_RX) {
+               /* enable VLAN tag insert/strip */
+               ctrl |= E1000_CTRL_VME;
+       } else {
+               /* disable VLAN tag insert/strip */
+               ctrl &= ~E1000_CTRL_VME;
+       }
+       ew32(CTRL, ctrl);
+}
 static void e1000_vlan_filter_on_off(struct e1000_adapter *adapter,
                                     bool filter_on)
 {
@@ -4779,6 +4798,7 @@ static void e1000_vlan_filter_on_off(struct e1000_adapter *adapter,
        if (!test_bit(__E1000_DOWN, &adapter->flags))
                e1000_irq_disable(adapter);
 
+       __e1000_vlan_mode(adapter, adapter->netdev->features);
        if (filter_on) {
                /* enable VLAN receive filtering */
                rctl = er32(RCTL);
@@ -4799,24 +4819,14 @@ static void e1000_vlan_filter_on_off(struct e1000_adapter *adapter,
 }
 
 static void e1000_vlan_mode(struct net_device *netdev,
-       netdev_features_t features)
+                           netdev_features_t features)
 {
        struct e1000_adapter *adapter = netdev_priv(netdev);
-       struct e1000_hw *hw = &adapter->hw;
-       u32 ctrl;
 
        if (!test_bit(__E1000_DOWN, &adapter->flags))
                e1000_irq_disable(adapter);
 
-       ctrl = er32(CTRL);
-       if (features & NETIF_F_HW_VLAN_RX) {
-               /* enable VLAN tag insert/strip */
-               ctrl |= E1000_CTRL_VME;
-       } else {
-               /* disable VLAN tag insert/strip */
-               ctrl &= ~E1000_CTRL_VME;
-       }
-       ew32(CTRL, ctrl);
+       __e1000_vlan_mode(adapter, features);
 
        if (!test_bit(__E1000_DOWN, &adapter->flags))
                e1000_irq_enable(adapter);
index 7152eb1..2c38a65 100644 (file)
 char e1000e_driver_name[] = "e1000e";
 const char e1000e_driver_version[] = DRV_VERSION;
 
+#define DEFAULT_MSG_ENABLE (NETIF_MSG_DRV|NETIF_MSG_PROBE|NETIF_MSG_LINK)
+static int debug = -1;
+module_param(debug, int, 0);
+MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
+
 static void e1000e_disable_aspm(struct pci_dev *pdev, u16 state);
 
 static const struct e1000_info *e1000_info_tbl[] = {
@@ -6172,7 +6177,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
        adapter->hw.adapter = adapter;
        adapter->hw.mac.type = ei->mac;
        adapter->max_hw_frame_size = ei->max_hw_frame_size;
-       adapter->msg_enable = (1 << NETIF_MSG_DRV | NETIF_MSG_PROBE) - 1;
+       adapter->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE);
 
        mmio_start = pci_resource_start(pdev, 0);
        mmio_len = pci_resource_len(pdev, 0);
index c490241..5ec3159 100644 (file)
@@ -238,6 +238,11 @@ MODULE_DESCRIPTION("Intel(R) Gigabit Ethernet Network Driver");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_VERSION);
 
+#define DEFAULT_MSG_ENABLE (NETIF_MSG_DRV|NETIF_MSG_PROBE|NETIF_MSG_LINK)
+static int debug = -1;
+module_param(debug, int, 0);
+MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
+
 struct igb_reg_info {
        u32 ofs;
        char *name;
@@ -1893,7 +1898,7 @@ static int __devinit igb_probe(struct pci_dev *pdev,
        adapter->pdev = pdev;
        hw = &adapter->hw;
        hw->back = adapter;
-       adapter->msg_enable = NETIF_MSG_DRV | NETIF_MSG_PROBE;
+       adapter->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE);
 
        mmio_start = pci_resource_start(pdev, 0);
        mmio_len = pci_resource_len(pdev, 0);
index 217c143..d61ca2a 100644 (file)
@@ -55,6 +55,11 @@ static const char igbvf_driver_string[] =
 static const char igbvf_copyright[] =
                  "Copyright (c) 2009 - 2012 Intel Corporation.";
 
+#define DEFAULT_MSG_ENABLE (NETIF_MSG_DRV|NETIF_MSG_PROBE|NETIF_MSG_LINK)
+static int debug = -1;
+module_param(debug, int, 0);
+MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
+
 static int igbvf_poll(struct napi_struct *napi, int budget);
 static void igbvf_reset(struct igbvf_adapter *);
 static void igbvf_set_interrupt_capability(struct igbvf_adapter *);
@@ -2649,7 +2654,7 @@ static int __devinit igbvf_probe(struct pci_dev *pdev,
        adapter->flags = ei->flags;
        adapter->hw.back = adapter;
        adapter->hw.mac.type = ei->mac;
-       adapter->msg_enable = (1 << NETIF_MSG_DRV | NETIF_MSG_PROBE) - 1;
+       adapter->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE);
 
        /* PCI config space info */
 
index 82aaa79..5fce363 100644 (file)
@@ -134,8 +134,8 @@ MODULE_DESCRIPTION("Intel(R) PRO/10GbE Network Driver");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_VERSION);
 
-#define DEFAULT_DEBUG_LEVEL_SHIFT 3
-static int debug = DEFAULT_DEBUG_LEVEL_SHIFT;
+#define DEFAULT_MSG_ENABLE (NETIF_MSG_DRV|NETIF_MSG_PROBE|NETIF_MSG_LINK)
+static int debug = -1;
 module_param(debug, int, 0);
 MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
 
@@ -442,7 +442,7 @@ ixgb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        adapter->netdev = netdev;
        adapter->pdev = pdev;
        adapter->hw.back = adapter;
-       adapter->msg_enable = netif_msg_init(debug, DEFAULT_DEBUG_LEVEL_SHIFT);
+       adapter->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE);
 
        adapter->hw.hw_addr = pci_ioremap_bar(pdev, BAR_0);
        if (!adapter->hw.hw_addr) {
index 80e26ff..74e1921 100644 (file)
@@ -544,7 +544,7 @@ struct ixgbe_fdir_filter {
        u16 action;
 };
 
-enum ixbge_state_t {
+enum ixgbe_state_t {
        __IXGBE_TESTING,
        __IXGBE_RESETTING,
        __IXGBE_DOWN,
index 398fc22..3e26b1f 100644 (file)
@@ -63,8 +63,8 @@ static char ixgbe_default_device_descr[] =
                              "Intel(R) 10 Gigabit Network Connection";
 #endif
 #define MAJ 3
-#define MIN 6
-#define BUILD 7
+#define MIN 8
+#define BUILD 21
 #define DRV_VERSION __stringify(MAJ) "." __stringify(MIN) "." \
        __stringify(BUILD) "-k"
 const char ixgbe_driver_version[] = DRV_VERSION;
@@ -141,13 +141,16 @@ module_param(allow_unsupported_sfp, uint, 0);
 MODULE_PARM_DESC(allow_unsupported_sfp,
                 "Allow unsupported and untested SFP+ modules on 82599-based adapters");
 
+#define DEFAULT_MSG_ENABLE (NETIF_MSG_DRV|NETIF_MSG_PROBE|NETIF_MSG_LINK)
+static int debug = -1;
+module_param(debug, int, 0);
+MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
+
 MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>");
 MODULE_DESCRIPTION("Intel(R) 10 Gigabit PCI Express Network Driver");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_VERSION);
 
-#define DEFAULT_DEBUG_LEVEL_SHIFT 3
-
 static void ixgbe_service_event_schedule(struct ixgbe_adapter *adapter)
 {
        if (!test_bit(__IXGBE_DOWN, &adapter->state) &&
@@ -6834,7 +6837,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
        adapter->pdev = pdev;
        hw = &adapter->hw;
        hw->back = adapter;
-       adapter->msg_enable = (1 << DEFAULT_DEBUG_LEVEL_SHIFT) - 1;
+       adapter->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE);
 
        hw->hw_addr = ioremap(pci_resource_start(pdev, 0),
                              pci_resource_len(pdev, 0));
index 581c659..307611a 100644 (file)
@@ -91,7 +91,10 @@ MODULE_DESCRIPTION("Intel(R) 82599 Virtual Function Driver");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_VERSION);
 
-#define DEFAULT_DEBUG_LEVEL_SHIFT 3
+#define DEFAULT_MSG_ENABLE (NETIF_MSG_DRV|NETIF_MSG_PROBE|NETIF_MSG_LINK)
+static int debug = -1;
+module_param(debug, int, 0);
+MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
 
 /* forward decls */
 static void ixgbevf_set_itr_msix(struct ixgbevf_q_vector *q_vector);
@@ -3367,7 +3370,7 @@ static int __devinit ixgbevf_probe(struct pci_dev *pdev,
        adapter->pdev = pdev;
        hw = &adapter->hw;
        hw->back = adapter;
-       adapter->msg_enable = (1 << DEFAULT_DEBUG_LEVEL_SHIFT) - 1;
+       adapter->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE);
 
        /*
         * call save state here in standalone driver because it relies on
index 423a1a2..b806d9b 100644 (file)
@@ -1767,13 +1767,14 @@ static int sky2_open(struct net_device *dev)
 
        sky2_hw_up(sky2);
 
+       /* Enable interrupts from phy/mac for port */
+       imask = sky2_read32(hw, B0_IMSK);
+
        if (hw->chip_id == CHIP_ID_YUKON_OPT ||
            hw->chip_id == CHIP_ID_YUKON_PRM ||
            hw->chip_id == CHIP_ID_YUKON_OP_2)
                imask |= Y2_IS_PHY_QLNK;        /* enable PHY Quick Link */
 
-       /* Enable interrupts from phy/mac for port */
-       imask = sky2_read32(hw, B0_IMSK);
        imask |= portirq_msk[port];
        sky2_write32(hw, B0_IMSK, imask);
        sky2_read32(hw, B0_IMSK);
index 6944424..6dfc26d 100644 (file)
@@ -1441,7 +1441,7 @@ static int lpc_eth_drv_probe(struct platform_device *pdev)
        }
 #endif
        if (!is_valid_ether_addr(ndev->dev_addr))
-               dev_hw_addr_random(ndev, ndev->dev_addr);
+               eth_hw_addr_random(ndev);
 
        /* Reset the ethernet controller */
        __lpc_eth_reset(pldat);
index 9755b49..3fb2355 100644 (file)
@@ -7,7 +7,8 @@ config SH_ETH
        depends on SUPERH && \
                (CPU_SUBTYPE_SH7710 || CPU_SUBTYPE_SH7712 || \
                 CPU_SUBTYPE_SH7763 || CPU_SUBTYPE_SH7619 || \
-                CPU_SUBTYPE_SH7724 || CPU_SUBTYPE_SH7757)
+                CPU_SUBTYPE_SH7724 || CPU_SUBTYPE_SH7734 || \
+                CPU_SUBTYPE_SH7757)
        select CRC32
        select NET_CORE
        select MII
@@ -16,4 +17,4 @@ config SH_ETH
        ---help---
          Renesas SuperH Ethernet device driver.
          This driver supporting CPUs are:
-               - SH7710, SH7712, SH7763, SH7619, SH7724, and SH7757.
+               - SH7619, SH7710, SH7712, SH7724, SH7734, SH7763 and SH7757.
index 8615961..d63e09b 100644 (file)
@@ -1,8 +1,8 @@
 /*
  *  SuperH Ethernet device driver
  *
- *  Copyright (C) 2006-2008 Nobuhiro Iwamatsu
- *  Copyright (C) 2008-2009 Renesas Solutions Corp.
+ *  Copyright (C) 2006-2012 Nobuhiro Iwamatsu
+ *  Copyright (C) 2008-2012 Renesas Solutions Corp.
  *
  *  This program is free software; you can redistribute it and/or modify it
  *  under the terms and conditions of the GNU General Public License,
@@ -38,6 +38,7 @@
 #include <linux/slab.h>
 #include <linux/ethtool.h>
 #include <linux/if_vlan.h>
+#include <linux/clk.h>
 #include <linux/sh_eth.h>
 
 #include "sh_eth.h"
@@ -279,8 +280,9 @@ static struct sh_eth_cpu_data *sh_eth_get_cpu_data(struct sh_eth_private *mdp)
                return &sh_eth_my_cpu_data;
 }
 
-#elif defined(CONFIG_CPU_SUBTYPE_SH7763)
+#elif defined(CONFIG_CPU_SUBTYPE_SH7734) || defined(CONFIG_CPU_SUBTYPE_SH7763)
 #define SH_ETH_HAS_TSU 1
+static void sh_eth_reset_hw_crc(struct net_device *ndev);
 static void sh_eth_chip_reset(struct net_device *ndev)
 {
        struct sh_eth_private *mdp = netdev_priv(ndev);
@@ -314,6 +316,9 @@ static void sh_eth_reset(struct net_device *ndev)
        sh_eth_write(ndev, 0x0, RDFAR);
        sh_eth_write(ndev, 0x0, RDFXR);
        sh_eth_write(ndev, 0x0, RDFFR);
+
+       /* Reset HW CRC register */
+       sh_eth_reset_hw_crc(ndev);
 }
 
 static void sh_eth_set_duplex(struct net_device *ndev)
@@ -370,8 +375,17 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
        .no_trimd       = 1,
        .no_ade         = 1,
        .tsu            = 1,
+#if defined(CONFIG_CPU_SUBTYPE_SH7734)
+       .hw_crc     = 1,
+#endif
 };
 
+static void sh_eth_reset_hw_crc(struct net_device *ndev)
+{
+       if (sh_eth_my_cpu_data.hw_crc)
+               sh_eth_write(ndev, 0x0, CSMR);
+}
+
 #elif defined(CONFIG_CPU_SUBTYPE_SH7619)
 #define SH_ETH_RESET_DEFAULT   1
 static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
@@ -790,7 +804,7 @@ static int sh_eth_dev_init(struct net_device *ndev)
        /* all sh_eth int mask */
        sh_eth_write(ndev, 0, EESIPR);
 
-#if defined(__LITTLE_ENDIAN__)
+#if defined(__LITTLE_ENDIAN)
        if (mdp->cd->hw_swap)
                sh_eth_write(ndev, EDMR_EL, EDMR);
        else
index 57dc262..0fa14af 100644 (file)
@@ -1,8 +1,8 @@
 /*
  *  SuperH Ethernet device driver
  *
- *  Copyright (C) 2006-2008 Nobuhiro Iwamatsu
- *  Copyright (C) 2008-2011 Renesas Solutions Corp.
+ *  Copyright (C) 2006-2012 Nobuhiro Iwamatsu
+ *  Copyright (C) 2008-2012 Renesas Solutions Corp.
  *
  *  This program is free software; you can redistribute it and/or modify it
  *  under the terms and conditions of the GNU General Public License,
@@ -98,6 +98,8 @@ enum {
        CEECR,
        MAFCR,
        RTRATE,
+       CSMR,
+       RMII_MII,
 
        /* TSU Absolute address */
        ARSTR,
@@ -172,6 +174,7 @@ static const u16 sh_eth_offset_gigabit[SH_ETH_MAX_REGISTER_OFFSET] = {
        [RMCR]  = 0x0458,
        [RPADIR]        = 0x0460,
        [FCFTR] = 0x0468,
+       [CSMR] = 0x04E4,
 
        [ECMR]  = 0x0500,
        [ECSR]  = 0x0510,
@@ -200,6 +203,7 @@ static const u16 sh_eth_offset_gigabit[SH_ETH_MAX_REGISTER_OFFSET] = {
        [CERCR] = 0x0768,
        [CEECR] = 0x0770,
        [MAFCR] = 0x0778,
+       [RMII_MII] =  0x0790,
 
        [ARSTR] = 0x0000,
        [TSU_CTRST]     = 0x0004,
@@ -377,7 +381,7 @@ static const u16 sh_eth_offset_fast_sh3_sh2[SH_ETH_MAX_REGISTER_OFFSET] = {
 /*
  * Register's bits
  */
-#ifdef CONFIG_CPU_SUBTYPE_SH7763
+#if defined(CONFIG_CPU_SUBTYPE_SH7734) || defined(CONFIG_CPU_SUBTYPE_SH7763)
 /* EDSR */
 enum EDSR_BIT {
        EDSR_ENT = 0x01, EDSR_ENR = 0x02,
@@ -689,7 +693,7 @@ enum TSU_FWSLC_BIT {
  */
 struct sh_eth_txdesc {
        u32 status;             /* TD0 */
-#if defined(CONFIG_CPU_LITTLE_ENDIAN)
+#if defined(__LITTLE_ENDIAN)
        u16 pad0;               /* TD1 */
        u16 buffer_length;      /* TD1 */
 #else
@@ -706,7 +710,7 @@ struct sh_eth_txdesc {
  */
 struct sh_eth_rxdesc {
        u32 status;             /* RD0 */
-#if defined(CONFIG_CPU_LITTLE_ENDIAN)
+#if defined(__LITTLE_ENDIAN)
        u16 frame_length;       /* RD1 */
        u16 buffer_length;      /* RD1 */
 #else
@@ -751,6 +755,7 @@ struct sh_eth_cpu_data {
        unsigned rpadir:1;              /* E-DMAC have RPADIR */
        unsigned no_trimd:1;            /* E-DMAC DO NOT have TRIMD */
        unsigned no_ade:1;      /* E-DMAC DO NOT have ADE bit in EESR */
+       unsigned hw_crc:1;      /* E-DMAC have CSMR */
 };
 
 struct sh_eth_private {
index 39b8cf3..fcfa01f 100644 (file)
@@ -503,30 +503,32 @@ static int rhine_vlan_rx_add_vid(struct net_device *dev, unsigned short vid);
 static int rhine_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid);
 static void rhine_restart_tx(struct net_device *dev);
 
-static void rhine_wait_bit(struct rhine_private *rp, u8 reg, u8 mask, bool high)
+static void rhine_wait_bit(struct rhine_private *rp, u8 reg, u8 mask, bool low)
 {
        void __iomem *ioaddr = rp->base;
        int i;
 
        for (i = 0; i < 1024; i++) {
-               if (high ^ !!(ioread8(ioaddr + reg) & mask))
+               bool has_mask_bits = !!(ioread8(ioaddr + reg) & mask);
+
+               if (low ^ has_mask_bits)
                        break;
                udelay(10);
        }
        if (i > 64) {
                netif_dbg(rp, hw, rp->dev, "%s bit wait (%02x/%02x) cycle "
-                         "count: %04d\n", high ? "high" : "low", reg, mask, i);
+                         "count: %04d\n", low ? "low" : "high", reg, mask, i);
        }
 }
 
 static void rhine_wait_bit_high(struct rhine_private *rp, u8 reg, u8 mask)
 {
-       rhine_wait_bit(rp, reg, mask, true);
+       rhine_wait_bit(rp, reg, mask, false);
 }
 
 static void rhine_wait_bit_low(struct rhine_private *rp, u8 reg, u8 mask)
 {
-       rhine_wait_bit(rp, reg, mask, false);
+       rhine_wait_bit(rp, reg, mask, true);
 }
 
 static u32 rhine_get_events(struct rhine_private *rp)
index a57f057..91d2588 100644 (file)
@@ -375,8 +375,8 @@ static void rionet_remove(struct rio_dev *rdev)
        struct net_device *ndev = rio_get_drvdata(rdev);
        struct rionet_peer *peer, *tmp;
 
-       free_pages((unsigned long)rionet_active, rdev->net->hport->sys_size ?
-                                       __fls(sizeof(void *)) + 4 : 0);
+       free_pages((unsigned long)rionet_active, get_order(sizeof(void *) *
+                       RIO_MAX_ROUTE_ENTRIES(rdev->net->hport->sys_size)));
        unregister_netdev(ndev);
        free_netdev(ndev);
 
@@ -432,15 +432,16 @@ static int rionet_setup_netdev(struct rio_mport *mport, struct net_device *ndev)
        int rc = 0;
        struct rionet_private *rnet;
        u16 device_id;
+       const size_t rionet_active_bytes = sizeof(void *) *
+                               RIO_MAX_ROUTE_ENTRIES(mport->sys_size);
 
        rionet_active = (struct rio_dev **)__get_free_pages(GFP_KERNEL,
-                       mport->sys_size ? __fls(sizeof(void *)) + 4 : 0);
+                       get_order(rionet_active_bytes));
        if (!rionet_active) {
                rc = -ENOMEM;
                goto out;
        }
-       memset((void *)rionet_active, 0, sizeof(void *) *
-                               RIO_MAX_ROUTE_ENTRIES(mport->sys_size));
+       memset((void *)rionet_active, 0, rionet_active_bytes);
 
        /* Set up private area */
        rnet = netdev_priv(ndev);
index 3886b30..3e41b00 100644 (file)
@@ -165,13 +165,13 @@ static void rx_complete(struct urb *req)
                                memcpy(skb_put(skb, 1), page_address(page), 1);
                                skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags,
                                                page, 1, req->actual_length,
-                                               req->actual_length);
+                                               PAGE_SIZE);
                                page = NULL;
                        }
                } else {
                        skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags,
                                        page, 0, req->actual_length,
-                                       req->actual_length);
+                                       PAGE_SIZE);
                        page = NULL;
                }
                if (req->actual_length < PAGE_SIZE)
index 439690b..685a4e2 100644 (file)
@@ -93,6 +93,7 @@ static int eem_bind(struct usbnet *dev, struct usb_interface *intf)
        /* no jumbogram (16K) support for now */
 
        dev->net->hard_header_len += EEM_HEAD + ETH_FCS_LEN;
+       dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len;
 
        return 0;
 }
index 6dda2fe..d363b31 100644 (file)
 #define        RTL8150_REQ_SET_REGS    0x05
 
 
-/* Transmit status register errors */
-#define TSR_ECOL               (1<<5)
-#define TSR_LCOL               (1<<4)
-#define TSR_LOSS_CRS           (1<<3)
-#define TSR_JBR                        (1<<2)
-#define TSR_ERRORS             (TSR_ECOL | TSR_LCOL | TSR_LOSS_CRS | TSR_JBR)
-/* Receive status register errors */
-#define RSR_CRC                        (1<<2)
-#define RSR_FAE                        (1<<1)
-#define RSR_ERRORS             (RSR_CRC | RSR_FAE)
-
-/* Media status register definitions */
-#define MSR_DUPLEX             (1<<4)
-#define MSR_SPEED              (1<<3)
-#define MSR_LINK               (1<<2)
-
-/* Interrupt pipe data */
-#define INT_TSR                        0x00
-#define INT_RSR                        0x01
-#define INT_MSR                        0x02
-#define INT_WAKSR              0x03
-#define INT_TXOK_CNT           0x04
-#define INT_RXLOST_CNT         0x05
-#define INT_CRERR_CNT          0x06
-#define INT_COL_CNT            0x07
-
 /* Transmit status register errors */
 #define TSR_ECOL               (1<<5)
 #define TSR_LCOL               (1<<4)
index c3197ce..34db195 100644 (file)
@@ -337,6 +337,11 @@ static const struct usb_device_id  products [] = {
        .driver_info = ZAURUS_PXA_INFO,
 },
 {
+       /* Motorola Rokr E6 */
+       USB_DEVICE_AND_INTERFACE_INFO(0x22b8, 0x6027, USB_CLASS_COMM,
+                       USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
+       .driver_info = (unsigned long) &bogus_mdlm_info,
+}, {
        /* Motorola MOTOMAGX phones */
        USB_DEVICE_AND_INTERFACE_INFO(0x22b8, 0x6425, USB_CLASS_COMM,
                        USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
index 019da01..4de2760 100644 (file)
@@ -625,12 +625,13 @@ static netdev_tx_t start_xmit(struct sk_buff *skb, struct net_device *dev)
 
        /* This can happen with OOM and indirect buffers. */
        if (unlikely(capacity < 0)) {
-               if (net_ratelimit()) {
-                       if (likely(capacity == -ENOMEM)) {
+               if (likely(capacity == -ENOMEM)) {
+                       if (net_ratelimit()) {
                                dev_warn(&dev->dev,
                                         "TX queue failure: out of memory\n");
                        } else {
-                               dev->stats.tx_fifo_errors++;
+                       dev->stats.tx_fifo_errors++;
+                       if (net_ratelimit())
                                dev_warn(&dev->dev,
                                         "Unexpected TX queue failure: %d\n",
                                         capacity);
index 63e4b70..1d76ae8 100644 (file)
@@ -597,7 +597,8 @@ static void i2400m_get_drvinfo(struct net_device *net_dev,
        struct i2400m *i2400m = net_dev_to_i2400m(net_dev);
 
        strncpy(info->driver, KBUILD_MODNAME, sizeof(info->driver) - 1);
-       strncpy(info->fw_version, i2400m->fw_name, sizeof(info->fw_version) - 1);
+       strncpy(info->fw_version,
+               i2400m->fw_name ? : "", sizeof(info->fw_version) - 1);
        if (net_dev->dev.parent)
                strncpy(info->bus_info, dev_name(net_dev->dev.parent),
                        sizeof(info->bus_info) - 1);
index 2c1b8b6..29b1e03 100644 (file)
@@ -339,6 +339,23 @@ int i2400mu_bus_reset(struct i2400m *i2400m, enum i2400m_reset_type rt)
        return result;
 }
 
+static void i2400mu_get_drvinfo(struct net_device *net_dev,
+                                struct ethtool_drvinfo *info)
+{
+       struct i2400m *i2400m = net_dev_to_i2400m(net_dev);
+       struct i2400mu *i2400mu = container_of(i2400m, struct i2400mu, i2400m);
+       struct usb_device *udev = i2400mu->usb_dev;
+
+       strncpy(info->driver, KBUILD_MODNAME, sizeof(info->driver) - 1);
+       strncpy(info->fw_version,
+               i2400m->fw_name ? : "", sizeof(info->fw_version) - 1);
+       usb_make_path(udev, info->bus_info, sizeof(info->bus_info));
+}
+
+static const struct ethtool_ops i2400mu_ethtool_ops = {
+       .get_drvinfo = i2400mu_get_drvinfo,
+       .get_link = ethtool_op_get_link,
+};
 
 static
 void i2400mu_netdev_setup(struct net_device *net_dev)
@@ -347,6 +364,7 @@ void i2400mu_netdev_setup(struct net_device *net_dev)
        struct i2400mu *i2400mu = container_of(i2400m, struct i2400mu, i2400m);
        i2400mu_init(i2400mu);
        i2400m_netdev_setup(net_dev);
+       net_dev->ethtool_ops = &i2400mu_ethtool_ops;
 }
 
 
index 2f4b48e..e5cceb0 100644 (file)
@@ -20,7 +20,6 @@
 
 /* Common calibration code */
 
-#define ATH9K_NF_TOO_HIGH      -60
 
 static int16_t ath9k_hw_get_nf_hist_mid(int16_t *nfCalBuffer)
 {
@@ -346,10 +345,10 @@ static void ath9k_hw_nf_sanitize(struct ath_hw *ah, s16 *nf)
                        "NF calibrated [%s] [chain %d] is %d\n",
                        (i >= 3 ? "ext" : "ctl"), i % 3, nf[i]);
 
-               if (nf[i] > ATH9K_NF_TOO_HIGH) {
+               if (nf[i] > limit->max) {
                        ath_dbg(common, CALIBRATE,
                                "NF[%d] (%d) > MAX (%d), correcting to MAX\n",
-                               i, nf[i], ATH9K_NF_TOO_HIGH);
+                               i, nf[i], limit->max);
                        nf[i] = limit->max;
                } else if (nf[i] < limit->min) {
                        ath_dbg(common, CALIBRATE,
index 60159f4..cb00645 100644 (file)
@@ -680,7 +680,7 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
        hw->queues = 4;
        hw->max_rates = 4;
        hw->channel_change_time = 5000;
-       hw->max_listen_interval = 10;
+       hw->max_listen_interval = 1;
        hw->max_rate_tries = 10;
        hw->sta_data_size = sizeof(struct ath_node);
        hw->vif_data_size = sizeof(struct ath_vif);
index 3879485..215eb25 100644 (file)
@@ -640,7 +640,7 @@ static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta,
        an->sta = sta;
        an->vif = vif;
 
-       if (sta->ht_cap.ht_supported) {
+       if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
                ath_tx_node_init(sc, an);
                an->maxampdu = 1 << (IEEE80211_HT_MAX_AMPDU_FACTOR +
                                     sta->ht_cap.ampdu_factor);
@@ -659,7 +659,7 @@ static void ath_node_detach(struct ath_softc *sc, struct ieee80211_sta *sta)
        an->sta = NULL;
 #endif
 
-       if (sta->ht_cap.ht_supported)
+       if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT)
                ath_tx_node_cleanup(sc, an);
 }
 
index f4ae3ba..1c4583c 100644 (file)
@@ -1913,13 +1913,13 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
                if (sc->rx.frag) {
                        int space = skb->len - skb_tailroom(hdr_skb);
 
-                       sc->rx.frag = NULL;
-
                        if (pskb_expand_head(hdr_skb, 0, space, GFP_ATOMIC) < 0) {
                                dev_kfree_skb(skb);
                                goto requeue_drop_frag;
                        }
 
+                       sc->rx.frag = NULL;
+
                        skb_copy_from_linear_data(skb, skb_put(hdr_skb, skb->len),
                                                  skb->len);
                        dev_kfree_skb_any(skb);
index 4fcdac6..2b02257 100644 (file)
@@ -11507,9 +11507,9 @@ static int ipw_wdev_init(struct net_device *dev)
                        rc = -ENOMEM;
                        goto out;
                }
-               /* translate geo->bg to a_band.channels */
+               /* translate geo->a to a_band.channels */
                for (i = 0; i < geo->a_channels; i++) {
-                       a_band->channels[i].band = IEEE80211_BAND_2GHZ;
+                       a_band->channels[i].band = IEEE80211_BAND_5GHZ;
                        a_band->channels[i].center_freq = geo->a[i].freq;
                        a_band->channels[i].hw_value = geo->a[i].channel;
                        a_band->channels[i].max_power = geo->a[i].max_power;
index 0c12093..faec404 100644 (file)
@@ -2673,8 +2673,6 @@ il3945_bg_restart(struct work_struct *data)
 
        if (test_and_clear_bit(S_FW_ERROR, &il->status)) {
                mutex_lock(&il->mutex);
-               /* FIXME: vif can be dereferenced */
-               il->vif = NULL;
                il->is_open = 0;
                mutex_unlock(&il->mutex);
                il3945_down(il);
index 17f1c68..c46275a 100644 (file)
@@ -5652,8 +5652,6 @@ il4965_bg_restart(struct work_struct *data)
 
        if (test_and_clear_bit(S_FW_ERROR, &il->status)) {
                mutex_lock(&il->mutex);
-               /* FIXME: do we dereference vif without mutex locked ? */
-               il->vif = NULL;
                il->is_open = 0;
 
                __il4965_down(il);
index e5ac047..eaf2494 100644 (file)
@@ -4508,6 +4508,7 @@ il_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
 {
        struct il_priv *il = hw->priv;
        int err;
+       bool reset;
 
        mutex_lock(&il->mutex);
        D_MAC80211("enter: type %d, addr %pM\n", vif->type, vif->addr);
@@ -4518,7 +4519,12 @@ il_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
                goto out;
        }
 
-       if (il->vif) {
+       /*
+        * We do not support multiple virtual interfaces, but on hardware reset
+        * we have to add the same interface again.
+        */
+       reset = (il->vif == vif);
+       if (il->vif && !reset) {
                err = -EOPNOTSUPP;
                goto out;
        }
@@ -4528,8 +4534,11 @@ il_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
 
        err = il_set_mode(il);
        if (err) {
-               il->vif = NULL;
-               il->iw_mode = NL80211_IFTYPE_STATION;
+               IL_WARN("Fail to set mode %d\n", vif->type);
+               if (!reset) {
+                       il->vif = NULL;
+                       il->iw_mode = NL80211_IFTYPE_STATION;
+               }
        }
 
 out:
@@ -5279,9 +5288,9 @@ il_mac_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
                D_MAC80211("BSSID %pM\n", bss_conf->bssid);
 
                /*
-                * If there is currently a HW scan going on in the
-                * background then we need to cancel it else the RXON
-                * below/in post_associate will fail.
+                * If there is currently a HW scan going on in the background,
+                * then we need to cancel it, otherwise sometimes we are not
+                * able to authenticate (FIXME: why ?)
                 */
                if (il_scan_cancel_timeout(il, 100)) {
                        D_MAC80211("leave - scan abort failed\n");
@@ -5290,14 +5299,10 @@ il_mac_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
                }
 
                /* mac80211 only sets assoc when in STATION mode */
-               if (vif->type == NL80211_IFTYPE_ADHOC || bss_conf->assoc) {
-                       memcpy(il->staging.bssid_addr, bss_conf->bssid,
-                              ETH_ALEN);
+               memcpy(il->staging.bssid_addr, bss_conf->bssid, ETH_ALEN);
 
-                       /* currently needed in a few places */
-                       memcpy(il->bssid, bss_conf->bssid, ETH_ALEN);
-               } else
-                       il->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+               /* FIXME: currently needed in a few places */
+               memcpy(il->bssid, bss_conf->bssid, ETH_ALEN);
        }
 
        /*
index dd6c64a..88e3ad2 100644 (file)
@@ -1336,6 +1336,10 @@ static void qbuf_scan(struct orinoco_private *priv, void *buf,
        unsigned long flags;
 
        sd = kmalloc(sizeof(*sd), GFP_ATOMIC);
+       if (!sd) {
+               printk(KERN_ERR "%s: failed to alloc memory\n", __func__);
+               return;
+       }
        sd->buf = buf;
        sd->len = len;
        sd->type = type;
@@ -1353,6 +1357,10 @@ static void qabort_scan(struct orinoco_private *priv)
        unsigned long flags;
 
        sd = kmalloc(sizeof(*sd), GFP_ATOMIC);
+       if (!sd) {
+               printk(KERN_ERR "%s: failed to alloc memory\n", __func__);
+               return;
+       }
        sd->len = -1; /* Abort */
 
        spin_lock_irqsave(&priv->scan_lock, flags);
index cd490ab..001735f 100644 (file)
@@ -163,7 +163,13 @@ static bool rt2800usb_tx_sta_fifo_read_completed(struct rt2x00_dev *rt2x00dev,
 
                /* Reschedule urb to read TX status again instantly */
                return true;
-       } else if (rt2800usb_txstatus_pending(rt2x00dev)) {
+       }
+
+       /* Check if there is any entry that timedout waiting on TX status */
+       if (rt2800usb_txstatus_timeout(rt2x00dev))
+               queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work);
+
+       if (rt2800usb_txstatus_pending(rt2x00dev)) {
                /* Read register after 250 us */
                hrtimer_start(&rt2x00dev->txstatus_timer, ktime_set(0, 250000),
                              HRTIMER_MODE_REL);
@@ -178,7 +184,7 @@ stop_reading:
         * here again if status reading is needed.
         */
        if (rt2800usb_txstatus_pending(rt2x00dev) &&
-           test_and_set_bit(TX_STATUS_READING, &rt2x00dev->flags))
+           !test_and_set_bit(TX_STATUS_READING, &rt2x00dev->flags))
                return true;
        else
                return false;
index 1eec3a0..4c01624 100644 (file)
@@ -1893,7 +1893,7 @@ void rtl92c_phy_set_io(struct ieee80211_hw *hw)
                break;
        case IO_CMD_PAUSE_DM_BY_SCAN:
                rtlphy->initgain_backup.xaagccore1 = dm_digtable.cur_igvalue;
-               dm_digtable.cur_igvalue = 0x17;
+               dm_digtable.cur_igvalue = 0x37;
                rtl92c_dm_write_dig(hw);
                break;
        default:
index 34591ee..28fc5fb 100644 (file)
@@ -3077,7 +3077,7 @@ static void rtl92d_phy_set_io(struct ieee80211_hw *hw)
                break;
        case IO_CMD_PAUSE_DM_BY_SCAN:
                rtlphy->initgain_backup.xaagccore1 = de_digtable.cur_igvalue;
-               de_digtable.cur_igvalue = 0x17;
+               de_digtable.cur_igvalue = 0x37;
                rtl92d_dm_write_dig(hw);
                break;
        default:
index 85a5ceb..965a629 100644 (file)
@@ -345,7 +345,7 @@ static void pn_rx_complete(struct usb_ep *ep, struct usb_request *req)
                }
 
                skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page,
-                               skb->len <= 1, req->actual, req->actual);
+                               skb->len <= 1, req->actual, PAGE_SIZE);
                page = NULL;
 
                if (req->actual < req->length) { /* Last fragment */
index 8a36183..1488302 100644 (file)
@@ -10,6 +10,7 @@
 #error "Cannot use generic cmpxchg on SMP"
 #endif
 
+#include <linux/types.h>
 #include <linux/irqflags.h>
 
 #ifndef xchg
index d838c94..2eba340 100644 (file)
@@ -31,6 +31,8 @@ static inline void crypto_set_aead_spawn(
        crypto_set_spawn(&spawn->base, inst);
 }
 
+struct crypto_alg *crypto_lookup_aead(const char *name, u32 type, u32 mask);
+
 int crypto_grab_aead(struct crypto_aead_spawn *spawn, const char *name,
                     u32 type, u32 mask);
 
index 3a748a6..06e8b32 100644 (file)
@@ -34,6 +34,8 @@ static inline void crypto_set_skcipher_spawn(
 int crypto_grab_skcipher(struct crypto_skcipher_spawn *spawn, const char *name,
                         u32 type, u32 mask);
 
+struct crypto_alg *crypto_lookup_skcipher(const char *name, u32 type, u32 mask);
+
 static inline void crypto_drop_skcipher(struct crypto_skcipher_spawn *spawn)
 {
        crypto_drop_spawn(&spawn->base);
index 34a7b89..64ff02d 100644 (file)
@@ -617,6 +617,17 @@ struct drm_get_cap {
        __u64 value;
 };
 
+#define DRM_CLOEXEC O_CLOEXEC
+struct drm_prime_handle {
+       __u32 handle;
+
+       /** Flags.. only applicable for handle->fd */
+       __u32 flags;
+
+       /** Returned dmabuf file descriptor */
+       __s32 fd;
+};
+
 #include "drm_mode.h"
 
 #define DRM_IOCTL_BASE                 'd'
@@ -673,7 +684,8 @@ struct drm_get_cap {
 #define DRM_IOCTL_UNLOCK               DRM_IOW( 0x2b, struct drm_lock)
 #define DRM_IOCTL_FINISH               DRM_IOW( 0x2c, struct drm_lock)
 
-#define DRM_IOCTL_GEM_PRIME_OPEN        DRM_IOWR(0x2e, struct drm_gem_open)
+#define DRM_IOCTL_PRIME_HANDLE_TO_FD    DRM_IOWR(0x2d, struct drm_prime_handle)
+#define DRM_IOCTL_PRIME_FD_TO_HANDLE    DRM_IOWR(0x2e, struct drm_prime_handle)
 
 #define DRM_IOCTL_AGP_ACQUIRE          DRM_IO(  0x30)
 #define DRM_IOCTL_AGP_RELEASE          DRM_IO(  0x31)
index 574bd1c..dd73104 100644 (file)
@@ -91,6 +91,7 @@ struct drm_device;
 #define DRM_UT_CORE            0x01
 #define DRM_UT_DRIVER          0x02
 #define DRM_UT_KMS             0x04
+#define DRM_UT_PRIME           0x08
 /*
  * Three debug levels are defined.
  * drm_core, drm_driver, drm_kms
@@ -150,6 +151,7 @@ int drm_err(const char *func, const char *format, ...);
 #define DRIVER_IRQ_VBL2    0x800
 #define DRIVER_GEM         0x1000
 #define DRIVER_MODESET     0x2000
+#define DRIVER_PRIME       0x4000
 
 #define DRIVER_BUS_PCI 0x1
 #define DRIVER_BUS_PLATFORM 0x2
@@ -215,6 +217,11 @@ int drm_err(const char *func, const char *format, ...);
                drm_ut_debug_printk(DRM_UT_KMS, DRM_NAME,               \
                                         __func__, fmt, ##args);        \
        } while (0)
+#define DRM_DEBUG_PRIME(fmt, args...)                                  \
+       do {                                                            \
+               drm_ut_debug_printk(DRM_UT_PRIME, DRM_NAME,             \
+                                       __func__, fmt, ##args);         \
+       } while (0)
 #define DRM_LOG(fmt, args...)                                          \
        do {                                                            \
                drm_ut_debug_printk(DRM_UT_CORE, NULL,                  \
@@ -238,6 +245,7 @@ int drm_err(const char *func, const char *format, ...);
 #else
 #define DRM_DEBUG_DRIVER(fmt, args...) do { } while (0)
 #define DRM_DEBUG_KMS(fmt, args...)    do { } while (0)
+#define DRM_DEBUG_PRIME(fmt, args...)  do { } while (0)
 #define DRM_DEBUG(fmt, arg...)          do { } while (0)
 #define DRM_LOG(fmt, arg...)           do { } while (0)
 #define DRM_LOG_KMS(fmt, args...) do { } while (0)
@@ -410,6 +418,12 @@ struct drm_pending_event {
        void (*destroy)(struct drm_pending_event *event);
 };
 
+/* initial implementaton using a linked list - todo hashtab */
+struct drm_prime_file_private {
+       struct list_head head;
+       struct mutex lock;
+};
+
 /** File private data */
 struct drm_file {
        int authenticated;
@@ -437,6 +451,8 @@ struct drm_file {
        wait_queue_head_t event_wait;
        struct list_head event_list;
        int event_space;
+
+       struct drm_prime_file_private prime;
 };
 
 /** Wait queue */
@@ -652,6 +668,12 @@ struct drm_gem_object {
        uint32_t pending_write_domain;
 
        void *driver_private;
+
+       /* dma buf exported from this GEM object */
+       struct dma_buf *export_dma_buf;
+
+       /* dma buf attachment backing this object */
+       struct dma_buf_attachment *import_attach;
 };
 
 #include "drm_crtc.h"
@@ -890,6 +912,20 @@ struct drm_driver {
        int (*gem_open_object) (struct drm_gem_object *, struct drm_file *);
        void (*gem_close_object) (struct drm_gem_object *, struct drm_file *);
 
+       /* prime: */
+       /* export handle -> fd (see drm_gem_prime_handle_to_fd() helper) */
+       int (*prime_handle_to_fd)(struct drm_device *dev, struct drm_file *file_priv,
+                               uint32_t handle, uint32_t flags, int *prime_fd);
+       /* import fd -> handle (see drm_gem_prime_fd_to_handle() helper) */
+       int (*prime_fd_to_handle)(struct drm_device *dev, struct drm_file *file_priv,
+                               int prime_fd, uint32_t *handle);
+       /* export GEM -> dmabuf */
+       struct dma_buf * (*gem_prime_export)(struct drm_device *dev,
+                               struct drm_gem_object *obj, int flags);
+       /* import dmabuf -> GEM */
+       struct drm_gem_object * (*gem_prime_import)(struct drm_device *dev,
+                               struct dma_buf *dma_buf);
+
        /* vga arb irq handler */
        void (*vgaarb_irq)(struct drm_device *dev, bool state);
 
@@ -1509,6 +1545,32 @@ extern int drm_vblank_info(struct seq_file *m, void *data);
 extern int drm_clients_info(struct seq_file *m, void* data);
 extern int drm_gem_name_info(struct seq_file *m, void *data);
 
+
+extern int drm_gem_prime_handle_to_fd(struct drm_device *dev,
+               struct drm_file *file_priv, uint32_t handle, uint32_t flags,
+               int *prime_fd);
+extern int drm_gem_prime_fd_to_handle(struct drm_device *dev,
+               struct drm_file *file_priv, int prime_fd, uint32_t *handle);
+
+extern int drm_prime_handle_to_fd_ioctl(struct drm_device *dev, void *data,
+                                       struct drm_file *file_priv);
+extern int drm_prime_fd_to_handle_ioctl(struct drm_device *dev, void *data,
+                                       struct drm_file *file_priv);
+
+extern struct sg_table *drm_prime_pages_to_sg(struct page **pages, int nr_pages);
+extern void drm_prime_gem_destroy(struct drm_gem_object *obj, struct sg_table *sg);
+
+
+void drm_prime_init_file_private(struct drm_prime_file_private *prime_fpriv);
+void drm_prime_destroy_file_private(struct drm_prime_file_private *prime_fpriv);
+int drm_prime_add_imported_buf_handle(struct drm_prime_file_private *prime_fpriv, struct dma_buf *dma_buf, uint32_t handle);
+int drm_prime_lookup_imported_buf_handle(struct drm_prime_file_private *prime_fpriv, struct dma_buf *dma_buf, uint32_t *handle);
+void drm_prime_remove_imported_buf_handle(struct drm_prime_file_private *prime_fpriv, struct dma_buf *dma_buf);
+
+int drm_prime_add_dma_buf(struct drm_device *dev, struct drm_gem_object *obj);
+int drm_prime_lookup_obj(struct drm_device *dev, struct dma_buf *buf,
+                        struct drm_gem_object **obj);
+
 #if DRM_DEBUG_CODE
 extern int drm_vma_info(struct seq_file *m, void *data);
 #endif
index d05df28..3c9b616 100644 (file)
@@ -3,6 +3,7 @@ header-y += can/
 header-y += caif/
 header-y += dvb/
 header-y += hdlc/
+header-y += hsi/
 header-y += isdn/
 header-y += mmc/
 header-y += nfsd/
index 1ffdb98..a2c819d 100644 (file)
@@ -764,12 +764,6 @@ static inline const struct cpumask *get_cpu_mask(unsigned int cpu)
  *
  */
 #ifndef CONFIG_DISABLE_OBSOLETE_CPUMASK_FUNCTIONS
-/* These strip const, as traditionally they weren't const. */
-#define cpu_possible_map       (*(cpumask_t *)cpu_possible_mask)
-#define cpu_online_map         (*(cpumask_t *)cpu_online_mask)
-#define cpu_present_map                (*(cpumask_t *)cpu_present_mask)
-#define cpu_active_map         (*(cpumask_t *)cpu_active_mask)
-
 #define cpumask_of_cpu(cpu) (*get_cpu_mask(cpu))
 
 #define CPU_MASK_LAST_WORD BITMAP_LAST_WORD_MASK(NR_CPUS)
index 532fb58..4abf2ea 100644 (file)
@@ -100,3 +100,6 @@ struct crypto_report_rng {
        char type[CRYPTO_MAX_NAME];
        unsigned int seedsize;
 };
+
+#define CRYPTO_REPORT_MAXSIZE (sizeof(struct crypto_user_alg) + \
+                              sizeof(struct crypto_report_blkcipher))
index 4db7b68..cdc9b71 100644 (file)
@@ -2,6 +2,7 @@
 #define _LINUX_FIREWIRE_H
 
 #include <linux/completion.h>
+#include <linux/device.h>
 #include <linux/dma-mapping.h>
 #include <linux/kernel.h>
 #include <linux/kref.h>
@@ -64,8 +65,6 @@
 #define CSR_MODEL              0x17
 #define CSR_DIRECTORY_ID       0x20
 
-struct device;
-
 struct fw_csr_iterator {
        const u32 *p;
        const u32 *end;
diff --git a/include/linux/hsi/Kbuild b/include/linux/hsi/Kbuild
new file mode 100644 (file)
index 0000000..271a770
--- /dev/null
@@ -0,0 +1 @@
+header-y += hsi_char.h
diff --git a/include/linux/hsi/hsi.h b/include/linux/hsi/hsi.h
new file mode 100644 (file)
index 0000000..4b17806
--- /dev/null
@@ -0,0 +1,410 @@
+/*
+ * HSI core header file.
+ *
+ * Copyright (C) 2010 Nokia Corporation. All rights reserved.
+ *
+ * Contact: Carlos Chinea <carlos.chinea@nokia.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 published by the Free Software Foundation.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#ifndef __LINUX_HSI_H__
+#define __LINUX_HSI_H__
+
+#include <linux/device.h>
+#include <linux/mutex.h>
+#include <linux/scatterlist.h>
+#include <linux/spinlock.h>
+#include <linux/list.h>
+#include <linux/module.h>
+
+/* HSI message ttype */
+#define HSI_MSG_READ   0
+#define HSI_MSG_WRITE  1
+
+/* HSI configuration values */
+enum {
+       HSI_MODE_STREAM = 1,
+       HSI_MODE_FRAME,
+};
+
+enum {
+       HSI_FLOW_SYNC,  /* Synchronized flow */
+       HSI_FLOW_PIPE,  /* Pipelined flow */
+};
+
+enum {
+       HSI_ARB_RR,     /* Round-robin arbitration */
+       HSI_ARB_PRIO,   /* Channel priority arbitration */
+};
+
+#define HSI_MAX_CHANNELS       16
+
+/* HSI message status codes */
+enum {
+       HSI_STATUS_COMPLETED,   /* Message transfer is completed */
+       HSI_STATUS_PENDING,     /* Message pending to be read/write (POLL) */
+       HSI_STATUS_PROCEEDING,  /* Message transfer is ongoing */
+       HSI_STATUS_QUEUED,      /* Message waiting to be served */
+       HSI_STATUS_ERROR,       /* Error when message transfer was ongoing */
+};
+
+/* HSI port event codes */
+enum {
+       HSI_EVENT_START_RX,
+       HSI_EVENT_STOP_RX,
+};
+
+/**
+ * struct hsi_config - Configuration for RX/TX HSI modules
+ * @mode: Bit transmission mode (STREAM or FRAME)
+ * @channels: Number of channels to use [1..16]
+ * @speed: Max bit transmission speed (Kbit/s)
+ * @flow: RX flow type (SYNCHRONIZED or PIPELINE)
+ * @arb_mode: Arbitration mode for TX frame (Round robin, priority)
+ */
+struct hsi_config {
+       unsigned int    mode;
+       unsigned int    channels;
+       unsigned int    speed;
+       union {
+               unsigned int    flow;           /* RX only */
+               unsigned int    arb_mode;       /* TX only */
+       };
+};
+
+/**
+ * struct hsi_board_info - HSI client board info
+ * @name: Name for the HSI device
+ * @hsi_id: HSI controller id where the client sits
+ * @port: Port number in the controller where the client sits
+ * @tx_cfg: HSI TX configuration
+ * @rx_cfg: HSI RX configuration
+ * @platform_data: Platform related data
+ * @archdata: Architecture-dependent device data
+ */
+struct hsi_board_info {
+       const char              *name;
+       unsigned int            hsi_id;
+       unsigned int            port;
+       struct hsi_config       tx_cfg;
+       struct hsi_config       rx_cfg;
+       void                    *platform_data;
+       struct dev_archdata     *archdata;
+};
+
+#ifdef CONFIG_HSI_BOARDINFO
+extern int hsi_register_board_info(struct hsi_board_info const *info,
+                                                       unsigned int len);
+#else
+static inline int hsi_register_board_info(struct hsi_board_info const *info,
+                                                       unsigned int len)
+{
+       return 0;
+}
+#endif /* CONFIG_HSI_BOARDINFO */
+
+/**
+ * struct hsi_client - HSI client attached to an HSI port
+ * @device: Driver model representation of the device
+ * @tx_cfg: HSI TX configuration
+ * @rx_cfg: HSI RX configuration
+ * @hsi_start_rx: Called after incoming wake line goes high
+ * @hsi_stop_rx: Called after incoming wake line goes low
+ */
+struct hsi_client {
+       struct device           device;
+       struct hsi_config       tx_cfg;
+       struct hsi_config       rx_cfg;
+       void                    (*hsi_start_rx)(struct hsi_client *cl);
+       void                    (*hsi_stop_rx)(struct hsi_client *cl);
+       /* private: */
+       unsigned int            pclaimed:1;
+       struct list_head        link;
+};
+
+#define to_hsi_client(dev) container_of(dev, struct hsi_client, device)
+
+static inline void hsi_client_set_drvdata(struct hsi_client *cl, void *data)
+{
+       dev_set_drvdata(&cl->device, data);
+}
+
+static inline void *hsi_client_drvdata(struct hsi_client *cl)
+{
+       return dev_get_drvdata(&cl->device);
+}
+
+/**
+ * struct hsi_client_driver - Driver associated to an HSI client
+ * @driver: Driver model representation of the driver
+ */
+struct hsi_client_driver {
+       struct device_driver    driver;
+};
+
+#define to_hsi_client_driver(drv) container_of(drv, struct hsi_client_driver,\
+                                                                       driver)
+
+int hsi_register_client_driver(struct hsi_client_driver *drv);
+
+static inline void hsi_unregister_client_driver(struct hsi_client_driver *drv)
+{
+       driver_unregister(&drv->driver);
+}
+
+/**
+ * struct hsi_msg - HSI message descriptor
+ * @link: Free to use by the current descriptor owner
+ * @cl: HSI device client that issues the transfer
+ * @sgt: Head of the scatterlist array
+ * @context: Client context data associated to the transfer
+ * @complete: Transfer completion callback
+ * @destructor: Destructor to free resources when flushing
+ * @status: Status of the transfer when completed
+ * @actual_len: Actual length of data transfered on completion
+ * @channel: Channel were to TX/RX the message
+ * @ttype: Transfer type (TX if set, RX otherwise)
+ * @break_frame: if true HSI will send/receive a break frame. Data buffers are
+ *             ignored in the request.
+ */
+struct hsi_msg {
+       struct list_head        link;
+       struct hsi_client       *cl;
+       struct sg_table         sgt;
+       void                    *context;
+
+       void                    (*complete)(struct hsi_msg *msg);
+       void                    (*destructor)(struct hsi_msg *msg);
+
+       int                     status;
+       unsigned int            actual_len;
+       unsigned int            channel;
+       unsigned int            ttype:1;
+       unsigned int            break_frame:1;
+};
+
+struct hsi_msg *hsi_alloc_msg(unsigned int n_frag, gfp_t flags);
+void hsi_free_msg(struct hsi_msg *msg);
+
+/**
+ * struct hsi_port - HSI port device
+ * @device: Driver model representation of the device
+ * @tx_cfg: Current TX path configuration
+ * @rx_cfg: Current RX path configuration
+ * @num: Port number
+ * @shared: Set when port can be shared by different clients
+ * @claimed: Reference count of clients which claimed the port
+ * @lock: Serialize port claim
+ * @async: Asynchronous transfer callback
+ * @setup: Callback to set the HSI client configuration
+ * @flush: Callback to clean the HW state and destroy all pending transfers
+ * @start_tx: Callback to inform that a client wants to TX data
+ * @stop_tx: Callback to inform that a client no longer wishes to TX data
+ * @release: Callback to inform that a client no longer uses the port
+ * @clients: List of hsi_clients using the port.
+ * @clock: Lock to serialize access to the clients list.
+ */
+struct hsi_port {
+       struct device                   device;
+       struct hsi_config               tx_cfg;
+       struct hsi_config               rx_cfg;
+       unsigned int                    num;
+       unsigned int                    shared:1;
+       int                             claimed;
+       struct mutex                    lock;
+       int                             (*async)(struct hsi_msg *msg);
+       int                             (*setup)(struct hsi_client *cl);
+       int                             (*flush)(struct hsi_client *cl);
+       int                             (*start_tx)(struct hsi_client *cl);
+       int                             (*stop_tx)(struct hsi_client *cl);
+       int                             (*release)(struct hsi_client *cl);
+       struct list_head                clients;
+       spinlock_t                      clock;
+};
+
+#define to_hsi_port(dev) container_of(dev, struct hsi_port, device)
+#define hsi_get_port(cl) to_hsi_port((cl)->device.parent)
+
+void hsi_event(struct hsi_port *port, unsigned int event);
+int hsi_claim_port(struct hsi_client *cl, unsigned int share);
+void hsi_release_port(struct hsi_client *cl);
+
+static inline int hsi_port_claimed(struct hsi_client *cl)
+{
+       return cl->pclaimed;
+}
+
+static inline void hsi_port_set_drvdata(struct hsi_port *port, void *data)
+{
+       dev_set_drvdata(&port->device, data);
+}
+
+static inline void *hsi_port_drvdata(struct hsi_port *port)
+{
+       return dev_get_drvdata(&port->device);
+}
+
+/**
+ * struct hsi_controller - HSI controller device
+ * @device: Driver model representation of the device
+ * @owner: Pointer to the module owning the controller
+ * @id: HSI controller ID
+ * @num_ports: Number of ports in the HSI controller
+ * @port: Array of HSI ports
+ */
+struct hsi_controller {
+       struct device           device;
+       struct module           *owner;
+       unsigned int            id;
+       unsigned int            num_ports;
+       struct hsi_port         *port;
+};
+
+#define to_hsi_controller(dev) container_of(dev, struct hsi_controller, device)
+
+struct hsi_controller *hsi_alloc_controller(unsigned int n_ports, gfp_t flags);
+void hsi_free_controller(struct hsi_controller *hsi);
+int hsi_register_controller(struct hsi_controller *hsi);
+void hsi_unregister_controller(struct hsi_controller *hsi);
+
+static inline void hsi_controller_set_drvdata(struct hsi_controller *hsi,
+                                                               void *data)
+{
+       dev_set_drvdata(&hsi->device, data);
+}
+
+static inline void *hsi_controller_drvdata(struct hsi_controller *hsi)
+{
+       return dev_get_drvdata(&hsi->device);
+}
+
+static inline struct hsi_port *hsi_find_port_num(struct hsi_controller *hsi,
+                                                       unsigned int num)
+{
+       return (num < hsi->num_ports) ? &hsi->port[num] : NULL;
+}
+
+/*
+ * API for HSI clients
+ */
+int hsi_async(struct hsi_client *cl, struct hsi_msg *msg);
+
+/**
+ * hsi_id - Get HSI controller ID associated to a client
+ * @cl: Pointer to a HSI client
+ *
+ * Return the controller id where the client is attached to
+ */
+static inline unsigned int hsi_id(struct hsi_client *cl)
+{
+       return  to_hsi_controller(cl->device.parent->parent)->id;
+}
+
+/**
+ * hsi_port_id - Gets the port number a client is attached to
+ * @cl: Pointer to HSI client
+ *
+ * Return the port number associated to the client
+ */
+static inline unsigned int hsi_port_id(struct hsi_client *cl)
+{
+       return  to_hsi_port(cl->device.parent)->num;
+}
+
+/**
+ * hsi_setup - Configure the client's port
+ * @cl: Pointer to the HSI client
+ *
+ * When sharing ports, clients should either relay on a single
+ * client setup or have the same setup for all of them.
+ *
+ * Return -errno on failure, 0 on success
+ */
+static inline int hsi_setup(struct hsi_client *cl)
+{
+       if (!hsi_port_claimed(cl))
+               return -EACCES;
+       return  hsi_get_port(cl)->setup(cl);
+}
+
+/**
+ * hsi_flush - Flush all pending transactions on the client's port
+ * @cl: Pointer to the HSI client
+ *
+ * This function will destroy all pending hsi_msg in the port and reset
+ * the HW port so it is ready to receive and transmit from a clean state.
+ *
+ * Return -errno on failure, 0 on success
+ */
+static inline int hsi_flush(struct hsi_client *cl)
+{
+       if (!hsi_port_claimed(cl))
+               return -EACCES;
+       return hsi_get_port(cl)->flush(cl);
+}
+
+/**
+ * hsi_async_read - Submit a read transfer
+ * @cl: Pointer to the HSI client
+ * @msg: HSI message descriptor of the transfer
+ *
+ * Return -errno on failure, 0 on success
+ */
+static inline int hsi_async_read(struct hsi_client *cl, struct hsi_msg *msg)
+{
+       msg->ttype = HSI_MSG_READ;
+       return hsi_async(cl, msg);
+}
+
+/**
+ * hsi_async_write - Submit a write transfer
+ * @cl: Pointer to the HSI client
+ * @msg: HSI message descriptor of the transfer
+ *
+ * Return -errno on failure, 0 on success
+ */
+static inline int hsi_async_write(struct hsi_client *cl, struct hsi_msg *msg)
+{
+       msg->ttype = HSI_MSG_WRITE;
+       return hsi_async(cl, msg);
+}
+
+/**
+ * hsi_start_tx - Signal the port that the client wants to start a TX
+ * @cl: Pointer to the HSI client
+ *
+ * Return -errno on failure, 0 on success
+ */
+static inline int hsi_start_tx(struct hsi_client *cl)
+{
+       if (!hsi_port_claimed(cl))
+               return -EACCES;
+       return hsi_get_port(cl)->start_tx(cl);
+}
+
+/**
+ * hsi_stop_tx - Signal the port that the client no longer wants to transmit
+ * @cl: Pointer to the HSI client
+ *
+ * Return -errno on failure, 0 on success
+ */
+static inline int hsi_stop_tx(struct hsi_client *cl)
+{
+       if (!hsi_port_claimed(cl))
+               return -EACCES;
+       return hsi_get_port(cl)->stop_tx(cl);
+}
+#endif /* __LINUX_HSI_H__ */
diff --git a/include/linux/hsi/hsi_char.h b/include/linux/hsi/hsi_char.h
new file mode 100644 (file)
index 0000000..76160b4
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Part of the HSI character device driver.
+ *
+ * Copyright (C) 2010 Nokia Corporation. All rights reserved.
+ *
+ * Contact: Andras Domokos <andras.domokos at nokia.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 published by the Free Software Foundation.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+
+#ifndef __HSI_CHAR_H
+#define __HSI_CHAR_H
+
+#define HSI_CHAR_MAGIC         'k'
+#define HSC_IOW(num, dtype)    _IOW(HSI_CHAR_MAGIC, num, dtype)
+#define HSC_IOR(num, dtype)    _IOR(HSI_CHAR_MAGIC, num, dtype)
+#define HSC_IOWR(num, dtype)   _IOWR(HSI_CHAR_MAGIC, num, dtype)
+#define HSC_IO(num)            _IO(HSI_CHAR_MAGIC, num)
+
+#define HSC_RESET              HSC_IO(16)
+#define HSC_SET_PM             HSC_IO(17)
+#define HSC_SEND_BREAK         HSC_IO(18)
+#define HSC_SET_RX             HSC_IOW(19, struct hsc_rx_config)
+#define HSC_GET_RX             HSC_IOW(20, struct hsc_rx_config)
+#define HSC_SET_TX             HSC_IOW(21, struct hsc_tx_config)
+#define HSC_GET_TX             HSC_IOW(22, struct hsc_tx_config)
+
+#define HSC_PM_DISABLE         0
+#define HSC_PM_ENABLE          1
+
+#define HSC_MODE_STREAM                1
+#define HSC_MODE_FRAME         2
+#define HSC_FLOW_SYNC          0
+#define HSC_ARB_RR             0
+#define HSC_ARB_PRIO           1
+
+struct hsc_rx_config {
+       uint32_t mode;
+       uint32_t flow;
+       uint32_t channels;
+};
+
+struct hsc_tx_config {
+       uint32_t mode;
+       uint32_t channels;
+       uint32_t speed;
+       uint32_t arb_mode;
+};
+
+#endif /* __HSI_CHAR_H */
index 79c4f26..18a5d02 100644 (file)
@@ -22,7 +22,7 @@
 #define EQL_DEFAULT_SLAVE_PRIORITY 28800
 #define EQL_DEFAULT_MAX_SLAVES     4
 #define EQL_DEFAULT_MTU            576
-#define EQL_DEFAULT_RESCHED_IVAL   100
+#define EQL_DEFAULT_RESCHED_IVAL   HZ
 
 #define EQL_ENSLAVE     (SIOCDEVPRIVATE)
 #define EQL_EMANCIPATE  (SIOCDEVPRIVATE + 1)
index d056263..b0f2c56 100644 (file)
@@ -4,8 +4,8 @@
  * GPL v2 Only
  */
 
-#ifndef __ATMEL_NAND_H__
-#define __ATMEL_NAND_H__
+#ifndef __ATMEL_H__
+#define __ATMEL_H__
 
 #include <linux/mtd/nand.h>
 
@@ -24,4 +24,4 @@ struct atmel_nand_data {
        unsigned int    num_parts;
 };
 
-#endif /* __ATMEL_NAND_H__ */
+#endif /* __ATMEL_H__ */
index 248fb05..83d800c 100644 (file)
@@ -620,8 +620,10 @@ struct sta_bss_parameters {
  * @llid: mesh local link id
  * @plid: mesh peer link id
  * @plink_state: mesh peer link state
- * @signal: signal strength of last received packet in dBm
- * @signal_avg: signal strength average in dBm
+ * @signal: the signal strength, type depends on the wiphy's signal_type
+       NOTE: For CFG80211_SIGNAL_TYPE_MBM, value is expressed in _dBm_.
+ * @signal_avg: avg signal strength, type depends on the wiphy's signal_type
+       NOTE: For CFG80211_SIGNAL_TYPE_MBM, value is expressed in _dBm_.
  * @txrate: current unicast bitrate from this station
  * @rxrate: current unicast bitrate to this station
  * @rx_packets: packets received from this station
index 72f33fa..6cfd71d 100644 (file)
@@ -1414,8 +1414,8 @@ endif # MODULES
 config INIT_ALL_POSSIBLE
        bool
        help
-         Back when each arch used to define their own cpu_online_map and
-         cpu_possible_map, some of them chose to initialize cpu_possible_map
+         Back when each arch used to define their own cpu_online_mask and
+         cpu_possible_mask, some of them chose to initialize cpu_possible_mask
          with all 1s, and others with all 0s.  When they were centralised,
          it was better to provide this option than to break all the archs
          and have several arch maintainers pursuing me down dark alleys.
index b96ad75..14f7070 100644 (file)
@@ -270,11 +270,11 @@ static struct file_system_type cpuset_fs_type = {
  * are online.  If none are online, walk up the cpuset hierarchy
  * until we find one that does have some online cpus.  If we get
  * all the way to the top and still haven't found any online cpus,
- * return cpu_online_map.  Or if passed a NULL cs from an exit'ing
- * task, return cpu_online_map.
+ * return cpu_online_mask.  Or if passed a NULL cs from an exit'ing
+ * task, return cpu_online_mask.
  *
  * One way or another, we guarantee to return some non-empty subset
- * of cpu_online_map.
+ * of cpu_online_mask.
  *
  * Call with callback_mutex held.
  */
@@ -867,7 +867,7 @@ static int update_cpumask(struct cpuset *cs, struct cpuset *trialcs,
        int retval;
        int is_load_balanced;
 
-       /* top_cpuset.cpus_allowed tracks cpu_online_map; it's read-only */
+       /* top_cpuset.cpus_allowed tracks cpu_online_mask; it's read-only */
        if (cs == &top_cpuset)
                return -EACCES;
 
@@ -2149,7 +2149,7 @@ void __init cpuset_init_smp(void)
  *
  * Description: Returns the cpumask_var_t cpus_allowed of the cpuset
  * attached to the specified @tsk.  Guaranteed to return some non-empty
- * subset of cpu_online_map, even if this means going outside the
+ * subset of cpu_online_mask, even if this means going outside the
  * tasks cpuset.
  **/
 
index c3c46c7..0c56d44 100644 (file)
@@ -5,6 +5,7 @@
  * context. The enqueueing is NMI-safe.
  */
 
+#include <linux/bug.h>
 #include <linux/kernel.h>
 #include <linux/export.h>
 #include <linux/irq_work.h>
index 6f10eb2..89fe3d1 100644 (file)
@@ -1,6 +1,8 @@
 /*
  * padata.c - generic interface to process data streams in parallel
  *
+ * See Documentation/padata.txt for an api documentation.
+ *
  * Copyright (C) 2008, 2009 secunet Security Networks AG
  * Copyright (C) 2008, 2009 Steffen Klassert <steffen.klassert@secunet.com>
  *
@@ -354,13 +356,13 @@ static int padata_setup_cpumasks(struct parallel_data *pd,
        if (!alloc_cpumask_var(&pd->cpumask.pcpu, GFP_KERNEL))
                return -ENOMEM;
 
-       cpumask_and(pd->cpumask.pcpu, pcpumask, cpu_active_mask);
+       cpumask_and(pd->cpumask.pcpu, pcpumask, cpu_online_mask);
        if (!alloc_cpumask_var(&pd->cpumask.cbcpu, GFP_KERNEL)) {
                free_cpumask_var(pd->cpumask.cbcpu);
                return -ENOMEM;
        }
 
-       cpumask_and(pd->cpumask.cbcpu, cbcpumask, cpu_active_mask);
+       cpumask_and(pd->cpumask.cbcpu, cbcpumask, cpu_online_mask);
        return 0;
 }
 
@@ -564,7 +566,7 @@ EXPORT_SYMBOL(padata_unregister_cpumask_notifier);
 static bool padata_validate_cpumask(struct padata_instance *pinst,
                                    const struct cpumask *cpumask)
 {
-       if (!cpumask_intersects(cpumask, cpu_active_mask)) {
+       if (!cpumask_intersects(cpumask, cpu_online_mask)) {
                pinst->flags |= PADATA_INVALID;
                return false;
        }
@@ -678,7 +680,7 @@ static int __padata_add_cpu(struct padata_instance *pinst, int cpu)
 {
        struct parallel_data *pd;
 
-       if (cpumask_test_cpu(cpu, cpu_active_mask)) {
+       if (cpumask_test_cpu(cpu, cpu_online_mask)) {
                pd = padata_alloc_pd(pinst, pinst->cpumask.pcpu,
                                     pinst->cpumask.cbcpu);
                if (!pd)
@@ -746,6 +748,9 @@ static int __padata_remove_cpu(struct padata_instance *pinst, int cpu)
                        return -ENOMEM;
 
                padata_replace(pinst, pd);
+
+               cpumask_clear_cpu(cpu, pd->cpumask.cbcpu);
+               cpumask_clear_cpu(cpu, pd->cpumask.pcpu);
        }
 
        return 0;
index 8e21b6d..a5c2248 100644 (file)
@@ -167,7 +167,8 @@ static struct garp_attr *garp_attr_lookup(const struct garp_applicant *app,
        return NULL;
 }
 
-static void garp_attr_insert(struct garp_applicant *app, struct garp_attr *new)
+static struct garp_attr *garp_attr_create(struct garp_applicant *app,
+                                         const void *data, u8 len, u8 type)
 {
        struct rb_node *parent = NULL, **p = &app->gid.rb_node;
        struct garp_attr *attr;
@@ -176,21 +177,16 @@ static void garp_attr_insert(struct garp_applicant *app, struct garp_attr *new)
        while (*p) {
                parent = *p;
                attr = rb_entry(parent, struct garp_attr, node);
-               d = garp_attr_cmp(attr, new->data, new->dlen, new->type);
+               d = garp_attr_cmp(attr, data, len, type);
                if (d < 0)
                        p = &parent->rb_left;
                else if (d > 0)
                        p = &parent->rb_right;
+               else {
+                       /* The attribute already exists; re-use it. */
+                       return attr;
+               }
        }
-       rb_link_node(&new->node, parent, p);
-       rb_insert_color(&new->node, &app->gid);
-}
-
-static struct garp_attr *garp_attr_create(struct garp_applicant *app,
-                                         const void *data, u8 len, u8 type)
-{
-       struct garp_attr *attr;
-
        attr = kmalloc(sizeof(*attr) + len, GFP_ATOMIC);
        if (!attr)
                return attr;
@@ -198,7 +194,9 @@ static struct garp_attr *garp_attr_create(struct garp_applicant *app,
        attr->type  = type;
        attr->dlen  = len;
        memcpy(attr->data, data, len);
-       garp_attr_insert(app, attr);
+
+       rb_link_node(&attr->node, parent, p);
+       rb_insert_color(&attr->node, &app->gid);
        return attr;
 }
 
index 5d59155..6c7dc9d 100644 (file)
@@ -1596,6 +1596,7 @@ int dev_forward_skb(struct net_device *dev, struct sk_buff *skb)
                kfree_skb(skb);
                return NET_RX_DROP;
        }
+       skb->skb_iif = 0;
        skb_set_dev(skb, dev);
        skb->tstamp.tv64 = 0;
        skb->pkt_type = PACKET_HOST;
index 4dc1c10..167ea10 100644 (file)
@@ -2041,7 +2041,7 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr,
                if (err < 0)
                        goto e_err;
        }
-       rth = rt_dst_alloc(init_net.loopback_dev,
+       rth = rt_dst_alloc(dev_net(dev)->loopback_dev,
                           IN_DEV_CONF_GET(in_dev, NOPOLICY), false);
        if (!rth)
                goto e_nobufs;
index 496b627..3992e26 100644 (file)
@@ -881,6 +881,16 @@ static struct rt6_info *ip6_pol_route_input(struct net *net, struct fib6_table *
        return ip6_pol_route(net, table, fl6->flowi6_iif, fl6, flags);
 }
 
+static struct dst_entry *ip6_route_input_lookup(struct net *net,
+                                               struct net_device *dev,
+                                               struct flowi6 *fl6, int flags)
+{
+       if (rt6_need_strict(&fl6->daddr) && dev->type != ARPHRD_PIMREG)
+               flags |= RT6_LOOKUP_F_IFACE;
+
+       return fib6_rule_lookup(net, fl6, flags, ip6_pol_route_input);
+}
+
 void ip6_route_input(struct sk_buff *skb)
 {
        const struct ipv6hdr *iph = ipv6_hdr(skb);
@@ -895,10 +905,7 @@ void ip6_route_input(struct sk_buff *skb)
                .flowi6_proto = iph->nexthdr,
        };
 
-       if (rt6_need_strict(&iph->daddr) && skb->dev->type != ARPHRD_PIMREG)
-               flags |= RT6_LOOKUP_F_IFACE;
-
-       skb_dst_set(skb, fib6_rule_lookup(net, &fl6, flags, ip6_pol_route_input));
+       skb_dst_set(skb, ip6_route_input_lookup(net, skb->dev, &fl6, flags));
 }
 
 static struct rt6_info *ip6_pol_route_output(struct net *net, struct fib6_table *table,
@@ -2537,7 +2544,7 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void
        struct sk_buff *skb;
        struct rtmsg *rtm;
        struct flowi6 fl6;
-       int err, iif = 0;
+       int err, iif = 0, oif = 0;
 
        err = nlmsg_parse(nlh, sizeof(*rtm), tb, RTA_MAX, rtm_ipv6_policy);
        if (err < 0)
@@ -2564,15 +2571,29 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void
                iif = nla_get_u32(tb[RTA_IIF]);
 
        if (tb[RTA_OIF])
-               fl6.flowi6_oif = nla_get_u32(tb[RTA_OIF]);
+               oif = nla_get_u32(tb[RTA_OIF]);
 
        if (iif) {
                struct net_device *dev;
+               int flags = 0;
+
                dev = __dev_get_by_index(net, iif);
                if (!dev) {
                        err = -ENODEV;
                        goto errout;
                }
+
+               fl6.flowi6_iif = iif;
+
+               if (!ipv6_addr_any(&fl6.saddr))
+                       flags |= RT6_LOOKUP_F_HAS_SADDR;
+
+               rt = (struct rt6_info *)ip6_route_input_lookup(net, dev, &fl6,
+                                                              flags);
+       } else {
+               fl6.flowi6_oif = oif;
+
+               rt = (struct rt6_info *)ip6_route_output(net, NULL, &fl6);
        }
 
        skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
@@ -2587,7 +2608,6 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void
        skb_reset_mac_header(skb);
        skb_reserve(skb, MAX_HEADER + sizeof(struct ipv6hdr));
 
-       rt = (struct rt6_info*) ip6_route_output(net, NULL, &fl6);
        skb_dst_set(skb, &rt->dst);
 
        err = rt6_fill_node(net, skb, rt, &fl6.daddr, &fl6.saddr, iif,
index 1068f66..64d3ce5 100644 (file)
@@ -49,6 +49,8 @@ static void ieee80211_free_tid_rx(struct rcu_head *h)
                container_of(h, struct tid_ampdu_rx, rcu_head);
        int i;
 
+       del_timer_sync(&tid_rx->reorder_timer);
+
        for (i = 0; i < tid_rx->buf_size; i++)
                dev_kfree_skb(tid_rx->reorder_buf[i]);
        kfree(tid_rx->reorder_buf);
@@ -91,7 +93,6 @@ void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
                                     tid, WLAN_BACK_RECIPIENT, reason);
 
        del_timer_sync(&tid_rx->session_timer);
-       del_timer_sync(&tid_rx->reorder_timer);
 
        call_rcu(&tid_rx->rcu_head, ieee80211_free_tid_rx);
 }
index b581a24..1633648 100644 (file)
@@ -102,9 +102,6 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed)
 
        might_sleep();
 
-       /* If this off-channel logic ever changes,  ieee80211_on_oper_channel
-        * may need to change as well.
-        */
        offchannel_flag = local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL;
        if (local->scan_channel) {
                chan = local->scan_channel;
index 33cd169..c70e176 100644 (file)
@@ -370,7 +370,7 @@ static int ieee80211_start_sw_scan(struct ieee80211_local *local)
         */
        drv_sw_scan_start(local);
 
-       local->leave_oper_channel_time = 0;
+       local->leave_oper_channel_time = jiffies;
        local->next_scan_state = SCAN_DECISION;
        local->scan_channel_idx = 0;
 
index 3eb348b..d98c868 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/skbuff.h>
+#include <linux/atomic.h>
 #include <linux/netlink.h>
 #include <linux/rculist.h>
 #include <linux/slab.h>
@@ -17,7 +18,6 @@
 #include <linux/errno.h>
 #include <net/netlink.h>
 #include <net/sock.h>
-#include <asm/atomic.h>
 
 #include <linux/netfilter.h>
 #include <linux/netfilter/nfnetlink.h>
index 1ab8689..906cc05 100644 (file)
@@ -95,11 +95,11 @@ static int rose_set_mac_address(struct net_device *dev, void *addr)
        struct sockaddr *sa = addr;
        int err;
 
-       if (!memcpy(dev->dev_addr, sa->sa_data, dev->addr_len))
+       if (!memcmp(dev->dev_addr, sa->sa_data, dev->addr_len))
                return 0;
 
        if (dev->flags & IFF_UP) {
-               err = rose_add_loopback_node((rose_address *)dev->dev_addr);
+               err = rose_add_loopback_node((rose_address *)sa->sa_data);
                if (err)
                        return err;
 
index 4c1eb94..e49da27 100644 (file)
@@ -2386,7 +2386,9 @@ nla_put_failure:
 }
 
 static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
-                               int flags, struct net_device *dev,
+                               int flags,
+                               struct cfg80211_registered_device *rdev,
+                               struct net_device *dev,
                                const u8 *mac_addr, struct station_info *sinfo)
 {
        void *hdr;
@@ -2425,12 +2427,18 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
        if (sinfo->filled & STATION_INFO_PLINK_STATE)
                NLA_PUT_U8(msg, NL80211_STA_INFO_PLINK_STATE,
                            sinfo->plink_state);
-       if (sinfo->filled & STATION_INFO_SIGNAL)
-               NLA_PUT_U8(msg, NL80211_STA_INFO_SIGNAL,
-                          sinfo->signal);
-       if (sinfo->filled & STATION_INFO_SIGNAL_AVG)
-               NLA_PUT_U8(msg, NL80211_STA_INFO_SIGNAL_AVG,
-                          sinfo->signal_avg);
+       switch (rdev->wiphy.signal_type) {
+       case CFG80211_SIGNAL_TYPE_MBM:
+               if (sinfo->filled & STATION_INFO_SIGNAL)
+                       NLA_PUT_U8(msg, NL80211_STA_INFO_SIGNAL,
+                                  sinfo->signal);
+               if (sinfo->filled & STATION_INFO_SIGNAL_AVG)
+                       NLA_PUT_U8(msg, NL80211_STA_INFO_SIGNAL_AVG,
+                                  sinfo->signal_avg);
+               break;
+       default:
+               break;
+       }
        if (sinfo->filled & STATION_INFO_TX_BITRATE) {
                if (!nl80211_put_sta_rate(msg, &sinfo->txrate,
                                          NL80211_STA_INFO_TX_BITRATE))
@@ -2523,7 +2531,7 @@ static int nl80211_dump_station(struct sk_buff *skb,
                if (nl80211_send_station(skb,
                                NETLINK_CB(cb->skb).pid,
                                cb->nlh->nlmsg_seq, NLM_F_MULTI,
-                               netdev, mac_addr,
+                               dev, netdev, mac_addr,
                                &sinfo) < 0)
                        goto out;
 
@@ -2568,7 +2576,7 @@ static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info)
                return -ENOMEM;
 
        if (nl80211_send_station(msg, info->snd_pid, info->snd_seq, 0,
-                                dev, mac_addr, &sinfo) < 0) {
+                                rdev, dev, mac_addr, &sinfo) < 0) {
                nlmsg_free(msg);
                return -ENOBUFS;
        }
@@ -7596,7 +7604,8 @@ void nl80211_send_sta_event(struct cfg80211_registered_device *rdev,
        if (!msg)
                return;
 
-       if (nl80211_send_station(msg, 0, 0, 0, dev, mac_addr, sinfo) < 0) {
+       if (nl80211_send_station(msg, 0, 0, 0,
+                                rdev, dev, mac_addr, sinfo) < 0) {
                nlmsg_free(msg);
                return;
        }
index 0d6004e..cf7b12f 100755 (executable)
@@ -254,6 +254,6 @@ case "$1" in
 esac
 
 # Remove structure forward declarations.
-if [ -n $remove_structs ]; then
+if [ -n "$remove_structs" ]; then
     LANG=C sed -i -e '/^\([a-zA-Z_][a-zA-Z0-9_]*\)\t.*\t\/\^struct \1;.*\$\/;"\tx$/d' $1
 fi
index afbabf4..3fea5a1 100644 (file)
@@ -58,9 +58,9 @@ static int mpc8610_hpcd_machine_probe(struct snd_soc_card *card)
 {
        struct mpc8610_hpcd_data *machine_data =
                container_of(card, struct mpc8610_hpcd_data, card);
-       struct ccsr_guts_86xx __iomem *guts;
+       struct ccsr_guts __iomem *guts;
 
-       guts = ioremap(guts_phys, sizeof(struct ccsr_guts_86xx));
+       guts = ioremap(guts_phys, sizeof(struct ccsr_guts));
        if (!guts) {
                dev_err(card->dev, "could not map global utilities\n");
                return -ENOMEM;
@@ -142,9 +142,9 @@ static int mpc8610_hpcd_machine_remove(struct snd_soc_card *card)
 {
        struct mpc8610_hpcd_data *machine_data =
                container_of(card, struct mpc8610_hpcd_data, card);
-       struct ccsr_guts_86xx __iomem *guts;
+       struct ccsr_guts __iomem *guts;
 
-       guts = ioremap(guts_phys, sizeof(struct ccsr_guts_86xx));
+       guts = ioremap(guts_phys, sizeof(struct ccsr_guts));
        if (!guts) {
                dev_err(card->dev, "could not map global utilities\n");
                return -ENOMEM;
index 4662340..982a1c9 100644 (file)
@@ -46,7 +46,7 @@
  * ch: The channel on the DMA controller (0, 1, 2, or 3)
  * device: The device to set as the target (CCSR_GUTS_DMUXCR_xxx)
  */
-static inline void guts_set_dmuxcr(struct ccsr_guts_85xx __iomem *guts,
+static inline void guts_set_dmuxcr(struct ccsr_guts __iomem *guts,
        unsigned int co, unsigned int ch, unsigned int device)
 {
        unsigned int shift = 16 + (8 * (1 - co) + 2 * (3 - ch));
@@ -90,9 +90,9 @@ static int p1022_ds_machine_probe(struct snd_soc_card *card)
 {
        struct machine_data *mdata =
                container_of(card, struct machine_data, card);
-       struct ccsr_guts_85xx __iomem *guts;
+       struct ccsr_guts __iomem *guts;
 
-       guts = ioremap(guts_phys, sizeof(struct ccsr_guts_85xx));
+       guts = ioremap(guts_phys, sizeof(struct ccsr_guts));
        if (!guts) {
                dev_err(card->dev, "could not map global utilities\n");
                return -ENOMEM;
@@ -164,9 +164,9 @@ static int p1022_ds_machine_remove(struct snd_soc_card *card)
 {
        struct machine_data *mdata =
                container_of(card, struct machine_data, card);
-       struct ccsr_guts_85xx __iomem *guts;
+       struct ccsr_guts __iomem *guts;
 
-       guts = ioremap(guts_phys, sizeof(struct ccsr_guts_85xx));
+       guts = ioremap(guts_phys, sizeof(struct ccsr_guts));
        if (!guts) {
                dev_err(card->dev, "could not map global utilities\n");
                return -ENOMEM;