Merge branch 'for-rmk/hugepages' of git://git.linaro.org/people/stevecapper/linux...
authorRussell King <rmk+kernel@arm.linux.org.uk>
Tue, 18 Jun 2013 19:03:30 +0000 (20:03 +0100)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Tue, 18 Jun 2013 19:05:48 +0000 (20:05 +0100)
These changes bring both HugeTLB support and Transparent HugePage
(THP) support to ARM.  Only long descriptors (LPAE) are supported
in this series.

The code has been tested on an Arndale board (Exynos 5250).

491 files changed:
Documentation/devicetree/bindings/net/macb.txt
Documentation/devicetree/bindings/video/simple-framebuffer.txt [new file with mode: 0644]
Documentation/rapidio/rapidio.txt
Documentation/rapidio/sysfs.txt
MAINTAINERS
Makefile
arch/arc/boot/dts/abilis_tb100_dvk.dts
arch/arc/boot/dts/abilis_tb101_dvk.dts
arch/arc/boot/dts/abilis_tb10x.dtsi
arch/arc/include/asm/cacheflush.h
arch/arc/include/asm/page.h
arch/arc/include/asm/pgtable.h
arch/arc/include/asm/tlb.h
arch/arc/mm/cache_arc700.c
arch/arc/mm/tlb.c
arch/arc/mm/tlbex.S
arch/arc/plat-tb10x/tb10x.c
arch/arm/Kconfig
arch/arm/boot/dts/Makefile
arch/arm/boot/dts/armada-370-xp.dtsi
arch/arm/boot/dts/armada-370.dtsi
arch/arm/boot/dts/armada-xp-gp.dts
arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts
arch/arm/boot/dts/armada-xp.dtsi
arch/arm/boot/dts/at91sam9260.dtsi
arch/arm/boot/dts/at91sam9n12.dtsi
arch/arm/boot/dts/at91sam9x25ek.dts
arch/arm/boot/dts/omap3.dtsi
arch/arm/boot/dts/sama5d3.dtsi
arch/arm/boot/dts/sama5d3xcm.dtsi
arch/arm/boot/dts/ste-nomadik-s8815.dts
arch/arm/boot/dts/sun4i-a10-mini-xplus.dts
arch/arm/configs/omap1_defconfig
arch/arm/configs/omap2plus_defconfig
arch/arm/configs/tegra_defconfig
arch/arm/crypto/sha1-armv4-large.S
arch/arm/include/asm/hugetlb-3level.h [new file with mode: 0644]
arch/arm/include/asm/hugetlb.h [new file with mode: 0644]
arch/arm/include/asm/pgtable-3level-hwdef.h
arch/arm/include/asm/pgtable-3level.h
arch/arm/include/asm/pgtable.h
arch/arm/include/asm/tlb.h
arch/arm/include/asm/tlbflush.h
arch/arm/include/debug/ux500.S
arch/arm/kernel/process.c
arch/arm/mach-at91/at91rm9200_time.c
arch/arm/mach-at91/at91sam9n12.c
arch/arm/mach-at91/include/mach/at91_pmc.h
arch/arm/mach-imx/clk-imx6q.c
arch/arm/mach-imx/headsmp.S
arch/arm/mach-imx/platsmp.c
arch/arm/mach-kirkwood/common.c
arch/arm/mach-kirkwood/ts219-setup.c
arch/arm/mach-mvebu/Kconfig
arch/arm/mach-mvebu/armada-370-xp.c
arch/arm/mach-omap1/dma.c
arch/arm/mach-omap2/cclock33xx_data.c
arch/arm/mach-omap2/omap_hwmod.c
arch/arm/mach-omap2/omap_hwmod.h
arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c
arch/arm/mach-omap2/omap_hwmod_33xx_data.c
arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
arch/arm/mach-omap2/omap_hwmod_44xx_data.c
arch/arm/mach-omap2/serial.c
arch/arm/mach-orion5x/common.c
arch/arm/mach-shmobile/board-marzen.c
arch/arm/mach-sunxi/Kconfig
arch/arm/mach-ux500/Kconfig
arch/arm/mach-ux500/board-mop500.c
arch/arm/mach-ux500/cpu-db8500.c
arch/arm/mach-ux500/setup.h
arch/arm/mach-vt8500/vt8500.c
arch/arm/mm/Makefile
arch/arm/mm/dma-mapping.c
arch/arm/mm/flush.c
arch/arm/mm/fsr-3level.c
arch/arm/mm/hugetlbpage.c [new file with mode: 0644]
arch/arm/plat-orion/common.c
arch/arm/plat-orion/include/plat/common.h
arch/arm/vfp/entry.S
arch/avr32/Kconfig
arch/avr32/include/asm/Kbuild
arch/avr32/include/asm/numnodes.h [deleted file]
arch/avr32/include/asm/param.h [deleted file]
arch/avr32/include/uapi/asm/Kbuild
arch/avr32/include/uapi/asm/param.h [deleted file]
arch/avr32/kernel/module.c
arch/mips/alchemy/board-gpr.c
arch/mips/alchemy/common/time.c
arch/mips/ath79/setup.c
arch/mips/cobalt/reset.c
arch/mips/configs/db1000_defconfig
arch/mips/configs/db1235_defconfig
arch/mips/configs/lemote2f_defconfig
arch/mips/include/asm/clock.h
arch/mips/include/asm/idle.h [new file with mode: 0644]
arch/mips/include/asm/kvm.h [deleted file]
arch/mips/include/asm/page.h
arch/mips/include/asm/processor.h
arch/mips/include/uapi/asm/kvm.h [new file with mode: 0644]
arch/mips/include/uapi/asm/unistd.h
arch/mips/kernel/Makefile
arch/mips/kernel/cpu-probe.c
arch/mips/kernel/genex.S
arch/mips/kernel/idle.c [new file with mode: 0644]
arch/mips/kernel/kprobes.c
arch/mips/kernel/proc.c
arch/mips/kernel/process.c
arch/mips/kernel/scall64-64.S
arch/mips/kernel/smp.c
arch/mips/kernel/smtc.c
arch/mips/kernel/traps.c
arch/mips/kvm/kvm_tlb.c
arch/mips/loongson/common/reset.c
arch/mips/loongson1/common/reset.c
arch/mips/netlogic/xlp/setup.c
arch/mips/netlogic/xlr/setup.c
arch/mips/pmcs-msp71xx/msp_setup.c
arch/mips/txx9/generic/setup.c
arch/mips/vr41xx/common/pmu.c
arch/mips/wrppmc/reset.c
arch/parisc/include/asm/assembly.h
arch/parisc/include/asm/hardirq.h
arch/parisc/include/asm/processor.h
arch/parisc/kernel/entry.S
arch/parisc/kernel/hardware.c
arch/parisc/kernel/irq.c
arch/parisc/kernel/pacache.S
arch/parisc/kernel/traps.c
arch/parisc/kernel/unaligned.c
arch/powerpc/configs/ps3_defconfig
arch/powerpc/include/asm/pci-bridge.h
arch/powerpc/include/asm/processor.h
arch/powerpc/kernel/asm-offsets.c
arch/powerpc/kernel/cpu_setup_power.S
arch/powerpc/kernel/entry_64.S
arch/powerpc/kernel/pci-common.c
arch/powerpc/kernel/pci_64.c
arch/powerpc/kernel/pci_dn.c
arch/powerpc/platforms/powernv/Kconfig
arch/powerpc/platforms/powernv/pci-ioda.c
arch/powerpc/platforms/powernv/pci.c
arch/powerpc/platforms/pseries/msi.c
arch/score/mm/init.c
arch/x86/pci/mrst.c
drivers/acpi/Makefile
drivers/acpi/acpi_lpss.c
drivers/acpi/csrt.c [deleted file]
drivers/acpi/device_pm.c
drivers/acpi/internal.h
drivers/acpi/pci_root.c
drivers/acpi/scan.c
drivers/acpi/video_detect.c
drivers/base/bus.c
drivers/base/core.c
drivers/bcma/scan.c
drivers/block/brd.c
drivers/block/xsysace.c
drivers/char/lp.c
drivers/char/random.c
drivers/char/ttyprintk.c
drivers/clk/tegra/clk-tegra20.c
drivers/clk/x86/clk-lpt.c
drivers/cpufreq/Kconfig.x86
drivers/cpufreq/arm_big_little_dt.c
drivers/cpufreq/cpufreq.c
drivers/cpufreq/intel_pstate.c
drivers/cpufreq/loongson2_cpufreq.c
drivers/crypto/nx/nx-aes-cbc.c
drivers/crypto/nx/nx-aes-ecb.c
drivers/crypto/nx/nx-aes-gcm.c
drivers/crypto/nx/nx-sha256.c
drivers/crypto/nx/nx-sha512.c
drivers/crypto/nx/nx.c
drivers/dma/acpi-dma.c
drivers/edac/amd64_edac_inj.c
drivers/gpio/Kconfig
drivers/gpio/gpio-langwell.c
drivers/gpio/gpio-ml-ioh.c
drivers/gpio/gpio-mxs.c
drivers/gpio/gpio-omap.c
drivers/gpio/gpio-pch.c
drivers/gpio/gpio-sch.c
drivers/gpio/gpio-viperboard.c
drivers/hv/channel_mgmt.c
drivers/iio/adc/exynos_adc.c
drivers/iio/common/st_sensors/st_sensors_core.c
drivers/iio/dac/Kconfig
drivers/input/tablet/wacom_wac.c
drivers/input/tablet/wacom_wac.h
drivers/input/touchscreen/egalax_ts.c
drivers/isdn/capi/kcapi.c
drivers/leds/leds-ot200.c
drivers/mfd/Kconfig
drivers/mfd/ab8500-core.c
drivers/mfd/ab8500-debugfs.c
drivers/mfd/ab8500-gpadc.c
drivers/mfd/ab8500-sysctrl.c
drivers/mfd/abx500-core.c
drivers/mfd/cros_ec_spi.c
drivers/mfd/db8500-prcmu.c
drivers/mfd/si476x-cmd.c
drivers/misc/dummy-irq.c
drivers/misc/mei/bus.c
drivers/misc/mei/main.c
drivers/misc/vmw_vmci/Kconfig
drivers/misc/vmw_vmci/vmci_queue_pair.c
drivers/net/bonding/bond_3ad.c
drivers/net/bonding/bond_3ad.h
drivers/net/bonding/bond_main.c
drivers/net/bonding/bond_procfs.c
drivers/net/bonding/bond_sysfs.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
drivers/net/ethernet/broadcom/tg3.c
drivers/net/ethernet/cadence/macb.c
drivers/net/ethernet/cadence/macb.h
drivers/net/ethernet/emulex/benet/be_cmds.c
drivers/net/ethernet/emulex/benet/be_main.c
drivers/net/ethernet/freescale/fec_main.c
drivers/net/ethernet/freescale/gianfar_ptp.c
drivers/net/ethernet/icplus/ipg.h
drivers/net/ethernet/marvell/mv643xx_eth.c
drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c
drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c
drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c
drivers/net/ethernet/realtek/8139cp.c
drivers/net/ethernet/realtek/r8169.c
drivers/net/ethernet/sfc/efx.c
drivers/net/ethernet/sfc/net_driver.h
drivers/net/ethernet/sfc/rx.c
drivers/net/usb/qmi_wwan.c
drivers/net/usb/rtl8150.c
drivers/net/usb/usbnet.c
drivers/net/virtio_net.c
drivers/net/vxlan.c
drivers/net/wireless/ath/ath9k/ar9003_calib.c
drivers/net/wireless/ath/ath9k/ar9485_initvals.h
drivers/net/wireless/ath/ath9k/ath9k.h
drivers/net/wireless/ath/ath9k/debug.c
drivers/net/wireless/ath/ath9k/debug.h
drivers/net/wireless/ath/ath9k/init.c
drivers/net/wireless/ath/ath9k/main.c
drivers/net/wireless/ath/ath9k/xmit.c
drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
drivers/net/wireless/iwlegacy/common.c
drivers/net/wireless/iwlwifi/mvm/fw-api.h
drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
drivers/net/wireless/iwlwifi/mvm/mac80211.c
drivers/net/wireless/iwlwifi/mvm/mvm.h
drivers/net/wireless/iwlwifi/mvm/ops.c
drivers/net/wireless/iwlwifi/mvm/scan.c
drivers/net/wireless/iwlwifi/mvm/sta.c
drivers/net/wireless/iwlwifi/mvm/sta.h
drivers/net/wireless/iwlwifi/mvm/tx.c
drivers/net/wireless/mac80211_hwsim.c
drivers/net/wireless/rtlwifi/rtl8188ee/trx.h
drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
drivers/parisc/superio.c
drivers/pci/hotplug/acpiphp_glue.c
drivers/power/Kconfig
drivers/power/pm2301_charger.c
drivers/power/wm831x_backup.c
drivers/rapidio/Kconfig
drivers/rapidio/Makefile
drivers/rapidio/devices/tsi721.c
drivers/rapidio/rio-driver.c
drivers/rapidio/rio-scan.c
drivers/rapidio/rio-sysfs.c
drivers/rapidio/rio.c
drivers/rapidio/rio.h
drivers/rtc/rtc-max8998.c
drivers/rtc/rtc-pl031.c
drivers/staging/Kconfig
drivers/staging/android/logger.c
drivers/staging/android/logger.h
drivers/staging/comedi/Kconfig
drivers/staging/comedi/comedi_buf.c
drivers/staging/comedi/comedi_fops.c
drivers/staging/comedi/drivers/ni_labpc.c
drivers/staging/comedi/drivers/ni_labpc.h
drivers/staging/comedi/drivers/ni_mio_common.c
drivers/staging/dwc2/Kconfig
drivers/staging/dwc2/hcd_intr.c
drivers/staging/dwc2/platform.c
drivers/staging/gdm72xx/Kconfig
drivers/staging/iio/adc/mxs-lradc.c
drivers/staging/iio/light/tsl2x7x_core.c
drivers/staging/imx-drm/Kconfig
drivers/staging/imx-drm/imx-tve.c
drivers/staging/media/solo6x10/Kconfig
drivers/staging/nvec/nvec.c
drivers/staging/nvec/nvec.h
drivers/staging/nvec/nvec_kbd.c
drivers/staging/nvec/nvec_power.c
drivers/staging/nvec/nvec_ps2.c
drivers/staging/sep/Kconfig
drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c
drivers/staging/vt6656/hostap.c
drivers/staging/vt6656/iwctl.c
drivers/staging/zcache/ramster/ramster-howto.txt [new file with mode: 0644]
drivers/staging/zcache/zcache-main.c
drivers/tty/ehv_bytechan.c
drivers/tty/mxser.c
drivers/tty/n_tty.c
drivers/tty/rocket.c
drivers/tty/serial/8250/8250_dw.c
drivers/tty/serial/amba-pl011.c
drivers/tty/serial/mcf.c
drivers/tty/serial/mpc52xx_uart.c
drivers/tty/serial/nwpserial.c
drivers/tty/serial/omap-serial.c
drivers/tty/serial/samsung.c
drivers/tty/vt/vt.c
drivers/tty/vt/vt_ioctl.c
drivers/uio/Kconfig
drivers/usb/atm/cxacru.c
drivers/usb/chipidea/Kconfig
drivers/usb/chipidea/ci13xxx_imx.c
drivers/usb/core/Kconfig
drivers/usb/core/quirks.c
drivers/usb/dwc3/Kconfig
drivers/usb/dwc3/dwc3-exynos.c
drivers/usb/gadget/Kconfig
drivers/usb/gadget/atmel_usba_udc.c
drivers/usb/gadget/bcm63xx_udc.c
drivers/usb/gadget/configfs.c
drivers/usb/gadget/dummy_hcd.c
drivers/usb/gadget/f_ecm.c
drivers/usb/gadget/f_subset.c
drivers/usb/gadget/f_uac2.c
drivers/usb/gadget/fusb300_udc.c
drivers/usb/gadget/imx_udc.c
drivers/usb/gadget/m66592-udc.c
drivers/usb/gadget/pxa25x_udc.c
drivers/usb/gadget/r8a66597-udc.c
drivers/usb/gadget/s3c-hsotg.c
drivers/usb/gadget/s3c2410_udc.c
drivers/usb/gadget/zero.c
drivers/usb/host/Kconfig
drivers/usb/host/ehci-atmel.c
drivers/usb/host/ehci-hcd.c
drivers/usb/host/ehci-omap.c
drivers/usb/host/ehci-orion.c
drivers/usb/host/ehci-s5p.c
drivers/usb/host/ehci-spear.c
drivers/usb/host/ehci-tegra.c
drivers/usb/host/isp1760-hcd.c
drivers/usb/host/isp1760-if.c
drivers/usb/host/ohci-at91.c
drivers/usb/host/ohci-exynos.c
drivers/usb/host/ohci-hcd.c
drivers/usb/host/ohci-nxp.c
drivers/usb/host/ohci-omap3.c
drivers/usb/host/ohci-pxa27x.c
drivers/usb/host/ohci-spear.c
drivers/usb/host/oxu210hp-hcd.c
drivers/usb/host/sl811-hcd.c
drivers/usb/host/uhci-hub.c
drivers/usb/host/uhci-platform.c
drivers/usb/host/uhci-q.c
drivers/usb/host/xhci-mem.c
drivers/usb/musb/musb_dsps.c
drivers/usb/musb/omap2430.c
drivers/usb/phy/Kconfig
drivers/usb/phy/phy-ab8500-usb.c
drivers/usb/phy/phy-fsl-usb.c
drivers/usb/phy/phy-gpio-vbus-usb.c
drivers/usb/phy/phy-isp1301.c
drivers/usb/phy/phy-mv-usb.c
drivers/usb/phy/phy-mxs-usb.c
drivers/usb/phy/phy-nop.c
drivers/usb/serial/ftdi_sio.c
drivers/usb/serial/ftdi_sio_ids.h
drivers/usb/serial/generic.c
drivers/usb/serial/io_ti.c
drivers/usb/serial/option.c
drivers/usb/serial/ti_usb_3410_5052.c
drivers/usb/serial/usb-serial.c
drivers/usb/storage/realtek_cr.c
drivers/video/Kconfig
drivers/video/Makefile
drivers/video/console/Makefile
drivers/video/simplefb.c [new file with mode: 0644]
fs/aio.c
fs/cifs/inode.c
fs/fat/inode.c
fs/gfs2/Kconfig
fs/gfs2/lops.c
fs/gfs2/quota.c
fs/gfs2/rgrp.c
fs/hfs/bnode.c
fs/nfs/callback_proc.c
fs/nfs/callback_xdr.c
fs/nfs/nfs4client.c
fs/nfs/nfs4proc.c
fs/nfs/nfs4session.c
fs/nfs/nfs4session.h
fs/nfs/nfs4state.c
fs/nilfs2/inode.c
fs/ocfs2/extent_map.c
fs/ocfs2/file.c
fs/xfs/xfs_aops.c
fs/xfs/xfs_attr_leaf.c
fs/xfs/xfs_buf.c
fs/xfs/xfs_da_btree.c
fs/xfs/xfs_dir2_leaf.c
fs/xfs/xfs_extfree_item.c
fs/xfs/xfs_log_cil.c
fs/xfs/xfs_vnodeops.c
include/acpi/acpi_bus.h
include/linux/acpi_dma.h
include/linux/bcma/bcma.h
include/linux/brcmphy.h
include/linux/kernel.h
include/linux/mfd/abx500/ab8500.h
include/linux/netdevice.h
include/linux/pci-acpi.h
include/linux/platform_data/clk-lpss.h
include/linux/platform_data/serial-omap.h
include/linux/printk.h
include/linux/rio.h
include/linux/rio_drv.h
include/linux/socket.h
include/linux/uio.h
include/linux/usb/gadget.h
include/linux/usb/serial.h
include/linux/vt_kern.h
include/linux/wait.h
include/net/mac80211.h
include/net/netfilter/nf_log.h
include/net/netfilter/nfnetlink_log.h
include/uapi/linux/virtio_console.h
ipc/sem.c
kernel/auditfilter.c
kernel/trace/trace_events.c
lib/Makefile
lib/iovec.c [new file with mode: 0644]
lib/klist.c
lib/mpi/longlong.h
mm/huge_memory.c
mm/memcontrol.c
mm/memory_hotplug.c
mm/migrate.c
mm/mmu_notifier.c
mm/page_alloc.c
mm/pagewalk.c
net/802/mrp.c
net/batman-adv/main.c
net/batman-adv/originator.c
net/batman-adv/originator.h
net/batman-adv/soft-interface.c
net/batman-adv/translation-table.c
net/bridge/netfilter/ebt_log.c
net/bridge/netfilter/ebt_ulog.c
net/core/iovec.c
net/ipv4/ip_gre.c
net/ipv4/netfilter/ipt_ULOG.c
net/ipv4/tcp.c
net/ipv4/tcp_input.c
net/ipv4/tcp_output.c
net/ipv6/ip6_output.c
net/irda/irlap_frame.c
net/mac80211/ieee80211_i.h
net/mac80211/mlme.c
net/mac80211/rate.c
net/mac80211/rx.c
net/mac80211/tkip.c
net/mac80211/util.c
net/netfilter/nf_log.c
net/netfilter/nfnetlink_log.c
net/netfilter/nfnetlink_queue_core.c
net/netfilter/xt_LOG.c
net/netfilter/xt_NFLOG.c
net/netfilter/xt_TCPOPTSTRIP.c
net/netlabel/netlabel_domainhash.c
net/sunrpc/auth_gss/auth_gss.c
net/sunrpc/netns.h
net/sunrpc/rpc_pipe.c
net/sunrpc/sched.c
net/wireless/core.c
net/wireless/nl80211.c
net/wireless/sme.c
net/wireless/trace.h
net/xfrm/xfrm_output.c
tools/perf/scripts/python/net_dropmonitor.py
tools/testing/selftests/Makefile
tools/testing/selftests/soft-dirty/Makefile [deleted file]
tools/testing/selftests/soft-dirty/soft-dirty.c [deleted file]

index 44afa0e5057d1580698fa81462925d87a9896856..4ff65047bb9a8c63e3e647331fe2f32e1551db56 100644 (file)
@@ -4,7 +4,7 @@ Required properties:
 - compatible: Should be "cdns,[<chip>-]{macb|gem}"
   Use "cdns,at91sam9260-macb" Atmel at91sam9260 and at91sam9263 SoCs.
   Use "cdns,at32ap7000-macb" for other 10/100 usage or use the generic form: "cdns,macb".
-  Use "cnds,pc302-gem" for Picochip picoXcell pc302 and later devices based on
+  Use "cdns,pc302-gem" for Picochip picoXcell pc302 and later devices based on
   the Cadence GEM, or the generic form: "cdns,gem".
 - reg: Address and length of the register set for the device
 - interrupts: Should contain macb interrupt
diff --git a/Documentation/devicetree/bindings/video/simple-framebuffer.txt b/Documentation/devicetree/bindings/video/simple-framebuffer.txt
new file mode 100644 (file)
index 0000000..3ea4605
--- /dev/null
@@ -0,0 +1,25 @@
+Simple Framebuffer
+
+A simple frame-buffer describes a raw memory region that may be rendered to,
+with the assumption that the display hardware has already been set up to scan
+out from that buffer.
+
+Required properties:
+- compatible: "simple-framebuffer"
+- reg: Should contain the location and size of the framebuffer memory.
+- width: The width of the framebuffer in pixels.
+- height: The height of the framebuffer in pixels.
+- stride: The number of bytes in each line of the framebuffer.
+- format: The format of the framebuffer surface. Valid values are:
+  - r5g6b5 (16-bit pixels, d[15:11]=r, d[10:5]=g, d[4:0]=b).
+
+Example:
+
+       framebuffer {
+               compatible = "simple-framebuffer";
+               reg = <0x1d385000 (1600 * 1200 * 2)>;
+               width = <1600>;
+               height = <1200>;
+               stride = <(1600 * 2)>;
+               format = "r5g6b5";
+       };
index c75694b35d08b7f6f70290a1b715658f4d6c7156..a9c16c979da215d35d774e8e739848fe535acdd1 100644 (file)
@@ -79,20 +79,63 @@ master port that is used to communicate with devices within the network.
 In order to initialize the RapidIO subsystem, a platform must initialize and
 register at least one master port within the RapidIO network. To register mport
 within the subsystem controller driver initialization code calls function
-rio_register_mport() for each available master port. After all active master
-ports are registered with a RapidIO subsystem, the rio_init_mports() routine
-is called to perform enumeration and discovery.
+rio_register_mport() for each available master port.
 
-In the current PowerPC-based implementation a subsys_initcall() is specified to
-perform controller initialization and mport registration. At the end it directly
-calls rio_init_mports() to execute RapidIO enumeration and discovery.
+RapidIO subsystem uses subsys_initcall() or device_initcall() to perform
+controller initialization (depending on controller device type).
+
+After all active master ports are registered with a RapidIO subsystem,
+an enumeration and/or discovery routine may be called automatically or
+by user-space command.
 
 4. Enumeration and Discovery
 ----------------------------
 
-When rio_init_mports() is called it scans a list of registered master ports and
-calls an enumeration or discovery routine depending on the configured role of a
-master port: host or agent.
+4.1 Overview
+------------
+
+RapidIO subsystem configuration options allow users to specify enumeration and
+discovery methods as statically linked components or loadable modules.
+An enumeration/discovery method implementation and available input parameters
+define how any given method can be attached to available RapidIO mports:
+simply to all available mports OR individually to the specified mport device.
+
+Depending on selected enumeration/discovery build configuration, there are
+several methods to initiate an enumeration and/or discovery process:
+
+  (a) Statically linked enumeration and discovery process can be started
+  automatically during kernel initialization time using corresponding module
+  parameters. This was the original method used since introduction of RapidIO
+  subsystem. Now this method relies on enumerator module parameter which is
+  'rio-scan.scan' for existing basic enumeration/discovery method.
+  When automatic start of enumeration/discovery is used a user has to ensure
+  that all discovering endpoints are started before the enumerating endpoint
+  and are waiting for enumeration to be completed.
+  Configuration option CONFIG_RAPIDIO_DISC_TIMEOUT defines time that discovering
+  endpoint waits for enumeration to be completed. If the specified timeout
+  expires the discovery process is terminated without obtaining RapidIO network
+  information. NOTE: a timed out discovery process may be restarted later using
+  a user-space command as it is described later if the given endpoint was
+  enumerated successfully.
+
+  (b) Statically linked enumeration and discovery process can be started by
+  a command from user space. This initiation method provides more flexibility
+  for a system startup compared to the option (a) above. After all participating
+  endpoints have been successfully booted, an enumeration process shall be
+  started first by issuing a user-space command, after an enumeration is
+  completed a discovery process can be started on all remaining endpoints.
+
+  (c) Modular enumeration and discovery process can be started by a command from
+  user space. After an enumeration/discovery module is loaded, a network scan
+  process can be started by issuing a user-space command.
+  Similar to the option (b) above, an enumerator has to be started first.
+
+  (d) Modular enumeration and discovery process can be started by a module
+  initialization routine. In this case an enumerating module shall be loaded
+  first.
+
+When a network scan process is started it calls an enumeration or discovery
+routine depending on the configured role of a master port: host or agent.
 
 Enumeration is performed by a master port if it is configured as a host port by
 assigning a host device ID greater than or equal to zero. A host device ID is
@@ -104,8 +147,58 @@ for it.
 The enumeration and discovery routines use RapidIO maintenance transactions
 to access the configuration space of devices.
 
-The enumeration process is implemented according to the enumeration algorithm
-outlined in the RapidIO Interconnect Specification: Annex I [1].
+4.2 Automatic Start of Enumeration and Discovery
+------------------------------------------------
+
+Automatic enumeration/discovery start method is applicable only to built-in
+enumeration/discovery RapidIO configuration selection. To enable automatic
+enumeration/discovery start by existing basic enumerator method set use boot
+command line parameter "rio-scan.scan=1".
+
+This configuration requires synchronized start of all RapidIO endpoints that
+form a network which will be enumerated/discovered. Discovering endpoints have
+to be started before an enumeration starts to ensure that all RapidIO
+controllers have been initialized and are ready to be discovered. Configuration
+parameter CONFIG_RAPIDIO_DISC_TIMEOUT defines time (in seconds) which
+a discovering endpoint will wait for enumeration to be completed.
+
+When automatic enumeration/discovery start is selected, basic method's
+initialization routine calls rio_init_mports() to perform enumeration or
+discovery for all known mport devices.
+
+Depending on RapidIO network size and configuration this automatic
+enumeration/discovery start method may be difficult to use due to the
+requirement for synchronized start of all endpoints.
+
+4.3 User-space Start of Enumeration and Discovery
+-------------------------------------------------
+
+User-space start of enumeration and discovery can be used with built-in and
+modular build configurations. For user-space controlled start RapidIO subsystem
+creates the sysfs write-only attribute file '/sys/bus/rapidio/scan'. To initiate
+an enumeration or discovery process on specific mport device, a user needs to
+write mport_ID (not RapidIO destination ID) into that file. The mport_ID is a
+sequential number (0 ... RIO_MAX_MPORTS) assigned during mport device
+registration. For example for machine with single RapidIO controller, mport_ID
+for that controller always will be 0.
+
+To initiate RapidIO enumeration/discovery on all available mports a user may
+write '-1' (or RIO_MPORT_ANY) into the scan attribute file.
+
+4.4 Basic Enumeration Method
+----------------------------
+
+This is an original enumeration/discovery method which is available since
+first release of RapidIO subsystem code. The enumeration process is
+implemented according to the enumeration algorithm outlined in the RapidIO
+Interconnect Specification: Annex I [1].
+
+This method can be configured as statically linked or loadable module.
+The method's single parameter "scan" allows to trigger the enumeration/discovery
+process from module initialization routine.
+
+This enumeration/discovery method can be started only once and does not support
+unloading if it is built as a module.
 
 The enumeration process traverses the network using a recursive depth-first
 algorithm. When a new device is found, the enumerator takes ownership of that
@@ -160,6 +253,19 @@ time period. If this wait time period expires before enumeration is completed,
 an agent skips RapidIO discovery and continues with remaining kernel
 initialization.
 
+4.5 Adding New Enumeration/Discovery Method
+-------------------------------------------
+
+RapidIO subsystem code organization allows addition of new enumeration/discovery
+methods as new configuration options without significant impact to to the core
+RapidIO code.
+
+A new enumeration/discovery method has to be attached to one or more mport
+devices before an enumeration/discovery process can be started. Normally,
+method's module initialization routine calls rio_register_scan() to attach
+an enumerator to a specified mport device (or devices). The basic enumerator
+implementation demonstrates this process.
+
 5. References
 -------------
 
index 97f71ce575d65c08652788c95746d47d975e02d0..19878179da4c78657967868fc36ce2abe35aae94 100644 (file)
@@ -88,3 +88,20 @@ that exports additional attributes.
 
 IDT_GEN2:
  errlog - reads contents of device error log until it is empty.
+
+
+5. RapidIO Bus Attributes
+-------------------------
+
+RapidIO bus subdirectory /sys/bus/rapidio implements the following bus-specific
+attribute:
+
+  scan - allows to trigger enumeration discovery process from user space. This
+        is a write-only attribute. To initiate an enumeration or discovery
+        process on specific mport device, a user needs to write mport_ID (not
+        RapidIO destination ID) into this file. The mport_ID is a sequential
+        number (0 ... RIO_MAX_MPORTS) assigned to the mport device.
+        For example, for a machine with a single RapidIO controller, mport_ID
+        for that controller always will be 0.
+        To initiate RapidIO enumeration/discovery on all available mports
+        a user must write '-1' (or RIO_MPORT_ANY) into this attribute file.
index 829c0321108b6cff2fe6999c629fea11e5915e57..fd3a495a0005f7d9ad333f7bbd98438a811dea57 100644 (file)
@@ -3865,9 +3865,16 @@ M:       K. Y. Srinivasan <kys@microsoft.com>
 M:     Haiyang Zhang <haiyangz@microsoft.com>
 L:     devel@linuxdriverproject.org
 S:     Maintained
-F:     drivers/hv/
+F:     arch/x86/include/asm/mshyperv.h
+F:     arch/x86/include/uapi/asm/hyperv.h
+F:     arch/x86/kernel/cpu/mshyperv.c
 F:     drivers/hid/hid-hyperv.c
+F:     drivers/hv/
 F:     drivers/net/hyperv/
+F:     drivers/scsi/storvsc_drv.c
+F:     drivers/video/hyperv_fb.c
+F:     include/linux/hyperv.h
+F:     tools/hv/
 
 I2C OVER PARALLEL PORT
 M:     Jean Delvare <khali@linux-fr.org>
@@ -4641,12 +4648,13 @@ F:      include/linux/sunrpc/
 F:     include/uapi/linux/sunrpc/
 
 KERNEL VIRTUAL MACHINE (KVM)
-M:     Marcelo Tosatti <mtosatti@redhat.com>
 M:     Gleb Natapov <gleb@redhat.com>
+M:     Paolo Bonzini <pbonzini@redhat.com>
 L:     kvm@vger.kernel.org
-W:     http://kvm.qumranet.com
+W:     http://linux-kvm.org
 S:     Supported
-F:     Documentation/*/kvm.txt
+F:     Documentation/*/kvm*.txt
+F:     Documentation/virtual/kvm/
 F:     arch/*/kvm/
 F:     arch/*/include/asm/kvm*
 F:     include/linux/kvm*
@@ -5516,18 +5524,18 @@ F:      Documentation/networking/s2io.txt
 F:     Documentation/networking/vxge.txt
 F:     drivers/net/ethernet/neterion/
 
-NETFILTER/IPTABLES/IPCHAINS
-P:     Harald Welte
-P:     Jozsef Kadlecsik
+NETFILTER/IPTABLES
 M:     Pablo Neira Ayuso <pablo@netfilter.org>
 M:     Patrick McHardy <kaber@trash.net>
+M:     Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
 L:     netfilter-devel@vger.kernel.org
 L:     netfilter@vger.kernel.org
 L:     coreteam@netfilter.org
 W:     http://www.netfilter.org/
 W:     http://www.iptables.org/
-T:     git git://1984.lsi.us.es/nf
-T:     git git://1984.lsi.us.es/nf-next
+Q:     http://patchwork.ozlabs.org/project/netfilter-devel/list/
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next.git
 S:     Supported
 F:     include/linux/netfilter*
 F:     include/linux/netfilter/
@@ -6076,6 +6084,7 @@ L:        linux-parisc@vger.kernel.org
 W:     http://www.parisc-linux.org/
 Q:     http://patchwork.kernel.org/project/linux-parisc/list/
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/jejb/parisc-2.6.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux.git
 S:     Maintained
 F:     arch/parisc/
 F:     drivers/parisc/
index 93875f5122a32510d82555bbef001a18ea58308e..73e20dba55c1007fa66706771efaba26d932fbb3 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 3
 PATCHLEVEL = 10
 SUBLEVEL = 0
-EXTRAVERSION = -rc2
+EXTRAVERSION = -rc3
 NAME = Unicycling Gorilla
 
 # *DOCUMENTATION*
index c0fd3623c39387d5f2fbdc1da3552f08ff13e4da..0fa0d4abe79557cf8338c92ddf2a58a3e9d9d61c 100644 (file)
@@ -37,7 +37,7 @@
 
        soc100 {
                uart@FF100000 {
-                       pinctrl-names = "abilis,simple-default";
+                       pinctrl-names = "default";
                        pinctrl-0 = <&pctl_uart0>;
                };
                ethernet@FE100000 {
index 6f8c381f62685102891817da925d6b6b8aed9827..a4d80ce283aec1e7df6ca447fadc2a31b72f8b2c 100644 (file)
@@ -37,7 +37,7 @@
 
        soc100 {
                uart@FF100000 {
-                       pinctrl-names = "abilis,simple-default";
+                       pinctrl-names = "default";
                        pinctrl-0 = <&pctl_uart0>;
                };
                ethernet@FE100000 {
index a6139fc5aaa3e2f6faefbc7fdd5e369611697145..b97e3051ba4bfcd43db2bd66c00df1815a87090b 100644 (file)
@@ -88,8 +88,7 @@
                };
 
                uart@FF100000 {
-                       compatible = "snps,dw-apb-uart",
-                                       "abilis,simple-pinctrl";
+                       compatible = "snps,dw-apb-uart";
                        reg = <0xFF100000 0x100>;
                        clock-frequency = <166666666>;
                        interrupts = <25 1>;
                        #address-cells = <1>;
                        #size-cells = <0>;
                        cell-index = <1>;
-                       compatible = "abilis,tb100-spi",
-                                       "abilis,simple-pinctrl";
+                       compatible = "abilis,tb100-spi";
                        num-cs = <2>;
                        reg = <0xFE011000 0x20>;
                        interrupt-parent = <&tb10x_ictl>;
index 9f841af41092f059a604c0631984bb3c6ef067d7..ef62682e8d9567670fc435be9bc5ddfddb5fa06b 100644 (file)
@@ -93,14 +93,16 @@ static inline int cache_is_vipt_aliasing(void)
 #endif
 }
 
-#define CACHE_COLOR(addr)      (((unsigned long)(addr) >> (PAGE_SHIFT)) & 3)
+#define CACHE_COLOR(addr)      (((unsigned long)(addr) >> (PAGE_SHIFT)) & 1)
 
 /*
  * checks if two addresses (after page aligning) index into same cache set
  */
 #define addr_not_cache_congruent(addr1, addr2)                         \
+({                                                                     \
        cache_is_vipt_aliasing() ?                                      \
-               (CACHE_COLOR(addr1) != CACHE_COLOR(addr2)) : 0          \
+               (CACHE_COLOR(addr1) != CACHE_COLOR(addr2)) : 0;         \
+})
 
 #define copy_to_user_page(vma, page, vaddr, dst, src, len)             \
 do {                                                                   \
index 374a35514116c17a71a610c2959e90d213e7ed97..ab84bf131fe135a2070c4a22bc5c177020787759 100644 (file)
 #define clear_page(paddr)              memset((paddr), 0, PAGE_SIZE)
 #define copy_page(to, from)            memcpy((to), (from), PAGE_SIZE)
 
-#ifndef CONFIG_ARC_CACHE_VIPT_ALIASING
-
-#define clear_user_page(addr, vaddr, pg)       clear_page(addr)
-#define copy_user_page(vto, vfrom, vaddr, pg)  copy_page(vto, vfrom)
-
-#else  /* VIPT aliasing dcache */
-
 struct vm_area_struct;
 struct page;
 
@@ -35,8 +28,6 @@ void copy_user_highpage(struct page *to, struct page *from,
                        unsigned long u_vaddr, struct vm_area_struct *vma);
 void clear_user_page(void *to, unsigned long u_vaddr, struct page *page);
 
-#endif /* CONFIG_ARC_CACHE_VIPT_ALIASING */
-
 #undef STRICT_MM_TYPECHECKS
 
 #ifdef STRICT_MM_TYPECHECKS
index 1cc4720faccbecf7862253720988f54e9b43751a..95b1522212a73fce42cd1a7a5c18546c61232346 100644 (file)
@@ -57,9 +57,9 @@
 
 #define _PAGE_ACCESSED      (1<<1)     /* Page is accessed (S) */
 #define _PAGE_CACHEABLE     (1<<2)     /* Page is cached (H) */
-#define _PAGE_EXECUTE       (1<<3)     /* Page has user execute perm (H) */
-#define _PAGE_WRITE         (1<<4)     /* Page has user write perm (H) */
-#define _PAGE_READ          (1<<5)     /* Page has user read perm (H) */
+#define _PAGE_U_EXECUTE     (1<<3)     /* Page has user execute perm (H) */
+#define _PAGE_U_WRITE       (1<<4)     /* Page has user write perm (H) */
+#define _PAGE_U_READ        (1<<5)     /* Page has user read perm (H) */
 #define _PAGE_K_EXECUTE     (1<<6)     /* Page has kernel execute perm (H) */
 #define _PAGE_K_WRITE       (1<<7)     /* Page has kernel write perm (H) */
 #define _PAGE_K_READ        (1<<8)     /* Page has kernel perm (H) */
@@ -72,9 +72,9 @@
 
 /* PD1 */
 #define _PAGE_CACHEABLE     (1<<0)     /* Page is cached (H) */
-#define _PAGE_EXECUTE       (1<<1)     /* Page has user execute perm (H) */
-#define _PAGE_WRITE         (1<<2)     /* Page has user write perm (H) */
-#define _PAGE_READ          (1<<3)     /* Page has user read perm (H) */
+#define _PAGE_U_EXECUTE     (1<<1)     /* Page has user execute perm (H) */
+#define _PAGE_U_WRITE       (1<<2)     /* Page has user write perm (H) */
+#define _PAGE_U_READ        (1<<3)     /* Page has user read perm (H) */
 #define _PAGE_K_EXECUTE     (1<<4)     /* Page has kernel execute perm (H) */
 #define _PAGE_K_WRITE       (1<<5)     /* Page has kernel write perm (H) */
 #define _PAGE_K_READ        (1<<6)     /* Page has kernel perm (H) */
@@ -93,7 +93,8 @@
 #endif
 
 /* Kernel allowed all permissions for all pages */
-#define _K_PAGE_PERMS  (_PAGE_K_EXECUTE | _PAGE_K_WRITE | _PAGE_K_READ)
+#define _K_PAGE_PERMS  (_PAGE_K_EXECUTE | _PAGE_K_WRITE | _PAGE_K_READ | \
+                       _PAGE_GLOBAL | _PAGE_PRESENT)
 
 #ifdef CONFIG_ARC_CACHE_PAGES
 #define _PAGE_DEF_CACHEABLE _PAGE_CACHEABLE
  * -by default cached, unless config otherwise
  * -present in memory
  */
-#define ___DEF (_PAGE_PRESENT | _K_PAGE_PERMS | _PAGE_DEF_CACHEABLE)
+#define ___DEF (_PAGE_PRESENT | _PAGE_DEF_CACHEABLE)
+
+#define _PAGE_READ     (_PAGE_U_READ    | _PAGE_K_READ)
+#define _PAGE_WRITE    (_PAGE_U_WRITE   | _PAGE_K_WRITE)
+#define _PAGE_EXECUTE  (_PAGE_U_EXECUTE | _PAGE_K_EXECUTE)
 
 /* Set of bits not changed in pte_modify */
 #define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_MODIFIED)
  * kernel vaddr space - visible in all addr spaces, but kernel mode only
  * Thus Global, all-kernel-access, no-user-access, cached
  */
-#define PAGE_KERNEL          __pgprot(___DEF | _PAGE_GLOBAL)
+#define PAGE_KERNEL          __pgprot(_K_PAGE_PERMS | _PAGE_DEF_CACHEABLE)
 
 /* ioremap */
-#define PAGE_KERNEL_NO_CACHE __pgprot(_PAGE_PRESENT | _K_PAGE_PERMS | \
-                                                    _PAGE_GLOBAL)
+#define PAGE_KERNEL_NO_CACHE __pgprot(_K_PAGE_PERMS)
 
 /**************************************************************************
  * Mapping of vm_flags (Generic VM) to PTE flags (arch specific)
index 85b6df839bd7b93b11465c066bdd063b32e68b77..cb0c708ca6654cd38d0d73f40e6f43135e34c01e 100644 (file)
@@ -16,7 +16,7 @@
 /* Masks for actual TLB "PD"s */
 #define PTE_BITS_IN_PD0        (_PAGE_GLOBAL | _PAGE_PRESENT)
 #define PTE_BITS_IN_PD1        (PAGE_MASK | _PAGE_CACHEABLE | \
-                        _PAGE_EXECUTE | _PAGE_WRITE | _PAGE_READ | \
+                        _PAGE_U_EXECUTE | _PAGE_U_WRITE | _PAGE_U_READ | \
                         _PAGE_K_EXECUTE | _PAGE_K_WRITE | _PAGE_K_READ)
 
 #ifndef __ASSEMBLY__
index 2f12bca8aef30c4155b21e514e3ba9dd5ec63468..aedce1905441cffb1958f00af149b0a939740371 100644 (file)
@@ -610,7 +610,7 @@ void __sync_icache_dcache(unsigned long paddr, unsigned long vaddr, int len)
 
        local_irq_save(flags);
        __ic_line_inv_vaddr(paddr, vaddr, len);
-       __dc_line_op(paddr, vaddr, len, OP_FLUSH);
+       __dc_line_op(paddr, vaddr, len, OP_FLUSH_N_INV);
        local_irq_restore(flags);
 }
 
@@ -676,6 +676,17 @@ void flush_cache_range(struct vm_area_struct *vma, unsigned long start,
        flush_cache_all();
 }
 
+void flush_anon_page(struct vm_area_struct *vma, struct page *page,
+                    unsigned long u_vaddr)
+{
+       /* TBD: do we really need to clear the kernel mapping */
+       __flush_dcache_page(page_address(page), u_vaddr);
+       __flush_dcache_page(page_address(page), page_address(page));
+
+}
+
+#endif
+
 void copy_user_highpage(struct page *to, struct page *from,
        unsigned long u_vaddr, struct vm_area_struct *vma)
 {
@@ -725,16 +736,6 @@ void clear_user_page(void *to, unsigned long u_vaddr, struct page *page)
        set_bit(PG_arch_1, &page->flags);
 }
 
-void flush_anon_page(struct vm_area_struct *vma, struct page *page,
-                    unsigned long u_vaddr)
-{
-       /* TBD: do we really need to clear the kernel mapping */
-       __flush_dcache_page(page_address(page), u_vaddr);
-       __flush_dcache_page(page_address(page), page_address(page));
-
-}
-
-#endif
 
 /**********************************************************************
  * Explicit Cache flush request from user space via syscall
index 066145b5f3488bcaa515769728d0389a00fc7ed7..fe1c5a073afe4cf996d28b6486c6b296fbd94344 100644 (file)
@@ -444,7 +444,8 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long vaddr_unaligned,
         *             so userspace sees the right data.
         *  (Avoids the flush for Non-exec + congruent mapping case)
         */
-       if (vma->vm_flags & VM_EXEC || addr_not_cache_congruent(paddr, vaddr)) {
+       if ((vma->vm_flags & VM_EXEC) ||
+            addr_not_cache_congruent(paddr, vaddr)) {
                struct page *page = pfn_to_page(pte_pfn(*ptep));
 
                int dirty = test_and_clear_bit(PG_arch_1, &page->flags);
index 9df765dc7c3abb56755cac6591aa5765ca155587..3357d26ffe54267a8ba9d26e596019b187e23bdd 100644 (file)
@@ -277,7 +277,7 @@ ARC_ENTRY EV_TLBMissI
        ;----------------------------------------------------------------
        ; VERIFY_PTE: Check if PTE permissions approp for executing code
        cmp_s   r2, VMALLOC_START
-       mov.lo  r2, (_PAGE_PRESENT | _PAGE_READ | _PAGE_EXECUTE)
+       mov.lo  r2, (_PAGE_PRESENT | _PAGE_U_READ | _PAGE_U_EXECUTE)
        mov.hs  r2, (_PAGE_PRESENT | _PAGE_K_READ | _PAGE_K_EXECUTE)
 
        and     r3, r0, r2  ; Mask out NON Flag bits from PTE
@@ -320,9 +320,9 @@ ARC_ENTRY EV_TLBMissD
        mov_s   r2, 0
        lr      r3, [ecr]
        btst_s  r3, ECR_C_BIT_DTLB_LD_MISS      ; Read Access
-       or.nz   r2, r2, _PAGE_READ              ; chk for Read flag in PTE
+       or.nz   r2, r2, _PAGE_U_READ            ; chk for Read flag in PTE
        btst_s  r3, ECR_C_BIT_DTLB_ST_MISS      ; Write Access
-       or.nz   r2, r2, _PAGE_WRITE             ; chk for Write flag in PTE
+       or.nz   r2, r2, _PAGE_U_WRITE           ; chk for Write flag in PTE
        ; Above laddering takes care of XCHG access
        ;   which is both Read and Write
 
index d3567691c7e1259174a9b6db4cf65593c2fb7536..06cb309294608a6753652049e7c4f3df6d8f8ada 100644 (file)
@@ -34,31 +34,6 @@ static void __init tb10x_platform_init(void)
        of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
 }
 
-static void __init tb10x_platform_late_init(void)
-{
-       struct device_node *dn;
-
-       /*
-        * Pinctrl documentation recommends setting up the iomux here for
-        * all modules which don't require control over the pins themselves.
-        * Modules which need this kind of assistance are compatible with
-        * "abilis,simple-pinctrl", i.e. we can easily iterate over them.
-        * TODO: Does this recommended method work cleanly with pins required
-        * by modules?
-        */
-       for_each_compatible_node(dn, NULL, "abilis,simple-pinctrl") {
-               struct platform_device *pd = of_find_device_by_node(dn);
-               struct pinctrl *pctl;
-
-               pctl = pinctrl_get_select(&pd->dev, "abilis,simple-default");
-               if (IS_ERR(pctl)) {
-                       int ret = PTR_ERR(pctl);
-                       dev_err(&pd->dev, "Could not set up pinctrl: %d\n",
-                               ret);
-               }
-       }
-}
-
 static const char *tb10x_compat[] __initdata = {
        "abilis,arc-tb10x",
        NULL,
@@ -67,5 +42,4 @@ static const char *tb10x_compat[] __initdata = {
 MACHINE_START(TB10x, "tb10x")
        .dt_compat      = tb10x_compat,
        .init_machine   = tb10x_platform_init,
-       .init_late      = tb10x_platform_late_init,
 MACHINE_END
index ec38cacb3d083fcca2ab69874523da3d64f14e42..aba657a9d3a68aa0062e2dd0740cb1b006519c30 100644 (file)
@@ -1707,6 +1707,14 @@ config HW_PERF_EVENTS
          Enable hardware performance counter support for perf events. If
          disabled, perf events will use software events only.
 
+config SYS_SUPPORTS_HUGETLBFS
+       def_bool y
+       depends on ARM_LPAE
+
+config HAVE_ARCH_TRANSPARENT_HUGEPAGE
+       def_bool y
+       depends on ARM_LPAE
+
 source "mm/Kconfig"
 
 config FORCE_MAX_ZONEORDER
index b9f7121e6ecf02c561e5b1b10308659aad23fb28..f0895c581a89be8668a99db10e6873ae94be0cef 100644 (file)
@@ -177,7 +177,9 @@ dtb-$(CONFIG_ARCH_SPEAR3XX)+= spear300-evb.dtb \
        spear320-evb.dtb \
        spear320-hmi.dtb
 dtb-$(CONFIG_ARCH_SPEAR6XX)+= spear600-evb.dtb
-dtb-$(CONFIG_ARCH_SUNXI) += sun4i-a10-cubieboard.dtb \
+dtb-$(CONFIG_ARCH_SUNXI) += \
+       sun4i-a10-cubieboard.dtb \
+       sun4i-a10-mini-xplus.dtb \
        sun4i-a10-hackberry.dtb \
        sun5i-a13-olinuxino.dtb
 dtb-$(CONFIG_ARCH_TEGRA) += tegra20-harmony.dtb \
index 272bbc65fab05b809b9df0a57497c14d37eac302..550eb772c30e4c47c2f7f0896469a033dee3e23b 100644 (file)
@@ -33,7 +33,8 @@
                #size-cells = <1>;
                compatible = "simple-bus";
                interrupt-parent = <&mpic>;
-               ranges = <0 0 0xd0000000 0x100000>;
+               ranges = <0          0 0xd0000000 0x0100000 /* internal registers */
+                         0xe0000000 0 0xe0000000 0x8100000 /* PCIe */>;
 
                internal-regs {
                        compatible = "simple-bus";
index b2c1b5af9749cd0f0b358d32dfbb159c7deab280..aee2b1866ce2ede35fbd58a6bbea1e29ac6b16ea 100644 (file)
@@ -29,7 +29,8 @@
        };
 
        soc {
-               ranges = <0 0xd0000000 0x100000>;
+               ranges = <0          0xd0000000 0x0100000 /* internal registers */
+                         0xe0000000 0xe0000000 0x8100000 /* PCIe */>;
                internal-regs {
                        system-controller@18200 {
                                compatible = "marvell,armada-370-xp-system-controller";
 
                        L2: l2-cache {
                                compatible = "marvell,aurora-outer-cache";
-                               reg = <0xd0008000 0x1000>;
+                               reg = <0x08000 0x1000>;
                                cache-id-part = <0x100>;
                                wt-override;
                        };
 
-                       mpic: interrupt-controller@20000 {
+                       interrupt-controller@20000 {
                                reg = <0x20a00 0x1d0>, <0x21870 0x58>;
                        };
 
index 26ad06fc147ed78f9446bb5119a1e6e001867dba..3ee63d128e27cf27b3c8f6c5211bcf05b6dadc9e 100644 (file)
@@ -39,6 +39,9 @@
        };
 
        soc {
+               ranges = <0          0 0xd0000000 0x100000
+                         0xf0000000 0 0xf0000000 0x1000000>;
+
                internal-regs {
                        serial@12000 {
                                clock-frequency = <250000000>;
index f14d36c4615984399b71c36e920ed84be96fcb74..46b785064dd869917afa981103136459a5826922 100644 (file)
@@ -27,6 +27,9 @@
        };
 
        soc {
+               ranges = <0          0 0xd0000000 0x100000
+                         0xf0000000 0 0xf0000000 0x8000000>;
+
                internal-regs {
                        serial@12000 {
                                clock-frequency = <250000000>;
index bacab11c10dc8151eb7f2b6eb8cf0d2905a52f0e..5b902f9a3af29a84fd0ee83000c8d0f2ffa280ea 100644 (file)
@@ -31,7 +31,7 @@
                                wt-override;
                        };
 
-                       mpic: interrupt-controller@20000 {
+                       interrupt-controller@20000 {
                              reg = <0x20a00 0x2d0>, <0x21070 0x58>;
                        };
 
index 70b5ccbac234a63d12228e161e2620d4e2d8e40a..84c4bef2d7268760a6d927bd8ed2fdf7d547ea59 100644 (file)
                                                atmel,pins =
                                                        <0 10 0x2 0x0   /* PA10 periph B */
                                                         0 11 0x2 0x0   /* PA11 periph B */
-                                                        0 24 0x2 0x0   /* PA24 periph B */
+                                                        0 22 0x2 0x0   /* PA22 periph B */
                                                         0 25 0x2 0x0   /* PA25 periph B */
                                                         0 26 0x2 0x0   /* PA26 periph B */
                                                         0 27 0x2 0x0   /* PA27 periph B */
index 3de8e6dfbcb150baa7251d1803990724d93e4fe2..8d25f889928eccd3c7a3440dd9522e4f1d34e37c 100644 (file)
@@ -57,6 +57,7 @@
                                compatible = "atmel,at91rm9200-aic";
                                interrupt-controller;
                                reg = <0xfffff000 0x200>;
+                               atmel,external-irqs = <31>;
                        };
 
                        ramc0: ramc@ffffe800 {
index 3b40d11d65e70c0daabdeddafe27180cacd12825..315250b4995e74e4452af0d0e46bb847790fbaf5 100644 (file)
@@ -11,7 +11,7 @@
 /include/ "at91sam9x5ek.dtsi"
 
 / {
-       model = "Atmel AT91SAM9G25-EK";
+       model = "Atmel AT91SAM9X25-EK";
        compatible = "atmel,at91sam9x25ek", "atmel,at91sam9x5ek", "atmel,at91sam9x5", "atmel,at91sam9";
 
        ahb {
index 82a404da1c0d9531b632e265943632e7ea48d468..99ba6e14ebf3f5880660e3073aebda1fdce3e53b 100644 (file)
                usb_otg_hs: usb_otg_hs@480ab000 {
                        compatible = "ti,omap3-musb";
                        reg = <0x480ab000 0x1000>;
-                       interrupts = <0 92 0x4>, <0 93 0x4>;
+                       interrupts = <92>, <93>;
                        interrupt-names = "mc", "dma";
                        ti,hwmods = "usb_otg_hs";
                        multipoint = <1>;
index 2e643ea51cceba014b713843a81a1f11a4fd88be..5000e0d428496d8105f6157f4ba54b4603796657 100644 (file)
                                compatible = "atmel,at91sam9x5-spi";
                                reg = <0xf0004000 0x100>;
                                interrupts = <24 4 3>;
-                               cs-gpios = <&pioD 13 0
-                                           &pioD 14 0 /* conflicts with SCK0 and CANRX0 */
-                                           &pioD 15 0 /* conflicts with CTS0 and CANTX0 */
-                                           &pioD 16 0 /* conflicts with RTS0 and PWMFI3 */
-                                          >;
                                pinctrl-names = "default";
                                pinctrl-0 = <&pinctrl_spi0>;
                                status = "disabled";
                        };
 
                        macb0: ethernet@f0028000 {
-                               compatible = "cnds,pc302-gem", "cdns,gem";
+                               compatible = "cdns,pc302-gem", "cdns,gem";
                                reg = <0xf0028000 0x100>;
                                interrupts = <34 4 3>;
                                pinctrl-names = "default";
                                compatible = "atmel,at91sam9x5-spi";
                                reg = <0xf8008000 0x100>;
                                interrupts = <25 4 3>;
-                               cs-gpios = <&pioC 25 0
-                                           &pioC 26 0 /* conflitcs with TWD1 and ISI_D11 */
-                                           &pioC 27 0 /* conflitcs with TWCK1 and ISI_D10 */
-                                           &pioC 28 0 /* conflitcs with PWMFI0 and ISI_D9 */
-                                          >;
                                pinctrl-names = "default";
                                pinctrl-0 = <&pinctrl_spi1>;
                                status = "disabled";
index 1f8ed404626cdb1edba6825a49c90d7a435d81aa..b336e7787cb3ea35ac312e83a66bc948a988e977 100644 (file)
 
        ahb {
                apb {
+                       spi0: spi@f0004000 {
+                               cs-gpios = <&pioD 13 0>, <0>, <0>, <0>;
+                       };
+
                        macb0: ethernet@f0028000 {
                                phy-mode = "rgmii";
                        };
index b28fbf3408e3b29c265db2f7448649819fe85df1..6f82d9368948856e8123b7193bbfc8230986f96f 100644 (file)
                bootargs = "root=/dev/ram0 console=ttyAMA1,115200n8 earlyprintk";
        };
 
+       /* This is where the interrupt is routed on the S8815 board */
+       external-bus@34000000 {
+               ethernet@300 {
+                       interrupt-parent = <&gpio3>;
+                       interrupts = <8 0x1>;
+               };
+       };
+
        /* Custom board node with GPIO pins to active etc */
        usb-s8815 {
                /* The S8815 is using this very GPIO pin for the SMSC91x IRQs */
                ethernet-gpio {
-                       gpios = <&gpio3 19 0x1>;
-                       interrupts = <19 0x1>;
-                       interrupt-parent = <&gpio3>;
+                       gpios = <&gpio3 8 0x1>;
                };
                /* This will bias the MMC/SD card detect line */
                mmcsd-gpio {
index 4a7c35d6726aaa1290e4ee42b6ac47f517fc159a..078ed7f618d7910cc6030fdf9b288b3b124da065 100644 (file)
@@ -22,8 +22,8 @@
                bootargs = "earlyprintk console=ttyS0,115200";
        };
 
-       soc {
-               uart0: uart@01c28000 {
+       soc@01c20000 {
+               uart0: serial@01c28000 {
                        pinctrl-names = "default";
                        pinctrl-0 = <&uart0_pins_a>;
                        status = "okay";
index 7e0ebb64a7f9dafe5c73b9201c39e344c309ef93..9940f7b4e438c258d125cc6567ac1b7a9b2fc429 100644 (file)
@@ -199,7 +199,6 @@ CONFIG_USB_PHY=y
 CONFIG_USB_DEBUG=y
 CONFIG_USB_DEVICEFS=y
 # CONFIG_USB_DEVICE_CLASS is not set
-CONFIG_USB_SUSPEND=y
 CONFIG_USB_MON=y
 CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_STORAGE=y
index c1ef64bc5abd65781da53de52d4cfd3e392e29cc..abbe31937c65228e53dc2c97b4b2d4c14451ec38 100644 (file)
@@ -20,6 +20,7 @@ CONFIG_MODULE_FORCE_UNLOAD=y
 CONFIG_MODVERSIONS=y
 CONFIG_MODULE_SRCVERSION_ALL=y
 # CONFIG_BLK_DEV_BSG is not set
+CONFIG_ARCH_MULTI_V6=y
 CONFIG_ARCH_OMAP2PLUS=y
 CONFIG_OMAP_RESET_CLOCKS=y
 CONFIG_OMAP_MUX_DEBUG=y
@@ -204,7 +205,6 @@ CONFIG_USB=y
 CONFIG_USB_DEBUG=y
 CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
 CONFIG_USB_DEVICEFS=y
-CONFIG_USB_SUSPEND=y
 CONFIG_USB_MON=y
 CONFIG_USB_WDM=y
 CONFIG_USB_STORAGE=y
index a5f0485133cf9d9fc608a742e158b629405e1c7d..f7ba316164d4e9e4572f396249e70ad65e9163a9 100644 (file)
@@ -153,6 +153,7 @@ CONFIG_MEDIA_CAMERA_SUPPORT=y
 CONFIG_MEDIA_USB_SUPPORT=y
 CONFIG_USB_VIDEO_CLASS=m
 CONFIG_DRM=y
+CONFIG_TEGRA_HOST1X=y
 CONFIG_DRM_TEGRA=y
 CONFIG_BACKLIGHT_LCD_SUPPORT=y
 # CONFIG_LCD_CLASS_DEVICE is not set
@@ -202,7 +203,7 @@ CONFIG_TEGRA20_APB_DMA=y
 CONFIG_STAGING=y
 CONFIG_SENSORS_ISL29018=y
 CONFIG_SENSORS_ISL29028=y
-CONFIG_SENSORS_AK8975=y
+CONFIG_AK8975=y
 CONFIG_MFD_NVEC=y
 CONFIG_KEYBOARD_NVEC=y
 CONFIG_SERIO_NVEC_PS2=y
index 92c6eed7aac9cded01cd9bd259deba3bd6fda782..99207c45ec10f56891cd40d53b8a5fe524337f0f 100644 (file)
@@ -195,6 +195,7 @@ ENTRY(sha1_block_data_order)
        add     r3,r3,r10                       @ E+=F_00_19(B,C,D)
        cmp     r14,sp
        bne     .L_00_15                @ [((11+4)*5+2)*3]
+       sub     sp,sp,#25*4
 #if __ARM_ARCH__<7
        ldrb    r10,[r1,#2]
        ldrb    r9,[r1,#3]
@@ -290,7 +291,6 @@ ENTRY(sha1_block_data_order)
        add     r3,r3,r10                       @ E+=F_00_19(B,C,D)
 
        ldr     r8,.LK_20_39            @ [+15+16*4]
-       sub     sp,sp,#25*4
        cmn     sp,#0                   @ [+3], clear carry to denote 20_39
 .L_20_39_or_60_79:
        ldr     r9,[r14,#15*4]
diff --git a/arch/arm/include/asm/hugetlb-3level.h b/arch/arm/include/asm/hugetlb-3level.h
new file mode 100644 (file)
index 0000000..d4014fb
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * arch/arm/include/asm/hugetlb-3level.h
+ *
+ * Copyright (C) 2012 ARM Ltd.
+ *
+ * Based on arch/x86/include/asm/hugetlb.h.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _ASM_ARM_HUGETLB_3LEVEL_H
+#define _ASM_ARM_HUGETLB_3LEVEL_H
+
+
+/*
+ * If our huge pte is non-zero then mark the valid bit.
+ * This allows pte_present(huge_ptep_get(ptep)) to return true for non-zero
+ * ptes.
+ * (The valid bit is automatically cleared by set_pte_at for PROT_NONE ptes).
+ */
+static inline pte_t huge_ptep_get(pte_t *ptep)
+{
+       pte_t retval = *ptep;
+       if (pte_val(retval))
+               pte_val(retval) |= L_PTE_VALID;
+       return retval;
+}
+
+static inline void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
+                                  pte_t *ptep, pte_t pte)
+{
+       set_pte_at(mm, addr, ptep, pte);
+}
+
+static inline void huge_ptep_clear_flush(struct vm_area_struct *vma,
+                                        unsigned long addr, pte_t *ptep)
+{
+       ptep_clear_flush(vma, addr, ptep);
+}
+
+static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
+                                          unsigned long addr, pte_t *ptep)
+{
+       ptep_set_wrprotect(mm, addr, ptep);
+}
+
+static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
+                                           unsigned long addr, pte_t *ptep)
+{
+       return ptep_get_and_clear(mm, addr, ptep);
+}
+
+static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
+                                            unsigned long addr, pte_t *ptep,
+                                            pte_t pte, int dirty)
+{
+       return ptep_set_access_flags(vma, addr, ptep, pte, dirty);
+}
+
+#endif /* _ASM_ARM_HUGETLB_3LEVEL_H */
diff --git a/arch/arm/include/asm/hugetlb.h b/arch/arm/include/asm/hugetlb.h
new file mode 100644 (file)
index 0000000..1f1b1cd
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * arch/arm/include/asm/hugetlb.h
+ *
+ * Copyright (C) 2012 ARM Ltd.
+ *
+ * Based on arch/x86/include/asm/hugetlb.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _ASM_ARM_HUGETLB_H
+#define _ASM_ARM_HUGETLB_H
+
+#include <asm/page.h>
+#include <asm-generic/hugetlb.h>
+
+#include <asm/hugetlb-3level.h>
+
+static inline void hugetlb_free_pgd_range(struct mmu_gather *tlb,
+                                         unsigned long addr, unsigned long end,
+                                         unsigned long floor,
+                                         unsigned long ceiling)
+{
+       free_pgd_range(tlb, addr, end, floor, ceiling);
+}
+
+
+static inline int is_hugepage_only_range(struct mm_struct *mm,
+                                        unsigned long addr, unsigned long len)
+{
+       return 0;
+}
+
+static inline int prepare_hugepage_range(struct file *file,
+                                        unsigned long addr, unsigned long len)
+{
+       struct hstate *h = hstate_file(file);
+       if (len & ~huge_page_mask(h))
+               return -EINVAL;
+       if (addr & ~huge_page_mask(h))
+               return -EINVAL;
+       return 0;
+}
+
+static inline void hugetlb_prefault_arch_hook(struct mm_struct *mm)
+{
+}
+
+static inline int huge_pte_none(pte_t pte)
+{
+       return pte_none(pte);
+}
+
+static inline pte_t huge_pte_wrprotect(pte_t pte)
+{
+       return pte_wrprotect(pte);
+}
+
+static inline int arch_prepare_hugepage(struct page *page)
+{
+       return 0;
+}
+
+static inline void arch_release_hugepage(struct page *page)
+{
+}
+
+static inline void arch_clear_hugepage_flags(struct page *page)
+{
+       clear_bit(PG_dcache_clean, &page->flags);
+}
+
+#endif /* _ASM_ARM_HUGETLB_H */
index 18f5cef82ad58988e1c8d9b77ab95eb995330bbf..f088c864c9926723f615feb125ddb3b207e50c21 100644 (file)
@@ -30,6 +30,7 @@
 #define PMD_TYPE_FAULT         (_AT(pmdval_t, 0) << 0)
 #define PMD_TYPE_TABLE         (_AT(pmdval_t, 3) << 0)
 #define PMD_TYPE_SECT          (_AT(pmdval_t, 1) << 0)
+#define PMD_TABLE_BIT          (_AT(pmdval_t, 1) << 1)
 #define PMD_BIT4               (_AT(pmdval_t, 0))
 #define PMD_DOMAIN(x)          (_AT(pmdval_t, 0))
 #define PMD_APTABLE_SHIFT      (61)
@@ -41,6 +42,8 @@
  */
 #define PMD_SECT_BUFFERABLE    (_AT(pmdval_t, 1) << 2)
 #define PMD_SECT_CACHEABLE     (_AT(pmdval_t, 1) << 3)
+#define PMD_SECT_USER          (_AT(pmdval_t, 1) << 6)         /* AP[1] */
+#define PMD_SECT_RDONLY                (_AT(pmdval_t, 1) << 7)         /* AP[2] */
 #define PMD_SECT_S             (_AT(pmdval_t, 3) << 8)
 #define PMD_SECT_AF            (_AT(pmdval_t, 1) << 10)
 #define PMD_SECT_nG            (_AT(pmdval_t, 1) << 11)
@@ -66,6 +69,7 @@
 #define PTE_TYPE_MASK          (_AT(pteval_t, 3) << 0)
 #define PTE_TYPE_FAULT         (_AT(pteval_t, 0) << 0)
 #define PTE_TYPE_PAGE          (_AT(pteval_t, 3) << 0)
+#define PTE_TABLE_BIT          (_AT(pteval_t, 1) << 1)
 #define PTE_BUFFERABLE         (_AT(pteval_t, 1) << 2)         /* AttrIndx[0] */
 #define PTE_CACHEABLE          (_AT(pteval_t, 1) << 3)         /* AttrIndx[1] */
 #define PTE_EXT_SHARED         (_AT(pteval_t, 3) << 8)         /* SH[1:0], inner shareable */
index 86b8fe398b9514d89a9032658f6bb3ad221b069e..54733e5ef7a1540ce383d154a15cd9873187544d 100644 (file)
 
 #define USER_PTRS_PER_PGD      (PAGE_OFFSET / PGDIR_SIZE)
 
+/*
+ * Hugetlb definitions.
+ */
+#define HPAGE_SHIFT            PMD_SHIFT
+#define HPAGE_SIZE             (_AC(1, UL) << HPAGE_SHIFT)
+#define HPAGE_MASK             (~(HPAGE_SIZE - 1))
+#define HUGETLB_PAGE_ORDER     (HPAGE_SHIFT - PAGE_SHIFT)
+
 /*
  * "Linux" PTE definitions for LPAE.
  *
 #define L_PTE_SPECIAL          (_AT(pteval_t, 1) << 56)        /* unused */
 #define L_PTE_NONE             (_AT(pteval_t, 1) << 57)        /* PROT_NONE */
 
+#define PMD_SECT_VALID         (_AT(pmdval_t, 1) << 0)
+#define PMD_SECT_DIRTY         (_AT(pmdval_t, 1) << 55)
+#define PMD_SECT_SPLITTING     (_AT(pmdval_t, 1) << 56)
+#define PMD_SECT_NONE          (_AT(pmdval_t, 1) << 57)
+
 /*
  * To be used in assembly code with the upper page attributes.
  */
@@ -166,8 +179,83 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr)
                clean_pmd_entry(pmdp);  \
        } while (0)
 
+/*
+ * For 3 levels of paging the PTE_EXT_NG bit will be set for user address ptes
+ * that are written to a page table but not for ptes created with mk_pte.
+ *
+ * In hugetlb_no_page, a new huge pte (new_pte) is generated and passed to
+ * hugetlb_cow, where it is compared with an entry in a page table.
+ * This comparison test fails erroneously leading ultimately to a memory leak.
+ *
+ * To correct this behaviour, we mask off PTE_EXT_NG for any pte that is
+ * present before running the comparison.
+ */
+#define __HAVE_ARCH_PTE_SAME
+#define pte_same(pte_a,pte_b)  ((pte_present(pte_a) ? pte_val(pte_a) & ~PTE_EXT_NG     \
+                                       : pte_val(pte_a))                               \
+                               == (pte_present(pte_b) ? pte_val(pte_b) & ~PTE_EXT_NG   \
+                                       : pte_val(pte_b)))
+
 #define set_pte_ext(ptep,pte,ext) cpu_set_pte_ext(ptep,__pte(pte_val(pte)|(ext)))
 
+#define pte_huge(pte)          (pte_val(pte) && !(pte_val(pte) & PTE_TABLE_BIT))
+#define pte_mkhuge(pte)                (__pte(pte_val(pte) & ~PTE_TABLE_BIT))
+
+#define pmd_young(pmd)         (pmd_val(pmd) & PMD_SECT_AF)
+
+#define __HAVE_ARCH_PMD_WRITE
+#define pmd_write(pmd)         (!(pmd_val(pmd) & PMD_SECT_RDONLY))
+
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+#define pmd_trans_huge(pmd)    (pmd_val(pmd) && !(pmd_val(pmd) & PMD_TABLE_BIT))
+#define pmd_trans_splitting(pmd) (pmd_val(pmd) & PMD_SECT_SPLITTING)
+#endif
+
+#define PMD_BIT_FUNC(fn,op) \
+static inline pmd_t pmd_##fn(pmd_t pmd) { pmd_val(pmd) op; return pmd; }
+
+PMD_BIT_FUNC(wrprotect,        |= PMD_SECT_RDONLY);
+PMD_BIT_FUNC(mkold,    &= ~PMD_SECT_AF);
+PMD_BIT_FUNC(mksplitting, |= PMD_SECT_SPLITTING);
+PMD_BIT_FUNC(mkwrite,   &= ~PMD_SECT_RDONLY);
+PMD_BIT_FUNC(mkdirty,   |= PMD_SECT_DIRTY);
+PMD_BIT_FUNC(mkyoung,   |= PMD_SECT_AF);
+
+#define pmd_mkhuge(pmd)                (__pmd(pmd_val(pmd) & ~PMD_TABLE_BIT))
+
+#define pmd_pfn(pmd)           (((pmd_val(pmd) & PMD_MASK) & PHYS_MASK) >> PAGE_SHIFT)
+#define pfn_pmd(pfn,prot)      (__pmd(((phys_addr_t)(pfn) << PAGE_SHIFT) | pgprot_val(prot)))
+#define mk_pmd(page,prot)      pfn_pmd(page_to_pfn(page),prot)
+
+/* represent a notpresent pmd by zero, this is used by pmdp_invalidate */
+#define pmd_mknotpresent(pmd)  (__pmd(0))
+
+static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot)
+{
+       const pmdval_t mask = PMD_SECT_USER | PMD_SECT_XN | PMD_SECT_RDONLY |
+                               PMD_SECT_VALID | PMD_SECT_NONE;
+       pmd_val(pmd) = (pmd_val(pmd) & ~mask) | (pgprot_val(newprot) & mask);
+       return pmd;
+}
+
+static inline void set_pmd_at(struct mm_struct *mm, unsigned long addr,
+                             pmd_t *pmdp, pmd_t pmd)
+{
+       BUG_ON(addr >= TASK_SIZE);
+
+       /* create a faulting entry if PROT_NONE protected */
+       if (pmd_val(pmd) & PMD_SECT_NONE)
+               pmd_val(pmd) &= ~PMD_SECT_VALID;
+
+       *pmdp = __pmd(pmd_val(pmd) | PMD_SECT_nG);
+       flush_pmd_entry(pmdp);
+}
+
+static inline int has_transparent_hugepage(void)
+{
+       return 1;
+}
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* _ASM_PGTABLE_3LEVEL_H */
index 9bcd262a900842dfc685991511d4850fb3601ff5..eaedce7b7e3a61856f609a31ba64d55187521050 100644 (file)
@@ -24,6 +24,9 @@
 #include <asm/memory.h>
 #include <asm/pgtable-hwdef.h>
 
+
+#include <asm/tlbflush.h>
+
 #ifdef CONFIG_ARM_LPAE
 #include <asm/pgtable-3level.h>
 #else
index 99a19512ee26e2e5d99135d21f10d8b99e606226..bdc62da2f212cb54e9a3ae5945d3b0e602305cdc 100644 (file)
@@ -223,6 +223,12 @@ static inline void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmdp,
 #endif
 }
 
+static inline void
+tlb_remove_pmd_tlb_entry(struct mmu_gather *tlb, pmd_t *pmdp, unsigned long addr)
+{
+       tlb_add_flush(tlb, addr);
+}
+
 #define pte_free_tlb(tlb, ptep, addr)  __pte_free_tlb(tlb, ptep, addr)
 #define pmd_free_tlb(tlb, pmdp, addr)  __pmd_free_tlb(tlb, pmdp, addr)
 #define pud_free_tlb(tlb, pudp, addr)  pud_free((tlb)->mm, pudp)
index ded7c16f80cc056de147fa950acb28af98ffb062..fdbb9e369745c4b09d776a4568caa52702b7e9a7 100644 (file)
@@ -535,6 +535,8 @@ static inline void update_mmu_cache(struct vm_area_struct *vma,
 }
 #endif
 
+#define update_mmu_cache_pmd(vma, address, pmd) do { } while (0)
+
 #endif
 
 #elif defined(CONFIG_SMP)      /* !CONFIG_MMU */
index 2848857f5b62f91f7babe3ae928d932e252f723c..fbd24beeb1fad70886ea044387c873a65ef455e2 100644 (file)
@@ -24,9 +24,9 @@
 #define U8500_UART0_PHYS_BASE  (0x80120000)
 #define U8500_UART1_PHYS_BASE  (0x80121000)
 #define U8500_UART2_PHYS_BASE  (0x80007000)
-#define U8500_UART0_VIRT_BASE  (0xa8120000)
-#define U8500_UART1_VIRT_BASE  (0xa8121000)
-#define U8500_UART2_VIRT_BASE  (0xa8007000)
+#define U8500_UART0_VIRT_BASE  (0xf8120000)
+#define U8500_UART1_VIRT_BASE  (0xf8121000)
+#define U8500_UART2_VIRT_BASE  (0xf8007000)
 #define __UX500_PHYS_UART(n)   U8500_UART##n##_PHYS_BASE
 #define __UX500_VIRT_UART(n)   U8500_UART##n##_VIRT_BASE
 #endif
index f219703168366f8142321b93750e0027f1e6c6b2..282de4826abb640bd310ce8cf6099dec297803ce 100644 (file)
@@ -411,7 +411,6 @@ static struct vm_area_struct gate_vma = {
        .vm_start       = 0xffff0000,
        .vm_end         = 0xffff0000 + PAGE_SIZE,
        .vm_flags       = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC,
-       .vm_mm          = &init_mm,
 };
 
 static int __init gate_vma_init(void)
index 2acdff4c1dfea8c72c7106dff630a4870d6e70a9..180b3024bec3ab36cc2d7cdb62e92d7b2298d297 100644 (file)
@@ -174,6 +174,7 @@ clkevt32k_next_event(unsigned long delta, struct clock_event_device *dev)
 static struct clock_event_device clkevt = {
        .name           = "at91_tick",
        .features       = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+       .shift          = 32,
        .rating         = 150,
        .set_next_event = clkevt32k_next_event,
        .set_mode       = clkevt32k_mode,
@@ -264,9 +265,11 @@ void __init at91rm9200_timer_init(void)
        at91_st_write(AT91_ST_RTMR, 1);
 
        /* Setup timer clockevent, with minimum of two ticks (important!!) */
+       clkevt.mult = div_sc(AT91_SLOW_CLOCK, NSEC_PER_SEC, clkevt.shift);
+       clkevt.max_delta_ns = clockevent_delta2ns(AT91_ST_ALMV, &clkevt);
+       clkevt.min_delta_ns = clockevent_delta2ns(2, &clkevt) + 1;
        clkevt.cpumask = cpumask_of(0);
-       clockevents_config_and_register(&clkevt, AT91_SLOW_CLOCK,
-                                       2, AT91_ST_ALMV);
+       clockevents_register_device(&clkevt);
 
        /* register clocksource */
        clocksource_register_hz(&clk32k, AT91_SLOW_CLOCK);
index 13cdbcd48f51eca105add53d8a674a2ea0e5fa45..c7d670d118025eaf71a4dd145d0d3a33d300a415 100644 (file)
@@ -223,13 +223,7 @@ static void __init at91sam9n12_map_io(void)
        at91_init_sram(0, AT91SAM9N12_SRAM_BASE, AT91SAM9N12_SRAM_SIZE);
 }
 
-void __init at91sam9n12_initialize(void)
-{
-       at91_extern_irq = (1 << AT91SAM9N12_ID_IRQ0);
-}
-
 AT91_SOC_START(at91sam9n12)
        .map_io = at91sam9n12_map_io,
        .register_clocks = at91sam9n12_register_clocks,
-       .init = at91sam9n12_initialize,
 AT91_SOC_END
index 31df12029c4e9a5b32695874e95fb9e4e4c75589..2bd7f51b0b8204d92c4bde747d197ad9dc21fa36 100644 (file)
@@ -179,9 +179,9 @@ extern void __iomem *at91_pmc_base;
 #define                AT91_PMC_PCR_CMD        (0x1  <<  12)           /* Command (read=0, write=1) */
 #define                AT91_PMC_PCR_DIV(n)     ((n)  <<  16)           /* Divisor Value */
 #define                        AT91_PMC_PCR_DIV0       0x0                     /* Peripheral clock is MCK */
-#define                        AT91_PMC_PCR_DIV2       0x2                     /* Peripheral clock is MCK/2 */
-#define                        AT91_PMC_PCR_DIV4       0x4                     /* Peripheral clock is MCK/4 */
-#define                        AT91_PMC_PCR_DIV8       0x8                     /* Peripheral clock is MCK/8 */
+#define                        AT91_PMC_PCR_DIV2       0x1                     /* Peripheral clock is MCK/2 */
+#define                        AT91_PMC_PCR_DIV4       0x2                     /* Peripheral clock is MCK/4 */
+#define                        AT91_PMC_PCR_DIV8       0x3                     /* Peripheral clock is MCK/8 */
 #define                AT91_PMC_PCR_EN         (0x1  <<  28)           /* Enable */
 
 #endif
index 151259003086e8d1f0db34015742ab307b3f986a..dda9a2bd3acbb34da147542d3080770292c8771c 100644 (file)
@@ -177,7 +177,8 @@ int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode)
 static const char *step_sels[] = { "osc", "pll2_pfd2_396m", };
 static const char *pll1_sw_sels[]      = { "pll1_sys", "step", };
 static const char *periph_pre_sels[]   = { "pll2_bus", "pll2_pfd2_396m", "pll2_pfd0_352m", "pll2_198m", };
-static const char *periph_clk2_sels[]  = { "pll3_usb_otg", "osc", };
+static const char *periph_clk2_sels[]  = { "pll3_usb_otg", "osc", "osc", "dummy", };
+static const char *periph2_clk2_sels[] = { "pll3_usb_otg", "pll2_bus", };
 static const char *periph_sels[]       = { "periph_pre", "periph_clk2", };
 static const char *periph2_sels[]      = { "periph2_pre", "periph2_clk2", };
 static const char *axi_sels[]          = { "periph", "pll2_pfd2_396m", "pll3_pfd1_540m", };
@@ -185,7 +186,7 @@ static const char *audio_sels[]     = { "pll4_post_div", "pll3_pfd2_508m", "pll3_pfd
 static const char *gpu_axi_sels[]      = { "axi", "ahb", };
 static const char *gpu2d_core_sels[]   = { "axi", "pll3_usb_otg", "pll2_pfd0_352m", "pll2_pfd2_396m", };
 static const char *gpu3d_core_sels[]   = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll2_pfd2_396m", };
-static const char *gpu3d_shader_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll2_pfd9_720m", };
+static const char *gpu3d_shader_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll3_pfd0_720m", };
 static const char *ipu_sels[]          = { "mmdc_ch0_axi", "pll2_pfd2_396m", "pll3_120m", "pll3_pfd1_540m", };
 static const char *ldb_di_sels[]       = { "pll5_video", "pll2_pfd0_352m", "pll2_pfd2_396m", "mmdc_ch1_axi", "pll3_usb_otg", };
 static const char *ipu_di_pre_sels[]   = { "mmdc_ch0_axi", "pll3_usb_otg", "pll5_video_div", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll3_pfd1_540m", };
@@ -369,8 +370,8 @@ int __init mx6q_clocks_init(void)
        clk[pll1_sw]          = imx_clk_mux("pll1_sw",          base + 0xc,  2,  1, pll1_sw_sels,      ARRAY_SIZE(pll1_sw_sels));
        clk[periph_pre]       = imx_clk_mux("periph_pre",       base + 0x18, 18, 2, periph_pre_sels,   ARRAY_SIZE(periph_pre_sels));
        clk[periph2_pre]      = imx_clk_mux("periph2_pre",      base + 0x18, 21, 2, periph_pre_sels,   ARRAY_SIZE(periph_pre_sels));
-       clk[periph_clk2_sel]  = imx_clk_mux("periph_clk2_sel",  base + 0x18, 12, 1, periph_clk2_sels,  ARRAY_SIZE(periph_clk2_sels));
-       clk[periph2_clk2_sel] = imx_clk_mux("periph2_clk2_sel", base + 0x18, 20, 1, periph_clk2_sels,  ARRAY_SIZE(periph_clk2_sels));
+       clk[periph_clk2_sel]  = imx_clk_mux("periph_clk2_sel",  base + 0x18, 12, 2, periph_clk2_sels,  ARRAY_SIZE(periph_clk2_sels));
+       clk[periph2_clk2_sel] = imx_clk_mux("periph2_clk2_sel", base + 0x18, 20, 1, periph2_clk2_sels, ARRAY_SIZE(periph2_clk2_sels));
        clk[axi_sel]          = imx_clk_mux("axi_sel",          base + 0x14, 6,  2, axi_sels,          ARRAY_SIZE(axi_sels));
        clk[esai_sel]         = imx_clk_mux("esai_sel",         base + 0x20, 19, 2, audio_sels,        ARRAY_SIZE(audio_sels));
        clk[asrc_sel]         = imx_clk_mux("asrc_sel",         base + 0x30, 7,  2, audio_sels,        ARRAY_SIZE(audio_sels));
@@ -498,7 +499,7 @@ int __init mx6q_clocks_init(void)
        clk[ldb_di1]      = imx_clk_gate2("ldb_di1",       "ldb_di1_podf",      base + 0x74, 14);
        clk[ipu2_di1]     = imx_clk_gate2("ipu2_di1",      "ipu2_di1_sel",      base + 0x74, 10);
        clk[hsi_tx]       = imx_clk_gate2("hsi_tx",        "hsi_tx_podf",       base + 0x74, 16);
-       clk[mlb]          = imx_clk_gate2("mlb",           "pll8_mlb",          base + 0x74, 18);
+       clk[mlb]          = imx_clk_gate2("mlb",           "axi",               base + 0x74, 18);
        clk[mmdc_ch0_axi] = imx_clk_gate2("mmdc_ch0_axi",  "mmdc_ch0_axi_podf", base + 0x74, 20);
        clk[mmdc_ch1_axi] = imx_clk_gate2("mmdc_ch1_axi",  "mmdc_ch1_axi_podf", base + 0x74, 22);
        clk[ocram]        = imx_clk_gate2("ocram",         "ahb",               base + 0x74, 28);
index 67b9c48dcafe7dc1ee281c49ece9de88338297f4..627f16f0e9d1d393d48527e50f25c5e22c81987d 100644 (file)
        .section ".text.head", "ax"
 
 #ifdef CONFIG_SMP
+diag_reg_offset:
+       .word   g_diag_reg - .
+
+       .macro  set_diag_reg
+       adr     r0, diag_reg_offset
+       ldr     r1, [r0]
+       add     r1, r1, r0              @ r1 = physical &g_diag_reg
+       ldr     r0, [r1]
+       mcr     p15, 0, r0, c15, c0, 1  @ write diagnostic register
+       .endm
+
 ENTRY(v7_secondary_startup)
        bl      v7_invalidate_l1
+       set_diag_reg
        b       secondary_startup
 ENDPROC(v7_secondary_startup)
 #endif
index 4a69305db65e395366187a84cde322e37fc99e94..c6e1ab5448822c8aaed044413f726b0dc8c47a39 100644 (file)
@@ -12,6 +12,7 @@
 
 #include <linux/init.h>
 #include <linux/smp.h>
+#include <asm/cacheflush.h>
 #include <asm/page.h>
 #include <asm/smp_scu.h>
 #include <asm/mach/map.h>
@@ -21,6 +22,7 @@
 
 #define SCU_STANDBY_ENABLE     (1 << 5)
 
+u32 g_diag_reg;
 static void __iomem *scu_base;
 
 static struct map_desc scu_io_desc __initdata = {
@@ -80,6 +82,18 @@ void imx_smp_prepare(void)
 static void __init imx_smp_prepare_cpus(unsigned int max_cpus)
 {
        imx_smp_prepare();
+
+       /*
+        * The diagnostic register holds the errata bits.  Mostly bootloader
+        * does not bring up secondary cores, so that when errata bits are set
+        * in bootloader, they are set only for boot cpu.  But on a SMP
+        * configuration, it should be equally done on every single core.
+        * Read the register from boot cpu here, and will replicate it into
+        * secondary cores when booting them.
+        */
+       asm("mrc p15, 0, %0, c15, c0, 1" : "=r" (g_diag_reg) : : "cc");
+       __cpuc_flush_dcache_area(&g_diag_reg, sizeof(g_diag_reg));
+       outer_clean_range(__pa(&g_diag_reg), __pa(&g_diag_reg + 1));
 }
 
 struct smp_operations  imx_smp_ops __initdata = {
index c2cae69e6d2bb9343798a7a3398ce174850d59cf..f389228975637cd85d3f9f9444ae30e0f34537cc 100644 (file)
@@ -528,12 +528,6 @@ void __init kirkwood_init_early(void)
 {
        orion_time_set_base(TIMER_VIRT_BASE);
 
-       /*
-        * Some Kirkwood devices allocate their coherent buffers from atomic
-        * context. Increase size of atomic coherent pool to make sure such
-        * the allocations won't fail.
-        */
-       init_dma_coherent_pool_size(SZ_1M);
        mvebu_mbus_init("marvell,kirkwood-mbus",
                        BRIDGE_WINS_BASE, BRIDGE_WINS_SZ,
                        DDR_WINDOW_CPU_BASE, DDR_WINDOW_CPU_SZ);
index 283abff902287357a27da54427a390432317bca2..e1267d6b468f1f6d0d0a0e7efa40391bff077183 100644 (file)
@@ -124,7 +124,7 @@ static void __init qnap_ts219_init(void)
 static int __init ts219_pci_init(void)
 {
        if (machine_is_ts219())
-               kirkwood_pcie_init(KW_PCIE0);
+               kirkwood_pcie_init(KW_PCIE1 | KW_PCIE0);
 
        return 0;
 }
index e11acbb0a46d4316c82f23cb333744cbab41d89f..80a8bcacd9d539c0a684e3beaa927b07dd720566 100644 (file)
@@ -15,6 +15,7 @@ config ARCH_MVEBU
        select MVEBU_CLK_GATING
        select MVEBU_MBUS
        select ZONE_DMA if ARM_LPAE
+       select ARCH_REQUIRE_GPIOLIB
 
 if ARCH_MVEBU
 
index 42a4cb3087e23ab04ea2e7e22971c1f38aeb9aa2..1c48890bb72b2c7ad1301cdc9f8bad007362bf57 100644 (file)
@@ -53,13 +53,6 @@ void __init armada_370_xp_init_early(void)
 {
        char *mbus_soc_name;
 
-       /*
-        * Some Armada 370/XP devices allocate their coherent buffers
-        * from atomic context. Increase size of atomic coherent pool
-        * to make sure such the allocations won't fail.
-        */
-       init_dma_coherent_pool_size(SZ_1M);
-
        /*
         * This initialization will be replaced by a DT-based
         * initialization once the mvebu-mbus driver gains DT support.
index 68ab858e27b754bea93264889ab9b020cf67d698..a94b3a718d1a771dda53f5e06542fb6a6989cee8 100644 (file)
@@ -345,6 +345,7 @@ static int __init omap1_system_dma_init(void)
                dev_err(&pdev->dev,
                        "%s: Memory allocation failed for d->chan!\n",
                        __func__);
+               ret = -ENOMEM;
                goto exit_release_d;
        }
 
index 6ebc7803bc3e37b48ff9c1b394a39e2a3dff9a28..af3544ce4f0273b8eb8b43c22295a5ae6ced76a3 100644 (file)
@@ -454,9 +454,29 @@ DEFINE_CLK_GATE(cefuse_fck, "sys_clkin_ck", &sys_clkin_ck, 0x0,
  */
 DEFINE_CLK_FIXED_FACTOR(clkdiv32k_ck, "clk_24mhz", &clk_24mhz, 0x0, 1, 732);
 
-DEFINE_CLK_GATE(clkdiv32k_ick, "clkdiv32k_ck", &clkdiv32k_ck, 0x0,
-               AM33XX_CM_PER_CLKDIV32K_CLKCTRL, AM33XX_MODULEMODE_SWCTRL_SHIFT,
-               0x0, NULL);
+static struct clk clkdiv32k_ick;
+
+static const char *clkdiv32k_ick_parent_names[] = {
+       "clkdiv32k_ck",
+};
+
+static const struct clk_ops clkdiv32k_ick_ops = {
+       .enable         = &omap2_dflt_clk_enable,
+       .disable        = &omap2_dflt_clk_disable,
+       .is_enabled     = &omap2_dflt_clk_is_enabled,
+       .init           = &omap2_init_clk_clkdm,
+};
+
+static struct clk_hw_omap clkdiv32k_ick_hw = {
+       .hw     = {
+               .clk    = &clkdiv32k_ick,
+       },
+       .enable_reg     = AM33XX_CM_PER_CLKDIV32K_CLKCTRL,
+       .enable_bit     = AM33XX_MODULEMODE_SWCTRL_SHIFT,
+       .clkdm_name     = "clk_24mhz_clkdm",
+};
+
+DEFINE_STRUCT_CLK(clkdiv32k_ick, clkdiv32k_ick_parent_names, clkdiv32k_ick_ops);
 
 /* "usbotg_fck" is an additional clock and not really a modulemode */
 DEFINE_CLK_GATE(usbotg_fck, "dpll_per_ck", &dpll_per_ck, 0x0,
index d25a95fe99216c582f97b0a0aee860c3573eaf68..7341eff63f56df8f58d5b72d8db9a71feb86112d 100644 (file)
@@ -1356,13 +1356,27 @@ static void _enable_sysc(struct omap_hwmod *oh)
 
        clkdm = _get_clkdm(oh);
        if (sf & SYSC_HAS_SIDLEMODE) {
+               if (oh->flags & HWMOD_SWSUP_SIDLE ||
+                   oh->flags & HWMOD_SWSUP_SIDLE_ACT) {
+                       idlemode = HWMOD_IDLEMODE_NO;
+               } else {
+                       if (sf & SYSC_HAS_ENAWAKEUP)
+                               _enable_wakeup(oh, &v);
+                       if (oh->class->sysc->idlemodes & SIDLE_SMART_WKUP)
+                               idlemode = HWMOD_IDLEMODE_SMART_WKUP;
+                       else
+                               idlemode = HWMOD_IDLEMODE_SMART;
+               }
+
+               /*
+                * This is special handling for some IPs like
+                * 32k sync timer. Force them to idle!
+                */
                clkdm_act = (clkdm && clkdm->flags & CLKDM_ACTIVE_WITH_MPU);
                if (clkdm_act && !(oh->class->sysc->idlemodes &
                                   (SIDLE_SMART | SIDLE_SMART_WKUP)))
                        idlemode = HWMOD_IDLEMODE_FORCE;
-               else
-                       idlemode = (oh->flags & HWMOD_SWSUP_SIDLE) ?
-                               HWMOD_IDLEMODE_NO : HWMOD_IDLEMODE_SMART;
+
                _set_slave_idlemode(oh, idlemode, &v);
        }
 
@@ -1391,10 +1405,6 @@ static void _enable_sysc(struct omap_hwmod *oh)
            (sf & SYSC_HAS_CLOCKACTIVITY))
                _set_clockactivity(oh, oh->class->sysc->clockact, &v);
 
-       /* If slave is in SMARTIDLE, also enable wakeup */
-       if ((sf & SYSC_HAS_SIDLEMODE) && !(oh->flags & HWMOD_SWSUP_SIDLE))
-               _enable_wakeup(oh, &v);
-
        _write_sysconfig(v, oh);
 
        /*
@@ -1430,13 +1440,16 @@ static void _idle_sysc(struct omap_hwmod *oh)
        sf = oh->class->sysc->sysc_flags;
 
        if (sf & SYSC_HAS_SIDLEMODE) {
-               /* XXX What about HWMOD_IDLEMODE_SMART_WKUP? */
-               if (oh->flags & HWMOD_SWSUP_SIDLE ||
-                   !(oh->class->sysc->idlemodes &
-                     (SIDLE_SMART | SIDLE_SMART_WKUP)))
+               if (oh->flags & HWMOD_SWSUP_SIDLE) {
                        idlemode = HWMOD_IDLEMODE_FORCE;
-               else
-                       idlemode = HWMOD_IDLEMODE_SMART;
+               } else {
+                       if (sf & SYSC_HAS_ENAWAKEUP)
+                               _enable_wakeup(oh, &v);
+                       if (oh->class->sysc->idlemodes & SIDLE_SMART_WKUP)
+                               idlemode = HWMOD_IDLEMODE_SMART_WKUP;
+                       else
+                               idlemode = HWMOD_IDLEMODE_SMART;
+               }
                _set_slave_idlemode(oh, idlemode, &v);
        }
 
@@ -1455,10 +1468,6 @@ static void _idle_sysc(struct omap_hwmod *oh)
                _set_master_standbymode(oh, idlemode, &v);
        }
 
-       /* If slave is in SMARTIDLE, also enable wakeup */
-       if ((sf & SYSC_HAS_SIDLEMODE) && !(oh->flags & HWMOD_SWSUP_SIDLE))
-               _enable_wakeup(oh, &v);
-
        _write_sysconfig(v, oh);
 }
 
@@ -2065,7 +2074,7 @@ static int _omap4_get_context_lost(struct omap_hwmod *oh)
  * do so is present in the hwmod data, then call it and pass along the
  * return value; otherwise, return 0.
  */
-static int __init _enable_preprogram(struct omap_hwmod *oh)
+static int _enable_preprogram(struct omap_hwmod *oh)
 {
        if (!oh->class->enable_preprogram)
                return 0;
@@ -2245,42 +2254,6 @@ static int _idle(struct omap_hwmod *oh)
        return 0;
 }
 
-/**
- * omap_hwmod_set_ocp_autoidle - set the hwmod's OCP autoidle bit
- * @oh: struct omap_hwmod *
- * @autoidle: desired AUTOIDLE bitfield value (0 or 1)
- *
- * Sets the IP block's OCP autoidle bit in hardware, and updates our
- * local copy. Intended to be used by drivers that require
- * direct manipulation of the AUTOIDLE bits.
- * Returns -EINVAL if @oh is null or is not in the ENABLED state, or passes
- * along the return value from _set_module_autoidle().
- *
- * Any users of this function should be scrutinized carefully.
- */
-int omap_hwmod_set_ocp_autoidle(struct omap_hwmod *oh, u8 autoidle)
-{
-       u32 v;
-       int retval = 0;
-       unsigned long flags;
-
-       if (!oh || oh->_state != _HWMOD_STATE_ENABLED)
-               return -EINVAL;
-
-       spin_lock_irqsave(&oh->_lock, flags);
-
-       v = oh->_sysc_cache;
-
-       retval = _set_module_autoidle(oh, autoidle, &v);
-
-       if (!retval)
-               _write_sysconfig(v, oh);
-
-       spin_unlock_irqrestore(&oh->_lock, flags);
-
-       return retval;
-}
-
 /**
  * _shutdown - shutdown an omap_hwmod
  * @oh: struct omap_hwmod *
@@ -3179,38 +3152,6 @@ error:
        return ret;
 }
 
-/**
- * omap_hwmod_set_slave_idlemode - set the hwmod's OCP slave idlemode
- * @oh: struct omap_hwmod *
- * @idlemode: SIDLEMODE field bits (shifted to bit 0)
- *
- * Sets the IP block's OCP slave idlemode in hardware, and updates our
- * local copy.  Intended to be used by drivers that have some erratum
- * that requires direct manipulation of the SIDLEMODE bits.  Returns
- * -EINVAL if @oh is null, or passes along the return value from
- * _set_slave_idlemode().
- *
- * XXX Does this function have any current users?  If not, we should
- * remove it; it is better to let the rest of the hwmod code handle this.
- * Any users of this function should be scrutinized carefully.
- */
-int omap_hwmod_set_slave_idlemode(struct omap_hwmod *oh, u8 idlemode)
-{
-       u32 v;
-       int retval = 0;
-
-       if (!oh)
-               return -EINVAL;
-
-       v = oh->_sysc_cache;
-
-       retval = _set_slave_idlemode(oh, idlemode, &v);
-       if (!retval)
-               _write_sysconfig(v, oh);
-
-       return retval;
-}
-
 /**
  * omap_hwmod_lookup - look up a registered omap_hwmod by name
  * @name: name of the omap_hwmod to look up
index fe5962921f07244e602429b758f0d5ccecb7398c..0c898f58ac9bb490e8873a24074e53c1480530a6 100644 (file)
@@ -463,6 +463,9 @@ struct omap_hwmod_omap4_prcm {
  *     is kept in force-standby mode. Failing to do so causes PM problems
  *     with musb on OMAP3630 at least. Note that musb has a dedicated register
  *     to control MSTANDBY signal when MIDLEMODE is set to force-standby.
+ * HWMOD_SWSUP_SIDLE_ACT: omap_hwmod code should manually bring the module
+ *     out of idle, but rely on smart-idle to the put it back in idle,
+ *     so the wakeups are still functional (Only known case for now is UART)
  */
 #define HWMOD_SWSUP_SIDLE                      (1 << 0)
 #define HWMOD_SWSUP_MSTANDBY                   (1 << 1)
@@ -476,6 +479,7 @@ struct omap_hwmod_omap4_prcm {
 #define HWMOD_EXT_OPT_MAIN_CLK                 (1 << 9)
 #define HWMOD_BLOCK_WFI                                (1 << 10)
 #define HWMOD_FORCE_MSTANDBY                   (1 << 11)
+#define HWMOD_SWSUP_SIDLE_ACT                  (1 << 12)
 
 /*
  * omap_hwmod._int_flags definitions
@@ -641,9 +645,6 @@ int omap_hwmod_read_hardreset(struct omap_hwmod *oh, const char *name);
 int omap_hwmod_enable_clocks(struct omap_hwmod *oh);
 int omap_hwmod_disable_clocks(struct omap_hwmod *oh);
 
-int omap_hwmod_set_slave_idlemode(struct omap_hwmod *oh, u8 idlemode);
-int omap_hwmod_set_ocp_autoidle(struct omap_hwmod *oh, u8 autoidle);
-
 int omap_hwmod_reset(struct omap_hwmod *oh);
 void omap_hwmod_ocp_barrier(struct omap_hwmod *oh);
 
index c8c64b3e1acc009efa24b91da269034b8603e714..d05fc7b54567f0dbb6597a1d641ce130caf7ee9b 100644 (file)
@@ -512,6 +512,7 @@ struct omap_hwmod omap2xxx_uart1_hwmod = {
        .mpu_irqs       = omap2_uart1_mpu_irqs,
        .sdma_reqs      = omap2_uart1_sdma_reqs,
        .main_clk       = "uart1_fck",
+       .flags          = HWMOD_SWSUP_SIDLE_ACT,
        .prcm           = {
                .omap2 = {
                        .module_offs = CORE_MOD,
@@ -531,6 +532,7 @@ struct omap_hwmod omap2xxx_uart2_hwmod = {
        .mpu_irqs       = omap2_uart2_mpu_irqs,
        .sdma_reqs      = omap2_uart2_sdma_reqs,
        .main_clk       = "uart2_fck",
+       .flags          = HWMOD_SWSUP_SIDLE_ACT,
        .prcm           = {
                .omap2 = {
                        .module_offs = CORE_MOD,
@@ -550,6 +552,7 @@ struct omap_hwmod omap2xxx_uart3_hwmod = {
        .mpu_irqs       = omap2_uart3_mpu_irqs,
        .sdma_reqs      = omap2_uart3_sdma_reqs,
        .main_clk       = "uart3_fck",
+       .flags          = HWMOD_SWSUP_SIDLE_ACT,
        .prcm           = {
                .omap2 = {
                        .module_offs = CORE_MOD,
index 01d8f324450a951f89174b4cebdf82f8b9dad6b1..075f7cc510261ee959352daf07818370b4188ab9 100644 (file)
@@ -1995,6 +1995,7 @@ static struct omap_hwmod am33xx_uart1_hwmod = {
        .name           = "uart1",
        .class          = &uart_class,
        .clkdm_name     = "l4_wkup_clkdm",
+       .flags          = HWMOD_SWSUP_SIDLE_ACT,
        .mpu_irqs       = am33xx_uart1_irqs,
        .sdma_reqs      = uart1_edma_reqs,
        .main_clk       = "dpll_per_m2_div4_wkupdm_ck",
@@ -2015,6 +2016,7 @@ static struct omap_hwmod am33xx_uart2_hwmod = {
        .name           = "uart2",
        .class          = &uart_class,
        .clkdm_name     = "l4ls_clkdm",
+       .flags          = HWMOD_SWSUP_SIDLE_ACT,
        .mpu_irqs       = am33xx_uart2_irqs,
        .sdma_reqs      = uart1_edma_reqs,
        .main_clk       = "dpll_per_m2_div4_ck",
@@ -2042,6 +2044,7 @@ static struct omap_hwmod am33xx_uart3_hwmod = {
        .name           = "uart3",
        .class          = &uart_class,
        .clkdm_name     = "l4ls_clkdm",
+       .flags          = HWMOD_SWSUP_SIDLE_ACT,
        .mpu_irqs       = am33xx_uart3_irqs,
        .sdma_reqs      = uart3_edma_reqs,
        .main_clk       = "dpll_per_m2_div4_ck",
@@ -2062,6 +2065,7 @@ static struct omap_hwmod am33xx_uart4_hwmod = {
        .name           = "uart4",
        .class          = &uart_class,
        .clkdm_name     = "l4ls_clkdm",
+       .flags          = HWMOD_SWSUP_SIDLE_ACT,
        .mpu_irqs       = am33xx_uart4_irqs,
        .sdma_reqs      = uart1_edma_reqs,
        .main_clk       = "dpll_per_m2_div4_ck",
@@ -2082,6 +2086,7 @@ static struct omap_hwmod am33xx_uart5_hwmod = {
        .name           = "uart5",
        .class          = &uart_class,
        .clkdm_name     = "l4ls_clkdm",
+       .flags          = HWMOD_SWSUP_SIDLE_ACT,
        .mpu_irqs       = am33xx_uart5_irqs,
        .sdma_reqs      = uart1_edma_reqs,
        .main_clk       = "dpll_per_m2_div4_ck",
@@ -2102,6 +2107,7 @@ static struct omap_hwmod am33xx_uart6_hwmod = {
        .name           = "uart6",
        .class          = &uart_class,
        .clkdm_name     = "l4ls_clkdm",
+       .flags          = HWMOD_SWSUP_SIDLE_ACT,
        .mpu_irqs       = am33xx_uart6_irqs,
        .sdma_reqs      = uart1_edma_reqs,
        .main_clk       = "dpll_per_m2_div4_ck",
index 4083606ea1da15e7efeb279d7c33c3f3cc7618b3..31c7126eb3bb65d724cfc71ed0c0733a4202e4d6 100644 (file)
@@ -490,6 +490,7 @@ static struct omap_hwmod omap3xxx_uart1_hwmod = {
        .mpu_irqs       = omap2_uart1_mpu_irqs,
        .sdma_reqs      = omap2_uart1_sdma_reqs,
        .main_clk       = "uart1_fck",
+       .flags          = HWMOD_SWSUP_SIDLE_ACT,
        .prcm           = {
                .omap2 = {
                        .module_offs = CORE_MOD,
@@ -508,6 +509,7 @@ static struct omap_hwmod omap3xxx_uart2_hwmod = {
        .mpu_irqs       = omap2_uart2_mpu_irqs,
        .sdma_reqs      = omap2_uart2_sdma_reqs,
        .main_clk       = "uart2_fck",
+       .flags          = HWMOD_SWSUP_SIDLE_ACT,
        .prcm           = {
                .omap2 = {
                        .module_offs = CORE_MOD,
@@ -526,6 +528,7 @@ static struct omap_hwmod omap3xxx_uart3_hwmod = {
        .mpu_irqs       = omap2_uart3_mpu_irqs,
        .sdma_reqs      = omap2_uart3_sdma_reqs,
        .main_clk       = "uart3_fck",
+       .flags          = HWMOD_SWSUP_SIDLE_ACT,
        .prcm           = {
                .omap2 = {
                        .module_offs = OMAP3430_PER_MOD,
@@ -555,6 +558,7 @@ static struct omap_hwmod omap36xx_uart4_hwmod = {
        .mpu_irqs       = uart4_mpu_irqs,
        .sdma_reqs      = uart4_sdma_reqs,
        .main_clk       = "uart4_fck",
+       .flags          = HWMOD_SWSUP_SIDLE_ACT,
        .prcm           = {
                .omap2 = {
                        .module_offs = OMAP3430_PER_MOD,
index eaba9dc91a0d9824a530cf185537a28a881b5a24..848b6dc67590716f7663151f46a5809f097e9cf1 100644 (file)
@@ -3434,6 +3434,7 @@ static struct omap_hwmod omap44xx_uart1_hwmod = {
        .name           = "uart1",
        .class          = &omap44xx_uart_hwmod_class,
        .clkdm_name     = "l4_per_clkdm",
+       .flags          = HWMOD_SWSUP_SIDLE_ACT,
        .mpu_irqs       = omap44xx_uart1_irqs,
        .sdma_reqs      = omap44xx_uart1_sdma_reqs,
        .main_clk       = "func_48m_fclk",
@@ -3462,6 +3463,7 @@ static struct omap_hwmod omap44xx_uart2_hwmod = {
        .name           = "uart2",
        .class          = &omap44xx_uart_hwmod_class,
        .clkdm_name     = "l4_per_clkdm",
+       .flags          = HWMOD_SWSUP_SIDLE_ACT,
        .mpu_irqs       = omap44xx_uart2_irqs,
        .sdma_reqs      = omap44xx_uart2_sdma_reqs,
        .main_clk       = "func_48m_fclk",
@@ -3490,7 +3492,8 @@ static struct omap_hwmod omap44xx_uart3_hwmod = {
        .name           = "uart3",
        .class          = &omap44xx_uart_hwmod_class,
        .clkdm_name     = "l4_per_clkdm",
-       .flags          = HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET,
+       .flags          = HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET |
+                               HWMOD_SWSUP_SIDLE_ACT,
        .mpu_irqs       = omap44xx_uart3_irqs,
        .sdma_reqs      = omap44xx_uart3_sdma_reqs,
        .main_clk       = "func_48m_fclk",
@@ -3519,6 +3522,7 @@ static struct omap_hwmod omap44xx_uart4_hwmod = {
        .name           = "uart4",
        .class          = &omap44xx_uart_hwmod_class,
        .clkdm_name     = "l4_per_clkdm",
+       .flags          = HWMOD_SWSUP_SIDLE_ACT,
        .mpu_irqs       = omap44xx_uart4_irqs,
        .sdma_reqs      = omap44xx_uart4_sdma_reqs,
        .main_clk       = "func_48m_fclk",
index 8396b5b7e912d91e48adbcc3b785041845b9f677..f6601563aa6903f93e04f9656a58593907f89b0e 100644 (file)
@@ -95,38 +95,9 @@ static void omap_uart_enable_wakeup(struct device *dev, bool enable)
                omap_hwmod_disable_wakeup(od->hwmods[0]);
 }
 
-/*
- * Errata i291: [UART]:Cannot Acknowledge Idle Requests
- * in Smartidle Mode When Configured for DMA Operations.
- * WA: configure uart in force idle mode.
- */
-static void omap_uart_set_noidle(struct device *dev)
-{
-       struct platform_device *pdev = to_platform_device(dev);
-       struct omap_device *od = to_omap_device(pdev);
-
-       omap_hwmod_set_slave_idlemode(od->hwmods[0], HWMOD_IDLEMODE_NO);
-}
-
-static void omap_uart_set_smartidle(struct device *dev)
-{
-       struct platform_device *pdev = to_platform_device(dev);
-       struct omap_device *od = to_omap_device(pdev);
-       u8 idlemode;
-
-       if (od->hwmods[0]->class->sysc->idlemodes & SIDLE_SMART_WKUP)
-               idlemode = HWMOD_IDLEMODE_SMART_WKUP;
-       else
-               idlemode = HWMOD_IDLEMODE_SMART;
-
-       omap_hwmod_set_slave_idlemode(od->hwmods[0], idlemode);
-}
-
 #else
 static void omap_uart_enable_wakeup(struct device *dev, bool enable)
 {}
-static void omap_uart_set_noidle(struct device *dev) {}
-static void omap_uart_set_smartidle(struct device *dev) {}
 #endif /* CONFIG_PM */
 
 #ifdef CONFIG_OMAP_MUX
@@ -299,8 +270,6 @@ void __init omap_serial_init_port(struct omap_board_data *bdata,
        omap_up.uartclk = OMAP24XX_BASE_BAUD * 16;
        omap_up.flags = UPF_BOOT_AUTOCONF;
        omap_up.get_context_loss_count = omap_pm_get_dev_context_loss_count;
-       omap_up.set_forceidle = omap_uart_set_smartidle;
-       omap_up.set_noidle = omap_uart_set_noidle;
        omap_up.enable_wakeup = omap_uart_enable_wakeup;
        omap_up.dma_rx_buf_size = info->dma_rx_buf_size;
        omap_up.dma_rx_timeout = info->dma_rx_timeout;
index b97fd672e89d74f40e3ebfc0b1e18c365be785f3..f8a6db9239bf3c3ff7a88c29925cdce0961590cb 100644 (file)
@@ -199,13 +199,6 @@ void __init orion5x_init_early(void)
 
        orion_time_set_base(TIMER_VIRT_BASE);
 
-       /*
-        * Some Orion5x devices allocate their coherent buffers from atomic
-        * context. Increase size of atomic coherent pool to make sure such
-        * the allocations won't fail.
-        */
-       init_dma_coherent_pool_size(SZ_1M);
-
        /* Initialize the MBUS driver */
        orion5x_pcie_id(&dev, &rev);
        if (dev == MV88F5281_DEV_ID)
index 91052855cc1216245eb71fe14cb13d5e5f85c63d..b9594e911ce7680d28448fa50cf854ceb91b33bf 100644 (file)
@@ -212,8 +212,8 @@ static struct platform_device *marzen_devices[] __initdata = {
 static struct usb_phy *phy;
 static int usb_power_on(struct platform_device *pdev)
 {
-       if (!phy)
-               return -EIO;
+       if (IS_ERR(phy))
+               return PTR_ERR(phy);
 
        pm_runtime_enable(&pdev->dev);
        pm_runtime_get_sync(&pdev->dev);
@@ -225,7 +225,7 @@ static int usb_power_on(struct platform_device *pdev)
 
 static void usb_power_off(struct platform_device *pdev)
 {
-       if (!phy)
+       if (IS_ERR(phy))
                return;
 
        usb_phy_shutdown(phy);
index d259c782d742873f0e0c53b1a43e7bcd85069286..5b045e302b4359d65b91ac31110dd566d2e10391 100644 (file)
@@ -1,5 +1,6 @@
 config ARCH_SUNXI
        bool "Allwinner A1X SOCs" if ARCH_MULTI_V7
+       select ARCH_REQUIRE_GPIOLIB
        select CLKSRC_MMIO
        select CLKSRC_OF
        select COMMON_CLK
index 6a4387e39df809f1b21d899b89d2212924ae19cd..b19b07204aafbeb53ced9f4226164ecd9c036cff 100644 (file)
@@ -51,6 +51,7 @@ config MACH_MOP500
        bool "U8500 Development platform, MOP500 versions"
        select I2C
        select I2C_NOMADIK
+       select REGULATOR
        select REGULATOR_FIXED_VOLTAGE
        select SOC_BUS
        select UX500_SOC_DB8500
index 3cd555ac6d0a3e5c81478dfbf71f79f10e72b73b..78389de94dde34f6eaee0f73c479d33eda4846dd 100644 (file)
@@ -623,7 +623,7 @@ static void __init mop500_init_machine(void)
        sdi0_reg_info.gpios[0].gpio = GPIO_SDMMC_1V8_3V_SEL;
 
        mop500_pinmaps_init();
-       parent = u8500_init_devices(&ab8500_platdata);
+       parent = u8500_init_devices();
 
        for (i = 0; i < ARRAY_SIZE(mop500_platform_devs); i++)
                mop500_platform_devs[i]->dev.parent = parent;
@@ -660,7 +660,7 @@ static void __init snowball_init_machine(void)
        sdi0_reg_info.gpios[0].gpio = SNOWBALL_SDMMC_1V8_3V_GPIO;
 
        snowball_pinmaps_init();
-       parent = u8500_init_devices(&ab8500_platdata);
+       parent = u8500_init_devices();
 
        for (i = 0; i < ARRAY_SIZE(snowball_platform_devs); i++)
                snowball_platform_devs[i]->dev.parent = parent;
@@ -698,7 +698,7 @@ static void __init hrefv60_init_machine(void)
        sdi0_reg_info.gpios[0].gpio = HREFV60_SDMMC_1V8_3V_GPIO;
 
        hrefv60_pinmaps_init();
-       parent = u8500_init_devices(&ab8500_platdata);
+       parent = u8500_init_devices();
 
        for (i = 0; i < ARRAY_SIZE(mop500_platform_devs); i++)
                mop500_platform_devs[i]->dev.parent = parent;
index e90b5ab23b6daf7e691bbff5b74fd6c165e96518..46cca52890bcfd486f30018556059c12bcf22391 100644 (file)
@@ -206,7 +206,7 @@ static struct device * __init db8500_soc_device_init(void)
 /*
  * This function is called from the board init
  */
-struct device * __init u8500_init_devices(struct ab8500_platform_data *ab8500)
+struct device * __init u8500_init_devices(void)
 {
        struct device *parent;
        int i;
@@ -220,8 +220,6 @@ struct device * __init u8500_init_devices(struct ab8500_platform_data *ab8500)
        for (i = 0; i < ARRAY_SIZE(platform_devs); i++)
                platform_devs[i]->dev.parent = parent;
 
-       db8500_prcmu_device.dev.platform_data = ab8500;
-
        platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs));
 
        return parent;
@@ -278,7 +276,7 @@ static struct of_dev_auxdata u8500_auxdata_lookup[] __initdata = {
        OF_DEV_AUXDATA("st,nomadik-i2c", 0x8012a000, "nmk-i2c.4", NULL),
        OF_DEV_AUXDATA("stericsson,db8500-prcmu", 0x80157000, "db8500-prcmu",
                        &db8500_prcmu_pdata),
-       OF_DEV_AUXDATA("smsc,lan9115", 0x50000000, "smsc911x", NULL),
+       OF_DEV_AUXDATA("smsc,lan9115", 0x50000000, "smsc911x.0", NULL),
        /* Requires device name bindings. */
        OF_DEV_AUXDATA("stericsson,nmk-pinctrl", U8500_PRCMU_BASE,
                "pinctrl-db8500", NULL),
index bddce2b493722f84c5821103a38eea4a85d8833d..cad3ca86c540f7eb67c454ce44f0317b80312ad3 100644 (file)
@@ -18,7 +18,7 @@
 void __init ux500_map_io(void);
 extern void __init u8500_map_io(void);
 
-extern struct device * __init u8500_init_devices(struct ab8500_platform_data *ab8500);
+extern struct device * __init u8500_init_devices(void);
 
 extern void __init ux500_init_irq(void);
 extern void __init ux500_init_late(void);
index 1dd281efc02035dac37cc971a0db4c69c98c8a11..f5c33df7a5971731844478e9a29024c660c35c52 100644 (file)
@@ -173,6 +173,7 @@ static const char * const vt8500_dt_compat[] = {
        "wm,wm8505",
        "wm,wm8750",
        "wm,wm8850",
+       NULL
 };
 
 DT_MACHINE_START(WMT_DT, "VIA/Wondermedia SoC (Device Tree Support)")
index ee558a01f390925ca016f901697091660be48af4..ecfe6e53f6e03ffe7a12bf0776b784106f7efe19 100644 (file)
@@ -16,6 +16,7 @@ obj-$(CONFIG_MODULES)         += proc-syms.o
 
 obj-$(CONFIG_ALIGNMENT_TRAP)   += alignment.o
 obj-$(CONFIG_HIGHMEM)          += highmem.o
+obj-$(CONFIG_HUGETLB_PAGE)     += hugetlbpage.o
 
 obj-$(CONFIG_CPU_ABRT_NOMMU)   += abort-nommu.o
 obj-$(CONFIG_CPU_ABRT_EV4)     += abort-ev4.o
index ef3e0f3aac96261d1c8e73671a00419c977902bc..9674476a75dcd2151dbfe298c7c00ecef2ec20cd 100644 (file)
@@ -250,7 +250,7 @@ static void __dma_free_buffer(struct page *page, size_t size)
 
 #ifdef CONFIG_MMU
 #ifdef CONFIG_HUGETLB_PAGE
-#error ARM Coherent DMA allocator does not (yet) support huge TLB
+#warning ARM Coherent DMA allocator does not (yet) support huge TLB
 #endif
 
 static void *__alloc_from_contiguous(struct device *dev, size_t size,
index 0d473cce501c137e8c87c40f9ccb455d6ec275eb..370640780d57ed788650b02387e84a712477c15c 100644 (file)
@@ -17,6 +17,7 @@
 #include <asm/highmem.h>
 #include <asm/smp_plat.h>
 #include <asm/tlbflush.h>
+#include <linux/hugetlb.h>
 
 #include "mm.h"
 
@@ -168,19 +169,23 @@ void __flush_dcache_page(struct address_space *mapping, struct page *page)
         * coherent with the kernels mapping.
         */
        if (!PageHighMem(page)) {
-               __cpuc_flush_dcache_area(page_address(page), PAGE_SIZE);
+               size_t page_size = PAGE_SIZE << compound_order(page);
+               __cpuc_flush_dcache_area(page_address(page), page_size);
        } else {
-               void *addr;
-
+               unsigned long i;
                if (cache_is_vipt_nonaliasing()) {
-                       addr = kmap_atomic(page);
-                       __cpuc_flush_dcache_area(addr, PAGE_SIZE);
-                       kunmap_atomic(addr);
-               } else {
-                       addr = kmap_high_get(page);
-                       if (addr) {
+                       for (i = 0; i < (1 << compound_order(page)); i++) {
+                               void *addr = kmap_atomic(page);
                                __cpuc_flush_dcache_area(addr, PAGE_SIZE);
-                               kunmap_high(page);
+                               kunmap_atomic(addr);
+                       }
+               } else {
+                       for (i = 0; i < (1 << compound_order(page)); i++) {
+                               void *addr = kmap_high_get(page);
+                               if (addr) {
+                                       __cpuc_flush_dcache_area(addr, PAGE_SIZE);
+                                       kunmap_high(page);
+                               }
                        }
                }
        }
index 05a4e943183650ddba75efd5727d2196a01aeb94..ab4409a2307e07a602f1fcba08519cbbf2201d00 100644 (file)
@@ -9,11 +9,11 @@ static struct fsr_info fsr_info[] = {
        { do_page_fault,        SIGSEGV, SEGV_MAPERR,   "level 3 translation fault"     },
        { do_bad,               SIGBUS,  0,             "reserved access flag fault"    },
        { do_bad,               SIGSEGV, SEGV_ACCERR,   "level 1 access flag fault"     },
-       { do_bad,               SIGSEGV, SEGV_ACCERR,   "level 2 access flag fault"     },
+       { do_page_fault,        SIGSEGV, SEGV_ACCERR,   "level 2 access flag fault"     },
        { do_page_fault,        SIGSEGV, SEGV_ACCERR,   "level 3 access flag fault"     },
        { do_bad,               SIGBUS,  0,             "reserved permission fault"     },
        { do_bad,               SIGSEGV, SEGV_ACCERR,   "level 1 permission fault"      },
-       { do_sect_fault,        SIGSEGV, SEGV_ACCERR,   "level 2 permission fault"      },
+       { do_page_fault,        SIGSEGV, SEGV_ACCERR,   "level 2 permission fault"      },
        { do_page_fault,        SIGSEGV, SEGV_ACCERR,   "level 3 permission fault"      },
        { do_bad,               SIGBUS,  0,             "synchronous external abort"    },
        { do_bad,               SIGBUS,  0,             "asynchronous external abort"   },
diff --git a/arch/arm/mm/hugetlbpage.c b/arch/arm/mm/hugetlbpage.c
new file mode 100644 (file)
index 0000000..3d1e4a2
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * arch/arm/mm/hugetlbpage.c
+ *
+ * Copyright (C) 2012 ARM Ltd.
+ *
+ * Based on arch/x86/include/asm/hugetlb.h and Bill Carson's patches
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/hugetlb.h>
+#include <linux/pagemap.h>
+#include <linux/err.h>
+#include <linux/sysctl.h>
+#include <asm/mman.h>
+#include <asm/tlb.h>
+#include <asm/tlbflush.h>
+#include <asm/pgalloc.h>
+
+/*
+ * On ARM, huge pages are backed by pmd's rather than pte's, so we do a lot
+ * of type casting from pmd_t * to pte_t *.
+ */
+
+pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr)
+{
+       pgd_t *pgd;
+       pud_t *pud;
+       pmd_t *pmd = NULL;
+
+       pgd = pgd_offset(mm, addr);
+       if (pgd_present(*pgd)) {
+               pud = pud_offset(pgd, addr);
+               if (pud_present(*pud))
+                       pmd = pmd_offset(pud, addr);
+       }
+
+       return (pte_t *)pmd;
+}
+
+struct page *follow_huge_addr(struct mm_struct *mm, unsigned long address,
+                             int write)
+{
+       return ERR_PTR(-EINVAL);
+}
+
+int pud_huge(pud_t pud)
+{
+       return 0;
+}
+
+int huge_pmd_unshare(struct mm_struct *mm, unsigned long *addr, pte_t *ptep)
+{
+       return 0;
+}
+
+pte_t *huge_pte_alloc(struct mm_struct *mm,
+                       unsigned long addr, unsigned long sz)
+{
+       pgd_t *pgd;
+       pud_t *pud;
+       pte_t *pte = NULL;
+
+       pgd = pgd_offset(mm, addr);
+       pud = pud_alloc(mm, pgd, addr);
+       if (pud)
+               pte = (pte_t *)pmd_alloc(mm, pud, addr);
+
+       return pte;
+}
+
+struct page *
+follow_huge_pmd(struct mm_struct *mm, unsigned long address,
+               pmd_t *pmd, int write)
+{
+       struct page *page;
+
+       page = pte_page(*(pte_t *)pmd);
+       if (page)
+               page += ((address & ~PMD_MASK) >> PAGE_SHIFT);
+       return page;
+}
+
+int pmd_huge(pmd_t pmd)
+{
+       return pmd_val(pmd) && !(pmd_val(pmd) & PMD_TABLE_BIT);
+}
index 251f827271e918adf62b378d59aef9e7272d8b70..c019b7aaf776b7d622aa5c97146070aee57ef523 100644 (file)
@@ -383,7 +383,7 @@ static struct resource orion_ge10_shared_resources[] = {
 
 static struct platform_device orion_ge10_shared = {
        .name           = MV643XX_ETH_SHARED_NAME,
-       .id             = 1,
+       .id             = 2,
        .dev            = {
                .platform_data  = &orion_ge10_shared_data,
        },
@@ -398,8 +398,8 @@ static struct resource orion_ge10_resources[] = {
 
 static struct platform_device orion_ge10 = {
        .name           = MV643XX_ETH_NAME,
-       .id             = 1,
-       .num_resources  = 2,
+       .id             = 2,
+       .num_resources  = 1,
        .resource       = orion_ge10_resources,
        .dev            = {
                .coherent_dma_mask      = DMA_BIT_MASK(32),
@@ -432,7 +432,7 @@ static struct resource orion_ge11_shared_resources[] = {
 
 static struct platform_device orion_ge11_shared = {
        .name           = MV643XX_ETH_SHARED_NAME,
-       .id             = 1,
+       .id             = 3,
        .dev            = {
                .platform_data  = &orion_ge11_shared_data,
        },
@@ -447,8 +447,8 @@ static struct resource orion_ge11_resources[] = {
 
 static struct platform_device orion_ge11 = {
        .name           = MV643XX_ETH_NAME,
-       .id             = 1,
-       .num_resources  = 2,
+       .id             = 3,
+       .num_resources  = 1,
        .resource       = orion_ge11_resources,
        .dev            = {
                .coherent_dma_mask      = DMA_BIT_MASK(32),
index e06fc5fefa14c9ec7d0b46b002da64bc8cb425f8..d9a24f605a2b786dce8a85744c662f310f7d80a8 100644 (file)
@@ -10,6 +10,7 @@
 
 #ifndef __PLAT_COMMON_H
 #include <linux/mv643xx_eth.h>
+#include <linux/platform_data/usb-ehci-orion.h>
 
 struct dsa_platform_data;
 struct mv_sata_platform_data;
index 323ce1a62bbfa3465230632d5d7d35c458f380fa..46e17492fd1f3ecccda92c660474c805707b788b 100644 (file)
@@ -60,7 +60,7 @@ ENTRY(vfp_testing_entry)
        str     r11, [r10, #TI_PREEMPT]
 #endif
        ldr     r0, VFP_arch_address
-       str     r5, [r0]                @ known non-zero value
+       str     r0, [r0]                @ set to non-zero value
        mov     pc, r9                  @ we have handled the fault
 ENDPROC(vfp_testing_entry)
 
index bdc35589277f721805eed5675fe0bfabd8dc0aec..549903cfc2cbe6f223025ff1b04017939f7dd336 100644 (file)
@@ -205,6 +205,11 @@ config ARCH_DISCONTIGMEM_ENABLE
 config ARCH_SPARSEMEM_ENABLE
        def_bool n
 
+config NODES_SHIFT
+       int
+       default "2"
+       depends on NEED_MULTIPLE_NODES
+
 source "mm/Kconfig"
 
 config OWNERSHIP_TRACE
index 4dd4f78d3dcc80a0799a96ab7fc629fe09b728ac..d22af851f3f638b09fdc4394a05e2cebf8a10201 100644 (file)
@@ -2,3 +2,4 @@
 generic-y      += clkdev.h
 generic-y      += exec.h
 generic-y      += trace_clock.h
+generic-y      += param.h
diff --git a/arch/avr32/include/asm/numnodes.h b/arch/avr32/include/asm/numnodes.h
deleted file mode 100644 (file)
index 0b864d7..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef __ASM_AVR32_NUMNODES_H
-#define __ASM_AVR32_NUMNODES_H
-
-/* Max 4 nodes */
-#define NODES_SHIFT    2
-
-#endif /* __ASM_AVR32_NUMNODES_H */
diff --git a/arch/avr32/include/asm/param.h b/arch/avr32/include/asm/param.h
deleted file mode 100644 (file)
index 009a167..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef __ASM_AVR32_PARAM_H
-#define __ASM_AVR32_PARAM_H
-
-#include <uapi/asm/param.h>
-
-# define HZ            CONFIG_HZ
-# define USER_HZ       100             /* User interfaces are in "ticks" */
-# define CLOCKS_PER_SEC        (USER_HZ)       /* frequency at which times() counts */
-#endif /* __ASM_AVR32_PARAM_H */
index df53e7a467740a34846a4852c93122f3ef82a18e..3b85eaddf525f2be65d5772be3f28051afac7b43 100644 (file)
@@ -33,3 +33,4 @@ header-y += termbits.h
 header-y += termios.h
 header-y += types.h
 header-y += unistd.h
+generic-y += param.h
diff --git a/arch/avr32/include/uapi/asm/param.h b/arch/avr32/include/uapi/asm/param.h
deleted file mode 100644 (file)
index d28aa5e..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-#ifndef _UAPI__ASM_AVR32_PARAM_H
-#define _UAPI__ASM_AVR32_PARAM_H
-
-
-#ifndef HZ
-# define HZ            100
-#endif
-
-/* TODO: Should be configurable */
-#define EXEC_PAGESIZE  4096
-
-#ifndef NOGROUP
-# define NOGROUP       (-1)
-#endif
-
-#define MAXHOSTNAMELEN 64
-
-#endif /* _UAPI__ASM_AVR32_PARAM_H */
index 596f7305d93f017c43af7fc5f965ea4d0b988246..2c9412908024d4ce88d8945cf953b0d24437dcaf 100644 (file)
@@ -264,7 +264,7 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, const char *strtab,
                        break;
                case R_AVR32_GOT18SW:
                        if ((relocation & 0xfffe0003) != 0
-                           && (relocation & 0xfffc0003) != 0xffff0000)
+                           && (relocation & 0xfffc0000) != 0xfffc0000)
                                return reloc_overflow(module, "R_AVR32_GOT18SW",
                                                     relocation);
                        relocation >>= 2;
index cb0f6afb73894ef16019b7a53861330a49d72d27..9edc35ff8cf1420e9576f195f92658e71517c073 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/i2c.h>
 #include <linux/i2c-gpio.h>
 #include <asm/bootinfo.h>
+#include <asm/idle.h>
 #include <asm/reboot.h>
 #include <asm/mach-au1x00/au1000.h>
 #include <prom.h>
index 38afb11ba2c4605e5c370f979eba3bc86a97621b..93fa586d52e2d480d6157cc0fcffdf962cad6534 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/interrupt.h>
 #include <linux/spinlock.h>
 
+#include <asm/idle.h>
 #include <asm/processor.h>
 #include <asm/time.h>
 #include <asm/mach-au1x00/au1000.h>
index a0233a2c198812980405dc05e117de444413552e..8be4e856b8b8942e903c286c2004fb46c4d0df9d 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/clk.h>
 
 #include <asm/bootinfo.h>
+#include <asm/idle.h>
 #include <asm/time.h>          /* for mips_hpt_frequency */
 #include <asm/reboot.h>                /* for _machine_{restart,halt} */
 #include <asm/mips_machine.h>
index 516b4428df4ecd3ac5b45a6397f8ffe4a2e070c1..4eedd481dd007bba3b25bfd733fca34cbe895730 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/io.h>
 #include <linux/leds.h>
 
+#include <asm/idle.h>
 #include <asm/processor.h>
 
 #include <cobalt.h>
index face9d26e6d5a1558c93cd149e60eb742fad8619..bac26b971c5e86342dc751bf946434a6ceead08f 100644 (file)
@@ -228,7 +228,6 @@ CONFIG_HIDRAW=y
 CONFIG_USB_HID=y
 CONFIG_USB_SUPPORT=y
 CONFIG_USB=y
-CONFIG_USB_SUSPEND=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_EHCI_ROOT_HUB_TT=y
 CONFIG_USB_EHCI_TT_NEWSCHED=y
index 14752dde754018170930faa0aabfbd049b2a4312..e2b4ad55462f3477f6c4b5e63d54057064b92fde 100644 (file)
@@ -344,7 +344,6 @@ CONFIG_UHID=y
 CONFIG_USB_HIDDEV=y
 CONFIG_USB=y
 CONFIG_USB_DYNAMIC_MINORS=y
-CONFIG_USB_SUSPEND=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_EHCI_HCD_PLATFORM=y
 CONFIG_USB_EHCI_ROOT_HUB_TT=y
index b6acd2f256b682f4c3ab37774eb3ba70bcee7595..343bebc4b63b981724a17b770dc71b895d4dc225 100644 (file)
@@ -300,7 +300,6 @@ CONFIG_USB=y
 CONFIG_USB_DEVICEFS=y
 # CONFIG_USB_DEVICE_CLASS is not set
 CONFIG_USB_DYNAMIC_MINORS=y
-CONFIG_USB_SUSPEND=y
 CONFIG_USB_OTG_WHITELIST=y
 CONFIG_USB_MON=y
 CONFIG_USB_EHCI_HCD=y
index c9456e7a7283dfa15b507f021bb3f8f6696a45ca..778e32d817bc7da48056167edb4e137547ca9ef4 100644 (file)
@@ -6,8 +6,6 @@
 #include <linux/seq_file.h>
 #include <linux/clk.h>
 
-extern void (*cpu_wait) (void);
-
 struct clk;
 
 struct clk_ops {
diff --git a/arch/mips/include/asm/idle.h b/arch/mips/include/asm/idle.h
new file mode 100644 (file)
index 0000000..d192158
--- /dev/null
@@ -0,0 +1,23 @@
+#ifndef __ASM_IDLE_H
+#define __ASM_IDLE_H
+
+#include <linux/linkage.h>
+
+extern void (*cpu_wait)(void);
+extern void r4k_wait(void);
+extern asmlinkage void __r4k_wait(void);
+extern void r4k_wait_irqoff(void);
+extern void __pastwait(void);
+
+static inline int using_rollback_handler(void)
+{
+       return cpu_wait == r4k_wait;
+}
+
+static inline int address_is_in_r4k_wait_irqoff(unsigned long addr)
+{
+       return addr >= (unsigned long)r4k_wait_irqoff &&
+              addr < (unsigned long)__pastwait;
+}
+
+#endif /* __ASM_IDLE_H  */
diff --git a/arch/mips/include/asm/kvm.h b/arch/mips/include/asm/kvm.h
deleted file mode 100644 (file)
index 85789ea..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
-* This file is subject to the terms and conditions of the GNU General Public
-* License.  See the file "COPYING" in the main directory of this archive
-* for more details.
-*
-* Copyright (C) 2012  MIPS Technologies, Inc.  All rights reserved.
-* Authors: Sanjay Lal <sanjayl@kymasys.com>
-*/
-
-#ifndef __LINUX_KVM_MIPS_H
-#define __LINUX_KVM_MIPS_H
-
-#include <linux/types.h>
-
-#define __KVM_MIPS
-
-#define N_MIPS_COPROC_REGS      32
-#define N_MIPS_COPROC_SEL      8
-
-/* for KVM_GET_REGS and KVM_SET_REGS */
-struct kvm_regs {
-       __u32 gprs[32];
-       __u32 hi;
-       __u32 lo;
-       __u32 pc;
-
-       __u32 cp0reg[N_MIPS_COPROC_REGS][N_MIPS_COPROC_SEL];
-};
-
-/* for KVM_GET_SREGS and KVM_SET_SREGS */
-struct kvm_sregs {
-};
-
-/* for KVM_GET_FPU and KVM_SET_FPU */
-struct kvm_fpu {
-};
-
-struct kvm_debug_exit_arch {
-};
-
-/* for KVM_SET_GUEST_DEBUG */
-struct kvm_guest_debug_arch {
-};
-
-struct kvm_mips_interrupt {
-       /* in */
-       __u32 cpu;
-       __u32 irq;
-};
-
-/* definition of registers in kvm_run */
-struct kvm_sync_regs {
-};
-
-#endif /* __LINUX_KVM_MIPS_H */
index ec1ca537fbc1b6ac3f04b4f0c4f1b6b9c24f600a..f59552fae9173264ab58ffd3fbe95e080ec5db93 100644 (file)
@@ -171,14 +171,13 @@ typedef struct { unsigned long pgprot; } pgprot_t;
 
 #ifdef CONFIG_FLATMEM
 
-#define pfn_valid(pfn)                                                 \
-({                                                                     \
-       unsigned long __pfn = (pfn);                                    \
-       /* avoid <linux/bootmem.h> include hell */                      \
-       extern unsigned long min_low_pfn;                               \
-                                                                       \
-       __pfn >= min_low_pfn && __pfn < max_mapnr;                      \
-})
+static inline int pfn_valid(unsigned long pfn)
+{
+       /* avoid <linux/mm.h> include hell */
+       extern unsigned long max_mapnr;
+
+       return pfn >= ARCH_PFN_OFFSET && pfn < max_mapnr;
+}
 
 #elif defined(CONFIG_SPARSEMEM)
 
index 71686c897deaa2651bbb5808ae4192f57ea1f54f..1470b7b68b0e98996d271b25b86584fb6f3261a5 100644 (file)
@@ -28,7 +28,6 @@
 /*
  * System setup and hardware flags..
  */
-extern void (*cpu_wait)(void);
 
 extern unsigned int vced_count, vcei_count;
 
diff --git a/arch/mips/include/uapi/asm/kvm.h b/arch/mips/include/uapi/asm/kvm.h
new file mode 100644 (file)
index 0000000..85789ea
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+* This file is subject to the terms and conditions of the GNU General Public
+* License.  See the file "COPYING" in the main directory of this archive
+* for more details.
+*
+* Copyright (C) 2012  MIPS Technologies, Inc.  All rights reserved.
+* Authors: Sanjay Lal <sanjayl@kymasys.com>
+*/
+
+#ifndef __LINUX_KVM_MIPS_H
+#define __LINUX_KVM_MIPS_H
+
+#include <linux/types.h>
+
+#define __KVM_MIPS
+
+#define N_MIPS_COPROC_REGS      32
+#define N_MIPS_COPROC_SEL      8
+
+/* for KVM_GET_REGS and KVM_SET_REGS */
+struct kvm_regs {
+       __u32 gprs[32];
+       __u32 hi;
+       __u32 lo;
+       __u32 pc;
+
+       __u32 cp0reg[N_MIPS_COPROC_REGS][N_MIPS_COPROC_SEL];
+};
+
+/* for KVM_GET_SREGS and KVM_SET_SREGS */
+struct kvm_sregs {
+};
+
+/* for KVM_GET_FPU and KVM_SET_FPU */
+struct kvm_fpu {
+};
+
+struct kvm_debug_exit_arch {
+};
+
+/* for KVM_SET_GUEST_DEBUG */
+struct kvm_guest_debug_arch {
+};
+
+struct kvm_mips_interrupt {
+       /* in */
+       __u32 cpu;
+       __u32 irq;
+};
+
+/* definition of registers in kvm_run */
+struct kvm_sync_regs {
+};
+
+#endif /* __LINUX_KVM_MIPS_H */
index 16338b84fa79d337c9d0f32c64f37de9a23a43e3..1dee279f96659c6ae2d2ac6d42af77483454076d 100644 (file)
 #define __NR_process_vm_writev         (__NR_Linux + 305)
 #define __NR_kcmp                      (__NR_Linux + 306)
 #define __NR_finit_module              (__NR_Linux + 307)
+#define __NR_getdents64                        (__NR_Linux + 308)
 
 /*
  * Offset of the last Linux 64-bit flavoured syscall
  */
-#define __NR_Linux_syscalls            307
+#define __NR_Linux_syscalls            308
 
 #endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */
 
 #define __NR_64_Linux                  5000
-#define __NR_64_Linux_syscalls         307
+#define __NR_64_Linux_syscalls         308
 
 #if _MIPS_SIM == _MIPS_SIM_NABI32
 
index 6ad9e04bdf6210a8b722e92aca5e49161cb4deca..423d871a946ba15ae5b5ea70338530949fa8d166 100644 (file)
@@ -4,7 +4,7 @@
 
 extra-y                := head.o vmlinux.lds
 
-obj-y          += cpu-probe.o branch.o entry.o genex.o irq.o process.o \
+obj-y          += cpu-probe.o branch.o entry.o genex.o idle.o irq.o process.o \
                   prom.o ptrace.o reset.o setup.o signal.o syscall.o \
                   time.o topology.o traps.o unaligned.o watch.o vdso.o
 
index 4bbffdb9024ffb9cf437adb4fd5243e75e68a88c..c6568bf4b1b05559b43bc18f65e33c84a85963ba 100644 (file)
 #include <asm/spram.h>
 #include <asm/uaccess.h>
 
-/*
- * Not all of the MIPS CPUs have the "wait" instruction available. Moreover,
- * the implementation of the "wait" feature differs between CPU families. This
- * points to the function that implements CPU specific wait.
- * The wait instruction stops the pipeline and reduces the power consumption of
- * the CPU very much.
- */
-void (*cpu_wait)(void);
-EXPORT_SYMBOL(cpu_wait);
-
-static void r3081_wait(void)
-{
-       unsigned long cfg = read_c0_conf();
-       write_c0_conf(cfg | R30XX_CONF_HALT);
-}
-
-static void r39xx_wait(void)
-{
-       local_irq_disable();
-       if (!need_resched())
-               write_c0_conf(read_c0_conf() | TX39_CONF_HALT);
-       local_irq_enable();
-}
-
-extern void r4k_wait(void);
-
-/*
- * This variant is preferable as it allows testing need_resched and going to
- * sleep depending on the outcome atomically.  Unfortunately the "It is
- * implementation-dependent whether the pipeline restarts when a non-enabled
- * interrupt is requested" restriction in the MIPS32/MIPS64 architecture makes
- * using this version a gamble.
- */
-void r4k_wait_irqoff(void)
-{
-       local_irq_disable();
-       if (!need_resched())
-               __asm__("       .set    push            \n"
-                       "       .set    mips3           \n"
-                       "       wait                    \n"
-                       "       .set    pop             \n");
-       local_irq_enable();
-       __asm__("       .globl __pastwait       \n"
-               "__pastwait:                    \n");
-}
-
-/*
- * The RM7000 variant has to handle erratum 38.         The workaround is to not
- * have any pending stores when the WAIT instruction is executed.
- */
-static void rm7k_wait_irqoff(void)
-{
-       local_irq_disable();
-       if (!need_resched())
-               __asm__(
-               "       .set    push                                    \n"
-               "       .set    mips3                                   \n"
-               "       .set    noat                                    \n"
-               "       mfc0    $1, $12                                 \n"
-               "       sync                                            \n"
-               "       mtc0    $1, $12         # stalls until W stage  \n"
-               "       wait                                            \n"
-               "       mtc0    $1, $12         # stalls until W stage  \n"
-               "       .set    pop                                     \n");
-       local_irq_enable();
-}
-
-/*
- * The Au1xxx wait is available only if using 32khz counter or
- * external timer source, but specifically not CP0 Counter.
- * alchemy/common/time.c may override cpu_wait!
- */
-static void au1k_wait(void)
-{
-       __asm__("       .set    mips3                   \n"
-               "       cache   0x14, 0(%0)             \n"
-               "       cache   0x14, 32(%0)            \n"
-               "       sync                            \n"
-               "       nop                             \n"
-               "       wait                            \n"
-               "       nop                             \n"
-               "       nop                             \n"
-               "       nop                             \n"
-               "       nop                             \n"
-               "       .set    mips0                   \n"
-               : : "r" (au1k_wait));
-}
-
-static int __initdata nowait;
-
-static int __init wait_disable(char *s)
-{
-       nowait = 1;
-
-       return 1;
-}
-
-__setup("nowait", wait_disable);
-
 static int __cpuinitdata mips_fpu_disabled;
 
 static int __init fpu_disable(char *s)
@@ -150,105 +51,6 @@ static int __init dsp_disable(char *s)
 
 __setup("nodsp", dsp_disable);
 
-void __init check_wait(void)
-{
-       struct cpuinfo_mips *c = &current_cpu_data;
-
-       if (nowait) {
-               printk("Wait instruction disabled.\n");
-               return;
-       }
-
-       switch (c->cputype) {
-       case CPU_R3081:
-       case CPU_R3081E:
-               cpu_wait = r3081_wait;
-               break;
-       case CPU_TX3927:
-               cpu_wait = r39xx_wait;
-               break;
-       case CPU_R4200:
-/*     case CPU_R4300: */
-       case CPU_R4600:
-       case CPU_R4640:
-       case CPU_R4650:
-       case CPU_R4700:
-       case CPU_R5000:
-       case CPU_R5500:
-       case CPU_NEVADA:
-       case CPU_4KC:
-       case CPU_4KEC:
-       case CPU_4KSC:
-       case CPU_5KC:
-       case CPU_25KF:
-       case CPU_PR4450:
-       case CPU_BMIPS3300:
-       case CPU_BMIPS4350:
-       case CPU_BMIPS4380:
-       case CPU_BMIPS5000:
-       case CPU_CAVIUM_OCTEON:
-       case CPU_CAVIUM_OCTEON_PLUS:
-       case CPU_CAVIUM_OCTEON2:
-       case CPU_JZRISC:
-       case CPU_LOONGSON1:
-       case CPU_XLR:
-       case CPU_XLP:
-               cpu_wait = r4k_wait;
-               break;
-
-       case CPU_RM7000:
-               cpu_wait = rm7k_wait_irqoff;
-               break;
-
-       case CPU_M14KC:
-       case CPU_M14KEC:
-       case CPU_24K:
-       case CPU_34K:
-       case CPU_1004K:
-               cpu_wait = r4k_wait;
-               if (read_c0_config7() & MIPS_CONF7_WII)
-                       cpu_wait = r4k_wait_irqoff;
-               break;
-
-       case CPU_74K:
-               cpu_wait = r4k_wait;
-               if ((c->processor_id & 0xff) >= PRID_REV_ENCODE_332(2, 1, 0))
-                       cpu_wait = r4k_wait_irqoff;
-               break;
-
-       case CPU_TX49XX:
-               cpu_wait = r4k_wait_irqoff;
-               break;
-       case CPU_ALCHEMY:
-               cpu_wait = au1k_wait;
-               break;
-       case CPU_20KC:
-               /*
-                * WAIT on Rev1.0 has E1, E2, E3 and E16.
-                * WAIT on Rev2.0 and Rev3.0 has E16.
-                * Rev3.1 WAIT is nop, why bother
-                */
-               if ((c->processor_id & 0xff) <= 0x64)
-                       break;
-
-               /*
-                * Another rev is incremeting c0_count at a reduced clock
-                * rate while in WAIT mode.  So we basically have the choice
-                * between using the cp0 timer as clocksource or avoiding
-                * the WAIT instruction.  Until more details are known,
-                * disable the use of WAIT for 20Kc entirely.
-                  cpu_wait = r4k_wait;
-                */
-               break;
-       case CPU_RM9000:
-               if ((c->processor_id & 0x00ff) >= 0x40)
-                       cpu_wait = r4k_wait;
-               break;
-       default:
-               break;
-       }
-}
-
 static inline void check_errata(void)
 {
        struct cpuinfo_mips *c = &current_cpu_data;
index 9098829bfcb0cea7c08c51e4b0d95a337fcbf5bb..31fa856829cbf2620521317e5247d42b9e3fb087 100644 (file)
@@ -122,7 +122,7 @@ handle_vcei:
        __FINIT
 
        .align  5       /* 32 byte rollback region */
-LEAF(r4k_wait)
+LEAF(__r4k_wait)
        .set    push
        .set    noreorder
        /* start of rollback region */
@@ -146,14 +146,14 @@ LEAF(r4k_wait)
        jr      ra
        nop
        .set    pop
-       END(r4k_wait)
+       END(__r4k_wait)
 
        .macro  BUILD_ROLLBACK_PROLOGUE handler
        FEXPORT(rollback_\handler)
        .set    push
        .set    noat
        MFC0    k0, CP0_EPC
-       PTR_LA  k1, r4k_wait
+       PTR_LA  k1, __r4k_wait
        ori     k0, 0x1f        /* 32 byte rollback region */
        xori    k0, 0x1f
        bne     k0, k1, 9f
diff --git a/arch/mips/kernel/idle.c b/arch/mips/kernel/idle.c
new file mode 100644 (file)
index 0000000..3b09b88
--- /dev/null
@@ -0,0 +1,244 @@
+/*
+ * MIPS idle loop and WAIT instruction support.
+ *
+ * Copyright (C) xxxx  the Anonymous
+ * Copyright (C) 1994 - 2006 Ralf Baechle
+ * Copyright (C) 2003, 2004  Maciej W. Rozycki
+ * Copyright (C) 2001, 2004, 2011, 2012         MIPS Technologies, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include <linux/export.h>
+#include <linux/init.h>
+#include <linux/irqflags.h>
+#include <linux/printk.h>
+#include <linux/sched.h>
+#include <asm/cpu.h>
+#include <asm/cpu-info.h>
+#include <asm/idle.h>
+#include <asm/mipsregs.h>
+
+/*
+ * Not all of the MIPS CPUs have the "wait" instruction available. Moreover,
+ * the implementation of the "wait" feature differs between CPU families. This
+ * points to the function that implements CPU specific wait.
+ * The wait instruction stops the pipeline and reduces the power consumption of
+ * the CPU very much.
+ */
+void (*cpu_wait)(void);
+EXPORT_SYMBOL(cpu_wait);
+
+static void r3081_wait(void)
+{
+       unsigned long cfg = read_c0_conf();
+       write_c0_conf(cfg | R30XX_CONF_HALT);
+       local_irq_enable();
+}
+
+static void r39xx_wait(void)
+{
+       if (!need_resched())
+               write_c0_conf(read_c0_conf() | TX39_CONF_HALT);
+       local_irq_enable();
+}
+
+void r4k_wait(void)
+{
+       local_irq_enable();
+       __r4k_wait();
+}
+
+/*
+ * This variant is preferable as it allows testing need_resched and going to
+ * sleep depending on the outcome atomically.  Unfortunately the "It is
+ * implementation-dependent whether the pipeline restarts when a non-enabled
+ * interrupt is requested" restriction in the MIPS32/MIPS64 architecture makes
+ * using this version a gamble.
+ */
+void r4k_wait_irqoff(void)
+{
+       if (!need_resched())
+               __asm__(
+               "       .set    push            \n"
+               "       .set    mips3           \n"
+               "       wait                    \n"
+               "       .set    pop             \n");
+       local_irq_enable();
+       __asm__(
+       "       .globl __pastwait       \n"
+       "__pastwait:                    \n");
+}
+
+/*
+ * The RM7000 variant has to handle erratum 38.         The workaround is to not
+ * have any pending stores when the WAIT instruction is executed.
+ */
+static void rm7k_wait_irqoff(void)
+{
+       if (!need_resched())
+               __asm__(
+               "       .set    push                                    \n"
+               "       .set    mips3                                   \n"
+               "       .set    noat                                    \n"
+               "       mfc0    $1, $12                                 \n"
+               "       sync                                            \n"
+               "       mtc0    $1, $12         # stalls until W stage  \n"
+               "       wait                                            \n"
+               "       mtc0    $1, $12         # stalls until W stage  \n"
+               "       .set    pop                                     \n");
+       local_irq_enable();
+}
+
+/*
+ * The Au1xxx wait is available only if using 32khz counter or
+ * external timer source, but specifically not CP0 Counter.
+ * alchemy/common/time.c may override cpu_wait!
+ */
+static void au1k_wait(void)
+{
+       __asm__(
+       "       .set    mips3                   \n"
+       "       cache   0x14, 0(%0)             \n"
+       "       cache   0x14, 32(%0)            \n"
+       "       sync                            \n"
+       "       nop                             \n"
+       "       wait                            \n"
+       "       nop                             \n"
+       "       nop                             \n"
+       "       nop                             \n"
+       "       nop                             \n"
+       "       .set    mips0                   \n"
+       : : "r" (au1k_wait));
+       local_irq_enable();
+}
+
+static int __initdata nowait;
+
+static int __init wait_disable(char *s)
+{
+       nowait = 1;
+
+       return 1;
+}
+
+__setup("nowait", wait_disable);
+
+void __init check_wait(void)
+{
+       struct cpuinfo_mips *c = &current_cpu_data;
+
+       if (nowait) {
+               printk("Wait instruction disabled.\n");
+               return;
+       }
+
+       switch (c->cputype) {
+       case CPU_R3081:
+       case CPU_R3081E:
+               cpu_wait = r3081_wait;
+               break;
+       case CPU_TX3927:
+               cpu_wait = r39xx_wait;
+               break;
+       case CPU_R4200:
+/*     case CPU_R4300: */
+       case CPU_R4600:
+       case CPU_R4640:
+       case CPU_R4650:
+       case CPU_R4700:
+       case CPU_R5000:
+       case CPU_R5500:
+       case CPU_NEVADA:
+       case CPU_4KC:
+       case CPU_4KEC:
+       case CPU_4KSC:
+       case CPU_5KC:
+       case CPU_25KF:
+       case CPU_PR4450:
+       case CPU_BMIPS3300:
+       case CPU_BMIPS4350:
+       case CPU_BMIPS4380:
+       case CPU_BMIPS5000:
+       case CPU_CAVIUM_OCTEON:
+       case CPU_CAVIUM_OCTEON_PLUS:
+       case CPU_CAVIUM_OCTEON2:
+       case CPU_JZRISC:
+       case CPU_LOONGSON1:
+       case CPU_XLR:
+       case CPU_XLP:
+               cpu_wait = r4k_wait;
+               break;
+
+       case CPU_RM7000:
+               cpu_wait = rm7k_wait_irqoff;
+               break;
+
+       case CPU_M14KC:
+       case CPU_M14KEC:
+       case CPU_24K:
+       case CPU_34K:
+       case CPU_1004K:
+               cpu_wait = r4k_wait;
+               if (read_c0_config7() & MIPS_CONF7_WII)
+                       cpu_wait = r4k_wait_irqoff;
+               break;
+
+       case CPU_74K:
+               cpu_wait = r4k_wait;
+               if ((c->processor_id & 0xff) >= PRID_REV_ENCODE_332(2, 1, 0))
+                       cpu_wait = r4k_wait_irqoff;
+               break;
+
+       case CPU_TX49XX:
+               cpu_wait = r4k_wait_irqoff;
+               break;
+       case CPU_ALCHEMY:
+               cpu_wait = au1k_wait;
+               break;
+       case CPU_20KC:
+               /*
+                * WAIT on Rev1.0 has E1, E2, E3 and E16.
+                * WAIT on Rev2.0 and Rev3.0 has E16.
+                * Rev3.1 WAIT is nop, why bother
+                */
+               if ((c->processor_id & 0xff) <= 0x64)
+                       break;
+
+               /*
+                * Another rev is incremeting c0_count at a reduced clock
+                * rate while in WAIT mode.  So we basically have the choice
+                * between using the cp0 timer as clocksource or avoiding
+                * the WAIT instruction.  Until more details are known,
+                * disable the use of WAIT for 20Kc entirely.
+                  cpu_wait = r4k_wait;
+                */
+               break;
+       case CPU_RM9000:
+               if ((c->processor_id & 0x00ff) >= 0x40)
+                       cpu_wait = r4k_wait;
+               break;
+       default:
+               break;
+       }
+}
+
+static void smtc_idle_hook(void)
+{
+#ifdef CONFIG_MIPS_MT_SMTC
+       void smtc_idle_loop_hook(void);
+
+       smtc_idle_loop_hook();
+#endif
+}
+
+void arch_cpu_idle(void)
+{
+       smtc_idle_hook();
+       if (cpu_wait)
+               cpu_wait();
+       else
+               local_irq_enable();
+}
index 12bc4ebdf55b6bf5e087532feafcaddca94b417e..1f8187ab0997be478f69b66eadb8ac4a6bf7e489 100644 (file)
@@ -207,7 +207,10 @@ void __kprobes arch_disarm_kprobe(struct kprobe *p)
 
 void __kprobes arch_remove_kprobe(struct kprobe *p)
 {
-       free_insn_slot(p->ainsn.insn, 0);
+       if (p->ainsn.insn) {
+               free_insn_slot(p->ainsn.insn, 0);
+               p->ainsn.insn = NULL;
+       }
 }
 
 static void save_previous_kprobe(struct kprobe_ctlblk *kcb)
index a3e461408b7e830758d3b3dfeed661573277131e..acb34373679e21f9940f62f251e64dc1e32e5f17 100644 (file)
@@ -10,6 +10,7 @@
 #include <asm/bootinfo.h>
 #include <asm/cpu.h>
 #include <asm/cpu-features.h>
+#include <asm/idle.h>
 #include <asm/mipsregs.h>
 #include <asm/processor.h>
 #include <asm/prom.h>
index a682a87bcc043152bb741623d196032e444e81d1..c6a041d9d05d57fcd71f91a228c86524e00efd08 100644 (file)
@@ -51,19 +51,6 @@ void arch_cpu_idle_dead(void)
 }
 #endif
 
-void arch_cpu_idle(void)
-{
-#ifdef CONFIG_MIPS_MT_SMTC
-       extern void smtc_idle_loop_hook(void);
-
-       smtc_idle_loop_hook();
-#endif
-       if (cpu_wait)
-               (*cpu_wait)();
-       else
-               local_irq_enable();
-}
-
 asmlinkage void ret_from_fork(void);
 asmlinkage void ret_from_kernel_thread(void);
 
index 36cfd4060e1f423eed05869a1adc9591f36ab662..97a5909a61cf0c623dfdf8284eaf11bf13e7adf7 100644 (file)
@@ -423,4 +423,5 @@ sys_call_table:
        PTR     sys_process_vm_writev           /* 5305 */
        PTR     sys_kcmp
        PTR     sys_finit_module
+       PTR     sys_getdents64
        .size   sys_call_table,.-sys_call_table
index c17619fe18e32a9f23a5df7e18b0b943b5d0cf2c..6e7862ab46cc4a6fef3c31e1ade85e04b357824f 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/atomic.h>
 #include <asm/cpu.h>
 #include <asm/processor.h>
+#include <asm/idle.h>
 #include <asm/r4k-timer.h>
 #include <asm/mmu_context.h>
 #include <asm/time.h>
index 7186222dc5bb285a4ff74a23a5851dd03b9356c1..75a4fd709841a9df42d4eba3218e053f7bf8c351 100644 (file)
@@ -34,6 +34,7 @@
 #include <asm/hardirq.h>
 #include <asm/hazards.h>
 #include <asm/irq.h>
+#include <asm/idle.h>
 #include <asm/mmu_context.h>
 #include <asm/mipsregs.h>
 #include <asm/cacheflush.h>
@@ -858,7 +859,6 @@ void smtc_send_ipi(int cpu, int type, unsigned int action)
        unsigned long flags;
        int mtflags;
        unsigned long tcrestart;
-       extern void r4k_wait_irqoff(void), __pastwait(void);
        int set_resched_flag = (type == LINUX_SMP_IPI &&
                                action == SMP_RESCHEDULE_YOURSELF);
 
@@ -914,8 +914,7 @@ void smtc_send_ipi(int cpu, int type, unsigned int action)
                         */
                        if (cpu_wait == r4k_wait_irqoff) {
                                tcrestart = read_tc_c0_tcrestart();
-                               if (tcrestart >= (unsigned long)r4k_wait_irqoff
-                                   && tcrestart < (unsigned long)__pastwait) {
+                               if (address_is_in_r4k_wait_irqoff(tcrestart)) {
                                        write_tc_c0_tcrestart(__pastwait);
                                        tcstatus &= ~TCSTATUS_IXMT;
                                        write_tc_c0_tcstatus(tcstatus);
index cb14db3c57646e22a467e092059d4f084538f447..e3be67012d7882d23d657841d4bc7d436839c648 100644 (file)
@@ -41,6 +41,7 @@
 #include <asm/dsp.h>
 #include <asm/fpu.h>
 #include <asm/fpu_emulator.h>
+#include <asm/idle.h>
 #include <asm/mipsregs.h>
 #include <asm/mipsmtregs.h>
 #include <asm/module.h>
@@ -57,7 +58,6 @@
 #include <asm/uasm.h>
 
 extern void check_wait(void);
-extern asmlinkage void r4k_wait(void);
 extern asmlinkage void rollback_handle_int(void);
 extern asmlinkage void handle_int(void);
 extern u32 handle_tlbl[];
@@ -1542,7 +1542,7 @@ static void *set_vi_srs_handler(int n, vi_handler_t addr, int srs)
                extern char except_vec_vi, except_vec_vi_lui;
                extern char except_vec_vi_ori, except_vec_vi_end;
                extern char rollback_except_vec_vi;
-               char *vec_start = (cpu_wait == r4k_wait) ?
+               char *vec_start = using_rollback_handler() ?
                        &rollback_except_vec_vi : &except_vec_vi;
 #ifdef CONFIG_MIPS_MT_SMTC
                /*
@@ -1812,10 +1812,8 @@ void __init trap_init(void)
        extern char except_vec4;
        extern char except_vec3_r4000;
        unsigned long i;
-       int rollback;
 
        check_wait();
-       rollback = (cpu_wait == r4k_wait);
 
 #if defined(CONFIG_KGDB)
        if (kgdb_early_setup)
@@ -1892,7 +1890,8 @@ void __init trap_init(void)
        if (board_be_init)
                board_be_init();
 
-       set_except_vector(0, rollback ? rollback_handle_int : handle_int);
+       set_except_vector(0, using_rollback_handler() ? rollback_handle_int
+                                                     : handle_int);
        set_except_vector(1, handle_tlbm);
        set_except_vector(2, handle_tlbl);
        set_except_vector(3, handle_tlbs);
index e3f0d9b8b6c59604fdb60e67d3a230493da5a49f..c777dd36d4a8bf88be1000dc993bc2d8774b6a33 100644 (file)
@@ -17,6 +17,8 @@
 #include <linux/delay.h>
 #include <linux/module.h>
 #include <linux/kvm_host.h>
+#include <linux/srcu.h>
+
 
 #include <asm/cpu.h>
 #include <asm/bootinfo.h>
@@ -169,21 +171,27 @@ void kvm_mips_dump_shadow_tlbs(struct kvm_vcpu *vcpu)
        }
 }
 
-static void kvm_mips_map_page(struct kvm *kvm, gfn_t gfn)
+static int kvm_mips_map_page(struct kvm *kvm, gfn_t gfn)
 {
+       int srcu_idx, err = 0;
        pfn_t pfn;
 
        if (kvm->arch.guest_pmap[gfn] != KVM_INVALID_PAGE)
-               return;
+               return 0;
 
+        srcu_idx = srcu_read_lock(&kvm->srcu);
        pfn = kvm_mips_gfn_to_pfn(kvm, gfn);
 
        if (kvm_mips_is_error_pfn(pfn)) {
-               panic("Couldn't get pfn for gfn %#" PRIx64 "!\n", gfn);
+               kvm_err("Couldn't get pfn for gfn %#" PRIx64 "!\n", gfn);
+               err = -EFAULT;
+               goto out;
        }
 
        kvm->arch.guest_pmap[gfn] = pfn;
-       return;
+out:
+       srcu_read_unlock(&kvm->srcu, srcu_idx);
+       return err;
 }
 
 /* Translate guest KSEG0 addresses to Host PA */
@@ -207,7 +215,10 @@ unsigned long kvm_mips_translate_guest_kseg0_to_hpa(struct kvm_vcpu *vcpu,
                        gva);
                return KVM_INVALID_PAGE;
        }
-       kvm_mips_map_page(vcpu->kvm, gfn);
+
+       if (kvm_mips_map_page(vcpu->kvm, gfn) < 0)
+               return KVM_INVALID_ADDR;
+
        return (kvm->arch.guest_pmap[gfn] << PAGE_SHIFT) + offset;
 }
 
@@ -310,8 +321,11 @@ int kvm_mips_handle_kseg0_tlb_fault(unsigned long badvaddr,
        even = !(gfn & 0x1);
        vaddr = badvaddr & (PAGE_MASK << 1);
 
-       kvm_mips_map_page(vcpu->kvm, gfn);
-       kvm_mips_map_page(vcpu->kvm, gfn ^ 0x1);
+       if (kvm_mips_map_page(vcpu->kvm, gfn) < 0)
+               return -1;
+
+       if (kvm_mips_map_page(vcpu->kvm, gfn ^ 0x1) < 0)
+               return -1;
 
        if (even) {
                pfn0 = kvm->arch.guest_pmap[gfn];
@@ -389,8 +403,11 @@ kvm_mips_handle_mapped_seg_tlb_fault(struct kvm_vcpu *vcpu,
                pfn0 = 0;
                pfn1 = 0;
        } else {
-               kvm_mips_map_page(kvm, mips3_tlbpfn_to_paddr(tlb->tlb_lo0) >> PAGE_SHIFT);
-               kvm_mips_map_page(kvm, mips3_tlbpfn_to_paddr(tlb->tlb_lo1) >> PAGE_SHIFT);
+               if (kvm_mips_map_page(kvm, mips3_tlbpfn_to_paddr(tlb->tlb_lo0) >> PAGE_SHIFT) < 0)
+                       return -1;
+
+               if (kvm_mips_map_page(kvm, mips3_tlbpfn_to_paddr(tlb->tlb_lo1) >> PAGE_SHIFT) < 0)
+                       return -1;
 
                pfn0 = kvm->arch.guest_pmap[mips3_tlbpfn_to_paddr(tlb->tlb_lo0) >> PAGE_SHIFT];
                pfn1 = kvm->arch.guest_pmap[mips3_tlbpfn_to_paddr(tlb->tlb_lo1) >> PAGE_SHIFT];
index 35c8c64684941603f29c072478fd42b7401a7be8..65bfbb5d06f442efbd6601600097f94124cc171c 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/init.h>
 #include <linux/pm.h>
 
+#include <asm/idle.h>
 #include <asm/reboot.h>
 
 #include <loongson.h>
index d4f610f9604a27296a685ea1455bbd18717b48be..547f34b69e4c06a471032ab588b8391e62f0cc39 100644 (file)
@@ -9,6 +9,7 @@
 
 #include <linux/io.h>
 #include <linux/pm.h>
+#include <asm/idle.h>
 #include <asm/reboot.h>
 
 #include <loongson1.h>
index af319143b59187a4918805f737e2dcdb480845e7..eaa99d28cb8eddbf1fe0311740f22054bb4e15ad 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/pm.h>
 #include <linux/bootmem.h>
 
+#include <asm/idle.h>
 #include <asm/reboot.h>
 #include <asm/time.h>
 #include <asm/bootinfo.h>
index e3e094100e3e51f2ea879431f85a9512d84e22a4..89c8c1066632b5f2800c1a4f2ecaef212ac890cf 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/serial_8250.h>
 #include <linux/pm.h>
 
+#include <asm/idle.h>
 #include <asm/reboot.h>
 #include <asm/time.h>
 #include <asm/bootinfo.h>
index 1651cfdbfe7b1303c03b629171190e8df013ad16..396b2967ad856bb974da6ff8055d27037cd9b654 100644 (file)
@@ -12,6 +12,7 @@
 
 #include <asm/bootinfo.h>
 #include <asm/cacheflush.h>
+#include <asm/idle.h>
 #include <asm/r4kcache.h>
 #include <asm/reboot.h>
 #include <asm/smp-ops.h>
index 5364aabc21027951532bc5d0e7d97898344f701a..681e7f86c08000f29884ce369efafab86afe1b29 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/slab.h>
 #include <linux/irq.h>
 #include <asm/bootinfo.h>
+#include <asm/idle.h>
 #include <asm/time.h>
 #include <asm/reboot.h>
 #include <asm/r4kcache.h>
index 70a3f90131d82af9d67bac9ff2d8d206812dde6b..d7f755833c3f43431b48f38b296da4df34d993e6 100644 (file)
@@ -27,6 +27,7 @@
 
 #include <asm/cacheflush.h>
 #include <asm/cpu.h>
+#include <asm/idle.h>
 #include <asm/io.h>
 #include <asm/processor.h>
 #include <asm/reboot.h>
index cc5474b24f0657f6b51091d6f2779427a03d3e78..80beb188ed476ebb2775db8a89673bd1de95f631 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/kernel.h>
 
 #include <asm/cacheflush.h>
+#include <asm/idle.h>
 #include <asm/mipsregs.h>
 #include <asm/processor.h>
 
index 89fb40005e3f81e875ed0111952e7941282832cf..0da848232344fc41d9583cc10f8510a54a7d6a16 100644 (file)
        SAVE_SP  (%sr4, PT_SR4 (\regs))
        SAVE_SP  (%sr5, PT_SR5 (\regs))
        SAVE_SP  (%sr6, PT_SR6 (\regs))
-       SAVE_SP  (%sr7, PT_SR7 (\regs))
 
        SAVE_CR  (%cr17, PT_IASQ0(\regs))
        mtctl    %r0,   %cr17
index c19f7138ba48b91dfffe1046da708782057cc779..241c34518465d9404f56b786a86554a1e89824a3 100644 (file)
 
 typedef struct {
        unsigned int __softirq_pending;
-#ifdef CONFIG_DEBUG_STACKOVERFLOW
        unsigned int kernel_stack_usage;
-#ifdef CONFIG_IRQSTACKS
        unsigned int irq_stack_usage;
-       unsigned int irq_stack_counter;
-#endif
-#endif
 #ifdef CONFIG_SMP
        unsigned int irq_resched_count;
        unsigned int irq_call_count;
 #endif
+       unsigned int irq_unaligned_count;
+       unsigned int irq_fpassist_count;
        unsigned int irq_tlb_count;
 } ____cacheline_aligned irq_cpustat_t;
 
index cfbc43929cf6d20e2e53df0be823b8166ff576c0..cc2290a3cace1e0d65f8e69be0138c0c09cc8b2a 100644 (file)
@@ -17,7 +17,6 @@
 #include <asm/ptrace.h>
 #include <asm/types.h>
 #include <asm/percpu.h>
-
 #endif /* __ASSEMBLY__ */
 
 /*
 
 #ifndef __ASSEMBLY__
 
-/*
- * IRQ STACK - used for irq handler
- */
-#ifdef __KERNEL__
-
-#include <linux/spinlock_types.h>
-
-#define IRQ_STACK_SIZE      (4096 << 2) /* 16k irq stack size */
-
-union irq_stack_union {
-       unsigned long stack[IRQ_STACK_SIZE/sizeof(unsigned long)];
-       raw_spinlock_t lock;
-};
-
-DECLARE_PER_CPU(union irq_stack_union, irq_stack_union);
-
-void call_on_stack(unsigned long p1, void *func, unsigned long new_stack);
-
-#endif /* __KERNEL__ */
-
 /*
  * Data detected about CPUs at boot time which is the same for all CPU's.
  * HP boxes are SMP - ie identical processors.
index ae27cb6ce19ab012e45c8eeadc77dec77846c526..e8f07dd2840186a934632104fdc3116fa7293506 100644 (file)
        rsm     PSW_SM_I, %r0   /* barrier for "Relied upon Translation */
        mtsp    %r0, %sr4
        mtsp    %r0, %sr5
-       mfsp    %sr7, %r1
-       or,=    %r0,%r1,%r0     /* Only save sr7 in sr3 if sr7 != 0 */
-       mtsp    %r1, %sr3
+       mtsp    %r0, %sr6
        tovirt_r1 %r29
        load32  KERNEL_PSW, %r1
 
        rsm     PSW_SM_QUIET,%r0        /* second "heavy weight" ctl op */
-       mtsp    %r0, %sr6
-       mtsp    %r0, %sr7
        mtctl   %r0, %cr17      /* Clear IIASQ tail */
        mtctl   %r0, %cr17      /* Clear IIASQ head */
        mtctl   %r1, %ipsw
 
        /* we save the registers in the task struct */
 
+       copy    %r30, %r17
        mfctl   %cr30, %r1
+       ldo     THREAD_SZ_ALGN(%r1), %r30
+       mtsp    %r0,%sr7
+       mtsp    %r16,%sr3
        tophys  %r1,%r9
        LDREG   TI_TASK(%r9), %r1       /* thread_info -> task_struct */
        tophys  %r1,%r9
        ldo     TASK_REGS(%r9),%r9
-       STREG   %r30, PT_GR30(%r9)
+       STREG   %r17,PT_GR30(%r9)
        STREG   %r29,PT_GR29(%r9)
        STREG   %r26,PT_GR26(%r9)
+       STREG   %r16,PT_SR7(%r9)
        copy    %r9,%r29
-       mfctl   %cr30, %r1
-       ldo     THREAD_SZ_ALGN(%r1), %r30
        .endm
 
        .macro  get_stack_use_r30
        /* we put a struct pt_regs on the stack and save the registers there */
 
        tophys  %r30,%r9
-       STREG   %r30,PT_GR30(%r9)
+       copy    %r30,%r1
        ldo     PT_SZ_ALGN(%r30),%r30
+       STREG   %r1,PT_GR30(%r9)
        STREG   %r29,PT_GR29(%r9)
        STREG   %r26,PT_GR26(%r9)
+       STREG   %r16,PT_SR7(%r9)
        copy    %r9,%r29
        .endm
 
index f7752f6af29e090e559d74e0d8d1206bd50a72ef..9e2d2e408529f744b7bf5b7830cec15ad48a6012 100644 (file)
@@ -222,6 +222,7 @@ static struct hp_hardware hp_hardware_list[] = {
        {HPHW_NPROC,0x5DD,0x4,0x81,"Duet W2"},
        {HPHW_NPROC,0x5DE,0x4,0x81,"Piccolo W+"},
        {HPHW_NPROC,0x5DF,0x4,0x81,"Cantata W2"},
+       {HPHW_NPROC,0x5DF,0x0,0x00,"Marcato W+? (rp5470)"},
        {HPHW_NPROC,0x5E0,0x4,0x91,"Cantata DC- W2"},
        {HPHW_NPROC,0x5E1,0x4,0x91,"Crescendo DC- W2"},
        {HPHW_NPROC,0x5E2,0x4,0x91,"Crescendo 650 W2"},
index 55237a70e19773940f67e8e62ac7d43c60f36608..2e6443b1e9228426ba94d8602c8956c5daec93c2 100644 (file)
 #include <linux/interrupt.h>
 #include <linux/kernel_stat.h>
 #include <linux/seq_file.h>
-#include <linux/spinlock.h>
 #include <linux/types.h>
 #include <asm/io.h>
 
 #include <asm/smp.h>
+#include <asm/ldcw.h>
 
 #undef PARISC_IRQ_CR16_COUNTS
 
@@ -172,10 +172,6 @@ int arch_show_interrupts(struct seq_file *p, int prec)
        for_each_online_cpu(j)
                seq_printf(p, "%10u ", irq_stats(j)->irq_stack_usage);
        seq_puts(p, "  Interrupt stack usage\n");
-       seq_printf(p, "%*s: ", prec, "ISC");
-       for_each_online_cpu(j)
-               seq_printf(p, "%10u ", irq_stats(j)->irq_stack_counter);
-       seq_puts(p, "  Interrupt stack usage counter\n");
 # endif
 #endif
 #ifdef CONFIG_SMP
@@ -188,6 +184,14 @@ int arch_show_interrupts(struct seq_file *p, int prec)
                seq_printf(p, "%10u ", irq_stats(j)->irq_call_count);
        seq_puts(p, "  Function call interrupts\n");
 #endif
+       seq_printf(p, "%*s: ", prec, "UAH");
+       for_each_online_cpu(j)
+               seq_printf(p, "%10u ", irq_stats(j)->irq_unaligned_count);
+       seq_puts(p, "  Unaligned access handler traps\n");
+       seq_printf(p, "%*s: ", prec, "FPA");
+       for_each_online_cpu(j)
+               seq_printf(p, "%10u ", irq_stats(j)->irq_fpassist_count);
+       seq_puts(p, "  Floating point assist traps\n");
        seq_printf(p, "%*s: ", prec, "TLB");
        for_each_online_cpu(j)
                seq_printf(p, "%10u ", irq_stats(j)->irq_tlb_count);
@@ -376,6 +380,24 @@ static inline int eirr_to_irq(unsigned long eirr)
        return (BITS_PER_LONG - bit) + TIMER_IRQ;
 }
 
+#ifdef CONFIG_IRQSTACKS
+/*
+ * IRQ STACK - used for irq handler
+ */
+#define IRQ_STACK_SIZE      (4096 << 2) /* 16k irq stack size */
+
+union irq_stack_union {
+       unsigned long stack[IRQ_STACK_SIZE/sizeof(unsigned long)];
+       volatile unsigned int slock[4];
+       volatile unsigned int lock[1];
+};
+
+DEFINE_PER_CPU(union irq_stack_union, irq_stack_union) = {
+               .slock = { 1,1,1,1 },
+       };
+#endif
+
+
 int sysctl_panic_on_stackoverflow = 1;
 
 static inline void stack_overflow_check(struct pt_regs *regs)
@@ -442,27 +464,26 @@ panic_check:
 }
 
 #ifdef CONFIG_IRQSTACKS
-DEFINE_PER_CPU(union irq_stack_union, irq_stack_union) = {
-               .lock = __RAW_SPIN_LOCK_UNLOCKED((irq_stack_union).lock)
-       };
+/* in entry.S: */
+void call_on_stack(unsigned long p1, void *func, unsigned long new_stack);
 
 static void execute_on_irq_stack(void *func, unsigned long param1)
 {
        union irq_stack_union *union_ptr;
        unsigned long irq_stack;
-       raw_spinlock_t *irq_stack_in_use;
+       volatile unsigned int *irq_stack_in_use;
 
        union_ptr = &per_cpu(irq_stack_union, smp_processor_id());
        irq_stack = (unsigned long) &union_ptr->stack;
-       irq_stack = ALIGN(irq_stack + sizeof(irq_stack_union.lock),
+       irq_stack = ALIGN(irq_stack + sizeof(irq_stack_union.slock),
                         64); /* align for stack frame usage */
 
        /* We may be called recursive. If we are already using the irq stack,
         * just continue to use it. Use spinlocks to serialize
         * the irq stack usage.
         */
-       irq_stack_in_use = &union_ptr->lock;
-       if (!raw_spin_trylock(irq_stack_in_use)) {
+       irq_stack_in_use = (volatile unsigned int *)__ldcw_align(union_ptr);
+       if (!__ldcw(irq_stack_in_use)) {
                void (*direct_call)(unsigned long p1) = func;
 
                /* We are using the IRQ stack already.
@@ -474,10 +495,8 @@ static void execute_on_irq_stack(void *func, unsigned long param1)
        /* This is where we switch to the IRQ stack. */
        call_on_stack(param1, func, irq_stack);
 
-       __inc_irq_stat(irq_stack_counter);
-
        /* free up irq stack usage. */
-       do_raw_spin_unlock(irq_stack_in_use);
+       *irq_stack_in_use = 1;
 }
 
 asmlinkage void do_softirq(void)
index 5e1de6072be57f0c92ce04950284fe7f10c5bf4c..36d7f402e48edb8b8cb13dea9e302d1e84edfdf9 100644 (file)
@@ -605,14 +605,14 @@ ENTRY(copy_user_page_asm)
        convert_phys_for_tlb_insert20 %r26      /* convert phys addr to tlb insert format */
        convert_phys_for_tlb_insert20 %r23      /* convert phys addr to tlb insert format */
        depd            %r24,63,22, %r28        /* Form aliased virtual address 'to' */
-       depdi           0, 63,PAGE_SHIFT, %r28  /* Clear any offset bits */
+       depdi           0, 63,PAGE_SHIFT, %r28  /* Clear any offset bits */
        copy            %r28, %r29
        depdi           1, 41,1, %r29           /* Form aliased virtual address 'from' */
 #else
        extrw,u         %r26, 24,25, %r26       /* convert phys addr to tlb insert format */
        extrw,u         %r23, 24,25, %r23       /* convert phys addr to tlb insert format */
        depw            %r24, 31,22, %r28       /* Form aliased virtual address 'to' */
-       depwi           0, 31,12, %r28          /* Clear any offset bits */
+       depwi           0, 31,PAGE_SHIFT, %r28  /* Clear any offset bits */
        copy            %r28, %r29
        depwi           1, 9,1, %r29            /* Form aliased virtual address 'from' */
 #endif
@@ -762,7 +762,7 @@ ENTRY(clear_user_page_asm)
 #else
        extrw,u         %r26, 24,25, %r26       /* convert phys addr to tlb insert format */
        depw            %r25, 31,22, %r28       /* Form aliased virtual address 'to' */
-       depwi           0, 31,12, %r28          /* Clear any offset bits */
+       depwi           0, 31,PAGE_SHIFT, %r28  /* Clear any offset bits */
 #endif
 
        /* Purge any old translation */
@@ -846,7 +846,7 @@ ENTRY(flush_dcache_page_asm)
 #else
        extrw,u         %r26, 24,25, %r26       /* convert phys addr to tlb insert format */
        depw            %r25, 31,22, %r28       /* Form aliased virtual address 'to' */
-       depwi           0, 31,12, %r28          /* Clear any offset bits */
+       depwi           0, 31,PAGE_SHIFT, %r28  /* Clear any offset bits */
 #endif
 
        /* Purge any old translation */
@@ -918,11 +918,11 @@ ENTRY(flush_icache_page_asm)
 #endif
        convert_phys_for_tlb_insert20 %r26      /* convert phys addr to tlb insert format */
        depd            %r25, 63,22, %r28       /* Form aliased virtual address 'to' */
-       depdi           0, 63,PAGE_SHIFT, %r28  /* Clear any offset bits */
+       depdi           0, 63,PAGE_SHIFT, %r28  /* Clear any offset bits */
 #else
        extrw,u         %r26, 24,25, %r26       /* convert phys addr to tlb insert format */
        depw            %r25, 31,22, %r28       /* Form aliased virtual address 'to' */
-       depwi           0, 31,12, %r28          /* Clear any offset bits */
+       depwi           0, 31,PAGE_SHIFT, %r28  /* Clear any offset bits */
 #endif
 
        /* Purge any old translation */
index fe41a98043bbcf287e3ee3562972d6b693e140d0..04e47c6a45626347aa261d3725005cdafb9385ad 100644 (file)
@@ -646,6 +646,7 @@ void notrace handle_interruption(int code, struct pt_regs *regs)
        case 14:
                /* Assist Exception Trap, i.e. floating point exception. */
                die_if_kernel("Floating point exception", regs, 0); /* quiet */
+               __inc_irq_stat(irq_fpassist_count);
                handle_fpe(regs);
                return;
 
index 234e3682cf0900ef0e55e18e168d1ad5324afd5f..d7c0acb35ec248c51329a5cb4594189bd5f5040f 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/signal.h>
 #include <linux/ratelimit.h>
 #include <asm/uaccess.h>
+#include <asm/hardirq.h>
 
 /* #define DEBUG_UNALIGNED 1 */
 
@@ -454,6 +455,8 @@ void handle_unaligned(struct pt_regs *regs)
        struct siginfo si;
        register int flop=0;    /* true if this is a flop */
 
+       __inc_irq_stat(irq_unaligned_count);
+
        /* log a message with pacing */
        if (user_mode(regs)) {
                if (current->thread.flags & PARISC_UAC_SIGBUS) {
index f79196232917140f0afef3085f53d63e32f5e5d7..139a8308070c8fee09665b81d168ef092e584d3e 100644 (file)
@@ -136,7 +136,6 @@ CONFIG_HID_SMARTJOYPLUS=m
 CONFIG_USB_HIDDEV=y
 CONFIG_USB=m
 CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
-CONFIG_USB_SUSPEND=y
 CONFIG_USB_MON=m
 CONFIG_USB_EHCI_HCD=m
 # CONFIG_USB_EHCI_HCD_PPC_OF is not set
index 8b11b5bd9938b847a5439eb5e13851653af9fe25..2c1d8cb9b26562a295ab6b6016261b0d692df30b 100644 (file)
@@ -174,6 +174,8 @@ struct pci_dn {
 /* Get the pointer to a device_node's pci_dn */
 #define PCI_DN(dn)     ((struct pci_dn *) (dn)->data)
 
+extern struct pci_dn *pci_get_pdn(struct pci_dev *pdev);
+
 extern void * update_dn_pci_info(struct device_node *dn, void *data);
 
 static inline int pci_device_from_OF_node(struct device_node *np,
index d7e67ca8b4a6fb48f26b7a778be4db8873862012..594db6bc093c521ad7a9a07e98163d0d2ec18c88 100644 (file)
@@ -284,6 +284,12 @@ struct thread_struct {
        unsigned long   ebbrr;
        unsigned long   ebbhr;
        unsigned long   bescr;
+       unsigned long   siar;
+       unsigned long   sdar;
+       unsigned long   sier;
+       unsigned long   mmcr0;
+       unsigned long   mmcr2;
+       unsigned long   mmcra;
 #endif
 };
 
index b51a97cfedf88ff2b7884ef19485ff081d18cf78..6f16ffafa6f01542d54ccc684c3f8d5d7d6add5c 100644 (file)
@@ -127,6 +127,12 @@ int main(void)
        DEFINE(THREAD_BESCR, offsetof(struct thread_struct, bescr));
        DEFINE(THREAD_EBBHR, offsetof(struct thread_struct, ebbhr));
        DEFINE(THREAD_EBBRR, offsetof(struct thread_struct, ebbrr));
+       DEFINE(THREAD_SIAR, offsetof(struct thread_struct, siar));
+       DEFINE(THREAD_SDAR, offsetof(struct thread_struct, sdar));
+       DEFINE(THREAD_SIER, offsetof(struct thread_struct, sier));
+       DEFINE(THREAD_MMCR0, offsetof(struct thread_struct, mmcr0));
+       DEFINE(THREAD_MMCR2, offsetof(struct thread_struct, mmcr2));
+       DEFINE(THREAD_MMCRA, offsetof(struct thread_struct, mmcra));
 #endif
 #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
        DEFINE(PACATMSCRATCH, offsetof(struct paca_struct, tm_scratch));
index a283b6442b266544235e11bc061d33d58f321b05..18b5b9cf8e3730f4608ca6ff997810d5cc47df9a 100644 (file)
@@ -135,8 +135,12 @@ __init_HFSCR:
        blr
 
 __init_TLB:
-       /* Clear the TLB */
-       li      r6,128
+       /*
+        * Clear the TLB using the "IS 3" form of tlbiel instruction
+        * (invalidate by congruence class). P7 has 128 CCs, P8 has 512
+        * so we just always do 512
+        */
+       li      r6,512
        mtctr   r6
        li      r7,0xc00        /* IS field = 0b11 */
        ptesync
index 51cfb8fc301f1299299bcc49edb12c7f9bc57eab..0e9095e47b5b0098da33aeb262694fa8d5e0c0ef 100644 (file)
@@ -465,6 +465,20 @@ BEGIN_FTR_SECTION
        std     r0, THREAD_EBBHR(r3)
        mfspr   r0, SPRN_EBBRR
        std     r0, THREAD_EBBRR(r3)
+
+       /* PMU registers made user read/(write) by EBB */
+       mfspr   r0, SPRN_SIAR
+       std     r0, THREAD_SIAR(r3)
+       mfspr   r0, SPRN_SDAR
+       std     r0, THREAD_SDAR(r3)
+       mfspr   r0, SPRN_SIER
+       std     r0, THREAD_SIER(r3)
+       mfspr   r0, SPRN_MMCR0
+       std     r0, THREAD_MMCR0(r3)
+       mfspr   r0, SPRN_MMCR2
+       std     r0, THREAD_MMCR2(r3)
+       mfspr   r0, SPRN_MMCRA
+       std     r0, THREAD_MMCRA(r3)
 END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
 #endif
 
@@ -560,6 +574,20 @@ BEGIN_FTR_SECTION
        ld      r0, THREAD_EBBRR(r4)
        mtspr   SPRN_EBBRR, r0
 
+       /* PMU registers made user read/(write) by EBB */
+       ld      r0, THREAD_SIAR(r4)
+       mtspr   SPRN_SIAR, r0
+       ld      r0, THREAD_SDAR(r4)
+       mtspr   SPRN_SDAR, r0
+       ld      r0, THREAD_SIER(r4)
+       mtspr   SPRN_SIER, r0
+       ld      r0, THREAD_MMCR0(r4)
+       mtspr   SPRN_MMCR0, r0
+       ld      r0, THREAD_MMCR2(r4)
+       mtspr   SPRN_MMCR2, r0
+       ld      r0, THREAD_MMCRA(r4)
+       mtspr   SPRN_MMCRA, r0
+
        ld      r0,THREAD_TAR(r4)
        mtspr   SPRN_TAR,r0
 END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
index 6053f037ef0af4368551d1e866769c39f6ea6143..e9acf50dd5b29b0ed5f416d9704bd287b30d1469 100644 (file)
@@ -1520,9 +1520,10 @@ static void pcibios_setup_phb_resources(struct pci_controller *hose,
        for (i = 0; i < 3; ++i) {
                res = &hose->mem_resources[i];
                if (!res->flags) {
-                       printk(KERN_ERR "PCI: Memory resource 0 not set for "
-                              "host bridge %s (domain %d)\n",
-                              hose->dn->full_name, hose->global_number);
+                       if (i == 0)
+                               printk(KERN_ERR "PCI: Memory resource 0 not set for "
+                                      "host bridge %s (domain %d)\n",
+                                      hose->dn->full_name, hose->global_number);
                        continue;
                }
                offset = hose->mem_offset[i];
index 873050d268406e4a343d2e597c80ec7d99795552..2e8629654ca872443e89e30455b05f54c1850eb0 100644 (file)
@@ -266,3 +266,13 @@ int pcibus_to_node(struct pci_bus *bus)
 }
 EXPORT_SYMBOL(pcibus_to_node);
 #endif
+
+static void quirk_radeon_32bit_msi(struct pci_dev *dev)
+{
+       struct pci_dn *pdn = pci_get_pdn(dev);
+
+       if (pdn)
+               pdn->force_32bit_msi = 1;
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x68f2, quirk_radeon_32bit_msi);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0xaa68, quirk_radeon_32bit_msi);
index e7af165f8b9d402add808fc5ce3760b9674d7c7a..df038442548a1397fb3cf5c9458fc39379a381a2 100644 (file)
 #include <asm/ppc-pci.h>
 #include <asm/firmware.h>
 
+struct pci_dn *pci_get_pdn(struct pci_dev *pdev)
+{
+       struct device_node *dn = pci_device_to_OF_node(pdev);
+       if (!dn)
+               return NULL;
+       return PCI_DN(dn);
+}
+
 /*
  * Traverse_func that inits the PCI fields of the device node.
  * NOTE: this *must* be done before read/write config to the device.
index d3e840d643af5135dc0b4e0acb6cec114967264a..c24684c818ab015cc9140d9870f26dc97bfb162a 100644 (file)
@@ -6,6 +6,7 @@ config PPC_POWERNV
        select PPC_ICP_NATIVE
        select PPC_P7_NAP
        select PPC_PCI_CHOICE if EMBEDDED
+       select EPAPR_BOOT
        default y
 
 config POWERNV_MSI
index 3937aaae5bc491108c2ae7deed7a1f555bdd8609..9c9d15e4cdf2700f803471667f83720430844c68 100644 (file)
@@ -68,16 +68,6 @@ define_pe_printk_level(pe_err, KERN_ERR);
 define_pe_printk_level(pe_warn, KERN_WARNING);
 define_pe_printk_level(pe_info, KERN_INFO);
 
-static struct pci_dn *pnv_ioda_get_pdn(struct pci_dev *dev)
-{
-       struct device_node *np;
-
-       np = pci_device_to_OF_node(dev);
-       if (!np)
-               return NULL;
-       return PCI_DN(np);
-}
-
 static int pnv_ioda_alloc_pe(struct pnv_phb *phb)
 {
        unsigned long pe;
@@ -110,7 +100,7 @@ static struct pnv_ioda_pe *pnv_ioda_get_pe(struct pci_dev *dev)
 {
        struct pci_controller *hose = pci_bus_to_host(dev->bus);
        struct pnv_phb *phb = hose->private_data;
-       struct pci_dn *pdn = pnv_ioda_get_pdn(dev);
+       struct pci_dn *pdn = pci_get_pdn(dev);
 
        if (!pdn)
                return NULL;
@@ -173,7 +163,7 @@ static int pnv_ioda_configure_pe(struct pnv_phb *phb, struct pnv_ioda_pe *pe)
 
        /* Add to all parents PELT-V */
        while (parent) {
-               struct pci_dn *pdn = pnv_ioda_get_pdn(parent);
+               struct pci_dn *pdn = pci_get_pdn(parent);
                if (pdn && pdn->pe_number != IODA_INVALID_PE) {
                        rc = opal_pci_set_peltv(phb->opal_id, pdn->pe_number,
                                                pe->pe_number, OPAL_ADD_PE_TO_DOMAIN);
@@ -252,7 +242,7 @@ static struct pnv_ioda_pe *pnv_ioda_setup_dev_PE(struct pci_dev *dev)
 {
        struct pci_controller *hose = pci_bus_to_host(dev->bus);
        struct pnv_phb *phb = hose->private_data;
-       struct pci_dn *pdn = pnv_ioda_get_pdn(dev);
+       struct pci_dn *pdn = pci_get_pdn(dev);
        struct pnv_ioda_pe *pe;
        int pe_num;
 
@@ -323,7 +313,7 @@ static void pnv_ioda_setup_same_PE(struct pci_bus *bus, struct pnv_ioda_pe *pe)
        struct pci_dev *dev;
 
        list_for_each_entry(dev, &bus->devices, bus_list) {
-               struct pci_dn *pdn = pnv_ioda_get_pdn(dev);
+               struct pci_dn *pdn = pci_get_pdn(dev);
 
                if (pdn == NULL) {
                        pr_warn("%s: No device node associated with device !\n",
@@ -436,7 +426,7 @@ static void pnv_pci_ioda_setup_PEs(void)
 
 static void pnv_pci_ioda_dma_dev_setup(struct pnv_phb *phb, struct pci_dev *pdev)
 {
-       struct pci_dn *pdn = pnv_ioda_get_pdn(pdev);
+       struct pci_dn *pdn = pci_get_pdn(pdev);
        struct pnv_ioda_pe *pe;
 
        /*
@@ -768,6 +758,7 @@ static int pnv_pci_ioda_msi_setup(struct pnv_phb *phb, struct pci_dev *dev,
                                  unsigned int is_64, struct msi_msg *msg)
 {
        struct pnv_ioda_pe *pe = pnv_ioda_get_pe(dev);
+       struct pci_dn *pdn = pci_get_pdn(dev);
        struct irq_data *idata;
        struct irq_chip *ichip;
        unsigned int xive_num = hwirq - phb->msi_base;
@@ -783,6 +774,10 @@ static int pnv_pci_ioda_msi_setup(struct pnv_phb *phb, struct pci_dev *dev,
        if (pe->mve_number < 0)
                return -ENXIO;
 
+       /* Force 32-bit MSI on some broken devices */
+       if (pdn && pdn->force_32bit_msi)
+               is_64 = 0;
+
        /* Assign XIVE to PE */
        rc = opal_pci_set_xive_pe(phb->opal_id, pe->pe_number, xive_num);
        if (rc) {
@@ -1035,7 +1030,7 @@ static int pnv_pci_enable_device_hook(struct pci_dev *dev)
        if (!phb->initialized)
                return 0;
 
-       pdn = pnv_ioda_get_pdn(dev);
+       pdn = pci_get_pdn(dev);
        if (!pdn || pdn->pe_number == IODA_INVALID_PE)
                return -EINVAL;
 
index 163bd7422f1ca555d79a7a8bfe1734ca44fc98fb..277343cc6a3d7f87966408f088a33b61f502ecda 100644 (file)
@@ -47,6 +47,10 @@ static int pnv_msi_check_device(struct pci_dev* pdev, int nvec, int type)
 {
        struct pci_controller *hose = pci_bus_to_host(pdev->bus);
        struct pnv_phb *phb = hose->private_data;
+       struct pci_dn *pdn = pci_get_pdn(pdev);
+
+       if (pdn && pdn->force_32bit_msi && !phb->msi32_support)
+               return -ENODEV;
 
        return (phb && phb->msi_bmp.bitmap) ? 0 : -ENODEV;
 }
@@ -367,7 +371,7 @@ static void pnv_tce_free(struct iommu_table *tbl, long index, long npages)
        while (npages--)
                *(tcep++) = 0;
 
-       if (tbl->it_type & TCE_PCI_SWINV_CREATE)
+       if (tbl->it_type & TCE_PCI_SWINV_FREE)
                pnv_pci_ioda_tce_invalidate(tbl, tces, tcep - 1);
 }
 
index 420524e6f8c95c6118462cefb80723312d213437..6d2f0abce6fae652d207b499ac99a47e20a500f2 100644 (file)
@@ -26,26 +26,6 @@ static int query_token, change_token;
 #define RTAS_CHANGE_MSIX_FN    4
 #define RTAS_CHANGE_32MSI_FN   5
 
-static struct pci_dn *get_pdn(struct pci_dev *pdev)
-{
-       struct device_node *dn;
-       struct pci_dn *pdn;
-
-       dn = pci_device_to_OF_node(pdev);
-       if (!dn) {
-               dev_dbg(&pdev->dev, "rtas_msi: No OF device node\n");
-               return NULL;
-       }
-
-       pdn = PCI_DN(dn);
-       if (!pdn) {
-               dev_dbg(&pdev->dev, "rtas_msi: No PCI DN\n");
-               return NULL;
-       }
-
-       return pdn;
-}
-
 /* RTAS Helpers */
 
 static int rtas_change_msi(struct pci_dn *pdn, u32 func, u32 num_irqs)
@@ -91,7 +71,7 @@ static void rtas_disable_msi(struct pci_dev *pdev)
 {
        struct pci_dn *pdn;
 
-       pdn = get_pdn(pdev);
+       pdn = pci_get_pdn(pdev);
        if (!pdn)
                return;
 
@@ -152,7 +132,7 @@ static int check_req(struct pci_dev *pdev, int nvec, char *prop_name)
        struct pci_dn *pdn;
        const u32 *req_msi;
 
-       pdn = get_pdn(pdev);
+       pdn = pci_get_pdn(pdev);
        if (!pdn)
                return -ENODEV;
 
@@ -394,6 +374,23 @@ static int check_msix_entries(struct pci_dev *pdev)
        return 0;
 }
 
+static void rtas_hack_32bit_msi_gen2(struct pci_dev *pdev)
+{
+       u32 addr_hi, addr_lo;
+
+       /*
+        * We should only get in here for IODA1 configs. This is based on the
+        * fact that we using RTAS for MSIs, we don't have the 32 bit MSI RTAS
+        * support, and we are in a PCIe Gen2 slot.
+        */
+       dev_info(&pdev->dev,
+                "rtas_msi: No 32 bit MSI firmware support, forcing 32 bit MSI\n");
+       pci_read_config_dword(pdev, pdev->msi_cap + PCI_MSI_ADDRESS_HI, &addr_hi);
+       addr_lo = 0xffff0000 | ((addr_hi >> (48 - 32)) << 4);
+       pci_write_config_dword(pdev, pdev->msi_cap + PCI_MSI_ADDRESS_LO, addr_lo);
+       pci_write_config_dword(pdev, pdev->msi_cap + PCI_MSI_ADDRESS_HI, 0);
+}
+
 static int rtas_setup_msi_irqs(struct pci_dev *pdev, int nvec_in, int type)
 {
        struct pci_dn *pdn;
@@ -401,8 +398,9 @@ static int rtas_setup_msi_irqs(struct pci_dev *pdev, int nvec_in, int type)
        struct msi_desc *entry;
        struct msi_msg msg;
        int nvec = nvec_in;
+       int use_32bit_msi_hack = 0;
 
-       pdn = get_pdn(pdev);
+       pdn = pci_get_pdn(pdev);
        if (!pdn)
                return -ENODEV;
 
@@ -428,15 +426,31 @@ static int rtas_setup_msi_irqs(struct pci_dev *pdev, int nvec_in, int type)
         */
 again:
        if (type == PCI_CAP_ID_MSI) {
-               if (pdn->force_32bit_msi)
+               if (pdn->force_32bit_msi) {
                        rc = rtas_change_msi(pdn, RTAS_CHANGE_32MSI_FN, nvec);
-               else
+                       if (rc < 0) {
+                               /*
+                                * We only want to run the 32 bit MSI hack below if
+                                * the max bus speed is Gen2 speed
+                                */
+                               if (pdev->bus->max_bus_speed != PCIE_SPEED_5_0GT)
+                                       return rc;
+
+                               use_32bit_msi_hack = 1;
+                       }
+               } else
+                       rc = -1;
+
+               if (rc < 0)
                        rc = rtas_change_msi(pdn, RTAS_CHANGE_MSI_FN, nvec);
 
-               if (rc < 0 && !pdn->force_32bit_msi) {
+               if (rc < 0) {
                        pr_debug("rtas_msi: trying the old firmware call.\n");
                        rc = rtas_change_msi(pdn, RTAS_CHANGE_FN, nvec);
                }
+
+               if (use_32bit_msi_hack && rc > 0)
+                       rtas_hack_32bit_msi_gen2(pdev);
        } else
                rc = rtas_change_msi(pdn, RTAS_CHANGE_MSIX_FN, nvec);
 
@@ -518,12 +532,3 @@ static int rtas_msi_init(void)
 }
 arch_initcall(rtas_msi_init);
 
-static void quirk_radeon(struct pci_dev *dev)
-{
-       struct pci_dn *pdn = get_pdn(dev);
-
-       if (pdn)
-               pdn->force_32bit_msi = 1;
-}
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x68f2, quirk_radeon);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0xaa68, quirk_radeon);
index d8f988a37d16a59518bac5e612a6d19d2bb0ad95..0940682ab38bdd700227226e22803e6310096aa5 100644 (file)
@@ -41,8 +41,6 @@
 unsigned long empty_zero_page;
 EXPORT_SYMBOL_GPL(empty_zero_page);
 
-static struct kcore_list kcore_mem, kcore_vmalloc;
-
 static void setup_zero_page(void)
 {
        struct page *page;
index 0e0fabf173429006612eb014ec591df98e4b2deb..6eb18c42a28a3584546e87a57f9cccf5af3473e3 100644 (file)
@@ -141,11 +141,6 @@ static int pci_device_update_fixed(struct pci_bus *bus, unsigned int devfn,
  */
 static bool type1_access_ok(unsigned int bus, unsigned int devfn, int reg)
 {
-       if (bus == 0 && (devfn == PCI_DEVFN(2, 0)
-                               || devfn == PCI_DEVFN(0, 0)
-                               || devfn == PCI_DEVFN(3, 0)))
-               return 1;
-
        /* This is a workaround for A0 LNC bug where PCI status register does
         * not have new CAP bit set. can not be written by SW either.
         *
@@ -155,7 +150,10 @@ static bool type1_access_ok(unsigned int bus, unsigned int devfn, int reg)
         */
        if (reg >= 0x100 || reg == PCI_STATUS || reg == PCI_HEADER_TYPE)
                return 0;
-
+       if (bus == 0 && (devfn == PCI_DEVFN(2, 0)
+                               || devfn == PCI_DEVFN(0, 0)
+                               || devfn == PCI_DEVFN(3, 0)))
+               return 1;
        return 0; /* langwell on others */
 }
 
index ecb743bf05a54c4541f028f60170f45dcd20bb8b..536562c626a2fab4bb20c128abcf27f4404ca23f 100644 (file)
@@ -24,7 +24,7 @@ acpi-y                                += nvs.o
 # Power management related files
 acpi-y                         += wakeup.o
 acpi-y                         += sleep.o
-acpi-$(CONFIG_PM)              += device_pm.o
+acpi-y                         += device_pm.o
 acpi-$(CONFIG_ACPI_SLEEP)      += proc.o
 
 
@@ -38,7 +38,6 @@ acpi-y                                += processor_core.o
 acpi-y                         += ec.o
 acpi-$(CONFIG_ACPI_DOCK)       += dock.o
 acpi-y                         += pci_root.o pci_link.o pci_irq.o
-acpi-y                         += csrt.o
 acpi-$(CONFIG_X86_INTEL_LPSS)  += acpi_lpss.o
 acpi-y                         += acpi_platform.o
 acpi-y                         += power.o
index b1c95422ce74ab79dd13937fd6a7ad260e1055e5..652fd5ce303c4a9efdbfa3f6d4eb330fba42a5bd 100644 (file)
@@ -35,11 +35,16 @@ ACPI_MODULE_NAME("acpi_lpss");
 
 struct lpss_device_desc {
        bool clk_required;
-       const char *clk_parent;
+       const char *clkdev_name;
        bool ltr_required;
        unsigned int prv_offset;
 };
 
+static struct lpss_device_desc lpss_dma_desc = {
+       .clk_required = true,
+       .clkdev_name = "hclk",
+};
+
 struct lpss_private_data {
        void __iomem *mmio_base;
        resource_size_t mmio_size;
@@ -49,7 +54,6 @@ struct lpss_private_data {
 
 static struct lpss_device_desc lpt_dev_desc = {
        .clk_required = true,
-       .clk_parent = "lpss_clk",
        .prv_offset = 0x800,
        .ltr_required = true,
 };
@@ -60,6 +64,9 @@ static struct lpss_device_desc lpt_sdio_dev_desc = {
 };
 
 static const struct acpi_device_id acpi_lpss_device_ids[] = {
+       /* Generic LPSS devices */
+       { "INTL9C60", (unsigned long)&lpss_dma_desc },
+
        /* Lynxpoint LPSS devices */
        { "INT33C0", (unsigned long)&lpt_dev_desc },
        { "INT33C1", (unsigned long)&lpt_dev_desc },
@@ -91,16 +98,27 @@ static int register_device_clock(struct acpi_device *adev,
                                 struct lpss_private_data *pdata)
 {
        const struct lpss_device_desc *dev_desc = pdata->dev_desc;
+       struct lpss_clk_data *clk_data;
 
        if (!lpss_clk_dev)
                lpt_register_clock_device();
 
-       if (!dev_desc->clk_parent || !pdata->mmio_base
+       clk_data = platform_get_drvdata(lpss_clk_dev);
+       if (!clk_data)
+               return -ENODEV;
+
+       if (dev_desc->clkdev_name) {
+               clk_register_clkdev(clk_data->clk, dev_desc->clkdev_name,
+                                   dev_name(&adev->dev));
+               return 0;
+       }
+
+       if (!pdata->mmio_base
            || pdata->mmio_size < dev_desc->prv_offset + LPSS_CLK_SIZE)
                return -ENODATA;
 
        pdata->clk = clk_register_gate(NULL, dev_name(&adev->dev),
-                                      dev_desc->clk_parent, 0,
+                                      clk_data->name, 0,
                                       pdata->mmio_base + dev_desc->prv_offset,
                                       0, 0, NULL);
        if (IS_ERR(pdata->clk))
diff --git a/drivers/acpi/csrt.c b/drivers/acpi/csrt.c
deleted file mode 100644 (file)
index 5c15a91..0000000
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Support for Core System Resources Table (CSRT)
- *
- * Copyright (C) 2013, Intel Corporation
- * Authors: Mika Westerberg <mika.westerberg@linux.intel.com>
- *         Andy Shevchenko <andriy.shevchenko@linux.intel.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#define pr_fmt(fmt) "ACPI: CSRT: " fmt
-
-#include <linux/acpi.h>
-#include <linux/device.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/sizes.h>
-
-ACPI_MODULE_NAME("CSRT");
-
-static int __init acpi_csrt_parse_shared_info(struct platform_device *pdev,
-                                             const struct acpi_csrt_group *grp)
-{
-       const struct acpi_csrt_shared_info *si;
-       struct resource res[3];
-       size_t nres;
-       int ret;
-
-       memset(res, 0, sizeof(res));
-       nres = 0;
-
-       si = (const struct acpi_csrt_shared_info *)&grp[1];
-       /*
-        * The peripherals that are listed on CSRT typically support only
-        * 32-bit addresses so we only use the low part of MMIO base for
-        * now.
-        */
-       if (!si->mmio_base_high && si->mmio_base_low) {
-               /*
-                * There is no size of the memory resource in shared_info
-                * so we assume that it is 4k here.
-                */
-               res[nres].start = si->mmio_base_low;
-               res[nres].end = res[0].start + SZ_4K - 1;
-               res[nres++].flags = IORESOURCE_MEM;
-       }
-
-       if (si->gsi_interrupt) {
-               int irq = acpi_register_gsi(NULL, si->gsi_interrupt,
-                                           si->interrupt_mode,
-                                           si->interrupt_polarity);
-               res[nres].start = irq;
-               res[nres].end = irq;
-               res[nres++].flags = IORESOURCE_IRQ;
-       }
-
-       if (si->base_request_line || si->num_handshake_signals) {
-               /*
-                * We pass the driver a DMA resource describing the range
-                * of request lines the device supports.
-                */
-               res[nres].start = si->base_request_line;
-               res[nres].end = res[nres].start + si->num_handshake_signals - 1;
-               res[nres++].flags = IORESOURCE_DMA;
-       }
-
-       ret = platform_device_add_resources(pdev, res, nres);
-       if (ret) {
-               if (si->gsi_interrupt)
-                       acpi_unregister_gsi(si->gsi_interrupt);
-               return ret;
-       }
-
-       return 0;
-}
-
-static int __init
-acpi_csrt_parse_resource_group(const struct acpi_csrt_group *grp)
-{
-       struct platform_device *pdev;
-       char vendor[5], name[16];
-       int ret, i;
-
-       vendor[0] = grp->vendor_id;
-       vendor[1] = grp->vendor_id >> 8;
-       vendor[2] = grp->vendor_id >> 16;
-       vendor[3] = grp->vendor_id >> 24;
-       vendor[4] = '\0';
-
-       if (grp->shared_info_length != sizeof(struct acpi_csrt_shared_info))
-               return -ENODEV;
-
-       snprintf(name, sizeof(name), "%s%04X", vendor, grp->device_id);
-       pdev = platform_device_alloc(name, PLATFORM_DEVID_AUTO);
-       if (!pdev)
-               return -ENOMEM;
-
-       /* Add resources based on the shared info */
-       ret = acpi_csrt_parse_shared_info(pdev, grp);
-       if (ret)
-               goto fail;
-
-       ret = platform_device_add(pdev);
-       if (ret)
-               goto fail;
-
-       for (i = 0; i < pdev->num_resources; i++)
-               dev_dbg(&pdev->dev, "%pR\n", &pdev->resource[i]);
-
-       return 0;
-
-fail:
-       platform_device_put(pdev);
-       return ret;
-}
-
-/*
- * CSRT or Core System Resources Table is a proprietary ACPI table
- * introduced by Microsoft. This table can contain devices that are not in
- * the system DSDT table. In particular DMA controllers might be described
- * here.
- *
- * We present these devices as normal platform devices that don't have ACPI
- * IDs or handle. The platform device name will be something like
- * <VENDOR><DEVID>.<n>.auto for example: INTL9C06.0.auto.
- */
-void __init acpi_csrt_init(void)
-{
-       struct acpi_csrt_group *grp, *end;
-       struct acpi_table_csrt *csrt;
-       acpi_status status;
-       int ret;
-
-       status = acpi_get_table(ACPI_SIG_CSRT, 0,
-                               (struct acpi_table_header **)&csrt);
-       if (ACPI_FAILURE(status)) {
-               if (status != AE_NOT_FOUND)
-                       pr_warn("failed to get the CSRT table\n");
-               return;
-       }
-
-       pr_debug("parsing CSRT table for devices\n");
-
-       grp = (struct acpi_csrt_group *)(csrt + 1);
-       end = (struct acpi_csrt_group *)((void *)csrt + csrt->header.length);
-
-       while (grp < end) {
-               ret = acpi_csrt_parse_resource_group(grp);
-               if (ret) {
-                       pr_warn("error in parsing resource group: %d\n", ret);
-                       return;
-               }
-
-               grp = (struct acpi_csrt_group *)((void *)grp + grp->length);
-       }
-}
index 96de787e6104d5509b024d27d4ad9b32527a1d7b..bc493aa3af19d87e42a18da312815de3c6fbb125 100644 (file)
 #define _COMPONENT     ACPI_POWER_COMPONENT
 ACPI_MODULE_NAME("device_pm");
 
-static DEFINE_MUTEX(acpi_pm_notifier_lock);
-
-/**
- * acpi_add_pm_notifier - Register PM notifier for given ACPI device.
- * @adev: ACPI device to add the notifier for.
- * @context: Context information to pass to the notifier routine.
- *
- * NOTE: @adev need not be a run-wake or wakeup device to be a valid source of
- * PM wakeup events.  For example, wakeup events may be generated for bridges
- * if one of the devices below the bridge is signaling wakeup, even if the
- * bridge itself doesn't have a wakeup GPE associated with it.
- */
-acpi_status acpi_add_pm_notifier(struct acpi_device *adev,
-                                acpi_notify_handler handler, void *context)
-{
-       acpi_status status = AE_ALREADY_EXISTS;
-
-       mutex_lock(&acpi_pm_notifier_lock);
-
-       if (adev->wakeup.flags.notifier_present)
-               goto out;
-
-       status = acpi_install_notify_handler(adev->handle,
-                                            ACPI_SYSTEM_NOTIFY,
-                                            handler, context);
-       if (ACPI_FAILURE(status))
-               goto out;
-
-       adev->wakeup.flags.notifier_present = true;
-
- out:
-       mutex_unlock(&acpi_pm_notifier_lock);
-       return status;
-}
-
-/**
- * acpi_remove_pm_notifier - Unregister PM notifier from given ACPI device.
- * @adev: ACPI device to remove the notifier from.
- */
-acpi_status acpi_remove_pm_notifier(struct acpi_device *adev,
-                                   acpi_notify_handler handler)
-{
-       acpi_status status = AE_BAD_PARAMETER;
-
-       mutex_lock(&acpi_pm_notifier_lock);
-
-       if (!adev->wakeup.flags.notifier_present)
-               goto out;
-
-       status = acpi_remove_notify_handler(adev->handle,
-                                           ACPI_SYSTEM_NOTIFY,
-                                           handler);
-       if (ACPI_FAILURE(status))
-               goto out;
-
-       adev->wakeup.flags.notifier_present = false;
-
- out:
-       mutex_unlock(&acpi_pm_notifier_lock);
-       return status;
-}
-
 /**
  * acpi_power_state_string - String representation of ACPI device power state.
  * @state: ACPI device power state to return the string representation of.
@@ -385,6 +323,69 @@ bool acpi_bus_power_manageable(acpi_handle handle)
 }
 EXPORT_SYMBOL(acpi_bus_power_manageable);
 
+#ifdef CONFIG_PM
+static DEFINE_MUTEX(acpi_pm_notifier_lock);
+
+/**
+ * acpi_add_pm_notifier - Register PM notifier for given ACPI device.
+ * @adev: ACPI device to add the notifier for.
+ * @context: Context information to pass to the notifier routine.
+ *
+ * NOTE: @adev need not be a run-wake or wakeup device to be a valid source of
+ * PM wakeup events.  For example, wakeup events may be generated for bridges
+ * if one of the devices below the bridge is signaling wakeup, even if the
+ * bridge itself doesn't have a wakeup GPE associated with it.
+ */
+acpi_status acpi_add_pm_notifier(struct acpi_device *adev,
+                                acpi_notify_handler handler, void *context)
+{
+       acpi_status status = AE_ALREADY_EXISTS;
+
+       mutex_lock(&acpi_pm_notifier_lock);
+
+       if (adev->wakeup.flags.notifier_present)
+               goto out;
+
+       status = acpi_install_notify_handler(adev->handle,
+                                            ACPI_SYSTEM_NOTIFY,
+                                            handler, context);
+       if (ACPI_FAILURE(status))
+               goto out;
+
+       adev->wakeup.flags.notifier_present = true;
+
+ out:
+       mutex_unlock(&acpi_pm_notifier_lock);
+       return status;
+}
+
+/**
+ * acpi_remove_pm_notifier - Unregister PM notifier from given ACPI device.
+ * @adev: ACPI device to remove the notifier from.
+ */
+acpi_status acpi_remove_pm_notifier(struct acpi_device *adev,
+                                   acpi_notify_handler handler)
+{
+       acpi_status status = AE_BAD_PARAMETER;
+
+       mutex_lock(&acpi_pm_notifier_lock);
+
+       if (!adev->wakeup.flags.notifier_present)
+               goto out;
+
+       status = acpi_remove_notify_handler(adev->handle,
+                                           ACPI_SYSTEM_NOTIFY,
+                                           handler);
+       if (ACPI_FAILURE(status))
+               goto out;
+
+       adev->wakeup.flags.notifier_present = false;
+
+ out:
+       mutex_unlock(&acpi_pm_notifier_lock);
+       return status;
+}
+
 bool acpi_bus_can_wakeup(acpi_handle handle)
 {
        struct acpi_device *device;
@@ -1023,3 +1024,4 @@ void acpi_dev_pm_remove_dependent(acpi_handle handle, struct device *depdev)
        mutex_unlock(&adev->physical_node_lock);
 }
 EXPORT_SYMBOL_GPL(acpi_dev_pm_remove_dependent);
+#endif /* CONFIG_PM */
index 6f1afd9118c806f728ce161033e932f3dcfc485f..297cbf456f86bee35300ef6c72058615663f563f 100644 (file)
@@ -35,7 +35,6 @@ void acpi_pci_link_init(void);
 void acpi_pci_root_hp_init(void);
 void acpi_platform_init(void);
 int acpi_sysfs_init(void);
-void acpi_csrt_init(void);
 #ifdef CONFIG_ACPI_CONTAINER
 void acpi_container_init(void);
 #else
index 1dd6f6c8587442ab1fcbdf7d7bd78d98ef551a9b..e427dc516c76d1d8d73b5a91c7d4f1f73b83cfbf 100644 (file)
@@ -641,7 +641,9 @@ static void _handle_hotplug_event_root(struct work_struct *work)
                /* bus enumerate */
                printk(KERN_DEBUG "%s: Bus check notify on %s\n", __func__,
                                 (char *)buffer.pointer);
-               if (!root)
+               if (root)
+                       acpiphp_check_host_bridge(handle);
+               else
                        handle_root_bridge_insertion(handle);
 
                break;
index c1bc608339a6007b9d1ecbbd0f2669626d4a538f..44225cb15f3a248fb842c6e3b3d3f188f47aa99d 100644 (file)
@@ -2043,7 +2043,6 @@ int __init acpi_scan_init(void)
        acpi_pci_link_init();
        acpi_platform_init();
        acpi_lpss_init();
-       acpi_csrt_init();
        acpi_container_init();
        acpi_memory_hotplug_init();
 
index 66f67626f02ec42c5324085fc0a026f2ffca783d..e6bd910bc6edee4b55e3b6de7888bdd5c5ec06f6 100644 (file)
@@ -161,6 +161,14 @@ static struct dmi_system_id video_detect_dmi_table[] = {
                DMI_MATCH(DMI_PRODUCT_NAME, "UL30VT"),
                },
        },
+       {
+       .callback = video_detect_force_vendor,
+       .ident = "Asus UL30A",
+       .matches = {
+               DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
+               DMI_MATCH(DMI_PRODUCT_NAME, "UL30A"),
+               },
+       },
        { },
 };
 
index 1a68f947ded86c45e546c837005704a1ed45f293..d414331b480e72afc9ac8ac505dee449f1c795d9 100644 (file)
@@ -1295,6 +1295,7 @@ int subsys_virtual_register(struct bus_type *subsys,
 
        return subsys_register(subsys, groups, virtual_dir);
 }
+EXPORT_SYMBOL_GPL(subsys_virtual_register);
 
 int __init buses_init(void)
 {
index 016312437577ca3378706560a77068dcda67de81..2499cefdcdf2429d9503506d5514a4943f9ec4e1 100644 (file)
@@ -572,9 +572,11 @@ int device_create_file(struct device *dev,
 
        if (dev) {
                WARN(((attr->attr.mode & S_IWUGO) && !attr->store),
-                               "Write permission without 'store'\n");
+                       "Attribute %s: write permission without 'store'\n",
+                       attr->attr.name);
                WARN(((attr->attr.mode & S_IRUGO) && !attr->show),
-                               "Read permission without 'show'\n");
+                       "Attribute %s: read permission without 'show'\n",
+                       attr->attr.name);
                error = sysfs_create_file(&dev->kobj, &attr->attr);
        }
 
index bca9c80056febb4f90215534ca67d6adbf0aee80..8bffa5c9818c8e598a7f1408bd56a511f5773f29 100644 (file)
@@ -84,6 +84,8 @@ static const struct bcma_device_id_name bcma_bcm_device_names[] = {
        { BCMA_CORE_I2S, "I2S" },
        { BCMA_CORE_SDR_DDR1_MEM_CTL, "SDR/DDR1 Memory Controller" },
        { BCMA_CORE_SHIM, "SHIM" },
+       { BCMA_CORE_PCIE2, "PCIe Gen2" },
+       { BCMA_CORE_ARM_CR4, "ARM CR4" },
        { BCMA_CORE_DEFAULT, "Default" },
 };
 
index f1a29f8e9d33dbe45474172a24f952f32ce4ba47..9bf4371755f22fa93d4ccbe7d2bb605ec56a4048 100644 (file)
@@ -117,13 +117,13 @@ static struct page *brd_insert_page(struct brd_device *brd, sector_t sector)
 
        spin_lock(&brd->brd_lock);
        idx = sector >> PAGE_SECTORS_SHIFT;
+       page->index = idx;
        if (radix_tree_insert(&brd->brd_pages, idx, page)) {
                __free_page(page);
                page = radix_tree_lookup(&brd->brd_pages, idx);
                BUG_ON(!page);
                BUG_ON(page->index != idx);
-       } else
-               page->index = idx;
+       }
        spin_unlock(&brd->brd_lock);
 
        radix_tree_preload_end();
index f8ef15f37c5ec67eb6a35151b756c7496a1a666d..3fd130fdfbc1f742aa706ea96aa5d20361d05d37 100644 (file)
@@ -1160,8 +1160,7 @@ static int ace_probe(struct platform_device *dev)
        dev_dbg(&dev->dev, "ace_probe(%p)\n", dev);
 
        /* device id and bus width */
-       of_property_read_u32(dev->dev.of_node, "port-number", &id);
-       if (id < 0)
+       if (of_property_read_u32(dev->dev.of_node, "port-number", &id))
                id = 0;
        if (of_find_property(dev->dev.of_node, "8-bit", NULL))
                bus_width = ACE_BUS_WIDTH_8;
index dafd9ac6428f2de6e4c2120c675337307d8bd9d6..0913d79424d3a3e81930a4c138979a621de18605 100644 (file)
@@ -622,9 +622,12 @@ static int lp_do_ioctl(unsigned int minor, unsigned int cmd,
                                return -EFAULT;
                        break;
                case LPGETSTATUS:
+                       if (mutex_lock_interruptible(&lp_table[minor].port_mutex))
+                               return -EINTR;
                        lp_claim_parport_or_block (&lp_table[minor]);
                        status = r_str(minor);
                        lp_release_parport (&lp_table[minor]);
+                       mutex_unlock(&lp_table[minor].port_mutex);
 
                        if (copy_to_user(argp, &status, sizeof(int)))
                                return -EFAULT;
index cd9a6211dcadd61243905335a87d1e75bd91940e..35487e8ded59f106e3a7b157aa3d5bf46f9579e8 100644 (file)
@@ -865,16 +865,24 @@ static size_t account(struct entropy_store *r, size_t nbytes, int min,
        if (r->entropy_count / 8 < min + reserved) {
                nbytes = 0;
        } else {
+               int entropy_count, orig;
+retry:
+               entropy_count = orig = ACCESS_ONCE(r->entropy_count);
                /* If limited, never pull more than available */
-               if (r->limit && nbytes + reserved >= r->entropy_count / 8)
-                       nbytes = r->entropy_count/8 - reserved;
-
-               if (r->entropy_count / 8 >= nbytes + reserved)
-                       r->entropy_count -= nbytes*8;
-               else
-                       r->entropy_count = reserved;
+               if (r->limit && nbytes + reserved >= entropy_count / 8)
+                       nbytes = entropy_count/8 - reserved;
+
+               if (entropy_count / 8 >= nbytes + reserved) {
+                       entropy_count -= nbytes*8;
+                       if (cmpxchg(&r->entropy_count, orig, entropy_count) != orig)
+                               goto retry;
+               } else {
+                       entropy_count = reserved;
+                       if (cmpxchg(&r->entropy_count, orig, entropy_count) != orig)
+                               goto retry;
+               }
 
-               if (r->entropy_count < random_write_wakeup_thresh)
+               if (entropy_count < random_write_wakeup_thresh)
                        wakeup_write = 1;
        }
 
@@ -957,10 +965,23 @@ static ssize_t extract_entropy(struct entropy_store *r, void *buf,
 {
        ssize_t ret = 0, i;
        __u8 tmp[EXTRACT_SIZE];
+       unsigned long flags;
 
        /* if last_data isn't primed, we need EXTRACT_SIZE extra bytes */
-       if (fips_enabled && !r->last_data_init)
-               nbytes += EXTRACT_SIZE;
+       if (fips_enabled) {
+               spin_lock_irqsave(&r->lock, flags);
+               if (!r->last_data_init) {
+                       r->last_data_init = true;
+                       spin_unlock_irqrestore(&r->lock, flags);
+                       trace_extract_entropy(r->name, EXTRACT_SIZE,
+                                             r->entropy_count, _RET_IP_);
+                       xfer_secondary_pool(r, EXTRACT_SIZE);
+                       extract_buf(r, tmp);
+                       spin_lock_irqsave(&r->lock, flags);
+                       memcpy(r->last_data, tmp, EXTRACT_SIZE);
+               }
+               spin_unlock_irqrestore(&r->lock, flags);
+       }
 
        trace_extract_entropy(r->name, nbytes, r->entropy_count, _RET_IP_);
        xfer_secondary_pool(r, nbytes);
@@ -970,19 +991,6 @@ static ssize_t extract_entropy(struct entropy_store *r, void *buf,
                extract_buf(r, tmp);
 
                if (fips_enabled) {
-                       unsigned long flags;
-
-
-                       /* prime last_data value if need be, per fips 140-2 */
-                       if (!r->last_data_init) {
-                               spin_lock_irqsave(&r->lock, flags);
-                               memcpy(r->last_data, tmp, EXTRACT_SIZE);
-                               r->last_data_init = true;
-                               nbytes -= EXTRACT_SIZE;
-                               spin_unlock_irqrestore(&r->lock, flags);
-                               extract_buf(r, tmp);
-                       }
-
                        spin_lock_irqsave(&r->lock, flags);
                        if (!memcmp(tmp, r->last_data, EXTRACT_SIZE))
                                panic("Hardware RNG duplicated output!\n");
index 4945bd3d18d0e9de294ba2f1fb8c996662820a39..d5d2e4a985aa8602ff75f840f6af7e963f68471d 100644 (file)
@@ -179,7 +179,6 @@ static int __init ttyprintk_init(void)
 {
        int ret = -ENOMEM;
 
-       tpk_port.port.ops = &null_ops;
        mutex_init(&tpk_port.port_write_mutex);
 
        ttyprintk_driver = tty_alloc_driver(1,
@@ -190,6 +189,7 @@ static int __init ttyprintk_init(void)
                return PTR_ERR(ttyprintk_driver);
 
        tty_port_init(&tpk_port.port);
+       tpk_port.port.ops = &null_ops;
 
        ttyprintk_driver->driver_name = "ttyprintk";
        ttyprintk_driver->name = "ttyprintk";
index 8292a00c3de9f1dbae8b19e23b6ac45b3d275866..075db0c99edb9b8569556d853fbaee0e88c2cb2c 100644 (file)
@@ -872,6 +872,14 @@ static void __init tegra20_periph_clk_init(void)
        struct clk *clk;
        int i;
 
+       /* ac97 */
+       clk = tegra_clk_register_periph_gate("ac97", "pll_a_out0",
+                                   TEGRA_PERIPH_ON_APB,
+                                   clk_base, 0, 3, &periph_l_regs,
+                                   periph_clk_enb_refcnt);
+       clk_register_clkdev(clk, NULL, "tegra20-ac97");
+       clks[ac97] = clk;
+
        /* apbdma */
        clk = tegra_clk_register_periph_gate("apbdma", "pclk", 0, clk_base,
                                    0, 34, &periph_h_regs,
@@ -1234,9 +1242,6 @@ static __initdata struct tegra_clk_init_table init_table[] = {
        {uartc, pll_p, 0, 0},
        {uartd, pll_p, 0, 0},
        {uarte, pll_p, 0, 0},
-       {usbd, clk_max, 12000000, 0},
-       {usb2, clk_max, 12000000, 0},
-       {usb3, clk_max, 12000000, 0},
        {pll_a, clk_max, 56448000, 1},
        {pll_a_out0, clk_max, 11289600, 1},
        {cdev1, clk_max, 0, 1},
index 5cf4f4686406e639e71353984ea7b84d0bc2709b..4f45eee9e33b2746f95c42867c2339f67707fb30 100644 (file)
 #include <linux/clk-provider.h>
 #include <linux/err.h>
 #include <linux/module.h>
+#include <linux/platform_data/clk-lpss.h>
 #include <linux/platform_device.h>
 
 #define PRV_CLOCK_PARAMS 0x800
 
 static int lpt_clk_probe(struct platform_device *pdev)
 {
+       struct lpss_clk_data *drvdata;
        struct clk *clk;
 
+       drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
+       if (!drvdata)
+               return -ENOMEM;
+
        /* LPSS free running clock */
-       clk = clk_register_fixed_rate(&pdev->dev, "lpss_clk", NULL, CLK_IS_ROOT,
-                                     100000000);
+       drvdata->name = "lpss_clk";
+       clk = clk_register_fixed_rate(&pdev->dev, drvdata->name, NULL,
+                                     CLK_IS_ROOT, 100000000);
        if (IS_ERR(clk))
                return PTR_ERR(clk);
 
-       /* Shared DMA clock */
-       clk_register_clkdev(clk, "hclk", "INTL9C60.0.auto");
+       drvdata->clk = clk;
+       platform_set_drvdata(pdev, drvdata);
        return 0;
 }
 
index 2b8a8c3745486d4cdf62c79490ad263815bf6032..6bd63d63d356ba0f2fc731e65824409cee9bf158 100644 (file)
@@ -272,7 +272,7 @@ config X86_LONGHAUL
 config X86_E_POWERSAVER
        tristate "VIA C7 Enhanced PowerSaver (DANGEROUS)"
        select CPU_FREQ_TABLE
-       depends on X86_32
+       depends on X86_32 && ACPI_PROCESSOR
        help
          This adds the CPUFreq driver for VIA C7 processors.  However, this driver
          does not have any safeguards to prevent operating the CPU out of spec
index 173ed059d95f5fa2d46093d69b7912d1074df3de..fd9e3ea6a480aad30c0f9c593eb683470605e36d 100644 (file)
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
+#include <linux/cpu.h>
 #include <linux/cpufreq.h>
 #include <linux/device.h>
 #include <linux/export.h>
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/opp.h>
+#include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/types.h>
 #include "arm_big_little.h"
 
-static int dt_init_opp_table(struct device *cpu_dev)
+/* get cpu node with valid operating-points */
+static struct device_node *get_cpu_node_with_valid_op(int cpu)
 {
-       struct device_node *np, *parent;
-       int count = 0, ret;
+       struct device_node *np = NULL, *parent;
+       int count = 0;
 
        parent = of_find_node_by_path("/cpus");
        if (!parent) {
                pr_err("failed to find OF /cpus\n");
-               return -ENOENT;
+               return NULL;
        }
 
        for_each_child_of_node(parent, np) {
-               if (count++ != cpu_dev->id)
+               if (count++ != cpu)
                        continue;
                if (!of_get_property(np, "operating-points", NULL)) {
-                       ret = -ENODATA;
-               } else {
-                       cpu_dev->of_node = np;
-                       ret = of_init_opp_table(cpu_dev);
+                       of_node_put(np);
+                       np = NULL;
                }
-               of_node_put(np);
-               of_node_put(parent);
 
-               return ret;
+               break;
        }
 
-       return -ENODEV;
+       of_node_put(parent);
+       return np;
+}
+
+static int dt_init_opp_table(struct device *cpu_dev)
+{
+       struct device_node *np;
+       int ret;
+
+       np = get_cpu_node_with_valid_op(cpu_dev->id);
+       if (!np)
+               return -ENODATA;
+
+       cpu_dev->of_node = np;
+       ret = of_init_opp_table(cpu_dev);
+       of_node_put(np);
+
+       return ret;
 }
 
 static int dt_get_transition_latency(struct device *cpu_dev)
 {
-       struct device_node *np, *parent;
+       struct device_node *np;
        u32 transition_latency = CPUFREQ_ETERNAL;
-       int count = 0;
 
-       parent = of_find_node_by_path("/cpus");
-       if (!parent) {
-               pr_info("Failed to find OF /cpus. Use CPUFREQ_ETERNAL transition latency\n");
+       np = get_cpu_node_with_valid_op(cpu_dev->id);
+       if (!np)
                return CPUFREQ_ETERNAL;
-       }
-
-       for_each_child_of_node(parent, np) {
-               if (count++ != cpu_dev->id)
-                       continue;
 
-               of_property_read_u32(np, "clock-latency", &transition_latency);
-               of_node_put(np);
-               of_node_put(parent);
+       of_property_read_u32(np, "clock-latency", &transition_latency);
+       of_node_put(np);
 
-               return transition_latency;
-       }
-
-       pr_info("clock-latency isn't found, use CPUFREQ_ETERNAL transition latency\n");
-       return CPUFREQ_ETERNAL;
+       pr_debug("%s: clock-latency: %d\n", __func__, transition_latency);
+       return transition_latency;
 }
 
 static struct cpufreq_arm_bL_ops dt_bL_ops = {
@@ -91,17 +96,33 @@ static struct cpufreq_arm_bL_ops dt_bL_ops = {
        .init_opp_table = dt_init_opp_table,
 };
 
-static int generic_bL_init(void)
+static int generic_bL_probe(struct platform_device *pdev)
 {
+       struct device_node *np;
+
+       np = get_cpu_node_with_valid_op(0);
+       if (!np)
+               return -ENODEV;
+
+       of_node_put(np);
        return bL_cpufreq_register(&dt_bL_ops);
 }
-module_init(generic_bL_init);
 
-static void generic_bL_exit(void)
+static int generic_bL_remove(struct platform_device *pdev)
 {
-       return bL_cpufreq_unregister(&dt_bL_ops);
+       bL_cpufreq_unregister(&dt_bL_ops);
+       return 0;
 }
-module_exit(generic_bL_exit);
+
+static struct platform_driver generic_bL_platdrv = {
+       .driver = {
+               .name   = "arm-bL-cpufreq-dt",
+               .owner  = THIS_MODULE,
+       },
+       .probe          = generic_bL_probe,
+       .remove         = generic_bL_remove,
+};
+module_platform_driver(generic_bL_platdrv);
 
 MODULE_AUTHOR("Viresh Kumar <viresh.kumar@linaro.org>");
 MODULE_DESCRIPTION("Generic ARM big LITTLE cpufreq driver via DT");
index 4b8c7f297d74db41778aa31b5e0fbcf4c389bda5..2d53f47d1747360b8968c7c308c0f975777ef9ab 100644 (file)
@@ -1729,18 +1729,23 @@ static int __cpufreq_set_policy(struct cpufreq_policy *data,
                        /* end old governor */
                        if (data->governor) {
                                __cpufreq_governor(data, CPUFREQ_GOV_STOP);
+                               unlock_policy_rwsem_write(policy->cpu);
                                __cpufreq_governor(data,
                                                CPUFREQ_GOV_POLICY_EXIT);
+                               lock_policy_rwsem_write(policy->cpu);
                        }
 
                        /* start new governor */
                        data->governor = policy->governor;
                        if (!__cpufreq_governor(data, CPUFREQ_GOV_POLICY_INIT)) {
-                               if (!__cpufreq_governor(data, CPUFREQ_GOV_START))
+                               if (!__cpufreq_governor(data, CPUFREQ_GOV_START)) {
                                        failed = 0;
-                               else
+                               } else {
+                                       unlock_policy_rwsem_write(policy->cpu);
                                        __cpufreq_governor(data,
                                                        CPUFREQ_GOV_POLICY_EXIT);
+                                       lock_policy_rwsem_write(policy->cpu);
+                               }
                        }
 
                        if (failed) {
index 9c36ace92a39c4c0d501fb4692c91a19af132727..07f2840ad80596b529488f40808e10c70782f498 100644 (file)
@@ -521,6 +521,7 @@ static void intel_pstate_timer_func(unsigned long __data)
 static const struct x86_cpu_id intel_pstate_cpu_ids[] = {
        ICPU(0x2a, default_policy),
        ICPU(0x2d, default_policy),
+       ICPU(0x3a, default_policy),
        {}
 };
 MODULE_DEVICE_TABLE(x86cpu, intel_pstate_cpu_ids);
index 84889573b5669f22e1632108c5f32b94285d5814..d53912768946b96c1c27b017dbaeb7a10e7c2feb 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/platform_device.h>
 
 #include <asm/clock.h>
+#include <asm/idle.h>
 
 #include <asm/mach-loongson/loongson.h>
 
@@ -200,6 +201,7 @@ static void loongson2_cpu_wait(void)
        LOONGSON_CHIPCFG0 &= ~0x7;      /* Put CPU into wait mode */
        LOONGSON_CHIPCFG0 = cpu_freq;   /* Restore CPU state */
        spin_unlock_irqrestore(&loongson2_wait_lock, flags);
+       local_irq_enable();
 }
 
 static int __init cpufreq_init(void)
index a76d4c4f29f50798ed3ecafaa871d98a7d02c7e3..35d483f8db66b2a3ecb204181ffd0d43b0aaaffe 100644 (file)
@@ -126,6 +126,7 @@ struct crypto_alg nx_cbc_aes_alg = {
        .cra_blocksize   = AES_BLOCK_SIZE,
        .cra_ctxsize     = sizeof(struct nx_crypto_ctx),
        .cra_type        = &crypto_blkcipher_type,
+       .cra_alignmask   = 0xf,
        .cra_module      = THIS_MODULE,
        .cra_init        = nx_crypto_ctx_aes_cbc_init,
        .cra_exit        = nx_crypto_ctx_exit,
index ba5f1611336fe9fa5165cfa680e7acc2b7e38637..7bbc9a81da219e5c27e021c9ef6c880d194c90d3 100644 (file)
@@ -123,6 +123,7 @@ struct crypto_alg nx_ecb_aes_alg = {
        .cra_priority    = 300,
        .cra_flags       = CRYPTO_ALG_TYPE_BLKCIPHER,
        .cra_blocksize   = AES_BLOCK_SIZE,
+       .cra_alignmask   = 0xf,
        .cra_ctxsize     = sizeof(struct nx_crypto_ctx),
        .cra_type        = &crypto_blkcipher_type,
        .cra_module      = THIS_MODULE,
index c8109edc5cfb02063c1bd6c5914985846bccac2a..6cca6c392b00f34fa65ad4663b1725bd7b3842fe 100644 (file)
@@ -219,7 +219,7 @@ static int gcm_aes_nx_crypt(struct aead_request *req, int enc)
        if (enc)
                NX_CPB_FDM(csbcpb) |= NX_FDM_ENDE_ENCRYPT;
        else
-               nbytes -= AES_BLOCK_SIZE;
+               nbytes -= crypto_aead_authsize(crypto_aead_reqtfm(req));
 
        csbcpb->cpb.aes_gcm.bit_length_data = nbytes * 8;
 
index 9767315f8c0bd069a451f1a2c74bbf2f2bff628d..67024f2f0b78746bdbfcb8c5ffde595754a0b155 100644 (file)
@@ -69,7 +69,7 @@ static int nx_sha256_update(struct shash_desc *desc, const u8 *data,
         *  1: <= SHA256_BLOCK_SIZE: copy into state, return 0
         *  2: > SHA256_BLOCK_SIZE: process X blocks, copy in leftover
         */
-       if (len + sctx->count <= SHA256_BLOCK_SIZE) {
+       if (len + sctx->count < SHA256_BLOCK_SIZE) {
                memcpy(sctx->buf + sctx->count, data, len);
                sctx->count += len;
                goto out;
@@ -110,7 +110,8 @@ static int nx_sha256_update(struct shash_desc *desc, const u8 *data,
        atomic_inc(&(nx_ctx->stats->sha256_ops));
 
        /* copy the leftover back into the state struct */
-       memcpy(sctx->buf, data + len - leftover, leftover);
+       if (leftover)
+               memcpy(sctx->buf, data + len - leftover, leftover);
        sctx->count = leftover;
 
        csbcpb->cpb.sha256.message_bit_length += (u64)
@@ -130,6 +131,7 @@ static int nx_sha256_final(struct shash_desc *desc, u8 *out)
        struct nx_sg *in_sg, *out_sg;
        int rc;
 
+
        if (NX_CPB_FDM(csbcpb) & NX_FDM_CONTINUATION) {
                /* we've hit the nx chip previously, now we're finalizing,
                 * so copy over the partial digest */
@@ -162,7 +164,7 @@ static int nx_sha256_final(struct shash_desc *desc, u8 *out)
 
        atomic_inc(&(nx_ctx->stats->sha256_ops));
 
-       atomic64_add(csbcpb->cpb.sha256.message_bit_length,
+       atomic64_add(csbcpb->cpb.sha256.message_bit_length / 8,
                     &(nx_ctx->stats->sha256_bytes));
        memcpy(out, csbcpb->cpb.sha256.message_digest, SHA256_DIGEST_SIZE);
 out:
index 3177b8c3d5f1e3073ef559d902fe3cd488e8360b..08eee11223490c7a1a249a2f559f960e72e7af2c 100644 (file)
@@ -69,7 +69,7 @@ static int nx_sha512_update(struct shash_desc *desc, const u8 *data,
         *  1: <= SHA512_BLOCK_SIZE: copy into state, return 0
         *  2: > SHA512_BLOCK_SIZE: process X blocks, copy in leftover
         */
-       if ((u64)len + sctx->count[0] <= SHA512_BLOCK_SIZE) {
+       if ((u64)len + sctx->count[0] < SHA512_BLOCK_SIZE) {
                memcpy(sctx->buf + sctx->count[0], data, len);
                sctx->count[0] += len;
                goto out;
@@ -110,7 +110,8 @@ static int nx_sha512_update(struct shash_desc *desc, const u8 *data,
        atomic_inc(&(nx_ctx->stats->sha512_ops));
 
        /* copy the leftover back into the state struct */
-       memcpy(sctx->buf, data + len - leftover, leftover);
+       if (leftover)
+               memcpy(sctx->buf, data + len - leftover, leftover);
        sctx->count[0] = leftover;
 
        spbc_bits = csbcpb->cpb.sha512.spbc * 8;
@@ -168,7 +169,7 @@ static int nx_sha512_final(struct shash_desc *desc, u8 *out)
                goto out;
 
        atomic_inc(&(nx_ctx->stats->sha512_ops));
-       atomic64_add(csbcpb->cpb.sha512.message_bit_length_lo,
+       atomic64_add(csbcpb->cpb.sha512.message_bit_length_lo / 8,
                     &(nx_ctx->stats->sha512_bytes));
 
        memcpy(out, csbcpb->cpb.sha512.message_digest, SHA512_DIGEST_SIZE);
index c767f232e6933bc876adedd56a1f7e655f93c815..bbdab6e5ccf08f75fcc23481dbb9d29a1df6cd69 100644 (file)
@@ -211,44 +211,20 @@ int nx_build_sg_lists(struct nx_crypto_ctx  *nx_ctx,
 {
        struct nx_sg *nx_insg = nx_ctx->in_sg;
        struct nx_sg *nx_outsg = nx_ctx->out_sg;
-       struct blkcipher_walk walk;
-       int rc;
-
-       blkcipher_walk_init(&walk, dst, src, nbytes);
-       rc = blkcipher_walk_virt_block(desc, &walk, AES_BLOCK_SIZE);
-       if (rc)
-               goto out;
 
        if (iv)
-               memcpy(iv, walk.iv, AES_BLOCK_SIZE);
+               memcpy(iv, desc->info, AES_BLOCK_SIZE);
 
-       while (walk.nbytes) {
-               nx_insg = nx_build_sg_list(nx_insg, walk.src.virt.addr,
-                                          walk.nbytes, nx_ctx->ap->sglen);
-               nx_outsg = nx_build_sg_list(nx_outsg, walk.dst.virt.addr,
-                                           walk.nbytes, nx_ctx->ap->sglen);
-
-               rc = blkcipher_walk_done(desc, &walk, 0);
-               if (rc)
-                       break;
-       }
-
-       if (walk.nbytes) {
-               nx_insg = nx_build_sg_list(nx_insg, walk.src.virt.addr,
-                                          walk.nbytes, nx_ctx->ap->sglen);
-               nx_outsg = nx_build_sg_list(nx_outsg, walk.dst.virt.addr,
-                                           walk.nbytes, nx_ctx->ap->sglen);
-
-               rc = 0;
-       }
+       nx_insg = nx_walk_and_build(nx_insg, nx_ctx->ap->sglen, src, 0, nbytes);
+       nx_outsg = nx_walk_and_build(nx_outsg, nx_ctx->ap->sglen, dst, 0, nbytes);
 
        /* these lengths should be negative, which will indicate to phyp that
         * the input and output parameters are scatterlists, not linear
         * buffers */
        nx_ctx->op.inlen = (nx_ctx->in_sg - nx_insg) * sizeof(struct nx_sg);
        nx_ctx->op.outlen = (nx_ctx->out_sg - nx_outsg) * sizeof(struct nx_sg);
-out:
-       return rc;
+
+       return 0;
 }
 
 /**
@@ -454,6 +430,8 @@ static int nx_register_algs(void)
        if (rc)
                goto out;
 
+       nx_driver.of.status = NX_OKAY;
+
        rc = crypto_register_alg(&nx_ecb_aes_alg);
        if (rc)
                goto out;
@@ -498,8 +476,6 @@ static int nx_register_algs(void)
        if (rc)
                goto out_unreg_s512;
 
-       nx_driver.of.status = NX_OKAY;
-
        goto out;
 
 out_unreg_s512:
index ba6fc62e965163bca45cd55d148188812e08374a..5a18f82f732af57a319628190713e6bd054cf8b3 100644 (file)
@@ -4,7 +4,8 @@
  * Based on of-dma.c
  *
  * Copyright (C) 2013, Intel Corporation
- * Author: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+ * Authors: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+ *         Mika Westerberg <mika.westerberg@linux.intel.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
 #include <linux/list.h>
 #include <linux/mutex.h>
 #include <linux/slab.h>
+#include <linux/ioport.h>
 #include <linux/acpi.h>
 #include <linux/acpi_dma.h>
 
 static LIST_HEAD(acpi_dma_list);
 static DEFINE_MUTEX(acpi_dma_lock);
 
+/**
+ * acpi_dma_parse_resource_group - match device and parse resource group
+ * @grp:       CSRT resource group
+ * @adev:      ACPI device to match with
+ * @adma:      struct acpi_dma of the given DMA controller
+ *
+ * Returns 1 on success, 0 when no information is available, or appropriate
+ * errno value on error.
+ *
+ * In order to match a device from DSDT table to the corresponding CSRT device
+ * we use MMIO address and IRQ.
+ */
+static int acpi_dma_parse_resource_group(const struct acpi_csrt_group *grp,
+               struct acpi_device *adev, struct acpi_dma *adma)
+{
+       const struct acpi_csrt_shared_info *si;
+       struct list_head resource_list;
+       struct resource_list_entry *rentry;
+       resource_size_t mem = 0, irq = 0;
+       u32 vendor_id;
+       int ret;
+
+       if (grp->shared_info_length != sizeof(struct acpi_csrt_shared_info))
+               return -ENODEV;
+
+       INIT_LIST_HEAD(&resource_list);
+       ret = acpi_dev_get_resources(adev, &resource_list, NULL, NULL);
+       if (ret <= 0)
+               return 0;
+
+       list_for_each_entry(rentry, &resource_list, node) {
+               if (resource_type(&rentry->res) == IORESOURCE_MEM)
+                       mem = rentry->res.start;
+               else if (resource_type(&rentry->res) == IORESOURCE_IRQ)
+                       irq = rentry->res.start;
+       }
+
+       acpi_dev_free_resource_list(&resource_list);
+
+       /* Consider initial zero values as resource not found */
+       if (mem == 0 && irq == 0)
+               return 0;
+
+       si = (const struct acpi_csrt_shared_info *)&grp[1];
+
+       /* Match device by MMIO and IRQ */
+       if (si->mmio_base_low != mem || si->gsi_interrupt != irq)
+               return 0;
+
+       vendor_id = le32_to_cpu(grp->vendor_id);
+       dev_dbg(&adev->dev, "matches with %.4s%04X (rev %u)\n",
+               (char *)&vendor_id, grp->device_id, grp->revision);
+
+       /* Check if the request line range is available */
+       if (si->base_request_line == 0 && si->num_handshake_signals == 0)
+               return 0;
+
+       adma->base_request_line = si->base_request_line;
+       adma->end_request_line = si->base_request_line +
+                                si->num_handshake_signals - 1;
+
+       dev_dbg(&adev->dev, "request line base: 0x%04x end: 0x%04x\n",
+               adma->base_request_line, adma->end_request_line);
+
+       return 1;
+}
+
+/**
+ * acpi_dma_parse_csrt - parse CSRT to exctract additional DMA resources
+ * @adev:      ACPI device to match with
+ * @adma:      struct acpi_dma of the given DMA controller
+ *
+ * CSRT or Core System Resources Table is a proprietary ACPI table
+ * introduced by Microsoft. This table can contain devices that are not in
+ * the system DSDT table. In particular DMA controllers might be described
+ * here.
+ *
+ * We are using this table to get the request line range of the specific DMA
+ * controller to be used later.
+ *
+ */
+static void acpi_dma_parse_csrt(struct acpi_device *adev, struct acpi_dma *adma)
+{
+       struct acpi_csrt_group *grp, *end;
+       struct acpi_table_csrt *csrt;
+       acpi_status status;
+       int ret;
+
+       status = acpi_get_table(ACPI_SIG_CSRT, 0,
+                               (struct acpi_table_header **)&csrt);
+       if (ACPI_FAILURE(status)) {
+               if (status != AE_NOT_FOUND)
+                       dev_warn(&adev->dev, "failed to get the CSRT table\n");
+               return;
+       }
+
+       grp = (struct acpi_csrt_group *)(csrt + 1);
+       end = (struct acpi_csrt_group *)((void *)csrt + csrt->header.length);
+
+       while (grp < end) {
+               ret = acpi_dma_parse_resource_group(grp, adev, adma);
+               if (ret < 0) {
+                       dev_warn(&adev->dev,
+                                "error in parsing resource group\n");
+                       return;
+               }
+
+               grp = (struct acpi_csrt_group *)((void *)grp + grp->length);
+       }
+}
+
 /**
  * acpi_dma_controller_register - Register a DMA controller to ACPI DMA helpers
  * @dev:               struct device of DMA controller
@@ -61,6 +174,8 @@ int acpi_dma_controller_register(struct device *dev,
        adma->acpi_dma_xlate = acpi_dma_xlate;
        adma->data = data;
 
+       acpi_dma_parse_csrt(adev, adma);
+
        /* Now queue acpi_dma controller structure in list */
        mutex_lock(&acpi_dma_lock);
        list_add_tail(&adma->dma_controllers, &acpi_dma_list);
@@ -149,6 +264,45 @@ void devm_acpi_dma_controller_free(struct device *dev)
 }
 EXPORT_SYMBOL_GPL(devm_acpi_dma_controller_free);
 
+/**
+ * acpi_dma_update_dma_spec - prepare dma specifier to pass to translation function
+ * @adma:      struct acpi_dma of DMA controller
+ * @dma_spec:  dma specifier to update
+ *
+ * Returns 0, if no information is avaiable, -1 on mismatch, and 1 otherwise.
+ *
+ * Accordingly to ACPI 5.0 Specification Table 6-170 "Fixed DMA Resource
+ * Descriptor":
+ *     DMA Request Line bits is a platform-relative number uniquely
+ *     identifying the request line assigned. Request line-to-Controller
+ *     mapping is done in a controller-specific OS driver.
+ * That's why we can safely adjust slave_id when the appropriate controller is
+ * found.
+ */
+static int acpi_dma_update_dma_spec(struct acpi_dma *adma,
+               struct acpi_dma_spec *dma_spec)
+{
+       /* Set link to the DMA controller device */
+       dma_spec->dev = adma->dev;
+
+       /* Check if the request line range is available */
+       if (adma->base_request_line == 0 && adma->end_request_line == 0)
+               return 0;
+
+       /* Check if slave_id falls to the range */
+       if (dma_spec->slave_id < adma->base_request_line ||
+           dma_spec->slave_id > adma->end_request_line)
+               return -1;
+
+       /*
+        * Here we adjust slave_id. It should be a relative number to the base
+        * request line.
+        */
+       dma_spec->slave_id -= adma->base_request_line;
+
+       return 1;
+}
+
 struct acpi_dma_parser_data {
        struct acpi_dma_spec dma_spec;
        size_t index;
@@ -193,6 +347,7 @@ struct dma_chan *acpi_dma_request_slave_chan_by_index(struct device *dev,
        struct acpi_device *adev;
        struct acpi_dma *adma;
        struct dma_chan *chan = NULL;
+       int found;
 
        /* Check if the device was enumerated by ACPI */
        if (!dev || !ACPI_HANDLE(dev))
@@ -219,9 +374,20 @@ struct dma_chan *acpi_dma_request_slave_chan_by_index(struct device *dev,
        mutex_lock(&acpi_dma_lock);
 
        list_for_each_entry(adma, &acpi_dma_list, dma_controllers) {
-               dma_spec->dev = adma->dev;
+               /*
+                * We are not going to call translation function if slave_id
+                * doesn't fall to the request range.
+                */
+               found = acpi_dma_update_dma_spec(adma, dma_spec);
+               if (found < 0)
+                       continue;
                chan = adma->acpi_dma_xlate(dma_spec, adma);
-               if (chan)
+               /*
+                * Try to get a channel only from the DMA controller that
+                * matches the slave_id. See acpi_dma_update_dma_spec()
+                * description for the details.
+                */
+               if (found > 0 || chan)
                        break;
        }
 
index 8c171fa1cb9bc65f5531e178bd45cb9a0ef0c9ad..845f04786c2de4baedf0952d2ec2b5a830e62602 100644 (file)
@@ -202,9 +202,9 @@ static DEVICE_ATTR(inject_word, S_IRUGO | S_IWUSR,
                   amd64_inject_word_show, amd64_inject_word_store);
 static DEVICE_ATTR(inject_ecc_vector, S_IRUGO | S_IWUSR,
                   amd64_inject_ecc_vector_show, amd64_inject_ecc_vector_store);
-static DEVICE_ATTR(inject_write, S_IRUGO | S_IWUSR,
+static DEVICE_ATTR(inject_write, S_IWUSR,
                   NULL, amd64_inject_write_store);
-static DEVICE_ATTR(inject_read, S_IRUGO | S_IWUSR,
+static DEVICE_ATTR(inject_read,  S_IWUSR,
                   NULL, amd64_inject_read_store);
 
 
index 87d567089f13653297ddc001ec0fda8746254465..573c449c49b9138a69f8aaf9a999e8a41898d2e1 100644 (file)
@@ -636,7 +636,7 @@ config GPIO_MAX7301
 
 config GPIO_MCP23S08
        tristate "Microchip MCP23xxx I/O expander"
-       depends on SPI_MASTER || I2C
+       depends on (SPI_MASTER && !I2C) || I2C
        help
          SPI/I2C driver for Microchip MCP23S08/MCP23S17/MCP23008/MCP23017
          I/O expanders.
index 634c3d37f7b5e010fe315e0734c4205ab4abce58..62ef10a641c4250b273263c78e51bd2534ed632a 100644 (file)
@@ -324,6 +324,7 @@ static int lnw_gpio_probe(struct pci_dev *pdev,
        resource_size_t start, len;
        struct lnw_gpio *lnw;
        u32 gpio_base;
+       u32 irq_base;
        int retval;
        int ngpio = id->driver_data;
 
@@ -345,6 +346,7 @@ static int lnw_gpio_probe(struct pci_dev *pdev,
                retval = -EFAULT;
                goto err_ioremap;
        }
+       irq_base = *(u32 *)base;
        gpio_base = *((u32 *)base + 1);
        /* release the IO mapping, since we already get the info from bar1 */
        iounmap(base);
@@ -365,13 +367,6 @@ static int lnw_gpio_probe(struct pci_dev *pdev,
                goto err_ioremap;
        }
 
-       lnw->domain = irq_domain_add_linear(pdev->dev.of_node, ngpio,
-                                           &lnw_gpio_irq_ops, lnw);
-       if (!lnw->domain) {
-               retval = -ENOMEM;
-               goto err_ioremap;
-       }
-
        lnw->reg_base = base;
        lnw->chip.label = dev_name(&pdev->dev);
        lnw->chip.request = lnw_gpio_request;
@@ -384,6 +379,14 @@ static int lnw_gpio_probe(struct pci_dev *pdev,
        lnw->chip.ngpio = ngpio;
        lnw->chip.can_sleep = 0;
        lnw->pdev = pdev;
+
+       lnw->domain = irq_domain_add_simple(pdev->dev.of_node, ngpio, irq_base,
+                                           &lnw_gpio_irq_ops, lnw);
+       if (!lnw->domain) {
+               retval = -ENOMEM;
+               goto err_ioremap;
+       }
+
        pci_set_drvdata(pdev, lnw);
        retval = gpiochip_add(&lnw->chip);
        if (retval) {
index b73366523faebf4db81c3fbb020365f8afd75123..0966f2637ad2dc849f12d7224dbf7d6af1c75c13 100644 (file)
@@ -496,8 +496,7 @@ err_irq_alloc_descs:
 err_gpiochip_add:
        while (--i >= 0) {
                chip--;
-               ret = gpiochip_remove(&chip->gpio);
-               if (ret)
+               if (gpiochip_remove(&chip->gpio))
                        dev_err(&pdev->dev, "Failed gpiochip_remove(%d)\n", i);
        }
        kfree(chip_save);
index 25000b0f84532645ad7eab5d85278dfdd9b2557b..f8e6af20dfbf1d0efc5fce0060b6ace3792cb1ad 100644 (file)
@@ -326,7 +326,8 @@ static int mxs_gpio_probe(struct platform_device *pdev)
 
        err = bgpio_init(&port->bgc, &pdev->dev, 4,
                         port->base + PINCTRL_DIN(port),
-                        port->base + PINCTRL_DOUT(port), NULL,
+                        port->base + PINCTRL_DOUT(port) + MXS_SET,
+                        port->base + PINCTRL_DOUT(port) + MXS_CLR,
                         port->base + PINCTRL_DOE(port), NULL, 0);
        if (err)
                goto out_irqdesc_free;
index 2050891d9c65a4936533fb14a4b2d8b95b379cb5..d3f7d2db870f985253a603f3f53f2b5475ee97f6 100644 (file)
@@ -69,6 +69,7 @@ struct gpio_bank {
        bool is_mpuio;
        bool dbck_flag;
        bool loses_context;
+       bool context_valid;
        int stride;
        u32 width;
        int context_loss_count;
@@ -1128,6 +1129,10 @@ static int omap_gpio_probe(struct platform_device *pdev)
                        bank->loses_context = true;
        } else {
                bank->loses_context = pdata->loses_context;
+
+               if (bank->loses_context)
+                       bank->get_context_loss_count =
+                               pdata->get_context_loss_count;
        }
 
 
@@ -1178,9 +1183,6 @@ static int omap_gpio_probe(struct platform_device *pdev)
        omap_gpio_chip_init(bank);
        omap_gpio_show_rev(bank);
 
-       if (bank->loses_context)
-               bank->get_context_loss_count = pdata->get_context_loss_count;
-
        pm_runtime_put(bank->dev);
 
        list_add_tail(&bank->node, &omap_gpio_list);
@@ -1259,6 +1261,8 @@ update_gpio_context_count:
        return 0;
 }
 
+static void omap_gpio_init_context(struct gpio_bank *p);
+
 static int omap_gpio_runtime_resume(struct device *dev)
 {
        struct platform_device *pdev = to_platform_device(dev);
@@ -1268,6 +1272,20 @@ static int omap_gpio_runtime_resume(struct device *dev)
        int c;
 
        spin_lock_irqsave(&bank->lock, flags);
+
+       /*
+        * On the first resume during the probe, the context has not
+        * been initialised and so initialise it now. Also initialise
+        * the context loss count.
+        */
+       if (bank->loses_context && !bank->context_valid) {
+               omap_gpio_init_context(bank);
+
+               if (bank->get_context_loss_count)
+                       bank->context_loss_count =
+                               bank->get_context_loss_count(bank->dev);
+       }
+
        _gpio_dbck_enable(bank);
 
        /*
@@ -1384,6 +1402,29 @@ void omap2_gpio_resume_after_idle(void)
 }
 
 #if defined(CONFIG_PM_RUNTIME)
+static void omap_gpio_init_context(struct gpio_bank *p)
+{
+       struct omap_gpio_reg_offs *regs = p->regs;
+       void __iomem *base = p->base;
+
+       p->context.ctrl         = __raw_readl(base + regs->ctrl);
+       p->context.oe           = __raw_readl(base + regs->direction);
+       p->context.wake_en      = __raw_readl(base + regs->wkup_en);
+       p->context.leveldetect0 = __raw_readl(base + regs->leveldetect0);
+       p->context.leveldetect1 = __raw_readl(base + regs->leveldetect1);
+       p->context.risingdetect = __raw_readl(base + regs->risingdetect);
+       p->context.fallingdetect = __raw_readl(base + regs->fallingdetect);
+       p->context.irqenable1   = __raw_readl(base + regs->irqenable);
+       p->context.irqenable2   = __raw_readl(base + regs->irqenable2);
+
+       if (regs->set_dataout && p->regs->clr_dataout)
+               p->context.dataout = __raw_readl(base + regs->set_dataout);
+       else
+               p->context.dataout = __raw_readl(base + regs->dataout);
+
+       p->context_valid = true;
+}
+
 static void omap_gpio_restore_context(struct gpio_bank *bank)
 {
        __raw_writel(bank->context.wake_en,
@@ -1421,6 +1462,7 @@ static void omap_gpio_restore_context(struct gpio_bank *bank)
 #else
 #define omap_gpio_runtime_suspend NULL
 #define omap_gpio_runtime_resume NULL
+static void omap_gpio_init_context(struct gpio_bank *p) {}
 #endif
 
 static const struct dev_pm_ops gpio_pm_ops = {
index cdf599687cf7b1e4704fa213cf77961bb8f66cfd..0fec097e838df23c264b62405b2cf10bd0531bae 100644 (file)
@@ -424,8 +424,7 @@ end:
 err_request_irq:
        irq_free_descs(irq_base, gpio_pins[chip->ioh]);
 
-       ret = gpiochip_remove(&chip->gpio);
-       if (ret)
+       if (gpiochip_remove(&chip->gpio))
                dev_err(&pdev->dev, "%s gpiochip_remove failed\n", __func__);
 
 err_gpiochip_add:
index 1e4de16ceb419e148c9c233aef0746143530efca..5af65719b95dafad605fb8f1f733ead623b78bf5 100644 (file)
@@ -272,10 +272,8 @@ static int sch_gpio_probe(struct platform_device *pdev)
        return 0;
 
 err_sch_gpio_resume:
-       err = gpiochip_remove(&sch_gpio_core);
-       if (err)
-               dev_err(&pdev->dev, "%s failed, %d\n",
-                               "gpiochip_remove()", err);
+       if (gpiochip_remove(&sch_gpio_core))
+               dev_err(&pdev->dev, "%s gpiochip_remove failed\n", __func__);
 
 err_sch_gpio_core:
        release_region(res->start, resource_size(res));
index 095ab14cea4d16d672e009fb40d6929a2e5d16e0..5ac2919197fe70775f8d17fda5a6dafaab9af677 100644 (file)
@@ -446,7 +446,8 @@ static int vprbrd_gpio_probe(struct platform_device *pdev)
        return ret;
 
 err_gpiob:
-       ret = gpiochip_remove(&vb_gpio->gpioa);
+       if (gpiochip_remove(&vb_gpio->gpioa))
+               dev_err(&pdev->dev, "%s gpiochip_remove failed\n", __func__);
 
 err_gpioa:
        return ret;
index bad8128b283a8752a11e1c3a13d02c83bb1df07b..21ef68934a20bba366c1ea1c5be9705f0fafe6fa 100644 (file)
@@ -329,7 +329,7 @@ static u32 get_vp_index(uuid_le *type_guid)
                return 0;
        }
        cur_cpu = (++next_vp % max_cpus);
-       return cur_cpu;
+       return hv_context.vp_index[cur_cpu];
 }
 
 /*
index 9f3a8ef1fb3e4484bcbc027337ce75a3f6e13425..b3d03d335948a5a5757bd4d49650b1685cbfb78b 100644 (file)
@@ -390,8 +390,8 @@ static int exynos_adc_remove(struct platform_device *pdev)
 #ifdef CONFIG_PM_SLEEP
 static int exynos_adc_suspend(struct device *dev)
 {
-       struct platform_device *pdev = to_platform_device(dev);
-       struct exynos_adc *info = platform_get_drvdata(pdev);
+       struct iio_dev *indio_dev = dev_get_drvdata(dev);
+       struct exynos_adc *info = iio_priv(indio_dev);
        u32 con;
 
        if (info->version == ADC_V2) {
@@ -413,8 +413,8 @@ static int exynos_adc_suspend(struct device *dev)
 
 static int exynos_adc_resume(struct device *dev)
 {
-       struct platform_device *pdev = to_platform_device(dev);
-       struct exynos_adc *info = platform_get_drvdata(pdev);
+       struct iio_dev *indio_dev = dev_get_drvdata(dev);
+       struct exynos_adc *info = iio_priv(indio_dev);
        int ret;
 
        ret = regulator_enable(info->vdd);
index bd33473f8e38afd4deeeb243f12c2bf981587740..ed9bc8ae933030158c9d23b41acfc2bd2de7d61e 100644 (file)
@@ -312,6 +312,8 @@ int st_sensors_read_info_raw(struct iio_dev *indio_dev,
                        goto read_error;
 
                *val = *val >> ch->scan_type.shift;
+
+               err = st_sensors_set_enable(indio_dev, false);
        }
        mutex_unlock(&indio_dev->mlock);
 
index f4a6f0838327daaffe032bc4b3403d4c59bc83a7..b61160bd935eafffd7e04207a0e0fb043f87450f 100644 (file)
@@ -5,7 +5,7 @@ menu "Digital to analog converters"
 
 config AD5064
        tristate "Analog Devices AD5064 and similar multi-channel DAC driver"
-       depends on (SPI_MASTER || I2C)
+       depends on (SPI_MASTER && I2C!=m) || I2C
        help
          Say yes here to build support for Analog Devices AD5024, AD5025, AD5044,
          AD5045, AD5064, AD5064-1, AD5065, AD5628, AD5629R, AD5648, AD5666, AD5668,
@@ -27,7 +27,7 @@ config AD5360
 
 config AD5380
        tristate "Analog Devices AD5380/81/82/83/84/90/91/92 DAC driver"
-       depends on (SPI_MASTER || I2C)
+       depends on (SPI_MASTER && I2C!=m) || I2C
        select REGMAP_I2C if I2C
        select REGMAP_SPI if SPI_MASTER
        help
@@ -57,7 +57,7 @@ config AD5624R_SPI
 
 config AD5446
        tristate "Analog Devices AD5446 and similar single channel DACs driver"
-       depends on (SPI_MASTER || I2C)
+       depends on (SPI_MASTER && I2C!=m) || I2C
        help
          Say yes here to build support for Analog Devices AD5300, AD5301, AD5310,
          AD5311, AD5320, AD5321, AD5444, AD5446, AD5450, AD5451, AD5452, AD5453,
index 0bfd8cf252002d4095dc699cf8277931b1ec00a0..5c68e4486845b6ae1ef0855ddb4b0df220c6c008 100644 (file)
@@ -342,10 +342,10 @@ static int wacom_intuos_inout(struct wacom_wac *wacom)
                wacom->id[idx] = (data[2] << 4) | (data[3] >> 4) |
                        ((data[7] & 0x0f) << 20) | ((data[8] & 0xf0) << 12);
 
-               switch (wacom->id[idx] & 0xfffff) {
+               switch (wacom->id[idx]) {
                case 0x812: /* Inking pen */
                case 0x801: /* Intuos3 Inking pen */
-               case 0x20802: /* Intuos4 Inking Pen */
+               case 0x120802: /* Intuos4/5 Inking Pen */
                case 0x012:
                        wacom->tool[idx] = BTN_TOOL_PENCIL;
                        break;
@@ -356,11 +356,13 @@ static int wacom_intuos_inout(struct wacom_wac *wacom)
                case 0x823: /* Intuos3 Grip Pen */
                case 0x813: /* Intuos3 Classic Pen */
                case 0x885: /* Intuos3 Marker Pen */
-               case 0x802: /* Intuos4 General Pen */
-               case 0x804: /* Intuos4 Marker Pen */
-               case 0x40802: /* Intuos4 Classic Pen */
-               case 0x18802: /* DTH2242 Grip Pen */
+               case 0x802: /* Intuos4/5 13HD/24HD General Pen */
+               case 0x804: /* Intuos4/5 13HD/24HD Marker Pen */
                case 0x022:
+               case 0x100804: /* Intuos4/5 13HD/24HD Art Pen */
+               case 0x140802: /* Intuos4/5 13HD/24HD Classic Pen */
+               case 0x160802: /* Cintiq 13HD Pro Pen */
+               case 0x180802: /* DTH2242 Pen */
                        wacom->tool[idx] = BTN_TOOL_PEN;
                        break;
 
@@ -391,10 +393,14 @@ static int wacom_intuos_inout(struct wacom_wac *wacom)
                case 0x82b: /* Intuos3 Grip Pen Eraser */
                case 0x81b: /* Intuos3 Classic Pen Eraser */
                case 0x91b: /* Intuos3 Airbrush Eraser */
-               case 0x80c: /* Intuos4 Marker Pen Eraser */
-               case 0x80a: /* Intuos4 General Pen Eraser */
-               case 0x4080a: /* Intuos4 Classic Pen Eraser */
-               case 0x90a: /* Intuos4 Airbrush Eraser */
+               case 0x80c: /* Intuos4/5 13HD/24HD Marker Pen Eraser */
+               case 0x80a: /* Intuos4/5 13HD/24HD General Pen Eraser */
+               case 0x90a: /* Intuos4/5 13HD/24HD Airbrush Eraser */
+               case 0x14080a: /* Intuos4/5 13HD/24HD Classic Pen Eraser */
+               case 0x10090a: /* Intuos4/5 13HD/24HD Airbrush Eraser */
+               case 0x10080c: /* Intuos4/5 13HD/24HD Art Pen Eraser */
+               case 0x16080a: /* Cintiq 13HD Pro Pen Eraser */
+               case 0x18080a: /* DTH2242 Eraser */
                        wacom->tool[idx] = BTN_TOOL_RUBBER;
                        break;
 
@@ -402,7 +408,8 @@ static int wacom_intuos_inout(struct wacom_wac *wacom)
                case 0x912:
                case 0x112:
                case 0x913: /* Intuos3 Airbrush */
-               case 0x902: /* Intuos4 Airbrush */
+               case 0x902: /* Intuos4/5 13HD/24HD Airbrush */
+               case 0x100902: /* Intuos4/5 13HD/24HD Airbrush */
                        wacom->tool[idx] = BTN_TOOL_AIRBRUSH;
                        break;
 
@@ -533,10 +540,8 @@ static int wacom_intuos_irq(struct wacom_wac *wacom)
                                input_report_key(input, BTN_8, (data[3] & 0x80));
                        }
                        if (data[1] | (data[2] & 0x01) | data[3]) {
-                               input_report_key(input, wacom->tool[1], 1);
                                input_report_abs(input, ABS_MISC, PAD_DEVICE_ID);
                        } else {
-                               input_report_key(input, wacom->tool[1], 0);
                                input_report_abs(input, ABS_MISC, 0);
                        }
                } else if (features->type == DTK) {
@@ -546,6 +551,26 @@ static int wacom_intuos_irq(struct wacom_wac *wacom)
                        input_report_key(input, BTN_3, (data[6] & 0x08));
                        input_report_key(input, BTN_4, (data[6] & 0x10));
                        input_report_key(input, BTN_5, (data[6] & 0x20));
+                       if (data[6] & 0x3f) {
+                               input_report_abs(input, ABS_MISC, PAD_DEVICE_ID);
+                       } else {
+                               input_report_abs(input, ABS_MISC, 0);
+                       }
+               } else if (features->type == WACOM_13HD) {
+                       input_report_key(input, BTN_0, (data[3] & 0x01));
+                       input_report_key(input, BTN_1, (data[4] & 0x01));
+                       input_report_key(input, BTN_2, (data[4] & 0x02));
+                       input_report_key(input, BTN_3, (data[4] & 0x04));
+                       input_report_key(input, BTN_4, (data[4] & 0x08));
+                       input_report_key(input, BTN_5, (data[4] & 0x10));
+                       input_report_key(input, BTN_6, (data[4] & 0x20));
+                       input_report_key(input, BTN_7, (data[4] & 0x40));
+                       input_report_key(input, BTN_8, (data[4] & 0x80));
+                       if ((data[3] & 0x01) | data[4]) {
+                               input_report_abs(input, ABS_MISC, PAD_DEVICE_ID);
+                       } else {
+                               input_report_abs(input, ABS_MISC, 0);
+                       }
                } else if (features->type == WACOM_24HD) {
                        input_report_key(input, BTN_0, (data[6] & 0x01));
                        input_report_key(input, BTN_1, (data[6] & 0x02));
@@ -590,10 +615,8 @@ static int wacom_intuos_irq(struct wacom_wac *wacom)
                        }
 
                        if (data[1] | data[2] | (data[3] & 0x1f) | data[4] | data[6] | data[8]) {
-                               input_report_key(input, wacom->tool[1], 1);
                                input_report_abs(input, ABS_MISC, PAD_DEVICE_ID);
                        } else {
-                               input_report_key(input, wacom->tool[1], 0);
                                input_report_abs(input, ABS_MISC, 0);
                        }
                } else if (features->type >= INTUOS5S && features->type <= INTUOS5L) {
@@ -618,10 +641,8 @@ static int wacom_intuos_irq(struct wacom_wac *wacom)
                        }
 
                        if (data[2] | (data[3] & 0x01) | data[4] | data[5]) {
-                               input_report_key(input, wacom->tool[1], 1);
                                input_report_abs(input, ABS_MISC, PAD_DEVICE_ID);
                        } else {
-                               input_report_key(input, wacom->tool[1], 0);
                                input_report_abs(input, ABS_MISC, 0);
                        }
                } else {
@@ -668,10 +689,8 @@ static int wacom_intuos_irq(struct wacom_wac *wacom)
                        if ((data[5] & 0x1f) | data[6] | (data[1] & 0x1f) |
                                data[2] | (data[3] & 0x1f) | data[4] | data[8] |
                                (data[7] & 0x01)) {
-                               input_report_key(input, wacom->tool[1], 1);
                                input_report_abs(input, ABS_MISC, PAD_DEVICE_ID);
                        } else {
-                               input_report_key(input, wacom->tool[1], 0);
                                input_report_abs(input, ABS_MISC, 0);
                        }
                }
@@ -1301,6 +1320,7 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len)
        case INTUOS4L:
        case CINTIQ:
        case WACOM_BEE:
+       case WACOM_13HD:
        case WACOM_21UX2:
        case WACOM_22HD:
        case WACOM_24HD:
@@ -1530,15 +1550,15 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev,
                __set_bit(KEY_PROG1, input_dev->keybit);
                __set_bit(KEY_PROG2, input_dev->keybit);
                __set_bit(KEY_PROG3, input_dev->keybit);
+
+               input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0);
+               input_set_abs_params(input_dev, ABS_THROTTLE, 0, 71, 0, 0);
                /* fall through */
 
        case DTK:
                for (i = 0; i < 6; i++)
                        __set_bit(BTN_0 + i, input_dev->keybit);
 
-               input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0);
-               input_set_abs_params(input_dev, ABS_THROTTLE, 0, 71, 0, 0);
-
                __set_bit(INPUT_PROP_DIRECT, input_dev->propbit);
 
                wacom_setup_cintiq(wacom_wac);
@@ -1579,6 +1599,15 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev,
                wacom_setup_cintiq(wacom_wac);
                break;
 
+       case WACOM_13HD:
+               for (i = 0; i < 9; i++)
+                       __set_bit(BTN_0 + i, input_dev->keybit);
+
+               input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0);
+               __set_bit(INPUT_PROP_DIRECT, input_dev->propbit);
+               wacom_setup_cintiq(wacom_wac);
+               break;
+
        case INTUOS3:
        case INTUOS3L:
                __set_bit(BTN_4, input_dev->keybit);
@@ -1950,6 +1979,9 @@ static const struct wacom_features wacom_features_0xC5 =
 static const struct wacom_features wacom_features_0xC6 =
        { "Wacom Cintiq 12WX",    WACOM_PKGLEN_INTUOS,    53020, 33440, 1023,
          63, WACOM_BEE, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
+static const struct wacom_features wacom_features_0x304 =
+       { "Wacom Cintiq 13HD",    WACOM_PKGLEN_INTUOS,    59552, 33848, 1023,
+         63, WACOM_13HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
 static const struct wacom_features wacom_features_0xC7 =
        { "Wacom DTU1931",        WACOM_PKGLEN_GRAPHIRE,  37832, 30305,  511,
          0, PL, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
@@ -1959,6 +1991,9 @@ static const struct wacom_features wacom_features_0xCE =
 static const struct wacom_features wacom_features_0xF0 =
        { "Wacom DTU1631",        WACOM_PKGLEN_GRAPHIRE,  34623, 19553,  511,
          0, DTU, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
+static const struct wacom_features wacom_features_0x57 =
+       { "Wacom DTK2241",        WACOM_PKGLEN_INTUOS,    95840, 54260, 2047,
+         63, DTK, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES};
 static const struct wacom_features wacom_features_0x59 = /* Pen */
        { "Wacom DTH2242",        WACOM_PKGLEN_INTUOS,    95840, 54260, 2047,
          63, DTK, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES,
@@ -1972,6 +2007,12 @@ static const struct wacom_features wacom_features_0xCC =
 static const struct wacom_features wacom_features_0xFA =
        { "Wacom Cintiq 22HD",    WACOM_PKGLEN_INTUOS,    95840, 54260, 2047,
          63, WACOM_22HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
+static const struct wacom_features wacom_features_0x5B =
+       { "Wacom Cintiq 22HDT", WACOM_PKGLEN_INTUOS,      95840, 54260, 2047,
+         63, WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x5e };
+static const struct wacom_features wacom_features_0x5E =
+       { "Wacom Cintiq 22HDT", .type = WACOM_24HDT,
+         .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x5b, .touch_max = 10 };
 static const struct wacom_features wacom_features_0x90 =
        { "Wacom ISDv4 90",       WACOM_PKGLEN_GRAPHIRE,  26202, 16325,  255,
          0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
@@ -2143,8 +2184,11 @@ const struct usb_device_id wacom_ids[] = {
        { USB_DEVICE_WACOM(0x43) },
        { USB_DEVICE_WACOM(0x44) },
        { USB_DEVICE_WACOM(0x45) },
+       { USB_DEVICE_WACOM(0x57) },
        { USB_DEVICE_WACOM(0x59) },
        { USB_DEVICE_DETAILED(0x5D, USB_CLASS_HID, 0, 0) },
+       { USB_DEVICE_WACOM(0x5B) },
+       { USB_DEVICE_DETAILED(0x5E, USB_CLASS_HID, 0, 0) },
        { USB_DEVICE_WACOM(0xB0) },
        { USB_DEVICE_WACOM(0xB1) },
        { USB_DEVICE_WACOM(0xB2) },
@@ -2205,6 +2249,7 @@ const struct usb_device_id wacom_ids[] = {
        { USB_DEVICE_WACOM(0x100) },
        { USB_DEVICE_WACOM(0x101) },
        { USB_DEVICE_WACOM(0x10D) },
+       { USB_DEVICE_WACOM(0x304) },
        { USB_DEVICE_WACOM(0x4001) },
        { USB_DEVICE_WACOM(0x47) },
        { USB_DEVICE_WACOM(0xF4) },
index 5f9a7721e16cf36a1a92021a03ddb45648292b88..dfc9e08e7f70458c0a41378ae7034a027e52d0ea 100644 (file)
@@ -82,6 +82,7 @@ enum {
        WACOM_24HD,
        CINTIQ,
        WACOM_BEE,
+       WACOM_13HD,
        WACOM_MO,
        WIRELESS,
        BAMBOO_PT,
index 17c9097f3b5ddddd40fad74345b1d2376c4ada7a..39f3df8670c311ec2373ec4ddad585ce4217743b 100644 (file)
@@ -216,7 +216,7 @@ static int egalax_ts_probe(struct i2c_client *client,
        input_set_abs_params(input_dev,
                             ABS_MT_POSITION_X, 0, EGALAX_MAX_X, 0, 0);
        input_set_abs_params(input_dev,
-                            ABS_MT_POSITION_X, 0, EGALAX_MAX_Y, 0, 0);
+                            ABS_MT_POSITION_Y, 0, EGALAX_MAX_Y, 0, 0);
        input_mt_init_slots(input_dev, MAX_SUPPORT_POINTS, 0);
 
        input_set_drvdata(input_dev, ts);
index 9b1b274c7d256d96667c42150e19f7cf547d3f1f..c123709acf823829a274db2ca6ced2060bbae341 100644 (file)
@@ -93,7 +93,7 @@ capi_ctr_put(struct capi_ctr *ctr)
 
 static inline struct capi_ctr *get_capi_ctr_by_nr(u16 contr)
 {
-       if (contr - 1 >= CAPI_MAXCONTR)
+       if (contr < 1 || contr - 1 >= CAPI_MAXCONTR)
                return NULL;
 
        return capi_controller[contr - 1];
@@ -103,7 +103,7 @@ static inline struct capi20_appl *__get_capi_appl_by_nr(u16 applid)
 {
        lockdep_assert_held(&capi_controller_lock);
 
-       if (applid - 1 >= CAPI_MAXAPPL)
+       if (applid < 1 || applid - 1 >= CAPI_MAXAPPL)
                return NULL;
 
        return capi_applications[applid - 1];
@@ -111,7 +111,7 @@ static inline struct capi20_appl *__get_capi_appl_by_nr(u16 applid)
 
 static inline struct capi20_appl *get_capi_appl_by_nr(u16 applid)
 {
-       if (applid - 1 >= CAPI_MAXAPPL)
+       if (applid < 1 || applid - 1 >= CAPI_MAXAPPL)
                return NULL;
 
        return rcu_dereference(capi_applications[applid - 1]);
index ee14662ed5cef46b845aeeb3557e55dcd6580efb..98cae529373f44aa202a1a5c0f9d2f2259ab0e98 100644 (file)
@@ -47,37 +47,37 @@ static struct ot200_led leds[] = {
        {
                .name = "led_1",
                .port = 0x49,
-               .mask = BIT(7),
+               .mask = BIT(6),
        },
        {
                .name = "led_2",
                .port = 0x49,
-               .mask = BIT(6),
+               .mask = BIT(5),
        },
        {
                .name = "led_3",
                .port = 0x49,
-               .mask = BIT(5),
+               .mask = BIT(4),
        },
        {
                .name = "led_4",
                .port = 0x49,
-               .mask = BIT(4),
+               .mask = BIT(3),
        },
        {
                .name = "led_5",
                .port = 0x49,
-               .mask = BIT(3),
+               .mask = BIT(2),
        },
        {
                .name = "led_6",
                .port = 0x49,
-               .mask = BIT(2),
+               .mask = BIT(1),
        },
        {
                .name = "led_7",
                .port = 0x49,
-               .mask = BIT(1),
+               .mask = BIT(0),
        }
 };
 
index d9aed1593e5d34855b488a89750da5ed68f1a0fe..d54e985748b78403956a0b7ba0d2b8634b949244 100644 (file)
@@ -579,7 +579,7 @@ config AB8500_CORE
 
 config AB8500_DEBUG
        bool "Enable debug info via debugfs"
-       depends on AB8500_CORE && DEBUG_FS
+       depends on AB8500_GPADC && DEBUG_FS
        default y if DEBUG_FS
        help
          Select this option if you want debug information using the debug
@@ -818,6 +818,7 @@ config MFD_TPS65910
 config MFD_TPS65912
        bool "TI TPS65912 Power Management chip"
        depends on GPIOLIB
+       select MFD_CORE
        help
          If you say yes here you get support for the TPS65912 series of
          PM chips.
index 8e8a016effe95251cca5692fed6c7b4442139630..258b367e39891468eb4dd0a9dabf05558a75446d 100644 (file)
@@ -867,6 +867,15 @@ static struct resource ab8500_chargalg_resources[] = {};
 
 #ifdef CONFIG_DEBUG_FS
 static struct resource ab8500_debug_resources[] = {
+       {
+               .name   = "IRQ_AB8500",
+               /*
+                * Number will be filled in. NOTE: this is deliberately
+                * not flagged as an IRQ in ordet to avoid remapping using
+                * the irqdomain in the MFD core, so that this IRQ passes
+                * unremapped to the debug code.
+                */
+       },
        {
                .name   = "IRQ_FIRST",
                .start  = AB8500_INT_MAIN_EXT_CH_NOT_OK,
@@ -1051,6 +1060,7 @@ static struct mfd_cell ab8500_devs[] = {
        },
        {
                .name = "ab8500-gpadc",
+               .of_compatible = "stericsson,ab8500-gpadc",
                .num_resources = ARRAY_SIZE(ab8500_gpadc_resources),
                .resources = ab8500_gpadc_resources,
        },
@@ -1097,7 +1107,7 @@ static struct mfd_cell ab8500_devs[] = {
                .of_compatible = "stericsson,ab8500-denc",
        },
        {
-               .name = "ab8500-gpio",
+               .name = "pinctrl-ab8500",
                .of_compatible = "stericsson,ab8500-gpio",
        },
        {
@@ -1208,6 +1218,7 @@ static struct mfd_cell ab8505_devs[] = {
        },
        {
                .name = "ab8500-gpadc",
+               .of_compatible = "stericsson,ab8500-gpadc",
                .num_resources = ARRAY_SIZE(ab8505_gpadc_resources),
                .resources = ab8505_gpadc_resources,
        },
@@ -1234,7 +1245,7 @@ static struct mfd_cell ab8505_devs[] = {
                .name = "ab8500-leds",
        },
        {
-               .name = "ab8500-gpio",
+               .name = "pinctrl-ab8505",
        },
        {
                .name = "ab8500-usb",
@@ -1271,6 +1282,7 @@ static struct mfd_cell ab8540_devs[] = {
        },
        {
                .name = "ab8500-gpadc",
+               .of_compatible = "stericsson,ab8500-gpadc",
                .num_resources = ARRAY_SIZE(ab8505_gpadc_resources),
                .resources = ab8505_gpadc_resources,
        },
@@ -1302,7 +1314,7 @@ static struct mfd_cell ab8540_devs[] = {
                .resources = ab8500_temp_resources,
        },
        {
-               .name = "ab8500-gpio",
+               .name = "pinctrl-ab8540",
        },
        {
                .name = "ab8540-usb",
@@ -1712,6 +1724,12 @@ static int ab8500_probe(struct platform_device *pdev)
        if (ret)
                return ret;
 
+#if CONFIG_DEBUG_FS
+       /* Pass to debugfs */
+       ab8500_debug_resources[0].start = ab8500->irq;
+       ab8500_debug_resources[0].end = ab8500->irq;
+#endif
+
        if (is_ab9540(ab8500))
                ret = mfd_add_devices(ab8500->dev, 0, ab9540_devs,
                                ARRAY_SIZE(ab9540_devs), NULL,
index b88bbbc15f1e962f8f131d0f50bc25768091f55c..37b7ce4c7c3be57b4c8ea30474ec1edee47f8ad5 100644 (file)
 #include <linux/ctype.h>
 #endif
 
-/* TODO: this file should not reference IRQ_DB8500_AB8500! */
-#include <mach/irqs.h>
-
 static u32 debug_bank;
 static u32 debug_address;
 
+static int irq_ab8500;
 static int irq_first;
 static int irq_last;
 static u32 *irq_count;
@@ -1589,7 +1587,7 @@ void ab8500_debug_register_interrupt(int line)
 {
        if (line < num_interrupt_lines) {
                num_interrupts[line]++;
-               if (suspend_test_wake_cause_interrupt_is_mine(IRQ_DB8500_AB8500))
+               if (suspend_test_wake_cause_interrupt_is_mine(irq_ab8500))
                        num_wake_interrupts[line]++;
        }
 }
@@ -2941,6 +2939,7 @@ static int ab8500_debug_probe(struct platform_device *plf)
        struct dentry *file;
        int ret = -ENOMEM;
        struct ab8500 *ab8500;
+       struct resource *res;
        debug_bank = AB8500_MISC;
        debug_address = AB8500_REV_REG & 0x00FF;
 
@@ -2959,6 +2958,15 @@ static int ab8500_debug_probe(struct platform_device *plf)
        if (!event_name)
                goto out_freedev_attr;
 
+       res = platform_get_resource_byname(plf, 0, "IRQ_AB8500");
+       if (!res) {
+               dev_err(&plf->dev, "AB8500 irq not found, err %d\n",
+                       irq_first);
+               ret = -ENXIO;
+               goto out_freeevent_name;
+       }
+       irq_ab8500 = res->start;
+
        irq_first = platform_get_irq_byname(plf, "IRQ_FIRST");
        if (irq_first < 0) {
                dev_err(&plf->dev, "First irq not found, err %d\n",
index 5e65b28a5d0901e1dc5058c084dc444cd2c4a1bd..13f7866de46eb21a4cdf0363f0386d315f8171dd 100644 (file)
@@ -907,14 +907,17 @@ static int ab8500_gpadc_suspend(struct device *dev)
 static int ab8500_gpadc_resume(struct device *dev)
 {
        struct ab8500_gpadc *gpadc = dev_get_drvdata(dev);
+       int ret;
 
-       regulator_enable(gpadc->regu);
+       ret = regulator_enable(gpadc->regu);
+       if (ret)
+               dev_err(dev, "Failed to enable vtvout LDO: %d\n", ret);
 
        pm_runtime_mark_last_busy(gpadc->dev);
        pm_runtime_put_autosuspend(gpadc->dev);
 
        mutex_unlock(&gpadc->ab8500_gpadc_lock);
-       return 0;
+       return ret;
 }
 
 static int ab8500_gpadc_probe(struct platform_device *pdev)
index fbca1ced49faac60bfffdef6ff6e19474475ff7b..8e0dae59844d494cd4e2c79904779b8f0a3c0acf 100644 (file)
@@ -23,7 +23,7 @@
 
 static struct device *sysctrl_dev;
 
-void ab8500_power_off(void)
+static void ab8500_power_off(void)
 {
        sigset_t old;
        sigset_t all;
@@ -104,7 +104,7 @@ void ab8500_restart(char mode, const char *cmd)
 
        plat = dev_get_platdata(sysctrl_dev->parent);
        pdata = plat->sysctrl;
-       if (pdata->reboot_reason_code)
+       if (pdata && pdata->reboot_reason_code)
                reason = pdata->reboot_reason_code(cmd);
        else
                pr_warn("[%s] No reboot reason set. Default reason %d\n",
@@ -188,14 +188,15 @@ static int ab8500_sysctrl_probe(struct platform_device *pdev)
 
        plat = dev_get_platdata(pdev->dev.parent);
 
-       if (!(plat && plat->sysctrl))
+       if (!plat)
                return -EINVAL;
 
-       if (plat->pm_power_off)
+       sysctrl_dev = &pdev->dev;
+
+       if (!pm_power_off)
                pm_power_off = ab8500_power_off;
 
        pdata = plat->sysctrl;
-
        if (pdata) {
                int last, ret, i, j;
 
@@ -226,6 +227,10 @@ static int ab8500_sysctrl_probe(struct platform_device *pdev)
 static int ab8500_sysctrl_remove(struct platform_device *pdev)
 {
        sysctrl_dev = NULL;
+
+       if (pm_power_off == ab8500_power_off)
+               pm_power_off = NULL;
+
        return 0;
 }
 
index 9818afba25153b377cf2b64b54b18bccc02f3e2c..3714acb6145864611cd29fd314c7bfd9d0af5bfb 100644 (file)
@@ -156,7 +156,7 @@ EXPORT_SYMBOL(abx500_startup_irq_enabled);
 void abx500_dump_all_banks(void)
 {
        struct abx500_ops *ops;
-       struct device dummy_child = {0};
+       struct device dummy_child = {NULL};
        struct abx500_device_entry *dev_entry;
 
        list_for_each_entry(dev_entry, &abx500_list, list) {
index 19193cf1e7a1bf9075a4eb63e157b6a419eba14f..367ccb58ecb15a1954cf39e936c46bc5a4bf3498 100644 (file)
@@ -120,7 +120,7 @@ static int cros_ec_spi_receive_response(struct cros_ec_device *ec_dev,
 
                for (end = ptr + EC_MSG_PREAMBLE_COUNT; ptr != end; ptr++) {
                        if (*ptr == EC_MSG_HEADER) {
-                               dev_dbg(ec_dev->dev, "msg found at %ld\n",
+                               dev_dbg(ec_dev->dev, "msg found at %zd\n",
                                        ptr - ec_dev->din);
                                break;
                        }
@@ -154,7 +154,7 @@ static int cros_ec_spi_receive_response(struct cros_ec_device *ec_dev,
                 * maximum-supported transfer size.
                 */
                todo = min(need_len, 256);
-               dev_dbg(ec_dev->dev, "loop, todo=%d, need_len=%d, ptr=%ld\n",
+               dev_dbg(ec_dev->dev, "loop, todo=%d, need_len=%d, ptr=%zd\n",
                        todo, need_len, ptr - ec_dev->din);
 
                memset(&trans, '\0', sizeof(trans));
@@ -178,7 +178,7 @@ static int cros_ec_spi_receive_response(struct cros_ec_device *ec_dev,
                need_len -= todo;
        }
 
-       dev_dbg(ec_dev->dev, "loop done, ptr=%ld\n", ptr - ec_dev->din);
+       dev_dbg(ec_dev->dev, "loop done, ptr=%zd\n", ptr - ec_dev->din);
 
        return 0;
 }
index 319b8abe742b4ef0d4bf5b74e300514e5c031c91..66f80973596bd8833557d13c1bfc5426a6b1290d 100644 (file)
@@ -1613,6 +1613,8 @@ static unsigned long dsiclk_rate(u8 n)
 
        if (divsel == PRCM_DSI_PLLOUT_SEL_OFF)
                divsel = dsiclk[n].divsel;
+       else
+               dsiclk[n].divsel = divsel;
 
        switch (divsel) {
        case PRCM_DSI_PLLOUT_SEL_PHI_4:
@@ -3095,6 +3097,7 @@ static struct mfd_cell db8500_prcmu_devs[] = {
                .num_resources = ARRAY_SIZE(db8500_thsens_resources),
                .resources = db8500_thsens_resources,
                .platform_data = &db8500_thsens_data,
+               .pdata_size = sizeof(db8500_thsens_data),
        },
 };
 
index de48b4e884501b7cce5540f87f9144c0a8b60742..6f1ef63086c9df98c56c00369c7b91b60c5320c5 100644 (file)
@@ -29,6 +29,8 @@
 
 #include <linux/mfd/si476x-core.h>
 
+#include <asm/unaligned.h>
+
 #define msb(x)                  ((u8)((u16) x >> 8))
 #define lsb(x)                  ((u8)((u16) x &  0x00FF))
 
@@ -150,7 +152,7 @@ enum si476x_acf_status_report_bits {
        SI476X_ACF_SOFTMUTE_INT = (1 << 0),
 
        SI476X_ACF_SMUTE        = (1 << 0),
-       SI476X_ACF_SMATTN       = 0b11111,
+       SI476X_ACF_SMATTN       = 0x1f,
        SI476X_ACF_PILOT        = (1 << 7),
        SI476X_ACF_STBLEND      = ~SI476X_ACF_PILOT,
 };
@@ -483,7 +485,7 @@ int si476x_core_cmd_get_property(struct si476x_core *core, u16 property)
        if (err < 0)
                return err;
        else
-               return be16_to_cpup((__be16 *)(resp + 2));
+               return get_unaligned_be16(resp + 2);
 }
 EXPORT_SYMBOL_GPL(si476x_core_cmd_get_property);
 
@@ -772,18 +774,18 @@ int si476x_core_cmd_am_rsq_status(struct si476x_core *core,
        if (!report)
                return err;
 
-       report->snrhint         = 0b00001000 & resp[1];
-       report->snrlint         = 0b00000100 & resp[1];
-       report->rssihint        = 0b00000010 & resp[1];
-       report->rssilint        = 0b00000001 & resp[1];
+       report->snrhint         = 0x08 & resp[1];
+       report->snrlint         = 0x04 & resp[1];
+       report->rssihint        = 0x02 & resp[1];
+       report->rssilint        = 0x01 & resp[1];
 
-       report->bltf            = 0b10000000 & resp[2];
-       report->snr_ready       = 0b00100000 & resp[2];
-       report->rssiready       = 0b00001000 & resp[2];
-       report->afcrl           = 0b00000010 & resp[2];
-       report->valid           = 0b00000001 & resp[2];
+       report->bltf            = 0x80 & resp[2];
+       report->snr_ready       = 0x20 & resp[2];
+       report->rssiready       = 0x08 & resp[2];
+       report->afcrl           = 0x02 & resp[2];
+       report->valid           = 0x01 & resp[2];
 
-       report->readfreq        = be16_to_cpup((__be16 *)(resp + 3));
+       report->readfreq        = get_unaligned_be16(resp + 3);
        report->freqoff         = resp[5];
        report->rssi            = resp[6];
        report->snr             = resp[7];
@@ -931,26 +933,26 @@ int si476x_core_cmd_fm_rds_status(struct si476x_core *core,
        if (err < 0 || report == NULL)
                return err;
 
-       report->rdstpptyint     = 0b00010000 & resp[1];
-       report->rdspiint        = 0b00001000 & resp[1];
-       report->rdssyncint      = 0b00000010 & resp[1];
-       report->rdsfifoint      = 0b00000001 & resp[1];
+       report->rdstpptyint     = 0x10 & resp[1];
+       report->rdspiint        = 0x08 & resp[1];
+       report->rdssyncint      = 0x02 & resp[1];
+       report->rdsfifoint      = 0x01 & resp[1];
 
-       report->tpptyvalid      = 0b00010000 & resp[2];
-       report->pivalid         = 0b00001000 & resp[2];
-       report->rdssync         = 0b00000010 & resp[2];
-       report->rdsfifolost     = 0b00000001 & resp[2];
+       report->tpptyvalid      = 0x10 & resp[2];
+       report->pivalid         = 0x08 & resp[2];
+       report->rdssync         = 0x02 & resp[2];
+       report->rdsfifolost     = 0x01 & resp[2];
 
-       report->tp              = 0b00100000 & resp[3];
-       report->pty             = 0b00011111 & resp[3];
+       report->tp              = 0x20 & resp[3];
+       report->pty             = 0x1f & resp[3];
 
-       report->pi              = be16_to_cpup((__be16 *)(resp + 4));
+       report->pi              = get_unaligned_be16(resp + 4);
        report->rdsfifoused     = resp[6];
 
-       report->ble[V4L2_RDS_BLOCK_A]   = 0b11000000 & resp[7];
-       report->ble[V4L2_RDS_BLOCK_B]   = 0b00110000 & resp[7];
-       report->ble[V4L2_RDS_BLOCK_C]   = 0b00001100 & resp[7];
-       report->ble[V4L2_RDS_BLOCK_D]   = 0b00000011 & resp[7];
+       report->ble[V4L2_RDS_BLOCK_A]   = 0xc0 & resp[7];
+       report->ble[V4L2_RDS_BLOCK_B]   = 0x30 & resp[7];
+       report->ble[V4L2_RDS_BLOCK_C]   = 0x0c & resp[7];
+       report->ble[V4L2_RDS_BLOCK_D]   = 0x03 & resp[7];
 
        report->rds[V4L2_RDS_BLOCK_A].block = V4L2_RDS_BLOCK_A;
        report->rds[V4L2_RDS_BLOCK_A].msb = resp[8];
@@ -991,9 +993,9 @@ int si476x_core_cmd_fm_rds_blockcount(struct si476x_core *core,
                                       SI476X_DEFAULT_TIMEOUT);
 
        if (!err) {
-               report->expected        = be16_to_cpup((__be16 *)(resp + 2));
-               report->received        = be16_to_cpup((__be16 *)(resp + 4));
-               report->uncorrectable   = be16_to_cpup((__be16 *)(resp + 6));
+               report->expected        = get_unaligned_be16(resp + 2);
+               report->received        = get_unaligned_be16(resp + 4);
+               report->uncorrectable   = get_unaligned_be16(resp + 6);
        }
 
        return err;
@@ -1005,7 +1007,7 @@ int si476x_core_cmd_fm_phase_diversity(struct si476x_core *core,
 {
        u8       resp[CMD_FM_PHASE_DIVERSITY_NRESP];
        const u8 args[CMD_FM_PHASE_DIVERSITY_NARGS] = {
-               mode & 0b111,
+               mode & 0x07,
        };
 
        return si476x_core_send_command(core, CMD_FM_PHASE_DIVERSITY,
@@ -1162,7 +1164,7 @@ static int si476x_core_cmd_am_tune_freq_a20(struct si476x_core *core,
        const int am_freq = tuneargs->freq;
        u8       resp[CMD_AM_TUNE_FREQ_NRESP];
        const u8 args[CMD_AM_TUNE_FREQ_NARGS] = {
-               (tuneargs->zifsr << 6) | (tuneargs->injside & 0b11),
+               (tuneargs->zifsr << 6) | (tuneargs->injside & 0x03),
                msb(am_freq),
                lsb(am_freq),
        };
@@ -1197,20 +1199,20 @@ static int si476x_core_cmd_fm_rsq_status_a10(struct si476x_core *core,
        if (err < 0 || report == NULL)
                return err;
 
-       report->multhint        = 0b10000000 & resp[1];
-       report->multlint        = 0b01000000 & resp[1];
-       report->snrhint         = 0b00001000 & resp[1];
-       report->snrlint         = 0b00000100 & resp[1];
-       report->rssihint        = 0b00000010 & resp[1];
-       report->rssilint        = 0b00000001 & resp[1];
+       report->multhint        = 0x80 & resp[1];
+       report->multlint        = 0x40 & resp[1];
+       report->snrhint         = 0x08 & resp[1];
+       report->snrlint         = 0x04 & resp[1];
+       report->rssihint        = 0x02 & resp[1];
+       report->rssilint        = 0x01 & resp[1];
 
-       report->bltf            = 0b10000000 & resp[2];
-       report->snr_ready       = 0b00100000 & resp[2];
-       report->rssiready       = 0b00001000 & resp[2];
-       report->afcrl           = 0b00000010 & resp[2];
-       report->valid           = 0b00000001 & resp[2];
+       report->bltf            = 0x80 & resp[2];
+       report->snr_ready       = 0x20 & resp[2];
+       report->rssiready       = 0x08 & resp[2];
+       report->afcrl           = 0x02 & resp[2];
+       report->valid           = 0x01 & resp[2];
 
-       report->readfreq        = be16_to_cpup((__be16 *)(resp + 3));
+       report->readfreq        = get_unaligned_be16(resp + 3);
        report->freqoff         = resp[5];
        report->rssi            = resp[6];
        report->snr             = resp[7];
@@ -1218,7 +1220,7 @@ static int si476x_core_cmd_fm_rsq_status_a10(struct si476x_core *core,
        report->hassi           = resp[10];
        report->mult            = resp[11];
        report->dev             = resp[12];
-       report->readantcap      = be16_to_cpup((__be16 *)(resp + 13));
+       report->readantcap      = get_unaligned_be16(resp + 13);
        report->assi            = resp[15];
        report->usn             = resp[16];
 
@@ -1251,20 +1253,20 @@ static int si476x_core_cmd_fm_rsq_status_a20(struct si476x_core *core,
        if (err < 0 || report == NULL)
                return err;
 
-       report->multhint        = 0b10000000 & resp[1];
-       report->multlint        = 0b01000000 & resp[1];
-       report->snrhint         = 0b00001000 & resp[1];
-       report->snrlint         = 0b00000100 & resp[1];
-       report->rssihint        = 0b00000010 & resp[1];
-       report->rssilint        = 0b00000001 & resp[1];
+       report->multhint        = 0x80 & resp[1];
+       report->multlint        = 0x40 & resp[1];
+       report->snrhint         = 0x08 & resp[1];
+       report->snrlint         = 0x04 & resp[1];
+       report->rssihint        = 0x02 & resp[1];
+       report->rssilint        = 0x01 & resp[1];
 
-       report->bltf            = 0b10000000 & resp[2];
-       report->snr_ready       = 0b00100000 & resp[2];
-       report->rssiready       = 0b00001000 & resp[2];
-       report->afcrl           = 0b00000010 & resp[2];
-       report->valid           = 0b00000001 & resp[2];
+       report->bltf            = 0x80 & resp[2];
+       report->snr_ready       = 0x20 & resp[2];
+       report->rssiready       = 0x08 & resp[2];
+       report->afcrl           = 0x02 & resp[2];
+       report->valid           = 0x01 & resp[2];
 
-       report->readfreq        = be16_to_cpup((__be16 *)(resp + 3));
+       report->readfreq        = get_unaligned_be16(resp + 3);
        report->freqoff         = resp[5];
        report->rssi            = resp[6];
        report->snr             = resp[7];
@@ -1272,7 +1274,7 @@ static int si476x_core_cmd_fm_rsq_status_a20(struct si476x_core *core,
        report->hassi           = resp[10];
        report->mult            = resp[11];
        report->dev             = resp[12];
-       report->readantcap      = be16_to_cpup((__be16 *)(resp + 13));
+       report->readantcap      = get_unaligned_be16(resp + 13);
        report->assi            = resp[15];
        report->usn             = resp[16];
 
@@ -1306,21 +1308,21 @@ static int si476x_core_cmd_fm_rsq_status_a30(struct si476x_core *core,
        if (err < 0 || report == NULL)
                return err;
 
-       report->multhint        = 0b10000000 & resp[1];
-       report->multlint        = 0b01000000 & resp[1];
-       report->snrhint         = 0b00001000 & resp[1];
-       report->snrlint         = 0b00000100 & resp[1];
-       report->rssihint        = 0b00000010 & resp[1];
-       report->rssilint        = 0b00000001 & resp[1];
-
-       report->bltf            = 0b10000000 & resp[2];
-       report->snr_ready       = 0b00100000 & resp[2];
-       report->rssiready       = 0b00001000 & resp[2];
-       report->injside         = 0b00000100 & resp[2];
-       report->afcrl           = 0b00000010 & resp[2];
-       report->valid           = 0b00000001 & resp[2];
-
-       report->readfreq        = be16_to_cpup((__be16 *)(resp + 3));
+       report->multhint        = 0x80 & resp[1];
+       report->multlint        = 0x40 & resp[1];
+       report->snrhint         = 0x08 & resp[1];
+       report->snrlint         = 0x04 & resp[1];
+       report->rssihint        = 0x02 & resp[1];
+       report->rssilint        = 0x01 & resp[1];
+
+       report->bltf            = 0x80 & resp[2];
+       report->snr_ready       = 0x20 & resp[2];
+       report->rssiready       = 0x08 & resp[2];
+       report->injside         = 0x04 & resp[2];
+       report->afcrl           = 0x02 & resp[2];
+       report->valid           = 0x01 & resp[2];
+
+       report->readfreq        = get_unaligned_be16(resp + 3);
        report->freqoff         = resp[5];
        report->rssi            = resp[6];
        report->snr             = resp[7];
@@ -1329,7 +1331,7 @@ static int si476x_core_cmd_fm_rsq_status_a30(struct si476x_core *core,
        report->hassi           = resp[10];
        report->mult            = resp[11];
        report->dev             = resp[12];
-       report->readantcap      = be16_to_cpup((__be16 *)(resp + 13));
+       report->readantcap      = get_unaligned_be16(resp + 13);
        report->assi            = resp[15];
        report->usn             = resp[16];
 
@@ -1337,7 +1339,7 @@ static int si476x_core_cmd_fm_rsq_status_a30(struct si476x_core *core,
        report->rdsdev          = resp[18];
        report->assidev         = resp[19];
        report->strongdev       = resp[20];
-       report->rdspi           = be16_to_cpup((__be16 *)(resp + 21));
+       report->rdspi           = get_unaligned_be16(resp + 21);
 
        return err;
 }
index 7014167e2c619f23acc05398973552fd8ab23f9e..c37eeedfe215634775a59fa581d83f749a3fb536 100644 (file)
@@ -19,7 +19,7 @@
 #include <linux/irq.h>
 #include <linux/interrupt.h>
 
-static int irq;
+static int irq = -1;
 
 static irqreturn_t dummy_interrupt(int irq, void *dev_id)
 {
@@ -36,6 +36,10 @@ static irqreturn_t dummy_interrupt(int irq, void *dev_id)
 
 static int __init dummy_irq_init(void)
 {
+       if (irq < 0) {
+               printk(KERN_ERR "dummy-irq: no IRQ given.  Use irq=N\n");
+               return -EIO;
+       }
        if (request_irq(irq, &dummy_interrupt, IRQF_SHARED, "dummy_irq", &irq)) {
                printk(KERN_ERR "dummy-irq: cannot register IRQ %d\n", irq);
                return -EIO;
index 1e935eacaa7faee9903e20303dc703c75ed014ff..9ecd49a7be1b33cac4ece186e35e3ebc255d9d78 100644 (file)
@@ -496,6 +496,8 @@ int mei_cl_disable_device(struct mei_cl_device *device)
                }
        }
 
+       device->event_cb = NULL;
+
        mutex_unlock(&dev->device_lock);
 
        if (!device->ops || !device->ops->disable)
index 7c44c8dbae424904c53e041f5723ab51bf974e6f..053139f610861fa98c6778176d86f5a4969660f7 100644 (file)
@@ -489,11 +489,16 @@ static int mei_ioctl_connect_client(struct file *file,
 
        /* find ME client we're trying to connect to */
        i = mei_me_cl_by_uuid(dev, &data->in_client_uuid);
-       if (i >= 0 && !dev->me_clients[i].props.fixed_address) {
-               cl->me_client_id = dev->me_clients[i].client_id;
-               cl->state = MEI_FILE_CONNECTING;
+       if (i < 0 || dev->me_clients[i].props.fixed_address) {
+               dev_dbg(&dev->pdev->dev, "Cannot connect to FW Client UUID = %pUl\n",
+                               &data->in_client_uuid);
+               rets = -ENODEV;
+               goto end;
        }
 
+       cl->me_client_id = dev->me_clients[i].client_id;
+       cl->state = MEI_FILE_CONNECTING;
+
        dev_dbg(&dev->pdev->dev, "Connect to FW Client ID = %d\n",
                        cl->me_client_id);
        dev_dbg(&dev->pdev->dev, "FW Client - Protocol Version = %d\n",
@@ -527,11 +532,6 @@ static int mei_ioctl_connect_client(struct file *file,
                goto end;
        }
 
-       if (cl->state != MEI_FILE_CONNECTING) {
-               rets = -ENODEV;
-               goto end;
-       }
-
 
        /* prepare the output buffer */
        client = &data->out_client_properties;
@@ -543,7 +543,6 @@ static int mei_ioctl_connect_client(struct file *file,
        rets = mei_cl_connect(cl, file);
 
 end:
-       dev_dbg(&dev->pdev->dev, "free connect cb memory.");
        return rets;
 }
 
index ea98f7e9ccd19d6ef8ea862616bcc4c0f3055b8d..39c2ecadb273d374b41be572bee6431e7b81e784 100644 (file)
@@ -4,7 +4,7 @@
 
 config VMWARE_VMCI
        tristate "VMware VMCI Driver"
-       depends on X86 && PCI && NET
+       depends on X86 && PCI
        help
          This is VMware's Virtual Machine Communication Interface.  It enables
          high-speed communication between host and guest in a virtual
index d94245dbd7651edc70e9bb23d6d9dcacbfdbd5d7..8ff2e5ee8fb8b955f8da30c8b2a2eba94ed43710 100644 (file)
@@ -23,7 +23,7 @@
 #include <linux/pagemap.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
-#include <linux/socket.h>
+#include <linux/uio.h>
 #include <linux/wait.h>
 #include <linux/vmalloc.h>
 
index fc58d118d844e3eefd684348d9ffeac48b7dfe74..390061d096934f83c04171a1a8a62bf9d8345ec5 100644 (file)
@@ -2360,14 +2360,15 @@ int bond_3ad_set_carrier(struct bonding *bond)
 }
 
 /**
- * bond_3ad_get_active_agg_info - get information of the active aggregator
+ * __bond_3ad_get_active_agg_info - get information of the active aggregator
  * @bond: bonding struct to work on
  * @ad_info: ad_info struct to fill with the bond's info
  *
  * Returns:   0 on success
  *          < 0 on error
  */
-int bond_3ad_get_active_agg_info(struct bonding *bond, struct ad_info *ad_info)
+int __bond_3ad_get_active_agg_info(struct bonding *bond,
+                                  struct ad_info *ad_info)
 {
        struct aggregator *aggregator = NULL;
        struct port *port;
@@ -2391,6 +2392,18 @@ int bond_3ad_get_active_agg_info(struct bonding *bond, struct ad_info *ad_info)
        return -1;
 }
 
+/* Wrapper used to hold bond->lock so no slave manipulation can occur */
+int bond_3ad_get_active_agg_info(struct bonding *bond, struct ad_info *ad_info)
+{
+       int ret;
+
+       read_lock(&bond->lock);
+       ret = __bond_3ad_get_active_agg_info(bond, ad_info);
+       read_unlock(&bond->lock);
+
+       return ret;
+}
+
 int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev)
 {
        struct slave *slave, *start_at;
@@ -2402,8 +2415,8 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev)
        struct ad_info ad_info;
        int res = 1;
 
-       if (bond_3ad_get_active_agg_info(bond, &ad_info)) {
-               pr_debug("%s: Error: bond_3ad_get_active_agg_info failed\n",
+       if (__bond_3ad_get_active_agg_info(bond, &ad_info)) {
+               pr_debug("%s: Error: __bond_3ad_get_active_agg_info failed\n",
                         dev->name);
                goto out;
        }
index 0cfaa4afdecea333bd3d8831aa1e8c9e118e50b7..5d91ad0cc04142df9e73a52a62d06e5ab4d3898e 100644 (file)
@@ -273,6 +273,8 @@ void bond_3ad_adapter_speed_changed(struct slave *slave);
 void bond_3ad_adapter_duplex_changed(struct slave *slave);
 void bond_3ad_handle_link_change(struct slave *slave, char link);
 int  bond_3ad_get_active_agg_info(struct bonding *bond, struct ad_info *ad_info);
+int  __bond_3ad_get_active_agg_info(struct bonding *bond,
+                                   struct ad_info *ad_info);
 int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev);
 int bond_3ad_lacpdu_recv(const struct sk_buff *skb, struct bonding *bond,
                         struct slave *slave);
index d0aade04e49aff739294de120d44defaba46fbf2..29b846cbfb48d3380fa8dae7e87782e641e2519b 100644 (file)
@@ -1362,6 +1362,7 @@ static netdev_features_t bond_fix_features(struct net_device *dev,
                                                     slave->dev->features,
                                                     mask);
        }
+       features = netdev_add_tso_features(features, mask);
 
 out:
        read_unlock(&bond->lock);
@@ -2555,8 +2556,8 @@ static void bond_arp_send(struct net_device *slave_dev, int arp_op, __be32 dest_
 {
        struct sk_buff *skb;
 
-       pr_debug("arp %d on slave %s: dst %x src %x vid %d\n", arp_op,
-                slave_dev->name, dest_ip, src_ip, vlan_id);
+       pr_debug("arp %d on slave %s: dst %pI4 src %pI4 vid %d\n", arp_op,
+                slave_dev->name, &dest_ip, &src_ip, vlan_id);
 
        skb = arp_create(arp_op, ETH_P_ARP, dest_ip, slave_dev, src_ip,
                         NULL, slave_dev->dev_addr, NULL);
@@ -2588,7 +2589,7 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave)
                __be32 addr;
                if (!targets[i])
                        break;
-               pr_debug("basa: target %x\n", targets[i]);
+               pr_debug("basa: target %pI4\n", &targets[i]);
                if (!bond_vlan_used(bond)) {
                        pr_debug("basa: empty vlan: arp_send\n");
                        addr = bond_confirm_addr(bond->dev, targets[i], 0);
@@ -4470,7 +4471,7 @@ int bond_parse_parm(const char *buf, const struct bond_parm_tbl *tbl)
 
 static int bond_check_params(struct bond_params *params)
 {
-       int arp_validate_value, fail_over_mac_value, primary_reselect_value;
+       int arp_validate_value, fail_over_mac_value, primary_reselect_value, i;
 
        /*
         * Convert string parameters.
@@ -4650,19 +4651,18 @@ static int bond_check_params(struct bond_params *params)
                arp_interval = BOND_LINK_ARP_INTERV;
        }
 
-       for (arp_ip_count = 0;
-            (arp_ip_count < BOND_MAX_ARP_TARGETS) && arp_ip_target[arp_ip_count];
-            arp_ip_count++) {
+       for (arp_ip_count = 0, i = 0;
+            (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[arp_ip_count]);
-               if (!isdigit(arp_ip_target[arp_ip_count][0]) ||
-                   ip == 0 || ip == htonl(INADDR_BROADCAST)) {
+               __be32 ip = in_aton(arp_ip_target[i]);
+               if (!isdigit(arp_ip_target[i][0]) || ip == 0 ||
+                   ip == htonl(INADDR_BROADCAST)) {
                        pr_warning("Warning: bad arp_ip_target module parameter (%s), ARP monitoring will not be performed\n",
-                                  arp_ip_target[arp_ip_count]);
+                                  arp_ip_target[i]);
                        arp_interval = 0;
                } else {
-                       arp_target[arp_ip_count] = ip;
+                       arp_target[arp_ip_count++] = ip;
                }
        }
 
@@ -4696,8 +4696,6 @@ static int bond_check_params(struct bond_params *params)
        if (miimon) {
                pr_info("MII link monitoring set to %d ms\n", miimon);
        } else if (arp_interval) {
-               int i;
-
                pr_info("ARP monitoring set to %d ms, validate %s, with %d target(s):",
                        arp_interval,
                        arp_validate_tbl[arp_validate_value].modename,
index 94d06f1307b850f927c85b4b7645f49859b4772b..4060d41f0ee7b15bc228b6bda9488a9e6cc9c821 100644 (file)
@@ -130,7 +130,7 @@ static void bond_info_show_master(struct seq_file *seq)
                seq_printf(seq, "Aggregator selection policy (ad_select): %s\n",
                           ad_select_tbl[bond->params.ad_select].modename);
 
-               if (bond_3ad_get_active_agg_info(bond, &ad_info)) {
+               if (__bond_3ad_get_active_agg_info(bond, &ad_info)) {
                        seq_printf(seq, "bond %s has no active aggregator\n",
                                   bond->dev->name);
                } else {
index ea7a388f484306710a33375f3a553fd1ecc5b621..d7434e0a610e925e6a8b6de206856b37b4fd0375 100644 (file)
@@ -316,6 +316,9 @@ static ssize_t bonding_store_mode(struct device *d,
        int new_value, ret = count;
        struct bonding *bond = to_bond(d);
 
+       if (!rtnl_trylock())
+               return restart_syscall();
+
        if (bond->dev->flags & IFF_UP) {
                pr_err("unable to update mode of %s because interface is up.\n",
                       bond->dev->name);
@@ -352,6 +355,7 @@ static ssize_t bonding_store_mode(struct device *d,
                bond->dev->name, bond_mode_tbl[new_value].modename,
                new_value);
 out:
+       rtnl_unlock();
        return ret;
 }
 static DEVICE_ATTR(mode, S_IRUGO | S_IWUSR,
@@ -1315,7 +1319,6 @@ static ssize_t bonding_show_mii_status(struct device *d,
 }
 static DEVICE_ATTR(mii_status, S_IRUGO, bonding_show_mii_status, NULL);
 
-
 /*
  * Show current 802.3ad aggregator ID.
  */
@@ -1329,7 +1332,7 @@ static ssize_t bonding_show_ad_aggregator(struct device *d,
        if (bond->params.mode == BOND_MODE_8023AD) {
                struct ad_info ad_info;
                count = sprintf(buf, "%d\n",
-                               (bond_3ad_get_active_agg_info(bond, &ad_info))
+                               bond_3ad_get_active_agg_info(bond, &ad_info)
                                ?  0 : ad_info.aggregator_id);
        }
 
@@ -1351,7 +1354,7 @@ static ssize_t bonding_show_ad_num_ports(struct device *d,
        if (bond->params.mode == BOND_MODE_8023AD) {
                struct ad_info ad_info;
                count = sprintf(buf, "%d\n",
-                               (bond_3ad_get_active_agg_info(bond, &ad_info))
+                               bond_3ad_get_active_agg_info(bond, &ad_info)
                                ?  0 : ad_info.ports);
        }
 
@@ -1373,7 +1376,7 @@ static ssize_t bonding_show_ad_actor_key(struct device *d,
        if (bond->params.mode == BOND_MODE_8023AD) {
                struct ad_info ad_info;
                count = sprintf(buf, "%d\n",
-                               (bond_3ad_get_active_agg_info(bond, &ad_info))
+                               bond_3ad_get_active_agg_info(bond, &ad_info)
                                ?  0 : ad_info.actor_key);
        }
 
@@ -1395,7 +1398,7 @@ static ssize_t bonding_show_ad_partner_key(struct device *d,
        if (bond->params.mode == BOND_MODE_8023AD) {
                struct ad_info ad_info;
                count = sprintf(buf, "%d\n",
-                               (bond_3ad_get_active_agg_info(bond, &ad_info))
+                               bond_3ad_get_active_agg_info(bond, &ad_info)
                                ?  0 : ad_info.partner_key);
        }
 
index b8fbe266ab68f1619a18b7e49e9d6df19a5f0625..be59ec4b2c30a642878e86bb5953520202c142e7 100644 (file)
@@ -3313,6 +3313,7 @@ static void bnx2x_set_pbd_gso_e2(struct sk_buff *skb, u32 *parsing_data,
  */
 static void bnx2x_set_pbd_gso(struct sk_buff *skb,
                              struct eth_tx_parse_bd_e1x *pbd,
+                             struct eth_tx_start_bd *tx_start_bd,
                              u32 xmit_type)
 {
        pbd->lso_mss = cpu_to_le16(skb_shinfo(skb)->gso_size);
@@ -3326,11 +3327,14 @@ static void bnx2x_set_pbd_gso(struct sk_buff *skb,
                                                   ip_hdr(skb)->daddr,
                                                   0, IPPROTO_TCP, 0));
 
-       } else
+               /* GSO on 57710/57711 needs FW to calculate IP checksum */
+               tx_start_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_IP_CSUM;
+       } else {
                pbd->tcp_pseudo_csum =
                        bswab16(~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
                                                 &ipv6_hdr(skb)->daddr,
                                                 0, IPPROTO_TCP, 0));
+       }
 
        pbd->global_data |=
                cpu_to_le16(ETH_TX_PARSE_BD_E1X_PSEUDO_CS_WITHOUT_LEN);
@@ -3814,7 +3818,8 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
                        bnx2x_set_pbd_gso_e2(skb, &pbd_e2_parsing_data,
                                             xmit_type);
                else
-                       bnx2x_set_pbd_gso(skb, pbd_e1x, xmit_type);
+                       bnx2x_set_pbd_gso(skb, pbd_e1x, tx_start_bd,
+                                         xmit_type);
        }
 
        /* Set the PBD's parsing_data field if not zero
index 728d42ab2a7636e4656a28174ac2b8c9159c60f0..1f2dd928888ae9339a8f53122d76fe6ebe3ad6fa 100644 (file)
@@ -94,10 +94,10 @@ static inline void _tg3_flag_clear(enum TG3_FLAGS flag, unsigned long *bits)
 
 #define DRV_MODULE_NAME                "tg3"
 #define TG3_MAJ_NUM                    3
-#define TG3_MIN_NUM                    131
+#define TG3_MIN_NUM                    132
 #define DRV_MODULE_VERSION     \
        __stringify(TG3_MAJ_NUM) "." __stringify(TG3_MIN_NUM)
-#define DRV_MODULE_RELDATE     "April 09, 2013"
+#define DRV_MODULE_RELDATE     "May 21, 2013"
 
 #define RESET_KIND_SHUTDOWN    0
 #define RESET_KIND_INIT                1
@@ -2957,6 +2957,31 @@ static int tg3_5700_link_polarity(struct tg3 *tp, u32 speed)
        return 0;
 }
 
+static bool tg3_phy_power_bug(struct tg3 *tp)
+{
+       switch (tg3_asic_rev(tp)) {
+       case ASIC_REV_5700:
+       case ASIC_REV_5704:
+               return true;
+       case ASIC_REV_5780:
+               if (tp->phy_flags & TG3_PHYFLG_MII_SERDES)
+                       return true;
+               return false;
+       case ASIC_REV_5717:
+               if (!tp->pci_fn)
+                       return true;
+               return false;
+       case ASIC_REV_5719:
+       case ASIC_REV_5720:
+               if ((tp->phy_flags & TG3_PHYFLG_PHY_SERDES) &&
+                   !tp->pci_fn)
+                       return true;
+               return false;
+       }
+
+       return false;
+}
+
 static void tg3_power_down_phy(struct tg3 *tp, bool do_low_power)
 {
        u32 val;
@@ -3016,12 +3041,7 @@ static void tg3_power_down_phy(struct tg3 *tp, bool do_low_power)
        /* The PHY should not be powered down on some chips because
         * of bugs.
         */
-       if (tg3_asic_rev(tp) == ASIC_REV_5700 ||
-           tg3_asic_rev(tp) == ASIC_REV_5704 ||
-           (tg3_asic_rev(tp) == ASIC_REV_5780 &&
-            (tp->phy_flags & TG3_PHYFLG_MII_SERDES)) ||
-           (tg3_asic_rev(tp) == ASIC_REV_5717 &&
-            !tp->pci_fn))
+       if (tg3_phy_power_bug(tp))
                return;
 
        if (tg3_chip_rev(tp) == CHIPREV_5784_AX ||
@@ -7428,6 +7448,20 @@ static inline int tg3_4g_overflow_test(dma_addr_t mapping, int len)
        return (base > 0xffffdcc0) && (base + len + 8 < base);
 }
 
+/* Test for TSO DMA buffers that cross into regions which are within MSS bytes
+ * of any 4GB boundaries: 4G, 8G, etc
+ */
+static inline int tg3_4g_tso_overflow_test(struct tg3 *tp, dma_addr_t mapping,
+                                          u32 len, u32 mss)
+{
+       if (tg3_asic_rev(tp) == ASIC_REV_5762 && mss) {
+               u32 base = (u32) mapping & 0xffffffff;
+
+               return ((base + len + (mss & 0x3fff)) < base);
+       }
+       return 0;
+}
+
 /* Test for DMA addresses > 40-bit */
 static inline int tg3_40bit_overflow_test(struct tg3 *tp, dma_addr_t mapping,
                                          int len)
@@ -7464,6 +7498,9 @@ static bool tg3_tx_frag_set(struct tg3_napi *tnapi, u32 *entry, u32 *budget,
        if (tg3_4g_overflow_test(map, len))
                hwbug = true;
 
+       if (tg3_4g_tso_overflow_test(tp, map, len, mss))
+               hwbug = true;
+
        if (tg3_40bit_overflow_test(tp, map, len))
                hwbug = true;
 
@@ -8874,6 +8911,10 @@ static int tg3_chip_reset(struct tg3 *tp)
                tg3_halt_cpu(tp, RX_CPU_BASE);
        }
 
+       err = tg3_poll_fw(tp);
+       if (err)
+               return err;
+
        tw32(GRC_MODE, tp->grc_mode);
 
        if (tg3_chip_rev_id(tp) == CHIPREV_ID_5705_A0) {
@@ -8904,10 +8945,6 @@ static int tg3_chip_reset(struct tg3 *tp)
 
        tg3_ape_unlock(tp, TG3_APE_LOCK_GRC);
 
-       err = tg3_poll_fw(tp);
-       if (err)
-               return err;
-
        tg3_mdio_start(tp);
 
        if (tg3_flag(tp, PCI_EXPRESS) &&
index 6be513deb17f69b73be4b321821e99d3ec7a17cd..c89aa41dd44873f02fbea97c6af3f3cd6132dcbd 100644 (file)
@@ -485,7 +485,8 @@ static void macb_tx_interrupt(struct macb *bp)
        status = macb_readl(bp, TSR);
        macb_writel(bp, TSR, status);
 
-       macb_writel(bp, ISR, MACB_BIT(TCOMP));
+       if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE)
+               macb_writel(bp, ISR, MACB_BIT(TCOMP));
 
        netdev_vdbg(bp->dev, "macb_tx_interrupt status = 0x%03lx\n",
                (unsigned long)status);
@@ -738,7 +739,8 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id)
                         * now.
                         */
                        macb_writel(bp, IDR, MACB_RX_INT_FLAGS);
-                       macb_writel(bp, ISR, MACB_BIT(RCOMP));
+                       if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE)
+                               macb_writel(bp, ISR, MACB_BIT(RCOMP));
 
                        if (napi_schedule_prep(&bp->napi)) {
                                netdev_vdbg(bp->dev, "scheduling RX softirq\n");
@@ -1062,6 +1064,17 @@ static void macb_configure_dma(struct macb *bp)
        }
 }
 
+/*
+ * Configure peripheral capacities according to integration options used
+ */
+static void macb_configure_caps(struct macb *bp)
+{
+       if (macb_is_gem(bp)) {
+               if (GEM_BF(IRQCOR, gem_readl(bp, DCFG1)) == 0)
+                       bp->caps |= MACB_CAPS_ISR_CLEAR_ON_WRITE;
+       }
+}
+
 static void macb_init_hw(struct macb *bp)
 {
        u32 config;
@@ -1084,6 +1097,7 @@ static void macb_init_hw(struct macb *bp)
        bp->duplex = DUPLEX_HALF;
 
        macb_configure_dma(bp);
+       macb_configure_caps(bp);
 
        /* Initialize TX and RX buffers */
        macb_writel(bp, RBQP, bp->rx_ring_dma);
index 993d703806885d9f3ebedd4f5c035bfdd03306d8..548c0ecae8697e5ffb0006819f7670b9fba813f8 100644 (file)
 #define MACB_REV_SIZE                          16
 
 /* Bitfields in DCFG1. */
+#define GEM_IRQCOR_OFFSET                      23
+#define GEM_IRQCOR_SIZE                                1
 #define GEM_DBWDEF_OFFSET                      25
 #define GEM_DBWDEF_SIZE                                3
 
 #define MACB_MAN_READ                          2
 #define MACB_MAN_CODE                          2
 
+/* Capability mask bits */
+#define MACB_CAPS_ISR_CLEAR_ON_WRITE           0x1
+
 /* Bit manipulation macros */
 #define MACB_BIT(name)                                 \
        (1 << MACB_##name##_OFFSET)
@@ -574,6 +579,8 @@ struct macb {
        unsigned int            speed;
        unsigned int            duplex;
 
+       u32                     caps;
+
        phy_interface_t         phy_interface;
 
        /* AT91RM9200 transmit */
index fd7b547698abd89f829008e717e34f2fc9d9e2f9..a236ecd27cf384dea6af9e0a992a075dab306a5d 100644 (file)
@@ -2976,22 +2976,17 @@ static struct be_nic_resource_desc *be_get_nic_desc(u8 *buf, u32 desc_count,
        for (i = 0; i < desc_count; i++) {
                desc->desc_len = desc->desc_len ? : RESOURCE_DESC_SIZE;
                if (((void *)desc + desc->desc_len) >
-                   (void *)(buf + max_buf_size)) {
-                       desc = NULL;
-                       break;
-               }
+                   (void *)(buf + max_buf_size))
+                       return NULL;
 
                if (desc->desc_type == NIC_RESOURCE_DESC_TYPE_V0 ||
                    desc->desc_type == NIC_RESOURCE_DESC_TYPE_V1)
-                       break;
+                       return desc;
 
                desc = (void *)desc + desc->desc_len;
        }
 
-       if (!desc || i == MAX_RESOURCE_DESC)
-               return NULL;
-
-       return desc;
+       return NULL;
 }
 
 /* Uses Mbox */
index a444110b060fd74361759be2f9f3a25a4f0fe095..ca2967b0f18b672bb0af9ca25eaeb586f3baa47e 100644 (file)
@@ -780,26 +780,18 @@ static struct sk_buff *be_insert_vlan_in_pkt(struct be_adapter *adapter,
        if (unlikely(!skb))
                return skb;
 
-       if (vlan_tx_tag_present(skb)) {
+       if (vlan_tx_tag_present(skb))
                vlan_tag = be_get_tx_vlan_tag(adapter, skb);
-               skb = __vlan_put_tag(skb, htons(ETH_P_8021Q), vlan_tag);
-               if (skb)
-                       skb->vlan_tci = 0;
-       }
-
-       if (qnq_async_evt_rcvd(adapter) && adapter->pvid) {
-               if (!vlan_tag)
-                       vlan_tag = adapter->pvid;
-               if (skip_hw_vlan)
-                       *skip_hw_vlan = true;
-       }
+       else if (qnq_async_evt_rcvd(adapter) && adapter->pvid)
+               vlan_tag = adapter->pvid;
 
        if (vlan_tag) {
                skb = __vlan_put_tag(skb, htons(ETH_P_8021Q), vlan_tag);
                if (unlikely(!skb))
                        return skb;
-
                skb->vlan_tci = 0;
+               if (skip_hw_vlan)
+                       *skip_hw_vlan = true;
        }
 
        /* Insert the outer VLAN, if any */
index ca9825ca88c92c91adc24e16fd995bff076e4b67..85a06037b242bc8e5afd5916069062450aa4c1a4 100644 (file)
@@ -109,7 +109,7 @@ static struct platform_device_id fec_devtype[] = {
                .driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_HAS_GBIT |
                                FEC_QUIRK_HAS_BUFDESC_EX | FEC_QUIRK_HAS_CSUM,
        }, {
-               .name = "mvf-fec",
+               .name = "mvf600-fec",
                .driver_data = FEC_QUIRK_ENET_MAC,
        }, {
                /* sentinel */
@@ -122,7 +122,7 @@ enum imx_fec_type {
        IMX27_FEC,      /* runs on i.mx27/35/51 */
        IMX28_FEC,
        IMX6Q_FEC,
-       MVF_FEC,
+       MVF600_FEC,
 };
 
 static const struct of_device_id fec_dt_ids[] = {
@@ -130,7 +130,7 @@ static const struct of_device_id fec_dt_ids[] = {
        { .compatible = "fsl,imx27-fec", .data = &fec_devtype[IMX27_FEC], },
        { .compatible = "fsl,imx28-fec", .data = &fec_devtype[IMX28_FEC], },
        { .compatible = "fsl,imx6q-fec", .data = &fec_devtype[IMX6Q_FEC], },
-       { .compatible = "fsl,mvf-fec", .data = &fec_devtype[MVF_FEC], },
+       { .compatible = "fsl,mvf600-fec", .data = &fec_devtype[MVF600_FEC], },
        { /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, fec_dt_ids);
@@ -451,7 +451,7 @@ fec_restart(struct net_device *ndev, int duplex)
                netif_device_detach(ndev);
                napi_disable(&fep->napi);
                netif_stop_queue(ndev);
-               netif_tx_lock(ndev);
+               netif_tx_lock_bh(ndev);
        }
 
        /* Whack a reset.  We should wait for this. */
@@ -616,10 +616,10 @@ fec_restart(struct net_device *ndev, int duplex)
        writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK);
 
        if (netif_running(ndev)) {
-               netif_device_attach(ndev);
-               napi_enable(&fep->napi);
+               netif_tx_unlock_bh(ndev);
                netif_wake_queue(ndev);
-               netif_tx_unlock(ndev);
+               napi_enable(&fep->napi);
+               netif_device_attach(ndev);
        }
 }
 
index 576e4b858fce09d7bd00f1a7492daf598bbe1741..083ea2b4d20a4106e5ae3c993da3855504493f0f 100644 (file)
@@ -524,6 +524,7 @@ static int gianfar_ptp_probe(struct platform_device *dev)
        return 0;
 
 no_clock:
+       iounmap(etsects->regs);
 no_ioremap:
        release_resource(etsects->rsrc);
 no_resource:
index 6ce027355fcf721932336aee3fce299f4fe7f716..abb300a3191293387d3250ad4c215a49164011ba 100644 (file)
@@ -195,57 +195,57 @@ enum ipg_regs {
 /* TFD data structure masks. */
 
 /* TFDList, TFC */
-#define        IPG_TFC_RSVD_MASK                       0x0000FFFF9FFFFFFF
-#define        IPG_TFC_FRAMEID                         0x000000000000FFFF
-#define        IPG_TFC_WORDALIGN                       0x0000000000030000
-#define        IPG_TFC_WORDALIGNTODWORD                0x0000000000000000
-#define        IPG_TFC_WORDALIGNTOWORD                 0x0000000000020000
-#define        IPG_TFC_WORDALIGNDISABLED               0x0000000000030000
-#define        IPG_TFC_TCPCHECKSUMENABLE               0x0000000000040000
-#define        IPG_TFC_UDPCHECKSUMENABLE               0x0000000000080000
-#define        IPG_TFC_IPCHECKSUMENABLE                0x0000000000100000
-#define        IPG_TFC_FCSAPPENDDISABLE                0x0000000000200000
-#define        IPG_TFC_TXINDICATE                      0x0000000000400000
-#define        IPG_TFC_TXDMAINDICATE                   0x0000000000800000
-#define        IPG_TFC_FRAGCOUNT                       0x000000000F000000
-#define        IPG_TFC_VLANTAGINSERT                   0x0000000010000000
-#define        IPG_TFC_TFDDONE                         0x0000000080000000
-#define        IPG_TFC_VID                             0x00000FFF00000000
-#define        IPG_TFC_CFI                             0x0000100000000000
-#define        IPG_TFC_USERPRIORITY                    0x0000E00000000000
+#define        IPG_TFC_RSVD_MASK                       0x0000FFFF9FFFFFFFULL
+#define        IPG_TFC_FRAMEID                         0x000000000000FFFFULL
+#define        IPG_TFC_WORDALIGN                       0x0000000000030000ULL
+#define        IPG_TFC_WORDALIGNTODWORD                0x0000000000000000ULL
+#define        IPG_TFC_WORDALIGNTOWORD                 0x0000000000020000ULL
+#define        IPG_TFC_WORDALIGNDISABLED               0x0000000000030000ULL
+#define        IPG_TFC_TCPCHECKSUMENABLE               0x0000000000040000ULL
+#define        IPG_TFC_UDPCHECKSUMENABLE               0x0000000000080000ULL
+#define        IPG_TFC_IPCHECKSUMENABLE                0x0000000000100000ULL
+#define        IPG_TFC_FCSAPPENDDISABLE                0x0000000000200000ULL
+#define        IPG_TFC_TXINDICATE                      0x0000000000400000ULL
+#define        IPG_TFC_TXDMAINDICATE                   0x0000000000800000ULL
+#define        IPG_TFC_FRAGCOUNT                       0x000000000F000000ULL
+#define        IPG_TFC_VLANTAGINSERT                   0x0000000010000000ULL
+#define        IPG_TFC_TFDDONE                         0x0000000080000000ULL
+#define        IPG_TFC_VID                             0x00000FFF00000000ULL
+#define        IPG_TFC_CFI                             0x0000100000000000ULL
+#define        IPG_TFC_USERPRIORITY                    0x0000E00000000000ULL
 
 /* TFDList, FragInfo */
-#define        IPG_TFI_RSVD_MASK                       0xFFFF00FFFFFFFFFF
-#define        IPG_TFI_FRAGADDR                        0x000000FFFFFFFFFF
-#define        IPG_TFI_FRAGLEN                         0xFFFF000000000000LL
+#define        IPG_TFI_RSVD_MASK                       0xFFFF00FFFFFFFFFFULL
+#define        IPG_TFI_FRAGADDR                        0x000000FFFFFFFFFFULL
+#define        IPG_TFI_FRAGLEN                         0xFFFF000000000000ULL
 
 /* RFD data structure masks. */
 
 /* RFDList, RFS */
-#define        IPG_RFS_RSVD_MASK                       0x0000FFFFFFFFFFFF
-#define        IPG_RFS_RXFRAMELEN                      0x000000000000FFFF
-#define        IPG_RFS_RXFIFOOVERRUN                   0x0000000000010000
-#define        IPG_RFS_RXRUNTFRAME                     0x0000000000020000
-#define        IPG_RFS_RXALIGNMENTERROR                0x0000000000040000
-#define        IPG_RFS_RXFCSERROR                      0x0000000000080000
-#define        IPG_RFS_RXOVERSIZEDFRAME                0x0000000000100000
-#define        IPG_RFS_RXLENGTHERROR                   0x0000000000200000
-#define        IPG_RFS_VLANDETECTED                    0x0000000000400000
-#define        IPG_RFS_TCPDETECTED                     0x0000000000800000
-#define        IPG_RFS_TCPERROR                        0x0000000001000000
-#define        IPG_RFS_UDPDETECTED                     0x0000000002000000
-#define        IPG_RFS_UDPERROR                        0x0000000004000000
-#define        IPG_RFS_IPDETECTED                      0x0000000008000000
-#define        IPG_RFS_IPERROR                         0x0000000010000000
-#define        IPG_RFS_FRAMESTART                      0x0000000020000000
-#define        IPG_RFS_FRAMEEND                        0x0000000040000000
-#define        IPG_RFS_RFDDONE                         0x0000000080000000
-#define        IPG_RFS_TCI                             0x0000FFFF00000000
+#define        IPG_RFS_RSVD_MASK                       0x0000FFFFFFFFFFFFULL
+#define        IPG_RFS_RXFRAMELEN                      0x000000000000FFFFULL
+#define        IPG_RFS_RXFIFOOVERRUN                   0x0000000000010000ULL
+#define        IPG_RFS_RXRUNTFRAME                     0x0000000000020000ULL
+#define        IPG_RFS_RXALIGNMENTERROR                0x0000000000040000ULL
+#define        IPG_RFS_RXFCSERROR                      0x0000000000080000ULL
+#define        IPG_RFS_RXOVERSIZEDFRAME                0x0000000000100000ULL
+#define        IPG_RFS_RXLENGTHERROR                   0x0000000000200000ULL
+#define        IPG_RFS_VLANDETECTED                    0x0000000000400000ULL
+#define        IPG_RFS_TCPDETECTED                     0x0000000000800000ULL
+#define        IPG_RFS_TCPERROR                        0x0000000001000000ULL
+#define        IPG_RFS_UDPDETECTED                     0x0000000002000000ULL
+#define        IPG_RFS_UDPERROR                        0x0000000004000000ULL
+#define        IPG_RFS_IPDETECTED                      0x0000000008000000ULL
+#define        IPG_RFS_IPERROR                         0x0000000010000000ULL
+#define        IPG_RFS_FRAMESTART                      0x0000000020000000ULL
+#define        IPG_RFS_FRAMEEND                        0x0000000040000000ULL
+#define        IPG_RFS_RFDDONE                         0x0000000080000000ULL
+#define        IPG_RFS_TCI                             0x0000FFFF00000000ULL
 
 /* RFDList, FragInfo */
-#define        IPG_RFI_RSVD_MASK                       0xFFFF00FFFFFFFFFF
-#define        IPG_RFI_FRAGADDR                        0x000000FFFFFFFFFF
-#define        IPG_RFI_FRAGLEN                         0xFFFF000000000000LL
+#define        IPG_RFI_RSVD_MASK                       0xFFFF00FFFFFFFFFFULL
+#define        IPG_RFI_FRAGADDR                        0x000000FFFFFFFFFFULL
+#define        IPG_RFI_FRAGLEN                         0xFFFF000000000000ULL
 
 /* I/O Register masks. */
 
index d0afeea181fb0fd35918941c6e19a0008ded1141..2ad1494efbb3021e796481da6c4f48f21e63ca30 100644 (file)
@@ -867,7 +867,7 @@ static int txq_reclaim(struct tx_queue *txq, int budget, int force)
        struct netdev_queue *nq = netdev_get_tx_queue(mp->dev, txq->index);
        int reclaimed;
 
-       __netif_tx_lock(nq, smp_processor_id());
+       __netif_tx_lock_bh(nq);
 
        reclaimed = 0;
        while (reclaimed < budget && txq->tx_desc_count > 0) {
@@ -913,7 +913,7 @@ static int txq_reclaim(struct tx_queue *txq, int budget, int force)
                dev_kfree_skb(skb);
        }
 
-       __netif_tx_unlock(nq);
+       __netif_tx_unlock_bh(nq);
 
        if (reclaimed < budget)
                mp->work_tx &= ~(1 << txq->index);
@@ -2745,7 +2745,7 @@ static int mv643xx_eth_probe(struct platform_device *pdev)
 
        INIT_WORK(&mp->tx_timeout_task, tx_timeout_task);
 
-       netif_napi_add(dev, &mp->napi, mv643xx_eth_poll, 128);
+       netif_napi_add(dev, &mp->napi, mv643xx_eth_poll, NAPI_POLL_WEIGHT);
 
        init_timer(&mp->rx_oom);
        mp->rx_oom.data = (unsigned long)mp;
index 019c5f78732ead011ca07edecee78ac435368ff1..c1b693cb3df38b180d1cece6d4acfe5582bb9d6a 100644 (file)
@@ -907,8 +907,11 @@ struct qlcnic_ipaddr {
 #define QLCNIC_FW_HANG                 0x4000
 #define QLCNIC_FW_LRO_MSS_CAP          0x8000
 #define QLCNIC_TX_INTR_SHARED          0x10000
+#define QLCNIC_APP_CHANGED_FLAGS       0x20000
 #define QLCNIC_IS_MSI_FAMILY(adapter) \
        ((adapter)->flags & (QLCNIC_MSI_ENABLED | QLCNIC_MSIX_ENABLED))
+#define QLCNIC_IS_TSO_CAPABLE(adapter)  \
+       ((adapter)->ahw->capabilities & QLCNIC_FW_CAPABILITY_TSO)
 
 #define QLCNIC_DEF_NUM_STS_DESC_RINGS  4
 #define QLCNIC_MSIX_TBL_SPACE          8192
@@ -1034,6 +1037,7 @@ struct qlcnic_adapter {
        spinlock_t rx_mac_learn_lock;
        u32 file_prd_off;       /*File fw product offset*/
        u32 fw_version;
+       u32 offload_flags;
        const struct firmware *fw;
 };
 
@@ -1542,6 +1546,8 @@ void qlcnic_add_lb_filter(struct qlcnic_adapter *, struct sk_buff *, int, u16);
 int qlcnic_83xx_configure_opmode(struct qlcnic_adapter *adapter);
 int qlcnic_read_mac_addr(struct qlcnic_adapter *);
 int qlcnic_setup_netdev(struct qlcnic_adapter *, struct net_device *, int);
+void qlcnic_set_netdev_features(struct qlcnic_adapter *,
+                               struct qlcnic_esw_func_cfg *);
 void qlcnic_sriov_vf_schedule_multi(struct net_device *);
 void qlcnic_vf_add_mc_list(struct net_device *, u16);
 
index c67d1eb35e8f7deab13803f74eb0e79dbce71c90..5e7fb1dfb97b54c63c46314eea8eeccd9dbbc643 100644 (file)
@@ -382,8 +382,6 @@ static int qlcnic_83xx_idc_tx_soft_reset(struct qlcnic_adapter *adapter)
        clear_bit(__QLCNIC_RESETTING, &adapter->state);
        dev_err(&adapter->pdev->dev, "%s:\n", __func__);
 
-       adapter->netdev->trans_start = jiffies;
-
        return 0;
 }
 
index 6a6512ba9f38824f0d72a844aaa0d96a95415a8f..106a12f2a02f5173fea587ed8a09f0b2882c0335 100644 (file)
@@ -973,16 +973,57 @@ int qlcnic_change_mtu(struct net_device *netdev, int mtu)
        return rc;
 }
 
+static netdev_features_t qlcnic_process_flags(struct qlcnic_adapter *adapter,
+                                             netdev_features_t features)
+{
+       u32 offload_flags = adapter->offload_flags;
+
+       if (offload_flags & BIT_0) {
+               features |= NETIF_F_RXCSUM | NETIF_F_IP_CSUM |
+                           NETIF_F_IPV6_CSUM;
+               adapter->rx_csum = 1;
+               if (QLCNIC_IS_TSO_CAPABLE(adapter)) {
+                       if (!(offload_flags & BIT_1))
+                               features &= ~NETIF_F_TSO;
+                       else
+                               features |= NETIF_F_TSO;
+
+                       if (!(offload_flags & BIT_2))
+                               features &= ~NETIF_F_TSO6;
+                       else
+                               features |= NETIF_F_TSO6;
+               }
+       } else {
+               features &= ~(NETIF_F_RXCSUM |
+                             NETIF_F_IP_CSUM |
+                             NETIF_F_IPV6_CSUM);
+
+               if (QLCNIC_IS_TSO_CAPABLE(adapter))
+                       features &= ~(NETIF_F_TSO | NETIF_F_TSO6);
+               adapter->rx_csum = 0;
+       }
+
+       return features;
+}
 
 netdev_features_t qlcnic_fix_features(struct net_device *netdev,
        netdev_features_t features)
 {
        struct qlcnic_adapter *adapter = netdev_priv(netdev);
+       netdev_features_t changed;
 
-       if ((adapter->flags & QLCNIC_ESWITCH_ENABLED) &&
-           qlcnic_82xx_check(adapter)) {
-               netdev_features_t changed = features ^ netdev->features;
-               features ^= changed & (NETIF_F_ALL_CSUM | NETIF_F_RXCSUM);
+       if (qlcnic_82xx_check(adapter) &&
+           (adapter->flags & QLCNIC_ESWITCH_ENABLED)) {
+               if (adapter->flags & QLCNIC_APP_CHANGED_FLAGS) {
+                       features = qlcnic_process_flags(adapter, features);
+               } else {
+                       changed = features ^ netdev->features;
+                       features ^= changed & (NETIF_F_RXCSUM |
+                                              NETIF_F_IP_CSUM |
+                                              NETIF_F_IPV6_CSUM |
+                                              NETIF_F_TSO |
+                                              NETIF_F_TSO6);
+               }
        }
 
        if (!(features & NETIF_F_RXCSUM))
index 8fb836d4129f964de07bd964405754a5b0cb74fb..aeb26a8506799c6a9263e41fa5d82633deafb9d7 100644 (file)
@@ -84,14 +84,9 @@ static int qlcnic_start_firmware(struct qlcnic_adapter *);
 static void qlcnic_free_lb_filters_mem(struct qlcnic_adapter *adapter);
 static void qlcnic_dev_set_npar_ready(struct qlcnic_adapter *);
 static int qlcnicvf_start_firmware(struct qlcnic_adapter *);
-static void qlcnic_set_netdev_features(struct qlcnic_adapter *,
-                               struct qlcnic_esw_func_cfg *);
 static int qlcnic_vlan_rx_add(struct net_device *, __be16, u16);
 static int qlcnic_vlan_rx_del(struct net_device *, __be16, u16);
 
-#define QLCNIC_IS_TSO_CAPABLE(adapter) \
-       ((adapter)->ahw->capabilities & QLCNIC_FW_CAPABILITY_TSO)
-
 static u32 qlcnic_vlan_tx_check(struct qlcnic_adapter *adapter)
 {
        struct qlcnic_hardware_context *ahw = adapter->ahw;
@@ -1074,8 +1069,6 @@ void qlcnic_set_eswitch_port_features(struct qlcnic_adapter *adapter,
 
        if (!esw_cfg->promisc_mode)
                adapter->flags |= QLCNIC_PROMISC_DISABLED;
-
-       qlcnic_set_netdev_features(adapter, esw_cfg);
 }
 
 int qlcnic_set_eswitch_port_config(struct qlcnic_adapter *adapter)
@@ -1090,51 +1083,23 @@ int qlcnic_set_eswitch_port_config(struct qlcnic_adapter *adapter)
                        return -EIO;
        qlcnic_set_vlan_config(adapter, &esw_cfg);
        qlcnic_set_eswitch_port_features(adapter, &esw_cfg);
+       qlcnic_set_netdev_features(adapter, &esw_cfg);
 
        return 0;
 }
 
-static void
-qlcnic_set_netdev_features(struct qlcnic_adapter *adapter,
-               struct qlcnic_esw_func_cfg *esw_cfg)
+void qlcnic_set_netdev_features(struct qlcnic_adapter *adapter,
+                               struct qlcnic_esw_func_cfg *esw_cfg)
 {
        struct net_device *netdev = adapter->netdev;
-       unsigned long features, vlan_features;
 
        if (qlcnic_83xx_check(adapter))
                return;
 
-       features = (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_RXCSUM |
-                   NETIF_F_IPV6_CSUM | NETIF_F_GRO);
-       vlan_features = (NETIF_F_SG | NETIF_F_IP_CSUM |
-                       NETIF_F_IPV6_CSUM);
-
-       if (QLCNIC_IS_TSO_CAPABLE(adapter)) {
-               features |= (NETIF_F_TSO | NETIF_F_TSO6);
-               vlan_features |= (NETIF_F_TSO | NETIF_F_TSO6);
-       }
-
-       if (netdev->features & NETIF_F_LRO)
-               features |= NETIF_F_LRO;
-
-       if (esw_cfg->offload_flags & BIT_0) {
-               netdev->features |= features;
-               adapter->rx_csum = 1;
-               if (!(esw_cfg->offload_flags & BIT_1)) {
-                       netdev->features &= ~NETIF_F_TSO;
-                       features &= ~NETIF_F_TSO;
-               }
-               if (!(esw_cfg->offload_flags & BIT_2)) {
-                       netdev->features &= ~NETIF_F_TSO6;
-                       features &= ~NETIF_F_TSO6;
-               }
-       } else {
-               netdev->features &= ~features;
-               features &= ~features;
-               adapter->rx_csum = 0;
-       }
-
-       netdev->vlan_features = (features & vlan_features);
+       adapter->offload_flags = esw_cfg->offload_flags;
+       adapter->flags |= QLCNIC_APP_CHANGED_FLAGS;
+       netdev_update_features(netdev);
+       adapter->flags &= ~QLCNIC_APP_CHANGED_FLAGS;
 }
 
 static int
@@ -2016,8 +1981,10 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        pci_enable_pcie_error_reporting(pdev);
 
        ahw = kzalloc(sizeof(struct qlcnic_hardware_context), GFP_KERNEL);
-       if (!ahw)
+       if (!ahw) {
+               err = -ENOMEM;
                goto err_out_free_res;
+       }
 
        switch (ent->device) {
        case PCI_DEVICE_ID_QLOGIC_QLE824X:
@@ -2053,6 +2020,7 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
        adapter->qlcnic_wq = create_singlethread_workqueue("qlcnic");
        if (adapter->qlcnic_wq == NULL) {
+               err = -ENOMEM;
                dev_err(&pdev->dev, "Failed to create workqueue\n");
                goto err_out_free_netdev;
        }
@@ -2133,6 +2101,10 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                        goto err_out_disable_msi;
        }
 
+       err = qlcnic_get_act_pci_func(adapter);
+       if (err)
+               goto err_out_disable_mbx_intr;
+
        err = qlcnic_setup_netdev(adapter, netdev, pci_using_dac);
        if (err)
                goto err_out_disable_mbx_intr;
@@ -2162,9 +2134,6 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                break;
        }
 
-       if (qlcnic_get_act_pci_func(adapter))
-               goto err_out_disable_mbx_intr;
-
        if (adapter->drv_mac_learn)
                qlcnic_alloc_lb_filters_mem(adapter);
 
@@ -3149,10 +3118,8 @@ qlcnic_check_health(struct qlcnic_adapter *adapter)
                if (adapter->need_fw_reset)
                        goto detach;
 
-               if (adapter->ahw->reset_context && qlcnic_auto_fw_reset) {
+               if (adapter->ahw->reset_context && qlcnic_auto_fw_reset)
                        qlcnic_reset_hw_context(adapter);
-                       adapter->netdev->trans_start = jiffies;
-               }
 
                return 0;
        }
index 3869c3864deb469ef1e4d43d8cb8ed28c7af204a..196b2d100407bf1de67d284c85f88e9f48d310c1 100644 (file)
@@ -1734,7 +1734,6 @@ static int qlcnic_sriov_vf_handle_context_reset(struct qlcnic_adapter *adapter)
 
        if (!qlcnic_sriov_vf_reinit_driver(adapter)) {
                qlcnic_sriov_vf_attach(adapter);
-               adapter->netdev->trans_start = jiffies;
                adapter->tx_timeo_cnt = 0;
                adapter->reset_ctx_cnt = 0;
                adapter->fw_fail_cnt = 0;
index 4e22e794a1863ea1abec985d91abe154afcf8b49..e7a2fe21b64911939b5279e3f459f7108054fed6 100644 (file)
@@ -544,6 +544,9 @@ static ssize_t qlcnic_sysfs_write_esw_config(struct file *file,
                switch (esw_cfg[i].op_mode) {
                case QLCNIC_PORT_DEFAULTS:
                        qlcnic_set_eswitch_port_features(adapter, &esw_cfg[i]);
+                       rtnl_lock();
+                       qlcnic_set_netdev_features(adapter, &esw_cfg[i]);
+                       rtnl_unlock();
                        break;
                case QLCNIC_ADD_VLAN:
                        qlcnic_set_vlan_config(adapter, &esw_cfg[i]);
index 7d1fb9ad1296e5825da2d845129ef38b51728cd7..03523459c4061627d1fad51f751082298eec2147 100644 (file)
@@ -1136,6 +1136,7 @@ static void cp_clean_rings (struct cp_private *cp)
                        cp->dev->stats.tx_dropped++;
                }
        }
+       netdev_reset_queue(cp->dev);
 
        memset(cp->rx_ring, 0, sizeof(struct cp_desc) * CP_RX_RING_SIZE);
        memset(cp->tx_ring, 0, sizeof(struct cp_desc) * CP_TX_RING_SIZE);
index 79c520b64fddd00ab36436215abbfa5847aa8336..393f961a013cec14daf9c624021fdd60be23939d 100644 (file)
@@ -5856,7 +5856,20 @@ err_out:
        return -EIO;
 }
 
-static inline void rtl8169_tso_csum(struct rtl8169_private *tp,
+static bool rtl_skb_pad(struct sk_buff *skb)
+{
+       if (skb_padto(skb, ETH_ZLEN))
+               return false;
+       skb_put(skb, ETH_ZLEN - skb->len);
+       return true;
+}
+
+static bool rtl_test_hw_pad_bug(struct rtl8169_private *tp, struct sk_buff *skb)
+{
+       return skb->len < ETH_ZLEN && tp->mac_version == RTL_GIGA_MAC_VER_34;
+}
+
+static inline bool rtl8169_tso_csum(struct rtl8169_private *tp,
                                    struct sk_buff *skb, u32 *opts)
 {
        const struct rtl_tx_desc_info *info = tx_desc_info + tp->txd_version;
@@ -5869,13 +5882,20 @@ static inline void rtl8169_tso_csum(struct rtl8169_private *tp,
        } else if (skb->ip_summed == CHECKSUM_PARTIAL) {
                const struct iphdr *ip = ip_hdr(skb);
 
+               if (unlikely(rtl_test_hw_pad_bug(tp, skb)))
+                       return skb_checksum_help(skb) == 0 && rtl_skb_pad(skb);
+
                if (ip->protocol == IPPROTO_TCP)
                        opts[offset] |= info->checksum.tcp;
                else if (ip->protocol == IPPROTO_UDP)
                        opts[offset] |= info->checksum.udp;
                else
                        WARN_ON_ONCE(1);
+       } else {
+               if (unlikely(rtl_test_hw_pad_bug(tp, skb)))
+                       return rtl_skb_pad(skb);
        }
+       return true;
 }
 
 static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
@@ -5896,17 +5916,15 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
                goto err_stop_0;
        }
 
-       /* 8168evl does not automatically pad to minimum length. */
-       if (unlikely(tp->mac_version == RTL_GIGA_MAC_VER_34 &&
-                    skb->len < ETH_ZLEN)) {
-               if (skb_padto(skb, ETH_ZLEN))
-                       goto err_update_stats;
-               skb_put(skb, ETH_ZLEN - skb->len);
-       }
-
        if (unlikely(le32_to_cpu(txd->opts1) & DescOwn))
                goto err_stop_0;
 
+       opts[1] = cpu_to_le32(rtl8169_tx_vlan_tag(skb));
+       opts[0] = DescOwn;
+
+       if (!rtl8169_tso_csum(tp, skb, opts))
+               goto err_update_stats;
+
        len = skb_headlen(skb);
        mapping = dma_map_single(d, skb->data, len, DMA_TO_DEVICE);
        if (unlikely(dma_mapping_error(d, mapping))) {
@@ -5918,11 +5936,6 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
        tp->tx_skb[entry].len = len;
        txd->addr = cpu_to_le64(mapping);
 
-       opts[1] = cpu_to_le32(rtl8169_tx_vlan_tag(skb));
-       opts[0] = DescOwn;
-
-       rtl8169_tso_csum(tp, skb, opts);
-
        frags = rtl8169_xmit_frags(tp, skb, opts);
        if (frags < 0)
                goto err_dma_1;
index 01b99206139a0acefeb9452ad62b55346c6278f6..39e4cb39de29493d30079f3ddcfc81e46cfbf5b4 100644 (file)
@@ -638,14 +638,16 @@ 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) +
-                     EFX_PAGE_IP_ALIGN + efx->rx_dma_len);
+                     NET_IP_ALIGN + efx->rx_dma_len);
        if (rx_buf_len <= PAGE_SIZE) {
                efx->rx_scatter = false;
                efx->rx_buffer_order = 0;
        } else if (efx->type->can_rx_scatter) {
+               BUILD_BUG_ON(EFX_RX_USR_BUF_SIZE % L1_CACHE_BYTES);
                BUILD_BUG_ON(sizeof(struct efx_rx_page_state) +
-                            EFX_PAGE_IP_ALIGN + EFX_RX_USR_BUF_SIZE >
-                            PAGE_SIZE / 2);
+                            2 * ALIGN(NET_IP_ALIGN + EFX_RX_USR_BUF_SIZE,
+                                      EFX_RX_BUF_ALIGNMENT) >
+                            PAGE_SIZE);
                efx->rx_scatter = true;
                efx->rx_dma_len = EFX_RX_USR_BUF_SIZE;
                efx->rx_buffer_order = 0;
index 9bd433a095c57b8a127b24a7ec5e55c60a50b24b..39d6bd77f0157523fcafc9b4ac8d0affded56d76 100644 (file)
 /* Maximum possible MTU the driver supports */
 #define EFX_MAX_MTU (9 * 1024)
 
-/* Size of an RX scatter buffer.  Small enough to pack 2 into a 4K page. */
-#define EFX_RX_USR_BUF_SIZE 1824
+/* Size of an RX scatter buffer.  Small enough to pack 2 into a 4K page,
+ * and should be a multiple of the cache line size.
+ */
+#define EFX_RX_USR_BUF_SIZE    (2048 - 256)
+
+/* If possible, we should ensure cache line alignment at start and end
+ * of every buffer.  Otherwise, we just need to ensure 4-byte
+ * alignment of the network header.
+ */
+#if NET_IP_ALIGN == 0
+#define EFX_RX_BUF_ALIGNMENT   L1_CACHE_BYTES
+#else
+#define EFX_RX_BUF_ALIGNMENT   4
+#endif
 
 /* Forward declare Precision Time Protocol (PTP) support structure. */
 struct efx_ptp_data;
@@ -467,25 +479,12 @@ enum nic_state {
        STATE_RECOVERY = 3,     /* device recovering from PCI error */
 };
 
-/*
- * Alignment of page-allocated RX buffers
- *
- * Controls the number of bytes inserted at the start of an RX buffer.
- * This is the equivalent of NET_IP_ALIGN [which controls the alignment
- * of the skb->head for hardware DMA].
- */
-#ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
-#define EFX_PAGE_IP_ALIGN 0
-#else
-#define EFX_PAGE_IP_ALIGN NET_IP_ALIGN
-#endif
-
 /*
  * Alignment of the skb->head which wraps a page-allocated RX buffer
  *
  * The skb allocated to wrap an rx_buffer can have this alignment. Since
  * the data is memcpy'd from the rx_buf, it does not need to be equal to
- * EFX_PAGE_IP_ALIGN.
+ * NET_IP_ALIGN.
  */
 #define EFX_PAGE_SKB_ALIGN 2
 
index e73e30bac10e268a6f031d717a3551cda1ddeeae..a7dfe36cabf4b7855291237c0ed5ec5caec28519 100644 (file)
@@ -93,8 +93,8 @@ 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 + EFX_PAGE_IP_ALIGN,
-                                     L1_CACHE_BYTES);
+       efx->rx_page_buf_step = ALIGN(efx->rx_dma_len + NET_IP_ALIGN,
+                                     EFX_RX_BUF_ALIGNMENT);
        efx->rx_bufs_per_page = efx->rx_buffer_order ? 1 :
                ((PAGE_SIZE - sizeof(struct efx_rx_page_state)) /
                 efx->rx_page_buf_step);
@@ -188,9 +188,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 + EFX_PAGE_IP_ALIGN;
+                       rx_buf->dma_addr = dma_addr + NET_IP_ALIGN;
                        rx_buf->page = page;
-                       rx_buf->page_offset = page_offset + EFX_PAGE_IP_ALIGN;
+                       rx_buf->page_offset = page_offset + NET_IP_ALIGN;
                        rx_buf->len = efx->rx_dma_len;
                        rx_buf->flags = 0;
                        ++rx_queue->added_count;
index cf887c2384e95004547bf56ef7dc8ea0a67e66e5..86adfa0a912e071c0585b9821b55210eb69456a5 100644 (file)
@@ -582,6 +582,7 @@ static const struct usb_device_id products[] = {
        {QMI_FIXED_INTF(0x1bbb, 0x011e, 4)},    /* Telekom Speedstick LTE II (Alcatel One Touch L100V LTE) */
        {QMI_FIXED_INTF(0x2357, 0x0201, 4)},    /* TP-LINK HSUPA Modem MA180 */
        {QMI_FIXED_INTF(0x1bc7, 0x1200, 5)},    /* Telit LE920 */
+       {QMI_FIXED_INTF(0x1e2d, 0x12d1, 4)},    /* Cinterion PLxx */
 
        /* 4. Gobi 1000 devices */
        {QMI_GOBI1K_DEVICE(0x05c6, 0x9212)},    /* Acer Gobi Modem Device */
index a491d3a95393e4c533918c572ab7ba9256fa48ec..6cbdac67f3a0d3f899b0a3ca783d427b2e1c9704 100644 (file)
@@ -130,19 +130,23 @@ struct rtl8150 {
        struct usb_device *udev;
        struct tasklet_struct tl;
        struct net_device *netdev;
-       struct urb *rx_urb, *tx_urb, *intr_urb, *ctrl_urb;
+       struct urb *rx_urb, *tx_urb, *intr_urb;
        struct sk_buff *tx_skb, *rx_skb;
        struct sk_buff *rx_skb_pool[RX_SKB_POOL_SIZE];
        spinlock_t rx_pool_lock;
        struct usb_ctrlrequest dr;
        int intr_interval;
-       __le16 rx_creg;
        u8 *intr_buff;
        u8 phy;
 };
 
 typedef struct rtl8150 rtl8150_t;
 
+struct async_req {
+       struct usb_ctrlrequest dr;
+       u16 rx_creg;
+};
+
 static const char driver_name [] = "rtl8150";
 
 /*
@@ -164,51 +168,47 @@ static int set_registers(rtl8150_t * dev, u16 indx, u16 size, void *data)
                               indx, 0, data, size, 500);
 }
 
-static void ctrl_callback(struct urb *urb)
+static void async_set_reg_cb(struct urb *urb)
 {
-       rtl8150_t *dev;
+       struct async_req *req = (struct async_req *)urb->context;
        int status = urb->status;
 
-       switch (status) {
-       case 0:
-               break;
-       case -EINPROGRESS:
-               break;
-       case -ENOENT:
-               break;
-       default:
-               if (printk_ratelimit())
-                       dev_warn(&urb->dev->dev, "ctrl urb status %d\n", status);
-       }
-       dev = urb->context;
-       clear_bit(RX_REG_SET, &dev->flags);
+       if (status < 0)
+               dev_dbg(&urb->dev->dev, "%s failed with %d", __func__, status);
+       kfree(req);
+       usb_free_urb(urb);
 }
 
-static int async_set_registers(rtl8150_t * dev, u16 indx, u16 size)
+static int async_set_registers(rtl8150_t *dev, u16 indx, u16 size, u16 reg)
 {
-       int ret;
-
-       if (test_bit(RX_REG_SET, &dev->flags))
-               return -EAGAIN;
+       int res = -ENOMEM;
+       struct urb *async_urb;
+       struct async_req *req;
 
-       dev->dr.bRequestType = RTL8150_REQT_WRITE;
-       dev->dr.bRequest = RTL8150_REQ_SET_REGS;
-       dev->dr.wValue = cpu_to_le16(indx);
-       dev->dr.wIndex = 0;
-       dev->dr.wLength = cpu_to_le16(size);
-       dev->ctrl_urb->transfer_buffer_length = size;
-       usb_fill_control_urb(dev->ctrl_urb, dev->udev,
-                        usb_sndctrlpipe(dev->udev, 0), (char *) &dev->dr,
-                        &dev->rx_creg, size, ctrl_callback, dev);
-       if ((ret = usb_submit_urb(dev->ctrl_urb, GFP_ATOMIC))) {
-               if (ret == -ENODEV)
+       req = kmalloc(sizeof(struct async_req), GFP_ATOMIC);
+       if (req == NULL)
+               return res;
+       async_urb = usb_alloc_urb(0, GFP_ATOMIC);
+       if (async_urb == NULL) {
+               kfree(req);
+               return res;
+       }
+       req->rx_creg = cpu_to_le16(reg);
+       req->dr.bRequestType = RTL8150_REQT_WRITE;
+       req->dr.bRequest = RTL8150_REQ_SET_REGS;
+       req->dr.wIndex = 0;
+       req->dr.wValue = cpu_to_le16(indx);
+       req->dr.wLength = cpu_to_le16(size);
+       usb_fill_control_urb(async_urb, dev->udev,
+                            usb_sndctrlpipe(dev->udev, 0), (void *)&req->dr,
+                            &req->rx_creg, size, async_set_reg_cb, req);
+       res = usb_submit_urb(async_urb, GFP_ATOMIC);
+       if (res) {
+               if (res == -ENODEV)
                        netif_device_detach(dev->netdev);
-               dev_err(&dev->udev->dev,
-                       "control request submission failed: %d\n", ret);
-       } else
-               set_bit(RX_REG_SET, &dev->flags);
-
-       return ret;
+               dev_err(&dev->udev->dev, "%s failed with %d\n", __func__, res);
+       }
+       return res;
 }
 
 static int read_mii_word(rtl8150_t * dev, u8 phy, __u8 indx, u16 * reg)
@@ -330,13 +330,6 @@ static int alloc_all_urbs(rtl8150_t * dev)
                usb_free_urb(dev->tx_urb);
                return 0;
        }
-       dev->ctrl_urb = usb_alloc_urb(0, GFP_KERNEL);
-       if (!dev->ctrl_urb) {
-               usb_free_urb(dev->rx_urb);
-               usb_free_urb(dev->tx_urb);
-               usb_free_urb(dev->intr_urb);
-               return 0;
-       }
 
        return 1;
 }
@@ -346,7 +339,6 @@ static void free_all_urbs(rtl8150_t * dev)
        usb_free_urb(dev->rx_urb);
        usb_free_urb(dev->tx_urb);
        usb_free_urb(dev->intr_urb);
-       usb_free_urb(dev->ctrl_urb);
 }
 
 static void unlink_all_urbs(rtl8150_t * dev)
@@ -354,7 +346,6 @@ static void unlink_all_urbs(rtl8150_t * dev)
        usb_kill_urb(dev->rx_urb);
        usb_kill_urb(dev->tx_urb);
        usb_kill_urb(dev->intr_urb);
-       usb_kill_urb(dev->ctrl_urb);
 }
 
 static inline struct sk_buff *pull_skb(rtl8150_t *dev)
@@ -629,7 +620,6 @@ static int enable_net_traffic(rtl8150_t * dev)
        }
        /* RCR bit7=1 attach Rx info at the end;  =0 HW CRC (which is broken) */
        rcr = 0x9e;
-       dev->rx_creg = cpu_to_le16(rcr);
        tcr = 0xd8;
        cr = 0x0c;
        if (!(rcr & 0x80))
@@ -662,20 +652,22 @@ static void rtl8150_tx_timeout(struct net_device *netdev)
 static void rtl8150_set_multicast(struct net_device *netdev)
 {
        rtl8150_t *dev = netdev_priv(netdev);
+       u16 rx_creg = 0x9e;
+
        netif_stop_queue(netdev);
        if (netdev->flags & IFF_PROMISC) {
-               dev->rx_creg |= cpu_to_le16(0x0001);
+               rx_creg |= 0x0001;
                dev_info(&netdev->dev, "%s: promiscuous mode\n", netdev->name);
        } else if (!netdev_mc_empty(netdev) ||
                   (netdev->flags & IFF_ALLMULTI)) {
-               dev->rx_creg &= cpu_to_le16(0xfffe);
-               dev->rx_creg |= cpu_to_le16(0x0002);
+               rx_creg &= 0xfffe;
+               rx_creg |= 0x0002;
                dev_info(&netdev->dev, "%s: allmulti set\n", netdev->name);
        } else {
                /* ~RX_MULTICAST, ~RX_PROMISCUOUS */
-               dev->rx_creg &= cpu_to_le16(0x00fc);
+               rx_creg &= 0x00fc;
        }
-       async_set_registers(dev, RCR, 2);
+       async_set_registers(dev, RCR, sizeof(rx_creg), rx_creg);
        netif_wake_queue(netdev);
 }
 
index f95cb032394bb03f05b7ae2605b7b9585e8e3c67..06ee82f557d45ba31b4847c187f57771ae2c73d2 100644 (file)
@@ -1477,7 +1477,7 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
 
        /* usbnet already took usb runtime pm, so have to enable the feature
         * for usb interface, otherwise usb_autopm_get_interface may return
-        * failure if USB_SUSPEND(RUNTIME_PM) is enabled.
+        * failure if RUNTIME_PM is enabled.
         */
        if (!driver->supports_autosuspend) {
                driver->supports_autosuspend = 1;
index 655bb25eed2b6e208baf2acb8b15a5f55d76f4a9..c9e00387d9996e3c5b0660a57bf296e4ff15f3d5 100644 (file)
@@ -636,10 +636,11 @@ static int virtnet_open(struct net_device *dev)
        struct virtnet_info *vi = netdev_priv(dev);
        int i;
 
-       for (i = 0; i < vi->curr_queue_pairs; i++) {
-               /* Make sure we have some buffers: if oom use wq. */
-               if (!try_fill_recv(&vi->rq[i], GFP_KERNEL))
-                       schedule_delayed_work(&vi->refill, 0);
+       for (i = 0; i < vi->max_queue_pairs; i++) {
+               if (i < vi->curr_queue_pairs)
+                       /* Make sure we have some buffers: if oom use wq. */
+                       if (!try_fill_recv(&vi->rq[i], GFP_KERNEL))
+                               schedule_delayed_work(&vi->refill, 0);
                virtnet_napi_enable(&vi->rq[i]);
        }
 
index ba81f3c39a837af31af507dd1b2c7f4a599fe479..3b1d2ee7156b00195376c674f605f5749a2daf64 100644 (file)
@@ -301,7 +301,7 @@ static inline struct hlist_head *vxlan_fdb_head(struct vxlan_dev *vxlan,
 }
 
 /* Look up Ethernet address in forwarding table */
-static struct vxlan_fdb *vxlan_find_mac(struct vxlan_dev *vxlan,
+static struct vxlan_fdb *__vxlan_find_mac(struct vxlan_dev *vxlan,
                                        const u8 *mac)
 
 {
@@ -316,6 +316,18 @@ static struct vxlan_fdb *vxlan_find_mac(struct vxlan_dev *vxlan,
        return NULL;
 }
 
+static struct vxlan_fdb *vxlan_find_mac(struct vxlan_dev *vxlan,
+                                       const u8 *mac)
+{
+       struct vxlan_fdb *f;
+
+       f = __vxlan_find_mac(vxlan, mac);
+       if (f)
+               f->used = jiffies;
+
+       return f;
+}
+
 /* Add/update destinations for multicast */
 static int vxlan_fdb_append(struct vxlan_fdb *f,
                            __be32 ip, __be16 port, __u32 vni, __u32 ifindex)
@@ -353,7 +365,7 @@ static int vxlan_fdb_create(struct vxlan_dev *vxlan,
        struct vxlan_fdb *f;
        int notify = 0;
 
-       f = vxlan_find_mac(vxlan, mac);
+       f = __vxlan_find_mac(vxlan, mac);
        if (f) {
                if (flags & NLM_F_EXCL) {
                        netdev_dbg(vxlan->dev,
@@ -563,7 +575,6 @@ static void vxlan_snoop(struct net_device *dev,
 
        f = vxlan_find_mac(vxlan, src_mac);
        if (likely(f)) {
-               f->used = jiffies;
                if (likely(f->remote.remote_ip == src_ip))
                        return;
 
index 639ba7d18ea41d14fd1ef55913c8bbc9ac7d8d42..6988e1d081f225c0c0a8efd0dc49fbacb4fc6a1a 100644 (file)
@@ -965,7 +965,7 @@ static void ar9003_hw_do_manual_peak_cal(struct ath_hw *ah,
 {
        int i;
 
-       if (!AR_SREV_9462(ah) && !AR_SREV_9565(ah))
+       if (!AR_SREV_9462(ah) && !AR_SREV_9565(ah) && !AR_SREV_9485(ah))
                return;
 
        for (i = 0; i < AR9300_MAX_CHAINS; i++) {
index 712f415b8c0861165ab2a2ee74cbea853788295b..88ff1d7b53ab41c642333d553646e90065c3045b 100644 (file)
@@ -1020,7 +1020,7 @@ static const u32 ar9485_1_1_baseband_postamble[][5] = {
        {0x0000a284, 0x00000000, 0x00000000, 0x000002a0, 0x000002a0},
        {0x0000a288, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
        {0x0000a28c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-       {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18},
+       {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00058d18, 0x00058d18},
        {0x0000a2d0, 0x00071981, 0x00071981, 0x00071982, 0x00071982},
        {0x0000a2d8, 0xf999a83a, 0xf999a83a, 0xf999a83a, 0xf999a83a},
        {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
index 8a1888d0207042ae5b97a91b77ce2fb025ac7ab1..366002f266f8745a600be340986a0f032bf65551 100644 (file)
@@ -254,6 +254,7 @@ struct ath_atx_tid {
        int sched;
        int paused;
        u8 state;
+       bool stop_cb;
 };
 
 struct ath_node {
@@ -351,7 +352,8 @@ void ath_tx_tasklet(struct ath_softc *sc);
 void ath_tx_edma_tasklet(struct ath_softc *sc);
 int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
                      u16 tid, u16 *ssn);
-void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid);
+bool ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid,
+                     bool flush);
 void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid);
 
 void ath_tx_aggr_wakeup(struct ath_softc *sc, struct ath_node *an);
index e6307b86363a3aee4d78ca7303f137c1da788dae..b37eb8d38811587a72bd575805c40c0680387c3f 100644 (file)
@@ -2008,6 +2008,14 @@ void ath9k_get_et_stats(struct ieee80211_hw *hw,
        WARN_ON(i != ATH9K_SSTATS_LEN);
 }
 
+void ath9k_deinit_debug(struct ath_softc *sc)
+{
+       if (config_enabled(CONFIG_ATH9K_DEBUGFS) && sc->rfs_chan_spec_scan) {
+               relay_close(sc->rfs_chan_spec_scan);
+               sc->rfs_chan_spec_scan = NULL;
+       }
+}
+
 int ath9k_init_debug(struct ath_hw *ah)
 {
        struct ath_common *common = ath9k_hw_common(ah);
index 794a7ec83a246cb85619aba6dfdb717c5955381c..9d49aab8b989fe733d98ea27793f2db01874d66a 100644 (file)
@@ -304,6 +304,7 @@ struct ath9k_debug {
 };
 
 int ath9k_init_debug(struct ath_hw *ah);
+void ath9k_deinit_debug(struct ath_softc *sc);
 
 void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status);
 void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf,
@@ -339,6 +340,10 @@ static inline int ath9k_init_debug(struct ath_hw *ah)
        return 0;
 }
 
+static inline void ath9k_deinit_debug(struct ath_softc *sc)
+{
+}
+
 static inline void ath_debug_stat_interrupt(struct ath_softc *sc,
                                            enum ath9k_int status)
 {
index 0237b28689619ab231a3e5d8dea7c211db3f1bbe..aba415103f942e51d2a29553a33ebd3c9a6be960 100644 (file)
@@ -906,7 +906,7 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc,
        if (!ath_is_world_regd(reg)) {
                error = regulatory_hint(hw->wiphy, reg->alpha2);
                if (error)
-                       goto unregister;
+                       goto debug_cleanup;
        }
 
        ath_init_leds(sc);
@@ -914,6 +914,8 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc,
 
        return 0;
 
+debug_cleanup:
+       ath9k_deinit_debug(sc);
 unregister:
        ieee80211_unregister_hw(hw);
 rx_cleanup:
@@ -942,11 +944,6 @@ static void ath9k_deinit_softc(struct ath_softc *sc)
                sc->dfs_detector->exit(sc->dfs_detector);
 
        ath9k_eeprom_release(sc);
-
-       if (config_enabled(CONFIG_ATH9K_DEBUGFS) && sc->rfs_chan_spec_scan) {
-               relay_close(sc->rfs_chan_spec_scan);
-               sc->rfs_chan_spec_scan = NULL;
-       }
 }
 
 void ath9k_deinit_device(struct ath_softc *sc)
@@ -960,6 +957,7 @@ void ath9k_deinit_device(struct ath_softc *sc)
 
        ath9k_ps_restore(sc);
 
+       ath9k_deinit_debug(sc);
        ieee80211_unregister_hw(hw);
        ath_rx_cleanup(sc);
        ath9k_deinit_softc(sc);
index a18414b5948b513ec1ccddf795fbfd8aeca17fb2..2382d1262e7f06d0c09973fe39b9ee242b582648 100644 (file)
@@ -1687,6 +1687,7 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw,
                              u16 tid, u16 *ssn, u8 buf_size)
 {
        struct ath_softc *sc = hw->priv;
+       bool flush = false;
        int ret = 0;
 
        local_bh_disable();
@@ -1703,12 +1704,13 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw,
                        ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
                ath9k_ps_restore(sc);
                break;
-       case IEEE80211_AMPDU_TX_STOP_CONT:
        case IEEE80211_AMPDU_TX_STOP_FLUSH:
        case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
+               flush = true;
+       case IEEE80211_AMPDU_TX_STOP_CONT:
                ath9k_ps_wakeup(sc);
-               ath_tx_aggr_stop(sc, sta, tid);
-               ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
+               if (ath_tx_aggr_stop(sc, sta, tid, flush))
+                       ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
                ath9k_ps_restore(sc);
                break;
        case IEEE80211_AMPDU_TX_OPERATIONAL:
index eab0fcb7ded6452604fd36f645872282735b1170..14bb3354ea645e970a9c847ab9b75fa7225ef8b4 100644 (file)
@@ -164,7 +164,20 @@ static void ath_set_rates(struct ieee80211_vif *vif, struct ieee80211_sta *sta,
                               ARRAY_SIZE(bf->rates));
 }
 
-static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
+static void ath_tx_clear_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
+{
+       tid->state &= ~AGGR_ADDBA_COMPLETE;
+       tid->state &= ~AGGR_CLEANUP;
+       if (!tid->stop_cb)
+               return;
+
+       ieee80211_start_tx_ba_cb_irqsafe(tid->an->vif, tid->an->sta->addr,
+                                        tid->tidno);
+       tid->stop_cb = false;
+}
+
+static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid,
+                            bool flush_packets)
 {
        struct ath_txq *txq = tid->ac->txq;
        struct sk_buff *skb;
@@ -181,16 +194,15 @@ static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
        while ((skb = __skb_dequeue(&tid->buf_q))) {
                fi = get_frame_info(skb);
                bf = fi->bf;
+               if (!bf && !flush_packets)
+                       bf = ath_tx_setup_buffer(sc, txq, tid, skb);
 
                if (!bf) {
-                       bf = ath_tx_setup_buffer(sc, txq, tid, skb);
-                       if (!bf) {
-                               ieee80211_free_txskb(sc->hw, skb);
-                               continue;
-                       }
+                       ieee80211_free_txskb(sc->hw, skb);
+                       continue;
                }
 
-               if (fi->retries) {
+               if (fi->retries || flush_packets) {
                        list_add_tail(&bf->list, &bf_head);
                        ath_tx_update_baw(sc, tid, bf->bf_state.seqno);
                        ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0);
@@ -201,12 +213,10 @@ static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
                }
        }
 
-       if (tid->baw_head == tid->baw_tail) {
-               tid->state &= ~AGGR_ADDBA_COMPLETE;
-               tid->state &= ~AGGR_CLEANUP;
-       }
+       if (tid->baw_head == tid->baw_tail)
+               ath_tx_clear_tid(sc, tid);
 
-       if (sendbar) {
+       if (sendbar && !flush_packets) {
                ath_txq_unlock(sc, txq);
                ath_send_bar(tid, tid->seq_start);
                ath_txq_lock(sc, txq);
@@ -277,9 +287,7 @@ static void ath_tid_drain(struct ath_softc *sc, struct ath_txq *txq,
 
                list_add_tail(&bf->list, &bf_head);
 
-               if (fi->retries)
-                       ath_tx_update_baw(sc, tid, bf->bf_state.seqno);
-
+               ath_tx_update_baw(sc, tid, bf->bf_state.seqno);
                ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0);
        }
 
@@ -602,7 +610,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
        }
 
        if (tid->state & AGGR_CLEANUP)
-               ath_tx_flush_tid(sc, tid);
+               ath_tx_flush_tid(sc, tid, false);
 
        rcu_read_unlock();
 
@@ -620,6 +628,7 @@ static void ath_tx_process_buffer(struct ath_softc *sc, struct ath_txq *txq,
                                  struct ath_tx_status *ts, struct ath_buf *bf,
                                  struct list_head *bf_head)
 {
+       struct ieee80211_tx_info *info;
        bool txok, flush;
 
        txok = !(ts->ts_status & ATH9K_TXERR_MASK);
@@ -631,8 +640,12 @@ static void ath_tx_process_buffer(struct ath_softc *sc, struct ath_txq *txq,
                txq->axq_ampdu_depth--;
 
        if (!bf_isampdu(bf)) {
-               if (!flush)
+               if (!flush) {
+                       info = IEEE80211_SKB_CB(bf->bf_mpdu);
+                       memcpy(info->control.rates, bf->rates,
+                              sizeof(info->control.rates));
                        ath_tx_rc_status(sc, bf, ts, 1, txok ? 0 : 1, txok);
+               }
                ath_tx_complete_buf(sc, bf, txq, bf_head, ts, txok);
        } else
                ath_tx_complete_aggr(sc, txq, bf, bf_head, ts, txok);
@@ -676,7 +689,7 @@ static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf,
 
        skb = bf->bf_mpdu;
        tx_info = IEEE80211_SKB_CB(skb);
-       rates = tx_info->control.rates;
+       rates = bf->rates;
 
        /*
         * Find the lowest frame length among the rate series that will have a
@@ -1256,18 +1269,23 @@ int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
        return 0;
 }
 
-void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
+bool ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid,
+                     bool flush)
 {
        struct ath_node *an = (struct ath_node *)sta->drv_priv;
        struct ath_atx_tid *txtid = ATH_AN_2_TID(an, tid);
        struct ath_txq *txq = txtid->ac->txq;
+       bool ret = !flush;
+
+       if (flush)
+               txtid->stop_cb = false;
 
        if (txtid->state & AGGR_CLEANUP)
-               return;
+               return false;
 
        if (!(txtid->state & AGGR_ADDBA_COMPLETE)) {
                txtid->state &= ~AGGR_ADDBA_PROGRESS;
-               return;
+               return ret;
        }
 
        ath_txq_lock(sc, txq);
@@ -1279,13 +1297,17 @@ void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
         * TID can only be reused after all in-progress subframes have been
         * completed.
         */
-       if (txtid->baw_head != txtid->baw_tail)
+       if (txtid->baw_head != txtid->baw_tail) {
                txtid->state |= AGGR_CLEANUP;
-       else
+               ret = false;
+               txtid->stop_cb = !flush;
+       } else {
                txtid->state &= ~AGGR_ADDBA_COMPLETE;
+       }
 
-       ath_tx_flush_tid(sc, txtid);
+       ath_tx_flush_tid(sc, txtid, flush);
        ath_txq_unlock_complete(sc, txq);
+       return ret;
 }
 
 void ath_tx_aggr_sleep(struct ieee80211_sta *sta, struct ath_softc *sc,
@@ -2415,6 +2437,7 @@ void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an)
                tid->ac = &an->ac[acno];
                tid->state &= ~AGGR_ADDBA_COMPLETE;
                tid->state &= ~AGGR_ADDBA_PROGRESS;
+               tid->stop_cb = false;
        }
 
        for (acno = 0, ac = &an->ac[acno];
@@ -2451,8 +2474,7 @@ void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an)
                }
 
                ath_tid_drain(sc, txq, tid);
-               tid->state &= ~AGGR_ADDBA_COMPLETE;
-               tid->state &= ~AGGR_CLEANUP;
+               ath_tx_clear_tid(sc, tid);
 
                ath_txq_unlock(sc, txq);
        }
index 6d758f2853522fc1c2112186e21f6595867a99f1..761f501959a9784c541ad65f107fd8ba1600bf04 100644 (file)
@@ -4140,6 +4140,10 @@ static const struct ieee80211_iface_limit brcmf_iface_limits[] = {
                .types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
                         BIT(NL80211_IFTYPE_P2P_GO)
        },
+       {
+               .max = 1,
+               .types = BIT(NL80211_IFTYPE_P2P_DEVICE)
+       }
 };
 static const struct ieee80211_iface_combination brcmf_iface_combos[] = {
        {
@@ -4197,7 +4201,8 @@ static struct wiphy *brcmf_setup_wiphy(struct device *phydev)
                                 BIT(NL80211_IFTYPE_ADHOC) |
                                 BIT(NL80211_IFTYPE_AP) |
                                 BIT(NL80211_IFTYPE_P2P_CLIENT) |
-                                BIT(NL80211_IFTYPE_P2P_GO);
+                                BIT(NL80211_IFTYPE_P2P_GO) |
+                                BIT(NL80211_IFTYPE_P2P_DEVICE);
        wiphy->iface_combinations = brcmf_iface_combos;
        wiphy->n_iface_combinations = ARRAY_SIZE(brcmf_iface_combos);
        wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
index 592d0aa634a8f7693bafc85235ecbd9ae123d039..e9a3cbc409ae1d239fb7ff9c4a43436e9994f26d 100644 (file)
@@ -1423,7 +1423,7 @@ il_setup_rx_scan_handlers(struct il_priv *il)
 }
 EXPORT_SYMBOL(il_setup_rx_scan_handlers);
 
-inline u16
+u16
 il_get_active_dwell_time(struct il_priv *il, enum ieee80211_band band,
                         u8 n_probes)
 {
index 191dcae8ba476573e2da094ab8f2a8a262ad89ce..c6384555aab4de0172c7f1a7c5662cce776e76ed 100644 (file)
@@ -173,6 +173,8 @@ enum {
        REPLY_DEBUG_CMD = 0xf0,
        DEBUG_LOG_MSG = 0xf7,
 
+       MCAST_FILTER_CMD = 0xd0,
+
        /* D3 commands/notifications */
        D3_CONFIG_CMD = 0xd3,
        PROT_OFFLOAD_CONFIG_CMD = 0xd4,
@@ -948,4 +950,29 @@ struct iwl_set_calib_default_cmd {
        u8 data[0];
 } __packed; /* PHY_CALIB_OVERRIDE_VALUES_S */
 
+#define MAX_PORT_ID_NUM        2
+
+/**
+ * struct iwl_mcast_filter_cmd - configure multicast filter.
+ * @filter_own: Set 1 to filter out multicast packets sent by station itself
+ * @port_id:   Multicast MAC addresses array specifier. This is a strange way
+ *             to identify network interface adopted in host-device IF.
+ *             It is used by FW as index in array of addresses. This array has
+ *             MAX_PORT_ID_NUM members.
+ * @count:     Number of MAC addresses in the array
+ * @pass_all:  Set 1 to pass all multicast packets.
+ * @bssid:     current association BSSID.
+ * @addr_list: Place holder for array of MAC addresses.
+ *             IMPORTANT: add padding if necessary to ensure DWORD alignment.
+ */
+struct iwl_mcast_filter_cmd {
+       u8 filter_own;
+       u8 port_id;
+       u8 count;
+       u8 pass_all;
+       u8 bssid[6];
+       u8 reserved[2];
+       u8 addr_list[0];
+} __packed; /* MCAST_FILTERING_CMD_API_S_VER_1 */
+
 #endif /* __fw_api_h__ */
index e6eca4d66f6c8bf2b0b9ada40a6ca9fe9ab83ce4..b2cc3d98e0f7aa2e89b744b17cd706ed20268cc6 100644 (file)
@@ -586,10 +586,12 @@ static int iwl_mvm_mac_ctxt_send_cmd(struct iwl_mvm *mvm,
  */
 static void iwl_mvm_mac_ctxt_cmd_fill_sta(struct iwl_mvm *mvm,
                                          struct ieee80211_vif *vif,
-                                         struct iwl_mac_data_sta *ctxt_sta)
+                                         struct iwl_mac_data_sta *ctxt_sta,
+                                         bool force_assoc_off)
 {
        /* We need the dtim_period to set the MAC as associated */
-       if (vif->bss_conf.assoc && vif->bss_conf.dtim_period) {
+       if (vif->bss_conf.assoc && vif->bss_conf.dtim_period &&
+           !force_assoc_off) {
                u32 dtim_offs;
 
                /*
@@ -659,7 +661,8 @@ static int iwl_mvm_mac_ctxt_cmd_station(struct iwl_mvm *mvm,
                cmd.filter_flags &= ~cpu_to_le32(MAC_FILTER_IN_BEACON);
 
        /* Fill the data specific for station mode */
-       iwl_mvm_mac_ctxt_cmd_fill_sta(mvm, vif, &cmd.sta);
+       iwl_mvm_mac_ctxt_cmd_fill_sta(mvm, vif, &cmd.sta,
+                                     action == FW_CTXT_ACTION_ADD);
 
        return iwl_mvm_mac_ctxt_send_cmd(mvm, &cmd);
 }
@@ -677,7 +680,8 @@ static int iwl_mvm_mac_ctxt_cmd_p2p_client(struct iwl_mvm *mvm,
        iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action);
 
        /* Fill the data specific for station mode */
-       iwl_mvm_mac_ctxt_cmd_fill_sta(mvm, vif, &cmd.p2p_sta.sta);
+       iwl_mvm_mac_ctxt_cmd_fill_sta(mvm, vif, &cmd.p2p_sta.sta,
+                                     action == FW_CTXT_ACTION_ADD);
 
        cmd.p2p_sta.ctwin = cpu_to_le32(noa->oppps_ctwindow &
                                        IEEE80211_P2P_OPPPS_CTWINDOW_MASK);
index dd158ec571fbb183374858e20ffd80325206db9d..a5eb8c82f16a806fea43738629e738cdeaaba0b6 100644 (file)
@@ -701,6 +701,20 @@ static void iwl_mvm_configure_filter(struct ieee80211_hw *hw,
        *total_flags = 0;
 }
 
+static int iwl_mvm_configure_mcast_filter(struct iwl_mvm *mvm,
+                                         struct ieee80211_vif *vif)
+{
+       struct iwl_mcast_filter_cmd mcast_filter_cmd = {
+               .pass_all = 1,
+       };
+
+       memcpy(mcast_filter_cmd.bssid, vif->bss_conf.bssid, ETH_ALEN);
+
+       return iwl_mvm_send_cmd_pdu(mvm, MCAST_FILTER_CMD, CMD_SYNC,
+                                   sizeof(mcast_filter_cmd),
+                                   &mcast_filter_cmd);
+}
+
 static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
                                             struct ieee80211_vif *vif,
                                             struct ieee80211_bss_conf *bss_conf,
@@ -722,6 +736,7 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
                                return;
                        }
                        iwl_mvm_bt_coex_vif_assoc(mvm, vif);
+                       iwl_mvm_configure_mcast_filter(mvm, vif);
                } else if (mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT) {
                        /* remove AP station now that the MAC is unassoc */
                        ret = iwl_mvm_rm_sta_id(mvm, vif, mvmvif->ap_sta_id);
@@ -931,7 +946,7 @@ static void iwl_mvm_mac_sta_notify(struct ieee80211_hw *hw,
 
        switch (cmd) {
        case STA_NOTIFY_SLEEP:
-               if (atomic_read(&mvmsta->pending_frames) > 0)
+               if (atomic_read(&mvm->pending_frames[mvmsta->sta_id]) > 0)
                        ieee80211_sta_block_awake(hw, sta, true);
                /*
                 * The fw updates the STA to be asleep. Tx packets on the Tx
index 8269bc5629519726c7092314cf8ce3d9d955606c..9f46b23801bc84187b6aba6ed4b89ca7149eafc6 100644 (file)
@@ -292,6 +292,7 @@ struct iwl_mvm {
        struct ieee80211_sta __rcu *fw_id_to_mac_id[IWL_MVM_STATION_COUNT];
        struct work_struct sta_drained_wk;
        unsigned long sta_drained[BITS_TO_LONGS(IWL_MVM_STATION_COUNT)];
+       atomic_t pending_frames[IWL_MVM_STATION_COUNT];
 
        /* configured by mac80211 */
        u32 rts_threshold;
index fe031d304d1eddfcdf7131cb3bf172d54a6121d0..b29c31a41594ecbfd66989e0eaaa020758007aac 100644 (file)
@@ -292,6 +292,7 @@ static const char *iwl_mvm_cmd_strings[REPLY_MAX] = {
        CMD(BT_COEX_PROT_ENV),
        CMD(BT_PROFILE_NOTIFICATION),
        CMD(BT_CONFIG),
+       CMD(MCAST_FILTER_CMD),
 };
 #undef CMD
 
index 2157b0f8ced5cc7c314a246d758a869128e57c59..2476e43799d5e6d5bfd182e62b30b3cbe77020a9 100644 (file)
@@ -298,6 +298,12 @@ int iwl_mvm_scan_request(struct iwl_mvm *mvm,
        else
                cmd->type = cpu_to_le32(SCAN_TYPE_FORCED);
 
+       /*
+        * TODO: This is a WA due to a bug in the FW AUX framework that does not
+        * properly handle time events that fail to be scheduled
+        */
+       cmd->type = cpu_to_le32(SCAN_TYPE_FORCED);
+
        cmd->repeats = cpu_to_le32(1);
 
        /*
index 0fd96e4da4613457746e11909945e6716c21c47e..5c664ed54400ed65c5232c9092c62dceaeadfdcd 100644 (file)
@@ -219,7 +219,7 @@ int iwl_mvm_add_sta(struct iwl_mvm *mvm,
        mvm_sta->max_agg_bufsize = LINK_QUAL_AGG_FRAME_LIMIT_DEF;
 
        /* HW restart, don't assume the memory has been zeroed */
-       atomic_set(&mvm_sta->pending_frames, 0);
+       atomic_set(&mvm->pending_frames[sta_id], 0);
        mvm_sta->tid_disable_agg = 0;
        mvm_sta->tfd_queue_msk = 0;
        for (i = 0; i < IEEE80211_NUM_ACS; i++)
@@ -406,15 +406,22 @@ int iwl_mvm_rm_sta(struct iwl_mvm *mvm,
                mvmvif->ap_sta_id = IWL_MVM_STATION_COUNT;
        }
 
+       /*
+        * Make sure that the tx response code sees the station as -EBUSY and
+        * calls the drain worker.
+        */
+       spin_lock_bh(&mvm_sta->lock);
        /*
         * There are frames pending on the AC queues for this station.
         * We need to wait until all the frames are drained...
         */
-       if (atomic_read(&mvm_sta->pending_frames)) {
-               ret = iwl_mvm_drain_sta(mvm, mvm_sta, true);
+       if (atomic_read(&mvm->pending_frames[mvm_sta->sta_id])) {
                rcu_assign_pointer(mvm->fw_id_to_mac_id[mvm_sta->sta_id],
                                   ERR_PTR(-EBUSY));
+               spin_unlock_bh(&mvm_sta->lock);
+               ret = iwl_mvm_drain_sta(mvm, mvm_sta, true);
        } else {
+               spin_unlock_bh(&mvm_sta->lock);
                ret = iwl_mvm_rm_sta_common(mvm, mvm_sta->sta_id);
                rcu_assign_pointer(mvm->fw_id_to_mac_id[mvm_sta->sta_id], NULL);
        }
index 12abd2d71835273e2405e94656f9f52454d7c9d1..a4ddce77aaaefa1eff7599ea275a9663b6cee648 100644 (file)
@@ -274,7 +274,6 @@ struct iwl_mvm_tid_data {
  * @bt_reduced_txpower: is reduced tx power enabled for this station
  * @lock: lock to protect the whole struct. Since %tid_data is access from Tx
  * and from Tx response flow, it needs a spinlock.
- * @pending_frames: number of frames for this STA on the shared Tx queues.
  * @tid_data: per tid data. Look at %iwl_mvm_tid_data.
  *
  * When mac80211 creates a station it reserves some space (hw->sta_data_size)
@@ -290,7 +289,6 @@ struct iwl_mvm_sta {
        u8 max_agg_bufsize;
        bool bt_reduced_txpower;
        spinlock_t lock;
-       atomic_t pending_frames;
        struct iwl_mvm_tid_data tid_data[IWL_MAX_TID_COUNT];
        struct iwl_lq_sta lq_sta;
        struct ieee80211_vif *vif;
index 479074303bd7f9af07a615c2a6a4ab6e286bf10e..f212f16502ff43c3b446d3f99e136fbf5c4b795a 100644 (file)
@@ -416,9 +416,8 @@ int iwl_mvm_tx_skb(struct iwl_mvm *mvm, struct sk_buff *skb,
 
        spin_unlock(&mvmsta->lock);
 
-       if (mvmsta->vif->type == NL80211_IFTYPE_AP &&
-           txq_id < IWL_MVM_FIRST_AGG_QUEUE)
-               atomic_inc(&mvmsta->pending_frames);
+       if (txq_id < IWL_MVM_FIRST_AGG_QUEUE)
+               atomic_inc(&mvm->pending_frames[mvmsta->sta_id]);
 
        return 0;
 
@@ -680,16 +679,41 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
        /*
         * If the txq is not an AMPDU queue, there is no chance we freed
         * several skbs. Check that out...
-        * If there are no pending frames for this STA, notify mac80211 that
-        * this station can go to sleep in its STA table.
         */
-       if (txq_id < IWL_MVM_FIRST_AGG_QUEUE && mvmsta &&
-           !WARN_ON(skb_freed > 1) &&
-           mvmsta->vif->type == NL80211_IFTYPE_AP &&
-           atomic_sub_and_test(skb_freed, &mvmsta->pending_frames)) {
-               ieee80211_sta_block_awake(mvm->hw, sta, false);
-               set_bit(sta_id, mvm->sta_drained);
-               schedule_work(&mvm->sta_drained_wk);
+       if (txq_id < IWL_MVM_FIRST_AGG_QUEUE && !WARN_ON(skb_freed > 1) &&
+           atomic_sub_and_test(skb_freed, &mvm->pending_frames[sta_id])) {
+               if (mvmsta) {
+                       /*
+                        * If there are no pending frames for this STA, notify
+                        * mac80211 that this station can go to sleep in its
+                        * STA table.
+                        */
+                       if (mvmsta->vif->type == NL80211_IFTYPE_AP)
+                               ieee80211_sta_block_awake(mvm->hw, sta, false);
+                       /*
+                        * We might very well have taken mvmsta pointer while
+                        * the station was being removed. The remove flow might
+                        * have seen a pending_frame (because we didn't take
+                        * the lock) even if now the queues are drained. So make
+                        * really sure now that this the station is not being
+                        * removed. If it is, run the drain worker to remove it.
+                        */
+                       spin_lock_bh(&mvmsta->lock);
+                       sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]);
+                       if (IS_ERR_OR_NULL(sta)) {
+                               /*
+                                * Station disappeared in the meantime:
+                                * so we are draining.
+                                */
+                               set_bit(sta_id, mvm->sta_drained);
+                               schedule_work(&mvm->sta_drained_wk);
+                       }
+                       spin_unlock_bh(&mvmsta->lock);
+               } else if (!mvmsta) {
+                       /* Tx response without STA, so we are draining */
+                       set_bit(sta_id, mvm->sta_drained);
+                       schedule_work(&mvm->sta_drained_wk);
+               }
        }
 
        rcu_read_unlock();
index b878a32e7a984d9f00410b04deed1f9483de1b10..cb34c7895f2a299b8c6b8f6c094f79cd9ab88c85 100644 (file)
@@ -1723,11 +1723,11 @@ static void mac80211_hwsim_free(void)
        class_destroy(hwsim_class);
 }
 
-
-static struct device_driver mac80211_hwsim_driver = {
-       .name = "mac80211_hwsim",
-       .bus = &platform_bus_type,
-       .owner = THIS_MODULE,
+static struct platform_driver mac80211_hwsim_driver = {
+       .driver = {
+               .name = "mac80211_hwsim",
+               .owner = THIS_MODULE,
+       },
 };
 
 static const struct net_device_ops hwsim_netdev_ops = {
@@ -2219,7 +2219,7 @@ static int __init init_mac80211_hwsim(void)
        spin_lock_init(&hwsim_radio_lock);
        INIT_LIST_HEAD(&hwsim_radios);
 
-       err = driver_register(&mac80211_hwsim_driver);
+       err = platform_driver_register(&mac80211_hwsim_driver);
        if (err)
                return err;
 
@@ -2254,7 +2254,7 @@ static int __init init_mac80211_hwsim(void)
                        err = -ENOMEM;
                        goto failed_drvdata;
                }
-               data->dev->driver = &mac80211_hwsim_driver;
+               data->dev->driver = &mac80211_hwsim_driver.driver;
                err = device_bind_driver(data->dev);
                if (err != 0) {
                        printk(KERN_DEBUG
@@ -2564,7 +2564,7 @@ failed_drvdata:
 failed:
        mac80211_hwsim_free();
 failed_unregister_driver:
-       driver_unregister(&mac80211_hwsim_driver);
+       platform_driver_unregister(&mac80211_hwsim_driver);
        return err;
 }
 module_init(init_mac80211_hwsim);
@@ -2577,6 +2577,6 @@ static void __exit exit_mac80211_hwsim(void)
 
        mac80211_hwsim_free();
        unregister_netdev(hwsim_mon);
-       driver_unregister(&mac80211_hwsim_driver);
+       platform_driver_unregister(&mac80211_hwsim_driver);
 }
 module_exit(exit_mac80211_hwsim);
index d3a02e73f53ad59f99dd00be5417776d67022466..21ca33a7c770b83e338bd735084d417444810efc 100644 (file)
@@ -550,7 +550,7 @@ do {                                                                \
         rxmcs == DESC92C_RATE11M)
 
 struct phy_rx_agc_info_t {
-       #if __LITTLE_ENDIAN
+       #ifdef __LITTLE_ENDIAN
                u8      gain:7, trsw:1;
        #else
                u8      trsw:1, gain:7;
@@ -574,7 +574,7 @@ struct phy_status_rpt {
        u8      stream_target_csi[2];
        u8      sig_evm;
        u8      rsvd_3;
-#if __LITTLE_ENDIAN
+#ifdef __LITTLE_ENDIAN
        u8      antsel_rx_keep_2:1;     /*ex_intf_flg:1;*/
        u8      sgi_en:1;
        u8      rxsc:2;
index 23d640a4debdd7c1d336c9e2f57ab51fbe06fd5e..938b1e670b9355950a2272dcc68b06b657effcbf 100644 (file)
@@ -349,6 +349,7 @@ static struct usb_device_id rtl8192c_usb_ids[] = {
        {RTL_USB_DEVICE(0x07aa, 0x0056, rtl92cu_hal_cfg)}, /*ATKK-Gemtek*/
        {RTL_USB_DEVICE(0x07b8, 0x8178, rtl92cu_hal_cfg)}, /*Funai -Abocom*/
        {RTL_USB_DEVICE(0x0846, 0x9021, rtl92cu_hal_cfg)}, /*Netgear-Sercomm*/
+       {RTL_USB_DEVICE(0x0846, 0xf001, rtl92cu_hal_cfg)}, /*On Netwrks N300MA*/
        {RTL_USB_DEVICE(0x0b05, 0x17ab, rtl92cu_hal_cfg)}, /*ASUS-Edimax*/
        {RTL_USB_DEVICE(0x0bda, 0x8186, rtl92cu_hal_cfg)}, /*Realtek 92CE-VAU*/
        {RTL_USB_DEVICE(0x0df6, 0x0061, rtl92cu_hal_cfg)}, /*Sitecom-Edimax*/
index ac6e8e7a02df079222725fc35074045f249719b2..a042d065a0c757bdee271718808c349c6a07898e 100644 (file)
@@ -494,15 +494,4 @@ static struct pci_driver superio_driver = {
        .probe =        superio_probe,
 };
 
-static int __init superio_modinit(void)
-{
-       return pci_register_driver(&superio_driver);
-}
-
-static void __exit superio_exit(void)
-{
-       pci_unregister_driver(&superio_driver);
-}
-
-module_init(superio_modinit);
-module_exit(superio_exit);
+module_pci_driver(superio_driver);
index 96fed19c6d90358833e37d1e9f55b1899b2d11b8..716aa93fff76437ab0038de385d7c4fa7ec04834 100644 (file)
@@ -950,6 +950,20 @@ check_sub_bridges(acpi_handle handle, u32 lvl, void *context, void **rv)
        return AE_OK ;
 }
 
+void acpiphp_check_host_bridge(acpi_handle handle)
+{
+       struct acpiphp_bridge *bridge;
+
+       bridge = acpiphp_handle_to_bridge(handle);
+       if (bridge) {
+               acpiphp_check_bridge(bridge);
+               put_bridge(bridge);
+       }
+
+       acpi_walk_namespace(ACPI_TYPE_DEVICE, handle,
+               ACPI_UINT32_MAX, check_sub_bridges, NULL, NULL, NULL);
+}
+
 static void _handle_hotplug_event_bridge(struct work_struct *work)
 {
        struct acpiphp_bridge *bridge;
index 0d0b5d7d19d02f9e2c0a245de4da43f084e3340e..7b8979c63f4882e6c3e5375b9f9c35c40e5a829c 100644 (file)
@@ -152,6 +152,7 @@ config BATTERY_SBS
 
 config BATTERY_BQ27x00
        tristate "BQ27x00 battery driver"
+       depends on I2C || I2C=n
        help
          Say Y here to enable support for batteries with BQ27x00 (I2C/HDQ) chips.
 
@@ -284,6 +285,7 @@ config CHARGER_LP8788
        tristate "TI LP8788 charger driver"
        depends on MFD_LP8788
        depends on LP8788_ADC
+       depends on IIO
        help
          Say Y to enable support for the LP8788 linear charger.
 
index a44175139bbf3a619d65fe611cc9fa961388cd76..fef56e2041b325cf9e086d434f1755fbca0a8857 100644 (file)
@@ -1269,5 +1269,5 @@ module_exit(pm2xxx_charger_exit);
 
 MODULE_LICENSE("GPL v2");
 MODULE_AUTHOR("Rajkumar kasirajan, Olivier Launay");
-MODULE_ALIAS("platform:pm2xxx-charger");
+MODULE_ALIAS("i2c:pm2xxx-charger");
 MODULE_DESCRIPTION("PM2xxx charger management driver");
index 58cbb009b74f144564b069bf9344e801a5f02743..56fb509f4be00834f964fa2636b35c97eebf6849 100644 (file)
@@ -207,7 +207,6 @@ static int wm831x_backup_remove(struct platform_device *pdev)
        struct wm831x_backup *devdata = platform_get_drvdata(pdev);
 
        power_supply_unregister(&devdata->backup);
-       kfree(devdata->backup.name);
 
        return 0;
 }
index 6194d35ebb9740c0af7f999dcb7b73aec75d91ca..5ab056494bbefc63d3e3a0a3daffcedd7c0a9ef4 100644 (file)
@@ -47,4 +47,24 @@ config RAPIDIO_DEBUG
 
          If you are unsure about this, say N here.
 
+choice
+       prompt "Enumeration method"
+       depends on RAPIDIO
+       default RAPIDIO_ENUM_BASIC
+       help
+         There are different enumeration and discovery mechanisms offered
+         for RapidIO subsystem. You may select single built-in method or
+         or any number of methods to be built as modules.
+         Selecting a built-in method disables use of loadable methods.
+
+         If unsure, select Basic built-in.
+
+config RAPIDIO_ENUM_BASIC
+       tristate "Basic"
+       help
+         This option includes basic RapidIO fabric enumeration and discovery
+         mechanism similar to one described in RapidIO specification Annex 1.
+
+endchoice
+
 source "drivers/rapidio/switches/Kconfig"
index ec3fb81210041e532206faac578cc9c897edaf82..3036702ffe8b5950e83c9979c6e596fb9aa57db3 100644 (file)
@@ -1,7 +1,8 @@
 #
 # Makefile for RapidIO interconnect services
 #
-obj-y += rio.o rio-access.o rio-driver.o rio-scan.o rio-sysfs.o
+obj-y += rio.o rio-access.o rio-driver.o rio-sysfs.o
+obj-$(CONFIG_RAPIDIO_ENUM_BASIC) += rio-scan.o
 
 obj-$(CONFIG_RAPIDIO)          += switches/
 obj-$(CONFIG_RAPIDIO)          += devices/
index 6faba406b6e9f705bb047232b796d8476e89e1db..a8b2c23a7ef4b7acbe4a771fbf72a2ddffded52f 100644 (file)
@@ -471,6 +471,10 @@ static irqreturn_t tsi721_irqhandler(int irq, void *ptr)
        u32 intval;
        u32 ch_inte;
 
+       /* For MSI mode disable all device-level interrupts */
+       if (priv->flags & TSI721_USING_MSI)
+               iowrite32(0, priv->regs + TSI721_DEV_INTE);
+
        dev_int = ioread32(priv->regs + TSI721_DEV_INT);
        if (!dev_int)
                return IRQ_NONE;
@@ -560,6 +564,14 @@ static irqreturn_t tsi721_irqhandler(int irq, void *ptr)
                }
        }
 #endif
+
+       /* For MSI mode re-enable device-level interrupts */
+       if (priv->flags & TSI721_USING_MSI) {
+               dev_int = TSI721_DEV_INT_SR2PC_CH | TSI721_DEV_INT_SRIO |
+                       TSI721_DEV_INT_SMSG_CH | TSI721_DEV_INT_BDMA_CH;
+               iowrite32(dev_int, priv->regs + TSI721_DEV_INTE);
+       }
+
        return IRQ_HANDLED;
 }
 
index 0f4a53bdaa3cf9b8e60c4c8dfbf5d6f80b3cf882..a0c875563d7669fbf69916c95bd0b0219417d985 100644 (file)
@@ -164,6 +164,13 @@ void rio_unregister_driver(struct rio_driver *rdrv)
        driver_unregister(&rdrv->driver);
 }
 
+void rio_attach_device(struct rio_dev *rdev)
+{
+       rdev->dev.bus = &rio_bus_type;
+       rdev->dev.parent = &rio_bus;
+}
+EXPORT_SYMBOL_GPL(rio_attach_device);
+
 /**
  *  rio_match_bus - Tell if a RIO device structure has a matching RIO driver device id structure
  *  @dev: the standard device structure to match against
@@ -200,6 +207,7 @@ struct bus_type rio_bus_type = {
        .name = "rapidio",
        .match = rio_match_bus,
        .dev_attrs = rio_dev_attrs,
+       .bus_attrs = rio_bus_attrs,
        .probe = rio_device_probe,
        .remove = rio_device_remove,
 };
index a965acd3c0e4e9f6903f95c4fdb7d8f6331669d3..4c15dbf810871e04f55bb28d30d0f7e2d1cc826d 100644 (file)
 
 #include "rio.h"
 
-LIST_HEAD(rio_devices);
-
 static void rio_init_em(struct rio_dev *rdev);
 
-DEFINE_SPINLOCK(rio_global_list_lock);
-
 static int next_destid = 0;
 static int next_comptag = 1;
 
@@ -326,127 +322,6 @@ static int rio_is_switch(struct rio_dev *rdev)
        return 0;
 }
 
-/**
- * rio_switch_init - Sets switch operations for a particular vendor switch
- * @rdev: RIO device
- * @do_enum: Enumeration/Discovery mode flag
- *
- * Searches the RIO switch ops table for known switch types. If the vid
- * and did match a switch table entry, then call switch initialization
- * routine to setup switch-specific routines.
- */
-static void rio_switch_init(struct rio_dev *rdev, int do_enum)
-{
-       struct rio_switch_ops *cur = __start_rio_switch_ops;
-       struct rio_switch_ops *end = __end_rio_switch_ops;
-
-       while (cur < end) {
-               if ((cur->vid == rdev->vid) && (cur->did == rdev->did)) {
-                       pr_debug("RIO: calling init routine for %s\n",
-                                rio_name(rdev));
-                       cur->init_hook(rdev, do_enum);
-                       break;
-               }
-               cur++;
-       }
-
-       if ((cur >= end) && (rdev->pef & RIO_PEF_STD_RT)) {
-               pr_debug("RIO: adding STD routing ops for %s\n",
-                       rio_name(rdev));
-               rdev->rswitch->add_entry = rio_std_route_add_entry;
-               rdev->rswitch->get_entry = rio_std_route_get_entry;
-               rdev->rswitch->clr_table = rio_std_route_clr_table;
-       }
-
-       if (!rdev->rswitch->add_entry || !rdev->rswitch->get_entry)
-               printk(KERN_ERR "RIO: missing routing ops for %s\n",
-                      rio_name(rdev));
-}
-
-/**
- * rio_add_device- Adds a RIO device to the device model
- * @rdev: RIO device
- *
- * Adds the RIO device to the global device list and adds the RIO
- * device to the RIO device list.  Creates the generic sysfs nodes
- * for an RIO device.
- */
-static int rio_add_device(struct rio_dev *rdev)
-{
-       int err;
-
-       err = device_add(&rdev->dev);
-       if (err)
-               return err;
-
-       spin_lock(&rio_global_list_lock);
-       list_add_tail(&rdev->global_list, &rio_devices);
-       spin_unlock(&rio_global_list_lock);
-
-       rio_create_sysfs_dev_files(rdev);
-
-       return 0;
-}
-
-/**
- * rio_enable_rx_tx_port - enable input receiver and output transmitter of
- * given port
- * @port: Master port associated with the RIO network
- * @local: local=1 select local port otherwise a far device is reached
- * @destid: Destination ID of the device to check host bit
- * @hopcount: Number of hops to reach the target
- * @port_num: Port (-number on switch) to enable on a far end device
- *
- * Returns 0 or 1 from on General Control Command and Status Register
- * (EXT_PTR+0x3C)
- */
-inline int rio_enable_rx_tx_port(struct rio_mport *port,
-                                int local, u16 destid,
-                                u8 hopcount, u8 port_num) {
-#ifdef CONFIG_RAPIDIO_ENABLE_RX_TX_PORTS
-       u32 regval;
-       u32 ext_ftr_ptr;
-
-       /*
-       * enable rx input tx output port
-       */
-       pr_debug("rio_enable_rx_tx_port(local = %d, destid = %d, hopcount = "
-                "%d, port_num = %d)\n", local, destid, hopcount, port_num);
-
-       ext_ftr_ptr = rio_mport_get_physefb(port, local, destid, hopcount);
-
-       if (local) {
-               rio_local_read_config_32(port, ext_ftr_ptr +
-                               RIO_PORT_N_CTL_CSR(0),
-                               &regval);
-       } else {
-               if (rio_mport_read_config_32(port, destid, hopcount,
-               ext_ftr_ptr + RIO_PORT_N_CTL_CSR(port_num), &regval) < 0)
-                       return -EIO;
-       }
-
-       if (regval & RIO_PORT_N_CTL_P_TYP_SER) {
-               /* serial */
-               regval = regval | RIO_PORT_N_CTL_EN_RX_SER
-                               | RIO_PORT_N_CTL_EN_TX_SER;
-       } else {
-               /* parallel */
-               regval = regval | RIO_PORT_N_CTL_EN_RX_PAR
-                               | RIO_PORT_N_CTL_EN_TX_PAR;
-       }
-
-       if (local) {
-               rio_local_write_config_32(port, ext_ftr_ptr +
-                                         RIO_PORT_N_CTL_CSR(0), regval);
-       } else {
-               if (rio_mport_write_config_32(port, destid, hopcount,
-                   ext_ftr_ptr + RIO_PORT_N_CTL_CSR(port_num), regval) < 0)
-                       return -EIO;
-       }
-#endif
-       return 0;
-}
-
 /**
  * rio_setup_device- Allocates and sets up a RIO device
  * @net: RIO network
@@ -587,8 +462,7 @@ static struct rio_dev *rio_setup_device(struct rio_net *net,
                             rdev->destid);
        }
 
-       rdev->dev.bus = &rio_bus_type;
-       rdev->dev.parent = &rio_bus;
+       rio_attach_device(rdev);
 
        device_initialize(&rdev->dev);
        rdev->dev.release = rio_release_dev;
@@ -1260,19 +1134,30 @@ static void rio_pw_enable(struct rio_mport *port, int enable)
 /**
  * rio_enum_mport- Start enumeration through a master port
  * @mport: Master port to send transactions
+ * @flags: Enumeration control flags
  *
  * Starts the enumeration process. If somebody has enumerated our
  * master port device, then give up. If not and we have an active
  * link, then start recursive peer enumeration. Returns %0 if
  * enumeration succeeds or %-EBUSY if enumeration fails.
  */
-int rio_enum_mport(struct rio_mport *mport)
+int rio_enum_mport(struct rio_mport *mport, u32 flags)
 {
        struct rio_net *net = NULL;
        int rc = 0;
 
        printk(KERN_INFO "RIO: enumerate master port %d, %s\n", mport->id,
               mport->name);
+
+       /*
+        * To avoid multiple start requests (repeat enumeration is not supported
+        * by this method) check if enumeration/discovery was performed for this
+        * mport: if mport was added into the list of mports for a net exit
+        * with error.
+        */
+       if (mport->nnode.next || mport->nnode.prev)
+               return -EBUSY;
+
        /* If somebody else enumerated our master port device, bail. */
        if (rio_enum_host(mport) < 0) {
                printk(KERN_INFO
@@ -1362,14 +1247,16 @@ static void rio_build_route_tables(struct rio_net *net)
 /**
  * rio_disc_mport- Start discovery through a master port
  * @mport: Master port to send transactions
+ * @flags: discovery control flags
  *
  * Starts the discovery process. If we have an active link,
- * then wait for the signal that enumeration is complete.
+ * then wait for the signal that enumeration is complete (if wait
+ * is allowed).
  * When enumeration completion is signaled, start recursive
  * peer discovery. Returns %0 if discovery succeeds or %-EBUSY
  * on failure.
  */
-int rio_disc_mport(struct rio_mport *mport)
+int rio_disc_mport(struct rio_mport *mport, u32 flags)
 {
        struct rio_net *net = NULL;
        unsigned long to_end;
@@ -1379,6 +1266,11 @@ int rio_disc_mport(struct rio_mport *mport)
 
        /* If master port has an active link, allocate net and discover peers */
        if (rio_mport_is_active(mport)) {
+               if (rio_enum_complete(mport))
+                       goto enum_done;
+               else if (flags & RIO_SCAN_ENUM_NO_WAIT)
+                       return -EAGAIN;
+
                pr_debug("RIO: wait for enumeration to complete...\n");
 
                to_end = jiffies + CONFIG_RAPIDIO_DISC_TIMEOUT * HZ;
@@ -1421,3 +1313,41 @@ enum_done:
 bail:
        return -EBUSY;
 }
+
+static struct rio_scan rio_scan_ops = {
+       .enumerate = rio_enum_mport,
+       .discover = rio_disc_mport,
+};
+
+static bool scan;
+module_param(scan, bool, 0);
+MODULE_PARM_DESC(scan, "Start RapidIO network enumeration/discovery "
+                       "(default = 0)");
+
+/**
+ * rio_basic_attach:
+ *
+ * When this enumeration/discovery method is loaded as a module this function
+ * registers its specific enumeration and discover routines for all available
+ * RapidIO mport devices. The "scan" command line parameter controls ability of
+ * the module to start RapidIO enumeration/discovery automatically.
+ *
+ * Returns 0 for success or -EIO if unable to register itself.
+ *
+ * This enumeration/discovery method cannot be unloaded and therefore does not
+ * provide a matching cleanup_module routine.
+ */
+
+static int __init rio_basic_attach(void)
+{
+       if (rio_register_scan(RIO_MPORT_ANY, &rio_scan_ops))
+               return -EIO;
+       if (scan)
+               rio_init_mports();
+       return 0;
+}
+
+late_initcall(rio_basic_attach);
+
+MODULE_DESCRIPTION("Basic RapidIO enumeration/discovery");
+MODULE_LICENSE("GPL");
index 4dbe360989be8b3ed1b156e7f61aeaafb5b68fff..66d4acd5e18fd8f230cbb732a12dce1b90f98978 100644 (file)
@@ -285,3 +285,48 @@ void rio_remove_sysfs_dev_files(struct rio_dev *rdev)
                        rdev->rswitch->sw_sysfs(rdev, RIO_SW_SYSFS_REMOVE);
        }
 }
+
+static ssize_t bus_scan_store(struct bus_type *bus, const char *buf,
+                               size_t count)
+{
+       long val;
+       struct rio_mport *port = NULL;
+       int rc;
+
+       if (kstrtol(buf, 0, &val) < 0)
+               return -EINVAL;
+
+       if (val == RIO_MPORT_ANY) {
+               rc = rio_init_mports();
+               goto exit;
+       }
+
+       if (val < 0 || val >= RIO_MAX_MPORTS)
+               return -EINVAL;
+
+       port = rio_find_mport((int)val);
+
+       if (!port) {
+               pr_debug("RIO: %s: mport_%d not available\n",
+                        __func__, (int)val);
+               return -EINVAL;
+       }
+
+       if (!port->nscan)
+               return -EINVAL;
+
+       if (port->host_deviceid >= 0)
+               rc = port->nscan->enumerate(port, 0);
+       else
+               rc = port->nscan->discover(port, RIO_SCAN_ENUM_NO_WAIT);
+exit:
+       if (!rc)
+               rc = count;
+
+       return rc;
+}
+
+struct bus_attribute rio_bus_attrs[] = {
+       __ATTR(scan, (S_IWUSR|S_IWGRP), NULL, bus_scan_store),
+       __ATTR_NULL
+};
index d553b5d137224434bc2466582d5004644039b25b..cb1c08996fbb133a2a49b68635a563abf3a2742c 100644 (file)
 
 #include "rio.h"
 
+static LIST_HEAD(rio_devices);
+static DEFINE_SPINLOCK(rio_global_list_lock);
+
 static LIST_HEAD(rio_mports);
+static DEFINE_MUTEX(rio_mport_list_lock);
 static unsigned char next_portid;
 static DEFINE_SPINLOCK(rio_mmap_lock);
 
@@ -52,6 +56,32 @@ u16 rio_local_get_device_id(struct rio_mport *port)
        return (RIO_GET_DID(port->sys_size, result));
 }
 
+/**
+ * rio_add_device- Adds a RIO device to the device model
+ * @rdev: RIO device
+ *
+ * Adds the RIO device to the global device list and adds the RIO
+ * device to the RIO device list.  Creates the generic sysfs nodes
+ * for an RIO device.
+ */
+int rio_add_device(struct rio_dev *rdev)
+{
+       int err;
+
+       err = device_add(&rdev->dev);
+       if (err)
+               return err;
+
+       spin_lock(&rio_global_list_lock);
+       list_add_tail(&rdev->global_list, &rio_devices);
+       spin_unlock(&rio_global_list_lock);
+
+       rio_create_sysfs_dev_files(rdev);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(rio_add_device);
+
 /**
  * rio_request_inb_mbox - request inbound mailbox service
  * @mport: RIO master port from which to allocate the mailbox resource
@@ -489,6 +519,7 @@ rio_mport_get_physefb(struct rio_mport *port, int local,
 
        return ext_ftr_ptr;
 }
+EXPORT_SYMBOL_GPL(rio_mport_get_physefb);
 
 /**
  * rio_get_comptag - Begin or continue searching for a RIO device by component tag
@@ -521,6 +552,7 @@ exit:
        spin_unlock(&rio_global_list_lock);
        return rdev;
 }
+EXPORT_SYMBOL_GPL(rio_get_comptag);
 
 /**
  * rio_set_port_lockout - Sets/clears LOCKOUT bit (RIO EM 1.3) for a switch port.
@@ -545,6 +577,107 @@ int rio_set_port_lockout(struct rio_dev *rdev, u32 pnum, int lock)
                                  regval);
        return 0;
 }
+EXPORT_SYMBOL_GPL(rio_set_port_lockout);
+
+/**
+ * rio_switch_init - Sets switch operations for a particular vendor switch
+ * @rdev: RIO device
+ * @do_enum: Enumeration/Discovery mode flag
+ *
+ * Searches the RIO switch ops table for known switch types. If the vid
+ * and did match a switch table entry, then call switch initialization
+ * routine to setup switch-specific routines.
+ */
+void rio_switch_init(struct rio_dev *rdev, int do_enum)
+{
+       struct rio_switch_ops *cur = __start_rio_switch_ops;
+       struct rio_switch_ops *end = __end_rio_switch_ops;
+
+       while (cur < end) {
+               if ((cur->vid == rdev->vid) && (cur->did == rdev->did)) {
+                       pr_debug("RIO: calling init routine for %s\n",
+                                rio_name(rdev));
+                       cur->init_hook(rdev, do_enum);
+                       break;
+               }
+               cur++;
+       }
+
+       if ((cur >= end) && (rdev->pef & RIO_PEF_STD_RT)) {
+               pr_debug("RIO: adding STD routing ops for %s\n",
+                       rio_name(rdev));
+               rdev->rswitch->add_entry = rio_std_route_add_entry;
+               rdev->rswitch->get_entry = rio_std_route_get_entry;
+               rdev->rswitch->clr_table = rio_std_route_clr_table;
+       }
+
+       if (!rdev->rswitch->add_entry || !rdev->rswitch->get_entry)
+               printk(KERN_ERR "RIO: missing routing ops for %s\n",
+                      rio_name(rdev));
+}
+EXPORT_SYMBOL_GPL(rio_switch_init);
+
+/**
+ * rio_enable_rx_tx_port - enable input receiver and output transmitter of
+ * given port
+ * @port: Master port associated with the RIO network
+ * @local: local=1 select local port otherwise a far device is reached
+ * @destid: Destination ID of the device to check host bit
+ * @hopcount: Number of hops to reach the target
+ * @port_num: Port (-number on switch) to enable on a far end device
+ *
+ * Returns 0 or 1 from on General Control Command and Status Register
+ * (EXT_PTR+0x3C)
+ */
+int rio_enable_rx_tx_port(struct rio_mport *port,
+                         int local, u16 destid,
+                         u8 hopcount, u8 port_num)
+{
+#ifdef CONFIG_RAPIDIO_ENABLE_RX_TX_PORTS
+       u32 regval;
+       u32 ext_ftr_ptr;
+
+       /*
+       * enable rx input tx output port
+       */
+       pr_debug("rio_enable_rx_tx_port(local = %d, destid = %d, hopcount = "
+                "%d, port_num = %d)\n", local, destid, hopcount, port_num);
+
+       ext_ftr_ptr = rio_mport_get_physefb(port, local, destid, hopcount);
+
+       if (local) {
+               rio_local_read_config_32(port, ext_ftr_ptr +
+                               RIO_PORT_N_CTL_CSR(0),
+                               &regval);
+       } else {
+               if (rio_mport_read_config_32(port, destid, hopcount,
+               ext_ftr_ptr + RIO_PORT_N_CTL_CSR(port_num), &regval) < 0)
+                       return -EIO;
+       }
+
+       if (regval & RIO_PORT_N_CTL_P_TYP_SER) {
+               /* serial */
+               regval = regval | RIO_PORT_N_CTL_EN_RX_SER
+                               | RIO_PORT_N_CTL_EN_TX_SER;
+       } else {
+               /* parallel */
+               regval = regval | RIO_PORT_N_CTL_EN_RX_PAR
+                               | RIO_PORT_N_CTL_EN_TX_PAR;
+       }
+
+       if (local) {
+               rio_local_write_config_32(port, ext_ftr_ptr +
+                                         RIO_PORT_N_CTL_CSR(0), regval);
+       } else {
+               if (rio_mport_write_config_32(port, destid, hopcount,
+                   ext_ftr_ptr + RIO_PORT_N_CTL_CSR(port_num), regval) < 0)
+                       return -EIO;
+       }
+#endif
+       return 0;
+}
+EXPORT_SYMBOL_GPL(rio_enable_rx_tx_port);
+
 
 /**
  * rio_chk_dev_route - Validate route to the specified device.
@@ -610,6 +743,7 @@ rio_mport_chk_dev_access(struct rio_mport *mport, u16 destid, u8 hopcount)
 
        return 0;
 }
+EXPORT_SYMBOL_GPL(rio_mport_chk_dev_access);
 
 /**
  * rio_chk_dev_access - Validate access to the specified device.
@@ -941,6 +1075,7 @@ rio_mport_get_efb(struct rio_mport *port, int local, u16 destid,
                return RIO_GET_BLOCK_ID(reg_val);
        }
 }
+EXPORT_SYMBOL_GPL(rio_mport_get_efb);
 
 /**
  * rio_mport_get_feature - query for devices' extended features
@@ -997,6 +1132,7 @@ rio_mport_get_feature(struct rio_mport * port, int local, u16 destid,
 
        return 0;
 }
+EXPORT_SYMBOL_GPL(rio_mport_get_feature);
 
 /**
  * rio_get_asm - Begin or continue searching for a RIO device by vid/did/asm_vid/asm_did
@@ -1246,6 +1382,95 @@ EXPORT_SYMBOL_GPL(rio_dma_prep_slave_sg);
 
 #endif /* CONFIG_RAPIDIO_DMA_ENGINE */
 
+/**
+ * rio_find_mport - find RIO mport by its ID
+ * @mport_id: number (ID) of mport device
+ *
+ * Given a RIO mport number, the desired mport is located
+ * in the global list of mports. If the mport is found, a pointer to its
+ * data structure is returned.  If no mport is found, %NULL is returned.
+ */
+struct rio_mport *rio_find_mport(int mport_id)
+{
+       struct rio_mport *port;
+
+       mutex_lock(&rio_mport_list_lock);
+       list_for_each_entry(port, &rio_mports, node) {
+               if (port->id == mport_id)
+                       goto found;
+       }
+       port = NULL;
+found:
+       mutex_unlock(&rio_mport_list_lock);
+
+       return port;
+}
+
+/**
+ * rio_register_scan - enumeration/discovery method registration interface
+ * @mport_id: mport device ID for which fabric scan routine has to be set
+ *            (RIO_MPORT_ANY = set for all available mports)
+ * @scan_ops: enumeration/discovery control structure
+ *
+ * Assigns enumeration or discovery method to the specified mport device (or all
+ * available mports if RIO_MPORT_ANY is specified).
+ * Returns error if the mport already has an enumerator attached to it.
+ * In case of RIO_MPORT_ANY ignores ports with valid scan routines and returns
+ * an error if was unable to find at least one available mport.
+ */
+int rio_register_scan(int mport_id, struct rio_scan *scan_ops)
+{
+       struct rio_mport *port;
+       int rc = -EBUSY;
+
+       mutex_lock(&rio_mport_list_lock);
+       list_for_each_entry(port, &rio_mports, node) {
+               if (port->id == mport_id || mport_id == RIO_MPORT_ANY) {
+                       if (port->nscan && mport_id == RIO_MPORT_ANY)
+                               continue;
+                       else if (port->nscan)
+                               break;
+
+                       port->nscan = scan_ops;
+                       rc = 0;
+
+                       if (mport_id != RIO_MPORT_ANY)
+                               break;
+               }
+       }
+       mutex_unlock(&rio_mport_list_lock);
+
+       return rc;
+}
+EXPORT_SYMBOL_GPL(rio_register_scan);
+
+/**
+ * rio_unregister_scan - removes enumeration/discovery method from mport
+ * @mport_id: mport device ID for which fabric scan routine has to be
+ *            unregistered (RIO_MPORT_ANY = set for all available mports)
+ *
+ * Removes enumeration or discovery method assigned to the specified mport
+ * device (or all available mports if RIO_MPORT_ANY is specified).
+ */
+int rio_unregister_scan(int mport_id)
+{
+       struct rio_mport *port;
+
+       mutex_lock(&rio_mport_list_lock);
+       list_for_each_entry(port, &rio_mports, node) {
+               if (port->id == mport_id || mport_id == RIO_MPORT_ANY) {
+                       if (port->nscan)
+                               port->nscan = NULL;
+                       if (mport_id != RIO_MPORT_ANY)
+                               break;
+               }
+       }
+       mutex_unlock(&rio_mport_list_lock);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(rio_unregister_scan);
+
 static void rio_fixup_device(struct rio_dev *dev)
 {
 }
@@ -1274,7 +1499,7 @@ static void disc_work_handler(struct work_struct *_work)
        work = container_of(_work, struct rio_disc_work, work);
        pr_debug("RIO: discovery work for mport %d %s\n",
                 work->mport->id, work->mport->name);
-       rio_disc_mport(work->mport);
+       work->mport->nscan->discover(work->mport, 0);
 }
 
 int rio_init_mports(void)
@@ -1290,12 +1515,15 @@ int rio_init_mports(void)
         * First, run enumerations and check if we need to perform discovery
         * on any of the registered mports.
         */
+       mutex_lock(&rio_mport_list_lock);
        list_for_each_entry(port, &rio_mports, node) {
-               if (port->host_deviceid >= 0)
-                       rio_enum_mport(port);
-               else
+               if (port->host_deviceid >= 0) {
+                       if (port->nscan)
+                               port->nscan->enumerate(port, 0);
+               } else
                        n++;
        }
+       mutex_unlock(&rio_mport_list_lock);
 
        if (!n)
                goto no_disc;
@@ -1322,14 +1550,16 @@ int rio_init_mports(void)
        }
 
        n = 0;
+       mutex_lock(&rio_mport_list_lock);
        list_for_each_entry(port, &rio_mports, node) {
-               if (port->host_deviceid < 0) {
+               if (port->host_deviceid < 0 && port->nscan) {
                        work[n].mport = port;
                        INIT_WORK(&work[n].work, disc_work_handler);
                        queue_work(rio_wq, &work[n].work);
                        n++;
                }
        }
+       mutex_unlock(&rio_mport_list_lock);
 
        flush_workqueue(rio_wq);
        pr_debug("RIO: destroy discovery workqueue\n");
@@ -1342,8 +1572,6 @@ no_disc:
        return 0;
 }
 
-device_initcall_sync(rio_init_mports);
-
 static int hdids[RIO_MAX_MPORTS + 1];
 
 static int rio_get_hdid(int index)
@@ -1371,7 +1599,10 @@ int rio_register_mport(struct rio_mport *port)
 
        port->id = next_portid++;
        port->host_deviceid = rio_get_hdid(port->id);
+       port->nscan = NULL;
+       mutex_lock(&rio_mport_list_lock);
        list_add_tail(&port->node, &rio_mports);
+       mutex_unlock(&rio_mport_list_lock);
        return 0;
 }
 
@@ -1386,3 +1617,4 @@ EXPORT_SYMBOL_GPL(rio_request_inb_mbox);
 EXPORT_SYMBOL_GPL(rio_release_inb_mbox);
 EXPORT_SYMBOL_GPL(rio_request_outb_mbox);
 EXPORT_SYMBOL_GPL(rio_release_outb_mbox);
+EXPORT_SYMBOL_GPL(rio_init_mports);
index b1af414f15e60f8e0cee81270321fa2d6ddf5c84..c14f864dea5cbf420fd247ec6d4584c89e932703 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/rio.h>
 
 #define RIO_MAX_CHK_RETRY      3
+#define RIO_MPORT_ANY          (-1)
 
 /* Functions internal to the RIO core code */
 
@@ -27,8 +28,6 @@ extern u32 rio_mport_get_efb(struct rio_mport *port, int local, u16 destid,
 extern int rio_mport_chk_dev_access(struct rio_mport *mport, u16 destid,
                                    u8 hopcount);
 extern int rio_create_sysfs_dev_files(struct rio_dev *rdev);
-extern int rio_enum_mport(struct rio_mport *mport);
-extern int rio_disc_mport(struct rio_mport *mport);
 extern int rio_std_route_add_entry(struct rio_mport *mport, u16 destid,
                                   u8 hopcount, u16 table, u16 route_destid,
                                   u8 route_port);
@@ -39,10 +38,18 @@ extern int rio_std_route_clr_table(struct rio_mport *mport, u16 destid,
                                   u8 hopcount, u16 table);
 extern int rio_set_port_lockout(struct rio_dev *rdev, u32 pnum, int lock);
 extern struct rio_dev *rio_get_comptag(u32 comp_tag, struct rio_dev *from);
+extern int rio_add_device(struct rio_dev *rdev);
+extern void rio_switch_init(struct rio_dev *rdev, int do_enum);
+extern int rio_enable_rx_tx_port(struct rio_mport *port, int local, u16 destid,
+                                u8 hopcount, u8 port_num);
+extern int rio_register_scan(int mport_id, struct rio_scan *scan_ops);
+extern int rio_unregister_scan(int mport_id);
+extern void rio_attach_device(struct rio_dev *rdev);
+extern struct rio_mport *rio_find_mport(int mport_id);
 
 /* Structures internal to the RIO core code */
 extern struct device_attribute rio_dev_attrs[];
-extern spinlock_t rio_global_list_lock;
+extern struct bus_attribute rio_bus_attrs[];
 
 extern struct rio_switch_ops __start_rio_switch_ops[];
 extern struct rio_switch_ops __end_rio_switch_ops[];
index 48b6612fae7fb59b13804972e2709884f79da92a..d5af7baa48b56c893e449b418d158f7b25448628 100644 (file)
@@ -285,7 +285,7 @@ static int max8998_rtc_probe(struct platform_device *pdev)
                        info->irq, ret);
 
        dev_info(&pdev->dev, "RTC CHIP NAME: %s\n", pdev->id_entry->name);
-       if (pdata->rtc_delay) {
+       if (pdata && pdata->rtc_delay) {
                info->lp3974_bug_workaround = true;
                dev_warn(&pdev->dev, "LP3974 with RTC REGERR option."
                                " RTC updates will be extremely slow.\n");
index 8900ea784817a66d12300f844a162026580e42c0..0f0609b1aa2ccfead83ec98db660a58fac5736de 100644 (file)
@@ -306,7 +306,7 @@ static int pl031_remove(struct amba_device *adev)
        struct pl031_local *ldata = dev_get_drvdata(&adev->dev);
 
        amba_set_drvdata(adev, NULL);
-       free_irq(adev->irq[0], ldata->rtc);
+       free_irq(adev->irq[0], ldata);
        rtc_device_unregister(ldata->rtc);
        iounmap(ldata->base);
        kfree(ldata);
index 4e8a1794f50a893120c028bf915616216697ada6..aefe820a8005585934f9d80b2d62a69b44555b29 100644 (file)
@@ -72,10 +72,10 @@ source "drivers/staging/sep/Kconfig"
 
 source "drivers/staging/iio/Kconfig"
 
-source "drivers/staging/zram/Kconfig"
-
 source "drivers/staging/zsmalloc/Kconfig"
 
+source "drivers/staging/zram/Kconfig"
+
 source "drivers/staging/wlags49_h2/Kconfig"
 
 source "drivers/staging/wlags49_h25/Kconfig"
index b040200a5a5502d7a110e9064d25b10600196065..9bd874789ce5fc93906a78f62a68e542541bd288 100644 (file)
@@ -242,7 +242,7 @@ static ssize_t do_read_log_to_user(struct logger_log *log,
  * 'log->buffer' which contains the first entry readable by 'euid'
  */
 static size_t get_next_entry_by_uid(struct logger_log *log,
-               size_t off, uid_t euid)
+               size_t off, kuid_t euid)
 {
        while (off != log->w_off) {
                struct logger_entry *entry;
@@ -251,7 +251,7 @@ static size_t get_next_entry_by_uid(struct logger_log *log,
 
                entry = get_entry_header(log, off, &scratch);
 
-               if (entry->euid == euid)
+               if (uid_eq(entry->euid, euid))
                        return off;
 
                next_len = sizeof(struct logger_entry) + entry->len;
index cc6bbd99c8e0326838246557f104d90fd11f9998..70af7d805dff191d744987f30e3b4b4093f3363e 100644 (file)
@@ -66,7 +66,7 @@ struct logger_entry {
        __s32           tid;
        __s32           sec;
        __s32           nsec;
-       uid_t           euid;
+       kuid_t          euid;
        char            msg[0];
 };
 
index 7871579bb83d8177d2ea262c38110446389fe923..87e852a0ef49140a24f72ba37cb051ad793c89d4 100644 (file)
@@ -981,6 +981,7 @@ config COMEDI_ME_DAQ
 
 config COMEDI_NI_6527
        tristate "NI 6527 support"
+       depends on HAS_DMA
        select COMEDI_MITE
        ---help---
          Enable support for the National Instruments 6527 PCI card
@@ -990,6 +991,7 @@ config COMEDI_NI_6527
 
 config COMEDI_NI_65XX
        tristate "NI 65xx static dio PCI card support"
+       depends on HAS_DMA
        select COMEDI_MITE
        ---help---
          Enable support for National Instruments 65xx static dio boards.
@@ -1003,6 +1005,7 @@ config COMEDI_NI_65XX
 
 config COMEDI_NI_660X
        tristate "NI 660x counter/timer PCI card support"
+       depends on HAS_DMA
        select COMEDI_NI_TIOCMD
        ---help---
          Enable support for National Instruments PCI-6601 (ni_660x), PCI-6602,
@@ -1013,6 +1016,7 @@ config COMEDI_NI_660X
 
 config COMEDI_NI_670X
        tristate "NI 670x PCI card support"
+       depends on HAS_DMA
        select COMEDI_MITE
        ---help---
          Enable support for National Instruments PCI-6703 and PCI-6704
@@ -1022,6 +1026,7 @@ config COMEDI_NI_670X
 
 config COMEDI_NI_LABPC_PCI
        tristate "NI Lab-PC PCI-1200 support"
+       depends on HAS_DMA
        select COMEDI_NI_LABPC
        select COMEDI_MITE
        ---help---
@@ -1032,6 +1037,7 @@ config COMEDI_NI_LABPC_PCI
 
 config COMEDI_NI_PCIDIO
        tristate "NI PCI-DIO32HS, PCI-6533, PCI-6534 support"
+       depends on HAS_DMA
        select COMEDI_MITE
        select COMEDI_8255
        ---help---
@@ -1043,6 +1049,7 @@ config COMEDI_NI_PCIDIO
 
 config COMEDI_NI_PCIMIO
        tristate "NI PCI-MIO-E series and M series support"
+       depends on HAS_DMA
        select COMEDI_NI_TIOCMD
        select COMEDI_8255
        select COMEDI_FC
@@ -1095,10 +1102,12 @@ config COMEDI_SSV_DNP
          called ssv_dnp.
 
 config COMEDI_MITE
+       depends on HAS_DMA
        tristate
 
 config COMEDI_NI_TIOCMD
        tristate
+       depends on HAS_DMA
        select COMEDI_NI_TIO
        select COMEDI_MITE
 
index ca709901fb3e841c27c9fc2a69133d3975cfece1..d4be0e68509b7f6a0b54d6bf7c412105349acdc6 100644 (file)
@@ -51,10 +51,12 @@ static void __comedi_buf_free(struct comedi_device *dev,
                        clear_bit(PG_reserved,
                                  &(virt_to_page(buf->virt_addr)->flags));
                        if (s->async_dma_dir != DMA_NONE) {
+#ifdef CONFIG_HAS_DMA
                                dma_free_coherent(dev->hw_dev,
                                                  PAGE_SIZE,
                                                  buf->virt_addr,
                                                  buf->dma_addr);
+#endif
                        } else {
                                free_page((unsigned long)buf->virt_addr);
                        }
@@ -74,6 +76,12 @@ static void __comedi_buf_alloc(struct comedi_device *dev,
        struct comedi_buf_page *buf;
        unsigned i;
 
+       if (!IS_ENABLED(CONFIG_HAS_DMA) && s->async_dma_dir != DMA_NONE) {
+               dev_err(dev->class_dev,
+                       "dma buffer allocation not supported\n");
+               return;
+       }
+
        async->buf_page_list = vzalloc(sizeof(*buf) * n_pages);
        if (async->buf_page_list)
                pages = vmalloc(sizeof(struct page *) * n_pages);
@@ -84,11 +92,15 @@ static void __comedi_buf_alloc(struct comedi_device *dev,
        for (i = 0; i < n_pages; i++) {
                buf = &async->buf_page_list[i];
                if (s->async_dma_dir != DMA_NONE)
+#ifdef CONFIG_HAS_DMA
                        buf->virt_addr = dma_alloc_coherent(dev->hw_dev,
                                                            PAGE_SIZE,
                                                            &buf->dma_addr,
                                                            GFP_KERNEL |
                                                            __GFP_COMP);
+#else
+                       break;
+#endif
                else
                        buf->virt_addr = (void *)get_zeroed_page(GFP_KERNEL);
                if (!buf->virt_addr)
index 00f2547024ec6b1a2d2abf6abf52dbcc1697dbc8..924c54c9c31fad595d1cdf9331db17d8c40413f4 100644 (file)
@@ -246,9 +246,6 @@ static int resize_async_buffer(struct comedi_device *dev,
                return -EBUSY;
        }
 
-       if (!async->prealloc_buf)
-               return -EINVAL;
-
        /* make sure buffer is an integral number of pages
         * (we round up) */
        new_size = (new_size + PAGE_SIZE - 1) & PAGE_MASK;
index 3d978f34d212b4c9f925ad928496403f8039c40f..77a7bb63258034ae0dd2b88bd692a0b6da9fe317 100644 (file)
@@ -976,8 +976,7 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
                /* clear flip-flop to make sure 2-byte registers for
                 * count and address get set correctly */
                clear_dma_ff(devpriv->dma_chan);
-               set_dma_addr(devpriv->dma_chan,
-                            virt_to_bus(devpriv->dma_buffer));
+               set_dma_addr(devpriv->dma_chan, devpriv->dma_addr);
                /*  set appropriate size of transfer */
                devpriv->dma_transfer_size = labpc_suggest_transfer_size(cmd);
                if (cmd->stop_src == TRIG_COUNT &&
@@ -1089,7 +1088,7 @@ static void labpc_drain_dma(struct comedi_device *dev)
                devpriv->count -= num_points;
 
        /*  set address and count for next transfer */
-       set_dma_addr(devpriv->dma_chan, virt_to_bus(devpriv->dma_buffer));
+       set_dma_addr(devpriv->dma_chan, devpriv->dma_addr);
        set_dma_count(devpriv->dma_chan, leftover * sample_size);
        release_dma_lock(flags);
 
@@ -1741,6 +1740,9 @@ static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it)
                                unsigned long dma_flags;
 
                                devpriv->dma_chan = dma_chan;
+                               devpriv->dma_addr =
+                                       virt_to_bus(devpriv->dma_buffer);
+
                                dma_flags = claim_dma_lock();
                                disable_dma(devpriv->dma_chan);
                                set_dma_mode(devpriv->dma_chan, DMA_MODE_READ);
index 615f16f271c0a8078a1a6a22339393ffdeddf2ed..4b691f5a9965098cd6edebb5be04d940ea65af19 100644 (file)
@@ -82,6 +82,7 @@ struct labpc_private {
        unsigned int divisor_b1;
        unsigned int dma_chan;  /*  dma channel to use */
        u16 *dma_buffer;        /*  buffer ai will dma into */
+       phys_addr_t dma_addr;
        /* transfer size in bytes for current transfer */
        unsigned int dma_transfer_size;
        /* we are using dma/fifo-half-full/etc. */
index a46d579016d9571eef12db6bff2e95beea47e4d2..8c5dee9b3b05188c85110ee171fb179d354bd858 100644 (file)
@@ -310,9 +310,11 @@ static int ni_gpct_insn_read(struct comedi_device *dev,
 static int ni_gpct_insn_config(struct comedi_device *dev,
                               struct comedi_subdevice *s,
                               struct comedi_insn *insn, unsigned int *data);
+#ifdef PCIDMA
 static int ni_gpct_cmd(struct comedi_device *dev, struct comedi_subdevice *s);
 static int ni_gpct_cmdtest(struct comedi_device *dev,
                           struct comedi_subdevice *s, struct comedi_cmd *cmd);
+#endif
 static int ni_gpct_cancel(struct comedi_device *dev,
                          struct comedi_subdevice *s);
 static void handle_gpct_interrupt(struct comedi_device *dev,
@@ -4617,9 +4619,7 @@ static int ni_E_init(struct comedi_device *dev)
        for (j = 0; j < NUM_GPCT; ++j) {
                s = &dev->subdevices[NI_GPCT_SUBDEV(j)];
                s->type = COMEDI_SUBD_COUNTER;
-               s->subdev_flags =
-                   SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL | SDF_CMD_READ
-                   /* | SDF_CMD_WRITE */ ;
+               s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL;
                s->n_chan = 3;
                if (board->reg_type & ni_reg_m_series_mask)
                        s->maxdata = 0xffffffff;
@@ -4628,11 +4628,14 @@ static int ni_E_init(struct comedi_device *dev)
                s->insn_read = &ni_gpct_insn_read;
                s->insn_write = &ni_gpct_insn_write;
                s->insn_config = &ni_gpct_insn_config;
+#ifdef PCIDMA
+               s->subdev_flags |= SDF_CMD_READ /* | SDF_CMD_WRITE */;
                s->do_cmd = &ni_gpct_cmd;
                s->len_chanlist = 1;
                s->do_cmdtest = &ni_gpct_cmdtest;
                s->cancel = &ni_gpct_cancel;
                s->async_dma_dir = DMA_BIDIRECTIONAL;
+#endif
                s->private = &devpriv->counter_dev->counters[j];
 
                devpriv->counter_dev->counters[j].chip_index = 0;
@@ -5216,10 +5219,10 @@ static int ni_gpct_insn_write(struct comedi_device *dev,
        return ni_tio_winsn(counter, insn, data);
 }
 
+#ifdef PCIDMA
 static int ni_gpct_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 {
        int retval;
-#ifdef PCIDMA
        struct ni_gpct *counter = s->private;
 /* const struct comedi_cmd *cmd = &s->async->cmd; */
 
@@ -5233,23 +5236,20 @@ static int ni_gpct_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
        ni_tio_acknowledge_and_confirm(counter, NULL, NULL, NULL, NULL);
        ni_e_series_enable_second_irq(dev, counter->counter_index, 1);
        retval = ni_tio_cmd(counter, s->async);
-#else
-       retval = -ENOTSUPP;
-#endif
        return retval;
 }
+#endif
 
+#ifdef PCIDMA
 static int ni_gpct_cmdtest(struct comedi_device *dev,
                           struct comedi_subdevice *s, struct comedi_cmd *cmd)
 {
-#ifdef PCIDMA
        struct ni_gpct *counter = s->private;
 
        return ni_tio_cmdtest(counter, cmd);
-#else
        return -ENOTSUPP;
-#endif
 }
+#endif
 
 static int ni_gpct_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
 {
index f0b4739c65a17eeff63facaf8158cfedbe0ba025..d15d9d58e5ac2a3022c92e9843f7de7b64685f1f 100644 (file)
@@ -2,7 +2,6 @@ config USB_DWC2
        tristate "DesignWare USB2 DRD Core Support"
        depends on USB
        depends on VIRT_TO_BUS
-       select USB_OTG_UTILS
        help
          Say Y or M here if your system has a Dual Role HighSpeed
          USB controller based on the DesignWare HSOTG IP Core.
@@ -39,6 +38,7 @@ config USB_DWC2_TRACK_MISSED_SOFS
        bool "Enable Missed SOF Tracking"
        help
          Say Y here to enable logging of missed SOF events to the dmesg log.
+         WARNING: This feature is still experimental.
          If in doubt, say N.
 
 config USB_DWC2_DEBUG_PERIODIC
index 6e5dbed6ccec06d8427b995f88bad428d6fcdf15..e24062f0a49ebd87ec2d30b06f914309d21173c0 100644 (file)
@@ -56,8 +56,6 @@
 static void dwc2_track_missed_sofs(struct dwc2_hsotg *hsotg)
 {
 #ifdef CONFIG_USB_DWC2_TRACK_MISSED_SOFS
-#warning Compiling code to track missed SOFs
-
        u16 curr_frame_number = hsotg->frame_number;
 
        if (hsotg->frame_num_idx < FRAME_NUM_ARRAY_SIZE) {
index b610960e93d3fd10f1a6a34d56fa7bea83e52711..44cce2fa6361194a36ac72dff5825575fd324bf5 100644 (file)
@@ -95,6 +95,14 @@ static int dwc2_driver_probe(struct platform_device *dev)
 
        hsotg->dev = &dev->dev;
 
+       /*
+        * Use reasonable defaults so platforms don't have to provide these.
+        */
+       if (!dev->dev.dma_mask)
+               dev->dev.dma_mask = &dev->dev.coherent_dma_mask;
+       if (!dev->dev.coherent_dma_mask)
+               dev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
+
        irq = platform_get_irq(dev, 0);
        if (irq < 0) {
                dev_err(&dev->dev, "missing IRQ resource\n");
index 3c18efe3136575ab20559923881ad44da9bd0835..69059138de4ab334b96f44b63599be2ddceed7e9 100644 (file)
@@ -39,7 +39,7 @@ if WIMAX_GDM72XX_USB
 
 config WIMAX_GDM72XX_USB_PM
        bool "Enable power managerment support"
-       depends on USB_SUSPEND
+       depends on PM_RUNTIME
 
 endif # WIMAX_GDM72XX_USB
 
index 2856b8fd44adf808f8ca871f1960f7dec2272b93..163c638e4095f3b893668bb5d83e8e2110b76afb 100644 (file)
@@ -690,7 +690,6 @@ static void mxs_lradc_trigger_remove(struct iio_dev *iio)
 static int mxs_lradc_buffer_preenable(struct iio_dev *iio)
 {
        struct mxs_lradc *lradc = iio_priv(iio);
-       struct iio_buffer *buffer = iio->buffer;
        int ret = 0, chan, ofs = 0;
        unsigned long enable = 0;
        uint32_t ctrl4_set = 0;
@@ -698,7 +697,7 @@ static int mxs_lradc_buffer_preenable(struct iio_dev *iio)
        uint32_t ctrl1_irq = 0;
        const uint32_t chan_value = LRADC_CH_ACCUMULATE |
                ((LRADC_DELAY_TIMER_LOOP - 1) << LRADC_CH_NUM_SAMPLES_OFFSET);
-       const int len = bitmap_weight(buffer->scan_mask, LRADC_MAX_TOTAL_CHANS);
+       const int len = bitmap_weight(iio->active_scan_mask, LRADC_MAX_TOTAL_CHANS);
 
        if (!len)
                return -EINVAL;
@@ -725,7 +724,7 @@ static int mxs_lradc_buffer_preenable(struct iio_dev *iio)
                lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR);
        writel(0xff, lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_CLR);
 
-       for_each_set_bit(chan, buffer->scan_mask, LRADC_MAX_TOTAL_CHANS) {
+       for_each_set_bit(chan, iio->active_scan_mask, LRADC_MAX_TOTAL_CHANS) {
                ctrl4_set |= chan << LRADC_CTRL4_LRADCSELECT_OFFSET(ofs);
                ctrl4_clr |= LRADC_CTRL4_LRADCSELECT_MASK(ofs);
                ctrl1_irq |= LRADC_CTRL1_LRADC_IRQ_EN(ofs);
index d060f2572512af496f094036cfbc9460a19850d3..c99f890cc6c65ae9ea13a9aafa8c8258e21e3cb8 100644 (file)
@@ -1869,6 +1869,7 @@ static int tsl2x7x_probe(struct i2c_client *clientp,
                dev_info(&chip->client->dev,
                                "%s: i2c device found does not match expected id\n",
                                __func__);
+               ret = -EINVAL;
                goto fail1;
        }
 
@@ -1907,7 +1908,7 @@ static int tsl2x7x_probe(struct i2c_client *clientp,
                if (ret) {
                        dev_err(&clientp->dev,
                                "%s: irq request failed", __func__);
-                       goto fail2;
+                       goto fail1;
                }
        }
 
@@ -1920,17 +1921,17 @@ static int tsl2x7x_probe(struct i2c_client *clientp,
        if (ret) {
                dev_err(&clientp->dev,
                        "%s: iio registration failed\n", __func__);
-               goto fail1;
+               goto fail2;
        }
 
        dev_info(&clientp->dev, "%s Light sensor found.\n", id->name);
 
        return 0;
 
-fail1:
+fail2:
        if (clientp->irq)
                free_irq(clientp->irq, indio_dev);
-fail2:
+fail1:
        iio_device_free(indio_dev);
 
        return ret;
index 8c9e40390f42fae3b0f52d3d989d79891d2778f1..ef699f75318636db921fd693ee798d6bedffc7dc 100644 (file)
@@ -1,6 +1,7 @@
 config DRM_IMX
        tristate "DRM Support for Freescale i.MX"
        select DRM_KMS_HELPER
+       select VIDEOMODE_HELPERS
        select DRM_GEM_CMA_HELPER
        select DRM_KMS_CMA_HELPER
        depends on DRM && (ARCH_MXC || ARCH_MULTIPLATFORM)
@@ -19,10 +20,12 @@ config DRM_IMX_FB_HELPER
 config DRM_IMX_PARALLEL_DISPLAY
        tristate "Support for parallel displays"
        depends on DRM_IMX
+       select VIDEOMODE_HELPERS
 
 config DRM_IMX_TVE
        tristate "Support for TV and VGA displays"
        depends on DRM_IMX
+       select REGMAP_MMIO
        help
          Choose this to enable the internal Television Encoder (TVe)
          found on i.MX53 processors.
@@ -30,6 +33,7 @@ config DRM_IMX_TVE
 config DRM_IMX_IPUV3_CORE
        tristate "IPUv3 core support"
        depends on DRM_IMX
+       depends on RESET_CONTROLLER
        help
          Choose this if you have a i.MX5/6 system and want
          to use the IPU. This option only enables IPU base
@@ -38,5 +42,6 @@ config DRM_IMX_IPUV3_CORE
 config DRM_IMX_IPUV3
        tristate "DRM Support for i.MX IPUv3"
        depends on DRM_IMX
+       depends on DRM_IMX_IPUV3_CORE
        help
          Choose this if you have a i.MX5 or i.MX6 processor.
index ac16344644073340cdce7f350134791e58136f62..03892de9bd7e1103665c2144212722436b97b8be 100644 (file)
@@ -670,7 +670,9 @@ static int imx_tve_probe(struct platform_device *pdev)
        tve->dac_reg = devm_regulator_get(&pdev->dev, "dac");
        if (!IS_ERR(tve->dac_reg)) {
                regulator_set_voltage(tve->dac_reg, 2750000, 2750000);
-               regulator_enable(tve->dac_reg);
+               ret = regulator_enable(tve->dac_reg);
+               if (ret)
+                       return ret;
        }
 
        tve->clk = devm_clk_get(&pdev->dev, "tve");
index ec32776ff5475310c37074c8ed2e5cf5cabd3d06..df6569b997b88269bfdb48fd17dc410a0da50c0a 100644 (file)
@@ -1,6 +1,7 @@
 config SOLO6X10
        tristate "Softlogic 6x10 MPEG codec cards"
        depends on PCI && VIDEO_DEV && SND && I2C
+       depends on FONTS
        select VIDEOBUF2_DMA_SG
        select VIDEOBUF2_DMA_CONTIG
        select SND_PCM
index 863b22e51b45f87bc074b4b5920ab25fa0ef1d38..197c393c4ca752a9f50062e2852afd2bb8be89a3 100644 (file)
@@ -123,6 +123,20 @@ int nvec_register_notifier(struct nvec_chip *nvec, struct notifier_block *nb,
 }
 EXPORT_SYMBOL_GPL(nvec_register_notifier);
 
+/**
+ * nvec_unregister_notifier - Unregister a notifier with nvec
+ * @nvec: A &struct nvec_chip
+ * @nb: The notifier block to unregister
+ *
+ * Unregisters a notifier with @nvec. The notifier will be removed from the
+ * atomic notifier chain.
+ */
+int nvec_unregister_notifier(struct nvec_chip *nvec, struct notifier_block *nb)
+{
+       return atomic_notifier_chain_unregister(&nvec->notifier_list, nb);
+}
+EXPORT_SYMBOL_GPL(nvec_unregister_notifier);
+
 /**
  * nvec_status_notifier - The final notifier
  *
@@ -185,7 +199,7 @@ static struct nvec_msg *nvec_msg_alloc(struct nvec_chip *nvec,
  *
  * Free the given message
  */
-inline void nvec_msg_free(struct nvec_chip *nvec, struct nvec_msg *msg)
+void nvec_msg_free(struct nvec_chip *nvec, struct nvec_msg *msg)
 {
        if (msg != &nvec->tx_scratch)
                dev_vdbg(nvec->dev, "INFO: Free %ti\n", msg - nvec->msg_pool);
@@ -810,7 +824,7 @@ static int tegra_nvec_probe(struct platform_device *pdev)
                return -ENODEV;
        }
 
-       i2c_clk = clk_get(&pdev->dev, "div-clk");
+       i2c_clk = devm_clk_get(&pdev->dev, "div-clk");
        if (IS_ERR(i2c_clk)) {
                dev_err(nvec->dev, "failed to get controller clock\n");
                return -ENODEV;
@@ -897,8 +911,11 @@ static int tegra_nvec_remove(struct platform_device *pdev)
 
        nvec_toggle_global_events(nvec, false);
        mfd_remove_devices(nvec->dev);
+       nvec_unregister_notifier(nvec, &nvec->nvec_status_notifier);
        cancel_work_sync(&nvec->rx_work);
        cancel_work_sync(&nvec->tx_work);
+       /* FIXME: needs check wether nvec is responsible for power off */
+       pm_power_off = NULL;
 
        return 0;
 }
index b7a14bc0ab9153319b58bad6f30f7e538d3fc775..2b1316d87470eaa9f3c84b775854bc56d10da3ab 100644 (file)
@@ -197,9 +197,8 @@ extern int nvec_register_notifier(struct nvec_chip *nvec,
                                  struct notifier_block *nb,
                                  unsigned int events);
 
-extern int nvec_unregister_notifier(struct device *dev,
-                                   struct notifier_block *nb,
-                                   unsigned int events);
+extern int nvec_unregister_notifier(struct nvec_chip *dev,
+                                   struct notifier_block *nb);
 
 extern void nvec_msg_free(struct nvec_chip *nvec, struct nvec_msg *msg);
 
index 7445ce6422bbc9e868b0274c3dd65bce4b3b4a08..a0ec52a4114f277938ba274b9e4cfe8632a749d7 100644 (file)
@@ -169,8 +169,15 @@ fail:
 
 static int nvec_kbd_remove(struct platform_device *pdev)
 {
+       struct nvec_chip *nvec = dev_get_drvdata(pdev->dev.parent);
+       char disable_kbd[] = { NVEC_KBD, DISABLE_KBD },
+            uncnfg_wake_key_reporting[] = { NVEC_KBD, CNFG_WAKE_KEY_REPORTING,
+                                               false };
+       nvec_write_async(nvec, uncnfg_wake_key_reporting, 3);
+       nvec_write_async(nvec, disable_kbd, 2);
+       nvec_unregister_notifier(nvec, &keys_dev.notifier);
+
        input_unregister_device(keys_dev.input);
-       input_free_device(keys_dev.input);
 
        return 0;
 }
@@ -188,4 +195,5 @@ module_platform_driver(nvec_kbd_driver);
 
 MODULE_AUTHOR("Marc Dietrich <marvin24@gmx.de>");
 MODULE_DESCRIPTION("NVEC keyboard driver");
+MODULE_ALIAS("platform:nvec-kbd");
 MODULE_LICENSE("GPL");
index 296f7b9a8c8c11f32d8eb35612bd75a1cabe1b4b..aacfcd6954a371ab23e47491230818a644b7e772 100644 (file)
@@ -414,6 +414,7 @@ static int nvec_power_remove(struct platform_device *pdev)
        struct nvec_power *power = platform_get_drvdata(pdev);
 
        cancel_delayed_work_sync(&power->poller);
+       nvec_unregister_notifier(power->nvec, &power->notifier);
        switch (pdev->id) {
        case AC:
                power_supply_unregister(&nvec_psy);
index aff6b9b9f9aa76b4c460ad6e5fe410e56f72f09d..06dbb02085a936c52ee97bec1787da0ec92179d4 100644 (file)
@@ -106,7 +106,7 @@ static int nvec_mouse_probe(struct platform_device *pdev)
        struct serio *ser_dev;
        char mouse_reset[] = { NVEC_PS2, SEND_COMMAND, PSMOUSE_RST, 3 };
 
-       ser_dev = devm_kzalloc(&pdev->dev, sizeof(struct serio), GFP_KERNEL);
+       ser_dev = kzalloc(sizeof(struct serio), GFP_KERNEL);
        if (ser_dev == NULL)
                return -ENOMEM;
 
@@ -133,6 +133,11 @@ static int nvec_mouse_probe(struct platform_device *pdev)
 
 static int nvec_mouse_remove(struct platform_device *pdev)
 {
+       struct nvec_chip *nvec = dev_get_drvdata(pdev->dev.parent);
+
+       ps2_sendcommand(ps2_dev.ser_dev, DISABLE_MOUSE);
+       ps2_stopstreaming(ps2_dev.ser_dev);
+       nvec_unregister_notifier(nvec, &ps2_dev.notifier);
        serio_unregister_port(ps2_dev.ser_dev);
 
        return 0;
@@ -179,4 +184,5 @@ module_platform_driver(nvec_mouse_driver);
 
 MODULE_DESCRIPTION("NVEC mouse driver");
 MODULE_AUTHOR("Marc Dietrich <marvin24@gmx.de>");
+MODULE_ALIAS("platform:nvec-mouse");
 MODULE_LICENSE("GPL");
index 185b676d858ad627a737619417a04ba0dd08191f..aab945a316ea47753d82130bb4043d9f7df7b255 100644 (file)
@@ -1,6 +1,6 @@
 config DX_SEP
        tristate "Discretix SEP driver"
-       depends on PCI
+       depends on PCI && CRYPTO
        help
          Discretix SEP driver; used for the security processor subsystem
          on board the Intel Mobile Internet Device and adds SEP availability
index fe667dde43ce4b0180c0f6cbfcb526debfaed719..386362c9964ff1e8856adcaa14fa000aa82686f5 100644 (file)
@@ -1087,7 +1087,11 @@ static int synaptics_rmi4_resume(struct device *dev)
        unsigned char intr_status;
        struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev);
 
-       regulator_enable(rmi4_data->regulator);
+       retval = regulator_enable(rmi4_data->regulator);
+       if (retval) {
+               dev_err(dev, "Regulator enable failed (%d)\n", retval);
+               return retval;
+       }
 
        enable_irq(rmi4_data->i2c_client->irq);
        rmi4_data->touch_stopped = false;
index f4f1bf7a30fdff871cedd0cceaeb95b2cd8c24c7..c699a3058b39920a34daf1a6f63524be990e29cb 100644 (file)
@@ -133,7 +133,7 @@ static int hostap_disable_hostapd(struct vnt_private *pDevice, int rtnl_locked)
             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Netdevice %s unregistered\n",
                       pDevice->dev->name, pDevice->apdev->name);
        }
-       kfree(pDevice->apdev);
+       free_netdev(pDevice->apdev);
        pDevice->apdev = NULL;
     pDevice->bEnable8021x = false;
     pDevice->bEnableHostWEP = false;
index c335808211ee54b929441028e738797d457ead86..d0cf7d8a20e5640fe507f3ff1b1dc64c170f9408 100644 (file)
@@ -1345,9 +1345,12 @@ int iwctl_siwpower(struct net_device *dev, struct iw_request_info *info,
                return rc;
        }
 
+       spin_lock_irq(&pDevice->lock);
+
        if (wrq->disabled) {
                pDevice->ePSMode = WMAC_POWER_CAM;
                PSvDisablePowerSaving(pDevice);
+               spin_unlock_irq(&pDevice->lock);
                return rc;
        }
        if ((wrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
@@ -1358,6 +1361,9 @@ int iwctl_siwpower(struct net_device *dev, struct iw_request_info *info,
                pDevice->ePSMode = WMAC_POWER_FAST;
                PSvEnablePowerSaving((void *)pDevice, pMgmt->wListenInterval);
        }
+
+       spin_unlock_irq(&pDevice->lock);
+
        switch (wrq->flags & IW_POWER_MODE) {
        case IW_POWER_UNICAST_R:
                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_UNICAST_R \n");
diff --git a/drivers/staging/zcache/ramster/ramster-howto.txt b/drivers/staging/zcache/ramster/ramster-howto.txt
new file mode 100644 (file)
index 0000000..7b1ee3b
--- /dev/null
@@ -0,0 +1,366 @@
+                       RAMSTER HOW-TO
+
+Author: Dan Magenheimer
+Ramster maintainer: Konrad Wilk <konrad.wilk@oracle.com>
+
+This is a HOWTO document for ramster which, as of this writing, is in
+the kernel as a subdirectory of zcache in drivers/staging, called ramster.
+(Zcache can be built with or without ramster functionality.)  If enabled
+and properly configured, ramster allows memory capacity load balancing
+across multiple machines in a cluster.  Further, the ramster code serves
+as an example of asynchronous access for zcache (as well as cleancache and
+frontswap) that may prove useful for future transcendent memory
+implementations, such as KVM and NVRAM.  While ramster works today on
+any network connection that supports kernel sockets, its features may
+become more interesting on future high-speed fabrics/interconnects.
+
+Ramster requires both kernel and userland support.  The userland support,
+called ramster-tools, is known to work with EL6-based distros, but is a
+set of poorly-hacked slightly-modified cluster tools based on ocfs2, which
+includes an init file, a config file, and a userland binary that interfaces
+to the kernel.  This state of userland support reflects the abysmal userland
+skills of this suitably-embarrassed author; any help/patches to turn
+ramster-tools into more distributable rpms/debs useful for a wider range
+of distros would be appreciated.  The source RPM that can be used as a
+starting point is available at:
+    http://oss.oracle.com/projects/tmem/files/RAMster/ 
+
+As a result of this author's ignorance, userland setup described in this
+HOWTO assumes an EL6 distro and is described in EL6 syntax.  Apologies
+if this offends anyone!
+
+Kernel support has only been tested on x86_64.  Systems with an active
+ocfs2 filesystem should work, but since ramster leverages a lot of
+code from ocfs2, there may be latent issues.  A kernel configuration that
+includes CONFIG_OCFS2_FS should build OK, and should certainly run OK
+if no ocfs2 filesystem is mounted.
+
+This HOWTO demonstrates memory capacity load balancing for a two-node
+cluster, where one node called the "local" node becomes overcommitted
+and the other node called the "remote" node provides additional RAM
+capacity for use by the local node.  Ramster is capable of more complex
+topologies; see the last section titled "ADVANCED RAMSTER TOPOLOGIES".
+
+If you find any terms in this HOWTO unfamiliar or don't understand the
+motivation for ramster, the following LWN reading is recommended:
+-- Transcendent Memory in a Nutshell (lwn.net/Articles/454795)
+-- The future calculus of memory management (lwn.net/Articles/475681)
+And since ramster is built on top of zcache, this article may be helpful:
+-- In-kernel memory compression (lwn.net/Articles/545244)
+
+Now that you've memorized the contents of those articles, let's get started!
+
+A. PRELIMINARY
+
+1) Install two x86_64 Linux systems that are known to work when
+   upgraded to a recent upstream Linux kernel version.
+
+On each system:
+
+2) Configure, build and install, then boot Linux, just to ensure it
+   can be done with an unmodified upstream kernel.  Confirm you booted
+   the upstream kernel with "uname -a".
+
+3) If you plan to do any performance testing or unless you plan to
+   test only swapping, the "WasActive" patch is also highly recommended.
+   (Search lkml.org for WasActive, apply the patch, rebuild your kernel.)
+   For a demo or simple testing, the patch can be ignored.
+
+4) Install ramster-tools as root.  An x86_64 rpm for EL6-based systems
+   can be found at:
+    http://oss.oracle.com/projects/tmem/files/RAMster/ 
+   (Sorry but for now, non-EL6 users must recreate ramster-tools on
+   their own from source.  See above.)
+
+5) Ensure that debugfs is mounted at each boot.  Examples below assume it
+   is mounted at /sys/kernel/debug.
+
+B. BUILDING RAMSTER INTO THE KERNEL
+
+Do the following on each system:
+
+1) Using the kernel configuration mechanism of your choice, change
+   your config to include:
+
+       CONFIG_CLEANCACHE=y
+       CONFIG_FRONTSWAP=y
+       CONFIG_STAGING=y
+       CONFIG_CONFIGFS_FS=y # NOTE: MUST BE y, not m
+       CONFIG_ZCACHE=y
+       CONFIG_RAMSTER=y
+
+   For a linux-3.10 or later kernel, you should also set:
+
+       CONFIG_ZCACHE_DEBUG=y
+       CONFIG_RAMSTER_DEBUG=y
+
+   Before building the kernel please doublecheck your kernel config
+   file to ensure all of the settings are correct.
+
+2) Build this kernel and change your boot file (e.g. /etc/grub.conf)
+   so that the new kernel will boot.
+
+3) Add "zcache" and "ramster" as kernel boot parameters for the new kernel.
+
+4) Reboot each system approximately simultaneously.
+
+5) Check dmesg to ensure there are some messages from ramster, prefixed
+   by "ramster:"
+
+       # dmesg | grep ramster
+
+   You should also see a lot of files in:
+
+       # ls /sys/kernel/debug/zcache
+       # ls /sys/kernel/debug/ramster
+
+   These are mostly counters for various zcache and ramster activities.
+   You should also see files in:
+
+       # ls /sys/kernel/mm/ramster
+
+   These are sysfs files that control ramster as we shall see.
+
+   Ramster now will act as a single-system zcache on each system
+   but doesn't yet know anything about the cluster so can't yet do
+   anything remotely.
+
+C. CONFIGURING THE RAMSTER CLUSTER
+
+This part can be error prone unless you are familiar with clustering
+filesystems.  We need to describe the cluster in a /etc/ramster.conf
+file and the init scripts that parse it are extremely picky about
+the syntax.
+
+1) Create a /etc/ramster.conf file and ensure it is identical on both
+   systems.  This file mimics the ocfs2 format and there is a good amount
+   of documentation that can be searched for ocfs2.conf, but you can use:
+
+       cluster:
+               name = ramster
+               node_count = 2
+       node:
+               name = system1
+               cluster = ramster
+               number = 0
+               ip_address = my.ip.ad.r1
+               ip_port = 7777
+       node:
+               name = system2
+               cluster = ramster
+               number = 1
+               ip_address = my.ip.ad.r2
+               ip_port = 7777
+
+   You must ensure that the "name" field in the file exactly matches
+   the output of "hostname" on each system; if "hostname" shows a
+   fully-qualified hostname, ensure the name is fully qualified in
+   /etc/ramster.conf.  Obviously, substitute my.ip.ad.rx with proper
+   ip addresses.
+
+2) Enable the ramster service and configure it.  If you used the
+   EL6 ramster-tools, this would be:
+
+       # chkconfig --add ramster
+       # service ramster configure
+
+   Set "load on boot" to "y", cluster to start is "ramster" (or whatever
+   name you chose in ramster.conf), heartbeat dead threshold as "500",
+   network idle timeout as "1000000".  Leave the others as default.
+
+3) Reboot both systems.  After reboot, try (assuming EL6 ramster-tools):
+
+       # service ramster status
+
+   You should see "Checking RAMSTER cluster "ramster": Online".  If you do
+   not, something is wrong and ramster will not work.  Note that you
+   should also see that the driver for "configfs" is loaded and mounted,
+   the driver for ocfs2_dlmfs is not loaded, and some numbers for network
+   parameters.  You will also see "Checking RAMSTER heartbeat: Not active".
+   That's all OK.
+
+4) Now you need to start the cluster heartbeat; the cluster is not "up"
+   until all nodes detect a heartbeat.  In a real cluster, heartbeat detection
+   is done via a cluster filesystem, but ramster doesn't require one.  Some
+   hack-y kernel code in ramster can start the heartbeat for you though if
+   you tell it what nodes are "up".  To enable the heartbeat, do:
+
+       # echo 0 > /sys/kernel/mm/ramster/manual_node_up
+       # echo 1 > /sys/kernel/mm/ramster/manual_node_up
+
+   This must be done on BOTH nodes and, to avoid timeouts, must be done
+   approximately concurrently on both nodes.  On an EL6 system, it is
+   convenient to put these lines in /etc/rc.local.  To confirm that the
+   cluster is now up, on both systems do:
+
+       # dmesg | grep ramster
+
+   You should see ramster "Accepted connection" messages in dmesg on both
+   nodes after this.  Note that if you check userland status again with
+
+       # service ramster status
+
+   you will still see "Checking RAMSTER heartbeat: Not active".  That's
+   still OK... the ramster kernel heartbeat hack doesn't communicate to
+   userland.
+
+5) You now must tell each node the node to which it should "remotify" pages.
+   On this two node cluster, we will assume the "local" node, node 0, has
+   memory overcommitted and will use ramster to utilize RAM capacity on
+   the "remote node", node 1.  To configure this, on node 0, you do:
+
+       # echo 1 > /sys/kernel/mm/ramster/remote_target_nodenum
+
+   You should see "ramster: node 1 set as remotification target" in dmesg
+   on node 0.  Again, on EL6, /etc/rc.local is a good place to put this
+   on node 0 so you don't forget to do it at each boot.
+
+6) One more step:  By default, the ramster code does not "remotify" any
+   pages; this is primarily for testing purposes, but sometimes it is
+   useful.  This may change in the future, but for now, on node 0, you do:
+
+       # echo 1 > /sys/kernel/mm/ramster/pers_remotify_enable
+       # echo 1 > /sys/kernel/mm/ramster/eph_remotify_enable
+
+   The first enables remotifying swap (persistent, aka frontswap) pages,
+   the second enables remotifying of page cache (ephemeral, cleancache)
+   pages.
+
+   On EL6, these lines can also be put in /etc/rc.local (AFTER the
+   node_up lines), or at the beginning of a script that runs a workload.
+
+7) Note that most testing has been done with both/all machines booted
+   roughly simultaneously to avoid cluster timeouts.  Ideally, you should
+   do this too unless you are trying to break ramster rather than just
+   use it. ;-)
+
+D. TESTING RAMSTER
+
+1) Note that ramster has no value unless pages get "remotified".  For
+   swap/frontswap/persistent pages, this doesn't happen unless/until
+   the workload would cause swapping to occur, at which point pages
+   are put into frontswap/zcache, and the remotification thread starts
+   working.  To get to the point where the system swaps, you either
+   need a workload for which the working set exceeds the RAM in the
+   system; or you need to somehow reduce the amount of RAM one of
+   the system sees.  This latter is easy when testing in a VM, but
+   harder on physical systems.  In some cases, "mem=xxxM" on the
+   kernel command line restricts memory, but for some values of xxx
+   the kernel may fail to boot.  One may also try creating a fixed
+   RAMdisk, doing nothing with it, but ensuring that it eats up a fixed
+   amount of RAM.
+
+2) To see if ramster is working, on the "remote node", node 1, try:
+
+       # grep . /sys/kernel/debug/ramster/foreign_*
+        # # note, that is space-dot-space between grep and the pathname
+
+   to monitor the number (and max) ephemeral and persistent pages
+   that ramster has sent.  If these stay at zero, ramster is not working
+   either because the workload on the local node (node 0) isn't creating
+   enough memory pressure or because "remotifying" isn't working.  On the
+   local system, node 0, you can watch lots of useful information also.
+   Try:
+
+       grep . /sys/kernel/debug/zcache/*pageframes* \
+               /sys/kernel/debug/zcache/*zbytes* \
+               /sys/kernel/debug/zcache/*zpages* \
+               /sys/kernel/debug/ramster/*remote*
+
+   Of particular note are the remote_*_pages_succ_get counters.  These
+   show how many disk reads and/or disk writes have been avoided on the
+   overcommitted local system by storing pages remotely using ramster.
+
+   At the risk of information overload, you can also grep:
+
+        /sys/kernel/debug/cleancache/* and /sys/kernel/debug/frontswap/*
+
+   These show, for example, how many disk reads and/or disk writes have
+   been avoided by using zcache to optimize RAM on the local system.
+
+
+AUTOMATIC SWAP REPATRIATION
+
+You may notice that while the systems are idle, the foreign persistent
+page count on the remote machine slowly decreases.  This is because
+ramster implements "frontswap selfshrinking":  When possible, swap
+pages that have been remotified are slowly repatriated to the local
+machine.  This is so that local RAM can be used when possible and
+so that, in case of remote machine crash, the probability of loss
+of data is reduced.
+
+REBOOTING / POWEROFF
+
+If a system is shut down while some of its swap pages still reside
+on a remote system, the system may lock up during the shutdown
+sequence.  This will occur if the network is shut down before the
+swap mechansim is shut down, which is the default ordering on many
+distros.  To avoid this annoying problem, simply shut off the swap
+subsystem before starting the shutdown sequence, e.g.:
+
+       # swapoff -a
+       # reboot
+
+Ideally, this swapoff-before-ifdown ordering should be enforced permanently
+using shutdown scripts.
+
+KNOWN PROBLEMS
+
+1) You may periodically see messages such as:
+
+    ramster_r2net, message length problem
+
+   This is harmless but indicates that a node is sending messages
+   containing compressed pages that exceed the maximum for zcache
+   (PAGE_SIZE*15/16).  The sender side needs to be fixed.
+
+2) If you see a "No longer connected to node..." message or a "No connection
+   established with node X after N seconds", it is possible you may
+   be in an unrecoverable state.  If you are certain all of the
+   appropriate cluster configuration steps described above have been
+   performed, try rebooting the two servers concurrently to see if
+   the cluster starts.
+
+   Note that "Connection to node... shutdown, state 7" is an intermediate
+   connection state.  As long as you later see "Accepted connection", the
+   intermediate states are harmless.
+
+3) There are known issues in counting certain values.  As a result
+   you may see periodic warnings from the kernel.  Almost always you
+   will see "ramster: bad accounting for XXX".  There are also "WARN_ONCE"
+   messages.  If you see kernel warnings with a tombstone, please report
+   them.  They are harmless but reflect bugs that need to be eventually fixed.
+
+ADVANCED RAMSTER TOPOLOGIES
+
+The kernel code for ramster can support up to eight nodes in a cluster,
+but no testing has been done with more than three nodes.
+
+In the example described above, the "remote" node serves as a RAM
+overflow for the "local" node.  This can be made symmetric by appropriate
+settings of the sysfs remote_target_nodenum file.  For example, by setting:
+
+       # echo 1 > /sys/kernel/mm/ramster/remote_target_nodenum
+
+on node 0, and
+
+       # echo 0 > /sys/kernel/mm/ramster/remote_target_nodenum
+
+on node 1, each node can serve as a RAM overflow for the other.
+
+For more than two nodes, a "RAM server" can be configured.  For a
+three node system, set:
+
+       # echo 0 > /sys/kernel/mm/ramster/remote_target_nodenum
+
+on node 1, and
+
+       # echo 0 > /sys/kernel/mm/ramster/remote_target_nodenum
+
+on node 2.  Then node 0 is a RAM server for node 1 and node 2.
+
+In this implementation of ramster, any remote node is potentially a single
+point of failure (SPOF).  Though the probability of failure is reduced
+by automatic swap repatriation (see above), a proposed future enhancement
+to ramster improves high-availability for the cluster by sending a copy
+of each page of date to two other nodes.  Patches welcome!
index 522cb8e5514269b12eaee3a8875ba6f241c64dad..dcceed29d31ae415818d1fceecc6518cbc017845 100644 (file)
@@ -1922,15 +1922,15 @@ out:
 
 #ifdef CONFIG_ZCACHE_MODULE
 #ifdef CONFIG_RAMSTER
-module_param(ramster_enabled, int, S_IRUGO);
+module_param(ramster_enabled, bool, S_IRUGO);
 module_param(disable_frontswap_selfshrink, int, S_IRUGO);
 #endif
-module_param(disable_cleancache, int, S_IRUGO);
-module_param(disable_frontswap, int, S_IRUGO);
+module_param(disable_cleancache, bool, S_IRUGO);
+module_param(disable_frontswap, bool, S_IRUGO);
 #ifdef FRONTSWAP_HAS_EXCLUSIVE_GETS
 module_param(frontswap_has_exclusive_gets, bool, S_IRUGO);
 #endif
-module_param(disable_frontswap_ignore_nonactive, int, S_IRUGO);
+module_param(disable_frontswap_ignore_nonactive, bool, S_IRUGO);
 module_param(zcache_comp_name, charp, S_IRUGO);
 module_init(zcache_init);
 MODULE_LICENSE("GPL");
index 6d0c27cd03da2676b91bfef307482a83be765697..9bffcec5ad82a4bcf0f05e3a89c73cf0b62433dc 100644 (file)
@@ -859,6 +859,7 @@ error:
  */
 static void __exit ehv_bc_exit(void)
 {
+       platform_driver_unregister(&ehv_bc_tty_driver);
        tty_unregister_driver(ehv_bc_driver);
        put_tty_driver(ehv_bc_driver);
        kfree(bcs);
index 71d6eb2c93b1c6335ba123cc9ac3c17a2af0d805..4c4a236745692ab1ee2e674f5d7dbf0334002dae 100644 (file)
@@ -1618,8 +1618,12 @@ static int mxser_ioctl_special(unsigned int cmd, void __user *argp)
                                if (ip->type == PORT_16550A)
                                        me->fifo[p] = 1;
 
-                               opmode = inb(ip->opmode_ioaddr)>>((p % 4) * 2);
-                               opmode &= OP_MODE_MASK;
+                               if (ip->board->chip_flag == MOXA_MUST_MU860_HWID) {
+                                       opmode = inb(ip->opmode_ioaddr)>>((p % 4) * 2);
+                                       opmode &= OP_MODE_MASK;
+                               } else {
+                                       opmode = RS232_MODE;
+                               }
                                me->iftype[p] = opmode;
                                mutex_unlock(&port->mutex);
                        }
@@ -1676,6 +1680,9 @@ static int mxser_ioctl(struct tty_struct *tty,
                int shiftbit;
                unsigned char val, mask;
 
+               if (info->board->chip_flag != MOXA_MUST_MU860_HWID)
+                       return -EFAULT;
+
                p = tty->index % 4;
                if (cmd == MOXA_SET_OP_MODE) {
                        if (get_user(opmode, (int __user *) argp))
index d655416087b7099d7639923c7c0a478c72a5afbe..6c7fe90ad72d48d2834536331e6826ee2719f94f 100644 (file)
@@ -1573,6 +1573,14 @@ static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old)
                        ldata->real_raw = 0;
        }
        n_tty_set_room(tty);
+       /*
+        * Fix tty hang when I_IXON(tty) is cleared, but the tty
+        * been stopped by STOP_CHAR(tty) before it.
+        */
+       if (!I_IXON(tty) && old && (old->c_iflag & IXON) && !tty->flow_stopped) {
+               start_tty(tty);
+       }
+
        /* The termios change make the tty ready for I/O */
        wake_up_interruptible(&tty->write_wait);
        wake_up_interruptible(&tty->read_wait);
index 82d35c5a58fd0bc16649aacc3c004377ff23de54..354564ea47c504446ba5aeab1153d48edc4acc48 100644 (file)
@@ -150,12 +150,14 @@ static Word_t aiop_intr_bits[AIOP_CTL_SIZE] = {
        AIOP_INTR_BIT_3
 };
 
+#ifdef CONFIG_PCI
 static Word_t upci_aiop_intr_bits[AIOP_CTL_SIZE] = {
        UPCI_AIOP_INTR_BIT_0,
        UPCI_AIOP_INTR_BIT_1,
        UPCI_AIOP_INTR_BIT_2,
        UPCI_AIOP_INTR_BIT_3
 };
+#endif
 
 static Byte_t RData[RDATASIZE] = {
        0x00, 0x09, 0xf6, 0x82,
@@ -227,7 +229,6 @@ static unsigned long nextLineNumber;
 static int __init init_ISA(int i);
 static void rp_wait_until_sent(struct tty_struct *tty, int timeout);
 static void rp_flush_buffer(struct tty_struct *tty);
-static void rmSpeakerReset(CONTROLLER_T * CtlP, unsigned long model);
 static unsigned char GetLineNumber(int ctrl, int aiop, int ch);
 static unsigned char SetLineNumber(int ctrl, int aiop, int ch);
 static void rp_start(struct tty_struct *tty);
@@ -241,11 +242,6 @@ static void sDisInterrupts(CHANNEL_T * ChP, Word_t Flags);
 static void sModemReset(CONTROLLER_T * CtlP, int chan, int on);
 static void sPCIModemReset(CONTROLLER_T * CtlP, int chan, int on);
 static int sWriteTxPrioByte(CHANNEL_T * ChP, Byte_t Data);
-static int sPCIInitController(CONTROLLER_T * CtlP, int CtlNum,
-                             ByteIO_t * AiopIOList, int AiopIOListSize,
-                             WordIO_t ConfigIO, int IRQNum, Byte_t Frequency,
-                             int PeriodicOnly, int altChanRingIndicator,
-                             int UPCIRingInd);
 static int sInitController(CONTROLLER_T * CtlP, int CtlNum, ByteIO_t MudbacIO,
                           ByteIO_t * AiopIOList, int AiopIOListSize,
                           int IRQNum, Byte_t Frequency, int PeriodicOnly);
@@ -1775,6 +1771,145 @@ static DEFINE_PCI_DEVICE_TABLE(rocket_pci_ids) = {
 };
 MODULE_DEVICE_TABLE(pci, rocket_pci_ids);
 
+/*  Resets the speaker controller on RocketModem II and III devices */
+static void rmSpeakerReset(CONTROLLER_T * CtlP, unsigned long model)
+{
+       ByteIO_t addr;
+
+       /* RocketModem II speaker control is at the 8th port location of offset 0x40 */
+       if ((model == MODEL_RP4M) || (model == MODEL_RP6M)) {
+               addr = CtlP->AiopIO[0] + 0x4F;
+               sOutB(addr, 0);
+       }
+
+       /* RocketModem III speaker control is at the 1st port location of offset 0x80 */
+       if ((model == MODEL_UPCI_RM3_8PORT)
+           || (model == MODEL_UPCI_RM3_4PORT)) {
+               addr = CtlP->AiopIO[0] + 0x88;
+               sOutB(addr, 0);
+       }
+}
+
+/***************************************************************************
+Function: sPCIInitController
+Purpose:  Initialization of controller global registers and controller
+          structure.
+Call:     sPCIInitController(CtlP,CtlNum,AiopIOList,AiopIOListSize,
+                          IRQNum,Frequency,PeriodicOnly)
+          CONTROLLER_T *CtlP; Ptr to controller structure
+          int CtlNum; Controller number
+          ByteIO_t *AiopIOList; List of I/O addresses for each AIOP.
+             This list must be in the order the AIOPs will be found on the
+             controller.  Once an AIOP in the list is not found, it is
+             assumed that there are no more AIOPs on the controller.
+          int AiopIOListSize; Number of addresses in AiopIOList
+          int IRQNum; Interrupt Request number.  Can be any of the following:
+                         0: Disable global interrupts
+                         3: IRQ 3
+                         4: IRQ 4
+                         5: IRQ 5
+                         9: IRQ 9
+                         10: IRQ 10
+                         11: IRQ 11
+                         12: IRQ 12
+                         15: IRQ 15
+          Byte_t Frequency: A flag identifying the frequency
+                   of the periodic interrupt, can be any one of the following:
+                      FREQ_DIS - periodic interrupt disabled
+                      FREQ_137HZ - 137 Hertz
+                      FREQ_69HZ - 69 Hertz
+                      FREQ_34HZ - 34 Hertz
+                      FREQ_17HZ - 17 Hertz
+                      FREQ_9HZ - 9 Hertz
+                      FREQ_4HZ - 4 Hertz
+                   If IRQNum is set to 0 the Frequency parameter is
+                   overidden, it is forced to a value of FREQ_DIS.
+          int PeriodicOnly: 1 if all interrupts except the periodic
+                               interrupt are to be blocked.
+                            0 is both the periodic interrupt and
+                               other channel interrupts are allowed.
+                            If IRQNum is set to 0 the PeriodicOnly parameter is
+                               overidden, it is forced to a value of 0.
+Return:   int: Number of AIOPs on the controller, or CTLID_NULL if controller
+               initialization failed.
+
+Comments:
+          If periodic interrupts are to be disabled but AIOP interrupts
+          are allowed, set Frequency to FREQ_DIS and PeriodicOnly to 0.
+
+          If interrupts are to be completely disabled set IRQNum to 0.
+
+          Setting Frequency to FREQ_DIS and PeriodicOnly to 1 is an
+          invalid combination.
+
+          This function performs initialization of global interrupt modes,
+          but it does not actually enable global interrupts.  To enable
+          and disable global interrupts use functions sEnGlobalInt() and
+          sDisGlobalInt().  Enabling of global interrupts is normally not
+          done until all other initializations are complete.
+
+          Even if interrupts are globally enabled, they must also be
+          individually enabled for each channel that is to generate
+          interrupts.
+
+Warnings: No range checking on any of the parameters is done.
+
+          No context switches are allowed while executing this function.
+
+          After this function all AIOPs on the controller are disabled,
+          they can be enabled with sEnAiop().
+*/
+static int sPCIInitController(CONTROLLER_T * CtlP, int CtlNum,
+                             ByteIO_t * AiopIOList, int AiopIOListSize,
+                             WordIO_t ConfigIO, int IRQNum, Byte_t Frequency,
+                             int PeriodicOnly, int altChanRingIndicator,
+                             int UPCIRingInd)
+{
+       int i;
+       ByteIO_t io;
+
+       CtlP->AltChanRingIndicator = altChanRingIndicator;
+       CtlP->UPCIRingInd = UPCIRingInd;
+       CtlP->CtlNum = CtlNum;
+       CtlP->CtlID = CTLID_0001;       /* controller release 1 */
+       CtlP->BusType = isPCI;  /* controller release 1 */
+
+       if (ConfigIO) {
+               CtlP->isUPCI = 1;
+               CtlP->PCIIO = ConfigIO + _PCI_9030_INT_CTRL;
+               CtlP->PCIIO2 = ConfigIO + _PCI_9030_GPIO_CTRL;
+               CtlP->AiopIntrBits = upci_aiop_intr_bits;
+       } else {
+               CtlP->isUPCI = 0;
+               CtlP->PCIIO =
+                   (WordIO_t) ((ByteIO_t) AiopIOList[0] + _PCI_INT_FUNC);
+               CtlP->AiopIntrBits = aiop_intr_bits;
+       }
+
+       sPCIControllerEOI(CtlP);        /* clear EOI if warm init */
+       /* Init AIOPs */
+       CtlP->NumAiop = 0;
+       for (i = 0; i < AiopIOListSize; i++) {
+               io = AiopIOList[i];
+               CtlP->AiopIO[i] = (WordIO_t) io;
+               CtlP->AiopIntChanIO[i] = io + _INT_CHAN;
+
+               CtlP->AiopID[i] = sReadAiopID(io);      /* read AIOP ID */
+               if (CtlP->AiopID[i] == AIOPID_NULL)     /* if AIOP does not exist */
+                       break;  /* done looking for AIOPs */
+
+               CtlP->AiopNumChan[i] = sReadAiopNumChan((WordIO_t) io); /* num channels in AIOP */
+               sOutW((WordIO_t) io + _INDX_ADDR, _CLK_PRE);    /* clock prescaler */
+               sOutB(io + _INDX_DATA, sClockPrescale);
+               CtlP->NumAiop++;        /* bump count of AIOPs */
+       }
+
+       if (CtlP->NumAiop == 0)
+               return (-1);
+       else
+               return (CtlP->NumAiop);
+}
+
 /*
  *  Called when a PCI card is found.  Retrieves and stores model information,
  *  init's aiopic and serial port hardware.
@@ -2519,147 +2654,6 @@ static int sInitController(CONTROLLER_T * CtlP, int CtlNum, ByteIO_t MudbacIO,
                return (CtlP->NumAiop);
 }
 
-#ifdef CONFIG_PCI
-/***************************************************************************
-Function: sPCIInitController
-Purpose:  Initialization of controller global registers and controller
-          structure.
-Call:     sPCIInitController(CtlP,CtlNum,AiopIOList,AiopIOListSize,
-                          IRQNum,Frequency,PeriodicOnly)
-          CONTROLLER_T *CtlP; Ptr to controller structure
-          int CtlNum; Controller number
-          ByteIO_t *AiopIOList; List of I/O addresses for each AIOP.
-             This list must be in the order the AIOPs will be found on the
-             controller.  Once an AIOP in the list is not found, it is
-             assumed that there are no more AIOPs on the controller.
-          int AiopIOListSize; Number of addresses in AiopIOList
-          int IRQNum; Interrupt Request number.  Can be any of the following:
-                         0: Disable global interrupts
-                         3: IRQ 3
-                         4: IRQ 4
-                         5: IRQ 5
-                         9: IRQ 9
-                         10: IRQ 10
-                         11: IRQ 11
-                         12: IRQ 12
-                         15: IRQ 15
-          Byte_t Frequency: A flag identifying the frequency
-                   of the periodic interrupt, can be any one of the following:
-                      FREQ_DIS - periodic interrupt disabled
-                      FREQ_137HZ - 137 Hertz
-                      FREQ_69HZ - 69 Hertz
-                      FREQ_34HZ - 34 Hertz
-                      FREQ_17HZ - 17 Hertz
-                      FREQ_9HZ - 9 Hertz
-                      FREQ_4HZ - 4 Hertz
-                   If IRQNum is set to 0 the Frequency parameter is
-                   overidden, it is forced to a value of FREQ_DIS.
-          int PeriodicOnly: 1 if all interrupts except the periodic
-                               interrupt are to be blocked.
-                            0 is both the periodic interrupt and
-                               other channel interrupts are allowed.
-                            If IRQNum is set to 0 the PeriodicOnly parameter is
-                               overidden, it is forced to a value of 0.
-Return:   int: Number of AIOPs on the controller, or CTLID_NULL if controller
-               initialization failed.
-
-Comments:
-          If periodic interrupts are to be disabled but AIOP interrupts
-          are allowed, set Frequency to FREQ_DIS and PeriodicOnly to 0.
-
-          If interrupts are to be completely disabled set IRQNum to 0.
-
-          Setting Frequency to FREQ_DIS and PeriodicOnly to 1 is an
-          invalid combination.
-
-          This function performs initialization of global interrupt modes,
-          but it does not actually enable global interrupts.  To enable
-          and disable global interrupts use functions sEnGlobalInt() and
-          sDisGlobalInt().  Enabling of global interrupts is normally not
-          done until all other initializations are complete.
-
-          Even if interrupts are globally enabled, they must also be
-          individually enabled for each channel that is to generate
-          interrupts.
-
-Warnings: No range checking on any of the parameters is done.
-
-          No context switches are allowed while executing this function.
-
-          After this function all AIOPs on the controller are disabled,
-          they can be enabled with sEnAiop().
-*/
-static int sPCIInitController(CONTROLLER_T * CtlP, int CtlNum,
-                             ByteIO_t * AiopIOList, int AiopIOListSize,
-                             WordIO_t ConfigIO, int IRQNum, Byte_t Frequency,
-                             int PeriodicOnly, int altChanRingIndicator,
-                             int UPCIRingInd)
-{
-       int i;
-       ByteIO_t io;
-
-       CtlP->AltChanRingIndicator = altChanRingIndicator;
-       CtlP->UPCIRingInd = UPCIRingInd;
-       CtlP->CtlNum = CtlNum;
-       CtlP->CtlID = CTLID_0001;       /* controller release 1 */
-       CtlP->BusType = isPCI;  /* controller release 1 */
-
-       if (ConfigIO) {
-               CtlP->isUPCI = 1;
-               CtlP->PCIIO = ConfigIO + _PCI_9030_INT_CTRL;
-               CtlP->PCIIO2 = ConfigIO + _PCI_9030_GPIO_CTRL;
-               CtlP->AiopIntrBits = upci_aiop_intr_bits;
-       } else {
-               CtlP->isUPCI = 0;
-               CtlP->PCIIO =
-                   (WordIO_t) ((ByteIO_t) AiopIOList[0] + _PCI_INT_FUNC);
-               CtlP->AiopIntrBits = aiop_intr_bits;
-       }
-
-       sPCIControllerEOI(CtlP);        /* clear EOI if warm init */
-       /* Init AIOPs */
-       CtlP->NumAiop = 0;
-       for (i = 0; i < AiopIOListSize; i++) {
-               io = AiopIOList[i];
-               CtlP->AiopIO[i] = (WordIO_t) io;
-               CtlP->AiopIntChanIO[i] = io + _INT_CHAN;
-
-               CtlP->AiopID[i] = sReadAiopID(io);      /* read AIOP ID */
-               if (CtlP->AiopID[i] == AIOPID_NULL)     /* if AIOP does not exist */
-                       break;  /* done looking for AIOPs */
-
-               CtlP->AiopNumChan[i] = sReadAiopNumChan((WordIO_t) io); /* num channels in AIOP */
-               sOutW((WordIO_t) io + _INDX_ADDR, _CLK_PRE);    /* clock prescaler */
-               sOutB(io + _INDX_DATA, sClockPrescale);
-               CtlP->NumAiop++;        /* bump count of AIOPs */
-       }
-
-       if (CtlP->NumAiop == 0)
-               return (-1);
-       else
-               return (CtlP->NumAiop);
-}
-
-/*  Resets the speaker controller on RocketModem II and III devices */
-static void rmSpeakerReset(CONTROLLER_T * CtlP, unsigned long model)
-{
-       ByteIO_t addr;
-
-       /* RocketModem II speaker control is at the 8th port location of offset 0x40 */
-       if ((model == MODEL_RP4M) || (model == MODEL_RP6M)) {
-               addr = CtlP->AiopIO[0] + 0x4F;
-               sOutB(addr, 0);
-       }
-
-       /* RocketModem III speaker control is at the 1st port location of offset 0x80 */
-       if ((model == MODEL_UPCI_RM3_8PORT)
-           || (model == MODEL_UPCI_RM3_4PORT)) {
-               addr = CtlP->AiopIO[0] + 0x88;
-               sOutB(addr, 0);
-       }
-}
-#endif
-
 /***************************************************************************
 Function: sReadAiopID
 Purpose:  Read the AIOP idenfication number directly from an AIOP.
index beaa283f5cc6f75c24484b11beb73704f25a6ccd..d07b6af3a9379db82927677a5915d9bae01d7874 100644 (file)
@@ -338,7 +338,8 @@ static int dw8250_runtime_suspend(struct device *dev)
 {
        struct dw8250_data *data = dev_get_drvdata(dev);
 
-       clk_disable_unprepare(data->clk);
+       if (!IS_ERR(data->clk))
+               clk_disable_unprepare(data->clk);
 
        return 0;
 }
@@ -347,7 +348,8 @@ static int dw8250_runtime_resume(struct device *dev)
 {
        struct dw8250_data *data = dev_get_drvdata(dev);
 
-       clk_prepare_enable(data->clk);
+       if (!IS_ERR(data->clk))
+               clk_prepare_enable(data->clk);
 
        return 0;
 }
@@ -367,6 +369,7 @@ MODULE_DEVICE_TABLE(of, dw8250_of_match);
 static const struct acpi_device_id dw8250_acpi_match[] = {
        { "INT33C4", 0 },
        { "INT33C5", 0 },
+       { "80860F0A", 0 },
        { },
 };
 MODULE_DEVICE_TABLE(acpi, dw8250_acpi_match);
index 8ab70a6209199145f840b9d0cff0b255700f454c..e2774f9ecd59f16915e0647028e643e616b9c4cb 100644 (file)
@@ -332,7 +332,7 @@ static void pl011_dma_probe_initcall(struct device *dev, struct uart_amba_port *
                dmaengine_slave_config(chan, &rx_conf);
                uap->dmarx.chan = chan;
 
-               if (plat->dma_rx_poll_enable) {
+               if (plat && plat->dma_rx_poll_enable) {
                        /* Set poll rate if specified. */
                        if (plat->dma_rx_poll_rate) {
                                uap->dmarx.auto_poll_rate = false;
index e956377a38fe53e299766724c278a05a35d802c4..65be0c00c4bff3f802549a23dfe34515a5a03b54 100644 (file)
@@ -707,8 +707,10 @@ static int __init mcf_init(void)
        if (rc)
                return rc;
        rc = platform_driver_register(&mcf_platform_driver);
-       if (rc)
+       if (rc) {
+               uart_unregister_driver(&mcf_driver);
                return rc;
+       }
        return 0;
 }
 
index 018bad922554fc45b9ad711bcab2a106fc683b6e..f51b280f3bf280b882130ec92b499be65937eed2 100644 (file)
@@ -1497,18 +1497,23 @@ mpc52xx_uart_init(void)
        if (psc_ops && psc_ops->fifoc_init) {
                ret = psc_ops->fifoc_init();
                if (ret)
-                       return ret;
+                       goto err_init;
        }
 
        ret = platform_driver_register(&mpc52xx_uart_of_driver);
        if (ret) {
                printk(KERN_ERR "%s: platform_driver_register failed (%i)\n",
                       __FILE__, ret);
-               uart_unregister_driver(&mpc52xx_uart_driver);
-               return ret;
+               goto err_reg;
        }
 
        return 0;
+err_reg:
+       if (psc_ops && psc_ops->fifoc_uninit)
+               psc_ops->fifoc_uninit();
+err_init:
+       uart_unregister_driver(&mpc52xx_uart_driver);
+       return ret;
 }
 
 static void __exit
index 77287c54f331682425403e045b0548c7f460590c..549c70a2a63e8397521b63fd6120e7dad9cfb079 100644 (file)
@@ -199,7 +199,7 @@ static void nwpserial_shutdown(struct uart_port *port)
        dcr_write(up->dcr_host, UART_IER, up->ier);
 
        /* free irq */
-       free_irq(up->port.irq, port);
+       free_irq(up->port.irq, up);
 }
 
 static int nwpserial_verify_port(struct uart_port *port,
index 30d4f7a783cd1f0bbfdf6ebaf491f2400153eaf0..f0b9f6b52b32cd887ad6b86586f97aa9eec9648c 100644 (file)
@@ -202,26 +202,6 @@ static int serial_omap_get_context_loss_count(struct uart_omap_port *up)
        return pdata->get_context_loss_count(up->dev);
 }
 
-static void serial_omap_set_forceidle(struct uart_omap_port *up)
-{
-       struct omap_uart_port_info *pdata = up->dev->platform_data;
-
-       if (!pdata || !pdata->set_forceidle)
-               return;
-
-       pdata->set_forceidle(up->dev);
-}
-
-static void serial_omap_set_noidle(struct uart_omap_port *up)
-{
-       struct omap_uart_port_info *pdata = up->dev->platform_data;
-
-       if (!pdata || !pdata->set_noidle)
-               return;
-
-       pdata->set_noidle(up->dev);
-}
-
 static void serial_omap_enable_wakeup(struct uart_omap_port *up, bool enable)
 {
        struct omap_uart_port_info *pdata = up->dev->platform_data;
@@ -298,8 +278,6 @@ static void serial_omap_stop_tx(struct uart_port *port)
                serial_out(up, UART_IER, up->ier);
        }
 
-       serial_omap_set_forceidle(up);
-
        pm_runtime_mark_last_busy(up->dev);
        pm_runtime_put_autosuspend(up->dev);
 }
@@ -364,7 +342,6 @@ static void serial_omap_start_tx(struct uart_port *port)
 
        pm_runtime_get_sync(up->dev);
        serial_omap_enable_ier_thri(up);
-       serial_omap_set_noidle(up);
        pm_runtime_mark_last_busy(up->dev);
        pm_runtime_put_autosuspend(up->dev);
 }
index 074b9194144fdefa1e09536a96626129624a64e0..89429410a245e7b1d97b6602776a2b9be20881ab 100644 (file)
@@ -1803,6 +1803,7 @@ static int __init s3c24xx_serial_modinit(void)
 
 static void __exit s3c24xx_serial_modexit(void)
 {
+       platform_driver_unregister(&samsung_serial_driver);
        uart_unregister_driver(&s3c24xx_uart_drv);
 }
 
index fbd447b390f775fa8182a290266d3d4f41f46e2c..740202d8a5c4b732ab9c98b188c995d3a0f78587 100644 (file)
@@ -779,7 +779,6 @@ int vc_allocate(unsigned int currcons)      /* return 0 on success */
                con_set_default_unimap(vc);
            vc->vc_screenbuf = kmalloc(vc->vc_screenbuf_size, GFP_KERNEL);
            if (!vc->vc_screenbuf) {
-               tty_port_destroy(&vc->port);
                kfree(vc);
                vc_cons[currcons].d = NULL;
                return -ENOMEM;
@@ -986,26 +985,25 @@ static int vt_resize(struct tty_struct *tty, struct winsize *ws)
        return ret;
 }
 
-void vc_deallocate(unsigned int currcons)
+struct vc_data *vc_deallocate(unsigned int currcons)
 {
+       struct vc_data *vc = NULL;
+
        WARN_CONSOLE_UNLOCKED();
 
        if (vc_cons_allocated(currcons)) {
-               struct vc_data *vc = vc_cons[currcons].d;
-               struct vt_notifier_param param = { .vc = vc };
+               struct vt_notifier_param param;
 
+               param.vc = vc = vc_cons[currcons].d;
                atomic_notifier_call_chain(&vt_notifier_list, VT_DEALLOCATE, &param);
                vcs_remove_sysfs(currcons);
                vc->vc_sw->con_deinit(vc);
                put_pid(vc->vt_pid);
                module_put(vc->vc_sw->owner);
                kfree(vc->vc_screenbuf);
-               if (currcons >= MIN_NR_CONSOLES) {
-                       tty_port_destroy(&vc->port);
-                       kfree(vc);
-               }
                vc_cons[currcons].d = NULL;
        }
+       return vc;
 }
 
 /*
index 98ff1735eafc0841428a2e2fa2257909073c775e..fc2c06c66e89d5e7536c5bb5387bc0fd9a837086 100644 (file)
@@ -283,6 +283,51 @@ do_unimap_ioctl(int cmd, struct unimapdesc __user *user_ud, int perm, struct vc_
        return 0;
 }
 
+/* deallocate a single console, if possible (leave 0) */
+static int vt_disallocate(unsigned int vc_num)
+{
+       struct vc_data *vc = NULL;
+       int ret = 0;
+
+       if (!vc_num)
+               return 0;
+
+       console_lock();
+       if (VT_BUSY(vc_num))
+               ret = -EBUSY;
+       else
+               vc = vc_deallocate(vc_num);
+       console_unlock();
+
+       if (vc && vc_num >= MIN_NR_CONSOLES) {
+               tty_port_destroy(&vc->port);
+               kfree(vc);
+       }
+
+       return ret;
+}
+
+/* deallocate all unused consoles, but leave 0 */
+static void vt_disallocate_all(void)
+{
+       struct vc_data *vc[MAX_NR_CONSOLES];
+       int i;
+
+       console_lock();
+       for (i = 1; i < MAX_NR_CONSOLES; i++)
+               if (!VT_BUSY(i))
+                       vc[i] = vc_deallocate(i);
+               else
+                       vc[i] = NULL;
+       console_unlock();
+
+       for (i = 1; i < MAX_NR_CONSOLES; i++) {
+               if (vc[i] && i >= MIN_NR_CONSOLES) {
+                       tty_port_destroy(&vc[i]->port);
+                       kfree(vc[i]);
+               }
+       }
+}
 
 
 /*
@@ -769,24 +814,10 @@ int vt_ioctl(struct tty_struct *tty,
                        ret = -ENXIO;
                        break;
                }
-               if (arg == 0) {
-                   /* deallocate all unused consoles, but leave 0 */
-                       console_lock();
-                       for (i=1; i<MAX_NR_CONSOLES; i++)
-                               if (! VT_BUSY(i))
-                                       vc_deallocate(i);
-                       console_unlock();
-               } else {
-                       /* deallocate a single console, if possible */
-                       arg--;
-                       if (VT_BUSY(arg))
-                               ret = -EBUSY;
-                       else if (arg) {                       /* leave 0 */
-                               console_lock();
-                               vc_deallocate(arg);
-                               console_unlock();
-                       }
-               }
+               if (arg == 0)
+                       vt_disallocate_all();
+               else
+                       ret = vt_disallocate(--arg);
                break;
 
        case VT_RESIZE:
index e92eeaf251fe33c8c12f693b54db8b75258643a2..5295be0342c1acc88f5698bbdc29a16268ad551a 100644 (file)
@@ -45,6 +45,7 @@ config UIO_PDRV_GENIRQ
 
 config UIO_DMEM_GENIRQ
        tristate "Userspace platform driver with generic irq and dynamic memory"
+       depends on HAS_DMA
        help
          Platform driver for Userspace I/O devices, including generic
          interrupt handling code. Shared interrupts are not supported.
index b7eb86ad6bf2c2538e1a5d08d358c9b29f432e76..8a7eb77233b4a7b275e042dfeb965be2f45393f8 100644 (file)
@@ -686,7 +686,8 @@ static int cxacru_cm_get_array(struct cxacru_data *instance, enum cxacru_cm_requ
 {
        int ret, len;
        __le32 *buf;
-       int offb, offd;
+       int offb;
+       unsigned int offd;
        const int stride = CMD_PACKET_SIZE / (4 * 2) - 1;
        int buflen =  ((size - 1) / stride + 1 + size * 2) * 4;
 
index 608a2aeb400c929726c4a9581dfad1e09eeed179..b2df442eb3e5b9537772569cfd321e32e5ef2ce5 100644 (file)
@@ -20,7 +20,7 @@ config USB_CHIPIDEA_UDC
 config USB_CHIPIDEA_HOST
        bool "ChipIdea host controller"
        depends on USB=y || USB=USB_CHIPIDEA
-       depends on USB_EHCI_HCD
+       depends on USB_EHCI_HCD=y
        select USB_EHCI_ROOT_HUB_TT
        help
          Say Y here to enable host controller functionality of the
index 8faec9dbbb84326d436ffc568451b322eb95a1a3..73f9d5f15adb6706b30a48b4c34963027d2565a0 100644 (file)
@@ -173,17 +173,10 @@ static int ci13xxx_imx_probe(struct platform_device *pdev)
 
        ci13xxx_imx_platdata.phy = data->phy;
 
-       if (!pdev->dev.dma_mask) {
-               pdev->dev.dma_mask = devm_kzalloc(&pdev->dev,
-                                     sizeof(*pdev->dev.dma_mask), GFP_KERNEL);
-               if (!pdev->dev.dma_mask) {
-                       ret = -ENOMEM;
-                       dev_err(&pdev->dev, "Failed to alloc dma_mask!\n");
-                       goto err;
-               }
-               *pdev->dev.dma_mask = DMA_BIT_MASK(32);
-               dma_set_coherent_mask(&pdev->dev, *pdev->dev.dma_mask);
-       }
+       if (!pdev->dev.dma_mask)
+               pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
+       if (!pdev->dev.coherent_dma_mask)
+               pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
 
        if (usbmisc_ops && usbmisc_ops->init) {
                ret = usbmisc_ops->init(&pdev->dev);
index 8772b3659296b90b2c009774fd3bba8c0498236e..db535b0aa172c85b3787a476b8fe3adeefbe3e6f 100644 (file)
@@ -51,7 +51,7 @@ config USB_DYNAMIC_MINORS
 
 config USB_OTG
        bool "OTG support"
-       depends on USB_SUSPEND
+       depends on PM_RUNTIME
        default n
        help
          The most notable feature of USB OTG is support for a
index ab5638d9c707c0524eb37a58fc1ce3e95d1a7ae9..a63598895077ff8c984c0ed473d5ee90afa52086 100644 (file)
@@ -88,6 +88,9 @@ static const struct usb_device_id usb_quirk_list[] = {
        /* Edirol SD-20 */
        { USB_DEVICE(0x0582, 0x0027), .driver_info = USB_QUIRK_RESET_RESUME },
 
+       /* Alcor Micro Corp. Hub */
+       { USB_DEVICE(0x058f, 0x9254), .driver_info = USB_QUIRK_RESET_RESUME },
+
        /* appletouch */
        { USB_DEVICE(0x05ac, 0x021a), .driver_info = USB_QUIRK_RESET_RESUME },
 
index ea5ee9c21c3514cc7a0fe87ff2f6d15bcc206eb2..757aa18027d05ca0eb198d97d92f1710e8e58def 100644 (file)
@@ -19,21 +19,21 @@ choice
 
 config USB_DWC3_HOST
        bool "Host only mode"
-       depends on USB
+       depends on USB=y || USB=USB_DWC3
        help
          Select this when you want to use DWC3 in host mode only,
          thereby the gadget feature will be regressed.
 
 config USB_DWC3_GADGET
        bool "Gadget only mode"
-       depends on USB_GADGET
+       depends on USB_GADGET=y || USB_GADGET=USB_DWC3
        help
          Select this when you want to use DWC3 in gadget mode only,
          thereby the host feature will be regressed.
 
 config USB_DWC3_DUAL_ROLE
        bool "Dual Role mode"
-       depends on (USB && USB_GADGET)
+       depends on ((USB=y || USB=USB_DWC3) && (USB_GADGET=y || USB_GADGET=USB_DWC3))
        help
          This is the default mode of working of DWC3 controller where
          both host and gadget features are enabled.
index a8afe6e2662186e50e45cf578d967c901c9a7456..929e7dd6e58bf6ea4e3d1d6ca7984303f0bbe00d 100644 (file)
@@ -95,8 +95,6 @@ static int dwc3_exynos_remove_child(struct device *dev, void *unused)
        return 0;
 }
 
-static u64 dwc3_exynos_dma_mask = DMA_BIT_MASK(32);
-
 static int dwc3_exynos_probe(struct platform_device *pdev)
 {
        struct dwc3_exynos      *exynos;
@@ -118,7 +116,9 @@ static int dwc3_exynos_probe(struct platform_device *pdev)
         * Once we move to full device tree support this will vanish off.
         */
        if (!dev->dma_mask)
-               dev->dma_mask = &dwc3_exynos_dma_mask;
+               dev->dma_mask = &dev->coherent_dma_mask;
+       if (!dev->coherent_dma_mask)
+               dev->coherent_dma_mask = DMA_BIT_MASK(32);
 
        platform_set_drvdata(pdev, exynos);
 
index 83300d94a8933ff97a52992466799874cdeacb20..f41aa0d0c414312163bf2076935fb96adccd7036 100644 (file)
@@ -146,7 +146,6 @@ config USB_LPC32XX
        depends on ARCH_LPC32XX
        depends on USB_PHY
        select USB_ISP1301
-       select USB_OTG_UTILS
        help
           This option selects the USB device controller in the LPC32xx SoC.
 
index f2a970f75bfa949b2c28db72c183e00790fea280..5a5128a226f737d2ec74915cde9f23d5d74e0470 100644 (file)
@@ -1992,8 +1992,6 @@ err_map_regs:
 err_get_hclk:
        clk_put(pclk);
 
-       platform_set_drvdata(pdev, NULL);
-
        return ret;
 }
 
index 79229779814768886610deb16f03c5a62b5c8613..fd24cb4540a49d6b0382b932ff99eae2dc9c309f 100644 (file)
@@ -2410,7 +2410,6 @@ static int bcm63xx_udc_remove(struct platform_device *pdev)
        usb_del_gadget_udc(&udc->gadget);
        BUG_ON(udc->driver);
 
-       platform_set_drvdata(pdev, NULL);
        bcm63xx_uninit_udc_hw(udc);
 
        return 0;
index 3d5cfc9c2c78a51950701b68bb94bfbb25f2f25c..80e7f75a56c7efa43b33a752671eb8c263bb1bf9 100644 (file)
@@ -821,8 +821,10 @@ static int configfs_composite_bind(struct usb_gadget *gadget,
                gi->gstrings[i] = NULL;
                s = usb_gstrings_attach(&gi->cdev, gi->gstrings,
                                USB_GADGET_FIRST_AVAIL_IDX);
-               if (IS_ERR(s))
+               if (IS_ERR(s)) {
+                       ret = PTR_ERR(s);
                        goto err_comp_cleanup;
+               }
 
                gi->cdev.desc.iManufacturer = s[USB_GADGET_MANUFACTURER_IDX].id;
                gi->cdev.desc.iProduct = s[USB_GADGET_PRODUCT_IDX].id;
@@ -847,8 +849,10 @@ static int configfs_composite_bind(struct usb_gadget *gadget,
                        }
                        cfg->gstrings[i] = NULL;
                        s = usb_gstrings_attach(&gi->cdev, cfg->gstrings, 1);
-                       if (IS_ERR(s))
+                       if (IS_ERR(s)) {
+                               ret = PTR_ERR(s);
                                goto err_comp_cleanup;
+                       }
                        c->iConfiguration = s[0].id;
                }
 
index a792e322f4f1b84c58e20538b48d1e7beea4082f..c588e8e486e590843ed2714403f282a7b3748a68 100644 (file)
@@ -1001,7 +1001,6 @@ static int dummy_udc_remove(struct platform_device *pdev)
        struct dummy    *dum = platform_get_drvdata(pdev);
 
        usb_del_gadget_udc(&dum->gadget);
-       platform_set_drvdata(pdev, NULL);
        device_remove_file(&dum->gadget.dev, &dev_attr_function);
        return 0;
 }
@@ -2661,8 +2660,10 @@ static int __init init(void)
        }
        for (i = 0; i < mod_data.num; i++) {
                dum[i] = kzalloc(sizeof(struct dummy), GFP_KERNEL);
-               if (!dum[i])
+               if (!dum[i]) {
+                       retval = -ENOMEM;
                        goto err_add_pdata;
+               }
                retval = platform_device_add_data(the_hcd_pdev[i], &dum[i],
                                sizeof(void *));
                if (retval)
index d893d69290794efa9c8d1e064fe1abd62077ff6a..abf8a31ae146028a89130835d600b4a7dfa00486 100644 (file)
@@ -816,6 +816,7 @@ ecm_unbind(struct usb_configuration *c, struct usb_function *f)
  * @c: the configuration to support the network link
  * @ethaddr: a buffer in which the ethernet address of the host side
  *     side of the link was recorded
+ * @dev: eth_dev structure
  * Context: single threaded during gadget setup
  *
  * Returns zero on success, else negative errno.
index 185d6f5e4e4d15a933aeaa5b5e8ab0edc2c642b5..7be04b3424941f73c96d7a6de51d53101efe0f92 100644 (file)
@@ -373,6 +373,7 @@ geth_unbind(struct usb_configuration *c, struct usb_function *f)
  * @c: the configuration to support the network link
  * @ethaddr: a buffer in which the ethernet address of the host side
  *     side of the link was recorded
+ * @dev: eth_dev structure
  * Context: single threaded during gadget setup
  *
  * Returns zero on success, else negative errno.
index c7468b6c07b0057041f63328da8cf075f6ada80b..03c1fb686644e02d34b5b0f4a9c8e847d6a6de27 100644 (file)
@@ -456,8 +456,6 @@ static int snd_uac2_remove(struct platform_device *pdev)
 {
        struct snd_card *card = platform_get_drvdata(pdev);
 
-       platform_set_drvdata(pdev, NULL);
-
        if (card)
                return snd_card_free(card);
 
index cec8871b77f9d9acd91b2c845175b6f9150e8571..b8632d40f8bffcd3f653a99c12f6d6b02a8cd11d 100644 (file)
@@ -1461,8 +1461,10 @@ static int __init fusb300_probe(struct platform_device *pdev)
 
        fusb300->ep0_req = fusb300_alloc_request(&fusb300->ep[0]->ep,
                                GFP_KERNEL);
-       if (fusb300->ep0_req == NULL)
+       if (fusb300->ep0_req == NULL) {
+               ret = -ENOMEM;
                goto clean_up3;
+       }
 
        init_controller(fusb300);
        ret = usb_add_gadget_udc(&pdev->dev, &fusb300->gadget);
index b5cebd6b0d7af170128ede0f90754052b694aeb2..9b2d24e4c95f0c27f3e98c0d2dbf3aa6bfad4b83 100644 (file)
@@ -1511,8 +1511,6 @@ static int __exit imx_udc_remove(struct platform_device *pdev)
        if (pdata->exit)
                pdata->exit(&pdev->dev);
 
-       platform_set_drvdata(pdev, NULL);
-
        return 0;
 }
 
index 866ef09992478e18c114592305297efe640d225f..51cfe72da5bb88d6fb0a21a1d1d2753fa2e6c115 100644 (file)
@@ -1660,8 +1660,10 @@ static int __init m66592_probe(struct platform_device *pdev)
        m66592->epaddr2ep[0] = &m66592->ep[0];
 
        m66592->ep0_req = m66592_alloc_request(&m66592->ep[0].ep, GFP_KERNEL);
-       if (m66592->ep0_req == NULL)
+       if (m66592->ep0_req == NULL) {
+               ret = -ENOMEM;
                goto clean_up3;
+       }
        m66592->ep0_req->complete = nop_completion;
 
        init_controller(m66592);
index ef47495dec8f5e638e97ee4171b0a54b22dc2ba4..95c531d5aa4fa2dd9fcf4d038c5426254cb16629 100644 (file)
@@ -2236,7 +2236,6 @@ static int __exit pxa25x_udc_remove(struct platform_device *pdev)
                dev->transceiver = NULL;
        }
 
-       platform_set_drvdata(pdev, NULL);
        the_controller = NULL;
        return 0;
 }
index 0b742d171843fc8579691930791d0926a7f3d958..7ff7d9cf2061d28ebcd2b4a2935678b0f1460144 100644 (file)
@@ -1977,8 +1977,10 @@ static int __init r8a66597_probe(struct platform_device *pdev)
 
        r8a66597->ep0_req = r8a66597_alloc_request(&r8a66597->ep[0].ep,
                                                        GFP_KERNEL);
-       if (r8a66597->ep0_req == NULL)
+       if (r8a66597->ep0_req == NULL) {
+               ret = -ENOMEM;
                goto clean_up3;
+       }
        r8a66597->ep0_req->complete = nop_completion;
 
        ret = usb_add_gadget_udc(&pdev->dev, &r8a66597->gadget);
index a3cdc32115d52c646f2ae2b89ded1fcf378a9d70..af22f24046b239dcc9dda8553c17377326c62ded 100644 (file)
@@ -437,7 +437,7 @@ static void s3c_hsotg_unmap_dma(struct s3c_hsotg *hsotg,
        if (hs_req->req.length == 0)
                return;
 
-       usb_gadget_unmap_request(&hsotg->gadget, hs_req, hs_ep->dir_in);
+       usb_gadget_unmap_request(&hsotg->gadget, req, hs_ep->dir_in);
 }
 
 /**
index d0e75e1b3ccb9323de0a29622586894710fd2679..09c4f70c93c4cb13639cf89ed7d423c2231df621 100644 (file)
@@ -1851,6 +1851,7 @@ static int s3c2410_udc_probe(struct platform_device *pdev)
                irq = gpio_to_irq(udc_info->vbus_pin);
                if (irq < 0) {
                        dev_err(dev, "no irq for gpio vbus pin\n");
+                       retval = irq;
                        goto err_gpio_claim;
                }
 
@@ -1948,8 +1949,6 @@ static int s3c2410_udc_remove(struct platform_device *pdev)
        iounmap(base_addr);
        release_mem_region(rsrc_start, rsrc_len);
 
-       platform_set_drvdata(pdev, NULL);
-
        if (!IS_ERR(udc_clock) && udc_clock != NULL) {
                clk_disable(udc_clock);
                clk_put(udc_clock);
index 2cd6262e8b7149a23d8458e76e5ef6ef3b919f1c..0deb9d6cde26245fd1c52c0b541eecd100aedce6 100644 (file)
@@ -284,12 +284,16 @@ static int __init zero_bind(struct usb_composite_dev *cdev)
        ss_opts->bulk_buflen = gzero_options.bulk_buflen;
 
        func_ss = usb_get_function(func_inst_ss);
-       if (IS_ERR(func_ss))
+       if (IS_ERR(func_ss)) {
+               status = PTR_ERR(func_ss);
                goto err_put_func_inst_ss;
+       }
 
        func_inst_lb = usb_get_function_instance("Loopback");
-       if (IS_ERR(func_inst_lb))
+       if (IS_ERR(func_inst_lb)) {
+               status = PTR_ERR(func_inst_lb);
                goto err_put_func_ss;
+       }
 
        lb_opts = container_of(func_inst_lb, struct f_lb_opts, func_inst);
        lb_opts->bulk_buflen = gzero_options.bulk_buflen;
index de94f2699063b12dd3c0cd1613a9cd2e37cd00c6..344d5e2f87d73a7234452a2b698f63b4959494e5 100644 (file)
@@ -507,7 +507,7 @@ endif # USB_OHCI_HCD
 
 config USB_UHCI_HCD
        tristate "UHCI HCD (most Intel and VIA) support"
-       depends on PCI || SPARC_LEON || ARCH_VT8500
+       depends on PCI || USB_UHCI_SUPPORT_NON_PCI_HC
        ---help---
          The Universal Host Controller Interface is a standard by Intel for
          accessing the USB hardware in the PC (which is also called the USB
@@ -524,26 +524,19 @@ config USB_UHCI_HCD
 
 config USB_UHCI_SUPPORT_NON_PCI_HC
        bool
-       depends on USB_UHCI_HCD
-       default y if (SPARC_LEON || ARCH_VT8500)
+       default y if (SPARC_LEON || USB_UHCI_PLATFORM)
 
 config USB_UHCI_PLATFORM
-       bool "Generic UHCI Platform Driver support"
-       depends on USB_UHCI_SUPPORT_NON_PCI_HC
+       bool
        default y if ARCH_VT8500
-       ---help---
-         Enable support for generic UHCI platform devices that require no
-         additional configuration.
 
 config USB_UHCI_BIG_ENDIAN_MMIO
        bool
-       depends on USB_UHCI_SUPPORT_NON_PCI_HC && SPARC_LEON
-       default y
+       default y if SPARC_LEON
 
 config USB_UHCI_BIG_ENDIAN_DESC
        bool
-       depends on USB_UHCI_SUPPORT_NON_PCI_HC && SPARC_LEON
-       default y
+       default y if SPARC_LEON
 
 config USB_FHCI_HCD
        tristate "Freescale QE USB Host Controller support"
index 66420097c24234eb3db9d09a656345cd80edcc9f..02f4611faa62c571a3a59ff4b33a35ead1966caf 100644 (file)
@@ -63,8 +63,6 @@ static void atmel_stop_ehci(struct platform_device *pdev)
 
 /*-------------------------------------------------------------------------*/
 
-static u64 at91_ehci_dma_mask = DMA_BIT_MASK(32);
-
 static int ehci_atmel_drv_probe(struct platform_device *pdev)
 {
        struct usb_hcd *hcd;
@@ -93,7 +91,9 @@ static int ehci_atmel_drv_probe(struct platform_device *pdev)
         * Once we have dma capability bindings this can go away.
         */
        if (!pdev->dev.dma_mask)
-               pdev->dev.dma_mask = &at91_ehci_dma_mask;
+               pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
+       if (!pdev->dev.coherent_dma_mask)
+               pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
 
        hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
        if (!hcd) {
index 312fc10da3c7aade0225cd126f28e372f1906058..246e124e6ac55c3dc66ba822a9b3f8ba5bebdd6a 100644 (file)
@@ -1286,23 +1286,6 @@ MODULE_LICENSE ("GPL");
 #define        PLATFORM_DRIVER         ehci_hcd_sead3_driver
 #endif
 
-#if !IS_ENABLED(CONFIG_USB_EHCI_PCI) && \
-       !IS_ENABLED(CONFIG_USB_EHCI_HCD_PLATFORM) && \
-       !IS_ENABLED(CONFIG_USB_CHIPIDEA_HOST) && \
-       !IS_ENABLED(CONFIG_USB_EHCI_MXC) && \
-       !IS_ENABLED(CONFIG_USB_EHCI_HCD_OMAP) && \
-       !IS_ENABLED(CONFIG_USB_EHCI_HCD_ORION) && \
-       !IS_ENABLED(CONFIG_USB_EHCI_HCD_SPEAR) && \
-       !IS_ENABLED(CONFIG_USB_EHCI_S5P) && \
-       !IS_ENABLED(CONFIG_USB_EHCI_HCD_AT91) && \
-       !IS_ENABLED(CONFIG_USB_EHCI_MSM) && \
-       !defined(PLATFORM_DRIVER) && \
-       !defined(PS3_SYSTEM_BUS_DRIVER) && \
-       !defined(OF_PLATFORM_DRIVER) && \
-       !defined(XILINX_OF_PLATFORM_DRIVER)
-#error "missing bus glue for ehci-hcd"
-#endif
-
 static int __init ehci_hcd_init(void)
 {
        int retval = 0;
index 3d1491b5f3605e68b0a72e1d5786233f5ad94d7b..16d7150e855722be6bc143c504d31120adf53f83 100644 (file)
@@ -90,8 +90,6 @@ static const struct ehci_driver_overrides ehci_omap_overrides __initdata = {
        .extra_priv_size = sizeof(struct omap_hcd),
 };
 
-static u64 omap_ehci_dma_mask = DMA_BIT_MASK(32);
-
 /**
  * ehci_hcd_omap_probe - initialize TI-based HCDs
  *
@@ -146,8 +144,10 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev)
         * Since shared usb code relies on it, set it here for now.
         * Once we have dma capability bindings this can go away.
         */
-       if (!pdev->dev.dma_mask)
-               pdev->dev.dma_mask = &omap_ehci_dma_mask;
+       if (!dev->dma_mask)
+               dev->dma_mask = &dev->coherent_dma_mask;
+       if (!dev->coherent_dma_mask)
+               dev->coherent_dma_mask = DMA_BIT_MASK(32);
 
        hcd = usb_create_hcd(&ehci_omap_hc_driver, dev,
                        dev_name(dev));
index 54c57948515051867df3dc8d218699ba6806e5ff..efbc588b48c50acbc2225c6be3f63ce1b1f35ffd 100644 (file)
@@ -137,8 +137,6 @@ ehci_orion_conf_mbus_windows(struct usb_hcd *hcd,
        }
 }
 
-static u64 ehci_orion_dma_mask = DMA_BIT_MASK(32);
-
 static int ehci_orion_drv_probe(struct platform_device *pdev)
 {
        struct orion_ehci_data *pd = pdev->dev.platform_data;
@@ -183,7 +181,9 @@ static int ehci_orion_drv_probe(struct platform_device *pdev)
         * now. Once we have dma capability bindings this can go away.
         */
        if (!pdev->dev.dma_mask)
-               pdev->dev.dma_mask = &ehci_orion_dma_mask;
+               pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
+       if (!pdev->dev.coherent_dma_mask)
+               pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
 
        if (!request_mem_region(res->start, resource_size(res),
                                ehci_orion_hc_driver.description)) {
index 635775278c7fec525a1a3566fce05bb77f3ad77e..379037f51a2fc41b7e7aaaf112a759ce70615ac5 100644 (file)
@@ -71,8 +71,6 @@ static void s5p_setup_vbus_gpio(struct platform_device *pdev)
                dev_err(dev, "can't request ehci vbus gpio %d", gpio);
 }
 
-static u64 ehci_s5p_dma_mask = DMA_BIT_MASK(32);
-
 static int s5p_ehci_probe(struct platform_device *pdev)
 {
        struct s5p_ehci_platdata *pdata = pdev->dev.platform_data;
@@ -90,7 +88,7 @@ static int s5p_ehci_probe(struct platform_device *pdev)
         * Once we move to full device tree support this will vanish off.
         */
        if (!pdev->dev.dma_mask)
-               pdev->dev.dma_mask = &ehci_s5p_dma_mask;
+               pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
        if (!pdev->dev.coherent_dma_mask)
                pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
 
@@ -107,6 +105,7 @@ static int s5p_ehci_probe(struct platform_device *pdev)
        if (IS_ERR(phy)) {
                /* Fallback to pdata */
                if (!pdata) {
+                       usb_put_hcd(hcd);
                        dev_warn(&pdev->dev, "no platform data or transceiver defined\n");
                        return -EPROBE_DEFER;
                } else {
index 61ecfb3d52f5d102f78d058fa5c032d37e0e7742..bd3e5cbc6240316dc5947f6f38dbc6a6c7492c51 100644 (file)
@@ -58,8 +58,6 @@ static int ehci_spear_drv_resume(struct device *dev)
 static SIMPLE_DEV_PM_OPS(ehci_spear_pm_ops, ehci_spear_drv_suspend,
                ehci_spear_drv_resume);
 
-static u64 spear_ehci_dma_mask = DMA_BIT_MASK(32);
-
 static int spear_ehci_hcd_drv_probe(struct platform_device *pdev)
 {
        struct usb_hcd *hcd ;
@@ -84,7 +82,9 @@ static int spear_ehci_hcd_drv_probe(struct platform_device *pdev)
         * Once we have dma capability bindings this can go away.
         */
        if (!pdev->dev.dma_mask)
-               pdev->dev.dma_mask = &spear_ehci_dma_mask;
+               pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
+       if (!pdev->dev.coherent_dma_mask)
+               pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
 
        usbh_clk = devm_clk_get(&pdev->dev, NULL);
        if (IS_ERR(usbh_clk)) {
index e3eddc31ac83fd4f2065a5815967700fa6932ef7..59d111bf44a9d961b45fc85b99d659a8a67230b4 100644 (file)
@@ -637,8 +637,6 @@ static void tegra_ehci_set_phcd(struct usb_phy *x, bool enable)
        writel(val, base + TEGRA_USB_PORTSC1);
 }
 
-static u64 tegra_ehci_dma_mask = DMA_BIT_MASK(32);
-
 static int tegra_ehci_probe(struct platform_device *pdev)
 {
        struct resource *res;
@@ -661,7 +659,9 @@ static int tegra_ehci_probe(struct platform_device *pdev)
         * Once we have dma capability bindings this can go away.
         */
        if (!pdev->dev.dma_mask)
-               pdev->dev.dma_mask = &tegra_ehci_dma_mask;
+               pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
+       if (!pdev->dev.coherent_dma_mask)
+               pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
 
        setup_vbus_gpio(pdev, pdata);
 
index 125e261f5bfca15be3d658f4cd976434c58b4912..2facee53eab16103af0a3abc0d67712f8ecc991f 100644 (file)
@@ -1739,7 +1739,7 @@ static int isp1760_hub_status_data(struct usb_hcd *hcd, char *buf)
        int retval = 1;
        unsigned long flags;
 
-       /* if !USB_SUSPEND, root hub timers won't get shut down ... */
+       /* if !PM_RUNTIME, root hub timers won't get shut down ... */
        if (!HC_IS_RUNNING(hcd->state))
                return 0;
 
index bbb791bd7617d6db99e064713ea95c527a83bfbf..a13709ee4e5d933bf4514df16296d66c7700ef17 100644 (file)
@@ -373,8 +373,10 @@ static int isp1760_plat_probe(struct platform_device *pdev)
        irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
        if (!irq_res) {
                pr_warning("isp1760: IRQ resource not available\n");
-               return -ENODEV;
+               ret = -ENODEV;
+               goto cleanup;
        }
+
        irqflags |= irq_res->flags & IRQF_TRIGGER_MASK;
 
        if (priv) {
index a0cb44f0e72420ad2c777f09818229a2a3f7c3c6..2ee1496dbc1d37c1f778d847712f78437abe21a4 100644 (file)
@@ -504,8 +504,6 @@ static const struct of_device_id at91_ohci_dt_ids[] = {
 
 MODULE_DEVICE_TABLE(of, at91_ohci_dt_ids);
 
-static u64 at91_ohci_dma_mask = DMA_BIT_MASK(32);
-
 static int ohci_at91_of_init(struct platform_device *pdev)
 {
        struct device_node *np = pdev->dev.of_node;
@@ -522,7 +520,9 @@ static int ohci_at91_of_init(struct platform_device *pdev)
         * Once we have dma capability bindings this can go away.
         */
        if (!pdev->dev.dma_mask)
-               pdev->dev.dma_mask = &at91_ohci_dma_mask;
+               pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
+       if (!pdev->dev.coherent_dma_mask)
+               pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
 
        pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
        if (!pdata)
index 07592c00af26ba166ad75280296c5364b19af9f2..b0b542c14e3132a9f35eceb86ef1255b676e13ca 100644 (file)
@@ -98,8 +98,6 @@ static const struct hc_driver exynos_ohci_hc_driver = {
        .start_port_reset       = ohci_start_port_reset,
 };
 
-static u64 ohci_exynos_dma_mask = DMA_BIT_MASK(32);
-
 static int exynos_ohci_probe(struct platform_device *pdev)
 {
        struct exynos4_ohci_platdata *pdata = pdev->dev.platform_data;
@@ -117,7 +115,7 @@ static int exynos_ohci_probe(struct platform_device *pdev)
         * Once we move to full device tree support this will vanish off.
         */
        if (!pdev->dev.dma_mask)
-               pdev->dev.dma_mask = &ohci_exynos_dma_mask;
+               pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
        if (!pdev->dev.coherent_dma_mask)
                pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
 
index 9e6de9586ae4bf82afb01f4c70464ffbbcd01117..fc627fd5411670369d89ba4aec7428b55e2fdef0 100644 (file)
@@ -233,14 +233,14 @@ static int ohci_urb_enqueue (
                        urb->start_frame = frame;
                }
        } else if (ed->type == PIPE_ISOCHRONOUS) {
-               u16     next = ohci_frame_no(ohci) + 2;
+               u16     next = ohci_frame_no(ohci) + 1;
                u16     frame = ed->last_iso + ed->interval;
 
                /* Behind the scheduling threshold? */
                if (unlikely(tick_before(frame, next))) {
 
                        /* USB_ISO_ASAP: Round up to the first available slot */
-                       if (urb->transfer_flags & URB_ISO_ASAP)
+                       if (urb->transfer_flags & URB_ISO_ASAP) {
                                frame += (next - frame + ed->interval - 1) &
                                                -ed->interval;
 
@@ -248,21 +248,25 @@ static int ohci_urb_enqueue (
                         * Not ASAP: Use the next slot in the stream.  If
                         * the entire URB falls before the threshold, fail.
                         */
-                       else if (tick_before(frame + ed->interval *
+                       } else {
+                               if (tick_before(frame + ed->interval *
                                        (urb->number_of_packets - 1), next)) {
-                               retval = -EXDEV;
-                               usb_hcd_unlink_urb_from_ep(hcd, urb);
-                               goto fail;
-                       }
+                                       retval = -EXDEV;
+                                       usb_hcd_unlink_urb_from_ep(hcd, urb);
+                                       goto fail;
+                               }
 
-                       /*
-                        * Some OHCI hardware doesn't handle late TDs
-                        * correctly.  After retiring them it proceeds to
-                        * the next ED instead of the next TD.  Therefore
-                        * we have to omit the late TDs entirely.
-                        */
-                       urb_priv->td_cnt = DIV_ROUND_UP(next - frame,
-                                       ed->interval);
+                               /*
+                                * Some OHCI hardware doesn't handle late TDs
+                                * correctly.  After retiring them it proceeds
+                                * to the next ED instead of the next TD.
+                                * Therefore we have to omit the late TDs
+                                * entirely.
+                                */
+                               urb_priv->td_cnt = DIV_ROUND_UP(
+                                               (u16) (next - frame),
+                                               ed->interval);
+                       }
                }
                urb->start_frame = frame;
        }
index f303cb04c2ddf6c791795401bc806b1015d2c49b..5d7eb72c506403b6e3022f14b09aa47e2c8a97c1 100644 (file)
@@ -223,8 +223,7 @@ static int usb_hcd_nxp_probe(struct platform_device *pdev)
 
        isp1301_i2c_client = isp1301_get_client(isp1301_node);
        if (!isp1301_i2c_client) {
-               ret = -EPROBE_DEFER;
-               goto out;
+               return -EPROBE_DEFER;
        }
 
        pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
@@ -234,7 +233,7 @@ static int usb_hcd_nxp_probe(struct platform_device *pdev)
        if (usb_disabled()) {
                dev_err(&pdev->dev, "USB is disabled\n");
                ret = -ENODEV;
-               goto out;
+               goto fail_disable;
        }
 
        /* Enable AHB slave USB clock, needed for further USB clock control */
@@ -245,19 +244,19 @@ static int usb_hcd_nxp_probe(struct platform_device *pdev)
        if (IS_ERR(usb_pll_clk)) {
                dev_err(&pdev->dev, "failed to acquire USB PLL\n");
                ret = PTR_ERR(usb_pll_clk);
-               goto out1;
+               goto fail_pll;
        }
 
        ret = clk_enable(usb_pll_clk);
        if (ret < 0) {
                dev_err(&pdev->dev, "failed to start USB PLL\n");
-               goto out2;
+               goto fail_pllen;
        }
 
        ret = clk_set_rate(usb_pll_clk, 48000);
        if (ret < 0) {
                dev_err(&pdev->dev, "failed to set USB clock rate\n");
-               goto out3;
+               goto fail_rate;
        }
 
        /* Enable USB device clock */
@@ -265,13 +264,13 @@ static int usb_hcd_nxp_probe(struct platform_device *pdev)
        if (IS_ERR(usb_dev_clk)) {
                dev_err(&pdev->dev, "failed to acquire USB DEV Clock\n");
                ret = PTR_ERR(usb_dev_clk);
-               goto out4;
+               goto fail_dev;
        }
 
        ret = clk_enable(usb_dev_clk);
        if (ret < 0) {
                dev_err(&pdev->dev, "failed to start USB DEV Clock\n");
-               goto out5;
+               goto fail_deven;
        }
 
        /* Enable USB otg clocks */
@@ -279,7 +278,7 @@ static int usb_hcd_nxp_probe(struct platform_device *pdev)
        if (IS_ERR(usb_otg_clk)) {
                dev_err(&pdev->dev, "failed to acquire USB DEV Clock\n");
                ret = PTR_ERR(usb_otg_clk);
-               goto out6;
+               goto fail_otg;
        }
 
        __raw_writel(__raw_readl(USB_CTRL) | USB_HOST_NEED_CLK_EN, USB_CTRL);
@@ -287,7 +286,7 @@ static int usb_hcd_nxp_probe(struct platform_device *pdev)
        ret = clk_enable(usb_otg_clk);
        if (ret < 0) {
                dev_err(&pdev->dev, "failed to start USB DEV Clock\n");
-               goto out7;
+               goto fail_otgen;
        }
 
        isp1301_configure();
@@ -296,14 +295,14 @@ static int usb_hcd_nxp_probe(struct platform_device *pdev)
        if (!hcd) {
                dev_err(&pdev->dev, "Failed to allocate HC buffer\n");
                ret = -ENOMEM;
-               goto out8;
+               goto fail_hcd;
        }
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        hcd->regs = devm_ioremap_resource(&pdev->dev, res);
        if (IS_ERR(hcd->regs)) {
                ret = PTR_ERR(hcd->regs);
-               goto out8;
+               goto fail_resource;
        }
        hcd->rsrc_start = res->start;
        hcd->rsrc_len = resource_size(res);
@@ -311,7 +310,7 @@ static int usb_hcd_nxp_probe(struct platform_device *pdev)
        irq = platform_get_irq(pdev, 0);
        if (irq < 0) {
                ret = -ENXIO;
-               goto out8;
+               goto fail_resource;
        }
 
        nxp_start_hc();
@@ -325,23 +324,24 @@ static int usb_hcd_nxp_probe(struct platform_device *pdev)
                return ret;
 
        nxp_stop_hc();
-out8:
+fail_resource:
        usb_put_hcd(hcd);
-out7:
+fail_hcd:
        clk_disable(usb_otg_clk);
-out6:
+fail_otgen:
        clk_put(usb_otg_clk);
-out5:
+fail_otg:
        clk_disable(usb_dev_clk);
-out4:
+fail_deven:
        clk_put(usb_dev_clk);
-out3:
+fail_dev:
+fail_rate:
        clk_disable(usb_pll_clk);
-out2:
+fail_pllen:
        clk_put(usb_pll_clk);
-out1:
+fail_pll:
+fail_disable:
        isp1301_i2c_client = NULL;
-out:
        return ret;
 }
 
index ddfc31427bc09e1fc95c63ea40f006ad00631e66..8663851c8d8eac79b5d358d9e6f81f6116d5fc41 100644 (file)
@@ -114,8 +114,6 @@ static const struct hc_driver ohci_omap3_hc_driver = {
 
 /*-------------------------------------------------------------------------*/
 
-static u64 omap_ohci_dma_mask = DMA_BIT_MASK(32);
-
 /*
  * configure so an HC device and id are always provided
  * always called with process context; sleeping is OK
@@ -168,8 +166,10 @@ static int ohci_hcd_omap3_probe(struct platform_device *pdev)
         * Since shared usb code relies on it, set it here for now.
         * Once we have dma capability bindings this can go away.
         */
-       if (!pdev->dev.dma_mask)
-               pdev->dev.dma_mask = &omap_ohci_dma_mask;
+       if (!dev->dma_mask)
+               dev->dma_mask = &dev->coherent_dma_mask;
+       if (!dev->coherent_dma_mask)
+               dev->coherent_dma_mask = DMA_BIT_MASK(32);
 
        hcd = usb_create_hcd(&ohci_omap3_hc_driver, dev,
                        dev_name(dev));
index efe71f3ca4772068c557b3063f33cd247a0e19df..279b2ef1741149fe05deda764c09151763f56f1d 100644 (file)
@@ -282,8 +282,6 @@ static const struct of_device_id pxa_ohci_dt_ids[] = {
 
 MODULE_DEVICE_TABLE(of, pxa_ohci_dt_ids);
 
-static u64 pxa_ohci_dma_mask = DMA_BIT_MASK(32);
-
 static int ohci_pxa_of_init(struct platform_device *pdev)
 {
        struct device_node *np = pdev->dev.of_node;
@@ -298,7 +296,9 @@ static int ohci_pxa_of_init(struct platform_device *pdev)
         * Once we have dma capability bindings this can go away.
         */
        if (!pdev->dev.dma_mask)
-               pdev->dev.dma_mask = &pxa_ohci_dma_mask;
+               pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
+       if (!pdev->dev.coherent_dma_mask)
+               pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
 
        pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
        if (!pdata)
index 9020bf0e2eca13f8837aa46ab8c5ee55969c8b49..3e19e0170d1195711b4f235fd4be043fb234d65e 100644 (file)
@@ -91,8 +91,6 @@ static const struct hc_driver ohci_spear_hc_driver = {
        .start_port_reset       = ohci_start_port_reset,
 };
 
-static u64 spear_ohci_dma_mask = DMA_BIT_MASK(32);
-
 static int spear_ohci_hcd_drv_probe(struct platform_device *pdev)
 {
        const struct hc_driver *driver = &ohci_spear_hc_driver;
@@ -114,7 +112,9 @@ static int spear_ohci_hcd_drv_probe(struct platform_device *pdev)
         * Once we have dma capability bindings this can go away.
         */
        if (!pdev->dev.dma_mask)
-               pdev->dev.dma_mask = &spear_ohci_dma_mask;
+               pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
+       if (!pdev->dev.coherent_dma_mask)
+               pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
 
        usbh_clk = devm_clk_get(&pdev->dev, NULL);
        if (IS_ERR(usbh_clk)) {
index 4f0f0339532f7e2729fe90f6972301ec32116041..0f401dbfaf073bb59f7faad445a19663bded3a0e 100644 (file)
@@ -3084,7 +3084,7 @@ static int oxu_hub_status_data(struct usb_hcd *hcd, char *buf)
        int ports, i, retval = 1;
        unsigned long flags;
 
-       /* if !USB_SUSPEND, root hub timers won't get shut down ... */
+       /* if !PM_RUNTIME, root hub timers won't get shut down ... */
        if (!HC_IS_RUNNING(hcd->state))
                return 0;
 
index ad4483efb6d602cad2a841d8747b5983c16fc33c..b2ec7fe758ddcf3dba22f922493ca6cebdeaea10 100644 (file)
@@ -22,7 +22,7 @@
  * and usb-storage.
  *
  * TODO:
- * - usb suspend/resume triggered by sl811 (with USB_SUSPEND)
+ * - usb suspend/resume triggered by sl811 (with PM_RUNTIME)
  * - various issues noted in the code
  * - performance work; use both register banks; ...
  * - use urb->iso_frame_desc[] with ISO transfers
index f87bee6d2789256fc8c8dcdde71a6e4510108397..9189bc984c98ce9804d51ec94c4aebe4147b8f3f 100644 (file)
@@ -225,7 +225,8 @@ static int uhci_hub_status_data(struct usb_hcd *hcd, char *buf)
                /* auto-stop if nothing connected for 1 second */
                if (any_ports_active(uhci))
                        uhci->rh_state = UHCI_RH_RUNNING;
-               else if (time_after_eq(jiffies, uhci->auto_stop_time))
+               else if (time_after_eq(jiffies, uhci->auto_stop_time) &&
+                               !uhci->wait_for_hp)
                        suspend_rh(uhci, UHCI_RH_AUTO_STOPPED);
                break;
 
index 8c4dace4b14a5c0455a79b389347cdfab640bd05..f1db61ada6a84c435aedc3967f04f8aab76c1e55 100644 (file)
@@ -60,8 +60,6 @@ static const struct hc_driver uhci_platform_hc_driver = {
        .hub_control =          uhci_hub_control,
 };
 
-static u64 platform_uhci_dma_mask = DMA_BIT_MASK(32);
-
 static int uhci_hcd_platform_probe(struct platform_device *pdev)
 {
        struct usb_hcd *hcd;
@@ -78,7 +76,9 @@ static int uhci_hcd_platform_probe(struct platform_device *pdev)
         * Once we have dma capability bindings this can go away.
         */
        if (!pdev->dev.dma_mask)
-               pdev->dev.dma_mask = &platform_uhci_dma_mask;
+               pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
+       if (!pdev->dev.coherent_dma_mask)
+               pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
 
        hcd = usb_create_hcd(&uhci_platform_hc_driver, &pdev->dev,
                        pdev->name);
index f0976d8190bc363b52d908540de8214fbeed43b8..041c6ddb695c8ec6fa17d371fe7904de2e47d5ab 100644 (file)
@@ -1287,7 +1287,7 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb,
                return -EINVAL;         /* Can't change the period */
 
        } else {
-               next = uhci->frame_number + 2;
+               next = uhci->frame_number + 1;
 
                /* Find the next unused frame */
                if (list_empty(&qh->queue)) {
index 965b539bc47410721c9021f41eb7bf051dcc8feb..2cfc465925bd9c8f67ddd8778957d86f6561a43a 100644 (file)
@@ -1423,15 +1423,17 @@ int xhci_endpoint_init(struct xhci_hcd *xhci,
        ep_ctx->ep_info2 |= cpu_to_le32(xhci_get_endpoint_type(udev, ep));
 
        /* Set the max packet size and max burst */
+       max_packet = GET_MAX_PACKET(usb_endpoint_maxp(&ep->desc));
+       max_burst = 0;
        switch (udev->speed) {
        case USB_SPEED_SUPER:
-               max_packet = usb_endpoint_maxp(&ep->desc);
-               ep_ctx->ep_info2 |= cpu_to_le32(MAX_PACKET(max_packet));
                /* dig out max burst from ep companion desc */
-               max_packet = ep->ss_ep_comp.bMaxBurst;
-               ep_ctx->ep_info2 |= cpu_to_le32(MAX_BURST(max_packet));
+               max_burst = ep->ss_ep_comp.bMaxBurst;
                break;
        case USB_SPEED_HIGH:
+               /* Some devices get this wrong */
+               if (usb_endpoint_xfer_bulk(&ep->desc))
+                       max_packet = 512;
                /* bits 11:12 specify the number of additional transaction
                 * opportunities per microframe (USB 2.0, section 9.6.6)
                 */
@@ -1439,17 +1441,16 @@ int xhci_endpoint_init(struct xhci_hcd *xhci,
                                usb_endpoint_xfer_int(&ep->desc)) {
                        max_burst = (usb_endpoint_maxp(&ep->desc)
                                     & 0x1800) >> 11;
-                       ep_ctx->ep_info2 |= cpu_to_le32(MAX_BURST(max_burst));
                }
-               /* Fall through */
+               break;
        case USB_SPEED_FULL:
        case USB_SPEED_LOW:
-               max_packet = GET_MAX_PACKET(usb_endpoint_maxp(&ep->desc));
-               ep_ctx->ep_info2 |= cpu_to_le32(MAX_PACKET(max_packet));
                break;
        default:
                BUG();
        }
+       ep_ctx->ep_info2 |= cpu_to_le32(MAX_PACKET(max_packet) |
+                       MAX_BURST(max_burst));
        max_esit_payload = xhci_get_max_esit_payload(xhci, udev, ep);
        ep_ctx->tx_info = cpu_to_le32(MAX_ESIT_PAYLOAD_FOR_EP(max_esit_payload));
 
index 3a18e44e9391850ab7f7ee7858cd6d134b59361e..e1b661d040217a3cdd0e76b325616f85adc04bd6 100644 (file)
@@ -560,6 +560,7 @@ static int dsps_create_musb_pdev(struct dsps_glue *glue, u8 id)
                if (!config) {
                        dev_err(&pdev->dev,
                                "failed to allocate musb hdrc config\n");
+                       ret = -ENOMEM;
                        goto err2;
                }
 
index 3551f1a30c655efdc2977556e9e4f6c540ea115a..628b93fe5cccf585d21759fa112086a345a2e92a 100644 (file)
@@ -549,7 +549,8 @@ static int omap2430_probe(struct platform_device *pdev)
                glue->control_otghs = omap_get_control_dev();
                if (IS_ERR(glue->control_otghs)) {
                        dev_vdbg(&pdev->dev, "Failed to get control device\n");
-                       return -ENODEV;
+                       ret = PTR_ERR(glue->control_otghs);
+                       goto err2;
                }
        } else {
                glue->control_otghs = ERR_PTR(-ENODEV);
index 371d0e74e9094132eb378366858dedd7e654d89f..7ef3eb8617a6c7adc7775bc76a5fb0fd3d699ef8 100644 (file)
@@ -25,7 +25,7 @@ config AB8500_USB
 
 config FSL_USB2_OTG
        bool "Freescale USB OTG Transceiver Driver"
-       depends on USB_EHCI_FSL && USB_FSL_USB2 && USB_SUSPEND
+       depends on USB_EHCI_FSL && USB_FSL_USB2 && PM_RUNTIME
        select USB_OTG
        help
          Enable this to support Freescale USB OTG transceiver.
@@ -139,7 +139,6 @@ config USB_ISP1301
        tristate "NXP ISP1301 USB transceiver support"
        depends on USB || USB_GADGET
        depends on I2C
-       select USB_OTG_UTILS
        help
          Say Y here to add support for the NXP ISP1301 USB transceiver driver.
          This chip is typically used as USB transceiver for USB host, gadget
@@ -162,7 +161,7 @@ config USB_MSM_OTG
 
 config USB_MV_OTG
        tristate "Marvell USB OTG support"
-       depends on USB_EHCI_MV && USB_MV_UDC && USB_SUSPEND
+       depends on USB_EHCI_MV && USB_MV_UDC && PM_RUNTIME
        select USB_OTG
        help
          Say Y here if you want to build Marvell USB OTG transciever
index 4acef26a2ef5c2daa5b7a163e2afd297903e9642..e5eb1b5a04ebb815ffd46be5c1ab48b2fb8ed193 100644 (file)
@@ -892,8 +892,6 @@ static int ab8500_usb_remove(struct platform_device *pdev)
        else if (ab->mode == USB_PERIPHERAL)
                ab8500_usb_peri_phy_dis(ab);
 
-       platform_set_drvdata(pdev, NULL);
-
        return 0;
 }
 
index 97b9308507c3dae718828645a79069c6af2de46e..e771bafb9f1da3375f9f0492493c973fe0862484 100644 (file)
@@ -799,6 +799,7 @@ static int fsl_otg_conf(struct platform_device *pdev)
 
        /* initialize the otg structure */
        fsl_otg_tc->phy.label = DRIVER_DESC;
+       fsl_otg_tc->phy.dev = &pdev->dev;
        fsl_otg_tc->phy.set_power = fsl_otg_set_power;
 
        fsl_otg_tc->phy.otg->phy = &fsl_otg_tc->phy;
index 4c76074e518d56f60c192f560dfc7a3d049de301..8443335c2ea0260414ea183fe69c809b5b328d64 100644 (file)
@@ -266,6 +266,7 @@ static int __init gpio_vbus_probe(struct platform_device *pdev)
        platform_set_drvdata(pdev, gpio_vbus);
        gpio_vbus->dev = &pdev->dev;
        gpio_vbus->phy.label = "gpio-vbus";
+       gpio_vbus->phy.dev = gpio_vbus->dev;
        gpio_vbus->phy.set_power = gpio_vbus_set_power;
        gpio_vbus->phy.set_suspend = gpio_vbus_set_suspend;
        gpio_vbus->phy.state = OTG_STATE_UNDEFINED;
@@ -343,7 +344,6 @@ err_irq:
                gpio_free(pdata->gpio_pullup);
        gpio_free(pdata->gpio_vbus);
 err_gpio:
-       platform_set_drvdata(pdev, NULL);
        kfree(gpio_vbus->phy.otg);
        kfree(gpio_vbus);
        return err;
@@ -365,7 +365,6 @@ static int __exit gpio_vbus_remove(struct platform_device *pdev)
        if (gpio_is_valid(pdata->gpio_pullup))
                gpio_free(pdata->gpio_pullup);
        gpio_free(gpio);
-       platform_set_drvdata(pdev, NULL);
        kfree(gpio_vbus->phy.otg);
        kfree(gpio_vbus);
 
index 225ae6c97eeb4758945cc08b558bdd27ddc7822d..8a55b37d1a024687f6be8078ef4f54f60cdc5111 100644 (file)
@@ -102,6 +102,7 @@ static int isp1301_probe(struct i2c_client *client,
        mutex_init(&isp->mutex);
 
        phy = &isp->phy;
+       phy->dev = &client->dev;
        phy->label = DRV_NAME;
        phy->init = isp1301_phy_init;
        phy->set_vbus = isp1301_phy_set_vbus;
index c987bbe278519c04bfc2e390dd59dd0ba6a8be60..4a6b03c738765814adc2eefe6bbbdef6eba8bf0b 100644 (file)
@@ -667,7 +667,6 @@ int mv_otg_remove(struct platform_device *pdev)
        mv_otg_disable(mvotg);
 
        usb_remove_phy(&mvotg->phy);
-       platform_set_drvdata(pdev, NULL);
 
        return 0;
 }
@@ -850,8 +849,6 @@ err_destroy_workqueue:
        flush_workqueue(mvotg->qwork);
        destroy_workqueue(mvotg->qwork);
 
-       platform_set_drvdata(pdev, NULL);
-
        return retval;
 }
 
index eb25dd2a14292f95f36ddbcb4fa712fd8aecea7e..bd601c537c8d434a3e33a7aa59d88d583472244f 100644 (file)
@@ -155,6 +155,7 @@ static int mxs_phy_probe(struct platform_device *pdev)
        mxs_phy->phy.set_suspend        = mxs_phy_suspend;
        mxs_phy->phy.notify_connect     = mxs_phy_on_connect;
        mxs_phy->phy.notify_disconnect  = mxs_phy_on_disconnect;
+       mxs_phy->phy.type               = USB_PHY_TYPE_USB2;
 
        ATOMIC_INIT_NOTIFIER_HEAD(&mxs_phy->phy.notifier);
 
@@ -175,8 +176,6 @@ static int mxs_phy_remove(struct platform_device *pdev)
 
        usb_remove_phy(&mxs_phy->phy);
 
-       platform_set_drvdata(pdev, NULL);
-
        return 0;
 }
 
index 2b10cc969bbb1f4457a463c2072508953a42fdc2..638cc5dade35227732e77e6c5ccb0d769eb47d8b 100644 (file)
@@ -254,8 +254,6 @@ static int nop_usb_xceiv_remove(struct platform_device *pdev)
 
        usb_remove_phy(&nop->phy);
 
-       platform_set_drvdata(pdev, NULL);
-
        return 0;
 }
 
index 242b5776648ab31c1e820bcc82dad0a48c629775..7260ec66034715e7a065d0f5fe6441f49a37f6b4 100644 (file)
@@ -189,6 +189,8 @@ static struct usb_device_id id_table_combined [] = {
        { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_GBM_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_GBM_BOOST_PID) },
        { USB_DEVICE(NEWPORT_VID, NEWPORT_AGILIS_PID) },
+       { USB_DEVICE(NEWPORT_VID, NEWPORT_CONEX_CC_PID) },
+       { USB_DEVICE(NEWPORT_VID, NEWPORT_CONEX_AGP_PID) },
        { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_IOBOARD_PID) },
        { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_MINI_IOBOARD_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_SPROG_II) },
@@ -924,8 +926,8 @@ static int  ftdi_tiocmset(struct tty_struct *tty,
 static int  ftdi_ioctl(struct tty_struct *tty,
                        unsigned int cmd, unsigned long arg);
 static void ftdi_break_ctl(struct tty_struct *tty, int break_state);
-static int ftdi_chars_in_buffer(struct tty_struct *tty);
-static int ftdi_get_modem_status(struct tty_struct *tty,
+static bool ftdi_tx_empty(struct usb_serial_port *port);
+static int ftdi_get_modem_status(struct usb_serial_port *port,
                                                unsigned char status[2]);
 
 static unsigned short int ftdi_232am_baud_base_to_divisor(int baud, int base);
@@ -961,7 +963,7 @@ static struct usb_serial_driver ftdi_sio_device = {
        .ioctl =                ftdi_ioctl,
        .set_termios =          ftdi_set_termios,
        .break_ctl =            ftdi_break_ctl,
-       .chars_in_buffer =      ftdi_chars_in_buffer,
+       .tx_empty =             ftdi_tx_empty,
 };
 
 static struct usb_serial_driver * const serial_drivers[] = {
@@ -2056,27 +2058,18 @@ static void ftdi_break_ctl(struct tty_struct *tty, int break_state)
 
 }
 
-static int ftdi_chars_in_buffer(struct tty_struct *tty)
+static bool ftdi_tx_empty(struct usb_serial_port *port)
 {
-       struct usb_serial_port *port = tty->driver_data;
-       int chars;
        unsigned char buf[2];
        int ret;
 
-       chars = usb_serial_generic_chars_in_buffer(tty);
-       if (chars)
-               goto out;
-
-       /* Check if hardware buffer is empty. */
-       ret = ftdi_get_modem_status(tty, buf);
+       ret = ftdi_get_modem_status(port, buf);
        if (ret == 2) {
                if (!(buf[1] & FTDI_RS_TEMT))
-                       chars = 1;
+                       return false;
        }
-out:
-       dev_dbg(&port->dev, "%s - %d\n", __func__, chars);
 
-       return chars;
+       return true;
 }
 
 /* old_termios contains the original termios settings and tty->termios contains
@@ -2268,10 +2261,9 @@ no_c_cflag_changes:
  * Returns the number of status bytes retrieved (device dependant), or
  * negative error code.
  */
-static int ftdi_get_modem_status(struct tty_struct *tty,
+static int ftdi_get_modem_status(struct usb_serial_port *port,
                                                unsigned char status[2])
 {
-       struct usb_serial_port *port = tty->driver_data;
        struct ftdi_private *priv = usb_get_serial_port_data(port);
        unsigned char *buf;
        int len;
@@ -2336,7 +2328,7 @@ static int ftdi_tiocmget(struct tty_struct *tty)
        unsigned char buf[2];
        int ret;
 
-       ret = ftdi_get_modem_status(tty, buf);
+       ret = ftdi_get_modem_status(port, buf);
        if (ret < 0)
                return ret;
 
index 98528270c43c21f5f8d66ccf594a269b32f0600f..6dd79253205dd7ec54278ddb078f08346cdbb4f8 100644 (file)
  */
 #define NEWPORT_VID                    0x104D
 #define NEWPORT_AGILIS_PID             0x3000
+#define NEWPORT_CONEX_CC_PID           0x3002
+#define NEWPORT_CONEX_AGP_PID          0x3006
 
 /* Interbiometrics USB I/O Board */
 /* Developed for Interbiometrics by Rudolf Gugler */
index 297665fdd16d31993a5e95cddd313626453be6c7..ba45170c78e5f601ec6b2c57f5f05600247803f4 100644 (file)
@@ -253,6 +253,37 @@ int usb_serial_generic_chars_in_buffer(struct tty_struct *tty)
 }
 EXPORT_SYMBOL_GPL(usb_serial_generic_chars_in_buffer);
 
+void usb_serial_generic_wait_until_sent(struct tty_struct *tty, long timeout)
+{
+       struct usb_serial_port *port = tty->driver_data;
+       unsigned int bps;
+       unsigned long period;
+       unsigned long expire;
+
+       bps = tty_get_baud_rate(tty);
+       if (!bps)
+               bps = 9600;     /* B0 */
+       /*
+        * Use a poll-period of roughly the time it takes to send one
+        * character or at least one jiffy.
+        */
+       period = max_t(unsigned long, (10 * HZ / bps), 1);
+       period = min_t(unsigned long, period, timeout);
+
+       dev_dbg(&port->dev, "%s - timeout = %u ms, period = %u ms\n",
+                                       __func__, jiffies_to_msecs(timeout),
+                                       jiffies_to_msecs(period));
+       expire = jiffies + timeout;
+       while (!port->serial->type->tx_empty(port)) {
+               schedule_timeout_interruptible(period);
+               if (signal_pending(current))
+                       break;
+               if (time_after(jiffies, expire))
+                       break;
+       }
+}
+EXPORT_SYMBOL_GPL(usb_serial_generic_wait_until_sent);
+
 static int usb_serial_generic_submit_read_urb(struct usb_serial_port *port,
                                                int index, gfp_t mem_flags)
 {
index 158bf4bc29cc2b6f60c7211ad0e9f8b75186bf04..1be6ba7bee27452ac55c08a06d98ff2394a2f7fb 100644 (file)
@@ -2019,8 +2019,6 @@ static int edge_chars_in_buffer(struct tty_struct *tty)
        struct edgeport_port *edge_port = usb_get_serial_port_data(port);
        int chars = 0;
        unsigned long flags;
-       int ret;
-
        if (edge_port == NULL)
                return 0;
 
@@ -2028,16 +2026,22 @@ static int edge_chars_in_buffer(struct tty_struct *tty)
        chars = kfifo_len(&edge_port->write_fifo);
        spin_unlock_irqrestore(&edge_port->ep_lock, flags);
 
-       if (!chars) {
-               ret = tx_active(edge_port);
-               if (ret > 0)
-                       chars = ret;
-       }
-
        dev_dbg(&port->dev, "%s - returns %d\n", __func__, chars);
        return chars;
 }
 
+static bool edge_tx_empty(struct usb_serial_port *port)
+{
+       struct edgeport_port *edge_port = usb_get_serial_port_data(port);
+       int ret;
+
+       ret = tx_active(edge_port);
+       if (ret > 0)
+               return false;
+
+       return true;
+}
+
 static void edge_throttle(struct tty_struct *tty)
 {
        struct usb_serial_port *port = tty->driver_data;
@@ -2557,6 +2561,7 @@ static struct usb_serial_driver edgeport_1port_device = {
        .write                  = edge_write,
        .write_room             = edge_write_room,
        .chars_in_buffer        = edge_chars_in_buffer,
+       .tx_empty               = edge_tx_empty,
        .break_ctl              = edge_break,
        .read_int_callback      = edge_interrupt_callback,
        .read_bulk_callback     = edge_bulk_in_callback,
@@ -2589,6 +2594,7 @@ static struct usb_serial_driver edgeport_2port_device = {
        .write                  = edge_write,
        .write_room             = edge_write_room,
        .chars_in_buffer        = edge_chars_in_buffer,
+       .tx_empty               = edge_tx_empty,
        .break_ctl              = edge_break,
        .read_int_callback      = edge_interrupt_callback,
        .read_bulk_callback     = edge_bulk_in_callback,
index 734372846abbb31b1381841f4f144a09a4f0b2a0..93d02bc4eb52f19dfa0a780e209be5aee84a885f 100644 (file)
@@ -196,6 +196,7 @@ static void option_instat_callback(struct urb *urb);
 
 #define DELL_PRODUCT_5800_MINICARD_VZW         0x8195  /* Novatel E362 */
 #define DELL_PRODUCT_5800_V2_MINICARD_VZW      0x8196  /* Novatel E362 */
+#define DELL_PRODUCT_5804_MINICARD_ATT         0x819b  /* Novatel E371 */
 
 #define KYOCERA_VENDOR_ID                      0x0c88
 #define KYOCERA_PRODUCT_KPC650                 0x17da
@@ -341,8 +342,8 @@ static void option_instat_callback(struct urb *urb);
 #define CINTERION_PRODUCT_EU3_E                        0x0051
 #define CINTERION_PRODUCT_EU3_P                        0x0052
 #define CINTERION_PRODUCT_PH8                  0x0053
-#define CINTERION_PRODUCT_AH                 0x0055
-#define CINTERION_PRODUCT_PLS8                 0x0060
+#define CINTERION_PRODUCT_AHXX                 0x0055
+#define CINTERION_PRODUCT_PLXX                 0x0060
 
 /* Olivetti products */
 #define OLIVETTI_VENDOR_ID                     0x0b3c
@@ -771,6 +772,7 @@ static const struct usb_device_id option_ids[] = {
        { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_VZW) },         /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */
        { USB_DEVICE_AND_INTERFACE_INFO(DELL_VENDOR_ID, DELL_PRODUCT_5800_MINICARD_VZW, 0xff, 0xff, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(DELL_VENDOR_ID, DELL_PRODUCT_5800_V2_MINICARD_VZW, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(DELL_VENDOR_ID, DELL_PRODUCT_5804_MINICARD_ATT, 0xff, 0xff, 0xff) },
        { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) },   /* ADU-E100, ADU-310 */
        { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) },
        { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_620UW) },
@@ -966,6 +968,8 @@ static const struct usb_device_id option_ids[] = {
          .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0330, 0xff, 0xff, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0395, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0412, 0xff, 0xff, 0xff), /* Telewell TW-LTE 4G */
+         .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0414, 0xff, 0xff, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0417, 0xff, 0xff, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1008, 0xff, 0xff, 0xff),
@@ -1264,8 +1268,9 @@ static const struct usb_device_id option_ids[] = {
        { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_EU3_E) },
        { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_EU3_P) },
        { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PH8) },
-       { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_AH6) },
-       { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PLS8) },
+       { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_AHXX) },
+       { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PLXX),
+               .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
        { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_HC28_MDM) }, 
        { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_HC28_MDMNET) },
        { USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC25_MDM) },
index cac47aef2918972ead4aeb01a43bd9166daec0ca..c92c5ed4e580ec6761d0acabc379cfe667faaeb1 100644 (file)
@@ -101,6 +101,7 @@ static int ti_write(struct tty_struct *tty, struct usb_serial_port *port,
                const unsigned char *data, int count);
 static int ti_write_room(struct tty_struct *tty);
 static int ti_chars_in_buffer(struct tty_struct *tty);
+static bool ti_tx_empty(struct usb_serial_port *port);
 static void ti_throttle(struct tty_struct *tty);
 static void ti_unthrottle(struct tty_struct *tty);
 static int ti_ioctl(struct tty_struct *tty,
@@ -222,6 +223,7 @@ static struct usb_serial_driver ti_1port_device = {
        .write                  = ti_write,
        .write_room             = ti_write_room,
        .chars_in_buffer        = ti_chars_in_buffer,
+       .tx_empty               = ti_tx_empty,
        .throttle               = ti_throttle,
        .unthrottle             = ti_unthrottle,
        .ioctl                  = ti_ioctl,
@@ -253,6 +255,7 @@ static struct usb_serial_driver ti_2port_device = {
        .write                  = ti_write,
        .write_room             = ti_write_room,
        .chars_in_buffer        = ti_chars_in_buffer,
+       .tx_empty               = ti_tx_empty,
        .throttle               = ti_throttle,
        .unthrottle             = ti_unthrottle,
        .ioctl                  = ti_ioctl,
@@ -684,8 +687,6 @@ static int ti_chars_in_buffer(struct tty_struct *tty)
        struct ti_port *tport = usb_get_serial_port_data(port);
        int chars = 0;
        unsigned long flags;
-       int ret;
-       u8 lsr;
 
        if (tport == NULL)
                return 0;
@@ -694,16 +695,22 @@ static int ti_chars_in_buffer(struct tty_struct *tty)
        chars = kfifo_len(&tport->write_fifo);
        spin_unlock_irqrestore(&tport->tp_lock, flags);
 
-       if (!chars) {
-               ret = ti_get_lsr(tport, &lsr);
-               if (!ret && !(lsr & TI_LSR_TX_EMPTY))
-                       chars = 1;
-       }
-
        dev_dbg(&port->dev, "%s - returns %d\n", __func__, chars);
        return chars;
 }
 
+static bool ti_tx_empty(struct usb_serial_port *port)
+{
+       struct ti_port *tport = usb_get_serial_port_data(port);
+       int ret;
+       u8 lsr;
+
+       ret = ti_get_lsr(tport, &lsr);
+       if (!ret && !(lsr & TI_LSR_TX_EMPTY))
+               return false;
+
+       return true;
+}
 
 static void ti_throttle(struct tty_struct *tty)
 {
index cf75beb1251bc85b3c709b989e1ddd5220094c7c..4753c005cfb6f8fffc5ff45999d7e89348c7f96f 100644 (file)
@@ -359,20 +359,29 @@ static int serial_chars_in_buffer(struct tty_struct *tty)
 {
        struct usb_serial_port *port = tty->driver_data;
        struct usb_serial *serial = port->serial;
-       int count = 0;
 
        dev_dbg(tty->dev, "%s\n", __func__);
 
-       mutex_lock(&serial->disc_mutex);
-       /* if the device was unplugged then any remaining characters
-          fell out of the connector ;) */
        if (serial->disconnected)
-               count = 0;
-       else
-               count = serial->type->chars_in_buffer(tty);
-       mutex_unlock(&serial->disc_mutex);
+               return 0;
+
+       return serial->type->chars_in_buffer(tty);
+}
+
+static void serial_wait_until_sent(struct tty_struct *tty, int timeout)
+{
+       struct usb_serial_port *port = tty->driver_data;
+       struct usb_serial *serial = port->serial;
+
+       dev_dbg(tty->dev, "%s\n", __func__);
+
+       if (!port->serial->type->wait_until_sent)
+               return;
 
-       return count;
+       mutex_lock(&serial->disc_mutex);
+       if (!serial->disconnected)
+               port->serial->type->wait_until_sent(tty, timeout);
+       mutex_unlock(&serial->disc_mutex);
 }
 
 static void serial_throttle(struct tty_struct *tty)
@@ -1191,6 +1200,7 @@ static const struct tty_operations serial_ops = {
        .unthrottle =           serial_unthrottle,
        .break_ctl =            serial_break,
        .chars_in_buffer =      serial_chars_in_buffer,
+       .wait_until_sent =      serial_wait_until_sent,
        .tiocmget =             serial_tiocmget,
        .tiocmset =             serial_tiocmset,
        .get_icount =           serial_get_icount,
@@ -1316,6 +1326,8 @@ static void usb_serial_operations_init(struct usb_serial_driver *device)
        set_to_generic_if_null(device, close);
        set_to_generic_if_null(device, write_room);
        set_to_generic_if_null(device, chars_in_buffer);
+       if (device->tx_empty)
+               set_to_generic_if_null(device, wait_until_sent);
        set_to_generic_if_null(device, read_bulk_callback);
        set_to_generic_if_null(device, write_bulk_callback);
        set_to_generic_if_null(device, process_read_urb);
index 8623577bbbe70d608eb0866f18be56c20513a5bf..281be56d56485535eaef90e890bb2bfebb30ad00 100644 (file)
@@ -105,8 +105,9 @@ struct rts51x_chip {
        int status_len;
 
        u32 flag;
-#ifdef CONFIG_REALTEK_AUTOPM
        struct us_data *us;
+
+#ifdef CONFIG_REALTEK_AUTOPM
        struct timer_list rts51x_suspend_timer;
        unsigned long timer_expires;
        int pwr_state;
@@ -988,6 +989,7 @@ static int init_realtek_cr(struct us_data *us)
        us->extra = chip;
        us->extra_destructor = realtek_cr_destructor;
        us->max_lun = chip->max_lun = rts51x_get_max_lun(us);
+       chip->us = us;
 
        usb_stor_dbg(us, "chip->max_lun = %d\n", chip->max_lun);
 
@@ -1010,10 +1012,8 @@ static int init_realtek_cr(struct us_data *us)
                        SET_AUTO_DELINK(chip);
        }
 #ifdef CONFIG_REALTEK_AUTOPM
-       if (ss_en) {
-               chip->us = us;
+       if (ss_en)
                realtek_cr_autosuspend_setup(us);
-       }
 #endif
 
        usb_stor_dbg(us, "chip->flag = 0x%x\n", chip->flag);
index d71d60f94fc19a7fcc34ace0940dfb841e9904fc..2e937bdace6f123a1b6f1c0c055b4422dde78875 100644 (file)
@@ -2199,7 +2199,7 @@ config FB_XILINX
 
 config FB_GOLDFISH
        tristate "Goldfish Framebuffer"
-       depends on FB
+       depends on FB && HAS_DMA
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
@@ -2453,6 +2453,23 @@ config FB_HYPERV
        help
          This framebuffer driver supports Microsoft Hyper-V Synthetic Video.
 
+config FB_SIMPLE
+       bool "Simple framebuffer support"
+       depends on (FB = y) && OF
+       select FB_CFB_FILLRECT
+       select FB_CFB_COPYAREA
+       select FB_CFB_IMAGEBLIT
+       help
+         Say Y if you want support for a simple frame-buffer.
+
+         This driver assumes that the display hardware has been initialized
+         before the kernel boots, and the kernel will simply render to the
+         pre-allocated frame buffer surface.
+
+         Configuration re: surface address, size, and format must be provided
+         through device tree, or potentially plain old platform data in the
+         future.
+
 source "drivers/video/omap/Kconfig"
 source "drivers/video/omap2/Kconfig"
 source "drivers/video/exynos/Kconfig"
index 7234e4a959e8c5b61e9d49b32d1057f83a7f290c..e8bae8dd4804d4bf797f444f239d5005a689390e 100644 (file)
@@ -166,6 +166,7 @@ obj-$(CONFIG_FB_MX3)                  += mx3fb.o
 obj-$(CONFIG_FB_DA8XX)           += da8xx-fb.o
 obj-$(CONFIG_FB_MXS)             += mxsfb.o
 obj-$(CONFIG_FB_SSD1307)         += ssd1307fb.o
+obj-$(CONFIG_FB_SIMPLE)           += simplefb.o
 
 # the test framebuffer is last
 obj-$(CONFIG_FB_VIRTUAL)          += vfb.o
index a862e9173ebed67d67cac954a98eb70a9f94c346..48da25c96cd3c2a160077e880f58fed3a52da0f8 100644 (file)
@@ -18,6 +18,8 @@ font-objs-$(CONFIG_FONT_MINI_4x6)  += font_mini_4x6.o
 
 font-objs += $(font-objs-y)
 
+obj-$(CONFIG_FONTS) += font.o
+
 # Each configuration option enables a list of files.
 
 obj-$(CONFIG_DUMMY_CONSOLE)       += dummycon.o
diff --git a/drivers/video/simplefb.c b/drivers/video/simplefb.c
new file mode 100644 (file)
index 0000000..e2e9e3e
--- /dev/null
@@ -0,0 +1,234 @@
+/*
+ * Simplest possible simple frame-buffer driver, as a platform device
+ *
+ * Copyright (c) 2013, Stephen Warren
+ *
+ * Based on q40fb.c, which was:
+ * Copyright (C) 2001 Richard Zidlicky <rz@linux-m68k.org>
+ *
+ * Also based on offb.c, which was:
+ * Copyright (C) 1997 Geert Uytterhoeven
+ * Copyright (C) 1996 Paul Mackerras
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ */
+
+#include <linux/errno.h>
+#include <linux/fb.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+static struct fb_fix_screeninfo simplefb_fix = {
+       .id             = "simple",
+       .type           = FB_TYPE_PACKED_PIXELS,
+       .visual         = FB_VISUAL_TRUECOLOR,
+       .accel          = FB_ACCEL_NONE,
+};
+
+static struct fb_var_screeninfo simplefb_var = {
+       .height         = -1,
+       .width          = -1,
+       .activate       = FB_ACTIVATE_NOW,
+       .vmode          = FB_VMODE_NONINTERLACED,
+};
+
+static int simplefb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+                             u_int transp, struct fb_info *info)
+{
+       u32 *pal = info->pseudo_palette;
+       u32 cr = red >> (16 - info->var.red.length);
+       u32 cg = green >> (16 - info->var.green.length);
+       u32 cb = blue >> (16 - info->var.blue.length);
+       u32 value;
+
+       if (regno >= 16)
+               return -EINVAL;
+
+       value = (cr << info->var.red.offset) |
+               (cg << info->var.green.offset) |
+               (cb << info->var.blue.offset);
+       if (info->var.transp.length > 0) {
+               u32 mask = (1 << info->var.transp.length) - 1;
+               mask <<= info->var.transp.offset;
+               value |= mask;
+       }
+       pal[regno] = value;
+
+       return 0;
+}
+
+static struct fb_ops simplefb_ops = {
+       .owner          = THIS_MODULE,
+       .fb_setcolreg   = simplefb_setcolreg,
+       .fb_fillrect    = cfb_fillrect,
+       .fb_copyarea    = cfb_copyarea,
+       .fb_imageblit   = cfb_imageblit,
+};
+
+struct simplefb_format {
+       const char *name;
+       u32 bits_per_pixel;
+       struct fb_bitfield red;
+       struct fb_bitfield green;
+       struct fb_bitfield blue;
+       struct fb_bitfield transp;
+};
+
+static struct simplefb_format simplefb_formats[] = {
+       { "r5g6b5", 16, {11, 5}, {5, 6}, {0, 5}, {0, 0} },
+};
+
+struct simplefb_params {
+       u32 width;
+       u32 height;
+       u32 stride;
+       struct simplefb_format *format;
+};
+
+static int simplefb_parse_dt(struct platform_device *pdev,
+                          struct simplefb_params *params)
+{
+       struct device_node *np = pdev->dev.of_node;
+       int ret;
+       const char *format;
+       int i;
+
+       ret = of_property_read_u32(np, "width", &params->width);
+       if (ret) {
+               dev_err(&pdev->dev, "Can't parse width property\n");
+               return ret;
+       }
+
+       ret = of_property_read_u32(np, "height", &params->height);
+       if (ret) {
+               dev_err(&pdev->dev, "Can't parse height property\n");
+               return ret;
+       }
+
+       ret = of_property_read_u32(np, "stride", &params->stride);
+       if (ret) {
+               dev_err(&pdev->dev, "Can't parse stride property\n");
+               return ret;
+       }
+
+       ret = of_property_read_string(np, "format", &format);
+       if (ret) {
+               dev_err(&pdev->dev, "Can't parse format property\n");
+               return ret;
+       }
+       params->format = NULL;
+       for (i = 0; i < ARRAY_SIZE(simplefb_formats); i++) {
+               if (strcmp(format, simplefb_formats[i].name))
+                       continue;
+               params->format = &simplefb_formats[i];
+               break;
+       }
+       if (!params->format) {
+               dev_err(&pdev->dev, "Invalid format value\n");
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int simplefb_probe(struct platform_device *pdev)
+{
+       int ret;
+       struct simplefb_params params;
+       struct fb_info *info;
+       struct resource *mem;
+
+       if (fb_get_options("simplefb", NULL))
+               return -ENODEV;
+
+       ret = simplefb_parse_dt(pdev, &params);
+       if (ret)
+               return ret;
+
+       mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!mem) {
+               dev_err(&pdev->dev, "No memory resource\n");
+               return -EINVAL;
+       }
+
+       info = framebuffer_alloc(sizeof(u32) * 16, &pdev->dev);
+       if (!info)
+               return -ENOMEM;
+       platform_set_drvdata(pdev, info);
+
+       info->fix = simplefb_fix;
+       info->fix.smem_start = mem->start;
+       info->fix.smem_len = resource_size(mem);
+       info->fix.line_length = params.stride;
+
+       info->var = simplefb_var;
+       info->var.xres = params.width;
+       info->var.yres = params.height;
+       info->var.xres_virtual = params.width;
+       info->var.yres_virtual = params.height;
+       info->var.bits_per_pixel = params.format->bits_per_pixel;
+       info->var.red = params.format->red;
+       info->var.green = params.format->green;
+       info->var.blue = params.format->blue;
+       info->var.transp = params.format->transp;
+
+       info->fbops = &simplefb_ops;
+       info->flags = FBINFO_DEFAULT;
+       info->screen_base = devm_ioremap(&pdev->dev, info->fix.smem_start,
+                                        info->fix.smem_len);
+       if (!info->screen_base) {
+               framebuffer_release(info);
+               return -ENODEV;
+       }
+       info->pseudo_palette = (void *)(info + 1);
+
+       ret = register_framebuffer(info);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "Unable to register simplefb: %d\n", ret);
+               framebuffer_release(info);
+               return ret;
+       }
+
+       dev_info(&pdev->dev, "fb%d: simplefb registered!\n", info->node);
+
+       return 0;
+}
+
+static int simplefb_remove(struct platform_device *pdev)
+{
+       struct fb_info *info = platform_get_drvdata(pdev);
+
+       unregister_framebuffer(info);
+       framebuffer_release(info);
+
+       return 0;
+}
+
+static const struct of_device_id simplefb_of_match[] = {
+       { .compatible = "simple-framebuffer", },
+       { },
+};
+MODULE_DEVICE_TABLE(of, simplefb_of_match);
+
+static struct platform_driver simplefb_driver = {
+       .driver = {
+               .name = "simple-framebuffer",
+               .owner = THIS_MODULE,
+               .of_match_table = simplefb_of_match,
+       },
+       .probe = simplefb_probe,
+       .remove = simplefb_remove,
+};
+module_platform_driver(simplefb_driver);
+
+MODULE_AUTHOR("Stephen Warren <swarren@wwwdotorg.org>");
+MODULE_DESCRIPTION("Simple framebuffer driver");
+MODULE_LICENSE("GPL v2");
index c5b1a8c10411ab108960eb74ed20f1b1a4bed601..7fe5bdee1630ec7fc89d3bc5d598d427f85e75df 100644 (file)
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -307,7 +307,9 @@ static void free_ioctx(struct kioctx *ctx)
        kunmap_atomic(ring);
 
        while (atomic_read(&ctx->reqs_active) > 0) {
-               wait_event(ctx->wait, head != ctx->tail);
+               wait_event(ctx->wait,
+                               head != ctx->tail ||
+                               atomic_read(&ctx->reqs_active) <= 0);
 
                avail = (head <= ctx->tail ? ctx->tail : ctx->nr_events) - head;
 
@@ -1299,8 +1301,7 @@ SYSCALL_DEFINE3(io_cancel, aio_context_t, ctx_id, struct iocb __user *, iocb,
  *     < min_nr if the timeout specified by timeout has elapsed
  *     before sufficient events are available, where timeout == NULL
  *     specifies an infinite timeout. Note that the timeout pointed to by
- *     timeout is relative and will be updated if not NULL and the
- *     operation blocks. Will fail with -ENOSYS if not implemented.
+ *     timeout is relative.  Will fail with -ENOSYS if not implemented.
  */
 SYSCALL_DEFINE5(io_getevents, aio_context_t, ctx_id,
                long, min_nr,
index fc3025199cb336f6c07c8172d19e501601a3f1f7..20efd81266c643338bcd81b434edfe9fbcacc0ac 100644 (file)
@@ -171,7 +171,8 @@ cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr)
 
        if (fattr->cf_flags & CIFS_FATTR_DFS_REFERRAL)
                inode->i_flags |= S_AUTOMOUNT;
-       cifs_set_ops(inode);
+       if (inode->i_state & I_NEW)
+               cifs_set_ops(inode);
 }
 
 void
index dfce656ddb333a6e7720c8ab0e32984ad82f11f3..5d4513cb1b3c03604792f145125b21fb338a3101 100644 (file)
@@ -1229,6 +1229,19 @@ static int fat_read_root(struct inode *inode)
        return 0;
 }
 
+static unsigned long calc_fat_clusters(struct super_block *sb)
+{
+       struct msdos_sb_info *sbi = MSDOS_SB(sb);
+
+       /* Divide first to avoid overflow */
+       if (sbi->fat_bits != 12) {
+               unsigned long ent_per_sec = sb->s_blocksize * 8 / sbi->fat_bits;
+               return ent_per_sec * sbi->fat_length;
+       }
+
+       return sbi->fat_length * sb->s_blocksize * 8 / sbi->fat_bits;
+}
+
 /*
  * Read the super block of an MS-DOS FS.
  */
@@ -1434,7 +1447,7 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat,
                sbi->dirty = b->fat16.state & FAT_STATE_DIRTY;
 
        /* check that FAT table does not overflow */
-       fat_clusters = sbi->fat_length * sb->s_blocksize * 8 / sbi->fat_bits;
+       fat_clusters = calc_fat_clusters(sb);
        total_clusters = min(total_clusters, fat_clusters - FAT_START_ENT);
        if (total_clusters > MAX_FAT(sb)) {
                if (!silent)
index eb08c9e43c2afb13947ca557f1a62da4626c5071..5a376ab81feb9021620cdb13b0cd1642059ead43 100644 (file)
@@ -26,7 +26,7 @@ config GFS2_FS
 config GFS2_FS_LOCKING_DLM
        bool "GFS2 DLM locking"
        depends on (GFS2_FS!=n) && NET && INET && (IPV6 || IPV6=n) && \
-               HOTPLUG && DLM && CONFIGFS_FS && SYSFS
+               HOTPLUG && CONFIGFS_FS && SYSFS && (DLM=y || DLM=GFS2_FS)
        help
          Multiple node locking module for GFS2
 
index c5fa758fd8446e1938036be9cdedaf75e2bc552b..68b4c8f1fce8568668bb9a8db82a321e6fe56e25 100644 (file)
@@ -212,7 +212,7 @@ static void gfs2_end_log_write(struct bio *bio, int error)
                fs_err(sdp, "Error %d writing to log\n", error);
        }
 
-       bio_for_each_segment(bvec, bio, i) {
+       bio_for_each_segment_all(bvec, bio, i) {
                page = bvec->bv_page;
                if (page_has_buffers(page))
                        gfs2_end_log_write_bh(sdp, bvec, error);
index c7c840e916f82f333861ac7998ccf53710cc34d8..c253b13722e8a8e2fc08b9708da11f74fe3b270a 100644 (file)
@@ -121,7 +121,7 @@ static u64 qd2index(struct gfs2_quota_data *qd)
 {
        struct kqid qid = qd->qd_id;
        return (2 * (u64)from_kqid(&init_user_ns, qid)) +
-               (qid.type == USRQUOTA) ? 0 : 1;
+               ((qid.type == USRQUOTA) ? 0 : 1);
 }
 
 static u64 qd2offset(struct gfs2_quota_data *qd)
@@ -721,7 +721,7 @@ get_a_page:
                        goto unlock_out;
        }
 
-       gfs2_trans_add_meta(ip->i_gl, bh);
+       gfs2_trans_add_data(ip->i_gl, bh);
 
        kaddr = kmap_atomic(page);
        if (offset + sizeof(struct gfs2_quota) > PAGE_CACHE_SIZE)
index 0c5a575b513ea2e28e4f4a4065de97db365fe576..5232525934aee170fe7218d729fef1af12fab6db 100644 (file)
@@ -1401,9 +1401,14 @@ static void rg_mblk_search(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip,
        u32 extlen;
        u32 free_blocks = rgd->rd_free_clone - rgd->rd_reserved;
        int ret;
+       struct inode *inode = &ip->i_inode;
 
-       extlen = max_t(u32, atomic_read(&rs->rs_sizehint), requested);
-       extlen = clamp(extlen, RGRP_RSRV_MINBLKS, free_blocks);
+       if (S_ISDIR(inode->i_mode))
+               extlen = 1;
+       else {
+               extlen = max_t(u32, atomic_read(&rs->rs_sizehint), requested);
+               extlen = clamp(extlen, RGRP_RSRV_MINBLKS, free_blocks);
+       }
        if ((rgd->rd_free_clone < rgd->rd_reserved) || (free_blocks < extlen))
                return;
 
index f3b1a15ccd5930e72896bdbaf3213460c3bb9f34..d3fa6bd9503e762c861debdd4fe64bef546bb78f 100644 (file)
@@ -415,7 +415,11 @@ struct hfs_bnode *hfs_bnode_create(struct hfs_btree *tree, u32 num)
        spin_lock(&tree->hash_lock);
        node = hfs_bnode_findhash(tree, num);
        spin_unlock(&tree->hash_lock);
-       BUG_ON(node);
+       if (node) {
+               pr_crit("new node %u already hashed?\n", num);
+               WARN_ON(1);
+               return node;
+       }
        node = __hfs_bnode_create(tree, num);
        if (!node)
                return ERR_PTR(-ENOMEM);
index a13d26ede254357d46bc1f24c7c404555048987f..0bc27684ebfa338d0b77c295427c31472ec66049 100644 (file)
@@ -414,7 +414,7 @@ __be32 nfs4_callback_sequence(struct cb_sequenceargs *args,
 
        spin_lock(&tbl->slot_tbl_lock);
        /* state manager is resetting the session */
-       if (test_bit(NFS4_SESSION_DRAINING, &clp->cl_session->session_state)) {
+       if (test_bit(NFS4_SLOT_TBL_DRAINING, &tbl->slot_tbl_state)) {
                spin_unlock(&tbl->slot_tbl_lock);
                status = htonl(NFS4ERR_DELAY);
                /* Return NFS4ERR_BADSESSION if we're draining the session
index 59461c957d9d7ed7204e09f9fad1aa0b154d8486..a35582c9d4440f8fe907192427b5c4f9a9a3b061 100644 (file)
@@ -763,7 +763,7 @@ static void nfs4_callback_free_slot(struct nfs4_session *session)
         * A single slot, so highest used slotid is either 0 or -1
         */
        tbl->highest_used_slotid = NFS4_NO_SLOT;
-       nfs4_session_drain_complete(session, tbl);
+       nfs4_slot_tbl_drain_complete(tbl);
        spin_unlock(&tbl->slot_tbl_lock);
 }
 
index 947b0c908aa908c643140dd7087b0927753c6d49..4cbad5d6b276f8c481984c166869e2679c2e241e 100644 (file)
@@ -203,7 +203,7 @@ struct nfs_client *nfs4_init_client(struct nfs_client *clp,
        __set_bit(NFS_CS_DISCRTRY, &clp->cl_flags);
        error = nfs_create_rpc_client(clp, timeparms, RPC_AUTH_GSS_KRB5I);
        if (error == -EINVAL)
-               error = nfs_create_rpc_client(clp, timeparms, RPC_AUTH_NULL);
+               error = nfs_create_rpc_client(clp, timeparms, RPC_AUTH_UNIX);
        if (error < 0)
                goto error;
 
index 8fbc100541154cbd31253dc261eb5eaafbe71e29..4e2fe714d5c292ae7776cb070c0c21fbfffdf7d1 100644 (file)
@@ -572,7 +572,7 @@ int nfs41_setup_sequence(struct nfs4_session *session,
        task->tk_timeout = 0;
 
        spin_lock(&tbl->slot_tbl_lock);
-       if (test_bit(NFS4_SESSION_DRAINING, &session->session_state) &&
+       if (test_bit(NFS4_SLOT_TBL_DRAINING, &tbl->slot_tbl_state) &&
            !args->sa_privileged) {
                /* The state manager will wait until the slot table is empty */
                dprintk("%s session is draining\n", __func__);
index ebda5f4a031b74d2c890d4c1e6cf932d869e8f2b..c4e225e4a9afc382b1eb689314ec2e7875cc1a45 100644 (file)
@@ -73,7 +73,7 @@ void nfs4_free_slot(struct nfs4_slot_table *tbl, struct nfs4_slot *slot)
                        tbl->highest_used_slotid = new_max;
                else {
                        tbl->highest_used_slotid = NFS4_NO_SLOT;
-                       nfs4_session_drain_complete(tbl->session, tbl);
+                       nfs4_slot_tbl_drain_complete(tbl);
                }
        }
        dprintk("%s: slotid %u highest_used_slotid %d\n", __func__,
@@ -226,7 +226,7 @@ static bool nfs41_assign_slot(struct rpc_task *task, void *pslot)
        struct nfs4_slot *slot = pslot;
        struct nfs4_slot_table *tbl = slot->table;
 
-       if (nfs4_session_draining(tbl->session) && !args->sa_privileged)
+       if (nfs4_slot_tbl_draining(tbl) && !args->sa_privileged)
                return false;
        slot->generation = tbl->generation;
        args->sa_slot = slot;
index 6f3cb39386d4e400d509e6526924fa0b5233ed74..ff7d9f0f8a65179fbf9bc795c4b1cdbf1ee56bf1 100644 (file)
@@ -25,6 +25,10 @@ struct nfs4_slot {
 };
 
 /* Sessions */
+enum nfs4_slot_tbl_state {
+       NFS4_SLOT_TBL_DRAINING,
+};
+
 #define SLOT_TABLE_SZ DIV_ROUND_UP(NFS4_MAX_SLOT_TABLE, 8*sizeof(long))
 struct nfs4_slot_table {
        struct nfs4_session *session;           /* Parent session */
@@ -43,6 +47,7 @@ struct nfs4_slot_table {
        unsigned long   generation;             /* Generation counter for
                                                   target_highest_slotid */
        struct completion complete;
+       unsigned long   slot_tbl_state;
 };
 
 /*
@@ -68,7 +73,6 @@ struct nfs4_session {
 
 enum nfs4_session_state {
        NFS4_SESSION_INITING,
-       NFS4_SESSION_DRAINING,
 };
 
 #if defined(CONFIG_NFS_V4_1)
@@ -88,12 +92,11 @@ extern void nfs4_destroy_session(struct nfs4_session *session);
 extern int nfs4_init_session(struct nfs_server *server);
 extern int nfs4_init_ds_session(struct nfs_client *, unsigned long);
 
-extern void nfs4_session_drain_complete(struct nfs4_session *session,
-               struct nfs4_slot_table *tbl);
+extern void nfs4_slot_tbl_drain_complete(struct nfs4_slot_table *tbl);
 
-static inline bool nfs4_session_draining(struct nfs4_session *session)
+static inline bool nfs4_slot_tbl_draining(struct nfs4_slot_table *tbl)
 {
-       return !!test_bit(NFS4_SESSION_DRAINING, &session->session_state);
+       return !!test_bit(NFS4_SLOT_TBL_DRAINING, &tbl->slot_tbl_state);
 }
 
 bool nfs41_wake_and_assign_slot(struct nfs4_slot_table *tbl,
index 300d17d85c0e03397d352746fc6fc775b39941e1..1fab140764c42756867f064a81b61903b8858a91 100644 (file)
@@ -241,7 +241,7 @@ static void nfs4_end_drain_session(struct nfs_client *clp)
        if (ses == NULL)
                return;
        tbl = &ses->fc_slot_table;
-       if (test_and_clear_bit(NFS4_SESSION_DRAINING, &ses->session_state)) {
+       if (test_and_clear_bit(NFS4_SLOT_TBL_DRAINING, &tbl->slot_tbl_state)) {
                spin_lock(&tbl->slot_tbl_lock);
                nfs41_wake_slot_table(tbl);
                spin_unlock(&tbl->slot_tbl_lock);
@@ -251,15 +251,15 @@ static void nfs4_end_drain_session(struct nfs_client *clp)
 /*
  * Signal state manager thread if session fore channel is drained
  */
-void nfs4_session_drain_complete(struct nfs4_session *session,
-               struct nfs4_slot_table *tbl)
+void nfs4_slot_tbl_drain_complete(struct nfs4_slot_table *tbl)
 {
-       if (nfs4_session_draining(session))
+       if (nfs4_slot_tbl_draining(tbl))
                complete(&tbl->complete);
 }
 
-static int nfs4_wait_on_slot_tbl(struct nfs4_slot_table *tbl)
+static int nfs4_drain_slot_tbl(struct nfs4_slot_table *tbl)
 {
+       set_bit(NFS4_SLOT_TBL_DRAINING, &tbl->slot_tbl_state);
        spin_lock(&tbl->slot_tbl_lock);
        if (tbl->highest_used_slotid != NFS4_NO_SLOT) {
                INIT_COMPLETION(tbl->complete);
@@ -275,13 +275,12 @@ static int nfs4_begin_drain_session(struct nfs_client *clp)
        struct nfs4_session *ses = clp->cl_session;
        int ret = 0;
 
-       set_bit(NFS4_SESSION_DRAINING, &ses->session_state);
        /* back channel */
-       ret = nfs4_wait_on_slot_tbl(&ses->bc_slot_table);
+       ret = nfs4_drain_slot_tbl(&ses->bc_slot_table);
        if (ret)
                return ret;
        /* fore channel */
-       return nfs4_wait_on_slot_tbl(&ses->fc_slot_table);
+       return nfs4_drain_slot_tbl(&ses->fc_slot_table);
 }
 
 static void nfs41_finish_session_reset(struct nfs_client *clp)
index 689fb608648e9a80db3c4e643feb3fe00ff1cfa4..bccfec8343c5ee34925cea97b8fc4006f8265084 100644 (file)
@@ -219,13 +219,32 @@ static int nilfs_writepage(struct page *page, struct writeback_control *wbc)
 
 static int nilfs_set_page_dirty(struct page *page)
 {
-       int ret = __set_page_dirty_buffers(page);
+       int ret = __set_page_dirty_nobuffers(page);
 
-       if (ret) {
+       if (page_has_buffers(page)) {
                struct inode *inode = page->mapping->host;
-               unsigned nr_dirty = 1 << (PAGE_SHIFT - inode->i_blkbits);
+               unsigned nr_dirty = 0;
+               struct buffer_head *bh, *head;
 
-               nilfs_set_file_dirty(inode, nr_dirty);
+               /*
+                * This page is locked by callers, and no other thread
+                * concurrently marks its buffers dirty since they are
+                * only dirtied through routines in fs/buffer.c in
+                * which call sites of mark_buffer_dirty are protected
+                * by page lock.
+                */
+               bh = head = page_buffers(page);
+               do {
+                       /* Do not mark hole blocks dirty */
+                       if (buffer_dirty(bh) || !buffer_mapped(bh))
+                               continue;
+
+                       set_buffer_dirty(bh);
+                       nr_dirty++;
+               } while (bh = bh->b_this_page, bh != head);
+
+               if (nr_dirty)
+                       nilfs_set_file_dirty(inode, nr_dirty);
        }
        return ret;
 }
index 1c39efb71bab6d2c4926962c0a642d291e2b360b..2487116d0d3312981834aa3667fd708dc7aa05ab 100644 (file)
@@ -790,7 +790,7 @@ int ocfs2_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
                                                 &hole_size, &rec, &is_last);
                if (ret) {
                        mlog_errno(ret);
-                       goto out;
+                       goto out_unlock;
                }
 
                if (rec.e_blkno == 0ULL) {
index 8a7509f9e6f5e0f49438876228a8e887ac2cdeb1..ff54014a24ecd58511c37a16b33f5e27a1e3e6dd 100644 (file)
@@ -2288,7 +2288,7 @@ relock:
                ret = ocfs2_inode_lock(inode, NULL, 1);
                if (ret < 0) {
                        mlog_errno(ret);
-                       goto out_sems;
+                       goto out;
                }
 
                ocfs2_inode_unlock(inode, 1);
index 2b2691b7342890e64e957d616dfb1c4aa2efc8c1..41a695048be7b09b87baf4517fd8124b6d7a8ffb 100644 (file)
@@ -725,6 +725,25 @@ xfs_convert_page(
                        (xfs_off_t)(page->index + 1) << PAGE_CACHE_SHIFT,
                        i_size_read(inode));
 
+       /*
+        * If the current map does not span the entire page we are about to try
+        * to write, then give up. The only way we can write a page that spans
+        * multiple mappings in a single writeback iteration is via the
+        * xfs_vm_writepage() function. Data integrity writeback requires the
+        * entire page to be written in a single attempt, otherwise the part of
+        * the page we don't write here doesn't get written as part of the data
+        * integrity sync.
+        *
+        * For normal writeback, we also don't attempt to write partial pages
+        * here as it simply means that write_cache_pages() will see it under
+        * writeback and ignore the page until some point in the future, at
+        * which time this will be the only page in the file that needs
+        * writeback.  Hence for more optimal IO patterns, we should always
+        * avoid partial page writeback due to multiple mappings on a page here.
+        */
+       if (!xfs_imap_valid(inode, imap, end_offset))
+               goto fail_unlock_page;
+
        len = 1 << inode->i_blkbits;
        p_offset = min_t(unsigned long, end_offset & (PAGE_CACHE_SIZE - 1),
                                        PAGE_CACHE_SIZE);
index 08d5457c948e051866217792e2fcbc12d1f5c726..0bce1b3485800a9319fb1116a5d8d11edf485392 100644 (file)
@@ -931,20 +931,22 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context)
  */
 int
 xfs_attr_shortform_allfit(
-       struct xfs_buf  *bp,
-       struct xfs_inode *dp)
+       struct xfs_buf          *bp,
+       struct xfs_inode        *dp)
 {
-       xfs_attr_leafblock_t *leaf;
-       xfs_attr_leaf_entry_t *entry;
+       struct xfs_attr_leafblock *leaf;
+       struct xfs_attr_leaf_entry *entry;
        xfs_attr_leaf_name_local_t *name_loc;
-       int bytes, i;
+       struct xfs_attr3_icleaf_hdr leafhdr;
+       int                     bytes;
+       int                     i;
 
        leaf = bp->b_addr;
-       ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC));
+       xfs_attr3_leaf_hdr_from_disk(&leafhdr, leaf);
+       entry = xfs_attr3_leaf_entryp(leaf);
 
-       entry = &leaf->entries[0];
        bytes = sizeof(struct xfs_attr_sf_hdr);
-       for (i = 0; i < be16_to_cpu(leaf->hdr.count); entry++, i++) {
+       for (i = 0; i < leafhdr.count; entry++, i++) {
                if (entry->flags & XFS_ATTR_INCOMPLETE)
                        continue;               /* don't copy partial entries */
                if (!(entry->flags & XFS_ATTR_LOCAL))
@@ -954,15 +956,15 @@ xfs_attr_shortform_allfit(
                        return(0);
                if (be16_to_cpu(name_loc->valuelen) >= XFS_ATTR_SF_ENTSIZE_MAX)
                        return(0);
-               bytes += sizeof(struct xfs_attr_sf_entry)-1
+               bytes += sizeof(struct xfs_attr_sf_entry) - 1
                                + name_loc->namelen
                                + be16_to_cpu(name_loc->valuelen);
        }
        if ((dp->i_mount->m_flags & XFS_MOUNT_ATTR2) &&
            (dp->i_d.di_format != XFS_DINODE_FMT_BTREE) &&
            (bytes == sizeof(struct xfs_attr_sf_hdr)))
-               return(-1);
-       return(xfs_attr_shortform_bytesfit(dp, bytes));
+               return -1;
+       return xfs_attr_shortform_bytesfit(dp, bytes);
 }
 
 /*
@@ -2330,9 +2332,10 @@ xfs_attr3_leaf_lookup_int(
                        if (!xfs_attr_namesp_match(args->flags, entry->flags))
                                continue;
                        args->index = probe;
+                       args->valuelen = be32_to_cpu(name_rmt->valuelen);
                        args->rmtblkno = be32_to_cpu(name_rmt->valueblk);
                        args->rmtblkcnt = XFS_B_TO_FSB(args->dp->i_mount,
-                                                  be32_to_cpu(name_rmt->valuelen));
+                                                      args->valuelen);
                        return XFS_ERROR(EEXIST);
                }
        }
index 82b70bda9f47a51eb3f31a50ae4fcd32f6c57047..0d255429968879f87496265e8ccb07e7f88c1de1 100644 (file)
@@ -1649,7 +1649,7 @@ xfs_alloc_buftarg(
 {
        xfs_buftarg_t           *btp;
 
-       btp = kmem_zalloc(sizeof(*btp), KM_SLEEP);
+       btp = kmem_zalloc(sizeof(*btp), KM_SLEEP | KM_NOFS);
 
        btp->bt_mount = mp;
        btp->bt_dev =  bdev->bd_dev;
index 9b26a99ebfe917ed67123a77794751fc2b72cecd..0b8b2a13cd24debe493c8982679a2c565ebae5a1 100644 (file)
@@ -270,6 +270,7 @@ xfs_da3_node_read_verify(
                                break;
                        return;
                case XFS_ATTR_LEAF_MAGIC:
+               case XFS_ATTR3_LEAF_MAGIC:
                        bp->b_ops = &xfs_attr3_leaf_buf_ops;
                        bp->b_ops->verify_read(bp);
                        return;
@@ -2464,7 +2465,8 @@ xfs_buf_map_from_irec(
        ASSERT(nirecs >= 1);
 
        if (nirecs > 1) {
-               map = kmem_zalloc(nirecs * sizeof(struct xfs_buf_map), KM_SLEEP);
+               map = kmem_zalloc(nirecs * sizeof(struct xfs_buf_map),
+                                 KM_SLEEP | KM_NOFS);
                if (!map)
                        return ENOMEM;
                *mapp = map;
@@ -2520,7 +2522,8 @@ xfs_dabuf_map(
                 * Optimize the one-block case.
                 */
                if (nfsb != 1)
-                       irecs = kmem_zalloc(sizeof(irec) * nfsb, KM_SLEEP);
+                       irecs = kmem_zalloc(sizeof(irec) * nfsb,
+                                           KM_SLEEP | KM_NOFS);
 
                nirecs = nfsb;
                error = xfs_bmapi_read(dp, (xfs_fileoff_t)bno, nfsb, irecs,
index 721ba2fe8e54581aebf884e1cb31d2f02e1e2534..da71a1819d780cd35bd9817fd89deabd5feb3eb7 100644 (file)
@@ -1336,7 +1336,7 @@ xfs_dir2_leaf_getdents(
                                     mp->m_sb.sb_blocksize);
        map_info = kmem_zalloc(offsetof(struct xfs_dir2_leaf_map_info, map) +
                                (length * sizeof(struct xfs_bmbt_irec)),
-                              KM_SLEEP);
+                              KM_SLEEP | KM_NOFS);
        map_info->map_size = length;
 
        /*
index c0f375087efc3256cf5196ff08cdd2068ce18834..452920a3f03fb2e4405ce52e34587e55acfb7abe 100644 (file)
@@ -305,11 +305,12 @@ xfs_efi_release(xfs_efi_log_item_t        *efip,
 {
        ASSERT(atomic_read(&efip->efi_next_extent) >= nextents);
        if (atomic_sub_and_test(nextents, &efip->efi_next_extent)) {
-               __xfs_efi_release(efip);
-
                /* recovery needs us to drop the EFI reference, too */
                if (test_bit(XFS_EFI_RECOVERED, &efip->efi_flags))
                        __xfs_efi_release(efip);
+
+               __xfs_efi_release(efip);
+               /* efip may now have been freed, do not reference it again. */
        }
 }
 
index e3d0b85d852b6e2c3b07bc07482d2a7e357ccf90..d0833b54e55d63ed83eb61cedfd110cd4a1263b2 100644 (file)
@@ -139,7 +139,7 @@ xlog_cil_prepare_log_vecs(
 
                new_lv = kmem_zalloc(sizeof(*new_lv) +
                                niovecs * sizeof(struct xfs_log_iovec),
-                               KM_SLEEP);
+                               KM_SLEEP|KM_NOFS);
 
                /* The allocated iovec region lies beyond the log vector. */
                new_lv->lv_iovecp = (struct xfs_log_iovec *)&new_lv[1];
index 1501f4fa51a6e4a0a683ca9998ded29a0410e450..0176bb21f09a5c3c0795f6f6932e07f92643c94a 100644 (file)
@@ -1453,7 +1453,7 @@ xfs_free_file_space(
        xfs_mount_t             *mp;
        int                     nimap;
        uint                    resblks;
-       uint                    rounding;
+       xfs_off_t               rounding;
        int                     rt;
        xfs_fileoff_t           startoffset_fsb;
        xfs_trans_t             *tp;
@@ -1482,7 +1482,7 @@ xfs_free_file_space(
                inode_dio_wait(VFS_I(ip));
        }
 
-       rounding = max_t(uint, 1 << mp->m_sb.sb_blocklog, PAGE_CACHE_SIZE);
+       rounding = max_t(xfs_off_t, 1 << mp->m_sb.sb_blocklog, PAGE_CACHE_SIZE);
        ioffset = offset & ~(rounding - 1);
        error = -filemap_write_and_wait_range(VFS_I(ip)->i_mapping,
                                              ioffset, -1);
index 98db31d9f9b410908b2056b192bf9813bc8ce4aa..636c59f2003a315c264777eccd0e3abfbdd8045f 100644 (file)
@@ -377,7 +377,6 @@ acpi_status acpi_bus_get_status_handle(acpi_handle handle,
                                       unsigned long long *sta);
 int acpi_bus_get_status(struct acpi_device *device);
 
-#ifdef CONFIG_PM
 int acpi_bus_set_power(acpi_handle handle, int state);
 const char *acpi_power_state_string(int state);
 int acpi_device_get_power(struct acpi_device *device, int *state);
@@ -385,41 +384,12 @@ int acpi_device_set_power(struct acpi_device *device, int state);
 int acpi_bus_init_power(struct acpi_device *device);
 int acpi_bus_update_power(acpi_handle handle, int *state_p);
 bool acpi_bus_power_manageable(acpi_handle handle);
+
+#ifdef CONFIG_PM
 bool acpi_bus_can_wakeup(acpi_handle handle);
-#else /* !CONFIG_PM */
-static inline int acpi_bus_set_power(acpi_handle handle, int state)
-{
-       return 0;
-}
-static inline const char *acpi_power_state_string(int state)
-{
-       return "D0";
-}
-static inline int acpi_device_get_power(struct acpi_device *device, int *state)
-{
-       return 0;
-}
-static inline int acpi_device_set_power(struct acpi_device *device, int state)
-{
-       return 0;
-}
-static inline int acpi_bus_init_power(struct acpi_device *device)
-{
-       return 0;
-}
-static inline int acpi_bus_update_power(acpi_handle handle, int *state_p)
-{
-       return 0;
-}
-static inline bool acpi_bus_power_manageable(acpi_handle handle)
-{
-       return false;
-}
-static inline bool acpi_bus_can_wakeup(acpi_handle handle)
-{
-       return false;
-}
-#endif /* !CONFIG_PM */
+#else
+static inline bool acpi_bus_can_wakeup(acpi_handle handle) { return false; }
+#endif
 
 #ifdef CONFIG_ACPI_PROC_EVENT
 int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data);
index d09deabc7bf64773eff4223d631830dc74ef45b3..fb0298082916fa7f7622de3fc2233ca4732b649e 100644 (file)
@@ -37,6 +37,8 @@ struct acpi_dma_spec {
  * @dev:               struct device of this controller
  * @acpi_dma_xlate:    callback function to find a suitable channel
  * @data:              private data used by a callback function
+ * @base_request_line: first supported request line (CSRT)
+ * @end_request_line:  last supported request line (CSRT)
  */
 struct acpi_dma {
        struct list_head        dma_controllers;
@@ -44,6 +46,8 @@ struct acpi_dma {
        struct dma_chan         *(*acpi_dma_xlate)
                                (struct acpi_dma_spec *, struct acpi_dma *);
        void                    *data;
+       unsigned short          base_request_line;
+       unsigned short          end_request_line;
 };
 
 /* Used with acpi_dma_simple_xlate() */
index f14a98a79c9d8b276d3407050d08f00b87c9c6be..2e34db82a6434d35d7f8c1b7b6b8385e08158bb2 100644 (file)
@@ -134,7 +134,10 @@ struct bcma_host_ops {
 #define BCMA_CORE_I2S                  0x834
 #define BCMA_CORE_SDR_DDR1_MEM_CTL     0x835   /* SDR/DDR1 memory controller core */
 #define BCMA_CORE_SHIM                 0x837   /* SHIM component in ubus/6362 */
-#define BCMA_CORE_ARM_CR4              0x83e
+#define BCMA_CORE_PHY_AC               0x83B
+#define BCMA_CORE_PCIE2                        0x83C   /* PCI Express Gen2 */
+#define BCMA_CORE_USB30_DEV            0x83D
+#define BCMA_CORE_ARM_CR4              0x83E
 #define BCMA_CORE_DEFAULT              0xFFF
 
 #define BCMA_MAX_NR_CORES              16
index b840a496028259076caff141de3a6a92ed177a3a..677b4f01b2d0bfd2dd1619d930ec92992bcd1d7d 100644 (file)
@@ -1,3 +1,6 @@
+#ifndef _LINUX_BRCMPHY_H
+#define _LINUX_BRCMPHY_H
+
 #define PHY_ID_BCM50610                        0x0143bd60
 #define PHY_ID_BCM50610M               0x0143bd70
 #define PHY_ID_BCM5241                 0x0143bc30
@@ -29,3 +32,5 @@
 #define PHY_BRCM_CLEAR_RGMII_MODE      0x00004000
 #define PHY_BRCM_DIS_TXCRXC_NOENRGY    0x00008000
 #define PHY_BCM_FLAGS_VALID            0x80000000
+
+#endif /* _LINUX_BRCMPHY_H */
index e96329ceb28c8440e470e3e073226ed24995a462..e9ef6d6b51d5b07f6471e96dc20efa5685416220 100644 (file)
@@ -562,6 +562,9 @@ int __trace_bprintk(unsigned long ip, const char *fmt, ...);
 extern __printf(2, 3)
 int __trace_printk(unsigned long ip, const char *fmt, ...);
 
+extern int __trace_bputs(unsigned long ip, const char *str);
+extern int __trace_puts(unsigned long ip, const char *str, int size);
+
 /**
  * trace_puts - write a string into the ftrace buffer
  * @str: the string to record
@@ -587,8 +590,6 @@ int __trace_printk(unsigned long ip, const char *fmt, ...);
  *  (1 when __trace_bputs is used, strlen(str) when __trace_puts is used)
  */
 
-extern int __trace_bputs(unsigned long ip, const char *str);
-extern int __trace_puts(unsigned long ip, const char *str, int size);
 #define trace_puts(str) ({                                             \
        static const char *trace_printk_fmt                             \
                __attribute__((section("__trace_printk_fmt"))) =        \
index fb1bf7d6a41018edf8358c76ffce8b74e2282cba..0390d5943ed6db1885ecf67612d7cd1da60e908b 100644 (file)
@@ -373,13 +373,11 @@ struct ab8500_sysctrl_platform_data;
 /**
  * struct ab8500_platform_data - AB8500 platform data
  * @irq_base: start of AB8500 IRQs, AB8500_NR_IRQS will be used
- * @pm_power_off: Should machine pm power off hook be registered or not
  * @init: board-specific initialization after detection of ab8500
  * @regulator: machine-specific constraints for regulators
  */
 struct ab8500_platform_data {
        int irq_base;
-       bool pm_power_off;
        void (*init) (struct ab8500 *);
        struct ab8500_regulator_platform_data *regulator;
        struct abx500_gpio_platform_data *gpio;
index a94a5a0ab122e8fc577df4db38eb65c1ec543f9c..60584b185a0c5d4ad61ed0435982ad4287dea8fc 100644 (file)
@@ -2733,6 +2733,17 @@ static inline netdev_features_t netdev_get_wanted_features(
 }
 netdev_features_t netdev_increment_features(netdev_features_t all,
        netdev_features_t one, netdev_features_t mask);
+
+/* Allow TSO being used on stacked device :
+ * Performing the GSO segmentation before last device
+ * is a performance improvement.
+ */
+static inline netdev_features_t netdev_add_tso_features(netdev_features_t features,
+                                                       netdev_features_t mask)
+{
+       return netdev_increment_features(features, NETIF_F_ALL_TSO, mask);
+}
+
 int __netdev_update_features(struct net_device *dev);
 void netdev_update_features(struct net_device *dev);
 void netdev_change_features(struct net_device *dev);
index 81b31613eb252b3a46052d2375e333affc91c77f..1704479772787b28950c9768a9e73c35c88dcd9a 100644 (file)
@@ -60,11 +60,13 @@ static inline void acpi_pci_slot_remove(struct pci_bus *bus) { }
 void acpiphp_init(void);
 void acpiphp_enumerate_slots(struct pci_bus *bus, acpi_handle handle);
 void acpiphp_remove_slots(struct pci_bus *bus);
+void acpiphp_check_host_bridge(acpi_handle handle);
 #else
 static inline void acpiphp_init(void) { }
 static inline void acpiphp_enumerate_slots(struct pci_bus *bus,
                                           acpi_handle handle) { }
 static inline void acpiphp_remove_slots(struct pci_bus *bus) { }
+static inline void acpiphp_check_host_bridge(acpi_handle handle) { }
 #endif
 
 #else  /* CONFIG_ACPI */
index 528e73ce46d2e2903b30172f61627ea113b8be02..23901992b9ddc2b4f67dc50ef0fe6e64f8173d2f 100644 (file)
 #ifndef __CLK_LPSS_H
 #define __CLK_LPSS_H
 
+struct lpss_clk_data {
+       const char *name;
+       struct clk *clk;
+};
+
 extern int lpt_clk_init(void);
 
 #endif /* __CLK_LPSS_H */
index ff9b0aab5281c2251e93f5a6f56ea09cf2e31289..c860c1b314c0473a7737cd6c7dacd65344fbc656 100644 (file)
@@ -43,8 +43,6 @@ struct omap_uart_port_info {
        int                     DTR_present;
 
        int (*get_context_loss_count)(struct device *);
-       void (*set_forceidle)(struct device *);
-       void (*set_noidle)(struct device *);
        void (*enable_wakeup)(struct device *, bool);
 };
 
index 6af944ab38f05638e7443122abbc1ec5592dfcbe..22c7052e937248e4c3337778d8608b3508a24ce5 100644 (file)
@@ -4,6 +4,7 @@
 #include <stdarg.h>
 #include <linux/init.h>
 #include <linux/kern_levels.h>
+#include <linux/linkage.h>
 
 extern const char linux_banner[];
 extern const char linux_proc_banner[];
index a3e7842786679567185ecdbc8835fd5936fb36f4..18e099342e6f82732a93b347b021ca7aa4e2b22d 100644 (file)
@@ -83,7 +83,6 @@
 
 extern struct bus_type rio_bus_type;
 extern struct device rio_bus;
-extern struct list_head rio_devices;   /* list of all devices */
 
 struct rio_mport;
 struct rio_dev;
@@ -237,6 +236,7 @@ enum rio_phy_type {
  * @name: Port name string
  * @priv: Master port private data
  * @dma: DMA device associated with mport
+ * @nscan: RapidIO network enumeration/discovery operations
  */
 struct rio_mport {
        struct list_head dbells;        /* list of doorbell events */
@@ -262,8 +262,14 @@ struct rio_mport {
 #ifdef CONFIG_RAPIDIO_DMA_ENGINE
        struct dma_device       dma;
 #endif
+       struct rio_scan *nscan;
 };
 
+/*
+ * Enumeration/discovery control flags
+ */
+#define RIO_SCAN_ENUM_NO_WAIT  0x00000001 /* Do not wait for enum completed */
+
 struct rio_id_table {
        u16 start;      /* logical minimal id */
        u32 max;        /* max number of IDs in table */
@@ -460,6 +466,16 @@ static inline struct rio_mport *dma_to_mport(struct dma_device *ddev)
 }
 #endif /* CONFIG_RAPIDIO_DMA_ENGINE */
 
+/**
+ * struct rio_scan - RIO enumeration and discovery operations
+ * @enumerate: Callback to perform RapidIO fabric enumeration.
+ * @discover: Callback to perform RapidIO fabric discovery.
+ */
+struct rio_scan {
+       int (*enumerate)(struct rio_mport *mport, u32 flags);
+       int (*discover)(struct rio_mport *mport, u32 flags);
+};
+
 /* Architecture and hardware-specific functions */
 extern int rio_register_mport(struct rio_mport *);
 extern int rio_open_inb_mbox(struct rio_mport *, void *, int, int);
index b75c05920ab58f976cb73223ce7a7da97a4b146d..5059994fe2970edf8942e537fd3fe81144c2ccb3 100644 (file)
@@ -433,5 +433,6 @@ extern u16 rio_local_get_device_id(struct rio_mport *port);
 extern struct rio_dev *rio_get_device(u16 vid, u16 did, struct rio_dev *from);
 extern struct rio_dev *rio_get_asm(u16 vid, u16 did, u16 asm_vid, u16 asm_did,
                                   struct rio_dev *from);
+extern int rio_init_mports(void);
 
 #endif                         /* LINUX_RIO_DRV_H */
index 428c37a1f95ce2eea8d9785ef69fc6050b5b7c96..33bf2dfab19d079d31a0373adc30ba9bc536edf8 100644 (file)
@@ -305,7 +305,6 @@ struct ucred {
 
 extern void cred_to_ucred(struct pid *pid, const struct cred *cred, struct ucred *ucred);
 
-extern int memcpy_fromiovec(unsigned char *kdata, struct iovec *iov, int len);
 extern int memcpy_fromiovecend(unsigned char *kdata, const struct iovec *iov,
                               int offset, int len);
 extern int csum_partial_copy_fromiovecend(unsigned char *kdata, 
@@ -314,7 +313,6 @@ extern int csum_partial_copy_fromiovecend(unsigned char *kdata,
                                          unsigned int len, __wsum *csump);
 
 extern int verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr_storage *address, int mode);
-extern int memcpy_toiovec(struct iovec *v, unsigned char *kdata, int len);
 extern int memcpy_toiovecend(const struct iovec *v, unsigned char *kdata,
                             int offset, int len);
 extern int move_addr_to_kernel(void __user *uaddr, int ulen, struct sockaddr_storage *kaddr);
index 629aaf51f30b8c1fdc6e27cd086c9caf19378896..c55ce243cc0985c450786e4cb63f8ed3c8e5c53b 100644 (file)
@@ -35,4 +35,7 @@ static inline size_t iov_length(const struct iovec *iov, unsigned long nr_segs)
 }
 
 unsigned long iov_shorten(struct iovec *iov, unsigned long nr_segs, size_t to);
+
+int memcpy_fromiovec(unsigned char *kdata, struct iovec *iov, int len);
+int memcpy_toiovec(struct iovec *iov, unsigned char *kdata, int len);
 #endif
index c454a88abf2e6fed7adda903a7d2e0626613e29f..f1b0dca60f127116113361da7ff61d726d0fa26a 100644 (file)
@@ -563,9 +563,8 @@ static inline int gadget_is_dualspeed(struct usb_gadget *g)
 }
 
 /**
- * gadget_is_superspeed() - return true if the hardware handles
- * supperspeed
- * @g: controller that might support supper speed
+ * gadget_is_superspeed() - return true if the hardware handles superspeed
+ * @g: controller that might support superspeed
  */
 static inline int gadget_is_superspeed(struct usb_gadget *g)
 {
index b9b0f7b4e43b81c4829802b5f0eea0cd0713974d..302ddf55d2daca5d74291b1eb9aaa2b4127fe7d2 100644 (file)
@@ -268,6 +268,8 @@ struct usb_serial_driver {
                        struct usb_serial_port *port, struct ktermios *old);
        void (*break_ctl)(struct tty_struct *tty, int break_state);
        int  (*chars_in_buffer)(struct tty_struct *tty);
+       void (*wait_until_sent)(struct tty_struct *tty, long timeout);
+       bool (*tx_empty)(struct usb_serial_port *port);
        void (*throttle)(struct tty_struct *tty);
        void (*unthrottle)(struct tty_struct *tty);
        int  (*tiocmget)(struct tty_struct *tty);
@@ -327,6 +329,8 @@ extern void usb_serial_generic_close(struct usb_serial_port *port);
 extern int usb_serial_generic_resume(struct usb_serial *serial);
 extern int usb_serial_generic_write_room(struct tty_struct *tty);
 extern int usb_serial_generic_chars_in_buffer(struct tty_struct *tty);
+extern void usb_serial_generic_wait_until_sent(struct tty_struct *tty,
+                                                               long timeout);
 extern void usb_serial_generic_read_bulk_callback(struct urb *urb);
 extern void usb_serial_generic_write_bulk_callback(struct urb *urb);
 extern void usb_serial_generic_throttle(struct tty_struct *tty);
index e8d65718560b3460b09123cb99d3a3f08685c217..0d33fca487748916faca92cad918c3726f713a57 100644 (file)
@@ -36,7 +36,7 @@ extern int fg_console, last_console, want_console;
 int vc_allocate(unsigned int console);
 int vc_cons_allocated(unsigned int console);
 int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int lines);
-void vc_deallocate(unsigned int console);
+struct vc_data *vc_deallocate(unsigned int console);
 void reset_palette(struct vc_data *vc);
 void do_blank_screen(int entering_gfx);
 void do_unblank_screen(int leaving_gfx);
index ac38be2692d89f2993381e57d6145ab75891b1d3..1133695eb0671d7aeb7f9140bf2b6adc3bc7483d 100644 (file)
@@ -217,6 +217,8 @@ do {                                                                        \
                if (!ret)                                               \
                        break;                                          \
        }                                                               \
+       if (!ret && (condition))                                        \
+               ret = 1;                                                \
        finish_wait(&wq, &__wait);                                      \
 } while (0)
 
@@ -233,8 +235,9 @@ do {                                                                        \
  * wake_up() has to be called after changing any variable that could
  * change the result of the wait condition.
  *
- * The function returns 0 if the @timeout elapsed, and the remaining
- * jiffies if the condition evaluated to true before the timeout elapsed.
+ * The function returns 0 if the @timeout elapsed, or the remaining
+ * jiffies (at least 1) if the @condition evaluated to %true before
+ * the @timeout elapsed.
  */
 #define wait_event_timeout(wq, condition, timeout)                     \
 ({                                                                     \
@@ -302,6 +305,8 @@ do {                                                                        \
                ret = -ERESTARTSYS;                                     \
                break;                                                  \
        }                                                               \
+       if (!ret && (condition))                                        \
+               ret = 1;                                                \
        finish_wait(&wq, &__wait);                                      \
 } while (0)
 
@@ -318,9 +323,10 @@ do {                                                                       \
  * wake_up() has to be called after changing any variable that could
  * change the result of the wait condition.
  *
- * The function returns 0 if the @timeout elapsed, -ERESTARTSYS if it
- * was interrupted by a signal, and the remaining jiffies otherwise
- * if the condition evaluated to true before the timeout elapsed.
+ * Returns:
+ * 0 if the @timeout elapsed, -%ERESTARTSYS if it was interrupted by
+ * a signal, or the remaining jiffies (at least 1) if the @condition
+ * evaluated to %true before the @timeout elapsed.
  */
 #define wait_event_interruptible_timeout(wq, condition, timeout)       \
 ({                                                                     \
index 04c2d4670dc6f66cefead56a19cd57e95cca9a5d..885898a40d13530504ad41e489b9d58a6b233366 100644 (file)
@@ -3043,7 +3043,8 @@ void ieee80211_napi_complete(struct ieee80211_hw *hw);
  * This function may not be called in IRQ context. Calls to this function
  * for a single hardware must be synchronized against each other. Calls to
  * this function, ieee80211_rx_ni() and ieee80211_rx_irqsafe() may not be
- * mixed for a single hardware.
+ * mixed for a single hardware. Must not run concurrently with
+ * ieee80211_tx_status() or ieee80211_tx_status_ni().
  *
  * In process context use instead ieee80211_rx_ni().
  *
@@ -3059,7 +3060,8 @@ void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb);
  * (internally defers to a tasklet.)
  *
  * Calls to this function, ieee80211_rx() or ieee80211_rx_ni() may not
- * be mixed for a single hardware.
+ * be mixed for a single hardware.Must not run concurrently with
+ * ieee80211_tx_status() or ieee80211_tx_status_ni().
  *
  * @hw: the hardware this frame came in on
  * @skb: the buffer to receive, owned by mac80211 after this call
@@ -3073,7 +3075,8 @@ void ieee80211_rx_irqsafe(struct ieee80211_hw *hw, struct sk_buff *skb);
  * (internally disables bottom halves).
  *
  * Calls to this function, ieee80211_rx() and ieee80211_rx_irqsafe() may
- * not be mixed for a single hardware.
+ * not be mixed for a single hardware. Must not run concurrently with
+ * ieee80211_tx_status() or ieee80211_tx_status_ni().
  *
  * @hw: the hardware this frame came in on
  * @skb: the buffer to receive, owned by mac80211 after this call
@@ -3196,7 +3199,8 @@ void ieee80211_get_tx_rates(struct ieee80211_vif *vif,
  * This function may not be called in IRQ context. Calls to this function
  * for a single hardware must be synchronized against each other. Calls
  * to this function, ieee80211_tx_status_ni() and ieee80211_tx_status_irqsafe()
- * may not be mixed for a single hardware.
+ * may not be mixed for a single hardware. Must not run concurrently with
+ * ieee80211_rx() or ieee80211_rx_ni().
  *
  * @hw: the hardware the frame was transmitted by
  * @skb: the frame that was transmitted, owned by mac80211 after this call
index 31f1fb9eb78478a6db6339065b69b280adb26916..99eac12d040ba375e0b1d8712d9a4b3005da5ee5 100644 (file)
@@ -30,7 +30,8 @@ struct nf_loginfo {
        } u;
 };
 
-typedef void nf_logfn(u_int8_t pf,
+typedef void nf_logfn(struct net *net,
+                     u_int8_t pf,
                      unsigned int hooknum,
                      const struct sk_buff *skb,
                      const struct net_device *in,
index e2dec42c2db2b5c07afc98165b140b76aa599f56..5ca3f14f0998e9962385821409d32f0ac66dbb43 100644 (file)
@@ -2,7 +2,8 @@
 #define _KER_NFNETLINK_LOG_H
 
 void
-nfulnl_log_packet(u_int8_t pf,
+nfulnl_log_packet(struct net *net,
+                 u_int8_t pf,
                  unsigned int hooknum,
                  const struct sk_buff *skb,
                  const struct net_device *in,
index ee13ab6c361409b31216da2e54790f804401fe51..c312f16bc4e7e692f4117b0a9280cadf1977f8db 100644 (file)
@@ -39,7 +39,7 @@
 #define VIRTIO_CONSOLE_F_SIZE  0       /* Does host provide console size? */
 #define VIRTIO_CONSOLE_F_MULTIPORT 1   /* Does host provide multiple ports? */
 
-#define VIRTIO_CONSOLE_BAD_ID          (~(u32)0)
+#define VIRTIO_CONSOLE_BAD_ID          (~(__u32)0)
 
 struct virtio_console_config {
        /* colums of the screens */
index a7e40ed8a07674fd0493c1495a012a09759d835b..70480a3aa69891b6ebc6c998e2202c3197a443ec 100644 (file)
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -752,19 +752,29 @@ static void do_smart_update(struct sem_array *sma, struct sembuf *sops, int nsop
                        int otime, struct list_head *pt)
 {
        int i;
+       int progress;
 
-       if (sma->complex_count || sops == NULL) {
-               if (update_queue(sma, -1, pt))
+       progress = 1;
+retry_global:
+       if (sma->complex_count) {
+               if (update_queue(sma, -1, pt)) {
+                       progress = 1;
                        otime = 1;
+                       sops = NULL;
+               }
        }
+       if (!progress)
+               goto done;
 
        if (!sops) {
                /* No semops; something special is going on. */
                for (i = 0; i < sma->sem_nsems; i++) {
-                       if (update_queue(sma, i, pt))
+                       if (update_queue(sma, i, pt)) {
                                otime = 1;
+                               progress = 1;
+                       }
                }
-               goto done;
+               goto done_checkretry;
        }
 
        /* Check the semaphores that were modified. */
@@ -772,8 +782,15 @@ static void do_smart_update(struct sem_array *sma, struct sembuf *sops, int nsop
                if (sops[i].sem_op > 0 ||
                        (sops[i].sem_op < 0 &&
                                sma->sem_base[sops[i].sem_num].semval == 0))
-                       if (update_queue(sma, sops[i].sem_num, pt))
+                       if (update_queue(sma, sops[i].sem_num, pt)) {
                                otime = 1;
+                               progress = 1;
+                       }
+       }
+done_checkretry:
+       if (progress) {
+               progress = 0;
+               goto retry_global;
        }
 done:
        if (otime)
index 83a2970295d19ffdb1bd7417ed2b1b54a815cba1..6bd4a90d1991cdf84e5d14fa187af4a3b3f390f9 100644 (file)
@@ -1021,9 +1021,6 @@ static void audit_log_rule_change(char *action, struct audit_krule *rule, int re
  * @seq: netlink audit message sequence (serial) number
  * @data: payload data
  * @datasz: size of payload data
- * @loginuid: loginuid of sender
- * @sessionid: sessionid for netlink audit message
- * @sid: SE Linux Security ID of sender
  */
 int audit_receive_filter(int type, int pid, int seq, void *data, size_t datasz)
 {
index 7a0cf68027ccf62118d4eb1da83ec00af3a0b49b..27963e2bf4bfe141d0884bbe9f05b0d74a7fcc47 100644 (file)
@@ -2072,8 +2072,10 @@ event_enable_func(struct ftrace_hash *hash,
  out_reg:
        /* Don't let event modules unload while probe registered */
        ret = try_module_get(file->event_call->mod);
-       if (!ret)
+       if (!ret) {
+               ret = -EBUSY;
                goto out_free;
+       }
 
        ret = __ftrace_event_enable_disable(file, 1, 1);
        if (ret < 0)
index e9c52e1b853a658c0b99580e092023d7f53a341e..c55a037a354eb9ffbd8f492f8e07c92e3aa0b941 100644 (file)
@@ -23,7 +23,7 @@ lib-y += kobject.o klist.o
 
 obj-y += bcd.o div64.o sort.o parser.o halfmd4.o debug_locks.o random32.o \
         bust_spinlocks.o hexdump.o kasprintf.o bitmap.o scatterlist.o \
-        gcd.o lcm.o list_sort.o uuid.o flex_array.o \
+        gcd.o lcm.o list_sort.o uuid.o flex_array.o iovec.o \
         bsearch.o find_last_bit.o find_next_bit.o llist.o memweight.o kfifo.o
 obj-y += string_helpers.o
 obj-$(CONFIG_TEST_STRING_HELPERS) += test-string_helpers.o
diff --git a/lib/iovec.c b/lib/iovec.c
new file mode 100644 (file)
index 0000000..454baa8
--- /dev/null
@@ -0,0 +1,53 @@
+#include <linux/uaccess.h>
+#include <linux/export.h>
+#include <linux/uio.h>
+
+/*
+ *     Copy iovec to kernel. Returns -EFAULT on error.
+ *
+ *     Note: this modifies the original iovec.
+ */
+
+int memcpy_fromiovec(unsigned char *kdata, struct iovec *iov, int len)
+{
+       while (len > 0) {
+               if (iov->iov_len) {
+                       int copy = min_t(unsigned int, len, iov->iov_len);
+                       if (copy_from_user(kdata, iov->iov_base, copy))
+                               return -EFAULT;
+                       len -= copy;
+                       kdata += copy;
+                       iov->iov_base += copy;
+                       iov->iov_len -= copy;
+               }
+               iov++;
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL(memcpy_fromiovec);
+
+/*
+ *     Copy kernel to iovec. Returns -EFAULT on error.
+ *
+ *     Note: this modifies the original iovec.
+ */
+
+int memcpy_toiovec(struct iovec *iov, unsigned char *kdata, int len)
+{
+       while (len > 0) {
+               if (iov->iov_len) {
+                       int copy = min_t(unsigned int, iov->iov_len, len);
+                       if (copy_to_user(iov->iov_base, kdata, copy))
+                               return -EFAULT;
+                       kdata += copy;
+                       len -= copy;
+                       iov->iov_len -= copy;
+                       iov->iov_base += copy;
+               }
+               iov++;
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL(memcpy_toiovec);
index 0874e41609a6fbf4d786f3b49aa76f85130893f7..358a368a2947057ef9d9309c9dd4fc893523d63d 100644 (file)
@@ -193,10 +193,10 @@ static void klist_release(struct kref *kref)
                if (waiter->node != n)
                        continue;
 
+               list_del(&waiter->list);
                waiter->woken = 1;
                mb();
                wake_up_process(waiter->process);
-               list_del(&waiter->list);
        }
        spin_unlock(&klist_remove_lock);
        knode_set_klist(n, NULL);
index 095ab157a5215a800d01585bbb50b0d6b6a88a17..d411355f238e2088247f0cbf51631c77ae78b10e 100644 (file)
@@ -318,7 +318,8 @@ extern UDItype __udiv_qrnnd();
             "rM" ((USItype)(bh)), \
             "rM" ((USItype)(al)), \
             "rM" ((USItype)(bl)))
-#if defined(_PA_RISC1_1)
+#if 0 && defined(_PA_RISC1_1)
+/* xmpyu uses floating point register which is not allowed in Linux kernel. */
 #define umul_ppmm(wh, wl, u, v) \
 do { \
        union {UDItype __ll; \
@@ -337,7 +338,7 @@ do { \
 #define UMUL_TIME 40
 #define UDIV_TIME 80
 #endif
-#ifndef LONGLONG_STANDALONE
+#if 0 /* #ifndef LONGLONG_STANDALONE */
 #define udiv_qrnnd(q, r, n1, n0, d) \
 do { USItype __r; \
        (q) = __udiv_qrnnd(&__r, (n1), (n0), (d)); \
index 03a89a2f464bef283770e84ad7186a5cc0915924..362c329b83fe7441b4d2119c1e164a54c58fc860 100644 (file)
@@ -2325,7 +2325,12 @@ static void collapse_huge_page(struct mm_struct *mm,
                pte_unmap(pte);
                spin_lock(&mm->page_table_lock);
                BUG_ON(!pmd_none(*pmd));
-               set_pmd_at(mm, address, pmd, _pmd);
+               /*
+                * We can only use set_pmd_at when establishing
+                * hugepmds and never for establishing regular pmds that
+                * points to regular pagetables. Use pmd_populate for that
+                */
+               pmd_populate(mm, pmd, pmd_pgtable(_pmd));
                spin_unlock(&mm->page_table_lock);
                anon_vma_unlock_write(vma->anon_vma);
                goto out;
index cb1c9dedf9b65c08a4a6d9d6f81ee01f2cb44c36..010d6c14129ae320ab9655a573d49af33e034659 100644 (file)
@@ -4108,8 +4108,6 @@ __mem_cgroup_uncharge_common(struct page *page, enum charge_type ctype,
        if (mem_cgroup_disabled())
                return NULL;
 
-       VM_BUG_ON(PageSwapCache(page));
-
        if (PageTransHuge(page)) {
                nr_pages <<= compound_order(page);
                VM_BUG_ON(!PageTransHuge(page));
@@ -4205,6 +4203,18 @@ void mem_cgroup_uncharge_page(struct page *page)
        if (page_mapped(page))
                return;
        VM_BUG_ON(page->mapping && !PageAnon(page));
+       /*
+        * If the page is in swap cache, uncharge should be deferred
+        * to the swap path, which also properly accounts swap usage
+        * and handles memcg lifetime.
+        *
+        * Note that this check is not stable and reclaim may add the
+        * page to swap cache at any time after this.  However, if the
+        * page is not in swap cache by the time page->mapcount hits
+        * 0, there won't be any page table references to the swap
+        * slot, and reclaim will free it and not actually write the
+        * page to disk.
+        */
        if (PageSwapCache(page))
                return;
        __mem_cgroup_uncharge_common(page, MEM_CGROUP_CHARGE_TYPE_ANON, false);
index a221fac1f47d39aef56278758765c023a7981796..1ad92b46753edfe8d9f54fae81c5f3aa15b34110 100644 (file)
@@ -720,9 +720,12 @@ int __remove_pages(struct zone *zone, unsigned long phys_start_pfn,
        start = phys_start_pfn << PAGE_SHIFT;
        size = nr_pages * PAGE_SIZE;
        ret = release_mem_region_adjustable(&iomem_resource, start, size);
-       if (ret)
-               pr_warn("Unable to release resource <%016llx-%016llx> (%d)\n",
-                               start, start + size - 1, ret);
+       if (ret) {
+               resource_size_t endres = start + size - 1;
+
+               pr_warn("Unable to release resource <%pa-%pa> (%d)\n",
+                               &start, &endres, ret);
+       }
 
        sections_to_remove = nr_pages / PAGES_PER_SECTION;
        for (i = 0; i < sections_to_remove; i++) {
index 27ed22579fd97a21171b952deb78316438e69297..b1f57501de9c8f4f0705b30fef748c4c3f145e86 100644 (file)
@@ -165,7 +165,7 @@ static int remove_migration_pte(struct page *new, struct vm_area_struct *vma,
                pte = arch_make_huge_pte(pte, vma, new, 0);
        }
 #endif
-       flush_cache_page(vma, addr, pte_pfn(pte));
+       flush_dcache_page(new);
        set_pte_at(mm, addr, ptep, pte);
 
        if (PageHuge(new)) {
index be04122fb277acd6a43a2f020e184ed2065258df..6725ff183374280ac9a5dcc786cd42f91d3cf669 100644 (file)
@@ -40,48 +40,44 @@ void __mmu_notifier_release(struct mm_struct *mm)
        int id;
 
        /*
-        * srcu_read_lock() here will block synchronize_srcu() in
-        * mmu_notifier_unregister() until all registered
-        * ->release() callouts this function makes have
-        * returned.
+        * SRCU here will block mmu_notifier_unregister until
+        * ->release returns.
         */
        id = srcu_read_lock(&srcu);
+       hlist_for_each_entry_rcu(mn, &mm->mmu_notifier_mm->list, hlist)
+               /*
+                * If ->release runs before mmu_notifier_unregister it must be
+                * handled, as it's the only way for the driver to flush all
+                * existing sptes and stop the driver from establishing any more
+                * sptes before all the pages in the mm are freed.
+                */
+               if (mn->ops->release)
+                       mn->ops->release(mn, mm);
+       srcu_read_unlock(&srcu, id);
+
        spin_lock(&mm->mmu_notifier_mm->lock);
        while (unlikely(!hlist_empty(&mm->mmu_notifier_mm->list))) {
                mn = hlist_entry(mm->mmu_notifier_mm->list.first,
                                 struct mmu_notifier,
                                 hlist);
-
                /*
-                * Unlink.  This will prevent mmu_notifier_unregister()
-                * from also making the ->release() callout.
+                * We arrived before mmu_notifier_unregister so
+                * mmu_notifier_unregister will do nothing other than to wait
+                * for ->release to finish and for mmu_notifier_unregister to
+                * return.
                 */
                hlist_del_init_rcu(&mn->hlist);
-               spin_unlock(&mm->mmu_notifier_mm->lock);
-
-               /*
-                * Clear sptes. (see 'release' description in mmu_notifier.h)
-                */
-               if (mn->ops->release)
-                       mn->ops->release(mn, mm);
-
-               spin_lock(&mm->mmu_notifier_mm->lock);
        }
        spin_unlock(&mm->mmu_notifier_mm->lock);
 
        /*
-        * All callouts to ->release() which we have done are complete.
-        * Allow synchronize_srcu() in mmu_notifier_unregister() to complete
-        */
-       srcu_read_unlock(&srcu, id);
-
-       /*
-        * mmu_notifier_unregister() may have unlinked a notifier and may
-        * still be calling out to it.  Additionally, other notifiers
-        * may have been active via vmtruncate() et. al. Block here
-        * to ensure that all notifier callouts for this mm have been
-        * completed and the sptes are really cleaned up before returning
-        * to exit_mmap().
+        * synchronize_srcu here prevents mmu_notifier_release from returning to
+        * exit_mmap (which would proceed with freeing all pages in the mm)
+        * until the ->release method returns, if it was invoked by
+        * mmu_notifier_unregister.
+        *
+        * The mmu_notifier_mm can't go away from under us because one mm_count
+        * is held by exit_mmap.
         */
        synchronize_srcu(&srcu);
 }
@@ -292,31 +288,34 @@ void mmu_notifier_unregister(struct mmu_notifier *mn, struct mm_struct *mm)
 {
        BUG_ON(atomic_read(&mm->mm_count) <= 0);
 
-       spin_lock(&mm->mmu_notifier_mm->lock);
        if (!hlist_unhashed(&mn->hlist)) {
+               /*
+                * SRCU here will force exit_mmap to wait for ->release to
+                * finish before freeing the pages.
+                */
                int id;
 
+               id = srcu_read_lock(&srcu);
                /*
-                * Ensure we synchronize up with __mmu_notifier_release().
+                * exit_mmap will block in mmu_notifier_release to guarantee
+                * that ->release is called before freeing the pages.
                 */
-               id = srcu_read_lock(&srcu);
-
-               hlist_del_rcu(&mn->hlist);
-               spin_unlock(&mm->mmu_notifier_mm->lock);
-
                if (mn->ops->release)
                        mn->ops->release(mn, mm);
+               srcu_read_unlock(&srcu, id);
 
+               spin_lock(&mm->mmu_notifier_mm->lock);
                /*
-                * Allow __mmu_notifier_release() to complete.
+                * Can not use list_del_rcu() since __mmu_notifier_release
+                * can delete it before we hold the lock.
                 */
-               srcu_read_unlock(&srcu, id);
-       } else
+               hlist_del_init_rcu(&mn->hlist);
                spin_unlock(&mm->mmu_notifier_mm->lock);
+       }
 
        /*
-        * Wait for any running method to finish, including ->release() if it
-        * was run by __mmu_notifier_release() instead of us.
+        * Wait for any running method to finish, of course including
+        * ->release if it was run by mmu_notifier_relase instead of us.
         */
        synchronize_srcu(&srcu);
 
index 98cbdf6e553217a87b62daac80d26c026ecf60e3..378a15bcd64940cd4bab29335604f757543839be 100644 (file)
@@ -5158,7 +5158,7 @@ unsigned long free_reserved_area(unsigned long start, unsigned long end,
        for (pages = 0; pos < end; pos += PAGE_SIZE, pages++) {
                if (poison)
                        memset((void *)pos, poison, PAGE_SIZE);
-               free_reserved_page(virt_to_page(pos));
+               free_reserved_page(virt_to_page((void *)pos));
        }
 
        if (pages && s)
index 35aa294656cd812d2773fede0d51179a8b7ee09a..5da2cbcfdbb56b0e9f4fe27d6e04137e59dfce3b 100644 (file)
@@ -127,28 +127,7 @@ static int walk_hugetlb_range(struct vm_area_struct *vma,
        return 0;
 }
 
-static struct vm_area_struct* hugetlb_vma(unsigned long addr, struct mm_walk *walk)
-{
-       struct vm_area_struct *vma;
-
-       /* We don't need vma lookup at all. */
-       if (!walk->hugetlb_entry)
-               return NULL;
-
-       VM_BUG_ON(!rwsem_is_locked(&walk->mm->mmap_sem));
-       vma = find_vma(walk->mm, addr);
-       if (vma && vma->vm_start <= addr && is_vm_hugetlb_page(vma))
-               return vma;
-
-       return NULL;
-}
-
 #else /* CONFIG_HUGETLB_PAGE */
-static struct vm_area_struct* hugetlb_vma(unsigned long addr, struct mm_walk *walk)
-{
-       return NULL;
-}
-
 static int walk_hugetlb_range(struct vm_area_struct *vma,
                              unsigned long addr, unsigned long end,
                              struct mm_walk *walk)
@@ -198,30 +177,53 @@ int walk_page_range(unsigned long addr, unsigned long end,
        if (!walk->mm)
                return -EINVAL;
 
+       VM_BUG_ON(!rwsem_is_locked(&walk->mm->mmap_sem));
+
        pgd = pgd_offset(walk->mm, addr);
        do {
-               struct vm_area_struct *vma;
+               struct vm_area_struct *vma = NULL;
 
                next = pgd_addr_end(addr, end);
 
                /*
-                * handle hugetlb vma individually because pagetable walk for
-                * the hugetlb page is dependent on the architecture and
-                * we can't handled it in the same manner as non-huge pages.
+                * This function was not intended to be vma based.
+                * But there are vma special cases to be handled:
+                * - hugetlb vma's
+                * - VM_PFNMAP vma's
                 */
-               vma = hugetlb_vma(addr, walk);
+               vma = find_vma(walk->mm, addr);
                if (vma) {
-                       if (vma->vm_end < next)
+                       /*
+                        * There are no page structures backing a VM_PFNMAP
+                        * range, so do not allow split_huge_page_pmd().
+                        */
+                       if ((vma->vm_start <= addr) &&
+                           (vma->vm_flags & VM_PFNMAP)) {
                                next = vma->vm_end;
+                               pgd = pgd_offset(walk->mm, next);
+                               continue;
+                       }
                        /*
-                        * Hugepage is very tightly coupled with vma, so
-                        * walk through hugetlb entries within a given vma.
+                        * Handle hugetlb vma individually because pagetable
+                        * walk for the hugetlb page is dependent on the
+                        * architecture and we can't handled it in the same
+                        * manner as non-huge pages.
                         */
-                       err = walk_hugetlb_range(vma, addr, next, walk);
-                       if (err)
-                               break;
-                       pgd = pgd_offset(walk->mm, next);
-                       continue;
+                       if (walk->hugetlb_entry && (vma->vm_start <= addr) &&
+                           is_vm_hugetlb_page(vma)) {
+                               if (vma->vm_end < next)
+                                       next = vma->vm_end;
+                               /*
+                                * Hugepage is very tightly coupled with vma,
+                                * so walk through hugetlb entries within a
+                                * given vma.
+                                */
+                               err = walk_hugetlb_range(vma, addr, next, walk);
+                               if (err)
+                                       break;
+                               pgd = pgd_offset(walk->mm, next);
+                               continue;
+                       }
                }
 
                if (pgd_none_or_clear_bad(pgd)) {
index e085bcc754f602e4401e51c8c29442a1bd143de8..1eb05d80b07bea736e85a389be0d98c8bfcb3d9c 100644 (file)
@@ -871,10 +871,10 @@ void mrp_uninit_applicant(struct net_device *dev, struct mrp_application *appl)
         */
        del_timer_sync(&app->join_timer);
 
-       spin_lock(&app->lock);
+       spin_lock_bh(&app->lock);
        mrp_mad_event(app, MRP_EVENT_TX);
        mrp_pdu_queue(app);
-       spin_unlock(&app->lock);
+       spin_unlock_bh(&app->lock);
 
        mrp_queue_xmit(app);
 
index 1240f07ad31dc631c5dc941f31bfd541f0205fea..51aafd669cbbd6a7714f9ab075f647313c8234d5 100644 (file)
@@ -181,6 +181,7 @@ void batadv_mesh_free(struct net_device *soft_iface)
        batadv_originator_free(bat_priv);
 
        free_percpu(bat_priv->bat_counters);
+       bat_priv->bat_counters = NULL;
 
        atomic_set(&bat_priv->mesh_state, BATADV_MESH_INACTIVE);
 }
index 2f3452546636ce71747ef9a8b1a949caae8d8f04..fad1a2093e15fee8889bb190fac96868143bd0f5 100644 (file)
@@ -156,12 +156,28 @@ static void batadv_orig_node_free_rcu(struct rcu_head *rcu)
        kfree(orig_node);
 }
 
+/**
+ * batadv_orig_node_free_ref - decrement the orig node refcounter and possibly
+ * schedule an rcu callback for freeing it
+ * @orig_node: the orig node to free
+ */
 void batadv_orig_node_free_ref(struct batadv_orig_node *orig_node)
 {
        if (atomic_dec_and_test(&orig_node->refcount))
                call_rcu(&orig_node->rcu, batadv_orig_node_free_rcu);
 }
 
+/**
+ * batadv_orig_node_free_ref_now - decrement the orig node refcounter and
+ * possibly free it (without rcu callback)
+ * @orig_node: the orig node to free
+ */
+void batadv_orig_node_free_ref_now(struct batadv_orig_node *orig_node)
+{
+       if (atomic_dec_and_test(&orig_node->refcount))
+               batadv_orig_node_free_rcu(&orig_node->rcu);
+}
+
 void batadv_originator_free(struct batadv_priv *bat_priv)
 {
        struct batadv_hashtable *hash = bat_priv->orig_hash;
index 7df48fa7669dd0ac173a51bafe3d6538fb049e4b..734e5a3d8a5b29fdf389b04db14e3a37504cf3cb 100644 (file)
@@ -26,6 +26,7 @@ int batadv_originator_init(struct batadv_priv *bat_priv);
 void batadv_originator_free(struct batadv_priv *bat_priv);
 void batadv_purge_orig_ref(struct batadv_priv *bat_priv);
 void batadv_orig_node_free_ref(struct batadv_orig_node *orig_node);
+void batadv_orig_node_free_ref_now(struct batadv_orig_node *orig_node);
 struct batadv_orig_node *batadv_get_orig_node(struct batadv_priv *bat_priv,
                                              const uint8_t *addr);
 struct batadv_neigh_node *
index 6f20d339e33adb3bab929d9bc406f3c8cebd959a..819dfb006cdfafbcd3c63d12c5f7e76c0588ed43 100644 (file)
@@ -505,6 +505,7 @@ unreg_debugfs:
        batadv_debugfs_del_meshif(dev);
 free_bat_counters:
        free_percpu(bat_priv->bat_counters);
+       bat_priv->bat_counters = NULL;
 
        return ret;
 }
index 5e89deeb9542979c72ba635fb1c18d301a9c1621..9e87485758455743984bf51bf783c7bf61cee348 100644 (file)
@@ -144,7 +144,12 @@ static void batadv_tt_orig_list_entry_free_rcu(struct rcu_head *rcu)
        struct batadv_tt_orig_list_entry *orig_entry;
 
        orig_entry = container_of(rcu, struct batadv_tt_orig_list_entry, rcu);
-       batadv_orig_node_free_ref(orig_entry->orig_node);
+
+       /* We are in an rcu callback here, therefore we cannot use
+        * batadv_orig_node_free_ref() and its call_rcu():
+        * An rcu_barrier() wouldn't wait for that to finish
+        */
+       batadv_orig_node_free_ref_now(orig_entry->orig_node);
        kfree(orig_entry);
 }
 
index 9878eb8204c524334be49d0445cae9c29927ca0d..19c37a4929bcd7619d43573285d5d33dfa3b865f 100644 (file)
@@ -72,13 +72,12 @@ print_ports(const struct sk_buff *skb, uint8_t protocol, int offset)
 }
 
 static void
-ebt_log_packet(u_int8_t pf, unsigned int hooknum,
-   const struct sk_buff *skb, const struct net_device *in,
-   const struct net_device *out, const struct nf_loginfo *loginfo,
-   const char *prefix)
+ebt_log_packet(struct net *net, u_int8_t pf, unsigned int hooknum,
+              const struct sk_buff *skb, const struct net_device *in,
+              const struct net_device *out, const struct nf_loginfo *loginfo,
+              const char *prefix)
 {
        unsigned int bitmask;
-       struct net *net = dev_net(in ? in : out);
 
        /* FIXME: Disabled from containers until syslog ns is supported */
        if (!net_eq(net, &init_net))
@@ -191,7 +190,7 @@ ebt_log_tg(struct sk_buff *skb, const struct xt_action_param *par)
                nf_log_packet(net, NFPROTO_BRIDGE, par->hooknum, skb,
                              par->in, par->out, &li, "%s", info->prefix);
        else
-               ebt_log_packet(NFPROTO_BRIDGE, par->hooknum, skb, par->in,
+               ebt_log_packet(net, NFPROTO_BRIDGE, par->hooknum, skb, par->in,
                               par->out, &li, info->prefix);
        return EBT_CONTINUE;
 }
index fc1905c514178a1ae439060588e06a7c5d26e446..df0364aa12d518c74b769b04d11c55182323773c 100644 (file)
@@ -131,14 +131,16 @@ static struct sk_buff *ulog_alloc_skb(unsigned int size)
        return skb;
 }
 
-static void ebt_ulog_packet(unsigned int hooknr, const struct sk_buff *skb,
-   const struct net_device *in, const struct net_device *out,
-   const struct ebt_ulog_info *uloginfo, const char *prefix)
+static void ebt_ulog_packet(struct net *net, unsigned int hooknr,
+                           const struct sk_buff *skb,
+                           const struct net_device *in,
+                           const struct net_device *out,
+                           const struct ebt_ulog_info *uloginfo,
+                           const char *prefix)
 {
        ebt_ulog_packet_msg_t *pm;
        size_t size, copy_len;
        struct nlmsghdr *nlh;
-       struct net *net = dev_net(in ? in : out);
        struct ebt_ulog_net *ebt = ebt_ulog_pernet(net);
        unsigned int group = uloginfo->nlgroup;
        ebt_ulog_buff_t *ub = &ebt->ulog_buffers[group];
@@ -233,7 +235,7 @@ unlock:
 }
 
 /* this function is registered with the netfilter core */
-static void ebt_log_packet(u_int8_t pf, unsigned int hooknum,
+static void ebt_log_packet(struct net *net, u_int8_t pf, unsigned int hooknum,
    const struct sk_buff *skb, const struct net_device *in,
    const struct net_device *out, const struct nf_loginfo *li,
    const char *prefix)
@@ -252,13 +254,15 @@ static void ebt_log_packet(u_int8_t pf, unsigned int hooknum,
                strlcpy(loginfo.prefix, prefix, sizeof(loginfo.prefix));
        }
 
-       ebt_ulog_packet(hooknum, skb, in, out, &loginfo, prefix);
+       ebt_ulog_packet(net, hooknum, skb, in, out, &loginfo, prefix);
 }
 
 static unsigned int
 ebt_ulog_tg(struct sk_buff *skb, const struct xt_action_param *par)
 {
-       ebt_ulog_packet(par->hooknum, skb, par->in, par->out,
+       struct net *net = dev_net(par->in ? par->in : par->out);
+
+       ebt_ulog_packet(net, par->hooknum, skb, par->in, par->out,
                        par->targinfo, NULL);
        return EBT_CONTINUE;
 }
index 7e7aeb01de45cf3236469d7f62b51254b73abac4..de178e462682af6c97dbfc4326df85942ec25174 100644 (file)
@@ -73,31 +73,6 @@ int verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr_storage *a
        return err;
 }
 
-/*
- *     Copy kernel to iovec. Returns -EFAULT on error.
- *
- *     Note: this modifies the original iovec.
- */
-
-int memcpy_toiovec(struct iovec *iov, unsigned char *kdata, int len)
-{
-       while (len > 0) {
-               if (iov->iov_len) {
-                       int copy = min_t(unsigned int, iov->iov_len, len);
-                       if (copy_to_user(iov->iov_base, kdata, copy))
-                               return -EFAULT;
-                       kdata += copy;
-                       len -= copy;
-                       iov->iov_len -= copy;
-                       iov->iov_base += copy;
-               }
-               iov++;
-       }
-
-       return 0;
-}
-EXPORT_SYMBOL(memcpy_toiovec);
-
 /*
  *     Copy kernel to iovec. Returns -EFAULT on error.
  */
@@ -124,31 +99,6 @@ int memcpy_toiovecend(const struct iovec *iov, unsigned char *kdata,
 }
 EXPORT_SYMBOL(memcpy_toiovecend);
 
-/*
- *     Copy iovec to kernel. Returns -EFAULT on error.
- *
- *     Note: this modifies the original iovec.
- */
-
-int memcpy_fromiovec(unsigned char *kdata, struct iovec *iov, int len)
-{
-       while (len > 0) {
-               if (iov->iov_len) {
-                       int copy = min_t(unsigned int, len, iov->iov_len);
-                       if (copy_from_user(kdata, iov->iov_base, copy))
-                               return -EFAULT;
-                       len -= copy;
-                       kdata += copy;
-                       iov->iov_base += copy;
-                       iov->iov_len -= copy;
-               }
-               iov++;
-       }
-
-       return 0;
-}
-EXPORT_SYMBOL(memcpy_fromiovec);
-
 /*
  *     Copy iovec from kernel. Returns -EFAULT on error.
  */
index c625e4dad4b05066d92fe02d1778b555234d0f2a..2a83591492dd6f3e8b7470c3e9b897dad7625a49 100644 (file)
@@ -235,7 +235,7 @@ static void ipgre_err(struct sk_buff *skb, u32 info)
           */
        struct net *net = dev_net(skb->dev);
        struct ip_tunnel_net *itn;
-       const struct iphdr *iph = (const struct iphdr *)skb->data;
+       const struct iphdr *iph;
        const int type = icmp_hdr(skb)->type;
        const int code = icmp_hdr(skb)->code;
        struct ip_tunnel *t;
@@ -281,6 +281,7 @@ static void ipgre_err(struct sk_buff *skb, u32 info)
        else
                itn = net_generic(net, ipgre_net_id);
 
+       iph = (const struct iphdr *)skb->data;
        t = ip_tunnel_lookup(itn, skb->dev->ifindex, tpi.flags,
                             iph->daddr, iph->saddr, tpi.key);
 
index f8a222cb64481c95e2f3b53207e3c6a3d372f4d2..cf08218ddbcf6799464139b681239137de2d9142 100644 (file)
@@ -162,7 +162,8 @@ static struct sk_buff *ulog_alloc_skb(unsigned int size)
        return skb;
 }
 
-static void ipt_ulog_packet(unsigned int hooknum,
+static void ipt_ulog_packet(struct net *net,
+                           unsigned int hooknum,
                            const struct sk_buff *skb,
                            const struct net_device *in,
                            const struct net_device *out,
@@ -174,7 +175,6 @@ static void ipt_ulog_packet(unsigned int hooknum,
        size_t size, copy_len;
        struct nlmsghdr *nlh;
        struct timeval tv;
-       struct net *net = dev_net(in ? in : out);
        struct ulog_net *ulog = ulog_pernet(net);
 
        /* ffs == find first bit set, necessary because userspace
@@ -291,12 +291,15 @@ alloc_failure:
 static unsigned int
 ulog_tg(struct sk_buff *skb, const struct xt_action_param *par)
 {
-       ipt_ulog_packet(par->hooknum, skb, par->in, par->out,
+       struct net *net = dev_net(par->in ? par->in : par->out);
+
+       ipt_ulog_packet(net, par->hooknum, skb, par->in, par->out,
                        par->targinfo, NULL);
        return XT_CONTINUE;
 }
 
-static void ipt_logfn(u_int8_t pf,
+static void ipt_logfn(struct net *net,
+                     u_int8_t pf,
                      unsigned int hooknum,
                      const struct sk_buff *skb,
                      const struct net_device *in,
@@ -318,7 +321,7 @@ static void ipt_logfn(u_int8_t pf,
                strlcpy(loginfo.prefix, prefix, sizeof(loginfo.prefix));
        }
 
-       ipt_ulog_packet(hooknum, skb, in, out, &loginfo, prefix);
+       ipt_ulog_packet(net, hooknum, skb, in, out, &loginfo, prefix);
 }
 
 static int ulog_tg_check(const struct xt_tgchk_param *par)
index dcb116dde2168759025d315f4e2d3b77994a276a..ab450c099aa49a3d4b68ca531e7f5426a8eabaf1 100644 (file)
@@ -2887,6 +2887,7 @@ struct sk_buff *tcp_tso_segment(struct sk_buff *skb,
        unsigned int mss;
        struct sk_buff *gso_skb = skb;
        __sum16 newcheck;
+       bool ooo_okay, copy_destructor;
 
        if (!pskb_may_pull(skb, sizeof(*th)))
                goto out;
@@ -2927,10 +2928,18 @@ struct sk_buff *tcp_tso_segment(struct sk_buff *skb,
                goto out;
        }
 
+       copy_destructor = gso_skb->destructor == tcp_wfree;
+       ooo_okay = gso_skb->ooo_okay;
+       /* All segments but the first should have ooo_okay cleared */
+       skb->ooo_okay = 0;
+
        segs = skb_segment(skb, features);
        if (IS_ERR(segs))
                goto out;
 
+       /* Only first segment might have ooo_okay set */
+       segs->ooo_okay = ooo_okay;
+
        delta = htonl(oldlen + (thlen + mss));
 
        skb = segs;
@@ -2950,6 +2959,17 @@ struct sk_buff *tcp_tso_segment(struct sk_buff *skb,
                                                    thlen, skb->csum));
 
                seq += mss;
+               if (copy_destructor) {
+                       skb->destructor = gso_skb->destructor;
+                       skb->sk = gso_skb->sk;
+                       /* {tcp|sock}_wfree() use exact truesize accounting :
+                        * sum(skb->truesize) MUST be exactly be gso_skb->truesize
+                        * So we account mss bytes of 'true size' for each segment.
+                        * The last segment will contain the remaining.
+                        */
+                       skb->truesize = mss;
+                       gso_skb->truesize -= mss;
+               }
                skb = skb->next;
                th = tcp_hdr(skb);
 
@@ -2962,7 +2982,7 @@ struct sk_buff *tcp_tso_segment(struct sk_buff *skb,
         * is freed at TX completion, and not right now when gso_skb
         * is freed by GSO engine
         */
-       if (gso_skb->destructor == tcp_wfree) {
+       if (copy_destructor) {
                swap(gso_skb->sk, skb->sk);
                swap(gso_skb->destructor, skb->destructor);
                swap(gso_skb->truesize, skb->truesize);
@@ -3269,8 +3289,11 @@ int tcp_md5_hash_skb_data(struct tcp_md5sig_pool *hp,
 
        for (i = 0; i < shi->nr_frags; ++i) {
                const struct skb_frag_struct *f = &shi->frags[i];
-               struct page *page = skb_frag_page(f);
-               sg_set_page(&sg, page, skb_frag_size(f), f->page_offset);
+               unsigned int offset = f->page_offset;
+               struct page *page = skb_frag_page(f) + (offset >> PAGE_SHIFT);
+
+               sg_set_page(&sg, page, skb_frag_size(f),
+                           offset_in_page(offset));
                if (crypto_hash_update(desc, &sg, skb_frag_size(f)))
                        return 1;
        }
index 08bbe609652891f593ccc2f48ec9975bbe2f335d..9c6225780bd5aafdb175a762d45c704e82416582 100644 (file)
@@ -2743,8 +2743,8 @@ static void tcp_process_loss(struct sock *sk, int flag, bool is_dupack)
  * tcp_xmit_retransmit_queue().
  */
 static void tcp_fastretrans_alert(struct sock *sk, int pkts_acked,
-                                 int prior_sacked, bool is_dupack,
-                                 int flag)
+                                 int prior_sacked, int prior_packets,
+                                 bool is_dupack, int flag)
 {
        struct inet_connection_sock *icsk = inet_csk(sk);
        struct tcp_sock *tp = tcp_sk(sk);
@@ -2804,7 +2804,8 @@ static void tcp_fastretrans_alert(struct sock *sk, int pkts_acked,
                                tcp_add_reno_sack(sk);
                } else
                        do_lost = tcp_try_undo_partial(sk, pkts_acked);
-               newly_acked_sacked = pkts_acked + tp->sacked_out - prior_sacked;
+               newly_acked_sacked = prior_packets - tp->packets_out +
+                                    tp->sacked_out - prior_sacked;
                break;
        case TCP_CA_Loss:
                tcp_process_loss(sk, flag, is_dupack);
@@ -2818,7 +2819,8 @@ static void tcp_fastretrans_alert(struct sock *sk, int pkts_acked,
                        if (is_dupack)
                                tcp_add_reno_sack(sk);
                }
-               newly_acked_sacked = pkts_acked + tp->sacked_out - prior_sacked;
+               newly_acked_sacked = prior_packets - tp->packets_out +
+                                    tp->sacked_out - prior_sacked;
 
                if (icsk->icsk_ca_state <= TCP_CA_Disorder)
                        tcp_try_undo_dsack(sk);
@@ -3330,9 +3332,10 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag)
        bool is_dupack = false;
        u32 prior_in_flight;
        u32 prior_fackets;
-       int prior_packets;
+       int prior_packets = tp->packets_out;
        int prior_sacked = tp->sacked_out;
        int pkts_acked = 0;
+       int previous_packets_out = 0;
 
        /* If the ack is older than previous acks
         * then we can probably ignore it.
@@ -3403,14 +3406,14 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag)
        sk->sk_err_soft = 0;
        icsk->icsk_probes_out = 0;
        tp->rcv_tstamp = tcp_time_stamp;
-       prior_packets = tp->packets_out;
        if (!prior_packets)
                goto no_queue;
 
        /* See if we can take anything off of the retransmit queue. */
+       previous_packets_out = tp->packets_out;
        flag |= tcp_clean_rtx_queue(sk, prior_fackets, prior_snd_una);
 
-       pkts_acked = prior_packets - tp->packets_out;
+       pkts_acked = previous_packets_out - tp->packets_out;
 
        if (tcp_ack_is_dubious(sk, flag)) {
                /* Advance CWND, if state allows this. */
@@ -3418,7 +3421,7 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag)
                        tcp_cong_avoid(sk, ack, prior_in_flight);
                is_dupack = !(flag & (FLAG_SND_UNA_ADVANCED | FLAG_NOT_DUP));
                tcp_fastretrans_alert(sk, pkts_acked, prior_sacked,
-                                     is_dupack, flag);
+                                     prior_packets, is_dupack, flag);
        } else {
                if (flag & FLAG_DATA_ACKED)
                        tcp_cong_avoid(sk, ack, prior_in_flight);
@@ -3441,7 +3444,7 @@ no_queue:
        /* If data was DSACKed, see if we can undo a cwnd reduction. */
        if (flag & FLAG_DSACKING_ACK)
                tcp_fastretrans_alert(sk, pkts_acked, prior_sacked,
-                                     is_dupack, flag);
+                                     prior_packets, is_dupack, flag);
        /* If this ack opens up a zero window, clear backoff.  It was
         * being used to time the probes, and is probably far higher than
         * it needs to be for normal retransmission.
@@ -3464,7 +3467,7 @@ old_ack:
        if (TCP_SKB_CB(skb)->sacked) {
                flag |= tcp_sacktag_write_queue(sk, skb, prior_snd_una);
                tcp_fastretrans_alert(sk, pkts_acked, prior_sacked,
-                                     is_dupack, flag);
+                                     prior_packets, is_dupack, flag);
        }
 
        SOCK_DEBUG(sk, "Ack %u before %u:%u\n", ack, tp->snd_una, tp->snd_nxt);
index 536d40929ba6f809d5c79968c48053202dd3748f..ec335fabd5cc12daba8addf5de86adc90abbd561 100644 (file)
@@ -874,11 +874,13 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it,
                                                           &md5);
        tcp_header_size = tcp_options_size + sizeof(struct tcphdr);
 
-       if (tcp_packets_in_flight(tp) == 0) {
+       if (tcp_packets_in_flight(tp) == 0)
                tcp_ca_event(sk, CA_EVENT_TX_START);
-               skb->ooo_okay = 1;
-       } else
-               skb->ooo_okay = 0;
+
+       /* if no packet is in qdisc/device queue, then allow XPS to select
+        * another queue.
+        */
+       skb->ooo_okay = sk_wmem_alloc_get(sk) == 0;
 
        skb_push(skb, tcp_header_size);
        skb_reset_transport_header(skb);
index d2eedf192330caf5a963c27ddaceffae5e4886b8..dae1949019d7b8dc77d14c39478571e86ad89f34 100644 (file)
@@ -1147,7 +1147,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
                        if (WARN_ON(np->cork.opt))
                                return -EINVAL;
 
-                       np->cork.opt = kmalloc(opt->tot_len, sk->sk_allocation);
+                       np->cork.opt = kzalloc(opt->tot_len, sk->sk_allocation);
                        if (unlikely(np->cork.opt == NULL))
                                return -ENOBUFS;
 
index 8c004161a843a2e33a963ddd254c4a0e5a129969..9ea0c933b9ff8803c071367bfef0df210090a90f 100644 (file)
@@ -544,7 +544,7 @@ static void irlap_recv_discovery_xid_cmd(struct irlap_cb *self,
                /*
                 *  We now have some discovery info to deliver!
                 */
-               discovery = kmalloc(sizeof(discovery_t), GFP_ATOMIC);
+               discovery = kzalloc(sizeof(discovery_t), GFP_ATOMIC);
                if (!discovery) {
                        IRDA_WARNING("%s: unable to malloc!\n", __func__);
                        return;
index 158e6eb188d388e99cb92a7a7cee9429a7bc2108..44be28cfc6c4b17c7ee6251a1670f207ea99922e 100644 (file)
@@ -1267,6 +1267,7 @@ void ieee80211_sta_reset_conn_monitor(struct ieee80211_sub_if_data *sdata);
 void ieee80211_mgd_stop(struct ieee80211_sub_if_data *sdata);
 void ieee80211_mgd_conn_tx_status(struct ieee80211_sub_if_data *sdata,
                                  __le16 fc, bool acked);
+void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata);
 
 /* IBSS code */
 void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local);
index 29620bfc7a69663c34ab89b5bd03875eaaa4c25c..a46e490f20dd777d2d7f8dd39c5bee02e4eb60ef 100644 (file)
@@ -1015,7 +1015,8 @@ static void ieee80211_chswitch_timer(unsigned long data)
 
 static void
 ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
-                                u64 timestamp, struct ieee802_11_elems *elems)
+                                u64 timestamp, struct ieee802_11_elems *elems,
+                                bool beacon)
 {
        struct ieee80211_local *local = sdata->local;
        struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
@@ -1032,6 +1033,7 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
        struct cfg80211_chan_def new_vht_chandef = {};
        const struct ieee80211_sec_chan_offs_ie *sec_chan_offs;
        const struct ieee80211_wide_bw_chansw_ie *wide_bw_chansw_ie;
+       const struct ieee80211_ht_operation *ht_oper;
        int secondary_channel_offset = -1;
 
        ASSERT_MGD_MTX(ifmgd);
@@ -1048,11 +1050,14 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
 
        sec_chan_offs = elems->sec_chan_offs;
        wide_bw_chansw_ie = elems->wide_bw_chansw_ie;
+       ht_oper = elems->ht_operation;
 
        if (ifmgd->flags & (IEEE80211_STA_DISABLE_HT |
                            IEEE80211_STA_DISABLE_40MHZ)) {
                sec_chan_offs = NULL;
                wide_bw_chansw_ie = NULL;
+               /* only used for bandwidth here */
+               ht_oper = NULL;
        }
 
        if (ifmgd->flags & IEEE80211_STA_DISABLE_VHT)
@@ -1094,10 +1099,20 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
                return;
        }
 
-       if (sec_chan_offs) {
+       if (!beacon && sec_chan_offs) {
                secondary_channel_offset = sec_chan_offs->sec_chan_offs;
+       } else if (beacon && ht_oper) {
+               secondary_channel_offset =
+                       ht_oper->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET;
        } else if (!(ifmgd->flags & IEEE80211_STA_DISABLE_HT)) {
-               /* if HT is enabled and the IE not present, it's still HT */
+               /*
+                * If it's not a beacon, HT is enabled and the IE not present,
+                * it's 20 MHz, 802.11-2012 8.5.2.6:
+                *      This element [the Secondary Channel Offset Element] is
+                *      present when switching to a 40 MHz channel. It may be
+                *      present when switching to a 20 MHz channel (in which
+                *      case the secondary channel offset is set to SCN).
+                */
                secondary_channel_offset = IEEE80211_HT_PARAM_CHA_SEC_NONE;
        }
 
@@ -2796,7 +2811,8 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
                mutex_unlock(&local->iflist_mtx);
        }
 
-       ieee80211_sta_process_chanswitch(sdata, rx_status->mactime, elems);
+       ieee80211_sta_process_chanswitch(sdata, rx_status->mactime,
+                                        elems, true);
 
 }
 
@@ -3210,7 +3226,7 @@ void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
 
                        ieee80211_sta_process_chanswitch(sdata,
                                                         rx_status->mactime,
-                                                        &elems);
+                                                        &elems, false);
                } else if (mgmt->u.action.category == WLAN_CATEGORY_PUBLIC) {
                        ies_len = skb->len -
                                  offsetof(struct ieee80211_mgmt,
@@ -3232,7 +3248,7 @@ void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
 
                        ieee80211_sta_process_chanswitch(sdata,
                                                         rx_status->mactime,
-                                                        &elems);
+                                                        &elems, false);
                }
                break;
        }
@@ -3623,6 +3639,31 @@ static void ieee80211_restart_sta_timer(struct ieee80211_sub_if_data *sdata)
        }
 }
 
+#ifdef CONFIG_PM
+void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata)
+{
+       struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
+
+       mutex_lock(&ifmgd->mtx);
+       if (!ifmgd->associated) {
+               mutex_unlock(&ifmgd->mtx);
+               return;
+       }
+
+       if (sdata->flags & IEEE80211_SDATA_DISCONNECT_RESUME) {
+               sdata->flags &= ~IEEE80211_SDATA_DISCONNECT_RESUME;
+               mlme_dbg(sdata, "driver requested disconnect after resume\n");
+               ieee80211_sta_connection_lost(sdata,
+                                             ifmgd->associated->bssid,
+                                             WLAN_REASON_UNSPECIFIED,
+                                             true);
+               mutex_unlock(&ifmgd->mtx);
+               return;
+       }
+       mutex_unlock(&ifmgd->mtx);
+}
+#endif
+
 /* interface setup */
 void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata)
 {
@@ -4329,7 +4370,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
        struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
        u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN];
        bool tx = !req->local_state_change;
-       bool sent_frame = false;
+       bool report_frame = false;
 
        mutex_lock(&ifmgd->mtx);
 
@@ -4346,7 +4387,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
                ieee80211_destroy_auth_data(sdata, false);
                mutex_unlock(&ifmgd->mtx);
 
-               sent_frame = tx;
+               report_frame = true;
                goto out;
        }
 
@@ -4354,12 +4395,12 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
            ether_addr_equal(ifmgd->associated->bssid, req->bssid)) {
                ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH,
                                       req->reason_code, tx, frame_buf);
-               sent_frame = tx;
+               report_frame = true;
        }
        mutex_unlock(&ifmgd->mtx);
 
  out:
-       if (sent_frame)
+       if (report_frame)
                __cfg80211_send_deauth(sdata->dev, frame_buf,
                                       IEEE80211_DEAUTH_FRAME_LEN);
 
index 0d51877efdb74260b07f33935ce2101df6f57678..d3f414fe67e0beb9592e87d344a6b3a5c0fed66b 100644 (file)
@@ -688,8 +688,15 @@ int rate_control_set_rates(struct ieee80211_hw *hw,
                           struct ieee80211_sta *pubsta,
                           struct ieee80211_sta_rates *rates)
 {
-       struct ieee80211_sta_rates *old = rcu_dereference(pubsta->rates);
+       struct ieee80211_sta_rates *old;
 
+       /*
+        * mac80211 guarantees that this function will not be called
+        * concurrently, so the following RCU access is safe, even without
+        * extra locking. This can not be checked easily, so we just set
+        * the condition to true.
+        */
+       old = rcu_dereference_protected(pubsta->rates, true);
        rcu_assign_pointer(pubsta->rates, rates);
        if (old)
                kfree_rcu(old, rcu_head);
index c8447af76ead2d598fc08c82860b64079e8c0d22..8e29526202568f0223401659f4301500d5f9d424 100644 (file)
@@ -3036,6 +3036,9 @@ static int prepare_for_handlers(struct ieee80211_rx_data *rx,
                         * and location updates. Note that mac80211
                         * itself never looks at these frames.
                         */
+                       if (!multicast &&
+                           !ether_addr_equal(sdata->vif.addr, hdr->addr1))
+                               return 0;
                        if (ieee80211_is_public_action(hdr, skb->len))
                                return 1;
                        if (!ieee80211_is_beacon(hdr->frame_control))
index 3ed801d90f1e67ccd24f85afa3196d910970742c..124b1fdc20d05531bccfa32e6ccc5f72c7cef1bb 100644 (file)
@@ -208,10 +208,10 @@ void ieee80211_get_tkip_p2k(struct ieee80211_key_conf *keyconf,
        u32 iv32 = get_unaligned_le32(&data[4]);
        u16 iv16 = data[2] | (data[0] << 8);
 
-       spin_lock_bh(&key->u.tkip.txlock);
+       spin_lock(&key->u.tkip.txlock);
        ieee80211_compute_tkip_p1k(key, iv32);
        tkip_mixing_phase2(tk, ctx, iv16, p2k);
-       spin_unlock_bh(&key->u.tkip.txlock);
+       spin_unlock(&key->u.tkip.txlock);
 }
 EXPORT_SYMBOL(ieee80211_get_tkip_p2k);
 
index 3f87fa468b1fc18d0ab00079166da5bf053aa738..27e07150eb465824475f9fc15348ed2615e46738 100644 (file)
@@ -1740,6 +1740,13 @@ int ieee80211_reconfig(struct ieee80211_local *local)
        mb();
        local->resuming = false;
 
+       list_for_each_entry(sdata, &local->interfaces, list) {
+               if (!ieee80211_sdata_running(sdata))
+                       continue;
+               if (sdata->vif.type == NL80211_IFTYPE_STATION)
+                       ieee80211_sta_restart(sdata);
+       }
+
        mod_timer(&local->sta_cleanup, jiffies + 1);
 #else
        WARN_ON(1);
index 388656d5a9ec45a6049af9e2915aaa7df1eefbbe..3b18dd1be7d9948ca4eb768a3c670a1c1e8ee910 100644 (file)
@@ -148,7 +148,7 @@ void nf_log_packet(struct net *net,
                va_start(args, fmt);
                vsnprintf(prefix, sizeof(prefix), fmt, args);
                va_end(args);
-               logger->logfn(pf, hooknum, skb, in, out, loginfo, prefix);
+               logger->logfn(net, pf, hooknum, skb, in, out, loginfo, prefix);
        }
        rcu_read_unlock();
 }
@@ -368,17 +368,20 @@ static int __net_init nf_log_net_init(struct net *net)
        return 0;
 
 out_sysctl:
+#ifdef CONFIG_PROC_FS
        /* For init_net: errors will trigger panic, don't unroll on error. */
        if (!net_eq(net, &init_net))
                remove_proc_entry("nf_log", net->nf.proc_netfilter);
-
+#endif
        return ret;
 }
 
 static void __net_exit nf_log_net_exit(struct net *net)
 {
        netfilter_log_sysctl_exit(net);
+#ifdef CONFIG_PROC_FS
        remove_proc_entry("nf_log", net->nf.proc_netfilter);
+#endif
 }
 
 static struct pernet_operations nf_log_net_ops = {
index faf1e9300d8adc358fa857ff4296892351060193..962e9792e3179997db98a448a76fc909432d841f 100644 (file)
@@ -602,7 +602,8 @@ static struct nf_loginfo default_loginfo = {
 
 /* log handler for internal netfilter logging api */
 void
-nfulnl_log_packet(u_int8_t pf,
+nfulnl_log_packet(struct net *net,
+                 u_int8_t pf,
                  unsigned int hooknum,
                  const struct sk_buff *skb,
                  const struct net_device *in,
@@ -615,7 +616,6 @@ nfulnl_log_packet(u_int8_t pf,
        const struct nf_loginfo *li;
        unsigned int qthreshold;
        unsigned int plen;
-       struct net *net = dev_net(in ? in : out);
        struct nfnl_log_net *log = nfnl_log_pernet(net);
 
        if (li_user && li_user->type == NF_LOG_TYPE_ULOG)
@@ -1045,7 +1045,9 @@ static int __net_init nfnl_log_net_init(struct net *net)
 
 static void __net_exit nfnl_log_net_exit(struct net *net)
 {
+#ifdef CONFIG_PROC_FS
        remove_proc_entry("nfnetlink_log", net->nf.proc_netfilter);
+#endif
 }
 
 static struct pernet_operations nfnl_log_net_ops = {
index 2e0e835baf7273427e84c971d4701f122e9c4a40..4e27fa035814ab8a571268b3a9e4dd8b0cd7bce4 100644 (file)
@@ -1285,7 +1285,9 @@ static int __net_init nfnl_queue_net_init(struct net *net)
 
 static void __net_exit nfnl_queue_net_exit(struct net *net)
 {
+#ifdef CONFIG_PROC_FS
        remove_proc_entry("nfnetlink_queue", net->nf.proc_netfilter);
+#endif
 }
 
 static struct pernet_operations nfnl_queue_net_ops = {
index fe573f6c9e9161e4201e6cbc8698c3b58b0583b2..491c7d821a0bd1f984159249312ae8f40345fd3a 100644 (file)
@@ -466,7 +466,8 @@ log_packet_common(struct sbuff *m,
 
 
 static void
-ipt_log_packet(u_int8_t pf,
+ipt_log_packet(struct net *net,
+              u_int8_t pf,
               unsigned int hooknum,
               const struct sk_buff *skb,
               const struct net_device *in,
@@ -475,7 +476,6 @@ ipt_log_packet(u_int8_t pf,
               const char *prefix)
 {
        struct sbuff *m;
-       struct net *net = dev_net(in ? in : out);
 
        /* FIXME: Disabled from containers until syslog ns is supported */
        if (!net_eq(net, &init_net))
@@ -797,7 +797,8 @@ fallback:
 }
 
 static void
-ip6t_log_packet(u_int8_t pf,
+ip6t_log_packet(struct net *net,
+               u_int8_t pf,
                unsigned int hooknum,
                const struct sk_buff *skb,
                const struct net_device *in,
@@ -806,7 +807,6 @@ ip6t_log_packet(u_int8_t pf,
                const char *prefix)
 {
        struct sbuff *m;
-       struct net *net = dev_net(in ? in : out);
 
        /* FIXME: Disabled from containers until syslog ns is supported */
        if (!net_eq(net, &init_net))
@@ -833,17 +833,18 @@ log_tg(struct sk_buff *skb, const struct xt_action_param *par)
 {
        const struct xt_log_info *loginfo = par->targinfo;
        struct nf_loginfo li;
+       struct net *net = dev_net(par->in ? par->in : par->out);
 
        li.type = NF_LOG_TYPE_LOG;
        li.u.log.level = loginfo->level;
        li.u.log.logflags = loginfo->logflags;
 
        if (par->family == NFPROTO_IPV4)
-               ipt_log_packet(NFPROTO_IPV4, par->hooknum, skb, par->in,
+               ipt_log_packet(net, NFPROTO_IPV4, par->hooknum, skb, par->in,
                               par->out, &li, loginfo->prefix);
 #if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
        else if (par->family == NFPROTO_IPV6)
-               ip6t_log_packet(NFPROTO_IPV6, par->hooknum, skb, par->in,
+               ip6t_log_packet(net, NFPROTO_IPV6, par->hooknum, skb, par->in,
                                par->out, &li, loginfo->prefix);
 #endif
        else
index a17dd0f589b22d3ffce573177414c4afa0790c1d..fb7497c928a0158675e377fe7b1f3ba4c043a8a9 100644 (file)
@@ -26,13 +26,14 @@ nflog_tg(struct sk_buff *skb, const struct xt_action_param *par)
 {
        const struct xt_nflog_info *info = par->targinfo;
        struct nf_loginfo li;
+       struct net *net = dev_net(par->in ? par->in : par->out);
 
        li.type              = NF_LOG_TYPE_ULOG;
        li.u.ulog.copy_len   = info->len;
        li.u.ulog.group      = info->group;
        li.u.ulog.qthreshold = info->threshold;
 
-       nfulnl_log_packet(par->family, par->hooknum, skb, par->in,
+       nfulnl_log_packet(net, par->family, par->hooknum, skb, par->in,
                          par->out, &li, info->prefix);
        return XT_CONTINUE;
 }
index 25fd1c4e1eec3229e8629420e6750ebe74bb6bea..1eb1a44bfd3d134452993dfb071aa15481857ad7 100644 (file)
@@ -30,17 +30,28 @@ static inline unsigned int optlen(const u_int8_t *opt, unsigned int offset)
 
 static unsigned int
 tcpoptstrip_mangle_packet(struct sk_buff *skb,
-                         const struct xt_tcpoptstrip_target_info *info,
+                         const struct xt_action_param *par,
                          unsigned int tcphoff, unsigned int minlen)
 {
+       const struct xt_tcpoptstrip_target_info *info = par->targinfo;
        unsigned int optl, i, j;
        struct tcphdr *tcph;
        u_int16_t n, o;
        u_int8_t *opt;
+       int len;
+
+       /* This is a fragment, no TCP header is available */
+       if (par->fragoff != 0)
+               return XT_CONTINUE;
 
        if (!skb_make_writable(skb, skb->len))
                return NF_DROP;
 
+       len = skb->len - tcphoff;
+       if (len < (int)sizeof(struct tcphdr) ||
+           tcp_hdr(skb)->doff * 4 > len)
+               return NF_DROP;
+
        tcph = (struct tcphdr *)(skb_network_header(skb) + tcphoff);
        opt  = (u_int8_t *)tcph;
 
@@ -76,7 +87,7 @@ tcpoptstrip_mangle_packet(struct sk_buff *skb,
 static unsigned int
 tcpoptstrip_tg4(struct sk_buff *skb, const struct xt_action_param *par)
 {
-       return tcpoptstrip_mangle_packet(skb, par->targinfo, ip_hdrlen(skb),
+       return tcpoptstrip_mangle_packet(skb, par, ip_hdrlen(skb),
               sizeof(struct iphdr) + sizeof(struct tcphdr));
 }
 
@@ -94,7 +105,7 @@ tcpoptstrip_tg6(struct sk_buff *skb, const struct xt_action_param *par)
        if (tcphoff < 0)
                return NF_DROP;
 
-       return tcpoptstrip_mangle_packet(skb, par->targinfo, tcphoff,
+       return tcpoptstrip_mangle_packet(skb, par, tcphoff,
               sizeof(*ipv6h) + sizeof(struct tcphdr));
 }
 #endif
index d8d42433755051023320299f919f69db9e58ec29..6bb1d42f0fac04c02a69ee1790d40baf7af53824 100644 (file)
@@ -245,6 +245,71 @@ static void netlbl_domhsh_audit_add(struct netlbl_dom_map *entry,
        }
 }
 
+/**
+ * netlbl_domhsh_validate - Validate a new domain mapping entry
+ * @entry: the entry to validate
+ *
+ * This function validates the new domain mapping entry to ensure that it is
+ * a valid entry.  Returns zero on success, negative values on failure.
+ *
+ */
+static int netlbl_domhsh_validate(const struct netlbl_dom_map *entry)
+{
+       struct netlbl_af4list *iter4;
+       struct netlbl_domaddr4_map *map4;
+#if IS_ENABLED(CONFIG_IPV6)
+       struct netlbl_af6list *iter6;
+       struct netlbl_domaddr6_map *map6;
+#endif /* IPv6 */
+
+       if (entry == NULL)
+               return -EINVAL;
+
+       switch (entry->type) {
+       case NETLBL_NLTYPE_UNLABELED:
+               if (entry->type_def.cipsov4 != NULL ||
+                   entry->type_def.addrsel != NULL)
+                       return -EINVAL;
+               break;
+       case NETLBL_NLTYPE_CIPSOV4:
+               if (entry->type_def.cipsov4 == NULL)
+                       return -EINVAL;
+               break;
+       case NETLBL_NLTYPE_ADDRSELECT:
+               netlbl_af4list_foreach(iter4, &entry->type_def.addrsel->list4) {
+                       map4 = netlbl_domhsh_addr4_entry(iter4);
+                       switch (map4->type) {
+                       case NETLBL_NLTYPE_UNLABELED:
+                               if (map4->type_def.cipsov4 != NULL)
+                                       return -EINVAL;
+                               break;
+                       case NETLBL_NLTYPE_CIPSOV4:
+                               if (map4->type_def.cipsov4 == NULL)
+                                       return -EINVAL;
+                               break;
+                       default:
+                               return -EINVAL;
+                       }
+               }
+#if IS_ENABLED(CONFIG_IPV6)
+               netlbl_af6list_foreach(iter6, &entry->type_def.addrsel->list6) {
+                       map6 = netlbl_domhsh_addr6_entry(iter6);
+                       switch (map6->type) {
+                       case NETLBL_NLTYPE_UNLABELED:
+                               break;
+                       default:
+                               return -EINVAL;
+                       }
+               }
+#endif /* IPv6 */
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
 /*
  * Domain Hash Table Functions
  */
@@ -311,6 +376,10 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry,
        struct netlbl_af6list *tmp6;
 #endif /* IPv6 */
 
+       ret_val = netlbl_domhsh_validate(entry);
+       if (ret_val != 0)
+               return ret_val;
+
        /* XXX - we can remove this RCU read lock as the spinlock protects the
         *       entire function, but before we do we need to fixup the
         *       netlbl_af[4,6]list RCU functions to do "the right thing" with
index 7da6b457f66abfab016fd8b21aeedcb14d5e7ff0..fc2f78d6a9b46fae51a3ba366bc50c23e9238101 100644 (file)
@@ -52,6 +52,8 @@
 #include <linux/sunrpc/gss_api.h>
 #include <asm/uaccess.h>
 
+#include "../netns.h"
+
 static const struct rpc_authops authgss_ops;
 
 static const struct rpc_credops gss_credops;
@@ -85,8 +87,6 @@ struct gss_auth {
 };
 
 /* pipe_version >= 0 if and only if someone has a pipe open. */
-static int pipe_version = -1;
-static atomic_t pipe_users = ATOMIC_INIT(0);
 static DEFINE_SPINLOCK(pipe_version_lock);
 static struct rpc_wait_queue pipe_version_rpc_waitqueue;
 static DECLARE_WAIT_QUEUE_HEAD(pipe_version_waitqueue);
@@ -266,24 +266,27 @@ struct gss_upcall_msg {
        char databuf[UPCALL_BUF_LEN];
 };
 
-static int get_pipe_version(void)
+static int get_pipe_version(struct net *net)
 {
+       struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
        int ret;
 
        spin_lock(&pipe_version_lock);
-       if (pipe_version >= 0) {
-               atomic_inc(&pipe_users);
-               ret = pipe_version;
+       if (sn->pipe_version >= 0) {
+               atomic_inc(&sn->pipe_users);
+               ret = sn->pipe_version;
        } else
                ret = -EAGAIN;
        spin_unlock(&pipe_version_lock);
        return ret;
 }
 
-static void put_pipe_version(void)
+static void put_pipe_version(struct net *net)
 {
-       if (atomic_dec_and_lock(&pipe_users, &pipe_version_lock)) {
-               pipe_version = -1;
+       struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
+
+       if (atomic_dec_and_lock(&sn->pipe_users, &pipe_version_lock)) {
+               sn->pipe_version = -1;
                spin_unlock(&pipe_version_lock);
        }
 }
@@ -291,9 +294,10 @@ static void put_pipe_version(void)
 static void
 gss_release_msg(struct gss_upcall_msg *gss_msg)
 {
+       struct net *net = rpc_net_ns(gss_msg->auth->client);
        if (!atomic_dec_and_test(&gss_msg->count))
                return;
-       put_pipe_version();
+       put_pipe_version(net);
        BUG_ON(!list_empty(&gss_msg->list));
        if (gss_msg->ctx != NULL)
                gss_put_ctx(gss_msg->ctx);
@@ -439,7 +443,10 @@ static void gss_encode_msg(struct gss_upcall_msg *gss_msg,
                                struct rpc_clnt *clnt,
                                const char *service_name)
 {
-       if (pipe_version == 0)
+       struct net *net = rpc_net_ns(clnt);
+       struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
+
+       if (sn->pipe_version == 0)
                gss_encode_v0_msg(gss_msg);
        else /* pipe_version == 1 */
                gss_encode_v1_msg(gss_msg, clnt, service_name);
@@ -455,7 +462,7 @@ gss_alloc_msg(struct gss_auth *gss_auth, struct rpc_clnt *clnt,
        gss_msg = kzalloc(sizeof(*gss_msg), GFP_NOFS);
        if (gss_msg == NULL)
                return ERR_PTR(-ENOMEM);
-       vers = get_pipe_version();
+       vers = get_pipe_version(rpc_net_ns(clnt));
        if (vers < 0) {
                kfree(gss_msg);
                return ERR_PTR(vers);
@@ -559,24 +566,34 @@ out:
 static inline int
 gss_create_upcall(struct gss_auth *gss_auth, struct gss_cred *gss_cred)
 {
+       struct net *net = rpc_net_ns(gss_auth->client);
+       struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
        struct rpc_pipe *pipe;
        struct rpc_cred *cred = &gss_cred->gc_base;
        struct gss_upcall_msg *gss_msg;
+       unsigned long timeout;
        DEFINE_WAIT(wait);
-       int err = 0;
+       int err;
 
        dprintk("RPC:       %s for uid %u\n",
                __func__, from_kuid(&init_user_ns, cred->cr_uid));
 retry:
+       err = 0;
+       /* Default timeout is 15s unless we know that gssd is not running */
+       timeout = 15 * HZ;
+       if (!sn->gssd_running)
+               timeout = HZ >> 2;
        gss_msg = gss_setup_upcall(gss_auth->client, gss_auth, cred);
        if (PTR_ERR(gss_msg) == -EAGAIN) {
                err = wait_event_interruptible_timeout(pipe_version_waitqueue,
-                               pipe_version >= 0, 15*HZ);
-               if (pipe_version < 0) {
+                               sn->pipe_version >= 0, timeout);
+               if (sn->pipe_version < 0) {
+                       if (err == 0)
+                               sn->gssd_running = 0;
                        warn_gssd();
                        err = -EACCES;
                }
-               if (err)
+               if (err < 0)
                        goto out;
                goto retry;
        }
@@ -707,20 +724,22 @@ out:
 
 static int gss_pipe_open(struct inode *inode, int new_version)
 {
+       struct net *net = inode->i_sb->s_fs_info;
+       struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
        int ret = 0;
 
        spin_lock(&pipe_version_lock);
-       if (pipe_version < 0) {
+       if (sn->pipe_version < 0) {
                /* First open of any gss pipe determines the version: */
-               pipe_version = new_version;
+               sn->pipe_version = new_version;
                rpc_wake_up(&pipe_version_rpc_waitqueue);
                wake_up(&pipe_version_waitqueue);
-       } else if (pipe_version != new_version) {
+       } else if (sn->pipe_version != new_version) {
                /* Trying to open a pipe of a different version */
                ret = -EBUSY;
                goto out;
        }
-       atomic_inc(&pipe_users);
+       atomic_inc(&sn->pipe_users);
 out:
        spin_unlock(&pipe_version_lock);
        return ret;
@@ -740,6 +759,7 @@ static int gss_pipe_open_v1(struct inode *inode)
 static void
 gss_pipe_release(struct inode *inode)
 {
+       struct net *net = inode->i_sb->s_fs_info;
        struct rpc_pipe *pipe = RPC_I(inode)->pipe;
        struct gss_upcall_msg *gss_msg;
 
@@ -758,7 +778,7 @@ restart:
        }
        spin_unlock(&pipe->lock);
 
-       put_pipe_version();
+       put_pipe_version(net);
 }
 
 static void
index 7111a4c9113baceef38042da1ff41a100ff58b21..74d948f5d5a1d399d13061ee5c910c2cacc6f720 100644 (file)
@@ -28,7 +28,11 @@ struct sunrpc_net {
        wait_queue_head_t gssp_wq;
        struct rpc_clnt *gssp_clnt;
        int use_gss_proxy;
+       int pipe_version;
+       atomic_t pipe_users;
        struct proc_dir_entry *use_gssp_proc;
+
+       unsigned int gssd_running;
 };
 
 extern int sunrpc_net_id;
index a9129f8d70706f5e33ac8f39cb3ea8a3e5825ca2..e7ce4b3eb0bdde4f209ba2cdf6cd1e3dbcca03f9 100644 (file)
@@ -216,11 +216,14 @@ rpc_destroy_inode(struct inode *inode)
 static int
 rpc_pipe_open(struct inode *inode, struct file *filp)
 {
+       struct net *net = inode->i_sb->s_fs_info;
+       struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
        struct rpc_pipe *pipe;
        int first_open;
        int res = -ENXIO;
 
        mutex_lock(&inode->i_mutex);
+       sn->gssd_running = 1;
        pipe = RPC_I(inode)->pipe;
        if (pipe == NULL)
                goto out;
@@ -1069,6 +1072,8 @@ void rpc_pipefs_init_net(struct net *net)
        struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
 
        mutex_init(&sn->pipefs_sb_lock);
+       sn->gssd_running = 1;
+       sn->pipe_version = -1;
 }
 
 /*
index f8529fc8e54275c5b7b9809f0219f20608ffb472..5356b120dbf8e2fe61ba88081d1fab1941f135a9 100644 (file)
@@ -324,11 +324,17 @@ EXPORT_SYMBOL_GPL(__rpc_wait_for_completion_task);
  * Note: If the task is ASYNC, and is being made runnable after sitting on an
  * rpc_wait_queue, this must be called with the queue spinlock held to protect
  * the wait queue operation.
+ * Note the ordering of rpc_test_and_set_running() and rpc_clear_queued(),
+ * which is needed to ensure that __rpc_execute() doesn't loop (due to the
+ * lockless RPC_IS_QUEUED() test) before we've had a chance to test
+ * the RPC_TASK_RUNNING flag.
  */
 static void rpc_make_runnable(struct rpc_task *task)
 {
+       bool need_wakeup = !rpc_test_and_set_running(task);
+
        rpc_clear_queued(task);
-       if (rpc_test_and_set_running(task))
+       if (!need_wakeup)
                return;
        if (RPC_IS_ASYNC(task)) {
                INIT_WORK(&task->u.tk_work, rpc_async_schedule);
index 84c9ad7e1dca0de703c7517774be813be7b5be2f..73405e00c800fd62ff703c9c030e31da70c69858 100644 (file)
@@ -638,17 +638,21 @@ int wiphy_register(struct wiphy *wiphy)
         * cfg80211_mutex lock
         */
        res = rfkill_register(rdev->rfkill);
-       if (res)
-               goto out_rm_dev;
+       if (res) {
+               device_del(&rdev->wiphy.dev);
+
+               mutex_lock(&cfg80211_mutex);
+               debugfs_remove_recursive(rdev->wiphy.debugfsdir);
+               list_del_rcu(&rdev->list);
+               wiphy_regulatory_deregister(wiphy);
+               mutex_unlock(&cfg80211_mutex);
+               return res;
+       }
 
        rtnl_lock();
        rdev->wiphy.registered = true;
        rtnl_unlock();
        return 0;
-
-out_rm_dev:
-       device_del(&rdev->wiphy.dev);
-       return res;
 }
 EXPORT_SYMBOL(wiphy_register);
 
@@ -866,7 +870,6 @@ void cfg80211_leave(struct cfg80211_registered_device *rdev,
 #endif
                __cfg80211_disconnect(rdev, dev,
                                      WLAN_REASON_DEAUTH_LEAVING, true);
-               cfg80211_mlme_down(rdev, dev);
                wdev_unlock(wdev);
                break;
        case NL80211_IFTYPE_MESH_POINT:
index afa283841e8c6ebfdab9713b43ee3c19134c0f2c..dfdb5e6432110f15afa4730e9fae0f05d7b011e8 100644 (file)
@@ -7577,6 +7577,8 @@ static int nl80211_send_wowlan_tcp(struct sk_buff *msg,
                    &tcp->payload_tok))
                return -ENOBUFS;
 
+       nla_nest_end(msg, nl_tcp);
+
        return 0;
 }
 
@@ -9970,6 +9972,7 @@ int nl80211_send_mgmt(struct cfg80211_registered_device *rdev,
        if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
            (netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
                                        netdev->ifindex)) ||
+           nla_put_u64(msg, NL80211_ATTR_WDEV, wdev_id(wdev)) ||
            nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq) ||
            (sig_dbm &&
             nla_put_u32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm)) ||
@@ -10010,6 +10013,7 @@ void cfg80211_mgmt_tx_status(struct wireless_dev *wdev, u64 cookie,
        if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
            (netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
                                   netdev->ifindex)) ||
+           nla_put_u64(msg, NL80211_ATTR_WDEV, wdev_id(wdev)) ||
            nla_put(msg, NL80211_ATTR_FRAME, len, buf) ||
            nla_put_u64(msg, NL80211_ATTR_COOKIE, cookie) ||
            (ack && nla_put_flag(msg, NL80211_ATTR_ACK)))
index a9dc5c736df061466463e01bb890fed8f28e5389..8b5eddfba1e5dfed07b1fb528204c125db2d7331 100644 (file)
@@ -961,7 +961,7 @@ int __cfg80211_disconnect(struct cfg80211_registered_device *rdev,
                /* was it connected by userspace SME? */
                if (!wdev->conn) {
                        cfg80211_mlme_down(rdev, dev);
-                       return 0;
+                       goto disconnect;
                }
 
                if (wdev->sme_state == CFG80211_SME_CONNECTING &&
@@ -987,6 +987,7 @@ int __cfg80211_disconnect(struct cfg80211_registered_device *rdev,
                        return err;
        }
 
+ disconnect:
        if (wdev->sme_state == CFG80211_SME_CONNECTED)
                __cfg80211_disconnected(dev, NULL, 0, 0, false);
        else if (wdev->sme_state == CFG80211_SME_CONNECTING)
index ecd4fcec3c94be2305b38385ab58e732c4f339a0..5755bc14abbd8220ff39a5f271043b5d4165d947 100644 (file)
@@ -2441,6 +2441,7 @@ TRACE_EVENT(cfg80211_report_wowlan_wakeup,
        TP_STRUCT__entry(
                WIPHY_ENTRY
                WDEV_ENTRY
+               __field(bool, non_wireless)
                __field(bool, disconnect)
                __field(bool, magic_pkt)
                __field(bool, gtk_rekey_failure)
@@ -2449,20 +2450,22 @@ TRACE_EVENT(cfg80211_report_wowlan_wakeup,
                __field(bool, rfkill_release)
                __field(s32, pattern_idx)
                __field(u32, packet_len)
-               __dynamic_array(u8, packet, wakeup->packet_present_len)
+               __dynamic_array(u8, packet,
+                               wakeup ? wakeup->packet_present_len : 0)
        ),
        TP_fast_assign(
                WIPHY_ASSIGN;
                WDEV_ASSIGN;
-               __entry->disconnect = wakeup->disconnect;
-               __entry->magic_pkt = wakeup->magic_pkt;
-               __entry->gtk_rekey_failure = wakeup->gtk_rekey_failure;
-               __entry->eap_identity_req = wakeup->eap_identity_req;
-               __entry->four_way_handshake = wakeup->four_way_handshake;
-               __entry->rfkill_release = wakeup->rfkill_release;
-               __entry->pattern_idx = wakeup->pattern_idx;
-               __entry->packet_len = wakeup->packet_len;
-               if (wakeup->packet && wakeup->packet_present_len)
+               __entry->non_wireless = !wakeup;
+               __entry->disconnect = wakeup ? wakeup->disconnect : false;
+               __entry->magic_pkt = wakeup ? wakeup->magic_pkt : false;
+               __entry->gtk_rekey_failure = wakeup ? wakeup->gtk_rekey_failure : false;
+               __entry->eap_identity_req = wakeup ? wakeup->eap_identity_req : false;
+               __entry->four_way_handshake = wakeup ? wakeup->four_way_handshake : false;
+               __entry->rfkill_release = wakeup ? wakeup->rfkill_release : false;
+               __entry->pattern_idx = wakeup ? wakeup->pattern_idx : false;
+               __entry->packet_len = wakeup ? wakeup->packet_len : false;
+               if (wakeup && wakeup->packet && wakeup->packet_present_len)
                        memcpy(__get_dynamic_array(packet), wakeup->packet,
                               wakeup->packet_present_len);
        ),
index bcfda8921b5bf944d38ac3e087eb1cccfac327fe..0cf003dfa8fcd3d4f2f974f21649b164f76429b3 100644 (file)
@@ -64,6 +64,7 @@ static int xfrm_output_one(struct sk_buff *skb, int err)
 
                if (unlikely(x->km.state != XFRM_STATE_VALID)) {
                        XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTSTATEINVALID);
+                       err = -EINVAL;
                        goto error;
                }
 
index a4ffc95000238cde8f086970f9d23d042ba99c59..b5740599aabd38ee1eebdbc2ce3f66b58a0437a6 100755 (executable)
@@ -15,35 +15,38 @@ kallsyms = []
 
 def get_kallsyms_table():
        global kallsyms
+
        try:
                f = open("/proc/kallsyms", "r")
-               linecount = 0
-               for line in f:
-                       linecount = linecount+1
-               f.seek(0)
        except:
                return
 
-
-       j = 0
        for line in f:
                loc = int(line.split()[0], 16)
                name = line.split()[2]
-               j = j +1
-               if ((j % 100) == 0):
-                       print "\r" + str(j) + "/" + str(linecount),
-               kallsyms.append({ 'loc': loc, 'name' : name})
-
-       print "\r" + str(j) + "/" + str(linecount)
+               kallsyms.append((loc, name))
        kallsyms.sort()
-       return
 
 def get_sym(sloc):
        loc = int(sloc)
-       for i in kallsyms:
-               if (i['loc'] >= loc):
-                       return (i['name'], i['loc']-loc)
-       return (None, 0)
+
+       # Invariant: kallsyms[i][0] <= loc for all 0 <= i <= start
+       #            kallsyms[i][0] > loc for all end <= i < len(kallsyms)
+       start, end = -1, len(kallsyms)
+       while end != start + 1:
+               pivot = (start + end) // 2
+               if loc < kallsyms[pivot][0]:
+                       end = pivot
+               else:
+                       start = pivot
+
+       # Now (start == -1 or kallsyms[start][0] <= loc)
+       # and (start == len(kallsyms) - 1 or loc < kallsyms[start + 1][0])
+       if start >= 0:
+               symloc, name = kallsyms[start]
+               return (name, loc - symloc)
+       else:
+               return (None, 0)
 
 def print_drop_table():
        print "%25s %25s %25s" % ("LOCATION", "OFFSET", "COUNT")
@@ -64,7 +67,7 @@ def trace_end():
 
 # called from perf, when it finds a correspoinding event
 def skb__kfree_skb(name, context, cpu, sec, nsec, pid, comm,
-                       skbaddr, protocol, location):
+                  skbaddr, location, protocol):
        slocation = str(location)
        try:
                drop_log[slocation] = drop_log[slocation] + 1
index d4abc59ce1d9e519c1be61628d0433602163dddb..0a63658065f0e9e41285f521665b80b975cfe86c 100644 (file)
@@ -6,7 +6,6 @@ TARGETS += memory-hotplug
 TARGETS += mqueue
 TARGETS += net
 TARGETS += ptrace
-TARGETS += soft-dirty
 TARGETS += vm
 
 all:
diff --git a/tools/testing/selftests/soft-dirty/Makefile b/tools/testing/selftests/soft-dirty/Makefile
deleted file mode 100644 (file)
index a9cdc82..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-CFLAGS += -iquote../../../../include/uapi -Wall
-soft-dirty: soft-dirty.c
-
-all: soft-dirty
-
-clean:
-       rm -f soft-dirty
-
-run_tests: all
-       @./soft-dirty || echo "soft-dirty selftests: [FAIL]"
diff --git a/tools/testing/selftests/soft-dirty/soft-dirty.c b/tools/testing/selftests/soft-dirty/soft-dirty.c
deleted file mode 100644 (file)
index aba4f87..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-#include <stdlib.h>
-#include <stdio.h>
-#include <sys/mman.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/types.h>
-
-typedef unsigned long long u64;
-
-#define PME_PRESENT    (1ULL << 63)
-#define PME_SOFT_DIRTY (1Ull << 55)
-
-#define PAGES_TO_TEST  3
-#ifndef PAGE_SIZE
-#define PAGE_SIZE      4096
-#endif
-
-static void get_pagemap2(char *mem, u64 *map)
-{
-       int fd;
-
-       fd = open("/proc/self/pagemap2", O_RDONLY);
-       if (fd < 0) {
-               perror("Can't open pagemap2");
-               exit(1);
-       }
-
-       lseek(fd, (unsigned long)mem / PAGE_SIZE * sizeof(u64), SEEK_SET);
-       read(fd, map, sizeof(u64) * PAGES_TO_TEST);
-       close(fd);
-}
-
-static inline char map_p(u64 map)
-{
-       return map & PME_PRESENT ? 'p' : '-';
-}
-
-static inline char map_sd(u64 map)
-{
-       return map & PME_SOFT_DIRTY ? 'd' : '-';
-}
-
-static int check_pte(int step, int page, u64 *map, u64 want)
-{
-       if ((map[page] & want) != want) {
-               printf("Step %d Page %d has %c%c, want %c%c\n",
-                               step, page,
-                               map_p(map[page]), map_sd(map[page]),
-                               map_p(want), map_sd(want));
-               return 1;
-       }
-
-       return 0;
-}
-
-static void clear_refs(void)
-{
-       int fd;
-       char *v = "4";
-
-       fd = open("/proc/self/clear_refs", O_WRONLY);
-       if (write(fd, v, 3) < 3) {
-               perror("Can't clear soft-dirty bit");
-               exit(1);
-       }
-       close(fd);
-}
-
-int main(void)
-{
-       char *mem, x;
-       u64 map[PAGES_TO_TEST];
-
-       mem = mmap(NULL, PAGES_TO_TEST * PAGE_SIZE,
-                       PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, 0, 0);
-
-       x = mem[0];
-       mem[2 * PAGE_SIZE] = 'c';
-       get_pagemap2(mem, map);
-
-       if (check_pte(1, 0, map, PME_PRESENT))
-               return 1;
-       if (check_pte(1, 1, map, 0))
-               return 1;
-       if (check_pte(1, 2, map, PME_PRESENT | PME_SOFT_DIRTY))
-               return 1;
-
-       clear_refs();
-       get_pagemap2(mem, map);
-
-       if (check_pte(2, 0, map, PME_PRESENT))
-               return 1;
-       if (check_pte(2, 1, map, 0))
-               return 1;
-       if (check_pte(2, 2, map, PME_PRESENT))
-               return 1;
-
-       mem[0] = 'a';
-       mem[PAGE_SIZE] = 'b';
-       x = mem[2 * PAGE_SIZE];
-       get_pagemap2(mem, map);
-
-       if (check_pte(3, 0, map, PME_PRESENT | PME_SOFT_DIRTY))
-               return 1;
-       if (check_pte(3, 1, map, PME_PRESENT | PME_SOFT_DIRTY))
-               return 1;
-       if (check_pte(3, 2, map, PME_PRESENT))
-               return 1;
-
-       (void)x; /* gcc warn */
-
-       printf("PASS\n");
-       return 0;
-}