]> Pileus Git - ~andy/linux/commitdiff
Merge branches 'iommu/fixes', 'dma-debug', 'x86/amd', 'x86/vt-d', 'arm/tegra' and...
authorJoerg Roedel <joro@8bytes.org>
Sun, 16 Dec 2012 11:24:09 +0000 (12:24 +0100)
committerJoerg Roedel <joro@8bytes.org>
Sun, 16 Dec 2012 11:24:09 +0000 (12:24 +0100)
392 files changed:
CREDITS
Documentation/DMA-API-HOWTO.txt
Documentation/DMA-API.txt
Documentation/devicetree/bindings/net/mdio-gpio.txt
Documentation/networking/vxlan.txt
MAINTAINERS
Makefile
arch/alpha/kernel/osf_sys.c
arch/arm/Kconfig
arch/arm/boot/compressed/head.S
arch/arm/common/timer-sp.c
arch/arm/include/asm/dma-mapping.h
arch/arm/mach-davinci/dm644x.c
arch/arm/mach-dove/include/mach/pm.h
arch/arm/mach-dove/irq.c
arch/arm/mach-exynos/dma.c
arch/arm/mach-exynos/include/mach/map.h
arch/arm/mach-ixp4xx/common-pci.c
arch/arm/mach-ixp4xx/common.c
arch/arm/mach-ixp4xx/goramo_mlr.c
arch/arm/mach-ixp4xx/include/mach/debug-macro.S
arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h
arch/arm/mach-ixp4xx/include/mach/qmgr.h
arch/arm/mach-ixp4xx/ixp4xx_npe.c
arch/arm/mach-ixp4xx/ixp4xx_qmgr.c
arch/arm/mach-kirkwood/pcie.c
arch/arm/mach-omap2/Makefile
arch/arm/mach-omap2/board-igep0020.c
arch/arm/mach-omap2/clock44xx_data.c
arch/arm/mach-omap2/common-board-devices.c
arch/arm/mach-omap2/devices.c
arch/arm/mach-omap2/omap-iommu.c
arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
arch/arm/mach-omap2/omap_hwmod_44xx_data.c
arch/arm/mach-omap2/twl-common.c
arch/arm/mm/proc-v6.S
arch/arm/plat-omap/i2c.c
arch/arm/plat-omap/include/plat/iommu2.h [deleted file]
arch/arm/plat-omap/include/plat/iovmm.h [deleted file]
arch/arm/plat-s3c24xx/dma.c
arch/arm64/include/asm/dma-mapping.h
arch/arm64/include/asm/unistd32.h
arch/c6x/include/asm/dma-mapping.h
arch/c6x/include/asm/setup.h [new file with mode: 0644]
arch/c6x/include/uapi/asm/Kbuild
arch/c6x/include/uapi/asm/kvm_para.h [deleted file]
arch/c6x/include/uapi/asm/setup.h
arch/c6x/kernel/entry.S
arch/ia64/include/asm/dma-mapping.h
arch/m68k/include/asm/signal.h
arch/microblaze/include/asm/dma-mapping.h
arch/microblaze/kernel/signal.c
arch/mips/include/asm/dma-mapping.h
arch/mips/include/asm/hugetlb.h
arch/mips/kernel/cpu-probe.c
arch/mips/kernel/entry.S
arch/mips/kernel/scall64-n32.S
arch/mips/kernel/setup.c
arch/mips/lib/mips-atomic.c
arch/mips/mm/tlb-r4k.c
arch/openrisc/kernel/signal.c
arch/parisc/kernel/signal32.c
arch/parisc/kernel/sys_parisc.c
arch/parisc/kernel/syscall_table.S
arch/powerpc/boot/dts/mpc5200b.dtsi
arch/powerpc/boot/dts/o2d.dtsi
arch/powerpc/boot/dts/pcm030.dts
arch/powerpc/include/asm/dma-mapping.h
arch/powerpc/platforms/52xx/mpc52xx_pic.c
arch/powerpc/platforms/pseries/eeh_pe.c
arch/powerpc/platforms/pseries/msi.c
arch/s390/kernel/compat_wrapper.S
arch/score/kernel/signal.c
arch/sh/include/asm/dma-mapping.h
arch/sh/kernel/signal_64.c
arch/sparc/boot/piggyback.c
arch/sparc/include/asm/dma-mapping.h
arch/sparc/include/asm/prom.h
arch/sparc/kernel/signal_64.c
arch/sparc/kernel/sys32.S
arch/sparc/kernel/syscalls.S
arch/sparc/kernel/systbls_64.S
arch/tile/include/asm/dma-mapping.h
arch/um/kernel/exec.c
arch/x86/boot/compressed/eboot.c
arch/x86/boot/header.S
arch/x86/include/asm/Kbuild
arch/x86/include/asm/dma-mapping.h
arch/x86/include/asm/fpu-internal.h
arch/x86/include/asm/ptrace.h
arch/x86/kernel/cpu/amd.c
arch/x86/kernel/cpu/mcheck/mce_amd.c
arch/x86/kernel/cpu/mcheck/mce_intel.c
arch/x86/kernel/entry_64.S
arch/x86/kernel/head_32.S
arch/x86/kernel/microcode_amd.c
arch/x86/kernel/ptrace.c
arch/x86/kernel/smpboot.c
arch/x86/kvm/emulate.c
arch/x86/mm/tlb.c
arch/x86/pci/ce4100.c
arch/x86/platform/ce4100/ce4100.c
block/blk-exec.c
drivers/ata/ahci_platform.c
drivers/ata/libata-acpi.c
drivers/ata/libata-core.c
drivers/ata/libata-scsi.c
drivers/ata/pata_arasan_cf.c
drivers/ata/sata_highbank.c
drivers/ata/sata_svw.c
drivers/atm/ambassador.c
drivers/base/power/qos.c
drivers/block/aoe/aoecmd.c
drivers/block/floppy.c
drivers/block/mtip32xx/mtip32xx.c
drivers/block/mtip32xx/mtip32xx.h
drivers/char/hw_random/Kconfig
drivers/char/hw_random/ixp4xx-rng.c
drivers/char/raw.c
drivers/crypto/Kconfig
drivers/crypto/ixp4xx_crypto.c
drivers/edac/amd64_edac.h
drivers/edac/edac_mc.c
drivers/edac/edac_stub.c
drivers/edac/i7300_edac.c
drivers/edac/i7core_edac.c
drivers/edac/i82975x_edac.c
drivers/edac/mce_amd_inj.c
drivers/firewire/sbp2.c
drivers/gpio/Kconfig
drivers/gpio/gpio-mcp23s08.c
drivers/gpio/gpio-mvebu.c
drivers/gpu/drm/exynos/exynos_drm_encoder.c
drivers/gpu/drm/exynos/exynos_drm_fbdev.c
drivers/gpu/drm/exynos/exynos_drm_fimd.c
drivers/gpu/drm/exynos/exynos_drm_plane.c
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/intel_bios.c
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_pm.c
drivers/gpu/drm/i915/intel_sdvo.c
drivers/gpu/drm/nouveau/core/engine/disp/nv50.c
drivers/gpu/drm/nouveau/core/engine/graph/ctxnv40.c
drivers/gpu/drm/nouveau/core/engine/graph/nv40.c
drivers/gpu/drm/nouveau/core/engine/graph/nv40.h
drivers/gpu/drm/nouveau/core/include/core/object.h
drivers/gpu/drm/nouveau/core/include/subdev/clock.h
drivers/gpu/drm/nouveau/core/subdev/bios/dcb.c
drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c
drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c
drivers/gpu/drm/nouveau/nouveau_abi16.c
drivers/gpu/drm/nouveau/nouveau_drm.c
drivers/gpu/drm/radeon/atombios_crtc.c
drivers/gpu/drm/radeon/evergreen.c
drivers/gpu/drm/radeon/radeon_agp.c
drivers/i2c/busses/i2c-at91.c
drivers/i2c/busses/i2c-mxs.c
drivers/i2c/busses/i2c-omap.c
drivers/i2c/busses/i2c-s3c2410.c
drivers/input/input-mt.c
drivers/input/matrix-keymap.c
drivers/input/mousedev.c
drivers/input/touchscreen/ads7846.c
drivers/iommu/Makefile
drivers/iommu/amd_iommu.c
drivers/iommu/amd_iommu_types.h
drivers/iommu/intel-iommu.c
drivers/iommu/omap-iommu-debug.c
drivers/iommu/omap-iommu.c
drivers/iommu/omap-iommu.h [moved from arch/arm/plat-omap/include/plat/iommu.h with 70% similarity]
drivers/iommu/omap-iommu2.c [moved from arch/arm/mach-omap2/iommu2.c with 88% similarity]
drivers/iommu/omap-iopgtable.h [moved from arch/arm/plat-omap/include/plat/iopgtable.h with 85% similarity]
drivers/iommu/omap-iovmm.c
drivers/iommu/tegra-gart.c
drivers/iommu/tegra-smmu.c
drivers/md/dm.c
drivers/md/md.c
drivers/md/raid1.c
drivers/md/raid10.c
drivers/md/raid5.c
drivers/media/dvb-frontends/stv0900_core.c
drivers/media/i2c/adv7604.c
drivers/media/i2c/soc_camera/mt9v022.c
drivers/media/platform/exynos-gsc/gsc-core.c
drivers/media/platform/exynos-gsc/gsc-m2m.c
drivers/media/platform/exynos-gsc/gsc-regs.h
drivers/media/platform/omap3isp/isp.c
drivers/media/platform/omap3isp/isp.h
drivers/media/platform/omap3isp/ispccdc.c
drivers/media/platform/omap3isp/ispstat.c
drivers/media/platform/omap3isp/ispstat.h
drivers/media/platform/omap3isp/ispvideo.c
drivers/media/platform/s5p-fimc/Kconfig
drivers/media/platform/s5p-fimc/fimc-capture.c
drivers/media/platform/s5p-fimc/fimc-lite.c
drivers/media/platform/s5p-fimc/fimc-m2m.c
drivers/media/platform/s5p-fimc/fimc-mdevice.c
drivers/media/platform/s5p-mfc/s5p_mfc.c
drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c
drivers/media/platform/sh_vou.c
drivers/media/platform/soc_camera/mx1_camera.c
drivers/media/platform/soc_camera/mx2_camera.c
drivers/media/platform/soc_camera/mx3_camera.c
drivers/media/platform/soc_camera/omap1_camera.c
drivers/media/platform/soc_camera/pxa_camera.c
drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c
drivers/media/usb/dvb-usb-v2/dvb_usb_core.c
drivers/media/usb/dvb-usb-v2/dvb_usb_urb.c
drivers/media/usb/dvb-usb-v2/rtl28xxu.c
drivers/mfd/arizona-core.c
drivers/mfd/arizona-irq.c
drivers/mfd/twl-core.c
drivers/mfd/twl4030-irq.c
drivers/mfd/wm5102-tables.c
drivers/mmc/host/sdhci-s3c.c
drivers/mmc/host/sh_mmcif.c
drivers/mtd/devices/slram.c
drivers/mtd/mtdcore.c
drivers/mtd/nand/nand_base.c
drivers/mtd/ofpart.c
drivers/mtd/onenand/onenand_base.c
drivers/mtd/ubi/wl.c
drivers/net/bonding/bond_main.c
drivers/net/bonding/bond_sysfs.c
drivers/net/can/usb/peak_usb/pcan_usb.c
drivers/net/can/usb/peak_usb/pcan_usb_pro.c
drivers/net/ethernet/8390/ne.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c
drivers/net/ethernet/realtek/8139cp.c
drivers/net/ethernet/sis/sis900.c
drivers/net/ethernet/xilinx/xilinx_axienet_main.c
drivers/net/ethernet/xscale/ixp4xx_eth.c
drivers/net/irda/sir_dev.c
drivers/net/phy/mdio-gpio.c
drivers/net/team/team.c
drivers/net/team/team_mode_broadcast.c
drivers/net/usb/qmi_wwan.c
drivers/net/wan/ixp4xx_hss.c
drivers/net/wireless/ath/ath9k/hw.c
drivers/net/wireless/iwlwifi/dvm/mac80211.c
drivers/net/wireless/iwlwifi/dvm/rxon.c
drivers/net/wireless/iwlwifi/pcie/tx.c
drivers/net/wireless/mwifiex/cmdevt.c
drivers/net/wireless/mwifiex/sdio.c
drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
drivers/net/xen-netfront.c
drivers/nfc/pn533.c
drivers/pinctrl/Kconfig
drivers/remoteproc/remoteproc_virtio.c
drivers/rtc/rtc-tps65910.c
drivers/scsi/isci/request.c
drivers/scsi/megaraid/megaraid_sas.h
drivers/scsi/megaraid/megaraid_sas_base.c
drivers/scsi/scsi.c
drivers/scsi/scsi_lib.c
drivers/scsi/sd.c
drivers/scsi/sd.h
drivers/target/target_core_transport.c
drivers/tty/vt/vt.c
drivers/usb/storage/scsiglue.c
drivers/vhost/vhost.c
drivers/video/omap2/dss/dsi.c
drivers/video/omap2/dss/dss.c
drivers/video/omap2/dss/hdmi.c
drivers/video/omap2/omapfb/omapfb-ioctl.c
drivers/xen/privcmd.c
fs/block_dev.c
fs/buffer.c
fs/cifs/file.c
fs/cifs/readdir.c
fs/cifs/smb1ops.c
fs/direct-io.c
fs/ext3/balloc.c
fs/file.c
fs/fs-writeback.c
fs/inode.c
fs/internal.h
fs/jbd/transaction.c
fs/jffs2/file.c
fs/namei.c
fs/nfs/dir.c
fs/notify/fanotify/fanotify_user.c
fs/proc/base.c
fs/reiserfs/inode.c
fs/reiserfs/stree.c
fs/reiserfs/super.c
fs/xfs/xfs_aops.c
fs/xfs/xfs_attr_leaf.c
fs/xfs/xfs_buf.c
include/drm/drm_pciids.h
include/linux/bug.h
include/linux/dma-debug.h
include/linux/fs.h
include/linux/gfp.h
include/linux/hw_breakpoint.h
include/linux/i2c-omap.h
include/linux/kernel.h
include/linux/mempolicy.h
include/linux/netdevice.h
include/linux/of_address.h
include/linux/omap-iommu.h [new file with mode: 0644]
include/linux/percpu-rwsem.h
include/linux/platform_data/iommu-omap.h [new file with mode: 0644]
include/linux/spi/ads7846.h
include/media/adv7604.h
include/net/tcp.h
include/net/xfrm.h
include/scsi/scsi_device.h
include/trace/events/gfpflags.h
include/uapi/linux/Kbuild
include/uapi/linux/hw_breakpoint.h [new file with mode: 0644]
kernel/events/hw_breakpoint.c
kernel/futex.c
kernel/modsign_pubkey.c
kernel/module_signing.c
kernel/sched/auto_group.c
kernel/sched/auto_group.h
kernel/watchdog.c
kernel/workqueue.c
lib/Makefile
lib/asn1_decoder.c
lib/dma-debug.c
lib/mpi/longlong.h
mm/compaction.c
mm/memory-failure.c
mm/mempolicy.c
mm/page_alloc.c
mm/shmem.c
mm/sparse.c
mm/vmscan.c
net/can/bcm.c
net/core/dev.c
net/core/net-sysfs.c
net/core/skbuff.c
net/ipv4/icmp.c
net/ipv4/inet_diag.c
net/ipv4/ip_fragment.c
net/ipv4/ipmr.c
net/ipv4/route.c
net/ipv4/tcp.c
net/ipv4/tcp_input.c
net/ipv4/tcp_output.c
net/ipv4/xfrm4_policy.c
net/ipv6/inet6_connection_sock.c
net/irda/irttp.c
net/mac80211/ibss.c
net/mac80211/offchannel.c
net/netfilter/ipset/ip_set_hash_ip.c
net/netfilter/ipset/ip_set_hash_ipport.c
net/netfilter/ipset/ip_set_hash_ipportip.c
net/netfilter/ipset/ip_set_hash_ipportnet.c
net/netfilter/ipset/ip_set_hash_netiface.c
net/netfilter/nfnetlink_cttimeout.c
net/nfc/llcp/llcp.c
net/openvswitch/flow.c
net/openvswitch/vport-netdev.c
net/sctp/chunk.c
net/sctp/socket.c
net/sctp/transport.c
scripts/headers_install.pl
scripts/sign-file
security/selinux/netnode.c
sound/pci/hda/hda_codec.c
sound/pci/hda/hda_codec.h
sound/pci/hda/hda_intel.c
sound/pci/hda/patch_cirrus.c
sound/pci/hda/patch_realtek.c
sound/soc/codecs/arizona.c
sound/soc/codecs/cs4271.c
sound/soc/kirkwood/kirkwood-dma.c
sound/soc/kirkwood/kirkwood-i2s.c
sound/soc/samsung/bells.c
sound/usb/midi.c
sound/usb/pcm.c
tools/Makefile
tools/perf/Makefile
tools/perf/arch/x86/include/perf_regs.h
tools/perf/builtin-kvm.c
tools/perf/builtin-test.c
tools/perf/perf.h
tools/perf/util/evsel.c
tools/perf/util/evsel.h
tools/perf/util/header.c
tools/perf/util/header.h
tools/perf/util/parse-events-test.c
tools/perf/util/parse-events.c
tools/perf/util/parse-events.h
tools/perf/util/pmu.h
tools/perf/util/session.h
tools/perf/util/strbuf.c
tools/scripts/Makefile.include

diff --git a/CREDITS b/CREDITS
index d8fe12a9421fa2a7145e7218cc7d664232d0d7ce..2346b09ca8bb9cfc3c4371eb5ad6058be818d990 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -1823,6 +1823,11 @@ S: Kattreinstr 38
 S: D-64295
 S: Germany
 
+N: Avi Kivity
+E: avi.kivity@gmail.com
+D: Kernel-based Virtual Machine (KVM)
+S: Ra'annana, Israel
+
 N: Andi Kleen
 E: andi@firstfloor.org
 U: http://www.halobates.de
index a0b6250add79c9c144fd1185fa91314febaa4241..4a4fb295ceefb722e5bbbf46dbff37af0669d848 100644 (file)
@@ -468,11 +468,46 @@ To map a single region, you do:
        size_t size = buffer->len;
 
        dma_handle = dma_map_single(dev, addr, size, direction);
+       if (dma_mapping_error(dma_handle)) {
+               /*
+                * reduce current DMA mapping usage,
+                * delay and try again later or
+                * reset driver.
+                */
+               goto map_error_handling;
+       }
 
 and to unmap it:
 
        dma_unmap_single(dev, dma_handle, size, direction);
 
+You should call dma_mapping_error() as dma_map_single() could fail and return
+error. Not all dma implementations support dma_mapping_error() interface.
+However, it is a good practice to call dma_mapping_error() interface, which
+will invoke the generic mapping error check interface. Doing so will ensure
+that the mapping code will work correctly on all dma implementations without
+any dependency on the specifics of the underlying implementation. Using the
+returned address without checking for errors could result in failures ranging
+from panics to silent data corruption. Couple of example of incorrect ways to
+check for errors that make assumptions about the underlying dma implementation
+are as follows and these are applicable to dma_map_page() as well.
+
+Incorrect example 1:
+       dma_addr_t dma_handle;
+
+       dma_handle = dma_map_single(dev, addr, size, direction);
+       if ((dma_handle & 0xffff != 0) || (dma_handle >= 0x1000000)) {
+               goto map_error;
+       }
+
+Incorrect example 2:
+       dma_addr_t dma_handle;
+
+       dma_handle = dma_map_single(dev, addr, size, direction);
+       if (dma_handle == DMA_ERROR_CODE) {
+               goto map_error;
+       }
+
 You should call dma_unmap_single when the DMA activity is finished, e.g.
 from the interrupt which told you that the DMA transfer is done.
 
@@ -489,6 +524,14 @@ Specifically:
        size_t size = buffer->len;
 
        dma_handle = dma_map_page(dev, page, offset, size, direction);
+       if (dma_mapping_error(dma_handle)) {
+               /*
+                * reduce current DMA mapping usage,
+                * delay and try again later or
+                * reset driver.
+                */
+               goto map_error_handling;
+       }
 
        ...
 
@@ -496,6 +539,12 @@ Specifically:
 
 Here, "offset" means byte offset within the given page.
 
+You should call dma_mapping_error() as dma_map_page() could fail and return
+error as outlined under the dma_map_single() discussion.
+
+You should call dma_unmap_page when the DMA activity is finished, e.g.
+from the interrupt which told you that the DMA transfer is done.
+
 With scatterlists, you map a region gathered from several regions by:
 
        int i, count = dma_map_sg(dev, sglist, nents, direction);
@@ -578,6 +627,14 @@ to use the dma_sync_*() interfaces.
                dma_addr_t mapping;
 
                mapping = dma_map_single(cp->dev, buffer, len, DMA_FROM_DEVICE);
+               if (dma_mapping_error(dma_handle)) {
+                       /*
+                        * reduce current DMA mapping usage,
+                        * delay and try again later or
+                        * reset driver.
+                        */
+                       goto map_error_handling;
+               }
 
                cp->rx_buf = buffer;
                cp->rx_len = len;
@@ -658,6 +715,75 @@ failure can be determined by:
                 * delay and try again later or
                 * reset driver.
                 */
+               goto map_error_handling;
+       }
+
+- unmap pages that are already mapped, when mapping error occurs in the middle
+  of a multiple page mapping attempt. These example are applicable to
+  dma_map_page() as well.
+
+Example 1:
+       dma_addr_t dma_handle1;
+       dma_addr_t dma_handle2;
+
+       dma_handle1 = dma_map_single(dev, addr, size, direction);
+       if (dma_mapping_error(dev, dma_handle1)) {
+               /*
+                * reduce current DMA mapping usage,
+                * delay and try again later or
+                * reset driver.
+                */
+               goto map_error_handling1;
+       }
+       dma_handle2 = dma_map_single(dev, addr, size, direction);
+       if (dma_mapping_error(dev, dma_handle2)) {
+               /*
+                * reduce current DMA mapping usage,
+                * delay and try again later or
+                * reset driver.
+                */
+               goto map_error_handling2;
+       }
+
+       ...
+
+       map_error_handling2:
+               dma_unmap_single(dma_handle1);
+       map_error_handling1:
+
+Example 2: (if buffers are allocated a loop, unmap all mapped buffers when
+           mapping error is detected in the middle)
+
+       dma_addr_t dma_addr;
+       dma_addr_t array[DMA_BUFFERS];
+       int save_index = 0;
+
+       for (i = 0; i < DMA_BUFFERS; i++) {
+
+               ...
+
+               dma_addr = dma_map_single(dev, addr, size, direction);
+               if (dma_mapping_error(dev, dma_addr)) {
+                       /*
+                        * reduce current DMA mapping usage,
+                        * delay and try again later or
+                        * reset driver.
+                        */
+                       goto map_error_handling;
+               }
+               array[i].dma_addr = dma_addr;
+               save_index++;
+       }
+
+       ...
+
+       map_error_handling:
+
+       for (i = 0; i < save_index; i++) {
+
+               ...
+
+               dma_unmap_single(array[i].dma_addr);
        }
 
 Networking drivers must call dev_kfree_skb to free the socket buffer
index 66bd97a95f10e18fc9b2a4bff7acb691957cc6a3..78a6c569d204bc0073e33fe093d34a8137e5eaf4 100644 (file)
@@ -678,3 +678,15 @@ out of dma_debug_entries. These entries are preallocated at boot. The number
 of preallocated entries is defined per architecture. If it is too low for you
 boot with 'dma_debug_entries=<your_desired_number>' to overwrite the
 architectural default.
+
+void debug_dmap_mapping_error(struct device *dev, dma_addr_t dma_addr);
+
+dma-debug interface debug_dma_mapping_error() to debug drivers that fail
+to check dma mapping errors on addresses returned by dma_map_single() and
+dma_map_page() interfaces. This interface clears a flag set by
+debug_dma_map_page() to indicate that dma_mapping_error() has been called by
+the driver. When driver does unmap, debug_dma_unmap() checks the flag and if
+this flag is still set, prints warning message that includes call trace that
+leads up to the unmap. This interface can be called from dma_mapping_error()
+routines to enable dma mapping error check debugging.
+
index bc9549529014730bc6abd0cefba2d82824370e5e..c79bab025369af4bb6320ba0e90f7fb386942cc1 100644 (file)
@@ -8,9 +8,16 @@ gpios property as described in section VIII.1 in the following order:
 
 MDC, MDIO.
 
+Note: Each gpio-mdio bus should have an alias correctly numbered in "aliases"
+node.
+
 Example:
 
-mdio {
+aliases {
+       mdio-gpio0 = <&mdio0>;
+};
+
+mdio0: mdio {
        compatible = "virtual,mdio-gpio";
        #address-cells = <1>;
        #size-cells = <0>;
index 5b34b762d7d5139a8cf0a9a8eacf739cae279a5b..6d993510f091c2088877ccfc1edf15474c5c723f 100644 (file)
@@ -32,7 +32,7 @@ no entry is in the forwarding table.
   # ip link delete vxlan0
 
 3. Show vxlan info
-  # ip -d show vxlan0
+  # ip -d link show vxlan0
 
 It is possible to create, destroy and display the vxlan
 forwarding table using the new bridge command.
@@ -41,7 +41,7 @@ forwarding table using the new bridge command.
   # bridge fdb add to 00:17:42:8a:b4:05 dst 192.19.0.2 dev vxlan0
 
 2. Delete forwarding table entry
-  # bridge fdb delete 00:17:42:8a:b4:05
+  # bridge fdb delete 00:17:42:8a:b4:05 dev vxlan0
 
 3. Show forwarding table
   # bridge fdb show dev vxlan0
index bb0b27db673f3c5d0f2cbf4215dc3efbe2c17bd3..9386a63ea8f63b653b683379ea54c7bd91eb72ec 100644 (file)
@@ -526,17 +526,17 @@ F:        drivers/video/geode/
 F:     arch/x86/include/asm/geode.h
 
 AMD IOMMU (AMD-VI)
-M:     Joerg Roedel <joerg.roedel@amd.com>
+M:     Joerg Roedel <joro@8bytes.org>
 L:     iommu@lists.linux-foundation.org
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git
-S:     Supported
+S:     Maintained
 F:     drivers/iommu/amd_iommu*.[ch]
 F:     include/linux/amd-iommu.h
 
 AMD MICROCODE UPDATE SUPPORT
-M:     Andreas Herrmann <andreas.herrmann3@amd.com>
+M:     Andreas Herrmann <herrmann.der.user@googlemail.com>
 L:     amd64-microcode@amd64.org
-S:     Supported
+S:     Maintained
 F:     arch/x86/kernel/microcode_amd.c
 
 AMS (Apple Motion Sensor) DRIVER
@@ -841,6 +841,14 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/kristoffer/linux-hpc.git
 F:     arch/arm/mach-sa1100/jornada720.c
 F:     arch/arm/mach-sa1100/include/mach/jornada720.h
 
+ARM/IGEP MACHINE SUPPORT
+M:     Enric Balletbo i Serra <eballetbo@gmail.com>
+M:     Javier Martinez Canillas <javier@dowhile0.org>
+L:     linux-omap@vger.kernel.org
+L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+S:     Maintained
+F:     arch/arm/mach-omap2/board-igep0020.c
+
 ARM/INCOME PXA270 SUPPORT
 M:     Marek Vasut <marek.vasut@gmail.com>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@ -2708,10 +2716,10 @@ F:      include/linux/edac.h
 
 EDAC-AMD64
 M:     Doug Thompson <dougthompson@xmission.com>
-M:     Borislav Petkov <borislav.petkov@amd.com>
+M:     Borislav Petkov <bp@alien8.de>
 L:     linux-edac@vger.kernel.org
 W:     bluesmoke.sourceforge.net
-S:     Supported
+S:     Maintained
 F:     drivers/edac/amd64_edac*
 
 EDAC-E752X
@@ -3753,7 +3761,7 @@ S:        Maintained
 F:     drivers/platform/x86/ideapad-laptop.c
 
 IDE/ATAPI DRIVERS
-M:     Borislav Petkov <petkovbb@gmail.com>
+M:     Borislav Petkov <bp@alien8.de>
 L:     linux-ide@vger.kernel.org
 S:     Maintained
 F:     Documentation/cdrom/ide-cd
@@ -4280,8 +4288,8 @@ F:        include/linux/lockd/
 F:     include/linux/sunrpc/
 
 KERNEL VIRTUAL MACHINE (KVM)
-M:     Avi Kivity <avi@redhat.com>
 M:     Marcelo Tosatti <mtosatti@redhat.com>
+M:     Gleb Natapov <gleb@redhat.com>
 L:     kvm@vger.kernel.org
 W:     http://kvm.qumranet.com
 S:     Supported
@@ -5413,7 +5421,7 @@ S:        Maintained
 F:     sound/drivers/opl4/
 
 OPROFILE
-M:     Robert Richter <robert.richter@amd.com>
+M:     Robert Richter <rric@kernel.org>
 L:     oprofile-list@lists.sf.net
 S:     Maintained
 F:     arch/*/include/asm/oprofile*.h
@@ -8198,7 +8206,7 @@ F:        drivers/platform/x86
 
 X86 MCE INFRASTRUCTURE
 M:     Tony Luck <tony.luck@intel.com>
-M:     Borislav Petkov <bp@amd64.org>
+M:     Borislav Petkov <bp@alien8.de>
 L:     linux-edac@vger.kernel.org
 S:     Maintained
 F:     arch/x86/kernel/cpu/mcheck/*
index 9f6ca124e89078d7830e5a10c4ff918dbefafbf0..540f7b240c77d7332f7c51746de660a709e6c431 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 3
 PATCHLEVEL = 7
 SUBLEVEL = 0
-EXTRAVERSION = -rc6
+EXTRAVERSION =
 NAME = Terrified Chipmunk
 
 # *DOCUMENTATION*
@@ -1321,10 +1321,12 @@ kernelversion:
 
 # Clear a bunch of variables before executing the submake
 tools/: FORCE
-       $(Q)$(MAKE) LDFLAGS= MAKEFLAGS= -C $(src)/tools/
+       $(Q)mkdir -p $(objtree)/tools
+       $(Q)$(MAKE) LDFLAGS= MAKEFLAGS= O=$(objtree) subdir=tools -C $(src)/tools/
 
 tools/%: FORCE
-       $(Q)$(MAKE) LDFLAGS= MAKEFLAGS= -C $(src)/tools/ $*
+       $(Q)mkdir -p $(objtree)/tools
+       $(Q)$(MAKE) LDFLAGS= MAKEFLAGS= O=$(objtree) subdir=tools -C $(src)/tools/ $*
 
 # Single targets
 # ---------------------------------------------------------------------------
index 1e6956a9060809e5b1cfed409d376f2d1e726f43..14db93e4c8a83662d459a6ff1a818318dbc61eeb 100644 (file)
@@ -445,7 +445,7 @@ struct procfs_args {
  * unhappy with OSF UFS. [CHECKME]
  */
 static int
-osf_ufs_mount(char *dirname, struct ufs_args __user *args, int flags)
+osf_ufs_mount(const char *dirname, struct ufs_args __user *args, int flags)
 {
        int retval;
        struct cdfs_args tmp;
@@ -465,7 +465,7 @@ osf_ufs_mount(char *dirname, struct ufs_args __user *args, int flags)
 }
 
 static int
-osf_cdfs_mount(char *dirname, struct cdfs_args __user *args, int flags)
+osf_cdfs_mount(const char *dirname, struct cdfs_args __user *args, int flags)
 {
        int retval;
        struct cdfs_args tmp;
@@ -485,7 +485,7 @@ osf_cdfs_mount(char *dirname, struct cdfs_args __user *args, int flags)
 }
 
 static int
-osf_procfs_mount(char *dirname, struct procfs_args __user *args, int flags)
+osf_procfs_mount(const char *dirname, struct procfs_args __user *args, int flags)
 {
        struct procfs_args tmp;
 
index ade7e924bef5faaf00de76c0354e025ed4371b35..9759fec0b704559454ce8e054eaaa5b6d7c25335 100644 (file)
@@ -547,6 +547,7 @@ config ARCH_KIRKWOOD
        select CPU_FEROCEON
        select GENERIC_CLOCKEVENTS
        select PCI
+       select PCI_QUIRKS
        select PLAT_ORION_LEGACY
        help
          Support for the following Marvell Kirkwood series SoCs:
index 90275f036cd14517affdb724ea4c6adf5194b72c..49ca86e37b8d3c0cbe2b0e84a5ab3abeacee6926 100644 (file)
@@ -652,6 +652,15 @@ __setup_mmu:       sub     r3, r4, #16384          @ Page directory size
                mov     pc, lr
 ENDPROC(__setup_mmu)
 
+@ Enable unaligned access on v6, to allow better code generation
+@ for the decompressor C code:
+__armv6_mmu_cache_on:
+               mrc     p15, 0, r0, c1, c0, 0   @ read SCTLR
+               bic     r0, r0, #2              @ A (no unaligned access fault)
+               orr     r0, r0, #1 << 22        @ U (v6 unaligned access model)
+               mcr     p15, 0, r0, c1, c0, 0   @ write SCTLR
+               b       __armv4_mmu_cache_on
+
 __arm926ejs_mmu_cache_on:
 #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
                mov     r0, #4                  @ put dcache in WT mode
@@ -694,6 +703,9 @@ __armv7_mmu_cache_on:
                bic     r0, r0, #1 << 28        @ clear SCTLR.TRE
                orr     r0, r0, #0x5000         @ I-cache enable, RR cache replacement
                orr     r0, r0, #0x003c         @ write buffer
+               bic     r0, r0, #2              @ A (no unaligned access fault)
+               orr     r0, r0, #1 << 22        @ U (v6 unaligned access model)
+                                               @ (needed for ARM1176)
 #ifdef CONFIG_MMU
 #ifdef CONFIG_CPU_ENDIAN_BE8
                orr     r0, r0, #1 << 25        @ big-endian page tables
@@ -914,7 +926,7 @@ proc_types:
 
                .word   0x0007b000              @ ARMv6
                .word   0x000ff000
-               W(b)    __armv4_mmu_cache_on
+               W(b)    __armv6_mmu_cache_on
                W(b)    __armv4_mmu_cache_off
                W(b)    __armv6_mmu_cache_flush
 
index df13a3ffff3514b703584483d1b43a9cb12d3953..9d2d3ba339ff9e79593b233245804f36f6e2e7a2 100644 (file)
@@ -162,7 +162,6 @@ static struct clock_event_device sp804_clockevent = {
        .set_mode       = sp804_set_mode,
        .set_next_event = sp804_set_next_event,
        .rating         = 300,
-       .cpumask        = cpu_all_mask,
 };
 
 static struct irqaction sp804_timer_irq = {
@@ -185,6 +184,7 @@ void __init sp804_clockevents_init(void __iomem *base, unsigned int irq,
        clkevt_reload = DIV_ROUND_CLOSEST(rate, HZ);
        evt->name = name;
        evt->irq = irq;
+       evt->cpumask = cpu_possible_mask;
 
        setup_irq(irq, &sp804_timer_irq);
        clockevents_config_and_register(evt, rate, 0xf, 0xffffffff);
index 23004847bb057becd348b5d1e870235b633acedd..78d8e9b5544f59bb04dcc2068a40ea433ae81553 100644 (file)
@@ -91,6 +91,7 @@ static inline dma_addr_t virt_to_dma(struct device *dev, void *addr)
  */
 static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
 {
+       debug_dma_mapping_error(dev, dma_addr);
        return dma_addr == DMA_ERROR_CODE;
 }
 
index cd0c8b1e1ecfad4a868b9aae3f6180a1b1794ed1..14e9947bad6e028bc9c41aecb5e1f36b045fe79a 100644 (file)
@@ -713,8 +713,7 @@ static int dm644x_venc_setup_clock(enum vpbe_enc_timings_type type,
                break;
        case VPBE_ENC_CUSTOM_TIMINGS:
                if (pclock <= 27000000) {
-                       v |= DM644X_VPSS_MUXSEL_PLL2_MODE |
-                            DM644X_VPSS_DACCLKEN;
+                       v |= DM644X_VPSS_DACCLKEN;
                        writel(v, DAVINCI_SYSMOD_VIRT(SYSMOD_VPSS_CLKCTL));
                } else {
                        /*
index 7bcd0dfce4b1ce51b8b0e1bfc96ebcf9a0167d12..b47f750386863a820119eb0d66e0a7da84fc5c99 100644 (file)
@@ -63,7 +63,7 @@ static inline int pmu_to_irq(int pin)
 
 static inline int irq_to_pmu(int irq)
 {
-       if (IRQ_DOVE_PMU_START < irq && irq < NR_IRQS)
+       if (IRQ_DOVE_PMU_START <= irq && irq < NR_IRQS)
                return irq - IRQ_DOVE_PMU_START;
 
        return -EINVAL;
index 087711524e8a29d1e0d2de7c919bd705976ddbd7..bc4344aa10092dc8568ed8fe3890073e22147b53 100644 (file)
@@ -46,8 +46,20 @@ static void pmu_irq_ack(struct irq_data *d)
        int pin = irq_to_pmu(d->irq);
        u32 u;
 
+       /*
+        * The PMU mask register is not RW0C: it is RW.  This means that
+        * the bits take whatever value is written to them; if you write
+        * a '1', you will set the interrupt.
+        *
+        * Unfortunately this means there is NO race free way to clear
+        * these interrupts.
+        *
+        * So, let's structure the code so that the window is as small as
+        * possible.
+        */
        u = ~(1 << (pin & 31));
-       writel(u, PMU_INTERRUPT_CAUSE);
+       u &= readl_relaxed(PMU_INTERRUPT_CAUSE);
+       writel_relaxed(u, PMU_INTERRUPT_CAUSE);
 }
 
 static struct irq_chip pmu_irq_chip = {
index 21d568b3b1497c90bb79eb841f45595020351db9..87e07d6fc615769df8edfe0af8be1569859d5422 100644 (file)
@@ -275,6 +275,9 @@ static int __init exynos_dma_init(void)
                exynos_pdma1_pdata.nr_valid_peri =
                        ARRAY_SIZE(exynos4210_pdma1_peri);
                exynos_pdma1_pdata.peri_id = exynos4210_pdma1_peri;
+
+               if (samsung_rev() == EXYNOS4210_REV_0)
+                       exynos_mdma1_device.res.start = EXYNOS4_PA_S_MDMA1;
        } else if (soc_is_exynos4212() || soc_is_exynos4412()) {
                exynos_pdma0_pdata.nr_valid_peri =
                        ARRAY_SIZE(exynos4212_pdma0_peri);
index 8480849affb922789d73b597c81b76c6778a16ba..ed4da4544cd2fded70c65dd7d5d5539635a94557 100644 (file)
@@ -90,6 +90,7 @@
 
 #define EXYNOS4_PA_MDMA0               0x10810000
 #define EXYNOS4_PA_MDMA1               0x12850000
+#define EXYNOS4_PA_S_MDMA1             0x12840000
 #define EXYNOS4_PA_PDMA0               0x12680000
 #define EXYNOS4_PA_PDMA1               0x12690000
 #define EXYNOS5_PA_MDMA0               0x10800000
index 1694f01ce2b6782deeb09c02b0ba1a5b4ade0918..6d6bde3e15fad4e4cf094a22c6ae6b8837a1580f 100644 (file)
@@ -410,6 +410,7 @@ void __init ixp4xx_pci_preinit(void)
                 * Enable the IO window to be way up high, at 0xfffffc00
                 */
                local_write_config(PCI_BASE_ADDRESS_5, 4, 0xfffffc01);
+               local_write_config(0x40, 4, 0x000080FF); /* No TRDY time limit */
        } else {
                printk("PCI: IXP4xx is target - No bus scan performed\n");
        }
index fdf91a160884407816d2ceb4fa577e1a9de97054..8c0c0e2d0727317078a93f2241763818acf1ac15 100644 (file)
@@ -67,15 +67,12 @@ static struct map_desc ixp4xx_io_desc[] __initdata = {
                .pfn            = __phys_to_pfn(IXP4XX_PCI_CFG_BASE_PHYS),
                .length         = IXP4XX_PCI_CFG_REGION_SIZE,
                .type           = MT_DEVICE
-       },
-#ifdef CONFIG_DEBUG_LL
-       {       /* Debug UART mapping */
-               .virtual        = (unsigned long)IXP4XX_DEBUG_UART_BASE_VIRT,
-               .pfn            = __phys_to_pfn(IXP4XX_DEBUG_UART_BASE_PHYS),
-               .length         = IXP4XX_DEBUG_UART_REGION_SIZE,
+       }, {    /* Queue Manager */
+               .virtual        = (unsigned long)IXP4XX_QMGR_BASE_VIRT,
+               .pfn            = __phys_to_pfn(IXP4XX_QMGR_BASE_PHYS),
+               .length         = IXP4XX_QMGR_REGION_SIZE,
                .type           = MT_DEVICE
-       }
-#endif
+       },
 };
 
 void __init ixp4xx_map_io(void)
index b800a031207c9db0eaaff139fb367b68374420f8..53b8348dfcc279c19fed814ac4f1d19afdafe5b6 100644 (file)
@@ -15,6 +15,7 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/flash.h>
 #include <asm/mach/pci.h>
+#include <asm/system_info.h>
 
 #define SLOT_ETHA              0x0B    /* IDSEL = AD21 */
 #define SLOT_ETHB              0x0C    /* IDSEL = AD20 */
@@ -329,7 +330,7 @@ static struct platform_device device_hss_tab[] = {
 };
 
 
-static struct platform_device *device_tab[6] __initdata = {
+static struct platform_device *device_tab[7] __initdata = {
        &device_flash,          /* index 0 */
 };
 
index 8c9f8d56449231c26f6c24ff74df7268063f6c77..ff686cbc5df44d54547b4816588fe808a5bdd424 100644 (file)
@@ -17,8 +17,8 @@
 #else
                mov     \rp, #0
 #endif
-                orr     \rv, \rp, #0xff000000  @ virtual
-               orr     \rv, \rv, #0x00b00000
+               orr     \rv, \rp, #0xfe000000   @ virtual
+               orr     \rv, \rv, #0x00f00000
                 orr     \rp, \rp, #0xc8000000  @ physical
                 .endm
 
index eb68b61ce975cdff4e96e0a411edec96832b8b2f..c5bae9c035d533e1bd1bba3246bf766e8a53c447 100644 (file)
  *
  * 0x50000000  0x10000000      ioremap'd       EXP BUS
  *
- * 0x6000000   0x00004000      ioremap'd       QMgr
+ * 0xC8000000  0x00013000      0xFEF00000      On-Chip Peripherals
  *
- * 0xC0000000  0x00001000      0xffbff000      PCI CFG
+ * 0xC0000000  0x00001000      0xFEF13000      PCI CFG
  *
- * 0xC4000000  0x00001000      0xffbfe000      EXP CFG
+ * 0xC4000000  0x00001000      0xFEF14000      EXP CFG
  *
- * 0xC8000000  0x00013000      0xffbeb000      On-Chip Peripherals
+ * 0x60000000  0x00004000      0xFEF15000      QMgr
  */
 
 /*
  * Queue Manager
  */
-#define IXP4XX_QMGR_BASE_PHYS          (0x60000000)
-#define IXP4XX_QMGR_REGION_SIZE                (0x00004000)
+#define IXP4XX_QMGR_BASE_PHYS          0x60000000
+#define IXP4XX_QMGR_BASE_VIRT          IOMEM(0xFEF15000)
+#define IXP4XX_QMGR_REGION_SIZE                0x00004000
 
 /*
- * Expansion BUS Configuration registers
+ * Peripheral space, including debug UART. Must be section-aligned so that
+ * it can be used with the low-level debug code.
  */
-#define IXP4XX_EXP_CFG_BASE_PHYS       (0xC4000000)
-#define IXP4XX_EXP_CFG_BASE_VIRT       IOMEM(0xFFBFE000)
-#define IXP4XX_EXP_CFG_REGION_SIZE     (0x00001000)
+#define IXP4XX_PERIPHERAL_BASE_PHYS    0xC8000000
+#define IXP4XX_PERIPHERAL_BASE_VIRT    IOMEM(0xFEF00000)
+#define IXP4XX_PERIPHERAL_REGION_SIZE  0x00013000
 
 /*
  * PCI Config registers
  */
-#define IXP4XX_PCI_CFG_BASE_PHYS       (0xC0000000)
-#define        IXP4XX_PCI_CFG_BASE_VIRT        IOMEM(0xFFBFF000)
-#define IXP4XX_PCI_CFG_REGION_SIZE     (0x00001000)
-
-/*
- * Peripheral space
- */
-#define IXP4XX_PERIPHERAL_BASE_PHYS    (0xC8000000)
-#define IXP4XX_PERIPHERAL_BASE_VIRT    IOMEM(0xFFBEB000)
-#define IXP4XX_PERIPHERAL_REGION_SIZE  (0x00013000)
+#define IXP4XX_PCI_CFG_BASE_PHYS       0xC0000000
+#define IXP4XX_PCI_CFG_BASE_VIRT       IOMEM(0xFEF13000)
+#define IXP4XX_PCI_CFG_REGION_SIZE     0x00001000
 
 /*
- * Debug UART
- *
- * This is basically a remap of UART1 into a region that is section
- * aligned so that it * can be used with the low-level debug code.
+ * Expansion BUS Configuration registers
  */
-#define        IXP4XX_DEBUG_UART_BASE_PHYS     (0xC8000000)
-#define        IXP4XX_DEBUG_UART_BASE_VIRT     IOMEM(0xffb00000)
-#define        IXP4XX_DEBUG_UART_REGION_SIZE   (0x00001000)
+#define IXP4XX_EXP_CFG_BASE_PHYS       0xC4000000
+#define IXP4XX_EXP_CFG_BASE_VIRT       0xFEF14000
+#define IXP4XX_EXP_CFG_REGION_SIZE     0x00001000
 
 #define IXP4XX_EXP_CS0_OFFSET  0x00
 #define IXP4XX_EXP_CS1_OFFSET   0x04
index 9e7cad2d54cb9e9add09c676378e7956b6d70b71..4de8da536dbb2aa11cc0e0ad03d00090fe31e7bb 100644 (file)
@@ -86,7 +86,7 @@ void qmgr_release_queue(unsigned int queue);
 
 static inline void qmgr_put_entry(unsigned int queue, u32 val)
 {
-       extern struct qmgr_regs __iomem *qmgr_regs;
+       struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT;
 #if DEBUG_QMGR
        BUG_ON(!qmgr_queue_descs[queue]); /* not yet requested */
 
@@ -99,7 +99,7 @@ static inline void qmgr_put_entry(unsigned int queue, u32 val)
 static inline u32 qmgr_get_entry(unsigned int queue)
 {
        u32 val;
-       extern struct qmgr_regs __iomem *qmgr_regs;
+       const struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT;
        val = __raw_readl(&qmgr_regs->acc[queue][0]);
 #if DEBUG_QMGR
        BUG_ON(!qmgr_queue_descs[queue]); /* not yet requested */
@@ -112,14 +112,14 @@ static inline u32 qmgr_get_entry(unsigned int queue)
 
 static inline int __qmgr_get_stat1(unsigned int queue)
 {
-       extern struct qmgr_regs __iomem *qmgr_regs;
+       const struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT;
        return (__raw_readl(&qmgr_regs->stat1[queue >> 3])
                >> ((queue & 7) << 2)) & 0xF;
 }
 
 static inline int __qmgr_get_stat2(unsigned int queue)
 {
-       extern struct qmgr_regs __iomem *qmgr_regs;
+       const struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT;
        BUG_ON(queue >= HALF_QUEUES);
        return (__raw_readl(&qmgr_regs->stat2[queue >> 4])
                >> ((queue & 0xF) << 1)) & 0x3;
@@ -145,7 +145,7 @@ static inline int qmgr_stat_empty(unsigned int queue)
  */
 static inline int qmgr_stat_below_low_watermark(unsigned int queue)
 {
-       extern struct qmgr_regs __iomem *qmgr_regs;
+       const struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT;
        if (queue >= HALF_QUEUES)
                return (__raw_readl(&qmgr_regs->statne_h) >>
                        (queue - HALF_QUEUES)) & 0x01;
@@ -172,7 +172,7 @@ static inline int qmgr_stat_above_high_watermark(unsigned int queue)
  */
 static inline int qmgr_stat_full(unsigned int queue)
 {
-       extern struct qmgr_regs __iomem *qmgr_regs;
+       const struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT;
        if (queue >= HALF_QUEUES)
                return (__raw_readl(&qmgr_regs->statf_h) >>
                        (queue - HALF_QUEUES)) & 0x01;
index a17ed79207a4fce30f67b405f758cd07b23f85ad..d4eb09a62863639ebb8205e2d203d4c9d089462f 100644 (file)
 /* NPE mailbox_status value for reset */
 #define RESET_MBOX_STAT                        0x0000F0F0
 
-const char *npe_names[] = { "NPE-A", "NPE-B", "NPE-C" };
+#define NPE_A_FIRMWARE "NPE-A"
+#define NPE_B_FIRMWARE "NPE-B"
+#define NPE_C_FIRMWARE "NPE-C"
+
+const char *npe_names[] = { NPE_A_FIRMWARE, NPE_B_FIRMWARE, NPE_C_FIRMWARE };
 
 #define print_npe(pri, npe, fmt, ...)                                  \
        printk(pri "%s: " fmt, npe_name(npe), ## __VA_ARGS__)
@@ -724,6 +728,9 @@ module_exit(npe_cleanup_module);
 
 MODULE_AUTHOR("Krzysztof Halasa");
 MODULE_LICENSE("GPL v2");
+MODULE_FIRMWARE(NPE_A_FIRMWARE);
+MODULE_FIRMWARE(NPE_B_FIRMWARE);
+MODULE_FIRMWARE(NPE_C_FIRMWARE);
 
 EXPORT_SYMBOL(npe_names);
 EXPORT_SYMBOL(npe_running);
index 852f7c9f87d06ff69c6defde901732a3926aea7d..9d1b6b7c394cfb5eb5ef2968065f97b5f2b875a7 100644 (file)
@@ -14,7 +14,7 @@
 #include <linux/module.h>
 #include <mach/qmgr.h>
 
-struct qmgr_regs __iomem *qmgr_regs;
+static struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT;
 static struct resource *mem_res;
 static spinlock_t qmgr_lock;
 static u32 used_sram_bitmap[4]; /* 128 16-dword pages */
@@ -293,12 +293,6 @@ static int qmgr_init(void)
        if (mem_res == NULL)
                return -EBUSY;
 
-       qmgr_regs = ioremap(IXP4XX_QMGR_BASE_PHYS, IXP4XX_QMGR_REGION_SIZE);
-       if (qmgr_regs == NULL) {
-               err = -ENOMEM;
-               goto error_map;
-       }
-
        /* reset qmgr registers */
        for (i = 0; i < 4; i++) {
                __raw_writel(0x33333333, &qmgr_regs->stat1[i]);
@@ -347,8 +341,6 @@ static int qmgr_init(void)
 error_irq2:
        free_irq(IRQ_IXP4XX_QM1, NULL);
 error_irq:
-       iounmap(qmgr_regs);
-error_map:
        release_mem_region(IXP4XX_QMGR_BASE_PHYS, IXP4XX_QMGR_REGION_SIZE);
        return err;
 }
@@ -359,7 +351,6 @@ static void qmgr_remove(void)
        free_irq(IRQ_IXP4XX_QM2, NULL);
        synchronize_irq(IRQ_IXP4XX_QM1);
        synchronize_irq(IRQ_IXP4XX_QM2);
-       iounmap(qmgr_regs);
        release_mem_region(IXP4XX_QMGR_BASE_PHYS, IXP4XX_QMGR_REGION_SIZE);
 }
 
@@ -369,7 +360,6 @@ module_exit(qmgr_remove);
 MODULE_LICENSE("GPL v2");
 MODULE_AUTHOR("Krzysztof Halasa");
 
-EXPORT_SYMBOL(qmgr_regs);
 EXPORT_SYMBOL(qmgr_set_irq);
 EXPORT_SYMBOL(qmgr_enable_irq);
 EXPORT_SYMBOL(qmgr_disable_irq);
index ec544918b12c057b56109c1e688a217bf9ac5750..74fc5a074fc453e8ba78d686ef8ecf9409f14c1b 100644 (file)
@@ -207,14 +207,19 @@ static int __init kirkwood_pcie_setup(int nr, struct pci_sys_data *sys)
        return 1;
 }
 
+/*
+ * The root complex has a hardwired class of PCI_CLASS_MEMORY_OTHER, when it
+ * is operating as a root complex this needs to be switched to
+ * PCI_CLASS_BRIDGE_HOST or Linux will errantly try to process the BAR's on
+ * the device. Decoding setup is handled by the orion code.
+ */
 static void __devinit rc_pci_fixup(struct pci_dev *dev)
 {
-       /*
-        * Prevent enumeration of root complex.
-        */
        if (dev->bus->parent == NULL && dev->devfn == 0) {
                int i;
 
+               dev->class &= 0xff;
+               dev->class |= PCI_CLASS_BRIDGE_HOST << 8;
                for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
                        dev->resource[i].start = 0;
                        dev->resource[i].end   = 0;
index fe40d9e488c96cdf1c68ba1d6dd7acc9631b360b..d6721a7f4c3bd88fc1e9d124fcfc78aa92ab0ea5 100644 (file)
@@ -184,8 +184,6 @@ obj-$(CONFIG_HW_PERF_EVENTS)                += pmu.o
 obj-$(CONFIG_OMAP_MBOX_FWK)            += mailbox_mach.o
 mailbox_mach-objs                      := mailbox.o
 
-obj-$(CONFIG_OMAP_IOMMU)               += iommu2.o
-
 iommu-$(CONFIG_OMAP_IOMMU)             := omap-iommu.o
 obj-y                                  += $(iommu-m) $(iommu-y)
 
index 48d5e41dfbfabe3da59ef00f7457f5012cf2ec1a..378590694447bdbdd3ed4d7862624ac5d000c402 100644 (file)
@@ -580,6 +580,11 @@ static void __init igep_wlan_bt_init(void)
        } else
                return;
 
+       /* Make sure that the GPIO pins are muxed correctly */
+       omap_mux_init_gpio(igep_wlan_bt_gpios[0].gpio, OMAP_PIN_OUTPUT);
+       omap_mux_init_gpio(igep_wlan_bt_gpios[1].gpio, OMAP_PIN_OUTPUT);
+       omap_mux_init_gpio(igep_wlan_bt_gpios[2].gpio, OMAP_PIN_OUTPUT);
+
        err = gpio_request_array(igep_wlan_bt_gpios,
                                 ARRAY_SIZE(igep_wlan_bt_gpios));
        if (err) {
index 6efc30c961a5806dbecff3fb595bab1abfbc9082..067c486fe2959077875492e1166bea8212b5b5e9 100644 (file)
@@ -1316,16 +1316,6 @@ static struct clk dmic_fck = {
        .clkdm_name     = "abe_clkdm",
 };
 
-static struct clk dsp_fck = {
-       .name           = "dsp_fck",
-       .ops            = &clkops_omap2_dflt,
-       .enable_reg     = OMAP4430_CM_TESLA_TESLA_CLKCTRL,
-       .enable_bit     = OMAP4430_MODULEMODE_HWCTRL,
-       .clkdm_name     = "tesla_clkdm",
-       .parent         = &dpll_iva_m4x2_ck,
-       .recalc         = &followparent_recalc,
-};
-
 static struct clk dss_sys_clk = {
        .name           = "dss_sys_clk",
        .ops            = &clkops_omap2_dflt,
@@ -1696,16 +1686,6 @@ static struct clk i2c4_fck = {
        .recalc         = &followparent_recalc,
 };
 
-static struct clk ipu_fck = {
-       .name           = "ipu_fck",
-       .ops            = &clkops_omap2_dflt,
-       .enable_reg     = OMAP4430_CM_DUCATI_DUCATI_CLKCTRL,
-       .enable_bit     = OMAP4430_MODULEMODE_HWCTRL,
-       .clkdm_name     = "ducati_clkdm",
-       .parent         = &ducati_clk_mux_ck,
-       .recalc         = &followparent_recalc,
-};
-
 static struct clk iss_ctrlclk = {
        .name           = "iss_ctrlclk",
        .ops            = &clkops_omap2_dflt,
@@ -3151,7 +3131,6 @@ static struct omap_clk omap44xx_clks[] = {
        CLK(NULL,       "div_ts_ck",                    &div_ts_ck,     CK_446X),
        CLK(NULL,       "dmic_sync_mux_ck",             &dmic_sync_mux_ck,      CK_443X),
        CLK(NULL,       "dmic_fck",                     &dmic_fck,      CK_443X),
-       CLK(NULL,       "dsp_fck",                      &dsp_fck,       CK_443X),
        CLK(NULL,       "dss_sys_clk",                  &dss_sys_clk,   CK_443X),
        CLK(NULL,       "dss_tv_clk",                   &dss_tv_clk,    CK_443X),
        CLK(NULL,       "dss_48mhz_clk",                &dss_48mhz_clk, CK_443X),
@@ -3183,7 +3162,6 @@ static struct omap_clk omap44xx_clks[] = {
        CLK(NULL,       "i2c2_fck",                     &i2c2_fck,      CK_443X),
        CLK(NULL,       "i2c3_fck",                     &i2c3_fck,      CK_443X),
        CLK(NULL,       "i2c4_fck",                     &i2c4_fck,      CK_443X),
-       CLK(NULL,       "ipu_fck",                      &ipu_fck,       CK_443X),
        CLK(NULL,       "iss_ctrlclk",                  &iss_ctrlclk,   CK_443X),
        CLK(NULL,       "iss_fck",                      &iss_fck,       CK_443X),
        CLK(NULL,       "iva_fck",                      &iva_fck,       CK_443X),
index 48daac2581b4a154a768923681ac108c084a5c98..84551f205e46fd20d5ef47849d279643f80f3b18 100644 (file)
@@ -64,30 +64,36 @@ void __init omap_ads7846_init(int bus_num, int gpio_pendown, int gpio_debounce,
        struct spi_board_info *spi_bi = &ads7846_spi_board_info;
        int err;
 
-       err = gpio_request_one(gpio_pendown, GPIOF_IN, "TSPenDown");
-       if (err) {
-               pr_err("Couldn't obtain gpio for TSPenDown: %d\n", err);
-               return;
-       }
+       /*
+        * If a board defines get_pendown_state() function, request the pendown
+        * GPIO and set the GPIO debounce time.
+        * If a board does not define the get_pendown_state() function, then
+        * the ads7846 driver will setup the pendown GPIO itself.
+        */
+       if (board_pdata && board_pdata->get_pendown_state) {
+               err = gpio_request_one(gpio_pendown, GPIOF_IN, "TSPenDown");
+               if (err) {
+                       pr_err("Couldn't obtain gpio for TSPenDown: %d\n", err);
+                       return;
+               }
 
-       if (gpio_debounce)
-               gpio_set_debounce(gpio_pendown, gpio_debounce);
+               if (gpio_debounce)
+                       gpio_set_debounce(gpio_pendown, gpio_debounce);
+
+               gpio_export(gpio_pendown, 0);
+       }
 
        spi_bi->bus_num = bus_num;
        spi_bi->irq     = gpio_to_irq(gpio_pendown);
 
+       ads7846_config.gpio_pendown = gpio_pendown;
+
        if (board_pdata) {
                board_pdata->gpio_pendown = gpio_pendown;
+               board_pdata->gpio_pendown_debounce = gpio_debounce;
                spi_bi->platform_data = board_pdata;
-               if (board_pdata->get_pendown_state)
-                       gpio_export(gpio_pendown, 0);
-       } else {
-               ads7846_config.gpio_pendown = gpio_pendown;
        }
 
-       if (!board_pdata || (board_pdata && !board_pdata->get_pendown_state))
-               gpio_free(gpio_pendown);
-
        spi_register_board_info(&ads7846_spi_board_info, 1);
 }
 #else
index c72b5a7277200d08bc28e3b5348bfedcb677fefc..787a996ec4eb06404f1c6f60ea18bcc532fc9c05 100644 (file)
@@ -127,7 +127,7 @@ static struct platform_device omap2cam_device = {
 
 #if defined(CONFIG_IOMMU_API)
 
-#include <plat/iommu.h>
+#include <linux/platform_data/iommu-omap.h>
 
 static struct resource omap3isp_resources[] = {
        {
@@ -214,7 +214,7 @@ static struct platform_device omap3isp_device = {
 };
 
 static struct omap_iommu_arch_data omap3_isp_iommu = {
-       .name = "isp",
+       .name = "mmu_isp",
 };
 
 int omap3_init_camera(struct isp_platform_data *pdata)
index df298d46707c78f38ccaa6051fded40dbc533fbf..7642fc4672c1f57b2b67a1839b341e9f15260170 100644 (file)
 
 #include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/slab.h>
 
-#include <plat/iommu.h>
+#include <linux/platform_data/iommu-omap.h>
+#include <plat/omap_hwmod.h>
+#include <plat/omap_device.h>
 
-#include "soc.h"
-#include "common.h"
-
-struct iommu_device {
-       resource_size_t base;
-       int irq;
-       struct iommu_platform_data pdata;
-       struct resource res[2];
-};
-static struct iommu_device *devices;
-static int num_iommu_devices;
-
-#ifdef CONFIG_ARCH_OMAP3
-static struct iommu_device omap3_devices[] = {
-       {
-               .base = 0x480bd400,
-               .irq = 24 + OMAP_INTC_START,
-               .pdata = {
-                       .name = "isp",
-                       .nr_tlb_entries = 8,
-                       .clk_name = "cam_ick",
-                       .da_start = 0x0,
-                       .da_end = 0xFFFFF000,
-               },
-       },
-#if defined(CONFIG_OMAP_IOMMU_IVA2)
-       {
-               .base = 0x5d000000,
-               .irq = 28 + OMAP_INTC_START,
-               .pdata = {
-                       .name = "iva2",
-                       .nr_tlb_entries = 32,
-                       .clk_name = "iva2_ck",
-                       .da_start = 0x11000000,
-                       .da_end = 0xFFFFF000,
-               },
-       },
-#endif
-};
-#define NR_OMAP3_IOMMU_DEVICES ARRAY_SIZE(omap3_devices)
-static struct platform_device *omap3_iommu_pdev[NR_OMAP3_IOMMU_DEVICES];
-#else
-#define omap3_devices          NULL
-#define NR_OMAP3_IOMMU_DEVICES 0
-#define omap3_iommu_pdev       NULL
-#endif
-
-#ifdef CONFIG_ARCH_OMAP4
-static struct iommu_device omap4_devices[] = {
-       {
-               .base = OMAP4_MMU1_BASE,
-               .irq = 100 + OMAP44XX_IRQ_GIC_START,
-               .pdata = {
-                       .name = "ducati",
-                       .nr_tlb_entries = 32,
-                       .clk_name = "ipu_fck",
-                       .da_start = 0x0,
-                       .da_end = 0xFFFFF000,
-               },
-       },
-       {
-               .base = OMAP4_MMU2_BASE,
-               .irq = 28 + OMAP44XX_IRQ_GIC_START,
-               .pdata = {
-                       .name = "tesla",
-                       .nr_tlb_entries = 32,
-                       .clk_name = "dsp_fck",
-                       .da_start = 0x0,
-                       .da_end = 0xFFFFF000,
-               },
-       },
-};
-#define NR_OMAP4_IOMMU_DEVICES ARRAY_SIZE(omap4_devices)
-static struct platform_device *omap4_iommu_pdev[NR_OMAP4_IOMMU_DEVICES];
-#else
-#define omap4_devices          NULL
-#define NR_OMAP4_IOMMU_DEVICES 0
-#define omap4_iommu_pdev       NULL
-#endif
-
-static struct platform_device **omap_iommu_pdev;
-
-static int __init omap_iommu_init(void)
+static int __init omap_iommu_dev_init(struct omap_hwmod *oh, void *unused)
 {
-       int i, err;
-       struct resource res[] = {
-               { .flags = IORESOURCE_MEM },
-               { .flags = IORESOURCE_IRQ },
-       };
+       struct platform_device *pdev;
+       struct iommu_platform_data *pdata;
+       struct omap_mmu_dev_attr *a = (struct omap_mmu_dev_attr *)oh->dev_attr;
+       static int i;
+
+       pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
+       if (!pdata)
+               return -ENOMEM;
+
+       pdata->name = oh->name;
+       pdata->nr_tlb_entries = a->nr_tlb_entries;
+       pdata->da_start = a->da_start;
+       pdata->da_end = a->da_end;
+
+       if (oh->rst_lines_cnt == 1) {
+               pdata->reset_name = oh->rst_lines->name;
+               pdata->assert_reset = omap_device_assert_hardreset;
+               pdata->deassert_reset = omap_device_deassert_hardreset;
+       }
 
-       if (cpu_is_omap34xx()) {
-               devices = omap3_devices;
-               omap_iommu_pdev = omap3_iommu_pdev;
-               num_iommu_devices = NR_OMAP3_IOMMU_DEVICES;
-       } else if (cpu_is_omap44xx()) {
-               devices = omap4_devices;
-               omap_iommu_pdev = omap4_iommu_pdev;
-               num_iommu_devices = NR_OMAP4_IOMMU_DEVICES;
-       } else
-               return -ENODEV;
+       pdev = omap_device_build("omap-iommu", i, oh, pdata, sizeof(*pdata),
+                               NULL, 0, 0);
 
-       for (i = 0; i < num_iommu_devices; i++) {
-               struct platform_device *pdev;
-               const struct iommu_device *d = &devices[i];
+       kfree(pdata);
 
-               pdev = platform_device_alloc("omap-iommu", i);
-               if (!pdev) {
-                       err = -ENOMEM;
-                       goto err_out;
-               }
+       if (IS_ERR(pdev)) {
+               pr_err("%s: device build err: %ld\n", __func__, PTR_ERR(pdev));
+               return PTR_ERR(pdev);
+       }
 
-               res[0].start = d->base;
-               res[0].end = d->base + MMU_REG_SIZE - 1;
-               res[1].start = res[1].end = d->irq;
+       i++;
 
-               err = platform_device_add_resources(pdev, res,
-                                                   ARRAY_SIZE(res));
-               if (err)
-                       goto err_out;
-               err = platform_device_add_data(pdev, &d->pdata,
-                                              sizeof(d->pdata));
-               if (err)
-                       goto err_out;
-               err = platform_device_add(pdev);
-               if (err)
-                       goto err_out;
-               omap_iommu_pdev[i] = pdev;
-       }
        return 0;
+}
 
-err_out:
-       while (i--)
-               platform_device_put(omap_iommu_pdev[i]);
-       return err;
+static int __init omap_iommu_init(void)
+{
+       return omap_hwmod_for_each_by_class("mmu", omap_iommu_dev_init, NULL);
 }
 /* must be ready before omap3isp is probed */
 subsys_initcall(omap_iommu_init);
 
 static void __exit omap_iommu_exit(void)
 {
-       int i;
-
-       for (i = 0; i < num_iommu_devices; i++)
-               platform_device_unregister(omap_iommu_pdev[i]);
+       /* Do nothing */
 }
 module_exit(omap_iommu_exit);
 
index f67b7ee07dd4f5575e206c2098bb67c88fa32873..621bc713723310fe720e67644088b5d5c4eadc72 100644 (file)
@@ -26,8 +26,8 @@
 #include <plat/mmc.h>
 #include <linux/platform_data/asoc-ti-mcbsp.h>
 #include <linux/platform_data/spi-omap2-mcspi.h>
+#include <linux/platform_data/iommu-omap.h>
 #include <plat/dmtimer.h>
-#include <plat/iommu.h>
 
 #include "am35xx.h"
 
index 0b1249e003987da276c2072aed5d39bcc334e8f5..4b985b9b81d00dc4316ca4742d93cf8196447511 100644 (file)
 #include <plat/dma.h>
 #include <linux/platform_data/spi-omap2-mcspi.h>
 #include <linux/platform_data/asoc-ti-mcbsp.h>
+#include <linux/platform_data/iommu-omap.h>
 #include <plat/mmc.h>
 #include <plat/dmtimer.h>
 #include <plat/common.h>
-#include <plat/iommu.h>
 
 #include "omap_hwmod_common_data.h"
 #include "cm1_44xx.h"
@@ -651,7 +651,7 @@ static struct omap_hwmod omap44xx_dsp_hwmod = {
        .mpu_irqs       = omap44xx_dsp_irqs,
        .rst_lines      = omap44xx_dsp_resets,
        .rst_lines_cnt  = ARRAY_SIZE(omap44xx_dsp_resets),
-       .main_clk       = "dsp_fck",
+       .main_clk       = "dpll_iva_m4x2_ck",
        .prcm = {
                .omap4 = {
                        .clkctrl_offs = OMAP4_CM_TESLA_TESLA_CLKCTRL_OFFSET,
@@ -1678,7 +1678,7 @@ static struct omap_hwmod omap44xx_ipu_hwmod = {
        .mpu_irqs       = omap44xx_ipu_irqs,
        .rst_lines      = omap44xx_ipu_resets,
        .rst_lines_cnt  = ARRAY_SIZE(omap44xx_ipu_resets),
-       .main_clk       = "ipu_fck",
+       .main_clk       = "ducati_clk_mux_ck",
        .prcm = {
                .omap4 = {
                        .clkctrl_offs = OMAP4_CM_DUCATI_DUCATI_CLKCTRL_OFFSET,
index 44c42057b61c2c292e42dbdcb5b47f3b9b65c401..a256135d8e48f59c0a6a103b2d449682caac9be2 100644 (file)
@@ -73,6 +73,7 @@ void __init omap4_pmic_init(const char *pmic_type,
 {
        /* PMIC part*/
        omap_mux_init_signal("sys_nirq1", OMAP_PIN_INPUT_PULLUP | OMAP_PIN_OFF_WAKEUPENABLE);
+       omap_mux_init_signal("fref_clk0_out.sys_drm_msecure", OMAP_PIN_OUTPUT);
        omap_pmic_init(1, 400, pmic_type, 7 + OMAP44XX_IRQ_GIC_START, pmic_data);
 
        /* Register additional devices on i2c1 bus if needed */
index 86b8b480634fbc652dbf11dd9d9abaec84fa5e00..09c5233f4dfc81993312734e1ce434b92c131553 100644 (file)
@@ -89,7 +89,7 @@ ENTRY(cpu_v6_dcache_clean_area)
        mov     pc, lr
 
 /*
- *     cpu_arm926_switch_mm(pgd_phys, tsk)
+ *     cpu_v6_switch_mm(pgd_phys, tsk)
  *
  *     Set the translation table base pointer to be pgd_phys
  *
index a5683a84c6ee0e313cb8f9daeeb7c72106952a4e..6013831a043e320fafd5e718a558d422fa67a624 100644 (file)
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
 #include <linux/i2c.h>
+#include <linux/i2c-omap.h>
 #include <linux/slab.h>
 #include <linux/err.h>
 #include <linux/clk.h>
 
 #include <mach/irqs.h>
 #include <plat/i2c.h>
+#include <plat/omap-pm.h>
 #include <plat/omap_device.h>
 
 #define OMAP_I2C_SIZE          0x3f
@@ -127,6 +129,16 @@ static inline int omap1_i2c_add_bus(int bus_id)
 
 
 #ifdef CONFIG_ARCH_OMAP2PLUS
+/*
+ * XXX This function is a temporary compatibility wrapper - only
+ * needed until the I2C driver can be converted to call
+ * omap_pm_set_max_dev_wakeup_lat() and handle a return code.
+ */
+static void omap_pm_set_max_mpu_wakeup_lat_compat(struct device *dev, long t)
+{
+       omap_pm_set_max_mpu_wakeup_lat(dev, t);
+}
+
 static inline int omap2_i2c_add_bus(int bus_id)
 {
        int l;
@@ -158,6 +170,15 @@ static inline int omap2_i2c_add_bus(int bus_id)
        dev_attr = (struct omap_i2c_dev_attr *)oh->dev_attr;
        pdata->flags = dev_attr->flags;
 
+       /*
+        * When waiting for completion of a i2c transfer, we need to
+        * set a wake up latency constraint for the MPU. This is to
+        * ensure quick enough wakeup from idle, when transfer
+        * completes.
+        * Only omap3 has support for constraints
+        */
+       if (cpu_is_omap34xx())
+               pdata->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat_compat;
        pdev = omap_device_build(name, bus_id, oh, pdata,
                        sizeof(struct omap_i2c_bus_platform_data),
                        NULL, 0, 0);
diff --git a/arch/arm/plat-omap/include/plat/iommu2.h b/arch/arm/plat-omap/include/plat/iommu2.h
deleted file mode 100644 (file)
index d4116b5..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * omap iommu: omap2 architecture specific definitions
- *
- * Copyright (C) 2008-2009 Nokia Corporation
- *
- * Written by Hiroshi DOYU <Hiroshi.DOYU@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.
- */
-
-#ifndef __MACH_IOMMU2_H
-#define __MACH_IOMMU2_H
-
-#include <linux/io.h>
-
-/*
- * MMU Register offsets
- */
-#define MMU_REVISION           0x00
-#define MMU_SYSCONFIG          0x10
-#define MMU_SYSSTATUS          0x14
-#define MMU_IRQSTATUS          0x18
-#define MMU_IRQENABLE          0x1c
-#define MMU_WALKING_ST         0x40
-#define MMU_CNTL               0x44
-#define MMU_FAULT_AD           0x48
-#define MMU_TTB                        0x4c
-#define MMU_LOCK               0x50
-#define MMU_LD_TLB             0x54
-#define MMU_CAM                        0x58
-#define MMU_RAM                        0x5c
-#define MMU_GFLUSH             0x60
-#define MMU_FLUSH_ENTRY                0x64
-#define MMU_READ_CAM           0x68
-#define MMU_READ_RAM           0x6c
-#define MMU_EMU_FAULT_AD       0x70
-
-#define MMU_REG_SIZE           256
-
-/*
- * MMU Register bit definitions
- */
-#define MMU_LOCK_BASE_SHIFT    10
-#define MMU_LOCK_BASE_MASK     (0x1f << MMU_LOCK_BASE_SHIFT)
-#define MMU_LOCK_BASE(x)       \
-       ((x & MMU_LOCK_BASE_MASK) >> MMU_LOCK_BASE_SHIFT)
-
-#define MMU_LOCK_VICT_SHIFT    4
-#define MMU_LOCK_VICT_MASK     (0x1f << MMU_LOCK_VICT_SHIFT)
-#define MMU_LOCK_VICT(x)       \
-       ((x & MMU_LOCK_VICT_MASK) >> MMU_LOCK_VICT_SHIFT)
-
-#define MMU_CAM_VATAG_SHIFT    12
-#define MMU_CAM_VATAG_MASK \
-       ((~0UL >> MMU_CAM_VATAG_SHIFT) << MMU_CAM_VATAG_SHIFT)
-#define MMU_CAM_P              (1 << 3)
-#define MMU_CAM_V              (1 << 2)
-#define MMU_CAM_PGSZ_MASK      3
-#define MMU_CAM_PGSZ_1M                (0 << 0)
-#define MMU_CAM_PGSZ_64K       (1 << 0)
-#define MMU_CAM_PGSZ_4K                (2 << 0)
-#define MMU_CAM_PGSZ_16M       (3 << 0)
-
-#define MMU_RAM_PADDR_SHIFT    12
-#define MMU_RAM_PADDR_MASK \
-       ((~0UL >> MMU_RAM_PADDR_SHIFT) << MMU_RAM_PADDR_SHIFT)
-#define MMU_RAM_ENDIAN_SHIFT   9
-#define MMU_RAM_ENDIAN_MASK    (1 << MMU_RAM_ENDIAN_SHIFT)
-#define MMU_RAM_ENDIAN_BIG     (1 << MMU_RAM_ENDIAN_SHIFT)
-#define MMU_RAM_ENDIAN_LITTLE  (0 << MMU_RAM_ENDIAN_SHIFT)
-#define MMU_RAM_ELSZ_SHIFT     7
-#define MMU_RAM_ELSZ_MASK      (3 << MMU_RAM_ELSZ_SHIFT)
-#define MMU_RAM_ELSZ_8         (0 << MMU_RAM_ELSZ_SHIFT)
-#define MMU_RAM_ELSZ_16                (1 << MMU_RAM_ELSZ_SHIFT)
-#define MMU_RAM_ELSZ_32                (2 << MMU_RAM_ELSZ_SHIFT)
-#define MMU_RAM_ELSZ_NONE      (3 << MMU_RAM_ELSZ_SHIFT)
-#define MMU_RAM_MIXED_SHIFT    6
-#define MMU_RAM_MIXED_MASK     (1 << MMU_RAM_MIXED_SHIFT)
-#define MMU_RAM_MIXED          MMU_RAM_MIXED_MASK
-
-/*
- * register accessors
- */
-static inline u32 iommu_read_reg(struct omap_iommu *obj, size_t offs)
-{
-       return __raw_readl(obj->regbase + offs);
-}
-
-static inline void iommu_write_reg(struct omap_iommu *obj, u32 val, size_t offs)
-{
-       __raw_writel(val, obj->regbase + offs);
-}
-
-#endif /* __MACH_IOMMU2_H */
diff --git a/arch/arm/plat-omap/include/plat/iovmm.h b/arch/arm/plat-omap/include/plat/iovmm.h
deleted file mode 100644 (file)
index 498e57c..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * omap iommu: simple virtual address space management
- *
- * Copyright (C) 2008-2009 Nokia Corporation
- *
- * Written by Hiroshi DOYU <Hiroshi.DOYU@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.
- */
-
-#ifndef __IOMMU_MMAP_H
-#define __IOMMU_MMAP_H
-
-#include <linux/iommu.h>
-
-struct iovm_struct {
-       struct omap_iommu       *iommu; /* iommu object which this belongs to */
-       u32                     da_start; /* area definition */
-       u32                     da_end;
-       u32                     flags; /* IOVMF_: see below */
-       struct list_head        list; /* linked in ascending order */
-       const struct sg_table   *sgt; /* keep 'page' <-> 'da' mapping */
-       void                    *va; /* mpu side mapped address */
-};
-
-/*
- * IOVMF_FLAGS: attribute for iommu virtual memory area(iovma)
- *
- * lower 16 bit is used for h/w and upper 16 bit is for s/w.
- */
-#define IOVMF_SW_SHIFT         16
-
-/*
- * iovma: h/w flags derived from cam and ram attribute
- */
-#define IOVMF_CAM_MASK         (~((1 << 10) - 1))
-#define IOVMF_RAM_MASK         (~IOVMF_CAM_MASK)
-
-#define IOVMF_PGSZ_MASK                (3 << 0)
-#define IOVMF_PGSZ_1M          MMU_CAM_PGSZ_1M
-#define IOVMF_PGSZ_64K         MMU_CAM_PGSZ_64K
-#define IOVMF_PGSZ_4K          MMU_CAM_PGSZ_4K
-#define IOVMF_PGSZ_16M         MMU_CAM_PGSZ_16M
-
-#define IOVMF_ENDIAN_MASK      (1 << 9)
-#define IOVMF_ENDIAN_BIG       MMU_RAM_ENDIAN_BIG
-#define IOVMF_ENDIAN_LITTLE    MMU_RAM_ENDIAN_LITTLE
-
-#define IOVMF_ELSZ_MASK                (3 << 7)
-#define IOVMF_ELSZ_8           MMU_RAM_ELSZ_8
-#define IOVMF_ELSZ_16          MMU_RAM_ELSZ_16
-#define IOVMF_ELSZ_32          MMU_RAM_ELSZ_32
-#define IOVMF_ELSZ_NONE                MMU_RAM_ELSZ_NONE
-
-#define IOVMF_MIXED_MASK       (1 << 6)
-#define IOVMF_MIXED            MMU_RAM_MIXED
-
-/*
- * iovma: s/w flags, used for mapping and umapping internally.
- */
-#define IOVMF_MMIO             (1 << IOVMF_SW_SHIFT)
-#define IOVMF_ALLOC            (2 << IOVMF_SW_SHIFT)
-#define IOVMF_ALLOC_MASK       (3 << IOVMF_SW_SHIFT)
-
-/* "superpages" is supported just with physically linear pages */
-#define IOVMF_DISCONT          (1 << (2 + IOVMF_SW_SHIFT))
-#define IOVMF_LINEAR           (2 << (2 + IOVMF_SW_SHIFT))
-#define IOVMF_LINEAR_MASK      (3 << (2 + IOVMF_SW_SHIFT))
-
-#define IOVMF_DA_FIXED         (1 << (4 + IOVMF_SW_SHIFT))
-
-
-extern struct iovm_struct *omap_find_iovm_area(struct device *dev, u32 da);
-extern u32
-omap_iommu_vmap(struct iommu_domain *domain, struct device *dev, u32 da,
-                       const struct sg_table *sgt, u32 flags);
-extern struct sg_table *omap_iommu_vunmap(struct iommu_domain *domain,
-                               struct device *dev, u32 da);
-extern u32
-omap_iommu_vmalloc(struct iommu_domain *domain, struct device *dev,
-                               u32 da, size_t bytes, u32 flags);
-extern void
-omap_iommu_vfree(struct iommu_domain *domain, struct device *dev,
-                               const u32 da);
-extern void *omap_da_to_va(struct device *dev, u32 da);
-
-#endif /* __IOMMU_MMAP_H */
index db98e7021f0daf7507fe55f91f1e73ef761a6dc3..0abd1c4698875f4edbb5be3cd506206c676019b6 100644 (file)
@@ -473,12 +473,13 @@ int s3c2410_dma_enqueue(enum dma_ch channel, void *id,
                pr_debug("dma%d: %s: buffer %p queued onto non-empty channel\n",
                         chan->number, __func__, buf);
 
-               if (chan->end == NULL)
+               if (chan->end == NULL) {
                        pr_debug("dma%d: %s: %p not empty, and chan->end==NULL?\n",
                                 chan->number, __func__, chan);
-
-               chan->end->next = buf;
-               chan->end = buf;
+               } else {
+                       chan->end->next = buf;
+                       chan->end = buf;
+               }
        }
 
        /* if necessary, update the next buffer field */
index 538f4b44db5d40b14b00e8b5384b189c313da0dd..99477689419849822602f0b152650d88dd18f241 100644 (file)
@@ -50,6 +50,7 @@ static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t dev_addr)
 static inline int dma_mapping_error(struct device *dev, dma_addr_t dev_addr)
 {
        struct dma_map_ops *ops = get_dma_ops(dev);
+       debug_dma_mapping_error(dev, dev_addr);
        return ops->mapping_error(dev, dev_addr);
 }
 
index 6d909faebf28d155020ef96e17654d5ae74bed6f..656a6f291a35195bc697a1f5e5112af7f1eab356 100644 (file)
@@ -392,7 +392,7 @@ __SYSCALL(367, sys_fanotify_init)
 __SYSCALL(368, compat_sys_fanotify_mark_wrapper)
 __SYSCALL(369, sys_prlimit64)
 __SYSCALL(370, sys_name_to_handle_at)
-__SYSCALL(371, sys_open_by_handle_at)
+__SYSCALL(371, compat_sys_open_by_handle_at)
 __SYSCALL(372, sys_clock_adjtime)
 __SYSCALL(373, sys_syncfs)
 
index 03579fd99dba62ad24c2649536a623ed37c24aa8..3c694065030f506708a9717ef7bbb5faf94f6bc1 100644 (file)
@@ -32,6 +32,7 @@ static inline int dma_set_mask(struct device *dev, u64 dma_mask)
  */
 static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
 {
+       debug_dma_mapping_error(dev, dma_addr);
        return dma_addr == ~0;
 }
 
diff --git a/arch/c6x/include/asm/setup.h b/arch/c6x/include/asm/setup.h
new file mode 100644 (file)
index 0000000..ecead15
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ *  Port on Texas Instruments TMS320C6x architecture
+ *
+ *  Copyright (C) 2004, 2009, 2010 2011 Texas Instruments Incorporated
+ *  Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.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.
+ */
+#ifndef _ASM_C6X_SETUP_H
+#define _ASM_C6X_SETUP_H
+
+#include <uapi/asm/setup.h>
+
+#ifndef __ASSEMBLY__
+extern char c6x_command_line[COMMAND_LINE_SIZE];
+
+extern int c6x_add_memory(phys_addr_t start, unsigned long size);
+
+extern unsigned long ram_start;
+extern unsigned long ram_end;
+
+extern int c6x_num_cores;
+extern unsigned int c6x_silicon_rev;
+extern unsigned int c6x_devstat;
+extern unsigned char c6x_fuse_mac[6];
+
+extern void machine_init(unsigned long dt_ptr);
+extern void time_init(void);
+
+#endif /* !__ASSEMBLY__ */
+#endif /* _ASM_C6X_SETUP_H */
index c312b424c4331b58aed335e43a3044e6088fce2c..e9bc2b2b814740d82e9a4fb9eae800a3bbfe5aad 100644 (file)
@@ -1,6 +1,8 @@
 # UAPI Header export list
 include include/uapi/asm-generic/Kbuild.asm
 
+generic-y += kvm_para.h
+
 header-y += byteorder.h
 header-y += kvm_para.h
 header-y += ptrace.h
diff --git a/arch/c6x/include/uapi/asm/kvm_para.h b/arch/c6x/include/uapi/asm/kvm_para.h
deleted file mode 100644 (file)
index 14fab8f..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-generic/kvm_para.h>
index a01e31896fa90937dec74fa746e6745c72a94891..ad9ac97a8dad3be119ab72754ab24f871c6ff880 100644 (file)
@@ -1,33 +1,6 @@
-/*
- *  Port on Texas Instruments TMS320C6x architecture
- *
- *  Copyright (C) 2004, 2009, 2010 2011 Texas Instruments Incorporated
- *  Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.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.
- */
-#ifndef _ASM_C6X_SETUP_H
-#define _ASM_C6X_SETUP_H
+#ifndef _UAPI_ASM_C6X_SETUP_H
+#define _UAPI_ASM_C6X_SETUP_H
 
 #define COMMAND_LINE_SIZE   1024
 
-#ifndef __ASSEMBLY__
-extern char c6x_command_line[COMMAND_LINE_SIZE];
-
-extern int c6x_add_memory(phys_addr_t start, unsigned long size);
-
-extern unsigned long ram_start;
-extern unsigned long ram_end;
-
-extern int c6x_num_cores;
-extern unsigned int c6x_silicon_rev;
-extern unsigned int c6x_devstat;
-extern unsigned char c6x_fuse_mac[6];
-
-extern void machine_init(unsigned long dt_ptr);
-extern void time_init(void);
-
-#endif /* !__ASSEMBLY__ */
-#endif /* _ASM_C6X_SETUP_H */
+#endif /* _UAPI_ASM_C6X_SETUP_H */
index 5449c36018fe2d269b2daaa162a25a39bfa53c9b..0ed6157dd256a81aeefc9e8de971f834f313a11d 100644 (file)
@@ -277,6 +277,8 @@ work_rescheduled:
  [A1]  BNOP    .S1     work_resched,5
 
 work_notifysig:
+       ;; enable interrupts for do_notify_resume()
+       UNMASK_INT B2
        B       .S2     do_notify_resume
        LDW     .D2T1   *+SP(REGS__END+8),A6 ; syscall flag
        ADDKPC  .S2     resume_userspace,B3,1
@@ -427,8 +429,7 @@ ENTRY(ret_from_kernel_execve)
 ENDPROC(ret_from_kernel_execve)
 
        ;;
-       ;; These are the interrupt handlers, responsible for calling __do_IRQ()
-       ;; int6 is used for syscalls (see _system_call entry)
+       ;; These are the interrupt handlers, responsible for calling c6x_do_IRQ()
        ;;
        .macro SAVE_ALL_INT
        SAVE_ALL IRP,ITSR
index 4f5e8148440d25b2d89d8824e9387878e33e4802..cf3ab7e784b5474be705c6e091431f5538b1ee00 100644 (file)
@@ -58,6 +58,7 @@ static inline void dma_free_attrs(struct device *dev, size_t size,
 static inline int dma_mapping_error(struct device *dev, dma_addr_t daddr)
 {
        struct dma_map_ops *ops = platform_dma_get_ops(dev);
+       debug_dma_mapping_error(dev, daddr);
        return ops->mapping_error(dev, daddr);
 }
 
index 67e489d8d1bd6450945b3b5a4320eaa4d1840953..2df26b57c26ada5cf34d6c608f75ebd7460f2063 100644 (file)
@@ -41,7 +41,7 @@ struct k_sigaction {
 static inline void sigaddset(sigset_t *set, int _sig)
 {
        asm ("bfset %0{%1,#1}"
-               : "+od" (*set)
+               : "+o" (*set)
                : "id" ((_sig - 1) ^ 31)
                : "cc");
 }
@@ -49,7 +49,7 @@ static inline void sigaddset(sigset_t *set, int _sig)
 static inline void sigdelset(sigset_t *set, int _sig)
 {
        asm ("bfclr %0{%1,#1}"
-               : "+od" (*set)
+               : "+o" (*set)
                : "id" ((_sig - 1) ^ 31)
                : "cc");
 }
@@ -65,7 +65,7 @@ static inline int __gen_sigismember(sigset_t *set, int _sig)
        int ret;
        asm ("bfextu %1{%2,#1},%0"
                : "=d" (ret)
-               : "od" (*set), "id" ((_sig-1) ^ 31)
+               : "o" (*set), "id" ((_sig-1) ^ 31)
                : "cc");
        return ret;
 }
index 01d228286cb0414c157707aa0535bf5f44787ec8..46460f1c49c44b161cbc3de84f1a6c2b69820661 100644 (file)
@@ -114,6 +114,8 @@ static inline void __dma_sync(unsigned long paddr,
 static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
 {
        struct dma_map_ops *ops = get_dma_ops(dev);
+
+       debug_dma_mapping_error(dev, dma_addr);
        if (ops->mapping_error)
                return ops->mapping_error(dev, dma_addr);
 
index 3847e5b9c601f68e189ca21749300b6b7e416415..3903e3d11f5a557d673fbcfcb051e1fd17e49392 100644 (file)
@@ -111,7 +111,7 @@ asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)
 
        /* It is more difficult to avoid calling this function than to
         call it and ignore errors. */
-       if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->r1))
+       if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->r1) == -EFAULT)
                goto badframe;
 
        return rval;
index be39a12901c6c33563b2abedf3a7698caf76ed4c..006b43e38a9c4f831bcc1135f0048c8b8c48aaf6 100644 (file)
@@ -40,6 +40,8 @@ static inline int dma_supported(struct device *dev, u64 mask)
 static inline int dma_mapping_error(struct device *dev, u64 mask)
 {
        struct dma_map_ops *ops = get_dma_ops(dev);
+
+       debug_dma_mapping_error(dev, mask);
        return ops->mapping_error(dev, mask);
 }
 
index bd94946a18f343da04b48aba1a13b83f6e724c18..ef99db994c2f9738dae4cc80a320aebcb55930f3 100644 (file)
@@ -95,7 +95,17 @@ static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
                                             pte_t *ptep, pte_t pte,
                                             int dirty)
 {
-       return ptep_set_access_flags(vma, addr, ptep, pte, dirty);
+       int changed = !pte_same(*ptep, pte);
+
+       if (changed) {
+               set_pte_at(vma->vm_mm, addr, ptep, pte);
+               /*
+                * There could be some standard sized pages in there,
+                * get them all.
+                */
+               flush_tlb_range(vma, addr, addr + HPAGE_SIZE);
+       }
+       return changed;
 }
 
 static inline pte_t huge_ptep_get(pte_t *ptep)
index b1fb7af3c35058f2e739b4ec41fb28d62d00c2d2..cce3782c96c9b792e412abc32fed55547dcde7c9 100644 (file)
@@ -510,7 +510,6 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
                                c->cputype = CPU_R3000A;
                                __cpu_name[cpu] = "R3000A";
                        }
-                       break;
                } else {
                        c->cputype = CPU_R3000;
                        __cpu_name[cpu] = "R3000";
index a6c133212003ed96537e6f950ec71c59d98559fb..9b00362f32f6d95d4577817bbd39757f880d0639 100644 (file)
@@ -36,6 +36,11 @@ FEXPORT(ret_from_exception)
 FEXPORT(ret_from_irq)
        LONG_S  s0, TI_REGS($28)
 FEXPORT(__ret_from_irq)
+/*
+ * We can be coming here from a syscall done in the kernel space,
+ * e.g. a failed kernel_execve().
+ */
+resume_userspace_check:
        LONG_L  t0, PT_STATUS(sp)               # returning to kernel mode?
        andi    t0, t0, KU_USER
        beqz    t0, resume_kernel
@@ -162,7 +167,7 @@ work_notifysig:                             # deal with pending signals and
        move    a0, sp
        li      a1, 0
        jal     do_notify_resume        # a2 already loaded
-       j       resume_userspace
+       j       resume_userspace_check
 
 FEXPORT(syscall_exit_partial)
        local_irq_disable               # make sure need_resched doesn't
index f6ba8381ee0186c5dfc1f19879ae4c39d15d52e9..86ec03f0e00c48f966e428eb1a7844cfcf3eff1a 100644 (file)
@@ -397,14 +397,14 @@ EXPORT(sysn32_call_table)
        PTR     sys_timerfd_create
        PTR     compat_sys_timerfd_gettime      /* 6285 */
        PTR     compat_sys_timerfd_settime
-       PTR     sys_signalfd4
+       PTR     compat_sys_signalfd4
        PTR     sys_eventfd2
        PTR     sys_epoll_create1
        PTR     sys_dup3                        /* 6290 */
        PTR     sys_pipe2
        PTR     sys_inotify_init1
-       PTR     sys_preadv
-       PTR     sys_pwritev
+       PTR     compat_sys_preadv
+       PTR     compat_sys_pwritev
        PTR     compat_sys_rt_tgsigqueueinfo    /* 6295 */
        PTR     sys_perf_event_open
        PTR     sys_accept4
index a53f8ec37aac68beef41b905b88cf1fe92e805d9..290dc6a1d7a344413e36f00fdacfa86e9d1bcbe3 100644 (file)
@@ -79,7 +79,7 @@ static struct resource data_resource = { .name = "Kernel data", };
 void __init add_memory_region(phys_t start, phys_t size, long type)
 {
        int x = boot_mem_map.nr_map;
-       struct boot_mem_map_entry *prev = boot_mem_map.map + x - 1;
+       int i;
 
        /* Sanity check */
        if (start + size < start) {
@@ -88,15 +88,29 @@ void __init add_memory_region(phys_t start, phys_t size, long type)
        }
 
        /*
-        * Try to merge with previous entry if any.  This is far less than
-        * perfect but is sufficient for most real world cases.
+        * Try to merge with existing entry, if any.
         */
-       if (x && prev->addr + prev->size == start && prev->type == type) {
-               prev->size += size;
+       for (i = 0; i < boot_mem_map.nr_map; i++) {
+               struct boot_mem_map_entry *entry = boot_mem_map.map + i;
+               unsigned long top;
+
+               if (entry->type != type)
+                       continue;
+
+               if (start + size < entry->addr)
+                       continue;                       /* no overlap */
+
+               if (entry->addr + entry->size < start)
+                       continue;                       /* no overlap */
+
+               top = max(entry->addr + entry->size, start + size);
+               entry->addr = min(entry->addr, start);
+               entry->size = top - entry->addr;
+
                return;
        }
 
-       if (x == BOOT_MEM_MAP_MAX) {
+       if (boot_mem_map.nr_map == BOOT_MEM_MAP_MAX) {
                pr_err("Ooops! Too many entries in the memory map!\n");
                return;
        }
index e091430dbeb1bcbd2451ab02cd959551289fab30..cd160be3ce4dc97b934b566b4c69197ceb07b342 100644 (file)
@@ -56,7 +56,7 @@ __asm__(
        "       .set    pop                                             \n"
        "       .endm                                                   \n");
 
-void arch_local_irq_disable(void)
+notrace void arch_local_irq_disable(void)
 {
        preempt_disable();
        __asm__ __volatile__(
@@ -93,7 +93,7 @@ __asm__(
        "       .set    pop                                             \n"
        "       .endm                                                   \n");
 
-unsigned long arch_local_irq_save(void)
+notrace unsigned long arch_local_irq_save(void)
 {
        unsigned long flags;
        preempt_disable();
@@ -135,7 +135,7 @@ __asm__(
        "       .set    pop                                             \n"
        "       .endm                                                   \n");
 
-void arch_local_irq_restore(unsigned long flags)
+notrace void arch_local_irq_restore(unsigned long flags)
 {
        unsigned long __tmp1;
 
@@ -159,7 +159,7 @@ void arch_local_irq_restore(unsigned long flags)
 EXPORT_SYMBOL(arch_local_irq_restore);
 
 
-void __arch_local_irq_restore(unsigned long flags)
+notrace void __arch_local_irq_restore(unsigned long flags)
 {
        unsigned long __tmp1;
 
index 4b9b935a070e0c4d0160f2c259c3dc553c40b35e..88e79ad6f811e79d07fc45cd51cf2a0580cb20bc 100644 (file)
@@ -120,18 +120,11 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
 
        if (cpu_context(cpu, mm) != 0) {
                unsigned long size, flags;
-               int huge = is_vm_hugetlb_page(vma);
 
                ENTER_CRITICAL(flags);
-               if (huge) {
-                       start = round_down(start, HPAGE_SIZE);
-                       end = round_up(end, HPAGE_SIZE);
-                       size = (end - start) >> HPAGE_SHIFT;
-               } else {
-                       start = round_down(start, PAGE_SIZE << 1);
-                       end = round_up(end, PAGE_SIZE << 1);
-                       size = (end - start) >> (PAGE_SHIFT + 1);
-               }
+               start = round_down(start, PAGE_SIZE << 1);
+               end = round_up(end, PAGE_SIZE << 1);
+               size = (end - start) >> (PAGE_SHIFT + 1);
                if (size <= current_cpu_data.tlbsize/2) {
                        int oldpid = read_c0_entryhi();
                        int newpid = cpu_asid(cpu, mm);
@@ -140,10 +133,7 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
                                int idx;
 
                                write_c0_entryhi(start | newpid);
-                               if (huge)
-                                       start += HPAGE_SIZE;
-                               else
-                                       start += (PAGE_SIZE << 1);
+                               start += (PAGE_SIZE << 1);
                                mtc0_tlbw_hazard();
                                tlb_probe();
                                tlb_probe_hazard();
index 30110297f4f9509d6437c8f5c3e80220add6e2a9..ddedc8a77861ac4372832be8e59ce60d54d616f7 100644 (file)
@@ -84,7 +84,6 @@ asmlinkage long _sys_rt_sigreturn(struct pt_regs *regs)
 {
        struct rt_sigframe *frame = (struct rt_sigframe __user *)regs->sp;
        sigset_t set;
-       stack_t st;
 
        /*
         * Since we stacked the signal on a dword boundary,
@@ -104,11 +103,10 @@ asmlinkage long _sys_rt_sigreturn(struct pt_regs *regs)
        if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
                goto badframe;
 
-       if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st)))
-               goto badframe;
        /* It is more difficult to avoid calling this function than to
           call it and ignore errors.  */
-       do_sigaltstack(&st, NULL, regs->sp);
+       if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->sp) == -EFAULT)
+               goto badframe;
 
        return regs->gpr[11];
 
index fd49aeda9eb8b0c4fef656e3dc00228c59251b99..5dede04f2f3ead372752fdbaaafceca5708b6902 100644 (file)
@@ -65,7 +65,8 @@ put_sigset32(compat_sigset_t __user *up, sigset_t *set, size_t sz)
 {
        compat_sigset_t s;
 
-       if (sz != sizeof *set) panic("put_sigset32()");
+       if (sz != sizeof *set)
+               return -EINVAL;
        sigset_64to32(&s, set);
 
        return copy_to_user(up, &s, sizeof s);
@@ -77,7 +78,8 @@ get_sigset32(compat_sigset_t __user *up, sigset_t *set, size_t sz)
        compat_sigset_t s;
        int r;
 
-       if (sz != sizeof *set) panic("put_sigset32()");
+       if (sz != sizeof *set)
+               return -EINVAL;
 
        if ((r = copy_from_user(&s, up, sz)) == 0) {
                sigset_32to64(set, &s);
index 7426e40699bdbf08575d0b69722e6594a1535076..f76c10863c6266c5a4fe6a3fbbe22d022a11e8c2 100644 (file)
@@ -73,6 +73,8 @@ static unsigned long get_shared_area(struct address_space *mapping,
        struct vm_area_struct *vma;
        int offset = mapping ? get_offset(mapping) : 0;
 
+       offset = (offset + (pgoff << PAGE_SHIFT)) & 0x3FF000;
+
        addr = DCACHE_ALIGN(addr - offset) + offset;
 
        for (vma = find_vma(current->mm, addr); ; vma = vma->vm_next) {
index 3735abd7f8f6f067488b20de9b44ab487ac2dff2..cbf5d59d5d6a8943edd6c74a0f1e6013aa640c19 100644 (file)
@@ -60,7 +60,7 @@
        ENTRY_SAME(fork_wrapper)
        ENTRY_SAME(read)
        ENTRY_SAME(write)
-       ENTRY_SAME(open)                /* 5 */
+       ENTRY_COMP(open)                /* 5 */
        ENTRY_SAME(close)
        ENTRY_SAME(waitpid)
        ENTRY_SAME(creat)
index 7ab286ab5300accb706fb72a2e343153cae85d18..39ed65a44c5fac5fc996b2d5ec25effbbf9853fa 100644 (file)
                        interrupts = <2 7 0>;
                };
 
+               sclpc@3c00 {
+                       compatible = "fsl,mpc5200-lpbfifo";
+                       reg = <0x3c00 0x60>;
+                       interrupts = <2 23 0>;
+               };
+
                i2c@3d00 {
                        #address-cells = <1>;
                        #size-cells = <0>;
index 3444eb8f0ade62305d0a935ca50a02d1fca16933..24f668039295b1b95ff279ff91974a7ad65582ff 100644 (file)
                                reg = <0>;
                        };
                };
-
-               sclpc@3c00 {
-                       compatible = "fsl,mpc5200-lpbfifo";
-                       reg = <0x3c00 0x60>;
-                       interrupts = <3 23 0>;
-               };
        };
 
        localbus {
index 9e354997eb7e3ccc29ac70ee5e7a31c3ce319b01..96512c05803336d937cabcf5b06aa86e43bc538b 100644 (file)
@@ -59,7 +59,7 @@
                        #gpio-cells = <2>;
                };
 
-               psc@2000 { /* PSC1 in ac97 mode */
+               audioplatform: psc@2000 { /* PSC1 in ac97 mode */
                        compatible = "mpc5200b-psc-ac97","fsl,mpc5200b-psc-ac97";
                        cell-index = <0>;
                };
        localbus {
                status = "disabled";
        };
+
+       sound {
+               compatible = "phytec,pcm030-audio-fabric";
+               asoc-platform = <&audioplatform>;
+       };
 };
index 78160874809a1e1e5faf8b049baec80a7bd24545..e27e9ad6818ea815164734711e1eb048e52ab5a2 100644 (file)
@@ -172,6 +172,7 @@ static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
 {
        struct dma_map_ops *dma_ops = get_dma_ops(dev);
 
+       debug_dma_mapping_error(dev, dma_addr);
        if (dma_ops->mapping_error)
                return dma_ops->mapping_error(dev, dma_addr);
 
index 8520b58a5e9a0f0027a95f0df2662cbab898c5cc..b89ef65392dc229b4ec026e23ddd9c5228ed05f1 100644 (file)
@@ -372,10 +372,11 @@ static int mpc52xx_irqhost_map(struct irq_domain *h, unsigned int virq,
        case MPC52xx_IRQ_L1_MAIN: irqchip = &mpc52xx_main_irqchip; break;
        case MPC52xx_IRQ_L1_PERP: irqchip = &mpc52xx_periph_irqchip; break;
        case MPC52xx_IRQ_L1_SDMA: irqchip = &mpc52xx_sdma_irqchip; break;
-       default:
-               pr_err("%s: invalid irq: virq=%i, l1=%i, l2=%i\n",
-                      __func__, virq, l1irq, l2irq);
-               return -EINVAL;
+       case MPC52xx_IRQ_L1_CRIT:
+               pr_warn("%s: Critical IRQ #%d is unsupported! Nopping it.\n",
+                       __func__, l2irq);
+               irq_set_chip(virq, &no_irq_chip);
+               return 0;
        }
 
        irq_set_chip_and_handler(virq, irqchip, handle_level_irq);
index 797cd181dc3f615fab312df9ccce4813263eedf4..d16c8ded10847ce19d67f26a39179587707ddbf0 100644 (file)
@@ -449,7 +449,7 @@ int eeh_rmv_from_parent_pe(struct eeh_dev *edev, int purge_pe)
                        if (list_empty(&pe->edevs)) {
                                cnt = 0;
                                list_for_each_entry(child, &pe->child_list, child) {
-                                       if (!(pe->type & EEH_PE_INVALID)) {
+                                       if (!(child->type & EEH_PE_INVALID)) {
                                                cnt++;
                                                break;
                                        }
index d19f4977c83492e1174be5456e1d0ff7ee33ca33..e5b084723131cc1ef0b6260f2a571f7071ee5995 100644 (file)
@@ -220,7 +220,8 @@ static struct device_node *find_pe_dn(struct pci_dev *dev, int *total)
 
        /* Get the top level device in the PE */
        edev = of_node_to_eeh_dev(dn);
-       edev = list_first_entry(&edev->pe->edevs, struct eeh_dev, list);
+       if (edev->pe)
+               edev = list_first_entry(&edev->pe->edevs, struct eeh_dev, list);
        dn = eeh_dev_to_of_node(edev);
        if (!dn)
                return NULL;
index ad79b846535c4d9345e884341f40481e9d38c492..827e094a2f494d09bdf1936cde25df431ec7c012 100644 (file)
@@ -28,7 +28,7 @@ ENTRY(sys32_open_wrapper)
        llgtr   %r2,%r2                 # const char *
        lgfr    %r3,%r3                 # int
        lgfr    %r4,%r4                 # int
-       jg      sys_open                # branch to system call
+       jg      compat_sys_open         # branch to system call
 
 ENTRY(sys32_close_wrapper)
        llgfr   %r2,%r2                 # unsigned int
index c268bbf8b41047b2717a5a41a7ed86178a7df24e..02353bde92d883c3aeb0557ba423e0e3c16edfad 100644 (file)
@@ -148,7 +148,6 @@ score_rt_sigreturn(struct pt_regs *regs)
 {
        struct rt_sigframe __user *frame;
        sigset_t set;
-       stack_t st;
        int sig;
 
        /* Always make any pending restarted system calls return -EINTR */
@@ -168,12 +167,10 @@ score_rt_sigreturn(struct pt_regs *regs)
        else if (sig)
                force_sig(sig, current);
 
-       if (__copy_from_user(&st, &frame->rs_uc.uc_stack, sizeof(st)))
-               goto badframe;
-
        /* It is more difficult to avoid calling this function than to
           call it and ignore errors.  */
-       do_sigaltstack((stack_t __user *)&st, NULL, regs->regs[0]);
+       if (do_sigaltstack(&frame->rs_uc.uc_stack, NULL, regs->regs[0]) == -EFAULT)
+               goto badframe;
        regs->is_syscall = 0;
 
        __asm__ __volatile__(
index 8bd965e00a159c2ae6f45af71b8804da23f84c98..b437f2c780b83f6c84d427f18af4416fa9e42fd7 100644 (file)
@@ -46,6 +46,7 @@ static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
 {
        struct dma_map_ops *ops = get_dma_ops(dev);
 
+       debug_dma_mapping_error(dev, dma_addr);
        if (ops->mapping_error)
                return ops->mapping_error(dev, dma_addr);
 
index 23853814bd174284a3a75c62b88154ac8fb890d3..d867cd95a62261c7ae25a91b4ce5d36b179b8f0f 100644 (file)
@@ -347,7 +347,6 @@ asmlinkage int sys_rt_sigreturn(unsigned long r2, unsigned long r3,
 {
        struct rt_sigframe __user *frame = (struct rt_sigframe __user *) (long) REF_REG_SP;
        sigset_t set;
-       stack_t __user st;
        long long ret;
 
        /* Always make any pending restarted system calls return -EINTR */
@@ -365,11 +364,10 @@ asmlinkage int sys_rt_sigreturn(unsigned long r2, unsigned long r3,
                goto badframe;
        regs->pc -= 4;
 
-       if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st)))
-               goto badframe;
        /* It is more difficult to avoid calling this function than to
           call it and ignore errors.  */
-       do_sigaltstack(&st, NULL, REF_REG_SP);
+       if (do_sigaltstack(&frame->uc.uc_stack, NULL, REF_REG_SP) == -EFAULT)
+               goto badframe;
 
        return (int) ret;
 
index c0a798fcf030ab7903d0508d0202d1a813cb52ca..bb7c95161d7188f5defd780ddec934b0395b48b0 100644 (file)
@@ -81,18 +81,18 @@ static void usage(void)
 
 static int start_line(const char *line)
 {
-       if (strcmp(line + 8, " T _start\n") == 0)
+       if (strcmp(line + 10, " _start\n") == 0)
                return 1;
-       else if (strcmp(line + 16, " T _start\n") == 0)
+       else if (strcmp(line + 18, " _start\n") == 0)
                return 1;
        return 0;
 }
 
 static int end_line(const char *line)
 {
-       if (strcmp(line + 8, " A _end\n") == 0)
+       if (strcmp(line + 10, " _end\n") == 0)
                return 1;
-       else if (strcmp (line + 16, " A _end\n") == 0)
+       else if (strcmp (line + 18, " _end\n") == 0)
                return 1;
        return 0;
 }
@@ -100,8 +100,8 @@ static int end_line(const char *line)
 /*
  * Find address for start and end in System.map.
  * The file looks like this:
- * f0004000 T _start
- * f0379f79 A _end
+ * f0004000 ... _start
+ * f0379f79 ... _end
  * 1234567890123456
  * ^coloumn 1
  * There is support for 64 bit addresses too.
index 8493fd3c7ba5a5ea39364948c26ecdd4feef41b8..05fe53f5346e2750d1d04b945741c06f6373f7ef 100644 (file)
@@ -59,6 +59,7 @@ static inline void dma_free_attrs(struct device *dev, size_t size,
 
 static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
 {
+       debug_dma_mapping_error(dev, dma_addr);
        return (dma_addr == DMA_ERROR_CODE);
 }
 
index f93003123bce01119544ef88b15b3e479fbf92cd..67c62578d17043bbff42e1880f1f7e8986cb971c 100644 (file)
@@ -63,10 +63,13 @@ extern char *of_console_options;
 extern void irq_trans_init(struct device_node *dp);
 extern char *build_path_component(struct device_node *dp);
 
-/* SPARC has a local implementation */
+/* SPARC has local implementations */
 extern int of_address_to_resource(struct device_node *dev, int index,
                                  struct resource *r);
 #define of_address_to_resource of_address_to_resource
 
+void __iomem *of_iomap(struct device_node *node, int index);
+#define of_iomap of_iomap
+
 #endif /* __KERNEL__ */
 #endif /* _SPARC_PROM_H */
index 867de2f8189c32acf359fe5575cd139ede6b7048..689e1ba628097e12ab95496d60df2225817483d3 100644 (file)
@@ -295,9 +295,7 @@ void do_rt_sigreturn(struct pt_regs *regs)
                err |= restore_fpu_state(regs, fpu_save);
 
        err |= __copy_from_user(&set, &sf->mask, sizeof(sigset_t));
-       err |= do_sigaltstack(&sf->stack, NULL, (unsigned long)sf);
-
-       if (err)
+       if (err || do_sigaltstack(&sf->stack, NULL, (unsigned long)sf) == -EFAULT)
                goto segv;
 
        err |= __get_user(rwin_save, &sf->rwin_save);
index 44025f4ba41f883d61647f180575651ee5113645..8475a474273ae1c615ce4277dd3bf74ba1ce9f0a 100644 (file)
@@ -47,7 +47,7 @@ STUB: sra     REG1, 0, REG1; \
        sra     REG4, 0, REG4
 
 SIGN1(sys32_exit, sparc_exit, %o0)
-SIGN1(sys32_exit_group, sys_exit_group, %o0)
+SIGN1(sys32_exit_group, sparc_exit_group, %o0)
 SIGN1(sys32_wait4, compat_sys_wait4, %o2)
 SIGN1(sys32_creat, sys_creat, %o1)
 SIGN1(sys32_mknod, sys_mknod, %o1)
index 7f5f65d0b3fde92235c838bd976916bc863d0315..bf2347794e3323c3220c92e4a96849d8c89d5fbf 100644 (file)
@@ -118,10 +118,20 @@ ret_from_syscall:
        ba,pt   %xcc, ret_sys_call
         ldx    [%sp + PTREGS_OFF + PT_V9_I0], %o0
 
+       .globl  sparc_exit_group
+       .type   sparc_exit_group,#function
+sparc_exit_group:
+       sethi   %hi(sys_exit_group), %g7
+       ba,pt   %xcc, 1f
+        or     %g7, %lo(sys_exit_group), %g7
+       .size   sparc_exit_group,.-sparc_exit_group
+
        .globl  sparc_exit
        .type   sparc_exit,#function
 sparc_exit:
-       rdpr    %pstate, %g2
+       sethi   %hi(sys_exit), %g7
+       or      %g7, %lo(sys_exit), %g7
+1:     rdpr    %pstate, %g2
        wrpr    %g2, PSTATE_IE, %pstate
        rdpr    %otherwin, %g1
        rdpr    %cansave, %g3
@@ -129,7 +139,7 @@ sparc_exit:
        wrpr    %g3, 0x0, %cansave
        wrpr    %g0, 0x0, %otherwin
        wrpr    %g2, 0x0, %pstate
-       ba,pt   %xcc, sys_exit
+       jmpl    %g7, %g0
         stb    %g0, [%g6 + TI_WSAVED]
        .size   sparc_exit,.-sparc_exit
 
index 1c9af9fa38e9b0b489cb38899685e4c4c76b6584..017b74a63dcb995dd9c18049bd1a1604d329fea5 100644 (file)
@@ -133,7 +133,7 @@ sys_call_table:
 /*170*/        .word sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr, sys_getdents
        .word sys_setsid, sys_fchdir, sys_fgetxattr, sys_listxattr, sys_llistxattr
 /*180*/        .word sys_flistxattr, sys_removexattr, sys_lremovexattr, sys_nis_syscall, sys_ni_syscall
-       .word sys_setpgid, sys_fremovexattr, sys_tkill, sys_exit_group, sys_newuname
+       .word sys_setpgid, sys_fremovexattr, sys_tkill, sparc_exit_group, sys_newuname
 /*190*/        .word sys_init_module, sys_sparc64_personality, sys_remap_file_pages, sys_epoll_create, sys_epoll_ctl
        .word sys_epoll_wait, sys_ioprio_set, sys_getppid, sys_nis_syscall, sys_sgetmask
 /*200*/        .word sys_ssetmask, sys_nis_syscall, sys_newlstat, sys_uselib, sys_nis_syscall
index 4b6247d1a315ae24331887a146758bcdbec8e570..f2ff191376b4c0b1956836560e5cf9f9299d9e25 100644 (file)
@@ -72,6 +72,7 @@ static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
 static inline int
 dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
 {
+       debug_dma_mapping_error(dev, dma_addr);
        return get_dma_ops(dev)->mapping_error(dev, dma_addr);
 }
 
index 3a8ece7d09ca2015b3e2c218a3e7a84e951d9bee..0d7103c9eff3d21c29f15f2f54d5aeabcb0a8449 100644 (file)
@@ -32,13 +32,14 @@ void flush_thread(void)
                       "err = %d\n", ret);
                force_sig(SIGKILL, current);
        }
+       get_safe_registers(current_pt_regs()->regs.gp,
+                          current_pt_regs()->regs.fp);
 
        __switch_mm(&current->mm->context.id);
 }
 
 void start_thread(struct pt_regs *regs, unsigned long eip, unsigned long esp)
 {
-       get_safe_registers(regs->regs.gp, regs->regs.fp);
        PT_REGS_IP(regs) = eip;
        PT_REGS_SP(regs) = esp;
        current->ptrace &= ~PT_DTRACE;
index c760e073963ed59004f66ed65aade6355c852da9..e87b0cac14b5e5d735ab21f9f3b163db52349938 100644 (file)
@@ -12,6 +12,8 @@
 #include <asm/setup.h>
 #include <asm/desc.h>
 
+#undef memcpy                  /* Use memcpy from misc.c */
+
 #include "eboot.h"
 
 static efi_system_table_t *sys_table;
index 2a017441b8b2ebc665a24a001f5d635f7dbc9955..8c132a625b94991c179def21973bb8ad3c3a56d5 100644 (file)
@@ -476,6 +476,3 @@ die:
 setup_corrupt:
        .byte   7
        .string "No setup signature found...\n"
-
-       .data
-dummy: .long   0
index 66e5f0ef0523ce2961a950c4657719e31c3e8db1..79fd8a3418f9d5cca461bef7fa0fb874c0d69aee 100644 (file)
@@ -12,6 +12,7 @@ header-y += mce.h
 header-y += msr-index.h
 header-y += msr.h
 header-y += mtrr.h
+header-y += perf_regs.h
 header-y += posix_types_32.h
 header-y += posix_types_64.h
 header-y += posix_types_x32.h
@@ -19,8 +20,10 @@ header-y += prctl.h
 header-y += processor-flags.h
 header-y += ptrace-abi.h
 header-y += sigcontext32.h
+header-y += svm.h
 header-y += ucontext.h
 header-y += vm86.h
+header-y += vmx.h
 header-y += vsyscall.h
 
 genhdr-y += unistd_32.h
index f7b4c7903e7e51eb317ecfcd6fa9be05a3336f65..808dae63eeea6f73eb312d4f5b7f77cf4e869e6c 100644 (file)
@@ -47,6 +47,7 @@ static inline struct dma_map_ops *get_dma_ops(struct device *dev)
 static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
 {
        struct dma_map_ops *ops = get_dma_ops(dev);
+       debug_dma_mapping_error(dev, dma_addr);
        if (ops->mapping_error)
                return ops->mapping_error(dev, dma_addr);
 
index 831dbb9c6c028537402bd65d46e94320a70ee7de..41ab26ea65648b43a910f97cd7903c8bbbc2516c 100644 (file)
@@ -399,14 +399,17 @@ static inline void drop_init_fpu(struct task_struct *tsk)
 typedef struct { int preload; } fpu_switch_t;
 
 /*
- * FIXME! We could do a totally lazy restore, but we need to
- * add a per-cpu "this was the task that last touched the FPU
- * on this CPU" variable, and the task needs to have a "I last
- * touched the FPU on this CPU" and check them.
+ * Must be run with preemption disabled: this clears the fpu_owner_task,
+ * on this CPU.
  *
- * We don't do that yet, so "fpu_lazy_restore()" always returns
- * false, but some day..
+ * This will disable any lazy FPU state restore of the current FPU state,
+ * but if the current thread owns the FPU, it will still be saved by.
  */
+static inline void __cpu_disable_lazy_restore(unsigned int cpu)
+{
+       per_cpu(fpu_owner_task, cpu) = NULL;
+}
+
 static inline int fpu_lazy_restore(struct task_struct *new, unsigned int cpu)
 {
        return new == this_cpu_read_stable(fpu_owner_task) &&
index dcfde52979c3e63be0d42627cc567cf76c733090..19f16ebaf4fa826216c7858d224365b2fdb74670 100644 (file)
@@ -205,21 +205,14 @@ static inline bool user_64bit_mode(struct pt_regs *regs)
 }
 #endif
 
-/*
- * X86_32 CPUs don't save ss and esp if the CPU is already in kernel mode
- * when it traps.  The previous stack will be directly underneath the saved
- * registers, and 'sp/ss' won't even have been saved. Thus the '&regs->sp'.
- *
- * This is valid only for kernel mode traps.
- */
-static inline unsigned long kernel_stack_pointer(struct pt_regs *regs)
-{
 #ifdef CONFIG_X86_32
-       return (unsigned long)(&regs->sp);
+extern unsigned long kernel_stack_pointer(struct pt_regs *regs);
 #else
+static inline unsigned long kernel_stack_pointer(struct pt_regs *regs)
+{
        return regs->sp;
-#endif
 }
+#endif
 
 #define GET_IP(regs) ((regs)->ip)
 #define GET_FP(regs) ((regs)->bp)
index f7e98a2c0d123ae0ebe7f61f1521f7dd7090a335..1b7d1656a042ff5e1886c6fff40bbde1ff3a472d 100644 (file)
@@ -631,6 +631,20 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c)
                }
        }
 
+       /*
+        * The way access filter has a performance penalty on some workloads.
+        * Disable it on the affected CPUs.
+        */
+       if ((c->x86 == 0x15) &&
+           (c->x86_model >= 0x02) && (c->x86_model < 0x20)) {
+               u64 val;
+
+               if (!rdmsrl_safe(0xc0011021, &val) && !(val & 0x1E)) {
+                       val |= 0x1E;
+                       wrmsrl_safe(0xc0011021, val);
+               }
+       }
+
        cpu_detect_cache_sizes(c);
 
        /* Multi core CPU? */
index 698b6ec12e0f40f9c292b9f84206b38214d9fe7e..1ac581f38dfa2771ba054c980cd9163546e8c9db 100644 (file)
@@ -6,7 +6,7 @@
  *
  *  Written by Jacob Shin - AMD, Inc.
  *
- *  Support: borislav.petkov@amd.com
+ *  Maintained by: Borislav Petkov <bp@alien8.de>
  *
  *  April 2006
  *     - added support for AMD Family 0x10 processors
index 5f88abf07e9ccc2237b27fea29c57b4b59315a64..4f9a3cbfc4a33fb801ab1bf2c822a83e76122897 100644 (file)
@@ -285,34 +285,39 @@ void cmci_clear(void)
        raw_spin_unlock_irqrestore(&cmci_discover_lock, flags);
 }
 
+static long cmci_rediscover_work_func(void *arg)
+{
+       int banks;
+
+       /* Recheck banks in case CPUs don't all have the same */
+       if (cmci_supported(&banks))
+               cmci_discover(banks);
+
+       return 0;
+}
+
 /*
  * After a CPU went down cycle through all the others and rediscover
  * Must run in process context.
  */
 void cmci_rediscover(int dying)
 {
-       int banks;
-       int cpu;
-       cpumask_var_t old;
+       int cpu, banks;
 
        if (!cmci_supported(&banks))
                return;
-       if (!alloc_cpumask_var(&old, GFP_KERNEL))
-               return;
-       cpumask_copy(old, &current->cpus_allowed);
 
        for_each_online_cpu(cpu) {
                if (cpu == dying)
                        continue;
-               if (set_cpus_allowed_ptr(current, cpumask_of(cpu)))
+
+               if (cpu == smp_processor_id()) {
+                       cmci_rediscover_work_func(NULL);
                        continue;
-               /* Recheck banks in case CPUs don't all have the same */
-               if (cmci_supported(&banks))
-                       cmci_discover(banks);
-       }
+               }
 
-       set_cpus_allowed_ptr(current, old);
-       free_cpumask_var(old);
+               work_on_cpu(cpu, cmci_rediscover_work_func, NULL);
+       }
 }
 
 /*
index b51b2c7ee51fcbc3738ed8bd05fb4fd67d9fe1ab..1328fe49a3f14d7a33615e892efca8d110aeb6e6 100644 (file)
@@ -995,8 +995,8 @@ END(interrupt)
         */
        .p2align CONFIG_X86_L1_CACHE_SHIFT
 common_interrupt:
-       ASM_CLAC
        XCPT_FRAME
+       ASM_CLAC
        addq $-0x80,(%rsp)              /* Adjust vector to [-256,-1] range */
        interrupt do_IRQ
        /* 0(%rsp): old_rsp-ARGOFFSET */
@@ -1135,8 +1135,8 @@ END(common_interrupt)
  */
 .macro apicinterrupt num sym do_sym
 ENTRY(\sym)
-       ASM_CLAC
        INTR_FRAME
+       ASM_CLAC
        pushq_cfi $~(\num)
 .Lcommon_\sym:
        interrupt \do_sym
@@ -1190,8 +1190,8 @@ apicinterrupt IRQ_WORK_VECTOR \
  */
 .macro zeroentry sym do_sym
 ENTRY(\sym)
-       ASM_CLAC
        INTR_FRAME
+       ASM_CLAC
        PARAVIRT_ADJUST_EXCEPTION_FRAME
        pushq_cfi $-1           /* ORIG_RAX: no syscall to restart */
        subq $ORIG_RAX-R15, %rsp
@@ -1208,8 +1208,8 @@ END(\sym)
 
 .macro paranoidzeroentry sym do_sym
 ENTRY(\sym)
-       ASM_CLAC
        INTR_FRAME
+       ASM_CLAC
        PARAVIRT_ADJUST_EXCEPTION_FRAME
        pushq_cfi $-1           /* ORIG_RAX: no syscall to restart */
        subq $ORIG_RAX-R15, %rsp
@@ -1227,8 +1227,8 @@ END(\sym)
 #define INIT_TSS_IST(x) PER_CPU_VAR(init_tss) + (TSS_ist + ((x) - 1) * 8)
 .macro paranoidzeroentry_ist sym do_sym ist
 ENTRY(\sym)
-       ASM_CLAC
        INTR_FRAME
+       ASM_CLAC
        PARAVIRT_ADJUST_EXCEPTION_FRAME
        pushq_cfi $-1           /* ORIG_RAX: no syscall to restart */
        subq $ORIG_RAX-R15, %rsp
@@ -1247,8 +1247,8 @@ END(\sym)
 
 .macro errorentry sym do_sym
 ENTRY(\sym)
-       ASM_CLAC
        XCPT_FRAME
+       ASM_CLAC
        PARAVIRT_ADJUST_EXCEPTION_FRAME
        subq $ORIG_RAX-R15, %rsp
        CFI_ADJUST_CFA_OFFSET ORIG_RAX-R15
@@ -1266,8 +1266,8 @@ END(\sym)
        /* error code is on the stack already */
 .macro paranoiderrorentry sym do_sym
 ENTRY(\sym)
-       ASM_CLAC
        XCPT_FRAME
+       ASM_CLAC
        PARAVIRT_ADJUST_EXCEPTION_FRAME
        subq $ORIG_RAX-R15, %rsp
        CFI_ADJUST_CFA_OFFSET ORIG_RAX-R15
index 957a47aec64e12d1833af368c337e4b4e03f56bd..4dac2f68ed4aaf2bf35e10687dbdf44234829347 100644 (file)
@@ -292,8 +292,8 @@ default_entry:
  *     be using the global pages. 
  *
  *     NOTE! If we are on a 486 we may have no cr4 at all!
- *     Specifically, cr4 exists if and only if CPUID exists,
- *     which in turn exists if and only if EFLAGS.ID exists.
+ *     Specifically, cr4 exists if and only if CPUID exists
+ *     and has flags other than the FPU flag set.
  */
        movl $X86_EFLAGS_ID,%ecx
        pushl %ecx
@@ -308,6 +308,11 @@ default_entry:
        testl %ecx,%eax
        jz 6f                   # No ID flag = no CPUID = no CR4
 
+       movl $1,%eax
+       cpuid
+       andl $~1,%edx           # Ignore CPUID.FPU
+       jz 6f                   # No flags or only CPUID.FPU = no CR4
+
        movl pa(mmu_cr4_features),%eax
        movl %eax,%cr4
 
index 7720ff5a9ee292a449ad13a9347e603def50df53..efdec7cd8e01057aeee63c95b16713c4803c7e61 100644 (file)
@@ -8,8 +8,8 @@
  *  Tigran Aivazian <tigran@aivazian.fsnet.co.uk>
  *
  *  Maintainers:
- *  Andreas Herrmann <andreas.herrmann3@amd.com>
- *  Borislav Petkov <borislav.petkov@amd.com>
+ *  Andreas Herrmann <herrmann.der.user@googlemail.com>
+ *  Borislav Petkov <bp@alien8.de>
  *
  *  This driver allows to upgrade microcode on F10h AMD
  *  CPUs and later.
@@ -190,6 +190,7 @@ static unsigned int verify_patch_size(int cpu, u32 patch_size,
 #define F1XH_MPB_MAX_SIZE 2048
 #define F14H_MPB_MAX_SIZE 1824
 #define F15H_MPB_MAX_SIZE 4096
+#define F16H_MPB_MAX_SIZE 3458
 
        switch (c->x86) {
        case 0x14:
@@ -198,6 +199,9 @@ static unsigned int verify_patch_size(int cpu, u32 patch_size,
        case 0x15:
                max_size = F15H_MPB_MAX_SIZE;
                break;
+       case 0x16:
+               max_size = F16H_MPB_MAX_SIZE;
+               break;
        default:
                max_size = F1XH_MPB_MAX_SIZE;
                break;
index b00b33a183908bdb201aa38266e40ad87d89754d..974b67e46dd0edeb38bbffcc77442d4f57e514d5 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/perf_event.h>
 #include <linux/hw_breakpoint.h>
 #include <linux/rcupdate.h>
+#include <linux/module.h>
 
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
@@ -166,6 +167,35 @@ static inline bool invalid_selector(u16 value)
 
 #define FLAG_MASK              FLAG_MASK_32
 
+/*
+ * X86_32 CPUs don't save ss and esp if the CPU is already in kernel mode
+ * when it traps.  The previous stack will be directly underneath the saved
+ * registers, and 'sp/ss' won't even have been saved. Thus the '&regs->sp'.
+ *
+ * Now, if the stack is empty, '&regs->sp' is out of range. In this
+ * case we try to take the previous stack. To always return a non-null
+ * stack pointer we fall back to regs as stack if no previous stack
+ * exists.
+ *
+ * This is valid only for kernel mode traps.
+ */
+unsigned long kernel_stack_pointer(struct pt_regs *regs)
+{
+       unsigned long context = (unsigned long)regs & ~(THREAD_SIZE - 1);
+       unsigned long sp = (unsigned long)&regs->sp;
+       struct thread_info *tinfo;
+
+       if (context == (sp & ~(THREAD_SIZE - 1)))
+               return sp;
+
+       tinfo = (struct thread_info *)context;
+       if (tinfo->previous_esp)
+               return tinfo->previous_esp;
+
+       return (unsigned long)regs;
+}
+EXPORT_SYMBOL_GPL(kernel_stack_pointer);
+
 static unsigned long *pt_regs_access(struct pt_regs *regs, unsigned long regno)
 {
        BUILD_BUG_ON(offsetof(struct pt_regs, bx) != 0);
@@ -1511,6 +1541,13 @@ void syscall_trace_leave(struct pt_regs *regs)
 {
        bool step;
 
+       /*
+        * We may come here right after calling schedule_user()
+        * or do_notify_resume(), in which case we can be in RCU
+        * user mode.
+        */
+       rcu_user_exit();
+
        audit_syscall_exit(regs);
 
        if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
index c80a33bc528b8e33ec6a1b9b4e6ca02964c21d7e..f3e2ec878b8c3ecad60901a2818d0ad30eeb29ca 100644 (file)
@@ -68,6 +68,8 @@
 #include <asm/mwait.h>
 #include <asm/apic.h>
 #include <asm/io_apic.h>
+#include <asm/i387.h>
+#include <asm/fpu-internal.h>
 #include <asm/setup.h>
 #include <asm/uv/uv.h>
 #include <linux/mc146818rtc.h>
@@ -818,6 +820,9 @@ int __cpuinit native_cpu_up(unsigned int cpu, struct task_struct *tidle)
 
        per_cpu(cpu_state, cpu) = CPU_UP_PREPARE;
 
+       /* the FPU context is blank, nobody can own it */
+       __cpu_disable_lazy_restore(cpu);
+
        err = do_boot_cpu(apicid, cpu, tidle);
        if (err) {
                pr_debug("do_boot_cpu failed %d\n", err);
index 39171cb307ea05d6687bfc083ddd87935cf4ca4d..bba39bfa1c4b03806cf1f42773cd8041f18b8759 100644 (file)
@@ -426,8 +426,7 @@ static void invalidate_registers(struct x86_emulate_ctxt *ctxt)
                        _ASM_EXTABLE(1b, 3b)                            \
                        : "=m" ((ctxt)->eflags), "=&r" (_tmp),          \
                          "+a" (*rax), "+d" (*rdx), "+qm"(_ex)          \
-                       : "i" (EFLAGS_MASK), "m" ((ctxt)->src.val),     \
-                         "a" (*rax), "d" (*rdx));                      \
+                       : "i" (EFLAGS_MASK), "m" ((ctxt)->src.val));    \
        } while (0)
 
 /* instruction has only one source operand, destination is implicit (e.g. mul, div, imul, idiv) */
index 0777f042e4002e695b316c99889b594daebc5448..60f926cd8b0edbf44277a18718dd86cb4a077bd1 100644 (file)
@@ -197,7 +197,7 @@ void flush_tlb_mm_range(struct mm_struct *mm, unsigned long start,
        }
 
        if (end == TLB_FLUSH_ALL || tlb_flushall_shift == -1
-                                       || vmflag == VM_HUGETLB) {
+                                       || vmflag & VM_HUGETLB) {
                local_flush_tlb();
                goto flush_all;
        }
index 41bd2a2d2c50f61a4948f954f296631c8dfd7961..b914e20b5a0033c7cb856c1e82eeea207187eb07 100644 (file)
@@ -115,6 +115,16 @@ static void sata_revid_read(struct sim_dev_reg *reg, u32 *value)
        reg_read(reg, value);
 }
 
+static void reg_noirq_read(struct sim_dev_reg *reg, u32 *value)
+{
+       unsigned long flags;
+
+       raw_spin_lock_irqsave(&pci_config_lock, flags);
+       /* force interrupt pin value to 0 */
+       *value = reg->sim_reg.value & 0xfff00ff;
+       raw_spin_unlock_irqrestore(&pci_config_lock, flags);
+}
+
 static struct sim_dev_reg bus1_fixups[] = {
        DEFINE_REG(2, 0, 0x10, (16*MB), reg_init, reg_read, reg_write)
        DEFINE_REG(2, 0, 0x14, (256), reg_init, reg_read, reg_write)
@@ -144,6 +154,7 @@ static struct sim_dev_reg bus1_fixups[] = {
        DEFINE_REG(11, 5, 0x10, (64*KB), reg_init, reg_read, reg_write)
        DEFINE_REG(11, 6, 0x10, (256), reg_init, reg_read, reg_write)
        DEFINE_REG(11, 7, 0x10, (64*KB), reg_init, reg_read, reg_write)
+       DEFINE_REG(11, 7, 0x3c, 256, reg_init, reg_noirq_read, reg_write)
        DEFINE_REG(12, 0, 0x10, (128*KB), reg_init, reg_read, reg_write)
        DEFINE_REG(12, 0, 0x14, (256), reg_init, reg_read, reg_write)
        DEFINE_REG(12, 1, 0x10, (1024), reg_init, reg_read, reg_write)
@@ -161,8 +172,10 @@ static struct sim_dev_reg bus1_fixups[] = {
        DEFINE_REG(16, 0, 0x10, (64*KB), reg_init, reg_read, reg_write)
        DEFINE_REG(16, 0, 0x14, (64*MB), reg_init, reg_read, reg_write)
        DEFINE_REG(16, 0, 0x18, (64*MB), reg_init, reg_read, reg_write)
+       DEFINE_REG(16, 0, 0x3c, 256, reg_init, reg_noirq_read, reg_write)
        DEFINE_REG(17, 0, 0x10, (128*KB), reg_init, reg_read, reg_write)
        DEFINE_REG(18, 0, 0x10, (1*KB), reg_init, reg_read, reg_write)
+       DEFINE_REG(18, 0, 0x3c, 256, reg_init, reg_noirq_read, reg_write)
 };
 
 static void __init init_sim_regs(void)
index 4c61b52191eb293bcaef2cac2380c6114cdaefcf..92525cb8e54c84c0ebe6b2caeacb47f4f8ab299b 100644 (file)
 #include <asm/i8259.h>
 #include <asm/io.h>
 #include <asm/io_apic.h>
+#include <asm/emergency-restart.h>
 
 static int ce4100_i8042_detect(void)
 {
        return 0;
 }
 
+/*
+ * The CE4100 platform has an internal 8051 Microcontroller which is
+ * responsible for signaling to the external Power Management Unit the
+ * intention to reset, reboot or power off the system. This 8051 device has
+ * its command register mapped at I/O port 0xcf9 and the value 0x4 is used
+ * to power off the system.
+ */
+static void ce4100_power_off(void)
+{
+       outb(0x4, 0xcf9);
+}
+
 #ifdef CONFIG_SERIAL_8250
 
 static unsigned int mem_serial_in(struct uart_port *p, int offset)
@@ -139,8 +152,19 @@ void __init x86_ce4100_early_setup(void)
        x86_init.mpparse.find_smp_config = x86_init_noop;
        x86_init.pci.init = ce4100_pci_init;
 
+       /*
+        * By default, the reboot method is ACPI which is supported by the
+        * CE4100 bootloader CEFDK using FADT.ResetReg Address and ResetValue
+        * the bootloader will however issue a system power off instead of
+        * reboot. By using BOOT_KBD we ensure proper system reboot as
+        * expected.
+        */
+       reboot_type = BOOT_KBD;
+
 #ifdef CONFIG_X86_IO_APIC
        x86_init.pci.init_irq = sdv_pci_init;
        x86_init.mpparse.setup_ioapic_ids = setup_ioapic_ids_from_mpc_nocheck;
 #endif
+
+       pm_power_off = ce4100_power_off;
 }
index 8b6dc5bd4dd061336172b144ae8c09da6bbc56f8..f71eac35c1b942005f3973fd9c919091b9b08bbd 100644 (file)
@@ -52,11 +52,17 @@ void blk_execute_rq_nowait(struct request_queue *q, struct gendisk *bd_disk,
                           rq_end_io_fn *done)
 {
        int where = at_head ? ELEVATOR_INSERT_FRONT : ELEVATOR_INSERT_BACK;
+       bool is_pm_resume;
 
        WARN_ON(irqs_disabled());
 
        rq->rq_disk = bd_disk;
        rq->end_io = done;
+       /*
+        * need to check this before __blk_run_queue(), because rq can
+        * be freed before that returns.
+        */
+       is_pm_resume = rq->cmd_type == REQ_TYPE_PM_RESUME;
 
        spin_lock_irq(q->queue_lock);
 
@@ -71,7 +77,7 @@ void blk_execute_rq_nowait(struct request_queue *q, struct gendisk *bd_disk,
        __elv_add_request(q, rq, where);
        __blk_run_queue(q);
        /* the queue is stopped so it won't be run */
-       if (rq->cmd_type == REQ_TYPE_PM_RESUME)
+       if (is_pm_resume)
                q->request_fn(q);
        spin_unlock_irq(q->queue_lock);
 }
index b1ae48054dc5773eab42917d5e9d10f9764602ae..b7078afddb74fe91c403642cf4679beec06c0ef9 100644 (file)
@@ -238,7 +238,7 @@ static int __devexit ahci_remove(struct platform_device *pdev)
        return 0;
 }
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static int ahci_suspend(struct device *dev)
 {
        struct ahci_platform_data *pdata = dev_get_platdata(dev);
index fd9ecf74e631afc800e56927069d97bd61774862..5b0ba3f20edcfd4603538ce7505d69dd93f8bb29 100644 (file)
@@ -1105,10 +1105,15 @@ static int ata_acpi_bind_device(struct ata_port *ap, struct scsi_device *sdev,
        struct acpi_device *acpi_dev;
        struct acpi_device_power_state *states;
 
-       if (ap->flags & ATA_FLAG_ACPI_SATA)
-               ata_dev = &ap->link.device[sdev->channel];
-       else
+       if (ap->flags & ATA_FLAG_ACPI_SATA) {
+               if (!sata_pmp_attached(ap))
+                       ata_dev = &ap->link.device[sdev->id];
+               else
+                       ata_dev = &ap->pmp_link[sdev->channel].device[sdev->id];
+       }
+       else {
                ata_dev = &ap->link.device[sdev->id];
+       }
 
        *handle = ata_dev_acpi_handle(ata_dev);
 
index 3cc7096cfda758e9b3ffd514aaf6e70928ec7f8d..f46fbd3bd3fb6b4456032a0255bad894e8fc9cdb 100644 (file)
@@ -2942,6 +2942,10 @@ const struct ata_timing *ata_timing_find_mode(u8 xfer_mode)
 
        if (xfer_mode == t->mode)
                return t;
+
+       WARN_ONCE(true, "%s: unable to find timing for xfer_mode 0x%x\n",
+                       __func__, xfer_mode);
+
        return NULL;
 }
 
index e3bda074fa12f59381f9e8911338c49a88611f36..a6df6a351d6e4ce263f717ad52bf1ebb72a1aae0 100644 (file)
@@ -1052,6 +1052,8 @@ static void ata_scsi_sdev_config(struct scsi_device *sdev)
 {
        sdev->use_10_for_rw = 1;
        sdev->use_10_for_ms = 1;
+       sdev->no_report_opcodes = 1;
+       sdev->no_write_same = 1;
 
        /* Schedule policy is determined by ->qc_defer() callback and
         * it needs to see every deferred qc.  Set dev_blocked to 1 to
index 26201ebef3ca652a16c12c6719eae2127ed212ad..371fd2c698b70ce1b283672c0c2472f8ce6ac263 100644 (file)
@@ -317,6 +317,12 @@ static int cf_init(struct arasan_cf_dev *acdev)
                return ret;
        }
 
+       ret = clk_set_rate(acdev->clk, 166000000);
+       if (ret) {
+               dev_warn(acdev->host->dev, "clock set rate failed");
+               return ret;
+       }
+
        spin_lock_irqsave(&acdev->host->lock, flags);
        /* configure CF interface clock */
        writel((pdata->cf_if_clk <= CF_IF_CLK_200M) ? pdata->cf_if_clk :
@@ -908,7 +914,7 @@ static int __devexit arasan_cf_remove(struct platform_device *pdev)
        return 0;
 }
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static int arasan_cf_suspend(struct device *dev)
 {
        struct ata_host *host = dev_get_drvdata(dev);
index 0d7c4c2cd26fed3d81ecf2bfe78a1a4939588da9..400bf1c3e982eac392652d086358858ef903ca82 100644 (file)
@@ -260,7 +260,7 @@ static const struct of_device_id ahci_of_match[] = {
 };
 MODULE_DEVICE_TABLE(of, ahci_of_match);
 
-static int __init ahci_highbank_probe(struct platform_device *pdev)
+static int __devinit ahci_highbank_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
        struct ahci_host_priv *hpriv;
@@ -378,7 +378,7 @@ static int __devexit ahci_highbank_remove(struct platform_device *pdev)
        return 0;
 }
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static int ahci_highbank_suspend(struct device *dev)
 {
        struct ata_host *host = dev_get_drvdata(dev);
index 44a4256533e1bd4e8aef978abdfc7e34361ad053..08608de87e4e6a971e9a36ef701f343a6982d5b7 100644 (file)
@@ -142,6 +142,39 @@ static int k2_sata_scr_write(struct ata_link *link,
        return 0;
 }
 
+static int k2_sata_softreset(struct ata_link *link,
+                            unsigned int *class, unsigned long deadline)
+{
+       u8 dmactl;
+       void __iomem *mmio = link->ap->ioaddr.bmdma_addr;
+
+       dmactl = readb(mmio + ATA_DMA_CMD);
+
+       /* Clear the start bit */
+       if (dmactl & ATA_DMA_START) {
+               dmactl &= ~ATA_DMA_START;
+               writeb(dmactl, mmio + ATA_DMA_CMD);
+       }
+
+       return ata_sff_softreset(link, class, deadline);
+}
+
+static int k2_sata_hardreset(struct ata_link *link,
+                            unsigned int *class, unsigned long deadline)
+{
+       u8 dmactl;
+       void __iomem *mmio = link->ap->ioaddr.bmdma_addr;
+
+       dmactl = readb(mmio + ATA_DMA_CMD);
+
+       /* Clear the start bit */
+       if (dmactl & ATA_DMA_START) {
+               dmactl &= ~ATA_DMA_START;
+               writeb(dmactl, mmio + ATA_DMA_CMD);
+       }
+
+       return sata_sff_hardreset(link, class, deadline);
+}
 
 static void k2_sata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
 {
@@ -346,6 +379,8 @@ static struct scsi_host_template k2_sata_sht = {
 
 static struct ata_port_operations k2_sata_ops = {
        .inherits               = &ata_bmdma_port_ops,
+       .softreset              = k2_sata_softreset,
+       .hardreset              = k2_sata_hardreset,
        .sff_tf_load            = k2_sata_tf_load,
        .sff_tf_read            = k2_sata_tf_read,
        .sff_check_status       = k2_stat_check_status,
index 89b30f32ba68b4f1e5cd58fc5911a95213abf163..ff7bb8a42ed62b042bff5f786b94775f8bfb87bc 100644 (file)
@@ -1961,6 +1961,7 @@ static int __devinit ucode_init (loader_block * lb, amb_dev * dev) {
     res = loader_verify(lb, dev, rec);
     if (res)
       break;
+    rec = ihex_next_binrec(rec);
   }
   release_firmware(fw);
   if (!res)
index 74a67e0019a2d246820ccb2858399bca193ff789..fbbd4ed2edf288318f8d165760c91ee420f1812c 100644 (file)
@@ -451,7 +451,7 @@ int dev_pm_qos_add_ancestor_request(struct device *dev,
        if (ancestor)
                error = dev_pm_qos_add_request(ancestor, req, value);
 
-       if (error)
+       if (error < 0)
                req->dev = NULL;
 
        return error;
index 3804a0af3ef192c441643eee425d06f747b86d97..9fe4f1865558abce9ccd7ebf1ee10a56284caf61 100644 (file)
@@ -935,7 +935,7 @@ aoe_end_request(struct aoedev *d, struct request *rq, int fastfail)
 
        /* cf. http://lkml.org/lkml/2006/10/31/28 */
        if (!fastfail)
-               q->request_fn(q);
+               __blk_run_queue(q);
 }
 
 static void
index 1c49d7173966ae52754cd75776ff50fa48f30d60..2ddd64a9ffdee43429653806be3262a80c372240 100644 (file)
@@ -4330,6 +4330,7 @@ out_unreg_region:
 out_unreg_blkdev:
        unregister_blkdev(FLOPPY_MAJOR, "fd");
 out_put_disk:
+       destroy_workqueue(floppy_wq);
        for (drive = 0; drive < N_DRIVE; drive++) {
                if (!disks[drive])
                        break;
@@ -4340,7 +4341,6 @@ out_put_disk:
                }
                put_disk(disks[drive]);
        }
-       destroy_workqueue(floppy_wq);
        return err;
 }
 
@@ -4555,6 +4555,8 @@ static void __exit floppy_module_exit(void)
        unregister_blkdev(FLOPPY_MAJOR, "fd");
        platform_driver_unregister(&floppy_driver);
 
+       destroy_workqueue(floppy_wq);
+
        for (drive = 0; drive < N_DRIVE; drive++) {
                del_timer_sync(&motor_off_timer[drive]);
 
@@ -4578,7 +4580,6 @@ static void __exit floppy_module_exit(void)
 
        cancel_delayed_work_sync(&fd_timeout);
        cancel_delayed_work_sync(&fd_timer);
-       destroy_workqueue(floppy_wq);
 
        if (atomic_read(&usage_count))
                floppy_release_irq_and_dma();
index adc6f36564cf3c9f214ca37c9b3cf8faffbe6cf8..9694dd99bbbc7253af1c3626823899f985b1afc2 100644 (file)
@@ -559,7 +559,7 @@ static void mtip_timeout_function(unsigned long int data)
        struct mtip_cmd *command;
        int tag, cmdto_cnt = 0;
        unsigned int bit, group;
-       unsigned int num_command_slots = port->dd->slot_groups * 32;
+       unsigned int num_command_slots;
        unsigned long to, tagaccum[SLOTBITS_IN_LONGS];
 
        if (unlikely(!port))
@@ -572,6 +572,7 @@ static void mtip_timeout_function(unsigned long int data)
        }
        /* clear the tag accumulator */
        memset(tagaccum, 0, SLOTBITS_IN_LONGS * sizeof(long));
+       num_command_slots = port->dd->slot_groups * 32;
 
        for (tag = 0; tag < num_command_slots; tag++) {
                /*
@@ -2218,8 +2219,8 @@ static int exec_drive_taskfile(struct driver_data *dd,
                fis.device);
 
        /* check for erase mode support during secure erase.*/
-       if ((fis.command == ATA_CMD_SEC_ERASE_UNIT)
-                                       && (outbuf[0] & MTIP_SEC_ERASE_MODE)) {
+       if ((fis.command == ATA_CMD_SEC_ERASE_UNIT) && outbuf &&
+                                       (outbuf[0] & MTIP_SEC_ERASE_MODE)) {
                erasemode = 1;
        }
 
@@ -2439,7 +2440,7 @@ static int mtip_hw_ioctl(struct driver_data *dd, unsigned int cmd,
  * return value
  *     None
  */
-static void mtip_hw_submit_io(struct driver_data *dd, sector_t start,
+static void mtip_hw_submit_io(struct driver_data *dd, sector_t sector,
                              int nsect, int nents, int tag, void *callback,
                              void *data, int dir)
 {
@@ -2447,6 +2448,7 @@ static void mtip_hw_submit_io(struct driver_data *dd, sector_t start,
        struct mtip_port *port = dd->port;
        struct mtip_cmd *command = &port->commands[tag];
        int dma_dir = (dir == READ) ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
+       u64 start = sector;
 
        /* Map the scatter list for DMA access */
        nents = dma_map_sg(&dd->pdev->dev, command->sg, nents, dma_dir);
@@ -2465,8 +2467,12 @@ static void mtip_hw_submit_io(struct driver_data *dd, sector_t start,
        fis->opts        = 1 << 7;
        fis->command     =
                (dir == READ ? ATA_CMD_FPDMA_READ : ATA_CMD_FPDMA_WRITE);
-       *((unsigned int *) &fis->lba_low) = (start & 0xFFFFFF);
-       *((unsigned int *) &fis->lba_low_ex) = ((start >> 24) & 0xFFFFFF);
+       fis->lba_low     = start & 0xFF;
+       fis->lba_mid     = (start >> 8) & 0xFF;
+       fis->lba_hi      = (start >> 16) & 0xFF;
+       fis->lba_low_ex  = (start >> 24) & 0xFF;
+       fis->lba_mid_ex  = (start >> 32) & 0xFF;
+       fis->lba_hi_ex   = (start >> 40) & 0xFF;
        fis->device      = 1 << 6;
        fis->features    = nsect & 0xFF;
        fis->features_ex = (nsect >> 8) & 0xFF;
index 5f4a917bd8bbcfe88283b3509e365a0faefbb3b5..b1742640556a782cee77701c78c4ddf7e961591a 100644 (file)
@@ -34,7 +34,7 @@
 #define PCIE_CONFIG_EXT_DEVICE_CONTROL_OFFSET  0x48
 
 /* check for erase mode support during secure erase */
-#define MTIP_SEC_ERASE_MODE     0x3
+#define MTIP_SEC_ERASE_MODE     0x2
 
 /* # of times to retry timed out/failed IOs */
 #define MTIP_MAX_RETRIES       2
@@ -155,14 +155,14 @@ enum {
        MTIP_DDF_REBUILD_FAILED_BIT = 8,
 };
 
-__packed struct smart_attr{
+struct smart_attr {
        u8 attr_id;
        u16 flags;
        u8 cur;
        u8 worst;
        u32 data;
        u8 res[3];
-};
+} __packed;
 
 /* Register Frame Information Structure (FIS), host to device. */
 struct host_to_dev_fis {
index fbd9b2b850ef1de0a84a57182ff79bdd38064896..c58ea9b80b1a3b63e65a52236d71c8db4cfa02c4 100644 (file)
@@ -127,12 +127,12 @@ config HW_RANDOM_VIA
          If unsure, say Y.
 
 config HW_RANDOM_IXP4XX
-       tristate "Intel IXP4xx NPU HW Random Number Generator support"
+       tristate "Intel IXP4xx NPU HW Pseudo-Random Number Generator support"
        depends on HW_RANDOM && ARCH_IXP4XX
        default HW_RANDOM
        ---help---
-         This driver provides kernel-side support for the Random
-         Number Generator hardware found on the Intel IXP4xx NPU.
+         This driver provides kernel-side support for the Pseudo-Random
+         Number Generator hardware found on the Intel IXP45x/46x NPU.
 
          To compile this driver as a module, choose M here: the
          module will be called ixp4xx-rng.
index 263567f5f3923fb12ae13d6401aa84f1b636aa07..beec1627db3c1b147fb4be577c61697ef2e1005f 100644 (file)
@@ -45,6 +45,9 @@ static int __init ixp4xx_rng_init(void)
        void __iomem * rng_base;
        int err;
 
+       if (!cpu_is_ixp46x()) /* includes IXP455 */
+               return -ENOSYS;
+
        rng_base = ioremap(0x70002100, 4);
        if (!rng_base)
                return -ENOMEM;
@@ -68,5 +71,5 @@ module_init(ixp4xx_rng_init);
 module_exit(ixp4xx_rng_exit);
 
 MODULE_AUTHOR("Deepak Saxena <dsaxena@plexity.net>");
-MODULE_DESCRIPTION("H/W Random Number Generator (RNG) driver for IXP4xx");
+MODULE_DESCRIPTION("H/W Pseudo-Random Number Generator (RNG) driver for IXP45x/46x");
 MODULE_LICENSE("GPL");
index 0bb207eaef2ff65e854866fddfdb11fce27cc066..54a3a6d09819922486f4de420f4ed0f96a6e7bb0 100644 (file)
@@ -285,7 +285,7 @@ static long raw_ctl_compat_ioctl(struct file *file, unsigned int cmd,
 
 static const struct file_operations raw_fops = {
        .read           = do_sync_read,
-       .aio_read       = blkdev_aio_read,
+       .aio_read       = generic_file_aio_read,
        .write          = do_sync_write,
        .aio_write      = blkdev_aio_write,
        .fsync          = blkdev_fsync,
index 308c7fb92a60b25a27d92ef11a9acbe80f23b921..f6644f59fd9da1042cec58487791f689d7ed127a 100644 (file)
@@ -224,7 +224,7 @@ config CRYPTO_DEV_TALITOS
 
 config CRYPTO_DEV_IXP4XX
        tristate "Driver for IXP4xx crypto hardware acceleration"
-       depends on ARCH_IXP4XX
+       depends on ARCH_IXP4XX && IXP4XX_QMGR && IXP4XX_NPE
        select CRYPTO_DES
        select CRYPTO_ALGAPI
        select CRYPTO_AUTHENC
index 8f3f74ce8c7fd7ac95e241c2c4504f06a52da38c..21180d6cad6e27f2f316a04b1e98fb2e61ac90d3 100644 (file)
@@ -750,12 +750,12 @@ static int setup_cipher(struct crypto_tfm *tfm, int encrypt,
        }
        if (cipher_cfg & MOD_AES) {
                switch (key_len) {
-                       case 16: keylen_cfg = MOD_AES128 | KEYLEN_128; break;
-                       case 24: keylen_cfg = MOD_AES192 | KEYLEN_192; break;
-                       case 32: keylen_cfg = MOD_AES256 | KEYLEN_256; break;
-                       default:
-                               *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
-                               return -EINVAL;
+               case 16: keylen_cfg = MOD_AES128; break;
+               case 24: keylen_cfg = MOD_AES192; break;
+               case 32: keylen_cfg = MOD_AES256; break;
+               default:
+                       *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
+                       return -EINVAL;
                }
                cipher_cfg |= keylen_cfg;
        } else if (cipher_cfg & MOD_3DES) {
index 8d4804732bacb77be17f07465e48f24ea513ab0c..8c4139647efc06acf50528a8d66f1e09995cc4cc 100644 (file)
@@ -33,7 +33,7 @@
  *             detection. The mods to Rev F required more family
  *             information detection.
  *
- *     Changes/Fixes by Borislav Petkov <borislav.petkov@amd.com>:
+ *     Changes/Fixes by Borislav Petkov <bp@alien8.de>:
  *             - misc fixes and code cleanups
  *
  * This module is based on the following documents
index 90f0b730e9bb1ee4a23a2941ea60021a12798d1f..75c0a1a85fc3ce553cb38f7099806874e26a2645 100644 (file)
@@ -416,10 +416,18 @@ struct mem_ctl_info *edac_mc_alloc(unsigned mc_num,
                dimm->cschannel = chn;
 
                /* Increment csrow location */
-               row++;
-               if (row == tot_csrows) {
-                       row = 0;
+               if (layers[0].is_virt_csrow) {
                        chn++;
+                       if (chn == tot_channels) {
+                               chn = 0;
+                               row++;
+                       }
+               } else {
+                       row++;
+                       if (row == tot_csrows) {
+                               row = 0;
+                               chn++;
+                       }
                }
 
                /* Increment dimm location */
index 6c86f6e545587202d3a9f729457ef38314490f70..351945fa2ecdca3f59a691db38206a0f13795797 100644 (file)
@@ -5,7 +5,7 @@
  *
  * 2007 (c) MontaVista Software, Inc.
  * 2010 (c) Advanced Micro Devices Inc.
- *         Borislav Petkov <borislav.petkov@amd.com>
+ *         Borislav Petkov <bp@alien8.de>
  *
  * This file is licensed under the terms of the GNU General Public
  * License version 2. This program is licensed "as is" without any
index a09d0667f72acb4aca4dda012b0d172a927182eb..9d669cd43618b605d7db354fde86df8c90c64f08 100644 (file)
@@ -197,8 +197,8 @@ static const char *ferr_fat_fbd_name[] = {
        [0]  = "Memory Write error on non-redundant retry or "
               "FBD configuration Write error on retry",
 };
-#define GET_FBD_FAT_IDX(fbderr)        (fbderr & (3 << 28))
-#define FERR_FAT_FBD_ERR_MASK ((1 << 0) | (1 << 1) | (1 << 2) | (1 << 3))
+#define GET_FBD_FAT_IDX(fbderr)        (((fbderr) >> 28) & 3)
+#define FERR_FAT_FBD_ERR_MASK ((1 << 0) | (1 << 1) | (1 << 2) | (1 << 22))
 
 #define FERR_NF_FBD    0xa0
 static const char *ferr_nf_fbd_name[] = {
@@ -225,7 +225,7 @@ static const char *ferr_nf_fbd_name[] = {
        [1]  = "Aliased Uncorrectable Non-Mirrored Demand Data ECC",
        [0]  = "Uncorrectable Data ECC on Replay",
 };
-#define GET_FBD_NF_IDX(fbderr) (fbderr & (3 << 28))
+#define GET_FBD_NF_IDX(fbderr) (((fbderr) >> 28) & 3)
 #define FERR_NF_FBD_ERR_MASK ((1 << 24) | (1 << 23) | (1 << 22) | (1 << 21) |\
                              (1 << 18) | (1 << 17) | (1 << 16) | (1 << 15) |\
                              (1 << 14) | (1 << 13) | (1 << 11) | (1 << 10) |\
@@ -464,7 +464,7 @@ static void i7300_process_fbd_error(struct mem_ctl_info *mci)
                errnum = find_first_bit(&errors,
                                        ARRAY_SIZE(ferr_nf_fbd_name));
                specific = GET_ERR_FROM_TABLE(ferr_nf_fbd_name, errnum);
-               branch = (GET_FBD_FAT_IDX(error_reg) == 2) ? 1 : 0;
+               branch = (GET_FBD_NF_IDX(error_reg) == 2) ? 1 : 0;
 
                pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map,
                        REDMEMA, &syndrome);
index 3672101023bd8d44c7fb136601a72a0290a9e936..10c8c00d6469398a211dc23b413d4d6495851b5a 100644 (file)
@@ -816,7 +816,7 @@ static ssize_t i7core_inject_store_##param(                 \
        struct device_attribute *mattr,                         \
        const char *data, size_t count)                         \
 {                                                              \
-       struct mem_ctl_info *mci = to_mci(dev);                 \
+       struct mem_ctl_info *mci = dev_get_drvdata(dev);        \
        struct i7core_pvt *pvt;                                 \
        long value;                                             \
        int rc;                                                 \
@@ -845,7 +845,7 @@ static ssize_t i7core_inject_show_##param(                  \
        struct device_attribute *mattr,                         \
        char *data)                                             \
 {                                                              \
-       struct mem_ctl_info *mci = to_mci(dev);                 \
+       struct mem_ctl_info *mci = dev_get_drvdata(dev);        \
        struct i7core_pvt *pvt;                                 \
                                                                \
        pvt = mci->pvt_info;                                    \
@@ -1052,7 +1052,7 @@ static ssize_t i7core_show_counter_##param(                       \
        struct device_attribute *mattr,                         \
        char *data)                                             \
 {                                                              \
-       struct mem_ctl_info *mci = to_mci(dev);                 \
+       struct mem_ctl_info *mci = dev_get_drvdata(dev);        \
        struct i7core_pvt *pvt = mci->pvt_info;                 \
                                                                \
        edac_dbg(1, "\n");                                      \
index 069e26c11c4f761997bbf2afb6b9bf1bf2d6b039..a98020409fa9933181fe93a550fdb2abaf572ebd 100644 (file)
@@ -370,10 +370,6 @@ static enum dev_type i82975x_dram_type(void __iomem *mch_window, int rank)
 static void i82975x_init_csrows(struct mem_ctl_info *mci,
                struct pci_dev *pdev, void __iomem *mch_window)
 {
-       static const char *labels[4] = {
-                                                       "DIMM A1", "DIMM A2",
-                                                       "DIMM B1", "DIMM B2"
-                                               };
        struct csrow_info *csrow;
        unsigned long last_cumul_size;
        u8 value;
@@ -423,9 +419,10 @@ static void i82975x_init_csrows(struct mem_ctl_info *mci,
                        dimm = mci->csrows[index]->channels[chan]->dimm;
 
                        dimm->nr_pages = nr_pages / csrow->nr_channels;
-                       strncpy(csrow->channels[chan]->dimm->label,
-                                       labels[(index >> 1) + (chan * 2)],
-                                       EDAC_MC_LABEL_LEN);
+
+                       snprintf(csrow->channels[chan]->dimm->label, EDAC_MC_LABEL_LEN, "DIMM %c%d",
+                                (chan == 0) ? 'A' : 'B',
+                                index);
                        dimm->grain = 1 << 7;   /* 128Byte cache-line resolution */
                        dimm->dtype = i82975x_dram_type(mch_window, index);
                        dimm->mtype = MEM_DDR2; /* I82975x supports only DDR2 */
index 66b5151c10807083e1e724cb58cc384cdde2f11c..2ae78f20cc28f3850cc26a9156927c7b4e8b085e 100644 (file)
@@ -6,7 +6,7 @@
  * This file may be distributed under the terms of the GNU General Public
  * License version 2.
  *
- * Copyright (c) 2010:  Borislav Petkov <borislav.petkov@amd.com>
+ * Copyright (c) 2010:  Borislav Petkov <bp@alien8.de>
  *                     Advanced Micro Devices Inc.
  */
 
@@ -168,6 +168,6 @@ module_init(edac_init_mce_inject);
 module_exit(edac_exit_mce_inject);
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Borislav Petkov <borislav.petkov@amd.com>");
+MODULE_AUTHOR("Borislav Petkov <bp@alien8.de>");
 MODULE_AUTHOR("AMD Inc.");
 MODULE_DESCRIPTION("MCE injection facility for testing MCE decoding");
index 1162d6b3bf8561d6ed1cfe399643dff6deb4027b..bb1b392f5cdacd1194e9af1772469c834e4192dd 100644 (file)
@@ -1546,6 +1546,8 @@ static int sbp2_scsi_slave_configure(struct scsi_device *sdev)
        struct sbp2_logical_unit *lu = sdev->hostdata;
 
        sdev->use_10_for_rw = 1;
+       sdev->no_report_opcodes = 1;
+       sdev->no_write_same = 1;
 
        if (sbp2_param_exclusive_login)
                sdev->manage_start_stop = 1;
index f11d8e3b4041b780c8c9f9ec154c3f0878025ec6..47150f5ded04ea4df13c14434fc3fa553141abaf 100644 (file)
@@ -466,7 +466,7 @@ config GPIO_ADP5588_IRQ
 
 config GPIO_ADNP
        tristate "Avionic Design N-bit GPIO expander"
-       depends on I2C && OF
+       depends on I2C && OF_GPIO
        help
          This option enables support for N GPIOs found on Avionic Design
          I2C GPIO expanders. The register space will be extended by powers
index 0f425189de11b3b5b8003a9c9abb330d9debd116..ce1c847600764602f568994f08167b8fc044dd9a 100644 (file)
@@ -77,7 +77,7 @@ struct mcp23s08_driver_data {
 
 /*----------------------------------------------------------------------*/
 
-#ifdef CONFIG_I2C
+#if IS_ENABLED(CONFIG_I2C)
 
 static int mcp23008_read(struct mcp23s08 *mcp, unsigned reg)
 {
@@ -399,7 +399,7 @@ static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev,
                break;
 #endif /* CONFIG_SPI_MASTER */
 
-#ifdef CONFIG_I2C
+#if IS_ENABLED(CONFIG_I2C)
        case MCP_TYPE_008:
                mcp->ops = &mcp23008_ops;
                mcp->chip.ngpio = 8;
@@ -473,7 +473,7 @@ fail:
 
 /*----------------------------------------------------------------------*/
 
-#ifdef CONFIG_I2C
+#if IS_ENABLED(CONFIG_I2C)
 
 static int __devinit mcp230xx_probe(struct i2c_client *client,
                                    const struct i2c_device_id *id)
index cf7afb9eb61ab02c4060532dbdd39e2c2c6e9561..be65c0451ad556e174b961f3542cc8d7b40e201c 100644 (file)
@@ -92,6 +92,11 @@ static inline void __iomem *mvebu_gpioreg_out(struct mvebu_gpio_chip *mvchip)
        return mvchip->membase + GPIO_OUT_OFF;
 }
 
+static inline void __iomem *mvebu_gpioreg_blink(struct mvebu_gpio_chip *mvchip)
+{
+       return mvchip->membase + GPIO_BLINK_EN_OFF;
+}
+
 static inline void __iomem *mvebu_gpioreg_io_conf(struct mvebu_gpio_chip *mvchip)
 {
        return mvchip->membase + GPIO_IO_CONF_OFF;
@@ -206,6 +211,23 @@ static int mvebu_gpio_get(struct gpio_chip *chip, unsigned pin)
        return (u >> pin) & 1;
 }
 
+static void mvebu_gpio_blink(struct gpio_chip *chip, unsigned pin, int value)
+{
+       struct mvebu_gpio_chip *mvchip =
+               container_of(chip, struct mvebu_gpio_chip, chip);
+       unsigned long flags;
+       u32 u;
+
+       spin_lock_irqsave(&mvchip->lock, flags);
+       u = readl_relaxed(mvebu_gpioreg_blink(mvchip));
+       if (value)
+               u |= 1 << pin;
+       else
+               u &= ~(1 << pin);
+       writel_relaxed(u, mvebu_gpioreg_blink(mvchip));
+       spin_unlock_irqrestore(&mvchip->lock, flags);
+}
+
 static int mvebu_gpio_direction_input(struct gpio_chip *chip, unsigned pin)
 {
        struct mvebu_gpio_chip *mvchip =
@@ -244,6 +266,7 @@ static int mvebu_gpio_direction_output(struct gpio_chip *chip, unsigned pin,
        if (ret)
                return ret;
 
+       mvebu_gpio_blink(chip, pin, 0);
        mvebu_gpio_set(chip, pin, value);
 
        spin_lock_irqsave(&mvchip->lock, flags);
index 241ad1eeec64d2097a4416bd76026723d384a215..f2df06c603f72a522527226aa9622cfd7e4c09fa 100644 (file)
@@ -226,6 +226,12 @@ static void exynos_drm_encoder_commit(struct drm_encoder *encoder)
         * already updated or not by exynos_drm_encoder_dpms function.
         */
        exynos_encoder->updated = true;
+
+       /*
+        * In case of setcrtc, there is no way to update encoder's dpms
+        * so update it here.
+        */
+       exynos_encoder->dpms = DRM_MODE_DPMS_ON;
 }
 
 static void exynos_drm_encoder_disable(struct drm_encoder *encoder)
@@ -507,6 +513,6 @@ void exynos_drm_encoder_plane_disable(struct drm_encoder *encoder, void *data)
         * because the setting for disabling the overlay will be updated
         * at vsync.
         */
-       if (overlay_ops->wait_for_vblank)
+       if (overlay_ops && overlay_ops->wait_for_vblank)
                overlay_ops->wait_for_vblank(manager->dev);
 }
index 67eb6ba56edf4b1bffe805a3bd5c06973c532726..e7466c4414cb8f04e8b462ce98a28dbe6a539b5e 100644 (file)
@@ -87,7 +87,8 @@ static int exynos_drm_fbdev_update(struct drm_fb_helper *helper,
 
        dev->mode_config.fb_base = (resource_size_t)buffer->dma_addr;
        fbi->screen_base = buffer->kvaddr + offset;
-       fbi->fix.smem_start = (unsigned long)(buffer->dma_addr + offset);
+       fbi->fix.smem_start = (unsigned long)(page_to_phys(buffer->pages[0]) +
+                               offset);
        fbi->screen_size = size;
        fbi->fix.smem_len = size;
 
index 130a2b510d4aebe1c9852b96457aea52e9857a15..e08478f19f1a0fd74f78136cde6ca3be00c69165 100644 (file)
@@ -61,11 +61,11 @@ struct fimd_driver_data {
        unsigned int timing_base;
 };
 
-struct fimd_driver_data exynos4_fimd_driver_data = {
+static struct fimd_driver_data exynos4_fimd_driver_data = {
        .timing_base = 0x0,
 };
 
-struct fimd_driver_data exynos5_fimd_driver_data = {
+static struct fimd_driver_data exynos5_fimd_driver_data = {
        .timing_base = 0x20000,
 };
 
index 60b877a388c280997d6042302c11fb2a7e8a0553..862ca1eb21020fdc2faf5ebc5c65b5b3a2899731 100644 (file)
@@ -204,7 +204,6 @@ exynos_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
                return ret;
 
        plane->crtc = crtc;
-       plane->fb = crtc->fb;
 
        exynos_plane_commit(plane);
        exynos_plane_dpms(plane, DRM_MODE_DPMS_ON);
index 107f09befe929540e9ad801ff2bbdfe97a6b651d..9b285da4449b005c3c38a2ac7001c3c222b2deed 100644 (file)
@@ -1796,7 +1796,7 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj)
         */
        mapping = obj->base.filp->f_path.dentry->d_inode->i_mapping;
        gfp = mapping_gfp_mask(mapping);
-       gfp |= __GFP_NORETRY | __GFP_NOWARN;
+       gfp |= __GFP_NORETRY | __GFP_NOWARN | __GFP_NO_KSWAPD;
        gfp &= ~(__GFP_IO | __GFP_WAIT);
        for_each_sg(st->sgl, sg, page_count, i) {
                page = shmem_read_mapping_page_gfp(mapping, i, gfp);
@@ -1809,7 +1809,7 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj)
                         * our own buffer, now let the real VM do its job and
                         * go down in flames if truly OOM.
                         */
-                       gfp &= ~(__GFP_NORETRY | __GFP_NOWARN);
+                       gfp &= ~(__GFP_NORETRY | __GFP_NOWARN | __GFP_NO_KSWAPD);
                        gfp |= __GFP_IO | __GFP_WAIT;
 
                        i915_gem_shrink_all(dev_priv);
@@ -1817,7 +1817,7 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj)
                        if (IS_ERR(page))
                                goto err_pages;
 
-                       gfp |= __GFP_NORETRY | __GFP_NOWARN;
+                       gfp |= __GFP_NORETRY | __GFP_NOWARN | __GFP_NO_KSWAPD;
                        gfp &= ~(__GFP_IO | __GFP_WAIT);
                }
 
index 0ed6baff4b0c2146d133006c52542b48076c5cc4..56846ed5ee55b1b4686afb4a2fb56a359f80c9bf 100644 (file)
@@ -499,12 +499,8 @@ parse_edp(struct drm_i915_private *dev_priv, struct bdb_header *bdb)
 
        edp = find_section(bdb, BDB_EDP);
        if (!edp) {
-               if (SUPPORTS_EDP(dev_priv->dev) && dev_priv->edp.support) {
-                       DRM_DEBUG_KMS("No eDP BDB found but eDP panel "
-                                     "supported, assume %dbpp panel color "
-                                     "depth.\n",
-                                     dev_priv->edp.bpp);
-               }
+               if (SUPPORTS_EDP(dev_priv->dev) && dev_priv->edp.support)
+                       DRM_DEBUG_KMS("No eDP BDB found but eDP panel supported.\n");
                return;
        }
 
@@ -657,9 +653,6 @@ init_vbt_defaults(struct drm_i915_private *dev_priv)
        dev_priv->lvds_use_ssc = 1;
        dev_priv->lvds_ssc_freq = intel_bios_ssc_frequency(dev, 1);
        DRM_DEBUG_KMS("Set default to SSC at %dMHz\n", dev_priv->lvds_ssc_freq);
-
-       /* eDP data */
-       dev_priv->edp.bpp = 18;
 }
 
 static int __init intel_no_opregion_vbt_callback(const struct dmi_system_id *id)
index 4154bcd7a0708b957d4b176607662933ac49fc0d..b426d44a2b055d5a8afb31a0ba4bc9fd40ea0554 100644 (file)
@@ -3845,7 +3845,7 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc,
                        /* Use VBT settings if we have an eDP panel */
                        unsigned int edp_bpc = dev_priv->edp.bpp / 3;
 
-                       if (edp_bpc < display_bpc) {
+                       if (edp_bpc && edp_bpc < display_bpc) {
                                DRM_DEBUG_KMS("clamping display bpc (was %d) to eDP (%d)\n", display_bpc, edp_bpc);
                                display_bpc = edp_bpc;
                        }
index 72f41aaa71ff330637bdc82d4ee8e0c04091bdf2..442968f8b20151e16d4b8bbd6e15093fb4d7ed85 100644 (file)
@@ -2373,15 +2373,9 @@ int intel_enable_rc6(const struct drm_device *dev)
        if (i915_enable_rc6 >= 0)
                return i915_enable_rc6;
 
-       if (INTEL_INFO(dev)->gen == 5) {
-#ifdef CONFIG_INTEL_IOMMU
-               /* Disable rc6 on ilk if VT-d is on. */
-               if (intel_iommu_gfx_mapped)
-                       return false;
-#endif
-               DRM_DEBUG_DRIVER("Ironlake: only RC6 available\n");
-               return INTEL_RC6_ENABLE;
-       }
+       /* Disable RC6 on Ironlake */
+       if (INTEL_INFO(dev)->gen == 5)
+               return 0;
 
        if (IS_HASWELL(dev)) {
                DRM_DEBUG_DRIVER("Haswell: only RC6 available\n");
index c600fb06e25e6a4798cd7f7f5841593025d3f484..a6ac0b416964c3751475522654cac0ccb6ccc574 100644 (file)
@@ -2201,7 +2201,6 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device)
                connector->connector_type = DRM_MODE_CONNECTOR_HDMIA;
                intel_sdvo->is_hdmi = true;
        }
-       intel_sdvo->base.cloneable = true;
 
        intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo);
        if (intel_sdvo->is_hdmi)
@@ -2232,7 +2231,6 @@ intel_sdvo_tv_init(struct intel_sdvo *intel_sdvo, int type)
 
        intel_sdvo->is_tv = true;
        intel_sdvo->base.needs_tv_clock = true;
-       intel_sdvo->base.cloneable = false;
 
        intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo);
 
@@ -2275,8 +2273,6 @@ intel_sdvo_analog_init(struct intel_sdvo *intel_sdvo, int device)
                intel_sdvo_connector->output_flag = SDVO_OUTPUT_RGB1;
        }
 
-       intel_sdvo->base.cloneable = true;
-
        intel_sdvo_connector_init(intel_sdvo_connector,
                                  intel_sdvo);
        return true;
@@ -2307,9 +2303,6 @@ intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, int device)
                intel_sdvo_connector->output_flag = SDVO_OUTPUT_LVDS1;
        }
 
-       /* SDVO LVDS is not cloneable because the input mode gets adjusted by the encoder */
-       intel_sdvo->base.cloneable = false;
-
        intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo);
        if (!intel_sdvo_create_enhance_property(intel_sdvo, intel_sdvo_connector))
                goto err;
@@ -2721,6 +2714,16 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob)
                goto err_output;
        }
 
+       /*
+        * Cloning SDVO with anything is often impossible, since the SDVO
+        * encoder can request a special input timing mode. And even if that's
+        * not the case we have evidence that cloning a plain unscaled mode with
+        * VGA doesn't really work. Furthermore the cloning flags are way too
+        * simplistic anyway to express such constraints, so just give up on
+        * cloning for SDVO encoders.
+        */
+       intel_sdvo->base.cloneable = false;
+
        /* Only enable the hotplug irq if we need it, to work around noisy
         * hotplug lines.
         */
index 05a909a17ceee67590195f0e9c60fd4a10857ed1..15b182c84ce8b74b55f0cb1073c452a410329f6e 100644 (file)
@@ -49,13 +49,7 @@ nv50_disp_intr_vblank(struct nv50_disp_priv *priv, int crtc)
                if (chan->vblank.crtc != crtc)
                        continue;
 
-               if (nv_device(priv)->chipset == 0x50) {
-                       nv_wr32(priv, 0x001704, chan->vblank.channel);
-                       nv_wr32(priv, 0x001710, 0x80000000 | chan->vblank.ctxdma);
-                       bar->flush(bar);
-                       nv_wr32(priv, 0x001570, chan->vblank.offset);
-                       nv_wr32(priv, 0x001574, chan->vblank.value);
-               } else {
+               if (nv_device(priv)->chipset >= 0xc0) {
                        nv_wr32(priv, 0x001718, 0x80000000 | chan->vblank.channel);
                        bar->flush(bar);
                        nv_wr32(priv, 0x06000c,
@@ -63,6 +57,17 @@ nv50_disp_intr_vblank(struct nv50_disp_priv *priv, int crtc)
                        nv_wr32(priv, 0x060010,
                                lower_32_bits(chan->vblank.offset));
                        nv_wr32(priv, 0x060014, chan->vblank.value);
+               } else {
+                       nv_wr32(priv, 0x001704, chan->vblank.channel);
+                       nv_wr32(priv, 0x001710, 0x80000000 | chan->vblank.ctxdma);
+                       bar->flush(bar);
+                       if (nv_device(priv)->chipset == 0x50) {
+                               nv_wr32(priv, 0x001570, chan->vblank.offset);
+                               nv_wr32(priv, 0x001574, chan->vblank.value);
+                       } else {
+                               nv_wr32(priv, 0x060010, chan->vblank.offset);
+                               nv_wr32(priv, 0x060014, chan->vblank.value);
+                       }
                }
 
                list_del(&chan->vblank.head);
index e45035efb8ca084c37785ffd4a0ca789523d4a2b..7bbb1e1b7a8d1ebbeeb275dd38e27caaa7a1400c 100644 (file)
@@ -669,21 +669,27 @@ nv40_grctx_fill(struct nouveau_device *device, struct nouveau_gpuobj *mem)
                           });
 }
 
-void
+int
 nv40_grctx_init(struct nouveau_device *device, u32 *size)
 {
-       u32 ctxprog[256], i;
+       u32 *ctxprog = kmalloc(256 * 4, GFP_KERNEL), i;
        struct nouveau_grctx ctx = {
                .device = device,
                .mode = NOUVEAU_GRCTX_PROG,
                .data = ctxprog,
-               .ctxprog_max = ARRAY_SIZE(ctxprog)
+               .ctxprog_max = 256,
        };
 
+       if (!ctxprog)
+               return -ENOMEM;
+
        nv40_grctx_generate(&ctx);
 
        nv_wr32(device, 0x400324, 0);
        for (i = 0; i < ctx.ctxprog_len; i++)
                nv_wr32(device, 0x400328, ctxprog[i]);
        *size = ctx.ctxvals_pos * 4;
+
+       kfree(ctxprog);
+       return 0;
 }
index 425001204a89b6133648d6752fb362159fca4cef..cc6574eeb80e6459166224185a5bd81ce41e9aa4 100644 (file)
@@ -346,7 +346,9 @@ nv40_graph_init(struct nouveau_object *object)
                return ret;
 
        /* generate and upload context program */
-       nv40_grctx_init(nv_device(priv), &priv->size);
+       ret = nv40_grctx_init(nv_device(priv), &priv->size);
+       if (ret)
+               return ret;
 
        /* No context present currently */
        nv_wr32(priv, NV40_PGRAPH_CTXCTL_CUR, 0x00000000);
index d2ac975afc2e8f46feff64c6be4c16e04faf73b3..7da35a4e7970d1684433f3fd036c60492a5ddb0d 100644 (file)
@@ -15,7 +15,7 @@ nv44_graph_class(void *priv)
        return !(0x0baf & (1 << (device->chipset & 0x0f)));
 }
 
-void nv40_grctx_init(struct nouveau_device *, u32 *size);
+int  nv40_grctx_init(struct nouveau_device *, u32 *size);
 void nv40_grctx_fill(struct nouveau_device *, struct nouveau_gpuobj *);
 
 #endif
index 818feabbf4a0969f090f897852fe4476a422b1b6..486f1a9217fd6cd51dc2c5530d455eaa155c86b4 100644 (file)
@@ -175,14 +175,18 @@ nv_mo32(void *obj, u32 addr, u32 mask, u32 data)
        return temp;
 }
 
-static inline bool
-nv_strncmp(void *obj, u32 addr, u32 len, const char *str)
+static inline int
+nv_memcmp(void *obj, u32 addr, const char *str, u32 len)
 {
+       unsigned char c1, c2;
+
        while (len--) {
-               if (nv_ro08(obj, addr++) != *(str++))
-                       return false;
+               c1 = nv_ro08(obj, addr++);
+               c2 = *(str++);
+               if (c1 != c2)
+                       return c1 - c2;
        }
-       return true;
+       return 0;
 }
 
 #endif
index 39e73b91d360a3753dbcc3c210ca1e77f00332ec..41b7a6a76f1981ae3427278bacaf8d2c99edbe09 100644 (file)
@@ -54,6 +54,7 @@ int nv04_clock_pll_calc(struct nouveau_clock *, struct nvbios_pll *,
                        int clk, struct nouveau_pll_vals *);
 int nv04_clock_pll_prog(struct nouveau_clock *, u32 reg1,
                        struct nouveau_pll_vals *);
-
+int nva3_clock_pll_calc(struct nouveau_clock *, struct nvbios_pll *,
+                       int clk, struct nouveau_pll_vals *);
 
 #endif
index 7d750382a833c33b64fbbf40c98a1d8f936399e2..c511971577490499002426ed04087a517d8e0dab 100644 (file)
@@ -64,7 +64,7 @@ dcb_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
                }
        } else
        if (*ver >= 0x15) {
-               if (!nv_strncmp(bios, dcb - 7, 7, "DEV_REC")) {
+               if (!nv_memcmp(bios, dcb - 7, "DEV_REC", 7)) {
                        u16 i2c = nv_ro16(bios, dcb + 2);
                        *hdr = 4;
                        *cnt = (i2c - dcb) / 10;
index cc8d7d162d7c348da6770d7404f195e9191d41e1..9068c98b96f64f2f8c0c5a18d478400d09855553 100644 (file)
@@ -66,6 +66,24 @@ nva3_clock_pll_set(struct nouveau_clock *clk, u32 type, u32 freq)
        return ret;
 }
 
+int
+nva3_clock_pll_calc(struct nouveau_clock *clock, struct nvbios_pll *info,
+                   int clk, struct nouveau_pll_vals *pv)
+{
+       int ret, N, M, P;
+
+       ret = nva3_pll_calc(clock, info, clk, &N, NULL, &M, &P);
+
+       if (ret > 0) {
+               pv->refclk = info->refclk;
+               pv->N1 = N;
+               pv->M1 = M;
+               pv->log2P = P;
+       }
+       return ret;
+}
+
+
 static int
 nva3_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
                struct nouveau_oclass *oclass, void *data, u32 size,
@@ -80,6 +98,7 @@ nva3_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
                return ret;
 
        priv->base.pll_set = nva3_clock_pll_set;
+       priv->base.pll_calc = nva3_clock_pll_calc;
        return 0;
 }
 
index 5ccce0b17bf3dd209bde225486b41bab55fcdf79..f6962c9b6c36b6f00db2715287dedf1c3adb9f4e 100644 (file)
@@ -79,6 +79,7 @@ nvc0_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
                return ret;
 
        priv->base.pll_set = nvc0_clock_pll_set;
+       priv->base.pll_calc = nva3_clock_pll_calc;
        return 0;
 }
 
index cc79c796afee316cd810125b93dd86fbef940d5e..cbf1fc60a38682be197dc1bb1f0f15c8853a06e6 100644 (file)
@@ -241,6 +241,10 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS)
 
        if (unlikely(!abi16))
                return -ENOMEM;
+
+       if (!drm->channel)
+               return nouveau_abi16_put(abi16, -ENODEV);
+
        client = nv_client(abi16->client);
 
        if (init->fb_ctxdma_handle == ~0 || init->tt_ctxdma_handle == ~0)
index 0910125cbbc3be3cfa757f0976f3afea8cac6a21..8503b2ea570a0616234e409c524593f37a98648e 100644 (file)
@@ -129,7 +129,8 @@ nouveau_accel_init(struct nouveau_drm *drm)
 
        /* initialise synchronisation routines */
        if      (device->card_type < NV_10) ret = nv04_fence_create(drm);
-       else if (device->chipset   <  0x84) ret = nv10_fence_create(drm);
+       else if (device->card_type < NV_50) ret = nv10_fence_create(drm);
+       else if (device->chipset   <  0x84) ret = nv50_fence_create(drm);
        else if (device->card_type < NV_C0) ret = nv84_fence_create(drm);
        else                                ret = nvc0_fence_create(drm);
        if (ret) {
index 3bce0299f64a664f9d1de78a6f452c907221694f..24d932f5320324fcdb726185a08481b4738e9ccf 100644 (file)
@@ -1696,42 +1696,22 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc)
                        return ATOM_PPLL2;
                DRM_ERROR("unable to allocate a PPLL\n");
                return ATOM_PPLL_INVALID;
-       } else if (ASIC_IS_AVIVO(rdev)) {
-               /* in DP mode, the DP ref clock can come from either PPLL
-                * depending on the asic:
-                * DCE3: PPLL1 or PPLL2
-                */
-               if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(radeon_crtc->encoder))) {
-                       /* use the same PPLL for all DP monitors */
-                       pll = radeon_get_shared_dp_ppll(crtc);
-                       if (pll != ATOM_PPLL_INVALID)
-                               return pll;
-               } else {
-                       /* use the same PPLL for all monitors with the same clock */
-                       pll = radeon_get_shared_nondp_ppll(crtc);
-                       if (pll != ATOM_PPLL_INVALID)
-                               return pll;
-               }
-               /* all other cases */
-               pll_in_use = radeon_get_pll_use_mask(crtc);
-               /* the order shouldn't matter here, but we probably
-                * need this until we have atomic modeset
-                */
-               if (rdev->flags & RADEON_IS_IGP) {
-                       if (!(pll_in_use & (1 << ATOM_PPLL1)))
-                               return ATOM_PPLL1;
-                       if (!(pll_in_use & (1 << ATOM_PPLL2)))
-                               return ATOM_PPLL2;
-               } else {
-                       if (!(pll_in_use & (1 << ATOM_PPLL2)))
-                               return ATOM_PPLL2;
-                       if (!(pll_in_use & (1 << ATOM_PPLL1)))
-                               return ATOM_PPLL1;
-               }
-               DRM_ERROR("unable to allocate a PPLL\n");
-               return ATOM_PPLL_INVALID;
        } else {
                /* on pre-R5xx asics, the crtc to pll mapping is hardcoded */
+               /* some atombios (observed in some DCE2/DCE3) code have a bug,
+                * the matching btw pll and crtc is done through
+                * PCLK_CRTC[1|2]_CNTL (0x480/0x484) but atombios code use the
+                * pll (1 or 2) to select which register to write. ie if using
+                * pll1 it will use PCLK_CRTC1_CNTL (0x480) and if using pll2
+                * it will use PCLK_CRTC2_CNTL (0x484), it then use crtc id to
+                * choose which value to write. Which is reverse order from
+                * register logic. So only case that works is when pllid is
+                * same as crtcid or when both pll and crtc are enabled and
+                * both use same clock.
+                *
+                * So just return crtc id as if crtc and pll were hard linked
+                * together even if they aren't
+                */
                return radeon_crtc->crtc_id;
        }
 }
index af31f829f4a8bd6910b8e19ec5bff001b660d3e6..219942c660d7d2129e7c21ac375761dcd5309c9f 100644 (file)
@@ -1330,6 +1330,8 @@ void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *sav
                                        break;
                                udelay(1);
                        }
+               } else {
+                       save->crtc_enabled[i] = false;
                }
        }
 
index 10ea17a6b2a6edfae76955f7e8f2ccd08ea7b1fe..42433344cb1b24860998067fe7c96baf332c1ece 100644 (file)
@@ -69,9 +69,12 @@ static struct radeon_agpmode_quirk radeon_agpmode_quirk_list[] = {
        /* Intel 82830 830 Chipset Host Bridge / Mobility M6 LY Needs AGPMode 2 (fdo #17360)*/
        { PCI_VENDOR_ID_INTEL, 0x3575, PCI_VENDOR_ID_ATI, 0x4c59,
                PCI_VENDOR_ID_DELL, 0x00e3, 2},
-       /* Intel 82852/82855 host bridge / Mobility FireGL 9000 R250 Needs AGPMode 1 (lp #296617) */
+       /* Intel 82852/82855 host bridge / Mobility FireGL 9000 RV250 Needs AGPMode 1 (lp #296617) */
        { PCI_VENDOR_ID_INTEL, 0x3580, PCI_VENDOR_ID_ATI, 0x4c66,
                PCI_VENDOR_ID_DELL, 0x0149, 1},
+       /* Intel 82855PM host bridge / Mobility FireGL 9000 RV250 Needs AGPMode 1 for suspend/resume */
+       { PCI_VENDOR_ID_INTEL, 0x3340, PCI_VENDOR_ID_ATI, 0x4c66,
+               PCI_VENDOR_ID_IBM, 0x0531, 1},
        /* Intel 82852/82855 host bridge / Mobility 9600 M10 RV350 Needs AGPMode 1 (deb #467460) */
        { PCI_VENDOR_ID_INTEL, 0x3580, PCI_VENDOR_ID_ATI, 0x4e50,
                0x1025, 0x0061, 1},
index aa59a254be2c3e3755a377d0c0c1f02dfa6c797d..c02bf208084f0a52cbb08548a36cece9c0ca3fb9 100644 (file)
@@ -39,6 +39,7 @@
 #define        AT91_TWI_STOP           0x0002  /* Send a Stop Condition */
 #define        AT91_TWI_MSEN           0x0004  /* Master Transfer Enable */
 #define        AT91_TWI_SVDIS          0x0020  /* Slave Transfer Disable */
+#define        AT91_TWI_QUICK          0x0040  /* SMBus quick command */
 #define        AT91_TWI_SWRST          0x0080  /* Software Reset */
 
 #define        AT91_TWI_MMR            0x0004  /* Master Mode Register */
@@ -212,7 +213,11 @@ static int at91_do_twi_transfer(struct at91_twi_dev *dev)
 
        INIT_COMPLETION(dev->cmd_complete);
        dev->transfer_status = 0;
-       if (dev->msg->flags & I2C_M_RD) {
+
+       if (!dev->buf_len) {
+               at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_QUICK);
+               at91_twi_write(dev, AT91_TWI_IER, AT91_TWI_TXCOMP);
+       } else if (dev->msg->flags & I2C_M_RD) {
                unsigned start_flags = AT91_TWI_START;
 
                if (at91_twi_read(dev, AT91_TWI_SR) & AT91_TWI_RXRDY) {
index 286ca191782098fe44f8a9c995b0015e2e3693ef..0670da79ee5e53cd0682dbdc1e7b311a196f73e1 100644 (file)
@@ -287,12 +287,14 @@ read_init_dma_fail:
 select_init_dma_fail:
        dma_unmap_sg(i2c->dev, &i2c->sg_io[0], 1, DMA_TO_DEVICE);
 select_init_pio_fail:
+       dmaengine_terminate_all(i2c->dmach);
        return -EINVAL;
 
 /* Write failpath. */
 write_init_dma_fail:
        dma_unmap_sg(i2c->dev, i2c->sg_io, 2, DMA_TO_DEVICE);
 write_init_pio_fail:
+       dmaengine_terminate_all(i2c->dmach);
        return -EINVAL;
 }
 
index db31eaed6ea59b32083df49f757c1fc949c60303..3525c9e62cb0f9bf23f47705fd86d3bba9707b45 100644 (file)
@@ -43,7 +43,6 @@
 #include <linux/slab.h>
 #include <linux/i2c-omap.h>
 #include <linux/pm_runtime.h>
-#include <linux/pm_qos.h>
 
 /* I2C controller revisions */
 #define OMAP_I2C_OMAP1_REV_2           0x20
@@ -187,8 +186,9 @@ struct omap_i2c_dev {
        int                     reg_shift;      /* bit shift for I2C register addresses */
        struct completion       cmd_complete;
        struct resource         *ioarea;
-       u32                     latency;        /* maximum MPU wkup latency */
-       struct pm_qos_request   pm_qos_request;
+       u32                     latency;        /* maximum mpu wkup latency */
+       void                    (*set_mpu_wkup_lat)(struct device *dev,
+                                                   long latency);
        u32                     speed;          /* Speed of bus in kHz */
        u32                     dtrev;          /* extra revision from DT */
        u32                     flags;
@@ -494,7 +494,9 @@ static void omap_i2c_resize_fifo(struct omap_i2c_dev *dev, u8 size, bool is_rx)
                dev->b_hw = 1; /* Enable hardware fixes */
 
        /* calculate wakeup latency constraint for MPU */
-       dev->latency = (1000000 * dev->threshold) / (1000 * dev->speed / 8);
+       if (dev->set_mpu_wkup_lat != NULL)
+               dev->latency = (1000000 * dev->threshold) /
+                       (1000 * dev->speed / 8);
 }
 
 /*
@@ -522,6 +524,9 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap,
        dev->buf = msg->buf;
        dev->buf_len = msg->len;
 
+       /* make sure writes to dev->buf_len are ordered */
+       barrier();
+
        omap_i2c_write_reg(dev, OMAP_I2C_CNT_REG, dev->buf_len);
 
        /* Clear the FIFO Buffers */
@@ -579,7 +584,6 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap,
         */
        timeout = wait_for_completion_timeout(&dev->cmd_complete,
                                                OMAP_I2C_TIMEOUT);
-       dev->buf_len = 0;
        if (timeout == 0) {
                dev_err(dev->dev, "controller timed out\n");
                omap_i2c_init(dev);
@@ -629,16 +633,8 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
        if (r < 0)
                goto out;
 
-       /*
-        * When waiting for completion of a i2c transfer, we need to
-        * set a wake up latency constraint for the MPU. This is to
-        * ensure quick enough wakeup from idle, when transfer
-        * completes.
-        */
-       if (dev->latency)
-               pm_qos_add_request(&dev->pm_qos_request,
-                                  PM_QOS_CPU_DMA_LATENCY,
-                                  dev->latency);
+       if (dev->set_mpu_wkup_lat != NULL)
+               dev->set_mpu_wkup_lat(dev->dev, dev->latency);
 
        for (i = 0; i < num; i++) {
                r = omap_i2c_xfer_msg(adap, &msgs[i], (i == (num - 1)));
@@ -646,8 +642,8 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
                        break;
        }
 
-       if (dev->latency)
-               pm_qos_remove_request(&dev->pm_qos_request);
+       if (dev->set_mpu_wkup_lat != NULL)
+               dev->set_mpu_wkup_lat(dev->dev, -1);
 
        if (r == 0)
                r = num;
@@ -1104,6 +1100,7 @@ omap_i2c_probe(struct platform_device *pdev)
        } else if (pdata != NULL) {
                dev->speed = pdata->clkrate;
                dev->flags = pdata->flags;
+               dev->set_mpu_wkup_lat = pdata->set_mpu_wkup_lat;
                dev->dtrev = pdata->rev;
        }
 
@@ -1159,8 +1156,9 @@ omap_i2c_probe(struct platform_device *pdev)
                        dev->b_hw = 1; /* Enable hardware fixes */
 
                /* calculate wakeup latency constraint for MPU */
-               dev->latency = (1000000 * dev->fifo_size) /
-                              (1000 * dev->speed / 8);
+               if (dev->set_mpu_wkup_lat != NULL)
+                       dev->latency = (1000000 * dev->fifo_size) /
+                                      (1000 * dev->speed / 8);
        }
 
        /* reset ASAP, clearing any IRQs */
index 3e0335f1fc60df8b78ce50c7a4e5284e82ad432f..9d902725bac94f28c91aa26ec57615988cd96e77 100644 (file)
@@ -806,6 +806,7 @@ static int s3c24xx_i2c_parse_dt_gpio(struct s3c24xx_i2c *i2c)
                        dev_err(i2c->dev, "invalid gpio[%d]: %d\n", idx, gpio);
                        goto free_gpio;
                }
+               i2c->gpios[idx] = gpio;
 
                ret = gpio_request(gpio, "i2c-bus");
                if (ret) {
index c0ec7d42c3be05ffd574daec1870d44d560ed15a..1abbc170d8b77f302154323a0ea944474bfd5d37 100644 (file)
@@ -26,10 +26,14 @@ static void copy_abs(struct input_dev *dev, unsigned int dst, unsigned int src)
  * input_mt_init_slots() - initialize MT input slots
  * @dev: input device supporting MT events and finger tracking
  * @num_slots: number of slots used by the device
+ * @flags: mt tasks to handle in core
  *
  * This function allocates all necessary memory for MT slot handling
  * in the input device, prepares the ABS_MT_SLOT and
  * ABS_MT_TRACKING_ID events for use and sets up appropriate buffers.
+ * Depending on the flags set, it also performs pointer emulation and
+ * frame synchronization.
+ *
  * May be called repeatedly. Returns -EINVAL if attempting to
  * reinitialize with a different number of slots.
  */
index 443ad64b7f2a2344ff6e8801dfe2c7f0a1e0a0a1..d88d9be1d1b7881b5fe5acfd674bf1ca12c17793 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/input.h>
 #include <linux/of.h>
 #include <linux/export.h>
+#include <linux/module.h>
 #include <linux/input/matrix_keypad.h>
 
 static bool matrix_keypad_map_key(struct input_dev *input_dev,
@@ -161,3 +162,5 @@ int matrix_keypad_build_keymap(const struct matrix_keymap_data *keymap_data,
        return 0;
 }
 EXPORT_SYMBOL(matrix_keypad_build_keymap);
+
+MODULE_LICENSE("GPL");
index 8f02e3d0e712789dc2cccbb0cb52fe40fc0620db..4c842c320c2ede9f2bf42d507ee5c91f00eef7e3 100644 (file)
@@ -12,8 +12,8 @@
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #define MOUSEDEV_MINOR_BASE    32
-#define MOUSEDEV_MINORS                32
-#define MOUSEDEV_MIX           31
+#define MOUSEDEV_MINORS                31
+#define MOUSEDEV_MIX           63
 
 #include <linux/sched.h>
 #include <linux/slab.h>
index f02028ec3db6a6384dc194e7633ee12e8bbb7685..78e5d9ab0ba7fd991e55cff240257248f42b7ba1 100644 (file)
@@ -955,7 +955,8 @@ static int ads7846_resume(struct device *dev)
 
 static SIMPLE_DEV_PM_OPS(ads7846_pm, ads7846_suspend, ads7846_resume);
 
-static int __devinit ads7846_setup_pendown(struct spi_device *spi, struct ads7846 *ts)
+static int __devinit ads7846_setup_pendown(struct spi_device *spi,
+                                          struct ads7846 *ts)
 {
        struct ads7846_platform_data *pdata = spi->dev.platform_data;
        int err;
@@ -981,6 +982,9 @@ static int __devinit ads7846_setup_pendown(struct spi_device *spi, struct ads784
 
                ts->gpio_pendown = pdata->gpio_pendown;
 
+               if (pdata->gpio_pendown_debounce)
+                       gpio_set_debounce(pdata->gpio_pendown,
+                                         pdata->gpio_pendown_debounce);
        } else {
                dev_err(&spi->dev, "no get_pendown_state nor gpio_pendown?\n");
                return -EINVAL;
index 14a4d5fc94fa3122efc44eb87bdc6770f9693c37..f66b816d455ced7e9cc58d370e7935fcc6291888 100644 (file)
@@ -7,6 +7,7 @@ obj-$(CONFIG_DMAR_TABLE) += dmar.o
 obj-$(CONFIG_INTEL_IOMMU) += iova.o intel-iommu.o
 obj-$(CONFIG_IRQ_REMAP) += intel_irq_remapping.o irq_remapping.o
 obj-$(CONFIG_OMAP_IOMMU) += omap-iommu.o
+obj-$(CONFIG_OMAP_IOMMU) += omap-iommu2.o
 obj-$(CONFIG_OMAP_IOVMM) += omap-iovmm.o
 obj-$(CONFIG_OMAP_IOMMU_DEBUG) += omap-iommu-debug.o
 obj-$(CONFIG_TEGRA_IOMMU_GART) += tegra-gart.o
index 55074cba20eba9012d6a310acef62b965728bcea..c1c74e030a58df6ea1020cec05c0f01acb14fb76 100644 (file)
  * physically contiguous memory regions it is mapping into page sizes
  * that we support.
  *
- * Traditionally the IOMMU core just handed us the mappings directly,
- * after making sure the size is an order of a 4KiB page and that the
- * mapping has natural alignment.
- *
- * To retain this behavior, we currently advertise that we support
- * all page sizes that are an order of 4KiB.
- *
- * If at some point we'd like to utilize the IOMMU core's new behavior,
- * we could change this to advertise the real page sizes we support.
+ * 512GB Pages are not supported due to a hardware bug
  */
-#define AMD_IOMMU_PGSIZES      (~0xFFFUL)
+#define AMD_IOMMU_PGSIZES      ((~0xFFFUL) & ~(2ULL << 38))
 
 static DEFINE_RWLOCK(amd_iommu_devtable_lock);
 
@@ -140,6 +132,9 @@ static void free_dev_data(struct iommu_dev_data *dev_data)
        list_del(&dev_data->dev_data_list);
        spin_unlock_irqrestore(&dev_data_list_lock, flags);
 
+       if (dev_data->group)
+               iommu_group_put(dev_data->group);
+
        kfree(dev_data);
 }
 
@@ -274,41 +269,23 @@ static void swap_pci_ref(struct pci_dev **from, struct pci_dev *to)
        *from = to;
 }
 
-#define REQ_ACS_FLAGS  (PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF)
-
-static int iommu_init_device(struct device *dev)
+static struct pci_bus *find_hosted_bus(struct pci_bus *bus)
 {
-       struct pci_dev *dma_pdev = NULL, *pdev = to_pci_dev(dev);
-       struct iommu_dev_data *dev_data;
-       struct iommu_group *group;
-       u16 alias;
-       int ret;
-
-       if (dev->archdata.iommu)
-               return 0;
-
-       dev_data = find_dev_data(get_device_id(dev));
-       if (!dev_data)
-               return -ENOMEM;
-
-       alias = amd_iommu_alias_table[dev_data->devid];
-       if (alias != dev_data->devid) {
-               struct iommu_dev_data *alias_data;
+       while (!bus->self) {
+               if (!pci_is_root_bus(bus))
+                       bus = bus->parent;
+               else
+                       return ERR_PTR(-ENODEV);
+       }
 
-               alias_data = find_dev_data(alias);
-               if (alias_data == NULL) {
-                       pr_err("AMD-Vi: Warning: Unhandled device %s\n",
-                                       dev_name(dev));
-                       free_dev_data(dev_data);
-                       return -ENOTSUPP;
-               }
-               dev_data->alias_data = alias_data;
+       return bus;
+}
 
-               dma_pdev = pci_get_bus_and_slot(alias >> 8, alias & 0xff);
-       }
+#define REQ_ACS_FLAGS  (PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF)
 
-       if (dma_pdev == NULL)
-               dma_pdev = pci_dev_get(pdev);
+static struct pci_dev *get_isolation_root(struct pci_dev *pdev)
+{
+       struct pci_dev *dma_pdev = pdev;
 
        /* Account for quirked devices */
        swap_pci_ref(&dma_pdev, pci_get_dma_source(dma_pdev));
@@ -330,14 +307,9 @@ static int iommu_init_device(struct device *dev)
         * Finding the next device may require skipping virtual buses.
         */
        while (!pci_is_root_bus(dma_pdev->bus)) {
-               struct pci_bus *bus = dma_pdev->bus;
-
-               while (!bus->self) {
-                       if (!pci_is_root_bus(bus))
-                               bus = bus->parent;
-                       else
-                               goto root_bus;
-               }
+               struct pci_bus *bus = find_hosted_bus(dma_pdev->bus);
+               if (IS_ERR(bus))
+                       break;
 
                if (pci_acs_path_enabled(bus->self, NULL, REQ_ACS_FLAGS))
                        break;
@@ -345,19 +317,137 @@ static int iommu_init_device(struct device *dev)
                swap_pci_ref(&dma_pdev, pci_dev_get(bus->self));
        }
 
-root_bus:
-       group = iommu_group_get(&dma_pdev->dev);
-       pci_dev_put(dma_pdev);
+       return dma_pdev;
+}
+
+static int use_pdev_iommu_group(struct pci_dev *pdev, struct device *dev)
+{
+       struct iommu_group *group = iommu_group_get(&pdev->dev);
+       int ret;
+
        if (!group) {
                group = iommu_group_alloc();
                if (IS_ERR(group))
                        return PTR_ERR(group);
+
+               WARN_ON(&pdev->dev != dev);
        }
 
        ret = iommu_group_add_device(group, dev);
-
        iommu_group_put(group);
+       return ret;
+}
+
+static int use_dev_data_iommu_group(struct iommu_dev_data *dev_data,
+                                   struct device *dev)
+{
+       if (!dev_data->group) {
+               struct iommu_group *group = iommu_group_alloc();
+               if (IS_ERR(group))
+                       return PTR_ERR(group);
+
+               dev_data->group = group;
+       }
+
+       return iommu_group_add_device(dev_data->group, dev);
+}
+
+static int init_iommu_group(struct device *dev)
+{
+       struct iommu_dev_data *dev_data;
+       struct iommu_group *group;
+       struct pci_dev *dma_pdev;
+       int ret;
+
+       group = iommu_group_get(dev);
+       if (group) {
+               iommu_group_put(group);
+               return 0;
+       }
+
+       dev_data = find_dev_data(get_device_id(dev));
+       if (!dev_data)
+               return -ENOMEM;
+
+       if (dev_data->alias_data) {
+               u16 alias;
+               struct pci_bus *bus;
+
+               if (dev_data->alias_data->group)
+                       goto use_group;
+
+               /*
+                * If the alias device exists, it's effectively just a first
+                * level quirk for finding the DMA source.
+                */
+               alias = amd_iommu_alias_table[dev_data->devid];
+               dma_pdev = pci_get_bus_and_slot(alias >> 8, alias & 0xff);
+               if (dma_pdev) {
+                       dma_pdev = get_isolation_root(dma_pdev);
+                       goto use_pdev;
+               }
+
+               /*
+                * If the alias is virtual, try to find a parent device
+                * and test whether the IOMMU group is actualy rooted above
+                * the alias.  Be careful to also test the parent device if
+                * we think the alias is the root of the group.
+                */
+               bus = pci_find_bus(0, alias >> 8);
+               if (!bus)
+                       goto use_group;
+
+               bus = find_hosted_bus(bus);
+               if (IS_ERR(bus) || !bus->self)
+                       goto use_group;
+
+               dma_pdev = get_isolation_root(pci_dev_get(bus->self));
+               if (dma_pdev != bus->self || (dma_pdev->multifunction &&
+                   !pci_acs_enabled(dma_pdev, REQ_ACS_FLAGS)))
+                       goto use_pdev;
+
+               pci_dev_put(dma_pdev);
+               goto use_group;
+       }
+
+       dma_pdev = get_isolation_root(pci_dev_get(to_pci_dev(dev)));
+use_pdev:
+       ret = use_pdev_iommu_group(dma_pdev, dev);
+       pci_dev_put(dma_pdev);
+       return ret;
+use_group:
+       return use_dev_data_iommu_group(dev_data->alias_data, dev);
+}
+
+static int iommu_init_device(struct device *dev)
+{
+       struct pci_dev *pdev = to_pci_dev(dev);
+       struct iommu_dev_data *dev_data;
+       u16 alias;
+       int ret;
+
+       if (dev->archdata.iommu)
+               return 0;
+
+       dev_data = find_dev_data(get_device_id(dev));
+       if (!dev_data)
+               return -ENOMEM;
+
+       alias = amd_iommu_alias_table[dev_data->devid];
+       if (alias != dev_data->devid) {
+               struct iommu_dev_data *alias_data;
+
+               alias_data = find_dev_data(alias);
+               if (alias_data == NULL) {
+                       pr_err("AMD-Vi: Warning: Unhandled device %s\n",
+                                       dev_name(dev));
+                       free_dev_data(dev_data);
+                       return -ENOTSUPP;
+               }
+               dev_data->alias_data = alias_data;
+       }
 
+       ret = init_iommu_group(dev);
        if (ret)
                return ret;
 
index c9aa3d079ff0377c376012bb5130b62e6bcefb8e..e38ab438bb342e241c1b5e545a0b01a4e4ea5017 100644 (file)
@@ -426,6 +426,7 @@ struct iommu_dev_data {
        struct iommu_dev_data *alias_data;/* The alias dev_data */
        struct protection_domain *domain; /* Domain the device is bound to */
        atomic_t bind;                    /* Domain attach reference count */
+       struct iommu_group *group;        /* IOMMU group for virtual aliases */
        u16 devid;                        /* PCI Device ID */
        bool iommu_v2;                    /* Device can make use of IOMMUv2 */
        bool passthrough;                 /* Default for device is pt_domain */
index ca3ee46a8d61aa3348602b2e3353d9701aa678aa..f7fd3d0aeb4ca55bc2130a76c76e0adae4de28fc 100644 (file)
@@ -4139,7 +4139,7 @@ static void swap_pci_ref(struct pci_dev **from, struct pci_dev *to)
 static int intel_iommu_add_device(struct device *dev)
 {
        struct pci_dev *pdev = to_pci_dev(dev);
-       struct pci_dev *bridge, *dma_pdev;
+       struct pci_dev *bridge, *dma_pdev = NULL;
        struct iommu_group *group;
        int ret;
 
@@ -4153,7 +4153,7 @@ static int intel_iommu_add_device(struct device *dev)
                        dma_pdev = pci_get_domain_bus_and_slot(
                                                pci_domain_nr(pdev->bus),
                                                bridge->subordinate->number, 0);
-               else
+               if (!dma_pdev)
                        dma_pdev = pci_dev_get(bridge);
        } else
                dma_pdev = pci_dev_get(pdev);
index f55fc5dfbadcfe420030cfd8b6632b98b48c2601..d97fbe4fb9b1358f0f7bea574edd6c8cd73502df 100644 (file)
 #include <linux/uaccess.h>
 #include <linux/platform_device.h>
 #include <linux/debugfs.h>
+#include <linux/omap-iommu.h>
+#include <linux/platform_data/iommu-omap.h>
 
-#include <plat/iommu.h>
-#include <plat/iovmm.h>
-
-#include <plat/iopgtable.h>
+#include "omap-iopgtable.h"
+#include "omap-iommu.h"
 
 #define MAXCOLUMN 100 /* for short messages */
 
index d0b1234581be17da531c7c39f18c6a0c48f68d75..18108c1405e2ae433646f1f1de6d3878e30fcb29 100644 (file)
 #include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
-#include <linux/clk.h>
 #include <linux/platform_device.h>
 #include <linux/iommu.h>
+#include <linux/omap-iommu.h>
 #include <linux/mutex.h>
 #include <linux/spinlock.h>
+#include <linux/io.h>
+#include <linux/pm_runtime.h>
 
 #include <asm/cacheflush.h>
 
-#include <plat/iommu.h>
+#include <linux/platform_data/iommu-omap.h>
 
-#include <plat/iopgtable.h>
+#include "omap-iopgtable.h"
+#include "omap-iommu.h"
 
 #define for_each_iotlb_cr(obj, n, __i, cr)                             \
        for (__i = 0;                                                   \
@@ -51,6 +54,21 @@ struct omap_iommu_domain {
        spinlock_t lock;
 };
 
+#define MMU_LOCK_BASE_SHIFT    10
+#define MMU_LOCK_BASE_MASK     (0x1f << MMU_LOCK_BASE_SHIFT)
+#define MMU_LOCK_BASE(x)       \
+       ((x & MMU_LOCK_BASE_MASK) >> MMU_LOCK_BASE_SHIFT)
+
+#define MMU_LOCK_VICT_SHIFT    4
+#define MMU_LOCK_VICT_MASK     (0x1f << MMU_LOCK_VICT_SHIFT)
+#define MMU_LOCK_VICT(x)       \
+       ((x & MMU_LOCK_VICT_MASK) >> MMU_LOCK_VICT_SHIFT)
+
+struct iotlb_lock {
+       short base;
+       short vict;
+};
+
 /* accommodate the difference between omap1 and omap2/3 */
 static const struct iommu_functions *arch_iommu;
 
@@ -125,31 +143,44 @@ EXPORT_SYMBOL_GPL(omap_iommu_arch_version);
 static int iommu_enable(struct omap_iommu *obj)
 {
        int err;
+       struct platform_device *pdev = to_platform_device(obj->dev);
+       struct iommu_platform_data *pdata = pdev->dev.platform_data;
 
-       if (!obj)
+       if (!obj || !pdata)
                return -EINVAL;
 
        if (!arch_iommu)
                return -ENODEV;
 
-       clk_enable(obj->clk);
+       if (pdata->deassert_reset) {
+               err = pdata->deassert_reset(pdev, pdata->reset_name);
+               if (err) {
+                       dev_err(obj->dev, "deassert_reset failed: %d\n", err);
+                       return err;
+               }
+       }
+
+       pm_runtime_get_sync(obj->dev);
 
        err = arch_iommu->enable(obj);
 
-       clk_disable(obj->clk);
        return err;
 }
 
 static void iommu_disable(struct omap_iommu *obj)
 {
-       if (!obj)
-               return;
+       struct platform_device *pdev = to_platform_device(obj->dev);
+       struct iommu_platform_data *pdata = pdev->dev.platform_data;
 
-       clk_enable(obj->clk);
+       if (!obj || !pdata)
+               return;
 
        arch_iommu->disable(obj);
 
-       clk_disable(obj->clk);
+       pm_runtime_put_sync(obj->dev);
+
+       if (pdata->assert_reset)
+               pdata->assert_reset(pdev, pdata->reset_name);
 }
 
 /*
@@ -272,7 +303,7 @@ static int load_iotlb_entry(struct omap_iommu *obj, struct iotlb_entry *e)
        if (!obj || !obj->nr_tlb_entries || !e)
                return -EINVAL;
 
-       clk_enable(obj->clk);
+       pm_runtime_get_sync(obj->dev);
 
        iotlb_lock_get(obj, &l);
        if (l.base == obj->nr_tlb_entries) {
@@ -302,7 +333,7 @@ static int load_iotlb_entry(struct omap_iommu *obj, struct iotlb_entry *e)
 
        cr = iotlb_alloc_cr(obj, e);
        if (IS_ERR(cr)) {
-               clk_disable(obj->clk);
+               pm_runtime_put_sync(obj->dev);
                return PTR_ERR(cr);
        }
 
@@ -316,7 +347,7 @@ static int load_iotlb_entry(struct omap_iommu *obj, struct iotlb_entry *e)
                l.vict = l.base;
        iotlb_lock_set(obj, &l);
 out:
-       clk_disable(obj->clk);
+       pm_runtime_put_sync(obj->dev);
        return err;
 }
 
@@ -346,7 +377,7 @@ static void flush_iotlb_page(struct omap_iommu *obj, u32 da)
        int i;
        struct cr_regs cr;
 
-       clk_enable(obj->clk);
+       pm_runtime_get_sync(obj->dev);
 
        for_each_iotlb_cr(obj, obj->nr_tlb_entries, i, cr) {
                u32 start;
@@ -365,7 +396,7 @@ static void flush_iotlb_page(struct omap_iommu *obj, u32 da)
                        iommu_write_reg(obj, 1, MMU_FLUSH_ENTRY);
                }
        }
-       clk_disable(obj->clk);
+       pm_runtime_put_sync(obj->dev);
 
        if (i == obj->nr_tlb_entries)
                dev_dbg(obj->dev, "%s: no page for %08x\n", __func__, da);
@@ -379,7 +410,7 @@ static void flush_iotlb_all(struct omap_iommu *obj)
 {
        struct iotlb_lock l;
 
-       clk_enable(obj->clk);
+       pm_runtime_get_sync(obj->dev);
 
        l.base = 0;
        l.vict = 0;
@@ -387,7 +418,7 @@ static void flush_iotlb_all(struct omap_iommu *obj)
 
        iommu_write_reg(obj, 1, MMU_GFLUSH);
 
-       clk_disable(obj->clk);
+       pm_runtime_put_sync(obj->dev);
 }
 
 #if defined(CONFIG_OMAP_IOMMU_DEBUG) || defined(CONFIG_OMAP_IOMMU_DEBUG_MODULE)
@@ -397,11 +428,11 @@ ssize_t omap_iommu_dump_ctx(struct omap_iommu *obj, char *buf, ssize_t bytes)
        if (!obj || !buf)
                return -EINVAL;
 
-       clk_enable(obj->clk);
+       pm_runtime_get_sync(obj->dev);
 
        bytes = arch_iommu->dump_ctx(obj, buf, bytes);
 
-       clk_disable(obj->clk);
+       pm_runtime_put_sync(obj->dev);
 
        return bytes;
 }
@@ -415,7 +446,7 @@ __dump_tlb_entries(struct omap_iommu *obj, struct cr_regs *crs, int num)
        struct cr_regs tmp;
        struct cr_regs *p = crs;
 
-       clk_enable(obj->clk);
+       pm_runtime_get_sync(obj->dev);
        iotlb_lock_get(obj, &saved);
 
        for_each_iotlb_cr(obj, num, i, tmp) {
@@ -425,7 +456,7 @@ __dump_tlb_entries(struct omap_iommu *obj, struct cr_regs *crs, int num)
        }
 
        iotlb_lock_set(obj, &saved);
-       clk_disable(obj->clk);
+       pm_runtime_put_sync(obj->dev);
 
        return  p - crs;
 }
@@ -789,9 +820,7 @@ static irqreturn_t iommu_fault_handler(int irq, void *data)
        if (!obj->refcount)
                return IRQ_NONE;
 
-       clk_enable(obj->clk);
        errs = iommu_report_fault(obj, &da);
-       clk_disable(obj->clk);
        if (errs == 0)
                return IRQ_HANDLED;
 
@@ -913,17 +942,10 @@ static int __devinit omap_iommu_probe(struct platform_device *pdev)
        struct resource *res;
        struct iommu_platform_data *pdata = pdev->dev.platform_data;
 
-       if (pdev->num_resources != 2)
-               return -EINVAL;
-
        obj = kzalloc(sizeof(*obj) + MMU_REG_SIZE, GFP_KERNEL);
        if (!obj)
                return -ENOMEM;
 
-       obj->clk = clk_get(&pdev->dev, pdata->clk_name);
-       if (IS_ERR(obj->clk))
-               goto err_clk;
-
        obj->nr_tlb_entries = pdata->nr_tlb_entries;
        obj->name = pdata->name;
        obj->dev = &pdev->dev;
@@ -966,6 +988,9 @@ static int __devinit omap_iommu_probe(struct platform_device *pdev)
                goto err_irq;
        platform_set_drvdata(pdev, obj);
 
+       pm_runtime_irq_safe(obj->dev);
+       pm_runtime_enable(obj->dev);
+
        dev_info(&pdev->dev, "%s registered\n", obj->name);
        return 0;
 
@@ -974,8 +999,6 @@ err_irq:
 err_ioremap:
        release_mem_region(res->start, resource_size(res));
 err_mem:
-       clk_put(obj->clk);
-err_clk:
        kfree(obj);
        return err;
 }
@@ -996,7 +1019,8 @@ static int __devexit omap_iommu_remove(struct platform_device *pdev)
        release_mem_region(res->start, resource_size(res));
        iounmap(obj->regbase);
 
-       clk_put(obj->clk);
+       pm_runtime_disable(obj->dev);
+
        dev_info(&pdev->dev, "%s removed\n", obj->name);
        kfree(obj);
        return 0;
@@ -1015,6 +1039,23 @@ static void iopte_cachep_ctor(void *iopte)
        clean_dcache_area(iopte, IOPTE_TABLE_SIZE);
 }
 
+static u32 iotlb_init_entry(struct iotlb_entry *e, u32 da, u32 pa,
+                                  u32 flags)
+{
+       memset(e, 0, sizeof(*e));
+
+       e->da           = da;
+       e->pa           = pa;
+       e->valid        = 1;
+       /* FIXME: add OMAP1 support */
+       e->pgsz         = flags & MMU_CAM_PGSZ_MASK;
+       e->endian       = flags & MMU_RAM_ENDIAN_MASK;
+       e->elsz         = flags & MMU_RAM_ELSZ_MASK;
+       e->mixed        = flags & MMU_RAM_MIXED_MASK;
+
+       return iopgsz_to_bytes(e->pgsz);
+}
+
 static int omap_iommu_map(struct iommu_domain *domain, unsigned long da,
                         phys_addr_t pa, size_t bytes, int prot)
 {
similarity index 70%
rename from arch/arm/plat-omap/include/plat/iommu.h
rename to drivers/iommu/omap-iommu.h
index 68b5f0362f356a0adb402706fec5378828d716ae..1200842066025dec7c6da98791ce64919b858fdd 100644 (file)
@@ -10,8 +10,9 @@
  * published by the Free Software Foundation.
  */
 
-#ifndef __MACH_IOMMU_H
-#define __MACH_IOMMU_H
+#if defined(CONFIG_ARCH_OMAP1)
+#error "iommu for this processor not implemented yet"
+#endif
 
 struct iotlb_entry {
        u32 da;
@@ -28,7 +29,6 @@ struct iotlb_entry {
 struct omap_iommu {
        const char      *name;
        struct module   *owner;
-       struct clk      *clk;
        void __iomem    *regbase;
        struct device   *dev;
        void            *isr_priv;
@@ -71,11 +71,6 @@ struct cr_regs {
        };
 };
 
-struct iotlb_lock {
-       short base;
-       short vict;
-};
-
 /* architecture specific functions */
 struct iommu_functions {
        unsigned long   version;
@@ -103,42 +98,6 @@ struct iommu_functions {
        ssize_t (*dump_ctx)(struct omap_iommu *obj, char *buf, ssize_t len);
 };
 
-/**
- * struct omap_mmu_dev_attr - OMAP mmu device attributes for omap_hwmod
- * @da_start:          device address where the va space starts.
- * @da_end:            device address where the va space ends.
- * @nr_tlb_entries:    number of entries supported by the translation
- *                     look-aside buffer (TLB).
- */
-struct omap_mmu_dev_attr {
-       u32 da_start;
-       u32 da_end;
-       int nr_tlb_entries;
-};
-
-struct iommu_platform_data {
-       const char *name;
-       const char *clk_name;
-       const int nr_tlb_entries;
-       u32 da_start;
-       u32 da_end;
-};
-
-/**
- * struct iommu_arch_data - omap iommu private data
- * @name: name of the iommu device
- * @iommu_dev: handle of the iommu device
- *
- * This is an omap iommu private data object, which binds an iommu user
- * to its iommu device. This object should be placed at the iommu user's
- * dev_archdata so generic IOMMU API can be used without having to
- * utilize omap-specific plumbing anymore.
- */
-struct omap_iommu_arch_data {
-       const char *name;
-       struct omap_iommu *iommu_dev;
-};
-
 #ifdef CONFIG_IOMMU_API
 /**
  * dev_to_omap_iommu() - retrieves an omap iommu object from a user device
@@ -152,18 +111,57 @@ static inline struct omap_iommu *dev_to_omap_iommu(struct device *dev)
 }
 #endif
 
-/* IOMMU errors */
-#define OMAP_IOMMU_ERR_TLB_MISS                (1 << 0)
-#define OMAP_IOMMU_ERR_TRANS_FAULT     (1 << 1)
-#define OMAP_IOMMU_ERR_EMU_MISS                (1 << 2)
-#define OMAP_IOMMU_ERR_TBLWALK_FAULT   (1 << 3)
-#define OMAP_IOMMU_ERR_MULTIHIT_FAULT  (1 << 4)
+/*
+ * MMU Register offsets
+ */
+#define MMU_REVISION           0x00
+#define MMU_IRQSTATUS          0x18
+#define MMU_IRQENABLE          0x1c
+#define MMU_WALKING_ST         0x40
+#define MMU_CNTL               0x44
+#define MMU_FAULT_AD           0x48
+#define MMU_TTB                        0x4c
+#define MMU_LOCK               0x50
+#define MMU_LD_TLB             0x54
+#define MMU_CAM                        0x58
+#define MMU_RAM                        0x5c
+#define MMU_GFLUSH             0x60
+#define MMU_FLUSH_ENTRY                0x64
+#define MMU_READ_CAM           0x68
+#define MMU_READ_RAM           0x6c
+#define MMU_EMU_FAULT_AD       0x70
+
+#define MMU_REG_SIZE           256
 
-#if defined(CONFIG_ARCH_OMAP1)
-#error "iommu for this processor not implemented yet"
-#else
-#include <plat/iommu2.h>
-#endif
+/*
+ * MMU Register bit definitions
+ */
+#define MMU_CAM_VATAG_SHIFT    12
+#define MMU_CAM_VATAG_MASK \
+       ((~0UL >> MMU_CAM_VATAG_SHIFT) << MMU_CAM_VATAG_SHIFT)
+#define MMU_CAM_P              (1 << 3)
+#define MMU_CAM_V              (1 << 2)
+#define MMU_CAM_PGSZ_MASK      3
+#define MMU_CAM_PGSZ_1M                (0 << 0)
+#define MMU_CAM_PGSZ_64K       (1 << 0)
+#define MMU_CAM_PGSZ_4K                (2 << 0)
+#define MMU_CAM_PGSZ_16M       (3 << 0)
+
+#define MMU_RAM_PADDR_SHIFT    12
+#define MMU_RAM_PADDR_MASK \
+       ((~0UL >> MMU_RAM_PADDR_SHIFT) << MMU_RAM_PADDR_SHIFT)
+
+#define MMU_RAM_ENDIAN_MASK    (1 << MMU_RAM_ENDIAN_SHIFT)
+#define MMU_RAM_ENDIAN_BIG     (1 << MMU_RAM_ENDIAN_SHIFT)
+
+#define MMU_RAM_ELSZ_MASK      (3 << MMU_RAM_ELSZ_SHIFT)
+#define MMU_RAM_ELSZ_8         (0 << MMU_RAM_ELSZ_SHIFT)
+#define MMU_RAM_ELSZ_16                (1 << MMU_RAM_ELSZ_SHIFT)
+#define MMU_RAM_ELSZ_32                (2 << MMU_RAM_ELSZ_SHIFT)
+#define MMU_RAM_ELSZ_NONE      (3 << MMU_RAM_ELSZ_SHIFT)
+#define MMU_RAM_MIXED_SHIFT    6
+#define MMU_RAM_MIXED_MASK     (1 << MMU_RAM_MIXED_SHIFT)
+#define MMU_RAM_MIXED          MMU_RAM_MIXED_MASK
 
 /*
  * utilities for super page(16MB, 1MB, 64KB and 4KB)
@@ -199,23 +197,29 @@ extern void omap_iotlb_cr_to_e(struct cr_regs *cr, struct iotlb_entry *e);
 extern int
 omap_iopgtable_store_entry(struct omap_iommu *obj, struct iotlb_entry *e);
 
-extern int omap_iommu_set_isr(const char *name,
-                int (*isr)(struct omap_iommu *obj, u32 da, u32 iommu_errs,
-                                   void *priv),
-                        void *isr_priv);
-
 extern void omap_iommu_save_ctx(struct device *dev);
 extern void omap_iommu_restore_ctx(struct device *dev);
 
-extern int omap_install_iommu_arch(const struct iommu_functions *ops);
-extern void omap_uninstall_iommu_arch(const struct iommu_functions *ops);
-
 extern int omap_foreach_iommu_device(void *data,
                                int (*fn)(struct device *, void *));
 
+extern int omap_install_iommu_arch(const struct iommu_functions *ops);
+extern void omap_uninstall_iommu_arch(const struct iommu_functions *ops);
+
 extern ssize_t
 omap_iommu_dump_ctx(struct omap_iommu *obj, char *buf, ssize_t len);
 extern size_t
 omap_dump_tlb_entries(struct omap_iommu *obj, char *buf, ssize_t len);
 
-#endif /* __MACH_IOMMU_H */
+/*
+ * register accessors
+ */
+static inline u32 iommu_read_reg(struct omap_iommu *obj, size_t offs)
+{
+       return __raw_readl(obj->regbase + offs);
+}
+
+static inline void iommu_write_reg(struct omap_iommu *obj, u32 val, size_t offs)
+{
+       __raw_writel(val, obj->regbase + offs);
+}
similarity index 88%
rename from arch/arm/mach-omap2/iommu2.c
rename to drivers/iommu/omap-iommu2.c
index eefc37912ef37fce2b65236f0f4f60ee34c6b99d..d745094a69ddf180eeea86b4727a844008383682 100644 (file)
 
 #include <linux/err.h>
 #include <linux/device.h>
+#include <linux/io.h>
 #include <linux/jiffies.h>
 #include <linux/module.h>
+#include <linux/omap-iommu.h>
 #include <linux/slab.h>
 #include <linux/stringify.h>
+#include <linux/platform_data/iommu-omap.h>
 
-#include <plat/iommu.h>
+#include "omap-iommu.h"
 
 /*
  * omap2 architecture specific register bit definitions
  */
 #define IOMMU_ARCH_VERSION     0x00000011
 
-/* SYSCONF */
-#define MMU_SYS_IDLE_SHIFT     3
-#define MMU_SYS_IDLE_FORCE     (0 << MMU_SYS_IDLE_SHIFT)
-#define MMU_SYS_IDLE_NONE      (1 << MMU_SYS_IDLE_SHIFT)
-#define MMU_SYS_IDLE_SMART     (2 << MMU_SYS_IDLE_SHIFT)
-#define MMU_SYS_IDLE_MASK      (3 << MMU_SYS_IDLE_SHIFT)
-
-#define MMU_SYS_SOFTRESET      (1 << 1)
-#define MMU_SYS_AUTOIDLE       1
-
-/* SYSSTATUS */
-#define MMU_SYS_RESETDONE      1
-
 /* IRQSTATUS & IRQENABLE */
 #define MMU_IRQ_MULTIHITFAULT  (1 << 4)
 #define MMU_IRQ_TABLEWALKFAULT (1 << 3)
         ((pgsz) == MMU_CAM_PGSZ_64K) ? 0xffff0000 :    \
         ((pgsz) == MMU_CAM_PGSZ_4K)  ? 0xfffff000 : 0)
 
+/* IOMMU errors */
+#define OMAP_IOMMU_ERR_TLB_MISS                (1 << 0)
+#define OMAP_IOMMU_ERR_TRANS_FAULT     (1 << 1)
+#define OMAP_IOMMU_ERR_EMU_MISS                (1 << 2)
+#define OMAP_IOMMU_ERR_TBLWALK_FAULT   (1 << 3)
+#define OMAP_IOMMU_ERR_MULTIHIT_FAULT  (1 << 4)
 
 static void __iommu_set_twl(struct omap_iommu *obj, bool on)
 {
@@ -88,7 +84,6 @@ static void __iommu_set_twl(struct omap_iommu *obj, bool on)
 static int omap2_iommu_enable(struct omap_iommu *obj)
 {
        u32 l, pa;
-       unsigned long timeout;
 
        if (!obj->iopgd || !IS_ALIGNED((u32)obj->iopgd,  SZ_16K))
                return -EINVAL;
@@ -97,29 +92,10 @@ static int omap2_iommu_enable(struct omap_iommu *obj)
        if (!IS_ALIGNED(pa, SZ_16K))
                return -EINVAL;
 
-       iommu_write_reg(obj, MMU_SYS_SOFTRESET, MMU_SYSCONFIG);
-
-       timeout = jiffies + msecs_to_jiffies(20);
-       do {
-               l = iommu_read_reg(obj, MMU_SYSSTATUS);
-               if (l & MMU_SYS_RESETDONE)
-                       break;
-       } while (!time_after(jiffies, timeout));
-
-       if (!(l & MMU_SYS_RESETDONE)) {
-               dev_err(obj->dev, "can't take mmu out of reset\n");
-               return -ENODEV;
-       }
-
        l = iommu_read_reg(obj, MMU_REVISION);
        dev_info(obj->dev, "%s: version %d.%d\n", obj->name,
                 (l >> 4) & 0xf, l & 0xf);
 
-       l = iommu_read_reg(obj, MMU_SYSCONFIG);
-       l &= ~MMU_SYS_IDLE_MASK;
-       l |= (MMU_SYS_IDLE_SMART | MMU_SYS_AUTOIDLE);
-       iommu_write_reg(obj, l, MMU_SYSCONFIG);
-
        iommu_write_reg(obj, pa, MMU_TTB);
 
        __iommu_set_twl(obj, true);
@@ -133,7 +109,6 @@ static void omap2_iommu_disable(struct omap_iommu *obj)
 
        l &= ~MMU_CNTL_MASK;
        iommu_write_reg(obj, l, MMU_CNTL);
-       iommu_write_reg(obj, MMU_SYS_IDLE_FORCE, MMU_SYSCONFIG);
 
        dev_dbg(obj->dev, "%s is shutting down\n", obj->name);
 }
@@ -262,8 +237,6 @@ omap2_iommu_dump_ctx(struct omap_iommu *obj, char *buf, ssize_t len)
        char *p = buf;
 
        pr_reg(REVISION);
-       pr_reg(SYSCONFIG);
-       pr_reg(SYSSTATUS);
        pr_reg(IRQSTATUS);
        pr_reg(IRQENABLE);
        pr_reg(WALKING_ST);
similarity index 85%
rename from arch/arm/plat-omap/include/plat/iopgtable.h
rename to drivers/iommu/omap-iopgtable.h
index 66a813977d52f453c155b45710028f087e1dec35..cd4ae9e5b0c6bf20bc485c448ca00ed059478ebe 100644 (file)
@@ -10,9 +10,6 @@
  * published by the Free Software Foundation.
  */
 
-#ifndef __PLAT_OMAP_IOMMU_H
-#define __PLAT_OMAP_IOMMU_H
-
 /*
  * "L2 table" address mask and size definitions.
  */
@@ -97,24 +94,5 @@ static inline phys_addr_t omap_iommu_translate(u32 d, u32 va, u32 mask)
 #define iopte_index(da)                (((da) >> IOPTE_SHIFT) & (PTRS_PER_IOPTE - 1))
 #define iopte_offset(iopgd, da)        (iopgd_page_vaddr(iopgd) + iopte_index(da))
 
-static inline u32 iotlb_init_entry(struct iotlb_entry *e, u32 da, u32 pa,
-                                  u32 flags)
-{
-       memset(e, 0, sizeof(*e));
-
-       e->da           = da;
-       e->pa           = pa;
-       e->valid        = 1;
-       /* FIXME: add OMAP1 support */
-       e->pgsz         = flags & MMU_CAM_PGSZ_MASK;
-       e->endian       = flags & MMU_RAM_ENDIAN_MASK;
-       e->elsz         = flags & MMU_RAM_ELSZ_MASK;
-       e->mixed        = flags & MMU_RAM_MIXED_MASK;
-
-       return iopgsz_to_bytes(e->pgsz);
-}
-
 #define to_iommu(dev)                                                  \
        (struct omap_iommu *)platform_get_drvdata(to_platform_device(dev))
-
-#endif /* __PLAT_OMAP_IOMMU_H */
index 2e10c3e0a7aee3eaa3815f473e06d6999ce8866b..46d87569073951c7c63cbd13a354e9ff91a0941f 100644 (file)
 #include <linux/device.h>
 #include <linux/scatterlist.h>
 #include <linux/iommu.h>
+#include <linux/omap-iommu.h>
+#include <linux/platform_data/iommu-omap.h>
 
 #include <asm/cacheflush.h>
 #include <asm/mach/map.h>
 
-#include <plat/iommu.h>
-#include <plat/iovmm.h>
+#include "omap-iopgtable.h"
+#include "omap-iommu.h"
 
-#include <plat/iopgtable.h>
+/*
+ * IOVMF_FLAGS: attribute for iommu virtual memory area(iovma)
+ *
+ * lower 16 bit is used for h/w and upper 16 bit is for s/w.
+ */
+#define IOVMF_SW_SHIFT         16
+
+/*
+ * iovma: h/w flags derived from cam and ram attribute
+ */
+#define IOVMF_CAM_MASK         (~((1 << 10) - 1))
+#define IOVMF_RAM_MASK         (~IOVMF_CAM_MASK)
+
+#define IOVMF_PGSZ_MASK                (3 << 0)
+#define IOVMF_PGSZ_1M          MMU_CAM_PGSZ_1M
+#define IOVMF_PGSZ_64K         MMU_CAM_PGSZ_64K
+#define IOVMF_PGSZ_4K          MMU_CAM_PGSZ_4K
+#define IOVMF_PGSZ_16M         MMU_CAM_PGSZ_16M
+
+#define IOVMF_ENDIAN_MASK      (1 << 9)
+#define IOVMF_ENDIAN_BIG       MMU_RAM_ENDIAN_BIG
+
+#define IOVMF_ELSZ_MASK                (3 << 7)
+#define IOVMF_ELSZ_16          MMU_RAM_ELSZ_16
+#define IOVMF_ELSZ_32          MMU_RAM_ELSZ_32
+#define IOVMF_ELSZ_NONE                MMU_RAM_ELSZ_NONE
+
+#define IOVMF_MIXED_MASK       (1 << 6)
+#define IOVMF_MIXED            MMU_RAM_MIXED
+
+/*
+ * iovma: s/w flags, used for mapping and umapping internally.
+ */
+#define IOVMF_MMIO             (1 << IOVMF_SW_SHIFT)
+#define IOVMF_ALLOC            (2 << IOVMF_SW_SHIFT)
+#define IOVMF_ALLOC_MASK       (3 << IOVMF_SW_SHIFT)
+
+/* "superpages" is supported just with physically linear pages */
+#define IOVMF_DISCONT          (1 << (2 + IOVMF_SW_SHIFT))
+#define IOVMF_LINEAR           (2 << (2 + IOVMF_SW_SHIFT))
+#define IOVMF_LINEAR_MASK      (3 << (2 + IOVMF_SW_SHIFT))
+
+#define IOVMF_DA_FIXED         (1 << (4 + IOVMF_SW_SHIFT))
 
 static struct kmem_cache *iovm_area_cachep;
 
index c16e8fc8a4bd11677971140d6c2d20f48e6e3582..4c9db62814ffde1c2f3cc513eda788490cb000f4 100644 (file)
@@ -398,6 +398,7 @@ static int tegra_gart_probe(struct platform_device *pdev)
        do_gart_setup(gart, NULL);
 
        gart_handle = gart;
+       bus_set_iommu(&platform_bus_type, &gart_iommu_ops);
        return 0;
 
 fail:
@@ -450,7 +451,6 @@ static struct platform_driver tegra_gart_driver = {
 
 static int __devinit tegra_gart_init(void)
 {
-       bus_set_iommu(&platform_bus_type, &gart_iommu_ops);
        return platform_driver_register(&tegra_gart_driver);
 }
 
index a649f146d17bad0b62d15a1d174c57147a9a2a2f..843123acbb8dd430c2813d85ee5c24091575531b 100644 (file)
@@ -696,10 +696,8 @@ static void __smmu_iommu_unmap(struct smmu_as *as, dma_addr_t iova)
        *pte = _PTE_VACANT(iova);
        FLUSH_CPU_DCACHE(pte, page, sizeof(*pte));
        flush_ptc_and_tlb(as->smmu, as, iova, pte, page, 0);
-       if (!--(*count)) {
+       if (!--(*count))
                free_ptbl(as, iova);
-               smmu_flush_regs(as->smmu, 0);
-       }
 }
 
 static void __smmu_iommu_map_pfn(struct smmu_as *as, dma_addr_t iova,
@@ -1054,6 +1052,7 @@ static int smmu_debugfs_stats_show(struct seq_file *s, void *v)
                        stats[i], val, offs);
        }
        seq_printf(s, "\n");
+       dput(dent);
 
        return 0;
 }
@@ -1233,6 +1232,7 @@ static int tegra_smmu_probe(struct platform_device *pdev)
 
        smmu_debugfs_create(smmu);
        smmu_handle = smmu;
+       bus_set_iommu(&platform_bus_type, &smmu_iommu_ops);
        return 0;
 }
 
@@ -1277,7 +1277,6 @@ static struct platform_driver tegra_smmu_driver = {
 
 static int __devinit tegra_smmu_init(void)
 {
-       bus_set_iommu(&platform_bus_type, &smmu_iommu_ops);
        return platform_driver_register(&tegra_smmu_driver);
 }
 
index 02db9183ca01e8b64ce54a649dacc943c883f38f..77e6eff41cae9bb7c693aac363c509f65c44251d 100644 (file)
@@ -740,8 +740,14 @@ static void rq_completed(struct mapped_device *md, int rw, int run_queue)
        if (!md_in_flight(md))
                wake_up(&md->wait);
 
+       /*
+        * Run this off this callpath, as drivers could invoke end_io while
+        * inside their request_fn (and holding the queue lock). Calling
+        * back into ->request_fn() could deadlock attempting to grab the
+        * queue lock again.
+        */
        if (run_queue)
-               blk_run_queue(md->queue);
+               blk_run_queue_async(md->queue);
 
        /*
         * dm_put() must be at the end of this function. See the comment above
index 9ab768acfb623f8bbb13870e5f65150a60ecad07..61200717687b85b3fed040f9599ffd1987b8842d 100644 (file)
@@ -1817,10 +1817,10 @@ retry:
                        memset(bbp, 0xff, PAGE_SIZE);
 
                        for (i = 0 ; i < bb->count ; i++) {
-                               u64 internal_bb = *p++;
+                               u64 internal_bb = p[i];
                                u64 store_bb = ((BB_OFFSET(internal_bb) << 10)
                                                | BB_LEN(internal_bb));
-                               *bbp++ = cpu_to_le64(store_bb);
+                               bbp[i] = cpu_to_le64(store_bb);
                        }
                        bb->changed = 0;
                        if (read_seqretry(&bb->lock, seq))
@@ -5294,7 +5294,7 @@ void md_stop_writes(struct mddev *mddev)
 }
 EXPORT_SYMBOL_GPL(md_stop_writes);
 
-void md_stop(struct mddev *mddev)
+static void __md_stop(struct mddev *mddev)
 {
        mddev->ready = 0;
        mddev->pers->stop(mddev);
@@ -5304,6 +5304,18 @@ void md_stop(struct mddev *mddev)
        mddev->pers = NULL;
        clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
 }
+
+void md_stop(struct mddev *mddev)
+{
+       /* stop the array and free an attached data structures.
+        * This is called from dm-raid
+        */
+       __md_stop(mddev);
+       bitmap_destroy(mddev);
+       if (mddev->bio_set)
+               bioset_free(mddev->bio_set);
+}
+
 EXPORT_SYMBOL_GPL(md_stop);
 
 static int md_set_readonly(struct mddev *mddev, struct block_device *bdev)
@@ -5364,7 +5376,7 @@ static int do_md_stop(struct mddev * mddev, int mode,
                        set_disk_ro(disk, 0);
 
                __md_stop_writes(mddev);
-               md_stop(mddev);
+               __md_stop(mddev);
                mddev->queue->merge_bvec_fn = NULL;
                mddev->queue->backing_dev_info.congested_fn = NULL;
 
@@ -7936,9 +7948,9 @@ int md_is_badblock(struct badblocks *bb, sector_t s, int sectors,
                   sector_t *first_bad, int *bad_sectors)
 {
        int hi;
-       int lo = 0;
+       int lo;
        u64 *p = bb->page;
-       int rv = 0;
+       int rv;
        sector_t target = s + sectors;
        unsigned seq;
 
@@ -7953,7 +7965,8 @@ int md_is_badblock(struct badblocks *bb, sector_t s, int sectors,
 
 retry:
        seq = read_seqbegin(&bb->lock);
-
+       lo = 0;
+       rv = 0;
        hi = bb->count;
 
        /* Binary search between lo and hi for 'target'
index 636bae0405e8167edcec328e5759b3f949dd0876..a0f73092176e06cd736885496e02a5fab601dffe 100644 (file)
@@ -963,7 +963,7 @@ static void raid1_unplug(struct blk_plug_cb *cb, bool from_schedule)
        struct r1conf *conf = mddev->private;
        struct bio *bio;
 
-       if (from_schedule) {
+       if (from_schedule || current->bio_list) {
                spin_lock_irq(&conf->device_lock);
                bio_list_merge(&conf->pending_bio_list, &plug->pending);
                conf->pending_count += plug->pending_cnt;
index d1295aff41739eea048f0e43513dfba6ade4c8f1..c9acbd717131ba8e28f4362d3e1aca967922ede8 100644 (file)
@@ -499,7 +499,7 @@ static void raid10_end_write_request(struct bio *bio, int error)
         */
        one_write_done(r10_bio);
        if (dec_rdev)
-               rdev_dec_pending(conf->mirrors[dev].rdev, conf->mddev);
+               rdev_dec_pending(rdev, conf->mddev);
 }
 
 /*
@@ -1069,7 +1069,7 @@ static void raid10_unplug(struct blk_plug_cb *cb, bool from_schedule)
        struct r10conf *conf = mddev->private;
        struct bio *bio;
 
-       if (from_schedule) {
+       if (from_schedule || current->bio_list) {
                spin_lock_irq(&conf->device_lock);
                bio_list_merge(&conf->pending_bio_list, &plug->pending);
                conf->pending_count += plug->pending_cnt;
@@ -1334,18 +1334,21 @@ retry_write:
                        blocked_rdev = rrdev;
                        break;
                }
+               if (rdev && (test_bit(Faulty, &rdev->flags)
+                            || test_bit(Unmerged, &rdev->flags)))
+                       rdev = NULL;
                if (rrdev && (test_bit(Faulty, &rrdev->flags)
                              || test_bit(Unmerged, &rrdev->flags)))
                        rrdev = NULL;
 
                r10_bio->devs[i].bio = NULL;
                r10_bio->devs[i].repl_bio = NULL;
-               if (!rdev || test_bit(Faulty, &rdev->flags) ||
-                   test_bit(Unmerged, &rdev->flags)) {
+
+               if (!rdev && !rrdev) {
                        set_bit(R10BIO_Degraded, &r10_bio->state);
                        continue;
                }
-               if (test_bit(WriteErrorSeen, &rdev->flags)) {
+               if (rdev && test_bit(WriteErrorSeen, &rdev->flags)) {
                        sector_t first_bad;
                        sector_t dev_sector = r10_bio->devs[i].addr;
                        int bad_sectors;
@@ -1387,8 +1390,10 @@ retry_write:
                                        max_sectors = good_sectors;
                        }
                }
-               r10_bio->devs[i].bio = bio;
-               atomic_inc(&rdev->nr_pending);
+               if (rdev) {
+                       r10_bio->devs[i].bio = bio;
+                       atomic_inc(&rdev->nr_pending);
+               }
                if (rrdev) {
                        r10_bio->devs[i].repl_bio = bio;
                        atomic_inc(&rrdev->nr_pending);
@@ -1444,69 +1449,71 @@ retry_write:
        for (i = 0; i < conf->copies; i++) {
                struct bio *mbio;
                int d = r10_bio->devs[i].devnum;
-               if (!r10_bio->devs[i].bio)
-                       continue;
+               if (r10_bio->devs[i].bio) {
+                       struct md_rdev *rdev = conf->mirrors[d].rdev;
+                       mbio = bio_clone_mddev(bio, GFP_NOIO, mddev);
+                       md_trim_bio(mbio, r10_bio->sector - bio->bi_sector,
+                                   max_sectors);
+                       r10_bio->devs[i].bio = mbio;
+
+                       mbio->bi_sector = (r10_bio->devs[i].addr+
+                                          choose_data_offset(r10_bio,
+                                                             rdev));
+                       mbio->bi_bdev = rdev->bdev;
+                       mbio->bi_end_io = raid10_end_write_request;
+                       mbio->bi_rw = WRITE | do_sync | do_fua | do_discard;
+                       mbio->bi_private = r10_bio;
 
-               mbio = bio_clone_mddev(bio, GFP_NOIO, mddev);
-               md_trim_bio(mbio, r10_bio->sector - bio->bi_sector,
-                           max_sectors);
-               r10_bio->devs[i].bio = mbio;
+                       atomic_inc(&r10_bio->remaining);
 
-               mbio->bi_sector = (r10_bio->devs[i].addr+
-                                  choose_data_offset(r10_bio,
-                                                     conf->mirrors[d].rdev));
-               mbio->bi_bdev = conf->mirrors[d].rdev->bdev;
-               mbio->bi_end_io = raid10_end_write_request;
-               mbio->bi_rw = WRITE | do_sync | do_fua | do_discard;
-               mbio->bi_private = r10_bio;
+                       cb = blk_check_plugged(raid10_unplug, mddev,
+                                              sizeof(*plug));
+                       if (cb)
+                               plug = container_of(cb, struct raid10_plug_cb,
+                                                   cb);
+                       else
+                               plug = NULL;
+                       spin_lock_irqsave(&conf->device_lock, flags);
+                       if (plug) {
+                               bio_list_add(&plug->pending, mbio);
+                               plug->pending_cnt++;
+                       } else {
+                               bio_list_add(&conf->pending_bio_list, mbio);
+                               conf->pending_count++;
+                       }
+                       spin_unlock_irqrestore(&conf->device_lock, flags);
+                       if (!plug)
+                               md_wakeup_thread(mddev->thread);
+               }
 
-               atomic_inc(&r10_bio->remaining);
+               if (r10_bio->devs[i].repl_bio) {
+                       struct md_rdev *rdev = conf->mirrors[d].replacement;
+                       if (rdev == NULL) {
+                               /* Replacement just got moved to main 'rdev' */
+                               smp_mb();
+                               rdev = conf->mirrors[d].rdev;
+                       }
+                       mbio = bio_clone_mddev(bio, GFP_NOIO, mddev);
+                       md_trim_bio(mbio, r10_bio->sector - bio->bi_sector,
+                                   max_sectors);
+                       r10_bio->devs[i].repl_bio = mbio;
+
+                       mbio->bi_sector = (r10_bio->devs[i].addr +
+                                          choose_data_offset(
+                                                  r10_bio, rdev));
+                       mbio->bi_bdev = rdev->bdev;
+                       mbio->bi_end_io = raid10_end_write_request;
+                       mbio->bi_rw = WRITE | do_sync | do_fua | do_discard;
+                       mbio->bi_private = r10_bio;
 
-               cb = blk_check_plugged(raid10_unplug, mddev, sizeof(*plug));
-               if (cb)
-                       plug = container_of(cb, struct raid10_plug_cb, cb);
-               else
-                       plug = NULL;
-               spin_lock_irqsave(&conf->device_lock, flags);
-               if (plug) {
-                       bio_list_add(&plug->pending, mbio);
-                       plug->pending_cnt++;
-               } else {
+                       atomic_inc(&r10_bio->remaining);
+                       spin_lock_irqsave(&conf->device_lock, flags);
                        bio_list_add(&conf->pending_bio_list, mbio);
                        conf->pending_count++;
+                       spin_unlock_irqrestore(&conf->device_lock, flags);
+                       if (!mddev_check_plugged(mddev))
+                               md_wakeup_thread(mddev->thread);
                }
-               spin_unlock_irqrestore(&conf->device_lock, flags);
-               if (!plug)
-                       md_wakeup_thread(mddev->thread);
-
-               if (!r10_bio->devs[i].repl_bio)
-                       continue;
-
-               mbio = bio_clone_mddev(bio, GFP_NOIO, mddev);
-               md_trim_bio(mbio, r10_bio->sector - bio->bi_sector,
-                           max_sectors);
-               r10_bio->devs[i].repl_bio = mbio;
-
-               /* We are actively writing to the original device
-                * so it cannot disappear, so the replacement cannot
-                * become NULL here
-                */
-               mbio->bi_sector = (r10_bio->devs[i].addr +
-                                  choose_data_offset(
-                                          r10_bio,
-                                          conf->mirrors[d].replacement));
-               mbio->bi_bdev = conf->mirrors[d].replacement->bdev;
-               mbio->bi_end_io = raid10_end_write_request;
-               mbio->bi_rw = WRITE | do_sync | do_fua | do_discard;
-               mbio->bi_private = r10_bio;
-
-               atomic_inc(&r10_bio->remaining);
-               spin_lock_irqsave(&conf->device_lock, flags);
-               bio_list_add(&conf->pending_bio_list, mbio);
-               conf->pending_count++;
-               spin_unlock_irqrestore(&conf->device_lock, flags);
-               if (!mddev_check_plugged(mddev))
-                       md_wakeup_thread(mddev->thread);
        }
 
        /* Don't remove the bias on 'remaining' (one_write_done) until
index c5439dce0295078ecf82094af5474a649284ce61..a4502686e7a8763fb5aeded988f026b2a9dd1c99 100644 (file)
@@ -2774,10 +2774,12 @@ static void handle_stripe_clean_event(struct r5conf *conf,
                        dev = &sh->dev[i];
                        if (!test_bit(R5_LOCKED, &dev->flags) &&
                            (test_bit(R5_UPTODATE, &dev->flags) ||
-                            test_and_clear_bit(R5_Discard, &dev->flags))) {
+                            test_bit(R5_Discard, &dev->flags))) {
                                /* We can return any write requests */
                                struct bio *wbi, *wbi2;
                                pr_debug("Return write for disc %d\n", i);
+                               if (test_and_clear_bit(R5_Discard, &dev->flags))
+                                       clear_bit(R5_UPTODATE, &dev->flags);
                                wbi = dev->written;
                                dev->written = NULL;
                                while (wbi && wbi->bi_sector <
@@ -2795,7 +2797,8 @@ static void handle_stripe_clean_event(struct r5conf *conf,
                                         !test_bit(STRIPE_DEGRADED, &sh->state),
                                                0);
                        }
-               }
+               } else if (test_bit(R5_Discard, &sh->dev[i].flags))
+                       clear_bit(R5_Discard, &sh->dev[i].flags);
 
        if (test_and_clear_bit(STRIPE_FULL_WRITE, &sh->state))
                if (atomic_dec_and_test(&conf->pending_full_writes))
@@ -3490,40 +3493,6 @@ static void handle_stripe(struct stripe_head *sh)
                        handle_failed_sync(conf, sh, &s);
        }
 
-       /*
-        * might be able to return some write requests if the parity blocks
-        * are safe, or on a failed drive
-        */
-       pdev = &sh->dev[sh->pd_idx];
-       s.p_failed = (s.failed >= 1 && s.failed_num[0] == sh->pd_idx)
-               || (s.failed >= 2 && s.failed_num[1] == sh->pd_idx);
-       qdev = &sh->dev[sh->qd_idx];
-       s.q_failed = (s.failed >= 1 && s.failed_num[0] == sh->qd_idx)
-               || (s.failed >= 2 && s.failed_num[1] == sh->qd_idx)
-               || conf->level < 6;
-
-       if (s.written &&
-           (s.p_failed || ((test_bit(R5_Insync, &pdev->flags)
-                            && !test_bit(R5_LOCKED, &pdev->flags)
-                            && (test_bit(R5_UPTODATE, &pdev->flags) ||
-                                test_bit(R5_Discard, &pdev->flags))))) &&
-           (s.q_failed || ((test_bit(R5_Insync, &qdev->flags)
-                            && !test_bit(R5_LOCKED, &qdev->flags)
-                            && (test_bit(R5_UPTODATE, &qdev->flags) ||
-                                test_bit(R5_Discard, &qdev->flags))))))
-               handle_stripe_clean_event(conf, sh, disks, &s.return_bi);
-
-       /* Now we might consider reading some blocks, either to check/generate
-        * parity, or to satisfy requests
-        * or to load a block that is being partially written.
-        */
-       if (s.to_read || s.non_overwrite
-           || (conf->level == 6 && s.to_write && s.failed)
-           || (s.syncing && (s.uptodate + s.compute < disks))
-           || s.replacing
-           || s.expanding)
-               handle_stripe_fill(sh, &s, disks);
-
        /* Now we check to see if any write operations have recently
         * completed
         */
@@ -3561,6 +3530,40 @@ static void handle_stripe(struct stripe_head *sh)
                        s.dec_preread_active = 1;
        }
 
+       /*
+        * might be able to return some write requests if the parity blocks
+        * are safe, or on a failed drive
+        */
+       pdev = &sh->dev[sh->pd_idx];
+       s.p_failed = (s.failed >= 1 && s.failed_num[0] == sh->pd_idx)
+               || (s.failed >= 2 && s.failed_num[1] == sh->pd_idx);
+       qdev = &sh->dev[sh->qd_idx];
+       s.q_failed = (s.failed >= 1 && s.failed_num[0] == sh->qd_idx)
+               || (s.failed >= 2 && s.failed_num[1] == sh->qd_idx)
+               || conf->level < 6;
+
+       if (s.written &&
+           (s.p_failed || ((test_bit(R5_Insync, &pdev->flags)
+                            && !test_bit(R5_LOCKED, &pdev->flags)
+                            && (test_bit(R5_UPTODATE, &pdev->flags) ||
+                                test_bit(R5_Discard, &pdev->flags))))) &&
+           (s.q_failed || ((test_bit(R5_Insync, &qdev->flags)
+                            && !test_bit(R5_LOCKED, &qdev->flags)
+                            && (test_bit(R5_UPTODATE, &qdev->flags) ||
+                                test_bit(R5_Discard, &qdev->flags))))))
+               handle_stripe_clean_event(conf, sh, disks, &s.return_bi);
+
+       /* Now we might consider reading some blocks, either to check/generate
+        * parity, or to satisfy requests
+        * or to load a block that is being partially written.
+        */
+       if (s.to_read || s.non_overwrite
+           || (conf->level == 6 && s.to_write && s.failed)
+           || (s.syncing && (s.uptodate + s.compute < disks))
+           || s.replacing
+           || s.expanding)
+               handle_stripe_fill(sh, &s, disks);
+
        /* Now to consider new write requests and what else, if anything
         * should be read.  We do not handle new writes when:
         * 1/ A 'write' operation (copy+xor) is already in flight.
@@ -5529,6 +5532,10 @@ static int run(struct mddev *mddev)
                 * discard data disk but write parity disk
                 */
                stripe = stripe * PAGE_SIZE;
+               /* Round up to power of 2, as discard handling
+                * currently assumes that */
+               while ((stripe-1) & stripe)
+                       stripe = (stripe | (stripe-1)) + 1;
                mddev->queue->limits.discard_alignment = stripe;
                mddev->queue->limits.discard_granularity = stripe;
                /*
index 262dfa503c2a3e2db6cca50a5028d57ca46736df..b551ca350e00005bdcf93637a5e8b153f66e844a 100644 (file)
@@ -300,15 +300,15 @@ static enum fe_stv0900_error stv0900_set_mclk(struct stv0900_internal *intp, u32
 {
        u32 m_div, clk_sel;
 
-       dprintk("%s: Mclk set to %d, Quartz = %d\n", __func__, mclk,
-                       intp->quartz);
-
        if (intp == NULL)
                return STV0900_INVALID_HANDLE;
 
        if (intp->errs)
                return STV0900_I2C_ERROR;
 
+       dprintk("%s: Mclk set to %d, Quartz = %d\n", __func__, mclk,
+                       intp->quartz);
+
        clk_sel = ((stv0900_get_bits(intp, F0900_SELX1RATIO) == 1) ? 4 : 6);
        m_div = ((clk_sel * mclk) / intp->quartz) - 1;
        stv0900_write_bits(intp, F0900_M_DIV, m_div);
index 109bc9b12e740eec80dda9e0eb9dea30a530fb5e..05f8950f6f91b54cbad5f195fcfecd3cc6a784c1 100644 (file)
@@ -53,8 +53,7 @@ MODULE_LICENSE("GPL");
 /* ADV7604 system clock frequency */
 #define ADV7604_fsc (28636360)
 
-#define DIGITAL_INPUT ((state->prim_mode == ADV7604_PRIM_MODE_HDMI_COMP) || \
-                       (state->prim_mode == ADV7604_PRIM_MODE_HDMI_GR))
+#define DIGITAL_INPUT (state->mode == ADV7604_MODE_HDMI)
 
 /*
  **********************************************************************
@@ -68,7 +67,7 @@ struct adv7604_state {
        struct v4l2_subdev sd;
        struct media_pad pad;
        struct v4l2_ctrl_handler hdl;
-       enum adv7604_prim_mode prim_mode;
+       enum adv7604_mode mode;
        struct v4l2_dv_timings timings;
        u8 edid[256];
        unsigned edid_blocks;
@@ -77,6 +76,7 @@ struct adv7604_state {
        struct workqueue_struct *work_queues;
        struct delayed_work delayed_work_enable_hotplug;
        bool connector_hdmi;
+       bool restart_stdi_once;
 
        /* i2c clients */
        struct i2c_client *i2c_avlink;
@@ -106,7 +106,6 @@ static const struct v4l2_dv_timings adv7604_timings[] = {
        V4L2_DV_BT_CEA_720X576P50,
        V4L2_DV_BT_CEA_1280X720P24,
        V4L2_DV_BT_CEA_1280X720P25,
-       V4L2_DV_BT_CEA_1280X720P30,
        V4L2_DV_BT_CEA_1280X720P50,
        V4L2_DV_BT_CEA_1280X720P60,
        V4L2_DV_BT_CEA_1920X1080P24,
@@ -115,6 +114,7 @@ static const struct v4l2_dv_timings adv7604_timings[] = {
        V4L2_DV_BT_CEA_1920X1080P50,
        V4L2_DV_BT_CEA_1920X1080P60,
 
+       /* sorted by DMT ID */
        V4L2_DV_BT_DMT_640X350P85,
        V4L2_DV_BT_DMT_640X400P85,
        V4L2_DV_BT_DMT_720X400P85,
@@ -164,6 +164,89 @@ static const struct v4l2_dv_timings adv7604_timings[] = {
        { },
 };
 
+struct adv7604_video_standards {
+       struct v4l2_dv_timings timings;
+       u8 vid_std;
+       u8 v_freq;
+};
+
+/* sorted by number of lines */
+static const struct adv7604_video_standards adv7604_prim_mode_comp[] = {
+       /* { V4L2_DV_BT_CEA_720X480P59_94, 0x0a, 0x00 }, TODO flickering */
+       { V4L2_DV_BT_CEA_720X576P50, 0x0b, 0x00 },
+       { V4L2_DV_BT_CEA_1280X720P50, 0x19, 0x01 },
+       { V4L2_DV_BT_CEA_1280X720P60, 0x19, 0x00 },
+       { V4L2_DV_BT_CEA_1920X1080P24, 0x1e, 0x04 },
+       { V4L2_DV_BT_CEA_1920X1080P25, 0x1e, 0x03 },
+       { V4L2_DV_BT_CEA_1920X1080P30, 0x1e, 0x02 },
+       { V4L2_DV_BT_CEA_1920X1080P50, 0x1e, 0x01 },
+       { V4L2_DV_BT_CEA_1920X1080P60, 0x1e, 0x00 },
+       /* TODO add 1920x1080P60_RB (CVT timing) */
+       { },
+};
+
+/* sorted by number of lines */
+static const struct adv7604_video_standards adv7604_prim_mode_gr[] = {
+       { V4L2_DV_BT_DMT_640X480P60, 0x08, 0x00 },
+       { V4L2_DV_BT_DMT_640X480P72, 0x09, 0x00 },
+       { V4L2_DV_BT_DMT_640X480P75, 0x0a, 0x00 },
+       { V4L2_DV_BT_DMT_640X480P85, 0x0b, 0x00 },
+       { V4L2_DV_BT_DMT_800X600P56, 0x00, 0x00 },
+       { V4L2_DV_BT_DMT_800X600P60, 0x01, 0x00 },
+       { V4L2_DV_BT_DMT_800X600P72, 0x02, 0x00 },
+       { V4L2_DV_BT_DMT_800X600P75, 0x03, 0x00 },
+       { V4L2_DV_BT_DMT_800X600P85, 0x04, 0x00 },
+       { V4L2_DV_BT_DMT_1024X768P60, 0x0c, 0x00 },
+       { V4L2_DV_BT_DMT_1024X768P70, 0x0d, 0x00 },
+       { V4L2_DV_BT_DMT_1024X768P75, 0x0e, 0x00 },
+       { V4L2_DV_BT_DMT_1024X768P85, 0x0f, 0x00 },
+       { V4L2_DV_BT_DMT_1280X1024P60, 0x05, 0x00 },
+       { V4L2_DV_BT_DMT_1280X1024P75, 0x06, 0x00 },
+       { V4L2_DV_BT_DMT_1360X768P60, 0x12, 0x00 },
+       { V4L2_DV_BT_DMT_1366X768P60, 0x13, 0x00 },
+       { V4L2_DV_BT_DMT_1400X1050P60, 0x14, 0x00 },
+       { V4L2_DV_BT_DMT_1400X1050P75, 0x15, 0x00 },
+       { V4L2_DV_BT_DMT_1600X1200P60, 0x16, 0x00 }, /* TODO not tested */
+       /* TODO add 1600X1200P60_RB (not a DMT timing) */
+       { V4L2_DV_BT_DMT_1680X1050P60, 0x18, 0x00 },
+       { V4L2_DV_BT_DMT_1920X1200P60_RB, 0x19, 0x00 }, /* TODO not tested */
+       { },
+};
+
+/* sorted by number of lines */
+static const struct adv7604_video_standards adv7604_prim_mode_hdmi_comp[] = {
+       { V4L2_DV_BT_CEA_720X480P59_94, 0x0a, 0x00 },
+       { V4L2_DV_BT_CEA_720X576P50, 0x0b, 0x00 },
+       { V4L2_DV_BT_CEA_1280X720P50, 0x13, 0x01 },
+       { V4L2_DV_BT_CEA_1280X720P60, 0x13, 0x00 },
+       { V4L2_DV_BT_CEA_1920X1080P24, 0x1e, 0x04 },
+       { V4L2_DV_BT_CEA_1920X1080P25, 0x1e, 0x03 },
+       { V4L2_DV_BT_CEA_1920X1080P30, 0x1e, 0x02 },
+       { V4L2_DV_BT_CEA_1920X1080P50, 0x1e, 0x01 },
+       { V4L2_DV_BT_CEA_1920X1080P60, 0x1e, 0x00 },
+       { },
+};
+
+/* sorted by number of lines */
+static const struct adv7604_video_standards adv7604_prim_mode_hdmi_gr[] = {
+       { V4L2_DV_BT_DMT_640X480P60, 0x08, 0x00 },
+       { V4L2_DV_BT_DMT_640X480P72, 0x09, 0x00 },
+       { V4L2_DV_BT_DMT_640X480P75, 0x0a, 0x00 },
+       { V4L2_DV_BT_DMT_640X480P85, 0x0b, 0x00 },
+       { V4L2_DV_BT_DMT_800X600P56, 0x00, 0x00 },
+       { V4L2_DV_BT_DMT_800X600P60, 0x01, 0x00 },
+       { V4L2_DV_BT_DMT_800X600P72, 0x02, 0x00 },
+       { V4L2_DV_BT_DMT_800X600P75, 0x03, 0x00 },
+       { V4L2_DV_BT_DMT_800X600P85, 0x04, 0x00 },
+       { V4L2_DV_BT_DMT_1024X768P60, 0x0c, 0x00 },
+       { V4L2_DV_BT_DMT_1024X768P70, 0x0d, 0x00 },
+       { V4L2_DV_BT_DMT_1024X768P75, 0x0e, 0x00 },
+       { V4L2_DV_BT_DMT_1024X768P85, 0x0f, 0x00 },
+       { V4L2_DV_BT_DMT_1280X1024P60, 0x05, 0x00 },
+       { V4L2_DV_BT_DMT_1280X1024P75, 0x06, 0x00 },
+       { },
+};
+
 /* ----------------------------------------------------------------------- */
 
 static inline struct adv7604_state *to_state(struct v4l2_subdev *sd)
@@ -672,64 +755,144 @@ static int adv7604_s_detect_tx_5v_ctrl(struct v4l2_subdev *sd)
                                ((io_read(sd, 0x6f) & 0x10) >> 4));
 }
 
-static void configure_free_run(struct v4l2_subdev *sd, const struct v4l2_bt_timings *timings)
+static int find_and_set_predefined_video_timings(struct v4l2_subdev *sd,
+               u8 prim_mode,
+               const struct adv7604_video_standards *predef_vid_timings,
+               const struct v4l2_dv_timings *timings)
+{
+       struct adv7604_state *state = to_state(sd);
+       int i;
+
+       for (i = 0; predef_vid_timings[i].timings.bt.width; i++) {
+               if (!v4l_match_dv_timings(timings, &predef_vid_timings[i].timings,
+                                       DIGITAL_INPUT ? 250000 : 1000000))
+                       continue;
+               io_write(sd, 0x00, predef_vid_timings[i].vid_std); /* video std */
+               io_write(sd, 0x01, (predef_vid_timings[i].v_freq << 4) +
+                               prim_mode); /* v_freq and prim mode */
+               return 0;
+       }
+
+       return -1;
+}
+
+static int configure_predefined_video_timings(struct v4l2_subdev *sd,
+               struct v4l2_dv_timings *timings)
 {
+       struct adv7604_state *state = to_state(sd);
+       int err;
+
+       v4l2_dbg(1, debug, sd, "%s", __func__);
+
+       /* reset to default values */
+       io_write(sd, 0x16, 0x43);
+       io_write(sd, 0x17, 0x5a);
+       /* disable embedded syncs for auto graphics mode */
+       cp_write_and_or(sd, 0x81, 0xef, 0x00);
+       cp_write(sd, 0x8f, 0x00);
+       cp_write(sd, 0x90, 0x00);
+       cp_write(sd, 0xa2, 0x00);
+       cp_write(sd, 0xa3, 0x00);
+       cp_write(sd, 0xa4, 0x00);
+       cp_write(sd, 0xa5, 0x00);
+       cp_write(sd, 0xa6, 0x00);
+       cp_write(sd, 0xa7, 0x00);
+       cp_write(sd, 0xab, 0x00);
+       cp_write(sd, 0xac, 0x00);
+
+       switch (state->mode) {
+       case ADV7604_MODE_COMP:
+       case ADV7604_MODE_GR:
+               err = find_and_set_predefined_video_timings(sd,
+                               0x01, adv7604_prim_mode_comp, timings);
+               if (err)
+                       err = find_and_set_predefined_video_timings(sd,
+                                       0x02, adv7604_prim_mode_gr, timings);
+               break;
+       case ADV7604_MODE_HDMI:
+               err = find_and_set_predefined_video_timings(sd,
+                               0x05, adv7604_prim_mode_hdmi_comp, timings);
+               if (err)
+                       err = find_and_set_predefined_video_timings(sd,
+                                       0x06, adv7604_prim_mode_hdmi_gr, timings);
+               break;
+       default:
+               v4l2_dbg(2, debug, sd, "%s: Unknown mode %d\n",
+                               __func__, state->mode);
+               err = -1;
+               break;
+       }
+
+
+       return err;
+}
+
+static void configure_custom_video_timings(struct v4l2_subdev *sd,
+               const struct v4l2_bt_timings *bt)
+{
+       struct adv7604_state *state = to_state(sd);
        struct i2c_client *client = v4l2_get_subdevdata(sd);
-       u32 width = htotal(timings);
-       u32 height = vtotal(timings);
-       u16 ch1_fr_ll = (((u32)timings->pixelclock / 100) > 0) ?
-               ((width * (ADV7604_fsc / 100)) / ((u32)timings->pixelclock / 100)) : 0;
+       u32 width = htotal(bt);
+       u32 height = vtotal(bt);
+       u16 cp_start_sav = bt->hsync + bt->hbackporch - 4;
+       u16 cp_start_eav = width - bt->hfrontporch;
+       u16 cp_start_vbi = height - bt->vfrontporch;
+       u16 cp_end_vbi = bt->vsync + bt->vbackporch;
+       u16 ch1_fr_ll = (((u32)bt->pixelclock / 100) > 0) ?
+               ((width * (ADV7604_fsc / 100)) / ((u32)bt->pixelclock / 100)) : 0;
+       const u8 pll[2] = {
+               0xc0 | ((width >> 8) & 0x1f),
+               width & 0xff
+       };
 
        v4l2_dbg(2, debug, sd, "%s\n", __func__);
 
-       cp_write(sd, 0x8f, (ch1_fr_ll >> 8) & 0x7);     /* CH1_FR_LL */
-       cp_write(sd, 0x90, ch1_fr_ll & 0xff);           /* CH1_FR_LL */
-       cp_write(sd, 0xab, (height >> 4) & 0xff); /* CP_LCOUNT_MAX */
-       cp_write(sd, 0xac, (height & 0x0f) << 4); /* CP_LCOUNT_MAX */
-       /* TODO support interlaced */
-       cp_write(sd, 0x91, 0x10);       /* INTERLACED */
-
-       /* Should only be set in auto-graphics mode [REF_02 p. 91-92] */
-       if ((io_read(sd, 0x00) == 0x07) && (io_read(sd, 0x01) == 0x02)) {
-               u16 cp_start_sav, cp_start_eav, cp_start_vbi, cp_end_vbi;
-               const u8 pll[2] = {
-                       (0xc0 | ((width >> 8) & 0x1f)),
-                       (width & 0xff)
-               };
+       switch (state->mode) {
+       case ADV7604_MODE_COMP:
+       case ADV7604_MODE_GR:
+               /* auto graphics */
+               io_write(sd, 0x00, 0x07); /* video std */
+               io_write(sd, 0x01, 0x02); /* prim mode */
+               /* enable embedded syncs for auto graphics mode */
+               cp_write_and_or(sd, 0x81, 0xef, 0x10);
 
+               /* Should only be set in auto-graphics mode [REF_02, p. 91-92] */
                /* setup PLL_DIV_MAN_EN and PLL_DIV_RATIO */
                /* IO-map reg. 0x16 and 0x17 should be written in sequence */
                if (adv_smbus_write_i2c_block_data(client, 0x16, 2, pll)) {
                        v4l2_err(sd, "writing to reg 0x16 and 0x17 failed\n");
-                       return;
+                       break;
                }
 
                /* active video - horizontal timing */
-               cp_start_sav = timings->hsync + timings->hbackporch - 4;
-               cp_start_eav = width - timings->hfrontporch;
                cp_write(sd, 0xa2, (cp_start_sav >> 4) & 0xff);
-               cp_write(sd, 0xa3, ((cp_start_sav & 0x0f) << 4) | ((cp_start_eav >> 8) & 0x0f));
+               cp_write(sd, 0xa3, ((cp_start_sav & 0x0f) << 4) |
+                                       ((cp_start_eav >> 8) & 0x0f));
                cp_write(sd, 0xa4, cp_start_eav & 0xff);
 
                /* active video - vertical timing */
-               cp_start_vbi = height - timings->vfrontporch;
-               cp_end_vbi = timings->vsync + timings->vbackporch;
                cp_write(sd, 0xa5, (cp_start_vbi >> 4) & 0xff);
-               cp_write(sd, 0xa6, ((cp_start_vbi & 0xf) << 4) | ((cp_end_vbi >> 8) & 0xf));
+               cp_write(sd, 0xa6, ((cp_start_vbi & 0xf) << 4) |
+                                       ((cp_end_vbi >> 8) & 0xf));
                cp_write(sd, 0xa7, cp_end_vbi & 0xff);
-       } else {
-               /* reset to default values */
-               io_write(sd, 0x16, 0x43);
-               io_write(sd, 0x17, 0x5a);
-               cp_write(sd, 0xa2, 0x00);
-               cp_write(sd, 0xa3, 0x00);
-               cp_write(sd, 0xa4, 0x00);
-               cp_write(sd, 0xa5, 0x00);
-               cp_write(sd, 0xa6, 0x00);
-               cp_write(sd, 0xa7, 0x00);
+               break;
+       case ADV7604_MODE_HDMI:
+               /* set default prim_mode/vid_std for HDMI
+                  accoring to [REF_03, c. 4.2] */
+               io_write(sd, 0x00, 0x02); /* video std */
+               io_write(sd, 0x01, 0x06); /* prim mode */
+               break;
+       default:
+               v4l2_dbg(2, debug, sd, "%s: Unknown mode %d\n",
+                               __func__, state->mode);
+               break;
        }
-}
 
+       cp_write(sd, 0x8f, (ch1_fr_ll >> 8) & 0x7);
+       cp_write(sd, 0x90, ch1_fr_ll & 0xff);
+       cp_write(sd, 0xab, (height >> 4) & 0xff);
+       cp_write(sd, 0xac, (height & 0x0f) << 4);
+}
 
 static void set_rgb_quantization_range(struct v4l2_subdev *sd)
 {
@@ -738,12 +901,7 @@ static void set_rgb_quantization_range(struct v4l2_subdev *sd)
        switch (state->rgb_quantization_range) {
        case V4L2_DV_RGB_RANGE_AUTO:
                /* automatic */
-               if ((hdmi_read(sd, 0x05) & 0x80) ||
-                               (state->prim_mode == ADV7604_PRIM_MODE_COMP) ||
-                               (state->prim_mode == ADV7604_PRIM_MODE_RGB)) {
-                       /* receiving HDMI or analog signal */
-                       io_write_and_or(sd, 0x02, 0x0f, 0xf0);
-               } else {
+               if (DIGITAL_INPUT && !(hdmi_read(sd, 0x05) & 0x80)) {
                        /* receiving DVI-D signal */
 
                        /* ADV7604 selects RGB limited range regardless of
@@ -756,6 +914,9 @@ static void set_rgb_quantization_range(struct v4l2_subdev *sd)
                                /* RGB full range (0-255) */
                                io_write_and_or(sd, 0x02, 0x0f, 0x10);
                        }
+               } else {
+                       /* receiving HDMI or analog signal, set automode */
+                       io_write_and_or(sd, 0x02, 0x0f, 0xf0);
                }
                break;
        case V4L2_DV_RGB_RANGE_LIMITED:
@@ -967,8 +1128,10 @@ static int stdi2dv_timings(struct v4l2_subdev *sd,
                        state->aspect_ratio, timings))
                return 0;
 
-       v4l2_dbg(2, debug, sd, "%s: No format candidate found for lcf=%d, bl = %d\n",
-                       __func__, stdi->lcf, stdi->bl);
+       v4l2_dbg(2, debug, sd,
+               "%s: No format candidate found for lcvs = %d, lcf=%d, bl = %d, %chsync, %cvsync\n",
+               __func__, stdi->lcvs, stdi->lcf, stdi->bl,
+               stdi->hs_pol, stdi->vs_pol);
        return -1;
 }
 
@@ -1123,7 +1286,7 @@ static int adv7604_query_dv_timings(struct v4l2_subdev *sd,
                adv7604_fill_optional_dv_timings_fields(sd, timings);
        } else {
                /* find format
-                * Since LCVS values are inaccurate (REF_03, page 275-276),
+                * Since LCVS values are inaccurate [REF_03, p. 275-276],
                 * stdi2dv_timings() is called with lcvs +-1 if the first attempt fails.
                 */
                if (!stdi2dv_timings(sd, &stdi, timings))
@@ -1135,9 +1298,31 @@ static int adv7604_query_dv_timings(struct v4l2_subdev *sd,
                stdi.lcvs -= 2;
                v4l2_dbg(1, debug, sd, "%s: lcvs - 1 = %d\n", __func__, stdi.lcvs);
                if (stdi2dv_timings(sd, &stdi, timings)) {
+                       /*
+                        * The STDI block may measure wrong values, especially
+                        * for lcvs and lcf. If the driver can not find any
+                        * valid timing, the STDI block is restarted to measure
+                        * the video timings again. The function will return an
+                        * error, but the restart of STDI will generate a new
+                        * STDI interrupt and the format detection process will
+                        * restart.
+                        */
+                       if (state->restart_stdi_once) {
+                               v4l2_dbg(1, debug, sd, "%s: restart STDI\n", __func__);
+                               /* TODO restart STDI for Sync Channel 2 */
+                               /* enter one-shot mode */
+                               cp_write_and_or(sd, 0x86, 0xf9, 0x00);
+                               /* trigger STDI restart */
+                               cp_write_and_or(sd, 0x86, 0xf9, 0x04);
+                               /* reset to continuous mode */
+                               cp_write_and_or(sd, 0x86, 0xf9, 0x02);
+                               state->restart_stdi_once = false;
+                               return -ENOLINK;
+                       }
                        v4l2_dbg(1, debug, sd, "%s: format not supported\n", __func__);
                        return -ERANGE;
                }
+               state->restart_stdi_once = true;
        }
 found:
 
@@ -1166,6 +1351,7 @@ static int adv7604_s_dv_timings(struct v4l2_subdev *sd,
 {
        struct adv7604_state *state = to_state(sd);
        struct v4l2_bt_timings *bt;
+       int err;
 
        if (!timings)
                return -EINVAL;
@@ -1178,12 +1364,20 @@ static int adv7604_s_dv_timings(struct v4l2_subdev *sd,
                                __func__, (u32)bt->pixelclock);
                return -ERANGE;
        }
+
        adv7604_fill_optional_dv_timings_fields(sd, timings);
 
        state->timings = *timings;
 
-       /* freerun */
-       configure_free_run(sd, bt);
+       cp_write(sd, 0x91, bt->interlaced ? 0x50 : 0x10);
+
+       /* Use prim_mode and vid_std when available */
+       err = configure_predefined_video_timings(sd, timings);
+       if (err) {
+               /* custom settings when the video format
+                does not have prim_mode/vid_std */
+               configure_custom_video_timings(sd, bt);
+       }
 
        set_rgb_quantization_range(sd);
 
@@ -1203,24 +1397,25 @@ static int adv7604_g_dv_timings(struct v4l2_subdev *sd,
        return 0;
 }
 
-static void enable_input(struct v4l2_subdev *sd, enum adv7604_prim_mode prim_mode)
+static void enable_input(struct v4l2_subdev *sd)
 {
-       switch (prim_mode) {
-       case ADV7604_PRIM_MODE_COMP:
-       case ADV7604_PRIM_MODE_RGB:
+       struct adv7604_state *state = to_state(sd);
+
+       switch (state->mode) {
+       case ADV7604_MODE_COMP:
+       case ADV7604_MODE_GR:
                /* enable */
                io_write(sd, 0x15, 0xb0);   /* Disable Tristate of Pins (no audio) */
                break;
-       case ADV7604_PRIM_MODE_HDMI_COMP:
-       case ADV7604_PRIM_MODE_HDMI_GR:
+       case ADV7604_MODE_HDMI:
                /* enable */
                hdmi_write(sd, 0x1a, 0x0a); /* Unmute audio */
                hdmi_write(sd, 0x01, 0x00); /* Enable HDMI clock terminators */
                io_write(sd, 0x15, 0xa0);   /* Disable Tristate of Pins */
                break;
        default:
-               v4l2_err(sd, "%s: reserved primary mode 0x%0x\n",
-                               __func__, prim_mode);
+               v4l2_dbg(2, debug, sd, "%s: Unknown mode %d\n",
+                               __func__, state->mode);
                break;
        }
 }
@@ -1233,17 +1428,13 @@ static void disable_input(struct v4l2_subdev *sd)
        hdmi_write(sd, 0x01, 0x78); /* Disable HDMI clock terminators */
 }
 
-static void select_input(struct v4l2_subdev *sd, enum adv7604_prim_mode prim_mode)
+static void select_input(struct v4l2_subdev *sd)
 {
-       switch (prim_mode) {
-       case ADV7604_PRIM_MODE_COMP:
-       case ADV7604_PRIM_MODE_RGB:
-               /* set mode and select free run resolution */
-               io_write(sd, 0x00, 0x07); /* video std */
-               io_write(sd, 0x01, 0x02); /* prim mode */
-               /* enable embedded syncs for auto graphics mode */
-               cp_write_and_or(sd, 0x81, 0xef, 0x10);
+       struct adv7604_state *state = to_state(sd);
 
+       switch (state->mode) {
+       case ADV7604_MODE_COMP:
+       case ADV7604_MODE_GR:
                /* reset ADI recommended settings for HDMI: */
                /* "ADV7604 Register Settings Recommendations (rev. 2.5, June 2010)" p. 4. */
                hdmi_write(sd, 0x0d, 0x04); /* HDMI filter optimization */
@@ -1271,16 +1462,7 @@ static void select_input(struct v4l2_subdev *sd, enum adv7604_prim_mode prim_mod
                cp_write(sd, 0x40, 0x5c); /* CP core pre-gain control. Graphics mode */
                break;
 
-       case ADV7604_PRIM_MODE_HDMI_COMP:
-       case ADV7604_PRIM_MODE_HDMI_GR:
-               /* set mode and select free run resolution */
-               /* video std */
-               io_write(sd, 0x00,
-                       (prim_mode == ADV7604_PRIM_MODE_HDMI_GR) ? 0x02 : 0x1e);
-               io_write(sd, 0x01, prim_mode); /* prim mode */
-               /* disable embedded syncs for auto graphics mode */
-               cp_write_and_or(sd, 0x81, 0xef, 0x00);
-
+       case ADV7604_MODE_HDMI:
                /* set ADI recommended settings for HDMI: */
                /* "ADV7604 Register Settings Recommendations (rev. 2.5, June 2010)" p. 4. */
                hdmi_write(sd, 0x0d, 0x84); /* HDMI filter optimization */
@@ -1309,7 +1491,8 @@ static void select_input(struct v4l2_subdev *sd, enum adv7604_prim_mode prim_mod
 
                break;
        default:
-               v4l2_err(sd, "%s: reserved primary mode 0x%0x\n", __func__, prim_mode);
+               v4l2_dbg(2, debug, sd, "%s: Unknown mode %d\n",
+                               __func__, state->mode);
                break;
        }
 }
@@ -1321,26 +1504,13 @@ static int adv7604_s_routing(struct v4l2_subdev *sd,
 
        v4l2_dbg(2, debug, sd, "%s: input %d", __func__, input);
 
-       switch (input) {
-       case 0:
-               /* TODO select HDMI_COMP or HDMI_GR */
-               state->prim_mode = ADV7604_PRIM_MODE_HDMI_COMP;
-               break;
-       case 1:
-               state->prim_mode = ADV7604_PRIM_MODE_RGB;
-               break;
-       case 2:
-               state->prim_mode = ADV7604_PRIM_MODE_COMP;
-               break;
-       default:
-               return -EINVAL;
-       }
+       state->mode = input;
 
        disable_input(sd);
 
-       select_input(sd, state->prim_mode);
+       select_input(sd);
 
-       enable_input(sd, state->prim_mode);
+       enable_input(sd);
 
        return 0;
 }
@@ -1549,8 +1719,9 @@ static int adv7604_log_status(struct v4l2_subdev *sd)
        v4l2_info(sd, "CP locked: %s\n", no_lock_cp(sd) ? "false" : "true");
        v4l2_info(sd, "CP free run: %s\n",
                        (!!(cp_read(sd, 0xff) & 0x10) ? "on" : "off"));
-       v4l2_info(sd, "Prim-mode = 0x%x, video std = 0x%x\n",
-                       io_read(sd, 0x01) & 0x0f, io_read(sd, 0x00) & 0x3f);
+       v4l2_info(sd, "Prim-mode = 0x%x, video std = 0x%x, v_freq = 0x%x\n",
+                       io_read(sd, 0x01) & 0x0f, io_read(sd, 0x00) & 0x3f,
+                       (io_read(sd, 0x01) & 0x70) >> 4);
 
        v4l2_info(sd, "-----Video Timings-----\n");
        if (read_stdi(sd, &stdi))
@@ -1712,9 +1883,9 @@ static int adv7604_core_init(struct v4l2_subdev *sd)
        cp_write(sd, 0xba, (pdata->hdmi_free_run_mode << 1) | 0x01); /* HDMI free run */
        cp_write(sd, 0xf3, 0xdc); /* Low threshold to enter/exit free run mode */
        cp_write(sd, 0xf9, 0x23); /*  STDI ch. 1 - LCVS change threshold -
-                                     ADI recommended setting [REF_01 c. 2.3.3] */
+                                     ADI recommended setting [REF_01, c. 2.3.3] */
        cp_write(sd, 0x45, 0x23); /*  STDI ch. 2 - LCVS change threshold -
-                                     ADI recommended setting [REF_01 c. 2.3.3] */
+                                     ADI recommended setting [REF_01, c. 2.3.3] */
        cp_write(sd, 0xc9, 0x2d); /* use prim_mode and vid_std as free run resolution
                                     for digital formats */
 
@@ -1724,11 +1895,6 @@ static int adv7604_core_init(struct v4l2_subdev *sd)
        afe_write(sd, 0x02, pdata->ain_sel); /* Select analog input muxing mode */
        io_write_and_or(sd, 0x30, ~(1 << 4), pdata->output_bus_lsb_to_msb << 4);
 
-       state->prim_mode = pdata->prim_mode;
-       select_input(sd, pdata->prim_mode);
-
-       enable_input(sd, pdata->prim_mode);
-
        /* interrupts */
        io_write(sd, 0x40, 0xc2); /* Configure INT1 */
        io_write(sd, 0x41, 0xd7); /* STDI irq for any change, disable INT2 */
@@ -1883,6 +2049,7 @@ static int adv7604_probe(struct i2c_client *client,
                v4l2_err(sd, "failed to create all i2c clients\n");
                goto err_i2c;
        }
+       state->restart_stdi_once = true;
 
        /* work queues */
        state->work_queues = create_singlethread_workqueue(client->name);
index 13057b966ee9abe10b7d4e29331ec80ba52fa20a..333ef178d6fbfe1d5622fd161c01856182b01871 100644 (file)
@@ -263,9 +263,14 @@ static int mt9v022_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a)
                if (ret & 1) /* Autoexposure */
                        ret = reg_write(client, mt9v022->reg->max_total_shutter_width,
                                        rect.height + mt9v022->y_skip_top + 43);
-               else
-                       ret = reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH,
-                                       rect.height + mt9v022->y_skip_top + 43);
+               /*
+                * If autoexposure is off, there is no need to set
+                * MT9V022_TOTAL_SHUTTER_WIDTH here. Autoexposure can be off
+                * only if the user has set exposure manually, using the
+                * V4L2_CID_EXPOSURE_AUTO with the value V4L2_EXPOSURE_MANUAL.
+                * In this case the register MT9V022_TOTAL_SHUTTER_WIDTH
+                * already contains the correct value.
+                */
        }
        /* Setup frame format: defaults apart from width and height */
        if (!ret)
index bfec9e65aefbd78cca43638f7ffe5bdbc339c3ae..19cbb12a12a2c814424a32b8db8ae2b30074d687 100644 (file)
@@ -965,8 +965,10 @@ static struct platform_device_id gsc_driver_ids[] = {
 MODULE_DEVICE_TABLE(platform, gsc_driver_ids);
 
 static const struct of_device_id exynos_gsc_match[] = {
-       { .compatible = "samsung,exynos5250-gsc",
-       .data = &gsc_v_100_drvdata, },
+       {
+               .compatible = "samsung,exynos5-gsc",
+               .data = &gsc_v_100_drvdata,
+       },
        {},
 };
 MODULE_DEVICE_TABLE(of, exynos_gsc_match);
index 3c7f00577bd9fbbe5ed9d78369eb6d965a10d1b4..c065d040ed944630b9d3a4b569fcfc0c5db5f4f4 100644 (file)
@@ -657,8 +657,7 @@ static int gsc_m2m_release(struct file *file)
        pr_debug("pid: %d, state: 0x%lx, refcnt= %d",
                task_pid_nr(current), gsc->state, gsc->m2m.refcnt);
 
-       if (mutex_lock_interruptible(&gsc->lock))
-               return -ERESTARTSYS;
+       mutex_lock(&gsc->lock);
 
        v4l2_m2m_ctx_release(ctx->m2m_ctx);
        gsc_ctrls_delete(ctx);
@@ -732,6 +731,7 @@ int gsc_register_m2m_device(struct gsc_dev *gsc)
        gsc->vdev.ioctl_ops     = &gsc_m2m_ioctl_ops;
        gsc->vdev.release       = video_device_release_empty;
        gsc->vdev.lock          = &gsc->lock;
+       gsc->vdev.vfl_dir       = VFL_DIR_M2M;
        snprintf(gsc->vdev.name, sizeof(gsc->vdev.name), "%s.%d:m2m",
                                        GSC_MODULE_NAME, gsc->id);
 
index 533e9947a925db5a2eec166fbcd25dca0a1392b8..4678f9a6a4fd0e6f6d2c9cb7bb57e69698295956 100644 (file)
 #define GSC_IN_ROT_YFLIP               (2 << 16)
 #define GSC_IN_ROT_XFLIP               (1 << 16)
 #define GSC_IN_RGB_TYPE_MASK           (3 << 14)
-#define GSC_IN_RGB_HD_WIDE             (3 << 14)
-#define GSC_IN_RGB_HD_NARROW           (2 << 14)
-#define GSC_IN_RGB_SD_WIDE             (1 << 14)
-#define GSC_IN_RGB_SD_NARROW           (0 << 14)
+#define GSC_IN_RGB_HD_NARROW           (3 << 14)
+#define GSC_IN_RGB_HD_WIDE             (2 << 14)
+#define GSC_IN_RGB_SD_NARROW           (1 << 14)
+#define GSC_IN_RGB_SD_WIDE             (0 << 14)
 #define GSC_IN_YUV422_1P_ORDER_MASK    (1 << 13)
 #define GSC_IN_YUV422_1P_ORDER_LSB_Y   (0 << 13)
 #define GSC_IN_YUV422_1P_OEDER_LSB_C   (1 << 13)
 #define GSC_OUT_GLOBAL_ALPHA_MASK      (0xff << 24)
 #define GSC_OUT_GLOBAL_ALPHA(x)                ((x) << 24)
 #define GSC_OUT_RGB_TYPE_MASK          (3 << 10)
-#define GSC_OUT_RGB_HD_NARROW          (3 << 10)
-#define GSC_OUT_RGB_HD_WIDE            (2 << 10)
-#define GSC_OUT_RGB_SD_NARROW          (1 << 10)
-#define GSC_OUT_RGB_SD_WIDE            (0 << 10)
+#define GSC_OUT_RGB_HD_WIDE            (3 << 10)
+#define GSC_OUT_RGB_HD_NARROW          (2 << 10)
+#define GSC_OUT_RGB_SD_WIDE            (1 << 10)
+#define GSC_OUT_RGB_SD_NARROW          (0 << 10)
 #define GSC_OUT_YUV422_1P_ORDER_MASK   (1 << 9)
 #define GSC_OUT_YUV422_1P_ORDER_LSB_Y  (0 << 9)
 #define GSC_OUT_YUV422_1P_OEDER_LSB_C  (1 << 9)
index 99640d8c1db0a51d9e2fa2d9a6e64f23f2f1b2ee..7f182f0ff3daaacfd578a2590d4ec06db24f0e2a 100644 (file)
@@ -61,6 +61,7 @@
 #include <linux/i2c.h>
 #include <linux/interrupt.h>
 #include <linux/module.h>
+#include <linux/omap-iommu.h>
 #include <linux/platform_device.h>
 #include <linux/regulator/consumer.h>
 #include <linux/slab.h>
index 8be7487c326f7741b5de7145db939667ead5887f..8d6866942b85a2b1266a0fbfa3a692c6437d6e4b 100644 (file)
 #include <media/v4l2-device.h>
 #include <linux/device.h>
 #include <linux/io.h>
+#include <linux/iommu.h>
 #include <linux/platform_device.h>
 #include <linux/wait.h>
-#include <linux/iommu.h>
-#include <plat/iommu.h>
-#include <plat/iovmm.h>
 
 #include "ispstat.h"
 #include "ispccdc.h"
index 60181ab96063ea12be4f0a10f6b02e5a86e29991..60e60aa64fb461cb05799ec72fbe4f67e0ef62a1 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/device.h>
 #include <linux/dma-mapping.h>
 #include <linux/mm.h>
+#include <linux/omap-iommu.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <media/v4l2-event.h>
@@ -1706,7 +1707,7 @@ static long ccdc_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
 }
 
 static int ccdc_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
-                               const struct v4l2_event_subscription *sub)
+                               struct v4l2_event_subscription *sub)
 {
        if (sub->type != V4L2_EVENT_FRAME_SYNC)
                return -EINVAL;
@@ -1719,7 +1720,7 @@ static int ccdc_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
 }
 
 static int ccdc_unsubscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
-                                 const struct v4l2_event_subscription *sub)
+                                 struct v4l2_event_subscription *sub)
 {
        return v4l2_event_unsubscribe(fh, sub);
 }
index d7ac76b5c2aee4d38916057b1757d2366b27b188..e7939869bda76c1037366223e6691fc456ca6876 100644 (file)
@@ -26,6 +26,7 @@
  */
 
 #include <linux/dma-mapping.h>
+#include <linux/omap-iommu.h>
 #include <linux/slab.h>
 #include <linux/uaccess.h>
 
@@ -1025,7 +1026,7 @@ void omap3isp_stat_dma_isr(struct ispstat *stat)
 
 int omap3isp_stat_subscribe_event(struct v4l2_subdev *subdev,
                                  struct v4l2_fh *fh,
-                                 const struct v4l2_event_subscription *sub)
+                                 struct v4l2_event_subscription *sub)
 {
        struct ispstat *stat = v4l2_get_subdevdata(subdev);
 
@@ -1037,7 +1038,7 @@ int omap3isp_stat_subscribe_event(struct v4l2_subdev *subdev,
 
 int omap3isp_stat_unsubscribe_event(struct v4l2_subdev *subdev,
                                    struct v4l2_fh *fh,
-                                   const struct v4l2_event_subscription *sub)
+                                   struct v4l2_event_subscription *sub)
 {
        return v4l2_event_unsubscribe(fh, sub);
 }
index a6fe653eb237dc171c6aef71f31d62ddc1a30550..9b7c8654dc8a4cadea05dd1ff629ad35b8ebae85 100644 (file)
@@ -147,10 +147,10 @@ int omap3isp_stat_init(struct ispstat *stat, const char *name,
 void omap3isp_stat_cleanup(struct ispstat *stat);
 int omap3isp_stat_subscribe_event(struct v4l2_subdev *subdev,
                                  struct v4l2_fh *fh,
-                                 const struct v4l2_event_subscription *sub);
+                                 struct v4l2_event_subscription *sub);
 int omap3isp_stat_unsubscribe_event(struct v4l2_subdev *subdev,
                                    struct v4l2_fh *fh,
-                                   const struct v4l2_event_subscription *sub);
+                                   struct v4l2_event_subscription *sub);
 int omap3isp_stat_s_stream(struct v4l2_subdev *subdev, int enable);
 
 int omap3isp_stat_busy(struct ispstat *stat);
index a0b737fecf138e61413fca9ca6c36443b5b452f4..6e74346cc357133a3cc212cacc65876a2ec2e3e1 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/clk.h>
 #include <linux/mm.h>
 #include <linux/module.h>
+#include <linux/omap-iommu.h>
 #include <linux/pagemap.h>
 #include <linux/scatterlist.h>
 #include <linux/sched.h>
@@ -34,8 +35,6 @@
 #include <linux/vmalloc.h>
 #include <media/v4l2-dev.h>
 #include <media/v4l2-ioctl.h>
-#include <plat/iommu.h>
-#include <plat/iovmm.h>
 #include <plat/omap-pm.h>
 
 #include "ispvideo.h"
@@ -792,7 +791,7 @@ isp_video_get_crop(struct file *file, void *fh, struct v4l2_crop *crop)
 }
 
 static int
-isp_video_set_crop(struct file *file, void *fh, struct v4l2_crop *crop)
+isp_video_set_crop(struct file *file, void *fh, const struct v4l2_crop *crop)
 {
        struct isp_video *video = video_drvdata(file);
        struct v4l2_subdev *subdev;
index 8f090a8f270e7465b018940a2eb9fd6dba33eeaf..c16b20d86ed283d65723dda5854f5e1fb3675097 100644 (file)
@@ -24,6 +24,7 @@ config VIDEO_S5P_FIMC
 config VIDEO_S5P_MIPI_CSIS
        tristate "S5P/EXYNOS MIPI-CSI2 receiver (MIPI-CSIS) driver"
        depends on REGULATOR
+       select S5P_SETUP_MIPIPHY
        help
          This is a V4L2 driver for Samsung S5P and EXYNOS4 SoC MIPI-CSI2
          receiver (MIPI-CSIS) devices.
index 367efd164d0f1c9580111b12b51c8e2a9f225bfa..891ee873c62b8c281cf83f74cf1b29b1925a0f55 100644 (file)
@@ -556,8 +556,7 @@ static int fimc_capture_close(struct file *file)
 
        dbg("pid: %d, state: 0x%lx", task_pid_nr(current), fimc->state);
 
-       if (mutex_lock_interruptible(&fimc->lock))
-               return -ERESTARTSYS;
+       mutex_lock(&fimc->lock);
 
        if (--fimc->vid_cap.refcnt == 0) {
                clear_bit(ST_CAPT_BUSY, &fimc->state);
@@ -1736,7 +1735,9 @@ static int fimc_register_capture_device(struct fimc_dev *fimc,
        q->mem_ops = &vb2_dma_contig_memops;
        q->buf_struct_size = sizeof(struct fimc_vid_buffer);
 
-       vb2_queue_init(q);
+       ret = vb2_queue_init(q);
+       if (ret)
+               goto err_ent;
 
        vid_cap->vd_pad.flags = MEDIA_PAD_FL_SINK;
        ret = media_entity_init(&vfd->entity, 1, &vid_cap->vd_pad, 0);
@@ -1772,9 +1773,13 @@ static int fimc_capture_subdev_registered(struct v4l2_subdev *sd)
        if (ret)
                return ret;
 
+       fimc->pipeline_ops = v4l2_get_subdev_hostdata(sd);
+
        ret = fimc_register_capture_device(fimc, sd->v4l2_dev);
-       if (ret)
+       if (ret) {
                fimc_unregister_m2m_device(fimc);
+               fimc->pipeline_ops = NULL;
+       }
 
        return ret;
 }
@@ -1791,6 +1796,7 @@ static void fimc_capture_subdev_unregistered(struct v4l2_subdev *sd)
        if (video_is_registered(&fimc->vid_cap.vfd)) {
                video_unregister_device(&fimc->vid_cap.vfd);
                media_entity_cleanup(&fimc->vid_cap.vfd.entity);
+               fimc->pipeline_ops = NULL;
        }
        kfree(fimc->vid_cap.ctx);
        fimc->vid_cap.ctx = NULL;
index 70bcf39de87994f99dc38ae11c1a2c115d56433d..1b309a72f09fbe847c1b4ac2178c1717a68f5a04 100644 (file)
@@ -491,8 +491,7 @@ static int fimc_lite_close(struct file *file)
        struct fimc_lite *fimc = video_drvdata(file);
        int ret;
 
-       if (mutex_lock_interruptible(&fimc->lock))
-               return -ERESTARTSYS;
+       mutex_lock(&fimc->lock);
 
        if (--fimc->ref_count == 0 && fimc->out_path == FIMC_IO_DMA) {
                clear_bit(ST_FLITE_IN_USE, &fimc->state);
@@ -1253,7 +1252,9 @@ static int fimc_lite_subdev_registered(struct v4l2_subdev *sd)
        q->buf_struct_size = sizeof(struct flite_buffer);
        q->drv_priv = fimc;
 
-       vb2_queue_init(q);
+       ret = vb2_queue_init(q);
+       if (ret < 0)
+               return ret;
 
        fimc->vd_pad.flags = MEDIA_PAD_FL_SINK;
        ret = media_entity_init(&vfd->entity, 1, &fimc->vd_pad, 0);
@@ -1261,10 +1262,12 @@ static int fimc_lite_subdev_registered(struct v4l2_subdev *sd)
                return ret;
 
        video_set_drvdata(vfd, fimc);
+       fimc->pipeline_ops = v4l2_get_subdev_hostdata(sd);
 
        ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1);
        if (ret < 0) {
                media_entity_cleanup(&vfd->entity);
+               fimc->pipeline_ops = NULL;
                return ret;
        }
 
@@ -1283,6 +1286,7 @@ static void fimc_lite_subdev_unregistered(struct v4l2_subdev *sd)
        if (video_is_registered(&fimc->vfd)) {
                video_unregister_device(&fimc->vfd);
                media_entity_cleanup(&fimc->vfd.entity);
+               fimc->pipeline_ops = NULL;
        }
 }
 
index 4500e44f6857c909adcbd74cb13ad4dc2ac85cbc..62afed3162eaec518d74cd0a72b5c26a8725987a 100644 (file)
@@ -718,8 +718,7 @@ static int fimc_m2m_release(struct file *file)
        dbg("pid: %d, state: 0x%lx, refcnt= %d",
                task_pid_nr(current), fimc->state, fimc->m2m.refcnt);
 
-       if (mutex_lock_interruptible(&fimc->lock))
-               return -ERESTARTSYS;
+       mutex_lock(&fimc->lock);
 
        v4l2_m2m_ctx_release(ctx->m2m_ctx);
        fimc_ctrls_delete(ctx);
index 80ada5882f62c8156c74265a7279eca9e6fbc35c..0531ab70a94c42e512165d4bd3cfb5f117973d19 100644 (file)
@@ -343,53 +343,50 @@ static int fimc_md_register_sensor_entities(struct fimc_md *fmd)
 static int fimc_register_callback(struct device *dev, void *p)
 {
        struct fimc_dev *fimc = dev_get_drvdata(dev);
-       struct v4l2_subdev *sd = &fimc->vid_cap.subdev;
+       struct v4l2_subdev *sd;
        struct fimc_md *fmd = p;
-       int ret = 0;
-
-       if (!fimc || !fimc->pdev)
-               return 0;
+       int ret;
 
-       if (fimc->pdev->id < 0 || fimc->pdev->id >= FIMC_MAX_DEVS)
+       if (fimc == NULL || fimc->id >= FIMC_MAX_DEVS)
                return 0;
 
-       fimc->pipeline_ops = &fimc_pipeline_ops;
-       fmd->fimc[fimc->pdev->id] = fimc;
+       sd = &fimc->vid_cap.subdev;
        sd->grp_id = FIMC_GROUP_ID;
+       v4l2_set_subdev_hostdata(sd, (void *)&fimc_pipeline_ops);
 
        ret = v4l2_device_register_subdev(&fmd->v4l2_dev, sd);
        if (ret) {
                v4l2_err(&fmd->v4l2_dev, "Failed to register FIMC.%d (%d)\n",
                         fimc->id, ret);
+               return ret;
        }
 
-       return ret;
+       fmd->fimc[fimc->id] = fimc;
+       return 0;
 }
 
 static int fimc_lite_register_callback(struct device *dev, void *p)
 {
        struct fimc_lite *fimc = dev_get_drvdata(dev);
-       struct v4l2_subdev *sd = &fimc->subdev;
        struct fimc_md *fmd = p;
        int ret;
 
-       if (fimc == NULL)
+       if (fimc == NULL || fimc->index >= FIMC_LITE_MAX_DEVS)
                return 0;
 
-       if (fimc->index >= FIMC_LITE_MAX_DEVS)
-               return 0;
-
-       fimc->pipeline_ops = &fimc_pipeline_ops;
-       fmd->fimc_lite[fimc->index] = fimc;
-       sd->grp_id = FLITE_GROUP_ID;
+       fimc->subdev.grp_id = FLITE_GROUP_ID;
+       v4l2_set_subdev_hostdata(&fimc->subdev, (void *)&fimc_pipeline_ops);
 
-       ret = v4l2_device_register_subdev(&fmd->v4l2_dev, sd);
+       ret = v4l2_device_register_subdev(&fmd->v4l2_dev, &fimc->subdev);
        if (ret) {
                v4l2_err(&fmd->v4l2_dev,
                         "Failed to register FIMC-LITE.%d (%d)\n",
                         fimc->index, ret);
+               return ret;
        }
-       return ret;
+
+       fmd->fimc_lite[fimc->index] = fimc;
+       return 0;
 }
 
 static int csis_register_callback(struct device *dev, void *p)
@@ -407,10 +404,12 @@ static int csis_register_callback(struct device *dev, void *p)
        v4l2_info(sd, "csis%d sd: %s\n", pdev->id, sd->name);
 
        id = pdev->id < 0 ? 0 : pdev->id;
-       fmd->csis[id].sd = sd;
        sd->grp_id = CSIS_GROUP_ID;
+
        ret = v4l2_device_register_subdev(&fmd->v4l2_dev, sd);
-       if (ret)
+       if (!ret)
+               fmd->csis[id].sd = sd;
+       else
                v4l2_err(&fmd->v4l2_dev,
                         "Failed to register CSIS subdevice: %d\n", ret);
        return ret;
index 130f4ac8649ec644faf589e734145761f5d7cc91..3afe879d54d7dec195cc99ff49aa316ff42ff53a 100644 (file)
@@ -381,11 +381,8 @@ static void s5p_mfc_handle_frame(struct s5p_mfc_ctx *ctx,
                ctx->consumed_stream += s5p_mfc_hw_call(dev->mfc_ops,
                                                get_consumed_stream, dev);
                if (ctx->codec_mode != S5P_MFC_CODEC_H264_DEC &&
-                       s5p_mfc_hw_call(dev->mfc_ops,
-                               get_dec_frame_type, dev) ==
-                                       S5P_FIMV_DECODE_FRAME_P_FRAME
-                                       && ctx->consumed_stream + STUFF_BYTE <
-                                       src_buf->b->v4l2_planes[0].bytesused) {
+                       ctx->consumed_stream + STUFF_BYTE <
+                       src_buf->b->v4l2_planes[0].bytesused) {
                        /* Run MFC again on the same buffer */
                        mfc_debug(2, "Running again the same buffer\n");
                        ctx->after_packed_pb = 1;
index 50b5bee3c44e970070d4af07c0a6751c333d08e9..3a8cfd9fc1bd045e8fb05bd177b341c01e25595b 100644 (file)
@@ -1762,7 +1762,7 @@ int s5p_mfc_get_dspl_y_adr_v6(struct s5p_mfc_dev *dev)
 
 int s5p_mfc_get_dec_y_adr_v6(struct s5p_mfc_dev *dev)
 {
-       return mfc_read(dev, S5P_FIMV_D_DISPLAY_LUMA_ADDR_V6);
+       return mfc_read(dev, S5P_FIMV_D_DECODED_LUMA_ADDR_V6);
 }
 
 int s5p_mfc_get_dspl_status_v6(struct s5p_mfc_dev *dev)
index 85fd312f0a829fee9f45b1e682694cc3fc475cf3..a1c87f0ceaabe0285ddd2d6b03dd3ead5303d22d 100644 (file)
@@ -935,9 +935,10 @@ static int sh_vou_g_crop(struct file *file, void *fh, struct v4l2_crop *a)
 /* Assume a dull encoder, do all the work ourselves. */
 static int sh_vou_s_crop(struct file *file, void *fh, const struct v4l2_crop *a)
 {
+       struct v4l2_crop a_writable = *a;
        struct video_device *vdev = video_devdata(file);
        struct sh_vou_device *vou_dev = video_get_drvdata(vdev);
-       struct v4l2_rect *rect = &a->c;
+       struct v4l2_rect *rect = &a_writable.c;
        struct v4l2_crop sd_crop = {.type = V4L2_BUF_TYPE_VIDEO_OUTPUT};
        struct v4l2_pix_format *pix = &vou_dev->pix;
        struct sh_vou_geometry geo;
index bbe70991d30b6ac0b2ef598ccafba7519ab138b9..032b8c9097f99a7d35866a242b7897302b260860 100644 (file)
@@ -470,14 +470,6 @@ static void mx1_camera_remove_device(struct soc_camera_device *icd)
        pcdev->icd = NULL;
 }
 
-static int mx1_camera_set_crop(struct soc_camera_device *icd,
-                              struct v4l2_crop *a)
-{
-       struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
-
-       return v4l2_subdev_call(sd, video, s_crop, a);
-}
-
 static int mx1_camera_set_bus_param(struct soc_camera_device *icd)
 {
        struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
@@ -689,7 +681,6 @@ static struct soc_camera_host_ops mx1_soc_camera_host_ops = {
        .add            = mx1_camera_add_device,
        .remove         = mx1_camera_remove_device,
        .set_bus_param  = mx1_camera_set_bus_param,
-       .set_crop       = mx1_camera_set_crop,
        .set_fmt        = mx1_camera_set_fmt,
        .try_fmt        = mx1_camera_try_fmt,
        .init_videobuf  = mx1_camera_init_videobuf,
index 9fd9d1c5b218a5b51ff0522b9969db06e795706c..9a55f4c4c7f4ec9ad9a050ca0d8220e482ee9818 100644 (file)
@@ -864,8 +864,10 @@ static int mx2_start_streaming(struct vb2_queue *q, unsigned int count)
 
                bytesperline = soc_mbus_bytes_per_line(icd->user_width,
                                icd->current_fmt->host_fmt);
-               if (bytesperline < 0)
+               if (bytesperline < 0) {
+                       spin_unlock_irqrestore(&pcdev->lock, flags);
                        return bytesperline;
+               }
 
                /*
                 * I didn't manage to properly enable/disable the prp
@@ -878,8 +880,10 @@ static int mx2_start_streaming(struct vb2_queue *q, unsigned int count)
                pcdev->discard_buffer = dma_alloc_coherent(ici->v4l2_dev.dev,
                                pcdev->discard_size, &pcdev->discard_buffer_dma,
                                GFP_KERNEL);
-               if (!pcdev->discard_buffer)
+               if (!pcdev->discard_buffer) {
+                       spin_unlock_irqrestore(&pcdev->lock, flags);
                        return -ENOMEM;
+               }
 
                pcdev->buf_discard[0].discard = true;
                list_add_tail(&pcdev->buf_discard[0].queue,
@@ -1099,9 +1103,10 @@ static int mx2_camera_set_bus_param(struct soc_camera_device *icd)
 }
 
 static int mx2_camera_set_crop(struct soc_camera_device *icd,
-                               struct v4l2_crop *a)
+                               const struct v4l2_crop *a)
 {
-       struct v4l2_rect *rect = &a->c;
+       struct v4l2_crop a_writable = *a;
+       struct v4l2_rect *rect = &a_writable.c;
        struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
        struct v4l2_mbus_framefmt mf;
        int ret;
index 3557ac97e4303f4743330850a5144f43cb06cbd0..261f6e9e1b176dcbc543992204162673f06935c4 100644 (file)
@@ -799,9 +799,10 @@ static inline void stride_align(__u32 *width)
  * default g_crop and cropcap from soc_camera.c
  */
 static int mx3_camera_set_crop(struct soc_camera_device *icd,
-                              struct v4l2_crop *a)
+                              const struct v4l2_crop *a)
 {
-       struct v4l2_rect *rect = &a->c;
+       struct v4l2_crop a_writable = *a;
+       struct v4l2_rect *rect = &a_writable.c;
        struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
        struct mx3_camera_dev *mx3_cam = ici->priv;
        struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
index fa08c7695ccb05aa61d680d8bcf4f002516d2894..13636a58510606635a69cda964f57054a2e607b7 100644 (file)
@@ -1215,9 +1215,9 @@ static int set_mbus_format(struct omap1_cam_dev *pcdev, struct device *dev,
 }
 
 static int omap1_cam_set_crop(struct soc_camera_device *icd,
-                              struct v4l2_crop *crop)
+                              const struct v4l2_crop *crop)
 {
-       struct v4l2_rect *rect = &crop->c;
+       const struct v4l2_rect *rect = &crop->c;
        const struct soc_camera_format_xlate *xlate = icd->current_fmt;
        struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
        struct device *dev = icd->parent;
index 1e3776d08dacb6f6159a417ecbe5d6bf9c935f3f..3434ffe79c6ecc445a8b451dc2c55767b552c217 100644 (file)
@@ -1337,9 +1337,9 @@ static int pxa_camera_check_frame(u32 width, u32 height)
 }
 
 static int pxa_camera_set_crop(struct soc_camera_device *icd,
-                              struct v4l2_crop *a)
+                              const struct v4l2_crop *a)
 {
-       struct v4l2_rect *rect = &a->c;
+       const struct v4l2_rect *rect = &a->c;
        struct device *dev = icd->parent;
        struct soc_camera_host *ici = to_soc_camera_host(dev);
        struct pxa_camera_dev *pcdev = ici->priv;
index 0a24253dcda2a9afd42d4a2bfb017a5c016171ac..2d8861c0e8f2c23baae9908a0fdf2955e458ead3 100644 (file)
@@ -1182,13 +1182,13 @@ static void sh_mobile_ceu_put_formats(struct soc_camera_device *icd)
 }
 
 /* Check if any dimension of r1 is smaller than respective one of r2 */
-static bool is_smaller(struct v4l2_rect *r1, struct v4l2_rect *r2)
+static bool is_smaller(const struct v4l2_rect *r1, const struct v4l2_rect *r2)
 {
        return r1->width < r2->width || r1->height < r2->height;
 }
 
 /* Check if r1 fails to cover r2 */
-static bool is_inside(struct v4l2_rect *r1, struct v4l2_rect *r2)
+static bool is_inside(const struct v4l2_rect *r1, const struct v4l2_rect *r2)
 {
        return r1->left > r2->left || r1->top > r2->top ||
                r1->left + r1->width < r2->left + r2->width ||
@@ -1263,7 +1263,7 @@ static void update_subrect(struct sh_mobile_ceu_cam *cam)
  * 3. if (2) failed, try to request the maximum image
  */
 static int client_s_crop(struct soc_camera_device *icd, struct v4l2_crop *crop,
-                        const struct v4l2_crop *cam_crop)
+                        struct v4l2_crop *cam_crop)
 {
        struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
        struct v4l2_rect *rect = &crop->c, *cam_rect = &cam_crop->c;
@@ -1519,7 +1519,8 @@ static int client_scale(struct soc_camera_device *icd,
 static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd,
                                  const struct v4l2_crop *a)
 {
-       struct v4l2_rect *rect = &a->c;
+       struct v4l2_crop a_writable = *a;
+       const struct v4l2_rect *rect = &a_writable.c;
        struct device *dev = icd->parent;
        struct soc_camera_host *ici = to_soc_camera_host(dev);
        struct sh_mobile_ceu_dev *pcdev = ici->priv;
@@ -1545,7 +1546,7 @@ static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd,
         * 1. - 2. Apply iterative camera S_CROP for new input window, read back
         * actual camera rectangle.
         */
-       ret = client_s_crop(icd, a, &cam_crop);
+       ret = client_s_crop(icd, &a_writable, &cam_crop);
        if (ret < 0)
                return ret;
 
@@ -1946,7 +1947,7 @@ static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd,
 }
 
 static int sh_mobile_ceu_set_livecrop(struct soc_camera_device *icd,
-                                     struct v4l2_crop *a)
+                                     const struct v4l2_crop *a)
 {
        struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
        struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
index 9859d2a2449b974bf162a32f78eeb8a543f9bf5f..ba51f65204de833cb9965f5f0764f85c8ce9166e 100644 (file)
@@ -283,14 +283,13 @@ static inline int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed,
 
        /* activate the pid on the device pid filter */
        if (adap->props->caps & DVB_USB_ADAP_HAS_PID_FILTER &&
-                       adap->pid_filtering &&
-                       adap->props->pid_filter)
+                       adap->pid_filtering && adap->props->pid_filter) {
                ret = adap->props->pid_filter(adap, dvbdmxfeed->index,
                                dvbdmxfeed->pid, (count == 1) ? 1 : 0);
-                       if (ret < 0)
-                               dev_err(&d->udev->dev, "%s: pid_filter() " \
-                                               "failed=%d\n", KBUILD_MODNAME,
-                                               ret);
+               if (ret < 0)
+                       dev_err(&d->udev->dev, "%s: pid_filter() failed=%d\n",
+                                       KBUILD_MODNAME, ret);
+       }
 
        /* start feeding if it is first pid */
        if (adap->feed_count == 1 && count == 1) {
index 0431beed0ef44dcfcfc7043d85fe514f602f1d10..5716662b483451f4d3a5fb6204091a6285f349e2 100644 (file)
@@ -32,9 +32,7 @@ int dvb_usbv2_generic_rw(struct dvb_usb_device *d, u8 *wbuf, u16 wlen, u8 *rbuf,
                return -EINVAL;
        }
 
-       ret = mutex_lock_interruptible(&d->usb_mutex);
-       if (ret < 0)
-               return ret;
+       mutex_lock(&d->usb_mutex);
 
        dev_dbg(&d->udev->dev, "%s: >>> %*ph\n", __func__, wlen, wbuf);
 
index adabba8d28bc80fa69b76348f40b83f63a680390..093f1acce403e7fa35ddea58914dd386ee32f426 100644 (file)
@@ -1346,6 +1346,10 @@ static const struct usb_device_id rtl28xxu_id_table[] = {
                &rtl2832u_props, "DigitalNow Quad DVB-T Receiver", NULL) },
        { DVB_USB_DEVICE(USB_VID_TERRATEC, 0x00d3,
                &rtl2832u_props, "TerraTec Cinergy T Stick RC (Rev. 3)", NULL) },
+       { DVB_USB_DEVICE(USB_VID_DEXATEK, 0x1102,
+               &rtl2832u_props, "Dexatek DK mini DVB-T Dongle", NULL) },
+       { DVB_USB_DEVICE(USB_VID_TERRATEC, 0x00d7,
+               &rtl2832u_props, "TerraTec Cinergy T Stick+", NULL) },
        { }
 };
 MODULE_DEVICE_TABLE(usb, rtl28xxu_id_table);
index 1b48f2094806c75fa8914657978f1b7bf814ae93..f4f9bf84bc7b6348bc804b6368f5522cc29e2ddf 100644 (file)
@@ -96,11 +96,11 @@ static irqreturn_t arizona_underclocked(int irq, void *data)
                return IRQ_NONE;
        }
 
-       if (val & ARIZONA_AIF3_UNDERCLOCKED_STS)
-               dev_err(arizona->dev, "AIF3 underclocked\n");
        if (val & ARIZONA_AIF3_UNDERCLOCKED_STS)
                dev_err(arizona->dev, "AIF3 underclocked\n");
        if (val & ARIZONA_AIF2_UNDERCLOCKED_STS)
+               dev_err(arizona->dev, "AIF2 underclocked\n");
+       if (val & ARIZONA_AIF1_UNDERCLOCKED_STS)
                dev_err(arizona->dev, "AIF1 underclocked\n");
        if (val & ARIZONA_ISRC2_UNDERCLOCKED_STS)
                dev_err(arizona->dev, "ISRC2 underclocked\n");
@@ -415,11 +415,19 @@ int __devinit arizona_dev_init(struct arizona *arizona)
 
        /* If we have a /RESET GPIO we'll already be reset */
        if (!arizona->pdata.reset) {
+               regcache_mark_dirty(arizona->regmap);
+
                ret = regmap_write(arizona->regmap, ARIZONA_SOFTWARE_RESET, 0);
                if (ret != 0) {
                        dev_err(dev, "Failed to reset device: %d\n", ret);
                        goto err_reset;
                }
+
+               ret = regcache_sync(arizona->regmap);
+               if (ret != 0) {
+                       dev_err(dev, "Failed to sync device: %d\n", ret);
+                       goto err_reset;
+               }
        }
 
        ret = arizona_wait_for_boot(arizona);
@@ -520,7 +528,7 @@ int __devinit arizona_dev_init(struct arizona *arizona)
                break;
        case WM5110:
                ret = mfd_add_devices(arizona->dev, -1, wm5110_devs,
-                                     ARRAY_SIZE(wm5102_devs), NULL, 0, NULL);
+                                     ARRAY_SIZE(wm5110_devs), NULL, 0, NULL);
                break;
        }
 
index ef0f2d001df20524695906c42993b368d9fa8a81..b1b0091774055213c6b0a573f4075b8ebb7af5d9 100644 (file)
@@ -178,6 +178,7 @@ int arizona_irq_init(struct arizona *arizona)
 
                switch (arizona->rev) {
                case 0:
+               case 1:
                        ctrlif_error = false;
                        break;
                default:
index 4ae6423202058c0e1e7d7c9c262b8c25fd38d917..a071a8643a4776e9cccd70bb3c4ea7bc786203ab 100644 (file)
@@ -671,7 +671,7 @@ add_children(struct twl4030_platform_data *pdata, unsigned irq_base,
        }
 
        if (IS_ENABLED(CONFIG_PWM_TWL6030) && twl_class_is_6030()) {
-               child = add_child(TWL6030_MODULE_ID1, "twl6030-pwm", NULL, 0,
+               child = add_child(SUB_CHIP_ID1, "twl6030-pwm", NULL, 0,
                                  false, 0, 0);
                if (IS_ERR(child))
                        return PTR_ERR(child);
index ad733d76207ac11320f69603ea1a3235f81b9495..cdd1173ed4e9641b0290bffbac7a860563f6c581 100644 (file)
@@ -672,7 +672,8 @@ int twl4030_sih_setup(struct device *dev, int module, int irq_base)
        irq = sih_mod + twl4030_irq_base;
        irq_set_handler_data(irq, agent);
        agent->irq_name = kasprintf(GFP_KERNEL, "twl4030_%s", sih->name);
-       status = request_threaded_irq(irq, NULL, handle_twl4030_sih, 0,
+       status = request_threaded_irq(irq, NULL, handle_twl4030_sih,
+                                     IRQF_EARLY_RESUME,
                                      agent->irq_name ?: sih->name, NULL);
 
        dev_info(dev, "%s (irq %d) chaining IRQs %d..%d\n", sih->name,
index 01b9255ed6310cf9f984d4177fc59b9e21b6348e..14490cc785d29879f37a06ee52ffed57b8c32c9e 100644 (file)
@@ -43,6 +43,7 @@ static const struct reg_default wm5102_reva_patch[] = {
        { 0x479, 0x0A30 },
        { 0x47B, 0x0810 },
        { 0x47D, 0x0510 },
+       { 0x4D1, 0x017F },
        { 0x500, 0x000D },
        { 0x507, 0x1820 },
        { 0x508, 0x1820 },
@@ -52,524 +53,6 @@ static const struct reg_default wm5102_reva_patch[] = {
        { 0x580, 0x000D },
        { 0x587, 0x1820 },
        { 0x588, 0x1820 },
-       { 0x101, 0x8140 },
-       { 0x3000, 0x2225 },
-       { 0x3001, 0x3a03 },
-       { 0x3002, 0x0225 },
-       { 0x3003, 0x0801 },
-       { 0x3004, 0x6249 },
-       { 0x3005, 0x0c04 },
-       { 0x3006, 0x0225 },
-       { 0x3007, 0x5901 },
-       { 0x3008, 0xe249 },
-       { 0x3009, 0x030d },
-       { 0x300a, 0x0249 },
-       { 0x300b, 0x2c01 },
-       { 0x300c, 0xe249 },
-       { 0x300d, 0x4342 },
-       { 0x300e, 0xe249 },
-       { 0x300f, 0x73c0 },
-       { 0x3010, 0x4249 },
-       { 0x3011, 0x0c00 },
-       { 0x3012, 0x0225 },
-       { 0x3013, 0x1f01 },
-       { 0x3014, 0x0225 },
-       { 0x3015, 0x1e01 },
-       { 0x3016, 0x0225 },
-       { 0x3017, 0xfa00 },
-       { 0x3018, 0x0000 },
-       { 0x3019, 0xf000 },
-       { 0x301a, 0x0000 },
-       { 0x301b, 0xf000 },
-       { 0x301c, 0x0000 },
-       { 0x301d, 0xf000 },
-       { 0x301e, 0x0000 },
-       { 0x301f, 0xf000 },
-       { 0x3020, 0x0000 },
-       { 0x3021, 0xf000 },
-       { 0x3022, 0x0000 },
-       { 0x3023, 0xf000 },
-       { 0x3024, 0x0000 },
-       { 0x3025, 0xf000 },
-       { 0x3026, 0x0000 },
-       { 0x3027, 0xf000 },
-       { 0x3028, 0x0000 },
-       { 0x3029, 0xf000 },
-       { 0x302a, 0x0000 },
-       { 0x302b, 0xf000 },
-       { 0x302c, 0x0000 },
-       { 0x302d, 0xf000 },
-       { 0x302e, 0x0000 },
-       { 0x302f, 0xf000 },
-       { 0x3030, 0x0225 },
-       { 0x3031, 0x1a01 },
-       { 0x3032, 0x0225 },
-       { 0x3033, 0x1e00 },
-       { 0x3034, 0x0225 },
-       { 0x3035, 0x1f00 },
-       { 0x3036, 0x6225 },
-       { 0x3037, 0xf800 },
-       { 0x3038, 0x0000 },
-       { 0x3039, 0xf000 },
-       { 0x303a, 0x0000 },
-       { 0x303b, 0xf000 },
-       { 0x303c, 0x0000 },
-       { 0x303d, 0xf000 },
-       { 0x303e, 0x0000 },
-       { 0x303f, 0xf000 },
-       { 0x3040, 0x2226 },
-       { 0x3041, 0x3a03 },
-       { 0x3042, 0x0226 },
-       { 0x3043, 0x0801 },
-       { 0x3044, 0x6249 },
-       { 0x3045, 0x0c06 },
-       { 0x3046, 0x0226 },
-       { 0x3047, 0x5901 },
-       { 0x3048, 0xe249 },
-       { 0x3049, 0x030d },
-       { 0x304a, 0x0249 },
-       { 0x304b, 0x2c01 },
-       { 0x304c, 0xe249 },
-       { 0x304d, 0x4342 },
-       { 0x304e, 0xe249 },
-       { 0x304f, 0x73c0 },
-       { 0x3050, 0x4249 },
-       { 0x3051, 0x0c00 },
-       { 0x3052, 0x0226 },
-       { 0x3053, 0x1f01 },
-       { 0x3054, 0x0226 },
-       { 0x3055, 0x1e01 },
-       { 0x3056, 0x0226 },
-       { 0x3057, 0xfa00 },
-       { 0x3058, 0x0000 },
-       { 0x3059, 0xf000 },
-       { 0x305a, 0x0000 },
-       { 0x305b, 0xf000 },
-       { 0x305c, 0x0000 },
-       { 0x305d, 0xf000 },
-       { 0x305e, 0x0000 },
-       { 0x305f, 0xf000 },
-       { 0x3060, 0x0000 },
-       { 0x3061, 0xf000 },
-       { 0x3062, 0x0000 },
-       { 0x3063, 0xf000 },
-       { 0x3064, 0x0000 },
-       { 0x3065, 0xf000 },
-       { 0x3066, 0x0000 },
-       { 0x3067, 0xf000 },
-       { 0x3068, 0x0000 },
-       { 0x3069, 0xf000 },
-       { 0x306a, 0x0000 },
-       { 0x306b, 0xf000 },
-       { 0x306c, 0x0000 },
-       { 0x306d, 0xf000 },
-       { 0x306e, 0x0000 },
-       { 0x306f, 0xf000 },
-       { 0x3070, 0x0226 },
-       { 0x3071, 0x1a01 },
-       { 0x3072, 0x0226 },
-       { 0x3073, 0x1e00 },
-       { 0x3074, 0x0226 },
-       { 0x3075, 0x1f00 },
-       { 0x3076, 0x6226 },
-       { 0x3077, 0xf800 },
-       { 0x3078, 0x0000 },
-       { 0x3079, 0xf000 },
-       { 0x307a, 0x0000 },
-       { 0x307b, 0xf000 },
-       { 0x307c, 0x0000 },
-       { 0x307d, 0xf000 },
-       { 0x307e, 0x0000 },
-       { 0x307f, 0xf000 },
-       { 0x3080, 0x2227 },
-       { 0x3081, 0x3a03 },
-       { 0x3082, 0x0227 },
-       { 0x3083, 0x0801 },
-       { 0x3084, 0x6255 },
-       { 0x3085, 0x0c04 },
-       { 0x3086, 0x0227 },
-       { 0x3087, 0x5901 },
-       { 0x3088, 0xe255 },
-       { 0x3089, 0x030d },
-       { 0x308a, 0x0255 },
-       { 0x308b, 0x2c01 },
-       { 0x308c, 0xe255 },
-       { 0x308d, 0x4342 },
-       { 0x308e, 0xe255 },
-       { 0x308f, 0x73c0 },
-       { 0x3090, 0x4255 },
-       { 0x3091, 0x0c00 },
-       { 0x3092, 0x0227 },
-       { 0x3093, 0x1f01 },
-       { 0x3094, 0x0227 },
-       { 0x3095, 0x1e01 },
-       { 0x3096, 0x0227 },
-       { 0x3097, 0xfa00 },
-       { 0x3098, 0x0000 },
-       { 0x3099, 0xf000 },
-       { 0x309a, 0x0000 },
-       { 0x309b, 0xf000 },
-       { 0x309c, 0x0000 },
-       { 0x309d, 0xf000 },
-       { 0x309e, 0x0000 },
-       { 0x309f, 0xf000 },
-       { 0x30a0, 0x0000 },
-       { 0x30a1, 0xf000 },
-       { 0x30a2, 0x0000 },
-       { 0x30a3, 0xf000 },
-       { 0x30a4, 0x0000 },
-       { 0x30a5, 0xf000 },
-       { 0x30a6, 0x0000 },
-       { 0x30a7, 0xf000 },
-       { 0x30a8, 0x0000 },
-       { 0x30a9, 0xf000 },
-       { 0x30aa, 0x0000 },
-       { 0x30ab, 0xf000 },
-       { 0x30ac, 0x0000 },
-       { 0x30ad, 0xf000 },
-       { 0x30ae, 0x0000 },
-       { 0x30af, 0xf000 },
-       { 0x30b0, 0x0227 },
-       { 0x30b1, 0x1a01 },
-       { 0x30b2, 0x0227 },
-       { 0x30b3, 0x1e00 },
-       { 0x30b4, 0x0227 },
-       { 0x30b5, 0x1f00 },
-       { 0x30b6, 0x6227 },
-       { 0x30b7, 0xf800 },
-       { 0x30b8, 0x0000 },
-       { 0x30b9, 0xf000 },
-       { 0x30ba, 0x0000 },
-       { 0x30bb, 0xf000 },
-       { 0x30bc, 0x0000 },
-       { 0x30bd, 0xf000 },
-       { 0x30be, 0x0000 },
-       { 0x30bf, 0xf000 },
-       { 0x30c0, 0x2228 },
-       { 0x30c1, 0x3a03 },
-       { 0x30c2, 0x0228 },
-       { 0x30c3, 0x0801 },
-       { 0x30c4, 0x6255 },
-       { 0x30c5, 0x0c06 },
-       { 0x30c6, 0x0228 },
-       { 0x30c7, 0x5901 },
-       { 0x30c8, 0xe255 },
-       { 0x30c9, 0x030d },
-       { 0x30ca, 0x0255 },
-       { 0x30cb, 0x2c01 },
-       { 0x30cc, 0xe255 },
-       { 0x30cd, 0x4342 },
-       { 0x30ce, 0xe255 },
-       { 0x30cf, 0x73c0 },
-       { 0x30d0, 0x4255 },
-       { 0x30d1, 0x0c00 },
-       { 0x30d2, 0x0228 },
-       { 0x30d3, 0x1f01 },
-       { 0x30d4, 0x0228 },
-       { 0x30d5, 0x1e01 },
-       { 0x30d6, 0x0228 },
-       { 0x30d7, 0xfa00 },
-       { 0x30d8, 0x0000 },
-       { 0x30d9, 0xf000 },
-       { 0x30da, 0x0000 },
-       { 0x30db, 0xf000 },
-       { 0x30dc, 0x0000 },
-       { 0x30dd, 0xf000 },
-       { 0x30de, 0x0000 },
-       { 0x30df, 0xf000 },
-       { 0x30e0, 0x0000 },
-       { 0x30e1, 0xf000 },
-       { 0x30e2, 0x0000 },
-       { 0x30e3, 0xf000 },
-       { 0x30e4, 0x0000 },
-       { 0x30e5, 0xf000 },
-       { 0x30e6, 0x0000 },
-       { 0x30e7, 0xf000 },
-       { 0x30e8, 0x0000 },
-       { 0x30e9, 0xf000 },
-       { 0x30ea, 0x0000 },
-       { 0x30eb, 0xf000 },
-       { 0x30ec, 0x0000 },
-       { 0x30ed, 0xf000 },
-       { 0x30ee, 0x0000 },
-       { 0x30ef, 0xf000 },
-       { 0x30f0, 0x0228 },
-       { 0x30f1, 0x1a01 },
-       { 0x30f2, 0x0228 },
-       { 0x30f3, 0x1e00 },
-       { 0x30f4, 0x0228 },
-       { 0x30f5, 0x1f00 },
-       { 0x30f6, 0x6228 },
-       { 0x30f7, 0xf800 },
-       { 0x30f8, 0x0000 },
-       { 0x30f9, 0xf000 },
-       { 0x30fa, 0x0000 },
-       { 0x30fb, 0xf000 },
-       { 0x30fc, 0x0000 },
-       { 0x30fd, 0xf000 },
-       { 0x30fe, 0x0000 },
-       { 0x30ff, 0xf000 },
-       { 0x3100, 0x222b },
-       { 0x3101, 0x3a03 },
-       { 0x3102, 0x222b },
-       { 0x3103, 0x5803 },
-       { 0x3104, 0xe26f },
-       { 0x3105, 0x030d },
-       { 0x3106, 0x626f },
-       { 0x3107, 0x2c01 },
-       { 0x3108, 0xe26f },
-       { 0x3109, 0x4342 },
-       { 0x310a, 0xe26f },
-       { 0x310b, 0x73c0 },
-       { 0x310c, 0x026f },
-       { 0x310d, 0x0c00 },
-       { 0x310e, 0x022b },
-       { 0x310f, 0x1f01 },
-       { 0x3110, 0x022b },
-       { 0x3111, 0x1e01 },
-       { 0x3112, 0x022b },
-       { 0x3113, 0xfa00 },
-       { 0x3114, 0x0000 },
-       { 0x3115, 0xf000 },
-       { 0x3116, 0x0000 },
-       { 0x3117, 0xf000 },
-       { 0x3118, 0x0000 },
-       { 0x3119, 0xf000 },
-       { 0x311a, 0x0000 },
-       { 0x311b, 0xf000 },
-       { 0x311c, 0x0000 },
-       { 0x311d, 0xf000 },
-       { 0x311e, 0x0000 },
-       { 0x311f, 0xf000 },
-       { 0x3120, 0x022b },
-       { 0x3121, 0x0a01 },
-       { 0x3122, 0x022b },
-       { 0x3123, 0x1e00 },
-       { 0x3124, 0x022b },
-       { 0x3125, 0x1f00 },
-       { 0x3126, 0x622b },
-       { 0x3127, 0xf800 },
-       { 0x3128, 0x0000 },
-       { 0x3129, 0xf000 },
-       { 0x312a, 0x0000 },
-       { 0x312b, 0xf000 },
-       { 0x312c, 0x0000 },
-       { 0x312d, 0xf000 },
-       { 0x312e, 0x0000 },
-       { 0x312f, 0xf000 },
-       { 0x3130, 0x0000 },
-       { 0x3131, 0xf000 },
-       { 0x3132, 0x0000 },
-       { 0x3133, 0xf000 },
-       { 0x3134, 0x0000 },
-       { 0x3135, 0xf000 },
-       { 0x3136, 0x0000 },
-       { 0x3137, 0xf000 },
-       { 0x3138, 0x0000 },
-       { 0x3139, 0xf000 },
-       { 0x313a, 0x0000 },
-       { 0x313b, 0xf000 },
-       { 0x313c, 0x0000 },
-       { 0x313d, 0xf000 },
-       { 0x313e, 0x0000 },
-       { 0x313f, 0xf000 },
-       { 0x3140, 0x0000 },
-       { 0x3141, 0xf000 },
-       { 0x3142, 0x0000 },
-       { 0x3143, 0xf000 },
-       { 0x3144, 0x0000 },
-       { 0x3145, 0xf000 },
-       { 0x3146, 0x0000 },
-       { 0x3147, 0xf000 },
-       { 0x3148, 0x0000 },
-       { 0x3149, 0xf000 },
-       { 0x314a, 0x0000 },
-       { 0x314b, 0xf000 },
-       { 0x314c, 0x0000 },
-       { 0x314d, 0xf000 },
-       { 0x314e, 0x0000 },
-       { 0x314f, 0xf000 },
-       { 0x3150, 0x0000 },
-       { 0x3151, 0xf000 },
-       { 0x3152, 0x0000 },
-       { 0x3153, 0xf000 },
-       { 0x3154, 0x0000 },
-       { 0x3155, 0xf000 },
-       { 0x3156, 0x0000 },
-       { 0x3157, 0xf000 },
-       { 0x3158, 0x0000 },
-       { 0x3159, 0xf000 },
-       { 0x315a, 0x0000 },
-       { 0x315b, 0xf000 },
-       { 0x315c, 0x0000 },
-       { 0x315d, 0xf000 },
-       { 0x315e, 0x0000 },
-       { 0x315f, 0xf000 },
-       { 0x3160, 0x0000 },
-       { 0x3161, 0xf000 },
-       { 0x3162, 0x0000 },
-       { 0x3163, 0xf000 },
-       { 0x3164, 0x0000 },
-       { 0x3165, 0xf000 },
-       { 0x3166, 0x0000 },
-       { 0x3167, 0xf000 },
-       { 0x3168, 0x0000 },
-       { 0x3169, 0xf000 },
-       { 0x316a, 0x0000 },
-       { 0x316b, 0xf000 },
-       { 0x316c, 0x0000 },
-       { 0x316d, 0xf000 },
-       { 0x316e, 0x0000 },
-       { 0x316f, 0xf000 },
-       { 0x3170, 0x0000 },
-       { 0x3171, 0xf000 },
-       { 0x3172, 0x0000 },
-       { 0x3173, 0xf000 },
-       { 0x3174, 0x0000 },
-       { 0x3175, 0xf000 },
-       { 0x3176, 0x0000 },
-       { 0x3177, 0xf000 },
-       { 0x3178, 0x0000 },
-       { 0x3179, 0xf000 },
-       { 0x317a, 0x0000 },
-       { 0x317b, 0xf000 },
-       { 0x317c, 0x0000 },
-       { 0x317d, 0xf000 },
-       { 0x317e, 0x0000 },
-       { 0x317f, 0xf000 },
-       { 0x3180, 0x2001 },
-       { 0x3181, 0xf101 },
-       { 0x3182, 0x0000 },
-       { 0x3183, 0xf000 },
-       { 0x3184, 0x0000 },
-       { 0x3185, 0xf000 },
-       { 0x3186, 0x0000 },
-       { 0x3187, 0xf000 },
-       { 0x3188, 0x0000 },
-       { 0x3189, 0xf000 },
-       { 0x318a, 0x0000 },
-       { 0x318b, 0xf000 },
-       { 0x318c, 0x0000 },
-       { 0x318d, 0xf000 },
-       { 0x318e, 0x0000 },
-       { 0x318f, 0xf000 },
-       { 0x3190, 0x0000 },
-       { 0x3191, 0xf000 },
-       { 0x3192, 0x0000 },
-       { 0x3193, 0xf000 },
-       { 0x3194, 0x0000 },
-       { 0x3195, 0xf000 },
-       { 0x3196, 0x0000 },
-       { 0x3197, 0xf000 },
-       { 0x3198, 0x0000 },
-       { 0x3199, 0xf000 },
-       { 0x319a, 0x0000 },
-       { 0x319b, 0xf000 },
-       { 0x319c, 0x0000 },
-       { 0x319d, 0xf000 },
-       { 0x319e, 0x0000 },
-       { 0x319f, 0xf000 },
-       { 0x31a0, 0x0000 },
-       { 0x31a1, 0xf000 },
-       { 0x31a2, 0x0000 },
-       { 0x31a3, 0xf000 },
-       { 0x31a4, 0x0000 },
-       { 0x31a5, 0xf000 },
-       { 0x31a6, 0x0000 },
-       { 0x31a7, 0xf000 },
-       { 0x31a8, 0x0000 },
-       { 0x31a9, 0xf000 },
-       { 0x31aa, 0x0000 },
-       { 0x31ab, 0xf000 },
-       { 0x31ac, 0x0000 },
-       { 0x31ad, 0xf000 },
-       { 0x31ae, 0x0000 },
-       { 0x31af, 0xf000 },
-       { 0x31b0, 0x0000 },
-       { 0x31b1, 0xf000 },
-       { 0x31b2, 0x0000 },
-       { 0x31b3, 0xf000 },
-       { 0x31b4, 0x0000 },
-       { 0x31b5, 0xf000 },
-       { 0x31b6, 0x0000 },
-       { 0x31b7, 0xf000 },
-       { 0x31b8, 0x0000 },
-       { 0x31b9, 0xf000 },
-       { 0x31ba, 0x0000 },
-       { 0x31bb, 0xf000 },
-       { 0x31bc, 0x0000 },
-       { 0x31bd, 0xf000 },
-       { 0x31be, 0x0000 },
-       { 0x31bf, 0xf000 },
-       { 0x31c0, 0x0000 },
-       { 0x31c1, 0xf000 },
-       { 0x31c2, 0x0000 },
-       { 0x31c3, 0xf000 },
-       { 0x31c4, 0x0000 },
-       { 0x31c5, 0xf000 },
-       { 0x31c6, 0x0000 },
-       { 0x31c7, 0xf000 },
-       { 0x31c8, 0x0000 },
-       { 0x31c9, 0xf000 },
-       { 0x31ca, 0x0000 },
-       { 0x31cb, 0xf000 },
-       { 0x31cc, 0x0000 },
-       { 0x31cd, 0xf000 },
-       { 0x31ce, 0x0000 },
-       { 0x31cf, 0xf000 },
-       { 0x31d0, 0x0000 },
-       { 0x31d1, 0xf000 },
-       { 0x31d2, 0x0000 },
-       { 0x31d3, 0xf000 },
-       { 0x31d4, 0x0000 },
-       { 0x31d5, 0xf000 },
-       { 0x31d6, 0x0000 },
-       { 0x31d7, 0xf000 },
-       { 0x31d8, 0x0000 },
-       { 0x31d9, 0xf000 },
-       { 0x31da, 0x0000 },
-       { 0x31db, 0xf000 },
-       { 0x31dc, 0x0000 },
-       { 0x31dd, 0xf000 },
-       { 0x31de, 0x0000 },
-       { 0x31df, 0xf000 },
-       { 0x31e0, 0x0000 },
-       { 0x31e1, 0xf000 },
-       { 0x31e2, 0x0000 },
-       { 0x31e3, 0xf000 },
-       { 0x31e4, 0x0000 },
-       { 0x31e5, 0xf000 },
-       { 0x31e6, 0x0000 },
-       { 0x31e7, 0xf000 },
-       { 0x31e8, 0x0000 },
-       { 0x31e9, 0xf000 },
-       { 0x31ea, 0x0000 },
-       { 0x31eb, 0xf000 },
-       { 0x31ec, 0x0000 },
-       { 0x31ed, 0xf000 },
-       { 0x31ee, 0x0000 },
-       { 0x31ef, 0xf000 },
-       { 0x31f0, 0x0000 },
-       { 0x31f1, 0xf000 },
-       { 0x31f2, 0x0000 },
-       { 0x31f3, 0xf000 },
-       { 0x31f4, 0x0000 },
-       { 0x31f5, 0xf000 },
-       { 0x31f6, 0x0000 },
-       { 0x31f7, 0xf000 },
-       { 0x31f8, 0x0000 },
-       { 0x31f9, 0xf000 },
-       { 0x31fa, 0x0000 },
-       { 0x31fb, 0xf000 },
-       { 0x31fc, 0x0000 },
-       { 0x31fd, 0xf000 },
-       { 0x31fe, 0x0000 },
-       { 0x31ff, 0xf000 },
-       { 0x024d, 0xff50 },
-       { 0x0252, 0xff50 },
-       { 0x0259, 0x0112 },
-       { 0x025e, 0x0112 },
-       { 0x101, 0x0304 },
        { 0x80, 0x0000 },
 };
 
index a54dd5d7a5f94b1b3e550e799ee95999c5e54df8..c9ec725884e5cbe6b841a2008241fc8b20db2d8d 100644 (file)
@@ -373,18 +373,25 @@ static struct sdhci_ops sdhci_s3c_ops = {
 static void sdhci_s3c_notify_change(struct platform_device *dev, int state)
 {
        struct sdhci_host *host = platform_get_drvdata(dev);
+       struct sdhci_s3c *sc = sdhci_priv(host);
        unsigned long flags;
 
        if (host) {
                spin_lock_irqsave(&host->lock, flags);
                if (state) {
                        dev_dbg(&dev->dev, "card inserted.\n");
+#ifdef CONFIG_PM_RUNTIME
+                       clk_prepare_enable(sc->clk_io);
+#endif
                        host->flags &= ~SDHCI_DEVICE_DEAD;
                        host->quirks |= SDHCI_QUIRK_BROKEN_CARD_DETECTION;
                } else {
                        dev_dbg(&dev->dev, "card removed.\n");
                        host->flags |= SDHCI_DEVICE_DEAD;
                        host->quirks &= ~SDHCI_QUIRK_BROKEN_CARD_DETECTION;
+#ifdef CONFIG_PM_RUNTIME
+                       clk_disable_unprepare(sc->clk_io);
+#endif
                }
                tasklet_schedule(&host->card_tasklet);
                spin_unlock_irqrestore(&host->lock, flags);
index d25bc97dc5c60063bb609b22973e41790ced9762..7eaee3eeb6b2bffed13af54651e6ad5e19d0b409 100644 (file)
@@ -1104,7 +1104,6 @@ static irqreturn_t sh_mmcif_irqt(int irq, void *dev_id)
 {
        struct sh_mmcif_host *host = dev_id;
        struct mmc_request *mrq = host->mrq;
-       struct mmc_data *data = mrq->data;
 
        cancel_delayed_work_sync(&host->timeout_work);
 
@@ -1152,13 +1151,14 @@ static irqreturn_t sh_mmcif_irqt(int irq, void *dev_id)
        case MMCIF_WAIT_FOR_READ_END:
        case MMCIF_WAIT_FOR_WRITE_END:
                if (host->sd_error)
-                       data->error = sh_mmcif_error_manage(host);
+                       mrq->data->error = sh_mmcif_error_manage(host);
                break;
        default:
                BUG();
        }
 
        if (host->wait_for != MMCIF_WAIT_FOR_STOP) {
+               struct mmc_data *data = mrq->data;
                if (!mrq->cmd->error && data && !data->error)
                        data->bytes_xfered =
                                data->blocks * data->blksz;
@@ -1231,10 +1231,6 @@ static irqreturn_t sh_mmcif_intr(int irq, void *dev_id)
                host->sd_error = true;
                dev_dbg(&host->pd->dev, "int err state = %08x\n", state);
        }
-       if (host->state == STATE_IDLE) {
-               dev_info(&host->pd->dev, "Spurious IRQ status 0x%x", state);
-               return IRQ_HANDLED;
-       }
        if (state & ~(INT_CMD12RBE | INT_CMD12CRE)) {
                if (!host->dma_active)
                        return IRQ_WAKE_THREAD;
index 8f52fc858e48bec08f900963996c0d37bd4601cb..5a5cd2ace4a6b05126e642e06d04950f52108ab8 100644 (file)
@@ -240,7 +240,7 @@ static int parse_cmdline(char *devname, char *szstart, char *szlength)
 
        if (*(szlength) != '+') {
                devlength = simple_strtoul(szlength, &buffer, 0);
-               devlength = handle_unit(devlength, buffer) - devstart;
+               devlength = handle_unit(devlength, buffer);
                if (devlength < devstart)
                        goto err_out;
 
index 374c46dff7dd65d3aea7eef69b22a332d727ad0f..ec794a72975dd886205f2460e2eaba08089a8daf 100644 (file)
@@ -1077,7 +1077,8 @@ EXPORT_SYMBOL_GPL(mtd_writev);
  * until the request succeeds or until the allocation size falls below
  * the system page size. This attempts to make sure it does not adversely
  * impact system performance, so when allocating more than one page, we
- * ask the memory allocator to avoid re-trying.
+ * ask the memory allocator to avoid re-trying, swapping, writing back
+ * or performing I/O.
  *
  * Note, this function also makes sure that the allocated buffer is aligned to
  * the MTD device's min. I/O unit, i.e. the "mtd->writesize" value.
@@ -1091,7 +1092,8 @@ EXPORT_SYMBOL_GPL(mtd_writev);
  */
 void *mtd_kmalloc_up_to(const struct mtd_info *mtd, size_t *size)
 {
-       gfp_t flags = __GFP_NOWARN | __GFP_WAIT | __GFP_NORETRY;
+       gfp_t flags = __GFP_NOWARN | __GFP_WAIT |
+                      __GFP_NORETRY | __GFP_NO_KSWAPD;
        size_t min_alloc = max_t(size_t, mtd->writesize, PAGE_SIZE);
        void *kbuf;
 
index ec6841d8e956f74f5224363392632900a39e1f8e..1a03b7f673ce0d59c8613144fd51d1ffb299e4fd 100644 (file)
@@ -2983,13 +2983,15 @@ static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip,
        /*
         * Field definitions are in the following datasheets:
         * Old style (4,5 byte ID): Samsung K9GAG08U0M (p.32)
-        * New style   (6 byte ID): Samsung K9GAG08U0F (p.44)
+        * New Samsung (6 byte ID): Samsung K9GAG08U0F (p.44)
         * Hynix MLC   (6 byte ID): Hynix H27UBG8T2B (p.22)
         *
-        * Check for ID length, cell type, and Hynix/Samsung ID to decide what
-        * to do.
+        * Check for ID length, non-zero 6th byte, cell type, and Hynix/Samsung
+        * ID to decide what to do.
         */
-       if (id_len == 6 && id_data[0] == NAND_MFR_SAMSUNG) {
+       if (id_len == 6 && id_data[0] == NAND_MFR_SAMSUNG &&
+                       (chip->cellinfo & NAND_CI_CELLTYPE_MSK) &&
+                       id_data[5] != 0x00) {
                /* Calc pagesize */
                mtd->writesize = 2048 << (extid & 0x03);
                extid >>= 2;
index 64be8f0848b075cdccb647309ff88d12b3fa547d..d9127e2ed808eab6ddfe5835c68cfa88ef490cf0 100644 (file)
@@ -121,7 +121,7 @@ static int parse_ofoldpart_partitions(struct mtd_info *master,
        nr_parts = plen / sizeof(part[0]);
 
        *pparts = kzalloc(nr_parts * sizeof(*(*pparts)), GFP_KERNEL);
-       if (!pparts)
+       if (!*pparts)
                return -ENOMEM;
 
        names = of_get_property(dp, "partition-names", &plen);
index 7153e0d27101e3eed06ac17addcdbd4734c7ccc3..b3f41f200622b39f5ef7d46ab6b772ed2eb9e97e 100644 (file)
@@ -3694,7 +3694,7 @@ static int flexonenand_check_blocks_erased(struct mtd_info *mtd, int start, int
  * flexonenand_set_boundary    - Writes the SLC boundary
  * @param mtd                  - mtd info structure
  */
-int flexonenand_set_boundary(struct mtd_info *mtd, int die,
+static int flexonenand_set_boundary(struct mtd_info *mtd, int die,
                                    int boundary, int lock)
 {
        struct onenand_chip *this = mtd->priv;
index da7b44998b402866643ef824055d6ed3916bcf4f..2144f611196e3188bd3983ea5e084dd4bafd47ff 100644 (file)
@@ -498,7 +498,7 @@ out:
  * @ubi: UBI device description object
  *
  * This function returns a physical eraseblock in case of success and a
- * negative error code in case of failure. Might sleep.
+ * negative error code in case of failure.
  */
 static int __wl_get_peb(struct ubi_device *ubi)
 {
@@ -540,13 +540,6 @@ retry:
         * ubi_wl_get_peb() after removing e from the pool. */
        prot_queue_add(ubi, e);
 #endif
-       err = ubi_self_check_all_ff(ubi, e->pnum, ubi->vid_hdr_aloffset,
-                                   ubi->peb_size - ubi->vid_hdr_aloffset);
-       if (err) {
-               ubi_err("new PEB %d does not contain all 0xFF bytes", e->pnum);
-               return err;
-       }
-
        return e->pnum;
 }
 
@@ -679,17 +672,30 @@ static struct ubi_wl_entry *get_peb_for_wl(struct ubi_device *ubi)
 #else
 static struct ubi_wl_entry *get_peb_for_wl(struct ubi_device *ubi)
 {
-       return find_wl_entry(ubi, &ubi->free, WL_FREE_MAX_DIFF);
+       struct ubi_wl_entry *e;
+
+       e = find_wl_entry(ubi, &ubi->free, WL_FREE_MAX_DIFF);
+       self_check_in_wl_tree(ubi, e, &ubi->free);
+       rb_erase(&e->u.rb, &ubi->free);
+
+       return e;
 }
 
 int ubi_wl_get_peb(struct ubi_device *ubi)
 {
-       int peb;
+       int peb, err;
 
        spin_lock(&ubi->wl_lock);
        peb = __wl_get_peb(ubi);
        spin_unlock(&ubi->wl_lock);
 
+       err = ubi_self_check_all_ff(ubi, peb, ubi->vid_hdr_aloffset,
+                                   ubi->peb_size - ubi->vid_hdr_aloffset);
+       if (err) {
+               ubi_err("new PEB %d does not contain all 0xFF bytes", peb);
+               return err;
+       }
+
        return peb;
 }
 #endif
index b2530b00212558411f917abbe077ec75cb985f5e..a7d47350ea4b5657d4ee9683b92d7243ea2a9361 100644 (file)
@@ -1379,6 +1379,8 @@ static void bond_compute_features(struct bonding *bond)
        struct net_device *bond_dev = bond->dev;
        netdev_features_t vlan_features = BOND_VLAN_FEATURES;
        unsigned short max_hard_header_len = ETH_HLEN;
+       unsigned int gso_max_size = GSO_MAX_SIZE;
+       u16 gso_max_segs = GSO_MAX_SEGS;
        int i;
        unsigned int flags, dst_release_flag = IFF_XMIT_DST_RELEASE;
 
@@ -1394,11 +1396,16 @@ static void bond_compute_features(struct bonding *bond)
                dst_release_flag &= slave->dev->priv_flags;
                if (slave->dev->hard_header_len > max_hard_header_len)
                        max_hard_header_len = slave->dev->hard_header_len;
+
+               gso_max_size = min(gso_max_size, slave->dev->gso_max_size);
+               gso_max_segs = min(gso_max_segs, slave->dev->gso_max_segs);
        }
 
 done:
        bond_dev->vlan_features = vlan_features;
        bond_dev->hard_header_len = max_hard_header_len;
+       bond_dev->gso_max_segs = gso_max_segs;
+       netif_set_gso_max_size(bond_dev, gso_max_size);
 
        flags = bond_dev->priv_flags & ~IFF_XMIT_DST_RELEASE;
        bond_dev->priv_flags = flags | dst_release_flag;
@@ -3452,6 +3459,28 @@ static int bond_xmit_hash_policy_l34(struct sk_buff *skb, int count)
 
 /*-------------------------- Device entry points ----------------------------*/
 
+static void bond_work_init_all(struct bonding *bond)
+{
+       INIT_DELAYED_WORK(&bond->mcast_work,
+                         bond_resend_igmp_join_requests_delayed);
+       INIT_DELAYED_WORK(&bond->alb_work, bond_alb_monitor);
+       INIT_DELAYED_WORK(&bond->mii_work, bond_mii_monitor);
+       if (bond->params.mode == BOND_MODE_ACTIVEBACKUP)
+               INIT_DELAYED_WORK(&bond->arp_work, bond_activebackup_arp_mon);
+       else
+               INIT_DELAYED_WORK(&bond->arp_work, bond_loadbalance_arp_mon);
+       INIT_DELAYED_WORK(&bond->ad_work, bond_3ad_state_machine_handler);
+}
+
+static void bond_work_cancel_all(struct bonding *bond)
+{
+       cancel_delayed_work_sync(&bond->mii_work);
+       cancel_delayed_work_sync(&bond->arp_work);
+       cancel_delayed_work_sync(&bond->alb_work);
+       cancel_delayed_work_sync(&bond->ad_work);
+       cancel_delayed_work_sync(&bond->mcast_work);
+}
+
 static int bond_open(struct net_device *bond_dev)
 {
        struct bonding *bond = netdev_priv(bond_dev);
@@ -3474,41 +3503,27 @@ static int bond_open(struct net_device *bond_dev)
        }
        read_unlock(&bond->lock);
 
-       INIT_DELAYED_WORK(&bond->mcast_work, bond_resend_igmp_join_requests_delayed);
+       bond_work_init_all(bond);
 
        if (bond_is_lb(bond)) {
                /* bond_alb_initialize must be called before the timer
                 * is started.
                 */
-               if (bond_alb_initialize(bond, (bond->params.mode == BOND_MODE_ALB))) {
-                       /* something went wrong - fail the open operation */
+               if (bond_alb_initialize(bond, (bond->params.mode == BOND_MODE_ALB)))
                        return -ENOMEM;
-               }
-
-               INIT_DELAYED_WORK(&bond->alb_work, bond_alb_monitor);
                queue_delayed_work(bond->wq, &bond->alb_work, 0);
        }
 
-       if (bond->params.miimon) {  /* link check interval, in milliseconds. */
-               INIT_DELAYED_WORK(&bond->mii_work, bond_mii_monitor);
+       if (bond->params.miimon)  /* link check interval, in milliseconds. */
                queue_delayed_work(bond->wq, &bond->mii_work, 0);
-       }
 
        if (bond->params.arp_interval) {  /* arp interval, in milliseconds. */
-               if (bond->params.mode == BOND_MODE_ACTIVEBACKUP)
-                       INIT_DELAYED_WORK(&bond->arp_work,
-                                         bond_activebackup_arp_mon);
-               else
-                       INIT_DELAYED_WORK(&bond->arp_work,
-                                         bond_loadbalance_arp_mon);
-
                queue_delayed_work(bond->wq, &bond->arp_work, 0);
                if (bond->params.arp_validate)
                        bond->recv_probe = bond_arp_rcv;
        }
 
        if (bond->params.mode == BOND_MODE_8023AD) {
-               INIT_DELAYED_WORK(&bond->ad_work, bond_3ad_state_machine_handler);
                queue_delayed_work(bond->wq, &bond->ad_work, 0);
                /* register to receive LACPDUs */
                bond->recv_probe = bond_3ad_lacpdu_recv;
@@ -3523,34 +3538,10 @@ static int bond_close(struct net_device *bond_dev)
        struct bonding *bond = netdev_priv(bond_dev);
 
        write_lock_bh(&bond->lock);
-
        bond->send_peer_notif = 0;
-
        write_unlock_bh(&bond->lock);
 
-       if (bond->params.miimon) {  /* link check interval, in milliseconds. */
-               cancel_delayed_work_sync(&bond->mii_work);
-       }
-
-       if (bond->params.arp_interval) {  /* arp interval, in milliseconds. */
-               cancel_delayed_work_sync(&bond->arp_work);
-       }
-
-       switch (bond->params.mode) {
-       case BOND_MODE_8023AD:
-               cancel_delayed_work_sync(&bond->ad_work);
-               break;
-       case BOND_MODE_TLB:
-       case BOND_MODE_ALB:
-               cancel_delayed_work_sync(&bond->alb_work);
-               break;
-       default:
-               break;
-       }
-
-       if (delayed_work_pending(&bond->mcast_work))
-               cancel_delayed_work_sync(&bond->mcast_work);
-
+       bond_work_cancel_all(bond);
        if (bond_is_lb(bond)) {
                /* Must be called only after all
                 * slaves have been released
@@ -4429,26 +4420,6 @@ static void bond_setup(struct net_device *bond_dev)
        bond_dev->features |= bond_dev->hw_features;
 }
 
-static void bond_work_cancel_all(struct bonding *bond)
-{
-       if (bond->params.miimon && delayed_work_pending(&bond->mii_work))
-               cancel_delayed_work_sync(&bond->mii_work);
-
-       if (bond->params.arp_interval && delayed_work_pending(&bond->arp_work))
-               cancel_delayed_work_sync(&bond->arp_work);
-
-       if (bond->params.mode == BOND_MODE_ALB &&
-           delayed_work_pending(&bond->alb_work))
-               cancel_delayed_work_sync(&bond->alb_work);
-
-       if (bond->params.mode == BOND_MODE_8023AD &&
-           delayed_work_pending(&bond->ad_work))
-               cancel_delayed_work_sync(&bond->ad_work);
-
-       if (delayed_work_pending(&bond->mcast_work))
-               cancel_delayed_work_sync(&bond->mcast_work);
-}
-
 /*
 * Destroy a bonding device.
 * Must be under rtnl_lock when this function is called.
@@ -4699,12 +4670,13 @@ static int bond_check_params(struct bond_params *params)
             arp_ip_count++) {
                /* not complete check, but should be good enough to
                   catch mistakes */
-               if (!isdigit(arp_ip_target[arp_ip_count][0])) {
+               __be32 ip = in_aton(arp_ip_target[arp_ip_count]);
+               if (!isdigit(arp_ip_target[arp_ip_count][0]) ||
+                   ip == 0 || ip == htonl(INADDR_BROADCAST)) {
                        pr_warning("Warning: bad arp_ip_target module parameter (%s), ARP monitoring will not be performed\n",
                                   arp_ip_target[arp_ip_count]);
                        arp_interval = 0;
                } else {
-                       __be32 ip = in_aton(arp_ip_target[arp_ip_count]);
                        arp_target[arp_ip_count] = ip;
                }
        }
index ef8d2a080d17f4c61b8f28aa7e07bc54ed5c0abc..1877ed7ca0864ed4adfb614de862ed40dde730bd 100644 (file)
@@ -513,6 +513,8 @@ static ssize_t bonding_store_arp_interval(struct device *d,
        int new_value, ret = count;
        struct bonding *bond = to_bond(d);
 
+       if (!rtnl_trylock())
+               return restart_syscall();
        if (sscanf(buf, "%d", &new_value) != 1) {
                pr_err("%s: no arp_interval value specified.\n",
                       bond->dev->name);
@@ -539,10 +541,6 @@ static ssize_t bonding_store_arp_interval(struct device *d,
                pr_info("%s: ARP monitoring cannot be used with MII monitoring. %s Disabling MII monitoring.\n",
                        bond->dev->name, bond->dev->name);
                bond->params.miimon = 0;
-               if (delayed_work_pending(&bond->mii_work)) {
-                       cancel_delayed_work(&bond->mii_work);
-                       flush_workqueue(bond->wq);
-               }
        }
        if (!bond->params.arp_targets[0]) {
                pr_info("%s: ARP monitoring has been set up, but no ARP targets have been specified.\n",
@@ -554,19 +552,12 @@ static ssize_t bonding_store_arp_interval(struct device *d,
                 * timer will get fired off when the open function
                 * is called.
                 */
-               if (!delayed_work_pending(&bond->arp_work)) {
-                       if (bond->params.mode == BOND_MODE_ACTIVEBACKUP)
-                               INIT_DELAYED_WORK(&bond->arp_work,
-                                                 bond_activebackup_arp_mon);
-                       else
-                               INIT_DELAYED_WORK(&bond->arp_work,
-                                                 bond_loadbalance_arp_mon);
-
-                       queue_delayed_work(bond->wq, &bond->arp_work, 0);
-               }
+               cancel_delayed_work_sync(&bond->mii_work);
+               queue_delayed_work(bond->wq, &bond->arp_work, 0);
        }
 
 out:
+       rtnl_unlock();
        return ret;
 }
 static DEVICE_ATTR(arp_interval, S_IRUGO | S_IWUSR,
@@ -962,6 +953,8 @@ static ssize_t bonding_store_miimon(struct device *d,
        int new_value, ret = count;
        struct bonding *bond = to_bond(d);
 
+       if (!rtnl_trylock())
+               return restart_syscall();
        if (sscanf(buf, "%d", &new_value) != 1) {
                pr_err("%s: no miimon value specified.\n",
                       bond->dev->name);
@@ -993,10 +986,6 @@ static ssize_t bonding_store_miimon(struct device *d,
                                bond->params.arp_validate =
                                        BOND_ARP_VALIDATE_NONE;
                        }
-                       if (delayed_work_pending(&bond->arp_work)) {
-                               cancel_delayed_work(&bond->arp_work);
-                               flush_workqueue(bond->wq);
-                       }
                }
 
                if (bond->dev->flags & IFF_UP) {
@@ -1005,15 +994,12 @@ static ssize_t bonding_store_miimon(struct device *d,
                         * timer will get fired off when the open function
                         * is called.
                         */
-                       if (!delayed_work_pending(&bond->mii_work)) {
-                               INIT_DELAYED_WORK(&bond->mii_work,
-                                                 bond_mii_monitor);
-                               queue_delayed_work(bond->wq,
-                                                  &bond->mii_work, 0);
-                       }
+                       cancel_delayed_work_sync(&bond->arp_work);
+                       queue_delayed_work(bond->wq, &bond->mii_work, 0);
                }
        }
 out:
+       rtnl_unlock();
        return ret;
 }
 static DEVICE_ATTR(miimon, S_IRUGO | S_IWUSR,
@@ -1582,6 +1568,7 @@ static ssize_t bonding_store_slaves_active(struct device *d,
                goto out;
        }
 
+       read_lock(&bond->lock);
        bond_for_each_slave(bond, slave, i) {
                if (!bond_is_active_slave(slave)) {
                        if (new_value)
@@ -1590,6 +1577,7 @@ static ssize_t bonding_store_slaves_active(struct device *d,
                                slave->inactive = 1;
                }
        }
+       read_unlock(&bond->lock);
 out:
        return ret;
 }
index 86f26a1ede4c18a233a85310b0bfb5f9a92da856..25723d8ee20130b19ad95b885a99e5c1ba019517 100644 (file)
@@ -519,8 +519,10 @@ static int pcan_usb_decode_error(struct pcan_usb_msg_context *mc, u8 n,
        mc->pdev->dev.can.state = new_state;
 
        if (status_len & PCAN_USB_STATUSLEN_TIMESTAMP) {
+               struct skb_shared_hwtstamps *hwts = skb_hwtstamps(skb);
+
                peak_usb_get_ts_tv(&mc->pdev->time_ref, mc->ts16, &tv);
-               skb->tstamp = timeval_to_ktime(tv);
+               hwts->hwtstamp = timeval_to_ktime(tv);
        }
 
        netif_rx(skb);
@@ -605,6 +607,7 @@ static int pcan_usb_decode_data(struct pcan_usb_msg_context *mc, u8 status_len)
        struct sk_buff *skb;
        struct can_frame *cf;
        struct timeval tv;
+       struct skb_shared_hwtstamps *hwts;
 
        skb = alloc_can_skb(mc->netdev, &cf);
        if (!skb)
@@ -652,7 +655,8 @@ static int pcan_usb_decode_data(struct pcan_usb_msg_context *mc, u8 status_len)
 
        /* convert timestamp into kernel time */
        peak_usb_get_ts_tv(&mc->pdev->time_ref, mc->ts16, &tv);
-       skb->tstamp = timeval_to_ktime(tv);
+       hwts = skb_hwtstamps(skb);
+       hwts->hwtstamp = timeval_to_ktime(tv);
 
        /* push the skb */
        netif_rx(skb);
index e1626d92511adc88d084345f7fdbf098a4aafb09..30d79bfa5b109e5d6d212df46658a4cf1216d6e1 100644 (file)
@@ -532,6 +532,7 @@ static int pcan_usb_pro_handle_canmsg(struct pcan_usb_pro_interface *usb_if,
        struct can_frame *can_frame;
        struct sk_buff *skb;
        struct timeval tv;
+       struct skb_shared_hwtstamps *hwts;
 
        skb = alloc_can_skb(netdev, &can_frame);
        if (!skb)
@@ -549,7 +550,8 @@ static int pcan_usb_pro_handle_canmsg(struct pcan_usb_pro_interface *usb_if,
                memcpy(can_frame->data, rx->data, can_frame->can_dlc);
 
        peak_usb_get_ts_tv(&usb_if->time_ref, le32_to_cpu(rx->ts32), &tv);
-       skb->tstamp = timeval_to_ktime(tv);
+       hwts = skb_hwtstamps(skb);
+       hwts->hwtstamp = timeval_to_ktime(tv);
 
        netif_rx(skb);
        netdev->stats.rx_packets++;
@@ -570,6 +572,7 @@ static int pcan_usb_pro_handle_error(struct pcan_usb_pro_interface *usb_if,
        u8 err_mask = 0;
        struct sk_buff *skb;
        struct timeval tv;
+       struct skb_shared_hwtstamps *hwts;
 
        /* nothing should be sent while in BUS_OFF state */
        if (dev->can.state == CAN_STATE_BUS_OFF)
@@ -664,7 +667,8 @@ static int pcan_usb_pro_handle_error(struct pcan_usb_pro_interface *usb_if,
        dev->can.state = new_state;
 
        peak_usb_get_ts_tv(&usb_if->time_ref, le32_to_cpu(er->ts32), &tv);
-       skb->tstamp = timeval_to_ktime(tv);
+       hwts = skb_hwtstamps(skb);
+       hwts->hwtstamp = timeval_to_ktime(tv);
        netif_rx(skb);
        netdev->stats.rx_packets++;
        netdev->stats.rx_bytes += can_frame->can_dlc;
index d04911d33b647080278f81678869c032e1a3c853..47618e505355ae91fc0ade4e50231ec780bcc56f 100644 (file)
@@ -813,6 +813,7 @@ static int __init ne_drv_probe(struct platform_device *pdev)
                dev->irq = irq[this_dev];
                dev->mem_end = bad[this_dev];
        }
+       SET_NETDEV_DEV(dev, &pdev->dev);
        err = do_ne_probe(dev);
        if (err) {
                free_netdev(dev);
index bd1fd3d87c24d3979f01a0e9864af9866c62b9aa..01611b33a93de82c8b735b2e1c3e115a9b8e807f 100644 (file)
@@ -9545,10 +9545,13 @@ static int __devinit bnx2x_prev_unload_common(struct bnx2x *bp)
  */
 static void __devinit bnx2x_prev_interrupted_dmae(struct bnx2x *bp)
 {
-       u32 val = REG_RD(bp, PGLUE_B_REG_PGLUE_B_INT_STS);
-       if (val & PGLUE_B_PGLUE_B_INT_STS_REG_WAS_ERROR_ATTN) {
-               BNX2X_ERR("was error bit was found to be set in pglueb upon startup. Clearing");
-               REG_WR(bp, PGLUE_B_REG_WAS_ERROR_PF_7_0_CLR, 1 << BP_FUNC(bp));
+       if (!CHIP_IS_E1x(bp)) {
+               u32 val = REG_RD(bp, PGLUE_B_REG_PGLUE_B_INT_STS);
+               if (val & PGLUE_B_PGLUE_B_INT_STS_REG_WAS_ERROR_ATTN) {
+                       BNX2X_ERR("was error bit was found to be set in pglueb upon startup. Clearing");
+                       REG_WR(bp, PGLUE_B_REG_WAS_ERROR_PF_7_0_CLR,
+                              1 << BP_FUNC(bp));
+               }
        }
 }
 
index 5d36795877cb48ef90cd8ea5fac1c11ca05e30d0..b799ab12a2918bb7f0c5b8bdc0d5db70ecaf4392 100644 (file)
@@ -237,7 +237,7 @@ static int mlx4_en_dcbnl_ieee_setmaxrate(struct net_device *dev,
        if (err)
                return err;
 
-       memcpy(priv->maxrate, tmp, sizeof(*priv->maxrate));
+       memcpy(priv->maxrate, tmp, sizeof(priv->maxrate));
 
        return 0;
 }
index 1c818254b7bec650da02fc352625570a3937b6f8..609125a249d9484835f77fd445e6a8ba32e299db 100644 (file)
@@ -979,17 +979,6 @@ static void cp_init_hw (struct cp_private *cp)
        cpw32_f (MAC0 + 0, le32_to_cpu (*(__le32 *) (dev->dev_addr + 0)));
        cpw32_f (MAC0 + 4, le32_to_cpu (*(__le32 *) (dev->dev_addr + 4)));
 
-       cpw32_f(HiTxRingAddr, 0);
-       cpw32_f(HiTxRingAddr + 4, 0);
-
-       ring_dma = cp->ring_dma;
-       cpw32_f(RxRingAddr, ring_dma & 0xffffffff);
-       cpw32_f(RxRingAddr + 4, (ring_dma >> 16) >> 16);
-
-       ring_dma += sizeof(struct cp_desc) * CP_RX_RING_SIZE;
-       cpw32_f(TxRingAddr, ring_dma & 0xffffffff);
-       cpw32_f(TxRingAddr + 4, (ring_dma >> 16) >> 16);
-
        cp_start_hw(cp);
        cpw8(TxThresh, 0x06); /* XXX convert magic num to a constant */
 
@@ -1003,6 +992,17 @@ static void cp_init_hw (struct cp_private *cp)
 
        cpw8(Config5, cpr8(Config5) & PMEStatus);
 
+       cpw32_f(HiTxRingAddr, 0);
+       cpw32_f(HiTxRingAddr + 4, 0);
+
+       ring_dma = cp->ring_dma;
+       cpw32_f(RxRingAddr, ring_dma & 0xffffffff);
+       cpw32_f(RxRingAddr + 4, (ring_dma >> 16) >> 16);
+
+       ring_dma += sizeof(struct cp_desc) * CP_RX_RING_SIZE;
+       cpw32_f(TxRingAddr, ring_dma & 0xffffffff);
+       cpw32_f(TxRingAddr + 4, (ring_dma >> 16) >> 16);
+
        cpw16(MultiIntr, 0);
 
        cpw8_f(Cfg9346, Cfg9346_Lock);
@@ -1060,17 +1060,22 @@ static int cp_init_rings (struct cp_private *cp)
 
 static int cp_alloc_rings (struct cp_private *cp)
 {
+       struct device *d = &cp->pdev->dev;
        void *mem;
+       int rc;
 
-       mem = dma_alloc_coherent(&cp->pdev->dev, CP_RING_BYTES,
-                                &cp->ring_dma, GFP_KERNEL);
+       mem = dma_alloc_coherent(d, CP_RING_BYTES, &cp->ring_dma, GFP_KERNEL);
        if (!mem)
                return -ENOMEM;
 
        cp->rx_ring = mem;
        cp->tx_ring = &cp->rx_ring[CP_RX_RING_SIZE];
 
-       return cp_init_rings(cp);
+       rc = cp_init_rings(cp);
+       if (rc < 0)
+               dma_free_coherent(d, CP_RING_BYTES, cp->rx_ring, cp->ring_dma);
+
+       return rc;
 }
 
 static void cp_clean_rings (struct cp_private *cp)
index fb9f6b38511f97beddbff380c2ae7d31878e4ff4..edf5edb13140fb5908f0197298d17cf3b1cb7503 100644 (file)
@@ -2479,7 +2479,7 @@ static int sis900_resume(struct pci_dev *pci_dev)
        netif_start_queue(net_dev);
 
        /* Workaround for EDB */
-       sis900_set_mode(ioaddr, HW_SPEED_10_MBPS, FDX_CAPABLE_HALF_SELECTED);
+       sis900_set_mode(sis_priv, HW_SPEED_10_MBPS, FDX_CAPABLE_HALF_SELECTED);
 
        /* Enable all known interrupts by setting the interrupt mask. */
        sw32(imr, RxSOVR | RxORN | RxERR | RxOK | TxURN | TxERR | TxIDLE);
index 77e6db9dcfedb2514da5e9a939f60313ceabbfb7..a788501e978e116908cf0e7a0c92745c275b2009 100644 (file)
@@ -894,6 +894,8 @@ out:
        return IRQ_HANDLED;
 }
 
+static void axienet_dma_err_handler(unsigned long data);
+
 /**
  * axienet_open - Driver open routine.
  * @ndev:      Pointer to net_device structure
index 98934bdf6acffc053fcd317721e8d92cf649ba14..477d6729b17f7f391c34a520bc08f8031bfbd4ae 100644 (file)
@@ -1102,10 +1102,12 @@ static int init_queues(struct port *port)
 {
        int i;
 
-       if (!ports_open)
-               if (!(dma_pool = dma_pool_create(DRV_NAME, NULL,
-                                                POOL_ALLOC_SIZE, 32, 0)))
+       if (!ports_open) {
+               dma_pool = dma_pool_create(DRV_NAME, &port->netdev->dev,
+                                          POOL_ALLOC_SIZE, 32, 0);
+               if (!dma_pool)
                        return -ENOMEM;
+       }
 
        if (!(port->desc_tab = dma_pool_alloc(dma_pool, GFP_KERNEL,
                                              &port->desc_tab_phys)))
index 5039f08f5a5b23cacd0f145cd790a30fce47806e..43e9ab4f4d7edc0b6771c1664d2064c164e37ec3 100644 (file)
@@ -222,7 +222,7 @@ static void sirdev_config_fsm(struct work_struct *work)
                        break;
 
                case SIRDEV_STATE_DONGLE_SPEED:
-                       if (dev->dongle_drv->reset) {
+                       if (dev->dongle_drv->set_speed) {
                                ret = dev->dongle_drv->set_speed(dev, fsm->param);
                                if (ret < 0) {
                                        fsm->result = ret;
index 899274f2f9b1dd1da0aac0442807b6e42b0cddc2..2ed1140df3e9fc0afbc25bce03e5a6eba7ceb228 100644 (file)
@@ -185,17 +185,20 @@ static int __devinit mdio_gpio_probe(struct platform_device *pdev)
 {
        struct mdio_gpio_platform_data *pdata;
        struct mii_bus *new_bus;
-       int ret;
+       int ret, bus_id;
 
-       if (pdev->dev.of_node)
+       if (pdev->dev.of_node) {
                pdata = mdio_gpio_of_get_data(pdev);
-       else
+               bus_id = of_alias_get_id(pdev->dev.of_node, "mdio-gpio");
+       } else {
                pdata = pdev->dev.platform_data;
+               bus_id = pdev->id;
+       }
 
        if (!pdata)
                return -ENODEV;
 
-       new_bus = mdio_gpio_bus_init(&pdev->dev, pdata, pdev->id);
+       new_bus = mdio_gpio_bus_init(&pdev->dev, pdata, bus_id);
        if (!new_bus)
                return -ENODEV;
 
index d44cca327588858e26023a99cee8c64a940cf173..ad86660fb8f92b092f06c9b41d03e416991f4636 100644 (file)
@@ -1794,10 +1794,12 @@ static void team_setup(struct net_device *dev)
 
        dev->features |= NETIF_F_LLTX;
        dev->features |= NETIF_F_GRO;
-       dev->hw_features = NETIF_F_HW_VLAN_TX |
+       dev->hw_features = TEAM_VLAN_FEATURES |
+                          NETIF_F_HW_VLAN_TX |
                           NETIF_F_HW_VLAN_RX |
                           NETIF_F_HW_VLAN_FILTER;
 
+       dev->hw_features &= ~(NETIF_F_ALL_CSUM & ~NETIF_F_HW_CSUM);
        dev->features |= dev->hw_features;
 }
 
index 9db0171e93669f483eeae19791ed4e090c333bb0..c5db428e73fa2200f3ef8a5ea5124ceeebb6ef78 100644 (file)
@@ -29,8 +29,8 @@ static bool bc_transmit(struct team *team, struct sk_buff *skb)
                        if (last) {
                                skb2 = skb_clone(skb, GFP_ATOMIC);
                                if (skb2) {
-                                       ret = team_dev_queue_xmit(team, last,
-                                                                 skb2);
+                                       ret = !team_dev_queue_xmit(team, last,
+                                                                  skb2);
                                        if (!sum_ret)
                                                sum_ret = ret;
                                }
@@ -39,7 +39,7 @@ static bool bc_transmit(struct team *team, struct sk_buff *skb)
                }
        }
        if (last) {
-               ret = team_dev_queue_xmit(team, last, skb);
+               ret = !team_dev_queue_xmit(team, last, skb);
                if (!sum_ret)
                        sum_ret = ret;
        }
index 3b566fa0f8e6277ee62f281211a0507dfdf7c227..1ea91f4237f053e731093fe3fc85e5897f97f5d7 100644 (file)
@@ -385,6 +385,7 @@ static const struct usb_device_id products[] = {
        },
 
        /* 3. Combined interface devices matching on interface number */
+       {QMI_FIXED_INTF(0x12d1, 0x140c, 1)},    /* Huawei E173 */
        {QMI_FIXED_INTF(0x19d2, 0x0002, 1)},
        {QMI_FIXED_INTF(0x19d2, 0x0012, 1)},
        {QMI_FIXED_INTF(0x19d2, 0x0017, 3)},
index 3f575afd8cfcb03f283df0932f6fb33bb1495cca..760776b3d66c0033cae82c73c18fcad8fd7b57d5 100644 (file)
@@ -969,10 +969,12 @@ static int init_hdlc_queues(struct port *port)
 {
        int i;
 
-       if (!ports_open)
-               if (!(dma_pool = dma_pool_create(DRV_NAME, NULL,
-                                                POOL_ALLOC_SIZE, 32, 0)))
+       if (!ports_open) {
+               dma_pool = dma_pool_create(DRV_NAME, &port->netdev->dev,
+                                          POOL_ALLOC_SIZE, 32, 0);
+               if (!dma_pool)
                        return -ENOMEM;
+       }
 
        if (!(port->desc_tab = dma_pool_alloc(dma_pool, GFP_KERNEL,
                                              &port->desc_tab_phys)))
@@ -1363,7 +1365,7 @@ static int __devinit hss_init_one(struct platform_device *pdev)
 
        platform_set_drvdata(pdev, port);
 
-       netdev_info(dev, "HSS-%i\n", port->id);
+       netdev_info(dev, "initialized\n");
        return 0;
 
 err_free_netdev:
index 8e1559aba495a0bd7447ac2c79703d49caf70abd..1829b445d0b01852ea11111692174c766b3c7e55 100644 (file)
@@ -1456,7 +1456,7 @@ static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type)
        switch (type) {
        case ATH9K_RESET_POWER_ON:
                ret = ath9k_hw_set_reset_power_on(ah);
-               if (!ret)
+               if (ret)
                        ah->reset_power_on = true;
                break;
        case ATH9K_RESET_WARM:
index fa4d1b8cd9f6fb62ab56e4bdc9f1811efde7d30d..2d9eee93c743aa0f7bfe6d98330ccacead4fe201 100644 (file)
@@ -1354,6 +1354,20 @@ static int iwlagn_mac_add_interface(struct ieee80211_hw *hw,
        vif_priv->ctx = ctx;
        ctx->vif = vif;
 
+       /*
+        * In SNIFFER device type, the firmware reports the FCS to
+        * the host, rather than snipping it off. Unfortunately,
+        * mac80211 doesn't (yet) provide a per-packet flag for
+        * this, so that we have to set the hardware flag based
+        * on the interfaces added. As the monitor interface can
+        * only be present by itself, and will be removed before
+        * other interfaces are added, this is safe.
+        */
+       if (vif->type == NL80211_IFTYPE_MONITOR)
+               priv->hw->flags |= IEEE80211_HW_RX_INCLUDES_FCS;
+       else
+               priv->hw->flags &= ~IEEE80211_HW_RX_INCLUDES_FCS;
+
        err = iwl_setup_interface(priv, ctx);
        if (!err || reset)
                goto out;
index 10896393e5a05be9b44de522f388eb91603b81a8..2830ea29050286f1a8d44d43a14ca820810daca9 100644 (file)
@@ -1012,12 +1012,12 @@ static void iwl_calc_basic_rates(struct iwl_priv *priv,
         * As a consequence, it's not as complicated as it sounds, just add
         * any lower rates to the ACK rate bitmap.
         */
-       if (IWL_RATE_11M_INDEX < lowest_present_ofdm)
-               ofdm |= IWL_RATE_11M_MASK >> IWL_FIRST_CCK_RATE;
-       if (IWL_RATE_5M_INDEX < lowest_present_ofdm)
-               ofdm |= IWL_RATE_5M_MASK >> IWL_FIRST_CCK_RATE;
-       if (IWL_RATE_2M_INDEX < lowest_present_ofdm)
-               ofdm |= IWL_RATE_2M_MASK >> IWL_FIRST_CCK_RATE;
+       if (IWL_RATE_11M_INDEX < lowest_present_cck)
+               cck |= IWL_RATE_11M_MASK >> IWL_FIRST_CCK_RATE;
+       if (IWL_RATE_5M_INDEX < lowest_present_cck)
+               cck |= IWL_RATE_5M_MASK >> IWL_FIRST_CCK_RATE;
+       if (IWL_RATE_2M_INDEX < lowest_present_cck)
+               cck |= IWL_RATE_2M_MASK >> IWL_FIRST_CCK_RATE;
        /* 1M already there or needed so always add */
        cck |= IWL_RATE_1M_MASK >> IWL_FIRST_CCK_RATE;
 
index 105e3af3c621b0b9e335fbe42d1ea1e444bfa579..79a4ddc002d3dac1ce4aa9182bd2a2a0cf76630b 100644 (file)
@@ -480,20 +480,12 @@ void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo,
 void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id)
 {
        struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
-       u16 rd_ptr, wr_ptr;
-       int n_bd = trans_pcie->txq[txq_id].q.n_bd;
 
        if (!test_and_clear_bit(txq_id, trans_pcie->queue_used)) {
                WARN_ONCE(1, "queue %d not used", txq_id);
                return;
        }
 
-       rd_ptr = iwl_read_prph(trans, SCD_QUEUE_RDPTR(txq_id)) & (n_bd - 1);
-       wr_ptr = iwl_read_prph(trans, SCD_QUEUE_WRPTR(txq_id));
-
-       WARN_ONCE(rd_ptr != wr_ptr, "queue %d isn't empty: [%d,%d]",
-                 txq_id, rd_ptr, wr_ptr);
-
        iwl_txq_set_inactive(trans, txq_id);
        IWL_DEBUG_TX_QUEUES(trans, "Deactivate queue %d\n", txq_id);
 }
index 8d465107f52b2c5073acad20d8d0acbe0485be5e..ae9010ed58debd4a8dc5001e03cbe866b2c9a8a2 100644 (file)
@@ -890,9 +890,6 @@ mwifiex_cmd_timeout_func(unsigned long function_context)
                return;
        }
        cmd_node = adapter->curr_cmd;
-       if (cmd_node->wait_q_enabled)
-               adapter->cmd_wait_q.status = -ETIMEDOUT;
-
        if (cmd_node) {
                adapter->dbg.timeout_cmd_id =
                        adapter->dbg.last_cmd_id[adapter->dbg.last_cmd_index];
@@ -938,6 +935,14 @@ mwifiex_cmd_timeout_func(unsigned long function_context)
 
                dev_err(adapter->dev, "ps_mode=%d ps_state=%d\n",
                        adapter->ps_mode, adapter->ps_state);
+
+               if (cmd_node->wait_q_enabled) {
+                       adapter->cmd_wait_q.status = -ETIMEDOUT;
+                       wake_up_interruptible(&adapter->cmd_wait_q.wait);
+                       mwifiex_cancel_pending_ioctl(adapter);
+                       /* reset cmd_sent flag to unblock new commands */
+                       adapter->cmd_sent = false;
+               }
        }
        if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING)
                mwifiex_init_fw_complete(adapter);
index fc8a9bfa1248305fababa37b59ca90110a57afaa..82cf0fa2d9f683a391bb2215f94447d53d09ef40 100644 (file)
@@ -161,7 +161,6 @@ static int mwifiex_sdio_suspend(struct device *dev)
        struct sdio_mmc_card *card;
        struct mwifiex_adapter *adapter;
        mmc_pm_flag_t pm_flag = 0;
-       int hs_actived = 0;
        int i;
        int ret = 0;
 
@@ -188,12 +187,14 @@ static int mwifiex_sdio_suspend(struct device *dev)
        adapter = card->adapter;
 
        /* Enable the Host Sleep */
-       hs_actived = mwifiex_enable_hs(adapter);
-       if (hs_actived) {
-               pr_debug("cmd: suspend with MMC_PM_KEEP_POWER\n");
-               ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
+       if (!mwifiex_enable_hs(adapter)) {
+               dev_err(adapter->dev, "cmd: failed to suspend\n");
+               return -EFAULT;
        }
 
+       dev_dbg(adapter->dev, "cmd: suspend with MMC_PM_KEEP_POWER\n");
+       ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
+
        /* Indicate device suspended */
        adapter->is_suspended = true;
 
index 9970c2b1b19979dc3577472c7c21e27703a38a76..b7e6607e6b6d038bd604657bb4fdcc883b171d7a 100644 (file)
@@ -297,6 +297,7 @@ static struct usb_device_id rtl8192c_usb_ids[] = {
        /*=== Customer ID ===*/
        /****** 8188CU ********/
        {RTL_USB_DEVICE(0x050d, 0x1102, rtl92cu_hal_cfg)}, /*Belkin - Edimax*/
+       {RTL_USB_DEVICE(0x050d, 0x11f2, rtl92cu_hal_cfg)}, /*Belkin - ISY*/
        {RTL_USB_DEVICE(0x06f8, 0xe033, rtl92cu_hal_cfg)}, /*Hercules - Edimax*/
        {RTL_USB_DEVICE(0x07b8, 0x8188, rtl92cu_hal_cfg)}, /*Abocom - Abocom*/
        {RTL_USB_DEVICE(0x07b8, 0x8189, rtl92cu_hal_cfg)}, /*Funai - Abocom*/
index caa011008cd0c9fe11b38507e7f550552bd93170..fc24eb9b3948666b0819156539138958dd6888f1 100644 (file)
@@ -452,29 +452,85 @@ static void xennet_make_frags(struct sk_buff *skb, struct net_device *dev,
        /* Grant backend access to each skb fragment page. */
        for (i = 0; i < frags; i++) {
                skb_frag_t *frag = skb_shinfo(skb)->frags + i;
+               struct page *page = skb_frag_page(frag);
 
-               tx->flags |= XEN_NETTXF_more_data;
+               len = skb_frag_size(frag);
+               offset = frag->page_offset;
 
-               id = get_id_from_freelist(&np->tx_skb_freelist, np->tx_skbs);
-               np->tx_skbs[id].skb = skb_get(skb);
-               tx = RING_GET_REQUEST(&np->tx, prod++);
-               tx->id = id;
-               ref = gnttab_claim_grant_reference(&np->gref_tx_head);
-               BUG_ON((signed short)ref < 0);
+               /* Data must not cross a page boundary. */
+               BUG_ON(len + offset > PAGE_SIZE<<compound_order(page));
 
-               mfn = pfn_to_mfn(page_to_pfn(skb_frag_page(frag)));
-               gnttab_grant_foreign_access_ref(ref, np->xbdev->otherend_id,
-                                               mfn, GNTMAP_readonly);
+               /* Skip unused frames from start of page */
+               page += offset >> PAGE_SHIFT;
+               offset &= ~PAGE_MASK;
 
-               tx->gref = np->grant_tx_ref[id] = ref;
-               tx->offset = frag->page_offset;
-               tx->size = skb_frag_size(frag);
-               tx->flags = 0;
+               while (len > 0) {
+                       unsigned long bytes;
+
+                       BUG_ON(offset >= PAGE_SIZE);
+
+                       bytes = PAGE_SIZE - offset;
+                       if (bytes > len)
+                               bytes = len;
+
+                       tx->flags |= XEN_NETTXF_more_data;
+
+                       id = get_id_from_freelist(&np->tx_skb_freelist,
+                                                 np->tx_skbs);
+                       np->tx_skbs[id].skb = skb_get(skb);
+                       tx = RING_GET_REQUEST(&np->tx, prod++);
+                       tx->id = id;
+                       ref = gnttab_claim_grant_reference(&np->gref_tx_head);
+                       BUG_ON((signed short)ref < 0);
+
+                       mfn = pfn_to_mfn(page_to_pfn(page));
+                       gnttab_grant_foreign_access_ref(ref,
+                                                       np->xbdev->otherend_id,
+                                                       mfn, GNTMAP_readonly);
+
+                       tx->gref = np->grant_tx_ref[id] = ref;
+                       tx->offset = offset;
+                       tx->size = bytes;
+                       tx->flags = 0;
+
+                       offset += bytes;
+                       len -= bytes;
+
+                       /* Next frame */
+                       if (offset == PAGE_SIZE && len) {
+                               BUG_ON(!PageCompound(page));
+                               page++;
+                               offset = 0;
+                       }
+               }
        }
 
        np->tx.req_prod_pvt = prod;
 }
 
+/*
+ * Count how many ring slots are required to send the frags of this
+ * skb. Each frag might be a compound page.
+ */
+static int xennet_count_skb_frag_slots(struct sk_buff *skb)
+{
+       int i, frags = skb_shinfo(skb)->nr_frags;
+       int pages = 0;
+
+       for (i = 0; i < frags; i++) {
+               skb_frag_t *frag = skb_shinfo(skb)->frags + i;
+               unsigned long size = skb_frag_size(frag);
+               unsigned long offset = frag->page_offset;
+
+               /* Skip unused frames from start of page */
+               offset &= ~PAGE_MASK;
+
+               pages += PFN_UP(offset + size);
+       }
+
+       return pages;
+}
+
 static int xennet_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        unsigned short id;
@@ -487,23 +543,23 @@ static int xennet_start_xmit(struct sk_buff *skb, struct net_device *dev)
        grant_ref_t ref;
        unsigned long mfn;
        int notify;
-       int frags = skb_shinfo(skb)->nr_frags;
+       int slots;
        unsigned int offset = offset_in_page(data);
        unsigned int len = skb_headlen(skb);
        unsigned long flags;
 
-       frags += DIV_ROUND_UP(offset + len, PAGE_SIZE);
-       if (unlikely(frags > MAX_SKB_FRAGS + 1)) {
-               printk(KERN_ALERT "xennet: skb rides the rocket: %d frags\n",
-                      frags);
-               dump_stack();
+       slots = DIV_ROUND_UP(offset + len, PAGE_SIZE) +
+               xennet_count_skb_frag_slots(skb);
+       if (unlikely(slots > MAX_SKB_FRAGS + 1)) {
+               net_alert_ratelimited(
+                       "xennet: skb rides the rocket: %d slots\n", slots);
                goto drop;
        }
 
        spin_lock_irqsave(&np->tx_lock, flags);
 
        if (unlikely(!netif_carrier_ok(dev) ||
-                    (frags > 1 && !xennet_can_sg(dev)) ||
+                    (slots > 1 && !xennet_can_sg(dev)) ||
                     netif_needs_gso(skb, netif_skb_features(skb)))) {
                spin_unlock_irqrestore(&np->tx_lock, flags);
                goto drop;
index 97c440a8cd615798a1e61250628e0030ede37694..30ae18a03a9ccc650a195547086866a66646cd98 100644 (file)
@@ -698,13 +698,14 @@ static void pn533_wq_cmd(struct work_struct *work)
 
        cmd = list_first_entry(&dev->cmd_queue, struct pn533_cmd, queue);
 
+       list_del(&cmd->queue);
+
        mutex_unlock(&dev->cmd_lock);
 
        __pn533_send_cmd_frame_async(dev, cmd->out_frame, cmd->in_frame,
                                     cmd->in_frame_len, cmd->cmd_complete,
                                     cmd->arg, cmd->flags);
 
-       list_del(&cmd->queue);
        kfree(cmd);
 }
 
@@ -1678,11 +1679,14 @@ static void pn533_deactivate_target(struct nfc_dev *nfc_dev,
 static int pn533_in_dep_link_up_complete(struct pn533 *dev, void *arg,
                                                u8 *params, int params_len)
 {
-       struct pn533_cmd_jump_dep *cmd;
        struct pn533_cmd_jump_dep_response *resp;
        struct nfc_target nfc_target;
        u8 target_gt_len;
        int rc;
+       struct pn533_cmd_jump_dep *cmd = (struct pn533_cmd_jump_dep *)arg;
+       u8 active = cmd->active;
+
+       kfree(arg);
 
        if (params_len == -ENOENT) {
                nfc_dev_dbg(&dev->interface->dev, "");
@@ -1704,7 +1708,6 @@ static int pn533_in_dep_link_up_complete(struct pn533 *dev, void *arg,
        }
 
        resp = (struct pn533_cmd_jump_dep_response *) params;
-       cmd = (struct pn533_cmd_jump_dep *) arg;
        rc = resp->status & PN533_CMD_RET_MASK;
        if (rc != PN533_CMD_RET_SUCCESS) {
                nfc_dev_err(&dev->interface->dev,
@@ -1734,7 +1737,7 @@ static int pn533_in_dep_link_up_complete(struct pn533 *dev, void *arg,
        if (rc == 0)
                rc = nfc_dep_link_is_up(dev->nfc_dev,
                                                dev->nfc_dev->targets[0].idx,
-                                               !cmd->active, NFC_RF_INITIATOR);
+                                               !active, NFC_RF_INITIATOR);
 
        return 0;
 }
@@ -1819,12 +1822,8 @@ static int pn533_dep_link_up(struct nfc_dev *nfc_dev, struct nfc_target *target,
        rc = pn533_send_cmd_frame_async(dev, dev->out_frame, dev->in_frame,
                                dev->in_maxlen, pn533_in_dep_link_up_complete,
                                cmd, GFP_KERNEL);
-       if (rc)
-               goto out;
-
-
-out:
-       kfree(cmd);
+       if (rc < 0)
+               kfree(cmd);
 
        return rc;
 }
@@ -2078,8 +2077,12 @@ error:
 static int pn533_tm_send_complete(struct pn533 *dev, void *arg,
                                  u8 *params, int params_len)
 {
+       struct sk_buff *skb_out = arg;
+
        nfc_dev_dbg(&dev->interface->dev, "%s", __func__);
 
+       dev_kfree_skb(skb_out);
+
        if (params_len < 0) {
                nfc_dev_err(&dev->interface->dev,
                            "Error %d when sending data",
@@ -2117,7 +2120,7 @@ static int pn533_tm_send(struct nfc_dev *nfc_dev, struct sk_buff *skb)
 
        rc = pn533_send_cmd_frame_async(dev, out_frame, dev->in_frame,
                                        dev->in_maxlen, pn533_tm_send_complete,
-                                       NULL, GFP_KERNEL);
+                                       skb, GFP_KERNEL);
        if (rc) {
                nfc_dev_err(&dev->interface->dev,
                            "Error %d when trying to send data", rc);
index d96caefd914a90d2db11f05278f565a7e7cc79ee..aeecf0f72cad50c633953e4ffd9617709239095b 100644 (file)
@@ -178,7 +178,7 @@ config PINCTRL_COH901
          ports of 8 GPIO pins each.
 
 config PINCTRL_SAMSUNG
-       bool "Samsung pinctrl driver"
+       bool
        depends on OF && GPIOLIB
        select PINMUX
        select PINCONF
index e7a4780e93db4fb8ab9c3134debc960930cd6906..9e198e5906750baf663518296d5ae130cbf4a05d 100644 (file)
@@ -120,15 +120,11 @@ static struct virtqueue *rp_find_vq(struct virtio_device *vdev,
        return vq;
 }
 
-static void rproc_virtio_del_vqs(struct virtio_device *vdev)
+static void __rproc_virtio_del_vqs(struct virtio_device *vdev)
 {
        struct virtqueue *vq, *n;
-       struct rproc *rproc = vdev_to_rproc(vdev);
        struct rproc_vring *rvring;
 
-       /* power down the remote processor before deleting vqs */
-       rproc_shutdown(rproc);
-
        list_for_each_entry_safe(vq, n, &vdev->vqs, list) {
                rvring = vq->priv;
                rvring->vq = NULL;
@@ -137,6 +133,16 @@ static void rproc_virtio_del_vqs(struct virtio_device *vdev)
        }
 }
 
+static void rproc_virtio_del_vqs(struct virtio_device *vdev)
+{
+       struct rproc *rproc = vdev_to_rproc(vdev);
+
+       /* power down the remote processor before deleting vqs */
+       rproc_shutdown(rproc);
+
+       __rproc_virtio_del_vqs(vdev);
+}
+
 static int rproc_virtio_find_vqs(struct virtio_device *vdev, unsigned nvqs,
                       struct virtqueue *vqs[],
                       vq_callback_t *callbacks[],
@@ -163,7 +169,7 @@ static int rproc_virtio_find_vqs(struct virtio_device *vdev, unsigned nvqs,
        return 0;
 
 error:
-       rproc_virtio_del_vqs(vdev);
+       __rproc_virtio_del_vqs(vdev);
        return ret;
 }
 
index 7a82337e4deee1ae9d1648ec6df5dbbcfe344ba4..073108dcf9e7b5660f1a4f9fb7074605bf247845 100644 (file)
@@ -288,11 +288,11 @@ static int __devinit tps65910_rtc_probe(struct platform_device *pdev)
 static int __devexit tps65910_rtc_remove(struct platform_device *pdev)
 {
        /* leave rtc running, but disable irqs */
-       struct rtc_device *rtc = platform_get_drvdata(pdev);
+       struct tps65910_rtc *tps_rtc = platform_get_drvdata(pdev);
 
-       tps65910_rtc_alarm_irq_enable(&rtc->dev, 0);
+       tps65910_rtc_alarm_irq_enable(&pdev->dev, 0);
 
-       rtc_device_unregister(rtc);
+       rtc_device_unregister(tps_rtc->rtc);
        return 0;
 }
 
index c1bafc3f3fb19bad3a1587c85345ef2c4fa9545f..9594ab62702b1786d51d7ac80f7e10b365b6ce61 100644 (file)
@@ -1972,7 +1972,7 @@ sci_io_request_frame_handler(struct isci_request *ireq,
                                                                      frame_index,
                                                                      (void **)&frame_buffer);
 
-                       sci_controller_copy_sata_response(&ireq->stp.req,
+                       sci_controller_copy_sata_response(&ireq->stp.rsp,
                                                               frame_header,
                                                               frame_buffer);
 
index 16b7a72a70c4aae344cefb39f64d4b9ca5155eb8..3b2365c8eab23a38fda34d71b27a7497294dd5fb 100644 (file)
@@ -1276,7 +1276,7 @@ struct megasas_evt_detail {
 } __attribute__ ((packed));
 
 struct megasas_aen_event {
-       struct work_struct hotplug_work;
+       struct delayed_work hotplug_work;
        struct megasas_instance *instance;
 };
 
index d2c5366aff7fba67ffa0bdef6007d69ff8e37de2..e4f2baacf1e1783ec9054bae3f7013afb5af0a5f 100644 (file)
@@ -2060,9 +2060,9 @@ megasas_service_aen(struct megasas_instance *instance, struct megasas_cmd *cmd)
                } else {
                        ev->instance = instance;
                        instance->ev = ev;
-                       INIT_WORK(&ev->hotplug_work, megasas_aen_polling);
-                       schedule_delayed_work(
-                               (struct delayed_work *)&ev->hotplug_work, 0);
+                       INIT_DELAYED_WORK(&ev->hotplug_work,
+                                         megasas_aen_polling);
+                       schedule_delayed_work(&ev->hotplug_work, 0);
                }
        }
 }
@@ -4352,8 +4352,7 @@ megasas_suspend(struct pci_dev *pdev, pm_message_t state)
        /* cancel the delayed work if this work still in queue */
        if (instance->ev != NULL) {
                struct megasas_aen_event *ev = instance->ev;
-               cancel_delayed_work_sync(
-                       (struct delayed_work *)&ev->hotplug_work);
+               cancel_delayed_work_sync(&ev->hotplug_work);
                instance->ev = NULL;
        }
 
@@ -4545,8 +4544,7 @@ static void __devexit megasas_detach_one(struct pci_dev *pdev)
        /* cancel the delayed work if this work still in queue*/
        if (instance->ev != NULL) {
                struct megasas_aen_event *ev = instance->ev;
-               cancel_delayed_work_sync(
-                       (struct delayed_work *)&ev->hotplug_work);
+               cancel_delayed_work_sync(&ev->hotplug_work);
                instance->ev = NULL;
        }
 
@@ -5190,7 +5188,7 @@ static void
 megasas_aen_polling(struct work_struct *work)
 {
        struct megasas_aen_event *ev =
-               container_of(work, struct megasas_aen_event, hotplug_work);
+               container_of(work, struct megasas_aen_event, hotplug_work.work);
        struct megasas_instance *instance = ev->instance;
        union megasas_evt_class_locale class_locale;
        struct  Scsi_Host *host;
index 2936b447cae93bc544fc054c862ecd6d1abb92c6..2c0d0ec8150b62d62d8ca3ca9ecc777a950a7c0a 100644 (file)
@@ -55,6 +55,7 @@
 #include <linux/cpu.h>
 #include <linux/mutex.h>
 #include <linux/async.h>
+#include <asm/unaligned.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
@@ -1061,6 +1062,50 @@ int scsi_get_vpd_page(struct scsi_device *sdev, u8 page, unsigned char *buf,
 }
 EXPORT_SYMBOL_GPL(scsi_get_vpd_page);
 
+/**
+ * scsi_report_opcode - Find out if a given command opcode is supported
+ * @sdev:      scsi device to query
+ * @buffer:    scratch buffer (must be at least 20 bytes long)
+ * @len:       length of buffer
+ * @opcode:    opcode for command to look up
+ *
+ * Uses the REPORT SUPPORTED OPERATION CODES to look up the given
+ * opcode. Returns 0 if RSOC fails or if the command opcode is
+ * unsupported. Returns 1 if the device claims to support the command.
+ */
+int scsi_report_opcode(struct scsi_device *sdev, unsigned char *buffer,
+                      unsigned int len, unsigned char opcode)
+{
+       unsigned char cmd[16];
+       struct scsi_sense_hdr sshdr;
+       int result;
+
+       if (sdev->no_report_opcodes || sdev->scsi_level < SCSI_SPC_3)
+               return 0;
+
+       memset(cmd, 0, 16);
+       cmd[0] = MAINTENANCE_IN;
+       cmd[1] = MI_REPORT_SUPPORTED_OPERATION_CODES;
+       cmd[2] = 1;             /* One command format */
+       cmd[3] = opcode;
+       put_unaligned_be32(len, &cmd[6]);
+       memset(buffer, 0, len);
+
+       result = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buffer, len,
+                                 &sshdr, 30 * HZ, 3, NULL);
+
+       if (result && scsi_sense_valid(&sshdr) &&
+           sshdr.sense_key == ILLEGAL_REQUEST &&
+           (sshdr.asc == 0x20 || sshdr.asc == 0x24) && sshdr.ascq == 0x00)
+               return 0;
+
+       if ((buffer[1] & 3) == 3) /* Command supported */
+               return 1;
+
+       return 0;
+}
+EXPORT_SYMBOL(scsi_report_opcode);
+
 /**
  * scsi_device_get  -  get an additional reference to a scsi_device
  * @sdev:      device to get a reference to
index da36a3a81a9ee2206f753a04d4fbbe91b883e00a..9032e910bca3044055ed23310b38c126318736bb 100644 (file)
@@ -900,11 +900,23 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
                                action = ACTION_FAIL;
                                error = -EILSEQ;
                        /* INVALID COMMAND OPCODE or INVALID FIELD IN CDB */
-                       } else if ((sshdr.asc == 0x20 || sshdr.asc == 0x24) &&
-                                  (cmd->cmnd[0] == UNMAP ||
-                                   cmd->cmnd[0] == WRITE_SAME_16 ||
-                                   cmd->cmnd[0] == WRITE_SAME)) {
-                               description = "Discard failure";
+                       } else if (sshdr.asc == 0x20 || sshdr.asc == 0x24) {
+                               switch (cmd->cmnd[0]) {
+                               case UNMAP:
+                                       description = "Discard failure";
+                                       break;
+                               case WRITE_SAME:
+                               case WRITE_SAME_16:
+                                       if (cmd->cmnd[1] & 0x8)
+                                               description = "Discard failure";
+                                       else
+                                               description =
+                                                       "Write same failure";
+                                       break;
+                               default:
+                                       description = "Invalid command failure";
+                                       break;
+                               }
                                action = ACTION_FAIL;
                                error = -EREMOTEIO;
                        } else
index 12f6fdfc11474a9363ae6c641959832d2c1d6440..352bc77b7c886fb80c057019c3edc2d5b95b7d7e 100644 (file)
@@ -99,6 +99,7 @@ MODULE_ALIAS_SCSI_DEVICE(TYPE_RBC);
 #endif
 
 static void sd_config_discard(struct scsi_disk *, unsigned int);
+static void sd_config_write_same(struct scsi_disk *);
 static int  sd_revalidate_disk(struct gendisk *);
 static void sd_unlock_native_capacity(struct gendisk *disk);
 static int  sd_probe(struct device *);
@@ -395,6 +396,45 @@ sd_store_max_medium_access_timeouts(struct device *dev,
        return err ? err : count;
 }
 
+static ssize_t
+sd_show_write_same_blocks(struct device *dev, struct device_attribute *attr,
+                         char *buf)
+{
+       struct scsi_disk *sdkp = to_scsi_disk(dev);
+
+       return snprintf(buf, 20, "%u\n", sdkp->max_ws_blocks);
+}
+
+static ssize_t
+sd_store_write_same_blocks(struct device *dev, struct device_attribute *attr,
+                          const char *buf, size_t count)
+{
+       struct scsi_disk *sdkp = to_scsi_disk(dev);
+       struct scsi_device *sdp = sdkp->device;
+       unsigned long max;
+       int err;
+
+       if (!capable(CAP_SYS_ADMIN))
+               return -EACCES;
+
+       if (sdp->type != TYPE_DISK)
+               return -EINVAL;
+
+       err = kstrtoul(buf, 10, &max);
+
+       if (err)
+               return err;
+
+       if (max == 0)
+               sdp->no_write_same = 1;
+       else if (max <= SD_MAX_WS16_BLOCKS)
+               sdkp->max_ws_blocks = max;
+
+       sd_config_write_same(sdkp);
+
+       return count;
+}
+
 static struct device_attribute sd_disk_attrs[] = {
        __ATTR(cache_type, S_IRUGO|S_IWUSR, sd_show_cache_type,
               sd_store_cache_type),
@@ -410,6 +450,8 @@ static struct device_attribute sd_disk_attrs[] = {
        __ATTR(thin_provisioning, S_IRUGO, sd_show_thin_provisioning, NULL),
        __ATTR(provisioning_mode, S_IRUGO|S_IWUSR, sd_show_provisioning_mode,
               sd_store_provisioning_mode),
+       __ATTR(max_write_same_blocks, S_IRUGO|S_IWUSR,
+              sd_show_write_same_blocks, sd_store_write_same_blocks),
        __ATTR(max_medium_access_timeouts, S_IRUGO|S_IWUSR,
               sd_show_max_medium_access_timeouts,
               sd_store_max_medium_access_timeouts),
@@ -561,19 +603,23 @@ static void sd_config_discard(struct scsi_disk *sdkp, unsigned int mode)
                return;
 
        case SD_LBP_UNMAP:
-               max_blocks = min_not_zero(sdkp->max_unmap_blocks, 0xffffffff);
+               max_blocks = min_not_zero(sdkp->max_unmap_blocks,
+                                         (u32)SD_MAX_WS16_BLOCKS);
                break;
 
        case SD_LBP_WS16:
-               max_blocks = min_not_zero(sdkp->max_ws_blocks, 0xffffffff);
+               max_blocks = min_not_zero(sdkp->max_ws_blocks,
+                                         (u32)SD_MAX_WS16_BLOCKS);
                break;
 
        case SD_LBP_WS10:
-               max_blocks = min_not_zero(sdkp->max_ws_blocks, (u32)0xffff);
+               max_blocks = min_not_zero(sdkp->max_ws_blocks,
+                                         (u32)SD_MAX_WS10_BLOCKS);
                break;
 
        case SD_LBP_ZERO:
-               max_blocks = min_not_zero(sdkp->max_ws_blocks, (u32)0xffff);
+               max_blocks = min_not_zero(sdkp->max_ws_blocks,
+                                         (u32)SD_MAX_WS10_BLOCKS);
                q->limits.discard_zeroes_data = 1;
                break;
        }
@@ -583,29 +629,26 @@ static void sd_config_discard(struct scsi_disk *sdkp, unsigned int mode)
 }
 
 /**
- * scsi_setup_discard_cmnd - unmap blocks on thinly provisioned device
+ * sd_setup_discard_cmnd - unmap blocks on thinly provisioned device
  * @sdp: scsi device to operate one
  * @rq: Request to prepare
  *
  * Will issue either UNMAP or WRITE SAME(16) depending on preference
  * indicated by target device.
  **/
-static int scsi_setup_discard_cmnd(struct scsi_device *sdp, struct request *rq)
+static int sd_setup_discard_cmnd(struct scsi_device *sdp, struct request *rq)
 {
        struct scsi_disk *sdkp = scsi_disk(rq->rq_disk);
-       struct bio *bio = rq->bio;
-       sector_t sector = bio->bi_sector;
-       unsigned int nr_sectors = bio_sectors(bio);
+       sector_t sector = blk_rq_pos(rq);
+       unsigned int nr_sectors = blk_rq_sectors(rq);
+       unsigned int nr_bytes = blk_rq_bytes(rq);
        unsigned int len;
        int ret;
        char *buf;
        struct page *page;
 
-       if (sdkp->device->sector_size == 4096) {
-               sector >>= 3;
-               nr_sectors >>= 3;
-       }
-
+       sector >>= ilog2(sdp->sector_size) - 9;
+       nr_sectors >>= ilog2(sdp->sector_size) - 9;
        rq->timeout = SD_TIMEOUT;
 
        memset(rq->cmd, 0, rq->cmd_len);
@@ -660,6 +703,7 @@ static int scsi_setup_discard_cmnd(struct scsi_device *sdp, struct request *rq)
        blk_add_request_payload(rq, page, len);
        ret = scsi_setup_blk_pc_cmnd(sdp, rq);
        rq->buffer = page_address(page);
+       rq->__data_len = nr_bytes;
 
 out:
        if (ret != BLKPREP_OK) {
@@ -669,6 +713,83 @@ out:
        return ret;
 }
 
+static void sd_config_write_same(struct scsi_disk *sdkp)
+{
+       struct request_queue *q = sdkp->disk->queue;
+       unsigned int logical_block_size = sdkp->device->sector_size;
+       unsigned int blocks = 0;
+
+       if (sdkp->device->no_write_same) {
+               sdkp->max_ws_blocks = 0;
+               goto out;
+       }
+
+       /* Some devices can not handle block counts above 0xffff despite
+        * supporting WRITE SAME(16). Consequently we default to 64k
+        * blocks per I/O unless the device explicitly advertises a
+        * bigger limit.
+        */
+       if (sdkp->max_ws_blocks == 0)
+               sdkp->max_ws_blocks = SD_MAX_WS10_BLOCKS;
+
+       if (sdkp->ws16 || sdkp->max_ws_blocks > SD_MAX_WS10_BLOCKS)
+               blocks = min_not_zero(sdkp->max_ws_blocks,
+                                     (u32)SD_MAX_WS16_BLOCKS);
+       else
+               blocks = min_not_zero(sdkp->max_ws_blocks,
+                                     (u32)SD_MAX_WS10_BLOCKS);
+
+out:
+       blk_queue_max_write_same_sectors(q, blocks * (logical_block_size >> 9));
+}
+
+/**
+ * sd_setup_write_same_cmnd - write the same data to multiple blocks
+ * @sdp: scsi device to operate one
+ * @rq: Request to prepare
+ *
+ * Will issue either WRITE SAME(10) or WRITE SAME(16) depending on
+ * preference indicated by target device.
+ **/
+static int sd_setup_write_same_cmnd(struct scsi_device *sdp, struct request *rq)
+{
+       struct scsi_disk *sdkp = scsi_disk(rq->rq_disk);
+       struct bio *bio = rq->bio;
+       sector_t sector = blk_rq_pos(rq);
+       unsigned int nr_sectors = blk_rq_sectors(rq);
+       unsigned int nr_bytes = blk_rq_bytes(rq);
+       int ret;
+
+       if (sdkp->device->no_write_same)
+               return BLKPREP_KILL;
+
+       BUG_ON(bio_offset(bio) || bio_iovec(bio)->bv_len != sdp->sector_size);
+
+       sector >>= ilog2(sdp->sector_size) - 9;
+       nr_sectors >>= ilog2(sdp->sector_size) - 9;
+
+       rq->__data_len = sdp->sector_size;
+       rq->timeout = SD_WRITE_SAME_TIMEOUT;
+       memset(rq->cmd, 0, rq->cmd_len);
+
+       if (sdkp->ws16 || sector > 0xffffffff || nr_sectors > 0xffff) {
+               rq->cmd_len = 16;
+               rq->cmd[0] = WRITE_SAME_16;
+               put_unaligned_be64(sector, &rq->cmd[2]);
+               put_unaligned_be32(nr_sectors, &rq->cmd[10]);
+       } else {
+               rq->cmd_len = 10;
+               rq->cmd[0] = WRITE_SAME;
+               put_unaligned_be32(sector, &rq->cmd[2]);
+               put_unaligned_be16(nr_sectors, &rq->cmd[7]);
+       }
+
+       ret = scsi_setup_blk_pc_cmnd(sdp, rq);
+       rq->__data_len = nr_bytes;
+
+       return ret;
+}
+
 static int scsi_setup_flush_cmnd(struct scsi_device *sdp, struct request *rq)
 {
        rq->timeout = SD_FLUSH_TIMEOUT;
@@ -712,7 +833,10 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq)
         * block PC requests to make life easier.
         */
        if (rq->cmd_flags & REQ_DISCARD) {
-               ret = scsi_setup_discard_cmnd(sdp, rq);
+               ret = sd_setup_discard_cmnd(sdp, rq);
+               goto out;
+       } else if (rq->cmd_flags & REQ_WRITE_SAME) {
+               ret = sd_setup_write_same_cmnd(sdp, rq);
                goto out;
        } else if (rq->cmd_flags & REQ_FLUSH) {
                ret = scsi_setup_flush_cmnd(sdp, rq);
@@ -1482,12 +1606,21 @@ static int sd_done(struct scsi_cmnd *SCpnt)
        unsigned int good_bytes = result ? 0 : scsi_bufflen(SCpnt);
        struct scsi_sense_hdr sshdr;
        struct scsi_disk *sdkp = scsi_disk(SCpnt->request->rq_disk);
+       struct request *req = SCpnt->request;
        int sense_valid = 0;
        int sense_deferred = 0;
        unsigned char op = SCpnt->cmnd[0];
+       unsigned char unmap = SCpnt->cmnd[1] & 8;
 
-       if ((SCpnt->request->cmd_flags & REQ_DISCARD) && !result)
-               scsi_set_resid(SCpnt, 0);
+       if (req->cmd_flags & REQ_DISCARD || req->cmd_flags & REQ_WRITE_SAME) {
+               if (!result) {
+                       good_bytes = blk_rq_bytes(req);
+                       scsi_set_resid(SCpnt, 0);
+               } else {
+                       good_bytes = 0;
+                       scsi_set_resid(SCpnt, blk_rq_bytes(req));
+               }
+       }
 
        if (result) {
                sense_valid = scsi_command_normalize_sense(SCpnt, &sshdr);
@@ -1536,9 +1669,25 @@ static int sd_done(struct scsi_cmnd *SCpnt)
                if (sshdr.asc == 0x10)  /* DIX: Host detected corruption */
                        good_bytes = sd_completed_bytes(SCpnt);
                /* INVALID COMMAND OPCODE or INVALID FIELD IN CDB */
-               if ((sshdr.asc == 0x20 || sshdr.asc == 0x24) &&
-                   (op == UNMAP || op == WRITE_SAME_16 || op == WRITE_SAME))
-                       sd_config_discard(sdkp, SD_LBP_DISABLE);
+               if (sshdr.asc == 0x20 || sshdr.asc == 0x24) {
+                       switch (op) {
+                       case UNMAP:
+                               sd_config_discard(sdkp, SD_LBP_DISABLE);
+                               break;
+                       case WRITE_SAME_16:
+                       case WRITE_SAME:
+                               if (unmap)
+                                       sd_config_discard(sdkp, SD_LBP_DISABLE);
+                               else {
+                                       sdkp->device->no_write_same = 1;
+                                       sd_config_write_same(sdkp);
+
+                                       good_bytes = 0;
+                                       req->__data_len = blk_rq_bytes(req);
+                                       req->cmd_flags |= REQ_QUIET;
+                               }
+                       }
+               }
                break;
        default:
                break;
@@ -2374,9 +2523,7 @@ static void sd_read_block_limits(struct scsi_disk *sdkp)
        if (buffer[3] == 0x3c) {
                unsigned int lba_count, desc_count;
 
-               sdkp->max_ws_blocks =
-                       (u32) min_not_zero(get_unaligned_be64(&buffer[36]),
-                                          (u64)0xffffffff);
+               sdkp->max_ws_blocks = (u32)get_unaligned_be64(&buffer[36]);
 
                if (!sdkp->lbpme)
                        goto out;
@@ -2469,6 +2616,13 @@ static void sd_read_block_provisioning(struct scsi_disk *sdkp)
        kfree(buffer);
 }
 
+static void sd_read_write_same(struct scsi_disk *sdkp, unsigned char *buffer)
+{
+       if (scsi_report_opcode(sdkp->device, buffer, SD_BUF_SIZE,
+                              WRITE_SAME_16))
+               sdkp->ws16 = 1;
+}
+
 static int sd_try_extended_inquiry(struct scsi_device *sdp)
 {
        /*
@@ -2528,6 +2682,7 @@ static int sd_revalidate_disk(struct gendisk *disk)
                sd_read_write_protect_flag(sdkp, buffer);
                sd_read_cache_type(sdkp, buffer);
                sd_read_app_tag_own(sdkp, buffer);
+               sd_read_write_same(sdkp, buffer);
        }
 
        sdkp->first_scan = 0;
@@ -2545,6 +2700,7 @@ static int sd_revalidate_disk(struct gendisk *disk)
        blk_queue_flush(sdkp->disk->queue, flush);
 
        set_capacity(disk, sdkp->capacity);
+       sd_config_write_same(sdkp);
        kfree(buffer);
 
  out:
index 47c52a6d733c0f757b4ef42236e89fba172b857c..74a1e4ca5401f9a58e6e705bb2fc8a99fcd04a0f 100644 (file)
@@ -14,6 +14,7 @@
 #define SD_TIMEOUT             (30 * HZ)
 #define SD_MOD_TIMEOUT         (75 * HZ)
 #define SD_FLUSH_TIMEOUT       (60 * HZ)
+#define SD_WRITE_SAME_TIMEOUT  (120 * HZ)
 
 /*
  * Number of allowed retries
@@ -38,6 +39,11 @@ enum {
        SD_MEMPOOL_SIZE = 2,    /* CDB pool size */
 };
 
+enum {
+       SD_MAX_WS10_BLOCKS = 0xffff,
+       SD_MAX_WS16_BLOCKS = 0x7fffff,
+};
+
 enum {
        SD_LBP_FULL = 0,        /* Full logical block provisioning */
        SD_LBP_UNMAP,           /* Use UNMAP command */
@@ -77,6 +83,7 @@ struct scsi_disk {
        unsigned        lbpws : 1;
        unsigned        lbpws10 : 1;
        unsigned        lbpvpd : 1;
+       unsigned        ws16 : 1;
 };
 #define to_scsi_disk(obj) container_of(obj,struct scsi_disk,dev)
 
index 9097155e9ebe7100c0bc1a4ac13b7c508a84ac8a..dcecbfb172436b3ec0d51232efd988e7247f9afe 100644 (file)
@@ -1819,8 +1819,10 @@ void target_execute_cmd(struct se_cmd *cmd)
        /*
         * If the received CDB has aleady been aborted stop processing it here.
         */
-       if (transport_check_aborted_status(cmd, 1))
+       if (transport_check_aborted_status(cmd, 1)) {
+               complete(&cmd->t_transport_stop_comp);
                return;
+       }
 
        /*
         * Determine if IOCTL context caller in requesting the stopping of this
@@ -3067,7 +3069,7 @@ void transport_send_task_abort(struct se_cmd *cmd)
        unsigned long flags;
 
        spin_lock_irqsave(&cmd->t_state_lock, flags);
-       if (cmd->se_cmd_flags & SCF_SENT_CHECK_CONDITION) {
+       if (cmd->se_cmd_flags & (SCF_SENT_CHECK_CONDITION | SCF_SENT_DELAYED_TAS)) {
                spin_unlock_irqrestore(&cmd->t_state_lock, flags);
                return;
        }
index f87d7e8964bf0849c1ab3e3da327e3a14c9b35a2..4e0d0c3734b326f80c635b1839fb4397eadcc59f 100644 (file)
@@ -539,25 +539,25 @@ static void insert_char(struct vc_data *vc, unsigned int nr)
 {
        unsigned short *p = (unsigned short *) vc->vc_pos;
 
-       scr_memmovew(p + nr, p, vc->vc_cols - vc->vc_x);
+       scr_memmovew(p + nr, p, (vc->vc_cols - vc->vc_x) * 2);
        scr_memsetw(p, vc->vc_video_erase_char, nr * 2);
        vc->vc_need_wrap = 0;
        if (DO_UPDATE(vc))
                do_update_region(vc, (unsigned long) p,
-                       (vc->vc_cols - vc->vc_x) / 2 + 1);
+                       vc->vc_cols - vc->vc_x);
 }
 
 static void delete_char(struct vc_data *vc, unsigned int nr)
 {
        unsigned short *p = (unsigned short *) vc->vc_pos;
 
-       scr_memcpyw(p, p + nr, vc->vc_cols - vc->vc_x - nr);
+       scr_memcpyw(p, p + nr, (vc->vc_cols - vc->vc_x - nr) * 2);
        scr_memsetw(p + vc->vc_cols - vc->vc_x - nr, vc->vc_video_erase_char,
                        nr * 2);
        vc->vc_need_wrap = 0;
        if (DO_UPDATE(vc))
                do_update_region(vc, (unsigned long) p,
-                       (vc->vc_cols - vc->vc_x) / 2);
+                       vc->vc_cols - vc->vc_x);
 }
 
 static int softcursor_original;
index a3d54366afccde598a4ba5f3240909044f975266..92f35abee92d281990e17ccdb4f388d33ed67f0e 100644 (file)
@@ -186,6 +186,12 @@ static int slave_configure(struct scsi_device *sdev)
                /* Some devices don't handle VPD pages correctly */
                sdev->skip_vpd_pages = 1;
 
+               /* Do not attempt to use REPORT SUPPORTED OPERATION CODES */
+               sdev->no_report_opcodes = 1;
+
+               /* Do not attempt to use WRITE SAME */
+               sdev->no_write_same = 1;
+
                /* Some disks return the total number of blocks in response
                 * to READ CAPACITY rather than the highest block number.
                 * If this device makes that mistake, tell the sd driver. */
index 99ac2cb08b43bcb3b570969d752bff25126f298d..dedaf81d8f36fd89a5258d9a21fd261401f6e0d9 100644 (file)
@@ -1076,7 +1076,7 @@ static int translate_desc(struct vhost_dev *dev, u64 addr, u32 len,
                }
                _iov = iov + ret;
                size = reg->memory_size - addr + reg->guest_phys_addr;
-               _iov->iov_len = min((u64)len, size);
+               _iov->iov_len = min((u64)len - s, size);
                _iov->iov_base = (void __user *)(unsigned long)
                        (reg->userspace_addr + addr - reg->guest_phys_addr);
                s += size;
index d64ac3842884f4e9eac994dd03fdc311646d27b9..bee92846cfab930f6304a9ebb4316b25b8780bc7 100644 (file)
@@ -365,11 +365,20 @@ struct platform_device *dsi_get_dsidev_from_id(int module)
        struct omap_dss_output *out;
        enum omap_dss_output_id id;
 
-       id = module == 0 ? OMAP_DSS_OUTPUT_DSI1 : OMAP_DSS_OUTPUT_DSI2;
+       switch (module) {
+       case 0:
+               id = OMAP_DSS_OUTPUT_DSI1;
+               break;
+       case 1:
+               id = OMAP_DSS_OUTPUT_DSI2;
+               break;
+       default:
+               return NULL;
+       }
 
        out = omap_dss_get_output(id);
 
-       return out->pdev;
+       return out ? out->pdev : NULL;
 }
 
 static inline void dsi_write_reg(struct platform_device *dsidev,
index 2ab1c3e96553d81297ad5f942eed2cfb76a5064b..5f6eea801b064a37949b3cc66bf9ca5f2dde3431 100644 (file)
@@ -697,11 +697,15 @@ static int dss_get_clocks(void)
 
        dss.dss_clk = clk;
 
-       clk = clk_get(NULL, dss.feat->clk_name);
-       if (IS_ERR(clk)) {
-               DSSERR("Failed to get %s\n", dss.feat->clk_name);
-               r = PTR_ERR(clk);
-               goto err;
+       if (dss.feat->clk_name) {
+               clk = clk_get(NULL, dss.feat->clk_name);
+               if (IS_ERR(clk)) {
+                       DSSERR("Failed to get %s\n", dss.feat->clk_name);
+                       r = PTR_ERR(clk);
+                       goto err;
+               }
+       } else {
+               clk = NULL;
        }
 
        dss.dpll4_m4_ck = clk;
@@ -805,10 +809,10 @@ static int __init dss_init_features(struct device *dev)
 
        if (cpu_is_omap24xx())
                src = &omap24xx_dss_feats;
-       else if (cpu_is_omap34xx())
-               src = &omap34xx_dss_feats;
        else if (cpu_is_omap3630())
                src = &omap3630_dss_feats;
+       else if (cpu_is_omap34xx())
+               src = &omap34xx_dss_feats;
        else if (cpu_is_omap44xx())
                src = &omap44xx_dss_feats;
        else if (soc_is_omap54xx())
index a48a7dd75b3303a3bba28e10b01e4c1f133c00d3..8c9b8b3b7f773cd41c00f78b923070f87c325f70 100644 (file)
@@ -644,8 +644,10 @@ static void hdmi_dump_regs(struct seq_file *s)
 {
        mutex_lock(&hdmi.lock);
 
-       if (hdmi_runtime_get())
+       if (hdmi_runtime_get()) {
+               mutex_unlock(&hdmi.lock);
                return;
+       }
 
        hdmi.ip_data.ops->dump_wrapper(&hdmi.ip_data, s);
        hdmi.ip_data.ops->dump_pll(&hdmi.ip_data, s);
index 606b89f12351d4e1cc2cb234fd4e5c481bf82cda..d630b26a005c7ae2e0bea55b1c0a644fc64ad1e9 100644 (file)
@@ -787,7 +787,7 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
 
        case OMAPFB_WAITFORVSYNC:
                DBG("ioctl WAITFORVSYNC\n");
-               if (!display && !display->output && !display->output->manager) {
+               if (!display || !display->output || !display->output->manager) {
                        r = -EINVAL;
                        break;
                }
index 8adb9cc267f96e201ade041441ef8a317ce336d8..71f5c459b088aa5e21066b77adbcb5f34f7b9843 100644 (file)
@@ -361,13 +361,13 @@ static long privcmd_ioctl_mmap_batch(void __user *udata, int version)
        down_write(&mm->mmap_sem);
 
        vma = find_vma(mm, m.addr);
-       ret = -EINVAL;
        if (!vma ||
            vma->vm_ops != &privcmd_vm_ops ||
            (m.addr != vma->vm_start) ||
            ((m.addr + (nr_pages << PAGE_SHIFT)) != vma->vm_end) ||
            !privcmd_enforce_singleshot_mapping(vma)) {
                up_write(&mm->mmap_sem);
+               ret = -EINVAL;
                goto out;
        }
 
@@ -383,12 +383,16 @@ static long privcmd_ioctl_mmap_batch(void __user *udata, int version)
 
        up_write(&mm->mmap_sem);
 
-       if (state.global_error && (version == 1)) {
-               /* Write back errors in second pass. */
-               state.user_mfn = (xen_pfn_t *)m.arr;
-               state.err      = err_array;
-               ret = traverse_pages(m.num, sizeof(xen_pfn_t),
-                                    &pagelist, mmap_return_errors_v1, &state);
+       if (version == 1) {
+               if (state.global_error) {
+                       /* Write back errors in second pass. */
+                       state.user_mfn = (xen_pfn_t *)m.arr;
+                       state.err      = err_array;
+                       ret = traverse_pages(m.num, sizeof(xen_pfn_t),
+                                            &pagelist, mmap_return_errors_v1, &state);
+               } else
+                       ret = 0;
+
        } else if (version == 2) {
                ret = __copy_to_user(m.err, err_array, m.num * sizeof(int));
                if (ret)
index 1a1e5e3b1eafc7f00454cb2d544b8761161d015e..ab3a456f66506a5a134f5280739e82c572b15f55 100644 (file)
@@ -70,19 +70,6 @@ static void bdev_inode_switch_bdi(struct inode *inode,
        spin_unlock(&dst->wb.list_lock);
 }
 
-sector_t blkdev_max_block(struct block_device *bdev)
-{
-       sector_t retval = ~((sector_t)0);
-       loff_t sz = i_size_read(bdev->bd_inode);
-
-       if (sz) {
-               unsigned int size = block_size(bdev);
-               unsigned int sizebits = blksize_bits(size);
-               retval = (sz >> sizebits);
-       }
-       return retval;
-}
-
 /* Kill _all_ buffers and pagecache , dirty or not.. */
 void kill_bdev(struct block_device *bdev)
 {
@@ -116,8 +103,6 @@ EXPORT_SYMBOL(invalidate_bdev);
 
 int set_blocksize(struct block_device *bdev, int size)
 {
-       struct address_space *mapping;
-
        /* Size must be a power of two, and between 512 and PAGE_SIZE */
        if (size > PAGE_SIZE || size < 512 || !is_power_of_2(size))
                return -EINVAL;
@@ -126,19 +111,6 @@ int set_blocksize(struct block_device *bdev, int size)
        if (size < bdev_logical_block_size(bdev))
                return -EINVAL;
 
-       /* Prevent starting I/O or mapping the device */
-       percpu_down_write(&bdev->bd_block_size_semaphore);
-
-       /* Check that the block device is not memory mapped */
-       mapping = bdev->bd_inode->i_mapping;
-       mutex_lock(&mapping->i_mmap_mutex);
-       if (mapping_mapped(mapping)) {
-               mutex_unlock(&mapping->i_mmap_mutex);
-               percpu_up_write(&bdev->bd_block_size_semaphore);
-               return -EBUSY;
-       }
-       mutex_unlock(&mapping->i_mmap_mutex);
-
        /* Don't change the size if it is same as current */
        if (bdev->bd_block_size != size) {
                sync_blockdev(bdev);
@@ -146,9 +118,6 @@ int set_blocksize(struct block_device *bdev, int size)
                bdev->bd_inode->i_blkbits = blksize_bits(size);
                kill_bdev(bdev);
        }
-
-       percpu_up_write(&bdev->bd_block_size_semaphore);
-
        return 0;
 }
 
@@ -181,52 +150,12 @@ static int
 blkdev_get_block(struct inode *inode, sector_t iblock,
                struct buffer_head *bh, int create)
 {
-       if (iblock >= blkdev_max_block(I_BDEV(inode))) {
-               if (create)
-                       return -EIO;
-
-               /*
-                * for reads, we're just trying to fill a partial page.
-                * return a hole, they will have to call get_block again
-                * before they can fill it, and they will get -EIO at that
-                * time
-                */
-               return 0;
-       }
        bh->b_bdev = I_BDEV(inode);
        bh->b_blocknr = iblock;
        set_buffer_mapped(bh);
        return 0;
 }
 
-static int
-blkdev_get_blocks(struct inode *inode, sector_t iblock,
-               struct buffer_head *bh, int create)
-{
-       sector_t end_block = blkdev_max_block(I_BDEV(inode));
-       unsigned long max_blocks = bh->b_size >> inode->i_blkbits;
-
-       if ((iblock + max_blocks) > end_block) {
-               max_blocks = end_block - iblock;
-               if ((long)max_blocks <= 0) {
-                       if (create)
-                               return -EIO;    /* write fully beyond EOF */
-                       /*
-                        * It is a read which is fully beyond EOF.  We return
-                        * a !buffer_mapped buffer
-                        */
-                       max_blocks = 0;
-               }
-       }
-
-       bh->b_bdev = I_BDEV(inode);
-       bh->b_blocknr = iblock;
-       bh->b_size = max_blocks << inode->i_blkbits;
-       if (max_blocks)
-               set_buffer_mapped(bh);
-       return 0;
-}
-
 static ssize_t
 blkdev_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
                        loff_t offset, unsigned long nr_segs)
@@ -235,7 +164,7 @@ blkdev_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
        struct inode *inode = file->f_mapping->host;
 
        return __blockdev_direct_IO(rw, iocb, inode, I_BDEV(inode), iov, offset,
-                                   nr_segs, blkdev_get_blocks, NULL, NULL, 0);
+                                   nr_segs, blkdev_get_block, NULL, NULL, 0);
 }
 
 int __sync_blockdev(struct block_device *bdev, int wait)
@@ -459,12 +388,6 @@ static struct inode *bdev_alloc_inode(struct super_block *sb)
        struct bdev_inode *ei = kmem_cache_alloc(bdev_cachep, GFP_KERNEL);
        if (!ei)
                return NULL;
-
-       if (unlikely(percpu_init_rwsem(&ei->bdev.bd_block_size_semaphore))) {
-               kmem_cache_free(bdev_cachep, ei);
-               return NULL;
-       }
-
        return &ei->vfs_inode;
 }
 
@@ -473,8 +396,6 @@ static void bdev_i_callback(struct rcu_head *head)
        struct inode *inode = container_of(head, struct inode, i_rcu);
        struct bdev_inode *bdi = BDEV_I(inode);
 
-       percpu_free_rwsem(&bdi->bdev.bd_block_size_semaphore);
-
        kmem_cache_free(bdev_cachep, bdi);
 }
 
@@ -1593,22 +1514,6 @@ static long block_ioctl(struct file *file, unsigned cmd, unsigned long arg)
        return blkdev_ioctl(bdev, mode, cmd, arg);
 }
 
-ssize_t blkdev_aio_read(struct kiocb *iocb, const struct iovec *iov,
-                       unsigned long nr_segs, loff_t pos)
-{
-       ssize_t ret;
-       struct block_device *bdev = I_BDEV(iocb->ki_filp->f_mapping->host);
-
-       percpu_down_read(&bdev->bd_block_size_semaphore);
-
-       ret = generic_file_aio_read(iocb, iov, nr_segs, pos);
-
-       percpu_up_read(&bdev->bd_block_size_semaphore);
-
-       return ret;
-}
-EXPORT_SYMBOL_GPL(blkdev_aio_read);
-
 /*
  * Write data to the block device.  Only intended for the block device itself
  * and the raw driver which basically is a fake block device.
@@ -1620,16 +1525,12 @@ ssize_t blkdev_aio_write(struct kiocb *iocb, const struct iovec *iov,
                         unsigned long nr_segs, loff_t pos)
 {
        struct file *file = iocb->ki_filp;
-       struct block_device *bdev = I_BDEV(file->f_mapping->host);
        struct blk_plug plug;
        ssize_t ret;
 
        BUG_ON(iocb->ki_pos != pos);
 
        blk_start_plug(&plug);
-
-       percpu_down_read(&bdev->bd_block_size_semaphore);
-
        ret = __generic_file_aio_write(iocb, iov, nr_segs, &iocb->ki_pos);
        if (ret > 0 || ret == -EIOCBQUEUED) {
                ssize_t err;
@@ -1638,62 +1539,27 @@ ssize_t blkdev_aio_write(struct kiocb *iocb, const struct iovec *iov,
                if (err < 0 && ret > 0)
                        ret = err;
        }
-
-       percpu_up_read(&bdev->bd_block_size_semaphore);
-
        blk_finish_plug(&plug);
-
        return ret;
 }
 EXPORT_SYMBOL_GPL(blkdev_aio_write);
 
-static int blkdev_mmap(struct file *file, struct vm_area_struct *vma)
-{
-       int ret;
-       struct block_device *bdev = I_BDEV(file->f_mapping->host);
-
-       percpu_down_read(&bdev->bd_block_size_semaphore);
-
-       ret = generic_file_mmap(file, vma);
-
-       percpu_up_read(&bdev->bd_block_size_semaphore);
-
-       return ret;
-}
-
-static ssize_t blkdev_splice_read(struct file *file, loff_t *ppos,
-                                 struct pipe_inode_info *pipe, size_t len,
-                                 unsigned int flags)
-{
-       ssize_t ret;
-       struct block_device *bdev = I_BDEV(file->f_mapping->host);
-
-       percpu_down_read(&bdev->bd_block_size_semaphore);
-
-       ret = generic_file_splice_read(file, ppos, pipe, len, flags);
-
-       percpu_up_read(&bdev->bd_block_size_semaphore);
-
-       return ret;
-}
-
-static ssize_t blkdev_splice_write(struct pipe_inode_info *pipe,
-                                  struct file *file, loff_t *ppos, size_t len,
-                                  unsigned int flags)
+static ssize_t blkdev_aio_read(struct kiocb *iocb, const struct iovec *iov,
+                        unsigned long nr_segs, loff_t pos)
 {
-       ssize_t ret;
-       struct block_device *bdev = I_BDEV(file->f_mapping->host);
-
-       percpu_down_read(&bdev->bd_block_size_semaphore);
-
-       ret = generic_file_splice_write(pipe, file, ppos, len, flags);
+       struct file *file = iocb->ki_filp;
+       struct inode *bd_inode = file->f_mapping->host;
+       loff_t size = i_size_read(bd_inode);
 
-       percpu_up_read(&bdev->bd_block_size_semaphore);
+       if (pos >= size)
+               return 0;
 
-       return ret;
+       size -= pos;
+       if (size < INT_MAX)
+               nr_segs = iov_shorten((struct iovec *)iov, nr_segs, size);
+       return generic_file_aio_read(iocb, iov, nr_segs, pos);
 }
 
-
 /*
  * Try to release a page associated with block device when the system
  * is under memory pressure.
@@ -1724,16 +1590,16 @@ const struct file_operations def_blk_fops = {
        .llseek         = block_llseek,
        .read           = do_sync_read,
        .write          = do_sync_write,
-       .aio_read       = blkdev_aio_read,
+       .aio_read       = blkdev_aio_read,
        .aio_write      = blkdev_aio_write,
-       .mmap           = blkdev_mmap,
+       .mmap           = generic_file_mmap,
        .fsync          = blkdev_fsync,
        .unlocked_ioctl = block_ioctl,
 #ifdef CONFIG_COMPAT
        .compat_ioctl   = compat_blkdev_ioctl,
 #endif
-       .splice_read    = blkdev_splice_read,
-       .splice_write   = blkdev_splice_write,
+       .splice_read    = generic_file_splice_read,
+       .splice_write   = generic_file_splice_write,
 };
 
 int ioctl_by_bdev(struct block_device *bdev, unsigned cmd, unsigned long arg)
index b5f044283edb53b1c9a65f01b385de3f77898a91..ec0aca8ba6bfdc79022563007207c5a70d23bd37 100644 (file)
@@ -911,6 +911,18 @@ link_dev_buffers(struct page *page, struct buffer_head *head)
        attach_page_buffers(page, head);
 }
 
+static sector_t blkdev_max_block(struct block_device *bdev, unsigned int size)
+{
+       sector_t retval = ~((sector_t)0);
+       loff_t sz = i_size_read(bdev->bd_inode);
+
+       if (sz) {
+               unsigned int sizebits = blksize_bits(size);
+               retval = (sz >> sizebits);
+       }
+       return retval;
+}
+
 /*
  * Initialise the state of a blockdev page's buffers.
  */ 
@@ -921,7 +933,7 @@ init_page_buffers(struct page *page, struct block_device *bdev,
        struct buffer_head *head = page_buffers(page);
        struct buffer_head *bh = head;
        int uptodate = PageUptodate(page);
-       sector_t end_block = blkdev_max_block(I_BDEV(bdev->bd_inode));
+       sector_t end_block = blkdev_max_block(I_BDEV(bdev->bd_inode), size);
 
        do {
                if (!buffer_mapped(bh)) {
@@ -1552,6 +1564,28 @@ void unmap_underlying_metadata(struct block_device *bdev, sector_t block)
 }
 EXPORT_SYMBOL(unmap_underlying_metadata);
 
+/*
+ * Size is a power-of-two in the range 512..PAGE_SIZE,
+ * and the case we care about most is PAGE_SIZE.
+ *
+ * So this *could* possibly be written with those
+ * constraints in mind (relevant mostly if some
+ * architecture has a slow bit-scan instruction)
+ */
+static inline int block_size_bits(unsigned int blocksize)
+{
+       return ilog2(blocksize);
+}
+
+static struct buffer_head *create_page_buffers(struct page *page, struct inode *inode, unsigned int b_state)
+{
+       BUG_ON(!PageLocked(page));
+
+       if (!page_has_buffers(page))
+               create_empty_buffers(page, 1 << ACCESS_ONCE(inode->i_blkbits), b_state);
+       return page_buffers(page);
+}
+
 /*
  * NOTE! All mapped/uptodate combinations are valid:
  *
@@ -1589,19 +1623,13 @@ static int __block_write_full_page(struct inode *inode, struct page *page,
        sector_t block;
        sector_t last_block;
        struct buffer_head *bh, *head;
-       const unsigned blocksize = 1 << inode->i_blkbits;
+       unsigned int blocksize, bbits;
        int nr_underway = 0;
        int write_op = (wbc->sync_mode == WB_SYNC_ALL ?
                        WRITE_SYNC : WRITE);
 
-       BUG_ON(!PageLocked(page));
-
-       last_block = (i_size_read(inode) - 1) >> inode->i_blkbits;
-
-       if (!page_has_buffers(page)) {
-               create_empty_buffers(page, blocksize,
+       head = create_page_buffers(page, inode,
                                        (1 << BH_Dirty)|(1 << BH_Uptodate));
-       }
 
        /*
         * Be very careful.  We have no exclusion from __set_page_dirty_buffers
@@ -1613,9 +1641,12 @@ static int __block_write_full_page(struct inode *inode, struct page *page,
         * handle that here by just cleaning them.
         */
 
-       block = (sector_t)page->index << (PAGE_CACHE_SHIFT - inode->i_blkbits);
-       head = page_buffers(page);
        bh = head;
+       blocksize = bh->b_size;
+       bbits = block_size_bits(blocksize);
+
+       block = (sector_t)page->index << (PAGE_CACHE_SHIFT - bbits);
+       last_block = (i_size_read(inode) - 1) >> bbits;
 
        /*
         * Get all the dirty buffers mapped to disk addresses and
@@ -1806,12 +1837,10 @@ int __block_write_begin(struct page *page, loff_t pos, unsigned len,
        BUG_ON(to > PAGE_CACHE_SIZE);
        BUG_ON(from > to);
 
-       blocksize = 1 << inode->i_blkbits;
-       if (!page_has_buffers(page))
-               create_empty_buffers(page, blocksize, 0);
-       head = page_buffers(page);
+       head = create_page_buffers(page, inode, 0);
+       blocksize = head->b_size;
+       bbits = block_size_bits(blocksize);
 
-       bbits = inode->i_blkbits;
        block = (sector_t)page->index << (PAGE_CACHE_SHIFT - bbits);
 
        for(bh = head, block_start = 0; bh != head || !block_start;
@@ -1881,11 +1910,11 @@ static int __block_commit_write(struct inode *inode, struct page *page,
        unsigned blocksize;
        struct buffer_head *bh, *head;
 
-       blocksize = 1 << inode->i_blkbits;
+       bh = head = page_buffers(page);
+       blocksize = bh->b_size;
 
-       for(bh = head = page_buffers(page), block_start = 0;
-           bh != head || !block_start;
-           block_start=block_end, bh = bh->b_this_page) {
+       block_start = 0;
+       do {
                block_end = block_start + blocksize;
                if (block_end <= from || block_start >= to) {
                        if (!buffer_uptodate(bh))
@@ -1895,7 +1924,10 @@ static int __block_commit_write(struct inode *inode, struct page *page,
                        mark_buffer_dirty(bh);
                }
                clear_buffer_new(bh);
-       }
+
+               block_start = block_end;
+               bh = bh->b_this_page;
+       } while (bh != head);
 
        /*
         * If this is a partial write which happened to make all buffers
@@ -2020,7 +2052,6 @@ EXPORT_SYMBOL(generic_write_end);
 int block_is_partially_uptodate(struct page *page, read_descriptor_t *desc,
                                        unsigned long from)
 {
-       struct inode *inode = page->mapping->host;
        unsigned block_start, block_end, blocksize;
        unsigned to;
        struct buffer_head *bh, *head;
@@ -2029,13 +2060,13 @@ int block_is_partially_uptodate(struct page *page, read_descriptor_t *desc,
        if (!page_has_buffers(page))
                return 0;
 
-       blocksize = 1 << inode->i_blkbits;
+       head = page_buffers(page);
+       blocksize = head->b_size;
        to = min_t(unsigned, PAGE_CACHE_SIZE - from, desc->count);
        to = from + to;
        if (from < blocksize && to > PAGE_CACHE_SIZE - blocksize)
                return 0;
 
-       head = page_buffers(page);
        bh = head;
        block_start = 0;
        do {
@@ -2068,18 +2099,16 @@ int block_read_full_page(struct page *page, get_block_t *get_block)
        struct inode *inode = page->mapping->host;
        sector_t iblock, lblock;
        struct buffer_head *bh, *head, *arr[MAX_BUF_PER_PAGE];
-       unsigned int blocksize;
+       unsigned int blocksize, bbits;
        int nr, i;
        int fully_mapped = 1;
 
-       BUG_ON(!PageLocked(page));
-       blocksize = 1 << inode->i_blkbits;
-       if (!page_has_buffers(page))
-               create_empty_buffers(page, blocksize, 0);
-       head = page_buffers(page);
+       head = create_page_buffers(page, inode, 0);
+       blocksize = head->b_size;
+       bbits = block_size_bits(blocksize);
 
-       iblock = (sector_t)page->index << (PAGE_CACHE_SHIFT - inode->i_blkbits);
-       lblock = (i_size_read(inode)+blocksize-1) >> inode->i_blkbits;
+       iblock = (sector_t)page->index << (PAGE_CACHE_SHIFT - bbits);
+       lblock = (i_size_read(inode)+blocksize-1) >> bbits;
        bh = head;
        nr = 0;
        i = 0;
@@ -2864,6 +2893,55 @@ static void end_bio_bh_io_sync(struct bio *bio, int err)
        bio_put(bio);
 }
 
+/*
+ * This allows us to do IO even on the odd last sectors
+ * of a device, even if the bh block size is some multiple
+ * of the physical sector size.
+ *
+ * We'll just truncate the bio to the size of the device,
+ * and clear the end of the buffer head manually.
+ *
+ * Truly out-of-range accesses will turn into actual IO
+ * errors, this only handles the "we need to be able to
+ * do IO at the final sector" case.
+ */
+static void guard_bh_eod(int rw, struct bio *bio, struct buffer_head *bh)
+{
+       sector_t maxsector;
+       unsigned bytes;
+
+       maxsector = i_size_read(bio->bi_bdev->bd_inode) >> 9;
+       if (!maxsector)
+               return;
+
+       /*
+        * If the *whole* IO is past the end of the device,
+        * let it through, and the IO layer will turn it into
+        * an EIO.
+        */
+       if (unlikely(bio->bi_sector >= maxsector))
+               return;
+
+       maxsector -= bio->bi_sector;
+       bytes = bio->bi_size;
+       if (likely((bytes >> 9) <= maxsector))
+               return;
+
+       /* Uhhuh. We've got a bh that straddles the device size! */
+       bytes = maxsector << 9;
+
+       /* Truncate the bio.. */
+       bio->bi_size = bytes;
+       bio->bi_io_vec[0].bv_len = bytes;
+
+       /* ..and clear the end of the buffer for reads */
+       if ((rw & RW_MASK) == READ) {
+               void *kaddr = kmap_atomic(bh->b_page);
+               memset(kaddr + bh_offset(bh) + bytes, 0, bh->b_size - bytes);
+               kunmap_atomic(kaddr);
+       }
+}
+
 int submit_bh(int rw, struct buffer_head * bh)
 {
        struct bio *bio;
@@ -2900,6 +2978,9 @@ int submit_bh(int rw, struct buffer_head * bh)
        bio->bi_end_io = end_bio_bh_io_sync;
        bio->bi_private = bh;
 
+       /* Take care of bh's that straddle the end of the device */
+       guard_bh_eod(rw, bio, bh);
+
        bio_get(bio);
        submit_bio(rw, bio);
 
index edb25b4bbb959c49e0681d7a7b992b2e1093a710..70b6f4c3a0c1c73d1a0babc2be2dbcab0b17e552 100644 (file)
@@ -1794,7 +1794,6 @@ static int cifs_writepages(struct address_space *mapping,
        struct TCP_Server_Info *server;
        struct page *page;
        int rc = 0;
-       loff_t isize = i_size_read(mapping->host);
 
        /*
         * If wsize is smaller than the page cache size, default to writing
@@ -1899,7 +1898,7 @@ retry:
                         */
                        set_page_writeback(page);
 
-                       if (page_offset(page) >= isize) {
+                       if (page_offset(page) >= i_size_read(mapping->host)) {
                                done = true;
                                unlock_page(page);
                                end_page_writeback(page);
@@ -1932,7 +1931,8 @@ retry:
                wdata->offset = page_offset(wdata->pages[0]);
                wdata->pagesz = PAGE_CACHE_SIZE;
                wdata->tailsz =
-                       min(isize - page_offset(wdata->pages[nr_pages - 1]),
+                       min(i_size_read(mapping->host) -
+                           page_offset(wdata->pages[nr_pages - 1]),
                            (loff_t)PAGE_CACHE_SIZE);
                wdata->bytes = ((nr_pages - 1) * PAGE_CACHE_SIZE) +
                                        wdata->tailsz;
index f9b5d3d6cf33461081f4945d61a5d604fe2ef468..1c576e8713669534be76853aa6c45e97482def96 100644 (file)
@@ -86,14 +86,17 @@ cifs_readdir_lookup(struct dentry *parent, struct qstr *name,
 
        dentry = d_lookup(parent, name);
        if (dentry) {
+               int err;
                inode = dentry->d_inode;
                /* update inode in place if i_ino didn't change */
                if (inode && CIFS_I(inode)->uniqueid == fattr->cf_uniqueid) {
                        cifs_fattr_to_inode(inode, fattr);
                        return dentry;
                }
-               d_drop(dentry);
+               err = d_invalidate(dentry);
                dput(dentry);
+               if (err)
+                       return NULL;
        }
 
        dentry = d_alloc(parent, name);
index 56cc4be87807ae2c734b647c5c78d5480d234e7b..34cea27983335fbf9dea43697cc8663ecf5aa091 100644 (file)
@@ -766,7 +766,6 @@ smb_set_file_info(struct inode *inode, const char *full_path,
        struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
        struct tcon_link *tlink = NULL;
        struct cifs_tcon *tcon;
-       FILE_BASIC_INFO info_buf;
 
        /* if the file is already open for write, just use that fileid */
        open_file = find_writable_file(cinode, true);
@@ -817,7 +816,7 @@ smb_set_file_info(struct inode *inode, const char *full_path,
        netpid = current->tgid;
 
 set_via_filehandle:
-       rc = CIFSSMBSetFileInfo(xid, tcon, &info_buf, netfid, netpid);
+       rc = CIFSSMBSetFileInfo(xid, tcon, buf, netfid, netpid);
        if (!rc)
                cinode->cifsAttrs = le32_to_cpu(buf->Attributes);
 
index f86c720dba0eeea72d7ecefdefa8ad0b52886011..cf5b44b10c6759454e662dcf0a99f3511f374a3c 100644 (file)
@@ -540,6 +540,7 @@ static int get_more_blocks(struct dio *dio, struct dio_submit *sdio,
        sector_t fs_endblk;     /* Into file, in filesystem-sized blocks */
        unsigned long fs_count; /* Number of filesystem-sized blocks */
        int create;
+       unsigned int i_blkbits = sdio->blkbits + sdio->blkfactor;
 
        /*
         * If there was a memory error and we've overwritten all the
@@ -554,7 +555,7 @@ static int get_more_blocks(struct dio *dio, struct dio_submit *sdio,
                fs_count = fs_endblk - fs_startblk + 1;
 
                map_bh->b_state = 0;
-               map_bh->b_size = fs_count << dio->inode->i_blkbits;
+               map_bh->b_size = fs_count << i_blkbits;
 
                /*
                 * For writes inside i_size on a DIO_SKIP_HOLES filesystem we
@@ -1053,7 +1054,8 @@ do_blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode,
        int seg;
        size_t size;
        unsigned long addr;
-       unsigned blkbits = inode->i_blkbits;
+       unsigned i_blkbits = ACCESS_ONCE(inode->i_blkbits);
+       unsigned blkbits = i_blkbits;
        unsigned blocksize_mask = (1 << blkbits) - 1;
        ssize_t retval = -EINVAL;
        loff_t end = offset;
@@ -1149,7 +1151,7 @@ do_blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode,
        dio->inode = inode;
        dio->rw = rw;
        sdio.blkbits = blkbits;
-       sdio.blkfactor = inode->i_blkbits - blkbits;
+       sdio.blkfactor = i_blkbits - blkbits;
        sdio.block_in_file = offset >> blkbits;
 
        sdio.get_block = get_block;
index 7320a66e958f8d45e796c796ee150b786c3f7f8e..22548f56197b52cf06b343285b7e7beb7d74cb10 100644 (file)
@@ -2101,8 +2101,9 @@ int ext3_trim_fs(struct super_block *sb, struct fstrim_range *range)
        end = start + (range->len >> sb->s_blocksize_bits) - 1;
        minlen = range->minlen >> sb->s_blocksize_bits;
 
-       if (unlikely(minlen > EXT3_BLOCKS_PER_GROUP(sb)) ||
-           unlikely(start >= max_blks))
+       if (minlen > EXT3_BLOCKS_PER_GROUP(sb) ||
+           start >= max_blks ||
+           range->len < sb->s_blocksize)
                return -EINVAL;
        if (end >= max_blks)
                end = max_blks - 1;
index 708d997a77485989d53583084a3e1b99354fb407..eff23162485f93176255199b3ed74176534ae489 100644 (file)
--- a/fs/file.c
+++ b/fs/file.c
@@ -685,7 +685,6 @@ void do_close_on_exec(struct files_struct *files)
        struct fdtable *fdt;
 
        /* exec unshares first */
-       BUG_ON(atomic_read(&files->count) != 1);
        spin_lock(&files->file_lock);
        for (i = 0; ; i++) {
                unsigned long set;
@@ -995,16 +994,18 @@ int iterate_fd(struct files_struct *files, unsigned n,
                const void *p)
 {
        struct fdtable *fdt;
-       struct file *file;
        int res = 0;
        if (!files)
                return 0;
        spin_lock(&files->file_lock);
-       fdt = files_fdtable(files);
-       while (!res && n < fdt->max_fds) {
-               file = rcu_dereference_check_fdtable(files, fdt->fd[n++]);
-               if (file)
-                       res = f(p, file, n);
+       for (fdt = files_fdtable(files); n < fdt->max_fds; n++) {
+               struct file *file;
+               file = rcu_dereference_check_fdtable(files, fdt->fd[n]);
+               if (!file)
+                       continue;
+               res = f(p, file, n);
+               if (res)
+                       break;
        }
        spin_unlock(&files->file_lock);
        return res;
index 51ea267d444c4d7aef1259521aa1f06154f26d13..3e3422f7f0a4b4c46080cf798c4185af0642e05d 100644 (file)
@@ -228,6 +228,8 @@ static void requeue_io(struct inode *inode, struct bdi_writeback *wb)
 static void inode_sync_complete(struct inode *inode)
 {
        inode->i_state &= ~I_SYNC;
+       /* If inode is clean an unused, put it into LRU now... */
+       inode_add_lru(inode);
        /* Waiters must see I_SYNC cleared before being woken up */
        smp_mb();
        wake_up_bit(&inode->i_state, __I_SYNC);
index b03c7195724685e74cba0275adaa718755eb5455..64999f144153d7740018203f884c24eb2a829f54 100644 (file)
@@ -408,6 +408,19 @@ static void inode_lru_list_add(struct inode *inode)
        spin_unlock(&inode->i_sb->s_inode_lru_lock);
 }
 
+/*
+ * Add inode to LRU if needed (inode is unused and clean).
+ *
+ * Needs inode->i_lock held.
+ */
+void inode_add_lru(struct inode *inode)
+{
+       if (!(inode->i_state & (I_DIRTY | I_SYNC | I_FREEING | I_WILL_FREE)) &&
+           !atomic_read(&inode->i_count) && inode->i_sb->s_flags & MS_ACTIVE)
+               inode_lru_list_add(inode);
+}
+
+
 static void inode_lru_list_del(struct inode *inode)
 {
        spin_lock(&inode->i_sb->s_inode_lru_lock);
@@ -1390,8 +1403,7 @@ static void iput_final(struct inode *inode)
 
        if (!drop && (sb->s_flags & MS_ACTIVE)) {
                inode->i_state |= I_REFERENCED;
-               if (!(inode->i_state & (I_DIRTY|I_SYNC)))
-                       inode_lru_list_add(inode);
+               inode_add_lru(inode);
                spin_unlock(&inode->i_lock);
                return;
        }
index 916b7cbf3e3e4fae7bc831c66373b5d5ea7a3c4a..2f6af7f645ebc3d8862da4edb1d71bc811c8d788 100644 (file)
@@ -110,6 +110,7 @@ extern int open_check_o_direct(struct file *f);
  * inode.c
  */
 extern spinlock_t inode_sb_list_lock;
+extern void inode_add_lru(struct inode *inode);
 
 /*
  * fs-writeback.c
index 78b7f84241d47b6b6503df68935f790bccd58ee9..7f5120bf0ec29cff214cc8ccb2a23bfb02ad3419 100644 (file)
@@ -1961,7 +1961,9 @@ retry:
                        spin_unlock(&journal->j_list_lock);
                        jbd_unlock_bh_state(bh);
                        spin_unlock(&journal->j_state_lock);
+                       unlock_buffer(bh);
                        log_wait_commit(journal, tid);
+                       lock_buffer(bh);
                        goto retry;
                }
                /*
index 60ef3fb707ffbfc6a77f1257efc82544cf0f9489..1506673c087e11ae820245baadc8ae74cb9f01b2 100644 (file)
@@ -138,33 +138,39 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping,
        struct page *pg;
        struct inode *inode = mapping->host;
        struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
+       struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
+       struct jffs2_raw_inode ri;
+       uint32_t alloc_len = 0;
        pgoff_t index = pos >> PAGE_CACHE_SHIFT;
        uint32_t pageofs = index << PAGE_CACHE_SHIFT;
        int ret = 0;
 
+       jffs2_dbg(1, "%s()\n", __func__);
+
+       if (pageofs > inode->i_size) {
+               ret = jffs2_reserve_space(c, sizeof(ri), &alloc_len,
+                                         ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE);
+               if (ret)
+                       return ret;
+       }
+
+       mutex_lock(&f->sem);
        pg = grab_cache_page_write_begin(mapping, index, flags);
-       if (!pg)
+       if (!pg) {
+               if (alloc_len)
+                       jffs2_complete_reservation(c);
+               mutex_unlock(&f->sem);
                return -ENOMEM;
+       }
        *pagep = pg;
 
-       jffs2_dbg(1, "%s()\n", __func__);
-
-       if (pageofs > inode->i_size) {
+       if (alloc_len) {
                /* Make new hole frag from old EOF to new page */
-               struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
-               struct jffs2_raw_inode ri;
                struct jffs2_full_dnode *fn;
-               uint32_t alloc_len;
 
                jffs2_dbg(1, "Writing new hole frag 0x%x-0x%x between current EOF and new page\n",
                          (unsigned int)inode->i_size, pageofs);
 
-               ret = jffs2_reserve_space(c, sizeof(ri), &alloc_len,
-                                         ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE);
-               if (ret)
-                       goto out_page;
-
-               mutex_lock(&f->sem);
                memset(&ri, 0, sizeof(ri));
 
                ri.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
@@ -191,7 +197,6 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping,
                if (IS_ERR(fn)) {
                        ret = PTR_ERR(fn);
                        jffs2_complete_reservation(c);
-                       mutex_unlock(&f->sem);
                        goto out_page;
                }
                ret = jffs2_add_full_dnode_to_inode(c, f, fn);
@@ -206,12 +211,10 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping,
                        jffs2_mark_node_obsolete(c, fn->raw);
                        jffs2_free_full_dnode(fn);
                        jffs2_complete_reservation(c);
-                       mutex_unlock(&f->sem);
                        goto out_page;
                }
                jffs2_complete_reservation(c);
                inode->i_size = pageofs;
-               mutex_unlock(&f->sem);
        }
 
        /*
@@ -220,18 +223,18 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping,
         * case of a short-copy.
         */
        if (!PageUptodate(pg)) {
-               mutex_lock(&f->sem);
                ret = jffs2_do_readpage_nolock(inode, pg);
-               mutex_unlock(&f->sem);
                if (ret)
                        goto out_page;
        }
+       mutex_unlock(&f->sem);
        jffs2_dbg(1, "end write_begin(). pg->flags %lx\n", pg->flags);
        return ret;
 
 out_page:
        unlock_page(pg);
        page_cache_release(pg);
+       mutex_unlock(&f->sem);
        return ret;
 }
 
index 937f9d50c84bdead7516057fead3d5a702ead4b9..5f4cdf3ad913fec928835d87fbe499efdf7d67e5 100644 (file)
@@ -2131,6 +2131,11 @@ struct dentry *lookup_one_len(const char *name, struct dentry *base, int len)
        if (!len)
                return ERR_PTR(-EACCES);
 
+       if (unlikely(name[0] == '.')) {
+               if (len < 2 || (len == 2 && name[1] == '.'))
+                       return ERR_PTR(-EACCES);
+       }
+
        while (len--) {
                c = *(const unsigned char *)name++;
                if (c == '/' || c == '\0')
index ce8cb926526bfad79aabe5b8448f80212e1670f9..b9e66b7e0c1495ba05c1fb6a4b2f1557ca6a9b24 100644 (file)
@@ -450,7 +450,8 @@ void nfs_prime_dcache(struct dentry *parent, struct nfs_entry *entry)
                        nfs_refresh_inode(dentry->d_inode, entry->fattr);
                        goto out;
                } else {
-                       d_drop(dentry);
+                       if (d_invalidate(dentry) != 0)
+                               goto out;
                        dput(dentry);
                }
        }
@@ -1100,6 +1101,8 @@ out_set_verifier:
 out_zap_parent:
        nfs_zap_caches(dir);
  out_bad:
+       nfs_free_fattr(fattr);
+       nfs_free_fhandle(fhandle);
        nfs_mark_for_revalidate(dir);
        if (inode && S_ISDIR(inode->i_mode)) {
                /* Purge readdir caches. */
@@ -1112,8 +1115,6 @@ out_zap_parent:
                shrink_dcache_parent(dentry);
        }
        d_drop(dentry);
-       nfs_free_fattr(fattr);
-       nfs_free_fhandle(fhandle);
        dput(parent);
        dfprintk(LOOKUPCACHE, "NFS: %s(%s/%s) is invalid\n",
                        __func__, dentry->d_parent->d_name.name,
index 721d692fa8d4a20dd5bf593d3f732d8b3f913261..6fcaeb8c902e4c3bc862c6c81db0a884068274b7 100644 (file)
@@ -258,7 +258,8 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group,
        if (ret)
                goto out_close_fd;
 
-       fd_install(fd, f);
+       if (fd != FAN_NOFD)
+               fd_install(fd, f);
        return fanotify_event_metadata.event_len;
 
 out_close_fd:
index 3c231adf845088ee51517c1f7fd0745284d88be2..9e28356a959a2f4f0aecddd6170ebacfa799a5b3 100644 (file)
@@ -1877,8 +1877,9 @@ static struct dentry *proc_map_files_lookup(struct inode *dir,
        if (!vma)
                goto out_no_vma;
 
-       result = proc_map_files_instantiate(dir, dentry, task,
-                       (void *)(unsigned long)vma->vm_file->f_mode);
+       if (vma->vm_file)
+               result = proc_map_files_instantiate(dir, dentry, task,
+                               (void *)(unsigned long)vma->vm_file->f_mode);
 
 out_no_vma:
        up_read(&mm->mmap_sem);
index f27f01a98aa2c9573c6cc61fe093c821ce6e107c..d83736fbc26cb4679cf074ee33263f125f13afa7 100644 (file)
@@ -1782,8 +1782,9 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th,
 
        BUG_ON(!th->t_trans_id);
 
-       dquot_initialize(inode);
+       reiserfs_write_unlock(inode->i_sb);
        err = dquot_alloc_inode(inode);
+       reiserfs_write_lock(inode->i_sb);
        if (err)
                goto out_end_trans;
        if (!dir->i_nlink) {
@@ -1979,8 +1980,10 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th,
 
       out_end_trans:
        journal_end(th, th->t_super, th->t_blocks_allocated);
+       reiserfs_write_unlock(inode->i_sb);
        /* Drop can be outside and it needs more credits so it's better to have it outside */
        dquot_drop(inode);
+       reiserfs_write_lock(inode->i_sb);
        inode->i_flags |= S_NOQUOTA;
        make_bad_inode(inode);
 
@@ -3103,10 +3106,9 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr)
        /* must be turned off for recursive notify_change calls */
        ia_valid = attr->ia_valid &= ~(ATTR_KILL_SUID|ATTR_KILL_SGID);
 
-       depth = reiserfs_write_lock_once(inode->i_sb);
        if (is_quota_modification(inode, attr))
                dquot_initialize(inode);
-
+       depth = reiserfs_write_lock_once(inode->i_sb);
        if (attr->ia_valid & ATTR_SIZE) {
                /* version 2 items will be caught by the s_maxbytes check
                 ** done for us in vmtruncate
@@ -3170,7 +3172,9 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr)
                error = journal_begin(&th, inode->i_sb, jbegin_count);
                if (error)
                        goto out;
+               reiserfs_write_unlock_once(inode->i_sb, depth);
                error = dquot_transfer(inode, attr);
+               depth = reiserfs_write_lock_once(inode->i_sb);
                if (error) {
                        journal_end(&th, inode->i_sb, jbegin_count);
                        goto out;
index f8afa4b162b8f026da18b1cf2364e7d1cd6f5116..2f40a4c70a4d9667ca34e00ef2b31888255276c2 100644 (file)
@@ -1968,7 +1968,9 @@ int reiserfs_paste_into_item(struct reiserfs_transaction_handle *th, struct tree
                       key2type(&(key->on_disk_key)));
 #endif
 
+       reiserfs_write_unlock(inode->i_sb);
        retval = dquot_alloc_space_nodirty(inode, pasted_size);
+       reiserfs_write_lock(inode->i_sb);
        if (retval) {
                pathrelse(search_path);
                return retval;
@@ -2061,9 +2063,11 @@ int reiserfs_insert_item(struct reiserfs_transaction_handle *th,
                               "reiserquota insert_item(): allocating %u id=%u type=%c",
                               quota_bytes, inode->i_uid, head2type(ih));
 #endif
+               reiserfs_write_unlock(inode->i_sb);
                /* We can't dirty inode here. It would be immediately written but
                 * appropriate stat item isn't inserted yet... */
                retval = dquot_alloc_space_nodirty(inode, quota_bytes);
+               reiserfs_write_lock(inode->i_sb);
                if (retval) {
                        pathrelse(path);
                        return retval;
index 1078ae179993bb12f105d39fb1d847eb84c12414..418bdc3a57da4e11092477fa1b3cbf2e37f71422 100644 (file)
@@ -298,7 +298,9 @@ static int finish_unfinished(struct super_block *s)
                        retval = remove_save_link_only(s, &save_link_key, 0);
                        continue;
                }
+               reiserfs_write_unlock(s);
                dquot_initialize(inode);
+               reiserfs_write_lock(s);
 
                if (truncate && S_ISDIR(inode->i_mode)) {
                        /* We got a truncate request for a dir which is impossible.
@@ -1335,7 +1337,7 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg)
                                kfree(qf_names[i]);
 #endif
                err = -EINVAL;
-               goto out_err;
+               goto out_unlock;
        }
 #ifdef CONFIG_QUOTA
        handle_quota_files(s, qf_names, &qfmt);
@@ -1379,7 +1381,7 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg)
        if (blocks) {
                err = reiserfs_resize(s, blocks);
                if (err != 0)
-                       goto out_err;
+                       goto out_unlock;
        }
 
        if (*mount_flags & MS_RDONLY) {
@@ -1389,9 +1391,15 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg)
                        /* it is read-only already */
                        goto out_ok;
 
+               /*
+                * Drop write lock. Quota will retake it when needed and lock
+                * ordering requires calling dquot_suspend() without it.
+                */
+               reiserfs_write_unlock(s);
                err = dquot_suspend(s, -1);
                if (err < 0)
                        goto out_err;
+               reiserfs_write_lock(s);
 
                /* try to remount file system with read-only permissions */
                if (sb_umount_state(rs) == REISERFS_VALID_FS
@@ -1401,7 +1409,7 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg)
 
                err = journal_begin(&th, s, 10);
                if (err)
-                       goto out_err;
+                       goto out_unlock;
 
                /* Mounting a rw partition read-only. */
                reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1);
@@ -1416,7 +1424,7 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg)
 
                if (reiserfs_is_journal_aborted(journal)) {
                        err = journal->j_errno;
-                       goto out_err;
+                       goto out_unlock;
                }
 
                handle_data_mode(s, mount_options);
@@ -1425,7 +1433,7 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg)
                s->s_flags &= ~MS_RDONLY;       /* now it is safe to call journal_begin */
                err = journal_begin(&th, s, 10);
                if (err)
-                       goto out_err;
+                       goto out_unlock;
 
                /* Mount a partition which is read-only, read-write */
                reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1);
@@ -1442,10 +1450,16 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg)
        SB_JOURNAL(s)->j_must_wait = 1;
        err = journal_end(&th, s, 10);
        if (err)
-               goto out_err;
+               goto out_unlock;
 
        if (!(*mount_flags & MS_RDONLY)) {
+               /*
+                * Drop write lock. Quota will retake it when needed and lock
+                * ordering requires calling dquot_resume() without it.
+                */
+               reiserfs_write_unlock(s);
                dquot_resume(s, -1);
+               reiserfs_write_lock(s);
                finish_unfinished(s);
                reiserfs_xattr_init(s, *mount_flags);
        }
@@ -1455,9 +1469,10 @@ out_ok:
        reiserfs_write_unlock(s);
        return 0;
 
+out_unlock:
+       reiserfs_write_unlock(s);
 out_err:
        kfree(new_opts);
-       reiserfs_write_unlock(s);
        return err;
 }
 
@@ -2095,13 +2110,15 @@ static int reiserfs_write_dquot(struct dquot *dquot)
                          REISERFS_QUOTA_TRANS_BLOCKS(dquot->dq_sb));
        if (ret)
                goto out;
+       reiserfs_write_unlock(dquot->dq_sb);
        ret = dquot_commit(dquot);
+       reiserfs_write_lock(dquot->dq_sb);
        err =
            journal_end(&th, dquot->dq_sb,
                        REISERFS_QUOTA_TRANS_BLOCKS(dquot->dq_sb));
        if (!ret && err)
                ret = err;
-      out:
+out:
        reiserfs_write_unlock(dquot->dq_sb);
        return ret;
 }
@@ -2117,13 +2134,15 @@ static int reiserfs_acquire_dquot(struct dquot *dquot)
                          REISERFS_QUOTA_INIT_BLOCKS(dquot->dq_sb));
        if (ret)
                goto out;
+       reiserfs_write_unlock(dquot->dq_sb);
        ret = dquot_acquire(dquot);
+       reiserfs_write_lock(dquot->dq_sb);
        err =
            journal_end(&th, dquot->dq_sb,
                        REISERFS_QUOTA_INIT_BLOCKS(dquot->dq_sb));
        if (!ret && err)
                ret = err;
-      out:
+out:
        reiserfs_write_unlock(dquot->dq_sb);
        return ret;
 }
@@ -2137,19 +2156,21 @@ static int reiserfs_release_dquot(struct dquot *dquot)
        ret =
            journal_begin(&th, dquot->dq_sb,
                          REISERFS_QUOTA_DEL_BLOCKS(dquot->dq_sb));
+       reiserfs_write_unlock(dquot->dq_sb);
        if (ret) {
                /* Release dquot anyway to avoid endless cycle in dqput() */
                dquot_release(dquot);
                goto out;
        }
        ret = dquot_release(dquot);
+       reiserfs_write_lock(dquot->dq_sb);
        err =
            journal_end(&th, dquot->dq_sb,
                        REISERFS_QUOTA_DEL_BLOCKS(dquot->dq_sb));
        if (!ret && err)
                ret = err;
-      out:
        reiserfs_write_unlock(dquot->dq_sb);
+out:
        return ret;
 }
 
@@ -2174,11 +2195,13 @@ static int reiserfs_write_info(struct super_block *sb, int type)
        ret = journal_begin(&th, sb, 2);
        if (ret)
                goto out;
+       reiserfs_write_unlock(sb);
        ret = dquot_commit_info(sb, type);
+       reiserfs_write_lock(sb);
        err = journal_end(&th, sb, 2);
        if (!ret && err)
                ret = err;
-      out:
+out:
        reiserfs_write_unlock(sb);
        return ret;
 }
@@ -2203,8 +2226,11 @@ static int reiserfs_quota_on(struct super_block *sb, int type, int format_id,
        struct reiserfs_transaction_handle th;
        int opt = type == USRQUOTA ? REISERFS_USRQUOTA : REISERFS_GRPQUOTA;
 
-       if (!(REISERFS_SB(sb)->s_mount_opt & (1 << opt)))
-               return -EINVAL;
+       reiserfs_write_lock(sb);
+       if (!(REISERFS_SB(sb)->s_mount_opt & (1 << opt))) {
+               err = -EINVAL;
+               goto out;
+       }
 
        /* Quotafile not on the same filesystem? */
        if (path->dentry->d_sb != sb) {
@@ -2246,8 +2272,10 @@ static int reiserfs_quota_on(struct super_block *sb, int type, int format_id,
                if (err)
                        goto out;
        }
-       err = dquot_quota_on(sb, type, format_id, path);
+       reiserfs_write_unlock(sb);
+       return dquot_quota_on(sb, type, format_id, path);
 out:
+       reiserfs_write_unlock(sb);
        return err;
 }
 
@@ -2320,7 +2348,9 @@ static ssize_t reiserfs_quota_write(struct super_block *sb, int type,
                tocopy = sb->s_blocksize - offset < towrite ?
                    sb->s_blocksize - offset : towrite;
                tmp_bh.b_state = 0;
+               reiserfs_write_lock(sb);
                err = reiserfs_get_block(inode, blk, &tmp_bh, GET_BLOCK_CREATE);
+               reiserfs_write_unlock(sb);
                if (err)
                        goto out;
                if (offset || tocopy != sb->s_blocksize)
@@ -2336,10 +2366,12 @@ static ssize_t reiserfs_quota_write(struct super_block *sb, int type,
                flush_dcache_page(bh->b_page);
                set_buffer_uptodate(bh);
                unlock_buffer(bh);
+               reiserfs_write_lock(sb);
                reiserfs_prepare_for_journal(sb, bh, 1);
                journal_mark_dirty(current->journal_info, sb, bh);
                if (!journal_quota)
                        reiserfs_add_ordered_list(inode, bh);
+               reiserfs_write_unlock(sb);
                brelse(bh);
                offset = 0;
                towrite -= tocopy;
index e562dd43f41fe762eb4d49c7814f1f002fe965c9..e57e2daa357c34fc9634871a1d41dd76569cf871 100644 (file)
@@ -481,11 +481,17 @@ static inline int bio_add_buffer(struct bio *bio, struct buffer_head *bh)
  *
  * The fix is two passes across the ioend list - one to start writeback on the
  * buffer_heads, and then submit them for I/O on the second pass.
+ *
+ * If @fail is non-zero, it means that we have a situation where some part of
+ * the submission process has failed after we have marked paged for writeback
+ * and unlocked them. In this situation, we need to fail the ioend chain rather
+ * than submit it to IO. This typically only happens on a filesystem shutdown.
  */
 STATIC void
 xfs_submit_ioend(
        struct writeback_control *wbc,
-       xfs_ioend_t             *ioend)
+       xfs_ioend_t             *ioend,
+       int                     fail)
 {
        xfs_ioend_t             *head = ioend;
        xfs_ioend_t             *next;
@@ -506,6 +512,18 @@ xfs_submit_ioend(
                next = ioend->io_list;
                bio = NULL;
 
+               /*
+                * If we are failing the IO now, just mark the ioend with an
+                * error and finish it. This will run IO completion immediately
+                * as there is only one reference to the ioend at this point in
+                * time.
+                */
+               if (fail) {
+                       ioend->io_error = -fail;
+                       xfs_finish_ioend(ioend);
+                       continue;
+               }
+
                for (bh = ioend->io_buffer_head; bh; bh = bh->b_private) {
 
                        if (!bio) {
@@ -1060,7 +1078,18 @@ xfs_vm_writepage(
 
        xfs_start_page_writeback(page, 1, count);
 
-       if (ioend && imap_valid) {
+       /* if there is no IO to be submitted for this page, we are done */
+       if (!ioend)
+               return 0;
+
+       ASSERT(iohead);
+
+       /*
+        * Any errors from this point onwards need tobe reported through the IO
+        * completion path as we have marked the initial page as under writeback
+        * and unlocked it.
+        */
+       if (imap_valid) {
                xfs_off_t               end_index;
 
                end_index = imap.br_startoff + imap.br_blockcount;
@@ -1079,20 +1108,15 @@ xfs_vm_writepage(
                                  wbc, end_index);
        }
 
-       if (iohead) {
-               /*
-                * Reserve log space if we might write beyond the on-disk
-                * inode size.
-                */
-               if (ioend->io_type != XFS_IO_UNWRITTEN &&
-                   xfs_ioend_is_append(ioend)) {
-                       err = xfs_setfilesize_trans_alloc(ioend);
-                       if (err)
-                               goto error;
-               }
 
-               xfs_submit_ioend(wbc, iohead);
-       }
+       /*
+        * Reserve log space if we might write beyond the on-disk inode size.
+        */
+       err = 0;
+       if (ioend->io_type != XFS_IO_UNWRITTEN && xfs_ioend_is_append(ioend))
+               err = xfs_setfilesize_trans_alloc(ioend);
+
+       xfs_submit_ioend(wbc, iohead, err);
 
        return 0;
 
index d330111ca738eef9ff86b5fd28723c0b63a9b379..70eec1829776309b3cba83e9a660aa6de5ad9693 100644 (file)
@@ -1291,6 +1291,7 @@ xfs_attr_leaf_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1,
        leaf2 = blk2->bp->b_addr;
        ASSERT(leaf1->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC));
        ASSERT(leaf2->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC));
+       ASSERT(leaf2->hdr.count == 0);
        args = state->args;
 
        trace_xfs_attr_leaf_rebalance(args);
@@ -1361,6 +1362,7 @@ xfs_attr_leaf_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1,
                 * I assert that since all callers pass in an empty
                 * second buffer, this code should never execute.
                 */
+               ASSERT(0);
 
                /*
                 * Figure the total bytes to be added to the destination leaf.
@@ -1422,10 +1424,24 @@ xfs_attr_leaf_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1,
                        args->index2 = 0;
                        args->blkno2 = blk2->blkno;
                } else {
+                       /*
+                        * On a double leaf split, the original attr location
+                        * is already stored in blkno2/index2, so don't
+                        * overwrite it overwise we corrupt the tree.
+                        */
                        blk2->index = blk1->index
                                    - be16_to_cpu(leaf1->hdr.count);
-                       args->index = args->index2 = blk2->index;
-                       args->blkno = args->blkno2 = blk2->blkno;
+                       args->index = blk2->index;
+                       args->blkno = blk2->blkno;
+                       if (!state->extravalid) {
+                               /*
+                                * set the new attr location to match the old
+                                * one and let the higher level split code
+                                * decide where in the leaf to place it.
+                                */
+                               args->index2 = blk2->index;
+                               args->blkno2 = blk2->blkno;
+                       }
                }
        } else {
                ASSERT(state->inleaf == 1);
index 933b7930b8636da970a627d571388b11e8dabde7..4b0b8dd1b7b0ea2bbc431ef523ec5412eb4fd584 100644 (file)
@@ -1197,9 +1197,14 @@ xfs_buf_bio_end_io(
 {
        xfs_buf_t               *bp = (xfs_buf_t *)bio->bi_private;
 
-       xfs_buf_ioerror(bp, -error);
+       /*
+        * don't overwrite existing errors - otherwise we can lose errors on
+        * buffers that require multiple bios to complete.
+        */
+       if (!bp->b_error)
+               xfs_buf_ioerror(bp, -error);
 
-       if (!error && xfs_buf_is_vmapped(bp) && (bp->b_flags & XBF_READ))
+       if (!bp->b_error && xfs_buf_is_vmapped(bp) && (bp->b_flags & XBF_READ))
                invalidate_kernel_vmap_range(bp->b_addr, xfs_buf_vmap_len(bp));
 
        _xfs_buf_ioend(bp, 1);
@@ -1279,6 +1284,11 @@ next_chunk:
                if (size)
                        goto next_chunk;
        } else {
+               /*
+                * This is guaranteed not to be the last io reference count
+                * because the caller (xfs_buf_iorequest) holds a count itself.
+                */
+               atomic_dec(&bp->b_io_remaining);
                xfs_buf_ioerror(bp, EIO);
                bio_put(bio);
        }
index af1cbaf535edeb395954583d1d1c1cd0c255c64c..c5c35e629426b506d2e7d00fe876f2e528a48f80 100644 (file)
        {0x1002, 0x6798, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x6799, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x679A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI|RADEON_NEW_MEMMAP}, \
+       {0x1002, 0x679B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x679E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x679F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x6800, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
index aaac4bba6f5c7faa1d2b95b13983323658c8188c..b1cf40de847e42e0b1555252949a34a5f3a6e54a 100644 (file)
@@ -15,6 +15,7 @@ struct pt_regs;
 #define BUILD_BUG_ON_NOT_POWER_OF_2(n)
 #define BUILD_BUG_ON_ZERO(e) (0)
 #define BUILD_BUG_ON_NULL(e) ((void*)0)
+#define BUILD_BUG_ON_INVALID(e) (0)
 #define BUILD_BUG_ON(condition)
 #define BUILD_BUG() (0)
 #else /* __CHECKER__ */
index 171ad8aedc835258e152b94b2bc92242045d9c3e..fc0e34ce038f4055eaf7160cb1eb7693b7cc7e5d 100644 (file)
@@ -39,6 +39,8 @@ extern void debug_dma_map_page(struct device *dev, struct page *page,
                               int direction, dma_addr_t dma_addr,
                               bool map_single);
 
+extern void debug_dma_mapping_error(struct device *dev, dma_addr_t dma_addr);
+
 extern void debug_dma_unmap_page(struct device *dev, dma_addr_t addr,
                                 size_t size, int direction, bool map_single);
 
@@ -105,6 +107,11 @@ static inline void debug_dma_map_page(struct device *dev, struct page *page,
 {
 }
 
+static inline void debug_dma_mapping_error(struct device *dev,
+                                         dma_addr_t dma_addr)
+{
+}
+
 static inline void debug_dma_unmap_page(struct device *dev, dma_addr_t addr,
                                        size_t size, int direction,
                                        bool map_single)
index b33cfc97b9caef81de7e525c44e23c4db6a5ba18..75fe9a1348036c52b863fb47737eb6b0f9dd8789 100644 (file)
@@ -462,8 +462,6 @@ struct block_device {
        int                     bd_fsfreeze_count;
        /* Mutex for freeze */
        struct mutex            bd_fsfreeze_mutex;
-       /* A semaphore that prevents I/O while block size is being changed */
-       struct percpu_rw_semaphore      bd_block_size_semaphore;
 };
 
 /*
@@ -2049,7 +2047,6 @@ extern void unregister_blkdev(unsigned int, const char *);
 extern struct block_device *bdget(dev_t);
 extern struct block_device *bdgrab(struct block_device *bdev);
 extern void bd_set_size(struct block_device *, loff_t size);
-extern sector_t blkdev_max_block(struct block_device *bdev);
 extern void bd_forget(struct inode *inode);
 extern void bdput(struct block_device *);
 extern void invalidate_bdev(struct block_device *);
@@ -2379,8 +2376,6 @@ extern int generic_segment_checks(const struct iovec *iov,
                unsigned long *nr_segs, size_t *count, int access_flags);
 
 /* fs/block_dev.c */
-extern ssize_t blkdev_aio_read(struct kiocb *iocb, const struct iovec *iov,
-                              unsigned long nr_segs, loff_t pos);
 extern ssize_t blkdev_aio_write(struct kiocb *iocb, const struct iovec *iov,
                                unsigned long nr_segs, loff_t pos);
 extern int blkdev_fsync(struct file *filp, loff_t start, loff_t end,
index 02c1c9710be0e5fea029fd4462fe57793154216e..d0a79678f169f8c9a7675e4343419975cbb29142 100644 (file)
@@ -31,6 +31,7 @@ struct vm_area_struct;
 #define ___GFP_THISNODE                0x40000u
 #define ___GFP_RECLAIMABLE     0x80000u
 #define ___GFP_NOTRACK         0x200000u
+#define ___GFP_NO_KSWAPD       0x400000u
 #define ___GFP_OTHER_NODE      0x800000u
 #define ___GFP_WRITE           0x1000000u
 
@@ -85,6 +86,7 @@ struct vm_area_struct;
 #define __GFP_RECLAIMABLE ((__force gfp_t)___GFP_RECLAIMABLE) /* Page is reclaimable */
 #define __GFP_NOTRACK  ((__force gfp_t)___GFP_NOTRACK)  /* Don't track with kmemcheck */
 
+#define __GFP_NO_KSWAPD        ((__force gfp_t)___GFP_NO_KSWAPD)
 #define __GFP_OTHER_NODE ((__force gfp_t)___GFP_OTHER_NODE) /* On behalf of other node */
 #define __GFP_WRITE    ((__force gfp_t)___GFP_WRITE)   /* Allocator intends to dirty page */
 
@@ -114,7 +116,8 @@ struct vm_area_struct;
                                 __GFP_MOVABLE)
 #define GFP_IOFS       (__GFP_IO | __GFP_FS)
 #define GFP_TRANSHUGE  (GFP_HIGHUSER_MOVABLE | __GFP_COMP | \
-                        __GFP_NOMEMALLOC | __GFP_NORETRY | __GFP_NOWARN)
+                        __GFP_NOMEMALLOC | __GFP_NORETRY | __GFP_NOWARN | \
+                        __GFP_NO_KSWAPD)
 
 #ifdef CONFIG_NUMA
 #define GFP_THISNODE   (__GFP_THISNODE | __GFP_NOWARN | __GFP_NORETRY)
index 6ae9c631a1be51c7221321a9a2ceb787217e4ff0..0464c85e63fd05d1fc10f0f03eeac56fe03f3e8e 100644 (file)
@@ -1,35 +1,8 @@
 #ifndef _LINUX_HW_BREAKPOINT_H
 #define _LINUX_HW_BREAKPOINT_H
 
-enum {
-       HW_BREAKPOINT_LEN_1 = 1,
-       HW_BREAKPOINT_LEN_2 = 2,
-       HW_BREAKPOINT_LEN_4 = 4,
-       HW_BREAKPOINT_LEN_8 = 8,
-};
-
-enum {
-       HW_BREAKPOINT_EMPTY     = 0,
-       HW_BREAKPOINT_R         = 1,
-       HW_BREAKPOINT_W         = 2,
-       HW_BREAKPOINT_RW        = HW_BREAKPOINT_R | HW_BREAKPOINT_W,
-       HW_BREAKPOINT_X         = 4,
-       HW_BREAKPOINT_INVALID   = HW_BREAKPOINT_RW | HW_BREAKPOINT_X,
-};
-
-enum bp_type_idx {
-       TYPE_INST       = 0,
-#ifdef CONFIG_HAVE_MIXED_BREAKPOINTS_REGS
-       TYPE_DATA       = 0,
-#else
-       TYPE_DATA       = 1,
-#endif
-       TYPE_MAX
-};
-
-#ifdef __KERNEL__
-
 #include <linux/perf_event.h>
+#include <uapi/linux/hw_breakpoint.h>
 
 #ifdef CONFIG_HAVE_HW_BREAKPOINT
 
@@ -151,6 +124,4 @@ static inline struct arch_hw_breakpoint *counter_arch_bp(struct perf_event *bp)
 }
 
 #endif /* CONFIG_HAVE_HW_BREAKPOINT */
-#endif /* __KERNEL__ */
-
 #endif /* _LINUX_HW_BREAKPOINT_H */
index df804ba73e0b2ae97d935ba2c3797cd36b1499de..92a0dc75bc74661541e5b5c15f4cdd095c922b38 100644 (file)
@@ -34,6 +34,7 @@ struct omap_i2c_bus_platform_data {
        u32             clkrate;
        u32             rev;
        u32             flags;
+       void            (*set_mpu_wkup_lat)(struct device *dev, long set);
 };
 
 #endif
index a123b13b70fd80cb12def4c100ee198606b7c6b6..7d8dfc7392f11f020f1a4de28ff66f416c19c964 100644 (file)
@@ -701,6 +701,13 @@ static inline void ftrace_dump(enum ftrace_dump_mode oops_dump_mode) { }
 #define COMPACTION_BUILD 0
 #endif
 
+/* This helps us to avoid #ifdef CONFIG_SYMBOL_PREFIX */
+#ifdef CONFIG_SYMBOL_PREFIX
+#define SYMBOL_PREFIX CONFIG_SYMBOL_PREFIX
+#else
+#define SYMBOL_PREFIX ""
+#endif
+
 /* Rebuild everything on CONFIG_FTRACE_MCOUNT_RECORD */
 #ifdef CONFIG_FTRACE_MCOUNT_RECORD
 # define REBUILD_DUE_TO_FTRACE_MCOUNT_RECORD
index e5ccb9ddd90eeb634665e88afd13d56184fff241..dbd212723b74e3d88eb7a7e13bc241e420db84bb 100644 (file)
@@ -82,16 +82,6 @@ static inline void mpol_cond_put(struct mempolicy *pol)
                __mpol_put(pol);
 }
 
-extern struct mempolicy *__mpol_cond_copy(struct mempolicy *tompol,
-                                         struct mempolicy *frompol);
-static inline struct mempolicy *mpol_cond_copy(struct mempolicy *tompol,
-                                               struct mempolicy *frompol)
-{
-       if (!frompol)
-               return frompol;
-       return __mpol_cond_copy(tompol, frompol);
-}
-
 extern struct mempolicy *__mpol_dup(struct mempolicy *pol);
 static inline struct mempolicy *mpol_dup(struct mempolicy *pol)
 {
@@ -215,12 +205,6 @@ static inline void mpol_cond_put(struct mempolicy *pol)
 {
 }
 
-static inline struct mempolicy *mpol_cond_copy(struct mempolicy *to,
-                                               struct mempolicy *from)
-{
-       return from;
-}
-
 static inline void mpol_get(struct mempolicy *pol)
 {
 }
index f8eda0276f03fadf3be56e8e70f928f792714406..a848ffc327f4f19e3b1da926f52aa361fd27b654 100644 (file)
@@ -1488,6 +1488,9 @@ struct napi_gro_cb {
 
        /* Used in ipv6_gro_receive() */
        int     proto;
+
+       /* used in skb_gro_receive() slow path */
+       struct sk_buff *last;
 };
 
 #define NAPI_GRO_CB(skb) ((struct napi_gro_cb *)(skb)->cb)
index e20e3af68fb6acbaf6a51c5aec465bb753a54968..0506eb53519b635286be2b2c54b8a4c7e524a3d7 100644 (file)
@@ -42,10 +42,12 @@ static inline struct device_node *of_find_matching_node_by_address(
 {
        return NULL;
 }
+#ifndef of_iomap
 static inline void __iomem *of_iomap(struct device_node *device, int index)
 {
        return NULL;
 }
+#endif
 static inline const __be32 *of_get_address(struct device_node *dev, int index,
                                        u64 *size, unsigned int *flags)
 {
diff --git a/include/linux/omap-iommu.h b/include/linux/omap-iommu.h
new file mode 100644 (file)
index 0000000..cac78de
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * omap iommu: simple virtual address space management
+ *
+ * Copyright (C) 2008-2009 Nokia Corporation
+ *
+ * Written by Hiroshi DOYU <Hiroshi.DOYU@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.
+ */
+
+#ifndef _INTEL_IOMMU_H_
+#define _INTEL_IOMMU_H_
+
+struct iovm_struct {
+       struct omap_iommu       *iommu; /* iommu object which this belongs to */
+       u32                     da_start; /* area definition */
+       u32                     da_end;
+       u32                     flags; /* IOVMF_: see below */
+       struct list_head        list; /* linked in ascending order */
+       const struct sg_table   *sgt; /* keep 'page' <-> 'da' mapping */
+       void                    *va; /* mpu side mapped address */
+};
+
+#define MMU_RAM_ENDIAN_SHIFT   9
+#define MMU_RAM_ENDIAN_LITTLE  (0 << MMU_RAM_ENDIAN_SHIFT)
+#define MMU_RAM_ELSZ_8         (0 << MMU_RAM_ELSZ_SHIFT)
+#define IOVMF_ENDIAN_LITTLE    MMU_RAM_ENDIAN_LITTLE
+#define MMU_RAM_ELSZ_SHIFT     7
+#define IOVMF_ELSZ_8           MMU_RAM_ELSZ_8
+
+struct iommu_domain;
+
+extern struct iovm_struct *omap_find_iovm_area(struct device *dev, u32 da);
+extern u32
+omap_iommu_vmap(struct iommu_domain *domain, struct device *dev, u32 da,
+                       const struct sg_table *sgt, u32 flags);
+extern struct sg_table *omap_iommu_vunmap(struct iommu_domain *domain,
+                               struct device *dev, u32 da);
+extern u32
+omap_iommu_vmalloc(struct iommu_domain *domain, struct device *dev,
+                               u32 da, size_t bytes, u32 flags);
+extern void
+omap_iommu_vfree(struct iommu_domain *domain, struct device *dev,
+                               const u32 da);
+extern void *omap_da_to_va(struct device *dev, u32 da);
+
+extern void omap_iommu_save_ctx(struct device *dev);
+extern void omap_iommu_restore_ctx(struct device *dev);
+
+#endif
index 250a4acddb2b8975a6c8278a3c5b1d803f36b585..bd1e86071e57c27219b2746ab715d419c60fcc2c 100644 (file)
@@ -13,7 +13,7 @@ struct percpu_rw_semaphore {
 };
 
 #define light_mb()     barrier()
-#define heavy_mb()     synchronize_sched()
+#define heavy_mb()     synchronize_sched_expedited()
 
 static inline void percpu_down_read(struct percpu_rw_semaphore *p)
 {
@@ -51,7 +51,7 @@ static inline void percpu_down_write(struct percpu_rw_semaphore *p)
 {
        mutex_lock(&p->mtx);
        p->locked = true;
-       synchronize_sched(); /* make sure that all readers exit the rcu_read_lock_sched region */
+       synchronize_sched_expedited(); /* make sure that all readers exit the rcu_read_lock_sched region */
        while (__percpu_count(p->counters))
                msleep(1);
        heavy_mb(); /* C, between read of p->counter and write to data, paired with B */
diff --git a/include/linux/platform_data/iommu-omap.h b/include/linux/platform_data/iommu-omap.h
new file mode 100644 (file)
index 0000000..5b429c4
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * omap iommu: main structures
+ *
+ * Copyright (C) 2008-2009 Nokia Corporation
+ *
+ * Written by Hiroshi DOYU <Hiroshi.DOYU@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.
+ */
+
+#include <linux/platform_device.h>
+
+#define MMU_REG_SIZE           256
+
+/**
+ * struct iommu_arch_data - omap iommu private data
+ * @name: name of the iommu device
+ * @iommu_dev: handle of the iommu device
+ *
+ * This is an omap iommu private data object, which binds an iommu user
+ * to its iommu device. This object should be placed at the iommu user's
+ * dev_archdata so generic IOMMU API can be used without having to
+ * utilize omap-specific plumbing anymore.
+ */
+struct omap_iommu_arch_data {
+       const char *name;
+       struct omap_iommu *iommu_dev;
+};
+
+/**
+ * struct omap_mmu_dev_attr - OMAP mmu device attributes for omap_hwmod
+ * @da_start:          device address where the va space starts.
+ * @da_end:            device address where the va space ends.
+ * @nr_tlb_entries:    number of entries supported by the translation
+ *                     look-aside buffer (TLB).
+ */
+struct omap_mmu_dev_attr {
+       u32 da_start;
+       u32 da_end;
+       int nr_tlb_entries;
+};
+
+struct iommu_platform_data {
+       const char *name;
+       const char *reset_name;
+       int nr_tlb_entries;
+       u32 da_start;
+       u32 da_end;
+
+       int (*assert_reset)(struct platform_device *pdev, const char *name);
+       int (*deassert_reset)(struct platform_device *pdev, const char *name);
+};
index c64de9dd7631bb44232eeca7d8080c62521c5b1e..2f694f3846a9ad1a5d052e96d5f68cd9a152c313 100644 (file)
@@ -46,8 +46,9 @@ struct ads7846_platform_data {
        u16     debounce_rep;           /* additional consecutive good readings
                                         * required after the first two */
        int     gpio_pendown;           /* the GPIO used to decide the pendown
-                                        * state if get_pendown_state == NULL
-                                        */
+                                        * state if get_pendown_state == NULL */
+       int     gpio_pendown_debounce;  /* platform specific debounce time for
+                                        * the gpio_pendown */
        int     (*get_pendown_state)(void);
        int     (*filter_init)  (const struct ads7846_platform_data *pdata,
                                 void **filter_data);
index 171b957db74399ac1f82f2efe22a70857452156b..dc004bc926c92154729fd89b9c88a1a93d579092 100644 (file)
@@ -40,14 +40,6 @@ enum adv7604_op_ch_sel {
        ADV7604_OP_CH_SEL_RBG = 5,
 };
 
-/* Primary mode (IO register 0x01, [3:0]) */
-enum adv7604_prim_mode {
-       ADV7604_PRIM_MODE_COMP = 1,
-       ADV7604_PRIM_MODE_RGB = 2,
-       ADV7604_PRIM_MODE_HDMI_COMP = 5,
-       ADV7604_PRIM_MODE_HDMI_GR = 6,
-};
-
 /* Input Color Space (IO register 0x02, [7:4]) */
 enum adv7604_inp_color_space {
        ADV7604_INP_COLOR_SPACE_LIM_RGB = 0,
@@ -103,9 +95,6 @@ struct adv7604_platform_data {
        /* Bus rotation and reordering */
        enum adv7604_op_ch_sel op_ch_sel;
 
-       /* Primary mode */
-       enum adv7604_prim_mode prim_mode;
-
        /* Select output format */
        enum adv7604_op_format_sel op_format_sel;
 
@@ -142,6 +131,16 @@ struct adv7604_platform_data {
        u8 i2c_vdp;
 };
 
+/*
+ * Mode of operation.
+ * This is used as the input argument of the s_routing video op.
+ */
+enum adv7604_mode {
+       ADV7604_MODE_COMP,
+       ADV7604_MODE_GR,
+       ADV7604_MODE_HDMI,
+};
+
 #define V4L2_CID_ADV_RX_ANALOG_SAMPLING_PHASE  (V4L2_CID_DV_CLASS_BASE + 0x1000)
 #define V4L2_CID_ADV_RX_FREE_RUN_COLOR_MANUAL  (V4L2_CID_DV_CLASS_BASE + 0x1001)
 #define V4L2_CID_ADV_RX_FREE_RUN_COLOR         (V4L2_CID_DV_CLASS_BASE + 0x1002)
index 6feeccd83dd7557abd30e32c0547f483b79bd238..4af45e33105db2ee37b8ca66d6ec4122aa487456 100644 (file)
@@ -525,6 +525,7 @@ static inline __u32 cookie_v6_init_sequence(struct sock *sk,
 extern void __tcp_push_pending_frames(struct sock *sk, unsigned int cur_mss,
                                      int nonagle);
 extern bool tcp_may_send_now(struct sock *sk);
+extern int __tcp_retransmit_skb(struct sock *, struct sk_buff *);
 extern int tcp_retransmit_skb(struct sock *, struct sk_buff *);
 extern void tcp_retransmit_timer(struct sock *sk);
 extern void tcp_xmit_retransmit_queue(struct sock *);
index 6f0ba01afe7315d443a0aad152a9df2d5a22abf6..63445ede48bb7fd04b175c111935fb77464568b6 100644 (file)
@@ -1351,7 +1351,7 @@ struct xfrm6_tunnel {
 };
 
 extern void xfrm_init(void);
-extern void xfrm4_init(int rt_hash_size);
+extern void xfrm4_init(void);
 extern int xfrm_state_init(struct net *net);
 extern void xfrm_state_fini(struct net *net);
 extern void xfrm4_state_init(void);
index 88fae8d2015471885972da8407d0077106b527cc..55367b04dc9445e142369e98d2134d459eb5ef83 100644 (file)
@@ -135,6 +135,8 @@ struct scsi_device {
                                     * because we did a bus reset. */
        unsigned use_10_for_rw:1; /* first try 10-byte read / write */
        unsigned use_10_for_ms:1; /* first try 10-byte mode sense/select */
+       unsigned no_report_opcodes:1;   /* no REPORT SUPPORTED OPERATION CODES */
+       unsigned no_write_same:1;       /* no WRITE SAME command */
        unsigned skip_ms_page_8:1;      /* do not use MODE SENSE page 0x08 */
        unsigned skip_ms_page_3f:1;     /* do not use MODE SENSE page 0x3f */
        unsigned skip_vpd_pages:1;      /* do not read VPD pages */
@@ -362,6 +364,8 @@ extern int scsi_test_unit_ready(struct scsi_device *sdev, int timeout,
                                int retries, struct scsi_sense_hdr *sshdr);
 extern int scsi_get_vpd_page(struct scsi_device *, u8 page, unsigned char *buf,
                             int buf_len);
+extern int scsi_report_opcode(struct scsi_device *sdev, unsigned char *buffer,
+                             unsigned int len, unsigned char opcode);
 extern int scsi_device_set_state(struct scsi_device *sdev,
                                 enum scsi_device_state state);
 extern struct scsi_event *sdev_evt_alloc(enum scsi_device_event evt_type,
index 9391706e92541d2b5d865610a88525bf8215a599..d6fd8e5b14b76c41bfd532c3fa86255e4e92b0f3 100644 (file)
@@ -36,6 +36,7 @@
        {(unsigned long)__GFP_RECLAIMABLE,      "GFP_RECLAIMABLE"},     \
        {(unsigned long)__GFP_MOVABLE,          "GFP_MOVABLE"},         \
        {(unsigned long)__GFP_NOTRACK,          "GFP_NOTRACK"},         \
+       {(unsigned long)__GFP_NO_KSWAPD,        "GFP_NO_KSWAPD"},       \
        {(unsigned long)__GFP_OTHER_NODE,       "GFP_OTHER_NODE"}       \
        ) : "GFP_NOWAIT"
 
index e194387ef7845a77c53114f0e3dbada06e4c8189..19e765fbfef716442b38f1bc89eb7490c08c0c76 100644 (file)
@@ -415,3 +415,4 @@ header-y += wireless.h
 header-y += x25.h
 header-y += xattr.h
 header-y += xfrm.h
+header-y += hw_breakpoint.h
diff --git a/include/uapi/linux/hw_breakpoint.h b/include/uapi/linux/hw_breakpoint.h
new file mode 100644 (file)
index 0000000..b04000a
--- /dev/null
@@ -0,0 +1,30 @@
+#ifndef _UAPI_LINUX_HW_BREAKPOINT_H
+#define _UAPI_LINUX_HW_BREAKPOINT_H
+
+enum {
+       HW_BREAKPOINT_LEN_1 = 1,
+       HW_BREAKPOINT_LEN_2 = 2,
+       HW_BREAKPOINT_LEN_4 = 4,
+       HW_BREAKPOINT_LEN_8 = 8,
+};
+
+enum {
+       HW_BREAKPOINT_EMPTY     = 0,
+       HW_BREAKPOINT_R         = 1,
+       HW_BREAKPOINT_W         = 2,
+       HW_BREAKPOINT_RW        = HW_BREAKPOINT_R | HW_BREAKPOINT_W,
+       HW_BREAKPOINT_X         = 4,
+       HW_BREAKPOINT_INVALID   = HW_BREAKPOINT_RW | HW_BREAKPOINT_X,
+};
+
+enum bp_type_idx {
+       TYPE_INST       = 0,
+#ifdef CONFIG_HAVE_MIXED_BREAKPOINTS_REGS
+       TYPE_DATA       = 0,
+#else
+       TYPE_DATA       = 1,
+#endif
+       TYPE_MAX
+};
+
+#endif /* _UAPI_LINUX_HW_BREAKPOINT_H */
index 9a7b487c6fe240c1a2e4f5c70ef68da6370ebf78..fe8a916507ed278cf545196561878a842547a865 100644 (file)
@@ -111,14 +111,16 @@ static unsigned int max_task_bp_pinned(int cpu, enum bp_type_idx type)
  * Count the number of breakpoints of the same type and same task.
  * The given event must be not on the list.
  */
-static int task_bp_pinned(struct perf_event *bp, enum bp_type_idx type)
+static int task_bp_pinned(int cpu, struct perf_event *bp, enum bp_type_idx type)
 {
        struct task_struct *tsk = bp->hw.bp_target;
        struct perf_event *iter;
        int count = 0;
 
        list_for_each_entry(iter, &bp_task_head, hw.bp_list) {
-               if (iter->hw.bp_target == tsk && find_slot_idx(iter) == type)
+               if (iter->hw.bp_target == tsk &&
+                   find_slot_idx(iter) == type &&
+                   cpu == iter->cpu)
                        count += hw_breakpoint_weight(iter);
        }
 
@@ -141,7 +143,7 @@ fetch_bp_busy_slots(struct bp_busy_slots *slots, struct perf_event *bp,
                if (!tsk)
                        slots->pinned += max_task_bp_pinned(cpu, type);
                else
-                       slots->pinned += task_bp_pinned(bp, type);
+                       slots->pinned += task_bp_pinned(cpu, bp, type);
                slots->flexible = per_cpu(nr_bp_flexible[type], cpu);
 
                return;
@@ -154,7 +156,7 @@ fetch_bp_busy_slots(struct bp_busy_slots *slots, struct perf_event *bp,
                if (!tsk)
                        nr += max_task_bp_pinned(cpu, type);
                else
-                       nr += task_bp_pinned(bp, type);
+                       nr += task_bp_pinned(cpu, bp, type);
 
                if (nr > slots->pinned)
                        slots->pinned = nr;
@@ -188,7 +190,7 @@ static void toggle_bp_task_slot(struct perf_event *bp, int cpu, bool enable,
        int old_idx = 0;
        int idx = 0;
 
-       old_count = task_bp_pinned(bp, type);
+       old_count = task_bp_pinned(cpu, bp, type);
        old_idx = old_count - 1;
        idx = old_idx + weight;
 
index 20ef219bbe9b76b3d54e6b501366f15cd97c464a..19eb089ca003a7f7a09347eb393d5241cc93342e 100644 (file)
@@ -843,6 +843,9 @@ static void wake_futex(struct futex_q *q)
 {
        struct task_struct *p = q->task;
 
+       if (WARN(q->pi_state || q->rt_waiter, "refusing to wake PI futex\n"))
+               return;
+
        /*
         * We set q->lock_ptr = NULL _before_ we wake up the task. If
         * a non-futex wake up happens on another CPU then the task
@@ -1078,6 +1081,10 @@ retry_private:
 
        plist_for_each_entry_safe(this, next, head, list) {
                if (match_futex (&this->key, &key1)) {
+                       if (this->pi_state || this->rt_waiter) {
+                               ret = -EINVAL;
+                               goto out_unlock;
+                       }
                        wake_futex(this);
                        if (++ret >= nr_wake)
                                break;
@@ -1090,6 +1097,10 @@ retry_private:
                op_ret = 0;
                plist_for_each_entry_safe(this, next, head, list) {
                        if (match_futex (&this->key, &key2)) {
+                               if (this->pi_state || this->rt_waiter) {
+                                       ret = -EINVAL;
+                                       goto out_unlock;
+                               }
                                wake_futex(this);
                                if (++op_ret >= nr_wake2)
                                        break;
@@ -1098,6 +1109,7 @@ retry_private:
                ret += op_ret;
        }
 
+out_unlock:
        double_unlock_hb(hb1, hb2);
 out_put_keys:
        put_futex_key(&key2);
@@ -1387,9 +1399,13 @@ retry_private:
                /*
                 * FUTEX_WAIT_REQEUE_PI and FUTEX_CMP_REQUEUE_PI should always
                 * be paired with each other and no other futex ops.
+                *
+                * We should never be requeueing a futex_q with a pi_state,
+                * which is awaiting a futex_unlock_pi().
                 */
                if ((requeue_pi && !this->rt_waiter) ||
-                   (!requeue_pi && this->rt_waiter)) {
+                   (!requeue_pi && this->rt_waiter) ||
+                   this->pi_state) {
                        ret = -EINVAL;
                        break;
                }
index 4646eb2c382011de7c051577d0fe8b590b4dddca..767e559dfb10e697d207cdc1dedca0b00d5b5bdf 100644 (file)
@@ -21,10 +21,10 @@ struct key *modsign_keyring;
 extern __initdata const u8 modsign_certificate_list[];
 extern __initdata const u8 modsign_certificate_list_end[];
 asm(".section .init.data,\"aw\"\n"
-    "modsign_certificate_list:\n"
+    SYMBOL_PREFIX "modsign_certificate_list:\n"
     ".incbin \"signing_key.x509\"\n"
     ".incbin \"extra_certificates\"\n"
-    "modsign_certificate_list_end:"
+    SYMBOL_PREFIX "modsign_certificate_list_end:"
     );
 
 /*
index ea1b1df5dbb0077a167caaf8e013b8baf765e902..f2970bddc5ea6224b8c0357970a543c90ac11da0 100644 (file)
  *     - Information block
  */
 struct module_signature {
-       enum pkey_algo          algo : 8;       /* Public-key crypto algorithm */
-       enum pkey_hash_algo     hash : 8;       /* Digest algorithm */
-       enum pkey_id_type       id_type : 8;    /* Key identifier type */
-       u8                      signer_len;     /* Length of signer's name */
-       u8                      key_id_len;     /* Length of key identifier */
-       u8                      __pad[3];
-       __be32                  sig_len;        /* Length of signature data */
+       u8      algo;           /* Public-key crypto algorithm [enum pkey_algo] */
+       u8      hash;           /* Digest algorithm [enum pkey_hash_algo] */
+       u8      id_type;        /* Key identifier type [enum pkey_id_type] */
+       u8      signer_len;     /* Length of signer's name */
+       u8      key_id_len;     /* Length of key identifier */
+       u8      __pad[3];
+       __be32  sig_len;        /* Length of signature data */
 };
 
 /*
index 0984a21076a3ed8a37e56d5381bff6320d8fa5f2..15f60d01198bf4b0b126f8f3ac9fa8f2726aaa89 100644 (file)
@@ -143,15 +143,11 @@ autogroup_move_group(struct task_struct *p, struct autogroup *ag)
 
        p->signal->autogroup = autogroup_kref_get(ag);
 
-       if (!ACCESS_ONCE(sysctl_sched_autogroup_enabled))
-               goto out;
-
        t = p;
        do {
                sched_move_task(t);
        } while_each_thread(p, t);
 
-out:
        unlock_task_sighand(p, &flags);
        autogroup_kref_put(prev);
 }
index 8bd047142816dea81894bb27ccc3c78a38ac3d61..443232ebbb53b24ea369ca3c4fbb7b53c5e8cbef 100644 (file)
@@ -4,11 +4,6 @@
 #include <linux/rwsem.h>
 
 struct autogroup {
-       /*
-        * reference doesn't mean how many thread attach to this
-        * autogroup now. It just stands for the number of task
-        * could use this autogroup.
-        */
        struct kref             kref;
        struct task_group       *tg;
        struct rw_semaphore     lock;
index 9d4c8d5a1f538b25b6698483ed37080ecb7652fc..c8c21be11ab48e25569b43a31aee148d7d89c6d1 100644 (file)
@@ -116,7 +116,7 @@ static unsigned long get_timestamp(int this_cpu)
        return cpu_clock(this_cpu) >> 30LL;  /* 2^30 ~= 10^9 */
 }
 
-static unsigned long get_sample_period(void)
+static u64 get_sample_period(void)
 {
        /*
         * convert watchdog_thresh from seconds to ns
@@ -125,7 +125,7 @@ static unsigned long get_sample_period(void)
         * and hard thresholds) to increment before the
         * hardlockup detector generates a warning
         */
-       return get_softlockup_thresh() * (NSEC_PER_SEC / 5);
+       return get_softlockup_thresh() * ((u64)NSEC_PER_SEC / 5);
 }
 
 /* Commands for resetting the watchdog */
@@ -368,6 +368,9 @@ static void watchdog_disable(unsigned int cpu)
 {
        struct hrtimer *hrtimer = &__raw_get_cpu_var(watchdog_hrtimer);
 
+       if (!watchdog_enabled)
+               return;
+
        watchdog_set_prio(SCHED_NORMAL, 0);
        hrtimer_cancel(hrtimer);
        /* disable the perf event */
index 042d221d33cc1675fadf7ee291e86717f2c8f6c9..1dae900df798d1c4e1be722567fd2906041f08f5 100644 (file)
@@ -1361,8 +1361,19 @@ static void __queue_delayed_work(int cpu, struct workqueue_struct *wq,
 
        WARN_ON_ONCE(timer->function != delayed_work_timer_fn ||
                     timer->data != (unsigned long)dwork);
-       BUG_ON(timer_pending(timer));
-       BUG_ON(!list_empty(&work->entry));
+       WARN_ON_ONCE(timer_pending(timer));
+       WARN_ON_ONCE(!list_empty(&work->entry));
+
+       /*
+        * If @delay is 0, queue @dwork->work immediately.  This is for
+        * both optimization and correctness.  The earliest @timer can
+        * expire is on the closest next tick and delayed_work users depend
+        * on that there's no such delay when @delay is 0.
+        */
+       if (!delay) {
+               __queue_work(cpu, wq, &dwork->work);
+               return;
+       }
 
        timer_stats_timer_set_start_info(&dwork->timer);
 
@@ -1417,9 +1428,6 @@ bool queue_delayed_work_on(int cpu, struct workqueue_struct *wq,
        bool ret = false;
        unsigned long flags;
 
-       if (!delay)
-               return queue_work_on(cpu, wq, &dwork->work);
-
        /* read the comment in __queue_work() */
        local_irq_save(flags);
 
@@ -2407,8 +2415,10 @@ static int rescuer_thread(void *__wq)
 repeat:
        set_current_state(TASK_INTERRUPTIBLE);
 
-       if (kthread_should_stop())
+       if (kthread_should_stop()) {
+               __set_current_state(TASK_RUNNING);
                return 0;
+       }
 
        /*
         * See whether any cpu is asking for help.  Unbounded
index 821a16229111eba69f189ae9be683f02eeb70862..a08b791200f3723883fc1328f7410a076f1146ee 100644 (file)
@@ -163,7 +163,7 @@ $(obj)/crc32table.h: $(obj)/gen_crc32table
 #
 obj-$(CONFIG_OID_REGISTRY) += oid_registry.o
 
-$(obj)/oid_registry.c: $(obj)/oid_registry_data.c
+$(obj)/oid_registry.o: $(obj)/oid_registry_data.c
 
 $(obj)/oid_registry_data.c: $(srctree)/include/linux/oid_registry.h \
                            $(src)/build_OID_registry
index de2c8b5a715bd9c1f75129bc40293ac68f1f92e9..5293d2433029d391c3b95c18320d45c77d117c67 100644 (file)
@@ -91,7 +91,7 @@ next_tag:
 
        /* Extract the length */
        len = data[dp++];
-       if (len < 0x7f) {
+       if (len <= 0x7f) {
                dp += len;
                goto next_tag;
        }
index d84beb994f36f1c0b6d7e82fa02fc558a13f88c9..5e396accd3d02a8dce6d06cc2d6020e311b308b0 100644 (file)
@@ -45,6 +45,12 @@ enum {
        dma_debug_coherent,
 };
 
+enum map_err_types {
+       MAP_ERR_CHECK_NOT_APPLICABLE,
+       MAP_ERR_NOT_CHECKED,
+       MAP_ERR_CHECKED,
+};
+
 #define DMA_DEBUG_STACKTRACE_ENTRIES 5
 
 struct dma_debug_entry {
@@ -57,6 +63,7 @@ struct dma_debug_entry {
        int              direction;
        int              sg_call_ents;
        int              sg_mapped_ents;
+       enum map_err_types  map_err_type;
 #ifdef CONFIG_STACKTRACE
        struct           stack_trace stacktrace;
        unsigned long    st_entries[DMA_DEBUG_STACKTRACE_ENTRIES];
@@ -114,6 +121,12 @@ static struct device_driver *current_driver                    __read_mostly;
 
 static DEFINE_RWLOCK(driver_name_lock);
 
+static const char *const maperr2str[] = {
+       [MAP_ERR_CHECK_NOT_APPLICABLE] = "dma map error check not applicable",
+       [MAP_ERR_NOT_CHECKED] = "dma map error not checked",
+       [MAP_ERR_CHECKED] = "dma map error checked",
+};
+
 static const char *type2name[4] = { "single", "page",
                                    "scather-gather", "coherent" };
 
@@ -376,11 +389,12 @@ void debug_dma_dump_mappings(struct device *dev)
                list_for_each_entry(entry, &bucket->list, list) {
                        if (!dev || dev == entry->dev) {
                                dev_info(entry->dev,
-                                        "%s idx %d P=%Lx D=%Lx L=%Lx %s\n",
+                                        "%s idx %d P=%Lx D=%Lx L=%Lx %s %s\n",
                                         type2name[entry->type], idx,
                                         (unsigned long long)entry->paddr,
                                         entry->dev_addr, entry->size,
-                                        dir2name[entry->direction]);
+                                        dir2name[entry->direction],
+                                        maperr2str[entry->map_err_type]);
                        }
                }
 
@@ -844,16 +858,16 @@ static void check_unmap(struct dma_debug_entry *ref)
        struct hash_bucket *bucket;
        unsigned long flags;
 
-       if (dma_mapping_error(ref->dev, ref->dev_addr)) {
-               err_printk(ref->dev, NULL, "DMA-API: device driver tries "
-                          "to free an invalid DMA memory address\n");
-               return;
-       }
-
        bucket = get_hash_bucket(ref, &flags);
        entry = bucket_find_exact(bucket, ref);
 
        if (!entry) {
+               if (dma_mapping_error(ref->dev, ref->dev_addr)) {
+                       err_printk(ref->dev, NULL,
+                                  "DMA-API: device driver tries "
+                                  "to free an invalid DMA memory address\n");
+                       return;
+               }
                err_printk(ref->dev, NULL, "DMA-API: device driver tries "
                           "to free DMA memory it has not allocated "
                           "[device address=0x%016llx] [size=%llu bytes]\n",
@@ -910,6 +924,15 @@ static void check_unmap(struct dma_debug_entry *ref)
                           dir2name[ref->direction]);
        }
 
+       if (entry->map_err_type == MAP_ERR_NOT_CHECKED) {
+               err_printk(ref->dev, entry,
+                          "DMA-API: device driver failed to check map error"
+                          "[device address=0x%016llx] [size=%llu bytes] "
+                          "[mapped as %s]",
+                          ref->dev_addr, ref->size,
+                          type2name[entry->type]);
+       }
+
        hash_bucket_del(entry);
        dma_entry_free(entry);
 
@@ -1017,7 +1040,7 @@ void debug_dma_map_page(struct device *dev, struct page *page, size_t offset,
        if (unlikely(global_disable))
                return;
 
-       if (unlikely(dma_mapping_error(dev, dma_addr)))
+       if (dma_mapping_error(dev, dma_addr))
                return;
 
        entry = dma_entry_alloc();
@@ -1030,6 +1053,7 @@ void debug_dma_map_page(struct device *dev, struct page *page, size_t offset,
        entry->dev_addr  = dma_addr;
        entry->size      = size;
        entry->direction = direction;
+       entry->map_err_type = MAP_ERR_NOT_CHECKED;
 
        if (map_single)
                entry->type = dma_debug_single;
@@ -1045,6 +1069,30 @@ void debug_dma_map_page(struct device *dev, struct page *page, size_t offset,
 }
 EXPORT_SYMBOL(debug_dma_map_page);
 
+void debug_dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
+{
+       struct dma_debug_entry ref;
+       struct dma_debug_entry *entry;
+       struct hash_bucket *bucket;
+       unsigned long flags;
+
+       if (unlikely(global_disable))
+               return;
+
+       ref.dev = dev;
+       ref.dev_addr = dma_addr;
+       bucket = get_hash_bucket(&ref, &flags);
+       entry = bucket_find_exact(bucket, &ref);
+
+       if (!entry)
+               goto out;
+
+       entry->map_err_type = MAP_ERR_CHECKED;
+out:
+       put_hash_bucket(bucket, &flags);
+}
+EXPORT_SYMBOL(debug_dma_mapping_error);
+
 void debug_dma_unmap_page(struct device *dev, dma_addr_t addr,
                          size_t size, int direction, bool map_single)
 {
index 678ce4f1e124b4be4c255f297cef1e29477e7ce0..095ab157a5215a800d01585bbb50b0d6b6a88a17 100644 (file)
@@ -641,7 +641,14 @@ do { \
        **************  MIPS  *****************
        ***************************************/
 #if defined(__mips__) && W_TYPE_SIZE == 32
-#if __GNUC__ > 2 || __GNUC_MINOR__ >= 7
+#if __GNUC__ >= 4 && __GNUC_MINOR__ >= 4
+#define umul_ppmm(w1, w0, u, v)                        \
+do {                                           \
+       UDItype __ll = (UDItype)(u) * (v);      \
+       w1 = __ll >> 32;                        \
+       w0 = __ll;                              \
+} while (0)
+#elif __GNUC__ > 2 || __GNUC_MINOR__ >= 7
 #define umul_ppmm(w1, w0, u, v) \
        __asm__ ("multu %2,%3" \
        : "=l" ((USItype)(w0)), \
@@ -666,7 +673,15 @@ do { \
        **************  MIPS/64  **************
        ***************************************/
 #if (defined(__mips) && __mips >= 3) && W_TYPE_SIZE == 64
-#if __GNUC__ > 2 || __GNUC_MINOR__ >= 7
+#if __GNUC__ >= 4 && __GNUC_MINOR__ >= 4
+#define umul_ppmm(w1, w0, u, v) \
+do {                                                                   \
+       typedef unsigned int __ll_UTItype __attribute__((mode(TI)));    \
+       __ll_UTItype __ll = (__ll_UTItype)(u) * (v);                    \
+       w1 = __ll >> 64;                                                \
+       w0 = __ll;                                                      \
+} while (0)
+#elif __GNUC__ > 2 || __GNUC_MINOR__ >= 7
 #define umul_ppmm(w1, w0, u, v) \
        __asm__ ("dmultu %2,%3" \
        : "=l" ((UDItype)(w0)), \
index 9eef55838fca5ff99580982e85ea0c0fa6dea839..694eaabaaebdc0827c93d81c97f200fc534a115e 100644 (file)
@@ -713,7 +713,15 @@ static void isolate_freepages(struct zone *zone,
 
                /* Found a block suitable for isolating free pages from */
                isolated = 0;
-               end_pfn = min(pfn + pageblock_nr_pages, zone_end_pfn);
+
+               /*
+                * As pfn may not start aligned, pfn+pageblock_nr_page
+                * may cross a MAX_ORDER_NR_PAGES boundary and miss
+                * a pfn_valid check. Ensure isolate_freepages_block()
+                * only scans within a pageblock
+                */
+               end_pfn = ALIGN(pfn + 1, pageblock_nr_pages);
+               end_pfn = min(end_pfn, zone_end_pfn);
                isolated = isolate_freepages_block(cc, pfn, end_pfn,
                                                   freelist, false);
                nr_freepages += isolated;
index 6c5899b9034aa7d769e5fd80e139cad61af104c0..8b20278be6a62fa49a23615cf5bee60bd71b0ed0 100644 (file)
@@ -1476,9 +1476,17 @@ int soft_offline_page(struct page *page, int flags)
 {
        int ret;
        unsigned long pfn = page_to_pfn(page);
+       struct page *hpage = compound_trans_head(page);
 
        if (PageHuge(page))
                return soft_offline_huge_page(page, flags);
+       if (PageTransHuge(hpage)) {
+               if (PageAnon(hpage) && unlikely(split_huge_page(hpage))) {
+                       pr_info("soft offline: %#lx: failed to split THP\n",
+                               pfn);
+                       return -EBUSY;
+               }
+       }
 
        ret = get_any_page(page, pfn, flags);
        if (ret < 0)
index d04a8a54c294f852f55e624e3c41d1b03b7a56e9..4ea600da8940aa209bad6e0ca56ee69ad480ebc2 100644 (file)
@@ -2037,28 +2037,6 @@ struct mempolicy *__mpol_dup(struct mempolicy *old)
        return new;
 }
 
-/*
- * If *frompol needs [has] an extra ref, copy *frompol to *tompol ,
- * eliminate the * MPOL_F_* flags that require conditional ref and
- * [NOTE!!!] drop the extra ref.  Not safe to reference *frompol directly
- * after return.  Use the returned value.
- *
- * Allows use of a mempolicy for, e.g., multiple allocations with a single
- * policy lookup, even if the policy needs/has extra ref on lookup.
- * shmem_readahead needs this.
- */
-struct mempolicy *__mpol_cond_copy(struct mempolicy *tompol,
-                                               struct mempolicy *frompol)
-{
-       if (!mpol_needs_cond_ref(frompol))
-               return frompol;
-
-       *tompol = *frompol;
-       tompol->flags &= ~MPOL_F_SHARED;        /* copy doesn't need unref */
-       __mpol_put(frompol);
-       return tompol;
-}
-
 /* Slow path of a mempolicy comparison */
 bool __mpol_equal(struct mempolicy *a, struct mempolicy *b)
 {
index 7bb35ac0964aaa425b3888e0963e3d7fa2ac1e53..7e208f0ad68ccb1468b408b5a50a981be8beb3a5 100644 (file)
@@ -1405,7 +1405,7 @@ int capture_free_page(struct page *page, int alloc_order, int migratetype)
 
        mt = get_pageblock_migratetype(page);
        if (unlikely(mt != MIGRATE_ISOLATE))
-               __mod_zone_freepage_state(zone, -(1UL << order), mt);
+               __mod_zone_freepage_state(zone, -(1UL << alloc_order), mt);
 
        if (alloc_order != order)
                expand(zone, page, alloc_order, order,
@@ -1422,7 +1422,7 @@ int capture_free_page(struct page *page, int alloc_order, int migratetype)
                }
        }
 
-       return 1UL << order;
+       return 1UL << alloc_order;
 }
 
 /*
@@ -2416,8 +2416,9 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order,
                goto nopage;
 
 restart:
-       wake_all_kswapd(order, zonelist, high_zoneidx,
-                                       zone_idx(preferred_zone));
+       if (!(gfp_mask & __GFP_NO_KSWAPD))
+               wake_all_kswapd(order, zonelist, high_zoneidx,
+                                               zone_idx(preferred_zone));
 
        /*
         * OK, we're below the kswapd watermark and have kicked background
@@ -2494,7 +2495,7 @@ rebalance:
         * system then fail the allocation instead of entering direct reclaim.
         */
        if ((deferred_compaction || contended_compaction) &&
-           (gfp_mask & (__GFP_MOVABLE|__GFP_REPEAT)) == __GFP_MOVABLE)
+                                               (gfp_mask & __GFP_NO_KSWAPD))
                goto nopage;
 
        /* Try direct reclaim and then allocating */
index 89341b658bd06b05d908f8becfef7fe0d904b808..50c5b8f3a359b611a22e1e3715dd816880e4651e 100644 (file)
@@ -910,25 +910,29 @@ static struct mempolicy *shmem_get_sbmpol(struct shmem_sb_info *sbinfo)
 static struct page *shmem_swapin(swp_entry_t swap, gfp_t gfp,
                        struct shmem_inode_info *info, pgoff_t index)
 {
-       struct mempolicy mpol, *spol;
        struct vm_area_struct pvma;
-
-       spol = mpol_cond_copy(&mpol,
-                       mpol_shared_policy_lookup(&info->policy, index));
+       struct page *page;
 
        /* Create a pseudo vma that just contains the policy */
        pvma.vm_start = 0;
        /* Bias interleave by inode number to distribute better across nodes */
        pvma.vm_pgoff = index + info->vfs_inode.i_ino;
        pvma.vm_ops = NULL;
-       pvma.vm_policy = spol;
-       return swapin_readahead(swap, gfp, &pvma, 0);
+       pvma.vm_policy = mpol_shared_policy_lookup(&info->policy, index);
+
+       page = swapin_readahead(swap, gfp, &pvma, 0);
+
+       /* Drop reference taken by mpol_shared_policy_lookup() */
+       mpol_cond_put(pvma.vm_policy);
+
+       return page;
 }
 
 static struct page *shmem_alloc_page(gfp_t gfp,
                        struct shmem_inode_info *info, pgoff_t index)
 {
        struct vm_area_struct pvma;
+       struct page *page;
 
        /* Create a pseudo vma that just contains the policy */
        pvma.vm_start = 0;
@@ -937,10 +941,12 @@ static struct page *shmem_alloc_page(gfp_t gfp,
        pvma.vm_ops = NULL;
        pvma.vm_policy = mpol_shared_policy_lookup(&info->policy, index);
 
-       /*
-        * alloc_page_vma() will drop the shared policy reference
-        */
-       return alloc_page_vma(gfp, &pvma, 0);
+       page = alloc_page_vma(gfp, &pvma, 0);
+
+       /* Drop reference taken by mpol_shared_policy_lookup() */
+       mpol_cond_put(pvma.vm_policy);
+
+       return page;
 }
 #else /* !CONFIG_NUMA */
 #ifdef CONFIG_TMPFS
index fac95f2888f2d1fbe923fd83ff7d43786ac89c58..a83de2f72b3061ee541c3b74fc6ddc6cfb8e202d 100644 (file)
@@ -617,7 +617,7 @@ static void __kfree_section_memmap(struct page *memmap, unsigned long nr_pages)
 {
        return; /* XXX: Not implemented yet */
 }
-static void free_map_bootmem(struct page *page, unsigned long nr_pages)
+static void free_map_bootmem(struct page *memmap, unsigned long nr_pages)
 {
 }
 #else
@@ -658,10 +658,11 @@ static void __kfree_section_memmap(struct page *memmap, unsigned long nr_pages)
                           get_order(sizeof(struct page) * nr_pages));
 }
 
-static void free_map_bootmem(struct page *page, unsigned long nr_pages)
+static void free_map_bootmem(struct page *memmap, unsigned long nr_pages)
 {
        unsigned long maps_section_nr, removing_section_nr, i;
        unsigned long magic;
+       struct page *page = virt_to_page(memmap);
 
        for (i = 0; i < nr_pages; i++, page++) {
                magic = (unsigned long) page->lru.next;
@@ -710,13 +711,10 @@ static void free_section_usemap(struct page *memmap, unsigned long *usemap)
         */
 
        if (memmap) {
-               struct page *memmap_page;
-               memmap_page = virt_to_page(memmap);
-
                nr_pages = PAGE_ALIGN(PAGES_PER_SECTION * sizeof(struct page))
                        >> PAGE_SHIFT;
 
-               free_map_bootmem(memmap_page, nr_pages);
+               free_map_bootmem(memmap, nr_pages);
        }
 }
 
index 48550c66f1f21d4fdff9afd38f6c1fa97f56ef49..b7ed37675644ce7734946bfe5d2e2cfdc7f08fbc 100644 (file)
@@ -2207,9 +2207,12 @@ static bool pfmemalloc_watermark_ok(pg_data_t *pgdat)
  * Throttle direct reclaimers if backing storage is backed by the network
  * and the PFMEMALLOC reserve for the preferred node is getting dangerously
  * depleted. kswapd will continue to make progress and wake the processes
- * when the low watermark is reached
+ * when the low watermark is reached.
+ *
+ * Returns true if a fatal signal was delivered during throttling. If this
+ * happens, the page allocator should not consider triggering the OOM killer.
  */
-static void throttle_direct_reclaim(gfp_t gfp_mask, struct zonelist *zonelist,
+static bool throttle_direct_reclaim(gfp_t gfp_mask, struct zonelist *zonelist,
                                        nodemask_t *nodemask)
 {
        struct zone *zone;
@@ -2224,13 +2227,20 @@ static void throttle_direct_reclaim(gfp_t gfp_mask, struct zonelist *zonelist,
         * processes to block on log_wait_commit().
         */
        if (current->flags & PF_KTHREAD)
-               return;
+               goto out;
+
+       /*
+        * If a fatal signal is pending, this process should not throttle.
+        * It should return quickly so it can exit and free its memory
+        */
+       if (fatal_signal_pending(current))
+               goto out;
 
        /* Check if the pfmemalloc reserves are ok */
        first_zones_zonelist(zonelist, high_zoneidx, NULL, &zone);
        pgdat = zone->zone_pgdat;
        if (pfmemalloc_watermark_ok(pgdat))
-               return;
+               goto out;
 
        /* Account for the throttling */
        count_vm_event(PGSCAN_DIRECT_THROTTLE);
@@ -2246,12 +2256,20 @@ static void throttle_direct_reclaim(gfp_t gfp_mask, struct zonelist *zonelist,
        if (!(gfp_mask & __GFP_FS)) {
                wait_event_interruptible_timeout(pgdat->pfmemalloc_wait,
                        pfmemalloc_watermark_ok(pgdat), HZ);
-               return;
+
+               goto check_pending;
        }
 
        /* Throttle until kswapd wakes the process */
        wait_event_killable(zone->zone_pgdat->pfmemalloc_wait,
                pfmemalloc_watermark_ok(pgdat));
+
+check_pending:
+       if (fatal_signal_pending(current))
+               return true;
+
+out:
+       return false;
 }
 
 unsigned long try_to_free_pages(struct zonelist *zonelist, int order,
@@ -2273,13 +2291,12 @@ unsigned long try_to_free_pages(struct zonelist *zonelist, int order,
                .gfp_mask = sc.gfp_mask,
        };
 
-       throttle_direct_reclaim(gfp_mask, zonelist, nodemask);
-
        /*
-        * Do not enter reclaim if fatal signal is pending. 1 is returned so
-        * that the page allocator does not consider triggering OOM
+        * Do not enter reclaim if fatal signal was delivered while throttled.
+        * 1 is returned so that the page allocator does not OOM kill at this
+        * point.
         */
-       if (fatal_signal_pending(current))
+       if (throttle_direct_reclaim(gfp_mask, zonelist, nodemask))
                return 1;
 
        trace_mm_vmscan_direct_reclaim_begin(order,
@@ -2397,6 +2414,19 @@ static void age_active_anon(struct zone *zone, struct scan_control *sc)
        } while (memcg);
 }
 
+static bool zone_balanced(struct zone *zone, int order,
+                         unsigned long balance_gap, int classzone_idx)
+{
+       if (!zone_watermark_ok_safe(zone, order, high_wmark_pages(zone) +
+                                   balance_gap, classzone_idx, 0))
+               return false;
+
+       if (COMPACTION_BUILD && order && !compaction_suitable(zone, order))
+               return false;
+
+       return true;
+}
+
 /*
  * pgdat_balanced is used when checking if a node is balanced for high-order
  * allocations. Only zones that meet watermarks and are in a zone allowed
@@ -2475,8 +2505,7 @@ static bool prepare_kswapd_sleep(pg_data_t *pgdat, int order, long remaining,
                        continue;
                }
 
-               if (!zone_watermark_ok_safe(zone, order, high_wmark_pages(zone),
-                                                       i, 0))
+               if (!zone_balanced(zone, order, 0, i))
                        all_zones_ok = false;
                else
                        balanced += zone->present_pages;
@@ -2585,8 +2614,7 @@ loop_again:
                                break;
                        }
 
-                       if (!zone_watermark_ok_safe(zone, order,
-                                       high_wmark_pages(zone), 0, 0)) {
+                       if (!zone_balanced(zone, order, 0, 0)) {
                                end_zone = i;
                                break;
                        } else {
@@ -2662,9 +2690,8 @@ loop_again:
                                testorder = 0;
 
                        if ((buffer_heads_over_limit && is_highmem_idx(i)) ||
-                                   !zone_watermark_ok_safe(zone, testorder,
-                                       high_wmark_pages(zone) + balance_gap,
-                                       end_zone, 0)) {
+                           !zone_balanced(zone, testorder,
+                                          balance_gap, end_zone)) {
                                shrink_zone(zone, &sc);
 
                                reclaim_state->reclaimed_slab = 0;
@@ -2691,8 +2718,7 @@ loop_again:
                                continue;
                        }
 
-                       if (!zone_watermark_ok_safe(zone, testorder,
-                                       high_wmark_pages(zone), end_zone, 0)) {
+                       if (!zone_balanced(zone, testorder, 0, end_zone)) {
                                all_zones_ok = 0;
                                /*
                                 * We are still under min water mark.  This
@@ -2797,29 +2823,10 @@ out:
                        if (!populated_zone(zone))
                                continue;
 
-                       if (zone->all_unreclaimable &&
-                           sc.priority != DEF_PRIORITY)
-                               continue;
-
-                       /* Would compaction fail due to lack of free memory? */
-                       if (COMPACTION_BUILD &&
-                           compaction_suitable(zone, order) == COMPACT_SKIPPED)
-                               goto loop_again;
-
-                       /* Confirm the zone is balanced for order-0 */
-                       if (!zone_watermark_ok(zone, 0,
-                                       high_wmark_pages(zone), 0, 0)) {
-                               order = sc.order = 0;
-                               goto loop_again;
-                       }
-
                        /* Check if the memory needs to be defragmented. */
                        if (zone_watermark_ok(zone, order,
                                    low_wmark_pages(zone), *classzone_idx, 0))
                                zones_need_compaction = 0;
-
-                       /* If balanced, clear the congested flag */
-                       zone_clear_flag(zone, ZONE_CONGESTED);
                }
 
                if (zones_need_compaction)
index 6f747582718ed28464b4eaa2bd45740939c13506..969b7cdff59d9480e4a7a77cbff72acb0e12eae7 100644 (file)
@@ -1084,6 +1084,9 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
                op->sk = sk;
                op->ifindex = ifindex;
 
+               /* ifindex for timeout events w/o previous frame reception */
+               op->rx_ifindex = ifindex;
+
                /* initialize uninitialized (kzalloc) structure */
                hrtimer_init(&op->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
                op->timer.function = bcm_rx_timeout_handler;
index c0946cb2b3547f4fdea0fa56b8f7e17c71a75012..e5942bf45a6d9b7e7412a2100b7ef116610aab65 100644 (file)
@@ -3451,6 +3451,8 @@ static int napi_gro_complete(struct sk_buff *skb)
        struct list_head *head = &ptype_base[ntohs(type) & PTYPE_HASH_MASK];
        int err = -ENOENT;
 
+       BUILD_BUG_ON(sizeof(struct napi_gro_cb) > sizeof(skb->cb));
+
        if (NAPI_GRO_CB(skb)->count == 1) {
                skb_shinfo(skb)->gso_size = 0;
                goto out;
index bcf02f608cbfa76ad06da490f2dbf423e728fc17..017a8bacfb2773483c97c8fa3b162e03f09f454a 100644 (file)
@@ -429,6 +429,17 @@ static struct attribute_group netstat_group = {
        .name  = "statistics",
        .attrs  = netstat_attrs,
 };
+
+#if IS_ENABLED(CONFIG_WIRELESS_EXT) || IS_ENABLED(CONFIG_CFG80211)
+static struct attribute *wireless_attrs[] = {
+       NULL
+};
+
+static struct attribute_group wireless_group = {
+       .name = "wireless",
+       .attrs = wireless_attrs,
+};
+#endif
 #endif /* CONFIG_SYSFS */
 
 #ifdef CONFIG_RPS
@@ -1409,6 +1420,15 @@ int netdev_register_kobject(struct net_device *net)
                groups++;
 
        *groups++ = &netstat_group;
+
+#if IS_ENABLED(CONFIG_WIRELESS_EXT) || IS_ENABLED(CONFIG_CFG80211)
+       if (net->ieee80211_ptr)
+               *groups++ = &wireless_group;
+#if IS_ENABLED(CONFIG_WIRELESS_EXT)
+       else if (net->wireless_handlers)
+               *groups++ = &wireless_group;
+#endif
+#endif
 #endif /* CONFIG_SYSFS */
 
        error = device_add(dev);
index 4007c1437fdaf615bbf197ad52e545529e7bce59..3f0636cd76cdcd132278e4f860ee1f581fd8174c 100644 (file)
@@ -3004,7 +3004,7 @@ int skb_gro_receive(struct sk_buff **head, struct sk_buff *skb)
        skb_shinfo(nskb)->gso_size = pinfo->gso_size;
        pinfo->gso_size = 0;
        skb_header_release(p);
-       nskb->prev = p;
+       NAPI_GRO_CB(nskb)->last = p;
 
        nskb->data_len += p->len;
        nskb->truesize += p->truesize;
@@ -3030,8 +3030,8 @@ merge:
 
        __skb_pull(skb, offset);
 
-       p->prev->next = skb;
-       p->prev = skb;
+       NAPI_GRO_CB(p)->last->next = skb;
+       NAPI_GRO_CB(p)->last = skb;
        skb_header_release(skb);
 
 done:
index f2eccd531746bea19eb269fa0d75266b20f69ebc..17ff9fd7cddab0db42c718173cfd85a9586d6d16 100644 (file)
@@ -257,7 +257,8 @@ static inline bool icmpv4_xrlim_allow(struct net *net, struct rtable *rt,
                struct inet_peer *peer = inet_getpeer_v4(net->ipv4.peers, fl4->daddr, 1);
                rc = inet_peer_xrlim_allow(peer,
                                           net->ipv4.sysctl_icmp_ratelimit);
-               inet_putpeer(peer);
+               if (peer)
+                       inet_putpeer(peer);
        }
 out:
        return rc;
index 0c34bfabc11fc8bcb8056a67abf0feb0b652154f..e23e16dc501d5458632df5e884149f89b30f9e28 100644 (file)
@@ -44,6 +44,10 @@ struct inet_diag_entry {
        u16 dport;
        u16 family;
        u16 userlocks;
+#if IS_ENABLED(CONFIG_IPV6)
+       struct in6_addr saddr_storage;  /* for IPv4-mapped-IPv6 addresses */
+       struct in6_addr daddr_storage;  /* for IPv4-mapped-IPv6 addresses */
+#endif
 };
 
 static DEFINE_MUTEX(inet_diag_table_mutex);
@@ -428,25 +432,31 @@ static int inet_diag_bc_run(const struct nlattr *_bc,
                                break;
                        }
 
-                       if (cond->prefix_len == 0)
-                               break;
-
                        if (op->code == INET_DIAG_BC_S_COND)
                                addr = entry->saddr;
                        else
                                addr = entry->daddr;
 
+                       if (cond->family != AF_UNSPEC &&
+                           cond->family != entry->family) {
+                               if (entry->family == AF_INET6 &&
+                                   cond->family == AF_INET) {
+                                       if (addr[0] == 0 && addr[1] == 0 &&
+                                           addr[2] == htonl(0xffff) &&
+                                           bitstring_match(addr + 3,
+                                                           cond->addr,
+                                                           cond->prefix_len))
+                                               break;
+                               }
+                               yes = 0;
+                               break;
+                       }
+
+                       if (cond->prefix_len == 0)
+                               break;
                        if (bitstring_match(addr, cond->addr,
                                            cond->prefix_len))
                                break;
-                       if (entry->family == AF_INET6 &&
-                           cond->family == AF_INET) {
-                               if (addr[0] == 0 && addr[1] == 0 &&
-                                   addr[2] == htonl(0xffff) &&
-                                   bitstring_match(addr + 3, cond->addr,
-                                                   cond->prefix_len))
-                                       break;
-                       }
                        yes = 0;
                        break;
                }
@@ -509,6 +519,55 @@ static int valid_cc(const void *bc, int len, int cc)
        return 0;
 }
 
+/* Validate an inet_diag_hostcond. */
+static bool valid_hostcond(const struct inet_diag_bc_op *op, int len,
+                          int *min_len)
+{
+       int addr_len;
+       struct inet_diag_hostcond *cond;
+
+       /* Check hostcond space. */
+       *min_len += sizeof(struct inet_diag_hostcond);
+       if (len < *min_len)
+               return false;
+       cond = (struct inet_diag_hostcond *)(op + 1);
+
+       /* Check address family and address length. */
+       switch (cond->family) {
+       case AF_UNSPEC:
+               addr_len = 0;
+               break;
+       case AF_INET:
+               addr_len = sizeof(struct in_addr);
+               break;
+       case AF_INET6:
+               addr_len = sizeof(struct in6_addr);
+               break;
+       default:
+               return false;
+       }
+       *min_len += addr_len;
+       if (len < *min_len)
+               return false;
+
+       /* Check prefix length (in bits) vs address length (in bytes). */
+       if (cond->prefix_len > 8 * addr_len)
+               return false;
+
+       return true;
+}
+
+/* Validate a port comparison operator. */
+static inline bool valid_port_comparison(const struct inet_diag_bc_op *op,
+                                        int len, int *min_len)
+{
+       /* Port comparisons put the port in a follow-on inet_diag_bc_op. */
+       *min_len += sizeof(struct inet_diag_bc_op);
+       if (len < *min_len)
+               return false;
+       return true;
+}
+
 static int inet_diag_bc_audit(const void *bytecode, int bytecode_len)
 {
        const void *bc = bytecode;
@@ -516,29 +575,39 @@ static int inet_diag_bc_audit(const void *bytecode, int bytecode_len)
 
        while (len > 0) {
                const struct inet_diag_bc_op *op = bc;
+               int min_len = sizeof(struct inet_diag_bc_op);
 
 //printk("BC: %d %d %d {%d} / %d\n", op->code, op->yes, op->no, op[1].no, len);
                switch (op->code) {
-               case INET_DIAG_BC_AUTO:
                case INET_DIAG_BC_S_COND:
                case INET_DIAG_BC_D_COND:
+                       if (!valid_hostcond(bc, len, &min_len))
+                               return -EINVAL;
+                       break;
                case INET_DIAG_BC_S_GE:
                case INET_DIAG_BC_S_LE:
                case INET_DIAG_BC_D_GE:
                case INET_DIAG_BC_D_LE:
-               case INET_DIAG_BC_JMP:
-                       if (op->no < 4 || op->no > len + 4 || op->no & 3)
-                               return -EINVAL;
-                       if (op->no < len &&
-                           !valid_cc(bytecode, bytecode_len, len - op->no))
+                       if (!valid_port_comparison(bc, len, &min_len))
                                return -EINVAL;
                        break;
+               case INET_DIAG_BC_AUTO:
+               case INET_DIAG_BC_JMP:
                case INET_DIAG_BC_NOP:
                        break;
                default:
                        return -EINVAL;
                }
-               if (op->yes < 4 || op->yes > len + 4 || op->yes & 3)
+
+               if (op->code != INET_DIAG_BC_NOP) {
+                       if (op->no < min_len || op->no > len + 4 || op->no & 3)
+                               return -EINVAL;
+                       if (op->no < len &&
+                           !valid_cc(bytecode, bytecode_len, len - op->no))
+                               return -EINVAL;
+               }
+
+               if (op->yes < min_len || op->yes > len + 4 || op->yes & 3)
                        return -EINVAL;
                bc  += op->yes;
                len -= op->yes;
@@ -596,6 +665,36 @@ static int inet_twsk_diag_dump(struct inet_timewait_sock *tw,
                                   cb->nlh->nlmsg_seq, NLM_F_MULTI, cb->nlh);
 }
 
+/* Get the IPv4, IPv6, or IPv4-mapped-IPv6 local and remote addresses
+ * from a request_sock. For IPv4-mapped-IPv6 we must map IPv4 to IPv6.
+ */
+static inline void inet_diag_req_addrs(const struct sock *sk,
+                                      const struct request_sock *req,
+                                      struct inet_diag_entry *entry)
+{
+       struct inet_request_sock *ireq = inet_rsk(req);
+
+#if IS_ENABLED(CONFIG_IPV6)
+       if (sk->sk_family == AF_INET6) {
+               if (req->rsk_ops->family == AF_INET6) {
+                       entry->saddr = inet6_rsk(req)->loc_addr.s6_addr32;
+                       entry->daddr = inet6_rsk(req)->rmt_addr.s6_addr32;
+               } else if (req->rsk_ops->family == AF_INET) {
+                       ipv6_addr_set_v4mapped(ireq->loc_addr,
+                                              &entry->saddr_storage);
+                       ipv6_addr_set_v4mapped(ireq->rmt_addr,
+                                              &entry->daddr_storage);
+                       entry->saddr = entry->saddr_storage.s6_addr32;
+                       entry->daddr = entry->daddr_storage.s6_addr32;
+               }
+       } else
+#endif
+       {
+               entry->saddr = &ireq->loc_addr;
+               entry->daddr = &ireq->rmt_addr;
+       }
+}
+
 static int inet_diag_fill_req(struct sk_buff *skb, struct sock *sk,
                              struct request_sock *req,
                              struct user_namespace *user_ns,
@@ -637,8 +736,10 @@ static int inet_diag_fill_req(struct sk_buff *skb, struct sock *sk,
        r->idiag_inode = 0;
 #if IS_ENABLED(CONFIG_IPV6)
        if (r->idiag_family == AF_INET6) {
-               *(struct in6_addr *)r->id.idiag_src = inet6_rsk(req)->loc_addr;
-               *(struct in6_addr *)r->id.idiag_dst = inet6_rsk(req)->rmt_addr;
+               struct inet_diag_entry entry;
+               inet_diag_req_addrs(sk, req, &entry);
+               memcpy(r->id.idiag_src, entry.saddr, sizeof(struct in6_addr));
+               memcpy(r->id.idiag_dst, entry.daddr, sizeof(struct in6_addr));
        }
 #endif
 
@@ -691,18 +792,7 @@ static int inet_diag_dump_reqs(struct sk_buff *skb, struct sock *sk,
                                continue;
 
                        if (bc) {
-                               entry.saddr =
-#if IS_ENABLED(CONFIG_IPV6)
-                                       (entry.family == AF_INET6) ?
-                                       inet6_rsk(req)->loc_addr.s6_addr32 :
-#endif
-                                       &ireq->loc_addr;
-                               entry.daddr =
-#if IS_ENABLED(CONFIG_IPV6)
-                                       (entry.family == AF_INET6) ?
-                                       inet6_rsk(req)->rmt_addr.s6_addr32 :
-#endif
-                                       &ireq->rmt_addr;
+                               inet_diag_req_addrs(sk, req, &entry);
                                entry.dport = ntohs(ireq->rmt_port);
 
                                if (!inet_diag_bc_run(bc, &entry))
index 448e68546827431098c980bafc4a63967764942f..8d5cc75dac88286fa6a10f24d7cb8f16c7c1bc14 100644 (file)
@@ -707,28 +707,27 @@ EXPORT_SYMBOL(ip_defrag);
 
 struct sk_buff *ip_check_defrag(struct sk_buff *skb, u32 user)
 {
-       const struct iphdr *iph;
+       struct iphdr iph;
        u32 len;
 
        if (skb->protocol != htons(ETH_P_IP))
                return skb;
 
-       if (!pskb_may_pull(skb, sizeof(struct iphdr)))
+       if (!skb_copy_bits(skb, 0, &iph, sizeof(iph)))
                return skb;
 
-       iph = ip_hdr(skb);
-       if (iph->ihl < 5 || iph->version != 4)
+       if (iph.ihl < 5 || iph.version != 4)
                return skb;
-       if (!pskb_may_pull(skb, iph->ihl*4))
-               return skb;
-       iph = ip_hdr(skb);
-       len = ntohs(iph->tot_len);
-       if (skb->len < len || len < (iph->ihl * 4))
+
+       len = ntohs(iph.tot_len);
+       if (skb->len < len || len < (iph.ihl * 4))
                return skb;
 
-       if (ip_is_fragment(ip_hdr(skb))) {
+       if (ip_is_fragment(&iph)) {
                skb = skb_share_check(skb, GFP_ATOMIC);
                if (skb) {
+                       if (!pskb_may_pull(skb, iph.ihl*4))
+                               return skb;
                        if (pskb_trim_rcsum(skb, len))
                                return skb;
                        memset(IPCB(skb), 0, sizeof(struct inet_skb_parm));
index 6168c4dc58b1db546c567ef0c55842ab42edee16..3eab2b2ffd34e41fd84588a27c23de0d43e16fc4 100644 (file)
@@ -1318,6 +1318,10 @@ int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, unsi
                if (get_user(v, (u32 __user *)optval))
                        return -EFAULT;
 
+               /* "pimreg%u" should not exceed 16 bytes (IFNAMSIZ) */
+               if (v != RT_TABLE_DEFAULT && v >= 1000000000)
+                       return -EINVAL;
+
                rtnl_lock();
                ret = 0;
                if (sk == rtnl_dereference(mrt->mroute_sk)) {
index a8c651216fa62a44d9226eed3294e3e5f3484a3d..df251424d816b460ae268f21d337c57e64452fc6 100644 (file)
@@ -1785,6 +1785,7 @@ static struct rtable *__mkroute_output(const struct fib_result *res,
        if (dev_out->flags & IFF_LOOPBACK)
                flags |= RTCF_LOCAL;
 
+       do_cache = true;
        if (type == RTN_BROADCAST) {
                flags |= RTCF_BROADCAST | RTCF_LOCAL;
                fi = NULL;
@@ -1793,6 +1794,8 @@ static struct rtable *__mkroute_output(const struct fib_result *res,
                if (!ip_check_mc_rcu(in_dev, fl4->daddr, fl4->saddr,
                                     fl4->flowi4_proto))
                        flags &= ~RTCF_LOCAL;
+               else
+                       do_cache = false;
                /* If multicast route do not exist use
                 * default one, but do not gateway in this case.
                 * Yes, it is hack.
@@ -1802,8 +1805,8 @@ static struct rtable *__mkroute_output(const struct fib_result *res,
        }
 
        fnhe = NULL;
-       do_cache = fi != NULL;
-       if (fi) {
+       do_cache &= fi != NULL;
+       if (do_cache) {
                struct rtable __rcu **prth;
                struct fib_nh *nh = &FIB_RES_NH(*res);
 
@@ -2597,7 +2600,7 @@ int __init ip_rt_init(void)
                pr_err("Unable to create route proc files\n");
 #ifdef CONFIG_XFRM
        xfrm_init();
-       xfrm4_init(ip_rt_max_size);
+       xfrm4_init();
 #endif
        rtnl_register(PF_INET, RTM_GETROUTE, inet_rtm_getroute, NULL, NULL);
 
index 083092e3aed68db2dd5e9c3fb9cd43759a529abe..e457c7ab2e28daf5607e93ef0c31e667f1cec216 100644 (file)
@@ -830,8 +830,8 @@ static int tcp_send_mss(struct sock *sk, int *size_goal, int flags)
        return mss_now;
 }
 
-static ssize_t do_tcp_sendpages(struct sock *sk, struct page **pages, int poffset,
-                        size_t psize, int flags)
+static ssize_t do_tcp_sendpages(struct sock *sk, struct page *page, int offset,
+                               size_t size, int flags)
 {
        struct tcp_sock *tp = tcp_sk(sk);
        int mss_now, size_goal;
@@ -858,12 +858,9 @@ static ssize_t do_tcp_sendpages(struct sock *sk, struct page **pages, int poffse
        if (sk->sk_err || (sk->sk_shutdown & SEND_SHUTDOWN))
                goto out_err;
 
-       while (psize > 0) {
+       while (size > 0) {
                struct sk_buff *skb = tcp_write_queue_tail(sk);
-               struct page *page = pages[poffset / PAGE_SIZE];
                int copy, i;
-               int offset = poffset % PAGE_SIZE;
-               int size = min_t(size_t, psize, PAGE_SIZE - offset);
                bool can_coalesce;
 
                if (!tcp_send_head(sk) || (copy = size_goal - skb->len) <= 0) {
@@ -912,8 +909,8 @@ new_segment:
                        TCP_SKB_CB(skb)->tcp_flags &= ~TCPHDR_PSH;
 
                copied += copy;
-               poffset += copy;
-               if (!(psize -= copy))
+               offset += copy;
+               if (!(size -= copy))
                        goto out;
 
                if (skb->len < size_goal || (flags & MSG_OOB))
@@ -960,7 +957,7 @@ int tcp_sendpage(struct sock *sk, struct page *page, int offset,
                                        flags);
 
        lock_sock(sk);
-       res = do_tcp_sendpages(sk, &page, offset, size, flags);
+       res = do_tcp_sendpages(sk, page, offset, size, flags);
        release_sock(sk);
        return res;
 }
index 609ff98aeb47ce99500614ff4a8a9cfe3a290d28..181fc8234a529d5b6663f683e0da19e5ab17c1e8 100644 (file)
@@ -5645,7 +5645,11 @@ static bool tcp_rcv_fastopen_synack(struct sock *sk, struct sk_buff *synack,
        tcp_fastopen_cache_set(sk, mss, cookie, syn_drop);
 
        if (data) { /* Retransmit unacked data in SYN */
-               tcp_retransmit_skb(sk, data);
+               tcp_for_write_queue_from(data, sk) {
+                       if (data == tcp_send_head(sk) ||
+                           __tcp_retransmit_skb(sk, data))
+                               break;
+               }
                tcp_rearm_rto(sk);
                return true;
        }
index 2798706cb06385aa87fdb05ba1ed2c6a0a14e6e5..948ac275b9b52ed10c1adaa9f931760a0903c788 100644 (file)
@@ -2309,12 +2309,11 @@ static void tcp_retrans_try_collapse(struct sock *sk, struct sk_buff *to,
  * state updates are done by the caller.  Returns non-zero if an
  * error occurred which prevented the send.
  */
-int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb)
+int __tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb)
 {
        struct tcp_sock *tp = tcp_sk(sk);
        struct inet_connection_sock *icsk = inet_csk(sk);
        unsigned int cur_mss;
-       int err;
 
        /* Inconslusive MTU probe */
        if (icsk->icsk_mtup.probe_size) {
@@ -2387,11 +2386,17 @@ int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb)
        if (unlikely(NET_IP_ALIGN && ((unsigned long)skb->data & 3))) {
                struct sk_buff *nskb = __pskb_copy(skb, MAX_TCP_HEADER,
                                                   GFP_ATOMIC);
-               err = nskb ? tcp_transmit_skb(sk, nskb, 0, GFP_ATOMIC) :
-                            -ENOBUFS;
+               return nskb ? tcp_transmit_skb(sk, nskb, 0, GFP_ATOMIC) :
+                             -ENOBUFS;
        } else {
-               err = tcp_transmit_skb(sk, skb, 1, GFP_ATOMIC);
+               return tcp_transmit_skb(sk, skb, 1, GFP_ATOMIC);
        }
+}
+
+int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb)
+{
+       struct tcp_sock *tp = tcp_sk(sk);
+       int err = __tcp_retransmit_skb(sk, skb);
 
        if (err == 0) {
                /* Update global TCP statistics. */
index 05c5ab8d983c462f75ab6143ca653669d36c1005..3be0ac2c1920e668be3f53f44a3df731a44204fc 100644 (file)
@@ -279,19 +279,8 @@ static void __exit xfrm4_policy_fini(void)
        xfrm_policy_unregister_afinfo(&xfrm4_policy_afinfo);
 }
 
-void __init xfrm4_init(int rt_max_size)
+void __init xfrm4_init(void)
 {
-       /*
-        * Select a default value for the gc_thresh based on the main route
-        * table hash size.  It seems to me the worst case scenario is when
-        * we have ipsec operating in transport mode, in which we create a
-        * dst_entry per socket.  The xfrm gc algorithm starts trying to remove
-        * entries at gc_thresh, and prevents new allocations as 2*gc_thresh
-        * so lets set an initial xfrm gc_thresh value at the rt_max_size/2.
-        * That will let us store an ipsec connection per route table entry,
-        * and start cleaning when were 1/2 full
-        */
-       xfrm4_dst_ops.gc_thresh = rt_max_size/2;
        dst_entries_init(&xfrm4_dst_ops);
 
        xfrm4_state_init();
index c4f934176cabd92ebfb4bba774335427b9f8932a..30647857a375bce469c50071636b5aef6c5a33d7 100644 (file)
@@ -252,6 +252,7 @@ struct dst_entry *inet6_csk_update_pmtu(struct sock *sk, u32 mtu)
                return NULL;
        dst->ops->update_pmtu(dst, sk, NULL, mtu);
 
-       return inet6_csk_route_socket(sk, &fl6);
+       dst = inet6_csk_route_socket(sk, &fl6);
+       return IS_ERR(dst) ? NULL : dst;
 }
 EXPORT_SYMBOL_GPL(inet6_csk_update_pmtu);
index 1002e3396f7287049b41c53e4aaa5cdc285a73e6..ae43c62f9045ba94ced0f025a9ecacb3bf145af1 100644 (file)
@@ -441,6 +441,7 @@ struct tsap_cb *irttp_open_tsap(__u8 stsap_sel, int credit, notify_t *notify)
        lsap = irlmp_open_lsap(stsap_sel, &ttp_notify, 0);
        if (lsap == NULL) {
                IRDA_DEBUG(0, "%s: unable to allocate LSAP!!\n", __func__);
+               __irttp_close_tsap(self);
                return NULL;
        }
 
index bf87c70ac6c5fe1e2b920c6db827e1e9da6abe36..c21e33d1abd0d945ba041182dff52ad3f9ed4dc6 100644 (file)
@@ -1151,10 +1151,6 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata)
 
        mutex_lock(&sdata->u.ibss.mtx);
 
-       sdata->u.ibss.state = IEEE80211_IBSS_MLME_SEARCH;
-       memset(sdata->u.ibss.bssid, 0, ETH_ALEN);
-       sdata->u.ibss.ssid_len = 0;
-
        active_ibss = ieee80211_sta_active_ibss(sdata);
 
        if (!active_ibss && !is_zero_ether_addr(ifibss->bssid)) {
@@ -1175,6 +1171,10 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata)
                }
        }
 
+       ifibss->state = IEEE80211_IBSS_MLME_SEARCH;
+       memset(ifibss->bssid, 0, ETH_ALEN);
+       ifibss->ssid_len = 0;
+
        sta_info_flush(sdata->local, sdata);
 
        spin_lock_bh(&ifibss->incomplete_lock);
index 83608ac167801f1c06fc55dd3ab53370d947cbc7..2c84185dfdb0c2e9901d86b0903463061ddaaecf 100644 (file)
@@ -458,8 +458,6 @@ void ieee80211_roc_purge(struct ieee80211_sub_if_data *sdata)
                list_move_tail(&roc->list, &tmp_list);
                roc->abort = true;
        }
-
-       ieee80211_start_next_roc(local);
        mutex_unlock(&local->mtx);
 
        list_for_each_entry_safe(roc, tmp, &tmp_list, list) {
index ec3dba5dcd62f081c1749fb60f2aa71cd31d11ad..5c0b78528e55b1af2288aa2e1a398202131413d5 100644 (file)
@@ -173,6 +173,7 @@ hash_ip4_uadt(struct ip_set *set, struct nlattr *tb[],
                return adtfn(set, &nip, timeout, flags);
        }
 
+       ip_to = ip;
        if (tb[IPSET_ATTR_IP_TO]) {
                ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to);
                if (ret)
@@ -185,8 +186,7 @@ hash_ip4_uadt(struct ip_set *set, struct nlattr *tb[],
                if (!cidr || cidr > 32)
                        return -IPSET_ERR_INVALID_CIDR;
                ip_set_mask_from_to(ip, ip_to, cidr);
-       } else
-               ip_to = ip;
+       }
 
        hosts = h->netmask == 32 ? 1 : 2 << (32 - h->netmask - 1);
 
index 0171f7502fa58d035fcda2361a6c4968acf09b7b..6283351f4eebee920c2939613ff05676b16f91ad 100644 (file)
@@ -162,7 +162,7 @@ hash_ipport4_uadt(struct ip_set *set, struct nlattr *tb[],
        const struct ip_set_hash *h = set->data;
        ipset_adtfn adtfn = set->variant->adt[adt];
        struct hash_ipport4_elem data = { };
-       u32 ip, ip_to = 0, p = 0, port, port_to;
+       u32 ip, ip_to, p = 0, port, port_to;
        u32 timeout = h->timeout;
        bool with_ports = false;
        int ret;
@@ -210,7 +210,7 @@ hash_ipport4_uadt(struct ip_set *set, struct nlattr *tb[],
                return ip_set_eexist(ret, flags) ? 0 : ret;
        }
 
-       ip = ntohl(data.ip);
+       ip_to = ip = ntohl(data.ip);
        if (tb[IPSET_ATTR_IP_TO]) {
                ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to);
                if (ret)
@@ -223,8 +223,7 @@ hash_ipport4_uadt(struct ip_set *set, struct nlattr *tb[],
                if (!cidr || cidr > 32)
                        return -IPSET_ERR_INVALID_CIDR;
                ip_set_mask_from_to(ip, ip_to, cidr);
-       } else
-               ip_to = ip;
+       }
 
        port_to = port = ntohs(data.port);
        if (with_ports && tb[IPSET_ATTR_PORT_TO]) {
index 6344ef551ec811208b79ddc54c89a1270c2419cd..6a21271c8d5a9f5da822c9789d55b761924d6da5 100644 (file)
@@ -166,7 +166,7 @@ hash_ipportip4_uadt(struct ip_set *set, struct nlattr *tb[],
        const struct ip_set_hash *h = set->data;
        ipset_adtfn adtfn = set->variant->adt[adt];
        struct hash_ipportip4_elem data = { };
-       u32 ip, ip_to = 0, p = 0, port, port_to;
+       u32 ip, ip_to, p = 0, port, port_to;
        u32 timeout = h->timeout;
        bool with_ports = false;
        int ret;
@@ -218,7 +218,7 @@ hash_ipportip4_uadt(struct ip_set *set, struct nlattr *tb[],
                return ip_set_eexist(ret, flags) ? 0 : ret;
        }
 
-       ip = ntohl(data.ip);
+       ip_to = ip = ntohl(data.ip);
        if (tb[IPSET_ATTR_IP_TO]) {
                ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to);
                if (ret)
@@ -231,8 +231,7 @@ hash_ipportip4_uadt(struct ip_set *set, struct nlattr *tb[],
                if (!cidr || cidr > 32)
                        return -IPSET_ERR_INVALID_CIDR;
                ip_set_mask_from_to(ip, ip_to, cidr);
-       } else
-               ip_to = ip;
+       }
 
        port_to = port = ntohs(data.port);
        if (with_ports && tb[IPSET_ATTR_PORT_TO]) {
index cb71f9a774e7d50d67998aaaadc199a563f43f40..2d5cd4ee30eb4d5872b4aa9be7199a3d8999f6c7 100644 (file)
@@ -215,8 +215,8 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
        const struct ip_set_hash *h = set->data;
        ipset_adtfn adtfn = set->variant->adt[adt];
        struct hash_ipportnet4_elem data = { .cidr = HOST_MASK - 1 };
-       u32 ip, ip_to = 0, p = 0, port, port_to;
-       u32 ip2_from = 0, ip2_to, ip2_last, ip2;
+       u32 ip, ip_to, p = 0, port, port_to;
+       u32 ip2_from, ip2_to, ip2_last, ip2;
        u32 timeout = h->timeout;
        bool with_ports = false;
        u8 cidr;
@@ -286,6 +286,7 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
                return ip_set_eexist(ret, flags) ? 0 : ret;
        }
 
+       ip_to = ip;
        if (tb[IPSET_ATTR_IP_TO]) {
                ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to);
                if (ret)
@@ -306,6 +307,8 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
                if (port > port_to)
                        swap(port, port_to);
        }
+
+       ip2_to = ip2_from;
        if (tb[IPSET_ATTR_IP2_TO]) {
                ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP2_TO], &ip2_to);
                if (ret)
index b9a63381e34998e08ab5271f7d82cca9058a76d8..45a101439bc5dc62798e62b1516b78a9d8096272 100644 (file)
@@ -793,7 +793,7 @@ static struct ip_set_type hash_netiface_type __read_mostly = {
                [IPSET_ATTR_IP]         = { .type = NLA_NESTED },
                [IPSET_ATTR_IP_TO]      = { .type = NLA_NESTED },
                [IPSET_ATTR_IFACE]      = { .type = NLA_NUL_STRING,
-                                           .len = IPSET_MAXNAMELEN - 1 },
+                                           .len  = IFNAMSIZ - 1 },
                [IPSET_ATTR_CADT_FLAGS] = { .type = NLA_U32 },
                [IPSET_ATTR_CIDR]       = { .type = NLA_U8 },
                [IPSET_ATTR_TIMEOUT]    = { .type = NLA_U32 },
index 8847b4d8be06b9ad536c2bb32d9bbd3d34a7c289..701c88a20fea4c2a3ca6c9b4b2189521e13f96fe 100644 (file)
@@ -41,7 +41,8 @@ MODULE_DESCRIPTION("cttimeout: Extended Netfilter Connection Tracking timeout tu
 static LIST_HEAD(cttimeout_list);
 
 static const struct nla_policy cttimeout_nla_policy[CTA_TIMEOUT_MAX+1] = {
-       [CTA_TIMEOUT_NAME]      = { .type = NLA_NUL_STRING },
+       [CTA_TIMEOUT_NAME]      = { .type = NLA_NUL_STRING,
+                                   .len  = CTNL_TIMEOUT_NAME_MAX - 1},
        [CTA_TIMEOUT_L3PROTO]   = { .type = NLA_U16 },
        [CTA_TIMEOUT_L4PROTO]   = { .type = NLA_U8 },
        [CTA_TIMEOUT_DATA]      = { .type = NLA_NESTED },
index cc10d073c3381179671ef709b58baf4600e51a2b..9e8f4b2801f6099ebd5afcff20d2b5ef19e16589 100644 (file)
@@ -1210,7 +1210,7 @@ int nfc_llcp_register_device(struct nfc_dev *ndev)
        local->remote_miu = LLCP_DEFAULT_MIU;
        local->remote_lto = LLCP_DEFAULT_LTO;
 
-       list_add(&llcp_devices, &local->list);
+       list_add(&local->list, &llcp_devices);
 
        return 0;
 }
index 98c70630ad06178778dc4f1e04275fa6032facc8..733cbf49ed1f506ae263d50675775e2e96e3356d 100644 (file)
@@ -702,15 +702,11 @@ int ovs_flow_extract(struct sk_buff *skb, u16 in_port, struct sw_flow_key *key,
                        /* We only match on the lower 8 bits of the opcode. */
                        if (ntohs(arp->ar_op) <= 0xff)
                                key->ip.proto = ntohs(arp->ar_op);
-
-                       if (key->ip.proto == ARPOP_REQUEST
-                                       || key->ip.proto == ARPOP_REPLY) {
-                               memcpy(&key->ipv4.addr.src, arp->ar_sip, sizeof(key->ipv4.addr.src));
-                               memcpy(&key->ipv4.addr.dst, arp->ar_tip, sizeof(key->ipv4.addr.dst));
-                               memcpy(key->ipv4.arp.sha, arp->ar_sha, ETH_ALEN);
-                               memcpy(key->ipv4.arp.tha, arp->ar_tha, ETH_ALEN);
-                               key_len = SW_FLOW_KEY_OFFSET(ipv4.arp);
-                       }
+                       memcpy(&key->ipv4.addr.src, arp->ar_sip, sizeof(key->ipv4.addr.src));
+                       memcpy(&key->ipv4.addr.dst, arp->ar_tip, sizeof(key->ipv4.addr.dst));
+                       memcpy(key->ipv4.arp.sha, arp->ar_sha, ETH_ALEN);
+                       memcpy(key->ipv4.arp.tha, arp->ar_tha, ETH_ALEN);
+                       key_len = SW_FLOW_KEY_OFFSET(ipv4.arp);
                }
        } else if (key->eth.type == htons(ETH_P_IPV6)) {
                int nh_len;             /* IPv6 Header + Extensions */
index 3c1e58ba714bf9534b597c9f28147cc7c3038b39..a9033481fa5e867b2264fa9f834a4041786ed166 100644 (file)
@@ -158,7 +158,7 @@ static int netdev_send(struct vport *vport, struct sk_buff *skb)
 
        if (unlikely(packet_length(skb) > mtu && !skb_is_gso(skb))) {
                net_warn_ratelimited("%s: dropped over-mtu packet: %d > %d\n",
-                                    ovs_dp_name(vport->dp),
+                                    netdev_vport->dev->name,
                                     packet_length(skb), mtu);
                goto error;
        }
index 7c2df9c33df37a588c426e7945cd71233edd4577..69ce21e3716f89fbfc78b050ffc3943455906d27 100644 (file)
@@ -183,7 +183,7 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc,
 
        msg = sctp_datamsg_new(GFP_KERNEL);
        if (!msg)
-               return NULL;
+               return ERR_PTR(-ENOMEM);
 
        /* Note: Calculate this outside of the loop, so that all fragments
         * have the same expiration.
@@ -280,11 +280,14 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc,
 
                chunk = sctp_make_datafrag_empty(asoc, sinfo, len, frag, 0);
 
-               if (!chunk)
+               if (!chunk) {
+                       err = -ENOMEM;
                        goto errout;
+               }
+
                err = sctp_user_addto_chunk(chunk, offset, len, msgh->msg_iov);
                if (err < 0)
-                       goto errout;
+                       goto errout_chunk_free;
 
                offset += len;
 
@@ -315,8 +318,10 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc,
 
                chunk = sctp_make_datafrag_empty(asoc, sinfo, over, frag, 0);
 
-               if (!chunk)
+               if (!chunk) {
+                       err = -ENOMEM;
                        goto errout;
+               }
 
                err = sctp_user_addto_chunk(chunk, offset, over,msgh->msg_iov);
 
@@ -324,7 +329,7 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc,
                __skb_pull(chunk->skb, (__u8 *)chunk->chunk_hdr
                           - (__u8 *)chunk->skb->data);
                if (err < 0)
-                       goto errout;
+                       goto errout_chunk_free;
 
                sctp_datamsg_assign(msg, chunk);
                list_add_tail(&chunk->frag_list, &msg->chunks);
@@ -332,6 +337,9 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc,
 
        return msg;
 
+errout_chunk_free:
+       sctp_chunk_free(chunk);
+
 errout:
        list_for_each_safe(pos, temp, &msg->chunks) {
                list_del_init(pos);
@@ -339,7 +347,7 @@ errout:
                sctp_chunk_free(chunk);
        }
        sctp_datamsg_put(msg);
-       return NULL;
+       return ERR_PTR(err);
 }
 
 /* Check whether this message has expired. */
index a60d1f8b41c5e2330e837265e175202aba322fcb..406d957d08fbcb7d9cb532a8143d363c277c3ec8 100644 (file)
@@ -1915,8 +1915,8 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
 
        /* Break the message into multiple chunks of maximum size. */
        datamsg = sctp_datamsg_from_user(asoc, sinfo, msg, msg_len);
-       if (!datamsg) {
-               err = -ENOMEM;
+       if (IS_ERR(datamsg)) {
+               err = PTR_ERR(datamsg);
                goto out_free;
        }
 
index 953c21e4af977a752362187976e84b578bdb085c..206cf5238fd3ef00183f87e52734398ab475fbdb 100644 (file)
@@ -331,7 +331,7 @@ void sctp_transport_update_rto(struct sctp_transport *tp, __u32 rtt)
                 * 1/8, rto_alpha would be expressed as 3.
                 */
                tp->rttvar = tp->rttvar - (tp->rttvar >> net->sctp.rto_beta)
-                       + ((abs(tp->srtt - rtt)) >> net->sctp.rto_beta);
+                       + (((__u32)abs64((__s64)tp->srtt - (__s64)rtt)) >> net->sctp.rto_beta);
                tp->srtt = tp->srtt - (tp->srtt >> net->sctp.rto_alpha)
                        + (rtt >> net->sctp.rto_alpha);
        } else {
index 239d22d4207b92aee3fb0a9233375acf673d2311..6c353ae8a4517b1e7ab4b2b4fa28012e96de9921 100644 (file)
@@ -42,6 +42,9 @@ foreach my $filename (@files) {
                $line =~ s/(^|\s)(inline)\b/$1__$2__/g;
                $line =~ s/(^|\s)(asm)\b(\s|[(]|$)/$1__$2__$3/g;
                $line =~ s/(^|\s|[(])(volatile)\b(\s|[(]|$)/$1__$2__$3/g;
+               $line =~ s/#ifndef _UAPI/#ifndef /;
+               $line =~ s/#define _UAPI/#define /;
+               $line =~ s!#endif /[*] _UAPI!#endif /* !;
                printf {$out} "%s", $line;
        }
        close $out;
index 87ca59d36e7ef64754892be3d842ac614bf2a9d5..974a20b661b79c6385f5fbc0cd40cd57e2a7ef94 100755 (executable)
@@ -156,12 +156,12 @@ sub asn1_extract($$@)
 
        if ($l == 0x1) {
            $len = unpack("C", substr(${$cursor->[2]}, $cursor->[0], 1));
-       } elsif ($l = 0x2) {
+       } elsif ($l == 0x2) {
            $len = unpack("n", substr(${$cursor->[2]}, $cursor->[0], 2));
-       } elsif ($l = 0x3) {
+       } elsif ($l == 0x3) {
            $len = unpack("C", substr(${$cursor->[2]}, $cursor->[0], 1)) << 16;
            $len = unpack("n", substr(${$cursor->[2]}, $cursor->[0] + 1, 2));
-       } elsif ($l = 0x4) {
+       } elsif ($l == 0x4) {
            $len = unpack("N", substr(${$cursor->[2]}, $cursor->[0], 4));
        } else {
            die $x509, ": ", $cursor->[0], ": ASN.1 element too long (", $l, ")\n";
index 28f911cdd7c79dc292171fea10385adad51a27eb..c5454c0477c346e4d814f5ff209feba86e5b86ad 100644 (file)
@@ -174,7 +174,8 @@ static void sel_netnode_insert(struct sel_netnode *node)
        if (sel_netnode_hash[idx].size == SEL_NETNODE_HASH_BKT_LIMIT) {
                struct sel_netnode *tail;
                tail = list_entry(
-                       rcu_dereference(sel_netnode_hash[idx].list.prev),
+                       rcu_dereference_protected(sel_netnode_hash[idx].list.prev,
+                                                 lockdep_is_held(&sel_netnode_lock)),
                        struct sel_netnode, list);
                list_del_rcu(&tail->list);
                kfree_rcu(tail, rcu);
index 70d4848b5cd0ad25ce272877f9c759ed010dfc58..d010de12335e16525df3219cbe33647262316f7e 100644 (file)
@@ -95,6 +95,7 @@ int snd_hda_delete_codec_preset(struct hda_codec_preset_list *preset)
 EXPORT_SYMBOL_HDA(snd_hda_delete_codec_preset);
 
 #ifdef CONFIG_PM
+#define codec_in_pm(codec)     ((codec)->in_pm)
 static void hda_power_work(struct work_struct *work);
 static void hda_keep_power_on(struct hda_codec *codec);
 #define hda_codec_is_power_on(codec)   ((codec)->power_on)
@@ -104,6 +105,7 @@ static inline void hda_call_pm_notify(struct hda_bus *bus, bool power_up)
                bus->ops.pm_notify(bus, power_up);
 }
 #else
+#define codec_in_pm(codec)     0
 static inline void hda_keep_power_on(struct hda_codec *codec) {}
 #define hda_codec_is_power_on(codec)   1
 #define hda_call_pm_notify(bus, state) {}
@@ -228,7 +230,7 @@ static int codec_exec_verb(struct hda_codec *codec, unsigned int cmd,
        }
        mutex_unlock(&bus->cmd_mutex);
        snd_hda_power_down(codec);
-       if (res && *res == -1 && bus->rirb_error) {
+       if (!codec_in_pm(codec) && res && *res == -1 && bus->rirb_error) {
                if (bus->response_reset) {
                        snd_printd("hda_codec: resetting BUS due to "
                                   "fatal communication error\n");
@@ -238,7 +240,7 @@ static int codec_exec_verb(struct hda_codec *codec, unsigned int cmd,
                goto again;
        }
        /* clear reset-flag when the communication gets recovered */
-       if (!err)
+       if (!err || codec_in_pm(codec))
                bus->response_reset = 0;
        return err;
 }
@@ -3616,6 +3618,8 @@ static unsigned int hda_call_codec_suspend(struct hda_codec *codec, bool in_wq)
 {
        unsigned int state;
 
+       codec->in_pm = 1;
+
        if (codec->patch_ops.suspend)
                codec->patch_ops.suspend(codec);
        hda_cleanup_all_streams(codec);
@@ -3630,6 +3634,7 @@ static unsigned int hda_call_codec_suspend(struct hda_codec *codec, bool in_wq)
        codec->power_transition = 0;
        codec->power_jiffies = jiffies;
        spin_unlock(&codec->power_lock);
+       codec->in_pm = 0;
        return state;
 }
 
@@ -3638,6 +3643,8 @@ static unsigned int hda_call_codec_suspend(struct hda_codec *codec, bool in_wq)
  */
 static void hda_call_codec_resume(struct hda_codec *codec)
 {
+       codec->in_pm = 1;
+
        /* set as if powered on for avoiding re-entering the resume
         * in the resume / power-save sequence
         */
@@ -3656,6 +3663,8 @@ static void hda_call_codec_resume(struct hda_codec *codec)
                snd_hda_codec_resume_cache(codec);
        }
        snd_hda_jack_report_sync(codec);
+
+       codec->in_pm = 0;
        snd_hda_power_down(codec); /* flag down before returning */
 }
 #endif /* CONFIG_PM */
index 507fe8a917b69b09993193ef460f4fbc3f3af31a..4f4e545c0f4b2ded6029d21851b3443973ea7d23 100644 (file)
@@ -869,6 +869,7 @@ struct hda_codec {
        unsigned int power_on :1;       /* current (global) power-state */
        unsigned int d3_stop_clk:1;     /* support D3 operation without BCLK */
        unsigned int pm_down_notified:1; /* PM notified to controller */
+       unsigned int in_pm:1;           /* suspend/resume being performed */
        int power_transition;   /* power-state in transition */
        int power_count;        /* current (global) power refcount */
        struct delayed_work power_work; /* delayed task for powerdown */
index cd2dbaf1be786c61a3a1a446d7df5836d9622f35..f9d870e554d98d2fabe8791e904d7a393c8925e6 100644 (file)
@@ -556,6 +556,12 @@ enum {
 #define AZX_DCAPS_ALIGN_BUFSIZE        (1 << 22)       /* buffer size alignment */
 #define AZX_DCAPS_4K_BDLE_BOUNDARY (1 << 23)   /* BDLE in 4k boundary */
 #define AZX_DCAPS_COUNT_LPIB_DELAY  (1 << 25)  /* Take LPIB as delay */
+#define AZX_DCAPS_PM_RUNTIME   (1 << 26)       /* runtime PM support */
+
+/* quirks for Intel PCH */
+#define AZX_DCAPS_INTEL_PCH \
+       (AZX_DCAPS_SCH_SNOOP | AZX_DCAPS_BUFSIZE | \
+        AZX_DCAPS_COUNT_LPIB_DELAY | AZX_DCAPS_PM_RUNTIME)
 
 /* quirks for ATI SB / AMD Hudson */
 #define AZX_DCAPS_PRESET_ATI_SB \
@@ -2433,6 +2439,9 @@ static void azx_power_notify(struct hda_bus *bus, bool power_up)
 {
        struct azx *chip = bus->private_data;
 
+       if (!(chip->driver_caps & AZX_DCAPS_PM_RUNTIME))
+               return;
+
        if (power_up)
                pm_runtime_get_sync(&chip->pci->dev);
        else
@@ -2548,7 +2557,8 @@ static int azx_runtime_suspend(struct device *dev)
        struct snd_card *card = dev_get_drvdata(dev);
        struct azx *chip = card->private_data;
 
-       if (!power_save_controller)
+       if (!power_save_controller ||
+           !(chip->driver_caps & AZX_DCAPS_PM_RUNTIME))
                return -EAGAIN;
 
        azx_stop_chip(chip);
@@ -3429,39 +3439,30 @@ static void __devexit azx_remove(struct pci_dev *pci)
 static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
        /* CPT */
        { PCI_DEVICE(0x8086, 0x1c20),
-         .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
-         AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY },
+         .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
        /* PBG */
        { PCI_DEVICE(0x8086, 0x1d20),
-         .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
-         AZX_DCAPS_BUFSIZE},
+         .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
        /* Panther Point */
        { PCI_DEVICE(0x8086, 0x1e20),
-         .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
-         AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY },
+         .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
        /* Lynx Point */
        { PCI_DEVICE(0x8086, 0x8c20),
-         .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
-         AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY },
+         .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
        /* Lynx Point-LP */
        { PCI_DEVICE(0x8086, 0x9c20),
-         .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
-         AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY },
+         .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
        /* Lynx Point-LP */
        { PCI_DEVICE(0x8086, 0x9c21),
-         .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
-         AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY },
+         .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
        /* Haswell */
        { PCI_DEVICE(0x8086, 0x0c0c),
-         .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP |
-         AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY },
+         .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH },
        { PCI_DEVICE(0x8086, 0x0d0c),
-         .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP |
-         AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY },
+         .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH },
        /* 5 Series/3400 */
        { PCI_DEVICE(0x8086, 0x3b56),
-         .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP |
-         AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY },
+         .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH },
        /* SCH */
        { PCI_DEVICE(0x8086, 0x811b),
          .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP |
index d5f3a26d608db72f1e4ef3f596392eb5a4f25a67..3bcb671723583ed852ec97aa844d2736ffd4b330 100644 (file)
@@ -466,6 +466,7 @@ static int parse_output(struct hda_codec *codec)
                memcpy(cfg->speaker_pins, cfg->line_out_pins,
                       sizeof(cfg->speaker_pins));
                cfg->line_outs = 0;
+               memset(cfg->line_out_pins, 0, sizeof(cfg->line_out_pins));
        }
 
        return 0;
index 68fd49294b26d2f327aff5decd88efa90df68d92..ad68d223f8af9e7dc43d24af303aab1eec64ca3d 100644 (file)
@@ -7065,6 +7065,7 @@ static const struct hda_codec_preset snd_hda_preset_realtek[] = {
        { .id = 0x10ec0282, .name = "ALC282", .patch = patch_alc269 },
        { .id = 0x10ec0283, .name = "ALC283", .patch = patch_alc269 },
        { .id = 0x10ec0290, .name = "ALC290", .patch = patch_alc269 },
+       { .id = 0x10ec0292, .name = "ALC292", .patch = patch_alc269 },
        { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
          .patch = patch_alc861 },
        { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
index c03b65af30598f8f03dfba2d7353913a33a0bfe9..054967d8bac2f6d089214e390b1bd6ce416f64b2 100644 (file)
@@ -268,7 +268,7 @@ EXPORT_SYMBOL_GPL(arizona_out_ev);
 static unsigned int arizona_sysclk_48k_rates[] = {
        6144000,
        12288000,
-       22579200,
+       24576000,
        49152000,
        73728000,
        98304000,
@@ -278,7 +278,7 @@ static unsigned int arizona_sysclk_48k_rates[] = {
 static unsigned int arizona_sysclk_44k1_rates[] = {
        5644800,
        11289600,
-       24576000,
+       22579200,
        45158400,
        67737600,
        90316800,
index f994af34f552f4b08c4e01880c3410a4890afb7c..e3f0a7f3131e14b7895aadf2daf8bf81f6058d8b 100644 (file)
@@ -485,7 +485,7 @@ static int cs4271_probe(struct snd_soc_codec *codec)
                gpio_nreset = cs4271plat->gpio_nreset;
 
        if (gpio_nreset >= 0)
-               if (gpio_request(gpio_nreset, "CS4271 Reset"))
+               if (devm_gpio_request(codec->dev, gpio_nreset, "CS4271 Reset"))
                        gpio_nreset = -EINVAL;
        if (gpio_nreset >= 0) {
                /* Reset codec */
@@ -535,15 +535,10 @@ static int cs4271_probe(struct snd_soc_codec *codec)
 static int cs4271_remove(struct snd_soc_codec *codec)
 {
        struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
-       int gpio_nreset;
 
-       gpio_nreset = cs4271->gpio_nreset;
-
-       if (gpio_is_valid(gpio_nreset)) {
+       if (gpio_is_valid(cs4271->gpio_nreset))
                /* Set codec to the reset state */
-               gpio_set_value(gpio_nreset, 0);
-               gpio_free(gpio_nreset);
-       }
+               gpio_set_value(cs4271->gpio_nreset, 0);
 
        return 0;
 };
index b9f16598324c9b4b85373b6f55d785011c4d8b68..2ba08148655f32ee2fa7301c44d65b54e7ea02fb 100644 (file)
@@ -71,7 +71,6 @@ static irqreturn_t kirkwood_dma_irq(int irq, void *dev_id)
                printk(KERN_WARNING "%s: got err interrupt 0x%lx\n",
                                __func__, cause);
                writel(cause, priv->io + KIRKWOOD_ERR_CAUSE);
-               return IRQ_HANDLED;
        }
 
        /* we've enabled only bytes interrupts ... */
@@ -178,7 +177,7 @@ static int kirkwood_dma_open(struct snd_pcm_substream *substream)
        }
 
        dram = mv_mbus_dram_info();
-       addr = virt_to_phys(substream->dma_buffer.area);
+       addr = substream->dma_buffer.addr;
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
                prdata->play_stream = substream;
                kirkwood_dma_conf_mbus_windows(priv->io,
index 542538d10ab7df46b02fc2b6bb3630c8bed45322..1d5db484d2df331b15e8e385cd32e2acd79e4d79 100644 (file)
@@ -95,7 +95,7 @@ static inline void kirkwood_set_dco(void __iomem *io, unsigned long rate)
        do {
                cpu_relax();
                value = readl(io + KIRKWOOD_DCO_SPCR_STATUS);
-               value &= KIRKWOOD_DCO_SPCR_STATUS;
+               value &= KIRKWOOD_DCO_SPCR_STATUS_DCO_LOCK;
        } while (value == 0);
 }
 
@@ -180,67 +180,72 @@ static int kirkwood_i2s_play_trigger(struct snd_pcm_substream *substream,
                                int cmd, struct snd_soc_dai *dai)
 {
        struct kirkwood_dma_data *priv = snd_soc_dai_get_drvdata(dai);
-       unsigned long value;
-
-       /*
-        * specs says KIRKWOOD_PLAYCTL must be read 2 times before
-        * changing it. So read 1 time here and 1 later.
-        */
-       value = readl(priv->io + KIRKWOOD_PLAYCTL);
+       uint32_t ctl, value;
+
+       ctl = readl(priv->io + KIRKWOOD_PLAYCTL);
+       if (ctl & KIRKWOOD_PLAYCTL_PAUSE) {
+               unsigned timeout = 5000;
+               /*
+                * The Armada510 spec says that if we enter pause mode, the
+                * busy bit must be read back as clear _twice_.  Make sure
+                * we respect that otherwise we get DMA underruns.
+                */
+               do {
+                       value = ctl;
+                       ctl = readl(priv->io + KIRKWOOD_PLAYCTL);
+                       if (!((ctl | value) & KIRKWOOD_PLAYCTL_PLAY_BUSY))
+                               break;
+                       udelay(1);
+               } while (timeout--);
+
+               if ((ctl | value) & KIRKWOOD_PLAYCTL_PLAY_BUSY)
+                       dev_notice(dai->dev, "timed out waiting for busy to deassert: %08x\n",
+                                  ctl);
+       }
 
        switch (cmd) {
        case SNDRV_PCM_TRIGGER_START:
-               /* stop audio, enable interrupts */
-               value = readl(priv->io + KIRKWOOD_PLAYCTL);
-               value |= KIRKWOOD_PLAYCTL_PAUSE;
-               writel(value, priv->io + KIRKWOOD_PLAYCTL);
-
                value = readl(priv->io + KIRKWOOD_INT_MASK);
                value |= KIRKWOOD_INT_CAUSE_PLAY_BYTES;
                writel(value, priv->io + KIRKWOOD_INT_MASK);
 
                /* configure audio & enable i2s playback */
-               value = readl(priv->io + KIRKWOOD_PLAYCTL);
-               value &= ~KIRKWOOD_PLAYCTL_BURST_MASK;
-               value &= ~(KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE
+               ctl &= ~KIRKWOOD_PLAYCTL_BURST_MASK;
+               ctl &= ~(KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE
                                | KIRKWOOD_PLAYCTL_SPDIF_EN);
 
                if (priv->burst == 32)
-                       value |= KIRKWOOD_PLAYCTL_BURST_32;
+                       ctl |= KIRKWOOD_PLAYCTL_BURST_32;
                else
-                       value |= KIRKWOOD_PLAYCTL_BURST_128;
-               value |= KIRKWOOD_PLAYCTL_I2S_EN;
-               writel(value, priv->io + KIRKWOOD_PLAYCTL);
+                       ctl |= KIRKWOOD_PLAYCTL_BURST_128;
+               ctl |= KIRKWOOD_PLAYCTL_I2S_EN;
+               writel(ctl, priv->io + KIRKWOOD_PLAYCTL);
                break;
 
        case SNDRV_PCM_TRIGGER_STOP:
                /* stop audio, disable interrupts */
-               value = readl(priv->io + KIRKWOOD_PLAYCTL);
-               value |= KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE;
-               writel(value, priv->io + KIRKWOOD_PLAYCTL);
+               ctl |= KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE;
+               writel(ctl, priv->io + KIRKWOOD_PLAYCTL);
 
                value = readl(priv->io + KIRKWOOD_INT_MASK);
                value &= ~KIRKWOOD_INT_CAUSE_PLAY_BYTES;
                writel(value, priv->io + KIRKWOOD_INT_MASK);
 
                /* disable all playbacks */
-               value = readl(priv->io + KIRKWOOD_PLAYCTL);
-               value &= ~(KIRKWOOD_PLAYCTL_I2S_EN | KIRKWOOD_PLAYCTL_SPDIF_EN);
-               writel(value, priv->io + KIRKWOOD_PLAYCTL);
+               ctl &= ~(KIRKWOOD_PLAYCTL_I2S_EN | KIRKWOOD_PLAYCTL_SPDIF_EN);
+               writel(ctl, priv->io + KIRKWOOD_PLAYCTL);
                break;
 
        case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
        case SNDRV_PCM_TRIGGER_SUSPEND:
-               value = readl(priv->io + KIRKWOOD_PLAYCTL);
-               value |= KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE;
-               writel(value, priv->io + KIRKWOOD_PLAYCTL);
+               ctl |= KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE;
+               writel(ctl, priv->io + KIRKWOOD_PLAYCTL);
                break;
 
        case SNDRV_PCM_TRIGGER_RESUME:
        case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
-               value = readl(priv->io + KIRKWOOD_PLAYCTL);
-               value &= ~(KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE);
-               writel(value, priv->io + KIRKWOOD_PLAYCTL);
+               ctl &= ~(KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE);
+               writel(ctl, priv->io + KIRKWOOD_PLAYCTL);
                break;
 
        default:
@@ -260,11 +265,6 @@ static int kirkwood_i2s_rec_trigger(struct snd_pcm_substream *substream,
 
        switch (cmd) {
        case SNDRV_PCM_TRIGGER_START:
-               /* stop audio, enable interrupts */
-               value = readl(priv->io + KIRKWOOD_RECCTL);
-               value |= KIRKWOOD_RECCTL_PAUSE;
-               writel(value, priv->io + KIRKWOOD_RECCTL);
-
                value = readl(priv->io + KIRKWOOD_INT_MASK);
                value |= KIRKWOOD_INT_CAUSE_REC_BYTES;
                writel(value, priv->io + KIRKWOOD_INT_MASK);
index b56b9a3c61690ac982c0420131b936de7f9d0296..a2ca1567b9e4ff93a481d99065820d887ff8a72c 100644 (file)
@@ -212,7 +212,7 @@ static struct snd_soc_dai_link bells_dai_wm5102[] = {
        {
                .name = "Sub",
                .stream_name = "Sub",
-               .cpu_dai_name = "wm5110-aif3",
+               .cpu_dai_name = "wm5102-aif3",
                .codec_dai_name = "wm9081-hifi",
                .codec_name = "wm9081.1-006c",
                .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
@@ -247,7 +247,7 @@ static struct snd_soc_dai_link bells_dai_wm5110[] = {
        {
                .name = "Sub",
                .stream_name = "Sub",
-               .cpu_dai_name = "wm5102-aif3",
+               .cpu_dai_name = "wm5110-aif3",
                .codec_dai_name = "wm9081-hifi",
                .codec_name = "wm9081.1-006c",
                .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
index c83f6143c0eb34d8f77f969e1928427458b4268a..eeefbce3873c11dc35a6e174c4ace79daeeaa8c1 100644 (file)
@@ -148,6 +148,7 @@ struct snd_usb_midi_out_endpoint {
                struct snd_usb_midi_out_endpoint* ep;
                struct snd_rawmidi_substream *substream;
                int active;
+               bool autopm_reference;
                uint8_t cable;          /* cable number << 4 */
                uint8_t state;
 #define STATE_UNKNOWN  0
@@ -1076,7 +1077,8 @@ static int snd_usbmidi_output_open(struct snd_rawmidi_substream *substream)
                return -ENXIO;
        }
        err = usb_autopm_get_interface(umidi->iface);
-       if (err < 0)
+       port->autopm_reference = err >= 0;
+       if (err < 0 && err != -EACCES)
                return -EIO;
        substream->runtime->private_data = port;
        port->state = STATE_UNKNOWN;
@@ -1087,9 +1089,11 @@ static int snd_usbmidi_output_open(struct snd_rawmidi_substream *substream)
 static int snd_usbmidi_output_close(struct snd_rawmidi_substream *substream)
 {
        struct snd_usb_midi* umidi = substream->rmidi->private_data;
+       struct usbmidi_out_port *port = substream->runtime->private_data;
 
        substream_open(substream, 0);
-       usb_autopm_put_interface(umidi->iface);
+       if (port->autopm_reference)
+               usb_autopm_put_interface(umidi->iface);
        return 0;
 }
 
index 5c12a3fe8c3e8dfae0af6388b9ee3ea8c6c16047..ef6fa24fc473b08a89dd33ef8158f004185f54cb 100644 (file)
@@ -459,7 +459,7 @@ static int configure_endpoint(struct snd_usb_substream *subs)
                return ret;
 
        if (subs->sync_endpoint)
-               ret = snd_usb_endpoint_set_params(subs->data_endpoint,
+               ret = snd_usb_endpoint_set_params(subs->sync_endpoint,
                                                  subs->pcm_format,
                                                  subs->channels,
                                                  subs->period_bytes,
index 3ae43947a171f3d9924a22898fe1e410beb89a98..1f9a529fe544f768c4322e884e4c34d02d482b5e 100644 (file)
@@ -31,44 +31,44 @@ help:
        @echo '  clean: a summary clean target to clean _all_ folders'
 
 cpupower: FORCE
-       $(QUIET_SUBDIR0)power/$@/ $(QUIET_SUBDIR1)
+       $(call descend,power/$@)
 
 firewire lguest perf usb virtio vm: FORCE
-       $(QUIET_SUBDIR0)$@/ $(QUIET_SUBDIR1)
+       $(call descend,$@)
 
 selftests: FORCE
-       $(QUIET_SUBDIR0)testing/$@/ $(QUIET_SUBDIR1)
+       $(call descend,testing/$@)
 
 turbostat x86_energy_perf_policy: FORCE
-       $(QUIET_SUBDIR0)power/x86/$@/ $(QUIET_SUBDIR1)
+       $(call descend,power/x86/$@)
 
 cpupower_install:
-       $(QUIET_SUBDIR0)power/$(@:_install=)/ $(QUIET_SUBDIR1) install
+       $(call descend,power/$(@:_install=),install)
 
 firewire_install lguest_install perf_install usb_install virtio_install vm_install:
-       $(QUIET_SUBDIR0)$(@:_install=)/ $(QUIET_SUBDIR1) install
+       $(call descend,$(@:_install=),install)
 
 selftests_install:
-       $(QUIET_SUBDIR0)testing/$(@:_clean=)/ $(QUIET_SUBDIR1) install
+       $(call descend,testing/$(@:_clean=),install)
 
 turbostat_install x86_energy_perf_policy_install:
-       $(QUIET_SUBDIR0)power/x86/$(@:_install=)/ $(QUIET_SUBDIR1) install
+       $(call descend,power/x86/$(@:_install=),install)
 
 install: cpupower_install firewire_install lguest_install perf_install \
                selftests_install turbostat_install usb_install virtio_install \
                vm_install x86_energy_perf_policy_install
 
 cpupower_clean:
-       $(QUIET_SUBDIR0)power/cpupower/ $(QUIET_SUBDIR1) clean
+       $(call descend,power/cpupower,clean)
 
 firewire_clean lguest_clean perf_clean usb_clean virtio_clean vm_clean:
-       $(QUIET_SUBDIR0)$(@:_clean=)/ $(QUIET_SUBDIR1) clean
+       $(call descend,$(@:_clean=),clean)
 
 selftests_clean:
-       $(QUIET_SUBDIR0)testing/$(@:_clean=)/ $(QUIET_SUBDIR1) clean
+       $(call descend,testing/$(@:_clean=),clean)
 
 turbostat_clean x86_energy_perf_policy_clean:
-       $(QUIET_SUBDIR0)power/x86/$(@:_clean=)/ $(QUIET_SUBDIR1) clean
+       $(call descend,power/x86/$(@:_clean=),clean)
 
 clean: cpupower_clean firewire_clean lguest_clean perf_clean selftests_clean \
                turbostat_clean usb_clean virtio_clean vm_clean \
index 00deed4d61598c5d40d8c607a0da1f42402cefd6..0a619af5be4377fd395dc1b638b40d095d9d7cdd 100644 (file)
@@ -169,7 +169,34 @@ endif
 
 ### --- END CONFIGURATION SECTION ---
 
-BASIC_CFLAGS = -Iutil/include -Iarch/$(ARCH)/include -I$(OUTPUT)util -I$(TRACE_EVENT_DIR) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE
+ifeq ($(srctree),)
+srctree := $(patsubst %/,%,$(dir $(shell pwd)))
+srctree := $(patsubst %/,%,$(dir $(srctree)))
+#$(info Determined 'srctree' to be $(srctree))
+endif
+
+ifneq ($(objtree),)
+#$(info Determined 'objtree' to be $(objtree))
+endif
+
+ifneq ($(OUTPUT),)
+#$(info Determined 'OUTPUT' to be $(OUTPUT))
+endif
+
+BASIC_CFLAGS = \
+       -Iutil/include \
+       -Iarch/$(ARCH)/include \
+       $(if $(objtree),-I$(objtree)/arch/$(ARCH)/include/generated/uapi) \
+       -I$(srctree)/arch/$(ARCH)/include/uapi \
+       -I$(srctree)/arch/$(ARCH)/include \
+       $(if $(objtree),-I$(objtree)/include/generated/uapi) \
+       -I$(srctree)/include/uapi \
+       -I$(srctree)/include \
+       -I$(OUTPUT)util \
+       -Iutil \
+       -I. \
+       -I$(TRACE_EVENT_DIR) \
+       -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE
 BASIC_LDFLAGS =
 
 # Guard against environment variables
index 46fc9f15c6b37e23daf4ba5ae72bbf62226e461b..7fcdcdbee917a8473acf25fe7ac72c6c5a9732b0 100644 (file)
@@ -3,7 +3,7 @@
 
 #include <stdlib.h>
 #include "../../util/types.h"
-#include "../../../../../arch/x86/include/asm/perf_regs.h"
+#include <asm/perf_regs.h>
 
 #ifndef ARCH_X86_64
 #define PERF_REGS_MASK ((1ULL << PERF_REG_X86_32_MAX) - 1)
index 260abc535b5b428e817ebaa5a4354fbe67a947e1..283b4397e397fdd3155c4bcf11b23caeeb2bb139 100644 (file)
 #include <pthread.h>
 #include <math.h>
 
-#include "../../arch/x86/include/asm/svm.h"
-#include "../../arch/x86/include/asm/vmx.h"
-#include "../../arch/x86/include/asm/kvm.h"
+#if defined(__i386__) || defined(__x86_64__)
+#include <asm/svm.h>
+#include <asm/vmx.h>
+#include <asm/kvm.h>
 
 struct event_key {
        #define INVALID_KEY     (~0ULL)
@@ -58,7 +59,7 @@ struct kvm_event_key {
 };
 
 
-struct perf_kvm;
+struct perf_kvm_stat;
 
 struct kvm_events_ops {
        bool (*is_begin_event)(struct perf_evsel *evsel,
@@ -66,7 +67,7 @@ struct kvm_events_ops {
                               struct event_key *key);
        bool (*is_end_event)(struct perf_evsel *evsel,
                             struct perf_sample *sample, struct event_key *key);
-       void (*decode_key)(struct perf_kvm *kvm, struct event_key *key,
+       void (*decode_key)(struct perf_kvm_stat *kvm, struct event_key *key,
                           char decode[20]);
        const char *name;
 };
@@ -79,7 +80,7 @@ struct exit_reasons_table {
 #define EVENTS_BITS            12
 #define EVENTS_CACHE_SIZE      (1UL << EVENTS_BITS)
 
-struct perf_kvm {
+struct perf_kvm_stat {
        struct perf_tool    tool;
        struct perf_session *session;
 
@@ -146,7 +147,7 @@ static struct exit_reasons_table svm_exit_reasons[] = {
        SVM_EXIT_REASONS
 };
 
-static const char *get_exit_reason(struct perf_kvm *kvm, u64 exit_code)
+static const char *get_exit_reason(struct perf_kvm_stat *kvm, u64 exit_code)
 {
        int i = kvm->exit_reasons_size;
        struct exit_reasons_table *tbl = kvm->exit_reasons;
@@ -162,7 +163,7 @@ static const char *get_exit_reason(struct perf_kvm *kvm, u64 exit_code)
        return "UNKNOWN";
 }
 
-static void exit_event_decode_key(struct perf_kvm *kvm,
+static void exit_event_decode_key(struct perf_kvm_stat *kvm,
                                  struct event_key *key,
                                  char decode[20])
 {
@@ -228,7 +229,7 @@ static bool mmio_event_end(struct perf_evsel *evsel, struct perf_sample *sample,
        return false;
 }
 
-static void mmio_event_decode_key(struct perf_kvm *kvm __maybe_unused,
+static void mmio_event_decode_key(struct perf_kvm_stat *kvm __maybe_unused,
                                  struct event_key *key,
                                  char decode[20])
 {
@@ -271,7 +272,7 @@ static bool ioport_event_end(struct perf_evsel *evsel,
        return kvm_entry_event(evsel);
 }
 
-static void ioport_event_decode_key(struct perf_kvm *kvm __maybe_unused,
+static void ioport_event_decode_key(struct perf_kvm_stat *kvm __maybe_unused,
                                    struct event_key *key,
                                    char decode[20])
 {
@@ -286,7 +287,7 @@ static struct kvm_events_ops ioport_events = {
        .name = "IO Port Access"
 };
 
-static bool register_kvm_events_ops(struct perf_kvm *kvm)
+static bool register_kvm_events_ops(struct perf_kvm_stat *kvm)
 {
        bool ret = true;
 
@@ -311,7 +312,7 @@ struct vcpu_event_record {
 };
 
 
-static void init_kvm_event_record(struct perf_kvm *kvm)
+static void init_kvm_event_record(struct perf_kvm_stat *kvm)
 {
        int i;
 
@@ -360,7 +361,7 @@ static struct kvm_event *kvm_alloc_init_event(struct event_key *key)
        return event;
 }
 
-static struct kvm_event *find_create_kvm_event(struct perf_kvm *kvm,
+static struct kvm_event *find_create_kvm_event(struct perf_kvm_stat *kvm,
                                               struct event_key *key)
 {
        struct kvm_event *event;
@@ -381,7 +382,7 @@ static struct kvm_event *find_create_kvm_event(struct perf_kvm *kvm,
        return event;
 }
 
-static bool handle_begin_event(struct perf_kvm *kvm,
+static bool handle_begin_event(struct perf_kvm_stat *kvm,
                               struct vcpu_event_record *vcpu_record,
                               struct event_key *key, u64 timestamp)
 {
@@ -425,7 +426,7 @@ static bool update_kvm_event(struct kvm_event *event, int vcpu_id,
        return true;
 }
 
-static bool handle_end_event(struct perf_kvm *kvm,
+static bool handle_end_event(struct perf_kvm_stat *kvm,
                             struct vcpu_event_record *vcpu_record,
                             struct event_key *key,
                             u64 timestamp)
@@ -486,7 +487,7 @@ struct vcpu_event_record *per_vcpu_record(struct thread *thread,
        return thread->priv;
 }
 
-static bool handle_kvm_event(struct perf_kvm *kvm,
+static bool handle_kvm_event(struct perf_kvm_stat *kvm,
                             struct thread *thread,
                             struct perf_evsel *evsel,
                             struct perf_sample *sample)
@@ -541,7 +542,7 @@ static struct kvm_event_key keys[] = {
        { NULL, NULL }
 };
 
-static bool select_key(struct perf_kvm *kvm)
+static bool select_key(struct perf_kvm_stat *kvm)
 {
        int i;
 
@@ -577,7 +578,8 @@ static void insert_to_result(struct rb_root *result, struct kvm_event *event,
        rb_insert_color(&event->rb, result);
 }
 
-static void update_total_count(struct perf_kvm *kvm, struct kvm_event *event)
+static void
+update_total_count(struct perf_kvm_stat *kvm, struct kvm_event *event)
 {
        int vcpu = kvm->trace_vcpu;
 
@@ -590,7 +592,7 @@ static bool event_is_valid(struct kvm_event *event, int vcpu)
        return !!get_event_count(event, vcpu);
 }
 
-static void sort_result(struct perf_kvm *kvm)
+static void sort_result(struct perf_kvm_stat *kvm)
 {
        unsigned int i;
        int vcpu = kvm->trace_vcpu;
@@ -627,7 +629,7 @@ static void print_vcpu_info(int vcpu)
                pr_info("VCPU %d:\n\n", vcpu);
 }
 
-static void print_result(struct perf_kvm *kvm)
+static void print_result(struct perf_kvm_stat *kvm)
 {
        char decode[20];
        struct kvm_event *event;
@@ -670,7 +672,8 @@ static int process_sample_event(struct perf_tool *tool,
                                struct machine *machine)
 {
        struct thread *thread = machine__findnew_thread(machine, sample->tid);
-       struct perf_kvm *kvm = container_of(tool, struct perf_kvm, tool);
+       struct perf_kvm_stat *kvm = container_of(tool, struct perf_kvm_stat,
+                                                tool);
 
        if (thread == NULL) {
                pr_debug("problem processing %d event, skipping it.\n",
@@ -701,7 +704,7 @@ static int get_cpu_isa(struct perf_session *session)
        return isa;
 }
 
-static int read_events(struct perf_kvm *kvm)
+static int read_events(struct perf_kvm_stat *kvm)
 {
        int ret;
 
@@ -750,7 +753,7 @@ static bool verify_vcpu(int vcpu)
        return true;
 }
 
-static int kvm_events_report_vcpu(struct perf_kvm *kvm)
+static int kvm_events_report_vcpu(struct perf_kvm_stat *kvm)
 {
        int ret = -EINVAL;
        int vcpu = kvm->trace_vcpu;
@@ -798,7 +801,8 @@ static const char * const record_args[] = {
                _p;                     \
        })
 
-static int kvm_events_record(struct perf_kvm *kvm, int argc, const char **argv)
+static int
+kvm_events_record(struct perf_kvm_stat *kvm, int argc, const char **argv)
 {
        unsigned int rec_argc, i, j;
        const char **rec_argv;
@@ -821,7 +825,8 @@ static int kvm_events_record(struct perf_kvm *kvm, int argc, const char **argv)
        return cmd_record(i, rec_argv, NULL);
 }
 
-static int kvm_events_report(struct perf_kvm *kvm, int argc, const char **argv)
+static int
+kvm_events_report(struct perf_kvm_stat *kvm, int argc, const char **argv)
 {
        const struct option kvm_events_report_options[] = {
                OPT_STRING(0, "event", &kvm->report_event, "report event",
@@ -864,24 +869,37 @@ static void print_kvm_stat_usage(void)
        printf("\nOtherwise, it is the alias of 'perf stat':\n");
 }
 
-static int kvm_cmd_stat(struct perf_kvm *kvm, int argc, const char **argv)
+static int kvm_cmd_stat(const char *file_name, int argc, const char **argv)
 {
+       struct perf_kvm_stat kvm = {
+               .file_name = file_name,
+
+               .trace_vcpu     = -1,
+               .report_event   = "vmexit",
+               .sort_key       = "sample",
+
+               .exit_reasons = svm_exit_reasons,
+               .exit_reasons_size = ARRAY_SIZE(svm_exit_reasons),
+               .exit_reasons_isa = "SVM",
+       };
+
        if (argc == 1) {
                print_kvm_stat_usage();
                goto perf_stat;
        }
 
        if (!strncmp(argv[1], "rec", 3))
-               return kvm_events_record(kvm, argc - 1, argv + 1);
+               return kvm_events_record(&kvm, argc - 1, argv + 1);
 
        if (!strncmp(argv[1], "rep", 3))
-               return kvm_events_report(kvm, argc - 1 , argv + 1);
+               return kvm_events_report(&kvm, argc - 1 , argv + 1);
 
 perf_stat:
        return cmd_stat(argc, argv, NULL);
 }
+#endif
 
-static int __cmd_record(struct perf_kvm *kvm, int argc, const char **argv)
+static int __cmd_record(const char *file_name, int argc, const char **argv)
 {
        int rec_argc, i = 0, j;
        const char **rec_argv;
@@ -890,7 +908,7 @@ static int __cmd_record(struct perf_kvm *kvm, int argc, const char **argv)
        rec_argv = calloc(rec_argc + 1, sizeof(char *));
        rec_argv[i++] = strdup("record");
        rec_argv[i++] = strdup("-o");
-       rec_argv[i++] = strdup(kvm->file_name);
+       rec_argv[i++] = strdup(file_name);
        for (j = 1; j < argc; j++, i++)
                rec_argv[i] = argv[j];
 
@@ -899,7 +917,7 @@ static int __cmd_record(struct perf_kvm *kvm, int argc, const char **argv)
        return cmd_record(i, rec_argv, NULL);
 }
 
-static int __cmd_report(struct perf_kvm *kvm, int argc, const char **argv)
+static int __cmd_report(const char *file_name, int argc, const char **argv)
 {
        int rec_argc, i = 0, j;
        const char **rec_argv;
@@ -908,7 +926,7 @@ static int __cmd_report(struct perf_kvm *kvm, int argc, const char **argv)
        rec_argv = calloc(rec_argc + 1, sizeof(char *));
        rec_argv[i++] = strdup("report");
        rec_argv[i++] = strdup("-i");
-       rec_argv[i++] = strdup(kvm->file_name);
+       rec_argv[i++] = strdup(file_name);
        for (j = 1; j < argc; j++, i++)
                rec_argv[i] = argv[j];
 
@@ -917,7 +935,8 @@ static int __cmd_report(struct perf_kvm *kvm, int argc, const char **argv)
        return cmd_report(i, rec_argv, NULL);
 }
 
-static int __cmd_buildid_list(struct perf_kvm *kvm, int argc, const char **argv)
+static int
+__cmd_buildid_list(const char *file_name, int argc, const char **argv)
 {
        int rec_argc, i = 0, j;
        const char **rec_argv;
@@ -926,7 +945,7 @@ static int __cmd_buildid_list(struct perf_kvm *kvm, int argc, const char **argv)
        rec_argv = calloc(rec_argc + 1, sizeof(char *));
        rec_argv[i++] = strdup("buildid-list");
        rec_argv[i++] = strdup("-i");
-       rec_argv[i++] = strdup(kvm->file_name);
+       rec_argv[i++] = strdup(file_name);
        for (j = 1; j < argc; j++, i++)
                rec_argv[i] = argv[j];
 
@@ -937,20 +956,12 @@ static int __cmd_buildid_list(struct perf_kvm *kvm, int argc, const char **argv)
 
 int cmd_kvm(int argc, const char **argv, const char *prefix __maybe_unused)
 {
-       struct perf_kvm kvm = {
-               .trace_vcpu     = -1,
-               .report_event   = "vmexit",
-               .sort_key       = "sample",
-
-               .exit_reasons = svm_exit_reasons,
-               .exit_reasons_size = ARRAY_SIZE(svm_exit_reasons),
-               .exit_reasons_isa = "SVM",
-       };
+       const char *file_name;
 
        const struct option kvm_options[] = {
-               OPT_STRING('i', "input", &kvm.file_name, "file",
+               OPT_STRING('i', "input", &file_name, "file",
                           "Input file name"),
-               OPT_STRING('o', "output", &kvm.file_name, "file",
+               OPT_STRING('o', "output", &file_name, "file",
                           "Output file name"),
                OPT_BOOLEAN(0, "guest", &perf_guest,
                            "Collect guest os data"),
@@ -985,32 +996,34 @@ int cmd_kvm(int argc, const char **argv, const char *prefix __maybe_unused)
        if (!perf_host)
                perf_guest = 1;
 
-       if (!kvm.file_name) {
+       if (!file_name) {
                if (perf_host && !perf_guest)
-                       kvm.file_name = strdup("perf.data.host");
+                       file_name = strdup("perf.data.host");
                else if (!perf_host && perf_guest)
-                       kvm.file_name = strdup("perf.data.guest");
+                       file_name = strdup("perf.data.guest");
                else
-                       kvm.file_name = strdup("perf.data.kvm");
+                       file_name = strdup("perf.data.kvm");
 
-               if (!kvm.file_name) {
+               if (!file_name) {
                        pr_err("Failed to allocate memory for filename\n");
                        return -ENOMEM;
                }
        }
 
        if (!strncmp(argv[0], "rec", 3))
-               return __cmd_record(&kvm, argc, argv);
+               return __cmd_record(file_name, argc, argv);
        else if (!strncmp(argv[0], "rep", 3))
-               return __cmd_report(&kvm, argc, argv);
+               return __cmd_report(file_name, argc, argv);
        else if (!strncmp(argv[0], "diff", 4))
                return cmd_diff(argc, argv, NULL);
        else if (!strncmp(argv[0], "top", 3))
                return cmd_top(argc, argv, NULL);
        else if (!strncmp(argv[0], "buildid-list", 12))
-               return __cmd_buildid_list(&kvm, argc, argv);
+               return __cmd_buildid_list(file_name, argc, argv);
+#if defined(__i386__) || defined(__x86_64__)
        else if (!strncmp(argv[0], "stat", 4))
-               return kvm_cmd_stat(&kvm, argc, argv);
+               return kvm_cmd_stat(file_name, argc, argv);
+#endif
        else
                usage_with_options(kvm_usage, kvm_options);
 
index 484f26cc0c00c6ee80d74e93bddc3fe24eae4c1f..5acd6e8e658bfcae9dad3e3cb9656481a084f450 100644 (file)
@@ -15,7 +15,7 @@
 #include "util/thread_map.h"
 #include "util/pmu.h"
 #include "event-parse.h"
-#include "../../include/linux/hw_breakpoint.h"
+#include <linux/hw_breakpoint.h>
 
 #include <sys/mman.h>
 
index c50985eaec41f479d2593dab749d061d3cb03c3d..238f923f22181698f1610ed8b14f512b76706fb1 100644 (file)
@@ -5,8 +5,9 @@ struct winsize;
 
 void get_term_dimensions(struct winsize *ws);
 
+#include <asm/unistd.h>
+
 #if defined(__i386__)
-#include "../../arch/x86/include/asm/unistd.h"
 #define rmb()          asm volatile("lock; addl $0,0(%%esp)" ::: "memory")
 #define cpu_relax()    asm volatile("rep; nop" ::: "memory");
 #define CPUINFO_PROC   "model name"
@@ -16,7 +17,6 @@ void get_term_dimensions(struct winsize *ws);
 #endif
 
 #if defined(__x86_64__)
-#include "../../arch/x86/include/asm/unistd.h"
 #define rmb()          asm volatile("lfence" ::: "memory")
 #define cpu_relax()    asm volatile("rep; nop" ::: "memory");
 #define CPUINFO_PROC   "model name"
@@ -26,20 +26,17 @@ void get_term_dimensions(struct winsize *ws);
 #endif
 
 #ifdef __powerpc__
-#include "../../arch/powerpc/include/asm/unistd.h"
 #define rmb()          asm volatile ("sync" ::: "memory")
 #define cpu_relax()    asm volatile ("" ::: "memory");
 #define CPUINFO_PROC   "cpu"
 #endif
 
 #ifdef __s390__
-#include "../../arch/s390/include/asm/unistd.h"
 #define rmb()          asm volatile("bcr 15,0" ::: "memory")
 #define cpu_relax()    asm volatile("" ::: "memory");
 #endif
 
 #ifdef __sh__
-#include "../../arch/sh/include/asm/unistd.h"
 #if defined(__SH4A__) || defined(__SH5__)
 # define rmb()         asm volatile("synco" ::: "memory")
 #else
@@ -50,35 +47,30 @@ void get_term_dimensions(struct winsize *ws);
 #endif
 
 #ifdef __hppa__
-#include "../../arch/parisc/include/asm/unistd.h"
 #define rmb()          asm volatile("" ::: "memory")
 #define cpu_relax()    asm volatile("" ::: "memory");
 #define CPUINFO_PROC   "cpu"
 #endif
 
 #ifdef __sparc__
-#include "../../arch/sparc/include/uapi/asm/unistd.h"
 #define rmb()          asm volatile("":::"memory")
 #define cpu_relax()    asm volatile("":::"memory")
 #define CPUINFO_PROC   "cpu"
 #endif
 
 #ifdef __alpha__
-#include "../../arch/alpha/include/asm/unistd.h"
 #define rmb()          asm volatile("mb" ::: "memory")
 #define cpu_relax()    asm volatile("" ::: "memory")
 #define CPUINFO_PROC   "cpu model"
 #endif
 
 #ifdef __ia64__
-#include "../../arch/ia64/include/asm/unistd.h"
 #define rmb()          asm volatile ("mf" ::: "memory")
 #define cpu_relax()    asm volatile ("hint @pause" ::: "memory")
 #define CPUINFO_PROC   "model name"
 #endif
 
 #ifdef __arm__
-#include "../../arch/arm/include/asm/unistd.h"
 /*
  * Use the __kuser_memory_barrier helper in the CPU helper page. See
  * arch/arm/kernel/entry-armv.S in the kernel source for details.
@@ -89,13 +81,11 @@ void get_term_dimensions(struct winsize *ws);
 #endif
 
 #ifdef __aarch64__
-#include "../../arch/arm64/include/asm/unistd.h"
 #define rmb()          asm volatile("dmb ld" ::: "memory")
 #define cpu_relax()    asm volatile("yield" ::: "memory")
 #endif
 
 #ifdef __mips__
-#include "../../arch/mips/include/asm/unistd.h"
 #define rmb()          asm volatile(                                   \
                                ".set   mips2\n\t"                      \
                                "sync\n\t"                              \
@@ -112,7 +102,7 @@ void get_term_dimensions(struct winsize *ws);
 #include <sys/types.h>
 #include <sys/syscall.h>
 
-#include "../../include/uapi/linux/perf_event.h"
+#include <linux/perf_event.h>
 #include "util/types.h"
 #include <stdbool.h>
 
index 618d41140abd368072d9c978f70969233cd70260..d144d464ce39d12eed66e22342ad2ebc2ac8cc7f 100644 (file)
@@ -18,8 +18,8 @@
 #include "cpumap.h"
 #include "thread_map.h"
 #include "target.h"
-#include "../../../include/linux/hw_breakpoint.h"
-#include "../../../include/uapi/linux/perf_event.h"
+#include <linux/hw_breakpoint.h>
+#include <linux/perf_event.h>
 #include "perf_regs.h"
 
 #define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y))
index 6f94d6dea00f4b26efb86533509b4c9dace89737..d99b476ef37c723be395885c3d4d17798873ab6d 100644 (file)
@@ -3,7 +3,8 @@
 
 #include <linux/list.h>
 #include <stdbool.h>
-#include "../../../include/uapi/linux/perf_event.h"
+#include <stddef.h>
+#include <linux/perf_event.h>
 #include "types.h"
 #include "xyarray.h"
 #include "cgroup.h"
index 7daad237dea530f504f764b8189b06957b1905e6..566b84c695c880b43349675780ff88225b2828cc 100644 (file)
@@ -1378,6 +1378,8 @@ static void print_numa_topology(struct perf_header *ph, int fd __maybe_unused,
 
                str = tmp + 1;
                fprintf(fp, "# node%u cpu list : %s\n", c, str);
+
+               str += strlen(str) + 1;
        }
        return;
 error:
index 879d215cdac9007c360fbd4862c2e0d3aaa514e3..9bc00783f24f4648000ee1e10e3b194aec463a22 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef __PERF_HEADER_H
 #define __PERF_HEADER_H
 
-#include "../../../include/uapi/linux/perf_event.h"
+#include <linux/perf_event.h>
 #include <sys/types.h>
 #include <stdbool.h>
 #include "types.h"
index 516ecd9ddd6ee275c1e3144abc8a3d091b6114bb..6ef213b35ecd0bf4c83729f8c71f05c3631716fd 100644 (file)
@@ -3,7 +3,7 @@
 #include "evsel.h"
 #include "evlist.h"
 #include "sysfs.h"
-#include "../../../include/linux/hw_breakpoint.h"
+#include <linux/hw_breakpoint.h>
 
 #define TEST_ASSERT_VAL(text, cond) \
 do { \
index 75c7b0fca6d96baadc7b084c84a73d3f89ea3273..6b6d03e93c3d92790a53d5e67ead9f023a221cd5 100644 (file)
@@ -1,4 +1,4 @@
-#include "../../../include/linux/hw_breakpoint.h"
+#include <linux/hw_breakpoint.h>
 #include "util.h"
 #include "../perf.h"
 #include "evlist.h"
index 839230ceb18bd918b194d0fc719607445ad7bb00..2820c407adb23017dbdcc5139dae3dc7cada738a 100644 (file)
@@ -7,7 +7,7 @@
 #include <linux/list.h>
 #include <stdbool.h>
 #include "types.h"
-#include "../../../include/uapi/linux/perf_event.h"
+#include <linux/perf_event.h>
 #include "types.h"
 
 struct list_head;
index 39f3abac77448021daf35d13f5c8fea57538db49..fdeb8ac7c5d27fee5ee15978edbfd90ce9270054 100644 (file)
@@ -2,7 +2,7 @@
 #define __PMU_H
 
 #include <linux/bitops.h>
-#include "../../../include/uapi/linux/perf_event.h"
+#include <linux/perf_event.h>
 
 enum {
        PERF_PMU_FORMAT_VALUE_CONFIG,
index dd6426163ba6d70332d03a7aeac1205f59e146d4..0eae00ad5fe7ad1e9124cf52f1975c8616451b63 100644 (file)
@@ -7,7 +7,7 @@
 #include "symbol.h"
 #include "thread.h"
 #include <linux/rbtree.h>
-#include "../../../include/uapi/linux/perf_event.h"
+#include <linux/perf_event.h>
 
 struct sample_queue;
 struct ip_callchain;
index 2eeb51baf077f16a84386840dab2539c8512dfb2..cfa906882e2ceb2ed138fb4fd996474324f4d6c3 100644 (file)
@@ -90,17 +90,17 @@ void strbuf_addf(struct strbuf *sb, const char *fmt, ...)
        if (!strbuf_avail(sb))
                strbuf_grow(sb, 64);
        va_start(ap, fmt);
-       len = vscnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap);
+       len = vsnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap);
        va_end(ap);
        if (len < 0)
-               die("your vscnprintf is broken");
+               die("your vsnprintf is broken");
        if (len > strbuf_avail(sb)) {
                strbuf_grow(sb, len);
                va_start(ap, fmt);
-               len = vscnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap);
+               len = vsnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap);
                va_end(ap);
                if (len > strbuf_avail(sb)) {
-                       die("this should not happen, your snprintf is broken");
+                       die("this should not happen, your vsnprintf is broken");
                }
        }
        strbuf_setlen(sb, sb->len + len);
index 96ce80a3743ba22e13935f238e9835aca8923326..2964b96aa55fd350896cd45efc5a9e13538551ad 100644 (file)
@@ -1,8 +1,11 @@
-ifeq ("$(origin O)", "command line")
+ifeq ($(origin O), command line)
        dummy := $(if $(shell test -d $(O) || echo $(O)),$(error O=$(O) does not exist),)
        ABSOLUTE_O := $(shell cd $(O) ; pwd)
-       OUTPUT := $(ABSOLUTE_O)/
+       OUTPUT := $(ABSOLUTE_O)/$(if $(subdir),$(subdir)/)
        COMMAND_O := O=$(ABSOLUTE_O)
+ifeq ($(objtree),)
+       objtree := $(O)
+endif
 endif
 
 ifneq ($(OUTPUT),)
@@ -41,7 +44,16 @@ else
 NO_SUBDIR = :
 endif
 
-QUIET_SUBDIR0  = +$(MAKE) -C # space to separate -C and subdir
+#
+# Define a callable command for descending to a new directory
+#
+# Call by doing: $(call descend,directory[,target])
+#
+descend = \
+       +mkdir -p $(OUTPUT)$(1) && \
+       $(MAKE) $(COMMAND_O) subdir=$(if $(subdir),$(subdir)/$(1),$(1)) $(PRINT_DIR) -C $(1) $(2)
+
+QUIET_SUBDIR0  = +$(MAKE) $(COMMAND_O) -C # space to separate -C and subdir
 QUIET_SUBDIR1  =
 
 ifneq ($(findstring $(MAKEFLAGS),s),s)
@@ -56,5 +68,10 @@ ifndef V
                         $(MAKE) $(PRINT_DIR) -C $$subdir
        QUIET_FLEX     = @echo '   ' FLEX $@;
        QUIET_BISON    = @echo '   ' BISON $@;
+
+       descend = \
+               @echo '   ' DESCEND $(1); \
+               mkdir -p $(OUTPUT)$(1) && \
+               $(MAKE) $(COMMAND_O) subdir=$(if $(subdir),$(subdir)/$(1),$(1)) $(PRINT_DIR) -C $(1) $(2)
 endif
 endif