summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/arm/sunxi/clocks.txt56
-rw-r--r--Documentation/clk.txt4
-rw-r--r--Documentation/devicetree/bindings/clock/axi-clkgen.txt22
-rw-r--r--Documentation/devicetree/bindings/clock/sunxi.txt151
-rw-r--r--Documentation/devicetree/bindings/mfd/ab8500.txt6
-rw-r--r--Documentation/devicetree/bindings/tty/serial/of-serial.txt3
-rw-r--r--Documentation/input/alps.txt67
-rw-r--r--Documentation/networking/tuntap.txt77
-rw-r--r--Documentation/trace/ftrace.txt2
-rw-r--r--MAINTAINERS27
-rw-r--r--Makefile2
-rw-r--r--arch/Kconfig7
-rw-r--r--arch/alpha/Kconfig2
-rw-r--r--arch/arm/Kconfig13
-rw-r--r--arch/arm/Kconfig.debug2
-rw-r--r--arch/arm/boot/Makefile2
-rw-r--r--arch/arm/boot/dts/armada-370-rd.dts8
-rw-r--r--arch/arm/boot/dts/armada-370-xp.dtsi5
-rw-r--r--arch/arm/boot/dts/armada-xp.dtsi4
-rw-r--r--arch/arm/boot/dts/bcm2835.dtsi2
-rw-r--r--arch/arm/boot/dts/dbx5x0.dtsi3
-rw-r--r--arch/arm/boot/dts/dove.dtsi5
-rw-r--r--arch/arm/boot/dts/href.dtsi2
-rw-r--r--arch/arm/boot/dts/hrefv60plus.dts2
-rw-r--r--arch/arm/boot/dts/imx53-mba53.dts3
-rw-r--r--arch/arm/boot/dts/kirkwood-dns320.dts2
-rw-r--r--arch/arm/boot/dts/kirkwood-dns325.dts1
-rw-r--r--arch/arm/boot/dts/kirkwood-dockstar.dts1
-rw-r--r--arch/arm/boot/dts/kirkwood-dreamplug.dts1
-rw-r--r--arch/arm/boot/dts/kirkwood-goflexnet.dts1
-rw-r--r--arch/arm/boot/dts/kirkwood-ib62x0.dts1
-rw-r--r--arch/arm/boot/dts/kirkwood-iconnect.dts1
-rw-r--r--arch/arm/boot/dts/kirkwood-iomega_ix2_200.dts1
-rw-r--r--arch/arm/boot/dts/kirkwood-km_kirkwood.dts1
-rw-r--r--arch/arm/boot/dts/kirkwood-lschlv2.dts1
-rw-r--r--arch/arm/boot/dts/kirkwood-lsxhl.dts1
-rw-r--r--arch/arm/boot/dts/kirkwood-mplcec4.dts1
-rw-r--r--arch/arm/boot/dts/kirkwood-ns2-common.dtsi1
-rw-r--r--arch/arm/boot/dts/kirkwood-nsa310.dts1
-rw-r--r--arch/arm/boot/dts/kirkwood-openblocks_a6.dts2
-rw-r--r--arch/arm/boot/dts/kirkwood-topkick.dts1
-rw-r--r--arch/arm/boot/dts/kirkwood.dtsi5
-rw-r--r--arch/arm/boot/dts/orion5x-lacie-ethernet-disk-mini-v2.dts2
-rw-r--r--arch/arm/boot/dts/snowball.dts2
-rw-r--r--arch/arm/boot/dts/socfpga.dtsi3
-rw-r--r--arch/arm/boot/dts/tegra20.dtsi1
-rw-r--r--arch/arm/boot/dts/tegra30.dtsi1
-rw-r--r--arch/arm/configs/mxs_defconfig1
-rw-r--r--arch/arm/configs/omap2plus_defconfig2
-rw-r--r--arch/arm/include/asm/xen/events.h25
-rw-r--r--arch/arm/mach-at91/board-foxg20.c1
-rw-r--r--arch/arm/mach-at91/board-stamp9g20.c1
-rw-r--r--arch/arm/mach-imx/clk-busy.c2
-rw-r--r--arch/arm/mach-imx/clk-imx6q.c2
-rw-r--r--arch/arm/mach-imx/headsmp.S18
-rw-r--r--arch/arm/mach-imx/pm-imx6q.c15
-rw-r--r--arch/arm/mach-ixp4xx/vulcan-setup.c1
-rw-r--r--arch/arm/mach-kirkwood/board-dt.c25
-rw-r--r--arch/arm/mach-mxs/icoll.c2
-rw-r--r--arch/arm/mach-mxs/mach-mxs.c10
-rw-r--r--arch/arm/mach-mxs/mm.c1
-rw-r--r--arch/arm/mach-mxs/ocotp.c1
-rw-r--r--arch/arm/mach-omap1/common.h2
-rw-r--r--arch/arm/mach-omap2/Kconfig6
-rw-r--r--arch/arm/mach-omap2/board-generic.c2
-rw-r--r--arch/arm/mach-omap2/board-rx51.c2
-rw-r--r--arch/arm/mach-omap2/common.h1
-rw-r--r--arch/arm/mach-omap2/gpmc.c6
-rw-r--r--arch/arm/mach-omap2/mux.c9
-rw-r--r--arch/arm/mach-pxa/raumfeld.c1
-rw-r--r--arch/arm/mach-spear3xx/spear3xx.c2
-rw-r--r--arch/arm/mm/dma-mapping.c5
-rw-r--r--arch/arm/plat-orion/addr-map.c7
-rw-r--r--arch/arm/plat-spear/Kconfig2
-rw-r--r--arch/avr32/Kconfig2
-rw-r--r--arch/blackfin/Kconfig2
-rw-r--r--arch/cris/Kconfig2
-rw-r--r--arch/frv/Kconfig2
-rw-r--r--arch/h8300/Kconfig2
-rw-r--r--arch/ia64/Kconfig2
-rw-r--r--arch/m32r/Kconfig2
-rw-r--r--arch/m32r/include/uapi/asm/stat.h4
-rw-r--r--arch/m68k/Kconfig2
-rw-r--r--arch/m68k/Kconfig.machine1
-rw-r--r--arch/m68k/include/asm/MC68328.h10
-rw-r--r--arch/m68k/kernel/setup_no.c3
-rw-r--r--arch/m68k/mm/init.c2
-rw-r--r--arch/m68k/platform/coldfire/m528x.c2
-rw-r--r--arch/microblaze/Kconfig2
-rw-r--r--arch/mips/Kconfig2
-rw-r--r--arch/mn10300/Kconfig2
-rw-r--r--arch/openrisc/Kconfig3
-rw-r--r--arch/parisc/Kconfig2
-rw-r--r--arch/powerpc/Kconfig2
-rw-r--r--arch/s390/Kconfig2
-rw-r--r--arch/s390/include/asm/cpu_mf.h1
-rw-r--r--arch/score/Kconfig2
-rw-r--r--arch/tile/Kconfig2
-rw-r--r--arch/um/drivers/chan.h2
-rw-r--r--arch/um/drivers/chan_kern.c4
-rw-r--r--arch/um/drivers/chan_user.c12
-rw-r--r--arch/um/drivers/chan_user.h6
-rw-r--r--arch/um/drivers/line.c42
-rw-r--r--arch/um/drivers/net_kern.c2
-rw-r--r--arch/um/drivers/ssl.c1
-rw-r--r--arch/um/drivers/stdio_console.c1
-rw-r--r--arch/um/os-Linux/signal.c2
-rw-r--r--arch/um/os-Linux/start_up.c2
-rw-r--r--arch/unicore32/Kconfig2
-rw-r--r--arch/x86/Kconfig2
-rw-r--r--arch/x86/kernel/cpu/perf_event_intel_ds.c10
-rw-r--r--arch/x86/power/cpu.c2
-rw-r--r--arch/xtensa/Kconfig2
-rw-r--r--drivers/acpi/processor_perflib.c4
-rw-r--r--drivers/char/hw_random/virtio-rng.c13
-rw-r--r--drivers/clk/Kconfig8
-rw-r--r--drivers/clk/Makefile3
-rw-r--r--drivers/clk/clk-axi-clkgen.c331
-rw-r--r--drivers/clk/clk-composite.c201
-rw-r--r--drivers/clk/clk-divider.c5
-rw-r--r--drivers/clk/clk-mux.c50
-rw-r--r--drivers/clk/clk-prima2.c2
-rw-r--r--drivers/clk/clk-zynq.c1
-rw-r--r--drivers/clk/clk.c193
-rw-r--r--drivers/clk/mvebu/clk-cpu.c17
-rw-r--r--drivers/clk/mvebu/clk-cpu.h22
-rw-r--r--drivers/clk/mvebu/clk.c6
-rw-r--r--drivers/clk/mxs/clk.c1
-rw-r--r--drivers/clk/spear/spear1340_clock.c18
-rw-r--r--drivers/clk/sunxi/Makefile5
-rw-r--r--drivers/clk/sunxi/clk-factors.c180
-rw-r--r--drivers/clk/sunxi/clk-factors.h27
-rw-r--r--drivers/clk/sunxi/clk-sunxi.c450
-rw-r--r--drivers/clk/tegra/clk-tegra20.c1
-rw-r--r--drivers/clk/tegra/clk-tegra30.c1
-rw-r--r--drivers/clk/tegra/clk.h27
-rw-r--r--drivers/clk/ux500/clk-prcmu.c136
-rw-r--r--drivers/clocksource/sunxi_timer.c4
-rw-r--r--drivers/gpio/gpio-mvebu.c7
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/disp/nv50.c4
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_abi16.c5
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bo.c4
-rw-r--r--drivers/gpu/drm/nouveau/nv50_display.c1
-rw-r--r--drivers/hwmon/lineage-pem.c2
-rw-r--r--drivers/hwmon/pmbus/ltc2978.c14
-rw-r--r--drivers/hwmon/pmbus/pmbus_core.c12
-rw-r--r--drivers/iio/common/st_sensors/st_sensors_core.c9
-rw-r--r--drivers/iio/dac/ad5064.c64
-rw-r--r--drivers/iio/imu/inv_mpu6050/Kconfig1
-rw-r--r--drivers/infiniband/hw/mlx4/cm.c1
-rw-r--r--drivers/input/keyboard/tc3589x-keypad.c8
-rw-r--r--drivers/input/mouse/alps.c85
-rw-r--r--drivers/input/mouse/alps.h1
-rw-r--r--drivers/input/mouse/cypress_ps2.c19
-rw-r--r--drivers/input/tablet/wacom_wac.c4
-rw-r--r--drivers/input/touchscreen/ads7846.c7
-rw-r--r--drivers/input/touchscreen/mms114.c34
-rw-r--r--drivers/irqchip/irq-gic.c2
-rw-r--r--drivers/isdn/i4l/isdn_tty.c4
-rw-r--r--drivers/mfd/Kconfig1
-rw-r--r--drivers/mfd/ab8500-gpadc.c17
-rw-r--r--drivers/mfd/omap-usb-host.c6
-rw-r--r--drivers/mfd/palmas.c36
-rw-r--r--drivers/mfd/tps65912-core.c1
-rw-r--r--drivers/mfd/twl4030-audio.c2
-rw-r--r--drivers/mfd/twl4030-madc.c2
-rw-r--r--drivers/net/bonding/bond_main.c5
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c17
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h4
-rw-r--r--drivers/net/ethernet/broadcom/tg3.c14
-rw-r--r--drivers/net/ethernet/emulex/benet/be.h1
-rw-r--r--drivers/net/ethernet/emulex/benet/be_cmds.c36
-rw-r--r--drivers/net/ethernet/emulex/benet/be_hw.h4
-rw-r--r--drivers/net/ethernet/emulex/benet/be_main.c10
-rw-r--r--drivers/net/ethernet/intel/e1000e/ethtool.c13
-rw-r--r--drivers/net/ethernet/intel/e1000e/ich8lan.c71
-rw-r--r--drivers/net/ethernet/intel/e1000e/ich8lan.h2
-rw-r--r--drivers/net/ethernet/intel/e1000e/netdev.c82
-rw-r--r--drivers/net/ethernet/intel/e1000e/regs.h1
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_82575.c11
-rw-r--r--drivers/net/ethernet/intel/igb/igb.h2
-rw-r--r--drivers/net/ethernet/intel/igb/igb_hwmon.c14
-rw-r--r--drivers/net/ethernet/intel/igb/igb_main.c76
-rw-r--r--drivers/net/ethernet/marvell/mv643xx_eth.c55
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/cq.c2
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_netdev.c86
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/fw.c8
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/main.c2
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mlx4.h2
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mlx4_en.h1
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mr.c10
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/pd.c2
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/port.c8
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/qp.c8
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/resource_tracker.c3
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/srq.c2
-rw-r--r--drivers/net/ethernet/sfc/efx.h4
-rw-r--r--drivers/net/ethernet/sfc/rx.c2
-rw-r--r--drivers/net/hippi/rrunner.c3
-rw-r--r--drivers/net/macvlan.c1
-rw-r--r--drivers/net/team/team.c2
-rw-r--r--drivers/net/tun.c2
-rw-r--r--drivers/net/vmxnet3/vmxnet3_drv.c1
-rw-r--r--drivers/net/vmxnet3/vmxnet3_ethtool.c6
-rw-r--r--drivers/net/vmxnet3/vmxnet3_int.h4
-rw-r--r--drivers/net/vxlan.c10
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/sta.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-devtrace.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-drv.c3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-modparams.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans.h20
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api.h18
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw.c133
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mvm.h3
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/ops.c18
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rx.c37
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/sta.c10
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/tx.c6
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/internal.h34
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/rx.c14
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/tx.c266
-rw-r--r--drivers/rtc/rtc-mv.c28
-rw-r--r--drivers/staging/comedi/drivers/dt9812.c16
-rw-r--r--drivers/staging/comedi/drivers/usbdux.c31
-rw-r--r--drivers/staging/comedi/drivers/usbduxfast.c30
-rw-r--r--drivers/staging/comedi/drivers/usbduxsigma.c27
-rw-r--r--drivers/staging/imx-drm/ipuv3-crtc.c23
-rw-r--r--drivers/staging/tidspbridge/rmgr/drv.c70
-rw-r--r--drivers/staging/vt6656/card.c2
-rw-r--r--drivers/staging/vt6656/main_usb.c4
-rw-r--r--drivers/staging/zcache/ramster/tcp.c25
-rw-r--r--drivers/tty/serial/8250/8250.c52
-rw-r--r--drivers/tty/serial/8250/8250_pci.c21
-rw-r--r--drivers/tty/serial/8250/8250_pnp.c12
-rw-r--r--drivers/tty/serial/Kconfig4
-rw-r--r--drivers/tty/serial/bcm63xx_uart.c8
-rw-r--r--drivers/tty/serial/mpc52xx_uart.c2
-rw-r--r--drivers/tty/serial/of_serial.c6
-rw-r--r--drivers/tty/serial/vt8500_serial.c9
-rw-r--r--drivers/tty/tty_buffer.c2
-rw-r--r--drivers/usb/Makefile2
-rw-r--r--drivers/usb/c67x00/c67x00-sched.c4
-rw-r--r--drivers/usb/chipidea/udc.c6
-rw-r--r--drivers/usb/class/cdc-wdm.c23
-rw-r--r--drivers/usb/dwc3/core.c1
-rw-r--r--drivers/usb/dwc3/dwc3-exynos.c2
-rw-r--r--drivers/usb/dwc3/dwc3-omap.c8
-rw-r--r--drivers/usb/dwc3/dwc3-pci.c2
-rw-r--r--drivers/usb/dwc3/ep0.c7
-rw-r--r--drivers/usb/dwc3/gadget.c3
-rw-r--r--drivers/usb/gadget/Makefile12
-rw-r--r--drivers/usb/gadget/composite.c5
-rw-r--r--drivers/usb/gadget/f_uac1.c1
-rw-r--r--drivers/usb/gadget/imx_udc.c20
-rw-r--r--drivers/usb/gadget/omap_udc.c3
-rw-r--r--drivers/usb/gadget/pxa25x_udc.c24
-rw-r--r--drivers/usb/gadget/pxa27x_udc.c18
-rw-r--r--drivers/usb/gadget/s3c2410_udc.c28
-rw-r--r--drivers/usb/gadget/u_uac1.c3
-rw-r--r--drivers/usb/host/ehci-hcd.c6
-rw-r--r--drivers/usb/host/ehci-q.c36
-rw-r--r--drivers/usb/musb/Kconfig5
-rw-r--r--drivers/usb/musb/musb_core.c6
-rw-r--r--drivers/usb/musb/omap2430.c12
-rw-r--r--drivers/usb/otg/otg.c10
-rw-r--r--drivers/usb/phy/omap-control-usb.c24
-rw-r--r--drivers/usb/phy/omap-usb3.c8
-rw-r--r--drivers/usb/phy/samsung-usbphy.c8
-rw-r--r--drivers/usb/serial/cp210x.c20
-rw-r--r--drivers/usb/serial/option.c5
-rw-r--r--drivers/usb/serial/qcaux.c1
-rw-r--r--drivers/usb/serial/qcserial.c7
-rw-r--r--drivers/usb/serial/quatech2.c7
-rw-r--r--drivers/usb/storage/initializers.c76
-rw-r--r--drivers/usb/storage/initializers.h4
-rw-r--r--drivers/usb/storage/unusual_devs.h337
-rw-r--r--drivers/video/omap/lcd_ams_delta.c1
-rw-r--r--drivers/video/omap/lcd_osk.c3
-rw-r--r--drivers/w1/masters/w1-gpio.c6
-rw-r--r--drivers/w1/w1.c3
-rw-r--r--drivers/xen/xen-acpi-processor.c8
-rw-r--r--drivers/xen/xen-pciback/pciback_ops.c3
-rw-r--r--drivers/xen/xen-stub.c1
-rw-r--r--fs/btrfs/extent-tree.c5
-rw-r--r--fs/btrfs/file.c1
-rw-r--r--fs/btrfs/inode.c3
-rw-r--r--fs/btrfs/locking.h1
-rw-r--r--fs/btrfs/qgroup.c10
-rw-r--r--fs/btrfs/transaction.c11
-rw-r--r--fs/btrfs/volumes.c6
-rw-r--r--fs/cifs/cifsfs.c1
-rw-r--r--fs/compat.c15
-rw-r--r--fs/ext2/ialloc.c1
-rw-r--r--fs/ext2/inode.c2
-rw-r--r--fs/ext3/super.c4
-rw-r--r--fs/ext4/super.c2
-rw-r--r--fs/freevxfs/vxfs_super.c1
-rw-r--r--fs/hostfs/hostfs_kern.c10
-rw-r--r--fs/hpfs/super.c1
-rw-r--r--fs/isofs/inode.c1
-rw-r--r--fs/nfs/super.c1
-rw-r--r--fs/nfsd/nfs4state.c36
-rw-r--r--fs/pipe.c3
-rw-r--r--fs/quota/dquot.c5
-rw-r--r--fs/reiserfs/super.c4
-rw-r--r--fs/squashfs/super.c1
-rw-r--r--fs/sysv/super.c1
-rw-r--r--fs/udf/super.c1
-rw-r--r--include/acpi/processor.h3
-rw-r--r--include/asm-generic/atomic.h6
-rw-r--r--include/asm-generic/cmpxchg.h10
-rw-r--r--include/linux/clk-private.h2
-rw-r--r--include/linux/clk-provider.h61
-rw-r--r--include/linux/clk/sunxi.h22
-rw-r--r--include/linux/idr.h68
-rw-r--r--include/linux/iio/common/st_sensors.h9
-rw-r--r--include/linux/list.h4
-rw-r--r--include/linux/mfd/palmas.h1
-rw-r--r--include/linux/mfd/tps65912.h1
-rw-r--r--include/linux/mfd/wm831x/auxadc.h2
-rw-r--r--include/linux/mfd/wm831x/core.h2
-rw-r--r--include/linux/perf_event.h6
-rw-r--r--include/linux/res_counter.h1
-rw-r--r--include/linux/usb/composite.h3
-rw-r--r--include/uapi/linux/acct.h6
-rw-r--r--include/uapi/linux/aio_abi.h4
-rw-r--r--include/uapi/linux/raid/md_p.h6
-rw-r--r--include/uapi/linux/serial_core.h5
-rw-r--r--init/Kconfig4
-rw-r--r--kernel/fork.c5
-rw-r--r--kernel/futex.c46
-rw-r--r--kernel/signal.c5
-rw-r--r--kernel/trace/Kconfig24
-rw-r--r--kernel/trace/trace.c27
-rw-r--r--kernel/user_namespace.c4
-rw-r--r--kernel/workqueue.c7
-rw-r--r--lib/idr.c80
-rw-r--r--lib/xz/Kconfig2
-rw-r--r--mm/Kconfig8
-rw-r--r--mm/fremap.c5
-rw-r--r--mm/memory_hotplug.c2
-rw-r--r--mm/process_vm_access.c8
-rw-r--r--net/bridge/br_device.c2
-rw-r--r--net/bridge/br_input.c2
-rw-r--r--net/bridge/br_mdb.c4
-rw-r--r--net/bridge/br_multicast.c3
-rw-r--r--net/bridge/br_private.h4
-rw-r--r--net/ceph/osdmap.c42
-rw-r--r--net/core/dev.c5
-rw-r--r--net/core/rtnetlink.c1
-rw-r--r--net/dcb/dcbnl.c8
-rw-r--r--net/ieee802154/6lowpan.h2
-rw-r--r--net/ipv4/inet_connection_sock.c1
-rw-r--r--net/ipv4/ip_options.c2
-rw-r--r--net/ipv6/ip6_input.c3
-rw-r--r--net/irda/ircomm/ircomm_tty.c29
-rw-r--r--net/key/af_key.c8
-rw-r--r--net/mac80211/cfg.c21
-rw-r--r--net/mac80211/iface.c6
-rw-r--r--net/mac80211/mlme.c28
-rw-r--r--net/mac80211/tx.c3
-rw-r--r--net/netfilter/nf_conntrack_helper.c11
-rw-r--r--net/netfilter/nfnetlink.c7
-rw-r--r--net/netfilter/xt_AUDIT.c3
-rw-r--r--net/netlabel/netlabel_unlabeled.c27
-rw-r--r--net/rds/stats.c1
-rw-r--r--net/sched/sch_qfq.c66
-rw-r--r--net/sunrpc/auth_gss/svcauth_gss.c12
-rw-r--r--net/sunrpc/rpc_pipe.c1
-rw-r--r--net/sunrpc/xprtsock.c15
-rw-r--r--net/wireless/core.c3
-rw-r--r--net/wireless/nl80211.c51
-rw-r--r--scripts/Makefile.headersinst11
-rw-r--r--security/keys/compat.c4
-rw-r--r--security/keys/process_keys.c2
-rw-r--r--sound/core/seq/seq_timer.c8
-rw-r--r--sound/oss/sequencer.c6
-rw-r--r--sound/pci/asihpi/asihpi.c3
-rw-r--r--sound/pci/hda/hda_codec.c24
-rw-r--r--sound/pci/hda/patch_ca0132.c28
-rw-r--r--sound/pci/hda/patch_cirrus.c4
-rw-r--r--sound/pci/hda/patch_sigmatel.c29
-rw-r--r--sound/usb/card.c15
-rw-r--r--tools/usb/ffs-test.c2
384 files changed, 4423 insertions, 1826 deletions
diff --git a/Documentation/arm/sunxi/clocks.txt b/Documentation/arm/sunxi/clocks.txt
new file mode 100644
index 000000000000..e09a88aa3136
--- /dev/null
+++ b/Documentation/arm/sunxi/clocks.txt
@@ -0,0 +1,56 @@
+Frequently asked questions about the sunxi clock system
+=======================================================
+
+This document contains useful bits of information that people tend to ask
+about the sunxi clock system, as well as accompanying ASCII art when adequate.
+
+Q: Why is the main 24MHz oscillator gatable? Wouldn't that break the
+ system?
+
+A: The 24MHz oscillator allows gating to save power. Indeed, if gated
+ carelessly the system would stop functioning, but with the right
+ steps, one can gate it and keep the system running. Consider this
+ simplified suspend example:
+
+ While the system is operational, you would see something like
+
+ 24MHz 32kHz
+ |
+ PLL1
+ \
+ \_ CPU Mux
+ |
+ [CPU]
+
+ When you are about to suspend, you switch the CPU Mux to the 32kHz
+ oscillator:
+
+ 24Mhz 32kHz
+ | |
+ PLL1 |
+ /
+ CPU Mux _/
+ |
+ [CPU]
+
+ Finally you can gate the main oscillator
+
+ 32kHz
+ |
+ |
+ /
+ CPU Mux _/
+ |
+ [CPU]
+
+Q: Were can I learn more about the sunxi clocks?
+
+A: The linux-sunxi wiki contains a page documenting the clock registers,
+ you can find it at
+
+ http://linux-sunxi.org/A10/CCM
+
+ The authoritative source for information at this time is the ccmu driver
+ released by Allwinner, you can find it at
+
+ https://github.com/linux-sunxi/linux-sunxi/tree/sunxi-3.0/arch/arm/mach-sun4i/clock/ccmu
diff --git a/Documentation/clk.txt b/Documentation/clk.txt
index 1943fae014fd..4274a546eb57 100644
--- a/Documentation/clk.txt
+++ b/Documentation/clk.txt
@@ -174,9 +174,9 @@ int clk_foo_enable(struct clk_hw *hw)
};
Below is a matrix detailing which clk_ops are mandatory based upon the
-hardware capbilities of that clock. A cell marked as "y" means
+hardware capabilities of that clock. A cell marked as "y" means
mandatory, a cell marked as "n" implies that either including that
-callback is invalid or otherwise uneccesary. Empty cells are either
+callback is invalid or otherwise unnecessary. Empty cells are either
optional or must be evaluated on a case-by-case basis.
clock hardware characteristics
diff --git a/Documentation/devicetree/bindings/clock/axi-clkgen.txt b/Documentation/devicetree/bindings/clock/axi-clkgen.txt
new file mode 100644
index 000000000000..028b493e97ff
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/axi-clkgen.txt
@@ -0,0 +1,22 @@
+Binding for the axi-clkgen clock generator
+
+This binding uses the common clock binding[1].
+
+[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
+
+Required properties:
+- compatible : shall be "adi,axi-clkgen".
+- #clock-cells : from common clock binding; Should always be set to 0.
+- reg : Address and length of the axi-clkgen register set.
+- clocks : Phandle and clock specifier for the parent clock.
+
+Optional properties:
+- clock-output-names : From common clock binding.
+
+Example:
+ clock@0xff000000 {
+ compatible = "adi,axi-clkgen";
+ #clock-cells = <0>;
+ reg = <0xff000000 0x1000>;
+ clocks = <&osc 1>;
+ };
diff --git a/Documentation/devicetree/bindings/clock/sunxi.txt b/Documentation/devicetree/bindings/clock/sunxi.txt
new file mode 100644
index 000000000000..729f52426fe1
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/sunxi.txt
@@ -0,0 +1,151 @@
+Device Tree Clock bindings for arch-sunxi
+
+This binding uses the common clock binding[1].
+
+[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
+
+Required properties:
+- compatible : shall be one of the following:
+ "allwinner,sun4i-osc-clk" - for a gatable oscillator
+ "allwinner,sun4i-pll1-clk" - for the main PLL clock
+ "allwinner,sun4i-cpu-clk" - for the CPU multiplexer clock
+ "allwinner,sun4i-axi-clk" - for the AXI clock
+ "allwinner,sun4i-axi-gates-clk" - for the AXI gates
+ "allwinner,sun4i-ahb-clk" - for the AHB clock
+ "allwinner,sun4i-ahb-gates-clk" - for the AHB gates
+ "allwinner,sun4i-apb0-clk" - for the APB0 clock
+ "allwinner,sun4i-apb0-gates-clk" - for the APB0 gates
+ "allwinner,sun4i-apb1-clk" - for the APB1 clock
+ "allwinner,sun4i-apb1-mux-clk" - for the APB1 clock muxing
+ "allwinner,sun4i-apb1-gates-clk" - for the APB1 gates
+
+Required properties for all clocks:
+- reg : shall be the control register address for the clock.
+- clocks : shall be the input parent clock(s) phandle for the clock
+- #clock-cells : from common clock binding; shall be set to 0 except for
+ "allwinner,sun4i-*-gates-clk" where it shall be set to 1
+
+Additionally, "allwinner,sun4i-*-gates-clk" clocks require:
+- clock-output-names : the corresponding gate names that the clock controls
+
+For example:
+
+osc24M: osc24M@01c20050 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-osc-clk";
+ reg = <0x01c20050 0x4>;
+ clocks = <&osc24M_fixed>;
+};
+
+pll1: pll1@01c20000 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-pll1-clk";
+ reg = <0x01c20000 0x4>;
+ clocks = <&osc24M>;
+};
+
+cpu: cpu@01c20054 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-cpu-clk";
+ reg = <0x01c20054 0x4>;
+ clocks = <&osc32k>, <&osc24M>, <&pll1>;
+};
+
+
+
+Gate clock outputs
+
+The "allwinner,sun4i-*-gates-clk" clocks provide several gatable outputs;
+their corresponding offsets as present on sun4i are listed below. Note that
+some of these gates are not present on sun5i.
+
+ * AXI gates ("allwinner,sun4i-axi-gates-clk")
+
+ DRAM 0
+
+ * AHB gates ("allwinner,sun4i-ahb-gates-clk")
+
+ USB0 0
+ EHCI0 1
+ OHCI0 2*
+ EHCI1 3
+ OHCI1 4*
+ SS 5
+ DMA 6
+ BIST 7
+ MMC0 8
+ MMC1 9
+ MMC2 10
+ MMC3 11
+ MS 12**
+ NAND 13
+ SDRAM 14
+
+ ACE 16
+ EMAC 17
+ TS 18
+
+ SPI0 20
+ SPI1 21
+ SPI2 22
+ SPI3 23
+ PATA 24
+ SATA 25**
+ GPS 26*
+
+ VE 32
+ TVD 33
+ TVE0 34
+ TVE1 35
+ LCD0 36
+ LCD1 37
+
+ CSI0 40
+ CSI1 41
+
+ HDMI 43
+ DE_BE0 44
+ DE_BE1 45
+ DE_FE0 46
+ DE_FE1 47
+
+ MP 50
+
+ MALI400 52
+
+ * APB0 gates ("allwinner,sun4i-apb0-gates-clk")
+
+ CODEC 0
+ SPDIF 1*
+ AC97 2
+ IIS 3
+
+ PIO 5
+ IR0 6
+ IR1 7
+
+ KEYPAD 10
+
+ * APB1 gates ("allwinner,sun4i-apb1-gates-clk")
+
+ I2C0 0
+ I2C1 1
+ I2C2 2
+
+ CAN 4
+ SCR 5
+ PS20 6
+ PS21 7
+
+ UART0 16
+ UART1 17
+ UART2 18
+ UART3 19
+ UART4 20
+ UART5 21
+ UART6 22
+ UART7 23
+
+Notation:
+ [*]: The datasheet didn't mention these, but they are present on AW code
+ [**]: The datasheet had this marked as "NC" but they are used on AW code
diff --git a/Documentation/devicetree/bindings/mfd/ab8500.txt b/Documentation/devicetree/bindings/mfd/ab8500.txt
index 13b707b7355c..c3a14e0ad0ad 100644
--- a/Documentation/devicetree/bindings/mfd/ab8500.txt
+++ b/Documentation/devicetree/bindings/mfd/ab8500.txt
@@ -13,9 +13,6 @@ Required parent device properties:
4 = active high level-sensitive
8 = active low level-sensitive
-Optional parent device properties:
-- reg : contains the PRCMU mailbox address for the AB8500 i2c port
-
The AB8500 consists of a large and varied group of sub-devices:
Device IRQ Names Supply Names Description
@@ -86,9 +83,8 @@ Non-standard child device properties:
- stericsson,amic2-bias-vamic1 : Analoge Mic wishes to use a non-standard Vamic
- stericsson,earpeice-cmv : Earpeice voltage (only: 950 | 1100 | 1270 | 1580)
-ab8500@5 {
+ab8500 {
compatible = "stericsson,ab8500";
- reg = <5>; /* mailbox 5 is i2c */
interrupts = <0 40 0x4>;
interrupt-controller;
#interrupt-cells = <2>;
diff --git a/Documentation/devicetree/bindings/tty/serial/of-serial.txt b/Documentation/devicetree/bindings/tty/serial/of-serial.txt
index 1e1145ca4f3c..8f01cb190f25 100644
--- a/Documentation/devicetree/bindings/tty/serial/of-serial.txt
+++ b/Documentation/devicetree/bindings/tty/serial/of-serial.txt
@@ -11,6 +11,9 @@ Required properties:
- "nvidia,tegra20-uart"
- "nxp,lpc3220-uart"
- "ibm,qpace-nwp-serial"
+ - "altr,16550-FIFO32"
+ - "altr,16550-FIFO64"
+ - "altr,16550-FIFO128"
- "serial" if the port type is unknown.
- reg : offset and length of the register set for the device.
- interrupts : should contain uart interrupt.
diff --git a/Documentation/input/alps.txt b/Documentation/input/alps.txt
index 3262b6e4d686..e544c7ff8cfa 100644
--- a/Documentation/input/alps.txt
+++ b/Documentation/input/alps.txt
@@ -3,10 +3,26 @@ ALPS Touchpad Protocol
Introduction
------------
-
-Currently the ALPS touchpad driver supports four protocol versions in use by
-ALPS touchpads, called versions 1, 2, 3, and 4. Information about the various
-protocol versions is contained in the following sections.
+Currently the ALPS touchpad driver supports five protocol versions in use by
+ALPS touchpads, called versions 1, 2, 3, 4 and 5.
+
+Since roughly mid-2010 several new ALPS touchpads have been released and
+integrated into a variety of laptops and netbooks. These new touchpads
+have enough behavior differences that the alps_model_data definition
+table, describing the properties of the different versions, is no longer
+adequate. The design choices were to re-define the alps_model_data
+table, with the risk of regression testing existing devices, or isolate
+the new devices outside of the alps_model_data table. The latter design
+choice was made. The new touchpad signatures are named: "Rushmore",
+"Pinnacle", and "Dolphin", which you will see in the alps.c code.
+For the purposes of this document, this group of ALPS touchpads will
+generically be called "new ALPS touchpads".
+
+We experimented with probing the ACPI interface _HID (Hardware ID)/_CID
+(Compatibility ID) definition as a way to uniquely identify the
+different ALPS variants but there did not appear to be a 1:1 mapping.
+In fact, it appeared to be an m:n mapping between the _HID and actual
+hardware type.
Detection
---------
@@ -20,9 +36,13 @@ If the E6 report is successful, the touchpad model is identified using the "E7
report" sequence: E8-E7-E7-E7-E9. The response is the model signature and is
matched against known models in the alps_model_data_array.
-With protocol versions 3 and 4, the E7 report model signature is always
-73-02-64. To differentiate between these versions, the response from the
-"Enter Command Mode" sequence must be inspected as described below.
+For older touchpads supporting protocol versions 3 and 4, the E7 report
+model signature is always 73-02-64. To differentiate between these
+versions, the response from the "Enter Command Mode" sequence must be
+inspected as described below.
+
+The new ALPS touchpads have an E7 signature of 73-03-50 or 73-03-0A but
+seem to be better differentiated by the EC Command Mode response.
Command Mode
------------
@@ -47,6 +67,14 @@ address of the register being read, and the third contains the value of the
register. Registers are written by writing the value one nibble at a time
using the same encoding used for addresses.
+For the new ALPS touchpads, the EC command is used to enter command
+mode. The response in the new ALPS touchpads is significantly different,
+and more important in determining the behavior. This code has been
+separated from the original alps_model_data table and put in the
+alps_identify function. For example, there seem to be two hardware init
+sequences for the "Dolphin" touchpads as determined by the second byte
+of the EC response.
+
Packet Format
-------------
@@ -187,3 +215,28 @@ There are several things worth noting here.
well.
So far no v4 devices with tracksticks have been encountered.
+
+ALPS Absolute Mode - Protocol Version 5
+---------------------------------------
+This is basically Protocol Version 3 but with different logic for packet
+decode. It uses the same alps_process_touchpad_packet_v3 call with a
+specialized decode_fields function pointer to correctly interpret the
+packets. This appears to only be used by the Dolphin devices.
+
+For single-touch, the 6-byte packet format is:
+
+ byte 0: 1 1 0 0 1 0 0 0
+ byte 1: 0 x6 x5 x4 x3 x2 x1 x0
+ byte 2: 0 y6 y5 y4 y3 y2 y1 y0
+ byte 3: 0 M R L 1 m r l
+ byte 4: y10 y9 y8 y7 x10 x9 x8 x7
+ byte 5: 0 z6 z5 z4 z3 z2 z1 z0
+
+For mt, the format is:
+
+ byte 0: 1 1 1 n3 1 n2 n1 x24
+ byte 1: 1 y7 y6 y5 y4 y3 y2 y1
+ byte 2: ? x2 x1 y12 y11 y10 y9 y8
+ byte 3: 0 x23 x22 x21 x20 x19 x18 x17
+ byte 4: 0 x9 x8 x7 x6 x5 x4 x3
+ byte 5: 0 x16 x15 x14 x13 x12 x11 x10
diff --git a/Documentation/networking/tuntap.txt b/Documentation/networking/tuntap.txt
index c0aab985bad9..949d5dcdd9a3 100644
--- a/Documentation/networking/tuntap.txt
+++ b/Documentation/networking/tuntap.txt
@@ -105,6 +105,83 @@ Copyright (C) 1999-2000 Maxim Krasnyansky <max_mk@yahoo.com>
Proto [2 bytes]
Raw protocol(IP, IPv6, etc) frame.
+ 3.3 Multiqueue tuntap interface:
+
+ From version 3.8, Linux supports multiqueue tuntap which can uses multiple
+ file descriptors (queues) to parallelize packets sending or receiving. The
+ device allocation is the same as before, and if user wants to create multiple
+ queues, TUNSETIFF with the same device name must be called many times with
+ IFF_MULTI_QUEUE flag.
+
+ char *dev should be the name of the device, queues is the number of queues to
+ be created, fds is used to store and return the file descriptors (queues)
+ created to the caller. Each file descriptor were served as the interface of a
+ queue which could be accessed by userspace.
+
+ #include <linux/if.h>
+ #include <linux/if_tun.h>
+
+ int tun_alloc_mq(char *dev, int queues, int *fds)
+ {
+ struct ifreq ifr;
+ int fd, err, i;
+
+ if (!dev)
+ return -1;
+
+ memset(&ifr, 0, sizeof(ifr));
+ /* Flags: IFF_TUN - TUN device (no Ethernet headers)
+ * IFF_TAP - TAP device
+ *
+ * IFF_NO_PI - Do not provide packet information
+ * IFF_MULTI_QUEUE - Create a queue of multiqueue device
+ */
+ ifr.ifr_flags = IFF_TAP | IFF_NO_PI | IFF_MULTI_QUEUE;
+ strcpy(ifr.ifr_name, dev);
+
+ for (i = 0; i < queues; i++) {
+ if ((fd = open("/dev/net/tun", O_RDWR)) < 0)
+ goto err;
+ err = ioctl(fd, TUNSETIFF, (void *)&ifr);
+ if (err) {
+ close(fd);
+ goto err;
+ }
+ fds[i] = fd;
+ }
+
+ return 0;
+ err:
+ for (--i; i >= 0; i--)
+ close(fds[i]);
+ return err;
+ }
+
+ A new ioctl(TUNSETQUEUE) were introduced to enable or disable a queue. When
+ calling it with IFF_DETACH_QUEUE flag, the queue were disabled. And when
+ calling it with IFF_ATTACH_QUEUE flag, the queue were enabled. The queue were
+ enabled by default after it was created through TUNSETIFF.
+
+ fd is the file descriptor (queue) that we want to enable or disable, when
+ enable is true we enable it, otherwise we disable it
+
+ #include <linux/if.h>
+ #include <linux/if_tun.h>
+
+ int tun_set_queue(int fd, int enable)
+ {
+ struct ifreq ifr;
+
+ memset(&ifr, 0, sizeof(ifr));
+
+ if (enable)
+ ifr.ifr_flags = IFF_ATTACH_QUEUE;
+ else
+ ifr.ifr_flags = IFF_DETACH_QUEUE;
+
+ return ioctl(fd, TUNSETQUEUE, (void *)&ifr);
+ }
+
Universal TUN/TAP device driver Frequently Asked Question.
1. What platforms are supported by TUN/TAP driver ?
diff --git a/Documentation/trace/ftrace.txt b/Documentation/trace/ftrace.txt
index 53d6a3c51d87..a372304aef10 100644
--- a/Documentation/trace/ftrace.txt
+++ b/Documentation/trace/ftrace.txt
@@ -1873,7 +1873,7 @@ feature:
status\input | 0 | 1 | else |
--------------+------------+------------+------------+
- not allocated |(do nothing)| alloc+swap | EINVAL |
+ not allocated |(do nothing)| alloc+swap |(do nothing)|
--------------+------------+------------+------------+
allocated | free | swap | clear |
--------------+------------+------------+------------+
diff --git a/MAINTAINERS b/MAINTAINERS
index 95616582c728..50b4d735f961 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4005,6 +4005,22 @@ M: Stanislaw Gruszka <stf_xl@wp.pl>
S: Maintained
F: drivers/usb/atm/ueagle-atm.c
+INA209 HARDWARE MONITOR DRIVER
+M: Guenter Roeck <linux@roeck-us.net>
+L: lm-sensors@lm-sensors.org
+S: Maintained
+F: Documentation/hwmon/ina209
+F: Documentation/devicetree/bindings/i2c/ina209.txt
+F: drivers/hwmon/ina209.c
+
+INA2XX HARDWARE MONITOR DRIVER
+M: Guenter Roeck <linux@roeck-us.net>
+L: lm-sensors@lm-sensors.org
+S: Maintained
+F: Documentation/hwmon/ina2xx
+F: drivers/hwmon/ina2xx.c
+F: include/linux/platform_data/ina2xx.h
+
INDUSTRY PACK SUBSYSTEM (IPACK)
M: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
M: Jens Taprogge <jens.taprogge@taprogge.org>
@@ -5098,6 +5114,15 @@ S: Maintained
F: Documentation/hwmon/max6650
F: drivers/hwmon/max6650.c
+MAX6697 HARDWARE MONITOR DRIVER
+M: Guenter Roeck <linux@roeck-us.net>
+L: lm-sensors@lm-sensors.org
+S: Maintained
+F: Documentation/hwmon/max6697
+F: Documentation/devicetree/bindings/i2c/max6697.txt
+F: drivers/hwmon/max6697.c
+F: include/linux/platform_data/max6697.h
+
MAXIRADIO FM RADIO RECEIVER DRIVER
M: Hans Verkuil <hverkuil@xs4all.nl>
L: linux-media@vger.kernel.org
@@ -6412,6 +6437,8 @@ F: Documentation/networking/LICENSE.qla3xxx
F: drivers/net/ethernet/qlogic/qla3xxx.*
QLOGIC QLCNIC (1/10)Gb ETHERNET DRIVER
+M: Rajesh Borundia <rajesh.borundia@qlogic.com>
+M: Shahed Shaikh <shahed.shaikh@qlogic.com>
M: Jitendra Kalsaria <jitendra.kalsaria@qlogic.com>
M: Sony Chacko <sony.chacko@qlogic.com>
M: linux-driver@qlogic.com
diff --git a/Makefile b/Makefile
index a05ea42c5f18..22113a77f8ed 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
VERSION = 3
PATCHLEVEL = 9
SUBLEVEL = 0
-EXTRAVERSION = -rc2
+EXTRAVERSION = -rc3
NAME = Unicycling Gorilla
# *DOCUMENTATION*
diff --git a/arch/Kconfig b/arch/Kconfig
index 5a1779c93940..1455579791ec 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -319,13 +319,6 @@ config ARCH_WANT_OLD_COMPAT_IPC
select ARCH_WANT_COMPAT_IPC_PARSE_VERSION
bool
-config HAVE_VIRT_TO_BUS
- bool
- help
- An architecture should select this if it implements the
- deprecated interface virt_to_bus(). All new architectures
- should probably not select this.
-
config HAVE_ARCH_SECCOMP_FILTER
bool
help
diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig
index 5833aa441481..8a33ba01301f 100644
--- a/arch/alpha/Kconfig
+++ b/arch/alpha/Kconfig
@@ -9,7 +9,7 @@ config ALPHA
select HAVE_PERF_EVENTS
select HAVE_DMA_ATTRS
select HAVE_GENERIC_HARDIRQS
- select HAVE_VIRT_TO_BUS
+ select VIRT_TO_BUS
select GENERIC_IRQ_PROBE
select AUTO_IRQ_AFFINITY if SMP
select GENERIC_IRQ_SHOW
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 5bfd584929c8..eaae82a182ed 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -49,7 +49,7 @@ config ARM
select HAVE_REGS_AND_STACK_ACCESS_API
select HAVE_SYSCALL_TRACEPOINTS
select HAVE_UID16
- select HAVE_VIRT_TO_BUS
+ select VIRT_TO_BUS
select KTIME_SCALAR
select PERF_USE_VMALLOC
select RTC_LIB
@@ -556,7 +556,6 @@ config ARCH_IXP4XX
config ARCH_DOVE
bool "Marvell Dove"
select ARCH_REQUIRE_GPIOLIB
- select COMMON_CLK_DOVE
select CPU_V7
select GENERIC_CLOCKEVENTS
select MIGHT_HAVE_PCI
@@ -1658,13 +1657,16 @@ config LOCAL_TIMERS
accounting to be spread across the timer interval, preventing a
"thundering herd" at every timer tick.
+# The GPIO number here must be sorted by descending number. In case of
+# a multiplatform kernel, we just want the highest value required by the
+# selected platforms.
config ARCH_NR_GPIO
int
default 1024 if ARCH_SHMOBILE || ARCH_TEGRA
- default 355 if ARCH_U8500
- default 264 if MACH_H4700
default 512 if SOC_OMAP5
+ default 355 if ARCH_U8500
default 288 if ARCH_VT8500 || ARCH_SUNXI
+ default 264 if MACH_H4700
default 0
help
Maximum number of GPIOs in the system.
@@ -1888,8 +1890,9 @@ config XEN_DOM0
config XEN
bool "Xen guest support on ARM (EXPERIMENTAL)"
- depends on ARM && OF
+ depends on ARM && AEABI && OF
depends on CPU_V7 && !CPU_V6
+ depends on !GENERIC_ATOMIC64
help
Say Y if you want to run Linux in a Virtual Machine on Xen on ARM.
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index acddddac7ee4..ecfcdba2d17c 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -492,7 +492,7 @@ config DEBUG_IMX_UART_PORT
DEBUG_IMX31_UART || \
DEBUG_IMX35_UART || \
DEBUG_IMX51_UART || \
- DEBUG_IMX50_IMX53_UART || \
+ DEBUG_IMX53_UART || \
DEBUG_IMX6Q_UART
default 1
help
diff --git a/arch/arm/boot/Makefile b/arch/arm/boot/Makefile
index 71768b8a1ab9..84aa2caf07ed 100644
--- a/arch/arm/boot/Makefile
+++ b/arch/arm/boot/Makefile
@@ -115,4 +115,4 @@ i:
$(CONFIG_SHELL) $(srctree)/$(src)/install.sh $(KERNELRELEASE) \
$(obj)/Image System.map "$(INSTALL_PATH)"
-subdir- := bootp compressed
+subdir- := bootp compressed dts
diff --git a/arch/arm/boot/dts/armada-370-rd.dts b/arch/arm/boot/dts/armada-370-rd.dts
index f8e4855bc9a5..070bba4f2585 100644
--- a/arch/arm/boot/dts/armada-370-rd.dts
+++ b/arch/arm/boot/dts/armada-370-rd.dts
@@ -64,5 +64,13 @@
status = "okay";
/* No CD or WP GPIOs */
};
+
+ usb@d0050000 {
+ status = "okay";
+ };
+
+ usb@d0051000 {
+ status = "okay";
+ };
};
};
diff --git a/arch/arm/boot/dts/armada-370-xp.dtsi b/arch/arm/boot/dts/armada-370-xp.dtsi
index 6f1acc75e155..5b708208b607 100644
--- a/arch/arm/boot/dts/armada-370-xp.dtsi
+++ b/arch/arm/boot/dts/armada-370-xp.dtsi
@@ -31,7 +31,6 @@
mpic: interrupt-controller@d0020000 {
compatible = "marvell,mpic";
#interrupt-cells = <1>;
- #address-cells = <1>;
#size-cells = <1>;
interrupt-controller;
};
@@ -54,7 +53,7 @@
reg = <0xd0012000 0x100>;
reg-shift = <2>;
interrupts = <41>;
- reg-io-width = <4>;
+ reg-io-width = <1>;
status = "disabled";
};
serial@d0012100 {
@@ -62,7 +61,7 @@
reg = <0xd0012100 0x100>;
reg-shift = <2>;
interrupts = <42>;
- reg-io-width = <4>;
+ reg-io-width = <1>;
status = "disabled";
};
diff --git a/arch/arm/boot/dts/armada-xp.dtsi b/arch/arm/boot/dts/armada-xp.dtsi
index 1443949c165e..ca00d8326c87 100644
--- a/arch/arm/boot/dts/armada-xp.dtsi
+++ b/arch/arm/boot/dts/armada-xp.dtsi
@@ -46,7 +46,7 @@
reg = <0xd0012200 0x100>;
reg-shift = <2>;
interrupts = <43>;
- reg-io-width = <4>;
+ reg-io-width = <1>;
status = "disabled";
};
serial@d0012300 {
@@ -54,7 +54,7 @@
reg = <0xd0012300 0x100>;
reg-shift = <2>;
interrupts = <44>;
- reg-io-width = <4>;
+ reg-io-width = <1>;
status = "disabled";
};
diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi
index 4bf2a8774aa7..7e0481e2441a 100644
--- a/arch/arm/boot/dts/bcm2835.dtsi
+++ b/arch/arm/boot/dts/bcm2835.dtsi
@@ -105,7 +105,7 @@
compatible = "fixed-clock";
reg = <1>;
#clock-cells = <0>;
- clock-frequency = <150000000>;
+ clock-frequency = <250000000>;
};
};
};
diff --git a/arch/arm/boot/dts/dbx5x0.dtsi b/arch/arm/boot/dts/dbx5x0.dtsi
index 69140ba99f46..9de93096601a 100644
--- a/arch/arm/boot/dts/dbx5x0.dtsi
+++ b/arch/arm/boot/dts/dbx5x0.dtsi
@@ -319,9 +319,8 @@
};
};
- ab8500@5 {
+ ab8500 {
compatible = "stericsson,ab8500";
- reg = <5>; /* mailbox 5 is i2c */
interrupt-parent = <&intc>;
interrupts = <0 40 0x4>;
interrupt-controller;
diff --git a/arch/arm/boot/dts/dove.dtsi b/arch/arm/boot/dts/dove.dtsi
index 67dbe20868a2..f7509cafc377 100644
--- a/arch/arm/boot/dts/dove.dtsi
+++ b/arch/arm/boot/dts/dove.dtsi
@@ -197,6 +197,11 @@
status = "disabled";
};
+ rtc@d8500 {
+ compatible = "marvell,orion-rtc";
+ reg = <0xd8500 0x20>;
+ };
+
crypto: crypto@30000 {
compatible = "marvell,orion-crypto";
reg = <0x30000 0x10000>,
diff --git a/arch/arm/boot/dts/href.dtsi b/arch/arm/boot/dts/href.dtsi
index 592fb9dc35bd..379128eb9d98 100644
--- a/arch/arm/boot/dts/href.dtsi
+++ b/arch/arm/boot/dts/href.dtsi
@@ -221,7 +221,7 @@
};
};
- ab8500@5 {
+ ab8500 {
ab8500-regulators {
ab8500_ldo_aux1_reg: ab8500_ldo_aux1 {
regulator-name = "V-DISPLAY";
diff --git a/arch/arm/boot/dts/hrefv60plus.dts b/arch/arm/boot/dts/hrefv60plus.dts
index 55f4191a626e..2b587a74b813 100644
--- a/arch/arm/boot/dts/hrefv60plus.dts
+++ b/arch/arm/boot/dts/hrefv60plus.dts
@@ -158,7 +158,7 @@
};
};
- ab8500@5 {
+ ab8500 {
ab8500-regulators {
ab8500_ldo_aux1_reg: ab8500_ldo_aux1 {
regulator-name = "V-DISPLAY";
diff --git a/arch/arm/boot/dts/imx53-mba53.dts b/arch/arm/boot/dts/imx53-mba53.dts
index e54fffd48369..468c0a1d48d9 100644
--- a/arch/arm/boot/dts/imx53-mba53.dts
+++ b/arch/arm/boot/dts/imx53-mba53.dts
@@ -42,10 +42,9 @@
fsl,pins = <689 0x10000 /* DISP1_DRDY */
482 0x10000 /* DISP1_HSYNC */
489 0x10000 /* DISP1_VSYNC */
- 684 0x10000 /* DISP1_DAT_0 */
515 0x10000 /* DISP1_DAT_22 */
523 0x10000 /* DISP1_DAT_23 */
- 543 0x10000 /* DISP1_DAT_21 */
+ 545 0x10000 /* DISP1_DAT_21 */
553 0x10000 /* DISP1_DAT_20 */
558 0x10000 /* DISP1_DAT_19 */
564 0x10000 /* DISP1_DAT_18 */
diff --git a/arch/arm/boot/dts/kirkwood-dns320.dts b/arch/arm/boot/dts/kirkwood-dns320.dts
index 5bb0bf39d3b8..c9c44b2f62d7 100644
--- a/arch/arm/boot/dts/kirkwood-dns320.dts
+++ b/arch/arm/boot/dts/kirkwood-dns320.dts
@@ -42,12 +42,10 @@
ocp@f1000000 {
serial@12000 {
- clock-frequency = <166666667>;
status = "okay";
};
serial@12100 {
- clock-frequency = <166666667>;
status = "okay";
};
};
diff --git a/arch/arm/boot/dts/kirkwood-dns325.dts b/arch/arm/boot/dts/kirkwood-dns325.dts
index d430713ea9b9..e4e4930dc5cf 100644
--- a/arch/arm/boot/dts/kirkwood-dns325.dts
+++ b/arch/arm/boot/dts/kirkwood-dns325.dts
@@ -50,7 +50,6 @@
};
};
serial@12000 {
- clock-frequency = <200000000>;
status = "okay";
};
};
diff --git a/arch/arm/boot/dts/kirkwood-dockstar.dts b/arch/arm/boot/dts/kirkwood-dockstar.dts
index 2e3dd34e21a5..0196cf6b0ef2 100644
--- a/arch/arm/boot/dts/kirkwood-dockstar.dts
+++ b/arch/arm/boot/dts/kirkwood-dockstar.dts
@@ -37,7 +37,6 @@
};
};
serial@12000 {
- clock-frequency = <200000000>;
status = "ok";
};
diff --git a/arch/arm/boot/dts/kirkwood-dreamplug.dts b/arch/arm/boot/dts/kirkwood-dreamplug.dts
index ef2d8c705709..289e51d86372 100644
--- a/arch/arm/boot/dts/kirkwood-dreamplug.dts
+++ b/arch/arm/boot/dts/kirkwood-dreamplug.dts
@@ -38,7 +38,6 @@
};
};
serial@12000 {
- clock-frequency = <200000000>;
status = "ok";
};
diff --git a/arch/arm/boot/dts/kirkwood-goflexnet.dts b/arch/arm/boot/dts/kirkwood-goflexnet.dts
index 1b133e0c566e..bd83b8fc7c83 100644
--- a/arch/arm/boot/dts/kirkwood-goflexnet.dts
+++ b/arch/arm/boot/dts/kirkwood-goflexnet.dts
@@ -73,7 +73,6 @@
};
};
serial@12000 {
- clock-frequency = <200000000>;
status = "ok";
};
diff --git a/arch/arm/boot/dts/kirkwood-ib62x0.dts b/arch/arm/boot/dts/kirkwood-ib62x0.dts
index 71902da33d63..5335b1aa8601 100644
--- a/arch/arm/boot/dts/kirkwood-ib62x0.dts
+++ b/arch/arm/boot/dts/kirkwood-ib62x0.dts
@@ -51,7 +51,6 @@
};
};
serial@12000 {
- clock-frequency = <200000000>;
status = "okay";
};
diff --git a/arch/arm/boot/dts/kirkwood-iconnect.dts b/arch/arm/boot/dts/kirkwood-iconnect.dts
index 504f16be8b54..12ccf74ac3c4 100644
--- a/arch/arm/boot/dts/kirkwood-iconnect.dts
+++ b/arch/arm/boot/dts/kirkwood-iconnect.dts
@@ -78,7 +78,6 @@
};
};
serial@12000 {
- clock-frequency = <200000000>;
status = "ok";
};
diff --git a/arch/arm/boot/dts/kirkwood-iomega_ix2_200.dts b/arch/arm/boot/dts/kirkwood-iomega_ix2_200.dts
index 6cae4599c4b3..93c3afbef9ee 100644
--- a/arch/arm/boot/dts/kirkwood-iomega_ix2_200.dts
+++ b/arch/arm/boot/dts/kirkwood-iomega_ix2_200.dts
@@ -115,7 +115,6 @@
};
serial@12000 {
- clock-frequency = <200000000>;
status = "ok";
};
diff --git a/arch/arm/boot/dts/kirkwood-km_kirkwood.dts b/arch/arm/boot/dts/kirkwood-km_kirkwood.dts
index 8db3123ac80f..5bbd0542cdd3 100644
--- a/arch/arm/boot/dts/kirkwood-km_kirkwood.dts
+++ b/arch/arm/boot/dts/kirkwood-km_kirkwood.dts
@@ -34,7 +34,6 @@
};
serial@12000 {
- clock-frequency = <200000000>;
status = "ok";
};
diff --git a/arch/arm/boot/dts/kirkwood-lschlv2.dts b/arch/arm/boot/dts/kirkwood-lschlv2.dts
index 9510c9ea666c..9f55d95f35f5 100644
--- a/arch/arm/boot/dts/kirkwood-lschlv2.dts
+++ b/arch/arm/boot/dts/kirkwood-lschlv2.dts
@@ -13,7 +13,6 @@
ocp@f1000000 {
serial@12000 {
- clock-frequency = <166666667>;
status = "okay";
};
};
diff --git a/arch/arm/boot/dts/kirkwood-lsxhl.dts b/arch/arm/boot/dts/kirkwood-lsxhl.dts
index 739019c4cba9..5c84c118ed8d 100644
--- a/arch/arm/boot/dts/kirkwood-lsxhl.dts
+++ b/arch/arm/boot/dts/kirkwood-lsxhl.dts
@@ -13,7 +13,6 @@
ocp@f1000000 {
serial@12000 {
- clock-frequency = <200000000>;
status = "okay";
};
};
diff --git a/arch/arm/boot/dts/kirkwood-mplcec4.dts b/arch/arm/boot/dts/kirkwood-mplcec4.dts
index 662dfd81b1ce..758824118a9a 100644
--- a/arch/arm/boot/dts/kirkwood-mplcec4.dts
+++ b/arch/arm/boot/dts/kirkwood-mplcec4.dts
@@ -90,7 +90,6 @@
};
serial@12000 {
- clock-frequency = <200000000>;
status = "ok";
};
diff --git a/arch/arm/boot/dts/kirkwood-ns2-common.dtsi b/arch/arm/boot/dts/kirkwood-ns2-common.dtsi
index e8e7ecef1650..6affd924fe11 100644
--- a/arch/arm/boot/dts/kirkwood-ns2-common.dtsi
+++ b/arch/arm/boot/dts/kirkwood-ns2-common.dtsi
@@ -23,7 +23,6 @@
};
serial@12000 {
- clock-frequency = <166666667>;
status = "okay";
};
diff --git a/arch/arm/boot/dts/kirkwood-nsa310.dts b/arch/arm/boot/dts/kirkwood-nsa310.dts
index 3a178cf708d7..a7412b937a8a 100644
--- a/arch/arm/boot/dts/kirkwood-nsa310.dts
+++ b/arch/arm/boot/dts/kirkwood-nsa310.dts
@@ -117,7 +117,6 @@
};
serial@12000 {
- clock-frequency = <200000000>;
status = "ok";
};
diff --git a/arch/arm/boot/dts/kirkwood-openblocks_a6.dts b/arch/arm/boot/dts/kirkwood-openblocks_a6.dts
index ede7fe0d7a87..d27f7245f8e7 100644
--- a/arch/arm/boot/dts/kirkwood-openblocks_a6.dts
+++ b/arch/arm/boot/dts/kirkwood-openblocks_a6.dts
@@ -18,12 +18,10 @@
ocp@f1000000 {
serial@12000 {
- clock-frequency = <200000000>;
status = "ok";
};
serial@12100 {
- clock-frequency = <200000000>;
status = "ok";
};
diff --git a/arch/arm/boot/dts/kirkwood-topkick.dts b/arch/arm/boot/dts/kirkwood-topkick.dts
index 842ff95d60df..66eb45b00b25 100644
--- a/arch/arm/boot/dts/kirkwood-topkick.dts
+++ b/arch/arm/boot/dts/kirkwood-topkick.dts
@@ -108,7 +108,6 @@
};
serial@12000 {
- clock-frequency = <200000000>;
status = "ok";
};
diff --git a/arch/arm/boot/dts/kirkwood.dtsi b/arch/arm/boot/dts/kirkwood.dtsi
index 2c738d9dc82a..fada7e6d24d8 100644
--- a/arch/arm/boot/dts/kirkwood.dtsi
+++ b/arch/arm/boot/dts/kirkwood.dtsi
@@ -38,6 +38,7 @@
interrupt-controller;
#interrupt-cells = <2>;
interrupts = <35>, <36>, <37>, <38>;
+ clocks = <&gate_clk 7>;
};
gpio1: gpio@10140 {
@@ -49,6 +50,7 @@
interrupt-controller;
#interrupt-cells = <2>;
interrupts = <39>, <40>, <41>;
+ clocks = <&gate_clk 7>;
};
serial@12000 {
@@ -57,7 +59,6 @@
reg-shift = <2>;
interrupts = <33>;
clocks = <&gate_clk 7>;
- /* set clock-frequency in board dts */
status = "disabled";
};
@@ -67,7 +68,6 @@
reg-shift = <2>;
interrupts = <34>;
clocks = <&gate_clk 7>;
- /* set clock-frequency in board dts */
status = "disabled";
};
@@ -75,6 +75,7 @@
compatible = "marvell,kirkwood-rtc", "marvell,orion-rtc";
reg = <0x10300 0x20>;
interrupts = <53>;
+ clocks = <&gate_clk 7>;
};
spi@10600 {
diff --git a/arch/arm/boot/dts/orion5x-lacie-ethernet-disk-mini-v2.dts b/arch/arm/boot/dts/orion5x-lacie-ethernet-disk-mini-v2.dts
index 5a3a58b7e18f..0077fc8510b7 100644
--- a/arch/arm/boot/dts/orion5x-lacie-ethernet-disk-mini-v2.dts
+++ b/arch/arm/boot/dts/orion5x-lacie-ethernet-disk-mini-v2.dts
@@ -11,7 +11,7 @@
/ {
model = "LaCie Ethernet Disk mini V2";
- compatible = "lacie,ethernet-disk-mini-v2", "marvell-orion5x-88f5182", "marvell,orion5x";
+ compatible = "lacie,ethernet-disk-mini-v2", "marvell,orion5x-88f5182", "marvell,orion5x";
memory {
reg = <0x00000000 0x4000000>; /* 64 MB */
diff --git a/arch/arm/boot/dts/snowball.dts b/arch/arm/boot/dts/snowball.dts
index 27f31a5fa494..d3ec32f6b790 100644
--- a/arch/arm/boot/dts/snowball.dts
+++ b/arch/arm/boot/dts/snowball.dts
@@ -298,7 +298,7 @@
};
};
- ab8500@5 {
+ ab8500 {
ab8500-regulators {
ab8500_ldo_aux1_reg: ab8500_ldo_aux1 {
regulator-name = "V-DISPLAY";
diff --git a/arch/arm/boot/dts/socfpga.dtsi b/arch/arm/boot/dts/socfpga.dtsi
index 936d2306e7e1..7e8769bd5977 100644
--- a/arch/arm/boot/dts/socfpga.dtsi
+++ b/arch/arm/boot/dts/socfpga.dtsi
@@ -75,6 +75,9 @@
compatible = "arm,pl330", "arm,primecell";
reg = <0xffe01000 0x1000>;
interrupts = <0 180 4>;
+ #dma-cells = <1>;
+ #dma-channels = <8>;
+ #dma-requests = <32>;
};
};
diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi
index 9a428931d042..48d00a099ce3 100644
--- a/arch/arm/boot/dts/tegra20.dtsi
+++ b/arch/arm/boot/dts/tegra20.dtsi
@@ -118,6 +118,7 @@
compatible = "arm,cortex-a9-twd-timer";
reg = <0x50040600 0x20>;
interrupts = <1 13 0x304>;
+ clocks = <&tegra_car 132>;
};
intc: interrupt-controller {
diff --git a/arch/arm/boot/dts/tegra30.dtsi b/arch/arm/boot/dts/tegra30.dtsi
index 767803e1fd55..9d87a3ffe998 100644
--- a/arch/arm/boot/dts/tegra30.dtsi
+++ b/arch/arm/boot/dts/tegra30.dtsi
@@ -119,6 +119,7 @@
compatible = "arm,cortex-a9-twd-timer";
reg = <0x50040600 0x20>;
interrupts = <1 13 0xf04>;
+ clocks = <&tegra_car 214>;
};
intc: interrupt-controller {
diff --git a/arch/arm/configs/mxs_defconfig b/arch/arm/configs/mxs_defconfig
index fbbc5bb022d5..6a99e30f81d2 100644
--- a/arch/arm/configs/mxs_defconfig
+++ b/arch/arm/configs/mxs_defconfig
@@ -116,6 +116,7 @@ CONFIG_SND_SOC=y
CONFIG_SND_MXS_SOC=y
CONFIG_SND_SOC_MXS_SGTL5000=y
CONFIG_USB=y
+CONFIG_USB_EHCI_HCD=y
CONFIG_USB_CHIPIDEA=y
CONFIG_USB_CHIPIDEA_HOST=y
CONFIG_USB_STORAGE=y
diff --git a/arch/arm/configs/omap2plus_defconfig b/arch/arm/configs/omap2plus_defconfig
index b16bae2c9a60..bd07864f14a0 100644
--- a/arch/arm/configs/omap2plus_defconfig
+++ b/arch/arm/configs/omap2plus_defconfig
@@ -126,6 +126,8 @@ CONFIG_INPUT_MISC=y
CONFIG_INPUT_TWL4030_PWRBUTTON=y
CONFIG_VT_HW_CONSOLE_BINDING=y
# CONFIG_LEGACY_PTYS is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_8250_NR_UARTS=32
CONFIG_SERIAL_8250_EXTENDED=y
CONFIG_SERIAL_8250_MANY_PORTS=y
diff --git a/arch/arm/include/asm/xen/events.h b/arch/arm/include/asm/xen/events.h
index 5c27696de14f..8b1f37bfeeec 100644
--- a/arch/arm/include/asm/xen/events.h
+++ b/arch/arm/include/asm/xen/events.h
@@ -2,6 +2,7 @@
#define _ASM_ARM_XEN_EVENTS_H
#include <asm/ptrace.h>
+#include <asm/atomic.h>
enum ipi_vector {
XEN_PLACEHOLDER_VECTOR,
@@ -15,26 +16,8 @@ static inline int xen_irqs_disabled(struct pt_regs *regs)
return raw_irqs_disabled_flags(regs->ARM_cpsr);
}
-/*
- * We cannot use xchg because it does not support 8-byte
- * values. However it is safe to use {ldr,dtd}exd directly because all
- * platforms which Xen can run on support those instructions.
- */
-static inline xen_ulong_t xchg_xen_ulong(xen_ulong_t *ptr, xen_ulong_t val)
-{
- xen_ulong_t oldval;
- unsigned int tmp;
-
- wmb();
- asm volatile("@ xchg_xen_ulong\n"
- "1: ldrexd %0, %H0, [%3]\n"
- " strexd %1, %2, %H2, [%3]\n"
- " teq %1, #0\n"
- " bne 1b"
- : "=&r" (oldval), "=&r" (tmp)
- : "r" (val), "r" (ptr)
- : "memory", "cc");
- return oldval;
-}
+#define xchg_xen_ulong(ptr, val) atomic64_xchg(container_of((ptr), \
+ atomic64_t, \
+ counter), (val))
#endif /* _ASM_ARM_XEN_EVENTS_H */
diff --git a/arch/arm/mach-at91/board-foxg20.c b/arch/arm/mach-at91/board-foxg20.c
index 2ea7059b840b..c20a870ea9c9 100644
--- a/arch/arm/mach-at91/board-foxg20.c
+++ b/arch/arm/mach-at91/board-foxg20.c
@@ -176,6 +176,7 @@ static struct w1_gpio_platform_data w1_gpio_pdata = {
/* If you choose to use a pin other than PB16 it needs to be 3.3V */
.pin = AT91_PIN_PB16,
.is_open_drain = 1,
+ .ext_pullup_enable_pin = -EINVAL,
};
static struct platform_device w1_device = {
diff --git a/arch/arm/mach-at91/board-stamp9g20.c b/arch/arm/mach-at91/board-stamp9g20.c
index a033b8df9fb2..869cbecf00b7 100644
--- a/arch/arm/mach-at91/board-stamp9g20.c
+++ b/arch/arm/mach-at91/board-stamp9g20.c
@@ -188,6 +188,7 @@ static struct spi_board_info portuxg20_spi_devices[] = {
static struct w1_gpio_platform_data w1_gpio_pdata = {
.pin = AT91_PIN_PA29,
.is_open_drain = 1,
+ .ext_pullup_enable_pin = -EINVAL,
};
static struct platform_device w1_device = {
diff --git a/arch/arm/mach-imx/clk-busy.c b/arch/arm/mach-imx/clk-busy.c
index 1ab91b5209e6..85b728cc27ab 100644
--- a/arch/arm/mach-imx/clk-busy.c
+++ b/arch/arm/mach-imx/clk-busy.c
@@ -169,7 +169,7 @@ struct clk *imx_clk_busy_mux(const char *name, void __iomem *reg, u8 shift,
busy->mux.reg = reg;
busy->mux.shift = shift;
- busy->mux.width = width;
+ busy->mux.mask = BIT(width) - 1;
busy->mux.lock = &imx_ccm_lock;
busy->mux_ops = &clk_mux_ops;
diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c
index 7b025ee528a5..2f9ff93a4e61 100644
--- a/arch/arm/mach-imx/clk-imx6q.c
+++ b/arch/arm/mach-imx/clk-imx6q.c
@@ -172,7 +172,7 @@ static struct clk *clk[clk_max];
static struct clk_onecell_data clk_data;
static enum mx6q_clks const clks_init_on[] __initconst = {
- mmdc_ch0_axi, rom,
+ mmdc_ch0_axi, rom, pll1_sys,
};
static struct clk_div_table clk_enet_ref_table[] = {
diff --git a/arch/arm/mach-imx/headsmp.S b/arch/arm/mach-imx/headsmp.S
index 921fc1555854..a58c8b0527cc 100644
--- a/arch/arm/mach-imx/headsmp.S
+++ b/arch/arm/mach-imx/headsmp.S
@@ -26,16 +26,16 @@ ENDPROC(v7_secondary_startup)
#ifdef CONFIG_PM
/*
- * The following code is located into the .data section. This is to
- * allow phys_l2x0_saved_regs to be accessed with a relative load
- * as we are running on physical address here.
+ * The following code must assume it is running from physical address
+ * where absolute virtual addresses to the data section have to be
+ * turned into relative ones.
*/
- .data
- .align
#ifdef CONFIG_CACHE_L2X0
.macro pl310_resume
- ldr r2, phys_l2x0_saved_regs
+ adr r0, l2x0_saved_regs_offset
+ ldr r2, [r0]
+ add r2, r2, r0
ldr r0, [r2, #L2X0_R_PHY_BASE] @ get physical base of l2x0
ldr r1, [r2, #L2X0_R_AUX_CTRL] @ get aux_ctrl value
str r1, [r0, #L2X0_AUX_CTRL] @ restore aux_ctrl
@@ -43,9 +43,9 @@ ENDPROC(v7_secondary_startup)
str r1, [r0, #L2X0_CTRL] @ re-enable L2
.endm
- .globl phys_l2x0_saved_regs
-phys_l2x0_saved_regs:
- .long 0
+l2x0_saved_regs_offset:
+ .word l2x0_saved_regs - .
+
#else
.macro pl310_resume
.endm
diff --git a/arch/arm/mach-imx/pm-imx6q.c b/arch/arm/mach-imx/pm-imx6q.c
index ee42d20cba19..5faba7a3c95f 100644
--- a/arch/arm/mach-imx/pm-imx6q.c
+++ b/arch/arm/mach-imx/pm-imx6q.c
@@ -22,8 +22,6 @@
#include "common.h"
#include "hardware.h"
-extern unsigned long phys_l2x0_saved_regs;
-
static int imx6q_suspend_finish(unsigned long val)
{
cpu_do_idle();
@@ -57,18 +55,5 @@ static const struct platform_suspend_ops imx6q_pm_ops = {
void __init imx6q_pm_init(void)
{
- /*
- * The l2x0 core code provides an infrastucture to save and restore
- * l2x0 registers across suspend/resume cycle. But because imx6q
- * retains L2 content during suspend and needs to resume L2 before
- * MMU is enabled, it can only utilize register saving support and
- * have to take care of restoring on its own. So we save physical
- * address of the data structure used by l2x0 core to save registers,
- * and later restore the necessary ones in imx6q resume entry.
- */
-#ifdef CONFIG_CACHE_L2X0
- phys_l2x0_saved_regs = __pa(&l2x0_saved_regs);
-#endif
-
suspend_set_ops(&imx6q_pm_ops);
}
diff --git a/arch/arm/mach-ixp4xx/vulcan-setup.c b/arch/arm/mach-ixp4xx/vulcan-setup.c
index d42730a1d4ab..d599e354ca57 100644
--- a/arch/arm/mach-ixp4xx/vulcan-setup.c
+++ b/arch/arm/mach-ixp4xx/vulcan-setup.c
@@ -163,6 +163,7 @@ static struct platform_device vulcan_max6369 = {
static struct w1_gpio_platform_data vulcan_w1_gpio_pdata = {
.pin = 14,
+ .ext_pullup_enable_pin = -EINVAL,
};
static struct platform_device vulcan_w1_gpio = {
diff --git a/arch/arm/mach-kirkwood/board-dt.c b/arch/arm/mach-kirkwood/board-dt.c
index 2e73e9d53f70..d367aa6b47bb 100644
--- a/arch/arm/mach-kirkwood/board-dt.c
+++ b/arch/arm/mach-kirkwood/board-dt.c
@@ -41,16 +41,12 @@ static void __init kirkwood_legacy_clk_init(void)
struct device_node *np = of_find_compatible_node(
NULL, NULL, "marvell,kirkwood-gating-clock");
-
struct of_phandle_args clkspec;
+ struct clk *clk;
clkspec.np = np;
clkspec.args_count = 1;
- clkspec.args[0] = CGC_BIT_GE0;
- orion_clkdev_add(NULL, "mv643xx_eth_port.0",
- of_clk_get_from_provider(&clkspec));
-
clkspec.args[0] = CGC_BIT_PEX0;
orion_clkdev_add("0", "pcie",
of_clk_get_from_provider(&clkspec));
@@ -59,9 +55,24 @@ static void __init kirkwood_legacy_clk_init(void)
orion_clkdev_add("1", "pcie",
of_clk_get_from_provider(&clkspec));
- clkspec.args[0] = CGC_BIT_GE1;
- orion_clkdev_add(NULL, "mv643xx_eth_port.1",
+ clkspec.args[0] = CGC_BIT_SDIO;
+ orion_clkdev_add(NULL, "mvsdio",
of_clk_get_from_provider(&clkspec));
+
+ /*
+ * The ethernet interfaces forget the MAC address assigned by
+ * u-boot if the clocks are turned off. Until proper DT support
+ * is available we always enable them for now.
+ */
+ clkspec.args[0] = CGC_BIT_GE0;
+ clk = of_clk_get_from_provider(&clkspec);
+ orion_clkdev_add(NULL, "mv643xx_eth_port.0", clk);
+ clk_prepare_enable(clk);
+
+ clkspec.args[0] = CGC_BIT_GE1;
+ clk = of_clk_get_from_provider(&clkspec);
+ orion_clkdev_add(NULL, "mv643xx_eth_port.1", clk);
+ clk_prepare_enable(clk);
}
static void __init kirkwood_of_clk_init(void)
diff --git a/arch/arm/mach-mxs/icoll.c b/arch/arm/mach-mxs/icoll.c
index 8fb23af154b3..e26eeba46598 100644
--- a/arch/arm/mach-mxs/icoll.c
+++ b/arch/arm/mach-mxs/icoll.c
@@ -100,7 +100,7 @@ static struct irq_domain_ops icoll_irq_domain_ops = {
.xlate = irq_domain_xlate_onecell,
};
-void __init icoll_of_init(struct device_node *np,
+static void __init icoll_of_init(struct device_node *np,
struct device_node *interrupt_parent)
{
/*
diff --git a/arch/arm/mach-mxs/mach-mxs.c b/arch/arm/mach-mxs/mach-mxs.c
index 052186713347..3218f1f2c0e0 100644
--- a/arch/arm/mach-mxs/mach-mxs.c
+++ b/arch/arm/mach-mxs/mach-mxs.c
@@ -402,17 +402,17 @@ static void __init cfa10049_init(void)
{
enable_clk_enet_out();
update_fec_mac_prop(OUI_CRYSTALFONTZ);
+
+ mxsfb_pdata.mode_list = cfa10049_video_modes;
+ mxsfb_pdata.mode_count = ARRAY_SIZE(cfa10049_video_modes);
+ mxsfb_pdata.default_bpp = 32;
+ mxsfb_pdata.ld_intf_width = STMLCDIF_18BIT;
}
static void __init cfa10037_init(void)
{
enable_clk_enet_out();
update_fec_mac_prop(OUI_CRYSTALFONTZ);
-
- mxsfb_pdata.mode_list = cfa10049_video_modes;
- mxsfb_pdata.mode_count = ARRAY_SIZE(cfa10049_video_modes);
- mxsfb_pdata.default_bpp = 32;
- mxsfb_pdata.ld_intf_width = STMLCDIF_18BIT;
}
static void __init apf28_init(void)
diff --git a/arch/arm/mach-mxs/mm.c b/arch/arm/mach-mxs/mm.c
index a4294aa9f301..e63b7d87acbd 100644
--- a/arch/arm/mach-mxs/mm.c
+++ b/arch/arm/mach-mxs/mm.c
@@ -18,6 +18,7 @@
#include <mach/mx23.h>
#include <mach/mx28.h>
+#include <mach/common.h>
/*
* Define the MX23 memory map.
diff --git a/arch/arm/mach-mxs/ocotp.c b/arch/arm/mach-mxs/ocotp.c
index 54add60f94c9..1dff46703753 100644
--- a/arch/arm/mach-mxs/ocotp.c
+++ b/arch/arm/mach-mxs/ocotp.c
@@ -19,6 +19,7 @@
#include <asm/processor.h> /* for cpu_relax() */
#include <mach/mxs.h>
+#include <mach/common.h>
#define OCOTP_WORD_OFFSET 0x20
#define OCOTP_WORD_COUNT 0x20
diff --git a/arch/arm/mach-omap1/common.h b/arch/arm/mach-omap1/common.h
index fb18831e88aa..14f7e9920479 100644
--- a/arch/arm/mach-omap1/common.h
+++ b/arch/arm/mach-omap1/common.h
@@ -31,6 +31,8 @@
#include <plat/i2c.h>
+#include <mach/irqs.h>
+
#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
void omap7xx_map_io(void);
#else
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
index 49ac3dfebef9..8111cd9ff3e5 100644
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -311,9 +311,6 @@ config MACH_OMAP_ZOOM2
default y
select OMAP_PACKAGE_CBB
select REGULATOR_FIXED_VOLTAGE if REGULATOR
- select SERIAL_8250
- select SERIAL_8250_CONSOLE
- select SERIAL_CORE_CONSOLE
config MACH_OMAP_ZOOM3
bool "OMAP3630 Zoom3 board"
@@ -321,9 +318,6 @@ config MACH_OMAP_ZOOM3
default y
select OMAP_PACKAGE_CBP
select REGULATOR_FIXED_VOLTAGE if REGULATOR
- select SERIAL_8250
- select SERIAL_8250_CONSOLE
- select SERIAL_CORE_CONSOLE
config MACH_CM_T35
bool "CompuLab CM-T35/CM-T3730 modules"
diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c
index 0274ff7a2a2b..e54a48060198 100644
--- a/arch/arm/mach-omap2/board-generic.c
+++ b/arch/arm/mach-omap2/board-generic.c
@@ -102,6 +102,7 @@ DT_MACHINE_START(OMAP3_DT, "Generic OMAP3 (Flattened Device Tree)")
.init_irq = omap_intc_of_init,
.handle_irq = omap3_intc_handle_irq,
.init_machine = omap_generic_init,
+ .init_late = omap3_init_late,
.init_time = omap3_sync32k_timer_init,
.dt_compat = omap3_boards_compat,
.restart = omap3xxx_restart,
@@ -119,6 +120,7 @@ DT_MACHINE_START(OMAP3_GP_DT, "Generic OMAP3-GP (Flattened Device Tree)")
.init_irq = omap_intc_of_init,
.handle_irq = omap3_intc_handle_irq,
.init_machine = omap_generic_init,
+ .init_late = omap3_init_late,
.init_time = omap3_secure_sync32k_timer_init,
.dt_compat = omap3_gp_boards_compat,
.restart = omap3xxx_restart,
diff --git a/arch/arm/mach-omap2/board-rx51.c b/arch/arm/mach-omap2/board-rx51.c
index f7c4616cbb60..d2ea68ea678a 100644
--- a/arch/arm/mach-omap2/board-rx51.c
+++ b/arch/arm/mach-omap2/board-rx51.c
@@ -17,6 +17,7 @@
#include <linux/io.h>
#include <linux/gpio.h>
#include <linux/leds.h>
+#include <linux/usb/phy.h>
#include <linux/usb/musb.h>
#include <linux/platform_data/spi-omap2-mcspi.h>
@@ -98,6 +99,7 @@ static void __init rx51_init(void)
sdrc_params = nokia_get_sdram_timings();
omap_sdrc_init(sdrc_params, sdrc_params);
+ usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb");
usb_musb_init(&musb_board_data);
rx51_peripherals_init();
diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h
index 0a6b9c7a63da..40f4a03d728f 100644
--- a/arch/arm/mach-omap2/common.h
+++ b/arch/arm/mach-omap2/common.h
@@ -108,7 +108,6 @@ void omap35xx_init_late(void);
void omap3630_init_late(void);
void am35xx_init_late(void);
void ti81xx_init_late(void);
-void omap4430_init_late(void);
int omap2_common_pm_late_init(void);
#if defined(CONFIG_SOC_OMAP2420) || defined(CONFIG_SOC_OMAP2430)
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index e4b16c8efe8b..410e1bac7815 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -1122,9 +1122,6 @@ int gpmc_calc_timings(struct gpmc_timings *gpmc_t,
/* TODO: remove, see function definition */
gpmc_convert_ps_to_ns(gpmc_t);
- /* Now the GPMC is initialised, unreserve the chip-selects */
- gpmc_cs_map = 0;
-
return 0;
}
@@ -1383,6 +1380,9 @@ static int gpmc_probe(struct platform_device *pdev)
if (IS_ERR_VALUE(gpmc_setup_irq()))
dev_warn(gpmc_dev, "gpmc_setup_irq failed\n");
+ /* Now the GPMC is initialised, unreserve the chip-selects */
+ gpmc_cs_map = 0;
+
rc = gpmc_probe_dt(pdev);
if (rc < 0) {
clk_disable_unprepare(gpmc_l3_clk);
diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c
index 6a217c98db54..f82cf878d6af 100644
--- a/arch/arm/mach-omap2/mux.c
+++ b/arch/arm/mach-omap2/mux.c
@@ -211,8 +211,6 @@ static int __init _omap_mux_get_by_name(struct omap_mux_partition *partition,
return -EINVAL;
}
- pr_err("%s: Could not find signal %s\n", __func__, muxname);
-
return -ENODEV;
}
@@ -234,6 +232,8 @@ int __init omap_mux_get_by_name(const char *muxname,
return mux_mode;
}
+ pr_err("%s: Could not find signal %s\n", __func__, muxname);
+
return -ENODEV;
}
@@ -739,8 +739,9 @@ static void __init omap_mux_dbg_create_entry(
list_for_each_entry(e, &partition->muxmodes, node) {
struct omap_mux *m = &e->mux;
- (void)debugfs_create_file(m->muxnames[0], S_IWUSR, mux_dbg_dir,
- m, &omap_mux_dbg_signal_fops);
+ (void)debugfs_create_file(m->muxnames[0], S_IWUSR | S_IRUGO,
+ mux_dbg_dir, m,
+ &omap_mux_dbg_signal_fops);
}
}
diff --git a/arch/arm/mach-pxa/raumfeld.c b/arch/arm/mach-pxa/raumfeld.c
index af41888acbd6..969b0ba7fa70 100644
--- a/arch/arm/mach-pxa/raumfeld.c
+++ b/arch/arm/mach-pxa/raumfeld.c
@@ -505,6 +505,7 @@ static struct w1_gpio_platform_data w1_gpio_platform_data = {
.pin = GPIO_ONE_WIRE,
.is_open_drain = 0,
.enable_external_pullup = w1_enable_external_pullup,
+ .ext_pullup_enable_pin = -EINVAL,
};
struct platform_device raumfeld_w1_gpio_device = {
diff --git a/arch/arm/mach-spear3xx/spear3xx.c b/arch/arm/mach-spear3xx/spear3xx.c
index f9d754f90c59..d2b3937c4014 100644
--- a/arch/arm/mach-spear3xx/spear3xx.c
+++ b/arch/arm/mach-spear3xx/spear3xx.c
@@ -14,7 +14,7 @@
#define pr_fmt(fmt) "SPEAr3xx: " fmt
#include <linux/amba/pl022.h>
-#include <linux/amba/pl08x.h>
+#include <linux/amba/pl080.h>
#include <linux/io.h>
#include <plat/pl080.h>
#include <mach/generic.h>
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index c7e3759f16d3..e9db6b4bf65a 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -342,6 +342,7 @@ static int __init atomic_pool_init(void)
{
struct dma_pool *pool = &atomic_pool;
pgprot_t prot = pgprot_dmacoherent(pgprot_kernel);
+ gfp_t gfp = GFP_KERNEL | GFP_DMA;
unsigned long nr_pages = pool->size >> PAGE_SHIFT;
unsigned long *bitmap;
struct page *page;
@@ -361,8 +362,8 @@ static int __init atomic_pool_init(void)
ptr = __alloc_from_contiguous(NULL, pool->size, prot, &page,
atomic_pool_init);
else
- ptr = __alloc_remap_buffer(NULL, pool->size, GFP_KERNEL, prot,
- &page, atomic_pool_init);
+ ptr = __alloc_remap_buffer(NULL, pool->size, gfp, prot, &page,
+ atomic_pool_init);
if (ptr) {
int i;
diff --git a/arch/arm/plat-orion/addr-map.c b/arch/arm/plat-orion/addr-map.c
index febe3862873c..807ac8e5cbc0 100644
--- a/arch/arm/plat-orion/addr-map.c
+++ b/arch/arm/plat-orion/addr-map.c
@@ -157,9 +157,12 @@ void __init orion_setup_cpu_mbus_target(const struct orion_addr_map_cfg *cfg,
u32 size = readl(ddr_window_cpu_base + DDR_SIZE_CS_OFF(i));
/*
- * Chip select enabled?
+ * We only take care of entries for which the chip
+ * select is enabled, and that don't have high base
+ * address bits set (devices can only access the first
+ * 32 bits of the memory).
*/
- if (size & 1) {
+ if ((size & 1) && !(base & 0xF)) {
struct mbus_dram_window *w;
w = &orion_mbus_dram_info.cs[cs++];
diff --git a/arch/arm/plat-spear/Kconfig b/arch/arm/plat-spear/Kconfig
index 739d016eb273..8a08c31b5e20 100644
--- a/arch/arm/plat-spear/Kconfig
+++ b/arch/arm/plat-spear/Kconfig
@@ -10,7 +10,7 @@ choice
config ARCH_SPEAR13XX
bool "ST SPEAr13xx with Device Tree"
- select ARCH_HAVE_CPUFREQ
+ select ARCH_HAS_CPUFREQ
select ARM_GIC
select CPU_V7
select GPIO_SPEAR_SPICS
diff --git a/arch/avr32/Kconfig b/arch/avr32/Kconfig
index 9b89257b2cfd..c1a868d398bd 100644
--- a/arch/avr32/Kconfig
+++ b/arch/avr32/Kconfig
@@ -7,7 +7,7 @@ config AVR32
select HAVE_OPROFILE
select HAVE_KPROBES
select HAVE_GENERIC_HARDIRQS
- select HAVE_VIRT_TO_BUS
+ select VIRT_TO_BUS
select GENERIC_IRQ_PROBE
select GENERIC_ATOMIC64
select HARDIRQS_SW_RESEND
diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig
index 600494c70e96..c3f2e0bc644a 100644
--- a/arch/blackfin/Kconfig
+++ b/arch/blackfin/Kconfig
@@ -33,7 +33,7 @@ config BLACKFIN
select ARCH_HAVE_CUSTOM_GPIO_H
select ARCH_WANT_OPTIONAL_GPIOLIB
select HAVE_UID16
- select HAVE_VIRT_TO_BUS
+ select VIRT_TO_BUS
select ARCH_WANT_IPC_PARSE_VERSION
select HAVE_GENERIC_HARDIRQS
select GENERIC_ATOMIC64
diff --git a/arch/cris/Kconfig b/arch/cris/Kconfig
index bb0ac66cf533..06dd026533e3 100644
--- a/arch/cris/Kconfig
+++ b/arch/cris/Kconfig
@@ -43,7 +43,7 @@ config CRIS
select GENERIC_ATOMIC64
select HAVE_GENERIC_HARDIRQS
select HAVE_UID16
- select HAVE_VIRT_TO_BUS
+ select VIRT_TO_BUS
select ARCH_WANT_IPC_PARSE_VERSION
select GENERIC_IRQ_SHOW
select GENERIC_IOMAP
diff --git a/arch/frv/Kconfig b/arch/frv/Kconfig
index 12369b194c7b..2ce731f9aa4d 100644
--- a/arch/frv/Kconfig
+++ b/arch/frv/Kconfig
@@ -6,7 +6,7 @@ config FRV
select HAVE_PERF_EVENTS
select HAVE_UID16
select HAVE_GENERIC_HARDIRQS
- select HAVE_VIRT_TO_BUS
+ select VIRT_TO_BUS
select GENERIC_IRQ_SHOW
select HAVE_DEBUG_BUGVERBOSE
select ARCH_HAVE_NMI_SAFE_CMPXCHG
diff --git a/arch/h8300/Kconfig b/arch/h8300/Kconfig
index ae8551eb3736..79250de1b12a 100644
--- a/arch/h8300/Kconfig
+++ b/arch/h8300/Kconfig
@@ -5,7 +5,7 @@ config H8300
select HAVE_GENERIC_HARDIRQS
select GENERIC_ATOMIC64
select HAVE_UID16
- select HAVE_VIRT_TO_BUS
+ select VIRT_TO_BUS
select ARCH_WANT_IPC_PARSE_VERSION
select GENERIC_IRQ_SHOW
select GENERIC_CPU_DEVICES
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
index 33f3fdc0b214..9a02f71c6b1f 100644
--- a/arch/ia64/Kconfig
+++ b/arch/ia64/Kconfig
@@ -26,7 +26,7 @@ config IA64
select HAVE_MEMBLOCK
select HAVE_MEMBLOCK_NODE_MAP
select HAVE_VIRT_CPU_ACCOUNTING
- select HAVE_VIRT_TO_BUS
+ select VIRT_TO_BUS
select ARCH_DISCARD_MEMBLOCK
select GENERIC_IRQ_PROBE
select GENERIC_PENDING_IRQ if SMP
diff --git a/arch/m32r/Kconfig b/arch/m32r/Kconfig
index 92623818a1fe..bcd17b206571 100644
--- a/arch/m32r/Kconfig
+++ b/arch/m32r/Kconfig
@@ -10,7 +10,7 @@ config M32R
select ARCH_WANT_IPC_PARSE_VERSION
select HAVE_DEBUG_BUGVERBOSE
select HAVE_GENERIC_HARDIRQS
- select HAVE_VIRT_TO_BUS
+ select VIRT_TO_BUS
select GENERIC_IRQ_PROBE
select GENERIC_IRQ_SHOW
select GENERIC_ATOMIC64
diff --git a/arch/m32r/include/uapi/asm/stat.h b/arch/m32r/include/uapi/asm/stat.h
index da4518f82d6d..98470fe483b6 100644
--- a/arch/m32r/include/uapi/asm/stat.h
+++ b/arch/m32r/include/uapi/asm/stat.h
@@ -63,10 +63,10 @@ struct stat64 {
long long st_size;
unsigned long st_blksize;
-#if defined(__BIG_ENDIAN)
+#if defined(__BYTE_ORDER) ? __BYTE_ORDER == __BIG_ENDIAN : defined(__BIG_ENDIAN)
unsigned long __pad4; /* future possible st_blocks high bits */
unsigned long st_blocks; /* Number 512-byte blocks allocated. */
-#elif defined(__LITTLE_ENDIAN)
+#elif defined(__BYTE_ORDER) ? __BYTE_ORDER == __LITTLE_ENDIAN : defined(__LITTLE_ENDIAN)
unsigned long st_blocks; /* Number 512-byte blocks allocated. */
unsigned long __pad4; /* future possible st_blocks high bits */
#else
diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
index 0e708c78e01c..6de813370b8c 100644
--- a/arch/m68k/Kconfig
+++ b/arch/m68k/Kconfig
@@ -8,7 +8,7 @@ config M68K
select GENERIC_IRQ_SHOW
select GENERIC_ATOMIC64
select HAVE_UID16
- select HAVE_VIRT_TO_BUS
+ select VIRT_TO_BUS
select ARCH_HAVE_NMI_SAFE_CMPXCHG if RMW_INSNS
select GENERIC_CPU_DEVICES
select GENERIC_STRNCPY_FROM_USER if MMU
diff --git a/arch/m68k/Kconfig.machine b/arch/m68k/Kconfig.machine
index 7cdf6b010381..7240584d3439 100644
--- a/arch/m68k/Kconfig.machine
+++ b/arch/m68k/Kconfig.machine
@@ -310,7 +310,6 @@ config COBRA5282
config SOM5282EM
bool "EMAC.Inc SOM5282EM board support"
depends on M528x
- select EMAC_INC
help
Support for the EMAC.Inc SOM5282EM module.
diff --git a/arch/m68k/include/asm/MC68328.h b/arch/m68k/include/asm/MC68328.h
index a337e56d09bf..4ebf098b8a1f 100644
--- a/arch/m68k/include/asm/MC68328.h
+++ b/arch/m68k/include/asm/MC68328.h
@@ -293,7 +293,7 @@
/*
* Here go the bitmasks themselves
*/
-#define IMR_MSPIM (1 << SPIM _IRQ_NUM) /* Mask SPI Master interrupt */
+#define IMR_MSPIM (1 << SPIM_IRQ_NUM) /* Mask SPI Master interrupt */
#define IMR_MTMR2 (1 << TMR2_IRQ_NUM) /* Mask Timer 2 interrupt */
#define IMR_MUART (1 << UART_IRQ_NUM) /* Mask UART interrupt */
#define IMR_MWDT (1 << WDT_IRQ_NUM) /* Mask Watchdog Timer interrupt */
@@ -327,7 +327,7 @@
#define IWR_ADDR 0xfffff308
#define IWR LONG_REF(IWR_ADDR)
-#define IWR_SPIM (1 << SPIM _IRQ_NUM) /* SPI Master interrupt */
+#define IWR_SPIM (1 << SPIM_IRQ_NUM) /* SPI Master interrupt */
#define IWR_TMR2 (1 << TMR2_IRQ_NUM) /* Timer 2 interrupt */
#define IWR_UART (1 << UART_IRQ_NUM) /* UART interrupt */
#define IWR_WDT (1 << WDT_IRQ_NUM) /* Watchdog Timer interrupt */
@@ -357,7 +357,7 @@
#define ISR_ADDR 0xfffff30c
#define ISR LONG_REF(ISR_ADDR)
-#define ISR_SPIM (1 << SPIM _IRQ_NUM) /* SPI Master interrupt */
+#define ISR_SPIM (1 << SPIM_IRQ_NUM) /* SPI Master interrupt */
#define ISR_TMR2 (1 << TMR2_IRQ_NUM) /* Timer 2 interrupt */
#define ISR_UART (1 << UART_IRQ_NUM) /* UART interrupt */
#define ISR_WDT (1 << WDT_IRQ_NUM) /* Watchdog Timer interrupt */
@@ -391,7 +391,7 @@
#define IPR_ADDR 0xfffff310
#define IPR LONG_REF(IPR_ADDR)
-#define IPR_SPIM (1 << SPIM _IRQ_NUM) /* SPI Master interrupt */
+#define IPR_SPIM (1 << SPIM_IRQ_NUM) /* SPI Master interrupt */
#define IPR_TMR2 (1 << TMR2_IRQ_NUM) /* Timer 2 interrupt */
#define IPR_UART (1 << UART_IRQ_NUM) /* UART interrupt */
#define IPR_WDT (1 << WDT_IRQ_NUM) /* Watchdog Timer interrupt */
@@ -757,7 +757,7 @@
/* 'EZ328-compatible definitions */
#define TCN_ADDR TCN1_ADDR
-#define TCN TCN
+#define TCN TCN1
/*
* Timer Unit 1 and 2 Status Registers
diff --git a/arch/m68k/kernel/setup_no.c b/arch/m68k/kernel/setup_no.c
index 71fb29938dba..911ba472e6c4 100644
--- a/arch/m68k/kernel/setup_no.c
+++ b/arch/m68k/kernel/setup_no.c
@@ -57,6 +57,9 @@ void (*mach_reset)(void);
void (*mach_halt)(void);
void (*mach_power_off)(void);
+#ifdef CONFIG_M68000
+#define CPU_NAME "MC68000"
+#endif
#ifdef CONFIG_M68328
#define CPU_NAME "MC68328"
#endif
diff --git a/arch/m68k/mm/init.c b/arch/m68k/mm/init.c
index afd8106fd83b..519aad8fa812 100644
--- a/arch/m68k/mm/init.c
+++ b/arch/m68k/mm/init.c
@@ -188,7 +188,7 @@ void __init mem_init(void)
}
}
-#if !defined(CONFIG_SUN3) && !defined(CONFIG_COLDFIRE)
+#if defined(CONFIG_MMU) && !defined(CONFIG_SUN3) && !defined(CONFIG_COLDFIRE)
/* insert pointer tables allocated so far into the tablelist */
init_pointer_table((unsigned long)kernel_pg_dir);
for (i = 0; i < PTRS_PER_PGD; i++) {
diff --git a/arch/m68k/platform/coldfire/m528x.c b/arch/m68k/platform/coldfire/m528x.c
index 83b7dad7a84e..b03a9d271837 100644
--- a/arch/m68k/platform/coldfire/m528x.c
+++ b/arch/m68k/platform/coldfire/m528x.c
@@ -69,7 +69,7 @@ static void __init m528x_uarts_init(void)
u8 port;
/* make sure PUAPAR is set for UART0 and UART1 */
- port = readb(MCF5282_GPIO_PUAPAR);
+ port = readb(MCFGPIO_PUAPAR);
port |= 0x03 | (0x03 << 2);
writeb(port, MCFGPIO_PUAPAR);
}
diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig
index 7843d11156e6..1323fa2530eb 100644
--- a/arch/microblaze/Kconfig
+++ b/arch/microblaze/Kconfig
@@ -19,7 +19,7 @@ config MICROBLAZE
select HAVE_DEBUG_KMEMLEAK
select IRQ_DOMAIN
select HAVE_GENERIC_HARDIRQS
- select HAVE_VIRT_TO_BUS
+ select VIRT_TO_BUS
select GENERIC_IRQ_PROBE
select GENERIC_IRQ_SHOW
select GENERIC_PCI_IOMAP
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index ae9c716c46bb..cd2e21ff562a 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -38,7 +38,7 @@ config MIPS
select GENERIC_CLOCKEVENTS
select GENERIC_CMOS_UPDATE
select HAVE_MOD_ARCH_SPECIFIC
- select HAVE_VIRT_TO_BUS
+ select VIRT_TO_BUS
select MODULES_USE_ELF_REL if MODULES
select MODULES_USE_ELF_RELA if MODULES && 64BIT
select CLONE_BACKWARDS
diff --git a/arch/mn10300/Kconfig b/arch/mn10300/Kconfig
index b06c7360b1c6..428da175d073 100644
--- a/arch/mn10300/Kconfig
+++ b/arch/mn10300/Kconfig
@@ -8,7 +8,7 @@ config MN10300
select HAVE_ARCH_KGDB
select GENERIC_ATOMIC64
select HAVE_NMI_WATCHDOG if MN10300_WD_TIMER
- select HAVE_VIRT_TO_BUS
+ select VIRT_TO_BUS
select GENERIC_CLOCKEVENTS
select MODULES_USE_ELF_RELA
select OLD_SIGSUSPEND3
diff --git a/arch/openrisc/Kconfig b/arch/openrisc/Kconfig
index 014a6482ed4c..9ab3bf2eca8d 100644
--- a/arch/openrisc/Kconfig
+++ b/arch/openrisc/Kconfig
@@ -9,10 +9,9 @@ config OPENRISC
select OF_EARLY_FLATTREE
select IRQ_DOMAIN
select HAVE_MEMBLOCK
- select ARCH_WANT_OPTIONAL_GPIOLIB
+ select ARCH_REQUIRE_GPIOLIB
select HAVE_ARCH_TRACEHOOK
select HAVE_GENERIC_HARDIRQS
- select HAVE_VIRT_TO_BUS
select GENERIC_IRQ_CHIP
select GENERIC_IRQ_PROBE
select GENERIC_IRQ_SHOW
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
index a9ff712a2864..0339181bf3ac 100644
--- a/arch/parisc/Kconfig
+++ b/arch/parisc/Kconfig
@@ -21,7 +21,7 @@ config PARISC
select GENERIC_STRNCPY_FROM_USER
select SYSCTL_ARCH_UNALIGN_ALLOW
select HAVE_MOD_ARCH_SPECIFIC
- select HAVE_VIRT_TO_BUS
+ select VIRT_TO_BUS
select MODULES_USE_ELF_RELA
select CLONE_BACKWARDS
select TTY # Needed for pdc_cons.c
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index b89d7eb730a2..80821512e9cc 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -98,7 +98,7 @@ config PPC
select HAVE_FUNCTION_GRAPH_TRACER
select SYSCTL_EXCEPTION_TRACE
select ARCH_WANT_OPTIONAL_GPIOLIB
- select HAVE_VIRT_TO_BUS if !PPC64
+ select VIRT_TO_BUS if !PPC64
select HAVE_IDE
select HAVE_IOREMAP_PROT
select HAVE_EFFICIENT_UNALIGNED_ACCESS
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index 4b505370a1d5..eb8fb629f00b 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -134,7 +134,7 @@ config S390
select HAVE_SYSCALL_WRAPPERS
select HAVE_UID16 if 32BIT
select HAVE_VIRT_CPU_ACCOUNTING
- select HAVE_VIRT_TO_BUS
+ select VIRT_TO_BUS
select INIT_ALL_POSSIBLE
select KTIME_SCALAR if 32BIT
select MODULES_USE_ELF_RELA
diff --git a/arch/s390/include/asm/cpu_mf.h b/arch/s390/include/asm/cpu_mf.h
index f1eddd150dd7..c879fad404c8 100644
--- a/arch/s390/include/asm/cpu_mf.h
+++ b/arch/s390/include/asm/cpu_mf.h
@@ -12,6 +12,7 @@
#ifndef _ASM_S390_CPU_MF_H
#define _ASM_S390_CPU_MF_H
+#include <linux/errno.h>
#include <asm/facility.h>
#define CPU_MF_INT_SF_IAE (1 << 31) /* invalid entry address */
diff --git a/arch/score/Kconfig b/arch/score/Kconfig
index e569aa1fd2ba..c8def8bc9020 100644
--- a/arch/score/Kconfig
+++ b/arch/score/Kconfig
@@ -12,7 +12,7 @@ config SCORE
select GENERIC_CPU_DEVICES
select GENERIC_CLOCKEVENTS
select HAVE_MOD_ARCH_SPECIFIC
- select HAVE_VIRT_TO_BUS
+ select VIRT_TO_BUS
select MODULES_USE_ELF_REL
select CLONE_BACKWARDS
diff --git a/arch/tile/Kconfig b/arch/tile/Kconfig
index ff496ab1e794..25877aebc685 100644
--- a/arch/tile/Kconfig
+++ b/arch/tile/Kconfig
@@ -17,7 +17,7 @@ config TILE
select GENERIC_IRQ_SHOW
select HAVE_DEBUG_BUGVERBOSE
select HAVE_SYSCALL_WRAPPERS if TILEGX
- select HAVE_VIRT_TO_BUS
+ select VIRT_TO_BUS
select SYS_HYPERVISOR
select ARCH_HAVE_NMI_SAFE_CMPXCHG
select GENERIC_CLOCKEVENTS
diff --git a/arch/um/drivers/chan.h b/arch/um/drivers/chan.h
index 78f1b8999964..c512b0306dd4 100644
--- a/arch/um/drivers/chan.h
+++ b/arch/um/drivers/chan.h
@@ -37,7 +37,7 @@ extern int console_write_chan(struct chan *chan, const char *buf,
extern int console_open_chan(struct line *line, struct console *co);
extern void deactivate_chan(struct chan *chan, int irq);
extern void reactivate_chan(struct chan *chan, int irq);
-extern void chan_enable_winch(struct chan *chan, struct tty_struct *tty);
+extern void chan_enable_winch(struct chan *chan, struct tty_port *port);
extern int enable_chan(struct line *line);
extern void close_chan(struct line *line);
extern int chan_window_size(struct line *line,
diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c
index 15c553c239a1..80b47cb71e0a 100644
--- a/arch/um/drivers/chan_kern.c
+++ b/arch/um/drivers/chan_kern.c
@@ -122,10 +122,10 @@ static int open_chan(struct list_head *chans)
return err;
}
-void chan_enable_winch(struct chan *chan, struct tty_struct *tty)
+void chan_enable_winch(struct chan *chan, struct tty_port *port)
{
if (chan && chan->primary && chan->ops->winch)
- register_winch(chan->fd, tty);
+ register_winch(chan->fd, port);
}
static void line_timer_cb(struct work_struct *work)
diff --git a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c
index 9be670ad23b5..3fd7c3efdb18 100644
--- a/arch/um/drivers/chan_user.c
+++ b/arch/um/drivers/chan_user.c
@@ -216,7 +216,7 @@ static int winch_thread(void *arg)
}
}
-static int winch_tramp(int fd, struct tty_struct *tty, int *fd_out,
+static int winch_tramp(int fd, struct tty_port *port, int *fd_out,
unsigned long *stack_out)
{
struct winch_data data;
@@ -271,7 +271,7 @@ static int winch_tramp(int fd, struct tty_struct *tty, int *fd_out,
return err;
}
-void register_winch(int fd, struct tty_struct *tty)
+void register_winch(int fd, struct tty_port *port)
{
unsigned long stack;
int pid, thread, count, thread_fd = -1;
@@ -281,17 +281,17 @@ void register_winch(int fd, struct tty_struct *tty)
return;
pid = tcgetpgrp(fd);
- if (is_skas_winch(pid, fd, tty)) {
- register_winch_irq(-1, fd, -1, tty, 0);
+ if (is_skas_winch(pid, fd, port)) {
+ register_winch_irq(-1, fd, -1, port, 0);
return;
}
if (pid == -1) {
- thread = winch_tramp(fd, tty, &thread_fd, &stack);
+ thread = winch_tramp(fd, port, &thread_fd, &stack);
if (thread < 0)
return;
- register_winch_irq(thread_fd, fd, thread, tty, stack);
+ register_winch_irq(thread_fd, fd, thread, port, stack);
count = write(thread_fd, &c, sizeof(c));
if (count != sizeof(c))
diff --git a/arch/um/drivers/chan_user.h b/arch/um/drivers/chan_user.h
index dc693298eb8f..03f1b565c5f9 100644
--- a/arch/um/drivers/chan_user.h
+++ b/arch/um/drivers/chan_user.h
@@ -38,10 +38,10 @@ extern int generic_window_size(int fd, void *unused, unsigned short *rows_out,
unsigned short *cols_out);
extern void generic_free(void *data);
-struct tty_struct;
-extern void register_winch(int fd, struct tty_struct *tty);
+struct tty_port;
+extern void register_winch(int fd, struct tty_port *port);
extern void register_winch_irq(int fd, int tty_fd, int pid,
- struct tty_struct *tty, unsigned long stack);
+ struct tty_port *port, unsigned long stack);
#define __channel_help(fn, prefix) \
__uml_help(fn, prefix "[0-9]*=<channel description>\n" \
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c
index f1b38571f94e..be541cf69fd2 100644
--- a/arch/um/drivers/line.c
+++ b/arch/um/drivers/line.c
@@ -305,7 +305,7 @@ static int line_activate(struct tty_port *port, struct tty_struct *tty)
return ret;
if (!line->sigio) {
- chan_enable_winch(line->chan_out, tty);
+ chan_enable_winch(line->chan_out, port);
line->sigio = 1;
}
@@ -315,8 +315,22 @@ static int line_activate(struct tty_port *port, struct tty_struct *tty)
return 0;
}
+static void unregister_winch(struct tty_struct *tty);
+
+static void line_destruct(struct tty_port *port)
+{
+ struct tty_struct *tty = tty_port_tty_get(port);
+ struct line *line = tty->driver_data;
+
+ if (line->sigio) {
+ unregister_winch(tty);
+ line->sigio = 0;
+ }
+}
+
static const struct tty_port_operations line_port_ops = {
.activate = line_activate,
+ .destruct = line_destruct,
};
int line_open(struct tty_struct *tty, struct file *filp)
@@ -340,18 +354,6 @@ int line_install(struct tty_driver *driver, struct tty_struct *tty,
return 0;
}
-static void unregister_winch(struct tty_struct *tty);
-
-void line_cleanup(struct tty_struct *tty)
-{
- struct line *line = tty->driver_data;
-
- if (line->sigio) {
- unregister_winch(tty);
- line->sigio = 0;
- }
-}
-
void line_close(struct tty_struct *tty, struct file * filp)
{
struct line *line = tty->driver_data;
@@ -601,7 +603,7 @@ struct winch {
int fd;
int tty_fd;
int pid;
- struct tty_struct *tty;
+ struct tty_port *port;
unsigned long stack;
struct work_struct work;
};
@@ -655,7 +657,7 @@ static irqreturn_t winch_interrupt(int irq, void *data)
goto out;
}
}
- tty = winch->tty;
+ tty = tty_port_tty_get(winch->port);
if (tty != NULL) {
line = tty->driver_data;
if (line != NULL) {
@@ -663,6 +665,7 @@ static irqreturn_t winch_interrupt(int irq, void *data)
&tty->winsize.ws_col);
kill_pgrp(tty->pgrp, SIGWINCH, 1);
}
+ tty_kref_put(tty);
}
out:
if (winch->fd != -1)
@@ -670,7 +673,7 @@ static irqreturn_t winch_interrupt(int irq, void *data)
return IRQ_HANDLED;
}
-void register_winch_irq(int fd, int tty_fd, int pid, struct tty_struct *tty,
+void register_winch_irq(int fd, int tty_fd, int pid, struct tty_port *port,
unsigned long stack)
{
struct winch *winch;
@@ -685,7 +688,7 @@ void register_winch_irq(int fd, int tty_fd, int pid, struct tty_struct *tty,
.fd = fd,
.tty_fd = tty_fd,
.pid = pid,
- .tty = tty,
+ .port = port,
.stack = stack });
if (um_request_irq(WINCH_IRQ, fd, IRQ_READ, winch_interrupt,
@@ -714,15 +717,18 @@ static void unregister_winch(struct tty_struct *tty)
{
struct list_head *ele, *next;
struct winch *winch;
+ struct tty_struct *wtty;
spin_lock(&winch_handler_lock);
list_for_each_safe(ele, next, &winch_handlers) {
winch = list_entry(ele, struct winch, list);
- if (winch->tty == tty) {
+ wtty = tty_port_tty_get(winch->port);
+ if (wtty == tty) {
free_winch(winch);
break;
}
+ tty_kref_put(wtty);
}
spin_unlock(&winch_handler_lock);
}
diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c
index d8926c303629..39f186252e02 100644
--- a/arch/um/drivers/net_kern.c
+++ b/arch/um/drivers/net_kern.c
@@ -218,6 +218,7 @@ static int uml_net_start_xmit(struct sk_buff *skb, struct net_device *dev)
spin_lock_irqsave(&lp->lock, flags);
len = (*lp->write)(lp->fd, skb, lp);
+ skb_tx_timestamp(skb);
if (len == skb->len) {
dev->stats.tx_packets++;
@@ -281,6 +282,7 @@ static void uml_net_get_drvinfo(struct net_device *dev,
static const struct ethtool_ops uml_net_ethtool_ops = {
.get_drvinfo = uml_net_get_drvinfo,
.get_link = ethtool_op_get_link,
+ .get_ts_info = ethtool_op_get_ts_info,
};
static void uml_net_user_timer_expire(unsigned long _conn)
diff --git a/arch/um/drivers/ssl.c b/arch/um/drivers/ssl.c
index 16fdd0a0f9d6..b8d14fa52059 100644
--- a/arch/um/drivers/ssl.c
+++ b/arch/um/drivers/ssl.c
@@ -105,7 +105,6 @@ static const struct tty_operations ssl_ops = {
.throttle = line_throttle,
.unthrottle = line_unthrottle,
.install = ssl_install,
- .cleanup = line_cleanup,
.hangup = line_hangup,
};
diff --git a/arch/um/drivers/stdio_console.c b/arch/um/drivers/stdio_console.c
index 827777af3f6d..7b361f36ca96 100644
--- a/arch/um/drivers/stdio_console.c
+++ b/arch/um/drivers/stdio_console.c
@@ -110,7 +110,6 @@ static const struct tty_operations console_ops = {
.set_termios = line_set_termios,
.throttle = line_throttle,
.unthrottle = line_unthrottle,
- .cleanup = line_cleanup,
.hangup = line_hangup,
};
diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c
index b1469fe93295..9d9f1b4bf826 100644
--- a/arch/um/os-Linux/signal.c
+++ b/arch/um/os-Linux/signal.c
@@ -15,7 +15,7 @@
#include <sysdep/mcontext.h>
#include "internal.h"
-void (*sig_info[NSIG])(int, siginfo_t *, struct uml_pt_regs *) = {
+void (*sig_info[NSIG])(int, struct siginfo *, struct uml_pt_regs *) = {
[SIGTRAP] = relay_signal,
[SIGFPE] = relay_signal,
[SIGILL] = relay_signal,
diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c
index da4b9e9999fd..337518c5042a 100644
--- a/arch/um/os-Linux/start_up.c
+++ b/arch/um/os-Linux/start_up.c
@@ -15,6 +15,8 @@
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/wait.h>
+#include <sys/time.h>
+#include <sys/resource.h>
#include <asm/unistd.h>
#include <init.h>
#include <os.h>
diff --git a/arch/unicore32/Kconfig b/arch/unicore32/Kconfig
index dc50b157fc83..2943e3acdf0c 100644
--- a/arch/unicore32/Kconfig
+++ b/arch/unicore32/Kconfig
@@ -9,7 +9,7 @@ config UNICORE32
select GENERIC_ATOMIC64
select HAVE_KERNEL_LZO
select HAVE_KERNEL_LZMA
- select HAVE_VIRT_TO_BUS
+ select VIRT_TO_BUS
select ARCH_HAVE_CUSTOM_GPIO_H
select GENERIC_FIND_FIRST_BIT
select GENERIC_IRQ_PROBE
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index a4f24f5b1218..70c0f3da0476 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -112,7 +112,7 @@ config X86
select GENERIC_STRNLEN_USER
select HAVE_CONTEXT_TRACKING if X86_64
select HAVE_IRQ_TIME_ACCOUNTING
- select HAVE_VIRT_TO_BUS
+ select VIRT_TO_BUS
select MODULES_USE_ELF_REL if X86_32
select MODULES_USE_ELF_RELA if X86_64
select CLONE_BACKWARDS if X86_32
diff --git a/arch/x86/kernel/cpu/perf_event_intel_ds.c b/arch/x86/kernel/cpu/perf_event_intel_ds.c
index 826054a4f2ee..b05a575d56f4 100644
--- a/arch/x86/kernel/cpu/perf_event_intel_ds.c
+++ b/arch/x86/kernel/cpu/perf_event_intel_ds.c
@@ -729,3 +729,13 @@ void intel_ds_init(void)
}
}
}
+
+void perf_restore_debug_store(void)
+{
+ struct debug_store *ds = __this_cpu_read(cpu_hw_events.ds);
+
+ if (!x86_pmu.bts && !x86_pmu.pebs)
+ return;
+
+ wrmsrl(MSR_IA32_DS_AREA, (unsigned long)ds);
+}
diff --git a/arch/x86/power/cpu.c b/arch/x86/power/cpu.c
index 120cee1c3f8d..3c68768d7a75 100644
--- a/arch/x86/power/cpu.c
+++ b/arch/x86/power/cpu.c
@@ -11,6 +11,7 @@
#include <linux/suspend.h>
#include <linux/export.h>
#include <linux/smp.h>
+#include <linux/perf_event.h>
#include <asm/pgtable.h>
#include <asm/proto.h>
@@ -228,6 +229,7 @@ static void __restore_processor_state(struct saved_context *ctxt)
do_fpu_end();
x86_platform.restore_sched_clock_state();
mtrr_bp_restore();
+ perf_restore_debug_store();
}
/* Needed by apm.c */
diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig
index 35876ffac11d..b09de49dbec5 100644
--- a/arch/xtensa/Kconfig
+++ b/arch/xtensa/Kconfig
@@ -9,7 +9,7 @@ config XTENSA
select HAVE_IDE
select GENERIC_ATOMIC64
select HAVE_GENERIC_HARDIRQS
- select HAVE_VIRT_TO_BUS
+ select VIRT_TO_BUS
select GENERIC_IRQ_SHOW
select GENERIC_CPU_DEVICES
select MODULES_USE_ELF_RELA
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c
index 53e7ac9403a7..e854582f29a6 100644
--- a/drivers/acpi/processor_perflib.c
+++ b/drivers/acpi/processor_perflib.c
@@ -465,7 +465,7 @@ static int acpi_processor_get_performance_states(struct acpi_processor *pr)
return result;
}
-static int acpi_processor_get_performance_info(struct acpi_processor *pr)
+int acpi_processor_get_performance_info(struct acpi_processor *pr)
{
int result = 0;
acpi_status status = AE_OK;
@@ -509,7 +509,7 @@ static int acpi_processor_get_performance_info(struct acpi_processor *pr)
#endif
return result;
}
-
+EXPORT_SYMBOL_GPL(acpi_processor_get_performance_info);
int acpi_processor_notify_smm(struct module *calling_module)
{
acpi_status status;
diff --git a/drivers/char/hw_random/virtio-rng.c b/drivers/char/hw_random/virtio-rng.c
index 10fd71ccf587..6bf4d47324eb 100644
--- a/drivers/char/hw_random/virtio-rng.c
+++ b/drivers/char/hw_random/virtio-rng.c
@@ -92,14 +92,22 @@ static int probe_common(struct virtio_device *vdev)
{
int err;
+ if (vq) {
+ /* We only support one device for now */
+ return -EBUSY;
+ }
/* We expect a single virtqueue. */
vq = virtio_find_single_vq(vdev, random_recv_done, "input");
- if (IS_ERR(vq))
- return PTR_ERR(vq);
+ if (IS_ERR(vq)) {
+ err = PTR_ERR(vq);
+ vq = NULL;
+ return err;
+ }
err = hwrng_register(&virtio_hwrng);
if (err) {
vdev->config->del_vqs(vdev);
+ vq = NULL;
return err;
}
@@ -112,6 +120,7 @@ static void remove_common(struct virtio_device *vdev)
busy = false;
hwrng_unregister(&virtio_hwrng);
vdev->config->del_vqs(vdev);
+ vq = NULL;
}
static int virtrng_probe(struct virtio_device *vdev)
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index a47e6ee98b8c..a64caefdba12 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -63,6 +63,14 @@ config CLK_TWL6040
McPDM. McPDM module is using the external bit clock on the McPDM bus
as functional clock.
+config COMMON_CLK_AXI_CLKGEN
+ tristate "AXI clkgen driver"
+ depends on ARCH_ZYNQ || MICROBLAZE
+ help
+ ---help---
+ Support for the Analog Devices axi-clkgen pcore clock generator for Xilinx
+ FPGAs. It is commonly used in Analog Devices' reference designs.
+
endmenu
source "drivers/clk/mvebu/Kconfig"
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 300d4775d926..79e98e416724 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -7,6 +7,7 @@ obj-$(CONFIG_COMMON_CLK) += clk-fixed-factor.o
obj-$(CONFIG_COMMON_CLK) += clk-fixed-rate.o
obj-$(CONFIG_COMMON_CLK) += clk-gate.o
obj-$(CONFIG_COMMON_CLK) += clk-mux.o
+obj-$(CONFIG_COMMON_CLK) += clk-composite.o
# SoCs specific
obj-$(CONFIG_ARCH_BCM2835) += clk-bcm2835.o
@@ -23,6 +24,7 @@ ifeq ($(CONFIG_COMMON_CLK), y)
obj-$(CONFIG_ARCH_MMP) += mmp/
endif
obj-$(CONFIG_MACH_LOONGSON1) += clk-ls1x.o
+obj-$(CONFIG_ARCH_SUNXI) += sunxi/
obj-$(CONFIG_ARCH_U8500) += ux500/
obj-$(CONFIG_ARCH_VT8500) += clk-vt8500.o
obj-$(CONFIG_ARCH_ZYNQ) += clk-zynq.o
@@ -31,6 +33,7 @@ obj-$(CONFIG_ARCH_TEGRA) += tegra/
obj-$(CONFIG_X86) += x86/
# Chip specific
+obj-$(CONFIG_COMMON_CLK_AXI_CLKGEN) += clk-axi-clkgen.o
obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o
obj-$(CONFIG_COMMON_CLK_MAX77686) += clk-max77686.o
obj-$(CONFIG_CLK_TWL6040) += clk-twl6040.o
diff --git a/drivers/clk/clk-axi-clkgen.c b/drivers/clk/clk-axi-clkgen.c
new file mode 100644
index 000000000000..8137327847c3
--- /dev/null
+++ b/drivers/clk/clk-axi-clkgen.c
@@ -0,0 +1,331 @@
+/*
+ * AXI clkgen driver
+ *
+ * Copyright 2012-2013 Analog Devices Inc.
+ * Author: Lars-Peter Clausen <lars@metafoo.de>
+ *
+ * Licensed under the GPL-2.
+ *
+ */
+
+#include <linux/platform_device.h>
+#include <linux/clk-provider.h>
+#include <linux/clk.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/module.h>
+#include <linux/err.h>
+
+#define AXI_CLKGEN_REG_UPDATE_ENABLE 0x04
+#define AXI_CLKGEN_REG_CLK_OUT1 0x08
+#define AXI_CLKGEN_REG_CLK_OUT2 0x0c
+#define AXI_CLKGEN_REG_CLK_DIV 0x10
+#define AXI_CLKGEN_REG_CLK_FB1 0x14
+#define AXI_CLKGEN_REG_CLK_FB2 0x18
+#define AXI_CLKGEN_REG_LOCK1 0x1c
+#define AXI_CLKGEN_REG_LOCK2 0x20
+#define AXI_CLKGEN_REG_LOCK3 0x24
+#define AXI_CLKGEN_REG_FILTER1 0x28
+#define AXI_CLKGEN_REG_FILTER2 0x2c
+
+struct axi_clkgen {
+ void __iomem *base;
+ struct clk_hw clk_hw;
+};
+
+static uint32_t axi_clkgen_lookup_filter(unsigned int m)
+{
+ switch (m) {
+ case 0:
+ return 0x01001990;
+ case 1:
+ return 0x01001190;
+ case 2:
+ return 0x01009890;
+ case 3:
+ return 0x01001890;
+ case 4:
+ return 0x01008890;
+ case 5 ... 8:
+ return 0x01009090;
+ case 9 ... 11:
+ return 0x01000890;
+ case 12:
+ return 0x08009090;
+ case 13 ... 22:
+ return 0x01001090;
+ case 23 ... 36:
+ return 0x01008090;
+ case 37 ... 46:
+ return 0x08001090;
+ default:
+ return 0x08008090;
+ }
+}
+
+static const uint32_t axi_clkgen_lock_table[] = {
+ 0x060603e8, 0x060603e8, 0x080803e8, 0x0b0b03e8,
+ 0x0e0e03e8, 0x111103e8, 0x131303e8, 0x161603e8,
+ 0x191903e8, 0x1c1c03e8, 0x1f1f0384, 0x1f1f0339,
+ 0x1f1f02ee, 0x1f1f02bc, 0x1f1f028a, 0x1f1f0271,
+ 0x1f1f023f, 0x1f1f0226, 0x1f1f020d, 0x1f1f01f4,
+ 0x1f1f01db, 0x1f1f01c2, 0x1f1f01a9, 0x1f1f0190,
+ 0x1f1f0190, 0x1f1f0177, 0x1f1f015e, 0x1f1f015e,
+ 0x1f1f0145, 0x1f1f0145, 0x1f1f012c, 0x1f1f012c,
+ 0x1f1f012c, 0x1f1f0113, 0x1f1f0113, 0x1f1f0113,
+};
+
+static uint32_t axi_clkgen_lookup_lock(unsigned int m)
+{
+ if (m < ARRAY_SIZE(axi_clkgen_lock_table))
+ return axi_clkgen_lock_table[m];
+ return 0x1f1f00fa;
+}
+
+static const unsigned int fpfd_min = 10000;
+static const unsigned int fpfd_max = 300000;
+static const unsigned int fvco_min = 600000;
+static const unsigned int fvco_max = 1200000;
+
+static void axi_clkgen_calc_params(unsigned long fin, unsigned long fout,
+ unsigned int *best_d, unsigned int *best_m, unsigned int *best_dout)
+{
+ unsigned long d, d_min, d_max, _d_min, _d_max;
+ unsigned long m, m_min, m_max;
+ unsigned long f, dout, best_f, fvco;
+
+ fin /= 1000;
+ fout /= 1000;
+
+ best_f = ULONG_MAX;
+ *best_d = 0;
+ *best_m = 0;
+ *best_dout = 0;
+
+ d_min = max_t(unsigned long, DIV_ROUND_UP(fin, fpfd_max), 1);
+ d_max = min_t(unsigned long, fin / fpfd_min, 80);
+
+ m_min = max_t(unsigned long, DIV_ROUND_UP(fvco_min, fin) * d_min, 1);
+ m_max = min_t(unsigned long, fvco_max * d_max / fin, 64);
+
+ for (m = m_min; m <= m_max; m++) {
+ _d_min = max(d_min, DIV_ROUND_UP(fin * m, fvco_max));
+ _d_max = min(d_max, fin * m / fvco_min);
+
+ for (d = _d_min; d <= _d_max; d++) {
+ fvco = fin * m / d;
+
+ dout = DIV_ROUND_CLOSEST(fvco, fout);
+ dout = clamp_t(unsigned long, dout, 1, 128);
+ f = fvco / dout;
+ if (abs(f - fout) < abs(best_f - fout)) {
+ best_f = f;
+ *best_d = d;
+ *best_m = m;
+ *best_dout = dout;
+ if (best_f == fout)
+ return;
+ }
+ }
+ }
+}
+
+static void axi_clkgen_calc_clk_params(unsigned int divider, unsigned int *low,
+ unsigned int *high, unsigned int *edge, unsigned int *nocount)
+{
+ if (divider == 1)
+ *nocount = 1;
+ else
+ *nocount = 0;
+
+ *high = divider / 2;
+ *edge = divider % 2;
+ *low = divider - *high;
+}
+
+static void axi_clkgen_write(struct axi_clkgen *axi_clkgen,
+ unsigned int reg, unsigned int val)
+{
+ writel(val, axi_clkgen->base + reg);
+}
+
+static void axi_clkgen_read(struct axi_clkgen *axi_clkgen,
+ unsigned int reg, unsigned int *val)
+{
+ *val = readl(axi_clkgen->base + reg);
+}
+
+static struct axi_clkgen *clk_hw_to_axi_clkgen(struct clk_hw *clk_hw)
+{
+ return container_of(clk_hw, struct axi_clkgen, clk_hw);
+}
+
+static int axi_clkgen_set_rate(struct clk_hw *clk_hw,
+ unsigned long rate, unsigned long parent_rate)
+{
+ struct axi_clkgen *axi_clkgen = clk_hw_to_axi_clkgen(clk_hw);
+ unsigned int d, m, dout;
+ unsigned int nocount;
+ unsigned int high;
+ unsigned int edge;
+ unsigned int low;
+ uint32_t filter;
+ uint32_t lock;
+
+ if (parent_rate == 0 || rate == 0)
+ return -EINVAL;
+
+ axi_clkgen_calc_params(parent_rate, rate, &d, &m, &dout);
+
+ if (d == 0 || dout == 0 || m == 0)
+ return -EINVAL;
+
+ filter = axi_clkgen_lookup_filter(m - 1);
+ lock = axi_clkgen_lookup_lock(m - 1);
+
+ axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_UPDATE_ENABLE, 0);
+
+ axi_clkgen_calc_clk_params(dout, &low, &high, &edge, &nocount);
+ axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_CLK_OUT1,
+ (high << 6) | low);
+ axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_CLK_OUT2,
+ (edge << 7) | (nocount << 6));
+
+ axi_clkgen_calc_clk_params(d, &low, &high, &edge, &nocount);
+ axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_CLK_DIV,
+ (edge << 13) | (nocount << 12) | (high << 6) | low);
+
+ axi_clkgen_calc_clk_params(m, &low, &high, &edge, &nocount);
+ axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_CLK_FB1,
+ (high << 6) | low);
+ axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_CLK_FB2,
+ (edge << 7) | (nocount << 6));
+
+ axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_LOCK1, lock & 0x3ff);
+ axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_LOCK2,
+ (((lock >> 16) & 0x1f) << 10) | 0x1);
+ axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_LOCK3,
+ (((lock >> 24) & 0x1f) << 10) | 0x3e9);
+ axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_FILTER1, filter >> 16);
+ axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_FILTER2, filter);
+
+ axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_UPDATE_ENABLE, 1);
+
+ return 0;
+}
+
+static long axi_clkgen_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *parent_rate)
+{
+ unsigned int d, m, dout;
+
+ axi_clkgen_calc_params(*parent_rate, rate, &d, &m, &dout);
+
+ if (d == 0 || dout == 0 || m == 0)
+ return -EINVAL;
+
+ return *parent_rate / d * m / dout;
+}
+
+static unsigned long axi_clkgen_recalc_rate(struct clk_hw *clk_hw,
+ unsigned long parent_rate)
+{
+ struct axi_clkgen *axi_clkgen = clk_hw_to_axi_clkgen(clk_hw);
+ unsigned int d, m, dout;
+ unsigned int reg;
+ unsigned long long tmp;
+
+ axi_clkgen_read(axi_clkgen, AXI_CLKGEN_REG_CLK_OUT1, &reg);
+ dout = (reg & 0x3f) + ((reg >> 6) & 0x3f);
+ axi_clkgen_read(axi_clkgen, AXI_CLKGEN_REG_CLK_DIV, &reg);
+ d = (reg & 0x3f) + ((reg >> 6) & 0x3f);
+ axi_clkgen_read(axi_clkgen, AXI_CLKGEN_REG_CLK_FB1, &reg);
+ m = (reg & 0x3f) + ((reg >> 6) & 0x3f);
+
+ if (d == 0 || dout == 0)
+ return 0;
+
+ tmp = (unsigned long long)(parent_rate / d) * m;
+ do_div(tmp, dout);
+
+ if (tmp > ULONG_MAX)
+ return ULONG_MAX;
+
+ return tmp;
+}
+
+static const struct clk_ops axi_clkgen_ops = {
+ .recalc_rate = axi_clkgen_recalc_rate,
+ .round_rate = axi_clkgen_round_rate,
+ .set_rate = axi_clkgen_set_rate,
+};
+
+static int axi_clkgen_probe(struct platform_device *pdev)
+{
+ struct axi_clkgen *axi_clkgen;
+ struct clk_init_data init;
+ const char *parent_name;
+ const char *clk_name;
+ struct resource *mem;
+ struct clk *clk;
+
+ axi_clkgen = devm_kzalloc(&pdev->dev, sizeof(*axi_clkgen), GFP_KERNEL);
+ if (!axi_clkgen)
+ return -ENOMEM;
+
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ axi_clkgen->base = devm_ioremap_resource(&pdev->dev, mem);
+ if (IS_ERR(axi_clkgen->base))
+ return PTR_ERR(axi_clkgen->base);
+
+ parent_name = of_clk_get_parent_name(pdev->dev.of_node, 0);
+ if (!parent_name)
+ return -EINVAL;
+
+ clk_name = pdev->dev.of_node->name;
+ of_property_read_string(pdev->dev.of_node, "clock-output-names",
+ &clk_name);
+
+ init.name = clk_name;
+ init.ops = &axi_clkgen_ops;
+ init.flags = 0;
+ init.parent_names = &parent_name;
+ init.num_parents = 1;
+
+ axi_clkgen->clk_hw.init = &init;
+ clk = devm_clk_register(&pdev->dev, &axi_clkgen->clk_hw);
+ if (IS_ERR(clk))
+ return PTR_ERR(clk);
+
+ return of_clk_add_provider(pdev->dev.of_node, of_clk_src_simple_get,
+ clk);
+}
+
+static int axi_clkgen_remove(struct platform_device *pdev)
+{
+ of_clk_del_provider(pdev->dev.of_node);
+
+ return 0;
+}
+
+static const struct of_device_id axi_clkgen_ids[] = {
+ { .compatible = "adi,axi-clkgen-1.00.a" },
+ { },
+};
+MODULE_DEVICE_TABLE(of, axi_clkgen_ids);
+
+static struct platform_driver axi_clkgen_driver = {
+ .driver = {
+ .name = "adi-axi-clkgen",
+ .owner = THIS_MODULE,
+ .of_match_table = axi_clkgen_ids,
+ },
+ .probe = axi_clkgen_probe,
+ .remove = axi_clkgen_remove,
+};
+module_platform_driver(axi_clkgen_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
+MODULE_DESCRIPTION("Driver for the Analog Devices' AXI clkgen pcore clock generator");
diff --git a/drivers/clk/clk-composite.c b/drivers/clk/clk-composite.c
new file mode 100644
index 000000000000..097dee4fd209
--- /dev/null
+++ b/drivers/clk/clk-composite.c
@@ -0,0 +1,201 @@
+/*
+ * Copyright (c) 2013 NVIDIA CORPORATION. All rights reserved.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+
+#define to_clk_composite(_hw) container_of(_hw, struct clk_composite, hw)
+
+static u8 clk_composite_get_parent(struct clk_hw *hw)
+{
+ struct clk_composite *composite = to_clk_composite(hw);
+ const struct clk_ops *mux_ops = composite->mux_ops;
+ struct clk_hw *mux_hw = composite->mux_hw;
+
+ mux_hw->clk = hw->clk;
+
+ return mux_ops->get_parent(mux_hw);
+}
+
+static int clk_composite_set_parent(struct clk_hw *hw, u8 index)
+{
+ struct clk_composite *composite = to_clk_composite(hw);
+ const struct clk_ops *mux_ops = composite->mux_ops;
+ struct clk_hw *mux_hw = composite->mux_hw;
+
+ mux_hw->clk = hw->clk;
+
+ return mux_ops->set_parent(mux_hw, index);
+}
+
+static unsigned long clk_composite_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct clk_composite *composite = to_clk_composite(hw);
+ const struct clk_ops *div_ops = composite->div_ops;
+ struct clk_hw *div_hw = composite->div_hw;
+
+ div_hw->clk = hw->clk;
+
+ return div_ops->recalc_rate(div_hw, parent_rate);
+}
+
+static long clk_composite_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *prate)
+{
+ struct clk_composite *composite = to_clk_composite(hw);
+ const struct clk_ops *div_ops = composite->div_ops;
+ struct clk_hw *div_hw = composite->div_hw;
+
+ div_hw->clk = hw->clk;
+
+ return div_ops->round_rate(div_hw, rate, prate);
+}
+
+static int clk_composite_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct clk_composite *composite = to_clk_composite(hw);
+ const struct clk_ops *div_ops = composite->div_ops;
+ struct clk_hw *div_hw = composite->div_hw;
+
+ div_hw->clk = hw->clk;
+
+ return div_ops->set_rate(div_hw, rate, parent_rate);
+}
+
+static int clk_composite_is_enabled(struct clk_hw *hw)
+{
+ struct clk_composite *composite = to_clk_composite(hw);
+ const struct clk_ops *gate_ops = composite->gate_ops;
+ struct clk_hw *gate_hw = composite->gate_hw;
+
+ gate_hw->clk = hw->clk;
+
+ return gate_ops->is_enabled(gate_hw);
+}
+
+static int clk_composite_enable(struct clk_hw *hw)
+{
+ struct clk_composite *composite = to_clk_composite(hw);
+ const struct clk_ops *gate_ops = composite->gate_ops;
+ struct clk_hw *gate_hw = composite->gate_hw;
+
+ gate_hw->clk = hw->clk;
+
+ return gate_ops->enable(gate_hw);
+}
+
+static void clk_composite_disable(struct clk_hw *hw)
+{
+ struct clk_composite *composite = to_clk_composite(hw);
+ const struct clk_ops *gate_ops = composite->gate_ops;
+ struct clk_hw *gate_hw = composite->gate_hw;
+
+ gate_hw->clk = hw->clk;
+
+ gate_ops->disable(gate_hw);
+}
+
+struct clk *clk_register_composite(struct device *dev, const char *name,
+ const char **parent_names, int num_parents,
+ struct clk_hw *mux_hw, const struct clk_ops *mux_ops,
+ struct clk_hw *div_hw, const struct clk_ops *div_ops,
+ struct clk_hw *gate_hw, const struct clk_ops *gate_ops,
+ unsigned long flags)
+{
+ struct clk *clk;
+ struct clk_init_data init;
+ struct clk_composite *composite;
+ struct clk_ops *clk_composite_ops;
+
+ composite = kzalloc(sizeof(*composite), GFP_KERNEL);
+ if (!composite) {
+ pr_err("%s: could not allocate composite clk\n", __func__);
+ return ERR_PTR(-ENOMEM);
+ }
+
+ init.name = name;
+ init.flags = flags | CLK_IS_BASIC;
+ init.parent_names = parent_names;
+ init.num_parents = num_parents;
+
+ clk_composite_ops = &composite->ops;
+
+ if (mux_hw && mux_ops) {
+ if (!mux_ops->get_parent || !mux_ops->set_parent) {
+ clk = ERR_PTR(-EINVAL);
+ goto err;
+ }
+
+ composite->mux_hw = mux_hw;
+ composite->mux_ops = mux_ops;
+ clk_composite_ops->get_parent = clk_composite_get_parent;
+ clk_composite_ops->set_parent = clk_composite_set_parent;
+ }
+
+ if (div_hw && div_ops) {
+ if (!div_ops->recalc_rate || !div_ops->round_rate ||
+ !div_ops->set_rate) {
+ clk = ERR_PTR(-EINVAL);
+ goto err;
+ }
+
+ composite->div_hw = div_hw;
+ composite->div_ops = div_ops;
+ clk_composite_ops->recalc_rate = clk_composite_recalc_rate;
+ clk_composite_ops->round_rate = clk_composite_round_rate;
+ clk_composite_ops->set_rate = clk_composite_set_rate;
+ }
+
+ if (gate_hw && gate_ops) {
+ if (!gate_ops->is_enabled || !gate_ops->enable ||
+ !gate_ops->disable) {
+ clk = ERR_PTR(-EINVAL);
+ goto err;
+ }
+
+ composite->gate_hw = gate_hw;
+ composite->gate_ops = gate_ops;
+ clk_composite_ops->is_enabled = clk_composite_is_enabled;
+ clk_composite_ops->enable = clk_composite_enable;
+ clk_composite_ops->disable = clk_composite_disable;
+ }
+
+ init.ops = clk_composite_ops;
+ composite->hw.init = &init;
+
+ clk = clk_register(dev, &composite->hw);
+ if (IS_ERR(clk))
+ goto err;
+
+ if (composite->mux_hw)
+ composite->mux_hw->clk = clk;
+
+ if (composite->div_hw)
+ composite->div_hw->clk = clk;
+
+ if (composite->gate_hw)
+ composite->gate_hw->clk = clk;
+
+ return clk;
+
+err:
+ kfree(composite);
+ return clk;
+}
diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c
index 68b402101170..6d9674160430 100644
--- a/drivers/clk/clk-divider.c
+++ b/drivers/clk/clk-divider.c
@@ -109,8 +109,9 @@ static unsigned long clk_divider_recalc_rate(struct clk_hw *hw,
div = _get_div(divider, val);
if (!div) {
- WARN(1, "%s: Invalid divisor for clock %s\n", __func__,
- __clk_get_name(hw->clk));
+ WARN(!(divider->flags & CLK_DIVIDER_ALLOW_ZERO),
+ "%s: Zero divisor and CLK_DIVIDER_ALLOW_ZERO not set\n",
+ __clk_get_name(hw->clk));
return parent_rate;
}
diff --git a/drivers/clk/clk-mux.c b/drivers/clk/clk-mux.c
index 508c032edce4..25b1734560d0 100644
--- a/drivers/clk/clk-mux.c
+++ b/drivers/clk/clk-mux.c
@@ -32,6 +32,7 @@
static u8 clk_mux_get_parent(struct clk_hw *hw)
{
struct clk_mux *mux = to_clk_mux(hw);
+ int num_parents = __clk_get_num_parents(hw->clk);
u32 val;
/*
@@ -42,7 +43,16 @@ static u8 clk_mux_get_parent(struct clk_hw *hw)
* val = 0x4 really means "bit 2, index starts at bit 0"
*/
val = readl(mux->reg) >> mux->shift;
- val &= (1 << mux->width) - 1;
+ val &= mux->mask;
+
+ if (mux->table) {
+ int i;
+
+ for (i = 0; i < num_parents; i++)
+ if (mux->table[i] == val)
+ return i;
+ return -EINVAL;
+ }
if (val && (mux->flags & CLK_MUX_INDEX_BIT))
val = ffs(val) - 1;
@@ -50,7 +60,7 @@ static u8 clk_mux_get_parent(struct clk_hw *hw)
if (val && (mux->flags & CLK_MUX_INDEX_ONE))
val--;
- if (val >= __clk_get_num_parents(hw->clk))
+ if (val >= num_parents)
return -EINVAL;
return val;
@@ -62,17 +72,22 @@ static int clk_mux_set_parent(struct clk_hw *hw, u8 index)
u32 val;
unsigned long flags = 0;
- if (mux->flags & CLK_MUX_INDEX_BIT)
- index = (1 << ffs(index));
+ if (mux->table)
+ index = mux->table[index];
- if (mux->flags & CLK_MUX_INDEX_ONE)
- index++;
+ else {
+ if (mux->flags & CLK_MUX_INDEX_BIT)
+ index = (1 << ffs(index));
+
+ if (mux->flags & CLK_MUX_INDEX_ONE)
+ index++;
+ }
if (mux->lock)
spin_lock_irqsave(mux->lock, flags);
val = readl(mux->reg);
- val &= ~(((1 << mux->width) - 1) << mux->shift);
+ val &= ~(mux->mask << mux->shift);
val |= index << mux->shift;
writel(val, mux->reg);
@@ -88,10 +103,10 @@ const struct clk_ops clk_mux_ops = {
};
EXPORT_SYMBOL_GPL(clk_mux_ops);
-struct clk *clk_register_mux(struct device *dev, const char *name,
+struct clk *clk_register_mux_table(struct device *dev, const char *name,
const char **parent_names, u8 num_parents, unsigned long flags,
- void __iomem *reg, u8 shift, u8 width,
- u8 clk_mux_flags, spinlock_t *lock)
+ void __iomem *reg, u8 shift, u32 mask,
+ u8 clk_mux_flags, u32 *table, spinlock_t *lock)
{
struct clk_mux *mux;
struct clk *clk;
@@ -113,9 +128,10 @@ struct clk *clk_register_mux(struct device *dev, const char *name,
/* struct clk_mux assignments */
mux->reg = reg;
mux->shift = shift;
- mux->width = width;
+ mux->mask = mask;
mux->flags = clk_mux_flags;
mux->lock = lock;
+ mux->table = table;
mux->hw.init = &init;
clk = clk_register(dev, &mux->hw);
@@ -125,3 +141,15 @@ struct clk *clk_register_mux(struct device *dev, const char *name,
return clk;
}
+
+struct clk *clk_register_mux(struct device *dev, const char *name,
+ const char **parent_names, u8 num_parents, unsigned long flags,
+ void __iomem *reg, u8 shift, u8 width,
+ u8 clk_mux_flags, spinlock_t *lock)
+{
+ u32 mask = BIT(width) - 1;
+
+ return clk_register_mux_table(dev, name, parent_names, num_parents,
+ flags, reg, shift, mask, clk_mux_flags,
+ NULL, lock);
+}
diff --git a/drivers/clk/clk-prima2.c b/drivers/clk/clk-prima2.c
index f8e9d0c27be2..643ca653fef0 100644
--- a/drivers/clk/clk-prima2.c
+++ b/drivers/clk/clk-prima2.c
@@ -1113,7 +1113,7 @@ void __init sirfsoc_of_clk_init(void)
for (i = pll1; i < maxclk; i++) {
prima2_clks[i] = clk_register(NULL, prima2_clk_hw_array[i]);
- BUG_ON(!prima2_clks[i]);
+ BUG_ON(IS_ERR(prima2_clks[i]));
}
clk_register_clkdev(prima2_clks[cpu], NULL, "cpu");
clk_register_clkdev(prima2_clks[io], NULL, "io");
diff --git a/drivers/clk/clk-zynq.c b/drivers/clk/clk-zynq.c
index b14a25f39255..32062977f453 100644
--- a/drivers/clk/clk-zynq.c
+++ b/drivers/clk/clk-zynq.c
@@ -20,6 +20,7 @@
#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/clk-provider.h>
+#include <linux/clk/zynq.h>
static void __iomem *slcr_base;
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index ed87b2405806..0230c9d95975 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -19,14 +19,77 @@
#include <linux/of.h>
#include <linux/device.h>
#include <linux/init.h>
+#include <linux/sched.h>
static DEFINE_SPINLOCK(enable_lock);
static DEFINE_MUTEX(prepare_lock);
+static struct task_struct *prepare_owner;
+static struct task_struct *enable_owner;
+
+static int prepare_refcnt;
+static int enable_refcnt;
+
static HLIST_HEAD(clk_root_list);
static HLIST_HEAD(clk_orphan_list);
static LIST_HEAD(clk_notifier_list);
+/*** locking ***/
+static void clk_prepare_lock(void)
+{
+ if (!mutex_trylock(&prepare_lock)) {
+ if (prepare_owner == current) {
+ prepare_refcnt++;
+ return;
+ }
+ mutex_lock(&prepare_lock);
+ }
+ WARN_ON_ONCE(prepare_owner != NULL);
+ WARN_ON_ONCE(prepare_refcnt != 0);
+ prepare_owner = current;
+ prepare_refcnt = 1;
+}
+
+static void clk_prepare_unlock(void)
+{
+ WARN_ON_ONCE(prepare_owner != current);
+ WARN_ON_ONCE(prepare_refcnt == 0);
+
+ if (--prepare_refcnt)
+ return;
+ prepare_owner = NULL;
+ mutex_unlock(&prepare_lock);
+}
+
+static unsigned long clk_enable_lock(void)
+{
+ unsigned long flags;
+
+ if (!spin_trylock_irqsave(&enable_lock, flags)) {
+ if (enable_owner == current) {
+ enable_refcnt++;
+ return flags;
+ }
+ spin_lock_irqsave(&enable_lock, flags);
+ }
+ WARN_ON_ONCE(enable_owner != NULL);
+ WARN_ON_ONCE(enable_refcnt != 0);
+ enable_owner = current;
+ enable_refcnt = 1;
+ return flags;
+}
+
+static void clk_enable_unlock(unsigned long flags)
+{
+ WARN_ON_ONCE(enable_owner != current);
+ WARN_ON_ONCE(enable_refcnt == 0);
+
+ if (--enable_refcnt)
+ return;
+ enable_owner = NULL;
+ spin_unlock_irqrestore(&enable_lock, flags);
+}
+
/*** debugfs support ***/
#ifdef CONFIG_COMMON_CLK_DEBUG
@@ -69,7 +132,7 @@ static int clk_summary_show(struct seq_file *s, void *data)
seq_printf(s, " clock enable_cnt prepare_cnt rate\n");
seq_printf(s, "---------------------------------------------------------------------\n");
- mutex_lock(&prepare_lock);
+ clk_prepare_lock();
hlist_for_each_entry(c, &clk_root_list, child_node)
clk_summary_show_subtree(s, c, 0);
@@ -77,7 +140,7 @@ static int clk_summary_show(struct seq_file *s, void *data)
hlist_for_each_entry(c, &clk_orphan_list, child_node)
clk_summary_show_subtree(s, c, 0);
- mutex_unlock(&prepare_lock);
+ clk_prepare_unlock();
return 0;
}
@@ -130,7 +193,7 @@ static int clk_dump(struct seq_file *s, void *data)
seq_printf(s, "{");
- mutex_lock(&prepare_lock);
+ clk_prepare_lock();
hlist_for_each_entry(c, &clk_root_list, child_node) {
if (!first_node)
@@ -144,7 +207,7 @@ static int clk_dump(struct seq_file *s, void *data)
clk_dump_subtree(s, c, 0);
}
- mutex_unlock(&prepare_lock);
+ clk_prepare_unlock();
seq_printf(s, "}");
return 0;
@@ -316,7 +379,7 @@ static int __init clk_debug_init(void)
if (!orphandir)
return -ENOMEM;
- mutex_lock(&prepare_lock);
+ clk_prepare_lock();
hlist_for_each_entry(clk, &clk_root_list, child_node)
clk_debug_create_subtree(clk, rootdir);
@@ -326,7 +389,7 @@ static int __init clk_debug_init(void)
inited = 1;
- mutex_unlock(&prepare_lock);
+ clk_prepare_unlock();
return 0;
}
@@ -336,6 +399,31 @@ static inline int clk_debug_register(struct clk *clk) { return 0; }
#endif
/* caller must hold prepare_lock */
+static void clk_unprepare_unused_subtree(struct clk *clk)
+{
+ struct clk *child;
+
+ if (!clk)
+ return;
+
+ hlist_for_each_entry(child, &clk->children, child_node)
+ clk_unprepare_unused_subtree(child);
+
+ if (clk->prepare_count)
+ return;
+
+ if (clk->flags & CLK_IGNORE_UNUSED)
+ return;
+
+ if (__clk_is_prepared(clk)) {
+ if (clk->ops->unprepare_unused)
+ clk->ops->unprepare_unused(clk->hw);
+ else if (clk->ops->unprepare)
+ clk->ops->unprepare(clk->hw);
+ }
+}
+
+/* caller must hold prepare_lock */
static void clk_disable_unused_subtree(struct clk *clk)
{
struct clk *child;
@@ -347,7 +435,7 @@ static void clk_disable_unused_subtree(struct clk *clk)
hlist_for_each_entry(child, &clk->children, child_node)
clk_disable_unused_subtree(child);
- spin_lock_irqsave(&enable_lock, flags);
+ flags = clk_enable_lock();
if (clk->enable_count)
goto unlock_out;
@@ -368,7 +456,7 @@ static void clk_disable_unused_subtree(struct clk *clk)
}
unlock_out:
- spin_unlock_irqrestore(&enable_lock, flags);
+ clk_enable_unlock(flags);
out:
return;
@@ -378,7 +466,7 @@ static int clk_disable_unused(void)
{
struct clk *clk;
- mutex_lock(&prepare_lock);
+ clk_prepare_lock();
hlist_for_each_entry(clk, &clk_root_list, child_node)
clk_disable_unused_subtree(clk);
@@ -386,7 +474,13 @@ static int clk_disable_unused(void)
hlist_for_each_entry(clk, &clk_orphan_list, child_node)
clk_disable_unused_subtree(clk);
- mutex_unlock(&prepare_lock);
+ hlist_for_each_entry(clk, &clk_root_list, child_node)
+ clk_unprepare_unused_subtree(clk);
+
+ hlist_for_each_entry(clk, &clk_orphan_list, child_node)
+ clk_unprepare_unused_subtree(clk);
+
+ clk_prepare_unlock();
return 0;
}
@@ -451,6 +545,27 @@ unsigned long __clk_get_flags(struct clk *clk)
return !clk ? 0 : clk->flags;
}
+bool __clk_is_prepared(struct clk *clk)
+{
+ int ret;
+
+ if (!clk)
+ return false;
+
+ /*
+ * .is_prepared is optional for clocks that can prepare
+ * fall back to software usage counter if it is missing
+ */
+ if (!clk->ops->is_prepared) {
+ ret = clk->prepare_count ? 1 : 0;
+ goto out;
+ }
+
+ ret = clk->ops->is_prepared(clk->hw);
+out:
+ return !!ret;
+}
+
bool __clk_is_enabled(struct clk *clk)
{
int ret;
@@ -548,9 +663,9 @@ void __clk_unprepare(struct clk *clk)
*/
void clk_unprepare(struct clk *clk)
{
- mutex_lock(&prepare_lock);
+ clk_prepare_lock();
__clk_unprepare(clk);
- mutex_unlock(&prepare_lock);
+ clk_prepare_unlock();
}
EXPORT_SYMBOL_GPL(clk_unprepare);
@@ -596,9 +711,9 @@ int clk_prepare(struct clk *clk)
{
int ret;
- mutex_lock(&prepare_lock);
+ clk_prepare_lock();
ret = __clk_prepare(clk);
- mutex_unlock(&prepare_lock);
+ clk_prepare_unlock();
return ret;
}
@@ -640,9 +755,9 @@ void clk_disable(struct clk *clk)
{
unsigned long flags;
- spin_lock_irqsave(&enable_lock, flags);
+ flags = clk_enable_lock();
__clk_disable(clk);
- spin_unlock_irqrestore(&enable_lock, flags);
+ clk_enable_unlock(flags);
}
EXPORT_SYMBOL_GPL(clk_disable);
@@ -693,9 +808,9 @@ int clk_enable(struct clk *clk)
unsigned long flags;
int ret;
- spin_lock_irqsave(&enable_lock, flags);
+ flags = clk_enable_lock();
ret = __clk_enable(clk);
- spin_unlock_irqrestore(&enable_lock, flags);
+ clk_enable_unlock(flags);
return ret;
}
@@ -740,9 +855,9 @@ long clk_round_rate(struct clk *clk, unsigned long rate)
{
unsigned long ret;
- mutex_lock(&prepare_lock);
+ clk_prepare_lock();
ret = __clk_round_rate(clk, rate);
- mutex_unlock(&prepare_lock);
+ clk_prepare_unlock();
return ret;
}
@@ -837,13 +952,13 @@ unsigned long clk_get_rate(struct clk *clk)
{
unsigned long rate;
- mutex_lock(&prepare_lock);
+ clk_prepare_lock();
if (clk && (clk->flags & CLK_GET_RATE_NOCACHE))
__clk_recalc_rates(clk, 0);
rate = __clk_get_rate(clk);
- mutex_unlock(&prepare_lock);
+ clk_prepare_unlock();
return rate;
}
@@ -974,7 +1089,7 @@ static struct clk *clk_propagate_rate_change(struct clk *clk, unsigned long even
int ret = NOTIFY_DONE;
if (clk->rate == clk->new_rate)
- return 0;
+ return NULL;
if (clk->notifier_count) {
ret = __clk_notify(clk, event, clk->rate, clk->new_rate);
@@ -1048,7 +1163,7 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
int ret = 0;
/* prevent racing with updates to the clock topology */
- mutex_lock(&prepare_lock);
+ clk_prepare_lock();
/* bail early if nothing to do */
if (rate == clk->rate)
@@ -1080,7 +1195,7 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
clk_change_rate(top);
out:
- mutex_unlock(&prepare_lock);
+ clk_prepare_unlock();
return ret;
}
@@ -1096,9 +1211,9 @@ struct clk *clk_get_parent(struct clk *clk)
{
struct clk *parent;
- mutex_lock(&prepare_lock);
+ clk_prepare_lock();
parent = __clk_get_parent(clk);
- mutex_unlock(&prepare_lock);
+ clk_prepare_unlock();
return parent;
}
@@ -1242,19 +1357,19 @@ static int __clk_set_parent(struct clk *clk, struct clk *parent)
__clk_prepare(parent);
/* FIXME replace with clk_is_enabled(clk) someday */
- spin_lock_irqsave(&enable_lock, flags);
+ flags = clk_enable_lock();
if (clk->enable_count)
__clk_enable(parent);
- spin_unlock_irqrestore(&enable_lock, flags);
+ clk_enable_unlock(flags);
/* change clock input source */
ret = clk->ops->set_parent(clk->hw, i);
/* clean up old prepare and enable */
- spin_lock_irqsave(&enable_lock, flags);
+ flags = clk_enable_lock();
if (clk->enable_count)
__clk_disable(old_parent);
- spin_unlock_irqrestore(&enable_lock, flags);
+ clk_enable_unlock(flags);
if (clk->prepare_count)
__clk_unprepare(old_parent);
@@ -1286,7 +1401,7 @@ int clk_set_parent(struct clk *clk, struct clk *parent)
return -ENOSYS;
/* prevent racing with updates to the clock topology */
- mutex_lock(&prepare_lock);
+ clk_prepare_lock();
if (clk->parent == parent)
goto out;
@@ -1315,7 +1430,7 @@ int clk_set_parent(struct clk *clk, struct clk *parent)
__clk_reparent(clk, parent);
out:
- mutex_unlock(&prepare_lock);
+ clk_prepare_unlock();
return ret;
}
@@ -1338,7 +1453,7 @@ int __clk_init(struct device *dev, struct clk *clk)
if (!clk)
return -EINVAL;
- mutex_lock(&prepare_lock);
+ clk_prepare_lock();
/* check to see if a clock with this name is already registered */
if (__clk_lookup(clk->name)) {
@@ -1462,7 +1577,7 @@ int __clk_init(struct device *dev, struct clk *clk)
clk_debug_register(clk);
out:
- mutex_unlock(&prepare_lock);
+ clk_prepare_unlock();
return ret;
}
@@ -1696,7 +1811,7 @@ int clk_notifier_register(struct clk *clk, struct notifier_block *nb)
if (!clk || !nb)
return -EINVAL;
- mutex_lock(&prepare_lock);
+ clk_prepare_lock();
/* search the list of notifiers for this clk */
list_for_each_entry(cn, &clk_notifier_list, node)
@@ -1720,7 +1835,7 @@ int clk_notifier_register(struct clk *clk, struct notifier_block *nb)
clk->notifier_count++;
out:
- mutex_unlock(&prepare_lock);
+ clk_prepare_unlock();
return ret;
}
@@ -1745,7 +1860,7 @@ int clk_notifier_unregister(struct clk *clk, struct notifier_block *nb)
if (!clk || !nb)
return -EINVAL;
- mutex_lock(&prepare_lock);
+ clk_prepare_lock();
list_for_each_entry(cn, &clk_notifier_list, node)
if (cn->clk == clk)
@@ -1766,7 +1881,7 @@ int clk_notifier_unregister(struct clk *clk, struct notifier_block *nb)
ret = -ENOENT;
}
- mutex_unlock(&prepare_lock);
+ clk_prepare_unlock();
return ret;
}
diff --git a/drivers/clk/mvebu/clk-cpu.c b/drivers/clk/mvebu/clk-cpu.c
index 9dd2551a0a41..b0fbc0715491 100644
--- a/drivers/clk/mvebu/clk-cpu.c
+++ b/drivers/clk/mvebu/clk-cpu.c
@@ -16,7 +16,6 @@
#include <linux/io.h>
#include <linux/of.h>
#include <linux/delay.h>
-#include "clk-cpu.h"
#define SYS_CTRL_CLK_DIVIDER_CTRL_OFFSET 0x0
#define SYS_CTRL_CLK_DIVIDER_VALUE_OFFSET 0xC
@@ -173,17 +172,5 @@ clks_out:
kfree(cpuclk);
}
-static const __initconst struct of_device_id clk_cpu_match[] = {
- {
- .compatible = "marvell,armada-xp-cpu-clock",
- .data = of_cpu_clk_setup,
- },
- {
- /* sentinel */
- },
-};
-
-void __init mvebu_cpu_clk_init(void)
-{
- of_clk_init(clk_cpu_match);
-}
+CLK_OF_DECLARE(armada_xp_cpu_clock, "marvell,armada-xp-cpu-clock",
+ of_cpu_clk_setup);
diff --git a/drivers/clk/mvebu/clk-cpu.h b/drivers/clk/mvebu/clk-cpu.h
deleted file mode 100644
index 08e2affba4e6..000000000000
--- a/drivers/clk/mvebu/clk-cpu.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Marvell MVEBU CPU clock handling.
- *
- * Copyright (C) 2012 Marvell
- *
- * Gregory CLEMENT <gregory.clement@free-electrons.com>
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#ifndef __MVEBU_CLK_CPU_H
-#define __MVEBU_CLK_CPU_H
-
-#ifdef CONFIG_MVEBU_CLK_CPU
-void __init mvebu_cpu_clk_init(void);
-#else
-static inline void mvebu_cpu_clk_init(void) {}
-#endif
-
-#endif
diff --git a/drivers/clk/mvebu/clk.c b/drivers/clk/mvebu/clk.c
index 855681b8a9dc..29f10fb3006c 100644
--- a/drivers/clk/mvebu/clk.c
+++ b/drivers/clk/mvebu/clk.c
@@ -10,18 +10,14 @@
* warranty of any kind, whether express or implied.
*/
#include <linux/kernel.h>
-#include <linux/clk.h>
#include <linux/clk-provider.h>
-#include <linux/of_address.h>
-#include <linux/clk/mvebu.h>
#include <linux/of.h>
#include "clk-core.h"
-#include "clk-cpu.h"
#include "clk-gating-ctrl.h"
void __init mvebu_clocks_init(void)
{
mvebu_core_clk_init();
mvebu_gating_clk_init();
- mvebu_cpu_clk_init();
+ of_clk_init(NULL);
}
diff --git a/drivers/clk/mxs/clk.c b/drivers/clk/mxs/clk.c
index b24d56067c80..5301bce8957b 100644
--- a/drivers/clk/mxs/clk.c
+++ b/drivers/clk/mxs/clk.c
@@ -13,6 +13,7 @@
#include <linux/io.h>
#include <linux/jiffies.h>
#include <linux/spinlock.h>
+#include "clk.h"
DEFINE_SPINLOCK(mxs_lock);
diff --git a/drivers/clk/spear/spear1340_clock.c b/drivers/clk/spear/spear1340_clock.c
index 82abea366b78..35e7e2698e10 100644
--- a/drivers/clk/spear/spear1340_clock.c
+++ b/drivers/clk/spear/spear1340_clock.c
@@ -960,47 +960,47 @@ void __init spear1340_clk_init(void)
SPEAR1340_SPDIF_IN_CLK_ENB, 0, &_lock);
clk_register_clkdev(clk, NULL, "d0100000.spdif-in");
- clk = clk_register_gate(NULL, "acp_clk", "acp_mclk", 0,
+ clk = clk_register_gate(NULL, "acp_clk", "ahb_clk", 0,
SPEAR1340_PERIP2_CLK_ENB, SPEAR1340_ACP_CLK_ENB, 0,
&_lock);
clk_register_clkdev(clk, NULL, "acp_clk");
- clk = clk_register_gate(NULL, "plgpio_clk", "plgpio_mclk", 0,
+ clk = clk_register_gate(NULL, "plgpio_clk", "ahb_clk", 0,
SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_PLGPIO_CLK_ENB, 0,
&_lock);
clk_register_clkdev(clk, NULL, "e2800000.gpio");
- clk = clk_register_gate(NULL, "video_dec_clk", "video_dec_mclk", 0,
+ clk = clk_register_gate(NULL, "video_dec_clk", "ahb_clk", 0,
SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_VIDEO_DEC_CLK_ENB,
0, &_lock);
clk_register_clkdev(clk, NULL, "video_dec");
- clk = clk_register_gate(NULL, "video_enc_clk", "video_enc_mclk", 0,
+ clk = clk_register_gate(NULL, "video_enc_clk", "ahb_clk", 0,
SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_VIDEO_ENC_CLK_ENB,
0, &_lock);
clk_register_clkdev(clk, NULL, "video_enc");
- clk = clk_register_gate(NULL, "video_in_clk", "video_in_mclk", 0,
+ clk = clk_register_gate(NULL, "video_in_clk", "ahb_clk", 0,
SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_VIDEO_IN_CLK_ENB, 0,
&_lock);
clk_register_clkdev(clk, NULL, "spear_vip");
- clk = clk_register_gate(NULL, "cam0_clk", "cam0_mclk", 0,
+ clk = clk_register_gate(NULL, "cam0_clk", "ahb_clk", 0,
SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_CAM0_CLK_ENB, 0,
&_lock);
clk_register_clkdev(clk, NULL, "d0200000.cam0");
- clk = clk_register_gate(NULL, "cam1_clk", "cam1_mclk", 0,
+ clk = clk_register_gate(NULL, "cam1_clk", "ahb_clk", 0,
SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_CAM1_CLK_ENB, 0,
&_lock);
clk_register_clkdev(clk, NULL, "d0300000.cam1");
- clk = clk_register_gate(NULL, "cam2_clk", "cam2_mclk", 0,
+ clk = clk_register_gate(NULL, "cam2_clk", "ahb_clk", 0,
SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_CAM2_CLK_ENB, 0,
&_lock);
clk_register_clkdev(clk, NULL, "d0400000.cam2");
- clk = clk_register_gate(NULL, "cam3_clk", "cam3_mclk", 0,
+ clk = clk_register_gate(NULL, "cam3_clk", "ahb_clk", 0,
SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_CAM3_CLK_ENB, 0,
&_lock);
clk_register_clkdev(clk, NULL, "d0500000.cam3");
diff --git a/drivers/clk/sunxi/Makefile b/drivers/clk/sunxi/Makefile
new file mode 100644
index 000000000000..b5bac917612c
--- /dev/null
+++ b/drivers/clk/sunxi/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for sunxi specific clk
+#
+
+obj-y += clk-sunxi.o clk-factors.o
diff --git a/drivers/clk/sunxi/clk-factors.c b/drivers/clk/sunxi/clk-factors.c
new file mode 100644
index 000000000000..88523f91d9b7
--- /dev/null
+++ b/drivers/clk/sunxi/clk-factors.c
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2013 Emilio López <emilio@elopez.com.ar>
+ *
+ * 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.
+ *
+ * Adjustable factor-based clock implementation
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/string.h>
+
+#include <linux/delay.h>
+
+#include "clk-factors.h"
+
+/*
+ * DOC: basic adjustable factor-based clock that cannot gate
+ *
+ * Traits of this clock:
+ * prepare - clk_prepare only ensures that parents are prepared
+ * enable - clk_enable only ensures that parents are enabled
+ * rate - rate is adjustable.
+ * clk->rate = (parent->rate * N * (K + 1) >> P) / (M + 1)
+ * parent - fixed parent. No clk_set_parent support
+ */
+
+struct clk_factors {
+ struct clk_hw hw;
+ void __iomem *reg;
+ struct clk_factors_config *config;
+ void (*get_factors) (u32 *rate, u32 parent, u8 *n, u8 *k, u8 *m, u8 *p);
+ spinlock_t *lock;
+};
+
+#define to_clk_factors(_hw) container_of(_hw, struct clk_factors, hw)
+
+#define SETMASK(len, pos) (((-1U) >> (31-len)) << (pos))
+#define CLRMASK(len, pos) (~(SETMASK(len, pos)))
+#define FACTOR_GET(bit, len, reg) (((reg) & SETMASK(len, bit)) >> (bit))
+
+#define FACTOR_SET(bit, len, reg, val) \
+ (((reg) & CLRMASK(len, bit)) | (val << (bit)))
+
+static unsigned long clk_factors_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ u8 n = 1, k = 0, p = 0, m = 0;
+ u32 reg;
+ unsigned long rate;
+ struct clk_factors *factors = to_clk_factors(hw);
+ struct clk_factors_config *config = factors->config;
+
+ /* Fetch the register value */
+ reg = readl(factors->reg);
+
+ /* Get each individual factor if applicable */
+ if (config->nwidth != SUNXI_FACTORS_NOT_APPLICABLE)
+ n = FACTOR_GET(config->nshift, config->nwidth, reg);
+ if (config->kwidth != SUNXI_FACTORS_NOT_APPLICABLE)
+ k = FACTOR_GET(config->kshift, config->kwidth, reg);
+ if (config->mwidth != SUNXI_FACTORS_NOT_APPLICABLE)
+ m = FACTOR_GET(config->mshift, config->mwidth, reg);
+ if (config->pwidth != SUNXI_FACTORS_NOT_APPLICABLE)
+ p = FACTOR_GET(config->pshift, config->pwidth, reg);
+
+ /* Calculate the rate */
+ rate = (parent_rate * n * (k + 1) >> p) / (m + 1);
+
+ return rate;
+}
+
+static long clk_factors_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *parent_rate)
+{
+ struct clk_factors *factors = to_clk_factors(hw);
+ factors->get_factors((u32 *)&rate, (u32)*parent_rate,
+ NULL, NULL, NULL, NULL);
+
+ return rate;
+}
+
+static int clk_factors_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ u8 n, k, m, p;
+ u32 reg;
+ struct clk_factors *factors = to_clk_factors(hw);
+ struct clk_factors_config *config = factors->config;
+ unsigned long flags = 0;
+
+ factors->get_factors((u32 *)&rate, (u32)parent_rate, &n, &k, &m, &p);
+
+ if (factors->lock)
+ spin_lock_irqsave(factors->lock, flags);
+
+ /* Fetch the register value */
+ reg = readl(factors->reg);
+
+ /* Set up the new factors - macros do not do anything if width is 0 */
+ reg = FACTOR_SET(config->nshift, config->nwidth, reg, n);
+ reg = FACTOR_SET(config->kshift, config->kwidth, reg, k);
+ reg = FACTOR_SET(config->mshift, config->mwidth, reg, m);
+ reg = FACTOR_SET(config->pshift, config->pwidth, reg, p);
+
+ /* Apply them now */
+ writel(reg, factors->reg);
+
+ /* delay 500us so pll stabilizes */
+ __delay((rate >> 20) * 500 / 2);
+
+ if (factors->lock)
+ spin_unlock_irqrestore(factors->lock, flags);
+
+ return 0;
+}
+
+static const struct clk_ops clk_factors_ops = {
+ .recalc_rate = clk_factors_recalc_rate,
+ .round_rate = clk_factors_round_rate,
+ .set_rate = clk_factors_set_rate,
+};
+
+/**
+ * clk_register_factors - register a factors clock with
+ * the clock framework
+ * @dev: device registering this clock
+ * @name: name of this clock
+ * @parent_name: name of clock's parent
+ * @flags: framework-specific flags
+ * @reg: register address to adjust factors
+ * @config: shift and width of factors n, k, m and p
+ * @get_factors: function to calculate the factors for a given frequency
+ * @lock: shared register lock for this clock
+ */
+struct clk *clk_register_factors(struct device *dev, const char *name,
+ const char *parent_name,
+ unsigned long flags, void __iomem *reg,
+ struct clk_factors_config *config,
+ void (*get_factors)(u32 *rate, u32 parent,
+ u8 *n, u8 *k, u8 *m, u8 *p),
+ spinlock_t *lock)
+{
+ struct clk_factors *factors;
+ struct clk *clk;
+ struct clk_init_data init;
+
+ /* allocate the factors */
+ factors = kzalloc(sizeof(struct clk_factors), GFP_KERNEL);
+ if (!factors) {
+ pr_err("%s: could not allocate factors clk\n", __func__);
+ return ERR_PTR(-ENOMEM);
+ }
+
+ init.name = name;
+ init.ops = &clk_factors_ops;
+ init.flags = flags;
+ init.parent_names = (parent_name ? &parent_name : NULL);
+ init.num_parents = (parent_name ? 1 : 0);
+
+ /* struct clk_factors assignments */
+ factors->reg = reg;
+ factors->config = config;
+ factors->lock = lock;
+ factors->hw.init = &init;
+ factors->get_factors = get_factors;
+
+ /* register the clock */
+ clk = clk_register(dev, &factors->hw);
+
+ if (IS_ERR(clk))
+ kfree(factors);
+
+ return clk;
+}
diff --git a/drivers/clk/sunxi/clk-factors.h b/drivers/clk/sunxi/clk-factors.h
new file mode 100644
index 000000000000..f49851cc4380
--- /dev/null
+++ b/drivers/clk/sunxi/clk-factors.h
@@ -0,0 +1,27 @@
+#ifndef __MACH_SUNXI_CLK_FACTORS_H
+#define __MACH_SUNXI_CLK_FACTORS_H
+
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+
+#define SUNXI_FACTORS_NOT_APPLICABLE (0)
+
+struct clk_factors_config {
+ u8 nshift;
+ u8 nwidth;
+ u8 kshift;
+ u8 kwidth;
+ u8 mshift;
+ u8 mwidth;
+ u8 pshift;
+ u8 pwidth;
+};
+
+struct clk *clk_register_factors(struct device *dev, const char *name,
+ const char *parent_name,
+ unsigned long flags, void __iomem *reg,
+ struct clk_factors_config *config,
+ void (*get_factors) (u32 *rate, u32 parent_rate,
+ u8 *n, u8 *k, u8 *m, u8 *p),
+ spinlock_t *lock);
+#endif
diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
new file mode 100644
index 000000000000..0bb0eb4ed217
--- /dev/null
+++ b/drivers/clk/sunxi/clk-sunxi.c
@@ -0,0 +1,450 @@
+/*
+ * Copyright 2013 Emilio López
+ *
+ * Emilio López <emilio@elopez.com.ar>
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/clk/sunxi.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+#include "clk-factors.h"
+
+static DEFINE_SPINLOCK(clk_lock);
+
+/**
+ * sunxi_osc_clk_setup() - Setup function for gatable oscillator
+ */
+
+#define SUNXI_OSC24M_GATE 0
+
+static void __init sunxi_osc_clk_setup(struct device_node *node)
+{
+ struct clk *clk;
+ const char *clk_name = node->name;
+ const char *parent;
+ void *reg;
+
+ reg = of_iomap(node, 0);
+
+ parent = of_clk_get_parent_name(node, 0);
+
+ clk = clk_register_gate(NULL, clk_name, parent, 0, reg,
+ SUNXI_OSC24M_GATE, 0, &clk_lock);
+
+ if (clk) {
+ of_clk_add_provider(node, of_clk_src_simple_get, clk);
+ clk_register_clkdev(clk, clk_name, NULL);
+ }
+}
+
+
+
+/**
+ * sunxi_get_pll1_factors() - calculates n, k, m, p factors for PLL1
+ * PLL1 rate is calculated as follows
+ * rate = (parent_rate * n * (k + 1) >> p) / (m + 1);
+ * parent_rate is always 24Mhz
+ */
+
+static void sunxi_get_pll1_factors(u32 *freq, u32 parent_rate,
+ u8 *n, u8 *k, u8 *m, u8 *p)
+{
+ u8 div;
+
+ /* Normalize value to a 6M multiple */
+ div = *freq / 6000000;
+ *freq = 6000000 * div;
+
+ /* we were called to round the frequency, we can now return */
+ if (n == NULL)
+ return;
+
+ /* m is always zero for pll1 */
+ *m = 0;
+
+ /* k is 1 only on these cases */
+ if (*freq >= 768000000 || *freq == 42000000 || *freq == 54000000)
+ *k = 1;
+ else
+ *k = 0;
+
+ /* p will be 3 for divs under 10 */
+ if (div < 10)
+ *p = 3;
+
+ /* p will be 2 for divs between 10 - 20 and odd divs under 32 */
+ else if (div < 20 || (div < 32 && (div & 1)))
+ *p = 2;
+
+ /* p will be 1 for even divs under 32, divs under 40 and odd pairs
+ * of divs between 40-62 */
+ else if (div < 40 || (div < 64 && (div & 2)))
+ *p = 1;
+
+ /* any other entries have p = 0 */
+ else
+ *p = 0;
+
+ /* calculate a suitable n based on k and p */
+ div <<= *p;
+ div /= (*k + 1);
+ *n = div / 4;
+}
+
+
+
+/**
+ * sunxi_get_apb1_factors() - calculates m, p factors for APB1
+ * APB1 rate is calculated as follows
+ * rate = (parent_rate >> p) / (m + 1);
+ */
+
+static void sunxi_get_apb1_factors(u32 *freq, u32 parent_rate,
+ u8 *n, u8 *k, u8 *m, u8 *p)
+{
+ u8 calcm, calcp;
+
+ if (parent_rate < *freq)
+ *freq = parent_rate;
+
+ parent_rate = (parent_rate + (*freq - 1)) / *freq;
+
+ /* Invalid rate! */
+ if (parent_rate > 32)
+ return;
+
+ if (parent_rate <= 4)
+ calcp = 0;
+ else if (parent_rate <= 8)
+ calcp = 1;
+ else if (parent_rate <= 16)
+ calcp = 2;
+ else
+ calcp = 3;
+
+ calcm = (parent_rate >> calcp) - 1;
+
+ *freq = (parent_rate >> calcp) / (calcm + 1);
+
+ /* we were called to round the frequency, we can now return */
+ if (n == NULL)
+ return;
+
+ *m = calcm;
+ *p = calcp;
+}
+
+
+
+/**
+ * sunxi_factors_clk_setup() - Setup function for factor clocks
+ */
+
+struct factors_data {
+ struct clk_factors_config *table;
+ void (*getter) (u32 *rate, u32 parent_rate, u8 *n, u8 *k, u8 *m, u8 *p);
+};
+
+static struct clk_factors_config pll1_config = {
+ .nshift = 8,
+ .nwidth = 5,
+ .kshift = 4,
+ .kwidth = 2,
+ .mshift = 0,
+ .mwidth = 2,
+ .pshift = 16,
+ .pwidth = 2,
+};
+
+static struct clk_factors_config apb1_config = {
+ .mshift = 0,
+ .mwidth = 5,
+ .pshift = 16,
+ .pwidth = 2,
+};
+
+static const __initconst struct factors_data pll1_data = {
+ .table = &pll1_config,
+ .getter = sunxi_get_pll1_factors,
+};
+
+static const __initconst struct factors_data apb1_data = {
+ .table = &apb1_config,
+ .getter = sunxi_get_apb1_factors,
+};
+
+static void __init sunxi_factors_clk_setup(struct device_node *node,
+ struct factors_data *data)
+{
+ struct clk *clk;
+ const char *clk_name = node->name;
+ const char *parent;
+ void *reg;
+
+ reg = of_iomap(node, 0);
+
+ parent = of_clk_get_parent_name(node, 0);
+
+ clk = clk_register_factors(NULL, clk_name, parent, 0, reg,
+ data->table, data->getter, &clk_lock);
+
+ if (clk) {
+ of_clk_add_provider(node, of_clk_src_simple_get, clk);
+ clk_register_clkdev(clk, clk_name, NULL);
+ }
+}
+
+
+
+/**
+ * sunxi_mux_clk_setup() - Setup function for muxes
+ */
+
+#define SUNXI_MUX_GATE_WIDTH 2
+
+struct mux_data {
+ u8 shift;
+};
+
+static const __initconst struct mux_data cpu_data = {
+ .shift = 16,
+};
+
+static const __initconst struct mux_data apb1_mux_data = {
+ .shift = 24,
+};
+
+static void __init sunxi_mux_clk_setup(struct device_node *node,
+ struct mux_data *data)
+{
+ struct clk *clk;
+ const char *clk_name = node->name;
+ const char *parents[5];
+ void *reg;
+ int i = 0;
+
+ reg = of_iomap(node, 0);
+
+ while (i < 5 && (parents[i] = of_clk_get_parent_name(node, i)) != NULL)
+ i++;
+
+ clk = clk_register_mux(NULL, clk_name, parents, i, 0, reg,
+ data->shift, SUNXI_MUX_GATE_WIDTH,
+ 0, &clk_lock);
+
+ if (clk) {
+ of_clk_add_provider(node, of_clk_src_simple_get, clk);
+ clk_register_clkdev(clk, clk_name, NULL);
+ }
+}
+
+
+
+/**
+ * sunxi_divider_clk_setup() - Setup function for simple divider clocks
+ */
+
+#define SUNXI_DIVISOR_WIDTH 2
+
+struct div_data {
+ u8 shift;
+ u8 pow;
+};
+
+static const __initconst struct div_data axi_data = {
+ .shift = 0,
+ .pow = 0,
+};
+
+static const __initconst struct div_data ahb_data = {
+ .shift = 4,
+ .pow = 1,
+};
+
+static const __initconst struct div_data apb0_data = {
+ .shift = 8,
+ .pow = 1,
+};
+
+static void __init sunxi_divider_clk_setup(struct device_node *node,
+ struct div_data *data)
+{
+ struct clk *clk;
+ const char *clk_name = node->name;
+ const char *clk_parent;
+ void *reg;
+
+ reg = of_iomap(node, 0);
+
+ clk_parent = of_clk_get_parent_name(node, 0);
+
+ clk = clk_register_divider(NULL, clk_name, clk_parent, 0,
+ reg, data->shift, SUNXI_DIVISOR_WIDTH,
+ data->pow ? CLK_DIVIDER_POWER_OF_TWO : 0,
+ &clk_lock);
+ if (clk) {
+ of_clk_add_provider(node, of_clk_src_simple_get, clk);
+ clk_register_clkdev(clk, clk_name, NULL);
+ }
+}
+
+
+
+/**
+ * sunxi_gates_clk_setup() - Setup function for leaf gates on clocks
+ */
+
+#define SUNXI_GATES_MAX_SIZE 64
+
+struct gates_data {
+ DECLARE_BITMAP(mask, SUNXI_GATES_MAX_SIZE);
+};
+
+static const __initconst struct gates_data axi_gates_data = {
+ .mask = {1},
+};
+
+static const __initconst struct gates_data ahb_gates_data = {
+ .mask = {0x7F77FFF, 0x14FB3F},
+};
+
+static const __initconst struct gates_data apb0_gates_data = {
+ .mask = {0x4EF},
+};
+
+static const __initconst struct gates_data apb1_gates_data = {
+ .mask = {0xFF00F7},
+};
+
+static void __init sunxi_gates_clk_setup(struct device_node *node,
+ struct gates_data *data)
+{
+ struct clk_onecell_data *clk_data;
+ const char *clk_parent;
+ const char *clk_name;
+ void *reg;
+ int qty;
+ int i = 0;
+ int j = 0;
+ int ignore;
+
+ reg = of_iomap(node, 0);
+
+ clk_parent = of_clk_get_parent_name(node, 0);
+
+ /* Worst-case size approximation and memory allocation */
+ qty = find_last_bit(data->mask, SUNXI_GATES_MAX_SIZE);
+ clk_data = kmalloc(sizeof(struct clk_onecell_data), GFP_KERNEL);
+ if (!clk_data)
+ return;
+ clk_data->clks = kzalloc((qty+1) * sizeof(struct clk *), GFP_KERNEL);
+ if (!clk_data->clks) {
+ kfree(clk_data);
+ return;
+ }
+
+ for_each_set_bit(i, data->mask, SUNXI_GATES_MAX_SIZE) {
+ of_property_read_string_index(node, "clock-output-names",
+ j, &clk_name);
+
+ /* No driver claims this clock, but it should remain gated */
+ ignore = !strcmp("ahb_sdram", clk_name) ? CLK_IGNORE_UNUSED : 0;
+
+ clk_data->clks[i] = clk_register_gate(NULL, clk_name,
+ clk_parent, ignore,
+ reg + 4 * (i/32), i % 32,
+ 0, &clk_lock);
+ WARN_ON(IS_ERR(clk_data->clks[i]));
+
+ j++;
+ }
+
+ /* Adjust to the real max */
+ clk_data->clk_num = i;
+
+ of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+}
+
+/* Matches for of_clk_init */
+static const __initconst struct of_device_id clk_match[] = {
+ {.compatible = "fixed-clock", .data = of_fixed_clk_setup,},
+ {.compatible = "allwinner,sun4i-osc-clk", .data = sunxi_osc_clk_setup,},
+ {}
+};
+
+/* Matches for factors clocks */
+static const __initconst struct of_device_id clk_factors_match[] = {
+ {.compatible = "allwinner,sun4i-pll1-clk", .data = &pll1_data,},
+ {.compatible = "allwinner,sun4i-apb1-clk", .data = &apb1_data,},
+ {}
+};
+
+/* Matches for divider clocks */
+static const __initconst struct of_device_id clk_div_match[] = {
+ {.compatible = "allwinner,sun4i-axi-clk", .data = &axi_data,},
+ {.compatible = "allwinner,sun4i-ahb-clk", .data = &ahb_data,},
+ {.compatible = "allwinner,sun4i-apb0-clk", .data = &apb0_data,},
+ {}
+};
+
+/* Matches for mux clocks */
+static const __initconst struct of_device_id clk_mux_match[] = {
+ {.compatible = "allwinner,sun4i-cpu-clk", .data = &cpu_data,},
+ {.compatible = "allwinner,sun4i-apb1-mux-clk", .data = &apb1_mux_data,},
+ {}
+};
+
+/* Matches for gate clocks */
+static const __initconst struct of_device_id clk_gates_match[] = {
+ {.compatible = "allwinner,sun4i-axi-gates-clk", .data = &axi_gates_data,},
+ {.compatible = "allwinner,sun4i-ahb-gates-clk", .data = &ahb_gates_data,},
+ {.compatible = "allwinner,sun4i-apb0-gates-clk", .data = &apb0_gates_data,},
+ {.compatible = "allwinner,sun4i-apb1-gates-clk", .data = &apb1_gates_data,},
+ {}
+};
+
+static void __init of_sunxi_table_clock_setup(const struct of_device_id *clk_match,
+ void *function)
+{
+ struct device_node *np;
+ const struct div_data *data;
+ const struct of_device_id *match;
+ void (*setup_function)(struct device_node *, const void *) = function;
+
+ for_each_matching_node(np, clk_match) {
+ match = of_match_node(clk_match, np);
+ data = match->data;
+ setup_function(np, data);
+ }
+}
+
+void __init sunxi_init_clocks(void)
+{
+ /* Register all the simple sunxi clocks on DT */
+ of_clk_init(clk_match);
+
+ /* Register factor clocks */
+ of_sunxi_table_clock_setup(clk_factors_match, sunxi_factors_clk_setup);
+
+ /* Register divider clocks */
+ of_sunxi_table_clock_setup(clk_div_match, sunxi_divider_clk_setup);
+
+ /* Register mux clocks */
+ of_sunxi_table_clock_setup(clk_mux_match, sunxi_mux_clk_setup);
+
+ /* Register gate clocks */
+ of_sunxi_table_clock_setup(clk_gates_match, sunxi_gates_clk_setup);
+}
diff --git a/drivers/clk/tegra/clk-tegra20.c b/drivers/clk/tegra/clk-tegra20.c
index 143ce1f899ad..1e2de7305362 100644
--- a/drivers/clk/tegra/clk-tegra20.c
+++ b/drivers/clk/tegra/clk-tegra20.c
@@ -1292,7 +1292,6 @@ static struct tegra_clk_duplicate tegra_clk_duplicates[] = {
TEGRA_CLK_DUPLICATE(usbd, "tegra-ehci.0", NULL),
TEGRA_CLK_DUPLICATE(usbd, "tegra-otg", NULL),
TEGRA_CLK_DUPLICATE(cclk, NULL, "cpu"),
- TEGRA_CLK_DUPLICATE(twd, "smp_twd", NULL),
TEGRA_CLK_DUPLICATE(clk_max, NULL, NULL), /* Must be the last entry */
};
diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c
index 32c61cb6d0bb..ba6f51bc9f3b 100644
--- a/drivers/clk/tegra/clk-tegra30.c
+++ b/drivers/clk/tegra/clk-tegra30.c
@@ -1931,7 +1931,6 @@ static struct tegra_clk_duplicate tegra_clk_duplicates[] = {
TEGRA_CLK_DUPLICATE(cml1, "tegra_sata_cml", NULL),
TEGRA_CLK_DUPLICATE(cml0, "tegra_pcie", "cml"),
TEGRA_CLK_DUPLICATE(pciex, "tegra_pcie", "pciex"),
- TEGRA_CLK_DUPLICATE(twd, "smp_twd", NULL),
TEGRA_CLK_DUPLICATE(vcp, "nvavp", "vcp"),
TEGRA_CLK_DUPLICATE(clk_max, NULL, NULL), /* MUST be the last entry */
};
diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h
index 0744731c6229..a09d7dcaf183 100644
--- a/drivers/clk/tegra/clk.h
+++ b/drivers/clk/tegra/clk.h
@@ -355,15 +355,16 @@ struct clk *tegra_clk_register_periph_nodiv(const char *name,
struct tegra_clk_periph *periph, void __iomem *clk_base,
u32 offset);
-#define TEGRA_CLK_PERIPH(_mux_shift, _mux_width, _mux_flags, \
+#define TEGRA_CLK_PERIPH(_mux_shift, _mux_mask, _mux_flags, \
_div_shift, _div_width, _div_frac_width, \
_div_flags, _clk_num, _enb_refcnt, _regs, \
- _gate_flags) \
+ _gate_flags, _table) \
{ \
.mux = { \
.flags = _mux_flags, \
.shift = _mux_shift, \
- .width = _mux_width, \
+ .mask = _mux_mask, \
+ .table = _table, \
}, \
.divider = { \
.flags = _div_flags, \
@@ -393,26 +394,36 @@ struct tegra_periph_init_data {
const char *dev_id;
};
-#define TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parent_names, _offset, \
- _mux_shift, _mux_width, _mux_flags, _div_shift, \
+#define TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parent_names, _offset,\
+ _mux_shift, _mux_mask, _mux_flags, _div_shift, \
_div_width, _div_frac_width, _div_flags, _regs, \
- _clk_num, _enb_refcnt, _gate_flags, _clk_id) \
+ _clk_num, _enb_refcnt, _gate_flags, _clk_id, _table) \
{ \
.name = _name, \
.clk_id = _clk_id, \
.parent_names = _parent_names, \
.num_parents = ARRAY_SIZE(_parent_names), \
- .periph = TEGRA_CLK_PERIPH(_mux_shift, _mux_width, \
+ .periph = TEGRA_CLK_PERIPH(_mux_shift, _mux_mask, \
_mux_flags, _div_shift, \
_div_width, _div_frac_width, \
_div_flags, _clk_num, \
_enb_refcnt, _regs, \
- _gate_flags), \
+ _gate_flags, _table), \
.offset = _offset, \
.con_id = _con_id, \
.dev_id = _dev_id, \
}
+#define TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parent_names, _offset,\
+ _mux_shift, _mux_width, _mux_flags, _div_shift, \
+ _div_width, _div_frac_width, _div_flags, _regs, \
+ _clk_num, _enb_refcnt, _gate_flags, _clk_id) \
+ TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parent_names, _offset,\
+ _mux_shift, BIT(_mux_width) - 1, _mux_flags, \
+ _div_shift, _div_width, _div_frac_width, _div_flags, \
+ _regs, _clk_num, _enb_refcnt, _gate_flags, _clk_id,\
+ NULL)
+
/**
* struct clk_super_mux - super clock
*
diff --git a/drivers/clk/ux500/clk-prcmu.c b/drivers/clk/ux500/clk-prcmu.c
index 74faa7e3cf59..293a28854417 100644
--- a/drivers/clk/ux500/clk-prcmu.c
+++ b/drivers/clk/ux500/clk-prcmu.c
@@ -20,15 +20,23 @@
struct clk_prcmu {
struct clk_hw hw;
u8 cg_sel;
+ int is_prepared;
int is_enabled;
+ int opp_requested;
};
/* PRCMU clock operations. */
static int clk_prcmu_prepare(struct clk_hw *hw)
{
+ int ret;
struct clk_prcmu *clk = to_clk_prcmu(hw);
- return prcmu_request_clock(clk->cg_sel, true);
+
+ ret = prcmu_request_clock(clk->cg_sel, true);
+ if (!ret)
+ clk->is_prepared = 1;
+
+ return ret;;
}
static void clk_prcmu_unprepare(struct clk_hw *hw)
@@ -36,7 +44,15 @@ static void clk_prcmu_unprepare(struct clk_hw *hw)
struct clk_prcmu *clk = to_clk_prcmu(hw);
if (prcmu_request_clock(clk->cg_sel, false))
pr_err("clk_prcmu: %s failed to disable %s.\n", __func__,
- hw->init->name);
+ __clk_get_name(hw->clk));
+ else
+ clk->is_prepared = 0;
+}
+
+static int clk_prcmu_is_prepared(struct clk_hw *hw)
+{
+ struct clk_prcmu *clk = to_clk_prcmu(hw);
+ return clk->is_prepared;
}
static int clk_prcmu_enable(struct clk_hw *hw)
@@ -79,58 +95,52 @@ static int clk_prcmu_set_rate(struct clk_hw *hw, unsigned long rate,
return prcmu_set_clock_rate(clk->cg_sel, rate);
}
-static int request_ape_opp100(bool enable)
-{
- static int reqs;
- int err = 0;
-
- if (enable) {
- if (!reqs)
- err = prcmu_qos_add_requirement(PRCMU_QOS_APE_OPP,
- "clock", 100);
- if (!err)
- reqs++;
- } else {
- reqs--;
- if (!reqs)
- prcmu_qos_remove_requirement(PRCMU_QOS_APE_OPP,
- "clock");
- }
- return err;
-}
-
static int clk_prcmu_opp_prepare(struct clk_hw *hw)
{
int err;
struct clk_prcmu *clk = to_clk_prcmu(hw);
- err = request_ape_opp100(true);
- if (err) {
- pr_err("clk_prcmu: %s failed to request APE OPP100 for %s.\n",
- __func__, hw->init->name);
- return err;
+ if (!clk->opp_requested) {
+ err = prcmu_qos_add_requirement(PRCMU_QOS_APE_OPP,
+ (char *)__clk_get_name(hw->clk),
+ 100);
+ if (err) {
+ pr_err("clk_prcmu: %s fail req APE OPP for %s.\n",
+ __func__, __clk_get_name(hw->clk));
+ return err;
+ }
+ clk->opp_requested = 1;
}
err = prcmu_request_clock(clk->cg_sel, true);
- if (err)
- request_ape_opp100(false);
+ if (err) {
+ prcmu_qos_remove_requirement(PRCMU_QOS_APE_OPP,
+ (char *)__clk_get_name(hw->clk));
+ clk->opp_requested = 0;
+ return err;
+ }
- return err;
+ clk->is_prepared = 1;
+ return 0;
}
static void clk_prcmu_opp_unprepare(struct clk_hw *hw)
{
struct clk_prcmu *clk = to_clk_prcmu(hw);
- if (prcmu_request_clock(clk->cg_sel, false))
- goto out_error;
- if (request_ape_opp100(false))
- goto out_error;
- return;
-
-out_error:
- pr_err("clk_prcmu: %s failed to disable %s.\n", __func__,
- hw->init->name);
+ if (prcmu_request_clock(clk->cg_sel, false)) {
+ pr_err("clk_prcmu: %s failed to disable %s.\n", __func__,
+ __clk_get_name(hw->clk));
+ return;
+ }
+
+ if (clk->opp_requested) {
+ prcmu_qos_remove_requirement(PRCMU_QOS_APE_OPP,
+ (char *)__clk_get_name(hw->clk));
+ clk->opp_requested = 0;
+ }
+
+ clk->is_prepared = 0;
}
static int clk_prcmu_opp_volt_prepare(struct clk_hw *hw)
@@ -138,38 +148,49 @@ static int clk_prcmu_opp_volt_prepare(struct clk_hw *hw)
int err;
struct clk_prcmu *clk = to_clk_prcmu(hw);
- err = prcmu_request_ape_opp_100_voltage(true);
- if (err) {
- pr_err("clk_prcmu: %s failed to request APE OPP VOLT for %s.\n",
- __func__, hw->init->name);
- return err;
+ if (!clk->opp_requested) {
+ err = prcmu_request_ape_opp_100_voltage(true);
+ if (err) {
+ pr_err("clk_prcmu: %s fail req APE OPP VOLT for %s.\n",
+ __func__, __clk_get_name(hw->clk));
+ return err;
+ }
+ clk->opp_requested = 1;
}
err = prcmu_request_clock(clk->cg_sel, true);
- if (err)
+ if (err) {
prcmu_request_ape_opp_100_voltage(false);
+ clk->opp_requested = 0;
+ return err;
+ }
- return err;
+ clk->is_prepared = 1;
+ return 0;
}
static void clk_prcmu_opp_volt_unprepare(struct clk_hw *hw)
{
struct clk_prcmu *clk = to_clk_prcmu(hw);
- if (prcmu_request_clock(clk->cg_sel, false))
- goto out_error;
- if (prcmu_request_ape_opp_100_voltage(false))
- goto out_error;
- return;
-
-out_error:
- pr_err("clk_prcmu: %s failed to disable %s.\n", __func__,
- hw->init->name);
+ if (prcmu_request_clock(clk->cg_sel, false)) {
+ pr_err("clk_prcmu: %s failed to disable %s.\n", __func__,
+ __clk_get_name(hw->clk));
+ return;
+ }
+
+ if (clk->opp_requested) {
+ prcmu_request_ape_opp_100_voltage(false);
+ clk->opp_requested = 0;
+ }
+
+ clk->is_prepared = 0;
}
static struct clk_ops clk_prcmu_scalable_ops = {
.prepare = clk_prcmu_prepare,
.unprepare = clk_prcmu_unprepare,
+ .is_prepared = clk_prcmu_is_prepared,
.enable = clk_prcmu_enable,
.disable = clk_prcmu_disable,
.is_enabled = clk_prcmu_is_enabled,
@@ -181,6 +202,7 @@ static struct clk_ops clk_prcmu_scalable_ops = {
static struct clk_ops clk_prcmu_gate_ops = {
.prepare = clk_prcmu_prepare,
.unprepare = clk_prcmu_unprepare,
+ .is_prepared = clk_prcmu_is_prepared,
.enable = clk_prcmu_enable,
.disable = clk_prcmu_disable,
.is_enabled = clk_prcmu_is_enabled,
@@ -202,6 +224,7 @@ static struct clk_ops clk_prcmu_rate_ops = {
static struct clk_ops clk_prcmu_opp_gate_ops = {
.prepare = clk_prcmu_opp_prepare,
.unprepare = clk_prcmu_opp_unprepare,
+ .is_prepared = clk_prcmu_is_prepared,
.enable = clk_prcmu_enable,
.disable = clk_prcmu_disable,
.is_enabled = clk_prcmu_is_enabled,
@@ -211,6 +234,7 @@ static struct clk_ops clk_prcmu_opp_gate_ops = {
static struct clk_ops clk_prcmu_opp_volt_scalable_ops = {
.prepare = clk_prcmu_opp_volt_prepare,
.unprepare = clk_prcmu_opp_volt_unprepare,
+ .is_prepared = clk_prcmu_is_prepared,
.enable = clk_prcmu_enable,
.disable = clk_prcmu_disable,
.is_enabled = clk_prcmu_is_enabled,
@@ -242,7 +266,9 @@ static struct clk *clk_reg_prcmu(const char *name,
}
clk->cg_sel = cg_sel;
+ clk->is_prepared = 1;
clk->is_enabled = 1;
+ clk->opp_requested = 0;
/* "rate" can be used for changing the initial frequency */
if (rate)
prcmu_set_clock_rate(cg_sel, rate);
diff --git a/drivers/clocksource/sunxi_timer.c b/drivers/clocksource/sunxi_timer.c
index 4086b9167159..0ce85e29769b 100644
--- a/drivers/clocksource/sunxi_timer.c
+++ b/drivers/clocksource/sunxi_timer.c
@@ -23,7 +23,7 @@
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/sunxi_timer.h>
-#include <linux/clk-provider.h>
+#include <linux/clk/sunxi.h>
#define TIMER_CTL_REG 0x00
#define TIMER_CTL_ENABLE (1 << 0)
@@ -123,7 +123,7 @@ void __init sunxi_timer_init(void)
if (irq <= 0)
panic("Can't parse IRQ");
- of_clk_init(NULL);
+ sunxi_init_clocks();
clk = of_clk_get(node, 0);
if (IS_ERR(clk))
diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c
index 7472182967ce..61a6fde6c089 100644
--- a/drivers/gpio/gpio-mvebu.c
+++ b/drivers/gpio/gpio-mvebu.c
@@ -42,6 +42,7 @@
#include <linux/io.h>
#include <linux/of_irq.h>
#include <linux/of_device.h>
+#include <linux/clk.h>
#include <linux/pinctrl/consumer.h>
/*
@@ -496,6 +497,7 @@ static int mvebu_gpio_probe(struct platform_device *pdev)
struct resource *res;
struct irq_chip_generic *gc;
struct irq_chip_type *ct;
+ struct clk *clk;
unsigned int ngpios;
int soc_variant;
int i, cpu, id;
@@ -529,6 +531,11 @@ static int mvebu_gpio_probe(struct platform_device *pdev)
return id;
}
+ clk = devm_clk_get(&pdev->dev, NULL);
+ /* Not all SoCs require a clock.*/
+ if (!IS_ERR(clk))
+ clk_prepare_enable(clk);
+
mvchip->soc_variant = soc_variant;
mvchip->chip.label = dev_name(&pdev->dev);
mvchip->chip.dev = &pdev->dev;
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c
index 5fa13267bd9f..02e369f80449 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c
+++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c
@@ -544,13 +544,13 @@ nv50_disp_curs_ofuncs = {
static void
nv50_disp_base_vblank_enable(struct nouveau_event *event, int head)
{
- nv_mask(event->priv, 0x61002c, (1 << head), (1 << head));
+ nv_mask(event->priv, 0x61002c, (4 << head), (4 << head));
}
static void
nv50_disp_base_vblank_disable(struct nouveau_event *event, int head)
{
- nv_mask(event->priv, 0x61002c, (1 << head), (0 << head));
+ nv_mask(event->priv, 0x61002c, (4 << head), 0);
}
static int
diff --git a/drivers/gpu/drm/nouveau/nouveau_abi16.c b/drivers/gpu/drm/nouveau/nouveau_abi16.c
index 41241922263f..3b6dc883e150 100644
--- a/drivers/gpu/drm/nouveau/nouveau_abi16.c
+++ b/drivers/gpu/drm/nouveau/nouveau_abi16.c
@@ -116,6 +116,11 @@ nouveau_abi16_chan_fini(struct nouveau_abi16 *abi16,
{
struct nouveau_abi16_ntfy *ntfy, *temp;
+ /* wait for all activity to stop before releasing notify object, which
+ * may be still in use */
+ if (chan->chan && chan->ntfy)
+ nouveau_channel_idle(chan->chan);
+
/* cleanup notifier state */
list_for_each_entry_safe(ntfy, temp, &chan->notifiers, head) {
nouveau_abi16_ntfy_fini(chan, ntfy);
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c
index 11ca82148edc..7ff10711a4d0 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
@@ -801,7 +801,7 @@ nv50_bo_move_m2mf(struct nouveau_channel *chan, struct ttm_buffer_object *bo,
stride = 16 * 4;
height = amount / stride;
- if (new_mem->mem_type == TTM_PL_VRAM &&
+ if (old_mem->mem_type == TTM_PL_VRAM &&
nouveau_bo_tile_layout(nvbo)) {
ret = RING_SPACE(chan, 8);
if (ret)
@@ -823,7 +823,7 @@ nv50_bo_move_m2mf(struct nouveau_channel *chan, struct ttm_buffer_object *bo,
BEGIN_NV04(chan, NvSubCopy, 0x0200, 1);
OUT_RING (chan, 1);
}
- if (old_mem->mem_type == TTM_PL_VRAM &&
+ if (new_mem->mem_type == TTM_PL_VRAM &&
nouveau_bo_tile_layout(nvbo)) {
ret = RING_SPACE(chan, 8);
if (ret)
diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c
index 87a5a56ed358..2db57990f65c 100644
--- a/drivers/gpu/drm/nouveau/nv50_display.c
+++ b/drivers/gpu/drm/nouveau/nv50_display.c
@@ -2276,6 +2276,7 @@ nv50_display_create(struct drm_device *dev)
NV_WARN(drm, "failed to create encoder %d/%d/%d: %d\n",
dcbe->location, dcbe->type,
ffs(dcbe->or) - 1, ret);
+ ret = 0;
}
}
diff --git a/drivers/hwmon/lineage-pem.c b/drivers/hwmon/lineage-pem.c
index 41df29f59b0e..ebbb9f4f27a3 100644
--- a/drivers/hwmon/lineage-pem.c
+++ b/drivers/hwmon/lineage-pem.c
@@ -422,6 +422,7 @@ static struct attribute *pem_input_attributes[] = {
&sensor_dev_attr_in2_input.dev_attr.attr,
&sensor_dev_attr_curr1_input.dev_attr.attr,
&sensor_dev_attr_power1_input.dev_attr.attr,
+ NULL
};
static const struct attribute_group pem_input_group = {
@@ -432,6 +433,7 @@ static struct attribute *pem_fan_attributes[] = {
&sensor_dev_attr_fan1_input.dev_attr.attr,
&sensor_dev_attr_fan2_input.dev_attr.attr,
&sensor_dev_attr_fan3_input.dev_attr.attr,
+ NULL
};
static const struct attribute_group pem_fan_group = {
diff --git a/drivers/hwmon/pmbus/ltc2978.c b/drivers/hwmon/pmbus/ltc2978.c
index a58de38e23d8..6d6130752f94 100644
--- a/drivers/hwmon/pmbus/ltc2978.c
+++ b/drivers/hwmon/pmbus/ltc2978.c
@@ -59,7 +59,7 @@ enum chips { ltc2978, ltc3880 };
struct ltc2978_data {
enum chips id;
int vin_min, vin_max;
- int temp_min, temp_max;
+ int temp_min, temp_max[2];
int vout_min[8], vout_max[8];
int iout_max[2];
int temp2_max;
@@ -113,9 +113,10 @@ static int ltc2978_read_word_data_common(struct i2c_client *client, int page,
ret = pmbus_read_word_data(client, page,
LTC2978_MFR_TEMPERATURE_PEAK);
if (ret >= 0) {
- if (lin11_to_val(ret) > lin11_to_val(data->temp_max))
- data->temp_max = ret;
- ret = data->temp_max;
+ if (lin11_to_val(ret)
+ > lin11_to_val(data->temp_max[page]))
+ data->temp_max[page] = ret;
+ ret = data->temp_max[page];
}
break;
case PMBUS_VIRT_RESET_VOUT_HISTORY:
@@ -266,7 +267,7 @@ static int ltc2978_write_word_data(struct i2c_client *client, int page,
break;
case PMBUS_VIRT_RESET_TEMP_HISTORY:
data->temp_min = 0x7bff;
- data->temp_max = 0x7c00;
+ data->temp_max[page] = 0x7c00;
ret = ltc2978_clear_peaks(client, page, data->id);
break;
default:
@@ -323,7 +324,8 @@ static int ltc2978_probe(struct i2c_client *client,
data->vin_min = 0x7bff;
data->vin_max = 0x7c00;
data->temp_min = 0x7bff;
- data->temp_max = 0x7c00;
+ for (i = 0; i < ARRAY_SIZE(data->temp_max); i++)
+ data->temp_max[i] = 0x7c00;
data->temp2_max = 0x7c00;
switch (data->id) {
diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c
index 80eef50c50fd..9add60920ac0 100644
--- a/drivers/hwmon/pmbus/pmbus_core.c
+++ b/drivers/hwmon/pmbus/pmbus_core.c
@@ -766,12 +766,14 @@ static ssize_t pmbus_show_label(struct device *dev,
static int pmbus_add_attribute(struct pmbus_data *data, struct attribute *attr)
{
if (data->num_attributes >= data->max_attributes - 1) {
- data->max_attributes += PMBUS_ATTR_ALLOC_SIZE;
- data->group.attrs = krealloc(data->group.attrs,
- sizeof(struct attribute *) *
- data->max_attributes, GFP_KERNEL);
- if (data->group.attrs == NULL)
+ int new_max_attrs = data->max_attributes + PMBUS_ATTR_ALLOC_SIZE;
+ void *new_attrs = krealloc(data->group.attrs,
+ new_max_attrs * sizeof(void *),
+ GFP_KERNEL);
+ if (!new_attrs)
return -ENOMEM;
+ data->group.attrs = new_attrs;
+ data->max_attributes = new_max_attrs;
}
data->group.attrs[data->num_attributes++] = attr;
diff --git a/drivers/iio/common/st_sensors/st_sensors_core.c b/drivers/iio/common/st_sensors/st_sensors_core.c
index 0198324a8b0c..bd33473f8e38 100644
--- a/drivers/iio/common/st_sensors/st_sensors_core.c
+++ b/drivers/iio/common/st_sensors/st_sensors_core.c
@@ -62,7 +62,7 @@ st_sensors_match_odr_error:
int st_sensors_set_odr(struct iio_dev *indio_dev, unsigned int odr)
{
int err;
- struct st_sensor_odr_avl odr_out;
+ struct st_sensor_odr_avl odr_out = {0, 0};
struct st_sensor_data *sdata = iio_priv(indio_dev);
err = st_sensors_match_odr(sdata->sensor, odr, &odr_out);
@@ -114,7 +114,7 @@ st_sensors_match_odr_error:
static int st_sensors_set_fullscale(struct iio_dev *indio_dev, unsigned int fs)
{
- int err, i;
+ int err, i = 0;
struct st_sensor_data *sdata = iio_priv(indio_dev);
err = st_sensors_match_fs(sdata->sensor, fs, &i);
@@ -139,14 +139,13 @@ st_accel_set_fullscale_error:
int st_sensors_set_enable(struct iio_dev *indio_dev, bool enable)
{
- bool found;
u8 tmp_value;
int err = -EINVAL;
- struct st_sensor_odr_avl odr_out;
+ bool found = false;
+ struct st_sensor_odr_avl odr_out = {0, 0};
struct st_sensor_data *sdata = iio_priv(indio_dev);
if (enable) {
- found = false;
tmp_value = sdata->sensor->pw.value_on;
if ((sdata->sensor->odr.addr == sdata->sensor->pw.addr) &&
(sdata->sensor->odr.mask == sdata->sensor->pw.mask)) {
diff --git a/drivers/iio/dac/ad5064.c b/drivers/iio/dac/ad5064.c
index 2fe1d4edcb2f..74f2d52795f6 100644
--- a/drivers/iio/dac/ad5064.c
+++ b/drivers/iio/dac/ad5064.c
@@ -27,7 +27,6 @@
#define AD5064_ADDR(x) ((x) << 20)
#define AD5064_CMD(x) ((x) << 24)
-#define AD5064_ADDR_DAC(chan) (chan)
#define AD5064_ADDR_ALL_DAC 0xF
#define AD5064_CMD_WRITE_INPUT_N 0x0
@@ -131,15 +130,15 @@ static int ad5064_write(struct ad5064_state *st, unsigned int cmd,
}
static int ad5064_sync_powerdown_mode(struct ad5064_state *st,
- unsigned int channel)
+ const struct iio_chan_spec *chan)
{
unsigned int val;
int ret;
- val = (0x1 << channel);
+ val = (0x1 << chan->address);
- if (st->pwr_down[channel])
- val |= st->pwr_down_mode[channel] << 8;
+ if (st->pwr_down[chan->channel])
+ val |= st->pwr_down_mode[chan->channel] << 8;
ret = ad5064_write(st, AD5064_CMD_POWERDOWN_DAC, 0, val, 0);
@@ -169,7 +168,7 @@ static int ad5064_set_powerdown_mode(struct iio_dev *indio_dev,
mutex_lock(&indio_dev->mlock);
st->pwr_down_mode[chan->channel] = mode + 1;
- ret = ad5064_sync_powerdown_mode(st, chan->channel);
+ ret = ad5064_sync_powerdown_mode(st, chan);
mutex_unlock(&indio_dev->mlock);
return ret;
@@ -205,7 +204,7 @@ static ssize_t ad5064_write_dac_powerdown(struct iio_dev *indio_dev,
mutex_lock(&indio_dev->mlock);
st->pwr_down[chan->channel] = pwr_down;
- ret = ad5064_sync_powerdown_mode(st, chan->channel);
+ ret = ad5064_sync_powerdown_mode(st, chan);
mutex_unlock(&indio_dev->mlock);
return ret ? ret : len;
}
@@ -258,7 +257,7 @@ static int ad5064_write_raw(struct iio_dev *indio_dev,
switch (mask) {
case IIO_CHAN_INFO_RAW:
- if (val > (1 << chan->scan_type.realbits) || val < 0)
+ if (val >= (1 << chan->scan_type.realbits) || val < 0)
return -EINVAL;
mutex_lock(&indio_dev->mlock);
@@ -292,34 +291,44 @@ static const struct iio_chan_spec_ext_info ad5064_ext_info[] = {
{ },
};
-#define AD5064_CHANNEL(chan, bits) { \
+#define AD5064_CHANNEL(chan, addr, bits) { \
.type = IIO_VOLTAGE, \
.indexed = 1, \
.output = 1, \
.channel = (chan), \
.info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \
- .address = AD5064_ADDR_DAC(chan), \
+ .address = addr, \
.scan_type = IIO_ST('u', (bits), 16, 20 - (bits)), \
.ext_info = ad5064_ext_info, \
}
#define DECLARE_AD5064_CHANNELS(name, bits) \
const struct iio_chan_spec name[] = { \
- AD5064_CHANNEL(0, bits), \
- AD5064_CHANNEL(1, bits), \
- AD5064_CHANNEL(2, bits), \
- AD5064_CHANNEL(3, bits), \
- AD5064_CHANNEL(4, bits), \
- AD5064_CHANNEL(5, bits), \
- AD5064_CHANNEL(6, bits), \
- AD5064_CHANNEL(7, bits), \
+ AD5064_CHANNEL(0, 0, bits), \
+ AD5064_CHANNEL(1, 1, bits), \
+ AD5064_CHANNEL(2, 2, bits), \
+ AD5064_CHANNEL(3, 3, bits), \
+ AD5064_CHANNEL(4, 4, bits), \
+ AD5064_CHANNEL(5, 5, bits), \
+ AD5064_CHANNEL(6, 6, bits), \
+ AD5064_CHANNEL(7, 7, bits), \
+}
+
+#define DECLARE_AD5065_CHANNELS(name, bits) \
+const struct iio_chan_spec name[] = { \
+ AD5064_CHANNEL(0, 0, bits), \
+ AD5064_CHANNEL(1, 3, bits), \
}
static DECLARE_AD5064_CHANNELS(ad5024_channels, 12);
static DECLARE_AD5064_CHANNELS(ad5044_channels, 14);
static DECLARE_AD5064_CHANNELS(ad5064_channels, 16);
+static DECLARE_AD5065_CHANNELS(ad5025_channels, 12);
+static DECLARE_AD5065_CHANNELS(ad5045_channels, 14);
+static DECLARE_AD5065_CHANNELS(ad5065_channels, 16);
+
static const struct ad5064_chip_info ad5064_chip_info_tbl[] = {
[ID_AD5024] = {
.shared_vref = false,
@@ -328,7 +337,7 @@ static const struct ad5064_chip_info ad5064_chip_info_tbl[] = {
},
[ID_AD5025] = {
.shared_vref = false,
- .channels = ad5024_channels,
+ .channels = ad5025_channels,
.num_channels = 2,
},
[ID_AD5044] = {
@@ -338,7 +347,7 @@ static const struct ad5064_chip_info ad5064_chip_info_tbl[] = {
},
[ID_AD5045] = {
.shared_vref = false,
- .channels = ad5044_channels,
+ .channels = ad5045_channels,
.num_channels = 2,
},
[ID_AD5064] = {
@@ -353,7 +362,7 @@ static const struct ad5064_chip_info ad5064_chip_info_tbl[] = {
},
[ID_AD5065] = {
.shared_vref = false,
- .channels = ad5064_channels,
+ .channels = ad5065_channels,
.num_channels = 2,
},
[ID_AD5628_1] = {
@@ -429,6 +438,7 @@ static int ad5064_probe(struct device *dev, enum ad5064_type type,
{
struct iio_dev *indio_dev;
struct ad5064_state *st;
+ unsigned int midscale;
unsigned int i;
int ret;
@@ -465,11 +475,6 @@ static int ad5064_probe(struct device *dev, enum ad5064_type type,
goto error_free_reg;
}
- for (i = 0; i < st->chip_info->num_channels; ++i) {
- st->pwr_down_mode[i] = AD5064_LDAC_PWRDN_1K;
- st->dac_cache[i] = 0x8000;
- }
-
indio_dev->dev.parent = dev;
indio_dev->name = name;
indio_dev->info = &ad5064_info;
@@ -477,6 +482,13 @@ static int ad5064_probe(struct device *dev, enum ad5064_type type,
indio_dev->channels = st->chip_info->channels;
indio_dev->num_channels = st->chip_info->num_channels;
+ midscale = (1 << indio_dev->channels[0].scan_type.realbits) / 2;
+
+ for (i = 0; i < st->chip_info->num_channels; ++i) {
+ st->pwr_down_mode[i] = AD5064_LDAC_PWRDN_1K;
+ st->dac_cache[i] = midscale;
+ }
+
ret = iio_device_register(indio_dev);
if (ret)
goto error_disable_reg;
diff --git a/drivers/iio/imu/inv_mpu6050/Kconfig b/drivers/iio/imu/inv_mpu6050/Kconfig
index b5cfa3a354cf..361b2328453d 100644
--- a/drivers/iio/imu/inv_mpu6050/Kconfig
+++ b/drivers/iio/imu/inv_mpu6050/Kconfig
@@ -5,6 +5,7 @@
config INV_MPU6050_IIO
tristate "Invensense MPU6050 devices"
depends on I2C && SYSFS
+ select IIO_BUFFER
select IIO_TRIGGERED_BUFFER
help
This driver supports the Invensense MPU6050 devices.
diff --git a/drivers/infiniband/hw/mlx4/cm.c b/drivers/infiniband/hw/mlx4/cm.c
index e0d79b2395e4..add98d01476c 100644
--- a/drivers/infiniband/hw/mlx4/cm.c
+++ b/drivers/infiniband/hw/mlx4/cm.c
@@ -362,7 +362,6 @@ void mlx4_ib_cm_paravirt_init(struct mlx4_ib_dev *dev)
INIT_LIST_HEAD(&dev->sriov.cm_list);
dev->sriov.sl_id_map = RB_ROOT;
idr_init(&dev->sriov.pv_id_table);
- idr_pre_get(&dev->sriov.pv_id_table, GFP_KERNEL);
}
/* slave = -1 ==> all slaves */
diff --git a/drivers/input/keyboard/tc3589x-keypad.c b/drivers/input/keyboard/tc3589x-keypad.c
index 2fb0d76a04c4..208de7cbb7fa 100644
--- a/drivers/input/keyboard/tc3589x-keypad.c
+++ b/drivers/input/keyboard/tc3589x-keypad.c
@@ -70,8 +70,6 @@
#define TC3589x_EVT_INT_CLR 0x2
#define TC3589x_KBD_INT_CLR 0x1
-#define TC3589x_KBD_KEYMAP_SIZE 64
-
/**
* struct tc_keypad - data structure used by keypad driver
* @tc3589x: pointer to tc35893
@@ -88,7 +86,7 @@ struct tc_keypad {
const struct tc3589x_keypad_platform_data *board;
unsigned int krow;
unsigned int kcol;
- unsigned short keymap[TC3589x_KBD_KEYMAP_SIZE];
+ unsigned short *keymap;
bool keypad_stopped;
};
@@ -338,12 +336,14 @@ static int tc3589x_keypad_probe(struct platform_device *pdev)
error = matrix_keypad_build_keymap(plat->keymap_data, NULL,
TC3589x_MAX_KPROW, TC3589x_MAX_KPCOL,
- keypad->keymap, input);
+ NULL, input);
if (error) {
dev_err(&pdev->dev, "Failed to build keymap\n");
goto err_free_mem;
}
+ keypad->keymap = input->keycode;
+
input_set_capability(input, EV_MSC, MSC_SCAN);
if (!plat->no_autorepeat)
__set_bit(EV_REP, input->evbit);
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
index 7b99fc7c9438..0238e0e14335 100644
--- a/drivers/input/mouse/alps.c
+++ b/drivers/input/mouse/alps.c
@@ -490,6 +490,29 @@ static void alps_decode_rushmore(struct alps_fields *f, unsigned char *p)
f->y_map |= (p[5] & 0x20) << 6;
}
+static void alps_decode_dolphin(struct alps_fields *f, unsigned char *p)
+{
+ f->first_mp = !!(p[0] & 0x02);
+ f->is_mp = !!(p[0] & 0x20);
+
+ f->fingers = ((p[0] & 0x6) >> 1 |
+ (p[0] & 0x10) >> 2);
+ f->x_map = ((p[2] & 0x60) >> 5) |
+ ((p[4] & 0x7f) << 2) |
+ ((p[5] & 0x7f) << 9) |
+ ((p[3] & 0x07) << 16) |
+ ((p[3] & 0x70) << 15) |
+ ((p[0] & 0x01) << 22);
+ f->y_map = (p[1] & 0x7f) |
+ ((p[2] & 0x1f) << 7);
+
+ f->x = ((p[1] & 0x7f) | ((p[4] & 0x0f) << 7));
+ f->y = ((p[2] & 0x7f) | ((p[4] & 0xf0) << 3));
+ f->z = (p[0] & 4) ? 0 : p[5] & 0x7f;
+
+ alps_decode_buttons_v3(f, p);
+}
+
static void alps_process_touchpad_packet_v3(struct psmouse *psmouse)
{
struct alps_data *priv = psmouse->private;
@@ -874,7 +897,8 @@ static psmouse_ret_t alps_process_byte(struct psmouse *psmouse)
}
/* Bytes 2 - pktsize should have 0 in the highest bit */
- if (psmouse->pktcnt >= 2 && psmouse->pktcnt <= psmouse->pktsize &&
+ if (priv->proto_version != ALPS_PROTO_V5 &&
+ psmouse->pktcnt >= 2 && psmouse->pktcnt <= psmouse->pktsize &&
(psmouse->packet[psmouse->pktcnt - 1] & 0x80)) {
psmouse_dbg(psmouse, "refusing packet[%i] = %x\n",
psmouse->pktcnt - 1,
@@ -994,8 +1018,7 @@ static int alps_rpt_cmd(struct psmouse *psmouse, int init_command,
return 0;
}
-static int alps_enter_command_mode(struct psmouse *psmouse,
- unsigned char *resp)
+static int alps_enter_command_mode(struct psmouse *psmouse)
{
unsigned char param[4];
@@ -1004,14 +1027,12 @@ static int alps_enter_command_mode(struct psmouse *psmouse,
return -1;
}
- if (param[0] != 0x88 || (param[1] != 0x07 && param[1] != 0x08)) {
+ if ((param[0] != 0x88 || (param[1] != 0x07 && param[1] != 0x08)) &&
+ param[0] != 0x73) {
psmouse_dbg(psmouse,
"unknown response while entering command mode\n");
return -1;
}
-
- if (resp)
- *resp = param[2];
return 0;
}
@@ -1176,7 +1197,7 @@ static int alps_passthrough_mode_v3(struct psmouse *psmouse,
{
int reg_val, ret = -1;
- if (alps_enter_command_mode(psmouse, NULL))
+ if (alps_enter_command_mode(psmouse))
return -1;
reg_val = alps_command_mode_read_reg(psmouse, reg_base + 0x0008);
@@ -1216,7 +1237,7 @@ static int alps_probe_trackstick_v3(struct psmouse *psmouse, int reg_base)
{
int ret = -EIO, reg_val;
- if (alps_enter_command_mode(psmouse, NULL))
+ if (alps_enter_command_mode(psmouse))
goto error;
reg_val = alps_command_mode_read_reg(psmouse, reg_base + 0x08);
@@ -1279,7 +1300,7 @@ static int alps_setup_trackstick_v3(struct psmouse *psmouse, int reg_base)
* supported by this driver. If bit 1 isn't set the packet
* format is different.
*/
- if (alps_enter_command_mode(psmouse, NULL) ||
+ if (alps_enter_command_mode(psmouse) ||
alps_command_mode_write_reg(psmouse,
reg_base + 0x08, 0x82) ||
alps_exit_command_mode(psmouse))
@@ -1306,7 +1327,7 @@ static int alps_hw_init_v3(struct psmouse *psmouse)
alps_setup_trackstick_v3(psmouse, ALPS_REG_BASE_PINNACLE) == -EIO)
goto error;
- if (alps_enter_command_mode(psmouse, NULL) ||
+ if (alps_enter_command_mode(psmouse) ||
alps_absolute_mode_v3(psmouse)) {
psmouse_err(psmouse, "Failed to enter absolute mode\n");
goto error;
@@ -1381,7 +1402,7 @@ static int alps_hw_init_rushmore_v3(struct psmouse *psmouse)
priv->flags &= ~ALPS_DUALPOINT;
}
- if (alps_enter_command_mode(psmouse, NULL) ||
+ if (alps_enter_command_mode(psmouse) ||
alps_command_mode_read_reg(psmouse, 0xc2d9) == -1 ||
alps_command_mode_write_reg(psmouse, 0xc2cb, 0x00))
goto error;
@@ -1431,7 +1452,7 @@ static int alps_hw_init_v4(struct psmouse *psmouse)
struct ps2dev *ps2dev = &psmouse->ps2dev;
unsigned char param[4];
- if (alps_enter_command_mode(psmouse, NULL))
+ if (alps_enter_command_mode(psmouse))
goto error;
if (alps_absolute_mode_v4(psmouse)) {
@@ -1499,6 +1520,23 @@ error:
return -1;
}
+static int alps_hw_init_dolphin_v1(struct psmouse *psmouse)
+{
+ struct ps2dev *ps2dev = &psmouse->ps2dev;
+ unsigned char param[2];
+
+ /* This is dolphin "v1" as empirically defined by florin9doi */
+ param[0] = 0x64;
+ param[1] = 0x28;
+
+ if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSTREAM) ||
+ ps2_command(ps2dev, &param[0], PSMOUSE_CMD_SETRATE) ||
+ ps2_command(ps2dev, &param[1], PSMOUSE_CMD_SETRATE))
+ return -1;
+
+ return 0;
+}
+
static void alps_set_defaults(struct alps_data *priv)
{
priv->byte0 = 0x8f;
@@ -1532,6 +1570,21 @@ static void alps_set_defaults(struct alps_data *priv)
priv->nibble_commands = alps_v4_nibble_commands;
priv->addr_command = PSMOUSE_CMD_DISABLE;
break;
+ case ALPS_PROTO_V5:
+ priv->hw_init = alps_hw_init_dolphin_v1;
+ priv->process_packet = alps_process_packet_v3;
+ priv->decode_fields = alps_decode_dolphin;
+ priv->set_abs_params = alps_set_abs_params_mt;
+ priv->nibble_commands = alps_v3_nibble_commands;
+ priv->addr_command = PSMOUSE_CMD_RESET_WRAP;
+ priv->byte0 = 0xc8;
+ priv->mask0 = 0xc8;
+ priv->flags = 0;
+ priv->x_max = 1360;
+ priv->y_max = 660;
+ priv->x_bits = 23;
+ priv->y_bits = 12;
+ break;
}
}
@@ -1592,6 +1645,12 @@ static int alps_identify(struct psmouse *psmouse, struct alps_data *priv)
if (alps_match_table(psmouse, priv, e7, ec) == 0) {
return 0;
+ } else if (e7[0] == 0x73 && e7[1] == 0x03 && e7[2] == 0x50 &&
+ ec[0] == 0x73 && ec[1] == 0x01) {
+ priv->proto_version = ALPS_PROTO_V5;
+ alps_set_defaults(priv);
+
+ return 0;
} else if (ec[0] == 0x88 && ec[1] == 0x08) {
priv->proto_version = ALPS_PROTO_V3;
alps_set_defaults(priv);
diff --git a/drivers/input/mouse/alps.h b/drivers/input/mouse/alps.h
index 970480551b6e..eee59853b9ce 100644
--- a/drivers/input/mouse/alps.h
+++ b/drivers/input/mouse/alps.h
@@ -16,6 +16,7 @@
#define ALPS_PROTO_V2 2
#define ALPS_PROTO_V3 3
#define ALPS_PROTO_V4 4
+#define ALPS_PROTO_V5 5
/**
* struct alps_model_info - touchpad ID table
diff --git a/drivers/input/mouse/cypress_ps2.c b/drivers/input/mouse/cypress_ps2.c
index 1673dc6c8092..f51765fff054 100644
--- a/drivers/input/mouse/cypress_ps2.c
+++ b/drivers/input/mouse/cypress_ps2.c
@@ -236,6 +236,13 @@ static int cypress_read_fw_version(struct psmouse *psmouse)
cytp->fw_version = param[2] & FW_VERSION_MASX;
cytp->tp_metrics_supported = (param[2] & TP_METRICS_MASK) ? 1 : 0;
+ /*
+ * Trackpad fw_version 11 (in Dell XPS12) yields a bogus response to
+ * CYTP_CMD_READ_TP_METRICS so do not try to use it. LP: #1103594.
+ */
+ if (cytp->fw_version >= 11)
+ cytp->tp_metrics_supported = 0;
+
psmouse_dbg(psmouse, "cytp->fw_version = %d\n", cytp->fw_version);
psmouse_dbg(psmouse, "cytp->tp_metrics_supported = %d\n",
cytp->tp_metrics_supported);
@@ -258,6 +265,9 @@ static int cypress_read_tp_metrics(struct psmouse *psmouse)
cytp->tp_res_x = cytp->tp_max_abs_x / cytp->tp_width;
cytp->tp_res_y = cytp->tp_max_abs_y / cytp->tp_high;
+ if (!cytp->tp_metrics_supported)
+ return 0;
+
memset(param, 0, sizeof(param));
if (cypress_send_ext_cmd(psmouse, CYTP_CMD_READ_TP_METRICS, param) == 0) {
/* Update trackpad parameters. */
@@ -315,18 +325,15 @@ static int cypress_read_tp_metrics(struct psmouse *psmouse)
static int cypress_query_hardware(struct psmouse *psmouse)
{
- struct cytp_data *cytp = psmouse->private;
int ret;
ret = cypress_read_fw_version(psmouse);
if (ret)
return ret;
- if (cytp->tp_metrics_supported) {
- ret = cypress_read_tp_metrics(psmouse);
- if (ret)
- return ret;
- }
+ ret = cypress_read_tp_metrics(psmouse);
+ if (ret)
+ return ret;
return 0;
}
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c
index 41b6fbf60112..1daa97913b7d 100644
--- a/drivers/input/tablet/wacom_wac.c
+++ b/drivers/input/tablet/wacom_wac.c
@@ -2017,6 +2017,9 @@ static const struct wacom_features wacom_features_0x100 =
static const struct wacom_features wacom_features_0x101 =
{ "Wacom ISDv4 101", WACOM_PKGLEN_MTTPC, 26202, 16325, 255,
0, MTTPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
+static const struct wacom_features wacom_features_0x10D =
+ { "Wacom ISDv4 10D", WACOM_PKGLEN_MTTPC, 26202, 16325, 255,
+ 0, MTTPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
static const struct wacom_features wacom_features_0x4001 =
{ "Wacom ISDv4 4001", WACOM_PKGLEN_MTTPC, 26202, 16325, 255,
0, MTTPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
@@ -2201,6 +2204,7 @@ const struct usb_device_id wacom_ids[] = {
{ USB_DEVICE_WACOM(0xEF) },
{ USB_DEVICE_WACOM(0x100) },
{ USB_DEVICE_WACOM(0x101) },
+ { USB_DEVICE_WACOM(0x10D) },
{ USB_DEVICE_WACOM(0x4001) },
{ USB_DEVICE_WACOM(0x47) },
{ USB_DEVICE_WACOM(0xF4) },
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c
index 4f702b3ec1a3..434c3df250ca 100644
--- a/drivers/input/touchscreen/ads7846.c
+++ b/drivers/input/touchscreen/ads7846.c
@@ -236,7 +236,12 @@ static void __ads7846_disable(struct ads7846 *ts)
/* Must be called with ts->lock held */
static void __ads7846_enable(struct ads7846 *ts)
{
- regulator_enable(ts->reg);
+ int error;
+
+ error = regulator_enable(ts->reg);
+ if (error != 0)
+ dev_err(&ts->spi->dev, "Failed to enable supply: %d\n", error);
+
ads7846_restart(ts);
}
diff --git a/drivers/input/touchscreen/mms114.c b/drivers/input/touchscreen/mms114.c
index 4a29ddf6bf1e..1443532fe6c4 100644
--- a/drivers/input/touchscreen/mms114.c
+++ b/drivers/input/touchscreen/mms114.c
@@ -314,15 +314,27 @@ static int mms114_start(struct mms114_data *data)
struct i2c_client *client = data->client;
int error;
- if (data->core_reg)
- regulator_enable(data->core_reg);
- if (data->io_reg)
- regulator_enable(data->io_reg);
+ error = regulator_enable(data->core_reg);
+ if (error) {
+ dev_err(&client->dev, "Failed to enable avdd: %d\n", error);
+ return error;
+ }
+
+ error = regulator_enable(data->io_reg);
+ if (error) {
+ dev_err(&client->dev, "Failed to enable vdd: %d\n", error);
+ regulator_disable(data->core_reg);
+ return error;
+ }
+
mdelay(MMS114_POWERON_DELAY);
error = mms114_setup_regs(data);
- if (error < 0)
+ if (error < 0) {
+ regulator_disable(data->io_reg);
+ regulator_disable(data->core_reg);
return error;
+ }
if (data->pdata->cfg_pin)
data->pdata->cfg_pin(true);
@@ -335,16 +347,20 @@ static int mms114_start(struct mms114_data *data)
static void mms114_stop(struct mms114_data *data)
{
struct i2c_client *client = data->client;
+ int error;
disable_irq(client->irq);
if (data->pdata->cfg_pin)
data->pdata->cfg_pin(false);
- if (data->io_reg)
- regulator_disable(data->io_reg);
- if (data->core_reg)
- regulator_disable(data->core_reg);
+ error = regulator_disable(data->io_reg);
+ if (error)
+ dev_warn(&client->dev, "Failed to disable vdd: %d\n", error);
+
+ error = regulator_disable(data->core_reg);
+ if (error)
+ dev_warn(&client->dev, "Failed to disable avdd: %d\n", error);
}
static int mms114_input_open(struct input_dev *dev)
diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
index 644d72468423..a32e0d5aa45f 100644
--- a/drivers/irqchip/irq-gic.c
+++ b/drivers/irqchip/irq-gic.c
@@ -648,7 +648,7 @@ void gic_raise_softirq(const struct cpumask *mask, unsigned int irq)
/* Convert our logical CPU mask into a physical one. */
for_each_cpu(cpu, mask)
- map |= 1 << cpu_logical_map(cpu);
+ map |= gic_cpu_map[cpu];
/*
* Ensure that stores to Normal memory are visible to the
diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c
index d8a7d8323414..ebaebdf30f98 100644
--- a/drivers/isdn/i4l/isdn_tty.c
+++ b/drivers/isdn/i4l/isdn_tty.c
@@ -902,7 +902,9 @@ isdn_tty_send_msg(modem_info *info, atemu *m, char *msg)
int j;
int l;
- l = strlen(msg);
+ l = min(strlen(msg), sizeof(cmd.parm) - sizeof(cmd.parm.cmsg)
+ + sizeof(cmd.parm.cmsg.para) - 2);
+
if (!l) {
isdn_tty_modem_result(RESULT_ERROR, info);
return;
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 671f5b171c73..c346941a2515 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -858,6 +858,7 @@ config EZX_PCAP
config AB8500_CORE
bool "ST-Ericsson AB8500 Mixed Signal Power Management chip"
depends on GENERIC_HARDIRQS && ABX500_CORE && MFD_DB8500_PRCMU
+ select POWER_SUPPLY
select MFD_CORE
select IRQ_DOMAIN
help
diff --git a/drivers/mfd/ab8500-gpadc.c b/drivers/mfd/ab8500-gpadc.c
index b1f3561b023f..5f341a50ee5a 100644
--- a/drivers/mfd/ab8500-gpadc.c
+++ b/drivers/mfd/ab8500-gpadc.c
@@ -594,9 +594,12 @@ static int ab8500_gpadc_runtime_suspend(struct device *dev)
static int ab8500_gpadc_runtime_resume(struct device *dev)
{
struct ab8500_gpadc *gpadc = dev_get_drvdata(dev);
+ int ret;
- regulator_enable(gpadc->regu);
- return 0;
+ ret = regulator_enable(gpadc->regu);
+ if (ret)
+ dev_err(dev, "Failed to enable vtvout LDO: %d\n", ret);
+ return ret;
}
static int ab8500_gpadc_runtime_idle(struct device *dev)
@@ -643,7 +646,7 @@ static int ab8500_gpadc_probe(struct platform_device *pdev)
}
/* VTVout LDO used to power up ab8500-GPADC */
- gpadc->regu = regulator_get(&pdev->dev, "vddadc");
+ gpadc->regu = devm_regulator_get(&pdev->dev, "vddadc");
if (IS_ERR(gpadc->regu)) {
ret = PTR_ERR(gpadc->regu);
dev_err(gpadc->dev, "failed to get vtvout LDO\n");
@@ -652,7 +655,11 @@ static int ab8500_gpadc_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, gpadc);
- regulator_enable(gpadc->regu);
+ ret = regulator_enable(gpadc->regu);
+ if (ret) {
+ dev_err(gpadc->dev, "Failed to enable vtvout LDO: %d\n", ret);
+ goto fail_enable;
+ }
pm_runtime_set_autosuspend_delay(gpadc->dev, GPADC_AUDOSUSPEND_DELAY);
pm_runtime_use_autosuspend(gpadc->dev);
@@ -663,6 +670,8 @@ static int ab8500_gpadc_probe(struct platform_device *pdev)
list_add_tail(&gpadc->node, &ab8500_gpadc_list);
dev_dbg(gpadc->dev, "probe success\n");
return 0;
+
+fail_enable:
fail_irq:
free_irq(gpadc->irq, gpadc);
fail:
diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c
index 6b5edf64de2b..4febc5c7fdee 100644
--- a/drivers/mfd/omap-usb-host.c
+++ b/drivers/mfd/omap-usb-host.c
@@ -460,15 +460,15 @@ static void omap_usbhs_init(struct device *dev)
switch (omap->usbhs_rev) {
case OMAP_USBHS_REV1:
- omap_usbhs_rev1_hostconfig(omap, reg);
+ reg = omap_usbhs_rev1_hostconfig(omap, reg);
break;
case OMAP_USBHS_REV2:
- omap_usbhs_rev2_hostconfig(omap, reg);
+ reg = omap_usbhs_rev2_hostconfig(omap, reg);
break;
default: /* newer revisions */
- omap_usbhs_rev2_hostconfig(omap, reg);
+ reg = omap_usbhs_rev2_hostconfig(omap, reg);
break;
}
diff --git a/drivers/mfd/palmas.c b/drivers/mfd/palmas.c
index bbdbc50a3cca..73bf76df1044 100644
--- a/drivers/mfd/palmas.c
+++ b/drivers/mfd/palmas.c
@@ -257,9 +257,24 @@ static struct regmap_irq_chip palmas_irq_chip = {
PALMAS_INT1_MASK),
};
-static void palmas_dt_to_pdata(struct device_node *node,
+static int palmas_set_pdata_irq_flag(struct i2c_client *i2c,
struct palmas_platform_data *pdata)
{
+ struct irq_data *irq_data = irq_get_irq_data(i2c->irq);
+ if (!irq_data) {
+ dev_err(&i2c->dev, "Invalid IRQ: %d\n", i2c->irq);
+ return -EINVAL;
+ }
+
+ pdata->irq_flags = irqd_get_trigger_type(irq_data);
+ dev_info(&i2c->dev, "Irq flag is 0x%08x\n", pdata->irq_flags);
+ return 0;
+}
+
+static void palmas_dt_to_pdata(struct i2c_client *i2c,
+ struct palmas_platform_data *pdata)
+{
+ struct device_node *node = i2c->dev.of_node;
int ret;
u32 prop;
@@ -283,6 +298,8 @@ static void palmas_dt_to_pdata(struct device_node *node,
pdata->power_ctrl = PALMAS_POWER_CTRL_NSLEEP_MASK |
PALMAS_POWER_CTRL_ENABLE1_MASK |
PALMAS_POWER_CTRL_ENABLE2_MASK;
+ if (i2c->irq)
+ palmas_set_pdata_irq_flag(i2c, pdata);
}
static int palmas_i2c_probe(struct i2c_client *i2c,
@@ -304,7 +321,7 @@ static int palmas_i2c_probe(struct i2c_client *i2c,
if (!pdata)
return -ENOMEM;
- palmas_dt_to_pdata(node, pdata);
+ palmas_dt_to_pdata(i2c, pdata);
}
if (!pdata)
@@ -344,6 +361,19 @@ static int palmas_i2c_probe(struct i2c_client *i2c,
}
}
+ /* Change interrupt line output polarity */
+ if (pdata->irq_flags & IRQ_TYPE_LEVEL_HIGH)
+ reg = PALMAS_POLARITY_CTRL_INT_POLARITY;
+ else
+ reg = 0;
+ ret = palmas_update_bits(palmas, PALMAS_PU_PD_OD_BASE,
+ PALMAS_POLARITY_CTRL, PALMAS_POLARITY_CTRL_INT_POLARITY,
+ reg);
+ if (ret < 0) {
+ dev_err(palmas->dev, "POLARITY_CTRL updat failed: %d\n", ret);
+ goto err;
+ }
+
/* Change IRQ into clear on read mode for efficiency */
slave = PALMAS_BASE_TO_SLAVE(PALMAS_INTERRUPT_BASE);
addr = PALMAS_BASE_TO_REG(PALMAS_INTERRUPT_BASE, PALMAS_INT_CTRL);
@@ -352,7 +382,7 @@ static int palmas_i2c_probe(struct i2c_client *i2c,
regmap_write(palmas->regmap[slave], addr, reg);
ret = regmap_add_irq_chip(palmas->regmap[slave], palmas->irq,
- IRQF_ONESHOT | IRQF_TRIGGER_LOW, 0, &palmas_irq_chip,
+ IRQF_ONESHOT | pdata->irq_flags, 0, &palmas_irq_chip,
&palmas->irq_data);
if (ret < 0)
goto err;
diff --git a/drivers/mfd/tps65912-core.c b/drivers/mfd/tps65912-core.c
index 4658b5bdcd84..aeb8e40ab424 100644
--- a/drivers/mfd/tps65912-core.c
+++ b/drivers/mfd/tps65912-core.c
@@ -169,6 +169,7 @@ err:
void tps65912_device_exit(struct tps65912 *tps65912)
{
mfd_remove_devices(tps65912->dev);
+ tps65912_irq_exit(tps65912);
kfree(tps65912);
}
diff --git a/drivers/mfd/twl4030-audio.c b/drivers/mfd/twl4030-audio.c
index e16edca92670..d2ab222138c2 100644
--- a/drivers/mfd/twl4030-audio.c
+++ b/drivers/mfd/twl4030-audio.c
@@ -118,7 +118,7 @@ EXPORT_SYMBOL_GPL(twl4030_audio_enable_resource);
* Disable the resource.
* The function returns with error or the content of the register
*/
-int twl4030_audio_disable_resource(unsigned id)
+int twl4030_audio_disable_resource(enum twl4030_audio_res id)
{
struct twl4030_audio *audio = platform_get_drvdata(twl4030_audio_dev);
int val;
diff --git a/drivers/mfd/twl4030-madc.c b/drivers/mfd/twl4030-madc.c
index 88ff9dc83305..942b666a2a07 100644
--- a/drivers/mfd/twl4030-madc.c
+++ b/drivers/mfd/twl4030-madc.c
@@ -800,7 +800,7 @@ static int twl4030_madc_remove(struct platform_device *pdev)
static struct platform_driver twl4030_madc_driver = {
.probe = twl4030_madc_probe,
- .remove = __exit_p(twl4030_madc_remove),
+ .remove = twl4030_madc_remove,
.driver = {
.name = "twl4030_madc",
.owner = THIS_MODULE,
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 7bd068a6056a..8b4e96e01d6c 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -1964,7 +1964,6 @@ static int __bond_release_one(struct net_device *bond_dev,
}
block_netpoll_tx();
- call_netdevice_notifiers(NETDEV_RELEASE, bond_dev);
write_lock_bh(&bond->lock);
slave = bond_get_slave_by_dev(bond, slave_dev);
@@ -2066,8 +2065,10 @@ static int __bond_release_one(struct net_device *bond_dev,
write_unlock_bh(&bond->lock);
unblock_netpoll_tx();
- if (bond->slave_cnt == 0)
+ if (bond->slave_cnt == 0) {
call_netdevice_notifiers(NETDEV_CHANGEADDR, bond->dev);
+ call_netdevice_notifiers(NETDEV_RELEASE, bond->dev);
+ }
bond_compute_features(bond);
if (!(bond_dev->features & NETIF_F_VLAN_CHALLENGED) &&
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
index 31c5787970db..77ebae0ac64a 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
@@ -8647,7 +8647,9 @@ void bnx2x_handle_module_detect_int(struct link_params *params)
MDIO_WC_DEVAD,
MDIO_WC_REG_DIGITAL5_MISC6,
&rx_tx_in_reset);
- if (!rx_tx_in_reset) {
+ if ((!rx_tx_in_reset) &&
+ (params->link_flags &
+ PHY_INITIALIZED)) {
bnx2x_warpcore_reset_lane(bp, phy, 1);
bnx2x_warpcore_config_sfi(phy, params);
bnx2x_warpcore_reset_lane(bp, phy, 0);
@@ -12527,6 +12529,8 @@ int bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
vars->mac_type = MAC_TYPE_NONE;
vars->phy_flags = 0;
+ vars->check_kr2_recovery_cnt = 0;
+ params->link_flags = PHY_INITIALIZED;
/* Driver opens NIG-BRB filters */
bnx2x_set_rx_filter(params, 1);
/* Check if link flap can be avoided */
@@ -12691,6 +12695,7 @@ int bnx2x_lfa_reset(struct link_params *params,
struct bnx2x *bp = params->bp;
vars->link_up = 0;
vars->phy_flags = 0;
+ params->link_flags &= ~PHY_INITIALIZED;
if (!params->lfa_base)
return bnx2x_link_reset(params, vars, 1);
/*
@@ -13411,6 +13416,7 @@ static void bnx2x_disable_kr2(struct link_params *params,
vars->link_attr_sync &= ~LINK_ATTR_SYNC_KR2_ENABLE;
bnx2x_update_link_attr(params, vars->link_attr_sync);
+ vars->check_kr2_recovery_cnt = CHECK_KR2_RECOVERY_CNT;
/* Restart AN on leading lane */
bnx2x_warpcore_restart_AN_KR(phy, params);
}
@@ -13439,6 +13445,15 @@ static void bnx2x_check_kr2_wa(struct link_params *params,
return;
}
+ /* Once KR2 was disabled, wait 5 seconds before checking KR2 recovery
+ * since some switches tend to reinit the AN process and clear the
+ * advertised BP/NP after ~2 seconds causing the KR2 to be disabled
+ * and recovered many times
+ */
+ if (vars->check_kr2_recovery_cnt > 0) {
+ vars->check_kr2_recovery_cnt--;
+ return;
+ }
lane = bnx2x_get_warpcore_lane(phy, params);
CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK,
MDIO_AER_BLOCK_AER_REG, lane);
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h
index be5c195d03dd..56c2aae4e2c8 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h
@@ -309,6 +309,7 @@ struct link_params {
req_flow_ctrl is set to AUTO */
u16 link_flags;
#define LINK_FLAGS_INT_DISABLED (1<<0)
+#define PHY_INITIALIZED (1<<1)
u32 lfa_base;
};
@@ -342,7 +343,8 @@ struct link_vars {
u32 link_status;
u32 eee_status;
u8 fault_detected;
- u8 rsrv1;
+ u8 check_kr2_recovery_cnt;
+#define CHECK_KR2_RECOVERY_CNT 5
u16 periodic_flags;
#define PERIODIC_FLAGS_LINK_EVENT 0x0001
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index fdb9b5655414..93729f942358 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -1869,6 +1869,8 @@ static void tg3_link_report(struct tg3 *tp)
tg3_ump_link_report(tp);
}
+
+ tp->link_up = netif_carrier_ok(tp->dev);
}
static u16 tg3_advert_flowctrl_1000X(u8 flow_ctrl)
@@ -2522,12 +2524,6 @@ static int tg3_phy_reset_5703_4_5(struct tg3 *tp)
return err;
}
-static void tg3_carrier_on(struct tg3 *tp)
-{
- netif_carrier_on(tp->dev);
- tp->link_up = true;
-}
-
static void tg3_carrier_off(struct tg3 *tp)
{
netif_carrier_off(tp->dev);
@@ -2553,7 +2549,7 @@ static int tg3_phy_reset(struct tg3 *tp)
return -EBUSY;
if (netif_running(tp->dev) && tp->link_up) {
- tg3_carrier_off(tp);
+ netif_carrier_off(tp->dev);
tg3_link_report(tp);
}
@@ -4262,9 +4258,9 @@ static bool tg3_test_and_report_link_chg(struct tg3 *tp, int curr_link_up)
{
if (curr_link_up != tp->link_up) {
if (curr_link_up) {
- tg3_carrier_on(tp);
+ netif_carrier_on(tp->dev);
} else {
- tg3_carrier_off(tp);
+ netif_carrier_off(tp->dev);
if (tp->phy_flags & TG3_PHYFLG_MII_SERDES)
tp->phy_flags &= ~TG3_PHYFLG_PARALLEL_DETECT;
}
diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h
index 28ceb8414185..29aff55f2eea 100644
--- a/drivers/net/ethernet/emulex/benet/be.h
+++ b/drivers/net/ethernet/emulex/benet/be.h
@@ -349,6 +349,7 @@ struct be_adapter {
struct pci_dev *pdev;
struct net_device *netdev;
+ u8 __iomem *csr; /* CSR BAR used only for BE2/3 */
u8 __iomem *db; /* Door Bell */
struct mutex mbox_lock; /* For serializing mbox cmds to BE card */
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c
index 071aea79d218..3c9b4f12e3e5 100644
--- a/drivers/net/ethernet/emulex/benet/be_cmds.c
+++ b/drivers/net/ethernet/emulex/benet/be_cmds.c
@@ -473,19 +473,17 @@ static int be_mbox_notify_wait(struct be_adapter *adapter)
return 0;
}
-static int be_POST_stage_get(struct be_adapter *adapter, u16 *stage)
+static u16 be_POST_stage_get(struct be_adapter *adapter)
{
u32 sem;
- u32 reg = skyhawk_chip(adapter) ? SLIPORT_SEMAPHORE_OFFSET_SH :
- SLIPORT_SEMAPHORE_OFFSET_BE;
- pci_read_config_dword(adapter->pdev, reg, &sem);
- *stage = sem & POST_STAGE_MASK;
-
- if ((sem >> POST_ERR_SHIFT) & POST_ERR_MASK)
- return -1;
+ if (BEx_chip(adapter))
+ sem = ioread32(adapter->csr + SLIPORT_SEMAPHORE_OFFSET_BEx);
else
- return 0;
+ pci_read_config_dword(adapter->pdev,
+ SLIPORT_SEMAPHORE_OFFSET_SH, &sem);
+
+ return sem & POST_STAGE_MASK;
}
int lancer_wait_ready(struct be_adapter *adapter)
@@ -579,19 +577,17 @@ int be_fw_wait_ready(struct be_adapter *adapter)
}
do {
- status = be_POST_stage_get(adapter, &stage);
- if (status) {
- dev_err(dev, "POST error; stage=0x%x\n", stage);
- return -1;
- } else if (stage != POST_STAGE_ARMFW_RDY) {
- if (msleep_interruptible(2000)) {
- dev_err(dev, "Waiting for POST aborted\n");
- return -EINTR;
- }
- timeout += 2;
- } else {
+ stage = be_POST_stage_get(adapter);
+ if (stage == POST_STAGE_ARMFW_RDY)
return 0;
+
+ dev_info(dev, "Waiting for POST, %ds elapsed\n",
+ timeout);
+ if (msleep_interruptible(2000)) {
+ dev_err(dev, "Waiting for POST aborted\n");
+ return -EINTR;
}
+ timeout += 2;
} while (timeout < 60);
dev_err(dev, "POST timeout; stage=0x%x\n", stage);
diff --git a/drivers/net/ethernet/emulex/benet/be_hw.h b/drivers/net/ethernet/emulex/benet/be_hw.h
index 541d4530d5bf..62dc220695f7 100644
--- a/drivers/net/ethernet/emulex/benet/be_hw.h
+++ b/drivers/net/ethernet/emulex/benet/be_hw.h
@@ -32,8 +32,8 @@
#define MPU_EP_CONTROL 0
/********** MPU semphore: used for SH & BE *************/
-#define SLIPORT_SEMAPHORE_OFFSET_BE 0x7c
-#define SLIPORT_SEMAPHORE_OFFSET_SH 0x94
+#define SLIPORT_SEMAPHORE_OFFSET_BEx 0xac /* CSR BAR offset */
+#define SLIPORT_SEMAPHORE_OFFSET_SH 0x94 /* PCI-CFG offset */
#define POST_STAGE_MASK 0x0000FFFF
#define POST_ERR_MASK 0x1
#define POST_ERR_SHIFT 31
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index 3860888ac711..08e54f3d288b 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -3688,6 +3688,8 @@ static void be_netdev_init(struct net_device *netdev)
static void be_unmap_pci_bars(struct be_adapter *adapter)
{
+ if (adapter->csr)
+ pci_iounmap(adapter->pdev, adapter->csr);
if (adapter->db)
pci_iounmap(adapter->pdev, adapter->db);
}
@@ -3721,6 +3723,12 @@ static int be_map_pci_bars(struct be_adapter *adapter)
adapter->if_type = (sli_intf & SLI_INTF_IF_TYPE_MASK) >>
SLI_INTF_IF_TYPE_SHIFT;
+ if (BEx_chip(adapter) && be_physfn(adapter)) {
+ adapter->csr = pci_iomap(adapter->pdev, 2, 0);
+ if (adapter->csr == NULL)
+ return -ENOMEM;
+ }
+
addr = pci_iomap(adapter->pdev, db_bar(adapter), 0);
if (addr == NULL)
goto pci_map_err;
@@ -4329,6 +4337,8 @@ static pci_ers_result_t be_eeh_reset(struct pci_dev *pdev)
pci_restore_state(pdev);
/* Check if card is ok and fw is ready */
+ dev_info(&adapter->pdev->dev,
+ "Waiting for FW to be ready after EEH reset\n");
status = be_fw_wait_ready(adapter);
if (status)
return PCI_ERS_RESULT_DISCONNECT;
diff --git a/drivers/net/ethernet/intel/e1000e/ethtool.c b/drivers/net/ethernet/intel/e1000e/ethtool.c
index 2c1813737f6d..f91a8f3f9d48 100644
--- a/drivers/net/ethernet/intel/e1000e/ethtool.c
+++ b/drivers/net/ethernet/intel/e1000e/ethtool.c
@@ -36,6 +36,7 @@
#include <linux/delay.h>
#include <linux/vmalloc.h>
#include <linux/mdio.h>
+#include <linux/pm_runtime.h>
#include "e1000.h"
@@ -2229,7 +2230,19 @@ static int e1000e_get_ts_info(struct net_device *netdev,
return 0;
}
+static int e1000e_ethtool_begin(struct net_device *netdev)
+{
+ return pm_runtime_get_sync(netdev->dev.parent);
+}
+
+static void e1000e_ethtool_complete(struct net_device *netdev)
+{
+ pm_runtime_put_sync(netdev->dev.parent);
+}
+
static const struct ethtool_ops e1000_ethtool_ops = {
+ .begin = e1000e_ethtool_begin,
+ .complete = e1000e_ethtool_complete,
.get_settings = e1000_get_settings,
.set_settings = e1000_set_settings,
.get_drvinfo = e1000_get_drvinfo,
diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c
index dff7bff8b8e0..121a865c7fbd 100644
--- a/drivers/net/ethernet/intel/e1000e/ich8lan.c
+++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c
@@ -782,6 +782,59 @@ release:
}
/**
+ * e1000_k1_workaround_lpt_lp - K1 workaround on Lynxpoint-LP
+ * @hw: pointer to the HW structure
+ * @link: link up bool flag
+ *
+ * When K1 is enabled for 1Gbps, the MAC can miss 2 DMA completion indications
+ * preventing further DMA write requests. Workaround the issue by disabling
+ * the de-assertion of the clock request when in 1Gpbs mode.
+ **/
+static s32 e1000_k1_workaround_lpt_lp(struct e1000_hw *hw, bool link)
+{
+ u32 fextnvm6 = er32(FEXTNVM6);
+ s32 ret_val = 0;
+
+ if (link && (er32(STATUS) & E1000_STATUS_SPEED_1000)) {
+ u16 kmrn_reg;
+
+ ret_val = hw->phy.ops.acquire(hw);
+ if (ret_val)
+ return ret_val;
+
+ ret_val =
+ e1000e_read_kmrn_reg_locked(hw, E1000_KMRNCTRLSTA_K1_CONFIG,
+ &kmrn_reg);
+ if (ret_val)
+ goto release;
+
+ ret_val =
+ e1000e_write_kmrn_reg_locked(hw,
+ E1000_KMRNCTRLSTA_K1_CONFIG,
+ kmrn_reg &
+ ~E1000_KMRNCTRLSTA_K1_ENABLE);
+ if (ret_val)
+ goto release;
+
+ usleep_range(10, 20);
+
+ ew32(FEXTNVM6, fextnvm6 | E1000_FEXTNVM6_REQ_PLL_CLK);
+
+ ret_val =
+ e1000e_write_kmrn_reg_locked(hw,
+ E1000_KMRNCTRLSTA_K1_CONFIG,
+ kmrn_reg);
+release:
+ hw->phy.ops.release(hw);
+ } else {
+ /* clear FEXTNVM6 bit 8 on link down or 10/100 */
+ ew32(FEXTNVM6, fextnvm6 & ~E1000_FEXTNVM6_REQ_PLL_CLK);
+ }
+
+ return ret_val;
+}
+
+/**
* e1000_check_for_copper_link_ich8lan - Check for link (Copper)
* @hw: pointer to the HW structure
*
@@ -818,6 +871,14 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
return ret_val;
}
+ /* Work-around I218 hang issue */
+ if ((hw->adapter->pdev->device == E1000_DEV_ID_PCH_LPTLP_I218_LM) ||
+ (hw->adapter->pdev->device == E1000_DEV_ID_PCH_LPTLP_I218_V)) {
+ ret_val = e1000_k1_workaround_lpt_lp(hw, link);
+ if (ret_val)
+ return ret_val;
+ }
+
/* Clear link partner's EEE ability */
hw->dev_spec.ich8lan.eee_lp_ability = 0;
@@ -3954,8 +4015,16 @@ void e1000_suspend_workarounds_ich8lan(struct e1000_hw *hw)
phy_ctrl = er32(PHY_CTRL);
phy_ctrl |= E1000_PHY_CTRL_GBE_DISABLE;
+
if (hw->phy.type == e1000_phy_i217) {
- u16 phy_reg;
+ u16 phy_reg, device_id = hw->adapter->pdev->device;
+
+ if ((device_id == E1000_DEV_ID_PCH_LPTLP_I218_LM) ||
+ (device_id == E1000_DEV_ID_PCH_LPTLP_I218_V)) {
+ u32 fextnvm6 = er32(FEXTNVM6);
+
+ ew32(FEXTNVM6, fextnvm6 & ~E1000_FEXTNVM6_REQ_PLL_CLK);
+ }
ret_val = hw->phy.ops.acquire(hw);
if (ret_val)
diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.h b/drivers/net/ethernet/intel/e1000e/ich8lan.h
index b6d3174d7d2d..8bf4655c2e17 100644
--- a/drivers/net/ethernet/intel/e1000e/ich8lan.h
+++ b/drivers/net/ethernet/intel/e1000e/ich8lan.h
@@ -92,6 +92,8 @@
#define E1000_FEXTNVM4_BEACON_DURATION_8USEC 0x7
#define E1000_FEXTNVM4_BEACON_DURATION_16USEC 0x3
+#define E1000_FEXTNVM6_REQ_PLL_CLK 0x00000100
+
#define PCIE_ICH8_SNOOP_ALL PCIE_NO_SNOOP_ALL
#define E1000_ICH_RAR_ENTRIES 7
diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c
index a177b8b65c44..948b86ffa4f0 100644
--- a/drivers/net/ethernet/intel/e1000e/netdev.c
+++ b/drivers/net/ethernet/intel/e1000e/netdev.c
@@ -4303,6 +4303,7 @@ static int e1000_open(struct net_device *netdev)
netif_start_queue(netdev);
adapter->idle_check = true;
+ hw->mac.get_link_status = true;
pm_runtime_put(&pdev->dev);
/* fire a link status change interrupt to start the watchdog */
@@ -4662,6 +4663,7 @@ static void e1000_phy_read_status(struct e1000_adapter *adapter)
(adapter->hw.phy.media_type == e1000_media_type_copper)) {
int ret_val;
+ pm_runtime_get_sync(&adapter->pdev->dev);
ret_val = e1e_rphy(hw, MII_BMCR, &phy->bmcr);
ret_val |= e1e_rphy(hw, MII_BMSR, &phy->bmsr);
ret_val |= e1e_rphy(hw, MII_ADVERTISE, &phy->advertise);
@@ -4672,6 +4674,7 @@ static void e1000_phy_read_status(struct e1000_adapter *adapter)
ret_val |= e1e_rphy(hw, MII_ESTATUS, &phy->estatus);
if (ret_val)
e_warn("Error reading PHY register\n");
+ pm_runtime_put_sync(&adapter->pdev->dev);
} else {
/* Do not read PHY registers if link is not up
* Set values to typical power-on defaults
@@ -5887,8 +5890,7 @@ release:
return retval;
}
-static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake,
- bool runtime)
+static int __e1000_shutdown(struct pci_dev *pdev, bool runtime)
{
struct net_device *netdev = pci_get_drvdata(pdev);
struct e1000_adapter *adapter = netdev_priv(netdev);
@@ -5912,10 +5914,6 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake,
}
e1000e_reset_interrupt_capability(adapter);
- retval = pci_save_state(pdev);
- if (retval)
- return retval;
-
status = er32(STATUS);
if (status & E1000_STATUS_LU)
wufc &= ~E1000_WUFC_LNKC;
@@ -5971,13 +5969,6 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake,
ew32(WUFC, 0);
}
- *enable_wake = !!wufc;
-
- /* make sure adapter isn't asleep if manageability is enabled */
- if ((adapter->flags & FLAG_MNG_PT_ENABLED) ||
- (hw->mac.ops.check_mng_mode(hw)))
- *enable_wake = true;
-
if (adapter->hw.phy.type == e1000_phy_igp_3)
e1000e_igp3_phy_powerdown_workaround_ich8lan(&adapter->hw);
@@ -5986,27 +5977,7 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake,
*/
e1000e_release_hw_control(adapter);
- pci_disable_device(pdev);
-
- return 0;
-}
-
-static void e1000_power_off(struct pci_dev *pdev, bool sleep, bool wake)
-{
- if (sleep && wake) {
- pci_prepare_to_sleep(pdev);
- return;
- }
-
- pci_wake_from_d3(pdev, wake);
- pci_set_power_state(pdev, PCI_D3hot);
-}
-
-static void e1000_complete_shutdown(struct pci_dev *pdev, bool sleep,
- bool wake)
-{
- struct net_device *netdev = pci_get_drvdata(pdev);
- struct e1000_adapter *adapter = netdev_priv(netdev);
+ pci_clear_master(pdev);
/* The pci-e switch on some quad port adapters will report a
* correctable error when the MAC transitions from D0 to D3. To
@@ -6021,12 +5992,13 @@ static void e1000_complete_shutdown(struct pci_dev *pdev, bool sleep,
pcie_capability_write_word(us_dev, PCI_EXP_DEVCTL,
(devctl & ~PCI_EXP_DEVCTL_CERE));
- e1000_power_off(pdev, sleep, wake);
+ pci_save_state(pdev);
+ pci_prepare_to_sleep(pdev);
pcie_capability_write_word(us_dev, PCI_EXP_DEVCTL, devctl);
- } else {
- e1000_power_off(pdev, sleep, wake);
}
+
+ return 0;
}
#ifdef CONFIG_PCIEASPM
@@ -6084,9 +6056,7 @@ static int __e1000_resume(struct pci_dev *pdev)
if (aspm_disable_flag)
e1000e_disable_aspm(pdev, aspm_disable_flag);
- pci_set_power_state(pdev, PCI_D0);
- pci_restore_state(pdev);
- pci_save_state(pdev);
+ pci_set_master(pdev);
e1000e_set_interrupt_capability(adapter);
if (netif_running(netdev)) {
@@ -6152,14 +6122,8 @@ static int __e1000_resume(struct pci_dev *pdev)
static int e1000_suspend(struct device *dev)
{
struct pci_dev *pdev = to_pci_dev(dev);
- int retval;
- bool wake;
-
- retval = __e1000_shutdown(pdev, &wake, false);
- if (!retval)
- e1000_complete_shutdown(pdev, true, wake);
- return retval;
+ return __e1000_shutdown(pdev, false);
}
static int e1000_resume(struct device *dev)
@@ -6182,13 +6146,10 @@ static int e1000_runtime_suspend(struct device *dev)
struct net_device *netdev = pci_get_drvdata(pdev);
struct e1000_adapter *adapter = netdev_priv(netdev);
- if (e1000e_pm_ready(adapter)) {
- bool wake;
-
- __e1000_shutdown(pdev, &wake, true);
- }
+ if (!e1000e_pm_ready(adapter))
+ return 0;
- return 0;
+ return __e1000_shutdown(pdev, true);
}
static int e1000_idle(struct device *dev)
@@ -6226,12 +6187,7 @@ static int e1000_runtime_resume(struct device *dev)
static void e1000_shutdown(struct pci_dev *pdev)
{
- bool wake = false;
-
- __e1000_shutdown(pdev, &wake, false);
-
- if (system_state == SYSTEM_POWER_OFF)
- e1000_complete_shutdown(pdev, false, wake);
+ __e1000_shutdown(pdev, false);
}
#ifdef CONFIG_NET_POLL_CONTROLLER
@@ -6352,9 +6308,9 @@ static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev)
"Cannot re-enable PCI device after reset.\n");
result = PCI_ERS_RESULT_DISCONNECT;
} else {
- pci_set_master(pdev);
pdev->state_saved = true;
pci_restore_state(pdev);
+ pci_set_master(pdev);
pci_enable_wake(pdev, PCI_D3hot, 0);
pci_enable_wake(pdev, PCI_D3cold, 0);
@@ -6783,7 +6739,11 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
/* initialize the wol settings based on the eeprom settings */
adapter->wol = adapter->eeprom_wol;
- device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
+
+ /* make sure adapter isn't asleep if manageability is enabled */
+ if (adapter->wol || (adapter->flags & FLAG_MNG_PT_ENABLED) ||
+ (hw->mac.ops.check_mng_mode(hw)))
+ device_wakeup_enable(&pdev->dev);
/* save off EEPROM version number */
e1000_read_nvm(&adapter->hw, 5, 1, &adapter->eeprom_vers);
diff --git a/drivers/net/ethernet/intel/e1000e/regs.h b/drivers/net/ethernet/intel/e1000e/regs.h
index 794fe1497666..a7e6a3e37257 100644
--- a/drivers/net/ethernet/intel/e1000e/regs.h
+++ b/drivers/net/ethernet/intel/e1000e/regs.h
@@ -42,6 +42,7 @@
#define E1000_FEXTNVM 0x00028 /* Future Extended NVM - RW */
#define E1000_FEXTNVM3 0x0003C /* Future Extended NVM 3 - RW */
#define E1000_FEXTNVM4 0x00024 /* Future Extended NVM 4 - RW */
+#define E1000_FEXTNVM6 0x00010 /* Future Extended NVM 6 - RW */
#define E1000_FEXTNVM7 0x000E4 /* Future Extended NVM 7 - RW */
#define E1000_FCT 0x00030 /* Flow Control Type - RW */
#define E1000_VET 0x00038 /* VLAN Ether Type - RW */
diff --git a/drivers/net/ethernet/intel/igb/e1000_82575.c b/drivers/net/ethernet/intel/igb/e1000_82575.c
index 84e7e0909def..b64542acfa34 100644
--- a/drivers/net/ethernet/intel/igb/e1000_82575.c
+++ b/drivers/net/ethernet/intel/igb/e1000_82575.c
@@ -1361,11 +1361,16 @@ static s32 igb_setup_copper_link_82575(struct e1000_hw *hw)
switch (hw->phy.type) {
case e1000_phy_i210:
case e1000_phy_m88:
- if (hw->phy.id == I347AT4_E_PHY_ID ||
- hw->phy.id == M88E1112_E_PHY_ID)
+ switch (hw->phy.id) {
+ case I347AT4_E_PHY_ID:
+ case M88E1112_E_PHY_ID:
+ case I210_I_PHY_ID:
ret_val = igb_copper_link_setup_m88_gen2(hw);
- else
+ break;
+ default:
ret_val = igb_copper_link_setup_m88(hw);
+ break;
+ }
break;
case e1000_phy_igp_3:
ret_val = igb_copper_link_setup_igp(hw);
diff --git a/drivers/net/ethernet/intel/igb/igb.h b/drivers/net/ethernet/intel/igb/igb.h
index d27edbc63923..25151401c2ab 100644
--- a/drivers/net/ethernet/intel/igb/igb.h
+++ b/drivers/net/ethernet/intel/igb/igb.h
@@ -447,7 +447,7 @@ struct igb_adapter {
#endif
struct i2c_algo_bit_data i2c_algo;
struct i2c_adapter i2c_adap;
- struct igb_i2c_client_list *i2c_clients;
+ struct i2c_client *i2c_client;
};
#define IGB_FLAG_HAS_MSI (1 << 0)
diff --git a/drivers/net/ethernet/intel/igb/igb_hwmon.c b/drivers/net/ethernet/intel/igb/igb_hwmon.c
index 0a9b073d0b03..4623502054d5 100644
--- a/drivers/net/ethernet/intel/igb/igb_hwmon.c
+++ b/drivers/net/ethernet/intel/igb/igb_hwmon.c
@@ -39,6 +39,10 @@
#include <linux/pci.h>
#ifdef CONFIG_IGB_HWMON
+struct i2c_board_info i350_sensor_info = {
+ I2C_BOARD_INFO("i350bb", (0Xf8 >> 1)),
+};
+
/* hwmon callback functions */
static ssize_t igb_hwmon_show_location(struct device *dev,
struct device_attribute *attr,
@@ -188,6 +192,7 @@ int igb_sysfs_init(struct igb_adapter *adapter)
unsigned int i;
int n_attrs;
int rc = 0;
+ struct i2c_client *client = NULL;
/* If this method isn't defined we don't support thermals */
if (adapter->hw.mac.ops.init_thermal_sensor_thresh == NULL)
@@ -198,6 +203,15 @@ int igb_sysfs_init(struct igb_adapter *adapter)
if (rc)
goto exit;
+ /* init i2c_client */
+ client = i2c_new_device(&adapter->i2c_adap, &i350_sensor_info);
+ if (client == NULL) {
+ dev_info(&adapter->pdev->dev,
+ "Failed to create new i2c device..\n");
+ goto exit;
+ }
+ adapter->i2c_client = client;
+
/* Allocation space for max attributes
* max num sensors * values (loc, temp, max, caution)
*/
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
index ed79a1c53b59..4dbd62968c7a 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -1923,10 +1923,6 @@ void igb_set_fw_version(struct igb_adapter *adapter)
return;
}
-static const struct i2c_board_info i350_sensor_info = {
- I2C_BOARD_INFO("i350bb", 0Xf8),
-};
-
/* igb_init_i2c - Init I2C interface
* @adapter: pointer to adapter structure
*
@@ -6227,13 +6223,6 @@ static struct sk_buff *igb_build_rx_buffer(struct igb_ring *rx_ring,
/* If we spanned a buffer we have a huge mess so test for it */
BUG_ON(unlikely(!igb_test_staterr(rx_desc, E1000_RXD_STAT_EOP)));
- /* Guarantee this function can be used by verifying buffer sizes */
- BUILD_BUG_ON(SKB_WITH_OVERHEAD(IGB_RX_BUFSZ) < (NET_SKB_PAD +
- NET_IP_ALIGN +
- IGB_TS_HDR_LEN +
- ETH_FRAME_LEN +
- ETH_FCS_LEN));
-
rx_buffer = &rx_ring->rx_buffer_info[rx_ring->next_to_clean];
page = rx_buffer->page;
prefetchw(page);
@@ -7724,67 +7713,6 @@ static void igb_init_dmac(struct igb_adapter *adapter, u32 pba)
}
}
-static DEFINE_SPINLOCK(i2c_clients_lock);
-
-/* igb_get_i2c_client - returns matching client
- * in adapters's client list.
- * @adapter: adapter struct
- * @dev_addr: device address of i2c needed.
- */
-static struct i2c_client *
-igb_get_i2c_client(struct igb_adapter *adapter, u8 dev_addr)
-{
- ulong flags;
- struct igb_i2c_client_list *client_list;
- struct i2c_client *client = NULL;
- struct i2c_board_info client_info = {
- I2C_BOARD_INFO("igb", 0x00),
- };
-
- spin_lock_irqsave(&i2c_clients_lock, flags);
- client_list = adapter->i2c_clients;
-
- /* See if we already have an i2c_client */
- while (client_list) {
- if (client_list->client->addr == (dev_addr >> 1)) {
- client = client_list->client;
- goto exit;
- } else {
- client_list = client_list->next;
- }
- }
-
- /* no client_list found, create a new one */
- client_list = kzalloc(sizeof(*client_list), GFP_ATOMIC);
- if (client_list == NULL)
- goto exit;
-
- /* dev_addr passed to us is left-shifted by 1 bit
- * i2c_new_device call expects it to be flush to the right.
- */
- client_info.addr = dev_addr >> 1;
- client_info.platform_data = adapter;
- client_list->client = i2c_new_device(&adapter->i2c_adap, &client_info);
- if (client_list->client == NULL) {
- dev_info(&adapter->pdev->dev,
- "Failed to create new i2c device..\n");
- goto err_no_client;
- }
-
- /* insert new client at head of list */
- client_list->next = adapter->i2c_clients;
- adapter->i2c_clients = client_list;
-
- client = client_list->client;
- goto exit;
-
-err_no_client:
- kfree(client_list);
-exit:
- spin_unlock_irqrestore(&i2c_clients_lock, flags);
- return client;
-}
-
/* igb_read_i2c_byte - Reads 8 bit word over I2C
* @hw: pointer to hardware structure
* @byte_offset: byte offset to read
@@ -7798,7 +7726,7 @@ s32 igb_read_i2c_byte(struct e1000_hw *hw, u8 byte_offset,
u8 dev_addr, u8 *data)
{
struct igb_adapter *adapter = container_of(hw, struct igb_adapter, hw);
- struct i2c_client *this_client = igb_get_i2c_client(adapter, dev_addr);
+ struct i2c_client *this_client = adapter->i2c_client;
s32 status;
u16 swfw_mask = 0;
@@ -7835,7 +7763,7 @@ s32 igb_write_i2c_byte(struct e1000_hw *hw, u8 byte_offset,
u8 dev_addr, u8 data)
{
struct igb_adapter *adapter = container_of(hw, struct igb_adapter, hw);
- struct i2c_client *this_client = igb_get_i2c_client(adapter, dev_addr);
+ struct i2c_client *this_client = adapter->i2c_client;
s32 status;
u16 swfw_mask = E1000_SWFW_PHY0_SM;
diff --git a/drivers/net/ethernet/marvell/mv643xx_eth.c b/drivers/net/ethernet/marvell/mv643xx_eth.c
index 29140502b71a..6562c736a1d8 100644
--- a/drivers/net/ethernet/marvell/mv643xx_eth.c
+++ b/drivers/net/ethernet/marvell/mv643xx_eth.c
@@ -1081,6 +1081,45 @@ static void txq_set_fixed_prio_mode(struct tx_queue *txq)
/* mii management interface *************************************************/
+static void mv643xx_adjust_pscr(struct mv643xx_eth_private *mp)
+{
+ u32 pscr = rdlp(mp, PORT_SERIAL_CONTROL);
+ u32 autoneg_disable = FORCE_LINK_PASS |
+ DISABLE_AUTO_NEG_SPEED_GMII |
+ DISABLE_AUTO_NEG_FOR_FLOW_CTRL |
+ DISABLE_AUTO_NEG_FOR_DUPLEX;
+
+ if (mp->phy->autoneg == AUTONEG_ENABLE) {
+ /* enable auto negotiation */
+ pscr &= ~autoneg_disable;
+ goto out_write;
+ }
+
+ pscr |= autoneg_disable;
+
+ if (mp->phy->speed == SPEED_1000) {
+ /* force gigabit, half duplex not supported */
+ pscr |= SET_GMII_SPEED_TO_1000;
+ pscr |= SET_FULL_DUPLEX_MODE;
+ goto out_write;
+ }
+
+ pscr &= ~SET_GMII_SPEED_TO_1000;
+
+ if (mp->phy->speed == SPEED_100)
+ pscr |= SET_MII_SPEED_TO_100;
+ else
+ pscr &= ~SET_MII_SPEED_TO_100;
+
+ if (mp->phy->duplex == DUPLEX_FULL)
+ pscr |= SET_FULL_DUPLEX_MODE;
+ else
+ pscr &= ~SET_FULL_DUPLEX_MODE;
+
+out_write:
+ wrlp(mp, PORT_SERIAL_CONTROL, pscr);
+}
+
static irqreturn_t mv643xx_eth_err_irq(int irq, void *dev_id)
{
struct mv643xx_eth_shared_private *msp = dev_id;
@@ -1499,6 +1538,7 @@ static int
mv643xx_eth_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
struct mv643xx_eth_private *mp = netdev_priv(dev);
+ int ret;
if (mp->phy == NULL)
return -EINVAL;
@@ -1508,7 +1548,10 @@ mv643xx_eth_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
*/
cmd->advertising &= ~ADVERTISED_1000baseT_Half;
- return phy_ethtool_sset(mp->phy, cmd);
+ ret = phy_ethtool_sset(mp->phy, cmd);
+ if (!ret)
+ mv643xx_adjust_pscr(mp);
+ return ret;
}
static void mv643xx_eth_get_drvinfo(struct net_device *dev,
@@ -2442,11 +2485,15 @@ static int mv643xx_eth_stop(struct net_device *dev)
static int mv643xx_eth_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
struct mv643xx_eth_private *mp = netdev_priv(dev);
+ int ret;
- if (mp->phy != NULL)
- return phy_mii_ioctl(mp->phy, ifr, cmd);
+ if (mp->phy == NULL)
+ return -ENOTSUPP;
- return -EOPNOTSUPP;
+ ret = phy_mii_ioctl(mp->phy, ifr, cmd);
+ if (!ret)
+ mv643xx_adjust_pscr(mp);
+ return ret;
}
static int mv643xx_eth_change_mtu(struct net_device *dev, int new_mtu)
diff --git a/drivers/net/ethernet/mellanox/mlx4/cq.c b/drivers/net/ethernet/mellanox/mlx4/cq.c
index 7e64033d7de3..0706623cfb96 100644
--- a/drivers/net/ethernet/mellanox/mlx4/cq.c
+++ b/drivers/net/ethernet/mellanox/mlx4/cq.c
@@ -226,7 +226,7 @@ void __mlx4_cq_free_icm(struct mlx4_dev *dev, int cqn)
static void mlx4_cq_free_icm(struct mlx4_dev *dev, int cqn)
{
- u64 in_param;
+ u64 in_param = 0;
int err;
if (mlx4_is_mfunc(dev)) {
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
index bb4d8d99f36d..995d4b6d5c1e 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
@@ -565,34 +565,38 @@ static void mlx4_en_put_qp(struct mlx4_en_priv *priv)
struct mlx4_en_dev *mdev = priv->mdev;
struct mlx4_dev *dev = mdev->dev;
int qpn = priv->base_qpn;
- u64 mac = mlx4_en_mac_to_u64(priv->dev->dev_addr);
-
- en_dbg(DRV, priv, "Registering MAC: %pM for deleting\n",
- priv->dev->dev_addr);
- mlx4_unregister_mac(dev, priv->port, mac);
+ u64 mac;
- if (dev->caps.steering_mode != MLX4_STEERING_MODE_A0) {
+ if (dev->caps.steering_mode == MLX4_STEERING_MODE_A0) {
+ mac = mlx4_en_mac_to_u64(priv->dev->dev_addr);
+ en_dbg(DRV, priv, "Registering MAC: %pM for deleting\n",
+ priv->dev->dev_addr);
+ mlx4_unregister_mac(dev, priv->port, mac);
+ } else {
struct mlx4_mac_entry *entry;
struct hlist_node *tmp;
struct hlist_head *bucket;
- unsigned int mac_hash;
+ unsigned int i;
- mac_hash = priv->dev->dev_addr[MLX4_EN_MAC_HASH_IDX];
- bucket = &priv->mac_hash[mac_hash];
- hlist_for_each_entry_safe(entry, tmp, bucket, hlist) {
- if (ether_addr_equal_64bits(entry->mac,
- priv->dev->dev_addr)) {
- en_dbg(DRV, priv, "Releasing qp: port %d, MAC %pM, qpn %d\n",
- priv->port, priv->dev->dev_addr, qpn);
+ for (i = 0; i < MLX4_EN_MAC_HASH_SIZE; ++i) {
+ bucket = &priv->mac_hash[i];
+ hlist_for_each_entry_safe(entry, tmp, bucket, hlist) {
+ mac = mlx4_en_mac_to_u64(entry->mac);
+ en_dbg(DRV, priv, "Registering MAC: %pM for deleting\n",
+ entry->mac);
mlx4_en_uc_steer_release(priv, entry->mac,
qpn, entry->reg_id);
- mlx4_qp_release_range(dev, qpn, 1);
+ mlx4_unregister_mac(dev, priv->port, mac);
hlist_del_rcu(&entry->hlist);
kfree_rcu(entry, rcu);
- break;
}
}
+
+ en_dbg(DRV, priv, "Releasing qp: port %d, qpn %d\n",
+ priv->port, qpn);
+ mlx4_qp_release_range(dev, qpn, 1);
+ priv->flags &= ~MLX4_EN_FLAG_FORCE_PROMISC;
}
}
@@ -650,28 +654,10 @@ u64 mlx4_en_mac_to_u64(u8 *addr)
return mac;
}
-static int mlx4_en_set_mac(struct net_device *dev, void *addr)
-{
- struct mlx4_en_priv *priv = netdev_priv(dev);
- struct mlx4_en_dev *mdev = priv->mdev;
- struct sockaddr *saddr = addr;
-
- if (!is_valid_ether_addr(saddr->sa_data))
- return -EADDRNOTAVAIL;
-
- memcpy(dev->dev_addr, saddr->sa_data, ETH_ALEN);
- queue_work(mdev->workqueue, &priv->mac_task);
- return 0;
-}
-
-static void mlx4_en_do_set_mac(struct work_struct *work)
+static int mlx4_en_do_set_mac(struct mlx4_en_priv *priv)
{
- struct mlx4_en_priv *priv = container_of(work, struct mlx4_en_priv,
- mac_task);
- struct mlx4_en_dev *mdev = priv->mdev;
int err = 0;
- mutex_lock(&mdev->state_lock);
if (priv->port_up) {
/* Remove old MAC and insert the new one */
err = mlx4_en_replace_mac(priv, priv->base_qpn,
@@ -683,7 +669,26 @@ static void mlx4_en_do_set_mac(struct work_struct *work)
} else
en_dbg(HW, priv, "Port is down while registering mac, exiting...\n");
+ return err;
+}
+
+static int mlx4_en_set_mac(struct net_device *dev, void *addr)
+{
+ struct mlx4_en_priv *priv = netdev_priv(dev);
+ struct mlx4_en_dev *mdev = priv->mdev;
+ struct sockaddr *saddr = addr;
+ int err;
+
+ if (!is_valid_ether_addr(saddr->sa_data))
+ return -EADDRNOTAVAIL;
+
+ memcpy(dev->dev_addr, saddr->sa_data, ETH_ALEN);
+
+ mutex_lock(&mdev->state_lock);
+ err = mlx4_en_do_set_mac(priv);
mutex_unlock(&mdev->state_lock);
+
+ return err;
}
static void mlx4_en_clear_list(struct net_device *dev)
@@ -1348,7 +1353,7 @@ static void mlx4_en_do_get_stats(struct work_struct *work)
queue_delayed_work(mdev->workqueue, &priv->stats_task, STATS_DELAY);
}
if (mdev->mac_removed[MLX4_MAX_PORTS + 1 - priv->port]) {
- queue_work(mdev->workqueue, &priv->mac_task);
+ mlx4_en_do_set_mac(priv);
mdev->mac_removed[MLX4_MAX_PORTS + 1 - priv->port] = 0;
}
mutex_unlock(&mdev->state_lock);
@@ -1828,9 +1833,11 @@ int mlx4_en_alloc_resources(struct mlx4_en_priv *priv)
}
#ifdef CONFIG_RFS_ACCEL
- priv->dev->rx_cpu_rmap = alloc_irq_cpu_rmap(priv->mdev->dev->caps.comp_pool);
- if (!priv->dev->rx_cpu_rmap)
- goto err;
+ if (priv->mdev->dev->caps.comp_pool) {
+ priv->dev->rx_cpu_rmap = alloc_irq_cpu_rmap(priv->mdev->dev->caps.comp_pool);
+ if (!priv->dev->rx_cpu_rmap)
+ goto err;
+ }
#endif
return 0;
@@ -2078,7 +2085,6 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
priv->msg_enable = MLX4_EN_MSG_LEVEL;
spin_lock_init(&priv->stats_lock);
INIT_WORK(&priv->rx_mode_task, mlx4_en_do_set_rx_mode);
- INIT_WORK(&priv->mac_task, mlx4_en_do_set_mac);
INIT_WORK(&priv->watchdog_task, mlx4_en_restart);
INIT_WORK(&priv->linkstate_task, mlx4_en_linkstate);
INIT_DELAYED_WORK(&priv->stats_task, mlx4_en_do_get_stats);
diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.c b/drivers/net/ethernet/mellanox/mlx4/fw.c
index 50917eb3013e..f6245579962d 100644
--- a/drivers/net/ethernet/mellanox/mlx4/fw.c
+++ b/drivers/net/ethernet/mellanox/mlx4/fw.c
@@ -787,6 +787,14 @@ int mlx4_QUERY_DEV_CAP_wrapper(struct mlx4_dev *dev, int slave,
bmme_flags &= ~MLX4_BMME_FLAG_TYPE_2_WIN;
MLX4_PUT(outbox->buf, bmme_flags, QUERY_DEV_CAP_BMME_FLAGS_OFFSET);
+ /* turn off device-managed steering capability if not enabled */
+ if (dev->caps.steering_mode != MLX4_STEERING_MODE_DEVICE_MANAGED) {
+ MLX4_GET(field, outbox->buf,
+ QUERY_DEV_CAP_FLOW_STEERING_RANGE_EN_OFFSET);
+ field &= 0x7f;
+ MLX4_PUT(outbox->buf, field,
+ QUERY_DEV_CAP_FLOW_STEERING_RANGE_EN_OFFSET);
+ }
return 0;
}
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c
index d180bc46826a..16abde20e1fc 100644
--- a/drivers/net/ethernet/mellanox/mlx4/main.c
+++ b/drivers/net/ethernet/mellanox/mlx4/main.c
@@ -1555,7 +1555,7 @@ void __mlx4_counter_free(struct mlx4_dev *dev, u32 idx)
void mlx4_counter_free(struct mlx4_dev *dev, u32 idx)
{
- u64 in_param;
+ u64 in_param = 0;
if (mlx4_is_mfunc(dev)) {
set_param_l(&in_param, idx);
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
index cf883345af88..d738454116a0 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
@@ -1235,7 +1235,7 @@ int mlx4_get_qp_per_mgm(struct mlx4_dev *dev);
static inline void set_param_l(u64 *arg, u32 val)
{
- *((u32 *)arg) = val;
+ *arg = (*arg & 0xffffffff00000000ULL) | (u64) val;
}
static inline void set_param_h(u64 *arg, u32 val)
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
index c313d7e943a9..f710b7ce0dcb 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
@@ -509,7 +509,6 @@ struct mlx4_en_priv {
struct mlx4_en_cq rx_cq[MAX_RX_RINGS];
struct mlx4_qp drop_qp;
struct work_struct rx_mode_task;
- struct work_struct mac_task;
struct work_struct watchdog_task;
struct work_struct linkstate_task;
struct delayed_work stats_task;
diff --git a/drivers/net/ethernet/mellanox/mlx4/mr.c b/drivers/net/ethernet/mellanox/mlx4/mr.c
index 602ca9bf78e4..f91719a08cba 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mr.c
+++ b/drivers/net/ethernet/mellanox/mlx4/mr.c
@@ -183,7 +183,7 @@ u32 __mlx4_alloc_mtt_range(struct mlx4_dev *dev, int order)
static u32 mlx4_alloc_mtt_range(struct mlx4_dev *dev, int order)
{
- u64 in_param;
+ u64 in_param = 0;
u64 out_param;
int err;
@@ -240,7 +240,7 @@ void __mlx4_free_mtt_range(struct mlx4_dev *dev, u32 offset, int order)
static void mlx4_free_mtt_range(struct mlx4_dev *dev, u32 offset, int order)
{
- u64 in_param;
+ u64 in_param = 0;
int err;
if (mlx4_is_mfunc(dev)) {
@@ -351,7 +351,7 @@ void __mlx4_mpt_release(struct mlx4_dev *dev, u32 index)
static void mlx4_mpt_release(struct mlx4_dev *dev, u32 index)
{
- u64 in_param;
+ u64 in_param = 0;
if (mlx4_is_mfunc(dev)) {
set_param_l(&in_param, index);
@@ -374,7 +374,7 @@ int __mlx4_mpt_alloc_icm(struct mlx4_dev *dev, u32 index)
static int mlx4_mpt_alloc_icm(struct mlx4_dev *dev, u32 index)
{
- u64 param;
+ u64 param = 0;
if (mlx4_is_mfunc(dev)) {
set_param_l(&param, index);
@@ -395,7 +395,7 @@ void __mlx4_mpt_free_icm(struct mlx4_dev *dev, u32 index)
static void mlx4_mpt_free_icm(struct mlx4_dev *dev, u32 index)
{
- u64 in_param;
+ u64 in_param = 0;
if (mlx4_is_mfunc(dev)) {
set_param_l(&in_param, index);
diff --git a/drivers/net/ethernet/mellanox/mlx4/pd.c b/drivers/net/ethernet/mellanox/mlx4/pd.c
index 1ac88637ad9d..00f223acada7 100644
--- a/drivers/net/ethernet/mellanox/mlx4/pd.c
+++ b/drivers/net/ethernet/mellanox/mlx4/pd.c
@@ -101,7 +101,7 @@ void __mlx4_xrcd_free(struct mlx4_dev *dev, u32 xrcdn)
void mlx4_xrcd_free(struct mlx4_dev *dev, u32 xrcdn)
{
- u64 in_param;
+ u64 in_param = 0;
int err;
if (mlx4_is_mfunc(dev)) {
diff --git a/drivers/net/ethernet/mellanox/mlx4/port.c b/drivers/net/ethernet/mellanox/mlx4/port.c
index 719ead15e491..10c57c86388b 100644
--- a/drivers/net/ethernet/mellanox/mlx4/port.c
+++ b/drivers/net/ethernet/mellanox/mlx4/port.c
@@ -175,7 +175,7 @@ EXPORT_SYMBOL_GPL(__mlx4_register_mac);
int mlx4_register_mac(struct mlx4_dev *dev, u8 port, u64 mac)
{
- u64 out_param;
+ u64 out_param = 0;
int err;
if (mlx4_is_mfunc(dev)) {
@@ -222,7 +222,7 @@ EXPORT_SYMBOL_GPL(__mlx4_unregister_mac);
void mlx4_unregister_mac(struct mlx4_dev *dev, u8 port, u64 mac)
{
- u64 out_param;
+ u64 out_param = 0;
if (mlx4_is_mfunc(dev)) {
set_param_l(&out_param, port);
@@ -361,7 +361,7 @@ out:
int mlx4_register_vlan(struct mlx4_dev *dev, u8 port, u16 vlan, int *index)
{
- u64 out_param;
+ u64 out_param = 0;
int err;
if (mlx4_is_mfunc(dev)) {
@@ -406,7 +406,7 @@ out:
void mlx4_unregister_vlan(struct mlx4_dev *dev, u8 port, int index)
{
- u64 in_param;
+ u64 in_param = 0;
int err;
if (mlx4_is_mfunc(dev)) {
diff --git a/drivers/net/ethernet/mellanox/mlx4/qp.c b/drivers/net/ethernet/mellanox/mlx4/qp.c
index 81e2abe07bbb..e891b058c1be 100644
--- a/drivers/net/ethernet/mellanox/mlx4/qp.c
+++ b/drivers/net/ethernet/mellanox/mlx4/qp.c
@@ -222,7 +222,7 @@ int __mlx4_qp_reserve_range(struct mlx4_dev *dev, int cnt, int align,
int mlx4_qp_reserve_range(struct mlx4_dev *dev, int cnt, int align, int *base)
{
- u64 in_param;
+ u64 in_param = 0;
u64 out_param;
int err;
@@ -255,7 +255,7 @@ void __mlx4_qp_release_range(struct mlx4_dev *dev, int base_qpn, int cnt)
void mlx4_qp_release_range(struct mlx4_dev *dev, int base_qpn, int cnt)
{
- u64 in_param;
+ u64 in_param = 0;
int err;
if (mlx4_is_mfunc(dev)) {
@@ -319,7 +319,7 @@ err_out:
static int mlx4_qp_alloc_icm(struct mlx4_dev *dev, int qpn)
{
- u64 param;
+ u64 param = 0;
if (mlx4_is_mfunc(dev)) {
set_param_l(&param, qpn);
@@ -344,7 +344,7 @@ void __mlx4_qp_free_icm(struct mlx4_dev *dev, int qpn)
static void mlx4_qp_free_icm(struct mlx4_dev *dev, int qpn)
{
- u64 in_param;
+ u64 in_param = 0;
if (mlx4_is_mfunc(dev)) {
set_param_l(&in_param, qpn);
diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
index 083fb48dc3d7..2995687f1aee 100644
--- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
+++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
@@ -2990,6 +2990,9 @@ int mlx4_QP_ATTACH_wrapper(struct mlx4_dev *dev, int slave,
u8 steer_type_mask = 2;
enum mlx4_steer_type type = (gid[7] & steer_type_mask) >> 1;
+ if (dev->caps.steering_mode != MLX4_STEERING_MODE_B0)
+ return -EINVAL;
+
qpn = vhcr->in_modifier & 0xffffff;
err = get_res(dev, slave, qpn, RES_QP, &rqp);
if (err)
diff --git a/drivers/net/ethernet/mellanox/mlx4/srq.c b/drivers/net/ethernet/mellanox/mlx4/srq.c
index feda6c00829f..e329fe1f11b7 100644
--- a/drivers/net/ethernet/mellanox/mlx4/srq.c
+++ b/drivers/net/ethernet/mellanox/mlx4/srq.c
@@ -149,7 +149,7 @@ void __mlx4_srq_free_icm(struct mlx4_dev *dev, int srqn)
static void mlx4_srq_free_icm(struct mlx4_dev *dev, int srqn)
{
- u64 in_param;
+ u64 in_param = 0;
if (mlx4_is_mfunc(dev)) {
set_param_l(&in_param, srqn);
diff --git a/drivers/net/ethernet/sfc/efx.h b/drivers/net/ethernet/sfc/efx.h
index 50247dfe8f57..d2f790df6dcb 100644
--- a/drivers/net/ethernet/sfc/efx.h
+++ b/drivers/net/ethernet/sfc/efx.h
@@ -171,9 +171,9 @@ static inline void efx_device_detach_sync(struct efx_nic *efx)
* TX scheduler is stopped when we're done and before
* netif_device_present() becomes false.
*/
- netif_tx_lock(dev);
+ netif_tx_lock_bh(dev);
netif_device_detach(dev);
- netif_tx_unlock(dev);
+ netif_tx_unlock_bh(dev);
}
#endif /* EFX_EFX_H */
diff --git a/drivers/net/ethernet/sfc/rx.c b/drivers/net/ethernet/sfc/rx.c
index 879ff5849bbd..bb579a6128c8 100644
--- a/drivers/net/ethernet/sfc/rx.c
+++ b/drivers/net/ethernet/sfc/rx.c
@@ -215,7 +215,7 @@ static int efx_init_rx_buffers_page(struct efx_rx_queue *rx_queue)
rx_buf = efx_rx_buffer(rx_queue, index);
rx_buf->dma_addr = dma_addr + EFX_PAGE_IP_ALIGN;
rx_buf->u.page = page;
- rx_buf->page_offset = page_offset;
+ rx_buf->page_offset = page_offset + EFX_PAGE_IP_ALIGN;
rx_buf->len = efx->rx_buffer_len - EFX_PAGE_IP_ALIGN;
rx_buf->flags = EFX_RX_BUF_PAGE;
++rx_queue->added_count;
diff --git a/drivers/net/hippi/rrunner.c b/drivers/net/hippi/rrunner.c
index e5b19b056909..3c4d6274bb9b 100644
--- a/drivers/net/hippi/rrunner.c
+++ b/drivers/net/hippi/rrunner.c
@@ -202,6 +202,9 @@ static int rr_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
return 0;
out:
+ if (rrpriv->evt_ring)
+ pci_free_consistent(pdev, EVT_RING_SIZE, rrpriv->evt_ring,
+ rrpriv->evt_ring_dma);
if (rrpriv->rx_ring)
pci_free_consistent(pdev, RX_TOTAL_SIZE, rrpriv->rx_ring,
rrpriv->rx_ring_dma);
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index 417b2af1aa80..73abbc1655d5 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -660,6 +660,7 @@ void macvlan_common_setup(struct net_device *dev)
ether_setup(dev);
dev->priv_flags &= ~(IFF_XMIT_DST_RELEASE | IFF_TX_SKB_SHARING);
+ dev->priv_flags |= IFF_UNICAST_FLT;
dev->netdev_ops = &macvlan_netdev_ops;
dev->destructor = free_netdev;
dev->header_ops = &macvlan_hard_header_ops,
diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c
index 05c5efe84591..bf3419297875 100644
--- a/drivers/net/team/team.c
+++ b/drivers/net/team/team.c
@@ -1138,6 +1138,8 @@ static int team_port_del(struct team *team, struct net_device *port_dev)
netdev_upper_dev_unlink(port_dev, dev);
team_port_disable_netpoll(port);
vlan_vids_del_by_dev(port_dev, dev);
+ dev_uc_unsync(port_dev, dev);
+ dev_mc_unsync(port_dev, dev);
dev_close(port_dev);
team_port_leave(team, port);
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 2c6a22e278ea..b7c457adc0dc 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -747,6 +747,8 @@ static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev)
goto drop;
skb_orphan(skb);
+ nf_reset(skb);
+
/* Enqueue packet */
skb_queue_tail(&tfile->socket.sk->sk_receive_queue, skb);
diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c
index 4aad350e4dae..eae7a03d4f9b 100644
--- a/drivers/net/vmxnet3/vmxnet3_drv.c
+++ b/drivers/net/vmxnet3/vmxnet3_drv.c
@@ -2958,6 +2958,7 @@ vmxnet3_probe_device(struct pci_dev *pdev,
adapter->num_rx_queues = num_rx_queues;
adapter->num_tx_queues = num_tx_queues;
+ adapter->rx_buf_per_pkt = 1;
size = sizeof(struct Vmxnet3_TxQueueDesc) * adapter->num_tx_queues;
size += sizeof(struct Vmxnet3_RxQueueDesc) * adapter->num_rx_queues;
diff --git a/drivers/net/vmxnet3/vmxnet3_ethtool.c b/drivers/net/vmxnet3/vmxnet3_ethtool.c
index a0feb17a0238..63a124340cbe 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethtool.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethtool.c
@@ -472,6 +472,12 @@ vmxnet3_set_ringparam(struct net_device *netdev,
VMXNET3_RX_RING_MAX_SIZE)
return -EINVAL;
+ /* if adapter not yet initialized, do nothing */
+ if (adapter->rx_buf_per_pkt == 0) {
+ netdev_err(netdev, "adapter not completely initialized, "
+ "ring size cannot be changed yet\n");
+ return -EOPNOTSUPP;
+ }
/* round it up to a multiple of VMXNET3_RING_SIZE_ALIGN */
new_tx_ring_size = (param->tx_pending + VMXNET3_RING_SIZE_MASK) &
diff --git a/drivers/net/vmxnet3/vmxnet3_int.h b/drivers/net/vmxnet3/vmxnet3_int.h
index 3198384689d9..35418146fa17 100644
--- a/drivers/net/vmxnet3/vmxnet3_int.h
+++ b/drivers/net/vmxnet3/vmxnet3_int.h
@@ -70,10 +70,10 @@
/*
* Version numbers
*/
-#define VMXNET3_DRIVER_VERSION_STRING "1.1.29.0-k"
+#define VMXNET3_DRIVER_VERSION_STRING "1.1.30.0-k"
/* a 32-bit int, each byte encode a verion number in VMXNET3_DRIVER_VERSION */
-#define VMXNET3_DRIVER_VERSION_NUM 0x01011D00
+#define VMXNET3_DRIVER_VERSION_NUM 0x01011E00
#if defined(CONFIG_PCI_MSI)
/* RSS only makes sense if MSI-X is supported. */
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index f10e58ac9c1b..7cee7a3068ec 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -961,6 +961,8 @@ static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct net_device *dev)
iph->ttl = ttl ? : ip4_dst_hoplimit(&rt->dst);
tunnel_ip_select_ident(skb, old_iph, &rt->dst);
+ nf_reset(skb);
+
vxlan_set_owner(dev, skb);
/* See iptunnel_xmit() */
@@ -1504,6 +1506,14 @@ static __net_init int vxlan_init_net(struct net *net)
static __net_exit void vxlan_exit_net(struct net *net)
{
struct vxlan_net *vn = net_generic(net, vxlan_net_id);
+ struct vxlan_dev *vxlan;
+ unsigned h;
+
+ rtnl_lock();
+ for (h = 0; h < VNI_HASH_SIZE; ++h)
+ hlist_for_each_entry(vxlan, &vn->vni_list[h], hlist)
+ dev_close(vxlan->dev);
+ rtnl_unlock();
if (vn->sock) {
sk_release_kernel(vn->sock->sk);
diff --git a/drivers/net/wireless/iwlwifi/dvm/sta.c b/drivers/net/wireless/iwlwifi/dvm/sta.c
index 94ef33838bc6..b775769f8322 100644
--- a/drivers/net/wireless/iwlwifi/dvm/sta.c
+++ b/drivers/net/wireless/iwlwifi/dvm/sta.c
@@ -151,7 +151,7 @@ int iwl_send_add_sta(struct iwl_priv *priv,
sta_id, sta->sta.addr, flags & CMD_ASYNC ? "a" : "");
if (!(flags & CMD_ASYNC)) {
- cmd.flags |= CMD_WANT_SKB | CMD_WANT_HCMD;
+ cmd.flags |= CMD_WANT_SKB;
might_sleep();
}
diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.h b/drivers/net/wireless/iwlwifi/iwl-devtrace.h
index 10f01793d7a6..81aa91fab5aa 100644
--- a/drivers/net/wireless/iwlwifi/iwl-devtrace.h
+++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.h
@@ -363,7 +363,7 @@ TRACE_EVENT(iwlwifi_dev_hcmd,
__entry->flags = cmd->flags;
memcpy(__get_dynamic_array(hcmd), hdr, sizeof(*hdr));
- for (i = 0; i < IWL_MAX_CMD_TFDS; i++) {
+ for (i = 0; i < IWL_MAX_CMD_TBS_PER_TFD; i++) {
if (!cmd->len[i])
continue;
memcpy((u8 *)__get_dynamic_array(hcmd) + offset,
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c
index 6f228bb2b844..fbfd2d137117 100644
--- a/drivers/net/wireless/iwlwifi/iwl-drv.c
+++ b/drivers/net/wireless/iwlwifi/iwl-drv.c
@@ -1102,7 +1102,6 @@ void iwl_drv_stop(struct iwl_drv *drv)
/* shared module parameters */
struct iwl_mod_params iwlwifi_mod_params = {
- .amsdu_size_8K = 1,
.restart_fw = 1,
.plcp_check = true,
.bt_coex_active = true,
@@ -1207,7 +1206,7 @@ MODULE_PARM_DESC(11n_disable,
"disable 11n functionality, bitmap: 1: full, 2: agg TX, 4: agg RX");
module_param_named(amsdu_size_8K, iwlwifi_mod_params.amsdu_size_8K,
int, S_IRUGO);
-MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size");
+MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size (default 0)");
module_param_named(fw_restart, iwlwifi_mod_params.restart_fw, int, S_IRUGO);
MODULE_PARM_DESC(fw_restart, "restart firmware in case of error");
diff --git a/drivers/net/wireless/iwlwifi/iwl-modparams.h b/drivers/net/wireless/iwlwifi/iwl-modparams.h
index e5e3a79eae2f..2c2a729092f5 100644
--- a/drivers/net/wireless/iwlwifi/iwl-modparams.h
+++ b/drivers/net/wireless/iwlwifi/iwl-modparams.h
@@ -91,7 +91,7 @@ enum iwl_power_level {
* @sw_crypto: using hardware encryption, default = 0
* @disable_11n: disable 11n capabilities, default = 0,
* use IWL_DISABLE_HT_* constants
- * @amsdu_size_8K: enable 8K amsdu size, default = 1
+ * @amsdu_size_8K: enable 8K amsdu size, default = 0
* @restart_fw: restart firmware, default = 1
* @plcp_check: enable plcp health check, default = true
* @wd_disable: enable stuck queue check, default = 0
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h
index 8c7bec6b9a0b..0cac2b7af78b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/iwlwifi/iwl-trans.h
@@ -186,19 +186,13 @@ struct iwl_rx_packet {
* @CMD_ASYNC: Return right away and don't want for the response
* @CMD_WANT_SKB: valid only with CMD_SYNC. The caller needs the buffer of the
* response. The caller needs to call iwl_free_resp when done.
- * @CMD_WANT_HCMD: The caller needs to get the HCMD that was sent in the
- * response handler. Chunks flagged by %IWL_HCMD_DFL_NOCOPY won't be
- * copied. The pointer passed to the response handler is in the transport
- * ownership and don't need to be freed by the op_mode. This also means
- * that the pointer is invalidated after the op_mode's handler returns.
* @CMD_ON_DEMAND: This command is sent by the test mode pipe.
*/
enum CMD_MODE {
CMD_SYNC = 0,
CMD_ASYNC = BIT(0),
CMD_WANT_SKB = BIT(1),
- CMD_WANT_HCMD = BIT(2),
- CMD_ON_DEMAND = BIT(3),
+ CMD_ON_DEMAND = BIT(2),
};
#define DEF_CMD_PAYLOAD_SIZE 320
@@ -217,7 +211,11 @@ struct iwl_device_cmd {
#define TFD_MAX_PAYLOAD_SIZE (sizeof(struct iwl_device_cmd))
-#define IWL_MAX_CMD_TFDS 2
+/*
+ * number of transfer buffers (fragments) per transmit frame descriptor;
+ * this is just the driver's idea, the hardware supports 20
+ */
+#define IWL_MAX_CMD_TBS_PER_TFD 2
/**
* struct iwl_hcmd_dataflag - flag for each one of the chunks of the command
@@ -254,15 +252,15 @@ enum iwl_hcmd_dataflag {
* @id: id of the host command
*/
struct iwl_host_cmd {
- const void *data[IWL_MAX_CMD_TFDS];
+ const void *data[IWL_MAX_CMD_TBS_PER_TFD];
struct iwl_rx_packet *resp_pkt;
unsigned long _rx_page_addr;
u32 _rx_page_order;
int handler_status;
u32 flags;
- u16 len[IWL_MAX_CMD_TFDS];
- u8 dataflags[IWL_MAX_CMD_TFDS];
+ u16 len[IWL_MAX_CMD_TBS_PER_TFD];
+ u8 dataflags[IWL_MAX_CMD_TBS_PER_TFD];
u8 id;
};
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
index 23eebda848b0..2adb61f103f4 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
@@ -762,18 +762,20 @@ struct iwl_phy_context_cmd {
#define IWL_RX_INFO_PHY_CNT 8
#define IWL_RX_INFO_AGC_IDX 1
#define IWL_RX_INFO_RSSI_AB_IDX 2
-#define IWL_RX_INFO_RSSI_C_IDX 3
-#define IWL_OFDM_AGC_DB_MSK 0xfe00
-#define IWL_OFDM_AGC_DB_POS 9
+#define IWL_OFDM_AGC_A_MSK 0x0000007f
+#define IWL_OFDM_AGC_A_POS 0
+#define IWL_OFDM_AGC_B_MSK 0x00003f80
+#define IWL_OFDM_AGC_B_POS 7
+#define IWL_OFDM_AGC_CODE_MSK 0x3fe00000
+#define IWL_OFDM_AGC_CODE_POS 20
#define IWL_OFDM_RSSI_INBAND_A_MSK 0x00ff
-#define IWL_OFDM_RSSI_ALLBAND_A_MSK 0xff00
#define IWL_OFDM_RSSI_A_POS 0
+#define IWL_OFDM_RSSI_ALLBAND_A_MSK 0xff00
+#define IWL_OFDM_RSSI_ALLBAND_A_POS 8
#define IWL_OFDM_RSSI_INBAND_B_MSK 0xff0000
-#define IWL_OFDM_RSSI_ALLBAND_B_MSK 0xff000000
#define IWL_OFDM_RSSI_B_POS 16
-#define IWL_OFDM_RSSI_INBAND_C_MSK 0x00ff
-#define IWL_OFDM_RSSI_ALLBAND_C_MSK 0xff00
-#define IWL_OFDM_RSSI_C_POS 0
+#define IWL_OFDM_RSSI_ALLBAND_B_MSK 0xff000000
+#define IWL_OFDM_RSSI_ALLBAND_B_POS 24
/**
* struct iwl_rx_phy_info - phy info
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw.c b/drivers/net/wireless/iwlwifi/mvm/fw.c
index d3d959db03a9..500f818dba04 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw.c
+++ b/drivers/net/wireless/iwlwifi/mvm/fw.c
@@ -79,17 +79,8 @@
#define UCODE_VALID_OK cpu_to_le32(0x1)
/* Default calibration values for WkP - set to INIT image w/o running */
-static const u8 wkp_calib_values_bb_filter[] = { 0xbf, 0x00, 0x5f, 0x00, 0x2f,
- 0x00, 0x18, 0x00 };
-static const u8 wkp_calib_values_rx_dc[] = { 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
- 0x7f, 0x7f, 0x7f };
-static const u8 wkp_calib_values_tx_lo[] = { 0x00, 0x00, 0x00, 0x00 };
-static const u8 wkp_calib_values_tx_iq[] = { 0xff, 0x00, 0xff, 0x00, 0x00,
- 0x00 };
-static const u8 wkp_calib_values_rx_iq[] = { 0xff, 0x00, 0x00, 0x00 };
static const u8 wkp_calib_values_rx_iq_skew[] = { 0x00, 0x00, 0x01, 0x00 };
static const u8 wkp_calib_values_tx_iq_skew[] = { 0x01, 0x00, 0x00, 0x00 };
-static const u8 wkp_calib_values_xtal[] = { 0xd2, 0xd2 };
struct iwl_calib_default_data {
u16 size;
@@ -99,12 +90,7 @@ struct iwl_calib_default_data {
#define CALIB_SIZE_N_DATA(_buf) {.size = sizeof(_buf), .data = &_buf}
static const struct iwl_calib_default_data wkp_calib_default_data[12] = {
- [5] = CALIB_SIZE_N_DATA(wkp_calib_values_rx_dc),
- [6] = CALIB_SIZE_N_DATA(wkp_calib_values_bb_filter),
- [7] = CALIB_SIZE_N_DATA(wkp_calib_values_tx_lo),
- [8] = CALIB_SIZE_N_DATA(wkp_calib_values_tx_iq),
[9] = CALIB_SIZE_N_DATA(wkp_calib_values_tx_iq_skew),
- [10] = CALIB_SIZE_N_DATA(wkp_calib_values_rx_iq),
[11] = CALIB_SIZE_N_DATA(wkp_calib_values_rx_iq_skew),
};
@@ -241,20 +227,6 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm,
return 0;
}
-#define IWL_HW_REV_ID_RAINBOW 0x2
-#define IWL_PROJ_TYPE_LHP 0x5
-
-static u32 iwl_mvm_build_phy_cfg(struct iwl_mvm *mvm)
-{
- struct iwl_nvm_data *data = mvm->nvm_data;
- /* Temp calls to static definitions, will be changed to CSR calls */
- u8 hw_rev_id = IWL_HW_REV_ID_RAINBOW;
- u8 project_type = IWL_PROJ_TYPE_LHP;
-
- return data->radio_cfg_dash | (data->radio_cfg_step << 2) |
- (hw_rev_id << 4) | ((project_type & 0x7f) << 6) |
- (data->valid_tx_ant << 16) | (data->valid_rx_ant << 20);
-}
static int iwl_send_phy_cfg_cmd(struct iwl_mvm *mvm)
{
@@ -262,7 +234,7 @@ static int iwl_send_phy_cfg_cmd(struct iwl_mvm *mvm)
enum iwl_ucode_type ucode_type = mvm->cur_ucode;
/* Set parameters */
- phy_cfg_cmd.phy_cfg = cpu_to_le32(iwl_mvm_build_phy_cfg(mvm));
+ phy_cfg_cmd.phy_cfg = cpu_to_le32(mvm->fw->phy_config);
phy_cfg_cmd.calib_control.event_trigger =
mvm->fw->default_calib[ucode_type].event_trigger;
phy_cfg_cmd.calib_control.flow_trigger =
@@ -275,103 +247,6 @@ static int iwl_send_phy_cfg_cmd(struct iwl_mvm *mvm)
sizeof(phy_cfg_cmd), &phy_cfg_cmd);
}
-/* Starting with the new PHY DB implementation - New calibs are enabled */
-/* Value - 0x405e7 */
-#define IWL_CALIB_DEFAULT_FLOW_INIT (IWL_CALIB_CFG_XTAL_IDX |\
- IWL_CALIB_CFG_TEMPERATURE_IDX |\
- IWL_CALIB_CFG_VOLTAGE_READ_IDX |\
- IWL_CALIB_CFG_DC_IDX |\
- IWL_CALIB_CFG_BB_FILTER_IDX |\
- IWL_CALIB_CFG_LO_LEAKAGE_IDX |\
- IWL_CALIB_CFG_TX_IQ_IDX |\
- IWL_CALIB_CFG_RX_IQ_IDX |\
- IWL_CALIB_CFG_AGC_IDX)
-
-#define IWL_CALIB_DEFAULT_EVENT_INIT 0x0
-
-/* Value 0x41567 */
-#define IWL_CALIB_DEFAULT_FLOW_RUN (IWL_CALIB_CFG_XTAL_IDX |\
- IWL_CALIB_CFG_TEMPERATURE_IDX |\
- IWL_CALIB_CFG_VOLTAGE_READ_IDX |\
- IWL_CALIB_CFG_BB_FILTER_IDX |\
- IWL_CALIB_CFG_DC_IDX |\
- IWL_CALIB_CFG_TX_IQ_IDX |\
- IWL_CALIB_CFG_RX_IQ_IDX |\
- IWL_CALIB_CFG_SENSITIVITY_IDX |\
- IWL_CALIB_CFG_AGC_IDX)
-
-#define IWL_CALIB_DEFAULT_EVENT_RUN (IWL_CALIB_CFG_XTAL_IDX |\
- IWL_CALIB_CFG_TEMPERATURE_IDX |\
- IWL_CALIB_CFG_VOLTAGE_READ_IDX |\
- IWL_CALIB_CFG_TX_PWR_IDX |\
- IWL_CALIB_CFG_DC_IDX |\
- IWL_CALIB_CFG_TX_IQ_IDX |\
- IWL_CALIB_CFG_SENSITIVITY_IDX)
-
-/*
- * Sets the calibrations trigger values that will be sent to the FW for runtime
- * and init calibrations.
- * The ones given in the FW TLV are not correct.
- */
-static void iwl_set_default_calib_trigger(struct iwl_mvm *mvm)
-{
- struct iwl_tlv_calib_ctrl default_calib;
-
- /*
- * WkP FW TLV calib bits are wrong, overwrite them.
- * This defines the dynamic calibrations which are implemented in the
- * uCode both for init(flow) calculation and event driven calibs.
- */
-
- /* Init Image */
- default_calib.event_trigger = cpu_to_le32(IWL_CALIB_DEFAULT_EVENT_INIT);
- default_calib.flow_trigger = cpu_to_le32(IWL_CALIB_DEFAULT_FLOW_INIT);
-
- if (default_calib.event_trigger !=
- mvm->fw->default_calib[IWL_UCODE_INIT].event_trigger)
- IWL_ERR(mvm,
- "Updating the event calib for INIT image: 0x%x -> 0x%x\n",
- mvm->fw->default_calib[IWL_UCODE_INIT].event_trigger,
- default_calib.event_trigger);
- if (default_calib.flow_trigger !=
- mvm->fw->default_calib[IWL_UCODE_INIT].flow_trigger)
- IWL_ERR(mvm,
- "Updating the flow calib for INIT image: 0x%x -> 0x%x\n",
- mvm->fw->default_calib[IWL_UCODE_INIT].flow_trigger,
- default_calib.flow_trigger);
-
- memcpy((void *)&mvm->fw->default_calib[IWL_UCODE_INIT],
- &default_calib, sizeof(struct iwl_tlv_calib_ctrl));
- IWL_ERR(mvm,
- "Setting uCode init calibrations event 0x%x, trigger 0x%x\n",
- default_calib.event_trigger,
- default_calib.flow_trigger);
-
- /* Run time image */
- default_calib.event_trigger = cpu_to_le32(IWL_CALIB_DEFAULT_EVENT_RUN);
- default_calib.flow_trigger = cpu_to_le32(IWL_CALIB_DEFAULT_FLOW_RUN);
-
- if (default_calib.event_trigger !=
- mvm->fw->default_calib[IWL_UCODE_REGULAR].event_trigger)
- IWL_ERR(mvm,
- "Updating the event calib for RT image: 0x%x -> 0x%x\n",
- mvm->fw->default_calib[IWL_UCODE_REGULAR].event_trigger,
- default_calib.event_trigger);
- if (default_calib.flow_trigger !=
- mvm->fw->default_calib[IWL_UCODE_REGULAR].flow_trigger)
- IWL_ERR(mvm,
- "Updating the flow calib for RT image: 0x%x -> 0x%x\n",
- mvm->fw->default_calib[IWL_UCODE_REGULAR].flow_trigger,
- default_calib.flow_trigger);
-
- memcpy((void *)&mvm->fw->default_calib[IWL_UCODE_REGULAR],
- &default_calib, sizeof(struct iwl_tlv_calib_ctrl));
- IWL_ERR(mvm,
- "Setting uCode runtime calibs event 0x%x, trigger 0x%x\n",
- default_calib.event_trigger,
- default_calib.flow_trigger);
-}
-
static int iwl_set_default_calibrations(struct iwl_mvm *mvm)
{
u8 cmd_raw[16]; /* holds the variable size commands */
@@ -446,8 +321,10 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
ret = iwl_nvm_check_version(mvm->nvm_data, mvm->trans);
WARN_ON(ret);
- /* Override the calibrations from TLV and the const of fw */
- iwl_set_default_calib_trigger(mvm);
+ /* Send TX valid antennas before triggering calibrations */
+ ret = iwl_send_tx_ant_cfg(mvm, mvm->nvm_data->valid_tx_ant);
+ if (ret)
+ goto error;
/* WkP doesn't have all calibrations, need to set default values */
if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) {
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h
index 537711b10478..bdae700c769e 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h
@@ -80,7 +80,8 @@
#define IWL_INVALID_MAC80211_QUEUE 0xff
#define IWL_MVM_MAX_ADDRESSES 2
-#define IWL_RSSI_OFFSET 44
+/* RSSI offset for WkP */
+#define IWL_RSSI_OFFSET 50
enum iwl_mvm_tx_fifo {
IWL_MVM_TX_FIFO_BK = 0,
diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c
index aa59adf87db3..d0f9c1e0475e 100644
--- a/drivers/net/wireless/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/iwlwifi/mvm/ops.c
@@ -624,12 +624,8 @@ static void iwl_mvm_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb)
ieee80211_free_txskb(mvm->hw, skb);
}
-static void iwl_mvm_nic_error(struct iwl_op_mode *op_mode)
+static void iwl_mvm_nic_restart(struct iwl_mvm *mvm)
{
- struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
-
- iwl_mvm_dump_nic_error_log(mvm);
-
iwl_abort_notification_waits(&mvm->notif_wait);
/*
@@ -663,9 +659,21 @@ static void iwl_mvm_nic_error(struct iwl_op_mode *op_mode)
}
}
+static void iwl_mvm_nic_error(struct iwl_op_mode *op_mode)
+{
+ struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
+
+ iwl_mvm_dump_nic_error_log(mvm);
+
+ iwl_mvm_nic_restart(mvm);
+}
+
static void iwl_mvm_cmd_queue_full(struct iwl_op_mode *op_mode)
{
+ struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
+
WARN_ON(1);
+ iwl_mvm_nic_restart(mvm);
}
static const struct iwl_op_mode_ops iwl_mvm_ops = {
diff --git a/drivers/net/wireless/iwlwifi/mvm/rx.c b/drivers/net/wireless/iwlwifi/mvm/rx.c
index 3f40ab05bbd8..b0b190d0ec23 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rx.c
+++ b/drivers/net/wireless/iwlwifi/mvm/rx.c
@@ -131,33 +131,42 @@ static void iwl_mvm_pass_packet_to_mac80211(struct iwl_mvm *mvm,
static int iwl_mvm_calc_rssi(struct iwl_mvm *mvm,
struct iwl_rx_phy_info *phy_info)
{
- u32 rssi_a, rssi_b, rssi_c, max_rssi, agc_db;
+ int rssi_a, rssi_b, rssi_a_dbm, rssi_b_dbm, max_rssi_dbm;
+ int rssi_all_band_a, rssi_all_band_b;
+ u32 agc_a, agc_b, max_agc;
u32 val;
- /* Find max rssi among 3 possible receivers.
+ /* Find max rssi among 2 possible receivers.
* These values are measured by the Digital Signal Processor (DSP).
* They should stay fairly constant even as the signal strength varies,
* if the radio's Automatic Gain Control (AGC) is working right.
* AGC value (see below) will provide the "interesting" info.
*/
+ val = le32_to_cpu(phy_info->non_cfg_phy[IWL_RX_INFO_AGC_IDX]);
+ agc_a = (val & IWL_OFDM_AGC_A_MSK) >> IWL_OFDM_AGC_A_POS;
+ agc_b = (val & IWL_OFDM_AGC_B_MSK) >> IWL_OFDM_AGC_B_POS;
+ max_agc = max_t(u32, agc_a, agc_b);
+
val = le32_to_cpu(phy_info->non_cfg_phy[IWL_RX_INFO_RSSI_AB_IDX]);
rssi_a = (val & IWL_OFDM_RSSI_INBAND_A_MSK) >> IWL_OFDM_RSSI_A_POS;
rssi_b = (val & IWL_OFDM_RSSI_INBAND_B_MSK) >> IWL_OFDM_RSSI_B_POS;
- val = le32_to_cpu(phy_info->non_cfg_phy[IWL_RX_INFO_RSSI_C_IDX]);
- rssi_c = (val & IWL_OFDM_RSSI_INBAND_C_MSK) >> IWL_OFDM_RSSI_C_POS;
-
- val = le32_to_cpu(phy_info->non_cfg_phy[IWL_RX_INFO_AGC_IDX]);
- agc_db = (val & IWL_OFDM_AGC_DB_MSK) >> IWL_OFDM_AGC_DB_POS;
+ rssi_all_band_a = (val & IWL_OFDM_RSSI_ALLBAND_A_MSK) >>
+ IWL_OFDM_RSSI_ALLBAND_A_POS;
+ rssi_all_band_b = (val & IWL_OFDM_RSSI_ALLBAND_B_MSK) >>
+ IWL_OFDM_RSSI_ALLBAND_B_POS;
- max_rssi = max_t(u32, rssi_a, rssi_b);
- max_rssi = max_t(u32, max_rssi, rssi_c);
+ /*
+ * dBm = rssi dB - agc dB - constant.
+ * Higher AGC (higher radio gain) means lower signal.
+ */
+ rssi_a_dbm = rssi_a - IWL_RSSI_OFFSET - agc_a;
+ rssi_b_dbm = rssi_b - IWL_RSSI_OFFSET - agc_b;
+ max_rssi_dbm = max_t(int, rssi_a_dbm, rssi_b_dbm);
- IWL_DEBUG_STATS(mvm, "Rssi In A %d B %d C %d Max %d AGC dB %d\n",
- rssi_a, rssi_b, rssi_c, max_rssi, agc_db);
+ IWL_DEBUG_STATS(mvm, "Rssi In A %d B %d Max %d AGCA %d AGCB %d\n",
+ rssi_a_dbm, rssi_b_dbm, max_rssi_dbm, agc_a, agc_b);
- /* dBm = max_rssi dB - agc dB - constant.
- * Higher AGC (higher radio gain) means lower signal. */
- return max_rssi - agc_db - IWL_RSSI_OFFSET;
+ return max_rssi_dbm;
}
/*
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c
index 861a7f9f8e7f..274f44e2ef60 100644
--- a/drivers/net/wireless/iwlwifi/mvm/sta.c
+++ b/drivers/net/wireless/iwlwifi/mvm/sta.c
@@ -770,6 +770,16 @@ int iwl_mvm_sta_tx_agg_stop(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
u16 txq_id;
int err;
+
+ /*
+ * If mac80211 is cleaning its state, then say that we finished since
+ * our state has been cleared anyway.
+ */
+ if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) {
+ ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
+ return 0;
+ }
+
spin_lock_bh(&mvmsta->lock);
txq_id = tid_data->txq_id;
diff --git a/drivers/net/wireless/iwlwifi/mvm/tx.c b/drivers/net/wireless/iwlwifi/mvm/tx.c
index 6b67ce3f679c..6645efe5c03e 100644
--- a/drivers/net/wireless/iwlwifi/mvm/tx.c
+++ b/drivers/net/wireless/iwlwifi/mvm/tx.c
@@ -607,12 +607,8 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
/* Single frame failure in an AMPDU queue => send BAR */
if (txq_id >= IWL_FIRST_AMPDU_QUEUE &&
- !(info->flags & IEEE80211_TX_STAT_ACK)) {
- /* there must be only one skb in the skb_list */
- WARN_ON_ONCE(skb_freed > 1 ||
- !skb_queue_empty(&skbs));
+ !(info->flags & IEEE80211_TX_STAT_ACK))
info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
- }
/* W/A FW bug: seq_ctl is wrong when the queue is flushed */
if (status == TX_STATUS_FAIL_FIFO_FLUSHED) {
diff --git a/drivers/net/wireless/iwlwifi/pcie/internal.h b/drivers/net/wireless/iwlwifi/pcie/internal.h
index 3d62e8055352..148843e7f34f 100644
--- a/drivers/net/wireless/iwlwifi/pcie/internal.h
+++ b/drivers/net/wireless/iwlwifi/pcie/internal.h
@@ -137,10 +137,6 @@ static inline int iwl_queue_dec_wrap(int index, int n_bd)
struct iwl_cmd_meta {
/* only for SYNC commands, iff the reply skb is wanted */
struct iwl_host_cmd *source;
-
- DEFINE_DMA_UNMAP_ADDR(mapping);
- DEFINE_DMA_UNMAP_LEN(len);
-
u32 flags;
};
@@ -185,25 +181,36 @@ struct iwl_queue {
/*
* The FH will write back to the first TB only, so we need
* to copy some data into the buffer regardless of whether
- * it should be mapped or not. This indicates how much to
- * copy, even for HCMDs it must be big enough to fit the
- * DRAM scratch from the TX cmd, at least 16 bytes.
+ * it should be mapped or not. This indicates how big the
+ * first TB must be to include the scratch buffer. Since
+ * the scratch is 4 bytes at offset 12, it's 16 now. If we
+ * make it bigger then allocations will be bigger and copy
+ * slower, so that's probably not useful.
*/
-#define IWL_HCMD_MIN_COPY_SIZE 16
+#define IWL_HCMD_SCRATCHBUF_SIZE 16
struct iwl_pcie_txq_entry {
struct iwl_device_cmd *cmd;
- struct iwl_device_cmd *copy_cmd;
struct sk_buff *skb;
/* buffer to free after command completes */
const void *free_buf;
struct iwl_cmd_meta meta;
};
+struct iwl_pcie_txq_scratch_buf {
+ struct iwl_cmd_header hdr;
+ u8 buf[8];
+ __le32 scratch;
+};
+
/**
* struct iwl_txq - Tx Queue for DMA
* @q: generic Rx/Tx queue descriptor
* @tfds: transmit frame descriptors (DMA memory)
+ * @scratchbufs: start of command headers, including scratch buffers, for
+ * the writeback -- this is DMA memory and an array holding one buffer
+ * for each command on the queue
+ * @scratchbufs_dma: DMA address for the scratchbufs start
* @entries: transmit entries (driver state)
* @lock: queue lock
* @stuck_timer: timer that fires if queue gets stuck
@@ -217,6 +224,8 @@ struct iwl_pcie_txq_entry {
struct iwl_txq {
struct iwl_queue q;
struct iwl_tfd *tfds;
+ struct iwl_pcie_txq_scratch_buf *scratchbufs;
+ dma_addr_t scratchbufs_dma;
struct iwl_pcie_txq_entry *entries;
spinlock_t lock;
struct timer_list stuck_timer;
@@ -225,6 +234,13 @@ struct iwl_txq {
u8 active;
};
+static inline dma_addr_t
+iwl_pcie_get_scratchbuf_dma(struct iwl_txq *txq, int idx)
+{
+ return txq->scratchbufs_dma +
+ sizeof(struct iwl_pcie_txq_scratch_buf) * idx;
+}
+
/**
* struct iwl_trans_pcie - PCIe transport specific data
* @rxq: all the RX queue data
diff --git a/drivers/net/wireless/iwlwifi/pcie/rx.c b/drivers/net/wireless/iwlwifi/pcie/rx.c
index b0ae06d2456f..567e67ad1f61 100644
--- a/drivers/net/wireless/iwlwifi/pcie/rx.c
+++ b/drivers/net/wireless/iwlwifi/pcie/rx.c
@@ -637,22 +637,14 @@ static void iwl_pcie_rx_handle_rb(struct iwl_trans *trans,
index = SEQ_TO_INDEX(sequence);
cmd_index = get_cmd_index(&txq->q, index);
- if (reclaim) {
- struct iwl_pcie_txq_entry *ent;
- ent = &txq->entries[cmd_index];
- cmd = ent->copy_cmd;
- WARN_ON_ONCE(!cmd && ent->meta.flags & CMD_WANT_HCMD);
- } else {
+ if (reclaim)
+ cmd = txq->entries[cmd_index].cmd;
+ else
cmd = NULL;
- }
err = iwl_op_mode_rx(trans->op_mode, &rxcb, cmd);
if (reclaim) {
- /* The original command isn't needed any more */
- kfree(txq->entries[cmd_index].copy_cmd);
- txq->entries[cmd_index].copy_cmd = NULL;
- /* nor is the duplicated part of the command */
kfree(txq->entries[cmd_index].free_buf);
txq->entries[cmd_index].free_buf = NULL;
}
diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c
index 8b625a7f5685..8595c16f74de 100644
--- a/drivers/net/wireless/iwlwifi/pcie/tx.c
+++ b/drivers/net/wireless/iwlwifi/pcie/tx.c
@@ -191,12 +191,9 @@ static void iwl_pcie_txq_stuck_timer(unsigned long data)
}
for (i = q->read_ptr; i != q->write_ptr;
- i = iwl_queue_inc_wrap(i, q->n_bd)) {
- struct iwl_tx_cmd *tx_cmd =
- (struct iwl_tx_cmd *)txq->entries[i].cmd->payload;
+ i = iwl_queue_inc_wrap(i, q->n_bd))
IWL_ERR(trans, "scratch %d = 0x%08x\n", i,
- get_unaligned_le32(&tx_cmd->scratch));
- }
+ le32_to_cpu(txq->scratchbufs[i].scratch));
iwl_op_mode_nic_error(trans->op_mode);
}
@@ -367,8 +364,8 @@ static inline u8 iwl_pcie_tfd_get_num_tbs(struct iwl_tfd *tfd)
}
static void iwl_pcie_tfd_unmap(struct iwl_trans *trans,
- struct iwl_cmd_meta *meta, struct iwl_tfd *tfd,
- enum dma_data_direction dma_dir)
+ struct iwl_cmd_meta *meta,
+ struct iwl_tfd *tfd)
{
int i;
int num_tbs;
@@ -382,17 +379,12 @@ static void iwl_pcie_tfd_unmap(struct iwl_trans *trans,
return;
}
- /* Unmap tx_cmd */
- if (num_tbs)
- dma_unmap_single(trans->dev,
- dma_unmap_addr(meta, mapping),
- dma_unmap_len(meta, len),
- DMA_BIDIRECTIONAL);
+ /* first TB is never freed - it's the scratchbuf data */
- /* Unmap chunks, if any. */
for (i = 1; i < num_tbs; i++)
dma_unmap_single(trans->dev, iwl_pcie_tfd_tb_get_addr(tfd, i),
- iwl_pcie_tfd_tb_get_len(tfd, i), dma_dir);
+ iwl_pcie_tfd_tb_get_len(tfd, i),
+ DMA_TO_DEVICE);
tfd->num_tbs = 0;
}
@@ -406,8 +398,7 @@ static void iwl_pcie_tfd_unmap(struct iwl_trans *trans,
* Does NOT advance any TFD circular buffer read/write indexes
* Does NOT free the TFD itself (which is within circular buffer)
*/
-static void iwl_pcie_txq_free_tfd(struct iwl_trans *trans, struct iwl_txq *txq,
- enum dma_data_direction dma_dir)
+static void iwl_pcie_txq_free_tfd(struct iwl_trans *trans, struct iwl_txq *txq)
{
struct iwl_tfd *tfd_tmp = txq->tfds;
@@ -418,8 +409,7 @@ static void iwl_pcie_txq_free_tfd(struct iwl_trans *trans, struct iwl_txq *txq,
lockdep_assert_held(&txq->lock);
/* We have only q->n_window txq->entries, but we use q->n_bd tfds */
- iwl_pcie_tfd_unmap(trans, &txq->entries[idx].meta, &tfd_tmp[rd_ptr],
- dma_dir);
+ iwl_pcie_tfd_unmap(trans, &txq->entries[idx].meta, &tfd_tmp[rd_ptr]);
/* free SKB */
if (txq->entries) {
@@ -479,6 +469,7 @@ static int iwl_pcie_txq_alloc(struct iwl_trans *trans,
{
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
size_t tfd_sz = sizeof(struct iwl_tfd) * TFD_QUEUE_SIZE_MAX;
+ size_t scratchbuf_sz;
int i;
if (WARN_ON(txq->entries || txq->tfds))
@@ -514,9 +505,25 @@ static int iwl_pcie_txq_alloc(struct iwl_trans *trans,
IWL_ERR(trans, "dma_alloc_coherent(%zd) failed\n", tfd_sz);
goto error;
}
+
+ BUILD_BUG_ON(IWL_HCMD_SCRATCHBUF_SIZE != sizeof(*txq->scratchbufs));
+ BUILD_BUG_ON(offsetof(struct iwl_pcie_txq_scratch_buf, scratch) !=
+ sizeof(struct iwl_cmd_header) +
+ offsetof(struct iwl_tx_cmd, scratch));
+
+ scratchbuf_sz = sizeof(*txq->scratchbufs) * slots_num;
+
+ txq->scratchbufs = dma_alloc_coherent(trans->dev, scratchbuf_sz,
+ &txq->scratchbufs_dma,
+ GFP_KERNEL);
+ if (!txq->scratchbufs)
+ goto err_free_tfds;
+
txq->q.id = txq_id;
return 0;
+err_free_tfds:
+ dma_free_coherent(trans->dev, tfd_sz, txq->tfds, txq->q.dma_addr);
error:
if (txq->entries && txq_id == trans_pcie->cmd_queue)
for (i = 0; i < slots_num; i++)
@@ -565,22 +572,13 @@ static void iwl_pcie_txq_unmap(struct iwl_trans *trans, int txq_id)
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
struct iwl_txq *txq = &trans_pcie->txq[txq_id];
struct iwl_queue *q = &txq->q;
- enum dma_data_direction dma_dir;
if (!q->n_bd)
return;
- /* In the command queue, all the TBs are mapped as BIDI
- * so unmap them as such.
- */
- if (txq_id == trans_pcie->cmd_queue)
- dma_dir = DMA_BIDIRECTIONAL;
- else
- dma_dir = DMA_TO_DEVICE;
-
spin_lock_bh(&txq->lock);
while (q->write_ptr != q->read_ptr) {
- iwl_pcie_txq_free_tfd(trans, txq, dma_dir);
+ iwl_pcie_txq_free_tfd(trans, txq);
q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd);
}
spin_unlock_bh(&txq->lock);
@@ -610,7 +608,6 @@ static void iwl_pcie_txq_free(struct iwl_trans *trans, int txq_id)
if (txq_id == trans_pcie->cmd_queue)
for (i = 0; i < txq->q.n_window; i++) {
kfree(txq->entries[i].cmd);
- kfree(txq->entries[i].copy_cmd);
kfree(txq->entries[i].free_buf);
}
@@ -619,6 +616,10 @@ static void iwl_pcie_txq_free(struct iwl_trans *trans, int txq_id)
dma_free_coherent(dev, sizeof(struct iwl_tfd) *
txq->q.n_bd, txq->tfds, txq->q.dma_addr);
txq->q.dma_addr = 0;
+
+ dma_free_coherent(dev,
+ sizeof(*txq->scratchbufs) * txq->q.n_window,
+ txq->scratchbufs, txq->scratchbufs_dma);
}
kfree(txq->entries);
@@ -962,7 +963,7 @@ void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn,
iwl_pcie_txq_inval_byte_cnt_tbl(trans, txq);
- iwl_pcie_txq_free_tfd(trans, txq, DMA_TO_DEVICE);
+ iwl_pcie_txq_free_tfd(trans, txq);
}
iwl_pcie_txq_progress(trans_pcie, txq);
@@ -1152,29 +1153,29 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
void *dup_buf = NULL;
dma_addr_t phys_addr;
int idx;
- u16 copy_size, cmd_size, dma_size;
+ u16 copy_size, cmd_size, scratch_size;
bool had_nocopy = false;
int i;
u32 cmd_pos;
- const u8 *cmddata[IWL_MAX_CMD_TFDS];
- u16 cmdlen[IWL_MAX_CMD_TFDS];
+ const u8 *cmddata[IWL_MAX_CMD_TBS_PER_TFD];
+ u16 cmdlen[IWL_MAX_CMD_TBS_PER_TFD];
copy_size = sizeof(out_cmd->hdr);
cmd_size = sizeof(out_cmd->hdr);
/* need one for the header if the first is NOCOPY */
- BUILD_BUG_ON(IWL_MAX_CMD_TFDS > IWL_NUM_OF_TBS - 1);
+ BUILD_BUG_ON(IWL_MAX_CMD_TBS_PER_TFD > IWL_NUM_OF_TBS - 1);
- for (i = 0; i < IWL_MAX_CMD_TFDS; i++) {
+ for (i = 0; i < IWL_MAX_CMD_TBS_PER_TFD; i++) {
cmddata[i] = cmd->data[i];
cmdlen[i] = cmd->len[i];
if (!cmd->len[i])
continue;
- /* need at least IWL_HCMD_MIN_COPY_SIZE copied */
- if (copy_size < IWL_HCMD_MIN_COPY_SIZE) {
- int copy = IWL_HCMD_MIN_COPY_SIZE - copy_size;
+ /* need at least IWL_HCMD_SCRATCHBUF_SIZE copied */
+ if (copy_size < IWL_HCMD_SCRATCHBUF_SIZE) {
+ int copy = IWL_HCMD_SCRATCHBUF_SIZE - copy_size;
if (copy > cmdlen[i])
copy = cmdlen[i];
@@ -1260,15 +1261,15 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
/* and copy the data that needs to be copied */
cmd_pos = offsetof(struct iwl_device_cmd, payload);
copy_size = sizeof(out_cmd->hdr);
- for (i = 0; i < IWL_MAX_CMD_TFDS; i++) {
+ for (i = 0; i < IWL_MAX_CMD_TBS_PER_TFD; i++) {
int copy = 0;
if (!cmd->len)
continue;
- /* need at least IWL_HCMD_MIN_COPY_SIZE copied */
- if (copy_size < IWL_HCMD_MIN_COPY_SIZE) {
- copy = IWL_HCMD_MIN_COPY_SIZE - copy_size;
+ /* need at least IWL_HCMD_SCRATCHBUF_SIZE copied */
+ if (copy_size < IWL_HCMD_SCRATCHBUF_SIZE) {
+ copy = IWL_HCMD_SCRATCHBUF_SIZE - copy_size;
if (copy > cmd->len[i])
copy = cmd->len[i];
@@ -1286,50 +1287,38 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
}
}
- WARN_ON_ONCE(txq->entries[idx].copy_cmd);
-
- /*
- * since out_cmd will be the source address of the FH, it will write
- * the retry count there. So when the user needs to receivce the HCMD
- * that corresponds to the response in the response handler, it needs
- * to set CMD_WANT_HCMD.
- */
- if (cmd->flags & CMD_WANT_HCMD) {
- txq->entries[idx].copy_cmd =
- kmemdup(out_cmd, cmd_pos, GFP_ATOMIC);
- if (unlikely(!txq->entries[idx].copy_cmd)) {
- idx = -ENOMEM;
- goto out;
- }
- }
-
IWL_DEBUG_HC(trans,
"Sending command %s (#%x), seq: 0x%04X, %d bytes at %d[%d]:%d\n",
get_cmd_string(trans_pcie, out_cmd->hdr.cmd),
out_cmd->hdr.cmd, le16_to_cpu(out_cmd->hdr.sequence),
cmd_size, q->write_ptr, idx, trans_pcie->cmd_queue);
- /*
- * If the entire command is smaller than IWL_HCMD_MIN_COPY_SIZE, we must
- * still map at least that many bytes for the hardware to write back to.
- * We have enough space, so that's not a problem.
- */
- dma_size = max_t(u16, copy_size, IWL_HCMD_MIN_COPY_SIZE);
+ /* start the TFD with the scratchbuf */
+ scratch_size = min_t(int, copy_size, IWL_HCMD_SCRATCHBUF_SIZE);
+ memcpy(&txq->scratchbufs[q->write_ptr], &out_cmd->hdr, scratch_size);
+ iwl_pcie_txq_build_tfd(trans, txq,
+ iwl_pcie_get_scratchbuf_dma(txq, q->write_ptr),
+ scratch_size, 1);
+
+ /* map first command fragment, if any remains */
+ if (copy_size > scratch_size) {
+ phys_addr = dma_map_single(trans->dev,
+ ((u8 *)&out_cmd->hdr) + scratch_size,
+ copy_size - scratch_size,
+ DMA_TO_DEVICE);
+ if (dma_mapping_error(trans->dev, phys_addr)) {
+ iwl_pcie_tfd_unmap(trans, out_meta,
+ &txq->tfds[q->write_ptr]);
+ idx = -ENOMEM;
+ goto out;
+ }
- phys_addr = dma_map_single(trans->dev, &out_cmd->hdr, dma_size,
- DMA_BIDIRECTIONAL);
- if (unlikely(dma_mapping_error(trans->dev, phys_addr))) {
- idx = -ENOMEM;
- goto out;
+ iwl_pcie_txq_build_tfd(trans, txq, phys_addr,
+ copy_size - scratch_size, 0);
}
- dma_unmap_addr_set(out_meta, mapping, phys_addr);
- dma_unmap_len_set(out_meta, len, dma_size);
-
- iwl_pcie_txq_build_tfd(trans, txq, phys_addr, copy_size, 1);
-
/* map the remaining (adjusted) nocopy/dup fragments */
- for (i = 0; i < IWL_MAX_CMD_TFDS; i++) {
+ for (i = 0; i < IWL_MAX_CMD_TBS_PER_TFD; i++) {
const void *data = cmddata[i];
if (!cmdlen[i])
@@ -1340,11 +1329,10 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
if (cmd->dataflags[i] & IWL_HCMD_DFL_DUP)
data = dup_buf;
phys_addr = dma_map_single(trans->dev, (void *)data,
- cmdlen[i], DMA_BIDIRECTIONAL);
+ cmdlen[i], DMA_TO_DEVICE);
if (dma_mapping_error(trans->dev, phys_addr)) {
iwl_pcie_tfd_unmap(trans, out_meta,
- &txq->tfds[q->write_ptr],
- DMA_BIDIRECTIONAL);
+ &txq->tfds[q->write_ptr]);
idx = -ENOMEM;
goto out;
}
@@ -1418,7 +1406,7 @@ void iwl_pcie_hcmd_complete(struct iwl_trans *trans,
cmd = txq->entries[cmd_index].cmd;
meta = &txq->entries[cmd_index].meta;
- iwl_pcie_tfd_unmap(trans, meta, &txq->tfds[index], DMA_BIDIRECTIONAL);
+ iwl_pcie_tfd_unmap(trans, meta, &txq->tfds[index]);
/* Input error checking is done when commands are added to queue. */
if (meta->flags & CMD_WANT_SKB) {
@@ -1597,10 +1585,9 @@ int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
struct iwl_cmd_meta *out_meta;
struct iwl_txq *txq;
struct iwl_queue *q;
- dma_addr_t phys_addr = 0;
- dma_addr_t txcmd_phys;
- dma_addr_t scratch_phys;
- u16 len, firstlen, secondlen;
+ dma_addr_t tb0_phys, tb1_phys, scratch_phys;
+ void *tb1_addr;
+ u16 len, tb1_len, tb2_len;
u8 wait_write_ptr = 0;
__le16 fc = hdr->frame_control;
u8 hdr_len = ieee80211_hdrlen(fc);
@@ -1638,85 +1625,80 @@ int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
cpu_to_le16((u16)(QUEUE_TO_SEQ(txq_id) |
INDEX_TO_SEQ(q->write_ptr)));
+ tb0_phys = iwl_pcie_get_scratchbuf_dma(txq, q->write_ptr);
+ scratch_phys = tb0_phys + sizeof(struct iwl_cmd_header) +
+ offsetof(struct iwl_tx_cmd, scratch);
+
+ tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys);
+ tx_cmd->dram_msb_ptr = iwl_get_dma_hi_addr(scratch_phys);
+
/* Set up first empty entry in queue's array of Tx/cmd buffers */
out_meta = &txq->entries[q->write_ptr].meta;
/*
- * Use the first empty entry in this queue's command buffer array
- * to contain the Tx command and MAC header concatenated together
- * (payload data will be in another buffer).
- * Size of this varies, due to varying MAC header length.
- * If end is not dword aligned, we'll have 2 extra bytes at the end
- * of the MAC header (device reads on dword boundaries).
- * We'll tell device about this padding later.
+ * The second TB (tb1) points to the remainder of the TX command
+ * and the 802.11 header - dword aligned size
+ * (This calculation modifies the TX command, so do it before the
+ * setup of the first TB)
*/
- len = sizeof(struct iwl_tx_cmd) +
- sizeof(struct iwl_cmd_header) + hdr_len;
- firstlen = (len + 3) & ~3;
+ len = sizeof(struct iwl_tx_cmd) + sizeof(struct iwl_cmd_header) +
+ hdr_len - IWL_HCMD_SCRATCHBUF_SIZE;
+ tb1_len = (len + 3) & ~3;
/* Tell NIC about any 2-byte padding after MAC header */
- if (firstlen != len)
+ if (tb1_len != len)
tx_cmd->tx_flags |= TX_CMD_FLG_MH_PAD_MSK;
- /* Physical address of this Tx command's header (not MAC header!),
- * within command buffer array. */
- txcmd_phys = dma_map_single(trans->dev,
- &dev_cmd->hdr, firstlen,
- DMA_BIDIRECTIONAL);
- if (unlikely(dma_mapping_error(trans->dev, txcmd_phys)))
- goto out_err;
- dma_unmap_addr_set(out_meta, mapping, txcmd_phys);
- dma_unmap_len_set(out_meta, len, firstlen);
+ /* The first TB points to the scratchbuf data - min_copy bytes */
+ memcpy(&txq->scratchbufs[q->write_ptr], &dev_cmd->hdr,
+ IWL_HCMD_SCRATCHBUF_SIZE);
+ iwl_pcie_txq_build_tfd(trans, txq, tb0_phys,
+ IWL_HCMD_SCRATCHBUF_SIZE, 1);
- if (!ieee80211_has_morefrags(fc)) {
- txq->need_update = 1;
- } else {
- wait_write_ptr = 1;
- txq->need_update = 0;
- }
+ /* there must be data left over for TB1 or this code must be changed */
+ BUILD_BUG_ON(sizeof(struct iwl_tx_cmd) < IWL_HCMD_SCRATCHBUF_SIZE);
- /* Set up TFD's 2nd entry to point directly to remainder of skb,
- * if any (802.11 null frames have no payload). */
- secondlen = skb->len - hdr_len;
- if (secondlen > 0) {
- phys_addr = dma_map_single(trans->dev, skb->data + hdr_len,
- secondlen, DMA_TO_DEVICE);
- if (unlikely(dma_mapping_error(trans->dev, phys_addr))) {
- dma_unmap_single(trans->dev,
- dma_unmap_addr(out_meta, mapping),
- dma_unmap_len(out_meta, len),
- DMA_BIDIRECTIONAL);
+ /* map the data for TB1 */
+ tb1_addr = ((u8 *)&dev_cmd->hdr) + IWL_HCMD_SCRATCHBUF_SIZE;
+ tb1_phys = dma_map_single(trans->dev, tb1_addr, tb1_len, DMA_TO_DEVICE);
+ if (unlikely(dma_mapping_error(trans->dev, tb1_phys)))
+ goto out_err;
+ iwl_pcie_txq_build_tfd(trans, txq, tb1_phys, tb1_len, 0);
+
+ /*
+ * Set up TFD's third entry to point directly to remainder
+ * of skb, if any (802.11 null frames have no payload).
+ */
+ tb2_len = skb->len - hdr_len;
+ if (tb2_len > 0) {
+ dma_addr_t tb2_phys = dma_map_single(trans->dev,
+ skb->data + hdr_len,
+ tb2_len, DMA_TO_DEVICE);
+ if (unlikely(dma_mapping_error(trans->dev, tb2_phys))) {
+ iwl_pcie_tfd_unmap(trans, out_meta,
+ &txq->tfds[q->write_ptr]);
goto out_err;
}
+ iwl_pcie_txq_build_tfd(trans, txq, tb2_phys, tb2_len, 0);
}
- /* Attach buffers to TFD */
- iwl_pcie_txq_build_tfd(trans, txq, txcmd_phys, firstlen, 1);
- if (secondlen > 0)
- iwl_pcie_txq_build_tfd(trans, txq, phys_addr, secondlen, 0);
-
- scratch_phys = txcmd_phys + sizeof(struct iwl_cmd_header) +
- offsetof(struct iwl_tx_cmd, scratch);
-
- /* take back ownership of DMA buffer to enable update */
- dma_sync_single_for_cpu(trans->dev, txcmd_phys, firstlen,
- DMA_BIDIRECTIONAL);
- tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys);
- tx_cmd->dram_msb_ptr = iwl_get_dma_hi_addr(scratch_phys);
-
/* Set up entry for this TFD in Tx byte-count array */
iwl_pcie_txq_update_byte_cnt_tbl(trans, txq, le16_to_cpu(tx_cmd->len));
- dma_sync_single_for_device(trans->dev, txcmd_phys, firstlen,
- DMA_BIDIRECTIONAL);
-
trace_iwlwifi_dev_tx(trans->dev, skb,
&txq->tfds[txq->q.write_ptr],
sizeof(struct iwl_tfd),
- &dev_cmd->hdr, firstlen,
- skb->data + hdr_len, secondlen);
+ &dev_cmd->hdr, IWL_HCMD_SCRATCHBUF_SIZE + tb1_len,
+ skb->data + hdr_len, tb2_len);
trace_iwlwifi_dev_tx_data(trans->dev, skb,
- skb->data + hdr_len, secondlen);
+ skb->data + hdr_len, tb2_len);
+
+ if (!ieee80211_has_morefrags(fc)) {
+ txq->need_update = 1;
+ } else {
+ wait_write_ptr = 1;
+ txq->need_update = 0;
+ }
/* start timer if queue currently empty */
if (txq->need_update && q->read_ptr == q->write_ptr &&
diff --git a/drivers/rtc/rtc-mv.c b/drivers/rtc/rtc-mv.c
index 57233c885998..8f87fec27ce7 100644
--- a/drivers/rtc/rtc-mv.c
+++ b/drivers/rtc/rtc-mv.c
@@ -14,6 +14,7 @@
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/delay.h>
+#include <linux/clk.h>
#include <linux/gfp.h>
#include <linux/module.h>
@@ -41,6 +42,7 @@ struct rtc_plat_data {
struct rtc_device *rtc;
void __iomem *ioaddr;
int irq;
+ struct clk *clk;
};
static int mv_rtc_set_time(struct device *dev, struct rtc_time *tm)
@@ -221,6 +223,7 @@ static int mv_rtc_probe(struct platform_device *pdev)
struct rtc_plat_data *pdata;
resource_size_t size;
u32 rtc_time;
+ int ret = 0;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res)
@@ -239,11 +242,17 @@ static int mv_rtc_probe(struct platform_device *pdev)
if (!pdata->ioaddr)
return -ENOMEM;
+ pdata->clk = devm_clk_get(&pdev->dev, NULL);
+ /* Not all SoCs require a clock.*/
+ if (!IS_ERR(pdata->clk))
+ clk_prepare_enable(pdata->clk);
+
/* make sure the 24 hours mode is enabled */
rtc_time = readl(pdata->ioaddr + RTC_TIME_REG_OFFS);
if (rtc_time & RTC_HOURS_12H_MODE) {
dev_err(&pdev->dev, "24 Hours mode not supported.\n");
- return -EINVAL;
+ ret = -EINVAL;
+ goto out;
}
/* make sure it is actually functional */
@@ -252,7 +261,8 @@ static int mv_rtc_probe(struct platform_device *pdev)
rtc_time = readl(pdata->ioaddr + RTC_TIME_REG_OFFS);
if (rtc_time == 0x01000000) {
dev_err(&pdev->dev, "internal RTC not ticking\n");
- return -ENODEV;
+ ret = -ENODEV;
+ goto out;
}
}
@@ -268,8 +278,10 @@ static int mv_rtc_probe(struct platform_device *pdev)
} else
pdata->rtc = rtc_device_register(pdev->name, &pdev->dev,
&mv_rtc_ops, THIS_MODULE);
- if (IS_ERR(pdata->rtc))
- return PTR_ERR(pdata->rtc);
+ if (IS_ERR(pdata->rtc)) {
+ ret = PTR_ERR(pdata->rtc);
+ goto out;
+ }
if (pdata->irq >= 0) {
writel(0, pdata->ioaddr + RTC_ALARM_INTERRUPT_MASK_REG_OFFS);
@@ -282,6 +294,11 @@ static int mv_rtc_probe(struct platform_device *pdev)
}
return 0;
+out:
+ if (!IS_ERR(pdata->clk))
+ clk_disable_unprepare(pdata->clk);
+
+ return ret;
}
static int __exit mv_rtc_remove(struct platform_device *pdev)
@@ -292,6 +309,9 @@ static int __exit mv_rtc_remove(struct platform_device *pdev)
device_init_wakeup(&pdev->dev, 0);
rtc_device_unregister(pdata->rtc);
+ if (!IS_ERR(pdata->clk))
+ clk_disable_unprepare(pdata->clk);
+
return 0;
}
diff --git a/drivers/staging/comedi/drivers/dt9812.c b/drivers/staging/comedi/drivers/dt9812.c
index 192cf088f834..57b451904791 100644
--- a/drivers/staging/comedi/drivers/dt9812.c
+++ b/drivers/staging/comedi/drivers/dt9812.c
@@ -947,12 +947,13 @@ static int dt9812_di_rinsn(struct comedi_device *dev,
unsigned int *data)
{
struct comedi_dt9812 *devpriv = dev->private;
+ unsigned int channel = CR_CHAN(insn->chanspec);
int n;
u8 bits = 0;
dt9812_digital_in(devpriv->slot, &bits);
for (n = 0; n < insn->n; n++)
- data[n] = ((1 << insn->chanspec) & bits) != 0;
+ data[n] = ((1 << channel) & bits) != 0;
return n;
}
@@ -961,12 +962,13 @@ static int dt9812_do_winsn(struct comedi_device *dev,
unsigned int *data)
{
struct comedi_dt9812 *devpriv = dev->private;
+ unsigned int channel = CR_CHAN(insn->chanspec);
int n;
u8 bits = 0;
dt9812_digital_out_shadow(devpriv->slot, &bits);
for (n = 0; n < insn->n; n++) {
- u8 mask = 1 << insn->chanspec;
+ u8 mask = 1 << channel;
bits &= ~mask;
if (data[n])
@@ -981,13 +983,13 @@ static int dt9812_ai_rinsn(struct comedi_device *dev,
unsigned int *data)
{
struct comedi_dt9812 *devpriv = dev->private;
+ unsigned int channel = CR_CHAN(insn->chanspec);
int n;
for (n = 0; n < insn->n; n++) {
u16 value = 0;
- dt9812_analog_in(devpriv->slot, insn->chanspec, &value,
- DT9812_GAIN_1);
+ dt9812_analog_in(devpriv->slot, channel, &value, DT9812_GAIN_1);
data[n] = value;
}
return n;
@@ -998,12 +1000,13 @@ static int dt9812_ao_rinsn(struct comedi_device *dev,
unsigned int *data)
{
struct comedi_dt9812 *devpriv = dev->private;
+ unsigned int channel = CR_CHAN(insn->chanspec);
int n;
u16 value;
for (n = 0; n < insn->n; n++) {
value = 0;
- dt9812_analog_out_shadow(devpriv->slot, insn->chanspec, &value);
+ dt9812_analog_out_shadow(devpriv->slot, channel, &value);
data[n] = value;
}
return n;
@@ -1014,10 +1017,11 @@ static int dt9812_ao_winsn(struct comedi_device *dev,
unsigned int *data)
{
struct comedi_dt9812 *devpriv = dev->private;
+ unsigned int channel = CR_CHAN(insn->chanspec);
int n;
for (n = 0; n < insn->n; n++)
- dt9812_analog_out(devpriv->slot, insn->chanspec, data[n]);
+ dt9812_analog_out(devpriv->slot, channel, data[n]);
return n;
}
diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c
index 1a0062a04456..6aac1f60bc42 100644
--- a/drivers/staging/comedi/drivers/usbdux.c
+++ b/drivers/staging/comedi/drivers/usbdux.c
@@ -730,10 +730,14 @@ static void usbduxsub_ao_IsocIrq(struct urb *urb)
static int usbduxsub_start(struct usbduxsub *usbduxsub)
{
int errcode = 0;
- uint8_t local_transfer_buffer[16];
+ uint8_t *local_transfer_buffer;
+
+ local_transfer_buffer = kmalloc(1, GFP_KERNEL);
+ if (!local_transfer_buffer)
+ return -ENOMEM;
/* 7f92 to zero */
- local_transfer_buffer[0] = 0;
+ *local_transfer_buffer = 0;
errcode = usb_control_msg(usbduxsub->usbdev,
/* create a pipe for a control transfer */
usb_sndctrlpipe(usbduxsub->usbdev, 0),
@@ -751,22 +755,25 @@ static int usbduxsub_start(struct usbduxsub *usbduxsub)
1,
/* Timeout */
BULK_TIMEOUT);
- if (errcode < 0) {
+ if (errcode < 0)
dev_err(&usbduxsub->interface->dev,
"comedi_: control msg failed (start)\n");
- return errcode;
- }
- return 0;
+
+ kfree(local_transfer_buffer);
+ return errcode;
}
static int usbduxsub_stop(struct usbduxsub *usbduxsub)
{
int errcode = 0;
+ uint8_t *local_transfer_buffer;
- uint8_t local_transfer_buffer[16];
+ local_transfer_buffer = kmalloc(1, GFP_KERNEL);
+ if (!local_transfer_buffer)
+ return -ENOMEM;
/* 7f92 to one */
- local_transfer_buffer[0] = 1;
+ *local_transfer_buffer = 1;
errcode = usb_control_msg(usbduxsub->usbdev,
usb_sndctrlpipe(usbduxsub->usbdev, 0),
/* bRequest, "Firmware" */
@@ -781,12 +788,12 @@ static int usbduxsub_stop(struct usbduxsub *usbduxsub)
1,
/* Timeout */
BULK_TIMEOUT);
- if (errcode < 0) {
+ if (errcode < 0)
dev_err(&usbduxsub->interface->dev,
"comedi_: control msg failed (stop)\n");
- return errcode;
- }
- return 0;
+
+ kfree(local_transfer_buffer);
+ return errcode;
}
static int usbduxsub_upload(struct usbduxsub *usbduxsub,
diff --git a/drivers/staging/comedi/drivers/usbduxfast.c b/drivers/staging/comedi/drivers/usbduxfast.c
index 4bf5dd094dc9..1ba0e3df492d 100644
--- a/drivers/staging/comedi/drivers/usbduxfast.c
+++ b/drivers/staging/comedi/drivers/usbduxfast.c
@@ -436,10 +436,14 @@ static void usbduxfastsub_ai_Irq(struct urb *urb)
static int usbduxfastsub_start(struct usbduxfastsub_s *udfs)
{
int ret;
- unsigned char local_transfer_buffer[16];
+ unsigned char *local_transfer_buffer;
+
+ local_transfer_buffer = kmalloc(1, GFP_KERNEL);
+ if (!local_transfer_buffer)
+ return -ENOMEM;
/* 7f92 to zero */
- local_transfer_buffer[0] = 0;
+ *local_transfer_buffer = 0;
/* bRequest, "Firmware" */
ret = usb_control_msg(udfs->usbdev, usb_sndctrlpipe(udfs->usbdev, 0),
USBDUXFASTSUB_FIRMWARE,
@@ -450,22 +454,25 @@ static int usbduxfastsub_start(struct usbduxfastsub_s *udfs)
local_transfer_buffer,
1, /* Length */
EZTIMEOUT); /* Timeout */
- if (ret < 0) {
+ if (ret < 0)
dev_err(&udfs->interface->dev,
"control msg failed (start)\n");
- return ret;
- }
- return 0;
+ kfree(local_transfer_buffer);
+ return ret;
}
static int usbduxfastsub_stop(struct usbduxfastsub_s *udfs)
{
int ret;
- unsigned char local_transfer_buffer[16];
+ unsigned char *local_transfer_buffer;
+
+ local_transfer_buffer = kmalloc(1, GFP_KERNEL);
+ if (!local_transfer_buffer)
+ return -ENOMEM;
/* 7f92 to one */
- local_transfer_buffer[0] = 1;
+ *local_transfer_buffer = 1;
/* bRequest, "Firmware" */
ret = usb_control_msg(udfs->usbdev, usb_sndctrlpipe(udfs->usbdev, 0),
USBDUXFASTSUB_FIRMWARE,
@@ -474,13 +481,12 @@ static int usbduxfastsub_stop(struct usbduxfastsub_s *udfs)
0x0000, /* Index */
local_transfer_buffer, 1, /* Length */
EZTIMEOUT); /* Timeout */
- if (ret < 0) {
+ if (ret < 0)
dev_err(&udfs->interface->dev,
"control msg failed (stop)\n");
- return ret;
- }
- return 0;
+ kfree(local_transfer_buffer);
+ return ret;
}
static int usbduxfastsub_upload(struct usbduxfastsub_s *udfs,
diff --git a/drivers/staging/comedi/drivers/usbduxsigma.c b/drivers/staging/comedi/drivers/usbduxsigma.c
index d066351a71b2..a728c8fc32a2 100644
--- a/drivers/staging/comedi/drivers/usbduxsigma.c
+++ b/drivers/staging/comedi/drivers/usbduxsigma.c
@@ -681,7 +681,11 @@ static void usbduxsub_ao_IsocIrq(struct urb *urb)
static int usbduxsub_start(struct usbduxsub *usbduxsub)
{
int errcode = 0;
- uint8_t local_transfer_buffer[16];
+ uint8_t *local_transfer_buffer;
+
+ local_transfer_buffer = kmalloc(16, GFP_KERNEL);
+ if (!local_transfer_buffer)
+ return -ENOMEM;
/* 7f92 to zero */
local_transfer_buffer[0] = 0;
@@ -702,19 +706,22 @@ static int usbduxsub_start(struct usbduxsub *usbduxsub)
1,
/* Timeout */
BULK_TIMEOUT);
- if (errcode < 0) {
+ if (errcode < 0)
dev_err(&usbduxsub->interface->dev,
"comedi_: control msg failed (start)\n");
- return errcode;
- }
- return 0;
+
+ kfree(local_transfer_buffer);
+ return errcode;
}
static int usbduxsub_stop(struct usbduxsub *usbduxsub)
{
int errcode = 0;
+ uint8_t *local_transfer_buffer;
- uint8_t local_transfer_buffer[16];
+ local_transfer_buffer = kmalloc(16, GFP_KERNEL);
+ if (!local_transfer_buffer)
+ return -ENOMEM;
/* 7f92 to one */
local_transfer_buffer[0] = 1;
@@ -732,12 +739,12 @@ static int usbduxsub_stop(struct usbduxsub *usbduxsub)
1,
/* Timeout */
BULK_TIMEOUT);
- if (errcode < 0) {
+ if (errcode < 0)
dev_err(&usbduxsub->interface->dev,
"comedi_: control msg failed (stop)\n");
- return errcode;
- }
- return 0;
+
+ kfree(local_transfer_buffer);
+ return errcode;
}
static int usbduxsub_upload(struct usbduxsub *usbduxsub,
diff --git a/drivers/staging/imx-drm/ipuv3-crtc.c b/drivers/staging/imx-drm/ipuv3-crtc.c
index 4b3a019409b5..b028b0d1317b 100644
--- a/drivers/staging/imx-drm/ipuv3-crtc.c
+++ b/drivers/staging/imx-drm/ipuv3-crtc.c
@@ -483,17 +483,6 @@ static int ipu_get_resources(struct ipu_crtc *ipu_crtc,
goto err_out;
}
- ipu_crtc->irq = ipu_idmac_channel_irq(ipu, ipu_crtc->ipu_ch,
- IPU_IRQ_EOF);
- ret = devm_request_irq(ipu_crtc->dev, ipu_crtc->irq, ipu_irq_handler, 0,
- "imx_drm", ipu_crtc);
- if (ret < 0) {
- dev_err(ipu_crtc->dev, "irq request failed with %d.\n", ret);
- goto err_out;
- }
-
- disable_irq(ipu_crtc->irq);
-
return 0;
err_out:
ipu_put_resources(ipu_crtc);
@@ -504,6 +493,7 @@ err_out:
static int ipu_crtc_init(struct ipu_crtc *ipu_crtc,
struct ipu_client_platformdata *pdata)
{
+ struct ipu_soc *ipu = dev_get_drvdata(ipu_crtc->dev->parent);
int ret;
ret = ipu_get_resources(ipu_crtc, pdata);
@@ -522,6 +512,17 @@ static int ipu_crtc_init(struct ipu_crtc *ipu_crtc,
goto err_put_resources;
}
+ ipu_crtc->irq = ipu_idmac_channel_irq(ipu, ipu_crtc->ipu_ch,
+ IPU_IRQ_EOF);
+ ret = devm_request_irq(ipu_crtc->dev, ipu_crtc->irq, ipu_irq_handler, 0,
+ "imx_drm", ipu_crtc);
+ if (ret < 0) {
+ dev_err(ipu_crtc->dev, "irq request failed with %d.\n", ret);
+ goto err_put_resources;
+ }
+
+ disable_irq(ipu_crtc->irq);
+
return 0;
err_put_resources:
diff --git a/drivers/staging/tidspbridge/rmgr/drv.c b/drivers/staging/tidspbridge/rmgr/drv.c
index db1da28cecba..be26917a6896 100644
--- a/drivers/staging/tidspbridge/rmgr/drv.c
+++ b/drivers/staging/tidspbridge/rmgr/drv.c
@@ -76,37 +76,28 @@ int drv_insert_node_res_element(void *hnode, void *node_resource,
struct node_res_object **node_res_obj =
(struct node_res_object **)node_resource;
struct process_context *ctxt = (struct process_context *)process_ctxt;
- int status = 0;
int retval;
*node_res_obj = kzalloc(sizeof(struct node_res_object), GFP_KERNEL);
- if (!*node_res_obj) {
- status = -ENOMEM;
- goto func_end;
- }
+ if (!*node_res_obj)
+ return -ENOMEM;
(*node_res_obj)->node = hnode;
- retval = idr_get_new(ctxt->node_id, *node_res_obj,
- &(*node_res_obj)->id);
- if (retval == -EAGAIN) {
- if (!idr_pre_get(ctxt->node_id, GFP_KERNEL)) {
- pr_err("%s: OUT OF MEMORY\n", __func__);
- status = -ENOMEM;
- goto func_end;
- }
-
- retval = idr_get_new(ctxt->node_id, *node_res_obj,
- &(*node_res_obj)->id);
+ retval = idr_alloc(ctxt->node_id, *node_res_obj, 0, 0, GFP_KERNEL);
+ if (retval >= 0) {
+ (*node_res_obj)->id = retval;
+ return 0;
}
- if (retval) {
+
+ kfree(*node_res_obj);
+
+ if (retval == -ENOSPC) {
pr_err("%s: FAILED, IDR is FULL\n", __func__);
- status = -EFAULT;
+ return -EFAULT;
+ } else {
+ pr_err("%s: OUT OF MEMORY\n", __func__);
+ return -ENOMEM;
}
-func_end:
- if (status)
- kfree(*node_res_obj);
-
- return status;
}
/* Release all Node resources and its context
@@ -201,35 +192,26 @@ int drv_proc_insert_strm_res_element(void *stream_obj,
struct strm_res_object **pstrm_res =
(struct strm_res_object **)strm_res;
struct process_context *ctxt = (struct process_context *)process_ctxt;
- int status = 0;
int retval;
*pstrm_res = kzalloc(sizeof(struct strm_res_object), GFP_KERNEL);
- if (*pstrm_res == NULL) {
- status = -EFAULT;
- goto func_end;
- }
+ if (*pstrm_res == NULL)
+ return -EFAULT;
(*pstrm_res)->stream = stream_obj;
- retval = idr_get_new(ctxt->stream_id, *pstrm_res,
- &(*pstrm_res)->id);
- if (retval == -EAGAIN) {
- if (!idr_pre_get(ctxt->stream_id, GFP_KERNEL)) {
- pr_err("%s: OUT OF MEMORY\n", __func__);
- status = -ENOMEM;
- goto func_end;
- }
-
- retval = idr_get_new(ctxt->stream_id, *pstrm_res,
- &(*pstrm_res)->id);
+ retval = idr_alloc(ctxt->stream_id, *pstrm_res, 0, 0, GFP_KERNEL);
+ if (retval >= 0) {
+ (*pstrm_res)->id = retval;
+ return 0;
}
- if (retval) {
+
+ if (retval == -ENOSPC) {
pr_err("%s: FAILED, IDR is FULL\n", __func__);
- status = -EPERM;
+ return -EPERM;
+ } else {
+ pr_err("%s: OUT OF MEMORY\n", __func__);
+ return -ENOMEM;
}
-
-func_end:
- return status;
}
static int drv_proc_free_strm_res(int id, void *p, void *process_ctxt)
diff --git a/drivers/staging/vt6656/card.c b/drivers/staging/vt6656/card.c
index 22918a106d73..d2479b766450 100644
--- a/drivers/staging/vt6656/card.c
+++ b/drivers/staging/vt6656/card.c
@@ -790,7 +790,7 @@ u64 CARDqGetNextTBTT(u64 qwTSF, WORD wBeaconInterval)
if ((~uLowNextTBTT) < uLowRemain)
qwTSF = ((qwTSF >> 32) + 1) << 32;
- qwTSF = (qwTSF & 0xffffffff00000000UL) |
+ qwTSF = (qwTSF & 0xffffffff00000000ULL) |
(u64)(uLowNextTBTT + uLowRemain);
return (qwTSF);
diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c
index d5f53e1a74a2..a5063a6f64d9 100644
--- a/drivers/staging/vt6656/main_usb.c
+++ b/drivers/staging/vt6656/main_usb.c
@@ -669,8 +669,6 @@ static int vt6656_suspend(struct usb_interface *intf, pm_message_t message)
if (device->flags & DEVICE_FLAGS_OPENED)
device_close(device->dev);
- usb_put_dev(interface_to_usbdev(intf));
-
return 0;
}
@@ -681,8 +679,6 @@ static int vt6656_resume(struct usb_interface *intf)
if (!device || !device->dev)
return -ENODEV;
- usb_get_dev(interface_to_usbdev(intf));
-
if (!(device->flags & DEVICE_FLAGS_OPENED))
device_open(device->dev);
diff --git a/drivers/staging/zcache/ramster/tcp.c b/drivers/staging/zcache/ramster/tcp.c
index aa2a1a763aa4..f6e1e5209d88 100644
--- a/drivers/staging/zcache/ramster/tcp.c
+++ b/drivers/staging/zcache/ramster/tcp.c
@@ -300,27 +300,22 @@ static u8 r2net_num_from_nn(struct r2net_node *nn)
static int r2net_prep_nsw(struct r2net_node *nn, struct r2net_status_wait *nsw)
{
- int ret = 0;
+ int ret;
- do {
- if (!idr_pre_get(&nn->nn_status_idr, GFP_ATOMIC)) {
- ret = -EAGAIN;
- break;
- }
- spin_lock(&nn->nn_lock);
- ret = idr_get_new(&nn->nn_status_idr, nsw, &nsw->ns_id);
- if (ret == 0)
- list_add_tail(&nsw->ns_node_item,
- &nn->nn_status_list);
- spin_unlock(&nn->nn_lock);
- } while (ret == -EAGAIN);
+ spin_lock(&nn->nn_lock);
+ ret = idr_alloc(&nn->nn_status_idr, nsw, 0, 0, GFP_ATOMIC);
+ if (ret >= 0) {
+ nsw->ns_id = ret;
+ list_add_tail(&nsw->ns_node_item, &nn->nn_status_list);
+ }
+ spin_unlock(&nn->nn_lock);
- if (ret == 0) {
+ if (ret >= 0) {
init_waitqueue_head(&nsw->ns_wq);
nsw->ns_sys_status = R2NET_ERR_NONE;
nsw->ns_status = 0;
+ return 0;
}
-
return ret;
}
diff --git a/drivers/tty/serial/8250/8250.c b/drivers/tty/serial/8250/8250.c
index 0efc815a4968..cf6a5383748a 100644
--- a/drivers/tty/serial/8250/8250.c
+++ b/drivers/tty/serial/8250/8250.c
@@ -301,7 +301,28 @@ static const struct serial8250_config uart_config[] = {
},
[PORT_8250_CIR] = {
.name = "CIR port"
- }
+ },
+ [PORT_ALTR_16550_F32] = {
+ .name = "Altera 16550 FIFO32",
+ .fifo_size = 32,
+ .tx_loadsz = 32,
+ .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
+ .flags = UART_CAP_FIFO | UART_CAP_AFE,
+ },
+ [PORT_ALTR_16550_F64] = {
+ .name = "Altera 16550 FIFO64",
+ .fifo_size = 64,
+ .tx_loadsz = 64,
+ .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
+ .flags = UART_CAP_FIFO | UART_CAP_AFE,
+ },
+ [PORT_ALTR_16550_F128] = {
+ .name = "Altera 16550 FIFO128",
+ .fifo_size = 128,
+ .tx_loadsz = 128,
+ .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
+ .flags = UART_CAP_FIFO | UART_CAP_AFE,
+ },
};
/* Uart divisor latch read */
@@ -3396,3 +3417,32 @@ module_param_array(probe_rsa, ulong, &probe_rsa_count, 0444);
MODULE_PARM_DESC(probe_rsa, "Probe I/O ports for RSA");
#endif
MODULE_ALIAS_CHARDEV_MAJOR(TTY_MAJOR);
+
+#ifndef MODULE
+/* This module was renamed to 8250_core in 3.7. Keep the old "8250" name
+ * working as well for the module options so we don't break people. We
+ * need to keep the names identical and the convenient macros will happily
+ * refuse to let us do that by failing the build with redefinition errors
+ * of global variables. So we stick them inside a dummy function to avoid
+ * those conflicts. The options still get parsed, and the redefined
+ * MODULE_PARAM_PREFIX lets us keep the "8250." syntax alive.
+ *
+ * This is hacky. I'm sorry.
+ */
+static void __used s8250_options(void)
+{
+#undef MODULE_PARAM_PREFIX
+#define MODULE_PARAM_PREFIX "8250."
+
+ module_param_cb(share_irqs, &param_ops_uint, &share_irqs, 0644);
+ module_param_cb(nr_uarts, &param_ops_uint, &nr_uarts, 0644);
+ module_param_cb(skip_txen_test, &param_ops_uint, &skip_txen_test, 0644);
+#ifdef CONFIG_SERIAL_8250_RSA
+ __module_param_call(MODULE_PARAM_PREFIX, probe_rsa,
+ &param_array_ops, .arr = &__param_arr_probe_rsa,
+ 0444, -1);
+#endif
+}
+#else
+MODULE_ALIAS("8250");
+#endif
diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c
index 791c5a77ec61..aa76825229dc 100644
--- a/drivers/tty/serial/8250/8250_pci.c
+++ b/drivers/tty/serial/8250/8250_pci.c
@@ -1571,6 +1571,7 @@ pci_wch_ch353_setup(struct serial_private *priv,
/* Unknown vendors/cards - this should not be in linux/pci_ids.h */
#define PCI_SUBDEVICE_ID_UNKNOWN_0x1584 0x1584
+#define PCI_SUBDEVICE_ID_UNKNOWN_0x1588 0x1588
/*
* Master list of serial port init/setup/exit quirks.
@@ -1852,15 +1853,6 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
},
{
.vendor = PCI_VENDOR_ID_PLX,
- .device = PCI_DEVICE_ID_PLX_9050,
- .subvendor = PCI_VENDOR_ID_PLX,
- .subdevice = PCI_SUBDEVICE_ID_UNKNOWN_0x1584,
- .init = pci_plx9050_init,
- .setup = pci_default_setup,
- .exit = pci_plx9050_exit,
- },
- {
- .vendor = PCI_VENDOR_ID_PLX,
.device = PCI_DEVICE_ID_PLX_ROMULUS,
.subvendor = PCI_VENDOR_ID_PLX,
.subdevice = PCI_DEVICE_ID_PLX_ROMULUS,
@@ -3733,7 +3725,12 @@ static struct pci_device_id serial_pci_tbl[] = {
{ PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
PCI_VENDOR_ID_PLX,
PCI_SUBDEVICE_ID_UNKNOWN_0x1584, 0, 0,
- pbn_b0_4_115200 },
+ pbn_b2_4_115200 },
+ /* Unknown card - subdevice 0x1588 */
+ { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
+ PCI_VENDOR_ID_PLX,
+ PCI_SUBDEVICE_ID_UNKNOWN_0x1588, 0, 0,
+ pbn_b2_8_115200 },
{ PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
PCI_SUBVENDOR_ID_KEYSPAN,
PCI_SUBDEVICE_ID_KEYSPAN_SX2, 0, 0,
@@ -4791,6 +4788,10 @@ static struct pci_device_id serial_pci_tbl[] = {
PCI_VENDOR_ID_IBM, 0x0299,
0, 0, pbn_b0_bt_2_115200 },
+ { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9835,
+ 0x1000, 0x0012,
+ 0, 0, pbn_b0_bt_2_115200 },
+
{ PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9901,
0xA000, 0x1000,
0, 0, pbn_b0_1_115200 },
diff --git a/drivers/tty/serial/8250/8250_pnp.c b/drivers/tty/serial/8250/8250_pnp.c
index 35d9ab95c5cb..b3455a970a1d 100644
--- a/drivers/tty/serial/8250/8250_pnp.c
+++ b/drivers/tty/serial/8250/8250_pnp.c
@@ -429,6 +429,7 @@ serial_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
{
struct uart_8250_port uart;
int ret, line, flags = dev_id->driver_data;
+ struct resource *res = NULL;
if (flags & UNKNOWN_DEV) {
ret = serial_pnp_guess_board(dev);
@@ -439,11 +440,12 @@ serial_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
memset(&uart, 0, sizeof(uart));
if (pnp_irq_valid(dev, 0))
uart.port.irq = pnp_irq(dev, 0);
- if ((flags & CIR_PORT) && pnp_port_valid(dev, 2)) {
- uart.port.iobase = pnp_port_start(dev, 2);
- uart.port.iotype = UPIO_PORT;
- } else if (pnp_port_valid(dev, 0)) {
- uart.port.iobase = pnp_port_start(dev, 0);
+ if ((flags & CIR_PORT) && pnp_port_valid(dev, 2))
+ res = pnp_get_resource(dev, IORESOURCE_IO, 2);
+ else if (pnp_port_valid(dev, 0))
+ res = pnp_get_resource(dev, IORESOURCE_IO, 0);
+ if (pnp_resource_enabled(res)) {
+ uart.port.iobase = res->start;
uart.port.iotype = UPIO_PORT;
} else if (pnp_mem_valid(dev, 0)) {
uart.port.mapbase = pnp_mem_start(dev, 0);
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
index cf9210db9fa9..7e7006fd404e 100644
--- a/drivers/tty/serial/Kconfig
+++ b/drivers/tty/serial/Kconfig
@@ -211,14 +211,14 @@ config SERIAL_SAMSUNG
config SERIAL_SAMSUNG_UARTS_4
bool
depends on PLAT_SAMSUNG
- default y if !(CPU_S3C2410 || SERIAL_S3C2412 || CPU_S3C2440 || CPU_S3C2442)
+ default y if !(CPU_S3C2410 || CPU_S3C2412 || CPU_S3C2440 || CPU_S3C2442)
help
Internal node for the common case of 4 Samsung compatible UARTs
config SERIAL_SAMSUNG_UARTS
int
depends on PLAT_SAMSUNG
- default 6 if ARCH_S5P6450
+ default 6 if CPU_S5P6450
default 4 if SERIAL_SAMSUNG_UARTS_4 || CPU_S3C2416
default 3
help
diff --git a/drivers/tty/serial/bcm63xx_uart.c b/drivers/tty/serial/bcm63xx_uart.c
index 719594e5fc21..52a3ecd40421 100644
--- a/drivers/tty/serial/bcm63xx_uart.c
+++ b/drivers/tty/serial/bcm63xx_uart.c
@@ -235,7 +235,7 @@ static const char *bcm_uart_type(struct uart_port *port)
*/
static void bcm_uart_do_rx(struct uart_port *port)
{
- struct tty_port *port = &port->state->port;
+ struct tty_port *tty_port = &port->state->port;
unsigned int max_count;
/* limit number of char read in interrupt, should not be
@@ -260,7 +260,7 @@ static void bcm_uart_do_rx(struct uart_port *port)
bcm_uart_writel(port, val, UART_CTL_REG);
port->icount.overrun++;
- tty_insert_flip_char(port, 0, TTY_OVERRUN);
+ tty_insert_flip_char(tty_port, 0, TTY_OVERRUN);
}
if (!(iestat & UART_IR_STAT(UART_IR_RXNOTEMPTY)))
@@ -299,11 +299,11 @@ static void bcm_uart_do_rx(struct uart_port *port)
if ((cstat & port->ignore_status_mask) == 0)
- tty_insert_flip_char(port, c, flag);
+ tty_insert_flip_char(tty_port, c, flag);
} while (--max_count);
- tty_flip_buffer_push(port);
+ tty_flip_buffer_push(tty_port);
}
/*
diff --git a/drivers/tty/serial/mpc52xx_uart.c b/drivers/tty/serial/mpc52xx_uart.c
index c0e1fad51be7..018bad922554 100644
--- a/drivers/tty/serial/mpc52xx_uart.c
+++ b/drivers/tty/serial/mpc52xx_uart.c
@@ -550,7 +550,7 @@ static int mpc512x_psc_clock(struct uart_port *port, int enable)
return 0;
psc_num = (port->mapbase & 0xf00) >> 8;
- snprintf(clk_name, sizeof(clk_name), "psc%d_clk", psc_num);
+ snprintf(clk_name, sizeof(clk_name), "psc%d_mclk", psc_num);
psc_clk = clk_get(port->dev, clk_name);
if (IS_ERR(psc_clk)) {
dev_err(port->dev, "Failed to get PSC clock entry!\n");
diff --git a/drivers/tty/serial/of_serial.c b/drivers/tty/serial/of_serial.c
index d5874605682b..b025d5438275 100644
--- a/drivers/tty/serial/of_serial.c
+++ b/drivers/tty/serial/of_serial.c
@@ -241,6 +241,12 @@ static struct of_device_id of_platform_serial_table[] = {
{ .compatible = "ns16850", .data = (void *)PORT_16850, },
{ .compatible = "nvidia,tegra20-uart", .data = (void *)PORT_TEGRA, },
{ .compatible = "nxp,lpc3220-uart", .data = (void *)PORT_LPC3220, },
+ { .compatible = "altr,16550-FIFO32",
+ .data = (void *)PORT_ALTR_16550_F32, },
+ { .compatible = "altr,16550-FIFO64",
+ .data = (void *)PORT_ALTR_16550_F64, },
+ { .compatible = "altr,16550-FIFO128",
+ .data = (void *)PORT_ALTR_16550_F128, },
#ifdef CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL
{ .compatible = "ibm,qpace-nwp-serial",
.data = (void *)PORT_NWPSERIAL, },
diff --git a/drivers/tty/serial/vt8500_serial.c b/drivers/tty/serial/vt8500_serial.c
index a3f9dd5c9dff..705240e6c4ec 100644
--- a/drivers/tty/serial/vt8500_serial.c
+++ b/drivers/tty/serial/vt8500_serial.c
@@ -611,14 +611,7 @@ static int vt8500_serial_probe(struct platform_device *pdev)
vt8500_port->uart.dev = &pdev->dev;
vt8500_port->uart.flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF;
- vt8500_port->clk = of_clk_get(pdev->dev.of_node, 0);
- if (!IS_ERR(vt8500_port->clk)) {
- vt8500_port->uart.uartclk = clk_get_rate(vt8500_port->clk);
- } else {
- /* use the default of 24Mhz if not specified and warn */
- pr_warn("%s: serial clock source not specified\n", __func__);
- vt8500_port->uart.uartclk = 24000000;
- }
+ vt8500_port->uart.uartclk = clk_get_rate(vt8500_port->clk);
snprintf(vt8500_port->name, sizeof(vt8500_port->name),
"VT8500 UART%d", pdev->id);
diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c
index bb119934e76c..578aa7594b11 100644
--- a/drivers/tty/tty_buffer.c
+++ b/drivers/tty/tty_buffer.c
@@ -425,7 +425,7 @@ static void flush_to_ldisc(struct work_struct *work)
struct tty_ldisc *disc;
tty = port->itty;
- if (WARN_RATELIMIT(tty == NULL, "tty is NULL\n"))
+ if (tty == NULL)
return;
disc = tty_ldisc_ref(tty);
diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile
index f5ed3d75fa5a..8f5ebced5df0 100644
--- a/drivers/usb/Makefile
+++ b/drivers/usb/Makefile
@@ -46,7 +46,7 @@ obj-$(CONFIG_USB_MICROTEK) += image/
obj-$(CONFIG_USB_SERIAL) += serial/
obj-$(CONFIG_USB) += misc/
-obj-$(CONFIG_USB_COMMON) += phy/
+obj-$(CONFIG_USB_OTG_UTILS) += phy/
obj-$(CONFIG_EARLY_PRINTK_DBGP) += early/
obj-$(CONFIG_USB_ATM) += atm/
diff --git a/drivers/usb/c67x00/c67x00-sched.c b/drivers/usb/c67x00/c67x00-sched.c
index a03fbc15fa9c..aa491627a45b 100644
--- a/drivers/usb/c67x00/c67x00-sched.c
+++ b/drivers/usb/c67x00/c67x00-sched.c
@@ -100,7 +100,7 @@ struct c67x00_urb_priv {
#define TD_PIDEP_OFFSET 0x04
#define TD_PIDEPMASK_PID 0xF0
#define TD_PIDEPMASK_EP 0x0F
-#define TD_PORTLENMASK_DL 0x02FF
+#define TD_PORTLENMASK_DL 0x03FF
#define TD_PORTLENMASK_PN 0xC000
#define TD_STATUS_OFFSET 0x07
@@ -590,7 +590,7 @@ static int c67x00_create_td(struct c67x00_hcd *c67x00, struct urb *urb,
{
struct c67x00_td *td;
struct c67x00_urb_priv *urbp = urb->hcpriv;
- const __u8 active_flag = 1, retry_cnt = 1;
+ const __u8 active_flag = 1, retry_cnt = 3;
__u8 cmd = 0;
int tt = 0;
diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
index 2f45bba8561d..f64fbea1cf20 100644
--- a/drivers/usb/chipidea/udc.c
+++ b/drivers/usb/chipidea/udc.c
@@ -1767,7 +1767,7 @@ static int udc_start(struct ci13xxx *ci)
goto put_transceiver;
}
- retval = dbg_create_files(&ci->gadget.dev);
+ retval = dbg_create_files(ci->dev);
if (retval)
goto unreg_device;
@@ -1796,7 +1796,7 @@ remove_trans:
dev_err(dev, "error = %i\n", retval);
remove_dbg:
- dbg_remove_files(&ci->gadget.dev);
+ dbg_remove_files(ci->dev);
unreg_device:
device_unregister(&ci->gadget.dev);
put_transceiver:
@@ -1836,7 +1836,7 @@ static void udc_stop(struct ci13xxx *ci)
if (ci->global_phy)
usb_put_phy(ci->transceiver);
}
- dbg_remove_files(&ci->gadget.dev);
+ dbg_remove_files(ci->dev);
device_unregister(&ci->gadget.dev);
/* my kobject is dynamic, I swear! */
memset(&ci->gadget, 0, sizeof(ci->gadget));
diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c
index 5f0cb417b736..122d056d96d5 100644
--- a/drivers/usb/class/cdc-wdm.c
+++ b/drivers/usb/class/cdc-wdm.c
@@ -56,6 +56,7 @@ MODULE_DEVICE_TABLE (usb, wdm_ids);
#define WDM_RESPONDING 7
#define WDM_SUSPENDING 8
#define WDM_RESETTING 9
+#define WDM_OVERFLOW 10
#define WDM_MAX 16
@@ -155,6 +156,7 @@ static void wdm_in_callback(struct urb *urb)
{
struct wdm_device *desc = urb->context;
int status = urb->status;
+ int length = urb->actual_length;
spin_lock(&desc->iuspin);
clear_bit(WDM_RESPONDING, &desc->flags);
@@ -185,9 +187,17 @@ static void wdm_in_callback(struct urb *urb)
}
desc->rerr = status;
- desc->reslength = urb->actual_length;
- memmove(desc->ubuf + desc->length, desc->inbuf, desc->reslength);
- desc->length += desc->reslength;
+ if (length + desc->length > desc->wMaxCommand) {
+ /* The buffer would overflow */
+ set_bit(WDM_OVERFLOW, &desc->flags);
+ } else {
+ /* we may already be in overflow */
+ if (!test_bit(WDM_OVERFLOW, &desc->flags)) {
+ memmove(desc->ubuf + desc->length, desc->inbuf, length);
+ desc->length += length;
+ desc->reslength = length;
+ }
+ }
skip_error:
wake_up(&desc->wait);
@@ -435,6 +445,11 @@ retry:
rv = -ENODEV;
goto err;
}
+ if (test_bit(WDM_OVERFLOW, &desc->flags)) {
+ clear_bit(WDM_OVERFLOW, &desc->flags);
+ rv = -ENOBUFS;
+ goto err;
+ }
i++;
if (file->f_flags & O_NONBLOCK) {
if (!test_bit(WDM_READ, &desc->flags)) {
@@ -478,6 +493,7 @@ retry:
spin_unlock_irq(&desc->iuspin);
goto retry;
}
+
if (!desc->reslength) { /* zero length read */
dev_dbg(&desc->intf->dev, "%s: zero length - clearing WDM_READ\n", __func__);
clear_bit(WDM_READ, &desc->flags);
@@ -1004,6 +1020,7 @@ static int wdm_post_reset(struct usb_interface *intf)
struct wdm_device *desc = wdm_find_device(intf);
int rv;
+ clear_bit(WDM_OVERFLOW, &desc->flags);
clear_bit(WDM_RESETTING, &desc->flags);
rv = recover_from_urb_loss(desc);
mutex_unlock(&desc->wlock);
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 999909451e37..ffa6b004a84b 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -583,6 +583,7 @@ static int dwc3_remove(struct platform_device *pdev)
break;
}
+ dwc3_free_event_buffers(dwc);
dwc3_core_exit(dwc);
return 0;
diff --git a/drivers/usb/dwc3/dwc3-exynos.c b/drivers/usb/dwc3/dwc3-exynos.c
index b50da53e9a52..b082bec7343e 100644
--- a/drivers/usb/dwc3/dwc3-exynos.c
+++ b/drivers/usb/dwc3/dwc3-exynos.c
@@ -23,8 +23,6 @@
#include <linux/usb/nop-usb-xceiv.h>
#include <linux/of.h>
-#include "core.h"
-
struct dwc3_exynos {
struct platform_device *dwc3;
struct platform_device *usb2_phy;
diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c
index 22f337f57219..afa05e3c9cf4 100644
--- a/drivers/usb/dwc3/dwc3-omap.c
+++ b/drivers/usb/dwc3/dwc3-omap.c
@@ -54,8 +54,6 @@
#include <linux/usb/otg.h>
#include <linux/usb/nop-usb-xceiv.h>
-#include "core.h"
-
/*
* All these registers belong to OMAP's Wrapper around the
* DesignWare USB3 Core.
@@ -465,20 +463,20 @@ static int dwc3_omap_remove(struct platform_device *pdev)
return 0;
}
-static const struct of_device_id of_dwc3_matach[] = {
+static const struct of_device_id of_dwc3_match[] = {
{
"ti,dwc3",
},
{ },
};
-MODULE_DEVICE_TABLE(of, of_dwc3_matach);
+MODULE_DEVICE_TABLE(of, of_dwc3_match);
static struct platform_driver dwc3_omap_driver = {
.probe = dwc3_omap_probe,
.remove = dwc3_omap_remove,
.driver = {
.name = "omap-dwc3",
- .of_match_table = of_dwc3_matach,
+ .of_match_table = of_dwc3_match,
},
};
diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c
index 7d70f44567d2..e8d77689a322 100644
--- a/drivers/usb/dwc3/dwc3-pci.c
+++ b/drivers/usb/dwc3/dwc3-pci.c
@@ -45,8 +45,6 @@
#include <linux/usb/otg.h>
#include <linux/usb/nop-usb-xceiv.h>
-#include "core.h"
-
/* FIXME define these in <linux/pci_ids.h> */
#define PCI_VENDOR_ID_SYNOPSYS 0x16c3
#define PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3 0xabcd
diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
index d7da073a23fe..1d139ca05ef1 100644
--- a/drivers/usb/dwc3/ep0.c
+++ b/drivers/usb/dwc3/ep0.c
@@ -891,7 +891,8 @@ static void __dwc3_ep0_do_control_data(struct dwc3 *dwc,
DWC3_TRBCTL_CONTROL_DATA);
} else if (!IS_ALIGNED(req->request.length, dep->endpoint.maxpacket)
&& (dep->number == 0)) {
- u32 transfer_size;
+ u32 transfer_size;
+ u32 maxpacket;
ret = usb_gadget_map_request(&dwc->gadget, &req->request,
dep->number);
@@ -902,8 +903,8 @@ static void __dwc3_ep0_do_control_data(struct dwc3 *dwc,
WARN_ON(req->request.length > DWC3_EP0_BOUNCE_SIZE);
- transfer_size = roundup(req->request.length,
- (u32) dep->endpoint.maxpacket);
+ maxpacket = dep->endpoint.maxpacket;
+ transfer_size = roundup(req->request.length, maxpacket);
dwc->ep0_bounced = true;
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index a04342f6cbfa..82e160e96fca 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -2159,7 +2159,6 @@ static void dwc3_gadget_phy_suspend(struct dwc3 *dwc, u8 speed)
static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc)
{
- struct dwc3_gadget_ep_cmd_params params;
struct dwc3_ep *dep;
int ret;
u32 reg;
@@ -2167,8 +2166,6 @@ static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc)
dev_vdbg(dwc->dev, "%s\n", __func__);
- memset(&params, 0x00, sizeof(params));
-
reg = dwc3_readl(dwc->regs, DWC3_DSTS);
speed = reg & DWC3_DSTS_CONNECTSPD;
dwc->speed = speed;
diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
index 97a13c349cc5..82fb22511356 100644
--- a/drivers/usb/gadget/Makefile
+++ b/drivers/usb/gadget/Makefile
@@ -35,6 +35,12 @@ mv_udc-y := mv_udc_core.o
obj-$(CONFIG_USB_FUSB300) += fusb300_udc.o
obj-$(CONFIG_USB_MV_U3D) += mv_u3d_core.o
+# USB Functions
+obj-$(CONFIG_USB_F_ACM) += f_acm.o
+f_ss_lb-y := f_loopback.o f_sourcesink.o
+obj-$(CONFIG_USB_F_SS_LB) += f_ss_lb.o
+obj-$(CONFIG_USB_U_SERIAL) += u_serial.o
+
#
# USB gadget drivers
#
@@ -74,9 +80,3 @@ obj-$(CONFIG_USB_G_WEBCAM) += g_webcam.o
obj-$(CONFIG_USB_G_NCM) += g_ncm.o
obj-$(CONFIG_USB_G_ACM_MS) += g_acm_ms.o
obj-$(CONFIG_USB_GADGET_TARGET) += tcm_usb_gadget.o
-
-# USB Functions
-obj-$(CONFIG_USB_F_ACM) += f_acm.o
-f_ss_lb-y := f_loopback.o f_sourcesink.o
-obj-$(CONFIG_USB_F_SS_LB) += f_ss_lb.o
-obj-$(CONFIG_USB_U_SERIAL) += u_serial.o
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index 7c821de8ce3d..c0d62b278610 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -1757,10 +1757,7 @@ static const struct usb_gadget_driver composite_driver_template = {
/**
* usb_composite_probe() - register a composite driver
* @driver: the driver to register
- * @bind: the callback used to allocate resources that are shared across the
- * whole device, such as string IDs, and add its configurations using
- * @usb_add_config(). This may fail by returning a negative errno
- * value; it should return zero on successful initialization.
+ *
* Context: single threaded during gadget setup
*
* This function is used to register drivers using the composite driver
diff --git a/drivers/usb/gadget/f_uac1.c b/drivers/usb/gadget/f_uac1.c
index f570e667a640..fa8ea4ea00c1 100644
--- a/drivers/usb/gadget/f_uac1.c
+++ b/drivers/usb/gadget/f_uac1.c
@@ -418,6 +418,7 @@ static int audio_get_intf_req(struct usb_function *f,
req->context = audio;
req->complete = f_audio_complete;
+ len = min_t(size_t, sizeof(value), len);
memcpy(req->buf, &value, len);
return len;
diff --git a/drivers/usb/gadget/imx_udc.c b/drivers/usb/gadget/imx_udc.c
index 8efd7555fa21..5bd930d779b9 100644
--- a/drivers/usb/gadget/imx_udc.c
+++ b/drivers/usb/gadget/imx_udc.c
@@ -1334,27 +1334,18 @@ static int imx_udc_start(struct usb_gadget *gadget,
struct usb_gadget_driver *driver)
{
struct imx_udc_struct *imx_usb;
- int retval;
imx_usb = container_of(gadget, struct imx_udc_struct, gadget);
/* first hook up the driver ... */
imx_usb->driver = driver;
imx_usb->gadget.dev.driver = &driver->driver;
- retval = device_add(&imx_usb->gadget.dev);
- if (retval)
- goto fail;
-
D_INI(imx_usb->dev, "<%s> registered gadget driver '%s'\n",
__func__, driver->driver.name);
imx_udc_enable(imx_usb);
return 0;
-fail:
- imx_usb->driver = NULL;
- imx_usb->gadget.dev.driver = NULL;
- return retval;
}
static int imx_udc_stop(struct usb_gadget *gadget,
@@ -1370,8 +1361,6 @@ static int imx_udc_stop(struct usb_gadget *gadget,
imx_usb->gadget.dev.driver = NULL;
imx_usb->driver = NULL;
- device_del(&imx_usb->gadget.dev);
-
D_INI(imx_usb->dev, "<%s> unregistered gadget driver '%s'\n",
__func__, driver->driver.name);
@@ -1477,6 +1466,10 @@ static int __init imx_udc_probe(struct platform_device *pdev)
imx_usb->gadget.dev.parent = &pdev->dev;
imx_usb->gadget.dev.dma_mask = pdev->dev.dma_mask;
+ ret = device_add(&imx_usb->gadget.dev);
+ if (retval)
+ goto fail4;
+
platform_set_drvdata(pdev, imx_usb);
usb_init_data(imx_usb);
@@ -1488,9 +1481,11 @@ static int __init imx_udc_probe(struct platform_device *pdev)
ret = usb_add_gadget_udc(&pdev->dev, &imx_usb->gadget);
if (ret)
- goto fail4;
+ goto fail5;
return 0;
+fail5:
+ device_unregister(&imx_usb->gadget.dev);
fail4:
for (i = 0; i < IMX_USB_NB_EP + 1; i++)
free_irq(imx_usb->usbd_int[i], imx_usb);
@@ -1514,6 +1509,7 @@ static int __exit imx_udc_remove(struct platform_device *pdev)
int i;
usb_del_gadget_udc(&imx_usb->gadget);
+ device_unregister(&imx_usb->gadget.dev);
imx_udc_disable(imx_usb);
del_timer(&imx_usb->timer);
diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c
index 06be85c2b233..f8445653577f 100644
--- a/drivers/usb/gadget/omap_udc.c
+++ b/drivers/usb/gadget/omap_udc.c
@@ -62,6 +62,7 @@
#define DRIVER_VERSION "4 October 2004"
#define OMAP_DMA_USB_W2FC_TX0 29
+#define OMAP_DMA_USB_W2FC_RX0 26
/*
* The OMAP UDC needs _very_ early endpoint setup: before enabling the
@@ -1310,7 +1311,7 @@ static int omap_pullup(struct usb_gadget *gadget, int is_on)
}
static int omap_udc_start(struct usb_gadget *g,
- struct usb_gadget_driver *driver)
+ struct usb_gadget_driver *driver);
static int omap_udc_stop(struct usb_gadget *g,
struct usb_gadget_driver *driver);
diff --git a/drivers/usb/gadget/pxa25x_udc.c b/drivers/usb/gadget/pxa25x_udc.c
index 2bbcdce942dc..d0f37484b6b0 100644
--- a/drivers/usb/gadget/pxa25x_udc.c
+++ b/drivers/usb/gadget/pxa25x_udc.c
@@ -1266,13 +1266,6 @@ static int pxa25x_udc_start(struct usb_gadget *g,
dev->gadget.dev.driver = &driver->driver;
dev->pullup = 1;
- retval = device_add (&dev->gadget.dev);
- if (retval) {
- dev->driver = NULL;
- dev->gadget.dev.driver = NULL;
- return retval;
- }
-
/* ... then enable host detection and ep0; and we're ready
* for set_configuration as well as eventual disconnect.
*/
@@ -1310,6 +1303,10 @@ stop_activity(struct pxa25x_udc *dev, struct usb_gadget_driver *driver)
}
del_timer_sync(&dev->timer);
+ /* report disconnect; the driver is already quiesced */
+ if (driver)
+ driver->disconnect(&dev->gadget);
+
/* re-init driver-visible data structures */
udc_reinit(dev);
}
@@ -1331,7 +1328,6 @@ static int pxa25x_udc_stop(struct usb_gadget*g,
dev->gadget.dev.driver = NULL;
dev->driver = NULL;
- device_del (&dev->gadget.dev);
dump_state(dev);
return 0;
@@ -2146,6 +2142,13 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev)
dev->gadget.dev.parent = &pdev->dev;
dev->gadget.dev.dma_mask = pdev->dev.dma_mask;
+ retval = device_add(&dev->gadget.dev);
+ if (retval) {
+ dev->driver = NULL;
+ dev->gadget.dev.driver = NULL;
+ goto err_device_add;
+ }
+
the_controller = dev;
platform_set_drvdata(pdev, dev);
@@ -2196,6 +2199,8 @@ lubbock_fail0:
free_irq(irq, dev);
#endif
err_irq1:
+ device_unregister(&dev->gadget.dev);
+ err_device_add:
if (gpio_is_valid(dev->mach->gpio_pullup))
gpio_free(dev->mach->gpio_pullup);
err_gpio_pullup:
@@ -2217,10 +2222,11 @@ static int __exit pxa25x_udc_remove(struct platform_device *pdev)
{
struct pxa25x_udc *dev = platform_get_drvdata(pdev);
- usb_del_gadget_udc(&dev->gadget);
if (dev->driver)
return -EBUSY;
+ usb_del_gadget_udc(&dev->gadget);
+ device_unregister(&dev->gadget.dev);
dev->pullup = 0;
pullup(dev);
diff --git a/drivers/usb/gadget/pxa27x_udc.c b/drivers/usb/gadget/pxa27x_udc.c
index f7d25795821a..2fc867652ef5 100644
--- a/drivers/usb/gadget/pxa27x_udc.c
+++ b/drivers/usb/gadget/pxa27x_udc.c
@@ -1814,11 +1814,6 @@ static int pxa27x_udc_start(struct usb_gadget *g,
udc->gadget.dev.driver = &driver->driver;
dplus_pullup(udc, 1);
- retval = device_add(&udc->gadget.dev);
- if (retval) {
- dev_err(udc->dev, "device_add error %d\n", retval);
- goto fail;
- }
if (!IS_ERR_OR_NULL(udc->transceiver)) {
retval = otg_set_peripheral(udc->transceiver->otg,
&udc->gadget);
@@ -1876,7 +1871,6 @@ static int pxa27x_udc_stop(struct usb_gadget *g,
udc->driver = NULL;
- device_del(&udc->gadget.dev);
if (!IS_ERR_OR_NULL(udc->transceiver))
return otg_set_peripheral(udc->transceiver->otg, NULL);
@@ -2480,13 +2474,24 @@ static int __init pxa_udc_probe(struct platform_device *pdev)
driver_name, udc->irq, retval);
goto err_irq;
}
+
+ retval = device_add(&udc->gadget.dev);
+ if (retval) {
+ dev_err(udc->dev, "device_add error %d\n", retval);
+ goto err_dev_add;
+ }
+
retval = usb_add_gadget_udc(&pdev->dev, &udc->gadget);
if (retval)
goto err_add_udc;
pxa_init_debugfs(udc);
+
return 0;
+
err_add_udc:
+ device_unregister(&udc->gadget.dev);
+err_dev_add:
free_irq(udc->irq, udc);
err_irq:
iounmap(udc->regs);
@@ -2507,6 +2512,7 @@ static int __exit pxa_udc_remove(struct platform_device *_dev)
int gpio = udc->mach->gpio_pullup;
usb_del_gadget_udc(&udc->gadget);
+ device_del(&udc->gadget.dev);
usb_gadget_unregister_driver(udc->driver);
free_irq(udc->irq, udc);
pxa_cleanup_debugfs(udc);
diff --git a/drivers/usb/gadget/s3c2410_udc.c b/drivers/usb/gadget/s3c2410_udc.c
index fc07b4381286..08f89652533b 100644
--- a/drivers/usb/gadget/s3c2410_udc.c
+++ b/drivers/usb/gadget/s3c2410_udc.c
@@ -1668,8 +1668,7 @@ static void s3c2410_udc_enable(struct s3c2410_udc *dev)
static int s3c2410_udc_start(struct usb_gadget *g,
struct usb_gadget_driver *driver)
{
- struct s3c2410_udc *udc = to_s3c2410(g)
- int retval;
+ struct s3c2410_udc *udc = to_s3c2410(g);
dprintk(DEBUG_NORMAL, "%s() '%s'\n", __func__, driver->driver.name);
@@ -1677,22 +1676,10 @@ static int s3c2410_udc_start(struct usb_gadget *g,
udc->driver = driver;
udc->gadget.dev.driver = &driver->driver;
- /* Bind the driver */
- retval = device_add(&udc->gadget.dev);
- if (retval) {
- dev_err(&udc->gadget.dev, "Error in device_add() : %d\n", retval);
- goto register_error;
- }
-
/* Enable udc */
s3c2410_udc_enable(udc);
return 0;
-
-register_error:
- udc->driver = NULL;
- udc->gadget.dev.driver = NULL;
- return retval;
}
static int s3c2410_udc_stop(struct usb_gadget *g,
@@ -1700,7 +1687,6 @@ static int s3c2410_udc_stop(struct usb_gadget *g,
{
struct s3c2410_udc *udc = to_s3c2410(g);
- device_del(&udc->gadget.dev);
udc->driver = NULL;
/* Disable udc */
@@ -1842,6 +1828,13 @@ static int s3c2410_udc_probe(struct platform_device *pdev)
udc->gadget.dev.parent = &pdev->dev;
udc->gadget.dev.dma_mask = pdev->dev.dma_mask;
+ /* Bind the driver */
+ retval = device_add(&udc->gadget.dev);
+ if (retval) {
+ dev_err(&udc->gadget.dev, "Error in device_add() : %d\n", retval);
+ goto err_device_add;
+ }
+
the_controller = udc;
platform_set_drvdata(pdev, udc);
@@ -1930,6 +1923,8 @@ err_gpio_claim:
err_int:
free_irq(IRQ_USBD, udc);
err_map:
+ device_unregister(&udc->gadget.dev);
+err_device_add:
iounmap(base_addr);
err_mem:
release_mem_region(rsrc_start, rsrc_len);
@@ -1947,10 +1942,11 @@ static int s3c2410_udc_remove(struct platform_device *pdev)
dev_dbg(&pdev->dev, "%s()\n", __func__);
- usb_del_gadget_udc(&udc->gadget);
if (udc->driver)
return -EBUSY;
+ usb_del_gadget_udc(&udc->gadget);
+ device_unregister(&udc->gadget.dev);
debugfs_remove(udc->regs_info);
if (udc_info && !udc_info->udc_command &&
diff --git a/drivers/usb/gadget/u_uac1.c b/drivers/usb/gadget/u_uac1.c
index e0c5e88e03ed..c7d460f43390 100644
--- a/drivers/usb/gadget/u_uac1.c
+++ b/drivers/usb/gadget/u_uac1.c
@@ -240,8 +240,11 @@ static int gaudio_open_snd_dev(struct gaudio *card)
snd = &card->playback;
snd->filp = filp_open(fn_play, O_WRONLY, 0);
if (IS_ERR(snd->filp)) {
+ int ret = PTR_ERR(snd->filp);
+
ERROR(card, "No such PCM playback device: %s\n", fn_play);
snd->filp = NULL;
+ return ret;
}
pcm_file = snd->filp->private_data;
snd->substream = pcm_file->substream;
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index b416a3fc9959..5726cb144abf 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -748,11 +748,9 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
/* guard against (alleged) silicon errata */
if (cmd & CMD_IAAD)
ehci_dbg(ehci, "IAA with IAAD still set?\n");
- if (ehci->async_iaa) {
+ if (ehci->async_iaa)
COUNT(ehci->stats.iaa);
- end_unlink_async(ehci);
- } else
- ehci_dbg(ehci, "IAA with nothing unlinked?\n");
+ end_unlink_async(ehci);
}
/* remote wakeup [4.3.1] */
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c
index fd252f0cfb3a..5464665f0b6a 100644
--- a/drivers/usb/host/ehci-q.c
+++ b/drivers/usb/host/ehci-q.c
@@ -135,7 +135,7 @@ qh_refresh (struct ehci_hcd *ehci, struct ehci_qh *qh)
* qtd is updated in qh_completions(). Update the QH
* overlay here.
*/
- if (cpu_to_hc32(ehci, qtd->qtd_dma) == qh->hw->hw_current) {
+ if (qh->hw->hw_token & ACTIVE_BIT(ehci)) {
qh->hw->hw_qtd_next = qtd->hw_next;
qtd = NULL;
}
@@ -449,11 +449,19 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh)
else if (last_status == -EINPROGRESS && !urb->unlinked)
continue;
- /* qh unlinked; token in overlay may be most current */
- if (state == QH_STATE_IDLE
- && cpu_to_hc32(ehci, qtd->qtd_dma)
- == hw->hw_current) {
+ /*
+ * If this was the active qtd when the qh was unlinked
+ * and the overlay's token is active, then the overlay
+ * hasn't been written back to the qtd yet so use its
+ * token instead of the qtd's. After the qtd is
+ * processed and removed, the overlay won't be valid
+ * any more.
+ */
+ if (state == QH_STATE_IDLE &&
+ qh->qtd_list.next == &qtd->qtd_list &&
+ (hw->hw_token & ACTIVE_BIT(ehci))) {
token = hc32_to_cpu(ehci, hw->hw_token);
+ hw->hw_token &= ~ACTIVE_BIT(ehci);
/* An unlink may leave an incomplete
* async transaction in the TT buffer.
@@ -1170,7 +1178,7 @@ static void single_unlink_async(struct ehci_hcd *ehci, struct ehci_qh *qh)
struct ehci_qh *prev;
/* Add to the end of the list of QHs waiting for the next IAAD */
- qh->qh_state = QH_STATE_UNLINK;
+ qh->qh_state = QH_STATE_UNLINK_WAIT;
if (ehci->async_unlink)
ehci->async_unlink_last->unlink_next = qh;
else
@@ -1213,9 +1221,19 @@ static void start_iaa_cycle(struct ehci_hcd *ehci, bool nested)
/* Do only the first waiting QH (nVidia bug?) */
qh = ehci->async_unlink;
- ehci->async_iaa = qh;
- ehci->async_unlink = qh->unlink_next;
- qh->unlink_next = NULL;
+
+ /*
+ * Intel (?) bug: The HC can write back the overlay region
+ * even after the IAA interrupt occurs. In self-defense,
+ * always go through two IAA cycles for each QH.
+ */
+ if (qh->qh_state == QH_STATE_UNLINK_WAIT) {
+ qh->qh_state = QH_STATE_UNLINK;
+ } else {
+ ehci->async_iaa = qh;
+ ehci->async_unlink = qh->unlink_next;
+ qh->unlink_next = NULL;
+ }
/* Make sure the unlinks are all visible to the hardware */
wmb();
diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig
index 45b19e2c60ba..05e51432dd2f 100644
--- a/drivers/usb/musb/Kconfig
+++ b/drivers/usb/musb/Kconfig
@@ -7,11 +7,6 @@
config USB_MUSB_HDRC
tristate 'Inventra Highspeed Dual Role Controller (TI, ADI, ...)'
depends on USB && USB_GADGET
- select NOP_USB_XCEIV if (ARCH_DAVINCI || MACH_OMAP3EVM || BLACKFIN)
- select NOP_USB_XCEIV if (SOC_TI81XX || SOC_AM33XX)
- select TWL4030_USB if MACH_OMAP_3430SDP
- select TWL6030_USB if MACH_OMAP_4430SDP || MACH_OMAP4_PANDA
- select OMAP_CONTROL_USB if MACH_OMAP_4430SDP || MACH_OMAP4_PANDA
select USB_OTG_UTILS
help
Say Y here if your system has a dual role high speed USB
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index 60b41cc28da4..daec6e0f7e38 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -1624,8 +1624,6 @@ EXPORT_SYMBOL_GPL(musb_dma_completion);
/*-------------------------------------------------------------------------*/
-#ifdef CONFIG_SYSFS
-
static ssize_t
musb_mode_show(struct device *dev, struct device_attribute *attr, char *buf)
{
@@ -1742,8 +1740,6 @@ static const struct attribute_group musb_attr_group = {
.attrs = musb_attributes,
};
-#endif /* sysfs */
-
/* Only used to provide driver mode change events */
static void musb_irq_work(struct work_struct *data)
{
@@ -1968,11 +1964,9 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
if (status < 0)
goto fail4;
-#ifdef CONFIG_SYSFS
status = sysfs_create_group(&musb->controller->kobj, &musb_attr_group);
if (status)
goto fail5;
-#endif
pm_runtime_put(musb->controller);
diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c
index 1762354fe793..1a42a458f2c4 100644
--- a/drivers/usb/musb/omap2430.c
+++ b/drivers/usb/musb/omap2430.c
@@ -51,7 +51,7 @@ struct omap2430_glue {
};
#define glue_to_musb(g) platform_get_drvdata(g->musb)
-struct omap2430_glue *_glue;
+static struct omap2430_glue *_glue;
static struct timer_list musb_idle_timer;
@@ -237,9 +237,13 @@ void omap_musb_mailbox(enum omap_musb_vbus_id_status status)
{
struct omap2430_glue *glue = _glue;
- if (glue && glue_to_musb(glue)) {
- glue->status = status;
- } else {
+ if (!glue) {
+ pr_err("%s: musb core is not yet initialized\n", __func__);
+ return;
+ }
+ glue->status = status;
+
+ if (!glue_to_musb(glue)) {
pr_err("%s: musb core is not yet ready\n", __func__);
return;
}
diff --git a/drivers/usb/otg/otg.c b/drivers/usb/otg/otg.c
index e1814397ca3a..2bd03d261a50 100644
--- a/drivers/usb/otg/otg.c
+++ b/drivers/usb/otg/otg.c
@@ -130,7 +130,7 @@ struct usb_phy *usb_get_phy(enum usb_phy_type type)
spin_lock_irqsave(&phy_lock, flags);
phy = __usb_find_phy(&phy_list, type);
- if (IS_ERR(phy)) {
+ if (IS_ERR(phy) || !try_module_get(phy->dev->driver->owner)) {
pr_err("unable to find transceiver of type %s\n",
usb_phy_type_string(type));
goto err0;
@@ -228,7 +228,7 @@ struct usb_phy *usb_get_phy_dev(struct device *dev, u8 index)
spin_lock_irqsave(&phy_lock, flags);
phy = __usb_find_phy_dev(dev, &phy_bind_list, index);
- if (IS_ERR(phy)) {
+ if (IS_ERR(phy) || !try_module_get(phy->dev->driver->owner)) {
pr_err("unable to find transceiver\n");
goto err0;
}
@@ -301,8 +301,12 @@ EXPORT_SYMBOL(devm_usb_put_phy);
*/
void usb_put_phy(struct usb_phy *x)
{
- if (x)
+ if (x) {
+ struct module *owner = x->dev->driver->owner;
+
put_device(x->dev);
+ module_put(owner);
+ }
}
EXPORT_SYMBOL(usb_put_phy);
diff --git a/drivers/usb/phy/omap-control-usb.c b/drivers/usb/phy/omap-control-usb.c
index 5323b71c3521..1419ceda9759 100644
--- a/drivers/usb/phy/omap-control-usb.c
+++ b/drivers/usb/phy/omap-control-usb.c
@@ -219,32 +219,26 @@ static int omap_control_usb_probe(struct platform_device *pdev)
res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
"control_dev_conf");
- control_usb->dev_conf = devm_request_and_ioremap(&pdev->dev, res);
- if (!control_usb->dev_conf) {
- dev_err(&pdev->dev, "Failed to obtain io memory\n");
- return -EADDRNOTAVAIL;
- }
+ control_usb->dev_conf = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(control_usb->dev_conf))
+ return PTR_ERR(control_usb->dev_conf);
if (control_usb->type == OMAP_CTRL_DEV_TYPE1) {
res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
"otghs_control");
- control_usb->otghs_control = devm_request_and_ioremap(
+ control_usb->otghs_control = devm_ioremap_resource(
&pdev->dev, res);
- if (!control_usb->otghs_control) {
- dev_err(&pdev->dev, "Failed to obtain io memory\n");
- return -EADDRNOTAVAIL;
- }
+ if (IS_ERR(control_usb->otghs_control))
+ return PTR_ERR(control_usb->otghs_control);
}
if (control_usb->type == OMAP_CTRL_DEV_TYPE2) {
res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
"phy_power_usb");
- control_usb->phy_power = devm_request_and_ioremap(
+ control_usb->phy_power = devm_ioremap_resource(
&pdev->dev, res);
- if (!control_usb->phy_power) {
- dev_dbg(&pdev->dev, "Failed to obtain io memory\n");
- return -EADDRNOTAVAIL;
- }
+ if (IS_ERR(control_usb->phy_power))
+ return PTR_ERR(control_usb->phy_power);
control_usb->sys_clk = devm_clk_get(control_usb->dev,
"sys_clkin");
diff --git a/drivers/usb/phy/omap-usb3.c b/drivers/usb/phy/omap-usb3.c
index fadc0c2b65bb..a6e60b1e102e 100644
--- a/drivers/usb/phy/omap-usb3.c
+++ b/drivers/usb/phy/omap-usb3.c
@@ -212,11 +212,9 @@ static int omap_usb3_probe(struct platform_device *pdev)
}
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pll_ctrl");
- phy->pll_ctrl_base = devm_request_and_ioremap(&pdev->dev, res);
- if (!phy->pll_ctrl_base) {
- dev_err(&pdev->dev, "ioremap of pll_ctrl failed\n");
- return -ENOMEM;
- }
+ phy->pll_ctrl_base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(phy->pll_ctrl_base))
+ return PTR_ERR(phy->pll_ctrl_base);
phy->dev = &pdev->dev;
diff --git a/drivers/usb/phy/samsung-usbphy.c b/drivers/usb/phy/samsung-usbphy.c
index 6ea553733832..967101ec15fd 100644
--- a/drivers/usb/phy/samsung-usbphy.c
+++ b/drivers/usb/phy/samsung-usbphy.c
@@ -787,11 +787,9 @@ static int samsung_usbphy_probe(struct platform_device *pdev)
return -ENODEV;
}
- phy_base = devm_request_and_ioremap(dev, phy_mem);
- if (!phy_base) {
- dev_err(dev, "%s: register mapping failed\n", __func__);
- return -ENXIO;
- }
+ phy_base = devm_ioremap_resource(dev, phy_mem);
+ if (IS_ERR(phy_base))
+ return PTR_ERR(phy_base);
sphy = devm_kzalloc(dev, sizeof(*sphy), GFP_KERNEL);
if (!sphy)
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
index edc0f0dcad83..4747d1c328ff 100644
--- a/drivers/usb/serial/cp210x.c
+++ b/drivers/usb/serial/cp210x.c
@@ -85,6 +85,7 @@ static const struct usb_device_id id_table[] = {
{ USB_DEVICE(0x10C4, 0x813F) }, /* Tams Master Easy Control */
{ USB_DEVICE(0x10C4, 0x814A) }, /* West Mountain Radio RIGblaster P&P */
{ USB_DEVICE(0x10C4, 0x814B) }, /* West Mountain Radio RIGtalk */
+ { USB_DEVICE(0x2405, 0x0003) }, /* West Mountain Radio RIGblaster Advantage */
{ USB_DEVICE(0x10C4, 0x8156) }, /* B&G H3000 link cable */
{ USB_DEVICE(0x10C4, 0x815E) }, /* Helicomm IP-Link 1220-DVM */
{ USB_DEVICE(0x10C4, 0x815F) }, /* Timewave HamLinkUSB */
@@ -150,6 +151,25 @@ static const struct usb_device_id id_table[] = {
{ USB_DEVICE(0x1BE3, 0x07A6) }, /* WAGO 750-923 USB Service Cable */
{ USB_DEVICE(0x1E29, 0x0102) }, /* Festo CPX-USB */
{ USB_DEVICE(0x1E29, 0x0501) }, /* Festo CMSP */
+ { USB_DEVICE(0x1FB9, 0x0100) }, /* Lake Shore Model 121 Current Source */
+ { USB_DEVICE(0x1FB9, 0x0200) }, /* Lake Shore Model 218A Temperature Monitor */
+ { USB_DEVICE(0x1FB9, 0x0201) }, /* Lake Shore Model 219 Temperature Monitor */
+ { USB_DEVICE(0x1FB9, 0x0202) }, /* Lake Shore Model 233 Temperature Transmitter */
+ { USB_DEVICE(0x1FB9, 0x0203) }, /* Lake Shore Model 235 Temperature Transmitter */
+ { USB_DEVICE(0x1FB9, 0x0300) }, /* Lake Shore Model 335 Temperature Controller */
+ { USB_DEVICE(0x1FB9, 0x0301) }, /* Lake Shore Model 336 Temperature Controller */
+ { USB_DEVICE(0x1FB9, 0x0302) }, /* Lake Shore Model 350 Temperature Controller */
+ { USB_DEVICE(0x1FB9, 0x0303) }, /* Lake Shore Model 371 AC Bridge */
+ { USB_DEVICE(0x1FB9, 0x0400) }, /* Lake Shore Model 411 Handheld Gaussmeter */
+ { USB_DEVICE(0x1FB9, 0x0401) }, /* Lake Shore Model 425 Gaussmeter */
+ { USB_DEVICE(0x1FB9, 0x0402) }, /* Lake Shore Model 455A Gaussmeter */
+ { USB_DEVICE(0x1FB9, 0x0403) }, /* Lake Shore Model 475A Gaussmeter */
+ { USB_DEVICE(0x1FB9, 0x0404) }, /* Lake Shore Model 465 Three Axis Gaussmeter */
+ { USB_DEVICE(0x1FB9, 0x0600) }, /* Lake Shore Model 625A Superconducting MPS */
+ { USB_DEVICE(0x1FB9, 0x0601) }, /* Lake Shore Model 642A Magnet Power Supply */
+ { USB_DEVICE(0x1FB9, 0x0602) }, /* Lake Shore Model 648 Magnet Power Supply */
+ { USB_DEVICE(0x1FB9, 0x0700) }, /* Lake Shore Model 737 VSM Controller */
+ { USB_DEVICE(0x1FB9, 0x0701) }, /* Lake Shore Model 776 Hall Matrix */
{ USB_DEVICE(0x3195, 0xF190) }, /* Link Instruments MSO-19 */
{ USB_DEVICE(0x3195, 0xF280) }, /* Link Instruments MSO-28 */
{ USB_DEVICE(0x3195, 0xF281) }, /* Link Instruments MSO-28 */
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index f7d339d8187b..558adfc05007 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -341,6 +341,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_AH6 0x0055
+#define CINTERION_PRODUCT_PLS8 0x0060
/* Olivetti products */
#define OLIVETTI_VENDOR_ID 0x0b3c
@@ -579,6 +581,7 @@ static const struct usb_device_id option_ids[] = {
{ USB_DEVICE(QUANTA_VENDOR_ID, 0xea42),
.driver_info = (kernel_ulong_t)&net_intf4_blacklist },
{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1c05, USB_CLASS_COMM, 0x02, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1c1f, USB_CLASS_COMM, 0x02, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1c23, USB_CLASS_COMM, 0x02, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E173, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t) &net_intf1_blacklist },
@@ -1260,6 +1263,8 @@ 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_HC28_MDM) },
{ USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_HC28_MDMNET) },
{ USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC25_MDM) },
diff --git a/drivers/usb/serial/qcaux.c b/drivers/usb/serial/qcaux.c
index 9b1b96f2d095..31f81c3c15eb 100644
--- a/drivers/usb/serial/qcaux.c
+++ b/drivers/usb/serial/qcaux.c
@@ -69,6 +69,7 @@ static struct usb_device_id id_table[] = {
{ USB_VENDOR_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, 0xff, 0xfd, 0xff) }, /* NMEA */
{ USB_VENDOR_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, 0xff, 0xfe, 0xff) }, /* WMC */
{ USB_VENDOR_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, 0xff, 0xff, 0xff) }, /* DIAG */
+ { USB_DEVICE_AND_INTERFACE_INFO(0x1fac, 0x0151, 0xff, 0xff, 0xff) },
{ },
};
MODULE_DEVICE_TABLE(usb, id_table);
diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c
index 24662547dc5b..59b32b782126 100644
--- a/drivers/usb/serial/qcserial.c
+++ b/drivers/usb/serial/qcserial.c
@@ -197,12 +197,15 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id)
if (is_gobi1k) {
/* Gobi 1K USB layout:
- * 0: serial port (doesn't respond)
+ * 0: DM/DIAG (use libqcdm from ModemManager for communication)
* 1: serial port (doesn't respond)
* 2: AT-capable modem port
* 3: QMI/net
*/
- if (ifnum == 2)
+ if (ifnum == 0) {
+ dev_dbg(dev, "Gobi 1K DM/DIAG interface found\n");
+ altsetting = 1;
+ } else if (ifnum == 2)
dev_dbg(dev, "Modem port found\n");
else
altsetting = -1;
diff --git a/drivers/usb/serial/quatech2.c b/drivers/usb/serial/quatech2.c
index 00e6c9bac8a3..d643a4d4d770 100644
--- a/drivers/usb/serial/quatech2.c
+++ b/drivers/usb/serial/quatech2.c
@@ -661,7 +661,9 @@ void qt2_process_read_urb(struct urb *urb)
__func__);
break;
}
- tty_flip_buffer_push(&port->port);
+
+ if (port_priv->is_open)
+ tty_flip_buffer_push(&port->port);
newport = *(ch + 3);
@@ -704,7 +706,8 @@ void qt2_process_read_urb(struct urb *urb)
tty_insert_flip_string(&port->port, ch, 1);
}
- tty_flip_buffer_push(&port->port);
+ if (port_priv->is_open)
+ tty_flip_buffer_push(&port->port);
}
static void qt2_write_bulk_callback(struct urb *urb)
diff --git a/drivers/usb/storage/initializers.c b/drivers/usb/storage/initializers.c
index 7ab9046ae0ec..105d900150c1 100644
--- a/drivers/usb/storage/initializers.c
+++ b/drivers/usb/storage/initializers.c
@@ -92,8 +92,8 @@ int usb_stor_ucr61s2b_init(struct us_data *us)
return 0;
}
-/* This places the HUAWEI usb dongles in multi-port mode */
-static int usb_stor_huawei_feature_init(struct us_data *us)
+/* This places the HUAWEI E220 devices in multi-port mode */
+int usb_stor_huawei_e220_init(struct us_data *us)
{
int result;
@@ -104,75 +104,3 @@ static int usb_stor_huawei_feature_init(struct us_data *us)
US_DEBUGP("Huawei mode set result is %d\n", result);
return 0;
}
-
-/*
- * It will send a scsi switch command called rewind' to huawei dongle.
- * When the dongle receives this command at the first time,
- * it will reboot immediately. After rebooted, it will ignore this command.
- * So it is unnecessary to read its response.
- */
-static int usb_stor_huawei_scsi_init(struct us_data *us)
-{
- int result = 0;
- int act_len = 0;
- struct bulk_cb_wrap *bcbw = (struct bulk_cb_wrap *) us->iobuf;
- char rewind_cmd[] = {0x11, 0x06, 0x20, 0x00, 0x00, 0x01, 0x01, 0x00,
- 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-
- bcbw->Signature = cpu_to_le32(US_BULK_CB_SIGN);
- bcbw->Tag = 0;
- bcbw->DataTransferLength = 0;
- bcbw->Flags = bcbw->Lun = 0;
- bcbw->Length = sizeof(rewind_cmd);
- memset(bcbw->CDB, 0, sizeof(bcbw->CDB));
- memcpy(bcbw->CDB, rewind_cmd, sizeof(rewind_cmd));
-
- result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, bcbw,
- US_BULK_CB_WRAP_LEN, &act_len);
- US_DEBUGP("transfer actual length=%d, result=%d\n", act_len, result);
- return result;
-}
-
-/*
- * It tries to find the supported Huawei USB dongles.
- * In Huawei, they assign the following product IDs
- * for all of their mobile broadband dongles,
- * including the new dongles in the future.
- * So if the product ID is not included in this list,
- * it means it is not Huawei's mobile broadband dongles.
- */
-static int usb_stor_huawei_dongles_pid(struct us_data *us)
-{
- struct usb_interface_descriptor *idesc;
- int idProduct;
-
- idesc = &us->pusb_intf->cur_altsetting->desc;
- idProduct = le16_to_cpu(us->pusb_dev->descriptor.idProduct);
- /* The first port is CDROM,
- * means the dongle in the single port mode,
- * and a switch command is required to be sent. */
- if (idesc && idesc->bInterfaceNumber == 0) {
- if ((idProduct == 0x1001)
- || (idProduct == 0x1003)
- || (idProduct == 0x1004)
- || (idProduct >= 0x1401 && idProduct <= 0x1500)
- || (idProduct >= 0x1505 && idProduct <= 0x1600)
- || (idProduct >= 0x1c02 && idProduct <= 0x2202)) {
- return 1;
- }
- }
- return 0;
-}
-
-int usb_stor_huawei_init(struct us_data *us)
-{
- int result = 0;
-
- if (usb_stor_huawei_dongles_pid(us)) {
- if (le16_to_cpu(us->pusb_dev->descriptor.idProduct) >= 0x1446)
- result = usb_stor_huawei_scsi_init(us);
- else
- result = usb_stor_huawei_feature_init(us);
- }
- return result;
-}
diff --git a/drivers/usb/storage/initializers.h b/drivers/usb/storage/initializers.h
index 5376d4fc76f0..529327fbb06b 100644
--- a/drivers/usb/storage/initializers.h
+++ b/drivers/usb/storage/initializers.h
@@ -46,5 +46,5 @@ int usb_stor_euscsi_init(struct us_data *us);
* flash reader */
int usb_stor_ucr61s2b_init(struct us_data *us);
-/* This places the HUAWEI usb dongles in multi-port mode */
-int usb_stor_huawei_init(struct us_data *us);
+/* This places the HUAWEI E220 devices in multi-port mode */
+int usb_stor_huawei_e220_init(struct us_data *us);
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
index 72923b56bbf6..da04a074e790 100644
--- a/drivers/usb/storage/unusual_devs.h
+++ b/drivers/usb/storage/unusual_devs.h
@@ -53,6 +53,14 @@
* as opposed to devices that do something strangely or wrongly.
*/
+/* In-kernel mode switching is deprecated. Do not add new devices to
+ * this list for the sole purpose of switching them to a different
+ * mode. Existing userspace solutions are superior.
+ *
+ * New mode switching devices should instead be added to the database
+ * maintained at http://www.draisberghof.de/usb_modeswitch/
+ */
+
#if !defined(CONFIG_USB_STORAGE_SDDR09) && \
!defined(CONFIG_USB_STORAGE_SDDR09_MODULE)
#define NO_SDDR09
@@ -1527,10 +1535,335 @@ UNUSUAL_DEV( 0x1210, 0x0003, 0x0100, 0x0100,
/* Reported by fangxiaozhi <huananhu@huawei.com>
* This brings the HUAWEI data card devices into multi-port mode
*/
-UNUSUAL_VENDOR_INTF(0x12d1, 0x08, 0x06, 0x50,
+UNUSUAL_DEV( 0x12d1, 0x1001, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1003, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1004, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1401, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1402, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1403, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1404, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1405, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1406, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1407, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1408, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1409, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x140A, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x140B, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x140C, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x140D, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x140E, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x140F, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1410, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1411, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1412, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1413, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1414, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1415, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1416, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1417, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1418, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1419, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x141A, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x141B, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x141C, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x141D, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x141E, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x141F, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1420, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1421, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1422, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1423, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1424, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1425, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1426, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1427, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1428, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1429, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x142A, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x142B, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x142C, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x142D, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x142E, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x142F, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1430, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1431, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1432, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1433, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1434, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1435, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1436, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1437, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1438, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1439, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x143A, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x143B, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x143C, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x143D, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x143E, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x143F, 0x0000, 0x0000,
"HUAWEI MOBILE",
"Mass Storage",
- USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_init,
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
0),
/* Reported by Vilius Bilinkevicius <vilisas AT xxx DOT lt) */
diff --git a/drivers/video/omap/lcd_ams_delta.c b/drivers/video/omap/lcd_ams_delta.c
index ed4cad87fbcd..4a5f2cd3d3bf 100644
--- a/drivers/video/omap/lcd_ams_delta.c
+++ b/drivers/video/omap/lcd_ams_delta.c
@@ -27,6 +27,7 @@
#include <linux/lcd.h>
#include <linux/gpio.h>
+#include <mach/hardware.h>
#include <mach/board-ams-delta.h>
#include "omapfb.h"
diff --git a/drivers/video/omap/lcd_osk.c b/drivers/video/omap/lcd_osk.c
index 3aa62da89195..7fbe04bce0ed 100644
--- a/drivers/video/omap/lcd_osk.c
+++ b/drivers/video/omap/lcd_osk.c
@@ -24,7 +24,10 @@
#include <linux/platform_device.h>
#include <asm/gpio.h>
+
+#include <mach/hardware.h>
#include <mach/mux.h>
+
#include "omapfb.h"
static int osk_panel_init(struct lcd_panel *panel, struct omapfb_device *fbdev)
diff --git a/drivers/w1/masters/w1-gpio.c b/drivers/w1/masters/w1-gpio.c
index d39dfa4cc235..46d97014342e 100644
--- a/drivers/w1/masters/w1-gpio.c
+++ b/drivers/w1/masters/w1-gpio.c
@@ -47,11 +47,13 @@ static u8 w1_gpio_read_bit(void *data)
return gpio_get_value(pdata->pin) ? 1 : 0;
}
+#if defined(CONFIG_OF)
static struct of_device_id w1_gpio_dt_ids[] = {
{ .compatible = "w1-gpio" },
{}
};
MODULE_DEVICE_TABLE(of, w1_gpio_dt_ids);
+#endif
static int w1_gpio_probe_dt(struct platform_device *pdev)
{
@@ -158,7 +160,7 @@ static int w1_gpio_probe(struct platform_device *pdev)
return err;
}
-static int __exit w1_gpio_remove(struct platform_device *pdev)
+static int w1_gpio_remove(struct platform_device *pdev)
{
struct w1_bus_master *master = platform_get_drvdata(pdev);
struct w1_gpio_platform_data *pdata = pdev->dev.platform_data;
@@ -210,7 +212,7 @@ static struct platform_driver w1_gpio_driver = {
.of_match_table = of_match_ptr(w1_gpio_dt_ids),
},
.probe = w1_gpio_probe,
- .remove = __exit_p(w1_gpio_remove),
+ .remove = w1_gpio_remove,
.suspend = w1_gpio_suspend,
.resume = w1_gpio_resume,
};
diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c
index 7994d933f040..7ce277d2bb67 100644
--- a/drivers/w1/w1.c
+++ b/drivers/w1/w1.c
@@ -924,7 +924,8 @@ void w1_search(struct w1_master *dev, u8 search_type, w1_slave_found_callback cb
tmp64 = (triplet_ret >> 2);
rn |= (tmp64 << i);
- if (kthread_should_stop()) {
+ /* ensure we're called from kthread and not by netlink callback */
+ if (!dev->priv && kthread_should_stop()) {
mutex_unlock(&dev->bus_mutex);
dev_dbg(&dev->dev, "Abort w1_search\n");
return;
diff --git a/drivers/xen/xen-acpi-processor.c b/drivers/xen/xen-acpi-processor.c
index 316df65163cf..f3278a6603ca 100644
--- a/drivers/xen/xen-acpi-processor.c
+++ b/drivers/xen/xen-acpi-processor.c
@@ -500,16 +500,16 @@ static int __init xen_acpi_processor_init(void)
(void)acpi_processor_preregister_performance(acpi_perf_data);
for_each_possible_cpu(i) {
+ struct acpi_processor *pr;
struct acpi_processor_performance *perf;
+ pr = per_cpu(processors, i);
perf = per_cpu_ptr(acpi_perf_data, i);
- rc = acpi_processor_register_performance(perf, i);
+ pr->performance = perf;
+ rc = acpi_processor_get_performance_info(pr);
if (rc)
goto err_out;
}
- rc = acpi_processor_notify_smm(THIS_MODULE);
- if (rc)
- goto err_unregister;
for_each_possible_cpu(i) {
struct acpi_processor *_pr;
diff --git a/drivers/xen/xen-pciback/pciback_ops.c b/drivers/xen/xen-pciback/pciback_ops.c
index 37c1f825f513..b98cf0c35725 100644
--- a/drivers/xen/xen-pciback/pciback_ops.c
+++ b/drivers/xen/xen-pciback/pciback_ops.c
@@ -113,7 +113,8 @@ void xen_pcibk_reset_device(struct pci_dev *dev)
if (dev->msi_enabled)
pci_disable_msi(dev);
#endif
- pci_disable_device(dev);
+ if (pci_is_enabled(dev))
+ pci_disable_device(dev);
pci_write_config_word(dev, PCI_COMMAND, 0);
diff --git a/drivers/xen/xen-stub.c b/drivers/xen/xen-stub.c
index d85e411cbf89..bbef194c5b01 100644
--- a/drivers/xen/xen-stub.c
+++ b/drivers/xen/xen-stub.c
@@ -25,7 +25,6 @@
#include <linux/export.h>
#include <linux/types.h>
#include <linux/acpi.h>
-#include <acpi/acpi_drivers.h>
#include <xen/acpi.h>
#ifdef CONFIG_ACPI
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 3e074dab2d57..9ac2eca681eb 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -1467,8 +1467,11 @@ int lookup_inline_extent_backref(struct btrfs_trans_handle *trans,
if (ret && !insert) {
err = -ENOENT;
goto out;
+ } else if (ret) {
+ err = -EIO;
+ WARN_ON(1);
+ goto out;
}
- BUG_ON(ret); /* Corruption */
leaf = path->nodes[0];
item_size = btrfs_item_size_nr(leaf, path->slots[0]);
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index af1d0605a5c1..5b4ea5f55b8f 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -591,6 +591,7 @@ void btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end,
}
compressed = test_bit(EXTENT_FLAG_COMPRESSED, &em->flags);
clear_bit(EXTENT_FLAG_PINNED, &em->flags);
+ clear_bit(EXTENT_FLAG_LOGGING, &flags);
remove_extent_mapping(em_tree, em);
if (no_splits)
goto next;
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index d1470adca8f8..ca1b767d51f7 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -2312,6 +2312,7 @@ again:
key.type = BTRFS_EXTENT_DATA_KEY;
key.offset = start;
+ path->leave_spinning = 1;
if (merge) {
struct btrfs_file_extent_item *fi;
u64 extent_len;
@@ -2368,6 +2369,7 @@ again:
btrfs_mark_buffer_dirty(leaf);
inode_add_bytes(inode, len);
+ btrfs_release_path(path);
ret = btrfs_inc_extent_ref(trans, root, new->bytenr,
new->disk_len, 0,
@@ -2381,6 +2383,7 @@ again:
ret = 1;
out_free_path:
btrfs_release_path(path);
+ path->leave_spinning = 0;
btrfs_end_transaction(trans, root);
out_unlock:
unlock_extent_cached(&BTRFS_I(inode)->io_tree, lock_start, lock_end,
diff --git a/fs/btrfs/locking.h b/fs/btrfs/locking.h
index ca52681e5f40..b81e0e9a4894 100644
--- a/fs/btrfs/locking.h
+++ b/fs/btrfs/locking.h
@@ -26,7 +26,6 @@
void btrfs_tree_lock(struct extent_buffer *eb);
void btrfs_tree_unlock(struct extent_buffer *eb);
-int btrfs_try_spin_lock(struct extent_buffer *eb);
void btrfs_tree_read_lock(struct extent_buffer *eb);
void btrfs_tree_read_unlock(struct extent_buffer *eb);
diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
index aee4b1cc3d98..5471e47d6559 100644
--- a/fs/btrfs/qgroup.c
+++ b/fs/btrfs/qgroup.c
@@ -1525,21 +1525,23 @@ int btrfs_qgroup_reserve(struct btrfs_root *root, u64 num_bytes)
if ((qg->lim_flags & BTRFS_QGROUP_LIMIT_MAX_RFER) &&
qg->reserved + qg->rfer + num_bytes >
- qg->max_rfer)
+ qg->max_rfer) {
ret = -EDQUOT;
+ goto out;
+ }
if ((qg->lim_flags & BTRFS_QGROUP_LIMIT_MAX_EXCL) &&
qg->reserved + qg->excl + num_bytes >
- qg->max_excl)
+ qg->max_excl) {
ret = -EDQUOT;
+ goto out;
+ }
list_for_each_entry(glist, &qg->groups, next_group) {
ulist_add(ulist, glist->group->qgroupid,
(uintptr_t)glist->group, GFP_ATOMIC);
}
}
- if (ret)
- goto out;
/*
* no limits exceeded, now record the reservation into all qgroups
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index 9250b9c4f01e..50767bbaad6c 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -625,14 +625,13 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans,
btrfs_trans_release_metadata(trans, root);
trans->block_rsv = NULL;
- /*
- * the same root has to be passed to start_transaction and
- * end_transaction. Subvolume quota depends on this.
- */
- WARN_ON(trans->root != root);
if (trans->qgroup_reserved) {
- btrfs_qgroup_free(root, trans->qgroup_reserved);
+ /*
+ * the same root has to be passed here between start_transaction
+ * and end_transaction. Subvolume quota depends on this.
+ */
+ btrfs_qgroup_free(trans->root, trans->qgroup_reserved);
trans->qgroup_reserved = 0;
}
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 6b9cff42265d..5989a92236f7 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -684,6 +684,12 @@ int btrfs_close_devices(struct btrfs_fs_devices *fs_devices)
__btrfs_close_devices(fs_devices);
free_fs_devices(fs_devices);
}
+ /*
+ * Wait for rcu kworkers under __btrfs_close_devices
+ * to finish all blkdev_puts so device is really
+ * free when umount is done.
+ */
+ rcu_barrier();
return ret;
}
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 1a052c0eee8e..3cf8a15af916 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -777,6 +777,7 @@ struct file_system_type cifs_fs_type = {
.kill_sb = cifs_kill_sb,
/* .fs_flags */
};
+MODULE_ALIAS_FS("cifs");
const struct inode_operations cifs_dir_inode_ops = {
.create = cifs_create,
.atomic_open = cifs_atomic_open,
diff --git a/fs/compat.c b/fs/compat.c
index fe40fde29111..d487985dd0ea 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -558,6 +558,10 @@ ssize_t compat_rw_copy_check_uvector(int type,
}
*ret_pointer = iov;
+ ret = -EFAULT;
+ if (!access_ok(VERIFY_READ, uvector, nr_segs*sizeof(*uvector)))
+ goto out;
+
/*
* Single unix specification:
* We should -EINVAL if an element length is not >= 0 and fitting an
@@ -1080,17 +1084,12 @@ static ssize_t compat_do_readv_writev(int type, struct file *file,
if (!file->f_op)
goto out;
- ret = -EFAULT;
- if (!access_ok(VERIFY_READ, uvector, nr_segs*sizeof(*uvector)))
- goto out;
-
- tot_len = compat_rw_copy_check_uvector(type, uvector, nr_segs,
+ ret = compat_rw_copy_check_uvector(type, uvector, nr_segs,
UIO_FASTIOV, iovstack, &iov);
- if (tot_len == 0) {
- ret = 0;
+ if (ret <= 0)
goto out;
- }
+ tot_len = ret;
ret = rw_verify_area(type, file, pos, tot_len);
if (ret < 0)
goto out;
diff --git a/fs/ext2/ialloc.c b/fs/ext2/ialloc.c
index 8f370e012e61..7cadd823bb31 100644
--- a/fs/ext2/ialloc.c
+++ b/fs/ext2/ialloc.c
@@ -118,7 +118,6 @@ void ext2_free_inode (struct inode * inode)
* as writing the quota to disk may need the lock as well.
*/
/* Quota is already initialized in iput() */
- ext2_xattr_delete_inode(inode);
dquot_free_inode(inode);
dquot_drop(inode);
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c
index c3881e56662e..fe60cc1117d8 100644
--- a/fs/ext2/inode.c
+++ b/fs/ext2/inode.c
@@ -34,6 +34,7 @@
#include "ext2.h"
#include "acl.h"
#include "xip.h"
+#include "xattr.h"
static int __ext2_write_inode(struct inode *inode, int do_sync);
@@ -88,6 +89,7 @@ void ext2_evict_inode(struct inode * inode)
inode->i_size = 0;
if (inode->i_blocks)
ext2_truncate_blocks(inode, 0);
+ ext2_xattr_delete_inode(inode);
}
invalidate_inode_buffers(inode);
diff --git a/fs/ext3/super.c b/fs/ext3/super.c
index 1d6e2ed85322..fb5120a5505c 100644
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -353,7 +353,7 @@ static struct block_device *ext3_blkdev_get(dev_t dev, struct super_block *sb)
return bdev;
fail:
- ext3_msg(sb, "error: failed to open journal device %s: %ld",
+ ext3_msg(sb, KERN_ERR, "error: failed to open journal device %s: %ld",
__bdevname(dev, b), PTR_ERR(bdev));
return NULL;
@@ -887,7 +887,7 @@ static ext3_fsblk_t get_sb_block(void **data, struct super_block *sb)
/*todo: use simple_strtoll with >32bit ext3 */
sb_block = simple_strtoul(options, &options, 0);
if (*options && *options != ',') {
- ext3_msg(sb, "error: invalid sb specification: %s",
+ ext3_msg(sb, KERN_ERR, "error: invalid sb specification: %s",
(char *) *data);
return 1;
}
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 34e855219231..b3818b48f418 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -91,6 +91,7 @@ static struct file_system_type ext2_fs_type = {
.fs_flags = FS_REQUIRES_DEV,
};
MODULE_ALIAS_FS("ext2");
+MODULE_ALIAS("ext2");
#define IS_EXT2_SB(sb) ((sb)->s_bdev->bd_holder == &ext2_fs_type)
#else
#define IS_EXT2_SB(sb) (0)
@@ -106,6 +107,7 @@ static struct file_system_type ext3_fs_type = {
.fs_flags = FS_REQUIRES_DEV,
};
MODULE_ALIAS_FS("ext3");
+MODULE_ALIAS("ext3");
#define IS_EXT3_SB(sb) ((sb)->s_bdev->bd_holder == &ext3_fs_type)
#else
#define IS_EXT3_SB(sb) (0)
diff --git a/fs/freevxfs/vxfs_super.c b/fs/freevxfs/vxfs_super.c
index 455074308069..e37eb274e492 100644
--- a/fs/freevxfs/vxfs_super.c
+++ b/fs/freevxfs/vxfs_super.c
@@ -258,6 +258,7 @@ static struct file_system_type vxfs_fs_type = {
.fs_flags = FS_REQUIRES_DEV,
};
MODULE_ALIAS_FS("vxfs"); /* makes mount -t vxfs autoload the module */
+MODULE_ALIAS("vxfs");
static int __init
vxfs_init(void)
diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c
index fbabb906066f..0f6e52d22b84 100644
--- a/fs/hostfs/hostfs_kern.c
+++ b/fs/hostfs/hostfs_kern.c
@@ -845,15 +845,8 @@ int hostfs_setattr(struct dentry *dentry, struct iattr *attr)
return err;
if ((attr->ia_valid & ATTR_SIZE) &&
- attr->ia_size != i_size_read(inode)) {
- int error;
-
- error = inode_newsize_ok(inode, attr->ia_size);
- if (error)
- return error;
-
+ attr->ia_size != i_size_read(inode))
truncate_setsize(inode, attr->ia_size);
- }
setattr_copy(inode, attr);
mark_inode_dirty(inode);
@@ -993,6 +986,7 @@ static struct file_system_type hostfs_type = {
.kill_sb = hostfs_kill_sb,
.fs_flags = 0,
};
+MODULE_ALIAS_FS("hostfs");
static int __init init_hostfs(void)
{
diff --git a/fs/hpfs/super.c b/fs/hpfs/super.c
index a3076228523d..a0617e706957 100644
--- a/fs/hpfs/super.c
+++ b/fs/hpfs/super.c
@@ -688,6 +688,7 @@ static struct file_system_type hpfs_fs_type = {
.kill_sb = kill_block_super,
.fs_flags = FS_REQUIRES_DEV,
};
+MODULE_ALIAS_FS("hpfs");
static int __init init_hpfs_fs(void)
{
diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c
index a67f16e846a2..d9b8aebdeb22 100644
--- a/fs/isofs/inode.c
+++ b/fs/isofs/inode.c
@@ -1557,6 +1557,7 @@ static struct file_system_type iso9660_fs_type = {
.fs_flags = FS_REQUIRES_DEV,
};
MODULE_ALIAS_FS("iso9660");
+MODULE_ALIAS("iso9660");
static int __init init_iso9660_fs(void)
{
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 95cdcb208dfb..2f8a29db0f1b 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -335,6 +335,7 @@ struct file_system_type nfs4_fs_type = {
.fs_flags = FS_RENAME_DOES_D_MOVE|FS_BINARY_MOUNTDATA,
};
MODULE_ALIAS_FS("nfs4");
+MODULE_ALIAS("nfs4");
EXPORT_SYMBOL_GPL(nfs4_fs_type);
static int __init register_nfs4_fs(void)
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 16d39c6c4fbb..2e27430b9070 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -230,37 +230,6 @@ static void nfs4_file_put_access(struct nfs4_file *fp, int oflag)
__nfs4_file_put_access(fp, oflag);
}
-static inline int get_new_stid(struct nfs4_stid *stid)
-{
- static int min_stateid = 0;
- struct idr *stateids = &stid->sc_client->cl_stateids;
- int new_stid;
- int error;
-
- error = idr_get_new_above(stateids, stid, min_stateid, &new_stid);
- /*
- * Note: the necessary preallocation was done in
- * nfs4_alloc_stateid(). The idr code caps the number of
- * preallocations that can exist at a time, but the state lock
- * prevents anyone from using ours before we get here:
- */
- WARN_ON_ONCE(error);
- /*
- * It shouldn't be a problem to reuse an opaque stateid value.
- * I don't think it is for 4.1. But with 4.0 I worry that, for
- * example, a stray write retransmission could be accepted by
- * the server when it should have been rejected. Therefore,
- * adopt a trick from the sctp code to attempt to maximize the
- * amount of time until an id is reused, by ensuring they always
- * "increase" (mod INT_MAX):
- */
-
- min_stateid = new_stid+1;
- if (min_stateid == INT_MAX)
- min_stateid = 0;
- return new_stid;
-}
-
static struct nfs4_stid *nfs4_alloc_stid(struct nfs4_client *cl, struct
kmem_cache *slab)
{
@@ -273,9 +242,8 @@ kmem_cache *slab)
if (!stid)
return NULL;
- if (!idr_pre_get(stateids, GFP_KERNEL))
- goto out_free;
- if (idr_get_new_above(stateids, stid, min_stateid, &new_id))
+ new_id = idr_alloc(stateids, stid, min_stateid, 0, GFP_KERNEL);
+ if (new_id < 0)
goto out_free;
stid->sc_client = cl;
stid->sc_type = 0;
diff --git a/fs/pipe.c b/fs/pipe.c
index 64a494cef0a0..2234f3f61f8d 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -863,6 +863,9 @@ pipe_rdwr_open(struct inode *inode, struct file *filp)
{
int ret = -ENOENT;
+ if (!(filp->f_mode & (FMODE_READ|FMODE_WRITE)))
+ return -EINVAL;
+
mutex_lock(&inode->i_mutex);
if (inode->i_pipe) {
diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
index 05ae3c97f7a5..3e64169ef527 100644
--- a/fs/quota/dquot.c
+++ b/fs/quota/dquot.c
@@ -1439,8 +1439,11 @@ static void __dquot_initialize(struct inode *inode, int type)
* did a write before quota was turned on
*/
rsv = inode_get_rsv_space(inode);
- if (unlikely(rsv))
+ if (unlikely(rsv)) {
+ spin_lock(&dq_data_lock);
dquot_resv_space(inode->i_dquot[cnt], rsv);
+ spin_unlock(&dq_data_lock);
+ }
}
}
out_err:
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
index 194113b1b11b..f8a23c3078f8 100644
--- a/fs/reiserfs/super.c
+++ b/fs/reiserfs/super.c
@@ -1147,8 +1147,7 @@ static int reiserfs_parse_options(struct super_block *s, char *options, /* strin
"on filesystem root.");
return 0;
}
- qf_names[qtype] =
- kmalloc(strlen(arg) + 1, GFP_KERNEL);
+ qf_names[qtype] = kstrdup(arg, GFP_KERNEL);
if (!qf_names[qtype]) {
reiserfs_warning(s, "reiserfs-2502",
"not enough memory "
@@ -1156,7 +1155,6 @@ static int reiserfs_parse_options(struct super_block *s, char *options, /* strin
"quotafile name.");
return 0;
}
- strcpy(qf_names[qtype], arg);
if (qtype == USRQUOTA)
*mount_options |= 1 << REISERFS_USRQUOTA;
else
diff --git a/fs/squashfs/super.c b/fs/squashfs/super.c
index 260e3928d4f5..60553a9053ca 100644
--- a/fs/squashfs/super.c
+++ b/fs/squashfs/super.c
@@ -489,6 +489,7 @@ static struct file_system_type squashfs_fs_type = {
.kill_sb = kill_block_super,
.fs_flags = FS_REQUIRES_DEV
};
+MODULE_ALIAS_FS("squashfs");
static const struct super_operations squashfs_super_ops = {
.alloc_inode = squashfs_alloc_inode,
diff --git a/fs/sysv/super.c b/fs/sysv/super.c
index a39938b1feea..d0c6a007ce83 100644
--- a/fs/sysv/super.c
+++ b/fs/sysv/super.c
@@ -555,6 +555,7 @@ static struct file_system_type v7_fs_type = {
.fs_flags = FS_REQUIRES_DEV,
};
MODULE_ALIAS_FS("v7");
+MODULE_ALIAS("v7");
static int __init init_sysv_fs(void)
{
diff --git a/fs/udf/super.c b/fs/udf/super.c
index bc5b30a819e8..9ac4057a86c9 100644
--- a/fs/udf/super.c
+++ b/fs/udf/super.c
@@ -118,6 +118,7 @@ static struct file_system_type udf_fstype = {
.kill_sb = kill_block_super,
.fs_flags = FS_REQUIRES_DEV,
};
+MODULE_ALIAS_FS("udf");
static struct kmem_cache *udf_inode_cachep;
diff --git a/include/acpi/processor.h b/include/acpi/processor.h
index 555d0337ad95..b327b5a9296d 100644
--- a/include/acpi/processor.h
+++ b/include/acpi/processor.h
@@ -235,6 +235,9 @@ extern void acpi_processor_unregister_performance(struct
if a _PPC object exists, rmmod is disallowed then */
int acpi_processor_notify_smm(struct module *calling_module);
+/* parsing the _P* objects. */
+extern int acpi_processor_get_performance_info(struct acpi_processor *pr);
+
/* for communication between multiple parts of the processor kernel module */
DECLARE_PER_CPU(struct acpi_processor *, processors);
extern struct acpi_processor_errata errata;
diff --git a/include/asm-generic/atomic.h b/include/asm-generic/atomic.h
index 1ced6413ea03..33bd2de3bc1e 100644
--- a/include/asm-generic/atomic.h
+++ b/include/asm-generic/atomic.h
@@ -136,12 +136,6 @@ static inline void atomic_dec(atomic_t *v)
#define atomic_xchg(ptr, v) (xchg(&(ptr)->counter, (v)))
#define atomic_cmpxchg(v, old, new) (cmpxchg(&((v)->counter), (old), (new)))
-#define cmpxchg_local(ptr, o, n) \
- ((__typeof__(*(ptr)))__cmpxchg_local_generic((ptr), (unsigned long)(o),\
- (unsigned long)(n), sizeof(*(ptr))))
-
-#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n))
-
static inline int __atomic_add_unless(atomic_t *v, int a, int u)
{
int c, old;
diff --git a/include/asm-generic/cmpxchg.h b/include/asm-generic/cmpxchg.h
index 14883026015d..811fb1e9b061 100644
--- a/include/asm-generic/cmpxchg.h
+++ b/include/asm-generic/cmpxchg.h
@@ -92,6 +92,16 @@ unsigned long __xchg(unsigned long x, volatile void *ptr, int size)
*/
#include <asm-generic/cmpxchg-local.h>
+#ifndef cmpxchg_local
+#define cmpxchg_local(ptr, o, n) \
+ ((__typeof__(*(ptr)))__cmpxchg_local_generic((ptr), (unsigned long)(o),\
+ (unsigned long)(n), sizeof(*(ptr))))
+#endif
+
+#ifndef cmpxchg64_local
+#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n))
+#endif
+
#define cmpxchg(ptr, o, n) cmpxchg_local((ptr), (o), (n))
#define cmpxchg64(ptr, o, n) cmpxchg64_local((ptr), (o), (n))
diff --git a/include/linux/clk-private.h b/include/linux/clk-private.h
index 9c7f5807824b..dd7adff76e81 100644
--- a/include/linux/clk-private.h
+++ b/include/linux/clk-private.h
@@ -152,7 +152,7 @@ struct clk {
}, \
.reg = _reg, \
.shift = _shift, \
- .width = _width, \
+ .mask = BIT(_width) - 1, \
.flags = _mux_flags, \
.lock = _lock, \
}; \
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index 7f197d7addb0..9fdfae74d669 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -45,6 +45,14 @@ struct clk_hw;
* undo any work done in the @prepare callback. Called with
* prepare_lock held.
*
+ * @is_prepared: Queries the hardware to determine if the clock is prepared.
+ * This function is allowed to sleep. Optional, if this op is not
+ * set then the prepare count will be used.
+ *
+ * @unprepare_unused: Unprepare the clock atomically. Only called from
+ * clk_disable_unused for prepare clocks with special needs.
+ * Called with prepare mutex held. This function may sleep.
+ *
* @enable: Enable the clock atomically. This must not return until the
* clock is generating a valid clock signal, usable by consumer
* devices. Called with enable_lock held. This function must not
@@ -108,6 +116,8 @@ struct clk_hw;
struct clk_ops {
int (*prepare)(struct clk_hw *hw);
void (*unprepare)(struct clk_hw *hw);
+ int (*is_prepared)(struct clk_hw *hw);
+ void (*unprepare_unused)(struct clk_hw *hw);
int (*enable)(struct clk_hw *hw);
void (*disable)(struct clk_hw *hw);
int (*is_enabled)(struct clk_hw *hw);
@@ -239,9 +249,14 @@ struct clk_div_table {
* CLK_DIVIDER_ONE_BASED - by default the divisor is the value read from the
* register plus one. If CLK_DIVIDER_ONE_BASED is set then the divider is
* the raw value read from the register, with the value of zero considered
- * invalid
+ * invalid, unless CLK_DIVIDER_ALLOW_ZERO is set.
* CLK_DIVIDER_POWER_OF_TWO - clock divisor is 2 raised to the value read from
* the hardware register
+ * CLK_DIVIDER_ALLOW_ZERO - Allow zero divisors. For dividers which have
+ * CLK_DIVIDER_ONE_BASED set, it is possible to end up with a zero divisor.
+ * Some hardware implementations gracefully handle this case and allow a
+ * zero divisor by not modifying their input clock
+ * (divide by one / bypass).
*/
struct clk_divider {
struct clk_hw hw;
@@ -255,6 +270,7 @@ struct clk_divider {
#define CLK_DIVIDER_ONE_BASED BIT(0)
#define CLK_DIVIDER_POWER_OF_TWO BIT(1)
+#define CLK_DIVIDER_ALLOW_ZERO BIT(2)
extern const struct clk_ops clk_divider_ops;
struct clk *clk_register_divider(struct device *dev, const char *name,
@@ -274,7 +290,7 @@ struct clk *clk_register_divider_table(struct device *dev, const char *name,
* @reg: register controlling multiplexer
* @shift: shift to multiplexer bit field
* @width: width of mutliplexer bit field
- * @num_clks: number of parent clocks
+ * @flags: hardware-specific flags
* @lock: register lock
*
* Clock with multiple selectable parents. Implements .get_parent, .set_parent
@@ -287,8 +303,9 @@ struct clk *clk_register_divider_table(struct device *dev, const char *name,
struct clk_mux {
struct clk_hw hw;
void __iomem *reg;
+ u32 *table;
+ u32 mask;
u8 shift;
- u8 width;
u8 flags;
spinlock_t *lock;
};
@@ -297,11 +314,17 @@ struct clk_mux {
#define CLK_MUX_INDEX_BIT BIT(1)
extern const struct clk_ops clk_mux_ops;
+
struct clk *clk_register_mux(struct device *dev, const char *name,
const char **parent_names, u8 num_parents, unsigned long flags,
void __iomem *reg, u8 shift, u8 width,
u8 clk_mux_flags, spinlock_t *lock);
+struct clk *clk_register_mux_table(struct device *dev, const char *name,
+ const char **parent_names, u8 num_parents, unsigned long flags,
+ void __iomem *reg, u8 shift, u32 mask,
+ u8 clk_mux_flags, u32 *table, spinlock_t *lock);
+
/**
* struct clk_fixed_factor - fixed multiplier and divider clock
*
@@ -325,6 +348,37 @@ struct clk *clk_register_fixed_factor(struct device *dev, const char *name,
const char *parent_name, unsigned long flags,
unsigned int mult, unsigned int div);
+/***
+ * struct clk_composite - aggregate clock of mux, divider and gate clocks
+ *
+ * @hw: handle between common and hardware-specific interfaces
+ * @mux_hw: handle between composite and hardware-specifix mux clock
+ * @div_hw: handle between composite and hardware-specifix divider clock
+ * @gate_hw: handle between composite and hardware-specifix gate clock
+ * @mux_ops: clock ops for mux
+ * @div_ops: clock ops for divider
+ * @gate_ops: clock ops for gate
+ */
+struct clk_composite {
+ struct clk_hw hw;
+ struct clk_ops ops;
+
+ struct clk_hw *mux_hw;
+ struct clk_hw *div_hw;
+ struct clk_hw *gate_hw;
+
+ const struct clk_ops *mux_ops;
+ const struct clk_ops *div_ops;
+ const struct clk_ops *gate_ops;
+};
+
+struct clk *clk_register_composite(struct device *dev, const char *name,
+ const char **parent_names, int num_parents,
+ struct clk_hw *mux_hw, const struct clk_ops *mux_ops,
+ struct clk_hw *div_hw, const struct clk_ops *div_ops,
+ struct clk_hw *gate_hw, const struct clk_ops *gate_ops,
+ unsigned long flags);
+
/**
* clk_register - allocate a new clock, register it and return an opaque cookie
* @dev: device that is registering this clock
@@ -351,6 +405,7 @@ unsigned int __clk_get_enable_count(struct clk *clk);
unsigned int __clk_get_prepare_count(struct clk *clk);
unsigned long __clk_get_rate(struct clk *clk);
unsigned long __clk_get_flags(struct clk *clk);
+bool __clk_is_prepared(struct clk *clk);
bool __clk_is_enabled(struct clk *clk);
struct clk *__clk_lookup(const char *name);
diff --git a/include/linux/clk/sunxi.h b/include/linux/clk/sunxi.h
new file mode 100644
index 000000000000..e074fdd5a236
--- /dev/null
+++ b/include/linux/clk/sunxi.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2012 Maxime Ripard
+ *
+ * Maxime Ripard <maxime.ripard@free-electrons.com>
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+#ifndef __LINUX_CLK_SUNXI_H_
+#define __LINUX_CLK_SUNXI_H_
+
+void __init sunxi_init_clocks(void);
+
+#endif
diff --git a/include/linux/idr.h b/include/linux/idr.h
index a6f38b5c34e4..2640c7e99e51 100644
--- a/include/linux/idr.h
+++ b/include/linux/idr.h
@@ -73,8 +73,6 @@ struct idr {
*/
void *idr_find_slowpath(struct idr *idp, int id);
-int idr_pre_get(struct idr *idp, gfp_t gfp_mask);
-int idr_get_new_above(struct idr *idp, void *ptr, int starting_id, int *id);
void idr_preload(gfp_t gfp_mask);
int idr_alloc(struct idr *idp, void *ptr, int start, int end, gfp_t gfp_mask);
int idr_for_each(struct idr *idp,
@@ -99,7 +97,7 @@ static inline void idr_preload_end(void)
/**
* idr_find - return pointer for given id
- * @idp: idr handle
+ * @idr: idr handle
* @id: lookup key
*
* Return the pointer given the id it has been registered with. A %NULL
@@ -120,19 +118,6 @@ static inline void *idr_find(struct idr *idr, int id)
}
/**
- * idr_get_new - allocate new idr entry
- * @idp: idr handle
- * @ptr: pointer you want associated with the id
- * @id: pointer to the allocated handle
- *
- * Simple wrapper around idr_get_new_above() w/ @starting_id of zero.
- */
-static inline int idr_get_new(struct idr *idp, void *ptr, int *id)
-{
- return idr_get_new_above(idp, ptr, 0, id);
-}
-
-/**
* idr_for_each_entry - iterate over an idr's elements of a given type
* @idp: idr handle
* @entry: the type * to use as cursor
@@ -143,7 +128,56 @@ static inline int idr_get_new(struct idr *idp, void *ptr, int *id)
entry != NULL; \
++id, entry = (typeof(entry))idr_get_next((idp), &(id)))
-void __idr_remove_all(struct idr *idp); /* don't use */
+/*
+ * Don't use the following functions. These exist only to suppress
+ * deprecated warnings on EXPORT_SYMBOL()s.
+ */
+int __idr_pre_get(struct idr *idp, gfp_t gfp_mask);
+int __idr_get_new_above(struct idr *idp, void *ptr, int starting_id, int *id);
+void __idr_remove_all(struct idr *idp);
+
+/**
+ * idr_pre_get - reserve resources for idr allocation
+ * @idp: idr handle
+ * @gfp_mask: memory allocation flags
+ *
+ * Part of old alloc interface. This is going away. Use
+ * idr_preload[_end]() and idr_alloc() instead.
+ */
+static inline int __deprecated idr_pre_get(struct idr *idp, gfp_t gfp_mask)
+{
+ return __idr_pre_get(idp, gfp_mask);
+}
+
+/**
+ * idr_get_new_above - allocate new idr entry above or equal to a start id
+ * @idp: idr handle
+ * @ptr: pointer you want associated with the id
+ * @starting_id: id to start search at
+ * @id: pointer to the allocated handle
+ *
+ * Part of old alloc interface. This is going away. Use
+ * idr_preload[_end]() and idr_alloc() instead.
+ */
+static inline int __deprecated idr_get_new_above(struct idr *idp, void *ptr,
+ int starting_id, int *id)
+{
+ return __idr_get_new_above(idp, ptr, starting_id, id);
+}
+
+/**
+ * idr_get_new - allocate new idr entry
+ * @idp: idr handle
+ * @ptr: pointer you want associated with the id
+ * @id: pointer to the allocated handle
+ *
+ * Part of old alloc interface. This is going away. Use
+ * idr_preload[_end]() and idr_alloc() instead.
+ */
+static inline int __deprecated idr_get_new(struct idr *idp, void *ptr, int *id)
+{
+ return __idr_get_new_above(idp, ptr, 0, id);
+}
/**
* idr_remove_all - remove all ids from the given idr tree
diff --git a/include/linux/iio/common/st_sensors.h b/include/linux/iio/common/st_sensors.h
index 1f86a97ab2e2..8bd12be0b02f 100644
--- a/include/linux/iio/common/st_sensors.h
+++ b/include/linux/iio/common/st_sensors.h
@@ -227,14 +227,17 @@ struct st_sensor_data {
};
#ifdef CONFIG_IIO_BUFFER
+irqreturn_t st_sensors_trigger_handler(int irq, void *p);
+
+int st_sensors_get_buffer_element(struct iio_dev *indio_dev, u8 *buf);
+#endif
+
+#ifdef CONFIG_IIO_TRIGGER
int st_sensors_allocate_trigger(struct iio_dev *indio_dev,
const struct iio_trigger_ops *trigger_ops);
void st_sensors_deallocate_trigger(struct iio_dev *indio_dev);
-irqreturn_t st_sensors_trigger_handler(int irq, void *p);
-
-int st_sensors_get_buffer_element(struct iio_dev *indio_dev, u8 *buf);
#else
static inline int st_sensors_allocate_trigger(struct iio_dev *indio_dev,
const struct iio_trigger_ops *trigger_ops)
diff --git a/include/linux/list.h b/include/linux/list.h
index d991cc147c98..6a1f8df9144b 100644
--- a/include/linux/list.h
+++ b/include/linux/list.h
@@ -667,7 +667,9 @@ static inline void hlist_move_list(struct hlist_head *old,
pos = n)
#define hlist_entry_safe(ptr, type, member) \
- (ptr) ? hlist_entry(ptr, type, member) : NULL
+ ({ typeof(ptr) ____ptr = (ptr); \
+ ____ptr ? hlist_entry(____ptr, type, member) : NULL; \
+ })
/**
* hlist_for_each_entry - iterate over list of given type
diff --git a/include/linux/mfd/palmas.h b/include/linux/mfd/palmas.h
index a4d13d7cd001..3bbda22721ea 100644
--- a/include/linux/mfd/palmas.h
+++ b/include/linux/mfd/palmas.h
@@ -221,6 +221,7 @@ struct palmas_clk_platform_data {
};
struct palmas_platform_data {
+ int irq_flags;
int gpio_base;
/* bit value to be loaded to the POWER_CTRL register */
diff --git a/include/linux/mfd/tps65912.h b/include/linux/mfd/tps65912.h
index aaceab402ec5..6d309032dc0d 100644
--- a/include/linux/mfd/tps65912.h
+++ b/include/linux/mfd/tps65912.h
@@ -323,5 +323,6 @@ int tps65912_device_init(struct tps65912 *tps65912);
void tps65912_device_exit(struct tps65912 *tps65912);
int tps65912_irq_init(struct tps65912 *tps65912, int irq,
struct tps65912_platform_data *pdata);
+int tps65912_irq_exit(struct tps65912 *tps65912);
#endif /* __LINUX_MFD_TPS65912_H */
diff --git a/include/linux/mfd/wm831x/auxadc.h b/include/linux/mfd/wm831x/auxadc.h
index b132067e9e99..867aa23f9370 100644
--- a/include/linux/mfd/wm831x/auxadc.h
+++ b/include/linux/mfd/wm831x/auxadc.h
@@ -15,6 +15,8 @@
#ifndef __MFD_WM831X_AUXADC_H__
#define __MFD_WM831X_AUXADC_H__
+struct wm831x;
+
/*
* R16429 (0x402D) - AuxADC Data
*/
diff --git a/include/linux/mfd/wm831x/core.h b/include/linux/mfd/wm831x/core.h
index 4a3b83a77614..76c22648436f 100644
--- a/include/linux/mfd/wm831x/core.h
+++ b/include/linux/mfd/wm831x/core.h
@@ -20,6 +20,7 @@
#include <linux/irqdomain.h>
#include <linux/list.h>
#include <linux/regmap.h>
+#include <linux/mfd/wm831x/auxadc.h>
/*
* Register values.
@@ -355,7 +356,6 @@ enum wm831x_parent {
};
struct wm831x;
-enum wm831x_auxadc;
typedef int (*wm831x_auxadc_read_fn)(struct wm831x *wm831x,
enum wm831x_auxadc input);
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index e47ee462c2f2..1d795df6f4cf 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -799,6 +799,12 @@ static inline int __perf_event_disable(void *info) { return -1; }
static inline void perf_event_task_tick(void) { }
#endif
+#if defined(CONFIG_PERF_EVENTS) && defined(CONFIG_CPU_SUP_INTEL)
+extern void perf_restore_debug_store(void);
+#else
+static inline void perf_restore_debug_store(void) { }
+#endif
+
#define perf_output_put(handle, x) perf_output_copy((handle), &(x), sizeof(x))
/*
diff --git a/include/linux/res_counter.h b/include/linux/res_counter.h
index 5ae8456d9670..c23099413ad6 100644
--- a/include/linux/res_counter.h
+++ b/include/linux/res_counter.h
@@ -14,6 +14,7 @@
*/
#include <linux/cgroup.h>
+#include <linux/errno.h>
/*
* The core object. the cgroup that wishes to account for some
diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h
index 3c671c1b37f6..8860594d6364 100644
--- a/include/linux/usb/composite.h
+++ b/include/linux/usb/composite.h
@@ -60,7 +60,7 @@ struct usb_configuration;
* @name: For diagnostics, identifies the function.
* @strings: tables of strings, keyed by identifiers assigned during bind()
* and by language IDs provided in control requests
- * @descriptors: Table of full (or low) speed descriptors, using interface and
+ * @fs_descriptors: Table of full (or low) speed descriptors, using interface and
* string identifiers assigned during @bind(). If this pointer is null,
* the function will not be available at full speed (or at low speed).
* @hs_descriptors: Table of high speed descriptors, using interface and
@@ -290,6 +290,7 @@ enum {
* after function notifications
* @resume: Notifies configuration when the host restarts USB traffic,
* before function notifications
+ * @gadget_driver: Gadget driver controlling this driver
*
* Devices default to reporting self powered operation. Devices which rely
* on bus powered operation should report this in their @bind method.
diff --git a/include/uapi/linux/acct.h b/include/uapi/linux/acct.h
index 11b6ca3e0873..df2f9a0bba6a 100644
--- a/include/uapi/linux/acct.h
+++ b/include/uapi/linux/acct.h
@@ -107,10 +107,12 @@ struct acct_v3
#define ACORE 0x08 /* ... dumped core */
#define AXSIG 0x10 /* ... was killed by a signal */
-#ifdef __BIG_ENDIAN
+#if defined(__BYTE_ORDER) ? __BYTE_ORDER == __BIG_ENDIAN : defined(__BIG_ENDIAN)
#define ACCT_BYTEORDER 0x80 /* accounting file is big endian */
-#else
+#elif defined(__BYTE_ORDER) ? __BYTE_ORDER == __LITTLE_ENDIAN : defined(__LITTLE_ENDIAN)
#define ACCT_BYTEORDER 0x00 /* accounting file is little endian */
+#else
+#error unspecified endianness
#endif
#ifndef __KERNEL__
diff --git a/include/uapi/linux/aio_abi.h b/include/uapi/linux/aio_abi.h
index 86fa7a71336a..bb2554f7fbd1 100644
--- a/include/uapi/linux/aio_abi.h
+++ b/include/uapi/linux/aio_abi.h
@@ -62,9 +62,9 @@ struct io_event {
__s64 res2; /* secondary result */
};
-#if defined(__LITTLE_ENDIAN)
+#if defined(__BYTE_ORDER) ? __BYTE_ORDER == __LITTLE_ENDIAN : defined(__LITTLE_ENDIAN)
#define PADDED(x,y) x, y
-#elif defined(__BIG_ENDIAN)
+#elif defined(__BYTE_ORDER) ? __BYTE_ORDER == __BIG_ENDIAN : defined(__BIG_ENDIAN)
#define PADDED(x,y) y, x
#else
#error edit for your odd byteorder.
diff --git a/include/uapi/linux/raid/md_p.h b/include/uapi/linux/raid/md_p.h
index ee753536ab70..fe1a5406d4d9 100644
--- a/include/uapi/linux/raid/md_p.h
+++ b/include/uapi/linux/raid/md_p.h
@@ -145,16 +145,18 @@ typedef struct mdp_superblock_s {
__u32 failed_disks; /* 4 Number of failed disks */
__u32 spare_disks; /* 5 Number of spare disks */
__u32 sb_csum; /* 6 checksum of the whole superblock */
-#ifdef __BIG_ENDIAN
+#if defined(__BYTE_ORDER) ? __BYTE_ORDER == __BIG_ENDIAN : defined(__BIG_ENDIAN)
__u32 events_hi; /* 7 high-order of superblock update count */
__u32 events_lo; /* 8 low-order of superblock update count */
__u32 cp_events_hi; /* 9 high-order of checkpoint update count */
__u32 cp_events_lo; /* 10 low-order of checkpoint update count */
-#else
+#elif defined(__BYTE_ORDER) ? __BYTE_ORDER == __LITTLE_ENDIAN : defined(__LITTLE_ENDIAN)
__u32 events_lo; /* 7 low-order of superblock update count */
__u32 events_hi; /* 8 high-order of superblock update count */
__u32 cp_events_lo; /* 9 low-order of checkpoint update count */
__u32 cp_events_hi; /* 10 high-order of checkpoint update count */
+#else
+#error unspecified endianness
#endif
__u32 recovery_cp; /* 11 recovery checkpoint sector count */
/* There are only valid for minor_version > 90 */
diff --git a/include/uapi/linux/serial_core.h b/include/uapi/linux/serial_core.h
index b6a23a483d74..74c2bf7211f8 100644
--- a/include/uapi/linux/serial_core.h
+++ b/include/uapi/linux/serial_core.h
@@ -51,7 +51,10 @@
#define PORT_8250_CIR 23 /* CIR infrared port, has its own driver */
#define PORT_XR17V35X 24 /* Exar XR17V35x UARTs */
#define PORT_BRCM_TRUMANAGE 25
-#define PORT_MAX_8250 25 /* max port ID */
+#define PORT_ALTR_16550_F32 26 /* Altera 16550 UART with 32 FIFOs */
+#define PORT_ALTR_16550_F64 27 /* Altera 16550 UART with 64 FIFOs */
+#define PORT_ALTR_16550_F128 28 /* Altera 16550 UART with 128 FIFOs */
+#define PORT_MAX_8250 28 /* max port ID */
/*
* ARM specific type numbers. These are not currently guaranteed
diff --git a/init/Kconfig b/init/Kconfig
index 22616cd434bc..5341d7232c3a 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -28,10 +28,6 @@ config BUILDTIME_EXTABLE_SORT
menu "General setup"
-config EXPERIMENTAL
- bool
- default y
-
config BROKEN
bool
diff --git a/kernel/fork.c b/kernel/fork.c
index 8d932b1c9056..1766d324d5e3 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -1141,6 +1141,9 @@ static struct task_struct *copy_process(unsigned long clone_flags,
if ((clone_flags & (CLONE_NEWNS|CLONE_FS)) == (CLONE_NEWNS|CLONE_FS))
return ERR_PTR(-EINVAL);
+ if ((clone_flags & (CLONE_NEWUSER|CLONE_FS)) == (CLONE_NEWUSER|CLONE_FS))
+ return ERR_PTR(-EINVAL);
+
/*
* Thread groups must share signals as well, and detached threads
* can only be started up within the thread group.
@@ -1807,7 +1810,7 @@ SYSCALL_DEFINE1(unshare, unsigned long, unshare_flags)
* If unsharing a user namespace must also unshare the thread.
*/
if (unshare_flags & CLONE_NEWUSER)
- unshare_flags |= CLONE_THREAD;
+ unshare_flags |= CLONE_THREAD | CLONE_FS;
/*
* If unsharing a pid namespace must also unshare the thread.
*/
diff --git a/kernel/futex.c b/kernel/futex.c
index f0090a993dab..b26dcfc02c94 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -223,7 +223,8 @@ static void drop_futex_key_refs(union futex_key *key)
* @rw: mapping needs to be read/write (values: VERIFY_READ,
* VERIFY_WRITE)
*
- * Returns a negative error code or 0
+ * Return: a negative error code or 0
+ *
* The key words are stored in *key on success.
*
* For shared mappings, it's (page->index, file_inode(vma->vm_file),
@@ -705,9 +706,9 @@ lookup_pi_state(u32 uval, struct futex_hash_bucket *hb,
* be "current" except in the case of requeue pi.
* @set_waiters: force setting the FUTEX_WAITERS bit (1) or not (0)
*
- * Returns:
- * 0 - ready to wait
- * 1 - acquired the lock
+ * Return:
+ * 0 - ready to wait;
+ * 1 - acquired the lock;
* <0 - error
*
* The hb->lock and futex_key refs shall be held by the caller.
@@ -1191,9 +1192,9 @@ void requeue_pi_wake_futex(struct futex_q *q, union futex_key *key,
* then direct futex_lock_pi_atomic() to force setting the FUTEX_WAITERS bit.
* hb1 and hb2 must be held by the caller.
*
- * Returns:
- * 0 - failed to acquire the lock atomicly
- * 1 - acquired the lock
+ * Return:
+ * 0 - failed to acquire the lock atomically;
+ * 1 - acquired the lock;
* <0 - error
*/
static int futex_proxy_trylock_atomic(u32 __user *pifutex,
@@ -1254,8 +1255,8 @@ static int futex_proxy_trylock_atomic(u32 __user *pifutex,
* Requeue waiters on uaddr1 to uaddr2. In the requeue_pi case, try to acquire
* uaddr2 atomically on behalf of the top waiter.
*
- * Returns:
- * >=0 - on success, the number of tasks requeued or woken
+ * Return:
+ * >=0 - on success, the number of tasks requeued or woken;
* <0 - on error
*/
static int futex_requeue(u32 __user *uaddr1, unsigned int flags,
@@ -1536,8 +1537,8 @@ static inline void queue_me(struct futex_q *q, struct futex_hash_bucket *hb)
* The q->lock_ptr must not be held by the caller. A call to unqueue_me() must
* be paired with exactly one earlier call to queue_me().
*
- * Returns:
- * 1 - if the futex_q was still queued (and we removed unqueued it)
+ * Return:
+ * 1 - if the futex_q was still queued (and we removed unqueued it);
* 0 - if the futex_q was already removed by the waking thread
*/
static int unqueue_me(struct futex_q *q)
@@ -1707,9 +1708,9 @@ static long futex_wait_restart(struct restart_block *restart);
* the pi_state owner as well as handle race conditions that may allow us to
* acquire the lock. Must be called with the hb lock held.
*
- * Returns:
- * 1 - success, lock taken
- * 0 - success, lock not taken
+ * Return:
+ * 1 - success, lock taken;
+ * 0 - success, lock not taken;
* <0 - on error (-EFAULT)
*/
static int fixup_owner(u32 __user *uaddr, struct futex_q *q, int locked)
@@ -1824,8 +1825,8 @@ static void futex_wait_queue_me(struct futex_hash_bucket *hb, struct futex_q *q,
* Return with the hb lock held and a q.key reference on success, and unlocked
* with no q.key reference on failure.
*
- * Returns:
- * 0 - uaddr contains val and hb has been locked
+ * Return:
+ * 0 - uaddr contains val and hb has been locked;
* <1 - -EFAULT or -EWOULDBLOCK (uaddr does not contain val) and hb is unlocked
*/
static int futex_wait_setup(u32 __user *uaddr, u32 val, unsigned int flags,
@@ -2203,9 +2204,9 @@ pi_faulted:
* the wakeup and return the appropriate error code to the caller. Must be
* called with the hb lock held.
*
- * Returns
- * 0 - no early wakeup detected
- * <0 - -ETIMEDOUT or -ERESTARTNOINTR
+ * Return:
+ * 0 = no early wakeup detected;
+ * <0 = -ETIMEDOUT or -ERESTARTNOINTR
*/
static inline
int handle_early_requeue_pi_wakeup(struct futex_hash_bucket *hb,
@@ -2247,7 +2248,6 @@ int handle_early_requeue_pi_wakeup(struct futex_hash_bucket *hb,
* @val: the expected value of uaddr
* @abs_time: absolute timeout
* @bitset: 32 bit wakeup bitset set by userspace, defaults to all
- * @clockrt: whether to use CLOCK_REALTIME (1) or CLOCK_MONOTONIC (0)
* @uaddr2: the pi futex we will take prior to returning to user-space
*
* The caller will wait on uaddr and will be requeued by futex_requeue() to
@@ -2258,7 +2258,7 @@ int handle_early_requeue_pi_wakeup(struct futex_hash_bucket *hb,
* there was a need to.
*
* We call schedule in futex_wait_queue_me() when we enqueue and return there
- * via the following:
+ * via the following--
* 1) wakeup on uaddr2 after an atomic lock acquisition by futex_requeue()
* 2) wakeup on uaddr2 after a requeue
* 3) signal
@@ -2276,8 +2276,8 @@ int handle_early_requeue_pi_wakeup(struct futex_hash_bucket *hb,
*
* If 4 or 7, we cleanup and return with -ETIMEDOUT.
*
- * Returns:
- * 0 - On success
+ * Return:
+ * 0 - On success;
* <0 - On error
*/
static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags,
diff --git a/kernel/signal.c b/kernel/signal.c
index 2ec870a4c3c4..dd72567767d9 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -485,6 +485,9 @@ flush_signal_handlers(struct task_struct *t, int force_default)
if (force_default || ka->sa.sa_handler != SIG_IGN)
ka->sa.sa_handler = SIG_DFL;
ka->sa.sa_flags = 0;
+#ifdef __ARCH_HAS_SA_RESTORER
+ ka->sa.sa_restorer = NULL;
+#endif
sigemptyset(&ka->sa.sa_mask);
ka++;
}
@@ -2682,7 +2685,7 @@ static int do_sigpending(void *set, unsigned long sigsetsize)
/**
* sys_rt_sigpending - examine a pending signal that has been raised
* while blocked
- * @set: stores pending signals
+ * @uset: stores pending signals
* @sigsetsize: size of sigset_t type or larger
*/
SYSCALL_DEFINE2(rt_sigpending, sigset_t __user *, uset, size_t, sigsetsize)
diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig
index 192473b22799..fc382d6e2765 100644
--- a/kernel/trace/Kconfig
+++ b/kernel/trace/Kconfig
@@ -414,24 +414,28 @@ config PROBE_EVENTS
def_bool n
config DYNAMIC_FTRACE
- bool "enable/disable ftrace tracepoints dynamically"
+ bool "enable/disable function tracing dynamically"
depends on FUNCTION_TRACER
depends on HAVE_DYNAMIC_FTRACE
default y
help
- This option will modify all the calls to ftrace dynamically
- (will patch them out of the binary image and replace them
- with a No-Op instruction) as they are called. A table is
- created to dynamically enable them again.
+ This option will modify all the calls to function tracing
+ dynamically (will patch them out of the binary image and
+ replace them with a No-Op instruction) on boot up. During
+ compile time, a table is made of all the locations that ftrace
+ can function trace, and this table is linked into the kernel
+ image. When this is enabled, functions can be individually
+ enabled, and the functions not enabled will not affect
+ performance of the system.
+
+ See the files in /sys/kernel/debug/tracing:
+ available_filter_functions
+ set_ftrace_filter
+ set_ftrace_notrace
This way a CONFIG_FUNCTION_TRACER kernel is slightly larger, but
otherwise has native performance as long as no tracing is active.
- The changes to the code are done by a kernel thread that
- wakes up once a second and checks to see if any ftrace calls
- were made. If so, it runs stop_machine (stops all CPUS)
- and modifies the code to jump over the call to ftrace.
-
config DYNAMIC_FTRACE_WITH_REGS
def_bool y
depends on DYNAMIC_FTRACE
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index c2e2c2310374..1f835a83cb2c 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -2400,6 +2400,27 @@ static void test_ftrace_alive(struct seq_file *m)
seq_printf(m, "# MAY BE MISSING FUNCTION EVENTS\n");
}
+#ifdef CONFIG_TRACER_MAX_TRACE
+static void print_snapshot_help(struct seq_file *m, struct trace_iterator *iter)
+{
+ if (iter->trace->allocated_snapshot)
+ seq_printf(m, "#\n# * Snapshot is allocated *\n#\n");
+ else
+ seq_printf(m, "#\n# * Snapshot is freed *\n#\n");
+
+ seq_printf(m, "# Snapshot commands:\n");
+ seq_printf(m, "# echo 0 > snapshot : Clears and frees snapshot buffer\n");
+ seq_printf(m, "# echo 1 > snapshot : Allocates snapshot buffer, if not already allocated.\n");
+ seq_printf(m, "# Takes a snapshot of the main buffer.\n");
+ seq_printf(m, "# echo 2 > snapshot : Clears snapshot buffer (but does not allocate)\n");
+ seq_printf(m, "# (Doesn't have to be '2' works with any number that\n");
+ seq_printf(m, "# is not a '0' or '1')\n");
+}
+#else
+/* Should never be called */
+static inline void print_snapshot_help(struct seq_file *m, struct trace_iterator *iter) { }
+#endif
+
static int s_show(struct seq_file *m, void *v)
{
struct trace_iterator *iter = v;
@@ -2411,7 +2432,9 @@ static int s_show(struct seq_file *m, void *v)
seq_puts(m, "#\n");
test_ftrace_alive(m);
}
- if (iter->trace && iter->trace->print_header)
+ if (iter->snapshot && trace_empty(iter))
+ print_snapshot_help(m, iter);
+ else if (iter->trace && iter->trace->print_header)
iter->trace->print_header(m);
else
trace_default_header(m);
@@ -4144,8 +4167,6 @@ tracing_snapshot_write(struct file *filp, const char __user *ubuf, size_t cnt,
default:
if (current_trace->allocated_snapshot)
tracing_reset_online_cpus(&max_tr);
- else
- ret = -EINVAL;
break;
}
diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c
index 8b650837083e..b14f4d342043 100644
--- a/kernel/user_namespace.c
+++ b/kernel/user_namespace.c
@@ -21,6 +21,7 @@
#include <linux/uaccess.h>
#include <linux/ctype.h>
#include <linux/projid.h>
+#include <linux/fs_struct.h>
static struct kmem_cache *user_ns_cachep __read_mostly;
@@ -837,6 +838,9 @@ static int userns_install(struct nsproxy *nsproxy, void *ns)
if (atomic_read(&current->mm->mm_users) > 1)
return -EINVAL;
+ if (current->fs->users != 1)
+ return -EINVAL;
+
if (!ns_capable(user_ns, CAP_SYS_ADMIN))
return -EPERM;
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index 81f2457811eb..55fac5b991b7 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -457,11 +457,12 @@ static int worker_pool_assign_id(struct worker_pool *pool)
int ret;
mutex_lock(&worker_pool_idr_mutex);
- idr_pre_get(&worker_pool_idr, GFP_KERNEL);
- ret = idr_get_new(&worker_pool_idr, pool, &pool->id);
+ ret = idr_alloc(&worker_pool_idr, pool, 0, 0, GFP_KERNEL);
+ if (ret >= 0)
+ pool->id = ret;
mutex_unlock(&worker_pool_idr_mutex);
- return ret;
+ return ret < 0 ? ret : 0;
}
/*
diff --git a/lib/idr.c b/lib/idr.c
index 00739aaf95a2..322e2816f2fb 100644
--- a/lib/idr.c
+++ b/lib/idr.c
@@ -106,8 +106,14 @@ static struct idr_layer *idr_layer_alloc(gfp_t gfp_mask, struct idr *layer_idr)
if (layer_idr)
return get_from_free_list(layer_idr);
- /* try to allocate directly from kmem_cache */
- new = kmem_cache_zalloc(idr_layer_cache, gfp_mask);
+ /*
+ * Try to allocate directly from kmem_cache. We want to try this
+ * before preload buffer; otherwise, non-preloading idr_alloc()
+ * users will end up taking advantage of preloading ones. As the
+ * following is allowed to fail for preloaded cases, suppress
+ * warning this time.
+ */
+ new = kmem_cache_zalloc(idr_layer_cache, gfp_mask | __GFP_NOWARN);
if (new)
return new;
@@ -115,18 +121,24 @@ static struct idr_layer *idr_layer_alloc(gfp_t gfp_mask, struct idr *layer_idr)
* Try to fetch one from the per-cpu preload buffer if in process
* context. See idr_preload() for details.
*/
- if (in_interrupt())
- return NULL;
-
- preempt_disable();
- new = __this_cpu_read(idr_preload_head);
- if (new) {
- __this_cpu_write(idr_preload_head, new->ary[0]);
- __this_cpu_dec(idr_preload_cnt);
- new->ary[0] = NULL;
+ if (!in_interrupt()) {
+ preempt_disable();
+ new = __this_cpu_read(idr_preload_head);
+ if (new) {
+ __this_cpu_write(idr_preload_head, new->ary[0]);
+ __this_cpu_dec(idr_preload_cnt);
+ new->ary[0] = NULL;
+ }
+ preempt_enable();
+ if (new)
+ return new;
}
- preempt_enable();
- return new;
+
+ /*
+ * Both failed. Try kmem_cache again w/o adding __GFP_NOWARN so
+ * that memory allocation failure warning is printed as intended.
+ */
+ return kmem_cache_zalloc(idr_layer_cache, gfp_mask);
}
static void idr_layer_rcu_free(struct rcu_head *head)
@@ -184,20 +196,7 @@ static void idr_mark_full(struct idr_layer **pa, int id)
}
}
-/**
- * idr_pre_get - reserve resources for idr allocation
- * @idp: idr handle
- * @gfp_mask: memory allocation flags
- *
- * This function should be called prior to calling the idr_get_new* functions.
- * It preallocates enough memory to satisfy the worst possible allocation. The
- * caller should pass in GFP_KERNEL if possible. This of course requires that
- * no spinning locks be held.
- *
- * If the system is REALLY out of memory this function returns %0,
- * otherwise %1.
- */
-int idr_pre_get(struct idr *idp, gfp_t gfp_mask)
+int __idr_pre_get(struct idr *idp, gfp_t gfp_mask)
{
while (idp->id_free_cnt < MAX_IDR_FREE) {
struct idr_layer *new;
@@ -208,13 +207,12 @@ int idr_pre_get(struct idr *idp, gfp_t gfp_mask)
}
return 1;
}
-EXPORT_SYMBOL(idr_pre_get);
+EXPORT_SYMBOL(__idr_pre_get);
/**
* sub_alloc - try to allocate an id without growing the tree depth
* @idp: idr handle
* @starting_id: id to start search at
- * @id: pointer to the allocated handle
* @pa: idr_layer[MAX_IDR_LEVEL] used as backtrack buffer
* @gfp_mask: allocation mask for idr_layer_alloc()
* @layer_idr: optional idr passed to idr_layer_alloc()
@@ -376,25 +374,7 @@ static void idr_fill_slot(struct idr *idr, void *ptr, int id,
idr_mark_full(pa, id);
}
-/**
- * idr_get_new_above - allocate new idr entry above or equal to a start id
- * @idp: idr handle
- * @ptr: pointer you want associated with the id
- * @starting_id: id to start search at
- * @id: pointer to the allocated handle
- *
- * This is the allocate id function. It should be called with any
- * required locks.
- *
- * If allocation from IDR's private freelist fails, idr_get_new_above() will
- * return %-EAGAIN. The caller should retry the idr_pre_get() call to refill
- * IDR's preallocation and then retry the idr_get_new_above() call.
- *
- * If the idr is full idr_get_new_above() will return %-ENOSPC.
- *
- * @id returns a value in the range @starting_id ... %0x7fffffff
- */
-int idr_get_new_above(struct idr *idp, void *ptr, int starting_id, int *id)
+int __idr_get_new_above(struct idr *idp, void *ptr, int starting_id, int *id)
{
struct idr_layer *pa[MAX_IDR_LEVEL + 1];
int rv;
@@ -407,7 +387,7 @@ int idr_get_new_above(struct idr *idp, void *ptr, int starting_id, int *id)
*id = rv;
return 0;
}
-EXPORT_SYMBOL(idr_get_new_above);
+EXPORT_SYMBOL(__idr_get_new_above);
/**
* idr_preload - preload for idr_alloc()
@@ -908,7 +888,7 @@ static void free_bitmap(struct ida *ida, struct ida_bitmap *bitmap)
int ida_pre_get(struct ida *ida, gfp_t gfp_mask)
{
/* allocate idr_layers */
- if (!idr_pre_get(&ida->idr, gfp_mask))
+ if (!__idr_pre_get(&ida->idr, gfp_mask))
return 0;
/* allocate free_bitmap */
diff --git a/lib/xz/Kconfig b/lib/xz/Kconfig
index 82a04d7ba99e..08837db52d94 100644
--- a/lib/xz/Kconfig
+++ b/lib/xz/Kconfig
@@ -15,7 +15,7 @@ config XZ_DEC_X86
config XZ_DEC_POWERPC
bool "PowerPC BCJ filter decoder"
- default y if POWERPC
+ default y if PPC
select XZ_DEC_BCJ
config XZ_DEC_IA64
diff --git a/mm/Kconfig b/mm/Kconfig
index ae55c1e04d10..3bea74f1ccfe 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -286,8 +286,12 @@ config NR_QUICK
default "1"
config VIRT_TO_BUS
- def_bool y
- depends on HAVE_VIRT_TO_BUS
+ bool
+ help
+ An architecture should select this if it implements the
+ deprecated interface virt_to_bus(). All new architectures
+ should probably not select this.
+
config MMU_NOTIFIER
bool
diff --git a/mm/fremap.c b/mm/fremap.c
index 0cd4c11488ed..4723ac8d2fc2 100644
--- a/mm/fremap.c
+++ b/mm/fremap.c
@@ -129,7 +129,7 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size,
struct vm_area_struct *vma;
int err = -EINVAL;
int has_write_lock = 0;
- vm_flags_t vm_flags;
+ vm_flags_t vm_flags = 0;
if (prot)
return err;
@@ -254,7 +254,8 @@ get_write_lock:
*/
out:
- vm_flags = vma->vm_flags;
+ if (vma)
+ vm_flags = vma->vm_flags;
if (likely(!has_write_lock))
up_read(&mm->mmap_sem);
else
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index b81a367b9f39..9597eec8239d 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -1801,7 +1801,7 @@ int __ref remove_memory(int nid, u64 start, u64 size)
int retry = 1;
start_pfn = PFN_DOWN(start);
- end_pfn = start_pfn + PFN_DOWN(size);
+ end_pfn = PFN_UP(start + size - 1);
/*
* When CONFIG_MEMCG is on, one memory block may be used by other
diff --git a/mm/process_vm_access.c b/mm/process_vm_access.c
index 926b46649749..fd26d0433509 100644
--- a/mm/process_vm_access.c
+++ b/mm/process_vm_access.c
@@ -429,12 +429,6 @@ compat_process_vm_rw(compat_pid_t pid,
if (flags != 0)
return -EINVAL;
- if (!access_ok(VERIFY_READ, lvec, liovcnt * sizeof(*lvec)))
- goto out;
-
- if (!access_ok(VERIFY_READ, rvec, riovcnt * sizeof(*rvec)))
- goto out;
-
if (vm_write)
rc = compat_rw_copy_check_uvector(WRITE, lvec, liovcnt,
UIO_FASTIOV, iovstack_l,
@@ -459,8 +453,6 @@ free_iovecs:
kfree(iov_r);
if (iov_l != iovstack_l)
kfree(iov_l);
-
-out:
return rc;
}
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
index d5f1d3fd4b28..314c73ed418f 100644
--- a/net/bridge/br_device.c
+++ b/net/bridge/br_device.c
@@ -66,7 +66,7 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
goto out;
}
- mdst = br_mdb_get(br, skb);
+ mdst = br_mdb_get(br, skb, vid);
if (mdst || BR_INPUT_SKB_CB_MROUTERS_ONLY(skb))
br_multicast_deliver(mdst, skb);
else
diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c
index 480330151898..828e2bcc1f52 100644
--- a/net/bridge/br_input.c
+++ b/net/bridge/br_input.c
@@ -97,7 +97,7 @@ int br_handle_frame_finish(struct sk_buff *skb)
if (is_broadcast_ether_addr(dest))
skb2 = skb;
else if (is_multicast_ether_addr(dest)) {
- mdst = br_mdb_get(br, skb);
+ mdst = br_mdb_get(br, skb, vid);
if (mdst || BR_INPUT_SKB_CB_MROUTERS_ONLY(skb)) {
if ((mdst && mdst->mglist) ||
br_multicast_is_router(br))
diff --git a/net/bridge/br_mdb.c b/net/bridge/br_mdb.c
index 9f97b850fc65..ee79f3f20383 100644
--- a/net/bridge/br_mdb.c
+++ b/net/bridge/br_mdb.c
@@ -80,6 +80,7 @@ static int br_mdb_fill_info(struct sk_buff *skb, struct netlink_callback *cb,
port = p->port;
if (port) {
struct br_mdb_entry e;
+ memset(&e, 0, sizeof(e));
e.ifindex = port->dev->ifindex;
e.state = p->state;
if (p->addr.proto == htons(ETH_P_IP))
@@ -136,6 +137,7 @@ static int br_mdb_dump(struct sk_buff *skb, struct netlink_callback *cb)
break;
bpm = nlmsg_data(nlh);
+ memset(bpm, 0, sizeof(*bpm));
bpm->ifindex = dev->ifindex;
if (br_mdb_fill_info(skb, cb, dev) < 0)
goto out;
@@ -171,6 +173,7 @@ static int nlmsg_populate_mdb_fill(struct sk_buff *skb,
return -EMSGSIZE;
bpm = nlmsg_data(nlh);
+ memset(bpm, 0, sizeof(*bpm));
bpm->family = AF_BRIDGE;
bpm->ifindex = dev->ifindex;
nest = nla_nest_start(skb, MDBA_MDB);
@@ -228,6 +231,7 @@ void br_mdb_notify(struct net_device *dev, struct net_bridge_port *port,
{
struct br_mdb_entry entry;
+ memset(&entry, 0, sizeof(entry));
entry.ifindex = port->dev->ifindex;
entry.addr.proto = group->proto;
entry.addr.u.ip4 = group->u.ip4;
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
index 10e6fce1bb62..923fbeaf7afd 100644
--- a/net/bridge/br_multicast.c
+++ b/net/bridge/br_multicast.c
@@ -132,7 +132,7 @@ static struct net_bridge_mdb_entry *br_mdb_ip6_get(
#endif
struct net_bridge_mdb_entry *br_mdb_get(struct net_bridge *br,
- struct sk_buff *skb)
+ struct sk_buff *skb, u16 vid)
{
struct net_bridge_mdb_htable *mdb = rcu_dereference(br->mdb);
struct br_ip ip;
@@ -144,6 +144,7 @@ struct net_bridge_mdb_entry *br_mdb_get(struct net_bridge *br,
return NULL;
ip.proto = skb->protocol;
+ ip.vid = vid;
switch (skb->protocol) {
case htons(ETH_P_IP):
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index 6d314c4e6bcb..3cbf5beb3d4b 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -442,7 +442,7 @@ extern int br_multicast_rcv(struct net_bridge *br,
struct net_bridge_port *port,
struct sk_buff *skb);
extern struct net_bridge_mdb_entry *br_mdb_get(struct net_bridge *br,
- struct sk_buff *skb);
+ struct sk_buff *skb, u16 vid);
extern void br_multicast_add_port(struct net_bridge_port *port);
extern void br_multicast_del_port(struct net_bridge_port *port);
extern void br_multicast_enable_port(struct net_bridge_port *port);
@@ -504,7 +504,7 @@ static inline int br_multicast_rcv(struct net_bridge *br,
}
static inline struct net_bridge_mdb_entry *br_mdb_get(struct net_bridge *br,
- struct sk_buff *skb)
+ struct sk_buff *skb, u16 vid)
{
return NULL;
}
diff --git a/net/ceph/osdmap.c b/net/ceph/osdmap.c
index 69bc4bf89e3e..4543b9aba40c 100644
--- a/net/ceph/osdmap.c
+++ b/net/ceph/osdmap.c
@@ -654,6 +654,24 @@ static int osdmap_set_max_osd(struct ceph_osdmap *map, int max)
return 0;
}
+static int __decode_pgid(void **p, void *end, struct ceph_pg *pg)
+{
+ u8 v;
+
+ ceph_decode_need(p, end, 1+8+4+4, bad);
+ v = ceph_decode_8(p);
+ if (v != 1)
+ goto bad;
+ pg->pool = ceph_decode_64(p);
+ pg->seed = ceph_decode_32(p);
+ *p += 4; /* skip preferred */
+ return 0;
+
+bad:
+ dout("error decoding pgid\n");
+ return -EINVAL;
+}
+
/*
* decode a full map.
*/
@@ -745,13 +763,12 @@ struct ceph_osdmap *osdmap_decode(void **p, void *end)
for (i = 0; i < len; i++) {
int n, j;
struct ceph_pg pgid;
- struct ceph_pg_v1 pgid_v1;
struct ceph_pg_mapping *pg;
- ceph_decode_need(p, end, sizeof(u32) + sizeof(u64), bad);
- ceph_decode_copy(p, &pgid_v1, sizeof(pgid_v1));
- pgid.pool = le32_to_cpu(pgid_v1.pool);
- pgid.seed = le16_to_cpu(pgid_v1.ps);
+ err = __decode_pgid(p, end, &pgid);
+ if (err)
+ goto bad;
+ ceph_decode_need(p, end, sizeof(u32), bad);
n = ceph_decode_32(p);
err = -EINVAL;
if (n > (UINT_MAX - sizeof(*pg)) / sizeof(u32))
@@ -818,8 +835,8 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end,
u16 version;
ceph_decode_16_safe(p, end, version, bad);
- if (version > 6) {
- pr_warning("got unknown v %d > %d of inc osdmap\n", version, 6);
+ if (version != 6) {
+ pr_warning("got unknown v %d != 6 of inc osdmap\n", version);
goto bad;
}
@@ -963,15 +980,14 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end,
while (len--) {
struct ceph_pg_mapping *pg;
int j;
- struct ceph_pg_v1 pgid_v1;
struct ceph_pg pgid;
u32 pglen;
- ceph_decode_need(p, end, sizeof(u64) + sizeof(u32), bad);
- ceph_decode_copy(p, &pgid_v1, sizeof(pgid_v1));
- pgid.pool = le32_to_cpu(pgid_v1.pool);
- pgid.seed = le16_to_cpu(pgid_v1.ps);
- pglen = ceph_decode_32(p);
+ err = __decode_pgid(p, end, &pgid);
+ if (err)
+ goto bad;
+ ceph_decode_need(p, end, sizeof(u32), bad);
+ pglen = ceph_decode_32(p);
if (pglen) {
ceph_decode_need(p, end, pglen*sizeof(u32), bad);
diff --git a/net/core/dev.c b/net/core/dev.c
index a06a7a58dd11..dffbef70cd31 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -3444,6 +3444,7 @@ ncls:
}
switch (rx_handler(&skb)) {
case RX_HANDLER_CONSUMED:
+ ret = NET_RX_SUCCESS;
goto unlock;
case RX_HANDLER_ANOTHER:
goto another_round;
@@ -4103,7 +4104,7 @@ static void net_rx_action(struct softirq_action *h)
* Allow this to run for 2 jiffies since which will allow
* an average latency of 1.5/HZ.
*/
- if (unlikely(budget <= 0 || time_after(jiffies, time_limit)))
+ if (unlikely(budget <= 0 || time_after_eq(jiffies, time_limit)))
goto softnet_break;
local_irq_enable();
@@ -4780,7 +4781,7 @@ EXPORT_SYMBOL(dev_set_mac_address);
/**
* dev_change_carrier - Change device carrier
* @dev: device
- * @new_carries: new value
+ * @new_carrier: new value
*
* Change device carrier
*/
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index b376410ff259..a585d45cc9d9 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -979,6 +979,7 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
* report anything.
*/
ivi.spoofchk = -1;
+ memset(ivi.mac, 0, sizeof(ivi.mac));
if (dev->netdev_ops->ndo_get_vf_config(dev, i, &ivi))
break;
vf_mac.vf =
diff --git a/net/dcb/dcbnl.c b/net/dcb/dcbnl.c
index 1b588e23cf80..21291f1abcd6 100644
--- a/net/dcb/dcbnl.c
+++ b/net/dcb/dcbnl.c
@@ -284,6 +284,7 @@ static int dcbnl_getperm_hwaddr(struct net_device *netdev, struct nlmsghdr *nlh,
if (!netdev->dcbnl_ops->getpermhwaddr)
return -EOPNOTSUPP;
+ memset(perm_addr, 0, sizeof(perm_addr));
netdev->dcbnl_ops->getpermhwaddr(netdev, perm_addr);
return nla_put(skb, DCB_ATTR_PERM_HWADDR, sizeof(perm_addr), perm_addr);
@@ -1042,6 +1043,7 @@ static int dcbnl_ieee_fill(struct sk_buff *skb, struct net_device *netdev)
if (ops->ieee_getets) {
struct ieee_ets ets;
+ memset(&ets, 0, sizeof(ets));
err = ops->ieee_getets(netdev, &ets);
if (!err &&
nla_put(skb, DCB_ATTR_IEEE_ETS, sizeof(ets), &ets))
@@ -1050,6 +1052,7 @@ static int dcbnl_ieee_fill(struct sk_buff *skb, struct net_device *netdev)
if (ops->ieee_getmaxrate) {
struct ieee_maxrate maxrate;
+ memset(&maxrate, 0, sizeof(maxrate));
err = ops->ieee_getmaxrate(netdev, &maxrate);
if (!err) {
err = nla_put(skb, DCB_ATTR_IEEE_MAXRATE,
@@ -1061,6 +1064,7 @@ static int dcbnl_ieee_fill(struct sk_buff *skb, struct net_device *netdev)
if (ops->ieee_getpfc) {
struct ieee_pfc pfc;
+ memset(&pfc, 0, sizeof(pfc));
err = ops->ieee_getpfc(netdev, &pfc);
if (!err &&
nla_put(skb, DCB_ATTR_IEEE_PFC, sizeof(pfc), &pfc))
@@ -1094,6 +1098,7 @@ static int dcbnl_ieee_fill(struct sk_buff *skb, struct net_device *netdev)
/* get peer info if available */
if (ops->ieee_peer_getets) {
struct ieee_ets ets;
+ memset(&ets, 0, sizeof(ets));
err = ops->ieee_peer_getets(netdev, &ets);
if (!err &&
nla_put(skb, DCB_ATTR_IEEE_PEER_ETS, sizeof(ets), &ets))
@@ -1102,6 +1107,7 @@ static int dcbnl_ieee_fill(struct sk_buff *skb, struct net_device *netdev)
if (ops->ieee_peer_getpfc) {
struct ieee_pfc pfc;
+ memset(&pfc, 0, sizeof(pfc));
err = ops->ieee_peer_getpfc(netdev, &pfc);
if (!err &&
nla_put(skb, DCB_ATTR_IEEE_PEER_PFC, sizeof(pfc), &pfc))
@@ -1280,6 +1286,7 @@ static int dcbnl_cee_fill(struct sk_buff *skb, struct net_device *netdev)
/* peer info if available */
if (ops->cee_peer_getpg) {
struct cee_pg pg;
+ memset(&pg, 0, sizeof(pg));
err = ops->cee_peer_getpg(netdev, &pg);
if (!err &&
nla_put(skb, DCB_ATTR_CEE_PEER_PG, sizeof(pg), &pg))
@@ -1288,6 +1295,7 @@ static int dcbnl_cee_fill(struct sk_buff *skb, struct net_device *netdev)
if (ops->cee_peer_getpfc) {
struct cee_pfc pfc;
+ memset(&pfc, 0, sizeof(pfc));
err = ops->cee_peer_getpfc(netdev, &pfc);
if (!err &&
nla_put(skb, DCB_ATTR_CEE_PEER_PFC, sizeof(pfc), &pfc))
diff --git a/net/ieee802154/6lowpan.h b/net/ieee802154/6lowpan.h
index 8c2251fb0a3f..bba5f8336317 100644
--- a/net/ieee802154/6lowpan.h
+++ b/net/ieee802154/6lowpan.h
@@ -84,7 +84,7 @@
(memcmp(addr1, addr2, length >> 3) == 0)
/* local link, i.e. FE80::/10 */
-#define is_addr_link_local(a) (((a)->s6_addr16[0]) == 0x80FE)
+#define is_addr_link_local(a) (((a)->s6_addr16[0]) == htons(0xFE80))
/*
* check whether we can compress the IID to 16 bits,
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
index 7d1874be1df3..786d97aee751 100644
--- a/net/ipv4/inet_connection_sock.c
+++ b/net/ipv4/inet_connection_sock.c
@@ -735,6 +735,7 @@ EXPORT_SYMBOL(inet_csk_destroy_sock);
* tcp/dccp_create_openreq_child().
*/
void inet_csk_prepare_forced_close(struct sock *sk)
+ __releases(&sk->sk_lock.slock)
{
/* sk_clone_lock locked the socket and set refcnt to 2 */
bh_unlock_sock(sk);
diff --git a/net/ipv4/ip_options.c b/net/ipv4/ip_options.c
index f6289bf6f332..310a3647c83d 100644
--- a/net/ipv4/ip_options.c
+++ b/net/ipv4/ip_options.c
@@ -423,7 +423,7 @@ int ip_options_compile(struct net *net,
put_unaligned_be32(midtime, timeptr);
opt->is_changed = 1;
}
- } else {
+ } else if ((optptr[3]&0xF) != IPOPT_TS_PRESPEC) {
unsigned int overflow = optptr[3]>>4;
if (overflow == 15) {
pp_ptr = optptr + 3;
diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c
index b1876e52091e..e33fe0ab2568 100644
--- a/net/ipv6/ip6_input.c
+++ b/net/ipv6/ip6_input.c
@@ -281,7 +281,8 @@ int ip6_mc_input(struct sk_buff *skb)
* IPv6 multicast router mode is now supported ;)
*/
if (dev_net(skb->dev)->ipv6.devconf_all->mc_forwarding &&
- !(ipv6_addr_type(&hdr->daddr) & IPV6_ADDR_LINKLOCAL) &&
+ !(ipv6_addr_type(&hdr->daddr) &
+ (IPV6_ADDR_LOOPBACK|IPV6_ADDR_LINKLOCAL)) &&
likely(!(IP6CB(skb)->flags & IP6SKB_FORWARDED))) {
/*
* Okay, we try to forward - split and duplicate
diff --git a/net/irda/ircomm/ircomm_tty.c b/net/irda/ircomm/ircomm_tty.c
index 9a5fd3c3e530..362ba47968e4 100644
--- a/net/irda/ircomm/ircomm_tty.c
+++ b/net/irda/ircomm/ircomm_tty.c
@@ -280,7 +280,7 @@ static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self,
struct tty_port *port = &self->port;
DECLARE_WAITQUEUE(wait, current);
int retval;
- int do_clocal = 0, extra_count = 0;
+ int do_clocal = 0;
unsigned long flags;
IRDA_DEBUG(2, "%s()\n", __func__ );
@@ -289,8 +289,15 @@ static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self,
* If non-blocking mode is set, or the port is not enabled,
* then make the check up front and then exit.
*/
- if (filp->f_flags & O_NONBLOCK || tty->flags & (1 << TTY_IO_ERROR)){
- /* nonblock mode is set or port is not enabled */
+ if (test_bit(TTY_IO_ERROR, &tty->flags)) {
+ port->flags |= ASYNC_NORMAL_ACTIVE;
+ return 0;
+ }
+
+ if (filp->f_flags & O_NONBLOCK) {
+ /* nonblock mode is set */
+ if (tty->termios.c_cflag & CBAUD)
+ tty_port_raise_dtr_rts(port);
port->flags |= ASYNC_NORMAL_ACTIVE;
IRDA_DEBUG(1, "%s(), O_NONBLOCK requested!\n", __func__ );
return 0;
@@ -315,18 +322,16 @@ static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self,
__FILE__, __LINE__, tty->driver->name, port->count);
spin_lock_irqsave(&port->lock, flags);
- if (!tty_hung_up_p(filp)) {
- extra_count = 1;
+ if (!tty_hung_up_p(filp))
port->count--;
- }
- spin_unlock_irqrestore(&port->lock, flags);
port->blocked_open++;
+ spin_unlock_irqrestore(&port->lock, flags);
while (1) {
if (tty->termios.c_cflag & CBAUD)
tty_port_raise_dtr_rts(port);
- current->state = TASK_INTERRUPTIBLE;
+ set_current_state(TASK_INTERRUPTIBLE);
if (tty_hung_up_p(filp) ||
!test_bit(ASYNCB_INITIALIZED, &port->flags)) {
@@ -361,13 +366,11 @@ static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self,
__set_current_state(TASK_RUNNING);
remove_wait_queue(&port->open_wait, &wait);
- if (extra_count) {
- /* ++ is not atomic, so this should be protected - Jean II */
- spin_lock_irqsave(&port->lock, flags);
+ spin_lock_irqsave(&port->lock, flags);
+ if (!tty_hung_up_p(filp))
port->count++;
- spin_unlock_irqrestore(&port->lock, flags);
- }
port->blocked_open--;
+ spin_unlock_irqrestore(&port->lock, flags);
IRDA_DEBUG(1, "%s(%d):block_til_ready after blocking on %s open_count=%d\n",
__FILE__, __LINE__, tty->driver->name, port->count);
diff --git a/net/key/af_key.c b/net/key/af_key.c
index 556fdafdd1ea..8555f331ea60 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -2201,7 +2201,7 @@ static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, const struct sadb_
XFRM_POLICY_BLOCK : XFRM_POLICY_ALLOW);
xp->priority = pol->sadb_x_policy_priority;
- sa = ext_hdrs[SADB_EXT_ADDRESS_SRC-1],
+ sa = ext_hdrs[SADB_EXT_ADDRESS_SRC-1];
xp->family = pfkey_sadb_addr2xfrm_addr(sa, &xp->selector.saddr);
if (!xp->family) {
err = -EINVAL;
@@ -2214,7 +2214,7 @@ static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, const struct sadb_
if (xp->selector.sport)
xp->selector.sport_mask = htons(0xffff);
- sa = ext_hdrs[SADB_EXT_ADDRESS_DST-1],
+ sa = ext_hdrs[SADB_EXT_ADDRESS_DST-1];
pfkey_sadb_addr2xfrm_addr(sa, &xp->selector.daddr);
xp->selector.prefixlen_d = sa->sadb_address_prefixlen;
@@ -2315,7 +2315,7 @@ static int pfkey_spddelete(struct sock *sk, struct sk_buff *skb, const struct sa
memset(&sel, 0, sizeof(sel));
- sa = ext_hdrs[SADB_EXT_ADDRESS_SRC-1],
+ sa = ext_hdrs[SADB_EXT_ADDRESS_SRC-1];
sel.family = pfkey_sadb_addr2xfrm_addr(sa, &sel.saddr);
sel.prefixlen_s = sa->sadb_address_prefixlen;
sel.proto = pfkey_proto_to_xfrm(sa->sadb_address_proto);
@@ -2323,7 +2323,7 @@ static int pfkey_spddelete(struct sock *sk, struct sk_buff *skb, const struct sa
if (sel.sport)
sel.sport_mask = htons(0xffff);
- sa = ext_hdrs[SADB_EXT_ADDRESS_DST-1],
+ sa = ext_hdrs[SADB_EXT_ADDRESS_DST-1];
pfkey_sadb_addr2xfrm_addr(sa, &sel.daddr);
sel.prefixlen_d = sa->sadb_address_prefixlen;
sel.proto = pfkey_proto_to_xfrm(sa->sadb_address_proto);
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 808f5fcd1ced..fb306814576a 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -3290,14 +3290,19 @@ static int ieee80211_cfg_get_channel(struct wiphy *wiphy,
int ret = -ENODATA;
rcu_read_lock();
- if (local->use_chanctx) {
- chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
- if (chanctx_conf) {
- *chandef = chanctx_conf->def;
- ret = 0;
- }
- } else if (local->open_count == local->monitors) {
- *chandef = local->monitor_chandef;
+ chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
+ if (chanctx_conf) {
+ *chandef = chanctx_conf->def;
+ ret = 0;
+ } else if (local->open_count > 0 &&
+ local->open_count == local->monitors &&
+ sdata->vif.type == NL80211_IFTYPE_MONITOR) {
+ if (local->use_chanctx)
+ *chandef = local->monitor_chandef;
+ else
+ cfg80211_chandef_create(chandef,
+ local->_oper_channel,
+ local->_oper_channel_type);
ret = 0;
}
rcu_read_unlock();
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 640afab304d7..baaa8608e52d 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -541,6 +541,9 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
ieee80211_adjust_monitor_flags(sdata, 1);
ieee80211_configure_filter(local);
+ mutex_lock(&local->mtx);
+ ieee80211_recalc_idle(local);
+ mutex_unlock(&local->mtx);
netif_carrier_on(dev);
break;
@@ -812,6 +815,9 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
ieee80211_adjust_monitor_flags(sdata, -1);
ieee80211_configure_filter(local);
+ mutex_lock(&local->mtx);
+ ieee80211_recalc_idle(local);
+ mutex_unlock(&local->mtx);
break;
case NL80211_IFTYPE_P2P_DEVICE:
/* relies on synchronize_rcu() below */
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 9f6464f3e05f..141577412d84 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -647,6 +647,9 @@ static void ieee80211_add_vht_ie(struct ieee80211_sub_if_data *sdata,
our_mcs = (le16_to_cpu(vht_cap.vht_mcs.rx_mcs_map) &
mask) >> shift;
+ if (our_mcs == IEEE80211_VHT_MCS_NOT_SUPPORTED)
+ continue;
+
switch (ap_mcs) {
default:
if (our_mcs <= ap_mcs)
@@ -3503,6 +3506,14 @@ void ieee80211_sta_quiesce(struct ieee80211_sub_if_data *sdata)
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
/*
+ * Stop timers before deleting work items, as timers
+ * could race and re-add the work-items. They will be
+ * re-established on connection.
+ */
+ del_timer_sync(&ifmgd->conn_mon_timer);
+ del_timer_sync(&ifmgd->bcn_mon_timer);
+
+ /*
* we need to use atomic bitops for the running bits
* only because both timers might fire at the same
* time -- the code here is properly synchronised.
@@ -3516,13 +3527,9 @@ void ieee80211_sta_quiesce(struct ieee80211_sub_if_data *sdata)
if (del_timer_sync(&ifmgd->timer))
set_bit(TMR_RUNNING_TIMER, &ifmgd->timers_running);
- cancel_work_sync(&ifmgd->chswitch_work);
if (del_timer_sync(&ifmgd->chswitch_timer))
set_bit(TMR_RUNNING_CHANSW, &ifmgd->timers_running);
-
- /* these will just be re-established on connection */
- del_timer_sync(&ifmgd->conn_mon_timer);
- del_timer_sync(&ifmgd->bcn_mon_timer);
+ cancel_work_sync(&ifmgd->chswitch_work);
}
void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata)
@@ -4315,6 +4322,17 @@ void ieee80211_mgd_stop(struct ieee80211_sub_if_data *sdata)
{
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
+ /*
+ * Make sure some work items will not run after this,
+ * they will not do anything but might not have been
+ * cancelled when disconnecting.
+ */
+ cancel_work_sync(&ifmgd->monitor_work);
+ cancel_work_sync(&ifmgd->beacon_connection_loss_work);
+ cancel_work_sync(&ifmgd->request_smps_work);
+ cancel_work_sync(&ifmgd->csa_connection_drop_work);
+ cancel_work_sync(&ifmgd->chswitch_work);
+
mutex_lock(&ifmgd->mtx);
if (ifmgd->assoc_data)
ieee80211_destroy_assoc_data(sdata, false);
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index ce78d1149f1d..8914d2d2881a 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -2745,7 +2745,8 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw,
cpu_to_le16(IEEE80211_FCTL_MOREDATA);
}
- sdata = IEEE80211_DEV_TO_SUB_IF(skb->dev);
+ if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
+ sdata = IEEE80211_DEV_TO_SUB_IF(skb->dev);
if (!ieee80211_tx_prepare(sdata, &tx, skb))
break;
dev_kfree_skb_any(skb);
diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c
index a9740bd6fe54..94b4b9853f60 100644
--- a/net/netfilter/nf_conntrack_helper.c
+++ b/net/netfilter/nf_conntrack_helper.c
@@ -339,6 +339,13 @@ void nf_ct_helper_log(struct sk_buff *skb, const struct nf_conn *ct,
{
const struct nf_conn_help *help;
const struct nf_conntrack_helper *helper;
+ struct va_format vaf;
+ va_list args;
+
+ va_start(args, fmt);
+
+ vaf.fmt = fmt;
+ vaf.va = &args;
/* Called from the helper function, this call never fails */
help = nfct_help(ct);
@@ -347,7 +354,9 @@ void nf_ct_helper_log(struct sk_buff *skb, const struct nf_conn *ct,
helper = rcu_dereference(help->helper);
nf_log_packet(nf_ct_l3num(ct), 0, skb, NULL, NULL, NULL,
- "nf_ct_%s: dropping packet: %s ", helper->name, fmt);
+ "nf_ct_%s: dropping packet: %pV ", helper->name, &vaf);
+
+ va_end(args);
}
EXPORT_SYMBOL_GPL(nf_ct_helper_log);
diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c
index d578ec251712..0b1b32cda307 100644
--- a/net/netfilter/nfnetlink.c
+++ b/net/netfilter/nfnetlink.c
@@ -62,11 +62,6 @@ void nfnl_unlock(__u8 subsys_id)
}
EXPORT_SYMBOL_GPL(nfnl_unlock);
-static struct mutex *nfnl_get_lock(__u8 subsys_id)
-{
- return &table[subsys_id].mutex;
-}
-
int nfnetlink_subsys_register(const struct nfnetlink_subsystem *n)
{
nfnl_lock(n->subsys_id);
@@ -199,7 +194,7 @@ replay:
rcu_read_unlock();
nfnl_lock(subsys_id);
if (rcu_dereference_protected(table[subsys_id].subsys,
- lockdep_is_held(nfnl_get_lock(subsys_id))) != ss ||
+ lockdep_is_held(&table[subsys_id].mutex)) != ss ||
nfnetlink_find_client(type, ss) != nc)
err = -EAGAIN;
else if (nc->call)
diff --git a/net/netfilter/xt_AUDIT.c b/net/netfilter/xt_AUDIT.c
index ba92824086f3..3228d7f24eb4 100644
--- a/net/netfilter/xt_AUDIT.c
+++ b/net/netfilter/xt_AUDIT.c
@@ -124,6 +124,9 @@ audit_tg(struct sk_buff *skb, const struct xt_action_param *par)
const struct xt_audit_info *info = par->targinfo;
struct audit_buffer *ab;
+ if (audit_enabled == 0)
+ goto errout;
+
ab = audit_log_start(NULL, GFP_ATOMIC, AUDIT_NETFILTER_PKT);
if (ab == NULL)
goto errout;
diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c
index 847d495cd4de..8a6c6ea466d8 100644
--- a/net/netlabel/netlabel_unlabeled.c
+++ b/net/netlabel/netlabel_unlabeled.c
@@ -1189,8 +1189,6 @@ static int netlbl_unlabel_staticlist(struct sk_buff *skb,
struct netlbl_unlhsh_walk_arg cb_arg;
u32 skip_bkt = cb->args[0];
u32 skip_chain = cb->args[1];
- u32 skip_addr4 = cb->args[2];
- u32 skip_addr6 = cb->args[3];
u32 iter_bkt;
u32 iter_chain = 0, iter_addr4 = 0, iter_addr6 = 0;
struct netlbl_unlhsh_iface *iface;
@@ -1215,7 +1213,7 @@ static int netlbl_unlabel_staticlist(struct sk_buff *skb,
continue;
netlbl_af4list_foreach_rcu(addr4,
&iface->addr4_list) {
- if (iter_addr4++ < skip_addr4)
+ if (iter_addr4++ < cb->args[2])
continue;
if (netlbl_unlabel_staticlist_gen(
NLBL_UNLABEL_C_STATICLIST,
@@ -1231,7 +1229,7 @@ static int netlbl_unlabel_staticlist(struct sk_buff *skb,
#if IS_ENABLED(CONFIG_IPV6)
netlbl_af6list_foreach_rcu(addr6,
&iface->addr6_list) {
- if (iter_addr6++ < skip_addr6)
+ if (iter_addr6++ < cb->args[3])
continue;
if (netlbl_unlabel_staticlist_gen(
NLBL_UNLABEL_C_STATICLIST,
@@ -1250,10 +1248,10 @@ static int netlbl_unlabel_staticlist(struct sk_buff *skb,
unlabel_staticlist_return:
rcu_read_unlock();
- cb->args[0] = skip_bkt;
- cb->args[1] = skip_chain;
- cb->args[2] = skip_addr4;
- cb->args[3] = skip_addr6;
+ cb->args[0] = iter_bkt;
+ cb->args[1] = iter_chain;
+ cb->args[2] = iter_addr4;
+ cb->args[3] = iter_addr6;
return skb->len;
}
@@ -1273,12 +1271,9 @@ static int netlbl_unlabel_staticlistdef(struct sk_buff *skb,
{
struct netlbl_unlhsh_walk_arg cb_arg;
struct netlbl_unlhsh_iface *iface;
- u32 skip_addr4 = cb->args[0];
- u32 skip_addr6 = cb->args[1];
- u32 iter_addr4 = 0;
+ u32 iter_addr4 = 0, iter_addr6 = 0;
struct netlbl_af4list *addr4;
#if IS_ENABLED(CONFIG_IPV6)
- u32 iter_addr6 = 0;
struct netlbl_af6list *addr6;
#endif
@@ -1292,7 +1287,7 @@ static int netlbl_unlabel_staticlistdef(struct sk_buff *skb,
goto unlabel_staticlistdef_return;
netlbl_af4list_foreach_rcu(addr4, &iface->addr4_list) {
- if (iter_addr4++ < skip_addr4)
+ if (iter_addr4++ < cb->args[0])
continue;
if (netlbl_unlabel_staticlist_gen(NLBL_UNLABEL_C_STATICLISTDEF,
iface,
@@ -1305,7 +1300,7 @@ static int netlbl_unlabel_staticlistdef(struct sk_buff *skb,
}
#if IS_ENABLED(CONFIG_IPV6)
netlbl_af6list_foreach_rcu(addr6, &iface->addr6_list) {
- if (iter_addr6++ < skip_addr6)
+ if (iter_addr6++ < cb->args[1])
continue;
if (netlbl_unlabel_staticlist_gen(NLBL_UNLABEL_C_STATICLISTDEF,
iface,
@@ -1320,8 +1315,8 @@ static int netlbl_unlabel_staticlistdef(struct sk_buff *skb,
unlabel_staticlistdef_return:
rcu_read_unlock();
- cb->args[0] = skip_addr4;
- cb->args[1] = skip_addr6;
+ cb->args[0] = iter_addr4;
+ cb->args[1] = iter_addr6;
return skb->len;
}
diff --git a/net/rds/stats.c b/net/rds/stats.c
index 7be790d60b90..73be187d389e 100644
--- a/net/rds/stats.c
+++ b/net/rds/stats.c
@@ -87,6 +87,7 @@ void rds_stats_info_copy(struct rds_info_iterator *iter,
for (i = 0; i < nr; i++) {
BUG_ON(strlen(names[i]) >= sizeof(ctr.name));
strncpy(ctr.name, names[i], sizeof(ctr.name) - 1);
+ ctr.name[sizeof(ctr.name) - 1] = '\0';
ctr.value = values[i];
rds_info_copy(iter, &ctr, sizeof(ctr));
diff --git a/net/sched/sch_qfq.c b/net/sched/sch_qfq.c
index e9a77f621c3d..d51852bba01c 100644
--- a/net/sched/sch_qfq.c
+++ b/net/sched/sch_qfq.c
@@ -298,6 +298,10 @@ static void qfq_update_agg(struct qfq_sched *q, struct qfq_aggregate *agg,
new_num_classes == q->max_agg_classes - 1) /* agg no more full */
hlist_add_head(&agg->nonfull_next, &q->nonfull_aggs);
+ /* The next assignment may let
+ * agg->initial_budget > agg->budgetmax
+ * hold, we will take it into account in charge_actual_service().
+ */
agg->budgetmax = new_num_classes * agg->lmax;
new_agg_weight = agg->class_weight * new_num_classes;
agg->inv_w = ONE_FP/new_agg_weight;
@@ -817,7 +821,7 @@ static void qfq_make_eligible(struct qfq_sched *q)
unsigned long old_vslot = q->oldV >> q->min_slot_shift;
if (vslot != old_vslot) {
- unsigned long mask = (1UL << fls(vslot ^ old_vslot)) - 1;
+ unsigned long mask = (1ULL << fls(vslot ^ old_vslot)) - 1;
qfq_move_groups(q, mask, IR, ER);
qfq_move_groups(q, mask, IB, EB);
}
@@ -988,12 +992,23 @@ static inline struct sk_buff *qfq_peek_skb(struct qfq_aggregate *agg,
/* Update F according to the actual service received by the aggregate. */
static inline void charge_actual_service(struct qfq_aggregate *agg)
{
- /* compute the service received by the aggregate */
- u32 service_received = agg->initial_budget - agg->budget;
+ /* Compute the service received by the aggregate, taking into
+ * account that, after decreasing the number of classes in
+ * agg, it may happen that
+ * agg->initial_budget - agg->budget > agg->bugdetmax
+ */
+ u32 service_received = min(agg->budgetmax,
+ agg->initial_budget - agg->budget);
agg->F = agg->S + (u64)service_received * agg->inv_w;
}
+static inline void qfq_update_agg_ts(struct qfq_sched *q,
+ struct qfq_aggregate *agg,
+ enum update_reason reason);
+
+static void qfq_schedule_agg(struct qfq_sched *q, struct qfq_aggregate *agg);
+
static struct sk_buff *qfq_dequeue(struct Qdisc *sch)
{
struct qfq_sched *q = qdisc_priv(sch);
@@ -1021,7 +1036,7 @@ static struct sk_buff *qfq_dequeue(struct Qdisc *sch)
in_serv_agg->initial_budget = in_serv_agg->budget =
in_serv_agg->budgetmax;
- if (!list_empty(&in_serv_agg->active))
+ if (!list_empty(&in_serv_agg->active)) {
/*
* Still active: reschedule for
* service. Possible optimization: if no other
@@ -1032,8 +1047,9 @@ static struct sk_buff *qfq_dequeue(struct Qdisc *sch)
* handle it, we would need to maintain an
* extra num_active_aggs field.
*/
- qfq_activate_agg(q, in_serv_agg, requeue);
- else if (sch->q.qlen == 0) { /* no aggregate to serve */
+ qfq_update_agg_ts(q, in_serv_agg, requeue);
+ qfq_schedule_agg(q, in_serv_agg);
+ } else if (sch->q.qlen == 0) { /* no aggregate to serve */
q->in_serv_agg = NULL;
return NULL;
}
@@ -1052,7 +1068,15 @@ static struct sk_buff *qfq_dequeue(struct Qdisc *sch)
qdisc_bstats_update(sch, skb);
agg_dequeue(in_serv_agg, cl, len);
- in_serv_agg->budget -= len;
+ /* If lmax is lowered, through qfq_change_class, for a class
+ * owning pending packets with larger size than the new value
+ * of lmax, then the following condition may hold.
+ */
+ if (unlikely(in_serv_agg->budget < len))
+ in_serv_agg->budget = 0;
+ else
+ in_serv_agg->budget -= len;
+
q->V += (u64)len * IWSUM;
pr_debug("qfq dequeue: len %u F %lld now %lld\n",
len, (unsigned long long) in_serv_agg->F,
@@ -1217,17 +1241,11 @@ static int qfq_enqueue(struct sk_buff *skb, struct Qdisc *sch)
cl->deficit = agg->lmax;
list_add_tail(&cl->alist, &agg->active);
- if (list_first_entry(&agg->active, struct qfq_class, alist) != cl)
- return err; /* aggregate was not empty, nothing else to do */
+ if (list_first_entry(&agg->active, struct qfq_class, alist) != cl ||
+ q->in_serv_agg == agg)
+ return err; /* non-empty or in service, nothing else to do */
- /* recharge budget */
- agg->initial_budget = agg->budget = agg->budgetmax;
-
- qfq_update_agg_ts(q, agg, enqueue);
- if (q->in_serv_agg == NULL)
- q->in_serv_agg = agg;
- else if (agg != q->in_serv_agg)
- qfq_schedule_agg(q, agg);
+ qfq_activate_agg(q, agg, enqueue);
return err;
}
@@ -1261,7 +1279,8 @@ static void qfq_schedule_agg(struct qfq_sched *q, struct qfq_aggregate *agg)
/* group was surely ineligible, remove */
__clear_bit(grp->index, &q->bitmaps[IR]);
__clear_bit(grp->index, &q->bitmaps[IB]);
- } else if (!q->bitmaps[ER] && qfq_gt(roundedS, q->V))
+ } else if (!q->bitmaps[ER] && qfq_gt(roundedS, q->V) &&
+ q->in_serv_agg == NULL)
q->V = roundedS;
grp->S = roundedS;
@@ -1284,8 +1303,15 @@ skip_update:
static void qfq_activate_agg(struct qfq_sched *q, struct qfq_aggregate *agg,
enum update_reason reason)
{
+ agg->initial_budget = agg->budget = agg->budgetmax; /* recharge budg. */
+
qfq_update_agg_ts(q, agg, reason);
- qfq_schedule_agg(q, agg);
+ if (q->in_serv_agg == NULL) { /* no aggr. in service or scheduled */
+ q->in_serv_agg = agg; /* start serving this aggregate */
+ /* update V: to be in service, agg must be eligible */
+ q->oldV = q->V = agg->S;
+ } else if (agg != q->in_serv_agg)
+ qfq_schedule_agg(q, agg);
}
static void qfq_slot_remove(struct qfq_sched *q, struct qfq_group *grp,
@@ -1357,8 +1383,6 @@ static void qfq_deactivate_agg(struct qfq_sched *q, struct qfq_aggregate *agg)
__set_bit(grp->index, &q->bitmaps[s]);
}
}
-
- qfq_update_eligible(q);
}
static void qfq_qlen_notify(struct Qdisc *sch, unsigned long arg)
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c
index f7d34e7b6f81..5ead60550895 100644
--- a/net/sunrpc/auth_gss/svcauth_gss.c
+++ b/net/sunrpc/auth_gss/svcauth_gss.c
@@ -447,17 +447,21 @@ static int rsc_parse(struct cache_detail *cd,
else {
int N, i;
+ /*
+ * NOTE: we skip uid_valid()/gid_valid() checks here:
+ * instead, * -1 id's are later mapped to the
+ * (export-specific) anonymous id by nfsd_setuser.
+ *
+ * (But supplementary gid's get no such special
+ * treatment so are checked for validity here.)
+ */
/* uid */
rsci.cred.cr_uid = make_kuid(&init_user_ns, id);
- if (!uid_valid(rsci.cred.cr_uid))
- goto out;
/* gid */
if (get_int(&mesg, &id))
goto out;
rsci.cred.cr_gid = make_kgid(&init_user_ns, id);
- if (!gid_valid(rsci.cred.cr_gid))
- goto out;
/* number of additional gid's */
if (get_int(&mesg, &N))
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
index a0f48a51e14e..a9129f8d7070 100644
--- a/net/sunrpc/rpc_pipe.c
+++ b/net/sunrpc/rpc_pipe.c
@@ -1175,6 +1175,7 @@ static struct file_system_type rpc_pipe_fs_type = {
.kill_sb = rpc_kill_sb,
};
MODULE_ALIAS_FS("rpc_pipefs");
+MODULE_ALIAS("rpc_pipefs");
static void
init_once(void *foo)
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index c1d8476b7692..3d02130828da 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -849,6 +849,14 @@ static void xs_tcp_close(struct rpc_xprt *xprt)
xs_tcp_shutdown(xprt);
}
+static void xs_local_destroy(struct rpc_xprt *xprt)
+{
+ xs_close(xprt);
+ xs_free_peer_addresses(xprt);
+ xprt_free(xprt);
+ module_put(THIS_MODULE);
+}
+
/**
* xs_destroy - prepare to shutdown a transport
* @xprt: doomed transport
@@ -862,10 +870,7 @@ static void xs_destroy(struct rpc_xprt *xprt)
cancel_delayed_work_sync(&transport->connect_worker);
- xs_close(xprt);
- xs_free_peer_addresses(xprt);
- xprt_free(xprt);
- module_put(THIS_MODULE);
+ xs_local_destroy(xprt);
}
static inline struct rpc_xprt *xprt_from_sock(struct sock *sk)
@@ -2482,7 +2487,7 @@ static struct rpc_xprt_ops xs_local_ops = {
.send_request = xs_local_send_request,
.set_retrans_timeout = xprt_set_retrans_timeout_def,
.close = xs_close,
- .destroy = xs_destroy,
+ .destroy = xs_local_destroy,
.print_stats = xs_local_print_stats,
};
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 5ffff039b017..ea4155fe9733 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -367,8 +367,7 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv)
rdev->wiphy.rts_threshold = (u32) -1;
rdev->wiphy.coverage_class = 0;
- rdev->wiphy.features = NL80211_FEATURE_SCAN_FLUSH |
- NL80211_FEATURE_ADVERTISE_CHAN_LIMITS;
+ rdev->wiphy.features = NL80211_FEATURE_SCAN_FLUSH;
return &rdev->wiphy;
}
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index e652d05ff712..d44ab216c0ec 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -557,18 +557,6 @@ static int nl80211_msg_put_channel(struct sk_buff *msg,
if ((chan->flags & IEEE80211_CHAN_RADAR) &&
nla_put_flag(msg, NL80211_FREQUENCY_ATTR_RADAR))
goto nla_put_failure;
- if ((chan->flags & IEEE80211_CHAN_NO_HT40MINUS) &&
- nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_HT40_MINUS))
- goto nla_put_failure;
- if ((chan->flags & IEEE80211_CHAN_NO_HT40PLUS) &&
- nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_HT40_PLUS))
- goto nla_put_failure;
- if ((chan->flags & IEEE80211_CHAN_NO_80MHZ) &&
- nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_80MHZ))
- goto nla_put_failure;
- if ((chan->flags & IEEE80211_CHAN_NO_160MHZ) &&
- nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_160MHZ))
- goto nla_put_failure;
if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_MAX_TX_POWER,
DBM_TO_MBM(chan->max_power)))
@@ -1310,15 +1298,6 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 portid, u32 seq, int flag
dev->wiphy.max_acl_mac_addrs))
goto nla_put_failure;
- if (dev->wiphy.extended_capabilities &&
- (nla_put(msg, NL80211_ATTR_EXT_CAPA,
- dev->wiphy.extended_capabilities_len,
- dev->wiphy.extended_capabilities) ||
- nla_put(msg, NL80211_ATTR_EXT_CAPA_MASK,
- dev->wiphy.extended_capabilities_len,
- dev->wiphy.extended_capabilities_mask)))
- goto nla_put_failure;
-
return genlmsg_end(msg, hdr);
nla_put_failure:
@@ -1328,7 +1307,7 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 portid, u32 seq, int flag
static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
{
- int idx = 0;
+ int idx = 0, ret;
int start = cb->args[0];
struct cfg80211_registered_device *dev;
@@ -1338,9 +1317,29 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
continue;
if (++idx <= start)
continue;
- if (nl80211_send_wiphy(skb, NETLINK_CB(cb->skb).portid,
- cb->nlh->nlmsg_seq, NLM_F_MULTI,
- dev) < 0) {
+ ret = nl80211_send_wiphy(skb, NETLINK_CB(cb->skb).portid,
+ cb->nlh->nlmsg_seq, NLM_F_MULTI,
+ dev);
+ if (ret < 0) {
+ /*
+ * If sending the wiphy data didn't fit (ENOBUFS or
+ * EMSGSIZE returned), this SKB is still empty (so
+ * it's not too big because another wiphy dataset is
+ * already in the skb) and we've not tried to adjust
+ * the dump allocation yet ... then adjust the alloc
+ * size to be bigger, and return 1 but with the empty
+ * skb. This results in an empty message being RX'ed
+ * in userspace, but that is ignored.
+ *
+ * We can then retry with the larger buffer.
+ */
+ if ((ret == -ENOBUFS || ret == -EMSGSIZE) &&
+ !skb->len &&
+ cb->min_dump_alloc < 4096) {
+ cb->min_dump_alloc = 4096;
+ mutex_unlock(&cfg80211_mutex);
+ return 1;
+ }
idx--;
break;
}
@@ -1357,7 +1356,7 @@ static int nl80211_get_wiphy(struct sk_buff *skb, struct genl_info *info)
struct sk_buff *msg;
struct cfg80211_registered_device *dev = info->user_ptr[0];
- msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
+ msg = nlmsg_new(4096, GFP_KERNEL);
if (!msg)
return -ENOMEM;
diff --git a/scripts/Makefile.headersinst b/scripts/Makefile.headersinst
index 25f216a841d5..477d137c0557 100644
--- a/scripts/Makefile.headersinst
+++ b/scripts/Makefile.headersinst
@@ -14,7 +14,7 @@ kbuild-file := $(srctree)/$(obj)/Kbuild
include $(kbuild-file)
# called may set destination dir (when installing to asm/)
-_dst := $(or $(destination-y),$(dst),$(obj))
+_dst := $(if $(destination-y),$(destination-y),$(if $(dst),$(dst),$(obj)))
old-kbuild-file := $(srctree)/$(subst uapi/,,$(obj))/Kbuild
ifneq ($(wildcard $(old-kbuild-file)),)
@@ -48,13 +48,14 @@ all-files := $(header-y) $(genhdr-y) $(wrapper-files)
output-files := $(addprefix $(installdir)/, $(all-files))
input-files := $(foreach hdr, $(header-y), \
- $(or \
+ $(if $(wildcard $(srcdir)/$(hdr)), \
$(wildcard $(srcdir)/$(hdr)), \
- $(wildcard $(oldsrcdir)/$(hdr)), \
- $(error Missing UAPI file $(srcdir)/$(hdr)) \
+ $(if $(wildcard $(oldsrcdir)/$(hdr)), \
+ $(wildcard $(oldsrcdir)/$(hdr)), \
+ $(error Missing UAPI file $(srcdir)/$(hdr))) \
)) \
$(foreach hdr, $(genhdr-y), \
- $(or \
+ $(if $(wildcard $(gendir)/$(hdr)), \
$(wildcard $(gendir)/$(hdr)), \
$(error Missing generated UAPI file $(gendir)/$(hdr)) \
))
diff --git a/security/keys/compat.c b/security/keys/compat.c
index 1c261763f479..d65fa7fa29ba 100644
--- a/security/keys/compat.c
+++ b/security/keys/compat.c
@@ -40,12 +40,12 @@ static long compat_keyctl_instantiate_key_iov(
ARRAY_SIZE(iovstack),
iovstack, &iov);
if (ret < 0)
- return ret;
+ goto err;
if (ret == 0)
goto no_payload_free;
ret = keyctl_instantiate_key_common(id, iov, ioc, ret, ringid);
-
+err:
if (iov != iovstack)
kfree(iov);
return ret;
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
index a571fad91010..42defae1e161 100644
--- a/security/keys/process_keys.c
+++ b/security/keys/process_keys.c
@@ -57,7 +57,7 @@ int install_user_keyrings(void)
kenter("%p{%u}", user, uid);
- if (user->uid_keyring) {
+ if (user->uid_keyring && user->session_keyring) {
kleave(" = 0 [exist]");
return 0;
}
diff --git a/sound/core/seq/seq_timer.c b/sound/core/seq/seq_timer.c
index 160b1bd0cd62..24d44b2f61ac 100644
--- a/sound/core/seq/seq_timer.c
+++ b/sound/core/seq/seq_timer.c
@@ -290,10 +290,10 @@ int snd_seq_timer_open(struct snd_seq_queue *q)
tid.device = SNDRV_TIMER_GLOBAL_SYSTEM;
err = snd_timer_open(&t, str, &tid, q->queue);
}
- if (err < 0) {
- snd_printk(KERN_ERR "seq fatal error: cannot create timer (%i)\n", err);
- return err;
- }
+ }
+ if (err < 0) {
+ snd_printk(KERN_ERR "seq fatal error: cannot create timer (%i)\n", err);
+ return err;
}
t->callback = snd_seq_timer_interrupt;
t->callback_data = q;
diff --git a/sound/oss/sequencer.c b/sound/oss/sequencer.c
index 30bcfe470f83..4ff60a6427d9 100644
--- a/sound/oss/sequencer.c
+++ b/sound/oss/sequencer.c
@@ -545,6 +545,9 @@ static void seq_chn_common_event(unsigned char *event_rec)
case MIDI_PGM_CHANGE:
if (seq_mode == SEQ_2)
{
+ if (chn > 15)
+ break;
+
synth_devs[dev]->chn_info[chn].pgm_num = p1;
if ((int) dev >= num_synths)
synth_devs[dev]->set_instr(dev, chn, p1);
@@ -596,6 +599,9 @@ static void seq_chn_common_event(unsigned char *event_rec)
case MIDI_PITCH_BEND:
if (seq_mode == SEQ_2)
{
+ if (chn > 15)
+ break;
+
synth_devs[dev]->chn_info[chn].bender_value = w14;
if ((int) dev < num_synths)
diff --git a/sound/pci/asihpi/asihpi.c b/sound/pci/asihpi/asihpi.c
index 3536b076b529..0aabfedeecba 100644
--- a/sound/pci/asihpi/asihpi.c
+++ b/sound/pci/asihpi/asihpi.c
@@ -2549,7 +2549,7 @@ static int snd_asihpi_sampleclock_add(struct snd_card_asihpi *asihpi,
static int snd_card_asihpi_mixer_new(struct snd_card_asihpi *asihpi)
{
- struct snd_card *card = asihpi->card;
+ struct snd_card *card;
unsigned int idx = 0;
unsigned int subindex = 0;
int err;
@@ -2557,6 +2557,7 @@ static int snd_card_asihpi_mixer_new(struct snd_card_asihpi *asihpi)
if (snd_BUG_ON(!asihpi))
return -EINVAL;
+ card = asihpi->card;
strcpy(card->mixername, "Asihpi Mixer");
err =
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 97c68dd24ef5..a9ebcf9e3710 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -494,7 +494,7 @@ static unsigned int get_num_conns(struct hda_codec *codec, hda_nid_t nid)
int snd_hda_get_num_raw_conns(struct hda_codec *codec, hda_nid_t nid)
{
- return get_num_conns(codec, nid) & AC_CLIST_LENGTH;
+ return snd_hda_get_raw_connections(codec, nid, NULL, 0);
}
/**
@@ -517,9 +517,6 @@ int snd_hda_get_raw_connections(struct hda_codec *codec, hda_nid_t nid,
hda_nid_t prev_nid;
int null_count = 0;
- if (snd_BUG_ON(!conn_list || max_conns <= 0))
- return -EINVAL;
-
parm = get_num_conns(codec, nid);
if (!parm)
return 0;
@@ -545,7 +542,8 @@ int snd_hda_get_raw_connections(struct hda_codec *codec, hda_nid_t nid,
AC_VERB_GET_CONNECT_LIST, 0);
if (parm == -1 && codec->bus->rirb_error)
return -EIO;
- conn_list[0] = parm & mask;
+ if (conn_list)
+ conn_list[0] = parm & mask;
return 1;
}
@@ -580,14 +578,20 @@ int snd_hda_get_raw_connections(struct hda_codec *codec, hda_nid_t nid,
continue;
}
for (n = prev_nid + 1; n <= val; n++) {
+ if (conn_list) {
+ if (conns >= max_conns)
+ return -ENOSPC;
+ conn_list[conns] = n;
+ }
+ conns++;
+ }
+ } else {
+ if (conn_list) {
if (conns >= max_conns)
return -ENOSPC;
- conn_list[conns++] = n;
+ conn_list[conns] = val;
}
- } else {
- if (conns >= max_conns)
- return -ENOSPC;
- conn_list[conns++] = val;
+ conns++;
}
prev_nid = val;
}
diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index eefc4563b2f9..0792b5725f9c 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -3239,7 +3239,7 @@ static int ca0132_set_vipsource(struct hda_codec *codec, int val)
struct ca0132_spec *spec = codec->spec;
unsigned int tmp;
- if (!dspload_is_loaded(codec))
+ if (spec->dsp_state != DSP_DOWNLOADED)
return 0;
/* if CrystalVoice if off, vipsource should be 0 */
@@ -4267,11 +4267,12 @@ static void ca0132_refresh_widget_caps(struct hda_codec *codec)
*/
static void ca0132_setup_defaults(struct hda_codec *codec)
{
+ struct ca0132_spec *spec = codec->spec;
unsigned int tmp;
int num_fx;
int idx, i;
- if (!dspload_is_loaded(codec))
+ if (spec->dsp_state != DSP_DOWNLOADED)
return;
/* out, in effects + voicefx */
@@ -4351,12 +4352,16 @@ static bool ca0132_download_dsp_images(struct hda_codec *codec)
return false;
dsp_os_image = (struct dsp_image_seg *)(fw_entry->data);
- dspload_image(codec, dsp_os_image, 0, 0, true, 0);
+ if (dspload_image(codec, dsp_os_image, 0, 0, true, 0)) {
+ pr_err("ca0132 dspload_image failed.\n");
+ goto exit_download;
+ }
+
dsp_loaded = dspload_wait_loaded(codec);
+exit_download:
release_firmware(fw_entry);
-
return dsp_loaded;
}
@@ -4367,16 +4372,13 @@ static void ca0132_download_dsp(struct hda_codec *codec)
#ifndef CONFIG_SND_HDA_CODEC_CA0132_DSP
return; /* NOP */
#endif
- spec->dsp_state = DSP_DOWNLOAD_INIT;
- if (spec->dsp_state == DSP_DOWNLOAD_INIT) {
- chipio_enable_clocks(codec);
- spec->dsp_state = DSP_DOWNLOADING;
- if (!ca0132_download_dsp_images(codec))
- spec->dsp_state = DSP_DOWNLOAD_FAILED;
- else
- spec->dsp_state = DSP_DOWNLOADED;
- }
+ chipio_enable_clocks(codec);
+ spec->dsp_state = DSP_DOWNLOADING;
+ if (!ca0132_download_dsp_images(codec))
+ spec->dsp_state = DSP_DOWNLOAD_FAILED;
+ else
+ spec->dsp_state = DSP_DOWNLOADED;
if (spec->dsp_state == DSP_DOWNLOADED)
ca0132_set_dsp_msr(codec, true);
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c
index 72ebb8a36b13..60d08f669f0c 100644
--- a/sound/pci/hda/patch_cirrus.c
+++ b/sound/pci/hda/patch_cirrus.c
@@ -506,6 +506,8 @@ static int patch_cs420x(struct hda_codec *codec)
if (!spec)
return -ENOMEM;
+ spec->gen.automute_hook = cs_automute;
+
snd_hda_pick_fixup(codec, cs420x_models, cs420x_fixup_tbl,
cs420x_fixups);
snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
@@ -893,6 +895,8 @@ static int patch_cs4210(struct hda_codec *codec)
if (!spec)
return -ENOMEM;
+ spec->gen.automute_hook = cs_automute;
+
snd_hda_pick_fixup(codec, cs421x_models, cs421x_fixup_tbl,
cs421x_fixups);
snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 83d5335ac348..dafe04ae8c72 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -815,6 +815,29 @@ static int find_mute_led_cfg(struct hda_codec *codec, int default_polarity)
return 0;
}
+/* check whether a built-in speaker is included in parsed pins */
+static bool has_builtin_speaker(struct hda_codec *codec)
+{
+ struct sigmatel_spec *spec = codec->spec;
+ hda_nid_t *nid_pin;
+ int nids, i;
+
+ if (spec->gen.autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT) {
+ nid_pin = spec->gen.autocfg.line_out_pins;
+ nids = spec->gen.autocfg.line_outs;
+ } else {
+ nid_pin = spec->gen.autocfg.speaker_pins;
+ nids = spec->gen.autocfg.speaker_outs;
+ }
+
+ for (i = 0; i < nids; i++) {
+ unsigned int def_conf = snd_hda_codec_get_pincfg(codec, nid_pin[i]);
+ if (snd_hda_get_input_pin_attr(def_conf) == INPUT_PIN_ATTR_INT)
+ return true;
+ }
+ return false;
+}
+
/*
* PC beep controls
*/
@@ -3890,6 +3913,12 @@ static int patch_stac92hd73xx(struct hda_codec *codec)
return err;
}
+ /* Don't GPIO-mute speakers if there are no internal speakers, because
+ * the GPIO might be necessary for Headphone
+ */
+ if (spec->eapd_switch && !has_builtin_speaker(codec))
+ spec->eapd_switch = 0;
+
codec->proc_widget_hook = stac92hd7x_proc_hook;
snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
diff --git a/sound/usb/card.c b/sound/usb/card.c
index 803953a9bff3..2da8ad75fd96 100644
--- a/sound/usb/card.c
+++ b/sound/usb/card.c
@@ -244,6 +244,21 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif)
usb_ifnum_to_if(dev, ctrlif)->intf_assoc;
if (!assoc) {
+ /*
+ * Firmware writers cannot count to three. So to find
+ * the IAD on the NuForce UDH-100, also check the next
+ * interface.
+ */
+ struct usb_interface *iface =
+ usb_ifnum_to_if(dev, ctrlif + 1);
+ if (iface &&
+ iface->intf_assoc &&
+ iface->intf_assoc->bFunctionClass == USB_CLASS_AUDIO &&
+ iface->intf_assoc->bFunctionProtocol == UAC_VERSION_2)
+ assoc = iface->intf_assoc;
+ }
+
+ if (!assoc) {
snd_printk(KERN_ERR "Audio class v2 interfaces need an interface association\n");
return -EINVAL;
}
diff --git a/tools/usb/ffs-test.c b/tools/usb/ffs-test.c
index 8674b9ec14f6..fe1e66b6ef40 100644
--- a/tools/usb/ffs-test.c
+++ b/tools/usb/ffs-test.c
@@ -38,7 +38,7 @@
#include <unistd.h>
#include <tools/le_byteshift.h>
-#include "../../include/linux/usb/functionfs.h"
+#include "../../include/uapi/linux/usb/functionfs.h"
/******************** Little Endian Handling ********************************/