]> Pileus Git - ~andy/linux/commitdiff
Merge branch 'sched-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 19 Dec 2013 17:11:22 +0000 (09:11 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 19 Dec 2013 17:11:22 +0000 (09:11 -0800)
Pull scheduler fixes from Ingo Molnar:
 "An RT group-scheduling fix and the sched-domains topology setup fix
  from Mel"

* 'sched-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  sched/rt: Fix rq's cpupri leak while enqueue/dequeue child RT entities
  sched: Assign correct scheduling domain to 'sd_llc'

538 files changed:
Documentation/DocBook/media/v4l/vidioc-expbuf.xml
Documentation/assoc_array.txt
Documentation/device-mapper/cache.txt
Documentation/devicetree/bindings/net/davinci_emac.txt
Documentation/devicetree/bindings/net/smsc-lan91c111.txt
Documentation/module-signing.txt [new file with mode: 0644]
Documentation/networking/ip-sysctl.txt
Documentation/networking/packet_mmap.txt
MAINTAINERS
Makefile
arch/arc/Kconfig
arch/arc/include/uapi/asm/unistd.h
arch/arc/kernel/perf_event.c
arch/arm/boot/dts/am3517-evm.dts
arch/arm/boot/dts/am3517.dtsi [new file with mode: 0644]
arch/arm/boot/dts/omap3-n900.dts
arch/arm/boot/dts/omap3-n950-n9.dtsi
arch/arm/boot/dts/omap34xx-hs.dtsi [new file with mode: 0644]
arch/arm/boot/dts/omap36xx-hs.dtsi [new file with mode: 0644]
arch/arm/boot/dts/sun6i-a31.dtsi
arch/arm/boot/dts/sun7i-a20.dtsi
arch/arm/include/asm/memory.h
arch/arm/kernel/head-nommu.S
arch/arm/kernel/head.S
arch/arm/kernel/process.c
arch/arm/kernel/setup.c
arch/arm/kernel/stacktrace.c
arch/arm/kernel/traps.c
arch/arm/mach-davinci/devices-da8xx.c
arch/arm/mach-davinci/dm355.c
arch/arm/mach-davinci/dm365.c
arch/arm/mach-davinci/dm644x.c
arch/arm/mach-davinci/dm646x.c
arch/arm/mach-highbank/highbank.c
arch/arm/mach-omap2/board-generic.c
arch/arm/mach-omap2/omap_device.c
arch/arm/mach-omap2/omap_device.h
arch/arm/mach-omap2/omap_hwmod.c
arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
arch/arm/mach-omap2/omap_hwmod_44xx_data.c
arch/arm/mach-omap2/omap_hwmod_54xx_data.c
arch/arm/mach-pxa/reset.c
arch/arm/mach-pxa/tosa.c
arch/arm/mach-tegra/fuse.c
arch/arm/mm/dma-mapping.c
arch/arm/mm/init.c
arch/avr32/boards/favr-32/setup.c
arch/avr32/configs/atngw100_defconfig
arch/avr32/configs/atngw100_evklcd100_defconfig
arch/avr32/configs/atngw100_evklcd101_defconfig
arch/avr32/configs/atngw100_mrmt_defconfig
arch/avr32/configs/atngw100mkii_defconfig
arch/avr32/configs/atngw100mkii_evklcd100_defconfig
arch/avr32/configs/atngw100mkii_evklcd101_defconfig
arch/avr32/configs/atstk1002_defconfig
arch/avr32/configs/atstk1003_defconfig
arch/avr32/configs/atstk1004_defconfig
arch/avr32/configs/atstk1006_defconfig
arch/avr32/configs/favr-32_defconfig
arch/avr32/configs/hammerhead_defconfig
arch/avr32/configs/merisc_defconfig
arch/avr32/configs/mimc200_defconfig
arch/avr32/kernel/time.c
arch/avr32/mach-at32ap/pm.c
arch/powerpc/include/asm/opal.h
arch/powerpc/kernel/crash_dump.c
arch/powerpc/kernel/ptrace.c
arch/powerpc/kernel/setup-common.c
arch/powerpc/kernel/smp.c
arch/powerpc/platforms/powernv/opal-lpc.c
arch/powerpc/platforms/powernv/opal-xscom.c
arch/powerpc/platforms/pseries/lparcfg.c
arch/powerpc/platforms/pseries/msi.c
arch/powerpc/platforms/pseries/nvram.c
arch/powerpc/platforms/pseries/pci.c
arch/s390/Kconfig
arch/s390/include/asm/sclp.h
arch/s390/kernel/asm-offsets.c
arch/s390/kernel/vdso.c
arch/s390/kernel/vdso32/clock_gettime.S
arch/s390/kernel/vdso64/clock_getres.S
arch/s390/kernel/vdso64/clock_gettime.S
arch/sh/lib/Makefile
arch/sparc/include/asm/pgtable_64.h
arch/x86/Makefile
arch/x86/boot/Makefile
arch/x86/boot/compressed/Makefile
arch/x86/include/asm/pgtable.h
arch/x86/kernel/cpu/perf_event.h
arch/x86/kvm/lapic.c
arch/x86/kvm/lapic.h
arch/x86/kvm/x86.c
arch/x86/mm/gup.c
arch/x86/platform/efi/efi.c
arch/x86/platform/uv/tlb_uv.c
arch/x86/realmode/rm/Makefile
drivers/base/regmap/regmap-mmio.c
drivers/base/regmap/regmap.c
drivers/block/null_blk.c
drivers/clk/clk-s2mps11.c
drivers/clocksource/Kconfig
drivers/clocksource/clksrc-of.c
drivers/clocksource/dw_apb_timer_of.c
drivers/clocksource/sun4i_timer.c
drivers/clocksource/time-armada-370-xp.c
drivers/cpufreq/at32ap-cpufreq.c
drivers/dma/amba-pl08x.c
drivers/dma/mmp_pdma.c
drivers/dma/s3c24xx-dma.c
drivers/dma/sh/rcar-hpbdma.c
drivers/edac/sb_edac.c
drivers/gpio/gpio-davinci.c
drivers/gpio/gpio-msm-v2.c
drivers/gpio/gpio-rcar.c
drivers/gpio/gpio-twl4030.c
drivers/gpu/drm/armada/armada_drm.h
drivers/gpu/drm/armada/armada_drv.c
drivers/gpu/drm/armada/armada_fbdev.c
drivers/gpu/drm/armada/armada_gem.c
drivers/gpu/drm/drm_edid.c
drivers/gpu/drm/drm_stub.c
drivers/gpu/drm/i915/i915_dma.c
drivers/gpu/drm/i915/i915_drv.c
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_gem_context.c
drivers/gpu/drm/i915/i915_gem_evict.c
drivers/gpu/drm/i915/i915_gem_gtt.c
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_drv.h
drivers/gpu/drm/i915/intel_panel.c
drivers/gpu/drm/i915/intel_pm.c
drivers/gpu/drm/i915/intel_ringbuffer.c
drivers/gpu/drm/i915/intel_uncore.c
drivers/gpu/drm/nouveau/nouveau_drm.c
drivers/gpu/drm/radeon/atombios_crtc.c
drivers/gpu/drm/radeon/cik_sdma.c
drivers/gpu/drm/radeon/radeon_asic.c
drivers/gpu/drm/radeon/radeon_drv.c
drivers/gpu/drm/radeon/radeon_pm.c
drivers/gpu/drm/radeon/rs690.c
drivers/gpu/drm/ttm/ttm_bo_vm.c
drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c
drivers/hid/hid-kye.c
drivers/hid/hid-sensor-hub.c
drivers/hwmon/hih6130.c
drivers/hwmon/lm78.c
drivers/hwmon/lm90.c
drivers/hwmon/sis5595.c
drivers/hwmon/vt8231.c
drivers/hwmon/w83l786ng.c
drivers/i2c/busses/i2c-imx.c
drivers/i2c/i2c-mux.c
drivers/iio/adc/ad7887.c
drivers/iio/imu/adis16400_core.c
drivers/iio/light/cm36651.c
drivers/input/misc/adxl34x.c
drivers/input/serio/serio.c
drivers/iommu/arm-smmu.c
drivers/md/dm-bufio.c
drivers/md/dm-cache-policy-mq.c
drivers/md/dm-cache-target.c
drivers/md/dm-delay.c
drivers/md/dm-snap.c
drivers/md/dm-stats.c
drivers/md/dm-table.c
drivers/md/dm-thin-metadata.c
drivers/md/dm-thin-metadata.h
drivers/md/dm-thin.c
drivers/md/persistent-data/dm-array.c
drivers/md/persistent-data/dm-block-manager.c
drivers/md/persistent-data/dm-block-manager.h
drivers/md/persistent-data/dm-space-map-common.c
drivers/md/persistent-data/dm-space-map-metadata.c
drivers/media/common/siano/smscoreapi.h
drivers/media/common/siano/smsdvb.h
drivers/media/dvb-core/dvb_demux.c
drivers/media/dvb-frontends/af9033.c
drivers/media/dvb-frontends/cxd2820r_c.c
drivers/media/dvb-frontends/dib8000.c
drivers/media/dvb-frontends/drxk_hard.c
drivers/media/dvb-frontends/rtl2830.c
drivers/media/i2c/adv7183_regs.h
drivers/media/i2c/adv7604.c
drivers/media/i2c/adv7842.c
drivers/media/i2c/ir-kbd-i2c.c
drivers/media/i2c/m5mols/m5mols_controls.c
drivers/media/i2c/mt9p031.c
drivers/media/i2c/s5c73m3/s5c73m3-core.c
drivers/media/i2c/s5c73m3/s5c73m3.h
drivers/media/i2c/saa7115.c
drivers/media/i2c/soc_camera/ov5642.c
drivers/media/i2c/ths7303.c
drivers/media/i2c/wm8775.c
drivers/media/pci/bt8xx/bttv-driver.c
drivers/media/pci/cx18/cx18-driver.h
drivers/media/pci/cx23885/cx23885-417.c
drivers/media/pci/pluto2/pluto2.c
drivers/media/pci/saa7164/saa7164-core.c
drivers/media/platform/coda.c
drivers/media/platform/exynos4-is/fimc-core.c
drivers/media/platform/exynos4-is/media-dev.c
drivers/media/platform/marvell-ccic/mmp-driver.c
drivers/media/platform/omap3isp/isp.c
drivers/media/platform/omap3isp/ispvideo.c
drivers/media/platform/s5p-mfc/regs-mfc.h
drivers/media/platform/s5p-mfc/s5p_mfc.c
drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c
drivers/media/platform/s5p-tv/mixer.h
drivers/media/platform/s5p-tv/mixer_video.c
drivers/media/platform/soc_camera/omap1_camera.c
drivers/media/platform/vivi.c
drivers/media/platform/vsp1/vsp1_drv.c
drivers/media/platform/vsp1/vsp1_video.c
drivers/media/radio/radio-shark.c
drivers/media/radio/radio-shark2.c
drivers/media/radio/radio-si476x.c
drivers/media/radio/radio-tea5764.c
drivers/media/radio/tef6862.c
drivers/media/rc/imon.c
drivers/media/rc/redrat3.c
drivers/media/tuners/mt2063.c
drivers/media/tuners/tuner-xc2028-types.h
drivers/media/usb/cx231xx/cx231xx-cards.c
drivers/media/usb/dvb-usb-v2/af9035.c
drivers/media/usb/dvb-usb-v2/mxl111sf.c
drivers/media/usb/dvb-usb/technisat-usb2.c
drivers/media/usb/em28xx/em28xx-video.c
drivers/media/usb/gspca/gl860/gl860.c
drivers/media/usb/gspca/pac207.c
drivers/media/usb/gspca/pac7302.c
drivers/media/usb/gspca/stk1135.c
drivers/media/usb/gspca/stv0680.c
drivers/media/usb/gspca/sunplus.c
drivers/media/usb/gspca/zc3xx.c
drivers/media/usb/pwc/pwc-if.c
drivers/media/usb/usbtv/usbtv.c
drivers/media/usb/uvc/uvc_video.c
drivers/media/v4l2-core/v4l2-ctrls.c
drivers/media/v4l2-core/videobuf2-core.c
drivers/media/v4l2-core/videobuf2-dma-contig.c
drivers/media/v4l2-core/videobuf2-dma-sg.c
drivers/mfd/sec-core.c
drivers/mfd/sec-irq.c
drivers/mtd/nand/pxa3xx_nand.c
drivers/net/bonding/bond_main.c
drivers/net/bonding/bond_sysfs.c
drivers/net/can/usb/ems_usb.c
drivers/net/can/usb/peak_usb/pcan_usb_pro.c
drivers/net/ethernet/allwinner/sun4i-emac.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
drivers/net/ethernet/broadcom/tg3.c
drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
drivers/net/ethernet/chelsio/cxgb4/sge.c
drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
drivers/net/ethernet/chelsio/cxgb4/t4_regs.h
drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h
drivers/net/ethernet/chelsio/cxgb4vf/adapter.h
drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c
drivers/net/ethernet/chelsio/cxgb4vf/sge.c
drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h
drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c
drivers/net/ethernet/emulex/benet/be_hw.h
drivers/net/ethernet/emulex/benet/be_main.c
drivers/net/ethernet/freescale/fec_main.c
drivers/net/ethernet/ibm/ehea/ehea_main.c
drivers/net/ethernet/intel/i40e/i40e_main.c
drivers/net/ethernet/intel/igb/e1000_phy.c
drivers/net/ethernet/marvell/mvneta.c
drivers/net/ethernet/mellanox/mlx4/main.c
drivers/net/ethernet/nvidia/forcedeth.c
drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c
drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
drivers/net/ethernet/qlogic/qlge/qlge.h
drivers/net/ethernet/qlogic/qlge/qlge_ethtool.c
drivers/net/ethernet/qlogic/qlge/qlge_main.c
drivers/net/ethernet/sfc/efx.c
drivers/net/ethernet/sfc/mcdi.c
drivers/net/ethernet/sfc/net_driver.h
drivers/net/ethernet/sfc/nic.h
drivers/net/ethernet/sfc/ptp.c
drivers/net/ethernet/sfc/rx.c
drivers/net/ethernet/smsc/smc91x.c
drivers/net/ethernet/tehuti/tehuti.c
drivers/net/ethernet/ti/cpsw.c
drivers/net/ethernet/ti/davinci_emac.c
drivers/net/ethernet/xilinx/ll_temac_main.c
drivers/net/ethernet/xilinx/xilinx_axienet_main.c
drivers/net/ethernet/xilinx/xilinx_emaclite.c
drivers/net/hyperv/netvsc_drv.c
drivers/net/macvtap.c
drivers/net/phy/micrel.c
drivers/net/tun.c
drivers/net/virtio_net.c
drivers/net/vxlan.c
drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
drivers/net/wireless/ath/ath9k/hw.c
drivers/net/wireless/ath/ath9k/xmit.c
drivers/net/wireless/ath/wcn36xx/smd.c
drivers/net/wireless/brcm80211/Kconfig
drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
drivers/net/wireless/iwlwifi/iwl-7000.c
drivers/net/wireless/iwlwifi/iwl-config.h
drivers/net/wireless/iwlwifi/iwl-csr.h
drivers/net/wireless/iwlwifi/mvm/bt-coex.c
drivers/net/wireless/iwlwifi/mvm/d3.c
drivers/net/wireless/iwlwifi/mvm/debugfs.c
drivers/net/wireless/iwlwifi/mvm/time-event.c
drivers/net/wireless/iwlwifi/pcie/drv.c
drivers/net/wireless/iwlwifi/pcie/internal.h
drivers/net/wireless/iwlwifi/pcie/rx.c
drivers/net/wireless/iwlwifi/pcie/trans.c
drivers/net/wireless/iwlwifi/pcie/tx.c
drivers/net/wireless/mac80211_hwsim.c
drivers/net/wireless/mwifiex/sta_ioctl.c
drivers/net/xen-netback/interface.c
drivers/net/xen-netback/netback.c
drivers/pci/host/pci-mvebu.c
drivers/pci/pci-driver.c
drivers/pci/pci.c
drivers/pci/remove.c
drivers/phy/Kconfig
drivers/phy/phy-core.c
drivers/pinctrl/sh-pfc/sh_pfc.h
drivers/regulator/as3722-regulator.c
drivers/regulator/core.c
drivers/regulator/pfuze100-regulator.c
drivers/regulator/s2mps11.c
drivers/regulator/s5m8767.c
drivers/rtc/rtc-at91rm9200.c
drivers/rtc/rtc-s5m.c
drivers/s390/block/dasd_genhd.c
drivers/s390/char/sclp_early.c
drivers/staging/comedi/drivers.c
drivers/staging/comedi/drivers/8255_pci.c
drivers/staging/iio/magnetometer/hmc5843.c
drivers/staging/imx-drm/imx-drm-core.c
drivers/staging/imx-drm/imx-tve.c
drivers/staging/imx-drm/ipu-v3/ipu-common.c
drivers/tty/n_tty.c
drivers/tty/serial/8250/8250_dw.c
drivers/tty/serial/xilinx_uartps.c
drivers/tty/tty_ldsem.c
drivers/usb/chipidea/core.c
drivers/usb/chipidea/host.c
drivers/usb/chipidea/udc.c
drivers/usb/class/cdc-wdm.c
drivers/usb/dwc3/core.c
drivers/usb/host/ohci-at91.c
drivers/usb/host/xhci-pci.c
drivers/usb/phy/Kconfig
drivers/usb/phy/phy-tegra-usb.c
drivers/usb/phy/phy-twl6030-usb.c
drivers/usb/serial/option.c
drivers/usb/serial/zte_ev.c
drivers/watchdog/bcm2835_wdt.c
drivers/watchdog/ep93xx_wdt.c
drivers/watchdog/ie6xx_wdt.c
drivers/watchdog/jz4740_wdt.c
drivers/watchdog/kempld_wdt.c
drivers/watchdog/max63xx_wdt.c
drivers/watchdog/orion_wdt.c
drivers/watchdog/pnx4008_wdt.c
drivers/watchdog/rt2880_wdt.c
drivers/watchdog/sc1200wdt.c
drivers/watchdog/shwdt.c
drivers/watchdog/softdog.c
drivers/watchdog/stmp3xxx_rtc_wdt.c
drivers/watchdog/txx9wdt.c
drivers/watchdog/ux500_wdt.c
fs/btrfs/extent-tree.c
fs/btrfs/ioctl.c
fs/btrfs/relocation.c
fs/btrfs/send.c
fs/btrfs/super.c
fs/ceph/addr.c
fs/ceph/inode.c
fs/dcache.c
fs/namei.c
fs/nfsd/nfscache.c
fs/proc/inode.c
fs/sysfs/file.c
fs/xfs/xfs_discard.c
fs/xfs/xfs_fsops.c
fs/xfs/xfs_ioctl.c
fs/xfs/xfs_ioctl32.c
include/asm-generic/pgtable.h
include/asm-generic/word-at-a-time.h
include/linux/assoc_array.h
include/linux/compiler-intel.h
include/linux/dcache.h
include/linux/hugetlb.h
include/linux/ipv6.h
include/linux/kernel.h
include/linux/kexec.h
include/linux/mfd/samsung/core.h
include/linux/micrel_phy.h
include/linux/migrate.h
include/linux/mm_types.h
include/linux/net.h
include/linux/netdevice.h
include/linux/pci.h
include/linux/reboot.h
include/linux/shmem_fs.h
include/linux/skbuff.h
include/media/videobuf2-core.h
include/net/ipv6.h
include/net/sctp/structs.h
include/net/sock.h
include/sound/memalloc.h
include/uapi/drm/vmwgfx_drm.h
include/uapi/linux/perf_event.h
include/uapi/sound/compress_offload.h
kernel/.gitignore
kernel/Makefile
kernel/events/core.c
kernel/fork.c
kernel/futex.c
kernel/kexec.c
kernel/reboot.c
kernel/sched/fair.c
kernel/system_certificates.S
kernel/system_keyring.c
kernel/user.c
kernel/workqueue.c
lib/assoc_array.c
mm/Kconfig
mm/compaction.c
mm/huge_memory.c
mm/memcontrol.c
mm/memory-failure.c
mm/mempolicy.c
mm/migrate.c
mm/mprotect.c
mm/page_alloc.c
mm/pgtable-generic.c
mm/rmap.c
mm/shmem.c
net/bridge/br_private.h
net/bridge/br_stp_bpdu.c
net/core/drop_monitor.c
net/core/neighbour.c
net/core/skbuff.c
net/core/sock.c
net/dccp/ipv6.c
net/ipv4/fib_rules.c
net/ipv4/netfilter/ipt_SYNPROXY.c
net/ipv4/netfilter/nft_reject_ipv4.c
net/ipv4/tcp_memcontrol.c
net/ipv4/udp.c
net/ipv6/addrconf.c
net/ipv6/datagram.c
net/ipv6/fib6_rules.c
net/ipv6/ndisc.c
net/ipv6/netfilter/ip6t_SYNPROXY.c
net/ipv6/raw.c
net/ipv6/route.c
net/ipv6/tcp_ipv6.c
net/ipv6/udp.c
net/l2tp/l2tp_ip6.c
net/mac80211/cfg.c
net/mac80211/ibss.c
net/mac80211/ieee80211_i.h
net/mac80211/iface.c
net/mac80211/main.c
net/mac80211/mesh.c
net/mac80211/mlme.c
net/mac80211/rc80211_minstrel_ht.c
net/mac80211/rx.c
net/mac80211/scan.c
net/mac80211/spectmgmt.c
net/mac80211/util.c
net/netfilter/ipset/ip_set_hash_netnet.c
net/netfilter/nf_tables_api.c
net/netfilter/xt_hashlimit.c
net/packet/af_packet.c
net/rds/ib_send.c
net/sched/act_api.c
net/sched/act_csum.c
net/sched/act_gact.c
net/sched/act_ipt.c
net/sched/act_mirred.c
net/sched/act_nat.c
net/sched/act_pedit.c
net/sched/act_police.c
net/sched/act_simple.c
net/sched/act_skbedit.c
net/sched/sch_htb.c
net/sched/sch_tbf.c
net/sctp/associola.c
net/sctp/output.c
net/sctp/probe.c
net/sctp/sm_statefuns.c
net/sctp/socket.c
net/sctp/sysctl.c
net/sctp/transport.c
net/tipc/core.c
net/tipc/handler.c
net/unix/af_unix.c
net/wireless/core.c
net/wireless/ibss.c
net/wireless/nl80211.c
scripts/sortextable.c
security/keys/big_key.c
security/keys/key.c
security/keys/keyring.c
security/selinux/hooks.c
security/selinux/include/xfrm.h
security/selinux/ss/services.c
security/selinux/xfrm.c
sound/core/pcm_lib.c
sound/pci/hda/hda_generic.c
sound/pci/hda/hda_generic.h
sound/pci/hda/hda_intel.c
sound/pci/hda/patch_analog.c
sound/pci/hda/patch_conexant.c
sound/pci/hda/patch_hdmi.c
sound/pci/hda/patch_realtek.c
sound/soc/atmel/atmel_ssc_dai.c
sound/soc/atmel/sam9x5_wm8731.c
sound/soc/codecs/wm5110.c
sound/soc/codecs/wm8904.c
sound/soc/codecs/wm8962.c
sound/soc/codecs/wm_adsp.c
sound/soc/fsl/imx-wm8962.c
sound/soc/kirkwood/kirkwood-i2s.c
sound/soc/soc-generic-dmaengine-pcm.c
sound/soc/soc-pcm.c
sound/soc/tegra/tegra20_i2s.c
sound/soc/tegra/tegra20_spdif.c
sound/soc/tegra/tegra30_i2s.c
sound/usb/mixer_quirks.c
tools/power/cpupower/utils/cpupower-set.c
virt/kvm/kvm_main.c

index e287c8fc803b437ce34550ba88777183f66ca0cc..4165e7bfa4ff7560c0283213e53a54b1575ab2e8 100644 (file)
@@ -73,7 +73,8 @@ range from zero to the maximal number of valid planes for the currently active
 format. For the single-planar API, applications must set <structfield> plane
 </structfield> to zero.  Additional flags may be posted in the <structfield>
 flags </structfield> field.  Refer to a manual for open() for details.
-Currently only O_CLOEXEC is supported.  All other fields must be set to zero.
+Currently only O_CLOEXEC, O_RDONLY, O_WRONLY, and O_RDWR are supported.  All
+other fields must be set to zero.
 In the case of multi-planar API, every plane is exported separately using
 multiple <constant> VIDIOC_EXPBUF </constant> calls. </para>
 
@@ -170,8 +171,9 @@ multi-planar API. Otherwise this value must be set to zero. </entry>
            <entry>__u32</entry>
            <entry><structfield>flags</structfield></entry>
            <entry>Flags for the newly created file, currently only <constant>
-O_CLOEXEC </constant> is supported, refer to the manual of open() for more
-details.</entry>
+O_CLOEXEC </constant>, <constant>O_RDONLY</constant>, <constant>O_WRONLY
+</constant>, and <constant>O_RDWR</constant> are supported, refer to the manual
+of open() for more details.</entry>
          </row>
          <row>
            <entry>__s32</entry>
index f4faec0f66e400dc18c176eb7c567dd2aa18f761..2f2c6cdd73c0c24ab29dcd3f68034f99f17c3125 100644 (file)
@@ -164,10 +164,10 @@ This points to a number of methods, all of which need to be provided:
 
  (4) Diff the index keys of two objects.
 
-       int (*diff_objects)(const void *a, const void *b);
+       int (*diff_objects)(const void *object, const void *index_key);
 
-     Return the bit position at which the index keys of two objects differ or
-     -1 if they are the same.
+     Return the bit position at which the index key of the specified object
+     differs from the given index key or -1 if they are the same.
 
 
  (5) Free an object.
index 274752f8bdf963b0f1757f2df446f6c5a503c6a5..719320b5ed3f36f476bd019781b774c3b4b8ace6 100644 (file)
@@ -266,10 +266,12 @@ E.g.
 Invalidation is removing an entry from the cache without writing it
 back.  Cache blocks can be invalidated via the invalidate_cblocks
 message, which takes an arbitrary number of cblock ranges.  Each cblock
-must be expressed as a decimal value, in the future a variant message
-that takes cblock ranges expressed in hexidecimal may be needed to
-better support efficient invalidation of larger caches.  The cache must
-be in passthrough mode when invalidate_cblocks is used.
+range's end value is "one past the end", meaning 5-10 expresses a range
+of values from 5 to 9.  Each cblock must be expressed as a decimal
+value, in the future a variant message that takes cblock ranges
+expressed in hexidecimal may be needed to better support efficient
+invalidation of larger caches.  The cache must be in passthrough mode
+when invalidate_cblocks is used.
 
    invalidate_cblocks [<cblock>|<cblock begin>-<cblock end>]*
 
index 48b259e29e873f71f3ccfd0a6877bffa609ebd39..bad381faf036e936d9d99a6baff5d1e053cc2cdd 100644 (file)
@@ -4,7 +4,7 @@ This file provides information, what the device node
 for the davinci_emac interface contains.
 
 Required properties:
-- compatible: "ti,davinci-dm6467-emac";
+- compatible: "ti,davinci-dm6467-emac" or "ti,am3517-emac"
 - reg: Offset and length of the register set for the device
 - ti,davinci-ctrl-reg-offset: offset to control register
 - ti,davinci-ctrl-mod-reg-offset: offset to control module register
index 953049b4248a71f4c242d56432730e5ae4c7fbc3..5a41a8658daa12087678a7d81f5f60038cbeddf8 100644 (file)
@@ -8,3 +8,7 @@ Required properties:
 Optional properties:
 - phy-device : phandle to Ethernet phy
 - local-mac-address : Ethernet mac address to use
+- reg-io-width : Mask of sizes (in bytes) of the IO accesses that
+  are supported on the device.  Valid value for SMSC LAN91c111 are
+  1, 2 or 4.  If it's omitted or invalid, the size would be 2 meaning
+  16-bit access only.
diff --git a/Documentation/module-signing.txt b/Documentation/module-signing.txt
new file mode 100644 (file)
index 0000000..2b40e04
--- /dev/null
@@ -0,0 +1,240 @@
+                       ==============================
+                       KERNEL MODULE SIGNING FACILITY
+                       ==============================
+
+CONTENTS
+
+ - Overview.
+ - Configuring module signing.
+ - Generating signing keys.
+ - Public keys in the kernel.
+ - Manually signing modules.
+ - Signed modules and stripping.
+ - Loading signed modules.
+ - Non-valid signatures and unsigned modules.
+ - Administering/protecting the private key.
+
+
+========
+OVERVIEW
+========
+
+The kernel module signing facility cryptographically signs modules during
+installation and then checks the signature upon loading the module.  This
+allows increased kernel security by disallowing the loading of unsigned modules
+or modules signed with an invalid key.  Module signing increases security by
+making it harder to load a malicious module into the kernel.  The module
+signature checking is done by the kernel so that it is not necessary to have
+trusted userspace bits.
+
+This facility uses X.509 ITU-T standard certificates to encode the public keys
+involved.  The signatures are not themselves encoded in any industrial standard
+type.  The facility currently only supports the RSA public key encryption
+standard (though it is pluggable and permits others to be used).  The possible
+hash algorithms that can be used are SHA-1, SHA-224, SHA-256, SHA-384, and
+SHA-512 (the algorithm is selected by data in the signature).
+
+
+==========================
+CONFIGURING MODULE SIGNING
+==========================
+
+The module signing facility is enabled by going to the "Enable Loadable Module
+Support" section of the kernel configuration and turning on
+
+       CONFIG_MODULE_SIG       "Module signature verification"
+
+This has a number of options available:
+
+ (1) "Require modules to be validly signed" (CONFIG_MODULE_SIG_FORCE)
+
+     This specifies how the kernel should deal with a module that has a
+     signature for which the key is not known or a module that is unsigned.
+
+     If this is off (ie. "permissive"), then modules for which the key is not
+     available and modules that are unsigned are permitted, but the kernel will
+     be marked as being tainted.
+
+     If this is on (ie. "restrictive"), only modules that have a valid
+     signature that can be verified by a public key in the kernel's possession
+     will be loaded.  All other modules will generate an error.
+
+     Irrespective of the setting here, if the module has a signature block that
+     cannot be parsed, it will be rejected out of hand.
+
+
+ (2) "Automatically sign all modules" (CONFIG_MODULE_SIG_ALL)
+
+     If this is on then modules will be automatically signed during the
+     modules_install phase of a build.  If this is off, then the modules must
+     be signed manually using:
+
+       scripts/sign-file
+
+
+ (3) "Which hash algorithm should modules be signed with?"
+
+     This presents a choice of which hash algorithm the installation phase will
+     sign the modules with:
+
+       CONFIG_SIG_SHA1         "Sign modules with SHA-1"
+       CONFIG_SIG_SHA224       "Sign modules with SHA-224"
+       CONFIG_SIG_SHA256       "Sign modules with SHA-256"
+       CONFIG_SIG_SHA384       "Sign modules with SHA-384"
+       CONFIG_SIG_SHA512       "Sign modules with SHA-512"
+
+     The algorithm selected here will also be built into the kernel (rather
+     than being a module) so that modules signed with that algorithm can have
+     their signatures checked without causing a dependency loop.
+
+
+=======================
+GENERATING SIGNING KEYS
+=======================
+
+Cryptographic keypairs are required to generate and check signatures.  A
+private key is used to generate a signature and the corresponding public key is
+used to check it.  The private key is only needed during the build, after which
+it can be deleted or stored securely.  The public key gets built into the
+kernel so that it can be used to check the signatures as the modules are
+loaded.
+
+Under normal conditions, the kernel build will automatically generate a new
+keypair using openssl if one does not exist in the files:
+
+       signing_key.priv
+       signing_key.x509
+
+during the building of vmlinux (the public part of the key needs to be built
+into vmlinux) using parameters in the:
+
+       x509.genkey
+
+file (which is also generated if it does not already exist).
+
+It is strongly recommended that you provide your own x509.genkey file.
+
+Most notably, in the x509.genkey file, the req_distinguished_name section
+should be altered from the default:
+
+       [ req_distinguished_name ]
+       O = Magrathea
+       CN = Glacier signing key
+       emailAddress = slartibartfast@magrathea.h2g2
+
+The generated RSA key size can also be set with:
+
+       [ req ]
+       default_bits = 4096
+
+
+It is also possible to manually generate the key private/public files using the
+x509.genkey key generation configuration file in the root node of the Linux
+kernel sources tree and the openssl command.  The following is an example to
+generate the public/private key files:
+
+       openssl req -new -nodes -utf8 -sha256 -days 36500 -batch -x509 \
+          -config x509.genkey -outform DER -out signing_key.x509 \
+          -keyout signing_key.priv
+
+
+=========================
+PUBLIC KEYS IN THE KERNEL
+=========================
+
+The kernel contains a ring of public keys that can be viewed by root.  They're
+in a keyring called ".system_keyring" that can be seen by:
+
+       [root@deneb ~]# cat /proc/keys
+       ...
+       223c7853 I------     1 perm 1f030000     0     0 keyring   .system_keyring: 1
+       302d2d52 I------     1 perm 1f010000     0     0 asymmetri Fedora kernel signing key: d69a84e6bce3d216b979e9505b3e3ef9a7118079: X509.RSA a7118079 []
+       ...
+
+Beyond the public key generated specifically for module signing, any file
+placed in the kernel source root directory or the kernel build root directory
+whose name is suffixed with ".x509" will be assumed to be an X.509 public key
+and will be added to the keyring.
+
+Further, the architecture code may take public keys from a hardware store and
+add those in also (e.g. from the UEFI key database).
+
+Finally, it is possible to add additional public keys by doing:
+
+       keyctl padd asymmetric "" [.system_keyring-ID] <[key-file]
+
+e.g.:
+
+       keyctl padd asymmetric "" 0x223c7853 <my_public_key.x509
+
+Note, however, that the kernel will only permit keys to be added to
+.system_keyring _if_ the new key's X.509 wrapper is validly signed by a key
+that is already resident in the .system_keyring at the time the key was added.
+
+
+=========================
+MANUALLY SIGNING MODULES
+=========================
+
+To manually sign a module, use the scripts/sign-file tool available in
+the Linux kernel source tree.  The script requires 4 arguments:
+
+       1.  The hash algorithm (e.g., sha256)
+       2.  The private key filename
+       3.  The public key filename
+       4.  The kernel module to be signed
+
+The following is an example to sign a kernel module:
+
+       scripts/sign-file sha512 kernel-signkey.priv \
+               kernel-signkey.x509 module.ko
+
+The hash algorithm used does not have to match the one configured, but if it
+doesn't, you should make sure that hash algorithm is either built into the
+kernel or can be loaded without requiring itself.
+
+
+============================
+SIGNED MODULES AND STRIPPING
+============================
+
+A signed module has a digital signature simply appended at the end.  The string
+"~Module signature appended~." at the end of the module's file confirms that a
+signature is present but it does not confirm that the signature is valid!
+
+Signed modules are BRITTLE as the signature is outside of the defined ELF
+container.  Thus they MAY NOT be stripped once the signature is computed and
+attached.  Note the entire module is the signed payload, including any and all
+debug information present at the time of signing.
+
+
+======================
+LOADING SIGNED MODULES
+======================
+
+Modules are loaded with insmod, modprobe, init_module() or finit_module(),
+exactly as for unsigned modules as no processing is done in userspace.  The
+signature checking is all done within the kernel.
+
+
+=========================================
+NON-VALID SIGNATURES AND UNSIGNED MODULES
+=========================================
+
+If CONFIG_MODULE_SIG_FORCE is enabled or enforcemodulesig=1 is supplied on
+the kernel command line, the kernel will only load validly signed modules
+for which it has a public key.   Otherwise, it will also load modules that are
+unsigned.   Any module for which the kernel has a key, but which proves to have
+a signature mismatch will not be permitted to load.
+
+Any module that has an unparseable signature will be rejected.
+
+
+=========================================
+ADMINISTERING/PROTECTING THE PRIVATE KEY
+=========================================
+
+Since the private key is used to sign modules, viruses and malware could use
+the private key to sign modules and compromise the operating system.  The
+private key must be either destroyed or moved to a secure location and not kept
+in the root node of the kernel source tree.
index 3c12d9a7ed00391d5c3f49ef80d7b1ae9abc40fe..8a984e994e61616a9dba0a4f425a5b4371b3ae99 100644 (file)
@@ -16,8 +16,12 @@ ip_default_ttl - INTEGER
        Default: 64 (as recommended by RFC1700)
 
 ip_no_pmtu_disc - BOOLEAN
-       Disable Path MTU Discovery.
-       default FALSE
+       Disable Path MTU Discovery. If enabled and a
+       fragmentation-required ICMP is received, the PMTU to this
+       destination will be set to min_pmtu (see below). You will need
+       to raise min_pmtu to the smallest interface MTU on your system
+       manually if you want to avoid locally generated fragments.
+       Default: FALSE
 
 min_pmtu - INTEGER
        default 552 - minimum discovered Path MTU
index c01223628a87ae5e522b714c8a3a86edda15dea5..8e48e3b142275ff1500df754301d39c7f1639d71 100644 (file)
@@ -123,6 +123,16 @@ Transmission process is similar to capture as shown below.
 [shutdown]  close() --------> destruction of the transmission socket and
                               deallocation of all associated resources.
 
+Socket creation and destruction is also straight forward, and is done
+the same way as in capturing described in the previous paragraph:
+
+ int fd = socket(PF_PACKET, mode, 0);
+
+The protocol can optionally be 0 in case we only want to transmit
+via this socket, which avoids an expensive call to packet_rcv().
+In this case, you also need to bind(2) the TX_RING with sll_protocol = 0
+set. Otherwise, htons(ETH_P_ALL) or any other protocol, for example.
+
 Binding the socket to your network interface is mandatory (with zero copy) to
 know the header size of frames used in the circular buffer.
 
index 9486fb6fe38ecb44b1653df1d4c573ad7f2845eb..52f761733bfeababaa0c75d4fa79eac6f8623023 100644 (file)
@@ -893,20 +893,15 @@ F:        arch/arm/include/asm/hardware/dec21285.h
 F:     arch/arm/mach-footbridge/
 
 ARM/FREESCALE IMX / MXC ARM ARCHITECTURE
+M:     Shawn Guo <shawn.guo@linaro.org>
 M:     Sascha Hauer <kernel@pengutronix.de>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
-T:     git git://git.pengutronix.de/git/imx/linux-2.6.git
+T:     git git://git.linaro.org/people/shawnguo/linux-2.6.git
 F:     arch/arm/mach-imx/
+F:     arch/arm/boot/dts/imx*
 F:     arch/arm/configs/imx*_defconfig
 
-ARM/FREESCALE IMX6
-M:     Shawn Guo <shawn.guo@linaro.org>
-L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
-S:     Maintained
-T:     git git://git.linaro.org/people/shawnguo/linux-2.6.git
-F:     arch/arm/mach-imx/*imx6*
-
 ARM/FREESCALE MXS ARM ARCHITECTURE
 M:     Shawn Guo <shawn.guo@linaro.org>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@ -3766,9 +3761,11 @@ F:       include/uapi/linux/gigaset_dev.h
 
 GPIO SUBSYSTEM
 M:     Linus Walleij <linus.walleij@linaro.org>
-S:     Maintained
+M:     Alexandre Courbot <gnurou@gmail.com>
 L:     linux-gpio@vger.kernel.org
-F:     Documentation/gpio.txt
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio.git
+S:     Maintained
+F:     Documentation/gpio/
 F:     drivers/gpio/
 F:     include/linux/gpio*
 F:     include/asm-generic/gpio.h
@@ -3836,6 +3833,12 @@ T:       git git://linuxtv.org/media_tree.git
 S:     Maintained
 F:     drivers/media/usb/gspca/
 
+GUID PARTITION TABLE (GPT)
+M:     Davidlohr Bueso <davidlohr@hp.com>
+L:     linux-efi@vger.kernel.org
+S:     Maintained
+F:     block/partitions/efi.*
+
 STK1160 USB VIDEO CAPTURE DRIVER
 M:     Ezequiel Garcia <elezegarcia@gmail.com>
 L:     linux-media@vger.kernel.org
@@ -4471,10 +4474,8 @@ M:       Bruce Allan <bruce.w.allan@intel.com>
 M:     Carolyn Wyborny <carolyn.wyborny@intel.com>
 M:     Don Skidmore <donald.c.skidmore@intel.com>
 M:     Greg Rose <gregory.v.rose@intel.com>
-M:     Peter P Waskiewicz Jr <peter.p.waskiewicz.jr@intel.com>
 M:     Alex Duyck <alexander.h.duyck@intel.com>
 M:     John Ronciak <john.ronciak@intel.com>
-M:     Tushar Dave <tushar.n.dave@intel.com>
 L:     e1000-devel@lists.sourceforge.net
 W:     http://www.intel.com/support/feedback.htm
 W:     http://e1000.sourceforge.net/
@@ -5918,12 +5919,21 @@ M:      Steffen Klassert <steffen.klassert@secunet.com>
 M:     Herbert Xu <herbert@gondor.apana.org.au>
 M:     "David S. Miller" <davem@davemloft.net>
 L:     netdev@vger.kernel.org
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec-next.git
 S:     Maintained
 F:     net/xfrm/
 F:     net/key/
 F:     net/ipv4/xfrm*
+F:     net/ipv4/esp4.c
+F:     net/ipv4/ah4.c
+F:     net/ipv4/ipcomp.c
+F:     net/ipv4/ip_vti.c
 F:     net/ipv6/xfrm*
+F:     net/ipv6/esp6.c
+F:     net/ipv6/ah6.c
+F:     net/ipv6/ipcomp6.c
+F:     net/ipv6/ip6_vti.c
 F:     include/uapi/linux/xfrm.h
 F:     include/net/xfrm.h
 
@@ -6470,19 +6480,52 @@ F:      drivers/pci/
 F:     include/linux/pci*
 F:     arch/x86/pci/
 
+PCI DRIVER FOR IMX6
+M:     Richard Zhu <r65037@freescale.com>
+M:     Shawn Guo <shawn.guo@linaro.org>
+L:     linux-pci@vger.kernel.org
+L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+S:     Maintained
+F:     drivers/pci/host/*imx6*
+
+PCI DRIVER FOR MVEBU (Marvell Armada 370 and Armada XP SOC support)
+M:     Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+M:     Jason Cooper <jason@lakedaemon.net>
+L:     linux-pci@vger.kernel.org
+L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+S:     Maintained
+F:     drivers/pci/host/*mvebu*
+
 PCI DRIVER FOR NVIDIA TEGRA
 M:     Thierry Reding <thierry.reding@gmail.com>
 L:     linux-tegra@vger.kernel.org
+L:     linux-pci@vger.kernel.org
 S:     Supported
 F:     Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
 F:     drivers/pci/host/pci-tegra.c
 
+PCI DRIVER FOR RENESAS R-CAR
+M:     Simon Horman <horms@verge.net.au>
+L:     linux-pci@vger.kernel.org
+L:     linux-sh@vger.kernel.org
+S:     Maintained
+F:     drivers/pci/host/*rcar*
+
 PCI DRIVER FOR SAMSUNG EXYNOS
 M:     Jingoo Han <jg1.han@samsung.com>
 L:     linux-pci@vger.kernel.org
+L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+L:     linux-samsung-soc@vger.kernel.org (moderated for non-subscribers)
 S:     Maintained
 F:     drivers/pci/host/pci-exynos.c
 
+PCI DRIVER FOR SYNOPSIS DESIGNWARE
+M:     Mohit Kumar <mohit.kumar@st.com>
+M:     Jingoo Han <jg1.han@samsung.com>
+L:     linux-pci@vger.kernel.org
+S:     Maintained
+F:     drivers/pci/host/*designware*
+
 PCMCIA SUBSYSTEM
 P:     Linux PCMCIA Team
 L:     linux-pcmcia@lists.infradead.org
index 890392f1c7c004d8c089938025655ad3317713b6..89cee8625651ae75809a610ad7d08f1644268325 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 3
 PATCHLEVEL = 13
 SUBLEVEL = 0
-EXTRAVERSION = -rc3
+EXTRAVERSION = -rc4
 NAME = One Giant Leap for Frogkind
 
 # *DOCUMENTATION*
@@ -732,19 +732,13 @@ export mod_strip_cmd
 # Select initial ramdisk compression format, default is gzip(1).
 # This shall be used by the dracut(8) tool while creating an initramfs image.
 #
-INITRD_COMPRESS=gzip
-ifeq ($(CONFIG_RD_BZIP2), y)
-        INITRD_COMPRESS=bzip2
-else ifeq ($(CONFIG_RD_LZMA), y)
-        INITRD_COMPRESS=lzma
-else ifeq ($(CONFIG_RD_XZ), y)
-        INITRD_COMPRESS=xz
-else ifeq ($(CONFIG_RD_LZO), y)
-        INITRD_COMPRESS=lzo
-else ifeq ($(CONFIG_RD_LZ4), y)
-        INITRD_COMPRESS=lz4
-endif
-export INITRD_COMPRESS
+INITRD_COMPRESS-y                  := gzip
+INITRD_COMPRESS-$(CONFIG_RD_BZIP2) := bzip2
+INITRD_COMPRESS-$(CONFIG_RD_LZMA)  := lzma
+INITRD_COMPRESS-$(CONFIG_RD_XZ)    := xz
+INITRD_COMPRESS-$(CONFIG_RD_LZO)   := lzo
+INITRD_COMPRESS-$(CONFIG_RD_LZ4)   := lz4
+export INITRD_COMPRESS := $(INITRD_COMPRESS-y)
 
 ifdef CONFIG_MODULE_SIG_ALL
 MODSECKEY = ./signing_key.priv
index 2ee0c9bfd0325537a5d9299649abac4992b722f5..9063ae6553ccb7a0a220b8db667ac770627addbf 100644 (file)
@@ -8,6 +8,7 @@
 
 config ARC
        def_bool y
+       select BUILDTIME_EXTABLE_SORT
        select CLONE_BACKWARDS
        # ARC Busybox based initramfs absolutely relies on DEVTMPFS for /dev
        select DEVTMPFS if !INITRAMFS_SOURCE=""
index 6f30484f34b78c5fa5052e68bbcbd3b4280a193f..68125dd766c68feeb9de6715c9d1694ed24e5491 100644 (file)
@@ -8,6 +8,9 @@
 
 /******** no-legacy-syscalls-ABI *******/
 
+#ifndef _UAPI_ASM_ARC_UNISTD_H
+#define _UAPI_ASM_ARC_UNISTD_H
+
 #define __ARCH_WANT_SYS_EXECVE
 #define __ARCH_WANT_SYS_CLONE
 #define __ARCH_WANT_SYS_VFORK
@@ -32,3 +35,5 @@ __SYSCALL(__NR_arc_gettls, sys_arc_gettls)
 /* Generic syscall (fs/filesystems.c - lost in asm-generic/unistd.h */
 #define __NR_sysfs             (__NR_arch_specific_syscall + 3)
 __SYSCALL(__NR_sysfs, sys_sysfs)
+
+#endif
index e46d81f709797a868b7cc68cc81ef71277a0f070..63177e4cb66d0d3a323b3e53081d4caaf2550ac0 100644 (file)
@@ -79,9 +79,9 @@ static int arc_pmu_cache_event(u64 config)
        cache_result    = (config >> 16) & 0xff;
        if (cache_type >= PERF_COUNT_HW_CACHE_MAX)
                return -EINVAL;
-       if (cache_type >= PERF_COUNT_HW_CACHE_OP_MAX)
+       if (cache_op >= PERF_COUNT_HW_CACHE_OP_MAX)
                return -EINVAL;
-       if (cache_type >= PERF_COUNT_HW_CACHE_RESULT_MAX)
+       if (cache_result >= PERF_COUNT_HW_CACHE_RESULT_MAX)
                return -EINVAL;
 
        ret = arc_pmu_cache_map[cache_type][cache_op][cache_result];
index e99dfaf70052f3dd993aa93588b6e47470befee2..03fcbf0a88a8ef24565257d32be79ab75dd4aa79 100644 (file)
@@ -7,11 +7,11 @@
  */
 /dts-v1/;
 
-#include "omap34xx.dtsi"
+#include "am3517.dtsi"
 
 / {
-       model = "TI AM3517 EVM (AM3517/05)";
-       compatible = "ti,am3517-evm", "ti,omap3";
+       model = "TI AM3517 EVM (AM3517/05 TMDSEVM3517)";
+       compatible = "ti,am3517-evm", "ti,am3517", "ti,omap3";
 
        memory {
                device_type = "memory";
diff --git a/arch/arm/boot/dts/am3517.dtsi b/arch/arm/boot/dts/am3517.dtsi
new file mode 100644 (file)
index 0000000..2fbe02f
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Device Tree Source for am3517 SoC
+ *
+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2.  This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#include "omap3.dtsi"
+
+/ {
+       aliases {
+               serial3 = &uart4;
+       };
+
+       ocp {
+               am35x_otg_hs: am35x_otg_hs@5c040000 {
+                       compatible = "ti,omap3-musb";
+                       ti,hwmods = "am35x_otg_hs";
+                       status = "disabled";
+                       reg = <0x5c040000 0x1000>;
+                       interrupts = <71>;
+                       interrupt-names = "mc";
+               };
+
+               davinci_emac: ethernet@0x5c000000 {
+                       compatible = "ti,am3517-emac";
+                       ti,hwmods = "davinci_emac";
+                       status = "disabled";
+                       reg = <0x5c000000 0x30000>;
+                       interrupts = <67 68 69 70>;
+                       ti,davinci-ctrl-reg-offset = <0x10000>;
+                       ti,davinci-ctrl-mod-reg-offset = <0>;
+                       ti,davinci-ctrl-ram-offset = <0x20000>;
+                       ti,davinci-ctrl-ram-size = <0x2000>;
+                       ti,davinci-rmii-en = /bits/ 8 <1>;
+                       local-mac-address = [ 00 00 00 00 00 00 ];
+               };
+
+               davinci_mdio: ethernet@0x5c030000 {
+                       compatible = "ti,davinci_mdio";
+                       ti,hwmods = "davinci_mdio";
+                       status = "disabled";
+                       reg = <0x5c030000 0x1000>;
+                       bus_freq = <1000000>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+               };
+
+               uart4: serial@4809e000 {
+                       compatible = "ti,omap3-uart";
+                       ti,hwmods = "uart4";
+                       status = "disabled";
+                       reg = <0x4809e000 0x400>;
+                       interrupts = <84>;
+                       dmas = <&sdma 55 &sdma 54>;
+                       dma-names = "tx", "rx";
+                       clock-frequency = <48000000>;
+               };
+       };
+};
index c2c306d13b87fcc19434f545268e69d94cbda945..6fc85f96353024ad61d04d74d7ca51f8afb1c7ce 100644 (file)
@@ -9,7 +9,7 @@
 
 /dts-v1/;
 
-#include "omap34xx.dtsi"
+#include "omap34xx-hs.dtsi"
 
 / {
        model = "Nokia N900";
index 94eb77d3b9ddc5a2c506f271834103cb06b4881e..5c26c184f2c18b50a18cdd51bd53b20f9b3f359b 100644 (file)
@@ -8,7 +8,7 @@
  * published by the Free Software Foundation.
  */
 
-#include "omap36xx.dtsi"
+#include "omap36xx-hs.dtsi"
 
 / {
        cpus {
diff --git a/arch/arm/boot/dts/omap34xx-hs.dtsi b/arch/arm/boot/dts/omap34xx-hs.dtsi
new file mode 100644 (file)
index 0000000..1ff6264
--- /dev/null
@@ -0,0 +1,16 @@
+/* Disabled modules for secure omaps */
+
+#include "omap34xx.dtsi"
+
+/* Secure omaps have some devices inaccessible depending on the firmware */
+&aes {
+       status = "disabled";
+};
+
+&sham {
+       status = "disabled";
+};
+
+&timer12 {
+       status = "disabled";
+};
diff --git a/arch/arm/boot/dts/omap36xx-hs.dtsi b/arch/arm/boot/dts/omap36xx-hs.dtsi
new file mode 100644 (file)
index 0000000..2c7febb
--- /dev/null
@@ -0,0 +1,16 @@
+/* Disabled modules for secure omaps */
+
+#include "omap36xx.dtsi"
+
+/* Secure omaps have some devices inaccessible depending on the firmware */
+&aes {
+       status = "disabled";
+};
+
+&sham {
+       status = "disabled";
+};
+
+&timer12 {
+       status = "disabled";
+};
index c1751a64889a615612101613d63145b15903bfc7..7f5878c2784ab28eff69c2a278dfa408fe70bc4d 100644 (file)
                pio: pinctrl@01c20800 {
                        compatible = "allwinner,sun6i-a31-pinctrl";
                        reg = <0x01c20800 0x400>;
-                       interrupts = <0 11 1>, <0 15 1>, <0 16 1>, <0 17 1>;
+                       interrupts = <0 11 4>,
+                                    <0 15 4>,
+                                    <0 16 4>,
+                                    <0 17 4>;
                        clocks = <&apb1_gates 5>;
                        gpio-controller;
                        interrupt-controller;
                timer@01c20c00 {
                        compatible = "allwinner,sun4i-timer";
                        reg = <0x01c20c00 0xa0>;
-                       interrupts = <0 18 1>,
-                                    <0 19 1>,
-                                    <0 20 1>,
-                                    <0 21 1>,
-                                    <0 22 1>;
+                       interrupts = <0 18 4>,
+                                    <0 19 4>,
+                                    <0 20 4>,
+                                    <0 21 4>,
+                                    <0 22 4>;
                        clocks = <&osc24M>;
                };
 
                uart0: serial@01c28000 {
                        compatible = "snps,dw-apb-uart";
                        reg = <0x01c28000 0x400>;
-                       interrupts = <0 0 1>;
+                       interrupts = <0 0 4>;
                        reg-shift = <2>;
                        reg-io-width = <4>;
                        clocks = <&apb2_gates 16>;
                uart1: serial@01c28400 {
                        compatible = "snps,dw-apb-uart";
                        reg = <0x01c28400 0x400>;
-                       interrupts = <0 1 1>;
+                       interrupts = <0 1 4>;
                        reg-shift = <2>;
                        reg-io-width = <4>;
                        clocks = <&apb2_gates 17>;
                uart2: serial@01c28800 {
                        compatible = "snps,dw-apb-uart";
                        reg = <0x01c28800 0x400>;
-                       interrupts = <0 2 1>;
+                       interrupts = <0 2 4>;
                        reg-shift = <2>;
                        reg-io-width = <4>;
                        clocks = <&apb2_gates 18>;
                uart3: serial@01c28c00 {
                        compatible = "snps,dw-apb-uart";
                        reg = <0x01c28c00 0x400>;
-                       interrupts = <0 3 1>;
+                       interrupts = <0 3 4>;
                        reg-shift = <2>;
                        reg-io-width = <4>;
                        clocks = <&apb2_gates 19>;
                uart4: serial@01c29000 {
                        compatible = "snps,dw-apb-uart";
                        reg = <0x01c29000 0x400>;
-                       interrupts = <0 4 1>;
+                       interrupts = <0 4 4>;
                        reg-shift = <2>;
                        reg-io-width = <4>;
                        clocks = <&apb2_gates 20>;
                uart5: serial@01c29400 {
                        compatible = "snps,dw-apb-uart";
                        reg = <0x01c29400 0x400>;
-                       interrupts = <0 5 1>;
+                       interrupts = <0 5 4>;
                        reg-shift = <2>;
                        reg-io-width = <4>;
                        clocks = <&apb2_gates 21>;
index e46cfedde74c220b698c829458dfa40cef916159..367611a0730bc0c978d24737fa611c1beeac7417 100644 (file)
                emac: ethernet@01c0b000 {
                        compatible = "allwinner,sun4i-emac";
                        reg = <0x01c0b000 0x1000>;
-                       interrupts = <0 55 1>;
+                       interrupts = <0 55 4>;
                        clocks = <&ahb_gates 17>;
                        status = "disabled";
                };
                pio: pinctrl@01c20800 {
                        compatible = "allwinner,sun7i-a20-pinctrl";
                        reg = <0x01c20800 0x400>;
-                       interrupts = <0 28 1>;
+                       interrupts = <0 28 4>;
                        clocks = <&apb0_gates 5>;
                        gpio-controller;
                        interrupt-controller;
                timer@01c20c00 {
                        compatible = "allwinner,sun4i-timer";
                        reg = <0x01c20c00 0x90>;
-                       interrupts = <0 22 1>,
-                                    <0 23 1>,
-                                    <0 24 1>,
-                                    <0 25 1>,
-                                    <0 67 1>,
-                                    <0 68 1>;
+                       interrupts = <0 22 4>,
+                                    <0 23 4>,
+                                    <0 24 4>,
+                                    <0 25 4>,
+                                    <0 67 4>,
+                                    <0 68 4>;
                        clocks = <&osc24M>;
                };
 
                uart0: serial@01c28000 {
                        compatible = "snps,dw-apb-uart";
                        reg = <0x01c28000 0x400>;
-                       interrupts = <0 1 1>;
+                       interrupts = <0 1 4>;
                        reg-shift = <2>;
                        reg-io-width = <4>;
                        clocks = <&apb1_gates 16>;
                uart1: serial@01c28400 {
                        compatible = "snps,dw-apb-uart";
                        reg = <0x01c28400 0x400>;
-                       interrupts = <0 2 1>;
+                       interrupts = <0 2 4>;
                        reg-shift = <2>;
                        reg-io-width = <4>;
                        clocks = <&apb1_gates 17>;
                uart2: serial@01c28800 {
                        compatible = "snps,dw-apb-uart";
                        reg = <0x01c28800 0x400>;
-                       interrupts = <0 3 1>;
+                       interrupts = <0 3 4>;
                        reg-shift = <2>;
                        reg-io-width = <4>;
                        clocks = <&apb1_gates 18>;
                uart3: serial@01c28c00 {
                        compatible = "snps,dw-apb-uart";
                        reg = <0x01c28c00 0x400>;
-                       interrupts = <0 4 1>;
+                       interrupts = <0 4 4>;
                        reg-shift = <2>;
                        reg-io-width = <4>;
                        clocks = <&apb1_gates 19>;
                uart4: serial@01c29000 {
                        compatible = "snps,dw-apb-uart";
                        reg = <0x01c29000 0x400>;
-                       interrupts = <0 17 1>;
+                       interrupts = <0 17 4>;
                        reg-shift = <2>;
                        reg-io-width = <4>;
                        clocks = <&apb1_gates 20>;
                uart5: serial@01c29400 {
                        compatible = "snps,dw-apb-uart";
                        reg = <0x01c29400 0x400>;
-                       interrupts = <0 18 1>;
+                       interrupts = <0 18 4>;
                        reg-shift = <2>;
                        reg-io-width = <4>;
                        clocks = <&apb1_gates 21>;
                uart6: serial@01c29800 {
                        compatible = "snps,dw-apb-uart";
                        reg = <0x01c29800 0x400>;
-                       interrupts = <0 19 1>;
+                       interrupts = <0 19 4>;
                        reg-shift = <2>;
                        reg-io-width = <4>;
                        clocks = <&apb1_gates 22>;
                uart7: serial@01c29c00 {
                        compatible = "snps,dw-apb-uart";
                        reg = <0x01c29c00 0x400>;
-                       interrupts = <0 20 1>;
+                       interrupts = <0 20 4>;
                        reg-shift = <2>;
                        reg-io-width = <4>;
                        clocks = <&apb1_gates 23>;
                i2c0: i2c@01c2ac00 {
                        compatible = "allwinner,sun4i-i2c";
                        reg = <0x01c2ac00 0x400>;
-                       interrupts = <0 7 1>;
+                       interrupts = <0 7 4>;
                        clocks = <&apb1_gates 0>;
                        clock-frequency = <100000>;
                        status = "disabled";
                i2c1: i2c@01c2b000 {
                        compatible = "allwinner,sun4i-i2c";
                        reg = <0x01c2b000 0x400>;
-                       interrupts = <0 8 1>;
+                       interrupts = <0 8 4>;
                        clocks = <&apb1_gates 1>;
                        clock-frequency = <100000>;
                        status = "disabled";
                i2c2: i2c@01c2b400 {
                        compatible = "allwinner,sun4i-i2c";
                        reg = <0x01c2b400 0x400>;
-                       interrupts = <0 9 1>;
+                       interrupts = <0 9 4>;
                        clocks = <&apb1_gates 2>;
                        clock-frequency = <100000>;
                        status = "disabled";
                i2c3: i2c@01c2b800 {
                        compatible = "allwinner,sun4i-i2c";
                        reg = <0x01c2b800 0x400>;
-                       interrupts = <0 88 1>;
+                       interrupts = <0 88 4>;
                        clocks = <&apb1_gates 3>;
                        clock-frequency = <100000>;
                        status = "disabled";
                i2c4: i2c@01c2bc00 {
                        compatible = "allwinner,sun4i-i2c";
                        reg = <0x01c2bc00 0x400>;
-                       interrupts = <0 89 1>;
+                       interrupts = <0 89 4>;
                        clocks = <&apb1_gates 15>;
                        clock-frequency = <100000>;
                        status = "disabled";
index 9ecccc865046a2c257277cd03a8f607ed5e0217d..6976b03e521369bddedfe6968cfa221c6705c552 100644 (file)
 #define TASK_UNMAPPED_BASE     UL(0x00000000)
 #endif
 
-#ifndef PHYS_OFFSET
-#define PHYS_OFFSET            UL(CONFIG_DRAM_BASE)
-#endif
-
 #ifndef END_MEM
 #define END_MEM                (UL(CONFIG_DRAM_BASE) + CONFIG_DRAM_SIZE)
 #endif
 
 #ifndef PAGE_OFFSET
-#define PAGE_OFFSET            (PHYS_OFFSET)
+#define PAGE_OFFSET            PLAT_PHYS_OFFSET
 #endif
 
 /*
  * The module can be at any place in ram in nommu mode.
  */
 #define MODULES_END            (END_MEM)
-#define MODULES_VADDR          (PHYS_OFFSET)
+#define MODULES_VADDR          PAGE_OFFSET
 
 #define XIP_VIRT_ADDR(physaddr)  (physaddr)
 
 #endif
 #define ARCH_PGD_MASK          ((1 << ARCH_PGD_SHIFT) - 1)
 
+/*
+ * PLAT_PHYS_OFFSET is the offset (from zero) of the start of physical
+ * memory.  This is used for XIP and NoMMU kernels, or by kernels which
+ * have their own mach/memory.h.  Assembly code must always use
+ * PLAT_PHYS_OFFSET and not PHYS_OFFSET.
+ */
+#ifndef PLAT_PHYS_OFFSET
+#define PLAT_PHYS_OFFSET       UL(CONFIG_PHYS_OFFSET)
+#endif
+
 #ifndef __ASSEMBLY__
 
 /*
@@ -239,6 +245,8 @@ static inline unsigned long __phys_to_virt(phys_addr_t x)
 
 #else
 
+#define PHYS_OFFSET    PLAT_PHYS_OFFSET
+
 static inline phys_addr_t __virt_to_phys(unsigned long x)
 {
        return (phys_addr_t)x - PAGE_OFFSET + PHYS_OFFSET;
@@ -251,17 +259,6 @@ static inline unsigned long __phys_to_virt(phys_addr_t x)
 
 #endif
 #endif
-#endif /* __ASSEMBLY__ */
-
-#ifndef PHYS_OFFSET
-#ifdef PLAT_PHYS_OFFSET
-#define PHYS_OFFSET    PLAT_PHYS_OFFSET
-#else
-#define PHYS_OFFSET    UL(CONFIG_PHYS_OFFSET)
-#endif
-#endif
-
-#ifndef __ASSEMBLY__
 
 /*
  * PFNs are used to describe any physical page; this means
index 14235ba64a90736ecebad575f5d88ea4568e8eaf..716249cc2ee18c178643e7e6c4a0cd0eb6a48c00 100644 (file)
@@ -68,7 +68,7 @@ ENTRY(stext)
 
 #ifdef CONFIG_ARM_MPU
        /* Calculate the size of a region covering just the kernel */
-       ldr     r5, =PHYS_OFFSET                @ Region start: PHYS_OFFSET
+       ldr     r5, =PLAT_PHYS_OFFSET           @ Region start: PHYS_OFFSET
        ldr     r6, =(_end)                     @ Cover whole kernel
        sub     r6, r6, r5                      @ Minimum size of region to map
        clz     r6, r6                          @ Region size must be 2^N...
@@ -213,7 +213,7 @@ ENTRY(__setup_mpu)
        set_region_nr r0, #MPU_RAM_REGION
        isb
        /* Full access from PL0, PL1, shared for CONFIG_SMP, cacheable */
-       ldr     r0, =PHYS_OFFSET                @ RAM starts at PHYS_OFFSET
+       ldr     r0, =PLAT_PHYS_OFFSET           @ RAM starts at PHYS_OFFSET
        ldr     r5,=(MPU_AP_PL1RW_PL0RW | MPU_RGN_NORMAL)
 
        setup_region r0, r5, r6, MPU_DATA_SIDE  @ PHYS_OFFSET, shared, enabled
index 11d59b32fb8dca45613ed00fb225a72359c19216..32f317e5828adafc2bdec200705a9d12c686711c 100644 (file)
@@ -110,7 +110,7 @@ ENTRY(stext)
        sub     r4, r3, r4                      @ (PHYS_OFFSET - PAGE_OFFSET)
        add     r8, r8, r4                      @ PHYS_OFFSET
 #else
-       ldr     r8, =PHYS_OFFSET                @ always constant in this case
+       ldr     r8, =PLAT_PHYS_OFFSET           @ always constant in this case
 #endif
 
        /*
index 94f6b05f9e24e8cd1d79063f03a9b2dd16791c67..92f7b15dd22121d4aa674fd78cd95cac8924c07f 100644 (file)
@@ -404,6 +404,7 @@ EXPORT_SYMBOL(dump_fpu);
 unsigned long get_wchan(struct task_struct *p)
 {
        struct stackframe frame;
+       unsigned long stack_page;
        int count = 0;
        if (!p || p == current || p->state == TASK_RUNNING)
                return 0;
@@ -412,9 +413,11 @@ unsigned long get_wchan(struct task_struct *p)
        frame.sp = thread_saved_sp(p);
        frame.lr = 0;                   /* recovered from the stack */
        frame.pc = thread_saved_pc(p);
+       stack_page = (unsigned long)task_stack_page(p);
        do {
-               int ret = unwind_frame(&frame);
-               if (ret < 0)
+               if (frame.sp < stack_page ||
+                   frame.sp >= stack_page + THREAD_SIZE ||
+                   unwind_frame(&frame) < 0)
                        return 0;
                if (!in_sched_functions(frame.pc))
                        return frame.pc;
index 6a1b8a81b1ae448168572a9558aaf026f9e7e47e..987a7f5bce5f1759d73c01a80099cea57a94025d 100644 (file)
@@ -873,8 +873,6 @@ void __init setup_arch(char **cmdline_p)
        machine_desc = mdesc;
        machine_name = mdesc->name;
 
-       setup_dma_zone(mdesc);
-
        if (mdesc->reboot_mode != REBOOT_HARD)
                reboot_mode = mdesc->reboot_mode;
 
@@ -892,6 +890,7 @@ void __init setup_arch(char **cmdline_p)
        sort(&meminfo.bank, meminfo.nr_banks, sizeof(meminfo.bank[0]), meminfo_cmp, NULL);
 
        early_paging_init(mdesc, lookup_processor_type(read_cpuid_id()));
+       setup_dma_zone(mdesc);
        sanity_check_meminfo();
        arm_memblock_init(&meminfo, mdesc);
 
index 00f79e59985bccaf54bd3b1c8f2e292f49014a47..af4e8c8a5422c4383396f7f4b3a836a67426b7de 100644 (file)
@@ -31,7 +31,7 @@ int notrace unwind_frame(struct stackframe *frame)
        high = ALIGN(low, THREAD_SIZE);
 
        /* check current frame pointer is within bounds */
-       if (fp < (low + 12) || fp + 4 >= high)
+       if (fp < low + 12 || fp > high - 4)
                return -EINVAL;
 
        /* restore the registers from the stack frame */
index dbf0923e8d76bda9392b902e0c8e500025d70402..7940241f0576b0db1cc0a749e449c7faf492518a 100644 (file)
@@ -509,9 +509,10 @@ static inline int
 __do_cache_op(unsigned long start, unsigned long end)
 {
        int ret;
-       unsigned long chunk = PAGE_SIZE;
 
        do {
+               unsigned long chunk = min(PAGE_SIZE, end - start);
+
                if (signal_pending(current)) {
                        struct thread_info *ti = current_thread_info();
 
index c46eccbbd51226f5ae6ab5a16e1c89668c35fa1d..78829c513fdc354bce631d67f45922efff84368d 100644 (file)
@@ -487,7 +487,7 @@ int __init da8xx_register_emac(void)
 
 static struct resource da830_mcasp1_resources[] = {
        {
-               .name   = "mcasp1",
+               .name   = "mpu",
                .start  = DAVINCI_DA830_MCASP1_REG_BASE,
                .end    = DAVINCI_DA830_MCASP1_REG_BASE + (SZ_1K * 12) - 1,
                .flags  = IORESOURCE_MEM,
@@ -515,7 +515,7 @@ static struct platform_device da830_mcasp1_device = {
 
 static struct resource da850_mcasp_resources[] = {
        {
-               .name   = "mcasp",
+               .name   = "mpu",
                .start  = DAVINCI_DA8XX_MCASP0_REG_BASE,
                .end    = DAVINCI_DA8XX_MCASP0_REG_BASE + (SZ_1K * 12) - 1,
                .flags  = IORESOURCE_MEM,
index ef9ff1fb6f52a2533378ba37563c06e877b32ea3..6117fc644188d9aa81c2397dbb60538db190beea 100644 (file)
@@ -641,6 +641,7 @@ static struct platform_device dm355_edma_device = {
 
 static struct resource dm355_asp1_resources[] = {
        {
+               .name   = "mpu",
                .start  = DAVINCI_ASP1_BASE,
                .end    = DAVINCI_ASP1_BASE + SZ_8K - 1,
                .flags  = IORESOURCE_MEM,
@@ -906,7 +907,7 @@ static struct davinci_gpio_platform_data dm355_gpio_platform_data = {
 int __init dm355_gpio_register(void)
 {
        return davinci_gpio_register(dm355_gpio_resources,
-                                    sizeof(dm355_gpio_resources),
+                                    ARRAY_SIZE(dm355_gpio_resources),
                                     &dm355_gpio_platform_data);
 }
 /*----------------------------------------------------------------------*/
index 1511a0680f9a1d399cf3094b538c3c52caa06547..d7c6f85d3fc9d5c4347ec214ae8e71a310f89b62 100644 (file)
@@ -720,7 +720,7 @@ static struct davinci_gpio_platform_data dm365_gpio_platform_data = {
 int __init dm365_gpio_register(void)
 {
        return davinci_gpio_register(dm365_gpio_resources,
-                                    sizeof(dm365_gpio_resources),
+                                    ARRAY_SIZE(dm365_gpio_resources),
                                     &dm365_gpio_platform_data);
 }
 
@@ -942,6 +942,7 @@ static struct platform_device dm365_edma_device = {
 
 static struct resource dm365_asp_resources[] = {
        {
+               .name   = "mpu",
                .start  = DAVINCI_DM365_ASP0_BASE,
                .end    = DAVINCI_DM365_ASP0_BASE + SZ_8K - 1,
                .flags  = IORESOURCE_MEM,
index 143a3217e8efb8fde1aa417700c45840d242aac0..3ce47997bb46150e82f40e718474feeae52b6d5e 100644 (file)
@@ -572,6 +572,7 @@ static struct platform_device dm644x_edma_device = {
 /* DM6446 EVM uses ASP0; line-out is a pair of RCA jacks */
 static struct resource dm644x_asp_resources[] = {
        {
+               .name   = "mpu",
                .start  = DAVINCI_ASP0_BASE,
                .end    = DAVINCI_ASP0_BASE + SZ_8K - 1,
                .flags  = IORESOURCE_MEM,
@@ -792,7 +793,7 @@ static struct davinci_gpio_platform_data dm644_gpio_platform_data = {
 int __init dm644x_gpio_register(void)
 {
        return davinci_gpio_register(dm644_gpio_resources,
-                                    sizeof(dm644_gpio_resources),
+                                    ARRAY_SIZE(dm644_gpio_resources),
                                     &dm644_gpio_platform_data);
 }
 /*----------------------------------------------------------------------*/
index 2a73f299c1d094615236359d6ac27959cdd16295..0e81fea65e7fb484cda893f0a4cd91d0b74fc0ad 100644 (file)
@@ -621,7 +621,7 @@ static struct platform_device dm646x_edma_device = {
 
 static struct resource dm646x_mcasp0_resources[] = {
        {
-               .name   = "mcasp0",
+               .name   = "mpu",
                .start  = DAVINCI_DM646X_MCASP0_REG_BASE,
                .end    = DAVINCI_DM646X_MCASP0_REG_BASE + (SZ_1K << 1) - 1,
                .flags  = IORESOURCE_MEM,
@@ -641,7 +641,7 @@ static struct resource dm646x_mcasp0_resources[] = {
 
 static struct resource dm646x_mcasp1_resources[] = {
        {
-               .name   = "mcasp1",
+               .name   = "mpu",
                .start  = DAVINCI_DM646X_MCASP1_REG_BASE,
                .end    = DAVINCI_DM646X_MCASP1_REG_BASE + (SZ_1K << 1) - 1,
                .flags  = IORESOURCE_MEM,
@@ -769,7 +769,7 @@ static struct davinci_gpio_platform_data dm646x_gpio_platform_data = {
 int __init dm646x_gpio_register(void)
 {
        return davinci_gpio_register(dm646x_gpio_resources,
-                                    sizeof(dm646x_gpio_resources),
+                                    ARRAY_SIZE(dm646x_gpio_resources),
                                     &dm646x_gpio_platform_data);
 }
 /*----------------------------------------------------------------------*/
index b3d7e5634b83cb02ce568040099027007820a45b..bd3bf66ce3449a31c9c7c9f56be6b4225ee9cbf9 100644 (file)
 #include <linux/clkdev.h>
 #include <linux/clocksource.h>
 #include <linux/dma-mapping.h>
+#include <linux/input.h>
 #include <linux/io.h>
 #include <linux/irqchip.h>
+#include <linux/mailbox.h>
 #include <linux/of.h>
 #include <linux/of_irq.h>
 #include <linux/of_platform.h>
 #include <linux/of_address.h>
+#include <linux/reboot.h>
 #include <linux/amba/bus.h>
 #include <linux/platform_device.h>
 
@@ -130,6 +133,24 @@ static struct platform_device highbank_cpuidle_device = {
        .name = "cpuidle-calxeda",
 };
 
+static int hb_keys_notifier(struct notifier_block *nb, unsigned long event, void *data)
+{
+       u32 key = *(u32 *)data;
+
+       if (event != 0x1000)
+               return 0;
+
+       if (key == KEY_POWER)
+               orderly_poweroff(false);
+       else if (key == 0xffff)
+               ctrl_alt_del();
+
+       return 0;
+}
+static struct notifier_block hb_keys_nb = {
+       .notifier_call = hb_keys_notifier,
+};
+
 static void __init highbank_init(void)
 {
        struct device_node *np;
@@ -145,6 +166,8 @@ static void __init highbank_init(void)
        bus_register_notifier(&platform_bus_type, &highbank_platform_nb);
        bus_register_notifier(&amba_bustype, &highbank_amba_nb);
 
+       pl320_ipc_register_notifier(&hb_keys_nb);
+
        of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
 
        if (psci_ops.cpu_suspend)
index 19f1652e94cfbf5e1f09d2d4cc27e44087cc68d7..8d972ff18c561111317aa96d61c0b9fda2d8cade 100644 (file)
@@ -131,6 +131,24 @@ DT_MACHINE_START(OMAP3_GP_DT, "Generic OMAP3-GP (Flattened Device Tree)")
        .dt_compat      = omap3_gp_boards_compat,
        .restart        = omap3xxx_restart,
 MACHINE_END
+
+static const char *am3517_boards_compat[] __initdata = {
+       "ti,am3517",
+       NULL,
+};
+
+DT_MACHINE_START(AM3517_DT, "Generic AM3517 (Flattened Device Tree)")
+       .reserve        = omap_reserve,
+       .map_io         = omap3_map_io,
+       .init_early     = am35xx_init_early,
+       .init_irq       = omap_intc_of_init,
+       .handle_irq     = omap3_intc_handle_irq,
+       .init_machine   = omap_generic_init,
+       .init_late      = omap3_init_late,
+       .init_time      = omap3_gptimer_timer_init,
+       .dt_compat      = am3517_boards_compat,
+       .restart        = omap3xxx_restart,
+MACHINE_END
 #endif
 
 #ifdef CONFIG_SOC_AM33XX
index 53f0735817bb7cf984f3fada24c7e8960941860c..e0a398cf28d80a409e25055c19ad44baef25d7fc 100644 (file)
@@ -183,6 +183,10 @@ static int omap_device_build_from_dt(struct platform_device *pdev)
 odbfd_exit1:
        kfree(hwmods);
 odbfd_exit:
+       /* if data/we are at fault.. load up a fail handler */
+       if (ret)
+               pdev->dev.pm_domain = &omap_device_fail_pm_domain;
+
        return ret;
 }
 
@@ -604,6 +608,19 @@ static int _od_runtime_resume(struct device *dev)
 
        return pm_generic_runtime_resume(dev);
 }
+
+static int _od_fail_runtime_suspend(struct device *dev)
+{
+       dev_warn(dev, "%s: FIXME: missing hwmod/omap_dev info\n", __func__);
+       return -ENODEV;
+}
+
+static int _od_fail_runtime_resume(struct device *dev)
+{
+       dev_warn(dev, "%s: FIXME: missing hwmod/omap_dev info\n", __func__);
+       return -ENODEV;
+}
+
 #endif
 
 #ifdef CONFIG_SUSPEND
@@ -657,6 +674,13 @@ static int _od_resume_noirq(struct device *dev)
 #define _od_resume_noirq NULL
 #endif
 
+struct dev_pm_domain omap_device_fail_pm_domain = {
+       .ops = {
+               SET_RUNTIME_PM_OPS(_od_fail_runtime_suspend,
+                                  _od_fail_runtime_resume, NULL)
+       }
+};
+
 struct dev_pm_domain omap_device_pm_domain = {
        .ops = {
                SET_RUNTIME_PM_OPS(_od_runtime_suspend, _od_runtime_resume,
index 17ca1aec271033d7551c2ffd4cf22fd0c4724fb2..78c02b355179894126f5e2e75f835fc1d753060a 100644 (file)
@@ -29,6 +29,7 @@
 #include "omap_hwmod.h"
 
 extern struct dev_pm_domain omap_device_pm_domain;
+extern struct dev_pm_domain omap_device_fail_pm_domain;
 
 /* omap_device._state values */
 #define OMAP_DEVICE_STATE_UNKNOWN      0
index e3f0ecaf87dd76c3b075c389173ac89faff04a6a..8a1b5e0bad40df2adbab8b202e0dd87602fe7921 100644 (file)
@@ -399,7 +399,7 @@ static int _set_clockactivity(struct omap_hwmod *oh, u8 clockact, u32 *v)
 }
 
 /**
- * _set_softreset: set OCP_SYSCONFIG.CLOCKACTIVITY bits in @v
+ * _set_softreset: set OCP_SYSCONFIG.SOFTRESET bit in @v
  * @oh: struct omap_hwmod *
  * @v: pointer to register contents to modify
  *
@@ -426,6 +426,36 @@ static int _set_softreset(struct omap_hwmod *oh, u32 *v)
        return 0;
 }
 
+/**
+ * _clear_softreset: clear OCP_SYSCONFIG.SOFTRESET bit in @v
+ * @oh: struct omap_hwmod *
+ * @v: pointer to register contents to modify
+ *
+ * Clear the SOFTRESET bit in @v for hwmod @oh.  Returns -EINVAL upon
+ * error or 0 upon success.
+ */
+static int _clear_softreset(struct omap_hwmod *oh, u32 *v)
+{
+       u32 softrst_mask;
+
+       if (!oh->class->sysc ||
+           !(oh->class->sysc->sysc_flags & SYSC_HAS_SOFTRESET))
+               return -EINVAL;
+
+       if (!oh->class->sysc->sysc_fields) {
+               WARN(1,
+                    "omap_hwmod: %s: sysc_fields absent for sysconfig class\n",
+                    oh->name);
+               return -EINVAL;
+       }
+
+       softrst_mask = (0x1 << oh->class->sysc->sysc_fields->srst_shift);
+
+       *v &= ~softrst_mask;
+
+       return 0;
+}
+
 /**
  * _wait_softreset_complete - wait for an OCP softreset to complete
  * @oh: struct omap_hwmod * to wait on
@@ -785,6 +815,7 @@ static int _init_interface_clks(struct omap_hwmod *oh)
                        pr_warning("omap_hwmod: %s: cannot clk_get interface_clk %s\n",
                                   oh->name, os->clk);
                        ret = -EINVAL;
+                       continue;
                }
                os->_clk = c;
                /*
@@ -821,6 +852,7 @@ static int _init_opt_clks(struct omap_hwmod *oh)
                        pr_warning("omap_hwmod: %s: cannot clk_get opt_clk %s\n",
                                   oh->name, oc->clk);
                        ret = -EINVAL;
+                       continue;
                }
                oc->_clk = c;
                /*
@@ -1911,6 +1943,12 @@ static int _ocp_softreset(struct omap_hwmod *oh)
        ret = _set_softreset(oh, &v);
        if (ret)
                goto dis_opt_clks;
+
+       _write_sysconfig(v, oh);
+       ret = _clear_softreset(oh, &v);
+       if (ret)
+               goto dis_opt_clks;
+
        _write_sysconfig(v, oh);
 
        if (oh->class->sysc->srst_udelay)
@@ -2326,38 +2364,80 @@ static int _shutdown(struct omap_hwmod *oh)
        return 0;
 }
 
+static int of_dev_find_hwmod(struct device_node *np,
+                            struct omap_hwmod *oh)
+{
+       int count, i, res;
+       const char *p;
+
+       count = of_property_count_strings(np, "ti,hwmods");
+       if (count < 1)
+               return -ENODEV;
+
+       for (i = 0; i < count; i++) {
+               res = of_property_read_string_index(np, "ti,hwmods",
+                                                   i, &p);
+               if (res)
+                       continue;
+               if (!strcmp(p, oh->name)) {
+                       pr_debug("omap_hwmod: dt %s[%i] uses hwmod %s\n",
+                                np->name, i, oh->name);
+                       return i;
+               }
+       }
+
+       return -ENODEV;
+}
+
 /**
  * of_dev_hwmod_lookup - look up needed hwmod from dt blob
  * @np: struct device_node *
  * @oh: struct omap_hwmod *
+ * @index: index of the entry found
+ * @found: struct device_node * found or NULL
  *
  * Parse the dt blob and find out needed hwmod. Recursive function is
  * implemented to take care hierarchical dt blob parsing.
- * Return: The device node on success or NULL on failure.
+ * Return: Returns 0 on success, -ENODEV when not found.
  */
-static struct device_node *of_dev_hwmod_lookup(struct device_node *np,
-                                               struct omap_hwmod *oh)
+static int of_dev_hwmod_lookup(struct device_node *np,
+                              struct omap_hwmod *oh,
+                              int *index,
+                              struct device_node **found)
 {
-       struct device_node *np0 = NULL, *np1 = NULL;
-       const char *p;
+       struct device_node *np0 = NULL;
+       int res;
+
+       res = of_dev_find_hwmod(np, oh);
+       if (res >= 0) {
+               *found = np;
+               *index = res;
+               return 0;
+       }
 
        for_each_child_of_node(np, np0) {
-               if (of_find_property(np0, "ti,hwmods", NULL)) {
-                       p = of_get_property(np0, "ti,hwmods", NULL);
-                       if (!strcmp(p, oh->name))
-                               return np0;
-                       np1 = of_dev_hwmod_lookup(np0, oh);
-                       if (np1)
-                               return np1;
+               struct device_node *fc;
+               int i;
+
+               res = of_dev_hwmod_lookup(np0, oh, &i, &fc);
+               if (res == 0) {
+                       *found = fc;
+                       *index = i;
+                       return 0;
                }
        }
-       return NULL;
+
+       *found = NULL;
+       *index = 0;
+
+       return -ENODEV;
 }
 
 /**
  * _init_mpu_rt_base - populate the virtual address for a hwmod
  * @oh: struct omap_hwmod * to locate the virtual address
  * @data: (unused, caller should pass NULL)
+ * @index: index of the reg entry iospace in device tree
  * @np: struct device_node * of the IP block's device node in the DT data
  *
  * Cache the virtual address used by the MPU to access this IP block's
@@ -2368,7 +2448,7 @@ static struct device_node *of_dev_hwmod_lookup(struct device_node *np,
  * -ENXIO on absent or invalid register target address space.
  */
 static int __init _init_mpu_rt_base(struct omap_hwmod *oh, void *data,
-                                   struct device_node *np)
+                                   int index, struct device_node *np)
 {
        struct omap_hwmod_addr_space *mem;
        void __iomem *va_start = NULL;
@@ -2390,13 +2470,17 @@ static int __init _init_mpu_rt_base(struct omap_hwmod *oh, void *data,
                if (!np)
                        return -ENXIO;
 
-               va_start = of_iomap(np, oh->mpu_rt_idx);
+               va_start = of_iomap(np, index + oh->mpu_rt_idx);
        } else {
                va_start = ioremap(mem->pa_start, mem->pa_end - mem->pa_start);
        }
 
        if (!va_start) {
-               pr_err("omap_hwmod: %s: Could not ioremap\n", oh->name);
+               if (mem)
+                       pr_err("omap_hwmod: %s: Could not ioremap\n", oh->name);
+               else
+                       pr_err("omap_hwmod: %s: Missing dt reg%i for %s\n",
+                              oh->name, index, np->full_name);
                return -ENXIO;
        }
 
@@ -2422,17 +2506,29 @@ static int __init _init_mpu_rt_base(struct omap_hwmod *oh, void *data,
  */
 static int __init _init(struct omap_hwmod *oh, void *data)
 {
-       int r;
+       int r, index;
        struct device_node *np = NULL;
 
        if (oh->_state != _HWMOD_STATE_REGISTERED)
                return 0;
 
-       if (of_have_populated_dt())
-               np = of_dev_hwmod_lookup(of_find_node_by_name(NULL, "ocp"), oh);
+       if (of_have_populated_dt()) {
+               struct device_node *bus;
+
+               bus = of_find_node_by_name(NULL, "ocp");
+               if (!bus)
+                       return -ENODEV;
+
+               r = of_dev_hwmod_lookup(bus, oh, &index, &np);
+               if (r)
+                       pr_debug("omap_hwmod: %s missing dt data\n", oh->name);
+               else if (np && index)
+                       pr_warn("omap_hwmod: %s using broken dt data from %s\n",
+                               oh->name, np->name);
+       }
 
        if (oh->class->sysc) {
-               r = _init_mpu_rt_base(oh, NULL, np);
+               r = _init_mpu_rt_base(oh, NULL, index, np);
                if (r < 0) {
                        WARN(1, "omap_hwmod: %s: doesn't have mpu register target base\n",
                             oh->name);
@@ -3169,6 +3265,11 @@ int omap_hwmod_softreset(struct omap_hwmod *oh)
                goto error;
        _write_sysconfig(v, oh);
 
+       ret = _clear_softreset(oh, &v);
+       if (ret)
+               goto error;
+       _write_sysconfig(v, oh);
+
 error:
        return ret;
 }
index 9e56fabd7fa3b834fbe09a463facd521592107a7..d33742908f970a21b24c2cefeef03799d3d84532 100644 (file)
@@ -1943,7 +1943,8 @@ static struct omap_hwmod_class_sysconfig omap3xxx_usb_host_hs_sysc = {
        .syss_offs      = 0x0014,
        .sysc_flags     = (SYSC_HAS_MIDLEMODE | SYSC_HAS_CLOCKACTIVITY |
                           SYSC_HAS_SIDLEMODE | SYSC_HAS_ENAWAKEUP |
-                          SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE),
+                          SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE |
+                          SYSS_HAS_RESET_STATUS),
        .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
                           MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART),
        .sysc_fields    = &omap_hwmod_sysc_type1,
@@ -2021,15 +2022,7 @@ static struct omap_hwmod omap3xxx_usb_host_hs_hwmod = {
         * hence HWMOD_SWSUP_MSTANDBY
         */
 
-       /*
-        * During system boot; If the hwmod framework resets the module
-        * the module will have smart idle settings; which can lead to deadlock
-        * (above Errata Id:i660); so, dont reset the module during boot;
-        * Use HWMOD_INIT_NO_RESET.
-        */
-
-       .flags          = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY |
-                         HWMOD_INIT_NO_RESET,
+       .flags          = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY,
 };
 
 /*
index 1e5b12cb8246290cc8e2865036e0f4a291513f9c..3318cae96e7d1e94a8699192d1c00512c8f34f38 100644 (file)
@@ -2937,7 +2937,7 @@ static struct omap_hwmod_class_sysconfig omap44xx_usb_host_hs_sysc = {
        .sysc_offs      = 0x0010,
        .syss_offs      = 0x0014,
        .sysc_flags     = (SYSC_HAS_MIDLEMODE | SYSC_HAS_SIDLEMODE |
-                          SYSC_HAS_SOFTRESET),
+                          SYSC_HAS_SOFTRESET | SYSC_HAS_RESET_STATUS),
        .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
                           SIDLE_SMART_WKUP | MSTANDBY_FORCE | MSTANDBY_NO |
                           MSTANDBY_SMART | MSTANDBY_SMART_WKUP),
@@ -3001,15 +3001,7 @@ static struct omap_hwmod omap44xx_usb_host_hs_hwmod = {
         * hence HWMOD_SWSUP_MSTANDBY
         */
 
-       /*
-        * During system boot; If the hwmod framework resets the module
-        * the module will have smart idle settings; which can lead to deadlock
-        * (above Errata Id:i660); so, dont reset the module during boot;
-        * Use HWMOD_INIT_NO_RESET.
-        */
-
-       .flags          = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY |
-                         HWMOD_INIT_NO_RESET,
+       .flags          = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY,
 };
 
 /*
index 9e08d6994a0b09c44760e03323c9543f720ad026..e297d6231c3aa3c35910d25f3115466be2d453ab 100644 (file)
@@ -1544,7 +1544,8 @@ static struct omap_hwmod_class_sysconfig omap54xx_usb_host_hs_sysc = {
        .rev_offs       = 0x0000,
        .sysc_offs      = 0x0010,
        .sysc_flags     = (SYSC_HAS_MIDLEMODE | SYSC_HAS_RESET_STATUS |
-                          SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET),
+                          SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET |
+                          SYSC_HAS_RESET_STATUS),
        .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
                           SIDLE_SMART_WKUP | MSTANDBY_FORCE | MSTANDBY_NO |
                           MSTANDBY_SMART | MSTANDBY_SMART_WKUP),
@@ -1598,15 +1599,7 @@ static struct omap_hwmod omap54xx_usb_host_hs_hwmod = {
         * hence HWMOD_SWSUP_MSTANDBY
         */
 
-       /*
-        * During system boot; If the hwmod framework resets the module
-        * the module will have smart idle settings; which can lead to deadlock
-        * (above Errata Id:i660); so, dont reset the module during boot;
-        * Use HWMOD_INIT_NO_RESET.
-        */
-
-       .flags          = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY |
-                         HWMOD_INIT_NO_RESET,
+       .flags          = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY,
        .main_clk       = "l3init_60m_fclk",
        .prcm = {
                .omap4 = {
index 0d5dd646f61fa7d5aa743d4c68f162a2453d00e0..263b15249b5b803436709e1e5e268b9552bedef0 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <mach/regs-ost.h>
 #include <mach/reset.h>
+#include <mach/smemc.h>
 
 unsigned int reset_status;
 EXPORT_SYMBOL(reset_status);
@@ -81,6 +82,12 @@ static void do_hw_reset(void)
        writel_relaxed(OSSR_M3, OSSR);
        /* ... in 100 ms */
        writel_relaxed(readl_relaxed(OSCR) + 368640, OSMR3);
+       /*
+        * SDRAM hangs on watchdog reset on Marvell PXA270 (erratum 71)
+        * we put SDRAM into self-refresh to prevent that
+        */
+       while (1)
+               writel_relaxed(MDREFR_SLFRSH, MDREFR);
 }
 
 void pxa_restart(enum reboot_mode mode, const char *cmd)
@@ -104,4 +111,3 @@ void pxa_restart(enum reboot_mode mode, const char *cmd)
                break;
        }
 }
-
index 0206b915a6f6e07e3de75854617284f9c56aa870..ef5557b807ed95bbfce94ecc1c3ec17549767aec 100644 (file)
@@ -425,57 +425,57 @@ static struct platform_device tosa_power_device = {
  * Tosa Keyboard
  */
 static const uint32_t tosakbd_keymap[] = {
-       KEY(0, 2, KEY_W),
-       KEY(0, 6, KEY_K),
-       KEY(0, 7, KEY_BACKSPACE),
-       KEY(0, 8, KEY_P),
-       KEY(1, 1, KEY_Q),
-       KEY(1, 2, KEY_E),
-       KEY(1, 3, KEY_T),
-       KEY(1, 4, KEY_Y),
-       KEY(1, 6, KEY_O),
-       KEY(1, 7, KEY_I),
-       KEY(1, 8, KEY_COMMA),
-       KEY(2, 1, KEY_A),
-       KEY(2, 2, KEY_D),
-       KEY(2, 3, KEY_G),
-       KEY(2, 4, KEY_U),
-       KEY(2, 6, KEY_L),
-       KEY(2, 7, KEY_ENTER),
-       KEY(2, 8, KEY_DOT),
-       KEY(3, 1, KEY_Z),
-       KEY(3, 2, KEY_C),
-       KEY(3, 3, KEY_V),
-       KEY(3, 4, KEY_J),
-       KEY(3, 5, TOSA_KEY_ADDRESSBOOK),
-       KEY(3, 6, TOSA_KEY_CANCEL),
-       KEY(3, 7, TOSA_KEY_CENTER),
-       KEY(3, 8, TOSA_KEY_OK),
-       KEY(3, 9, KEY_LEFTSHIFT),
-       KEY(4, 1, KEY_S),
-       KEY(4, 2, KEY_R),
-       KEY(4, 3, KEY_B),
-       KEY(4, 4, KEY_N),
-       KEY(4, 5, TOSA_KEY_CALENDAR),
-       KEY(4, 6, TOSA_KEY_HOMEPAGE),
-       KEY(4, 7, KEY_LEFTCTRL),
-       KEY(4, 8, TOSA_KEY_LIGHT),
-       KEY(4, 10, KEY_RIGHTSHIFT),
-       KEY(5, 1, KEY_TAB),
-       KEY(5, 2, KEY_SLASH),
-       KEY(5, 3, KEY_H),
-       KEY(5, 4, KEY_M),
-       KEY(5, 5, TOSA_KEY_MENU),
-       KEY(5, 7, KEY_UP),
-       KEY(5, 11, TOSA_KEY_FN),
-       KEY(6, 1, KEY_X),
-       KEY(6, 2, KEY_F),
-       KEY(6, 3, KEY_SPACE),
-       KEY(6, 4, KEY_APOSTROPHE),
-       KEY(6, 5, TOSA_KEY_MAIL),
-       KEY(6, 6, KEY_LEFT),
-       KEY(6, 7, KEY_DOWN),
-       KEY(6, 8, KEY_RIGHT),
+       KEY(0, 1, KEY_W),
+       KEY(0, 5, KEY_K),
+       KEY(0, 6, KEY_BACKSPACE),
+       KEY(0, 7, KEY_P),
+       KEY(1, 0, KEY_Q),
+       KEY(1, 1, KEY_E),
+       KEY(1, 2, KEY_T),
+       KEY(1, 3, KEY_Y),
+       KEY(1, 5, KEY_O),
+       KEY(1, 6, KEY_I),
+       KEY(1, 7, KEY_COMMA),
+       KEY(2, 0, KEY_A),
+       KEY(2, 1, KEY_D),
+       KEY(2, 2, KEY_G),
+       KEY(2, 3, KEY_U),
+       KEY(2, 5, KEY_L),
+       KEY(2, 6, KEY_ENTER),
+       KEY(2, 7, KEY_DOT),
+       KEY(3, 0, KEY_Z),
+       KEY(3, 1, KEY_C),
+       KEY(3, 2, KEY_V),
+       KEY(3, 3, KEY_J),
+       KEY(3, 4, TOSA_KEY_ADDRESSBOOK),
+       KEY(3, 5, TOSA_KEY_CANCEL),
+       KEY(3, 6, TOSA_KEY_CENTER),
+       KEY(3, 7, TOSA_KEY_OK),
+       KEY(3, 8, KEY_LEFTSHIFT),
+       KEY(4, 0, KEY_S),
+       KEY(4, 1, KEY_R),
+       KEY(4, 2, KEY_B),
+       KEY(4, 3, KEY_N),
+       KEY(4, 4, TOSA_KEY_CALENDAR),
+       KEY(4, 5, TOSA_KEY_HOMEPAGE),
+       KEY(4, 6, KEY_LEFTCTRL),
+       KEY(4, 7, TOSA_KEY_LIGHT),
+       KEY(4, 9, KEY_RIGHTSHIFT),
+       KEY(5, 0, KEY_TAB),
+       KEY(5, 1, KEY_SLASH),
+       KEY(5, 2, KEY_H),
+       KEY(5, 3, KEY_M),
+       KEY(5, 4, TOSA_KEY_MENU),
+       KEY(5, 6, KEY_UP),
+       KEY(5, 10, TOSA_KEY_FN),
+       KEY(6, 0, KEY_X),
+       KEY(6, 1, KEY_F),
+       KEY(6, 2, KEY_SPACE),
+       KEY(6, 3, KEY_APOSTROPHE),
+       KEY(6, 4, TOSA_KEY_MAIL),
+       KEY(6, 5, KEY_LEFT),
+       KEY(6, 6, KEY_DOWN),
+       KEY(6, 7, KEY_RIGHT),
 };
 
 static struct matrix_keymap_data tosakbd_keymap_data = {
index 9a4e910c3796154c8fa6c167851a8f6b112265f3..3a9c1f1c219dd47bd79ecb1c3bb9f1538abe4463 100644 (file)
@@ -198,10 +198,12 @@ void __init tegra_init_fuse(void)
        switch (tegra_chip_id) {
        case TEGRA20:
                tegra20_fuse_init_randomness();
+               break;
        case TEGRA30:
        case TEGRA114:
        default:
                tegra30_fuse_init_randomness();
+               break;
        }
 
        pr_info("Tegra Revision: %s SKU: %d CPU Process: %d Core Process: %d\n",
index f6b6bfa88ecff21ddde5646dfaafa0190792f247..f61a5707823a40e0af9474d4f18809f9196b1264 100644 (file)
@@ -158,13 +158,49 @@ struct dma_map_ops arm_coherent_dma_ops = {
 };
 EXPORT_SYMBOL(arm_coherent_dma_ops);
 
+static int __dma_supported(struct device *dev, u64 mask, bool warn)
+{
+       unsigned long max_dma_pfn;
+
+       /*
+        * If the mask allows for more memory than we can address,
+        * and we actually have that much memory, then we must
+        * indicate that DMA to this device is not supported.
+        */
+       if (sizeof(mask) != sizeof(dma_addr_t) &&
+           mask > (dma_addr_t)~0 &&
+           dma_to_pfn(dev, ~0) < max_pfn) {
+               if (warn) {
+                       dev_warn(dev, "Coherent DMA mask %#llx is larger than dma_addr_t allows\n",
+                                mask);
+                       dev_warn(dev, "Driver did not use or check the return value from dma_set_coherent_mask()?\n");
+               }
+               return 0;
+       }
+
+       max_dma_pfn = min(max_pfn, arm_dma_pfn_limit);
+
+       /*
+        * Translate the device's DMA mask to a PFN limit.  This
+        * PFN number includes the page which we can DMA to.
+        */
+       if (dma_to_pfn(dev, mask) < max_dma_pfn) {
+               if (warn)
+                       dev_warn(dev, "Coherent DMA mask %#llx (pfn %#lx-%#lx) covers a smaller range of system memory than the DMA zone pfn 0x0-%#lx\n",
+                                mask,
+                                dma_to_pfn(dev, 0), dma_to_pfn(dev, mask) + 1,
+                                max_dma_pfn + 1);
+               return 0;
+       }
+
+       return 1;
+}
+
 static u64 get_coherent_dma_mask(struct device *dev)
 {
        u64 mask = (u64)DMA_BIT_MASK(32);
 
        if (dev) {
-               unsigned long max_dma_pfn;
-
                mask = dev->coherent_dma_mask;
 
                /*
@@ -176,34 +212,8 @@ static u64 get_coherent_dma_mask(struct device *dev)
                        return 0;
                }
 
-               max_dma_pfn = min(max_pfn, arm_dma_pfn_limit);
-
-               /*
-                * If the mask allows for more memory than we can address,
-                * and we actually have that much memory, then fail the
-                * allocation.
-                */
-               if (sizeof(mask) != sizeof(dma_addr_t) &&
-                   mask > (dma_addr_t)~0 &&
-                   dma_to_pfn(dev, ~0) > max_dma_pfn) {
-                       dev_warn(dev, "Coherent DMA mask %#llx is larger than dma_addr_t allows\n",
-                                mask);
-                       dev_warn(dev, "Driver did not use or check the return value from dma_set_coherent_mask()?\n");
-                       return 0;
-               }
-
-               /*
-                * Now check that the mask, when translated to a PFN,
-                * fits within the allowable addresses which we can
-                * allocate.
-                */
-               if (dma_to_pfn(dev, mask) < max_dma_pfn) {
-                       dev_warn(dev, "Coherent DMA mask %#llx (pfn %#lx-%#lx) covers a smaller range of system memory than the DMA zone pfn 0x0-%#lx\n",
-                                mask,
-                                dma_to_pfn(dev, 0), dma_to_pfn(dev, mask) + 1,
-                                arm_dma_pfn_limit + 1);
+               if (!__dma_supported(dev, mask, true))
                        return 0;
-               }
        }
 
        return mask;
@@ -1032,28 +1042,7 @@ void arm_dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
  */
 int dma_supported(struct device *dev, u64 mask)
 {
-       unsigned long limit;
-
-       /*
-        * If the mask allows for more memory than we can address,
-        * and we actually have that much memory, then we must
-        * indicate that DMA to this device is not supported.
-        */
-       if (sizeof(mask) != sizeof(dma_addr_t) &&
-           mask > (dma_addr_t)~0 &&
-           dma_to_pfn(dev, ~0) > arm_dma_pfn_limit)
-               return 0;
-
-       /*
-        * Translate the device's DMA mask to a PFN limit.  This
-        * PFN number includes the page which we can DMA to.
-        */
-       limit = dma_to_pfn(dev, mask);
-
-       if (limit < arm_dma_pfn_limit)
-               return 0;
-
-       return 1;
+       return __dma_supported(dev, mask, false);
 }
 EXPORT_SYMBOL(dma_supported);
 
index 3e8f106ee5fe01855fe12f66b0c581822c0521da..1f7b19a470606726595ebc692f3b05aae94729c6 100644 (file)
@@ -229,7 +229,7 @@ void __init setup_dma_zone(const struct machine_desc *mdesc)
 #ifdef CONFIG_ZONE_DMA
        if (mdesc->dma_zone_size) {
                arm_dma_zone_size = mdesc->dma_zone_size;
-               arm_dma_limit = PHYS_OFFSET + arm_dma_zone_size - 1;
+               arm_dma_limit = __pv_phys_offset + arm_dma_zone_size - 1;
        } else
                arm_dma_limit = 0xffffffff;
        arm_dma_pfn_limit = arm_dma_limit >> PAGE_SHIFT;
index 7b1f2cd854008c16117cf5c39c06f4bd2115a9fa..1f121497b5177c4a3ac30d715dd98a1f623686cd 100644 (file)
@@ -298,8 +298,10 @@ static int __init set_abdac_rate(struct platform_device *pdev)
         */
        retval = clk_round_rate(pll1,
                        CONFIG_BOARD_FAVR32_ABDAC_RATE * 256 * 16);
-       if (retval < 0)
+       if (retval <= 0) {
+               retval = -EINVAL;
                goto out_abdac;
+       }
 
        retval = clk_set_rate(pll1, retval);
        if (retval != 0)
index d5aff36ade922f07ca18c34552b140919d598dfc..4733e38e7ae62cb111324ef17877bbd90b97a712 100644 (file)
@@ -59,7 +59,6 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 # CONFIG_PREVENT_FIRMWARE_BUILD is not set
 # CONFIG_FW_LOADER is not set
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
index 4abcf435d599a4a88b26ae1049b401dfcfa8a2e8..1be0ee31bd91c277753a5be27510ced4554712bf 100644 (file)
@@ -61,7 +61,6 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 # CONFIG_PREVENT_FIRMWARE_BUILD is not set
 # CONFIG_FW_LOADER is not set
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
index 18f3fa0470ff294a9755cd263d30c4a4080198e7..796e536f7bc43576d7079a41237356eb5977dbfe 100644 (file)
@@ -60,7 +60,6 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 # CONFIG_PREVENT_FIRMWARE_BUILD is not set
 # CONFIG_FW_LOADER is not set
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
index 06e389cfcd126e4c75111398758a5813d7fe2275..9a57da44eb6fd3390a5df2ce4d905bec1ec88c79 100644 (file)
@@ -48,7 +48,6 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 # CONFIG_PREVENT_FIRMWARE_BUILD is not set
 # CONFIG_FW_LOADER is not set
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
index 2518a1368d7caea758cfba9b152abe07b59870d0..97fe1b399b069d2965552ef78a7c3e29da1dd084 100644 (file)
@@ -59,7 +59,6 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 # CONFIG_PREVENT_FIRMWARE_BUILD is not set
 # CONFIG_FW_LOADER is not set
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
index 245ef6bd0fa61f56de23c1b4ce57abb51771489c..a176d24467e9d28f25e31364aa8e92b0fd3d8de0 100644 (file)
@@ -62,7 +62,6 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 # CONFIG_PREVENT_FIRMWARE_BUILD is not set
 # CONFIG_FW_LOADER is not set
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
index fa6cbac6e4189c2e5a39eed8b6cb49ec44a3dd96..d1bf6dcfc47d4c289fca01896377d67cfbc62a94 100644 (file)
@@ -61,7 +61,6 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 # CONFIG_PREVENT_FIRMWARE_BUILD is not set
 # CONFIG_FW_LOADER is not set
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
index bbd5131021a57d840bed7dede2db9d61b074e8f4..2813dd2b913876b0604c31751204b16ac6eb12fe 100644 (file)
@@ -53,7 +53,6 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 # CONFIG_PREVENT_FIRMWARE_BUILD is not set
 # CONFIG_FW_LOADER is not set
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
index c1cd726f901233b1dd552cb3d28f3375682f3ad9..f8ff3a3baad4cc702ed4b374b95c21c943b0a84f 100644 (file)
@@ -42,7 +42,6 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 # CONFIG_PREVENT_FIRMWARE_BUILD is not set
 # CONFIG_FW_LOADER is not set
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
index 754ae56b276739a58113bc89b87395d0b35b6ab2..992228e54e38cf56dc0cc1567c129d5ec907543b 100644 (file)
@@ -42,7 +42,6 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 # CONFIG_PREVENT_FIRMWARE_BUILD is not set
 # CONFIG_FW_LOADER is not set
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
index 58589d8cc0acd829af7612b782368a907f6c3e64..b8e698b0d1fa30e2563fff8e9a0792a36b8ec3a1 100644 (file)
@@ -54,7 +54,6 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 # CONFIG_PREVENT_FIRMWARE_BUILD is not set
 # CONFIG_FW_LOADER is not set
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
index c90fbf6d35bc16d60f12d1e5be4cf836f2fc9391..07bed3f7eb5e6022372ed35b6a8e303356cbbc8a 100644 (file)
@@ -58,7 +58,6 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 # CONFIG_PREVENT_FIRMWARE_BUILD is not set
 # CONFIG_FW_LOADER is not set
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
index ba7c31e269cb0aed7b0ba9a72c1ce641cf0e346a..18db853386c81e73087c2c106d7271a415c3dce2 100644 (file)
@@ -58,7 +58,6 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 # CONFIG_PREVENT_FIRMWARE_BUILD is not set
 # CONFIG_FW_LOADER is not set
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
index 65de4431108c837334dc07facfc578fb815d55cd..91df6b2986be2a1691449bfe47953715e387060d 100644 (file)
@@ -46,7 +46,6 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 # CONFIG_FW_LOADER is not set
 CONFIG_MTD=y
 CONFIG_MTD_CONCAT=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_CFI=y
index 0a8bfdc420e0e6730c4ba1464de3ee92fafd8a2f..d630e089dd322c6ab735831a4ebd5424308a9a75 100644 (file)
@@ -49,7 +49,6 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 # CONFIG_PREVENT_FIRMWARE_BUILD is not set
 # CONFIG_FW_LOADER is not set
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
index 12f828ad5058d09158f8d3e2007b76a7a42cbb4a..d0f771be9e96eda02c1045bbb5702cc9b9f74b8d 100644 (file)
@@ -59,7 +59,7 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id)
 static struct irqaction timer_irqaction = {
        .handler        = timer_interrupt,
        /* Oprofile uses the same irq as the timer, so allow it to be shared */
-       .flags          = IRQF_TIMER | IRQF_DISABLED | IRQF_SHARED,
+       .flags          = IRQF_TIMER | IRQF_SHARED,
        .name           = "avr32_comparator",
 };
 
index 32d680eb6f4842be56d17f40197c2a6fd4f77f37..db190842b80c74e026784037516df9b27471f4b8 100644 (file)
@@ -181,7 +181,7 @@ static const struct platform_suspend_ops avr32_pm_ops = {
        .enter  = avr32_pm_enter,
 };
 
-static unsigned long avr32_pm_offset(void *symbol)
+static unsigned long __init avr32_pm_offset(void *symbol)
 {
        extern u8 pm_exception[];
 
index 033c06be1d840da02423d596121940d0aa11adb5..7bdcf340016c412285df77ac56162aaa94982416 100644 (file)
@@ -720,13 +720,13 @@ int64_t opal_pci_next_error(uint64_t phb_id, uint64_t *first_frozen_pe,
 int64_t opal_pci_poll(uint64_t phb_id);
 int64_t opal_return_cpu(void);
 
-int64_t opal_xscom_read(uint32_t gcid, uint32_t pcb_addr, uint64_t *val);
+int64_t opal_xscom_read(uint32_t gcid, uint32_t pcb_addr, __be64 *val);
 int64_t opal_xscom_write(uint32_t gcid, uint32_t pcb_addr, uint64_t val);
 
 int64_t opal_lpc_write(uint32_t chip_id, enum OpalLPCAddressType addr_type,
                       uint32_t addr, uint32_t data, uint32_t sz);
 int64_t opal_lpc_read(uint32_t chip_id, enum OpalLPCAddressType addr_type,
-                     uint32_t addr, uint32_t *data, uint32_t sz);
+                     uint32_t addr, __be32 *data, uint32_t sz);
 int64_t opal_validate_flash(uint64_t buffer, uint32_t *size, uint32_t *result);
 int64_t opal_manage_flash(uint8_t op);
 int64_t opal_update_flash(uint64_t blk_list);
index 779a78c2643502a4414af7d646f4dce810deba72..11c1d069d920a1fc97ec601ab0542c41708d7cc1 100644 (file)
@@ -124,15 +124,15 @@ ssize_t copy_oldmem_page(unsigned long pfn, char *buf,
 void crash_free_reserved_phys_range(unsigned long begin, unsigned long end)
 {
        unsigned long addr;
-       const u32 *basep, *sizep;
+       const __be32 *basep, *sizep;
        unsigned int rtas_start = 0, rtas_end = 0;
 
        basep = of_get_property(rtas.dev, "linux,rtas-base", NULL);
        sizep = of_get_property(rtas.dev, "rtas-size", NULL);
 
        if (basep && sizep) {
-               rtas_start = *basep;
-               rtas_end = *basep + *sizep;
+               rtas_start = be32_to_cpup(basep);
+               rtas_end = rtas_start + be32_to_cpup(sizep);
        }
 
        for (addr = begin; addr < end; addr += PAGE_SIZE) {
index 75fb40498b419c3e8c1f2c639acfaa4f61f419d2..2e3d2bf536c5662c00f02e07cf36cd1e4b111825 100644 (file)
@@ -1555,7 +1555,7 @@ long arch_ptrace(struct task_struct *child, long request,
 
                        flush_fp_to_thread(child);
                        if (fpidx < (PT_FPSCR - PT_FPR0))
-                               memcpy(&tmp, &child->thread.fp_state.fpr,
+                               memcpy(&tmp, &child->thread.TS_FPR(fpidx),
                                       sizeof(long));
                        else
                                tmp = child->thread.fp_state.fpscr;
@@ -1588,7 +1588,7 @@ long arch_ptrace(struct task_struct *child, long request,
 
                        flush_fp_to_thread(child);
                        if (fpidx < (PT_FPSCR - PT_FPR0))
-                               memcpy(&child->thread.fp_state.fpr, &data,
+                               memcpy(&child->thread.TS_FPR(fpidx), &data,
                                       sizeof(long));
                        else
                                child->thread.fp_state.fpscr = data;
index febc80445d25850acf2578943c60357d8436b1c2..bc76cc6b419c2a8d0b5491637afadfe046278142 100644 (file)
@@ -479,7 +479,7 @@ void __init smp_setup_cpu_maps(void)
        if (machine_is(pseries) && firmware_has_feature(FW_FEATURE_LPAR) &&
            (dn = of_find_node_by_path("/rtas"))) {
                int num_addr_cell, num_size_cell, maxcpus;
-               const unsigned int *ireg;
+               const __be32 *ireg;
 
                num_addr_cell = of_n_addr_cells(dn);
                num_size_cell = of_n_size_cells(dn);
@@ -489,7 +489,7 @@ void __init smp_setup_cpu_maps(void)
                if (!ireg)
                        goto out;
 
-               maxcpus = ireg[num_addr_cell + num_size_cell];
+               maxcpus = be32_to_cpup(ireg + num_addr_cell + num_size_cell);
 
                /* Double maxcpus for processors which have SMT capability */
                if (cpu_has_feature(CPU_FTR_SMT))
index a3b64f3bf9a298b057cfdc57b008ea01eebecf63..c1cf4a1522d9940bf3bb97a3e995a2642dee41ca 100644 (file)
@@ -580,7 +580,7 @@ int __cpu_up(unsigned int cpu, struct task_struct *tidle)
 int cpu_to_core_id(int cpu)
 {
        struct device_node *np;
-       const int *reg;
+       const __be32 *reg;
        int id = -1;
 
        np = of_get_cpu_node(cpu, NULL);
@@ -591,7 +591,7 @@ int cpu_to_core_id(int cpu)
        if (!reg)
                goto out;
 
-       id = *reg;
+       id = be32_to_cpup(reg);
 out:
        of_node_put(np);
        return id;
index e7e59e4f9892deb85b8ff96b502a6c14fe989d19..79d83cad3d6709c543dad5bb96eafba2ff8756a7 100644 (file)
@@ -24,25 +24,25 @@ static int opal_lpc_chip_id = -1;
 static u8 opal_lpc_inb(unsigned long port)
 {
        int64_t rc;
-       uint32_t data;
+       __be32 data;
 
        if (opal_lpc_chip_id < 0 || port > 0xffff)
                return 0xff;
        rc = opal_lpc_read(opal_lpc_chip_id, OPAL_LPC_IO, port, &data, 1);
-       return rc ? 0xff : data;
+       return rc ? 0xff : be32_to_cpu(data);
 }
 
 static __le16 __opal_lpc_inw(unsigned long port)
 {
        int64_t rc;
-       uint32_t data;
+       __be32 data;
 
        if (opal_lpc_chip_id < 0 || port > 0xfffe)
                return 0xffff;
        if (port & 1)
                return (__le16)opal_lpc_inb(port) << 8 | opal_lpc_inb(port + 1);
        rc = opal_lpc_read(opal_lpc_chip_id, OPAL_LPC_IO, port, &data, 2);
-       return rc ? 0xffff : data;
+       return rc ? 0xffff : be32_to_cpu(data);
 }
 static u16 opal_lpc_inw(unsigned long port)
 {
@@ -52,7 +52,7 @@ static u16 opal_lpc_inw(unsigned long port)
 static __le32 __opal_lpc_inl(unsigned long port)
 {
        int64_t rc;
-       uint32_t data;
+       __be32 data;
 
        if (opal_lpc_chip_id < 0 || port > 0xfffc)
                return 0xffffffff;
@@ -62,7 +62,7 @@ static __le32 __opal_lpc_inl(unsigned long port)
                       (__le32)opal_lpc_inb(port + 2) <<  8 |
                               opal_lpc_inb(port + 3);
        rc = opal_lpc_read(opal_lpc_chip_id, OPAL_LPC_IO, port, &data, 4);
-       return rc ? 0xffffffff : data;
+       return rc ? 0xffffffff : be32_to_cpu(data);
 }
 
 static u32 opal_lpc_inl(unsigned long port)
index 4d99a8fd55acf2a286e8f7877cd919d2150355bf..4fbf276ac99eeb4e2900196e3905a3343bedc988 100644 (file)
@@ -96,9 +96,11 @@ static int opal_scom_read(scom_map_t map, u64 reg, u64 *value)
 {
        struct opal_scom_map *m = map;
        int64_t rc;
+       __be64 v;
 
        reg = opal_scom_unmangle(reg);
-       rc = opal_xscom_read(m->chip, m->addr + reg, (uint64_t *)__pa(value));
+       rc = opal_xscom_read(m->chip, m->addr + reg, (__be64 *)__pa(&v));
+       *value = be64_to_cpu(v);
        return opal_xscom_err_xlate(rc);
 }
 
index e738007eae643262d72942c599a6418b252b4849..c9fecf09b8fada71dec94e9833c35be524b498e4 100644 (file)
@@ -157,7 +157,7 @@ static void parse_ppp_data(struct seq_file *m)
 {
        struct hvcall_ppp_data ppp_data;
        struct device_node *root;
-       const int *perf_level;
+       const __be32 *perf_level;
        int rc;
 
        rc = h_get_ppp(&ppp_data);
@@ -201,7 +201,7 @@ static void parse_ppp_data(struct seq_file *m)
                perf_level = of_get_property(root,
                                "ibm,partition-performance-parameters-level",
                                             NULL);
-               if (perf_level && (*perf_level >= 1)) {
+               if (perf_level && (be32_to_cpup(perf_level) >= 1)) {
                        seq_printf(m,
                            "physical_procs_allocated_to_virtualization=%d\n",
                                   ppp_data.phys_platform_procs);
@@ -435,7 +435,7 @@ static int pseries_lparcfg_data(struct seq_file *m, void *v)
        int partition_potential_processors;
        int partition_active_processors;
        struct device_node *rtas_node;
-       const int *lrdrp = NULL;
+       const __be32 *lrdrp = NULL;
 
        rtas_node = of_find_node_by_path("/rtas");
        if (rtas_node)
@@ -444,7 +444,7 @@ static int pseries_lparcfg_data(struct seq_file *m, void *v)
        if (lrdrp == NULL) {
                partition_potential_processors = vdso_data->processorCount;
        } else {
-               partition_potential_processors = *(lrdrp + 4);
+               partition_potential_processors = be32_to_cpup(lrdrp + 4);
        }
        of_node_put(rtas_node);
 
@@ -654,7 +654,7 @@ static int lparcfg_data(struct seq_file *m, void *v)
        const char *model = "";
        const char *system_id = "";
        const char *tmp;
-       const unsigned int *lp_index_ptr;
+       const __be32 *lp_index_ptr;
        unsigned int lp_index = 0;
 
        seq_printf(m, "%s %s\n", MODULE_NAME, MODULE_VERS);
@@ -670,7 +670,7 @@ static int lparcfg_data(struct seq_file *m, void *v)
                lp_index_ptr = of_get_property(rootdn, "ibm,partition-no",
                                        NULL);
                if (lp_index_ptr)
-                       lp_index = *lp_index_ptr;
+                       lp_index = be32_to_cpup(lp_index_ptr);
                of_node_put(rootdn);
        }
        seq_printf(m, "serial_number=%s\n", system_id);
index 6d2f0abce6fae652d207b499ac99a47e20a500f2..0c882e83c4ce29373f6d3957b7de34979d9fae98 100644 (file)
@@ -130,7 +130,8 @@ static int check_req(struct pci_dev *pdev, int nvec, char *prop_name)
 {
        struct device_node *dn;
        struct pci_dn *pdn;
-       const u32 *req_msi;
+       const __be32 *p;
+       u32 req_msi;
 
        pdn = pci_get_pdn(pdev);
        if (!pdn)
@@ -138,19 +139,20 @@ static int check_req(struct pci_dev *pdev, int nvec, char *prop_name)
 
        dn = pdn->node;
 
-       req_msi = of_get_property(dn, prop_name, NULL);
-       if (!req_msi) {
+       p = of_get_property(dn, prop_name, NULL);
+       if (!p) {
                pr_debug("rtas_msi: No %s on %s\n", prop_name, dn->full_name);
                return -ENOENT;
        }
 
-       if (*req_msi < nvec) {
+       req_msi = be32_to_cpup(p);
+       if (req_msi < nvec) {
                pr_debug("rtas_msi: %s requests < %d MSIs\n", prop_name, nvec);
 
-               if (*req_msi == 0) /* Be paranoid */
+               if (req_msi == 0) /* Be paranoid */
                        return -ENOSPC;
 
-               return *req_msi;
+               return req_msi;
        }
 
        return 0;
@@ -171,7 +173,7 @@ static int check_req_msix(struct pci_dev *pdev, int nvec)
 static struct device_node *find_pe_total_msi(struct pci_dev *dev, int *total)
 {
        struct device_node *dn;
-       const u32 *p;
+       const __be32 *p;
 
        dn = of_node_get(pci_device_to_OF_node(dev));
        while (dn) {
@@ -179,7 +181,7 @@ static struct device_node *find_pe_total_msi(struct pci_dev *dev, int *total)
                if (p) {
                        pr_debug("rtas_msi: found prop on dn %s\n",
                                dn->full_name);
-                       *total = *p;
+                       *total = be32_to_cpup(p);
                        return dn;
                }
 
@@ -232,13 +234,13 @@ struct msi_counts {
 static void *count_non_bridge_devices(struct device_node *dn, void *data)
 {
        struct msi_counts *counts = data;
-       const u32 *p;
+       const __be32 *p;
        u32 class;
 
        pr_debug("rtas_msi: counting %s\n", dn->full_name);
 
        p = of_get_property(dn, "class-code", NULL);
-       class = p ? *p : 0;
+       class = p ? be32_to_cpup(p) : 0;
 
        if ((class >> 8) != PCI_CLASS_BRIDGE_PCI)
                counts->num_devices++;
@@ -249,7 +251,7 @@ static void *count_non_bridge_devices(struct device_node *dn, void *data)
 static void *count_spare_msis(struct device_node *dn, void *data)
 {
        struct msi_counts *counts = data;
-       const u32 *p;
+       const __be32 *p;
        int req;
 
        if (dn == counts->requestor)
@@ -260,11 +262,11 @@ static void *count_spare_msis(struct device_node *dn, void *data)
                req = 0;
                p = of_get_property(dn, "ibm,req#msi", NULL);
                if (p)
-                       req = *p;
+                       req = be32_to_cpup(p);
 
                p = of_get_property(dn, "ibm,req#msi-x", NULL);
                if (p)
-                       req = max(req, (int)*p);
+                       req = max(req, (int)be32_to_cpup(p));
        }
 
        if (req < counts->quota)
index 7bfaf58d4664460db12c94499fc151e251f47f68..d7096f2f7751a5a0e41cb30ee48fef3242901f09 100644 (file)
@@ -43,8 +43,8 @@ static char nvram_buf[NVRW_CNT];      /* assume this is in the first 4GB */
 static DEFINE_SPINLOCK(nvram_lock);
 
 struct err_log_info {
-       int error_type;
-       unsigned int seq_num;
+       __be32 error_type;
+       __be32 seq_num;
 };
 
 struct nvram_os_partition {
@@ -79,9 +79,9 @@ static const char *pseries_nvram_os_partitions[] = {
 };
 
 struct oops_log_info {
-       u16 version;
-       u16 report_length;
-       u64 timestamp;
+       __be16 version;
+       __be16 report_length;
+       __be64 timestamp;
 } __attribute__((packed));
 
 static void oops_to_nvram(struct kmsg_dumper *dumper,
@@ -291,8 +291,8 @@ int nvram_write_os_partition(struct nvram_os_partition *part, char * buff,
                length = part->size;
        }
 
-       info.error_type = err_type;
-       info.seq_num = error_log_cnt;
+       info.error_type = cpu_to_be32(err_type);
+       info.seq_num = cpu_to_be32(error_log_cnt);
 
        tmp_index = part->index;
 
@@ -364,8 +364,8 @@ int nvram_read_partition(struct nvram_os_partition *part, char *buff,
        }
 
        if (part->os_partition) {
-               *error_log_cnt = info.seq_num;
-               *err_type = info.error_type;
+               *error_log_cnt = be32_to_cpu(info.seq_num);
+               *err_type = be32_to_cpu(info.error_type);
        }
 
        return 0;
@@ -529,9 +529,9 @@ static int zip_oops(size_t text_len)
                pr_err("nvram: logging uncompressed oops/panic report\n");
                return -1;
        }
-       oops_hdr->version = OOPS_HDR_VERSION;
-       oops_hdr->report_length = (u16) zipped_len;
-       oops_hdr->timestamp = get_seconds();
+       oops_hdr->version = cpu_to_be16(OOPS_HDR_VERSION);
+       oops_hdr->report_length = cpu_to_be16(zipped_len);
+       oops_hdr->timestamp = cpu_to_be64(get_seconds());
        return 0;
 }
 
@@ -574,9 +574,9 @@ static int nvram_pstore_write(enum pstore_type_id type,
                                clobbering_unread_rtas_event())
                return -1;
 
-       oops_hdr->version = OOPS_HDR_VERSION;
-       oops_hdr->report_length = (u16) size;
-       oops_hdr->timestamp = get_seconds();
+       oops_hdr->version = cpu_to_be16(OOPS_HDR_VERSION);
+       oops_hdr->report_length = cpu_to_be16(size);
+       oops_hdr->timestamp = cpu_to_be64(get_seconds());
 
        if (compressed)
                err_type = ERR_TYPE_KERNEL_PANIC_GZ;
@@ -670,16 +670,16 @@ static ssize_t nvram_pstore_read(u64 *id, enum pstore_type_id *type,
                size_t length, hdr_size;
 
                oops_hdr = (struct oops_log_info *)buff;
-               if (oops_hdr->version < OOPS_HDR_VERSION) {
+               if (be16_to_cpu(oops_hdr->version) < OOPS_HDR_VERSION) {
                        /* Old format oops header had 2-byte record size */
                        hdr_size = sizeof(u16);
-                       length = oops_hdr->version;
+                       length = be16_to_cpu(oops_hdr->version);
                        time->tv_sec = 0;
                        time->tv_nsec = 0;
                } else {
                        hdr_size = sizeof(*oops_hdr);
-                       length = oops_hdr->report_length;
-                       time->tv_sec = oops_hdr->timestamp;
+                       length = be16_to_cpu(oops_hdr->report_length);
+                       time->tv_sec = be64_to_cpu(oops_hdr->timestamp);
                        time->tv_nsec = 0;
                }
                *buf = kmalloc(length, GFP_KERNEL);
@@ -889,13 +889,13 @@ static void oops_to_nvram(struct kmsg_dumper *dumper,
                kmsg_dump_get_buffer(dumper, false,
                                     oops_data, oops_data_sz, &text_len);
                err_type = ERR_TYPE_KERNEL_PANIC;
-               oops_hdr->version = OOPS_HDR_VERSION;
-               oops_hdr->report_length = (u16) text_len;
-               oops_hdr->timestamp = get_seconds();
+               oops_hdr->version = cpu_to_be16(OOPS_HDR_VERSION);
+               oops_hdr->report_length = cpu_to_be16(text_len);
+               oops_hdr->timestamp = cpu_to_be64(get_seconds());
        }
 
        (void) nvram_write_os_partition(&oops_log_partition, oops_buf,
-               (int) (sizeof(*oops_hdr) + oops_hdr->report_length), err_type,
+               (int) (sizeof(*oops_hdr) + text_len), err_type,
                ++oops_count);
 
        spin_unlock_irqrestore(&lock, flags);
index 5f93856cdf479a3950cd053288174e1a85db4cad..70670a2d9cf2ddd691a936dbe489d8e338ed4029 100644 (file)
@@ -113,7 +113,7 @@ int pseries_root_bridge_prepare(struct pci_host_bridge *bridge)
 {
        struct device_node *dn, *pdn;
        struct pci_bus *bus;
-       const uint32_t *pcie_link_speed_stats;
+       const __be32 *pcie_link_speed_stats;
 
        bus = bridge->bus;
 
@@ -122,7 +122,7 @@ int pseries_root_bridge_prepare(struct pci_host_bridge *bridge)
                return 0;
 
        for (pdn = dn; pdn != NULL; pdn = of_get_next_parent(pdn)) {
-               pcie_link_speed_stats = (const uint32_t *) of_get_property(pdn,
+               pcie_link_speed_stats = of_get_property(pdn,
                        "ibm,pcie-link-speed-stats", NULL);
                if (pcie_link_speed_stats)
                        break;
@@ -135,7 +135,7 @@ int pseries_root_bridge_prepare(struct pci_host_bridge *bridge)
                return 0;
        }
 
-       switch (pcie_link_speed_stats[0]) {
+       switch (be32_to_cpup(pcie_link_speed_stats)) {
        case 0x01:
                bus->max_bus_speed = PCIE_SPEED_2_5GT;
                break;
@@ -147,7 +147,7 @@ int pseries_root_bridge_prepare(struct pci_host_bridge *bridge)
                break;
        }
 
-       switch (pcie_link_speed_stats[1]) {
+       switch (be32_to_cpup(pcie_link_speed_stats)) {
        case 0x01:
                bus->cur_bus_speed = PCIE_SPEED_2_5GT;
                break;
index 5877e71901b345ef191a911f9ad0ba537abd9c8c..1e1a03d2d19fbbb35804d4fc28d8d9eac355a9c4 100644 (file)
@@ -347,14 +347,14 @@ config SMP
          Even if you don't know what to do here, say Y.
 
 config NR_CPUS
-       int "Maximum number of CPUs (2-64)"
-       range 2 64
+       int "Maximum number of CPUs (2-256)"
+       range 2 256
        depends on SMP
        default "32" if !64BIT
        default "64" if 64BIT
        help
          This allows you to specify the maximum number of CPUs which this
-         kernel will support.  The maximum supported value is 64 and the
+         kernel will support. The maximum supported value is 256 and the
          minimum value which makes sense is 2.
 
          This is purely to save memory - each supported CPU adds
index 30ef748bc161eb3a7f52084ea763d54fe6ed09fc..2f390956c7c1c930722320956a54d1e65ada5673 100644 (file)
@@ -8,6 +8,7 @@
 
 #include <linux/types.h>
 #include <asm/chpid.h>
+#include <asm/cpu.h>
 
 #define SCLP_CHP_INFO_MASK_SIZE                32
 
@@ -37,7 +38,7 @@ struct sclp_cpu_info {
        unsigned int standby;
        unsigned int combined;
        int has_cpu_type;
-       struct sclp_cpu_entry cpu[255];
+       struct sclp_cpu_entry cpu[MAX_CPU_ADDRESS + 1];
 };
 
 int sclp_get_cpu_info(struct sclp_cpu_info *info);
index 496116cd65ec8ef3a1b566ac8c1c0641dfcad5f4..e4c99a1836511b16b90de5b4591bea5dc9fc8e69 100644 (file)
@@ -72,6 +72,7 @@ int main(void)
        /* constants used by the vdso */
        DEFINE(__CLOCK_REALTIME, CLOCK_REALTIME);
        DEFINE(__CLOCK_MONOTONIC, CLOCK_MONOTONIC);
+       DEFINE(__CLOCK_THREAD_CPUTIME_ID, CLOCK_THREAD_CPUTIME_ID);
        DEFINE(__CLOCK_REALTIME_RES, MONOTONIC_RES_NSEC);
        BLANK();
        /* idle data offsets */
index a84476f2a9bb3ae488eb7a936021a744a822dd31..613649096783401e0cf9acf73069dff48a35e438 100644 (file)
@@ -125,7 +125,7 @@ int vdso_alloc_per_cpu(struct _lowcore *lowcore)
                psal[i] = 0x80000000;
 
        lowcore->paste[4] = (u32)(addr_t) psal;
-       psal[0] = 0x20000000;
+       psal[0] = 0x02000000;
        psal[2] = (u32)(addr_t) aste;
        *(unsigned long *) (aste + 2) = segment_table +
                _ASCE_TABLE_LENGTH + _ASCE_USER_BITS + _ASCE_TYPE_SEGMENT;
index 5be8e472f57d1d0debe31c849b4177492380d957..65fc3979c2f11bb037fd7f646c18a1188b4c4553 100644 (file)
@@ -46,18 +46,13 @@ __kernel_clock_gettime:
        jnm     3f
        a       %r0,__VDSO_TK_MULT(%r5)
 3:     alr     %r0,%r2
-       al      %r0,__VDSO_XTIME_NSEC(%r5)      /*  + tk->xtime_nsec */
-       al      %r1,__VDSO_XTIME_NSEC+4(%r5)
-       brc     12,4f
-       ahi     %r0,1
-4:     al      %r0,__VDSO_WTOM_NSEC(%r5)       /*  + wall_to_monotonic.nsec */
+       al      %r0,__VDSO_WTOM_NSEC(%r5)
        al      %r1,__VDSO_WTOM_NSEC+4(%r5)
        brc     12,5f
        ahi     %r0,1
 5:     l       %r2,__VDSO_TK_SHIFT(%r5)        /* Timekeeper shift */
        srdl    %r0,0(%r2)                      /*  >> tk->shift */
-       l       %r2,__VDSO_XTIME_SEC+4(%r5)
-       al      %r2,__VDSO_WTOM_SEC+4(%r5)
+       l       %r2,__VDSO_WTOM_SEC+4(%r5)
        cl      %r4,__VDSO_UPD_COUNT+4(%r5)     /* check update counter */
        jne     1b
        basr    %r5,0
index 176e1f75f9aa6c1554dbf0818b7d4cd6661c0846..34deba7c7ed1d8b18036b0b07f9b7cd9d41e9259 100644 (file)
@@ -23,7 +23,9 @@ __kernel_clock_getres:
        je      0f
        cghi    %r2,__CLOCK_MONOTONIC
        je      0f
-       cghi    %r2,-2          /* CLOCK_THREAD_CPUTIME_ID for this thread */
+       cghi    %r2,__CLOCK_THREAD_CPUTIME_ID
+       je      0f
+       cghi    %r2,-2          /* Per-thread CPUCLOCK with PID=0, VIRT=1 */
        jne     2f
        larl    %r5,_vdso_data
        icm     %r0,15,__LC_ECTG_OK(%r5)
index 0add1072ba306623665148816155f951f0baeeda..91940ed33a4ab21686f890481545cbfdd9404468 100644 (file)
@@ -22,7 +22,9 @@ __kernel_clock_gettime:
        larl    %r5,_vdso_data
        cghi    %r2,__CLOCK_REALTIME
        je      4f
-       cghi    %r2,-2          /* CLOCK_THREAD_CPUTIME_ID for this thread */
+       cghi    %r2,__CLOCK_THREAD_CPUTIME_ID
+       je      9f
+       cghi    %r2,-2          /* Per-thread CPUCLOCK with PID=0, VIRT=1 */
        je      9f
        cghi    %r2,__CLOCK_MONOTONIC
        jne     12f
@@ -35,13 +37,11 @@ __kernel_clock_gettime:
        jnz     0b
        stck    48(%r15)                        /* Store TOD clock */
        lgf     %r2,__VDSO_TK_SHIFT(%r5)        /* Timekeeper shift */
-       lg      %r0,__VDSO_XTIME_SEC(%r5)       /* tk->xtime_sec */
-       alg     %r0,__VDSO_WTOM_SEC(%r5)        /*  + wall_to_monotonic.sec */
+       lg      %r0,__VDSO_WTOM_SEC(%r5)
        lg      %r1,48(%r15)
        sg      %r1,__VDSO_XTIME_STAMP(%r5)     /* TOD - cycle_last */
        msgf    %r1,__VDSO_TK_MULT(%r5)         /*  * tk->mult */
-       alg     %r1,__VDSO_XTIME_NSEC(%r5)      /*  + tk->xtime_nsec */
-       alg     %r1,__VDSO_WTOM_NSEC(%r5)       /*  + wall_to_monotonic.nsec */
+       alg     %r1,__VDSO_WTOM_NSEC(%r5)
        srlg    %r1,%r1,0(%r2)                  /*  >> tk->shift */
        clg     %r4,__VDSO_UPD_COUNT(%r5)       /* check update counter */
        jne     0b
index 7b95f29e31749ec180e67028424580fadda1c3af..3baff31e58cf22c30b2d770162ee3c4b10c087ea 100644 (file)
@@ -6,7 +6,7 @@ lib-y  = delay.o memmove.o memchr.o \
         checksum.o strlen.o div64.o div64-generic.o
 
 # Extracted from libgcc
-lib-y += movmem.o ashldi3.o ashrdi3.o lshrdi3.o \
+obj-y += movmem.o ashldi3.o ashrdi3.o lshrdi3.o \
         ashlsi3.o ashrsi3.o ashiftrt.o lshrsi3.o \
         udiv_qrnnd.o
 
index 8358dc144959aacc8b369830c21c130593b9a804..0f9e94537eee78d9d41fffe82e32fc0098811ed2 100644 (file)
@@ -619,7 +619,7 @@ static inline unsigned long pte_present(pte_t pte)
 }
 
 #define pte_accessible pte_accessible
-static inline unsigned long pte_accessible(pte_t a)
+static inline unsigned long pte_accessible(struct mm_struct *mm, pte_t a)
 {
        return pte_val(a) & _PAGE_VALID;
 }
@@ -847,7 +847,7 @@ static inline void __set_pte_at(struct mm_struct *mm, unsigned long addr,
         * SUN4V NOTE: _PAGE_VALID is the same value in both the SUN4U
         *             and SUN4V pte layout, so this inline test is fine.
         */
-       if (likely(mm != &init_mm) && pte_accessible(orig))
+       if (likely(mm != &init_mm) && pte_accessible(mm, orig))
                tlb_batch_add(mm, addr, ptep, orig, fullmm);
 }
 
index eda00f9be0cf100caee9ec195f838c6e31885b70..57d021507120ed2a2b04d8b7a673a11bf73f0afc 100644 (file)
@@ -31,8 +31,8 @@ ifeq ($(CONFIG_X86_32),y)
 
         KBUILD_CFLAGS += -msoft-float -mregparm=3 -freg-struct-return
 
-        # Don't autogenerate SSE instructions
-       KBUILD_CFLAGS += -mno-sse
+        # Don't autogenerate MMX or SSE instructions
+        KBUILD_CFLAGS += -mno-mmx -mno-sse
 
         # Never want PIC in a 32-bit kernel, prevent breakage with GCC built
         # with nonstandard options
@@ -60,8 +60,8 @@ else
         KBUILD_AFLAGS += -m64
         KBUILD_CFLAGS += -m64
 
-        # Don't autogenerate SSE instructions
-       KBUILD_CFLAGS += -mno-sse
+        # Don't autogenerate MMX or SSE instructions
+        KBUILD_CFLAGS += -mno-mmx -mno-sse
 
        # Use -mpreferred-stack-boundary=3 if supported.
        KBUILD_CFLAGS += $(call cc-option,-mpreferred-stack-boundary=3)
index dce69a2568963bf97efa8a3598be4645cc93834b..d9c11956fce0e9128bfa5432ee3c752f2acd4999 100644 (file)
@@ -53,18 +53,18 @@ $(obj)/cpustr.h: $(obj)/mkcpustr FORCE
 
 # How to compile the 16-bit code.  Note we always compile for -march=i386,
 # that way we can complain to the user if the CPU is insufficient.
-KBUILD_CFLAGS  := $(USERINCLUDE) -g -Os -D_SETUP -D__KERNEL__ \
+KBUILD_CFLAGS  := $(USERINCLUDE) -m32 -g -Os -D_SETUP -D__KERNEL__ \
                   -DDISABLE_BRANCH_PROFILING \
                   -Wall -Wstrict-prototypes \
                   -march=i386 -mregparm=3 \
                   -include $(srctree)/$(src)/code16gcc.h \
                   -fno-strict-aliasing -fomit-frame-pointer -fno-pic \
+                  -mno-mmx -mno-sse \
                   $(call cc-option, -ffreestanding) \
                   $(call cc-option, -fno-toplevel-reorder,\
-                       $(call cc-option, -fno-unit-at-a-time)) \
+                  $(call cc-option, -fno-unit-at-a-time)) \
                   $(call cc-option, -fno-stack-protector) \
                   $(call cc-option, -mpreferred-stack-boundary=2)
-KBUILD_CFLAGS  += $(call cc-option, -m32)
 KBUILD_AFLAGS  := $(KBUILD_CFLAGS) -D__ASSEMBLY__
 GCOV_PROFILE := n
 
index dcd90df10ab4e271dd6ee0e3ed737015326efa18..c8a6792e78423ac2efcb091f8d2553a35fb34c68 100644 (file)
@@ -13,6 +13,7 @@ KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING
 cflags-$(CONFIG_X86_32) := -march=i386
 cflags-$(CONFIG_X86_64) := -mcmodel=small
 KBUILD_CFLAGS += $(cflags-y)
+KBUILD_CFLAGS += -mno-mmx -mno-sse
 KBUILD_CFLAGS += $(call cc-option,-ffreestanding)
 KBUILD_CFLAGS += $(call cc-option,-fno-stack-protector)
 
index 3d1999458709231affdc977df99530acf3a833ac..bbc8b12fa443d47ee9a8faa59b36767e7aec866c 100644 (file)
@@ -452,9 +452,16 @@ static inline int pte_present(pte_t a)
 }
 
 #define pte_accessible pte_accessible
-static inline int pte_accessible(pte_t a)
+static inline bool pte_accessible(struct mm_struct *mm, pte_t a)
 {
-       return pte_flags(a) & _PAGE_PRESENT;
+       if (pte_flags(a) & _PAGE_PRESENT)
+               return true;
+
+       if ((pte_flags(a) & (_PAGE_PROTNONE | _PAGE_NUMA)) &&
+                       mm_tlb_flush_pending(mm))
+               return true;
+
+       return false;
 }
 
 static inline int pte_hidden(pte_t pte)
index fd00bb29425d4da50194241c6ae3835775e12e6e..c1a861829d817a2749372060df21c6d689294fff 100644 (file)
@@ -262,11 +262,20 @@ struct cpu_hw_events {
        __EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK, \
                          HWEIGHT(n), 0, PERF_X86_EVENT_PEBS_ST_HSW)
 
-#define EVENT_CONSTRAINT_END           \
-       EVENT_CONSTRAINT(0, 0, 0)
+/*
+ * We define the end marker as having a weight of -1
+ * to enable blacklisting of events using a counter bitmask
+ * of zero and thus a weight of zero.
+ * The end marker has a weight that cannot possibly be
+ * obtained from counting the bits in the bitmask.
+ */
+#define EVENT_CONSTRAINT_END { .weight = -1 }
 
+/*
+ * Check for end marker with weight == -1
+ */
 #define for_each_event_constraint(e, c)        \
-       for ((e) = (c); (e)->weight; (e)++)
+       for ((e) = (c); (e)->weight != -1; (e)++)
 
 /*
  * Extra registers for specific events.
index 5439117d5c4cccfa00d28dd64fb5aa8fd488261e..dec48bfaddb8ff79ee7f7734cebfca7f36844461 100644 (file)
@@ -143,6 +143,8 @@ static inline int kvm_apic_id(struct kvm_lapic *apic)
        return (kvm_apic_get_reg(apic, APIC_ID) >> 24) & 0xff;
 }
 
+#define KVM_X2APIC_CID_BITS 0
+
 static void recalculate_apic_map(struct kvm *kvm)
 {
        struct kvm_apic_map *new, *old = NULL;
@@ -180,7 +182,8 @@ static void recalculate_apic_map(struct kvm *kvm)
                if (apic_x2apic_mode(apic)) {
                        new->ldr_bits = 32;
                        new->cid_shift = 16;
-                       new->cid_mask = new->lid_mask = 0xffff;
+                       new->cid_mask = (1 << KVM_X2APIC_CID_BITS) - 1;
+                       new->lid_mask = 0xffff;
                } else if (kvm_apic_sw_enabled(apic) &&
                                !new->cid_mask /* flat mode */ &&
                                kvm_apic_get_reg(apic, APIC_DFR) == APIC_DFR_CLUSTER) {
@@ -841,7 +844,8 @@ static u32 apic_get_tmcct(struct kvm_lapic *apic)
        ASSERT(apic != NULL);
 
        /* if initial count is 0, current count should also be 0 */
-       if (kvm_apic_get_reg(apic, APIC_TMICT) == 0)
+       if (kvm_apic_get_reg(apic, APIC_TMICT) == 0 ||
+               apic->lapic_timer.period == 0)
                return 0;
 
        remaining = hrtimer_get_remaining(&apic->lapic_timer.timer);
@@ -1691,7 +1695,6 @@ static void apic_sync_pv_eoi_from_guest(struct kvm_vcpu *vcpu,
 void kvm_lapic_sync_from_vapic(struct kvm_vcpu *vcpu)
 {
        u32 data;
-       void *vapic;
 
        if (test_bit(KVM_APIC_PV_EOI_PENDING, &vcpu->arch.apic_attention))
                apic_sync_pv_eoi_from_guest(vcpu, vcpu->arch.apic);
@@ -1699,9 +1702,8 @@ void kvm_lapic_sync_from_vapic(struct kvm_vcpu *vcpu)
        if (!test_bit(KVM_APIC_CHECK_VAPIC, &vcpu->arch.apic_attention))
                return;
 
-       vapic = kmap_atomic(vcpu->arch.apic->vapic_page);
-       data = *(u32 *)(vapic + offset_in_page(vcpu->arch.apic->vapic_addr));
-       kunmap_atomic(vapic);
+       kvm_read_guest_cached(vcpu->kvm, &vcpu->arch.apic->vapic_cache, &data,
+                               sizeof(u32));
 
        apic_set_tpr(vcpu->arch.apic, data & 0xff);
 }
@@ -1737,7 +1739,6 @@ void kvm_lapic_sync_to_vapic(struct kvm_vcpu *vcpu)
        u32 data, tpr;
        int max_irr, max_isr;
        struct kvm_lapic *apic = vcpu->arch.apic;
-       void *vapic;
 
        apic_sync_pv_eoi_to_guest(vcpu, apic);
 
@@ -1753,18 +1754,24 @@ void kvm_lapic_sync_to_vapic(struct kvm_vcpu *vcpu)
                max_isr = 0;
        data = (tpr & 0xff) | ((max_isr & 0xf0) << 8) | (max_irr << 24);
 
-       vapic = kmap_atomic(vcpu->arch.apic->vapic_page);
-       *(u32 *)(vapic + offset_in_page(vcpu->arch.apic->vapic_addr)) = data;
-       kunmap_atomic(vapic);
+       kvm_write_guest_cached(vcpu->kvm, &vcpu->arch.apic->vapic_cache, &data,
+                               sizeof(u32));
 }
 
-void kvm_lapic_set_vapic_addr(struct kvm_vcpu *vcpu, gpa_t vapic_addr)
+int kvm_lapic_set_vapic_addr(struct kvm_vcpu *vcpu, gpa_t vapic_addr)
 {
-       vcpu->arch.apic->vapic_addr = vapic_addr;
-       if (vapic_addr)
+       if (vapic_addr) {
+               if (kvm_gfn_to_hva_cache_init(vcpu->kvm,
+                                       &vcpu->arch.apic->vapic_cache,
+                                       vapic_addr, sizeof(u32)))
+                       return -EINVAL;
                __set_bit(KVM_APIC_CHECK_VAPIC, &vcpu->arch.apic_attention);
-       else
+       } else {
                __clear_bit(KVM_APIC_CHECK_VAPIC, &vcpu->arch.apic_attention);
+       }
+
+       vcpu->arch.apic->vapic_addr = vapic_addr;
+       return 0;
 }
 
 int kvm_x2apic_msr_write(struct kvm_vcpu *vcpu, u32 msr, u64 data)
index c730ac9fe80188d15957bf9b556918036db892ab..c8b0d0d2da5ce2d67f9342fba000e60e1aec84eb 100644 (file)
@@ -34,7 +34,7 @@ struct kvm_lapic {
         */
        void *regs;
        gpa_t vapic_addr;
-       struct page *vapic_page;
+       struct gfn_to_hva_cache vapic_cache;
        unsigned long pending_events;
        unsigned int sipi_vector;
 };
@@ -76,7 +76,7 @@ void kvm_set_lapic_tscdeadline_msr(struct kvm_vcpu *vcpu, u64 data);
 void kvm_apic_write_nodecode(struct kvm_vcpu *vcpu, u32 offset);
 void kvm_apic_set_eoi_accelerated(struct kvm_vcpu *vcpu, int vector);
 
-void kvm_lapic_set_vapic_addr(struct kvm_vcpu *vcpu, gpa_t vapic_addr);
+int kvm_lapic_set_vapic_addr(struct kvm_vcpu *vcpu, gpa_t vapic_addr);
 void kvm_lapic_sync_from_vapic(struct kvm_vcpu *vcpu);
 void kvm_lapic_sync_to_vapic(struct kvm_vcpu *vcpu);
 
index 21ef1ba184ae8500a70061f566ea55fde76cbfd2..5d004da1e35da9bdad0260f5d6b0f287330b194c 100644 (file)
@@ -3214,8 +3214,7 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
                r = -EFAULT;
                if (copy_from_user(&va, argp, sizeof va))
                        goto out;
-               r = 0;
-               kvm_lapic_set_vapic_addr(vcpu, va.vapic_addr);
+               r = kvm_lapic_set_vapic_addr(vcpu, va.vapic_addr);
                break;
        }
        case KVM_X86_SETUP_MCE: {
@@ -5739,36 +5738,6 @@ static void post_kvm_run_save(struct kvm_vcpu *vcpu)
                        !kvm_event_needs_reinjection(vcpu);
 }
 
-static int vapic_enter(struct kvm_vcpu *vcpu)
-{
-       struct kvm_lapic *apic = vcpu->arch.apic;
-       struct page *page;
-
-       if (!apic || !apic->vapic_addr)
-               return 0;
-
-       page = gfn_to_page(vcpu->kvm, apic->vapic_addr >> PAGE_SHIFT);
-       if (is_error_page(page))
-               return -EFAULT;
-
-       vcpu->arch.apic->vapic_page = page;
-       return 0;
-}
-
-static void vapic_exit(struct kvm_vcpu *vcpu)
-{
-       struct kvm_lapic *apic = vcpu->arch.apic;
-       int idx;
-
-       if (!apic || !apic->vapic_addr)
-               return;
-
-       idx = srcu_read_lock(&vcpu->kvm->srcu);
-       kvm_release_page_dirty(apic->vapic_page);
-       mark_page_dirty(vcpu->kvm, apic->vapic_addr >> PAGE_SHIFT);
-       srcu_read_unlock(&vcpu->kvm->srcu, idx);
-}
-
 static void update_cr8_intercept(struct kvm_vcpu *vcpu)
 {
        int max_irr, tpr;
@@ -6069,11 +6038,6 @@ static int __vcpu_run(struct kvm_vcpu *vcpu)
        struct kvm *kvm = vcpu->kvm;
 
        vcpu->srcu_idx = srcu_read_lock(&kvm->srcu);
-       r = vapic_enter(vcpu);
-       if (r) {
-               srcu_read_unlock(&kvm->srcu, vcpu->srcu_idx);
-               return r;
-       }
 
        r = 1;
        while (r > 0) {
@@ -6132,8 +6096,6 @@ static int __vcpu_run(struct kvm_vcpu *vcpu)
 
        srcu_read_unlock(&kvm->srcu, vcpu->srcu_idx);
 
-       vapic_exit(vcpu);
-
        return r;
 }
 
index dd74e46828c0fc243740b61a18c2dea654fafb5e..0596e8e0cc1992b1fc32a00277a4f879cd07a8f3 100644 (file)
@@ -83,6 +83,12 @@ static noinline int gup_pte_range(pmd_t pmd, unsigned long addr,
                pte_t pte = gup_get_pte(ptep);
                struct page *page;
 
+               /* Similar to the PMD case, NUMA hinting must take slow path */
+               if (pte_numa(pte)) {
+                       pte_unmap(ptep);
+                       return 0;
+               }
+
                if ((pte_flags(pte) & (mask | _PAGE_SPECIAL)) != mask) {
                        pte_unmap(ptep);
                        return 0;
@@ -167,6 +173,13 @@ static int gup_pmd_range(pud_t pud, unsigned long addr, unsigned long end,
                if (pmd_none(pmd) || pmd_trans_splitting(pmd))
                        return 0;
                if (unlikely(pmd_large(pmd))) {
+                       /*
+                        * NUMA hinting faults need to be handled in the GUP
+                        * slowpath for accounting purposes and so that they
+                        * can be serialised against THP migration.
+                        */
+                       if (pmd_numa(pmd))
+                               return 0;
                        if (!gup_huge_pmd(pmd, addr, next, write, pages, nr))
                                return 0;
                } else {
index 92c02344a060f2dacc7997185d6fd6bc04ed225e..cceb813044efc5dfdcbaf9fddbd076b23b2d1dc1 100644 (file)
@@ -690,13 +690,6 @@ void __init efi_init(void)
 
        set_bit(EFI_MEMMAP, &x86_efi_facility);
 
-#ifdef CONFIG_X86_32
-       if (efi_is_native()) {
-               x86_platform.get_wallclock = efi_get_time;
-               x86_platform.set_wallclock = efi_set_rtc_mmss;
-       }
-#endif
-
 #if EFI_DEBUG
        print_efi_memmap();
 #endif
index 0f92173a12b6ee1a1d5512c867585cd1ee07fc12..efe4d7220397ea81e13c88524f9234d0673b19cd 100644 (file)
@@ -1070,12 +1070,13 @@ const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask,
        unsigned long status;
 
        bcp = &per_cpu(bau_control, cpu);
-       stat = bcp->statp;
-       stat->s_enters++;
 
        if (bcp->nobau)
                return cpumask;
 
+       stat = bcp->statp;
+       stat->s_enters++;
+
        if (bcp->busy) {
                descriptor_status =
                        read_lmmr(UVH_LB_BAU_SB_ACTIVATION_STATUS_0);
index 88692871823f9910aeb071ad44a86d8c5c251411..9cac82588cbc49d86bc9457586941c69763d7749 100644 (file)
@@ -73,9 +73,10 @@ KBUILD_CFLAGS        := $(LINUXINCLUDE) -m32 -g -Os -D_SETUP -D__KERNEL__ -D_WAKEUP \
                   -march=i386 -mregparm=3 \
                   -include $(srctree)/$(src)/../../boot/code16gcc.h \
                   -fno-strict-aliasing -fomit-frame-pointer -fno-pic \
+                  -mno-mmx -mno-sse \
                   $(call cc-option, -ffreestanding) \
                   $(call cc-option, -fno-toplevel-reorder,\
-                       $(call cc-option, -fno-unit-at-a-time)) \
+                  $(call cc-option, -fno-unit-at-a-time)) \
                   $(call cc-option, -fno-stack-protector) \
                   $(call cc-option, -mpreferred-stack-boundary=2)
 KBUILD_AFLAGS  := $(KBUILD_CFLAGS) -D__ASSEMBLY__
index 98745dd77e8ccfb75080d47fb099448d81d1eaa8..81f977510775460fa2bf8b0bd500c69027c02274 100644 (file)
@@ -40,7 +40,7 @@ static int regmap_mmio_gather_write(void *context,
 
        BUG_ON(reg_size != 4);
 
-       if (ctx->clk) {
+       if (!IS_ERR(ctx->clk)) {
                ret = clk_enable(ctx->clk);
                if (ret < 0)
                        return ret;
@@ -73,7 +73,7 @@ static int regmap_mmio_gather_write(void *context,
                offset += ctx->val_bytes;
        }
 
-       if (ctx->clk)
+       if (!IS_ERR(ctx->clk))
                clk_disable(ctx->clk);
 
        return 0;
@@ -96,7 +96,7 @@ static int regmap_mmio_read(void *context,
 
        BUG_ON(reg_size != 4);
 
-       if (ctx->clk) {
+       if (!IS_ERR(ctx->clk)) {
                ret = clk_enable(ctx->clk);
                if (ret < 0)
                        return ret;
@@ -129,7 +129,7 @@ static int regmap_mmio_read(void *context,
                offset += ctx->val_bytes;
        }
 
-       if (ctx->clk)
+       if (!IS_ERR(ctx->clk))
                clk_disable(ctx->clk);
 
        return 0;
@@ -139,7 +139,7 @@ static void regmap_mmio_free_context(void *context)
 {
        struct regmap_mmio_context *ctx = context;
 
-       if (ctx->clk) {
+       if (!IS_ERR(ctx->clk)) {
                clk_unprepare(ctx->clk);
                clk_put(ctx->clk);
        }
@@ -209,6 +209,7 @@ static struct regmap_mmio_context *regmap_mmio_gen_context(struct device *dev,
 
        ctx->regs = regs;
        ctx->val_bytes = config->val_bits / 8;
+       ctx->clk = ERR_PTR(-ENODEV);
 
        if (clk_id == NULL)
                return ctx;
index 9c021d9cace0fcc74080ccec7b5a2b3933c65f2a..c2e00210094995fde1cc69998d03f98e01c75fb1 100644 (file)
@@ -1549,7 +1549,7 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val,
                                                val + (i * val_bytes),
                                                val_bytes);
                        if (ret != 0)
-                               return ret;
+                               goto out;
                }
        } else {
                ret = _regmap_raw_write(map, reg, wval, val_bytes * val_count);
@@ -1743,7 +1743,7 @@ static int _regmap_read(struct regmap *map, unsigned int reg,
 /**
  * regmap_read(): Read a value from a single register
  *
- * @map: Register map to write to
+ * @map: Register map to read from
  * @reg: Register to be read from
  * @val: Pointer to store read value
  *
@@ -1770,7 +1770,7 @@ EXPORT_SYMBOL_GPL(regmap_read);
 /**
  * regmap_raw_read(): Read raw data from the device
  *
- * @map: Register map to write to
+ * @map: Register map to read from
  * @reg: First register to be read from
  * @val: Pointer to store read value
  * @val_len: Size of data to read
@@ -1882,7 +1882,7 @@ EXPORT_SYMBOL_GPL(regmap_fields_read);
 /**
  * regmap_bulk_read(): Read multiple registers from the device
  *
- * @map: Register map to write to
+ * @map: Register map to read from
  * @reg: First register to be read from
  * @val: Pointer to store read value, in native register size for device
  * @val_count: Number of registers to read
index ea192ec029c45bf7354d8184b44e1eb460cdbf77..f370fc13aea5d7d8c2a2c78fb40722da0cc27407 100644 (file)
@@ -495,23 +495,23 @@ static int null_add_dev(void)
 
        spin_lock_init(&nullb->lock);
 
+       if (queue_mode == NULL_Q_MQ && use_per_node_hctx)
+               submit_queues = nr_online_nodes;
+
        if (setup_queues(nullb))
                goto err;
 
        if (queue_mode == NULL_Q_MQ) {
                null_mq_reg.numa_node = home_node;
                null_mq_reg.queue_depth = hw_queue_depth;
+               null_mq_reg.nr_hw_queues = submit_queues;
 
                if (use_per_node_hctx) {
                        null_mq_reg.ops->alloc_hctx = null_alloc_hctx;
                        null_mq_reg.ops->free_hctx = null_free_hctx;
-
-                       null_mq_reg.nr_hw_queues = nr_online_nodes;
                } else {
                        null_mq_reg.ops->alloc_hctx = blk_mq_alloc_single_hw_queue;
                        null_mq_reg.ops->free_hctx = blk_mq_free_single_hw_queue;
-
-                       null_mq_reg.nr_hw_queues = submit_queues;
                }
 
                nullb->q = blk_mq_init_queue(&null_mq_reg, nullb);
index 7be41e676a6470ab02b0bfd52867f54561a7960d..00a3abe103a5ac472dfb352a1bb0cec42cd29ddb 100644 (file)
@@ -60,7 +60,7 @@ static int s2mps11_clk_prepare(struct clk_hw *hw)
        struct s2mps11_clk *s2mps11 = to_s2mps11_clk(hw);
        int ret;
 
-       ret = regmap_update_bits(s2mps11->iodev->regmap,
+       ret = regmap_update_bits(s2mps11->iodev->regmap_pmic,
                                S2MPS11_REG_RTC_CTRL,
                                 s2mps11->mask, s2mps11->mask);
        if (!ret)
@@ -74,7 +74,7 @@ static void s2mps11_clk_unprepare(struct clk_hw *hw)
        struct s2mps11_clk *s2mps11 = to_s2mps11_clk(hw);
        int ret;
 
-       ret = regmap_update_bits(s2mps11->iodev->regmap, S2MPS11_REG_RTC_CTRL,
+       ret = regmap_update_bits(s2mps11->iodev->regmap_pmic, S2MPS11_REG_RTC_CTRL,
                           s2mps11->mask, ~s2mps11->mask);
 
        if (!ret)
@@ -174,7 +174,7 @@ static int s2mps11_clk_probe(struct platform_device *pdev)
                s2mps11_clk->hw.init = &s2mps11_clks_init[i];
                s2mps11_clk->mask = 1 << i;
 
-               ret = regmap_read(s2mps11_clk->iodev->regmap,
+               ret = regmap_read(s2mps11_clk->iodev->regmap_pmic,
                                  S2MPS11_REG_RTC_CTRL, &val);
                if (ret < 0)
                        goto err_reg;
index 5c07a56962dbcffc038b81eb09305e61ee1d83e6..634c4d6dd45a489384d4c6b293e56f0fcc2ba331 100644 (file)
@@ -75,6 +75,7 @@ config CLKSRC_DBX500_PRCMU_SCHED_CLOCK
 config CLKSRC_EFM32
        bool "Clocksource for Energy Micro's EFM32 SoCs" if !ARCH_EFM32
        depends on OF && ARM && (ARCH_EFM32 || COMPILE_TEST)
+       select CLKSRC_MMIO
        default ARCH_EFM32
        help
          Support to use the timers of EFM32 SoCs as clock source and clock
index 35639cf4e5a208af89c9b692eae32227bcefc5d3..b9ddd9e3a2f599e2cc7424c1eac18d4280b2f850 100644 (file)
@@ -35,6 +35,5 @@ void __init clocksource_of_init(void)
 
                init_func = match->data;
                init_func(np);
-               of_node_put(np);
        }
 }
index 45ba8aecc7298428016dd6d5601482362cce0c4e..2a2ea2717f3ac94dfba2fdd6a986c4630556e7da 100644 (file)
@@ -108,12 +108,11 @@ static void __init add_clocksource(struct device_node *source_timer)
 
 static u64 read_sched_clock(void)
 {
-       return __raw_readl(sched_io_base);
+       return ~__raw_readl(sched_io_base);
 }
 
 static const struct of_device_id sptimer_ids[] __initconst = {
        { .compatible = "picochip,pc3x2-rtc" },
-       { .compatible = "snps,dw-apb-timer-sp" },
        { /* Sentinel */ },
 };
 
@@ -151,4 +150,6 @@ static void __init dw_apb_timer_init(struct device_node *timer)
        num_called++;
 }
 CLOCKSOURCE_OF_DECLARE(pc3x2_timer, "picochip,pc3x2-timer", dw_apb_timer_init);
-CLOCKSOURCE_OF_DECLARE(apb_timer, "snps,dw-apb-timer-osc", dw_apb_timer_init);
+CLOCKSOURCE_OF_DECLARE(apb_timer_osc, "snps,dw-apb-timer-osc", dw_apb_timer_init);
+CLOCKSOURCE_OF_DECLARE(apb_timer_sp, "snps,dw-apb-timer-sp", dw_apb_timer_init);
+CLOCKSOURCE_OF_DECLARE(apb_timer, "snps,dw-apb-timer", dw_apb_timer_init);
index 2fb4695a28d83e2e0f26c1e787b0c575612c650c..a4f6119aafd814efe2839f416bbe8fe99bc41554 100644 (file)
@@ -179,6 +179,9 @@ static void __init sun4i_timer_init(struct device_node *node)
        writel(TIMER_CTL_CLK_SRC(TIMER_CTL_CLK_SRC_OSC24M),
               timer_base + TIMER_CTL_REG(0));
 
+       /* Make sure timer is stopped before playing with interrupts */
+       sun4i_clkevt_time_stop(0);
+
        ret = setup_irq(irq, &sun4i_timer_irq);
        if (ret)
                pr_warn("failed to setup irq %d\n", irq);
index d8e47e5027858faf9f99c0b3ad99883bd7bc9cc2..4e7f6802e840ba9379eb42d733801526d173e89e 100644 (file)
@@ -255,11 +255,6 @@ static void __init armada_370_xp_timer_common_init(struct device_node *np)
 
        ticks_per_jiffy = (timer_clk + HZ / 2) / HZ;
 
-       /*
-        * Set scale and timer for sched_clock.
-        */
-       sched_clock_register(armada_370_xp_read_sched_clock, 32, timer_clk);
-
        /*
         * Setup free-running clocksource timer (interrupts
         * disabled).
@@ -270,6 +265,11 @@ static void __init armada_370_xp_timer_common_init(struct device_node *np)
        timer_ctrl_clrset(0, TIMER0_EN | TIMER0_RELOAD_EN |
                             TIMER0_DIV(TIMER_DIVIDER_SHIFT));
 
+       /*
+        * Set scale and timer for sched_clock.
+        */
+       sched_clock_register(armada_370_xp_read_sched_clock, 32, timer_clk);
+
        clocksource_mmio_init(timer_base + TIMER0_VAL_OFF,
                              "armada_370_xp_clocksource",
                              timer_clk, 300, 32, clocksource_mmio_readl_down);
index 856ad80418ae5b92610e23e98922f0ff6505d34e..7c03dd84f66a35cabbde683eece8e23f73585743 100644 (file)
@@ -58,7 +58,7 @@ static int at32_set_target(struct cpufreq_policy *policy, unsigned int index)
        return 0;
 }
 
-static int __init at32_cpufreq_driver_init(struct cpufreq_policy *policy)
+static int at32_cpufreq_driver_init(struct cpufreq_policy *policy)
 {
        unsigned int frequency, rate, min_freq;
        int retval, steps, i;
index 16a2aa28f85672689f66c37039a8e72230e71b02..ec4ee5c1fe9dc2115e029d0c472bd32f48cb281c 100644 (file)
@@ -1169,7 +1169,7 @@ static void pl08x_desc_free(struct virt_dma_desc *vd)
        struct pl08x_txd *txd = to_pl08x_txd(&vd->tx);
        struct pl08x_dma_chan *plchan = to_pl08x_chan(vd->tx.chan);
 
-       dma_descriptor_unmap(txd);
+       dma_descriptor_unmap(&vd->tx);
        if (!txd->done)
                pl08x_release_mux(plchan);
 
index dcb1e05149a7664c6e65a214d783080d540aaafd..8869500ab92b84a4b93f4111f8936e6722d4911c 100644 (file)
@@ -1017,6 +1017,7 @@ static int mmp_pdma_probe(struct platform_device *op)
                }
        }
 
+       platform_set_drvdata(op, pdev);
        dev_info(pdev->device.dev, "initialized %d channels\n", dma_channels);
        return 0;
 }
index 4cb12797863678be86af66017ec2cffb54f5dd16..4eddedb6eb7dd3deb68550c1b8065e8b9d882278 100644 (file)
@@ -628,42 +628,13 @@ retry:
        s3cchan->state = S3C24XX_DMA_CHAN_IDLE;
 }
 
-static void s3c24xx_dma_unmap_buffers(struct s3c24xx_txd *txd)
-{
-       struct device *dev = txd->vd.tx.chan->device->dev;
-       struct s3c24xx_sg *dsg;
-
-       if (!(txd->vd.tx.flags & DMA_COMPL_SKIP_SRC_UNMAP)) {
-               if (txd->vd.tx.flags & DMA_COMPL_SRC_UNMAP_SINGLE)
-                       list_for_each_entry(dsg, &txd->dsg_list, node)
-                               dma_unmap_single(dev, dsg->src_addr, dsg->len,
-                                               DMA_TO_DEVICE);
-               else {
-                       list_for_each_entry(dsg, &txd->dsg_list, node)
-                               dma_unmap_page(dev, dsg->src_addr, dsg->len,
-                                               DMA_TO_DEVICE);
-               }
-       }
-
-       if (!(txd->vd.tx.flags & DMA_COMPL_SKIP_DEST_UNMAP)) {
-               if (txd->vd.tx.flags & DMA_COMPL_DEST_UNMAP_SINGLE)
-                       list_for_each_entry(dsg, &txd->dsg_list, node)
-                               dma_unmap_single(dev, dsg->dst_addr, dsg->len,
-                                               DMA_FROM_DEVICE);
-               else
-                       list_for_each_entry(dsg, &txd->dsg_list, node)
-                               dma_unmap_page(dev, dsg->dst_addr, dsg->len,
-                                               DMA_FROM_DEVICE);
-       }
-}
-
 static void s3c24xx_dma_desc_free(struct virt_dma_desc *vd)
 {
        struct s3c24xx_txd *txd = to_s3c24xx_txd(&vd->tx);
        struct s3c24xx_dma_chan *s3cchan = to_s3c24xx_dma_chan(vd->tx.chan);
 
        if (!s3cchan->slave)
-               s3c24xx_dma_unmap_buffers(txd);
+               dma_descriptor_unmap(&vd->tx);
 
        s3c24xx_dma_free_txd(txd);
 }
@@ -795,7 +766,7 @@ static enum dma_status s3c24xx_dma_tx_status(struct dma_chan *chan,
 
        spin_lock_irqsave(&s3cchan->vc.lock, flags);
        ret = dma_cookie_status(chan, cookie, txstate);
-       if (ret == DMA_SUCCESS) {
+       if (ret == DMA_COMPLETE) {
                spin_unlock_irqrestore(&s3cchan->vc.lock, flags);
                return ret;
        }
index ebad84591a6e22bd1f28866c3f0b1946eba3dff0..3083d901a414f000a54e0337e02973a4586399bf 100644 (file)
@@ -60,6 +60,7 @@
 #define HPB_DMAE_DSTPR_DMSTP   BIT(0)
 
 /* DMA status register (DSTSR) bits */
+#define HPB_DMAE_DSTSR_DQSTS   BIT(2)
 #define HPB_DMAE_DSTSR_DMSTS   BIT(0)
 
 /* DMA common registers */
@@ -286,6 +287,9 @@ static void hpb_dmae_halt(struct shdma_chan *schan)
 
        ch_reg_write(chan, HPB_DMAE_DCMDR_DQEND, HPB_DMAE_DCMDR);
        ch_reg_write(chan, HPB_DMAE_DSTPR_DMSTP, HPB_DMAE_DSTPR);
+
+       chan->plane_idx = 0;
+       chan->first_desc = true;
 }
 
 static const struct hpb_dmae_slave_config *
@@ -385,7 +389,10 @@ static bool hpb_dmae_channel_busy(struct shdma_chan *schan)
        struct hpb_dmae_chan *chan = to_chan(schan);
        u32 dstsr = ch_reg_read(chan, HPB_DMAE_DSTSR);
 
-       return (dstsr & HPB_DMAE_DSTSR_DMSTS) == HPB_DMAE_DSTSR_DMSTS;
+       if (chan->xfer_mode == XFER_DOUBLE)
+               return dstsr & HPB_DMAE_DSTSR_DQSTS;
+       else
+               return dstsr & HPB_DMAE_DSTSR_DMSTS;
 }
 
 static int
@@ -510,6 +517,8 @@ static int hpb_dmae_chan_probe(struct hpb_dmae_device *hpbdev, int id)
        }
 
        schan = &new_hpb_chan->shdma_chan;
+       schan->max_xfer_len = HPB_DMA_TCR_MAX;
+
        shdma_chan_probe(sdev, schan, id);
 
        if (pdev->id >= 0)
index 8472405c558612e949e5be4caa6a6ac7c889c335..d7f1b57bd3be07a36036e459e4682455eeb220c3 100644 (file)
@@ -945,7 +945,7 @@ static int get_memory_error_data(struct mem_ctl_info *mci,
        u32                     tad_offset;
        u32                     rir_way;
        u32                     mb, kb;
-       u64                     ch_addr, offset, limit, prv = 0;
+       u64                     ch_addr, offset, limit = 0, prv = 0;
 
 
        /*
index 8847adf392b7ecf823f9f603314c76001367203f..84be70157ad6b6e9809bd007c422e223c359d429 100644 (file)
@@ -327,7 +327,7 @@ static int gpio_to_irq_unbanked(struct gpio_chip *chip, unsigned offset)
         * NOTE:  we assume for now that only irqs in the first gpio_chip
         * can provide direct-mapped IRQs to AINTC (up to 32 GPIOs).
         */
-       if (offset < d->irq_base)
+       if (offset < d->gpio_unbanked)
                return d->gpio_irq + offset;
        else
                return -ENODEV;
@@ -419,6 +419,8 @@ static int davinci_gpio_irq_setup(struct platform_device *pdev)
 
                /* pass "bank 0" GPIO IRQs to AINTC */
                chips[0].chip.to_irq = gpio_to_irq_unbanked;
+               chips[0].gpio_irq = bank_irq;
+               chips[0].gpio_unbanked = pdata->gpio_unbanked;
                binten = BIT(0);
 
                /* AINTC handles mask/unmask; GPIO handles triggering */
index 7b37300973dbc15d1a424448d932867b4d10d06d..2baf0ddf7e0230f2b334fc9e25dfca3bbe0205c9 100644 (file)
@@ -252,7 +252,7 @@ static void msm_gpio_irq_mask(struct irq_data *d)
 
        spin_lock_irqsave(&tlmm_lock, irq_flags);
        writel(TARGET_PROC_NONE, GPIO_INTR_CFG_SU(gpio));
-       clear_gpio_bits(INTR_RAW_STATUS_EN | INTR_ENABLE, GPIO_INTR_CFG(gpio));
+       clear_gpio_bits(BIT(INTR_RAW_STATUS_EN) | BIT(INTR_ENABLE), GPIO_INTR_CFG(gpio));
        __clear_bit(gpio, msm_gpio.enabled_irqs);
        spin_unlock_irqrestore(&tlmm_lock, irq_flags);
 }
@@ -264,7 +264,7 @@ static void msm_gpio_irq_unmask(struct irq_data *d)
 
        spin_lock_irqsave(&tlmm_lock, irq_flags);
        __set_bit(gpio, msm_gpio.enabled_irqs);
-       set_gpio_bits(INTR_RAW_STATUS_EN | INTR_ENABLE, GPIO_INTR_CFG(gpio));
+       set_gpio_bits(BIT(INTR_RAW_STATUS_EN) | BIT(INTR_ENABLE), GPIO_INTR_CFG(gpio));
        writel(TARGET_PROC_SCORPION, GPIO_INTR_CFG_SU(gpio));
        spin_unlock_irqrestore(&tlmm_lock, irq_flags);
 }
index fe088a30567ac63325fd02be82b8e682aa2323eb..8b7e719a68c3662f454c76b3e82b9569abeb22f8 100644 (file)
@@ -169,7 +169,8 @@ static irqreturn_t gpio_rcar_irq_handler(int irq, void *dev_id)
        u32 pending;
        unsigned int offset, irqs_handled = 0;
 
-       while ((pending = gpio_rcar_read(p, INTDT))) {
+       while ((pending = gpio_rcar_read(p, INTDT) &
+                         gpio_rcar_read(p, INTMSK))) {
                offset = __ffs(pending);
                gpio_rcar_write(p, INTCLR, BIT(offset));
                generic_handle_irq(irq_find_mapping(p->irq_domain, offset));
index b97d6a6577b961d379a977e14a3c5c693cce5049..f9996899c1f29cd26e7267cbeb349378c6e26bb4 100644 (file)
@@ -300,7 +300,7 @@ static int twl_direction_in(struct gpio_chip *chip, unsigned offset)
        if (offset < TWL4030_GPIO_MAX)
                ret = twl4030_set_gpio_direction(offset, 1);
        else
-               ret = -EINVAL;
+               ret = -EINVAL;  /* LED outputs can't be set as input */
 
        if (!ret)
                priv->direction &= ~BIT(offset);
@@ -354,11 +354,20 @@ static void twl_set(struct gpio_chip *chip, unsigned offset, int value)
 static int twl_direction_out(struct gpio_chip *chip, unsigned offset, int value)
 {
        struct gpio_twl4030_priv *priv = to_gpio_twl4030(chip);
-       int ret = -EINVAL;
+       int ret = 0;
 
        mutex_lock(&priv->mutex);
-       if (offset < TWL4030_GPIO_MAX)
+       if (offset < TWL4030_GPIO_MAX) {
                ret = twl4030_set_gpio_direction(offset, 0);
+               if (ret) {
+                       mutex_unlock(&priv->mutex);
+                       return ret;
+               }
+       }
+
+       /*
+        *  LED gpios i.e. offset >= TWL4030_GPIO_MAX are always output
+        */
 
        priv->direction |= BIT(offset);
        mutex_unlock(&priv->mutex);
index eef09ec9a5ff03691f259031d6b0dc5337e4fb02..a72cae03b99b781d7becf0987c91317c3777a65c 100644 (file)
@@ -103,6 +103,7 @@ void armada_drm_queue_unref_work(struct drm_device *,
 extern const struct drm_mode_config_funcs armada_drm_mode_config_funcs;
 
 int armada_fbdev_init(struct drm_device *);
+void armada_fbdev_lastclose(struct drm_device *);
 void armada_fbdev_fini(struct drm_device *);
 
 int armada_overlay_plane_create(struct drm_device *, unsigned long);
index 4f2b28354915c68fcbc730af9ef8b50142ef26bb..62d0ff3efddf9bb5a08e1b209b5a40c6b8148e47 100644 (file)
@@ -321,6 +321,11 @@ static struct drm_ioctl_desc armada_ioctls[] = {
                DRM_UNLOCKED),
 };
 
+static void armada_drm_lastclose(struct drm_device *dev)
+{
+       armada_fbdev_lastclose(dev);
+}
+
 static const struct file_operations armada_drm_fops = {
        .owner                  = THIS_MODULE,
        .llseek                 = no_llseek,
@@ -337,7 +342,7 @@ static struct drm_driver armada_drm_driver = {
        .open                   = NULL,
        .preclose               = NULL,
        .postclose              = NULL,
-       .lastclose              = NULL,
+       .lastclose              = armada_drm_lastclose,
        .unload                 = armada_drm_unload,
        .get_vblank_counter     = drm_vblank_count,
        .enable_vblank          = armada_drm_enable_vblank,
index dd5ea77dac960c916fd5d8169c625a572a897e05..948cb14c561ec501e10bae0f89adb043dc0b2808 100644 (file)
@@ -105,9 +105,9 @@ static int armada_fb_create(struct drm_fb_helper *fbh,
        drm_fb_helper_fill_fix(info, dfb->fb.pitches[0], dfb->fb.depth);
        drm_fb_helper_fill_var(info, fbh, sizes->fb_width, sizes->fb_height);
 
-       DRM_DEBUG_KMS("allocated %dx%d %dbpp fb: 0x%08x\n",
-               dfb->fb.width, dfb->fb.height,
-               dfb->fb.bits_per_pixel, obj->phys_addr);
+       DRM_DEBUG_KMS("allocated %dx%d %dbpp fb: 0x%08llx\n",
+               dfb->fb.width, dfb->fb.height, dfb->fb.bits_per_pixel,
+               (unsigned long long)obj->phys_addr);
 
        return 0;
 
@@ -177,6 +177,16 @@ int armada_fbdev_init(struct drm_device *dev)
        return ret;
 }
 
+void armada_fbdev_lastclose(struct drm_device *dev)
+{
+       struct armada_private *priv = dev->dev_private;
+
+       drm_modeset_lock_all(dev);
+       if (priv->fbdev)
+               drm_fb_helper_restore_fbdev_mode(priv->fbdev);
+       drm_modeset_unlock_all(dev);
+}
+
 void armada_fbdev_fini(struct drm_device *dev)
 {
        struct armada_private *priv = dev->dev_private;
@@ -192,11 +202,11 @@ void armada_fbdev_fini(struct drm_device *dev)
                        framebuffer_release(info);
                }
 
+               drm_fb_helper_fini(fbh);
+
                if (fbh->fb)
                        fbh->fb->funcs->destroy(fbh->fb);
 
-               drm_fb_helper_fini(fbh);
-
                priv->fbdev = NULL;
        }
 }
index 9f2356bae7fdafb5318b172d47535b6b32408e07..887816f43476937fcfbceed5207025b63eccb132 100644 (file)
@@ -172,8 +172,9 @@ armada_gem_linear_back(struct drm_device *dev, struct armada_gem_object *obj)
                obj->dev_addr = obj->linear->start;
        }
 
-       DRM_DEBUG_DRIVER("obj %p phys %#x dev %#x\n",
-                        obj, obj->phys_addr, obj->dev_addr);
+       DRM_DEBUG_DRIVER("obj %p phys %#llx dev %#llx\n", obj,
+                        (unsigned long long)obj->phys_addr,
+                        (unsigned long long)obj->dev_addr);
 
        return 0;
 }
@@ -557,7 +558,6 @@ armada_gem_prime_import(struct drm_device *dev, struct dma_buf *buf)
                         * refcount on the gem object itself.
                         */
                        drm_gem_object_reference(obj);
-                       dma_buf_put(buf);
                        return obj;
                }
        }
@@ -573,6 +573,7 @@ armada_gem_prime_import(struct drm_device *dev, struct dma_buf *buf)
        }
 
        dobj->obj.import_attach = attach;
+       get_dma_buf(buf);
 
        /*
         * Don't call dma_buf_map_attachment() here - it maps the
index 0a1e4a5f4234dce320788330e97e8888016338ba..8835dcddfac3ab7c3ee1a4ba72360443e730aa74 100644 (file)
@@ -68,6 +68,8 @@
 #define EDID_QUIRK_DETAILED_SYNC_PP            (1 << 6)
 /* Force reduced-blanking timings for detailed modes */
 #define EDID_QUIRK_FORCE_REDUCED_BLANKING      (1 << 7)
+/* Force 8bpc */
+#define EDID_QUIRK_FORCE_8BPC                  (1 << 8)
 
 struct detailed_mode_closure {
        struct drm_connector *connector;
@@ -128,6 +130,9 @@ static struct edid_quirk {
 
        /* Medion MD 30217 PG */
        { "MED", 0x7b8, EDID_QUIRK_PREFER_LARGE_75 },
+
+       /* Panel in Samsung NP700G7A-S01PL notebook reports 6bpc */
+       { "SEC", 0xd033, EDID_QUIRK_FORCE_8BPC },
 };
 
 /*
@@ -3435,6 +3440,9 @@ int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid)
 
        drm_add_display_info(edid, &connector->display_info);
 
+       if (quirks & EDID_QUIRK_FORCE_8BPC)
+               connector->display_info.bpc = 8;
+
        return num_modes;
 }
 EXPORT_SYMBOL(drm_add_edid_modes);
index f53d5246979c386ed632b21c08decb3ab1296f9e..66dd3a001cf1b5ee43ec75f190b03146e7bbe46d 100644 (file)
@@ -566,11 +566,11 @@ err_unload:
        if (dev->driver->unload)
                dev->driver->unload(dev);
 err_primary_node:
-       drm_put_minor(dev->primary);
+       drm_unplug_minor(dev->primary);
 err_render_node:
-       drm_put_minor(dev->render);
+       drm_unplug_minor(dev->render);
 err_control_node:
-       drm_put_minor(dev->control);
+       drm_unplug_minor(dev->control);
 err_agp:
        if (dev->driver->bus->agp_destroy)
                dev->driver->bus->agp_destroy(dev);
index 0cab2d045135b66d0462c88d390e43eff3df7b20..5c648425c1e053616801b3e1e545791a5fe111c0 100644 (file)
@@ -83,6 +83,14 @@ void i915_update_dri1_breadcrumb(struct drm_device *dev)
        drm_i915_private_t *dev_priv = dev->dev_private;
        struct drm_i915_master_private *master_priv;
 
+       /*
+        * The dri breadcrumb update races against the drm master disappearing.
+        * Instead of trying to fix this (this is by far not the only ums issue)
+        * just don't do the update in kms mode.
+        */
+       if (drm_core_check_feature(dev, DRIVER_MODESET))
+               return;
+
        if (dev->primary->master) {
                master_priv = dev->primary->master->driver_priv;
                if (master_priv->sarea_priv)
@@ -1490,16 +1498,9 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
        spin_lock_init(&dev_priv->uncore.lock);
        spin_lock_init(&dev_priv->mm.object_stat_lock);
        mutex_init(&dev_priv->dpio_lock);
-       mutex_init(&dev_priv->rps.hw_lock);
        mutex_init(&dev_priv->modeset_restore_lock);
 
-       mutex_init(&dev_priv->pc8.lock);
-       dev_priv->pc8.requirements_met = false;
-       dev_priv->pc8.gpu_idle = false;
-       dev_priv->pc8.irqs_disabled = false;
-       dev_priv->pc8.enabled = false;
-       dev_priv->pc8.disable_count = 2; /* requirements_met + gpu_idle */
-       INIT_DELAYED_WORK(&dev_priv->pc8.enable_work, hsw_enable_pc8_work);
+       intel_pm_setup(dev);
 
        intel_display_crc_init(dev);
 
@@ -1603,7 +1604,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
        }
 
        intel_irq_init(dev);
-       intel_pm_init(dev);
        intel_uncore_sanitize(dev);
 
        /* Try to make sure MCHBAR is enabled before poking at it */
@@ -1848,8 +1848,10 @@ void i915_driver_lastclose(struct drm_device * dev)
 
 void i915_driver_preclose(struct drm_device * dev, struct drm_file *file_priv)
 {
+       mutex_lock(&dev->struct_mutex);
        i915_gem_context_close(dev, file_priv);
        i915_gem_release(dev, file_priv);
+       mutex_unlock(&dev->struct_mutex);
 }
 
 void i915_driver_postclose(struct drm_device *dev, struct drm_file *file)
index 2e367a1c6a644b70e7f5375f9e88a22dd0531e08..5b7b7e06cb3a09caec1cd7d5ab90401389df7a40 100644 (file)
@@ -651,6 +651,7 @@ static int __i915_drm_thaw(struct drm_device *dev, bool restore_gtt_mappings)
                intel_modeset_init_hw(dev);
 
                drm_modeset_lock_all(dev);
+               drm_mode_config_reset(dev);
                intel_modeset_setup_hw_state(dev, true);
                drm_modeset_unlock_all(dev);
 
index ccdbecca070d2340919d5499f80824ddb84db4ac..90fcccba17b00da4a91ea2556b53a81e877356f0 100644 (file)
@@ -1755,8 +1755,13 @@ struct drm_i915_file_private {
 #define IS_MOBILE(dev)         (INTEL_INFO(dev)->is_mobile)
 #define IS_HSW_EARLY_SDV(dev)  (IS_HASWELL(dev) && \
                                 ((dev)->pdev->device & 0xFF00) == 0x0C00)
-#define IS_ULT(dev)            (IS_HASWELL(dev) && \
+#define IS_BDW_ULT(dev)                (IS_BROADWELL(dev) && \
+                                (((dev)->pdev->device & 0xf) == 0x2  || \
+                                ((dev)->pdev->device & 0xf) == 0x6 || \
+                                ((dev)->pdev->device & 0xf) == 0xe))
+#define IS_HSW_ULT(dev)                (IS_HASWELL(dev) && \
                                 ((dev)->pdev->device & 0xFF00) == 0x0A00)
+#define IS_ULT(dev)            (IS_HSW_ULT(dev) || IS_BDW_ULT(dev))
 #define IS_HSW_GT3(dev)                (IS_HASWELL(dev) && \
                                 ((dev)->pdev->device & 0x00F0) == 0x0020)
 #define IS_PRELIMINARY_HW(intel_info) ((intel_info)->is_preliminary)
@@ -1901,9 +1906,7 @@ void i915_queue_hangcheck(struct drm_device *dev);
 void i915_handle_error(struct drm_device *dev, bool wedged);
 
 extern void intel_irq_init(struct drm_device *dev);
-extern void intel_pm_init(struct drm_device *dev);
 extern void intel_hpd_init(struct drm_device *dev);
-extern void intel_pm_init(struct drm_device *dev);
 
 extern void intel_uncore_sanitize(struct drm_device *dev);
 extern void intel_uncore_early_sanitize(struct drm_device *dev);
index 72a3df32292f79d88d1ba17dc8d620a24ad435ca..b0f42b9ca037ed472e1a0dd4cd663df6ffd70f06 100644 (file)
@@ -347,10 +347,8 @@ void i915_gem_context_close(struct drm_device *dev, struct drm_file *file)
 {
        struct drm_i915_file_private *file_priv = file->driver_priv;
 
-       mutex_lock(&dev->struct_mutex);
        idr_for_each(&file_priv->context_idr, context_idr_cleanup, NULL);
        idr_destroy(&file_priv->context_idr);
-       mutex_unlock(&dev->struct_mutex);
 }
 
 static struct i915_hw_context *
@@ -423,11 +421,21 @@ static int do_switch(struct i915_hw_context *to)
        if (ret)
                return ret;
 
-       /* Clear this page out of any CPU caches for coherent swap-in/out. Note
+       /*
+        * Pin can switch back to the default context if we end up calling into
+        * evict_everything - as a last ditch gtt defrag effort that also
+        * switches to the default context. Hence we need to reload from here.
+        */
+       from = ring->last_context;
+
+       /*
+        * Clear this page out of any CPU caches for coherent swap-in/out. Note
         * that thanks to write = false in this call and us not setting any gpu
         * write domains when putting a context object onto the active list
         * (when switching away from it), this won't block.
-        * XXX: We need a real interface to do this instead of trickery. */
+        *
+        * XXX: We need a real interface to do this instead of trickery.
+        */
        ret = i915_gem_object_set_to_gtt_domain(to->obj, false);
        if (ret) {
                i915_gem_object_unpin(to->obj);
index b7376533633d2cd74eeae8442a49588cf1af1cdc..8f3adc7d0dc823bd5e7848f013bda20d1d133cbc 100644 (file)
@@ -88,6 +88,7 @@ i915_gem_evict_something(struct drm_device *dev, struct i915_address_space *vm,
        } else
                drm_mm_init_scan(&vm->mm, min_size, alignment, cache_level);
 
+search_again:
        /* First see if there is a large enough contiguous idle region... */
        list_for_each_entry(vma, &vm->inactive_list, mm_list) {
                if (mark_free(vma, &unwind_list))
@@ -115,10 +116,17 @@ none:
                list_del_init(&vma->exec_list);
        }
 
-       /* We expect the caller to unpin, evict all and try again, or give up.
-        * So calling i915_gem_evict_vm() is unnecessary.
+       /* Can we unpin some objects such as idle hw contents,
+        * or pending flips?
         */
-       return -ENOSPC;
+       ret = nonblocking ? -ENOSPC : i915_gpu_idle(dev);
+       if (ret)
+               return ret;
+
+       /* Only idle the GPU and repeat the search once */
+       i915_gem_retire_requests(dev);
+       nonblocking = true;
+       goto search_again;
 
 found:
        /* drm_mm doesn't allow any other other operations while
index 38cb8d44a0133a6c096524a553d45fcb33cd72a1..c79dd2b1f70ecc2af6d0fb67a3c3289672eba7f9 100644 (file)
@@ -337,8 +337,8 @@ static void gen8_ppgtt_cleanup(struct i915_address_space *vm)
                kfree(ppgtt->gen8_pt_dma_addr[i]);
        }
 
-       __free_pages(ppgtt->gen8_pt_pages, ppgtt->num_pt_pages << PAGE_SHIFT);
-       __free_pages(ppgtt->pd_pages, ppgtt->num_pd_pages << PAGE_SHIFT);
+       __free_pages(ppgtt->gen8_pt_pages, get_order(ppgtt->num_pt_pages << PAGE_SHIFT));
+       __free_pages(ppgtt->pd_pages, get_order(ppgtt->num_pd_pages << PAGE_SHIFT));
 }
 
 /**
@@ -1241,6 +1241,11 @@ static inline unsigned int gen8_get_total_gtt_size(u16 bdw_gmch_ctl)
        bdw_gmch_ctl &= BDW_GMCH_GGMS_MASK;
        if (bdw_gmch_ctl)
                bdw_gmch_ctl = 1 << bdw_gmch_ctl;
+       if (bdw_gmch_ctl > 4) {
+               WARN_ON(!i915_preliminary_hw_support);
+               return 4<<20;
+       }
+
        return bdw_gmch_ctl << 20;
 }
 
index 080f6fd4e839b2e3a82926b5ba7ae99b871c9d9e..8b8bde7dce53abce2fea3c655e06ef765433d50f 100644 (file)
@@ -9135,7 +9135,7 @@ intel_pipe_config_compare(struct drm_device *dev,
        if (IS_G4X(dev) || INTEL_INFO(dev)->gen >= 5)
                PIPE_CONF_CHECK_I(pipe_bpp);
 
-       if (!IS_HASWELL(dev)) {
+       if (!HAS_DDI(dev)) {
                PIPE_CONF_CHECK_CLOCK_FUZZY(adjusted_mode.crtc_clock);
                PIPE_CONF_CHECK_CLOCK_FUZZY(port_clock);
        }
@@ -11036,8 +11036,6 @@ void intel_modeset_setup_hw_state(struct drm_device *dev,
        }
 
        intel_modeset_check_state(dev);
-
-       drm_mode_config_reset(dev);
 }
 
 void intel_modeset_gem_init(struct drm_device *dev)
@@ -11046,7 +11044,10 @@ void intel_modeset_gem_init(struct drm_device *dev)
 
        intel_setup_overlay(dev);
 
+       drm_modeset_lock_all(dev);
+       drm_mode_config_reset(dev);
        intel_modeset_setup_hw_state(dev, false);
+       drm_modeset_unlock_all(dev);
 }
 
 void intel_modeset_cleanup(struct drm_device *dev)
index a18e88b3e4250a1e51b21bd8db18729743918f3a..79f91f26e288d4bf2ae7815cb82cfc3271745bd5 100644 (file)
@@ -821,6 +821,7 @@ void intel_update_sprite_watermarks(struct drm_plane *plane,
                                    uint32_t sprite_width, int pixel_size,
                                    bool enabled, bool scaled);
 void intel_init_pm(struct drm_device *dev);
+void intel_pm_setup(struct drm_device *dev);
 bool intel_fbc_enabled(struct drm_device *dev);
 void intel_update_fbc(struct drm_device *dev);
 void intel_gpu_ips_init(struct drm_i915_private *dev_priv);
index f161ac02c4f6e613efbfc7f763cbb3566dc75248..e6f782d1c6696d94fe4d4a80cf7f4d6ee6b5c7d7 100644 (file)
@@ -451,7 +451,9 @@ static u32 intel_panel_get_backlight(struct drm_device *dev,
 
        spin_lock_irqsave(&dev_priv->backlight.lock, flags);
 
-       if (HAS_PCH_SPLIT(dev)) {
+       if (IS_BROADWELL(dev)) {
+               val = I915_READ(BLC_PWM_PCH_CTL2) & BACKLIGHT_DUTY_CYCLE_MASK;
+       } else if (HAS_PCH_SPLIT(dev)) {
                val = I915_READ(BLC_PWM_CPU_CTL) & BACKLIGHT_DUTY_CYCLE_MASK;
        } else {
                if (IS_VALLEYVIEW(dev))
@@ -479,6 +481,13 @@ static u32 intel_panel_get_backlight(struct drm_device *dev,
        return val;
 }
 
+static void intel_bdw_panel_set_backlight(struct drm_device *dev, u32 level)
+{
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       u32 val = I915_READ(BLC_PWM_PCH_CTL2) & ~BACKLIGHT_DUTY_CYCLE_MASK;
+       I915_WRITE(BLC_PWM_PCH_CTL2, val | level);
+}
+
 static void intel_pch_panel_set_backlight(struct drm_device *dev, u32 level)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
@@ -496,7 +505,9 @@ static void intel_panel_actually_set_backlight(struct drm_device *dev,
        DRM_DEBUG_DRIVER("set backlight PWM = %d\n", level);
        level = intel_panel_compute_brightness(dev, pipe, level);
 
-       if (HAS_PCH_SPLIT(dev))
+       if (IS_BROADWELL(dev))
+               return intel_bdw_panel_set_backlight(dev, level);
+       else if (HAS_PCH_SPLIT(dev))
                return intel_pch_panel_set_backlight(dev, level);
 
        if (is_backlight_combination_mode(dev)) {
@@ -666,7 +677,16 @@ void intel_panel_enable_backlight(struct intel_connector *connector)
                POSTING_READ(reg);
                I915_WRITE(reg, tmp | BLM_PWM_ENABLE);
 
-               if (HAS_PCH_SPLIT(dev) &&
+               if (IS_BROADWELL(dev)) {
+                       /*
+                        * Broadwell requires PCH override to drive the PCH
+                        * backlight pin. The above will configure the CPU
+                        * backlight pin, which we don't plan to use.
+                        */
+                       tmp = I915_READ(BLC_PWM_PCH_CTL1);
+                       tmp |= BLM_PCH_OVERRIDE_ENABLE | BLM_PCH_PWM_ENABLE;
+                       I915_WRITE(BLC_PWM_PCH_CTL1, tmp);
+               } else if (HAS_PCH_SPLIT(dev) &&
                    !(dev_priv->quirks & QUIRK_NO_PCH_PWM_ENABLE)) {
                        tmp = I915_READ(BLC_PWM_PCH_CTL1);
                        tmp |= BLM_PCH_PWM_ENABLE;
index 6e0d5e075b15cb338694013450da3752b92442f2..3657ab43c8fd1e20fc9deb10856166b4c35ec0d4 100644 (file)
@@ -5685,6 +5685,7 @@ static void __intel_set_power_well(struct drm_device *dev, bool enable)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
        bool is_enabled, enable_requested;
+       unsigned long irqflags;
        uint32_t tmp;
 
        tmp = I915_READ(HSW_PWR_WELL_DRIVER);
@@ -5702,9 +5703,24 @@ static void __intel_set_power_well(struct drm_device *dev, bool enable)
                                      HSW_PWR_WELL_STATE_ENABLED), 20))
                                DRM_ERROR("Timeout enabling power well\n");
                }
+
+               if (IS_BROADWELL(dev)) {
+                       spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
+                       I915_WRITE(GEN8_DE_PIPE_IMR(PIPE_B),
+                                  dev_priv->de_irq_mask[PIPE_B]);
+                       I915_WRITE(GEN8_DE_PIPE_IER(PIPE_B),
+                                  ~dev_priv->de_irq_mask[PIPE_B] |
+                                  GEN8_PIPE_VBLANK);
+                       I915_WRITE(GEN8_DE_PIPE_IMR(PIPE_C),
+                                  dev_priv->de_irq_mask[PIPE_C]);
+                       I915_WRITE(GEN8_DE_PIPE_IER(PIPE_C),
+                                  ~dev_priv->de_irq_mask[PIPE_C] |
+                                  GEN8_PIPE_VBLANK);
+                       POSTING_READ(GEN8_DE_PIPE_IER(PIPE_C));
+                       spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
+               }
        } else {
                if (enable_requested) {
-                       unsigned long irqflags;
                        enum pipe p;
 
                        I915_WRITE(HSW_PWR_WELL_DRIVER, 0);
@@ -6130,10 +6146,19 @@ int vlv_freq_opcode(int ddr_freq, int val)
        return val;
 }
 
-void intel_pm_init(struct drm_device *dev)
+void intel_pm_setup(struct drm_device *dev)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
 
+       mutex_init(&dev_priv->rps.hw_lock);
+
+       mutex_init(&dev_priv->pc8.lock);
+       dev_priv->pc8.requirements_met = false;
+       dev_priv->pc8.gpu_idle = false;
+       dev_priv->pc8.irqs_disabled = false;
+       dev_priv->pc8.enabled = false;
+       dev_priv->pc8.disable_count = 2; /* requirements_met + gpu_idle */
+       INIT_DELAYED_WORK(&dev_priv->pc8.enable_work, hsw_enable_pc8_work);
        INIT_DELAYED_WORK(&dev_priv->rps.delayed_resume_work,
                          intel_gen6_powersave_work);
 }
index b620337e6d672c164448090016a27d1b713a2a24..c2f09d4563008ff7e32238675dab1b4da02ec967 100644 (file)
@@ -965,6 +965,7 @@ void intel_ring_setup_status_page(struct intel_ring_buffer *ring)
        } else if (IS_GEN6(ring->dev)) {
                mmio = RING_HWS_PGA_GEN6(ring->mmio_base);
        } else {
+               /* XXX: gen8 returns to sanity */
                mmio = RING_HWS_PGA(ring->mmio_base);
        }
 
index 0b02078a0b848c4127385b1d3b5d3ab6be755c80..25cbe073c388a3185d1a32afeb805993e43d12d3 100644 (file)
@@ -784,6 +784,7 @@ static int gen6_do_reset(struct drm_device *dev)
 int intel_gpu_reset(struct drm_device *dev)
 {
        switch (INTEL_INFO(dev)->gen) {
+       case 8:
        case 7:
        case 6: return gen6_do_reset(dev);
        case 5: return ironlake_do_reset(dev);
index 7a3759f1c41a67bac6b48cdcfd5b10b5ac30ae39..98a22e6e27a11f73045fdbab161452309f2416ab 100644 (file)
@@ -858,6 +858,12 @@ static int nouveau_pmops_runtime_suspend(struct device *dev)
        if (nouveau_runtime_pm == 0)
                return -EINVAL;
 
+       /* are we optimus enabled? */
+       if (nouveau_runtime_pm == -1 && !nouveau_is_optimus() && !nouveau_is_v1_dsm()) {
+               DRM_DEBUG_DRIVER("failing to power off - not optimus\n");
+               return -EINVAL;
+       }
+
        nv_debug_level(SILENT);
        drm_kms_helper_poll_disable(drm_dev);
        vga_switcheroo_set_dynamic_switch(pdev, VGA_SWITCHEROO_OFF);
index 80a20120e6253590d07e9ec4b0085b6ea9d31437..b1970596a782a437547a1fe32475253a69557f97 100644 (file)
@@ -1196,7 +1196,9 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc,
        } else if ((rdev->family == CHIP_TAHITI) ||
                   (rdev->family == CHIP_PITCAIRN))
                fb_format |= SI_GRPH_PIPE_CONFIG(SI_ADDR_SURF_P8_32x32_8x16);
-       else if (rdev->family == CHIP_VERDE)
+       else if ((rdev->family == CHIP_VERDE) ||
+                (rdev->family == CHIP_OLAND) ||
+                (rdev->family == CHIP_HAINAN)) /* for completeness.  HAINAN has no display hw */
                fb_format |= SI_GRPH_PIPE_CONFIG(SI_ADDR_SURF_P4_8x16);
 
        switch (radeon_crtc->crtc_id) {
index 0300727a4f70d52c71e24931bbec8335ce6ba6d3..d08b83c6267b4cde4ff5ce0ad71754c1e5e446a1 100644 (file)
@@ -458,7 +458,7 @@ int cik_copy_dma(struct radeon_device *rdev,
                radeon_ring_write(ring, 0); /* src/dst endian swap */
                radeon_ring_write(ring, src_offset & 0xffffffff);
                radeon_ring_write(ring, upper_32_bits(src_offset) & 0xffffffff);
-               radeon_ring_write(ring, dst_offset & 0xfffffffc);
+               radeon_ring_write(ring, dst_offset & 0xffffffff);
                radeon_ring_write(ring, upper_32_bits(dst_offset) & 0xffffffff);
                src_offset += cur_size_in_bytes;
                dst_offset += cur_size_in_bytes;
index e354ce94cdd17492030e2bd85ef1406810e9e5df..c0425bb6223a99fae5eab07a069ab73ace19eec7 100644 (file)
@@ -2021,7 +2021,7 @@ static struct radeon_asic ci_asic = {
                .hdmi_setmode = &evergreen_hdmi_setmode,
        },
        .copy = {
-               .blit = NULL,
+               .blit = &cik_copy_cpdma,
                .blit_ring_index = RADEON_RING_TYPE_GFX_INDEX,
                .dma = &cik_copy_dma,
                .dma_ring_index = R600_RING_TYPE_DMA_INDEX,
@@ -2122,7 +2122,7 @@ static struct radeon_asic kv_asic = {
                .hdmi_setmode = &evergreen_hdmi_setmode,
        },
        .copy = {
-               .blit = NULL,
+               .blit = &cik_copy_cpdma,
                .blit_ring_index = RADEON_RING_TYPE_GFX_INDEX,
                .dma = &cik_copy_dma,
                .dma_ring_index = R600_RING_TYPE_DMA_INDEX,
index 9f5ff28864f6e3ccf4f4736cc55307735d87a70a..1958b36ad0e5cdddf623b8a54a16df0c501ca668 100644 (file)
@@ -508,15 +508,6 @@ static const struct file_operations radeon_driver_kms_fops = {
 #endif
 };
 
-
-static void
-radeon_pci_shutdown(struct pci_dev *pdev)
-{
-       struct drm_device *dev = pci_get_drvdata(pdev);
-
-       radeon_driver_unload_kms(dev);
-}
-
 static struct drm_driver kms_driver = {
        .driver_features =
            DRIVER_USE_AGP |
@@ -586,7 +577,6 @@ static struct pci_driver radeon_kms_pci_driver = {
        .probe = radeon_pci_probe,
        .remove = radeon_pci_remove,
        .driver.pm = &radeon_pm_ops,
-       .shutdown = radeon_pci_shutdown,
 };
 
 static int __init radeon_init(void)
index dc75bb603ea5f1921795c01be6d78438d5b8d98d..984097b907ef5ee67c8e59faf4198ccf8add5f1b 100644 (file)
@@ -552,8 +552,7 @@ static ssize_t radeon_hwmon_show_temp_thresh(struct device *dev,
                                             struct device_attribute *attr,
                                             char *buf)
 {
-       struct drm_device *ddev = dev_get_drvdata(dev);
-       struct radeon_device *rdev = ddev->dev_private;
+       struct radeon_device *rdev = dev_get_drvdata(dev);
        int hyst = to_sensor_dev_attr(attr)->index;
        int temp;
 
@@ -580,8 +579,7 @@ static umode_t hwmon_attributes_visible(struct kobject *kobj,
                                        struct attribute *attr, int index)
 {
        struct device *dev = container_of(kobj, struct device, kobj);
-       struct drm_device *ddev = dev_get_drvdata(dev);
-       struct radeon_device *rdev = ddev->dev_private;
+       struct radeon_device *rdev = dev_get_drvdata(dev);
 
        /* Skip limit attributes if DPM is not enabled */
        if (rdev->pm.pm_method != PM_METHOD_DPM &&
index 1c560629575a8906fb74e006285096f07eac7f19..e7dab069cccf48a05e19cfd7caf27bd65d38c53d 100644 (file)
@@ -162,6 +162,16 @@ static void rs690_mc_init(struct radeon_device *rdev)
        base = RREG32_MC(R_000100_MCCFG_FB_LOCATION);
        base = G_000100_MC_FB_START(base) << 16;
        rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev);
+       /* Some boards seem to be configured for 128MB of sideport memory,
+        * but really only have 64MB.  Just skip the sideport and use
+        * UMA memory.
+        */
+       if (rdev->mc.igp_sideport_enabled &&
+           (rdev->mc.real_vram_size == (384 * 1024 * 1024))) {
+               base += 128 * 1024 * 1024;
+               rdev->mc.real_vram_size -= 128 * 1024 * 1024;
+               rdev->mc.mc_vram_size = rdev->mc.real_vram_size;
+       }
 
        /* Use K8 direct mapping for fast fb access. */ 
        rdev->fastfb_working = false;
index b249ab9b1eb29c402d407049a42c2fda83b3ffb1..6440eeac22d250844d2203018258654e54483cd3 100644 (file)
@@ -169,9 +169,9 @@ static int ttm_bo_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
        }
 
        page_offset = ((address - vma->vm_start) >> PAGE_SHIFT) +
-           drm_vma_node_start(&bo->vma_node) - vma->vm_pgoff;
-       page_last = vma_pages(vma) +
-           drm_vma_node_start(&bo->vma_node) - vma->vm_pgoff;
+               vma->vm_pgoff - drm_vma_node_start(&bo->vma_node);
+       page_last = vma_pages(vma) + vma->vm_pgoff -
+               drm_vma_node_start(&bo->vma_node);
 
        if (unlikely(page_offset >= bo->num_pages)) {
                retval = VM_FAULT_SIGBUS;
index a51f48e3e917e0d3f5d4c73202be335df6f6919b..45d5b5ab6ca9d8788fe80f0fbfd9f164203c026a 100644 (file)
@@ -68,6 +68,9 @@ int vmw_getparam_ioctl(struct drm_device *dev, void *data,
                                  SVGA_FIFO_3D_HWVERSION));
                break;
        }
+       case DRM_VMW_PARAM_MAX_SURF_MEMORY:
+               param->value = dev_priv->memory_size;
+               break;
        default:
                DRM_ERROR("Illegal vmwgfx get param request: %d\n",
                          param->param);
index ecb5ca669e97615cb47cbb9d31381bf76e33f367..e7769636759129f2540c5c670f1cc332180191fe 100644 (file)
@@ -341,6 +341,7 @@ static __u8 *kye_report_fixup(struct hid_device *hdev, __u8 *rdesc,
        case USB_DEVICE_ID_GENIUS_GX_IMPERATOR:
                rdesc = kye_consumer_control_fixup(hdev, rdesc, rsize, 83,
                                        "Genius Gx Imperator Keyboard");
+               break;
        case USB_DEVICE_ID_GENIUS_MANTICORE:
                rdesc = kye_consumer_control_fixup(hdev, rdesc, rsize, 104,
                                        "Genius Manticore Keyboard");
index d87f7cb4bee5af2b6c9d08dc02630c08f0f69cfb..8fab82829f8b11321f957059837e8f50feb71828 100644 (file)
@@ -568,6 +568,8 @@ static int sensor_hub_probe(struct hid_device *hdev,
                                        ret = -ENOMEM;
                                        goto err_free_names;
                        }
+                       sd->hid_sensor_hub_client_devs[
+                               sd->hid_sensor_client_cnt].id = PLATFORM_DEVID_AUTO;
                        sd->hid_sensor_hub_client_devs[
                                sd->hid_sensor_client_cnt].name = name;
                        sd->hid_sensor_hub_client_devs[
index 2dc37c7c6947cfa6dd5fde0e72ff5701f7162dd0..7d68a08baaa83eb42366e17c29b4ff88bda68152 100644 (file)
@@ -43,6 +43,7 @@
  * @last_update: time of last update (jiffies)
  * @temperature: cached temperature measurement value
  * @humidity: cached humidity measurement value
+ * @write_length: length for I2C measurement request
  */
 struct hih6130 {
        struct device *hwmon_dev;
@@ -51,6 +52,7 @@ struct hih6130 {
        unsigned long last_update;
        int temperature;
        int humidity;
+       size_t write_length;
 };
 
 /**
@@ -121,8 +123,15 @@ static int hih6130_update_measurements(struct i2c_client *client)
         */
        if (time_after(jiffies, hih6130->last_update + HZ) || !hih6130->valid) {
 
-               /* write to slave address, no data, to request a measurement */
-               ret = i2c_master_send(client, tmp, 0);
+               /*
+                * Write to slave address to request a measurement.
+                * According with the datasheet it should be with no data, but
+                * for systems with I2C bus drivers that do not allow zero
+                * length packets we write one dummy byte to allow sensor
+                * measurements on them.
+                */
+               tmp[0] = 0;
+               ret = i2c_master_send(client, tmp, hih6130->write_length);
                if (ret < 0)
                        goto out;
 
@@ -252,6 +261,9 @@ static int hih6130_probe(struct i2c_client *client,
                goto fail_remove_sysfs;
        }
 
+       if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_QUICK))
+               hih6130->write_length = 1;
+
        return 0;
 
 fail_remove_sysfs:
index 6cf6bff790033756a70d1d57ebe9f8f1096899f8..a2f3b4a365e4bbafa17385df4fdca298a7ece0e5 100644 (file)
@@ -94,6 +94,8 @@ static inline u8 FAN_TO_REG(long rpm, int div)
 {
        if (rpm <= 0)
                return 255;
+       if (rpm > 1350000)
+               return 1;
        return clamp_val((1350000 + rpm * div / 2) / (rpm * div), 1, 254);
 }
 
index 4c4c1421bf28f66462d8d0bf5f2ee70947005ac0..8b8f3aa49726873b89267ebe45f4e145eab2c7bb 100644 (file)
@@ -1610,12 +1610,14 @@ static int lm90_probe(struct i2c_client *client,
                                                "lm90", client);
                if (err < 0) {
                        dev_err(dev, "cannot request IRQ %d\n", client->irq);
-                       goto exit_remove_files;
+                       goto exit_unregister;
                }
        }
 
        return 0;
 
+exit_unregister:
+       hwmon_device_unregister(data->hwmon_dev);
 exit_remove_files:
        lm90_remove_files(client, data);
 exit_restore:
index 1404e6319deb3cf918c1874f1be8b09b85902d65..72a889702f0dc091b895f653ce39a540aa40bf3b 100644 (file)
@@ -141,6 +141,8 @@ static inline u8 FAN_TO_REG(long rpm, int div)
 {
        if (rpm <= 0)
                return 255;
+       if (rpm > 1350000)
+               return 1;
        return clamp_val((1350000 + rpm * div / 2) / (rpm * div), 1, 254);
 }
 
index 0e7017841f7dacb9b1341e4313f4acaf009349a6..aee14e2192f8813dbb59dee615142db9505dcd9a 100644 (file)
@@ -145,7 +145,7 @@ static const u8 regtempmin[] = { 0x3a, 0x3e, 0x2c, 0x2e, 0x30, 0x32 };
  */
 static inline u8 FAN_TO_REG(long rpm, int div)
 {
-       if (rpm == 0)
+       if (rpm <= 0 || rpm > 1310720)
                return 0;
        return clamp_val(1310720 / (rpm * div), 1, 255);
 }
index edb06cda5a689a4be87046b138051f5b4b42e3ca..6ed76ceb92709078497571ad4cb6f8740d3490bb 100644 (file)
@@ -481,9 +481,11 @@ store_pwm(struct device *dev, struct device_attribute *attr,
        if (err)
                return err;
        val = clamp_val(val, 0, 255);
+       val = DIV_ROUND_CLOSEST(val, 0x11);
 
        mutex_lock(&data->update_lock);
-       data->pwm[nr] = val;
+       data->pwm[nr] = val * 0x11;
+       val |= w83l786ng_read_value(client, W83L786NG_REG_PWM[nr]) & 0xf0;
        w83l786ng_write_value(client, W83L786NG_REG_PWM[nr], val);
        mutex_unlock(&data->update_lock);
        return count;
@@ -510,7 +512,7 @@ store_pwm_enable(struct device *dev, struct device_attribute *attr,
        mutex_lock(&data->update_lock);
        reg = w83l786ng_read_value(client, W83L786NG_REG_FAN_CFG);
        data->pwm_enable[nr] = val;
-       reg &= ~(0x02 << W83L786NG_PWM_ENABLE_SHIFT[nr]);
+       reg &= ~(0x03 << W83L786NG_PWM_ENABLE_SHIFT[nr]);
        reg |= (val - 1) << W83L786NG_PWM_ENABLE_SHIFT[nr];
        w83l786ng_write_value(client, W83L786NG_REG_FAN_CFG, reg);
        mutex_unlock(&data->update_lock);
@@ -776,9 +778,10 @@ static struct w83l786ng_data *w83l786ng_update_device(struct device *dev)
                            ((pwmcfg >> W83L786NG_PWM_MODE_SHIFT[i]) & 1)
                            ? 0 : 1;
                        data->pwm_enable[i] =
-                           ((pwmcfg >> W83L786NG_PWM_ENABLE_SHIFT[i]) & 2) + 1;
-                       data->pwm[i] = w83l786ng_read_value(client,
-                           W83L786NG_REG_PWM[i]);
+                           ((pwmcfg >> W83L786NG_PWM_ENABLE_SHIFT[i]) & 3) + 1;
+                       data->pwm[i] =
+                           (w83l786ng_read_value(client, W83L786NG_REG_PWM[i])
+                            & 0x0f) * 0x11;
                }
 
 
index 1d7efa3169cd772ed2ba580b0c8cfd149eee09d5..d0cfbb4cb9643498540799281399cd1b314b91e3 100644 (file)
@@ -312,7 +312,9 @@ static int i2c_imx_start(struct imx_i2c_struct *i2c_imx)
 
        dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__);
 
-       clk_prepare_enable(i2c_imx->clk);
+       result = clk_prepare_enable(i2c_imx->clk);
+       if (result)
+               return result;
        imx_i2c_write_reg(i2c_imx->ifdr, i2c_imx, IMX_I2C_IFDR);
        /* Enable I2C controller */
        imx_i2c_write_reg(i2c_imx->hwdata->i2sr_clr_opcode, i2c_imx, IMX_I2C_I2SR);
index 797e3117bef7437ef2d6f734431a16e43acaed34..2d0847b6be626d00ee642daab806aeb259f6eb0b 100644 (file)
@@ -139,6 +139,8 @@ struct i2c_adapter *i2c_add_mux_adapter(struct i2c_adapter *parent,
        priv->adap.algo = &priv->algo;
        priv->adap.algo_data = priv;
        priv->adap.dev.parent = &parent->dev;
+       priv->adap.retries = parent->retries;
+       priv->adap.timeout = parent->timeout;
 
        /* Sanity check on class */
        if (i2c_mux_parent_classes(parent) & class)
index acb7f90359a3460371c9d1e8a00cd15c3a77a26d..749a6cadab8b3708d9a9e2d50f9d086f6f17e80e 100644 (file)
@@ -200,7 +200,13 @@ static const struct ad7887_chip_info ad7887_chip_info_tbl[] = {
                        .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
                        .address = 1,
                        .scan_index = 1,
-                       .scan_type = IIO_ST('u', 12, 16, 0),
+                       .scan_type = {
+                               .sign = 'u',
+                               .realbits = 12,
+                               .storagebits = 16,
+                               .shift = 0,
+                               .endianness = IIO_BE,
+                       },
                },
                .channel[1] = {
                        .type = IIO_VOLTAGE,
@@ -210,7 +216,13 @@ static const struct ad7887_chip_info ad7887_chip_info_tbl[] = {
                        .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
                        .address = 0,
                        .scan_index = 0,
-                       .scan_type = IIO_ST('u', 12, 16, 0),
+                       .scan_type = {
+                               .sign = 'u',
+                               .realbits = 12,
+                               .storagebits = 16,
+                               .shift = 0,
+                               .endianness = IIO_BE,
+                       },
                },
                .channel[2] = IIO_CHAN_SOFT_TIMESTAMP(2),
                .int_vref_mv = 2500,
index 3fb7757a10287b1991b4ef23676a8e4d2b315dad..368660dfe135a51c3cac05dd90d7dcb75dacb7c2 100644 (file)
@@ -651,7 +651,12 @@ static const struct iio_chan_spec adis16448_channels[] = {
                .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
                .address = ADIS16448_BARO_OUT,
                .scan_index = ADIS16400_SCAN_BARO,
-               .scan_type = IIO_ST('s', 16, 16, 0),
+               .scan_type = {
+                       .sign = 's',
+                       .realbits = 16,
+                       .storagebits = 16,
+                       .endianness = IIO_BE,
+               },
        },
        ADIS16400_TEMP_CHAN(ADIS16448_TEMP_OUT, 12),
        IIO_CHAN_SOFT_TIMESTAMP(11)
index 21df5713001831f91f5dbd592df94837bf612186..0922e39b0ea979a8355ac5da395d527ab871d269 100644 (file)
@@ -387,7 +387,7 @@ static int cm36651_read_int_time(struct cm36651_data *cm36651,
                return -EINVAL;
        }
 
-       return IIO_VAL_INT_PLUS_MICRO;
+       return IIO_VAL_INT;
 }
 
 static int cm36651_write_int_time(struct cm36651_data *cm36651,
index 0735de3a6468f85cad2c08a1dc601d5a67a67a23..1cb1da2944191cdefbec3c8b910ce16ea994a758 100644 (file)
 
 /* ORIENT ADXL346 only */
 #define ADXL346_2D_VALID               (1 << 6)
-#define ADXL346_2D_ORIENT(x)           (((x) & 0x3) >> 4)
+#define ADXL346_2D_ORIENT(x)           (((x) & 0x30) >> 4)
 #define ADXL346_3D_VALID               (1 << 3)
 #define ADXL346_3D_ORIENT(x)           ((x) & 0x7)
 #define ADXL346_2D_PORTRAIT_POS                0       /* +X */
index 98707fb2cb5d672b6b5bcdc8b787bb37c90c9989..8f4c4ab04bc2d8c61d5fda2a65696806e61ad6f2 100644 (file)
@@ -455,16 +455,26 @@ static DEVICE_ATTR_RO(type);
 static DEVICE_ATTR_RO(proto);
 static DEVICE_ATTR_RO(id);
 static DEVICE_ATTR_RO(extra);
-static DEVICE_ATTR_RO(modalias);
-static DEVICE_ATTR_WO(drvctl);
-static DEVICE_ATTR(description, S_IRUGO, serio_show_description, NULL);
-static DEVICE_ATTR(bind_mode, S_IWUSR | S_IRUGO, serio_show_bind_mode, serio_set_bind_mode);
 
 static struct attribute *serio_device_id_attrs[] = {
        &dev_attr_type.attr,
        &dev_attr_proto.attr,
        &dev_attr_id.attr,
        &dev_attr_extra.attr,
+       NULL
+};
+
+static struct attribute_group serio_id_attr_group = {
+       .name   = "id",
+       .attrs  = serio_device_id_attrs,
+};
+
+static DEVICE_ATTR_RO(modalias);
+static DEVICE_ATTR_WO(drvctl);
+static DEVICE_ATTR(description, S_IRUGO, serio_show_description, NULL);
+static DEVICE_ATTR(bind_mode, S_IWUSR | S_IRUGO, serio_show_bind_mode, serio_set_bind_mode);
+
+static struct attribute *serio_device_attrs[] = {
        &dev_attr_modalias.attr,
        &dev_attr_description.attr,
        &dev_attr_drvctl.attr,
@@ -472,13 +482,13 @@ static struct attribute *serio_device_id_attrs[] = {
        NULL
 };
 
-static struct attribute_group serio_id_attr_group = {
-       .name   = "id",
-       .attrs  = serio_device_id_attrs,
+static struct attribute_group serio_device_attr_group = {
+       .attrs  = serio_device_attrs,
 };
 
 static const struct attribute_group *serio_device_attr_groups[] = {
        &serio_id_attr_group,
+       &serio_device_attr_group,
        NULL
 };
 
index 1abfb5684ab7ebcb7c735e10c71625439490ca09..e46a88700b6824c735967118281c9f7feb6e41b0 100644 (file)
@@ -392,7 +392,7 @@ struct arm_smmu_domain {
        struct arm_smmu_cfg             root_cfg;
        phys_addr_t                     output_mask;
 
-       spinlock_t                      lock;
+       struct mutex                    lock;
 };
 
 static DEFINE_SPINLOCK(arm_smmu_devices_lock);
@@ -900,7 +900,7 @@ static int arm_smmu_domain_init(struct iommu_domain *domain)
                goto out_free_domain;
        smmu_domain->root_cfg.pgd = pgd;
 
-       spin_lock_init(&smmu_domain->lock);
+       mutex_init(&smmu_domain->lock);
        domain->priv = smmu_domain;
        return 0;
 
@@ -1137,7 +1137,7 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
         * Sanity check the domain. We don't currently support domains
         * that cross between different SMMU chains.
         */
-       spin_lock(&smmu_domain->lock);
+       mutex_lock(&smmu_domain->lock);
        if (!smmu_domain->leaf_smmu) {
                /* Now that we have a master, we can finalise the domain */
                ret = arm_smmu_init_domain_context(domain, dev);
@@ -1152,7 +1152,7 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
                        dev_name(device_smmu->dev));
                goto err_unlock;
        }
-       spin_unlock(&smmu_domain->lock);
+       mutex_unlock(&smmu_domain->lock);
 
        /* Looks ok, so add the device to the domain */
        master = find_smmu_master(smmu_domain->leaf_smmu, dev->of_node);
@@ -1162,7 +1162,7 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
        return arm_smmu_domain_add_master(smmu_domain, master);
 
 err_unlock:
-       spin_unlock(&smmu_domain->lock);
+       mutex_unlock(&smmu_domain->lock);
        return ret;
 }
 
@@ -1394,7 +1394,7 @@ static int arm_smmu_handle_mapping(struct arm_smmu_domain *smmu_domain,
        if (paddr & ~output_mask)
                return -ERANGE;
 
-       spin_lock(&smmu_domain->lock);
+       mutex_lock(&smmu_domain->lock);
        pgd += pgd_index(iova);
        end = iova + size;
        do {
@@ -1410,7 +1410,7 @@ static int arm_smmu_handle_mapping(struct arm_smmu_domain *smmu_domain,
        } while (pgd++, iova != end);
 
 out_unlock:
-       spin_unlock(&smmu_domain->lock);
+       mutex_unlock(&smmu_domain->lock);
 
        /* Ensure new page tables are visible to the hardware walker */
        if (smmu->features & ARM_SMMU_FEAT_COHERENT_WALK)
@@ -1423,9 +1423,8 @@ static int arm_smmu_map(struct iommu_domain *domain, unsigned long iova,
                        phys_addr_t paddr, size_t size, int flags)
 {
        struct arm_smmu_domain *smmu_domain = domain->priv;
-       struct arm_smmu_device *smmu = smmu_domain->leaf_smmu;
 
-       if (!smmu_domain || !smmu)
+       if (!smmu_domain)
                return -ENODEV;
 
        /* Check for silent address truncation up the SMMU chain. */
@@ -1449,44 +1448,34 @@ static size_t arm_smmu_unmap(struct iommu_domain *domain, unsigned long iova,
 static phys_addr_t arm_smmu_iova_to_phys(struct iommu_domain *domain,
                                         dma_addr_t iova)
 {
-       pgd_t *pgd;
-       pud_t *pud;
-       pmd_t *pmd;
-       pte_t *pte;
+       pgd_t *pgdp, pgd;
+       pud_t pud;
+       pmd_t pmd;
+       pte_t pte;
        struct arm_smmu_domain *smmu_domain = domain->priv;
        struct arm_smmu_cfg *root_cfg = &smmu_domain->root_cfg;
-       struct arm_smmu_device *smmu = root_cfg->smmu;
 
-       spin_lock(&smmu_domain->lock);
-       pgd = root_cfg->pgd;
-       if (!pgd)
-               goto err_unlock;
+       pgdp = root_cfg->pgd;
+       if (!pgdp)
+               return 0;
 
-       pgd += pgd_index(iova);
-       if (pgd_none_or_clear_bad(pgd))
-               goto err_unlock;
+       pgd = *(pgdp + pgd_index(iova));
+       if (pgd_none(pgd))
+               return 0;
 
-       pud = pud_offset(pgd, iova);
-       if (pud_none_or_clear_bad(pud))
-               goto err_unlock;
+       pud = *pud_offset(&pgd, iova);
+       if (pud_none(pud))
+               return 0;
 
-       pmd = pmd_offset(pud, iova);
-       if (pmd_none_or_clear_bad(pmd))
-               goto err_unlock;
+       pmd = *pmd_offset(&pud, iova);
+       if (pmd_none(pmd))
+               return 0;
 
-       pte = pmd_page_vaddr(*pmd) + pte_index(iova);
+       pte = *(pmd_page_vaddr(pmd) + pte_index(iova));
        if (pte_none(pte))
-               goto err_unlock;
-
-       spin_unlock(&smmu_domain->lock);
-       return __pfn_to_phys(pte_pfn(*pte)) | (iova & ~PAGE_MASK);
+               return 0;
 
-err_unlock:
-       spin_unlock(&smmu_domain->lock);
-       dev_warn(smmu->dev,
-                "invalid (corrupt?) page tables detected for iova 0x%llx\n",
-                (unsigned long long)iova);
-       return -EINVAL;
+       return __pfn_to_phys(pte_pfn(pte)) | (iova & ~PAGE_MASK);
 }
 
 static int arm_smmu_domain_has_cap(struct iommu_domain *domain,
@@ -1863,6 +1852,7 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev)
                dev_err(dev,
                        "found only %d context interrupt(s) but %d required\n",
                        smmu->num_context_irqs, smmu->num_context_banks);
+               err = -ENODEV;
                goto out_put_parent;
        }
 
index 173cbb20d10498b21440ada78b27f241b47af2cc..54bdd923316f92818d509f06986c9a9a3b7b1927 100644 (file)
@@ -1717,6 +1717,11 @@ static int __init dm_bufio_init(void)
 {
        __u64 mem;
 
+       dm_bufio_allocated_kmem_cache = 0;
+       dm_bufio_allocated_get_free_pages = 0;
+       dm_bufio_allocated_vmalloc = 0;
+       dm_bufio_current_allocated = 0;
+
        memset(&dm_bufio_caches, 0, sizeof dm_bufio_caches);
        memset(&dm_bufio_cache_names, 0, sizeof dm_bufio_cache_names);
 
index 416b7b752a6e0018d4a11800606a8be6b8890e22..64780ad73bb01737a957ea9682d016da4dbffa93 100644 (file)
@@ -730,15 +730,18 @@ static int pre_cache_entry_found(struct mq_policy *mq, struct entry *e,
        int r = 0;
        bool updated = updated_this_tick(mq, e);
 
-       requeue_and_update_tick(mq, e);
-
        if ((!discarded_oblock && updated) ||
-           !should_promote(mq, e, discarded_oblock, data_dir))
+           !should_promote(mq, e, discarded_oblock, data_dir)) {
+               requeue_and_update_tick(mq, e);
                result->op = POLICY_MISS;
-       else if (!can_migrate)
+
+       } else if (!can_migrate)
                r = -EWOULDBLOCK;
-       else
+
+       else {
+               requeue_and_update_tick(mq, e);
                r = pre_cache_to_cache(mq, e, result);
+       }
 
        return r;
 }
index 9efcf1059b99e3ae2e6e712eb150c0954646d5d8..1b1469ebe5cbad66af0853e0766ba20dbee63275 100644 (file)
@@ -2755,7 +2755,7 @@ static int resize_cache_dev(struct cache *cache, dm_cblock_t new_size)
 {
        int r;
 
-       r = dm_cache_resize(cache->cmd, cache->cache_size);
+       r = dm_cache_resize(cache->cmd, new_size);
        if (r) {
                DMERR("could not resize cache metadata");
                return r;
index 496d5f3646a5df623e6c0a9b22d35ad003c610bc..2f91d6d4a2ccf40023c6bccfe142d7781024c810 100644 (file)
@@ -20,6 +20,7 @@
 struct delay_c {
        struct timer_list delay_timer;
        struct mutex timer_lock;
+       struct workqueue_struct *kdelayd_wq;
        struct work_struct flush_expired_bios;
        struct list_head delayed_bios;
        atomic_t may_delay;
@@ -45,14 +46,13 @@ struct dm_delay_info {
 
 static DEFINE_MUTEX(delayed_bios_lock);
 
-static struct workqueue_struct *kdelayd_wq;
 static struct kmem_cache *delayed_cache;
 
 static void handle_delayed_timer(unsigned long data)
 {
        struct delay_c *dc = (struct delay_c *)data;
 
-       queue_work(kdelayd_wq, &dc->flush_expired_bios);
+       queue_work(dc->kdelayd_wq, &dc->flush_expired_bios);
 }
 
 static void queue_timeout(struct delay_c *dc, unsigned long expires)
@@ -191,6 +191,12 @@ out:
                goto bad_dev_write;
        }
 
+       dc->kdelayd_wq = alloc_workqueue("kdelayd", WQ_MEM_RECLAIM, 0);
+       if (!dc->kdelayd_wq) {
+               DMERR("Couldn't start kdelayd");
+               goto bad_queue;
+       }
+
        setup_timer(&dc->delay_timer, handle_delayed_timer, (unsigned long)dc);
 
        INIT_WORK(&dc->flush_expired_bios, flush_expired_bios);
@@ -203,6 +209,8 @@ out:
        ti->private = dc;
        return 0;
 
+bad_queue:
+       mempool_destroy(dc->delayed_pool);
 bad_dev_write:
        if (dc->dev_write)
                dm_put_device(ti, dc->dev_write);
@@ -217,7 +225,7 @@ static void delay_dtr(struct dm_target *ti)
 {
        struct delay_c *dc = ti->private;
 
-       flush_workqueue(kdelayd_wq);
+       destroy_workqueue(dc->kdelayd_wq);
 
        dm_put_device(ti, dc->dev_read);
 
@@ -350,12 +358,6 @@ static int __init dm_delay_init(void)
 {
        int r = -ENOMEM;
 
-       kdelayd_wq = alloc_workqueue("kdelayd", WQ_MEM_RECLAIM, 0);
-       if (!kdelayd_wq) {
-               DMERR("Couldn't start kdelayd");
-               goto bad_queue;
-       }
-
        delayed_cache = KMEM_CACHE(dm_delay_info, 0);
        if (!delayed_cache) {
                DMERR("Couldn't create delayed bio cache.");
@@ -373,8 +375,6 @@ static int __init dm_delay_init(void)
 bad_register:
        kmem_cache_destroy(delayed_cache);
 bad_memcache:
-       destroy_workqueue(kdelayd_wq);
-bad_queue:
        return r;
 }
 
@@ -382,7 +382,6 @@ static void __exit dm_delay_exit(void)
 {
        dm_unregister_target(&delay_target);
        kmem_cache_destroy(delayed_cache);
-       destroy_workqueue(kdelayd_wq);
 }
 
 /* Module hooks */
index aec57d76db5d616c8e692fa95cee58a8f62a0573..944690bafd93241d9348f0a4f1cad7f917ce7d83 100644 (file)
@@ -66,6 +66,18 @@ struct dm_snapshot {
 
        atomic_t pending_exceptions_count;
 
+       /* Protected by "lock" */
+       sector_t exception_start_sequence;
+
+       /* Protected by kcopyd single-threaded callback */
+       sector_t exception_complete_sequence;
+
+       /*
+        * A list of pending exceptions that completed out of order.
+        * Protected by kcopyd single-threaded callback.
+        */
+       struct list_head out_of_order_list;
+
        mempool_t *pending_pool;
 
        struct dm_exception_table pending;
@@ -173,6 +185,14 @@ struct dm_snap_pending_exception {
         */
        int started;
 
+       /* There was copying error. */
+       int copy_error;
+
+       /* A sequence number, it is used for in-order completion. */
+       sector_t exception_sequence;
+
+       struct list_head out_of_order_entry;
+
        /*
         * For writing a complete chunk, bypassing the copy.
         */
@@ -1094,6 +1114,9 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv)
        s->valid = 1;
        s->active = 0;
        atomic_set(&s->pending_exceptions_count, 0);
+       s->exception_start_sequence = 0;
+       s->exception_complete_sequence = 0;
+       INIT_LIST_HEAD(&s->out_of_order_list);
        init_rwsem(&s->lock);
        INIT_LIST_HEAD(&s->list);
        spin_lock_init(&s->pe_lock);
@@ -1443,6 +1466,19 @@ static void commit_callback(void *context, int success)
        pending_complete(pe, success);
 }
 
+static void complete_exception(struct dm_snap_pending_exception *pe)
+{
+       struct dm_snapshot *s = pe->snap;
+
+       if (unlikely(pe->copy_error))
+               pending_complete(pe, 0);
+
+       else
+               /* Update the metadata if we are persistent */
+               s->store->type->commit_exception(s->store, &pe->e,
+                                                commit_callback, pe);
+}
+
 /*
  * Called when the copy I/O has finished.  kcopyd actually runs
  * this code so don't block.
@@ -1452,13 +1488,32 @@ static void copy_callback(int read_err, unsigned long write_err, void *context)
        struct dm_snap_pending_exception *pe = context;
        struct dm_snapshot *s = pe->snap;
 
-       if (read_err || write_err)
-               pending_complete(pe, 0);
+       pe->copy_error = read_err || write_err;
 
-       else
-               /* Update the metadata if we are persistent */
-               s->store->type->commit_exception(s->store, &pe->e,
-                                                commit_callback, pe);
+       if (pe->exception_sequence == s->exception_complete_sequence) {
+               s->exception_complete_sequence++;
+               complete_exception(pe);
+
+               while (!list_empty(&s->out_of_order_list)) {
+                       pe = list_entry(s->out_of_order_list.next,
+                                       struct dm_snap_pending_exception, out_of_order_entry);
+                       if (pe->exception_sequence != s->exception_complete_sequence)
+                               break;
+                       s->exception_complete_sequence++;
+                       list_del(&pe->out_of_order_entry);
+                       complete_exception(pe);
+               }
+       } else {
+               struct list_head *lh;
+               struct dm_snap_pending_exception *pe2;
+
+               list_for_each_prev(lh, &s->out_of_order_list) {
+                       pe2 = list_entry(lh, struct dm_snap_pending_exception, out_of_order_entry);
+                       if (pe2->exception_sequence < pe->exception_sequence)
+                               break;
+               }
+               list_add(&pe->out_of_order_entry, lh);
+       }
 }
 
 /*
@@ -1553,6 +1608,8 @@ __find_pending_exception(struct dm_snapshot *s,
                return NULL;
        }
 
+       pe->exception_sequence = s->exception_start_sequence++;
+
        dm_insert_exception(&s->pending, &pe->e);
 
        return pe;
@@ -2192,7 +2249,7 @@ static struct target_type origin_target = {
 
 static struct target_type snapshot_target = {
        .name    = "snapshot",
-       .version = {1, 11, 1},
+       .version = {1, 12, 0},
        .module  = THIS_MODULE,
        .ctr     = snapshot_ctr,
        .dtr     = snapshot_dtr,
index 3d404c1371ed2d7e6f4fa052fd4379fbc89ec388..28a90122a5a89272f5873ed0911d2de19125c15b 100644 (file)
@@ -964,6 +964,7 @@ int dm_stats_message(struct mapped_device *md, unsigned argc, char **argv,
 
 int __init dm_statistics_init(void)
 {
+       shared_memory_amount = 0;
        dm_stat_need_rcu_barrier = 0;
        return 0;
 }
index 465f08ca62b1e355f8fd776fac4a6159d79a1a2e..3ba6a3859ce3c4957439ff3afdc4a5133bc2900b 100644 (file)
@@ -200,6 +200,11 @@ int dm_table_create(struct dm_table **result, fmode_t mode,
 
        num_targets = dm_round_up(num_targets, KEYS_PER_NODE);
 
+       if (!num_targets) {
+               kfree(t);
+               return -ENOMEM;
+       }
+
        if (alloc_targets(t, num_targets)) {
                kfree(t);
                return -ENOMEM;
index 60bce435f4fa1443c2994bd483e70ea096c7aa92..8a30ad54bd46aabc72f4ac1800890b5bd8041e11 100644 (file)
@@ -1697,6 +1697,14 @@ void dm_pool_metadata_read_only(struct dm_pool_metadata *pmd)
        up_write(&pmd->root_lock);
 }
 
+void dm_pool_metadata_read_write(struct dm_pool_metadata *pmd)
+{
+       down_write(&pmd->root_lock);
+       pmd->read_only = false;
+       dm_bm_set_read_write(pmd->bm);
+       up_write(&pmd->root_lock);
+}
+
 int dm_pool_register_metadata_threshold(struct dm_pool_metadata *pmd,
                                        dm_block_t threshold,
                                        dm_sm_threshold_fn fn,
index 845ebbe589a9e0a00505bab0150df48331233928..7bcc0e1d62386768d540c41da8e0a25bf7fe9e78 100644 (file)
@@ -193,6 +193,7 @@ int dm_pool_resize_metadata_dev(struct dm_pool_metadata *pmd, dm_block_t new_siz
  * that nothing is changing.
  */
 void dm_pool_metadata_read_only(struct dm_pool_metadata *pmd);
+void dm_pool_metadata_read_write(struct dm_pool_metadata *pmd);
 
 int dm_pool_register_metadata_threshold(struct dm_pool_metadata *pmd,
                                        dm_block_t threshold,
index 2c0cf511ec2385fa5a558b5d2e1e1ed0c874c9f6..ee29037ffc2e74633050b708718ccbe963bf20d1 100644 (file)
@@ -640,7 +640,9 @@ static void process_prepared_mapping(struct dm_thin_new_mapping *m)
         */
        r = dm_thin_insert_block(tc->td, m->virt_block, m->data_block);
        if (r) {
-               DMERR_LIMIT("dm_thin_insert_block() failed");
+               DMERR_LIMIT("%s: dm_thin_insert_block() failed: error = %d",
+                           dm_device_name(pool->pool_md), r);
+               set_pool_mode(pool, PM_READ_ONLY);
                cell_error(pool, m->cell);
                goto out;
        }
@@ -881,32 +883,23 @@ static void schedule_zero(struct thin_c *tc, dm_block_t virt_block,
        }
 }
 
-static int commit(struct pool *pool)
-{
-       int r;
-
-       r = dm_pool_commit_metadata(pool->pmd);
-       if (r)
-               DMERR_LIMIT("%s: commit failed: error = %d",
-                           dm_device_name(pool->pool_md), r);
-
-       return r;
-}
-
 /*
  * A non-zero return indicates read_only or fail_io mode.
  * Many callers don't care about the return value.
  */
-static int commit_or_fallback(struct pool *pool)
+static int commit(struct pool *pool)
 {
        int r;
 
        if (get_pool_mode(pool) != PM_WRITE)
                return -EINVAL;
 
-       r = commit(pool);
-       if (r)
+       r = dm_pool_commit_metadata(pool->pmd);
+       if (r) {
+               DMERR_LIMIT("%s: dm_pool_commit_metadata failed: error = %d",
+                           dm_device_name(pool->pool_md), r);
                set_pool_mode(pool, PM_READ_ONLY);
+       }
 
        return r;
 }
@@ -943,7 +936,9 @@ static int alloc_data_block(struct thin_c *tc, dm_block_t *result)
                 * Try to commit to see if that will free up some
                 * more space.
                 */
-               (void) commit_or_fallback(pool);
+               r = commit(pool);
+               if (r)
+                       return r;
 
                r = dm_pool_get_free_block_count(pool->pmd, &free_blocks);
                if (r)
@@ -957,7 +952,7 @@ static int alloc_data_block(struct thin_c *tc, dm_block_t *result)
                 * table reload).
                 */
                if (!free_blocks) {
-                       DMWARN("%s: no free space available.",
+                       DMWARN("%s: no free data space available.",
                               dm_device_name(pool->pool_md));
                        spin_lock_irqsave(&pool->lock, flags);
                        pool->no_free_space = 1;
@@ -967,8 +962,16 @@ static int alloc_data_block(struct thin_c *tc, dm_block_t *result)
        }
 
        r = dm_pool_alloc_data_block(pool->pmd, result);
-       if (r)
+       if (r) {
+               if (r == -ENOSPC &&
+                   !dm_pool_get_free_metadata_block_count(pool->pmd, &free_blocks) &&
+                   !free_blocks) {
+                       DMWARN("%s: no free metadata space available.",
+                              dm_device_name(pool->pool_md));
+                       set_pool_mode(pool, PM_READ_ONLY);
+               }
                return r;
+       }
 
        return 0;
 }
@@ -1349,7 +1352,7 @@ static void process_deferred_bios(struct pool *pool)
        if (bio_list_empty(&bios) && !need_commit_due_to_time(pool))
                return;
 
-       if (commit_or_fallback(pool)) {
+       if (commit(pool)) {
                while ((bio = bio_list_pop(&bios)))
                        bio_io_error(bio);
                return;
@@ -1397,6 +1400,7 @@ static void set_pool_mode(struct pool *pool, enum pool_mode mode)
        case PM_FAIL:
                DMERR("%s: switching pool to failure mode",
                      dm_device_name(pool->pool_md));
+               dm_pool_metadata_read_only(pool->pmd);
                pool->process_bio = process_bio_fail;
                pool->process_discard = process_bio_fail;
                pool->process_prepared_mapping = process_prepared_mapping_fail;
@@ -1421,6 +1425,7 @@ static void set_pool_mode(struct pool *pool, enum pool_mode mode)
                break;
 
        case PM_WRITE:
+               dm_pool_metadata_read_write(pool->pmd);
                pool->process_bio = process_bio;
                pool->process_discard = process_discard;
                pool->process_prepared_mapping = process_prepared_mapping;
@@ -1637,12 +1642,19 @@ static int bind_control_target(struct pool *pool, struct dm_target *ti)
        struct pool_c *pt = ti->private;
 
        /*
-        * We want to make sure that degraded pools are never upgraded.
+        * We want to make sure that a pool in PM_FAIL mode is never upgraded.
         */
        enum pool_mode old_mode = pool->pf.mode;
        enum pool_mode new_mode = pt->adjusted_pf.mode;
 
-       if (old_mode > new_mode)
+       /*
+        * If we were in PM_FAIL mode, rollback of metadata failed.  We're
+        * not going to recover without a thin_repair.  So we never let the
+        * pool move out of the old mode.  On the other hand a PM_READ_ONLY
+        * may have been due to a lack of metadata or data space, and may
+        * now work (ie. if the underlying devices have been resized).
+        */
+       if (old_mode == PM_FAIL)
                new_mode = old_mode;
 
        pool->ti = ti;
@@ -2266,7 +2278,7 @@ static int pool_preresume(struct dm_target *ti)
                return r;
 
        if (need_commit1 || need_commit2)
-               (void) commit_or_fallback(pool);
+               (void) commit(pool);
 
        return 0;
 }
@@ -2293,7 +2305,7 @@ static void pool_postsuspend(struct dm_target *ti)
 
        cancel_delayed_work(&pool->waker);
        flush_workqueue(pool->wq);
-       (void) commit_or_fallback(pool);
+       (void) commit(pool);
 }
 
 static int check_arg_count(unsigned argc, unsigned args_required)
@@ -2427,7 +2439,7 @@ static int process_reserve_metadata_snap_mesg(unsigned argc, char **argv, struct
        if (r)
                return r;
 
-       (void) commit_or_fallback(pool);
+       (void) commit(pool);
 
        r = dm_pool_reserve_metadata_snap(pool->pmd);
        if (r)
@@ -2489,7 +2501,7 @@ static int pool_message(struct dm_target *ti, unsigned argc, char **argv)
                DMWARN("Unrecognised thin pool target message received: %s", argv[0]);
 
        if (!r)
-               (void) commit_or_fallback(pool);
+               (void) commit(pool);
 
        return r;
 }
@@ -2544,7 +2556,7 @@ static void pool_status(struct dm_target *ti, status_type_t type,
 
                /* Commit to ensure statistics aren't out-of-date */
                if (!(status_flags & DM_STATUS_NOFLUSH_FLAG) && !dm_suspended(ti))
-                       (void) commit_or_fallback(pool);
+                       (void) commit(pool);
 
                r = dm_pool_get_metadata_transaction_id(pool->pmd, &transaction_id);
                if (r) {
index af96e24ec3280ff9c29a7b7f13fde6fc4ba43e52..1d75b1dc1e2e2fcdd24a3be8cf9f0168efacd51e 100644 (file)
@@ -317,8 +317,16 @@ static int shadow_ablock(struct dm_array_info *info, dm_block_t *root,
         * The shadow op will often be a noop.  Only insert if it really
         * copied data.
         */
-       if (dm_block_location(*block) != b)
+       if (dm_block_location(*block) != b) {
+               /*
+                * dm_tm_shadow_block will have already decremented the old
+                * block, but it is still referenced by the btree.  We
+                * increment to stop the insert decrementing it below zero
+                * when overwriting the old value.
+                */
+               dm_tm_inc(info->btree_info.tm, b);
                r = insert_ablock(info, index, *block, root);
+       }
 
        return r;
 }
index a7e8bf2963886dfa349a03644cf33ff1ded748c5..064a3c271baa8843657dca3c374ed89061565ad4 100644 (file)
@@ -626,6 +626,12 @@ void dm_bm_set_read_only(struct dm_block_manager *bm)
 }
 EXPORT_SYMBOL_GPL(dm_bm_set_read_only);
 
+void dm_bm_set_read_write(struct dm_block_manager *bm)
+{
+       bm->read_only = false;
+}
+EXPORT_SYMBOL_GPL(dm_bm_set_read_write);
+
 u32 dm_bm_checksum(const void *data, size_t len, u32 init_xor)
 {
        return crc32c(~(u32) 0, data, len) ^ init_xor;
index 9a82083a66b6a86833bccc1d2b6d4d43c9de6500..13cd58e1fe69ffb4ed477b10ee6bbbe6d58d9926 100644 (file)
@@ -108,9 +108,9 @@ int dm_bm_unlock(struct dm_block *b);
 int dm_bm_flush_and_unlock(struct dm_block_manager *bm,
                           struct dm_block *superblock);
 
- /*
 * Request data be prefetched into the cache.
 */
+/*
* Request data is prefetched into the cache.
+ */
 void dm_bm_prefetch(struct dm_block_manager *bm, dm_block_t b);
 
 /*
@@ -125,6 +125,7 @@ void dm_bm_prefetch(struct dm_block_manager *bm, dm_block_t b);
  * be returned if you do.
  */
 void dm_bm_set_read_only(struct dm_block_manager *bm);
+void dm_bm_set_read_write(struct dm_block_manager *bm);
 
 u32 dm_bm_checksum(const void *data, size_t len, u32 init_xor);
 
index 6058569fe86c3dcf862ddc933e234e721dbdc3e6..466a60bbd716f6470d1e4004ac217c3f546f5c81 100644 (file)
@@ -381,7 +381,7 @@ int sm_ll_find_free_block(struct ll_disk *ll, dm_block_t begin,
 }
 
 static int sm_ll_mutate(struct ll_disk *ll, dm_block_t b,
-                       uint32_t (*mutator)(void *context, uint32_t old),
+                       int (*mutator)(void *context, uint32_t old, uint32_t *new),
                        void *context, enum allocation_event *ev)
 {
        int r;
@@ -410,11 +410,17 @@ static int sm_ll_mutate(struct ll_disk *ll, dm_block_t b,
 
        if (old > 2) {
                r = sm_ll_lookup_big_ref_count(ll, b, &old);
-               if (r < 0)
+               if (r < 0) {
+                       dm_tm_unlock(ll->tm, nb);
                        return r;
+               }
        }
 
-       ref_count = mutator(context, old);
+       r = mutator(context, old, &ref_count);
+       if (r) {
+               dm_tm_unlock(ll->tm, nb);
+               return r;
+       }
 
        if (ref_count <= 2) {
                sm_set_bitmap(bm_le, bit, ref_count);
@@ -465,9 +471,10 @@ static int sm_ll_mutate(struct ll_disk *ll, dm_block_t b,
        return ll->save_ie(ll, index, &ie_disk);
 }
 
-static uint32_t set_ref_count(void *context, uint32_t old)
+static int set_ref_count(void *context, uint32_t old, uint32_t *new)
 {
-       return *((uint32_t *) context);
+       *new = *((uint32_t *) context);
+       return 0;
 }
 
 int sm_ll_insert(struct ll_disk *ll, dm_block_t b,
@@ -476,9 +483,10 @@ int sm_ll_insert(struct ll_disk *ll, dm_block_t b,
        return sm_ll_mutate(ll, b, set_ref_count, &ref_count, ev);
 }
 
-static uint32_t inc_ref_count(void *context, uint32_t old)
+static int inc_ref_count(void *context, uint32_t old, uint32_t *new)
 {
-       return old + 1;
+       *new = old + 1;
+       return 0;
 }
 
 int sm_ll_inc(struct ll_disk *ll, dm_block_t b, enum allocation_event *ev)
@@ -486,9 +494,15 @@ int sm_ll_inc(struct ll_disk *ll, dm_block_t b, enum allocation_event *ev)
        return sm_ll_mutate(ll, b, inc_ref_count, NULL, ev);
 }
 
-static uint32_t dec_ref_count(void *context, uint32_t old)
+static int dec_ref_count(void *context, uint32_t old, uint32_t *new)
 {
-       return old - 1;
+       if (!old) {
+               DMERR_LIMIT("unable to decrement a reference count below 0");
+               return -EINVAL;
+       }
+
+       *new = old - 1;
+       return 0;
 }
 
 int sm_ll_dec(struct ll_disk *ll, dm_block_t b, enum allocation_event *ev)
index 1c959684caef7512fafd3c1a5505c29c798a9c11..58fc1eef7499e1923ef00095502c1e1b49f50ffb 100644 (file)
@@ -384,12 +384,16 @@ static int sm_metadata_new_block(struct dm_space_map *sm, dm_block_t *b)
        struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm);
 
        int r = sm_metadata_new_block_(sm, b);
-       if (r)
+       if (r) {
                DMERR("unable to allocate new metadata block");
+               return r;
+       }
 
        r = sm_metadata_get_nr_free(sm, &count);
-       if (r)
+       if (r) {
                DMERR("couldn't get free block count");
+               return r;
+       }
 
        check_threshold(&smm->threshold, count);
 
index d0799e32336450d967114938fc610b66d4134070..9c9063cd3208909d5840a7c2cc745d1bf124f542 100644 (file)
@@ -955,7 +955,7 @@ struct sms_rx_stats {
        u32 modem_state;                /* from SMSHOSTLIB_DVB_MODEM_STATE_ET */
        s32 SNR;                /* dB */
        u32 ber;                /* Post Viterbi ber [1E-5] */
-       u32 ber_error_count;    /* Number of erronous SYNC bits. */
+       u32 ber_error_count;    /* Number of erroneous SYNC bits. */
        u32 ber_bit_count;      /* Total number of SYNC bits. */
        u32 ts_per;             /* Transport stream PER,
        0xFFFFFFFF indicate N/A */
@@ -981,7 +981,7 @@ struct sms_rx_stats_ex {
        u32 modem_state;                /* from SMSHOSTLIB_DVB_MODEM_STATE_ET */
        s32 SNR;                /* dB */
        u32 ber;                /* Post Viterbi ber [1E-5] */
-       u32 ber_error_count;    /* Number of erronous SYNC bits. */
+       u32 ber_error_count;    /* Number of erroneous SYNC bits. */
        u32 ber_bit_count;      /* Total number of SYNC bits. */
        u32 ts_per;             /* Transport stream PER,
        0xFFFFFFFF indicate N/A */
index 92c413ba0c7971386f052e2f4c4c00876062a31d..ae36d0ae0fb1991ae0ee2e16e392796ca12d271f 100644 (file)
@@ -95,7 +95,7 @@ struct RECEPTION_STATISTICS_PER_SLICES_S {
        u32 is_demod_locked;    /* 0 - not locked, 1 - locked */
 
        u32 ber_bit_count;      /* Total number of SYNC bits. */
-       u32 ber_error_count;    /* Number of erronous SYNC bits. */
+       u32 ber_error_count;    /* Number of erroneous SYNC bits. */
 
        s32 MRC_SNR;            /* dB */
        s32 mrc_in_band_pwr;    /* In band power in dBM */
index 58de4410c5258a7d6009ae47b5becd7e20fa6208..6c7ff0cdcd32ddd44cae9dcf85e98054a7601052 100644 (file)
@@ -435,7 +435,7 @@ static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf)
                dprintk_tscheck("TEI detected. "
                                "PID=0x%x data1=0x%x\n",
                                pid, buf[1]);
-               /* data in this packet cant be trusted - drop it unless
+               /* data in this packet can't be trusted - drop it unless
                 * module option dvb_demux_feed_err_pkts is set */
                if (!dvb_demux_feed_err_pkts)
                        return;
@@ -1032,8 +1032,13 @@ static int dmx_section_feed_release_filter(struct dmx_section_feed *feed,
                return -EINVAL;
        }
 
-       if (feed->is_filtering)
+       if (feed->is_filtering) {
+               /* release dvbdmx->mutex as far as it is
+                  acquired by stop_filtering() itself */
+               mutex_unlock(&dvbdmx->mutex);
                feed->stop_filtering(feed);
+               mutex_lock(&dvbdmx->mutex);
+       }
 
        spin_lock_irq(&dvbdmx->lock);
        f = dvbdmxfeed->filter;
index 30ee59052157815edd50669afe2293ed4e2e8867..65728c25ea05adcd50bd658c96a6c54dd6fb569b 100644 (file)
@@ -170,18 +170,18 @@ static int af9033_rd_reg_mask(struct af9033_state *state, u32 reg, u8 *val,
 static int af9033_wr_reg_val_tab(struct af9033_state *state,
                const struct reg_val *tab, int tab_len)
 {
+#define MAX_TAB_LEN 212
        int ret, i, j;
-       u8 buf[MAX_XFER_SIZE];
+       u8 buf[1 + MAX_TAB_LEN];
+
+       dev_dbg(&state->i2c->dev, "%s: tab_len=%d\n", __func__, tab_len);
 
        if (tab_len > sizeof(buf)) {
-               dev_warn(&state->i2c->dev,
-                        "%s: i2c wr len=%d is too big!\n",
-                        KBUILD_MODNAME, tab_len);
+               dev_warn(&state->i2c->dev, "%s: tab len %d is too big\n",
+                               KBUILD_MODNAME, tab_len);
                return -EINVAL;
        }
 
-       dev_dbg(&state->i2c->dev, "%s: tab_len=%d\n", __func__, tab_len);
-
        for (i = 0, j = 0; i < tab_len; i++) {
                buf[j] = tab[i].val;
 
index 125a44041011ca0ed17f99999a2bffaa5c1999a1..5c6ab4921bf11d2004ed77e9240b2452fbbb3974 100644 (file)
@@ -78,7 +78,7 @@ int cxd2820r_set_frontend_c(struct dvb_frontend *fe)
 
        num = if_freq / 1000; /* Hz => kHz */
        num *= 0x4000;
-       if_ctl = cxd2820r_div_u64_round_closest(num, 41000);
+       if_ctl = 0x4000 - cxd2820r_div_u64_round_closest(num, 41000);
        buf[0] = (if_ctl >> 8) & 0x3f;
        buf[1] = (if_ctl >> 0) & 0xff;
 
index 90536147bf0458c444a59e176b79ddff09471f4f..6dbbee453ee15adb0c4d6b97196beefe6e7d9523 100644 (file)
@@ -3048,7 +3048,7 @@ static int dib8000_tune(struct dvb_frontend *fe)
                        dib8000_set_diversity_in(state->fe[0], state->diversity_onoff);
 
                        locks = (dib8000_read_word(state, 180) >> 6) & 0x3f; /* P_coff_winlen ? */
-                       /* coff should lock over P_coff_winlen ofdm symbols : give 3 times this lenght to lock */
+                       /* coff should lock over P_coff_winlen ofdm symbols : give 3 times this length to lock */
                        *timeout = dib8000_get_timeout(state, 2 * locks, SYMBOL_DEPENDENT_ON);
                        *tune_state = CT_DEMOD_STEP_5;
                        break;
@@ -3115,7 +3115,7 @@ static int dib8000_tune(struct dvb_frontend *fe)
 
        case CT_DEMOD_STEP_9: /* 39 */
                        if ((state->revision == 0x8090) || ((dib8000_read_word(state, 1291) >> 9) & 0x1)) { /* fe capable of deinterleaving : esram */
-                               /* defines timeout for mpeg lock depending on interleaver lenght of longest layer */
+                               /* defines timeout for mpeg lock depending on interleaver length of longest layer */
                                for (i = 0; i < 3; i++) {
                                        if (c->layer[i].interleaving >= deeper_interleaver) {
                                                dprintk("layer%i: time interleaver = %d ", i, c->layer[i].interleaving);
index d416c15691dadd69b49eda6f26c70892c3a02652..bf29a3f0e6f0ca440990f7b8b61e71e9bd02674a 100644 (file)
@@ -1191,7 +1191,7 @@ static int mpegts_configure_pins(struct drxk_state *state, bool mpeg_enable)
                        goto error;
 
                if (state->m_enable_parallel == true) {
-                       /* paralel -> enable MD1 to MD7 */
+                       /* parallel -> enable MD1 to MD7 */
                        status = write16(state, SIO_PDR_MD1_CFG__A,
                                         sio_pdr_mdx_cfg);
                        if (status < 0)
@@ -1428,7 +1428,7 @@ static int mpegts_stop(struct drxk_state *state)
 
        dprintk(1, "\n");
 
-       /* Gracefull shutdown (byte boundaries) */
+       /* Graceful shutdown (byte boundaries) */
        status = read16(state, FEC_OC_SNC_MODE__A, &fec_oc_snc_mode);
        if (status < 0)
                goto error;
@@ -2021,7 +2021,7 @@ static int mpegts_dto_setup(struct drxk_state *state,
                fec_oc_dto_burst_len = 204;
        }
 
-       /* Check serial or parrallel output */
+       /* Check serial or parallel output */
        fec_oc_reg_ipr_mode &= (~(FEC_OC_IPR_MODE_SERIAL__M));
        if (state->m_enable_parallel == false) {
                /* MPEG data output is serial -> set ipr_mode[0] */
@@ -2908,7 +2908,7 @@ static int adc_synchronization(struct drxk_state *state)
                goto error;
 
        if (count == 1) {
-               /* Try sampling on a diffrent edge */
+               /* Try sampling on a different edge */
                u16 clk_neg = 0;
 
                status = read16(state, IQM_AF_CLKNEG__A, &clk_neg);
@@ -3306,7 +3306,7 @@ static int dvbt_sc_command(struct drxk_state *state,
        if (status < 0)
                goto error;
 
-       /* Retreive results parameters from SC */
+       /* Retrieve results parameters from SC */
        switch (cmd) {
                /* All commands yielding 5 results */
                /* All commands yielding 4 results */
@@ -3849,7 +3849,7 @@ static int set_dvbt(struct drxk_state *state, u16 intermediate_freqk_hz,
                break;
        }
 #if 0
-       /* No hierachical channels support in BDA */
+       /* No hierarchical channels support in BDA */
        /* Priority (only for hierarchical channels) */
        switch (channel->priority) {
        case DRX_PRIORITY_LOW:
@@ -4081,7 +4081,7 @@ error:
 /*============================================================================*/
 
 /**
-* \brief Retreive lock status .
+* \brief Retrieve lock status .
 * \param demod    Pointer to demodulator instance.
 * \param lockStat Pointer to lock status structure.
 * \return DRXStatus_t.
@@ -6174,7 +6174,7 @@ static int init_drxk(struct drxk_state *state)
                        goto error;
 
                /* Stamp driver version number in SCU data RAM in BCD code
-                       Done to enable field application engineers to retreive drxdriver version
+                       Done to enable field application engineers to retrieve drxdriver version
                        via I2C from SCU RAM.
                        Not using SCU command interface for SCU register access since no
                        microcode may be present.
@@ -6399,7 +6399,7 @@ static int drxk_set_parameters(struct dvb_frontend *fe)
        fe->ops.tuner_ops.get_if_frequency(fe, &IF);
        start(state, 0, IF);
 
-       /* After set_frontend, stats aren't avaliable */
+       /* After set_frontend, stats aren't available */
        p->strength.stat[0].scale = FE_SCALE_RELATIVE;
        p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
        p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
index 7efb796c472c475bed62f1a0bb783f5b991a5b1e..50e8b63e5169bad938b1fc8b79e0871a619364d3 100644 (file)
@@ -710,6 +710,7 @@ struct dvb_frontend *rtl2830_attach(const struct rtl2830_config *cfg,
                sizeof(priv->tuner_i2c_adapter.name));
        priv->tuner_i2c_adapter.algo = &rtl2830_tuner_i2c_algo;
        priv->tuner_i2c_adapter.algo_data = NULL;
+       priv->tuner_i2c_adapter.dev.parent = &i2c->dev;
        i2c_set_adapdata(&priv->tuner_i2c_adapter, priv);
        if (i2c_add_adapter(&priv->tuner_i2c_adapter) < 0) {
                dev_err(&i2c->dev,
index 4a5b7d211d2f14e3810111a7f6399405e5000935..b253d400e8176a8baa3d1ba6928a1911d74bdb9d 100644 (file)
@@ -52,9 +52,9 @@
 #define ADV7183_VS_FIELD_CTRL_1    0x31 /* Vsync field control 1 */
 #define ADV7183_VS_FIELD_CTRL_2    0x32 /* Vsync field control 2 */
 #define ADV7183_VS_FIELD_CTRL_3    0x33 /* Vsync field control 3 */
-#define ADV7183_HS_POS_CTRL_1      0x34 /* Hsync positon control 1 */
-#define ADV7183_HS_POS_CTRL_2      0x35 /* Hsync positon control 2 */
-#define ADV7183_HS_POS_CTRL_3      0x36 /* Hsync positon control 3 */
+#define ADV7183_HS_POS_CTRL_1      0x34 /* Hsync position control 1 */
+#define ADV7183_HS_POS_CTRL_2      0x35 /* Hsync position control 2 */
+#define ADV7183_HS_POS_CTRL_3      0x36 /* Hsync position control 3 */
 #define ADV7183_POLARITY           0x37 /* Polarity */
 #define ADV7183_NTSC_COMB_CTRL     0x38 /* NTSC comb control */
 #define ADV7183_PAL_COMB_CTRL      0x39 /* PAL comb control */
index fbfdd2fc2a367f5b48c67fc41785395508fc473d..a324106b9f11e985c0637c16578cd3922ee6f58b 100644 (file)
@@ -877,7 +877,7 @@ static void configure_custom_video_timings(struct v4l2_subdev *sd,
                break;
        case ADV7604_MODE_HDMI:
                /* set default prim_mode/vid_std for HDMI
-                  accoring to [REF_03, c. 4.2] */
+                  according to [REF_03, c. 4.2] */
                io_write(sd, 0x00, 0x02); /* video std */
                io_write(sd, 0x01, 0x06); /* prim mode */
                break;
index 22f729d66a9696522e18d42932ae383594cbca5f..b154f36740b49151e2b1e0daeaf307c53032f3e7 100644 (file)
@@ -1013,7 +1013,7 @@ static void configure_custom_video_timings(struct v4l2_subdev *sd,
                break;
        case ADV7842_MODE_HDMI:
                /* set default prim_mode/vid_std for HDMI
-                  accoring to [REF_03, c. 4.2] */
+                  according to [REF_03, c. 4.2] */
                io_write(sd, 0x00, 0x02); /* video std */
                io_write(sd, 0x01, 0x06); /* prim mode */
                break;
index 82bf5679da3064d5a8ffd9da91c3d9e085d8d8bb..99ee456700f4972ef53888d692aa5f4b19930bce 100644 (file)
@@ -394,7 +394,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
 
        if (!rc) {
                /*
-                * If platform_data doesn't specify rc_dev, initilize it
+                * If platform_data doesn't specify rc_dev, initialize it
                 * internally
                 */
                rc = rc_allocate_device();
index f34429e452abf4e01dfd71d38ceb690d3c5ab021..a60931e66312e1ff3818ff363c0edd920c0d6c04 100644 (file)
@@ -544,7 +544,7 @@ int m5mols_init_controls(struct v4l2_subdev *sd)
        u16 zoom_step;
        int ret;
 
-       /* Determine the firmware dependant control range and step values */
+       /* Determine the firmware dependent control range and step values */
        ret = m5mols_read_u16(sd, AE_MAX_GAIN_MON, &exposure_max);
        if (ret < 0)
                return ret;
index 4734836fe5a410c8cf4249d9c455f5ceaf4b627c..1c2303d18bf49db242c00ac0cab8a474843c6db1 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/i2c.h>
 #include <linux/log2.h>
 #include <linux/module.h>
+#include <linux/of.h>
 #include <linux/of_gpio.h>
 #include <linux/pm.h>
 #include <linux/regulator/consumer.h>
index 6fec9384d86e4877d5b750a9f9a9ceec53e06bde..e7f555cc827abb4ddc1eba44bb1526e1d32576e4 100644 (file)
@@ -1460,7 +1460,7 @@ static int s5c73m3_oif_registered(struct v4l2_subdev *sd)
        mutex_unlock(&state->lock);
 
        v4l2_dbg(1, s5c73m3_dbg, sd, "%s: Booting %s (%d)\n",
-                __func__, ret ? "failed" : "succeded", ret);
+                __func__, ret ? "failed" : "succeeded", ret);
 
        return ret;
 }
index 9d2c0865224609504ab1a9b9302cb99d53086e85..9dfa516f694471660f9de431c948ae279ed07bb9 100644 (file)
@@ -393,7 +393,7 @@ struct s5c73m3 {
 
        /* External master clock frequency */
        u32 mclk_frequency;
-       /* Video bus type - MIPI-CSI2/paralell */
+       /* Video bus type - MIPI-CSI2/parallel */
        enum v4l2_mbus_type bus_type;
 
        const struct s5c73m3_frame_size *sensor_pix_size[2];
index 637d026345271c154f4af2da7a53bde6adbcae94..afdbcb045ceece64685db171dac9699d8a7dfc49 100644 (file)
@@ -1699,7 +1699,7 @@ static void saa711x_write_platform_data(struct saa711x_state *state,
  * the analog demod.
  * If the tuner is not found, it returns -ENODEV.
  * If auto-detection is disabled and the tuner doesn't match what it was
- *     requred, it returns -EINVAL and fills 'name'.
+ *     required, it returns -EINVAL and fills 'name'.
  * If the chip is found, it returns the chip ID and fills 'name'.
  */
 static int saa711x_detect_chip(struct i2c_client *client,
index 0a5c5d4fedd6e375b34a1848f3b646a6577bd97d..d2daa6a8f27245b88f69d832b2f2537ab716b0f9 100644 (file)
@@ -642,7 +642,7 @@ static const struct ov5642_datafmt
 static int reg_read(struct i2c_client *client, u16 reg, u8 *val)
 {
        int ret;
-       /* We have 16-bit i2c addresses - care for endianess */
+       /* We have 16-bit i2c addresses - care for endianness */
        unsigned char data[2] = { reg >> 8, reg & 0xff };
 
        ret = i2c_master_send(client, data, 2);
index 42276d93624cada191b30eb7e3ca7ad40fb923fa..ed9ae8875348b6abdd226e3026e4b1d6f117c12f 100644 (file)
@@ -83,7 +83,8 @@ static int ths7303_write(struct v4l2_subdev *sd, u8 reg, u8 val)
 }
 
 /* following function is used to set ths7303 */
-int ths7303_setval(struct v4l2_subdev *sd, enum ths7303_filter_mode mode)
+static int ths7303_setval(struct v4l2_subdev *sd,
+                         enum ths7303_filter_mode mode)
 {
        struct i2c_client *client = v4l2_get_subdevdata(sd);
        struct ths7303_state *state = to_state(sd);
index 3f584a7d0781b9860aad6b6bb9f6ddef4ad2b449..bee7946faa7cc2ba28a690e219cd0c5dcf89ff3b 100644 (file)
@@ -130,12 +130,10 @@ static int wm8775_s_routing(struct v4l2_subdev *sd,
                return -EINVAL;
        }
        state->input = input;
-       if (!v4l2_ctrl_g_ctrl(state->mute))
+       if (v4l2_ctrl_g_ctrl(state->mute))
                return 0;
        if (!v4l2_ctrl_g_ctrl(state->vol))
                return 0;
-       if (!v4l2_ctrl_g_ctrl(state->bal))
-               return 0;
        wm8775_set_audio(sd, 1);
        return 0;
 }
index a3b1ee9c00d7152405e9ea0e71549f350194692e..92a06fd858652acddff2dd65ce07dee560445df1 100644 (file)
@@ -4182,7 +4182,8 @@ static int bttv_probe(struct pci_dev *dev, const struct pci_device_id *pci_id)
        }
        btv->std = V4L2_STD_PAL;
        init_irqreg(btv);
-       v4l2_ctrl_handler_setup(hdl);
+       if (!bttv_tvcards[btv->c.type].no_video)
+               v4l2_ctrl_handler_setup(hdl);
        if (hdl->error) {
                result = hdl->error;
                goto fail2;
index 2767c64df0c87f9c044aca755a63fbfd0c75adf3..57f4688ea55bdf2488eb14dc523d4a4c542a2609 100644 (file)
@@ -262,7 +262,7 @@ struct cx18_options {
 };
 
 /* per-mdl bit flags */
-#define CX18_F_M_NEED_SWAP  0  /* mdl buffer data must be endianess swapped */
+#define CX18_F_M_NEED_SWAP  0  /* mdl buffer data must be endianness swapped */
 
 /* per-stream, s_flags */
 #define CX18_F_S_CLAIMED       3       /* this stream is claimed */
index e3fc2c71808abbd0746cc7d9faabdfc14b9c583f..95666eee7b277026f3c1154a78361212653130b9 100644 (file)
@@ -427,7 +427,7 @@ int mc417_register_read(struct cx23885_dev *dev, u16 address, u32 *value)
        cx_write(MC417_RWD, regval);
 
        /* Transition RD to effect read transaction across bus.
-        * Transtion 0x5000 -> 0x9000 correct (RD/RDY -> WR/RDY)?
+        * Transition 0x5000 -> 0x9000 correct (RD/RDY -> WR/RDY)?
         * Should it be 0x9000 -> 0xF000 (also why is RDY being set, its
         * input only...)
         */
index 8164d74b46a4590af0db79f56bd8c41bacead624..655d6854a8d7fa165502c711bf6c83a017cc16be 100644 (file)
@@ -401,7 +401,7 @@ static int pluto_hw_init(struct pluto *pluto)
        /* set automatic LED control by FPGA */
        pluto_rw(pluto, REG_MISC, MISC_ALED, MISC_ALED);
 
-       /* set data endianess */
+       /* set data endianness */
 #ifdef __LITTLE_ENDIAN
        pluto_rw(pluto, REG_PIDn(0), PID0_END, PID0_END);
 #else
index 57ef5456f1e87e9cc042ec8dc05cdb07192bc15d..1bf06970ca3e8e180cb6a2f20d732c983af820b2 100644 (file)
@@ -1354,9 +1354,11 @@ static int saa7164_initdev(struct pci_dev *pci_dev,
                if (fw_debug) {
                        dev->kthread = kthread_run(saa7164_thread_function, dev,
                                "saa7164 debug");
-                       if (!dev->kthread)
+                       if (IS_ERR(dev->kthread)) {
+                               dev->kthread = NULL;
                                printk(KERN_ERR "%s() Failed to create "
                                        "debug kernel thread\n", __func__);
+                       }
                }
 
        } /* != BOARD_UNKNOWN */
index bd72fb97fea5ab05924c4eeb4f5452534f3c3f46..61f3dbcc259f40f8a0f6f2b4bfa9b52ed6bf24ee 100644 (file)
@@ -1434,7 +1434,7 @@ static void coda_buf_queue(struct vb2_buffer *vb)
        if (q_data->fourcc == V4L2_PIX_FMT_H264 &&
            vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
                /*
-                * For backwards compatiblity, queuing an empty buffer marks
+                * For backwards compatibility, queuing an empty buffer marks
                 * the stream end
                 */
                if (vb2_get_plane_payload(vb, 0) == 0)
index 3d66d88ea3a191911ce72a22a8198602d7640e35..f7915695c9073d37ca10da947c29891b8d0e45d5 100644 (file)
@@ -1039,7 +1039,7 @@ static int fimc_runtime_resume(struct device *dev)
 
        dbg("fimc%d: state: 0x%lx", fimc->id, fimc->state);
 
-       /* Enable clocks and perform basic initalization */
+       /* Enable clocks and perform basic initialization */
        clk_enable(fimc->clock[CLK_GATE]);
        fimc_hw_reset(fimc);
 
index 7a4ee4c0449deea95dc86e82a85af8412a1d5aad..c1bce170df6fbce44d519a498bf6d19694389306 100644 (file)
@@ -759,7 +759,7 @@ static int fimc_md_register_platform_entity(struct fimc_md *fmd,
                goto dev_unlock;
 
        drvdata = dev_get_drvdata(dev);
-       /* Some subdev didn't probe succesfully id drvdata is NULL */
+       /* Some subdev didn't probe successfully id drvdata is NULL */
        if (drvdata) {
                switch (plat_entity) {
                case IDX_FIMC:
index 3458fa0e2fd537916270fd9fbb0908d2b1610821..054507f16734de8c04c67fbda15d9afff60d6f11 100644 (file)
@@ -142,12 +142,6 @@ static int mmpcam_power_up(struct mcam_camera *mcam)
        struct mmp_camera *cam = mcam_to_cam(mcam);
        struct mmp_camera_platform_data *pdata;
 
-       if (mcam->bus_type == V4L2_MBUS_CSI2) {
-               cam->mipi_clk = devm_clk_get(mcam->dev, "mipi");
-               if ((IS_ERR(cam->mipi_clk) && mcam->dphy[2] == 0))
-                       return PTR_ERR(cam->mipi_clk);
-       }
-
 /*
  * Turn on power and clocks to the controller.
  */
@@ -186,12 +180,6 @@ static void mmpcam_power_down(struct mcam_camera *mcam)
        gpio_set_value(pdata->sensor_power_gpio, 0);
        gpio_set_value(pdata->sensor_reset_gpio, 0);
 
-       if (mcam->bus_type == V4L2_MBUS_CSI2 && !IS_ERR(cam->mipi_clk)) {
-               if (cam->mipi_clk)
-                       devm_clk_put(mcam->dev, cam->mipi_clk);
-               cam->mipi_clk = NULL;
-       }
-
        mcam_clk_disable(mcam);
 }
 
@@ -292,8 +280,9 @@ void mmpcam_calc_dphy(struct mcam_camera *mcam)
                return;
 
        /* get the escape clk, this is hard coded */
+       clk_prepare_enable(cam->mipi_clk);
        tx_clk_esc = (clk_get_rate(cam->mipi_clk) / 1000000) / 12;
-
+       clk_disable_unprepare(cam->mipi_clk);
        /*
         * dphy[2] - CSI2_DPHY6:
         * bit 0 ~ bit 7: CK Term Enable
@@ -325,19 +314,6 @@ static irqreturn_t mmpcam_irq(int irq, void *data)
        return IRQ_RETVAL(handled);
 }
 
-static void mcam_deinit_clk(struct mcam_camera *mcam)
-{
-       unsigned int i;
-
-       for (i = 0; i < NR_MCAM_CLK; i++) {
-               if (!IS_ERR(mcam->clk[i])) {
-                       if (mcam->clk[i])
-                               devm_clk_put(mcam->dev, mcam->clk[i]);
-               }
-               mcam->clk[i] = NULL;
-       }
-}
-
 static void mcam_init_clk(struct mcam_camera *mcam)
 {
        unsigned int i;
@@ -371,7 +347,6 @@ static int mmpcam_probe(struct platform_device *pdev)
        if (cam == NULL)
                return -ENOMEM;
        cam->pdev = pdev;
-       cam->mipi_clk = NULL;
        INIT_LIST_HEAD(&cam->devlist);
 
        mcam = &cam->mcam;
@@ -387,6 +362,11 @@ static int mmpcam_probe(struct platform_device *pdev)
        mcam->mclk_div = pdata->mclk_div;
        mcam->bus_type = pdata->bus_type;
        mcam->dphy = pdata->dphy;
+       if (mcam->bus_type == V4L2_MBUS_CSI2) {
+               cam->mipi_clk = devm_clk_get(mcam->dev, "mipi");
+               if ((IS_ERR(cam->mipi_clk) && mcam->dphy[2] == 0))
+                       return PTR_ERR(cam->mipi_clk);
+       }
        mcam->mipi_enabled = false;
        mcam->lane = pdata->lane;
        mcam->chip_id = MCAM_ARMADA610;
@@ -444,7 +424,7 @@ static int mmpcam_probe(struct platform_device *pdev)
         */
        ret = mmpcam_power_up(mcam);
        if (ret)
-               goto out_deinit_clk;
+               return ret;
        ret = mccic_register(mcam);
        if (ret)
                goto out_power_down;
@@ -469,8 +449,6 @@ out_unregister:
        mccic_shutdown(mcam);
 out_power_down:
        mmpcam_power_down(mcam);
-out_deinit_clk:
-       mcam_deinit_clk(mcam);
        return ret;
 }
 
@@ -478,18 +456,10 @@ out_deinit_clk:
 static int mmpcam_remove(struct mmp_camera *cam)
 {
        struct mcam_camera *mcam = &cam->mcam;
-       struct mmp_camera_platform_data *pdata;
 
        mmpcam_remove_device(cam);
        mccic_shutdown(mcam);
        mmpcam_power_down(mcam);
-       pdata = cam->pdev->dev.platform_data;
-       gpio_free(pdata->sensor_reset_gpio);
-       gpio_free(pdata->sensor_power_gpio);
-       mcam_deinit_clk(mcam);
-       iounmap(cam->power_regs);
-       iounmap(mcam->regs);
-       kfree(cam);
        return 0;
 }
 
index 1c3608039663e281d23541f17aedcbce044c87fb..561bce8ffb1b57c87dd1b45bbae6cbf7c2b479c1 100644 (file)
@@ -1673,7 +1673,7 @@ void omap3isp_print_status(struct isp_device *isp)
  * ISP clocks get disabled in suspend(). Similarly, the clocks are reenabled in
  * resume(), and the the pipelines are restarted in complete().
  *
- * TODO: PM dependencies between the ISP and sensors are not modeled explicitly
+ * TODO: PM dependencies between the ISP and sensors are not modelled explicitly
  * yet.
  */
 static int isp_pm_prepare(struct device *dev)
index a908d006f5277c2abe9adebcbb757ea699495fbf..f6304bb074f5edaa598f959515394448d30a3cc9 100644 (file)
@@ -339,14 +339,11 @@ __isp_video_get_format(struct isp_video *video, struct v4l2_format *format)
        if (subdev == NULL)
                return -EINVAL;
 
-       mutex_lock(&video->mutex);
-
        fmt.pad = pad;
        fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
-       ret = v4l2_subdev_call(subdev, pad, get_fmt, NULL, &fmt);
-       if (ret == -ENOIOCTLCMD)
-               ret = -EINVAL;
 
+       mutex_lock(&video->mutex);
+       ret = v4l2_subdev_call(subdev, pad, get_fmt, NULL, &fmt);
        mutex_unlock(&video->mutex);
 
        if (ret)
index 9319e93599ae5731241b58535583bc1a04b77e73..6ccc3f8c122add705d7338d0656ac744331823fb 100644 (file)
 #define S5P_FIMV_R2H_CMD_EDFU_INIT_RET         16
 #define S5P_FIMV_R2H_CMD_ERR_RET               32
 
-/* Dummy definition for MFCv6 compatibilty */
+/* Dummy definition for MFCv6 compatibility */
 #define S5P_FIMV_CODEC_H264_MVC_DEC            -1
 #define S5P_FIMV_R2H_CMD_FIELD_DONE_RET                -1
 #define S5P_FIMV_MFC_RESET                     -1
index 5f2c4ad6c2cb3427835ed2f40ec9ba5432ae3221..e46067a5785307ac7a1381bd8a8babd8e4ec4fc2 100644 (file)
@@ -239,7 +239,7 @@ static void s5p_mfc_handle_frame_copy_time(struct s5p_mfc_ctx *ctx)
        frame_type = s5p_mfc_hw_call(dev->mfc_ops, get_dec_frame_type, dev);
 
        /* Copy timestamp / timecode from decoded src to dst and set
-          appropraite flags */
+          appropriate flags */
        src_buf = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);
        list_for_each_entry(dst_buf, &ctx->dst_queue, list) {
                if (vb2_dma_contig_plane_dma_addr(dst_buf->b, 0) == dec_y_addr) {
@@ -428,7 +428,7 @@ static void s5p_mfc_handle_error(struct s5p_mfc_dev *dev,
                case MFCINST_FINISHING:
                case MFCINST_FINISHED:
                case MFCINST_RUNNING:
-                       /* It is higly probable that an error occured
+                       /* It is highly probable that an error occurred
                         * while decoding a frame */
                        clear_work_bit(ctx);
                        ctx->state = MFCINST_ERROR;
@@ -611,7 +611,7 @@ static irqreturn_t s5p_mfc_irq(int irq, void *priv)
        mfc_debug(1, "Int reason: %d (err: %08x)\n", reason, err);
        switch (reason) {
        case S5P_MFC_R2H_CMD_ERR_RET:
-               /* An error has occured */
+               /* An error has occurred */
                if (ctx->state == MFCINST_RUNNING &&
                        s5p_mfc_hw_call(dev->mfc_ops, err_dec, err) >=
                                dev->warn_start)
@@ -840,7 +840,7 @@ static int s5p_mfc_open(struct file *file)
        mutex_unlock(&dev->mfc_mutex);
        mfc_debug_leave();
        return ret;
-       /* Deinit when failure occured */
+       /* Deinit when failure occurred */
 err_queue_init:
        if (dev->num_inst == 1)
                s5p_mfc_deinit_hw(dev);
@@ -881,14 +881,14 @@ static int s5p_mfc_release(struct file *file)
        /* Mark context as idle */
        clear_work_bit_irqsave(ctx);
        /* If instance was initialised then
-        * return instance and free reosurces */
+        * return instance and free resources */
        if (ctx->inst_no != MFC_NO_INSTANCE_SET) {
                mfc_debug(2, "Has to free instance\n");
                ctx->state = MFCINST_RETURN_INST;
                set_work_bit_irqsave(ctx);
                s5p_mfc_clean_ctx_int_flags(ctx);
                s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
-               /* Wait until instance is returned or timeout occured */
+               /* Wait until instance is returned or timeout occurred */
                if (s5p_mfc_wait_for_done_ctx
                    (ctx, S5P_MFC_R2H_CMD_CLOSE_INSTANCE_RET, 0)) {
                        s5p_mfc_clock_off();
index 7cab6849fb5b73d9463c591b4b24eaffcae48bae..2475a3c9a0a62ab27330a347865530466d209e0d 100644 (file)
@@ -69,7 +69,7 @@ int s5p_mfc_alloc_firmware(struct s5p_mfc_dev *dev)
 
        } else {
                /* In this case bank2 can point to the same address as bank1.
-                * Firmware will always occupy the beggining of this area so it is
+                * Firmware will always occupy the beginning of this area so it is
                 * impossible having a video frame buffer with zero address. */
                dev->bank2 = dev->bank1;
        }
index 04e6490a45befbae453d55ef0a86be0bb32497d2..fb2acc53112a47201be7ec785057cdb491eabffc 100644 (file)
@@ -65,7 +65,7 @@ struct mxr_format {
        int num_subframes;
        /** specifies to which subframe belong given plane */
        int plane2subframe[MXR_MAX_PLANES];
-       /** internal code, driver dependant */
+       /** internal code, driver dependent */
        unsigned long cookie;
 };
 
index 641b1f071e06a2b74796f030ddfdcdc80644179b..81b97db111d8506a1c28df84a86ce4181f6ddccb 100644 (file)
@@ -528,7 +528,7 @@ static int mxr_s_dv_timings(struct file *file, void *fh,
        mutex_lock(&mdev->mutex);
 
        /* timings change cannot be done while there is an entity
-        * dependant on output configuration
+        * dependent on output configuration
         */
        if (mdev->n_output > 0) {
                mutex_unlock(&mdev->mutex);
@@ -585,7 +585,7 @@ static int mxr_s_std(struct file *file, void *fh, v4l2_std_id norm)
        mutex_lock(&mdev->mutex);
 
        /* standard change cannot be done while there is an entity
-        * dependant on output configuration
+        * dependent on output configuration
         */
        if (mdev->n_output > 0) {
                mutex_unlock(&mdev->mutex);
index 6769193c7c7bbeef27f723e98760f73ece8d0219..74ce8b6b79fa91c80644e0646996397befd325cc 100644 (file)
@@ -1495,7 +1495,7 @@ static int omap1_cam_set_bus_param(struct soc_camera_device *icd)
        if (ctrlclock & LCLK_EN)
                CAM_WRITE(pcdev, CTRLCLOCK, ctrlclock);
 
-       /* select bus endianess */
+       /* select bus endianness */
        xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
        fmt = xlate->host_fmt;
 
index 1d3f1196519669cca0509c1972bdb320d2d35ad1..2d4e73b45c5e3b05d7e4615f6f6fd0d46bd56656 100644 (file)
@@ -1108,7 +1108,7 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
        return 0;
 }
 
-/* timeperframe is arbitrary and continous */
+/* timeperframe is arbitrary and continuous */
 static int vidioc_enum_frameintervals(struct file *file, void *priv,
                                             struct v4l2_frmivalenum *fival)
 {
@@ -1125,7 +1125,7 @@ static int vidioc_enum_frameintervals(struct file *file, void *priv,
 
        fival->type = V4L2_FRMIVAL_TYPE_CONTINUOUS;
 
-       /* fill in stepwise (step=1.0 is requred by V4L2 spec) */
+       /* fill in stepwise (step=1.0 is required by V4L2 spec) */
        fival->stepwise.min  = tpf_min;
        fival->stepwise.max  = tpf_max;
        fival->stepwise.step = (struct v4l2_fract) {1, 1};
index 1c9e771aa15c7bb40b5a8a1de25d66b2b108c528..d16bf0f41e247bd69e3af1ebdc31e0309861e0fd 100644 (file)
@@ -323,7 +323,7 @@ static void vsp1_clocks_disable(struct vsp1_device *vsp1)
  * Increment the VSP1 reference count and initialize the device if the first
  * reference is taken.
  *
- * Return a pointer to the VSP1 device or NULL if an error occured.
+ * Return a pointer to the VSP1 device or NULL if an error occurred.
  */
 struct vsp1_device *vsp1_device_get(struct vsp1_device *vsp1)
 {
index 714c53ef6c11b19d48304405f363f750b26547d2..4b0ac07af662c2bca05c6534ecb52bfc15730c74 100644 (file)
@@ -1026,8 +1026,10 @@ int vsp1_video_init(struct vsp1_video *video, struct vsp1_entity *rwpf)
 
        /* ... and the buffers queue... */
        video->alloc_ctx = vb2_dma_contig_init_ctx(video->vsp1->dev);
-       if (IS_ERR(video->alloc_ctx))
+       if (IS_ERR(video->alloc_ctx)) {
+               ret = PTR_ERR(video->alloc_ctx);
                goto error;
+       }
 
        video->queue.type = video->type;
        video->queue.io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
index 3db8a8cfe1a87f4eb80e9c22950bbcac93b7daed..050b3bb96fecc13a15f05d3f294147200954e8dd 100644 (file)
@@ -271,8 +271,7 @@ static void shark_unregister_leds(struct shark_device *shark)
        cancel_work_sync(&shark->led_work);
 }
 
-#ifdef CONFIG_PM
-static void shark_resume_leds(struct shark_device *shark)
+static inline void shark_resume_leds(struct shark_device *shark)
 {
        if (test_bit(BLUE_IS_PULSE, &shark->brightness_new))
                set_bit(BLUE_PULSE_LED, &shark->brightness_new);
@@ -281,7 +280,6 @@ static void shark_resume_leds(struct shark_device *shark)
        set_bit(RED_LED, &shark->brightness_new);
        schedule_work(&shark->led_work);
 }
-#endif
 #else
 static int shark_register_leds(struct shark_device *shark, struct device *dev)
 {
index d86d90dab8bf880666a05ca0463aa83fc62f77de..8654e0dc5c95376aa7140498e10af342b955d15a 100644 (file)
@@ -237,8 +237,7 @@ static void shark_unregister_leds(struct shark_device *shark)
        cancel_work_sync(&shark->led_work);
 }
 
-#ifdef CONFIG_PM
-static void shark_resume_leds(struct shark_device *shark)
+static inline void shark_resume_leds(struct shark_device *shark)
 {
        int i;
 
@@ -247,7 +246,6 @@ static void shark_resume_leds(struct shark_device *shark)
 
        schedule_work(&shark->led_work);
 }
-#endif
 #else
 static int shark_register_leds(struct shark_device *shark, struct device *dev)
 {
index 9c9084cb99f7dd1fde0800f0325c58584edd9e19..2fd9009f86633e74b4752472f5db2829daf6d9ce 100644 (file)
@@ -268,8 +268,8 @@ struct si476x_radio;
  *
  * @tune_freq: Tune chip to a specific frequency
  * @seek_start: Star station seeking
- * @rsq_status: Get Recieved Signal Quality(RSQ) status
- * @rds_blckcnt: Get recived RDS blocks count
+ * @rsq_status: Get Received Signal Quality(RSQ) status
+ * @rds_blckcnt: Get received RDS blocks count
  * @phase_diversity: Change phase diversity mode of the tuner
  * @phase_div_status: Get phase diversity mode status
  * @acf_status: Get the status of Automatically Controlled
index 036e2f54f4db4b1bc5c6f574e19ccde1960da9b5..3ed1f5669f791b9d3015bb91efd80ba2fa82d0c0 100644 (file)
@@ -356,7 +356,7 @@ static int vidioc_s_frequency(struct file *file, void *priv,
                   So we keep it as-is. */
                return -EINVAL;
        }
-       clamp(freq, FREQ_MIN * FREQ_MUL, FREQ_MAX * FREQ_MUL);
+       freq = clamp(freq, FREQ_MIN * FREQ_MUL, FREQ_MAX * FREQ_MUL);
        tea5764_power_up(radio);
        tea5764_tune(radio, (freq * 125) / 2);
        return 0;
index 69e3245a58a0cbfcc1d333d390a30aa45e4c70d8..a9319a24c7efe1290efbc5b309bb719584cf7b5f 100644 (file)
@@ -112,7 +112,7 @@ static int tef6862_s_frequency(struct v4l2_subdev *sd, const struct v4l2_frequen
        if (f->tuner != 0)
                return -EINVAL;
 
-       clamp(freq, TEF6862_LO_FREQ, TEF6862_HI_FREQ);
+       freq = clamp(freq, TEF6862_LO_FREQ, TEF6862_HI_FREQ);
        pll = 1964 + ((freq - TEF6862_LO_FREQ) * 20) / FREQ_MUL;
        i2cmsg[0] = (MSA_MODE_PRESET << MSA_MODE_SHIFT) | WM_SUB_PLLM;
        i2cmsg[1] = (pll >> 8) & 0xff;
index 72e3fa652481671cff04e2c06a1478d21fb0ffb6..f329485c6629b038ff2aee825edff86c82189328 100644 (file)
@@ -1370,7 +1370,7 @@ static void imon_pad_to_keys(struct imon_context *ictx, unsigned char *buf)
         * 0x68nnnnB7 to 0x6AnnnnB7, the left mouse button generates
         * 0x688301b7 and the right one 0x688481b7. All other keys generate
         * 0x2nnnnnnn. Position coordinate is encoded in buf[1] and buf[2] with
-        * reversed endianess. Extract direction from buffer, rotate endianess,
+        * reversed endianness. Extract direction from buffer, rotate endianness,
         * adjust sign and feed the values into stabilize(). The resulting codes
         * will be 0x01008000, 0x01007F00, which match the newer devices.
         */
index 094484fac94cdbe52f7832f140f87895e922e631..a5d4f883d053a7b0ebca0543ac82d29d216ec26a 100644 (file)
@@ -118,7 +118,7 @@ static int debug;
 #define RR3_IR_IO_LENGTH_FUZZ  0x04
 /* Timeout for end of signal detection */
 #define RR3_IR_IO_SIG_TIMEOUT  0x05
-/* Minumum value for pause recognition. */
+/* Minimum value for pause recognition. */
 #define RR3_IR_IO_MIN_PAUSE    0x06
 
 /* Clock freq. of EZ-USB chip */
index 2e1a02e360ff0cd7279fed8ca20b80a3ee0b8ad8..20cca405bf452c46195ebbbadb37c8a535e85d0b 100644 (file)
@@ -1195,7 +1195,7 @@ static u32 mt2063_set_dnc_output_enable(struct mt2063_state *state,
  *   DNC Output is selected, the other is always off)
  *
  * @state:     ptr to mt2063_state structure
- * @Mode:      desired reciever delivery system
+ * @Mode:      desired receiver delivery system
  *
  * Note: Register cache must be valid for it to work
  */
@@ -2119,7 +2119,7 @@ static int mt2063_set_analog_params(struct dvb_frontend *fe,
 
 /*
  * As defined on EN 300 429, the DVB-C roll-off factor is 0.15.
- * So, the amount of the needed bandwith is given by:
+ * So, the amount of the needed bandwidth is given by:
  *     Bw = Symbol_rate * (1 + 0.15)
  * As such, the maximum symbol rate supported by 6 MHz is given by:
  *     max_symbol_rate = 6 MHz / 1.15 = 5217391 Bauds
index 74dc46a71f64555c07bb67be9ee09facf822ad41..7e4798783db733cc139e557444f12d4bddb820b5 100644 (file)
 #define V4L2_STD_A2            (V4L2_STD_A2_A    | V4L2_STD_A2_B)
 #define V4L2_STD_NICAM         (V4L2_STD_NICAM_A | V4L2_STD_NICAM_B)
 
-/* To preserve backward compatibilty,
+/* To preserve backward compatibility,
    (std & V4L2_STD_AUDIO) = 0 means that ALL audio stds are supported
  */
 
index e9d017bea377069da087751404e75f86b081c7cd..528cce958a82c4a67c91ea0c52841364db36f7d4 100644 (file)
@@ -1412,8 +1412,8 @@ err_v4l2:
        usb_set_intfdata(interface, NULL);
 err_if:
        usb_put_dev(udev);
-       kfree(dev);
        clear_bit(dev->devno, &cx231xx_devused);
+       kfree(dev);
        return retval;
 }
 
index c8fcd78425bd228ca4374daf94fdbf4ed1c0c17a..8f9b2cea88f009ec316fb1b97cbbfa67984fcda0 100644 (file)
@@ -131,7 +131,7 @@ static int af9035_wr_regs(struct dvb_usb_device *d, u32 reg, u8 *val, int len)
 {
        u8 wbuf[MAX_XFER_SIZE];
        u8 mbox = (reg >> 16) & 0xff;
-       struct usb_req req = { CMD_MEM_WR, mbox, sizeof(wbuf), wbuf, 0, NULL };
+       struct usb_req req = { CMD_MEM_WR, mbox, 6 + len, wbuf, 0, NULL };
 
        if (6 + len > sizeof(wbuf)) {
                dev_warn(&d->udev->dev, "%s: i2c wr: len=%d is too big!\n",
@@ -238,14 +238,15 @@ static int af9035_i2c_master_xfer(struct i2c_adapter *adap,
                } else {
                        /* I2C */
                        u8 buf[MAX_XFER_SIZE];
-                       struct usb_req req = { CMD_I2C_RD, 0, sizeof(buf),
+                       struct usb_req req = { CMD_I2C_RD, 0, 5 + msg[0].len,
                                        buf, msg[1].len, msg[1].buf };
 
                        if (5 + msg[0].len > sizeof(buf)) {
                                dev_warn(&d->udev->dev,
                                         "%s: i2c xfer: len=%d is too big!\n",
                                         KBUILD_MODNAME, msg[0].len);
-                               return -EOPNOTSUPP;
+                               ret = -EOPNOTSUPP;
+                               goto unlock;
                        }
                        req.mbox |= ((msg[0].addr & 0x80)  >>  3);
                        buf[0] = msg[1].len;
@@ -274,14 +275,15 @@ static int af9035_i2c_master_xfer(struct i2c_adapter *adap,
                } else {
                        /* I2C */
                        u8 buf[MAX_XFER_SIZE];
-                       struct usb_req req = { CMD_I2C_WR, 0, sizeof(buf), buf,
-                                       0, NULL };
+                       struct usb_req req = { CMD_I2C_WR, 0, 5 + msg[0].len,
+                                       buf, 0, NULL };
 
                        if (5 + msg[0].len > sizeof(buf)) {
                                dev_warn(&d->udev->dev,
                                         "%s: i2c xfer: len=%d is too big!\n",
                                         KBUILD_MODNAME, msg[0].len);
-                               return -EOPNOTSUPP;
+                               ret = -EOPNOTSUPP;
+                               goto unlock;
                        }
                        req.mbox |= ((msg[0].addr & 0x80)  >>  3);
                        buf[0] = msg[0].len;
@@ -319,6 +321,7 @@ static int af9035_i2c_master_xfer(struct i2c_adapter *adap,
                ret = -EOPNOTSUPP;
        }
 
+unlock:
        mutex_unlock(&d->i2c_mutex);
 
        if (ret < 0)
@@ -1534,6 +1537,8 @@ static const struct usb_device_id af9035_id_table[] = {
        /* XXX: that same ID [0ccd:0099] is used by af9015 driver too */
        { DVB_USB_DEVICE(USB_VID_TERRATEC, 0x0099,
                &af9035_props, "TerraTec Cinergy T Stick Dual RC (rev. 2)", NULL) },
+       { DVB_USB_DEVICE(USB_VID_LEADTEK, 0x6a05,
+               &af9035_props, "Leadtek WinFast DTV Dongle Dual", NULL) },
        { }
 };
 MODULE_DEVICE_TABLE(usb, af9035_id_table);
index 2627553f7de1f90c262f2d234d1d1faa9288f45f..08240e498451a55810e4bd00a75df73d0c1a607e 100644 (file)
@@ -266,7 +266,7 @@ static int mxl111sf_adap_fe_init(struct dvb_frontend *fe)
        struct mxl111sf_adap_state *adap_state = &state->adap_state[fe->id];
        int err;
 
-       /* exit if we didnt initialize the driver yet */
+       /* exit if we didn't initialize the driver yet */
        if (!state->chip_id) {
                mxl_debug("driver not yet initialized, exit.");
                goto fail;
@@ -322,7 +322,7 @@ static int mxl111sf_adap_fe_sleep(struct dvb_frontend *fe)
        struct mxl111sf_adap_state *adap_state = &state->adap_state[fe->id];
        int err;
 
-       /* exit if we didnt initialize the driver yet */
+       /* exit if we didn't initialize the driver yet */
        if (!state->chip_id) {
                mxl_debug("driver not yet initialized, exit.");
                goto fail;
index 40832a1aef6c71c0df2eaf51ffdea327bafe18da..98d24aefb640f80e12d6dd720f872273c71e6276 100644 (file)
@@ -102,7 +102,7 @@ static int technisat_usb2_i2c_access(struct usb_device *udev,
        if (rxlen > 62) {
                err("i2c RX buffer can't exceed 62 bytes (dev 0x%02x)",
                                device_addr);
-               txlen = 62;
+               rxlen = 62;
        }
 
        b[0] = I2C_SPEED_100KHZ_BIT;
index fc5d60efd4abe99f19acbafff7b83879da5ff3ac..dd19c9ff76e0f9a159c6630320814c89e9e83d5a 100644 (file)
@@ -1664,8 +1664,8 @@ static int em28xx_v4l2_close(struct file *filp)
 
        em28xx_videodbg("users=%d\n", dev->users);
 
-       mutex_lock(&dev->lock);
        vb2_fop_release(filp);
+       mutex_lock(&dev->lock);
 
        if (dev->users == 1) {
                /* the device is already disconnect,
index cb1e64ca59c9259b59ca1aaaaea036b6bd2c5fa0..cea8d7f51c3cc9430af956066d87b045b453c062 100644 (file)
@@ -438,7 +438,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
        s32 nToSkip =
                sd->swapRB * (gspca_dev->cam.cam_mode[mode].bytesperline + 1);
 
-       /* Test only against 0202h, so endianess does not matter */
+       /* Test only against 0202h, so endianness does not matter */
        switch (*(s16 *) data) {
        case 0x0202:            /* End of frame, start a new one */
                gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
index cd79c180f67b87e84689a8a162b4962bf5691cde..07529e5a0c5605186b3aa619b6b89d06cf98bc45 100644 (file)
@@ -416,7 +416,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 #if IS_ENABLED(CONFIG_INPUT)
 static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
                        u8 *data,               /* interrupt packet data */
-                       int len)                /* interrput packet length */
+                       int len)                /* interrupt packet length */
 {
        int ret = -EINVAL;
 
index a9150964356329d93ea136e151c0d7f0aebf8590..2fd1c5e31a0f2692a1d59dd88c72cbee74e61054 100644 (file)
@@ -874,7 +874,7 @@ static int sd_dbg_s_register(struct gspca_dev *gspca_dev,
 #if IS_ENABLED(CONFIG_INPUT)
 static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
                        u8 *data,               /* interrupt packet data */
-                       int len)                /* interrput packet length */
+                       int len)                /* interrupt packet length */
 {
        int ret = -EINVAL;
        u8 data0, data1;
index 1fc80af2a18907e57d54eac3f58481ada0f3cda7..48234c9a8b6c3e4b4b927eb654ddb0009aa3d8ba 100644 (file)
@@ -361,6 +361,9 @@ static void stk1135_configure_clock(struct gspca_dev *gspca_dev)
 
        /* set serial interface clock divider (30MHz/0x1f*16+2) = 60240 kHz) */
        reg_w(gspca_dev, STK1135_REG_SICTL + 2, 0x1f);
+
+       /* wait a while for sensor to catch up */
+       udelay(1000);
 }
 
 static void stk1135_camera_disable(struct gspca_dev *gspca_dev)
index 9c0827631b9c105658575ed52e754fd1efa0c740..7f94ec74282e3ea42b0c423130419b038a5e3edd 100644 (file)
@@ -139,7 +139,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
        struct sd *sd = (struct sd *) gspca_dev;
        struct cam *cam = &gspca_dev->cam;
 
-       /* Give the camera some time to settle, otherwise initalization will
+       /* Give the camera some time to settle, otherwise initialization will
           fail on hotplug, and yes it really needs a full second. */
        msleep(1000);
 
index a517d185febed4590bbb5f58306aa4e4a2c4f0f1..46c9f2229a18675c6a1ca39528dab2196937c0c5 100644 (file)
@@ -1027,6 +1027,7 @@ static const struct usb_device_id device_table[] = {
        {USB_DEVICE(0x055f, 0xc650), BS(SPCA533, 0)},
        {USB_DEVICE(0x05da, 0x1018), BS(SPCA504B, 0)},
        {USB_DEVICE(0x06d6, 0x0031), BS(SPCA533, 0)},
+       {USB_DEVICE(0x06d6, 0x0041), BS(SPCA504B, 0)},
        {USB_DEVICE(0x0733, 0x1311), BS(SPCA533, 0)},
        {USB_DEVICE(0x0733, 0x1314), BS(SPCA533, 0)},
        {USB_DEVICE(0x0733, 0x2211), BS(SPCA533, 0)},
index 7b95d8e88a20240305a8817b72c3459d80a5adc6..d3e1b6d8bf494f79d449c38c96be5d022ab61043 100644 (file)
@@ -6905,7 +6905,7 @@ static int sd_get_jcomp(struct gspca_dev *gspca_dev,
 #if IS_ENABLED(CONFIG_INPUT)
 static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
                        u8 *data,               /* interrupt packet data */
-                       int len)                /* interrput packet length */
+                       int len)                /* interrupt packet length */
 {
        if (len == 8 && data[4] == 1) {
                input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
index 77bbf788965953bbc67f8fa8b3ab18ccbe5806d8..78c9bc8e7f561744364a6de94f4aeaae382dd077 100644 (file)
@@ -1039,7 +1039,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
        /* Set the leds off */
        pwc_set_leds(pdev, 0, 0);
 
-       /* Setup intial videomode */
+       /* Setup initial videomode */
        rc = pwc_set_video_mode(pdev, MAX_WIDTH, MAX_HEIGHT,
                                V4L2_PIX_FMT_YUV420, 30, &compression, 1);
        if (rc)
index 8a505a90d3189a59876a916507ae50b6e11a0ed9..6222a4ab1e00bfff2d58d7816145bdae58fe4059 100644 (file)
 #define USBTV_ISOC_TRANSFERS   16
 #define USBTV_ISOC_PACKETS     8
 
-#define USBTV_WIDTH            720
-#define USBTV_HEIGHT           480
-
 #define USBTV_CHUNK_SIZE       256
 #define USBTV_CHUNK            240
-#define USBTV_CHUNKS           (USBTV_WIDTH * USBTV_HEIGHT \
-                                       / 4 / USBTV_CHUNK)
 
 /* Chunk header. */
 #define USBTV_MAGIC_OK(chunk)  ((be32_to_cpu(chunk[0]) & 0xff000000) \
 #define USBTV_ODD(chunk)       ((be32_to_cpu(chunk[0]) & 0x0000f000) >> 15)
 #define USBTV_CHUNK_NO(chunk)  (be32_to_cpu(chunk[0]) & 0x00000fff)
 
+#define USBTV_TV_STD  (V4L2_STD_525_60 | V4L2_STD_PAL)
+
+/* parameters for supported TV norms */
+struct usbtv_norm_params {
+       v4l2_std_id norm;
+       int cap_width, cap_height;
+};
+
+static struct usbtv_norm_params norm_params[] = {
+       {
+               .norm = V4L2_STD_525_60,
+               .cap_width = 720,
+               .cap_height = 480,
+       },
+       {
+               .norm = V4L2_STD_PAL,
+               .cap_width = 720,
+               .cap_height = 576,
+       }
+};
+
 /* A single videobuf2 frame buffer. */
 struct usbtv_buf {
        struct vb2_buffer vb;
@@ -94,11 +110,38 @@ struct usbtv {
                USBTV_COMPOSITE_INPUT,
                USBTV_SVIDEO_INPUT,
        } input;
+       v4l2_std_id norm;
+       int width, height;
+       int n_chunks;
        int iso_size;
        unsigned int sequence;
        struct urb *isoc_urbs[USBTV_ISOC_TRANSFERS];
 };
 
+static int usbtv_configure_for_norm(struct usbtv *usbtv, v4l2_std_id norm)
+{
+       int i, ret = 0;
+       struct usbtv_norm_params *params = NULL;
+
+       for (i = 0; i < ARRAY_SIZE(norm_params); i++) {
+               if (norm_params[i].norm & norm) {
+                       params = &norm_params[i];
+                       break;
+               }
+       }
+
+       if (params) {
+               usbtv->width = params->cap_width;
+               usbtv->height = params->cap_height;
+               usbtv->n_chunks = usbtv->width * usbtv->height
+                                               / 4 / USBTV_CHUNK;
+               usbtv->norm = params->norm;
+       } else
+               ret = -EINVAL;
+
+       return ret;
+}
+
 static int usbtv_set_regs(struct usbtv *usbtv, const u16 regs[][2], int size)
 {
        int ret;
@@ -158,6 +201,57 @@ static int usbtv_select_input(struct usbtv *usbtv, int input)
        return ret;
 }
 
+static int usbtv_select_norm(struct usbtv *usbtv, v4l2_std_id norm)
+{
+       int ret;
+       static const u16 pal[][2] = {
+               { USBTV_BASE + 0x001a, 0x0068 },
+               { USBTV_BASE + 0x010e, 0x0072 },
+               { USBTV_BASE + 0x010f, 0x00a2 },
+               { USBTV_BASE + 0x0112, 0x00b0 },
+               { USBTV_BASE + 0x0117, 0x0001 },
+               { USBTV_BASE + 0x0118, 0x002c },
+               { USBTV_BASE + 0x012d, 0x0010 },
+               { USBTV_BASE + 0x012f, 0x0020 },
+               { USBTV_BASE + 0x024f, 0x0002 },
+               { USBTV_BASE + 0x0254, 0x0059 },
+               { USBTV_BASE + 0x025a, 0x0016 },
+               { USBTV_BASE + 0x025b, 0x0035 },
+               { USBTV_BASE + 0x0263, 0x0017 },
+               { USBTV_BASE + 0x0266, 0x0016 },
+               { USBTV_BASE + 0x0267, 0x0036 }
+       };
+
+       static const u16 ntsc[][2] = {
+               { USBTV_BASE + 0x001a, 0x0079 },
+               { USBTV_BASE + 0x010e, 0x0068 },
+               { USBTV_BASE + 0x010f, 0x009c },
+               { USBTV_BASE + 0x0112, 0x00f0 },
+               { USBTV_BASE + 0x0117, 0x0000 },
+               { USBTV_BASE + 0x0118, 0x00fc },
+               { USBTV_BASE + 0x012d, 0x0004 },
+               { USBTV_BASE + 0x012f, 0x0008 },
+               { USBTV_BASE + 0x024f, 0x0001 },
+               { USBTV_BASE + 0x0254, 0x005f },
+               { USBTV_BASE + 0x025a, 0x0012 },
+               { USBTV_BASE + 0x025b, 0x0001 },
+               { USBTV_BASE + 0x0263, 0x001c },
+               { USBTV_BASE + 0x0266, 0x0011 },
+               { USBTV_BASE + 0x0267, 0x0005 }
+       };
+
+       ret = usbtv_configure_for_norm(usbtv, norm);
+
+       if (!ret) {
+               if (norm & V4L2_STD_525_60)
+                       ret = usbtv_set_regs(usbtv, ntsc, ARRAY_SIZE(ntsc));
+               else if (norm & V4L2_STD_PAL)
+                       ret = usbtv_set_regs(usbtv, pal, ARRAY_SIZE(pal));
+       }
+
+       return ret;
+}
+
 static int usbtv_setup_capture(struct usbtv *usbtv)
 {
        int ret;
@@ -225,26 +319,11 @@ static int usbtv_setup_capture(struct usbtv *usbtv)
 
                { USBTV_BASE + 0x0284, 0x0088 },
                { USBTV_BASE + 0x0003, 0x0004 },
-               { USBTV_BASE + 0x001a, 0x0079 },
                { USBTV_BASE + 0x0100, 0x00d3 },
-               { USBTV_BASE + 0x010e, 0x0068 },
-               { USBTV_BASE + 0x010f, 0x009c },
-               { USBTV_BASE + 0x0112, 0x00f0 },
                { USBTV_BASE + 0x0115, 0x0015 },
-               { USBTV_BASE + 0x0117, 0x0000 },
-               { USBTV_BASE + 0x0118, 0x00fc },
-               { USBTV_BASE + 0x012d, 0x0004 },
-               { USBTV_BASE + 0x012f, 0x0008 },
                { USBTV_BASE + 0x0220, 0x002e },
                { USBTV_BASE + 0x0225, 0x0008 },
                { USBTV_BASE + 0x024e, 0x0002 },
-               { USBTV_BASE + 0x024f, 0x0001 },
-               { USBTV_BASE + 0x0254, 0x005f },
-               { USBTV_BASE + 0x025a, 0x0012 },
-               { USBTV_BASE + 0x025b, 0x0001 },
-               { USBTV_BASE + 0x0263, 0x001c },
-               { USBTV_BASE + 0x0266, 0x0011 },
-               { USBTV_BASE + 0x0267, 0x0005 },
                { USBTV_BASE + 0x024e, 0x0002 },
                { USBTV_BASE + 0x024f, 0x0002 },
        };
@@ -253,6 +332,10 @@ static int usbtv_setup_capture(struct usbtv *usbtv)
        if (ret)
                return ret;
 
+       ret = usbtv_select_norm(usbtv, usbtv->norm);
+       if (ret)
+               return ret;
+
        ret = usbtv_select_input(usbtv, usbtv->input);
        if (ret)
                return ret;
@@ -296,7 +379,7 @@ static void usbtv_image_chunk(struct usbtv *usbtv, u32 *chunk)
        frame_id = USBTV_FRAME_ID(chunk);
        odd = USBTV_ODD(chunk);
        chunk_no = USBTV_CHUNK_NO(chunk);
-       if (chunk_no >= USBTV_CHUNKS)
+       if (chunk_no >= usbtv->n_chunks)
                return;
 
        /* Beginning of a frame. */
@@ -324,10 +407,10 @@ static void usbtv_image_chunk(struct usbtv *usbtv, u32 *chunk)
        usbtv->chunks_done++;
 
        /* Last chunk in a frame, signalling an end */
-       if (odd && chunk_no == USBTV_CHUNKS-1) {
+       if (odd && chunk_no == usbtv->n_chunks-1) {
                int size = vb2_plane_size(&buf->vb, 0);
                enum vb2_buffer_state state = usbtv->chunks_done ==
-                                               USBTV_CHUNKS ?
+                                               usbtv->n_chunks ?
                                                VB2_BUF_STATE_DONE :
                                                VB2_BUF_STATE_ERROR;
 
@@ -500,6 +583,8 @@ static int usbtv_querycap(struct file *file, void *priv,
 static int usbtv_enum_input(struct file *file, void *priv,
                                        struct v4l2_input *i)
 {
+       struct usbtv *dev = video_drvdata(file);
+
        switch (i->index) {
        case USBTV_COMPOSITE_INPUT:
                strlcpy(i->name, "Composite", sizeof(i->name));
@@ -512,7 +597,7 @@ static int usbtv_enum_input(struct file *file, void *priv,
        }
 
        i->type = V4L2_INPUT_TYPE_CAMERA;
-       i->std = V4L2_STD_525_60;
+       i->std = dev->vdev.tvnorms;
        return 0;
 }
 
@@ -531,23 +616,37 @@ static int usbtv_enum_fmt_vid_cap(struct file *file, void  *priv,
 static int usbtv_fmt_vid_cap(struct file *file, void *priv,
                                        struct v4l2_format *f)
 {
-       f->fmt.pix.width = USBTV_WIDTH;
-       f->fmt.pix.height = USBTV_HEIGHT;
+       struct usbtv *usbtv = video_drvdata(file);
+
+       f->fmt.pix.width = usbtv->width;
+       f->fmt.pix.height = usbtv->height;
        f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
        f->fmt.pix.field = V4L2_FIELD_INTERLACED;
-       f->fmt.pix.bytesperline = USBTV_WIDTH * 2;
+       f->fmt.pix.bytesperline = usbtv->width * 2;
        f->fmt.pix.sizeimage = (f->fmt.pix.bytesperline * f->fmt.pix.height);
        f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
-       f->fmt.pix.priv = 0;
+
        return 0;
 }
 
 static int usbtv_g_std(struct file *file, void *priv, v4l2_std_id *norm)
 {
-       *norm = V4L2_STD_525_60;
+       struct usbtv *usbtv = video_drvdata(file);
+       *norm = usbtv->norm;
        return 0;
 }
 
+static int usbtv_s_std(struct file *file, void *priv, v4l2_std_id norm)
+{
+       int ret = -EINVAL;
+       struct usbtv *usbtv = video_drvdata(file);
+
+       if ((norm & V4L2_STD_525_60) || (norm & V4L2_STD_PAL))
+               ret = usbtv_select_norm(usbtv, norm);
+
+       return ret;
+}
+
 static int usbtv_g_input(struct file *file, void *priv, unsigned int *i)
 {
        struct usbtv *usbtv = video_drvdata(file);
@@ -561,13 +660,6 @@ static int usbtv_s_input(struct file *file, void *priv, unsigned int i)
        return usbtv_select_input(usbtv, i);
 }
 
-static int usbtv_s_std(struct file *file, void *priv, v4l2_std_id norm)
-{
-       if (norm & V4L2_STD_525_60)
-               return 0;
-       return -EINVAL;
-}
-
 struct v4l2_ioctl_ops usbtv_ioctl_ops = {
        .vidioc_querycap = usbtv_querycap,
        .vidioc_enum_input = usbtv_enum_input,
@@ -604,10 +696,12 @@ static int usbtv_queue_setup(struct vb2_queue *vq,
        const struct v4l2_format *v4l_fmt, unsigned int *nbuffers,
        unsigned int *nplanes, unsigned int sizes[], void *alloc_ctxs[])
 {
+       struct usbtv *usbtv = vb2_get_drv_priv(vq);
+
        if (*nbuffers < 2)
                *nbuffers = 2;
        *nplanes = 1;
-       sizes[0] = USBTV_WIDTH * USBTV_HEIGHT / 2 * sizeof(u32);
+       sizes[0] = USBTV_CHUNK * usbtv->n_chunks * 2 * sizeof(u32);
 
        return 0;
 }
@@ -690,7 +784,11 @@ static int usbtv_probe(struct usb_interface *intf,
                return -ENOMEM;
        usbtv->dev = dev;
        usbtv->udev = usb_get_dev(interface_to_usbdev(intf));
+
        usbtv->iso_size = size;
+
+       (void)usbtv_configure_for_norm(usbtv, V4L2_STD_525_60);
+
        spin_lock_init(&usbtv->buflock);
        mutex_init(&usbtv->v4l2_lock);
        mutex_init(&usbtv->vb2q_lock);
@@ -727,7 +825,7 @@ static int usbtv_probe(struct usb_interface *intf,
        usbtv->vdev.release = video_device_release_empty;
        usbtv->vdev.fops = &usbtv_fops;
        usbtv->vdev.ioctl_ops = &usbtv_ioctl_ops;
-       usbtv->vdev.tvnorms = V4L2_STD_525_60;
+       usbtv->vdev.tvnorms = USBTV_TV_STD;
        usbtv->vdev.queue = &usbtv->vb2q;
        usbtv->vdev.lock = &usbtv->v4l2_lock;
        set_bit(V4L2_FL_USE_FH_PRIO, &usbtv->vdev.flags);
index 899cb6d1c4a4a74a68cae01dbea51de5befc821e..898c208889cd2d55dd5a22522a2d06340eb0891d 100644 (file)
@@ -556,7 +556,7 @@ static u16 uvc_video_clock_host_sof(const struct uvc_clock_sample *sample)
  *
  * SOF = ((SOF2 - SOF1) * PTS + SOF1 * STC2 - SOF2 * STC1) / (STC2 - STC1)   (1)
  *
- * to avoid loosing precision in the division. Similarly, the host timestamp is
+ * to avoid losing precision in the division. Similarly, the host timestamp is
  * computed with
  *
  * TS = ((TS2 - TS1) * PTS + TS1 * SOF2 - TS2 * SOF1) / (SOF2 - SOF1)       (2)
index 60dcc0f3b32e7b445352b455d377f5b2b794b4fb..fb46790d0eca795d5e411c54bf7129d96e61d3e9 100644 (file)
@@ -420,7 +420,7 @@ const char * const *v4l2_ctrl_get_menu(u32 id)
                "Advanced Simple",
                "Core",
                "Simple Scalable",
-               "Advanced Coding Efficency",
+               "Advanced Coding Efficiency",
                NULL,
        };
 
index b19b306c8f7f533d3112db441f692e57bd76638d..0edc165f418d9449f46e5696e4e093e7b3288fd1 100644 (file)
@@ -144,6 +144,25 @@ static void __vb2_buf_dmabuf_put(struct vb2_buffer *vb)
                __vb2_plane_dmabuf_put(q, &vb->planes[plane]);
 }
 
+/**
+ * __setup_lengths() - setup initial lengths for every plane in
+ * every buffer on the queue
+ */
+static void __setup_lengths(struct vb2_queue *q, unsigned int n)
+{
+       unsigned int buffer, plane;
+       struct vb2_buffer *vb;
+
+       for (buffer = q->num_buffers; buffer < q->num_buffers + n; ++buffer) {
+               vb = q->bufs[buffer];
+               if (!vb)
+                       continue;
+
+               for (plane = 0; plane < vb->num_planes; ++plane)
+                       vb->v4l2_planes[plane].length = q->plane_sizes[plane];
+       }
+}
+
 /**
  * __setup_offsets() - setup unique offsets ("cookies") for every plane in
  * every buffer on the queue
@@ -169,7 +188,6 @@ static void __setup_offsets(struct vb2_queue *q, unsigned int n)
                        continue;
 
                for (plane = 0; plane < vb->num_planes; ++plane) {
-                       vb->v4l2_planes[plane].length = q->plane_sizes[plane];
                        vb->v4l2_planes[plane].m.mem_offset = off;
 
                        dprintk(3, "Buffer %d, plane %d offset 0x%08lx\n",
@@ -241,6 +259,7 @@ static int __vb2_queue_alloc(struct vb2_queue *q, enum v4l2_memory memory,
                q->bufs[q->num_buffers + buffer] = vb;
        }
 
+       __setup_lengths(q, buffer);
        if (memory == V4L2_MEMORY_MMAP)
                __setup_offsets(q, buffer);
 
@@ -1824,8 +1843,8 @@ int vb2_expbuf(struct vb2_queue *q, struct v4l2_exportbuffer *eb)
                return -EINVAL;
        }
 
-       if (eb->flags & ~O_CLOEXEC) {
-               dprintk(1, "Queue does support only O_CLOEXEC flag\n");
+       if (eb->flags & ~(O_CLOEXEC | O_ACCMODE)) {
+               dprintk(1, "Queue does support only O_CLOEXEC and access mode flags\n");
                return -EINVAL;
        }
 
@@ -1848,14 +1867,14 @@ int vb2_expbuf(struct vb2_queue *q, struct v4l2_exportbuffer *eb)
 
        vb_plane = &vb->planes[eb->plane];
 
-       dbuf = call_memop(q, get_dmabuf, vb_plane->mem_priv);
+       dbuf = call_memop(q, get_dmabuf, vb_plane->mem_priv, eb->flags & O_ACCMODE);
        if (IS_ERR_OR_NULL(dbuf)) {
                dprintk(1, "Failed to export buffer %d, plane %d\n",
                        eb->index, eb->plane);
                return -EINVAL;
        }
 
-       ret = dma_buf_fd(dbuf, eb->flags);
+       ret = dma_buf_fd(dbuf, eb->flags & ~O_ACCMODE);
        if (ret < 0) {
                dprintk(3, "buffer %d, plane %d failed to export (%d)\n",
                        eb->index, eb->plane, ret);
index 646f08f4f504c05ae37dd95cbc1fe8333705e658..33d3871d1e131dce9a2f1d8392020dce5b8ff799 100644 (file)
@@ -393,7 +393,7 @@ static struct sg_table *vb2_dc_get_base_sgt(struct vb2_dc_buf *buf)
        return sgt;
 }
 
-static struct dma_buf *vb2_dc_get_dmabuf(void *buf_priv)
+static struct dma_buf *vb2_dc_get_dmabuf(void *buf_priv, unsigned long flags)
 {
        struct vb2_dc_buf *buf = buf_priv;
        struct dma_buf *dbuf;
@@ -404,7 +404,7 @@ static struct dma_buf *vb2_dc_get_dmabuf(void *buf_priv)
        if (WARN_ON(!buf->sgt_base))
                return NULL;
 
-       dbuf = dma_buf_export(buf, &vb2_dc_dmabuf_ops, buf->size, 0);
+       dbuf = dma_buf_export(buf, &vb2_dc_dmabuf_ops, buf->size, flags);
        if (IS_ERR(dbuf))
                return NULL;
 
index 2f860543912cd1c3f5dd4f286705b2c8b208dc37..0d3a8ffe47a3c15efc27faef3712f682e6a7f620 100644 (file)
@@ -178,7 +178,7 @@ static void *vb2_dma_sg_get_userptr(void *alloc_ctx, unsigned long vaddr,
        buf->pages = kzalloc(buf->num_pages * sizeof(struct page *),
                             GFP_KERNEL);
        if (!buf->pages)
-               return NULL;
+               goto userptr_fail_alloc_pages;
 
        num_pages_from_user = get_user_pages(current, current->mm,
                                             vaddr & PAGE_MASK,
@@ -204,6 +204,7 @@ userptr_fail_get_user_pages:
        while (--num_pages_from_user >= 0)
                put_page(buf->pages[num_pages_from_user]);
        kfree(buf->pages);
+userptr_fail_alloc_pages:
        kfree(buf);
        return NULL;
 }
index 34c18fb8c0896b46f49de48b4d5631a5d780a811..54cc25546592c7c7a1ba113104ca96fa5cacab83 100644 (file)
@@ -81,31 +81,31 @@ static struct of_device_id sec_dt_match[] = {
 
 int sec_reg_read(struct sec_pmic_dev *sec_pmic, u8 reg, void *dest)
 {
-       return regmap_read(sec_pmic->regmap, reg, dest);
+       return regmap_read(sec_pmic->regmap_pmic, reg, dest);
 }
 EXPORT_SYMBOL_GPL(sec_reg_read);
 
 int sec_bulk_read(struct sec_pmic_dev *sec_pmic, u8 reg, int count, u8 *buf)
 {
-       return regmap_bulk_read(sec_pmic->regmap, reg, buf, count);
+       return regmap_bulk_read(sec_pmic->regmap_pmic, reg, buf, count);
 }
 EXPORT_SYMBOL_GPL(sec_bulk_read);
 
 int sec_reg_write(struct sec_pmic_dev *sec_pmic, u8 reg, u8 value)
 {
-       return regmap_write(sec_pmic->regmap, reg, value);
+       return regmap_write(sec_pmic->regmap_pmic, reg, value);
 }
 EXPORT_SYMBOL_GPL(sec_reg_write);
 
 int sec_bulk_write(struct sec_pmic_dev *sec_pmic, u8 reg, int count, u8 *buf)
 {
-       return regmap_raw_write(sec_pmic->regmap, reg, buf, count);
+       return regmap_raw_write(sec_pmic->regmap_pmic, reg, buf, count);
 }
 EXPORT_SYMBOL_GPL(sec_bulk_write);
 
 int sec_reg_update(struct sec_pmic_dev *sec_pmic, u8 reg, u8 val, u8 mask)
 {
-       return regmap_update_bits(sec_pmic->regmap, reg, mask, val);
+       return regmap_update_bits(sec_pmic->regmap_pmic, reg, mask, val);
 }
 EXPORT_SYMBOL_GPL(sec_reg_update);
 
@@ -166,6 +166,11 @@ static struct regmap_config s5m8767_regmap_config = {
        .cache_type = REGCACHE_FLAT,
 };
 
+static const struct regmap_config sec_rtc_regmap_config = {
+       .reg_bits = 8,
+       .val_bits = 8,
+};
+
 #ifdef CONFIG_OF
 /*
  * Only the common platform data elements for s5m8767 are parsed here from the
@@ -266,9 +271,9 @@ static int sec_pmic_probe(struct i2c_client *i2c,
                break;
        }
 
-       sec_pmic->regmap = devm_regmap_init_i2c(i2c, regmap);
-       if (IS_ERR(sec_pmic->regmap)) {
-               ret = PTR_ERR(sec_pmic->regmap);
+       sec_pmic->regmap_pmic = devm_regmap_init_i2c(i2c, regmap);
+       if (IS_ERR(sec_pmic->regmap_pmic)) {
+               ret = PTR_ERR(sec_pmic->regmap_pmic);
                dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
                        ret);
                return ret;
@@ -277,6 +282,15 @@ static int sec_pmic_probe(struct i2c_client *i2c,
        sec_pmic->rtc = i2c_new_dummy(i2c->adapter, RTC_I2C_ADDR);
        i2c_set_clientdata(sec_pmic->rtc, sec_pmic);
 
+       sec_pmic->regmap_rtc = devm_regmap_init_i2c(sec_pmic->rtc,
+                       &sec_rtc_regmap_config);
+       if (IS_ERR(sec_pmic->regmap_rtc)) {
+               ret = PTR_ERR(sec_pmic->regmap_rtc);
+               dev_err(&i2c->dev, "Failed to allocate RTC register map: %d\n",
+                       ret);
+               return ret;
+       }
+
        if (pdata && pdata->cfg_pmic_irq)
                pdata->cfg_pmic_irq();
 
index 0dd84e99081e9d30539ab96cccc255591a18be82..b441b1be27cbe9165bd66f94e26c9f750125e665 100644 (file)
@@ -280,19 +280,19 @@ int sec_irq_init(struct sec_pmic_dev *sec_pmic)
 
        switch (type) {
        case S5M8763X:
-               ret = regmap_add_irq_chip(sec_pmic->regmap, sec_pmic->irq,
+               ret = regmap_add_irq_chip(sec_pmic->regmap_pmic, sec_pmic->irq,
                                  IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
                                  sec_pmic->irq_base, &s5m8763_irq_chip,
                                  &sec_pmic->irq_data);
                break;
        case S5M8767X:
-               ret = regmap_add_irq_chip(sec_pmic->regmap, sec_pmic->irq,
+               ret = regmap_add_irq_chip(sec_pmic->regmap_pmic, sec_pmic->irq,
                                  IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
                                  sec_pmic->irq_base, &s5m8767_irq_chip,
                                  &sec_pmic->irq_data);
                break;
        case S2MPS11X:
-               ret = regmap_add_irq_chip(sec_pmic->regmap, sec_pmic->irq,
+               ret = regmap_add_irq_chip(sec_pmic->regmap_pmic, sec_pmic->irq,
                                  IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
                                  sec_pmic->irq_base, &s2mps11_irq_chip,
                                  &sec_pmic->irq_data);
index 4cabdc9fda9076ceff440af42e028fb1073f9ed7..4b3aaa898a8b6b3a4975d2218370711981cb59c4 100644 (file)
@@ -962,7 +962,7 @@ static int pxa3xx_nand_init_buff(struct pxa3xx_nand_info *info)
 static void pxa3xx_nand_free_buff(struct pxa3xx_nand_info *info)
 {
        struct platform_device *pdev = info->pdev;
-       if (use_dma) {
+       if (info->use_dma) {
                pxa_free_dma(info->data_dma_ch);
                dma_free_coherent(&pdev->dev, info->buf_size,
                                  info->data_buff, info->data_buff_phys);
@@ -1259,10 +1259,6 @@ static struct of_device_id pxa3xx_nand_dt_ids[] = {
                .compatible = "marvell,pxa3xx-nand",
                .data       = (void *)PXA3XX_NAND_VARIANT_PXA,
        },
-       {
-               .compatible = "marvell,armada370-nand",
-               .data       = (void *)PXA3XX_NAND_VARIANT_ARMADA370,
-       },
        {}
 };
 MODULE_DEVICE_TABLE(of, pxa3xx_nand_dt_ids);
index 36eab0c4fb337b502c986d6c9ade7f1801d2a5f8..398e299ee1bded33a57d7eb91318b00b24513658 100644 (file)
@@ -4199,9 +4199,9 @@ static int bond_check_params(struct bond_params *params)
             (arp_ip_count < BOND_MAX_ARP_TARGETS) && arp_ip_target[i]; i++) {
                /* not complete check, but should be good enough to
                   catch mistakes */
-               __be32 ip = in_aton(arp_ip_target[i]);
-               if (!isdigit(arp_ip_target[i][0]) || ip == 0 ||
-                   ip == htonl(INADDR_BROADCAST)) {
+               __be32 ip;
+               if (!in4_pton(arp_ip_target[i], -1, (u8 *)&ip, -1, NULL) ||
+                   IS_IP_TARGET_UNUSABLE_ADDRESS(ip)) {
                        pr_warning("Warning: bad arp_ip_target module parameter (%s), ARP monitoring will not be performed\n",
                                   arp_ip_target[i]);
                        arp_interval = 0;
index abf5e106edc549c053e4d3ffdecce72c4470742e..0ae580bbc5db02ec4dbb3c5855ada7164f32c89a 100644 (file)
@@ -1635,12 +1635,12 @@ static ssize_t bonding_show_packets_per_slave(struct device *d,
                                              char *buf)
 {
        struct bonding *bond = to_bond(d);
-       int packets_per_slave = bond->params.packets_per_slave;
+       unsigned int packets_per_slave = bond->params.packets_per_slave;
 
        if (packets_per_slave > 1)
                packets_per_slave = reciprocal_value(packets_per_slave);
 
-       return sprintf(buf, "%d\n", packets_per_slave);
+       return sprintf(buf, "%u\n", packets_per_slave);
 }
 
 static ssize_t bonding_store_packets_per_slave(struct device *d,
index 5f9a7ad9b964da35190f01154492189965ba28ac..8aeec0b4601a2e8fe45290643a910a4fd8e4137b 100644 (file)
@@ -625,6 +625,7 @@ static int ems_usb_start(struct ems_usb *dev)
                        usb_unanchor_urb(urb);
                        usb_free_coherent(dev->udev, RX_BUFFER_SIZE, buf,
                                          urb->transfer_dma);
+                       usb_free_urb(urb);
                        break;
                }
 
@@ -798,8 +799,8 @@ static netdev_tx_t ems_usb_start_xmit(struct sk_buff *skb, struct net_device *ne
         * allowed (MAX_TX_URBS).
         */
        if (!context) {
-               usb_unanchor_urb(urb);
                usb_free_coherent(dev->udev, size, buf, urb->transfer_dma);
+               usb_free_urb(urb);
 
                netdev_warn(netdev, "couldn't find free context\n");
 
index 8ee9d1556e6e4eb3b8d32cfb988ba9870fccffaa..263dd921edc42342bba78ce9f2885862f0fc3087 100644 (file)
@@ -927,6 +927,9 @@ static int pcan_usb_pro_init(struct peak_usb_device *dev)
        /* set LED in default state (end of init phase) */
        pcan_usb_pro_set_led(dev, 0, 1);
 
+       kfree(bi);
+       kfree(fi);
+
        return 0;
 
  err_out:
index 50b853a79d7787c73d0ea8d0ac1f1e0853ac2adf..46dfb1378c17cac79064a5f3f809e94a1d75c584 100644 (file)
@@ -717,8 +717,7 @@ static int emac_open(struct net_device *dev)
        if (netif_msg_ifup(db))
                dev_dbg(db->dev, "enabling %s\n", dev->name);
 
-       if (devm_request_irq(db->dev, dev->irq, &emac_interrupt,
-                            0, dev->name, dev))
+       if (request_irq(dev->irq, &emac_interrupt, 0, dev->name, dev))
                return -EAGAIN;
 
        /* Initialize EMAC board */
@@ -774,6 +773,8 @@ static int emac_stop(struct net_device *ndev)
 
        emac_shutdown(ndev);
 
+       free_irq(ndev->irq, ndev);
+
        return 0;
 }
 
index 0216d592d0cee4b080a9d33d7776f632bf639453..2e46c28fc6019a892f7792c6017effe3f7db7063 100644 (file)
@@ -3114,6 +3114,11 @@ int bnx2x_sriov_configure(struct pci_dev *dev, int num_vfs_param)
 {
        struct bnx2x *bp = netdev_priv(pci_get_drvdata(dev));
 
+       if (!IS_SRIOV(bp)) {
+               BNX2X_ERR("failed to configure SR-IOV since vfdb was not allocated. Check dmesg for errors in probe stage\n");
+               return -EINVAL;
+       }
+
        DP(BNX2X_MSG_IOV, "bnx2x_sriov_configure called with %d, BNX2X_NR_VIRTFN(bp) was %d\n",
           num_vfs_param, BNX2X_NR_VIRTFN(bp));
 
index 369b736dde0533740a01718fd2d271fa7f10ad60..f3dd93b4aeaac1bc8cdff71c9113d6668e085fd2 100644 (file)
@@ -8932,6 +8932,9 @@ static int tg3_chip_reset(struct tg3 *tp)
        void (*write_op)(struct tg3 *, u32, u32);
        int i, err;
 
+       if (!pci_device_is_present(tp->pdev))
+               return -ENODEV;
+
        tg3_nvram_lock(tp);
 
        tg3_ape_lock(tp, TG3_APE_LOCK_GRC);
@@ -11581,10 +11584,11 @@ static int tg3_close(struct net_device *dev)
        memset(&tp->net_stats_prev, 0, sizeof(tp->net_stats_prev));
        memset(&tp->estats_prev, 0, sizeof(tp->estats_prev));
 
-       tg3_power_down_prepare(tp);
-
-       tg3_carrier_off(tp);
+       if (pci_device_is_present(tp->pdev)) {
+               tg3_power_down_prepare(tp);
 
+               tg3_carrier_off(tp);
+       }
        return 0;
 }
 
@@ -16499,6 +16503,9 @@ static int tg3_get_invariants(struct tg3 *tp, const struct pci_device_id *ent)
        /* Clear this out for sanity. */
        tw32(TG3PCI_MEM_WIN_BASE_ADDR, 0);
 
+       /* Clear TG3PCI_REG_BASE_ADDR to prevent hangs. */
+       tw32(TG3PCI_REG_BASE_ADDR, 0);
+
        pci_read_config_dword(tp->pdev, TG3PCI_PCISTATE,
                              &pci_state_reg);
        if ((pci_state_reg & PCISTATE_CONV_PCI_MODE) == 0 &&
@@ -17726,10 +17733,12 @@ static int tg3_suspend(struct device *device)
        struct pci_dev *pdev = to_pci_dev(device);
        struct net_device *dev = pci_get_drvdata(pdev);
        struct tg3 *tp = netdev_priv(dev);
-       int err;
+       int err = 0;
+
+       rtnl_lock();
 
        if (!netif_running(dev))
-               return 0;
+               goto unlock;
 
        tg3_reset_task_cancel(tp);
        tg3_phy_stop(tp);
@@ -17771,6 +17780,8 @@ out:
                        tg3_phy_start(tp);
        }
 
+unlock:
+       rtnl_unlock();
        return err;
 }
 
@@ -17779,10 +17790,12 @@ static int tg3_resume(struct device *device)
        struct pci_dev *pdev = to_pci_dev(device);
        struct net_device *dev = pci_get_drvdata(pdev);
        struct tg3 *tp = netdev_priv(dev);
-       int err;
+       int err = 0;
+
+       rtnl_lock();
 
        if (!netif_running(dev))
-               return 0;
+               goto unlock;
 
        netif_device_attach(dev);
 
@@ -17806,6 +17819,8 @@ out:
        if (!err)
                tg3_phy_start(tp);
 
+unlock:
+       rtnl_unlock();
        return err;
 }
 #endif /* CONFIG_PM_SLEEP */
index ecd2fb3ef69596146a7cf155323e624e397b6834..6c9308850453bf1ecd21173afa1d1cf11681c8c7 100644 (file)
 #include <asm/io.h>
 #include "cxgb4_uld.h"
 
-#define FW_VERSION_MAJOR 1
-#define FW_VERSION_MINOR 4
-#define FW_VERSION_MICRO 0
+#define T4FW_VERSION_MAJOR 0x01
+#define T4FW_VERSION_MINOR 0x06
+#define T4FW_VERSION_MICRO 0x18
+#define T4FW_VERSION_BUILD 0x00
 
-#define FW_VERSION_MAJOR_T5 0
-#define FW_VERSION_MINOR_T5 0
-#define FW_VERSION_MICRO_T5 0
+#define T5FW_VERSION_MAJOR 0x01
+#define T5FW_VERSION_MINOR 0x08
+#define T5FW_VERSION_MICRO 0x1C
+#define T5FW_VERSION_BUILD 0x00
 
 #define CH_WARN(adap, fmt, ...) dev_warn(adap->pdev_dev, fmt, ## __VA_ARGS__)
 
@@ -240,6 +242,26 @@ struct pci_params {
        unsigned char width;
 };
 
+#define CHELSIO_CHIP_CODE(version, revision) (((version) << 4) | (revision))
+#define CHELSIO_CHIP_FPGA          0x100
+#define CHELSIO_CHIP_VERSION(code) (((code) >> 4) & 0xf)
+#define CHELSIO_CHIP_RELEASE(code) ((code) & 0xf)
+
+#define CHELSIO_T4             0x4
+#define CHELSIO_T5             0x5
+
+enum chip_type {
+       T4_A1 = CHELSIO_CHIP_CODE(CHELSIO_T4, 1),
+       T4_A2 = CHELSIO_CHIP_CODE(CHELSIO_T4, 2),
+       T4_FIRST_REV    = T4_A1,
+       T4_LAST_REV     = T4_A2,
+
+       T5_A0 = CHELSIO_CHIP_CODE(CHELSIO_T5, 0),
+       T5_A1 = CHELSIO_CHIP_CODE(CHELSIO_T5, 1),
+       T5_FIRST_REV    = T5_A0,
+       T5_LAST_REV     = T5_A1,
+};
+
 struct adapter_params {
        struct tp_params  tp;
        struct vpd_params vpd;
@@ -259,7 +281,7 @@ struct adapter_params {
 
        unsigned char nports;             /* # of ethernet ports */
        unsigned char portvec;
-       unsigned char rev;                /* chip revision */
+       enum chip_type chip;               /* chip code */
        unsigned char offload;
 
        unsigned char bypass;
@@ -267,6 +289,23 @@ struct adapter_params {
        unsigned int ofldq_wr_cred;
 };
 
+#include "t4fw_api.h"
+
+#define FW_VERSION(chip) ( \
+               FW_HDR_FW_VER_MAJOR_GET(chip##FW_VERSION_MAJOR) | \
+               FW_HDR_FW_VER_MINOR_GET(chip##FW_VERSION_MINOR) | \
+               FW_HDR_FW_VER_MICRO_GET(chip##FW_VERSION_MICRO) | \
+               FW_HDR_FW_VER_BUILD_GET(chip##FW_VERSION_BUILD))
+#define FW_INTFVER(chip, intf) (FW_HDR_INTFVER_##intf)
+
+struct fw_info {
+       u8 chip;
+       char *fs_name;
+       char *fw_mod_name;
+       struct fw_hdr fw_hdr;
+};
+
+
 struct trace_params {
        u32 data[TRACE_LEN / 4];
        u32 mask[TRACE_LEN / 4];
@@ -512,25 +551,6 @@ struct sge {
 
 struct l2t_data;
 
-#define CHELSIO_CHIP_CODE(version, revision) (((version) << 4) | (revision))
-#define CHELSIO_CHIP_VERSION(code) ((code) >> 4)
-#define CHELSIO_CHIP_RELEASE(code) ((code) & 0xf)
-
-#define CHELSIO_T4             0x4
-#define CHELSIO_T5             0x5
-
-enum chip_type {
-       T4_A1 = CHELSIO_CHIP_CODE(CHELSIO_T4, 0),
-       T4_A2 = CHELSIO_CHIP_CODE(CHELSIO_T4, 1),
-       T4_A3 = CHELSIO_CHIP_CODE(CHELSIO_T4, 2),
-       T4_FIRST_REV    = T4_A1,
-       T4_LAST_REV     = T4_A3,
-
-       T5_A1 = CHELSIO_CHIP_CODE(CHELSIO_T5, 0),
-       T5_FIRST_REV    = T5_A1,
-       T5_LAST_REV     = T5_A1,
-};
-
 #ifdef CONFIG_PCI_IOV
 
 /* T4 supports SRIOV on PF0-3 and T5 on PF0-7.  However, the Serial
@@ -715,12 +735,12 @@ enum {
 
 static inline int is_t5(enum chip_type chip)
 {
-       return (chip >= T5_FIRST_REV && chip <= T5_LAST_REV);
+       return CHELSIO_CHIP_VERSION(chip) == CHELSIO_T5;
 }
 
 static inline int is_t4(enum chip_type chip)
 {
-       return (chip >= T4_FIRST_REV && chip <= T4_LAST_REV);
+       return CHELSIO_CHIP_VERSION(chip) == CHELSIO_T4;
 }
 
 static inline u32 t4_read_reg(struct adapter *adap, u32 reg_addr)
@@ -900,7 +920,11 @@ int get_vpd_params(struct adapter *adapter, struct vpd_params *p);
 int t4_load_fw(struct adapter *adapter, const u8 *fw_data, unsigned int size);
 unsigned int t4_flash_cfg_addr(struct adapter *adapter);
 int t4_load_cfg(struct adapter *adapter, const u8 *cfg_data, unsigned int size);
-int t4_check_fw_version(struct adapter *adapter);
+int t4_get_fw_version(struct adapter *adapter, u32 *vers);
+int t4_get_tp_version(struct adapter *adapter, u32 *vers);
+int t4_prep_fw(struct adapter *adap, struct fw_info *fw_info,
+              const u8 *fw_data, unsigned int fw_size,
+              struct fw_hdr *card_fw, enum dev_state state, int *reset);
 int t4_prep_adapter(struct adapter *adapter);
 int t4_port_init(struct adapter *adap, int mbox, int pf, int vf);
 void t4_fatal_err(struct adapter *adapter);
index 8b929eeecd2d37cd3b41e32d57bd1fa50402a230..d6b12e035a7d9f27d84d397dc2921713c7fed46f 100644 (file)
@@ -276,9 +276,9 @@ static DEFINE_PCI_DEVICE_TABLE(cxgb4_pci_tbl) = {
        { 0, }
 };
 
-#define FW_FNAME "cxgb4/t4fw.bin"
+#define FW4_FNAME "cxgb4/t4fw.bin"
 #define FW5_FNAME "cxgb4/t5fw.bin"
-#define FW_CFNAME "cxgb4/t4-config.txt"
+#define FW4_CFNAME "cxgb4/t4-config.txt"
 #define FW5_CFNAME "cxgb4/t5-config.txt"
 
 MODULE_DESCRIPTION(DRV_DESC);
@@ -286,7 +286,7 @@ MODULE_AUTHOR("Chelsio Communications");
 MODULE_LICENSE("Dual BSD/GPL");
 MODULE_VERSION(DRV_VERSION);
 MODULE_DEVICE_TABLE(pci, cxgb4_pci_tbl);
-MODULE_FIRMWARE(FW_FNAME);
+MODULE_FIRMWARE(FW4_FNAME);
 MODULE_FIRMWARE(FW5_FNAME);
 
 /*
@@ -1070,72 +1070,6 @@ freeout: t4_free_sge_resources(adap);
        return 0;
 }
 
-/*
- * Returns 0 if new FW was successfully loaded, a positive errno if a load was
- * started but failed, and a negative errno if flash load couldn't start.
- */
-static int upgrade_fw(struct adapter *adap)
-{
-       int ret;
-       u32 vers, exp_major;
-       const struct fw_hdr *hdr;
-       const struct firmware *fw;
-       struct device *dev = adap->pdev_dev;
-       char *fw_file_name;
-
-       switch (CHELSIO_CHIP_VERSION(adap->chip)) {
-       case CHELSIO_T4:
-               fw_file_name = FW_FNAME;
-               exp_major = FW_VERSION_MAJOR;
-               break;
-       case CHELSIO_T5:
-               fw_file_name = FW5_FNAME;
-               exp_major = FW_VERSION_MAJOR_T5;
-               break;
-       default:
-               dev_err(dev, "Unsupported chip type, %x\n", adap->chip);
-               return -EINVAL;
-       }
-
-       ret = request_firmware(&fw, fw_file_name, dev);
-       if (ret < 0) {
-               dev_err(dev, "unable to load firmware image %s, error %d\n",
-                       fw_file_name, ret);
-               return ret;
-       }
-
-       hdr = (const struct fw_hdr *)fw->data;
-       vers = ntohl(hdr->fw_ver);
-       if (FW_HDR_FW_VER_MAJOR_GET(vers) != exp_major) {
-               ret = -EINVAL;              /* wrong major version, won't do */
-               goto out;
-       }
-
-       /*
-        * If the flash FW is unusable or we found something newer, load it.
-        */
-       if (FW_HDR_FW_VER_MAJOR_GET(adap->params.fw_vers) != exp_major ||
-           vers > adap->params.fw_vers) {
-               dev_info(dev, "upgrading firmware ...\n");
-               ret = t4_fw_upgrade(adap, adap->mbox, fw->data, fw->size,
-                                   /*force=*/false);
-               if (!ret)
-                       dev_info(dev,
-                                "firmware upgraded to version %pI4 from %s\n",
-                                &hdr->fw_ver, fw_file_name);
-               else
-                       dev_err(dev, "firmware upgrade failed! err=%d\n", -ret);
-       } else {
-               /*
-                * Tell our caller that we didn't upgrade the firmware.
-                */
-               ret = -EINVAL;
-       }
-
-out:   release_firmware(fw);
-       return ret;
-}
-
 /*
  * Allocate a chunk of memory using kmalloc or, if that fails, vmalloc.
  * The allocated memory is cleared.
@@ -1415,7 +1349,7 @@ static int get_sset_count(struct net_device *dev, int sset)
 static int get_regs_len(struct net_device *dev)
 {
        struct adapter *adap = netdev2adap(dev);
-       if (is_t4(adap->chip))
+       if (is_t4(adap->params.chip))
                return T4_REGMAP_SIZE;
        else
                return T5_REGMAP_SIZE;
@@ -1499,7 +1433,7 @@ static void get_stats(struct net_device *dev, struct ethtool_stats *stats,
        data += sizeof(struct port_stats) / sizeof(u64);
        collect_sge_port_stats(adapter, pi, (struct queue_port_stats *)data);
        data += sizeof(struct queue_port_stats) / sizeof(u64);
-       if (!is_t4(adapter->chip)) {
+       if (!is_t4(adapter->params.chip)) {
                t4_write_reg(adapter, SGE_STAT_CFG, STATSOURCE_T5(7));
                val1 = t4_read_reg(adapter, SGE_STAT_TOTAL);
                val2 = t4_read_reg(adapter, SGE_STAT_MATCH);
@@ -1521,8 +1455,8 @@ static void get_stats(struct net_device *dev, struct ethtool_stats *stats,
  */
 static inline unsigned int mk_adap_vers(const struct adapter *ap)
 {
-       return CHELSIO_CHIP_VERSION(ap->chip) |
-               (CHELSIO_CHIP_RELEASE(ap->chip) << 10) | (1 << 16);
+       return CHELSIO_CHIP_VERSION(ap->params.chip) |
+               (CHELSIO_CHIP_RELEASE(ap->params.chip) << 10) | (1 << 16);
 }
 
 static void reg_block_dump(struct adapter *ap, void *buf, unsigned int start,
@@ -2189,7 +2123,7 @@ static void get_regs(struct net_device *dev, struct ethtool_regs *regs,
        static const unsigned int *reg_ranges;
        int arr_size = 0, buf_size = 0;
 
-       if (is_t4(ap->chip)) {
+       if (is_t4(ap->params.chip)) {
                reg_ranges = &t4_reg_ranges[0];
                arr_size = ARRAY_SIZE(t4_reg_ranges);
                buf_size = T4_REGMAP_SIZE;
@@ -2967,7 +2901,7 @@ static int setup_debugfs(struct adapter *adap)
                size = t4_read_reg(adap, MA_EDRAM1_BAR);
                add_debugfs_mem(adap, "edc1", MEM_EDC1, EDRAM_SIZE_GET(size));
        }
-       if (is_t4(adap->chip)) {
+       if (is_t4(adap->params.chip)) {
                size = t4_read_reg(adap, MA_EXT_MEMORY_BAR);
                if (i & EXT_MEM_ENABLE)
                        add_debugfs_mem(adap, "mc", MEM_MC,
@@ -3419,7 +3353,7 @@ unsigned int cxgb4_dbfifo_count(const struct net_device *dev, int lpfifo)
 
        v1 = t4_read_reg(adap, A_SGE_DBFIFO_STATUS);
        v2 = t4_read_reg(adap, SGE_DBFIFO_STATUS2);
-       if (is_t4(adap->chip)) {
+       if (is_t4(adap->params.chip)) {
                lp_count = G_LP_COUNT(v1);
                hp_count = G_HP_COUNT(v1);
        } else {
@@ -3588,7 +3522,7 @@ static void drain_db_fifo(struct adapter *adap, int usecs)
        do {
                v1 = t4_read_reg(adap, A_SGE_DBFIFO_STATUS);
                v2 = t4_read_reg(adap, SGE_DBFIFO_STATUS2);
-               if (is_t4(adap->chip)) {
+               if (is_t4(adap->params.chip)) {
                        lp_count = G_LP_COUNT(v1);
                        hp_count = G_HP_COUNT(v1);
                } else {
@@ -3708,7 +3642,7 @@ static void process_db_drop(struct work_struct *work)
 
        adap = container_of(work, struct adapter, db_drop_task);
 
-       if (is_t4(adap->chip)) {
+       if (is_t4(adap->params.chip)) {
                disable_dbs(adap);
                notify_rdma_uld(adap, CXGB4_CONTROL_DB_DROP);
                drain_db_fifo(adap, 1);
@@ -3753,7 +3687,7 @@ static void process_db_drop(struct work_struct *work)
 
 void t4_db_full(struct adapter *adap)
 {
-       if (is_t4(adap->chip)) {
+       if (is_t4(adap->params.chip)) {
                t4_set_reg_field(adap, SGE_INT_ENABLE3,
                                 DBFIFO_HP_INT | DBFIFO_LP_INT, 0);
                queue_work(workq, &adap->db_full_task);
@@ -3762,7 +3696,7 @@ void t4_db_full(struct adapter *adap)
 
 void t4_db_dropped(struct adapter *adap)
 {
-       if (is_t4(adap->chip))
+       if (is_t4(adap->params.chip))
                queue_work(workq, &adap->db_drop_task);
 }
 
@@ -3789,7 +3723,7 @@ static void uld_attach(struct adapter *adap, unsigned int uld)
        lli.nchan = adap->params.nports;
        lli.nports = adap->params.nports;
        lli.wr_cred = adap->params.ofldq_wr_cred;
-       lli.adapter_type = adap->params.rev;
+       lli.adapter_type = adap->params.chip;
        lli.iscsi_iolen = MAXRXDATA_GET(t4_read_reg(adap, TP_PARA_REG2));
        lli.udb_density = 1 << QUEUESPERPAGEPF0_GET(
                        t4_read_reg(adap, SGE_EGRESS_QUEUES_PER_PAGE_PF) >>
@@ -4483,7 +4417,7 @@ static void setup_memwin(struct adapter *adap)
        u32 bar0, mem_win0_base, mem_win1_base, mem_win2_base;
 
        bar0 = pci_resource_start(adap->pdev, 0);  /* truncation intentional */
-       if (is_t4(adap->chip)) {
+       if (is_t4(adap->params.chip)) {
                mem_win0_base = bar0 + MEMWIN0_BASE;
                mem_win1_base = bar0 + MEMWIN1_BASE;
                mem_win2_base = bar0 + MEMWIN2_BASE;
@@ -4668,8 +4602,10 @@ static int adap_init0_config(struct adapter *adapter, int reset)
        const struct firmware *cf;
        unsigned long mtype = 0, maddr = 0;
        u32 finiver, finicsum, cfcsum;
-       int ret, using_flash;
+       int ret;
+       int config_issued = 0;
        char *fw_config_file, fw_config_file_path[256];
+       char *config_name = NULL;
 
        /*
         * Reset device if necessary.
@@ -4686,9 +4622,9 @@ static int adap_init0_config(struct adapter *adapter, int reset)
         * then use that.  Otherwise, use the configuration file stored
         * in the adapter flash ...
         */
-       switch (CHELSIO_CHIP_VERSION(adapter->chip)) {
+       switch (CHELSIO_CHIP_VERSION(adapter->params.chip)) {
        case CHELSIO_T4:
-               fw_config_file = FW_CFNAME;
+               fw_config_file = FW4_CFNAME;
                break;
        case CHELSIO_T5:
                fw_config_file = FW5_CFNAME;
@@ -4702,13 +4638,16 @@ static int adap_init0_config(struct adapter *adapter, int reset)
 
        ret = request_firmware(&cf, fw_config_file, adapter->pdev_dev);
        if (ret < 0) {
-               using_flash = 1;
+               config_name = "On FLASH";
                mtype = FW_MEMTYPE_CF_FLASH;
                maddr = t4_flash_cfg_addr(adapter);
        } else {
                u32 params[7], val[7];
 
-               using_flash = 0;
+               sprintf(fw_config_file_path,
+                       "/lib/firmware/%s", fw_config_file);
+               config_name = fw_config_file_path;
+
                if (cf->size >= FLASH_CFG_MAX_SIZE)
                        ret = -ENOMEM;
                else {
@@ -4776,6 +4715,26 @@ static int adap_init0_config(struct adapter *adapter, int reset)
                      FW_LEN16(caps_cmd));
        ret = t4_wr_mbox(adapter, adapter->mbox, &caps_cmd, sizeof(caps_cmd),
                         &caps_cmd);
+
+       /* If the CAPS_CONFIG failed with an ENOENT (for a Firmware
+        * Configuration File in FLASH), our last gasp effort is to use the
+        * Firmware Configuration File which is embedded in the firmware.  A
+        * very few early versions of the firmware didn't have one embedded
+        * but we can ignore those.
+        */
+       if (ret == -ENOENT) {
+               memset(&caps_cmd, 0, sizeof(caps_cmd));
+               caps_cmd.op_to_write =
+                       htonl(FW_CMD_OP(FW_CAPS_CONFIG_CMD) |
+                                       FW_CMD_REQUEST |
+                                       FW_CMD_READ);
+               caps_cmd.cfvalid_to_len16 = htonl(FW_LEN16(caps_cmd));
+               ret = t4_wr_mbox(adapter, adapter->mbox, &caps_cmd,
+                               sizeof(caps_cmd), &caps_cmd);
+               config_name = "Firmware Default";
+       }
+
+       config_issued = 1;
        if (ret < 0)
                goto bye;
 
@@ -4816,7 +4775,6 @@ static int adap_init0_config(struct adapter *adapter, int reset)
        if (ret < 0)
                goto bye;
 
-       sprintf(fw_config_file_path, "/lib/firmware/%s", fw_config_file);
        /*
         * Return successfully and note that we're operating with parameters
         * not supplied by the driver, rather than from hard-wired
@@ -4824,11 +4782,8 @@ static int adap_init0_config(struct adapter *adapter, int reset)
         */
        adapter->flags |= USING_SOFT_PARAMS;
        dev_info(adapter->pdev_dev, "Successfully configured using Firmware "\
-                "Configuration File %s, version %#x, computed checksum %#x\n",
-                (using_flash
-                 ? "in device FLASH"
-                 : fw_config_file_path),
-                finiver, cfcsum);
+                "Configuration File \"%s\", version %#x, computed checksum %#x\n",
+                config_name, finiver, cfcsum);
        return 0;
 
        /*
@@ -4837,9 +4792,9 @@ static int adap_init0_config(struct adapter *adapter, int reset)
         * want to issue a warning since this is fairly common.)
         */
 bye:
-       if (ret != -ENOENT)
-               dev_warn(adapter->pdev_dev, "Configuration file error %d\n",
-                        -ret);
+       if (config_issued && ret != -ENOENT)
+               dev_warn(adapter->pdev_dev, "\"%s\" configuration file error %d\n",
+                        config_name, -ret);
        return ret;
 }
 
@@ -5086,6 +5041,47 @@ bye:
        return ret;
 }
 
+static struct fw_info fw_info_array[] = {
+       {
+               .chip = CHELSIO_T4,
+               .fs_name = FW4_CFNAME,
+               .fw_mod_name = FW4_FNAME,
+               .fw_hdr = {
+                       .chip = FW_HDR_CHIP_T4,
+                       .fw_ver = __cpu_to_be32(FW_VERSION(T4)),
+                       .intfver_nic = FW_INTFVER(T4, NIC),
+                       .intfver_vnic = FW_INTFVER(T4, VNIC),
+                       .intfver_ri = FW_INTFVER(T4, RI),
+                       .intfver_iscsi = FW_INTFVER(T4, ISCSI),
+                       .intfver_fcoe = FW_INTFVER(T4, FCOE),
+               },
+       }, {
+               .chip = CHELSIO_T5,
+               .fs_name = FW5_CFNAME,
+               .fw_mod_name = FW5_FNAME,
+               .fw_hdr = {
+                       .chip = FW_HDR_CHIP_T5,
+                       .fw_ver = __cpu_to_be32(FW_VERSION(T5)),
+                       .intfver_nic = FW_INTFVER(T5, NIC),
+                       .intfver_vnic = FW_INTFVER(T5, VNIC),
+                       .intfver_ri = FW_INTFVER(T5, RI),
+                       .intfver_iscsi = FW_INTFVER(T5, ISCSI),
+                       .intfver_fcoe = FW_INTFVER(T5, FCOE),
+               },
+       }
+};
+
+static struct fw_info *find_fw_info(int chip)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(fw_info_array); i++) {
+               if (fw_info_array[i].chip == chip)
+                       return &fw_info_array[i];
+       }
+       return NULL;
+}
+
 /*
  * Phase 0 of initialization: contact FW, obtain config, perform basic init.
  */
@@ -5123,44 +5119,54 @@ static int adap_init0(struct adapter *adap)
         * later reporting and B. to warn if the currently loaded firmware
         * is excessively mismatched relative to the driver.)
         */
-       ret = t4_check_fw_version(adap);
-
-       /* The error code -EFAULT is returned by t4_check_fw_version() if
-        * firmware on adapter < supported firmware. If firmware on adapter
-        * is too old (not supported by driver) and we're the MASTER_PF set
-        * adapter state to DEV_STATE_UNINIT to force firmware upgrade
-        * and reinitialization.
-        */
-       if ((adap->flags & MASTER_PF) && ret == -EFAULT)
-               state = DEV_STATE_UNINIT;
+       t4_get_fw_version(adap, &adap->params.fw_vers);
+       t4_get_tp_version(adap, &adap->params.tp_vers);
        if ((adap->flags & MASTER_PF) && state != DEV_STATE_INIT) {
-               if (ret == -EINVAL || ret == -EFAULT || ret > 0) {
-                       if (upgrade_fw(adap) >= 0) {
-                               /*
-                                * Note that the chip was reset as part of the
-                                * firmware upgrade so we don't reset it again
-                                * below and grab the new firmware version.
-                                */
-                               reset = 0;
-                               ret = t4_check_fw_version(adap);
-                       } else
-                               if (ret == -EFAULT) {
-                                       /*
-                                        * Firmware is old but still might
-                                        * work if we force reinitialization
-                                        * of the adapter. Ignoring FW upgrade
-                                        * failure.
-                                        */
-                                       dev_warn(adap->pdev_dev,
-                                                "Ignoring firmware upgrade "
-                                                "failure, and forcing driver "
-                                                "to reinitialize the "
-                                                "adapter.\n");
-                                       ret = 0;
-                               }
+               struct fw_info *fw_info;
+               struct fw_hdr *card_fw;
+               const struct firmware *fw;
+               const u8 *fw_data = NULL;
+               unsigned int fw_size = 0;
+
+               /* This is the firmware whose headers the driver was compiled
+                * against
+                */
+               fw_info = find_fw_info(CHELSIO_CHIP_VERSION(adap->params.chip));
+               if (fw_info == NULL) {
+                       dev_err(adap->pdev_dev,
+                               "unable to get firmware info for chip %d.\n",
+                               CHELSIO_CHIP_VERSION(adap->params.chip));
+                       return -EINVAL;
                }
+
+               /* allocate memory to read the header of the firmware on the
+                * card
+                */
+               card_fw = t4_alloc_mem(sizeof(*card_fw));
+
+               /* Get FW from from /lib/firmware/ */
+               ret = request_firmware(&fw, fw_info->fw_mod_name,
+                                      adap->pdev_dev);
+               if (ret < 0) {
+                       dev_err(adap->pdev_dev,
+                               "unable to load firmware image %s, error %d\n",
+                               fw_info->fw_mod_name, ret);
+               } else {
+                       fw_data = fw->data;
+                       fw_size = fw->size;
+               }
+
+               /* upgrade FW logic */
+               ret = t4_prep_fw(adap, fw_info, fw_data, fw_size, card_fw,
+                                state, &reset);
+
+               /* Cleaning up */
+               if (fw != NULL)
+                       release_firmware(fw);
+               t4_free_mem(card_fw);
+
                if (ret < 0)
-                       return ret;
+                       goto bye;
        }
 
        /*
@@ -5245,7 +5251,7 @@ static int adap_init0(struct adapter *adap)
                                if (ret == -ENOENT) {
                                        dev_info(adap->pdev_dev,
                                            "No Configuration File present "
-                                           "on adapter.  Using hard-wired "
+                                           "on adapter. Using hard-wired "
                                            "configuration parameters.\n");
                                        ret = adap_init0_no_config(adap, reset);
                                }
@@ -5787,7 +5793,7 @@ static void print_port_info(const struct net_device *dev)
 
        netdev_info(dev, "Chelsio %s rev %d %s %sNIC PCIe x%d%s%s\n",
                    adap->params.vpd.id,
-                   CHELSIO_CHIP_RELEASE(adap->params.rev), buf,
+                   CHELSIO_CHIP_RELEASE(adap->params.chip), buf,
                    is_offload(adap) ? "R" : "", adap->params.pci.width, spd,
                    (adap->flags & USING_MSIX) ? " MSI-X" :
                    (adap->flags & USING_MSI) ? " MSI" : "");
@@ -5910,7 +5916,7 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        if (err)
                goto out_unmap_bar0;
 
-       if (!is_t4(adapter->chip)) {
+       if (!is_t4(adapter->params.chip)) {
                s_qpp = QUEUESPERPAGEPF1 * adapter->fn;
                qpp = 1 << QUEUESPERPAGEPF0_GET(t4_read_reg(adapter,
                      SGE_EGRESS_QUEUES_PER_PAGE_PF) >> s_qpp);
@@ -6064,7 +6070,7 @@ sriov:
  out_free_dev:
        free_some_resources(adapter);
  out_unmap_bar:
-       if (!is_t4(adapter->chip))
+       if (!is_t4(adapter->params.chip))
                iounmap(adapter->bar2);
  out_unmap_bar0:
        iounmap(adapter->regs);
@@ -6116,7 +6122,7 @@ static void remove_one(struct pci_dev *pdev)
 
                free_some_resources(adapter);
                iounmap(adapter->regs);
-               if (!is_t4(adapter->chip))
+               if (!is_t4(adapter->params.chip))
                        iounmap(adapter->bar2);
                kfree(adapter);
                pci_disable_pcie_error_reporting(pdev);
index ac311f5f3eb9590d1d9b5fb3bb0a9c3f0fac5ce7..cc380c36e1a8687cd1c7f3b4c3dbf2d0b8c1bf47 100644 (file)
@@ -509,7 +509,7 @@ static inline void ring_fl_db(struct adapter *adap, struct sge_fl *q)
        u32 val;
        if (q->pend_cred >= 8) {
                val = PIDX(q->pend_cred / 8);
-               if (!is_t4(adap->chip))
+               if (!is_t4(adap->params.chip))
                        val |= DBTYPE(1);
                wmb();
                t4_write_reg(adap, MYPF_REG(SGE_PF_KDOORBELL), DBPRIO(1) |
@@ -847,7 +847,7 @@ static inline void ring_tx_db(struct adapter *adap, struct sge_txq *q, int n)
        wmb();            /* write descriptors before telling HW */
        spin_lock(&q->db_lock);
        if (!q->db_disabled) {
-               if (is_t4(adap->chip)) {
+               if (is_t4(adap->params.chip)) {
                        t4_write_reg(adap, MYPF_REG(SGE_PF_KDOORBELL),
                                     QID(q->cntxt_id) | PIDX(n));
                } else {
@@ -1596,7 +1596,7 @@ static noinline int handle_trace_pkt(struct adapter *adap,
                return 0;
        }
 
-       if (is_t4(adap->chip))
+       if (is_t4(adap->params.chip))
                __skb_pull(skb, sizeof(struct cpl_trace_pkt));
        else
                __skb_pull(skb, sizeof(struct cpl_t5_trace_pkt));
@@ -1661,7 +1661,7 @@ int t4_ethrx_handler(struct sge_rspq *q, const __be64 *rsp,
        const struct cpl_rx_pkt *pkt;
        struct sge_eth_rxq *rxq = container_of(q, struct sge_eth_rxq, rspq);
        struct sge *s = &q->adap->sge;
-       int cpl_trace_pkt = is_t4(q->adap->chip) ?
+       int cpl_trace_pkt = is_t4(q->adap->params.chip) ?
                            CPL_TRACE_PKT : CPL_TRACE_PKT_T5;
 
        if (unlikely(*(u8 *)rsp == cpl_trace_pkt))
@@ -2182,7 +2182,7 @@ err:
 static void init_txq(struct adapter *adap, struct sge_txq *q, unsigned int id)
 {
        q->cntxt_id = id;
-       if (!is_t4(adap->chip)) {
+       if (!is_t4(adap->params.chip)) {
                unsigned int s_qpp;
                unsigned short udb_density;
                unsigned long qpshift;
@@ -2641,7 +2641,7 @@ static int t4_sge_init_hard(struct adapter *adap)
         * Set up to drop DOORBELL writes when the DOORBELL FIFO overflows
         * and generate an interrupt when this occurs so we can recover.
         */
-       if (is_t4(adap->chip)) {
+       if (is_t4(adap->params.chip)) {
                t4_set_reg_field(adap, A_SGE_DBFIFO_STATUS,
                                 V_HP_INT_THRESH(M_HP_INT_THRESH) |
                                 V_LP_INT_THRESH(M_LP_INT_THRESH),
index 4cbb2f9850be554c9ec48afd7479b4fcd9e5ebc2..74a6fce5a15a6914faf74bbf903dcc76ec717775 100644 (file)
@@ -296,7 +296,7 @@ int t4_mc_read(struct adapter *adap, int idx, u32 addr, __be32 *data, u64 *ecc)
        u32 mc_bist_cmd, mc_bist_cmd_addr, mc_bist_cmd_len;
        u32 mc_bist_status_rdata, mc_bist_data_pattern;
 
-       if (is_t4(adap->chip)) {
+       if (is_t4(adap->params.chip)) {
                mc_bist_cmd = MC_BIST_CMD;
                mc_bist_cmd_addr = MC_BIST_CMD_ADDR;
                mc_bist_cmd_len = MC_BIST_CMD_LEN;
@@ -349,7 +349,7 @@ int t4_edc_read(struct adapter *adap, int idx, u32 addr, __be32 *data, u64 *ecc)
        u32 edc_bist_cmd, edc_bist_cmd_addr, edc_bist_cmd_len;
        u32 edc_bist_cmd_data_pattern, edc_bist_status_rdata;
 
-       if (is_t4(adap->chip)) {
+       if (is_t4(adap->params.chip)) {
                edc_bist_cmd = EDC_REG(EDC_BIST_CMD, idx);
                edc_bist_cmd_addr = EDC_REG(EDC_BIST_CMD_ADDR, idx);
                edc_bist_cmd_len = EDC_REG(EDC_BIST_CMD_LEN, idx);
@@ -402,7 +402,7 @@ int t4_edc_read(struct adapter *adap, int idx, u32 addr, __be32 *data, u64 *ecc)
 static int t4_mem_win_rw(struct adapter *adap, u32 addr, __be32 *data, int dir)
 {
        int i;
-       u32 win_pf = is_t4(adap->chip) ? 0 : V_PFNUM(adap->fn);
+       u32 win_pf = is_t4(adap->params.chip) ? 0 : V_PFNUM(adap->fn);
 
        /*
         * Setup offset into PCIE memory window.  Address must be a
@@ -863,104 +863,169 @@ unlock:
 }
 
 /**
- *     get_fw_version - read the firmware version
+ *     t4_get_fw_version - read the firmware version
  *     @adapter: the adapter
  *     @vers: where to place the version
  *
  *     Reads the FW version from flash.
  */
-static int get_fw_version(struct adapter *adapter, u32 *vers)
+int t4_get_fw_version(struct adapter *adapter, u32 *vers)
 {
-       return t4_read_flash(adapter, adapter->params.sf_fw_start +
-                            offsetof(struct fw_hdr, fw_ver), 1, vers, 0);
+       return t4_read_flash(adapter, FLASH_FW_START +
+                            offsetof(struct fw_hdr, fw_ver), 1,
+                            vers, 0);
 }
 
 /**
- *     get_tp_version - read the TP microcode version
+ *     t4_get_tp_version - read the TP microcode version
  *     @adapter: the adapter
  *     @vers: where to place the version
  *
  *     Reads the TP microcode version from flash.
  */
-static int get_tp_version(struct adapter *adapter, u32 *vers)
+int t4_get_tp_version(struct adapter *adapter, u32 *vers)
 {
-       return t4_read_flash(adapter, adapter->params.sf_fw_start +
+       return t4_read_flash(adapter, FLASH_FW_START +
                             offsetof(struct fw_hdr, tp_microcode_ver),
                             1, vers, 0);
 }
 
-/**
- *     t4_check_fw_version - check if the FW is compatible with this driver
- *     @adapter: the adapter
- *
- *     Checks if an adapter's FW is compatible with the driver.  Returns 0
- *     if there's exact match, a negative error if the version could not be
- *     read or there's a major version mismatch, and a positive value if the
- *     expected major version is found but there's a minor version mismatch.
+/* Is the given firmware API compatible with the one the driver was compiled
+ * with?
  */
-int t4_check_fw_version(struct adapter *adapter)
+static int fw_compatible(const struct fw_hdr *hdr1, const struct fw_hdr *hdr2)
 {
-       u32 api_vers[2];
-       int ret, major, minor, micro;
-       int exp_major, exp_minor, exp_micro;
 
-       ret = get_fw_version(adapter, &adapter->params.fw_vers);
-       if (!ret)
-               ret = get_tp_version(adapter, &adapter->params.tp_vers);
-       if (!ret)
-               ret = t4_read_flash(adapter, adapter->params.sf_fw_start +
-                                   offsetof(struct fw_hdr, intfver_nic),
-                                   2, api_vers, 1);
-       if (ret)
-               return ret;
+       /* short circuit if it's the exact same firmware version */
+       if (hdr1->chip == hdr2->chip && hdr1->fw_ver == hdr2->fw_ver)
+               return 1;
 
-       major = FW_HDR_FW_VER_MAJOR_GET(adapter->params.fw_vers);
-       minor = FW_HDR_FW_VER_MINOR_GET(adapter->params.fw_vers);
-       micro = FW_HDR_FW_VER_MICRO_GET(adapter->params.fw_vers);
+#define SAME_INTF(x) (hdr1->intfver_##x == hdr2->intfver_##x)
+       if (hdr1->chip == hdr2->chip && SAME_INTF(nic) && SAME_INTF(vnic) &&
+           SAME_INTF(ri) && SAME_INTF(iscsi) && SAME_INTF(fcoe))
+               return 1;
+#undef SAME_INTF
 
-       switch (CHELSIO_CHIP_VERSION(adapter->chip)) {
-       case CHELSIO_T4:
-               exp_major = FW_VERSION_MAJOR;
-               exp_minor = FW_VERSION_MINOR;
-               exp_micro = FW_VERSION_MICRO;
-               break;
-       case CHELSIO_T5:
-               exp_major = FW_VERSION_MAJOR_T5;
-               exp_minor = FW_VERSION_MINOR_T5;
-               exp_micro = FW_VERSION_MICRO_T5;
-               break;
-       default:
-               dev_err(adapter->pdev_dev, "Unsupported chip type, %x\n",
-                       adapter->chip);
-               return -EINVAL;
-       }
+       return 0;
+}
 
-       memcpy(adapter->params.api_vers, api_vers,
-              sizeof(adapter->params.api_vers));
+/* The firmware in the filesystem is usable, but should it be installed?
+ * This routine explains itself in detail if it indicates the filesystem
+ * firmware should be installed.
+ */
+static int should_install_fs_fw(struct adapter *adap, int card_fw_usable,
+                               int k, int c)
+{
+       const char *reason;
 
-       if (major < exp_major || (major == exp_major && minor < exp_minor) ||
-           (major == exp_major && minor == exp_minor && micro < exp_micro)) {
-               dev_err(adapter->pdev_dev,
-                       "Card has firmware version %u.%u.%u, minimum "
-                       "supported firmware is %u.%u.%u.\n", major, minor,
-                       micro, exp_major, exp_minor, exp_micro);
-               return -EFAULT;
+       if (!card_fw_usable) {
+               reason = "incompatible or unusable";
+               goto install;
        }
 
-       if (major != exp_major) {            /* major mismatch - fail */
-               dev_err(adapter->pdev_dev,
-                       "card FW has major version %u, driver wants %u\n",
-                       major, exp_major);
-               return -EINVAL;
+       if (k > c) {
+               reason = "older than the version supported with this driver";
+               goto install;
        }
 
-       if (minor == exp_minor && micro == exp_micro)
-               return 0;                                   /* perfect match */
+       return 0;
+
+install:
+       dev_err(adap->pdev_dev, "firmware on card (%u.%u.%u.%u) is %s, "
+               "installing firmware %u.%u.%u.%u on card.\n",
+               FW_HDR_FW_VER_MAJOR_GET(c), FW_HDR_FW_VER_MINOR_GET(c),
+               FW_HDR_FW_VER_MICRO_GET(c), FW_HDR_FW_VER_BUILD_GET(c), reason,
+               FW_HDR_FW_VER_MAJOR_GET(k), FW_HDR_FW_VER_MINOR_GET(k),
+               FW_HDR_FW_VER_MICRO_GET(k), FW_HDR_FW_VER_BUILD_GET(k));
 
-       /* Minor/micro version mismatch.  Report it but often it's OK. */
        return 1;
 }
 
+int t4_prep_fw(struct adapter *adap, struct fw_info *fw_info,
+              const u8 *fw_data, unsigned int fw_size,
+              struct fw_hdr *card_fw, enum dev_state state,
+              int *reset)
+{
+       int ret, card_fw_usable, fs_fw_usable;
+       const struct fw_hdr *fs_fw;
+       const struct fw_hdr *drv_fw;
+
+       drv_fw = &fw_info->fw_hdr;
+
+       /* Read the header of the firmware on the card */
+       ret = -t4_read_flash(adap, FLASH_FW_START,
+                           sizeof(*card_fw) / sizeof(uint32_t),
+                           (uint32_t *)card_fw, 1);
+       if (ret == 0) {
+               card_fw_usable = fw_compatible(drv_fw, (const void *)card_fw);
+       } else {
+               dev_err(adap->pdev_dev,
+                       "Unable to read card's firmware header: %d\n", ret);
+               card_fw_usable = 0;
+       }
+
+       if (fw_data != NULL) {
+               fs_fw = (const void *)fw_data;
+               fs_fw_usable = fw_compatible(drv_fw, fs_fw);
+       } else {
+               fs_fw = NULL;
+               fs_fw_usable = 0;
+       }
+
+       if (card_fw_usable && card_fw->fw_ver == drv_fw->fw_ver &&
+           (!fs_fw_usable || fs_fw->fw_ver == drv_fw->fw_ver)) {
+               /* Common case: the firmware on the card is an exact match and
+                * the filesystem one is an exact match too, or the filesystem
+                * one is absent/incompatible.
+                */
+       } else if (fs_fw_usable && state == DEV_STATE_UNINIT &&
+                  should_install_fs_fw(adap, card_fw_usable,
+                                       be32_to_cpu(fs_fw->fw_ver),
+                                       be32_to_cpu(card_fw->fw_ver))) {
+               ret = -t4_fw_upgrade(adap, adap->mbox, fw_data,
+                                    fw_size, 0);
+               if (ret != 0) {
+                       dev_err(adap->pdev_dev,
+                               "failed to install firmware: %d\n", ret);
+                       goto bye;
+               }
+
+               /* Installed successfully, update the cached header too. */
+               memcpy(card_fw, fs_fw, sizeof(*card_fw));
+               card_fw_usable = 1;
+               *reset = 0;     /* already reset as part of load_fw */
+       }
+
+       if (!card_fw_usable) {
+               uint32_t d, c, k;
+
+               d = be32_to_cpu(drv_fw->fw_ver);
+               c = be32_to_cpu(card_fw->fw_ver);
+               k = fs_fw ? be32_to_cpu(fs_fw->fw_ver) : 0;
+
+               dev_err(adap->pdev_dev, "Cannot find a usable firmware: "
+                       "chip state %d, "
+                       "driver compiled with %d.%d.%d.%d, "
+                       "card has %d.%d.%d.%d, filesystem has %d.%d.%d.%d\n",
+                       state,
+                       FW_HDR_FW_VER_MAJOR_GET(d), FW_HDR_FW_VER_MINOR_GET(d),
+                       FW_HDR_FW_VER_MICRO_GET(d), FW_HDR_FW_VER_BUILD_GET(d),
+                       FW_HDR_FW_VER_MAJOR_GET(c), FW_HDR_FW_VER_MINOR_GET(c),
+                       FW_HDR_FW_VER_MICRO_GET(c), FW_HDR_FW_VER_BUILD_GET(c),
+                       FW_HDR_FW_VER_MAJOR_GET(k), FW_HDR_FW_VER_MINOR_GET(k),
+                       FW_HDR_FW_VER_MICRO_GET(k), FW_HDR_FW_VER_BUILD_GET(k));
+               ret = EINVAL;
+               goto bye;
+       }
+
+       /* We're using whatever's on the card and it's known to be good. */
+       adap->params.fw_vers = be32_to_cpu(card_fw->fw_ver);
+       adap->params.tp_vers = be32_to_cpu(card_fw->tp_microcode_ver);
+
+bye:
+       return ret;
+}
+
 /**
  *     t4_flash_erase_sectors - erase a range of flash sectors
  *     @adapter: the adapter
@@ -1368,7 +1433,7 @@ static void pcie_intr_handler(struct adapter *adapter)
                                    PCIE_CORE_UTL_PCI_EXPRESS_PORT_STATUS,
                                    pcie_port_intr_info) +
              t4_handle_intr_status(adapter, PCIE_INT_CAUSE,
-                                   is_t4(adapter->chip) ?
+                                   is_t4(adapter->params.chip) ?
                                    pcie_intr_info : t5_pcie_intr_info);
 
        if (fat)
@@ -1782,7 +1847,7 @@ static void xgmac_intr_handler(struct adapter *adap, int port)
 {
        u32 v, int_cause_reg;
 
-       if (is_t4(adap->chip))
+       if (is_t4(adap->params.chip))
                int_cause_reg = PORT_REG(port, XGMAC_PORT_INT_CAUSE);
        else
                int_cause_reg = T5_PORT_REG(port, MAC_PORT_INT_CAUSE);
@@ -2250,7 +2315,7 @@ void t4_get_port_stats(struct adapter *adap, int idx, struct port_stats *p)
 
 #define GET_STAT(name) \
        t4_read_reg64(adap, \
-       (is_t4(adap->chip) ? PORT_REG(idx, MPS_PORT_STAT_##name##_L) : \
+       (is_t4(adap->params.chip) ? PORT_REG(idx, MPS_PORT_STAT_##name##_L) : \
        T5_PORT_REG(idx, MPS_PORT_STAT_##name##_L)))
 #define GET_STAT_COM(name) t4_read_reg64(adap, MPS_STAT_##name##_L)
 
@@ -2332,7 +2397,7 @@ void t4_wol_magic_enable(struct adapter *adap, unsigned int port,
 {
        u32 mag_id_reg_l, mag_id_reg_h, port_cfg_reg;
 
-       if (is_t4(adap->chip)) {
+       if (is_t4(adap->params.chip)) {
                mag_id_reg_l = PORT_REG(port, XGMAC_PORT_MAGIC_MACID_LO);
                mag_id_reg_h = PORT_REG(port, XGMAC_PORT_MAGIC_MACID_HI);
                port_cfg_reg = PORT_REG(port, XGMAC_PORT_CFG2);
@@ -2374,7 +2439,7 @@ int t4_wol_pat_enable(struct adapter *adap, unsigned int port, unsigned int map,
        int i;
        u32 port_cfg_reg;
 
-       if (is_t4(adap->chip))
+       if (is_t4(adap->params.chip))
                port_cfg_reg = PORT_REG(port, XGMAC_PORT_CFG2);
        else
                port_cfg_reg = T5_PORT_REG(port, MAC_PORT_CFG2);
@@ -2387,7 +2452,7 @@ int t4_wol_pat_enable(struct adapter *adap, unsigned int port, unsigned int map,
                return -EINVAL;
 
 #define EPIO_REG(name) \
-       (is_t4(adap->chip) ? PORT_REG(port, XGMAC_PORT_EPIO_##name) : \
+       (is_t4(adap->params.chip) ? PORT_REG(port, XGMAC_PORT_EPIO_##name) : \
        T5_PORT_REG(port, MAC_PORT_EPIO_##name))
 
        t4_write_reg(adap, EPIO_REG(DATA1), mask0 >> 32);
@@ -2474,7 +2539,7 @@ int t4_fwaddrspace_write(struct adapter *adap, unsigned int mbox,
 int t4_mem_win_read_len(struct adapter *adap, u32 addr, __be32 *data, int len)
 {
        int i, off;
-       u32 win_pf = is_t4(adap->chip) ? 0 : V_PFNUM(adap->fn);
+       u32 win_pf = is_t4(adap->params.chip) ? 0 : V_PFNUM(adap->fn);
 
        /* Align on a 2KB boundary.
         */
@@ -3306,7 +3371,7 @@ int t4_alloc_mac_filt(struct adapter *adap, unsigned int mbox,
        int i, ret;
        struct fw_vi_mac_cmd c;
        struct fw_vi_mac_exact *p;
-       unsigned int max_naddr = is_t4(adap->chip) ?
+       unsigned int max_naddr = is_t4(adap->params.chip) ?
                                       NUM_MPS_CLS_SRAM_L_INSTANCES :
                                       NUM_MPS_T5_CLS_SRAM_L_INSTANCES;
 
@@ -3368,7 +3433,7 @@ int t4_change_mac(struct adapter *adap, unsigned int mbox, unsigned int viid,
        int ret, mode;
        struct fw_vi_mac_cmd c;
        struct fw_vi_mac_exact *p = c.u.exact;
-       unsigned int max_mac_addr = is_t4(adap->chip) ?
+       unsigned int max_mac_addr = is_t4(adap->params.chip) ?
                                    NUM_MPS_CLS_SRAM_L_INSTANCES :
                                    NUM_MPS_T5_CLS_SRAM_L_INSTANCES;
 
@@ -3699,13 +3764,14 @@ int t4_prep_adapter(struct adapter *adapter)
 {
        int ret, ver;
        uint16_t device_id;
+       u32 pl_rev;
 
        ret = t4_wait_dev_ready(adapter);
        if (ret < 0)
                return ret;
 
        get_pci_mode(adapter, &adapter->params.pci);
-       adapter->params.rev = t4_read_reg(adapter, PL_REV);
+       pl_rev = G_REV(t4_read_reg(adapter, PL_REV));
 
        ret = get_flash_params(adapter);
        if (ret < 0) {
@@ -3717,14 +3783,13 @@ int t4_prep_adapter(struct adapter *adapter)
         */
        pci_read_config_word(adapter->pdev, PCI_DEVICE_ID, &device_id);
        ver = device_id >> 12;
+       adapter->params.chip = 0;
        switch (ver) {
        case CHELSIO_T4:
-               adapter->chip = CHELSIO_CHIP_CODE(CHELSIO_T4,
-                                                 adapter->params.rev);
+               adapter->params.chip |= CHELSIO_CHIP_CODE(CHELSIO_T4, pl_rev);
                break;
        case CHELSIO_T5:
-               adapter->chip = CHELSIO_CHIP_CODE(CHELSIO_T5,
-                                                 adapter->params.rev);
+               adapter->params.chip |= CHELSIO_CHIP_CODE(CHELSIO_T5, pl_rev);
                break;
        default:
                dev_err(adapter->pdev_dev, "Device %d is not supported\n",
@@ -3732,9 +3797,6 @@ int t4_prep_adapter(struct adapter *adapter)
                return -EINVAL;
        }
 
-       /* Reassign the updated revision field */
-       adapter->params.rev = adapter->chip;
-
        init_cong_ctrl(adapter->params.a_wnd, adapter->params.b_wnd);
 
        /*
index ef146c0ba4814ef5abff64794075b9d5e806c62b..0a8205d69d2c290aae4dbec30245c9dc3e18bd39 100644 (file)
 
 #define PL_REV 0x1943c
 
+#define S_REV    0
+#define M_REV    0xfU
+#define V_REV(x) ((x) << S_REV)
+#define G_REV(x) (((x) >> S_REV) & M_REV)
+
 #define LE_DB_CONFIG 0x19c04
 #define  HASHEN 0x00100000U
 
 #define EDC_STRIDE_T5 (EDC_T51_BASE_ADDR - EDC_T50_BASE_ADDR)
 #define EDC_REG_T5(reg, idx) (reg + EDC_STRIDE_T5 * idx)
 
+#define A_PL_VF_REV 0x4
+#define A_PL_VF_WHOAMI 0x0
+#define A_PL_VF_REVISION 0x8
+
+#define S_CHIPID    4
+#define M_CHIPID    0xfU
+#define V_CHIPID(x) ((x) << S_CHIPID)
+#define G_CHIPID(x) (((x) >> S_CHIPID) & M_CHIPID)
+
 #endif /* __T4_REGS_H */
index 6f77ac487743edfbe899f470805f58cc38d9c61b..74fea74ce0aa25a676045868fa0b48c4a3800860 100644 (file)
@@ -2157,7 +2157,7 @@ struct fw_debug_cmd {
 
 struct fw_hdr {
        u8 ver;
-       u8 reserved1;
+       u8 chip;                        /* terminator chip type */
        __be16  len512;                 /* bin length in units of 512-bytes */
        __be32  fw_ver;                 /* firmware version */
        __be32  tp_microcode_ver;
@@ -2176,6 +2176,11 @@ struct fw_hdr {
        __be32  reserved6[23];
 };
 
+enum fw_hdr_chip {
+       FW_HDR_CHIP_T4,
+       FW_HDR_CHIP_T5
+};
+
 #define FW_HDR_FW_VER_MAJOR_GET(x) (((x) >> 24) & 0xff)
 #define FW_HDR_FW_VER_MINOR_GET(x) (((x) >> 16) & 0xff)
 #define FW_HDR_FW_VER_MICRO_GET(x) (((x) >> 8) & 0xff)
index be5c7ef6ca939654365b6aec6dc108e03e0f74d9..68eaa9c88c7d8a77646bd217e00877a281254a59 100644 (file)
@@ -344,7 +344,6 @@ struct adapter {
        unsigned long registered_device_map;
        unsigned long open_device_map;
        unsigned long flags;
-       enum chip_type chip;
        struct adapter_params params;
 
        /* queue and interrupt resources */
index 5f90ec5f7519a4ac6e7916396cff31446f5c614b..0899c098359446346f7abe1939ac214705fd0acb 100644 (file)
@@ -1064,7 +1064,7 @@ static inline unsigned int mk_adap_vers(const struct adapter *adapter)
        /*
         * Chip version 4, revision 0x3f (cxgb4vf).
         */
-       return CHELSIO_CHIP_VERSION(adapter->chip) | (0x3f << 10);
+       return CHELSIO_CHIP_VERSION(adapter->params.chip) | (0x3f << 10);
 }
 
 /*
@@ -1551,9 +1551,13 @@ static void cxgb4vf_get_regs(struct net_device *dev,
        reg_block_dump(adapter, regbuf,
                       T4VF_MPS_BASE_ADDR + T4VF_MOD_MAP_MPS_FIRST,
                       T4VF_MPS_BASE_ADDR + T4VF_MOD_MAP_MPS_LAST);
+
+       /* T5 adds new registers in the PL Register map.
+        */
        reg_block_dump(adapter, regbuf,
                       T4VF_PL_BASE_ADDR + T4VF_MOD_MAP_PL_FIRST,
-                      T4VF_PL_BASE_ADDR + T4VF_MOD_MAP_PL_LAST);
+                      T4VF_PL_BASE_ADDR + (is_t4(adapter->params.chip)
+                      ? A_PL_VF_WHOAMI : A_PL_VF_REVISION));
        reg_block_dump(adapter, regbuf,
                       T4VF_CIM_BASE_ADDR + T4VF_MOD_MAP_CIM_FIRST,
                       T4VF_CIM_BASE_ADDR + T4VF_MOD_MAP_CIM_LAST);
@@ -2087,6 +2091,7 @@ static int adap_init0(struct adapter *adapter)
        unsigned int ethqsets;
        int err;
        u32 param, val = 0;
+       unsigned int chipid;
 
        /*
         * Wait for the device to become ready before proceeding ...
@@ -2114,12 +2119,14 @@ static int adap_init0(struct adapter *adapter)
                return err;
        }
 
+       adapter->params.chip = 0;
        switch (adapter->pdev->device >> 12) {
        case CHELSIO_T4:
-               adapter->chip = CHELSIO_CHIP_CODE(CHELSIO_T4, 0);
+               adapter->params.chip = CHELSIO_CHIP_CODE(CHELSIO_T4, 0);
                break;
        case CHELSIO_T5:
-               adapter->chip = CHELSIO_CHIP_CODE(CHELSIO_T5, 0);
+               chipid = G_REV(t4_read_reg(adapter, A_PL_VF_REV));
+               adapter->params.chip |= CHELSIO_CHIP_CODE(CHELSIO_T5, chipid);
                break;
        }
 
index 8475c4cda9e4ca72ef8a2b309788620e82fb67d3..0a89963c48ce78148d1abe6cd86151e850c24062 100644 (file)
@@ -537,7 +537,7 @@ static inline void ring_fl_db(struct adapter *adapter, struct sge_fl *fl)
         */
        if (fl->pend_cred >= FL_PER_EQ_UNIT) {
                val = PIDX(fl->pend_cred / FL_PER_EQ_UNIT);
-               if (!is_t4(adapter->chip))
+               if (!is_t4(adapter->params.chip))
                        val |= DBTYPE(1);
                wmb();
                t4_write_reg(adapter, T4VF_SGE_BASE_ADDR + SGE_VF_KDOORBELL,
index 53cbfed21d0b9871fe257ee75836dc2dadbdc185..61362450d05b4f83daeacf9a0c54ebed35e2da4c 100644 (file)
 #include "../cxgb4/t4fw_api.h"
 
 #define CHELSIO_CHIP_CODE(version, revision) (((version) << 4) | (revision))
-#define CHELSIO_CHIP_VERSION(code) ((code) >> 4)
+#define CHELSIO_CHIP_VERSION(code) (((code) >> 4) & 0xf)
 #define CHELSIO_CHIP_RELEASE(code) ((code) & 0xf)
 
+/* All T4 and later chips have their PCI-E Device IDs encoded as 0xVFPP where:
+ *
+ *   V  = "4" for T4; "5" for T5, etc. or
+ *      = "a" for T4 FPGA; "b" for T4 FPGA, etc.
+ *   F  = "0" for PF 0..3; "4".."7" for PF4..7; and "8" for VFs
+ *   PP = adapter product designation
+ */
 #define CHELSIO_T4             0x4
 #define CHELSIO_T5             0x5
 
 enum chip_type {
-       T4_A1 = CHELSIO_CHIP_CODE(CHELSIO_T4, 0),
-       T4_A2 = CHELSIO_CHIP_CODE(CHELSIO_T4, 1),
-       T4_A3 = CHELSIO_CHIP_CODE(CHELSIO_T4, 2),
+       T4_A1 = CHELSIO_CHIP_CODE(CHELSIO_T4, 1),
+       T4_A2 = CHELSIO_CHIP_CODE(CHELSIO_T4, 2),
        T4_FIRST_REV    = T4_A1,
-       T4_LAST_REV     = T4_A3,
+       T4_LAST_REV     = T4_A2,
 
-       T5_A1 = CHELSIO_CHIP_CODE(CHELSIO_T5, 0),
-       T5_FIRST_REV    = T5_A1,
+       T5_A0 = CHELSIO_CHIP_CODE(CHELSIO_T5, 0),
+       T5_A1 = CHELSIO_CHIP_CODE(CHELSIO_T5, 1),
+       T5_FIRST_REV    = T5_A0,
        T5_LAST_REV     = T5_A1,
 };
 
@@ -203,6 +210,7 @@ struct adapter_params {
        struct vpd_params vpd;          /* Vital Product Data */
        struct rss_params rss;          /* Receive Side Scaling */
        struct vf_resources vfres;      /* Virtual Function Resource limits */
+       enum chip_type chip;            /* chip code */
        u8 nports;                      /* # of Ethernet "ports" */
 };
 
@@ -253,7 +261,7 @@ static inline int t4vf_wr_mbox_ns(struct adapter *adapter, const void *cmd,
 
 static inline int is_t4(enum chip_type chip)
 {
-       return (chip >= T4_FIRST_REV && chip <= T4_LAST_REV);
+       return CHELSIO_CHIP_VERSION(chip) == CHELSIO_T4;
 }
 
 int t4vf_wait_dev_ready(struct adapter *);
index 9f96dc3bb11203e0781faa785d12ec31df4f76f3..d958c44341b5cb299d704600494de5be9d15bb72 100644 (file)
@@ -1027,7 +1027,7 @@ int t4vf_alloc_mac_filt(struct adapter *adapter, unsigned int viid, bool free,
        unsigned nfilters = 0;
        unsigned int rem = naddr;
        struct fw_vi_mac_cmd cmd, rpl;
-       unsigned int max_naddr = is_t4(adapter->chip) ?
+       unsigned int max_naddr = is_t4(adapter->params.chip) ?
                                 NUM_MPS_CLS_SRAM_L_INSTANCES :
                                 NUM_MPS_T5_CLS_SRAM_L_INSTANCES;
 
@@ -1121,7 +1121,7 @@ int t4vf_change_mac(struct adapter *adapter, unsigned int viid,
        struct fw_vi_mac_exact *p = &cmd.u.exact[0];
        size_t len16 = DIV_ROUND_UP(offsetof(struct fw_vi_mac_cmd,
                                             u.exact[1]), 16);
-       unsigned int max_naddr = is_t4(adapter->chip) ?
+       unsigned int max_naddr = is_t4(adapter->params.chip) ?
                                 NUM_MPS_CLS_SRAM_L_INSTANCES :
                                 NUM_MPS_T5_CLS_SRAM_L_INSTANCES;
 
index 3e2162121601e79481428c4d7ca02c3523dc0e33..dc88782185f26f000e4e58cd793f90f6064bbfb6 100644 (file)
@@ -64,6 +64,9 @@
 #define SLIPORT_ERROR_NO_RESOURCE1     0x2
 #define SLIPORT_ERROR_NO_RESOURCE2     0x9
 
+#define SLIPORT_ERROR_FW_RESET1                0x2
+#define SLIPORT_ERROR_FW_RESET2                0x0
+
 /********* Memory BAR register ************/
 #define PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET     0xfc
 /* Host Interrupt Enable, if set interrupts are enabled although "PCI Interrupt
index fee64bf10446092fa718caa12819e1be65ba0d6a..0fde69d5cb6afd610db5f2a57325e5d2e9f5ed94 100644 (file)
@@ -2464,8 +2464,16 @@ void be_detect_error(struct be_adapter *adapter)
         */
        if (sliport_status & SLIPORT_STATUS_ERR_MASK) {
                adapter->hw_error = true;
-               dev_err(&adapter->pdev->dev,
-                       "Error detected in the card\n");
+               /* Do not log error messages if its a FW reset */
+               if (sliport_err1 == SLIPORT_ERROR_FW_RESET1 &&
+                   sliport_err2 == SLIPORT_ERROR_FW_RESET2) {
+                       dev_info(&adapter->pdev->dev,
+                                "Firmware update in progress\n");
+                       return;
+               } else {
+                       dev_err(&adapter->pdev->dev,
+                               "Error detected in the card\n");
+               }
        }
 
        if (sliport_status & SLIPORT_STATUS_ERR_MASK) {
@@ -2932,28 +2940,35 @@ static void be_cancel_worker(struct be_adapter *adapter)
        }
 }
 
-static int be_clear(struct be_adapter *adapter)
+static void be_mac_clear(struct be_adapter *adapter)
 {
        int i;
 
+       if (adapter->pmac_id) {
+               for (i = 0; i < (adapter->uc_macs + 1); i++)
+                       be_cmd_pmac_del(adapter, adapter->if_handle,
+                                       adapter->pmac_id[i], 0);
+               adapter->uc_macs = 0;
+
+               kfree(adapter->pmac_id);
+               adapter->pmac_id = NULL;
+       }
+}
+
+static int be_clear(struct be_adapter *adapter)
+{
        be_cancel_worker(adapter);
 
        if (sriov_enabled(adapter))
                be_vf_clear(adapter);
 
        /* delete the primary mac along with the uc-mac list */
-       for (i = 0; i < (adapter->uc_macs + 1); i++)
-               be_cmd_pmac_del(adapter, adapter->if_handle,
-                               adapter->pmac_id[i], 0);
-       adapter->uc_macs = 0;
+       be_mac_clear(adapter);
 
        be_cmd_if_destroy(adapter, adapter->if_handle,  0);
 
        be_clear_queues(adapter);
 
-       kfree(adapter->pmac_id);
-       adapter->pmac_id = NULL;
-
        be_msix_disable(adapter);
        return 0;
 }
@@ -3812,6 +3827,8 @@ static int lancer_fw_download(struct be_adapter *adapter,
        }
 
        if (change_status == LANCER_FW_RESET_NEEDED) {
+               dev_info(&adapter->pdev->dev,
+                        "Resetting adapter to activate new FW\n");
                status = lancer_physdev_ctrl(adapter,
                                             PHYSDEV_CONTROL_FW_RESET_MASK);
                if (status) {
@@ -4363,13 +4380,13 @@ static int lancer_recover_func(struct be_adapter *adapter)
                        goto err;
        }
 
-       dev_err(dev, "Error recovery successful\n");
+       dev_err(dev, "Adapter recovery successful\n");
        return 0;
 err:
        if (status == -EAGAIN)
                dev_err(dev, "Waiting for resource provisioning\n");
        else
-               dev_err(dev, "Error recovery failed\n");
+               dev_err(dev, "Adapter recovery failed\n");
 
        return status;
 }
index 4cbebf3d80eb1492d847f1ad8a9888e2a6c17b97..e7c8b749c5a53f969096e3f442195d88f82597d7 100644 (file)
@@ -98,10 +98,6 @@ static void set_multicast_list(struct net_device *ndev);
  * detected as not set during a prior frame transmission, then the
  * ENET_TDAR[TDAR] bit is cleared at a later time, even if additional TxBDs
  * were added to the ring and the ENET_TDAR[TDAR] bit is set. This results in
- * If the ready bit in the transmit buffer descriptor (TxBD[R]) is previously
- * detected as not set during a prior frame transmission, then the
- * ENET_TDAR[TDAR] bit is cleared at a later time, even if additional TxBDs
- * were added to the ring and the ENET_TDAR[TDAR] bit is set. This results in
  * frames not being transmitted until there is a 0-to-1 transition on
  * ENET_TDAR[TDAR].
  */
@@ -385,7 +381,7 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
         * data.
         */
        bdp->cbd_bufaddr = dma_map_single(&fep->pdev->dev, bufaddr,
-                       FEC_ENET_TX_FRSIZE, DMA_TO_DEVICE);
+                       skb->len, DMA_TO_DEVICE);
        if (dma_mapping_error(&fep->pdev->dev, bdp->cbd_bufaddr)) {
                bdp->cbd_bufaddr = 0;
                fep->tx_skbuff[index] = NULL;
@@ -779,11 +775,10 @@ fec_enet_tx(struct net_device *ndev)
                else
                        index = bdp - fep->tx_bd_base;
 
-               dma_unmap_single(&fep->pdev->dev, bdp->cbd_bufaddr,
-                               FEC_ENET_TX_FRSIZE, DMA_TO_DEVICE);
-               bdp->cbd_bufaddr = 0;
-
                skb = fep->tx_skbuff[index];
+               dma_unmap_single(&fep->pdev->dev, bdp->cbd_bufaddr, skb->len,
+                               DMA_TO_DEVICE);
+               bdp->cbd_bufaddr = 0;
 
                /* Check for errors. */
                if (status & (BD_ENET_TX_HB | BD_ENET_TX_LC |
index 2d1c6bdd36189f9f595ada15599301ce992330a9..7628e0fd84554fd56eca5f4181f2ff31c85eca0d 100644 (file)
@@ -3033,7 +3033,7 @@ static struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter,
 
        dev->hw_features = NETIF_F_SG | NETIF_F_TSO |
                      NETIF_F_IP_CSUM | NETIF_F_HW_VLAN_CTAG_TX;
-       dev->features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_TSO |
+       dev->features = NETIF_F_SG | NETIF_F_TSO |
                      NETIF_F_HIGHDMA | NETIF_F_IP_CSUM |
                      NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX |
                      NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_RXCSUM;
index be15938ba2130372192276670e1621c3e470505c..12b0932204ba8ce425109714053d4bebbddc65b6 100644 (file)
@@ -354,6 +354,9 @@ static struct rtnl_link_stats64 *i40e_get_netdev_stats_struct(
        struct rtnl_link_stats64 *vsi_stats = i40e_get_vsi_stats_struct(vsi);
        int i;
 
+       if (!vsi->tx_rings)
+               return stats;
+
        rcu_read_lock();
        for (i = 0; i < vsi->num_queue_pairs; i++) {
                struct i40e_ring *tx_ring, *rx_ring;
index c4c4fe332c7ee06af09696cc8e5ba027d6d9ba15..ad2b74d95138c1542bb78a55b7d620e5695f2abb 100644 (file)
@@ -1728,7 +1728,10 @@ s32 igb_phy_has_link(struct e1000_hw *hw, u32 iterations,
                         * ownership of the resources, wait and try again to
                         * see if they have relinquished the resources yet.
                         */
-                       udelay(usec_interval);
+                       if (usec_interval >= 1000)
+                               mdelay(usec_interval/1000);
+                       else
+                               udelay(usec_interval);
                }
                ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status);
                if (ret_val)
index b8e232b4ea2da88aca164039f81f1852ba9f779e..d5f0d72e5e331792bb8a0078078627df66a83fb5 100644 (file)
@@ -1378,7 +1378,7 @@ static void mvneta_rxq_drop_pkts(struct mvneta_port *pp,
 
                dev_kfree_skb_any(skb);
                dma_unmap_single(pp->dev->dev.parent, rx_desc->buf_phys_addr,
-                                rx_desc->data_size, DMA_FROM_DEVICE);
+                                MVNETA_RX_BUF_SIZE(pp->pkt_size), DMA_FROM_DEVICE);
        }
 
        if (rx_done)
@@ -1424,7 +1424,7 @@ static int mvneta_rx(struct mvneta_port *pp, int rx_todo,
                }
 
                dma_unmap_single(pp->dev->dev.parent, rx_desc->buf_phys_addr,
-                                rx_desc->data_size, DMA_FROM_DEVICE);
+                                MVNETA_RX_BUF_SIZE(pp->pkt_size), DMA_FROM_DEVICE);
 
                rx_bytes = rx_desc->data_size -
                        (ETH_FCS_LEN + MVNETA_MH_SIZE);
index 5789ea2c934d4aaa15218bdaea2d565f42a82b41..01fc6515384db04fe03d548db8c16f8952f211e4 100644 (file)
@@ -2635,6 +2635,8 @@ static int __init mlx4_init(void)
                return -ENOMEM;
 
        ret = pci_register_driver(&mlx4_driver);
+       if (ret < 0)
+               destroy_workqueue(mlx4_wq);
        return ret < 0 ? ret : 0;
 }
 
index 2d045be4b5cf64a5921a6687b127609093df376e..1e8b9514718b8620859bc38025dbb878878dd0c0 100644 (file)
@@ -5150,8 +5150,10 @@ static void nv_self_test(struct net_device *dev, struct ethtool_test *test, u64
 {
        struct fe_priv *np = netdev_priv(dev);
        u8 __iomem *base = get_hwbase(dev);
-       int result;
-       memset(buffer, 0, nv_get_sset_count(dev, ETH_SS_TEST)*sizeof(u64));
+       int result, count;
+
+       count = nv_get_sset_count(dev, ETH_SS_TEST);
+       memset(buffer, 0, count * sizeof(u64));
 
        if (!nv_link_test(dev)) {
                test->flags |= ETH_TEST_FL_FAILED;
@@ -5195,7 +5197,7 @@ static void nv_self_test(struct net_device *dev, struct ethtool_test *test, u64
                        return;
                }
 
-               if (!nv_loopback_test(dev)) {
+               if (count > NV_TEST_COUNT_BASE && !nv_loopback_test(dev)) {
                        test->flags |= ETH_TEST_FL_FAILED;
                        buffer[3] = 1;
                }
index b1cb0ffb15c70d1970f3cbebab28ff7f8e8530ce..6055d397a29edf70317299e83966aba18b6ff5dc 100644 (file)
@@ -447,8 +447,9 @@ irqreturn_t qlcnic_83xx_intr(int irq, void *data)
 
        qlcnic_83xx_poll_process_aen(adapter);
 
-       if (ahw->diag_test == QLCNIC_INTERRUPT_TEST) {
-               ahw->diag_cnt++;
+       if (ahw->diag_test) {
+               if (ahw->diag_test == QLCNIC_INTERRUPT_TEST)
+                       ahw->diag_cnt++;
                qlcnic_83xx_enable_legacy_msix_mbx_intr(adapter);
                return IRQ_HANDLED;
        }
@@ -1345,11 +1346,6 @@ static int qlcnic_83xx_diag_alloc_res(struct net_device *netdev, int test,
        }
 
        if (adapter->ahw->diag_test == QLCNIC_LOOPBACK_TEST) {
-               /* disable and free mailbox interrupt */
-               if (!(adapter->flags & QLCNIC_MSIX_ENABLED)) {
-                       qlcnic_83xx_enable_mbx_poll(adapter);
-                       qlcnic_83xx_free_mbx_intr(adapter);
-               }
                adapter->ahw->loopback_state = 0;
                adapter->ahw->hw_ops->setup_link_event(adapter, 1);
        }
@@ -1363,33 +1359,20 @@ static void qlcnic_83xx_diag_free_res(struct net_device *netdev,
 {
        struct qlcnic_adapter *adapter = netdev_priv(netdev);
        struct qlcnic_host_sds_ring *sds_ring;
-       int ring, err;
+       int ring;
 
        clear_bit(__QLCNIC_DEV_UP, &adapter->state);
        if (adapter->ahw->diag_test == QLCNIC_INTERRUPT_TEST) {
                for (ring = 0; ring < adapter->drv_sds_rings; ring++) {
                        sds_ring = &adapter->recv_ctx->sds_rings[ring];
-                       qlcnic_83xx_disable_intr(adapter, sds_ring);
-                       if (!(adapter->flags & QLCNIC_MSIX_ENABLED))
-                               qlcnic_83xx_enable_mbx_poll(adapter);
+                       if (adapter->flags & QLCNIC_MSIX_ENABLED)
+                               qlcnic_83xx_disable_intr(adapter, sds_ring);
                }
        }
 
        qlcnic_fw_destroy_ctx(adapter);
        qlcnic_detach(adapter);
 
-       if (adapter->ahw->diag_test == QLCNIC_LOOPBACK_TEST) {
-               if (!(adapter->flags & QLCNIC_MSIX_ENABLED)) {
-                       err = qlcnic_83xx_setup_mbx_intr(adapter);
-                       qlcnic_83xx_disable_mbx_poll(adapter);
-                       if (err) {
-                               dev_err(&adapter->pdev->dev,
-                                       "%s: failed to setup mbx interrupt\n",
-                                       __func__);
-                               goto out;
-                       }
-               }
-       }
        adapter->ahw->diag_test = 0;
        adapter->drv_sds_rings = drv_sds_rings;
 
@@ -1399,9 +1382,6 @@ static void qlcnic_83xx_diag_free_res(struct net_device *netdev,
        if (netif_running(netdev))
                __qlcnic_up(adapter, netdev);
 
-       if (adapter->ahw->diag_test == QLCNIC_INTERRUPT_TEST &&
-           !(adapter->flags & QLCNIC_MSIX_ENABLED))
-               qlcnic_83xx_disable_mbx_poll(adapter);
 out:
        netif_device_attach(netdev);
 }
@@ -3754,6 +3734,19 @@ static void qlcnic_83xx_decode_mbx_rsp(struct qlcnic_adapter *adapter,
        return;
 }
 
+static inline void qlcnic_dump_mailbox_registers(struct qlcnic_adapter *adapter)
+{
+       struct qlcnic_hardware_context *ahw = adapter->ahw;
+       u32 offset;
+
+       offset = QLCRDX(ahw, QLCNIC_DEF_INT_MASK);
+       dev_info(&adapter->pdev->dev, "Mbx interrupt mask=0x%x, Mbx interrupt enable=0x%x, Host mbx control=0x%x, Fw mbx control=0x%x",
+                readl(ahw->pci_base0 + offset),
+                QLCRDX(ahw, QLCNIC_MBX_INTR_ENBL),
+                QLCRDX(ahw, QLCNIC_HOST_MBX_CTRL),
+                QLCRDX(ahw, QLCNIC_FW_MBX_CTRL));
+}
+
 static void qlcnic_83xx_mailbox_worker(struct work_struct *work)
 {
        struct qlcnic_mailbox *mbx = container_of(work, struct qlcnic_mailbox,
@@ -3798,6 +3791,8 @@ static void qlcnic_83xx_mailbox_worker(struct work_struct *work)
                                __func__, cmd->cmd_op, cmd->type, ahw->pci_func,
                                ahw->op_mode);
                        clear_bit(QLC_83XX_MBX_READY, &mbx->status);
+                       qlcnic_dump_mailbox_registers(adapter);
+                       qlcnic_83xx_get_mbx_data(adapter, cmd);
                        qlcnic_dump_mbx(adapter, cmd);
                        qlcnic_83xx_idc_request_reset(adapter,
                                                      QLCNIC_FORCE_FW_DUMP_KEY);
index 4cae6caa6bfa42476ff79b881784dd2f42a36db6..a6a33508e40137b124541f07e3433361b086afec 100644 (file)
@@ -662,4 +662,5 @@ pci_ers_result_t qlcnic_83xx_io_error_detected(struct pci_dev *,
                                               pci_channel_state_t);
 pci_ers_result_t qlcnic_83xx_io_slot_reset(struct pci_dev *);
 void qlcnic_83xx_io_resume(struct pci_dev *);
+void qlcnic_83xx_stop_hw(struct qlcnic_adapter *);
 #endif
index 89208e5b25d6a1bc5c829a52ea2d79edcb5d110e..918e18ddf0381acd2f8a3097603ec6bd914fc5a8 100644 (file)
@@ -740,6 +740,7 @@ static int qlcnic_83xx_idc_unknown_state(struct qlcnic_adapter *adapter)
        adapter->ahw->idc.err_code = -EIO;
        dev_err(&adapter->pdev->dev,
                "%s: Device in unknown state\n", __func__);
+       clear_bit(__QLCNIC_RESETTING, &adapter->state);
        return 0;
 }
 
@@ -818,7 +819,6 @@ static int qlcnic_83xx_idc_ready_state(struct qlcnic_adapter *adapter)
        struct qlcnic_hardware_context *ahw = adapter->ahw;
        struct qlcnic_mailbox *mbx = ahw->mailbox;
        int ret = 0;
-       u32 owner;
        u32 val;
 
        /* Perform NIC configuration based ready state entry actions */
@@ -848,9 +848,9 @@ static int qlcnic_83xx_idc_ready_state(struct qlcnic_adapter *adapter)
                        set_bit(__QLCNIC_RESETTING, &adapter->state);
                        qlcnic_83xx_idc_enter_need_reset_state(adapter, 1);
                }  else {
-                       owner = qlcnic_83xx_idc_find_reset_owner_id(adapter);
-                       if (ahw->pci_func == owner)
-                               qlcnic_dump_fw(adapter);
+                       netdev_info(adapter->netdev, "%s: Auto firmware recovery is disabled\n",
+                                   __func__);
+                       qlcnic_83xx_idc_enter_failed_state(adapter, 1);
                }
                return -EIO;
        }
@@ -948,13 +948,26 @@ static int qlcnic_83xx_idc_need_quiesce_state(struct qlcnic_adapter *adapter)
        return 0;
 }
 
-static int qlcnic_83xx_idc_failed_state(struct qlcnic_adapter *adapter)
+static void qlcnic_83xx_idc_failed_state(struct qlcnic_adapter *adapter)
 {
-       dev_err(&adapter->pdev->dev, "%s: please restart!!\n", __func__);
+       struct qlcnic_hardware_context *ahw = adapter->ahw;
+       u32 val, owner;
+
+       val = QLCRDX(adapter->ahw, QLC_83XX_IDC_CTRL);
+       if (val & QLC_83XX_IDC_DISABLE_FW_RESET_RECOVERY) {
+               owner = qlcnic_83xx_idc_find_reset_owner_id(adapter);
+               if (ahw->pci_func == owner) {
+                       qlcnic_83xx_stop_hw(adapter);
+                       qlcnic_dump_fw(adapter);
+               }
+       }
+
+       netdev_warn(adapter->netdev, "%s: Reboot will be required to recover the adapter!!\n",
+                   __func__);
        clear_bit(__QLCNIC_RESETTING, &adapter->state);
-       adapter->ahw->idc.err_code = -EIO;
+       ahw->idc.err_code = -EIO;
 
-       return 0;
+       return;
 }
 
 static int qlcnic_83xx_idc_quiesce_state(struct qlcnic_adapter *adapter)
@@ -1063,12 +1076,6 @@ void qlcnic_83xx_idc_poll_dev_state(struct work_struct *work)
        adapter->ahw->idc.prev_state = adapter->ahw->idc.curr_state;
        qlcnic_83xx_periodic_tasks(adapter);
 
-       /* Do not reschedule if firmaware is in hanged state and auto
-        * recovery is disabled
-        */
-       if ((adapter->flags & QLCNIC_FW_HANG) && !qlcnic_auto_fw_reset)
-               return;
-
        /* Re-schedule the function */
        if (test_bit(QLC_83XX_MODULE_LOADED, &adapter->ahw->idc.status))
                qlcnic_schedule_work(adapter, qlcnic_83xx_idc_poll_dev_state,
@@ -1219,10 +1226,10 @@ void qlcnic_83xx_idc_request_reset(struct qlcnic_adapter *adapter, u32 key)
        }
 
        val = QLCRDX(adapter->ahw, QLC_83XX_IDC_CTRL);
-       if ((val & QLC_83XX_IDC_DISABLE_FW_RESET_RECOVERY) ||
-           !qlcnic_auto_fw_reset) {
-               dev_err(&adapter->pdev->dev,
-                       "%s:failed, device in non reset mode\n", __func__);
+       if (val & QLC_83XX_IDC_DISABLE_FW_RESET_RECOVERY) {
+               netdev_info(adapter->netdev, "%s: Auto firmware recovery is disabled\n",
+                           __func__);
+               qlcnic_83xx_idc_enter_failed_state(adapter, 0);
                qlcnic_83xx_unlock_driver(adapter);
                return;
        }
@@ -1254,24 +1261,24 @@ static int qlcnic_83xx_copy_bootloader(struct qlcnic_adapter *adapter)
        if (size & 0xF)
                size = (size + 16) & ~0xF;
 
-       p_cache = kzalloc(size, GFP_KERNEL);
+       p_cache = vzalloc(size);
        if (p_cache == NULL)
                return -ENOMEM;
 
        ret = qlcnic_83xx_lockless_flash_read32(adapter, src, p_cache,
                                                size / sizeof(u32));
        if (ret) {
-               kfree(p_cache);
+               vfree(p_cache);
                return ret;
        }
        /* 16 byte write to MS memory */
        ret = qlcnic_83xx_ms_mem_write128(adapter, dest, (u32 *)p_cache,
                                          size / 16);
        if (ret) {
-               kfree(p_cache);
+               vfree(p_cache);
                return ret;
        }
-       kfree(p_cache);
+       vfree(p_cache);
 
        return ret;
 }
@@ -1939,7 +1946,7 @@ static void qlcnic_83xx_exec_template_cmd(struct qlcnic_adapter *p_dev,
        p_dev->ahw->reset.seq_index = index;
 }
 
-static void qlcnic_83xx_stop_hw(struct qlcnic_adapter *p_dev)
+void qlcnic_83xx_stop_hw(struct qlcnic_adapter *p_dev)
 {
        p_dev->ahw->reset.seq_index = 0;
 
@@ -1994,6 +2001,14 @@ static int qlcnic_83xx_restart_hw(struct qlcnic_adapter *adapter)
        val = QLCRDX(adapter->ahw, QLC_83XX_IDC_CTRL);
        if (!(val & QLC_83XX_IDC_GRACEFULL_RESET))
                qlcnic_dump_fw(adapter);
+
+       if (val & QLC_83XX_IDC_DISABLE_FW_RESET_RECOVERY) {
+               netdev_info(adapter->netdev, "%s: Auto firmware recovery is disabled\n",
+                           __func__);
+               qlcnic_83xx_idc_enter_failed_state(adapter, 1);
+               return err;
+       }
+
        qlcnic_83xx_init_hw(adapter);
 
        if (qlcnic_83xx_copy_bootloader(adapter))
@@ -2073,8 +2088,8 @@ int qlcnic_83xx_configure_opmode(struct qlcnic_adapter *adapter)
                ahw->nic_mode = QLCNIC_DEFAULT_MODE;
                adapter->nic_ops->init_driver = qlcnic_83xx_init_default_driver;
                ahw->idc.state_entry = qlcnic_83xx_idc_ready_state_entry;
-               adapter->max_sds_rings = ahw->max_rx_ques;
-               adapter->max_tx_rings = ahw->max_tx_ques;
+               adapter->max_sds_rings = QLCNIC_MAX_SDS_RINGS;
+               adapter->max_tx_rings = QLCNIC_MAX_TX_RINGS;
        } else {
                return -EIO;
        }
index b36c02fafcfd1ebe6f6ce8da49e73f73364f64b5..e3be2760665cd9e0781dc967a813fd1976778c3e 100644 (file)
@@ -667,30 +667,25 @@ qlcnic_set_ringparam(struct net_device *dev,
 static int qlcnic_validate_ring_count(struct qlcnic_adapter *adapter,
                                      u8 rx_ring, u8 tx_ring)
 {
+       if (rx_ring == 0 || tx_ring == 0)
+               return -EINVAL;
+
        if (rx_ring != 0) {
                if (rx_ring > adapter->max_sds_rings) {
-                       netdev_err(adapter->netdev, "Invalid ring count, SDS ring count %d should not be greater than max %d driver sds rings.\n",
+                       netdev_err(adapter->netdev,
+                                  "Invalid ring count, SDS ring count %d should not be greater than max %d driver sds rings.\n",
                                   rx_ring, adapter->max_sds_rings);
                        return -EINVAL;
                }
        }
 
         if (tx_ring != 0) {
-               if (qlcnic_82xx_check(adapter) &&
-                   (tx_ring > adapter->max_tx_rings)) {
+               if (tx_ring > adapter->max_tx_rings) {
                        netdev_err(adapter->netdev,
                                   "Invalid ring count, Tx ring count %d should not be greater than max %d driver Tx rings.\n",
                                   tx_ring, adapter->max_tx_rings);
                        return -EINVAL;
                }
-
-               if (qlcnic_83xx_check(adapter) &&
-                   (tx_ring > QLCNIC_SINGLE_RING)) {
-                       netdev_err(adapter->netdev,
-                                  "Invalid ring count, Tx ring count %d should not be greater than %d driver Tx rings.\n",
-                                  tx_ring, QLCNIC_SINGLE_RING);
-                        return -EINVAL;
-               }
        }
 
        return 0;
@@ -948,6 +943,7 @@ static int qlcnic_irq_test(struct net_device *netdev)
        struct qlcnic_hardware_context *ahw = adapter->ahw;
        struct qlcnic_cmd_args cmd;
        int ret, drv_sds_rings = adapter->drv_sds_rings;
+       int drv_tx_rings = adapter->drv_tx_rings;
 
        if (qlcnic_83xx_check(adapter))
                return qlcnic_83xx_interrupt_test(netdev);
@@ -980,6 +976,7 @@ free_diag_res:
 
 clear_diag_irq:
        adapter->drv_sds_rings = drv_sds_rings;
+       adapter->drv_tx_rings = drv_tx_rings;
        clear_bit(__QLCNIC_RESETTING, &adapter->state);
 
        return ret;
index 0149c94953474e6ad0ffd56b93cc440c67e77687..eda6c691d8970418ae14eb67db450a87314aa882 100644 (file)
@@ -687,17 +687,11 @@ void qlcnic_advert_link_change(struct qlcnic_adapter *adapter, int linkup)
        if (adapter->ahw->linkup && !linkup) {
                netdev_info(netdev, "NIC Link is down\n");
                adapter->ahw->linkup = 0;
-               if (netif_running(netdev)) {
-                       netif_carrier_off(netdev);
-                       netif_tx_stop_all_queues(netdev);
-               }
+               netif_carrier_off(netdev);
        } else if (!adapter->ahw->linkup && linkup) {
                netdev_info(netdev, "NIC Link is up\n");
                adapter->ahw->linkup = 1;
-               if (netif_running(netdev)) {
-                       netif_carrier_on(netdev);
-                       netif_wake_queue(netdev);
-               }
+               netif_carrier_on(netdev);
        }
 }
 
index 05c1eef8df1325359ef1bf73df8344492a95876d..2c8cac0c6a55a7e9a32541c4f88e7d0ddcd5a977 100644 (file)
@@ -1178,6 +1178,7 @@ qlcnic_initialize_nic(struct qlcnic_adapter *adapter)
        } else {
                adapter->ahw->nic_mode = QLCNIC_DEFAULT_MODE;
                adapter->max_tx_rings = QLCNIC_MAX_HW_TX_RINGS;
+               adapter->max_sds_rings = QLCNIC_MAX_SDS_RINGS;
                adapter->flags &= ~QLCNIC_ESWITCH_ENABLED;
        }
 
@@ -1940,7 +1941,6 @@ int qlcnic_diag_alloc_res(struct net_device *netdev, int test)
        qlcnic_detach(adapter);
 
        adapter->drv_sds_rings = QLCNIC_SINGLE_RING;
-       adapter->drv_tx_rings = QLCNIC_SINGLE_RING;
        adapter->ahw->diag_test = test;
        adapter->ahw->linkup = 0;
 
index 0c9c4e89559524d78aa789dfb65e5e32211b8bc1..03517478e589495dd763a13eaab31101a9ea0a08 100644 (file)
@@ -18,7 +18,7 @@
  */
 #define DRV_NAME       "qlge"
 #define DRV_STRING     "QLogic 10 Gigabit PCI-E Ethernet Driver "
-#define DRV_VERSION    "1.00.00.33"
+#define DRV_VERSION    "1.00.00.34"
 
 #define WQ_ADDR_ALIGN  0x3     /* 4 byte alignment */
 
index 0780e039b2718d902805414daeb6844b7d2086e7..8dee1beb9854813c94c1de36264a241703f9d0be 100644 (file)
@@ -181,6 +181,7 @@ static const char ql_gstrings_test[][ETH_GSTRING_LEN] = {
 };
 #define QLGE_TEST_LEN (sizeof(ql_gstrings_test) / ETH_GSTRING_LEN)
 #define QLGE_STATS_LEN ARRAY_SIZE(ql_gstrings_stats)
+#define QLGE_RCV_MAC_ERR_STATS 7
 
 static int ql_update_ring_coalescing(struct ql_adapter *qdev)
 {
@@ -280,6 +281,9 @@ static void ql_update_stats(struct ql_adapter *qdev)
                iter++;
        }
 
+       /* Update receive mac error statistics */
+       iter += QLGE_RCV_MAC_ERR_STATS;
+
        /*
         * Get Per-priority TX pause frame counter statistics.
         */
index a245dc18d769241bcf23d607458e33538c7ee99c..449f506d2e8ff3e71abc22bba6ce8e67bcf45305 100644 (file)
@@ -2376,14 +2376,6 @@ static netdev_features_t qlge_fix_features(struct net_device *ndev,
        netdev_features_t features)
 {
        int err;
-       /*
-        * Since there is no support for separate rx/tx vlan accel
-        * enable/disable make sure tx flag is always in same state as rx.
-        */
-       if (features & NETIF_F_HW_VLAN_CTAG_RX)
-               features |= NETIF_F_HW_VLAN_CTAG_TX;
-       else
-               features &= ~NETIF_F_HW_VLAN_CTAG_TX;
 
        /* Update the behavior of vlan accel in the adapter */
        err = qlge_update_hw_vlan_features(ndev, features);
index 2e27837ce6a289dc033c806e613f8dbca42496b9..fd844b53e38565cffa3e267fe0229f01f522a0d6 100644 (file)
@@ -585,7 +585,7 @@ static void efx_start_datapath(struct efx_nic *efx)
                           EFX_MAX_FRAME_LEN(efx->net_dev->mtu) +
                           efx->type->rx_buffer_padding);
        rx_buf_len = (sizeof(struct efx_rx_page_state) +
-                     NET_IP_ALIGN + efx->rx_dma_len);
+                     efx->rx_ip_align + efx->rx_dma_len);
        if (rx_buf_len <= PAGE_SIZE) {
                efx->rx_scatter = efx->type->always_rx_scatter;
                efx->rx_buffer_order = 0;
@@ -645,6 +645,8 @@ static void efx_start_datapath(struct efx_nic *efx)
                WARN_ON(channel->rx_pkt_n_frags);
        }
 
+       efx_ptp_start_datapath(efx);
+
        if (netif_device_present(efx->net_dev))
                netif_tx_wake_all_queues(efx->net_dev);
 }
@@ -659,6 +661,8 @@ static void efx_stop_datapath(struct efx_nic *efx)
        EFX_ASSERT_RESET_SERIALISED(efx);
        BUG_ON(efx->port_enabled);
 
+       efx_ptp_stop_datapath(efx);
+
        /* Stop RX refill */
        efx_for_each_channel(channel, efx) {
                efx_for_each_channel_rx_queue(rx_queue, channel)
@@ -2540,6 +2544,8 @@ static int efx_init_struct(struct efx_nic *efx,
 
        efx->net_dev = net_dev;
        efx->rx_prefix_size = efx->type->rx_prefix_size;
+       efx->rx_ip_align =
+               NET_IP_ALIGN ? (efx->rx_prefix_size + NET_IP_ALIGN) % 4 : 0;
        efx->rx_packet_hash_offset =
                efx->type->rx_hash_offset - efx->type->rx_prefix_size;
        spin_lock_init(&efx->stats_lock);
index 366c8e3e37844c8e2d8840a4662467067e937b3b..4b0bd8a1514dbb7035c7c0562cefc072901e585c 100644 (file)
@@ -50,6 +50,7 @@ struct efx_mcdi_async_param {
 static void efx_mcdi_timeout_async(unsigned long context);
 static int efx_mcdi_drv_attach(struct efx_nic *efx, bool driver_operating,
                               bool *was_attached_out);
+static bool efx_mcdi_poll_once(struct efx_nic *efx);
 
 static inline struct efx_mcdi_iface *efx_mcdi(struct efx_nic *efx)
 {
@@ -237,6 +238,21 @@ static void efx_mcdi_read_response_header(struct efx_nic *efx)
        }
 }
 
+static bool efx_mcdi_poll_once(struct efx_nic *efx)
+{
+       struct efx_mcdi_iface *mcdi = efx_mcdi(efx);
+
+       rmb();
+       if (!efx->type->mcdi_poll_response(efx))
+               return false;
+
+       spin_lock_bh(&mcdi->iface_lock);
+       efx_mcdi_read_response_header(efx);
+       spin_unlock_bh(&mcdi->iface_lock);
+
+       return true;
+}
+
 static int efx_mcdi_poll(struct efx_nic *efx)
 {
        struct efx_mcdi_iface *mcdi = efx_mcdi(efx);
@@ -272,18 +288,13 @@ static int efx_mcdi_poll(struct efx_nic *efx)
 
                time = jiffies;
 
-               rmb();
-               if (efx->type->mcdi_poll_response(efx))
+               if (efx_mcdi_poll_once(efx))
                        break;
 
                if (time_after(time, finish))
                        return -ETIMEDOUT;
        }
 
-       spin_lock_bh(&mcdi->iface_lock);
-       efx_mcdi_read_response_header(efx);
-       spin_unlock_bh(&mcdi->iface_lock);
-
        /* Return rc=0 like wait_event_timeout() */
        return 0;
 }
@@ -619,6 +630,16 @@ int efx_mcdi_rpc_finish(struct efx_nic *efx, unsigned cmd, size_t inlen,
                rc = efx_mcdi_await_completion(efx);
 
        if (rc != 0) {
+               netif_err(efx, hw, efx->net_dev,
+                         "MC command 0x%x inlen %d mode %d timed out\n",
+                         cmd, (int)inlen, mcdi->mode);
+
+               if (mcdi->mode == MCDI_MODE_EVENTS && efx_mcdi_poll_once(efx)) {
+                       netif_err(efx, hw, efx->net_dev,
+                                 "MCDI request was completed without an event\n");
+                       rc = 0;
+               }
+
                /* Close the race with efx_mcdi_ev_cpl() executing just too late
                 * and completing a request we've just cancelled, by ensuring
                 * that the seqno check therein fails.
@@ -627,11 +648,9 @@ int efx_mcdi_rpc_finish(struct efx_nic *efx, unsigned cmd, size_t inlen,
                ++mcdi->seqno;
                ++mcdi->credits;
                spin_unlock_bh(&mcdi->iface_lock);
+       }
 
-               netif_err(efx, hw, efx->net_dev,
-                         "MC command 0x%x inlen %d mode %d timed out\n",
-                         cmd, (int)inlen, mcdi->mode);
-       } else {
+       if (rc == 0) {
                size_t hdr_len, data_len;
 
                /* At the very least we need a memory barrier here to ensure
index b14a717ac3e8d95099b5d2648be590e138bc9e61..542a0d252ae0c25f6c60167c1ec9dba3943ba3d8 100644 (file)
@@ -683,6 +683,8 @@ struct vfdi_status;
  * @n_channels: Number of channels in use
  * @n_rx_channels: Number of channels used for RX (= number of RX queues)
  * @n_tx_channels: Number of channels used for TX
+ * @rx_ip_align: RX DMA address offset to have IP header aligned in
+ *     in accordance with NET_IP_ALIGN
  * @rx_dma_len: Current maximum RX DMA length
  * @rx_buffer_order: Order (log2) of number of pages for each RX buffer
  * @rx_buffer_truesize: Amortised allocation size of an RX buffer,
@@ -816,6 +818,7 @@ struct efx_nic {
        unsigned rss_spread;
        unsigned tx_channel_offset;
        unsigned n_tx_channels;
+       unsigned int rx_ip_align;
        unsigned int rx_dma_len;
        unsigned int rx_buffer_order;
        unsigned int rx_buffer_truesize;
index 11b6112d9249a734701eebe66414bd039702bcdd..91c63ec79c5fcb21d96545c0a6bad98e58cce5b9 100644 (file)
@@ -560,6 +560,8 @@ void efx_ptp_get_ts_info(struct efx_nic *efx, struct ethtool_ts_info *ts_info);
 bool efx_ptp_is_ptp_tx(struct efx_nic *efx, struct sk_buff *skb);
 int efx_ptp_tx(struct efx_nic *efx, struct sk_buff *skb);
 void efx_ptp_event(struct efx_nic *efx, efx_qword_t *ev);
+void efx_ptp_start_datapath(struct efx_nic *efx);
+void efx_ptp_stop_datapath(struct efx_nic *efx);
 
 extern const struct efx_nic_type falcon_a1_nic_type;
 extern const struct efx_nic_type falcon_b0_nic_type;
index 03acf57df04579bed5d0986f735f807491248cfb..3dd39dcfe36b92f3221119171b1e0c26729d85e8 100644 (file)
@@ -220,6 +220,7 @@ struct efx_ptp_timeset {
  * @evt_list: List of MC receive events awaiting packets
  * @evt_free_list: List of free events
  * @evt_lock: Lock for manipulating evt_list and evt_free_list
+ * @evt_overflow: Boolean indicating that event list has overflowed
  * @rx_evts: Instantiated events (on evt_list and evt_free_list)
  * @workwq: Work queue for processing pending PTP operations
  * @work: Work task
@@ -270,6 +271,7 @@ struct efx_ptp_data {
        struct list_head evt_list;
        struct list_head evt_free_list;
        spinlock_t evt_lock;
+       bool evt_overflow;
        struct efx_ptp_event_rx rx_evts[MAX_RECEIVE_EVENTS];
        struct workqueue_struct *workwq;
        struct work_struct work;
@@ -635,6 +637,11 @@ static void efx_ptp_drop_time_expired_events(struct efx_nic *efx)
                        }
                }
        }
+       /* If the event overflow flag is set and the event list is now empty
+        * clear the flag to re-enable the overflow warning message.
+        */
+       if (ptp->evt_overflow && list_empty(&ptp->evt_list))
+               ptp->evt_overflow = false;
        spin_unlock_bh(&ptp->evt_lock);
 }
 
@@ -676,6 +683,11 @@ static enum ptp_packet_state efx_ptp_match_rx(struct efx_nic *efx,
                        break;
                }
        }
+       /* If the event overflow flag is set and the event list is now empty
+        * clear the flag to re-enable the overflow warning message.
+        */
+       if (ptp->evt_overflow && list_empty(&ptp->evt_list))
+               ptp->evt_overflow = false;
        spin_unlock_bh(&ptp->evt_lock);
 
        return rc;
@@ -705,8 +717,9 @@ static bool efx_ptp_process_events(struct efx_nic *efx, struct sk_buff_head *q)
                        __skb_queue_tail(q, skb);
                } else if (time_after(jiffies, match->expiry)) {
                        match->state = PTP_PACKET_STATE_TIMED_OUT;
-                       netif_warn(efx, rx_err, efx->net_dev,
-                                  "PTP packet - no timestamp seen\n");
+                       if (net_ratelimit())
+                               netif_warn(efx, rx_err, efx->net_dev,
+                                          "PTP packet - no timestamp seen\n");
                        __skb_queue_tail(q, skb);
                } else {
                        /* Replace unprocessed entry and stop */
@@ -788,9 +801,14 @@ fail:
 static int efx_ptp_stop(struct efx_nic *efx)
 {
        struct efx_ptp_data *ptp = efx->ptp_data;
-       int rc = efx_ptp_disable(efx);
        struct list_head *cursor;
        struct list_head *next;
+       int rc;
+
+       if (ptp == NULL)
+               return 0;
+
+       rc = efx_ptp_disable(efx);
 
        if (ptp->rxfilter_installed) {
                efx_filter_remove_id_safe(efx, EFX_FILTER_PRI_REQUIRED,
@@ -809,11 +827,19 @@ static int efx_ptp_stop(struct efx_nic *efx)
        list_for_each_safe(cursor, next, &efx->ptp_data->evt_list) {
                list_move(cursor, &efx->ptp_data->evt_free_list);
        }
+       ptp->evt_overflow = false;
        spin_unlock_bh(&efx->ptp_data->evt_lock);
 
        return rc;
 }
 
+static int efx_ptp_restart(struct efx_nic *efx)
+{
+       if (efx->ptp_data && efx->ptp_data->enabled)
+               return efx_ptp_start(efx);
+       return 0;
+}
+
 static void efx_ptp_pps_worker(struct work_struct *work)
 {
        struct efx_ptp_data *ptp =
@@ -901,6 +927,7 @@ static int efx_ptp_probe_channel(struct efx_channel *channel)
        spin_lock_init(&ptp->evt_lock);
        for (pos = 0; pos < MAX_RECEIVE_EVENTS; pos++)
                list_add(&ptp->rx_evts[pos].link, &ptp->evt_free_list);
+       ptp->evt_overflow = false;
 
        ptp->phc_clock_info.owner = THIS_MODULE;
        snprintf(ptp->phc_clock_info.name,
@@ -989,7 +1016,11 @@ bool efx_ptp_is_ptp_tx(struct efx_nic *efx, struct sk_buff *skb)
                skb->len >= PTP_MIN_LENGTH &&
                skb->len <= MC_CMD_PTP_IN_TRANSMIT_PACKET_MAXNUM &&
                likely(skb->protocol == htons(ETH_P_IP)) &&
+               skb_transport_header_was_set(skb) &&
+               skb_network_header_len(skb) >= sizeof(struct iphdr) &&
                ip_hdr(skb)->protocol == IPPROTO_UDP &&
+               skb_headlen(skb) >=
+               skb_transport_offset(skb) + sizeof(struct udphdr) &&
                udp_hdr(skb)->dest == htons(PTP_EVENT_PORT);
 }
 
@@ -1106,7 +1137,7 @@ static int efx_ptp_change_mode(struct efx_nic *efx, bool enable_wanted,
 {
        if ((enable_wanted != efx->ptp_data->enabled) ||
            (enable_wanted && (efx->ptp_data->mode != new_mode))) {
-               int rc;
+               int rc = 0;
 
                if (enable_wanted) {
                        /* Change of mode requires disable */
@@ -1123,7 +1154,8 @@ static int efx_ptp_change_mode(struct efx_nic *efx, bool enable_wanted,
                         * succeed.
                         */
                        efx->ptp_data->mode = new_mode;
-                       rc = efx_ptp_start(efx);
+                       if (netif_running(efx->net_dev))
+                               rc = efx_ptp_start(efx);
                        if (rc == 0) {
                                rc = efx_ptp_synchronize(efx,
                                                         PTP_SYNC_ATTEMPTS * 2);
@@ -1295,8 +1327,13 @@ static void ptp_event_rx(struct efx_nic *efx, struct efx_ptp_data *ptp)
                list_add_tail(&evt->link, &ptp->evt_list);
 
                queue_work(ptp->workwq, &ptp->work);
-       } else {
-               netif_err(efx, rx_err, efx->net_dev, "No free PTP event");
+       } else if (!ptp->evt_overflow) {
+               /* Log a warning message and set the event overflow flag.
+                * The message won't be logged again until the event queue
+                * becomes empty.
+                */
+               netif_err(efx, rx_err, efx->net_dev, "PTP event queue overflow\n");
+               ptp->evt_overflow = true;
        }
        spin_unlock_bh(&ptp->evt_lock);
 }
@@ -1389,7 +1426,7 @@ static int efx_phc_adjfreq(struct ptp_clock_info *ptp, s32 delta)
        if (rc != 0)
                return rc;
 
-       ptp_data->current_adjfreq = delta;
+       ptp_data->current_adjfreq = adjustment_ns;
        return 0;
 }
 
@@ -1404,7 +1441,7 @@ static int efx_phc_adjtime(struct ptp_clock_info *ptp, s64 delta)
 
        MCDI_SET_DWORD(inbuf, PTP_IN_OP, MC_CMD_PTP_OP_ADJUST);
        MCDI_SET_DWORD(inbuf, PTP_IN_PERIPH_ID, 0);
-       MCDI_SET_QWORD(inbuf, PTP_IN_ADJUST_FREQ, 0);
+       MCDI_SET_QWORD(inbuf, PTP_IN_ADJUST_FREQ, ptp_data->current_adjfreq);
        MCDI_SET_DWORD(inbuf, PTP_IN_ADJUST_SECONDS, (u32)delta_ts.tv_sec);
        MCDI_SET_DWORD(inbuf, PTP_IN_ADJUST_NANOSECONDS, (u32)delta_ts.tv_nsec);
        return efx_mcdi_rpc(efx, MC_CMD_PTP, inbuf, sizeof(inbuf),
@@ -1491,3 +1528,14 @@ void efx_ptp_probe(struct efx_nic *efx)
                efx->extra_channel_type[EFX_EXTRA_CHANNEL_PTP] =
                        &efx_ptp_channel_type;
 }
+
+void efx_ptp_start_datapath(struct efx_nic *efx)
+{
+       if (efx_ptp_restart(efx))
+               netif_err(efx, drv, efx->net_dev, "Failed to restart PTP.\n");
+}
+
+void efx_ptp_stop_datapath(struct efx_nic *efx)
+{
+       efx_ptp_stop(efx);
+}
index 8f09e686fc2392a80f56610c78a61c6374b4a410..42488df1f4ec2af02feb9a46c408168b6a7dabec 100644 (file)
@@ -94,7 +94,7 @@ static inline void efx_sync_rx_buffer(struct efx_nic *efx,
 
 void efx_rx_config_page_split(struct efx_nic *efx)
 {
-       efx->rx_page_buf_step = ALIGN(efx->rx_dma_len + NET_IP_ALIGN,
+       efx->rx_page_buf_step = ALIGN(efx->rx_dma_len + efx->rx_ip_align,
                                      EFX_RX_BUF_ALIGNMENT);
        efx->rx_bufs_per_page = efx->rx_buffer_order ? 1 :
                ((PAGE_SIZE - sizeof(struct efx_rx_page_state)) /
@@ -189,9 +189,9 @@ static int efx_init_rx_buffers(struct efx_rx_queue *rx_queue)
                do {
                        index = rx_queue->added_count & rx_queue->ptr_mask;
                        rx_buf = efx_rx_buffer(rx_queue, index);
-                       rx_buf->dma_addr = dma_addr + NET_IP_ALIGN;
+                       rx_buf->dma_addr = dma_addr + efx->rx_ip_align;
                        rx_buf->page = page;
-                       rx_buf->page_offset = page_offset + NET_IP_ALIGN;
+                       rx_buf->page_offset = page_offset + efx->rx_ip_align;
                        rx_buf->len = efx->rx_dma_len;
                        rx_buf->flags = 0;
                        ++rx_queue->added_count;
index 0c9b5d94154f8d215ddaf40d3fb252764983d73b..8bf29eb4a5a003eacabb6ea1f93590f566bb1ede 100644 (file)
@@ -82,6 +82,7 @@ static const char version[] =
 #include <linux/mii.h>
 #include <linux/workqueue.h>
 #include <linux/of.h>
+#include <linux/of_device.h>
 
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
@@ -2184,6 +2185,15 @@ static void smc_release_datacs(struct platform_device *pdev, struct net_device *
        }
 }
 
+#if IS_BUILTIN(CONFIG_OF)
+static const struct of_device_id smc91x_match[] = {
+       { .compatible = "smsc,lan91c94", },
+       { .compatible = "smsc,lan91c111", },
+       {},
+};
+MODULE_DEVICE_TABLE(of, smc91x_match);
+#endif
+
 /*
  * smc_init(void)
  *   Input parameters:
@@ -2198,6 +2208,7 @@ static void smc_release_datacs(struct platform_device *pdev, struct net_device *
 static int smc_drv_probe(struct platform_device *pdev)
 {
        struct smc91x_platdata *pd = dev_get_platdata(&pdev->dev);
+       const struct of_device_id *match = NULL;
        struct smc_local *lp;
        struct net_device *ndev;
        struct resource *res, *ires;
@@ -2217,11 +2228,34 @@ static int smc_drv_probe(struct platform_device *pdev)
         */
 
        lp = netdev_priv(ndev);
+       lp->cfg.flags = 0;
 
        if (pd) {
                memcpy(&lp->cfg, pd, sizeof(lp->cfg));
                lp->io_shift = SMC91X_IO_SHIFT(lp->cfg.flags);
-       } else {
+       }
+
+#if IS_BUILTIN(CONFIG_OF)
+       match = of_match_device(of_match_ptr(smc91x_match), &pdev->dev);
+       if (match) {
+               struct device_node *np = pdev->dev.of_node;
+               u32 val;
+
+               /* Combination of IO widths supported, default to 16-bit */
+               if (!of_property_read_u32(np, "reg-io-width", &val)) {
+                       if (val & 1)
+                               lp->cfg.flags |= SMC91X_USE_8BIT;
+                       if ((val == 0) || (val & 2))
+                               lp->cfg.flags |= SMC91X_USE_16BIT;
+                       if (val & 4)
+                               lp->cfg.flags |= SMC91X_USE_32BIT;
+               } else {
+                       lp->cfg.flags |= SMC91X_USE_16BIT;
+               }
+       }
+#endif
+
+       if (!pd && !match) {
                lp->cfg.flags |= (SMC_CAN_USE_8BIT)  ? SMC91X_USE_8BIT  : 0;
                lp->cfg.flags |= (SMC_CAN_USE_16BIT) ? SMC91X_USE_16BIT : 0;
                lp->cfg.flags |= (SMC_CAN_USE_32BIT) ? SMC91X_USE_32BIT : 0;
@@ -2370,15 +2404,6 @@ static int smc_drv_resume(struct device *dev)
        return 0;
 }
 
-#ifdef CONFIG_OF
-static const struct of_device_id smc91x_match[] = {
-       { .compatible = "smsc,lan91c94", },
-       { .compatible = "smsc,lan91c111", },
-       {},
-};
-MODULE_DEVICE_TABLE(of, smc91x_match);
-#endif
-
 static struct dev_pm_ops smc_drv_pm_ops = {
        .suspend        = smc_drv_suspend,
        .resume         = smc_drv_resume,
index dd0dd6279b4eec8168c006457643568032ee358f..4f1d2549130e3396909f5287776663fa5bfb4e9e 100644 (file)
@@ -2019,7 +2019,6 @@ bdx_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                ndev->features = NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_TSO
                    | NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX |
                    NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_RXCSUM
-                   /*| NETIF_F_FRAGLIST */
                    ;
                ndev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG |
                        NETIF_F_TSO | NETIF_F_HW_VLAN_CTAG_TX;
index 7536a4c01293a9b3e97bf1171941b6724213ad6c..5120d9ce1dd4cdbdd8608550f87392d0a5f6bbb9 100644 (file)
@@ -1151,6 +1151,12 @@ static int cpsw_ndo_open(struct net_device *ndev)
                 * receive descs
                 */
                cpsw_info(priv, ifup, "submitted %d rx descriptors\n", i);
+
+               if (cpts_register(&priv->pdev->dev, priv->cpts,
+                                 priv->data.cpts_clock_mult,
+                                 priv->data.cpts_clock_shift))
+                       dev_err(priv->dev, "error registering cpts device\n");
+
        }
 
        /* Enable Interrupt pacing if configured */
@@ -1197,6 +1203,7 @@ static int cpsw_ndo_stop(struct net_device *ndev)
        netif_carrier_off(priv->ndev);
 
        if (cpsw_common_res_usage_state(priv) <= 1) {
+               cpts_unregister(priv->cpts);
                cpsw_intr_disable(priv);
                cpdma_ctlr_int_ctrl(priv->dma, false);
                cpdma_ctlr_stop(priv->dma);
@@ -1816,6 +1823,8 @@ static int cpsw_probe_dt(struct cpsw_platform_data *data,
                }
 
                i++;
+               if (i == data->slaves)
+                       break;
        }
 
        return 0;
@@ -1983,9 +1992,15 @@ static int cpsw_probe(struct platform_device *pdev)
                goto clean_runtime_disable_ret;
        }
        priv->regs = ss_regs;
-       priv->version = __raw_readl(&priv->regs->id_ver);
        priv->host_port = HOST_PORT_NUM;
 
+       /* Need to enable clocks with runtime PM api to access module
+        * registers
+        */
+       pm_runtime_get_sync(&pdev->dev);
+       priv->version = readl(&priv->regs->id_ver);
+       pm_runtime_put_sync(&pdev->dev);
+
        res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
        priv->wr_regs = devm_ioremap_resource(&pdev->dev, res);
        if (IS_ERR(priv->wr_regs)) {
@@ -2155,8 +2170,6 @@ static int cpsw_remove(struct platform_device *pdev)
                unregister_netdev(cpsw_get_slave_ndev(priv, 1));
        unregister_netdev(ndev);
 
-       cpts_unregister(priv->cpts);
-
        cpsw_ale_destroy(priv->ale);
        cpdma_chan_destroy(priv->txch);
        cpdma_chan_destroy(priv->rxch);
index 41ba974bf37cb9175c74ab40bba1817e890749e7..cd9b164a0434acb3a51066b5d0e17262a4bdc0dd 100644 (file)
@@ -61,6 +61,7 @@
 #include <linux/davinci_emac.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
+#include <linux/of_device.h>
 #include <linux/of_irq.h>
 #include <linux/of_net.h>
 
@@ -1752,10 +1753,14 @@ static const struct net_device_ops emac_netdev_ops = {
 #endif
 };
 
+static const struct of_device_id davinci_emac_of_match[];
+
 static struct emac_platform_data *
 davinci_emac_of_get_pdata(struct platform_device *pdev, struct emac_priv *priv)
 {
        struct device_node *np;
+       const struct of_device_id *match;
+       const struct emac_platform_data *auxdata;
        struct emac_platform_data *pdata = NULL;
        const u8 *mac_addr;
 
@@ -1793,7 +1798,20 @@ davinci_emac_of_get_pdata(struct platform_device *pdev, struct emac_priv *priv)
 
        priv->phy_node = of_parse_phandle(np, "phy-handle", 0);
        if (!priv->phy_node)
-               pdata->phy_id = "";
+               pdata->phy_id = NULL;
+
+       auxdata = pdev->dev.platform_data;
+       if (auxdata) {
+               pdata->interrupt_enable = auxdata->interrupt_enable;
+               pdata->interrupt_disable = auxdata->interrupt_disable;
+       }
+
+       match = of_match_device(davinci_emac_of_match, &pdev->dev);
+       if (match && match->data) {
+               auxdata = match->data;
+               pdata->version = auxdata->version;
+               pdata->hw_ram_addr = auxdata->hw_ram_addr;
+       }
 
        pdev->dev.platform_data = pdata;
 
@@ -2020,8 +2038,14 @@ static const struct dev_pm_ops davinci_emac_pm_ops = {
 };
 
 #if IS_ENABLED(CONFIG_OF)
+static const struct emac_platform_data am3517_emac_data = {
+       .version                = EMAC_VERSION_2,
+       .hw_ram_addr            = 0x01e20000,
+};
+
 static const struct of_device_id davinci_emac_of_match[] = {
        {.compatible = "ti,davinci-dm6467-emac", },
+       {.compatible = "ti,am3517-emac", .data = &am3517_emac_data, },
        {},
 };
 MODULE_DEVICE_TABLE(of, davinci_emac_of_match);
index 1f23641263232fce0255d237976cbf5470e22a6c..2166e879a0961544af056802b1dbcff5a011d2aa 100644 (file)
@@ -1017,7 +1017,7 @@ static int temac_of_probe(struct platform_device *op)
        platform_set_drvdata(op, ndev);
        SET_NETDEV_DEV(ndev, &op->dev);
        ndev->flags &= ~IFF_MULTICAST;  /* clear multicast */
-       ndev->features = NETIF_F_SG | NETIF_F_FRAGLIST;
+       ndev->features = NETIF_F_SG;
        ndev->netdev_ops = &temac_netdev_ops;
        ndev->ethtool_ops = &temac_ethtool_ops;
 #if 0
index b2ff038d6d200abc5dbcd9315806e6791cec3335..f9293da19e260caa8e06829242150ccc72c0ded0 100644 (file)
@@ -1486,7 +1486,7 @@ static int axienet_of_probe(struct platform_device *op)
 
        SET_NETDEV_DEV(ndev, &op->dev);
        ndev->flags &= ~IFF_MULTICAST;  /* clear multicast */
-       ndev->features = NETIF_F_SG | NETIF_F_FRAGLIST;
+       ndev->features = NETIF_F_SG;
        ndev->netdev_ops = &axienet_netdev_ops;
        ndev->ethtool_ops = &axienet_ethtool_ops;
 
index 74234a51c851186c0c9bcfbc140b261724144e20..fefb8cd5eb65e1cb462f2a277c0bda422a89cd60 100644 (file)
@@ -163,26 +163,9 @@ static void xemaclite_enable_interrupts(struct net_local *drvdata)
        __raw_writel(reg_data | XEL_TSR_XMIT_IE_MASK,
                     drvdata->base_addr + XEL_TSR_OFFSET);
 
-       /* Enable the Tx interrupts for the second Buffer if
-        * configured in HW */
-       if (drvdata->tx_ping_pong != 0) {
-               reg_data = __raw_readl(drvdata->base_addr +
-                                  XEL_BUFFER_OFFSET + XEL_TSR_OFFSET);
-               __raw_writel(reg_data | XEL_TSR_XMIT_IE_MASK,
-                            drvdata->base_addr + XEL_BUFFER_OFFSET +
-                            XEL_TSR_OFFSET);
-       }
-
        /* Enable the Rx interrupts for the first buffer */
        __raw_writel(XEL_RSR_RECV_IE_MASK, drvdata->base_addr + XEL_RSR_OFFSET);
 
-       /* Enable the Rx interrupts for the second Buffer if
-        * configured in HW */
-       if (drvdata->rx_ping_pong != 0) {
-               __raw_writel(XEL_RSR_RECV_IE_MASK, drvdata->base_addr +
-                            XEL_BUFFER_OFFSET + XEL_RSR_OFFSET);
-       }
-
        /* Enable the Global Interrupt Enable */
        __raw_writel(XEL_GIER_GIE_MASK, drvdata->base_addr + XEL_GIER_OFFSET);
 }
@@ -206,31 +189,10 @@ static void xemaclite_disable_interrupts(struct net_local *drvdata)
        __raw_writel(reg_data & (~XEL_TSR_XMIT_IE_MASK),
                     drvdata->base_addr + XEL_TSR_OFFSET);
 
-       /* Disable the Tx interrupts for the second Buffer
-        * if configured in HW */
-       if (drvdata->tx_ping_pong != 0) {
-               reg_data = __raw_readl(drvdata->base_addr + XEL_BUFFER_OFFSET +
-                                  XEL_TSR_OFFSET);
-               __raw_writel(reg_data & (~XEL_TSR_XMIT_IE_MASK),
-                            drvdata->base_addr + XEL_BUFFER_OFFSET +
-                            XEL_TSR_OFFSET);
-       }
-
        /* Disable the Rx interrupts for the first buffer */
        reg_data = __raw_readl(drvdata->base_addr + XEL_RSR_OFFSET);
        __raw_writel(reg_data & (~XEL_RSR_RECV_IE_MASK),
                     drvdata->base_addr + XEL_RSR_OFFSET);
-
-       /* Disable the Rx interrupts for the second buffer
-        * if configured in HW */
-       if (drvdata->rx_ping_pong != 0) {
-
-               reg_data = __raw_readl(drvdata->base_addr + XEL_BUFFER_OFFSET +
-                                  XEL_RSR_OFFSET);
-               __raw_writel(reg_data & (~XEL_RSR_RECV_IE_MASK),
-                            drvdata->base_addr + XEL_BUFFER_OFFSET +
-                            XEL_RSR_OFFSET);
-       }
 }
 
 /**
@@ -258,6 +220,13 @@ static void xemaclite_aligned_write(void *src_ptr, u32 *dest_ptr,
                *to_u16_ptr++ = *from_u16_ptr++;
                *to_u16_ptr++ = *from_u16_ptr++;
 
+               /* This barrier resolves occasional issues seen around
+                * cases where the data is not properly flushed out
+                * from the processor store buffers to the destination
+                * memory locations.
+                */
+               wmb();
+
                /* Output a word */
                *to_u32_ptr++ = align_buffer;
        }
@@ -273,6 +242,12 @@ static void xemaclite_aligned_write(void *src_ptr, u32 *dest_ptr,
                for (; length > 0; length--)
                        *to_u8_ptr++ = *from_u8_ptr++;
 
+               /* This barrier resolves occasional issues seen around
+                * cases where the data is not properly flushed out
+                * from the processor store buffers to the destination
+                * memory locations.
+                */
+               wmb();
                *to_u32_ptr = align_buffer;
        }
 }
index 524f713f60170b2d5632bbac6958ae0529a80b1c..f8135725bcf678c231cb833c3ab50487b1ec67e6 100644 (file)
@@ -327,7 +327,6 @@ static int netvsc_change_mtu(struct net_device *ndev, int mtu)
                return -EINVAL;
 
        nvdev->start_remove = true;
-       cancel_delayed_work_sync(&ndevctx->dwork);
        cancel_work_sync(&ndevctx->work);
        netif_tx_disable(ndev);
        rndis_filter_device_remove(hdev);
index 9093004f9b63004922a0202180d7341343287553..2a89da0803177355ebae2f31ce92ceb2fae00599 100644 (file)
@@ -770,7 +770,7 @@ static ssize_t macvtap_put_user(struct macvtap_queue *q,
        int ret;
        int vnet_hdr_len = 0;
        int vlan_offset = 0;
-       int copied;
+       int copied, total;
 
        if (q->flags & IFF_VNET_HDR) {
                struct virtio_net_hdr vnet_hdr;
@@ -785,7 +785,8 @@ static ssize_t macvtap_put_user(struct macvtap_queue *q,
                if (memcpy_toiovecend(iv, (void *)&vnet_hdr, 0, sizeof(vnet_hdr)))
                        return -EFAULT;
        }
-       copied = vnet_hdr_len;
+       total = copied = vnet_hdr_len;
+       total += skb->len;
 
        if (!vlan_tx_tag_present(skb))
                len = min_t(int, skb->len, len);
@@ -800,6 +801,7 @@ static ssize_t macvtap_put_user(struct macvtap_queue *q,
 
                vlan_offset = offsetof(struct vlan_ethhdr, h_vlan_proto);
                len = min_t(int, skb->len + VLAN_HLEN, len);
+               total += VLAN_HLEN;
 
                copy = min_t(int, vlan_offset, len);
                ret = skb_copy_datagram_const_iovec(skb, 0, iv, copied, copy);
@@ -817,10 +819,9 @@ static ssize_t macvtap_put_user(struct macvtap_queue *q,
        }
 
        ret = skb_copy_datagram_const_iovec(skb, vlan_offset, iv, copied, len);
-       copied += len;
 
 done:
-       return ret ? ret : copied;
+       return ret ? ret : total;
 }
 
 static ssize_t macvtap_do_read(struct macvtap_queue *q, struct kiocb *iocb,
@@ -875,7 +876,9 @@ static ssize_t macvtap_aio_read(struct kiocb *iocb, const struct iovec *iv,
        }
 
        ret = macvtap_do_read(q, iocb, iv, len, file->f_flags & O_NONBLOCK);
-       ret = min_t(ssize_t, ret, len); /* XXX copied from tun.c. Why? */
+       ret = min_t(ssize_t, ret, len);
+       if (ret > 0)
+               iocb->ki_pos = ret;
 out:
        return ret;
 }
index 3ae28f420868fc35af3b3ed4e652f96e43a8f35b..26fa05a472b467679071ee6d76642e87f8bc10cf 100644 (file)
@@ -335,6 +335,21 @@ static struct phy_driver ksphy_driver[] = {
        .suspend        = genphy_suspend,
        .resume         = genphy_resume,
        .driver         = { .owner = THIS_MODULE,},
+}, {
+       .phy_id         = PHY_ID_KSZ8041RNLI,
+       .phy_id_mask    = 0x00fffff0,
+       .name           = "Micrel KSZ8041RNLI",
+       .features       = PHY_BASIC_FEATURES |
+                         SUPPORTED_Pause | SUPPORTED_Asym_Pause,
+       .flags          = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
+       .config_init    = kszphy_config_init,
+       .config_aneg    = genphy_config_aneg,
+       .read_status    = genphy_read_status,
+       .ack_interrupt  = kszphy_ack_interrupt,
+       .config_intr    = kszphy_config_intr,
+       .suspend        = genphy_suspend,
+       .resume         = genphy_resume,
+       .driver         = { .owner = THIS_MODULE,},
 }, {
        .phy_id         = PHY_ID_KSZ8051,
        .phy_id_mask    = 0x00fffff0,
index 782e38bfc1eeea38215492aee5aaa587cc534525..7c8343a4f91823a579910cbcccc5827a2eb1d986 100644 (file)
@@ -1184,7 +1184,7 @@ static ssize_t tun_put_user(struct tun_struct *tun,
 {
        struct tun_pi pi = { 0, skb->protocol };
        ssize_t total = 0;
-       int vlan_offset = 0;
+       int vlan_offset = 0, copied;
 
        if (!(tun->flags & TUN_NO_PI)) {
                if ((len -= sizeof(pi)) < 0)
@@ -1248,6 +1248,8 @@ static ssize_t tun_put_user(struct tun_struct *tun,
                total += tun->vnet_hdr_sz;
        }
 
+       copied = total;
+       total += skb->len;
        if (!vlan_tx_tag_present(skb)) {
                len = min_t(int, skb->len, len);
        } else {
@@ -1262,24 +1264,24 @@ static ssize_t tun_put_user(struct tun_struct *tun,
 
                vlan_offset = offsetof(struct vlan_ethhdr, h_vlan_proto);
                len = min_t(int, skb->len + VLAN_HLEN, len);
+               total += VLAN_HLEN;
 
                copy = min_t(int, vlan_offset, len);
-               ret = skb_copy_datagram_const_iovec(skb, 0, iv, total, copy);
+               ret = skb_copy_datagram_const_iovec(skb, 0, iv, copied, copy);
                len -= copy;
-               total += copy;
+               copied += copy;
                if (ret || !len)
                        goto done;
 
                copy = min_t(int, sizeof(veth), len);
-               ret = memcpy_toiovecend(iv, (void *)&veth, total, copy);
+               ret = memcpy_toiovecend(iv, (void *)&veth, copied, copy);
                len -= copy;
-               total += copy;
+               copied += copy;
                if (ret || !len)
                        goto done;
        }
 
-       skb_copy_datagram_const_iovec(skb, vlan_offset, iv, total, len);
-       total += len;
+       skb_copy_datagram_const_iovec(skb, vlan_offset, iv, copied, len);
 
 done:
        tun->dev->stats.tx_packets++;
@@ -1356,6 +1358,8 @@ static ssize_t tun_chr_aio_read(struct kiocb *iocb, const struct iovec *iv,
        ret = tun_do_read(tun, tfile, iocb, iv, len,
                          file->f_flags & O_NONBLOCK);
        ret = min_t(ssize_t, ret, len);
+       if (ret > 0)
+               iocb->ki_pos = ret;
 out:
        tun_put(tun);
        return ret;
index 916241d16c6764c117f80fa7109bdbff7dfdb714..d208f860498106013913211183baa39a37f33982 100644 (file)
@@ -426,10 +426,10 @@ static void receive_buf(struct receive_queue *rq, void *buf, unsigned int len)
        if (unlikely(len < sizeof(struct virtio_net_hdr) + ETH_HLEN)) {
                pr_debug("%s: short packet %i\n", dev->name, len);
                dev->stats.rx_length_errors++;
-               if (vi->big_packets)
-                       give_pages(rq, buf);
-               else if (vi->mergeable_rx_bufs)
+               if (vi->mergeable_rx_bufs)
                        put_page(virt_to_head_page(buf));
+               else if (vi->big_packets)
+                       give_pages(rq, buf);
                else
                        dev_kfree_skb(buf);
                return;
@@ -1367,6 +1367,11 @@ static void virtnet_config_changed(struct virtio_device *vdev)
 
 static void virtnet_free_queues(struct virtnet_info *vi)
 {
+       int i;
+
+       for (i = 0; i < vi->max_queue_pairs; i++)
+               netif_napi_del(&vi->rq[i].napi);
+
        kfree(vi->rq);
        kfree(vi->sq);
 }
@@ -1396,10 +1401,10 @@ static void free_unused_bufs(struct virtnet_info *vi)
                struct virtqueue *vq = vi->rq[i].vq;
 
                while ((buf = virtqueue_detach_unused_buf(vq)) != NULL) {
-                       if (vi->big_packets)
-                               give_pages(&vi->rq[i], buf);
-                       else if (vi->mergeable_rx_bufs)
+                       if (vi->mergeable_rx_bufs)
                                put_page(virt_to_head_page(buf));
+                       else if (vi->big_packets)
+                               give_pages(&vi->rq[i], buf);
                        else
                                dev_kfree_skb(buf);
                        --vi->rq[i].num;
index 0358c07f7669142034e089660425a8fdb88236e2..249e01c5600c9010a19ca07c175867ec9e5fb91d 100644 (file)
@@ -1668,7 +1668,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
                        netdev_dbg(dev, "circular route to %pI4\n",
                                   &dst->sin.sin_addr.s_addr);
                        dev->stats.collisions++;
-                       goto tx_error;
+                       goto rt_tx_error;
                }
 
                /* Bypass encapsulation if the destination is local */
index 1ec52356b5a16956dda70a2f7365103497b43c68..130657db5c4314321159b8d3fb7ec69c1ee01d21 100644 (file)
@@ -3984,18 +3984,20 @@ static void ar9003_hw_quick_drop_apply(struct ath_hw *ah, u16 freq)
        int quick_drop;
        s32 t[3], f[3] = {5180, 5500, 5785};
 
-       if (!(pBase->miscConfiguration & BIT(1)))
+       if (!(pBase->miscConfiguration & BIT(4)))
                return;
 
-       if (freq < 4000)
-               quick_drop = eep->modalHeader2G.quick_drop;
-       else {
-               t[0] = eep->base_ext1.quick_drop_low;
-               t[1] = eep->modalHeader5G.quick_drop;
-               t[2] = eep->base_ext1.quick_drop_high;
-               quick_drop = ar9003_hw_power_interpolate(freq, f, t, 3);
+       if (AR_SREV_9300(ah) || AR_SREV_9580(ah) || AR_SREV_9340(ah)) {
+               if (freq < 4000) {
+                       quick_drop = eep->modalHeader2G.quick_drop;
+               } else {
+                       t[0] = eep->base_ext1.quick_drop_low;
+                       t[1] = eep->modalHeader5G.quick_drop;
+                       t[2] = eep->base_ext1.quick_drop_high;
+                       quick_drop = ar9003_hw_power_interpolate(freq, f, t, 3);
+               }
+               REG_RMW_FIELD(ah, AR_PHY_AGC, AR_PHY_AGC_QUICK_DROP, quick_drop);
        }
-       REG_RMW_FIELD(ah, AR_PHY_AGC, AR_PHY_AGC_QUICK_DROP, quick_drop);
 }
 
 static void ar9003_hw_txend_to_xpa_off_apply(struct ath_hw *ah, bool is2ghz)
@@ -4035,7 +4037,7 @@ static void ar9003_hw_xlna_bias_strength_apply(struct ath_hw *ah, bool is2ghz)
        struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
        u8 bias;
 
-       if (!(eep->baseEepHeader.featureEnable & 0x40))
+       if (!(eep->baseEepHeader.miscConfiguration & 0x40))
                return;
 
        if (!AR_SREV_9300(ah))
index 54b04155e43b1058575aa44df3e6ece1ab18e55e..8918035da3a3510c04ad45e106cebd3d267ad6e8 100644 (file)
@@ -146,10 +146,9 @@ static void ath9k_hw_set_clockrate(struct ath_hw *ah)
        else
                clockrate = ATH9K_CLOCK_RATE_5GHZ_OFDM;
 
-       if (IS_CHAN_HT40(chan))
-               clockrate *= 2;
-
-       if (ah->curchan) {
+       if (chan) {
+               if (IS_CHAN_HT40(chan))
+                       clockrate *= 2;
                if (IS_CHAN_HALF_RATE(chan))
                        clockrate /= 2;
                if (IS_CHAN_QUARTER_RATE(chan))
index 09cdbcd097394a3a2c324230c2743f5d181b0900..b5a19e098f2d72f49dde181184bce20dc47bcebf 100644 (file)
@@ -1276,6 +1276,10 @@ static void ath_tx_fill_desc(struct ath_softc *sc, struct ath_buf *bf,
                                if (!rts_thresh || (len > rts_thresh))
                                        rts = true;
                        }
+
+                       if (!aggr)
+                               len = fi->framelen;
+
                        ath_buf_set_rate(sc, bf, &info, len, rts);
                }
 
index de9eb2cfbf4b5784c36a97da2748acd357250c37..366339421d4f1c924e4e1e69c34ce88bce9ab028 100644 (file)
@@ -2041,13 +2041,20 @@ static void wcn36xx_smd_rsp_process(struct wcn36xx *wcn, void *buf, size_t len)
        case WCN36XX_HAL_DELETE_STA_CONTEXT_IND:
                mutex_lock(&wcn->hal_ind_mutex);
                msg_ind = kmalloc(sizeof(*msg_ind), GFP_KERNEL);
-               msg_ind->msg_len = len;
-               msg_ind->msg = kmalloc(len, GFP_KERNEL);
-               memcpy(msg_ind->msg, buf, len);
-               list_add_tail(&msg_ind->list, &wcn->hal_ind_queue);
-               queue_work(wcn->hal_ind_wq, &wcn->hal_ind_work);
-               wcn36xx_dbg(WCN36XX_DBG_HAL, "indication arrived\n");
+               if (msg_ind) {
+                       msg_ind->msg_len = len;
+                       msg_ind->msg = kmalloc(len, GFP_KERNEL);
+                       memcpy(msg_ind->msg, buf, len);
+                       list_add_tail(&msg_ind->list, &wcn->hal_ind_queue);
+                       queue_work(wcn->hal_ind_wq, &wcn->hal_ind_work);
+                       wcn36xx_dbg(WCN36XX_DBG_HAL, "indication arrived\n");
+               }
                mutex_unlock(&wcn->hal_ind_mutex);
+               if (msg_ind)
+                       break;
+               /* FIXME: Do something smarter then just printing an error. */
+               wcn36xx_err("Run out of memory while handling SMD_EVENT (%d)\n",
+                           msg_header->msg_type);
                break;
        default:
                wcn36xx_err("SMD_EVENT (%d) not supported\n",
index b00a7e92225f7b928f5a3cf7395f860af27299bd..54e36fcb39542e8361dfdc019134f3ba1538de8f 100644 (file)
@@ -5,6 +5,8 @@ config BRCMSMAC
        tristate "Broadcom IEEE802.11n PCIe SoftMAC WLAN driver"
        depends on MAC80211
        depends on BCMA
+       select NEW_LEDS if BCMA_DRIVER_GPIO
+       select LEDS_CLASS if BCMA_DRIVER_GPIO
        select BRCMUTIL
        select FW_LOADER
        select CRC_CCITT
index 905704e335d7164b90a4ecb6fd51c2324911c154..abc9ceca70f3630251ad077fe307f05a8a979adc 100644 (file)
@@ -109,6 +109,8 @@ static inline int brcmf_sdioh_f0_write_byte(struct brcmf_sdio_dev *sdiodev,
                                        brcmf_err("Disable F2 failed:%d\n",
                                                  err_ret);
                        }
+               } else {
+                       err_ret = -ENOENT;
                }
        } else if ((regaddr == SDIO_CCCR_ABORT) ||
                   (regaddr == SDIO_CCCR_IENx)) {
index 85879dbaa402cdaa88d93247b678aaac9a3ff000..3c34a72a5d64769b8bbf156f9a74d4748fcb0228 100644 (file)
@@ -67,8 +67,8 @@
 #include "iwl-agn-hw.h"
 
 /* Highest firmware API version supported */
-#define IWL7260_UCODE_API_MAX  7
-#define IWL3160_UCODE_API_MAX  7
+#define IWL7260_UCODE_API_MAX  8
+#define IWL3160_UCODE_API_MAX  8
 
 /* Oldest version we won't warn about */
 #define IWL7260_UCODE_API_OK   7
@@ -130,6 +130,7 @@ const struct iwl_cfg iwl7260_2ac_cfg = {
        .ht_params = &iwl7000_ht_params,
        .nvm_ver = IWL7260_NVM_VERSION,
        .nvm_calib_ver = IWL7260_TX_POWER_VERSION,
+       .host_interrupt_operation_mode = true,
 };
 
 const struct iwl_cfg iwl7260_2ac_cfg_high_temp = {
@@ -140,6 +141,7 @@ const struct iwl_cfg iwl7260_2ac_cfg_high_temp = {
        .nvm_ver = IWL7260_NVM_VERSION,
        .nvm_calib_ver = IWL7260_TX_POWER_VERSION,
        .high_temp = true,
+       .host_interrupt_operation_mode = true,
 };
 
 const struct iwl_cfg iwl7260_2n_cfg = {
@@ -149,6 +151,7 @@ const struct iwl_cfg iwl7260_2n_cfg = {
        .ht_params = &iwl7000_ht_params,
        .nvm_ver = IWL7260_NVM_VERSION,
        .nvm_calib_ver = IWL7260_TX_POWER_VERSION,
+       .host_interrupt_operation_mode = true,
 };
 
 const struct iwl_cfg iwl7260_n_cfg = {
@@ -158,6 +161,7 @@ const struct iwl_cfg iwl7260_n_cfg = {
        .ht_params = &iwl7000_ht_params,
        .nvm_ver = IWL7260_NVM_VERSION,
        .nvm_calib_ver = IWL7260_TX_POWER_VERSION,
+       .host_interrupt_operation_mode = true,
 };
 
 const struct iwl_cfg iwl3160_2ac_cfg = {
@@ -167,6 +171,7 @@ const struct iwl_cfg iwl3160_2ac_cfg = {
        .ht_params = &iwl7000_ht_params,
        .nvm_ver = IWL3160_NVM_VERSION,
        .nvm_calib_ver = IWL3160_TX_POWER_VERSION,
+       .host_interrupt_operation_mode = true,
 };
 
 const struct iwl_cfg iwl3160_2n_cfg = {
@@ -176,6 +181,7 @@ const struct iwl_cfg iwl3160_2n_cfg = {
        .ht_params = &iwl7000_ht_params,
        .nvm_ver = IWL3160_NVM_VERSION,
        .nvm_calib_ver = IWL3160_TX_POWER_VERSION,
+       .host_interrupt_operation_mode = true,
 };
 
 const struct iwl_cfg iwl3160_n_cfg = {
@@ -185,6 +191,7 @@ const struct iwl_cfg iwl3160_n_cfg = {
        .ht_params = &iwl7000_ht_params,
        .nvm_ver = IWL3160_NVM_VERSION,
        .nvm_calib_ver = IWL3160_TX_POWER_VERSION,
+       .host_interrupt_operation_mode = true,
 };
 
 const struct iwl_cfg iwl7265_2ac_cfg = {
@@ -196,5 +203,23 @@ const struct iwl_cfg iwl7265_2ac_cfg = {
        .nvm_calib_ver = IWL7265_TX_POWER_VERSION,
 };
 
+const struct iwl_cfg iwl7265_2n_cfg = {
+       .name = "Intel(R) Dual Band Wireless N 7265",
+       .fw_name_pre = IWL7265_FW_PRE,
+       IWL_DEVICE_7000,
+       .ht_params = &iwl7000_ht_params,
+       .nvm_ver = IWL7265_NVM_VERSION,
+       .nvm_calib_ver = IWL7265_TX_POWER_VERSION,
+};
+
+const struct iwl_cfg iwl7265_n_cfg = {
+       .name = "Intel(R) Wireless N 7265",
+       .fw_name_pre = IWL7265_FW_PRE,
+       IWL_DEVICE_7000,
+       .ht_params = &iwl7000_ht_params,
+       .nvm_ver = IWL7265_NVM_VERSION,
+       .nvm_calib_ver = IWL7265_TX_POWER_VERSION,
+};
+
 MODULE_FIRMWARE(IWL7260_MODULE_FIRMWARE(IWL7260_UCODE_API_OK));
 MODULE_FIRMWARE(IWL3160_MODULE_FIRMWARE(IWL3160_UCODE_API_OK));
index 18f232e8e81253b31d730755f242b7a51552157c..03fd9aa8bfda93b67122b1fea0688c60aad1f95c 100644 (file)
@@ -207,6 +207,8 @@ struct iwl_eeprom_params {
  * @rx_with_siso_diversity: 1x1 device with rx antenna diversity
  * @internal_wimax_coex: internal wifi/wimax combo device
  * @high_temp: Is this NIC is designated to be in high temperature.
+ * @host_interrupt_operation_mode: device needs host interrupt operation
+ *     mode set
  *
  * We enable the driver to be backward compatible wrt. hardware features.
  * API differences in uCode shouldn't be handled here but through TLVs
@@ -235,6 +237,7 @@ struct iwl_cfg {
        enum iwl_led_mode led_mode;
        const bool rx_with_siso_diversity;
        const bool internal_wimax_coex;
+       const bool host_interrupt_operation_mode;
        bool high_temp;
 };
 
@@ -294,6 +297,8 @@ extern const struct iwl_cfg iwl3160_2ac_cfg;
 extern const struct iwl_cfg iwl3160_2n_cfg;
 extern const struct iwl_cfg iwl3160_n_cfg;
 extern const struct iwl_cfg iwl7265_2ac_cfg;
+extern const struct iwl_cfg iwl7265_2n_cfg;
+extern const struct iwl_cfg iwl7265_n_cfg;
 #endif /* CONFIG_IWLMVM */
 
 #endif /* __IWL_CONFIG_H__ */
index 54a4fdc631b73c987f12e459e8245d38b18f0c0b..da4eca8b3007feabb267a1710c95a70306224455 100644 (file)
@@ -495,14 +495,11 @@ enum secure_load_status_reg {
  * the CSR_INT_COALESCING is an 8 bit register in 32-usec unit
  *
  * default interrupt coalescing timer is 64 x 32 = 2048 usecs
- * default interrupt coalescing calibration timer is 16 x 32 = 512 usecs
  */
 #define IWL_HOST_INT_TIMEOUT_MAX       (0xFF)
 #define IWL_HOST_INT_TIMEOUT_DEF       (0x40)
 #define IWL_HOST_INT_TIMEOUT_MIN       (0x0)
-#define IWL_HOST_INT_CALIB_TIMEOUT_MAX (0xFF)
-#define IWL_HOST_INT_CALIB_TIMEOUT_DEF (0x10)
-#define IWL_HOST_INT_CALIB_TIMEOUT_MIN (0x0)
+#define IWL_HOST_INT_OPER_MODE         BIT(31)
 
 /*****************************************************************************
  *                        7000/3000 series SHR DTS addresses                 *
index 5d066cbc5ac7eda17914e85c2510c53fe4a5be2a..75b72a956552759685613c249f51a31926059a8f 100644 (file)
@@ -391,7 +391,6 @@ int iwl_send_bt_init_conf(struct iwl_mvm *mvm)
                                            BT_VALID_LUT |
                                            BT_VALID_WIFI_RX_SW_PRIO_BOOST |
                                            BT_VALID_WIFI_TX_SW_PRIO_BOOST |
-                                           BT_VALID_MULTI_PRIO_LUT |
                                            BT_VALID_CORUN_LUT_20 |
                                            BT_VALID_CORUN_LUT_40 |
                                            BT_VALID_ANT_ISOLATION |
@@ -842,6 +841,11 @@ static void iwl_mvm_bt_rssi_iterator(void *_data, u8 *mac,
 
        sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[mvmvif->ap_sta_id],
                                        lockdep_is_held(&mvm->mutex));
+
+       /* This can happen if the station has been removed right now */
+       if (IS_ERR_OR_NULL(sta))
+               return;
+
        mvmsta = (void *)sta->drv_priv;
 
        data->num_bss_ifaces++;
index 6f45966817bb4c1d34cd3a10c4db74536f4a13bf..b9b81e881dd011e5ca06747f2bcceea4ece64ac9 100644 (file)
@@ -895,7 +895,7 @@ static int iwl_mvm_get_last_nonqos_seq(struct iwl_mvm *mvm,
                /* new API returns next, not last-used seqno */
                if (mvm->fw->ucode_capa.flags &
                                IWL_UCODE_TLV_FLAGS_D3_CONTINUITY_API)
-                       err -= 0x10;
+                       err = (u16) (err - 0x10);
        }
 
        iwl_free_resp(&cmd);
@@ -1549,7 +1549,7 @@ static bool iwl_mvm_setup_connection_keep(struct iwl_mvm *mvm,
        if (gtkdata.unhandled_cipher)
                return false;
        if (!gtkdata.num_keys)
-               return true;
+               goto out;
        if (!gtkdata.last_gtk)
                return false;
 
@@ -1600,6 +1600,7 @@ static bool iwl_mvm_setup_connection_keep(struct iwl_mvm *mvm,
                                           (void *)&replay_ctr, GFP_KERNEL);
        }
 
+out:
        mvmvif->seqno_valid = true;
        /* +0x10 because the set API expects next-to-use, not last-used */
        mvmvif->seqno = le16_to_cpu(status->non_qos_seq_ctr) + 0x10;
index 9864d713eb2cb54920053fb971a65866f5ec0bf4..a8fe6b41f9a34b417a12e5295c7b86c75361bb1b 100644 (file)
@@ -119,6 +119,10 @@ static ssize_t iwl_dbgfs_sta_drain_write(struct file *file,
 
        if (sscanf(buf, "%d %d", &sta_id, &drain) != 2)
                return -EINVAL;
+       if (sta_id < 0 || sta_id >= IWL_MVM_STATION_COUNT)
+               return -EINVAL;
+       if (drain < 0 || drain > 1)
+               return -EINVAL;
 
        mutex_lock(&mvm->mutex);
 
index 33cf56fdfc41f86b8bb517a8824740bdbb71a896..95ce4b601fef3050085518e59a4e32036c57fbfc 100644 (file)
@@ -176,8 +176,11 @@ static void iwl_mvm_te_handle_notif(struct iwl_mvm *mvm,
         * P2P Device discoveribility, while there are other higher priority
         * events in the system).
         */
-       if (WARN_ONCE(!le32_to_cpu(notif->status),
-                     "Failed to schedule time event\n")) {
+       if (!le32_to_cpu(notif->status)) {
+               bool start = le32_to_cpu(notif->action) &
+                               TE_V2_NOTIF_HOST_EVENT_START;
+               IWL_WARN(mvm, "Time Event %s notification failure\n",
+                        start ? "start" : "end");
                if (iwl_mvm_te_check_disconnect(mvm, te_data->vif, NULL)) {
                        iwl_mvm_te_clear_data(mvm, te_data);
                        return;
index 941c0c88f982639b28436a60e52a0fdc6fba8c4b..86605027c41d6b4187c15ba874ef8fe25056676e 100644 (file)
@@ -353,6 +353,27 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
 
 /* 7265 Series */
        {IWL_PCI_DEVICE(0x095A, 0x5010, iwl7265_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x095A, 0x5110, iwl7265_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x095B, 0x5310, iwl7265_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x095B, 0x5302, iwl7265_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x095B, 0x5210, iwl7265_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x095B, 0x5012, iwl7265_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x095B, 0x500A, iwl7265_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x095A, 0x5410, iwl7265_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x095A, 0x1010, iwl7265_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x095A, 0x5000, iwl7265_2n_cfg)},
+       {IWL_PCI_DEVICE(0x095B, 0x5200, iwl7265_2n_cfg)},
+       {IWL_PCI_DEVICE(0x095A, 0x5002, iwl7265_n_cfg)},
+       {IWL_PCI_DEVICE(0x095B, 0x5202, iwl7265_n_cfg)},
+       {IWL_PCI_DEVICE(0x095A, 0x9010, iwl7265_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x095A, 0x9210, iwl7265_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x095A, 0x9410, iwl7265_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x095A, 0x5020, iwl7265_2n_cfg)},
+       {IWL_PCI_DEVICE(0x095A, 0x502A, iwl7265_2n_cfg)},
+       {IWL_PCI_DEVICE(0x095A, 0x5420, iwl7265_2n_cfg)},
+       {IWL_PCI_DEVICE(0x095A, 0x5090, iwl7265_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x095B, 0x5290, iwl7265_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x095A, 0x5490, iwl7265_2ac_cfg)},
 #endif /* CONFIG_IWLMVM */
 
        {0}
index fa22639b63c947d68247698cf109070a823b792b..051268c037b1d4f7d03715cdbf13b68311f883ff 100644 (file)
@@ -477,4 +477,12 @@ static inline bool iwl_is_rfkill_set(struct iwl_trans *trans)
                CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW);
 }
 
+static inline void iwl_nic_error(struct iwl_trans *trans)
+{
+       struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
+
+       set_bit(STATUS_FW_ERROR, &trans_pcie->status);
+       iwl_op_mode_nic_error(trans->op_mode);
+}
+
 #endif /* __iwl_trans_int_pcie_h__ */
index 3f237b42eb36d3c94cc84f94d0ba86b6a7861e41..be3995afa9d0acee4ce7f6e0d60907f896594c53 100644 (file)
@@ -489,6 +489,10 @@ static void iwl_pcie_rx_hw_init(struct iwl_trans *trans, struct iwl_rxq *rxq)
 
        /* Set interrupt coalescing timer to default (2048 usecs) */
        iwl_write8(trans, CSR_INT_COALESCING, IWL_HOST_INT_TIMEOUT_DEF);
+
+       /* W/A for interrupt coalescing bug in 7260 and 3160 */
+       if (trans->cfg->host_interrupt_operation_mode)
+               iwl_set_bit(trans, CSR_INT_COALESCING, IWL_HOST_INT_OPER_MODE);
 }
 
 static void iwl_pcie_rx_init_rxb_lists(struct iwl_rxq *rxq)
@@ -796,12 +800,13 @@ static void iwl_pcie_irq_handle_error(struct iwl_trans *trans)
        iwl_pcie_dump_csr(trans);
        iwl_dump_fh(trans, NULL);
 
+       /* set the ERROR bit before we wake up the caller */
        set_bit(STATUS_FW_ERROR, &trans_pcie->status);
        clear_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status);
        wake_up(&trans_pcie->wait_command_queue);
 
        local_bh_disable();
-       iwl_op_mode_nic_error(trans->op_mode);
+       iwl_nic_error(trans);
        local_bh_enable();
 }
 
index 5d9337bec67a87c59f3ccef73e5f5b26644930d5..cde9c16f6e4febb26c66c2206068bdba973c708a 100644 (file)
@@ -279,9 +279,6 @@ static int iwl_pcie_nic_init(struct iwl_trans *trans)
        spin_lock_irqsave(&trans_pcie->irq_lock, flags);
        iwl_pcie_apm_init(trans);
 
-       /* Set interrupt coalescing calibration timer to default (512 usecs) */
-       iwl_write8(trans, CSR_INT_COALESCING, IWL_HOST_INT_CALIB_TIMEOUT_DEF);
-
        spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
 
        iwl_pcie_set_pwr(trans, false);
index 059c5acad3a0d2e7b9eb73bf6466ef088e54e5c2..0adde919a258a65f9585651e8efb89add27f2add 100644 (file)
@@ -207,7 +207,7 @@ static void iwl_pcie_txq_stuck_timer(unsigned long data)
                IWL_ERR(trans, "scratch %d = 0x%08x\n", i,
                        le32_to_cpu(txq->scratchbufs[i].scratch));
 
-       iwl_op_mode_nic_error(trans->op_mode);
+       iwl_nic_error(trans);
 }
 
 /*
@@ -1023,7 +1023,7 @@ static void iwl_pcie_cmdq_reclaim(struct iwl_trans *trans, int txq_id, int idx)
                if (nfreed++ > 0) {
                        IWL_ERR(trans, "HCMD skipped: index (%d) %d %d\n",
                                idx, q->write_ptr, q->read_ptr);
-                       iwl_op_mode_nic_error(trans->op_mode);
+                       iwl_nic_error(trans);
                }
        }
 
@@ -1562,7 +1562,7 @@ static int iwl_pcie_send_hcmd_sync(struct iwl_trans *trans,
                                       get_cmd_string(trans_pcie, cmd->id));
                        ret = -ETIMEDOUT;
 
-                       iwl_op_mode_nic_error(trans->op_mode);
+                       iwl_nic_error(trans);
 
                        goto cancel;
                }
index 9df7bc91a26f54c9812718e481c538895aa5b4f8..c72438bb2fafd24b8e59f416d4e4311752dce941 100644 (file)
@@ -383,6 +383,14 @@ struct hwsim_radiotap_hdr {
        __le16 rt_chbitmask;
 } __packed;
 
+struct hwsim_radiotap_ack_hdr {
+       struct ieee80211_radiotap_header hdr;
+       u8 rt_flags;
+       u8 pad;
+       __le16 rt_channel;
+       __le16 rt_chbitmask;
+} __packed;
+
 /* MAC80211_HWSIM netlinf family */
 static struct genl_family hwsim_genl_family = {
        .id = GENL_ID_GENERATE,
@@ -500,7 +508,7 @@ static void mac80211_hwsim_monitor_ack(struct ieee80211_channel *chan,
                                       const u8 *addr)
 {
        struct sk_buff *skb;
-       struct hwsim_radiotap_hdr *hdr;
+       struct hwsim_radiotap_ack_hdr *hdr;
        u16 flags;
        struct ieee80211_hdr *hdr11;
 
@@ -511,14 +519,14 @@ static void mac80211_hwsim_monitor_ack(struct ieee80211_channel *chan,
        if (skb == NULL)
                return;
 
-       hdr = (struct hwsim_radiotap_hdr *) skb_put(skb, sizeof(*hdr));
+       hdr = (struct hwsim_radiotap_ack_hdr *) skb_put(skb, sizeof(*hdr));
        hdr->hdr.it_version = PKTHDR_RADIOTAP_VERSION;
        hdr->hdr.it_pad = 0;
        hdr->hdr.it_len = cpu_to_le16(sizeof(*hdr));
        hdr->hdr.it_present = cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) |
                                          (1 << IEEE80211_RADIOTAP_CHANNEL));
        hdr->rt_flags = 0;
-       hdr->rt_rate = 0;
+       hdr->pad = 0;
        hdr->rt_channel = cpu_to_le16(chan->center_freq);
        flags = IEEE80211_CHAN_2GHZ;
        hdr->rt_chbitmask = cpu_to_le16(flags);
@@ -1230,7 +1238,7 @@ static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw,
                                              HRTIMER_MODE_REL);
                } else if (!info->enable_beacon) {
                        unsigned int count = 0;
-                       ieee80211_iterate_active_interfaces(
+                       ieee80211_iterate_active_interfaces_atomic(
                                data->hw, IEEE80211_IFACE_ITER_NORMAL,
                                mac80211_hwsim_bcn_en_iter, &count);
                        wiphy_debug(hw->wiphy, "  beaconing vifs remaining: %u",
index c8e029df770e38cac9a52dccb660666bd8cc9f74..a09398fe9e2a67218f50530af8a0b4616443cbbb 100644 (file)
@@ -319,8 +319,8 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss,
                if (bss_desc && bss_desc->ssid.ssid_len &&
                    (!mwifiex_ssid_cmp(&priv->curr_bss_params.bss_descriptor.
                                       ssid, &bss_desc->ssid))) {
-                       kfree(bss_desc);
-                       return 0;
+                       ret = 0;
+                       goto done;
                }
 
                /* Exit Adhoc mode first */
index 2329cccf1fa6dd15f65c4dc30c54c62cce0551a7..870f1fa583702ee4bc61d9acab3e4925a4d984e0 100644 (file)
@@ -368,11 +368,11 @@ int xenvif_connect(struct xenvif *vif, unsigned long tx_ring_ref,
                   unsigned long rx_ring_ref, unsigned int tx_evtchn,
                   unsigned int rx_evtchn)
 {
+       struct task_struct *task;
        int err = -ENOMEM;
 
-       /* Already connected through? */
-       if (vif->tx_irq)
-               return 0;
+       BUG_ON(vif->tx_irq);
+       BUG_ON(vif->task);
 
        err = xenvif_map_frontend_rings(vif, tx_ring_ref, rx_ring_ref);
        if (err < 0)
@@ -411,14 +411,16 @@ int xenvif_connect(struct xenvif *vif, unsigned long tx_ring_ref,
        }
 
        init_waitqueue_head(&vif->wq);
-       vif->task = kthread_create(xenvif_kthread,
-                                  (void *)vif, "%s", vif->dev->name);
-       if (IS_ERR(vif->task)) {
+       task = kthread_create(xenvif_kthread,
+                             (void *)vif, "%s", vif->dev->name);
+       if (IS_ERR(task)) {
                pr_warn("Could not allocate kthread for %s\n", vif->dev->name);
-               err = PTR_ERR(vif->task);
+               err = PTR_ERR(task);
                goto err_rx_unbind;
        }
 
+       vif->task = task;
+
        rtnl_lock();
        if (!vif->can_sg && vif->dev->mtu > ETH_DATA_LEN)
                dev_set_mtu(vif->dev, ETH_DATA_LEN);
@@ -461,8 +463,10 @@ void xenvif_disconnect(struct xenvif *vif)
        if (netif_carrier_ok(vif->dev))
                xenvif_carrier_off(vif);
 
-       if (vif->task)
+       if (vif->task) {
                kthread_stop(vif->task);
+               vif->task = NULL;
+       }
 
        if (vif->tx_irq) {
                if (vif->tx_irq == vif->rx_irq)
index 64f0e0d18b8188c1729f525e26a2ca8b88724d8f..27bbe58dcbe7bf424fdfd54a461af847836836eb 100644 (file)
@@ -452,7 +452,7 @@ static int xenvif_gop_skb(struct sk_buff *skb,
        }
 
        /* Set up a GSO prefix descriptor, if necessary */
-       if ((1 << skb_shinfo(skb)->gso_type) & vif->gso_prefix_mask) {
+       if ((1 << gso_type) & vif->gso_prefix_mask) {
                req = RING_GET_REQUEST(&vif->rx, vif->rx.req_cons++);
                meta = npo->meta + npo->meta_prod++;
                meta->gso_type = gso_type;
@@ -1149,75 +1149,95 @@ static int xenvif_set_skb_gso(struct xenvif *vif,
        return 0;
 }
 
-static inline void maybe_pull_tail(struct sk_buff *skb, unsigned int len)
+static inline int maybe_pull_tail(struct sk_buff *skb, unsigned int len,
+                                 unsigned int max)
 {
-       if (skb_is_nonlinear(skb) && skb_headlen(skb) < len) {
-               /* If we need to pullup then pullup to the max, so we
-                * won't need to do it again.
-                */
-               int target = min_t(int, skb->len, MAX_TCP_HEADER);
-               __pskb_pull_tail(skb, target - skb_headlen(skb));
-       }
+       if (skb_headlen(skb) >= len)
+               return 0;
+
+       /* If we need to pullup then pullup to the max, so we
+        * won't need to do it again.
+        */
+       if (max > skb->len)
+               max = skb->len;
+
+       if (__pskb_pull_tail(skb, max - skb_headlen(skb)) == NULL)
+               return -ENOMEM;
+
+       if (skb_headlen(skb) < len)
+               return -EPROTO;
+
+       return 0;
 }
 
+/* This value should be large enough to cover a tagged ethernet header plus
+ * maximally sized IP and TCP or UDP headers.
+ */
+#define MAX_IP_HDR_LEN 128
+
 static int checksum_setup_ip(struct xenvif *vif, struct sk_buff *skb,
                             int recalculate_partial_csum)
 {
-       struct iphdr *iph = (void *)skb->data;
-       unsigned int header_size;
        unsigned int off;
-       int err = -EPROTO;
+       bool fragment;
+       int err;
+
+       fragment = false;
 
-       off = sizeof(struct iphdr);
+       err = maybe_pull_tail(skb,
+                             sizeof(struct iphdr),
+                             MAX_IP_HDR_LEN);
+       if (err < 0)
+               goto out;
+
+       if (ip_hdr(skb)->frag_off & htons(IP_OFFSET | IP_MF))
+               fragment = true;
 
-       header_size = skb->network_header + off + MAX_IPOPTLEN;
-       maybe_pull_tail(skb, header_size);
+       off = ip_hdrlen(skb);
 
-       off = iph->ihl * 4;
+       err = -EPROTO;
+
+       if (fragment)
+               goto out;
 
-       switch (iph->protocol) {
+       switch (ip_hdr(skb)->protocol) {
        case IPPROTO_TCP:
+               err = maybe_pull_tail(skb,
+                                     off + sizeof(struct tcphdr),
+                                     MAX_IP_HDR_LEN);
+               if (err < 0)
+                       goto out;
+
                if (!skb_partial_csum_set(skb, off,
                                          offsetof(struct tcphdr, check)))
                        goto out;
 
-               if (recalculate_partial_csum) {
-                       struct tcphdr *tcph = tcp_hdr(skb);
-
-                       header_size = skb->network_header +
-                               off +
-                               sizeof(struct tcphdr);
-                       maybe_pull_tail(skb, header_size);
-
-                       tcph->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr,
-                                                        skb->len - off,
-                                                        IPPROTO_TCP, 0);
-               }
+               if (recalculate_partial_csum)
+                       tcp_hdr(skb)->check =
+                               ~csum_tcpudp_magic(ip_hdr(skb)->saddr,
+                                                  ip_hdr(skb)->daddr,
+                                                  skb->len - off,
+                                                  IPPROTO_TCP, 0);
                break;
        case IPPROTO_UDP:
+               err = maybe_pull_tail(skb,
+                                     off + sizeof(struct udphdr),
+                                     MAX_IP_HDR_LEN);
+               if (err < 0)
+                       goto out;
+
                if (!skb_partial_csum_set(skb, off,
                                          offsetof(struct udphdr, check)))
                        goto out;
 
-               if (recalculate_partial_csum) {
-                       struct udphdr *udph = udp_hdr(skb);
-
-                       header_size = skb->network_header +
-                               off +
-                               sizeof(struct udphdr);
-                       maybe_pull_tail(skb, header_size);
-
-                       udph->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr,
-                                                        skb->len - off,
-                                                        IPPROTO_UDP, 0);
-               }
+               if (recalculate_partial_csum)
+                       udp_hdr(skb)->check =
+                               ~csum_tcpudp_magic(ip_hdr(skb)->saddr,
+                                                  ip_hdr(skb)->daddr,
+                                                  skb->len - off,
+                                                  IPPROTO_UDP, 0);
                break;
        default:
-               if (net_ratelimit())
-                       netdev_err(vif->dev,
-                                  "Attempting to checksum a non-TCP/UDP packet, "
-                                  "dropping a protocol %d packet\n",
-                                  iph->protocol);
                goto out;
        }
 
@@ -1227,121 +1247,138 @@ out:
        return err;
 }
 
+/* This value should be large enough to cover a tagged ethernet header plus
+ * an IPv6 header, all options, and a maximal TCP or UDP header.
+ */
+#define MAX_IPV6_HDR_LEN 256
+
+#define OPT_HDR(type, skb, off) \
+       (type *)(skb_network_header(skb) + (off))
+
 static int checksum_setup_ipv6(struct xenvif *vif, struct sk_buff *skb,
                               int recalculate_partial_csum)
 {
-       int err = -EPROTO;
-       struct ipv6hdr *ipv6h = (void *)skb->data;
+       int err;
        u8 nexthdr;
-       unsigned int header_size;
        unsigned int off;
+       unsigned int len;
        bool fragment;
        bool done;
 
+       fragment = false;
        done = false;
 
        off = sizeof(struct ipv6hdr);
 
-       header_size = skb->network_header + off;
-       maybe_pull_tail(skb, header_size);
+       err = maybe_pull_tail(skb, off, MAX_IPV6_HDR_LEN);
+       if (err < 0)
+               goto out;
 
-       nexthdr = ipv6h->nexthdr;
+       nexthdr = ipv6_hdr(skb)->nexthdr;
 
-       while ((off <= sizeof(struct ipv6hdr) + ntohs(ipv6h->payload_len)) &&
-              !done) {
+       len = sizeof(struct ipv6hdr) + ntohs(ipv6_hdr(skb)->payload_len);
+       while (off <= len && !done) {
                switch (nexthdr) {
                case IPPROTO_DSTOPTS:
                case IPPROTO_HOPOPTS:
                case IPPROTO_ROUTING: {
-                       struct ipv6_opt_hdr *hp = (void *)(skb->data + off);
+                       struct ipv6_opt_hdr *hp;
 
-                       header_size = skb->network_header +
-                               off +
-                               sizeof(struct ipv6_opt_hdr);
-                       maybe_pull_tail(skb, header_size);
+                       err = maybe_pull_tail(skb,
+                                             off +
+                                             sizeof(struct ipv6_opt_hdr),
+                                             MAX_IPV6_HDR_LEN);
+                       if (err < 0)
+                               goto out;
 
+                       hp = OPT_HDR(struct ipv6_opt_hdr, skb, off);
                        nexthdr = hp->nexthdr;
                        off += ipv6_optlen(hp);
                        break;
                }
                case IPPROTO_AH: {
-                       struct ip_auth_hdr *hp = (void *)(skb->data + off);
+                       struct ip_auth_hdr *hp;
+
+                       err = maybe_pull_tail(skb,
+                                             off +
+                                             sizeof(struct ip_auth_hdr),
+                                             MAX_IPV6_HDR_LEN);
+                       if (err < 0)
+                               goto out;
 
-                       header_size = skb->network_header +
-                               off +
-                               sizeof(struct ip_auth_hdr);
-                       maybe_pull_tail(skb, header_size);
+                       hp = OPT_HDR(struct ip_auth_hdr, skb, off);
+                       nexthdr = hp->nexthdr;
+                       off += ipv6_authlen(hp);
+                       break;
+               }
+               case IPPROTO_FRAGMENT: {
+                       struct frag_hdr *hp;
+
+                       err = maybe_pull_tail(skb,
+                                             off +
+                                             sizeof(struct frag_hdr),
+                                             MAX_IPV6_HDR_LEN);
+                       if (err < 0)
+                               goto out;
+
+                       hp = OPT_HDR(struct frag_hdr, skb, off);
+
+                       if (hp->frag_off & htons(IP6_OFFSET | IP6_MF))
+                               fragment = true;
 
                        nexthdr = hp->nexthdr;
-                       off += (hp->hdrlen+2)<<2;
+                       off += sizeof(struct frag_hdr);
                        break;
                }
-               case IPPROTO_FRAGMENT:
-                       fragment = true;
-                       /* fall through */
                default:
                        done = true;
                        break;
                }
        }
 
-       if (!done) {
-               if (net_ratelimit())
-                       netdev_err(vif->dev, "Failed to parse packet header\n");
-               goto out;
-       }
+       err = -EPROTO;
 
-       if (fragment) {
-               if (net_ratelimit())
-                       netdev_err(vif->dev, "Packet is a fragment!\n");
+       if (!done || fragment)
                goto out;
-       }
 
        switch (nexthdr) {
        case IPPROTO_TCP:
+               err = maybe_pull_tail(skb,
+                                     off + sizeof(struct tcphdr),
+                                     MAX_IPV6_HDR_LEN);
+               if (err < 0)
+                       goto out;
+
                if (!skb_partial_csum_set(skb, off,
                                          offsetof(struct tcphdr, check)))
                        goto out;
 
-               if (recalculate_partial_csum) {
-                       struct tcphdr *tcph = tcp_hdr(skb);
-
-                       header_size = skb->network_header +
-                               off +
-                               sizeof(struct tcphdr);
-                       maybe_pull_tail(skb, header_size);
-
-                       tcph->check = ~csum_ipv6_magic(&ipv6h->saddr,
-                                                      &ipv6h->daddr,
-                                                      skb->len - off,
-                                                      IPPROTO_TCP, 0);
-               }
+               if (recalculate_partial_csum)
+                       tcp_hdr(skb)->check =
+                               ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
+                                                &ipv6_hdr(skb)->daddr,
+                                                skb->len - off,
+                                                IPPROTO_TCP, 0);
                break;
        case IPPROTO_UDP:
+               err = maybe_pull_tail(skb,
+                                     off + sizeof(struct udphdr),
+                                     MAX_IPV6_HDR_LEN);
+               if (err < 0)
+                       goto out;
+
                if (!skb_partial_csum_set(skb, off,
                                          offsetof(struct udphdr, check)))
                        goto out;
 
-               if (recalculate_partial_csum) {
-                       struct udphdr *udph = udp_hdr(skb);
-
-                       header_size = skb->network_header +
-                               off +
-                               sizeof(struct udphdr);
-                       maybe_pull_tail(skb, header_size);
-
-                       udph->check = ~csum_ipv6_magic(&ipv6h->saddr,
-                                                      &ipv6h->daddr,
-                                                      skb->len - off,
-                                                      IPPROTO_UDP, 0);
-               }
+               if (recalculate_partial_csum)
+                       udp_hdr(skb)->check =
+                               ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
+                                                &ipv6_hdr(skb)->daddr,
+                                                skb->len - off,
+                                                IPPROTO_UDP, 0);
                break;
        default:
-               if (net_ratelimit())
-                       netdev_err(vif->dev,
-                                  "Attempting to checksum a non-TCP/UDP packet, "
-                                  "dropping a protocol %d packet\n",
-                                  nexthdr);
                goto out;
        }
 
@@ -1411,14 +1448,15 @@ static bool tx_credit_exceeded(struct xenvif *vif, unsigned size)
        return false;
 }
 
-static unsigned xenvif_tx_build_gops(struct xenvif *vif)
+static unsigned xenvif_tx_build_gops(struct xenvif *vif, int budget)
 {
        struct gnttab_copy *gop = vif->tx_copy_ops, *request_gop;
        struct sk_buff *skb;
        int ret;
 
        while ((nr_pending_reqs(vif) + XEN_NETBK_LEGACY_SLOTS_MAX
-               < MAX_PENDING_REQS)) {
+               < MAX_PENDING_REQS) &&
+              (skb_queue_len(&vif->tx_queue) < budget)) {
                struct xen_netif_tx_request txreq;
                struct xen_netif_tx_request txfrags[XEN_NETBK_LEGACY_SLOTS_MAX];
                struct page *page;
@@ -1440,7 +1478,7 @@ static unsigned xenvif_tx_build_gops(struct xenvif *vif)
                        continue;
                }
 
-               RING_FINAL_CHECK_FOR_REQUESTS(&vif->tx, work_to_do);
+               work_to_do = RING_HAS_UNCONSUMED_REQUESTS(&vif->tx);
                if (!work_to_do)
                        break;
 
@@ -1580,14 +1618,13 @@ static unsigned xenvif_tx_build_gops(struct xenvif *vif)
 }
 
 
-static int xenvif_tx_submit(struct xenvif *vif, int budget)
+static int xenvif_tx_submit(struct xenvif *vif)
 {
        struct gnttab_copy *gop = vif->tx_copy_ops;
        struct sk_buff *skb;
        int work_done = 0;
 
-       while (work_done < budget &&
-              (skb = __skb_dequeue(&vif->tx_queue)) != NULL) {
+       while ((skb = __skb_dequeue(&vif->tx_queue)) != NULL) {
                struct xen_netif_tx_request *txp;
                u16 pending_idx;
                unsigned data_len;
@@ -1662,14 +1699,14 @@ int xenvif_tx_action(struct xenvif *vif, int budget)
        if (unlikely(!tx_work_todo(vif)))
                return 0;
 
-       nr_gops = xenvif_tx_build_gops(vif);
+       nr_gops = xenvif_tx_build_gops(vif, budget);
 
        if (nr_gops == 0)
                return 0;
 
        gnttab_batch_copy(vif->tx_copy_ops, nr_gops);
 
-       work_done = xenvif_tx_submit(vif, nr_gops);
+       work_done = xenvif_tx_submit(vif);
 
        return work_done;
 }
index c269e430c760a9bc80ad982db9cb4aa211f16f45..2aa7b77c7c88bab6c2b70b79666205c061afec7d 100644 (file)
@@ -447,6 +447,11 @@ static int mvebu_sw_pci_bridge_read(struct mvebu_pcie_port *port,
                *value = 0;
                break;
 
+       case PCI_INTERRUPT_LINE:
+               /* LINE PIN MIN_GNT MAX_LAT */
+               *value = 0;
+               break;
+
        default:
                *value = 0xffffffff;
                return PCIBIOS_BAD_REGISTER_NUMBER;
index 9042fdbd724405bc96808ed699a1d543fcf17c17..25f0bc6591645707bb3b452bbaa4c28bee0efc59 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/cpu.h>
 #include <linux/pm_runtime.h>
 #include <linux/suspend.h>
+#include <linux/kexec.h>
 #include "pci.h"
 
 struct pci_dynid {
@@ -288,12 +289,27 @@ static int pci_call_probe(struct pci_driver *drv, struct pci_dev *dev,
        int error, node;
        struct drv_dev_and_id ddi = { drv, dev, id };
 
-       /* Execute driver initialization on node where the device's
-          bus is attached to.  This way the driver likely allocates
-          its local memory on the right node without any need to
-          change it. */
+       /*
+        * Execute driver initialization on node where the device is
+        * attached.  This way the driver likely allocates its local memory
+        * on the right node.
+        */
        node = dev_to_node(&dev->dev);
-       if (node >= 0) {
+
+       /*
+        * On NUMA systems, we are likely to call a PF probe function using
+        * work_on_cpu().  If that probe calls pci_enable_sriov() (which
+        * adds the VF devices via pci_bus_add_device()), we may re-enter
+        * this function to call the VF probe function.  Calling
+        * work_on_cpu() again will cause a lockdep warning.  Since VFs are
+        * always on the same node as the PF, we can work around this by
+        * avoiding work_on_cpu() when we're already on the correct node.
+        *
+        * Preemption is enabled, so it's theoretically unsafe to use
+        * numa_node_id(), but even if we run the probe function on the
+        * wrong node, it should be functionally correct.
+        */
+       if (node >= 0 && node != numa_node_id()) {
                int cpu;
 
                get_online_cpus();
@@ -305,6 +321,7 @@ static int pci_call_probe(struct pci_driver *drv, struct pci_dev *dev,
                put_online_cpus();
        } else
                error = local_pci_probe(&ddi);
+
        return error;
 }
 
@@ -399,12 +416,17 @@ static void pci_device_shutdown(struct device *dev)
        pci_msi_shutdown(pci_dev);
        pci_msix_shutdown(pci_dev);
 
+#ifdef CONFIG_KEXEC
        /*
-        * Turn off Bus Master bit on the device to tell it to not
-        * continue to do DMA. Don't touch devices in D3cold or unknown states.
+        * If this is a kexec reboot, turn off Bus Master bit on the
+        * device to tell it to not continue to do DMA. Don't touch
+        * devices in D3cold or unknown states.
+        * If it is not a kexec reboot, firmware will hit the PCI
+        * devices with big hammer and stop their DMA any way.
         */
-       if (pci_dev->current_state <= PCI_D3hot)
+       if (kexec_in_progress && (pci_dev->current_state <= PCI_D3hot))
                pci_clear_master(pci_dev);
+#endif
 }
 
 #ifdef CONFIG_PM
index 33120d15666895a2b48aec1c83f7b41f7b93c3be..07369f32e8bbdd79b1294ad844baeb7dc80ef7ea 100644 (file)
@@ -4165,6 +4165,14 @@ int pci_set_vga_state(struct pci_dev *dev, bool decode,
        return 0;
 }
 
+bool pci_device_is_present(struct pci_dev *pdev)
+{
+       u32 v;
+
+       return pci_bus_read_dev_vendor_id(pdev->bus, pdev->devfn, &v, 0);
+}
+EXPORT_SYMBOL_GPL(pci_device_is_present);
+
 #define RESOURCE_ALIGNMENT_PARAM_SIZE COMMAND_LINE_SIZE
 static char resource_alignment_param[RESOURCE_ALIGNMENT_PARAM_SIZE] = {0};
 static DEFINE_SPINLOCK(resource_alignment_lock);
index 1576851028db700be2413b01e815cc8387b3cd47..cc9337a71529180eaebc7beb991dfb7c9e186ea8 100644 (file)
@@ -24,7 +24,7 @@ static void pci_stop_dev(struct pci_dev *dev)
        if (dev->is_added) {
                pci_proc_detach_device(dev);
                pci_remove_sysfs_dev_files(dev);
-               device_del(&dev->dev);
+               device_release_driver(&dev->dev);
                dev->is_added = 0;
        }
 
@@ -34,6 +34,8 @@ static void pci_stop_dev(struct pci_dev *dev)
 
 static void pci_destroy_dev(struct pci_dev *dev)
 {
+       device_del(&dev->dev);
+
        down_write(&pci_bus_sem);
        list_del(&dev->bus_list);
        up_write(&pci_bus_sem);
index a344f3d52361f0eed4d2a0d1fdc81a957e3a7967..330ef2d065670eb91b84a6d553bdf1df2dabf79f 100644 (file)
@@ -24,8 +24,8 @@ config PHY_EXYNOS_MIPI_VIDEO
 config OMAP_USB2
        tristate "OMAP USB2 PHY Driver"
        depends on ARCH_OMAP2PLUS
+       depends on USB_PHY
        select GENERIC_PHY
-       select USB_PHY
        select OMAP_CONTROL_USB
        help
          Enable this to support the transceiver that is part of SOC. This
@@ -36,8 +36,8 @@ config OMAP_USB2
 config TWL4030_USB
        tristate "TWL4030 USB Transceiver Driver"
        depends on TWL4030_CORE && REGULATOR_TWL4030 && USB_MUSB_OMAP2PLUS
+       depends on USB_PHY
        select GENERIC_PHY
-       select USB_PHY
        help
          Enable this to support the USB OTG transceiver on TWL4030
          family chips (including the TWL5030 and TPS659x0 devices).
index 03cf8fb815543537fb14995fde36a5216706dab9..58e0e97390287364287eae1eecdf8b43ba7b72f1 100644 (file)
@@ -437,23 +437,18 @@ struct phy *phy_create(struct device *dev, const struct phy_ops *ops,
        int id;
        struct phy *phy;
 
-       if (!dev) {
-               dev_WARN(dev, "no device provided for PHY\n");
-               ret = -EINVAL;
-               goto err0;
-       }
+       if (WARN_ON(!dev))
+               return ERR_PTR(-EINVAL);
 
        phy = kzalloc(sizeof(*phy), GFP_KERNEL);
-       if (!phy) {
-               ret = -ENOMEM;
-               goto err0;
-       }
+       if (!phy)
+               return ERR_PTR(-ENOMEM);
 
        id = ida_simple_get(&phy_ida, 0, 0, GFP_KERNEL);
        if (id < 0) {
                dev_err(dev, "unable to get id\n");
                ret = id;
-               goto err0;
+               goto free_phy;
        }
 
        device_initialize(&phy->dev);
@@ -468,11 +463,11 @@ struct phy *phy_create(struct device *dev, const struct phy_ops *ops,
 
        ret = dev_set_name(&phy->dev, "phy-%s.%d", dev_name(dev), id);
        if (ret)
-               goto err1;
+               goto put_dev;
 
        ret = device_add(&phy->dev);
        if (ret)
-               goto err1;
+               goto put_dev;
 
        if (pm_runtime_enabled(dev)) {
                pm_runtime_enable(&phy->dev);
@@ -481,12 +476,11 @@ struct phy *phy_create(struct device *dev, const struct phy_ops *ops,
 
        return phy;
 
-err1:
-       ida_remove(&phy_ida, phy->id);
+put_dev:
        put_device(&phy->dev);
+       ida_remove(&phy_ida, phy->id);
+free_phy:
        kfree(phy);
-
-err0:
        return ERR_PTR(ret);
 }
 EXPORT_SYMBOL_GPL(phy_create);
index 11bd0d970a5246a378185e77955e957d7b4e7376..e2142956a8e5fff5bd1363f3e6837e00b1064bff 100644 (file)
@@ -254,7 +254,7 @@ struct sh_pfc_soc_info {
 #define PINMUX_GPIO(_pin)                                              \
        [GPIO_##_pin] = {                                               \
                .pin = (u16)-1,                                         \
-               .name = __stringify(name),                              \
+               .name = __stringify(GPIO_##_pin),                       \
                .enum_id = _pin##_DATA,                                 \
        }
 
index 5917fe3dc983dc5335d62e393fe079459817d439..b9f1d24c6812eb91d0cf55031c617888b914c560 100644 (file)
@@ -590,8 +590,8 @@ static int as3722_sd016_set_current_limit(struct regulator_dev *rdev,
        default:
                return -EINVAL;
        }
+       ret <<= ffs(mask) - 1;
        val = ret & mask;
-       val <<= ffs(mask) - 1;
        return as3722_update_bits(as3722, reg, mask, val);
 }
 
index 3fe13130baec12218a58230863b313bf4c20d034..d85f31385b24fe9b68ae45dfe0ece4be0ecc2ceb 100644 (file)
@@ -119,6 +119,11 @@ static const char *rdev_get_name(struct regulator_dev *rdev)
                return "";
 }
 
+static bool have_full_constraints(void)
+{
+       return has_full_constraints || of_have_populated_dt();
+}
+
 /**
  * of_get_regulator - get a regulator device node based on supply name
  * @dev: Device pointer for the consumer (of regulator) device
@@ -1340,7 +1345,7 @@ static struct regulator *_regulator_get(struct device *dev, const char *id,
         * Assume that a regulator is physically present and enabled
         * even if it isn't hooked up and just provide a dummy.
         */
-       if (has_full_constraints && allow_dummy) {
+       if (have_full_constraints() && allow_dummy) {
                pr_warn("%s supply %s not found, using dummy regulator\n",
                        devname, id);
 
@@ -3627,7 +3632,7 @@ int regulator_suspend_finish(void)
                        if (error)
                                ret = error;
                } else {
-                       if (!has_full_constraints)
+                       if (!have_full_constraints())
                                goto unlock;
                        if (!ops->disable)
                                goto unlock;
@@ -3825,7 +3830,7 @@ static int __init regulator_init_complete(void)
                if (!enabled)
                        goto unlock;
 
-               if (has_full_constraints) {
+               if (have_full_constraints()) {
                        /* We log since this may kill the system if it
                         * goes wrong. */
                        rdev_info(rdev, "disabling\n");
index 032df3799efb7a144f6c1eef5cd0a3dfe17b6e50..8b5e4c712a0190b0643c6ee40a8918582829d4fd 100644 (file)
@@ -38,7 +38,7 @@
 
 #define PFUZE100_DEVICEID      0x0
 #define PFUZE100_REVID         0x3
-#define PFUZE100_FABID         0x3
+#define PFUZE100_FABID         0x4
 
 #define PFUZE100_SW1ABVOL      0x20
 #define PFUZE100_SW1CVOL       0x2e
index 333677d68d0ee31f784e76906bc930b592fc7257..9e61922d82302372c08ab5499b676a4b51363248 100644 (file)
@@ -438,7 +438,7 @@ common_reg:
        platform_set_drvdata(pdev, s2mps11);
 
        config.dev = &pdev->dev;
-       config.regmap = iodev->regmap;
+       config.regmap = iodev->regmap_pmic;
        config.driver_data = s2mps11;
        for (i = 0; i < S2MPS11_REGULATOR_MAX; i++) {
                if (!reg_np) {
index cbf91e25cf7ff2a632270caed53d05533fcf81db..aeb40aad0ae7775442f775403fdaea047bdd16d8 100644 (file)
@@ -925,7 +925,7 @@ static int s5m8767_pmic_probe(struct platform_device *pdev)
                config.dev = s5m8767->dev;
                config.init_data = pdata->regulators[i].initdata;
                config.driver_data = s5m8767;
-               config.regmap = iodev->regmap;
+               config.regmap = iodev->regmap_pmic;
                config.of_node = pdata->regulators[i].reg_node;
 
                rdev[i] = devm_regulator_register(&pdev->dev, &regulators[id],
index c0da95e95702123d403bf58ed4b894a104eeb2ec..3281c90691c3e143fe14142c9234e3f0a60650e6 100644 (file)
@@ -220,6 +220,8 @@ static int at91_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
 
        at91_alarm_year = tm.tm_year;
 
+       tm.tm_mon = alrm->time.tm_mon;
+       tm.tm_mday = alrm->time.tm_mday;
        tm.tm_hour = alrm->time.tm_hour;
        tm.tm_min = alrm->time.tm_min;
        tm.tm_sec = alrm->time.tm_sec;
index b7fd02bc0a1473a41f00bc233f845551085f5009..ae8119dc2846aac28c8f47019720bf93fd39803f 100644 (file)
 #include <linux/mfd/samsung/irq.h>
 #include <linux/mfd/samsung/rtc.h>
 
+/*
+ * Maximum number of retries for checking changes in UDR field
+ * of SEC_RTC_UDR_CON register (to limit possible endless loop).
+ *
+ * After writing to RTC registers (setting time or alarm) read the UDR field
+ * in SEC_RTC_UDR_CON register. UDR is auto-cleared when data have
+ * been transferred.
+ */
+#define UDR_READ_RETRY_CNT     5
+
 struct s5m_rtc_info {
        struct device *dev;
        struct sec_pmic_dev *s5m87xx;
-       struct regmap *rtc;
+       struct regmap *regmap;
        struct rtc_device *rtc_dev;
        int irq;
        int device_type;
@@ -84,12 +94,31 @@ static int s5m8767_tm_to_data(struct rtc_time *tm, u8 *data)
        }
 }
 
+/*
+ * Read RTC_UDR_CON register and wait till UDR field is cleared.
+ * This indicates that time/alarm update ended.
+ */
+static inline int s5m8767_wait_for_udr_update(struct s5m_rtc_info *info)
+{
+       int ret, retry = UDR_READ_RETRY_CNT;
+       unsigned int data;
+
+       do {
+               ret = regmap_read(info->regmap, SEC_RTC_UDR_CON, &data);
+       } while (--retry && (data & RTC_UDR_MASK) && !ret);
+
+       if (!retry)
+               dev_err(info->dev, "waiting for UDR update, reached max number of retries\n");
+
+       return ret;
+}
+
 static inline int s5m8767_rtc_set_time_reg(struct s5m_rtc_info *info)
 {
        int ret;
        unsigned int data;
 
-       ret = regmap_read(info->rtc, SEC_RTC_UDR_CON, &data);
+       ret = regmap_read(info->regmap, SEC_RTC_UDR_CON, &data);
        if (ret < 0) {
                dev_err(info->dev, "failed to read update reg(%d)\n", ret);
                return ret;
@@ -98,15 +127,13 @@ static inline int s5m8767_rtc_set_time_reg(struct s5m_rtc_info *info)
        data |= RTC_TIME_EN_MASK;
        data |= RTC_UDR_MASK;
 
-       ret = regmap_write(info->rtc, SEC_RTC_UDR_CON, data);
+       ret = regmap_write(info->regmap, SEC_RTC_UDR_CON, data);
        if (ret < 0) {
                dev_err(info->dev, "failed to write update reg(%d)\n", ret);
                return ret;
        }
 
-       do {
-               ret = regmap_read(info->rtc, SEC_RTC_UDR_CON, &data);
-       } while ((data & RTC_UDR_MASK) && !ret);
+       ret = s5m8767_wait_for_udr_update(info);
 
        return ret;
 }
@@ -116,7 +143,7 @@ static inline int s5m8767_rtc_set_alarm_reg(struct s5m_rtc_info *info)
        int ret;
        unsigned int data;
 
-       ret = regmap_read(info->rtc, SEC_RTC_UDR_CON, &data);
+       ret = regmap_read(info->regmap, SEC_RTC_UDR_CON, &data);
        if (ret < 0) {
                dev_err(info->dev, "%s: fail to read update reg(%d)\n",
                        __func__, ret);
@@ -126,16 +153,14 @@ static inline int s5m8767_rtc_set_alarm_reg(struct s5m_rtc_info *info)
        data &= ~RTC_TIME_EN_MASK;
        data |= RTC_UDR_MASK;
 
-       ret = regmap_write(info->rtc, SEC_RTC_UDR_CON, data);
+       ret = regmap_write(info->regmap, SEC_RTC_UDR_CON, data);
        if (ret < 0) {
                dev_err(info->dev, "%s: fail to write update reg(%d)\n",
                        __func__, ret);
                return ret;
        }
 
-       do {
-               ret = regmap_read(info->rtc, SEC_RTC_UDR_CON, &data);
-       } while ((data & RTC_UDR_MASK) && !ret);
+       ret = s5m8767_wait_for_udr_update(info);
 
        return ret;
 }
@@ -178,7 +203,7 @@ static int s5m_rtc_read_time(struct device *dev, struct rtc_time *tm)
        u8 data[8];
        int ret;
 
-       ret = regmap_bulk_read(info->rtc, SEC_RTC_SEC, data, 8);
+       ret = regmap_bulk_read(info->regmap, SEC_RTC_SEC, data, 8);
        if (ret < 0)
                return ret;
 
@@ -226,7 +251,7 @@ static int s5m_rtc_set_time(struct device *dev, struct rtc_time *tm)
                1900 + tm->tm_year, 1 + tm->tm_mon, tm->tm_mday,
                tm->tm_hour, tm->tm_min, tm->tm_sec, tm->tm_wday);
 
-       ret = regmap_raw_write(info->rtc, SEC_RTC_SEC, data, 8);
+       ret = regmap_raw_write(info->regmap, SEC_RTC_SEC, data, 8);
        if (ret < 0)
                return ret;
 
@@ -242,20 +267,20 @@ static int s5m_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
        unsigned int val;
        int ret, i;
 
-       ret = regmap_bulk_read(info->rtc, SEC_ALARM0_SEC, data, 8);
+       ret = regmap_bulk_read(info->regmap, SEC_ALARM0_SEC, data, 8);
        if (ret < 0)
                return ret;
 
        switch (info->device_type) {
        case S5M8763X:
                s5m8763_data_to_tm(data, &alrm->time);
-               ret = regmap_read(info->rtc, SEC_ALARM0_CONF, &val);
+               ret = regmap_read(info->regmap, SEC_ALARM0_CONF, &val);
                if (ret < 0)
                        return ret;
 
                alrm->enabled = !!val;
 
-               ret = regmap_read(info->rtc, SEC_RTC_STATUS, &val);
+               ret = regmap_read(info->regmap, SEC_RTC_STATUS, &val);
                if (ret < 0)
                        return ret;
 
@@ -278,7 +303,7 @@ static int s5m_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
                }
 
                alrm->pending = 0;
-               ret = regmap_read(info->rtc, SEC_RTC_STATUS, &val);
+               ret = regmap_read(info->regmap, SEC_RTC_STATUS, &val);
                if (ret < 0)
                        return ret;
                break;
@@ -301,7 +326,7 @@ static int s5m_rtc_stop_alarm(struct s5m_rtc_info *info)
        int ret, i;
        struct rtc_time tm;
 
-       ret = regmap_bulk_read(info->rtc, SEC_ALARM0_SEC, data, 8);
+       ret = regmap_bulk_read(info->regmap, SEC_ALARM0_SEC, data, 8);
        if (ret < 0)
                return ret;
 
@@ -312,14 +337,14 @@ static int s5m_rtc_stop_alarm(struct s5m_rtc_info *info)
 
        switch (info->device_type) {
        case S5M8763X:
-               ret = regmap_write(info->rtc, SEC_ALARM0_CONF, 0);
+               ret = regmap_write(info->regmap, SEC_ALARM0_CONF, 0);
                break;
 
        case S5M8767X:
                for (i = 0; i < 7; i++)
                        data[i] &= ~ALARM_ENABLE_MASK;
 
-               ret = regmap_raw_write(info->rtc, SEC_ALARM0_SEC, data, 8);
+               ret = regmap_raw_write(info->regmap, SEC_ALARM0_SEC, data, 8);
                if (ret < 0)
                        return ret;
 
@@ -341,7 +366,7 @@ static int s5m_rtc_start_alarm(struct s5m_rtc_info *info)
        u8 alarm0_conf;
        struct rtc_time tm;
 
-       ret = regmap_bulk_read(info->rtc, SEC_ALARM0_SEC, data, 8);
+       ret = regmap_bulk_read(info->regmap, SEC_ALARM0_SEC, data, 8);
        if (ret < 0)
                return ret;
 
@@ -353,7 +378,7 @@ static int s5m_rtc_start_alarm(struct s5m_rtc_info *info)
        switch (info->device_type) {
        case S5M8763X:
                alarm0_conf = 0x77;
-               ret = regmap_write(info->rtc, SEC_ALARM0_CONF, alarm0_conf);
+               ret = regmap_write(info->regmap, SEC_ALARM0_CONF, alarm0_conf);
                break;
 
        case S5M8767X:
@@ -368,7 +393,7 @@ static int s5m_rtc_start_alarm(struct s5m_rtc_info *info)
                if (data[RTC_YEAR1] & 0x7f)
                        data[RTC_YEAR1] |= ALARM_ENABLE_MASK;
 
-               ret = regmap_raw_write(info->rtc, SEC_ALARM0_SEC, data, 8);
+               ret = regmap_raw_write(info->regmap, SEC_ALARM0_SEC, data, 8);
                if (ret < 0)
                        return ret;
                ret = s5m8767_rtc_set_alarm_reg(info);
@@ -410,7 +435,7 @@ static int s5m_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
        if (ret < 0)
                return ret;
 
-       ret = regmap_raw_write(info->rtc, SEC_ALARM0_SEC, data, 8);
+       ret = regmap_raw_write(info->regmap, SEC_ALARM0_SEC, data, 8);
        if (ret < 0)
                return ret;
 
@@ -455,7 +480,7 @@ static const struct rtc_class_ops s5m_rtc_ops = {
 static void s5m_rtc_enable_wtsr(struct s5m_rtc_info *info, bool enable)
 {
        int ret;
-       ret = regmap_update_bits(info->rtc, SEC_WTSR_SMPL_CNTL,
+       ret = regmap_update_bits(info->regmap, SEC_WTSR_SMPL_CNTL,
                                 WTSR_ENABLE_MASK,
                                 enable ? WTSR_ENABLE_MASK : 0);
        if (ret < 0)
@@ -466,7 +491,7 @@ static void s5m_rtc_enable_wtsr(struct s5m_rtc_info *info, bool enable)
 static void s5m_rtc_enable_smpl(struct s5m_rtc_info *info, bool enable)
 {
        int ret;
-       ret = regmap_update_bits(info->rtc, SEC_WTSR_SMPL_CNTL,
+       ret = regmap_update_bits(info->regmap, SEC_WTSR_SMPL_CNTL,
                                 SMPL_ENABLE_MASK,
                                 enable ? SMPL_ENABLE_MASK : 0);
        if (ret < 0)
@@ -481,7 +506,7 @@ static int s5m8767_rtc_init_reg(struct s5m_rtc_info *info)
        int ret;
        struct rtc_time tm;
 
-       ret = regmap_read(info->rtc, SEC_RTC_UDR_CON, &tp_read);
+       ret = regmap_read(info->regmap, SEC_RTC_UDR_CON, &tp_read);
        if (ret < 0) {
                dev_err(info->dev, "%s: fail to read control reg(%d)\n",
                        __func__, ret);
@@ -493,7 +518,7 @@ static int s5m8767_rtc_init_reg(struct s5m_rtc_info *info)
        data[1] = (0 << BCD_EN_SHIFT) | (1 << MODEL24_SHIFT);
 
        info->rtc_24hr_mode = 1;
-       ret = regmap_raw_write(info->rtc, SEC_ALARM0_CONF, data, 2);
+       ret = regmap_raw_write(info->regmap, SEC_ALARM0_CONF, data, 2);
        if (ret < 0) {
                dev_err(info->dev, "%s: fail to write controlm reg(%d)\n",
                        __func__, ret);
@@ -515,7 +540,7 @@ static int s5m8767_rtc_init_reg(struct s5m_rtc_info *info)
                ret = s5m_rtc_set_time(info->dev, &tm);
        }
 
-       ret = regmap_update_bits(info->rtc, SEC_RTC_UDR_CON,
+       ret = regmap_update_bits(info->regmap, SEC_RTC_UDR_CON,
                                 RTC_TCON_MASK, tp_read | RTC_TCON_MASK);
        if (ret < 0)
                dev_err(info->dev, "%s: fail to update TCON reg(%d)\n",
@@ -542,17 +567,19 @@ static int s5m_rtc_probe(struct platform_device *pdev)
 
        info->dev = &pdev->dev;
        info->s5m87xx = s5m87xx;
-       info->rtc = s5m87xx->rtc;
+       info->regmap = s5m87xx->regmap_rtc;
        info->device_type = s5m87xx->device_type;
        info->wtsr_smpl = s5m87xx->wtsr_smpl;
 
        switch (pdata->device_type) {
        case S5M8763X:
-               info->irq = s5m87xx->irq_base + S5M8763_IRQ_ALARM0;
+               info->irq = regmap_irq_get_virq(s5m87xx->irq_data,
+                               S5M8763_IRQ_ALARM0);
                break;
 
        case S5M8767X:
-               info->irq = s5m87xx->irq_base + S5M8767_IRQ_RTCA1;
+               info->irq = regmap_irq_get_virq(s5m87xx->irq_data,
+                               S5M8767_IRQ_RTCA1);
                break;
 
        default:
@@ -596,7 +623,7 @@ static void s5m_rtc_shutdown(struct platform_device *pdev)
        if (info->wtsr_smpl) {
                for (i = 0; i < 3; i++) {
                        s5m_rtc_enable_wtsr(info, false);
-                       regmap_read(info->rtc, SEC_WTSR_SMPL_CNTL, &val);
+                       regmap_read(info->regmap, SEC_WTSR_SMPL_CNTL, &val);
                        pr_debug("%s: WTSR_SMPL reg(0x%02x)\n", __func__, val);
                        if (val & WTSR_ENABLE_MASK)
                                pr_emerg("%s: fail to disable WTSR\n",
@@ -612,6 +639,30 @@ static void s5m_rtc_shutdown(struct platform_device *pdev)
        s5m_rtc_enable_smpl(info, false);
 }
 
+static int s5m_rtc_resume(struct device *dev)
+{
+       struct s5m_rtc_info *info = dev_get_drvdata(dev);
+       int ret = 0;
+
+       if (device_may_wakeup(dev))
+               ret = disable_irq_wake(info->irq);
+
+       return ret;
+}
+
+static int s5m_rtc_suspend(struct device *dev)
+{
+       struct s5m_rtc_info *info = dev_get_drvdata(dev);
+       int ret = 0;
+
+       if (device_may_wakeup(dev))
+               ret = enable_irq_wake(info->irq);
+
+       return ret;
+}
+
+static SIMPLE_DEV_PM_OPS(s5m_rtc_pm_ops, s5m_rtc_suspend, s5m_rtc_resume);
+
 static const struct platform_device_id s5m_rtc_id[] = {
        { "s5m-rtc", 0 },
 };
@@ -620,6 +671,7 @@ static struct platform_driver s5m_rtc_driver = {
        .driver         = {
                .name   = "s5m-rtc",
                .owner  = THIS_MODULE,
+               .pm     = &s5m_rtc_pm_ops,
        },
        .probe          = s5m_rtc_probe,
        .shutdown       = s5m_rtc_shutdown,
index f64921756ad610375134b3b59f13bbdb5d9906af..f224d59c4b6be35b8a5d827dde6cdc173953f3f5 100644 (file)
@@ -87,7 +87,6 @@ void dasd_gendisk_free(struct dasd_block *block)
 {
        if (block->gdp) {
                del_gendisk(block->gdp);
-               block->gdp->queue = NULL;
                block->gdp->private_data = NULL;
                put_disk(block->gdp);
                block->gdp = NULL;
index f7aa080e9b28db1d5b962de7b5380f60ae97cc10..1465e9563101f0a2cbc697a8f26edb2200368d5f 100644 (file)
@@ -35,7 +35,6 @@ struct read_info_sccb {
        u8      _reserved5[4096 - 112]; /* 112-4095 */
 } __packed __aligned(PAGE_SIZE);
 
-static __initdata struct init_sccb early_event_mask_sccb __aligned(PAGE_SIZE);
 static __initdata struct read_info_sccb early_read_info_sccb;
 static __initdata char sccb_early[PAGE_SIZE] __aligned(PAGE_SIZE);
 static unsigned long sclp_hsa_size;
@@ -113,7 +112,7 @@ static void __init sclp_facilities_detect(void)
 
 bool __init sclp_has_linemode(void)
 {
-       struct init_sccb *sccb = &early_event_mask_sccb;
+       struct init_sccb *sccb = (void *) &sccb_early;
 
        if (sccb->header.response_code != 0x20)
                return 0;
@@ -126,7 +125,7 @@ bool __init sclp_has_linemode(void)
 
 bool __init sclp_has_vt220(void)
 {
-       struct init_sccb *sccb = &early_event_mask_sccb;
+       struct init_sccb *sccb = (void *) &sccb_early;
 
        if (sccb->header.response_code != 0x20)
                return 0;
index 8f02bf66e20b2002b3b52655919a89f95c0fcad9..4964d2a2fc7d54ba099541b3f9c2c61be4799936 100644 (file)
@@ -446,7 +446,7 @@ int comedi_load_firmware(struct comedi_device *dev,
                release_firmware(fw);
        }
 
-       return ret;
+       return ret < 0 ? ret : 0;
 }
 EXPORT_SYMBOL_GPL(comedi_load_firmware);
 
index 432e3f9c3301ecc7ce6f6d633913bf1e1e85f4e4..c55f234b29e6052e541dc7b7043d0a877682b4cb 100644 (file)
@@ -63,7 +63,8 @@ enum pci_8255_boardid {
        BOARD_ADLINK_PCI7296,
        BOARD_CB_PCIDIO24,
        BOARD_CB_PCIDIO24H,
-       BOARD_CB_PCIDIO48H,
+       BOARD_CB_PCIDIO48H_OLD,
+       BOARD_CB_PCIDIO48H_NEW,
        BOARD_CB_PCIDIO96H,
        BOARD_NI_PCIDIO96,
        BOARD_NI_PCIDIO96B,
@@ -106,11 +107,16 @@ static const struct pci_8255_boardinfo pci_8255_boards[] = {
                .dio_badr       = 2,
                .n_8255         = 1,
        },
-       [BOARD_CB_PCIDIO48H] = {
+       [BOARD_CB_PCIDIO48H_OLD] = {
                .name           = "cb_pci-dio48h",
                .dio_badr       = 1,
                .n_8255         = 2,
        },
+       [BOARD_CB_PCIDIO48H_NEW] = {
+               .name           = "cb_pci-dio48h",
+               .dio_badr       = 2,
+               .n_8255         = 2,
+       },
        [BOARD_CB_PCIDIO96H] = {
                .name           = "cb_pci-dio96h",
                .dio_badr       = 2,
@@ -263,7 +269,10 @@ static DEFINE_PCI_DEVICE_TABLE(pci_8255_pci_table) = {
        { PCI_VDEVICE(ADLINK, 0x7296), BOARD_ADLINK_PCI7296 },
        { PCI_VDEVICE(CB, 0x0028), BOARD_CB_PCIDIO24 },
        { PCI_VDEVICE(CB, 0x0014), BOARD_CB_PCIDIO24H },
-       { PCI_VDEVICE(CB, 0x000b), BOARD_CB_PCIDIO48H },
+       { PCI_DEVICE_SUB(PCI_VENDOR_ID_CB, 0x000b, 0x0000, 0x0000),
+         .driver_data = BOARD_CB_PCIDIO48H_OLD },
+       { PCI_DEVICE_SUB(PCI_VENDOR_ID_CB, 0x000b, PCI_VENDOR_ID_CB, 0x000b),
+         .driver_data = BOARD_CB_PCIDIO48H_NEW },
        { PCI_VDEVICE(CB, 0x0017), BOARD_CB_PCIDIO96H },
        { PCI_VDEVICE(NI, 0x0160), BOARD_NI_PCIDIO96 },
        { PCI_VDEVICE(NI, 0x1630), BOARD_NI_PCIDIO96B },
index 99421f90d1895f6a0691d4443c457f5aac2335db..0485d7f398672a61045367b7ac85a267b34b6e8d 100644 (file)
@@ -451,7 +451,12 @@ done:
                .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |  \
                        BIT(IIO_CHAN_INFO_SAMP_FREQ),                   \
                .scan_index = idx,                                      \
-               .scan_type = IIO_ST('s', 16, 16, IIO_BE),               \
+               .scan_type = {                                          \
+                       .sign = 's',                                    \
+                       .realbits = 16,                                 \
+                       .storagebits = 16,                              \
+                       .endianness = IIO_BE,                           \
+               },                                                      \
        }
 
 static const struct iio_chan_spec hmc5843_channels[] = {
index 6bd015ac9d683474a034924f8ffec3e752e1d382..96e4eee344ef602174acec2ce27cf57bfb0ce128 100644 (file)
@@ -88,8 +88,9 @@ static int imx_drm_driver_unload(struct drm_device *drm)
 
        imx_drm_device_put();
 
-       drm_mode_config_cleanup(imxdrm->drm);
+       drm_vblank_cleanup(imxdrm->drm);
        drm_kms_helper_poll_fini(imxdrm->drm);
+       drm_mode_config_cleanup(imxdrm->drm);
 
        return 0;
 }
@@ -199,8 +200,8 @@ static void imx_drm_driver_preclose(struct drm_device *drm,
        if (!file->is_master)
                return;
 
-       for (i = 0; i < 4; i++)
-               imx_drm_disable_vblank(drm , i);
+       for (i = 0; i < MAX_CRTC; i++)
+               imx_drm_disable_vblank(drm, i);
 }
 
 static const struct file_operations imx_drm_driver_fops = {
@@ -376,8 +377,6 @@ static int imx_drm_crtc_register(struct imx_drm_crtc *imx_drm_crtc)
        struct imx_drm_device *imxdrm = __imx_drm_device();
        int ret;
 
-       drm_crtc_init(imxdrm->drm, imx_drm_crtc->crtc,
-                       imx_drm_crtc->imx_drm_helper_funcs.crtc_funcs);
        ret = drm_mode_crtc_set_gamma_size(imx_drm_crtc->crtc, 256);
        if (ret)
                return ret;
@@ -385,6 +384,9 @@ static int imx_drm_crtc_register(struct imx_drm_crtc *imx_drm_crtc)
        drm_crtc_helper_add(imx_drm_crtc->crtc,
                        imx_drm_crtc->imx_drm_helper_funcs.crtc_helper_funcs);
 
+       drm_crtc_init(imxdrm->drm, imx_drm_crtc->crtc,
+                       imx_drm_crtc->imx_drm_helper_funcs.crtc_funcs);
+
        drm_mode_group_reinit(imxdrm->drm);
 
        return 0;
@@ -428,11 +430,11 @@ static int imx_drm_driver_load(struct drm_device *drm, unsigned long flags)
        ret = drm_mode_group_init_legacy_group(imxdrm->drm,
                        &imxdrm->drm->primary->mode_group);
        if (ret)
-               goto err_init;
+               goto err_kms;
 
        ret = drm_vblank_init(imxdrm->drm, MAX_CRTC);
        if (ret)
-               goto err_init;
+               goto err_kms;
 
        /*
         * with vblank_disable_allowed = true, vblank interrupt will be disabled
@@ -441,12 +443,19 @@ static int imx_drm_driver_load(struct drm_device *drm, unsigned long flags)
         */
        imxdrm->drm->vblank_disable_allowed = true;
 
-       if (!imx_drm_device_get())
+       if (!imx_drm_device_get()) {
                ret = -EINVAL;
+               goto err_vblank;
+       }
 
-       ret = 0;
+       mutex_unlock(&imxdrm->mutex);
+       return 0;
 
-err_init:
+err_vblank:
+       drm_vblank_cleanup(drm);
+err_kms:
+       drm_kms_helper_poll_fini(drm);
+       drm_mode_config_cleanup(drm);
        mutex_unlock(&imxdrm->mutex);
 
        return ret;
@@ -492,6 +501,15 @@ int imx_drm_add_crtc(struct drm_crtc *crtc,
 
        mutex_lock(&imxdrm->mutex);
 
+       /*
+        * The vblank arrays are dimensioned by MAX_CRTC - we can't
+        * pass IDs greater than this to those functions.
+        */
+       if (imxdrm->pipes >= MAX_CRTC) {
+               ret = -EINVAL;
+               goto err_busy;
+       }
+
        if (imxdrm->drm->open_count) {
                ret = -EBUSY;
                goto err_busy;
@@ -528,6 +546,7 @@ int imx_drm_add_crtc(struct drm_crtc *crtc,
        return 0;
 
 err_register:
+       list_del(&imx_drm_crtc->list);
        kfree(imx_drm_crtc);
 err_alloc:
 err_busy:
index 680f4c8fa0815481a410621eb616879dbb149109..2c44fef8d58b327df92e97667f0661c45e3e57d6 100644 (file)
@@ -114,7 +114,6 @@ struct imx_tve {
        struct drm_encoder encoder;
        struct imx_drm_encoder *imx_drm_encoder;
        struct device *dev;
-       spinlock_t enable_lock; /* serializes tve_enable/disable */
        spinlock_t lock;        /* register lock */
        bool enabled;
        int mode;
@@ -146,10 +145,8 @@ __releases(&tve->lock)
 
 static void tve_enable(struct imx_tve *tve)
 {
-       unsigned long flags;
        int ret;
 
-       spin_lock_irqsave(&tve->enable_lock, flags);
        if (!tve->enabled) {
                tve->enabled = true;
                clk_prepare_enable(tve->clk);
@@ -169,23 +166,18 @@ static void tve_enable(struct imx_tve *tve)
                             TVE_CD_SM_IEN |
                             TVE_CD_LM_IEN |
                             TVE_CD_MON_END_IEN);
-
-       spin_unlock_irqrestore(&tve->enable_lock, flags);
 }
 
 static void tve_disable(struct imx_tve *tve)
 {
-       unsigned long flags;
        int ret;
 
-       spin_lock_irqsave(&tve->enable_lock, flags);
        if (tve->enabled) {
                tve->enabled = false;
                ret = regmap_update_bits(tve->regmap, TVE_COM_CONF_REG,
                                         TVE_IPU_CLK_EN | TVE_EN, 0);
                clk_disable_unprepare(tve->clk);
        }
-       spin_unlock_irqrestore(&tve->enable_lock, flags);
 }
 
 static int tve_setup_tvout(struct imx_tve *tve)
@@ -601,7 +593,6 @@ static int imx_tve_probe(struct platform_device *pdev)
 
        tve->dev = &pdev->dev;
        spin_lock_init(&tve->lock);
-       spin_lock_init(&tve->enable_lock);
 
        ddc_node = of_parse_phandle(np, "ddc", 0);
        if (ddc_node) {
index 7a22ce619ed264ba536de785650700b02f6d3ef3..97ca6924dbb3fce7b5db813aefb781adb273187a 100644 (file)
@@ -996,35 +996,35 @@ static const struct ipu_platform_reg client_reg[] = {
        },
 };
 
+static DEFINE_MUTEX(ipu_client_id_mutex);
 static int ipu_client_id;
 
-static int ipu_add_subdevice_pdata(struct device *dev,
-               const struct ipu_platform_reg *reg)
-{
-       struct platform_device *pdev;
-
-       pdev = platform_device_register_data(dev, reg->name, ipu_client_id++,
-                       &reg->pdata, sizeof(struct ipu_platform_reg));
-
-       return PTR_ERR_OR_ZERO(pdev);
-}
-
 static int ipu_add_client_devices(struct ipu_soc *ipu)
 {
-       int ret;
-       int i;
+       struct device *dev = ipu->dev;
+       unsigned i;
+       int id, ret;
+
+       mutex_lock(&ipu_client_id_mutex);
+       id = ipu_client_id;
+       ipu_client_id += ARRAY_SIZE(client_reg);
+       mutex_unlock(&ipu_client_id_mutex);
 
        for (i = 0; i < ARRAY_SIZE(client_reg); i++) {
                const struct ipu_platform_reg *reg = &client_reg[i];
-               ret = ipu_add_subdevice_pdata(ipu->dev, reg);
-               if (ret)
+               struct platform_device *pdev;
+
+               pdev = platform_device_register_data(dev, reg->name,
+                       id++, &reg->pdata, sizeof(reg->pdata));
+
+               if (IS_ERR(pdev))
                        goto err_register;
        }
 
        return 0;
 
 err_register:
-       platform_device_unregister_children(to_platform_device(ipu->dev));
+       platform_device_unregister_children(to_platform_device(dev));
 
        return ret;
 }
index 268b62768f2b41eab5f7db4d4c5c8b9111f248b6..34aacaaae14ab9b595ea41744504c2cbc65b9ff3 100644 (file)
@@ -93,6 +93,7 @@ struct n_tty_data {
        size_t canon_head;
        size_t echo_head;
        size_t echo_commit;
+       size_t echo_mark;
        DECLARE_BITMAP(char_map, 256);
 
        /* private to n_tty_receive_overrun (single-threaded) */
@@ -336,6 +337,7 @@ static void reset_buffer_flags(struct n_tty_data *ldata)
 {
        ldata->read_head = ldata->canon_head = ldata->read_tail = 0;
        ldata->echo_head = ldata->echo_tail = ldata->echo_commit = 0;
+       ldata->echo_mark = 0;
        ldata->line_start = 0;
 
        ldata->erasing = 0;
@@ -787,6 +789,7 @@ static void commit_echoes(struct tty_struct *tty)
        size_t head;
 
        head = ldata->echo_head;
+       ldata->echo_mark = head;
        old = ldata->echo_commit - ldata->echo_tail;
 
        /* Process committed echoes if the accumulated # of bytes
@@ -811,10 +814,11 @@ static void process_echoes(struct tty_struct *tty)
        size_t echoed;
 
        if ((!L_ECHO(tty) && !L_ECHONL(tty)) ||
-           ldata->echo_commit == ldata->echo_tail)
+           ldata->echo_mark == ldata->echo_tail)
                return;
 
        mutex_lock(&ldata->output_lock);
+       ldata->echo_commit = ldata->echo_mark;
        echoed = __process_echoes(tty);
        mutex_unlock(&ldata->output_lock);
 
@@ -822,6 +826,7 @@ static void process_echoes(struct tty_struct *tty)
                tty->ops->flush_chars(tty);
 }
 
+/* NB: echo_mark and echo_head should be equivalent here */
 static void flush_echoes(struct tty_struct *tty)
 {
        struct n_tty_data *ldata = tty->disc_data;
index 4658e3e0ec4256d9b2e31f890ea72822abf47f93..06525f10e3641bc2140b140a50d8b994acd662d3 100644 (file)
@@ -96,7 +96,8 @@ static void dw8250_serial_out(struct uart_port *p, int offset, int value)
        if (offset == UART_LCR) {
                int tries = 1000;
                while (tries--) {
-                       if (value == p->serial_in(p, UART_LCR))
+                       unsigned int lcr = p->serial_in(p, UART_LCR);
+                       if ((value & ~UART_LCR_SPAR) == (lcr & ~UART_LCR_SPAR))
                                return;
                        dw8250_force_idle(p);
                        writeb(value, p->membase + (UART_LCR << p->regshift));
@@ -132,7 +133,8 @@ static void dw8250_serial_out32(struct uart_port *p, int offset, int value)
        if (offset == UART_LCR) {
                int tries = 1000;
                while (tries--) {
-                       if (value == p->serial_in(p, UART_LCR))
+                       unsigned int lcr = p->serial_in(p, UART_LCR);
+                       if ((value & ~UART_LCR_SPAR) == (lcr & ~UART_LCR_SPAR))
                                return;
                        dw8250_force_idle(p);
                        writel(value, p->membase + (UART_LCR << p->regshift));
@@ -455,6 +457,8 @@ MODULE_DEVICE_TABLE(of, dw8250_of_match);
 static const struct acpi_device_id dw8250_acpi_match[] = {
        { "INT33C4", 0 },
        { "INT33C5", 0 },
+       { "INT3434", 0 },
+       { "INT3435", 0 },
        { "80860F0A", 0 },
        { },
 };
index e46e9f3f19b90d34476b60a2e21aa656fc3c8fae..f619ad5b5eaefc891b6857c03edd942492198e18 100644 (file)
@@ -240,6 +240,7 @@ static irqreturn_t xuartps_isr(int irq, void *dev_id)
                                        continue;
                        }
 
+#ifdef SUPPORT_SYSRQ
                        /*
                         * uart_handle_sysrq_char() doesn't work if
                         * spinlocked, for some reason
@@ -253,6 +254,7 @@ static irqreturn_t xuartps_isr(int irq, void *dev_id)
                                }
                                spin_lock(&port->lock);
                        }
+#endif
 
                        port->icount.rx++;
 
index 22fad8ad5ac206c4cf22f820e9a4cf5c3f6cd8bd..d8a55e87877f06f3141602e4f08cdcb668c465b0 100644 (file)
@@ -86,11 +86,21 @@ static inline long ldsem_atomic_update(long delta, struct ld_semaphore *sem)
        return atomic_long_add_return(delta, (atomic_long_t *)&sem->count);
 }
 
+/*
+ * ldsem_cmpxchg() updates @*old with the last-known sem->count value.
+ * Returns 1 if count was successfully changed; @*old will have @new value.
+ * Returns 0 if count was not changed; @*old will have most recent sem->count
+ */
 static inline int ldsem_cmpxchg(long *old, long new, struct ld_semaphore *sem)
 {
-       long tmp = *old;
-       *old = atomic_long_cmpxchg(&sem->count, *old, new);
-       return *old == tmp;
+       long tmp = atomic_long_cmpxchg(&sem->count, *old, new);
+       if (tmp == *old) {
+               *old = new;
+               return 1;
+       } else {
+               *old = tmp;
+               return 0;
+       }
 }
 
 /*
index 5d8981c5235e50e42776cfb9f672977c11a61ef0..6e73f8cd60e513ca44de8d6bd00fe69085e4453f 100644 (file)
@@ -642,6 +642,10 @@ static int ci_hdrc_probe(struct platform_device *pdev)
                        : CI_ROLE_GADGET;
        }
 
+       /* only update vbus status for peripheral */
+       if (ci->role == CI_ROLE_GADGET)
+               ci_handle_vbus_change(ci);
+
        ret = ci_role_start(ci, ci->role);
        if (ret) {
                dev_err(dev, "can't start %s role\n", ci_role(ci)->name);
index 59e6020ea7539e5e331364ac067c9a16f27855ba..526cd77563d8a89c29f5444901ee3ba366b1575a 100644 (file)
@@ -88,7 +88,8 @@ static int host_start(struct ci_hdrc *ci)
        return ret;
 
 disable_reg:
-       regulator_disable(ci->platdata->reg_vbus);
+       if (ci->platdata->reg_vbus)
+               regulator_disable(ci->platdata->reg_vbus);
 
 put_hcd:
        usb_put_hcd(hcd);
index b34c81969cba672a7e880f405f2445adf36b7e6f..69d20fbb38a26a32357cc9f5d7fc4f81efa08cca 100644 (file)
@@ -1795,9 +1795,6 @@ static int udc_start(struct ci_hdrc *ci)
        pm_runtime_no_callbacks(&ci->gadget.dev);
        pm_runtime_enable(&ci->gadget.dev);
 
-       /* Update ci->vbus_active */
-       ci_handle_vbus_change(ci);
-
        return retval;
 
 destroy_eps:
index 4d387596f3f0a6e531caa1a9049a383d605091b4..0b23a8639311b182ee9e2afddcec1cb888269257 100644 (file)
@@ -854,13 +854,11 @@ static int wdm_manage_power(struct usb_interface *intf, int on)
 {
        /* need autopm_get/put here to ensure the usbcore sees the new value */
        int rv = usb_autopm_get_interface(intf);
-       if (rv < 0)
-               goto err;
 
        intf->needs_remote_wakeup = on;
-       usb_autopm_put_interface(intf);
-err:
-       return rv;
+       if (!rv)
+               usb_autopm_put_interface(intf);
+       return 0;
 }
 
 static int wdm_probe(struct usb_interface *intf, const struct usb_device_id *id)
index 74f9cf02da070a6d1c23b643a56f76e3264fb8cd..a49217ae35333846bb76912666f0efa12bca6813 100644 (file)
@@ -455,9 +455,6 @@ static int dwc3_probe(struct platform_device *pdev)
        if (IS_ERR(regs))
                return PTR_ERR(regs);
 
-       usb_phy_set_suspend(dwc->usb2_phy, 0);
-       usb_phy_set_suspend(dwc->usb3_phy, 0);
-
        spin_lock_init(&dwc->lock);
        platform_set_drvdata(pdev, dwc);
 
@@ -488,6 +485,9 @@ static int dwc3_probe(struct platform_device *pdev)
                goto err0;
        }
 
+       usb_phy_set_suspend(dwc->usb2_phy, 0);
+       usb_phy_set_suspend(dwc->usb3_phy, 0);
+
        ret = dwc3_event_buffers_setup(dwc);
        if (ret) {
                dev_err(dwc->dev, "failed to setup event buffers\n");
@@ -569,6 +569,8 @@ err2:
        dwc3_event_buffers_cleanup(dwc);
 
 err1:
+       usb_phy_set_suspend(dwc->usb2_phy, 1);
+       usb_phy_set_suspend(dwc->usb3_phy, 1);
        dwc3_core_exit(dwc);
 
 err0:
index 418444ebb1b8bb1fd1862fc9233c7562c5c40d81..8c356af79409f9ef4647d141bc6aa5146791496b 100644 (file)
@@ -136,23 +136,27 @@ static int usb_hcd_at91_probe(const struct hc_driver *driver,
        struct ohci_hcd *ohci;
        int retval;
        struct usb_hcd *hcd = NULL;
-
-       if (pdev->num_resources != 2) {
-               pr_debug("hcd probe: invalid num_resources");
-               return -ENODEV;
+       struct device *dev = &pdev->dev;
+       struct resource *res;
+       int irq;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!res) {
+               dev_dbg(dev, "hcd probe: missing memory resource\n");
+               return -ENXIO;
        }
 
-       if ((pdev->resource[0].flags != IORESOURCE_MEM)
-                       || (pdev->resource[1].flags != IORESOURCE_IRQ)) {
-               pr_debug("hcd probe: invalid resource type\n");
-               return -ENODEV;
+       irq = platform_get_irq(pdev, 0);
+       if (irq < 0) {
+               dev_dbg(dev, "hcd probe: missing irq resource\n");
+               return irq;
        }
 
        hcd = usb_create_hcd(driver, &pdev->dev, "at91");
        if (!hcd)
                return -ENOMEM;
-       hcd->rsrc_start = pdev->resource[0].start;
-       hcd->rsrc_len = resource_size(&pdev->resource[0]);
+       hcd->rsrc_start = res->start;
+       hcd->rsrc_len = resource_size(res);
 
        if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
                pr_debug("request_mem_region failed\n");
@@ -199,7 +203,7 @@ static int usb_hcd_at91_probe(const struct hc_driver *driver,
        ohci->num_ports = board->ports;
        at91_start_hc(pdev);
 
-       retval = usb_add_hcd(hcd, pdev->resource[1].start, IRQF_SHARED);
+       retval = usb_add_hcd(hcd, irq, IRQF_SHARED);
        if (retval == 0)
                return retval;
 
index b8dffd59eb256e52786328e5e4f1919846a80d9c..73f5208714a4a4d8270bd85acd1ec625fb9abf71 100644 (file)
@@ -128,7 +128,12 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
                 * any other sleep) on Haswell machines with LPT and LPT-LP
                 * with the new Intel BIOS
                 */
-               xhci->quirks |= XHCI_SPURIOUS_WAKEUP;
+               /* Limit the quirk to only known vendors, as this triggers
+                * yet another BIOS bug on some other machines
+                * https://bugzilla.kernel.org/show_bug.cgi?id=66171
+                */
+               if (pdev->subsystem_vendor == PCI_VENDOR_ID_HP)
+                       xhci->quirks |= XHCI_SPURIOUS_WAKEUP;
        }
        if (pdev->vendor == PCI_VENDOR_ID_ETRON &&
                        pdev->device == PCI_DEVICE_ID_ASROCK_P67) {
index 08e2f39027ec00ae0a7c5ae07b46fdd1cdbfae8f..2b41c636a52a7a1ecf3ae0e3df622d141307c038 100644 (file)
@@ -19,8 +19,9 @@ config AB8500_USB
          in host mode, low speed.
 
 config FSL_USB2_OTG
-       bool "Freescale USB OTG Transceiver Driver"
+       tristate "Freescale USB OTG Transceiver Driver"
        depends on USB_EHCI_FSL && USB_FSL_USB2 && PM_RUNTIME
+       depends on USB
        select USB_OTG
        select USB_PHY
        help
@@ -29,6 +30,7 @@ config FSL_USB2_OTG
 config ISP1301_OMAP
        tristate "Philips ISP1301 with OMAP OTG"
        depends on I2C && ARCH_OMAP_OTG
+       depends on USB
        select USB_PHY
        help
          If you say yes here you get support for the Philips ISP1301
index 82232acf1ab61b17cfbe9d084c3ed2188d554b18..bbe4f8e6e8d7492be10cc54cfe2f37e8001f2db6 100644 (file)
@@ -876,7 +876,7 @@ static int utmi_phy_probe(struct tegra_usb_phy *tegra_phy,
 
        tegra_phy->pad_regs = devm_ioremap(&pdev->dev, res->start,
                resource_size(res));
-       if (!tegra_phy->regs) {
+       if (!tegra_phy->pad_regs) {
                dev_err(&pdev->dev, "Failed to remap UTMI Pad regs\n");
                return -ENOMEM;
        }
index 30e8a61552d4d0526d999c0b49651593f04a5530..bad57ce77ba508e0f6ff8c07fa516e9477606a3c 100644 (file)
@@ -127,7 +127,8 @@ static inline int twl6030_writeb(struct twl6030_usb *twl, u8 module,
 
 static inline u8 twl6030_readb(struct twl6030_usb *twl, u8 module, u8 address)
 {
-       u8 data, ret = 0;
+       u8 data;
+       int ret;
 
        ret = twl_i2c_read_u8(module, &data, address);
        if (ret >= 0)
index 496b7e39d5bee4d64ac91b7e0187cd1771fd565a..cc7a24154490b29ebb39d4b9d3e72785c4320285 100644 (file)
@@ -251,6 +251,7 @@ static void option_instat_callback(struct urb *urb);
 #define ZTE_PRODUCT_MF628                      0x0015
 #define ZTE_PRODUCT_MF626                      0x0031
 #define ZTE_PRODUCT_MC2718                     0xffe8
+#define ZTE_PRODUCT_AC2726                     0xfff1
 
 #define BENQ_VENDOR_ID                         0x04a5
 #define BENQ_PRODUCT_H10                       0x4068
@@ -1453,6 +1454,7 @@ static const struct usb_device_id option_ids[] = {
        { USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff, 0x02, 0x01) },
        { USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff, 0x02, 0x05) },
        { USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff, 0x86, 0x10) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC2726, 0xff, 0xff, 0xff) },
 
        { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) },
        { USB_DEVICE(DLINK_VENDOR_ID, DLINK_PRODUCT_DWM_652) },
index fca4c752a4ed233199d82a787c0ebfbfff32e71c..eae2c873b39ff7dbb2ecd8d7624a1e2aec14e8ca 100644 (file)
@@ -281,8 +281,7 @@ static const struct usb_device_id id_table[] = {
        { USB_DEVICE(0x19d2, 0xfffd) },
        { USB_DEVICE(0x19d2, 0xfffc) },
        { USB_DEVICE(0x19d2, 0xfffb) },
-       /* AC2726, AC8710_V3 */
-       { USB_DEVICE_AND_INTERFACE_INFO(0x19d2, 0xfff1, 0xff, 0xff, 0xff) },
+       /* AC8710_V3 */
        { USB_DEVICE(0x19d2, 0xfff6) },
        { USB_DEVICE(0x19d2, 0xfff7) },
        { USB_DEVICE(0x19d2, 0xfff8) },
index a6a2cebb25879242b8408b1537838a67d932b2b3..cafa973c43be7af984fb9d39456b1d36b8913ea8 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/watchdog.h>
 #include <linux/platform_device.h>
 #include <linux/of_address.h>
-#include <linux/miscdevice.h>
 
 #define PM_RSTC                                0x1c
 #define PM_WDOG                                0x24
index 833e813118489216a8a27901f749f0765bd03e8f..d1d07f2f69df7cf61cd838feaa89650c22908098 100644 (file)
@@ -28,7 +28,6 @@
 
 #include <linux/platform_device.h>
 #include <linux/module.h>
-#include <linux/miscdevice.h>
 #include <linux/watchdog.h>
 #include <linux/timer.h>
 #include <linux/io.h>
index 70a240297c6d22f2a7d170a731f70320512f478a..07f88f54e5c03008159a5a276056340e65058086 100644 (file)
@@ -28,7 +28,6 @@
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/watchdog.h>
-#include <linux/miscdevice.h>
 #include <linux/seq_file.h>
 #include <linux/debugfs.h>
 #include <linux/uaccess.h>
index 2de486a7eea18a058808cbb33a0ec0fa5f3a650b..3aa50cfa335fda1576950451a492a92336da41cd 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/moduleparam.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
-#include <linux/miscdevice.h>
 #include <linux/watchdog.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
index a1a3638c579c857c382ec9c253e5f69424e1dbbb..20dc73844737a99cf30aa6852f6bfceb06d04984 100644 (file)
@@ -26,7 +26,6 @@
 
 #include <linux/module.h>
 #include <linux/moduleparam.h>
-#include <linux/miscdevice.h>
 #include <linux/uaccess.h>
 #include <linux/watchdog.h>
 #include <linux/platform_device.h>
index 6d4f3998e1f6c08e7158fdf1068b3a94c3bad448..bdb3f4a5b27c760b5c7509f957213037e234e2be 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/moduleparam.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
-#include <linux/miscdevice.h>
 #include <linux/watchdog.h>
 #include <linux/init.h>
 #include <linux/bitops.h>
index 44edca66d564195a8e20b54f20c8b4cc389eca2c..f7722a42467632030b4d36dc608e1af7cf497002 100644 (file)
@@ -16,7 +16,6 @@
 #include <linux/moduleparam.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
-#include <linux/miscdevice.h>
 #include <linux/platform_device.h>
 #include <linux/watchdog.h>
 #include <linux/init.h>
index 1bdcc313e1d9f713dc24c8b4cf7e2f7e9c312574..5bec20f5dc2db29ec5294bbdf03ee7b8106cb21a 100644 (file)
@@ -23,7 +23,6 @@
 #include <linux/moduleparam.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
-#include <linux/miscdevice.h>
 #include <linux/watchdog.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
index 53d37fea183e1b5be5f2f18093a1c4021e632bc9..d92c2d5859ce9f67c4af0f2c61fcbe6c8c396e74 100644 (file)
@@ -16,7 +16,6 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/watchdog.h>
-#include <linux/miscdevice.h>
 #include <linux/moduleparam.h>
 #include <linux/platform_device.h>
 
index 3b9fff9dcf654ba6abfb09f970a7d288147d7083..131193a7acdfd0bb07660095e0ff57c500eed6cb 100644 (file)
@@ -409,8 +409,9 @@ static int __init sc1200wdt_init(void)
 #if defined CONFIG_PNP
        /* now that the user has specified an IO port and we haven't detected
         * any devices, disable pnp support */
+       if (isapnp)
+               pnp_unregister_driver(&scl200wdt_pnp_driver);
        isapnp = 0;
-       pnp_unregister_driver(&scl200wdt_pnp_driver);
 #endif
 
        if (!request_region(io, io_len, SC1200_MODULE_NAME)) {
index f9b8e06f355808e763ca7a1f7f2e4511fe33c88f..af3528f84d65469196d2a409dbcfc531a09e57c6 100644 (file)
@@ -26,7 +26,6 @@
 #include <linux/init.h>
 #include <linux/types.h>
 #include <linux/spinlock.h>
-#include <linux/miscdevice.h>
 #include <linux/watchdog.h>
 #include <linux/pm_runtime.h>
 #include <linux/fs.h>
index ef2638fee4a8f7037c1f7c342ec1be1347ee3957..c04a1aa158e25762fcbe2b161052beaf56897d7f 100644 (file)
@@ -42,7 +42,6 @@
 #include <linux/moduleparam.h>
 #include <linux/types.h>
 #include <linux/timer.h>
-#include <linux/miscdevice.h>
 #include <linux/watchdog.h>
 #include <linux/notifier.h>
 #include <linux/reboot.h>
index d667f6b51d35f93aba02547f82653f3dbb189aa4..bb64ae3f47da58079ac816bde0d5c9abac5f0bff 100644 (file)
@@ -12,7 +12,6 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/miscdevice.h>
 #include <linux/watchdog.h>
 #include <linux/platform_device.h>
 #include <linux/stmp3xxx_rtc_wdt.h>
index 0fd0e8ae62a833b462b29bd09f8f5e7666e437bf..6a447e321dd0c3cf076169d7eac3c7b887a4b96b 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/types.h>
-#include <linux/miscdevice.h>
 #include <linux/watchdog.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
index e029b5768f2c1379279f034dc24c892b52fc0ec3..5aed9d7ad47e6ee81e96b4f16b15aa653a6a9482 100644 (file)
@@ -12,7 +12,6 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/moduleparam.h>
-#include <linux/miscdevice.h>
 #include <linux/err.h>
 #include <linux/uaccess.h>
 #include <linux/watchdog.h>
index 45d98d01028f7cdac43461a7acd42f5e17599f32..9c01509dd8abfb0fddc5480b7f4cb3b73002aad4 100644 (file)
@@ -767,20 +767,19 @@ int btrfs_lookup_extent_info(struct btrfs_trans_handle *trans,
        if (!path)
                return -ENOMEM;
 
-       if (metadata) {
-               key.objectid = bytenr;
-               key.type = BTRFS_METADATA_ITEM_KEY;
-               key.offset = offset;
-       } else {
-               key.objectid = bytenr;
-               key.type = BTRFS_EXTENT_ITEM_KEY;
-               key.offset = offset;
-       }
-
        if (!trans) {
                path->skip_locking = 1;
                path->search_commit_root = 1;
        }
+
+search_again:
+       key.objectid = bytenr;
+       key.offset = offset;
+       if (metadata)
+               key.type = BTRFS_METADATA_ITEM_KEY;
+       else
+               key.type = BTRFS_EXTENT_ITEM_KEY;
+
 again:
        ret = btrfs_search_slot(trans, root->fs_info->extent_root,
                                &key, path, 0, 0);
@@ -788,7 +787,6 @@ again:
                goto out_free;
 
        if (ret > 0 && metadata && key.type == BTRFS_METADATA_ITEM_KEY) {
-               metadata = 0;
                if (path->slots[0]) {
                        path->slots[0]--;
                        btrfs_item_key_to_cpu(path->nodes[0], &key,
@@ -855,7 +853,7 @@ again:
                        mutex_lock(&head->mutex);
                        mutex_unlock(&head->mutex);
                        btrfs_put_delayed_ref(&head->node);
-                       goto again;
+                       goto search_again;
                }
                if (head->extent_op && head->extent_op->update_flags)
                        extent_flags |= head->extent_op->flags_to_set;
index a111622598b0b23f82c84352e6b782361e079526..21da5762b0b1b33d193f3bd7f664995a43062bd6 100644 (file)
@@ -2121,7 +2121,7 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file,
 
        err = mutex_lock_killable_nested(&dir->i_mutex, I_MUTEX_PARENT);
        if (err == -EINTR)
-               goto out;
+               goto out_drop_write;
        dentry = lookup_one_len(vol_args->name, parent, namelen);
        if (IS_ERR(dentry)) {
                err = PTR_ERR(dentry);
@@ -2284,6 +2284,7 @@ out_dput:
        dput(dentry);
 out_unlock_dir:
        mutex_unlock(&dir->i_mutex);
+out_drop_write:
        mnt_drop_write_file(file);
 out:
        kfree(vol_args);
index ce459a7cb16dae48e233587cb28d271c4403f297..429c73c374b84f9bcd468067221bf99e0b9f67db 100644 (file)
@@ -571,7 +571,9 @@ static int is_cowonly_root(u64 root_objectid)
            root_objectid == BTRFS_CHUNK_TREE_OBJECTID ||
            root_objectid == BTRFS_DEV_TREE_OBJECTID ||
            root_objectid == BTRFS_TREE_LOG_OBJECTID ||
-           root_objectid == BTRFS_CSUM_TREE_OBJECTID)
+           root_objectid == BTRFS_CSUM_TREE_OBJECTID ||
+           root_objectid == BTRFS_UUID_TREE_OBJECTID ||
+           root_objectid == BTRFS_QUOTA_TREE_OBJECTID)
                return 1;
        return 0;
 }
@@ -1264,10 +1266,10 @@ static int __must_check __add_reloc_root(struct btrfs_root *root)
 }
 
 /*
- * helper to update/delete the 'address of tree root -> reloc tree'
+ * helper to delete the 'address of tree root -> reloc tree'
  * mapping
  */
-static int __update_reloc_root(struct btrfs_root *root, int del)
+static void __del_reloc_root(struct btrfs_root *root)
 {
        struct rb_node *rb_node;
        struct mapping_node *node = NULL;
@@ -1275,7 +1277,7 @@ static int __update_reloc_root(struct btrfs_root *root, int del)
 
        spin_lock(&rc->reloc_root_tree.lock);
        rb_node = tree_search(&rc->reloc_root_tree.rb_root,
-                             root->commit_root->start);
+                             root->node->start);
        if (rb_node) {
                node = rb_entry(rb_node, struct mapping_node, rb_node);
                rb_erase(&node->rb_node, &rc->reloc_root_tree.rb_root);
@@ -1283,23 +1285,45 @@ static int __update_reloc_root(struct btrfs_root *root, int del)
        spin_unlock(&rc->reloc_root_tree.lock);
 
        if (!node)
-               return 0;
+               return;
        BUG_ON((struct btrfs_root *)node->data != root);
 
-       if (!del) {
-               spin_lock(&rc->reloc_root_tree.lock);
-               node->bytenr = root->node->start;
-               rb_node = tree_insert(&rc->reloc_root_tree.rb_root,
-                                     node->bytenr, &node->rb_node);
-               spin_unlock(&rc->reloc_root_tree.lock);
-               if (rb_node)
-                       backref_tree_panic(rb_node, -EEXIST, node->bytenr);
-       } else {
-               spin_lock(&root->fs_info->trans_lock);
-               list_del_init(&root->root_list);
-               spin_unlock(&root->fs_info->trans_lock);
-               kfree(node);
+       spin_lock(&root->fs_info->trans_lock);
+       list_del_init(&root->root_list);
+       spin_unlock(&root->fs_info->trans_lock);
+       kfree(node);
+}
+
+/*
+ * helper to update the 'address of tree root -> reloc tree'
+ * mapping
+ */
+static int __update_reloc_root(struct btrfs_root *root, u64 new_bytenr)
+{
+       struct rb_node *rb_node;
+       struct mapping_node *node = NULL;
+       struct reloc_control *rc = root->fs_info->reloc_ctl;
+
+       spin_lock(&rc->reloc_root_tree.lock);
+       rb_node = tree_search(&rc->reloc_root_tree.rb_root,
+                             root->node->start);
+       if (rb_node) {
+               node = rb_entry(rb_node, struct mapping_node, rb_node);
+               rb_erase(&node->rb_node, &rc->reloc_root_tree.rb_root);
        }
+       spin_unlock(&rc->reloc_root_tree.lock);
+
+       if (!node)
+               return 0;
+       BUG_ON((struct btrfs_root *)node->data != root);
+
+       spin_lock(&rc->reloc_root_tree.lock);
+       node->bytenr = new_bytenr;
+       rb_node = tree_insert(&rc->reloc_root_tree.rb_root,
+                             node->bytenr, &node->rb_node);
+       spin_unlock(&rc->reloc_root_tree.lock);
+       if (rb_node)
+               backref_tree_panic(rb_node, -EEXIST, node->bytenr);
        return 0;
 }
 
@@ -1420,7 +1444,6 @@ int btrfs_update_reloc_root(struct btrfs_trans_handle *trans,
 {
        struct btrfs_root *reloc_root;
        struct btrfs_root_item *root_item;
-       int del = 0;
        int ret;
 
        if (!root->reloc_root)
@@ -1432,11 +1455,9 @@ int btrfs_update_reloc_root(struct btrfs_trans_handle *trans,
        if (root->fs_info->reloc_ctl->merge_reloc_tree &&
            btrfs_root_refs(root_item) == 0) {
                root->reloc_root = NULL;
-               del = 1;
+               __del_reloc_root(reloc_root);
        }
 
-       __update_reloc_root(reloc_root, del);
-
        if (reloc_root->commit_root != reloc_root->node) {
                btrfs_set_root_node(root_item, reloc_root->node);
                free_extent_buffer(reloc_root->commit_root);
@@ -2287,7 +2308,7 @@ void free_reloc_roots(struct list_head *list)
        while (!list_empty(list)) {
                reloc_root = list_entry(list->next, struct btrfs_root,
                                        root_list);
-               __update_reloc_root(reloc_root, 1);
+               __del_reloc_root(reloc_root);
                free_extent_buffer(reloc_root->node);
                free_extent_buffer(reloc_root->commit_root);
                kfree(reloc_root);
@@ -2332,7 +2353,7 @@ again:
 
                        ret = merge_reloc_root(rc, root);
                        if (ret) {
-                               __update_reloc_root(reloc_root, 1);
+                               __del_reloc_root(reloc_root);
                                free_extent_buffer(reloc_root->node);
                                free_extent_buffer(reloc_root->commit_root);
                                kfree(reloc_root);
@@ -2388,6 +2409,13 @@ out:
                btrfs_std_error(root->fs_info, ret);
                if (!list_empty(&reloc_roots))
                        free_reloc_roots(&reloc_roots);
+
+               /* new reloc root may be added */
+               mutex_lock(&root->fs_info->reloc_mutex);
+               list_splice_init(&rc->reloc_roots, &reloc_roots);
+               mutex_unlock(&root->fs_info->reloc_mutex);
+               if (!list_empty(&reloc_roots))
+                       free_reloc_roots(&reloc_roots);
        }
 
        BUG_ON(!RB_EMPTY_ROOT(&rc->reloc_root_tree.rb_root));
@@ -4522,6 +4550,11 @@ int btrfs_reloc_cow_block(struct btrfs_trans_handle *trans,
        BUG_ON(rc->stage == UPDATE_DATA_PTRS &&
               root->root_key.objectid == BTRFS_DATA_RELOC_TREE_OBJECTID);
 
+       if (root->root_key.objectid == BTRFS_TREE_RELOC_OBJECTID) {
+               if (buf == root->node)
+                       __update_reloc_root(root, cow->start);
+       }
+
        level = btrfs_header_level(buf);
        if (btrfs_header_generation(buf) <=
            btrfs_root_last_snapshot(&root->root_item))
index 6837fe87f3a6bb9f471f54c596e0d98fe67059a3..945d1db98f26968ec051a6ff6116f971f18e7303 100644 (file)
@@ -4723,8 +4723,8 @@ long btrfs_ioctl_send(struct file *mnt_file, void __user *arg_)
        }
 
        if (!access_ok(VERIFY_READ, arg->clone_sources,
-                       sizeof(*arg->clone_sources *
-                       arg->clone_sources_count))) {
+                       sizeof(*arg->clone_sources) *
+                       arg->clone_sources_count)) {
                ret = -EFAULT;
                goto out;
        }
index 2d8ac1bf0cf9b9d613215000758cbfa312b4962e..d71a11d13dfaa8b3065222c87ce964d8ba28e5b5 100644 (file)
@@ -432,7 +432,6 @@ int btrfs_parse_options(struct btrfs_root *root, char *options)
                        } else {
                                printk(KERN_INFO "btrfs: setting nodatacow\n");
                        }
-                       info->compress_type = BTRFS_COMPRESS_NONE;
                        btrfs_clear_opt(info->mount_opt, COMPRESS);
                        btrfs_clear_opt(info->mount_opt, FORCE_COMPRESS);
                        btrfs_set_opt(info->mount_opt, NODATACOW);
@@ -461,7 +460,6 @@ int btrfs_parse_options(struct btrfs_root *root, char *options)
                                btrfs_set_fs_incompat(info, COMPRESS_LZO);
                        } else if (strncmp(args[0].from, "no", 2) == 0) {
                                compress_type = "no";
-                               info->compress_type = BTRFS_COMPRESS_NONE;
                                btrfs_clear_opt(info->mount_opt, COMPRESS);
                                btrfs_clear_opt(info->mount_opt, FORCE_COMPRESS);
                                compress_force = false;
@@ -474,9 +472,10 @@ int btrfs_parse_options(struct btrfs_root *root, char *options)
                                btrfs_set_opt(info->mount_opt, FORCE_COMPRESS);
                                pr_info("btrfs: force %s compression\n",
                                        compress_type);
-                       } else
+                       } else if (btrfs_test_opt(root, COMPRESS)) {
                                pr_info("btrfs: use %s compression\n",
                                        compress_type);
+                       }
                        break;
                case Opt_ssd:
                        printk(KERN_INFO "btrfs: use ssd allocation scheme\n");
index 1e561c059539542e83a118edb003ffabca08506b..ec3ba43b9faae73fba6d6352da9515a812ec9f36 100644 (file)
@@ -210,9 +210,13 @@ static int readpage_nounlock(struct file *filp, struct page *page)
        if (err < 0) {
                SetPageError(page);
                goto out;
-       } else if (err < PAGE_CACHE_SIZE) {
+       } else {
+               if (err < PAGE_CACHE_SIZE) {
                /* zero fill remainder of page */
-               zero_user_segment(page, err, PAGE_CACHE_SIZE);
+                       zero_user_segment(page, err, PAGE_CACHE_SIZE);
+               } else {
+                       flush_dcache_page(page);
+               }
        }
        SetPageUptodate(page);
 
index 9a8e396aed89a43a0c824c3b682f96ac817ebc1c..278fd28912880b5cc09989ed7dcb8e7fbbfcb3ef 100644 (file)
@@ -978,7 +978,6 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req,
        struct ceph_mds_reply_inode *ininfo;
        struct ceph_vino vino;
        struct ceph_fs_client *fsc = ceph_sb_to_client(sb);
-       int i = 0;
        int err = 0;
 
        dout("fill_trace %p is_dentry %d is_target %d\n", req,
@@ -1039,6 +1038,29 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req,
                }
        }
 
+       if (rinfo->head->is_target) {
+               vino.ino = le64_to_cpu(rinfo->targeti.in->ino);
+               vino.snap = le64_to_cpu(rinfo->targeti.in->snapid);
+
+               in = ceph_get_inode(sb, vino);
+               if (IS_ERR(in)) {
+                       err = PTR_ERR(in);
+                       goto done;
+               }
+               req->r_target_inode = in;
+
+               err = fill_inode(in, &rinfo->targeti, NULL,
+                               session, req->r_request_started,
+                               (le32_to_cpu(rinfo->head->result) == 0) ?
+                               req->r_fmode : -1,
+                               &req->r_caps_reservation);
+               if (err < 0) {
+                       pr_err("fill_inode badness %p %llx.%llx\n",
+                               in, ceph_vinop(in));
+                       goto done;
+               }
+       }
+
        /*
         * ignore null lease/binding on snapdir ENOENT, or else we
         * will have trouble splicing in the virtual snapdir later
@@ -1108,7 +1130,6 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req,
                             ceph_dentry(req->r_old_dentry)->offset);
 
                        dn = req->r_old_dentry;  /* use old_dentry */
-                       in = dn->d_inode;
                }
 
                /* null dentry? */
@@ -1130,44 +1151,28 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req,
                }
 
                /* attach proper inode */
-               ininfo = rinfo->targeti.in;
-               vino.ino = le64_to_cpu(ininfo->ino);
-               vino.snap = le64_to_cpu(ininfo->snapid);
-               in = dn->d_inode;
-               if (!in) {
-                       in = ceph_get_inode(sb, vino);
-                       if (IS_ERR(in)) {
-                               pr_err("fill_trace bad get_inode "
-                                      "%llx.%llx\n", vino.ino, vino.snap);
-                               err = PTR_ERR(in);
-                               d_drop(dn);
-                               goto done;
-                       }
+               if (!dn->d_inode) {
+                       ihold(in);
                        dn = splice_dentry(dn, in, &have_lease, true);
                        if (IS_ERR(dn)) {
                                err = PTR_ERR(dn);
                                goto done;
                        }
                        req->r_dentry = dn;  /* may have spliced */
-                       ihold(in);
-               } else if (ceph_ino(in) == vino.ino &&
-                          ceph_snap(in) == vino.snap) {
-                       ihold(in);
-               } else {
+               } else if (dn->d_inode && dn->d_inode != in) {
                        dout(" %p links to %p %llx.%llx, not %llx.%llx\n",
-                            dn, in, ceph_ino(in), ceph_snap(in),
-                            vino.ino, vino.snap);
+                            dn, dn->d_inode, ceph_vinop(dn->d_inode),
+                            ceph_vinop(in));
                        have_lease = false;
-                       in = NULL;
                }
 
                if (have_lease)
                        update_dentry_lease(dn, rinfo->dlease, session,
                                            req->r_request_started);
                dout(" final dn %p\n", dn);
-               i++;
-       } else if ((req->r_op == CEPH_MDS_OP_LOOKUPSNAP ||
-                  req->r_op == CEPH_MDS_OP_MKSNAP) && !req->r_aborted) {
+       } else if (!req->r_aborted &&
+                  (req->r_op == CEPH_MDS_OP_LOOKUPSNAP ||
+                   req->r_op == CEPH_MDS_OP_MKSNAP)) {
                struct dentry *dn = req->r_dentry;
 
                /* fill out a snapdir LOOKUPSNAP dentry */
@@ -1177,52 +1182,15 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req,
                ininfo = rinfo->targeti.in;
                vino.ino = le64_to_cpu(ininfo->ino);
                vino.snap = le64_to_cpu(ininfo->snapid);
-               in = ceph_get_inode(sb, vino);
-               if (IS_ERR(in)) {
-                       pr_err("fill_inode get_inode badness %llx.%llx\n",
-                              vino.ino, vino.snap);
-                       err = PTR_ERR(in);
-                       d_delete(dn);
-                       goto done;
-               }
                dout(" linking snapped dir %p to dn %p\n", in, dn);
+               ihold(in);
                dn = splice_dentry(dn, in, NULL, true);
                if (IS_ERR(dn)) {
                        err = PTR_ERR(dn);
                        goto done;
                }
                req->r_dentry = dn;  /* may have spliced */
-               ihold(in);
-               rinfo->head->is_dentry = 1;  /* fool notrace handlers */
-       }
-
-       if (rinfo->head->is_target) {
-               vino.ino = le64_to_cpu(rinfo->targeti.in->ino);
-               vino.snap = le64_to_cpu(rinfo->targeti.in->snapid);
-
-               if (in == NULL || ceph_ino(in) != vino.ino ||
-                   ceph_snap(in) != vino.snap) {
-                       in = ceph_get_inode(sb, vino);
-                       if (IS_ERR(in)) {
-                               err = PTR_ERR(in);
-                               goto done;
-                       }
-               }
-               req->r_target_inode = in;
-
-               err = fill_inode(in,
-                                &rinfo->targeti, NULL,
-                                session, req->r_request_started,
-                                (le32_to_cpu(rinfo->head->result) == 0) ?
-                                req->r_fmode : -1,
-                                &req->r_caps_reservation);
-               if (err < 0) {
-                       pr_err("fill_inode badness %p %llx.%llx\n",
-                              in, ceph_vinop(in));
-                       goto done;
-               }
        }
-
 done:
        dout("fill_trace done err=%d\n", err);
        return err;
@@ -1272,7 +1240,7 @@ int ceph_readdir_prepopulate(struct ceph_mds_request *req,
        struct qstr dname;
        struct dentry *dn;
        struct inode *in;
-       int err = 0, i;
+       int err = 0, ret, i;
        struct inode *snapdir = NULL;
        struct ceph_mds_request_head *rhead = req->r_request->front.iov_base;
        struct ceph_dentry_info *di;
@@ -1305,6 +1273,7 @@ int ceph_readdir_prepopulate(struct ceph_mds_request *req,
                        ceph_fill_dirfrag(parent->d_inode, rinfo->dir_dir);
        }
 
+       /* FIXME: release caps/leases if error occurs */
        for (i = 0; i < rinfo->dir_nr; i++) {
                struct ceph_vino vino;
 
@@ -1329,9 +1298,10 @@ retry_lookup:
                                err = -ENOMEM;
                                goto out;
                        }
-                       err = ceph_init_dentry(dn);
-                       if (err < 0) {
+                       ret = ceph_init_dentry(dn);
+                       if (ret < 0) {
                                dput(dn);
+                               err = ret;
                                goto out;
                        }
                } else if (dn->d_inode &&
@@ -1351,9 +1321,6 @@ retry_lookup:
                        spin_unlock(&parent->d_lock);
                }
 
-               di = dn->d_fsdata;
-               di->offset = ceph_make_fpos(frag, i + r_readdir_offset);
-
                /* inode */
                if (dn->d_inode) {
                        in = dn->d_inode;
@@ -1366,26 +1333,39 @@ retry_lookup:
                                err = PTR_ERR(in);
                                goto out;
                        }
-                       dn = splice_dentry(dn, in, NULL, false);
-                       if (IS_ERR(dn))
-                               dn = NULL;
                }
 
                if (fill_inode(in, &rinfo->dir_in[i], NULL, session,
                               req->r_request_started, -1,
                               &req->r_caps_reservation) < 0) {
                        pr_err("fill_inode badness on %p\n", in);
+                       if (!dn->d_inode)
+                               iput(in);
+                       d_drop(dn);
                        goto next_item;
                }
-               if (dn)
-                       update_dentry_lease(dn, rinfo->dir_dlease[i],
-                                           req->r_session,
-                                           req->r_request_started);
+
+               if (!dn->d_inode) {
+                       dn = splice_dentry(dn, in, NULL, false);
+                       if (IS_ERR(dn)) {
+                               err = PTR_ERR(dn);
+                               dn = NULL;
+                               goto next_item;
+                       }
+               }
+
+               di = dn->d_fsdata;
+               di->offset = ceph_make_fpos(frag, i + r_readdir_offset);
+
+               update_dentry_lease(dn, rinfo->dir_dlease[i],
+                                   req->r_session,
+                                   req->r_request_started);
 next_item:
                if (dn)
                        dput(dn);
        }
-       req->r_did_prepopulate = true;
+       if (err == 0)
+               req->r_did_prepopulate = true;
 
 out:
        if (snapdir) {
index 4bdb300b16e2e940bab8eeb07417b7f87914815f..6055d61811d30f6d037daed87ffb11924b0ac5e5 100644 (file)
@@ -192,7 +192,7 @@ static inline int dentry_string_cmp(const unsigned char *cs, const unsigned char
                if (!tcount)
                        return 0;
        }
-       mask = ~(~0ul << tcount*8);
+       mask = bytemask_from_count(tcount);
        return unlikely(!!((a ^ b) & mask));
 }
 
index c53d3a9547f9295408fa3cfe0d5abfb72023e29e..3531deebad3084104e6a9fca7116ba68890ad5af 100644 (file)
@@ -1598,11 +1598,6 @@ static inline int nested_symlink(struct path *path, struct nameidata *nd)
  *   do a "get_unaligned()" if this helps and is sufficiently
  *   fast.
  *
- * - Little-endian machines (so that we can generate the mask
- *   of low bytes efficiently). Again, we *could* do a byte
- *   swapping load on big-endian architectures if that is not
- *   expensive enough to make the optimization worthless.
- *
  * - non-CONFIG_DEBUG_PAGEALLOC configurations (so that we
  *   do not trap on the (extremely unlikely) case of a page
  *   crossing operation.
@@ -1646,7 +1641,7 @@ unsigned int full_name_hash(const unsigned char *name, unsigned int len)
                if (!len)
                        goto done;
        }
-       mask = ~(~0ul << len*8);
+       mask = bytemask_from_count(len);
        hash += mask & a;
 done:
        return fold_hash(hash);
index 9186c7ce0b141b187a8b127a6608005a05ad53d1..b6af150c96b8cdf616950c1bd0f4f8403eeae5c8 100644 (file)
@@ -131,6 +131,13 @@ nfsd_reply_cache_alloc(void)
        return rp;
 }
 
+static void
+nfsd_reply_cache_unhash(struct svc_cacherep *rp)
+{
+       hlist_del_init(&rp->c_hash);
+       list_del_init(&rp->c_lru);
+}
+
 static void
 nfsd_reply_cache_free_locked(struct svc_cacherep *rp)
 {
@@ -417,7 +424,7 @@ nfsd_cache_lookup(struct svc_rqst *rqstp)
                rp = list_first_entry(&lru_head, struct svc_cacherep, c_lru);
                if (nfsd_cache_entry_expired(rp) ||
                    num_drc_entries >= max_drc_entries) {
-                       lru_put_end(rp);
+                       nfsd_reply_cache_unhash(rp);
                        prune_cache_entries();
                        goto search_cache;
                }
index 28955d4b7218e95a6ba7666111459b0382450786..124fc43c709088a46b26c90a16e251a2fd7c4f66 100644 (file)
@@ -292,16 +292,20 @@ proc_reg_get_unmapped_area(struct file *file, unsigned long orig_addr,
 {
        struct proc_dir_entry *pde = PDE(file_inode(file));
        unsigned long rv = -EIO;
-       unsigned long (*get_area)(struct file *, unsigned long, unsigned long,
-                                 unsigned long, unsigned long) = NULL;
+
        if (use_pde(pde)) {
+               typeof(proc_reg_get_unmapped_area) *get_area;
+
+               get_area = pde->proc_fops->get_unmapped_area;
 #ifdef CONFIG_MMU
-               get_area = current->mm->get_unmapped_area;
+               if (!get_area)
+                       get_area = current->mm->get_unmapped_area;
 #endif
-               if (pde->proc_fops->get_unmapped_area)
-                       get_area = pde->proc_fops->get_unmapped_area;
+
                if (get_area)
                        rv = get_area(file, orig_addr, len, pgoff, flags);
+               else
+                       rv = orig_addr;
                unuse_pde(pde);
        }
        return rv;
index b94f93685093edb4f2d189238989d3024fffa246..35e7d08fe629dfcb79553bcdcdf39af03b5e4960 100644 (file)
@@ -609,7 +609,7 @@ static int sysfs_open_file(struct inode *inode, struct file *file)
        struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
        struct kobject *kobj = attr_sd->s_parent->s_dir.kobj;
        struct sysfs_open_file *of;
-       bool has_read, has_write, has_mmap;
+       bool has_read, has_write;
        int error = -EACCES;
 
        /* need attr_sd for attr and ops, its parent for kobj */
@@ -621,7 +621,6 @@ static int sysfs_open_file(struct inode *inode, struct file *file)
 
                has_read = battr->read || battr->mmap;
                has_write = battr->write || battr->mmap;
-               has_mmap = battr->mmap;
        } else {
                const struct sysfs_ops *ops = sysfs_file_ops(attr_sd);
 
@@ -633,7 +632,6 @@ static int sysfs_open_file(struct inode *inode, struct file *file)
 
                has_read = ops->show;
                has_write = ops->store;
-               has_mmap = false;
        }
 
        /* check perms and supported operations */
@@ -661,9 +659,9 @@ static int sysfs_open_file(struct inode *inode, struct file *file)
         * open file has a separate mutex, it's okay as long as those don't
         * happen on the same file.  At this point, we can't easily give
         * each file a separate locking class.  Let's differentiate on
-        * whether the file has mmap or not for now.
+        * whether the file is bin or not for now.
         */
-       if (has_mmap)
+       if (sysfs_is_bin(attr_sd))
                mutex_init(&of->mutex);
        else
                mutex_init(&of->mutex);
index 8367d6dc18c9df7f51cd565e11395cba24929a53..4f11ef0111395bbb7775407e9039e92cad0a932d 100644 (file)
@@ -157,7 +157,7 @@ xfs_ioc_trim(
        struct xfs_mount                *mp,
        struct fstrim_range __user      *urange)
 {
-       struct request_queue    *q = mp->m_ddev_targp->bt_bdev->bd_disk->queue;
+       struct request_queue    *q = bdev_get_queue(mp->m_ddev_targp->bt_bdev);
        unsigned int            granularity = q->limits.discard_granularity;
        struct fstrim_range     range;
        xfs_daddr_t             start, end, minlen;
@@ -180,7 +180,8 @@ xfs_ioc_trim(
         * matter as trimming blocks is an advisory interface.
         */
        if (range.start >= XFS_FSB_TO_B(mp, mp->m_sb.sb_dblocks) ||
-           range.minlen > XFS_FSB_TO_B(mp, XFS_ALLOC_AG_MAX_USABLE(mp)))
+           range.minlen > XFS_FSB_TO_B(mp, XFS_ALLOC_AG_MAX_USABLE(mp)) ||
+           range.len < mp->m_sb.sb_blocksize)
                return -XFS_ERROR(EINVAL);
 
        start = BTOBB(range.start);
index a6e54b3319bd0f5deb573623f332486590fbe165..02fb943cbf22b36b4e6da8c66b03be8839dc03d4 100644 (file)
@@ -220,6 +220,8 @@ xfs_growfs_data_private(
         */
        nfree = 0;
        for (agno = nagcount - 1; agno >= oagcount; agno--, new -= agsize) {
+               __be32  *agfl_bno;
+
                /*
                 * AG freespace header block
                 */
@@ -279,8 +281,10 @@ xfs_growfs_data_private(
                        agfl->agfl_seqno = cpu_to_be32(agno);
                        uuid_copy(&agfl->agfl_uuid, &mp->m_sb.sb_uuid);
                }
+
+               agfl_bno = XFS_BUF_TO_AGFL_BNO(mp, bp);
                for (bucket = 0; bucket < XFS_AGFL_SIZE(mp); bucket++)
-                       agfl->agfl_bno[bucket] = cpu_to_be32(NULLAGBLOCK);
+                       agfl_bno[bucket] = cpu_to_be32(NULLAGBLOCK);
 
                error = xfs_bwrite(bp);
                xfs_buf_relse(bp);
index 4d613401a5e056a08dd2f8b21b77833bfe14cbc6..33ad9a77791f7ebbf3f8762e0c9df1af637c5328 100644 (file)
@@ -442,7 +442,8 @@ xfs_attrlist_by_handle(
                return -XFS_ERROR(EPERM);
        if (copy_from_user(&al_hreq, arg, sizeof(xfs_fsop_attrlist_handlereq_t)))
                return -XFS_ERROR(EFAULT);
-       if (al_hreq.buflen > XATTR_LIST_MAX)
+       if (al_hreq.buflen < sizeof(struct attrlist) ||
+           al_hreq.buflen > XATTR_LIST_MAX)
                return -XFS_ERROR(EINVAL);
 
        /*
index e8fb1231db8124dc08b2ffbcc551d6bfa1bc21f5..a7992f8de9d3fa53a63ab2d3250f0c4933caded9 100644 (file)
@@ -356,7 +356,8 @@ xfs_compat_attrlist_by_handle(
        if (copy_from_user(&al_hreq, arg,
                           sizeof(compat_xfs_fsop_attrlist_handlereq_t)))
                return -XFS_ERROR(EFAULT);
-       if (al_hreq.buflen > XATTR_LIST_MAX)
+       if (al_hreq.buflen < sizeof(struct attrlist) ||
+           al_hreq.buflen > XATTR_LIST_MAX)
                return -XFS_ERROR(EINVAL);
 
        /*
index f330d28e4d0eaf4d8e681bb905f52ff72465bea7..b12079afbd5f2757440a054e984dcd9f9e1b1547 100644 (file)
@@ -217,7 +217,7 @@ static inline int pmd_same(pmd_t pmd_a, pmd_t pmd_b)
 #endif
 
 #ifndef pte_accessible
-# define pte_accessible(pte)           ((void)(pte),1)
+# define pte_accessible(mm, pte)       ((void)(pte), 1)
 #endif
 
 #ifndef flush_tlb_fix_spurious_fault
index 3f21f1b72e45db6db5e8ef7ec75fb790ce6184a9..d3909effd7256ee1334910f72ab57becccff93f9 100644 (file)
@@ -49,4 +49,12 @@ static inline bool has_zero(unsigned long val, unsigned long *data, const struct
        return (val + c->high_bits) & ~rhs;
 }
 
+#ifndef zero_bytemask
+#ifdef CONFIG_64BIT
+#define zero_bytemask(mask)    (~0ul << fls64(mask))
+#else
+#define zero_bytemask(mask)    (~0ul << fls(mask))
+#endif /* CONFIG_64BIT */
+#endif /* zero_bytemask */
+
 #endif /* _ASM_WORD_AT_A_TIME_H */
index 9a193b84238a30c97814fcee82148739a5a82b30..a89df3be16863302dcedde84da6f0dbc278fde8c 100644 (file)
@@ -41,10 +41,10 @@ struct assoc_array_ops {
        /* Is this the object we're looking for? */
        bool (*compare_object)(const void *object, const void *index_key);
 
-       /* How different are two objects, to a bit position in their keys? (or
-        * -1 if they're the same)
+       /* How different is an object from an index key, to a bit position in
+        * their keys? (or -1 if they're the same)
         */
-       int (*diff_objects)(const void *a, const void *b);
+       int (*diff_objects)(const void *object, const void *index_key);
 
        /* Method to free an object. */
        void (*free_object)(void *object);
index 973ce10c40b651faa5d9e06f41eb49fefa492eab..dc1bd3dcf11fd6b72f93c5d3d9b674957bb705a0 100644 (file)
@@ -28,8 +28,6 @@
 
 #endif
 
-#define uninitialized_var(x) x
-
 #ifndef __HAVE_BUILTIN_BSWAP16__
 /* icc has this, but it's called _bswap16 */
 #define __HAVE_BUILTIN_BSWAP16__
index 57e87e749a484cbf09a2f9f21fac3d3f52574df9..bf72e9ac6de01d1b1783b0b4adfd441c9c9ac58c 100644 (file)
@@ -29,8 +29,10 @@ struct vfsmount;
 /* The hash is always the low bits of hash_len */
 #ifdef __LITTLE_ENDIAN
  #define HASH_LEN_DECLARE u32 hash; u32 len;
+ #define bytemask_from_count(cnt)      (~(~0ul << (cnt)*8))
 #else
  #define HASH_LEN_DECLARE u32 len; u32 hash;
+ #define bytemask_from_count(cnt)      (~(~0ul >> (cnt)*8))
 #endif
 
 /*
index 9649ff0c63f8d0bb5253cd08b3f32499986b4cfd..bd7e987522221f42b7042cc242abc8ca31a72996 100644 (file)
@@ -142,7 +142,10 @@ static inline int dequeue_hwpoisoned_huge_page(struct page *page)
        return 0;
 }
 
-#define isolate_huge_page(p, l) false
+static inline bool isolate_huge_page(struct page *page, struct list_head *list)
+{
+       return false;
+}
 #define putback_active_hugepage(p)     do {} while (0)
 #define is_hugepage_active(x)  false
 
index 5d89d1b808a6cc896f22332c477126c3d2f2b563..c56c350324e4b4670ef8d31397a1a777b9c08578 100644 (file)
@@ -4,6 +4,7 @@
 #include <uapi/linux/ipv6.h>
 
 #define ipv6_optlen(p)  (((p)->hdrlen+1) << 3)
+#define ipv6_authlen(p) (((p)->hdrlen+2) << 2)
 /*
  * This structure contains configuration options per IPv6 link.
  */
index d4e98d13eff4bda01b08313986b63135cc80ee2b..ecb87544cc5d888be056d903a2e0b227dd24c461 100644 (file)
@@ -193,7 +193,8 @@ extern int _cond_resched(void);
                (__x < 0) ? -__x : __x;         \
        })
 
-#if defined(CONFIG_PROVE_LOCKING) || defined(CONFIG_DEBUG_ATOMIC_SLEEP)
+#if defined(CONFIG_MMU) && \
+       (defined(CONFIG_PROVE_LOCKING) || defined(CONFIG_DEBUG_ATOMIC_SLEEP))
 void might_fault(void);
 #else
 static inline void might_fault(void) { }
index d78d28a733b15afdc25a620ca5925f6619f82a2c..5fd33dc1fe3ad265d352ed48f3a8cdeec0ca646e 100644 (file)
@@ -198,6 +198,9 @@ extern u32 vmcoreinfo_note[VMCOREINFO_NOTE_SIZE/4];
 extern size_t vmcoreinfo_size;
 extern size_t vmcoreinfo_max_size;
 
+/* flag to track if kexec reboot is in progress */
+extern bool kexec_in_progress;
+
 int __init parse_crashkernel(char *cmdline, unsigned long long system_ram,
                unsigned long long *crash_size, unsigned long long *crash_base);
 int parse_crashkernel_high(char *cmdline, unsigned long long system_ram,
index 2d0c9071bcfb795a4f34cdc44b1e88abae394c5e..cab2dd27907661e9c312e03088e398cc06c89a20 100644 (file)
@@ -39,7 +39,8 @@ enum sec_device_type {
 struct sec_pmic_dev {
        struct device *dev;
        struct sec_platform_data *pdata;
-       struct regmap *regmap;
+       struct regmap *regmap_pmic;
+       struct regmap *regmap_rtc;
        struct i2c_client *i2c;
        struct i2c_client *rtc;
 
index ad05ce60c1c97a052c11713f18532836829831cc..2e5b194b9b1900b9d5304cbdb52f14aac576b85e 100644 (file)
@@ -22,6 +22,8 @@
 #define PHY_ID_KSZ8021         0x00221555
 #define PHY_ID_KSZ8031         0x00221556
 #define PHY_ID_KSZ8041         0x00221510
+/* undocumented */
+#define PHY_ID_KSZ8041RNLI     0x00221537
 #define PHY_ID_KSZ8051         0x00221550
 /* same id: ks8001 Rev. A/B, and ks8721 Rev 3. */
 #define PHY_ID_KSZ8001         0x0022161A
index f5096b58b20d3ef64618e18ca37e1083b97af252..b7717d74da7f4d28c7c0a78cd9cd41ab6572ac22 100644 (file)
@@ -90,10 +90,19 @@ static inline int migrate_huge_page_move_mapping(struct address_space *mapping,
 #endif /* CONFIG_MIGRATION */
 
 #ifdef CONFIG_NUMA_BALANCING
+extern bool pmd_trans_migrating(pmd_t pmd);
+extern void wait_migrate_huge_page(struct anon_vma *anon_vma, pmd_t *pmd);
 extern int migrate_misplaced_page(struct page *page,
                                  struct vm_area_struct *vma, int node);
 extern bool migrate_ratelimited(int node);
 #else
+static inline bool pmd_trans_migrating(pmd_t pmd)
+{
+       return false;
+}
+static inline void wait_migrate_huge_page(struct anon_vma *anon_vma, pmd_t *pmd)
+{
+}
 static inline int migrate_misplaced_page(struct page *page,
                                         struct vm_area_struct *vma, int node)
 {
index bd299418a934e21b99c303af82a7c2f427bbf915..ad0616f2fe2c38d825d899c00f4e79e696c291ac 100644 (file)
@@ -442,6 +442,14 @@ struct mm_struct {
 
        /* numa_scan_seq prevents two threads setting pte_numa */
        int numa_scan_seq;
+#endif
+#if defined(CONFIG_NUMA_BALANCING) || defined(CONFIG_COMPACTION)
+       /*
+        * An operation with batched TLB flushing is going on. Anything that
+        * can move process memory needs to flush the TLB when moving a
+        * PROT_NONE or PROT_NUMA mapped page.
+        */
+       bool tlb_flush_pending;
 #endif
        struct uprobes_state uprobes_state;
 };
@@ -459,4 +467,45 @@ static inline cpumask_t *mm_cpumask(struct mm_struct *mm)
        return mm->cpu_vm_mask_var;
 }
 
+#if defined(CONFIG_NUMA_BALANCING) || defined(CONFIG_COMPACTION)
+/*
+ * Memory barriers to keep this state in sync are graciously provided by
+ * the page table locks, outside of which no page table modifications happen.
+ * The barriers below prevent the compiler from re-ordering the instructions
+ * around the memory barriers that are already present in the code.
+ */
+static inline bool mm_tlb_flush_pending(struct mm_struct *mm)
+{
+       barrier();
+       return mm->tlb_flush_pending;
+}
+static inline void set_tlb_flush_pending(struct mm_struct *mm)
+{
+       mm->tlb_flush_pending = true;
+
+       /*
+        * Guarantee that the tlb_flush_pending store does not leak into the
+        * critical section updating the page tables
+        */
+       smp_mb__before_spinlock();
+}
+/* Clearing is done after a TLB flush, which also provides a barrier. */
+static inline void clear_tlb_flush_pending(struct mm_struct *mm)
+{
+       barrier();
+       mm->tlb_flush_pending = false;
+}
+#else
+static inline bool mm_tlb_flush_pending(struct mm_struct *mm)
+{
+       return false;
+}
+static inline void set_tlb_flush_pending(struct mm_struct *mm)
+{
+}
+static inline void clear_tlb_flush_pending(struct mm_struct *mm)
+{
+}
+#endif
+
 #endif /* _LINUX_MM_TYPES_H */
index 4bcee94cef9314c44dfaa94fb17d3c905fefee08..69be3e6079c8c9320cff6598b8ba33ff1cdfb1f8 100644 (file)
@@ -181,7 +181,7 @@ struct proto_ops {
                                      int offset, size_t size, int flags);
        ssize_t         (*splice_read)(struct socket *sock,  loff_t *ppos,
                                       struct pipe_inode_info *pipe, size_t len, unsigned int flags);
-       void            (*set_peek_off)(struct sock *sk, int val);
+       int             (*set_peek_off)(struct sock *sk, int val);
 };
 
 #define DECLARE_SOCKADDR(type, dst, src)       \
index 7f0ed423a3606f1cc13e09a00d332dc4a45f924b..d9a550bf3e8e8a770c4198bf96bb2b81e34a3b6e 100644 (file)
@@ -1255,7 +1255,7 @@ struct net_device {
        unsigned char           perm_addr[MAX_ADDR_LEN]; /* permanent hw address */
        unsigned char           addr_assign_type; /* hw address assignment type */
        unsigned char           addr_len;       /* hardware address length      */
-       unsigned char           neigh_priv_len;
+       unsigned short          neigh_priv_len;
        unsigned short          dev_id;         /* Used to differentiate devices
                                                 * that share the same link
                                                 * layer address
index 1084a15175e04ff0bc715e3e429aab7027d279f8..a13d6825e586972835ba2b3d53ac4ab504ba5369 100644 (file)
@@ -960,6 +960,7 @@ void pci_update_resource(struct pci_dev *dev, int resno);
 int __must_check pci_assign_resource(struct pci_dev *dev, int i);
 int __must_check pci_reassign_resource(struct pci_dev *dev, int i, resource_size_t add_size, resource_size_t align);
 int pci_select_bars(struct pci_dev *dev, unsigned long flags);
+bool pci_device_is_present(struct pci_dev *pdev);
 
 /* ROM control related routines */
 int pci_enable_rom(struct pci_dev *pdev);
@@ -1567,65 +1568,65 @@ enum pci_fixup_pass {
 /* Anonymous variables would be nice... */
 #define DECLARE_PCI_FIXUP_SECTION(section, name, vendor, device, class,        \
                                  class_shift, hook)                    \
-       static const struct pci_fixup __pci_fixup_##name __used         \
+       static const struct pci_fixup __PASTE(__pci_fixup_##name,__LINE__) __used       \
        __attribute__((__section__(#section), aligned((sizeof(void *)))))    \
                = { vendor, device, class, class_shift, hook };
 
 #define DECLARE_PCI_FIXUP_CLASS_EARLY(vendor, device, class,           \
                                         class_shift, hook)             \
        DECLARE_PCI_FIXUP_SECTION(.pci_fixup_early,                     \
-               vendor##device##hook, vendor, device, class, class_shift, hook)
+               hook, vendor, device, class, class_shift, hook)
 #define DECLARE_PCI_FIXUP_CLASS_HEADER(vendor, device, class,          \
                                         class_shift, hook)             \
        DECLARE_PCI_FIXUP_SECTION(.pci_fixup_header,                    \
-               vendor##device##hook, vendor, device, class, class_shift, hook)
+               hook, vendor, device, class, class_shift, hook)
 #define DECLARE_PCI_FIXUP_CLASS_FINAL(vendor, device, class,           \
                                         class_shift, hook)             \
        DECLARE_PCI_FIXUP_SECTION(.pci_fixup_final,                     \
-               vendor##device##hook, vendor, device, class, class_shift, hook)
+               hook, vendor, device, class, class_shift, hook)
 #define DECLARE_PCI_FIXUP_CLASS_ENABLE(vendor, device, class,          \
                                         class_shift, hook)             \
        DECLARE_PCI_FIXUP_SECTION(.pci_fixup_enable,                    \
-               vendor##device##hook, vendor, device, class, class_shift, hook)
+               hook, vendor, device, class, class_shift, hook)
 #define DECLARE_PCI_FIXUP_CLASS_RESUME(vendor, device, class,          \
                                         class_shift, hook)             \
        DECLARE_PCI_FIXUP_SECTION(.pci_fixup_resume,                    \
-               resume##vendor##device##hook, vendor, device, class,    \
+               resume##hook, vendor, device, class,    \
                class_shift, hook)
 #define DECLARE_PCI_FIXUP_CLASS_RESUME_EARLY(vendor, device, class,    \
                                         class_shift, hook)             \
        DECLARE_PCI_FIXUP_SECTION(.pci_fixup_resume_early,              \
-               resume_early##vendor##device##hook, vendor, device,     \
+               resume_early##hook, vendor, device,     \
                class, class_shift, hook)
 #define DECLARE_PCI_FIXUP_CLASS_SUSPEND(vendor, device, class,         \
                                         class_shift, hook)             \
        DECLARE_PCI_FIXUP_SECTION(.pci_fixup_suspend,                   \
-               suspend##vendor##device##hook, vendor, device, class,   \
+               suspend##hook, vendor, device, class,   \
                class_shift, hook)
 
 #define DECLARE_PCI_FIXUP_EARLY(vendor, device, hook)                  \
        DECLARE_PCI_FIXUP_SECTION(.pci_fixup_early,                     \
-               vendor##device##hook, vendor, device, PCI_ANY_ID, 0, hook)
+               hook, vendor, device, PCI_ANY_ID, 0, hook)
 #define DECLARE_PCI_FIXUP_HEADER(vendor, device, hook)                 \
        DECLARE_PCI_FIXUP_SECTION(.pci_fixup_header,                    \
-               vendor##device##hook, vendor, device, PCI_ANY_ID, 0, hook)
+               hook, vendor, device, PCI_ANY_ID, 0, hook)
 #define DECLARE_PCI_FIXUP_FINAL(vendor, device, hook)                  \
        DECLARE_PCI_FIXUP_SECTION(.pci_fixup_final,                     \
-               vendor##device##hook, vendor, device, PCI_ANY_ID, 0, hook)
+               hook, vendor, device, PCI_ANY_ID, 0, hook)
 #define DECLARE_PCI_FIXUP_ENABLE(vendor, device, hook)                 \
        DECLARE_PCI_FIXUP_SECTION(.pci_fixup_enable,                    \
-               vendor##device##hook, vendor, device, PCI_ANY_ID, 0, hook)
+               hook, vendor, device, PCI_ANY_ID, 0, hook)
 #define DECLARE_PCI_FIXUP_RESUME(vendor, device, hook)                 \
        DECLARE_PCI_FIXUP_SECTION(.pci_fixup_resume,                    \
-               resume##vendor##device##hook, vendor, device,           \
+               resume##hook, vendor, device,           \
                PCI_ANY_ID, 0, hook)
 #define DECLARE_PCI_FIXUP_RESUME_EARLY(vendor, device, hook)           \
        DECLARE_PCI_FIXUP_SECTION(.pci_fixup_resume_early,              \
-               resume_early##vendor##device##hook, vendor, device,     \
+               resume_early##hook, vendor, device,     \
                PCI_ANY_ID, 0, hook)
 #define DECLARE_PCI_FIXUP_SUSPEND(vendor, device, hook)                        \
        DECLARE_PCI_FIXUP_SECTION(.pci_fixup_suspend,                   \
-               suspend##vendor##device##hook, vendor, device,          \
+               suspend##hook, vendor, device,          \
                PCI_ANY_ID, 0, hook)
 
 #ifdef CONFIG_PCI_QUIRKS
index 8e00f9f6f96395b3e209192259b6af58f7078143..9e7db9e73cc13ffc04d05b02c9c5ea0d877be7e9 100644 (file)
@@ -43,6 +43,7 @@ extern int unregister_reboot_notifier(struct notifier_block *);
  * Architecture-specific implementations of sys_reboot commands.
  */
 
+extern void migrate_to_reboot_cpu(void);
 extern void machine_restart(char *cmd);
 extern void machine_halt(void);
 extern void machine_power_off(void);
index 30aa0dc60d75786287226bf3cbedffd9f1b266a3..9d55438bc4ad766bf7f02d250c61d10c61c47b6e 100644 (file)
@@ -47,6 +47,8 @@ extern int shmem_init(void);
 extern int shmem_fill_super(struct super_block *sb, void *data, int silent);
 extern struct file *shmem_file_setup(const char *name,
                                        loff_t size, unsigned long flags);
+extern struct file *shmem_kernel_file_setup(const char *name, loff_t size,
+                                           unsigned long flags);
 extern int shmem_zero_setup(struct vm_area_struct *);
 extern int shmem_lock(struct file *file, int lock, struct user_struct *user);
 extern void shmem_unlock_mapping(struct address_space *mapping);
index bec1cc7d5e3c41efbc4939ab742eeb955b64b7f0..215b5ea1cb302c43f0e8b9532fbe3ce59ff0f612 100644 (file)
@@ -2263,6 +2263,24 @@ static inline void skb_postpull_rcsum(struct sk_buff *skb,
 
 unsigned char *skb_pull_rcsum(struct sk_buff *skb, unsigned int len);
 
+/**
+ *     pskb_trim_rcsum - trim received skb and update checksum
+ *     @skb: buffer to trim
+ *     @len: new length
+ *
+ *     This is exactly the same as pskb_trim except that it ensures the
+ *     checksum of received packets are still valid after the operation.
+ */
+
+static inline int pskb_trim_rcsum(struct sk_buff *skb, unsigned int len)
+{
+       if (likely(len >= skb->len))
+               return 0;
+       if (skb->ip_summed == CHECKSUM_COMPLETE)
+               skb->ip_summed = CHECKSUM_NONE;
+       return __pskb_trim(skb, len);
+}
+
 #define skb_queue_walk(queue, skb) \
                for (skb = (queue)->next;                                       \
                     skb != (struct sk_buff *)(queue);                          \
@@ -2360,27 +2378,6 @@ __wsum __skb_checksum(const struct sk_buff *skb, int offset, int len,
 __wsum skb_checksum(const struct sk_buff *skb, int offset, int len,
                    __wsum csum);
 
-/**
- *     pskb_trim_rcsum - trim received skb and update checksum
- *     @skb: buffer to trim
- *     @len: new length
- *
- *     This is exactly the same as pskb_trim except that it ensures the
- *     checksum of received packets are still valid after the operation.
- */
-
-static inline int pskb_trim_rcsum(struct sk_buff *skb, unsigned int len)
-{
-       if (likely(len >= skb->len))
-               return 0;
-       if (skb->ip_summed == CHECKSUM_COMPLETE) {
-               __wsum adj = skb_checksum(skb, len, skb->len - len, 0);
-
-               skb->csum = csum_sub(skb->csum, adj);
-       }
-       return __pskb_trim(skb, len);
-}
-
 static inline void *skb_header_pointer(const struct sk_buff *skb, int offset,
                                       int len, void *buffer)
 {
index bd8218b15009a810af8abd5df5a4bcad31dfdb20..941055e9d125af3bfe5a6915ff551e0bb1532445 100644 (file)
@@ -83,7 +83,7 @@ struct vb2_fileio_data;
 struct vb2_mem_ops {
        void            *(*alloc)(void *alloc_ctx, unsigned long size, gfp_t gfp_flags);
        void            (*put)(void *buf_priv);
-       struct dma_buf *(*get_dmabuf)(void *buf_priv);
+       struct dma_buf *(*get_dmabuf)(void *buf_priv, unsigned long flags);
 
        void            *(*get_userptr)(void *alloc_ctx, unsigned long vaddr,
                                        unsigned long size, int write);
index eb198acaac1d5f42b53ac97838511563fe7e874b..488316e339a124fa55fdeac686a4fc6d28c0dd2c 100644 (file)
@@ -110,7 +110,8 @@ struct frag_hdr {
        __be32  identification;
 };
 
-#define        IP6_MF  0x0001
+#define        IP6_MF          0x0001
+#define        IP6_OFFSET      0xFFF8
 
 #include <net/sock.h>
 
index ea0ca5f6e629cc8eb2e05e53b1531379617b3b79..67b5d0068273e64ac94125861699e790a9d06e9d 100644 (file)
@@ -1726,12 +1726,6 @@ struct sctp_association {
        /* How many duplicated TSNs have we seen?  */
        int numduptsns;
 
-       /* Number of seconds of idle time before an association is closed.
-        * In the association context, this is really used as a boolean
-        * since the real timeout is stored in the timeouts array
-        */
-       __u32 autoclose;
-
        /* These are to support
         * "SCTP Extensions for Dynamic Reconfiguration of IP Addresses
         *  and Enforcement of Flow and Message Limits"
index e3a18ff0c38b58aec20413489bf7237c54a14a77..2ef3c3eca47aacaa28ee25aecd236897d276845a 100644 (file)
@@ -1035,7 +1035,6 @@ enum cg_proto_flags {
 };
 
 struct cg_proto {
-       void                    (*enter_memory_pressure)(struct sock *sk);
        struct res_counter      memory_allocated;       /* Current allocated memory. */
        struct percpu_counter   sockets_allocated;      /* Current number of sockets. */
        int                     memory_pressure;
@@ -1155,8 +1154,7 @@ static inline void sk_leave_memory_pressure(struct sock *sk)
                struct proto *prot = sk->sk_prot;
 
                for (; cg_proto; cg_proto = parent_cg_proto(prot, cg_proto))
-                       if (cg_proto->memory_pressure)
-                               cg_proto->memory_pressure = 0;
+                       cg_proto->memory_pressure = 0;
        }
 
 }
@@ -1171,7 +1169,7 @@ static inline void sk_enter_memory_pressure(struct sock *sk)
                struct proto *prot = sk->sk_prot;
 
                for (; cg_proto; cg_proto = parent_cg_proto(prot, cg_proto))
-                       cg_proto->enter_memory_pressure(sk);
+                       cg_proto->memory_pressure = 1;
        }
 
        sk->sk_prot->enter_memory_pressure(sk);
index af998397041768a82ee347665e7040a9a4e44b9c..5f73785f5977e5f3c1b1a443c8f4a8f194b5f2b2 100644 (file)
@@ -108,7 +108,7 @@ static inline dma_addr_t snd_sgbuf_get_addr(struct snd_dma_buffer *dmab,
 {
        struct snd_sg_buf *sgbuf = dmab->private_data;
        dma_addr_t addr = sgbuf->table[offset >> PAGE_SHIFT].addr;
-       addr &= PAGE_MASK;
+       addr &= ~((dma_addr_t)PAGE_SIZE - 1);
        return addr + offset % PAGE_SIZE;
 }
 
index bcb0912afe7a4a233a171f2d1b4bb7d518c6884e..f854ca4a1372812dda6f71c20c8a84b3bdcfc19a 100644 (file)
@@ -75,6 +75,7 @@
 #define DRM_VMW_PARAM_FIFO_CAPS        4
 #define DRM_VMW_PARAM_MAX_FB_SIZE      5
 #define DRM_VMW_PARAM_FIFO_HW_VERSION  6
+#define DRM_VMW_PARAM_MAX_SURF_MEMORY  7
 
 /**
  * struct drm_vmw_getparam_arg
index e1802d6153aec4d0c5fd81300dcde057d9bf8a59..959d454f76a185c87ce7fc223a229d37db2564f8 100644 (file)
@@ -679,6 +679,7 @@ enum perf_event_type {
         *
         *      { u64                   weight;   } && PERF_SAMPLE_WEIGHT
         *      { u64                   data_src; } && PERF_SAMPLE_DATA_SRC
+        *      { u64                   transaction; } && PERF_SAMPLE_TRANSACTION
         * };
         */
        PERF_RECORD_SAMPLE                      = 9,
index d630163b9a2e6d46f079b00357be501d3b5335fc..5759810e1c1b9768f67f8e703c625b7ce9d76e94 100644 (file)
@@ -30,7 +30,7 @@
 #include <sound/compress_params.h>
 
 
-#define SNDRV_COMPRESS_VERSION SNDRV_PROTOCOL_VERSION(0, 1, 1)
+#define SNDRV_COMPRESS_VERSION SNDRV_PROTOCOL_VERSION(0, 1, 2)
 /**
  * struct snd_compressed_buffer: compressed buffer
  * @fragment_size: size of buffer fragment in bytes
@@ -67,8 +67,8 @@ struct snd_compr_params {
 struct snd_compr_tstamp {
        __u32 byte_offset;
        __u32 copied_total;
-       snd_pcm_uframes_t pcm_frames;
-       snd_pcm_uframes_t pcm_io_frames;
+       __u32 pcm_frames;
+       __u32 pcm_io_frames;
        __u32 sampling_rate;
 };
 
index b3097bde4e9cbc999e5d09205db8014e0da27632..790d83c7d16071ffb96827fc4a372fd9b8eb4c5f 100644 (file)
@@ -5,3 +5,4 @@ config_data.h
 config_data.gz
 timeconst.h
 hz.bc
+x509_certificate_list
index bbaf7d59c1bb14f166441e6532b55585790e4b52..bc010ee272b6cfec39892e6cb04b98cc06995e1a 100644 (file)
@@ -137,9 +137,10 @@ $(obj)/timeconst.h: $(obj)/hz.bc $(src)/timeconst.bc FORCE
 ###############################################################################
 ifeq ($(CONFIG_SYSTEM_TRUSTED_KEYRING),y)
 X509_CERTIFICATES-y := $(wildcard *.x509) $(wildcard $(srctree)/*.x509)
-X509_CERTIFICATES-$(CONFIG_MODULE_SIG) += signing_key.x509
-X509_CERTIFICATES := $(sort $(foreach CERT,$(X509_CERTIFICATES-y), \
+X509_CERTIFICATES-$(CONFIG_MODULE_SIG) += $(objtree)/signing_key.x509
+X509_CERTIFICATES-raw := $(sort $(foreach CERT,$(X509_CERTIFICATES-y), \
                                $(or $(realpath $(CERT)),$(CERT))))
+X509_CERTIFICATES := $(subst $(realpath $(objtree))/,,$(X509_CERTIFICATES-raw))
 
 ifeq ($(X509_CERTIFICATES),)
 $(warning *** No X.509 certificates found ***)
@@ -164,9 +165,9 @@ $(obj)/x509_certificate_list: $(X509_CERTIFICATES) $(obj)/.x509.list
 targets += $(obj)/.x509.list
 $(obj)/.x509.list:
        @echo $(X509_CERTIFICATES) >$@
+endif
 
 clean-files := x509_certificate_list .x509.list
-endif
 
 ifeq ($(CONFIG_MODULE_SIG),y)
 ###############################################################################
index 72348dc192c11e7a85560b67bc792415d969e22f..f5744010a8d2f980f1902279de41a866ceb00a37 100644 (file)
@@ -1396,6 +1396,8 @@ event_sched_out(struct perf_event *event,
        if (event->state != PERF_EVENT_STATE_ACTIVE)
                return;
 
+       perf_pmu_disable(event->pmu);
+
        event->state = PERF_EVENT_STATE_INACTIVE;
        if (event->pending_disable) {
                event->pending_disable = 0;
@@ -1412,6 +1414,8 @@ event_sched_out(struct perf_event *event,
                ctx->nr_freq--;
        if (event->attr.exclusive || !cpuctx->active_oncpu)
                cpuctx->exclusive = 0;
+
+       perf_pmu_enable(event->pmu);
 }
 
 static void
@@ -1652,6 +1656,7 @@ event_sched_in(struct perf_event *event,
                 struct perf_event_context *ctx)
 {
        u64 tstamp = perf_event_time(event);
+       int ret = 0;
 
        if (event->state <= PERF_EVENT_STATE_OFF)
                return 0;
@@ -1674,10 +1679,13 @@ event_sched_in(struct perf_event *event,
         */
        smp_wmb();
 
+       perf_pmu_disable(event->pmu);
+
        if (event->pmu->add(event, PERF_EF_START)) {
                event->state = PERF_EVENT_STATE_INACTIVE;
                event->oncpu = -1;
-               return -EAGAIN;
+               ret = -EAGAIN;
+               goto out;
        }
 
        event->tstamp_running += tstamp - event->tstamp_stopped;
@@ -1693,7 +1701,10 @@ event_sched_in(struct perf_event *event,
        if (event->attr.exclusive)
                cpuctx->exclusive = 1;
 
-       return 0;
+out:
+       perf_pmu_enable(event->pmu);
+
+       return ret;
 }
 
 static int
@@ -2743,6 +2754,8 @@ static void perf_adjust_freq_unthr_context(struct perf_event_context *ctx,
                if (!event_filter_match(event))
                        continue;
 
+               perf_pmu_disable(event->pmu);
+
                hwc = &event->hw;
 
                if (hwc->interrupts == MAX_INTERRUPTS) {
@@ -2752,7 +2765,7 @@ static void perf_adjust_freq_unthr_context(struct perf_event_context *ctx,
                }
 
                if (!event->attr.freq || !event->attr.sample_freq)
-                       continue;
+                       goto next;
 
                /*
                 * stop the event and update event->count
@@ -2774,6 +2787,8 @@ static void perf_adjust_freq_unthr_context(struct perf_event_context *ctx,
                        perf_adjust_period(event, period, delta, false);
 
                event->pmu->start(event, delta > 0 ? PERF_EF_RELOAD : 0);
+       next:
+               perf_pmu_enable(event->pmu);
        }
 
        perf_pmu_enable(ctx->pmu);
index 728d5be9548ce61913c85e14303248363eae0a31..5721f0e3f2da4d1d4bcbc788b4016c944bbfea03 100644 (file)
@@ -537,6 +537,7 @@ static struct mm_struct *mm_init(struct mm_struct *mm, struct task_struct *p)
        spin_lock_init(&mm->page_table_lock);
        mm_init_aio(mm);
        mm_init_owner(mm, p);
+       clear_tlb_flush_pending(mm);
 
        if (likely(!mm_alloc_pgd(mm))) {
                mm->def_flags = 0;
index 80ba086f021d3022afcf3f06ecdb1d920cdc8f7c..f6ff0191ecf72aca1d42f128771af55f9c859d13 100644 (file)
@@ -251,6 +251,9 @@ get_futex_key(u32 __user *uaddr, int fshared, union futex_key *key, int rw)
                return -EINVAL;
        address -= key->both.offset;
 
+       if (unlikely(!access_ok(rw, uaddr, sizeof(u32))))
+               return -EFAULT;
+
        /*
         * PROCESS_PRIVATE futexes are fast.
         * As the mm cannot disappear under us and the 'key' only needs
@@ -259,8 +262,6 @@ get_futex_key(u32 __user *uaddr, int fshared, union futex_key *key, int rw)
         *        but access_ok() should be faster than find_vma()
         */
        if (!fshared) {
-               if (unlikely(!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))))
-                       return -EFAULT;
                key->private.mm = mm;
                key->private.address = address;
                get_futex_key_refs(key);
@@ -288,7 +289,7 @@ again:
                put_page(page);
                /* serialize against __split_huge_page_splitting() */
                local_irq_disable();
-               if (likely(__get_user_pages_fast(address, 1, 1, &page) == 1)) {
+               if (likely(__get_user_pages_fast(address, 1, !ro, &page) == 1)) {
                        page_head = compound_head(page);
                        /*
                         * page_head is valid pointer but we must pin
index 490afc03627e52e34e51d69e0a15693b7716b17a..9c970167e4025f01be6bd696499eec2504c72ef7 100644 (file)
@@ -47,6 +47,9 @@ u32 vmcoreinfo_note[VMCOREINFO_NOTE_SIZE/4];
 size_t vmcoreinfo_size;
 size_t vmcoreinfo_max_size = sizeof(vmcoreinfo_data);
 
+/* Flag to indicate we are going to kexec a new kernel */
+bool kexec_in_progress = false;
+
 /* Location of the reserved area for the crash kernel */
 struct resource crashk_res = {
        .name  = "Crash kernel",
@@ -1675,7 +1678,9 @@ int kernel_kexec(void)
        } else
 #endif
        {
+               kexec_in_progress = true;
                kernel_restart_prepare(NULL);
+               migrate_to_reboot_cpu();
                printk(KERN_EMERG "Starting new kernel\n");
                machine_shutdown();
        }
index f813b3474646c5b320a19d9a8997349bdd14d68e..662c83fc16b77ed79b9474c681848858666055e0 100644 (file)
@@ -104,7 +104,7 @@ int unregister_reboot_notifier(struct notifier_block *nb)
 }
 EXPORT_SYMBOL(unregister_reboot_notifier);
 
-static void migrate_to_reboot_cpu(void)
+void migrate_to_reboot_cpu(void)
 {
        /* The boot cpu is always logical cpu 0 */
        int cpu = reboot_cpu;
index 9030da7bcb15f62f5d4873857c81e920e61fe052..c7395d97e4cb7c33f26925569adff8f7e3007d4e 100644 (file)
@@ -1738,6 +1738,13 @@ void task_numa_work(struct callback_head *work)
                    (vma->vm_file && (vma->vm_flags & (VM_READ|VM_WRITE)) == (VM_READ)))
                        continue;
 
+               /*
+                * Skip inaccessible VMAs to avoid any confusion between
+                * PROT_NONE and NUMA hinting ptes
+                */
+               if (!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE)))
+                       continue;
+
                do {
                        start = max(start, vma->vm_start);
                        end = ALIGN(start + (pages << PAGE_SHIFT), HPAGE_SIZE);
index 4aef390671cbb9653fc5c64342f656694585f56c..3e9868d47535b44d85e8515070bf86cf5cc6fe81 100644 (file)
@@ -3,8 +3,18 @@
 
        __INITRODATA
 
+       .align 8
        .globl VMLINUX_SYMBOL(system_certificate_list)
 VMLINUX_SYMBOL(system_certificate_list):
+__cert_list_start:
        .incbin "kernel/x509_certificate_list"
-       .globl VMLINUX_SYMBOL(system_certificate_list_end)
-VMLINUX_SYMBOL(system_certificate_list_end):
+__cert_list_end:
+
+       .align 8
+       .globl VMLINUX_SYMBOL(system_certificate_list_size)
+VMLINUX_SYMBOL(system_certificate_list_size):
+#ifdef CONFIG_64BIT
+       .quad __cert_list_end - __cert_list_start
+#else
+       .long __cert_list_end - __cert_list_start
+#endif
index 564dd93430a276b0ac7db03a59cbb5648a639c93..52ebc70263f4d8e806dc436fd55e6000cf818915 100644 (file)
@@ -22,7 +22,7 @@ struct key *system_trusted_keyring;
 EXPORT_SYMBOL_GPL(system_trusted_keyring);
 
 extern __initconst const u8 system_certificate_list[];
-extern __initconst const u8 system_certificate_list_end[];
+extern __initconst const unsigned long system_certificate_list_size;
 
 /*
  * Load the compiled-in keys
@@ -60,8 +60,8 @@ static __init int load_system_certificate_list(void)
 
        pr_notice("Loading compiled-in X.509 certificates\n");
 
-       end = system_certificate_list_end;
        p = system_certificate_list;
+       end = p + system_certificate_list_size;
        while (p < end) {
                /* Each cert begins with an ASN.1 SEQUENCE tag and must be more
                 * than 256 bytes in size.
index a3a0dbfda32957616f143ae2722541a5846c0a62..c006131beb77c5151f92cacb9e11e6a3b1defe1b 100644 (file)
@@ -51,9 +51,9 @@ struct user_namespace init_user_ns = {
        .owner = GLOBAL_ROOT_UID,
        .group = GLOBAL_ROOT_GID,
        .proc_inum = PROC_USER_INIT_INO,
-#ifdef CONFIG_KEYS_KERBEROS_CACHE
-       .krb_cache_register_sem =
-       __RWSEM_INITIALIZER(init_user_ns.krb_cache_register_sem),
+#ifdef CONFIG_PERSISTENT_KEYRINGS
+       .persistent_keyring_register_sem =
+       __RWSEM_INITIALIZER(init_user_ns.persistent_keyring_register_sem),
 #endif
 };
 EXPORT_SYMBOL_GPL(init_user_ns);
index c66912be990fbda0f61e7a58fdbc52cf304566c2..b010eac595d20eece261310cc4acb629ad70b92b 100644 (file)
@@ -2851,19 +2851,6 @@ already_gone:
        return false;
 }
 
-static bool __flush_work(struct work_struct *work)
-{
-       struct wq_barrier barr;
-
-       if (start_flush_work(work, &barr)) {
-               wait_for_completion(&barr.done);
-               destroy_work_on_stack(&barr.work);
-               return true;
-       } else {
-               return false;
-       }
-}
-
 /**
  * flush_work - wait for a work to finish executing the last queueing instance
  * @work: the work to flush
@@ -2877,10 +2864,18 @@ static bool __flush_work(struct work_struct *work)
  */
 bool flush_work(struct work_struct *work)
 {
+       struct wq_barrier barr;
+
        lock_map_acquire(&work->lockdep_map);
        lock_map_release(&work->lockdep_map);
 
-       return __flush_work(work);
+       if (start_flush_work(work, &barr)) {
+               wait_for_completion(&barr.done);
+               destroy_work_on_stack(&barr.work);
+               return true;
+       } else {
+               return false;
+       }
 }
 EXPORT_SYMBOL_GPL(flush_work);
 
@@ -4832,14 +4827,7 @@ long work_on_cpu(int cpu, long (*fn)(void *), void *arg)
 
        INIT_WORK_ONSTACK(&wfc.work, work_for_cpu_fn);
        schedule_work_on(cpu, &wfc.work);
-
-       /*
-        * The work item is on-stack and can't lead to deadlock through
-        * flushing.  Use __flush_work() to avoid spurious lockdep warnings
-        * when work_on_cpu()s are nested.
-        */
-       __flush_work(&wfc.work);
-
+       flush_work(&wfc.work);
        return wfc.ret;
 }
 EXPORT_SYMBOL_GPL(work_on_cpu);
index 17edeaf1918019b43c53dffd6e620298dcb710a2..1b6a44f1ec3e3b10f3b02d19f8ab0ce59453f6d5 100644 (file)
@@ -759,8 +759,8 @@ all_leaves_cluster_together:
        pr_devel("all leaves cluster together\n");
        diff = INT_MAX;
        for (i = 0; i < ASSOC_ARRAY_FAN_OUT; i++) {
-               int x = ops->diff_objects(assoc_array_ptr_to_leaf(edit->leaf),
-                                         assoc_array_ptr_to_leaf(node->slots[i]));
+               int x = ops->diff_objects(assoc_array_ptr_to_leaf(node->slots[i]),
+                                         index_key);
                if (x < diff) {
                        BUG_ON(x < 0);
                        diff = x;
index eb69f352401de910552fb7f28959b38f4746a878..723bbe04a0b0511976d3778a4df94cb2974eb9c8 100644 (file)
@@ -543,7 +543,7 @@ config ZSWAP
 
 config MEM_SOFT_DIRTY
        bool "Track memory changes"
-       depends on CHECKPOINT_RESTORE && HAVE_ARCH_SOFT_DIRTY
+       depends on CHECKPOINT_RESTORE && HAVE_ARCH_SOFT_DIRTY && PROC_FS
        select PROC_PAGE_MONITOR
        help
          This option enables memory changes tracking by introducing a
index 805165bcd3dd0ab8f27bbff2c9105927ed803c15..f58bcd016f432dd094d6f6378aa53f9799d30811 100644 (file)
@@ -134,6 +134,10 @@ static void update_pageblock_skip(struct compact_control *cc,
                        bool migrate_scanner)
 {
        struct zone *zone = cc->zone;
+
+       if (cc->ignore_skip_hint)
+               return;
+
        if (!page)
                return;
 
index bccd5a628ea6765478d2fa45dc01390a83ee8a5b..7de1bf85f6833422e16161445b71e328fad2e1f6 100644 (file)
@@ -882,6 +882,10 @@ int copy_huge_pmd(struct mm_struct *dst_mm, struct mm_struct *src_mm,
                ret = 0;
                goto out_unlock;
        }
+
+       /* mmap_sem prevents this happening but warn if that changes */
+       WARN_ON(pmd_trans_migrating(pmd));
+
        if (unlikely(pmd_trans_splitting(pmd))) {
                /* split huge page running from under us */
                spin_unlock(src_ptl);
@@ -1243,6 +1247,10 @@ struct page *follow_trans_huge_pmd(struct vm_area_struct *vma,
        if ((flags & FOLL_DUMP) && is_huge_zero_pmd(*pmd))
                return ERR_PTR(-EFAULT);
 
+       /* Full NUMA hinting faults to serialise migration in fault paths */
+       if ((flags & FOLL_NUMA) && pmd_numa(*pmd))
+               goto out;
+
        page = pmd_page(*pmd);
        VM_BUG_ON(!PageHead(page));
        if (flags & FOLL_TOUCH) {
@@ -1295,6 +1303,17 @@ int do_huge_pmd_numa_page(struct mm_struct *mm, struct vm_area_struct *vma,
        if (unlikely(!pmd_same(pmd, *pmdp)))
                goto out_unlock;
 
+       /*
+        * If there are potential migrations, wait for completion and retry
+        * without disrupting NUMA hinting information. Do not relock and
+        * check_same as the page may no longer be mapped.
+        */
+       if (unlikely(pmd_trans_migrating(*pmdp))) {
+               spin_unlock(ptl);
+               wait_migrate_huge_page(vma->anon_vma, pmdp);
+               goto out;
+       }
+
        page = pmd_page(pmd);
        BUG_ON(is_huge_zero_page(page));
        page_nid = page_to_nid(page);
@@ -1323,23 +1342,22 @@ int do_huge_pmd_numa_page(struct mm_struct *mm, struct vm_area_struct *vma,
                /* If the page was locked, there are no parallel migrations */
                if (page_locked)
                        goto clear_pmdnuma;
+       }
 
-               /*
-                * Otherwise wait for potential migrations and retry. We do
-                * relock and check_same as the page may no longer be mapped.
-                * As the fault is being retried, do not account for it.
-                */
+       /* Migration could have started since the pmd_trans_migrating check */
+       if (!page_locked) {
                spin_unlock(ptl);
                wait_on_page_locked(page);
                page_nid = -1;
                goto out;
        }
 
-       /* Page is misplaced, serialise migrations and parallel THP splits */
+       /*
+        * Page is misplaced. Page lock serialises migrations. Acquire anon_vma
+        * to serialises splits
+        */
        get_page(page);
        spin_unlock(ptl);
-       if (!page_locked)
-               lock_page(page);
        anon_vma = page_lock_anon_vma_read(page);
 
        /* Confirm the PMD did not change while page_table_lock was released */
@@ -1351,6 +1369,13 @@ int do_huge_pmd_numa_page(struct mm_struct *mm, struct vm_area_struct *vma,
                goto out_unlock;
        }
 
+       /* Bail if we fail to protect against THP splits for any reason */
+       if (unlikely(!anon_vma)) {
+               put_page(page);
+               page_nid = -1;
+               goto clear_pmdnuma;
+       }
+
        /*
         * Migrate the THP to the requested node, returns with page unlocked
         * and pmd_numa cleared.
@@ -1481,8 +1506,18 @@ int move_huge_pmd(struct vm_area_struct *vma, struct vm_area_struct *new_vma,
                pmd = pmdp_get_and_clear(mm, old_addr, old_pmd);
                VM_BUG_ON(!pmd_none(*new_pmd));
                set_pmd_at(mm, new_addr, new_pmd, pmd_mksoft_dirty(pmd));
-               if (new_ptl != old_ptl)
+               if (new_ptl != old_ptl) {
+                       pgtable_t pgtable;
+
+                       /*
+                        * Move preallocated PTE page table if new_pmd is on
+                        * different PMD page table.
+                        */
+                       pgtable = pgtable_trans_huge_withdraw(mm, old_pmd);
+                       pgtable_trans_huge_deposit(mm, new_pmd, pgtable);
+
                        spin_unlock(new_ptl);
+               }
                spin_unlock(old_ptl);
        }
 out:
@@ -1507,6 +1542,8 @@ int change_huge_pmd(struct vm_area_struct *vma, pmd_t *pmd,
                ret = 1;
                if (!prot_numa) {
                        entry = pmdp_get_and_clear(mm, addr, pmd);
+                       if (pmd_numa(entry))
+                               entry = pmd_mknonnuma(entry);
                        entry = pmd_modify(entry, newprot);
                        ret = HPAGE_PMD_NR;
                        BUG_ON(pmd_write(entry));
@@ -1521,7 +1558,7 @@ int change_huge_pmd(struct vm_area_struct *vma, pmd_t *pmd,
                         */
                        if (!is_huge_zero_page(page) &&
                            !pmd_numa(*pmd)) {
-                               entry = pmdp_get_and_clear(mm, addr, pmd);
+                               entry = *pmd;
                                entry = pmd_mknuma(entry);
                                ret = HPAGE_PMD_NR;
                        }
index f1a0ae6e11b86b3020c90d7241ba12d47d2bbaa8..bf5e8945714944f896e2dc79b33b75a491da4794 100644 (file)
@@ -2694,7 +2694,10 @@ static int __mem_cgroup_try_charge(struct mm_struct *mm,
                goto bypass;
 
        if (unlikely(task_in_memcg_oom(current)))
-               goto bypass;
+               goto nomem;
+
+       if (gfp_mask & __GFP_NOFAIL)
+               oom = false;
 
        /*
         * We always charge the cgroup the mm_struct belongs to.
@@ -6352,6 +6355,42 @@ static void mem_cgroup_css_offline(struct cgroup_subsys_state *css)
 static void mem_cgroup_css_free(struct cgroup_subsys_state *css)
 {
        struct mem_cgroup *memcg = mem_cgroup_from_css(css);
+       /*
+        * XXX: css_offline() would be where we should reparent all
+        * memory to prepare the cgroup for destruction.  However,
+        * memcg does not do css_tryget() and res_counter charging
+        * under the same RCU lock region, which means that charging
+        * could race with offlining.  Offlining only happens to
+        * cgroups with no tasks in them but charges can show up
+        * without any tasks from the swapin path when the target
+        * memcg is looked up from the swapout record and not from the
+        * current task as it usually is.  A race like this can leak
+        * charges and put pages with stale cgroup pointers into
+        * circulation:
+        *
+        * #0                        #1
+        *                           lookup_swap_cgroup_id()
+        *                           rcu_read_lock()
+        *                           mem_cgroup_lookup()
+        *                           css_tryget()
+        *                           rcu_read_unlock()
+        * disable css_tryget()
+        * call_rcu()
+        *   offline_css()
+        *     reparent_charges()
+        *                           res_counter_charge()
+        *                           css_put()
+        *                             css_free()
+        *                           pc->mem_cgroup = dead memcg
+        *                           add page to lru
+        *
+        * The bulk of the charges are still moved in offline_css() to
+        * avoid pinning a lot of pages in case a long-term reference
+        * like a swapout record is deferring the css_free() to long
+        * after offlining.  But this makes sure we catch any charges
+        * made after offlining:
+        */
+       mem_cgroup_reparent_charges(memcg);
 
        memcg_destroy_kmem(memcg);
        __mem_cgroup_free(memcg);
index b7c171602ba1ebb8697f0c523f1a62f51c3a2fa4..db08af92c6fce92d9e0d61ca5752aa003c52c3f2 100644 (file)
@@ -1505,10 +1505,16 @@ static int soft_offline_huge_page(struct page *page, int flags)
                if (ret > 0)
                        ret = -EIO;
        } else {
-               set_page_hwpoison_huge_page(hpage);
-               dequeue_hwpoisoned_huge_page(hpage);
-               atomic_long_add(1 << compound_order(hpage),
-                               &num_poisoned_pages);
+               /* overcommit hugetlb page will be freed to buddy */
+               if (PageHuge(page)) {
+                       set_page_hwpoison_huge_page(hpage);
+                       dequeue_hwpoisoned_huge_page(hpage);
+                       atomic_long_add(1 << compound_order(hpage),
+                                       &num_poisoned_pages);
+               } else {
+                       SetPageHWPoison(page);
+                       atomic_long_inc(&num_poisoned_pages);
+               }
        }
        return ret;
 }
index eca4a3129129751208b41cfe808e9e31e5dc7b5f..0cd2c4d4e2703f88f56b957b6f442a531fbd2e1f 100644 (file)
@@ -1197,14 +1197,16 @@ static struct page *new_vma_page(struct page *page, unsigned long private, int *
                        break;
                vma = vma->vm_next;
        }
+
+       if (PageHuge(page)) {
+               if (vma)
+                       return alloc_huge_page_noerr(vma, address, 1);
+               else
+                       return NULL;
+       }
        /*
-        * queue_pages_range() confirms that @page belongs to some vma,
-        * so vma shouldn't be NULL.
+        * if !vma, alloc_page_vma() will use task or system default policy
         */
-       BUG_ON(!vma);
-
-       if (PageHuge(page))
-               return alloc_huge_page_noerr(vma, address, 1);
        return alloc_page_vma(GFP_HIGHUSER_MOVABLE, vma, address);
 }
 #else
@@ -1318,7 +1320,7 @@ static long do_mbind(unsigned long start, unsigned long len,
                if (nr_failed && (flags & MPOL_MF_STRICT))
                        err = -EIO;
        } else
-               putback_lru_pages(&pagelist);
+               putback_movable_pages(&pagelist);
 
        up_write(&mm->mmap_sem);
  mpol_out:
index bb940045fe8595842ed58f2e32f87b83d40485e1..e9b7102013354197fb2c0d48cf6fb72731c27827 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/hugetlb_cgroup.h>
 #include <linux/gfp.h>
 #include <linux/balloon_compaction.h>
+#include <linux/mmu_notifier.h>
 
 #include <asm/tlbflush.h>
 
@@ -1654,6 +1655,18 @@ int numamigrate_isolate_page(pg_data_t *pgdat, struct page *page)
        return 1;
 }
 
+bool pmd_trans_migrating(pmd_t pmd)
+{
+       struct page *page = pmd_page(pmd);
+       return PageLocked(page);
+}
+
+void wait_migrate_huge_page(struct anon_vma *anon_vma, pmd_t *pmd)
+{
+       struct page *page = pmd_page(*pmd);
+       wait_on_page_locked(page);
+}
+
 /*
  * Attempt to migrate a misplaced page to the specified destination
  * node. Caller is expected to have an elevated reference count on
@@ -1716,12 +1729,14 @@ int migrate_misplaced_transhuge_page(struct mm_struct *mm,
                                struct page *page, int node)
 {
        spinlock_t *ptl;
-       unsigned long haddr = address & HPAGE_PMD_MASK;
        pg_data_t *pgdat = NODE_DATA(node);
        int isolated = 0;
        struct page *new_page = NULL;
        struct mem_cgroup *memcg = NULL;
        int page_lru = page_is_file_cache(page);
+       unsigned long mmun_start = address & HPAGE_PMD_MASK;
+       unsigned long mmun_end = mmun_start + HPAGE_PMD_SIZE;
+       pmd_t orig_entry;
 
        /*
         * Rate-limit the amount of data that is being migrated to a node.
@@ -1744,6 +1759,9 @@ int migrate_misplaced_transhuge_page(struct mm_struct *mm,
                goto out_fail;
        }
 
+       if (mm_tlb_flush_pending(mm))
+               flush_tlb_range(vma, mmun_start, mmun_end);
+
        /* Prepare a page as a migration target */
        __set_page_locked(new_page);
        SetPageSwapBacked(new_page);
@@ -1755,9 +1773,12 @@ int migrate_misplaced_transhuge_page(struct mm_struct *mm,
        WARN_ON(PageLRU(new_page));
 
        /* Recheck the target PMD */
+       mmu_notifier_invalidate_range_start(mm, mmun_start, mmun_end);
        ptl = pmd_lock(mm, pmd);
-       if (unlikely(!pmd_same(*pmd, entry))) {
+       if (unlikely(!pmd_same(*pmd, entry) || page_count(page) != 2)) {
+fail_putback:
                spin_unlock(ptl);
+               mmu_notifier_invalidate_range_end(mm, mmun_start, mmun_end);
 
                /* Reverse changes made by migrate_page_copy() */
                if (TestClearPageActive(new_page))
@@ -1774,7 +1795,8 @@ int migrate_misplaced_transhuge_page(struct mm_struct *mm,
                putback_lru_page(page);
                mod_zone_page_state(page_zone(page),
                         NR_ISOLATED_ANON + page_lru, -HPAGE_PMD_NR);
-               goto out_fail;
+
+               goto out_unlock;
        }
 
        /*
@@ -1786,16 +1808,35 @@ int migrate_misplaced_transhuge_page(struct mm_struct *mm,
         */
        mem_cgroup_prepare_migration(page, new_page, &memcg);
 
+       orig_entry = *pmd;
        entry = mk_pmd(new_page, vma->vm_page_prot);
-       entry = pmd_mknonnuma(entry);
-       entry = maybe_pmd_mkwrite(pmd_mkdirty(entry), vma);
        entry = pmd_mkhuge(entry);
+       entry = maybe_pmd_mkwrite(pmd_mkdirty(entry), vma);
 
-       pmdp_clear_flush(vma, haddr, pmd);
-       set_pmd_at(mm, haddr, pmd, entry);
-       page_add_new_anon_rmap(new_page, vma, haddr);
+       /*
+        * Clear the old entry under pagetable lock and establish the new PTE.
+        * Any parallel GUP will either observe the old page blocking on the
+        * page lock, block on the page table lock or observe the new page.
+        * The SetPageUptodate on the new page and page_add_new_anon_rmap
+        * guarantee the copy is visible before the pagetable update.
+        */
+       flush_cache_range(vma, mmun_start, mmun_end);
+       page_add_new_anon_rmap(new_page, vma, mmun_start);
+       pmdp_clear_flush(vma, mmun_start, pmd);
+       set_pmd_at(mm, mmun_start, pmd, entry);
+       flush_tlb_range(vma, mmun_start, mmun_end);
        update_mmu_cache_pmd(vma, address, &entry);
+
+       if (page_count(page) != 2) {
+               set_pmd_at(mm, mmun_start, pmd, orig_entry);
+               flush_tlb_range(vma, mmun_start, mmun_end);
+               update_mmu_cache_pmd(vma, address, &entry);
+               page_remove_rmap(new_page);
+               goto fail_putback;
+       }
+
        page_remove_rmap(page);
+
        /*
         * Finish the charge transaction under the page table lock to
         * prevent split_huge_page() from dividing up the charge
@@ -1803,6 +1844,7 @@ int migrate_misplaced_transhuge_page(struct mm_struct *mm,
         */
        mem_cgroup_end_migration(memcg, page, new_page, true);
        spin_unlock(ptl);
+       mmu_notifier_invalidate_range_end(mm, mmun_start, mmun_end);
 
        unlock_page(new_page);
        unlock_page(page);
@@ -1820,10 +1862,15 @@ int migrate_misplaced_transhuge_page(struct mm_struct *mm,
 out_fail:
        count_vm_events(PGMIGRATE_FAIL, HPAGE_PMD_NR);
 out_dropref:
-       entry = pmd_mknonnuma(entry);
-       set_pmd_at(mm, haddr, pmd, entry);
-       update_mmu_cache_pmd(vma, address, &entry);
+       ptl = pmd_lock(mm, pmd);
+       if (pmd_same(*pmd, entry)) {
+               entry = pmd_mknonnuma(entry);
+               set_pmd_at(mm, mmun_start, pmd, entry);
+               update_mmu_cache_pmd(vma, address, &entry);
+       }
+       spin_unlock(ptl);
 
+out_unlock:
        unlock_page(page);
        put_page(page);
        return 0;
index 26667971c824b08ca3dae7188a965e1e4efe0b79..bb53a6591aea1373d6bc74d5bb3e847650af8d24 100644 (file)
@@ -52,17 +52,21 @@ static unsigned long change_pte_range(struct vm_area_struct *vma, pmd_t *pmd,
                        pte_t ptent;
                        bool updated = false;
 
-                       ptent = ptep_modify_prot_start(mm, addr, pte);
                        if (!prot_numa) {
+                               ptent = ptep_modify_prot_start(mm, addr, pte);
+                               if (pte_numa(ptent))
+                                       ptent = pte_mknonnuma(ptent);
                                ptent = pte_modify(ptent, newprot);
                                updated = true;
                        } else {
                                struct page *page;
 
+                               ptent = *pte;
                                page = vm_normal_page(vma, addr, oldpte);
                                if (page) {
                                        if (!pte_numa(oldpte)) {
                                                ptent = pte_mknuma(ptent);
+                                               set_pte_at(mm, addr, pte, ptent);
                                                updated = true;
                                        }
                                }
@@ -79,7 +83,10 @@ static unsigned long change_pte_range(struct vm_area_struct *vma, pmd_t *pmd,
 
                        if (updated)
                                pages++;
-                       ptep_modify_prot_commit(mm, addr, pte, ptent);
+
+                       /* Only !prot_numa always clears the pte */
+                       if (!prot_numa)
+                               ptep_modify_prot_commit(mm, addr, pte, ptent);
                } else if (IS_ENABLED(CONFIG_MIGRATION) && !pte_file(oldpte)) {
                        swp_entry_t entry = pte_to_swp_entry(oldpte);
 
@@ -181,6 +188,7 @@ static unsigned long change_protection_range(struct vm_area_struct *vma,
        BUG_ON(addr >= end);
        pgd = pgd_offset(mm, addr);
        flush_cache_range(vma, addr, end);
+       set_tlb_flush_pending(mm);
        do {
                next = pgd_addr_end(addr, end);
                if (pgd_none_or_clear_bad(pgd))
@@ -192,6 +200,7 @@ static unsigned long change_protection_range(struct vm_area_struct *vma,
        /* Only flush the TLB if we actually modified any entries: */
        if (pages)
                flush_tlb_range(vma, start, end);
+       clear_tlb_flush_pending(mm);
 
        return pages;
 }
index 580a5f075ed0ab6e3047351a8271b1f053e35774..f861d0257e90048096b6398dabc7a8ce9a0bed3c 100644 (file)
@@ -1920,7 +1920,8 @@ zonelist_scan:
                 * back to remote zones that do not partake in the
                 * fairness round-robin cycle of this zonelist.
                 */
-               if (alloc_flags & ALLOC_WMARK_LOW) {
+               if ((alloc_flags & ALLOC_WMARK_LOW) &&
+                   (gfp_mask & GFP_MOVABLE_MASK)) {
                        if (zone_page_state(zone, NR_ALLOC_BATCH) <= 0)
                                continue;
                        if (zone_reclaim_mode &&
index cbb38545d9d6ab8d96ebcdb001ed9e19db772f59..a8b9199259342df9cafb84be53010eb2206ebece 100644 (file)
@@ -110,9 +110,10 @@ int pmdp_clear_flush_young(struct vm_area_struct *vma,
 pte_t ptep_clear_flush(struct vm_area_struct *vma, unsigned long address,
                       pte_t *ptep)
 {
+       struct mm_struct *mm = (vma)->vm_mm;
        pte_t pte;
-       pte = ptep_get_and_clear((vma)->vm_mm, address, ptep);
-       if (pte_accessible(pte))
+       pte = ptep_get_and_clear(mm, address, ptep);
+       if (pte_accessible(mm, pte))
                flush_tlb_page(vma, address);
        return pte;
 }
@@ -191,6 +192,9 @@ pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm, pmd_t *pmdp)
 void pmdp_invalidate(struct vm_area_struct *vma, unsigned long address,
                     pmd_t *pmdp)
 {
+       pmd_t entry = *pmdp;
+       if (pmd_numa(entry))
+               entry = pmd_mknonnuma(entry);
        set_pmd_at(vma->vm_mm, address, pmdp, pmd_mknotpresent(*pmdp));
        flush_tlb_range(vma, address, address + HPAGE_PMD_SIZE);
 }
index 55c8b8dc9ffb0c349eb63ad20a8d7bbcc2e9b25d..068522d8502a58e9465a963e68c37ce4ccf635d7 100644 (file)
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -600,7 +600,11 @@ pte_t *__page_check_address(struct page *page, struct mm_struct *mm,
        spinlock_t *ptl;
 
        if (unlikely(PageHuge(page))) {
+               /* when pud is not present, pte will be NULL */
                pte = huge_pte_offset(mm, address);
+               if (!pte)
+                       return NULL;
+
                ptl = huge_pte_lockptr(page_hstate(page), mm, pte);
                goto check;
        }
index 8297623fcaedec21b37b5080d376967e673afe92..902a14842b74a6efe5a0de23f965e8a2a9dad820 100644 (file)
@@ -2918,13 +2918,8 @@ static struct dentry_operations anon_ops = {
        .d_dname = simple_dname
 };
 
-/**
- * shmem_file_setup - get an unlinked file living in tmpfs
- * @name: name for dentry (to be seen in /proc/<pid>/maps
- * @size: size to be set for the file
- * @flags: VM_NORESERVE suppresses pre-accounting of the entire object size
- */
-struct file *shmem_file_setup(const char *name, loff_t size, unsigned long flags)
+static struct file *__shmem_file_setup(const char *name, loff_t size,
+                                      unsigned long flags, unsigned int i_flags)
 {
        struct file *res;
        struct inode *inode;
@@ -2957,6 +2952,7 @@ struct file *shmem_file_setup(const char *name, loff_t size, unsigned long flags
        if (!inode)
                goto put_dentry;
 
+       inode->i_flags |= i_flags;
        d_instantiate(path.dentry, inode);
        inode->i_size = size;
        clear_nlink(inode);     /* It is unlinked */
@@ -2977,6 +2973,32 @@ put_memory:
        shmem_unacct_size(flags, size);
        return res;
 }
+
+/**
+ * shmem_kernel_file_setup - get an unlinked file living in tmpfs which must be
+ *     kernel internal.  There will be NO LSM permission checks against the
+ *     underlying inode.  So users of this interface must do LSM checks at a
+ *     higher layer.  The one user is the big_key implementation.  LSM checks
+ *     are provided at the key level rather than the inode level.
+ * @name: name for dentry (to be seen in /proc/<pid>/maps
+ * @size: size to be set for the file
+ * @flags: VM_NORESERVE suppresses pre-accounting of the entire object size
+ */
+struct file *shmem_kernel_file_setup(const char *name, loff_t size, unsigned long flags)
+{
+       return __shmem_file_setup(name, size, flags, S_PRIVATE);
+}
+
+/**
+ * shmem_file_setup - get an unlinked file living in tmpfs
+ * @name: name for dentry (to be seen in /proc/<pid>/maps
+ * @size: size to be set for the file
+ * @flags: VM_NORESERVE suppresses pre-accounting of the entire object size
+ */
+struct file *shmem_file_setup(const char *name, loff_t size, unsigned long flags)
+{
+       return __shmem_file_setup(name, size, flags, 0);
+}
 EXPORT_SYMBOL_GPL(shmem_file_setup);
 
 /**
index 229d820bdf0b06453cb43058020d54e33f210297..045d56eaeca2b777973bf1450d7b410a09d2d9f1 100644 (file)
@@ -426,6 +426,16 @@ netdev_features_t br_features_recompute(struct net_bridge *br,
 int br_handle_frame_finish(struct sk_buff *skb);
 rx_handler_result_t br_handle_frame(struct sk_buff **pskb);
 
+static inline bool br_rx_handler_check_rcu(const struct net_device *dev)
+{
+       return rcu_dereference(dev->rx_handler) == br_handle_frame;
+}
+
+static inline struct net_bridge_port *br_port_get_check_rcu(const struct net_device *dev)
+{
+       return br_rx_handler_check_rcu(dev) ? br_port_get_rcu(dev) : NULL;
+}
+
 /* br_ioctl.c */
 int br_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
 int br_ioctl_deviceless_stub(struct net *net, unsigned int cmd,
index 8660ea3be7054571defa59bcfbfc0cd0dd7ab99e..bdb459d21ad8e2d5191023c5b096de39b6a78c90 100644 (file)
@@ -153,7 +153,7 @@ void br_stp_rcv(const struct stp_proto *proto, struct sk_buff *skb,
        if (buf[0] != 0 || buf[1] != 0 || buf[2] != 0)
                goto err;
 
-       p = br_port_get_rcu(dev);
+       p = br_port_get_check_rcu(dev);
        if (!p)
                goto err;
 
index 95897183226e18882bdbe16d8e9ba3a111ffae71..e70301eb7a4a0472d1ade5bd3d318fe453bd2b8b 100644 (file)
@@ -64,7 +64,6 @@ static struct genl_family net_drop_monitor_family = {
        .hdrsize        = 0,
        .name           = "NET_DM",
        .version        = 2,
-       .maxattr        = NET_DM_CMD_MAX,
 };
 
 static DEFINE_PER_CPU(struct per_cpu_dm_data, dm_cpu_data);
index ca15f32821fb8d536586354108488050b7cc6a0e..36b1443f9ae4b38cdd7b15f645f08032acac06d0 100644 (file)
@@ -1161,6 +1161,7 @@ int neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new,
                                                 neigh->parms->reachable_time :
                                                 0)));
                neigh->nud_state = new;
+               notify = 1;
        }
 
        if (lladdr != neigh->ha) {
index 2718fed53d8cf5b81a06c82f8cdf8ed96632185a..06e72d3cdf60dbd96a3ad4829cfcc2baec0a80e8 100644 (file)
@@ -3584,6 +3584,7 @@ void skb_scrub_packet(struct sk_buff *skb, bool xnet)
        skb->tstamp.tv64 = 0;
        skb->pkt_type = PACKET_HOST;
        skb->skb_iif = 0;
+       skb->local_df = 0;
        skb_dst_drop(skb);
        skb->mark = 0;
        secpath_reset(skb);
index ab20ed9b0f31da64cb118cf645fa88f5787b5571..5393b4b719d71de2e3126664e3dcd5882c0c99d9 100644 (file)
@@ -882,7 +882,7 @@ set_rcvbuf:
 
        case SO_PEEK_OFF:
                if (sock->ops->set_peek_off)
-                       sock->ops->set_peek_off(sk, val);
+                       ret = sock->ops->set_peek_off(sk, val);
                else
                        ret = -EOPNOTSUPP;
                break;
index 4ac71ff7c2e47c4a3bcec19206845c8afd7ce9e8..2b90a786e475f78ab7084765bfeedc608632255a 100644 (file)
@@ -851,7 +851,6 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
                        flowlabel = fl6_sock_lookup(sk, fl6.flowlabel);
                        if (flowlabel == NULL)
                                return -EINVAL;
-                       usin->sin6_addr = flowlabel->dst;
                        fl6_sock_release(flowlabel);
                }
        }
index 523be38e37de82736a28bc9aa229f1911d2eaa31..f2e15738534d316ed0c50b8be2e1976fa03052c5 100644 (file)
@@ -104,7 +104,10 @@ errout:
 static bool fib4_rule_suppress(struct fib_rule *rule, struct fib_lookup_arg *arg)
 {
        struct fib_result *result = (struct fib_result *) arg->result;
-       struct net_device *dev = result->fi->fib_dev;
+       struct net_device *dev = NULL;
+
+       if (result->fi)
+               dev = result->fi->fib_dev;
 
        /* do not accept result if the route does
         * not meet the required prefix length
index f13bd91d9a56774f58dcf14de892b2bedd855cc5..a313c3fbeb469e0594b2f7bccd788d687184bc61 100644 (file)
@@ -423,6 +423,7 @@ static void synproxy_tg4_destroy(const struct xt_tgdtor_param *par)
 static struct xt_target synproxy_tg4_reg __read_mostly = {
        .name           = "SYNPROXY",
        .family         = NFPROTO_IPV4,
+       .hooks          = (1 << NF_INET_LOCAL_IN) | (1 << NF_INET_FORWARD),
        .target         = synproxy_tg4,
        .targetsize     = sizeof(struct xt_synproxy_info),
        .checkentry     = synproxy_tg4_check,
index fff5ba1a33b76321f70d1365d072f7330d524ea9..4a5e94ac314a8cfdae20d8e393724ea2d01bd588 100644 (file)
@@ -72,7 +72,7 @@ static int nft_reject_dump(struct sk_buff *skb, const struct nft_expr *expr)
 {
        const struct nft_reject *priv = nft_expr_priv(expr);
 
-       if (nla_put_be32(skb, NFTA_REJECT_TYPE, priv->type))
+       if (nla_put_be32(skb, NFTA_REJECT_TYPE, htonl(priv->type)))
                goto nla_put_failure;
 
        switch (priv->type) {
index 269a89ecd2f441857f76c23d80e4f4c1e3cc0fdd..f7e522c558ba2eb43165f85d46c2ba3a91ce42eb 100644 (file)
@@ -6,13 +6,6 @@
 #include <linux/memcontrol.h>
 #include <linux/module.h>
 
-static void memcg_tcp_enter_memory_pressure(struct sock *sk)
-{
-       if (sk->sk_cgrp->memory_pressure)
-               sk->sk_cgrp->memory_pressure = 1;
-}
-EXPORT_SYMBOL(memcg_tcp_enter_memory_pressure);
-
 int tcp_init_cgroup(struct mem_cgroup *memcg, struct cgroup_subsys *ss)
 {
        /*
index 44f6a20fa29df830c1208e825816eaa11785f1ab..f140048334ce21f38d86ac4a2fdf770df5330d78 100644 (file)
@@ -560,15 +560,11 @@ static inline struct sock *__udp4_lib_lookup_skb(struct sk_buff *skb,
                                                 __be16 sport, __be16 dport,
                                                 struct udp_table *udptable)
 {
-       struct sock *sk;
        const struct iphdr *iph = ip_hdr(skb);
 
-       if (unlikely(sk = skb_steal_sock(skb)))
-               return sk;
-       else
-               return __udp4_lib_lookup(dev_net(skb_dst(skb)->dev), iph->saddr, sport,
-                                        iph->daddr, dport, inet_iif(skb),
-                                        udptable);
+       return __udp4_lib_lookup(dev_net(skb_dst(skb)->dev), iph->saddr, sport,
+                                iph->daddr, dport, inet_iif(skb),
+                                udptable);
 }
 
 struct sock *udp4_lib_lookup(struct net *net, __be32 saddr, __be16 sport,
@@ -1603,12 +1599,16 @@ static void flush_stack(struct sock **stack, unsigned int count,
                kfree_skb(skb1);
 }
 
-static void udp_sk_rx_dst_set(struct sock *sk, const struct sk_buff *skb)
+/* For TCP sockets, sk_rx_dst is protected by socket lock
+ * For UDP, we use xchg() to guard against concurrent changes.
+ */
+static void udp_sk_rx_dst_set(struct sock *sk, struct dst_entry *dst)
 {
-       struct dst_entry *dst = skb_dst(skb);
+       struct dst_entry *old;
 
        dst_hold(dst);
-       sk->sk_rx_dst = dst;
+       old = xchg(&sk->sk_rx_dst, dst);
+       dst_release(old);
 }
 
 /*
@@ -1739,15 +1739,16 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
        if (udp4_csum_init(skb, uh, proto))
                goto csum_error;
 
-       if (skb->sk) {
+       sk = skb_steal_sock(skb);
+       if (sk) {
+               struct dst_entry *dst = skb_dst(skb);
                int ret;
-               sk = skb->sk;
 
-               if (unlikely(sk->sk_rx_dst == NULL))
-                       udp_sk_rx_dst_set(sk, skb);
+               if (unlikely(sk->sk_rx_dst != dst))
+                       udp_sk_rx_dst_set(sk, dst);
 
                ret = udp_queue_rcv_skb(sk, skb);
-
+               sock_put(sk);
                /* a return value > 0 means to resubmit the input, but
                 * it wants the return to be -protocol, or 0
                 */
@@ -1913,17 +1914,20 @@ static struct sock *__udp4_lib_demux_lookup(struct net *net,
 
 void udp_v4_early_demux(struct sk_buff *skb)
 {
-       const struct iphdr *iph = ip_hdr(skb);
-       const struct udphdr *uh = udp_hdr(skb);
+       struct net *net = dev_net(skb->dev);
+       const struct iphdr *iph;
+       const struct udphdr *uh;
        struct sock *sk;
        struct dst_entry *dst;
-       struct net *net = dev_net(skb->dev);
        int dif = skb->dev->ifindex;
 
        /* validate the packet */
        if (!pskb_may_pull(skb, skb_transport_offset(skb) + sizeof(struct udphdr)))
                return;
 
+       iph = ip_hdr(skb);
+       uh = udp_hdr(skb);
+
        if (skb->pkt_type == PACKET_BROADCAST ||
            skb->pkt_type == PACKET_MULTICAST)
                sk = __udp4_lib_mcast_demux_lookup(net, uh->dest, iph->daddr,
index 12c97d8aa6bbb31ff1519459b89b7b9fb33817f5..d5fa5b8c443ecbbcb0ed09a10db19b06730b7d8b 100644 (file)
@@ -2613,7 +2613,7 @@ static void init_loopback(struct net_device *dev)
                        if (sp_ifa->rt)
                                continue;
 
-                       sp_rt = addrconf_dst_alloc(idev, &sp_ifa->addr, 0);
+                       sp_rt = addrconf_dst_alloc(idev, &sp_ifa->addr, false);
 
                        /* Failure cases are ignored */
                        if (!IS_ERR(sp_rt)) {
index 8dfe1f4d3c1a4e5f1e90be1603a2c84311f3a95b..93b1aa34c4320304125b478bbdad73b8b691b572 100644 (file)
@@ -73,7 +73,6 @@ int ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
                        flowlabel = fl6_sock_lookup(sk, fl6.flowlabel);
                        if (flowlabel == NULL)
                                return -EINVAL;
-                       usin->sin6_addr = flowlabel->dst;
                }
        }
 
index e27591635f92c45306a33cb9513628751e93dd16..3fd0a578329e523828fc56b40b6ffe217fd850dc 100644 (file)
@@ -122,7 +122,11 @@ out:
 static bool fib6_rule_suppress(struct fib_rule *rule, struct fib_lookup_arg *arg)
 {
        struct rt6_info *rt = (struct rt6_info *) arg->result;
-       struct net_device *dev = rt->rt6i_idev->dev;
+       struct net_device *dev = NULL;
+
+       if (rt->rt6i_idev)
+               dev = rt->rt6i_idev->dev;
+
        /* do not accept result if the route does
         * not meet the required prefix length
         */
index 3512177deb4d0e7d12c6d145781802074f490615..3008651713947c76dac697d466f1301d05bba025 100644 (file)
@@ -1277,6 +1277,9 @@ skip_linkparms:
                            ri->prefix_len == 0)
                                continue;
 #endif
+                       if (ri->prefix_len == 0 &&
+                           !in6_dev->cnf.accept_ra_defrtr)
+                               continue;
                        if (ri->prefix_len > in6_dev->cnf.accept_ra_rt_info_max_plen)
                                continue;
                        rt6_route_rcv(skb->dev, (u8*)p, (p->nd_opt_len) << 3,
index f78f41aca8e90967a026a145f938746ce317cf10..a0d17270117c37793be3cb61c4d767cd57f70611 100644 (file)
@@ -446,6 +446,7 @@ static void synproxy_tg6_destroy(const struct xt_tgdtor_param *par)
 static struct xt_target synproxy_tg6_reg __read_mostly = {
        .name           = "SYNPROXY",
        .family         = NFPROTO_IPV6,
+       .hooks          = (1 << NF_INET_LOCAL_IN) | (1 << NF_INET_FORWARD),
        .target         = synproxy_tg6,
        .targetsize     = sizeof(struct xt_synproxy_info),
        .checkentry     = synproxy_tg6_check,
index 7fb4e14c467f60b4a65236b04fda13c6b5b9107d..b6bb87e55805873ec3244db9586f58b14700835d 100644 (file)
@@ -792,7 +792,6 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
                                flowlabel = fl6_sock_lookup(sk, fl6.flowlabel);
                                if (flowlabel == NULL)
                                        return -EINVAL;
-                               daddr = &flowlabel->dst;
                        }
                }
 
index 7faa9d5e15033ae45715d63a33c21150e74f8665..a0a48ac3403f3a9284786aa5b8f00dc03696e2e0 100644 (file)
@@ -84,6 +84,8 @@ static int             ip6_dst_gc(struct dst_ops *ops);
 
 static int             ip6_pkt_discard(struct sk_buff *skb);
 static int             ip6_pkt_discard_out(struct sk_buff *skb);
+static int             ip6_pkt_prohibit(struct sk_buff *skb);
+static int             ip6_pkt_prohibit_out(struct sk_buff *skb);
 static void            ip6_link_failure(struct sk_buff *skb);
 static void            ip6_rt_update_pmtu(struct dst_entry *dst, struct sock *sk,
                                           struct sk_buff *skb, u32 mtu);
@@ -234,9 +236,6 @@ static const struct rt6_info ip6_null_entry_template = {
 
 #ifdef CONFIG_IPV6_MULTIPLE_TABLES
 
-static int ip6_pkt_prohibit(struct sk_buff *skb);
-static int ip6_pkt_prohibit_out(struct sk_buff *skb);
-
 static const struct rt6_info ip6_prohibit_entry_template = {
        .dst = {
                .__refcnt       = ATOMIC_INIT(1),
@@ -1565,21 +1564,24 @@ int ip6_route_add(struct fib6_config *cfg)
                                goto out;
                        }
                }
-               rt->dst.output = ip6_pkt_discard_out;
-               rt->dst.input = ip6_pkt_discard;
                rt->rt6i_flags = RTF_REJECT|RTF_NONEXTHOP;
                switch (cfg->fc_type) {
                case RTN_BLACKHOLE:
                        rt->dst.error = -EINVAL;
+                       rt->dst.output = dst_discard;
+                       rt->dst.input = dst_discard;
                        break;
                case RTN_PROHIBIT:
                        rt->dst.error = -EACCES;
+                       rt->dst.output = ip6_pkt_prohibit_out;
+                       rt->dst.input = ip6_pkt_prohibit;
                        break;
                case RTN_THROW:
-                       rt->dst.error = -EAGAIN;
-                       break;
                default:
-                       rt->dst.error = -ENETUNREACH;
+                       rt->dst.error = (cfg->fc_type == RTN_THROW) ? -EAGAIN
+                                       : -ENETUNREACH;
+                       rt->dst.output = ip6_pkt_discard_out;
+                       rt->dst.input = ip6_pkt_discard;
                        break;
                }
                goto install_route;
@@ -2144,8 +2146,6 @@ static int ip6_pkt_discard_out(struct sk_buff *skb)
        return ip6_pkt_drop(skb, ICMPV6_NOROUTE, IPSTATS_MIB_OUTNOROUTES);
 }
 
-#ifdef CONFIG_IPV6_MULTIPLE_TABLES
-
 static int ip6_pkt_prohibit(struct sk_buff *skb)
 {
        return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_INNOROUTES);
@@ -2157,8 +2157,6 @@ static int ip6_pkt_prohibit_out(struct sk_buff *skb)
        return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_OUTNOROUTES);
 }
 
-#endif
-
 /*
  *     Allocate a dst for local (unicast / anycast) address.
  */
@@ -2168,12 +2166,10 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev,
                                    bool anycast)
 {
        struct net *net = dev_net(idev->dev);
-       struct rt6_info *rt = ip6_dst_alloc(net, net->loopback_dev, 0, NULL);
-
-       if (!rt) {
-               net_warn_ratelimited("Maximum number of routes reached, consider increasing route/max_size\n");
+       struct rt6_info *rt = ip6_dst_alloc(net, net->loopback_dev,
+                                           DST_NOCOUNT, NULL);
+       if (!rt)
                return ERR_PTR(-ENOMEM);
-       }
 
        in6_dev_hold(idev);
 
index 0740f93a114a26ac09150638576f523bcd53694c..f67033b4bb6687621b7df4f9d3b691519c65f629 100644 (file)
@@ -156,7 +156,6 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
                        flowlabel = fl6_sock_lookup(sk, fl6.flowlabel);
                        if (flowlabel == NULL)
                                return -EINVAL;
-                       usin->sin6_addr = flowlabel->dst;
                        fl6_sock_release(flowlabel);
                }
        }
index bcd5699313c38139306d06f733cb1ba130a1503c..089c741a399217b2c7dd90f7783df4aa89eb5424 100644 (file)
@@ -1140,7 +1140,6 @@ do_udp_sendmsg:
                                flowlabel = fl6_sock_lookup(sk, fl6.flowlabel);
                                if (flowlabel == NULL)
                                        return -EINVAL;
-                               daddr = &flowlabel->dst;
                        }
                }
 
index d9b437e5500795219339c85a8aab8a0301cc77b9..bb6e206ea70b84ed180eb73a302fb6349b0f3fe8 100644 (file)
@@ -528,7 +528,6 @@ static int l2tp_ip6_sendmsg(struct kiocb *iocb, struct sock *sk,
                                flowlabel = fl6_sock_lookup(sk, fl6.flowlabel);
                                if (flowlabel == NULL)
                                        return -EINVAL;
-                               daddr = &flowlabel->dst;
                        }
                }
 
index 95667b088c5b73cd0e95e8c1753ed76acec9dca0..364ce0c5962fd48c85ea23b71b2d1dd463082575 100644 (file)
@@ -1368,7 +1368,7 @@ static int sta_apply_parameters(struct ieee80211_local *local,
                        changed |=
                              ieee80211_mps_set_sta_local_pm(sta,
                                                             params->local_pm);
-               ieee80211_bss_info_change_notify(sdata, changed);
+               ieee80211_mbss_info_change_notify(sdata, changed);
 #endif
        }
 
@@ -2488,8 +2488,7 @@ static int ieee80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
        struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
        struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 
-       if (sdata->vif.type != NL80211_IFTYPE_STATION &&
-           sdata->vif.type != NL80211_IFTYPE_MESH_POINT)
+       if (sdata->vif.type != NL80211_IFTYPE_STATION)
                return -EOPNOTSUPP;
 
        if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_PS))
@@ -3120,9 +3119,17 @@ static int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
                    params->chandef.chan->band)
                        return -EINVAL;
 
+               ifmsh->chsw_init = true;
+               if (!ifmsh->pre_value)
+                       ifmsh->pre_value = 1;
+               else
+                       ifmsh->pre_value++;
+
                err = ieee80211_mesh_csa_beacon(sdata, params, true);
-               if (err < 0)
+               if (err < 0) {
+                       ifmsh->chsw_init = false;
                        return err;
+               }
                break;
 #endif
        default:
index 531be040b9ae85972d61bf7df248ae28308d811b..27a39de89679b7d3710fea18a65b6d5df6d003d0 100644 (file)
@@ -823,6 +823,10 @@ ieee80211_ibss_process_chanswitch(struct ieee80211_sub_if_data *sdata,
        if (err)
                return false;
 
+       /* channel switch is not supported, disconnect */
+       if (!(sdata->local->hw.wiphy->flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH))
+               goto disconnect;
+
        params.count = csa_ie.count;
        params.chandef = csa_ie.chandef;
 
index 29dc505be125c3c19737f8f6cee911492c52727c..4aea4e7911135133818e66a1439b111d14e6147e 100644 (file)
@@ -1228,6 +1228,7 @@ struct ieee80211_csa_ie {
        u8 mode;
        u8 count;
        u8 ttl;
+       u16 pre_value;
 };
 
 /* Parsed Information Elements */
index ff101ea1d9ae1e208deb5d6fe1d67c1677b398c2..36c3a4cbcabf66b2a0864414b3c23ea2896b7c4e 100644 (file)
@@ -1325,7 +1325,6 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata,
                sdata->vif.bss_conf.bssid = NULL;
                break;
        case NL80211_IFTYPE_AP_VLAN:
-               break;
        case NL80211_IFTYPE_P2P_DEVICE:
                sdata->vif.bss_conf.bssid = sdata->vif.addr;
                break;
index 21d5d44444d04c82fc73c9fd6dee3f58ab56e512..7d1c3ac48ed941866170afdf387def183690d612 100644 (file)
@@ -940,6 +940,8 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
                wiphy_debug(local->hw.wiphy, "Failed to initialize wep: %d\n",
                            result);
 
+       local->hw.conf.flags = IEEE80211_CONF_IDLE;
+
        ieee80211_led_init(local);
 
        rtnl_lock();
@@ -1047,6 +1049,7 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw)
 
        cancel_work_sync(&local->restart_work);
        cancel_work_sync(&local->reconfig_filter);
+       flush_work(&local->sched_scan_stopped_work);
 
        ieee80211_clear_tx_pending(local);
        rate_control_deinitialize(local);
index 896fe3bd599e9bedd5db13dbc8ed04ab76e5bd88..ba105257d03f1cffc4398f42c52e67b1e8d3eaaa 100644 (file)
@@ -943,14 +943,19 @@ ieee80211_mesh_process_chnswitch(struct ieee80211_sub_if_data *sdata,
                 params.chandef.chan->center_freq);
 
        params.block_tx = csa_ie.mode & WLAN_EID_CHAN_SWITCH_PARAM_TX_RESTRICT;
-       if (beacon)
+       if (beacon) {
                ifmsh->chsw_ttl = csa_ie.ttl - 1;
-       else
-               ifmsh->chsw_ttl = 0;
+               if (ifmsh->pre_value >= csa_ie.pre_value)
+                       return false;
+               ifmsh->pre_value = csa_ie.pre_value;
+       }
 
-       if (ifmsh->chsw_ttl > 0)
+       if (ifmsh->chsw_ttl < ifmsh->mshcfg.dot11MeshTTL) {
                if (ieee80211_mesh_csa_beacon(sdata, &params, false) < 0)
                        return false;
+       } else {
+               return false;
+       }
 
        sdata->csa_radar_required = params.radar_required;
 
@@ -1163,7 +1168,6 @@ static int mesh_fwd_csa_frame(struct ieee80211_sub_if_data *sdata,
        offset_ttl = (len < 42) ? 7 : 10;
        *(pos + offset_ttl) -= 1;
        *(pos + offset_ttl + 1) &= ~WLAN_EID_CHAN_SWITCH_PARAM_INITIATOR;
-       sdata->u.mesh.chsw_ttl = *(pos + offset_ttl);
 
        memcpy(mgmt_fwd, mgmt, len);
        eth_broadcast_addr(mgmt_fwd->da);
@@ -1182,7 +1186,7 @@ static void mesh_rx_csa_frame(struct ieee80211_sub_if_data *sdata,
        u16 pre_value;
        bool fwd_csa = true;
        size_t baselen;
-       u8 *pos, ttl;
+       u8 *pos;
 
        if (mgmt->u.action.u.measurement.action_code !=
            WLAN_ACTION_SPCT_CHL_SWITCH)
@@ -1193,8 +1197,8 @@ static void mesh_rx_csa_frame(struct ieee80211_sub_if_data *sdata,
                           u.action.u.chan_switch.variable);
        ieee802_11_parse_elems(pos, len - baselen, false, &elems);
 
-       ttl = elems.mesh_chansw_params_ie->mesh_ttl;
-       if (!--ttl)
+       ifmsh->chsw_ttl = elems.mesh_chansw_params_ie->mesh_ttl;
+       if (!--ifmsh->chsw_ttl)
                fwd_csa = false;
 
        pre_value = le16_to_cpu(elems.mesh_chansw_params_ie->mesh_pre_value);
index d7504ab61a34c7ef6a51f8adce10e58c021408d0..b3a3ce316656ce8406859a3cdc325fa262e024a5 100644 (file)
@@ -1910,6 +1910,8 @@ static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata,
        if (ifmgd->flags & IEEE80211_STA_CONNECTION_POLL)
                already = true;
 
+       ifmgd->flags |= IEEE80211_STA_CONNECTION_POLL;
+
        mutex_unlock(&sdata->local->mtx);
 
        if (already)
index 5d60779a0c1be89e987b2cd478af865ec806d4bb..4096ff6cc24fe8a5c3505411c5b232e0d800e050 100644 (file)
@@ -226,7 +226,7 @@ minstrel_ht_calc_tp(struct minstrel_ht_sta *mi, int group, int rate)
                nsecs = 1000 * mi->overhead / MINSTREL_TRUNC(mi->avg_ampdu_len);
 
        nsecs += minstrel_mcs_groups[group].duration[rate];
-       tp = 1000000 * ((mr->probability * 1000) / nsecs);
+       tp = 1000000 * ((prob * 1000) / nsecs);
 
        mr->cur_tp = MINSTREL_TRUNC(tp);
 }
@@ -277,13 +277,15 @@ minstrel_ht_update_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi)
                        if (!(mg->supported & BIT(i)))
                                continue;
 
+                       index = MCS_GROUP_RATES * group + i;
+
                        /* initialize rates selections starting indexes */
                        if (!mg_rates_valid) {
                                mg->max_tp_rate = mg->max_tp_rate2 =
                                        mg->max_prob_rate = i;
                                if (!mi_rates_valid) {
                                        mi->max_tp_rate = mi->max_tp_rate2 =
-                                               mi->max_prob_rate = i;
+                                               mi->max_prob_rate = index;
                                        mi_rates_valid = true;
                                }
                                mg_rates_valid = true;
@@ -291,7 +293,6 @@ minstrel_ht_update_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi)
 
                        mr = &mg->rates[i];
                        mr->retry_updated = false;
-                       index = MCS_GROUP_RATES * group + i;
                        minstrel_calc_rate_ewma(mr);
                        minstrel_ht_calc_tp(mi, group, i);
 
index caecef870c0e44e3562cdc0a874bcfd233fc77a1..2b0debb0422b91d89a0a7982b94726f3b9ceae11 100644 (file)
@@ -911,7 +911,8 @@ static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx,
        u16 sc;
        u8 tid, ack_policy;
 
-       if (!ieee80211_is_data_qos(hdr->frame_control))
+       if (!ieee80211_is_data_qos(hdr->frame_control) ||
+           is_multicast_ether_addr(hdr->addr1))
                goto dont_reorder;
 
        /*
index 5ad66a83ef7f4d4525de163c2c2f1fe9d6931a04..bcc4833d7542b91e1b754ed490d1dedcaee559c1 100644 (file)
@@ -1088,6 +1088,6 @@ void ieee80211_sched_scan_stopped(struct ieee80211_hw *hw)
 
        trace_api_sched_scan_stopped(local);
 
-       ieee80211_queue_work(&local->hw, &local->sched_scan_stopped_work);
+       schedule_work(&local->sched_scan_stopped_work);
 }
 EXPORT_SYMBOL(ieee80211_sched_scan_stopped);
index a40da20b32e074a3923f844edf104eca33a6134c..6ab00907008461fb14d551b2633a8dbcd4fef623 100644 (file)
@@ -78,6 +78,8 @@ int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata,
        if (elems->mesh_chansw_params_ie) {
                csa_ie->ttl = elems->mesh_chansw_params_ie->mesh_ttl;
                csa_ie->mode = elems->mesh_chansw_params_ie->mesh_flags;
+               csa_ie->pre_value = le16_to_cpu(
+                               elems->mesh_chansw_params_ie->mesh_pre_value);
        }
 
        new_freq = ieee80211_channel_to_frequency(new_chan_no, new_band);
index 592a18171f95e9ec5273b03307235dff2bd1c946..9f9b9bd3fd44798e7030fb3a44c46da962cfd7ba 100644 (file)
@@ -2278,17 +2278,15 @@ void ieee80211_dfs_radar_detected_work(struct work_struct *work)
 {
        struct ieee80211_local *local =
                container_of(work, struct ieee80211_local, radar_detected_work);
-       struct cfg80211_chan_def chandef;
+       struct cfg80211_chan_def chandef = local->hw.conf.chandef;
 
        ieee80211_dfs_cac_cancel(local);
 
        if (local->use_chanctx)
                /* currently not handled */
                WARN_ON(1);
-       else {
-               chandef = local->hw.conf.chandef;
+       else
                cfg80211_radar_event(local->hw.wiphy, &chandef, GFP_KERNEL);
-       }
 }
 
 void ieee80211_radar_detected(struct ieee80211_hw *hw)
@@ -2459,14 +2457,9 @@ int ieee80211_send_action_csa(struct ieee80211_sub_if_data *sdata,
                          WLAN_EID_CHAN_SWITCH_PARAM_TX_RESTRICT : 0x00;
                put_unaligned_le16(WLAN_REASON_MESH_CHAN, pos); /* Reason Cd */
                pos += 2;
-               if (!ifmsh->pre_value)
-                       ifmsh->pre_value = 1;
-               else
-                       ifmsh->pre_value++;
                pre_value = cpu_to_le16(ifmsh->pre_value);
                memcpy(pos, &pre_value, 2);             /* Precedence Value */
                pos += 2;
-               ifmsh->chsw_init = true;
        }
 
        ieee80211_tx_skb(sdata, skb);
index 2bc2dec20b007026e78aba74451e70039c6e5988..6226803fc490ce33c53994c344a1c034b9b0cce9 100644 (file)
@@ -59,7 +59,7 @@ hash_netnet4_data_equal(const struct hash_netnet4_elem *ip1,
                     u32 *multi)
 {
        return ip1->ipcmp == ip2->ipcmp &&
-              ip2->ccmp == ip2->ccmp;
+              ip1->ccmp == ip2->ccmp;
 }
 
 static inline int
index dcddc49c0e08363044195695138543e4277f83f0..f93b7d06f4be9525ad4ab4314a106b01e85749ba 100644 (file)
@@ -1717,6 +1717,19 @@ nf_tables_delrule_one(struct nft_ctx *ctx, struct nft_rule *rule)
        return -ENOENT;
 }
 
+static int nf_table_delrule_by_chain(struct nft_ctx *ctx)
+{
+       struct nft_rule *rule;
+       int err;
+
+       list_for_each_entry(rule, &ctx->chain->rules, list) {
+               err = nf_tables_delrule_one(ctx, rule);
+               if (err < 0)
+                       return err;
+       }
+       return 0;
+}
+
 static int nf_tables_delrule(struct sock *nlsk, struct sk_buff *skb,
                             const struct nlmsghdr *nlh,
                             const struct nlattr * const nla[])
@@ -1725,8 +1738,8 @@ static int nf_tables_delrule(struct sock *nlsk, struct sk_buff *skb,
        const struct nft_af_info *afi;
        struct net *net = sock_net(skb->sk);
        const struct nft_table *table;
-       struct nft_chain *chain;
-       struct nft_rule *rule, *tmp;
+       struct nft_chain *chain = NULL;
+       struct nft_rule *rule;
        int family = nfmsg->nfgen_family, err = 0;
        struct nft_ctx ctx;
 
@@ -1738,22 +1751,29 @@ static int nf_tables_delrule(struct sock *nlsk, struct sk_buff *skb,
        if (IS_ERR(table))
                return PTR_ERR(table);
 
-       chain = nf_tables_chain_lookup(table, nla[NFTA_RULE_CHAIN]);
-       if (IS_ERR(chain))
-               return PTR_ERR(chain);
+       if (nla[NFTA_RULE_CHAIN]) {
+               chain = nf_tables_chain_lookup(table, nla[NFTA_RULE_CHAIN]);
+               if (IS_ERR(chain))
+                       return PTR_ERR(chain);
+       }
 
        nft_ctx_init(&ctx, skb, nlh, afi, table, chain, nla);
 
-       if (nla[NFTA_RULE_HANDLE]) {
-               rule = nf_tables_rule_lookup(chain, nla[NFTA_RULE_HANDLE]);
-               if (IS_ERR(rule))
-                       return PTR_ERR(rule);
+       if (chain) {
+               if (nla[NFTA_RULE_HANDLE]) {
+                       rule = nf_tables_rule_lookup(chain,
+                                                    nla[NFTA_RULE_HANDLE]);
+                       if (IS_ERR(rule))
+                               return PTR_ERR(rule);
 
-               err = nf_tables_delrule_one(&ctx, rule);
-       } else {
-               /* Remove all rules in this chain */
-               list_for_each_entry_safe(rule, tmp, &chain->rules, list) {
                        err = nf_tables_delrule_one(&ctx, rule);
+               } else {
+                       err = nf_table_delrule_by_chain(&ctx);
+               }
+       } else {
+               list_for_each_entry(chain, &table->chains, list) {
+                       ctx.chain = chain;
+                       err = nf_table_delrule_by_chain(&ctx);
                        if (err < 0)
                                break;
                }
index 9ff035c7140324632965fbf82764d532d4d0a284..a3910fc2122bc1aa560815394b525098cb02e85c 100644 (file)
@@ -325,21 +325,24 @@ static void htable_gc(unsigned long htlong)
        add_timer(&ht->timer);
 }
 
-static void htable_destroy(struct xt_hashlimit_htable *hinfo)
+static void htable_remove_proc_entry(struct xt_hashlimit_htable *hinfo)
 {
        struct hashlimit_net *hashlimit_net = hashlimit_pernet(hinfo->net);
        struct proc_dir_entry *parent;
 
-       del_timer_sync(&hinfo->timer);
-
        if (hinfo->family == NFPROTO_IPV4)
                parent = hashlimit_net->ipt_hashlimit;
        else
                parent = hashlimit_net->ip6t_hashlimit;
 
-       if(parent != NULL)
+       if (parent != NULL)
                remove_proc_entry(hinfo->name, parent);
+}
 
+static void htable_destroy(struct xt_hashlimit_htable *hinfo)
+{
+       del_timer_sync(&hinfo->timer);
+       htable_remove_proc_entry(hinfo);
        htable_selective_cleanup(hinfo, select_all);
        kfree(hinfo->name);
        vfree(hinfo);
@@ -883,21 +886,15 @@ static int __net_init hashlimit_proc_net_init(struct net *net)
 static void __net_exit hashlimit_proc_net_exit(struct net *net)
 {
        struct xt_hashlimit_htable *hinfo;
-       struct proc_dir_entry *pde;
        struct hashlimit_net *hashlimit_net = hashlimit_pernet(net);
 
-       /* recent_net_exit() is called before recent_mt_destroy(). Make sure
-        * that the parent xt_recent proc entry is is empty before trying to
-        * remove it.
+       /* hashlimit_net_exit() is called before hashlimit_mt_destroy().
+        * Make sure that the parent ipt_hashlimit and ip6t_hashlimit proc
+        * entries is empty before trying to remove it.
         */
        mutex_lock(&hashlimit_mutex);
-       pde = hashlimit_net->ipt_hashlimit;
-       if (pde == NULL)
-               pde = hashlimit_net->ip6t_hashlimit;
-
        hlist_for_each_entry(hinfo, &hashlimit_net->htables, node)
-               remove_proc_entry(hinfo->name, pde);
-
+               htable_remove_proc_entry(hinfo);
        hashlimit_net->ipt_hashlimit = NULL;
        hashlimit_net->ip6t_hashlimit = NULL;
        mutex_unlock(&hashlimit_mutex);
index ba2548bd85bf7d42b26e25ae9a2626b729fc8be9..88cfbc189558f75b4b508b849827eea18c3be7c0 100644 (file)
@@ -237,6 +237,30 @@ struct packet_skb_cb {
 static void __fanout_unlink(struct sock *sk, struct packet_sock *po);
 static void __fanout_link(struct sock *sk, struct packet_sock *po);
 
+static struct net_device *packet_cached_dev_get(struct packet_sock *po)
+{
+       struct net_device *dev;
+
+       rcu_read_lock();
+       dev = rcu_dereference(po->cached_dev);
+       if (likely(dev))
+               dev_hold(dev);
+       rcu_read_unlock();
+
+       return dev;
+}
+
+static void packet_cached_dev_assign(struct packet_sock *po,
+                                    struct net_device *dev)
+{
+       rcu_assign_pointer(po->cached_dev, dev);
+}
+
+static void packet_cached_dev_reset(struct packet_sock *po)
+{
+       RCU_INIT_POINTER(po->cached_dev, NULL);
+}
+
 /* register_prot_hook must be invoked with the po->bind_lock held,
  * or from a context in which asynchronous accesses to the packet
  * socket is not possible (packet_create()).
@@ -246,12 +270,10 @@ static void register_prot_hook(struct sock *sk)
        struct packet_sock *po = pkt_sk(sk);
 
        if (!po->running) {
-               if (po->fanout) {
+               if (po->fanout)
                        __fanout_link(sk, po);
-               } else {
+               else
                        dev_add_pack(&po->prot_hook);
-                       rcu_assign_pointer(po->cached_dev, po->prot_hook.dev);
-               }
 
                sock_hold(sk);
                po->running = 1;
@@ -270,12 +292,11 @@ static void __unregister_prot_hook(struct sock *sk, bool sync)
        struct packet_sock *po = pkt_sk(sk);
 
        po->running = 0;
-       if (po->fanout) {
+
+       if (po->fanout)
                __fanout_unlink(sk, po);
-       } else {
+       else
                __dev_remove_pack(&po->prot_hook);
-               RCU_INIT_POINTER(po->cached_dev, NULL);
-       }
 
        __sock_put(sk);
 
@@ -2059,19 +2080,6 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb,
        return tp_len;
 }
 
-static struct net_device *packet_cached_dev_get(struct packet_sock *po)
-{
-       struct net_device *dev;
-
-       rcu_read_lock();
-       dev = rcu_dereference(po->cached_dev);
-       if (dev)
-               dev_hold(dev);
-       rcu_read_unlock();
-
-       return dev;
-}
-
 static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
 {
        struct sk_buff *skb;
@@ -2088,7 +2096,7 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
 
        mutex_lock(&po->pg_vec_lock);
 
-       if (saddr == NULL) {
+       if (likely(saddr == NULL)) {
                dev     = packet_cached_dev_get(po);
                proto   = po->num;
                addr    = NULL;
@@ -2242,7 +2250,7 @@ static int packet_snd(struct socket *sock,
         *      Get and verify the address.
         */
 
-       if (saddr == NULL) {
+       if (likely(saddr == NULL)) {
                dev     = packet_cached_dev_get(po);
                proto   = po->num;
                addr    = NULL;
@@ -2451,6 +2459,8 @@ static int packet_release(struct socket *sock)
 
        spin_lock(&po->bind_lock);
        unregister_prot_hook(sk, false);
+       packet_cached_dev_reset(po);
+
        if (po->prot_hook.dev) {
                dev_put(po->prot_hook.dev);
                po->prot_hook.dev = NULL;
@@ -2506,14 +2516,17 @@ static int packet_do_bind(struct sock *sk, struct net_device *dev, __be16 protoc
 
        spin_lock(&po->bind_lock);
        unregister_prot_hook(sk, true);
+
        po->num = protocol;
        po->prot_hook.type = protocol;
        if (po->prot_hook.dev)
                dev_put(po->prot_hook.dev);
-       po->prot_hook.dev = dev;
 
+       po->prot_hook.dev = dev;
        po->ifindex = dev ? dev->ifindex : 0;
 
+       packet_cached_dev_assign(po, dev);
+
        if (protocol == 0)
                goto out_unlock;
 
@@ -2626,7 +2639,8 @@ static int packet_create(struct net *net, struct socket *sock, int protocol,
        po = pkt_sk(sk);
        sk->sk_family = PF_PACKET;
        po->num = proto;
-       RCU_INIT_POINTER(po->cached_dev, NULL);
+
+       packet_cached_dev_reset(po);
 
        sk->sk_destruct = packet_sock_destruct;
        sk_refcnt_debug_inc(sk);
@@ -3337,6 +3351,7 @@ static int packet_notifier(struct notifier_block *this,
                                                sk->sk_error_report(sk);
                                }
                                if (msg == NETDEV_UNREGISTER) {
+                                       packet_cached_dev_reset(po);
                                        po->ifindex = -1;
                                        if (po->prot_hook.dev)
                                                dev_put(po->prot_hook.dev);
index e59094981175cd6c390b5ed83a2dec15d8e2407e..37be6e226d1b46fefe8e0cf554580b1faf19cfb8 100644 (file)
@@ -552,9 +552,8 @@ int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm,
            && rm->m_inc.i_hdr.h_flags & RDS_FLAG_CONG_BITMAP) {
                rds_cong_map_updated(conn->c_fcong, ~(u64) 0);
                scat = &rm->data.op_sg[sg];
-               ret = sizeof(struct rds_header) + RDS_CONG_MAP_BYTES;
-               ret = min_t(int, ret, scat->length - conn->c_xmit_data_off);
-               return ret;
+               ret = max_t(int, RDS_CONG_MAP_BYTES, scat->length);
+               return sizeof(struct rds_header) + ret;
        }
 
        /* FIXME we may overallocate here */
index fd7072827a40139c4ffba595aaa261282641e37f..69cb848e83455035a3e9ad85b2d7922434069d7e 100644 (file)
@@ -270,6 +270,16 @@ int tcf_register_action(struct tc_action_ops *act)
 {
        struct tc_action_ops *a, **ap;
 
+       /* Must supply act, dump, cleanup and init */
+       if (!act->act || !act->dump || !act->cleanup || !act->init)
+               return -EINVAL;
+
+       /* Supply defaults */
+       if (!act->lookup)
+               act->lookup = tcf_hash_search;
+       if (!act->walk)
+               act->walk = tcf_generic_walker;
+
        write_lock(&act_mod_lock);
        for (ap = &act_base; (a = *ap) != NULL; ap = &a->next) {
                if (act->type == a->type || (strcmp(act->kind, a->kind) == 0)) {
@@ -381,7 +391,7 @@ int tcf_action_exec(struct sk_buff *skb, const struct tc_action *act,
        }
        while ((a = act) != NULL) {
 repeat:
-               if (a->ops && a->ops->act) {
+               if (a->ops) {
                        ret = a->ops->act(skb, a, res);
                        if (TC_MUNGED & skb->tc_verd) {
                                /* copied already, allow trampling */
@@ -405,7 +415,7 @@ void tcf_action_destroy(struct tc_action *act, int bind)
        struct tc_action *a;
 
        for (a = act; a; a = act) {
-               if (a->ops && a->ops->cleanup) {
+               if (a->ops) {
                        if (a->ops->cleanup(a, bind) == ACT_P_DELETED)
                                module_put(a->ops->owner);
                        act = act->next;
@@ -424,7 +434,7 @@ tcf_action_dump_old(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
 {
        int err = -EINVAL;
 
-       if (a->ops == NULL || a->ops->dump == NULL)
+       if (a->ops == NULL)
                return err;
        return a->ops->dump(skb, a, bind, ref);
 }
@@ -436,7 +446,7 @@ tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
        unsigned char *b = skb_tail_pointer(skb);
        struct nlattr *nest;
 
-       if (a->ops == NULL || a->ops->dump == NULL)
+       if (a->ops == NULL)
                return err;
 
        if (nla_put_string(skb, TCA_KIND, a->ops->kind))
@@ -723,8 +733,6 @@ tcf_action_get_1(struct nlattr *nla, struct nlmsghdr *n, u32 portid)
        a->ops = tc_lookup_action(tb[TCA_ACT_KIND]);
        if (a->ops == NULL)
                goto err_free;
-       if (a->ops->lookup == NULL)
-               goto err_mod;
        err = -ENOENT;
        if (a->ops->lookup(a, index) == 0)
                goto err_mod;
@@ -1084,12 +1092,6 @@ tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb)
        memset(&a, 0, sizeof(struct tc_action));
        a.ops = a_o;
 
-       if (a_o->walk == NULL) {
-               WARN(1, "tc_dump_action: %s !capable of dumping table\n",
-                    a_o->kind);
-               goto out_module_put;
-       }
-
        nlh = nlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
                        cb->nlh->nlmsg_type, sizeof(*t), 0);
        if (!nlh)
index 3a4c0caa1f7de0fdfdb618bac9308aa32330c7f7..5c5edf56adbd4fc9a4d64a509a9103511f995db4 100644 (file)
@@ -585,9 +585,7 @@ static struct tc_action_ops act_csum_ops = {
        .act            = tcf_csum,
        .dump           = tcf_csum_dump,
        .cleanup        = tcf_csum_cleanup,
-       .lookup         = tcf_hash_search,
        .init           = tcf_csum_init,
-       .walk           = tcf_generic_walker
 };
 
 MODULE_DESCRIPTION("Checksum updating actions");
index fd2b3cff5fa28cf4da25690da9e7bad410c60a78..5645a4d32abdd187f59d9f6301842e35d08762df 100644 (file)
@@ -206,9 +206,7 @@ static struct tc_action_ops act_gact_ops = {
        .act            =       tcf_gact,
        .dump           =       tcf_gact_dump,
        .cleanup        =       tcf_gact_cleanup,
-       .lookup         =       tcf_hash_search,
        .init           =       tcf_gact_init,
-       .walk           =       tcf_generic_walker
 };
 
 MODULE_AUTHOR("Jamal Hadi Salim(2002-4)");
index 60d88b6b9560bc0a7836fa0cba845ddd6a57cb3c..882a89762f77c2edb8b6d10d0c8ef69cf3e39aac 100644 (file)
@@ -298,9 +298,7 @@ static struct tc_action_ops act_ipt_ops = {
        .act            =       tcf_ipt,
        .dump           =       tcf_ipt_dump,
        .cleanup        =       tcf_ipt_cleanup,
-       .lookup         =       tcf_hash_search,
        .init           =       tcf_ipt_init,
-       .walk           =       tcf_generic_walker
 };
 
 static struct tc_action_ops act_xt_ops = {
@@ -312,9 +310,7 @@ static struct tc_action_ops act_xt_ops = {
        .act            =       tcf_ipt,
        .dump           =       tcf_ipt_dump,
        .cleanup        =       tcf_ipt_cleanup,
-       .lookup         =       tcf_hash_search,
        .init           =       tcf_ipt_init,
-       .walk           =       tcf_generic_walker
 };
 
 MODULE_AUTHOR("Jamal Hadi Salim(2002-13)");
index 977c10e0631b6dfe4ead45af617c0ad93c4a0759..252378121ce7cd1848beab20aa666389937bf610 100644 (file)
@@ -271,9 +271,7 @@ static struct tc_action_ops act_mirred_ops = {
        .act            =       tcf_mirred,
        .dump           =       tcf_mirred_dump,
        .cleanup        =       tcf_mirred_cleanup,
-       .lookup         =       tcf_hash_search,
        .init           =       tcf_mirred_init,
-       .walk           =       tcf_generic_walker
 };
 
 MODULE_AUTHOR("Jamal Hadi Salim(2002)");
index 876f0ef29694a3f28260a221d0862d4fe3756f8d..6a15ace002411a8c11efeed6156d72324b9eb2ff 100644 (file)
@@ -308,9 +308,7 @@ static struct tc_action_ops act_nat_ops = {
        .act            =       tcf_nat,
        .dump           =       tcf_nat_dump,
        .cleanup        =       tcf_nat_cleanup,
-       .lookup         =       tcf_hash_search,
        .init           =       tcf_nat_init,
-       .walk           =       tcf_generic_walker
 };
 
 MODULE_DESCRIPTION("Stateless NAT actions");
index 7ed78c9e505cf7e18bc5a0b066837d19d33d4b10..03b67674169c5db79eb546d93d0b4833324786d3 100644 (file)
@@ -243,9 +243,7 @@ static struct tc_action_ops act_pedit_ops = {
        .act            =       tcf_pedit,
        .dump           =       tcf_pedit_dump,
        .cleanup        =       tcf_pedit_cleanup,
-       .lookup         =       tcf_hash_search,
        .init           =       tcf_pedit_init,
-       .walk           =       tcf_generic_walker
 };
 
 MODULE_AUTHOR("Jamal Hadi Salim(2002-4)");
index 272d8e924cf6b2467e2772898aca2d7895131545..16a62c36928a78110923d36d5b87808936d8f90a 100644 (file)
@@ -407,7 +407,6 @@ static struct tc_action_ops act_police_ops = {
        .act            =       tcf_act_police,
        .dump           =       tcf_act_police_dump,
        .cleanup        =       tcf_act_police_cleanup,
-       .lookup         =       tcf_hash_search,
        .init           =       tcf_act_police_locate,
        .walk           =       tcf_act_police_walker
 };
index 7725eb4ab756caa841eca2e0f4778880c310e5c4..31157d3e729c8c29e8bb89ce03fa68c5ad8e7f39 100644 (file)
@@ -201,7 +201,6 @@ static struct tc_action_ops act_simp_ops = {
        .dump           =       tcf_simp_dump,
        .cleanup        =       tcf_simp_cleanup,
        .init           =       tcf_simp_init,
-       .walk           =       tcf_generic_walker,
 };
 
 MODULE_AUTHOR("Jamal Hadi Salim(2005)");
index cb4221171f93f0c5b8fbb98f41b11241aa17d02a..35ea643b4325562d74c4c05d9950a4f8a8a7ad32 100644 (file)
@@ -203,7 +203,6 @@ static struct tc_action_ops act_skbedit_ops = {
        .dump           =       tcf_skbedit_dump,
        .cleanup        =       tcf_skbedit_cleanup,
        .init           =       tcf_skbedit_init,
-       .walk           =       tcf_generic_walker,
 };
 
 MODULE_AUTHOR("Alexander Duyck, <alexander.h.duyck@intel.com>");
index 0e1e38b40025fd111f50bfce339a6d2e7cae1252..717b2108f852b52399270a5be516441d9c79ed83 100644 (file)
@@ -1477,11 +1477,22 @@ static int htb_change_class(struct Qdisc *sch, u32 classid,
                sch_tree_lock(sch);
        }
 
+       rate64 = tb[TCA_HTB_RATE64] ? nla_get_u64(tb[TCA_HTB_RATE64]) : 0;
+
+       ceil64 = tb[TCA_HTB_CEIL64] ? nla_get_u64(tb[TCA_HTB_CEIL64]) : 0;
+
+       psched_ratecfg_precompute(&cl->rate, &hopt->rate, rate64);
+       psched_ratecfg_precompute(&cl->ceil, &hopt->ceil, ceil64);
+
        /* it used to be a nasty bug here, we have to check that node
         * is really leaf before changing cl->un.leaf !
         */
        if (!cl->level) {
-               cl->quantum = hopt->rate.rate / q->rate2quantum;
+               u64 quantum = cl->rate.rate_bytes_ps;
+
+               do_div(quantum, q->rate2quantum);
+               cl->quantum = min_t(u64, quantum, INT_MAX);
+
                if (!hopt->quantum && cl->quantum < 1000) {
                        pr_warning(
                               "HTB: quantum of class %X is small. Consider r2q change.\n",
@@ -1500,13 +1511,6 @@ static int htb_change_class(struct Qdisc *sch, u32 classid,
                        cl->prio = TC_HTB_NUMPRIO - 1;
        }
 
-       rate64 = tb[TCA_HTB_RATE64] ? nla_get_u64(tb[TCA_HTB_RATE64]) : 0;
-
-       ceil64 = tb[TCA_HTB_CEIL64] ? nla_get_u64(tb[TCA_HTB_CEIL64]) : 0;
-
-       psched_ratecfg_precompute(&cl->rate, &hopt->rate, rate64);
-       psched_ratecfg_precompute(&cl->ceil, &hopt->ceil, ceil64);
-
        cl->buffer = PSCHED_TICKS2NS(hopt->buffer);
        cl->cbuffer = PSCHED_TICKS2NS(hopt->cbuffer);
 
index a6090051c5dbe3d0a9aee6a2921b91397dbdc363..887e672f9d7d4b185542957bcb7e10b7d8a70cec 100644 (file)
@@ -118,6 +118,32 @@ struct tbf_sched_data {
 };
 
 
+/* Time to Length, convert time in ns to length in bytes
+ * to determinate how many bytes can be sent in given time.
+ */
+static u64 psched_ns_t2l(const struct psched_ratecfg *r,
+                        u64 time_in_ns)
+{
+       /* The formula is :
+        * len = (time_in_ns * r->rate_bytes_ps) / NSEC_PER_SEC
+        */
+       u64 len = time_in_ns * r->rate_bytes_ps;
+
+       do_div(len, NSEC_PER_SEC);
+
+       if (unlikely(r->linklayer == TC_LINKLAYER_ATM)) {
+               do_div(len, 53);
+               len = len * 48;
+       }
+
+       if (len > r->overhead)
+               len -= r->overhead;
+       else
+               len = 0;
+
+       return len;
+}
+
 /*
  * Return length of individual segments of a gso packet,
  * including all headers (MAC, IP, TCP/UDP)
@@ -289,10 +315,11 @@ static int tbf_change(struct Qdisc *sch, struct nlattr *opt)
        struct tbf_sched_data *q = qdisc_priv(sch);
        struct nlattr *tb[TCA_TBF_MAX + 1];
        struct tc_tbf_qopt *qopt;
-       struct qdisc_rate_table *rtab = NULL;
-       struct qdisc_rate_table *ptab = NULL;
        struct Qdisc *child = NULL;
-       int max_size, n;
+       struct psched_ratecfg rate;
+       struct psched_ratecfg peak;
+       u64 max_size;
+       s64 buffer, mtu;
        u64 rate64 = 0, prate64 = 0;
 
        err = nla_parse_nested(tb, TCA_TBF_MAX, opt, tbf_policy);
@@ -304,38 +331,13 @@ static int tbf_change(struct Qdisc *sch, struct nlattr *opt)
                goto done;
 
        qopt = nla_data(tb[TCA_TBF_PARMS]);
-       rtab = qdisc_get_rtab(&qopt->rate, tb[TCA_TBF_RTAB]);
-       if (rtab == NULL)
-               goto done;
-
-       if (qopt->peakrate.rate) {
-               if (qopt->peakrate.rate > qopt->rate.rate)
-                       ptab = qdisc_get_rtab(&qopt->peakrate, tb[TCA_TBF_PTAB]);
-               if (ptab == NULL)
-                       goto done;
-       }
-
-       for (n = 0; n < 256; n++)
-               if (rtab->data[n] > qopt->buffer)
-                       break;
-       max_size = (n << qopt->rate.cell_log) - 1;
-       if (ptab) {
-               int size;
-
-               for (n = 0; n < 256; n++)
-                       if (ptab->data[n] > qopt->mtu)
-                               break;
-               size = (n << qopt->peakrate.cell_log) - 1;
-               if (size < max_size)
-                       max_size = size;
-       }
-       if (max_size < 0)
-               goto done;
+       if (qopt->rate.linklayer == TC_LINKLAYER_UNAWARE)
+               qdisc_put_rtab(qdisc_get_rtab(&qopt->rate,
+                                             tb[TCA_TBF_RTAB]));
 
-       if (max_size < psched_mtu(qdisc_dev(sch)))
-               pr_warn_ratelimited("sch_tbf: burst %u is lower than device %s mtu (%u) !\n",
-                                   max_size, qdisc_dev(sch)->name,
-                                   psched_mtu(qdisc_dev(sch)));
+       if (qopt->peakrate.linklayer == TC_LINKLAYER_UNAWARE)
+                       qdisc_put_rtab(qdisc_get_rtab(&qopt->peakrate,
+                                                     tb[TCA_TBF_PTAB]));
 
        if (q->qdisc != &noop_qdisc) {
                err = fifo_set_limit(q->qdisc, qopt->limit);
@@ -349,6 +351,39 @@ static int tbf_change(struct Qdisc *sch, struct nlattr *opt)
                }
        }
 
+       buffer = min_t(u64, PSCHED_TICKS2NS(qopt->buffer), ~0U);
+       mtu = min_t(u64, PSCHED_TICKS2NS(qopt->mtu), ~0U);
+
+       if (tb[TCA_TBF_RATE64])
+               rate64 = nla_get_u64(tb[TCA_TBF_RATE64]);
+       psched_ratecfg_precompute(&rate, &qopt->rate, rate64);
+
+       max_size = min_t(u64, psched_ns_t2l(&rate, buffer), ~0U);
+
+       if (qopt->peakrate.rate) {
+               if (tb[TCA_TBF_PRATE64])
+                       prate64 = nla_get_u64(tb[TCA_TBF_PRATE64]);
+               psched_ratecfg_precompute(&peak, &qopt->peakrate, prate64);
+               if (peak.rate_bytes_ps <= rate.rate_bytes_ps) {
+                       pr_warn_ratelimited("sch_tbf: peakrate %llu is lower than or equals to rate %llu !\n",
+                                           peak.rate_bytes_ps, rate.rate_bytes_ps);
+                       err = -EINVAL;
+                       goto done;
+               }
+
+               max_size = min_t(u64, max_size, psched_ns_t2l(&peak, mtu));
+       }
+
+       if (max_size < psched_mtu(qdisc_dev(sch)))
+               pr_warn_ratelimited("sch_tbf: burst %llu is lower than device %s mtu (%u) !\n",
+                                   max_size, qdisc_dev(sch)->name,
+                                   psched_mtu(qdisc_dev(sch)));
+
+       if (!max_size) {
+               err = -EINVAL;
+               goto done;
+       }
+
        sch_tree_lock(sch);
        if (child) {
                qdisc_tree_decrease_qlen(q->qdisc, q->qdisc->q.qlen);
@@ -362,13 +397,9 @@ static int tbf_change(struct Qdisc *sch, struct nlattr *opt)
        q->tokens = q->buffer;
        q->ptokens = q->mtu;
 
-       if (tb[TCA_TBF_RATE64])
-               rate64 = nla_get_u64(tb[TCA_TBF_RATE64]);
-       psched_ratecfg_precompute(&q->rate, &rtab->rate, rate64);
-       if (ptab) {
-               if (tb[TCA_TBF_PRATE64])
-                       prate64 = nla_get_u64(tb[TCA_TBF_PRATE64]);
-               psched_ratecfg_precompute(&q->peak, &ptab->rate, prate64);
+       memcpy(&q->rate, &rate, sizeof(struct psched_ratecfg));
+       if (qopt->peakrate.rate) {
+               memcpy(&q->peak, &peak, sizeof(struct psched_ratecfg));
                q->peak_present = true;
        } else {
                q->peak_present = false;
@@ -377,10 +408,6 @@ static int tbf_change(struct Qdisc *sch, struct nlattr *opt)
        sch_tree_unlock(sch);
        err = 0;
 done:
-       if (rtab)
-               qdisc_put_rtab(rtab);
-       if (ptab)
-               qdisc_put_rtab(ptab);
        return err;
 }
 
index 68a27f9796d2ece54bcb53b98a47e8f98645077b..31ed008c8e13e88b88935c5d83a503bdc089076e 100644 (file)
@@ -154,8 +154,7 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a
 
        asoc->timeouts[SCTP_EVENT_TIMEOUT_HEARTBEAT] = 0;
        asoc->timeouts[SCTP_EVENT_TIMEOUT_SACK] = asoc->sackdelay;
-       asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE] =
-               min_t(unsigned long, sp->autoclose, net->sctp.max_autoclose) * HZ;
+       asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE] = sp->autoclose * HZ;
 
        /* Initializes the timers */
        for (i = SCTP_EVENT_TIMEOUT_NONE; i < SCTP_NUM_TIMEOUT_TYPES; ++i)
@@ -291,8 +290,6 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a
                asoc->peer.ipv6_address = 1;
        INIT_LIST_HEAD(&asoc->asocs);
 
-       asoc->autoclose = sp->autoclose;
-
        asoc->default_stream = sp->default_stream;
        asoc->default_ppid = sp->default_ppid;
        asoc->default_flags = sp->default_flags;
index 0e2644d0a773710d149639ab3aa777c6313a7737..0fb140f8f088abe9421c401680731fb1c916a154 100644 (file)
@@ -581,7 +581,8 @@ int sctp_packet_transmit(struct sctp_packet *packet)
                unsigned long timeout;
 
                /* Restart the AUTOCLOSE timer when sending data. */
-               if (sctp_state(asoc, ESTABLISHED) && asoc->autoclose) {
+               if (sctp_state(asoc, ESTABLISHED) &&
+                   asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE]) {
                        timer = &asoc->timers[SCTP_EVENT_TIMEOUT_AUTOCLOSE];
                        timeout = asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE];
 
index 53c452efb40b4ab761a54acc37f8c1333fc73fd7..5e68b94ee64012571bc4d5f277a9cc594467cc3b 100644 (file)
@@ -38,6 +38,7 @@
 #include <net/sctp/sctp.h>
 #include <net/sctp/sm.h>
 
+MODULE_SOFTDEP("pre: sctp");
 MODULE_AUTHOR("Wei Yongjun <yjwei@cn.fujitsu.com>");
 MODULE_DESCRIPTION("SCTP snooper");
 MODULE_LICENSE("GPL");
@@ -182,6 +183,20 @@ static struct jprobe sctp_recv_probe = {
        .entry  = jsctp_sf_eat_sack,
 };
 
+static __init int sctp_setup_jprobe(void)
+{
+       int ret = register_jprobe(&sctp_recv_probe);
+
+       if (ret) {
+               if (request_module("sctp"))
+                       goto out;
+               ret = register_jprobe(&sctp_recv_probe);
+       }
+
+out:
+       return ret;
+}
+
 static __init int sctpprobe_init(void)
 {
        int ret = -ENOMEM;
@@ -202,7 +217,7 @@ static __init int sctpprobe_init(void)
                         &sctpprobe_fops))
                goto free_kfifo;
 
-       ret = register_jprobe(&sctp_recv_probe);
+       ret = sctp_setup_jprobe();
        if (ret)
                goto remove_proc;
 
index dfe3f36ff2aa27165b35a39d382583759cd3ebae..a26065be728901ed3c7e35690bafc51deabab115 100644 (file)
@@ -820,7 +820,7 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(struct net *net,
        SCTP_INC_STATS(net, SCTP_MIB_PASSIVEESTABS);
        sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_START, SCTP_NULL());
 
-       if (new_asoc->autoclose)
+       if (new_asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE])
                sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START,
                                SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE));
 
@@ -908,7 +908,7 @@ sctp_disposition_t sctp_sf_do_5_1E_ca(struct net *net,
        SCTP_INC_STATS(net, SCTP_MIB_CURRESTAB);
        SCTP_INC_STATS(net, SCTP_MIB_ACTIVEESTABS);
        sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_START, SCTP_NULL());
-       if (asoc->autoclose)
+       if (asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE])
                sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START,
                                SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE));
 
@@ -2970,7 +2970,7 @@ sctp_disposition_t sctp_sf_eat_data_6_2(struct net *net,
        if (chunk->chunk_hdr->flags & SCTP_DATA_SACK_IMM)
                force = SCTP_FORCE();
 
-       if (asoc->autoclose) {
+       if (asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE]) {
                sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,
                                SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE));
        }
@@ -3878,7 +3878,7 @@ sctp_disposition_t sctp_sf_eat_fwd_tsn(struct net *net,
                                SCTP_CHUNK(chunk));
 
        /* Count this as receiving DATA. */
-       if (asoc->autoclose) {
+       if (asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE]) {
                sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,
                                SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE));
        }
@@ -5267,7 +5267,7 @@ sctp_disposition_t sctp_sf_do_9_2_start_shutdown(
        sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,
                        SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD));
 
-       if (asoc->autoclose)
+       if (asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE])
                sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
                                SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE));
 
@@ -5346,7 +5346,7 @@ sctp_disposition_t sctp_sf_do_9_2_shutdown_ack(
        sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,
                        SCTP_TO(SCTP_EVENT_TIMEOUT_T2_SHUTDOWN));
 
-       if (asoc->autoclose)
+       if (asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE])
                sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
                                SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE));
 
index 72046b9729a8a6a669fb9c75446de8ef2fe345c6..42b709c95cf3d0f97b1de88d727a4258e8835396 100644 (file)
@@ -2196,6 +2196,7 @@ static int sctp_setsockopt_autoclose(struct sock *sk, char __user *optval,
                                     unsigned int optlen)
 {
        struct sctp_sock *sp = sctp_sk(sk);
+       struct net *net = sock_net(sk);
 
        /* Applicable to UDP-style socket only */
        if (sctp_style(sk, TCP))
@@ -2205,6 +2206,9 @@ static int sctp_setsockopt_autoclose(struct sock *sk, char __user *optval,
        if (copy_from_user(&sp->autoclose, optval, optlen))
                return -EFAULT;
 
+       if (sp->autoclose > net->sctp.max_autoclose)
+               sp->autoclose = net->sctp.max_autoclose;
+
        return 0;
 }
 
@@ -2811,6 +2815,8 @@ static int sctp_setsockopt_rtoinfo(struct sock *sk, char __user *optval, unsigne
 {
        struct sctp_rtoinfo rtoinfo;
        struct sctp_association *asoc;
+       unsigned long rto_min, rto_max;
+       struct sctp_sock *sp = sctp_sk(sk);
 
        if (optlen != sizeof (struct sctp_rtoinfo))
                return -EINVAL;
@@ -2824,26 +2830,36 @@ static int sctp_setsockopt_rtoinfo(struct sock *sk, char __user *optval, unsigne
        if (!asoc && rtoinfo.srto_assoc_id && sctp_style(sk, UDP))
                return -EINVAL;
 
+       rto_max = rtoinfo.srto_max;
+       rto_min = rtoinfo.srto_min;
+
+       if (rto_max)
+               rto_max = asoc ? msecs_to_jiffies(rto_max) : rto_max;
+       else
+               rto_max = asoc ? asoc->rto_max : sp->rtoinfo.srto_max;
+
+       if (rto_min)
+               rto_min = asoc ? msecs_to_jiffies(rto_min) : rto_min;
+       else
+               rto_min = asoc ? asoc->rto_min : sp->rtoinfo.srto_min;
+
+       if (rto_min > rto_max)
+               return -EINVAL;
+
        if (asoc) {
                if (rtoinfo.srto_initial != 0)
                        asoc->rto_initial =
                                msecs_to_jiffies(rtoinfo.srto_initial);
-               if (rtoinfo.srto_max != 0)
-                       asoc->rto_max = msecs_to_jiffies(rtoinfo.srto_max);
-               if (rtoinfo.srto_min != 0)
-                       asoc->rto_min = msecs_to_jiffies(rtoinfo.srto_min);
+               asoc->rto_max = rto_max;
+               asoc->rto_min = rto_min;
        } else {
                /* If there is no association or the association-id = 0
                 * set the values to the endpoint.
                 */
-               struct sctp_sock *sp = sctp_sk(sk);
-
                if (rtoinfo.srto_initial != 0)
                        sp->rtoinfo.srto_initial = rtoinfo.srto_initial;
-               if (rtoinfo.srto_max != 0)
-                       sp->rtoinfo.srto_max = rtoinfo.srto_max;
-               if (rtoinfo.srto_min != 0)
-                       sp->rtoinfo.srto_min = rtoinfo.srto_min;
+               sp->rtoinfo.srto_max = rto_max;
+               sp->rtoinfo.srto_min = rto_min;
        }
 
        return 0;
index 6b36561a1b3b7cceab5f5a4a9dce7aa2bc362266..b0565afb61c740bcd0ed9863049dc74cd62072f0 100644 (file)
@@ -56,11 +56,16 @@ extern long sysctl_sctp_mem[3];
 extern int sysctl_sctp_rmem[3];
 extern int sysctl_sctp_wmem[3];
 
-static int proc_sctp_do_hmac_alg(struct ctl_table *ctl,
-                               int write,
+static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, int write,
+                               void __user *buffer, size_t *lenp,
+                               loff_t *ppos);
+static int proc_sctp_do_rto_min(struct ctl_table *ctl, int write,
+                               void __user *buffer, size_t *lenp,
+                               loff_t *ppos);
+static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write,
                                void __user *buffer, size_t *lenp,
-
                                loff_t *ppos);
+
 static struct ctl_table sctp_table[] = {
        {
                .procname       = "sctp_mem",
@@ -102,17 +107,17 @@ static struct ctl_table sctp_net_table[] = {
                .data           = &init_net.sctp.rto_min,
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
-               .proc_handler   = proc_dointvec_minmax,
+               .proc_handler   = proc_sctp_do_rto_min,
                .extra1         = &one,
-               .extra2         = &timer_max
+               .extra2         = &init_net.sctp.rto_max
        },
        {
                .procname       = "rto_max",
                .data           = &init_net.sctp.rto_max,
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
-               .proc_handler   = proc_dointvec_minmax,
-               .extra1         = &one,
+               .proc_handler   = proc_sctp_do_rto_max,
+               .extra1         = &init_net.sctp.rto_min,
                .extra2         = &timer_max
        },
        {
@@ -294,8 +299,7 @@ static struct ctl_table sctp_net_table[] = {
        { /* sentinel */ }
 };
 
-static int proc_sctp_do_hmac_alg(struct ctl_table *ctl,
-                               int write,
+static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, int write,
                                void __user *buffer, size_t *lenp,
                                loff_t *ppos)
 {
@@ -342,6 +346,60 @@ static int proc_sctp_do_hmac_alg(struct ctl_table *ctl,
        return ret;
 }
 
+static int proc_sctp_do_rto_min(struct ctl_table *ctl, int write,
+                               void __user *buffer, size_t *lenp,
+                               loff_t *ppos)
+{
+       struct net *net = current->nsproxy->net_ns;
+       int new_value;
+       struct ctl_table tbl;
+       unsigned int min = *(unsigned int *) ctl->extra1;
+       unsigned int max = *(unsigned int *) ctl->extra2;
+       int ret;
+
+       memset(&tbl, 0, sizeof(struct ctl_table));
+       tbl.maxlen = sizeof(unsigned int);
+
+       if (write)
+               tbl.data = &new_value;
+       else
+               tbl.data = &net->sctp.rto_min;
+       ret = proc_dointvec(&tbl, write, buffer, lenp, ppos);
+       if (write) {
+               if (ret || new_value > max || new_value < min)
+                       return -EINVAL;
+               net->sctp.rto_min = new_value;
+       }
+       return ret;
+}
+
+static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write,
+                               void __user *buffer, size_t *lenp,
+                               loff_t *ppos)
+{
+       struct net *net = current->nsproxy->net_ns;
+       int new_value;
+       struct ctl_table tbl;
+       unsigned int min = *(unsigned int *) ctl->extra1;
+       unsigned int max = *(unsigned int *) ctl->extra2;
+       int ret;
+
+       memset(&tbl, 0, sizeof(struct ctl_table));
+       tbl.maxlen = sizeof(unsigned int);
+
+       if (write)
+               tbl.data = &new_value;
+       else
+               tbl.data = &net->sctp.rto_max;
+       ret = proc_dointvec(&tbl, write, buffer, lenp, ppos);
+       if (write) {
+               if (ret || new_value > max || new_value < min)
+                       return -EINVAL;
+               net->sctp.rto_max = new_value;
+       }
+       return ret;
+}
+
 int sctp_sysctl_net_register(struct net *net)
 {
        struct ctl_table *table;
index e332efb124cc0c34f93786232353c37dd2e10ea1..efc46ffed1fd63a5fb510046bc6fd013dd99c252 100644 (file)
@@ -573,7 +573,7 @@ void sctp_transport_burst_limited(struct sctp_transport *t)
        u32 old_cwnd = t->cwnd;
        u32 max_burst_bytes;
 
-       if (t->burst_limited)
+       if (t->burst_limited || asoc->max_burst == 0)
                return;
 
        max_burst_bytes = t->flight_size + (asoc->max_burst * asoc->pathmtu);
index fd4eeeaa972a6f4226f1dce420d7fb0b17670c78..c6d3f75a9e1bba6f99cff5aed75d8e5a96f94484 100644 (file)
@@ -113,7 +113,6 @@ err:
 static void tipc_core_stop(void)
 {
        tipc_netlink_stop();
-       tipc_handler_stop();
        tipc_cfg_stop();
        tipc_subscr_stop();
        tipc_nametbl_stop();
@@ -146,9 +145,10 @@ static int tipc_core_start(void)
                res = tipc_subscr_start();
        if (!res)
                res = tipc_cfg_init();
-       if (res)
+       if (res) {
+               tipc_handler_stop();
                tipc_core_stop();
-
+       }
        return res;
 }
 
@@ -178,6 +178,7 @@ static int __init tipc_init(void)
 
 static void __exit tipc_exit(void)
 {
+       tipc_handler_stop();
        tipc_core_stop_net();
        tipc_core_stop();
        pr_info("Deactivated\n");
index b36f0fcd9bdfe76d04adf287687190ada3e9ccca..e4bc8a2967447fbde1f39d0d19146f2c7848ac99 100644 (file)
@@ -56,12 +56,13 @@ unsigned int tipc_k_signal(Handler routine, unsigned long argument)
 {
        struct queue_item *item;
 
+       spin_lock_bh(&qitem_lock);
        if (!handler_enabled) {
                pr_err("Signal request ignored by handler\n");
+               spin_unlock_bh(&qitem_lock);
                return -ENOPROTOOPT;
        }
 
-       spin_lock_bh(&qitem_lock);
        item = kmem_cache_alloc(tipc_queue_item_cache, GFP_ATOMIC);
        if (!item) {
                pr_err("Signal queue out of memory\n");
@@ -112,10 +113,14 @@ void tipc_handler_stop(void)
        struct list_head *l, *n;
        struct queue_item *item;
 
-       if (!handler_enabled)
+       spin_lock_bh(&qitem_lock);
+       if (!handler_enabled) {
+               spin_unlock_bh(&qitem_lock);
                return;
-
+       }
        handler_enabled = 0;
+       spin_unlock_bh(&qitem_lock);
+
        tasklet_kill(&tipc_tasklet);
 
        spin_lock_bh(&qitem_lock);
index 01625ccc3ae64ac3b5b1c664feec7f0136973e04..a427623ee574e88d9926c7972a0650c5c6f9a3eb 100644 (file)
@@ -530,13 +530,17 @@ static int unix_seqpacket_sendmsg(struct kiocb *, struct socket *,
 static int unix_seqpacket_recvmsg(struct kiocb *, struct socket *,
                                  struct msghdr *, size_t, int);
 
-static void unix_set_peek_off(struct sock *sk, int val)
+static int unix_set_peek_off(struct sock *sk, int val)
 {
        struct unix_sock *u = unix_sk(sk);
 
-       mutex_lock(&u->readlock);
+       if (mutex_lock_interruptible(&u->readlock))
+               return -EINTR;
+
        sk->sk_peek_off = val;
        mutex_unlock(&u->readlock);
+
+       return 0;
 }
 
 
@@ -714,7 +718,9 @@ static int unix_autobind(struct socket *sock)
        int err;
        unsigned int retries = 0;
 
-       mutex_lock(&u->readlock);
+       err = mutex_lock_interruptible(&u->readlock);
+       if (err)
+               return err;
 
        err = 0;
        if (u->addr)
@@ -873,7 +879,9 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
                goto out;
        addr_len = err;
 
-       mutex_lock(&u->readlock);
+       err = mutex_lock_interruptible(&u->readlock);
+       if (err)
+               goto out;
 
        err = -EINVAL;
        if (u->addr)
index aff959e5a1b360e7cb467cade7f7d617544b3909..52b865fb7351ac3c221c120bc0cc236687a12513 100644 (file)
@@ -451,6 +451,15 @@ int wiphy_register(struct wiphy *wiphy)
        int i;
        u16 ifmodes = wiphy->interface_modes;
 
+       /* support for 5/10 MHz is broken due to nl80211 API mess - disable */
+       wiphy->flags &= ~WIPHY_FLAG_SUPPORTS_5_10_MHZ;
+
+       /*
+        * There are major locking problems in nl80211/mac80211 for CSA,
+        * disable for all drivers until this has been reworked.
+        */
+       wiphy->flags &= ~WIPHY_FLAG_HAS_CHANNEL_SWITCH;
+
 #ifdef CONFIG_PM
        if (WARN_ON(wiphy->wowlan &&
                    (wiphy->wowlan->flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE) &&
index 9d797df56649c5a47fdf1f61e665ee31e4b77e7c..89737ee2669a8de9bc8f02aa1c392052369d210b 100644 (file)
@@ -262,7 +262,7 @@ int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev,
 
        /* try to find an IBSS channel if none requested ... */
        if (!wdev->wext.ibss.chandef.chan) {
-               wdev->wext.ibss.chandef.width = NL80211_CHAN_WIDTH_20_NOHT;
+               struct ieee80211_channel *new_chan = NULL;
 
                for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
                        struct ieee80211_supported_band *sband;
@@ -278,18 +278,19 @@ int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev,
                                        continue;
                                if (chan->flags & IEEE80211_CHAN_DISABLED)
                                        continue;
-                               wdev->wext.ibss.chandef.chan = chan;
-                               wdev->wext.ibss.chandef.center_freq1 =
-                                       chan->center_freq;
+                               new_chan = chan;
                                break;
                        }
 
-                       if (wdev->wext.ibss.chandef.chan)
+                       if (new_chan)
                                break;
                }
 
-               if (!wdev->wext.ibss.chandef.chan)
+               if (!new_chan)
                        return -EINVAL;
+
+               cfg80211_chandef_create(&wdev->wext.ibss.chandef, new_chan,
+                                       NL80211_CHAN_NO_HT);
        }
 
        /* don't join -- SSID is not there */
@@ -363,9 +364,8 @@ int cfg80211_ibss_wext_siwfreq(struct net_device *dev,
                return err;
 
        if (chan) {
-               wdev->wext.ibss.chandef.chan = chan;
-               wdev->wext.ibss.chandef.width = NL80211_CHAN_WIDTH_20_NOHT;
-               wdev->wext.ibss.chandef.center_freq1 = freq;
+               cfg80211_chandef_create(&wdev->wext.ibss.chandef, chan,
+                                       NL80211_CHAN_NO_HT);
                wdev->wext.ibss.channel_fixed = true;
        } else {
                /* cfg80211_ibss_wext_join will pick one if needed */
index a1eb21073176115a587f9eb1edf5d36dba582484..138dc3bb8b67d8c345531a95ce0c8342271ce79e 100644 (file)
@@ -2687,7 +2687,7 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
        hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
                             NL80211_CMD_NEW_KEY);
        if (!hdr)
-               return -ENOBUFS;
+               goto nla_put_failure;
 
        cookie.msg = msg;
        cookie.idx = key_idx;
@@ -5349,6 +5349,10 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
                                err = -EINVAL;
                                goto out_free;
                        }
+
+                       if (!wiphy->bands[band])
+                               continue;
+
                        err = ieee80211_get_ratemask(wiphy->bands[band],
                                                     nla_data(attr),
                                                     nla_len(attr),
@@ -9633,8 +9637,9 @@ static int nl80211_add_scan_req(struct sk_buff *msg,
            nla_put(msg, NL80211_ATTR_IE, req->ie_len, req->ie))
                goto nla_put_failure;
 
-       if (req->flags)
-               nla_put_u32(msg, NL80211_ATTR_SCAN_FLAGS, req->flags);
+       if (req->flags &&
+           nla_put_u32(msg, NL80211_ATTR_SCAN_FLAGS, req->flags))
+               goto nla_put_failure;
 
        return 0;
  nla_put_failure:
@@ -11093,6 +11098,8 @@ void cfg80211_report_wowlan_wakeup(struct wireless_dev *wdev,
                struct nlattr *reasons;
 
                reasons = nla_nest_start(msg, NL80211_ATTR_WOWLAN_TRIGGERS);
+               if (!reasons)
+                       goto free_msg;
 
                if (wakeup->disconnect &&
                    nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT))
@@ -11118,16 +11125,18 @@ void cfg80211_report_wowlan_wakeup(struct wireless_dev *wdev,
                                wakeup->pattern_idx))
                        goto free_msg;
 
-               if (wakeup->tcp_match)
-                       nla_put_flag(msg, NL80211_WOWLAN_TRIG_WAKEUP_TCP_MATCH);
+               if (wakeup->tcp_match &&
+                   nla_put_flag(msg, NL80211_WOWLAN_TRIG_WAKEUP_TCP_MATCH))
+                       goto free_msg;
 
-               if (wakeup->tcp_connlost)
-                       nla_put_flag(msg,
-                                    NL80211_WOWLAN_TRIG_WAKEUP_TCP_CONNLOST);
+               if (wakeup->tcp_connlost &&
+                   nla_put_flag(msg, NL80211_WOWLAN_TRIG_WAKEUP_TCP_CONNLOST))
+                       goto free_msg;
 
-               if (wakeup->tcp_nomoretokens)
-                       nla_put_flag(msg,
-                               NL80211_WOWLAN_TRIG_WAKEUP_TCP_NOMORETOKENS);
+               if (wakeup->tcp_nomoretokens &&
+                   nla_put_flag(msg,
+                                NL80211_WOWLAN_TRIG_WAKEUP_TCP_NOMORETOKENS))
+                       goto free_msg;
 
                if (wakeup->packet) {
                        u32 pkt_attr = NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211;
@@ -11263,24 +11272,29 @@ void cfg80211_ft_event(struct net_device *netdev,
                return;
 
        hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FT_EVENT);
-       if (!hdr) {
-               nlmsg_free(msg);
-               return;
-       }
+       if (!hdr)
+               goto out;
 
-       nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
-       nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
-       nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, ft_event->target_ap);
-       if (ft_event->ies)
-               nla_put(msg, NL80211_ATTR_IE, ft_event->ies_len, ft_event->ies);
-       if (ft_event->ric_ies)
-               nla_put(msg, NL80211_ATTR_IE_RIC, ft_event->ric_ies_len,
-                       ft_event->ric_ies);
+       if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
+           nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
+           nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, ft_event->target_ap))
+               goto out;
+
+       if (ft_event->ies &&
+           nla_put(msg, NL80211_ATTR_IE, ft_event->ies_len, ft_event->ies))
+               goto out;
+       if (ft_event->ric_ies &&
+           nla_put(msg, NL80211_ATTR_IE_RIC, ft_event->ric_ies_len,
+                   ft_event->ric_ies))
+               goto out;
 
        genlmsg_end(msg, hdr);
 
        genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
                                NL80211_MCGRP_MLME, GFP_KERNEL);
+       return;
+ out:
+       nlmsg_free(msg);
 }
 EXPORT_SYMBOL(cfg80211_ft_event);
 
index 5f7a8b663cb9c9eb59b32f4ce63076a6a86914cc..7941fbdfb050e573120f36b770ae8321130d8d01 100644 (file)
 #include <tools/be_byteshift.h>
 #include <tools/le_byteshift.h>
 
+#ifndef EM_ARCOMPACT
+#define EM_ARCOMPACT   93
+#endif
+
 #ifndef EM_AARCH64
 #define EM_AARCH64     183
 #endif
@@ -268,6 +272,7 @@ do_file(char const *const fname)
        case EM_S390:
                custom_sort = sort_relative_table;
                break;
+       case EM_ARCOMPACT:
        case EM_ARM:
        case EM_AARCH64:
        case EM_MIPS:
index 7f44c3207a9bb95982d3bb41990568c41f64c54e..8137b27d641dad9080df66c829f8109472dbccc6 100644 (file)
@@ -70,7 +70,7 @@ int big_key_instantiate(struct key *key, struct key_preparsed_payload *prep)
                 *
                 * TODO: Encrypt the stored data with a temporary key.
                 */
-               file = shmem_file_setup("", datalen, 0);
+               file = shmem_kernel_file_setup("", datalen, 0);
                if (IS_ERR(file)) {
                        ret = PTR_ERR(file);
                        goto err_quota;
index 55d110f0acedc96d17bcc5f5903aaa743ed6cb32..6e21c11e48bc1cd434664d28f83084b54db50bd6 100644 (file)
@@ -272,7 +272,7 @@ struct key *key_alloc(struct key_type *type, const char *desc,
        }
 
        /* allocate and initialise the key and its description */
-       key = kmem_cache_alloc(key_jar, GFP_KERNEL);
+       key = kmem_cache_zalloc(key_jar, GFP_KERNEL);
        if (!key)
                goto no_memory_2;
 
@@ -293,18 +293,12 @@ struct key *key_alloc(struct key_type *type, const char *desc,
        key->uid = uid;
        key->gid = gid;
        key->perm = perm;
-       key->flags = 0;
-       key->expiry = 0;
-       key->payload.data = NULL;
-       key->security = NULL;
 
        if (!(flags & KEY_ALLOC_NOT_IN_QUOTA))
                key->flags |= 1 << KEY_FLAG_IN_QUOTA;
        if (flags & KEY_ALLOC_TRUSTED)
                key->flags |= 1 << KEY_FLAG_TRUSTED;
 
-       memset(&key->type_data, 0, sizeof(key->type_data));
-
 #ifdef KEY_DEBUGGING
        key->magic = KEY_DEBUG_MAGIC;
 #endif
index 69f0cb7bab7e873f8d8997d71db7c42430f72ce6..d46cbc5e335e9c330ccd74a08fcbf78aeafe8c96 100644 (file)
@@ -160,7 +160,7 @@ static u64 mult_64x32_and_fold(u64 x, u32 y)
 static unsigned long hash_key_type_and_desc(const struct keyring_index_key *index_key)
 {
        const unsigned level_shift = ASSOC_ARRAY_LEVEL_STEP;
-       const unsigned long level_mask = ASSOC_ARRAY_LEVEL_STEP_MASK;
+       const unsigned long fan_mask = ASSOC_ARRAY_FAN_MASK;
        const char *description = index_key->description;
        unsigned long hash, type;
        u32 piece;
@@ -194,10 +194,10 @@ static unsigned long hash_key_type_and_desc(const struct keyring_index_key *inde
         * ordinary keys by making sure the lowest level segment in the hash is
         * zero for keyrings and non-zero otherwise.
         */
-       if (index_key->type != &key_type_keyring && (hash & level_mask) == 0)
+       if (index_key->type != &key_type_keyring && (hash & fan_mask) == 0)
                return hash | (hash >> (ASSOC_ARRAY_KEY_CHUNK_SIZE - level_shift)) | 1;
-       if (index_key->type == &key_type_keyring && (hash & level_mask) != 0)
-               return (hash + (hash << level_shift)) & ~level_mask;
+       if (index_key->type == &key_type_keyring && (hash & fan_mask) != 0)
+               return (hash + (hash << level_shift)) & ~fan_mask;
        return hash;
 }
 
@@ -279,12 +279,11 @@ static bool keyring_compare_object(const void *object, const void *data)
  * Compare the index keys of a pair of objects and determine the bit position
  * at which they differ - if they differ.
  */
-static int keyring_diff_objects(const void *_a, const void *_b)
+static int keyring_diff_objects(const void *object, const void *data)
 {
-       const struct key *key_a = keyring_ptr_to_key(_a);
-       const struct key *key_b = keyring_ptr_to_key(_b);
+       const struct key *key_a = keyring_ptr_to_key(object);
        const struct keyring_index_key *a = &key_a->index_key;
-       const struct keyring_index_key *b = &key_b->index_key;
+       const struct keyring_index_key *b = data;
        unsigned long seg_a, seg_b;
        int level, i;
 
@@ -691,8 +690,8 @@ descend_to_node:
                smp_read_barrier_depends();
                ptr = ACCESS_ONCE(shortcut->next_node);
                BUG_ON(!assoc_array_ptr_is_node(ptr));
-               node = assoc_array_ptr_to_node(ptr);
        }
+       node = assoc_array_ptr_to_node(ptr);
 
 begin_node:
        kdebug("begin_node");
index 794c3ca49eac92998caa17be71a4bdc472c2e9c8..419491d8e7d20737cc2e2098882994a1fc37ca98 100644 (file)
@@ -53,6 +53,7 @@
 #include <net/ip.h>            /* for local_port_range[] */
 #include <net/sock.h>
 #include <net/tcp.h>           /* struct or_callable used in sock_rcv_skb */
+#include <net/inet_connection_sock.h>
 #include <net/net_namespace.h>
 #include <net/netlabel.h>
 #include <linux/uaccess.h>
 #include "audit.h"
 #include "avc_ss.h"
 
-#define SB_TYPE_FMT "%s%s%s"
-#define SB_SUBTYPE(sb) (sb->s_subtype && sb->s_subtype[0])
-#define SB_TYPE_ARGS(sb) sb->s_type->name, SB_SUBTYPE(sb) ? "." : "", SB_SUBTYPE(sb) ? sb->s_subtype : ""
-
 extern struct security_operations *security_ops;
 
 /* SECMARK reference count */
@@ -413,8 +410,8 @@ static int sb_finish_set_opts(struct super_block *sb)
                   the first boot of the SELinux kernel before we have
                   assigned xattr values to the filesystem. */
                if (!root_inode->i_op->getxattr) {
-                       printk(KERN_WARNING "SELinux: (dev %s, type "SB_TYPE_FMT") has no "
-                              "xattr support\n", sb->s_id, SB_TYPE_ARGS(sb));
+                       printk(KERN_WARNING "SELinux: (dev %s, type %s) has no "
+                              "xattr support\n", sb->s_id, sb->s_type->name);
                        rc = -EOPNOTSUPP;
                        goto out;
                }
@@ -422,22 +419,22 @@ static int sb_finish_set_opts(struct super_block *sb)
                if (rc < 0 && rc != -ENODATA) {
                        if (rc == -EOPNOTSUPP)
                                printk(KERN_WARNING "SELinux: (dev %s, type "
-                                      SB_TYPE_FMT") has no security xattr handler\n",
-                                      sb->s_id, SB_TYPE_ARGS(sb));
+                                      "%s) has no security xattr handler\n",
+                                      sb->s_id, sb->s_type->name);
                        else
                                printk(KERN_WARNING "SELinux: (dev %s, type "
-                                      SB_TYPE_FMT") getxattr errno %d\n", sb->s_id,
-                                      SB_TYPE_ARGS(sb), -rc);
+                                      "%s) getxattr errno %d\n", sb->s_id,
+                                      sb->s_type->name, -rc);
                        goto out;
                }
        }
 
        if (sbsec->behavior > ARRAY_SIZE(labeling_behaviors))
-               printk(KERN_ERR "SELinux: initialized (dev %s, type "SB_TYPE_FMT"), unknown behavior\n",
-                      sb->s_id, SB_TYPE_ARGS(sb));
+               printk(KERN_ERR "SELinux: initialized (dev %s, type %s), unknown behavior\n",
+                      sb->s_id, sb->s_type->name);
        else
-               printk(KERN_DEBUG "SELinux: initialized (dev %s, type "SB_TYPE_FMT"), %s\n",
-                      sb->s_id, SB_TYPE_ARGS(sb),
+               printk(KERN_DEBUG "SELinux: initialized (dev %s, type %s), %s\n",
+                      sb->s_id, sb->s_type->name,
                       labeling_behaviors[sbsec->behavior-1]);
 
        sbsec->flags |= SE_SBINITIALIZED;
@@ -600,6 +597,7 @@ static int selinux_set_mnt_opts(struct super_block *sb,
        const struct cred *cred = current_cred();
        int rc = 0, i;
        struct superblock_security_struct *sbsec = sb->s_security;
+       const char *name = sb->s_type->name;
        struct inode *inode = sbsec->sb->s_root->d_inode;
        struct inode_security_struct *root_isec = inode->i_security;
        u32 fscontext_sid = 0, context_sid = 0, rootcontext_sid = 0;
@@ -658,8 +656,8 @@ static int selinux_set_mnt_opts(struct super_block *sb,
                                             strlen(mount_options[i]), &sid);
                if (rc) {
                        printk(KERN_WARNING "SELinux: security_context_to_sid"
-                              "(%s) failed for (dev %s, type "SB_TYPE_FMT") errno=%d\n",
-                              mount_options[i], sb->s_id, SB_TYPE_ARGS(sb), rc);
+                              "(%s) failed for (dev %s, type %s) errno=%d\n",
+                              mount_options[i], sb->s_id, name, rc);
                        goto out;
                }
                switch (flags[i]) {
@@ -806,8 +804,7 @@ out:
 out_double_mount:
        rc = -EINVAL;
        printk(KERN_WARNING "SELinux: mount invalid.  Same superblock, different "
-              "security settings for (dev %s, type "SB_TYPE_FMT")\n", sb->s_id,
-              SB_TYPE_ARGS(sb));
+              "security settings for (dev %s, type %s)\n", sb->s_id, name);
        goto out;
 }
 
@@ -2480,8 +2477,8 @@ static int selinux_sb_remount(struct super_block *sb, void *data)
                rc = security_context_to_sid(mount_options[i], len, &sid);
                if (rc) {
                        printk(KERN_WARNING "SELinux: security_context_to_sid"
-                              "(%s) failed for (dev %s, type "SB_TYPE_FMT") errno=%d\n",
-                              mount_options[i], sb->s_id, SB_TYPE_ARGS(sb), rc);
+                              "(%s) failed for (dev %s, type %s) errno=%d\n",
+                              mount_options[i], sb->s_id, sb->s_type->name, rc);
                        goto out_free_opts;
                }
                rc = -EINVAL;
@@ -2519,8 +2516,8 @@ out_free_secdata:
        return rc;
 out_bad_option:
        printk(KERN_WARNING "SELinux: unable to change security options "
-              "during remount (dev %s, type "SB_TYPE_FMT")\n", sb->s_id,
-              SB_TYPE_ARGS(sb));
+              "during remount (dev %s, type=%s)\n", sb->s_id,
+              sb->s_type->name);
        goto out_free_opts;
 }
 
@@ -3828,7 +3825,7 @@ static int selinux_skb_peerlbl_sid(struct sk_buff *skb, u16 family, u32 *sid)
        u32 nlbl_sid;
        u32 nlbl_type;
 
-       err = selinux_skb_xfrm_sid(skb, &xfrm_sid);
+       err = selinux_xfrm_skb_sid(skb, &xfrm_sid);
        if (unlikely(err))
                return -EACCES;
        err = selinux_netlbl_skbuff_getsid(skb, family, &nlbl_type, &nlbl_sid);
@@ -3846,6 +3843,30 @@ static int selinux_skb_peerlbl_sid(struct sk_buff *skb, u16 family, u32 *sid)
        return 0;
 }
 
+/**
+ * selinux_conn_sid - Determine the child socket label for a connection
+ * @sk_sid: the parent socket's SID
+ * @skb_sid: the packet's SID
+ * @conn_sid: the resulting connection SID
+ *
+ * If @skb_sid is valid then the user:role:type information from @sk_sid is
+ * combined with the MLS information from @skb_sid in order to create
+ * @conn_sid.  If @skb_sid is not valid then then @conn_sid is simply a copy
+ * of @sk_sid.  Returns zero on success, negative values on failure.
+ *
+ */
+static int selinux_conn_sid(u32 sk_sid, u32 skb_sid, u32 *conn_sid)
+{
+       int err = 0;
+
+       if (skb_sid != SECSID_NULL)
+               err = security_sid_mls_copy(sk_sid, skb_sid, conn_sid);
+       else
+               *conn_sid = sk_sid;
+
+       return err;
+}
+
 /* socket security operations */
 
 static int socket_sockcreate_sid(const struct task_security_struct *tsec,
@@ -4452,7 +4473,7 @@ static int selinux_inet_conn_request(struct sock *sk, struct sk_buff *skb,
        struct sk_security_struct *sksec = sk->sk_security;
        int err;
        u16 family = sk->sk_family;
-       u32 newsid;
+       u32 connsid;
        u32 peersid;
 
        /* handle mapped IPv4 packets arriving via IPv6 sockets */
@@ -4462,16 +4483,11 @@ static int selinux_inet_conn_request(struct sock *sk, struct sk_buff *skb,
        err = selinux_skb_peerlbl_sid(skb, family, &peersid);
        if (err)
                return err;
-       if (peersid == SECSID_NULL) {
-               req->secid = sksec->sid;
-               req->peer_secid = SECSID_NULL;
-       } else {
-               err = security_sid_mls_copy(sksec->sid, peersid, &newsid);
-               if (err)
-                       return err;
-               req->secid = newsid;
-               req->peer_secid = peersid;
-       }
+       err = selinux_conn_sid(sksec->sid, peersid, &connsid);
+       if (err)
+               return err;
+       req->secid = connsid;
+       req->peer_secid = peersid;
 
        return selinux_netlbl_inet_conn_request(req, family);
 }
@@ -4731,6 +4747,7 @@ static unsigned int selinux_ipv6_forward(const struct nf_hook_ops *ops,
 static unsigned int selinux_ip_output(struct sk_buff *skb,
                                      u16 family)
 {
+       struct sock *sk;
        u32 sid;
 
        if (!netlbl_enabled())
@@ -4739,8 +4756,27 @@ static unsigned int selinux_ip_output(struct sk_buff *skb,
        /* we do this in the LOCAL_OUT path and not the POST_ROUTING path
         * because we want to make sure we apply the necessary labeling
         * before IPsec is applied so we can leverage AH protection */
-       if (skb->sk) {
-               struct sk_security_struct *sksec = skb->sk->sk_security;
+       sk = skb->sk;
+       if (sk) {
+               struct sk_security_struct *sksec;
+
+               if (sk->sk_state == TCP_LISTEN)
+                       /* if the socket is the listening state then this
+                        * packet is a SYN-ACK packet which means it needs to
+                        * be labeled based on the connection/request_sock and
+                        * not the parent socket.  unfortunately, we can't
+                        * lookup the request_sock yet as it isn't queued on
+                        * the parent socket until after the SYN-ACK is sent.
+                        * the "solution" is to simply pass the packet as-is
+                        * as any IP option based labeling should be copied
+                        * from the initial connection request (in the IP
+                        * layer).  it is far from ideal, but until we get a
+                        * security label in the packet itself this is the
+                        * best we can do. */
+                       return NF_ACCEPT;
+
+               /* standard practice, label using the parent socket */
+               sksec = sk->sk_security;
                sid = sksec->sid;
        } else
                sid = SECINITSID_KERNEL;
@@ -4810,27 +4846,36 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex,
         * as fast and as clean as possible. */
        if (!selinux_policycap_netpeer)
                return selinux_ip_postroute_compat(skb, ifindex, family);
+
+       secmark_active = selinux_secmark_enabled();
+       peerlbl_active = selinux_peerlbl_enabled();
+       if (!secmark_active && !peerlbl_active)
+               return NF_ACCEPT;
+
+       sk = skb->sk;
+
 #ifdef CONFIG_XFRM
        /* If skb->dst->xfrm is non-NULL then the packet is undergoing an IPsec
         * packet transformation so allow the packet to pass without any checks
         * since we'll have another chance to perform access control checks
         * when the packet is on it's final way out.
         * NOTE: there appear to be some IPv6 multicast cases where skb->dst
-        *       is NULL, in this case go ahead and apply access control. */
-       if (skb_dst(skb) != NULL && skb_dst(skb)->xfrm != NULL)
+        *       is NULL, in this case go ahead and apply access control.
+        * NOTE: if this is a local socket (skb->sk != NULL) that is in the
+        *       TCP listening state we cannot wait until the XFRM processing
+        *       is done as we will miss out on the SA label if we do;
+        *       unfortunately, this means more work, but it is only once per
+        *       connection. */
+       if (skb_dst(skb) != NULL && skb_dst(skb)->xfrm != NULL &&
+           !(sk != NULL && sk->sk_state == TCP_LISTEN))
                return NF_ACCEPT;
 #endif
-       secmark_active = selinux_secmark_enabled();
-       peerlbl_active = selinux_peerlbl_enabled();
-       if (!secmark_active && !peerlbl_active)
-               return NF_ACCEPT;
 
-       /* if the packet is being forwarded then get the peer label from the
-        * packet itself; otherwise check to see if it is from a local
-        * application or the kernel, if from an application get the peer label
-        * from the sending socket, otherwise use the kernel's sid */
-       sk = skb->sk;
        if (sk == NULL) {
+               /* Without an associated socket the packet is either coming
+                * from the kernel or it is being forwarded; check the packet
+                * to determine which and if the packet is being forwarded
+                * query the packet directly to determine the security label. */
                if (skb->skb_iif) {
                        secmark_perm = PACKET__FORWARD_OUT;
                        if (selinux_skb_peerlbl_sid(skb, family, &peer_sid))
@@ -4839,7 +4884,45 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex,
                        secmark_perm = PACKET__SEND;
                        peer_sid = SECINITSID_KERNEL;
                }
+       } else if (sk->sk_state == TCP_LISTEN) {
+               /* Locally generated packet but the associated socket is in the
+                * listening state which means this is a SYN-ACK packet.  In
+                * this particular case the correct security label is assigned
+                * to the connection/request_sock but unfortunately we can't
+                * query the request_sock as it isn't queued on the parent
+                * socket until after the SYN-ACK packet is sent; the only
+                * viable choice is to regenerate the label like we do in
+                * selinux_inet_conn_request().  See also selinux_ip_output()
+                * for similar problems. */
+               u32 skb_sid;
+               struct sk_security_struct *sksec = sk->sk_security;
+               if (selinux_skb_peerlbl_sid(skb, family, &skb_sid))
+                       return NF_DROP;
+               /* At this point, if the returned skb peerlbl is SECSID_NULL
+                * and the packet has been through at least one XFRM
+                * transformation then we must be dealing with the "final"
+                * form of labeled IPsec packet; since we've already applied
+                * all of our access controls on this packet we can safely
+                * pass the packet. */
+               if (skb_sid == SECSID_NULL) {
+                       switch (family) {
+                       case PF_INET:
+                               if (IPCB(skb)->flags & IPSKB_XFRM_TRANSFORMED)
+                                       return NF_ACCEPT;
+                               break;
+                       case PF_INET6:
+                               if (IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED)
+                                       return NF_ACCEPT;
+                       default:
+                               return NF_DROP_ERR(-ECONNREFUSED);
+                       }
+               }
+               if (selinux_conn_sid(sksec->sid, skb_sid, &peer_sid))
+                       return NF_DROP;
+               secmark_perm = PACKET__SEND;
        } else {
+               /* Locally generated packet, fetch the security label from the
+                * associated socket. */
                struct sk_security_struct *sksec = sk->sk_security;
                peer_sid = sksec->sid;
                secmark_perm = PACKET__SEND;
index 0dec76c64cf53853d0eea6aac983db307c8636b8..48c3cc94c1681718a78e6793c7e961e2d404f3fb 100644 (file)
@@ -39,6 +39,7 @@ int selinux_xfrm_sock_rcv_skb(u32 sk_sid, struct sk_buff *skb,
 int selinux_xfrm_postroute_last(u32 sk_sid, struct sk_buff *skb,
                                struct common_audit_data *ad, u8 proto);
 int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int ckall);
+int selinux_xfrm_skb_sid(struct sk_buff *skb, u32 *sid);
 
 static inline void selinux_xfrm_notify_policyload(void)
 {
@@ -79,11 +80,12 @@ static inline int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid,
 static inline void selinux_xfrm_notify_policyload(void)
 {
 }
-#endif
 
-static inline int selinux_skb_xfrm_sid(struct sk_buff *skb, u32 *sid)
+static inline int selinux_xfrm_skb_sid(struct sk_buff *skb, u32 *sid)
 {
-       return selinux_xfrm_decode_session(skb, sid, 0);
+       *sid = SECSID_NULL;
+       return 0;
 }
+#endif
 
 #endif /* _SELINUX_XFRM_H_ */
index ee470a0b5c27fdad95a59b258792b6182435b999..d106733ad9878d6ee7543ff31c05a51f2c74b523 100644 (file)
@@ -2334,50 +2334,16 @@ int security_fs_use(struct super_block *sb)
        struct ocontext *c;
        struct superblock_security_struct *sbsec = sb->s_security;
        const char *fstype = sb->s_type->name;
-       const char *subtype = (sb->s_subtype && sb->s_subtype[0]) ? sb->s_subtype : NULL;
-       struct ocontext *base = NULL;
 
        read_lock(&policy_rwlock);
 
-       for (c = policydb.ocontexts[OCON_FSUSE]; c; c = c->next) {
-               char *sub;
-               int baselen;
-
-               baselen = strlen(fstype);
-
-               /* if base does not match, this is not the one */
-               if (strncmp(fstype, c->u.name, baselen))
-                       continue;
-
-               /* if there is no subtype, this is the one! */
-               if (!subtype)
-                       break;
-
-               /* skip past the base in this entry */
-               sub = c->u.name + baselen;
-
-               /* entry is only a base. save it. keep looking for subtype */
-               if (sub[0] == '\0') {
-                       base = c;
-                       continue;
-               }
-
-               /* entry is not followed by a subtype, so it is not a match */
-               if (sub[0] != '.')
-                       continue;
-
-               /* whew, we found a subtype of this fstype */
-               sub++; /* move past '.' */
-
-               /* exact match of fstype AND subtype */
-               if (!strcmp(subtype, sub))
+       c = policydb.ocontexts[OCON_FSUSE];
+       while (c) {
+               if (strcmp(fstype, c->u.name) == 0)
                        break;
+               c = c->next;
        }
 
-       /* in case we had found an fstype match but no subtype match */
-       if (!c)
-               c = base;
-
        if (c) {
                sbsec->behavior = c->v.behavior;
                if (!c->sid[0]) {
index a91d205ec0c6094cc9a0fecb5d427d4d24b1ed9a..0462cb3ff0a741a36b279dcef37ee784e8520c5c 100644 (file)
@@ -209,19 +209,26 @@ int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x,
                            NULL) ? 0 : 1);
 }
 
-/*
- * LSM hook implementation that checks and/or returns the xfrm sid for the
- * incoming packet.
- */
-int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int ckall)
+static u32 selinux_xfrm_skb_sid_egress(struct sk_buff *skb)
 {
-       u32 sid_session = SECSID_NULL;
-       struct sec_path *sp;
+       struct dst_entry *dst = skb_dst(skb);
+       struct xfrm_state *x;
 
-       if (skb == NULL)
-               goto out;
+       if (dst == NULL)
+               return SECSID_NULL;
+       x = dst->xfrm;
+       if (x == NULL || !selinux_authorizable_xfrm(x))
+               return SECSID_NULL;
+
+       return x->security->ctx_sid;
+}
+
+static int selinux_xfrm_skb_sid_ingress(struct sk_buff *skb,
+                                       u32 *sid, int ckall)
+{
+       u32 sid_session = SECSID_NULL;
+       struct sec_path *sp = skb->sp;
 
-       sp = skb->sp;
        if (sp) {
                int i;
 
@@ -247,6 +254,30 @@ out:
        return 0;
 }
 
+/*
+ * LSM hook implementation that checks and/or returns the xfrm sid for the
+ * incoming packet.
+ */
+int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int ckall)
+{
+       if (skb == NULL) {
+               *sid = SECSID_NULL;
+               return 0;
+       }
+       return selinux_xfrm_skb_sid_ingress(skb, sid, ckall);
+}
+
+int selinux_xfrm_skb_sid(struct sk_buff *skb, u32 *sid)
+{
+       int rc;
+
+       rc = selinux_xfrm_skb_sid_ingress(skb, sid, 0);
+       if (rc == 0 && *sid == SECSID_NULL)
+               *sid = selinux_xfrm_skb_sid_egress(skb);
+
+       return rc;
+}
+
 /*
  * LSM hook implementation that allocs and transfers uctx spec to xfrm_policy.
  */
@@ -327,19 +358,22 @@ int selinux_xfrm_state_alloc_acquire(struct xfrm_state *x,
                return rc;
 
        ctx = kmalloc(sizeof(*ctx) + str_len, GFP_ATOMIC);
-       if (!ctx)
-               return -ENOMEM;
+       if (!ctx) {
+               rc = -ENOMEM;
+               goto out;
+       }
 
        ctx->ctx_doi = XFRM_SC_DOI_LSM;
        ctx->ctx_alg = XFRM_SC_ALG_SELINUX;
        ctx->ctx_sid = secid;
        ctx->ctx_len = str_len;
        memcpy(ctx->ctx_str, ctx_str, str_len);
-       kfree(ctx_str);
 
        x->security = ctx;
        atomic_inc(&selinux_xfrm_refcount);
-       return 0;
+out:
+       kfree(ctx_str);
+       return rc;
 }
 
 /*
index 6e03b465e44e3a05f82e93a2d25a61f030cc3cf6..a2104671f51d38df6eec99b3e0aa8ac570ea8988 100644 (file)
@@ -1937,6 +1937,8 @@ static int wait_for_avail(struct snd_pcm_substream *substream,
                case SNDRV_PCM_STATE_DISCONNECTED:
                        err = -EBADFD;
                        goto _endloop;
+               case SNDRV_PCM_STATE_PAUSED:
+                       continue;
                }
                if (!tout) {
                        snd_printd("%s write error (DMA or IRQ trouble?)\n",
index c4671d00babd6772193f955237c48412a3239a5a..c7f6d1cab6063a6483802ee6c80391c18c2de884 100644 (file)
@@ -474,6 +474,20 @@ static void invalidate_nid_path(struct hda_codec *codec, int idx)
        memset(path, 0, sizeof(*path));
 }
 
+/* return a DAC if paired to the given pin by codec driver */
+static hda_nid_t get_preferred_dac(struct hda_codec *codec, hda_nid_t pin)
+{
+       struct hda_gen_spec *spec = codec->spec;
+       const hda_nid_t *list = spec->preferred_dacs;
+
+       if (!list)
+               return 0;
+       for (; *list; list += 2)
+               if (*list == pin)
+                       return list[1];
+       return 0;
+}
+
 /* look for an empty DAC slot */
 static hda_nid_t look_for_dac(struct hda_codec *codec, hda_nid_t pin,
                              bool is_digital)
@@ -1192,7 +1206,14 @@ static int try_assign_dacs(struct hda_codec *codec, int num_outs,
                        continue;
                }
 
-               dacs[i] = look_for_dac(codec, pin, false);
+               dacs[i] = get_preferred_dac(codec, pin);
+               if (dacs[i]) {
+                       if (is_dac_already_used(codec, dacs[i]))
+                               badness += bad->shared_primary;
+               }
+
+               if (!dacs[i])
+                       dacs[i] = look_for_dac(codec, pin, false);
                if (!dacs[i] && !i) {
                        /* try to steal the DAC of surrounds for the front */
                        for (j = 1; j < num_outs; j++) {
@@ -4297,6 +4318,26 @@ static unsigned int snd_hda_gen_path_power_filter(struct hda_codec *codec,
        return AC_PWRST_D3;
 }
 
+/* mute all aamix inputs initially; parse up to the first leaves */
+static void mute_all_mixer_nid(struct hda_codec *codec, hda_nid_t mix)
+{
+       int i, nums;
+       const hda_nid_t *conn;
+       bool has_amp;
+
+       nums = snd_hda_get_conn_list(codec, mix, &conn);
+       has_amp = nid_has_mute(codec, mix, HDA_INPUT);
+       for (i = 0; i < nums; i++) {
+               if (has_amp)
+                       snd_hda_codec_amp_stereo(codec, mix,
+                                                HDA_INPUT, i,
+                                                0xff, HDA_AMP_MUTE);
+               else if (nid_has_volume(codec, conn[i], HDA_OUTPUT))
+                       snd_hda_codec_amp_stereo(codec, conn[i],
+                                                HDA_OUTPUT, 0,
+                                                0xff, HDA_AMP_MUTE);
+       }
+}
 
 /*
  * Parse the given BIOS configuration and set up the hda_gen_spec
@@ -4435,6 +4476,10 @@ int snd_hda_gen_parse_auto_config(struct hda_codec *codec,
                }
        }
 
+       /* mute all aamix input initially */
+       if (spec->mixer_nid)
+               mute_all_mixer_nid(codec, spec->mixer_nid);
+
  dig_only:
        parse_digital(codec);
 
index 7e45cb44d1514497385f2f6bc2b63251391cdaba..0929a06df8128495f5e717768fcfa28eaed7360d 100644 (file)
@@ -249,6 +249,9 @@ struct hda_gen_spec {
        const struct badness_table *main_out_badness;
        const struct badness_table *extra_out_badness;
 
+       /* preferred pin/DAC pairs; an array of paired NIDs */
+       const hda_nid_t *preferred_dacs;
+
        /* loopback mixing mode */
        bool aamix_mode;
 
index 27aa14007cbd400ebcb1f21e5e4036d58e778430..956871d8b3d26a9255723eb4bdfdf963c50f031b 100644 (file)
@@ -3433,6 +3433,10 @@ static void check_probe_mask(struct azx *chip, int dev)
  * white/black-list for enable_msi
  */
 static struct snd_pci_quirk msi_black_list[] = {
+       SND_PCI_QUIRK(0x103c, 0x2191, "HP", 0), /* AMD Hudson */
+       SND_PCI_QUIRK(0x103c, 0x2192, "HP", 0), /* AMD Hudson */
+       SND_PCI_QUIRK(0x103c, 0x21f7, "HP", 0), /* AMD Hudson */
+       SND_PCI_QUIRK(0x103c, 0x21fa, "HP", 0), /* AMD Hudson */
        SND_PCI_QUIRK(0x1043, 0x81f2, "ASUS", 0), /* Athlon64 X2 + nvidia */
        SND_PCI_QUIRK(0x1043, 0x81f6, "ASUS", 0), /* nvidia */
        SND_PCI_QUIRK(0x1043, 0x822d, "ASUS", 0), /* Athlon64 X2 + nvidia MCP55 */
index cac015be3325d9760366434c6e727c472a21dbf5..699262a3e07abcd9558bb538de0916d96bc63bcd 100644 (file)
@@ -340,6 +340,14 @@ static int patch_ad1986a(struct hda_codec *codec)
 {
        int err;
        struct ad198x_spec *spec;
+       static hda_nid_t preferred_pairs[] = {
+               0x1a, 0x03,
+               0x1b, 0x03,
+               0x1c, 0x04,
+               0x1d, 0x05,
+               0x1e, 0x03,
+               0
+       };
 
        err = alloc_ad_spec(codec);
        if (err < 0)
@@ -360,6 +368,8 @@ static int patch_ad1986a(struct hda_codec *codec)
         * So, let's disable the shared stream.
         */
        spec->gen.multiout.no_share_stream = 1;
+       /* give fixed DAC/pin pairs */
+       spec->gen.preferred_dacs = preferred_pairs;
 
        /* AD1986A can't manage the dynamic pin on/off smoothly */
        spec->gen.auto_mute_via_amp = 1;
index 1f2717f817a0142f4ef17910ffd50dafe42e4c09..3fbf2883e06e855e7a79213b0414e3049b539f28 100644 (file)
@@ -2936,7 +2936,6 @@ static const struct snd_pci_quirk cxt5066_cfg_tbl[] = {
        SND_PCI_QUIRK(0x1028, 0x0401, "Dell Vostro 1014", CXT5066_DELL_VOSTRO),
        SND_PCI_QUIRK(0x1028, 0x0408, "Dell Inspiron One 19T", CXT5066_IDEAPAD),
        SND_PCI_QUIRK(0x1028, 0x050f, "Dell Inspiron", CXT5066_IDEAPAD),
-       SND_PCI_QUIRK(0x1028, 0x0510, "Dell Vostro", CXT5066_IDEAPAD),
        SND_PCI_QUIRK(0x103c, 0x360b, "HP G60", CXT5066_HP_LAPTOP),
        SND_PCI_QUIRK(0x1043, 0x13f3, "Asus A52J", CXT5066_ASUS),
        SND_PCI_QUIRK(0x1043, 0x1643, "Asus K52JU", CXT5066_ASUS),
index c4a66ef6cf6f02e25134ab3f9b8ae1dfef6224ee..f281c8068557e63b72370e25a9973372dbaf0bae 100644 (file)
@@ -2337,8 +2337,9 @@ static int simple_playback_build_controls(struct hda_codec *codec)
        int err;
 
        per_cvt = get_cvt(spec, 0);
-       err = snd_hda_create_spdif_out_ctls(codec, per_cvt->cvt_nid,
-                                           per_cvt->cvt_nid);
+       err = snd_hda_create_dig_out_ctls(codec, per_cvt->cvt_nid,
+                                         per_cvt->cvt_nid,
+                                         HDA_PCM_TYPE_HDMI);
        if (err < 0)
                return err;
        return simple_hdmi_build_jack(codec, 0);
index c5ea483d755981cdbe6c24c24ba0c98478e4c709..c5646941539a87df9505eece6241dd5e9230c4ff 100644 (file)
@@ -3849,6 +3849,7 @@ enum {
        ALC269_FIXUP_ASUS_X101,
        ALC271_FIXUP_AMIC_MIC2,
        ALC271_FIXUP_HP_GATE_MIC_JACK,
+       ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572,
        ALC269_FIXUP_ACER_AC700,
        ALC269_FIXUP_LIMIT_INT_MIC_BOOST,
        ALC269VB_FIXUP_ASUS_ZENBOOK,
@@ -4111,6 +4112,12 @@ static const struct hda_fixup alc269_fixups[] = {
                .chained = true,
                .chain_id = ALC271_FIXUP_AMIC_MIC2,
        },
+       [ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572] = {
+               .type = HDA_FIXUP_FUNC,
+               .v.func = alc269_fixup_limit_int_mic_boost,
+               .chained = true,
+               .chain_id = ALC271_FIXUP_HP_GATE_MIC_JACK,
+       },
        [ALC269_FIXUP_ACER_AC700] = {
                .type = HDA_FIXUP_PINS,
                .v.pins = (const struct hda_pintbl[]) {
@@ -4208,6 +4215,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1025, 0x0740, "Acer AO725", ALC271_FIXUP_HP_GATE_MIC_JACK),
        SND_PCI_QUIRK(0x1025, 0x0742, "Acer AO756", ALC271_FIXUP_HP_GATE_MIC_JACK),
        SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC),
+       SND_PCI_QUIRK(0x1025, 0x0775, "Acer Aspire E1-572", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572),
        SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
        SND_PCI_QUIRK(0x1028, 0x05bd, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1028, 0x05be, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
@@ -4239,12 +4247,16 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1028, 0x0606, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1028, 0x0608, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1028, 0x0609, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
+       SND_PCI_QUIRK(0x1028, 0x0610, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1028, 0x0613, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1028, 0x0614, "Dell Inspiron 3135", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1028, 0x0616, "Dell Vostro 5470", ALC290_FIXUP_MONO_SPEAKERS),
        SND_PCI_QUIRK(0x1028, 0x061f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
+       SND_PCI_QUIRK(0x1028, 0x0629, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1028, 0x0638, "Dell Inspiron 5439", ALC290_FIXUP_MONO_SPEAKERS),
+       SND_PCI_QUIRK(0x1028, 0x063e, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1028, 0x063f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
+       SND_PCI_QUIRK(0x1028, 0x0640, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1028, 0x15cc, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1028, 0x15cd, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2),
@@ -5034,8 +5046,11 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
        SND_PCI_QUIRK(0x1028, 0x05d8, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1028, 0x05db, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
+       SND_PCI_QUIRK(0x1028, 0x0623, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
+       SND_PCI_QUIRK(0x1028, 0x0624, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1028, 0x0625, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1028, 0x0626, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
+       SND_PCI_QUIRK(0x1028, 0x0628, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800),
        SND_PCI_QUIRK(0x1043, 0x11cd, "Asus N550", ALC662_FIXUP_BASS_1A_CHMAP),
        SND_PCI_QUIRK(0x1043, 0x1477, "ASUS N56VZ", ALC662_FIXUP_BASS_CHMAP),
index 8697cedccd21240f76b4b5076ba6d0968a394d75..1ead3c977a51743619b0bb2084ec174b7cf867a8 100644 (file)
@@ -648,7 +648,7 @@ static int atmel_ssc_prepare(struct snd_pcm_substream *substream,
 
        dma_params = ssc_p->dma_params[dir];
 
-       ssc_writel(ssc_p->ssc->regs, CR, dma_params->mask->ssc_enable);
+       ssc_writel(ssc_p->ssc->regs, CR, dma_params->mask->ssc_disable);
        ssc_writel(ssc_p->ssc->regs, IDR, dma_params->mask->ssc_error);
 
        pr_debug("%s enabled SSC_SR=0x%08x\n",
@@ -657,6 +657,33 @@ static int atmel_ssc_prepare(struct snd_pcm_substream *substream,
        return 0;
 }
 
+static int atmel_ssc_trigger(struct snd_pcm_substream *substream,
+                            int cmd, struct snd_soc_dai *dai)
+{
+       struct atmel_ssc_info *ssc_p = &ssc_info[dai->id];
+       struct atmel_pcm_dma_params *dma_params;
+       int dir;
+
+       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+               dir = 0;
+       else
+               dir = 1;
+
+       dma_params = ssc_p->dma_params[dir];
+
+       switch (cmd) {
+       case SNDRV_PCM_TRIGGER_START:
+       case SNDRV_PCM_TRIGGER_RESUME:
+       case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+               ssc_writel(ssc_p->ssc->regs, CR, dma_params->mask->ssc_enable);
+               break;
+       default:
+               ssc_writel(ssc_p->ssc->regs, CR, dma_params->mask->ssc_disable);
+               break;
+       }
+
+       return 0;
+}
 
 #ifdef CONFIG_PM
 static int atmel_ssc_suspend(struct snd_soc_dai *cpu_dai)
@@ -731,6 +758,7 @@ static const struct snd_soc_dai_ops atmel_ssc_dai_ops = {
        .startup        = atmel_ssc_startup,
        .shutdown       = atmel_ssc_shutdown,
        .prepare        = atmel_ssc_prepare,
+       .trigger        = atmel_ssc_trigger,
        .hw_params      = atmel_ssc_hw_params,
        .set_fmt        = atmel_ssc_set_dai_fmt,
        .set_clkdiv     = atmel_ssc_set_dai_clkdiv,
index 1b372283bd01a947c26dc4da302f9b077adfe74a..7d6a9055874b822bb440eab72a66dc5c034127ed 100644 (file)
@@ -109,7 +109,7 @@ static int sam9x5_wm8731_driver_probe(struct platform_device *pdev)
        dai->stream_name = "WM8731 PCM";
        dai->codec_dai_name = "wm8731-hifi";
        dai->init = sam9x5_wm8731_init;
-       dai->dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
+       dai->dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_NF
                | SND_SOC_DAIFMT_CBM_CFM;
 
        ret = snd_soc_of_parse_card_name(card, "atmel,model");
index 99b359e19d35f46a3c95946d976b294300c6ea70..0ab2dc296474373e1e407abf0762afeeffead4c6 100644 (file)
@@ -1012,7 +1012,7 @@ static const struct snd_soc_dapm_route wm5110_dapm_routes[] = {
        { "AEC Loopback", "HPOUT3L", "OUT3L" },
        { "AEC Loopback", "HPOUT3R", "OUT3R" },
        { "HPOUT3L", NULL, "OUT3L" },
-       { "HPOUT3R", NULL, "OUT3L" },
+       { "HPOUT3R", NULL, "OUT3R" },
 
        { "AEC Loopback", "SPKOUTL", "OUT4L" },
        { "SPKOUTLN", NULL, "OUT4L" },
index 3938fb1c203ed86b5452ff130071d349a6821a87..53bbfac6a83ad14ed43d2aafca2514ea3a319468 100644 (file)
@@ -1444,7 +1444,7 @@ static int wm8904_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 
        switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
        case SND_SOC_DAIFMT_DSP_B:
-               aif1 |= WM8904_AIF_LRCLK_INV;
+               aif1 |= 0x3 | WM8904_AIF_LRCLK_INV;
        case SND_SOC_DAIFMT_DSP_A:
                aif1 |= 0x3;
                break;
index 543c5c2631b61827bcebca8af1926ea02b5655e9..0f17ed3e29f41dc9d7ddebb505b7fad8fc545b02 100644 (file)
@@ -2439,7 +2439,20 @@ static void wm8962_configure_bclk(struct snd_soc_codec *codec)
        snd_soc_update_bits(codec, WM8962_CLOCKING_4,
                            WM8962_SYSCLK_RATE_MASK, clocking4);
 
+       /* DSPCLK_DIV can be only generated correctly after enabling SYSCLK.
+        * So we here provisionally enable it and then disable it afterward
+        * if current bias_level hasn't reached SND_SOC_BIAS_ON.
+        */
+       if (codec->dapm.bias_level != SND_SOC_BIAS_ON)
+               snd_soc_update_bits(codec, WM8962_CLOCKING2,
+                               WM8962_SYSCLK_ENA_MASK, WM8962_SYSCLK_ENA);
+
        dspclk = snd_soc_read(codec, WM8962_CLOCKING1);
+
+       if (codec->dapm.bias_level != SND_SOC_BIAS_ON)
+               snd_soc_update_bits(codec, WM8962_CLOCKING2,
+                               WM8962_SYSCLK_ENA_MASK, 0);
+
        if (dspclk < 0) {
                dev_err(codec->dev, "Failed to read DSPCLK: %d\n", dspclk);
                return;
index 46ec0e9744d4b88b50cc922cfdc65a0b4247e567..4fbcab63e61f1c5d8b4843fdec5c6d3dbfa498ed 100644 (file)
@@ -1474,13 +1474,17 @@ static int wm_adsp2_ena(struct wm_adsp *dsp)
                return ret;
 
        /* Wait for the RAM to start, should be near instantaneous */
-       count = 0;
-       do {
+       for (count = 0; count < 10; ++count) {
                ret = regmap_read(dsp->regmap, dsp->base + ADSP2_STATUS1,
                                  &val);
                if (ret != 0)
                        return ret;
-       } while (!(val & ADSP2_RAM_RDY) && ++count < 10);
+
+               if (val & ADSP2_RAM_RDY)
+                       break;
+
+               msleep(1);
+       }
 
        if (!(val & ADSP2_RAM_RDY)) {
                adsp_err(dsp, "Failed to start DSP RAM\n");
index 61e48852b9e8bd21b26eec98cca4fc9ba0eea145..3fd76bc391de19a2431dd320d0abfbdcd9616cf5 100644 (file)
@@ -130,8 +130,6 @@ static int imx_wm8962_set_bias_level(struct snd_soc_card *card,
                break;
        }
 
-       dapm->bias_level = level;
-
        return 0;
 }
 
index 0b18f654b41340908d022003485d8a88c5e0c94e..3920a5e8125f886e15caa6607fed9e84a32950cd 100644 (file)
@@ -473,17 +473,17 @@ static struct snd_soc_dai_driver kirkwood_i2s_dai_extclk[2] = {
        .playback = {
                .channels_min = 1,
                .channels_max = 2,
-               .rates = SNDRV_PCM_RATE_8000_192000 |
-                        SNDRV_PCM_RATE_CONTINUOUS |
-                        SNDRV_PCM_RATE_KNOT,
+               .rates = SNDRV_PCM_RATE_CONTINUOUS,
+               .rate_min = 5512,
+               .rate_max = 192000,
                .formats = KIRKWOOD_I2S_FORMATS,
        },
        .capture = {
                .channels_min = 1,
                .channels_max = 2,
-               .rates = SNDRV_PCM_RATE_8000_192000 |
-                        SNDRV_PCM_RATE_CONTINUOUS |
-                        SNDRV_PCM_RATE_KNOT,
+               .rates = SNDRV_PCM_RATE_CONTINUOUS,
+               .rate_min = 5512,
+               .rate_max = 192000,
                .formats = KIRKWOOD_I2S_FORMATS,
        },
        .ops = &kirkwood_i2s_dai_ops,
@@ -494,17 +494,17 @@ static struct snd_soc_dai_driver kirkwood_i2s_dai_extclk[2] = {
        .playback = {
                .channels_min = 1,
                .channels_max = 2,
-               .rates = SNDRV_PCM_RATE_8000_192000 |
-                        SNDRV_PCM_RATE_CONTINUOUS |
-                        SNDRV_PCM_RATE_KNOT,
+               .rates = SNDRV_PCM_RATE_CONTINUOUS,
+               .rate_min = 5512,
+               .rate_max = 192000,
                .formats = KIRKWOOD_SPDIF_FORMATS,
        },
        .capture = {
                .channels_min = 1,
                .channels_max = 2,
-               .rates = SNDRV_PCM_RATE_8000_192000 |
-                        SNDRV_PCM_RATE_CONTINUOUS |
-                        SNDRV_PCM_RATE_KNOT,
+               .rates = SNDRV_PCM_RATE_CONTINUOUS,
+               .rate_min = 5512,
+               .rate_max = 192000,
                .formats = KIRKWOOD_SPDIF_FORMATS,
        },
        .ops = &kirkwood_i2s_dai_ops,
index cbc9c96ce1f412123a1704b171220a2990ad503d..41949af3baaed2580dae2df585222339ade75208 100644 (file)
@@ -305,6 +305,20 @@ static void dmaengine_pcm_request_chan_of(struct dmaengine_pcm *pcm,
        }
 }
 
+static void dmaengine_pcm_release_chan(struct dmaengine_pcm *pcm)
+{
+       unsigned int i;
+
+       for (i = SNDRV_PCM_STREAM_PLAYBACK; i <= SNDRV_PCM_STREAM_CAPTURE;
+            i++) {
+               if (!pcm->chan[i])
+                       continue;
+               dma_release_channel(pcm->chan[i]);
+               if (pcm->flags & SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX)
+                       break;
+       }
+}
+
 /**
  * snd_dmaengine_pcm_register - Register a dmaengine based PCM device
  * @dev: The parent device for the PCM device
@@ -315,6 +329,7 @@ int snd_dmaengine_pcm_register(struct device *dev,
        const struct snd_dmaengine_pcm_config *config, unsigned int flags)
 {
        struct dmaengine_pcm *pcm;
+       int ret;
 
        pcm = kzalloc(sizeof(*pcm), GFP_KERNEL);
        if (!pcm)
@@ -326,11 +341,20 @@ int snd_dmaengine_pcm_register(struct device *dev,
        dmaengine_pcm_request_chan_of(pcm, dev);
 
        if (flags & SND_DMAENGINE_PCM_FLAG_NO_RESIDUE)
-               return snd_soc_add_platform(dev, &pcm->platform,
+               ret = snd_soc_add_platform(dev, &pcm->platform,
                                &dmaengine_no_residue_pcm_platform);
        else
-               return snd_soc_add_platform(dev, &pcm->platform,
+               ret = snd_soc_add_platform(dev, &pcm->platform,
                                &dmaengine_pcm_platform);
+       if (ret)
+               goto err_free_dma;
+
+       return 0;
+
+err_free_dma:
+       dmaengine_pcm_release_chan(pcm);
+       kfree(pcm);
+       return ret;
 }
 EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_register);
 
@@ -345,7 +369,6 @@ void snd_dmaengine_pcm_unregister(struct device *dev)
 {
        struct snd_soc_platform *platform;
        struct dmaengine_pcm *pcm;
-       unsigned int i;
 
        platform = snd_soc_lookup_platform(dev);
        if (!platform)
@@ -353,15 +376,8 @@ void snd_dmaengine_pcm_unregister(struct device *dev)
 
        pcm = soc_platform_to_pcm(platform);
 
-       for (i = SNDRV_PCM_STREAM_PLAYBACK; i <= SNDRV_PCM_STREAM_CAPTURE; i++) {
-               if (pcm->chan[i]) {
-                       dma_release_channel(pcm->chan[i]);
-                       if (pcm->flags & SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX)
-                               break;
-               }
-       }
-
        snd_soc_remove_platform(platform);
+       dmaengine_pcm_release_chan(pcm);
        kfree(pcm);
 }
 EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_unregister);
index 11a90cd027faca2956172f3dfa92f6d2ee46a8fe..891b9a9bcbf885df92bad9007b3f23054ce68c18 100644 (file)
@@ -600,12 +600,13 @@ static int soc_pcm_hw_free(struct snd_pcm_substream *substream)
        struct snd_soc_platform *platform = rtd->platform;
        struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
        struct snd_soc_dai *codec_dai = rtd->codec_dai;
-       struct snd_soc_codec *codec = rtd->codec;
+       bool playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
 
        mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
 
        /* apply codec digital mute */
-       if (!codec->active)
+       if ((playback && codec_dai->playback_active == 1) ||
+           (!playback && codec_dai->capture_active == 1))
                snd_soc_dai_digital_mute(codec_dai, 1, substream->stream);
 
        /* free any machine hw params */
index 364bf6a907e1c39a36df89ded1d6b2681172940f..8c819f8114708f7a94e33929a04ebecbdf3e2ffc 100644 (file)
@@ -74,7 +74,7 @@ static int tegra20_i2s_set_fmt(struct snd_soc_dai *dai,
                                unsigned int fmt)
 {
        struct tegra20_i2s *i2s = snd_soc_dai_get_drvdata(dai);
-       unsigned int mask, val;
+       unsigned int mask = 0, val = 0;
 
        switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
        case SND_SOC_DAIFMT_NB_NF:
@@ -83,10 +83,10 @@ static int tegra20_i2s_set_fmt(struct snd_soc_dai *dai,
                return -EINVAL;
        }
 
-       mask = TEGRA20_I2S_CTRL_MASTER_ENABLE;
+       mask |= TEGRA20_I2S_CTRL_MASTER_ENABLE;
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
        case SND_SOC_DAIFMT_CBS_CFS:
-               val = TEGRA20_I2S_CTRL_MASTER_ENABLE;
+               val |= TEGRA20_I2S_CTRL_MASTER_ENABLE;
                break;
        case SND_SOC_DAIFMT_CBM_CFM:
                break;
index 08bc6931c7c7fc0477703037098a8e7185d7c69d..8c7c1028e5797dbc9b23ec88b58a4cd840db1c5c 100644 (file)
@@ -67,15 +67,15 @@ static int tegra20_spdif_hw_params(struct snd_pcm_substream *substream,
 {
        struct device *dev = dai->dev;
        struct tegra20_spdif *spdif = snd_soc_dai_get_drvdata(dai);
-       unsigned int mask, val;
+       unsigned int mask = 0, val = 0;
        int ret, spdifclock;
 
-       mask = TEGRA20_SPDIF_CTRL_PACK |
-              TEGRA20_SPDIF_CTRL_BIT_MODE_MASK;
+       mask |= TEGRA20_SPDIF_CTRL_PACK |
+               TEGRA20_SPDIF_CTRL_BIT_MODE_MASK;
        switch (params_format(params)) {
        case SNDRV_PCM_FORMAT_S16_LE:
-               val = TEGRA20_SPDIF_CTRL_PACK |
-                     TEGRA20_SPDIF_CTRL_BIT_MODE_16BIT;
+               val |= TEGRA20_SPDIF_CTRL_PACK |
+                      TEGRA20_SPDIF_CTRL_BIT_MODE_16BIT;
                break;
        default:
                return -EINVAL;
index 231a785b3921a5bd95d87914a92e7f5f2d266a63..02247fee1cf7e1450fb4bbcdf2e58cf5ee76c7e8 100644 (file)
@@ -118,7 +118,7 @@ static int tegra30_i2s_set_fmt(struct snd_soc_dai *dai,
                                unsigned int fmt)
 {
        struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai);
-       unsigned int mask, val;
+       unsigned int mask = 0, val = 0;
 
        switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
        case SND_SOC_DAIFMT_NB_NF:
@@ -127,10 +127,10 @@ static int tegra30_i2s_set_fmt(struct snd_soc_dai *dai,
                return -EINVAL;
        }
 
-       mask = TEGRA30_I2S_CTRL_MASTER_ENABLE;
+       mask |= TEGRA30_I2S_CTRL_MASTER_ENABLE;
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
        case SND_SOC_DAIFMT_CBS_CFS:
-               val = TEGRA30_I2S_CTRL_MASTER_ENABLE;
+               val |= TEGRA30_I2S_CTRL_MASTER_ENABLE;
                break;
        case SND_SOC_DAIFMT_CBM_CFM:
                break;
index 3454262358b398913779954846ab12c11e7c5973..f4b12c216f1cd55c2db4396746a5abc9f20ed302 100644 (file)
@@ -1603,7 +1603,7 @@ static int snd_microii_controls_create(struct usb_mixer_interface *mixer)
                        return err;
        }
 
-       return err;
+       return 0;
 }
 
 int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer)
index dc4de37621117f7dc6fe8d47669e761063c9eed0..bcf1d2f0b791337169ee54ffce946619006015ae 100644 (file)
@@ -18,9 +18,9 @@
 #include "helpers/bitmask.h"
 
 static struct option set_opts[] = {
-       { .name = "perf-bias",  .has_arg = optional_argument,   .flag = NULL,   .val = 'b'},
-       { .name = "sched-mc",   .has_arg = optional_argument,   .flag = NULL,   .val = 'm'},
-       { .name = "sched-smt",  .has_arg = optional_argument,   .flag = NULL,   .val = 's'},
+       { .name = "perf-bias",  .has_arg = required_argument,   .flag = NULL,   .val = 'b'},
+       { .name = "sched-mc",   .has_arg = required_argument,   .flag = NULL,   .val = 'm'},
+       { .name = "sched-smt",  .has_arg = required_argument,   .flag = NULL,   .val = 's'},
        { },
 };
 
index a0aa84b5941ac96aabae48b03d80278052ce8929..4f588bc941861b10f7d5dccf9305941c8d3cc218 100644 (file)
@@ -1898,6 +1898,9 @@ static int kvm_vm_ioctl_create_vcpu(struct kvm *kvm, u32 id)
        int r;
        struct kvm_vcpu *vcpu, *v;
 
+       if (id >= KVM_MAX_VCPUS)
+               return -EINVAL;
+
        vcpu = kvm_arch_vcpu_create(kvm, id);
        if (IS_ERR(vcpu))
                return PTR_ERR(vcpu);