Merge branch 'drm-fixes-intel' of git://people.freedesktop.org/~airlied/linux
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 3 Apr 2012 17:13:34 +0000 (10:13 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 3 Apr 2012 17:13:34 +0000 (10:13 -0700)
Pull drm update from Dave Airlie:
 "This pull just contains a forward of the Intel fixes from Daniel.

  The only annoyance is the RC6 enable, which really should have made
  -next, but since Ubuntu are shipping it I reckon its getting a good
  testing now by the time 3.4 comes out.

  The pull from Daniel contains his pull message to me:

    "A few patches for 3.4, major part is 3 regression fixes:
     - ppgtt broke hibernate on snb/ivb.  Somehow our QA claims that it
       still works, which is why this has not been caught earlier.
     - ppgtt flails in combination with dmar.  I kinda expected this one :(
     - fence handling bugfix for gen2/3.  Iirc this one is about a year
       old, fix curtesy Chris Wilson.  I've created an shockingly simple
       i-g-t test to catch this in the future."

     Wrt regressions I've just got a report that gmbus (newly enabled
     again in 3.4) is a bit noisy.  I'm looking into this atm.

     Also included are the rc6 enable patches for snb from Eugeni.  I
     wanted to include these in the main 3.4 pull but screwed it up.
     Please hit me.  Imo these kind of patches really should go in
     before -rc1, but in thise case rc6 has brought us tons of press and
     guinea pigs^W^W testers and ubuntu is already running with it.  So
     I estimate a pretty small chance for this to blow up.

     And some smaller things:
      - two minor locking snafus
      - server gt2 ivb pciid
      - 2 patches to sanitize the register state left behind by the bios
        some more
      - 2 new quirk entries
      - cs readback trick against missed IRQs from ivb also enabled on snb
      - sprite fix from Jesse"

Let's see if the "enable RC6 on sandybridge" finally works and sticks.
I've been enabling it by hand (i915.i915_enable_rc6=1) for several
months on my Macbook Air, and it definitely makes a difference (and has
worked for me).  But every time we enabled it before it showed some odd
hw buglet for *somebody*.

This time it's all good, I'm sure.

* 'drm-fixes-intel' of git://people.freedesktop.org/~airlied/linux:
  drm/i915: treat src w & h as fixed point in sprite handling code
  drm/i915: no-lvds quirk on MSI DC500
  drm/i915: Add lock on drm_helper_resume_force_mode
  drm/i915: don't leak struct_mutex lock on ppgtt init failures
  drm/i915: disable ppgtt on snb when dmar is enabled
  drm/i915: add Ivy Bridge GT2 Server entries
  drm/i915: properly clear SSC1 bit in the pch refclock init code
  drm/i915: apply CS reg readback trick against missed IRQ on snb
  drm/i915: quirk away broken OpRegion VBT
  drm/i915: enable plain RC6 on Sandy Bridge by default
  drm/i915: allow to select rc6 modes via kernel parameter
  drm/i915: Mark untiled BLT commands as fenced on gen2/3
  drm/i915: properly restore the ppgtt page directory on resume
  drm/i915: Sanitize BIOS debugging bits from PIPECONF

196 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/m68k/include/asm/atomic.h
arch/m68k/mac/config.c
arch/m68k/q40/config.c
arch/microblaze/include/asm/cmpxchg.h
arch/microblaze/include/asm/futex.h
arch/microblaze/include/asm/processor.h
arch/microblaze/kernel/early_printk.c
arch/microblaze/kernel/setup.c
arch/microblaze/kernel/unwind.c
arch/microblaze/lib/uaccess_old.S
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_fb_helper.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/gpu/drm/nouveau/Kconfig
drivers/gpu/drm/nouveau/nouveau_bios.c
drivers/gpu/drm/nouveau/nouveau_channel.c
drivers/gpu/drm/nouveau/nouveau_dma.h
drivers/gpu/drm/nouveau/nouveau_state.c
drivers/gpu/drm/radeon/atom.c
drivers/gpu/drm/radeon/atom.h
drivers/gpu/drm/radeon/radeon_object.c
drivers/gpu/drm/udl/udl_drv.c
drivers/gpu/drm/udl/udl_drv.h
drivers/gpu/drm/udl/udl_gem.c
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 9c27e5125dd26efb5ca49c4b2bc9beadb4d559d7..7514dbf0a6796c4e216a175fa79db0ed3ff470d9 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 5c51ed406d1d1c8c87d5f66e02b676f8ddb2f65a..cefd3d8bbd11db69f51ffee25094e138fc5d0cbd 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 a20bfd415e41cca69297760cee32de91c8d2812c..66ef8f35613d2190b4e2f5e42084a4736ff3dc69 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 3b7488fc33730c3098a62cea18f6d0b0de3ef584..e34b531dc3161a18cc55fc591bd1db0e7c6991dd 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 eecf3441ac2154c3806bc5b7f1f7cfc213a5f920..962232d627812799b0d4c537c00e62f58bf47df4 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 4087a569b43b15f7f135241c88092395651a4a7a..50d438db1f6ba3d8fc7131c30d340bb7d293d414 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 ab1869dac97a96a6399964e088f1dc58ff6191e2..4dd41fc9e23572793ec384b28b77fb9d5ada63d8 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 2cee7d1eb958bc39b19b31f18447fe4c6119419a..addbbe8028c29c8789fd730fa784b056065787e5 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 169a8400745659171efcfcefa6a4e55b9dbef060..c14011fe832d2fa8f014c0c5a7805204e5949387 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 71733866cb4f21c308d5e926b59d261576666741..70742ec997f86eb7ec06304da5715d3acd03569b 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 ba2484f4cb2a07e33f62d76666b04538dd80a8cf..c05868cc61c1aacc290ecfacfebb048cf032bc6f 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 41098a3803a22db4fa787d4ab5129dfe1da8456d..4f8d8bcdc7de53a2d4b7cbf89989a27243e59dea 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 15d1fd22bbc54fba10da9b9caf9598619e7cd7ec..9b44a9e2d05abcf77809cee85449d65bc78e8ef5 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 ac795d311f4411cef9cd8c76b1e91cc6b7d5988c..6f38b6120d96bc841f4563c1fe3202ae7a78b7f3 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 336e6173794f3a2c2b720d4b3ce87e8ddca7d67a..f4e32de263a7cefe98f3c9a5f7b2dc4071c12d00 100644 (file)
@@ -3,6 +3,7 @@
 
 #include <linux/types.h>
 #include <linux/irqflags.h>
+#include <asm/cmpxchg.h>
 
 /*
  * Atomic operations that C can't guarantee us.  Useful for
index 96fa6ed7e7995b5bbee00f1d3d6f513ccba288ad..d9f62e0f46c0b8861aff1509549be510c0b2a514 100644 (file)
@@ -980,6 +980,9 @@ int __init mac_platform_init(void)
 {
        u8 *swim_base;
 
+       if (!MACH_IS_MAC)
+               return -ENODEV;
+
        /*
         * Serial devices
         */
index 512adb64f7dd574bbe11613ddc21fc75e80bfcf1..8a1ce327c963da94dffa388f2fff533260467679 100644 (file)
@@ -334,6 +334,9 @@ static __init int q40_add_kbd_device(void)
 {
        struct platform_device *pdev;
 
+       if (!MACH_IS_Q40)
+               return -ENODEV;
+
        pdev = platform_device_register_simple("q40kbd", -1, NULL, 0);
        if (IS_ERR(pdev))
                return PTR_ERR(pdev);
index 0094859abd9b3c7cab1cb9a3a037b2a589b8d6c8..538afc0ab9f3d60f15d70c1a9ec53394c429475c 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef _ASM_MICROBLAZE_CMPXCHG_H
 #define _ASM_MICROBLAZE_CMPXCHG_H
 
+#include <linux/irqflags.h>
+
 void __bad_xchg(volatile void *ptr, int size);
 
 static inline unsigned long __xchg(unsigned long x, volatile void *ptr,
index b0526d2716fa7defea7c036c750284f5a7496443..ff8cde159d9a4809abac1994537b5425c71c9cb4 100644 (file)
@@ -24,7 +24,7 @@
                        .word   1b,4b,2b,4b;                            \
                        .previous;"                                     \
        : "=&r" (oldval), "=&r" (ret)                                   \
-       : "b" (uaddr), "i" (-EFAULT), "r" (oparg)                       \
+       : "r" (uaddr), "i" (-EFAULT), "r" (oparg)                       \
        );                                                              \
 })
 
index 510a8e1c16ba604f5200987fb779da24f45b48ea..bffb545272997b54c2a0090b398618f83320662a 100644 (file)
@@ -31,6 +31,8 @@ extern const struct seq_operations cpuinfo_op;
 /* Do necessary setup to start up a newly executed thread. */
 void start_thread(struct pt_regs *regs, unsigned long pc, unsigned long usp);
 
+extern void ret_from_fork(void);
+
 # endif /* __ASSEMBLY__ */
 
 # ifndef CONFIG_MMU
@@ -143,8 +145,6 @@ static inline void exit_thread(void)
 
 unsigned long get_wchan(struct task_struct *p);
 
-extern void ret_from_fork(void);
-
 /* The size allocated for kernel stacks. This _must_ be a power of two! */
 # define KERNEL_STACK_SIZE     0x2000
 
index ec485876d0d0ec3ca14b005325320fd5c154eb59..aba1f9a97d5d38aa64f31f4965be988ab1d597f7 100644 (file)
@@ -176,6 +176,7 @@ void __init remap_early_printk(void)
        base_addr = (u32) ioremap(base_addr, PAGE_SIZE);
        printk(KERN_CONT "0x%x\n", base_addr);
 
+#ifdef CONFIG_MMU
        /*
         * Early console is on the top of skipped TLB entries
         * decrease tlb_skip size ensure that hardcoded TLB entry will be
@@ -189,6 +190,7 @@ void __init remap_early_printk(void)
         *  cmp rX, orig_base_addr
         */
        tlb_skip -= 1;
+#endif
 }
 
 void __init disable_early_printk(void)
index 71af974aa24acfb82403968c23cb0cbccb7bb55a..16d8dfd9094b1a0df25eaa48799576449a8b234b 100644 (file)
@@ -206,6 +206,7 @@ static int microblaze_debugfs_init(void)
 }
 arch_initcall(microblaze_debugfs_init);
 
+# ifdef CONFIG_MMU
 static int __init debugfs_tlb(void)
 {
        struct dentry *d;
@@ -218,6 +219,7 @@ static int __init debugfs_tlb(void)
                return -ENOMEM;
 }
 device_initcall(debugfs_tlb);
+# endif
 #endif
 
 static int dflt_bus_notify(struct notifier_block *nb,
index 9781a528cfc9179c3c50c2f457fc62db54131b8b..6be4ae3c335140a0173dc0db06bab4dcf86f896d 100644 (file)
@@ -24,6 +24,7 @@
 #include <asm/sections.h>
 #include <asm/exceptions.h>
 #include <asm/unwind.h>
+#include <asm/switch_to.h>
 
 struct stack_trace;
 
index f037266cdaf3e358676c0428e83393c16dd410cb..f085995ee8482da474be869148b581543cbf786f 100644 (file)
@@ -122,22 +122,22 @@ __strnlen_user:
 15:    swi     r24, r5, 0x0018 + offset;       \
 16:    swi     r25, r5, 0x001C + offset;       \
        .section __ex_table,"a";                \
-       .word   1b, 0f;                         \
-       .word   2b, 0f;                         \
-       .word   3b, 0f;                         \
-       .word   4b, 0f;                         \
-       .word   5b, 0f;                         \
-       .word   6b, 0f;                         \
-       .word   7b, 0f;                         \
-       .word   8b, 0f;                         \
-       .word   9b, 0f;                         \
-       .word   10b, 0f;                        \
-       .word   11b, 0f;                        \
-       .word   12b, 0f;                        \
-       .word   13b, 0f;                        \
-       .word   14b, 0f;                        \
-       .word   15b, 0f;                        \
-       .word   16b, 0f;                        \
+       .word   1b, 33f;                        \
+       .word   2b, 33f;                        \
+       .word   3b, 33f;                        \
+       .word   4b, 33f;                        \
+       .word   5b, 33f;                        \
+       .word   6b, 33f;                        \
+       .word   7b, 33f;                        \
+       .word   8b, 33f;                        \
+       .word   9b, 33f;                        \
+       .word   10b, 33f;                       \
+       .word   11b, 33f;                       \
+       .word   12b, 33f;                       \
+       .word   13b, 33f;                       \
+       .word   14b, 33f;                       \
+       .word   15b, 33f;                       \
+       .word   16b, 33f;                       \
        .text
 
 #define COPY_80(offset)        \
@@ -190,14 +190,17 @@ w2:       sw      r4, r5, r3
 
 .align 4 /* Alignment is important to keep icache happy */
 page:  /* Create room on stack and save registers for storign values */
-       addik   r1, r1, -32
-       swi     r19, r1, 4
-       swi     r20, r1, 8
-       swi     r21, r1, 12
-       swi     r22, r1, 16
-       swi     r23, r1, 20
-       swi     r24, r1, 24
-       swi     r25, r1, 28
+       addik   r1, r1, -40
+       swi     r5, r1, 0
+       swi     r6, r1, 4
+       swi     r7, r1, 8
+       swi     r19, r1, 12
+       swi     r20, r1, 16
+       swi     r21, r1, 20
+       swi     r22, r1, 24
+       swi     r23, r1, 28
+       swi     r24, r1, 32
+       swi     r25, r1, 36
 loop:  /* r4, r19, r20, r21, r22, r23, r24, r25 are used for storing values */
        /* Loop unrolling to get performance boost */
        COPY_80(0x000);
@@ -205,21 +208,44 @@ loop:     /* r4, r19, r20, r21, r22, r23, r24, r25 are used for storing values */
        COPY_80(0x100);
        COPY_80(0x180);
        /* copy loop */
-       addik   r6, r6, 0x200
-       addik   r7, r7, -0x200
-       bneid   r7, loop
-       addik   r5, r5, 0x200
+       addik   r6, r6, 0x200
+       addik   r7, r7, -0x200
+       bneid   r7, loop
+       addik   r5, r5, 0x200
+
        /* Restore register content */
-       lwi     r19, r1, 4
-       lwi     r20, r1, 8
-       lwi     r21, r1, 12
-       lwi     r22, r1, 16
-       lwi     r23, r1, 20
-       lwi     r24, r1, 24
-       lwi     r25, r1, 28
-       addik   r1, r1, 32
+       lwi     r5, r1, 0
+       lwi     r6, r1, 4
+       lwi     r7, r1, 8
+       lwi     r19, r1, 12
+       lwi     r20, r1, 16
+       lwi     r21, r1, 20
+       lwi     r22, r1, 24
+       lwi     r23, r1, 28
+       lwi     r24, r1, 32
+       lwi     r25, r1, 36
+       addik   r1, r1, 40
        /* return back */
+       addik   r3, r0, 0
+       rtsd    r15, 8
+       nop
+
+/* Fault case - return temp count */
+33:
        addik   r3, r7, 0
+       /* Restore register content */
+       lwi     r5, r1, 0
+       lwi     r6, r1, 4
+       lwi     r7, r1, 8
+       lwi     r19, r1, 12
+       lwi     r20, r1, 16
+       lwi     r21, r1, 20
+       lwi     r22, r1, 24
+       lwi     r23, r1, 28
+       lwi     r24, r1, 32
+       lwi     r25, r1, 36
+       addik   r1, r1, 40
+       /* return back */
        rtsd    r15, 8
        nop
 
index c3e2b85c3b0294ef75315e683100c730ace5820a..97e7ce9b50ed4066d276ed98e47937bfd5236d42 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 802e6160f37e987802ac60b2e1cec193b4c832af..33f63bab478a7478ad34733eaa861f3aba01e78b 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 e309665b6c81962a82cb247b76f7b0312b0ba172..f8b2c592514de3293e219d92bb59939ec51e8ace 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 ca673569fd2421d390fbdd33029b98110727acae..3046e2986006b448c884bbb7355a676cc63e6ad9 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 9c1cce9de35fdf9ff28168a87f344b84ffc3370f..ba9376bf52a1e80bdaaef76201b50d973c932d0c 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 c4f75bbc0bd6160deedbb7ec127feb6e2c3bdc7f..f5dd38f1d0152b49b13c971c59fde0cd218cb93e 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 1f9ca07f53c8f33335cb316e11d6d61733e748cf..47037ec5589b88bca92df21c81a3a890f937bd36 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 db17f49886c26681b5fe1d61555e7c7b5f8602b9..fab316de57e96718a38abcd1c8434ca54b7ab363 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 2608752898c0823671b51773178edcd6e945398c..b71fae231049dfa86d25f3e5fef2216d968faa17 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 c6851df9ab741a4979ca373bc32b32862bfb5038..735b43bf8f82eebc8eec907c925b800cf49c544e 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 d667875be564ef97dbd55cc6ffced70e207ff202..de88e22694a05940b4dae2fd123688f7849fcdf8 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 38e7f6bd7922edd6c25e2169515cdccacfc81ea7..285cfef4ebc083cc24a554c3bb4a534a9092f48c 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 3ae56073cc3d717a8ab82b78be379d6fe52fb4e3..6c6defc24619fbab673b6296387c1dead503158b 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 4f957db01230906e23b8cdd854a2f4ac00813491..285213976a7f18811e5a90e5f00af2858c9a1cdd 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 f469145abaeb420e8dc31b44a87672273c14ab4d..22a215e94162362be8525740d0836a14efca4cb9 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 529042e4b9a22427577bc99211b9582a1f260aae..9ae875c8a2117f70ae664da9918b7baa9044b2a0 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 6d60e54e50a09a6fbbec45d686f85ba7b5c00fa3..3e204609d02e51905183ca21478ab6ae69e99459 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 1c250684c9028cfa70e17c675292d72247a69da1..27c07ed6adc1490921bceabcd6be5dac1cdb58b2 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 f8aef205d222234564b46fd7b35dede4ee865fd3..91db656294e85a642f40182b4245231293aaa22b 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 82b13bfcf3c0bc1cb5fc57f2caf1237aa4445580..6798343580f0bfcd9bc03eaab6baab9e675eb257 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 cc87a8441566d663071aa6b2fff7d105fc796a60..d6b6df5e874355c7c67624f6bdc7dc2a83cbfd82 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 48d6682f2434bfcc3ea0cbe70eb847e62de92d45..5b0e2926becd0ffdc6142c65a4f1d7fe3bf10969 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 f3b0c2cc9fea0ce611d07eb7fde72541d62860fa..976835d8f22e2a378f6166ff3ef20b37f7e1e6f9 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 ce04530d20003a42e045a634790691c99d715d53..aa4c488589ce51b7bbdf1089db7282e69bfaccad 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 cfe7a38708c3724d6fc88cc6b110d2917d85b3e9..18bdf74fa164042e0e3b07a7dd0867faf8d6069c 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 76a6e40a6f7c8e797882d2462a0533a4c1391901..782bd0a3c2f0f95496b1b144ebb3ec6e6218e0f8 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 f1950d1318273ae3b8dd2455ee493d436a7aaef8..135663a3e4fc945d4eaf9ef7706fa388feccfe07 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 e70ef2d86431bd7eef8c93adf219a88009ea6828..a59a25a1321843ff5fe72caf385b80aba0302f95 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 7340e1090b770302cdb055728b0c7740241c0ca6..642d88574b07a683c58e197a8a5b60d81ec92d85 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 bfb11e01133e23b3e33fdb2423e41c81f567fd86..e2d401ad8fbbed71bf6594f840dc63ab2dc367e0 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 3754ddc00af709fe8290a8234a2c20b1b53d28ee..9a6f04406e0d63ebee34841a15ebd665a50ad3cd 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 9848f9e39853fc9a06b497dae73c394c597c699c..313fce4f55747eb9d0fe8639a145ef7489c2e52e 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 0fe88e39945ecd5e4b13dee9ec03e362e0ebdfe8..e74b7cde9aee77482f27c739af6dad8cf024d725 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 bbc615206c6774d430889a76a0eb558551081437..62cd3c555bfbcf80a57dc29f1450786b5aa41ae4 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 7f9b6742f8b65889e5d90db2a0cb2f752eac301e..6e3409d590ac6eb55e19e43b3c0d8719262760cb 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 fa3e294fd34305c17fb9932a45d5439c1e006042..4ab08767118534c780b1136adf909024c7893414 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 4a475256585606889b791ce25a4f6683b21a315c..4cb375c0f8d173ff545c665971d8054d61fdfc17 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 ceb09cbd2329e782fe00a5c3e1326d217ab3e92b..818e763f826509b78efdcd2ca216e395b8a52c43 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 a19c8a063683205c35792991efad03fe961f8140..35e43673c45344afd3a58c382fb78a7bc419284d 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 5f85d8b34dbb0ed717484c03954a1254f4c5f0b1..92a94f4920ad6e2e5422ec7775f1891d70ed9d04 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 2e9852c0d487449911fc289e3520a90e6306f9b9..0a9e57e7446b277ed8cdcfdda3e29c17cc257f57 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 155206a6690879da2e6521c7604d74ad8f9e52a0..6f588e160fb0ec1bf4e035b282d8dd10f300e8f8 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 5671752f8d9cbccb2c5fb708bca8780883d56e19..5a5b6e4dd7386586b5a9e8d5559b6b104f48d447 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 b132ade26f778f2cfec7c2d5c7b6db48afe424d5..4f51bebac02c1493c5ed9a606327bf854b22be91 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 a0f768c1d9aa75fdb94a70dba711e175d8f66c9f..8d3a056ebeeaf250d5ec61f4fe0cba990001528c 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 04add3dca6fe44dfc242e89a36741c56786327fa..e4cb35159be43fe365ec569908f84732c5c67042 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 f76e42bcc6e7f4c213eef714761ee34630fbc483..f1ea0a0641350cbd0f7628bc3e7edde4fc38972d 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 29a89dad68b664b0dcfefdf29a19631904b21e3f..b2c99dc1c5e2f244bab9cf8fafcedb0860df67f6 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 6f0459cb745b8ccf6f338fe4750258537dcefef6..d236aef7e59fff7b7bc255cea2a86ce0a40425c1 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 262b19d6b627a7541266f0f569f97197be06e906..95952c82bf16653e40aa46ef1eeaa2f4fe96f8fa 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 a22ffa5bff9f85ca9ba961dc8896aa8be65c8fa3..0bf1b8910eebe74a6e86a32b3338ddf0a6d1ef1a 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 cc1148837e241d2c95332a630609a838d9ae59ee..e354bc0b052a22c22da2bf553586f665d2434000 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 a858532806ae34ae341c608d5c985a577992739e..c20da5bda3551cdcbc7c24d9605a24ef8654196b 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 0b65fbc8a6308c9b1f7aae823e7d10149d75c380..6116e3b75393c033da09649490c3603e49ddf206 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 7740dd26f00706d3b2059f475d10399f8f66d068..a0d6e894d97c05713dfa69db2e82ceaade3acfc7 100644 (file)
@@ -559,9 +559,13 @@ int drm_fb_helper_check_var(struct fb_var_screeninfo *var,
                return -EINVAL;
 
        /* Need to resize the fb object !!! */
-       if (var->bits_per_pixel > fb->bits_per_pixel || var->xres > fb->width || var->yres > fb->height) {
+       if (var->bits_per_pixel > fb->bits_per_pixel ||
+           var->xres > fb->width || var->yres > fb->height ||
+           var->xres_virtual > fb->width || var->yres_virtual > fb->height) {
                DRM_DEBUG("fb userspace requested width/height/bpp is greater than current fb "
-                         "object %dx%d-%d > %dx%d-%d\n", var->xres, var->yres, var->bits_per_pixel,
+                         "request %dx%d-%d (virtual %dx%d) > %dx%d-%d\n",
+                         var->xres, var->yres, var->bits_per_pixel,
+                         var->xres_virtual, var->yres_virtual,
                          fb->width, fb->height, fb->bits_per_pixel);
                return -EINVAL;
        }
index 7348a3dab250a47046eb1f025f12fb3365a5df16..cdfbf27b2b3ccf6bbda4d7e8c0ebef8b2c8e5381 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 0ef358e5324542a6be54751527e889c8eb8f3eca..83114b5e3cee236fe6a2f5b2cb261d6ba1abb3f8 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);
index ca1639918f57976b852bdcaab751d18402a882ad..97a81260485a15fb360a4fa6dfc37ac910fca303 100644 (file)
@@ -13,6 +13,7 @@ config DRM_NOUVEAU
        select ACPI_VIDEO if ACPI && X86 && BACKLIGHT_CLASS_DEVICE && VIDEO_OUTPUT_CONTROL && INPUT
        select ACPI_WMI if ACPI
        select MXM_WMI if ACPI
+       select POWER_SUPPLY
        help
          Choose this option for open-source nVidia support.
 
index 637afe71de5645108110fc73b37a0ba9b2a4255b..1947d6139a38e4cb7234fe090ec2456c7a3ac8d3 100644 (file)
@@ -177,14 +177,15 @@ bios_shadow_pci(struct nvbios *bios)
 
        if (!pci_enable_rom(pdev)) {
                void __iomem *rom = pci_map_rom(pdev, &length);
-               if (rom) {
+               if (rom && length) {
                        bios->data = kmalloc(length, GFP_KERNEL);
                        if (bios->data) {
                                memcpy_fromio(bios->data, rom, length);
                                bios->length = length;
                        }
-                       pci_unmap_rom(pdev, rom);
                }
+               if (rom)
+                       pci_unmap_rom(pdev, rom);
 
                pci_disable_rom(pdev);
        }
@@ -272,6 +273,7 @@ bios_shadow(struct drm_device *dev)
                mthd->score = score_vbios(bios, mthd->rw);
                mthd->size = bios->length;
                mthd->data = bios->data;
+               bios->data = NULL;
        } while (mthd->score != 3 && (++mthd)->shadow);
 
        mthd = shadow_methods;
@@ -280,7 +282,8 @@ bios_shadow(struct drm_device *dev)
                if (mthd->score > best->score) {
                        kfree(best->data);
                        best = mthd;
-               }
+               } else
+                       kfree(mthd->data);
        } while ((++mthd)->shadow);
 
        if (best->score) {
index 44e6416d4a336054409a24e05bfe20c66c4c7d1a..846afb0bfef4b5dff1ce87f06f6bd985a8fc1650 100644 (file)
@@ -436,11 +436,11 @@ nouveau_ioctl_fifo_alloc(struct drm_device *dev, void *data,
        }
 
        if (dev_priv->card_type < NV_C0) {
-               init->subchan[0].handle = NvSw;
-               init->subchan[0].grclass = NV_SW;
-               init->nr_subchan = 1;
-       } else {
-               init->nr_subchan = 0;
+               init->subchan[0].handle = 0x00000000;
+               init->subchan[0].grclass = 0x0000;
+               init->subchan[1].handle = NvSw;
+               init->subchan[1].grclass = NV_SW;
+               init->nr_subchan = 2;
        }
 
        /* Named memory object area */
index bcf0fd9e313eb6fdc2db1e158cdecfb77cf1310d..23d4edf992b7d20440eb53ce8273231ccfe487e1 100644 (file)
@@ -48,8 +48,8 @@ void nv50_dma_push(struct nouveau_channel *, struct nouveau_bo *,
 
 /* Hardcoded object assignments to subchannels (subchannel id). */
 enum {
-       NvSubSw         = 0,
-       NvSubM2MF       = 1,
+       NvSubM2MF       = 0,
+       NvSubSw         = 1,
        NvSub2D         = 2,
        NvSubCtxSurf2D  = 2,
        NvSubGdiRect    = 3,
index a4886b36d0faf771d6abc7d8aaa0983aca465850..c2a8511e855a344d515afe9a3daba8c74736f2b5 100644 (file)
@@ -642,7 +642,7 @@ nouveau_card_channel_init(struct drm_device *dev)
                OUT_RING  (chan, chan->vram_handle);
                OUT_RING  (chan, chan->gart_handle);
        } else
-       if (dev_priv->card_type <= NV_C0) {
+       if (dev_priv->card_type <= NV_D0) {
                ret = nouveau_gpuobj_gr_new(chan, 0x9039, 0x9039);
                if (ret)
                        goto error;
index d1bd239cd9e9eef5f88ef06e4964f158a7490986..5ce9bf51a8de680c1658e0dd26491e16f8f77511 100644 (file)
@@ -1306,8 +1306,11 @@ struct atom_context *atom_parse(struct card_info *card, void *bios)
 
 int atom_asic_init(struct atom_context *ctx)
 {
+       struct radeon_device *rdev = ctx->card->dev->dev_private;
        int hwi = CU16(ctx->data_table + ATOM_DATA_FWI_PTR);
        uint32_t ps[16];
+       int ret;
+
        memset(ps, 0, 64);
 
        ps[0] = cpu_to_le32(CU32(hwi + ATOM_FWI_DEFSCLK_PTR));
@@ -1317,7 +1320,17 @@ int atom_asic_init(struct atom_context *ctx)
 
        if (!CU16(ctx->cmd_table + 4 + 2 * ATOM_CMD_INIT))
                return 1;
-       return atom_execute_table(ctx, ATOM_CMD_INIT, ps);
+       ret = atom_execute_table(ctx, ATOM_CMD_INIT, ps);
+       if (ret)
+               return ret;
+
+       memset(ps, 0, 64);
+
+       if (rdev->family < CHIP_R600) {
+               if (CU16(ctx->cmd_table + 4 + 2 * ATOM_CMD_SPDFANCNTL))
+                       atom_execute_table(ctx, ATOM_CMD_SPDFANCNTL, ps);
+       }
+       return ret;
 }
 
 void atom_destroy(struct atom_context *ctx)
index 93cfe2086ba023b82b4271b136730a2d3a4cd25d..25fea631dad2d2ae03bee413b7d9254045a5f9d3 100644 (file)
@@ -44,6 +44,7 @@
 #define ATOM_CMD_SETSCLK       0x0A
 #define ATOM_CMD_SETMCLK       0x0B
 #define ATOM_CMD_SETPCLK       0x0C
+#define ATOM_CMD_SPDFANCNTL    0x39
 
 #define ATOM_DATA_FWI_PTR      0xC
 #define ATOM_DATA_IIO_PTR      0x32
index 6f70158d34e41f979ade9268cadeab8905ea4e81..df6a4dbd93f81acec1aa27f0312d2e47b5331b5c 100644 (file)
@@ -241,7 +241,8 @@ int radeon_bo_pin_restricted(struct radeon_bo *bo, u32 domain, u64 max_offset,
                                domain_start = bo->rdev->mc.vram_start;
                        else
                                domain_start = bo->rdev->mc.gtt_start;
-                       WARN_ON_ONCE((*gpu_addr - domain_start) > max_offset);
+                       WARN_ON_ONCE(max_offset <
+                                    (radeon_bo_gpu_offset(bo) - domain_start));
                }
 
                return 0;
index 5340c5f3987b0831d7d11f9c7a8c55735f14c4f5..53673907a6a0d93cf9367b62fdad247939bc70d3 100644 (file)
@@ -47,7 +47,7 @@ static struct vm_operations_struct udl_gem_vm_ops = {
 static const struct file_operations udl_driver_fops = {
        .owner = THIS_MODULE,
        .open = drm_open,
-       .mmap = drm_gem_mmap,
+       .mmap = udl_drm_gem_mmap,
        .poll = drm_poll,
        .read = drm_read,
        .unlocked_ioctl = drm_ioctl,
index 1612954a5bc4452e20bffdb30ab8e66b86f9e4cf..96820d03a30394a9e6b5eb8c42e528b5459ff931 100644 (file)
@@ -121,6 +121,7 @@ struct udl_gem_object *udl_gem_alloc_object(struct drm_device *dev,
 
 int udl_gem_vmap(struct udl_gem_object *obj);
 void udl_gem_vunmap(struct udl_gem_object *obj);
+int udl_drm_gem_mmap(struct file *filp, struct vm_area_struct *vma);
 int udl_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf);
 
 int udl_handle_damage(struct udl_framebuffer *fb, int x, int y,
index 852642dc11878ff912682628c097e8757bc7acb5..92f19ef329b0319819e47b57a007538275c93eaa 100644 (file)
@@ -71,6 +71,20 @@ int udl_dumb_destroy(struct drm_file *file, struct drm_device *dev,
        return drm_gem_handle_delete(file, handle);
 }
 
+int udl_drm_gem_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+       int ret;
+
+       ret = drm_gem_mmap(filp, vma);
+       if (ret)
+               return ret;
+
+       vma->vm_flags &= ~VM_PFNMAP;
+       vma->vm_flags |= VM_MIXEDMAP;
+
+       return ret;
+}
+
 int udl_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
 {
        struct udl_gem_object *obj = to_udl_bo(vma->vm_private_data);
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 05ed4d0cb18b0e0195bbceae9fc4d6fea8956a0b..c0b8c960ee3f7f115c6a5cd9ca3a7469b3185f3b 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 d055ae7fa040ff80fb77841e94e15d66575505ba..e2c83a2d76910629fc319d506af8735b323d080a 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 602338734634e184f50d8952911fa1d68d1cb9fd..8cde2a0538ab862f65b36411d4c3f06d2e0ec45e 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 b47e9bed2185a5c944ce7d25b473ed816d560418..884369f09cad1e3dbd519a8ea392227e4c2b0fce 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 10446ab404b55e48eb98be5b525ece01864db524..9a6da6edcfa899c99f62c140af7fe48223ce44cc 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 dd6de9f7a8a34ed0dd4f808c3b1a9f6783edc442..c726e09d0981bafc8ee3c1d2680a1e83326422c0 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 7f1e7ba75cd10c149d57c85551c54c02d3ee3db7..2183357f079948fe7590df8c095289329c231748 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 0c76186bb9e75aff0c3f7024780a8802d025285b..941b4e189adf67391ac06c8effefa820fbd0d5cb 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 a59cf961a436be4fc151b62160f2ad3d17429491..f219d38acf580075f4a9c6b93b54bfdcddbd0865 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 e37161f19250c278c69459fc9a08b86661c13c9a..2c9ee552dffcccd5cb22fcfbbbc99dea7e309141 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 f1f3ca65667ac379a0cdc7c435f92be3b721f623..44556b719e813ef164848d343b7bec97bb989b5d 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 8b163388659a63fa3fe8b056873065f02f679bdc..5c27454d2ec276c81e31cb09b7241b158db68441 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 5d71b7d43237f807cb45d1cc1e764d5439451c35..dbff5915b81a3b998f41d1f9bed232421417791b 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 beb4cdbdb6e1a5f06b980c9fad75f41faf65a154..efa557b76ac75e60235bf5fac8c828ef0588cbff 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 7ba557a610da1ea27d301b38814c28f299e0c0b4..763535ee4832e3882a3ee62a6654eeac7d328ae6 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 f7f9aa807264f51d8faef59a1f7297fa509d1b4f..e077d25087273721c0994b1c44dd5a41cceab882 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 fd7fb45818491b7fc6c206bb7f1958cc9aa38183..ab0a250f95fa14ea0107e7fcde58c0d3c33f8612 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 3f52fadee3edb15c1628099b06fd8786940219ef..5135733216252e2e05767515d1f0893c9715047d 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 4e4bb38758680728cd2178610fef2724f5b6f662..062ac333fde60be0732572f39e0a7a46335da499 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 9eb815941df56a6b207d6211c3d09ae272224dd9..f7f0bf5d037b67db6476bdfb06daef60d52e4ad1 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 4e3cd2f8debb544d4d90cfdedd2e045db6d7cdc6..17a46e76123f92a510b39d2ebaa29eeecf8e97ab 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 0e9aec8f69170c0dcbd46ef51dee46beff283ce6..4348b6fd44fac08e06666af2f581889d418ada7a 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 7152eb11b7b9391ce4d74b9b9b9775115d856a33..2c38a65ade8753df06caf24639f204e5eb90c2fc 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 c4902411d749b1469e556b9d667c766ea2ecbe20..5ec31598ee4775708094fabcd3e1775325e65dfa 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 217c143686d223233eff7fb39dad96181a10d101..d61ca2a732f0ef341ccaf036ce0dcb6efb468013 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 82aaa792cbf3a1472b50b623580e14e7eda5ecc6..5fce363d810a33ca2a8b26070734058777d5098b 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 80e26ff30ebf5d3c306cb30892e7c51ff5755877..74e192107f9ae6a204ef538d322a6975daba5962 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 398fc223cab967409f4d620d5e47f4c92d31a420..3e26b1f9ac75f0811e9b6e4662b4b77c94a77c25 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 581c65976bb49ae21cb9433416bb46d07096599d..307611ae831d5286436f13aa89ae0afe634534c5 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 423a1a2a702e77e6034f9ca31b8a80177d33e110..b806d9b4defb0426bde077c07376db82adde8b36 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 69444247c20bd30563552c69528b9047d4f5a697..6dfc26d85e4747bb645d577da44d8840a998405d 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 9755b49bbefb209d26ec17066ae7eebcee7fdd00..3fb2355af37e5bebcbbd7e6fa706ee120056bf8b 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 8615961c128761abfdcfba4df8964ce59ea04cd7..d63e09b29a961b8cfc809a23b04821b8d56e7a8f 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 57dc262611166de138727c63708834150f3dfad9..0fa14afce23d47bb95fff404ca198339d3a4b891 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 39b8cf3dafcdb9c20d1ed5bedddcfde684d65f3a..fcfa01f7ceb6983f649d14cf125d8e64d7319c86 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 a57f05726b5785a6d8ba7646fb3068c438869082..91d25888a1b98b136b6ec3704a58630d5f9b085c 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 3886b30ed37355394e6155f60bb7e559e598391e..3e41b00c6806c6b88020a0a441aee979d5c21637 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 439690be519feba0975c7eccf162016d2040472c..685a4e22c768e4bbe4c7e4f64348dd548b397507 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 6dda2fe5b15bcd00f3d6cde0a30f6e321075154f..d363b31053da13e667dc9793026041353ef1c3bb 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 c3197ce0e2ad33be4e23358f4c3a25f74caffff8..34db195fb8b00880bbc6f42d9d1837bbce67c601 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 019da012669fe724ecb0bf37f31df7da10c7df2f..4de2760c593762634f0925cf9ccb1ab9c7f2c111 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 63e4b709efa956b100626e3fc56bd248f4a7828f..1d76ae855f077dd5d3dbb7230d392ecc7c0b3c68 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 2c1b8b687646eedb0ac795a706c34cc32fa5ab29..29b1e033a10b51c3e23bf01905a2887e3b73041e 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 2f4b48e6fb036648af5eb1cdf35bd217b97dc67f..e5cceb0775749661360e4aef376d8eb05c4615a7 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 60159f4ee532aa97e2fb76d5b75b0ad8040773b6..cb006458fc4b62400a7f68e1778982c011eb6c79 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 38794850f005a52ab7987c9a95f52d87adb9470d..215eb2536b1e97878f0e9c891a93762f8d349be2 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 f4ae3ba994a8f85284cd157e227c8daeaf671b0c..1c4583c7ff7cffeba6ee39e1b04eefe43f71130f 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 4fcdac63a3007aff3822e8dd17ccd5db57ce69a6..2b022571a8595a5dd41c89bdd515d0f1fd0dc70b 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 0c1209390169d1f81a0bacdfe452b8008ecbee2a..faec404672081d5f72d03da9f44abac0de3c27d1 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 17f1c6853182d23ddfb092c3d0e7787a04ce0731..c46275a92565a592b15b66ff4d19fd271eb32f5b 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 e5ac04739bcc5f998487c7e29845ce0a757727fa..eaf249452e51713f91fe7067a6fa804d7f6ea1d0 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 dd6c64ac406e8f28d87e69d81dff7b4d8171e19c..88e3ad2d1db8dea4d5e2fcdee52285e399644bcd 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 cd490abced9159347cf875b9ea9349192c899dd3..001735f7a6619b5f5419e3abbc7371c989f432cf 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 1eec3a06d1f350935332a440f379367145b837d0..4c016241f34072bdb5136bea4b4ffee3f833afeb 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 34591eeb837617308284c5e5765e4f1440d5a7fd..28fc5fb8057be2ff9029619142fa2221e7690506 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 85a5cebe96b3635fb521d648f937c7e938e7a6c2..965a6293206acc5bb52facb12d8acf50d3c3c6a2 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 8a361834dc25887e658107a3bf5dbf5f8142752d..14883026015dc50be00508f8eccf9cf805ea0ef4 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 d838c945575a73bf313a809edece47ee27ad16a2..2eba340230a73a63e8a1472a20ff0ed0a451d981 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 3a748a6bf772b25e83e8657024cddea8f40d8026..06e8b32d541c57280edbf06fdd03772a84fa55ff 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 34a7b89fd0069841463e8089da0b03eb96bfa5b4..64ff02d5b73056f81d03ff2e54b784e3943ba658 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 574bd1c81ebddfa3cb410d17178f48bfc0f00994..dd731043fecda7eae6f67b5bd6396a5300aadd86 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 d05df2810354737714bec9f1f897657036ddc150..3c9b616c834a39601247a29f99fe08979317bf25 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 1ffdb9856bb9fcc0592a939e98de7447e10266af..a2c819d3c96e3d367b4de11b852efea54a79e80d 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 532fb58f16bf9a417f869d7fe24149e6283d4ff6..4abf2ea6a88761dd0980cba05553737c769bf72d 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 4db7b68f058240ed0611fb0616d5c5ea91e79279..cdc9b719e9c7e285e85878677a64ff4b3d7d3501 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 79c4f268410d2223ee31986cfae0dda8c0442fb4..18a5d02a864410df6b6eba5f8f6a67650150cacc 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 d056263545b118b09854cc9e5702a682ebc23886..b0f2c56a8ea26c454f3d8cc71661821ec87f38de 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 248fb05feb639aef5ae8d099a3e651d129ea2d14..83d800c31e3cf4b6a8829df75ff3d627ee826542 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 72f33faca44fbef6734cdce724090c917ccf52b9..6cfd71d064637a0335677e7e2f7d73d941c50fe4 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 b96ad75b7e64c6474b02d4d91534659bc43eb252..14f7070b4ba280ee353b84ccda1faa841ecd1ead 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 c3c46c72046e37898ebbedb567b7eede3d67ae60..0c56d44b9fd5736f05498966b332fa97b30356ac 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 6f10eb285ece5136177345ba368493a3b66932a9..89fe3d1b9efbc1f34351e5752dd730db3c5bbab4 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 8e21b6db3981cc93cb5e4e00e30b820c9ff97af1..a5c2248304397ae3d738eba7435d7dfaeb555976 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 5d59155adf2a27a8f54b7cbe09210dedf22efb6e..6c7dc9d78e10e1de7f9b706077cd13fc060cd811 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 4dc1c104c942204882acadcf73e709683ebaafd6..167ea10b521a8267b95bff128011b53d5cbb32c2 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 496b62712fe8c9c42f15e59d86cfd94bc936e59b..3992e26a603987cf8bba458dd4f687af5c900a2f 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 1068f668ac4ec3434b1524624df98c5bf08e5074..64d3ce5ea1a0787c22891a984d2e030ac0671937 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 b581a24fa15c43739538ea8d4ae0b4a843feedce..16336480c631a6bd61d47d1137d57ba80ce7aca4 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 33cd169013781321a813e10ebfb474c9595bd857..c70e176771359b5e9371df1da486b29a157084f7 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 3eb348bfc4fb11112d24d0c169c580f5e70b04e7..d98c868c148b6cff5f05f555a20547c76ca19f91 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 1ab8689726ec994644b4342772007a26cbcbba01..906cc05bba638bf9eba0dc70d4f04c06bf540ea6 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 4c1eb9472ddb322793f382035b76d760862e0f3f..e49da27970227bda3885ba825e44f36ccf20df0e 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 0d6004e20658e27b519874ac01c2499572906175..cf7b12fee573174c8aaf00ee75aa9d21c056d61d 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 afbabf427f27dcb72b01e9be5a96dc0c8540176e..3fea5a15ffe8c6c64e6d86b9587f7cf776f4fedd 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 46623405a2ce29ea00ae80080a4c88edc0a9e37b..982a1c94498344af320b3ce18798f24215474a9a 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;