summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/acpi/acpica/hwxface.c3
-rw-r--r--drivers/acpi/ec_sys.c8
-rw-r--r--drivers/acpi/osl.c3
-rw-r--r--drivers/acpi/processor_idle.c2
-rw-r--r--drivers/acpi/reboot.c3
-rw-r--r--drivers/acpi/sleep.c52
-rw-r--r--drivers/amba/bus.c42
-rw-r--r--drivers/ata/ata_piix.c2
-rw-r--r--drivers/ata/libata-core.c4
-rw-r--r--drivers/ata/libata-scsi.c4
-rw-r--r--drivers/ata/libata-transport.c1
-rw-r--r--drivers/ata/libata.h2
-rw-r--r--drivers/ata/sata_mv.c3
-rw-r--r--drivers/base/regmap/regcache-rbtree.c8
-rw-r--r--drivers/base/regmap/regcache.c1
-rw-r--r--drivers/base/regmap/regmap-debugfs.c12
-rw-r--r--drivers/base/soc.c4
-rw-r--r--drivers/bcma/Kconfig2
-rw-r--r--drivers/bcma/driver_pci_host.c1
-rw-r--r--drivers/bcma/sprom.c7
-rw-r--r--drivers/block/cciss_scsi.c3
-rw-r--r--drivers/block/mtip32xx/Kconfig2
-rw-r--r--drivers/block/mtip32xx/mtip32xx.c860
-rw-r--r--drivers/block/mtip32xx/mtip32xx.h58
-rw-r--r--drivers/block/virtio_blk.c42
-rw-r--r--drivers/block/xen-blkback/blkback.c50
-rw-r--r--drivers/block/xen-blkback/common.h6
-rw-r--r--drivers/block/xen-blkback/xenbus.c89
-rw-r--r--drivers/block/xen-blkfront.c43
-rw-r--r--drivers/bluetooth/ath3k.c4
-rw-r--r--drivers/bluetooth/btmrvl_debugfs.c26
-rw-r--r--drivers/bluetooth/btusb.c5
-rw-r--r--drivers/bluetooth/hci_ldisc.c2
-rw-r--r--drivers/char/apm-emulation.c2
-rw-r--r--drivers/char/hpet.c4
-rw-r--r--drivers/char/random.c11
-rw-r--r--drivers/char/tile-srom.c12
-rw-r--r--drivers/char/virtio_console.c8
-rw-r--r--drivers/clocksource/acpi_pm.c24
-rw-r--r--drivers/cpufreq/Kconfig.arm11
-rw-r--r--drivers/cpuidle/cpuidle.c5
-rw-r--r--drivers/crypto/ixp4xx_crypto.c1
-rw-r--r--drivers/crypto/talitos.c20
-rw-r--r--drivers/dma/Kconfig5
-rw-r--r--drivers/dma/coh901318.c9
-rw-r--r--drivers/dma/dmaengine.c14
-rw-r--r--drivers/dma/ioat/dma.c16
-rw-r--r--drivers/dma/ioat/dma.h6
-rw-r--r--drivers/dma/ioat/dma_v2.c12
-rw-r--r--drivers/dma/ioat/dma_v2.h4
-rw-r--r--drivers/dma/ioat/dma_v3.c49
-rw-r--r--drivers/dma/iop-adma.c4
-rw-r--r--drivers/edac/tile_edac.c4
-rw-r--r--drivers/gpio/Kconfig2
-rw-r--r--drivers/gpio/gpio-adp5588.c2
-rw-r--r--drivers/gpio/gpio-samsung.c16
-rw-r--r--drivers/gpio/gpio-sodaville.c23
-rw-r--r--drivers/gpio/gpio-tegra.c59
-rw-r--r--drivers/gpu/drm/drm_bufs.c12
-rw-r--r--drivers/gpu/drm/drm_crtc.c10
-rw-r--r--drivers/gpu/drm/drm_fops.c6
-rw-r--r--drivers/gpu/drm/drm_usb.c6
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_buf.c47
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_core.c14
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_drv.h10
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_fimd.c20
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_gem.c49
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_gem.h2
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_hdmi.c107
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_hdmi.h23
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_plane.c4
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_vidi.c20
-rw-r--r--drivers/gpu/drm/exynos/exynos_hdmi.c42
-rw-r--r--drivers/gpu/drm/exynos/exynos_mixer.c40
-rw-r--r--drivers/gpu/drm/gma500/mdfld_dsi_output.h1
-rw-r--r--drivers/gpu/drm/i810/i810_dma.c6
-rw-r--r--drivers/gpu/drm/i915/i915_debugfs.c14
-rw-r--r--drivers/gpu/drm/i915/i915_drv.c2
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c6
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h3
-rw-r--r--drivers/gpu/drm/i915/intel_display.c84
-rw-r--r--drivers/gpu/drm/i915/intel_dp.c49
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h4
-rw-r--r--drivers/gpu/drm/i915/intel_fb.c4
-rw-r--r--drivers/gpu/drm/i915/intel_i2c.c2
-rw-r--r--drivers/gpu/drm/i915/intel_lvds.c6
-rw-r--r--drivers/gpu/drm/i915/intel_panel.c2
-rw-r--r--drivers/gpu/drm/i915/intel_ringbuffer.c2
-rw-r--r--drivers/gpu/drm/i915/intel_sprite.c1
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_pm.c1
-rw-r--r--drivers/gpu/drm/nouveau/nv50_sor.c2
-rw-r--r--drivers/gpu/drm/radeon/atombios_encoders.c4
-rw-r--r--drivers/gpu/drm/radeon/r100.c2
-rw-r--r--drivers/gpu/drm/radeon/r600.c6
-rw-r--r--drivers/gpu/drm/radeon/r600_cp.c6
-rw-r--r--drivers/gpu/drm/radeon/radeon_clocks.c24
-rw-r--r--drivers/gpu/drm/radeon/radeon_combios.c8
-rw-r--r--drivers/gpu/drm/radeon/radeon_connectors.c4
-rw-r--r--drivers/gpu/drm/radeon/radeon_i2c.c4
-rw-r--r--drivers/gpu/drm/radeon/radeon_irq_kms.c6
-rw-r--r--drivers/gpu/drm/radeon/radeon_legacy_encoders.c12
-rw-r--r--drivers/gpu/drm/radeon/rv770.c4
-rw-r--r--drivers/gpu/drm/radeon/si.c5
-rw-r--r--drivers/gpu/drm/savage/savage_state.c6
-rw-r--r--drivers/hid/Kconfig2
-rw-r--r--drivers/hid/hid-picolcd.c16
-rw-r--r--drivers/hid/hid-tivo.c2
-rw-r--r--drivers/hid/hid-wiimote-debug.c8
-rw-r--r--drivers/hsi/clients/hsi_char.c2
-rw-r--r--drivers/hsi/hsi.c223
-rw-r--r--drivers/hwmon/acpi_power_meter.c1
-rw-r--r--drivers/hwmon/ads1015.c33
-rw-r--r--drivers/hwmon/fam15h_power.c39
-rw-r--r--drivers/hwmon/pmbus/pmbus_core.c17
-rw-r--r--drivers/hwmon/smsc47b397.c14
-rw-r--r--drivers/hwmon/smsc47m1.c19
-rw-r--r--drivers/i2c/busses/i2c-designware-pcidrv.c1
-rw-r--r--drivers/idle/i7300_idle.c8
-rw-r--r--drivers/infiniband/core/sysfs.c9
-rw-r--r--drivers/infiniband/hw/mlx4/main.c5
-rw-r--r--drivers/infiniband/ulp/srpt/ib_srpt.c1
-rw-r--r--drivers/input/misc/Kconfig3
-rw-r--r--drivers/input/misc/da9052_onkey.c3
-rw-r--r--drivers/input/misc/twl6040-vibra.c4
-rw-r--r--drivers/input/mouse/elantech.c10
-rw-r--r--drivers/input/mouse/gpio_mouse.c2
-rw-r--r--drivers/input/mouse/sentelic.c8
-rw-r--r--drivers/input/mouse/trackpoint.c14
-rw-r--r--drivers/input/touchscreen/tps6507x-ts.c4
-rw-r--r--drivers/iommu/omap-iommu-debug.c10
-rw-r--r--drivers/isdn/gigaset/interface.c2
-rw-r--r--drivers/leds/leds-atmel-pwm.c2
-rw-r--r--drivers/md/bitmap.c5
-rw-r--r--drivers/md/dm-raid.c4
-rw-r--r--drivers/md/md.c7
-rw-r--r--drivers/md/raid1.c3
-rw-r--r--drivers/md/raid10.c4
-rw-r--r--drivers/media/common/tuners/xc5000.c39
-rw-r--r--drivers/media/common/tuners/xc5000.h1
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.c37
-rw-r--r--drivers/media/dvb/dvb-usb/it913x.c54
-rw-r--r--drivers/media/dvb/frontends/drxk_hard.c6
-rw-r--r--drivers/media/rc/winbond-cir.c1
-rw-r--r--drivers/media/video/Kconfig2
-rw-r--r--drivers/media/video/ivtv/ivtv-ioctl.c4
-rw-r--r--drivers/media/video/mt9m032.c5
-rw-r--r--drivers/media/video/uvc/uvc_video.c50
-rw-r--r--drivers/mfd/Kconfig11
-rw-r--r--drivers/mfd/aat2870-core.c9
-rw-r--r--drivers/mfd/ab3100-core.c8
-rw-r--r--drivers/mfd/asic3.c4
-rw-r--r--drivers/mfd/db8500-prcmu.c1
-rw-r--r--drivers/mfd/omap-usb-host.c44
-rw-r--r--drivers/mfd/rc5t583.c39
-rw-r--r--drivers/mfd/twl6040-core.c114
-rw-r--r--drivers/misc/ibmasm/ibmasmfs.c8
-rw-r--r--drivers/mmc/card/block.c83
-rw-r--r--drivers/mmc/card/queue.c2
-rw-r--r--drivers/mmc/core/bus.c41
-rw-r--r--drivers/mmc/core/cd-gpio.c1
-rw-r--r--drivers/mmc/core/core.c74
-rw-r--r--drivers/mmc/core/mmc.c30
-rw-r--r--drivers/mmc/core/sdio_bus.c12
-rw-r--r--drivers/mmc/host/atmel-mci-regs.h1
-rw-r--r--drivers/mmc/host/atmel-mci.c55
-rw-r--r--drivers/mmc/host/dw_mmc.c7
-rw-r--r--drivers/mmc/host/omap_hsmmc.c187
-rw-r--r--drivers/mmc/host/sdhci-dove.c1
-rw-r--r--drivers/mmc/host/sdhci-esdhc-imx.c3
-rw-r--r--drivers/mmc/host/sdhci-pci.c6
-rw-r--r--drivers/mmc/host/sdhci-s3c.c159
-rw-r--r--drivers/mmc/host/sdhci.c7
-rw-r--r--drivers/mmc/host/sh_mmcif.c13
-rw-r--r--drivers/mtd/mtdchar.c20
-rw-r--r--drivers/mtd/ubi/debug.c10
-rw-r--r--drivers/net/arcnet/arc-rimi.c8
-rw-r--r--drivers/net/bonding/bond_main.c60
-rw-r--r--drivers/net/caif/caif_hsi.c9
-rw-r--r--drivers/net/caif/caif_spi.c10
-rw-r--r--drivers/net/can/usb/peak_usb/pcan_usb_pro.c2
-rw-r--r--drivers/net/dummy.c6
-rw-r--r--drivers/net/ethernet/atheros/atlx/atl1.c12
-rw-r--r--drivers/net/ethernet/atheros/atlx/atl1.h3
-rw-r--r--drivers/net/ethernet/atheros/atlx/atlx.c2
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c1
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_fw_defs.h110
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c159
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h8
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c9
-rw-r--r--drivers/net/ethernet/intel/e1000e/e1000.h6
-rw-r--r--drivers/net/ethernet/intel/e1000e/ich8lan.c15
-rw-r--r--drivers/net/ethernet/intel/e1000e/netdev.c26
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c164
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c10
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_main.c20
-rw-r--r--drivers/net/ethernet/marvell/sky2.c13
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mlx4_en.h5
-rw-r--r--drivers/net/ethernet/micrel/ks8851.c21
-rw-r--r--drivers/net/ethernet/micrel/ks8851_mll.c2
-rw-r--r--drivers/net/ethernet/micrel/ksz884x.c2
-rw-r--r--drivers/net/ethernet/realtek/8139cp.c10
-rw-r--r--drivers/net/ethernet/realtek/r8169.c3
-rw-r--r--drivers/net/ethernet/smsc/smsc911x.c17
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_main.c6
-rw-r--r--drivers/net/ethernet/ti/davinci_mdio.c5
-rw-r--r--drivers/net/ethernet/tile/tilepro.c77
-rw-r--r--drivers/net/ethernet/xilinx/xilinx_axienet.h4
-rw-r--r--drivers/net/ethernet/xilinx/xilinx_axienet_main.c6
-rw-r--r--drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c6
-rw-r--r--drivers/net/hyperv/netvsc_drv.c38
-rw-r--r--drivers/net/phy/icplus.c15
-rw-r--r--drivers/net/ppp/ppp_generic.c3
-rw-r--r--drivers/net/usb/qmi_wwan.c30
-rw-r--r--drivers/net/usb/smsc75xx.c1
-rw-r--r--drivers/net/virtio_net.c5
-rw-r--r--drivers/net/wan/farsync.c1
-rw-r--r--drivers/net/wimax/i2400m/debugfs.c15
-rw-r--r--drivers/net/wireless/ath/ath5k/ahb.c7
-rw-r--r--drivers/net/wireless/ath/ath5k/debug.c23
-rw-r--r--drivers/net/wireless/ath/ath6kl/debug.c42
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.c37
-rw-r--r--drivers/net/wireless/ath/ath9k/dfs_debug.c9
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_debug.c26
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c17
-rw-r--r--drivers/net/wireless/ath/ath9k/rc.c8
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c10
-rw-r--r--drivers/net/wireless/ath/carl9170/debug.c7
-rw-r--r--drivers/net/wireless/b43/debugfs.c8
-rw-r--r--drivers/net/wireless/b43legacy/debugfs.c8
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/main.c8
-rw-r--r--drivers/net/wireless/iwlegacy/3945-rs.c8
-rw-r--r--drivers/net/wireless/iwlegacy/4965-rs.c12
-rw-r--r--drivers/net/wireless/iwlegacy/debug.c12
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.c11
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debugfs.c12
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans-pcie.c12
-rw-r--r--drivers/net/wireless/iwmc3200wifi/debugfs.c14
-rw-r--r--drivers/net/wireless/iwmc3200wifi/sdio.c9
-rw-r--r--drivers/net/wireless/libertas/cfg.c9
-rw-r--r--drivers/net/wireless/libertas/debugfs.c10
-rw-r--r--drivers/net/wireless/mwifiex/debugfs.c18
-rw-r--r--drivers/net/wireless/mwifiex/pcie.h18
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c6
-rw-r--r--drivers/net/wireless/rtlwifi/base.c5
-rw-r--r--drivers/net/wireless/rtlwifi/pci.c7
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192de/sw.c6
-rw-r--r--drivers/net/wireless/rtlwifi/usb.c34
-rw-r--r--drivers/net/wireless/rtlwifi/wifi.h6
-rw-r--r--drivers/net/wireless/wl1251/debugfs.c14
-rw-r--r--drivers/net/wireless/wl12xx/debugfs.c38
-rw-r--r--drivers/net/xen-netfront.c2
-rw-r--r--drivers/of/gpio.c2
-rw-r--r--drivers/oprofile/oprofilefs.c14
-rw-r--r--drivers/pci/pci.c71
-rw-r--r--drivers/pci/xen-pcifront.c1
-rw-r--r--drivers/pinctrl/core.c25
-rw-r--r--drivers/platform/x86/dell-laptop.c1
-rw-r--r--drivers/platform/x86/intel_ips.c2
-rw-r--r--drivers/regulator/anatop-regulator.c6
-rw-r--r--drivers/remoteproc/remoteproc_debugfs.c13
-rw-r--r--drivers/rtc/rtc-88pm860x.c4
-rw-r--r--drivers/rtc/rtc-efi.c1
-rw-r--r--drivers/rtc/rtc-pl031.c3
-rw-r--r--drivers/rtc/rtc-r9701.c22
-rw-r--r--drivers/rtc/rtc-s3c.c31
-rw-r--r--drivers/rtc/rtc-twl.c43
-rw-r--r--drivers/s390/block/dasd_eckd.c24
-rw-r--r--drivers/s390/char/vmur.c2
-rw-r--r--drivers/scsi/lpfc/lpfc_debugfs.c9
-rw-r--r--drivers/scsi/scsi_error.c2
-rw-r--r--drivers/spi/spi-davinci.c6
-rw-r--r--drivers/spi/spi-dw.c8
-rw-r--r--drivers/spi/spi-fsl-spi.c4
-rw-r--r--drivers/spi/spi-imx.c12
-rw-r--r--drivers/spi/spi-pl022.c2
-rw-r--r--drivers/staging/android/Kconfig3
-rw-r--r--drivers/staging/android/lowmemorykiller.c48
-rw-r--r--drivers/staging/android/persistent_ram.c11
-rw-r--r--drivers/staging/android/timed_gpio.c27
-rw-r--r--drivers/staging/iio/inkern.c1
-rw-r--r--drivers/staging/iio/magnetometer/ak8975.c8
-rw-r--r--drivers/staging/iio/magnetometer/hmc5843.c4
-rw-r--r--drivers/staging/media/as102/as102_fw.c2
-rw-r--r--drivers/staging/omapdrm/omap_drv.c7
-rw-r--r--drivers/staging/ozwpan/TODO4
-rw-r--r--drivers/staging/ramster/Kconfig6
-rw-r--r--drivers/staging/rts_pstor/ms.c3
-rw-r--r--drivers/staging/rts_pstor/rtsx.c5
-rw-r--r--drivers/staging/rts_pstor/rtsx_transport.c11
-rw-r--r--drivers/staging/sep/sep_main.c6
-rw-r--r--drivers/staging/vme/devices/vme_pio2_core.c4
-rw-r--r--drivers/staging/vt6655/key.c3
-rw-r--r--drivers/staging/vt6656/ioctl.c3
-rw-r--r--drivers/staging/vt6656/key.c3
-rw-r--r--drivers/staging/xgifb/vb_init.c2
-rw-r--r--drivers/staging/xgifb/vb_setmode.c7
-rw-r--r--drivers/staging/xgifb/vb_table.h11
-rw-r--r--drivers/staging/zsmalloc/zsmalloc-main.c30
-rw-r--r--drivers/target/tcm_fc/tcm_fc.h1
-rw-r--r--drivers/target/tcm_fc/tfc_cmd.c10
-rw-r--r--drivers/target/tcm_fc/tfc_conf.c13
-rw-r--r--drivers/target/tcm_fc/tfc_io.c2
-rw-r--r--drivers/tty/amiserial.c4
-rw-r--r--drivers/tty/serial/8250/8250.c12
-rw-r--r--drivers/tty/serial/8250/8250_pci.c16
-rw-r--r--drivers/tty/serial/Kconfig2
-rw-r--r--drivers/tty/serial/altera_uart.c4
-rw-r--r--drivers/tty/serial/amba-pl011.c8
-rw-r--r--drivers/tty/serial/atmel_serial.c4
-rw-r--r--drivers/tty/serial/clps711x.c14
-rw-r--r--drivers/tty/serial/mfd.c9
-rw-r--r--drivers/tty/serial/omap-serial.c43
-rw-r--r--drivers/tty/serial/pch_uart.c20
-rw-r--r--drivers/tty/serial/samsung.c1
-rw-r--r--drivers/tty/serial/sh-sci.c167
-rw-r--r--drivers/tty/serial/sh-sci.h8
-rw-r--r--drivers/tty/sysrq.c2
-rw-r--r--drivers/tty/vt/vt.c3
-rw-r--r--drivers/usb/Kconfig16
-rw-r--r--drivers/usb/core/driver.c9
-rw-r--r--drivers/usb/core/hcd.c12
-rw-r--r--drivers/usb/core/hub.c19
-rw-r--r--drivers/usb/core/inode.c10
-rw-r--r--drivers/usb/core/message.c17
-rw-r--r--drivers/usb/core/urb.c12
-rw-r--r--drivers/usb/dwc3/core.c6
-rw-r--r--drivers/usb/dwc3/ep0.c12
-rw-r--r--drivers/usb/gadget/at91_udc.c8
-rw-r--r--drivers/usb/gadget/f_fs.c3
-rw-r--r--drivers/usb/gadget/f_rndis.c1
-rw-r--r--drivers/usb/gadget/fsl_udc_core.c25
-rw-r--r--drivers/usb/gadget/g_ffs.c4
-rw-r--r--drivers/usb/gadget/inode.c1
-rw-r--r--drivers/usb/gadget/s3c-hsotg.c17
-rw-r--r--drivers/usb/gadget/udc-core.c6
-rw-r--r--drivers/usb/gadget/uvc_queue.c4
-rw-r--r--drivers/usb/host/ehci-atmel.c1
-rw-r--r--drivers/usb/host/ehci-dbg.c9
-rw-r--r--drivers/usb/host/ehci-fsl.c7
-rw-r--r--drivers/usb/host/ehci-hcd.c12
-rw-r--r--drivers/usb/host/ehci-hub.c31
-rw-r--r--drivers/usb/host/ehci-omap.c39
-rw-r--r--drivers/usb/host/ehci-tegra.c3
-rw-r--r--drivers/usb/host/ehci.h2
-rw-r--r--drivers/usb/host/ohci-at91.c175
-rw-r--r--drivers/usb/host/pci-quirks.c10
-rw-r--r--drivers/usb/host/uhci-hub.c5
-rw-r--r--drivers/usb/host/xhci-dbg.c2
-rw-r--r--drivers/usb/host/xhci-ext-caps.h5
-rw-r--r--drivers/usb/host/xhci-mem.c9
-rw-r--r--drivers/usb/host/xhci-pci.c4
-rw-r--r--drivers/usb/host/xhci-ring.c6
-rw-r--r--drivers/usb/host/xhci.c12
-rw-r--r--drivers/usb/host/xhci.h4
-rw-r--r--drivers/usb/misc/usbtest.c9
-rw-r--r--drivers/usb/misc/yurex.c10
-rw-r--r--drivers/usb/musb/musb_core.c40
-rw-r--r--drivers/usb/musb/musb_host.c2
-rw-r--r--drivers/usb/musb/omap2430.c31
-rw-r--r--drivers/usb/serial/bus.c5
-rw-r--r--drivers/usb/serial/cp210x.c9
-rw-r--r--drivers/usb/serial/ftdi_sio.c36
-rw-r--r--drivers/usb/serial/metro-usb.c6
-rw-r--r--drivers/usb/serial/option.c1
-rw-r--r--drivers/usb/serial/pl2303.c2
-rw-r--r--drivers/usb/serial/sierra.c5
-rw-r--r--drivers/usb/serial/usb-serial.c31
-rw-r--r--drivers/usb/storage/usb.c30
-rw-r--r--drivers/uwb/hwa-rc.c3
-rw-r--r--drivers/uwb/neh.c12
-rw-r--r--drivers/uwb/uwb-debug.c9
-rw-r--r--drivers/vhost/net.c2
-rw-r--r--drivers/vhost/test.c2
-rw-r--r--drivers/vhost/vhost.c5
-rw-r--r--drivers/vhost/vhost.h2
-rw-r--r--drivers/video/au1100fb.c5
-rw-r--r--drivers/video/au1200fb.c2
-rw-r--r--drivers/video/backlight/Kconfig6
-rw-r--r--drivers/video/backlight/Makefile1
-rw-r--r--drivers/video/backlight/da9052_bl.c187
-rw-r--r--drivers/video/backlight/locomolcd.c9
-rw-r--r--drivers/video/kyro/STG4000Reg.h376
-rw-r--r--drivers/video/msm/mddi.c8
-rw-r--r--drivers/video/uvesafb.c11
-rw-r--r--drivers/virtio/virtio_balloon.c58
-rw-r--r--drivers/xen/gntdev.c2
-rw-r--r--drivers/xen/grant-table.c13
-rw-r--r--drivers/xen/manage.c1
-rw-r--r--drivers/xen/xen-pciback/pciback_ops.c2
-rw-r--r--drivers/xen/xenbus/xenbus_probe_frontend.c69
390 files changed, 4614 insertions, 3167 deletions
diff --git a/drivers/acpi/acpica/hwxface.c b/drivers/acpi/acpica/hwxface.c
index ab513a972c95..a716fede4f25 100644
--- a/drivers/acpi/acpica/hwxface.c
+++ b/drivers/acpi/acpica/hwxface.c
@@ -74,7 +74,8 @@ acpi_status acpi_reset(void)
/* Check if the reset register is supported */
- if (!reset_reg->address) {
+ if (!(acpi_gbl_FADT.flags & ACPI_FADT_RESET_REGISTER) ||
+ !reset_reg->address) {
return_ACPI_STATUS(AE_NOT_EXIST);
}
diff --git a/drivers/acpi/ec_sys.c b/drivers/acpi/ec_sys.c
index b258cab9061c..7586544fddb4 100644
--- a/drivers/acpi/ec_sys.c
+++ b/drivers/acpi/ec_sys.c
@@ -27,12 +27,6 @@ MODULE_PARM_DESC(write_support, "Dangerous, reboot and removal of battery may "
static struct dentry *acpi_ec_debugfs_dir;
-static int acpi_ec_open_io(struct inode *i, struct file *f)
-{
- f->private_data = i->i_private;
- return 0;
-}
-
static ssize_t acpi_ec_read_io(struct file *f, char __user *buf,
size_t count, loff_t *off)
{
@@ -95,7 +89,7 @@ static ssize_t acpi_ec_write_io(struct file *f, const char __user *buf,
static const struct file_operations acpi_ec_io_ops = {
.owner = THIS_MODULE,
- .open = acpi_ec_open_io,
+ .open = simple_open,
.read = acpi_ec_read_io,
.write = acpi_ec_write_io,
.llseek = default_llseek,
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index ba14fb93c929..c3881b2eb8b2 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -607,8 +607,7 @@ acpi_os_install_interrupt_handler(u32 gsi, acpi_osd_handler handler,
acpi_irq_handler = handler;
acpi_irq_context = context;
- if (request_threaded_irq(irq, NULL, acpi_irq, IRQF_SHARED, "acpi",
- acpi_irq)) {
+ if (request_irq(irq, acpi_irq, IRQF_SHARED, "acpi", acpi_irq)) {
printk(KERN_ERR PREFIX "SCI (IRQ%d) allocation failed\n", irq);
acpi_irq_handler = NULL;
return AE_NOT_ACQUIRED;
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index b3447f63e46b..f3decb30223f 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -786,7 +786,7 @@ static int acpi_idle_play_dead(struct cpuidle_device *dev, int index)
while (1) {
if (cx->entry_method == ACPI_CSTATE_HALT)
- halt();
+ safe_halt();
else if (cx->entry_method == ACPI_CSTATE_SYSTEMIO) {
inb(cx->address);
/* See comment in acpi_idle_do_entry() */
diff --git a/drivers/acpi/reboot.c b/drivers/acpi/reboot.c
index c1d612435939..a6c77e8b37bd 100644
--- a/drivers/acpi/reboot.c
+++ b/drivers/acpi/reboot.c
@@ -23,7 +23,8 @@ void acpi_reboot(void)
/* Is the reset register supported? The spec says we should be
* checking the bit width and bit offset, but Windows ignores
* these fields */
- /* Ignore also acpi_gbl_FADT.flags.ACPI_FADT_RESET_REGISTER */
+ if (!(acpi_gbl_FADT.flags & ACPI_FADT_RESET_REGISTER))
+ return;
reset_value = acpi_gbl_FADT.reset_value;
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c
index 1d661b5c3287..eb6fd233764b 100644
--- a/drivers/acpi/sleep.c
+++ b/drivers/acpi/sleep.c
@@ -28,23 +28,33 @@
#include "internal.h"
#include "sleep.h"
+u8 wake_sleep_flags = ACPI_NO_OPTIONAL_METHODS;
static unsigned int gts, bfs;
-module_param(gts, uint, 0644);
-module_param(bfs, uint, 0644);
-MODULE_PARM_DESC(gts, "Enable evaluation of _GTS on suspend.");
-MODULE_PARM_DESC(bfs, "Enable evaluation of _BFS on resume".);
-
-static u8 wake_sleep_flags(void)
+static int set_param_wake_flag(const char *val, struct kernel_param *kp)
{
- u8 flags = ACPI_NO_OPTIONAL_METHODS;
+ int ret = param_set_int(val, kp);
- if (gts)
- flags |= ACPI_EXECUTE_GTS;
- if (bfs)
- flags |= ACPI_EXECUTE_BFS;
+ if (ret)
+ return ret;
- return flags;
+ if (kp->arg == (const char *)&gts) {
+ if (gts)
+ wake_sleep_flags |= ACPI_EXECUTE_GTS;
+ else
+ wake_sleep_flags &= ~ACPI_EXECUTE_GTS;
+ }
+ if (kp->arg == (const char *)&bfs) {
+ if (bfs)
+ wake_sleep_flags |= ACPI_EXECUTE_BFS;
+ else
+ wake_sleep_flags &= ~ACPI_EXECUTE_BFS;
+ }
+ return ret;
}
+module_param_call(gts, set_param_wake_flag, param_get_int, &gts, 0644);
+module_param_call(bfs, set_param_wake_flag, param_get_int, &bfs, 0644);
+MODULE_PARM_DESC(gts, "Enable evaluation of _GTS on suspend.");
+MODULE_PARM_DESC(bfs, "Enable evaluation of _BFS on resume".);
static u8 sleep_states[ACPI_S_STATE_COUNT];
@@ -263,7 +273,6 @@ static int acpi_suspend_enter(suspend_state_t pm_state)
{
acpi_status status = AE_OK;
u32 acpi_state = acpi_target_sleep_state;
- u8 flags = wake_sleep_flags();
int error;
ACPI_FLUSH_CPU_CACHE();
@@ -271,7 +280,7 @@ static int acpi_suspend_enter(suspend_state_t pm_state)
switch (acpi_state) {
case ACPI_STATE_S1:
barrier();
- status = acpi_enter_sleep_state(acpi_state, flags);
+ status = acpi_enter_sleep_state(acpi_state, wake_sleep_flags);
break;
case ACPI_STATE_S3:
@@ -286,7 +295,7 @@ static int acpi_suspend_enter(suspend_state_t pm_state)
acpi_write_bit_register(ACPI_BITREG_SCI_ENABLE, 1);
/* Reprogram control registers and execute _BFS */
- acpi_leave_sleep_state_prep(acpi_state, flags);
+ acpi_leave_sleep_state_prep(acpi_state, wake_sleep_flags);
/* ACPI 3.0 specs (P62) says that it's the responsibility
* of the OSPM to clear the status bit [ implying that the
@@ -550,30 +559,27 @@ static int acpi_hibernation_begin(void)
static int acpi_hibernation_enter(void)
{
- u8 flags = wake_sleep_flags();
acpi_status status = AE_OK;
ACPI_FLUSH_CPU_CACHE();
/* This shouldn't return. If it returns, we have a problem */
- status = acpi_enter_sleep_state(ACPI_STATE_S4, flags);
+ status = acpi_enter_sleep_state(ACPI_STATE_S4, wake_sleep_flags);
/* Reprogram control registers and execute _BFS */
- acpi_leave_sleep_state_prep(ACPI_STATE_S4, flags);
+ acpi_leave_sleep_state_prep(ACPI_STATE_S4, wake_sleep_flags);
return ACPI_SUCCESS(status) ? 0 : -EFAULT;
}
static void acpi_hibernation_leave(void)
{
- u8 flags = wake_sleep_flags();
-
/*
* If ACPI is not enabled by the BIOS and the boot kernel, we need to
* enable it here.
*/
acpi_enable();
/* Reprogram control registers and execute _BFS */
- acpi_leave_sleep_state_prep(ACPI_STATE_S4, flags);
+ acpi_leave_sleep_state_prep(ACPI_STATE_S4, wake_sleep_flags);
/* Check the hardware signature */
if (facs && s4_hardware_signature != facs->hardware_signature) {
printk(KERN_EMERG "ACPI: Hardware changed while hibernated, "
@@ -828,12 +834,10 @@ static void acpi_power_off_prepare(void)
static void acpi_power_off(void)
{
- u8 flags = wake_sleep_flags();
-
/* acpi_sleep_prepare(ACPI_STATE_S5) should have already been called */
printk(KERN_DEBUG "%s called\n", __func__);
local_irq_disable();
- acpi_enter_sleep_state(ACPI_STATE_S5, flags);
+ acpi_enter_sleep_state(ACPI_STATE_S5, wake_sleep_flags);
}
/*
diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
index 01c2cf4efcdd..cc273226dbd0 100644
--- a/drivers/amba/bus.c
+++ b/drivers/amba/bus.c
@@ -247,8 +247,7 @@ static int amba_pm_restore(struct device *dev)
/*
* Hooks to provide runtime PM of the pclk (bus clock). It is safe to
* enable/disable the bus clock at runtime PM suspend/resume as this
- * does not result in loss of context. However, disabling vcore power
- * would do, so we leave that to the driver.
+ * does not result in loss of context.
*/
static int amba_pm_runtime_suspend(struct device *dev)
{
@@ -354,39 +353,6 @@ static void amba_put_disable_pclk(struct amba_device *pcdev)
clk_put(pclk);
}
-static int amba_get_enable_vcore(struct amba_device *pcdev)
-{
- struct regulator *vcore = regulator_get(&pcdev->dev, "vcore");
- int ret;
-
- pcdev->vcore = vcore;
-
- if (IS_ERR(vcore)) {
- /* It is OK not to supply a vcore regulator */
- if (PTR_ERR(vcore) == -ENODEV)
- return 0;
- return PTR_ERR(vcore);
- }
-
- ret = regulator_enable(vcore);
- if (ret) {
- regulator_put(vcore);
- pcdev->vcore = ERR_PTR(-ENODEV);
- }
-
- return ret;
-}
-
-static void amba_put_disable_vcore(struct amba_device *pcdev)
-{
- struct regulator *vcore = pcdev->vcore;
-
- if (!IS_ERR(vcore)) {
- regulator_disable(vcore);
- regulator_put(vcore);
- }
-}
-
/*
* These are the device model conversion veneers; they convert the
* device model structures to our more specific structures.
@@ -399,10 +365,6 @@ static int amba_probe(struct device *dev)
int ret;
do {
- ret = amba_get_enable_vcore(pcdev);
- if (ret)
- break;
-
ret = amba_get_enable_pclk(pcdev);
if (ret)
break;
@@ -420,7 +382,6 @@ static int amba_probe(struct device *dev)
pm_runtime_put_noidle(dev);
amba_put_disable_pclk(pcdev);
- amba_put_disable_vcore(pcdev);
} while (0);
return ret;
@@ -442,7 +403,6 @@ static int amba_remove(struct device *dev)
pm_runtime_put_noidle(dev);
amba_put_disable_pclk(pcdev);
- amba_put_disable_vcore(pcdev);
return ret;
}
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c
index 68013f96729f..7857e8fd0a3e 100644
--- a/drivers/ata/ata_piix.c
+++ b/drivers/ata/ata_piix.c
@@ -329,6 +329,8 @@ static const struct pci_device_id piix_pci_tbl[] = {
{ 0x8086, 0x8c08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
/* SATA Controller IDE (Lynx Point) */
{ 0x8086, 0x8c09, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
+ /* SATA Controller IDE (DH89xxCC) */
+ { 0x8086, 0x2326, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
{ } /* terminate list */
};
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index e0bda9ff89cd..28db50b57b91 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -95,7 +95,7 @@ static unsigned int ata_dev_set_xfermode(struct ata_device *dev);
static void ata_dev_xfermask(struct ata_device *dev);
static unsigned long ata_dev_blacklisted(const struct ata_device *dev);
-unsigned int ata_print_id = 1;
+atomic_t ata_print_id = ATOMIC_INIT(1);
struct ata_force_param {
const char *name;
@@ -6029,7 +6029,7 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
/* give ports names and add SCSI hosts */
for (i = 0; i < host->n_ports; i++)
- host->ports[i]->print_id = ata_print_id++;
+ host->ports[i]->print_id = atomic_inc_return(&ata_print_id);
/* Create associated sysfs transport objects */
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 1ee00c8b5b04..93dabdcd2cbe 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -3843,7 +3843,7 @@ int ata_sas_async_port_init(struct ata_port *ap)
int rc = ap->ops->port_start(ap);
if (!rc) {
- ap->print_id = ata_print_id++;
+ ap->print_id = atomic_inc_return(&ata_print_id);
__ata_port_probe(ap);
}
@@ -3867,7 +3867,7 @@ int ata_sas_port_init(struct ata_port *ap)
int rc = ap->ops->port_start(ap);
if (!rc) {
- ap->print_id = ata_print_id++;
+ ap->print_id = atomic_inc_return(&ata_print_id);
rc = ata_port_probe(ap);
}
diff --git a/drivers/ata/libata-transport.c b/drivers/ata/libata-transport.c
index 74aaee30e264..c34190485377 100644
--- a/drivers/ata/libata-transport.c
+++ b/drivers/ata/libata-transport.c
@@ -294,6 +294,7 @@ int ata_tport_add(struct device *parent,
device_enable_async_suspend(dev);
pm_runtime_set_active(dev);
pm_runtime_enable(dev);
+ pm_runtime_forbid(dev);
transport_add_device(dev);
transport_configure_device(dev);
diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h
index 2e26fcaf635b..9d0fd0b71852 100644
--- a/drivers/ata/libata.h
+++ b/drivers/ata/libata.h
@@ -53,7 +53,7 @@ enum {
ATA_DNXFER_QUIET = (1 << 31),
};
-extern unsigned int ata_print_id;
+extern atomic_t ata_print_id;
extern int atapi_passthru16;
extern int libata_fua;
extern int libata_noacpi;
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index 38950ea8398a..7336d4a7ab31 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -4025,7 +4025,8 @@ static int mv_platform_probe(struct platform_device *pdev)
struct ata_host *host;
struct mv_host_priv *hpriv;
struct resource *res;
- int n_ports, rc;
+ int n_ports = 0;
+ int rc;
ata_print_version_once(&pdev->dev, DRV_VERSION);
diff --git a/drivers/base/regmap/regcache-rbtree.c b/drivers/base/regmap/regcache-rbtree.c
index fb14a6343d4f..92b779ee002b 100644
--- a/drivers/base/regmap/regcache-rbtree.c
+++ b/drivers/base/regmap/regcache-rbtree.c
@@ -138,6 +138,7 @@ static int rbtree_show(struct seq_file *s, void *ignored)
unsigned int base, top;
int nodes = 0;
int registers = 0;
+ int average;
mutex_lock(&map->lock);
@@ -152,8 +153,13 @@ static int rbtree_show(struct seq_file *s, void *ignored)
registers += top - base + 1;
}
+ if (nodes)
+ average = registers / nodes;
+ else
+ average = 0;
+
seq_printf(s, "%d nodes, %d registers, average %d registers\n",
- nodes, registers, registers / nodes);
+ nodes, registers, average);
mutex_unlock(&map->lock);
diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c
index 87f54dbf601b..74b69095def6 100644
--- a/drivers/base/regmap/regcache.c
+++ b/drivers/base/regmap/regcache.c
@@ -346,6 +346,7 @@ out:
return ret;
}
+EXPORT_SYMBOL_GPL(regcache_sync_region);
/**
* regcache_cache_only: Put a register map into cache only mode
diff --git a/drivers/base/regmap/regmap-debugfs.c b/drivers/base/regmap/regmap-debugfs.c
index 58517a5dac13..251eb70f83e7 100644
--- a/drivers/base/regmap/regmap-debugfs.c
+++ b/drivers/base/regmap/regmap-debugfs.c
@@ -27,12 +27,6 @@ static size_t regmap_calc_reg_len(int max_val, char *buf, size_t buf_size)
return strlen(buf);
}
-static int regmap_open_file(struct inode *inode, struct file *file)
-{
- file->private_data = inode->i_private;
- return 0;
-}
-
static ssize_t regmap_name_read_file(struct file *file,
char __user *user_buf, size_t count,
loff_t *ppos)
@@ -57,7 +51,7 @@ static ssize_t regmap_name_read_file(struct file *file,
}
static const struct file_operations regmap_name_fops = {
- .open = regmap_open_file,
+ .open = simple_open,
.read = regmap_name_read_file,
.llseek = default_llseek,
};
@@ -174,7 +168,7 @@ static ssize_t regmap_map_write_file(struct file *file,
#endif
static const struct file_operations regmap_map_fops = {
- .open = regmap_open_file,
+ .open = simple_open,
.read = regmap_map_read_file,
.write = regmap_map_write_file,
.llseek = default_llseek,
@@ -243,7 +237,7 @@ out:
}
static const struct file_operations regmap_access_fops = {
- .open = regmap_open_file,
+ .open = simple_open,
.read = regmap_access_read_file,
.llseek = default_llseek,
};
diff --git a/drivers/base/soc.c b/drivers/base/soc.c
index 05f150382da8..ba29b2e73d48 100644
--- a/drivers/base/soc.c
+++ b/drivers/base/soc.c
@@ -15,7 +15,7 @@
#include <linux/sys_soc.h>
#include <linux/err.h>
-static DEFINE_IDR(soc_ida);
+static DEFINE_IDA(soc_ida);
static DEFINE_SPINLOCK(soc_lock);
static ssize_t soc_info_get(struct device *dev,
@@ -168,8 +168,6 @@ void soc_device_unregister(struct soc_device *soc_dev)
static int __init soc_bus_register(void)
{
- spin_lock_init(&soc_lock);
-
return bus_register(&soc_bus_type);
}
core_initcall(soc_bus_register);
diff --git a/drivers/bcma/Kconfig b/drivers/bcma/Kconfig
index c1172dafdffa..fb7c80fb721e 100644
--- a/drivers/bcma/Kconfig
+++ b/drivers/bcma/Kconfig
@@ -29,7 +29,7 @@ config BCMA_HOST_PCI
config BCMA_DRIVER_PCI_HOSTMODE
bool "Driver for PCI core working in hostmode"
- depends on BCMA && MIPS
+ depends on BCMA && MIPS && BCMA_HOST_PCI
help
PCI core hostmode operation (external PCI bus).
diff --git a/drivers/bcma/driver_pci_host.c b/drivers/bcma/driver_pci_host.c
index 4e20bcfa7ec5..d2097a11c3c7 100644
--- a/drivers/bcma/driver_pci_host.c
+++ b/drivers/bcma/driver_pci_host.c
@@ -10,6 +10,7 @@
*/
#include "bcma_private.h"
+#include <linux/pci.h>
#include <linux/export.h>
#include <linux/bcma/bcma.h>
#include <asm/paccess.h>
diff --git a/drivers/bcma/sprom.c b/drivers/bcma/sprom.c
index cdcf75c0954f..3e2a6002aae6 100644
--- a/drivers/bcma/sprom.c
+++ b/drivers/bcma/sprom.c
@@ -404,16 +404,19 @@ int bcma_sprom_get(struct bcma_bus *bus)
return -EOPNOTSUPP;
if (!bcma_sprom_ext_available(bus)) {
+ bool sprom_onchip;
+
/*
* External SPROM takes precedence so check
* on-chip OTP only when no external SPROM
* is present.
*/
- if (bcma_sprom_onchip_available(bus)) {
+ sprom_onchip = bcma_sprom_onchip_available(bus);
+ if (sprom_onchip) {
/* determine offset */
offset = bcma_sprom_onchip_offset(bus);
}
- if (!offset) {
+ if (!offset || !sprom_onchip) {
/*
* Maybe there is no SPROM on the device?
* Now we ask the arch code if there is some sprom
diff --git a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c
index e820b68d2f6c..acda773b3720 100644
--- a/drivers/block/cciss_scsi.c
+++ b/drivers/block/cciss_scsi.c
@@ -866,6 +866,7 @@ cciss_scsi_detect(ctlr_info_t *h)
sh->can_queue = cciss_tape_cmds;
sh->sg_tablesize = h->maxsgentries;
sh->max_cmd_len = MAX_COMMAND_SIZE;
+ sh->max_sectors = h->cciss_max_sectors;
((struct cciss_scsi_adapter_data_t *)
h->scsi_ctlr)->scsi_host = sh;
@@ -1410,7 +1411,7 @@ static void cciss_scatter_gather(ctlr_info_t *h, CommandList_struct *c,
/* track how many SG entries we are using */
if (request_nsgs > h->maxSG)
h->maxSG = request_nsgs;
- c->Header.SGTotal = (__u8) request_nsgs + chained;
+ c->Header.SGTotal = (u16) request_nsgs + chained;
if (request_nsgs > h->max_cmd_sgentries)
c->Header.SGList = h->max_cmd_sgentries;
else
diff --git a/drivers/block/mtip32xx/Kconfig b/drivers/block/mtip32xx/Kconfig
index b5dd14e072f2..0ba837fc62a8 100644
--- a/drivers/block/mtip32xx/Kconfig
+++ b/drivers/block/mtip32xx/Kconfig
@@ -4,6 +4,6 @@
config BLK_DEV_PCIESSD_MTIP32XX
tristate "Block Device Driver for Micron PCIe SSDs"
- depends on HOTPLUG_PCI_PCIE
+ depends on PCI
help
This enables the block driver for Micron PCIe SSDs.
diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c
index 8eb81c96608f..00f9fc992090 100644
--- a/drivers/block/mtip32xx/mtip32xx.c
+++ b/drivers/block/mtip32xx/mtip32xx.c
@@ -36,6 +36,7 @@
#include <linux/idr.h>
#include <linux/kthread.h>
#include <../drivers/ata/ahci.h>
+#include <linux/export.h>
#include "mtip32xx.h"
#define HW_CMD_SLOT_SZ (MTIP_MAX_COMMAND_SLOTS * 32)
@@ -44,6 +45,7 @@
#define HW_PORT_PRIV_DMA_SZ \
(HW_CMD_SLOT_SZ + HW_CMD_TBL_AR_SZ + AHCI_RX_FIS_SZ)
+#define HOST_CAP_NZDMA (1 << 19)
#define HOST_HSORG 0xFC
#define HSORG_DISABLE_SLOTGRP_INTR (1<<24)
#define HSORG_DISABLE_SLOTGRP_PXIS (1<<16)
@@ -139,6 +141,12 @@ static void mtip_command_cleanup(struct driver_data *dd)
int group = 0, commandslot = 0, commandindex = 0;
struct mtip_cmd *command;
struct mtip_port *port = dd->port;
+ static int in_progress;
+
+ if (in_progress)
+ return;
+
+ in_progress = 1;
for (group = 0; group < 4; group++) {
for (commandslot = 0; commandslot < 32; commandslot++) {
@@ -165,7 +173,8 @@ static void mtip_command_cleanup(struct driver_data *dd)
up(&port->cmd_slot);
- atomic_set(&dd->drv_cleanup_done, true);
+ set_bit(MTIP_DDF_CLEANUP_BIT, &dd->dd_flag);
+ in_progress = 0;
}
/*
@@ -262,6 +271,9 @@ static int hba_reset_nosleep(struct driver_data *dd)
&& time_before(jiffies, timeout))
mdelay(1);
+ if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag))
+ return -1;
+
if (readl(dd->mmio + HOST_CTL) & HOST_RESET)
return -1;
@@ -294,6 +306,10 @@ static inline void mtip_issue_ncq_command(struct mtip_port *port, int tag)
port->cmd_issue[MTIP_TAG_INDEX(tag)]);
spin_unlock_irqrestore(&port->cmd_issue_lock, flags);
+
+ /* Set the command's timeout value.*/
+ port->commands[tag].comp_time = jiffies + msecs_to_jiffies(
+ MTIP_NCQ_COMMAND_TIMEOUT_MS);
}
/*
@@ -420,7 +436,12 @@ static void mtip_init_port(struct mtip_port *port)
writel(0xFFFFFFFF, port->completed[i]);
/* Clear any pending interrupts for this port */
- writel(readl(port->mmio + PORT_IRQ_STAT), port->mmio + PORT_IRQ_STAT);
+ writel(readl(port->dd->mmio + PORT_IRQ_STAT),
+ port->dd->mmio + PORT_IRQ_STAT);
+
+ /* Clear any pending interrupts on the HBA. */
+ writel(readl(port->dd->mmio + HOST_IRQ_STAT),
+ port->dd->mmio + HOST_IRQ_STAT);
/* Enable port interrupts */
writel(DEF_PORT_IRQ, port->mmio + PORT_IRQ_MASK);
@@ -447,6 +468,9 @@ static void mtip_restart_port(struct mtip_port *port)
&& time_before(jiffies, timeout))
;
+ if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &port->dd->dd_flag))
+ return;
+
/*
* Chip quirk: escalate to hba reset if
* PxCMD.CR not clear after 500 ms
@@ -475,6 +499,9 @@ static void mtip_restart_port(struct mtip_port *port)
while (time_before(jiffies, timeout))
;
+ if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &port->dd->dd_flag))
+ return;
+
/* Clear PxSCTL.DET */
writel(readl(port->mmio + PORT_SCR_CTL) & ~1,
port->mmio + PORT_SCR_CTL);
@@ -486,15 +513,35 @@ static void mtip_restart_port(struct mtip_port *port)
&& time_before(jiffies, timeout))
;
+ if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &port->dd->dd_flag))
+ return;
+
if ((readl(port->mmio + PORT_SCR_STAT) & 0x01) == 0)
dev_warn(&port->dd->pdev->dev,
"COM reset failed\n");
- /* Clear SError, the PxSERR.DIAG.x should be set so clear it */
- writel(readl(port->mmio + PORT_SCR_ERR), port->mmio + PORT_SCR_ERR);
+ mtip_init_port(port);
+ mtip_start_port(port);
- /* Enable the DMA engine */
- mtip_enable_engine(port, 1);
+}
+
+/*
+ * Helper function for tag logging
+ */
+static void print_tags(struct driver_data *dd,
+ char *msg,
+ unsigned long *tagbits,
+ int cnt)
+{
+ unsigned char tagmap[128];
+ int group, tagmap_len = 0;
+
+ memset(tagmap, 0, sizeof(tagmap));
+ for (group = SLOTBITS_IN_LONGS; group > 0; group--)
+ tagmap_len = sprintf(tagmap + tagmap_len, "%016lX ",
+ tagbits[group-1]);
+ dev_warn(&dd->pdev->dev,
+ "%d command(s) %s: tagmap [%s]", cnt, msg, tagmap);
}
/*
@@ -514,15 +561,18 @@ static void mtip_timeout_function(unsigned long int data)
int tag, cmdto_cnt = 0;
unsigned int bit, group;
unsigned int num_command_slots = port->dd->slot_groups * 32;
+ unsigned long to, tagaccum[SLOTBITS_IN_LONGS];
if (unlikely(!port))
return;
- if (atomic_read(&port->dd->resumeflag) == true) {
+ if (test_bit(MTIP_DDF_RESUME_BIT, &port->dd->dd_flag)) {
mod_timer(&port->cmd_timer,
jiffies + msecs_to_jiffies(30000));
return;
}
+ /* clear the tag accumulator */
+ memset(tagaccum, 0, SLOTBITS_IN_LONGS * sizeof(long));
for (tag = 0; tag < num_command_slots; tag++) {
/*
@@ -540,12 +590,10 @@ static void mtip_timeout_function(unsigned long int data)
command = &port->commands[tag];
fis = (struct host_to_dev_fis *) command->command;
- dev_warn(&port->dd->pdev->dev,
- "Timeout for command tag %d\n", tag);
-
+ set_bit(tag, tagaccum);
cmdto_cnt++;
if (cmdto_cnt == 1)
- set_bit(MTIP_FLAG_EH_ACTIVE_BIT, &port->flags);
+ set_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags);
/*
* Clear the completed bit. This should prevent
@@ -578,15 +626,29 @@ static void mtip_timeout_function(unsigned long int data)
}
}
- if (cmdto_cnt) {
- dev_warn(&port->dd->pdev->dev,
- "%d commands timed out: restarting port",
- cmdto_cnt);
+ if (cmdto_cnt && !test_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags)) {
+ print_tags(port->dd, "timed out", tagaccum, cmdto_cnt);
+
mtip_restart_port(port);
- clear_bit(MTIP_FLAG_EH_ACTIVE_BIT, &port->flags);
+ clear_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags);
wake_up_interruptible(&port->svc_wait);
}
+ if (port->ic_pause_timer) {
+ to = port->ic_pause_timer + msecs_to_jiffies(1000);
+ if (time_after(jiffies, to)) {
+ if (!test_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags)) {
+ port->ic_pause_timer = 0;
+ clear_bit(MTIP_PF_SE_ACTIVE_BIT, &port->flags);
+ clear_bit(MTIP_PF_DM_ACTIVE_BIT, &port->flags);
+ clear_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags);
+ wake_up_interruptible(&port->svc_wait);
+ }
+
+
+ }
+ }
+
/* Restart the timer */
mod_timer(&port->cmd_timer,
jiffies + msecs_to_jiffies(MTIP_TIMEOUT_CHECK_PERIOD));
@@ -681,23 +743,18 @@ static void mtip_completion(struct mtip_port *port,
complete(waiting);
}
-/*
- * Helper function for tag logging
- */
-static void print_tags(struct driver_data *dd,
- char *msg,
- unsigned long *tagbits)
+static void mtip_null_completion(struct mtip_port *port,
+ int tag,
+ void *data,
+ int status)
{
- unsigned int tag, count = 0;
-
- for (tag = 0; tag < (dd->slot_groups) * 32; tag++) {
- if (test_bit(tag, tagbits))
- count++;
- }
- if (count)
- dev_info(&dd->pdev->dev, "%s [%i tags]\n", msg, count);
+ return;
}
+static int mtip_read_log_page(struct mtip_port *port, u8 page, u16 *buffer,
+ dma_addr_t buffer_dma, unsigned int sectors);
+static int mtip_get_smart_attr(struct mtip_port *port, unsigned int id,
+ struct smart_attr *attrib);
/*
* Handle an error.
*
@@ -708,12 +765,16 @@ static void print_tags(struct driver_data *dd,
*/
static void mtip_handle_tfe(struct driver_data *dd)
{
- int group, tag, bit, reissue;
+ int group, tag, bit, reissue, rv;
struct mtip_port *port;
- struct mtip_cmd *command;
+ struct mtip_cmd *cmd;
u32 completed;
struct host_to_dev_fis *fis;
unsigned long tagaccum[SLOTBITS_IN_LONGS];
+ unsigned int cmd_cnt = 0;
+ unsigned char *buf;
+ char *fail_reason = NULL;
+ int fail_all_ncq_write = 0, fail_all_ncq_cmds = 0;
dev_warn(&dd->pdev->dev, "Taskfile error\n");
@@ -722,8 +783,11 @@ static void mtip_handle_tfe(struct driver_data *dd)
/* Stop the timer to prevent command timeouts. */
del_timer(&port->cmd_timer);
+ /* clear the tag accumulator */
+ memset(tagaccum, 0, SLOTBITS_IN_LONGS * sizeof(long));
+
/* Set eh_active */
- set_bit(MTIP_FLAG_EH_ACTIVE_BIT, &port->flags);
+ set_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags);
/* Loop through all the groups */
for (group = 0; group < dd->slot_groups; group++) {
@@ -732,9 +796,6 @@ static void mtip_handle_tfe(struct driver_data *dd)
/* clear completed status register in the hardware.*/
writel(completed, port->completed[group]);
- /* clear the tag accumulator */
- memset(tagaccum, 0, SLOTBITS_IN_LONGS * sizeof(long));
-
/* Process successfully completed commands */
for (bit = 0; bit < 32 && completed; bit++) {
if (!(completed & (1<<bit)))
@@ -745,13 +806,14 @@ static void mtip_handle_tfe(struct driver_data *dd)
if (tag == MTIP_TAG_INTERNAL)
continue;
- command = &port->commands[tag];
- if (likely(command->comp_func)) {
+ cmd = &port->commands[tag];
+ if (likely(cmd->comp_func)) {
set_bit(tag, tagaccum);
- atomic_set(&port->commands[tag].active, 0);
- command->comp_func(port,
+ cmd_cnt++;
+ atomic_set(&cmd->active, 0);
+ cmd->comp_func(port,
tag,
- command->comp_data,
+ cmd->comp_data,
0);
} else {
dev_err(&port->dd->pdev->dev,
@@ -765,12 +827,45 @@ static void mtip_handle_tfe(struct driver_data *dd)
}
}
}
- print_tags(dd, "TFE tags completed:", tagaccum);
+
+ print_tags(dd, "completed (TFE)", tagaccum, cmd_cnt);
/* Restart the port */
mdelay(20);
mtip_restart_port(port);
+ /* Trying to determine the cause of the error */
+ rv = mtip_read_log_page(dd->port, ATA_LOG_SATA_NCQ,
+ dd->port->log_buf,
+ dd->port->log_buf_dma, 1);
+ if (rv) {
+ dev_warn(&dd->pdev->dev,
+ "Error in READ LOG EXT (10h) command\n");
+ /* non-critical error, don't fail the load */
+ } else {
+ buf = (unsigned char *)dd->port->log_buf;
+ if (buf[259] & 0x1) {
+ dev_info(&dd->pdev->dev,
+ "Write protect bit is set.\n");
+ set_bit(MTIP_DDF_WRITE_PROTECT_BIT, &dd->dd_flag);
+ fail_all_ncq_write = 1;
+ fail_reason = "write protect";
+ }
+ if (buf[288] == 0xF7) {
+ dev_info(&dd->pdev->dev,
+ "Exceeded Tmax, drive in thermal shutdown.\n");
+ set_bit(MTIP_DDF_OVER_TEMP_BIT, &dd->dd_flag);
+ fail_all_ncq_cmds = 1;
+ fail_reason = "thermal shutdown";
+ }
+ if (buf[288] == 0xBF) {
+ dev_info(&dd->pdev->dev,
+ "Drive indicates rebuild has failed.\n");
+ fail_all_ncq_cmds = 1;
+ fail_reason = "rebuild failed";
+ }
+ }
+
/* clear the tag accumulator */
memset(tagaccum, 0, SLOTBITS_IN_LONGS * sizeof(long));
@@ -779,32 +874,47 @@ static void mtip_handle_tfe(struct driver_data *dd)
for (bit = 0; bit < 32; bit++) {
reissue = 1;
tag = (group << 5) + bit;
+ cmd = &port->commands[tag];
/* If the active bit is set re-issue the command */
- if (atomic_read(&port->commands[tag].active) == 0)
+ if (atomic_read(&cmd->active) == 0)
continue;
- fis = (struct host_to_dev_fis *)
- port->commands[tag].command;
+ fis = (struct host_to_dev_fis *)cmd->command;
/* Should re-issue? */
if (tag == MTIP_TAG_INTERNAL ||
fis->command == ATA_CMD_SET_FEATURES)
reissue = 0;
+ else {
+ if (fail_all_ncq_cmds ||
+ (fail_all_ncq_write &&
+ fis->command == ATA_CMD_FPDMA_WRITE)) {
+ dev_warn(&dd->pdev->dev,
+ " Fail: %s w/tag %d [%s].\n",
+ fis->command == ATA_CMD_FPDMA_WRITE ?
+ "write" : "read",
+ tag,
+ fail_reason != NULL ?
+ fail_reason : "unknown");
+ atomic_set(&cmd->active, 0);
+ if (cmd->comp_func) {
+ cmd->comp_func(port, tag,
+ cmd->comp_data,
+ -ENODATA);
+ }
+ continue;
+ }
+ }
/*
* First check if this command has
* exceeded its retries.
*/
- if (reissue &&
- (port->commands[tag].retries-- > 0)) {
+ if (reissue && (cmd->retries-- > 0)) {
set_bit(tag, tagaccum);
- /* Update the timeout value. */
- port->commands[tag].comp_time =
- jiffies + msecs_to_jiffies(
- MTIP_NCQ_COMMAND_TIMEOUT_MS);
/* Re-issue the command. */
mtip_issue_ncq_command(port, tag);
@@ -814,13 +924,13 @@ static void mtip_handle_tfe(struct driver_data *dd)
/* Retire a command that will not be reissued */
dev_warn(&port->dd->pdev->dev,
"retiring tag %d\n", tag);
- atomic_set(&port->commands[tag].active, 0);
+ atomic_set(&cmd->active, 0);
- if (port->commands[tag].comp_func)
- port->commands[tag].comp_func(
+ if (cmd->comp_func)
+ cmd->comp_func(
port,
tag,
- port->commands[tag].comp_data,
+ cmd->comp_data,
PORT_IRQ_TF_ERR);
else
dev_warn(&port->dd->pdev->dev,
@@ -828,10 +938,10 @@ static void mtip_handle_tfe(struct driver_data *dd)
tag);
}
}
- print_tags(dd, "TFE tags reissued:", tagaccum);
+ print_tags(dd, "reissued (TFE)", tagaccum, cmd_cnt);
/* clear eh_active */
- clear_bit(MTIP_FLAG_EH_ACTIVE_BIT, &port->flags);
+ clear_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags);
wake_up_interruptible(&port->svc_wait);
mod_timer(&port->cmd_timer,
@@ -899,7 +1009,7 @@ static inline void mtip_process_legacy(struct driver_data *dd, u32 port_stat)
struct mtip_port *port = dd->port;
struct mtip_cmd *cmd = &port->commands[MTIP_TAG_INTERNAL];
- if (test_bit(MTIP_FLAG_IC_ACTIVE_BIT, &port->flags) &&
+ if (test_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags) &&
(cmd != NULL) && !(readl(port->cmd_issue[MTIP_TAG_INTERNAL])
& (1 << MTIP_TAG_INTERNAL))) {
if (cmd->comp_func) {
@@ -911,8 +1021,6 @@ static inline void mtip_process_legacy(struct driver_data *dd, u32 port_stat)
}
}
- dev_warn(&dd->pdev->dev, "IRQ status 0x%x ignored.\n", port_stat);
-
return;
}
@@ -968,6 +1076,9 @@ static inline irqreturn_t mtip_handle_irq(struct driver_data *data)
/* don't proceed further */
return IRQ_HANDLED;
}
+ if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT,
+ &dd->dd_flag))
+ return rv;
mtip_process_errors(dd, port_stat & PORT_IRQ_ERR);
}
@@ -1015,6 +1126,39 @@ static void mtip_issue_non_ncq_command(struct mtip_port *port, int tag)
port->cmd_issue[MTIP_TAG_INDEX(tag)]);
}
+static bool mtip_pause_ncq(struct mtip_port *port,
+ struct host_to_dev_fis *fis)
+{
+ struct host_to_dev_fis *reply;
+ unsigned long task_file_data;
+
+ reply = port->rxfis + RX_FIS_D2H_REG;
+ task_file_data = readl(port->mmio+PORT_TFDATA);
+
+ if ((task_file_data & 1) || (fis->command == ATA_CMD_SEC_ERASE_UNIT))
+ return false;
+
+ if (fis->command == ATA_CMD_SEC_ERASE_PREP) {
+ set_bit(MTIP_PF_SE_ACTIVE_BIT, &port->flags);
+ port->ic_pause_timer = jiffies;
+ return true;
+ } else if ((fis->command == ATA_CMD_DOWNLOAD_MICRO) &&
+ (fis->features == 0x03)) {
+ set_bit(MTIP_PF_DM_ACTIVE_BIT, &port->flags);
+ port->ic_pause_timer = jiffies;
+ return true;
+ } else if ((fis->command == ATA_CMD_SEC_ERASE_UNIT) ||
+ ((fis->command == 0xFC) &&
+ (fis->features == 0x27 || fis->features == 0x72 ||
+ fis->features == 0x62 || fis->features == 0x26))) {
+ /* Com reset after secure erase or lowlevel format */
+ mtip_restart_port(port);
+ return false;
+ }
+
+ return false;
+}
+
/*
* Wait for port to quiesce
*
@@ -1033,11 +1177,13 @@ static int mtip_quiesce_io(struct mtip_port *port, unsigned long timeout)
to = jiffies + msecs_to_jiffies(timeout);
do {
- if (test_bit(MTIP_FLAG_SVC_THD_ACTIVE_BIT, &port->flags) &&
- test_bit(MTIP_FLAG_ISSUE_CMDS_BIT, &port->flags)) {
+ if (test_bit(MTIP_PF_SVC_THD_ACTIVE_BIT, &port->flags) &&
+ test_bit(MTIP_PF_ISSUE_CMDS_BIT, &port->flags)) {
msleep(20);
continue; /* svc thd is actively issuing commands */
}
+ if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &port->dd->dd_flag))
+ return -EFAULT;
/*
* Ignore s_active bit 0 of array element 0.
* This bit will always be set
@@ -1074,7 +1220,7 @@ static int mtip_quiesce_io(struct mtip_port *port, unsigned long timeout)
* -EAGAIN Time out waiting for command to complete.
*/
static int mtip_exec_internal_command(struct mtip_port *port,
- void *fis,
+ struct host_to_dev_fis *fis,
int fis_len,
dma_addr_t buffer,
int buf_len,
@@ -1084,8 +1230,9 @@ static int mtip_exec_internal_command(struct mtip_port *port,
{
struct mtip_cmd_sg *command_sg;
DECLARE_COMPLETION_ONSTACK(wait);
- int rv = 0;
+ int rv = 0, ready2go = 1;
struct mtip_cmd *int_cmd = &port->commands[MTIP_TAG_INTERNAL];
+ unsigned long to;
/* Make sure the buffer is 8 byte aligned. This is asic specific. */
if (buffer & 0x00000007) {
@@ -1094,23 +1241,38 @@ static int mtip_exec_internal_command(struct mtip_port *port,
return -EFAULT;
}
- /* Only one internal command should be running at a time */
- if (test_and_set_bit(MTIP_TAG_INTERNAL, port->allocated)) {
+ to = jiffies + msecs_to_jiffies(timeout);
+ do {
+ ready2go = !test_and_set_bit(MTIP_TAG_INTERNAL,
+ port->allocated);
+ if (ready2go)
+ break;
+ mdelay(100);
+ } while (time_before(jiffies, to));
+ if (!ready2go) {
dev_warn(&port->dd->pdev->dev,
- "Internal command already active\n");
+ "Internal cmd active. new cmd [%02X]\n", fis->command);
return -EBUSY;
}
- set_bit(MTIP_FLAG_IC_ACTIVE_BIT, &port->flags);
+ set_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags);
+ port->ic_pause_timer = 0;
+
+ if (fis->command == ATA_CMD_SEC_ERASE_UNIT)
+ clear_bit(MTIP_PF_SE_ACTIVE_BIT, &port->flags);
+ else if (fis->command == ATA_CMD_DOWNLOAD_MICRO)
+ clear_bit(MTIP_PF_DM_ACTIVE_BIT, &port->flags);
if (atomic == GFP_KERNEL) {
- /* wait for io to complete if non atomic */
- if (mtip_quiesce_io(port, 5000) < 0) {
- dev_warn(&port->dd->pdev->dev,
- "Failed to quiesce IO\n");
- release_slot(port, MTIP_TAG_INTERNAL);
- clear_bit(MTIP_FLAG_IC_ACTIVE_BIT, &port->flags);
- wake_up_interruptible(&port->svc_wait);
- return -EBUSY;
+ if (fis->command != ATA_CMD_STANDBYNOW1) {
+ /* wait for io to complete if non atomic */
+ if (mtip_quiesce_io(port, 5000) < 0) {
+ dev_warn(&port->dd->pdev->dev,
+ "Failed to quiesce IO\n");
+ release_slot(port, MTIP_TAG_INTERNAL);
+ clear_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags);
+ wake_up_interruptible(&port->svc_wait);
+ return -EBUSY;
+ }
}
/* Set the completion function and data for the command. */
@@ -1120,7 +1282,7 @@ static int mtip_exec_internal_command(struct mtip_port *port,
} else {
/* Clear completion - we're going to poll */
int_cmd->comp_data = NULL;
- int_cmd->comp_func = NULL;
+ int_cmd->comp_func = mtip_null_completion;
}
/* Copy the command to the command table */
@@ -1159,6 +1321,12 @@ static int mtip_exec_internal_command(struct mtip_port *port,
"Internal command did not complete [%d] "
"within timeout of %lu ms\n",
atomic, timeout);
+ if (mtip_check_surprise_removal(port->dd->pdev) ||
+ test_bit(MTIP_DDF_REMOVE_PENDING_BIT,
+ &port->dd->dd_flag)) {
+ rv = -ENXIO;
+ goto exec_ic_exit;
+ }
rv = -EAGAIN;
}
@@ -1166,31 +1334,59 @@ static int mtip_exec_internal_command(struct mtip_port *port,
& (1 << MTIP_TAG_INTERNAL)) {
dev_warn(&port->dd->pdev->dev,
"Retiring internal command but CI is 1.\n");
+ if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT,
+ &port->dd->dd_flag)) {
+ hba_reset_nosleep(port->dd);
+ rv = -ENXIO;
+ } else {
+ mtip_restart_port(port);
+ rv = -EAGAIN;
+ }
+ goto exec_ic_exit;
}
} else {
/* Spin for <timeout> checking if command still outstanding */
timeout = jiffies + msecs_to_jiffies(timeout);
-
- while ((readl(
- port->cmd_issue[MTIP_TAG_INTERNAL])
- & (1 << MTIP_TAG_INTERNAL))
- && time_before(jiffies, timeout))
- ;
+ while ((readl(port->cmd_issue[MTIP_TAG_INTERNAL])
+ & (1 << MTIP_TAG_INTERNAL))
+ && time_before(jiffies, timeout)) {
+ if (mtip_check_surprise_removal(port->dd->pdev)) {
+ rv = -ENXIO;
+ goto exec_ic_exit;
+ }
+ if ((fis->command != ATA_CMD_STANDBYNOW1) &&
+ test_bit(MTIP_DDF_REMOVE_PENDING_BIT,
+ &port->dd->dd_flag)) {
+ rv = -ENXIO;
+ goto exec_ic_exit;
+ }
+ }
if (readl(port->cmd_issue[MTIP_TAG_INTERNAL])
& (1 << MTIP_TAG_INTERNAL)) {
dev_err(&port->dd->pdev->dev,
- "Internal command did not complete [%d]\n",
- atomic);
+ "Internal command did not complete [atomic]\n");
rv = -EAGAIN;
+ if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT,
+ &port->dd->dd_flag)) {
+ hba_reset_nosleep(port->dd);
+ rv = -ENXIO;
+ } else {
+ mtip_restart_port(port);
+ rv = -EAGAIN;
+ }
}
}
-
+exec_ic_exit:
/* Clear the allocated and active bits for the internal command. */
atomic_set(&int_cmd->active, 0);
release_slot(port, MTIP_TAG_INTERNAL);
- clear_bit(MTIP_FLAG_IC_ACTIVE_BIT, &port->flags);
+ if (rv >= 0 && mtip_pause_ncq(port, fis)) {
+ /* NCQ paused */
+ return rv;
+ }
+ clear_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags);
wake_up_interruptible(&port->svc_wait);
return rv;
@@ -1240,6 +1436,9 @@ static int mtip_get_identify(struct mtip_port *port, void __user *user_buffer)
int rv = 0;
struct host_to_dev_fis fis;
+ if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &port->dd->dd_flag))
+ return -EFAULT;
+
/* Build the FIS. */
memset(&fis, 0, sizeof(struct host_to_dev_fis));
fis.type = 0x27;
@@ -1313,6 +1512,7 @@ static int mtip_standby_immediate(struct mtip_port *port)
{
int rv;
struct host_to_dev_fis fis;
+ unsigned long start;
/* Build the FIS. */
memset(&fis, 0, sizeof(struct host_to_dev_fis));
@@ -1320,15 +1520,150 @@ static int mtip_standby_immediate(struct mtip_port *port)
fis.opts = 1 << 7;
fis.command = ATA_CMD_STANDBYNOW1;
- /* Execute the command. Use a 15-second timeout for large drives. */
+ start = jiffies;
rv = mtip_exec_internal_command(port,
&fis,
5,
0,
0,
0,
- GFP_KERNEL,
+ GFP_ATOMIC,
15000);
+ dbg_printk(MTIP_DRV_NAME "Time taken to complete standby cmd: %d ms\n",
+ jiffies_to_msecs(jiffies - start));
+ if (rv)
+ dev_warn(&port->dd->pdev->dev,
+ "STANDBY IMMEDIATE command failed.\n");
+
+ return rv;
+}
+
+/*
+ * Issue a READ LOG EXT command to the device.
+ *
+ * @port pointer to the port structure.
+ * @page page number to fetch
+ * @buffer pointer to buffer
+ * @buffer_dma dma address corresponding to @buffer
+ * @sectors page length to fetch, in sectors
+ *
+ * return value
+ * @rv return value from mtip_exec_internal_command()
+ */
+static int mtip_read_log_page(struct mtip_port *port, u8 page, u16 *buffer,
+ dma_addr_t buffer_dma, unsigned int sectors)
+{
+ struct host_to_dev_fis fis;
+
+ memset(&fis, 0, sizeof(struct host_to_dev_fis));
+ fis.type = 0x27;
+ fis.opts = 1 << 7;
+ fis.command = ATA_CMD_READ_LOG_EXT;
+ fis.sect_count = sectors & 0xFF;
+ fis.sect_cnt_ex = (sectors >> 8) & 0xFF;
+ fis.lba_low = page;
+ fis.lba_mid = 0;
+ fis.device = ATA_DEVICE_OBS;
+
+ memset(buffer, 0, sectors * ATA_SECT_SIZE);
+
+ return mtip_exec_internal_command(port,
+ &fis,
+ 5,
+ buffer_dma,
+ sectors * ATA_SECT_SIZE,
+ 0,
+ GFP_ATOMIC,
+ MTIP_INTERNAL_COMMAND_TIMEOUT_MS);
+}
+
+/*
+ * Issue a SMART READ DATA command to the device.
+ *
+ * @port pointer to the port structure.
+ * @buffer pointer to buffer
+ * @buffer_dma dma address corresponding to @buffer
+ *
+ * return value
+ * @rv return value from mtip_exec_internal_command()
+ */
+static int mtip_get_smart_data(struct mtip_port *port, u8 *buffer,
+ dma_addr_t buffer_dma)
+{
+ struct host_to_dev_fis fis;
+
+ memset(&fis, 0, sizeof(struct host_to_dev_fis));
+ fis.type = 0x27;
+ fis.opts = 1 << 7;
+ fis.command = ATA_CMD_SMART;
+ fis.features = 0xD0;
+ fis.sect_count = 1;
+ fis.lba_mid = 0x4F;
+ fis.lba_hi = 0xC2;
+ fis.device = ATA_DEVICE_OBS;
+
+ return mtip_exec_internal_command(port,
+ &fis,
+ 5,
+ buffer_dma,
+ ATA_SECT_SIZE,
+ 0,
+ GFP_ATOMIC,
+ 15000);
+}
+
+/*
+ * Get the value of a smart attribute
+ *
+ * @port pointer to the port structure
+ * @id attribute number
+ * @attrib pointer to return attrib information corresponding to @id
+ *
+ * return value
+ * -EINVAL NULL buffer passed or unsupported attribute @id.
+ * -EPERM Identify data not valid, SMART not supported or not enabled
+ */
+static int mtip_get_smart_attr(struct mtip_port *port, unsigned int id,
+ struct smart_attr *attrib)
+{
+ int rv, i;
+ struct smart_attr *pattr;
+
+ if (!attrib)
+ return -EINVAL;
+
+ if (!port->identify_valid) {
+ dev_warn(&port->dd->pdev->dev, "IDENTIFY DATA not valid\n");
+ return -EPERM;
+ }
+ if (!(port->identify[82] & 0x1)) {
+ dev_warn(&port->dd->pdev->dev, "SMART not supported\n");
+ return -EPERM;
+ }
+ if (!(port->identify[85] & 0x1)) {
+ dev_warn(&port->dd->pdev->dev, "SMART not enabled\n");
+ return -EPERM;
+ }
+
+ memset(port->smart_buf, 0, ATA_SECT_SIZE);
+ rv = mtip_get_smart_data(port, port->smart_buf, port->smart_buf_dma);
+ if (rv) {
+ dev_warn(&port->dd->pdev->dev, "Failed to ge SMART data\n");
+ return rv;
+ }
+
+ pattr = (struct smart_attr *)(port->smart_buf + 2);
+ for (i = 0; i < 29; i++, pattr++)
+ if (pattr->attr_id == id) {
+ memcpy(attrib, pattr, sizeof(struct smart_attr));
+ break;
+ }
+
+ if (i == 29) {
+ dev_warn(&port->dd->pdev->dev,
+ "Query for invalid SMART attribute ID\n");
+ rv = -EINVAL;
+ }
return rv;
}
@@ -1504,10 +1839,7 @@ static int exec_drive_task(struct mtip_port *port, u8 *command)
fis.cyl_hi = command[5];
fis.device = command[6] & ~0x10; /* Clear the dev bit*/
-
- dbg_printk(MTIP_DRV_NAME "%s: User Command: cmd %x, feat %x, "
- "nsect %x, sect %x, lcyl %x, "
- "hcyl %x, sel %x\n",
+ dbg_printk(MTIP_DRV_NAME " %s: User Command: cmd %x, feat %x, nsect %x, sect %x, lcyl %x, hcyl %x, sel %x\n",
__func__,
command[0],
command[1],
@@ -1534,8 +1866,7 @@ static int exec_drive_task(struct mtip_port *port, u8 *command)
command[4] = reply->cyl_low;
command[5] = reply->cyl_hi;
- dbg_printk(MTIP_DRV_NAME "%s: Completion Status: stat %x, "
- "err %x , cyl_lo %x cyl_hi %x\n",
+ dbg_printk(MTIP_DRV_NAME " %s: Completion Status: stat %x, err %x , cyl_lo %x cyl_hi %x\n",
__func__,
command[0],
command[1],
@@ -1578,7 +1909,7 @@ static int exec_drive_command(struct mtip_port *port, u8 *command,
}
dbg_printk(MTIP_DRV_NAME
- "%s: User Command: cmd %x, sect %x, "
+ " %s: User Command: cmd %x, sect %x, "
"feat %x, sectcnt %x\n",
__func__,
command[0],
@@ -1607,7 +1938,7 @@ static int exec_drive_command(struct mtip_port *port, u8 *command,
command[2] = command[3];
dbg_printk(MTIP_DRV_NAME
- "%s: Completion Status: stat %x, "
+ " %s: Completion Status: stat %x, "
"err %x, cmd %x\n",
__func__,
command[0],
@@ -1810,9 +2141,10 @@ static int exec_drive_taskfile(struct driver_data *dd,
}
dbg_printk(MTIP_DRV_NAME
- "taskfile: cmd %x, feat %x, nsect %x,"
+ " %s: cmd %x, feat %x, nsect %x,"
" sect/lbal %x, lcyl/lbam %x, hcyl/lbah %x,"
" head/dev %x\n",
+ __func__,
fis.command,
fis.features,
fis.sect_count,
@@ -1823,8 +2155,8 @@ static int exec_drive_taskfile(struct driver_data *dd,
switch (fis.command) {
case ATA_CMD_DOWNLOAD_MICRO:
- /* Change timeout for Download Microcode to 60 seconds.*/
- timeout = 60000;
+ /* Change timeout for Download Microcode to 2 minutes */
+ timeout = 120000;
break;
case ATA_CMD_SEC_ERASE_UNIT:
/* Change timeout for Security Erase Unit to 4 minutes.*/
@@ -1840,8 +2172,8 @@ static int exec_drive_taskfile(struct driver_data *dd,
timeout = 10000;
break;
case ATA_CMD_SMART:
- /* Change timeout for vendor unique command to 10 secs */
- timeout = 10000;
+ /* Change timeout for vendor unique command to 15 secs */
+ timeout = 15000;
break;
default:
timeout = MTIP_IOCTL_COMMAND_TIMEOUT_MS;
@@ -1903,18 +2235,8 @@ static int exec_drive_taskfile(struct driver_data *dd,
req_task->hob_ports[1] = reply->features_ex;
req_task->hob_ports[2] = reply->sect_cnt_ex;
}
-
- /* Com rest after secure erase or lowlevel format */
- if (((fis.command == ATA_CMD_SEC_ERASE_UNIT) ||
- ((fis.command == 0xFC) &&
- (fis.features == 0x27 || fis.features == 0x72 ||
- fis.features == 0x62 || fis.features == 0x26))) &&
- !(reply->command & 1)) {
- mtip_restart_port(dd->port);
- }
-
dbg_printk(MTIP_DRV_NAME
- "%s: Completion: stat %x,"
+ " %s: Completion: stat %x,"
"err %x, sect_cnt %x, lbalo %x,"
"lbamid %x, lbahi %x, dev %x\n",
__func__,
@@ -2080,14 +2402,10 @@ static void mtip_hw_submit_io(struct driver_data *dd, sector_t start,
struct host_to_dev_fis *fis;
struct mtip_port *port = dd->port;
struct mtip_cmd *command = &port->commands[tag];
+ int dma_dir = (dir == READ) ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
/* Map the scatter list for DMA access */
- if (dir == READ)
- nents = dma_map_sg(&dd->pdev->dev, command->sg,
- nents, DMA_FROM_DEVICE);
- else
- nents = dma_map_sg(&dd->pdev->dev, command->sg,
- nents, DMA_TO_DEVICE);
+ nents = dma_map_sg(&dd->pdev->dev, command->sg, nents, dma_dir);
command->scatter_ents = nents;
@@ -2127,7 +2445,7 @@ static void mtip_hw_submit_io(struct driver_data *dd, sector_t start,
*/
command->comp_data = dd;
command->comp_func = mtip_async_complete;
- command->direction = (dir == READ ? DMA_FROM_DEVICE : DMA_TO_DEVICE);
+ command->direction = dma_dir;
/*
* Set the completion function and data for the command passed
@@ -2140,19 +2458,16 @@ static void mtip_hw_submit_io(struct driver_data *dd, sector_t start,
* To prevent this command from being issued
* if an internal command is in progress or error handling is active.
*/
- if (unlikely(test_bit(MTIP_FLAG_IC_ACTIVE_BIT, &port->flags) ||
- test_bit(MTIP_FLAG_EH_ACTIVE_BIT, &port->flags))) {
+ if (port->flags & MTIP_PF_PAUSE_IO) {
set_bit(tag, port->cmds_to_issue);
- set_bit(MTIP_FLAG_ISSUE_CMDS_BIT, &port->flags);
+ set_bit(MTIP_PF_ISSUE_CMDS_BIT, &port->flags);
return;
}
/* Issue the command to the hardware */
mtip_issue_ncq_command(port, tag);
- /* Set the command's timeout value.*/
- port->commands[tag].comp_time = jiffies + msecs_to_jiffies(
- MTIP_NCQ_COMMAND_TIMEOUT_MS);
+ return;
}
/*
@@ -2191,6 +2506,10 @@ static struct scatterlist *mtip_hw_get_scatterlist(struct driver_data *dd,
down(&dd->port->cmd_slot);
*tag = get_slot(dd->port);
+ if (unlikely(test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag))) {
+ up(&dd->port->cmd_slot);
+ return NULL;
+ }
if (unlikely(*tag < 0))
return NULL;
@@ -2207,7 +2526,7 @@ static struct scatterlist *mtip_hw_get_scatterlist(struct driver_data *dd,
* return value
* The size, in bytes, of the data copied into buf.
*/
-static ssize_t hw_show_registers(struct device *dev,
+static ssize_t mtip_hw_show_registers(struct device *dev,
struct device_attribute *attr,
char *buf)
{
@@ -2216,7 +2535,7 @@ static ssize_t hw_show_registers(struct device *dev,
int size = 0;
int n;
- size += sprintf(&buf[size], "%s:\ns_active:\n", __func__);
+ size += sprintf(&buf[size], "S ACTive:\n");
for (n = 0; n < dd->slot_groups; n++)
size += sprintf(&buf[size], "0x%08x\n",
@@ -2240,20 +2559,39 @@ static ssize_t hw_show_registers(struct device *dev,
group_allocated);
}
- size += sprintf(&buf[size], "completed:\n");
+ size += sprintf(&buf[size], "Completed:\n");
for (n = 0; n < dd->slot_groups; n++)
size += sprintf(&buf[size], "0x%08x\n",
readl(dd->port->completed[n]));
- size += sprintf(&buf[size], "PORT_IRQ_STAT 0x%08x\n",
+ size += sprintf(&buf[size], "PORT IRQ STAT : 0x%08x\n",
readl(dd->port->mmio + PORT_IRQ_STAT));
- size += sprintf(&buf[size], "HOST_IRQ_STAT 0x%08x\n",
+ size += sprintf(&buf[size], "HOST IRQ STAT : 0x%08x\n",
readl(dd->mmio + HOST_IRQ_STAT));
return size;
}
-static DEVICE_ATTR(registers, S_IRUGO, hw_show_registers, NULL);
+
+static ssize_t mtip_hw_show_status(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct driver_data *dd = dev_to_disk(dev)->private_data;
+ int size = 0;
+
+ if (test_bit(MTIP_DDF_OVER_TEMP_BIT, &dd->dd_flag))
+ size += sprintf(buf, "%s", "thermal_shutdown\n");
+ else if (test_bit(MTIP_DDF_WRITE_PROTECT_BIT, &dd->dd_flag))
+ size += sprintf(buf, "%s", "write_protect\n");
+ else
+ size += sprintf(buf, "%s", "online\n");
+
+ return size;
+}
+
+static DEVICE_ATTR(registers, S_IRUGO, mtip_hw_show_registers, NULL);
+static DEVICE_ATTR(status, S_IRUGO, mtip_hw_show_status, NULL);
/*
* Create the sysfs related attributes.
@@ -2272,7 +2610,10 @@ static int mtip_hw_sysfs_init(struct driver_data *dd, struct kobject *kobj)
if (sysfs_create_file(kobj, &dev_attr_registers.attr))
dev_warn(&dd->pdev->dev,
- "Error creating registers sysfs entry\n");
+ "Error creating 'registers' sysfs entry\n");
+ if (sysfs_create_file(kobj, &dev_attr_status.attr))
+ dev_warn(&dd->pdev->dev,
+ "Error creating 'status' sysfs entry\n");
return 0;
}
@@ -2292,6 +2633,7 @@ static int mtip_hw_sysfs_exit(struct driver_data *dd, struct kobject *kobj)
return -EINVAL;
sysfs_remove_file(kobj, &dev_attr_registers.attr);
+ sysfs_remove_file(kobj, &dev_attr_status.attr);
return 0;
}
@@ -2384,10 +2726,12 @@ static int mtip_ftl_rebuild_poll(struct driver_data *dd)
"FTL rebuild in progress. Polling for completion.\n");
start = jiffies;
- dd->ftlrebuildflag = 1;
timeout = jiffies + msecs_to_jiffies(MTIP_FTL_REBUILD_TIMEOUT_MS);
do {
+ if (unlikely(test_bit(MTIP_DDF_REMOVE_PENDING_BIT,
+ &dd->dd_flag)))
+ return -EFAULT;
if (mtip_check_surprise_removal(dd->pdev))
return -EFAULT;
@@ -2408,22 +2752,17 @@ static int mtip_ftl_rebuild_poll(struct driver_data *dd)
dev_warn(&dd->pdev->dev,
"FTL rebuild complete (%d secs).\n",
jiffies_to_msecs(jiffies - start) / 1000);
- dd->ftlrebuildflag = 0;
mtip_block_initialize(dd);
- break;
+ return 0;
}
ssleep(10);
} while (time_before(jiffies, timeout));
/* Check for timeout */
- if (dd->ftlrebuildflag) {
- dev_err(&dd->pdev->dev,
+ dev_err(&dd->pdev->dev,
"Timed out waiting for FTL rebuild to complete (%d secs).\n",
jiffies_to_msecs(jiffies - start) / 1000);
- return -EFAULT;
- }
-
- return 0;
+ return -EFAULT;
}
/*
@@ -2448,14 +2787,17 @@ static int mtip_service_thread(void *data)
* is in progress nor error handling is active
*/
wait_event_interruptible(port->svc_wait, (port->flags) &&
- !test_bit(MTIP_FLAG_IC_ACTIVE_BIT, &port->flags) &&
- !test_bit(MTIP_FLAG_EH_ACTIVE_BIT, &port->flags));
+ !(port->flags & MTIP_PF_PAUSE_IO));
if (kthread_should_stop())
break;
- set_bit(MTIP_FLAG_SVC_THD_ACTIVE_BIT, &port->flags);
- if (test_bit(MTIP_FLAG_ISSUE_CMDS_BIT, &port->flags)) {
+ if (unlikely(test_bit(MTIP_DDF_REMOVE_PENDING_BIT,
+ &dd->dd_flag)))
+ break;
+
+ set_bit(MTIP_PF_SVC_THD_ACTIVE_BIT, &port->flags);
+ if (test_bit(MTIP_PF_ISSUE_CMDS_BIT, &port->flags)) {
slot = 1;
/* used to restrict the loop to one iteration */
slot_start = num_cmd_slots;
@@ -2480,21 +2822,19 @@ static int mtip_service_thread(void *data)
/* Issue the command to the hardware */
mtip_issue_ncq_command(port, slot);
- /* Set the command's timeout value.*/
- port->commands[slot].comp_time = jiffies +
- msecs_to_jiffies(MTIP_NCQ_COMMAND_TIMEOUT_MS);
-
clear_bit(slot, port->cmds_to_issue);
}
- clear_bit(MTIP_FLAG_ISSUE_CMDS_BIT, &port->flags);
- } else if (test_bit(MTIP_FLAG_REBUILD_BIT, &port->flags)) {
- mtip_ftl_rebuild_poll(dd);
- clear_bit(MTIP_FLAG_REBUILD_BIT, &port->flags);
+ clear_bit(MTIP_PF_ISSUE_CMDS_BIT, &port->flags);
+ } else if (test_bit(MTIP_PF_REBUILD_BIT, &port->flags)) {
+ if (!mtip_ftl_rebuild_poll(dd))
+ set_bit(MTIP_DDF_REBUILD_FAILED_BIT,
+ &dd->dd_flag);
+ clear_bit(MTIP_PF_REBUILD_BIT, &port->flags);
}
- clear_bit(MTIP_FLAG_SVC_THD_ACTIVE_BIT, &port->flags);
+ clear_bit(MTIP_PF_SVC_THD_ACTIVE_BIT, &port->flags);
- if (test_bit(MTIP_FLAG_SVC_THD_SHOULD_STOP_BIT, &port->flags))
+ if (test_bit(MTIP_PF_SVC_THD_STOP_BIT, &port->flags))
break;
}
return 0;
@@ -2513,6 +2853,9 @@ static int mtip_hw_init(struct driver_data *dd)
int i;
int rv;
unsigned int num_command_slots;
+ unsigned long timeout, timetaken;
+ unsigned char *buf;
+ struct smart_attr attr242;
dd->mmio = pcim_iomap_table(dd->pdev)[MTIP_ABAR];
@@ -2547,7 +2890,7 @@ static int mtip_hw_init(struct driver_data *dd)
/* Allocate memory for the command list. */
dd->port->command_list =
dmam_alloc_coherent(&dd->pdev->dev,
- HW_PORT_PRIV_DMA_SZ + (ATA_SECT_SIZE * 2),
+ HW_PORT_PRIV_DMA_SZ + (ATA_SECT_SIZE * 4),
&dd->port->command_list_dma,
GFP_KERNEL);
if (!dd->port->command_list) {
@@ -2560,7 +2903,7 @@ static int mtip_hw_init(struct driver_data *dd)
/* Clear the memory we have allocated. */
memset(dd->port->command_list,
0,
- HW_PORT_PRIV_DMA_SZ + (ATA_SECT_SIZE * 2));
+ HW_PORT_PRIV_DMA_SZ + (ATA_SECT_SIZE * 4));
/* Setup the addresse of the RX FIS. */
dd->port->rxfis = dd->port->command_list + HW_CMD_SLOT_SZ;
@@ -2576,10 +2919,19 @@ static int mtip_hw_init(struct driver_data *dd)
dd->port->identify_dma = dd->port->command_tbl_dma +
HW_CMD_TBL_AR_SZ;
- /* Setup the address of the sector buffer. */
+ /* Setup the address of the sector buffer - for some non-ncq cmds */
dd->port->sector_buffer = (void *) dd->port->identify + ATA_SECT_SIZE;
dd->port->sector_buffer_dma = dd->port->identify_dma + ATA_SECT_SIZE;
+ /* Setup the address of the log buf - for read log command */
+ dd->port->log_buf = (void *)dd->port->sector_buffer + ATA_SECT_SIZE;
+ dd->port->log_buf_dma = dd->port->sector_buffer_dma + ATA_SECT_SIZE;
+
+ /* Setup the address of the smart buf - for smart read data command */
+ dd->port->smart_buf = (void *)dd->port->log_buf + ATA_SECT_SIZE;
+ dd->port->smart_buf_dma = dd->port->log_buf_dma + ATA_SECT_SIZE;
+
+
/* Point the command headers at the command tables. */
for (i = 0; i < num_command_slots; i++) {
dd->port->commands[i].command_header =
@@ -2623,14 +2975,43 @@ static int mtip_hw_init(struct driver_data *dd)
dd->port->mmio + i*0x80 + PORT_SDBV;
}
- /* Reset the HBA. */
- if (mtip_hba_reset(dd) < 0) {
- dev_err(&dd->pdev->dev,
- "Card did not reset within timeout\n");
- rv = -EIO;
+ timetaken = jiffies;
+ timeout = jiffies + msecs_to_jiffies(30000);
+ while (((readl(dd->port->mmio + PORT_SCR_STAT) & 0x0F) != 0x03) &&
+ time_before(jiffies, timeout)) {
+ mdelay(100);
+ }
+ if (unlikely(mtip_check_surprise_removal(dd->pdev))) {
+ timetaken = jiffies - timetaken;
+ dev_warn(&dd->pdev->dev,
+ "Surprise removal detected at %u ms\n",
+ jiffies_to_msecs(timetaken));
+ rv = -ENODEV;
+ goto out2 ;
+ }
+ if (unlikely(test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag))) {
+ timetaken = jiffies - timetaken;
+ dev_warn(&dd->pdev->dev,
+ "Removal detected at %u ms\n",
+ jiffies_to_msecs(timetaken));
+ rv = -EFAULT;
goto out2;
}
+ /* Conditionally reset the HBA. */
+ if (!(readl(dd->mmio + HOST_CAP) & HOST_CAP_NZDMA)) {
+ if (mtip_hba_reset(dd) < 0) {
+ dev_err(&dd->pdev->dev,
+ "Card did not reset within timeout\n");
+ rv = -EIO;
+ goto out2;
+ }
+ } else {
+ /* Clear any pending interrupts on the HBA */
+ writel(readl(dd->mmio + HOST_IRQ_STAT),
+ dd->mmio + HOST_IRQ_STAT);
+ }
+
mtip_init_port(dd->port);
mtip_start_port(dd->port);
@@ -2660,6 +3041,12 @@ static int mtip_hw_init(struct driver_data *dd)
mod_timer(&dd->port->cmd_timer,
jiffies + msecs_to_jiffies(MTIP_TIMEOUT_CHECK_PERIOD));
+
+ if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag)) {
+ rv = -EFAULT;
+ goto out3;
+ }
+
if (mtip_get_identify(dd->port, NULL) < 0) {
rv = -EFAULT;
goto out3;
@@ -2667,10 +3054,47 @@ static int mtip_hw_init(struct driver_data *dd)
if (*(dd->port->identify + MTIP_FTL_REBUILD_OFFSET) ==
MTIP_FTL_REBUILD_MAGIC) {
- set_bit(MTIP_FLAG_REBUILD_BIT, &dd->port->flags);
+ set_bit(MTIP_PF_REBUILD_BIT, &dd->port->flags);
return MTIP_FTL_REBUILD_MAGIC;
}
mtip_dump_identify(dd->port);
+
+ /* check write protect, over temp and rebuild statuses */
+ rv = mtip_read_log_page(dd->port, ATA_LOG_SATA_NCQ,
+ dd->port->log_buf,
+ dd->port->log_buf_dma, 1);
+ if (rv) {
+ dev_warn(&dd->pdev->dev,
+ "Error in READ LOG EXT (10h) command\n");
+ /* non-critical error, don't fail the load */
+ } else {
+ buf = (unsigned char *)dd->port->log_buf;
+ if (buf[259] & 0x1) {
+ dev_info(&dd->pdev->dev,
+ "Write protect bit is set.\n");
+ set_bit(MTIP_DDF_WRITE_PROTECT_BIT, &dd->dd_flag);
+ }
+ if (buf[288] == 0xF7) {
+ dev_info(&dd->pdev->dev,
+ "Exceeded Tmax, drive in thermal shutdown.\n");
+ set_bit(MTIP_DDF_OVER_TEMP_BIT, &dd->dd_flag);
+ }
+ if (buf[288] == 0xBF) {
+ dev_info(&dd->pdev->dev,
+ "Drive indicates rebuild has failed.\n");
+ /* TODO */
+ }
+ }
+
+ /* get write protect progess */
+ memset(&attr242, 0, sizeof(struct smart_attr));
+ if (mtip_get_smart_attr(dd->port, 242, &attr242))
+ dev_warn(&dd->pdev->dev,
+ "Unable to check write protect progress\n");
+ else
+ dev_info(&dd->pdev->dev,
+ "Write protect progress: %d%% (%d blocks)\n",
+ attr242.cur, attr242.data);
return rv;
out3:
@@ -2688,7 +3112,7 @@ out2:
/* Free the command/command header memory. */
dmam_free_coherent(&dd->pdev->dev,
- HW_PORT_PRIV_DMA_SZ + (ATA_SECT_SIZE * 2),
+ HW_PORT_PRIV_DMA_SZ + (ATA_SECT_SIZE * 4),
dd->port->command_list,
dd->port->command_list_dma);
out1:
@@ -2712,9 +3136,12 @@ static int mtip_hw_exit(struct driver_data *dd)
* Send standby immediate (E0h) to the drive so that it
* saves its state.
*/
- if (atomic_read(&dd->drv_cleanup_done) != true) {
+ if (!test_bit(MTIP_DDF_CLEANUP_BIT, &dd->dd_flag)) {
- mtip_standby_immediate(dd->port);
+ if (!test_bit(MTIP_PF_REBUILD_BIT, &dd->port->flags))
+ if (mtip_standby_immediate(dd->port))
+ dev_warn(&dd->pdev->dev,
+ "STANDBY IMMEDIATE failed\n");
/* de-initialize the port. */
mtip_deinit_port(dd->port);
@@ -2734,7 +3161,7 @@ static int mtip_hw_exit(struct driver_data *dd)
/* Free the command/command header memory. */
dmam_free_coherent(&dd->pdev->dev,
- HW_PORT_PRIV_DMA_SZ + (ATA_SECT_SIZE * 2),
+ HW_PORT_PRIV_DMA_SZ + (ATA_SECT_SIZE * 4),
dd->port->command_list,
dd->port->command_list_dma);
/* Free the memory allocated for the for structure. */
@@ -2892,6 +3319,9 @@ static int mtip_block_ioctl(struct block_device *dev,
if (!dd)
return -ENOTTY;
+ if (unlikely(test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag)))
+ return -ENOTTY;
+
switch (cmd) {
case BLKFLSBUF:
return -ENOTTY;
@@ -2927,6 +3357,9 @@ static int mtip_block_compat_ioctl(struct block_device *dev,
if (!dd)
return -ENOTTY;
+ if (unlikely(test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag)))
+ return -ENOTTY;
+
switch (cmd) {
case BLKFLSBUF:
return -ENOTTY;
@@ -3049,6 +3482,24 @@ static void mtip_make_request(struct request_queue *queue, struct bio *bio)
int nents = 0;
int tag = 0;
+ if (unlikely(dd->dd_flag & MTIP_DDF_STOP_IO)) {
+ if (unlikely(test_bit(MTIP_DDF_REMOVE_PENDING_BIT,
+ &dd->dd_flag))) {
+ bio_endio(bio, -ENXIO);
+ return;
+ }
+ if (unlikely(test_bit(MTIP_DDF_OVER_TEMP_BIT, &dd->dd_flag))) {
+ bio_endio(bio, -ENODATA);
+ return;
+ }
+ if (unlikely(test_bit(MTIP_DDF_WRITE_PROTECT_BIT,
+ &dd->dd_flag) &&
+ bio_data_dir(bio))) {
+ bio_endio(bio, -ENODATA);
+ return;
+ }
+ }
+
if (unlikely(!bio_has_data(bio))) {
blk_queue_flush(queue, 0);
bio_endio(bio, 0);
@@ -3061,7 +3512,7 @@ static void mtip_make_request(struct request_queue *queue, struct bio *bio)
if (unlikely((bio)->bi_vcnt > MTIP_MAX_SG)) {
dev_warn(&dd->pdev->dev,
- "Maximum number of SGL entries exceeded");
+ "Maximum number of SGL entries exceeded\n");
bio_io_error(bio);
mtip_hw_release_scatterlist(dd, tag);
return;
@@ -3210,8 +3661,10 @@ skip_create_disk:
kobject_put(kobj);
}
- if (dd->mtip_svc_handler)
+ if (dd->mtip_svc_handler) {
+ set_bit(MTIP_DDF_INIT_DONE_BIT, &dd->dd_flag);
return rv; /* service thread created for handling rebuild */
+ }
start_service_thread:
sprintf(thd_name, "mtip_svc_thd_%02d", index);
@@ -3220,12 +3673,15 @@ start_service_thread:
dd, thd_name);
if (IS_ERR(dd->mtip_svc_handler)) {
- printk(KERN_ERR "mtip32xx: service thread failed to start\n");
+ dev_err(&dd->pdev->dev, "service thread failed to start\n");
dd->mtip_svc_handler = NULL;
rv = -EFAULT;
goto kthread_run_error;
}
+ if (wait_for_rebuild == MTIP_FTL_REBUILD_MAGIC)
+ rv = wait_for_rebuild;
+
return rv;
kthread_run_error:
@@ -3266,16 +3722,18 @@ static int mtip_block_remove(struct driver_data *dd)
struct kobject *kobj;
if (dd->mtip_svc_handler) {
- set_bit(MTIP_FLAG_SVC_THD_SHOULD_STOP_BIT, &dd->port->flags);
+ set_bit(MTIP_PF_SVC_THD_STOP_BIT, &dd->port->flags);
wake_up_interruptible(&dd->port->svc_wait);
kthread_stop(dd->mtip_svc_handler);
}
- /* Clean up the sysfs attributes managed by the protocol layer. */
- kobj = kobject_get(&disk_to_dev(dd->disk)->kobj);
- if (kobj) {
- mtip_hw_sysfs_exit(dd, kobj);
- kobject_put(kobj);
+ /* Clean up the sysfs attributes, if created */
+ if (test_bit(MTIP_DDF_INIT_DONE_BIT, &dd->dd_flag)) {
+ kobj = kobject_get(&disk_to_dev(dd->disk)->kobj);
+ if (kobj) {
+ mtip_hw_sysfs_exit(dd, kobj);
+ kobject_put(kobj);
+ }
}
/*
@@ -3283,6 +3741,11 @@ static int mtip_block_remove(struct driver_data *dd)
* from /dev
*/
del_gendisk(dd->disk);
+
+ spin_lock(&rssd_index_lock);
+ ida_remove(&rssd_index_ida, dd->index);
+ spin_unlock(&rssd_index_lock);
+
blk_cleanup_queue(dd->queue);
dd->disk = NULL;
dd->queue = NULL;
@@ -3312,6 +3775,11 @@ static int mtip_block_shutdown(struct driver_data *dd)
/* Delete our gendisk structure, and cleanup the blk queue. */
del_gendisk(dd->disk);
+
+ spin_lock(&rssd_index_lock);
+ ida_remove(&rssd_index_ida, dd->index);
+ spin_unlock(&rssd_index_lock);
+
blk_cleanup_queue(dd->queue);
dd->disk = NULL;
dd->queue = NULL;
@@ -3359,11 +3827,6 @@ static int mtip_pci_probe(struct pci_dev *pdev,
return -ENOMEM;
}
- /* Set the atomic variable as 1 in case of SRSI */
- atomic_set(&dd->drv_cleanup_done, true);
-
- atomic_set(&dd->resumeflag, false);
-
/* Attach the private data to this PCI device. */
pci_set_drvdata(pdev, dd);
@@ -3420,7 +3883,8 @@ static int mtip_pci_probe(struct pci_dev *pdev,
* instance number.
*/
instance++;
-
+ if (rv != MTIP_FTL_REBUILD_MAGIC)
+ set_bit(MTIP_DDF_INIT_DONE_BIT, &dd->dd_flag);
goto done;
block_initialize_err:
@@ -3434,9 +3898,6 @@ iomap_err:
pci_set_drvdata(pdev, NULL);
return rv;
done:
- /* Set the atomic variable as 0 in case of SRSI */
- atomic_set(&dd->drv_cleanup_done, true);
-
return rv;
}
@@ -3452,8 +3913,10 @@ static void mtip_pci_remove(struct pci_dev *pdev)
struct driver_data *dd = pci_get_drvdata(pdev);
int counter = 0;
+ set_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag);
+
if (mtip_check_surprise_removal(pdev)) {
- while (atomic_read(&dd->drv_cleanup_done) == false) {
+ while (!test_bit(MTIP_DDF_CLEANUP_BIT, &dd->dd_flag)) {
counter++;
msleep(20);
if (counter == 10) {
@@ -3463,8 +3926,6 @@ static void mtip_pci_remove(struct pci_dev *pdev)
}
}
}
- /* Set the atomic variable as 1 in case of SRSI */
- atomic_set(&dd->drv_cleanup_done, true);
/* Clean up the block layer. */
mtip_block_remove(dd);
@@ -3493,7 +3954,7 @@ static int mtip_pci_suspend(struct pci_dev *pdev, pm_message_t mesg)
return -EFAULT;
}
- atomic_set(&dd->resumeflag, true);
+ set_bit(MTIP_DDF_RESUME_BIT, &dd->dd_flag);
/* Disable ports & interrupts then send standby immediate */
rv = mtip_block_suspend(dd);
@@ -3559,7 +4020,7 @@ static int mtip_pci_resume(struct pci_dev *pdev)
dev_err(&pdev->dev, "Unable to resume\n");
err:
- atomic_set(&dd->resumeflag, false);
+ clear_bit(MTIP_DDF_RESUME_BIT, &dd->dd_flag);
return rv;
}
@@ -3608,18 +4069,25 @@ MODULE_DEVICE_TABLE(pci, mtip_pci_tbl);
*/
static int __init mtip_init(void)
{
+ int error;
+
printk(KERN_INFO MTIP_DRV_NAME " Version " MTIP_DRV_VERSION "\n");
/* Allocate a major block device number to use with this driver. */
- mtip_major = register_blkdev(0, MTIP_DRV_NAME);
- if (mtip_major < 0) {
+ error = register_blkdev(0, MTIP_DRV_NAME);
+ if (error <= 0) {
printk(KERN_ERR "Unable to register block device (%d)\n",
- mtip_major);
+ error);
return -EBUSY;
}
+ mtip_major = error;
/* Register our PCI operations. */
- return pci_register_driver(&mtip_pci_driver);
+ error = pci_register_driver(&mtip_pci_driver);
+ if (error)
+ unregister_blkdev(mtip_major, MTIP_DRV_NAME);
+
+ return error;
}
/*
diff --git a/drivers/block/mtip32xx/mtip32xx.h b/drivers/block/mtip32xx/mtip32xx.h
index e0554a8f2233..4ef58336310a 100644
--- a/drivers/block/mtip32xx/mtip32xx.h
+++ b/drivers/block/mtip32xx/mtip32xx.h
@@ -34,8 +34,8 @@
/* offset of Device Control register in PCIe extended capabilites space */
#define PCIE_CONFIG_EXT_DEVICE_CONTROL_OFFSET 0x48
-/* # of times to retry timed out IOs */
-#define MTIP_MAX_RETRIES 5
+/* # of times to retry timed out/failed IOs */
+#define MTIP_MAX_RETRIES 2
/* Various timeout values in ms */
#define MTIP_NCQ_COMMAND_TIMEOUT_MS 5000
@@ -114,12 +114,41 @@
#define __force_bit2int (unsigned int __force)
/* below are bit numbers in 'flags' defined in mtip_port */
-#define MTIP_FLAG_IC_ACTIVE_BIT 0
-#define MTIP_FLAG_EH_ACTIVE_BIT 1
-#define MTIP_FLAG_SVC_THD_ACTIVE_BIT 2
-#define MTIP_FLAG_ISSUE_CMDS_BIT 4
-#define MTIP_FLAG_REBUILD_BIT 5
-#define MTIP_FLAG_SVC_THD_SHOULD_STOP_BIT 8
+#define MTIP_PF_IC_ACTIVE_BIT 0 /* pio/ioctl */
+#define MTIP_PF_EH_ACTIVE_BIT 1 /* error handling */
+#define MTIP_PF_SE_ACTIVE_BIT 2 /* secure erase */
+#define MTIP_PF_DM_ACTIVE_BIT 3 /* download microcde */
+#define MTIP_PF_PAUSE_IO ((1 << MTIP_PF_IC_ACTIVE_BIT) | \
+ (1 << MTIP_PF_EH_ACTIVE_BIT) | \
+ (1 << MTIP_PF_SE_ACTIVE_BIT) | \
+ (1 << MTIP_PF_DM_ACTIVE_BIT))
+
+#define MTIP_PF_SVC_THD_ACTIVE_BIT 4
+#define MTIP_PF_ISSUE_CMDS_BIT 5
+#define MTIP_PF_REBUILD_BIT 6
+#define MTIP_PF_SVC_THD_STOP_BIT 8
+
+/* below are bit numbers in 'dd_flag' defined in driver_data */
+#define MTIP_DDF_REMOVE_PENDING_BIT 1
+#define MTIP_DDF_OVER_TEMP_BIT 2
+#define MTIP_DDF_WRITE_PROTECT_BIT 3
+#define MTIP_DDF_STOP_IO ((1 << MTIP_DDF_REMOVE_PENDING_BIT) | \
+ (1 << MTIP_DDF_OVER_TEMP_BIT) | \
+ (1 << MTIP_DDF_WRITE_PROTECT_BIT))
+
+#define MTIP_DDF_CLEANUP_BIT 5
+#define MTIP_DDF_RESUME_BIT 6
+#define MTIP_DDF_INIT_DONE_BIT 7
+#define MTIP_DDF_REBUILD_FAILED_BIT 8
+
+__packed struct smart_attr{
+ u8 attr_id;
+ u16 flags;
+ u8 cur;
+ u8 worst;
+ u32 data;
+ u8 res[3];
+};
/* Register Frame Information Structure (FIS), host to device. */
struct host_to_dev_fis {
@@ -345,6 +374,12 @@ struct mtip_port {
* when the command slot and all associated data structures
* are no longer needed.
*/
+ u16 *log_buf;
+ dma_addr_t log_buf_dma;
+
+ u8 *smart_buf;
+ dma_addr_t smart_buf_dma;
+
unsigned long allocated[SLOTBITS_IN_LONGS];
/*
* used to queue commands when an internal command is in progress
@@ -368,6 +403,7 @@ struct mtip_port {
* Timer used to complete commands that have been active for too long.
*/
struct timer_list cmd_timer;
+ unsigned long ic_pause_timer;
/*
* Semaphore used to block threads if there are no
* command slots available.
@@ -404,13 +440,9 @@ struct driver_data {
unsigned slot_groups; /* number of slot groups the product supports */
- atomic_t drv_cleanup_done; /* Atomic variable for SRSI */
-
unsigned long index; /* Index to determine the disk name */
- unsigned int ftlrebuildflag; /* FTL rebuild flag */
-
- atomic_t resumeflag; /* Atomic variable to track suspend/resume */
+ unsigned long dd_flag; /* NOTE: use atomic bit operations on this */
struct task_struct *mtip_svc_handler; /* task_struct of svc thd */
};
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
index c4a60badf252..0d39f2f4294a 100644
--- a/drivers/block/virtio_blk.c
+++ b/drivers/block/virtio_blk.c
@@ -351,6 +351,7 @@ static void virtblk_config_changed_work(struct work_struct *work)
cap_str_10, cap_str_2);
set_capacity(vblk->disk, capacity);
+ revalidate_disk(vblk->disk);
done:
mutex_unlock(&vblk->config_lock);
}
@@ -374,6 +375,34 @@ static int init_vq(struct virtio_blk *vblk)
return err;
}
+/*
+ * Legacy naming scheme used for virtio devices. We are stuck with it for
+ * virtio blk but don't ever use it for any new driver.
+ */
+static int virtblk_name_format(char *prefix, int index, char *buf, int buflen)
+{
+ const int base = 'z' - 'a' + 1;
+ char *begin = buf + strlen(prefix);
+ char *end = buf + buflen;
+ char *p;
+ int unit;
+
+ p = end - 1;
+ *p = '\0';
+ unit = base;
+ do {
+ if (p == begin)
+ return -EINVAL;
+ *--p = 'a' + (index % unit);
+ index = (index / unit) - 1;
+ } while (index >= 0);
+
+ memmove(begin, p, end - p);
+ memcpy(buf, prefix, strlen(prefix));
+
+ return 0;
+}
+
static int __devinit virtblk_probe(struct virtio_device *vdev)
{
struct virtio_blk *vblk;
@@ -442,18 +471,7 @@ static int __devinit virtblk_probe(struct virtio_device *vdev)
q->queuedata = vblk;
- if (index < 26) {
- sprintf(vblk->disk->disk_name, "vd%c", 'a' + index % 26);
- } else if (index < (26 + 1) * 26) {
- sprintf(vblk->disk->disk_name, "vd%c%c",
- 'a' + index / 26 - 1, 'a' + index % 26);
- } else {
- const unsigned int m1 = (index / 26 - 1) / 26 - 1;
- const unsigned int m2 = (index / 26 - 1) % 26;
- const unsigned int m3 = index % 26;
- sprintf(vblk->disk->disk_name, "vd%c%c%c",
- 'a' + m1, 'a' + m2, 'a' + m3);
- }
+ virtblk_name_format("vd", index, vblk->disk->disk_name, DISK_NAME_LEN);
vblk->disk->major = major;
vblk->disk->first_minor = index_to_minor(index);
diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c
index 0088bf60f368..73f196ca713f 100644
--- a/drivers/block/xen-blkback/blkback.c
+++ b/drivers/block/xen-blkback/blkback.c
@@ -321,6 +321,7 @@ struct seg_buf {
static void xen_blkbk_unmap(struct pending_req *req)
{
struct gnttab_unmap_grant_ref unmap[BLKIF_MAX_SEGMENTS_PER_REQUEST];
+ struct page *pages[BLKIF_MAX_SEGMENTS_PER_REQUEST];
unsigned int i, invcount = 0;
grant_handle_t handle;
int ret;
@@ -332,25 +333,12 @@ static void xen_blkbk_unmap(struct pending_req *req)
gnttab_set_unmap_op(&unmap[invcount], vaddr(req, i),
GNTMAP_host_map, handle);
pending_handle(req, i) = BLKBACK_INVALID_HANDLE;
+ pages[invcount] = virt_to_page(vaddr(req, i));
invcount++;
}
- ret = HYPERVISOR_grant_table_op(
- GNTTABOP_unmap_grant_ref, unmap, invcount);
+ ret = gnttab_unmap_refs(unmap, pages, invcount, false);
BUG_ON(ret);
- /*
- * Note, we use invcount, so nr->pages, so we can't index
- * using vaddr(req, i).
- */
- for (i = 0; i < invcount; i++) {
- ret = m2p_remove_override(
- virt_to_page(unmap[i].host_addr), false);
- if (ret) {
- pr_alert(DRV_PFX "Failed to remove M2P override for %lx\n",
- (unsigned long)unmap[i].host_addr);
- continue;
- }
- }
}
static int xen_blkbk_map(struct blkif_request *req,
@@ -378,7 +366,7 @@ static int xen_blkbk_map(struct blkif_request *req,
pending_req->blkif->domid);
}
- ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, map, nseg);
+ ret = gnttab_map_refs(map, NULL, &blkbk->pending_page(pending_req, 0), nseg);
BUG_ON(ret);
/*
@@ -398,15 +386,6 @@ static int xen_blkbk_map(struct blkif_request *req,
if (ret)
continue;
- ret = m2p_add_override(PFN_DOWN(map[i].dev_bus_addr),
- blkbk->pending_page(pending_req, i), NULL);
- if (ret) {
- pr_alert(DRV_PFX "Failed to install M2P override for %lx (ret: %d)\n",
- (unsigned long)map[i].dev_bus_addr, ret);
- /* We could switch over to GNTTABOP_copy */
- continue;
- }
-
seg[i].buf = map[i].dev_bus_addr |
(req->u.rw.seg[i].first_sect << 9);
}
@@ -419,21 +398,18 @@ static int dispatch_discard_io(struct xen_blkif *blkif,
int err = 0;
int status = BLKIF_RSP_OKAY;
struct block_device *bdev = blkif->vbd.bdev;
+ unsigned long secure;
blkif->st_ds_req++;
xen_blkif_get(blkif);
- if (blkif->blk_backend_type == BLKIF_BACKEND_PHY ||
- blkif->blk_backend_type == BLKIF_BACKEND_FILE) {
- unsigned long secure = (blkif->vbd.discard_secure &&
- (req->u.discard.flag & BLKIF_DISCARD_SECURE)) ?
- BLKDEV_DISCARD_SECURE : 0;
- err = blkdev_issue_discard(bdev,
- req->u.discard.sector_number,
- req->u.discard.nr_sectors,
- GFP_KERNEL, secure);
- } else
- err = -EOPNOTSUPP;
+ secure = (blkif->vbd.discard_secure &&
+ (req->u.discard.flag & BLKIF_DISCARD_SECURE)) ?
+ BLKDEV_DISCARD_SECURE : 0;
+
+ err = blkdev_issue_discard(bdev, req->u.discard.sector_number,
+ req->u.discard.nr_sectors,
+ GFP_KERNEL, secure);
if (err == -EOPNOTSUPP) {
pr_debug(DRV_PFX "discard op failed, not supported\n");
@@ -830,7 +806,7 @@ static int __init xen_blkif_init(void)
int i, mmap_pages;
int rc = 0;
- if (!xen_pv_domain())
+ if (!xen_domain())
return -ENODEV;
blkbk = kzalloc(sizeof(struct xen_blkbk), GFP_KERNEL);
diff --git a/drivers/block/xen-blkback/common.h b/drivers/block/xen-blkback/common.h
index d0ee7edc9be8..773cf27dc23f 100644
--- a/drivers/block/xen-blkback/common.h
+++ b/drivers/block/xen-blkback/common.h
@@ -146,11 +146,6 @@ enum blkif_protocol {
BLKIF_PROTOCOL_X86_64 = 3,
};
-enum blkif_backend_type {
- BLKIF_BACKEND_PHY = 1,
- BLKIF_BACKEND_FILE = 2,
-};
-
struct xen_vbd {
/* What the domain refers to this vbd as. */
blkif_vdev_t handle;
@@ -177,7 +172,6 @@ struct xen_blkif {
unsigned int irq;
/* Comms information. */
enum blkif_protocol blk_protocol;
- enum blkif_backend_type blk_backend_type;
union blkif_back_rings blk_rings;
void *blk_ring;
/* The VBD attached to this interface. */
diff --git a/drivers/block/xen-blkback/xenbus.c b/drivers/block/xen-blkback/xenbus.c
index 24a2fb57e5d0..4f66171c6683 100644
--- a/drivers/block/xen-blkback/xenbus.c
+++ b/drivers/block/xen-blkback/xenbus.c
@@ -381,72 +381,49 @@ int xen_blkbk_flush_diskcache(struct xenbus_transaction xbt,
err = xenbus_printf(xbt, dev->nodename, "feature-flush-cache",
"%d", state);
if (err)
- xenbus_dev_fatal(dev, err, "writing feature-flush-cache");
+ dev_warn(&dev->dev, "writing feature-flush-cache (%d)", err);
return err;
}
-int xen_blkbk_discard(struct xenbus_transaction xbt, struct backend_info *be)
+static void xen_blkbk_discard(struct xenbus_transaction xbt, struct backend_info *be)
{
struct xenbus_device *dev = be->dev;
struct xen_blkif *blkif = be->blkif;
- char *type;
int err;
int state = 0;
+ struct block_device *bdev = be->blkif->vbd.bdev;
+ struct request_queue *q = bdev_get_queue(bdev);
- type = xenbus_read(XBT_NIL, dev->nodename, "type", NULL);
- if (!IS_ERR(type)) {
- if (strncmp(type, "file", 4) == 0) {
- state = 1;
- blkif->blk_backend_type = BLKIF_BACKEND_FILE;
+ if (blk_queue_discard(q)) {
+ err = xenbus_printf(xbt, dev->nodename,
+ "discard-granularity", "%u",
+ q->limits.discard_granularity);
+ if (err) {
+ dev_warn(&dev->dev, "writing discard-granularity (%d)", err);
+ return;
}
- if (strncmp(type, "phy", 3) == 0) {
- struct block_device *bdev = be->blkif->vbd.bdev;
- struct request_queue *q = bdev_get_queue(bdev);
- if (blk_queue_discard(q)) {
- err = xenbus_printf(xbt, dev->nodename,
- "discard-granularity", "%u",
- q->limits.discard_granularity);
- if (err) {
- xenbus_dev_fatal(dev, err,
- "writing discard-granularity");
- goto kfree;
- }
- err = xenbus_printf(xbt, dev->nodename,
- "discard-alignment", "%u",
- q->limits.discard_alignment);
- if (err) {
- xenbus_dev_fatal(dev, err,
- "writing discard-alignment");
- goto kfree;
- }
- state = 1;
- blkif->blk_backend_type = BLKIF_BACKEND_PHY;
- }
- /* Optional. */
- err = xenbus_printf(xbt, dev->nodename,
- "discard-secure", "%d",
- blkif->vbd.discard_secure);
- if (err) {
- xenbus_dev_fatal(dev, err,
- "writting discard-secure");
- goto kfree;
- }
+ err = xenbus_printf(xbt, dev->nodename,
+ "discard-alignment", "%u",
+ q->limits.discard_alignment);
+ if (err) {
+ dev_warn(&dev->dev, "writing discard-alignment (%d)", err);
+ return;
+ }
+ state = 1;
+ /* Optional. */
+ err = xenbus_printf(xbt, dev->nodename,
+ "discard-secure", "%d",
+ blkif->vbd.discard_secure);
+ if (err) {
+ dev_warn(&dev->dev, "writing discard-secure (%d)", err);
+ return;
}
- } else {
- err = PTR_ERR(type);
- xenbus_dev_fatal(dev, err, "reading type");
- goto out;
}
-
err = xenbus_printf(xbt, dev->nodename, "feature-discard",
"%d", state);
if (err)
- xenbus_dev_fatal(dev, err, "writing feature-discard");
-kfree:
- kfree(type);
-out:
- return err;
+ dev_warn(&dev->dev, "writing feature-discard (%d)", err);
}
int xen_blkbk_barrier(struct xenbus_transaction xbt,
struct backend_info *be, int state)
@@ -457,7 +434,7 @@ int xen_blkbk_barrier(struct xenbus_transaction xbt,
err = xenbus_printf(xbt, dev->nodename, "feature-barrier",
"%d", state);
if (err)
- xenbus_dev_fatal(dev, err, "writing feature-barrier");
+ dev_warn(&dev->dev, "writing feature-barrier (%d)", err);
return err;
}
@@ -689,14 +666,12 @@ again:
return;
}
- err = xen_blkbk_flush_diskcache(xbt, be, be->blkif->vbd.flush_support);
- if (err)
- goto abort;
+ /* If we can't advertise it is OK. */
+ xen_blkbk_flush_diskcache(xbt, be, be->blkif->vbd.flush_support);
- err = xen_blkbk_discard(xbt, be);
+ xen_blkbk_discard(xbt, be);
- /* If we can't advertise it is OK. */
- err = xen_blkbk_barrier(xbt, be, be->blkif->vbd.flush_support);
+ xen_blkbk_barrier(xbt, be, be->blkif->vbd.flush_support);
err = xenbus_printf(xbt, dev->nodename, "sectors", "%llu",
(unsigned long long)vbd_sz(&be->blkif->vbd));
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
index d5e1ab956740..4e86393a09cf 100644
--- a/drivers/block/xen-blkfront.c
+++ b/drivers/block/xen-blkfront.c
@@ -43,6 +43,7 @@
#include <linux/slab.h>
#include <linux/mutex.h>
#include <linux/scatterlist.h>
+#include <linux/bitmap.h>
#include <xen/xen.h>
#include <xen/xenbus.h>
@@ -81,6 +82,7 @@ static const struct block_device_operations xlvbd_block_fops;
*/
struct blkfront_info
{
+ spinlock_t io_lock;
struct mutex mutex;
struct xenbus_device *xbdev;
struct gendisk *gd;
@@ -105,8 +107,6 @@ struct blkfront_info
int is_ready;
};
-static DEFINE_SPINLOCK(blkif_io_lock);
-
static unsigned int nr_minors;
static unsigned long *minors;
static DEFINE_SPINLOCK(minor_lock);
@@ -177,8 +177,7 @@ static int xlbd_reserve_minors(unsigned int minor, unsigned int nr)
spin_lock(&minor_lock);
if (find_next_bit(minors, end, minor) >= end) {
- for (; minor < end; ++minor)
- __set_bit(minor, minors);
+ bitmap_set(minors, minor, nr);
rc = 0;
} else
rc = -EBUSY;
@@ -193,8 +192,7 @@ static void xlbd_release_minors(unsigned int minor, unsigned int nr)
BUG_ON(end > nr_minors);
spin_lock(&minor_lock);
- for (; minor < end; ++minor)
- __clear_bit(minor, minors);
+ bitmap_clear(minors, minor, nr);
spin_unlock(&minor_lock);
}
@@ -419,7 +417,7 @@ static int xlvbd_init_blk_queue(struct gendisk *gd, u16 sector_size)
struct request_queue *rq;
struct blkfront_info *info = gd->private_data;
- rq = blk_init_queue(do_blkif_request, &blkif_io_lock);
+ rq = blk_init_queue(do_blkif_request, &info->io_lock);
if (rq == NULL)
return -1;
@@ -636,14 +634,14 @@ static void xlvbd_release_gendisk(struct blkfront_info *info)
if (info->rq == NULL)
return;
- spin_lock_irqsave(&blkif_io_lock, flags);
+ spin_lock_irqsave(&info->io_lock, flags);
/* No more blkif_request(). */
blk_stop_queue(info->rq);
/* No more gnttab callback work. */
gnttab_cancel_free_callback(&info->callback);
- spin_unlock_irqrestore(&blkif_io_lock, flags);
+ spin_unlock_irqrestore(&info->io_lock, flags);
/* Flush gnttab callback work. Must be done with no locks held. */
flush_work_sync(&info->work);
@@ -675,16 +673,16 @@ static void blkif_restart_queue(struct work_struct *work)
{
struct blkfront_info *info = container_of(work, struct blkfront_info, work);
- spin_lock_irq(&blkif_io_lock);
+ spin_lock_irq(&info->io_lock);
if (info->connected == BLKIF_STATE_CONNECTED)
kick_pending_request_queues(info);
- spin_unlock_irq(&blkif_io_lock);
+ spin_unlock_irq(&info->io_lock);
}
static void blkif_free(struct blkfront_info *info, int suspend)
{
/* Prevent new requests being issued until we fix things up. */
- spin_lock_irq(&blkif_io_lock);
+ spin_lock_irq(&info->io_lock);
info->connected = suspend ?
BLKIF_STATE_SUSPENDED : BLKIF_STATE_DISCONNECTED;
/* No more blkif_request(). */
@@ -692,7 +690,7 @@ static void blkif_free(struct blkfront_info *info, int suspend)
blk_stop_queue(info->rq);
/* No more gnttab callback work. */
gnttab_cancel_free_callback(&info->callback);
- spin_unlock_irq(&blkif_io_lock);
+ spin_unlock_irq(&info->io_lock);
/* Flush gnttab callback work. Must be done with no locks held. */
flush_work_sync(&info->work);
@@ -728,10 +726,10 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
struct blkfront_info *info = (struct blkfront_info *)dev_id;
int error;
- spin_lock_irqsave(&blkif_io_lock, flags);
+ spin_lock_irqsave(&info->io_lock, flags);
if (unlikely(info->connected != BLKIF_STATE_CONNECTED)) {
- spin_unlock_irqrestore(&blkif_io_lock, flags);
+ spin_unlock_irqrestore(&info->io_lock, flags);
return IRQ_HANDLED;
}
@@ -816,7 +814,7 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
kick_pending_request_queues(info);
- spin_unlock_irqrestore(&blkif_io_lock, flags);
+ spin_unlock_irqrestore(&info->io_lock, flags);
return IRQ_HANDLED;
}
@@ -991,6 +989,7 @@ static int blkfront_probe(struct xenbus_device *dev,
}
mutex_init(&info->mutex);
+ spin_lock_init(&info->io_lock);
info->xbdev = dev;
info->vdevice = vdevice;
info->connected = BLKIF_STATE_DISCONNECTED;
@@ -1068,7 +1067,7 @@ static int blkif_recover(struct blkfront_info *info)
xenbus_switch_state(info->xbdev, XenbusStateConnected);
- spin_lock_irq(&blkif_io_lock);
+ spin_lock_irq(&info->io_lock);
/* Now safe for us to use the shared ring */
info->connected = BLKIF_STATE_CONNECTED;
@@ -1079,7 +1078,7 @@ static int blkif_recover(struct blkfront_info *info)
/* Kick any other new requests queued since we resumed */
kick_pending_request_queues(info);
- spin_unlock_irq(&blkif_io_lock);
+ spin_unlock_irq(&info->io_lock);
return 0;
}
@@ -1277,10 +1276,10 @@ static void blkfront_connect(struct blkfront_info *info)
xenbus_switch_state(info->xbdev, XenbusStateConnected);
/* Kick pending requests. */
- spin_lock_irq(&blkif_io_lock);
+ spin_lock_irq(&info->io_lock);
info->connected = BLKIF_STATE_CONNECTED;
kick_pending_request_queues(info);
- spin_unlock_irq(&blkif_io_lock);
+ spin_unlock_irq(&info->io_lock);
add_disk(info->gd);
@@ -1410,7 +1409,6 @@ static int blkif_release(struct gendisk *disk, fmode_t mode)
mutex_lock(&blkfront_mutex);
bdev = bdget_disk(disk, 0);
- bdput(bdev);
if (bdev->bd_openers)
goto out;
@@ -1441,6 +1439,7 @@ static int blkif_release(struct gendisk *disk, fmode_t mode)
}
out:
+ bdput(bdev);
mutex_unlock(&blkfront_mutex);
return 0;
}
@@ -1475,7 +1474,7 @@ static int __init xlblk_init(void)
if (!xen_domain())
return -ENODEV;
- if (!xen_platform_pci_unplug)
+ if (xen_hvm_domain() && !xen_platform_pci_unplug)
return -ENODEV;
if (register_blkdev(XENVBD_MAJOR, DEV_NAME)) {
diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c
index 48442476ec00..ae9edca7b56d 100644
--- a/drivers/bluetooth/ath3k.c
+++ b/drivers/bluetooth/ath3k.c
@@ -72,7 +72,9 @@ static struct usb_device_id ath3k_table[] = {
/* Atheros AR3012 with sflash firmware*/
{ USB_DEVICE(0x0CF3, 0x3004) },
+ { USB_DEVICE(0x0CF3, 0x311D) },
{ USB_DEVICE(0x13d3, 0x3375) },
+ { USB_DEVICE(0x04CA, 0x3005) },
/* Atheros AR5BBU12 with sflash firmware */
{ USB_DEVICE(0x0489, 0xE02C) },
@@ -89,7 +91,9 @@ static struct usb_device_id ath3k_blist_tbl[] = {
/* Atheros AR3012 with sflash firmware*/
{ USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 },
+ { USB_DEVICE(0x0cf3, 0x311D), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
+ { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
{ } /* Terminating entry */
};
diff --git a/drivers/bluetooth/btmrvl_debugfs.c b/drivers/bluetooth/btmrvl_debugfs.c
index 6c20bbb54b71..428dbb7574bd 100644
--- a/drivers/bluetooth/btmrvl_debugfs.c
+++ b/drivers/bluetooth/btmrvl_debugfs.c
@@ -45,12 +45,6 @@ struct btmrvl_debugfs_data {
struct dentry *txdnldready;
};
-static int btmrvl_open_generic(struct inode *inode, struct file *file)
-{
- file->private_data = inode->i_private;
- return 0;
-}
-
static ssize_t btmrvl_hscfgcmd_write(struct file *file,
const char __user *ubuf, size_t count, loff_t *ppos)
{
@@ -93,7 +87,7 @@ static ssize_t btmrvl_hscfgcmd_read(struct file *file, char __user *userbuf,
static const struct file_operations btmrvl_hscfgcmd_fops = {
.read = btmrvl_hscfgcmd_read,
.write = btmrvl_hscfgcmd_write,
- .open = btmrvl_open_generic,
+ .open = simple_open,
.llseek = default_llseek,
};
@@ -134,7 +128,7 @@ static ssize_t btmrvl_psmode_read(struct file *file, char __user *userbuf,
static const struct file_operations btmrvl_psmode_fops = {
.read = btmrvl_psmode_read,
.write = btmrvl_psmode_write,
- .open = btmrvl_open_generic,
+ .open = simple_open,
.llseek = default_llseek,
};
@@ -180,7 +174,7 @@ static ssize_t btmrvl_pscmd_read(struct file *file, char __user *userbuf,
static const struct file_operations btmrvl_pscmd_fops = {
.read = btmrvl_pscmd_read,
.write = btmrvl_pscmd_write,
- .open = btmrvl_open_generic,
+ .open = simple_open,
.llseek = default_llseek,
};
@@ -221,7 +215,7 @@ static ssize_t btmrvl_gpiogap_read(struct file *file, char __user *userbuf,
static const struct file_operations btmrvl_gpiogap_fops = {
.read = btmrvl_gpiogap_read,
.write = btmrvl_gpiogap_write,
- .open = btmrvl_open_generic,
+ .open = simple_open,
.llseek = default_llseek,
};
@@ -265,7 +259,7 @@ static ssize_t btmrvl_hscmd_read(struct file *file, char __user *userbuf,
static const struct file_operations btmrvl_hscmd_fops = {
.read = btmrvl_hscmd_read,
.write = btmrvl_hscmd_write,
- .open = btmrvl_open_generic,
+ .open = simple_open,
.llseek = default_llseek,
};
@@ -305,7 +299,7 @@ static ssize_t btmrvl_hsmode_read(struct file *file, char __user * userbuf,
static const struct file_operations btmrvl_hsmode_fops = {
.read = btmrvl_hsmode_read,
.write = btmrvl_hsmode_write,
- .open = btmrvl_open_generic,
+ .open = simple_open,
.llseek = default_llseek,
};
@@ -323,7 +317,7 @@ static ssize_t btmrvl_curpsmode_read(struct file *file, char __user *userbuf,
static const struct file_operations btmrvl_curpsmode_fops = {
.read = btmrvl_curpsmode_read,
- .open = btmrvl_open_generic,
+ .open = simple_open,
.llseek = default_llseek,
};
@@ -341,7 +335,7 @@ static ssize_t btmrvl_psstate_read(struct file *file, char __user * userbuf,
static const struct file_operations btmrvl_psstate_fops = {
.read = btmrvl_psstate_read,
- .open = btmrvl_open_generic,
+ .open = simple_open,
.llseek = default_llseek,
};
@@ -359,7 +353,7 @@ static ssize_t btmrvl_hsstate_read(struct file *file, char __user *userbuf,
static const struct file_operations btmrvl_hsstate_fops = {
.read = btmrvl_hsstate_read,
- .open = btmrvl_open_generic,
+ .open = simple_open,
.llseek = default_llseek,
};
@@ -378,7 +372,7 @@ static ssize_t btmrvl_txdnldready_read(struct file *file, char __user *userbuf,
static const struct file_operations btmrvl_txdnldready_fops = {
.read = btmrvl_txdnldready_read,
- .open = btmrvl_open_generic,
+ .open = simple_open,
.llseek = default_llseek,
};
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 480cad920048..3311b812a0c6 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -61,7 +61,7 @@ static struct usb_device_id btusb_table[] = {
{ USB_DEVICE_INFO(0xe0, 0x01, 0x01) },
/* Broadcom SoftSailing reporting vendor specific */
- { USB_DEVICE(0x05ac, 0x21e1) },
+ { USB_DEVICE(0x0a5c, 0x21e1) },
/* Apple MacBookPro 7,1 */
{ USB_DEVICE(0x05ac, 0x8213) },
@@ -103,6 +103,7 @@ static struct usb_device_id btusb_table[] = {
/* Broadcom BCM20702A0 */
{ USB_DEVICE(0x0a5c, 0x21e3) },
{ USB_DEVICE(0x0a5c, 0x21e6) },
+ { USB_DEVICE(0x0a5c, 0x21e8) },
{ USB_DEVICE(0x0a5c, 0x21f3) },
{ USB_DEVICE(0x413c, 0x8197) },
@@ -129,7 +130,9 @@ static struct usb_device_id blacklist_table[] = {
/* Atheros 3012 with sflash firmware */
{ USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 },
+ { USB_DEVICE(0x0cf3, 0x311d), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
+ { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
/* Atheros AR5BBU12 with sflash firmware */
{ USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE },
diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c
index fd5adb408f44..98a8c05d4f23 100644
--- a/drivers/bluetooth/hci_ldisc.c
+++ b/drivers/bluetooth/hci_ldisc.c
@@ -299,11 +299,11 @@ static void hci_uart_tty_close(struct tty_struct *tty)
hci_uart_close(hdev);
if (test_and_clear_bit(HCI_UART_PROTO_SET, &hu->flags)) {
- hu->proto->close(hu);
if (hdev) {
hci_unregister_dev(hdev);
hci_free_dev(hdev);
}
+ hu->proto->close(hu);
}
kfree(hu);
diff --git a/drivers/char/apm-emulation.c b/drivers/char/apm-emulation.c
index 57501ca9204b..46118f845948 100644
--- a/drivers/char/apm-emulation.c
+++ b/drivers/char/apm-emulation.c
@@ -301,7 +301,7 @@ apm_ioctl(struct file *filp, u_int cmd, u_long arg)
* anything critical, chill a bit on each iteration.
*/
while (wait_event_freezable(apm_suspend_waitqueue,
- as->suspend_state == SUSPEND_DONE))
+ as->suspend_state != SUSPEND_ACKED))
msleep(10);
break;
case SUSPEND_ACKTO:
diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c
index 3845ab44c330..dfd7876f127c 100644
--- a/drivers/char/hpet.c
+++ b/drivers/char/hpet.c
@@ -906,8 +906,8 @@ int hpet_alloc(struct hpet_data *hdp)
hpetp->hp_which, hdp->hd_phys_address,
hpetp->hp_ntimer > 1 ? "s" : "");
for (i = 0; i < hpetp->hp_ntimer; i++)
- printk("%s %d", i > 0 ? "," : "", hdp->hd_irq[i]);
- printk("\n");
+ printk(KERN_CONT "%s %d", i > 0 ? "," : "", hdp->hd_irq[i]);
+ printk(KERN_CONT "\n");
temp = hpetp->hp_tick_freq;
remainder = do_div(temp, 1000000);
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 54ca8b23cde3..4ec04a754733 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -1260,10 +1260,15 @@ static int proc_do_uuid(ctl_table *table, int write,
uuid = table->data;
if (!uuid) {
uuid = tmp_uuid;
- uuid[8] = 0;
- }
- if (uuid[8] == 0)
generate_random_uuid(uuid);
+ } else {
+ static DEFINE_SPINLOCK(bootid_spinlock);
+
+ spin_lock(&bootid_spinlock);
+ if (!uuid[8])
+ generate_random_uuid(uuid);
+ spin_unlock(&bootid_spinlock);
+ }
sprintf(buf, "%pU", uuid);
diff --git a/drivers/char/tile-srom.c b/drivers/char/tile-srom.c
index 4dc019408fac..3b22a606f79d 100644
--- a/drivers/char/tile-srom.c
+++ b/drivers/char/tile-srom.c
@@ -194,17 +194,17 @@ static ssize_t srom_read(struct file *filp, char __user *buf,
hv_retval = _srom_read(srom->hv_devhdl, kernbuf,
*f_pos, bytes_this_pass);
- if (hv_retval > 0) {
- if (copy_to_user(buf, kernbuf, hv_retval) != 0) {
- retval = -EFAULT;
- break;
- }
- } else if (hv_retval <= 0) {
+ if (hv_retval <= 0) {
if (retval == 0)
retval = hv_retval;
break;
}
+ if (copy_to_user(buf, kernbuf, hv_retval) != 0) {
+ retval = -EFAULT;
+ break;
+ }
+
retval += hv_retval;
*f_pos += hv_retval;
buf += hv_retval;
diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
index b58b56187065..ddf86b6500b7 100644
--- a/drivers/char/virtio_console.c
+++ b/drivers/char/virtio_console.c
@@ -1038,12 +1038,6 @@ static struct attribute_group port_attribute_group = {
.attrs = port_sysfs_entries,
};
-static int debugfs_open(struct inode *inode, struct file *filp)
-{
- filp->private_data = inode->i_private;
- return 0;
-}
-
static ssize_t debugfs_read(struct file *filp, char __user *ubuf,
size_t count, loff_t *offp)
{
@@ -1087,7 +1081,7 @@ static ssize_t debugfs_read(struct file *filp, char __user *ubuf,
static const struct file_operations port_debugfs_ops = {
.owner = THIS_MODULE,
- .open = debugfs_open,
+ .open = simple_open,
.read = debugfs_read,
};
diff --git a/drivers/clocksource/acpi_pm.c b/drivers/clocksource/acpi_pm.c
index 82e882028fcf..6b5cf02c35c8 100644
--- a/drivers/clocksource/acpi_pm.c
+++ b/drivers/clocksource/acpi_pm.c
@@ -23,7 +23,6 @@
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/delay.h>
-#include <linux/async.h>
#include <asm/io.h>
/*
@@ -180,15 +179,17 @@ static int verify_pmtmr_rate(void)
/* Number of reads we try to get two different values */
#define ACPI_PM_READ_CHECKS 10000
-static void __init acpi_pm_clocksource_async(void *unused, async_cookie_t cookie)
+static int __init init_acpi_pm_clocksource(void)
{
cycle_t value1, value2;
unsigned int i, j = 0;
+ if (!pmtmr_ioport)
+ return -ENODEV;
/* "verify" this timing source: */
for (j = 0; j < ACPI_PM_MONOTONICITY_CHECKS; j++) {
- usleep_range(100 * j, 100 * j + 100);
+ udelay(100 * j);
value1 = clocksource_acpi_pm.read(&clocksource_acpi_pm);
for (i = 0; i < ACPI_PM_READ_CHECKS; i++) {
value2 = clocksource_acpi_pm.read(&clocksource_acpi_pm);
@@ -202,34 +203,25 @@ static void __init acpi_pm_clocksource_async(void *unused, async_cookie_t cookie
" 0x%#llx, 0x%#llx - aborting.\n",
value1, value2);
pmtmr_ioport = 0;
- return;
+ return -EINVAL;
}
if (i == ACPI_PM_READ_CHECKS) {
printk(KERN_INFO "PM-Timer failed consistency check "
" (0x%#llx) - aborting.\n", value1);
pmtmr_ioport = 0;
- return;
+ return -ENODEV;
}
}
if (verify_pmtmr_rate() != 0){
pmtmr_ioport = 0;
- return;
+ return -ENODEV;
}
- clocksource_register_hz(&clocksource_acpi_pm,
+ return clocksource_register_hz(&clocksource_acpi_pm,
PMTMR_TICKS_PER_SEC);
}
-static int __init init_acpi_pm_clocksource(void)
-{
- if (!pmtmr_ioport)
- return -ENODEV;
-
- async_schedule(acpi_pm_clocksource_async, NULL);
- return 0;
-}
-
/* We use fs_initcall because we want the PCI fixups to have run
* but we still need to load before device_initcall
*/
diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
index 32d790dd8180..5961e6415f08 100644
--- a/drivers/cpufreq/Kconfig.arm
+++ b/drivers/cpufreq/Kconfig.arm
@@ -4,6 +4,7 @@
config ARM_OMAP2PLUS_CPUFREQ
bool "TI OMAP2+"
+ depends on ARCH_OMAP2PLUS
default ARCH_OMAP2PLUS
select CPU_FREQ_TABLE
@@ -51,9 +52,6 @@ config ARM_S5PV210_CPUFREQ
config ARM_EXYNOS_CPUFREQ
bool "SAMSUNG EXYNOS SoCs"
depends on ARCH_EXYNOS
- select ARM_EXYNOS4210_CPUFREQ if CPU_EXYNOS4210
- select ARM_EXYNOS4X12_CPUFREQ if (SOC_EXYNOS4212 || SOC_EXYNOS4412)
- select ARM_EXYNOS5250_CPUFREQ if SOC_EXYNOS5250
default y
help
This adds the CPUFreq driver common part for Samsung
@@ -62,20 +60,19 @@ config ARM_EXYNOS_CPUFREQ
If in doubt, say N.
config ARM_EXYNOS4210_CPUFREQ
- bool "Samsung EXYNOS4210"
- depends on ARCH_EXYNOS
+ def_bool CPU_EXYNOS4210
help
This adds the CPUFreq driver for Samsung EXYNOS4210
SoC (S5PV310 or S5PC210).
config ARM_EXYNOS4X12_CPUFREQ
- bool "Samsung EXYNOS4X12"
+ def_bool (SOC_EXYNOS4212 || SOC_EXYNOS4412)
help
This adds the CPUFreq driver for Samsung EXYNOS4X12
SoC (EXYNOS4212 or EXYNOS4412).
config ARM_EXYNOS5250_CPUFREQ
- bool "Samsung EXYNOS5250"
+ def_bool SOC_EXYNOS5250
help
This adds the CPUFreq driver for Samsung EXYNOS5250
SoC.
diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
index 87411cebc577..2f0083a51a9a 100644
--- a/drivers/cpuidle/cpuidle.c
+++ b/drivers/cpuidle/cpuidle.c
@@ -74,7 +74,7 @@ static cpuidle_enter_t cpuidle_enter_ops;
/**
* cpuidle_play_dead - cpu off-lining
*
- * Only returns in case of an error
+ * Returns in case of an error or no driver
*/
int cpuidle_play_dead(void)
{
@@ -83,6 +83,9 @@ int cpuidle_play_dead(void)
int i, dead_state = -1;
int power_usage = -1;
+ if (!drv)
+ return -ENODEV;
+
/* Find lowest-power state that supports long-term idle */
for (i = CPUIDLE_DRIVER_STATE_START; i < drv->state_count; i++) {
struct cpuidle_state *s = &drv->states[i];
diff --git a/drivers/crypto/ixp4xx_crypto.c b/drivers/crypto/ixp4xx_crypto.c
index 0053d7ebb5ca..8f3f74ce8c7f 100644
--- a/drivers/crypto/ixp4xx_crypto.c
+++ b/drivers/crypto/ixp4xx_crypto.c
@@ -18,6 +18,7 @@
#include <linux/interrupt.h>
#include <linux/spinlock.h>
#include <linux/gfp.h>
+#include <linux/module.h>
#include <crypto/ctr.h>
#include <crypto/des.h>
diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index dc641c796526..921039e56f87 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -124,6 +124,9 @@ struct talitos_private {
void __iomem *reg;
int irq[2];
+ /* SEC global registers lock */
+ spinlock_t reg_lock ____cacheline_aligned;
+
/* SEC version geometry (from device tree node) */
unsigned int num_channels;
unsigned int chfifo_len;
@@ -412,6 +415,7 @@ static void talitos_done_##name(unsigned long data) \
{ \
struct device *dev = (struct device *)data; \
struct talitos_private *priv = dev_get_drvdata(dev); \
+ unsigned long flags; \
\
if (ch_done_mask & 1) \
flush_channel(dev, 0, 0, 0); \
@@ -427,8 +431,10 @@ static void talitos_done_##name(unsigned long data) \
out: \
/* At this point, all completed channels have been processed */ \
/* Unmask done interrupts for channels completed later on. */ \
+ spin_lock_irqsave(&priv->reg_lock, flags); \
setbits32(priv->reg + TALITOS_IMR, ch_done_mask); \
setbits32(priv->reg + TALITOS_IMR_LO, TALITOS_IMR_LO_INIT); \
+ spin_unlock_irqrestore(&priv->reg_lock, flags); \
}
DEF_TALITOS_DONE(4ch, TALITOS_ISR_4CHDONE)
DEF_TALITOS_DONE(ch0_2, TALITOS_ISR_CH_0_2_DONE)
@@ -619,22 +625,28 @@ static irqreturn_t talitos_interrupt_##name(int irq, void *data) \
struct device *dev = data; \
struct talitos_private *priv = dev_get_drvdata(dev); \
u32 isr, isr_lo; \
+ unsigned long flags; \
\
+ spin_lock_irqsave(&priv->reg_lock, flags); \
isr = in_be32(priv->reg + TALITOS_ISR); \
isr_lo = in_be32(priv->reg + TALITOS_ISR_LO); \
/* Acknowledge interrupt */ \
out_be32(priv->reg + TALITOS_ICR, isr & (ch_done_mask | ch_err_mask)); \
out_be32(priv->reg + TALITOS_ICR_LO, isr_lo); \
\
- if (unlikely((isr & ~TALITOS_ISR_4CHDONE) & ch_err_mask || isr_lo)) \
- talitos_error(dev, isr, isr_lo); \
- else \
+ if (unlikely(isr & ch_err_mask || isr_lo)) { \
+ spin_unlock_irqrestore(&priv->reg_lock, flags); \
+ talitos_error(dev, isr & ch_err_mask, isr_lo); \
+ } \
+ else { \
if (likely(isr & ch_done_mask)) { \
/* mask further done interrupts. */ \
clrbits32(priv->reg + TALITOS_IMR, ch_done_mask); \
/* done_task will unmask done interrupts at exit */ \
tasklet_schedule(&priv->done_task[tlet]); \
} \
+ spin_unlock_irqrestore(&priv->reg_lock, flags); \
+ } \
\
return (isr & (ch_done_mask | ch_err_mask) || isr_lo) ? IRQ_HANDLED : \
IRQ_NONE; \
@@ -2719,6 +2731,8 @@ static int talitos_probe(struct platform_device *ofdev)
priv->ofdev = ofdev;
+ spin_lock_init(&priv->reg_lock);
+
err = talitos_probe_irq(ofdev);
if (err)
goto err_out;
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index cf9da362d64f..ef378b5b17e4 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -91,11 +91,10 @@ config DW_DMAC
config AT_HDMAC
tristate "Atmel AHB DMA support"
- depends on ARCH_AT91SAM9RL || ARCH_AT91SAM9G45
+ depends on ARCH_AT91
select DMA_ENGINE
help
- Support the Atmel AHB DMA controller. This can be integrated in
- chips such as the Atmel AT91SAM9RL.
+ Support the Atmel AHB DMA controller.
config FSL_DMA
tristate "Freescale Elo and Elo Plus DMA support"
diff --git a/drivers/dma/coh901318.c b/drivers/dma/coh901318.c
index dc89455f5550..750925f9638b 100644
--- a/drivers/dma/coh901318.c
+++ b/drivers/dma/coh901318.c
@@ -104,13 +104,6 @@ static void coh901318_list_print(struct coh901318_chan *cohc,
static struct coh901318_base *debugfs_dma_base;
static struct dentry *dma_dentry;
-static int coh901318_debugfs_open(struct inode *inode, struct file *file)
-{
-
- file->private_data = inode->i_private;
- return 0;
-}
-
static int coh901318_debugfs_read(struct file *file, char __user *buf,
size_t count, loff_t *f_pos)
{
@@ -158,7 +151,7 @@ static int coh901318_debugfs_read(struct file *file, char __user *buf,
static const struct file_operations coh901318_debugfs_status_operations = {
.owner = THIS_MODULE,
- .open = coh901318_debugfs_open,
+ .open = simple_open,
.read = coh901318_debugfs_read,
.llseek = default_llseek,
};
diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
index 767bcc31b365..2397f6f451b1 100644
--- a/drivers/dma/dmaengine.c
+++ b/drivers/dma/dmaengine.c
@@ -332,6 +332,20 @@ struct dma_chan *dma_find_channel(enum dma_transaction_type tx_type)
}
EXPORT_SYMBOL(dma_find_channel);
+/*
+ * net_dma_find_channel - find a channel for net_dma
+ * net_dma has alignment requirements
+ */
+struct dma_chan *net_dma_find_channel(void)
+{
+ struct dma_chan *chan = dma_find_channel(DMA_MEMCPY);
+ if (chan && !is_dma_copy_aligned(chan->device, 1, 1, 1))
+ return NULL;
+
+ return chan;
+}
+EXPORT_SYMBOL(net_dma_find_channel);
+
/**
* dma_issue_pending_all - flush all pending operations across all channels
*/
diff --git a/drivers/dma/ioat/dma.c b/drivers/dma/ioat/dma.c
index 31493d80e0e9..73b2b65cb1de 100644
--- a/drivers/dma/ioat/dma.c
+++ b/drivers/dma/ioat/dma.c
@@ -546,9 +546,9 @@ void ioat_dma_unmap(struct ioat_chan_common *chan, enum dma_ctrl_flags flags,
PCI_DMA_TODEVICE, flags, 0);
}
-unsigned long ioat_get_current_completion(struct ioat_chan_common *chan)
+dma_addr_t ioat_get_current_completion(struct ioat_chan_common *chan)
{
- unsigned long phys_complete;
+ dma_addr_t phys_complete;
u64 completion;
completion = *chan->completion;
@@ -569,7 +569,7 @@ unsigned long ioat_get_current_completion(struct ioat_chan_common *chan)
}
bool ioat_cleanup_preamble(struct ioat_chan_common *chan,
- unsigned long *phys_complete)
+ dma_addr_t *phys_complete)
{
*phys_complete = ioat_get_current_completion(chan);
if (*phys_complete == chan->last_completion)
@@ -580,14 +580,14 @@ bool ioat_cleanup_preamble(struct ioat_chan_common *chan,
return true;
}
-static void __cleanup(struct ioat_dma_chan *ioat, unsigned long phys_complete)
+static void __cleanup(struct ioat_dma_chan *ioat, dma_addr_t phys_complete)
{
struct ioat_chan_common *chan = &ioat->base;
struct list_head *_desc, *n;
struct dma_async_tx_descriptor *tx;
- dev_dbg(to_dev(chan), "%s: phys_complete: %lx\n",
- __func__, phys_complete);
+ dev_dbg(to_dev(chan), "%s: phys_complete: %llx\n",
+ __func__, (unsigned long long) phys_complete);
list_for_each_safe(_desc, n, &ioat->used_desc) {
struct ioat_desc_sw *desc;
@@ -652,7 +652,7 @@ static void __cleanup(struct ioat_dma_chan *ioat, unsigned long phys_complete)
static void ioat1_cleanup(struct ioat_dma_chan *ioat)
{
struct ioat_chan_common *chan = &ioat->base;
- unsigned long phys_complete;
+ dma_addr_t phys_complete;
prefetch(chan->completion);
@@ -698,7 +698,7 @@ static void ioat1_timer_event(unsigned long data)
mod_timer(&chan->timer, jiffies + COMPLETION_TIMEOUT);
spin_unlock_bh(&ioat->desc_lock);
} else if (test_bit(IOAT_COMPLETION_PENDING, &chan->state)) {
- unsigned long phys_complete;
+ dma_addr_t phys_complete;
spin_lock_bh(&ioat->desc_lock);
/* if we haven't made progress and we have already
diff --git a/drivers/dma/ioat/dma.h b/drivers/dma/ioat/dma.h
index c7888bccd974..5e8fe01ba69d 100644
--- a/drivers/dma/ioat/dma.h
+++ b/drivers/dma/ioat/dma.h
@@ -88,7 +88,7 @@ struct ioatdma_device {
struct ioat_chan_common {
struct dma_chan common;
void __iomem *reg_base;
- unsigned long last_completion;
+ dma_addr_t last_completion;
spinlock_t cleanup_lock;
unsigned long state;
#define IOAT_COMPLETION_PENDING 0
@@ -310,7 +310,7 @@ int __devinit ioat_dma_self_test(struct ioatdma_device *device);
void __devexit ioat_dma_remove(struct ioatdma_device *device);
struct dca_provider * __devinit ioat_dca_init(struct pci_dev *pdev,
void __iomem *iobase);
-unsigned long ioat_get_current_completion(struct ioat_chan_common *chan);
+dma_addr_t ioat_get_current_completion(struct ioat_chan_common *chan);
void ioat_init_channel(struct ioatdma_device *device,
struct ioat_chan_common *chan, int idx);
enum dma_status ioat_dma_tx_status(struct dma_chan *c, dma_cookie_t cookie,
@@ -318,7 +318,7 @@ enum dma_status ioat_dma_tx_status(struct dma_chan *c, dma_cookie_t cookie,
void ioat_dma_unmap(struct ioat_chan_common *chan, enum dma_ctrl_flags flags,
size_t len, struct ioat_dma_descriptor *hw);
bool ioat_cleanup_preamble(struct ioat_chan_common *chan,
- unsigned long *phys_complete);
+ dma_addr_t *phys_complete);
void ioat_kobject_add(struct ioatdma_device *device, struct kobj_type *type);
void ioat_kobject_del(struct ioatdma_device *device);
extern const struct sysfs_ops ioat_sysfs_ops;
diff --git a/drivers/dma/ioat/dma_v2.c b/drivers/dma/ioat/dma_v2.c
index e8e110ff3d96..86895760b598 100644
--- a/drivers/dma/ioat/dma_v2.c
+++ b/drivers/dma/ioat/dma_v2.c
@@ -128,7 +128,7 @@ static void ioat2_start_null_desc(struct ioat2_dma_chan *ioat)
spin_unlock_bh(&ioat->prep_lock);
}
-static void __cleanup(struct ioat2_dma_chan *ioat, unsigned long phys_complete)
+static void __cleanup(struct ioat2_dma_chan *ioat, dma_addr_t phys_complete)
{
struct ioat_chan_common *chan = &ioat->base;
struct dma_async_tx_descriptor *tx;
@@ -179,7 +179,7 @@ static void __cleanup(struct ioat2_dma_chan *ioat, unsigned long phys_complete)
static void ioat2_cleanup(struct ioat2_dma_chan *ioat)
{
struct ioat_chan_common *chan = &ioat->base;
- unsigned long phys_complete;
+ dma_addr_t phys_complete;
spin_lock_bh(&chan->cleanup_lock);
if (ioat_cleanup_preamble(chan, &phys_complete))
@@ -260,7 +260,7 @@ int ioat2_reset_sync(struct ioat_chan_common *chan, unsigned long tmo)
static void ioat2_restart_channel(struct ioat2_dma_chan *ioat)
{
struct ioat_chan_common *chan = &ioat->base;
- unsigned long phys_complete;
+ dma_addr_t phys_complete;
ioat2_quiesce(chan, 0);
if (ioat_cleanup_preamble(chan, &phys_complete))
@@ -275,7 +275,7 @@ void ioat2_timer_event(unsigned long data)
struct ioat_chan_common *chan = &ioat->base;
if (test_bit(IOAT_COMPLETION_PENDING, &chan->state)) {
- unsigned long phys_complete;
+ dma_addr_t phys_complete;
u64 status;
status = ioat_chansts(chan);
@@ -572,9 +572,9 @@ bool reshape_ring(struct ioat2_dma_chan *ioat, int order)
*/
struct ioat_chan_common *chan = &ioat->base;
struct dma_chan *c = &chan->common;
- const u16 curr_size = ioat2_ring_size(ioat);
+ const u32 curr_size = ioat2_ring_size(ioat);
const u16 active = ioat2_ring_active(ioat);
- const u16 new_size = 1 << order;
+ const u32 new_size = 1 << order;
struct ioat_ring_ent **ring;
u16 i;
diff --git a/drivers/dma/ioat/dma_v2.h b/drivers/dma/ioat/dma_v2.h
index a2c413b2b8d8..be2a55b95c23 100644
--- a/drivers/dma/ioat/dma_v2.h
+++ b/drivers/dma/ioat/dma_v2.h
@@ -74,7 +74,7 @@ static inline struct ioat2_dma_chan *to_ioat2_chan(struct dma_chan *c)
return container_of(chan, struct ioat2_dma_chan, base);
}
-static inline u16 ioat2_ring_size(struct ioat2_dma_chan *ioat)
+static inline u32 ioat2_ring_size(struct ioat2_dma_chan *ioat)
{
return 1 << ioat->alloc_order;
}
@@ -91,7 +91,7 @@ static inline u16 ioat2_ring_pending(struct ioat2_dma_chan *ioat)
return CIRC_CNT(ioat->head, ioat->issued, ioat2_ring_size(ioat));
}
-static inline u16 ioat2_ring_space(struct ioat2_dma_chan *ioat)
+static inline u32 ioat2_ring_space(struct ioat2_dma_chan *ioat)
{
return ioat2_ring_size(ioat) - ioat2_ring_active(ioat);
}
diff --git a/drivers/dma/ioat/dma_v3.c b/drivers/dma/ioat/dma_v3.c
index 2c4476c0e405..f7f1dc62c15c 100644
--- a/drivers/dma/ioat/dma_v3.c
+++ b/drivers/dma/ioat/dma_v3.c
@@ -257,7 +257,7 @@ static bool desc_has_ext(struct ioat_ring_ent *desc)
* The difference from the dma_v2.c __cleanup() is that this routine
* handles extended descriptors and dma-unmapping raid operations.
*/
-static void __cleanup(struct ioat2_dma_chan *ioat, unsigned long phys_complete)
+static void __cleanup(struct ioat2_dma_chan *ioat, dma_addr_t phys_complete)
{
struct ioat_chan_common *chan = &ioat->base;
struct ioat_ring_ent *desc;
@@ -314,7 +314,7 @@ static void __cleanup(struct ioat2_dma_chan *ioat, unsigned long phys_complete)
static void ioat3_cleanup(struct ioat2_dma_chan *ioat)
{
struct ioat_chan_common *chan = &ioat->base;
- unsigned long phys_complete;
+ dma_addr_t phys_complete;
spin_lock_bh(&chan->cleanup_lock);
if (ioat_cleanup_preamble(chan, &phys_complete))
@@ -333,7 +333,7 @@ static void ioat3_cleanup_event(unsigned long data)
static void ioat3_restart_channel(struct ioat2_dma_chan *ioat)
{
struct ioat_chan_common *chan = &ioat->base;
- unsigned long phys_complete;
+ dma_addr_t phys_complete;
ioat2_quiesce(chan, 0);
if (ioat_cleanup_preamble(chan, &phys_complete))
@@ -348,7 +348,7 @@ static void ioat3_timer_event(unsigned long data)
struct ioat_chan_common *chan = &ioat->base;
if (test_bit(IOAT_COMPLETION_PENDING, &chan->state)) {
- unsigned long phys_complete;
+ dma_addr_t phys_complete;
u64 status;
status = ioat_chansts(chan);
@@ -1149,6 +1149,44 @@ static int ioat3_reset_hw(struct ioat_chan_common *chan)
return ioat2_reset_sync(chan, msecs_to_jiffies(200));
}
+static bool is_jf_ioat(struct pci_dev *pdev)
+{
+ switch (pdev->device) {
+ case PCI_DEVICE_ID_INTEL_IOAT_JSF0:
+ case PCI_DEVICE_ID_INTEL_IOAT_JSF1:
+ case PCI_DEVICE_ID_INTEL_IOAT_JSF2:
+ case PCI_DEVICE_ID_INTEL_IOAT_JSF3:
+ case PCI_DEVICE_ID_INTEL_IOAT_JSF4:
+ case PCI_DEVICE_ID_INTEL_IOAT_JSF5:
+ case PCI_DEVICE_ID_INTEL_IOAT_JSF6:
+ case PCI_DEVICE_ID_INTEL_IOAT_JSF7:
+ case PCI_DEVICE_ID_INTEL_IOAT_JSF8:
+ case PCI_DEVICE_ID_INTEL_IOAT_JSF9:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static bool is_snb_ioat(struct pci_dev *pdev)
+{
+ switch (pdev->device) {
+ case PCI_DEVICE_ID_INTEL_IOAT_SNB0:
+ case PCI_DEVICE_ID_INTEL_IOAT_SNB1:
+ case PCI_DEVICE_ID_INTEL_IOAT_SNB2:
+ case PCI_DEVICE_ID_INTEL_IOAT_SNB3:
+ case PCI_DEVICE_ID_INTEL_IOAT_SNB4:
+ case PCI_DEVICE_ID_INTEL_IOAT_SNB5:
+ case PCI_DEVICE_ID_INTEL_IOAT_SNB6:
+ case PCI_DEVICE_ID_INTEL_IOAT_SNB7:
+ case PCI_DEVICE_ID_INTEL_IOAT_SNB8:
+ case PCI_DEVICE_ID_INTEL_IOAT_SNB9:
+ return true;
+ default:
+ return false;
+ }
+}
+
int __devinit ioat3_dma_probe(struct ioatdma_device *device, int dca)
{
struct pci_dev *pdev = device->pdev;
@@ -1169,6 +1207,9 @@ int __devinit ioat3_dma_probe(struct ioatdma_device *device, int dca)
dma->device_alloc_chan_resources = ioat2_alloc_chan_resources;
dma->device_free_chan_resources = ioat2_free_chan_resources;
+ if (is_jf_ioat(pdev) || is_snb_ioat(pdev))
+ dma->copy_align = 6;
+
dma_cap_set(DMA_INTERRUPT, dma->cap_mask);
dma->device_prep_dma_interrupt = ioat3_prep_interrupt_lock;
diff --git a/drivers/dma/iop-adma.c b/drivers/dma/iop-adma.c
index da6c4c2c066a..79e3eba29702 100644
--- a/drivers/dma/iop-adma.c
+++ b/drivers/dma/iop-adma.c
@@ -1252,8 +1252,8 @@ iop_adma_pq_zero_sum_self_test(struct iop_adma_device *device)
struct page **pq_hw = &pq[IOP_ADMA_NUM_SRC_TEST+2];
/* address conversion buffers (dma_map / page_address) */
void *pq_sw[IOP_ADMA_NUM_SRC_TEST+2];
- dma_addr_t pq_src[IOP_ADMA_NUM_SRC_TEST];
- dma_addr_t pq_dest[2];
+ dma_addr_t pq_src[IOP_ADMA_NUM_SRC_TEST+2];
+ dma_addr_t *pq_dest = &pq_src[IOP_ADMA_NUM_SRC_TEST];
int i;
struct dma_async_tx_descriptor *tx;
diff --git a/drivers/edac/tile_edac.c b/drivers/edac/tile_edac.c
index 1d5cf06f6c6b..e99d00976189 100644
--- a/drivers/edac/tile_edac.c
+++ b/drivers/edac/tile_edac.c
@@ -145,7 +145,11 @@ static int __devinit tile_edac_mc_probe(struct platform_device *pdev)
mci->edac_ctl_cap = EDAC_FLAG_SECDED;
mci->mod_name = DRV_NAME;
+#ifdef __tilegx__
+ mci->ctl_name = "TILEGx_Memory_Controller";
+#else
mci->ctl_name = "TILEPro_Memory_Controller";
+#endif
mci->dev_name = dev_name(&pdev->dev);
mci->edac_check = tile_edac_check;
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index edadbdad31d0..e03653d69357 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -430,7 +430,7 @@ config GPIO_ML_IOH
config GPIO_SODAVILLE
bool "Intel Sodaville GPIO support"
- depends on X86 && PCI && OF && BROKEN
+ depends on X86 && PCI && OF
select GPIO_GENERIC
select GENERIC_IRQ_CHIP
help
diff --git a/drivers/gpio/gpio-adp5588.c b/drivers/gpio/gpio-adp5588.c
index 9ad1703d1408..ae5d7f12ce66 100644
--- a/drivers/gpio/gpio-adp5588.c
+++ b/drivers/gpio/gpio-adp5588.c
@@ -252,7 +252,7 @@ static irqreturn_t adp5588_irq_handler(int irq, void *devid)
if (ret < 0)
memset(dev->irq_stat, 0, ARRAY_SIZE(dev->irq_stat));
- for (bank = 0; bank <= ADP5588_BANK(ADP5588_MAXGPIO);
+ for (bank = 0, bit = 0; bank <= ADP5588_BANK(ADP5588_MAXGPIO);
bank++, bit = 0) {
pending = dev->irq_stat[bank] & dev->irq_mask[bank];
diff --git a/drivers/gpio/gpio-samsung.c b/drivers/gpio/gpio-samsung.c
index 46277877b7ec..19d6fc0229c3 100644
--- a/drivers/gpio/gpio-samsung.c
+++ b/drivers/gpio/gpio-samsung.c
@@ -2382,8 +2382,8 @@ static struct samsung_gpio_chip exynos4_gpios_3[] = {
#endif
};
-static struct samsung_gpio_chip exynos5_gpios_1[] = {
#ifdef CONFIG_ARCH_EXYNOS5
+static struct samsung_gpio_chip exynos5_gpios_1[] = {
{
.chip = {
.base = EXYNOS5_GPA0(0),
@@ -2541,11 +2541,11 @@ static struct samsung_gpio_chip exynos5_gpios_1[] = {
.to_irq = samsung_gpiolib_to_irq,
},
},
-#endif
};
+#endif
-static struct samsung_gpio_chip exynos5_gpios_2[] = {
#ifdef CONFIG_ARCH_EXYNOS5
+static struct samsung_gpio_chip exynos5_gpios_2[] = {
{
.chip = {
.base = EXYNOS5_GPE0(0),
@@ -2602,11 +2602,11 @@ static struct samsung_gpio_chip exynos5_gpios_2[] = {
},
},
-#endif
};
+#endif
-static struct samsung_gpio_chip exynos5_gpios_3[] = {
#ifdef CONFIG_ARCH_EXYNOS5
+static struct samsung_gpio_chip exynos5_gpios_3[] = {
{
.chip = {
.base = EXYNOS5_GPV0(0),
@@ -2638,11 +2638,11 @@ static struct samsung_gpio_chip exynos5_gpios_3[] = {
.label = "GPV4",
},
},
-#endif
};
+#endif
-static struct samsung_gpio_chip exynos5_gpios_4[] = {
#ifdef CONFIG_ARCH_EXYNOS5
+static struct samsung_gpio_chip exynos5_gpios_4[] = {
{
.chip = {
.base = EXYNOS5_GPZ(0),
@@ -2650,8 +2650,8 @@ static struct samsung_gpio_chip exynos5_gpios_4[] = {
.label = "GPZ",
},
},
-#endif
};
+#endif
#if defined(CONFIG_ARCH_EXYNOS) && defined(CONFIG_OF)
diff --git a/drivers/gpio/gpio-sodaville.c b/drivers/gpio/gpio-sodaville.c
index 9ba15d31d242..031e5d24837d 100644
--- a/drivers/gpio/gpio-sodaville.c
+++ b/drivers/gpio/gpio-sodaville.c
@@ -41,7 +41,7 @@
struct sdv_gpio_chip_data {
int irq_base;
void __iomem *gpio_pub_base;
- struct irq_domain id;
+ struct irq_domain *id;
struct irq_chip_generic *gc;
struct bgpio_chip bgpio;
};
@@ -51,10 +51,9 @@ static int sdv_gpio_pub_set_type(struct irq_data *d, unsigned int type)
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
struct sdv_gpio_chip_data *sd = gc->private;
void __iomem *type_reg;
- u32 irq_offs = d->irq - sd->irq_base;
u32 reg;
- if (irq_offs < 8)
+ if (d->hwirq < 8)
type_reg = sd->gpio_pub_base + GPIT1R0;
else
type_reg = sd->gpio_pub_base + GPIT1R1;
@@ -63,11 +62,11 @@ static int sdv_gpio_pub_set_type(struct irq_data *d, unsigned int type)
switch (type) {
case IRQ_TYPE_LEVEL_HIGH:
- reg &= ~BIT(4 * (irq_offs % 8));
+ reg &= ~BIT(4 * (d->hwirq % 8));
break;
case IRQ_TYPE_LEVEL_LOW:
- reg |= BIT(4 * (irq_offs % 8));
+ reg |= BIT(4 * (d->hwirq % 8));
break;
default:
@@ -91,7 +90,7 @@ static irqreturn_t sdv_gpio_pub_irq_handler(int irq, void *data)
u32 irq_bit = __fls(irq_stat);
irq_stat &= ~BIT(irq_bit);
- generic_handle_irq(sd->irq_base + irq_bit);
+ generic_handle_irq(irq_find_mapping(sd->id, irq_bit));
}
return IRQ_HANDLED;
@@ -127,7 +126,7 @@ static int sdv_xlate(struct irq_domain *h, struct device_node *node,
}
static struct irq_domain_ops irq_domain_sdv_ops = {
- .dt_translate = sdv_xlate,
+ .xlate = sdv_xlate,
};
static __devinit int sdv_register_irqsupport(struct sdv_gpio_chip_data *sd,
@@ -149,10 +148,6 @@ static __devinit int sdv_register_irqsupport(struct sdv_gpio_chip_data *sd,
if (ret)
goto out_free_desc;
- sd->id.irq_base = sd->irq_base;
- sd->id.of_node = of_node_get(pdev->dev.of_node);
- sd->id.ops = &irq_domain_sdv_ops;
-
/*
* This gpio irq controller latches level irqs. Testing shows that if
* we unmask & ACK the IRQ before the source of the interrupt is gone
@@ -179,7 +174,10 @@ static __devinit int sdv_register_irqsupport(struct sdv_gpio_chip_data *sd,
IRQ_GC_INIT_MASK_CACHE, IRQ_NOREQUEST,
IRQ_LEVEL | IRQ_NOPROBE);
- irq_domain_add(&sd->id);
+ sd->id = irq_domain_add_legacy(pdev->dev.of_node, SDV_NUM_PUB_GPIOS,
+ sd->irq_base, 0, &irq_domain_sdv_ops, sd);
+ if (!sd->id)
+ goto out_free_irq;
return 0;
out_free_irq:
free_irq(pdev->irq, sd);
@@ -260,7 +258,6 @@ static void sdv_gpio_remove(struct pci_dev *pdev)
{
struct sdv_gpio_chip_data *sd = pci_get_drvdata(pdev);
- irq_domain_del(&sd->id);
free_irq(pdev->irq, sd);
irq_free_descs(sd->irq_base, SDV_NUM_PUB_GPIOS);
diff --git a/drivers/gpio/gpio-tegra.c b/drivers/gpio/gpio-tegra.c
index 32de6707e3c4..12f349b3830d 100644
--- a/drivers/gpio/gpio-tegra.c
+++ b/drivers/gpio/gpio-tegra.c
@@ -22,7 +22,7 @@
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/gpio.h>
-#include <linux/of.h>
+#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/module.h>
#include <linux/irqdomain.h>
@@ -37,7 +37,8 @@
#define GPIO_PORT(x) (((x) >> 3) & 0x3)
#define GPIO_BIT(x) ((x) & 0x7)
-#define GPIO_REG(x) (GPIO_BANK(x) * 0x80 + GPIO_PORT(x) * 4)
+#define GPIO_REG(x) (GPIO_BANK(x) * tegra_gpio_bank_stride + \
+ GPIO_PORT(x) * 4)
#define GPIO_CNF(x) (GPIO_REG(x) + 0x00)
#define GPIO_OE(x) (GPIO_REG(x) + 0x10)
@@ -48,12 +49,12 @@
#define GPIO_INT_LVL(x) (GPIO_REG(x) + 0x60)
#define GPIO_INT_CLR(x) (GPIO_REG(x) + 0x70)
-#define GPIO_MSK_CNF(x) (GPIO_REG(x) + 0x800)
-#define GPIO_MSK_OE(x) (GPIO_REG(x) + 0x810)
-#define GPIO_MSK_OUT(x) (GPIO_REG(x) + 0X820)
-#define GPIO_MSK_INT_STA(x) (GPIO_REG(x) + 0x840)
-#define GPIO_MSK_INT_ENB(x) (GPIO_REG(x) + 0x850)
-#define GPIO_MSK_INT_LVL(x) (GPIO_REG(x) + 0x860)
+#define GPIO_MSK_CNF(x) (GPIO_REG(x) + tegra_gpio_upper_offset + 0x00)
+#define GPIO_MSK_OE(x) (GPIO_REG(x) + tegra_gpio_upper_offset + 0x10)
+#define GPIO_MSK_OUT(x) (GPIO_REG(x) + tegra_gpio_upper_offset + 0X20)
+#define GPIO_MSK_INT_STA(x) (GPIO_REG(x) + tegra_gpio_upper_offset + 0x40)
+#define GPIO_MSK_INT_ENB(x) (GPIO_REG(x) + tegra_gpio_upper_offset + 0x50)
+#define GPIO_MSK_INT_LVL(x) (GPIO_REG(x) + tegra_gpio_upper_offset + 0x60)
#define GPIO_INT_LVL_MASK 0x010101
#define GPIO_INT_LVL_EDGE_RISING 0x000101
@@ -78,6 +79,8 @@ struct tegra_gpio_bank {
static struct irq_domain *irq_domain;
static void __iomem *regs;
static u32 tegra_gpio_bank_count;
+static u32 tegra_gpio_bank_stride;
+static u32 tegra_gpio_upper_offset;
static struct tegra_gpio_bank *tegra_gpio_banks;
static inline void tegra_gpio_writel(u32 val, u32 reg)
@@ -333,6 +336,26 @@ static struct irq_chip tegra_gpio_irq_chip = {
#endif
};
+struct tegra_gpio_soc_config {
+ u32 bank_stride;
+ u32 upper_offset;
+};
+
+static struct tegra_gpio_soc_config tegra20_gpio_config = {
+ .bank_stride = 0x80,
+ .upper_offset = 0x800,
+};
+
+static struct tegra_gpio_soc_config tegra30_gpio_config = {
+ .bank_stride = 0x100,
+ .upper_offset = 0x80,
+};
+
+static struct of_device_id tegra_gpio_of_match[] __devinitdata = {
+ { .compatible = "nvidia,tegra30-gpio", .data = &tegra30_gpio_config },
+ { .compatible = "nvidia,tegra20-gpio", .data = &tegra20_gpio_config },
+ { },
+};
/* This lock class tells lockdep that GPIO irqs are in a different
* category than their parents, so it won't report false recursion.
@@ -341,6 +364,8 @@ static struct lock_class_key gpio_lock_class;
static int __devinit tegra_gpio_probe(struct platform_device *pdev)
{
+ const struct of_device_id *match;
+ struct tegra_gpio_soc_config *config;
int irq_base;
struct resource *res;
struct tegra_gpio_bank *bank;
@@ -348,6 +373,15 @@ static int __devinit tegra_gpio_probe(struct platform_device *pdev)
int i;
int j;
+ match = of_match_device(tegra_gpio_of_match, &pdev->dev);
+ if (match)
+ config = (struct tegra_gpio_soc_config *)match->data;
+ else
+ config = &tegra20_gpio_config;
+
+ tegra_gpio_bank_stride = config->bank_stride;
+ tegra_gpio_upper_offset = config->upper_offset;
+
for (;;) {
res = platform_get_resource(pdev, IORESOURCE_IRQ, tegra_gpio_bank_count);
if (!res)
@@ -402,7 +436,7 @@ static int __devinit tegra_gpio_probe(struct platform_device *pdev)
return -ENODEV;
}
- for (i = 0; i < 7; i++) {
+ for (i = 0; i < tegra_gpio_bank_count; i++) {
for (j = 0; j < 4; j++) {
int gpio = tegra_gpio_compose(i, j, 0);
tegra_gpio_writel(0x00, GPIO_INT_ENB(gpio));
@@ -441,11 +475,6 @@ static int __devinit tegra_gpio_probe(struct platform_device *pdev)
return 0;
}
-static struct of_device_id tegra_gpio_of_match[] __devinitdata = {
- { .compatible = "nvidia,tegra20-gpio", },
- { },
-};
-
static struct platform_driver tegra_gpio_driver = {
.driver = {
.name = "tegra-gpio",
@@ -485,7 +514,7 @@ static int dbg_gpio_show(struct seq_file *s, void *unused)
int i;
int j;
- for (i = 0; i < 7; i++) {
+ for (i = 0; i < tegra_gpio_bank_count; i++) {
for (j = 0; j < 4; j++) {
int gpio = tegra_gpio_compose(i, j, 0);
seq_printf(s,
diff --git a/drivers/gpu/drm/drm_bufs.c b/drivers/gpu/drm/drm_bufs.c
index 30372f7b2d45..348b367debeb 100644
--- a/drivers/gpu/drm/drm_bufs.c
+++ b/drivers/gpu/drm/drm_bufs.c
@@ -1510,8 +1510,8 @@ int drm_freebufs(struct drm_device *dev, void *data,
* \param arg pointer to a drm_buf_map structure.
* \return zero on success or a negative number on failure.
*
- * Maps the AGP, SG or PCI buffer region with do_mmap(), and copies information
- * about each buffer into user space. For PCI buffers, it calls do_mmap() with
+ * Maps the AGP, SG or PCI buffer region with vm_mmap(), and copies information
+ * about each buffer into user space. For PCI buffers, it calls vm_mmap() with
* offset equal to 0, which drm_mmap() interpretes as PCI buffers and calls
* drm_mmap_dma().
*/
@@ -1553,18 +1553,14 @@ int drm_mapbufs(struct drm_device *dev, void *data,
retcode = -EINVAL;
goto done;
}
- down_write(&current->mm->mmap_sem);
- virtual = do_mmap(file_priv->filp, 0, map->size,
+ virtual = vm_mmap(file_priv->filp, 0, map->size,
PROT_READ | PROT_WRITE,
MAP_SHARED,
token);
- up_write(&current->mm->mmap_sem);
} else {
- down_write(&current->mm->mmap_sem);
- virtual = do_mmap(file_priv->filp, 0, dma->byte_count,
+ virtual = vm_mmap(file_priv->filp, 0, dma->byte_count,
PROT_READ | PROT_WRITE,
MAP_SHARED, 0);
- up_write(&current->mm->mmap_sem);
}
if (virtual > -1024UL) {
/* Real error */
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index d3aaeb6ae236..c79870a75c2f 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -3335,10 +3335,12 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
ret = crtc->funcs->page_flip(crtc, fb, e);
if (ret) {
- spin_lock_irqsave(&dev->event_lock, flags);
- file_priv->event_space += sizeof e->event;
- spin_unlock_irqrestore(&dev->event_lock, flags);
- kfree(e);
+ if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) {
+ spin_lock_irqsave(&dev->event_lock, flags);
+ file_priv->event_space += sizeof e->event;
+ spin_unlock_irqrestore(&dev->event_lock, flags);
+ kfree(e);
+ }
}
out:
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
index cdfbf27b2b3c..123de28f94ef 100644
--- a/drivers/gpu/drm/drm_fops.c
+++ b/drivers/gpu/drm/drm_fops.c
@@ -507,12 +507,12 @@ int drm_release(struct inode *inode, struct file *filp)
drm_events_release(file_priv);
- if (dev->driver->driver_features & DRIVER_GEM)
- drm_gem_release(dev, file_priv);
-
if (dev->driver->driver_features & DRIVER_MODESET)
drm_fb_release(file_priv);
+ if (dev->driver->driver_features & DRIVER_GEM)
+ drm_gem_release(dev, file_priv);
+
mutex_lock(&dev->ctxlist_mutex);
if (!list_empty(&dev->ctxlist)) {
struct drm_ctx_list *pos, *n;
diff --git a/drivers/gpu/drm/drm_usb.c b/drivers/gpu/drm/drm_usb.c
index c8c83dad2ce1..37c9a523dd1c 100644
--- a/drivers/gpu/drm/drm_usb.c
+++ b/drivers/gpu/drm/drm_usb.c
@@ -1,6 +1,6 @@
#include "drmP.h"
#include <linux/usb.h>
-#include <linux/export.h>
+#include <linux/module.h>
int drm_get_usb_dev(struct usb_interface *interface,
const struct usb_device_id *id,
@@ -114,3 +114,7 @@ void drm_usb_exit(struct drm_driver *driver,
usb_deregister(udriver);
}
EXPORT_SYMBOL(drm_usb_exit);
+
+MODULE_AUTHOR("David Airlie");
+MODULE_DESCRIPTION("USB DRM support");
+MODULE_LICENSE("GPL and additional rights");
diff --git a/drivers/gpu/drm/exynos/exynos_drm_buf.c b/drivers/gpu/drm/exynos/exynos_drm_buf.c
index 4a3a5f72ed4a..de8d2090bce3 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_buf.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_buf.c
@@ -34,14 +34,14 @@
static int lowlevel_buffer_allocate(struct drm_device *dev,
unsigned int flags, struct exynos_drm_gem_buf *buf)
{
- dma_addr_t start_addr, end_addr;
+ dma_addr_t start_addr;
unsigned int npages, page_size, i = 0;
struct scatterlist *sgl;
int ret = 0;
DRM_DEBUG_KMS("%s\n", __FILE__);
- if (flags & EXYNOS_BO_NONCONTIG) {
+ if (IS_NONCONTIG_BUFFER(flags)) {
DRM_DEBUG_KMS("not support allocation type.\n");
return -EINVAL;
}
@@ -52,13 +52,13 @@ static int lowlevel_buffer_allocate(struct drm_device *dev,
}
if (buf->size >= SZ_1M) {
- npages = (buf->size >> SECTION_SHIFT) + 1;
+ npages = buf->size >> SECTION_SHIFT;
page_size = SECTION_SIZE;
} else if (buf->size >= SZ_64K) {
- npages = (buf->size >> 16) + 1;
+ npages = buf->size >> 16;
page_size = SZ_64K;
} else {
- npages = (buf->size >> PAGE_SHIFT) + 1;
+ npages = buf->size >> PAGE_SHIFT;
page_size = PAGE_SIZE;
}
@@ -76,26 +76,13 @@ static int lowlevel_buffer_allocate(struct drm_device *dev,
return -ENOMEM;
}
- buf->kvaddr = dma_alloc_writecombine(dev->dev, buf->size,
- &buf->dma_addr, GFP_KERNEL);
- if (!buf->kvaddr) {
- DRM_ERROR("failed to allocate buffer.\n");
- ret = -ENOMEM;
- goto err1;
- }
-
- start_addr = buf->dma_addr;
- end_addr = buf->dma_addr + buf->size;
-
- buf->pages = kzalloc(sizeof(struct page) * npages, GFP_KERNEL);
- if (!buf->pages) {
- DRM_ERROR("failed to allocate pages.\n");
- ret = -ENOMEM;
- goto err2;
- }
-
- start_addr = buf->dma_addr;
- end_addr = buf->dma_addr + buf->size;
+ buf->kvaddr = dma_alloc_writecombine(dev->dev, buf->size,
+ &buf->dma_addr, GFP_KERNEL);
+ if (!buf->kvaddr) {
+ DRM_ERROR("failed to allocate buffer.\n");
+ ret = -ENOMEM;
+ goto err1;
+ }
buf->pages = kzalloc(sizeof(struct page) * npages, GFP_KERNEL);
if (!buf->pages) {
@@ -105,23 +92,17 @@ static int lowlevel_buffer_allocate(struct drm_device *dev,
}
sgl = buf->sgt->sgl;
+ start_addr = buf->dma_addr;
while (i < npages) {
buf->pages[i] = phys_to_page(start_addr);
sg_set_page(sgl, buf->pages[i], page_size, 0);
sg_dma_address(sgl) = start_addr;
start_addr += page_size;
- if (end_addr - start_addr < page_size)
- break;
sgl = sg_next(sgl);
i++;
}
- buf->pages[i] = phys_to_page(start_addr);
-
- sgl = sg_next(sgl);
- sg_set_page(sgl, buf->pages[i+1], end_addr - start_addr, 0);
-
DRM_DEBUG_KMS("vaddr(0x%lx), dma_addr(0x%lx), size(0x%lx)\n",
(unsigned long)buf->kvaddr,
(unsigned long)buf->dma_addr,
@@ -150,7 +131,7 @@ static void lowlevel_buffer_deallocate(struct drm_device *dev,
* non-continuous memory would be released by exynos
* gem framework.
*/
- if (flags & EXYNOS_BO_NONCONTIG) {
+ if (IS_NONCONTIG_BUFFER(flags)) {
DRM_DEBUG_KMS("not support allocation type.\n");
return;
}
diff --git a/drivers/gpu/drm/exynos/exynos_drm_core.c b/drivers/gpu/drm/exynos/exynos_drm_core.c
index 411832e8e17a..eaf630dc5dba 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_core.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_core.c
@@ -54,16 +54,18 @@ static int exynos_drm_subdrv_probe(struct drm_device *dev,
*
* P.S. note that this driver is considered for modularization.
*/
- ret = subdrv->probe(dev, subdrv->manager.dev);
+ ret = subdrv->probe(dev, subdrv->dev);
if (ret)
return ret;
}
- if (subdrv->is_local)
+ if (!subdrv->manager)
return 0;
+ subdrv->manager->dev = subdrv->dev;
+
/* create and initialize a encoder for this sub driver. */
- encoder = exynos_drm_encoder_create(dev, &subdrv->manager,
+ encoder = exynos_drm_encoder_create(dev, subdrv->manager,
(1 << MAX_CRTC) - 1);
if (!encoder) {
DRM_ERROR("failed to create encoder\n");
@@ -186,7 +188,7 @@ int exynos_drm_subdrv_open(struct drm_device *dev, struct drm_file *file)
list_for_each_entry(subdrv, &exynos_drm_subdrv_list, list) {
if (subdrv->open) {
- ret = subdrv->open(dev, subdrv->manager.dev, file);
+ ret = subdrv->open(dev, subdrv->dev, file);
if (ret)
goto err;
}
@@ -197,7 +199,7 @@ int exynos_drm_subdrv_open(struct drm_device *dev, struct drm_file *file)
err:
list_for_each_entry_reverse(subdrv, &subdrv->list, list) {
if (subdrv->close)
- subdrv->close(dev, subdrv->manager.dev, file);
+ subdrv->close(dev, subdrv->dev, file);
}
return ret;
}
@@ -209,7 +211,7 @@ void exynos_drm_subdrv_close(struct drm_device *dev, struct drm_file *file)
list_for_each_entry(subdrv, &exynos_drm_subdrv_list, list) {
if (subdrv->close)
- subdrv->close(dev, subdrv->manager.dev, file);
+ subdrv->close(dev, subdrv->dev, file);
}
}
EXPORT_SYMBOL_GPL(exynos_drm_subdrv_close);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h
index fbd0a232c93d..1d814175cd49 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
@@ -225,24 +225,25 @@ struct exynos_drm_private {
* Exynos drm sub driver structure.
*
* @list: sub driver has its own list object to register to exynos drm driver.
+ * @dev: pointer to device object for subdrv device driver.
* @drm_dev: pointer to drm_device and this pointer would be set
* when sub driver calls exynos_drm_subdrv_register().
- * @is_local: appear encoder and connector disrelated device.
+ * @manager: subdrv has its own manager to control a hardware appropriately
+ * and we can access a hardware drawing on this manager.
* @probe: this callback would be called by exynos drm driver after
* subdrv is registered to it.
* @remove: this callback is used to release resources created
* by probe callback.
* @open: this would be called with drm device file open.
* @close: this would be called with drm device file close.
- * @manager: subdrv has its own manager to control a hardware appropriately
- * and we can access a hardware drawing on this manager.
* @encoder: encoder object owned by this sub driver.
* @connector: connector object owned by this sub driver.
*/
struct exynos_drm_subdrv {
struct list_head list;
+ struct device *dev;
struct drm_device *drm_dev;
- bool is_local;
+ struct exynos_drm_manager *manager;
int (*probe)(struct drm_device *drm_dev, struct device *dev);
void (*remove)(struct drm_device *dev);
@@ -251,7 +252,6 @@ struct exynos_drm_subdrv {
void (*close)(struct drm_device *drm_dev, struct device *dev,
struct drm_file *file);
- struct exynos_drm_manager manager;
struct drm_encoder *encoder;
struct drm_connector *connector;
};
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
index ecb6db229700..29fdbfeb43cb 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
@@ -172,7 +172,7 @@ static void fimd_dpms(struct device *subdrv_dev, int mode)
static void fimd_apply(struct device *subdrv_dev)
{
struct fimd_context *ctx = get_fimd_context(subdrv_dev);
- struct exynos_drm_manager *mgr = &ctx->subdrv.manager;
+ struct exynos_drm_manager *mgr = ctx->subdrv.manager;
struct exynos_drm_manager_ops *mgr_ops = mgr->ops;
struct exynos_drm_overlay_ops *ovl_ops = mgr->overlay_ops;
struct fimd_win_data *win_data;
@@ -577,6 +577,13 @@ static struct exynos_drm_overlay_ops fimd_overlay_ops = {
.disable = fimd_win_disable,
};
+static struct exynos_drm_manager fimd_manager = {
+ .pipe = -1,
+ .ops = &fimd_manager_ops,
+ .overlay_ops = &fimd_overlay_ops,
+ .display_ops = &fimd_display_ops,
+};
+
static void fimd_finish_pageflip(struct drm_device *drm_dev, int crtc)
{
struct exynos_drm_private *dev_priv = drm_dev->dev_private;
@@ -628,7 +635,7 @@ static irqreturn_t fimd_irq_handler(int irq, void *dev_id)
struct fimd_context *ctx = (struct fimd_context *)dev_id;
struct exynos_drm_subdrv *subdrv = &ctx->subdrv;
struct drm_device *drm_dev = subdrv->drm_dev;
- struct exynos_drm_manager *manager = &subdrv->manager;
+ struct exynos_drm_manager *manager = subdrv->manager;
u32 val;
val = readl(ctx->regs + VIDINTCON1);
@@ -744,7 +751,7 @@ static void fimd_clear_win(struct fimd_context *ctx, int win)
static int fimd_power_on(struct fimd_context *ctx, bool enable)
{
struct exynos_drm_subdrv *subdrv = &ctx->subdrv;
- struct device *dev = subdrv->manager.dev;
+ struct device *dev = subdrv->dev;
DRM_DEBUG_KMS("%s\n", __FILE__);
@@ -867,13 +874,10 @@ static int __devinit fimd_probe(struct platform_device *pdev)
subdrv = &ctx->subdrv;
+ subdrv->dev = dev;
+ subdrv->manager = &fimd_manager;
subdrv->probe = fimd_subdrv_probe;
subdrv->remove = fimd_subdrv_remove;
- subdrv->manager.pipe = -1;
- subdrv->manager.ops = &fimd_manager_ops;
- subdrv->manager.overlay_ops = &fimd_overlay_ops;
- subdrv->manager.display_ops = &fimd_display_ops;
- subdrv->manager.dev = dev;
mutex_init(&ctx->lock);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c
index fa1aa94a3d8e..392ce71ed6a1 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -56,9 +56,28 @@ static unsigned int convert_to_vm_err_msg(int msg)
return out_msg;
}
-static unsigned int mask_gem_flags(unsigned int flags)
+static int check_gem_flags(unsigned int flags)
{
- return flags &= EXYNOS_BO_NONCONTIG;
+ if (flags & ~(EXYNOS_BO_MASK)) {
+ DRM_ERROR("invalid flags.\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static unsigned long roundup_gem_size(unsigned long size, unsigned int flags)
+{
+ if (!IS_NONCONTIG_BUFFER(flags)) {
+ if (size >= SZ_1M)
+ return roundup(size, SECTION_SIZE);
+ else if (size >= SZ_64K)
+ return roundup(size, SZ_64K);
+ else
+ goto out;
+ }
+out:
+ return roundup(size, PAGE_SIZE);
}
static struct page **exynos_gem_get_pages(struct drm_gem_object *obj,
@@ -319,10 +338,17 @@ struct exynos_drm_gem_obj *exynos_drm_gem_create(struct drm_device *dev,
struct exynos_drm_gem_buf *buf;
int ret;
- size = roundup(size, PAGE_SIZE);
- DRM_DEBUG_KMS("%s: size = 0x%lx\n", __FILE__, size);
+ if (!size) {
+ DRM_ERROR("invalid size.\n");
+ return ERR_PTR(-EINVAL);
+ }
- flags = mask_gem_flags(flags);
+ size = roundup_gem_size(size, flags);
+ DRM_DEBUG_KMS("%s\n", __FILE__);
+
+ ret = check_gem_flags(flags);
+ if (ret)
+ return ERR_PTR(ret);
buf = exynos_drm_init_buf(dev, size);
if (!buf)
@@ -331,7 +357,7 @@ struct exynos_drm_gem_obj *exynos_drm_gem_create(struct drm_device *dev,
exynos_gem_obj = exynos_drm_gem_init(dev, size);
if (!exynos_gem_obj) {
ret = -ENOMEM;
- goto err;
+ goto err_fini_buf;
}
exynos_gem_obj->buffer = buf;
@@ -347,18 +373,19 @@ struct exynos_drm_gem_obj *exynos_drm_gem_create(struct drm_device *dev,
ret = exynos_drm_gem_get_pages(&exynos_gem_obj->base);
if (ret < 0) {
drm_gem_object_release(&exynos_gem_obj->base);
- goto err;
+ goto err_fini_buf;
}
} else {
ret = exynos_drm_alloc_buf(dev, buf, flags);
if (ret < 0) {
drm_gem_object_release(&exynos_gem_obj->base);
- goto err;
+ goto err_fini_buf;
}
}
return exynos_gem_obj;
-err:
+
+err_fini_buf:
exynos_drm_fini_buf(dev, buf);
return ERR_PTR(ret);
}
@@ -554,10 +581,8 @@ int exynos_drm_gem_mmap_ioctl(struct drm_device *dev, void *data,
obj->filp->f_op = &exynos_drm_gem_fops;
obj->filp->private_data = obj;
- down_write(&current->mm->mmap_sem);
- addr = do_mmap(obj->filp, 0, args->size,
+ addr = vm_mmap(obj->filp, 0, args->size,
PROT_READ | PROT_WRITE, MAP_SHARED, 0);
- up_write(&current->mm->mmap_sem);
drm_gem_object_unreference_unlocked(obj);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.h b/drivers/gpu/drm/exynos/exynos_drm_gem.h
index e40fbad8b705..4ed842039505 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.h
@@ -29,6 +29,8 @@
#define to_exynos_gem_obj(x) container_of(x,\
struct exynos_drm_gem_obj, base)
+#define IS_NONCONTIG_BUFFER(f) (f & EXYNOS_BO_NONCONTIG)
+
/*
* exynos drm gem buffer structure.
*
diff --git a/drivers/gpu/drm/exynos/exynos_drm_hdmi.c b/drivers/gpu/drm/exynos/exynos_drm_hdmi.c
index 14eb26b0ba1c..3424463676e0 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_hdmi.c
@@ -30,9 +30,8 @@
struct drm_hdmi_context, subdrv);
/* these callback points shoud be set by specific drivers. */
-static struct exynos_hdmi_display_ops *hdmi_display_ops;
-static struct exynos_hdmi_manager_ops *hdmi_manager_ops;
-static struct exynos_hdmi_overlay_ops *hdmi_overlay_ops;
+static struct exynos_hdmi_ops *hdmi_ops;
+static struct exynos_mixer_ops *mixer_ops;
struct drm_hdmi_context {
struct exynos_drm_subdrv subdrv;
@@ -40,31 +39,20 @@ struct drm_hdmi_context {
struct exynos_drm_hdmi_context *mixer_ctx;
};
-void exynos_drm_display_ops_register(struct exynos_hdmi_display_ops
- *display_ops)
+void exynos_hdmi_ops_register(struct exynos_hdmi_ops *ops)
{
DRM_DEBUG_KMS("%s\n", __FILE__);
- if (display_ops)
- hdmi_display_ops = display_ops;
+ if (ops)
+ hdmi_ops = ops;
}
-void exynos_drm_manager_ops_register(struct exynos_hdmi_manager_ops
- *manager_ops)
+void exynos_mixer_ops_register(struct exynos_mixer_ops *ops)
{
DRM_DEBUG_KMS("%s\n", __FILE__);
- if (manager_ops)
- hdmi_manager_ops = manager_ops;
-}
-
-void exynos_drm_overlay_ops_register(struct exynos_hdmi_overlay_ops
- *overlay_ops)
-{
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
- if (overlay_ops)
- hdmi_overlay_ops = overlay_ops;
+ if (ops)
+ mixer_ops = ops;
}
static bool drm_hdmi_is_connected(struct device *dev)
@@ -73,8 +61,8 @@ static bool drm_hdmi_is_connected(struct device *dev)
DRM_DEBUG_KMS("%s\n", __FILE__);
- if (hdmi_display_ops && hdmi_display_ops->is_connected)
- return hdmi_display_ops->is_connected(ctx->hdmi_ctx->ctx);
+ if (hdmi_ops && hdmi_ops->is_connected)
+ return hdmi_ops->is_connected(ctx->hdmi_ctx->ctx);
return false;
}
@@ -86,9 +74,9 @@ static int drm_hdmi_get_edid(struct device *dev,
DRM_DEBUG_KMS("%s\n", __FILE__);
- if (hdmi_display_ops && hdmi_display_ops->get_edid)
- return hdmi_display_ops->get_edid(ctx->hdmi_ctx->ctx,
- connector, edid, len);
+ if (hdmi_ops && hdmi_ops->get_edid)
+ return hdmi_ops->get_edid(ctx->hdmi_ctx->ctx, connector, edid,
+ len);
return 0;
}
@@ -99,9 +87,8 @@ static int drm_hdmi_check_timing(struct device *dev, void *timing)
DRM_DEBUG_KMS("%s\n", __FILE__);
- if (hdmi_display_ops && hdmi_display_ops->check_timing)
- return hdmi_display_ops->check_timing(ctx->hdmi_ctx->ctx,
- timing);
+ if (hdmi_ops && hdmi_ops->check_timing)
+ return hdmi_ops->check_timing(ctx->hdmi_ctx->ctx, timing);
return 0;
}
@@ -112,8 +99,8 @@ static int drm_hdmi_power_on(struct device *dev, int mode)
DRM_DEBUG_KMS("%s\n", __FILE__);
- if (hdmi_display_ops && hdmi_display_ops->power_on)
- return hdmi_display_ops->power_on(ctx->hdmi_ctx->ctx, mode);
+ if (hdmi_ops && hdmi_ops->power_on)
+ return hdmi_ops->power_on(ctx->hdmi_ctx->ctx, mode);
return 0;
}
@@ -130,13 +117,13 @@ static int drm_hdmi_enable_vblank(struct device *subdrv_dev)
{
struct drm_hdmi_context *ctx = to_context(subdrv_dev);
struct exynos_drm_subdrv *subdrv = &ctx->subdrv;
- struct exynos_drm_manager *manager = &subdrv->manager;
+ struct exynos_drm_manager *manager = subdrv->manager;
DRM_DEBUG_KMS("%s\n", __FILE__);
- if (hdmi_overlay_ops && hdmi_overlay_ops->enable_vblank)
- return hdmi_overlay_ops->enable_vblank(ctx->mixer_ctx->ctx,
- manager->pipe);
+ if (mixer_ops && mixer_ops->enable_vblank)
+ return mixer_ops->enable_vblank(ctx->mixer_ctx->ctx,
+ manager->pipe);
return 0;
}
@@ -147,8 +134,8 @@ static void drm_hdmi_disable_vblank(struct device *subdrv_dev)
DRM_DEBUG_KMS("%s\n", __FILE__);
- if (hdmi_overlay_ops && hdmi_overlay_ops->disable_vblank)
- return hdmi_overlay_ops->disable_vblank(ctx->mixer_ctx->ctx);
+ if (mixer_ops && mixer_ops->disable_vblank)
+ return mixer_ops->disable_vblank(ctx->mixer_ctx->ctx);
}
static void drm_hdmi_mode_fixup(struct device *subdrv_dev,
@@ -160,9 +147,9 @@ static void drm_hdmi_mode_fixup(struct device *subdrv_dev,
DRM_DEBUG_KMS("%s\n", __FILE__);
- if (hdmi_manager_ops && hdmi_manager_ops->mode_fixup)
- hdmi_manager_ops->mode_fixup(ctx->hdmi_ctx->ctx, connector,
- mode, adjusted_mode);
+ if (hdmi_ops && hdmi_ops->mode_fixup)
+ hdmi_ops->mode_fixup(ctx->hdmi_ctx->ctx, connector, mode,
+ adjusted_mode);
}
static void drm_hdmi_mode_set(struct device *subdrv_dev, void *mode)
@@ -171,8 +158,8 @@ static void drm_hdmi_mode_set(struct device *subdrv_dev, void *mode)
DRM_DEBUG_KMS("%s\n", __FILE__);
- if (hdmi_manager_ops && hdmi_manager_ops->mode_set)
- hdmi_manager_ops->mode_set(ctx->hdmi_ctx->ctx, mode);
+ if (hdmi_ops && hdmi_ops->mode_set)
+ hdmi_ops->mode_set(ctx->hdmi_ctx->ctx, mode);
}
static void drm_hdmi_get_max_resol(struct device *subdrv_dev,
@@ -182,9 +169,8 @@ static void drm_hdmi_get_max_resol(struct device *subdrv_dev,
DRM_DEBUG_KMS("%s\n", __FILE__);
- if (hdmi_manager_ops && hdmi_manager_ops->get_max_resol)
- hdmi_manager_ops->get_max_resol(ctx->hdmi_ctx->ctx, width,
- height);
+ if (hdmi_ops && hdmi_ops->get_max_resol)
+ hdmi_ops->get_max_resol(ctx->hdmi_ctx->ctx, width, height);
}
static void drm_hdmi_commit(struct device *subdrv_dev)
@@ -193,8 +179,8 @@ static void drm_hdmi_commit(struct device *subdrv_dev)
DRM_DEBUG_KMS("%s\n", __FILE__);
- if (hdmi_manager_ops && hdmi_manager_ops->commit)
- hdmi_manager_ops->commit(ctx->hdmi_ctx->ctx);
+ if (hdmi_ops && hdmi_ops->commit)
+ hdmi_ops->commit(ctx->hdmi_ctx->ctx);
}
static void drm_hdmi_dpms(struct device *subdrv_dev, int mode)
@@ -209,8 +195,8 @@ static void drm_hdmi_dpms(struct device *subdrv_dev, int mode)
case DRM_MODE_DPMS_STANDBY:
case DRM_MODE_DPMS_SUSPEND:
case DRM_MODE_DPMS_OFF:
- if (hdmi_manager_ops && hdmi_manager_ops->disable)
- hdmi_manager_ops->disable(ctx->hdmi_ctx->ctx);
+ if (hdmi_ops && hdmi_ops->disable)
+ hdmi_ops->disable(ctx->hdmi_ctx->ctx);
break;
default:
DRM_DEBUG_KMS("unkown dps mode: %d\n", mode);
@@ -235,8 +221,8 @@ static void drm_mixer_mode_set(struct device *subdrv_dev,
DRM_DEBUG_KMS("%s\n", __FILE__);
- if (hdmi_overlay_ops && hdmi_overlay_ops->win_mode_set)
- hdmi_overlay_ops->win_mode_set(ctx->mixer_ctx->ctx, overlay);
+ if (mixer_ops && mixer_ops->win_mode_set)
+ mixer_ops->win_mode_set(ctx->mixer_ctx->ctx, overlay);
}
static void drm_mixer_commit(struct device *subdrv_dev, int zpos)
@@ -245,8 +231,8 @@ static void drm_mixer_commit(struct device *subdrv_dev, int zpos)
DRM_DEBUG_KMS("%s\n", __FILE__);
- if (hdmi_overlay_ops && hdmi_overlay_ops->win_commit)
- hdmi_overlay_ops->win_commit(ctx->mixer_ctx->ctx, zpos);
+ if (mixer_ops && mixer_ops->win_commit)
+ mixer_ops->win_commit(ctx->mixer_ctx->ctx, zpos);
}
static void drm_mixer_disable(struct device *subdrv_dev, int zpos)
@@ -255,8 +241,8 @@ static void drm_mixer_disable(struct device *subdrv_dev, int zpos)
DRM_DEBUG_KMS("%s\n", __FILE__);
- if (hdmi_overlay_ops && hdmi_overlay_ops->win_disable)
- hdmi_overlay_ops->win_disable(ctx->mixer_ctx->ctx, zpos);
+ if (mixer_ops && mixer_ops->win_disable)
+ mixer_ops->win_disable(ctx->mixer_ctx->ctx, zpos);
}
static struct exynos_drm_overlay_ops drm_hdmi_overlay_ops = {
@@ -265,6 +251,12 @@ static struct exynos_drm_overlay_ops drm_hdmi_overlay_ops = {
.disable = drm_mixer_disable,
};
+static struct exynos_drm_manager hdmi_manager = {
+ .pipe = -1,
+ .ops = &drm_hdmi_manager_ops,
+ .overlay_ops = &drm_hdmi_overlay_ops,
+ .display_ops = &drm_hdmi_display_ops,
+};
static int hdmi_subdrv_probe(struct drm_device *drm_dev,
struct device *dev)
@@ -332,12 +324,9 @@ static int __devinit exynos_drm_hdmi_probe(struct platform_device *pdev)
subdrv = &ctx->subdrv;
+ subdrv->dev = dev;
+ subdrv->manager = &hdmi_manager;
subdrv->probe = hdmi_subdrv_probe;
- subdrv->manager.pipe = -1;
- subdrv->manager.ops = &drm_hdmi_manager_ops;
- subdrv->manager.overlay_ops = &drm_hdmi_overlay_ops;
- subdrv->manager.display_ops = &drm_hdmi_display_ops;
- subdrv->manager.dev = dev;
platform_set_drvdata(pdev, subdrv);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_hdmi.h b/drivers/gpu/drm/exynos/exynos_drm_hdmi.h
index 44497cfb6c74..f3ae192c8dcf 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_hdmi.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_hdmi.h
@@ -38,15 +38,15 @@ struct exynos_drm_hdmi_context {
void *ctx;
};
-struct exynos_hdmi_display_ops {
+struct exynos_hdmi_ops {
+ /* display */
bool (*is_connected)(void *ctx);
int (*get_edid)(void *ctx, struct drm_connector *connector,
u8 *edid, int len);
int (*check_timing)(void *ctx, void *timing);
int (*power_on)(void *ctx, int mode);
-};
-struct exynos_hdmi_manager_ops {
+ /* manager */
void (*mode_fixup)(void *ctx, struct drm_connector *connector,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode);
@@ -57,22 +57,17 @@ struct exynos_hdmi_manager_ops {
void (*disable)(void *ctx);
};
-struct exynos_hdmi_overlay_ops {
+struct exynos_mixer_ops {
+ /* manager */
int (*enable_vblank)(void *ctx, int pipe);
void (*disable_vblank)(void *ctx);
+
+ /* overlay */
void (*win_mode_set)(void *ctx, struct exynos_drm_overlay *overlay);
void (*win_commit)(void *ctx, int zpos);
void (*win_disable)(void *ctx, int zpos);
};
-extern struct platform_driver hdmi_driver;
-extern struct platform_driver mixer_driver;
-
-void exynos_drm_display_ops_register(struct exynos_hdmi_display_ops
- *display_ops);
-void exynos_drm_manager_ops_register(struct exynos_hdmi_manager_ops
- *manager_ops);
-void exynos_drm_overlay_ops_register(struct exynos_hdmi_overlay_ops
- *overlay_ops);
-
+void exynos_hdmi_ops_register(struct exynos_hdmi_ops *ops);
+void exynos_mixer_ops_register(struct exynos_mixer_ops *ops);
#endif
diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c
index c277a3a445f5..f92fe4c6174a 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_plane.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c
@@ -24,6 +24,10 @@ struct exynos_plane {
static const uint32_t formats[] = {
DRM_FORMAT_XRGB8888,
+ DRM_FORMAT_ARGB8888,
+ DRM_FORMAT_NV12,
+ DRM_FORMAT_NV12M,
+ DRM_FORMAT_NV12MT,
};
static int
diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
index 8e1339f9fe1f..7b9c153dceb6 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
@@ -199,7 +199,7 @@ static void vidi_dpms(struct device *subdrv_dev, int mode)
static void vidi_apply(struct device *subdrv_dev)
{
struct vidi_context *ctx = get_vidi_context(subdrv_dev);
- struct exynos_drm_manager *mgr = &ctx->subdrv.manager;
+ struct exynos_drm_manager *mgr = ctx->subdrv.manager;
struct exynos_drm_manager_ops *mgr_ops = mgr->ops;
struct exynos_drm_overlay_ops *ovl_ops = mgr->overlay_ops;
struct vidi_win_data *win_data;
@@ -374,6 +374,13 @@ static struct exynos_drm_overlay_ops vidi_overlay_ops = {
.disable = vidi_win_disable,
};
+static struct exynos_drm_manager vidi_manager = {
+ .pipe = -1,
+ .ops = &vidi_manager_ops,
+ .overlay_ops = &vidi_overlay_ops,
+ .display_ops = &vidi_display_ops,
+};
+
static void vidi_finish_pageflip(struct drm_device *drm_dev, int crtc)
{
struct exynos_drm_private *dev_priv = drm_dev->dev_private;
@@ -425,7 +432,7 @@ static void vidi_fake_vblank_handler(struct work_struct *work)
struct vidi_context *ctx = container_of(work, struct vidi_context,
work);
struct exynos_drm_subdrv *subdrv = &ctx->subdrv;
- struct exynos_drm_manager *manager = &subdrv->manager;
+ struct exynos_drm_manager *manager = subdrv->manager;
if (manager->pipe < 0)
return;
@@ -471,7 +478,7 @@ static void vidi_subdrv_remove(struct drm_device *drm_dev)
static int vidi_power_on(struct vidi_context *ctx, bool enable)
{
struct exynos_drm_subdrv *subdrv = &ctx->subdrv;
- struct device *dev = subdrv->manager.dev;
+ struct device *dev = subdrv->dev;
DRM_DEBUG_KMS("%s\n", __FILE__);
@@ -611,13 +618,10 @@ static int __devinit vidi_probe(struct platform_device *pdev)
ctx->raw_edid = (struct edid *)fake_edid_info;
subdrv = &ctx->subdrv;
+ subdrv->dev = dev;
+ subdrv->manager = &vidi_manager;
subdrv->probe = vidi_subdrv_probe;
subdrv->remove = vidi_subdrv_remove;
- subdrv->manager.pipe = -1;
- subdrv->manager.ops = &vidi_manager_ops;
- subdrv->manager.overlay_ops = &vidi_overlay_ops;
- subdrv->manager.display_ops = &vidi_display_ops;
- subdrv->manager.dev = dev;
mutex_init(&ctx->lock);
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c
index 575a8cbd3533..b00353876458 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -40,7 +40,6 @@
#include "exynos_hdmi.h"
-#define HDMI_OVERLAY_NUMBER 3
#define MAX_WIDTH 1920
#define MAX_HEIGHT 1080
#define get_hdmi_context(dev) platform_get_drvdata(to_platform_device(dev))
@@ -1194,7 +1193,7 @@ static int hdmi_conf_index(struct hdmi_context *hdata,
static bool hdmi_is_connected(void *ctx)
{
- struct hdmi_context *hdata = (struct hdmi_context *)ctx;
+ struct hdmi_context *hdata = ctx;
u32 val = hdmi_reg_read(hdata, HDMI_HPD_STATUS);
if (val)
@@ -1207,7 +1206,7 @@ static int hdmi_get_edid(void *ctx, struct drm_connector *connector,
u8 *edid, int len)
{
struct edid *raw_edid;
- struct hdmi_context *hdata = (struct hdmi_context *)ctx;
+ struct hdmi_context *hdata = ctx;
DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
@@ -1275,7 +1274,7 @@ static int hdmi_v14_check_timing(struct fb_videomode *check_timing)
static int hdmi_check_timing(void *ctx, void *timing)
{
- struct hdmi_context *hdata = (struct hdmi_context *)ctx;
+ struct hdmi_context *hdata = ctx;
struct fb_videomode *check_timing = timing;
DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
@@ -1312,13 +1311,6 @@ static int hdmi_display_power_on(void *ctx, int mode)
return 0;
}
-static struct exynos_hdmi_display_ops display_ops = {
- .is_connected = hdmi_is_connected,
- .get_edid = hdmi_get_edid,
- .check_timing = hdmi_check_timing,
- .power_on = hdmi_display_power_on,
-};
-
static void hdmi_set_acr(u32 freq, u8 *acr)
{
u32 n, cts;
@@ -1914,7 +1906,7 @@ static void hdmi_mode_fixup(void *ctx, struct drm_connector *connector,
struct drm_display_mode *adjusted_mode)
{
struct drm_display_mode *m;
- struct hdmi_context *hdata = (struct hdmi_context *)ctx;
+ struct hdmi_context *hdata = ctx;
int index;
DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
@@ -1951,7 +1943,7 @@ static void hdmi_mode_fixup(void *ctx, struct drm_connector *connector,
static void hdmi_mode_set(void *ctx, void *mode)
{
- struct hdmi_context *hdata = (struct hdmi_context *)ctx;
+ struct hdmi_context *hdata = ctx;
int conf_idx;
DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
@@ -1974,7 +1966,7 @@ static void hdmi_get_max_resol(void *ctx, unsigned int *width,
static void hdmi_commit(void *ctx)
{
- struct hdmi_context *hdata = (struct hdmi_context *)ctx;
+ struct hdmi_context *hdata = ctx;
DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
@@ -1985,7 +1977,7 @@ static void hdmi_commit(void *ctx)
static void hdmi_disable(void *ctx)
{
- struct hdmi_context *hdata = (struct hdmi_context *)ctx;
+ struct hdmi_context *hdata = ctx;
DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
@@ -1996,7 +1988,14 @@ static void hdmi_disable(void *ctx)
}
}
-static struct exynos_hdmi_manager_ops manager_ops = {
+static struct exynos_hdmi_ops hdmi_ops = {
+ /* display */
+ .is_connected = hdmi_is_connected,
+ .get_edid = hdmi_get_edid,
+ .check_timing = hdmi_check_timing,
+ .power_on = hdmi_display_power_on,
+
+ /* manager */
.mode_fixup = hdmi_mode_fixup,
.mode_set = hdmi_mode_set,
.get_max_resol = hdmi_get_max_resol,
@@ -2020,7 +2019,7 @@ static void hdmi_hotplug_func(struct work_struct *work)
static irqreturn_t hdmi_irq_handler(int irq, void *arg)
{
struct exynos_drm_hdmi_context *ctx = arg;
- struct hdmi_context *hdata = (struct hdmi_context *)ctx->ctx;
+ struct hdmi_context *hdata = ctx->ctx;
u32 intc_flag;
intc_flag = hdmi_reg_read(hdata, HDMI_INTC_FLAG);
@@ -2173,7 +2172,7 @@ static int hdmi_runtime_suspend(struct device *dev)
DRM_DEBUG_KMS("%s\n", __func__);
- hdmi_resource_poweroff((struct hdmi_context *)ctx->ctx);
+ hdmi_resource_poweroff(ctx->ctx);
return 0;
}
@@ -2184,7 +2183,7 @@ static int hdmi_runtime_resume(struct device *dev)
DRM_DEBUG_KMS("%s\n", __func__);
- hdmi_resource_poweron((struct hdmi_context *)ctx->ctx);
+ hdmi_resource_poweron(ctx->ctx);
return 0;
}
@@ -2322,8 +2321,7 @@ static int __devinit hdmi_probe(struct platform_device *pdev)
hdata->irq = res->start;
/* register specific callbacks to common hdmi. */
- exynos_drm_display_ops_register(&display_ops);
- exynos_drm_manager_ops_register(&manager_ops);
+ exynos_hdmi_ops_register(&hdmi_ops);
hdmi_resource_poweron(hdata);
@@ -2351,7 +2349,7 @@ err_data:
static int __devexit hdmi_remove(struct platform_device *pdev)
{
struct exynos_drm_hdmi_context *ctx = platform_get_drvdata(pdev);
- struct hdmi_context *hdata = (struct hdmi_context *)ctx->ctx;
+ struct hdmi_context *hdata = ctx->ctx;
DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c
index 4d5f41e19527..e15438c01129 100644
--- a/drivers/gpu/drm/exynos/exynos_mixer.c
+++ b/drivers/gpu/drm/exynos/exynos_mixer.c
@@ -37,7 +37,8 @@
#include "exynos_drm_drv.h"
#include "exynos_drm_hdmi.h"
-#define HDMI_OVERLAY_NUMBER 3
+#define MIXER_WIN_NR 3
+#define MIXER_DEFAULT_WIN 0
#define get_mixer_context(dev) platform_get_drvdata(to_platform_device(dev))
@@ -75,16 +76,12 @@ struct mixer_resources {
};
struct mixer_context {
- struct fb_videomode *default_timing;
- unsigned int default_win;
- unsigned int default_bpp;
unsigned int irq;
int pipe;
bool interlace;
- bool vp_enabled;
struct mixer_resources mixer_res;
- struct hdmi_win_data win_data[HDMI_OVERLAY_NUMBER];
+ struct hdmi_win_data win_data[MIXER_WIN_NR];
};
static const u8 filter_y_horiz_tap8[] = {
@@ -643,9 +640,9 @@ static void mixer_win_mode_set(void *ctx,
win = overlay->zpos;
if (win == DEFAULT_ZPOS)
- win = mixer_ctx->default_win;
+ win = MIXER_DEFAULT_WIN;
- if (win < 0 || win > HDMI_OVERLAY_NUMBER) {
+ if (win < 0 || win > MIXER_WIN_NR) {
DRM_ERROR("overlay plane[%d] is wrong\n", win);
return;
}
@@ -683,9 +680,9 @@ static void mixer_win_commit(void *ctx, int zpos)
DRM_DEBUG_KMS("[%d] %s, win: %d\n", __LINE__, __func__, win);
if (win == DEFAULT_ZPOS)
- win = mixer_ctx->default_win;
+ win = MIXER_DEFAULT_WIN;
- if (win < 0 || win > HDMI_OVERLAY_NUMBER) {
+ if (win < 0 || win > MIXER_WIN_NR) {
DRM_ERROR("overlay plane[%d] is wrong\n", win);
return;
}
@@ -706,9 +703,9 @@ static void mixer_win_disable(void *ctx, int zpos)
DRM_DEBUG_KMS("[%d] %s, win: %d\n", __LINE__, __func__, win);
if (win == DEFAULT_ZPOS)
- win = mixer_ctx->default_win;
+ win = MIXER_DEFAULT_WIN;
- if (win < 0 || win > HDMI_OVERLAY_NUMBER) {
+ if (win < 0 || win > MIXER_WIN_NR) {
DRM_ERROR("overlay plane[%d] is wrong\n", win);
return;
}
@@ -722,9 +719,12 @@ static void mixer_win_disable(void *ctx, int zpos)
spin_unlock_irqrestore(&res->reg_slock, flags);
}
-static struct exynos_hdmi_overlay_ops overlay_ops = {
+static struct exynos_mixer_ops mixer_ops = {
+ /* manager */
.enable_vblank = mixer_enable_vblank,
.disable_vblank = mixer_disable_vblank,
+
+ /* overlay */
.win_mode_set = mixer_win_mode_set,
.win_commit = mixer_win_commit,
.win_disable = mixer_win_disable,
@@ -771,8 +771,7 @@ static void mixer_finish_pageflip(struct drm_device *drm_dev, int crtc)
static irqreturn_t mixer_irq_handler(int irq, void *arg)
{
struct exynos_drm_hdmi_context *drm_hdmi_ctx = arg;
- struct mixer_context *ctx =
- (struct mixer_context *)drm_hdmi_ctx->ctx;
+ struct mixer_context *ctx = drm_hdmi_ctx->ctx;
struct mixer_resources *res = &ctx->mixer_res;
u32 val, val_base;
@@ -902,7 +901,7 @@ static int mixer_runtime_resume(struct device *dev)
DRM_DEBUG_KMS("resume - start\n");
- mixer_resource_poweron((struct mixer_context *)ctx->ctx);
+ mixer_resource_poweron(ctx->ctx);
return 0;
}
@@ -913,7 +912,7 @@ static int mixer_runtime_suspend(struct device *dev)
DRM_DEBUG_KMS("suspend - start\n");
- mixer_resource_poweroff((struct mixer_context *)ctx->ctx);
+ mixer_resource_poweroff(ctx->ctx);
return 0;
}
@@ -926,8 +925,7 @@ static const struct dev_pm_ops mixer_pm_ops = {
static int __devinit mixer_resources_init(struct exynos_drm_hdmi_context *ctx,
struct platform_device *pdev)
{
- struct mixer_context *mixer_ctx =
- (struct mixer_context *)ctx->ctx;
+ struct mixer_context *mixer_ctx = ctx->ctx;
struct device *dev = &pdev->dev;
struct mixer_resources *mixer_res = &mixer_ctx->mixer_res;
struct resource *res;
@@ -1076,7 +1074,7 @@ static int __devinit mixer_probe(struct platform_device *pdev)
goto fail;
/* register specific callback point to common hdmi. */
- exynos_drm_overlay_ops_register(&overlay_ops);
+ exynos_mixer_ops_register(&mixer_ops);
mixer_resource_poweron(ctx);
@@ -1093,7 +1091,7 @@ static int mixer_remove(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct exynos_drm_hdmi_context *drm_hdmi_ctx =
platform_get_drvdata(pdev);
- struct mixer_context *ctx = (struct mixer_context *)drm_hdmi_ctx->ctx;
+ struct mixer_context *ctx = drm_hdmi_ctx->ctx;
dev_info(dev, "remove successful\n");
diff --git a/drivers/gpu/drm/gma500/mdfld_dsi_output.h b/drivers/gpu/drm/gma500/mdfld_dsi_output.h
index 21071cef92a4..36eb0744841c 100644
--- a/drivers/gpu/drm/gma500/mdfld_dsi_output.h
+++ b/drivers/gpu/drm/gma500/mdfld_dsi_output.h
@@ -29,7 +29,6 @@
#define __MDFLD_DSI_OUTPUT_H__
#include <linux/backlight.h>
-#include <linux/version.h>
#include <drm/drmP.h>
#include <drm/drm.h>
#include <drm/drm_crtc.h>
diff --git a/drivers/gpu/drm/i810/i810_dma.c b/drivers/gpu/drm/i810/i810_dma.c
index 2c8a60c3b98e..f920fb5e42b6 100644
--- a/drivers/gpu/drm/i810/i810_dma.c
+++ b/drivers/gpu/drm/i810/i810_dma.c
@@ -129,6 +129,7 @@ static int i810_map_buffer(struct drm_buf *buf, struct drm_file *file_priv)
if (buf_priv->currently_mapped == I810_BUF_MAPPED)
return -EINVAL;
+ /* This is all entirely broken */
down_write(&current->mm->mmap_sem);
old_fops = file_priv->filp->f_op;
file_priv->filp->f_op = &i810_buffer_fops;
@@ -157,11 +158,8 @@ static int i810_unmap_buffer(struct drm_buf *buf)
if (buf_priv->currently_mapped != I810_BUF_MAPPED)
return -EINVAL;
- down_write(&current->mm->mmap_sem);
- retcode = do_munmap(current->mm,
- (unsigned long)buf_priv->virtual,
+ retcode = vm_munmap((unsigned long)buf_priv->virtual,
(size_t) buf->total);
- up_write(&current->mm->mmap_sem);
buf_priv->currently_mapped = I810_BUF_UNMAPPED;
buf_priv->virtual = NULL;
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index fdb7ccefffbd..b505b70dba05 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -1502,14 +1502,6 @@ static int i915_ppgtt_info(struct seq_file *m, void *data)
return 0;
}
-static int
-i915_debugfs_common_open(struct inode *inode,
- struct file *filp)
-{
- filp->private_data = inode->i_private;
- return 0;
-}
-
static ssize_t
i915_wedged_read(struct file *filp,
char __user *ubuf,
@@ -1560,7 +1552,7 @@ i915_wedged_write(struct file *filp,
static const struct file_operations i915_wedged_fops = {
.owner = THIS_MODULE,
- .open = i915_debugfs_common_open,
+ .open = simple_open,
.read = i915_wedged_read,
.write = i915_wedged_write,
.llseek = default_llseek,
@@ -1622,7 +1614,7 @@ i915_max_freq_write(struct file *filp,
static const struct file_operations i915_max_freq_fops = {
.owner = THIS_MODULE,
- .open = i915_debugfs_common_open,
+ .open = simple_open,
.read = i915_max_freq_read,
.write = i915_max_freq_write,
.llseek = default_llseek,
@@ -1693,7 +1685,7 @@ i915_cache_sharing_write(struct file *filp,
static const struct file_operations i915_cache_sharing_fops = {
.owner = THIS_MODULE,
- .open = i915_debugfs_common_open,
+ .open = simple_open,
.read = i915_cache_sharing_read,
.write = i915_cache_sharing_write,
.llseek = default_llseek,
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index dfa55e7478fb..ae8a64f9f845 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -64,7 +64,7 @@ MODULE_PARM_DESC(semaphores,
"Use semaphores for inter-ring sync (default: -1 (use per-chip defaults))");
int i915_enable_rc6 __read_mostly = -1;
-module_param_named(i915_enable_rc6, i915_enable_rc6, int, 0600);
+module_param_named(i915_enable_rc6, i915_enable_rc6, int, 0400);
MODULE_PARM_DESC(i915_enable_rc6,
"Enable power-saving render C-state 6. "
"Different stages can be selected via bitmask values "
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 4c65c639f772..0d1e4b7b4b99 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1087,11 +1087,9 @@ i915_gem_mmap_ioctl(struct drm_device *dev, void *data,
if (obj == NULL)
return -ENOENT;
- down_write(&current->mm->mmap_sem);
- addr = do_mmap(obj->filp, 0, args->size,
+ addr = vm_mmap(obj->filp, 0, args->size,
PROT_READ | PROT_WRITE, MAP_SHARED,
args->offset);
- up_write(&current->mm->mmap_sem);
drm_gem_object_unreference_unlocked(obj);
if (IS_ERR((void *)addr))
return addr;
@@ -1493,6 +1491,7 @@ i915_gem_object_move_off_active(struct drm_i915_gem_object *obj)
{
list_del_init(&obj->ring_list);
obj->last_rendering_seqno = 0;
+ obj->last_fenced_seqno = 0;
}
static void
@@ -1521,6 +1520,7 @@ i915_gem_object_move_to_inactive(struct drm_i915_gem_object *obj)
BUG_ON(!list_empty(&obj->gpu_write_list));
BUG_ON(!obj->active);
obj->ring = NULL;
+ obj->last_fenced_ring = NULL;
i915_gem_object_move_off_active(obj);
obj->fenced_gpu_access = false;
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 2abf4eb94039..b4bb1ef77ddc 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -3728,6 +3728,9 @@
#define GT_FIFO_FREE_ENTRIES 0x120008
#define GT_FIFO_NUM_RESERVED_ENTRIES 20
+#define GEN6_UCGCTL1 0x9400
+# define GEN6_BLBUNIT_CLOCK_GATE_DISABLE (1 << 5)
+
#define GEN6_UCGCTL2 0x9404
# define GEN6_RCZUNIT_CLOCK_GATE_DISABLE (1 << 13)
# define GEN6_RCPBUNIT_CLOCK_GATE_DISABLE (1 << 12)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 91b35fd1db8c..5908cd563400 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2245,6 +2245,33 @@ intel_pipe_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb,
}
static int
+intel_finish_fb(struct drm_framebuffer *old_fb)
+{
+ struct drm_i915_gem_object *obj = to_intel_framebuffer(old_fb)->obj;
+ struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
+ bool was_interruptible = dev_priv->mm.interruptible;
+ int ret;
+
+ wait_event(dev_priv->pending_flip_queue,
+ atomic_read(&dev_priv->mm.wedged) ||
+ atomic_read(&obj->pending_flip) == 0);
+
+ /* Big Hammer, we also need to ensure that any pending
+ * MI_WAIT_FOR_EVENT inside a user batch buffer on the
+ * current scanout is retired before unpinning the old
+ * framebuffer.
+ *
+ * This should only fail upon a hung GPU, in which case we
+ * can safely continue.
+ */
+ dev_priv->mm.interruptible = false;
+ ret = i915_gem_object_finish_gpu(obj);
+ dev_priv->mm.interruptible = was_interruptible;
+
+ return ret;
+}
+
+static int
intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
struct drm_framebuffer *old_fb)
{
@@ -2282,25 +2309,8 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
return ret;
}
- if (old_fb) {
- struct drm_i915_private *dev_priv = dev->dev_private;
- struct drm_i915_gem_object *obj = to_intel_framebuffer(old_fb)->obj;
-
- wait_event(dev_priv->pending_flip_queue,
- atomic_read(&dev_priv->mm.wedged) ||
- atomic_read(&obj->pending_flip) == 0);
-
- /* Big Hammer, we also need to ensure that any pending
- * MI_WAIT_FOR_EVENT inside a user batch buffer on the
- * current scanout is retired before unpinning the old
- * framebuffer.
- *
- * This should only fail upon a hung GPU, in which case we
- * can safely continue.
- */
- ret = i915_gem_object_finish_gpu(obj);
- (void) ret;
- }
+ if (old_fb)
+ intel_finish_fb(old_fb);
ret = intel_pipe_set_base_atomic(crtc, crtc->fb, x, y,
LEAVE_ATOMIC_MODE_SET);
@@ -3371,6 +3381,23 @@ static void intel_crtc_disable(struct drm_crtc *crtc)
struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
struct drm_device *dev = crtc->dev;
+ /* Flush any pending WAITs before we disable the pipe. Note that
+ * we need to drop the struct_mutex in order to acquire it again
+ * during the lowlevel dpms routines around a couple of the
+ * operations. It does not look trivial nor desirable to move
+ * that locking higher. So instead we leave a window for the
+ * submission of further commands on the fb before we can actually
+ * disable it. This race with userspace exists anyway, and we can
+ * only rely on the pipe being disabled by userspace after it
+ * receives the hotplug notification and has flushed any pending
+ * batches.
+ */
+ if (crtc->fb) {
+ mutex_lock(&dev->struct_mutex);
+ intel_finish_fb(crtc->fb);
+ mutex_unlock(&dev->struct_mutex);
+ }
+
crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
assert_plane_disabled(dev->dev_private, to_intel_crtc(crtc)->plane);
assert_pipe_disabled(dev->dev_private, to_intel_crtc(crtc)->pipe);
@@ -3451,8 +3478,11 @@ static bool intel_crtc_mode_fixup(struct drm_crtc *crtc,
return false;
}
- /* All interlaced capable intel hw wants timings in frames. */
- drm_mode_set_crtcinfo(adjusted_mode, 0);
+ /* All interlaced capable intel hw wants timings in frames. Note though
+ * that intel_lvds_mode_fixup does some funny tricks with the crtc
+ * timings, so we need to be careful not to clobber these.*/
+ if (!(adjusted_mode->private_flags & INTEL_MODE_CRTC_TIMINGS_SET))
+ drm_mode_set_crtcinfo(adjusted_mode, 0);
return true;
}
@@ -7438,7 +7468,13 @@ static int intel_gen6_queue_flip(struct drm_device *dev,
OUT_RING(fb->pitches[0] | obj->tiling_mode);
OUT_RING(obj->gtt_offset);
- pf = I915_READ(PF_CTL(intel_crtc->pipe)) & PF_ENABLE;
+ /* Contrary to the suggestions in the documentation,
+ * "Enable Panel Fitter" does not seem to be required when page
+ * flipping with a non-native mode, and worse causes a normal
+ * modeset to fail.
+ * pf = I915_READ(PF_CTL(intel_crtc->pipe)) & PF_ENABLE;
+ */
+ pf = 0;
pipesrc = I915_READ(PIPESRC(intel_crtc->pipe)) & 0x0fff0fff;
OUT_RING(pf | pipesrc);
ADVANCE_LP_RING();
@@ -8529,6 +8565,10 @@ static void gen6_init_clock_gating(struct drm_device *dev)
I915_WRITE(WM2_LP_ILK, 0);
I915_WRITE(WM1_LP_ILK, 0);
+ I915_WRITE(GEN6_UCGCTL1,
+ I915_READ(GEN6_UCGCTL1) |
+ GEN6_BLBUNIT_CLOCK_GATE_DISABLE);
+
/* According to the BSpec vol1g, bit 12 (RCPBUNIT) clock
* gating disable must be set. Failure to set it results in
* flickering pixels due to Z write ordering failures after
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 110552ff302c..4b637919f74f 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -219,14 +219,38 @@ intel_dp_max_data_rate(int max_link_clock, int max_lanes)
return (max_link_clock * max_lanes * 8) / 10;
}
+static bool
+intel_dp_adjust_dithering(struct intel_dp *intel_dp,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
+{
+ int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_dp));
+ int max_lanes = intel_dp_max_lane_count(intel_dp);
+ int max_rate, mode_rate;
+
+ mode_rate = intel_dp_link_required(mode->clock, 24);
+ max_rate = intel_dp_max_data_rate(max_link_clock, max_lanes);
+
+ if (mode_rate > max_rate) {
+ mode_rate = intel_dp_link_required(mode->clock, 18);
+ if (mode_rate > max_rate)
+ return false;
+
+ if (adjusted_mode)
+ adjusted_mode->private_flags
+ |= INTEL_MODE_DP_FORCE_6BPC;
+
+ return true;
+ }
+
+ return true;
+}
+
static int
intel_dp_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
struct intel_dp *intel_dp = intel_attached_dp(connector);
- int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_dp));
- int max_lanes = intel_dp_max_lane_count(intel_dp);
- int max_rate, mode_rate;
if (is_edp(intel_dp) && intel_dp->panel_fixed_mode) {
if (mode->hdisplay > intel_dp->panel_fixed_mode->hdisplay)
@@ -236,16 +260,8 @@ intel_dp_mode_valid(struct drm_connector *connector,
return MODE_PANEL;
}
- mode_rate = intel_dp_link_required(mode->clock, 24);
- max_rate = intel_dp_max_data_rate(max_link_clock, max_lanes);
-
- if (mode_rate > max_rate) {
- mode_rate = intel_dp_link_required(mode->clock, 18);
- if (mode_rate > max_rate)
- return MODE_CLOCK_HIGH;
- else
- mode->private_flags |= INTEL_MODE_DP_FORCE_6BPC;
- }
+ if (!intel_dp_adjust_dithering(intel_dp, mode, NULL))
+ return MODE_CLOCK_HIGH;
if (mode->clock < 10000)
return MODE_CLOCK_LOW;
@@ -672,7 +688,7 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
int lane_count, clock;
int max_lane_count = intel_dp_max_lane_count(intel_dp);
int max_clock = intel_dp_max_link_bw(intel_dp) == DP_LINK_BW_2_7 ? 1 : 0;
- int bpp = mode->private_flags & INTEL_MODE_DP_FORCE_6BPC ? 18 : 24;
+ int bpp;
static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 };
if (is_edp(intel_dp) && intel_dp->panel_fixed_mode) {
@@ -686,6 +702,11 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
mode->clock = intel_dp->panel_fixed_mode->clock;
}
+ if (!intel_dp_adjust_dithering(intel_dp, mode, adjusted_mode))
+ return false;
+
+ bpp = adjusted_mode->private_flags & INTEL_MODE_DP_FORCE_6BPC ? 18 : 24;
+
for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) {
for (clock = 0; clock <= max_clock; clock++) {
int link_avail = intel_dp_max_data_rate(intel_dp_link_clock(bws[clock]), lane_count);
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 5a14149b3794..715afa153025 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -105,6 +105,10 @@
#define INTEL_MODE_PIXEL_MULTIPLIER_SHIFT (0x0)
#define INTEL_MODE_PIXEL_MULTIPLIER_MASK (0xf << INTEL_MODE_PIXEL_MULTIPLIER_SHIFT)
#define INTEL_MODE_DP_FORCE_6BPC (0x10)
+/* This flag must be set by the encoder's mode_fixup if it changes the crtc
+ * timings in the mode to prevent the crtc fixup from overwriting them.
+ * Currently only lvds needs that. */
+#define INTEL_MODE_CRTC_TIMINGS_SET (0x20)
static inline void
intel_mode_set_pixel_multiplier(struct drm_display_mode *mode,
diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c
index 19ecd78b8a2c..6e9ee33fd412 100644
--- a/drivers/gpu/drm/i915/intel_fb.c
+++ b/drivers/gpu/drm/i915/intel_fb.c
@@ -279,6 +279,8 @@ void intel_fb_restore_mode(struct drm_device *dev)
struct drm_mode_config *config = &dev->mode_config;
struct drm_plane *plane;
+ mutex_lock(&dev->mode_config.mutex);
+
ret = drm_fb_helper_restore_fbdev_mode(&dev_priv->fbdev->helper);
if (ret)
DRM_DEBUG("failed to restore crtc mode\n");
@@ -286,4 +288,6 @@ void intel_fb_restore_mode(struct drm_device *dev)
/* Be sure to shut off any planes that may be active */
list_for_each_entry(plane, &config->plane_list, head)
plane->funcs->disable_plane(plane);
+
+ mutex_unlock(&dev->mode_config.mutex);
}
diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c
index 601c86e664af..8fdc95700218 100644
--- a/drivers/gpu/drm/i915/intel_i2c.c
+++ b/drivers/gpu/drm/i915/intel_i2c.c
@@ -390,7 +390,7 @@ int intel_setup_gmbus(struct drm_device *dev)
bus->has_gpio = intel_gpio_setup(bus, i);
/* XXX force bit banging until GMBUS is fully debugged */
- if (bus->has_gpio && IS_GEN2(dev))
+ if (bus->has_gpio)
bus->force_bit = true;
}
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index 95db2e988227..30e2c82101de 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -187,6 +187,8 @@ centre_horizontally(struct drm_display_mode *mode,
mode->crtc_hsync_start = mode->crtc_hblank_start + sync_pos;
mode->crtc_hsync_end = mode->crtc_hsync_start + sync_width;
+
+ mode->private_flags |= INTEL_MODE_CRTC_TIMINGS_SET;
}
static void
@@ -208,6 +210,8 @@ centre_vertically(struct drm_display_mode *mode,
mode->crtc_vsync_start = mode->crtc_vblank_start + sync_pos;
mode->crtc_vsync_end = mode->crtc_vsync_start + sync_width;
+
+ mode->private_flags |= INTEL_MODE_CRTC_TIMINGS_SET;
}
static inline u32 panel_fitter_scaling(u32 source, u32 target)
@@ -283,6 +287,8 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
for_each_pipe(pipe)
I915_WRITE(BCLRPAT(pipe), 0);
+ drm_mode_set_crtcinfo(adjusted_mode, 0);
+
switch (intel_lvds->fitting_mode) {
case DRM_MODE_SCALE_CENTER:
/*
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
index 230a141dbea3..48177ec4720e 100644
--- a/drivers/gpu/drm/i915/intel_panel.c
+++ b/drivers/gpu/drm/i915/intel_panel.c
@@ -47,8 +47,6 @@ intel_fixed_panel_mode(struct drm_display_mode *fixed_mode,
adjusted_mode->vtotal = fixed_mode->vtotal;
adjusted_mode->clock = fixed_mode->clock;
-
- drm_mode_set_crtcinfo(adjusted_mode, 0);
}
/* adjusted_mode has been preset to be the panel's fixed mode */
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index e25581a9f60f..f75806e5bff5 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -1038,7 +1038,7 @@ int intel_init_ring_buffer(struct drm_device *dev,
* of the buffer.
*/
ring->effective_size = ring->size;
- if (IS_I830(ring->dev))
+ if (IS_I830(ring->dev) || IS_845G(ring->dev))
ring->effective_size -= 128;
return 0;
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index a464771a7240..e90dfb625c42 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -95,7 +95,6 @@ ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb,
/* must disable */
sprctl |= SPRITE_TRICKLE_FEED_DISABLE;
sprctl |= SPRITE_ENABLE;
- sprctl |= SPRITE_DEST_KEY;
/* Sizes are 0 based */
src_w--;
diff --git a/drivers/gpu/drm/nouveau/nouveau_pm.c b/drivers/gpu/drm/nouveau/nouveau_pm.c
index 34d591b7d4ef..da3e7c3abab7 100644
--- a/drivers/gpu/drm/nouveau/nouveau_pm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_pm.c
@@ -235,6 +235,7 @@ nouveau_pm_profile_set(struct drm_device *dev, const char *profile)
return -EPERM;
strncpy(string, profile, sizeof(string));
+ string[sizeof(string) - 1] = 0;
if ((ptr = strchr(string, '\n')))
*ptr = '\0';
diff --git a/drivers/gpu/drm/nouveau/nv50_sor.c b/drivers/gpu/drm/nouveau/nv50_sor.c
index a7844ab6a50c..274640212475 100644
--- a/drivers/gpu/drm/nouveau/nv50_sor.c
+++ b/drivers/gpu/drm/nouveau/nv50_sor.c
@@ -42,7 +42,7 @@ nv50_sor_dp_lane_map(struct drm_device *dev, struct dcb_entry *dcb, u8 lane)
struct drm_nouveau_private *dev_priv = dev->dev_private;
static const u8 nvaf[] = { 24, 16, 8, 0 }; /* thanks, apple.. */
static const u8 nv50[] = { 16, 8, 0, 24 };
- if (dev_priv->card_type == 0xaf)
+ if (dev_priv->chipset == 0xaf)
return nvaf[lane];
return nv50[lane];
}
diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c b/drivers/gpu/drm/radeon/atombios_encoders.c
index e607c4d7dd98..2d39f9977e00 100644
--- a/drivers/gpu/drm/radeon/atombios_encoders.c
+++ b/drivers/gpu/drm/radeon/atombios_encoders.c
@@ -230,6 +230,10 @@ atombios_dvo_setup(struct drm_encoder *encoder, int action)
if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
return;
+ /* some R4xx chips have the wrong frev */
+ if (rdev->family <= CHIP_RV410)
+ frev = 1;
+
switch (frev) {
case 1:
switch (crev) {
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index 81801c176aa5..fe33d35dae8c 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -2553,7 +2553,7 @@ static void r100_pll_errata_after_data(struct radeon_device *rdev)
* or the chip could hang on a subsequent access
*/
if (rdev->pll_errata & CHIP_ERRATA_PLL_DELAY) {
- udelay(5000);
+ mdelay(5);
}
/* This function is required to workaround a hardware bug in some (all?)
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index 391bd2636a80..c8187c4b6ae8 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -1135,7 +1135,7 @@ static void r600_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc
}
if (rdev->flags & RADEON_IS_AGP) {
size_bf = mc->gtt_start;
- size_af = 0xFFFFFFFF - mc->gtt_end + 1;
+ size_af = 0xFFFFFFFF - mc->gtt_end;
if (size_bf > size_af) {
if (mc->mc_vram_size > size_bf) {
dev_warn(rdev->dev, "limiting VRAM\n");
@@ -1149,7 +1149,7 @@ static void r600_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc
mc->real_vram_size = size_af;
mc->mc_vram_size = size_af;
}
- mc->vram_start = mc->gtt_end;
+ mc->vram_start = mc->gtt_end + 1;
}
mc->vram_end = mc->vram_start + mc->mc_vram_size - 1;
dev_info(rdev->dev, "VRAM: %lluM 0x%08llX - 0x%08llX (%lluM used)\n",
@@ -2839,7 +2839,7 @@ void r600_rlc_stop(struct radeon_device *rdev)
/* r7xx asics need to soft reset RLC before halting */
WREG32(SRBM_SOFT_RESET, SOFT_RESET_RLC);
RREG32(SRBM_SOFT_RESET);
- udelay(15000);
+ mdelay(15);
WREG32(SRBM_SOFT_RESET, 0);
RREG32(SRBM_SOFT_RESET);
}
diff --git a/drivers/gpu/drm/radeon/r600_cp.c b/drivers/gpu/drm/radeon/r600_cp.c
index 84c546250955..75ed17c96115 100644
--- a/drivers/gpu/drm/radeon/r600_cp.c
+++ b/drivers/gpu/drm/radeon/r600_cp.c
@@ -407,7 +407,7 @@ static void r600_cp_load_microcode(drm_radeon_private_t *dev_priv)
RADEON_WRITE(R600_GRBM_SOFT_RESET, R600_SOFT_RESET_CP);
RADEON_READ(R600_GRBM_SOFT_RESET);
- DRM_UDELAY(15000);
+ mdelay(15);
RADEON_WRITE(R600_GRBM_SOFT_RESET, 0);
fw_data = (const __be32 *)dev_priv->me_fw->data;
@@ -500,7 +500,7 @@ static void r700_cp_load_microcode(drm_radeon_private_t *dev_priv)
RADEON_WRITE(R600_GRBM_SOFT_RESET, R600_SOFT_RESET_CP);
RADEON_READ(R600_GRBM_SOFT_RESET);
- DRM_UDELAY(15000);
+ mdelay(15);
RADEON_WRITE(R600_GRBM_SOFT_RESET, 0);
fw_data = (const __be32 *)dev_priv->pfp_fw->data;
@@ -1797,7 +1797,7 @@ static void r600_cp_init_ring_buffer(struct drm_device *dev,
RADEON_WRITE(R600_GRBM_SOFT_RESET, R600_SOFT_RESET_CP);
RADEON_READ(R600_GRBM_SOFT_RESET);
- DRM_UDELAY(15000);
+ mdelay(15);
RADEON_WRITE(R600_GRBM_SOFT_RESET, 0);
diff --git a/drivers/gpu/drm/radeon/radeon_clocks.c b/drivers/gpu/drm/radeon/radeon_clocks.c
index 6ae0c75f016a..9c6b29a41927 100644
--- a/drivers/gpu/drm/radeon/radeon_clocks.c
+++ b/drivers/gpu/drm/radeon/radeon_clocks.c
@@ -633,7 +633,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable)
tmp &= ~(R300_SCLK_FORCE_VAP);
tmp |= RADEON_SCLK_FORCE_CP;
WREG32_PLL(RADEON_SCLK_CNTL, tmp);
- udelay(15000);
+ mdelay(15);
tmp = RREG32_PLL(R300_SCLK_CNTL2);
tmp &= ~(R300_SCLK_FORCE_TCL |
@@ -651,12 +651,12 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable)
tmp |= (RADEON_ENGIN_DYNCLK_MODE |
(0x01 << RADEON_ACTIVE_HILO_LAT_SHIFT));
WREG32_PLL(RADEON_CLK_PWRMGT_CNTL, tmp);
- udelay(15000);
+ mdelay(15);
tmp = RREG32_PLL(RADEON_CLK_PIN_CNTL);
tmp |= RADEON_SCLK_DYN_START_CNTL;
WREG32_PLL(RADEON_CLK_PIN_CNTL, tmp);
- udelay(15000);
+ mdelay(15);
/* When DRI is enabled, setting DYN_STOP_LAT to zero can cause some R200
to lockup randomly, leave them as set by BIOS.
@@ -696,7 +696,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable)
tmp |= RADEON_SCLK_MORE_FORCEON;
}
WREG32_PLL(RADEON_SCLK_MORE_CNTL, tmp);
- udelay(15000);
+ mdelay(15);
}
/* RV200::A11 A12, RV250::A11 A12 */
@@ -709,7 +709,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable)
tmp |= RADEON_TCL_BYPASS_DISABLE;
WREG32_PLL(RADEON_PLL_PWRMGT_CNTL, tmp);
}
- udelay(15000);
+ mdelay(15);
/*enable dynamic mode for display clocks (PIXCLK and PIX2CLK) */
tmp = RREG32_PLL(RADEON_PIXCLKS_CNTL);
@@ -722,14 +722,14 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable)
RADEON_PIXCLK_TMDS_ALWAYS_ONb);
WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp);
- udelay(15000);
+ mdelay(15);
tmp = RREG32_PLL(RADEON_VCLK_ECP_CNTL);
tmp |= (RADEON_PIXCLK_ALWAYS_ONb |
RADEON_PIXCLK_DAC_ALWAYS_ONb);
WREG32_PLL(RADEON_VCLK_ECP_CNTL, tmp);
- udelay(15000);
+ mdelay(15);
}
} else {
/* Turn everything OFF (ForceON to everything) */
@@ -861,7 +861,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable)
}
WREG32_PLL(RADEON_SCLK_CNTL, tmp);
- udelay(16000);
+ mdelay(16);
if ((rdev->family == CHIP_R300) ||
(rdev->family == CHIP_R350)) {
@@ -870,7 +870,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable)
R300_SCLK_FORCE_GA |
R300_SCLK_FORCE_CBA);
WREG32_PLL(R300_SCLK_CNTL2, tmp);
- udelay(16000);
+ mdelay(16);
}
if (rdev->flags & RADEON_IS_IGP) {
@@ -878,7 +878,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable)
tmp &= ~(RADEON_FORCEON_MCLKA |
RADEON_FORCEON_YCLKA);
WREG32_PLL(RADEON_MCLK_CNTL, tmp);
- udelay(16000);
+ mdelay(16);
}
if ((rdev->family == CHIP_RV200) ||
@@ -887,7 +887,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable)
tmp = RREG32_PLL(RADEON_SCLK_MORE_CNTL);
tmp |= RADEON_SCLK_MORE_FORCEON;
WREG32_PLL(RADEON_SCLK_MORE_CNTL, tmp);
- udelay(16000);
+ mdelay(16);
}
tmp = RREG32_PLL(RADEON_PIXCLKS_CNTL);
@@ -900,7 +900,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable)
RADEON_PIXCLK_TMDS_ALWAYS_ONb);
WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp);
- udelay(16000);
+ mdelay(16);
tmp = RREG32_PLL(RADEON_VCLK_ECP_CNTL);
tmp &= ~(RADEON_PIXCLK_ALWAYS_ONb |
diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c
index 81fc100be7e1..2cad9fde92fc 100644
--- a/drivers/gpu/drm/radeon/radeon_combios.c
+++ b/drivers/gpu/drm/radeon/radeon_combios.c
@@ -2845,7 +2845,7 @@ bool radeon_combios_external_tmds_setup(struct drm_encoder *encoder)
case 4:
val = RBIOS16(index);
index += 2;
- udelay(val * 1000);
+ mdelay(val);
break;
case 6:
slave_addr = id & 0xff;
@@ -3044,7 +3044,7 @@ static void combios_parse_pll_table(struct drm_device *dev, uint16_t offset)
udelay(150);
break;
case 2:
- udelay(1000);
+ mdelay(1);
break;
case 3:
while (tmp--) {
@@ -3075,13 +3075,13 @@ static void combios_parse_pll_table(struct drm_device *dev, uint16_t offset)
/*mclk_cntl |= 0x00001111;*//* ??? */
WREG32_PLL(RADEON_MCLK_CNTL,
mclk_cntl);
- udelay(10000);
+ mdelay(10);
#endif
WREG32_PLL
(RADEON_CLK_PWRMGT_CNTL,
tmp &
~RADEON_CG_NO1_DEBUG_0);
- udelay(10000);
+ mdelay(10);
}
break;
default:
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c
index bd05156edbdb..3c2e7a000a2a 100644
--- a/drivers/gpu/drm/radeon/radeon_connectors.c
+++ b/drivers/gpu/drm/radeon/radeon_connectors.c
@@ -970,7 +970,7 @@ radeon_dvi_detect(struct drm_connector *connector, bool force)
encoder = obj_to_encoder(obj);
- if (encoder->encoder_type != DRM_MODE_ENCODER_DAC ||
+ if (encoder->encoder_type != DRM_MODE_ENCODER_DAC &&
encoder->encoder_type != DRM_MODE_ENCODER_TVDAC)
continue;
@@ -1000,6 +1000,7 @@ radeon_dvi_detect(struct drm_connector *connector, bool force)
* cases the DVI port is actually a virtual KVM port connected to the service
* processor.
*/
+out:
if ((!rdev->is_atom_bios) &&
(ret == connector_status_disconnected) &&
rdev->mode_info.bios_hardcoded_edid_size) {
@@ -1007,7 +1008,6 @@ radeon_dvi_detect(struct drm_connector *connector, bool force)
ret = connector_status_connected;
}
-out:
/* updated in get modes as well since we need to know if it's analog or digital */
radeon_connector_update_scratch_regs(connector, ret);
return ret;
diff --git a/drivers/gpu/drm/radeon/radeon_i2c.c b/drivers/gpu/drm/radeon/radeon_i2c.c
index 85bcfc8923a7..3edec1c198e3 100644
--- a/drivers/gpu/drm/radeon/radeon_i2c.c
+++ b/drivers/gpu/drm/radeon/radeon_i2c.c
@@ -900,6 +900,10 @@ struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev,
struct radeon_i2c_chan *i2c;
int ret;
+ /* don't add the mm_i2c bus unless hw_i2c is enabled */
+ if (rec->mm_i2c && (radeon_hw_i2c == 0))
+ return NULL;
+
i2c = kzalloc(sizeof(struct radeon_i2c_chan), GFP_KERNEL);
if (i2c == NULL)
return NULL;
diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c b/drivers/gpu/drm/radeon/radeon_irq_kms.c
index 66d5fe1c8174..65060b77c805 100644
--- a/drivers/gpu/drm/radeon/radeon_irq_kms.c
+++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c
@@ -147,6 +147,12 @@ static bool radeon_msi_ok(struct radeon_device *rdev)
(rdev->pdev->subsystem_device == 0x01fd))
return true;
+ /* RV515 seems to have MSI issues where it loses
+ * MSI rearms occasionally. This leads to lockups and freezes.
+ * disable it by default.
+ */
+ if (rdev->family == CHIP_RV515)
+ return false;
if (rdev->flags & RADEON_IS_IGP) {
/* APUs work fine with MSIs */
if (rdev->family >= CHIP_PALM)
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
index 2f46e0c8df53..42db254f6bb0 100644
--- a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
+++ b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
@@ -88,7 +88,7 @@ static void radeon_legacy_lvds_update(struct drm_encoder *encoder, int mode)
lvds_pll_cntl = RREG32(RADEON_LVDS_PLL_CNTL);
lvds_pll_cntl |= RADEON_LVDS_PLL_EN;
WREG32(RADEON_LVDS_PLL_CNTL, lvds_pll_cntl);
- udelay(1000);
+ mdelay(1);
lvds_pll_cntl = RREG32(RADEON_LVDS_PLL_CNTL);
lvds_pll_cntl &= ~RADEON_LVDS_PLL_RESET;
@@ -101,7 +101,7 @@ static void radeon_legacy_lvds_update(struct drm_encoder *encoder, int mode)
(backlight_level << RADEON_LVDS_BL_MOD_LEVEL_SHIFT));
if (is_mac)
lvds_gen_cntl |= RADEON_LVDS_BL_MOD_EN;
- udelay(panel_pwr_delay * 1000);
+ mdelay(panel_pwr_delay);
WREG32(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl);
break;
case DRM_MODE_DPMS_STANDBY:
@@ -118,10 +118,10 @@ static void radeon_legacy_lvds_update(struct drm_encoder *encoder, int mode)
WREG32(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl);
lvds_gen_cntl &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN | RADEON_LVDS_DIGON);
}
- udelay(panel_pwr_delay * 1000);
+ mdelay(panel_pwr_delay);
WREG32(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl);
WREG32_PLL(RADEON_PIXCLKS_CNTL, pixclks_cntl);
- udelay(panel_pwr_delay * 1000);
+ mdelay(panel_pwr_delay);
break;
}
@@ -656,7 +656,7 @@ static enum drm_connector_status radeon_legacy_primary_dac_detect(struct drm_enc
WREG32(RADEON_DAC_MACRO_CNTL, tmp);
- udelay(2000);
+ mdelay(2);
if (RREG32(RADEON_DAC_CNTL) & RADEON_DAC_CMP_OUTPUT)
found = connector_status_connected;
@@ -1499,7 +1499,7 @@ static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder
tmp = dac_cntl2 | RADEON_DAC2_DAC2_CLK_SEL | RADEON_DAC2_CMP_EN;
WREG32(RADEON_DAC_CNTL2, tmp);
- udelay(10000);
+ mdelay(10);
if (ASIC_IS_R300(rdev)) {
if (RREG32(RADEON_DAC_CNTL2) & RADEON_DAC2_CMP_OUT_B)
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c
index c62ae4be3845..cdab1aeaed6e 100644
--- a/drivers/gpu/drm/radeon/rv770.c
+++ b/drivers/gpu/drm/radeon/rv770.c
@@ -969,7 +969,7 @@ void r700_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc)
}
if (rdev->flags & RADEON_IS_AGP) {
size_bf = mc->gtt_start;
- size_af = 0xFFFFFFFF - mc->gtt_end + 1;
+ size_af = 0xFFFFFFFF - mc->gtt_end;
if (size_bf > size_af) {
if (mc->mc_vram_size > size_bf) {
dev_warn(rdev->dev, "limiting VRAM\n");
@@ -983,7 +983,7 @@ void r700_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc)
mc->real_vram_size = size_af;
mc->mc_vram_size = size_af;
}
- mc->vram_start = mc->gtt_end;
+ mc->vram_start = mc->gtt_end + 1;
}
mc->vram_end = mc->vram_start + mc->mc_vram_size - 1;
dev_info(rdev->dev, "VRAM: %lluM 0x%08llX - 0x%08llX (%lluM used)\n",
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c
index ac7a199ffece..27bda986fc2b 100644
--- a/drivers/gpu/drm/radeon/si.c
+++ b/drivers/gpu/drm/radeon/si.c
@@ -2999,8 +2999,8 @@ int si_rlc_init(struct radeon_device *rdev)
}
r = radeon_bo_pin(rdev->rlc.save_restore_obj, RADEON_GEM_DOMAIN_VRAM,
&rdev->rlc.save_restore_gpu_addr);
+ radeon_bo_unreserve(rdev->rlc.save_restore_obj);
if (r) {
- radeon_bo_unreserve(rdev->rlc.save_restore_obj);
dev_warn(rdev->dev, "(%d) pin RLC sr bo failed\n", r);
si_rlc_fini(rdev);
return r;
@@ -3023,9 +3023,8 @@ int si_rlc_init(struct radeon_device *rdev)
}
r = radeon_bo_pin(rdev->rlc.clear_state_obj, RADEON_GEM_DOMAIN_VRAM,
&rdev->rlc.clear_state_gpu_addr);
+ radeon_bo_unreserve(rdev->rlc.clear_state_obj);
if (r) {
-
- radeon_bo_unreserve(rdev->rlc.clear_state_obj);
dev_warn(rdev->dev, "(%d) pin RLC c bo failed\n", r);
si_rlc_fini(rdev);
return r;
diff --git a/drivers/gpu/drm/savage/savage_state.c b/drivers/gpu/drm/savage/savage_state.c
index 031aaaf79ac2..b6d8608375cd 100644
--- a/drivers/gpu/drm/savage/savage_state.c
+++ b/drivers/gpu/drm/savage/savage_state.c
@@ -988,7 +988,7 @@ int savage_bci_cmdbuf(struct drm_device *dev, void *data, struct drm_file *file_
* for locking on FreeBSD.
*/
if (cmdbuf->size) {
- kcmd_addr = kmalloc(cmdbuf->size * 8, GFP_KERNEL);
+ kcmd_addr = kmalloc_array(cmdbuf->size, 8, GFP_KERNEL);
if (kcmd_addr == NULL)
return -ENOMEM;
@@ -1015,8 +1015,8 @@ int savage_bci_cmdbuf(struct drm_device *dev, void *data, struct drm_file *file_
cmdbuf->vb_addr = kvb_addr;
}
if (cmdbuf->nbox) {
- kbox_addr = kmalloc(cmdbuf->nbox * sizeof(struct drm_clip_rect),
- GFP_KERNEL);
+ kbox_addr = kmalloc_array(cmdbuf->nbox, sizeof(struct drm_clip_rect),
+ GFP_KERNEL);
if (kbox_addr == NULL) {
ret = -ENOMEM;
goto done;
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index a3d033252995..ffddcba32af6 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -34,7 +34,7 @@ config HID
config HID_BATTERY_STRENGTH
bool
depends on HID && POWER_SUPPLY && HID = POWER_SUPPLY
- default y
+ default n
config HIDRAW
bool "/dev/hidraw raw HID device support"
diff --git a/drivers/hid/hid-picolcd.c b/drivers/hid/hid-picolcd.c
index 12f9777c385d..45c3433f7986 100644
--- a/drivers/hid/hid-picolcd.c
+++ b/drivers/hid/hid-picolcd.c
@@ -1525,12 +1525,6 @@ static const struct file_operations picolcd_debug_reset_fops = {
/*
* The "eeprom" file
*/
-static int picolcd_debug_eeprom_open(struct inode *i, struct file *f)
-{
- f->private_data = i->i_private;
- return 0;
-}
-
static ssize_t picolcd_debug_eeprom_read(struct file *f, char __user *u,
size_t s, loff_t *off)
{
@@ -1618,7 +1612,7 @@ static ssize_t picolcd_debug_eeprom_write(struct file *f, const char __user *u,
*/
static const struct file_operations picolcd_debug_eeprom_fops = {
.owner = THIS_MODULE,
- .open = picolcd_debug_eeprom_open,
+ .open = simple_open,
.read = picolcd_debug_eeprom_read,
.write = picolcd_debug_eeprom_write,
.llseek = generic_file_llseek,
@@ -1627,12 +1621,6 @@ static const struct file_operations picolcd_debug_eeprom_fops = {
/*
* The "flash" file
*/
-static int picolcd_debug_flash_open(struct inode *i, struct file *f)
-{
- f->private_data = i->i_private;
- return 0;
-}
-
/* record a flash address to buf (bounds check to be done by caller) */
static int _picolcd_flash_setaddr(struct picolcd_data *data, u8 *buf, long off)
{
@@ -1817,7 +1805,7 @@ static ssize_t picolcd_debug_flash_write(struct file *f, const char __user *u,
*/
static const struct file_operations picolcd_debug_flash_fops = {
.owner = THIS_MODULE,
- .open = picolcd_debug_flash_open,
+ .open = simple_open,
.read = picolcd_debug_flash_read,
.write = picolcd_debug_flash_write,
.llseek = generic_file_llseek,
diff --git a/drivers/hid/hid-tivo.c b/drivers/hid/hid-tivo.c
index de47039c708c..9f85f827607f 100644
--- a/drivers/hid/hid-tivo.c
+++ b/drivers/hid/hid-tivo.c
@@ -62,7 +62,7 @@ static int tivo_input_mapping(struct hid_device *hdev, struct hid_input *hi,
static const struct hid_device_id tivo_devices[] = {
/* TiVo Slide Bluetooth remote, pairs with a Broadcom dongle */
- { HID_USB_DEVICE(USB_VENDOR_ID_TIVO, USB_DEVICE_ID_TIVO_SLIDE_BT) },
+ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_TIVO, USB_DEVICE_ID_TIVO_SLIDE_BT) },
{ HID_USB_DEVICE(USB_VENDOR_ID_TIVO, USB_DEVICE_ID_TIVO_SLIDE) },
{ }
};
diff --git a/drivers/hid/hid-wiimote-debug.c b/drivers/hid/hid-wiimote-debug.c
index 17dabc1f339e..eec329197c16 100644
--- a/drivers/hid/hid-wiimote-debug.c
+++ b/drivers/hid/hid-wiimote-debug.c
@@ -23,12 +23,6 @@ struct wiimote_debug {
struct dentry *drm;
};
-static int wiidebug_eeprom_open(struct inode *i, struct file *f)
-{
- f->private_data = i->i_private;
- return 0;
-}
-
static ssize_t wiidebug_eeprom_read(struct file *f, char __user *u, size_t s,
loff_t *off)
{
@@ -83,7 +77,7 @@ static ssize_t wiidebug_eeprom_read(struct file *f, char __user *u, size_t s,
static const struct file_operations wiidebug_eeprom_fops = {
.owner = THIS_MODULE,
- .open = wiidebug_eeprom_open,
+ .open = simple_open,
.read = wiidebug_eeprom_read,
.llseek = generic_file_llseek,
};
diff --git a/drivers/hsi/clients/hsi_char.c b/drivers/hsi/clients/hsi_char.c
index 88a050df2389..3ad91f6447d8 100644
--- a/drivers/hsi/clients/hsi_char.c
+++ b/drivers/hsi/clients/hsi_char.c
@@ -123,7 +123,7 @@ struct hsc_client_data {
static unsigned int hsc_major;
/* Maximum buffer size that hsi_char will accept from userspace */
static unsigned int max_data_size = 0x1000;
-module_param(max_data_size, uint, S_IRUSR | S_IWUSR);
+module_param(max_data_size, uint, 0);
MODULE_PARM_DESC(max_data_size, "max read/write data size [4,8..65536] (^2)");
static void hsc_add_tail(struct hsc_channel *channel, struct hsi_msg *msg,
diff --git a/drivers/hsi/hsi.c b/drivers/hsi/hsi.c
index 4e2d79b79334..2d58f939d27f 100644
--- a/drivers/hsi/hsi.c
+++ b/drivers/hsi/hsi.c
@@ -21,26 +21,13 @@
*/
#include <linux/hsi/hsi.h>
#include <linux/compiler.h>
-#include <linux/rwsem.h>
#include <linux/list.h>
-#include <linux/spinlock.h>
#include <linux/kobject.h>
#include <linux/slab.h>
#include <linux/string.h>
+#include <linux/notifier.h>
#include "hsi_core.h"
-static struct device_type hsi_ctrl = {
- .name = "hsi_controller",
-};
-
-static struct device_type hsi_cl = {
- .name = "hsi_client",
-};
-
-static struct device_type hsi_port = {
- .name = "hsi_port",
-};
-
static ssize_t modalias_show(struct device *dev,
struct device_attribute *a __maybe_unused, char *buf)
{
@@ -54,8 +41,7 @@ static struct device_attribute hsi_bus_dev_attrs[] = {
static int hsi_bus_uevent(struct device *dev, struct kobj_uevent_env *env)
{
- if (dev->type == &hsi_cl)
- add_uevent_var(env, "MODALIAS=hsi:%s", dev_name(dev));
+ add_uevent_var(env, "MODALIAS=hsi:%s", dev_name(dev));
return 0;
}
@@ -80,12 +66,10 @@ static void hsi_client_release(struct device *dev)
static void hsi_new_client(struct hsi_port *port, struct hsi_board_info *info)
{
struct hsi_client *cl;
- unsigned long flags;
cl = kzalloc(sizeof(*cl), GFP_KERNEL);
if (!cl)
return;
- cl->device.type = &hsi_cl;
cl->tx_cfg = info->tx_cfg;
cl->rx_cfg = info->rx_cfg;
cl->device.bus = &hsi_bus_type;
@@ -93,14 +77,11 @@ static void hsi_new_client(struct hsi_port *port, struct hsi_board_info *info)
cl->device.release = hsi_client_release;
dev_set_name(&cl->device, info->name);
cl->device.platform_data = info->platform_data;
- spin_lock_irqsave(&port->clock, flags);
- list_add_tail(&cl->link, &port->clients);
- spin_unlock_irqrestore(&port->clock, flags);
if (info->archdata)
cl->device.archdata = *info->archdata;
if (device_register(&cl->device) < 0) {
pr_err("hsi: failed to register client: %s\n", info->name);
- kfree(cl);
+ put_device(&cl->device);
}
}
@@ -120,13 +101,6 @@ static void hsi_scan_board_info(struct hsi_controller *hsi)
static int hsi_remove_client(struct device *dev, void *data __maybe_unused)
{
- struct hsi_client *cl = to_hsi_client(dev);
- struct hsi_port *port = to_hsi_port(dev->parent);
- unsigned long flags;
-
- spin_lock_irqsave(&port->clock, flags);
- list_del(&cl->link);
- spin_unlock_irqrestore(&port->clock, flags);
device_unregister(dev);
return 0;
@@ -140,12 +114,17 @@ static int hsi_remove_port(struct device *dev, void *data __maybe_unused)
return 0;
}
-static void hsi_controller_release(struct device *dev __maybe_unused)
+static void hsi_controller_release(struct device *dev)
{
+ struct hsi_controller *hsi = to_hsi_controller(dev);
+
+ kfree(hsi->port);
+ kfree(hsi);
}
-static void hsi_port_release(struct device *dev __maybe_unused)
+static void hsi_port_release(struct device *dev)
{
+ kfree(to_hsi_port(dev));
}
/**
@@ -170,20 +149,12 @@ int hsi_register_controller(struct hsi_controller *hsi)
unsigned int i;
int err;
- hsi->device.type = &hsi_ctrl;
- hsi->device.bus = &hsi_bus_type;
- hsi->device.release = hsi_controller_release;
- err = device_register(&hsi->device);
+ err = device_add(&hsi->device);
if (err < 0)
return err;
for (i = 0; i < hsi->num_ports; i++) {
- hsi->port[i].device.parent = &hsi->device;
- hsi->port[i].device.bus = &hsi_bus_type;
- hsi->port[i].device.release = hsi_port_release;
- hsi->port[i].device.type = &hsi_port;
- INIT_LIST_HEAD(&hsi->port[i].clients);
- spin_lock_init(&hsi->port[i].clock);
- err = device_register(&hsi->port[i].device);
+ hsi->port[i]->device.parent = &hsi->device;
+ err = device_add(&hsi->port[i]->device);
if (err < 0)
goto out;
}
@@ -192,7 +163,9 @@ int hsi_register_controller(struct hsi_controller *hsi)
return 0;
out:
- hsi_unregister_controller(hsi);
+ while (i-- > 0)
+ device_del(&hsi->port[i]->device);
+ device_del(&hsi->device);
return err;
}
@@ -223,6 +196,29 @@ static inline int hsi_dummy_cl(struct hsi_client *cl __maybe_unused)
}
/**
+ * hsi_put_controller - Free an HSI controller
+ *
+ * @hsi: Pointer to the HSI controller to freed
+ *
+ * HSI controller drivers should only use this function if they need
+ * to free their allocated hsi_controller structures before a successful
+ * call to hsi_register_controller. Other use is not allowed.
+ */
+void hsi_put_controller(struct hsi_controller *hsi)
+{
+ unsigned int i;
+
+ if (!hsi)
+ return;
+
+ for (i = 0; i < hsi->num_ports; i++)
+ if (hsi->port && hsi->port[i])
+ put_device(&hsi->port[i]->device);
+ put_device(&hsi->device);
+}
+EXPORT_SYMBOL_GPL(hsi_put_controller);
+
+/**
* hsi_alloc_controller - Allocate an HSI controller and its ports
* @n_ports: Number of ports on the HSI controller
* @flags: Kernel allocation flags
@@ -232,55 +228,52 @@ static inline int hsi_dummy_cl(struct hsi_client *cl __maybe_unused)
struct hsi_controller *hsi_alloc_controller(unsigned int n_ports, gfp_t flags)
{
struct hsi_controller *hsi;
- struct hsi_port *port;
+ struct hsi_port **port;
unsigned int i;
if (!n_ports)
return NULL;
- port = kzalloc(sizeof(*port)*n_ports, flags);
- if (!port)
- return NULL;
hsi = kzalloc(sizeof(*hsi), flags);
if (!hsi)
- goto out;
- for (i = 0; i < n_ports; i++) {
- dev_set_name(&port[i].device, "port%d", i);
- port[i].num = i;
- port[i].async = hsi_dummy_msg;
- port[i].setup = hsi_dummy_cl;
- port[i].flush = hsi_dummy_cl;
- port[i].start_tx = hsi_dummy_cl;
- port[i].stop_tx = hsi_dummy_cl;
- port[i].release = hsi_dummy_cl;
- mutex_init(&port[i].lock);
+ return NULL;
+ port = kzalloc(sizeof(*port)*n_ports, flags);
+ if (!port) {
+ kfree(hsi);
+ return NULL;
}
hsi->num_ports = n_ports;
hsi->port = port;
+ hsi->device.release = hsi_controller_release;
+ device_initialize(&hsi->device);
+
+ for (i = 0; i < n_ports; i++) {
+ port[i] = kzalloc(sizeof(**port), flags);
+ if (port[i] == NULL)
+ goto out;
+ port[i]->num = i;
+ port[i]->async = hsi_dummy_msg;
+ port[i]->setup = hsi_dummy_cl;
+ port[i]->flush = hsi_dummy_cl;
+ port[i]->start_tx = hsi_dummy_cl;
+ port[i]->stop_tx = hsi_dummy_cl;
+ port[i]->release = hsi_dummy_cl;
+ mutex_init(&port[i]->lock);
+ ATOMIC_INIT_NOTIFIER_HEAD(&port[i]->n_head);
+ dev_set_name(&port[i]->device, "port%d", i);
+ hsi->port[i]->device.release = hsi_port_release;
+ device_initialize(&hsi->port[i]->device);
+ }
return hsi;
out:
- kfree(port);
+ hsi_put_controller(hsi);
return NULL;
}
EXPORT_SYMBOL_GPL(hsi_alloc_controller);
/**
- * hsi_free_controller - Free an HSI controller
- * @hsi: Pointer to HSI controller
- */
-void hsi_free_controller(struct hsi_controller *hsi)
-{
- if (!hsi)
- return;
-
- kfree(hsi->port);
- kfree(hsi);
-}
-EXPORT_SYMBOL_GPL(hsi_free_controller);
-
-/**
* hsi_free_msg - Free an HSI message
* @msg: Pointer to the HSI message
*
@@ -414,37 +407,67 @@ void hsi_release_port(struct hsi_client *cl)
}
EXPORT_SYMBOL_GPL(hsi_release_port);
-static int hsi_start_rx(struct hsi_client *cl, void *data __maybe_unused)
+static int hsi_event_notifier_call(struct notifier_block *nb,
+ unsigned long event, void *data __maybe_unused)
{
- if (cl->hsi_start_rx)
- (*cl->hsi_start_rx)(cl);
+ struct hsi_client *cl = container_of(nb, struct hsi_client, nb);
+
+ (*cl->ehandler)(cl, event);
return 0;
}
-static int hsi_stop_rx(struct hsi_client *cl, void *data __maybe_unused)
+/**
+ * hsi_register_port_event - Register a client to receive port events
+ * @cl: HSI client that wants to receive port events
+ * @cb: Event handler callback
+ *
+ * Clients should register a callback to be able to receive
+ * events from the ports. Registration should happen after
+ * claiming the port.
+ * The handler can be called in interrupt context.
+ *
+ * Returns -errno on error, or 0 on success.
+ */
+int hsi_register_port_event(struct hsi_client *cl,
+ void (*handler)(struct hsi_client *, unsigned long))
{
- if (cl->hsi_stop_rx)
- (*cl->hsi_stop_rx)(cl);
+ struct hsi_port *port = hsi_get_port(cl);
- return 0;
+ if (!handler || cl->ehandler)
+ return -EINVAL;
+ if (!hsi_port_claimed(cl))
+ return -EACCES;
+ cl->ehandler = handler;
+ cl->nb.notifier_call = hsi_event_notifier_call;
+
+ return atomic_notifier_chain_register(&port->n_head, &cl->nb);
}
+EXPORT_SYMBOL_GPL(hsi_register_port_event);
-static int hsi_port_for_each_client(struct hsi_port *port, void *data,
- int (*fn)(struct hsi_client *cl, void *data))
+/**
+ * hsi_unregister_port_event - Stop receiving port events for a client
+ * @cl: HSI client that wants to stop receiving port events
+ *
+ * Clients should call this function before releasing their associated
+ * port.
+ *
+ * Returns -errno on error, or 0 on success.
+ */
+int hsi_unregister_port_event(struct hsi_client *cl)
{
- struct hsi_client *cl;
+ struct hsi_port *port = hsi_get_port(cl);
+ int err;
- spin_lock(&port->clock);
- list_for_each_entry(cl, &port->clients, link) {
- spin_unlock(&port->clock);
- (*fn)(cl, data);
- spin_lock(&port->clock);
- }
- spin_unlock(&port->clock);
+ WARN_ON(!hsi_port_claimed(cl));
- return 0;
+ err = atomic_notifier_chain_unregister(&port->n_head, &cl->nb);
+ if (!err)
+ cl->ehandler = NULL;
+
+ return err;
}
+EXPORT_SYMBOL_GPL(hsi_unregister_port_event);
/**
* hsi_event -Notifies clients about port events
@@ -458,22 +481,12 @@ static int hsi_port_for_each_client(struct hsi_port *port, void *data,
* Events:
* HSI_EVENT_START_RX - Incoming wake line high
* HSI_EVENT_STOP_RX - Incoming wake line down
+ *
+ * Returns -errno on error, or 0 on success.
*/
-void hsi_event(struct hsi_port *port, unsigned int event)
+int hsi_event(struct hsi_port *port, unsigned long event)
{
- int (*fn)(struct hsi_client *cl, void *data);
-
- switch (event) {
- case HSI_EVENT_START_RX:
- fn = hsi_start_rx;
- break;
- case HSI_EVENT_STOP_RX:
- fn = hsi_stop_rx;
- break;
- default:
- return;
- }
- hsi_port_for_each_client(port, NULL, fn);
+ return atomic_notifier_call_chain(&port->n_head, event, NULL);
}
EXPORT_SYMBOL_GPL(hsi_event);
diff --git a/drivers/hwmon/acpi_power_meter.c b/drivers/hwmon/acpi_power_meter.c
index 145f13580ff0..9140236a0182 100644
--- a/drivers/hwmon/acpi_power_meter.c
+++ b/drivers/hwmon/acpi_power_meter.c
@@ -391,6 +391,7 @@ static ssize_t show_str(struct device *dev,
break;
default:
BUG();
+ val = "";
}
return sprintf(buf, "%s\n", val);
diff --git a/drivers/hwmon/ads1015.c b/drivers/hwmon/ads1015.c
index 7765e4f74ec5..1958f03efd7a 100644
--- a/drivers/hwmon/ads1015.c
+++ b/drivers/hwmon/ads1015.c
@@ -59,14 +59,11 @@ struct ads1015_data {
struct ads1015_channel_data channel_data[ADS1015_CHANNELS];
};
-static int ads1015_read_value(struct i2c_client *client, unsigned int channel,
- int *value)
+static int ads1015_read_adc(struct i2c_client *client, unsigned int channel)
{
u16 config;
- s16 conversion;
struct ads1015_data *data = i2c_get_clientdata(client);
unsigned int pga = data->channel_data[channel].pga;
- int fullscale;
unsigned int data_rate = data->channel_data[channel].data_rate;
unsigned int conversion_time_ms;
int res;
@@ -78,7 +75,6 @@ static int ads1015_read_value(struct i2c_client *client, unsigned int channel,
if (res < 0)
goto err_unlock;
config = res;
- fullscale = fullscale_table[pga];
conversion_time_ms = DIV_ROUND_UP(1000, data_rate_table[data_rate]);
/* setup and start single conversion */
@@ -105,33 +101,36 @@ static int ads1015_read_value(struct i2c_client *client, unsigned int channel,
}
res = i2c_smbus_read_word_swapped(client, ADS1015_CONVERSION);
- if (res < 0)
- goto err_unlock;
- conversion = res;
-
- mutex_unlock(&data->update_lock);
-
- *value = DIV_ROUND_CLOSEST(conversion * fullscale, 0x7ff0);
-
- return 0;
err_unlock:
mutex_unlock(&data->update_lock);
return res;
}
+static int ads1015_reg_to_mv(struct i2c_client *client, unsigned int channel,
+ s16 reg)
+{
+ struct ads1015_data *data = i2c_get_clientdata(client);
+ unsigned int pga = data->channel_data[channel].pga;
+ int fullscale = fullscale_table[pga];
+
+ return DIV_ROUND_CLOSEST(reg * fullscale, 0x7ff0);
+}
+
/* sysfs callback function */
static ssize_t show_in(struct device *dev, struct device_attribute *da,
char *buf)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
struct i2c_client *client = to_i2c_client(dev);
- int in;
int res;
+ int index = attr->index;
- res = ads1015_read_value(client, attr->index, &in);
+ res = ads1015_read_adc(client, index);
+ if (res < 0)
+ return res;
- return (res < 0) ? res : sprintf(buf, "%d\n", in);
+ return sprintf(buf, "%d\n", ads1015_reg_to_mv(client, index, res));
}
static const struct sensor_device_attribute ads1015_in[] = {
diff --git a/drivers/hwmon/fam15h_power.c b/drivers/hwmon/fam15h_power.c
index b7494af1e4a9..37a8fc92b44a 100644
--- a/drivers/hwmon/fam15h_power.c
+++ b/drivers/hwmon/fam15h_power.c
@@ -122,6 +122,38 @@ static bool __devinit fam15h_power_is_internal_node0(struct pci_dev *f4)
return true;
}
+/*
+ * Newer BKDG versions have an updated recommendation on how to properly
+ * initialize the running average range (was: 0xE, now: 0x9). This avoids
+ * counter saturations resulting in bogus power readings.
+ * We correct this value ourselves to cope with older BIOSes.
+ */
+static void __devinit tweak_runavg_range(struct pci_dev *pdev)
+{
+ u32 val;
+ const struct pci_device_id affected_device = {
+ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_NB_F4) };
+
+ /*
+ * let this quirk apply only to the current version of the
+ * northbridge, since future versions may change the behavior
+ */
+ if (!pci_match_id(&affected_device, pdev))
+ return;
+
+ pci_bus_read_config_dword(pdev->bus,
+ PCI_DEVFN(PCI_SLOT(pdev->devfn), 5),
+ REG_TDP_RUNNING_AVERAGE, &val);
+ if ((val & 0xf) != 0xe)
+ return;
+
+ val &= ~0xf;
+ val |= 0x9;
+ pci_bus_write_config_dword(pdev->bus,
+ PCI_DEVFN(PCI_SLOT(pdev->devfn), 5),
+ REG_TDP_RUNNING_AVERAGE, val);
+}
+
static void __devinit fam15h_power_init_data(struct pci_dev *f4,
struct fam15h_power_data *data)
{
@@ -155,6 +187,13 @@ static int __devinit fam15h_power_probe(struct pci_dev *pdev,
struct device *dev;
int err;
+ /*
+ * though we ignore every other northbridge, we still have to
+ * do the tweaking on _each_ node in MCM processors as the counters
+ * are working hand-in-hand
+ */
+ tweak_runavg_range(pdev);
+
if (!fam15h_power_is_internal_node0(pdev)) {
err = -ENODEV;
goto exit;
diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c
index be51037363c8..29b319db573e 100644
--- a/drivers/hwmon/pmbus/pmbus_core.c
+++ b/drivers/hwmon/pmbus/pmbus_core.c
@@ -710,13 +710,13 @@ static u16 pmbus_data2reg(struct pmbus_data *data,
* If a negative value is stored in any of the referenced registers, this value
* reflects an error code which will be returned.
*/
-static int pmbus_get_boolean(struct pmbus_data *data, int index, int *val)
+static int pmbus_get_boolean(struct pmbus_data *data, int index)
{
u8 s1 = (index >> 24) & 0xff;
u8 s2 = (index >> 16) & 0xff;
u8 reg = (index >> 8) & 0xff;
u8 mask = index & 0xff;
- int status;
+ int ret, status;
u8 regval;
status = data->status[reg];
@@ -725,7 +725,7 @@ static int pmbus_get_boolean(struct pmbus_data *data, int index, int *val)
regval = status & mask;
if (!s1 && !s2)
- *val = !!regval;
+ ret = !!regval;
else {
long v1, v2;
struct pmbus_sensor *sensor1, *sensor2;
@@ -739,9 +739,9 @@ static int pmbus_get_boolean(struct pmbus_data *data, int index, int *val)
v1 = pmbus_reg2data(data, sensor1);
v2 = pmbus_reg2data(data, sensor2);
- *val = !!(regval && v1 >= v2);
+ ret = !!(regval && v1 >= v2);
}
- return 0;
+ return ret;
}
static ssize_t pmbus_show_boolean(struct device *dev,
@@ -750,11 +750,10 @@ static ssize_t pmbus_show_boolean(struct device *dev,
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
struct pmbus_data *data = pmbus_update_device(dev);
int val;
- int err;
- err = pmbus_get_boolean(data, attr->index, &val);
- if (err)
- return err;
+ val = pmbus_get_boolean(data, attr->index);
+ if (val < 0)
+ return val;
return snprintf(buf, PAGE_SIZE, "%d\n", val);
}
diff --git a/drivers/hwmon/smsc47b397.c b/drivers/hwmon/smsc47b397.c
index d3b778da3f86..c5f6be478bad 100644
--- a/drivers/hwmon/smsc47b397.c
+++ b/drivers/hwmon/smsc47b397.c
@@ -343,10 +343,11 @@ exit:
return err;
}
-static int __init smsc47b397_find(unsigned short *addr)
+static int __init smsc47b397_find(void)
{
u8 id, rev;
char *name;
+ unsigned short addr;
superio_enter();
id = force_id ? force_id : superio_inb(SUPERIO_REG_DEVID);
@@ -370,14 +371,14 @@ static int __init smsc47b397_find(unsigned short *addr)
rev = superio_inb(SUPERIO_REG_DEVREV);
superio_select(SUPERIO_REG_LD8);
- *addr = (superio_inb(SUPERIO_REG_BASE_MSB) << 8)
+ addr = (superio_inb(SUPERIO_REG_BASE_MSB) << 8)
| superio_inb(SUPERIO_REG_BASE_LSB);
pr_info("found SMSC %s (base address 0x%04x, revision %u)\n",
- name, *addr, rev);
+ name, addr, rev);
superio_exit();
- return 0;
+ return addr;
}
static int __init smsc47b397_init(void)
@@ -385,9 +386,10 @@ static int __init smsc47b397_init(void)
unsigned short address;
int ret;
- ret = smsc47b397_find(&address);
- if (ret)
+ ret = smsc47b397_find();
+ if (ret < 0)
return ret;
+ address = ret;
ret = platform_driver_register(&smsc47b397_driver);
if (ret)
diff --git a/drivers/hwmon/smsc47m1.c b/drivers/hwmon/smsc47m1.c
index c590c1469793..b5aa38dd7ab9 100644
--- a/drivers/hwmon/smsc47m1.c
+++ b/drivers/hwmon/smsc47m1.c
@@ -491,10 +491,10 @@ static const struct attribute_group smsc47m1_group = {
.attrs = smsc47m1_attributes,
};
-static int __init smsc47m1_find(unsigned short *addr,
- struct smsc47m1_sio_data *sio_data)
+static int __init smsc47m1_find(struct smsc47m1_sio_data *sio_data)
{
u8 val;
+ unsigned short addr;
superio_enter();
val = force_id ? force_id : superio_inb(SUPERIO_REG_DEVID);
@@ -546,9 +546,9 @@ static int __init smsc47m1_find(unsigned short *addr,
}
superio_select();
- *addr = (superio_inb(SUPERIO_REG_BASE) << 8)
+ addr = (superio_inb(SUPERIO_REG_BASE) << 8)
| superio_inb(SUPERIO_REG_BASE + 1);
- if (*addr == 0) {
+ if (addr == 0) {
pr_info("Device address not set, will not use\n");
superio_exit();
return -ENODEV;
@@ -565,7 +565,7 @@ static int __init smsc47m1_find(unsigned short *addr,
}
superio_exit();
- return 0;
+ return addr;
}
/* Restore device to its initial state */
@@ -938,13 +938,15 @@ static int __init sm_smsc47m1_init(void)
unsigned short address;
struct smsc47m1_sio_data sio_data;
- if (smsc47m1_find(&address, &sio_data))
- return -ENODEV;
+ err = smsc47m1_find(&sio_data);
+ if (err < 0)
+ return err;
+ address = err;
/* Sets global pdev as a side effect */
err = smsc47m1_device_add(address, &sio_data);
if (err)
- goto exit;
+ return err;
err = platform_driver_probe(&smsc47m1_driver, smsc47m1_probe);
if (err)
@@ -955,7 +957,6 @@ static int __init sm_smsc47m1_init(void)
exit_device:
platform_device_unregister(pdev);
smsc47m1_restore(&sio_data);
-exit:
return err;
}
diff --git a/drivers/i2c/busses/i2c-designware-pcidrv.c b/drivers/i2c/busses/i2c-designware-pcidrv.c
index 37f42113af31..00e8f213f56e 100644
--- a/drivers/i2c/busses/i2c-designware-pcidrv.c
+++ b/drivers/i2c/busses/i2c-designware-pcidrv.c
@@ -182,7 +182,6 @@ static int i2c_dw_pci_resume(struct device *dev)
pci_restore_state(pdev);
i2c_dw_init(i2c);
- i2c_dw_enable(i2c);
return 0;
}
diff --git a/drivers/idle/i7300_idle.c b/drivers/idle/i7300_idle.c
index c976285d313e..fa080ebd568f 100644
--- a/drivers/idle/i7300_idle.c
+++ b/drivers/idle/i7300_idle.c
@@ -516,12 +516,6 @@ static struct notifier_block i7300_idle_nb = {
MODULE_DEVICE_TABLE(pci, pci_tbl);
-int stats_open_generic(struct inode *inode, struct file *fp)
-{
- fp->private_data = inode->i_private;
- return 0;
-}
-
static ssize_t stats_read_ul(struct file *fp, char __user *ubuf, size_t count,
loff_t *off)
{
@@ -534,7 +528,7 @@ static ssize_t stats_read_ul(struct file *fp, char __user *ubuf, size_t count,
}
static const struct file_operations idle_fops = {
- .open = stats_open_generic,
+ .open = simple_open,
.read = stats_read_ul,
.llseek = default_llseek,
};
diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c
index 83b720ef6c34..246fdc151652 100644
--- a/drivers/infiniband/core/sysfs.c
+++ b/drivers/infiniband/core/sysfs.c
@@ -179,7 +179,7 @@ static ssize_t rate_show(struct ib_port *p, struct port_attribute *unused,
{
struct ib_port_attr attr;
char *speed = "";
- int rate = -1; /* in deci-Gb/sec */
+ int rate; /* in deci-Gb/sec */
ssize_t ret;
ret = ib_query_port(p->ibdev, p->port_num, &attr);
@@ -187,9 +187,6 @@ static ssize_t rate_show(struct ib_port *p, struct port_attribute *unused,
return ret;
switch (attr.active_speed) {
- case IB_SPEED_SDR:
- rate = 25;
- break;
case IB_SPEED_DDR:
speed = " DDR";
rate = 50;
@@ -210,6 +207,10 @@ static ssize_t rate_show(struct ib_port *p, struct port_attribute *unused,
speed = " EDR";
rate = 250;
break;
+ case IB_SPEED_SDR:
+ default: /* default to SDR for invalid rates */
+ rate = 25;
+ break;
}
rate *= ib_width_enum_to_int(attr.active_width);
diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c
index 75d305629300..669673e81439 100644
--- a/drivers/infiniband/hw/mlx4/main.c
+++ b/drivers/infiniband/hw/mlx4/main.c
@@ -253,6 +253,11 @@ static int ib_link_query_port(struct ib_device *ibdev, u8 port,
if (out_mad->data[15] & 0x1)
props->active_speed = IB_SPEED_FDR10;
}
+
+ /* Avoid wrong speed value returned by FW if the IB link is down. */
+ if (props->state == IB_PORT_DOWN)
+ props->active_speed = IB_SPEED_SDR;
+
out:
kfree(in_mad);
kfree(out_mad);
diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c
index 69e2ad06e515..daf21b899999 100644
--- a/drivers/infiniband/ulp/srpt/ib_srpt.c
+++ b/drivers/infiniband/ulp/srpt/ib_srpt.c
@@ -3232,6 +3232,7 @@ static void srpt_add_one(struct ib_device *device)
srq_attr.attr.max_wr = sdev->srq_size;
srq_attr.attr.max_sge = 1;
srq_attr.attr.srq_limit = 0;
+ srq_attr.srq_type = IB_SRQT_BASIC;
sdev->srq = ib_create_srq(sdev->pd, &srq_attr);
if (IS_ERR(sdev->srq))
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index 2d787796bf50..7faf4a7fcaa9 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -380,8 +380,7 @@ config INPUT_TWL4030_VIBRA
config INPUT_TWL6040_VIBRA
tristate "Support for TWL6040 Vibrator"
- depends on TWL4030_CORE
- select TWL6040_CORE
+ depends on TWL6040_CORE
select INPUT_FF_MEMLESS
help
This option enables support for TWL6040 Vibrator Driver.
diff --git a/drivers/input/misc/da9052_onkey.c b/drivers/input/misc/da9052_onkey.c
index 34aebb8cd080..3c843cd725fa 100644
--- a/drivers/input/misc/da9052_onkey.c
+++ b/drivers/input/misc/da9052_onkey.c
@@ -95,7 +95,8 @@ static int __devinit da9052_onkey_probe(struct platform_device *pdev)
input_dev = input_allocate_device();
if (!onkey || !input_dev) {
dev_err(&pdev->dev, "Failed to allocate memory\n");
- return -ENOMEM;
+ error = -ENOMEM;
+ goto err_free_mem;
}
onkey->input = input_dev;
diff --git a/drivers/input/misc/twl6040-vibra.c b/drivers/input/misc/twl6040-vibra.c
index 45874fed523a..14e94f56cb7d 100644
--- a/drivers/input/misc/twl6040-vibra.c
+++ b/drivers/input/misc/twl6040-vibra.c
@@ -28,7 +28,7 @@
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/workqueue.h>
-#include <linux/i2c/twl.h>
+#include <linux/input.h>
#include <linux/mfd/twl6040.h>
#include <linux/slab.h>
#include <linux/delay.h>
@@ -257,7 +257,7 @@ static SIMPLE_DEV_PM_OPS(twl6040_vibra_pm_ops, twl6040_vibra_suspend, NULL);
static int __devinit twl6040_vibra_probe(struct platform_device *pdev)
{
- struct twl4030_vibra_data *pdata = pdev->dev.platform_data;
+ struct twl6040_vibra_data *pdata = pdev->dev.platform_data;
struct vibra_info *info;
int ret;
diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c
index d2c0db159b18..479011004a11 100644
--- a/drivers/input/mouse/elantech.c
+++ b/drivers/input/mouse/elantech.c
@@ -486,7 +486,6 @@ static void elantech_input_sync_v4(struct psmouse *psmouse)
unsigned char *packet = psmouse->packet;
input_report_key(dev, BTN_LEFT, packet[0] & 0x01);
- input_report_key(dev, BTN_RIGHT, packet[0] & 0x02);
input_mt_report_pointer_emulation(dev, true);
input_sync(dev);
}
@@ -967,6 +966,7 @@ static int elantech_set_input_params(struct psmouse *psmouse)
if (elantech_set_range(psmouse, &x_min, &y_min, &x_max, &y_max, &width))
return -1;
+ __set_bit(INPUT_PROP_POINTER, dev->propbit);
__set_bit(EV_KEY, dev->evbit);
__set_bit(EV_ABS, dev->evbit);
__clear_bit(EV_REL, dev->evbit);
@@ -1017,7 +1017,9 @@ static int elantech_set_input_params(struct psmouse *psmouse)
*/
psmouse_warn(psmouse, "couldn't query resolution data.\n");
}
-
+ /* v4 is clickpad, with only one button. */
+ __set_bit(INPUT_PROP_BUTTONPAD, dev->propbit);
+ __clear_bit(BTN_RIGHT, dev->keybit);
__set_bit(BTN_TOOL_QUADTAP, dev->keybit);
/* For X to recognize me as touchpad. */
input_set_abs_params(dev, ABS_X, x_min, x_max, 0, 0);
@@ -1245,6 +1247,8 @@ static void elantech_disconnect(struct psmouse *psmouse)
*/
static int elantech_reconnect(struct psmouse *psmouse)
{
+ psmouse_reset(psmouse);
+
if (elantech_detect(psmouse, 0))
return -1;
@@ -1324,6 +1328,8 @@ int elantech_init(struct psmouse *psmouse)
if (!etd)
return -ENOMEM;
+ psmouse_reset(psmouse);
+
etd->parity[0] = 1;
for (i = 1; i < 256; i++)
etd->parity[i] = etd->parity[i & (i - 1)] ^ 1;
diff --git a/drivers/input/mouse/gpio_mouse.c b/drivers/input/mouse/gpio_mouse.c
index a9ad8e1402be..39fe9b737cae 100644
--- a/drivers/input/mouse/gpio_mouse.c
+++ b/drivers/input/mouse/gpio_mouse.c
@@ -12,9 +12,9 @@
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/input-polldev.h>
+#include <linux/gpio.h>
#include <linux/gpio_mouse.h>
-#include <asm/gpio.h>
/*
* Timer function which is run every scan_ms ms when the device is opened.
diff --git a/drivers/input/mouse/sentelic.c b/drivers/input/mouse/sentelic.c
index a977bfaa6821..661a0ca3b3d6 100644
--- a/drivers/input/mouse/sentelic.c
+++ b/drivers/input/mouse/sentelic.c
@@ -741,6 +741,14 @@ static psmouse_ret_t fsp_process_byte(struct psmouse *psmouse)
}
} else {
/* SFAC packet */
+ if ((packet[0] & (FSP_PB0_LBTN|FSP_PB0_PHY_BTN)) ==
+ FSP_PB0_LBTN) {
+ /* On-pad click in SFAC mode should be handled
+ * by userspace. On-pad clicks in MFMC mode
+ * are real clickpad clicks, and not ignored.
+ */
+ packet[0] &= ~FSP_PB0_LBTN;
+ }
/* no multi-finger information */
ad->last_mt_fgr = 0;
diff --git a/drivers/input/mouse/trackpoint.c b/drivers/input/mouse/trackpoint.c
index 22b218018137..f3102494237d 100644
--- a/drivers/input/mouse/trackpoint.c
+++ b/drivers/input/mouse/trackpoint.c
@@ -304,7 +304,7 @@ int trackpoint_detect(struct psmouse *psmouse, bool set_properties)
return 0;
if (trackpoint_read(&psmouse->ps2dev, TP_EXT_BTN, &button_info)) {
- printk(KERN_WARNING "trackpoint.c: failed to get extended button data\n");
+ psmouse_warn(psmouse, "failed to get extended button data\n");
button_info = 0;
}
@@ -326,16 +326,18 @@ int trackpoint_detect(struct psmouse *psmouse, bool set_properties)
error = sysfs_create_group(&ps2dev->serio->dev.kobj, &trackpoint_attr_group);
if (error) {
- printk(KERN_ERR
- "trackpoint.c: failed to create sysfs attributes, error: %d\n",
- error);
+ psmouse_err(psmouse,
+ "failed to create sysfs attributes, error: %d\n",
+ error);
kfree(psmouse->private);
psmouse->private = NULL;
return -1;
}
- printk(KERN_INFO "IBM TrackPoint firmware: 0x%02x, buttons: %d/%d\n",
- firmware_id, (button_info & 0xf0) >> 4, button_info & 0x0f);
+ psmouse_info(psmouse,
+ "IBM TrackPoint firmware: 0x%02x, buttons: %d/%d\n",
+ firmware_id,
+ (button_info & 0xf0) >> 4, button_info & 0x0f);
return 0;
}
diff --git a/drivers/input/touchscreen/tps6507x-ts.c b/drivers/input/touchscreen/tps6507x-ts.c
index 6c6f6d8ea9b4..f7eda3d00fad 100644
--- a/drivers/input/touchscreen/tps6507x-ts.c
+++ b/drivers/input/touchscreen/tps6507x-ts.c
@@ -1,6 +1,4 @@
/*
- * drivers/input/touchscreen/tps6507x_ts.c
- *
* Touchscreen driver for the tps6507x chip.
*
* Copyright (c) 2009 RidgeRun (todd.fischer@ridgerun.com)
@@ -376,4 +374,4 @@ module_platform_driver(tps6507x_ts_driver);
MODULE_AUTHOR("Todd Fischer <todd.fischer@ridgerun.com>");
MODULE_DESCRIPTION("TPS6507x - TouchScreen driver");
MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("platform:tps6507x-tsc");
+MODULE_ALIAS("platform:tps6507x-ts");
diff --git a/drivers/iommu/omap-iommu-debug.c b/drivers/iommu/omap-iommu-debug.c
index 103dbd92e256..f55fc5dfbadc 100644
--- a/drivers/iommu/omap-iommu-debug.c
+++ b/drivers/iommu/omap-iommu-debug.c
@@ -323,15 +323,9 @@ err_out:
return count;
}
-static int debug_open_generic(struct inode *inode, struct file *file)
-{
- file->private_data = inode->i_private;
- return 0;
-}
-
#define DEBUG_FOPS(name) \
static const struct file_operations debug_##name##_fops = { \
- .open = debug_open_generic, \
+ .open = simple_open, \
.read = debug_read_##name, \
.write = debug_write_##name, \
.llseek = generic_file_llseek, \
@@ -339,7 +333,7 @@ static int debug_open_generic(struct inode *inode, struct file *file)
#define DEBUG_FOPS_RO(name) \
static const struct file_operations debug_##name##_fops = { \
- .open = debug_open_generic, \
+ .open = simple_open, \
.read = debug_read_##name, \
.llseek = generic_file_llseek, \
};
diff --git a/drivers/isdn/gigaset/interface.c b/drivers/isdn/gigaset/interface.c
index b3d6ac17272d..a6d9fd2858f7 100644
--- a/drivers/isdn/gigaset/interface.c
+++ b/drivers/isdn/gigaset/interface.c
@@ -176,7 +176,7 @@ static void if_close(struct tty_struct *tty, struct file *filp)
struct cardstate *cs = tty->driver_data;
if (!cs) { /* happens if we didn't find cs in open */
- printk(KERN_DEBUG "%s: no cardstate\n", __func__);
+ gig_dbg(DEBUG_IF, "%s: no cardstate", __func__);
return;
}
diff --git a/drivers/leds/leds-atmel-pwm.c b/drivers/leds/leds-atmel-pwm.c
index 800243b6037e..64ad702a2ecc 100644
--- a/drivers/leds/leds-atmel-pwm.c
+++ b/drivers/leds/leds-atmel-pwm.c
@@ -35,7 +35,7 @@ static void pwmled_brightness(struct led_classdev *cdev, enum led_brightness b)
* NOTE: we reuse the platform_data structure of GPIO leds,
* but repurpose its "gpio" number as a PWM channel number.
*/
-static int __init pwmled_probe(struct platform_device *pdev)
+static int __devinit pwmled_probe(struct platform_device *pdev)
{
const struct gpio_led_platform_data *pdata;
struct pwmled *leds;
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c
index 3d0dfa7a89a2..97e73e555d11 100644
--- a/drivers/md/bitmap.c
+++ b/drivers/md/bitmap.c
@@ -539,9 +539,6 @@ static int bitmap_new_disk_sb(struct bitmap *bitmap)
bitmap->events_cleared = bitmap->mddev->events;
sb->events_cleared = cpu_to_le64(bitmap->mddev->events);
- bitmap->flags |= BITMAP_HOSTENDIAN;
- sb->version = cpu_to_le32(BITMAP_MAJOR_HOSTENDIAN);
-
kunmap_atomic(sb);
return 0;
@@ -1788,7 +1785,9 @@ int bitmap_load(struct mddev *mddev)
* re-add of a missing device */
start = mddev->recovery_cp;
+ mutex_lock(&mddev->bitmap_info.mutex);
err = bitmap_init_from_disk(bitmap, start);
+ mutex_unlock(&mddev->bitmap_info.mutex);
if (err)
goto out;
diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c
index b0ba52459ed7..68965e663248 100644
--- a/drivers/md/dm-raid.c
+++ b/drivers/md/dm-raid.c
@@ -859,7 +859,7 @@ static int analyse_superblocks(struct dm_target *ti, struct raid_set *rs)
int ret;
unsigned redundancy = 0;
struct raid_dev *dev;
- struct md_rdev *rdev, *freshest;
+ struct md_rdev *rdev, *tmp, *freshest;
struct mddev *mddev = &rs->md;
switch (rs->raid_type->level) {
@@ -877,7 +877,7 @@ static int analyse_superblocks(struct dm_target *ti, struct raid_set *rs)
}
freshest = NULL;
- rdev_for_each(rdev, mddev) {
+ rdev_for_each_safe(rdev, tmp, mddev) {
if (!rdev->meta_bdev)
continue;
diff --git a/drivers/md/md.c b/drivers/md/md.c
index b572e1e386ce..477eb2e180c0 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -7560,14 +7560,14 @@ void md_check_recovery(struct mddev *mddev)
* any transients in the value of "sync_action".
*/
set_bit(MD_RECOVERY_RUNNING, &mddev->recovery);
- clear_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
/* Clear some bits that don't mean anything, but
* might be left set
*/
clear_bit(MD_RECOVERY_INTR, &mddev->recovery);
clear_bit(MD_RECOVERY_DONE, &mddev->recovery);
- if (test_bit(MD_RECOVERY_FROZEN, &mddev->recovery))
+ if (!test_and_clear_bit(MD_RECOVERY_NEEDED, &mddev->recovery) ||
+ test_bit(MD_RECOVERY_FROZEN, &mddev->recovery))
goto unlock;
/* no recovery is running.
* remove any failed drives, then
@@ -8140,7 +8140,8 @@ static int md_notify_reboot(struct notifier_block *this,
for_each_mddev(mddev, tmp) {
if (mddev_trylock(mddev)) {
- __md_stop_writes(mddev);
+ if (mddev->pers)
+ __md_stop_writes(mddev);
mddev->safemode = 2;
mddev_unlock(mddev);
}
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index d35e4c991e38..15dd59b84e94 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -1712,6 +1712,7 @@ static int process_checks(struct r1bio *r1_bio)
struct r1conf *conf = mddev->private;
int primary;
int i;
+ int vcnt;
for (primary = 0; primary < conf->raid_disks * 2; primary++)
if (r1_bio->bios[primary]->bi_end_io == end_sync_read &&
@@ -1721,9 +1722,9 @@ static int process_checks(struct r1bio *r1_bio)
break;
}
r1_bio->read_disk = primary;
+ vcnt = (r1_bio->sectors + PAGE_SIZE / 512 - 1) >> (PAGE_SHIFT - 9);
for (i = 0; i < conf->raid_disks * 2; i++) {
int j;
- int vcnt = r1_bio->sectors >> (PAGE_SHIFT- 9);
struct bio *pbio = r1_bio->bios[primary];
struct bio *sbio = r1_bio->bios[i];
int size;
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index fff782189e48..c8dbb84d5357 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -1788,6 +1788,7 @@ static void sync_request_write(struct mddev *mddev, struct r10bio *r10_bio)
struct r10conf *conf = mddev->private;
int i, first;
struct bio *tbio, *fbio;
+ int vcnt;
atomic_set(&r10_bio->remaining, 1);
@@ -1802,10 +1803,10 @@ static void sync_request_write(struct mddev *mddev, struct r10bio *r10_bio)
first = i;
fbio = r10_bio->devs[i].bio;
+ vcnt = (r10_bio->sectors + (PAGE_SIZE >> 9) - 1) >> (PAGE_SHIFT - 9);
/* now find blocks with errors */
for (i=0 ; i < conf->copies ; i++) {
int j, d;
- int vcnt = r10_bio->sectors >> (PAGE_SHIFT-9);
tbio = r10_bio->devs[i].bio;
@@ -1871,7 +1872,6 @@ static void sync_request_write(struct mddev *mddev, struct r10bio *r10_bio)
*/
for (i = 0; i < conf->copies; i++) {
int j, d;
- int vcnt = r10_bio->sectors >> (PAGE_SHIFT-9);
tbio = r10_bio->devs[i].repl_bio;
if (!tbio || !tbio->bi_end_io)
diff --git a/drivers/media/common/tuners/xc5000.c b/drivers/media/common/tuners/xc5000.c
index 7f98984e4fad..eab2ea424200 100644
--- a/drivers/media/common/tuners/xc5000.c
+++ b/drivers/media/common/tuners/xc5000.c
@@ -54,6 +54,7 @@ struct xc5000_priv {
struct list_head hybrid_tuner_instance_list;
u32 if_khz;
+ u32 xtal_khz;
u32 freq_hz;
u32 bandwidth;
u8 video_standard;
@@ -214,9 +215,9 @@ static const struct xc5000_fw_cfg xc5000a_1_6_114 = {
.size = 12401,
};
-static const struct xc5000_fw_cfg xc5000c_41_024_5_31875 = {
- .name = "dvb-fe-xc5000c-41.024.5-31875.fw",
- .size = 16503,
+static const struct xc5000_fw_cfg xc5000c_41_024_5 = {
+ .name = "dvb-fe-xc5000c-41.024.5.fw",
+ .size = 16497,
};
static inline const struct xc5000_fw_cfg *xc5000_assign_firmware(int chip_id)
@@ -226,7 +227,7 @@ static inline const struct xc5000_fw_cfg *xc5000_assign_firmware(int chip_id)
case XC5000A:
return &xc5000a_1_6_114;
case XC5000C:
- return &xc5000c_41_024_5_31875;
+ return &xc5000c_41_024_5;
}
}
@@ -572,6 +573,31 @@ static int xc_tune_channel(struct xc5000_priv *priv, u32 freq_hz, int mode)
return found;
}
+static int xc_set_xtal(struct dvb_frontend *fe)
+{
+ struct xc5000_priv *priv = fe->tuner_priv;
+ int ret = XC_RESULT_SUCCESS;
+
+ switch (priv->chip_id) {
+ default:
+ case XC5000A:
+ /* 32.000 MHz xtal is default */
+ break;
+ case XC5000C:
+ switch (priv->xtal_khz) {
+ default:
+ case 32000:
+ /* 32.000 MHz xtal is default */
+ break;
+ case 31875:
+ /* 31.875 MHz xtal configuration */
+ ret = xc_write_reg(priv, 0x000f, 0x8081);
+ break;
+ }
+ break;
+ }
+ return ret;
+}
static int xc5000_fwupload(struct dvb_frontend *fe)
{
@@ -603,6 +629,8 @@ static int xc5000_fwupload(struct dvb_frontend *fe)
} else {
printk(KERN_INFO "xc5000: firmware uploading...\n");
ret = xc_load_i2c_sequence(fe, fw->data);
+ if (XC_RESULT_SUCCESS == ret)
+ ret = xc_set_xtal(fe);
printk(KERN_INFO "xc5000: firmware upload complete...\n");
}
@@ -1164,6 +1192,9 @@ struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe,
priv->if_khz = cfg->if_khz;
}
+ if (priv->xtal_khz == 0)
+ priv->xtal_khz = cfg->xtal_khz;
+
if (priv->radio_input == 0)
priv->radio_input = cfg->radio_input;
diff --git a/drivers/media/common/tuners/xc5000.h b/drivers/media/common/tuners/xc5000.h
index 3396f8e02b40..39a73bf01406 100644
--- a/drivers/media/common/tuners/xc5000.h
+++ b/drivers/media/common/tuners/xc5000.h
@@ -34,6 +34,7 @@ struct xc5000_config {
u8 i2c_address;
u32 if_khz;
u8 radio_input;
+ u32 xtal_khz;
int chip_id;
};
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
index 4555baa383b2..0f64d7182657 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -143,10 +143,12 @@ struct dvb_frontend_private {
static void dvb_frontend_wakeup(struct dvb_frontend *fe);
static int dtv_get_frontend(struct dvb_frontend *fe,
struct dvb_frontend_parameters *p_out);
+static int dtv_property_legacy_params_sync(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *p);
static bool has_get_frontend(struct dvb_frontend *fe)
{
- return fe->ops.get_frontend;
+ return fe->ops.get_frontend != NULL;
}
/*
@@ -697,6 +699,7 @@ restart:
fepriv->algo_status |= DVBFE_ALGO_SEARCH_AGAIN;
fepriv->delay = HZ / 2;
}
+ dtv_property_legacy_params_sync(fe, &fepriv->parameters_out);
fe->ops.read_status(fe, &s);
if (s != fepriv->status) {
dvb_frontend_add_event(fe, s); /* update event list */
@@ -1443,6 +1446,28 @@ static int set_delivery_system(struct dvb_frontend *fe, u32 desired_system)
__func__);
return -EINVAL;
}
+ /*
+ * Get a delivery system that is compatible with DVBv3
+ * NOTE: in order for this to work with softwares like Kaffeine that
+ * uses a DVBv5 call for DVB-S2 and a DVBv3 call to go back to
+ * DVB-S, drivers that support both should put the SYS_DVBS entry
+ * before the SYS_DVBS2, otherwise it won't switch back to DVB-S.
+ * The real fix is that userspace applications should not use DVBv3
+ * and not trust on calling FE_SET_FRONTEND to switch the delivery
+ * system.
+ */
+ ncaps = 0;
+ while (fe->ops.delsys[ncaps] && ncaps < MAX_DELSYS) {
+ if (fe->ops.delsys[ncaps] == desired_system) {
+ delsys = desired_system;
+ break;
+ }
+ ncaps++;
+ }
+ if (delsys == SYS_UNDEFINED) {
+ dprintk("%s() Couldn't find a delivery system that matches %d\n",
+ __func__, desired_system);
+ }
} else {
/*
* This is a DVBv5 call. So, it likely knows the supported
@@ -1491,9 +1516,10 @@ static int set_delivery_system(struct dvb_frontend *fe, u32 desired_system)
__func__);
return -EINVAL;
}
- c->delivery_system = delsys;
}
+ c->delivery_system = delsys;
+
/*
* The DVBv3 or DVBv5 call is requesting a different system. So,
* emulation is needed.
@@ -1833,6 +1859,13 @@ static int dtv_set_frontend(struct dvb_frontend *fe)
return -EINVAL;
/*
+ * Initialize output parameters to match the values given by
+ * the user. FE_SET_FRONTEND triggers an initial frontend event
+ * with status = 0, which copies output parameters to userspace.
+ */
+ dtv_property_legacy_params_sync(fe, &fepriv->parameters_out);
+
+ /*
* Be sure that the bandwidth will be filled for all
* non-satellite systems, as tuners need to know what
* low pass/Nyquist half filter should be applied, in
diff --git a/drivers/media/dvb/dvb-usb/it913x.c b/drivers/media/dvb/dvb-usb/it913x.c
index 3b7b102f20ae..482d249ca7f3 100644
--- a/drivers/media/dvb/dvb-usb/it913x.c
+++ b/drivers/media/dvb/dvb-usb/it913x.c
@@ -238,12 +238,27 @@ static int it913x_read_reg(struct usb_device *udev, u32 reg)
static u32 it913x_query(struct usb_device *udev, u8 pro)
{
- int ret;
+ int ret, i;
u8 data[4];
- ret = it913x_io(udev, READ_LONG, pro, CMD_DEMOD_READ,
- 0x1222, 0, &data[0], 3);
+ u8 ver;
+
+ for (i = 0; i < 5; i++) {
+ ret = it913x_io(udev, READ_LONG, pro, CMD_DEMOD_READ,
+ 0x1222, 0, &data[0], 3);
+ ver = data[0];
+ if (ver > 0 && ver < 3)
+ break;
+ msleep(100);
+ }
- it913x_config.chip_ver = data[0];
+ if (ver < 1 || ver > 2) {
+ info("Failed to identify chip version applying 1");
+ it913x_config.chip_ver = 0x1;
+ it913x_config.chip_type = 0x9135;
+ return 0;
+ }
+
+ it913x_config.chip_ver = ver;
it913x_config.chip_type = (u16)(data[2] << 8) + data[1];
info("Chip Version=%02x Chip Type=%04x", it913x_config.chip_ver,
@@ -660,30 +675,41 @@ static int it913x_download_firmware(struct usb_device *udev,
if ((packet_size > min_pkt) || (i == fw->size)) {
fw_data = (u8 *)(fw->data + pos);
pos += packet_size;
- if (packet_size > 0)
- ret |= it913x_io(udev, WRITE_DATA,
+ if (packet_size > 0) {
+ ret = it913x_io(udev, WRITE_DATA,
DEV_0, CMD_SCATTER_WRITE, 0,
0, fw_data, packet_size);
+ if (ret < 0)
+ break;
+ }
udelay(1000);
}
}
i++;
}
- ret |= it913x_io(udev, WRITE_CMD, DEV_0, CMD_BOOT, 0, 0, NULL, 0);
-
- msleep(100);
-
if (ret < 0)
- info("FRM Firmware Download Failed (%04x)" , ret);
+ info("FRM Firmware Download Failed (%d)" , ret);
else
info("FRM Firmware Download Completed - Resetting Device");
- ret |= it913x_return_status(udev);
+ msleep(30);
+
+ ret = it913x_io(udev, WRITE_CMD, DEV_0, CMD_BOOT, 0, 0, NULL, 0);
+ if (ret < 0)
+ info("FRM Device not responding to reboot");
+
+ ret = it913x_return_status(udev);
+ if (ret == 0) {
+ info("FRM Failed to reboot device");
+ return -ENODEV;
+ }
msleep(30);
- ret |= it913x_wr_reg(udev, DEV_0, I2C_CLK, I2C_CLK_400);
+ ret = it913x_wr_reg(udev, DEV_0, I2C_CLK, I2C_CLK_400);
+
+ msleep(30);
/* Tuner function */
if (it913x_config.dual_mode)
@@ -901,5 +927,5 @@ module_usb_driver(it913x_driver);
MODULE_AUTHOR("Malcolm Priestley <tvboxspy@gmail.com>");
MODULE_DESCRIPTION("it913x USB 2 Driver");
-MODULE_VERSION("1.27");
+MODULE_VERSION("1.28");
MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/drxk_hard.c b/drivers/media/dvb/frontends/drxk_hard.c
index 36d11756492f..a414b1f2b6a5 100644
--- a/drivers/media/dvb/frontends/drxk_hard.c
+++ b/drivers/media/dvb/frontends/drxk_hard.c
@@ -1520,8 +1520,10 @@ static int scu_command(struct drxk_state *state,
dprintk(1, "\n");
if ((cmd == 0) || ((parameterLen > 0) && (parameter == NULL)) ||
- ((resultLen > 0) && (result == NULL)))
- goto error;
+ ((resultLen > 0) && (result == NULL))) {
+ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+ return status;
+ }
mutex_lock(&state->mutex);
diff --git a/drivers/media/rc/winbond-cir.c b/drivers/media/rc/winbond-cir.c
index b09c5fae489b..af526586fa26 100644
--- a/drivers/media/rc/winbond-cir.c
+++ b/drivers/media/rc/winbond-cir.c
@@ -1046,6 +1046,7 @@ wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id)
goto exit_unregister_led;
}
+ data->dev->driver_type = RC_DRIVER_IR_RAW;
data->dev->driver_name = WBCIR_NAME;
data->dev->input_name = WBCIR_NAME;
data->dev->input_phys = "wbcir/cir0";
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index f2479c5c0eb2..ce1e7ba940f6 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -492,7 +492,7 @@ config VIDEO_VS6624
config VIDEO_MT9M032
tristate "MT9M032 camera sensor support"
- depends on I2C && VIDEO_V4L2
+ depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
select VIDEO_APTINA_PLL
---help---
This driver supports MT9M032 camera sensors from Aptina, monochrome
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c
index 5452beef8e11..989e556913ed 100644
--- a/drivers/media/video/ivtv/ivtv-ioctl.c
+++ b/drivers/media/video/ivtv/ivtv-ioctl.c
@@ -1763,13 +1763,13 @@ static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
IVTV_DEBUG_IOCTL("AUDIO_CHANNEL_SELECT\n");
if (iarg > AUDIO_STEREO_SWAPPED)
return -EINVAL;
- return v4l2_ctrl_s_ctrl(itv->ctrl_audio_playback, iarg);
+ return v4l2_ctrl_s_ctrl(itv->ctrl_audio_playback, iarg + 1);
case AUDIO_BILINGUAL_CHANNEL_SELECT:
IVTV_DEBUG_IOCTL("AUDIO_BILINGUAL_CHANNEL_SELECT\n");
if (iarg > AUDIO_STEREO_SWAPPED)
return -EINVAL;
- return v4l2_ctrl_s_ctrl(itv->ctrl_audio_multilingual_playback, iarg);
+ return v4l2_ctrl_s_ctrl(itv->ctrl_audio_multilingual_playback, iarg + 1);
default:
return -EINVAL;
diff --git a/drivers/media/video/mt9m032.c b/drivers/media/video/mt9m032.c
index 7636672c3548..645973c5feb0 100644
--- a/drivers/media/video/mt9m032.c
+++ b/drivers/media/video/mt9m032.c
@@ -392,10 +392,11 @@ static int mt9m032_set_pad_format(struct v4l2_subdev *subdev,
}
/* Scaling is not supported, the format is thus fixed. */
- ret = mt9m032_get_pad_format(subdev, fh, fmt);
+ fmt->format = *__mt9m032_get_pad_format(sensor, fh, fmt->which);
+ ret = 0;
done:
- mutex_lock(&sensor->lock);
+ mutex_unlock(&sensor->lock);
return ret;
}
diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c
index 4a44f9a1bae0..b76b0ac0958f 100644
--- a/drivers/media/video/uvc/uvc_video.c
+++ b/drivers/media/video/uvc/uvc_video.c
@@ -468,22 +468,30 @@ uvc_video_clock_decode(struct uvc_streaming *stream, struct uvc_buffer *buf,
spin_unlock_irqrestore(&stream->clock.lock, flags);
}
-static int uvc_video_clock_init(struct uvc_streaming *stream)
+static void uvc_video_clock_reset(struct uvc_streaming *stream)
{
struct uvc_clock *clock = &stream->clock;
- spin_lock_init(&clock->lock);
clock->head = 0;
clock->count = 0;
- clock->size = 32;
clock->last_sof = -1;
clock->sof_offset = -1;
+}
+
+static int uvc_video_clock_init(struct uvc_streaming *stream)
+{
+ struct uvc_clock *clock = &stream->clock;
+
+ spin_lock_init(&clock->lock);
+ clock->size = 32;
clock->samples = kmalloc(clock->size * sizeof(*clock->samples),
GFP_KERNEL);
if (clock->samples == NULL)
return -ENOMEM;
+ uvc_video_clock_reset(stream);
+
return 0;
}
@@ -1424,8 +1432,6 @@ static void uvc_uninit_video(struct uvc_streaming *stream, int free_buffers)
if (free_buffers)
uvc_free_urb_buffers(stream);
-
- uvc_video_clock_cleanup(stream);
}
/*
@@ -1555,10 +1561,6 @@ static int uvc_init_video(struct uvc_streaming *stream, gfp_t gfp_flags)
uvc_video_stats_start(stream);
- ret = uvc_video_clock_init(stream);
- if (ret < 0)
- return ret;
-
if (intf->num_altsetting > 1) {
struct usb_host_endpoint *best_ep = NULL;
unsigned int best_psize = 3 * 1024;
@@ -1683,6 +1685,8 @@ int uvc_video_resume(struct uvc_streaming *stream, int reset)
stream->frozen = 0;
+ uvc_video_clock_reset(stream);
+
ret = uvc_commit_video(stream, &stream->ctrl);
if (ret < 0) {
uvc_queue_enable(&stream->queue, 0);
@@ -1819,25 +1823,35 @@ int uvc_video_enable(struct uvc_streaming *stream, int enable)
uvc_uninit_video(stream, 1);
usb_set_interface(stream->dev->udev, stream->intfnum, 0);
uvc_queue_enable(&stream->queue, 0);
+ uvc_video_clock_cleanup(stream);
return 0;
}
- ret = uvc_queue_enable(&stream->queue, 1);
+ ret = uvc_video_clock_init(stream);
if (ret < 0)
return ret;
+ ret = uvc_queue_enable(&stream->queue, 1);
+ if (ret < 0)
+ goto error_queue;
+
/* Commit the streaming parameters. */
ret = uvc_commit_video(stream, &stream->ctrl);
- if (ret < 0) {
- uvc_queue_enable(&stream->queue, 0);
- return ret;
- }
+ if (ret < 0)
+ goto error_commit;
ret = uvc_init_video(stream, GFP_KERNEL);
- if (ret < 0) {
- usb_set_interface(stream->dev->udev, stream->intfnum, 0);
- uvc_queue_enable(&stream->queue, 0);
- }
+ if (ret < 0)
+ goto error_video;
+
+ return 0;
+
+error_video:
+ usb_set_interface(stream->dev->udev, stream->intfnum, 0);
+error_commit:
+ uvc_queue_enable(&stream->queue, 0);
+error_queue:
+ uvc_video_clock_cleanup(stream);
return ret;
}
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 29f463cc09cb..11e44386fa9b 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -268,10 +268,17 @@ config TWL6030_PWM
This is used to control charging LED brightness.
config TWL6040_CORE
- bool
- depends on TWL4030_CORE && GENERIC_HARDIRQS
+ bool "Support for TWL6040 audio codec"
+ depends on I2C=y && GENERIC_HARDIRQS
select MFD_CORE
+ select REGMAP_I2C
default n
+ help
+ Say yes here if you want support for Texas Instruments TWL6040 audio
+ codec.
+ This driver provides common support for accessing the device,
+ additional drivers must be enabled in order to use the
+ functionality of the device (audio, vibra).
config MFD_STMPE
bool "Support STMicroelectronics STMPE"
diff --git a/drivers/mfd/aat2870-core.c b/drivers/mfd/aat2870-core.c
index 3aa36eb5c79b..44a3fdbadef4 100644
--- a/drivers/mfd/aat2870-core.c
+++ b/drivers/mfd/aat2870-core.c
@@ -262,13 +262,6 @@ static ssize_t aat2870_dump_reg(struct aat2870_data *aat2870, char *buf)
return count;
}
-static int aat2870_reg_open_file(struct inode *inode, struct file *file)
-{
- file->private_data = inode->i_private;
-
- return 0;
-}
-
static ssize_t aat2870_reg_read_file(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
@@ -330,7 +323,7 @@ static ssize_t aat2870_reg_write_file(struct file *file,
}
static const struct file_operations aat2870_reg_fops = {
- .open = aat2870_reg_open_file,
+ .open = simple_open,
.read = aat2870_reg_read_file,
.write = aat2870_reg_write_file,
};
diff --git a/drivers/mfd/ab3100-core.c b/drivers/mfd/ab3100-core.c
index 60107ee166fc..1efad20fb175 100644
--- a/drivers/mfd/ab3100-core.c
+++ b/drivers/mfd/ab3100-core.c
@@ -483,12 +483,6 @@ struct ab3100_get_set_reg_priv {
bool mode;
};
-static int ab3100_get_set_reg_open_file(struct inode *inode, struct file *file)
-{
- file->private_data = inode->i_private;
- return 0;
-}
-
static ssize_t ab3100_get_set_reg(struct file *file,
const char __user *user_buf,
size_t count, loff_t *ppos)
@@ -583,7 +577,7 @@ static ssize_t ab3100_get_set_reg(struct file *file,
}
static const struct file_operations ab3100_get_set_reg_fops = {
- .open = ab3100_get_set_reg_open_file,
+ .open = simple_open,
.write = ab3100_get_set_reg,
.llseek = noop_llseek,
};
diff --git a/drivers/mfd/asic3.c b/drivers/mfd/asic3.c
index 1895cf9fab8c..1582c3d95257 100644
--- a/drivers/mfd/asic3.c
+++ b/drivers/mfd/asic3.c
@@ -527,7 +527,9 @@ static void asic3_gpio_set(struct gpio_chip *chip,
static int asic3_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
{
- return (offset < ASIC3_NUM_GPIOS) ? IRQ_BOARD_START + offset : -ENXIO;
+ struct asic3 *asic = container_of(chip, struct asic3, gpio);
+
+ return (offset < ASIC3_NUM_GPIOS) ? asic->irq_base + offset : -ENXIO;
}
static __init int asic3_gpio_probe(struct platform_device *pdev,
diff --git a/drivers/mfd/db8500-prcmu.c b/drivers/mfd/db8500-prcmu.c
index ebc1e8658226..5be32489714f 100644
--- a/drivers/mfd/db8500-prcmu.c
+++ b/drivers/mfd/db8500-prcmu.c
@@ -2788,6 +2788,7 @@ static struct regulator_init_data db8500_regulators[DB8500_NUM_REGULATORS] = {
.constraints = {
.name = "db8500-vape",
.valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .always_on = true,
},
.consumer_supplies = db8500_vape_consumers,
.num_consumer_supplies = ARRAY_SIZE(db8500_vape_consumers),
diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c
index 95a2e546a489..c8aae6640e64 100644
--- a/drivers/mfd/omap-usb-host.c
+++ b/drivers/mfd/omap-usb-host.c
@@ -25,7 +25,6 @@
#include <linux/clk.h>
#include <linux/dma-mapping.h>
#include <linux/spinlock.h>
-#include <linux/gpio.h>
#include <plat/usb.h>
#include <linux/pm_runtime.h>
@@ -502,19 +501,6 @@ static void omap_usbhs_init(struct device *dev)
pm_runtime_get_sync(dev);
spin_lock_irqsave(&omap->lock, flags);
- if (pdata->ehci_data->phy_reset) {
- if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0]))
- gpio_request_one(pdata->ehci_data->reset_gpio_port[0],
- GPIOF_OUT_INIT_LOW, "USB1 PHY reset");
-
- if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1]))
- gpio_request_one(pdata->ehci_data->reset_gpio_port[1],
- GPIOF_OUT_INIT_LOW, "USB2 PHY reset");
-
- /* Hold the PHY in RESET for enough time till DIR is high */
- udelay(10);
- }
-
omap->usbhs_rev = usbhs_read(omap->uhh_base, OMAP_UHH_REVISION);
dev_dbg(dev, "OMAP UHH_REVISION 0x%x\n", omap->usbhs_rev);
@@ -593,39 +579,10 @@ static void omap_usbhs_init(struct device *dev)
usbhs_omap_tll_init(dev, OMAP_TLL_CHANNEL_COUNT);
}
- if (pdata->ehci_data->phy_reset) {
- /* Hold the PHY in RESET for enough time till
- * PHY is settled and ready
- */
- udelay(10);
-
- if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0]))
- gpio_set_value
- (pdata->ehci_data->reset_gpio_port[0], 1);
-
- if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1]))
- gpio_set_value
- (pdata->ehci_data->reset_gpio_port[1], 1);
- }
-
spin_unlock_irqrestore(&omap->lock, flags);
pm_runtime_put_sync(dev);
}
-static void omap_usbhs_deinit(struct device *dev)
-{
- struct usbhs_hcd_omap *omap = dev_get_drvdata(dev);
- struct usbhs_omap_platform_data *pdata = &omap->platdata;
-
- if (pdata->ehci_data->phy_reset) {
- if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0]))
- gpio_free(pdata->ehci_data->reset_gpio_port[0]);
-
- if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1]))
- gpio_free(pdata->ehci_data->reset_gpio_port[1]);
- }
-}
-
/**
* usbhs_omap_probe - initialize TI-based HCDs
@@ -860,7 +817,6 @@ static int __devexit usbhs_omap_remove(struct platform_device *pdev)
{
struct usbhs_hcd_omap *omap = platform_get_drvdata(pdev);
- omap_usbhs_deinit(&pdev->dev);
iounmap(omap->tll_base);
iounmap(omap->uhh_base);
clk_put(omap->init_60m_fclk);
diff --git a/drivers/mfd/rc5t583.c b/drivers/mfd/rc5t583.c
index 99ef944c621d..44afae0a69ce 100644
--- a/drivers/mfd/rc5t583.c
+++ b/drivers/mfd/rc5t583.c
@@ -80,44 +80,6 @@ static struct mfd_cell rc5t583_subdevs[] = {
{.name = "rc5t583-key", }
};
-int rc5t583_write(struct device *dev, uint8_t reg, uint8_t val)
-{
- struct rc5t583 *rc5t583 = dev_get_drvdata(dev);
- return regmap_write(rc5t583->regmap, reg, val);
-}
-
-int rc5t583_read(struct device *dev, uint8_t reg, uint8_t *val)
-{
- struct rc5t583 *rc5t583 = dev_get_drvdata(dev);
- unsigned int ival;
- int ret;
- ret = regmap_read(rc5t583->regmap, reg, &ival);
- if (!ret)
- *val = (uint8_t)ival;
- return ret;
-}
-
-int rc5t583_set_bits(struct device *dev, unsigned int reg,
- unsigned int bit_mask)
-{
- struct rc5t583 *rc5t583 = dev_get_drvdata(dev);
- return regmap_update_bits(rc5t583->regmap, reg, bit_mask, bit_mask);
-}
-
-int rc5t583_clear_bits(struct device *dev, unsigned int reg,
- unsigned int bit_mask)
-{
- struct rc5t583 *rc5t583 = dev_get_drvdata(dev);
- return regmap_update_bits(rc5t583->regmap, reg, bit_mask, 0);
-}
-
-int rc5t583_update(struct device *dev, unsigned int reg,
- unsigned int val, unsigned int mask)
-{
- struct rc5t583 *rc5t583 = dev_get_drvdata(dev);
- return regmap_update_bits(rc5t583->regmap, reg, mask, val);
-}
-
static int __rc5t583_set_ext_pwrreq1_control(struct device *dev,
int id, int ext_pwr, int slots)
{
@@ -197,6 +159,7 @@ int rc5t583_ext_power_req_config(struct device *dev, int ds_id,
ds_id, ext_pwr_req);
return 0;
}
+EXPORT_SYMBOL(rc5t583_ext_power_req_config);
static int rc5t583_clear_ext_power_req(struct rc5t583 *rc5t583,
struct rc5t583_platform_data *pdata)
diff --git a/drivers/mfd/twl6040-core.c b/drivers/mfd/twl6040-core.c
index b2d8e512d3cb..2d6bedadca09 100644
--- a/drivers/mfd/twl6040-core.c
+++ b/drivers/mfd/twl6040-core.c
@@ -30,7 +30,9 @@
#include <linux/platform_device.h>
#include <linux/gpio.h>
#include <linux/delay.h>
-#include <linux/i2c/twl.h>
+#include <linux/i2c.h>
+#include <linux/regmap.h>
+#include <linux/err.h>
#include <linux/mfd/core.h>
#include <linux/mfd/twl6040.h>
@@ -39,7 +41,7 @@
int twl6040_reg_read(struct twl6040 *twl6040, unsigned int reg)
{
int ret;
- u8 val = 0;
+ unsigned int val;
mutex_lock(&twl6040->io_mutex);
/* Vibra control registers from cache */
@@ -47,7 +49,7 @@ int twl6040_reg_read(struct twl6040 *twl6040, unsigned int reg)
reg == TWL6040_REG_VIBCTLR)) {
val = twl6040->vibra_ctrl_cache[VIBRACTRL_MEMBER(reg)];
} else {
- ret = twl_i2c_read_u8(TWL_MODULE_AUDIO_VOICE, &val, reg);
+ ret = regmap_read(twl6040->regmap, reg, &val);
if (ret < 0) {
mutex_unlock(&twl6040->io_mutex);
return ret;
@@ -64,7 +66,7 @@ int twl6040_reg_write(struct twl6040 *twl6040, unsigned int reg, u8 val)
int ret;
mutex_lock(&twl6040->io_mutex);
- ret = twl_i2c_write_u8(TWL_MODULE_AUDIO_VOICE, val, reg);
+ ret = regmap_write(twl6040->regmap, reg, val);
/* Cache the vibra control registers */
if (reg == TWL6040_REG_VIBCTLL || reg == TWL6040_REG_VIBCTLR)
twl6040->vibra_ctrl_cache[VIBRACTRL_MEMBER(reg)] = val;
@@ -77,16 +79,9 @@ EXPORT_SYMBOL(twl6040_reg_write);
int twl6040_set_bits(struct twl6040 *twl6040, unsigned int reg, u8 mask)
{
int ret;
- u8 val;
mutex_lock(&twl6040->io_mutex);
- ret = twl_i2c_read_u8(TWL_MODULE_AUDIO_VOICE, &val, reg);
- if (ret)
- goto out;
-
- val |= mask;
- ret = twl_i2c_write_u8(TWL_MODULE_AUDIO_VOICE, val, reg);
-out:
+ ret = regmap_update_bits(twl6040->regmap, reg, mask, mask);
mutex_unlock(&twl6040->io_mutex);
return ret;
}
@@ -95,16 +90,9 @@ EXPORT_SYMBOL(twl6040_set_bits);
int twl6040_clear_bits(struct twl6040 *twl6040, unsigned int reg, u8 mask)
{
int ret;
- u8 val;
mutex_lock(&twl6040->io_mutex);
- ret = twl_i2c_read_u8(TWL_MODULE_AUDIO_VOICE, &val, reg);
- if (ret)
- goto out;
-
- val &= ~mask;
- ret = twl_i2c_write_u8(TWL_MODULE_AUDIO_VOICE, val, reg);
-out:
+ ret = regmap_update_bits(twl6040->regmap, reg, mask, 0);
mutex_unlock(&twl6040->io_mutex);
return ret;
}
@@ -494,32 +482,58 @@ static struct resource twl6040_codec_rsrc[] = {
},
};
-static int __devinit twl6040_probe(struct platform_device *pdev)
+static bool twl6040_readable_reg(struct device *dev, unsigned int reg)
{
- struct twl4030_audio_data *pdata = pdev->dev.platform_data;
+ /* Register 0 is not readable */
+ if (!reg)
+ return false;
+ return true;
+}
+
+static struct regmap_config twl6040_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .max_register = TWL6040_REG_STATUS, /* 0x2e */
+
+ .readable_reg = twl6040_readable_reg,
+};
+
+static int __devinit twl6040_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct twl6040_platform_data *pdata = client->dev.platform_data;
struct twl6040 *twl6040;
struct mfd_cell *cell = NULL;
int ret, children = 0;
if (!pdata) {
- dev_err(&pdev->dev, "Platform data is missing\n");
+ dev_err(&client->dev, "Platform data is missing\n");
return -EINVAL;
}
/* In order to operate correctly we need valid interrupt config */
- if (!pdata->naudint_irq || !pdata->irq_base) {
- dev_err(&pdev->dev, "Invalid IRQ configuration\n");
+ if (!client->irq || !pdata->irq_base) {
+ dev_err(&client->dev, "Invalid IRQ configuration\n");
return -EINVAL;
}
- twl6040 = kzalloc(sizeof(struct twl6040), GFP_KERNEL);
- if (!twl6040)
- return -ENOMEM;
+ twl6040 = devm_kzalloc(&client->dev, sizeof(struct twl6040),
+ GFP_KERNEL);
+ if (!twl6040) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ twl6040->regmap = regmap_init_i2c(client, &twl6040_regmap_config);
+ if (IS_ERR(twl6040->regmap)) {
+ ret = PTR_ERR(twl6040->regmap);
+ goto err;
+ }
- platform_set_drvdata(pdev, twl6040);
+ i2c_set_clientdata(client, twl6040);
- twl6040->dev = &pdev->dev;
- twl6040->irq = pdata->naudint_irq;
+ twl6040->dev = &client->dev;
+ twl6040->irq = client->irq;
twl6040->irq_base = pdata->irq_base;
mutex_init(&twl6040->mutex);
@@ -588,12 +602,12 @@ static int __devinit twl6040_probe(struct platform_device *pdev)
}
if (children) {
- ret = mfd_add_devices(&pdev->dev, pdev->id, twl6040->cells,
+ ret = mfd_add_devices(&client->dev, -1, twl6040->cells,
children, NULL, 0);
if (ret)
goto mfd_err;
} else {
- dev_err(&pdev->dev, "No platform data found for children\n");
+ dev_err(&client->dev, "No platform data found for children\n");
ret = -ENODEV;
goto mfd_err;
}
@@ -608,14 +622,15 @@ gpio2_err:
if (gpio_is_valid(twl6040->audpwron))
gpio_free(twl6040->audpwron);
gpio1_err:
- platform_set_drvdata(pdev, NULL);
- kfree(twl6040);
+ i2c_set_clientdata(client, NULL);
+ regmap_exit(twl6040->regmap);
+err:
return ret;
}
-static int __devexit twl6040_remove(struct platform_device *pdev)
+static int __devexit twl6040_remove(struct i2c_client *client)
{
- struct twl6040 *twl6040 = platform_get_drvdata(pdev);
+ struct twl6040 *twl6040 = i2c_get_clientdata(client);
if (twl6040->power_count)
twl6040_power(twl6040, 0);
@@ -626,23 +641,30 @@ static int __devexit twl6040_remove(struct platform_device *pdev)
free_irq(twl6040->irq_base + TWL6040_IRQ_READY, twl6040);
twl6040_irq_exit(twl6040);
- mfd_remove_devices(&pdev->dev);
- platform_set_drvdata(pdev, NULL);
- kfree(twl6040);
+ mfd_remove_devices(&client->dev);
+ i2c_set_clientdata(client, NULL);
+ regmap_exit(twl6040->regmap);
return 0;
}
-static struct platform_driver twl6040_driver = {
+static const struct i2c_device_id twl6040_i2c_id[] = {
+ { "twl6040", 0, },
+ { },
+};
+MODULE_DEVICE_TABLE(i2c, twl6040_i2c_id);
+
+static struct i2c_driver twl6040_driver = {
+ .driver = {
+ .name = "twl6040",
+ .owner = THIS_MODULE,
+ },
.probe = twl6040_probe,
.remove = __devexit_p(twl6040_remove),
- .driver = {
- .owner = THIS_MODULE,
- .name = "twl6040",
- },
+ .id_table = twl6040_i2c_id,
};
-module_platform_driver(twl6040_driver);
+module_i2c_driver(twl6040_driver);
MODULE_DESCRIPTION("TWL6040 MFD");
MODULE_AUTHOR("Misael Lopez Cruz <misael.lopez@ti.com>");
diff --git a/drivers/misc/ibmasm/ibmasmfs.c b/drivers/misc/ibmasm/ibmasmfs.c
index 1c034b80d408..6673e578b3e9 100644
--- a/drivers/misc/ibmasm/ibmasmfs.c
+++ b/drivers/misc/ibmasm/ibmasmfs.c
@@ -500,12 +500,6 @@ static ssize_t r_heartbeat_file_write(struct file *file, const char __user *buf,
return 1;
}
-static int remote_settings_file_open(struct inode *inode, struct file *file)
-{
- file->private_data = inode->i_private;
- return 0;
-}
-
static int remote_settings_file_close(struct inode *inode, struct file *file)
{
return 0;
@@ -600,7 +594,7 @@ static const struct file_operations r_heartbeat_fops = {
};
static const struct file_operations remote_settings_fops = {
- .open = remote_settings_file_open,
+ .open = simple_open,
.release = remote_settings_file_close,
.read = remote_settings_file_read,
.write = remote_settings_file_write,
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index eed213a5c8cb..dabec556ebb8 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -873,7 +873,7 @@ static int mmc_blk_issue_secdiscard_rq(struct mmc_queue *mq,
{
struct mmc_blk_data *md = mq->data;
struct mmc_card *card = md->queue.card;
- unsigned int from, nr, arg;
+ unsigned int from, nr, arg, trim_arg, erase_arg;
int err = 0, type = MMC_BLK_SECDISCARD;
if (!(mmc_can_secure_erase_trim(card) || mmc_can_sanitize(card))) {
@@ -881,20 +881,26 @@ static int mmc_blk_issue_secdiscard_rq(struct mmc_queue *mq,
goto out;
}
+ from = blk_rq_pos(req);
+ nr = blk_rq_sectors(req);
+
/* The sanitize operation is supported at v4.5 only */
if (mmc_can_sanitize(card)) {
- err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
- EXT_CSD_SANITIZE_START, 1, 0);
- goto out;
+ erase_arg = MMC_ERASE_ARG;
+ trim_arg = MMC_TRIM_ARG;
+ } else {
+ erase_arg = MMC_SECURE_ERASE_ARG;
+ trim_arg = MMC_SECURE_TRIM1_ARG;
}
- from = blk_rq_pos(req);
- nr = blk_rq_sectors(req);
-
- if (mmc_can_trim(card) && !mmc_erase_group_aligned(card, from, nr))
- arg = MMC_SECURE_TRIM1_ARG;
- else
- arg = MMC_SECURE_ERASE_ARG;
+ if (mmc_erase_group_aligned(card, from, nr))
+ arg = erase_arg;
+ else if (mmc_can_trim(card))
+ arg = trim_arg;
+ else {
+ err = -EINVAL;
+ goto out;
+ }
retry:
if (card->quirks & MMC_QUIRK_INAND_CMD38) {
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
@@ -904,25 +910,41 @@ retry:
INAND_CMD38_ARG_SECERASE,
0);
if (err)
- goto out;
+ goto out_retry;
}
+
err = mmc_erase(card, from, nr, arg);
- if (!err && arg == MMC_SECURE_TRIM1_ARG) {
+ if (err == -EIO)
+ goto out_retry;
+ if (err)
+ goto out;
+
+ if (arg == MMC_SECURE_TRIM1_ARG) {
if (card->quirks & MMC_QUIRK_INAND_CMD38) {
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
INAND_CMD38_ARG_EXT_CSD,
INAND_CMD38_ARG_SECTRIM2,
0);
if (err)
- goto out;
+ goto out_retry;
}
+
err = mmc_erase(card, from, nr, MMC_SECURE_TRIM2_ARG);
+ if (err == -EIO)
+ goto out_retry;
+ if (err)
+ goto out;
}
-out:
- if (err == -EIO && !mmc_blk_reset(md, card->host, type))
+
+ if (mmc_can_sanitize(card))
+ err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
+ EXT_CSD_SANITIZE_START, 1, 0);
+out_retry:
+ if (err && !mmc_blk_reset(md, card->host, type))
goto retry;
if (!err)
mmc_blk_reset_success(md, type);
+out:
spin_lock_irq(&md->lock);
__blk_end_request(req, err, blk_rq_bytes(req));
spin_unlock_irq(&md->lock);
@@ -1623,24 +1645,6 @@ static int mmc_blk_alloc_parts(struct mmc_card *card, struct mmc_blk_data *md)
return ret;
}
-static int
-mmc_blk_set_blksize(struct mmc_blk_data *md, struct mmc_card *card)
-{
- int err;
-
- mmc_claim_host(card->host);
- err = mmc_set_blocklen(card, 512);
- mmc_release_host(card->host);
-
- if (err) {
- pr_err("%s: unable to set block size to 512: %d\n",
- md->disk->disk_name, err);
- return -EINVAL;
- }
-
- return 0;
-}
-
static void mmc_blk_remove_req(struct mmc_blk_data *md)
{
struct mmc_card *card;
@@ -1768,7 +1772,6 @@ static const struct mmc_fixup blk_fixups[] =
static int mmc_blk_probe(struct mmc_card *card)
{
struct mmc_blk_data *md, *part_md;
- int err;
char cap_str[10];
/*
@@ -1781,10 +1784,6 @@ static int mmc_blk_probe(struct mmc_card *card)
if (IS_ERR(md))
return PTR_ERR(md);
- err = mmc_blk_set_blksize(md, card);
- if (err)
- goto out;
-
string_get_size((u64)get_capacity(md->disk) << 9, STRING_UNITS_2,
cap_str, sizeof(cap_str));
pr_info("%s: %s %s %s %s\n",
@@ -1809,7 +1808,7 @@ static int mmc_blk_probe(struct mmc_card *card)
out:
mmc_blk_remove_parts(card, md);
mmc_blk_remove_req(md);
- return err;
+ return 0;
}
static void mmc_blk_remove(struct mmc_card *card)
@@ -1825,7 +1824,7 @@ static void mmc_blk_remove(struct mmc_card *card)
}
#ifdef CONFIG_PM
-static int mmc_blk_suspend(struct mmc_card *card, pm_message_t state)
+static int mmc_blk_suspend(struct mmc_card *card)
{
struct mmc_blk_data *part_md;
struct mmc_blk_data *md = mmc_get_drvdata(card);
@@ -1845,8 +1844,6 @@ static int mmc_blk_resume(struct mmc_card *card)
struct mmc_blk_data *md = mmc_get_drvdata(card);
if (md) {
- mmc_blk_set_blksize(md, card);
-
/*
* Resume involves the card going into idle state,
* so current partition is always the main one.
diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c
index 2517547b4366..996f8e36e23d 100644
--- a/drivers/mmc/card/queue.c
+++ b/drivers/mmc/card/queue.c
@@ -139,7 +139,7 @@ static void mmc_queue_setup_discard(struct request_queue *q,
queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, q);
q->limits.max_discard_sectors = max_discard;
- if (card->erased_byte == 0)
+ if (card->erased_byte == 0 && !mmc_can_discard(card))
q->limits.discard_zeroes_data = 1;
q->limits.discard_granularity = card->pref_erase << 9;
/* granularity must not be greater than max. discard */
diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c
index 5d011a39dfff..c60cee92a2b2 100644
--- a/drivers/mmc/core/bus.c
+++ b/drivers/mmc/core/bus.c
@@ -122,14 +122,14 @@ static int mmc_bus_remove(struct device *dev)
return 0;
}
-static int mmc_bus_suspend(struct device *dev, pm_message_t state)
+static int mmc_bus_suspend(struct device *dev)
{
struct mmc_driver *drv = to_mmc_driver(dev->driver);
struct mmc_card *card = mmc_dev_to_card(dev);
int ret = 0;
if (dev->driver && drv->suspend)
- ret = drv->suspend(card, state);
+ ret = drv->suspend(card);
return ret;
}
@@ -165,20 +165,14 @@ static int mmc_runtime_idle(struct device *dev)
return pm_runtime_suspend(dev);
}
+#endif /* !CONFIG_PM_RUNTIME */
+
static const struct dev_pm_ops mmc_bus_pm_ops = {
- .runtime_suspend = mmc_runtime_suspend,
- .runtime_resume = mmc_runtime_resume,
- .runtime_idle = mmc_runtime_idle,
+ SET_RUNTIME_PM_OPS(mmc_runtime_suspend, mmc_runtime_resume,
+ mmc_runtime_idle)
+ SET_SYSTEM_SLEEP_PM_OPS(mmc_bus_suspend, mmc_bus_resume)
};
-#define MMC_PM_OPS_PTR (&mmc_bus_pm_ops)
-
-#else /* !CONFIG_PM_RUNTIME */
-
-#define MMC_PM_OPS_PTR NULL
-
-#endif /* !CONFIG_PM_RUNTIME */
-
static struct bus_type mmc_bus_type = {
.name = "mmc",
.dev_attrs = mmc_dev_attrs,
@@ -186,9 +180,7 @@ static struct bus_type mmc_bus_type = {
.uevent = mmc_bus_uevent,
.probe = mmc_bus_probe,
.remove = mmc_bus_remove,
- .suspend = mmc_bus_suspend,
- .resume = mmc_bus_resume,
- .pm = MMC_PM_OPS_PTR,
+ .pm = &mmc_bus_pm_ops,
};
int mmc_register_bus(void)
@@ -267,6 +259,15 @@ int mmc_add_card(struct mmc_card *card)
{
int ret;
const char *type;
+ const char *uhs_bus_speed_mode = "";
+ static const char *const uhs_speeds[] = {
+ [UHS_SDR12_BUS_SPEED] = "SDR12 ",
+ [UHS_SDR25_BUS_SPEED] = "SDR25 ",
+ [UHS_SDR50_BUS_SPEED] = "SDR50 ",
+ [UHS_SDR104_BUS_SPEED] = "SDR104 ",
+ [UHS_DDR50_BUS_SPEED] = "DDR50 ",
+ };
+
dev_set_name(&card->dev, "%s:%04x", mmc_hostname(card->host), card->rca);
@@ -296,6 +297,10 @@ int mmc_add_card(struct mmc_card *card)
break;
}
+ if (mmc_sd_card_uhs(card) &&
+ (card->sd_bus_speed < ARRAY_SIZE(uhs_speeds)))
+ uhs_bus_speed_mode = uhs_speeds[card->sd_bus_speed];
+
if (mmc_host_is_spi(card->host)) {
pr_info("%s: new %s%s%s card on SPI\n",
mmc_hostname(card->host),
@@ -303,13 +308,13 @@ int mmc_add_card(struct mmc_card *card)
mmc_card_ddr_mode(card) ? "DDR " : "",
type);
} else {
- pr_info("%s: new %s%s%s%s card at address %04x\n",
+ pr_info("%s: new %s%s%s%s%s card at address %04x\n",
mmc_hostname(card->host),
mmc_card_uhs(card) ? "ultra high speed " :
(mmc_card_highspeed(card) ? "high speed " : ""),
(mmc_card_hs200(card) ? "HS200 " : ""),
mmc_card_ddr_mode(card) ? "DDR " : "",
- type, card->rca);
+ uhs_bus_speed_mode, type, card->rca);
}
#ifdef CONFIG_DEBUG_FS
diff --git a/drivers/mmc/core/cd-gpio.c b/drivers/mmc/core/cd-gpio.c
index 29de31e260dd..2c14be73254c 100644
--- a/drivers/mmc/core/cd-gpio.c
+++ b/drivers/mmc/core/cd-gpio.c
@@ -12,6 +12,7 @@
#include <linux/gpio.h>
#include <linux/interrupt.h>
#include <linux/jiffies.h>
+#include <linux/mmc/cd-gpio.h>
#include <linux/mmc/host.h>
#include <linux/module.h>
#include <linux/slab.h>
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 14f262e9246d..ba821fe70bca 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -527,10 +527,14 @@ void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card)
if (data->flags & MMC_DATA_WRITE)
/*
- * The limit is really 250 ms, but that is
- * insufficient for some crappy cards.
+ * The MMC spec "It is strongly recommended
+ * for hosts to implement more than 500ms
+ * timeout value even if the card indicates
+ * the 250ms maximum busy length." Even the
+ * previous value of 300ms is known to be
+ * insufficient for some cards.
*/
- limit_us = 300000;
+ limit_us = 3000000;
else
limit_us = 100000;
@@ -1405,7 +1409,10 @@ static unsigned int mmc_mmc_erase_timeout(struct mmc_card *card,
{
unsigned int erase_timeout;
- if (card->ext_csd.erase_group_def & 1) {
+ if (arg == MMC_DISCARD_ARG ||
+ (arg == MMC_TRIM_ARG && card->ext_csd.rev >= 6)) {
+ erase_timeout = card->ext_csd.trim_timeout;
+ } else if (card->ext_csd.erase_group_def & 1) {
/* High Capacity Erase Group Size uses HC timeouts */
if (arg == MMC_TRIM_ARG)
erase_timeout = card->ext_csd.trim_timeout;
@@ -1677,8 +1684,6 @@ int mmc_can_trim(struct mmc_card *card)
{
if (card->ext_csd.sec_feature_support & EXT_CSD_SEC_GB_CL_EN)
return 1;
- if (mmc_can_discard(card))
- return 1;
return 0;
}
EXPORT_SYMBOL(mmc_can_trim);
@@ -1697,6 +1702,8 @@ EXPORT_SYMBOL(mmc_can_discard);
int mmc_can_sanitize(struct mmc_card *card)
{
+ if (!mmc_can_trim(card) && !mmc_can_erase(card))
+ return 0;
if (card->ext_csd.sec_feature_support & EXT_CSD_SEC_SANITIZE)
return 1;
return 0;
@@ -2231,6 +2238,7 @@ int mmc_cache_ctrl(struct mmc_host *host, u8 enable)
mmc_card_is_removable(host))
return err;
+ mmc_claim_host(host);
if (card && mmc_card_mmc(card) &&
(card->ext_csd.cache_size > 0)) {
enable = !!enable;
@@ -2248,6 +2256,7 @@ int mmc_cache_ctrl(struct mmc_host *host, u8 enable)
card->ext_csd.cache_ctrl = enable;
}
}
+ mmc_release_host(host);
return err;
}
@@ -2265,49 +2274,32 @@ int mmc_suspend_host(struct mmc_host *host)
cancel_delayed_work(&host->detect);
mmc_flush_scheduled_work();
- if (mmc_try_claim_host(host)) {
- err = mmc_cache_ctrl(host, 0);
- mmc_release_host(host);
- } else {
- err = -EBUSY;
- }
+ err = mmc_cache_ctrl(host, 0);
if (err)
goto out;
mmc_bus_get(host);
if (host->bus_ops && !host->bus_dead) {
- /*
- * A long response time is not acceptable for device drivers
- * when doing suspend. Prevent mmc_claim_host in the suspend
- * sequence, to potentially wait "forever" by trying to
- * pre-claim the host.
- */
- if (mmc_try_claim_host(host)) {
- if (host->bus_ops->suspend) {
- err = host->bus_ops->suspend(host);
- }
- mmc_release_host(host);
+ if (host->bus_ops->suspend)
+ err = host->bus_ops->suspend(host);
- if (err == -ENOSYS || !host->bus_ops->resume) {
- /*
- * We simply "remove" the card in this case.
- * It will be redetected on resume. (Calling
- * bus_ops->remove() with a claimed host can
- * deadlock.)
- */
- if (host->bus_ops->remove)
- host->bus_ops->remove(host);
- mmc_claim_host(host);
- mmc_detach_bus(host);
- mmc_power_off(host);
- mmc_release_host(host);
- host->pm_flags = 0;
- err = 0;
- }
- } else {
- err = -EBUSY;
+ if (err == -ENOSYS || !host->bus_ops->resume) {
+ /*
+ * We simply "remove" the card in this case.
+ * It will be redetected on resume. (Calling
+ * bus_ops->remove() with a claimed host can
+ * deadlock.)
+ */
+ if (host->bus_ops->remove)
+ host->bus_ops->remove(host);
+ mmc_claim_host(host);
+ mmc_detach_bus(host);
+ mmc_power_off(host);
+ mmc_release_host(host);
+ host->pm_flags = 0;
+ err = 0;
}
}
mmc_bus_put(host);
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 02914d609a91..54df5adc0413 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -695,6 +695,11 @@ static int mmc_select_powerclass(struct mmc_card *card,
else if (host->ios.clock <= 200000000)
index = EXT_CSD_PWR_CL_200_195;
break;
+ case MMC_VDD_27_28:
+ case MMC_VDD_28_29:
+ case MMC_VDD_29_30:
+ case MMC_VDD_30_31:
+ case MMC_VDD_31_32:
case MMC_VDD_32_33:
case MMC_VDD_33_34:
case MMC_VDD_34_35:
@@ -1111,11 +1116,10 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
ext_csd_bits = (bus_width == MMC_BUS_WIDTH_8) ?
EXT_CSD_BUS_WIDTH_8 : EXT_CSD_BUS_WIDTH_4;
err = mmc_select_powerclass(card, ext_csd_bits, ext_csd);
- if (err) {
- pr_err("%s: power class selection to bus width %d failed\n",
- mmc_hostname(card->host), 1 << bus_width);
- goto err;
- }
+ if (err)
+ pr_warning("%s: power class selection to bus width %d"
+ " failed\n", mmc_hostname(card->host),
+ 1 << bus_width);
}
/*
@@ -1147,10 +1151,10 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
err = mmc_select_powerclass(card, ext_csd_bits[idx][0],
ext_csd);
if (err)
- pr_err("%s: power class selection to "
- "bus width %d failed\n",
- mmc_hostname(card->host),
- 1 << bus_width);
+ pr_warning("%s: power class selection to "
+ "bus width %d failed\n",
+ mmc_hostname(card->host),
+ 1 << bus_width);
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
EXT_CSD_BUS_WIDTH,
@@ -1178,10 +1182,10 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
err = mmc_select_powerclass(card, ext_csd_bits[idx][1],
ext_csd);
if (err)
- pr_err("%s: power class selection to "
- "bus width %d ddr %d failed\n",
- mmc_hostname(card->host),
- 1 << bus_width, ddr);
+ pr_warning("%s: power class selection to "
+ "bus width %d ddr %d failed\n",
+ mmc_hostname(card->host),
+ 1 << bus_width, ddr);
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
EXT_CSD_BUS_WIDTH,
diff --git a/drivers/mmc/core/sdio_bus.c b/drivers/mmc/core/sdio_bus.c
index 40989e6bb53a..236842ec955a 100644
--- a/drivers/mmc/core/sdio_bus.c
+++ b/drivers/mmc/core/sdio_bus.c
@@ -192,9 +192,15 @@ static int sdio_bus_remove(struct device *dev)
return ret;
}
-#ifdef CONFIG_PM_RUNTIME
+#ifdef CONFIG_PM
+
+static int pm_no_operation(struct device *dev)
+{
+ return 0;
+}
static const struct dev_pm_ops sdio_bus_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(pm_no_operation, pm_no_operation)
SET_RUNTIME_PM_OPS(
pm_generic_runtime_suspend,
pm_generic_runtime_resume,
@@ -204,11 +210,11 @@ static const struct dev_pm_ops sdio_bus_pm_ops = {
#define SDIO_PM_OPS_PTR (&sdio_bus_pm_ops)
-#else /* !CONFIG_PM_RUNTIME */
+#else /* !CONFIG_PM */
#define SDIO_PM_OPS_PTR NULL
-#endif /* !CONFIG_PM_RUNTIME */
+#endif /* !CONFIG_PM */
static struct bus_type sdio_bus_type = {
.name = "sdio",
diff --git a/drivers/mmc/host/atmel-mci-regs.h b/drivers/mmc/host/atmel-mci-regs.h
index 000b3ad0f5ca..787aba1682bb 100644
--- a/drivers/mmc/host/atmel-mci-regs.h
+++ b/drivers/mmc/host/atmel-mci-regs.h
@@ -31,6 +31,7 @@
# define ATMCI_MR_PDCFBYTE ( 1 << 13) /* Force Byte Transfer */
# define ATMCI_MR_PDCPADV ( 1 << 14) /* Padding Value */
# define ATMCI_MR_PDCMODE ( 1 << 15) /* PDC-oriented Mode */
+# define ATMCI_MR_CLKODD(x) ((x) << 16) /* LSB of Clock Divider */
#define ATMCI_DTOR 0x0008 /* Data Timeout */
# define ATMCI_DTOCYC(x) ((x) << 0) /* Data Timeout Cycles */
# define ATMCI_DTOMUL(x) ((x) << 4) /* Data Timeout Multiplier */
diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c
index 9819dc09ce08..e94476beca18 100644
--- a/drivers/mmc/host/atmel-mci.c
+++ b/drivers/mmc/host/atmel-mci.c
@@ -77,6 +77,7 @@ struct atmel_mci_caps {
bool has_cstor_reg;
bool has_highspeed;
bool has_rwproof;
+ bool has_odd_clk_div;
};
struct atmel_mci_dma {
@@ -482,7 +483,14 @@ err:
static inline unsigned int atmci_ns_to_clocks(struct atmel_mci *host,
unsigned int ns)
{
- return (ns * (host->bus_hz / 1000000) + 999) / 1000;
+ /*
+ * It is easier here to use us instead of ns for the timeout,
+ * it prevents from overflows during calculation.
+ */
+ unsigned int us = DIV_ROUND_UP(ns, 1000);
+
+ /* Maximum clock frequency is host->bus_hz/2 */
+ return us * (DIV_ROUND_UP(host->bus_hz, 2000000));
}
static void atmci_set_timeout(struct atmel_mci *host,
@@ -1127,16 +1135,27 @@ static void atmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
}
/* Calculate clock divider */
- clkdiv = DIV_ROUND_UP(host->bus_hz, 2 * clock_min) - 1;
- if (clkdiv > 255) {
- dev_warn(&mmc->class_dev,
- "clock %u too slow; using %lu\n",
- clock_min, host->bus_hz / (2 * 256));
- clkdiv = 255;
+ if (host->caps.has_odd_clk_div) {
+ clkdiv = DIV_ROUND_UP(host->bus_hz, clock_min) - 2;
+ if (clkdiv > 511) {
+ dev_warn(&mmc->class_dev,
+ "clock %u too slow; using %lu\n",
+ clock_min, host->bus_hz / (511 + 2));
+ clkdiv = 511;
+ }
+ host->mode_reg = ATMCI_MR_CLKDIV(clkdiv >> 1)
+ | ATMCI_MR_CLKODD(clkdiv & 1);
+ } else {
+ clkdiv = DIV_ROUND_UP(host->bus_hz, 2 * clock_min) - 1;
+ if (clkdiv > 255) {
+ dev_warn(&mmc->class_dev,
+ "clock %u too slow; using %lu\n",
+ clock_min, host->bus_hz / (2 * 256));
+ clkdiv = 255;
+ }
+ host->mode_reg = ATMCI_MR_CLKDIV(clkdiv);
}
- host->mode_reg = ATMCI_MR_CLKDIV(clkdiv);
-
/*
* WRPROOF and RDPROOF prevent overruns/underruns by
* stopping the clock when the FIFO is full/empty.
@@ -2007,35 +2026,35 @@ static void __init atmci_get_cap(struct atmel_mci *host)
"version: 0x%x\n", version);
host->caps.has_dma = 0;
- host->caps.has_pdc = 0;
+ host->caps.has_pdc = 1;
host->caps.has_cfg_reg = 0;
host->caps.has_cstor_reg = 0;
host->caps.has_highspeed = 0;
host->caps.has_rwproof = 0;
+ host->caps.has_odd_clk_div = 0;
/* keep only major version number */
switch (version & 0xf00) {
- case 0x100:
- case 0x200:
- host->caps.has_pdc = 1;
- host->caps.has_rwproof = 1;
- break;
- case 0x300:
- case 0x400:
case 0x500:
+ host->caps.has_odd_clk_div = 1;
+ case 0x400:
+ case 0x300:
#ifdef CONFIG_AT_HDMAC
host->caps.has_dma = 1;
#else
- host->caps.has_dma = 0;
dev_info(&host->pdev->dev,
"has dma capability but dma engine is not selected, then use pio\n");
#endif
+ host->caps.has_pdc = 0;
host->caps.has_cfg_reg = 1;
host->caps.has_cstor_reg = 1;
host->caps.has_highspeed = 1;
+ case 0x200:
host->caps.has_rwproof = 1;
+ case 0x100:
break;
default:
+ host->caps.has_pdc = 0;
dev_warn(&host->pdev->dev,
"Unmanaged mci version, set minimum capabilities\n");
break;
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index bf3c9b456aaf..ab3fc4617107 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -526,8 +526,10 @@ static int dw_mci_submit_data_dma(struct dw_mci *host, struct mmc_data *data)
return -ENODEV;
sg_len = dw_mci_pre_dma_transfer(host, data, 0);
- if (sg_len < 0)
+ if (sg_len < 0) {
+ host->dma_ops->stop(host);
return sg_len;
+ }
host->using_dma = 1;
@@ -1879,7 +1881,8 @@ static void dw_mci_init_dma(struct dw_mci *host)
if (!host->dma_ops)
goto no_dma;
- if (host->dma_ops->init) {
+ if (host->dma_ops->init && host->dma_ops->start &&
+ host->dma_ops->stop && host->dma_ops->cleanup) {
if (host->dma_ops->init(host)) {
dev_err(&host->dev, "%s: Unable to initialize "
"DMA Controller.\n", __func__);
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 47adb161d3ad..56d4499d4388 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -249,7 +249,7 @@ static int omap_hsmmc_set_power(struct device *dev, int slot, int power_on,
* the pbias cell programming support is still missing when
* booting with Device tree
*/
- if (of_have_populated_dt() && !vdd)
+ if (dev->of_node && !vdd)
return 0;
if (mmc_slot(host).before_set_reg)
@@ -1549,7 +1549,7 @@ static void omap_hsmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
* can't be allowed when booting with device
* tree.
*/
- (!of_have_populated_dt())) {
+ !host->dev->of_node) {
/*
* The mmc_select_voltage fn of the core does
* not seem to set the power_mode to
@@ -1741,7 +1741,7 @@ static const struct of_device_id omap_mmc_of_match[] = {
.data = &omap4_reg_offset,
},
{},
-}
+};
MODULE_DEVICE_TABLE(of, omap_mmc_of_match);
static struct omap_mmc_platform_data *of_get_hsmmc_pdata(struct device *dev)
@@ -1785,7 +1785,7 @@ static inline struct omap_mmc_platform_data
}
#endif
-static int __init omap_hsmmc_probe(struct platform_device *pdev)
+static int __devinit omap_hsmmc_probe(struct platform_device *pdev)
{
struct omap_mmc_platform_data *pdata = pdev->dev.platform_data;
struct mmc_host *mmc;
@@ -1818,8 +1818,6 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev)
if (res == NULL || irq < 0)
return -ENXIO;
- res->start += pdata->reg_offset;
- res->end += pdata->reg_offset;
res = request_mem_region(res->start, resource_size(res), pdev->name);
if (res == NULL)
return -EBUSY;
@@ -1843,7 +1841,7 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev)
host->dma_ch = -1;
host->irq = irq;
host->slot_id = 0;
- host->mapbase = res->start;
+ host->mapbase = res->start + pdata->reg_offset;
host->base = ioremap(host->mapbase, SZ_4K);
host->power_mode = MMC_POWER_OFF;
host->next_data.cookie = 1;
@@ -1875,8 +1873,6 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev)
goto err1;
}
- omap_hsmmc_context_save(host);
-
if (host->pdata->controller_flags & OMAP_HSMMC_BROKEN_MULTIBLOCK_READ) {
dev_info(&pdev->dev, "multiblock reads disabled due to 35xx erratum 2.1.1.128; MMC read performance may suffer\n");
mmc->caps2 |= MMC_CAP2_NO_MULTI_READ;
@@ -1887,6 +1883,8 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev)
pm_runtime_set_autosuspend_delay(host->dev, MMC_AUTOSUSPEND_DELAY);
pm_runtime_use_autosuspend(host->dev);
+ omap_hsmmc_context_save(host);
+
if (cpu_is_omap2430()) {
host->dbclk = clk_get(&pdev->dev, "mmchsdb_fck");
/*
@@ -2018,8 +2016,7 @@ err_reg:
err_irq_cd_init:
free_irq(host->irq, host);
err_irq:
- pm_runtime_mark_last_busy(host->dev);
- pm_runtime_put_autosuspend(host->dev);
+ pm_runtime_put_sync(host->dev);
pm_runtime_disable(host->dev);
clk_put(host->fclk);
if (host->got_dbclk) {
@@ -2037,35 +2034,33 @@ err:
return ret;
}
-static int omap_hsmmc_remove(struct platform_device *pdev)
+static int __devexit omap_hsmmc_remove(struct platform_device *pdev)
{
struct omap_hsmmc_host *host = platform_get_drvdata(pdev);
struct resource *res;
- if (host) {
- pm_runtime_get_sync(host->dev);
- mmc_remove_host(host->mmc);
- if (host->use_reg)
- omap_hsmmc_reg_put(host);
- if (host->pdata->cleanup)
- host->pdata->cleanup(&pdev->dev);
- free_irq(host->irq, host);
- if (mmc_slot(host).card_detect_irq)
- free_irq(mmc_slot(host).card_detect_irq, host);
-
- pm_runtime_put_sync(host->dev);
- pm_runtime_disable(host->dev);
- clk_put(host->fclk);
- if (host->got_dbclk) {
- clk_disable(host->dbclk);
- clk_put(host->dbclk);
- }
+ pm_runtime_get_sync(host->dev);
+ mmc_remove_host(host->mmc);
+ if (host->use_reg)
+ omap_hsmmc_reg_put(host);
+ if (host->pdata->cleanup)
+ host->pdata->cleanup(&pdev->dev);
+ free_irq(host->irq, host);
+ if (mmc_slot(host).card_detect_irq)
+ free_irq(mmc_slot(host).card_detect_irq, host);
- mmc_free_host(host->mmc);
- iounmap(host->base);
- omap_hsmmc_gpio_free(pdev->dev.platform_data);
+ pm_runtime_put_sync(host->dev);
+ pm_runtime_disable(host->dev);
+ clk_put(host->fclk);
+ if (host->got_dbclk) {
+ clk_disable(host->dbclk);
+ clk_put(host->dbclk);
}
+ mmc_free_host(host->mmc);
+ iounmap(host->base);
+ omap_hsmmc_gpio_free(pdev->dev.platform_data);
+
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (res)
release_mem_region(res->start, resource_size(res));
@@ -2078,49 +2073,45 @@ static int omap_hsmmc_remove(struct platform_device *pdev)
static int omap_hsmmc_suspend(struct device *dev)
{
int ret = 0;
- struct platform_device *pdev = to_platform_device(dev);
- struct omap_hsmmc_host *host = platform_get_drvdata(pdev);
+ struct omap_hsmmc_host *host = dev_get_drvdata(dev);
- if (host && host->suspended)
+ if (!host)
return 0;
- if (host) {
- pm_runtime_get_sync(host->dev);
- host->suspended = 1;
- if (host->pdata->suspend) {
- ret = host->pdata->suspend(&pdev->dev,
- host->slot_id);
- if (ret) {
- dev_dbg(mmc_dev(host->mmc),
- "Unable to handle MMC board"
- " level suspend\n");
- host->suspended = 0;
- return ret;
- }
- }
- ret = mmc_suspend_host(host->mmc);
+ if (host && host->suspended)
+ return 0;
+ pm_runtime_get_sync(host->dev);
+ host->suspended = 1;
+ if (host->pdata->suspend) {
+ ret = host->pdata->suspend(dev, host->slot_id);
if (ret) {
+ dev_dbg(dev, "Unable to handle MMC board"
+ " level suspend\n");
host->suspended = 0;
- if (host->pdata->resume) {
- ret = host->pdata->resume(&pdev->dev,
- host->slot_id);
- if (ret)
- dev_dbg(mmc_dev(host->mmc),
- "Unmask interrupt failed\n");
- }
- goto err;
+ return ret;
}
+ }
+ ret = mmc_suspend_host(host->mmc);
- if (!(host->mmc->pm_flags & MMC_PM_KEEP_POWER)) {
- omap_hsmmc_disable_irq(host);
- OMAP_HSMMC_WRITE(host->base, HCTL,
- OMAP_HSMMC_READ(host->base, HCTL) & ~SDBP);
+ if (ret) {
+ host->suspended = 0;
+ if (host->pdata->resume) {
+ ret = host->pdata->resume(dev, host->slot_id);
+ if (ret)
+ dev_dbg(dev, "Unmask interrupt failed\n");
}
- if (host->got_dbclk)
- clk_disable(host->dbclk);
+ goto err;
+ }
+ if (!(host->mmc->pm_flags & MMC_PM_KEEP_POWER)) {
+ omap_hsmmc_disable_irq(host);
+ OMAP_HSMMC_WRITE(host->base, HCTL,
+ OMAP_HSMMC_READ(host->base, HCTL) & ~SDBP);
}
+
+ if (host->got_dbclk)
+ clk_disable(host->dbclk);
err:
pm_runtime_put_sync(host->dev);
return ret;
@@ -2130,38 +2121,37 @@ err:
static int omap_hsmmc_resume(struct device *dev)
{
int ret = 0;
- struct platform_device *pdev = to_platform_device(dev);
- struct omap_hsmmc_host *host = platform_get_drvdata(pdev);
+ struct omap_hsmmc_host *host = dev_get_drvdata(dev);
+
+ if (!host)
+ return 0;
if (host && !host->suspended)
return 0;
- if (host) {
- pm_runtime_get_sync(host->dev);
+ pm_runtime_get_sync(host->dev);
- if (host->got_dbclk)
- clk_enable(host->dbclk);
+ if (host->got_dbclk)
+ clk_enable(host->dbclk);
- if (!(host->mmc->pm_flags & MMC_PM_KEEP_POWER))
- omap_hsmmc_conf_bus_power(host);
+ if (!(host->mmc->pm_flags & MMC_PM_KEEP_POWER))
+ omap_hsmmc_conf_bus_power(host);
- if (host->pdata->resume) {
- ret = host->pdata->resume(&pdev->dev, host->slot_id);
- if (ret)
- dev_dbg(mmc_dev(host->mmc),
- "Unmask interrupt failed\n");
- }
+ if (host->pdata->resume) {
+ ret = host->pdata->resume(dev, host->slot_id);
+ if (ret)
+ dev_dbg(dev, "Unmask interrupt failed\n");
+ }
- omap_hsmmc_protect_card(host);
+ omap_hsmmc_protect_card(host);
- /* Notify the core to resume the host */
- ret = mmc_resume_host(host->mmc);
- if (ret == 0)
- host->suspended = 0;
+ /* Notify the core to resume the host */
+ ret = mmc_resume_host(host->mmc);
+ if (ret == 0)
+ host->suspended = 0;
- pm_runtime_mark_last_busy(host->dev);
- pm_runtime_put_autosuspend(host->dev);
- }
+ pm_runtime_mark_last_busy(host->dev);
+ pm_runtime_put_autosuspend(host->dev);
return ret;
@@ -2178,7 +2168,7 @@ static int omap_hsmmc_runtime_suspend(struct device *dev)
host = platform_get_drvdata(to_platform_device(dev));
omap_hsmmc_context_save(host);
- dev_dbg(mmc_dev(host->mmc), "disabled\n");
+ dev_dbg(dev, "disabled\n");
return 0;
}
@@ -2189,7 +2179,7 @@ static int omap_hsmmc_runtime_resume(struct device *dev)
host = platform_get_drvdata(to_platform_device(dev));
omap_hsmmc_context_restore(host);
- dev_dbg(mmc_dev(host->mmc), "enabled\n");
+ dev_dbg(dev, "enabled\n");
return 0;
}
@@ -2202,7 +2192,8 @@ static struct dev_pm_ops omap_hsmmc_dev_pm_ops = {
};
static struct platform_driver omap_hsmmc_driver = {
- .remove = omap_hsmmc_remove,
+ .probe = omap_hsmmc_probe,
+ .remove = __devexit_p(omap_hsmmc_remove),
.driver = {
.name = DRIVER_NAME,
.owner = THIS_MODULE,
@@ -2211,21 +2202,7 @@ static struct platform_driver omap_hsmmc_driver = {
},
};
-static int __init omap_hsmmc_init(void)
-{
- /* Register the MMC driver */
- return platform_driver_probe(&omap_hsmmc_driver, omap_hsmmc_probe);
-}
-
-static void __exit omap_hsmmc_cleanup(void)
-{
- /* Unregister MMC driver */
- platform_driver_unregister(&omap_hsmmc_driver);
-}
-
-module_init(omap_hsmmc_init);
-module_exit(omap_hsmmc_cleanup);
-
+module_platform_driver(omap_hsmmc_driver);
MODULE_DESCRIPTION("OMAP High Speed Multimedia Card driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:" DRIVER_NAME);
diff --git a/drivers/mmc/host/sdhci-dove.c b/drivers/mmc/host/sdhci-dove.c
index 46fd1fd1b605..177f697b5835 100644
--- a/drivers/mmc/host/sdhci-dove.c
+++ b/drivers/mmc/host/sdhci-dove.c
@@ -20,6 +20,7 @@
*/
#include <linux/io.h>
+#include <linux/module.h>
#include <linux/mmc/host.h>
#include "sdhci-pltfm.h"
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index 6193a0d7bde5..8abdaf6697a8 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -467,8 +467,7 @@ static int __devinit sdhci_esdhc_imx_probe(struct platform_device *pdev)
clk_prepare_enable(clk);
pltfm_host->clk = clk;
- if (!is_imx25_esdhc(imx_data))
- host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL;
+ host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL;
if (is_imx25_esdhc(imx_data) || is_imx35_esdhc(imx_data))
/* Fix errata ENGcm07207 present on i.MX25 and i.MX35 */
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c
index fbbebe251e01..69ef0beae104 100644
--- a/drivers/mmc/host/sdhci-pci.c
+++ b/drivers/mmc/host/sdhci-pci.c
@@ -1418,8 +1418,6 @@ static int __devinit sdhci_pci_probe(struct pci_dev *pdev,
slots = chip->num_slots; /* Quirk may have changed this */
- pci_enable_msi(pdev);
-
for (i = 0; i < slots; i++) {
slot = sdhci_pci_probe_slot(pdev, chip, first_bar, i);
if (IS_ERR(slot)) {
@@ -1438,8 +1436,6 @@ static int __devinit sdhci_pci_probe(struct pci_dev *pdev,
return 0;
free:
- pci_disable_msi(pdev);
-
pci_set_drvdata(pdev, NULL);
kfree(chip);
@@ -1462,8 +1458,6 @@ static void __devexit sdhci_pci_remove(struct pci_dev *pdev)
for (i = 0; i < chip->num_slots; i++)
sdhci_pci_remove_slot(chip->slots[i]);
- pci_disable_msi(pdev);
-
pci_set_drvdata(pdev, NULL);
kfree(chip);
}
diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c
index b19e7d435f8d..55a164fcaa15 100644
--- a/drivers/mmc/host/sdhci-s3c.c
+++ b/drivers/mmc/host/sdhci-s3c.c
@@ -20,6 +20,10 @@
#include <linux/io.h>
#include <linux/gpio.h>
#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+#include <linux/pm.h>
+#include <linux/pm_runtime.h>
#include <linux/mmc/host.h>
@@ -53,6 +57,18 @@ struct sdhci_s3c {
struct clk *clk_bus[MAX_BUS_CLK];
};
+/**
+ * struct sdhci_s3c_driver_data - S3C SDHCI platform specific driver data
+ * @sdhci_quirks: sdhci host specific quirks.
+ *
+ * Specifies platform specific configuration of sdhci controller.
+ * Note: A structure for driver specific platform data is used for future
+ * expansion of its usage.
+ */
+struct sdhci_s3c_drv_data {
+ unsigned int sdhci_quirks;
+};
+
static inline struct sdhci_s3c *to_s3c(struct sdhci_host *host)
{
return sdhci_priv(host);
@@ -132,10 +148,10 @@ static unsigned int sdhci_s3c_consider_clock(struct sdhci_s3c *ourhost,
return UINT_MAX;
/*
- * Clock divider's step is different as 1 from that of host controller
- * when 'clk_type' is S3C_SDHCI_CLK_DIV_EXTERNAL.
+ * If controller uses a non-standard clock division, find the best clock
+ * speed possible with selected clock source and skip the division.
*/
- if (ourhost->pdata->clk_type) {
+ if (ourhost->host->quirks & SDHCI_QUIRK_NONSTANDARD_CLOCK) {
rate = clk_round_rate(clksrc, wanted);
return wanted - rate;
}
@@ -272,6 +288,8 @@ static unsigned int sdhci_cmu_get_min_clock(struct sdhci_host *host)
static void sdhci_cmu_set_clock(struct sdhci_host *host, unsigned int clock)
{
struct sdhci_s3c *ourhost = to_s3c(host);
+ unsigned long timeout;
+ u16 clk = 0;
/* don't bother if the clock is going off */
if (clock == 0)
@@ -282,6 +300,25 @@ static void sdhci_cmu_set_clock(struct sdhci_host *host, unsigned int clock)
clk_set_rate(ourhost->clk_bus[ourhost->cur_clk], clock);
host->clock = clock;
+
+ clk = SDHCI_CLOCK_INT_EN;
+ sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
+
+ /* Wait max 20 ms */
+ timeout = 20;
+ while (!((clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL))
+ & SDHCI_CLOCK_INT_STABLE)) {
+ if (timeout == 0) {
+ printk(KERN_ERR "%s: Internal clock never "
+ "stabilised.\n", mmc_hostname(host->mmc));
+ return;
+ }
+ timeout--;
+ mdelay(1);
+ }
+
+ clk |= SDHCI_CLOCK_CARD_EN;
+ sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
}
/**
@@ -382,16 +419,24 @@ static void sdhci_s3c_setup_card_detect_gpio(struct sdhci_s3c *sc)
}
}
+static inline struct sdhci_s3c_drv_data *sdhci_s3c_get_driver_data(
+ struct platform_device *pdev)
+{
+ return (struct sdhci_s3c_drv_data *)
+ platform_get_device_id(pdev)->driver_data;
+}
+
static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
{
- struct s3c_sdhci_platdata *pdata = pdev->dev.platform_data;
+ struct s3c_sdhci_platdata *pdata;
+ struct sdhci_s3c_drv_data *drv_data;
struct device *dev = &pdev->dev;
struct sdhci_host *host;
struct sdhci_s3c *sc;
struct resource *res;
int ret, irq, ptr, clks;
- if (!pdata) {
+ if (!pdev->dev.platform_data) {
dev_err(dev, "no device data specified\n");
return -ENOENT;
}
@@ -402,18 +447,20 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
return irq;
}
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- dev_err(dev, "no memory specified\n");
- return -ENOENT;
- }
-
host = sdhci_alloc_host(dev, sizeof(struct sdhci_s3c));
if (IS_ERR(host)) {
dev_err(dev, "sdhci_alloc_host() failed\n");
return PTR_ERR(host);
}
+ pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+ if (!pdata) {
+ ret = -ENOMEM;
+ goto err_io_clk;
+ }
+ memcpy(pdata, pdev->dev.platform_data, sizeof(*pdata));
+
+ drv_data = sdhci_s3c_get_driver_data(pdev);
sc = sdhci_priv(host);
sc->host = host;
@@ -464,15 +511,8 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
goto err_no_busclks;
}
- sc->ioarea = request_mem_region(res->start, resource_size(res),
- mmc_hostname(host->mmc));
- if (!sc->ioarea) {
- dev_err(dev, "failed to reserve register area\n");
- ret = -ENXIO;
- goto err_req_regs;
- }
-
- host->ioaddr = ioremap_nocache(res->start, resource_size(res));
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ host->ioaddr = devm_request_and_ioremap(&pdev->dev, res);
if (!host->ioaddr) {
dev_err(dev, "failed to map registers\n");
ret = -ENXIO;
@@ -491,6 +531,8 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
/* Setup quirks for the controller */
host->quirks |= SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC;
host->quirks |= SDHCI_QUIRK_NO_HISPD_BIT;
+ if (drv_data)
+ host->quirks |= drv_data->sdhci_quirks;
#ifndef CONFIG_MMC_SDHCI_S3C_DMA
@@ -518,6 +560,14 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
if (pdata->cd_type == S3C_SDHCI_CD_PERMANENT)
host->mmc->caps = MMC_CAP_NONREMOVABLE;
+ switch (pdata->max_width) {
+ case 8:
+ host->mmc->caps |= MMC_CAP_8_BIT_DATA;
+ case 4:
+ host->mmc->caps |= MMC_CAP_4_BIT_DATA;
+ break;
+ }
+
if (pdata->pm_caps)
host->mmc->pm_caps |= pdata->pm_caps;
@@ -531,7 +581,7 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
* If controller does not have internal clock divider,
* we can use overriding functions instead of default.
*/
- if (pdata->clk_type) {
+ if (host->quirks & SDHCI_QUIRK_NONSTANDARD_CLOCK) {
sdhci_s3c_ops.set_clock = sdhci_cmu_set_clock;
sdhci_s3c_ops.get_min_clock = sdhci_cmu_get_min_clock;
sdhci_s3c_ops.get_max_clock = sdhci_cmu_get_max_clock;
@@ -544,10 +594,17 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
if (pdata->host_caps2)
host->mmc->caps2 |= pdata->host_caps2;
+ pm_runtime_enable(&pdev->dev);
+ pm_runtime_set_autosuspend_delay(&pdev->dev, 50);
+ pm_runtime_use_autosuspend(&pdev->dev);
+ pm_suspend_ignore_children(&pdev->dev, 1);
+
ret = sdhci_add_host(host);
if (ret) {
dev_err(dev, "sdhci_add_host() failed\n");
- goto err_add_host;
+ pm_runtime_forbid(&pdev->dev);
+ pm_runtime_get_noresume(&pdev->dev);
+ goto err_req_regs;
}
/* The following two methods of card detection might call
@@ -561,10 +618,6 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
return 0;
- err_add_host:
- release_resource(sc->ioarea);
- kfree(sc->ioarea);
-
err_req_regs:
for (ptr = 0; ptr < MAX_BUS_CLK; ptr++) {
if (sc->clk_bus[ptr]) {
@@ -601,6 +654,8 @@ static int __devexit sdhci_s3c_remove(struct platform_device *pdev)
sdhci_remove_host(host, 1);
+ pm_runtime_disable(&pdev->dev);
+
for (ptr = 0; ptr < 3; ptr++) {
if (sc->clk_bus[ptr]) {
clk_disable(sc->clk_bus[ptr]);
@@ -610,18 +665,13 @@ static int __devexit sdhci_s3c_remove(struct platform_device *pdev)
clk_disable(sc->clk_io);
clk_put(sc->clk_io);
- iounmap(host->ioaddr);
- release_resource(sc->ioarea);
- kfree(sc->ioarea);
-
sdhci_free_host(host);
platform_set_drvdata(pdev, NULL);
return 0;
}
-#ifdef CONFIG_PM
-
+#ifdef CONFIG_PM_SLEEP
static int sdhci_s3c_suspend(struct device *dev)
{
struct sdhci_host *host = dev_get_drvdata(dev);
@@ -635,10 +685,29 @@ static int sdhci_s3c_resume(struct device *dev)
return sdhci_resume_host(host);
}
+#endif
+
+#ifdef CONFIG_PM_RUNTIME
+static int sdhci_s3c_runtime_suspend(struct device *dev)
+{
+ struct sdhci_host *host = dev_get_drvdata(dev);
+
+ return sdhci_runtime_suspend_host(host);
+}
+static int sdhci_s3c_runtime_resume(struct device *dev)
+{
+ struct sdhci_host *host = dev_get_drvdata(dev);
+
+ return sdhci_runtime_resume_host(host);
+}
+#endif
+
+#ifdef CONFIG_PM
static const struct dev_pm_ops sdhci_s3c_pmops = {
- .suspend = sdhci_s3c_suspend,
- .resume = sdhci_s3c_resume,
+ SET_SYSTEM_SLEEP_PM_OPS(sdhci_s3c_suspend, sdhci_s3c_resume)
+ SET_RUNTIME_PM_OPS(sdhci_s3c_runtime_suspend, sdhci_s3c_runtime_resume,
+ NULL)
};
#define SDHCI_S3C_PMOPS (&sdhci_s3c_pmops)
@@ -647,9 +716,31 @@ static const struct dev_pm_ops sdhci_s3c_pmops = {
#define SDHCI_S3C_PMOPS NULL
#endif
+#if defined(CONFIG_CPU_EXYNOS4210) || defined(CONFIG_SOC_EXYNOS4212)
+static struct sdhci_s3c_drv_data exynos4_sdhci_drv_data = {
+ .sdhci_quirks = SDHCI_QUIRK_NONSTANDARD_CLOCK,
+};
+#define EXYNOS4_SDHCI_DRV_DATA ((kernel_ulong_t)&exynos4_sdhci_drv_data)
+#else
+#define EXYNOS4_SDHCI_DRV_DATA ((kernel_ulong_t)NULL)
+#endif
+
+static struct platform_device_id sdhci_s3c_driver_ids[] = {
+ {
+ .name = "s3c-sdhci",
+ .driver_data = (kernel_ulong_t)NULL,
+ }, {
+ .name = "exynos4-sdhci",
+ .driver_data = EXYNOS4_SDHCI_DRV_DATA,
+ },
+ { }
+};
+MODULE_DEVICE_TABLE(platform, sdhci_s3c_driver_ids);
+
static struct platform_driver sdhci_s3c_driver = {
.probe = sdhci_s3c_probe,
.remove = __devexit_p(sdhci_s3c_remove),
+ .id_table = sdhci_s3c_driver_ids,
.driver = {
.owner = THIS_MODULE,
.name = "s3c-sdhci",
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 8262cadfdab7..ccefdebeff14 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -147,7 +147,7 @@ static void sdhci_set_card_detection(struct sdhci_host *host, bool enable)
u32 present, irqs;
if ((host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION) ||
- !mmc_card_is_removable(host->mmc))
+ (host->mmc->caps & MMC_CAP_NONREMOVABLE))
return;
present = sdhci_readl(host, SDHCI_PRESENT_STATE) &
@@ -2782,8 +2782,9 @@ int sdhci_add_host(struct sdhci_host *host)
mmc_card_is_removable(mmc))
mmc->caps |= MMC_CAP_NEEDS_POLL;
- /* UHS-I mode(s) supported by the host controller. */
- if (host->version >= SDHCI_SPEC_300)
+ /* Any UHS-I mode in caps implies SDR12 and SDR25 support. */
+ if (caps[1] & (SDHCI_SUPPORT_SDR104 | SDHCI_SUPPORT_SDR50 |
+ SDHCI_SUPPORT_DDR50))
mmc->caps |= MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25;
/* SDR104 supports also implies SDR50 support */
diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c
index aafaf0b6eb1c..724b35e85a26 100644
--- a/drivers/mmc/host/sh_mmcif.c
+++ b/drivers/mmc/host/sh_mmcif.c
@@ -454,7 +454,8 @@ static void sh_mmcif_clock_control(struct sh_mmcif_host *host, unsigned int clk)
sh_mmcif_bitset(host, MMCIF_CE_CLK_CTRL, CLK_SUP_PCLK);
else
sh_mmcif_bitset(host, MMCIF_CE_CLK_CTRL, CLK_CLEAR &
- ((fls(host->clk / clk) - 1) << 16));
+ ((fls(DIV_ROUND_UP(host->clk,
+ clk) - 1) - 1) << 16));
sh_mmcif_bitset(host, MMCIF_CE_CLK_CTRL, CLK_ENABLE);
}
@@ -1297,14 +1298,8 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev)
spin_lock_init(&host->lock);
mmc->ops = &sh_mmcif_ops;
- mmc->f_max = host->clk;
- /* close to 400KHz */
- if (mmc->f_max < 51200000)
- mmc->f_min = mmc->f_max / 128;
- else if (mmc->f_max < 102400000)
- mmc->f_min = mmc->f_max / 256;
- else
- mmc->f_min = mmc->f_max / 512;
+ mmc->f_max = host->clk / 2;
+ mmc->f_min = host->clk / 512;
if (pd->ocr)
mmc->ocr_avail = pd->ocr;
mmc->caps = MMC_CAP_MMC_HIGHSPEED;
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index 94eb05b1afdf..58fc65f5c817 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -106,16 +106,14 @@ static int mtdchar_open(struct inode *inode, struct file *file)
}
if (mtd->type == MTD_ABSENT) {
- put_mtd_device(mtd);
ret = -ENODEV;
- goto out;
+ goto out1;
}
mtd_ino = iget_locked(mnt->mnt_sb, devnum);
if (!mtd_ino) {
- put_mtd_device(mtd);
ret = -ENOMEM;
- goto out;
+ goto out1;
}
if (mtd_ino->i_state & I_NEW) {
mtd_ino->i_private = mtd;
@@ -127,23 +125,25 @@ static int mtdchar_open(struct inode *inode, struct file *file)
/* You can't open it RW if it's not a writeable device */
if ((file->f_mode & FMODE_WRITE) && !(mtd->flags & MTD_WRITEABLE)) {
- iput(mtd_ino);
- put_mtd_device(mtd);
ret = -EACCES;
- goto out;
+ goto out2;
}
mfi = kzalloc(sizeof(*mfi), GFP_KERNEL);
if (!mfi) {
- iput(mtd_ino);
- put_mtd_device(mtd);
ret = -ENOMEM;
- goto out;
+ goto out2;
}
mfi->ino = mtd_ino;
mfi->mtd = mtd;
file->private_data = mfi;
+ mutex_unlock(&mtd_mutex);
+ return 0;
+out2:
+ iput(mtd_ino);
+out1:
+ put_mtd_device(mtd);
out:
mutex_unlock(&mtd_mutex);
simple_release_fs(&mnt, &count);
diff --git a/drivers/mtd/ubi/debug.c b/drivers/mtd/ubi/debug.c
index e2cdebf40840..61af9bb560ab 100644
--- a/drivers/mtd/ubi/debug.c
+++ b/drivers/mtd/ubi/debug.c
@@ -386,19 +386,11 @@ out:
return count;
}
-static int default_open(struct inode *inode, struct file *file)
-{
- if (inode->i_private)
- file->private_data = inode->i_private;
-
- return 0;
-}
-
/* File operations for all UBI debugfs files */
static const struct file_operations dfs_fops = {
.read = dfs_file_read,
.write = dfs_file_write,
- .open = default_open,
+ .open = simple_open,
.llseek = no_llseek,
.owner = THIS_MODULE,
};
diff --git a/drivers/net/arcnet/arc-rimi.c b/drivers/net/arcnet/arc-rimi.c
index 25197b698dd6..b8b4c7ba884f 100644
--- a/drivers/net/arcnet/arc-rimi.c
+++ b/drivers/net/arcnet/arc-rimi.c
@@ -89,16 +89,16 @@ static int __init arcrimi_probe(struct net_device *dev)
BUGLVL(D_NORMAL) printk(VERSION);
BUGLVL(D_NORMAL) printk("E-mail me if you actually test the RIM I driver, please!\n");
- BUGMSG(D_NORMAL, "Given: node %02Xh, shmem %lXh, irq %d\n",
+ BUGLVL(D_NORMAL) printk("Given: node %02Xh, shmem %lXh, irq %d\n",
dev->dev_addr[0], dev->mem_start, dev->irq);
if (dev->mem_start <= 0 || dev->irq <= 0) {
- BUGMSG(D_NORMAL, "No autoprobe for RIM I; you "
+ BUGLVL(D_NORMAL) printk("No autoprobe for RIM I; you "
"must specify the shmem and irq!\n");
return -ENODEV;
}
if (dev->dev_addr[0] == 0) {
- BUGMSG(D_NORMAL, "You need to specify your card's station "
+ BUGLVL(D_NORMAL) printk("You need to specify your card's station "
"ID!\n");
return -ENODEV;
}
@@ -109,7 +109,7 @@ static int __init arcrimi_probe(struct net_device *dev)
* will be taken.
*/
if (!request_mem_region(dev->mem_start, MIRROR_SIZE, "arcnet (90xx)")) {
- BUGMSG(D_NORMAL, "Card memory already allocated\n");
+ BUGLVL(D_NORMAL) printk("Card memory already allocated\n");
return -ENODEV;
}
return arcrimi_found(dev);
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 941b4e189adf..62d2409bb293 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -2034,6 +2034,9 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
write_unlock_bh(&bond->lock);
unblock_netpoll_tx();
+ if (bond->slave_cnt == 0)
+ call_netdevice_notifiers(NETDEV_CHANGEADDR, bond->dev);
+
bond_compute_features(bond);
if (!(bond_dev->features & NETIF_F_VLAN_CHALLENGED) &&
(old_features & NETIF_F_VLAN_CHALLENGED))
@@ -3007,7 +3010,11 @@ static void bond_ab_arp_commit(struct bonding *bond, int delta_in_ticks)
trans_start + delta_in_ticks)) ||
bond->curr_active_slave != slave) {
slave->link = BOND_LINK_UP;
- bond->current_arp_slave = NULL;
+ if (bond->current_arp_slave) {
+ bond_set_slave_inactive_flags(
+ bond->current_arp_slave);
+ bond->current_arp_slave = NULL;
+ }
pr_info("%s: link status definitely up for interface %s.\n",
bond->dev->name, slave->dev->name);
@@ -3701,17 +3708,52 @@ static void bond_set_multicast_list(struct net_device *bond_dev)
read_unlock(&bond->lock);
}
-static int bond_neigh_setup(struct net_device *dev, struct neigh_parms *parms)
+static int bond_neigh_init(struct neighbour *n)
{
- struct bonding *bond = netdev_priv(dev);
+ struct bonding *bond = netdev_priv(n->dev);
struct slave *slave = bond->first_slave;
+ const struct net_device_ops *slave_ops;
+ struct neigh_parms parms;
+ int ret;
+
+ if (!slave)
+ return 0;
+
+ slave_ops = slave->dev->netdev_ops;
+
+ if (!slave_ops->ndo_neigh_setup)
+ return 0;
+
+ parms.neigh_setup = NULL;
+ parms.neigh_cleanup = NULL;
+ ret = slave_ops->ndo_neigh_setup(slave->dev, &parms);
+ if (ret)
+ return ret;
+
+ /*
+ * Assign slave's neigh_cleanup to neighbour in case cleanup is called
+ * after the last slave has been detached. Assumes that all slaves
+ * utilize the same neigh_cleanup (true at this writing as only user
+ * is ipoib).
+ */
+ n->parms->neigh_cleanup = parms.neigh_cleanup;
+
+ if (!parms.neigh_setup)
+ return 0;
+
+ return parms.neigh_setup(n);
+}
+
+/*
+ * The bonding ndo_neigh_setup is called at init time beofre any
+ * slave exists. So we must declare proxy setup function which will
+ * be used at run time to resolve the actual slave neigh param setup.
+ */
+static int bond_neigh_setup(struct net_device *dev,
+ struct neigh_parms *parms)
+{
+ parms->neigh_setup = bond_neigh_init;
- if (slave) {
- const struct net_device_ops *slave_ops
- = slave->dev->netdev_ops;
- if (slave_ops->ndo_neigh_setup)
- return slave_ops->ndo_neigh_setup(slave->dev, parms);
- }
return 0;
}
diff --git a/drivers/net/caif/caif_hsi.c b/drivers/net/caif/caif_hsi.c
index 9a66e2a910ae..9c1c8cd5223f 100644
--- a/drivers/net/caif/caif_hsi.c
+++ b/drivers/net/caif/caif_hsi.c
@@ -744,14 +744,14 @@ static void cfhsi_wake_up(struct work_struct *work)
size_t fifo_occupancy = 0;
/* Wakeup timeout */
- dev_err(&cfhsi->ndev->dev, "%s: Timeout.\n",
+ dev_dbg(&cfhsi->ndev->dev, "%s: Timeout.\n",
__func__);
/* Check FIFO to check if modem has sent something. */
WARN_ON(cfhsi->dev->cfhsi_fifo_occupancy(cfhsi->dev,
&fifo_occupancy));
- dev_err(&cfhsi->ndev->dev, "%s: Bytes in FIFO: %u.\n",
+ dev_dbg(&cfhsi->ndev->dev, "%s: Bytes in FIFO: %u.\n",
__func__, (unsigned) fifo_occupancy);
/* Check if we misssed the interrupt. */
@@ -1210,7 +1210,7 @@ int cfhsi_probe(struct platform_device *pdev)
static void cfhsi_shutdown(struct cfhsi *cfhsi)
{
- u8 *tx_buf, *rx_buf;
+ u8 *tx_buf, *rx_buf, *flip_buf;
/* Stop TXing */
netif_tx_stop_all_queues(cfhsi->ndev);
@@ -1234,7 +1234,7 @@ static void cfhsi_shutdown(struct cfhsi *cfhsi)
/* Store bufferes: will be freed later. */
tx_buf = cfhsi->tx_buf;
rx_buf = cfhsi->rx_buf;
-
+ flip_buf = cfhsi->rx_flip_buf;
/* Flush transmit queues. */
cfhsi_abort_tx(cfhsi);
@@ -1247,6 +1247,7 @@ static void cfhsi_shutdown(struct cfhsi *cfhsi)
/* Free buffers. */
kfree(tx_buf);
kfree(rx_buf);
+ kfree(flip_buf);
}
int cfhsi_remove(struct platform_device *pdev)
diff --git a/drivers/net/caif/caif_spi.c b/drivers/net/caif/caif_spi.c
index 96391c36fa74..b71ce9bf0afb 100644
--- a/drivers/net/caif/caif_spi.c
+++ b/drivers/net/caif/caif_spi.c
@@ -127,12 +127,6 @@ static inline void dev_debugfs_rem(struct cfspi *cfspi)
debugfs_remove(cfspi->dbgfs_dir);
}
-static int dbgfs_open(struct inode *inode, struct file *file)
-{
- file->private_data = inode->i_private;
- return 0;
-}
-
static ssize_t dbgfs_state(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
@@ -243,13 +237,13 @@ static ssize_t dbgfs_frame(struct file *file, char __user *user_buf,
}
static const struct file_operations dbgfs_state_fops = {
- .open = dbgfs_open,
+ .open = simple_open,
.read = dbgfs_state,
.owner = THIS_MODULE
};
static const struct file_operations dbgfs_frame_fops = {
- .open = dbgfs_open,
+ .open = simple_open,
.read = dbgfs_frame,
.owner = THIS_MODULE
};
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
index 5234586dff15..629c4ba5d49d 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
@@ -875,6 +875,7 @@ static int pcan_usb_pro_init(struct peak_usb_device *dev)
PCAN_USBPRO_INFO_FW,
&fi, sizeof(fi));
if (err) {
+ kfree(usb_if);
dev_err(dev->netdev->dev.parent,
"unable to read %s firmware info (err %d)\n",
pcan_usb_pro.name, err);
@@ -885,6 +886,7 @@ static int pcan_usb_pro_init(struct peak_usb_device *dev)
PCAN_USBPRO_INFO_BL,
&bi, sizeof(bi));
if (err) {
+ kfree(usb_if);
dev_err(dev->netdev->dev.parent,
"unable to read %s bootloader info (err %d)\n",
pcan_usb_pro.name, err);
diff --git a/drivers/net/dummy.c b/drivers/net/dummy.c
index d5c6d92f1ee7..442d91a2747b 100644
--- a/drivers/net/dummy.c
+++ b/drivers/net/dummy.c
@@ -107,14 +107,14 @@ static int dummy_dev_init(struct net_device *dev)
return 0;
}
-static void dummy_dev_free(struct net_device *dev)
+static void dummy_dev_uninit(struct net_device *dev)
{
free_percpu(dev->dstats);
- free_netdev(dev);
}
static const struct net_device_ops dummy_netdev_ops = {
.ndo_init = dummy_dev_init,
+ .ndo_uninit = dummy_dev_uninit,
.ndo_start_xmit = dummy_xmit,
.ndo_validate_addr = eth_validate_addr,
.ndo_set_rx_mode = set_multicast_list,
@@ -128,7 +128,7 @@ static void dummy_setup(struct net_device *dev)
/* Initialize the device structure. */
dev->netdev_ops = &dummy_netdev_ops;
- dev->destructor = dummy_dev_free;
+ dev->destructor = free_netdev;
/* Fill in device structure with ethernet-generic values. */
dev->tx_queue_len = 0;
diff --git a/drivers/net/ethernet/atheros/atlx/atl1.c b/drivers/net/ethernet/atheros/atlx/atl1.c
index 40ac41436549..c926857e8205 100644
--- a/drivers/net/ethernet/atheros/atlx/atl1.c
+++ b/drivers/net/ethernet/atheros/atlx/atl1.c
@@ -2476,7 +2476,7 @@ static irqreturn_t atl1_intr(int irq, void *data)
"pcie phy link down %x\n", status);
if (netif_running(adapter->netdev)) { /* reset MAC */
iowrite32(0, adapter->hw.hw_addr + REG_IMR);
- schedule_work(&adapter->pcie_dma_to_rst_task);
+ schedule_work(&adapter->reset_dev_task);
return IRQ_HANDLED;
}
}
@@ -2488,7 +2488,7 @@ static irqreturn_t atl1_intr(int irq, void *data)
"pcie DMA r/w error (status = 0x%x)\n",
status);
iowrite32(0, adapter->hw.hw_addr + REG_IMR);
- schedule_work(&adapter->pcie_dma_to_rst_task);
+ schedule_work(&adapter->reset_dev_task);
return IRQ_HANDLED;
}
@@ -2633,10 +2633,10 @@ static void atl1_down(struct atl1_adapter *adapter)
atl1_clean_rx_ring(adapter);
}
-static void atl1_tx_timeout_task(struct work_struct *work)
+static void atl1_reset_dev_task(struct work_struct *work)
{
struct atl1_adapter *adapter =
- container_of(work, struct atl1_adapter, tx_timeout_task);
+ container_of(work, struct atl1_adapter, reset_dev_task);
struct net_device *netdev = adapter->netdev;
netif_device_detach(netdev);
@@ -3038,12 +3038,10 @@ static int __devinit atl1_probe(struct pci_dev *pdev,
(unsigned long)adapter);
adapter->phy_timer_pending = false;
- INIT_WORK(&adapter->tx_timeout_task, atl1_tx_timeout_task);
+ INIT_WORK(&adapter->reset_dev_task, atl1_reset_dev_task);
INIT_WORK(&adapter->link_chg_task, atlx_link_chg_task);
- INIT_WORK(&adapter->pcie_dma_to_rst_task, atl1_tx_timeout_task);
-
err = register_netdev(netdev);
if (err)
goto err_common;
diff --git a/drivers/net/ethernet/atheros/atlx/atl1.h b/drivers/net/ethernet/atheros/atlx/atl1.h
index 109d6da8be97..e04bf4d71e46 100644
--- a/drivers/net/ethernet/atheros/atlx/atl1.h
+++ b/drivers/net/ethernet/atheros/atlx/atl1.h
@@ -758,9 +758,8 @@ struct atl1_adapter {
u16 link_speed;
u16 link_duplex;
spinlock_t lock;
- struct work_struct tx_timeout_task;
+ struct work_struct reset_dev_task;
struct work_struct link_chg_task;
- struct work_struct pcie_dma_to_rst_task;
struct timer_list phy_config_timer;
bool phy_timer_pending;
diff --git a/drivers/net/ethernet/atheros/atlx/atlx.c b/drivers/net/ethernet/atheros/atlx/atlx.c
index 3cd8837236dc..c9e9dc57986c 100644
--- a/drivers/net/ethernet/atheros/atlx/atlx.c
+++ b/drivers/net/ethernet/atheros/atlx/atlx.c
@@ -194,7 +194,7 @@ static void atlx_tx_timeout(struct net_device *netdev)
{
struct atlx_adapter *adapter = netdev_priv(netdev);
/* Do the reset outside of interrupt context */
- schedule_work(&adapter->tx_timeout_task);
+ schedule_work(&adapter->reset_dev_task);
}
/*
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
index 44556b719e81..4b054812713a 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
@@ -1874,7 +1874,6 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
* bnx2x_periodic_task().
*/
smp_mb();
- queue_delayed_work(bnx2x_wq, &bp->period_task, 0);
} else
bp->port.pmf = 0;
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_fw_defs.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_fw_defs.h
index cd6dfa9eaa3a..b9b263323436 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_fw_defs.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_fw_defs.h
@@ -25,31 +25,31 @@
(IRO[149].base + ((funcId) * IRO[149].m1))
#define CSTORM_IGU_MODE_OFFSET (IRO[157].base)
#define CSTORM_ISCSI_CQ_SIZE_OFFSET(pfId) \
- (IRO[315].base + ((pfId) * IRO[315].m1))
-#define CSTORM_ISCSI_CQ_SQN_SIZE_OFFSET(pfId) \
(IRO[316].base + ((pfId) * IRO[316].m1))
+#define CSTORM_ISCSI_CQ_SQN_SIZE_OFFSET(pfId) \
+ (IRO[317].base + ((pfId) * IRO[317].m1))
#define CSTORM_ISCSI_EQ_CONS_OFFSET(pfId, iscsiEqId) \
- (IRO[308].base + ((pfId) * IRO[308].m1) + ((iscsiEqId) * IRO[308].m2))
+ (IRO[309].base + ((pfId) * IRO[309].m1) + ((iscsiEqId) * IRO[309].m2))
#define CSTORM_ISCSI_EQ_NEXT_EQE_ADDR_OFFSET(pfId, iscsiEqId) \
- (IRO[310].base + ((pfId) * IRO[310].m1) + ((iscsiEqId) * IRO[310].m2))
+ (IRO[311].base + ((pfId) * IRO[311].m1) + ((iscsiEqId) * IRO[311].m2))
#define CSTORM_ISCSI_EQ_NEXT_PAGE_ADDR_OFFSET(pfId, iscsiEqId) \
- (IRO[309].base + ((pfId) * IRO[309].m1) + ((iscsiEqId) * IRO[309].m2))
+ (IRO[310].base + ((pfId) * IRO[310].m1) + ((iscsiEqId) * IRO[310].m2))
#define CSTORM_ISCSI_EQ_NEXT_PAGE_ADDR_VALID_OFFSET(pfId, iscsiEqId) \
- (IRO[311].base + ((pfId) * IRO[311].m1) + ((iscsiEqId) * IRO[311].m2))
+ (IRO[312].base + ((pfId) * IRO[312].m1) + ((iscsiEqId) * IRO[312].m2))
#define CSTORM_ISCSI_EQ_PROD_OFFSET(pfId, iscsiEqId) \
- (IRO[307].base + ((pfId) * IRO[307].m1) + ((iscsiEqId) * IRO[307].m2))
+ (IRO[308].base + ((pfId) * IRO[308].m1) + ((iscsiEqId) * IRO[308].m2))
#define CSTORM_ISCSI_EQ_SB_INDEX_OFFSET(pfId, iscsiEqId) \
- (IRO[313].base + ((pfId) * IRO[313].m1) + ((iscsiEqId) * IRO[313].m2))
+ (IRO[314].base + ((pfId) * IRO[314].m1) + ((iscsiEqId) * IRO[314].m2))
#define CSTORM_ISCSI_EQ_SB_NUM_OFFSET(pfId, iscsiEqId) \
- (IRO[312].base + ((pfId) * IRO[312].m1) + ((iscsiEqId) * IRO[312].m2))
+ (IRO[313].base + ((pfId) * IRO[313].m1) + ((iscsiEqId) * IRO[313].m2))
#define CSTORM_ISCSI_HQ_SIZE_OFFSET(pfId) \
- (IRO[314].base + ((pfId) * IRO[314].m1))
+ (IRO[315].base + ((pfId) * IRO[315].m1))
#define CSTORM_ISCSI_NUM_OF_TASKS_OFFSET(pfId) \
- (IRO[306].base + ((pfId) * IRO[306].m1))
+ (IRO[307].base + ((pfId) * IRO[307].m1))
#define CSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(pfId) \
- (IRO[305].base + ((pfId) * IRO[305].m1))
+ (IRO[306].base + ((pfId) * IRO[306].m1))
#define CSTORM_ISCSI_PAGE_SIZE_OFFSET(pfId) \
- (IRO[304].base + ((pfId) * IRO[304].m1))
+ (IRO[305].base + ((pfId) * IRO[305].m1))
#define CSTORM_RECORD_SLOW_PATH_OFFSET(funcId) \
(IRO[151].base + ((funcId) * IRO[151].m1))
#define CSTORM_SP_STATUS_BLOCK_DATA_OFFSET(pfId) \
@@ -96,37 +96,37 @@
#define TSTORM_FUNC_EN_OFFSET(funcId) \
(IRO[103].base + ((funcId) * IRO[103].m1))
#define TSTORM_ISCSI_ERROR_BITMAP_OFFSET(pfId) \
- (IRO[271].base + ((pfId) * IRO[271].m1))
-#define TSTORM_ISCSI_L2_ISCSI_OOO_CID_TABLE_OFFSET(pfId) \
(IRO[272].base + ((pfId) * IRO[272].m1))
-#define TSTORM_ISCSI_L2_ISCSI_OOO_CLIENT_ID_TABLE_OFFSET(pfId) \
+#define TSTORM_ISCSI_L2_ISCSI_OOO_CID_TABLE_OFFSET(pfId) \
(IRO[273].base + ((pfId) * IRO[273].m1))
-#define TSTORM_ISCSI_L2_ISCSI_OOO_PROD_OFFSET(pfId) \
+#define TSTORM_ISCSI_L2_ISCSI_OOO_CLIENT_ID_TABLE_OFFSET(pfId) \
(IRO[274].base + ((pfId) * IRO[274].m1))
+#define TSTORM_ISCSI_L2_ISCSI_OOO_PROD_OFFSET(pfId) \
+ (IRO[275].base + ((pfId) * IRO[275].m1))
#define TSTORM_ISCSI_NUM_OF_TASKS_OFFSET(pfId) \
- (IRO[270].base + ((pfId) * IRO[270].m1))
+ (IRO[271].base + ((pfId) * IRO[271].m1))
#define TSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(pfId) \
- (IRO[269].base + ((pfId) * IRO[269].m1))
+ (IRO[270].base + ((pfId) * IRO[270].m1))
#define TSTORM_ISCSI_PAGE_SIZE_OFFSET(pfId) \
- (IRO[268].base + ((pfId) * IRO[268].m1))
+ (IRO[269].base + ((pfId) * IRO[269].m1))
#define TSTORM_ISCSI_RQ_SIZE_OFFSET(pfId) \
- (IRO[267].base + ((pfId) * IRO[267].m1))
+ (IRO[268].base + ((pfId) * IRO[268].m1))
#define TSTORM_ISCSI_TCP_LOCAL_ADV_WND_OFFSET(pfId) \
- (IRO[276].base + ((pfId) * IRO[276].m1))
+ (IRO[277].base + ((pfId) * IRO[277].m1))
#define TSTORM_ISCSI_TCP_VARS_FLAGS_OFFSET(pfId) \
- (IRO[263].base + ((pfId) * IRO[263].m1))
-#define TSTORM_ISCSI_TCP_VARS_LSB_LOCAL_MAC_ADDR_OFFSET(pfId) \
(IRO[264].base + ((pfId) * IRO[264].m1))
-#define TSTORM_ISCSI_TCP_VARS_MID_LOCAL_MAC_ADDR_OFFSET(pfId) \
+#define TSTORM_ISCSI_TCP_VARS_LSB_LOCAL_MAC_ADDR_OFFSET(pfId) \
(IRO[265].base + ((pfId) * IRO[265].m1))
-#define TSTORM_ISCSI_TCP_VARS_MSB_LOCAL_MAC_ADDR_OFFSET(pfId) \
+#define TSTORM_ISCSI_TCP_VARS_MID_LOCAL_MAC_ADDR_OFFSET(pfId) \
(IRO[266].base + ((pfId) * IRO[266].m1))
+#define TSTORM_ISCSI_TCP_VARS_MSB_LOCAL_MAC_ADDR_OFFSET(pfId) \
+ (IRO[267].base + ((pfId) * IRO[267].m1))
#define TSTORM_MAC_FILTER_CONFIG_OFFSET(pfId) \
(IRO[202].base + ((pfId) * IRO[202].m1))
#define TSTORM_RECORD_SLOW_PATH_OFFSET(funcId) \
(IRO[105].base + ((funcId) * IRO[105].m1))
#define TSTORM_TCP_MAX_CWND_OFFSET(pfId) \
- (IRO[216].base + ((pfId) * IRO[216].m1))
+ (IRO[217].base + ((pfId) * IRO[217].m1))
#define TSTORM_VF_TO_PF_OFFSET(funcId) \
(IRO[104].base + ((funcId) * IRO[104].m1))
#define USTORM_AGG_DATA_OFFSET (IRO[206].base)
@@ -140,29 +140,29 @@
#define USTORM_ETH_PAUSE_ENABLED_OFFSET(portId) \
(IRO[183].base + ((portId) * IRO[183].m1))
#define USTORM_FCOE_EQ_PROD_OFFSET(pfId) \
- (IRO[317].base + ((pfId) * IRO[317].m1))
+ (IRO[318].base + ((pfId) * IRO[318].m1))
#define USTORM_FUNC_EN_OFFSET(funcId) \
(IRO[178].base + ((funcId) * IRO[178].m1))
#define USTORM_ISCSI_CQ_SIZE_OFFSET(pfId) \
- (IRO[281].base + ((pfId) * IRO[281].m1))
-#define USTORM_ISCSI_CQ_SQN_SIZE_OFFSET(pfId) \
(IRO[282].base + ((pfId) * IRO[282].m1))
+#define USTORM_ISCSI_CQ_SQN_SIZE_OFFSET(pfId) \
+ (IRO[283].base + ((pfId) * IRO[283].m1))
#define USTORM_ISCSI_ERROR_BITMAP_OFFSET(pfId) \
- (IRO[286].base + ((pfId) * IRO[286].m1))
+ (IRO[287].base + ((pfId) * IRO[287].m1))
#define USTORM_ISCSI_GLOBAL_BUF_PHYS_ADDR_OFFSET(pfId) \
- (IRO[283].base + ((pfId) * IRO[283].m1))
+ (IRO[284].base + ((pfId) * IRO[284].m1))
#define USTORM_ISCSI_NUM_OF_TASKS_OFFSET(pfId) \
- (IRO[279].base + ((pfId) * IRO[279].m1))
+ (IRO[280].base + ((pfId) * IRO[280].m1))
#define USTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(pfId) \
- (IRO[278].base + ((pfId) * IRO[278].m1))
+ (IRO[279].base + ((pfId) * IRO[279].m1))
#define USTORM_ISCSI_PAGE_SIZE_OFFSET(pfId) \
- (IRO[277].base + ((pfId) * IRO[277].m1))
+ (IRO[278].base + ((pfId) * IRO[278].m1))
#define USTORM_ISCSI_R2TQ_SIZE_OFFSET(pfId) \
- (IRO[280].base + ((pfId) * IRO[280].m1))
+ (IRO[281].base + ((pfId) * IRO[281].m1))
#define USTORM_ISCSI_RQ_BUFFER_SIZE_OFFSET(pfId) \
- (IRO[284].base + ((pfId) * IRO[284].m1))
-#define USTORM_ISCSI_RQ_SIZE_OFFSET(pfId) \
(IRO[285].base + ((pfId) * IRO[285].m1))
+#define USTORM_ISCSI_RQ_SIZE_OFFSET(pfId) \
+ (IRO[286].base + ((pfId) * IRO[286].m1))
#define USTORM_MEM_WORKAROUND_ADDRESS_OFFSET(pfId) \
(IRO[182].base + ((pfId) * IRO[182].m1))
#define USTORM_RECORD_SLOW_PATH_OFFSET(funcId) \
@@ -188,39 +188,39 @@
#define XSTORM_FUNC_EN_OFFSET(funcId) \
(IRO[47].base + ((funcId) * IRO[47].m1))
#define XSTORM_ISCSI_HQ_SIZE_OFFSET(pfId) \
- (IRO[294].base + ((pfId) * IRO[294].m1))
+ (IRO[295].base + ((pfId) * IRO[295].m1))
#define XSTORM_ISCSI_LOCAL_MAC_ADDR0_OFFSET(pfId) \
- (IRO[297].base + ((pfId) * IRO[297].m1))
-#define XSTORM_ISCSI_LOCAL_MAC_ADDR1_OFFSET(pfId) \
(IRO[298].base + ((pfId) * IRO[298].m1))
-#define XSTORM_ISCSI_LOCAL_MAC_ADDR2_OFFSET(pfId) \
+#define XSTORM_ISCSI_LOCAL_MAC_ADDR1_OFFSET(pfId) \
(IRO[299].base + ((pfId) * IRO[299].m1))
-#define XSTORM_ISCSI_LOCAL_MAC_ADDR3_OFFSET(pfId) \
+#define XSTORM_ISCSI_LOCAL_MAC_ADDR2_OFFSET(pfId) \
(IRO[300].base + ((pfId) * IRO[300].m1))
-#define XSTORM_ISCSI_LOCAL_MAC_ADDR4_OFFSET(pfId) \
+#define XSTORM_ISCSI_LOCAL_MAC_ADDR3_OFFSET(pfId) \
(IRO[301].base + ((pfId) * IRO[301].m1))
-#define XSTORM_ISCSI_LOCAL_MAC_ADDR5_OFFSET(pfId) \
+#define XSTORM_ISCSI_LOCAL_MAC_ADDR4_OFFSET(pfId) \
(IRO[302].base + ((pfId) * IRO[302].m1))
-#define XSTORM_ISCSI_LOCAL_VLAN_OFFSET(pfId) \
+#define XSTORM_ISCSI_LOCAL_MAC_ADDR5_OFFSET(pfId) \
(IRO[303].base + ((pfId) * IRO[303].m1))
+#define XSTORM_ISCSI_LOCAL_VLAN_OFFSET(pfId) \
+ (IRO[304].base + ((pfId) * IRO[304].m1))
#define XSTORM_ISCSI_NUM_OF_TASKS_OFFSET(pfId) \
- (IRO[293].base + ((pfId) * IRO[293].m1))
+ (IRO[294].base + ((pfId) * IRO[294].m1))
#define XSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(pfId) \
- (IRO[292].base + ((pfId) * IRO[292].m1))
+ (IRO[293].base + ((pfId) * IRO[293].m1))
#define XSTORM_ISCSI_PAGE_SIZE_OFFSET(pfId) \
- (IRO[291].base + ((pfId) * IRO[291].m1))
+ (IRO[292].base + ((pfId) * IRO[292].m1))
#define XSTORM_ISCSI_R2TQ_SIZE_OFFSET(pfId) \
- (IRO[296].base + ((pfId) * IRO[296].m1))
+ (IRO[297].base + ((pfId) * IRO[297].m1))
#define XSTORM_ISCSI_SQ_SIZE_OFFSET(pfId) \
- (IRO[295].base + ((pfId) * IRO[295].m1))
+ (IRO[296].base + ((pfId) * IRO[296].m1))
#define XSTORM_ISCSI_TCP_VARS_ADV_WND_SCL_OFFSET(pfId) \
- (IRO[290].base + ((pfId) * IRO[290].m1))
+ (IRO[291].base + ((pfId) * IRO[291].m1))
#define XSTORM_ISCSI_TCP_VARS_FLAGS_OFFSET(pfId) \
- (IRO[289].base + ((pfId) * IRO[289].m1))
+ (IRO[290].base + ((pfId) * IRO[290].m1))
#define XSTORM_ISCSI_TCP_VARS_TOS_OFFSET(pfId) \
- (IRO[288].base + ((pfId) * IRO[288].m1))
+ (IRO[289].base + ((pfId) * IRO[289].m1))
#define XSTORM_ISCSI_TCP_VARS_TTL_OFFSET(pfId) \
- (IRO[287].base + ((pfId) * IRO[287].m1))
+ (IRO[288].base + ((pfId) * IRO[288].m1))
#define XSTORM_RATE_SHAPING_PER_VN_VARS_OFFSET(pfId) \
(IRO[44].base + ((pfId) * IRO[44].m1))
#define XSTORM_RECORD_SLOW_PATH_OFFSET(funcId) \
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
index efa557b76ac7..64392ec410a3 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
@@ -942,6 +942,12 @@ static int bnx2x_ets_e3b0_sp_pri_to_cos_set(const struct link_params *params,
const u8 max_num_of_cos = (port) ? DCBX_E3B0_MAX_NUM_COS_PORT1 :
DCBX_E3B0_MAX_NUM_COS_PORT0;
+ if (pri >= max_num_of_cos) {
+ DP(NETIF_MSG_LINK, "bnx2x_ets_e3b0_sp_pri_to_cos_set invalid "
+ "parameter Illegal strict priority\n");
+ return -EINVAL;
+ }
+
if (sp_pri_to_cos[pri] != DCBX_INVALID_COS) {
DP(NETIF_MSG_LINK, "bnx2x_ets_e3b0_sp_pri_to_cos_set invalid "
"parameter There can't be two COS's with "
@@ -949,12 +955,6 @@ static int bnx2x_ets_e3b0_sp_pri_to_cos_set(const struct link_params *params,
return -EINVAL;
}
- if (pri > max_num_of_cos) {
- DP(NETIF_MSG_LINK, "bnx2x_ets_e3b0_sp_pri_to_cos_set invalid "
- "parameter Illegal strict priority\n");
- return -EINVAL;
- }
-
sp_pri_to_cos[pri] = cos_entry;
return 0;
@@ -1371,7 +1371,14 @@ static void bnx2x_update_pfc_xmac(struct link_params *params,
pfc1_val |= XMAC_PFC_CTRL_HI_REG_PFC_REFRESH_EN |
XMAC_PFC_CTRL_HI_REG_PFC_STATS_EN |
XMAC_PFC_CTRL_HI_REG_RX_PFC_EN |
- XMAC_PFC_CTRL_HI_REG_TX_PFC_EN;
+ XMAC_PFC_CTRL_HI_REG_TX_PFC_EN |
+ XMAC_PFC_CTRL_HI_REG_FORCE_PFC_XON;
+ /* Write pause and PFC registers */
+ REG_WR(bp, xmac_base + XMAC_REG_PAUSE_CTRL, pause_val);
+ REG_WR(bp, xmac_base + XMAC_REG_PFC_CTRL, pfc0_val);
+ REG_WR(bp, xmac_base + XMAC_REG_PFC_CTRL_HI, pfc1_val);
+ pfc1_val &= ~XMAC_PFC_CTRL_HI_REG_FORCE_PFC_XON;
+
}
/* Write pause and PFC registers */
@@ -3648,6 +3655,33 @@ static void bnx2x_ext_phy_update_adv_fc(struct bnx2x_phy *phy,
if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE) {
bnx2x_cl22_read(bp, phy, 0x4, &ld_pause);
bnx2x_cl22_read(bp, phy, 0x5, &lp_pause);
+ } else if (CHIP_IS_E3(bp) &&
+ SINGLE_MEDIA_DIRECT(params)) {
+ u8 lane = bnx2x_get_warpcore_lane(phy, params);
+ u16 gp_status, gp_mask;
+ bnx2x_cl45_read(bp, phy,
+ MDIO_AN_DEVAD, MDIO_WC_REG_GP2_STATUS_GP_2_4,
+ &gp_status);
+ gp_mask = (MDIO_WC_REG_GP2_STATUS_GP_2_4_CL73_AN_CMPL |
+ MDIO_WC_REG_GP2_STATUS_GP_2_4_CL37_LP_AN_CAP) <<
+ lane;
+ if ((gp_status & gp_mask) == gp_mask) {
+ bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD,
+ MDIO_AN_REG_ADV_PAUSE, &ld_pause);
+ bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD,
+ MDIO_AN_REG_LP_AUTO_NEG, &lp_pause);
+ } else {
+ bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD,
+ MDIO_AN_REG_CL37_FC_LD, &ld_pause);
+ bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD,
+ MDIO_AN_REG_CL37_FC_LP, &lp_pause);
+ ld_pause = ((ld_pause &
+ MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH)
+ << 3);
+ lp_pause = ((lp_pause &
+ MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH)
+ << 3);
+ }
} else {
bnx2x_cl45_read(bp, phy,
MDIO_AN_DEVAD,
@@ -3698,7 +3732,23 @@ static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy,
u16 val16 = 0, lane, bam37 = 0;
struct bnx2x *bp = params->bp;
DP(NETIF_MSG_LINK, "Enable Auto Negotiation for KR\n");
-
+ /* Set to default registers that may be overriden by 10G force */
+ bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
+ MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, 0x7);
+ bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
+ MDIO_WC_REG_PAR_DET_10G_CTRL, 0);
+ bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
+ MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, 0);
+ bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
+ MDIO_WC_REG_XGXSBLK1_LANECTRL0, 0xff);
+ bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
+ MDIO_WC_REG_XGXSBLK1_LANECTRL1, 0x5555);
+ bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD,
+ MDIO_WC_REG_IEEE0BLK_AUTONEGNP, 0x0);
+ bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
+ MDIO_WC_REG_RX66_CONTROL, 0x7415);
+ bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
+ MDIO_WC_REG_SERDESDIGITAL_MISC2, 0x6190);
/* Disable Autoneg: re-enable it after adv is done. */
bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
MDIO_WC_REG_IEEE0BLK_MIICNTL, 0);
@@ -3944,13 +3994,13 @@ static void bnx2x_warpcore_set_10G_XFI(struct bnx2x_phy *phy,
} else {
misc1_val |= 0x9;
- tap_val = ((0x12 << MDIO_WC_REG_TX_FIR_TAP_POST_TAP_OFFSET) |
- (0x2d << MDIO_WC_REG_TX_FIR_TAP_MAIN_TAP_OFFSET) |
- (0x00 << MDIO_WC_REG_TX_FIR_TAP_PRE_TAP_OFFSET));
+ tap_val = ((0x0f << MDIO_WC_REG_TX_FIR_TAP_POST_TAP_OFFSET) |
+ (0x2b << MDIO_WC_REG_TX_FIR_TAP_MAIN_TAP_OFFSET) |
+ (0x02 << MDIO_WC_REG_TX_FIR_TAP_PRE_TAP_OFFSET));
tx_driver_val =
- ((0x02 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) |
+ ((0x03 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) |
(0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) |
- (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET));
+ (0x06 << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET));
}
bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
MDIO_WC_REG_SERDESDIGITAL_MISC1, misc1_val);
@@ -4368,7 +4418,7 @@ static void bnx2x_warpcore_config_init(struct bnx2x_phy *phy,
switch (serdes_net_if) {
case PORT_HW_CFG_NET_SERDES_IF_KR:
/* Enable KR Auto Neg */
- if (params->loopback_mode == LOOPBACK_NONE)
+ if (params->loopback_mode != LOOPBACK_EXT)
bnx2x_warpcore_enable_AN_KR(phy, params, vars);
else {
DP(NETIF_MSG_LINK, "Setting KR 10G-Force\n");
@@ -6166,12 +6216,14 @@ int bnx2x_set_led(struct link_params *params,
tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
if (params->phy[EXT_PHY1].type ==
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE)
- EMAC_WR(bp, EMAC_REG_EMAC_LED, tmp & 0xfff1);
- else {
- EMAC_WR(bp, EMAC_REG_EMAC_LED,
- (tmp | EMAC_LED_OVERRIDE));
- }
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE)
+ tmp &= ~(EMAC_LED_1000MB_OVERRIDE |
+ EMAC_LED_100MB_OVERRIDE |
+ EMAC_LED_10MB_OVERRIDE);
+ else
+ tmp |= EMAC_LED_OVERRIDE;
+
+ EMAC_WR(bp, EMAC_REG_EMAC_LED, tmp);
break;
case LED_MODE_OPER:
@@ -6226,10 +6278,15 @@ int bnx2x_set_led(struct link_params *params,
hw_led_mode);
} else if ((params->phy[EXT_PHY1].type ==
PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE) &&
- (mode != LED_MODE_OPER)) {
+ (mode == LED_MODE_ON)) {
REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, 0);
tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
- EMAC_WR(bp, EMAC_REG_EMAC_LED, tmp | 0x3);
+ EMAC_WR(bp, EMAC_REG_EMAC_LED, tmp |
+ EMAC_LED_OVERRIDE | EMAC_LED_1000MB_OVERRIDE);
+ /* Break here; otherwise, it'll disable the
+ * intended override.
+ */
+ break;
} else
REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4,
hw_led_mode);
@@ -6244,13 +6301,9 @@ int bnx2x_set_led(struct link_params *params,
LED_BLINK_RATE_VAL_E1X_E2);
REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0 +
port*4, 1);
- if ((params->phy[EXT_PHY1].type !=
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE) &&
- (mode != LED_MODE_OPER)) {
- tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
- EMAC_WR(bp, EMAC_REG_EMAC_LED,
- (tmp & (~EMAC_LED_OVERRIDE)));
- }
+ tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
+ EMAC_WR(bp, EMAC_REG_EMAC_LED,
+ (tmp & (~EMAC_LED_OVERRIDE)));
if (CHIP_IS_E1(bp) &&
((speed == SPEED_2500) ||
@@ -6843,6 +6896,12 @@ int bnx2x_link_update(struct link_params *params, struct link_vars *vars)
SINGLE_MEDIA_DIRECT(params)) &&
(phy_vars[active_external_phy].fault_detected == 0));
+ /* Update the PFC configuration in case it was changed */
+ if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED)
+ vars->link_status |= LINK_STATUS_PFC_ENABLED;
+ else
+ vars->link_status &= ~LINK_STATUS_PFC_ENABLED;
+
if (vars->link_up)
rc = bnx2x_update_link_up(params, vars, link_10g_plus);
else
@@ -8030,7 +8089,9 @@ static int bnx2x_verify_sfp_module(struct bnx2x_phy *phy,
netdev_err(bp->dev, "Warning: Unqualified SFP+ module detected,"
" Port %d from %s part number %s\n",
params->port, vendor_name, vendor_pn);
- phy->flags |= FLAGS_SFP_NOT_APPROVED;
+ if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) !=
+ PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_WARNING_MSG)
+ phy->flags |= FLAGS_SFP_NOT_APPROVED;
return -EINVAL;
}
@@ -9090,6 +9151,12 @@ static int bnx2x_8727_config_init(struct bnx2x_phy *phy,
tmp2 &= 0xFFEF;
bnx2x_cl45_write(bp, phy,
MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_OPT_CFG_REG, tmp2);
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER,
+ &tmp2);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER,
+ (tmp2 & 0x7fff));
}
return 0;
@@ -9270,12 +9337,11 @@ static u8 bnx2x_8727_read_status(struct bnx2x_phy *phy,
MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL,
((1<<5) | (1<<2)));
}
- DP(NETIF_MSG_LINK, "Enabling 8727 TX laser if SFP is approved\n");
- bnx2x_8727_specific_func(phy, params, ENABLE_TX);
- /* If transmitter is disabled, ignore false link up indication */
- bnx2x_cl45_read(bp, phy,
- MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, &val1);
- if (val1 & (1<<15)) {
+
+ if (!(phy->flags & FLAGS_SFP_NOT_APPROVED)) {
+ DP(NETIF_MSG_LINK, "Enabling 8727 TX laser\n");
+ bnx2x_sfp_set_transmitter(params, phy, 1);
+ } else {
DP(NETIF_MSG_LINK, "Tx is disabled\n");
return 0;
}
@@ -9369,8 +9435,7 @@ static void bnx2x_save_848xx_spirom_version(struct bnx2x_phy *phy,
if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) {
bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD, 0x400f, &fw_ver1);
- bnx2x_save_spirom_version(bp, port,
- ((fw_ver1 & 0xf000)>>5) | (fw_ver1 & 0x7f),
+ bnx2x_save_spirom_version(bp, port, fw_ver1 & 0xfff,
phy->ver_addr);
} else {
/* For 32-bit registers in 848xx, access via MDIO2ARM i/f. */
@@ -9793,6 +9858,15 @@ static int bnx2x_84833_hw_reset_phy(struct bnx2x_phy *phy,
other_shmem_base_addr));
u32 shmem_base_path[2];
+
+ /* Work around for 84833 LED failure inside RESET status */
+ bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
+ MDIO_AN_REG_8481_LEGACY_MII_CTRL,
+ MDIO_AN_REG_8481_MII_CTRL_FORCE_1G);
+ bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
+ MDIO_AN_REG_8481_1G_100T_EXT_CTRL,
+ MIDO_AN_REG_8481_EXT_CTRL_FORCE_LEDS_OFF);
+
shmem_base_path[0] = params->shmem_base;
shmem_base_path[1] = other_shmem_base_addr;
@@ -10103,7 +10177,7 @@ static void bnx2x_848x3_link_reset(struct bnx2x_phy *phy,
u8 port;
u16 val16;
- if (!(CHIP_IS_E1(bp)))
+ if (!(CHIP_IS_E1x(bp)))
port = BP_PATH(bp);
else
port = params->port;
@@ -10130,7 +10204,7 @@ static void bnx2x_848xx_set_link_led(struct bnx2x_phy *phy,
u16 val;
u8 port;
- if (!(CHIP_IS_E1(bp)))
+ if (!(CHIP_IS_E1x(bp)))
port = BP_PATH(bp);
else
port = params->port;
@@ -12049,6 +12123,9 @@ int bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
bnx2x_emac_init(params, vars);
+ if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED)
+ vars->link_status |= LINK_STATUS_PFC_ENABLED;
+
if (params->num_phys == 0) {
DP(NETIF_MSG_LINK, "No phy found for initialization !!\n");
return -EINVAL;
@@ -12128,10 +12205,10 @@ int bnx2x_link_reset(struct link_params *params, struct link_vars *vars,
* Hold it as vars low
*/
/* clear link led */
+ bnx2x_set_mdio_clk(bp, params->chip_id, port);
bnx2x_set_led(params, vars, LED_MODE_OFF, 0);
if (reset_ext_phy) {
- bnx2x_set_mdio_clk(bp, params->chip_id, port);
for (phy_index = EXT_PHY1; phy_index < params->num_phys;
phy_index++) {
if (params->phy[phy_index].link_reset) {
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h
index ab0a250f95fa..c25803b9c0ca 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h
@@ -5354,6 +5354,7 @@
#define XMAC_CTRL_REG_TX_EN (0x1<<0)
#define XMAC_PAUSE_CTRL_REG_RX_PAUSE_EN (0x1<<18)
#define XMAC_PAUSE_CTRL_REG_TX_PAUSE_EN (0x1<<17)
+#define XMAC_PFC_CTRL_HI_REG_FORCE_PFC_XON (0x1<<1)
#define XMAC_PFC_CTRL_HI_REG_PFC_REFRESH_EN (0x1<<0)
#define XMAC_PFC_CTRL_HI_REG_PFC_STATS_EN (0x1<<3)
#define XMAC_PFC_CTRL_HI_REG_RX_PFC_EN (0x1<<4)
@@ -6820,10 +6821,13 @@ Theotherbitsarereservedandshouldbezero*/
#define MDIO_AN_REG_8481_10GBASE_T_AN_CTRL 0x0020
#define MDIO_AN_REG_8481_LEGACY_MII_CTRL 0xffe0
+#define MDIO_AN_REG_8481_MII_CTRL_FORCE_1G 0x40
#define MDIO_AN_REG_8481_LEGACY_MII_STATUS 0xffe1
#define MDIO_AN_REG_8481_LEGACY_AN_ADV 0xffe4
#define MDIO_AN_REG_8481_LEGACY_AN_EXPANSION 0xffe6
#define MDIO_AN_REG_8481_1000T_CTRL 0xffe9
+#define MDIO_AN_REG_8481_1G_100T_EXT_CTRL 0xfff0
+#define MIDO_AN_REG_8481_EXT_CTRL_FORCE_LEDS_OFF 0x0008
#define MDIO_AN_REG_8481_EXPANSION_REG_RD_RW 0xfff5
#define MDIO_AN_REG_8481_EXPANSION_REG_ACCESS 0xfff7
#define MDIO_AN_REG_8481_AUX_CTRL 0xfff8
@@ -6943,6 +6947,10 @@ Theotherbitsarereservedandshouldbezero*/
#define MDIO_WC_REG_GP2_STATUS_GP_2_2 0x81d2
#define MDIO_WC_REG_GP2_STATUS_GP_2_3 0x81d3
#define MDIO_WC_REG_GP2_STATUS_GP_2_4 0x81d4
+#define MDIO_WC_REG_GP2_STATUS_GP_2_4_CL73_AN_CMPL 0x1000
+#define MDIO_WC_REG_GP2_STATUS_GP_2_4_CL37_AN_CMPL 0x0100
+#define MDIO_WC_REG_GP2_STATUS_GP_2_4_CL37_LP_AN_CAP 0x0010
+#define MDIO_WC_REG_GP2_STATUS_GP_2_4_CL37_AN_CAP 0x1
#define MDIO_WC_REG_UC_INFO_B0_DEAD_TRAP 0x81EE
#define MDIO_WC_REG_UC_INFO_B1_VERSION 0x81F0
#define MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE 0x81F2
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
index 05ff076af06d..b126b98065a9 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
@@ -2000,13 +2000,6 @@ static const struct ethtool_ops cxgb_ethtool_ops = {
/*
* debugfs support
*/
-
-static int mem_open(struct inode *inode, struct file *file)
-{
- file->private_data = inode->i_private;
- return 0;
-}
-
static ssize_t mem_read(struct file *file, char __user *buf, size_t count,
loff_t *ppos)
{
@@ -2050,7 +2043,7 @@ static ssize_t mem_read(struct file *file, char __user *buf, size_t count,
static const struct file_operations mem_debugfs_fops = {
.owner = THIS_MODULE,
- .open = mem_open,
+ .open = simple_open,
.read = mem_read,
.llseek = default_llseek,
};
diff --git a/drivers/net/ethernet/intel/e1000e/e1000.h b/drivers/net/ethernet/intel/e1000e/e1000.h
index 86cdd4793992..b83897f76ee3 100644
--- a/drivers/net/ethernet/intel/e1000e/e1000.h
+++ b/drivers/net/ethernet/intel/e1000e/e1000.h
@@ -161,6 +161,12 @@ struct e1000_info;
/* Time to wait before putting the device into D3 if there's no link (in ms). */
#define LINK_TIMEOUT 100
+/*
+ * Count for polling __E1000_RESET condition every 10-20msec.
+ * Experimentation has shown the reset can take approximately 210msec.
+ */
+#define E1000_CHECK_RESET_COUNT 25
+
#define DEFAULT_RDTR 0
#define DEFAULT_RADV 8
#define BURST_RDTR 0x20
diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c
index 64c76443a7aa..b461c24945e3 100644
--- a/drivers/net/ethernet/intel/e1000e/ich8lan.c
+++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c
@@ -1310,10 +1310,6 @@ static s32 e1000_oem_bits_config_ich8lan(struct e1000_hw *hw, bool d0_state)
if (mac_reg & E1000_PHY_CTRL_D0A_LPLU)
oem_reg |= HV_OEM_BITS_LPLU;
-
- /* Set Restart auto-neg to activate the bits */
- if (!hw->phy.ops.check_reset_block(hw))
- oem_reg |= HV_OEM_BITS_RESTART_AN;
} else {
if (mac_reg & (E1000_PHY_CTRL_GBE_DISABLE |
E1000_PHY_CTRL_NOND0A_GBE_DISABLE))
@@ -1324,6 +1320,11 @@ static s32 e1000_oem_bits_config_ich8lan(struct e1000_hw *hw, bool d0_state)
oem_reg |= HV_OEM_BITS_LPLU;
}
+ /* Set Restart auto-neg to activate the bits */
+ if ((d0_state || (hw->mac.type != e1000_pchlan)) &&
+ !hw->phy.ops.check_reset_block(hw))
+ oem_reg |= HV_OEM_BITS_RESTART_AN;
+
ret_val = hw->phy.ops.write_reg_locked(hw, HV_OEM_BITS, oem_reg);
release:
@@ -3682,7 +3683,11 @@ void e1000_suspend_workarounds_ich8lan(struct e1000_hw *hw)
if (hw->mac.type >= e1000_pchlan) {
e1000_oem_bits_config_ich8lan(hw, false);
- e1000_phy_hw_reset_ich8lan(hw);
+
+ /* Reset PHY to activate OEM bits on 82577/8 */
+ if (hw->mac.type == e1000_pchlan)
+ e1000e_phy_hw_reset_generic(hw);
+
ret_val = hw->phy.ops.acquire(hw);
if (ret_val)
return;
diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c
index 2c38a65ade87..19ab2154802c 100644
--- a/drivers/net/ethernet/intel/e1000e/netdev.c
+++ b/drivers/net/ethernet/intel/e1000e/netdev.c
@@ -1059,6 +1059,13 @@ static void e1000_print_hw_hang(struct work_struct *work)
ew32(TIDV, adapter->tx_int_delay | E1000_TIDV_FPD);
/* execute the writes immediately */
e1e_flush();
+ /*
+ * Due to rare timing issues, write to TIDV again to ensure
+ * the write is successful
+ */
+ ew32(TIDV, adapter->tx_int_delay | E1000_TIDV_FPD);
+ /* execute the writes immediately */
+ e1e_flush();
adapter->tx_hang_recheck = true;
return;
}
@@ -3616,6 +3623,16 @@ static void e1000e_flush_descriptors(struct e1000_adapter *adapter)
/* execute the writes immediately */
e1e_flush();
+
+ /*
+ * due to rare timing issues, write to TIDV/RDTR again to ensure the
+ * write is successful
+ */
+ ew32(TIDV, adapter->tx_int_delay | E1000_TIDV_FPD);
+ ew32(RDTR, adapter->rx_int_delay | E1000_RDTR_FPD);
+
+ /* execute the writes immediately */
+ e1e_flush();
}
static void e1000e_update_stats(struct e1000_adapter *adapter);
@@ -3968,6 +3985,10 @@ static int e1000_close(struct net_device *netdev)
{
struct e1000_adapter *adapter = netdev_priv(netdev);
struct pci_dev *pdev = adapter->pdev;
+ int count = E1000_CHECK_RESET_COUNT;
+
+ while (test_bit(__E1000_RESETTING, &adapter->state) && count--)
+ usleep_range(10000, 20000);
WARN_ON(test_bit(__E1000_RESETTING, &adapter->state));
@@ -5472,6 +5493,11 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake,
netif_device_detach(netdev);
if (netif_running(netdev)) {
+ int count = E1000_CHECK_RESET_COUNT;
+
+ while (test_bit(__E1000_RESETTING, &adapter->state) && count--)
+ usleep_range(10000, 20000);
+
WARN_ON(test_bit(__E1000_RESETTING, &adapter->state));
e1000e_down(adapter);
e1000_free_irq(adapter);
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c
index dde65f951400..652e4b09546d 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c
@@ -44,62 +44,94 @@
#define DCB_NO_HW_CHG 1 /* DCB configuration did not change */
#define DCB_HW_CHG 2 /* DCB configuration changed, no reset */
-int ixgbe_copy_dcb_cfg(struct ixgbe_dcb_config *src_dcb_cfg,
- struct ixgbe_dcb_config *dst_dcb_cfg, int tc_max)
+int ixgbe_copy_dcb_cfg(struct ixgbe_dcb_config *scfg,
+ struct ixgbe_dcb_config *dcfg, int tc_max)
{
- struct tc_configuration *src_tc_cfg = NULL;
- struct tc_configuration *dst_tc_cfg = NULL;
- int i;
+ struct tc_configuration *src = NULL;
+ struct tc_configuration *dst = NULL;
+ int i, j;
+ int tx = DCB_TX_CONFIG;
+ int rx = DCB_RX_CONFIG;
+ int changes = 0;
- if (!src_dcb_cfg || !dst_dcb_cfg)
- return -EINVAL;
+ if (!scfg || !dcfg)
+ return changes;
for (i = DCB_PG_ATTR_TC_0; i < tc_max + DCB_PG_ATTR_TC_0; i++) {
- src_tc_cfg = &src_dcb_cfg->tc_config[i - DCB_PG_ATTR_TC_0];
- dst_tc_cfg = &dst_dcb_cfg->tc_config[i - DCB_PG_ATTR_TC_0];
+ src = &scfg->tc_config[i - DCB_PG_ATTR_TC_0];
+ dst = &dcfg->tc_config[i - DCB_PG_ATTR_TC_0];
- dst_tc_cfg->path[DCB_TX_CONFIG].prio_type =
- src_tc_cfg->path[DCB_TX_CONFIG].prio_type;
+ if (dst->path[tx].prio_type != src->path[tx].prio_type) {
+ dst->path[tx].prio_type = src->path[tx].prio_type;
+ changes |= BIT_PG_TX;
+ }
- dst_tc_cfg->path[DCB_TX_CONFIG].bwg_id =
- src_tc_cfg->path[DCB_TX_CONFIG].bwg_id;
+ if (dst->path[tx].bwg_id != src->path[tx].bwg_id) {
+ dst->path[tx].bwg_id = src->path[tx].bwg_id;
+ changes |= BIT_PG_TX;
+ }
- dst_tc_cfg->path[DCB_TX_CONFIG].bwg_percent =
- src_tc_cfg->path[DCB_TX_CONFIG].bwg_percent;
+ if (dst->path[tx].bwg_percent != src->path[tx].bwg_percent) {
+ dst->path[tx].bwg_percent = src->path[tx].bwg_percent;
+ changes |= BIT_PG_TX;
+ }
- dst_tc_cfg->path[DCB_TX_CONFIG].up_to_tc_bitmap =
- src_tc_cfg->path[DCB_TX_CONFIG].up_to_tc_bitmap;
+ if (dst->path[tx].up_to_tc_bitmap !=
+ src->path[tx].up_to_tc_bitmap) {
+ dst->path[tx].up_to_tc_bitmap =
+ src->path[tx].up_to_tc_bitmap;
+ changes |= (BIT_PG_TX | BIT_PFC | BIT_APP_UPCHG);
+ }
- dst_tc_cfg->path[DCB_RX_CONFIG].prio_type =
- src_tc_cfg->path[DCB_RX_CONFIG].prio_type;
+ if (dst->path[rx].prio_type != src->path[rx].prio_type) {
+ dst->path[rx].prio_type = src->path[rx].prio_type;
+ changes |= BIT_PG_RX;
+ }
- dst_tc_cfg->path[DCB_RX_CONFIG].bwg_id =
- src_tc_cfg->path[DCB_RX_CONFIG].bwg_id;
+ if (dst->path[rx].bwg_id != src->path[rx].bwg_id) {
+ dst->path[rx].bwg_id = src->path[rx].bwg_id;
+ changes |= BIT_PG_RX;
+ }
- dst_tc_cfg->path[DCB_RX_CONFIG].bwg_percent =
- src_tc_cfg->path[DCB_RX_CONFIG].bwg_percent;
+ if (dst->path[rx].bwg_percent != src->path[rx].bwg_percent) {
+ dst->path[rx].bwg_percent = src->path[rx].bwg_percent;
+ changes |= BIT_PG_RX;
+ }
- dst_tc_cfg->path[DCB_RX_CONFIG].up_to_tc_bitmap =
- src_tc_cfg->path[DCB_RX_CONFIG].up_to_tc_bitmap;
+ if (dst->path[rx].up_to_tc_bitmap !=
+ src->path[rx].up_to_tc_bitmap) {
+ dst->path[rx].up_to_tc_bitmap =
+ src->path[rx].up_to_tc_bitmap;
+ changes |= (BIT_PG_RX | BIT_PFC | BIT_APP_UPCHG);
+ }
}
for (i = DCB_PG_ATTR_BW_ID_0; i < DCB_PG_ATTR_BW_ID_MAX; i++) {
- dst_dcb_cfg->bw_percentage[DCB_TX_CONFIG]
- [i-DCB_PG_ATTR_BW_ID_0] = src_dcb_cfg->bw_percentage
- [DCB_TX_CONFIG][i-DCB_PG_ATTR_BW_ID_0];
- dst_dcb_cfg->bw_percentage[DCB_RX_CONFIG]
- [i-DCB_PG_ATTR_BW_ID_0] = src_dcb_cfg->bw_percentage
- [DCB_RX_CONFIG][i-DCB_PG_ATTR_BW_ID_0];
+ j = i - DCB_PG_ATTR_BW_ID_0;
+ if (dcfg->bw_percentage[tx][j] != scfg->bw_percentage[tx][j]) {
+ dcfg->bw_percentage[tx][j] = scfg->bw_percentage[tx][j];
+ changes |= BIT_PG_TX;
+ }
+ if (dcfg->bw_percentage[rx][j] != scfg->bw_percentage[rx][j]) {
+ dcfg->bw_percentage[rx][j] = scfg->bw_percentage[rx][j];
+ changes |= BIT_PG_RX;
+ }
}
for (i = DCB_PFC_UP_ATTR_0; i < DCB_PFC_UP_ATTR_MAX; i++) {
- dst_dcb_cfg->tc_config[i - DCB_PFC_UP_ATTR_0].dcb_pfc =
- src_dcb_cfg->tc_config[i - DCB_PFC_UP_ATTR_0].dcb_pfc;
+ j = i - DCB_PFC_UP_ATTR_0;
+ if (dcfg->tc_config[j].dcb_pfc != scfg->tc_config[j].dcb_pfc) {
+ dcfg->tc_config[j].dcb_pfc = scfg->tc_config[j].dcb_pfc;
+ changes |= BIT_PFC;
+ }
}
- dst_dcb_cfg->pfc_mode_enable = src_dcb_cfg->pfc_mode_enable;
+ if (dcfg->pfc_mode_enable != scfg->pfc_mode_enable) {
+ dcfg->pfc_mode_enable = scfg->pfc_mode_enable;
+ changes |= BIT_PFC;
+ }
- return 0;
+ return changes;
}
static u8 ixgbe_dcbnl_get_state(struct net_device *netdev)
@@ -179,20 +211,6 @@ static void ixgbe_dcbnl_set_pg_tc_cfg_tx(struct net_device *netdev, int tc,
if (up_map != DCB_ATTR_VALUE_UNDEFINED)
adapter->temp_dcb_cfg.tc_config[tc].path[0].up_to_tc_bitmap =
up_map;
-
- if ((adapter->temp_dcb_cfg.tc_config[tc].path[0].prio_type !=
- adapter->dcb_cfg.tc_config[tc].path[0].prio_type) ||
- (adapter->temp_dcb_cfg.tc_config[tc].path[0].bwg_id !=
- adapter->dcb_cfg.tc_config[tc].path[0].bwg_id) ||
- (adapter->temp_dcb_cfg.tc_config[tc].path[0].bwg_percent !=
- adapter->dcb_cfg.tc_config[tc].path[0].bwg_percent) ||
- (adapter->temp_dcb_cfg.tc_config[tc].path[0].up_to_tc_bitmap !=
- adapter->dcb_cfg.tc_config[tc].path[0].up_to_tc_bitmap))
- adapter->dcb_set_bitmap |= BIT_PG_TX;
-
- if (adapter->temp_dcb_cfg.tc_config[tc].path[0].up_to_tc_bitmap !=
- adapter->dcb_cfg.tc_config[tc].path[0].up_to_tc_bitmap)
- adapter->dcb_set_bitmap |= BIT_PFC | BIT_APP_UPCHG;
}
static void ixgbe_dcbnl_set_pg_bwg_cfg_tx(struct net_device *netdev, int bwg_id,
@@ -201,10 +219,6 @@ static void ixgbe_dcbnl_set_pg_bwg_cfg_tx(struct net_device *netdev, int bwg_id,
struct ixgbe_adapter *adapter = netdev_priv(netdev);
adapter->temp_dcb_cfg.bw_percentage[0][bwg_id] = bw_pct;
-
- if (adapter->temp_dcb_cfg.bw_percentage[0][bwg_id] !=
- adapter->dcb_cfg.bw_percentage[0][bwg_id])
- adapter->dcb_set_bitmap |= BIT_PG_TX;
}
static void ixgbe_dcbnl_set_pg_tc_cfg_rx(struct net_device *netdev, int tc,
@@ -223,20 +237,6 @@ static void ixgbe_dcbnl_set_pg_tc_cfg_rx(struct net_device *netdev, int tc,
if (up_map != DCB_ATTR_VALUE_UNDEFINED)
adapter->temp_dcb_cfg.tc_config[tc].path[1].up_to_tc_bitmap =
up_map;
-
- if ((adapter->temp_dcb_cfg.tc_config[tc].path[1].prio_type !=
- adapter->dcb_cfg.tc_config[tc].path[1].prio_type) ||
- (adapter->temp_dcb_cfg.tc_config[tc].path[1].bwg_id !=
- adapter->dcb_cfg.tc_config[tc].path[1].bwg_id) ||
- (adapter->temp_dcb_cfg.tc_config[tc].path[1].bwg_percent !=
- adapter->dcb_cfg.tc_config[tc].path[1].bwg_percent) ||
- (adapter->temp_dcb_cfg.tc_config[tc].path[1].up_to_tc_bitmap !=
- adapter->dcb_cfg.tc_config[tc].path[1].up_to_tc_bitmap))
- adapter->dcb_set_bitmap |= BIT_PG_RX;
-
- if (adapter->temp_dcb_cfg.tc_config[tc].path[1].up_to_tc_bitmap !=
- adapter->dcb_cfg.tc_config[tc].path[1].up_to_tc_bitmap)
- adapter->dcb_set_bitmap |= BIT_PFC;
}
static void ixgbe_dcbnl_set_pg_bwg_cfg_rx(struct net_device *netdev, int bwg_id,
@@ -245,10 +245,6 @@ static void ixgbe_dcbnl_set_pg_bwg_cfg_rx(struct net_device *netdev, int bwg_id,
struct ixgbe_adapter *adapter = netdev_priv(netdev);
adapter->temp_dcb_cfg.bw_percentage[1][bwg_id] = bw_pct;
-
- if (adapter->temp_dcb_cfg.bw_percentage[1][bwg_id] !=
- adapter->dcb_cfg.bw_percentage[1][bwg_id])
- adapter->dcb_set_bitmap |= BIT_PG_RX;
}
static void ixgbe_dcbnl_get_pg_tc_cfg_tx(struct net_device *netdev, int tc,
@@ -298,10 +294,8 @@ static void ixgbe_dcbnl_set_pfc_cfg(struct net_device *netdev, int priority,
adapter->temp_dcb_cfg.tc_config[priority].dcb_pfc = setting;
if (adapter->temp_dcb_cfg.tc_config[priority].dcb_pfc !=
- adapter->dcb_cfg.tc_config[priority].dcb_pfc) {
- adapter->dcb_set_bitmap |= BIT_PFC;
+ adapter->dcb_cfg.tc_config[priority].dcb_pfc)
adapter->temp_dcb_cfg.pfc_mode_enable = true;
- }
}
static void ixgbe_dcbnl_get_pfc_cfg(struct net_device *netdev, int priority,
@@ -336,7 +330,8 @@ static void ixgbe_dcbnl_devreset(struct net_device *dev)
static u8 ixgbe_dcbnl_set_all(struct net_device *netdev)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
- int ret, i;
+ int ret = DCB_NO_HW_CHG;
+ int i;
#ifdef IXGBE_FCOE
struct dcb_app app = {
.selector = DCB_APP_IDTYPE_ETHTYPE,
@@ -355,12 +350,13 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev)
/* Fail command if not in CEE mode */
if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_CEE))
- return 1;
+ return ret;
- ret = ixgbe_copy_dcb_cfg(&adapter->temp_dcb_cfg, &adapter->dcb_cfg,
- MAX_TRAFFIC_CLASS);
- if (ret)
- return DCB_NO_HW_CHG;
+ adapter->dcb_set_bitmap |= ixgbe_copy_dcb_cfg(&adapter->temp_dcb_cfg,
+ &adapter->dcb_cfg,
+ MAX_TRAFFIC_CLASS);
+ if (!adapter->dcb_set_bitmap)
+ return ret;
if (adapter->dcb_cfg.pfc_mode_enable) {
switch (adapter->hw.mac.type) {
@@ -420,6 +416,8 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev)
for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++)
netdev_set_prio_tc_map(netdev, i, prio_tc[i]);
+
+ ret = DCB_HW_CHG_RST;
}
if (adapter->dcb_set_bitmap & BIT_PFC) {
@@ -430,7 +428,8 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev)
DCB_TX_CONFIG, prio_tc);
ixgbe_dcb_unpack_pfc(&adapter->dcb_cfg, &pfc_en);
ixgbe_dcb_hw_pfc_config(&adapter->hw, pfc_en, prio_tc);
- ret = DCB_HW_CHG;
+ if (ret != DCB_HW_CHG_RST)
+ ret = DCB_HW_CHG;
}
if (adapter->dcb_cfg.pfc_mode_enable)
@@ -531,9 +530,6 @@ static void ixgbe_dcbnl_setpfcstate(struct net_device *netdev, u8 state)
struct ixgbe_adapter *adapter = netdev_priv(netdev);
adapter->temp_dcb_cfg.pfc_mode_enable = state;
- if (adapter->temp_dcb_cfg.pfc_mode_enable !=
- adapter->dcb_cfg.pfc_mode_enable)
- adapter->dcb_set_bitmap |= BIT_PFC;
}
/**
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c
index 027d7a75be39..ed1b47dc0834 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c
@@ -622,6 +622,16 @@ static int ixgbe_alloc_q_vector(struct ixgbe_adapter *adapter, int v_idx,
if (adapter->hw.mac.type == ixgbe_mac_82599EB)
set_bit(__IXGBE_RX_CSUM_UDP_ZERO_ERR, &ring->state);
+#ifdef IXGBE_FCOE
+ if (adapter->netdev->features & NETIF_F_FCOE_MTU) {
+ struct ixgbe_ring_feature *f;
+ f = &adapter->ring_feature[RING_F_FCOE];
+ if ((rxr_idx >= f->mask) &&
+ (rxr_idx < f->mask + f->indices))
+ set_bit(__IXGBE_RX_FCOE_BUFSZ, &ring->state);
+ }
+
+#endif /* IXGBE_FCOE */
/* apply Rx specific ring traits */
ring->count = adapter->rx_ring_count;
ring->queue_index = rxr_idx;
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 3e26b1f9ac75..a7f3cd872caf 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -3154,14 +3154,6 @@ static void ixgbe_set_rx_buffer_len(struct ixgbe_adapter *adapter)
set_ring_rsc_enabled(rx_ring);
else
clear_ring_rsc_enabled(rx_ring);
-#ifdef IXGBE_FCOE
- if (netdev->features & NETIF_F_FCOE_MTU) {
- struct ixgbe_ring_feature *f;
- f = &adapter->ring_feature[RING_F_FCOE];
- if ((i >= f->mask) && (i < f->mask + f->indices))
- set_bit(__IXGBE_RX_FCOE_BUFSZ, &rx_ring->state);
- }
-#endif /* IXGBE_FCOE */
}
}
@@ -4836,7 +4828,9 @@ static int ixgbe_resume(struct pci_dev *pdev)
pci_wake_from_d3(pdev, false);
+ rtnl_lock();
err = ixgbe_init_interrupt_scheme(adapter);
+ rtnl_unlock();
if (err) {
e_dev_err("Cannot initialize interrupts for device\n");
return err;
@@ -4893,6 +4887,16 @@ static int __ixgbe_shutdown(struct pci_dev *pdev, bool *enable_wake)
if (wufc) {
ixgbe_set_rx_mode(netdev);
+ /*
+ * enable the optics for both mult-speed fiber and
+ * 82599 SFP+ fiber as we can WoL.
+ */
+ if (hw->mac.ops.enable_tx_laser &&
+ (hw->phy.multispeed_fiber ||
+ (hw->mac.ops.get_media_type(hw) == ixgbe_media_type_fiber &&
+ hw->mac.type == ixgbe_mac_82599EB)))
+ hw->mac.ops.enable_tx_laser(hw);
+
/* turn on all-multi mode if wake on multicast is enabled */
if (wufc & IXGBE_WUFC_MC) {
fctrl = IXGBE_READ_REG(hw, IXGBE_FCTRL);
diff --git a/drivers/net/ethernet/marvell/sky2.c b/drivers/net/ethernet/marvell/sky2.c
index b806d9b4defb..c9b504e2dfc3 100644
--- a/drivers/net/ethernet/marvell/sky2.c
+++ b/drivers/net/ethernet/marvell/sky2.c
@@ -2469,6 +2469,17 @@ static int sky2_change_mtu(struct net_device *dev, int new_mtu)
return err;
}
+static inline bool needs_copy(const struct rx_ring_info *re,
+ unsigned length)
+{
+#ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
+ /* Some architectures need the IP header to be aligned */
+ if (!IS_ALIGNED(re->data_addr + ETH_HLEN, sizeof(u32)))
+ return true;
+#endif
+ return length < copybreak;
+}
+
/* For small just reuse existing skb for next receive */
static struct sk_buff *receive_copy(struct sky2_port *sky2,
const struct rx_ring_info *re,
@@ -2599,7 +2610,7 @@ static struct sk_buff *sky2_receive(struct net_device *dev,
goto error;
okay:
- if (length < copybreak)
+ if (needs_copy(re, length))
skb = receive_copy(sky2, re, length);
else
skb = receive_new(sky2, re, length);
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
index 9e2b911a1230..d69fee41f24a 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
@@ -83,8 +83,9 @@
#define MLX4_EN_WATCHDOG_TIMEOUT (15 * HZ)
-#define MLX4_EN_ALLOC_ORDER 2
-#define MLX4_EN_ALLOC_SIZE (PAGE_SIZE << MLX4_EN_ALLOC_ORDER)
+/* Use the maximum between 16384 and a single page */
+#define MLX4_EN_ALLOC_SIZE PAGE_ALIGN(16384)
+#define MLX4_EN_ALLOC_ORDER get_order(MLX4_EN_ALLOC_SIZE)
#define MLX4_EN_MAX_LRO_DESCRIPTORS 32
diff --git a/drivers/net/ethernet/micrel/ks8851.c b/drivers/net/ethernet/micrel/ks8851.c
index c722aa607d07..f8dda009d3c0 100644
--- a/drivers/net/ethernet/micrel/ks8851.c
+++ b/drivers/net/ethernet/micrel/ks8851.c
@@ -889,16 +889,17 @@ static int ks8851_net_stop(struct net_device *dev)
netif_stop_queue(dev);
mutex_lock(&ks->lock);
+ /* turn off the IRQs and ack any outstanding */
+ ks8851_wrreg16(ks, KS_IER, 0x0000);
+ ks8851_wrreg16(ks, KS_ISR, 0xffff);
+ mutex_unlock(&ks->lock);
/* stop any outstanding work */
flush_work(&ks->irq_work);
flush_work(&ks->tx_work);
flush_work(&ks->rxctrl_work);
- /* turn off the IRQs and ack any outstanding */
- ks8851_wrreg16(ks, KS_IER, 0x0000);
- ks8851_wrreg16(ks, KS_ISR, 0xffff);
-
+ mutex_lock(&ks->lock);
/* shutdown RX process */
ks8851_wrreg16(ks, KS_RXCR1, 0x0000);
@@ -907,6 +908,7 @@ static int ks8851_net_stop(struct net_device *dev)
/* set powermode to soft power down to save power */
ks8851_set_powermode(ks, PMECR_PM_SOFTDOWN);
+ mutex_unlock(&ks->lock);
/* ensure any queued tx buffers are dumped */
while (!skb_queue_empty(&ks->txq)) {
@@ -918,7 +920,6 @@ static int ks8851_net_stop(struct net_device *dev)
dev_kfree_skb(txb);
}
- mutex_unlock(&ks->lock);
return 0;
}
@@ -1418,6 +1419,7 @@ static int __devinit ks8851_probe(struct spi_device *spi)
struct net_device *ndev;
struct ks8851_net *ks;
int ret;
+ unsigned cider;
ndev = alloc_etherdev(sizeof(struct ks8851_net));
if (!ndev)
@@ -1484,8 +1486,8 @@ static int __devinit ks8851_probe(struct spi_device *spi)
ks8851_soft_reset(ks, GRR_GSR);
/* simple check for a valid chip being connected to the bus */
-
- if ((ks8851_rdreg16(ks, KS_CIDER) & ~CIDER_REV_MASK) != CIDER_ID) {
+ cider = ks8851_rdreg16(ks, KS_CIDER);
+ if ((cider & ~CIDER_REV_MASK) != CIDER_ID) {
dev_err(&spi->dev, "failed to read device ID\n");
ret = -ENODEV;
goto err_id;
@@ -1516,15 +1518,14 @@ static int __devinit ks8851_probe(struct spi_device *spi)
}
netdev_info(ndev, "revision %d, MAC %pM, IRQ %d, %s EEPROM\n",
- CIDER_REV_GET(ks8851_rdreg16(ks, KS_CIDER)),
- ndev->dev_addr, ndev->irq,
+ CIDER_REV_GET(cider), ndev->dev_addr, ndev->irq,
ks->rc_ccr & CCR_EEPROM ? "has" : "no");
return 0;
err_netdev:
- free_irq(ndev->irq, ndev);
+ free_irq(ndev->irq, ks);
err_id:
err_irq:
diff --git a/drivers/net/ethernet/micrel/ks8851_mll.c b/drivers/net/ethernet/micrel/ks8851_mll.c
index b8104d9f4081..5ffde23ac8fb 100644
--- a/drivers/net/ethernet/micrel/ks8851_mll.c
+++ b/drivers/net/ethernet/micrel/ks8851_mll.c
@@ -40,7 +40,7 @@
#define DRV_NAME "ks8851_mll"
static u8 KS_DEFAULT_MAC_ADDRESS[] = { 0x00, 0x10, 0xA1, 0x86, 0x95, 0x11 };
-#define MAX_RECV_FRAMES 32
+#define MAX_RECV_FRAMES 255
#define MAX_BUF_SIZE 2048
#define TX_BUF_SIZE 2000
#define RX_BUF_SIZE 2000
diff --git a/drivers/net/ethernet/micrel/ksz884x.c b/drivers/net/ethernet/micrel/ksz884x.c
index ef723b185d85..eaf9ff0262a9 100644
--- a/drivers/net/ethernet/micrel/ksz884x.c
+++ b/drivers/net/ethernet/micrel/ksz884x.c
@@ -5675,7 +5675,7 @@ static int netdev_set_mac_address(struct net_device *dev, void *addr)
memcpy(hw->override_addr, mac->sa_data, ETH_ALEN);
}
- memcpy(dev->dev_addr, mac->sa_data, MAX_ADDR_LEN);
+ memcpy(dev->dev_addr, mac->sa_data, ETH_ALEN);
interrupt = hw_block_intr(hw);
diff --git a/drivers/net/ethernet/realtek/8139cp.c b/drivers/net/ethernet/realtek/8139cp.c
index abc79076f867..b3287c0fe279 100644
--- a/drivers/net/ethernet/realtek/8139cp.c
+++ b/drivers/net/ethernet/realtek/8139cp.c
@@ -958,6 +958,11 @@ static inline void cp_start_hw (struct cp_private *cp)
cpw8(Cmd, RxOn | TxOn);
}
+static void cp_enable_irq(struct cp_private *cp)
+{
+ cpw16_f(IntrMask, cp_intr_mask);
+}
+
static void cp_init_hw (struct cp_private *cp)
{
struct net_device *dev = cp->dev;
@@ -997,8 +1002,6 @@ static void cp_init_hw (struct cp_private *cp)
cpw16(MultiIntr, 0);
- cpw16_f(IntrMask, cp_intr_mask);
-
cpw8_f(Cfg9346, Cfg9346_Lock);
}
@@ -1130,6 +1133,8 @@ static int cp_open (struct net_device *dev)
if (rc)
goto err_out_hw;
+ cp_enable_irq(cp);
+
netif_carrier_off(dev);
mii_check_media(&cp->mii_if, netif_msg_link(cp), true);
netif_start_queue(dev);
@@ -2031,6 +2036,7 @@ static int cp_resume (struct pci_dev *pdev)
/* FIXME: sh*t may happen if the Rx ring buffer is depleted */
cp_init_rings_index (cp);
cp_init_hw (cp);
+ cp_enable_irq(cp);
netif_start_queue (dev);
spin_lock_irqsave (&cp->lock, flags);
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
index 7b23554f80b6..f54509377efa 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -5810,7 +5810,10 @@ static void __rtl8169_resume(struct net_device *dev)
rtl_pll_power_up(tp);
+ rtl_lock_work(tp);
+ napi_enable(&tp->napi);
set_bit(RTL_FLAG_TASK_ENABLED, tp->wk.flags);
+ rtl_unlock_work(tp);
rtl_schedule_task(tp, RTL_FLAG_TASK_RESET_PENDING);
}
diff --git a/drivers/net/ethernet/smsc/smsc911x.c b/drivers/net/ethernet/smsc/smsc911x.c
index 4a6971027076..cd3defb11ffb 100644
--- a/drivers/net/ethernet/smsc/smsc911x.c
+++ b/drivers/net/ethernet/smsc/smsc911x.c
@@ -1166,10 +1166,8 @@ smsc911x_rx_counterrors(struct net_device *dev, unsigned int rxstat)
/* Quickly dumps bad packets */
static void
-smsc911x_rx_fastforward(struct smsc911x_data *pdata, unsigned int pktbytes)
+smsc911x_rx_fastforward(struct smsc911x_data *pdata, unsigned int pktwords)
{
- unsigned int pktwords = (pktbytes + NET_IP_ALIGN + 3) >> 2;
-
if (likely(pktwords >= 4)) {
unsigned int timeout = 500;
unsigned int val;
@@ -1233,7 +1231,7 @@ static int smsc911x_poll(struct napi_struct *napi, int budget)
continue;
}
- skb = netdev_alloc_skb(dev, pktlength + NET_IP_ALIGN);
+ skb = netdev_alloc_skb(dev, pktwords << 2);
if (unlikely(!skb)) {
SMSC_WARN(pdata, rx_err,
"Unable to allocate skb for rx packet");
@@ -1243,14 +1241,12 @@ static int smsc911x_poll(struct napi_struct *napi, int budget)
break;
}
- skb->data = skb->head;
- skb_reset_tail_pointer(skb);
+ pdata->ops->rx_readfifo(pdata,
+ (unsigned int *)skb->data, pktwords);
/* Align IP on 16B boundary */
skb_reserve(skb, NET_IP_ALIGN);
skb_put(skb, pktlength - 4);
- pdata->ops->rx_readfifo(pdata,
- (unsigned int *)skb->head, pktwords);
skb->protocol = eth_type_trans(skb, dev);
skb_checksum_none_assert(skb);
netif_receive_skb(skb);
@@ -1565,7 +1561,7 @@ static int smsc911x_open(struct net_device *dev)
smsc911x_reg_write(pdata, FIFO_INT, temp);
/* set RX Data offset to 2 bytes for alignment */
- smsc911x_reg_write(pdata, RX_CFG, (2 << 8));
+ smsc911x_reg_write(pdata, RX_CFG, (NET_IP_ALIGN << 8));
/* enable NAPI polling before enabling RX interrupts */
napi_enable(&pdata->napi);
@@ -2382,7 +2378,6 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev)
SET_NETDEV_DEV(dev, &pdev->dev);
pdata = netdev_priv(dev);
-
dev->irq = irq_res->start;
irq_flags = irq_res->flags & IRQF_TRIGGER_MASK;
pdata->ioaddr = ioremap_nocache(res->start, res_size);
@@ -2446,7 +2441,7 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev)
if (retval) {
SMSC_WARN(pdata, probe,
"Unable to claim requested irq: %d", dev->irq);
- goto out_free_irq;
+ goto out_disable_resources;
}
retval = register_netdev(dev);
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index e85ffbd54830..48d56da62f08 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -1737,10 +1737,12 @@ static int stmmac_hw_init(struct stmmac_priv *priv)
struct mac_device_info *mac;
/* Identify the MAC HW device */
- if (priv->plat->has_gmac)
+ if (priv->plat->has_gmac) {
+ priv->dev->priv_flags |= IFF_UNICAST_FLT;
mac = dwmac1000_setup(priv->ioaddr);
- else
+ } else {
mac = dwmac100_setup(priv->ioaddr);
+ }
if (!mac)
return -ENOMEM;
diff --git a/drivers/net/ethernet/ti/davinci_mdio.c b/drivers/net/ethernet/ti/davinci_mdio.c
index 2757c7d6e633..e4e47088e26b 100644
--- a/drivers/net/ethernet/ti/davinci_mdio.c
+++ b/drivers/net/ethernet/ti/davinci_mdio.c
@@ -181,6 +181,11 @@ static inline int wait_for_user_access(struct davinci_mdio_data *data)
__davinci_mdio_reset(data);
return -EAGAIN;
}
+
+ reg = __raw_readl(&regs->user[0].access);
+ if ((reg & USERACCESS_GO) == 0)
+ return 0;
+
dev_err(data->dev, "timed out waiting for user access\n");
return -ETIMEDOUT;
}
diff --git a/drivers/net/ethernet/tile/tilepro.c b/drivers/net/ethernet/tile/tilepro.c
index 261356c2dc99..3d501ec7fad7 100644
--- a/drivers/net/ethernet/tile/tilepro.c
+++ b/drivers/net/ethernet/tile/tilepro.c
@@ -342,6 +342,21 @@ inline int __netio_fastio1(u32 fastio_index, u32 arg0)
}
+static void tile_net_return_credit(struct tile_net_cpu *info)
+{
+ struct tile_netio_queue *queue = &info->queue;
+ netio_queue_user_impl_t *qup = &queue->__user_part;
+
+ /* Return four credits after every fourth packet. */
+ if (--qup->__receive_credit_remaining == 0) {
+ u32 interval = qup->__receive_credit_interval;
+ qup->__receive_credit_remaining = interval;
+ __netio_fastio_return_credits(qup->__fastio_index, interval);
+ }
+}
+
+
+
/*
* Provide a linux buffer to LIPP.
*/
@@ -433,7 +448,7 @@ static bool tile_net_provide_needed_buffer(struct tile_net_cpu *info,
struct sk_buff **skb_ptr;
/* Request 96 extra bytes for alignment purposes. */
- skb = netdev_alloc_skb(info->napi->dev, len + padding);
+ skb = netdev_alloc_skb(info->napi.dev, len + padding);
if (skb == NULL)
return false;
@@ -864,19 +879,11 @@ static bool tile_net_poll_aux(struct tile_net_cpu *info, int index)
stats->rx_packets++;
stats->rx_bytes += len;
-
- if (small)
- info->num_needed_small_buffers++;
- else
- info->num_needed_large_buffers++;
}
- /* Return four credits after every fourth packet. */
- if (--qup->__receive_credit_remaining == 0) {
- u32 interval = qup->__receive_credit_interval;
- qup->__receive_credit_remaining = interval;
- __netio_fastio_return_credits(qup->__fastio_index, interval);
- }
+ /* ISSUE: It would be nice to defer this until the packet has */
+ /* actually been processed. */
+ tile_net_return_credit(info);
/* Consume this packet. */
qup->__packet_receive_read = index2;
@@ -1543,7 +1550,7 @@ static int tile_net_drain_lipp_buffers(struct tile_net_priv *priv)
/* Drain all the LIPP buffers. */
while (true) {
- int buffer;
+ unsigned int buffer;
/* NOTE: This should never fail. */
if (hv_dev_pread(priv->hv_devhdl, 0, (HV_VirtAddr)&buffer,
@@ -1707,7 +1714,7 @@ static unsigned int tile_net_tx_frags(lepp_frag_t *frags,
if (!hash_default) {
void *va = pfn_to_kaddr(pfn) + f->page_offset;
BUG_ON(PageHighMem(skb_frag_page(f)));
- finv_buffer_remote(va, f->size, 0);
+ finv_buffer_remote(va, skb_frag_size(f), 0);
}
cpa = ((phys_addr_t)pfn << PAGE_SHIFT) + f->page_offset;
@@ -1735,8 +1742,8 @@ static unsigned int tile_net_tx_frags(lepp_frag_t *frags,
* Sometimes, if "sendfile()" requires copying, we will be called with
* "data" containing the header and payload, with "frags" being empty.
*
- * In theory, "sh->nr_frags" could be 3, but in practice, it seems
- * that this will never actually happen.
+ * Sometimes, for example when using NFS over TCP, a single segment can
+ * span 3 fragments, which must be handled carefully in LEPP.
*
* See "emulate_large_send_offload()" for some reference code, which
* does not handle checksumming.
@@ -1844,10 +1851,8 @@ static int tile_net_tx_tso(struct sk_buff *skb, struct net_device *dev)
spin_lock_irqsave(&priv->eq_lock, irqflags);
- /*
- * Handle completions if needed to make room.
- * HACK: Spin until there is sufficient room.
- */
+ /* Handle completions if needed to make room. */
+ /* NOTE: Return NETDEV_TX_BUSY if there is still no room. */
if (lepp_num_free_comp_slots(eq) == 0) {
nolds = tile_net_lepp_grab_comps(eq, olds, wanted, 0);
if (nolds == 0) {
@@ -1861,6 +1866,7 @@ busy:
cmd_tail = eq->cmd_tail;
/* Prepare to advance, detecting full queue. */
+ /* NOTE: Return NETDEV_TX_BUSY if the queue is full. */
cmd_next = cmd_tail + cmd_size;
if (cmd_tail < cmd_head && cmd_next >= cmd_head)
goto busy;
@@ -2023,10 +2029,8 @@ static int tile_net_tx(struct sk_buff *skb, struct net_device *dev)
spin_lock_irqsave(&priv->eq_lock, irqflags);
- /*
- * Handle completions if needed to make room.
- * HACK: Spin until there is sufficient room.
- */
+ /* Handle completions if needed to make room. */
+ /* NOTE: Return NETDEV_TX_BUSY if there is still no room. */
if (lepp_num_free_comp_slots(eq) == 0) {
nolds = tile_net_lepp_grab_comps(eq, olds, wanted, 0);
if (nolds == 0) {
@@ -2040,6 +2044,7 @@ busy:
cmd_tail = eq->cmd_tail;
/* Copy the commands, or fail. */
+ /* NOTE: Return NETDEV_TX_BUSY if the queue is full. */
for (i = 0; i < num_frags; i++) {
/* Prepare to advance, detecting full queue. */
@@ -2261,6 +2266,23 @@ static int tile_net_get_mac(struct net_device *dev)
return 0;
}
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+/*
+ * Polling 'interrupt' - used by things like netconsole to send skbs
+ * without having to re-enable interrupts. It's not called while
+ * the interrupt routine is executing.
+ */
+static void tile_net_netpoll(struct net_device *dev)
+{
+ struct tile_net_priv *priv = netdev_priv(dev);
+ disable_percpu_irq(priv->intr_id);
+ tile_net_handle_ingress_interrupt(priv->intr_id, dev);
+ enable_percpu_irq(priv->intr_id, 0);
+}
+#endif
+
+
static const struct net_device_ops tile_net_ops = {
.ndo_open = tile_net_open,
.ndo_stop = tile_net_stop,
@@ -2269,7 +2291,10 @@ static const struct net_device_ops tile_net_ops = {
.ndo_get_stats = tile_net_get_stats,
.ndo_change_mtu = tile_net_change_mtu,
.ndo_tx_timeout = tile_net_tx_timeout,
- .ndo_set_mac_address = tile_net_set_mac_address
+ .ndo_set_mac_address = tile_net_set_mac_address,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = tile_net_netpoll,
+#endif
};
@@ -2409,7 +2434,7 @@ static void tile_net_cleanup(void)
*/
static int tile_net_init_module(void)
{
- pr_info("Tilera IPP Net Driver\n");
+ pr_info("Tilera Network Driver\n");
tile_net_devs[0] = tile_net_dev_init("xgbe0");
tile_net_devs[1] = tile_net_dev_init("xgbe1");
diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet.h b/drivers/net/ethernet/xilinx/xilinx_axienet.h
index cc83af083fd7..44b8d2bad8c3 100644
--- a/drivers/net/ethernet/xilinx/xilinx_axienet.h
+++ b/drivers/net/ethernet/xilinx/xilinx_axienet.h
@@ -2,9 +2,7 @@
* Definitions for Xilinx Axi Ethernet device driver.
*
* Copyright (c) 2009 Secret Lab Technologies, Ltd.
- * Copyright (c) 2010 Xilinx, Inc. All rights reserved.
- * Copyright (c) 2012 Daniel Borkmann, <daniel.borkmann@tik.ee.ethz.ch>
- * Copyright (c) 2012 Ariane Keller, <ariane.keller@tik.ee.ethz.ch>
+ * Copyright (c) 2010 - 2012 Xilinx, Inc. All rights reserved.
*/
#ifndef XILINX_AXIENET_H
diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
index 2fcbeba6814b..9c365e192a31 100644
--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
@@ -4,9 +4,9 @@
* Copyright (c) 2008 Nissin Systems Co., Ltd., Yoshio Kashiwagi
* Copyright (c) 2005-2008 DLA Systems, David H. Lynch Jr. <dhlii@dlasys.net>
* Copyright (c) 2008-2009 Secret Lab Technologies Ltd.
- * Copyright (c) 2010 Xilinx, Inc. All rights reserved.
- * Copyright (c) 2012 Daniel Borkmann, <daniel.borkmann@tik.ee.ethz.ch>
- * Copyright (c) 2012 Ariane Keller, <ariane.keller@tik.ee.ethz.ch>
+ * Copyright (c) 2010 - 2011 Michal Simek <monstr@monstr.eu>
+ * Copyright (c) 2010 - 2011 PetaLogix
+ * Copyright (c) 2010 - 2012 Xilinx, Inc. All rights reserved.
*
* This is a driver for the Xilinx Axi Ethernet which is used in the Virtex6
* and Spartan6.
diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c b/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c
index d70b6e79f6c0..e90e1f46121e 100644
--- a/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c
+++ b/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c
@@ -2,9 +2,9 @@
* MDIO bus driver for the Xilinx Axi Ethernet device
*
* Copyright (c) 2009 Secret Lab Technologies, Ltd.
- * Copyright (c) 2010 Xilinx, Inc. All rights reserved.
- * Copyright (c) 2012 Daniel Borkmann, <daniel.borkmann@tik.ee.ethz.ch>
- * Copyright (c) 2012 Ariane Keller, <ariane.keller@tik.ee.ethz.ch>
+ * Copyright (c) 2010 - 2011 Michal Simek <monstr@monstr.eu>
+ * Copyright (c) 2010 - 2011 PetaLogix
+ * Copyright (c) 2010 - 2012 Xilinx, Inc. All rights reserved.
*/
#include <linux/of_address.h>
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index dd294783b5c5..2d59138db7f3 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -44,6 +44,7 @@ struct net_device_context {
/* point back to our device context */
struct hv_device *device_ctx;
struct delayed_work dwork;
+ struct work_struct work;
};
@@ -51,30 +52,22 @@ static int ring_size = 128;
module_param(ring_size, int, S_IRUGO);
MODULE_PARM_DESC(ring_size, "Ring buffer size (# of pages)");
-struct set_multicast_work {
- struct work_struct work;
- struct net_device *net;
-};
-
static void do_set_multicast(struct work_struct *w)
{
- struct set_multicast_work *swk =
- container_of(w, struct set_multicast_work, work);
- struct net_device *net = swk->net;
-
- struct net_device_context *ndevctx = netdev_priv(net);
+ struct net_device_context *ndevctx =
+ container_of(w, struct net_device_context, work);
struct netvsc_device *nvdev;
struct rndis_device *rdev;
nvdev = hv_get_drvdata(ndevctx->device_ctx);
- if (nvdev == NULL)
- goto out;
+ if (nvdev == NULL || nvdev->ndev == NULL)
+ return;
rdev = nvdev->extension;
if (rdev == NULL)
- goto out;
+ return;
- if (net->flags & IFF_PROMISC)
+ if (nvdev->ndev->flags & IFF_PROMISC)
rndis_filter_set_packet_filter(rdev,
NDIS_PACKET_TYPE_PROMISCUOUS);
else
@@ -82,21 +75,13 @@ static void do_set_multicast(struct work_struct *w)
NDIS_PACKET_TYPE_BROADCAST |
NDIS_PACKET_TYPE_ALL_MULTICAST |
NDIS_PACKET_TYPE_DIRECTED);
-
-out:
- kfree(w);
}
static void netvsc_set_multicast_list(struct net_device *net)
{
- struct set_multicast_work *swk =
- kmalloc(sizeof(struct set_multicast_work), GFP_ATOMIC);
- if (swk == NULL)
- return;
+ struct net_device_context *net_device_ctx = netdev_priv(net);
- swk->net = net;
- INIT_WORK(&swk->work, do_set_multicast);
- schedule_work(&swk->work);
+ schedule_work(&net_device_ctx->work);
}
static int netvsc_open(struct net_device *net)
@@ -125,6 +110,8 @@ static int netvsc_close(struct net_device *net)
netif_tx_disable(net);
+ /* Make sure netvsc_set_multicast_list doesn't re-enable filter! */
+ cancel_work_sync(&net_device_ctx->work);
ret = rndis_filter_close(device_obj);
if (ret != 0)
netdev_err(net, "unable to close device (ret %d).\n", ret);
@@ -335,6 +322,7 @@ static int netvsc_change_mtu(struct net_device *ndev, int mtu)
nvdev->start_remove = true;
cancel_delayed_work_sync(&ndevctx->dwork);
+ cancel_work_sync(&ndevctx->work);
netif_tx_disable(ndev);
rndis_filter_device_remove(hdev);
@@ -403,6 +391,7 @@ static int netvsc_probe(struct hv_device *dev,
net_device_ctx->device_ctx = dev;
hv_set_drvdata(dev, net);
INIT_DELAYED_WORK(&net_device_ctx->dwork, netvsc_send_garp);
+ INIT_WORK(&net_device_ctx->work, do_set_multicast);
net->netdev_ops = &device_ops;
@@ -456,6 +445,7 @@ static int netvsc_remove(struct hv_device *dev)
ndev_ctx = netdev_priv(net);
cancel_delayed_work_sync(&ndev_ctx->dwork);
+ cancel_work_sync(&ndev_ctx->work);
/* Stop outbound asap */
netif_tx_disable(net);
diff --git a/drivers/net/phy/icplus.c b/drivers/net/phy/icplus.c
index 0856e1b7a849..5ac46f5226f3 100644
--- a/drivers/net/phy/icplus.c
+++ b/drivers/net/phy/icplus.c
@@ -40,6 +40,7 @@ MODULE_LICENSE("GPL");
#define IP1001_PHASE_SEL_MASK 3 /* IP1001 RX/TXPHASE_SEL */
#define IP1001_APS_ON 11 /* IP1001 APS Mode bit */
#define IP101A_G_APS_ON 2 /* IP101A/G APS Mode bit */
+#define IP101A_G_IRQ_CONF_STATUS 0x11 /* Conf Info IRQ & Status Reg */
static int ip175c_config_init(struct phy_device *phydev)
{
@@ -162,7 +163,8 @@ static int ip101a_g_config_init(struct phy_device *phydev)
/* Enable Auto Power Saving mode */
c = phy_read(phydev, IP10XX_SPEC_CTRL_STATUS);
c |= IP101A_G_APS_ON;
- return c;
+
+ return phy_write(phydev, IP10XX_SPEC_CTRL_STATUS, c);
}
static int ip175c_read_status(struct phy_device *phydev)
@@ -184,6 +186,15 @@ static int ip175c_config_aneg(struct phy_device *phydev)
return 0;
}
+static int ip101a_g_ack_interrupt(struct phy_device *phydev)
+{
+ int err = phy_read(phydev, IP101A_G_IRQ_CONF_STATUS);
+ if (err < 0)
+ return err;
+
+ return 0;
+}
+
static struct phy_driver ip175c_driver = {
.phy_id = 0x02430d80,
.name = "ICPlus IP175C",
@@ -203,7 +214,6 @@ static struct phy_driver ip1001_driver = {
.phy_id_mask = 0x0ffffff0,
.features = PHY_GBIT_FEATURES | SUPPORTED_Pause |
SUPPORTED_Asym_Pause,
- .flags = PHY_HAS_INTERRUPT,
.config_init = &ip1001_config_init,
.config_aneg = &genphy_config_aneg,
.read_status = &genphy_read_status,
@@ -219,6 +229,7 @@ static struct phy_driver ip101a_g_driver = {
.features = PHY_BASIC_FEATURES | SUPPORTED_Pause |
SUPPORTED_Asym_Pause,
.flags = PHY_HAS_INTERRUPT,
+ .ack_interrupt = ip101a_g_ack_interrupt,
.config_init = &ip101a_g_config_init,
.config_aneg = &genphy_config_aneg,
.read_status = &genphy_read_status,
diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c
index 159da2905fe9..21d7151fb0ab 100644
--- a/drivers/net/ppp/ppp_generic.c
+++ b/drivers/net/ppp/ppp_generic.c
@@ -968,7 +968,6 @@ ppp_start_xmit(struct sk_buff *skb, struct net_device *dev)
proto = npindex_to_proto[npi];
put_unaligned_be16(proto, pp);
- netif_stop_queue(dev);
skb_queue_tail(&ppp->file.xq, skb);
ppp_xmit_process(ppp);
return NETDEV_TX_OK;
@@ -1063,6 +1062,8 @@ ppp_xmit_process(struct ppp *ppp)
code that we can accept some more. */
if (!ppp->xmit_pending && !skb_peek(&ppp->file.xq))
netif_wake_queue(ppp->dev);
+ else
+ netif_stop_queue(ppp->dev);
}
ppp_xmit_unlock(ppp);
}
diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
index 552d24bf862e..d316503b35d4 100644
--- a/drivers/net/usb/qmi_wwan.c
+++ b/drivers/net/usb/qmi_wwan.c
@@ -365,6 +365,27 @@ static const struct driver_info qmi_wwan_force_int4 = {
.data = BIT(4), /* interface whitelist bitmap */
};
+/* Sierra Wireless provide equally useless interface descriptors
+ * Devices in QMI mode can be switched between two different
+ * configurations:
+ * a) USB interface #8 is QMI/wwan
+ * b) USB interfaces #8, #19 and #20 are QMI/wwan
+ *
+ * Both configurations provide a number of other interfaces (serial++),
+ * some of which have the same endpoint configuration as we expect, so
+ * a whitelist or blacklist is necessary.
+ *
+ * FIXME: The below whitelist should include BIT(20). It does not
+ * because I cannot get it to work...
+ */
+static const struct driver_info qmi_wwan_sierra = {
+ .description = "Sierra Wireless wwan/QMI device",
+ .flags = FLAG_WWAN,
+ .bind = qmi_wwan_bind_gobi,
+ .unbind = qmi_wwan_unbind_shared,
+ .manage_power = qmi_wwan_manage_power,
+ .data = BIT(8) | BIT(19), /* interface whitelist bitmap */
+};
#define HUAWEI_VENDOR_ID 0x12D1
#define QMI_GOBI_DEVICE(vend, prod) \
@@ -445,6 +466,15 @@ static const struct usb_device_id products[] = {
.bInterfaceProtocol = 0xff,
.driver_info = (unsigned long)&qmi_wwan_force_int4,
},
+ { /* Sierra Wireless MC77xx in QMI mode */
+ .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
+ .idVendor = 0x1199,
+ .idProduct = 0x68a2,
+ .bInterfaceClass = 0xff,
+ .bInterfaceSubClass = 0xff,
+ .bInterfaceProtocol = 0xff,
+ .driver_info = (unsigned long)&qmi_wwan_sierra,
+ },
{QMI_GOBI_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */
{QMI_GOBI_DEVICE(0x03f0, 0x1f1d)}, /* HP un2400 Gobi Modem Device */
{QMI_GOBI_DEVICE(0x03f0, 0x371d)}, /* HP un2430 Mobile Broadband Module */
diff --git a/drivers/net/usb/smsc75xx.c b/drivers/net/usb/smsc75xx.c
index 187d01ccb973..a2349483cd2a 100644
--- a/drivers/net/usb/smsc75xx.c
+++ b/drivers/net/usb/smsc75xx.c
@@ -1051,6 +1051,7 @@ static int smsc75xx_bind(struct usbnet *dev, struct usb_interface *intf)
dev->net->ethtool_ops = &smsc75xx_ethtool_ops;
dev->net->flags |= IFF_MULTICAST;
dev->net->hard_header_len += SMSC75XX_TX_OVERHEAD;
+ dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len;
return 0;
}
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 4de2760c5937..af8acc85f4bb 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -626,16 +626,15 @@ static netdev_tx_t start_xmit(struct sk_buff *skb, struct net_device *dev)
/* This can happen with OOM and indirect buffers. */
if (unlikely(capacity < 0)) {
if (likely(capacity == -ENOMEM)) {
- if (net_ratelimit()) {
+ if (net_ratelimit())
dev_warn(&dev->dev,
"TX queue failure: out of memory\n");
- } else {
+ } else {
dev->stats.tx_fifo_errors++;
if (net_ratelimit())
dev_warn(&dev->dev,
"Unexpected TX queue failure: %d\n",
capacity);
- }
}
dev->stats.tx_dropped++;
kfree_skb(skb);
diff --git a/drivers/net/wan/farsync.c b/drivers/net/wan/farsync.c
index ebb9f24eefb5..1a623183cbe5 100644
--- a/drivers/net/wan/farsync.c
+++ b/drivers/net/wan/farsync.c
@@ -2483,6 +2483,7 @@ fst_add_one(struct pci_dev *pdev, const struct pci_device_id *ent)
pr_err("Control memory remap failed\n");
pci_release_regions(pdev);
pci_disable_device(pdev);
+ iounmap(card->mem);
kfree(card);
return -ENODEV;
}
diff --git a/drivers/net/wimax/i2400m/debugfs.c b/drivers/net/wimax/i2400m/debugfs.c
index 129ba36bd04d..4b66ab1d0e5c 100644
--- a/drivers/net/wimax/i2400m/debugfs.c
+++ b/drivers/net/wimax/i2400m/debugfs.c
@@ -53,17 +53,6 @@ struct dentry *debugfs_create_netdev_queue_stopped(
&fops_netdev_queue_stopped);
}
-
-/*
- * inode->i_private has the @data argument to debugfs_create_file()
- */
-static
-int i2400m_stats_open(struct inode *inode, struct file *filp)
-{
- filp->private_data = inode->i_private;
- return 0;
-}
-
/*
* We don't allow partial reads of this file, as then the reader would
* get weirdly confused data as it is updated.
@@ -117,7 +106,7 @@ ssize_t i2400m_rx_stats_write(struct file *filp, const char __user *buffer,
static
const struct file_operations i2400m_rx_stats_fops = {
.owner = THIS_MODULE,
- .open = i2400m_stats_open,
+ .open = simple_open,
.read = i2400m_rx_stats_read,
.write = i2400m_rx_stats_write,
.llseek = default_llseek,
@@ -170,7 +159,7 @@ ssize_t i2400m_tx_stats_write(struct file *filp, const char __user *buffer,
static
const struct file_operations i2400m_tx_stats_fops = {
.owner = THIS_MODULE,
- .open = i2400m_stats_open,
+ .open = simple_open,
.read = i2400m_tx_stats_read,
.write = i2400m_tx_stats_write,
.llseek = default_llseek,
diff --git a/drivers/net/wireless/ath/ath5k/ahb.c b/drivers/net/wireless/ath/ath5k/ahb.c
index 8faa129da5a0..8c50d9d19d78 100644
--- a/drivers/net/wireless/ath/ath5k/ahb.c
+++ b/drivers/net/wireless/ath/ath5k/ahb.c
@@ -19,6 +19,7 @@
#include <linux/nl80211.h>
#include <linux/platform_device.h>
#include <linux/etherdevice.h>
+#include <linux/export.h>
#include <ar231x_platform.h>
#include "ath5k.h"
#include "debug.h"
@@ -119,7 +120,7 @@ static int ath_ahb_probe(struct platform_device *pdev)
if (res == NULL) {
dev_err(&pdev->dev, "no IRQ resource found\n");
ret = -ENXIO;
- goto err_out;
+ goto err_iounmap;
}
irq = res->start;
@@ -128,7 +129,7 @@ static int ath_ahb_probe(struct platform_device *pdev)
if (hw == NULL) {
dev_err(&pdev->dev, "no memory for ieee80211_hw\n");
ret = -ENOMEM;
- goto err_out;
+ goto err_iounmap;
}
ah = hw->priv;
@@ -185,6 +186,8 @@ static int ath_ahb_probe(struct platform_device *pdev)
err_free_hw:
ieee80211_free_hw(hw);
platform_set_drvdata(pdev, NULL);
+ err_iounmap:
+ iounmap(mem);
err_out:
return ret;
}
diff --git a/drivers/net/wireless/ath/ath5k/debug.c b/drivers/net/wireless/ath/ath5k/debug.c
index 8c5ce8b0c734..e5e8f45d86ac 100644
--- a/drivers/net/wireless/ath/ath5k/debug.c
+++ b/drivers/net/wireless/ath/ath5k/debug.c
@@ -71,13 +71,6 @@ static unsigned int ath5k_debug;
module_param_named(debug, ath5k_debug, uint, 0);
-static int ath5k_debugfs_open(struct inode *inode, struct file *file)
-{
- file->private_data = inode->i_private;
- return 0;
-}
-
-
/* debugfs: registers */
struct reg {
@@ -265,7 +258,7 @@ static ssize_t write_file_beacon(struct file *file,
static const struct file_operations fops_beacon = {
.read = read_file_beacon,
.write = write_file_beacon,
- .open = ath5k_debugfs_open,
+ .open = simple_open,
.owner = THIS_MODULE,
.llseek = default_llseek,
};
@@ -285,7 +278,7 @@ static ssize_t write_file_reset(struct file *file,
static const struct file_operations fops_reset = {
.write = write_file_reset,
- .open = ath5k_debugfs_open,
+ .open = simple_open,
.owner = THIS_MODULE,
.llseek = noop_llseek,
};
@@ -365,7 +358,7 @@ static ssize_t write_file_debug(struct file *file,
static const struct file_operations fops_debug = {
.read = read_file_debug,
.write = write_file_debug,
- .open = ath5k_debugfs_open,
+ .open = simple_open,
.owner = THIS_MODULE,
.llseek = default_llseek,
};
@@ -477,7 +470,7 @@ static ssize_t write_file_antenna(struct file *file,
static const struct file_operations fops_antenna = {
.read = read_file_antenna,
.write = write_file_antenna,
- .open = ath5k_debugfs_open,
+ .open = simple_open,
.owner = THIS_MODULE,
.llseek = default_llseek,
};
@@ -532,7 +525,7 @@ static ssize_t read_file_misc(struct file *file, char __user *user_buf,
static const struct file_operations fops_misc = {
.read = read_file_misc,
- .open = ath5k_debugfs_open,
+ .open = simple_open,
.owner = THIS_MODULE,
};
@@ -647,7 +640,7 @@ static ssize_t write_file_frameerrors(struct file *file,
static const struct file_operations fops_frameerrors = {
.read = read_file_frameerrors,
.write = write_file_frameerrors,
- .open = ath5k_debugfs_open,
+ .open = simple_open,
.owner = THIS_MODULE,
.llseek = default_llseek,
};
@@ -810,7 +803,7 @@ static ssize_t write_file_ani(struct file *file,
static const struct file_operations fops_ani = {
.read = read_file_ani,
.write = write_file_ani,
- .open = ath5k_debugfs_open,
+ .open = simple_open,
.owner = THIS_MODULE,
.llseek = default_llseek,
};
@@ -881,7 +874,7 @@ static ssize_t write_file_queue(struct file *file,
static const struct file_operations fops_queue = {
.read = read_file_queue,
.write = write_file_queue,
- .open = ath5k_debugfs_open,
+ .open = simple_open,
.owner = THIS_MODULE,
.llseek = default_llseek,
};
diff --git a/drivers/net/wireless/ath/ath6kl/debug.c b/drivers/net/wireless/ath/ath6kl/debug.c
index 552adb3f80d0..d01403a263ff 100644
--- a/drivers/net/wireless/ath/ath6kl/debug.c
+++ b/drivers/net/wireless/ath/ath6kl/debug.c
@@ -217,12 +217,6 @@ void dump_cred_dist_stats(struct htc_target *target)
target->credit_info->cur_free_credits);
}
-static int ath6kl_debugfs_open(struct inode *inode, struct file *file)
-{
- file->private_data = inode->i_private;
- return 0;
-}
-
void ath6kl_debug_war(struct ath6kl *ar, enum ath6kl_war war)
{
switch (war) {
@@ -263,7 +257,7 @@ static ssize_t read_file_war_stats(struct file *file, char __user *user_buf,
static const struct file_operations fops_war_stats = {
.read = read_file_war_stats,
- .open = ath6kl_debugfs_open,
+ .open = simple_open,
.owner = THIS_MODULE,
.llseek = default_llseek,
};
@@ -488,7 +482,7 @@ static ssize_t ath6kl_fwlog_mask_write(struct file *file,
}
static const struct file_operations fops_fwlog_mask = {
- .open = ath6kl_debugfs_open,
+ .open = simple_open,
.read = ath6kl_fwlog_mask_read,
.write = ath6kl_fwlog_mask_write,
.owner = THIS_MODULE,
@@ -634,7 +628,7 @@ static ssize_t read_file_tgt_stats(struct file *file, char __user *user_buf,
static const struct file_operations fops_tgt_stats = {
.read = read_file_tgt_stats,
- .open = ath6kl_debugfs_open,
+ .open = simple_open,
.owner = THIS_MODULE,
.llseek = default_llseek,
};
@@ -699,7 +693,7 @@ static ssize_t read_file_credit_dist_stats(struct file *file,
static const struct file_operations fops_credit_dist_stats = {
.read = read_file_credit_dist_stats,
- .open = ath6kl_debugfs_open,
+ .open = simple_open,
.owner = THIS_MODULE,
.llseek = default_llseek,
};
@@ -802,7 +796,7 @@ static ssize_t ath6kl_endpoint_stats_write(struct file *file,
}
static const struct file_operations fops_endpoint_stats = {
- .open = ath6kl_debugfs_open,
+ .open = simple_open,
.read = ath6kl_endpoint_stats_read,
.write = ath6kl_endpoint_stats_write,
.owner = THIS_MODULE,
@@ -875,7 +869,7 @@ static ssize_t ath6kl_regread_write(struct file *file,
static const struct file_operations fops_diag_reg_read = {
.read = ath6kl_regread_read,
.write = ath6kl_regread_write,
- .open = ath6kl_debugfs_open,
+ .open = simple_open,
.owner = THIS_MODULE,
.llseek = default_llseek,
};
@@ -999,7 +993,7 @@ static ssize_t ath6kl_lrssi_roam_read(struct file *file,
static const struct file_operations fops_lrssi_roam_threshold = {
.read = ath6kl_lrssi_roam_read,
.write = ath6kl_lrssi_roam_write,
- .open = ath6kl_debugfs_open,
+ .open = simple_open,
.owner = THIS_MODULE,
.llseek = default_llseek,
};
@@ -1061,7 +1055,7 @@ static ssize_t ath6kl_regwrite_write(struct file *file,
static const struct file_operations fops_diag_reg_write = {
.read = ath6kl_regwrite_read,
.write = ath6kl_regwrite_write,
- .open = ath6kl_debugfs_open,
+ .open = simple_open,
.owner = THIS_MODULE,
.llseek = default_llseek,
};
@@ -1166,7 +1160,7 @@ static ssize_t ath6kl_roam_table_read(struct file *file, char __user *user_buf,
static const struct file_operations fops_roam_table = {
.read = ath6kl_roam_table_read,
- .open = ath6kl_debugfs_open,
+ .open = simple_open,
.owner = THIS_MODULE,
.llseek = default_llseek,
};
@@ -1204,7 +1198,7 @@ static ssize_t ath6kl_force_roam_write(struct file *file,
static const struct file_operations fops_force_roam = {
.write = ath6kl_force_roam_write,
- .open = ath6kl_debugfs_open,
+ .open = simple_open,
.owner = THIS_MODULE,
.llseek = default_llseek,
};
@@ -1244,7 +1238,7 @@ static ssize_t ath6kl_roam_mode_write(struct file *file,
static const struct file_operations fops_roam_mode = {
.write = ath6kl_roam_mode_write,
- .open = ath6kl_debugfs_open,
+ .open = simple_open,
.owner = THIS_MODULE,
.llseek = default_llseek,
};
@@ -1286,7 +1280,7 @@ static ssize_t ath6kl_keepalive_write(struct file *file,
}
static const struct file_operations fops_keepalive = {
- .open = ath6kl_debugfs_open,
+ .open = simple_open,
.read = ath6kl_keepalive_read,
.write = ath6kl_keepalive_write,
.owner = THIS_MODULE,
@@ -1331,7 +1325,7 @@ static ssize_t ath6kl_disconnect_timeout_write(struct file *file,
}
static const struct file_operations fops_disconnect_timeout = {
- .open = ath6kl_debugfs_open,
+ .open = simple_open,
.read = ath6kl_disconnect_timeout_read,
.write = ath6kl_disconnect_timeout_write,
.owner = THIS_MODULE,
@@ -1512,7 +1506,7 @@ static ssize_t ath6kl_create_qos_write(struct file *file,
static const struct file_operations fops_create_qos = {
.write = ath6kl_create_qos_write,
- .open = ath6kl_debugfs_open,
+ .open = simple_open,
.owner = THIS_MODULE,
.llseek = default_llseek,
};
@@ -1560,7 +1554,7 @@ static ssize_t ath6kl_delete_qos_write(struct file *file,
static const struct file_operations fops_delete_qos = {
.write = ath6kl_delete_qos_write,
- .open = ath6kl_debugfs_open,
+ .open = simple_open,
.owner = THIS_MODULE,
.llseek = default_llseek,
};
@@ -1593,7 +1587,7 @@ static ssize_t ath6kl_bgscan_int_write(struct file *file,
static const struct file_operations fops_bgscan_int = {
.write = ath6kl_bgscan_int_write,
- .open = ath6kl_debugfs_open,
+ .open = simple_open,
.owner = THIS_MODULE,
.llseek = default_llseek,
};
@@ -1651,7 +1645,7 @@ static ssize_t ath6kl_listen_int_read(struct file *file,
static const struct file_operations fops_listen_int = {
.read = ath6kl_listen_int_read,
.write = ath6kl_listen_int_write,
- .open = ath6kl_debugfs_open,
+ .open = simple_open,
.owner = THIS_MODULE,
.llseek = default_llseek,
};
@@ -1711,7 +1705,7 @@ static ssize_t ath6kl_power_params_write(struct file *file,
static const struct file_operations fops_power_params = {
.write = ath6kl_power_params_write,
- .open = ath6kl_debugfs_open,
+ .open = simple_open,
.owner = THIS_MODULE,
.llseek = default_llseek,
};
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index 35d1c8e91d1c..ff47b32ecaf4 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -26,11 +26,6 @@
#define REG_READ_D(_ah, _reg) \
ath9k_hw_common(_ah)->ops->read((_ah), (_reg))
-static int ath9k_debugfs_open(struct inode *inode, struct file *file)
-{
- file->private_data = inode->i_private;
- return 0;
-}
static ssize_t ath9k_debugfs_read_buf(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
@@ -83,7 +78,7 @@ static ssize_t write_file_debug(struct file *file, const char __user *user_buf,
static const struct file_operations fops_debug = {
.read = read_file_debug,
.write = write_file_debug,
- .open = ath9k_debugfs_open,
+ .open = simple_open,
.owner = THIS_MODULE,
.llseek = default_llseek,
};
@@ -129,7 +124,7 @@ static ssize_t write_file_tx_chainmask(struct file *file, const char __user *use
static const struct file_operations fops_tx_chainmask = {
.read = read_file_tx_chainmask,
.write = write_file_tx_chainmask,
- .open = ath9k_debugfs_open,
+ .open = simple_open,
.owner = THIS_MODULE,
.llseek = default_llseek,
};
@@ -172,7 +167,7 @@ static ssize_t write_file_rx_chainmask(struct file *file, const char __user *use
static const struct file_operations fops_rx_chainmask = {
.read = read_file_rx_chainmask,
.write = write_file_rx_chainmask,
- .open = ath9k_debugfs_open,
+ .open = simple_open,
.owner = THIS_MODULE,
.llseek = default_llseek,
};
@@ -223,7 +218,7 @@ static ssize_t write_file_disable_ani(struct file *file,
static const struct file_operations fops_disable_ani = {
.read = read_file_disable_ani,
.write = write_file_disable_ani,
- .open = ath9k_debugfs_open,
+ .open = simple_open,
.owner = THIS_MODULE,
.llseek = default_llseek,
};
@@ -324,7 +319,7 @@ static ssize_t read_file_dma(struct file *file, char __user *user_buf,
static const struct file_operations fops_dma = {
.read = read_file_dma,
- .open = ath9k_debugfs_open,
+ .open = simple_open,
.owner = THIS_MODULE,
.llseek = default_llseek,
};
@@ -446,7 +441,7 @@ static ssize_t read_file_interrupt(struct file *file, char __user *user_buf,
static const struct file_operations fops_interrupt = {
.read = read_file_interrupt,
- .open = ath9k_debugfs_open,
+ .open = simple_open,
.owner = THIS_MODULE,
.llseek = default_llseek,
};
@@ -852,28 +847,28 @@ void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf,
static const struct file_operations fops_xmit = {
.read = read_file_xmit,
- .open = ath9k_debugfs_open,
+ .open = simple_open,
.owner = THIS_MODULE,
.llseek = default_llseek,
};
static const struct file_operations fops_stations = {
.read = read_file_stations,
- .open = ath9k_debugfs_open,
+ .open = simple_open,
.owner = THIS_MODULE,
.llseek = default_llseek,
};
static const struct file_operations fops_misc = {
.read = read_file_misc,
- .open = ath9k_debugfs_open,
+ .open = simple_open,
.owner = THIS_MODULE,
.llseek = default_llseek,
};
static const struct file_operations fops_reset = {
.read = read_file_reset,
- .open = ath9k_debugfs_open,
+ .open = simple_open,
.owner = THIS_MODULE,
.llseek = default_llseek,
};
@@ -1016,7 +1011,7 @@ void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs)
static const struct file_operations fops_recv = {
.read = read_file_recv,
- .open = ath9k_debugfs_open,
+ .open = simple_open,
.owner = THIS_MODULE,
.llseek = default_llseek,
};
@@ -1055,7 +1050,7 @@ static ssize_t write_file_regidx(struct file *file, const char __user *user_buf,
static const struct file_operations fops_regidx = {
.read = read_file_regidx,
.write = write_file_regidx,
- .open = ath9k_debugfs_open,
+ .open = simple_open,
.owner = THIS_MODULE,
.llseek = default_llseek,
};
@@ -1102,7 +1097,7 @@ static ssize_t write_file_regval(struct file *file, const char __user *user_buf,
static const struct file_operations fops_regval = {
.read = read_file_regval,
.write = write_file_regval,
- .open = ath9k_debugfs_open,
+ .open = simple_open,
.owner = THIS_MODULE,
.llseek = default_llseek,
};
@@ -1191,7 +1186,7 @@ static ssize_t read_file_dump_nfcal(struct file *file, char __user *user_buf,
static const struct file_operations fops_dump_nfcal = {
.read = read_file_dump_nfcal,
- .open = ath9k_debugfs_open,
+ .open = simple_open,
.owner = THIS_MODULE,
.llseek = default_llseek,
};
@@ -1219,7 +1214,7 @@ static ssize_t read_file_base_eeprom(struct file *file, char __user *user_buf,
static const struct file_operations fops_base_eeprom = {
.read = read_file_base_eeprom,
- .open = ath9k_debugfs_open,
+ .open = simple_open,
.owner = THIS_MODULE,
.llseek = default_llseek,
};
@@ -1247,7 +1242,7 @@ static ssize_t read_file_modal_eeprom(struct file *file, char __user *user_buf,
static const struct file_operations fops_modal_eeprom = {
.read = read_file_modal_eeprom,
- .open = ath9k_debugfs_open,
+ .open = simple_open,
.owner = THIS_MODULE,
.llseek = default_llseek,
};
diff --git a/drivers/net/wireless/ath/ath9k/dfs_debug.c b/drivers/net/wireless/ath/ath9k/dfs_debug.c
index 106d031d834a..4364c103ed33 100644
--- a/drivers/net/wireless/ath/ath9k/dfs_debug.c
+++ b/drivers/net/wireless/ath/ath9k/dfs_debug.c
@@ -60,16 +60,9 @@ static ssize_t read_file_dfs(struct file *file, char __user *user_buf,
return retval;
}
-static int ath9k_dfs_debugfs_open(struct inode *inode, struct file *file)
-{
- file->private_data = inode->i_private;
-
- return 0;
-}
-
static const struct file_operations fops_dfs_stats = {
.read = read_file_dfs,
- .open = ath9k_dfs_debugfs_open,
+ .open = simple_open,
.owner = THIS_MODULE,
.llseek = default_llseek,
};
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c
index d3ff33c71aa5..3035deb7a0cd 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c
@@ -16,12 +16,6 @@
#include "htc.h"
-static int ath9k_debugfs_open(struct inode *inode, struct file *file)
-{
- file->private_data = inode->i_private;
- return 0;
-}
-
static ssize_t read_file_tgt_int_stats(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
@@ -75,7 +69,7 @@ static ssize_t read_file_tgt_int_stats(struct file *file, char __user *user_buf,
static const struct file_operations fops_tgt_int_stats = {
.read = read_file_tgt_int_stats,
- .open = ath9k_debugfs_open,
+ .open = simple_open,
.owner = THIS_MODULE,
.llseek = default_llseek,
};
@@ -145,7 +139,7 @@ static ssize_t read_file_tgt_tx_stats(struct file *file, char __user *user_buf,
static const struct file_operations fops_tgt_tx_stats = {
.read = read_file_tgt_tx_stats,
- .open = ath9k_debugfs_open,
+ .open = simple_open,
.owner = THIS_MODULE,
.llseek = default_llseek,
};
@@ -191,7 +185,7 @@ static ssize_t read_file_tgt_rx_stats(struct file *file, char __user *user_buf,
static const struct file_operations fops_tgt_rx_stats = {
.read = read_file_tgt_rx_stats,
- .open = ath9k_debugfs_open,
+ .open = simple_open,
.owner = THIS_MODULE,
.llseek = default_llseek,
};
@@ -243,7 +237,7 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
static const struct file_operations fops_xmit = {
.read = read_file_xmit,
- .open = ath9k_debugfs_open,
+ .open = simple_open,
.owner = THIS_MODULE,
.llseek = default_llseek,
};
@@ -364,7 +358,7 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf,
static const struct file_operations fops_recv = {
.read = read_file_recv,
- .open = ath9k_debugfs_open,
+ .open = simple_open,
.owner = THIS_MODULE,
.llseek = default_llseek,
};
@@ -399,7 +393,7 @@ static ssize_t read_file_slot(struct file *file, char __user *user_buf,
static const struct file_operations fops_slot = {
.read = read_file_slot,
- .open = ath9k_debugfs_open,
+ .open = simple_open,
.owner = THIS_MODULE,
.llseek = default_llseek,
};
@@ -446,7 +440,7 @@ static ssize_t read_file_queue(struct file *file, char __user *user_buf,
static const struct file_operations fops_queue = {
.read = read_file_queue,
- .open = ath9k_debugfs_open,
+ .open = simple_open,
.owner = THIS_MODULE,
.llseek = default_llseek,
};
@@ -487,7 +481,7 @@ static ssize_t write_file_debug(struct file *file, const char __user *user_buf,
static const struct file_operations fops_debug = {
.read = read_file_debug,
.write = write_file_debug,
- .open = ath9k_debugfs_open,
+ .open = simple_open,
.owner = THIS_MODULE,
.llseek = default_llseek,
};
@@ -636,7 +630,7 @@ static ssize_t read_file_base_eeprom(struct file *file, char __user *user_buf,
static const struct file_operations fops_base_eeprom = {
.read = read_file_base_eeprom,
- .open = ath9k_debugfs_open,
+ .open = simple_open,
.owner = THIS_MODULE,
.llseek = default_llseek,
};
@@ -917,7 +911,7 @@ static ssize_t read_file_modal_eeprom(struct file *file, char __user *user_buf,
static const struct file_operations fops_modal_eeprom = {
.read = read_file_modal_eeprom,
- .open = ath9k_debugfs_open,
+ .open = simple_open,
.owner = THIS_MODULE,
.llseek = default_llseek,
};
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 215eb2536b1e..798ea57252b4 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -118,15 +118,13 @@ void ath9k_ps_restore(struct ath_softc *sc)
if (--sc->ps_usecount != 0)
goto unlock;
- if (sc->ps_flags & PS_WAIT_FOR_TX_ACK)
- goto unlock;
-
- if (sc->ps_idle)
+ if (sc->ps_idle && (sc->ps_flags & PS_WAIT_FOR_TX_ACK))
mode = ATH9K_PM_FULL_SLEEP;
else if (sc->ps_enabled &&
!(sc->ps_flags & (PS_WAIT_FOR_BEACON |
PS_WAIT_FOR_CAB |
- PS_WAIT_FOR_PSPOLL_DATA)))
+ PS_WAIT_FOR_PSPOLL_DATA |
+ PS_WAIT_FOR_TX_ACK)))
mode = ATH9K_PM_NETWORK_SLEEP;
else
goto unlock;
@@ -1550,6 +1548,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
struct ath_hw *ah = sc->sc_ah;
struct ath_common *common = ath9k_hw_common(ah);
struct ieee80211_conf *conf = &hw->conf;
+ bool reset_channel = false;
ath9k_ps_wakeup(sc);
mutex_lock(&sc->mutex);
@@ -1558,6 +1557,12 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
sc->ps_idle = !!(conf->flags & IEEE80211_CONF_IDLE);
if (sc->ps_idle)
ath_cancel_work(sc);
+ else
+ /*
+ * The chip needs a reset to properly wake up from
+ * full sleep
+ */
+ reset_channel = ah->chip_fullsleep;
}
/*
@@ -1586,7 +1591,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
}
}
- if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
+ if ((changed & IEEE80211_CONF_CHANGE_CHANNEL) || reset_channel) {
struct ieee80211_channel *curchan = hw->conf.channel;
int pos = curchan->hw_value;
int old_pos = -1;
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c
index 4f848493fece..08bb45532701 100644
--- a/drivers/net/wireless/ath/ath9k/rc.c
+++ b/drivers/net/wireless/ath/ath9k/rc.c
@@ -1480,12 +1480,6 @@ static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband,
#ifdef CONFIG_ATH9K_DEBUGFS
-static int ath9k_debugfs_open(struct inode *inode, struct file *file)
-{
- file->private_data = inode->i_private;
- return 0;
-}
-
static ssize_t read_file_rcstat(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
@@ -1553,7 +1547,7 @@ static ssize_t read_file_rcstat(struct file *file, char __user *user_buf,
static const struct file_operations fops_rcstat = {
.read = read_file_rcstat,
- .open = ath9k_debugfs_open,
+ .open = simple_open,
.owner = THIS_MODULE
};
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 834e6bc45e8b..23eaa1b26ebe 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -1820,6 +1820,7 @@ static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc,
struct ath_frame_info *fi = get_frame_info(skb);
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
struct ath_buf *bf;
+ int fragno;
u16 seqno;
bf = ath_tx_get_buffer(sc);
@@ -1831,9 +1832,16 @@ static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc,
ATH_TXBUF_RESET(bf);
if (tid) {
+ fragno = le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG;
seqno = tid->seq_next;
hdr->seq_ctrl = cpu_to_le16(tid->seq_next << IEEE80211_SEQ_SEQ_SHIFT);
- INCR(tid->seq_next, IEEE80211_SEQ_MAX);
+
+ if (fragno)
+ hdr->seq_ctrl |= cpu_to_le16(fragno);
+
+ if (!ieee80211_has_morefrags(hdr->frame_control))
+ INCR(tid->seq_next, IEEE80211_SEQ_MAX);
+
bf->bf_state.seqno = seqno;
}
diff --git a/drivers/net/wireless/ath/carl9170/debug.c b/drivers/net/wireless/ath/carl9170/debug.c
index 3c164226687f..93fe6003a493 100644
--- a/drivers/net/wireless/ath/carl9170/debug.c
+++ b/drivers/net/wireless/ath/carl9170/debug.c
@@ -48,11 +48,6 @@
#define ADD(buf, off, max, fmt, args...) \
off += snprintf(&buf[off], max - off, fmt, ##args);
-static int carl9170_debugfs_open(struct inode *inode, struct file *file)
-{
- file->private_data = inode->i_private;
- return 0;
-}
struct carl9170_debugfs_fops {
unsigned int read_bufsize;
@@ -178,7 +173,7 @@ static const struct carl9170_debugfs_fops carl_debugfs_##name ##_ops = {\
.attr = _attr, \
.req_dev_state = _dstate, \
.fops = { \
- .open = carl9170_debugfs_open, \
+ .open = simple_open, \
.read = carl9170_debugfs_read, \
.write = carl9170_debugfs_write, \
.owner = THIS_MODULE \
diff --git a/drivers/net/wireless/b43/debugfs.c b/drivers/net/wireless/b43/debugfs.c
index e751fdee89b2..e807bd930647 100644
--- a/drivers/net/wireless/b43/debugfs.c
+++ b/drivers/net/wireless/b43/debugfs.c
@@ -500,12 +500,6 @@ out:
#undef fappend
-static int b43_debugfs_open(struct inode *inode, struct file *file)
-{
- file->private_data = inode->i_private;
- return 0;
-}
-
static ssize_t b43_debugfs_read(struct file *file, char __user *userbuf,
size_t count, loff_t *ppos)
{
@@ -624,7 +618,7 @@ out_unlock:
.read = _read, \
.write = _write, \
.fops = { \
- .open = b43_debugfs_open, \
+ .open = simple_open, \
.read = b43_debugfs_read, \
.write = b43_debugfs_write, \
.llseek = generic_file_llseek, \
diff --git a/drivers/net/wireless/b43legacy/debugfs.c b/drivers/net/wireless/b43legacy/debugfs.c
index 5e28ad0d6d17..1965edb765a2 100644
--- a/drivers/net/wireless/b43legacy/debugfs.c
+++ b/drivers/net/wireless/b43legacy/debugfs.c
@@ -197,12 +197,6 @@ static int restart_write_file(struct b43legacy_wldev *dev, const char *buf, size
#undef fappend
-static int b43legacy_debugfs_open(struct inode *inode, struct file *file)
-{
- file->private_data = inode->i_private;
- return 0;
-}
-
static ssize_t b43legacy_debugfs_read(struct file *file, char __user *userbuf,
size_t count, loff_t *ppos)
{
@@ -331,7 +325,7 @@ out_unlock:
.read = _read, \
.write = _write, \
.fops = { \
- .open = b43legacy_debugfs_open, \
+ .open = simple_open, \
.read = b43legacy_debugfs_read, \
.write = b43legacy_debugfs_write, \
.llseek = generic_file_llseek, \
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c
index 231ddf4a674f..7083db75b00c 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
@@ -7614,6 +7614,7 @@ brcms_c_recvctl(struct brcms_c_info *wlc, struct d11rxhdr *rxh,
{
int len_mpdu;
struct ieee80211_rx_status rx_status;
+ struct ieee80211_hdr *hdr;
memset(&rx_status, 0, sizeof(rx_status));
prep_mac80211_status(wlc, rxh, p, &rx_status);
@@ -7623,6 +7624,13 @@ brcms_c_recvctl(struct brcms_c_info *wlc, struct d11rxhdr *rxh,
skb_pull(p, D11_PHY_HDR_LEN);
__skb_trim(p, len_mpdu);
+ /* unmute transmit */
+ if (wlc->hw->suspended_fifos) {
+ hdr = (struct ieee80211_hdr *)p->data;
+ if (ieee80211_is_beacon(hdr->frame_control))
+ brcms_b_mute(wlc->hw, false);
+ }
+
memcpy(IEEE80211_SKB_RXCB(p), &rx_status, sizeof(rx_status));
ieee80211_rx_irqsafe(wlc->pub->ieee_hw, p);
}
diff --git a/drivers/net/wireless/iwlegacy/3945-rs.c b/drivers/net/wireless/iwlegacy/3945-rs.c
index 70bee1a4d876..4b10157d8686 100644
--- a/drivers/net/wireless/iwlegacy/3945-rs.c
+++ b/drivers/net/wireless/iwlegacy/3945-rs.c
@@ -821,12 +821,6 @@ out:
}
#ifdef CONFIG_MAC80211_DEBUGFS
-static int
-il3945_open_file_generic(struct inode *inode, struct file *file)
-{
- file->private_data = inode->i_private;
- return 0;
-}
static ssize_t
il3945_sta_dbgfs_stats_table_read(struct file *file, char __user *user_buf,
@@ -862,7 +856,7 @@ il3945_sta_dbgfs_stats_table_read(struct file *file, char __user *user_buf,
static const struct file_operations rs_sta_dbgfs_stats_table_ops = {
.read = il3945_sta_dbgfs_stats_table_read,
- .open = il3945_open_file_generic,
+ .open = simple_open,
.llseek = default_llseek,
};
diff --git a/drivers/net/wireless/iwlegacy/4965-rs.c b/drivers/net/wireless/iwlegacy/4965-rs.c
index d7e2856e41d3..11ab1247fae1 100644
--- a/drivers/net/wireless/iwlegacy/4965-rs.c
+++ b/drivers/net/wireless/iwlegacy/4965-rs.c
@@ -2518,12 +2518,6 @@ il4965_rs_free_sta(void *il_r, struct ieee80211_sta *sta, void *il_sta)
}
#ifdef CONFIG_MAC80211_DEBUGFS
-static int
-il4965_open_file_generic(struct inode *inode, struct file *file)
-{
- file->private_data = inode->i_private;
- return 0;
-}
static void
il4965_rs_dbgfs_set_mcs(struct il_lq_sta *lq_sta, u32 * rate_n_flags, int idx)
@@ -2695,7 +2689,7 @@ il4965_rs_sta_dbgfs_scale_table_read(struct file *file, char __user *user_buf,
static const struct file_operations rs_sta_dbgfs_scale_table_ops = {
.write = il4965_rs_sta_dbgfs_scale_table_write,
.read = il4965_rs_sta_dbgfs_scale_table_read,
- .open = il4965_open_file_generic,
+ .open = simple_open,
.llseek = default_llseek,
};
@@ -2740,7 +2734,7 @@ il4965_rs_sta_dbgfs_stats_table_read(struct file *file, char __user *user_buf,
static const struct file_operations rs_sta_dbgfs_stats_table_ops = {
.read = il4965_rs_sta_dbgfs_stats_table_read,
- .open = il4965_open_file_generic,
+ .open = simple_open,
.llseek = default_llseek,
};
@@ -2768,7 +2762,7 @@ il4965_rs_sta_dbgfs_rate_scale_data_read(struct file *file,
static const struct file_operations rs_sta_dbgfs_rate_scale_data_ops = {
.read = il4965_rs_sta_dbgfs_rate_scale_data_read,
- .open = il4965_open_file_generic,
+ .open = simple_open,
.llseek = default_llseek,
};
diff --git a/drivers/net/wireless/iwlegacy/debug.c b/drivers/net/wireless/iwlegacy/debug.c
index 229849150aac..eff26501d60a 100644
--- a/drivers/net/wireless/iwlegacy/debug.c
+++ b/drivers/net/wireless/iwlegacy/debug.c
@@ -160,18 +160,12 @@ static ssize_t il_dbgfs_##name##_write(struct file *file, \
const char __user *user_buf, \
size_t count, loff_t *ppos);
-static int
-il_dbgfs_open_file_generic(struct inode *inode, struct file *file)
-{
- file->private_data = inode->i_private;
- return 0;
-}
#define DEBUGFS_READ_FILE_OPS(name) \
DEBUGFS_READ_FUNC(name); \
static const struct file_operations il_dbgfs_##name##_ops = { \
.read = il_dbgfs_##name##_read, \
- .open = il_dbgfs_open_file_generic, \
+ .open = simple_open, \
.llseek = generic_file_llseek, \
};
@@ -179,7 +173,7 @@ static const struct file_operations il_dbgfs_##name##_ops = { \
DEBUGFS_WRITE_FUNC(name); \
static const struct file_operations il_dbgfs_##name##_ops = { \
.write = il_dbgfs_##name##_write, \
- .open = il_dbgfs_open_file_generic, \
+ .open = simple_open, \
.llseek = generic_file_llseek, \
};
@@ -189,7 +183,7 @@ static const struct file_operations il_dbgfs_##name##_ops = { \
static const struct file_operations il_dbgfs_##name##_ops = { \
.write = il_dbgfs_##name##_write, \
.read = il_dbgfs_##name##_read, \
- .open = il_dbgfs_open_file_generic, \
+ .open = simple_open, \
.llseek = generic_file_llseek, \
};
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index 53f8c51cfcdb..7e590b349dd7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -3083,11 +3083,6 @@ static void rs_free_sta(void *priv_r, struct ieee80211_sta *sta,
}
#ifdef CONFIG_MAC80211_DEBUGFS
-static int open_file_generic(struct inode *inode, struct file *file)
-{
- file->private_data = inode->i_private;
- return 0;
-}
static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta,
u32 *rate_n_flags, int index)
{
@@ -3226,7 +3221,7 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
static const struct file_operations rs_sta_dbgfs_scale_table_ops = {
.write = rs_sta_dbgfs_scale_table_write,
.read = rs_sta_dbgfs_scale_table_read,
- .open = open_file_generic,
+ .open = simple_open,
.llseek = default_llseek,
};
static ssize_t rs_sta_dbgfs_stats_table_read(struct file *file,
@@ -3269,7 +3264,7 @@ static ssize_t rs_sta_dbgfs_stats_table_read(struct file *file,
static const struct file_operations rs_sta_dbgfs_stats_table_ops = {
.read = rs_sta_dbgfs_stats_table_read,
- .open = open_file_generic,
+ .open = simple_open,
.llseek = default_llseek,
};
@@ -3295,7 +3290,7 @@ static ssize_t rs_sta_dbgfs_rate_scale_data_read(struct file *file,
static const struct file_operations rs_sta_dbgfs_rate_scale_data_ops = {
.read = rs_sta_dbgfs_rate_scale_data_read,
- .open = open_file_generic,
+ .open = simple_open,
.llseek = default_llseek,
};
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index b7b1c04f2fba..2bbaebd99ad4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -84,17 +84,11 @@ static ssize_t iwl_dbgfs_##name##_write(struct file *file, \
size_t count, loff_t *ppos);
-static int iwl_dbgfs_open_file_generic(struct inode *inode, struct file *file)
-{
- file->private_data = inode->i_private;
- return 0;
-}
-
#define DEBUGFS_READ_FILE_OPS(name) \
DEBUGFS_READ_FUNC(name); \
static const struct file_operations iwl_dbgfs_##name##_ops = { \
.read = iwl_dbgfs_##name##_read, \
- .open = iwl_dbgfs_open_file_generic, \
+ .open = simple_open, \
.llseek = generic_file_llseek, \
};
@@ -102,7 +96,7 @@ static const struct file_operations iwl_dbgfs_##name##_ops = { \
DEBUGFS_WRITE_FUNC(name); \
static const struct file_operations iwl_dbgfs_##name##_ops = { \
.write = iwl_dbgfs_##name##_write, \
- .open = iwl_dbgfs_open_file_generic, \
+ .open = simple_open, \
.llseek = generic_file_llseek, \
};
@@ -113,7 +107,7 @@ static const struct file_operations iwl_dbgfs_##name##_ops = { \
static const struct file_operations iwl_dbgfs_##name##_ops = { \
.write = iwl_dbgfs_##name##_write, \
.read = iwl_dbgfs_##name##_read, \
- .open = iwl_dbgfs_open_file_generic, \
+ .open = simple_open, \
.llseek = generic_file_llseek, \
};
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c
index b4f796c82e1e..4d7b30d3e648 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c
+++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c
@@ -1898,17 +1898,11 @@ static ssize_t iwl_dbgfs_##name##_write(struct file *file, \
size_t count, loff_t *ppos);
-static int iwl_dbgfs_open_file_generic(struct inode *inode, struct file *file)
-{
- file->private_data = inode->i_private;
- return 0;
-}
-
#define DEBUGFS_READ_FILE_OPS(name) \
DEBUGFS_READ_FUNC(name); \
static const struct file_operations iwl_dbgfs_##name##_ops = { \
.read = iwl_dbgfs_##name##_read, \
- .open = iwl_dbgfs_open_file_generic, \
+ .open = simple_open, \
.llseek = generic_file_llseek, \
};
@@ -1916,7 +1910,7 @@ static const struct file_operations iwl_dbgfs_##name##_ops = { \
DEBUGFS_WRITE_FUNC(name); \
static const struct file_operations iwl_dbgfs_##name##_ops = { \
.write = iwl_dbgfs_##name##_write, \
- .open = iwl_dbgfs_open_file_generic, \
+ .open = simple_open, \
.llseek = generic_file_llseek, \
};
@@ -1926,7 +1920,7 @@ static const struct file_operations iwl_dbgfs_##name##_ops = { \
static const struct file_operations iwl_dbgfs_##name##_ops = { \
.write = iwl_dbgfs_##name##_write, \
.read = iwl_dbgfs_##name##_read, \
- .open = iwl_dbgfs_open_file_generic, \
+ .open = simple_open, \
.llseek = generic_file_llseek, \
};
diff --git a/drivers/net/wireless/iwmc3200wifi/debugfs.c b/drivers/net/wireless/iwmc3200wifi/debugfs.c
index 87eef5773a02..b6199d124bb9 100644
--- a/drivers/net/wireless/iwmc3200wifi/debugfs.c
+++ b/drivers/net/wireless/iwmc3200wifi/debugfs.c
@@ -99,12 +99,6 @@ DEFINE_SIMPLE_ATTRIBUTE(fops_iwm_dbg_modules,
iwm_debugfs_u32_read, iwm_debugfs_dbg_modules_write,
"%llu\n");
-static int iwm_generic_open(struct inode *inode, struct file *filp)
-{
- filp->private_data = inode->i_private;
- return 0;
-}
-
static ssize_t iwm_debugfs_txq_read(struct file *filp, char __user *buffer,
size_t count, loff_t *ppos)
@@ -401,28 +395,28 @@ out:
static const struct file_operations iwm_debugfs_txq_fops = {
.owner = THIS_MODULE,
- .open = iwm_generic_open,
+ .open = simple_open,
.read = iwm_debugfs_txq_read,
.llseek = default_llseek,
};
static const struct file_operations iwm_debugfs_tx_credit_fops = {
.owner = THIS_MODULE,
- .open = iwm_generic_open,
+ .open = simple_open,
.read = iwm_debugfs_tx_credit_read,
.llseek = default_llseek,
};
static const struct file_operations iwm_debugfs_rx_ticket_fops = {
.owner = THIS_MODULE,
- .open = iwm_generic_open,
+ .open = simple_open,
.read = iwm_debugfs_rx_ticket_read,
.llseek = default_llseek,
};
static const struct file_operations iwm_debugfs_fw_err_fops = {
.owner = THIS_MODULE,
- .open = iwm_generic_open,
+ .open = simple_open,
.read = iwm_debugfs_fw_err_read,
.llseek = default_llseek,
};
diff --git a/drivers/net/wireless/iwmc3200wifi/sdio.c b/drivers/net/wireless/iwmc3200wifi/sdio.c
index 764b40dd24ad..0042f204b07f 100644
--- a/drivers/net/wireless/iwmc3200wifi/sdio.c
+++ b/drivers/net/wireless/iwmc3200wifi/sdio.c
@@ -264,13 +264,6 @@ static int if_sdio_send_chunk(struct iwm_priv *iwm, u8 *buf, int count)
return ret;
}
-/* debugfs hooks */
-static int iwm_debugfs_sdio_open(struct inode *inode, struct file *filp)
-{
- filp->private_data = inode->i_private;
- return 0;
-}
-
static ssize_t iwm_debugfs_sdio_read(struct file *filp, char __user *buffer,
size_t count, loff_t *ppos)
{
@@ -363,7 +356,7 @@ err:
static const struct file_operations iwm_debugfs_sdio_fops = {
.owner = THIS_MODULE,
- .open = iwm_debugfs_sdio_open,
+ .open = simple_open,
.read = iwm_debugfs_sdio_read,
.llseek = default_llseek,
};
diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c
index 3fa1ecebadfd..2fa879b015b6 100644
--- a/drivers/net/wireless/libertas/cfg.c
+++ b/drivers/net/wireless/libertas/cfg.c
@@ -103,7 +103,7 @@ static const u32 cipher_suites[] = {
* Convert NL80211's auth_type to the one from Libertas, see chapter 5.9.1
* in the firmware spec
*/
-static u8 lbs_auth_to_authtype(enum nl80211_auth_type auth_type)
+static int lbs_auth_to_authtype(enum nl80211_auth_type auth_type)
{
int ret = -ENOTSUPP;
@@ -1411,7 +1411,12 @@ static int lbs_cfg_connect(struct wiphy *wiphy, struct net_device *dev,
goto done;
}
- lbs_set_authtype(priv, sme);
+ ret = lbs_set_authtype(priv, sme);
+ if (ret == -ENOTSUPP) {
+ wiphy_err(wiphy, "unsupported authtype 0x%x\n", sme->auth_type);
+ goto done;
+ }
+
lbs_set_radio(priv, preamble, 1);
/* Do the actual association */
diff --git a/drivers/net/wireless/libertas/debugfs.c b/drivers/net/wireless/libertas/debugfs.c
index c192671610fc..a06cc283e23d 100644
--- a/drivers/net/wireless/libertas/debugfs.c
+++ b/drivers/net/wireless/libertas/debugfs.c
@@ -21,12 +21,6 @@ static char *szStates[] = {
static void lbs_debug_init(struct lbs_private *priv);
#endif
-static int open_file_generic(struct inode *inode, struct file *file)
-{
- file->private_data = inode->i_private;
- return 0;
-}
-
static ssize_t write_file_dummy(struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
{
@@ -696,7 +690,7 @@ out_unlock:
#define FOPS(fread, fwrite) { \
.owner = THIS_MODULE, \
- .open = open_file_generic, \
+ .open = simple_open, \
.read = (fread), \
.write = (fwrite), \
.llseek = generic_file_llseek, \
@@ -962,7 +956,7 @@ static ssize_t lbs_debugfs_write(struct file *f, const char __user *buf,
static const struct file_operations lbs_debug_fops = {
.owner = THIS_MODULE,
- .open = open_file_generic,
+ .open = simple_open,
.write = lbs_debugfs_write,
.read = lbs_debugfs_read,
.llseek = default_llseek,
diff --git a/drivers/net/wireless/mwifiex/debugfs.c b/drivers/net/wireless/mwifiex/debugfs.c
index d26a78b6b3c4..1a845074c52a 100644
--- a/drivers/net/wireless/mwifiex/debugfs.c
+++ b/drivers/net/wireless/mwifiex/debugfs.c
@@ -140,18 +140,6 @@ static struct mwifiex_debug_data items[] = {
static int num_of_items = ARRAY_SIZE(items);
/*
- * Generic proc file open handler.
- *
- * This function is called every time a file is accessed for read or write.
- */
-static int
-mwifiex_open_generic(struct inode *inode, struct file *file)
-{
- file->private_data = inode->i_private;
- return 0;
-}
-
-/*
* Proc info file read handler.
*
* This function is called when the 'info' file is opened for reading.
@@ -676,19 +664,19 @@ done:
static const struct file_operations mwifiex_dfs_##name##_fops = { \
.read = mwifiex_##name##_read, \
.write = mwifiex_##name##_write, \
- .open = mwifiex_open_generic, \
+ .open = simple_open, \
};
#define MWIFIEX_DFS_FILE_READ_OPS(name) \
static const struct file_operations mwifiex_dfs_##name##_fops = { \
.read = mwifiex_##name##_read, \
- .open = mwifiex_open_generic, \
+ .open = simple_open, \
};
#define MWIFIEX_DFS_FILE_WRITE_OPS(name) \
static const struct file_operations mwifiex_dfs_##name##_fops = { \
.write = mwifiex_##name##_write, \
- .open = mwifiex_open_generic, \
+ .open = simple_open, \
};
diff --git a/drivers/net/wireless/mwifiex/pcie.h b/drivers/net/wireless/mwifiex/pcie.h
index 445ff21772e2..2f218f9a3fd3 100644
--- a/drivers/net/wireless/mwifiex/pcie.h
+++ b/drivers/net/wireless/mwifiex/pcie.h
@@ -48,15 +48,15 @@
#define PCIE_HOST_INT_STATUS_MASK 0xC3C
#define PCIE_SCRATCH_2_REG 0xC40
#define PCIE_SCRATCH_3_REG 0xC44
-#define PCIE_SCRATCH_4_REG 0xCC0
-#define PCIE_SCRATCH_5_REG 0xCC4
-#define PCIE_SCRATCH_6_REG 0xCC8
-#define PCIE_SCRATCH_7_REG 0xCCC
-#define PCIE_SCRATCH_8_REG 0xCD0
-#define PCIE_SCRATCH_9_REG 0xCD4
-#define PCIE_SCRATCH_10_REG 0xCD8
-#define PCIE_SCRATCH_11_REG 0xCDC
-#define PCIE_SCRATCH_12_REG 0xCE0
+#define PCIE_SCRATCH_4_REG 0xCD0
+#define PCIE_SCRATCH_5_REG 0xCD4
+#define PCIE_SCRATCH_6_REG 0xCD8
+#define PCIE_SCRATCH_7_REG 0xCDC
+#define PCIE_SCRATCH_8_REG 0xCE0
+#define PCIE_SCRATCH_9_REG 0xCE4
+#define PCIE_SCRATCH_10_REG 0xCE8
+#define PCIE_SCRATCH_11_REG 0xCEC
+#define PCIE_SCRATCH_12_REG 0xCF0
#define CPU_INTR_DNLD_RDY BIT(0)
#define CPU_INTR_DOOR_BELL BIT(1)
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index fc9901e027c1..90cc5e772650 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -1062,11 +1062,6 @@ static int rt2x00lib_initialize(struct rt2x00_dev *rt2x00dev)
set_bit(DEVICE_STATE_INITIALIZED, &rt2x00dev->flags);
- /*
- * Register the extra components.
- */
- rt2x00rfkill_register(rt2x00dev);
-
return 0;
}
@@ -1210,6 +1205,7 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
rt2x00link_register(rt2x00dev);
rt2x00leds_register(rt2x00dev);
rt2x00debug_register(rt2x00dev);
+ rt2x00rfkill_register(rt2x00dev);
return 0;
diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c
index 510023554e5f..e54488db0e10 100644
--- a/drivers/net/wireless/rtlwifi/base.c
+++ b/drivers/net/wireless/rtlwifi/base.c
@@ -838,7 +838,10 @@ void rtl_get_tcb_desc(struct ieee80211_hw *hw,
__le16 fc = hdr->frame_control;
txrate = ieee80211_get_tx_rate(hw, info);
- tcb_desc->hw_rate = txrate->hw_value;
+ if (txrate)
+ tcb_desc->hw_rate = txrate->hw_value;
+ else
+ tcb_desc->hw_rate = 0;
if (ieee80211_is_data(fc)) {
/*
diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c
index 07dd38efe62a..288b035a3579 100644
--- a/drivers/net/wireless/rtlwifi/pci.c
+++ b/drivers/net/wireless/rtlwifi/pci.c
@@ -912,8 +912,13 @@ static void _rtl_pci_prepare_bcn_tasklet(struct ieee80211_hw *hw)
memset(&tcb_desc, 0, sizeof(struct rtl_tcb_desc));
ring = &rtlpci->tx_ring[BEACON_QUEUE];
pskb = __skb_dequeue(&ring->queue);
- if (pskb)
+ if (pskb) {
+ struct rtl_tx_desc *entry = &ring->desc[ring->idx];
+ pci_unmap_single(rtlpci->pdev, rtlpriv->cfg->ops->get_desc(
+ (u8 *) entry, true, HW_DESC_TXBUFF_ADDR),
+ pskb->len, PCI_DMA_TODEVICE);
kfree_skb(pskb);
+ }
/*NB: the beacon data buffer must be 32-bit aligned. */
pskb = ieee80211_beacon_get(hw, mac->vif);
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/sw.c b/drivers/net/wireless/rtlwifi/rtl8192de/sw.c
index 4898c502974d..480862c07f92 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/sw.c
@@ -91,7 +91,6 @@ static int rtl92d_init_sw_vars(struct ieee80211_hw *hw)
u8 tid;
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
- static int header_print;
rtlpriv->dm.dm_initialgain_enable = true;
rtlpriv->dm.dm_flag = 0;
@@ -171,10 +170,6 @@ static int rtl92d_init_sw_vars(struct ieee80211_hw *hw)
for (tid = 0; tid < 8; tid++)
skb_queue_head_init(&rtlpriv->mac80211.skb_waitq[tid]);
- /* Only load firmware for first MAC */
- if (header_print)
- return 0;
-
/* for firmware buf */
rtlpriv->rtlhal.pfirmware = vzalloc(0x8000);
if (!rtlpriv->rtlhal.pfirmware) {
@@ -186,7 +181,6 @@ static int rtl92d_init_sw_vars(struct ieee80211_hw *hw)
rtlpriv->max_fw_size = 0x8000;
pr_info("Driver for Realtek RTL8192DE WLAN interface\n");
pr_info("Loading firmware file %s\n", rtlpriv->cfg->fw_name);
- header_print++;
/* request fw */
err = request_firmware_nowait(THIS_MODULE, 1, rtlpriv->cfg->fw_name,
diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c
index 2e1e352864bb..d04dbda13f5a 100644
--- a/drivers/net/wireless/rtlwifi/usb.c
+++ b/drivers/net/wireless/rtlwifi/usb.c
@@ -124,46 +124,38 @@ static int _usbctrl_vendorreq_sync_read(struct usb_device *udev, u8 request,
return status;
}
-static u32 _usb_read_sync(struct usb_device *udev, u32 addr, u16 len)
+static u32 _usb_read_sync(struct rtl_priv *rtlpriv, u32 addr, u16 len)
{
+ struct device *dev = rtlpriv->io.dev;
+ struct usb_device *udev = to_usb_device(dev);
u8 request;
u16 wvalue;
u16 index;
- u32 *data;
- u32 ret;
+ __le32 *data = &rtlpriv->usb_data[rtlpriv->usb_data_index];
- data = kmalloc(sizeof(u32), GFP_KERNEL);
- if (!data)
- return -ENOMEM;
request = REALTEK_USB_VENQT_CMD_REQ;
index = REALTEK_USB_VENQT_CMD_IDX; /* n/a */
wvalue = (u16)addr;
_usbctrl_vendorreq_sync_read(udev, request, wvalue, index, data, len);
- ret = le32_to_cpu(*data);
- kfree(data);
- return ret;
+ if (++rtlpriv->usb_data_index >= RTL_USB_MAX_RX_COUNT)
+ rtlpriv->usb_data_index = 0;
+ return le32_to_cpu(*data);
}
static u8 _usb_read8_sync(struct rtl_priv *rtlpriv, u32 addr)
{
- struct device *dev = rtlpriv->io.dev;
-
- return (u8)_usb_read_sync(to_usb_device(dev), addr, 1);
+ return (u8)_usb_read_sync(rtlpriv, addr, 1);
}
static u16 _usb_read16_sync(struct rtl_priv *rtlpriv, u32 addr)
{
- struct device *dev = rtlpriv->io.dev;
-
- return (u16)_usb_read_sync(to_usb_device(dev), addr, 2);
+ return (u16)_usb_read_sync(rtlpriv, addr, 2);
}
static u32 _usb_read32_sync(struct rtl_priv *rtlpriv, u32 addr)
{
- struct device *dev = rtlpriv->io.dev;
-
- return _usb_read_sync(to_usb_device(dev), addr, 4);
+ return _usb_read_sync(rtlpriv, addr, 4);
}
static void _usb_write_async(struct usb_device *udev, u32 addr, u32 val,
@@ -955,6 +947,11 @@ int __devinit rtl_usb_probe(struct usb_interface *intf,
return -ENOMEM;
}
rtlpriv = hw->priv;
+ rtlpriv->usb_data = kzalloc(RTL_USB_MAX_RX_COUNT * sizeof(u32),
+ GFP_KERNEL);
+ if (!rtlpriv->usb_data)
+ return -ENOMEM;
+ rtlpriv->usb_data_index = 0;
init_completion(&rtlpriv->firmware_loading_complete);
SET_IEEE80211_DEV(hw, &intf->dev);
udev = interface_to_usbdev(intf);
@@ -1025,6 +1022,7 @@ void rtl_usb_disconnect(struct usb_interface *intf)
/* rtl_deinit_rfkill(hw); */
rtl_usb_deinit(hw);
rtl_deinit_core(hw);
+ kfree(rtlpriv->usb_data);
rtlpriv->cfg->ops->deinit_sw_leds(hw);
rtlpriv->cfg->ops->deinit_sw_vars(hw);
_rtl_usb_io_handler_release(hw);
diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h
index b591614c3b9b..28ebc69218a3 100644
--- a/drivers/net/wireless/rtlwifi/wifi.h
+++ b/drivers/net/wireless/rtlwifi/wifi.h
@@ -67,7 +67,7 @@
#define QOS_QUEUE_NUM 4
#define RTL_MAC80211_NUM_QUEUE 5
#define REALTEK_USB_VENQT_MAX_BUF_SIZE 254
-
+#define RTL_USB_MAX_RX_COUNT 100
#define QBSS_LOAD_SIZE 5
#define MAX_WMMELE_LENGTH 64
@@ -1629,6 +1629,10 @@ struct rtl_priv {
interface or hardware */
unsigned long status;
+ /* data buffer pointer for USB reads */
+ __le32 *usb_data;
+ int usb_data_index;
+
/*This must be the last item so
that it points to the data allocated
beyond this structure like:
diff --git a/drivers/net/wireless/wl1251/debugfs.c b/drivers/net/wireless/wl1251/debugfs.c
index 6c274007d200..448da1f8c22f 100644
--- a/drivers/net/wireless/wl1251/debugfs.c
+++ b/drivers/net/wireless/wl1251/debugfs.c
@@ -47,7 +47,7 @@ static ssize_t name## _read(struct file *file, char __user *userbuf, \
\
static const struct file_operations name## _ops = { \
.read = name## _read, \
- .open = wl1251_open_file_generic, \
+ .open = simple_open, \
.llseek = generic_file_llseek, \
};
@@ -84,7 +84,7 @@ static ssize_t sub## _ ##name## _read(struct file *file, \
\
static const struct file_operations sub## _ ##name## _ops = { \
.read = sub## _ ##name## _read, \
- .open = wl1251_open_file_generic, \
+ .open = simple_open, \
.llseek = generic_file_llseek, \
};
@@ -117,12 +117,6 @@ out:
mutex_unlock(&wl->mutex);
}
-static int wl1251_open_file_generic(struct inode *inode, struct file *file)
-{
- file->private_data = inode->i_private;
- return 0;
-}
-
DEBUGFS_FWSTATS_FILE(tx, internal_desc_overflow, 20, "%u");
DEBUGFS_FWSTATS_FILE(rx, out_of_mem, 20, "%u");
@@ -235,7 +229,7 @@ static ssize_t tx_queue_len_read(struct file *file, char __user *userbuf,
static const struct file_operations tx_queue_len_ops = {
.read = tx_queue_len_read,
- .open = wl1251_open_file_generic,
+ .open = simple_open,
.llseek = generic_file_llseek,
};
@@ -257,7 +251,7 @@ static ssize_t tx_queue_status_read(struct file *file, char __user *userbuf,
static const struct file_operations tx_queue_status_ops = {
.read = tx_queue_status_read,
- .open = wl1251_open_file_generic,
+ .open = simple_open,
.llseek = generic_file_llseek,
};
diff --git a/drivers/net/wireless/wl12xx/debugfs.c b/drivers/net/wireless/wl12xx/debugfs.c
index e1cf72765965..564d49575c94 100644
--- a/drivers/net/wireless/wl12xx/debugfs.c
+++ b/drivers/net/wireless/wl12xx/debugfs.c
@@ -63,7 +63,7 @@ static ssize_t name## _read(struct file *file, char __user *userbuf, \
\
static const struct file_operations name## _ops = { \
.read = name## _read, \
- .open = wl1271_open_file_generic, \
+ .open = simple_open, \
.llseek = generic_file_llseek, \
};
@@ -96,7 +96,7 @@ static ssize_t sub## _ ##name## _read(struct file *file, \
\
static const struct file_operations sub## _ ##name## _ops = { \
.read = sub## _ ##name## _read, \
- .open = wl1271_open_file_generic, \
+ .open = simple_open, \
.llseek = generic_file_llseek, \
};
@@ -126,12 +126,6 @@ out:
mutex_unlock(&wl->mutex);
}
-static int wl1271_open_file_generic(struct inode *inode, struct file *file)
-{
- file->private_data = inode->i_private;
- return 0;
-}
-
DEBUGFS_FWSTATS_FILE(tx, internal_desc_overflow, "%u");
DEBUGFS_FWSTATS_FILE(rx, out_of_mem, "%u");
@@ -243,7 +237,7 @@ static ssize_t tx_queue_len_read(struct file *file, char __user *userbuf,
static const struct file_operations tx_queue_len_ops = {
.read = tx_queue_len_read,
- .open = wl1271_open_file_generic,
+ .open = simple_open,
.llseek = default_llseek,
};
@@ -289,7 +283,7 @@ static ssize_t gpio_power_write(struct file *file,
static const struct file_operations gpio_power_ops = {
.read = gpio_power_read,
.write = gpio_power_write,
- .open = wl1271_open_file_generic,
+ .open = simple_open,
.llseek = default_llseek,
};
@@ -308,7 +302,7 @@ static ssize_t start_recovery_write(struct file *file,
static const struct file_operations start_recovery_ops = {
.write = start_recovery_write,
- .open = wl1271_open_file_generic,
+ .open = simple_open,
.llseek = default_llseek,
};
@@ -372,7 +366,7 @@ out:
static const struct file_operations dynamic_ps_timeout_ops = {
.read = dynamic_ps_timeout_read,
.write = dynamic_ps_timeout_write,
- .open = wl1271_open_file_generic,
+ .open = simple_open,
.llseek = default_llseek,
};
@@ -441,7 +435,7 @@ out:
static const struct file_operations forced_ps_ops = {
.read = forced_ps_read,
.write = forced_ps_write,
- .open = wl1271_open_file_generic,
+ .open = simple_open,
.llseek = default_llseek,
};
@@ -483,7 +477,7 @@ static ssize_t split_scan_timeout_write(struct file *file,
static const struct file_operations split_scan_timeout_ops = {
.read = split_scan_timeout_read,
.write = split_scan_timeout_write,
- .open = wl1271_open_file_generic,
+ .open = simple_open,
.llseek = default_llseek,
};
@@ -566,7 +560,7 @@ static ssize_t driver_state_read(struct file *file, char __user *user_buf,
static const struct file_operations driver_state_ops = {
.read = driver_state_read,
- .open = wl1271_open_file_generic,
+ .open = simple_open,
.llseek = default_llseek,
};
@@ -675,7 +669,7 @@ static ssize_t vifs_state_read(struct file *file, char __user *user_buf,
static const struct file_operations vifs_state_ops = {
.read = vifs_state_read,
- .open = wl1271_open_file_generic,
+ .open = simple_open,
.llseek = default_llseek,
};
@@ -733,7 +727,7 @@ static ssize_t dtim_interval_write(struct file *file,
static const struct file_operations dtim_interval_ops = {
.read = dtim_interval_read,
.write = dtim_interval_write,
- .open = wl1271_open_file_generic,
+ .open = simple_open,
.llseek = default_llseek,
};
@@ -791,7 +785,7 @@ static ssize_t suspend_dtim_interval_write(struct file *file,
static const struct file_operations suspend_dtim_interval_ops = {
.read = suspend_dtim_interval_read,
.write = suspend_dtim_interval_write,
- .open = wl1271_open_file_generic,
+ .open = simple_open,
.llseek = default_llseek,
};
@@ -849,7 +843,7 @@ static ssize_t beacon_interval_write(struct file *file,
static const struct file_operations beacon_interval_ops = {
.read = beacon_interval_read,
.write = beacon_interval_write,
- .open = wl1271_open_file_generic,
+ .open = simple_open,
.llseek = default_llseek,
};
@@ -904,7 +898,7 @@ static ssize_t rx_streaming_interval_read(struct file *file,
static const struct file_operations rx_streaming_interval_ops = {
.read = rx_streaming_interval_read,
.write = rx_streaming_interval_write,
- .open = wl1271_open_file_generic,
+ .open = simple_open,
.llseek = default_llseek,
};
@@ -959,7 +953,7 @@ static ssize_t rx_streaming_always_read(struct file *file,
static const struct file_operations rx_streaming_always_ops = {
.read = rx_streaming_always_read,
.write = rx_streaming_always_write,
- .open = wl1271_open_file_generic,
+ .open = simple_open,
.llseek = default_llseek,
};
@@ -1003,7 +997,7 @@ out:
static const struct file_operations beacon_filtering_ops = {
.write = beacon_filtering_write,
- .open = wl1271_open_file_generic,
+ .open = simple_open,
.llseek = default_llseek,
};
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
index 663b32c2e931..0ebbb1906c30 100644
--- a/drivers/net/xen-netfront.c
+++ b/drivers/net/xen-netfront.c
@@ -1965,7 +1965,7 @@ static int __init netif_init(void)
if (xen_initial_domain())
return 0;
- if (!xen_platform_pci_unplug)
+ if (xen_hvm_domain() && !xen_platform_pci_unplug)
return -ENODEV;
printk(KERN_INFO "Initialising Xen virtual ethernet driver.\n");
diff --git a/drivers/of/gpio.c b/drivers/of/gpio.c
index bba81216b4db..bf984b6dc477 100644
--- a/drivers/of/gpio.c
+++ b/drivers/of/gpio.c
@@ -140,7 +140,7 @@ int of_gpio_simple_xlate(struct gpio_chip *gc,
if (WARN_ON(gpiospec->args_count < gc->of_gpio_n_cells))
return -EINVAL;
- if (gpiospec->args[0] > gc->ngpio)
+ if (gpiospec->args[0] >= gc->ngpio)
return -EINVAL;
if (flags)
diff --git a/drivers/oprofile/oprofilefs.c b/drivers/oprofile/oprofilefs.c
index ee8fd037bb53..849357c1045c 100644
--- a/drivers/oprofile/oprofilefs.c
+++ b/drivers/oprofile/oprofilefs.c
@@ -117,25 +117,17 @@ static ssize_t ulong_write_file(struct file *file, char const __user *buf, size_
}
-static int default_open(struct inode *inode, struct file *filp)
-{
- if (inode->i_private)
- filp->private_data = inode->i_private;
- return 0;
-}
-
-
static const struct file_operations ulong_fops = {
.read = ulong_read_file,
.write = ulong_write_file,
- .open = default_open,
+ .open = simple_open,
.llseek = default_llseek,
};
static const struct file_operations ulong_ro_fops = {
.read = ulong_read_file,
- .open = default_open,
+ .open = simple_open,
.llseek = default_llseek,
};
@@ -187,7 +179,7 @@ static ssize_t atomic_read_file(struct file *file, char __user *buf, size_t coun
static const struct file_operations atomic_ro_fops = {
.read = atomic_read_file,
- .open = default_open,
+ .open = simple_open,
.llseek = default_llseek,
};
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 815674415267..111569ccab43 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -967,16 +967,59 @@ pci_save_state(struct pci_dev *dev)
return 0;
}
+static void pci_restore_config_dword(struct pci_dev *pdev, int offset,
+ u32 saved_val, int retry)
+{
+ u32 val;
+
+ pci_read_config_dword(pdev, offset, &val);
+ if (val == saved_val)
+ return;
+
+ for (;;) {
+ dev_dbg(&pdev->dev, "restoring config space at offset "
+ "%#x (was %#x, writing %#x)\n", offset, val, saved_val);
+ pci_write_config_dword(pdev, offset, saved_val);
+ if (retry-- <= 0)
+ return;
+
+ pci_read_config_dword(pdev, offset, &val);
+ if (val == saved_val)
+ return;
+
+ mdelay(1);
+ }
+}
+
+static void pci_restore_config_space_range(struct pci_dev *pdev,
+ int start, int end, int retry)
+{
+ int index;
+
+ for (index = end; index >= start; index--)
+ pci_restore_config_dword(pdev, 4 * index,
+ pdev->saved_config_space[index],
+ retry);
+}
+
+static void pci_restore_config_space(struct pci_dev *pdev)
+{
+ if (pdev->hdr_type == PCI_HEADER_TYPE_NORMAL) {
+ pci_restore_config_space_range(pdev, 10, 15, 0);
+ /* Restore BARs before the command register. */
+ pci_restore_config_space_range(pdev, 4, 9, 10);
+ pci_restore_config_space_range(pdev, 0, 3, 0);
+ } else {
+ pci_restore_config_space_range(pdev, 0, 15, 0);
+ }
+}
+
/**
* pci_restore_state - Restore the saved state of a PCI device
* @dev: - PCI device that we're dealing with
*/
void pci_restore_state(struct pci_dev *dev)
{
- int i;
- u32 val;
- int tries;
-
if (!dev->state_saved)
return;
@@ -984,24 +1027,8 @@ void pci_restore_state(struct pci_dev *dev)
pci_restore_pcie_state(dev);
pci_restore_ats_state(dev);
- /*
- * The Base Address register should be programmed before the command
- * register(s)
- */
- for (i = 15; i >= 0; i--) {
- pci_read_config_dword(dev, i * 4, &val);
- tries = 10;
- while (tries && val != dev->saved_config_space[i]) {
- dev_dbg(&dev->dev, "restoring config "
- "space at offset %#x (was %#x, writing %#x)\n",
- i, val, (int)dev->saved_config_space[i]);
- pci_write_config_dword(dev,i * 4,
- dev->saved_config_space[i]);
- pci_read_config_dword(dev, i * 4, &val);
- mdelay(10);
- tries--;
- }
- }
+ pci_restore_config_space(dev);
+
pci_restore_pcix_state(dev);
pci_restore_msi_state(dev);
pci_restore_iov_state(dev);
diff --git a/drivers/pci/xen-pcifront.c b/drivers/pci/xen-pcifront.c
index fd00ff02ab4d..d6cc62cb4cf7 100644
--- a/drivers/pci/xen-pcifront.c
+++ b/drivers/pci/xen-pcifront.c
@@ -290,6 +290,7 @@ static int pci_frontend_enable_msix(struct pci_dev *dev,
} else {
printk(KERN_DEBUG "enable msix get value %x\n",
op.value);
+ err = op.value;
}
} else {
dev_err(&dev->dev, "enable msix get err %x\n", err);
diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c
index ec3b8cc188af..df6296c5f47b 100644
--- a/drivers/pinctrl/core.c
+++ b/drivers/pinctrl/core.c
@@ -908,10 +908,6 @@ static int pinctrl_groups_show(struct seq_file *s, void *what)
const struct pinctrl_ops *ops = pctldev->desc->pctlops;
unsigned selector = 0;
- /* No grouping */
- if (!ops)
- return 0;
-
mutex_lock(&pinctrl_mutex);
seq_puts(s, "registered pin groups:\n");
@@ -1225,6 +1221,19 @@ static void pinctrl_remove_device_debugfs(struct pinctrl_dev *pctldev)
#endif
+static int pinctrl_check_ops(struct pinctrl_dev *pctldev)
+{
+ const struct pinctrl_ops *ops = pctldev->desc->pctlops;
+
+ if (!ops ||
+ !ops->list_groups ||
+ !ops->get_group_name ||
+ !ops->get_group_pins)
+ return -EINVAL;
+
+ return 0;
+}
+
/**
* pinctrl_register() - register a pin controller device
* @pctldesc: descriptor for this pin controller
@@ -1256,6 +1265,14 @@ struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc,
INIT_LIST_HEAD(&pctldev->gpio_ranges);
pctldev->dev = dev;
+ /* check core ops for sanity */
+ ret = pinctrl_check_ops(pctldev);
+ if (ret) {
+ pr_err("%s pinctrl ops lacks necessary functions\n",
+ pctldesc->name);
+ goto out_err;
+ }
+
/* If we're implementing pinmuxing, check the ops for sanity */
if (pctldesc->pmxops) {
ret = pinmux_check_ops(pctldev);
diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c
index a05fc9c955d8..e6c08ee8d46c 100644
--- a/drivers/platform/x86/dell-laptop.c
+++ b/drivers/platform/x86/dell-laptop.c
@@ -212,6 +212,7 @@ static struct dmi_system_id __devinitdata dell_quirks[] = {
},
.driver_data = &quirk_dell_vostro_v130,
},
+ { }
};
static struct calling_interface_buffer *buffer;
diff --git a/drivers/platform/x86/intel_ips.c b/drivers/platform/x86/intel_ips.c
index f7ba316e0ed6..0ffdb3cde2bb 100644
--- a/drivers/platform/x86/intel_ips.c
+++ b/drivers/platform/x86/intel_ips.c
@@ -1565,7 +1565,7 @@ static int ips_probe(struct pci_dev *dev, const struct pci_device_id *id)
ips->poll_turbo_status = true;
if (!ips_get_i915_syms(ips)) {
- dev_err(&dev->dev, "failed to get i915 symbols, graphics turbo disabled\n");
+ dev_info(&dev->dev, "failed to get i915 symbols, graphics turbo disabled until i915 loads\n");
ips->gpu_turbo_enabled = false;
} else {
dev_dbg(&dev->dev, "graphics turbo enabled\n");
diff --git a/drivers/regulator/anatop-regulator.c b/drivers/regulator/anatop-regulator.c
index 53969af17558..81fd606e47bc 100644
--- a/drivers/regulator/anatop-regulator.c
+++ b/drivers/regulator/anatop-regulator.c
@@ -214,7 +214,7 @@ static struct of_device_id __devinitdata of_anatop_regulator_match_tbl[] = {
{ /* end */ }
};
-static struct platform_driver anatop_regulator = {
+static struct platform_driver anatop_regulator_driver = {
.driver = {
.name = "anatop_regulator",
.owner = THIS_MODULE,
@@ -226,13 +226,13 @@ static struct platform_driver anatop_regulator = {
static int __init anatop_regulator_init(void)
{
- return platform_driver_register(&anatop_regulator);
+ return platform_driver_register(&anatop_regulator_driver);
}
postcore_initcall(anatop_regulator_init);
static void __exit anatop_regulator_exit(void)
{
- platform_driver_unregister(&anatop_regulator);
+ platform_driver_unregister(&anatop_regulator_driver);
}
module_exit(anatop_regulator_exit);
diff --git a/drivers/remoteproc/remoteproc_debugfs.c b/drivers/remoteproc/remoteproc_debugfs.c
index 70277a530133..85d31a69e117 100644
--- a/drivers/remoteproc/remoteproc_debugfs.c
+++ b/drivers/remoteproc/remoteproc_debugfs.c
@@ -50,16 +50,9 @@ static ssize_t rproc_trace_read(struct file *filp, char __user *userbuf,
return simple_read_from_buffer(userbuf, count, ppos, trace->va, len);
}
-static int rproc_open_generic(struct inode *inode, struct file *file)
-{
- file->private_data = inode->i_private;
-
- return 0;
-}
-
static const struct file_operations trace_rproc_ops = {
.read = rproc_trace_read,
- .open = rproc_open_generic,
+ .open = simple_open,
.llseek = generic_file_llseek,
};
@@ -94,7 +87,7 @@ static ssize_t rproc_state_read(struct file *filp, char __user *userbuf,
static const struct file_operations rproc_state_ops = {
.read = rproc_state_read,
- .open = rproc_open_generic,
+ .open = simple_open,
.llseek = generic_file_llseek,
};
@@ -114,7 +107,7 @@ static ssize_t rproc_name_read(struct file *filp, char __user *userbuf,
static const struct file_operations rproc_name_ops = {
.read = rproc_name_read,
- .open = rproc_open_generic,
+ .open = simple_open,
.llseek = generic_file_llseek,
};
diff --git a/drivers/rtc/rtc-88pm860x.c b/drivers/rtc/rtc-88pm860x.c
index afee0e8ae714..feddefc42109 100644
--- a/drivers/rtc/rtc-88pm860x.c
+++ b/drivers/rtc/rtc-88pm860x.c
@@ -72,9 +72,9 @@ static int pm860x_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
struct pm860x_rtc_info *info = dev_get_drvdata(dev);
if (enabled)
- pm860x_set_bits(info->i2c, PM8607_RTC1, ALARM, ALARM);
+ pm860x_set_bits(info->i2c, PM8607_RTC1, ALARM_EN, ALARM_EN);
else
- pm860x_set_bits(info->i2c, PM8607_RTC1, ALARM, 0);
+ pm860x_set_bits(info->i2c, PM8607_RTC1, ALARM_EN, 0);
return 0;
}
diff --git a/drivers/rtc/rtc-efi.c b/drivers/rtc/rtc-efi.c
index 550292304b0f..c9f890b088da 100644
--- a/drivers/rtc/rtc-efi.c
+++ b/drivers/rtc/rtc-efi.c
@@ -213,7 +213,6 @@ static struct platform_driver efi_rtc_driver = {
.name = "rtc-efi",
.owner = THIS_MODULE,
},
- .probe = efi_rtc_probe,
.remove = __exit_p(efi_rtc_remove),
};
diff --git a/drivers/rtc/rtc-pl031.c b/drivers/rtc/rtc-pl031.c
index 692de7360e94..684ef4bbfce4 100644
--- a/drivers/rtc/rtc-pl031.c
+++ b/drivers/rtc/rtc-pl031.c
@@ -339,8 +339,7 @@ static int pl031_probe(struct amba_device *adev, const struct amba_id *id)
dev_dbg(&adev->dev, "revision = 0x%01x\n", ldata->hw_revision);
/* Enable the clockwatch on ST Variants */
- if ((ldata->hw_designer == AMBA_VENDOR_ST) &&
- (ldata->hw_revision > 1))
+ if (ldata->hw_designer == AMBA_VENDOR_ST)
writel(readl(ldata->base + RTC_CR) | RTC_CR_CWEN,
ldata->base + RTC_CR);
diff --git a/drivers/rtc/rtc-r9701.c b/drivers/rtc/rtc-r9701.c
index 7f8e6c247935..33b6ba0afa0d 100644
--- a/drivers/rtc/rtc-r9701.c
+++ b/drivers/rtc/rtc-r9701.c
@@ -122,6 +122,7 @@ static const struct rtc_class_ops r9701_rtc_ops = {
static int __devinit r9701_probe(struct spi_device *spi)
{
struct rtc_device *rtc;
+ struct rtc_time dt;
unsigned char tmp;
int res;
@@ -132,6 +133,27 @@ static int __devinit r9701_probe(struct spi_device *spi)
return -ENODEV;
}
+ /*
+ * The device seems to be present. Now check if the registers
+ * contain invalid values. If so, try to write a default date:
+ * 2000/1/1 00:00:00
+ */
+ r9701_get_datetime(&spi->dev, &dt);
+ if (rtc_valid_tm(&dt)) {
+ dev_info(&spi->dev, "trying to repair invalid date/time\n");
+ dt.tm_sec = 0;
+ dt.tm_min = 0;
+ dt.tm_hour = 0;
+ dt.tm_mday = 1;
+ dt.tm_mon = 0;
+ dt.tm_year = 100;
+
+ if (r9701_set_datetime(&spi->dev, &dt)) {
+ dev_err(&spi->dev, "cannot repair RTC register\n");
+ return -ENODEV;
+ }
+ }
+
rtc = rtc_device_register("r9701",
&spi->dev, &r9701_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc))
diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c
index 9ccea134a996..3f3a29752369 100644
--- a/drivers/rtc/rtc-s3c.c
+++ b/drivers/rtc/rtc-s3c.c
@@ -40,6 +40,10 @@ enum s3c_cpu_type {
TYPE_S3C64XX,
};
+struct s3c_rtc_drv_data {
+ int cpu_type;
+};
+
/* I have yet to find an S3C implementation with more than one
* of these rtc blocks in */
@@ -446,10 +450,12 @@ static const struct of_device_id s3c_rtc_dt_match[];
static inline int s3c_rtc_get_driver_data(struct platform_device *pdev)
{
#ifdef CONFIG_OF
+ struct s3c_rtc_drv_data *data;
if (pdev->dev.of_node) {
const struct of_device_id *match;
match = of_match_node(s3c_rtc_dt_match, pdev->dev.of_node);
- return match->data;
+ data = (struct s3c_rtc_drv_data *) match->data;
+ return data->cpu_type;
}
#endif
return platform_get_device_id(pdev)->driver_data;
@@ -664,20 +670,27 @@ static int s3c_rtc_resume(struct platform_device *pdev)
#define s3c_rtc_resume NULL
#endif
+static struct s3c_rtc_drv_data s3c_rtc_drv_data_array[] = {
+ [TYPE_S3C2410] = { TYPE_S3C2410 },
+ [TYPE_S3C2416] = { TYPE_S3C2416 },
+ [TYPE_S3C2443] = { TYPE_S3C2443 },
+ [TYPE_S3C64XX] = { TYPE_S3C64XX },
+};
+
#ifdef CONFIG_OF
static const struct of_device_id s3c_rtc_dt_match[] = {
{
- .compatible = "samsung,s3c2410-rtc"
- .data = TYPE_S3C2410,
+ .compatible = "samsung,s3c2410-rtc",
+ .data = &s3c_rtc_drv_data_array[TYPE_S3C2410],
}, {
- .compatible = "samsung,s3c2416-rtc"
- .data = TYPE_S3C2416,
+ .compatible = "samsung,s3c2416-rtc",
+ .data = &s3c_rtc_drv_data_array[TYPE_S3C2416],
}, {
- .compatible = "samsung,s3c2443-rtc"
- .data = TYPE_S3C2443,
+ .compatible = "samsung,s3c2443-rtc",
+ .data = &s3c_rtc_drv_data_array[TYPE_S3C2443],
}, {
- .compatible = "samsung,s3c6410-rtc"
- .data = TYPE_S3C64XX,
+ .compatible = "samsung,s3c6410-rtc",
+ .data = &s3c_rtc_drv_data_array[TYPE_S3C64XX],
},
{},
};
diff --git a/drivers/rtc/rtc-twl.c b/drivers/rtc/rtc-twl.c
index 4c2c6df2a9ef..258abeabf624 100644
--- a/drivers/rtc/rtc-twl.c
+++ b/drivers/rtc/rtc-twl.c
@@ -112,6 +112,7 @@ static const u8 twl6030_rtc_reg_map[] = {
#define BIT_RTC_CTRL_REG_TEST_MODE_M 0x10
#define BIT_RTC_CTRL_REG_SET_32_COUNTER_M 0x20
#define BIT_RTC_CTRL_REG_GET_TIME_M 0x40
+#define BIT_RTC_CTRL_REG_RTC_V_OPT 0x80
/* RTC_STATUS_REG bitfields */
#define BIT_RTC_STATUS_REG_RUN_M 0x02
@@ -235,25 +236,57 @@ static int twl_rtc_read_time(struct device *dev, struct rtc_time *tm)
unsigned char rtc_data[ALL_TIME_REGS + 1];
int ret;
u8 save_control;
+ u8 rtc_control;
ret = twl_rtc_read_u8(&save_control, REG_RTC_CTRL_REG);
- if (ret < 0)
+ if (ret < 0) {
+ dev_err(dev, "%s: reading CTRL_REG, error %d\n", __func__, ret);
return ret;
+ }
+ /* for twl6030/32 make sure BIT_RTC_CTRL_REG_GET_TIME_M is clear */
+ if (twl_class_is_6030()) {
+ if (save_control & BIT_RTC_CTRL_REG_GET_TIME_M) {
+ save_control &= ~BIT_RTC_CTRL_REG_GET_TIME_M;
+ ret = twl_rtc_write_u8(save_control, REG_RTC_CTRL_REG);
+ if (ret < 0) {
+ dev_err(dev, "%s clr GET_TIME, error %d\n",
+ __func__, ret);
+ return ret;
+ }
+ }
+ }
- save_control |= BIT_RTC_CTRL_REG_GET_TIME_M;
+ /* Copy RTC counting registers to static registers or latches */
+ rtc_control = save_control | BIT_RTC_CTRL_REG_GET_TIME_M;
- ret = twl_rtc_write_u8(save_control, REG_RTC_CTRL_REG);
- if (ret < 0)
+ /* for twl6030/32 enable read access to static shadowed registers */
+ if (twl_class_is_6030())
+ rtc_control |= BIT_RTC_CTRL_REG_RTC_V_OPT;
+
+ ret = twl_rtc_write_u8(rtc_control, REG_RTC_CTRL_REG);
+ if (ret < 0) {
+ dev_err(dev, "%s: writing CTRL_REG, error %d\n", __func__, ret);
return ret;
+ }
ret = twl_i2c_read(TWL_MODULE_RTC, rtc_data,
(rtc_reg_map[REG_SECONDS_REG]), ALL_TIME_REGS);
if (ret < 0) {
- dev_err(dev, "rtc_read_time error %d\n", ret);
+ dev_err(dev, "%s: reading data, error %d\n", __func__, ret);
return ret;
}
+ /* for twl6030 restore original state of rtc control register */
+ if (twl_class_is_6030()) {
+ ret = twl_rtc_write_u8(save_control, REG_RTC_CTRL_REG);
+ if (ret < 0) {
+ dev_err(dev, "%s: restore CTRL_REG, error %d\n",
+ __func__, ret);
+ return ret;
+ }
+ }
+
tm->tm_sec = bcd2bin(rtc_data[0]);
tm->tm_min = bcd2bin(rtc_data[1]);
tm->tm_hour = bcd2bin(rtc_data[2]);
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
index c21871a4e73d..bc2e8a7c265b 100644
--- a/drivers/s390/block/dasd_eckd.c
+++ b/drivers/s390/block/dasd_eckd.c
@@ -2844,6 +2844,7 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track(
sector_t recid, trkid;
unsigned int offs;
unsigned int count, count_to_trk_end;
+ int ret;
basedev = block->base;
if (rq_data_dir(req) == READ) {
@@ -2884,8 +2885,8 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track(
itcw = itcw_init(cqr->data, itcw_size, itcw_op, 0, ctidaw, 0);
if (IS_ERR(itcw)) {
- dasd_sfree_request(cqr, startdev);
- return ERR_PTR(-EINVAL);
+ ret = -EINVAL;
+ goto out_error;
}
cqr->cpaddr = itcw_get_tcw(itcw);
if (prepare_itcw(itcw, first_trk, last_trk,
@@ -2897,8 +2898,8 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track(
/* Clock not in sync and XRC is enabled.
* Try again later.
*/
- dasd_sfree_request(cqr, startdev);
- return ERR_PTR(-EAGAIN);
+ ret = -EAGAIN;
+ goto out_error;
}
len_to_track_end = 0;
/*
@@ -2937,8 +2938,10 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track(
tidaw_flags = 0;
last_tidaw = itcw_add_tidaw(itcw, tidaw_flags,
dst, part_len);
- if (IS_ERR(last_tidaw))
- return ERR_PTR(-EINVAL);
+ if (IS_ERR(last_tidaw)) {
+ ret = -EINVAL;
+ goto out_error;
+ }
dst += part_len;
}
}
@@ -2947,8 +2950,10 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track(
dst = page_address(bv->bv_page) + bv->bv_offset;
last_tidaw = itcw_add_tidaw(itcw, 0x00,
dst, bv->bv_len);
- if (IS_ERR(last_tidaw))
- return ERR_PTR(-EINVAL);
+ if (IS_ERR(last_tidaw)) {
+ ret = -EINVAL;
+ goto out_error;
+ }
}
}
last_tidaw->flags |= TIDAW_FLAGS_LAST;
@@ -2968,6 +2973,9 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track(
cqr->buildclk = get_clock();
cqr->status = DASD_CQR_FILLED;
return cqr;
+out_error:
+ dasd_sfree_request(cqr, startdev);
+ return ERR_PTR(ret);
}
static struct dasd_ccw_req *dasd_eckd_build_cp(struct dasd_device *startdev,
diff --git a/drivers/s390/char/vmur.c b/drivers/s390/char/vmur.c
index 85f4a9a5d12e..73bef0bd394c 100644
--- a/drivers/s390/char/vmur.c
+++ b/drivers/s390/char/vmur.c
@@ -903,7 +903,7 @@ static int ur_set_online(struct ccw_device *cdev)
goto fail_urdev_put;
}
- cdev_init(urd->char_device, &ur_fops);
+ urd->char_device->ops = &ur_fops;
urd->char_device->dev = MKDEV(major, minor);
urd->char_device->owner = ur_fops.owner;
diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c
index 5bdf2eecb178..af04b0d6688d 100644
--- a/drivers/scsi/lpfc/lpfc_debugfs.c
+++ b/drivers/scsi/lpfc/lpfc_debugfs.c
@@ -997,13 +997,6 @@ lpfc_debugfs_dumpDataDif_write(struct file *file, const char __user *buf,
return nbytes;
}
-static int
-lpfc_debugfs_dif_err_open(struct inode *inode, struct file *file)
-{
- file->private_data = inode->i_private;
- return 0;
-}
-
static ssize_t
lpfc_debugfs_dif_err_read(struct file *file, char __user *buf,
size_t nbytes, loff_t *ppos)
@@ -3541,7 +3534,7 @@ static const struct file_operations lpfc_debugfs_op_dumpDif = {
#undef lpfc_debugfs_op_dif_err
static const struct file_operations lpfc_debugfs_op_dif_err = {
.owner = THIS_MODULE,
- .open = lpfc_debugfs_dif_err_open,
+ .open = simple_open,
.llseek = lpfc_debugfs_lseek,
.read = lpfc_debugfs_dif_err_read,
.write = lpfc_debugfs_dif_err_write,
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index 2cfcbffa41fd..386f0c53bea7 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -835,7 +835,7 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd,
scsi_eh_restore_cmnd(scmd, &ses);
- if (sdrv->eh_action)
+ if (sdrv && sdrv->eh_action)
rtn = sdrv->eh_action(scmd, cmnd, cmnd_size, rtn);
return rtn;
diff --git a/drivers/spi/spi-davinci.c b/drivers/spi/spi-davinci.c
index 31bfba805cf4..9b2901feaf78 100644
--- a/drivers/spi/spi-davinci.c
+++ b/drivers/spi/spi-davinci.c
@@ -653,7 +653,7 @@ static int davinci_spi_bufs(struct spi_device *spi, struct spi_transfer *t)
dev_dbg(sdev, "Couldn't DMA map a %d bytes RX buffer\n",
rx_buf_count);
if (t->tx_buf)
- dma_unmap_single(NULL, t->tx_dma, t->len,
+ dma_unmap_single(&spi->dev, t->tx_dma, t->len,
DMA_TO_DEVICE);
return -ENOMEM;
}
@@ -692,10 +692,10 @@ static int davinci_spi_bufs(struct spi_device *spi, struct spi_transfer *t)
if (spicfg->io_type == SPI_IO_TYPE_DMA) {
if (t->tx_buf)
- dma_unmap_single(NULL, t->tx_dma, t->len,
+ dma_unmap_single(&spi->dev, t->tx_dma, t->len,
DMA_TO_DEVICE);
- dma_unmap_single(NULL, t->rx_dma, rx_buf_count,
+ dma_unmap_single(&spi->dev, t->rx_dma, rx_buf_count,
DMA_FROM_DEVICE);
clear_io_bits(dspi->base + SPIINT, SPIINT_DMA_REQ_EN);
diff --git a/drivers/spi/spi-dw.c b/drivers/spi/spi-dw.c
index 082458d73ce9..d1a495f64e2d 100644
--- a/drivers/spi/spi-dw.c
+++ b/drivers/spi/spi-dw.c
@@ -63,12 +63,6 @@ struct chip_data {
};
#ifdef CONFIG_DEBUG_FS
-static int spi_show_regs_open(struct inode *inode, struct file *file)
-{
- file->private_data = inode->i_private;
- return 0;
-}
-
#define SPI_REGS_BUFSIZE 1024
static ssize_t spi_show_regs(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
@@ -128,7 +122,7 @@ static ssize_t spi_show_regs(struct file *file, char __user *user_buf,
static const struct file_operations mrst_spi_regs_ops = {
.owner = THIS_MODULE,
- .open = spi_show_regs_open,
+ .open = simple_open,
.read = spi_show_regs,
.llseek = default_llseek,
};
diff --git a/drivers/spi/spi-fsl-spi.c b/drivers/spi/spi-fsl-spi.c
index 24cacff57786..5f748c0d96bd 100644
--- a/drivers/spi/spi-fsl-spi.c
+++ b/drivers/spi/spi-fsl-spi.c
@@ -139,10 +139,12 @@ static void fsl_spi_change_mode(struct spi_device *spi)
static void fsl_spi_chipselect(struct spi_device *spi, int value)
{
struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(spi->master);
- struct fsl_spi_platform_data *pdata = spi->dev.parent->platform_data;
+ struct fsl_spi_platform_data *pdata;
bool pol = spi->mode & SPI_CS_HIGH;
struct spi_mpc8xxx_cs *cs = spi->controller_state;
+ pdata = spi->dev.parent->parent->platform_data;
+
if (value == BITBANG_CS_INACTIVE) {
if (pdata->cs_control)
pdata->cs_control(spi, !pol);
diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c
index 31054e3de4c1..570f22053be8 100644
--- a/drivers/spi/spi-imx.c
+++ b/drivers/spi/spi-imx.c
@@ -83,7 +83,7 @@ struct spi_imx_data {
struct spi_bitbang bitbang;
struct completion xfer_done;
- void *base;
+ void __iomem *base;
int irq;
struct clk *clk;
unsigned long spi_clk;
@@ -766,8 +766,12 @@ static int __devinit spi_imx_probe(struct platform_device *pdev)
}
ret = of_property_read_u32(np, "fsl,spi-num-chipselects", &num_cs);
- if (ret < 0)
- num_cs = mxc_platform_info->num_chipselect;
+ if (ret < 0) {
+ if (mxc_platform_info)
+ num_cs = mxc_platform_info->num_chipselect;
+ else
+ return ret;
+ }
master = spi_alloc_master(&pdev->dev,
sizeof(struct spi_imx_data) + sizeof(int) * num_cs);
@@ -784,7 +788,7 @@ static int __devinit spi_imx_probe(struct platform_device *pdev)
for (i = 0; i < master->num_chipselect; i++) {
int cs_gpio = of_get_named_gpio(np, "cs-gpios", i);
- if (cs_gpio < 0)
+ if (cs_gpio < 0 && mxc_platform_info)
cs_gpio = mxc_platform_info->chipselect[i];
spi_imx->chipselect[i] = cs_gpio;
diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c
index 96f0da66b185..09c925aaf320 100644
--- a/drivers/spi/spi-pl022.c
+++ b/drivers/spi/spi-pl022.c
@@ -2195,7 +2195,6 @@ static int pl022_runtime_suspend(struct device *dev)
struct pl022 *pl022 = dev_get_drvdata(dev);
clk_disable(pl022->clk);
- amba_vcore_disable(pl022->adev);
return 0;
}
@@ -2204,7 +2203,6 @@ static int pl022_runtime_resume(struct device *dev)
{
struct pl022 *pl022 = dev_get_drvdata(dev);
- amba_vcore_enable(pl022->adev);
clk_enable(pl022->clk);
return 0;
diff --git a/drivers/staging/android/Kconfig b/drivers/staging/android/Kconfig
index 08a3b1133d29..eb1dee26bda3 100644
--- a/drivers/staging/android/Kconfig
+++ b/drivers/staging/android/Kconfig
@@ -27,13 +27,14 @@ config ANDROID_LOGGER
config ANDROID_PERSISTENT_RAM
bool
+ depends on HAVE_MEMBLOCK
select REED_SOLOMON
select REED_SOLOMON_ENC8
select REED_SOLOMON_DEC8
config ANDROID_RAM_CONSOLE
bool "Android RAM buffer console"
- depends on !S390 && !UML
+ depends on !S390 && !UML && HAVE_MEMBLOCK
select ANDROID_PERSISTENT_RAM
default n
diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c
index 052b43e4e505..b91e4bc332a7 100644
--- a/drivers/staging/android/lowmemorykiller.c
+++ b/drivers/staging/android/lowmemorykiller.c
@@ -55,7 +55,6 @@ static int lowmem_minfree[6] = {
};
static int lowmem_minfree_size = 4;
-static struct task_struct *lowmem_deathpending;
static unsigned long lowmem_deathpending_timeout;
#define lowmem_print(level, x...) \
@@ -64,24 +63,6 @@ static unsigned long lowmem_deathpending_timeout;
printk(x); \
} while (0)
-static int
-task_notify_func(struct notifier_block *self, unsigned long val, void *data);
-
-static struct notifier_block task_nb = {
- .notifier_call = task_notify_func,
-};
-
-static int
-task_notify_func(struct notifier_block *self, unsigned long val, void *data)
-{
- struct task_struct *task = data;
-
- if (task == lowmem_deathpending)
- lowmem_deathpending = NULL;
-
- return NOTIFY_OK;
-}
-
static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc)
{
struct task_struct *tsk;
@@ -97,19 +78,6 @@ static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc)
int other_file = global_page_state(NR_FILE_PAGES) -
global_page_state(NR_SHMEM);
- /*
- * If we already have a death outstanding, then
- * bail out right away; indicating to vmscan
- * that we have nothing further to offer on
- * this pass.
- *
- * Note: Currently you need CONFIG_PROFILING
- * for this to work correctly.
- */
- if (lowmem_deathpending &&
- time_before_eq(jiffies, lowmem_deathpending_timeout))
- return 0;
-
if (lowmem_adj_size < array_size)
array_size = lowmem_adj_size;
if (lowmem_minfree_size < array_size)
@@ -148,6 +116,12 @@ static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc)
if (!p)
continue;
+ if (test_tsk_thread_flag(p, TIF_MEMDIE) &&
+ time_before_eq(jiffies, lowmem_deathpending_timeout)) {
+ task_unlock(p);
+ rcu_read_unlock();
+ return 0;
+ }
oom_score_adj = p->signal->oom_score_adj;
if (oom_score_adj < min_score_adj) {
task_unlock(p);
@@ -174,15 +148,9 @@ static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc)
lowmem_print(1, "send sigkill to %d (%s), adj %d, size %d\n",
selected->pid, selected->comm,
selected_oom_score_adj, selected_tasksize);
- /*
- * If CONFIG_PROFILING is off, then we don't want to stall
- * the killer by setting lowmem_deathpending.
- */
-#ifdef CONFIG_PROFILING
- lowmem_deathpending = selected;
lowmem_deathpending_timeout = jiffies + HZ;
-#endif
send_sig(SIGKILL, selected, 0);
+ set_tsk_thread_flag(selected, TIF_MEMDIE);
rem -= selected_tasksize;
}
lowmem_print(4, "lowmem_shrink %lu, %x, return %d\n",
@@ -198,7 +166,6 @@ static struct shrinker lowmem_shrinker = {
static int __init lowmem_init(void)
{
- task_handoff_register(&task_nb);
register_shrinker(&lowmem_shrinker);
return 0;
}
@@ -206,7 +173,6 @@ static int __init lowmem_init(void)
static void __exit lowmem_exit(void)
{
unregister_shrinker(&lowmem_shrinker);
- task_handoff_unregister(&task_nb);
}
module_param_named(cost, lowmem_shrinker.seeks, int, S_IRUGO | S_IWUSR);
diff --git a/drivers/staging/android/persistent_ram.c b/drivers/staging/android/persistent_ram.c
index e08f2574e30a..8d8c1e33e0ff 100644
--- a/drivers/staging/android/persistent_ram.c
+++ b/drivers/staging/android/persistent_ram.c
@@ -399,12 +399,12 @@ static __init
struct persistent_ram_zone *__persistent_ram_init(struct device *dev, bool ecc)
{
struct persistent_ram_zone *prz;
- int ret;
+ int ret = -ENOMEM;
prz = kzalloc(sizeof(struct persistent_ram_zone), GFP_KERNEL);
if (!prz) {
pr_err("persistent_ram: failed to allocate persistent ram zone\n");
- return ERR_PTR(-ENOMEM);
+ goto err;
}
INIT_LIST_HEAD(&prz->node);
@@ -412,13 +412,13 @@ struct persistent_ram_zone *__persistent_ram_init(struct device *dev, bool ecc)
ret = persistent_ram_buffer_init(dev_name(dev), prz);
if (ret) {
pr_err("persistent_ram: failed to initialize buffer\n");
- return ERR_PTR(ret);
+ goto err;
}
prz->ecc = ecc;
ret = persistent_ram_init_ecc(prz, prz->buffer_size);
if (ret)
- return ERR_PTR(ret);
+ goto err;
if (prz->buffer->sig == PERSISTENT_RAM_SIG) {
if (buffer_size(prz) > prz->buffer_size ||
@@ -442,6 +442,9 @@ struct persistent_ram_zone *__persistent_ram_init(struct device *dev, bool ecc)
atomic_set(&prz->buffer->size, 0);
return prz;
+err:
+ kfree(prz);
+ return ERR_PTR(ret);
}
struct persistent_ram_zone * __init
diff --git a/drivers/staging/android/timed_gpio.c b/drivers/staging/android/timed_gpio.c
index bc723eff11af..45c522cbe784 100644
--- a/drivers/staging/android/timed_gpio.c
+++ b/drivers/staging/android/timed_gpio.c
@@ -85,7 +85,7 @@ static int timed_gpio_probe(struct platform_device *pdev)
struct timed_gpio_platform_data *pdata = pdev->dev.platform_data;
struct timed_gpio *cur_gpio;
struct timed_gpio_data *gpio_data, *gpio_dat;
- int i, j, ret = 0;
+ int i, ret;
if (!pdata)
return -EBUSY;
@@ -108,18 +108,12 @@ static int timed_gpio_probe(struct platform_device *pdev)
gpio_dat->dev.get_time = gpio_get_time;
gpio_dat->dev.enable = gpio_enable;
ret = gpio_request(cur_gpio->gpio, cur_gpio->name);
- if (ret >= 0) {
- ret = timed_output_dev_register(&gpio_dat->dev);
- if (ret < 0)
- gpio_free(cur_gpio->gpio);
- }
+ if (ret < 0)
+ goto err_out;
+ ret = timed_output_dev_register(&gpio_dat->dev);
if (ret < 0) {
- for (j = 0; j < i; j++) {
- timed_output_dev_unregister(&gpio_data[i].dev);
- gpio_free(gpio_data[i].gpio);
- }
- kfree(gpio_data);
- return ret;
+ gpio_free(cur_gpio->gpio);
+ goto err_out;
}
gpio_dat->gpio = cur_gpio->gpio;
@@ -131,6 +125,15 @@ static int timed_gpio_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, gpio_data);
return 0;
+
+err_out:
+ while (--i >= 0) {
+ timed_output_dev_unregister(&gpio_data[i].dev);
+ gpio_free(gpio_data[i].gpio);
+ }
+ kfree(gpio_data);
+
+ return ret;
}
static int timed_gpio_remove(struct platform_device *pdev)
diff --git a/drivers/staging/iio/inkern.c b/drivers/staging/iio/inkern.c
index de2c8ea64965..ef07a02bf542 100644
--- a/drivers/staging/iio/inkern.c
+++ b/drivers/staging/iio/inkern.c
@@ -82,6 +82,7 @@ int iio_map_array_unregister(struct iio_dev *indio_dev,
ret = -ENODEV;
goto error_ret;
}
+ i++;
}
error_ret:
mutex_unlock(&iio_map_list_lock);
diff --git a/drivers/staging/iio/magnetometer/ak8975.c b/drivers/staging/iio/magnetometer/ak8975.c
index d5ddac3d8831..ebc2d0840caf 100644
--- a/drivers/staging/iio/magnetometer/ak8975.c
+++ b/drivers/staging/iio/magnetometer/ak8975.c
@@ -108,7 +108,8 @@ static const int ak8975_index_to_reg[] = {
static int ak8975_write_data(struct i2c_client *client,
u8 reg, u8 val, u8 mask, u8 shift)
{
- struct ak8975_data *data = i2c_get_clientdata(client);
+ struct iio_dev *indio_dev = i2c_get_clientdata(client);
+ struct ak8975_data *data = iio_priv(indio_dev);
u8 regval;
int ret;
@@ -159,7 +160,8 @@ static int ak8975_read_data(struct i2c_client *client,
*/
static int ak8975_setup(struct i2c_client *client)
{
- struct ak8975_data *data = i2c_get_clientdata(client);
+ struct iio_dev *indio_dev = i2c_get_clientdata(client);
+ struct ak8975_data *data = iio_priv(indio_dev);
u8 device_id;
int ret;
@@ -509,6 +511,7 @@ static int ak8975_probe(struct i2c_client *client,
goto exit_gpio;
}
data = iio_priv(indio_dev);
+ i2c_set_clientdata(client, indio_dev);
/* Perform some basic start-of-day setup of the device. */
err = ak8975_setup(client);
if (err < 0) {
@@ -516,7 +519,6 @@ static int ak8975_probe(struct i2c_client *client,
goto exit_free_iio;
}
- i2c_set_clientdata(client, indio_dev);
data->client = client;
mutex_init(&data->lock);
data->eoc_irq = client->irq;
diff --git a/drivers/staging/iio/magnetometer/hmc5843.c b/drivers/staging/iio/magnetometer/hmc5843.c
index 91dd3da70cb4..e00b416c4d33 100644
--- a/drivers/staging/iio/magnetometer/hmc5843.c
+++ b/drivers/staging/iio/magnetometer/hmc5843.c
@@ -521,7 +521,9 @@ static int hmc5843_detect(struct i2c_client *client,
/* Called when we have found a new HMC5843. */
static void hmc5843_init_client(struct i2c_client *client)
{
- struct hmc5843_data *data = i2c_get_clientdata(client);
+ struct iio_dev *indio_dev = i2c_get_clientdata(client);
+ struct hmc5843_data *data = iio_priv(indio_dev);
+
hmc5843_set_meas_conf(client, data->meas_conf);
hmc5843_set_rate(client, data->rate);
hmc5843_configure(client, data->operating_mode);
diff --git a/drivers/staging/media/as102/as102_fw.c b/drivers/staging/media/as102/as102_fw.c
index 43ebc43e6b9a..1075fb1df0d9 100644
--- a/drivers/staging/media/as102/as102_fw.c
+++ b/drivers/staging/media/as102/as102_fw.c
@@ -165,7 +165,7 @@ error:
int as102_fw_upload(struct as10x_bus_adapter_t *bus_adap)
{
int errno = -EFAULT;
- const struct firmware *firmware;
+ const struct firmware *firmware = NULL;
unsigned char *cmd_buf = NULL;
char *fw1, *fw2;
struct usb_device *dev = bus_adap->usb_dev;
diff --git a/drivers/staging/omapdrm/omap_drv.c b/drivers/staging/omapdrm/omap_drv.c
index 3df5b4c58ecd..620b8d54223d 100644
--- a/drivers/staging/omapdrm/omap_drv.c
+++ b/drivers/staging/omapdrm/omap_drv.c
@@ -803,9 +803,6 @@ static void pdev_shutdown(struct platform_device *device)
static int pdev_probe(struct platform_device *device)
{
DBG("%s", device->name);
- if (platform_driver_register(&omap_dmm_driver))
- dev_err(&device->dev, "DMM registration failed\n");
-
return drm_platform_init(&omap_drm_driver, device);
}
@@ -833,6 +830,10 @@ struct platform_driver pdev = {
static int __init omap_drm_init(void)
{
DBG("init");
+ if (platform_driver_register(&omap_dmm_driver)) {
+ /* we can continue on without DMM.. so not fatal */
+ dev_err(NULL, "DMM registration failed\n");
+ }
return platform_driver_register(&pdev);
}
diff --git a/drivers/staging/ozwpan/TODO b/drivers/staging/ozwpan/TODO
index f7a9c122f596..c2d30a7112f3 100644
--- a/drivers/staging/ozwpan/TODO
+++ b/drivers/staging/ozwpan/TODO
@@ -8,5 +8,7 @@ TODO:
- code review by USB developer community.
- testing with as many devices as possible.
-Please send any patches for this driver to Chris Kelly <ckelly@ozmodevices.com>
+Please send any patches for this driver to
+Rupesh Gujare <rgujare@ozmodevices.com>
+Chris Kelly <ckelly@ozmodevices.com>
and Greg Kroah-Hartman <gregkh@linuxfoundation.org>.
diff --git a/drivers/staging/ramster/Kconfig b/drivers/staging/ramster/Kconfig
index 8b57b87edda4..4af1f8d4b953 100644
--- a/drivers/staging/ramster/Kconfig
+++ b/drivers/staging/ramster/Kconfig
@@ -1,10 +1,6 @@
-# Dependency on CONFIG_BROKEN is because there is a commit dependency
-# on a cleancache naming change to be submitted by Konrad Wilk
-# a39c00ded70339603ffe1b0ffdf3ade85bcf009a "Merge branch 'stable/cleancache.v13'
-# into linux-next. Once this commit is present, BROKEN can be removed
config RAMSTER
bool "Cross-machine RAM capacity sharing, aka peer-to-peer tmem"
- depends on (CLEANCACHE || FRONTSWAP) && CONFIGFS_FS=y && !ZCACHE && !XVMALLOC && !HIGHMEM && BROKEN
+ depends on (CLEANCACHE || FRONTSWAP) && CONFIGFS_FS=y && !ZCACHE && !XVMALLOC && !HIGHMEM
select LZO_COMPRESS
select LZO_DECOMPRESS
default n
diff --git a/drivers/staging/rts_pstor/ms.c b/drivers/staging/rts_pstor/ms.c
index 66341dff8c99..f9a4498984cc 100644
--- a/drivers/staging/rts_pstor/ms.c
+++ b/drivers/staging/rts_pstor/ms.c
@@ -3498,7 +3498,8 @@ static int ms_rw_multi_sector(struct scsi_cmnd *srb, struct rtsx_chip *chip, u32
log_blk++;
- for (seg_no = 0; seg_no < sizeof(ms_start_idx)/2; seg_no++) {
+ for (seg_no = 0; seg_no < ARRAY_SIZE(ms_start_idx) - 1;
+ seg_no++) {
if (log_blk < ms_start_idx[seg_no+1])
break;
}
diff --git a/drivers/staging/rts_pstor/rtsx.c b/drivers/staging/rts_pstor/rtsx.c
index a7feb3e328a0..1dccd933a7e4 100644
--- a/drivers/staging/rts_pstor/rtsx.c
+++ b/drivers/staging/rts_pstor/rtsx.c
@@ -1000,6 +1000,11 @@ static int __devinit rtsx_probe(struct pci_dev *pci,
rtsx_init_chip(dev->chip);
+ /* set the supported max_lun and max_id for the scsi host
+ * NOTE: the minimal value of max_id is 1 */
+ host->max_id = 1;
+ host->max_lun = dev->chip->max_lun;
+
/* Start up our control thread */
th = kthread_run(rtsx_control_thread, dev, CR_DRIVER_NAME);
if (IS_ERR(th)) {
diff --git a/drivers/staging/rts_pstor/rtsx_transport.c b/drivers/staging/rts_pstor/rtsx_transport.c
index 4e3d2c106af0..9b2e5c99870f 100644
--- a/drivers/staging/rts_pstor/rtsx_transport.c
+++ b/drivers/staging/rts_pstor/rtsx_transport.c
@@ -335,6 +335,7 @@ static int rtsx_transfer_sglist_adma_partial(struct rtsx_chip *chip, u8 card,
int sg_cnt, i, resid;
int err = 0;
long timeleft;
+ struct scatterlist *sg_ptr;
u32 val = TRIG_DMA;
if ((sg == NULL) || (num_sg <= 0) || !offset || !index)
@@ -371,7 +372,7 @@ static int rtsx_transfer_sglist_adma_partial(struct rtsx_chip *chip, u8 card,
sg_cnt = dma_map_sg(&(rtsx->pci->dev), sg, num_sg, dma_dir);
resid = size;
-
+ sg_ptr = sg;
chip->sgi = 0;
/* Usually the next entry will be @sg@ + 1, but if this sg element
* is part of a chained scatterlist, it could jump to the start of
@@ -379,14 +380,14 @@ static int rtsx_transfer_sglist_adma_partial(struct rtsx_chip *chip, u8 card,
* the proper sg
*/
for (i = 0; i < *index; i++)
- sg = sg_next(sg);
+ sg_ptr = sg_next(sg_ptr);
for (i = *index; i < sg_cnt; i++) {
dma_addr_t addr;
unsigned int len;
u8 option;
- addr = sg_dma_address(sg);
- len = sg_dma_len(sg);
+ addr = sg_dma_address(sg_ptr);
+ len = sg_dma_len(sg_ptr);
RTSX_DEBUGP("DMA addr: 0x%x, Len: 0x%x\n",
(unsigned int)addr, len);
@@ -415,7 +416,7 @@ static int rtsx_transfer_sglist_adma_partial(struct rtsx_chip *chip, u8 card,
if (!resid)
break;
- sg = sg_next(sg);
+ sg_ptr = sg_next(sg_ptr);
}
RTSX_DEBUGP("SG table count = %d\n", chip->sgi);
diff --git a/drivers/staging/sep/sep_main.c b/drivers/staging/sep/sep_main.c
index ad54c2e5c932..f1701bc6e312 100644
--- a/drivers/staging/sep/sep_main.c
+++ b/drivers/staging/sep/sep_main.c
@@ -3114,7 +3114,7 @@ static long sep_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
current->pid);
if (1 == test_bit(SEP_LEGACY_SENDMSG_DONE_OFFSET,
&call_status->status)) {
- dev_warn(&sep->pdev->dev,
+ dev_dbg(&sep->pdev->dev,
"[PID%d] dcb prep needed before send msg\n",
current->pid);
error = -EPROTO;
@@ -3122,9 +3122,9 @@ static long sep_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
}
if (!arg) {
- dev_warn(&sep->pdev->dev,
+ dev_dbg(&sep->pdev->dev,
"[PID%d] dcb null arg\n", current->pid);
- error = EINVAL;
+ error = -EINVAL;
goto end_function;
}
diff --git a/drivers/staging/vme/devices/vme_pio2_core.c b/drivers/staging/vme/devices/vme_pio2_core.c
index 9fedc442a779..573c80003f0c 100644
--- a/drivers/staging/vme/devices/vme_pio2_core.c
+++ b/drivers/staging/vme/devices/vme_pio2_core.c
@@ -35,10 +35,10 @@ static int vector[PIO2_CARDS_MAX];
static int vector_num;
static int level[PIO2_CARDS_MAX];
static int level_num;
-static const char *variant[PIO2_CARDS_MAX];
+static char *variant[PIO2_CARDS_MAX];
static int variant_num;
-static int loopback;
+static bool loopback;
static int pio2_match(struct vme_dev *);
static int __devinit pio2_probe(struct vme_dev *);
diff --git a/drivers/staging/vt6655/key.c b/drivers/staging/vt6655/key.c
index 0ff8d7bbf2a7..774b0d4a7e06 100644
--- a/drivers/staging/vt6655/key.c
+++ b/drivers/staging/vt6655/key.c
@@ -655,6 +655,9 @@ bool KeybSetDefaultKey (
return (false);
}
+ if (uKeyLength > MAX_KEY_LEN)
+ return false;
+
pTable->KeyTable[MAX_KEY_TABLE-1].bInUse = true;
for(ii=0;ii<ETH_ALEN;ii++)
pTable->KeyTable[MAX_KEY_TABLE-1].abyBSSID[ii] = 0xFF;
diff --git a/drivers/staging/vt6656/ioctl.c b/drivers/staging/vt6656/ioctl.c
index 1463d76895f0..d59456c29df1 100644
--- a/drivers/staging/vt6656/ioctl.c
+++ b/drivers/staging/vt6656/ioctl.c
@@ -565,7 +565,7 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq)
result = -ENOMEM;
break;
}
- pNodeList = (PSNodeList)kmalloc(sizeof(SNodeList) + (sNodeList.uItem * sizeof(SNodeItem)), (int)GFP_ATOMIC);
+ pNodeList = kmalloc(sizeof(SNodeList) + (sNodeList.uItem * sizeof(SNodeItem)), (int)GFP_ATOMIC);
if (pNodeList == NULL) {
result = -ENOMEM;
break;
@@ -601,6 +601,7 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq)
}
}
if (copy_to_user(pReq->data, pNodeList, sizeof(SNodeList) + (sNodeList.uItem * sizeof(SNodeItem)))) {
+ kfree(pNodeList);
result = -EFAULT;
break;
}
diff --git a/drivers/staging/vt6656/key.c b/drivers/staging/vt6656/key.c
index 27bb523c8a97..ee62a06a75f4 100644
--- a/drivers/staging/vt6656/key.c
+++ b/drivers/staging/vt6656/key.c
@@ -684,6 +684,9 @@ BOOL KeybSetDefaultKey(
return (FALSE);
}
+ if (uKeyLength > MAX_KEY_LEN)
+ return false;
+
pTable->KeyTable[MAX_KEY_TABLE-1].bInUse = TRUE;
for (ii = 0; ii < ETH_ALEN; ii++)
pTable->KeyTable[MAX_KEY_TABLE-1].abyBSSID[ii] = 0xFF;
diff --git a/drivers/staging/xgifb/vb_init.c b/drivers/staging/xgifb/vb_init.c
index 94d5c35e22fb..3650bbff7686 100644
--- a/drivers/staging/xgifb/vb_init.c
+++ b/drivers/staging/xgifb/vb_init.c
@@ -61,7 +61,7 @@ XGINew_GetXG20DRAMType(struct xgi_hw_device_info *HwDeviceExtension,
}
temp = xgifb_reg_get(pVBInfo->P3c4, 0x3B);
/* SR3B[7][3]MAA15 MAA11 (Power on Trapping) */
- if ((temp & 0x88) == 0x80)
+ if (((temp & 0x88) == 0x80) || ((temp & 0x88) == 0x08))
data = 0; /* DDR */
else
data = 1; /* DDRII */
diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c
index 2919924213c4..60d4adf99923 100644
--- a/drivers/staging/xgifb/vb_setmode.c
+++ b/drivers/staging/xgifb/vb_setmode.c
@@ -152,6 +152,7 @@ void InitTo330Pointer(unsigned char ChipType, struct vb_device_info *pVBInfo)
pVBInfo->pXGINew_CR97 = &XG20_CR97;
if (ChipType == XG27) {
+ unsigned char temp;
pVBInfo->MCLKData
= (struct SiS_MCLKData *) XGI27New_MCLKData;
pVBInfo->CR40 = XGI27_cr41;
@@ -162,7 +163,13 @@ void InitTo330Pointer(unsigned char ChipType, struct vb_device_info *pVBInfo)
pVBInfo->pCRDE = XG27_CRDE;
pVBInfo->pSR40 = &XG27_SR40;
pVBInfo->pSR41 = &XG27_SR41;
+ pVBInfo->SR15 = XG27_SR13;
+ /*Z11m DDR*/
+ temp = xgifb_reg_get(pVBInfo->P3c4, 0x3B);
+ /* SR3B[7][3]MAA15 MAA11 (Power on Trapping) */
+ if (((temp & 0x88) == 0x80) || ((temp & 0x88) == 0x08))
+ pVBInfo->pXGINew_CR97 = &Z11m_CR97;
}
if (ChipType >= XG20) {
diff --git a/drivers/staging/xgifb/vb_table.h b/drivers/staging/xgifb/vb_table.h
index dddf261ed53d..e8d6f674b274 100644
--- a/drivers/staging/xgifb/vb_table.h
+++ b/drivers/staging/xgifb/vb_table.h
@@ -33,6 +33,13 @@ static struct XGI_ECLKDataStruct XGI340_ECLKData[] = {
{0x5c, 0x23, 0x01, 166}
};
+static unsigned char XG27_SR13[4][8] = {
+ {0x35, 0x45, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00}, /* SR13 */
+ {0x41, 0x51, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00}, /* SR14 */
+ {0x32, 0x32, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00}, /* SR18 */
+ {0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00} /* SR1B */
+};
+
static unsigned char XGI340_SR13[4][8] = {
{0x35, 0x45, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00}, /* SR13 */
{0x41, 0x51, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00}, /* SR14 */
@@ -71,7 +78,7 @@ static unsigned char XGI27_cr41[24][8] = {
{0x20, 0x40, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0 CR41 */
{0xC4, 0x40, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 1 CR8A */
{0xC4, 0x40, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 2 CR8B */
- {0xB5, 0x13, 0xa4, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 3 CR40[7],
+ {0xB3, 0x13, 0xa4, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 3 CR40[7],
CR99[2:0],
CR45[3:0]*/
{0xf0, 0xf5, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 4 CR59 */
@@ -2803,6 +2810,8 @@ static unsigned char XG27_CRDE[2];
static unsigned char XG27_SR40 = 0x04 ;
static unsigned char XG27_SR41 = 0x00 ;
+static unsigned char Z11m_CR97 = 0x80 ;
+
static struct XGI330_VCLKDataStruct XGI_VCLKData[] = {
/* SR2B,SR2C,SR2D */
{0x1B, 0xE1, 25}, /* 00 (25.175MHz) */
diff --git a/drivers/staging/zsmalloc/zsmalloc-main.c b/drivers/staging/zsmalloc/zsmalloc-main.c
index 09caa4f2687e..917461c66014 100644
--- a/drivers/staging/zsmalloc/zsmalloc-main.c
+++ b/drivers/staging/zsmalloc/zsmalloc-main.c
@@ -267,33 +267,39 @@ static unsigned long obj_idx_to_offset(struct page *page,
return off + obj_idx * class_size;
}
+static void reset_page(struct page *page)
+{
+ clear_bit(PG_private, &page->flags);
+ clear_bit(PG_private_2, &page->flags);
+ set_page_private(page, 0);
+ page->mapping = NULL;
+ page->freelist = NULL;
+ reset_page_mapcount(page);
+}
+
static void free_zspage(struct page *first_page)
{
- struct page *nextp, *tmp;
+ struct page *nextp, *tmp, *head_extra;
BUG_ON(!is_first_page(first_page));
BUG_ON(first_page->inuse);
- nextp = (struct page *)page_private(first_page);
+ head_extra = (struct page *)page_private(first_page);
- clear_bit(PG_private, &first_page->flags);
- clear_bit(PG_private_2, &first_page->flags);
- set_page_private(first_page, 0);
- first_page->mapping = NULL;
- first_page->freelist = NULL;
- reset_page_mapcount(first_page);
+ reset_page(first_page);
__free_page(first_page);
/* zspage with only 1 system page */
- if (!nextp)
+ if (!head_extra)
return;
- list_for_each_entry_safe(nextp, tmp, &nextp->lru, lru) {
+ list_for_each_entry_safe(nextp, tmp, &head_extra->lru, lru) {
list_del(&nextp->lru);
- clear_bit(PG_private_2, &nextp->flags);
- nextp->index = 0;
+ reset_page(nextp);
__free_page(nextp);
}
+ reset_page(head_extra);
+ __free_page(head_extra);
}
/* Initialize a newly allocated zspage */
diff --git a/drivers/target/tcm_fc/tcm_fc.h b/drivers/target/tcm_fc/tcm_fc.h
index 830657908db8..c5eb3c33c3db 100644
--- a/drivers/target/tcm_fc/tcm_fc.h
+++ b/drivers/target/tcm_fc/tcm_fc.h
@@ -122,6 +122,7 @@ struct ft_cmd {
/* Local sense buffer */
unsigned char ft_sense_buffer[TRANSPORT_SENSE_BUFFER];
u32 was_ddp_setup:1; /* Set only if ddp is setup */
+ u32 aborted:1; /* Set if aborted by reset or timeout */
struct scatterlist *sg; /* Set only if DDP is setup */
u32 sg_cnt; /* No. of item in scatterlist */
};
diff --git a/drivers/target/tcm_fc/tfc_cmd.c b/drivers/target/tcm_fc/tfc_cmd.c
index 62dec9715ce5..a375f257aabc 100644
--- a/drivers/target/tcm_fc/tfc_cmd.c
+++ b/drivers/target/tcm_fc/tfc_cmd.c
@@ -121,6 +121,8 @@ int ft_queue_status(struct se_cmd *se_cmd)
struct fc_exch *ep;
size_t len;
+ if (cmd->aborted)
+ return 0;
ft_dump_cmd(cmd, __func__);
ep = fc_seq_exch(cmd->seq);
lport = ep->lp;
@@ -187,6 +189,8 @@ int ft_write_pending(struct se_cmd *se_cmd)
ft_dump_cmd(cmd, __func__);
+ if (cmd->aborted)
+ return 0;
ep = fc_seq_exch(cmd->seq);
lport = ep->lp;
fp = fc_frame_alloc(lport, sizeof(*txrdy));
@@ -252,10 +256,10 @@ static void ft_recv_seq(struct fc_seq *sp, struct fc_frame *fp, void *arg)
struct ft_cmd *cmd = arg;
struct fc_frame_header *fh;
- if (IS_ERR(fp)) {
+ if (unlikely(IS_ERR(fp))) {
/* XXX need to find cmd if queued */
cmd->seq = NULL;
- transport_generic_free_cmd(&cmd->se_cmd, 0);
+ cmd->aborted = true;
return;
}
@@ -399,6 +403,8 @@ int ft_queue_tm_resp(struct se_cmd *se_cmd)
struct se_tmr_req *tmr = se_cmd->se_tmr_req;
enum fcp_resp_rsp_codes code;
+ if (cmd->aborted)
+ return 0;
switch (tmr->response) {
case TMR_FUNCTION_COMPLETE:
code = FCP_TMF_CMPL;
diff --git a/drivers/target/tcm_fc/tfc_conf.c b/drivers/target/tcm_fc/tfc_conf.c
index f357039349ba..2948dc944619 100644
--- a/drivers/target/tcm_fc/tfc_conf.c
+++ b/drivers/target/tcm_fc/tfc_conf.c
@@ -300,6 +300,7 @@ static struct se_portal_group *ft_add_tpg(
{
struct ft_lport_acl *lacl;
struct ft_tpg *tpg;
+ struct workqueue_struct *wq;
unsigned long index;
int ret;
@@ -321,18 +322,20 @@ static struct se_portal_group *ft_add_tpg(
tpg->lport_acl = lacl;
INIT_LIST_HEAD(&tpg->lun_list);
- ret = core_tpg_register(&ft_configfs->tf_ops, wwn, &tpg->se_tpg,
- tpg, TRANSPORT_TPG_TYPE_NORMAL);
- if (ret < 0) {
+ wq = alloc_workqueue("tcm_fc", 0, 1);
+ if (!wq) {
kfree(tpg);
return NULL;
}
- tpg->workqueue = alloc_workqueue("tcm_fc", 0, 1);
- if (!tpg->workqueue) {
+ ret = core_tpg_register(&ft_configfs->tf_ops, wwn, &tpg->se_tpg,
+ tpg, TRANSPORT_TPG_TYPE_NORMAL);
+ if (ret < 0) {
+ destroy_workqueue(wq);
kfree(tpg);
return NULL;
}
+ tpg->workqueue = wq;
mutex_lock(&ft_lport_lock);
list_add_tail(&tpg->list, &lacl->tpg_list);
diff --git a/drivers/target/tcm_fc/tfc_io.c b/drivers/target/tcm_fc/tfc_io.c
index 2b693eefac55..dc7c0db26e20 100644
--- a/drivers/target/tcm_fc/tfc_io.c
+++ b/drivers/target/tcm_fc/tfc_io.c
@@ -81,6 +81,8 @@ int ft_queue_data_in(struct se_cmd *se_cmd)
void *from;
void *to = NULL;
+ if (cmd->aborted)
+ return 0;
ep = fc_seq_exch(cmd->seq);
lport = ep->lp;
cmd->seq = lport->tt.seq_start_next(cmd->seq);
diff --git a/drivers/tty/amiserial.c b/drivers/tty/amiserial.c
index 24145c30c9b0..6cc4358f68c1 100644
--- a/drivers/tty/amiserial.c
+++ b/drivers/tty/amiserial.c
@@ -1073,8 +1073,10 @@ static int set_serial_info(struct tty_struct *tty, struct serial_state *state,
(new_serial.close_delay != port->close_delay) ||
(new_serial.xmit_fifo_size != state->xmit_fifo_size) ||
((new_serial.flags & ~ASYNC_USR_MASK) !=
- (port->flags & ~ASYNC_USR_MASK)))
+ (port->flags & ~ASYNC_USR_MASK))) {
+ tty_unlock();
return -EPERM;
+ }
port->flags = ((port->flags & ~ASYNC_USR_MASK) |
(new_serial.flags & ASYNC_USR_MASK));
state->custom_divisor = new_serial.custom_divisor;
diff --git a/drivers/tty/serial/8250/8250.c b/drivers/tty/serial/8250/8250.c
index 5b149b466ec8..5c27f7e6c9f1 100644
--- a/drivers/tty/serial/8250/8250.c
+++ b/drivers/tty/serial/8250/8250.c
@@ -1572,13 +1572,11 @@ static irqreturn_t serial8250_interrupt(int irq, void *dev_id)
do {
struct uart_8250_port *up;
struct uart_port *port;
- bool skip;
up = list_entry(l, struct uart_8250_port, list);
port = &up->port;
- skip = pass_counter && up->port.flags & UPF_IIR_ONCE;
- if (!skip && port->handle_irq(port)) {
+ if (port->handle_irq(port)) {
handled = 1;
end = NULL;
} else if (end == NULL)
@@ -2037,10 +2035,12 @@ static int serial8250_startup(struct uart_port *port)
spin_unlock_irqrestore(&port->lock, flags);
/*
- * If the interrupt is not reasserted, setup a timer to
- * kick the UART on a regular basis.
+ * If the interrupt is not reasserted, or we otherwise
+ * don't trust the iir, setup a timer to kick the UART
+ * on a regular basis.
*/
- if (!(iir1 & UART_IIR_NO_INT) && (iir & UART_IIR_NO_INT)) {
+ if ((!(iir1 & UART_IIR_NO_INT) && (iir & UART_IIR_NO_INT)) ||
+ up->port.flags & UPF_BUG_THRE) {
up->bugs |= UART_BUG_THRE;
pr_debug("ttyS%d - using backup timer\n",
serial_index(port));
diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c
index da2b0b0a183f..858dca865d6a 100644
--- a/drivers/tty/serial/8250/8250_pci.c
+++ b/drivers/tty/serial/8250/8250_pci.c
@@ -1096,7 +1096,7 @@ static int kt_serial_setup(struct serial_private *priv,
const struct pciserial_board *board,
struct uart_port *port, int idx)
{
- port->flags |= UPF_IIR_ONCE;
+ port->flags |= UPF_BUG_THRE;
return skip_tx_en_setup(priv, board, port, idx);
}
@@ -1118,18 +1118,6 @@ pci_xr17c154_setup(struct serial_private *priv,
return pci_default_setup(priv, board, port, idx);
}
-static int try_enable_msi(struct pci_dev *dev)
-{
- /* use msi if available, but fallback to legacy otherwise */
- pci_enable_msi(dev);
- return 0;
-}
-
-static void disable_msi(struct pci_dev *dev)
-{
- pci_disable_msi(dev);
-}
-
#define PCI_VENDOR_ID_SBSMODULARIO 0x124B
#define PCI_SUBVENDOR_ID_SBSMODULARIO 0x124B
#define PCI_DEVICE_ID_OCTPRO 0x0001
@@ -1249,9 +1237,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
.device = PCI_DEVICE_ID_INTEL_PATSBURG_KT,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
- .init = try_enable_msi,
.setup = kt_serial_setup,
- .exit = disable_msi,
},
/*
* ITE
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
index 665beb68f670..070b442c1f81 100644
--- a/drivers/tty/serial/Kconfig
+++ b/drivers/tty/serial/Kconfig
@@ -1041,7 +1041,7 @@ config SERIAL_OMAP
config SERIAL_OMAP_CONSOLE
bool "Console on OMAP serial port"
- depends on SERIAL_OMAP
+ depends on SERIAL_OMAP=y
select SERIAL_CORE_CONSOLE
help
Select this option if you would like to use omap serial port as
diff --git a/drivers/tty/serial/altera_uart.c b/drivers/tty/serial/altera_uart.c
index e7903751e058..1f0330915d5a 100644
--- a/drivers/tty/serial/altera_uart.c
+++ b/drivers/tty/serial/altera_uart.c
@@ -556,7 +556,7 @@ static int __devinit altera_uart_probe(struct platform_device *pdev)
res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (res_mem)
port->mapbase = res_mem->start;
- else if (platp->mapbase)
+ else if (platp)
port->mapbase = platp->mapbase;
else
return -EINVAL;
@@ -564,7 +564,7 @@ static int __devinit altera_uart_probe(struct platform_device *pdev)
res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
if (res_irq)
port->irq = res_irq->start;
- else if (platp->irq)
+ else if (platp)
port->irq = platp->irq;
/* Check platform data first so we can override device node data */
diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c
index 0c65c9e66986..3d569cd68f58 100644
--- a/drivers/tty/serial/amba-pl011.c
+++ b/drivers/tty/serial/amba-pl011.c
@@ -1946,10 +1946,6 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id)
goto unmap;
}
- /* Ensure interrupts from this UART are masked and cleared */
- writew(0, uap->port.membase + UART011_IMSC);
- writew(0xffff, uap->port.membase + UART011_ICR);
-
uap->vendor = vendor;
uap->lcrh_rx = vendor->lcrh_rx;
uap->lcrh_tx = vendor->lcrh_tx;
@@ -1967,6 +1963,10 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id)
uap->port.line = i;
pl011_dma_probe(uap);
+ /* Ensure interrupts from this UART are masked and cleared */
+ writew(0, uap->port.membase + UART011_IMSC);
+ writew(0xffff, uap->port.membase + UART011_ICR);
+
snprintf(uap->type, sizeof(uap->type), "PL011 rev%u", amba_rev(dev));
amba_ports[i] = uap;
diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c
index f9a6be7a9bed..3d7e1ee2fa57 100644
--- a/drivers/tty/serial/atmel_serial.c
+++ b/drivers/tty/serial/atmel_serial.c
@@ -389,6 +389,8 @@ static void atmel_start_rx(struct uart_port *port)
{
UART_PUT_CR(port, ATMEL_US_RSTSTA); /* reset status and receiver */
+ UART_PUT_CR(port, ATMEL_US_RXEN);
+
if (atmel_use_dma_rx(port)) {
/* enable PDC controller */
UART_PUT_IER(port, ATMEL_US_ENDRX | ATMEL_US_TIMEOUT |
@@ -404,6 +406,8 @@ static void atmel_start_rx(struct uart_port *port)
*/
static void atmel_stop_rx(struct uart_port *port)
{
+ UART_PUT_CR(port, ATMEL_US_RXDIS);
+
if (atmel_use_dma_rx(port)) {
/* disable PDC receive */
UART_PUT_PTCR(port, ATMEL_PDC_RXTDIS);
diff --git a/drivers/tty/serial/clps711x.c b/drivers/tty/serial/clps711x.c
index e6c3dbd781d6..836fe2731234 100644
--- a/drivers/tty/serial/clps711x.c
+++ b/drivers/tty/serial/clps711x.c
@@ -154,10 +154,9 @@ static irqreturn_t clps711xuart_int_tx(int irq, void *dev_id)
port->x_char = 0;
return IRQ_HANDLED;
}
- if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
- clps711xuart_stop_tx(port);
- return IRQ_HANDLED;
- }
+
+ if (uart_circ_empty(xmit) || uart_tx_stopped(port))
+ goto disable_tx_irq;
count = port->fifosize >> 1;
do {
@@ -171,8 +170,11 @@ static irqreturn_t clps711xuart_int_tx(int irq, void *dev_id)
if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
uart_write_wakeup(port);
- if (uart_circ_empty(xmit))
- clps711xuart_stop_tx(port);
+ if (uart_circ_empty(xmit)) {
+ disable_tx_irq:
+ disable_irq_nosync(TX_IRQ(port));
+ tx_enabled(port) = 0;
+ }
return IRQ_HANDLED;
}
diff --git a/drivers/tty/serial/mfd.c b/drivers/tty/serial/mfd.c
index a9234ba8f8d5..c4b50af46c44 100644
--- a/drivers/tty/serial/mfd.c
+++ b/drivers/tty/serial/mfd.c
@@ -127,11 +127,6 @@ static inline void serial_out(struct uart_hsu_port *up, int offset, int value)
#define HSU_REGS_BUFSIZE 1024
-static int hsu_show_regs_open(struct inode *inode, struct file *file)
-{
- file->private_data = inode->i_private;
- return 0;
-}
static ssize_t port_show_regs(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
@@ -231,14 +226,14 @@ static ssize_t dma_show_regs(struct file *file, char __user *user_buf,
static const struct file_operations port_regs_ops = {
.owner = THIS_MODULE,
- .open = hsu_show_regs_open,
+ .open = simple_open,
.read = port_show_regs,
.llseek = default_llseek,
};
static const struct file_operations dma_regs_ops = {
.owner = THIS_MODULE,
- .open = hsu_show_regs_open,
+ .open = simple_open,
.read = dma_show_regs,
.llseek = default_llseek,
};
diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c
index 0121486ac4fa..d00b38eb268e 100644
--- a/drivers/tty/serial/omap-serial.c
+++ b/drivers/tty/serial/omap-serial.c
@@ -1381,29 +1381,24 @@ static int serial_omap_probe(struct platform_device *pdev)
return -ENODEV;
}
- if (!request_mem_region(mem->start, resource_size(mem),
+ if (!devm_request_mem_region(&pdev->dev, mem->start, resource_size(mem),
pdev->dev.driver->name)) {
dev_err(&pdev->dev, "memory region already claimed\n");
return -EBUSY;
}
dma_rx = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx");
- if (!dma_rx) {
- ret = -EINVAL;
- goto err;
- }
+ if (!dma_rx)
+ return -ENXIO;
dma_tx = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx");
- if (!dma_tx) {
- ret = -EINVAL;
- goto err;
- }
+ if (!dma_tx)
+ return -ENXIO;
+
+ up = devm_kzalloc(&pdev->dev, sizeof(*up), GFP_KERNEL);
+ if (!up)
+ return -ENOMEM;
- up = kzalloc(sizeof(*up), GFP_KERNEL);
- if (up == NULL) {
- ret = -ENOMEM;
- goto do_release_region;
- }
up->pdev = pdev;
up->port.dev = &pdev->dev;
up->port.type = PORT_OMAP;
@@ -1423,16 +1418,17 @@ static int serial_omap_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "failed to get alias/pdev id, errno %d\n",
up->port.line);
ret = -ENODEV;
- goto err;
+ goto err_port_line;
}
sprintf(up->name, "OMAP UART%d", up->port.line);
up->port.mapbase = mem->start;
- up->port.membase = ioremap(mem->start, resource_size(mem));
+ up->port.membase = devm_ioremap(&pdev->dev, mem->start,
+ resource_size(mem));
if (!up->port.membase) {
dev_err(&pdev->dev, "can't ioremap UART\n");
ret = -ENOMEM;
- goto err;
+ goto err_ioremap;
}
up->port.flags = omap_up_info->flags;
@@ -1478,16 +1474,19 @@ static int serial_omap_probe(struct platform_device *pdev)
ret = uart_add_one_port(&serial_omap_reg, &up->port);
if (ret != 0)
- goto do_release_region;
+ goto err_add_port;
pm_runtime_put(&pdev->dev);
platform_set_drvdata(pdev, up);
return 0;
-err:
+
+err_add_port:
+ pm_runtime_put(&pdev->dev);
+ pm_runtime_disable(&pdev->dev);
+err_ioremap:
+err_port_line:
dev_err(&pdev->dev, "[UART%d]: failure [%s]: %d\n",
pdev->id, __func__, ret);
-do_release_region:
- release_mem_region(mem->start, resource_size(mem));
return ret;
}
@@ -1499,8 +1498,6 @@ static int serial_omap_remove(struct platform_device *dev)
pm_runtime_disable(&up->pdev->dev);
uart_remove_one_port(&serial_omap_reg, &up->port);
pm_qos_remove_request(&up->pm_qos_request);
-
- kfree(up);
}
platform_set_drvdata(dev, NULL);
diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c
index e825460478be..c2816f494807 100644
--- a/drivers/tty/serial/pch_uart.c
+++ b/drivers/tty/serial/pch_uart.c
@@ -210,6 +210,7 @@ enum {
#define CMITC_UARTCLK 192000000 /* 192.0000 MHz */
#define FRI2_64_UARTCLK 64000000 /* 64.0000 MHz */
#define FRI2_48_UARTCLK 48000000 /* 48.0000 MHz */
+#define NTC1_UARTCLK 64000000 /* 64.0000 MHz */
struct pch_uart_buffer {
unsigned char *buf;
@@ -304,11 +305,7 @@ static const int trigger_level_1[4] = { 1, 1, 1, 1 };
#ifdef CONFIG_DEBUG_FS
#define PCH_REGS_BUFSIZE 1024
-static int pch_show_regs_open(struct inode *inode, struct file *file)
-{
- file->private_data = inode->i_private;
- return 0;
-}
+
static ssize_t port_show_regs(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
@@ -362,7 +359,7 @@ static ssize_t port_show_regs(struct file *file, char __user *user_buf,
static const struct file_operations port_regs_ops = {
.owner = THIS_MODULE,
- .open = pch_show_regs_open,
+ .open = simple_open,
.read = port_show_regs,
.llseek = default_llseek,
};
@@ -388,6 +385,12 @@ static int pch_uart_get_uartclk(void)
if (cmp && strstr(cmp, "Fish River Island II"))
return FRI2_48_UARTCLK;
+ /* Kontron COMe-mTT10 (nanoETXexpress-TT) */
+ cmp = dmi_get_system_info(DMI_BOARD_NAME);
+ if (cmp && (strstr(cmp, "COMe-mTT") ||
+ strstr(cmp, "nanoETXexpress-TT")))
+ return NTC1_UARTCLK;
+
return DEFAULT_UARTCLK;
}
@@ -1444,9 +1447,11 @@ static int pch_uart_verify_port(struct uart_port *port,
__func__);
return -EOPNOTSUPP;
#endif
- priv->use_dma = 1;
priv->use_dma_flag = 1;
dev_info(priv->port.dev, "PCH UART : Use DMA Mode\n");
+ if (!priv->use_dma)
+ pch_request_dma(port);
+ priv->use_dma = 1;
}
return 0;
@@ -1655,6 +1660,7 @@ static struct eg20t_port *pch_uart_init_port(struct pci_dev *pdev,
}
pci_enable_msi(pdev);
+ pci_set_master(pdev);
iobase = pci_resource_start(pdev, 0);
mapbase = pci_resource_start(pdev, 1);
diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c
index de249d265bec..d8b0aee35632 100644
--- a/drivers/tty/serial/samsung.c
+++ b/drivers/tty/serial/samsung.c
@@ -982,6 +982,7 @@ static void s3c24xx_serial_resetport(struct uart_port *port,
ucon &= ucon_mask;
wr_regl(port, S3C2410_UCON, ucon | cfg->ucon);
+ wr_regl(port, S3C2410_ULCON, cfg->ulcon);
/* reset both fifos */
wr_regl(port, S3C2410_UFCON, cfg->ufcon | S3C2410_UFCON_RESETBOTH);
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index bf461cf99616..3158e17b665c 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -355,9 +355,6 @@ static void sci_serial_out(struct uart_port *p, int offset, int value)
WARN(1, "Invalid register access\n");
}
-#define sci_in(up, offset) (up->serial_in(up, offset))
-#define sci_out(up, offset, value) (up->serial_out(up, offset, value))
-
static int sci_probe_regmap(struct plat_sci_port *cfg)
{
switch (cfg->type) {
@@ -422,9 +419,9 @@ static int sci_poll_get_char(struct uart_port *port)
int c;
do {
- status = sci_in(port, SCxSR);
+ status = serial_port_in(port, SCxSR);
if (status & SCxSR_ERRORS(port)) {
- sci_out(port, SCxSR, SCxSR_ERROR_CLEAR(port));
+ serial_port_out(port, SCxSR, SCxSR_ERROR_CLEAR(port));
continue;
}
break;
@@ -433,11 +430,11 @@ static int sci_poll_get_char(struct uart_port *port)
if (!(status & SCxSR_RDxF(port)))
return NO_POLL_CHAR;
- c = sci_in(port, SCxRDR);
+ c = serial_port_in(port, SCxRDR);
/* Dummy read */
- sci_in(port, SCxSR);
- sci_out(port, SCxSR, SCxSR_RDxF_CLEAR(port));
+ serial_port_in(port, SCxSR);
+ serial_port_out(port, SCxSR, SCxSR_RDxF_CLEAR(port));
return c;
}
@@ -448,11 +445,11 @@ static void sci_poll_put_char(struct uart_port *port, unsigned char c)
unsigned short status;
do {
- status = sci_in(port, SCxSR);
+ status = serial_port_in(port, SCxSR);
} while (!(status & SCxSR_TDxE(port)));
- sci_out(port, SCxTDR, c);
- sci_out(port, SCxSR, SCxSR_TDxE_CLEAR(port) & ~SCxSR_TEND(port));
+ serial_port_out(port, SCxTDR, c);
+ serial_port_out(port, SCxSR, SCxSR_TDxE_CLEAR(port) & ~SCxSR_TEND(port));
}
#endif /* CONFIG_CONSOLE_POLL || CONFIG_SERIAL_SH_SCI_CONSOLE */
@@ -480,10 +477,10 @@ static void sci_init_pins(struct uart_port *port, unsigned int cflag)
((!(cflag & CRTSCTS)))) {
unsigned short status;
- status = sci_in(port, SCSPTR);
+ status = serial_port_in(port, SCSPTR);
status &= ~SCSPTR_CTSIO;
status |= SCSPTR_RTSIO;
- sci_out(port, SCSPTR, status); /* Set RTS = 1 */
+ serial_port_out(port, SCSPTR, status); /* Set RTS = 1 */
}
}
@@ -493,13 +490,13 @@ static int sci_txfill(struct uart_port *port)
reg = sci_getreg(port, SCTFDR);
if (reg->size)
- return sci_in(port, SCTFDR) & 0xff;
+ return serial_port_in(port, SCTFDR) & 0xff;
reg = sci_getreg(port, SCFDR);
if (reg->size)
- return sci_in(port, SCFDR) >> 8;
+ return serial_port_in(port, SCFDR) >> 8;
- return !(sci_in(port, SCxSR) & SCI_TDRE);
+ return !(serial_port_in(port, SCxSR) & SCI_TDRE);
}
static int sci_txroom(struct uart_port *port)
@@ -513,13 +510,13 @@ static int sci_rxfill(struct uart_port *port)
reg = sci_getreg(port, SCRFDR);
if (reg->size)
- return sci_in(port, SCRFDR) & 0xff;
+ return serial_port_in(port, SCRFDR) & 0xff;
reg = sci_getreg(port, SCFDR);
if (reg->size)
- return sci_in(port, SCFDR) & ((port->fifosize << 1) - 1);
+ return serial_port_in(port, SCFDR) & ((port->fifosize << 1) - 1);
- return (sci_in(port, SCxSR) & SCxSR_RDxF(port)) != 0;
+ return (serial_port_in(port, SCxSR) & SCxSR_RDxF(port)) != 0;
}
/*
@@ -547,14 +544,14 @@ static void sci_transmit_chars(struct uart_port *port)
unsigned short ctrl;
int count;
- status = sci_in(port, SCxSR);
+ status = serial_port_in(port, SCxSR);
if (!(status & SCxSR_TDxE(port))) {
- ctrl = sci_in(port, SCSCR);
+ ctrl = serial_port_in(port, SCSCR);
if (uart_circ_empty(xmit))
ctrl &= ~SCSCR_TIE;
else
ctrl |= SCSCR_TIE;
- sci_out(port, SCSCR, ctrl);
+ serial_port_out(port, SCSCR, ctrl);
return;
}
@@ -573,27 +570,27 @@ static void sci_transmit_chars(struct uart_port *port)
break;
}
- sci_out(port, SCxTDR, c);
+ serial_port_out(port, SCxTDR, c);
port->icount.tx++;
} while (--count > 0);
- sci_out(port, SCxSR, SCxSR_TDxE_CLEAR(port));
+ serial_port_out(port, SCxSR, SCxSR_TDxE_CLEAR(port));
if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
uart_write_wakeup(port);
if (uart_circ_empty(xmit)) {
sci_stop_tx(port);
} else {
- ctrl = sci_in(port, SCSCR);
+ ctrl = serial_port_in(port, SCSCR);
if (port->type != PORT_SCI) {
- sci_in(port, SCxSR); /* Dummy read */
- sci_out(port, SCxSR, SCxSR_TDxE_CLEAR(port));
+ serial_port_in(port, SCxSR); /* Dummy read */
+ serial_port_out(port, SCxSR, SCxSR_TDxE_CLEAR(port));
}
ctrl |= SCSCR_TIE;
- sci_out(port, SCSCR, ctrl);
+ serial_port_out(port, SCSCR, ctrl);
}
}
@@ -608,7 +605,7 @@ static void sci_receive_chars(struct uart_port *port)
unsigned short status;
unsigned char flag;
- status = sci_in(port, SCxSR);
+ status = serial_port_in(port, SCxSR);
if (!(status & SCxSR_RDxF(port)))
return;
@@ -621,7 +618,7 @@ static void sci_receive_chars(struct uart_port *port)
break;
if (port->type == PORT_SCI) {
- char c = sci_in(port, SCxRDR);
+ char c = serial_port_in(port, SCxRDR);
if (uart_handle_sysrq_char(port, c) ||
sci_port->break_flag)
count = 0;
@@ -629,9 +626,9 @@ static void sci_receive_chars(struct uart_port *port)
tty_insert_flip_char(tty, c, TTY_NORMAL);
} else {
for (i = 0; i < count; i++) {
- char c = sci_in(port, SCxRDR);
+ char c = serial_port_in(port, SCxRDR);
- status = sci_in(port, SCxSR);
+ status = serial_port_in(port, SCxSR);
#if defined(CONFIG_CPU_SH3)
/* Skip "chars" during break */
if (sci_port->break_flag) {
@@ -672,8 +669,8 @@ static void sci_receive_chars(struct uart_port *port)
}
}
- sci_in(port, SCxSR); /* dummy read */
- sci_out(port, SCxSR, SCxSR_RDxF_CLEAR(port));
+ serial_port_in(port, SCxSR); /* dummy read */
+ serial_port_out(port, SCxSR, SCxSR_RDxF_CLEAR(port));
copied += count;
port->icount.rx += count;
@@ -683,8 +680,8 @@ static void sci_receive_chars(struct uart_port *port)
/* Tell the rest of the system the news. New characters! */
tty_flip_buffer_push(tty);
} else {
- sci_in(port, SCxSR); /* dummy read */
- sci_out(port, SCxSR, SCxSR_RDxF_CLEAR(port));
+ serial_port_in(port, SCxSR); /* dummy read */
+ serial_port_out(port, SCxSR, SCxSR_RDxF_CLEAR(port));
}
}
@@ -726,7 +723,7 @@ static void sci_break_timer(unsigned long data)
static int sci_handle_errors(struct uart_port *port)
{
int copied = 0;
- unsigned short status = sci_in(port, SCxSR);
+ unsigned short status = serial_port_in(port, SCxSR);
struct tty_struct *tty = port->state->port.tty;
struct sci_port *s = to_sci_port(port);
@@ -804,8 +801,8 @@ static int sci_handle_fifo_overrun(struct uart_port *port)
if (!reg->size)
return 0;
- if ((sci_in(port, SCLSR) & (1 << s->cfg->overrun_bit))) {
- sci_out(port, SCLSR, 0);
+ if ((serial_port_in(port, SCLSR) & (1 << s->cfg->overrun_bit))) {
+ serial_port_out(port, SCLSR, 0);
port->icount.overrun++;
@@ -822,7 +819,7 @@ static int sci_handle_fifo_overrun(struct uart_port *port)
static int sci_handle_breaks(struct uart_port *port)
{
int copied = 0;
- unsigned short status = sci_in(port, SCxSR);
+ unsigned short status = serial_port_in(port, SCxSR);
struct tty_struct *tty = port->state->port.tty;
struct sci_port *s = to_sci_port(port);
@@ -859,8 +856,8 @@ static irqreturn_t sci_rx_interrupt(int irq, void *ptr)
struct sci_port *s = to_sci_port(port);
if (s->chan_rx) {
- u16 scr = sci_in(port, SCSCR);
- u16 ssr = sci_in(port, SCxSR);
+ u16 scr = serial_port_in(port, SCSCR);
+ u16 ssr = serial_port_in(port, SCxSR);
/* Disable future Rx interrupts */
if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) {
@@ -869,9 +866,9 @@ static irqreturn_t sci_rx_interrupt(int irq, void *ptr)
} else {
scr &= ~SCSCR_RIE;
}
- sci_out(port, SCSCR, scr);
+ serial_port_out(port, SCSCR, scr);
/* Clear current interrupt */
- sci_out(port, SCxSR, ssr & ~(1 | SCxSR_RDxF(port)));
+ serial_port_out(port, SCxSR, ssr & ~(1 | SCxSR_RDxF(port)));
dev_dbg(port->dev, "Rx IRQ %lu: setup t-out in %u jiffies\n",
jiffies, s->rx_timeout);
mod_timer(&s->rx_timer, jiffies + s->rx_timeout);
@@ -909,15 +906,15 @@ static irqreturn_t sci_er_interrupt(int irq, void *ptr)
if (port->type == PORT_SCI) {
if (sci_handle_errors(port)) {
/* discard character in rx buffer */
- sci_in(port, SCxSR);
- sci_out(port, SCxSR, SCxSR_RDxF_CLEAR(port));
+ serial_port_in(port, SCxSR);
+ serial_port_out(port, SCxSR, SCxSR_RDxF_CLEAR(port));
}
} else {
sci_handle_fifo_overrun(port);
sci_rx_interrupt(irq, ptr);
}
- sci_out(port, SCxSR, SCxSR_ERROR_CLEAR(port));
+ serial_port_out(port, SCxSR, SCxSR_ERROR_CLEAR(port));
/* Kick the transmission */
sci_tx_interrupt(irq, ptr);
@@ -931,7 +928,7 @@ static irqreturn_t sci_br_interrupt(int irq, void *ptr)
/* Handle BREAKs */
sci_handle_breaks(port);
- sci_out(port, SCxSR, SCxSR_BREAK_CLEAR(port));
+ serial_port_out(port, SCxSR, SCxSR_BREAK_CLEAR(port));
return IRQ_HANDLED;
}
@@ -955,8 +952,8 @@ static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr)
struct sci_port *s = to_sci_port(port);
irqreturn_t ret = IRQ_NONE;
- ssr_status = sci_in(port, SCxSR);
- scr_status = sci_in(port, SCSCR);
+ ssr_status = serial_port_in(port, SCxSR);
+ scr_status = serial_port_in(port, SCSCR);
err_enabled = scr_status & port_rx_irq_mask(port);
/* Tx Interrupt */
@@ -1170,7 +1167,7 @@ static void sci_free_gpios(struct sci_port *port)
static unsigned int sci_tx_empty(struct uart_port *port)
{
- unsigned short status = sci_in(port, SCxSR);
+ unsigned short status = serial_port_in(port, SCxSR);
unsigned short in_tx_fifo = sci_txfill(port);
return (status & SCxSR_TEND(port)) && !in_tx_fifo ? TIOCSER_TEMT : 0;
@@ -1198,7 +1195,7 @@ static void sci_set_mctrl(struct uart_port *port, unsigned int mctrl)
*/
reg = sci_getreg(port, SCFCR);
if (reg->size)
- sci_out(port, SCFCR, sci_in(port, SCFCR) | 1);
+ serial_port_out(port, SCFCR, serial_port_in(port, SCFCR) | 1);
}
}
@@ -1240,8 +1237,8 @@ static void sci_dma_tx_complete(void *arg)
} else {
s->cookie_tx = -EINVAL;
if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) {
- u16 ctrl = sci_in(port, SCSCR);
- sci_out(port, SCSCR, ctrl & ~SCSCR_TIE);
+ u16 ctrl = serial_port_in(port, SCSCR);
+ serial_port_out(port, SCSCR, ctrl & ~SCSCR_TIE);
}
}
@@ -1494,13 +1491,13 @@ static void sci_start_tx(struct uart_port *port)
#ifdef CONFIG_SERIAL_SH_SCI_DMA
if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) {
- u16 new, scr = sci_in(port, SCSCR);
+ u16 new, scr = serial_port_in(port, SCSCR);
if (s->chan_tx)
new = scr | 0x8000;
else
new = scr & ~0x8000;
if (new != scr)
- sci_out(port, SCSCR, new);
+ serial_port_out(port, SCSCR, new);
}
if (s->chan_tx && !uart_circ_empty(&s->port.state->xmit) &&
@@ -1512,8 +1509,8 @@ static void sci_start_tx(struct uart_port *port)
if (!s->chan_tx || port->type == PORT_SCIFA || port->type == PORT_SCIFB) {
/* Set TIE (Transmit Interrupt Enable) bit in SCSCR */
- ctrl = sci_in(port, SCSCR);
- sci_out(port, SCSCR, ctrl | SCSCR_TIE);
+ ctrl = serial_port_in(port, SCSCR);
+ serial_port_out(port, SCSCR, ctrl | SCSCR_TIE);
}
}
@@ -1522,40 +1519,40 @@ static void sci_stop_tx(struct uart_port *port)
unsigned short ctrl;
/* Clear TIE (Transmit Interrupt Enable) bit in SCSCR */
- ctrl = sci_in(port, SCSCR);
+ ctrl = serial_port_in(port, SCSCR);
if (port->type == PORT_SCIFA || port->type == PORT_SCIFB)
ctrl &= ~0x8000;
ctrl &= ~SCSCR_TIE;
- sci_out(port, SCSCR, ctrl);
+ serial_port_out(port, SCSCR, ctrl);
}
static void sci_start_rx(struct uart_port *port)
{
unsigned short ctrl;
- ctrl = sci_in(port, SCSCR) | port_rx_irq_mask(port);
+ ctrl = serial_port_in(port, SCSCR) | port_rx_irq_mask(port);
if (port->type == PORT_SCIFA || port->type == PORT_SCIFB)
ctrl &= ~0x4000;
- sci_out(port, SCSCR, ctrl);
+ serial_port_out(port, SCSCR, ctrl);
}
static void sci_stop_rx(struct uart_port *port)
{
unsigned short ctrl;
- ctrl = sci_in(port, SCSCR);
+ ctrl = serial_port_in(port, SCSCR);
if (port->type == PORT_SCIFA || port->type == PORT_SCIFB)
ctrl &= ~0x4000;
ctrl &= ~port_rx_irq_mask(port);
- sci_out(port, SCSCR, ctrl);
+ serial_port_out(port, SCSCR, ctrl);
}
static void sci_enable_ms(struct uart_port *port)
@@ -1589,13 +1586,13 @@ static void rx_timer_fn(unsigned long arg)
{
struct sci_port *s = (struct sci_port *)arg;
struct uart_port *port = &s->port;
- u16 scr = sci_in(port, SCSCR);
+ u16 scr = serial_port_in(port, SCSCR);
if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) {
scr &= ~0x4000;
enable_irq(s->cfg->irqs[1]);
}
- sci_out(port, SCSCR, scr | SCSCR_RIE);
+ serial_port_out(port, SCSCR, scr | SCSCR_RIE);
dev_dbg(port->dev, "DMA Rx timed out\n");
schedule_work(&s->work_rx);
}
@@ -1776,14 +1773,14 @@ static void sci_reset(struct uart_port *port)
unsigned int status;
do {
- status = sci_in(port, SCxSR);
+ status = serial_port_in(port, SCxSR);
} while (!(status & SCxSR_TEND(port)));
- sci_out(port, SCSCR, 0x00); /* TE=0, RE=0, CKE1=0 */
+ serial_port_out(port, SCSCR, 0x00); /* TE=0, RE=0, CKE1=0 */
reg = sci_getreg(port, SCFCR);
if (reg->size)
- sci_out(port, SCFCR, SCFCR_RFRST | SCFCR_TFRST);
+ serial_port_out(port, SCFCR, SCFCR_RFRST | SCFCR_TFRST);
}
static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
@@ -1812,7 +1809,7 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
sci_reset(port);
- smr_val = sci_in(port, SCSMR) & 3;
+ smr_val = serial_port_in(port, SCSMR) & 3;
if ((termios->c_cflag & CSIZE) == CS7)
smr_val |= 0x40;
@@ -1825,19 +1822,19 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
uart_update_timeout(port, termios->c_cflag, baud);
- sci_out(port, SCSMR, smr_val);
+ serial_port_out(port, SCSMR, smr_val);
dev_dbg(port->dev, "%s: SMR %x, t %x, SCSCR %x\n", __func__, smr_val, t,
s->cfg->scscr);
if (t > 0) {
if (t >= 256) {
- sci_out(port, SCSMR, (sci_in(port, SCSMR) & ~3) | 1);
+ serial_port_out(port, SCSMR, (serial_port_in(port, SCSMR) & ~3) | 1);
t >>= 2;
} else
- sci_out(port, SCSMR, sci_in(port, SCSMR) & ~3);
+ serial_port_out(port, SCSMR, serial_port_in(port, SCSMR) & ~3);
- sci_out(port, SCBRR, t);
+ serial_port_out(port, SCBRR, t);
udelay((1000000+(baud-1)) / baud); /* Wait one bit interval */
}
@@ -1845,7 +1842,7 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
reg = sci_getreg(port, SCFCR);
if (reg->size) {
- unsigned short ctrl = sci_in(port, SCFCR);
+ unsigned short ctrl = serial_port_in(port, SCFCR);
if (s->cfg->capabilities & SCIx_HAVE_RTSCTS) {
if (termios->c_cflag & CRTSCTS)
@@ -1861,10 +1858,10 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
*/
ctrl &= ~(SCFCR_RFRST | SCFCR_TFRST);
- sci_out(port, SCFCR, ctrl);
+ serial_port_out(port, SCFCR, ctrl);
}
- sci_out(port, SCSCR, s->cfg->scscr);
+ serial_port_out(port, SCSCR, s->cfg->scscr);
#ifdef CONFIG_SERIAL_SH_SCI_DMA
/*
@@ -2166,7 +2163,7 @@ static void serial_console_write(struct console *co, const char *s,
/* wait until fifo is empty and last bit has been transmitted */
bits = SCxSR_TDxE(port) | SCxSR_TEND(port);
- while ((sci_in(port, SCxSR) & bits) != bits)
+ while ((serial_port_in(port, SCxSR) & bits) != bits)
cpu_relax();
sci_port_disable(sci_port);
@@ -2260,12 +2257,12 @@ static int sci_runtime_suspend(struct device *dev)
if (uart_console(port)) {
struct plat_sci_reg *reg;
- sci_port->saved_smr = sci_in(port, SCSMR);
- sci_port->saved_brr = sci_in(port, SCBRR);
+ sci_port->saved_smr = serial_port_in(port, SCSMR);
+ sci_port->saved_brr = serial_port_in(port, SCBRR);
reg = sci_getreg(port, SCFCR);
if (reg->size)
- sci_port->saved_fcr = sci_in(port, SCFCR);
+ sci_port->saved_fcr = serial_port_in(port, SCFCR);
else
sci_port->saved_fcr = 0;
}
@@ -2279,13 +2276,13 @@ static int sci_runtime_resume(struct device *dev)
if (uart_console(port)) {
sci_reset(port);
- sci_out(port, SCSMR, sci_port->saved_smr);
- sci_out(port, SCBRR, sci_port->saved_brr);
+ serial_port_out(port, SCSMR, sci_port->saved_smr);
+ serial_port_out(port, SCBRR, sci_port->saved_brr);
if (sci_port->saved_fcr)
- sci_out(port, SCFCR, sci_port->saved_fcr);
+ serial_port_out(port, SCFCR, sci_port->saved_fcr);
- sci_out(port, SCSCR, sci_port->cfg->scscr);
+ serial_port_out(port, SCSCR, sci_port->cfg->scscr);
}
return 0;
}
diff --git a/drivers/tty/serial/sh-sci.h b/drivers/tty/serial/sh-sci.h
index a1a2d364f92b..4c22a1529aac 100644
--- a/drivers/tty/serial/sh-sci.h
+++ b/drivers/tty/serial/sh-sci.h
@@ -20,10 +20,10 @@
defined(CONFIG_ARCH_SH7372) || \
defined(CONFIG_ARCH_R8A7740)
-# define SCxSR_RDxF_CLEAR(port) (sci_in(port, SCxSR) & 0xfffc)
-# define SCxSR_ERROR_CLEAR(port) (sci_in(port, SCxSR) & 0xfd73)
-# define SCxSR_TDxE_CLEAR(port) (sci_in(port, SCxSR) & 0xffdf)
-# define SCxSR_BREAK_CLEAR(port) (sci_in(port, SCxSR) & 0xffe3)
+# define SCxSR_RDxF_CLEAR(port) (serial_port_in(port, SCxSR) & 0xfffc)
+# define SCxSR_ERROR_CLEAR(port) (serial_port_in(port, SCxSR) & 0xfd73)
+# define SCxSR_TDxE_CLEAR(port) (serial_port_in(port, SCxSR) & 0xffdf)
+# define SCxSR_BREAK_CLEAR(port) (serial_port_in(port, SCxSR) & 0xffe3)
#else
# define SCxSR_RDxF_CLEAR(port) (((port)->type == PORT_SCI) ? 0xbc : 0x00fc)
# define SCxSR_ERROR_CLEAR(port) (((port)->type == PORT_SCI) ? 0xc4 : 0x0073)
diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c
index 136e86faa1e1..05728894a88c 100644
--- a/drivers/tty/sysrq.c
+++ b/drivers/tty/sysrq.c
@@ -327,7 +327,7 @@ static void send_sig_all(int sig)
if (is_global_init(p))
continue;
- force_sig(sig, p);
+ do_send_sig_info(sig, SEND_SIG_FORCED, p, true);
}
read_unlock(&tasklist_lock);
}
diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index 3bdd4b19dd06..2156188db4a6 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -2932,11 +2932,10 @@ static int __init con_init(void)
gotoxy(vc, vc->vc_x, vc->vc_y);
csi_J(vc, 0);
update_screen(vc);
- pr_info("Console: %s %s %dx%d",
+ pr_info("Console: %s %s %dx%d\n",
vc->vc_can_do_color ? "colour" : "mono",
display_desc, vc->vc_cols, vc->vc_rows);
printable = 1;
- printk("\n");
console_unlock();
diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig
index cbd8f5f80596..76316a33061b 100644
--- a/drivers/usb/Kconfig
+++ b/drivers/usb/Kconfig
@@ -2,14 +2,6 @@
# USB device configuration
#
-menuconfig USB_SUPPORT
- bool "USB support"
- depends on HAS_IOMEM
- default y
- ---help---
- This option adds core support for Universal Serial Bus (USB).
- You will also need drivers from the following menu to make use of it.
-
# many non-PCI SOC chips embed OHCI
config USB_ARCH_HAS_OHCI
boolean
@@ -63,6 +55,14 @@ config USB_ARCH_HAS_XHCI
boolean
default PCI
+menuconfig USB_SUPPORT
+ bool "USB support"
+ depends on HAS_IOMEM
+ default y
+ ---help---
+ This option adds core support for Universal Serial Bus (USB).
+ You will also need drivers from the following menu to make use of it.
+
if USB_SUPPORT
config USB_COMMON
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index f8e2d6d52e5c..9a56635dc19c 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -1189,8 +1189,13 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg)
if (status == 0) {
status = usb_suspend_device(udev, msg);
- /* Again, ignore errors during system sleep transitions */
- if (!PMSG_IS_AUTO(msg))
+ /*
+ * Ignore errors from non-root-hub devices during
+ * system sleep transitions. For the most part,
+ * these devices should go to low power anyway when
+ * the entire bus is suspended.
+ */
+ if (udev->parent && !PMSG_IS_AUTO(msg))
status = 0;
}
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 9d7fc9a39933..140d3e11f212 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -1978,6 +1978,18 @@ int hcd_bus_suspend(struct usb_device *rhdev, pm_message_t msg)
if (status == 0) {
usb_set_device_state(rhdev, USB_STATE_SUSPENDED);
hcd->state = HC_STATE_SUSPENDED;
+
+ /* Did we race with a root-hub wakeup event? */
+ if (rhdev->do_remote_wakeup) {
+ char buffer[6];
+
+ status = hcd->driver->hub_status_data(hcd, buffer);
+ if (status != 0) {
+ dev_dbg(&rhdev->dev, "suspend raced with wakeup event\n");
+ hcd_bus_resume(rhdev, PMSG_AUTO_RESUME);
+ status = -EBUSY;
+ }
+ }
} else {
spin_lock_irq(&hcd_root_hub_lock);
if (!HCD_DEAD(hcd)) {
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 28664eb7f555..ec6c97dadbe4 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -1667,7 +1667,6 @@ void usb_disconnect(struct usb_device **pdev)
{
struct usb_device *udev = *pdev;
int i;
- struct usb_hcd *hcd = bus_to_hcd(udev->bus);
/* mark the device as inactive, so any further urb submissions for
* this device (and any of its children) will fail immediately.
@@ -1690,9 +1689,7 @@ void usb_disconnect(struct usb_device **pdev)
* so that the hardware is now fully quiesced.
*/
dev_dbg (&udev->dev, "unregistering device\n");
- mutex_lock(hcd->bandwidth_mutex);
usb_disable_device(udev, 0);
- mutex_unlock(hcd->bandwidth_mutex);
usb_hcd_synchronize_unlinks(udev);
usb_remove_ep_devs(&udev->ep0);
@@ -3163,6 +3160,22 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,
if (retval)
goto fail;
+ /*
+ * Some superspeed devices have finished the link training process
+ * and attached to a superspeed hub port, but the device descriptor
+ * got from those devices show they aren't superspeed devices. Warm
+ * reset the port attached by the devices can fix them.
+ */
+ if ((udev->speed == USB_SPEED_SUPER) &&
+ (le16_to_cpu(udev->descriptor.bcdUSB) < 0x0300)) {
+ dev_err(&udev->dev, "got a wrong device descriptor, "
+ "warm reset device\n");
+ hub_port_reset(hub, port1, udev,
+ HUB_BH_RESET_TIME, true);
+ retval = -EINVAL;
+ goto fail;
+ }
+
if (udev->descriptor.bMaxPacketSize0 == 0xff ||
udev->speed == USB_SPEED_SUPER)
i = 512;
diff --git a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c
index cefa0c8b5b6a..d2b9af59cba9 100644
--- a/drivers/usb/core/inode.c
+++ b/drivers/usb/core/inode.c
@@ -428,18 +428,10 @@ static loff_t default_file_lseek (struct file *file, loff_t offset, int orig)
return retval;
}
-static int default_open (struct inode *inode, struct file *file)
-{
- if (inode->i_private)
- file->private_data = inode->i_private;
-
- return 0;
-}
-
static const struct file_operations default_file_operations = {
.read = default_read_file,
.write = default_write_file,
- .open = default_open,
+ .open = simple_open,
.llseek = default_file_lseek,
};
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index b3bdfede45e6..ca717da3be95 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -308,7 +308,8 @@ static void sg_complete(struct urb *urb)
retval = usb_unlink_urb(io->urbs [i]);
if (retval != -EINPROGRESS &&
retval != -ENODEV &&
- retval != -EBUSY)
+ retval != -EBUSY &&
+ retval != -EIDRM)
dev_err(&io->dev->dev,
"%s, unlink --> %d\n",
__func__, retval);
@@ -317,7 +318,6 @@ static void sg_complete(struct urb *urb)
}
spin_lock(&io->lock);
}
- urb->dev = NULL;
/* on the last completion, signal usb_sg_wait() */
io->bytes += urb->actual_length;
@@ -524,7 +524,6 @@ void usb_sg_wait(struct usb_sg_request *io)
case -ENXIO: /* hc didn't queue this one */
case -EAGAIN:
case -ENOMEM:
- io->urbs[i]->dev = NULL;
retval = 0;
yield();
break;
@@ -542,7 +541,6 @@ void usb_sg_wait(struct usb_sg_request *io)
/* fail any uncompleted urbs */
default:
- io->urbs[i]->dev = NULL;
io->urbs[i]->status = retval;
dev_dbg(&io->dev->dev, "%s, submit --> %d\n",
__func__, retval);
@@ -593,7 +591,10 @@ void usb_sg_cancel(struct usb_sg_request *io)
if (!io->urbs [i]->dev)
continue;
retval = usb_unlink_urb(io->urbs [i]);
- if (retval != -EINPROGRESS && retval != -EBUSY)
+ if (retval != -EINPROGRESS
+ && retval != -ENODEV
+ && retval != -EBUSY
+ && retval != -EIDRM)
dev_warn(&io->dev->dev, "%s, unlink --> %d\n",
__func__, retval);
}
@@ -1135,8 +1136,6 @@ void usb_disable_interface(struct usb_device *dev, struct usb_interface *intf,
* Deallocates hcd/hardware state for the endpoints (nuking all or most
* pending urbs) and usbcore state for the interfaces, so that usbcore
* must usb_set_configuration() before any interfaces could be used.
- *
- * Must be called with hcd->bandwidth_mutex held.
*/
void usb_disable_device(struct usb_device *dev, int skip_ep0)
{
@@ -1189,7 +1188,9 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0)
usb_disable_endpoint(dev, i + USB_DIR_IN, false);
}
/* Remove endpoints from the host controller internal state */
+ mutex_lock(hcd->bandwidth_mutex);
usb_hcd_alloc_bandwidth(dev, NULL, NULL, NULL);
+ mutex_unlock(hcd->bandwidth_mutex);
/* Second pass: remove endpoint pointers */
}
for (i = skip_ep0; i < 16; ++i) {
@@ -1749,7 +1750,6 @@ free_interfaces:
/* if it's already configured, clear out old state first.
* getting rid of old interfaces means unbinding their drivers.
*/
- mutex_lock(hcd->bandwidth_mutex);
if (dev->state != USB_STATE_ADDRESS)
usb_disable_device(dev, 1); /* Skip ep0 */
@@ -1762,6 +1762,7 @@ free_interfaces:
* host controller will not allow submissions to dropped endpoints. If
* this call fails, the device state is unchanged.
*/
+ mutex_lock(hcd->bandwidth_mutex);
ret = usb_hcd_alloc_bandwidth(dev, cp, NULL, NULL);
if (ret < 0) {
mutex_unlock(hcd->bandwidth_mutex);
diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c
index 7239a73c1b8c..cd9b3a2cd8a7 100644
--- a/drivers/usb/core/urb.c
+++ b/drivers/usb/core/urb.c
@@ -539,6 +539,10 @@ EXPORT_SYMBOL_GPL(usb_submit_urb);
* never submitted, or it was unlinked before, or the hardware is already
* finished with it), even if the completion handler has not yet run.
*
+ * The URB must not be deallocated while this routine is running. In
+ * particular, when a driver calls this routine, it must insure that the
+ * completion handler cannot deallocate the URB.
+ *
* Unlinking and Endpoint Queues:
*
* [The behaviors and guarantees described below do not apply to virtual
@@ -603,6 +607,10 @@ EXPORT_SYMBOL_GPL(usb_unlink_urb);
* with error -EPERM. Thus even if the URB's completion handler always
* tries to resubmit, it will not succeed and the URB will become idle.
*
+ * The URB must not be deallocated while this routine is running. In
+ * particular, when a driver calls this routine, it must insure that the
+ * completion handler cannot deallocate the URB.
+ *
* This routine may not be used in an interrupt context (such as a bottom
* half or a completion handler), or when holding a spinlock, or in other
* situations where the caller can't schedule().
@@ -640,6 +648,10 @@ EXPORT_SYMBOL_GPL(usb_kill_urb);
* with error -EPERM. Thus even if the URB's completion handler always
* tries to resubmit, it will not succeed and the URB will become idle.
*
+ * The URB must not be deallocated while this routine is running. In
+ * particular, when a driver calls this routine, it must insure that the
+ * completion handler cannot deallocate the URB.
+ *
* This routine may not be used in an interrupt context (such as a bottom
* half or a completion handler), or when holding a spinlock, or in other
* situations where the caller can't schedule().
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 7bd815a507e8..99b58d84553a 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -206,11 +206,11 @@ static void dwc3_free_event_buffers(struct dwc3 *dwc)
for (i = 0; i < dwc->num_event_buffers; i++) {
evt = dwc->ev_buffs[i];
- if (evt) {
+ if (evt)
dwc3_free_one_event_buffer(dwc, evt);
- dwc->ev_buffs[i] = NULL;
- }
}
+
+ kfree(dwc->ev_buffs);
}
/**
diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
index 25910e251c04..3584a169886f 100644
--- a/drivers/usb/dwc3/ep0.c
+++ b/drivers/usb/dwc3/ep0.c
@@ -353,6 +353,9 @@ static int dwc3_ep0_handle_feature(struct dwc3 *dwc,
dwc->test_mode_nr = wIndex >> 8;
dwc->test_mode = true;
+ break;
+ default:
+ return -EINVAL;
}
break;
@@ -559,15 +562,20 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc,
length = trb->size & DWC3_TRB_SIZE_MASK;
if (dwc->ep0_bounced) {
+ unsigned transfer_size = ur->length;
+ unsigned maxp = ep0->endpoint.maxpacket;
+
+ transfer_size += (maxp - (transfer_size % maxp));
transferred = min_t(u32, ur->length,
- ep0->endpoint.maxpacket - length);
+ transfer_size - length);
memcpy(ur->buf, dwc->ep0_bounce, transferred);
dwc->ep0_bounced = false;
} else {
transferred = ur->length - length;
- ur->actual += transferred;
}
+ ur->actual += transferred;
+
if ((epnum & 1) && ur->actual < ur->length) {
/* for some reason we did not get everything out */
diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c
index 0c935d7c65bd..9d7bcd910074 100644
--- a/drivers/usb/gadget/at91_udc.c
+++ b/drivers/usb/gadget/at91_udc.c
@@ -1863,8 +1863,8 @@ static int __devinit at91udc_probe(struct platform_device *pdev)
mod_timer(&udc->vbus_timer,
jiffies + VBUS_POLL_TIMEOUT);
} else {
- if (request_irq(udc->board.vbus_pin, at91_vbus_irq,
- 0, driver_name, udc)) {
+ if (request_irq(gpio_to_irq(udc->board.vbus_pin),
+ at91_vbus_irq, 0, driver_name, udc)) {
DBG("request vbus irq %d failed\n",
udc->board.vbus_pin);
retval = -EBUSY;
@@ -1886,7 +1886,7 @@ static int __devinit at91udc_probe(struct platform_device *pdev)
return 0;
fail4:
if (gpio_is_valid(udc->board.vbus_pin) && !udc->board.vbus_polled)
- free_irq(udc->board.vbus_pin, udc);
+ free_irq(gpio_to_irq(udc->board.vbus_pin), udc);
fail3:
if (gpio_is_valid(udc->board.vbus_pin))
gpio_free(udc->board.vbus_pin);
@@ -1924,7 +1924,7 @@ static int __exit at91udc_remove(struct platform_device *pdev)
device_init_wakeup(&pdev->dev, 0);
remove_debug_file(udc);
if (gpio_is_valid(udc->board.vbus_pin)) {
- free_irq(udc->board.vbus_pin, udc);
+ free_irq(gpio_to_irq(udc->board.vbus_pin), udc);
gpio_free(udc->board.vbus_pin);
}
free_irq(udc->udp_irq, udc);
diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c
index 1cbba70836bc..f52cb1ae45d9 100644
--- a/drivers/usb/gadget/f_fs.c
+++ b/drivers/usb/gadget/f_fs.c
@@ -712,7 +712,7 @@ static long ffs_ep0_ioctl(struct file *file, unsigned code, unsigned long value)
if (code == FUNCTIONFS_INTERFACE_REVMAP) {
struct ffs_function *func = ffs->func;
ret = func ? ffs_func_revmap_intf(func, value) : -ENODEV;
- } else if (gadget->ops->ioctl) {
+ } else if (gadget && gadget->ops->ioctl) {
ret = gadget->ops->ioctl(gadget, code, value);
} else {
ret = -ENOTTY;
@@ -1382,6 +1382,7 @@ static void functionfs_unbind(struct ffs_data *ffs)
ffs->ep0req = NULL;
ffs->gadget = NULL;
ffs_data_put(ffs);
+ clear_bit(FFS_FL_BOUND, &ffs->flags);
}
}
diff --git a/drivers/usb/gadget/f_rndis.c b/drivers/usb/gadget/f_rndis.c
index 7b1cf18df5e3..52343654f5df 100644
--- a/drivers/usb/gadget/f_rndis.c
+++ b/drivers/usb/gadget/f_rndis.c
@@ -500,6 +500,7 @@ rndis_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl)
if (buf) {
memcpy(req->buf, buf, n);
req->complete = rndis_response_complete;
+ req->context = rndis;
rndis_free_response(rndis->config, buf);
value = n;
}
diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c
index 5f94e79cd6b9..55abfb6bd612 100644
--- a/drivers/usb/gadget/fsl_udc_core.c
+++ b/drivers/usb/gadget/fsl_udc_core.c
@@ -730,7 +730,7 @@ static void fsl_queue_td(struct fsl_ep *ep, struct fsl_req *req)
: (1 << (ep_index(ep)));
/* check if the pipe is empty */
- if (!(list_empty(&ep->queue))) {
+ if (!(list_empty(&ep->queue)) && !(ep_index(ep) == 0)) {
/* Add td to the end */
struct fsl_req *lastreq;
lastreq = list_entry(ep->queue.prev, struct fsl_req, queue);
@@ -918,10 +918,6 @@ fsl_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
return -ENOMEM;
}
- /* Update ep0 state */
- if ((ep_index(ep) == 0))
- udc->ep0_state = DATA_STATE_XMIT;
-
/* irq handler advances the queue */
if (req != NULL)
list_add_tail(&req->queue, &ep->queue);
@@ -1279,7 +1275,8 @@ static int ep0_prime_status(struct fsl_udc *udc, int direction)
udc->ep0_dir = USB_DIR_OUT;
ep = &udc->eps[0];
- udc->ep0_state = WAIT_FOR_OUT_STATUS;
+ if (udc->ep0_state != DATA_STATE_XMIT)
+ udc->ep0_state = WAIT_FOR_OUT_STATUS;
req->ep = ep;
req->req.length = 0;
@@ -1384,6 +1381,9 @@ static void ch9getstatus(struct fsl_udc *udc, u8 request_type, u16 value,
list_add_tail(&req->queue, &ep->queue);
udc->ep0_state = DATA_STATE_XMIT;
+ if (ep0_prime_status(udc, EP_DIR_OUT))
+ ep0stall(udc);
+
return;
stall:
ep0stall(udc);
@@ -1492,6 +1492,14 @@ static void setup_received_irq(struct fsl_udc *udc,
spin_lock(&udc->lock);
udc->ep0_state = (setup->bRequestType & USB_DIR_IN)
? DATA_STATE_XMIT : DATA_STATE_RECV;
+ /*
+ * If the data stage is IN, send status prime immediately.
+ * See 2.0 Spec chapter 8.5.3.3 for detail.
+ */
+ if (udc->ep0_state == DATA_STATE_XMIT)
+ if (ep0_prime_status(udc, EP_DIR_OUT))
+ ep0stall(udc);
+
} else {
/* No data phase, IN status from gadget */
udc->ep0_dir = USB_DIR_IN;
@@ -1520,9 +1528,8 @@ static void ep0_req_complete(struct fsl_udc *udc, struct fsl_ep *ep0,
switch (udc->ep0_state) {
case DATA_STATE_XMIT:
- /* receive status phase */
- if (ep0_prime_status(udc, EP_DIR_OUT))
- ep0stall(udc);
+ /* already primed at setup_received_irq */
+ udc->ep0_state = WAIT_FOR_OUT_STATUS;
break;
case DATA_STATE_RECV:
/* send status phase */
diff --git a/drivers/usb/gadget/g_ffs.c b/drivers/usb/gadget/g_ffs.c
index 331cd6729d3c..a85eaf40b948 100644
--- a/drivers/usb/gadget/g_ffs.c
+++ b/drivers/usb/gadget/g_ffs.c
@@ -161,7 +161,7 @@ static struct usb_composite_driver gfs_driver = {
static struct ffs_data *gfs_ffs_data;
static unsigned long gfs_registered;
-static int gfs_init(void)
+static int __init gfs_init(void)
{
ENTER();
@@ -169,7 +169,7 @@ static int gfs_init(void)
}
module_init(gfs_init);
-static void gfs_exit(void)
+static void __exit gfs_exit(void)
{
ENTER();
diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c
index 8793f32bab11..e58b16442971 100644
--- a/drivers/usb/gadget/inode.c
+++ b/drivers/usb/gadget/inode.c
@@ -1574,7 +1574,6 @@ static void destroy_ep_files (struct dev_data *dev)
DBG (dev, "%s %d\n", __func__, dev->state);
/* dev->state must prevent interference */
-restart:
spin_lock_irq (&dev->lock);
while (!list_empty(&dev->epfiles)) {
struct ep_data *ep;
diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c
index 69295ba9d99a..105b206cd844 100644
--- a/drivers/usb/gadget/s3c-hsotg.c
+++ b/drivers/usb/gadget/s3c-hsotg.c
@@ -340,7 +340,7 @@ static void s3c_hsotg_init_fifo(struct s3c_hsotg *hsotg)
/* currently we allocate TX FIFOs for all possible endpoints,
* and assume that they are all the same size. */
- for (ep = 0; ep <= 15; ep++) {
+ for (ep = 1; ep <= 15; ep++) {
val = addr;
val |= size << S3C_DPTXFSIZn_DPTxFSize_SHIFT;
addr += size;
@@ -741,7 +741,7 @@ static void s3c_hsotg_start_req(struct s3c_hsotg *hsotg,
/* write size / packets */
writel(epsize, hsotg->regs + epsize_reg);
- if (using_dma(hsotg)) {
+ if (using_dma(hsotg) && !continuing) {
unsigned int dma_reg;
/* write DMA address to control register, buffer already
@@ -1696,10 +1696,12 @@ static void s3c_hsotg_set_ep_maxpacket(struct s3c_hsotg *hsotg,
reg |= mpsval;
writel(reg, regs + S3C_DIEPCTL(ep));
- reg = readl(regs + S3C_DOEPCTL(ep));
- reg &= ~S3C_DxEPCTL_MPS_MASK;
- reg |= mpsval;
- writel(reg, regs + S3C_DOEPCTL(ep));
+ if (ep) {
+ reg = readl(regs + S3C_DOEPCTL(ep));
+ reg &= ~S3C_DxEPCTL_MPS_MASK;
+ reg |= mpsval;
+ writel(reg, regs + S3C_DOEPCTL(ep));
+ }
return;
@@ -1919,7 +1921,8 @@ static void s3c_hsotg_epint(struct s3c_hsotg *hsotg, unsigned int idx,
ints & S3C_DIEPMSK_TxFIFOEmpty) {
dev_dbg(hsotg->dev, "%s: ep%d: TxFIFOEmpty\n",
__func__, idx);
- s3c_hsotg_trytx(hsotg, hs_ep);
+ if (!using_dma(hsotg))
+ s3c_hsotg_trytx(hsotg, hs_ep);
}
}
}
diff --git a/drivers/usb/gadget/udc-core.c b/drivers/usb/gadget/udc-core.c
index 56da49f31d6c..2fa9865babed 100644
--- a/drivers/usb/gadget/udc-core.c
+++ b/drivers/usb/gadget/udc-core.c
@@ -264,8 +264,8 @@ static void usb_gadget_remove_driver(struct usb_udc *udc)
if (udc_is_newstyle(udc)) {
udc->driver->disconnect(udc->gadget);
udc->driver->unbind(udc->gadget);
- usb_gadget_udc_stop(udc->gadget, udc->driver);
usb_gadget_disconnect(udc->gadget);
+ usb_gadget_udc_stop(udc->gadget, udc->driver);
} else {
usb_gadget_stop(udc->gadget, udc->driver);
}
@@ -411,8 +411,12 @@ static ssize_t usb_udc_softconn_store(struct device *dev,
struct usb_udc *udc = container_of(dev, struct usb_udc, dev);
if (sysfs_streq(buf, "connect")) {
+ if (udc_is_newstyle(udc))
+ usb_gadget_udc_start(udc->gadget, udc->driver);
usb_gadget_connect(udc->gadget);
} else if (sysfs_streq(buf, "disconnect")) {
+ if (udc_is_newstyle(udc))
+ usb_gadget_udc_stop(udc->gadget, udc->driver);
usb_gadget_disconnect(udc->gadget);
} else {
dev_err(dev, "unsupported command '%s'\n", buf);
diff --git a/drivers/usb/gadget/uvc_queue.c b/drivers/usb/gadget/uvc_queue.c
index d776adb2da67..0cdf89d32a15 100644
--- a/drivers/usb/gadget/uvc_queue.c
+++ b/drivers/usb/gadget/uvc_queue.c
@@ -543,11 +543,11 @@ done:
return ret;
}
+/* called with queue->irqlock held.. */
static struct uvc_buffer *
uvc_queue_next_buffer(struct uvc_video_queue *queue, struct uvc_buffer *buf)
{
struct uvc_buffer *nextbuf;
- unsigned long flags;
if ((queue->flags & UVC_QUEUE_DROP_INCOMPLETE) &&
buf->buf.length != buf->buf.bytesused) {
@@ -556,14 +556,12 @@ uvc_queue_next_buffer(struct uvc_video_queue *queue, struct uvc_buffer *buf)
return buf;
}
- spin_lock_irqsave(&queue->irqlock, flags);
list_del(&buf->queue);
if (!list_empty(&queue->irqqueue))
nextbuf = list_first_entry(&queue->irqqueue, struct uvc_buffer,
queue);
else
nextbuf = NULL;
- spin_unlock_irqrestore(&queue->irqlock, flags);
buf->buf.sequence = queue->sequence++;
do_gettimeofday(&buf->buf.timestamp);
diff --git a/drivers/usb/host/ehci-atmel.c b/drivers/usb/host/ehci-atmel.c
index 19f318ababa2..cf14c95a6700 100644
--- a/drivers/usb/host/ehci-atmel.c
+++ b/drivers/usb/host/ehci-atmel.c
@@ -13,6 +13,7 @@
#include <linux/clk.h>
#include <linux/platform_device.h>
+#include <linux/of.h>
#include <linux/of_platform.h>
/* interface and function clocks */
diff --git a/drivers/usb/host/ehci-dbg.c b/drivers/usb/host/ehci-dbg.c
index fd9109d7eb0e..680e1a31fb87 100644
--- a/drivers/usb/host/ehci-dbg.c
+++ b/drivers/usb/host/ehci-dbg.c
@@ -352,7 +352,6 @@ static int debug_async_open(struct inode *, struct file *);
static int debug_periodic_open(struct inode *, struct file *);
static int debug_registers_open(struct inode *, struct file *);
static int debug_async_open(struct inode *, struct file *);
-static int debug_lpm_open(struct inode *, struct file *);
static ssize_t debug_lpm_read(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos);
static ssize_t debug_lpm_write(struct file *file, const char __user *buffer,
@@ -385,7 +384,7 @@ static const struct file_operations debug_registers_fops = {
};
static const struct file_operations debug_lpm_fops = {
.owner = THIS_MODULE,
- .open = debug_lpm_open,
+ .open = simple_open,
.read = debug_lpm_read,
.write = debug_lpm_write,
.release = debug_lpm_close,
@@ -970,12 +969,6 @@ static int debug_registers_open(struct inode *inode, struct file *file)
return file->private_data ? 0 : -ENOMEM;
}
-static int debug_lpm_open(struct inode *inode, struct file *file)
-{
- file->private_data = inode->i_private;
- return 0;
-}
-
static int debug_lpm_close(struct inode *inode, struct file *file)
{
return 0;
diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c
index 3e7345172e03..d0a84bd3f3eb 100644
--- a/drivers/usb/host/ehci-fsl.c
+++ b/drivers/usb/host/ehci-fsl.c
@@ -218,6 +218,9 @@ static void ehci_fsl_setup_phy(struct ehci_hcd *ehci,
u32 portsc;
struct usb_hcd *hcd = ehci_to_hcd(ehci);
void __iomem *non_ehci = hcd->regs;
+ struct fsl_usb2_platform_data *pdata;
+
+ pdata = hcd->self.controller->platform_data;
portsc = ehci_readl(ehci, &ehci->regs->port_status[port_offset]);
portsc &= ~(PORT_PTS_MSK | PORT_PTS_PTW);
@@ -234,7 +237,9 @@ static void ehci_fsl_setup_phy(struct ehci_hcd *ehci,
/* fall through */
case FSL_USB2_PHY_UTMI:
/* enable UTMI PHY */
- setbits32(non_ehci + FSL_SOC_USB_CTRL, CTRL_UTMI_PHY_EN);
+ if (pdata->have_sysif_regs)
+ setbits32(non_ehci + FSL_SOC_USB_CTRL,
+ CTRL_UTMI_PHY_EN);
portsc |= PORT_PTS_UTMI;
break;
case FSL_USB2_PHY_NONE:
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 057cdda7a489..4a3bc5b7a06f 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -347,6 +347,8 @@ static int ehci_reset (struct ehci_hcd *ehci)
if (ehci->debug)
dbgp_external_startup();
+ ehci->port_c_suspend = ehci->suspended_ports =
+ ehci->resuming_ports = 0;
return retval;
}
@@ -856,8 +858,13 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
goto dead;
}
+ /*
+ * We don't use STS_FLR, but some controllers don't like it to
+ * remain on, so mask it out along with the other status bits.
+ */
+ masked_status = status & (INTR_MASK | STS_FLR);
+
/* Shared IRQ? */
- masked_status = status & INTR_MASK;
if (!masked_status || unlikely(ehci->rh_state == EHCI_RH_HALTED)) {
spin_unlock(&ehci->lock);
return IRQ_NONE;
@@ -908,7 +915,7 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
pcd_status = status;
/* resume root hub? */
- if (!(cmd & CMD_RUN))
+ if (ehci->rh_state == EHCI_RH_SUSPENDED)
usb_hcd_resume_root_hub(hcd);
/* get per-port change detect bits */
@@ -939,6 +946,7 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
* like usb_port_resume() does.
*/
ehci->reset_done[i] = jiffies + msecs_to_jiffies(25);
+ set_bit(i, &ehci->resuming_ports);
ehci_dbg (ehci, "port %d remote wakeup\n", i + 1);
mod_timer(&hcd->rh_timer, ehci->reset_done[i]);
}
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
index 256fbd42e48c..38fe07623152 100644
--- a/drivers/usb/host/ehci-hub.c
+++ b/drivers/usb/host/ehci-hub.c
@@ -223,15 +223,10 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
* remote wakeup, we must fail the suspend.
*/
if (hcd->self.root_hub->do_remote_wakeup) {
- port = HCS_N_PORTS(ehci->hcs_params);
- while (port--) {
- if (ehci->reset_done[port] != 0) {
- spin_unlock_irq(&ehci->lock);
- ehci_dbg(ehci, "suspend failed because "
- "port %d is resuming\n",
- port + 1);
- return -EBUSY;
- }
+ if (ehci->resuming_ports) {
+ spin_unlock_irq(&ehci->lock);
+ ehci_dbg(ehci, "suspend failed because a port is resuming\n");
+ return -EBUSY;
}
}
@@ -554,16 +549,12 @@ static int
ehci_hub_status_data (struct usb_hcd *hcd, char *buf)
{
struct ehci_hcd *ehci = hcd_to_ehci (hcd);
- u32 temp, status = 0;
+ u32 temp, status;
u32 mask;
int ports, i, retval = 1;
unsigned long flags;
u32 ppcd = 0;
- /* if !USB_SUSPEND, root hub timers won't get shut down ... */
- if (ehci->rh_state != EHCI_RH_RUNNING)
- return 0;
-
/* init status to no-changes */
buf [0] = 0;
ports = HCS_N_PORTS (ehci->hcs_params);
@@ -572,6 +563,11 @@ ehci_hub_status_data (struct usb_hcd *hcd, char *buf)
retval++;
}
+ /* Inform the core about resumes-in-progress by returning
+ * a non-zero value even if there are no status changes.
+ */
+ status = ehci->resuming_ports;
+
/* Some boards (mostly VIA?) report bogus overcurrent indications,
* causing massive log spam unless we completely ignore them. It
* may be relevant that VIA VT8235 controllers, where PORT_POWER is
@@ -846,6 +842,7 @@ static int ehci_hub_control (
ehci_writel(ehci,
temp & ~(PORT_RWC_BITS | PORT_RESUME),
status_reg);
+ clear_bit(wIndex, &ehci->resuming_ports);
retval = handshake(ehci, status_reg,
PORT_RESUME, 0, 2000 /* 2msec */);
if (retval != 0) {
@@ -864,6 +861,7 @@ static int ehci_hub_control (
ehci->reset_done[wIndex])) {
status |= USB_PORT_STAT_C_RESET << 16;
ehci->reset_done [wIndex] = 0;
+ clear_bit(wIndex, &ehci->resuming_ports);
/* force reset to complete */
ehci_writel(ehci, temp & ~(PORT_RWC_BITS | PORT_RESET),
@@ -884,8 +882,10 @@ static int ehci_hub_control (
ehci_readl(ehci, status_reg));
}
- if (!(temp & (PORT_RESUME|PORT_RESET)))
+ if (!(temp & (PORT_RESUME|PORT_RESET))) {
ehci->reset_done[wIndex] = 0;
+ clear_bit(wIndex, &ehci->resuming_ports);
+ }
/* transfer dedicated ports to the companion hc */
if ((temp & PORT_CONNECT) &&
@@ -920,6 +920,7 @@ static int ehci_hub_control (
status |= USB_PORT_STAT_SUSPEND;
} else if (test_bit(wIndex, &ehci->suspended_ports)) {
clear_bit(wIndex, &ehci->suspended_ports);
+ clear_bit(wIndex, &ehci->resuming_ports);
ehci->reset_done[wIndex] = 0;
if (temp & PORT_PE)
set_bit(wIndex, &ehci->port_c_suspend);
diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c
index bba9850f32f0..5c78f9e71466 100644
--- a/drivers/usb/host/ehci-omap.c
+++ b/drivers/usb/host/ehci-omap.c
@@ -42,6 +42,7 @@
#include <plat/usb.h>
#include <linux/regulator/consumer.h>
#include <linux/pm_runtime.h>
+#include <linux/gpio.h>
/* EHCI Register Set */
#define EHCI_INSNREG04 (0xA0)
@@ -191,6 +192,19 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev)
}
}
+ if (pdata->phy_reset) {
+ if (gpio_is_valid(pdata->reset_gpio_port[0]))
+ gpio_request_one(pdata->reset_gpio_port[0],
+ GPIOF_OUT_INIT_LOW, "USB1 PHY reset");
+
+ if (gpio_is_valid(pdata->reset_gpio_port[1]))
+ gpio_request_one(pdata->reset_gpio_port[1],
+ GPIOF_OUT_INIT_LOW, "USB2 PHY reset");
+
+ /* Hold the PHY in RESET for enough time till DIR is high */
+ udelay(10);
+ }
+
pm_runtime_enable(dev);
pm_runtime_get_sync(dev);
@@ -237,6 +251,19 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev)
/* root ports should always stay powered */
ehci_port_power(omap_ehci, 1);
+ if (pdata->phy_reset) {
+ /* Hold the PHY in RESET for enough time till
+ * PHY is settled and ready
+ */
+ udelay(10);
+
+ if (gpio_is_valid(pdata->reset_gpio_port[0]))
+ gpio_set_value(pdata->reset_gpio_port[0], 1);
+
+ if (gpio_is_valid(pdata->reset_gpio_port[1]))
+ gpio_set_value(pdata->reset_gpio_port[1], 1);
+ }
+
return 0;
err_add_hcd:
@@ -259,8 +286,9 @@ err_io:
*/
static int ehci_hcd_omap_remove(struct platform_device *pdev)
{
- struct device *dev = &pdev->dev;
- struct usb_hcd *hcd = dev_get_drvdata(dev);
+ struct device *dev = &pdev->dev;
+ struct usb_hcd *hcd = dev_get_drvdata(dev);
+ struct ehci_hcd_omap_platform_data *pdata = dev->platform_data;
usb_remove_hcd(hcd);
disable_put_regulator(dev->platform_data);
@@ -269,6 +297,13 @@ static int ehci_hcd_omap_remove(struct platform_device *pdev)
pm_runtime_put_sync(dev);
pm_runtime_disable(dev);
+ if (pdata->phy_reset) {
+ if (gpio_is_valid(pdata->reset_gpio_port[0]))
+ gpio_free(pdata->reset_gpio_port[0]);
+
+ if (gpio_is_valid(pdata->reset_gpio_port[1]))
+ gpio_free(pdata->reset_gpio_port[1]);
+ }
return 0;
}
diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c
index 3de48a2d7955..86183366647f 100644
--- a/drivers/usb/host/ehci-tegra.c
+++ b/drivers/usb/host/ehci-tegra.c
@@ -224,6 +224,7 @@ static int tegra_ehci_hub_control(
temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS);
/* start resume signalling */
ehci_writel(ehci, temp | PORT_RESUME, status_reg);
+ set_bit(wIndex-1, &ehci->resuming_ports);
spin_unlock_irqrestore(&ehci->lock, flags);
msleep(20);
@@ -236,6 +237,7 @@ static int tegra_ehci_hub_control(
pr_err("%s: timeout waiting for SUSPEND\n", __func__);
ehci->reset_done[wIndex-1] = 0;
+ clear_bit(wIndex-1, &ehci->resuming_ports);
tegra->port_resuming = 1;
goto done;
@@ -729,7 +731,6 @@ static int tegra_ehci_probe(struct platform_device *pdev)
err = -ENODEV;
goto fail;
}
- set_irq_flags(irq, IRQF_VALID);
#ifdef CONFIG_USB_OTG_UTILS
if (pdata->operating_mode == TEGRA_USB_OTG) {
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index 8f9acbc96fde..2694ed6558d2 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -117,6 +117,8 @@ struct ehci_hcd { /* one per controller */
the change-suspend feature turned on */
unsigned long suspended_ports; /* which ports are
suspended */
+ unsigned long resuming_ports; /* which ports have
+ started to resume */
/* per-HC memory pools (could be per-bus, but ...) */
struct dma_pool *qh_pool; /* qh per active urb */
diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c
index db8963f5fbce..13ebeca8e73e 100644
--- a/drivers/usb/host/ohci-at91.c
+++ b/drivers/usb/host/ohci-at91.c
@@ -27,6 +27,10 @@
#error "CONFIG_ARCH_AT91 must be defined."
#endif
+#define valid_port(index) ((index) >= 0 && (index) < AT91_MAX_USBH_PORTS)
+#define at91_for_each_port(index) \
+ for ((index) = 0; (index) < AT91_MAX_USBH_PORTS; (index)++)
+
/* interface and function clocks; sometimes also an AHB clock */
static struct clk *iclk, *fclk, *hclk;
static int clocked;
@@ -90,7 +94,7 @@ static void at91_stop_hc(struct platform_device *pdev)
/*-------------------------------------------------------------------------*/
-static void usb_hcd_at91_remove (struct usb_hcd *, struct platform_device *);
+static void __devexit usb_hcd_at91_remove (struct usb_hcd *, struct platform_device *);
/* configure so an HC device and id are always provided */
/* always called with process context; sleeping is OK */
@@ -104,7 +108,7 @@ static void usb_hcd_at91_remove (struct usb_hcd *, struct platform_device *);
* then invokes the start() method for the HCD associated with it
* through the hotplug entry's driver_data.
*/
-static int usb_hcd_at91_probe(const struct hc_driver *driver,
+static int __devinit usb_hcd_at91_probe(const struct hc_driver *driver,
struct platform_device *pdev)
{
int retval;
@@ -199,7 +203,7 @@ static int usb_hcd_at91_probe(const struct hc_driver *driver,
* context, "rmmod" or something similar.
*
*/
-static void usb_hcd_at91_remove(struct usb_hcd *hcd,
+static void __devexit usb_hcd_at91_remove(struct usb_hcd *hcd,
struct platform_device *pdev)
{
usb_remove_hcd(hcd);
@@ -240,26 +244,26 @@ ohci_at91_start (struct usb_hcd *hcd)
static void ohci_at91_usb_set_power(struct at91_usbh_data *pdata, int port, int enable)
{
- if (port < 0 || port >= 2)
+ if (!valid_port(port))
return;
if (!gpio_is_valid(pdata->vbus_pin[port]))
return;
gpio_set_value(pdata->vbus_pin[port],
- !pdata->vbus_pin_active_low[port] ^ enable);
+ pdata->vbus_pin_active_low[port] ^ enable);
}
static int ohci_at91_usb_get_power(struct at91_usbh_data *pdata, int port)
{
- if (port < 0 || port >= 2)
+ if (!valid_port(port))
return -EINVAL;
if (!gpio_is_valid(pdata->vbus_pin[port]))
return -EINVAL;
return gpio_get_value(pdata->vbus_pin[port]) ^
- !pdata->vbus_pin_active_low[port];
+ pdata->vbus_pin_active_low[port];
}
/*
@@ -271,9 +275,9 @@ static int ohci_at91_hub_status_data(struct usb_hcd *hcd, char *buf)
int length = ohci_hub_status_data(hcd, buf);
int port;
- for (port = 0; port < ARRAY_SIZE(pdata->overcurrent_pin); port++) {
+ at91_for_each_port(port) {
if (pdata->overcurrent_changed[port]) {
- if (! length)
+ if (!length)
length = 1;
buf[0] |= 1 << (port + 1);
}
@@ -297,11 +301,17 @@ static int ohci_at91_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
"ohci_at91_hub_control(%p,0x%04x,0x%04x,0x%04x,%p,%04x)\n",
hcd, typeReq, wValue, wIndex, buf, wLength);
+ wIndex--;
+
switch (typeReq) {
case SetPortFeature:
if (wValue == USB_PORT_FEAT_POWER) {
dev_dbg(hcd->self.controller, "SetPortFeat: POWER\n");
- ohci_at91_usb_set_power(pdata, wIndex - 1, 1);
+ if (valid_port(wIndex)) {
+ ohci_at91_usb_set_power(pdata, wIndex, 1);
+ ret = 0;
+ }
+
goto out;
}
break;
@@ -312,9 +322,9 @@ static int ohci_at91_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
dev_dbg(hcd->self.controller,
"ClearPortFeature: C_OVER_CURRENT\n");
- if (wIndex == 1 || wIndex == 2) {
- pdata->overcurrent_changed[wIndex-1] = 0;
- pdata->overcurrent_status[wIndex-1] = 0;
+ if (valid_port(wIndex)) {
+ pdata->overcurrent_changed[wIndex] = 0;
+ pdata->overcurrent_status[wIndex] = 0;
}
goto out;
@@ -323,9 +333,8 @@ static int ohci_at91_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
dev_dbg(hcd->self.controller,
"ClearPortFeature: OVER_CURRENT\n");
- if (wIndex == 1 || wIndex == 2) {
- pdata->overcurrent_status[wIndex-1] = 0;
- }
+ if (valid_port(wIndex))
+ pdata->overcurrent_status[wIndex] = 0;
goto out;
@@ -333,15 +342,15 @@ static int ohci_at91_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
dev_dbg(hcd->self.controller,
"ClearPortFeature: POWER\n");
- if (wIndex == 1 || wIndex == 2) {
- ohci_at91_usb_set_power(pdata, wIndex - 1, 0);
+ if (valid_port(wIndex)) {
+ ohci_at91_usb_set_power(pdata, wIndex, 0);
return 0;
}
}
break;
}
- ret = ohci_hub_control(hcd, typeReq, wValue, wIndex, buf, wLength);
+ ret = ohci_hub_control(hcd, typeReq, wValue, wIndex + 1, buf, wLength);
if (ret)
goto out;
@@ -377,18 +386,15 @@ static int ohci_at91_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
dev_dbg(hcd->self.controller, "GetPortStatus(%d)\n", wIndex);
- if (wIndex == 1 || wIndex == 2) {
- if (! ohci_at91_usb_get_power(pdata, wIndex-1)) {
+ if (valid_port(wIndex)) {
+ if (!ohci_at91_usb_get_power(pdata, wIndex))
*data &= ~cpu_to_le32(RH_PS_PPS);
- }
- if (pdata->overcurrent_changed[wIndex-1]) {
+ if (pdata->overcurrent_changed[wIndex])
*data |= cpu_to_le32(RH_PS_OCIC);
- }
- if (pdata->overcurrent_status[wIndex-1]) {
+ if (pdata->overcurrent_status[wIndex])
*data |= cpu_to_le32(RH_PS_POCI);
- }
}
}
@@ -450,14 +456,14 @@ static irqreturn_t ohci_hcd_at91_overcurrent_irq(int irq, void *data)
/* From the GPIO notifying the over-current situation, find
* out the corresponding port */
- for (port = 0; port < ARRAY_SIZE(pdata->overcurrent_pin); port++) {
+ at91_for_each_port(port) {
if (gpio_to_irq(pdata->overcurrent_pin[port]) == irq) {
gpio = pdata->overcurrent_pin[port];
break;
}
}
- if (port == ARRAY_SIZE(pdata->overcurrent_pin)) {
+ if (port == AT91_MAX_USBH_PORTS) {
dev_err(& pdev->dev, "overcurrent interrupt from unknown GPIO\n");
return IRQ_HANDLED;
}
@@ -467,7 +473,7 @@ static irqreturn_t ohci_hcd_at91_overcurrent_irq(int irq, void *data)
/* When notified of an over-current situation, disable power
on the corresponding port, and mark this port in
over-current. */
- if (! val) {
+ if (!val) {
ohci_at91_usb_set_power(pdata, port, 0);
pdata->overcurrent_status[port] = 1;
pdata->overcurrent_changed[port] = 1;
@@ -492,7 +498,7 @@ static u64 at91_ohci_dma_mask = DMA_BIT_MASK(32);
static int __devinit ohci_at91_of_init(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
- int i, ret, gpio;
+ int i, gpio;
enum of_gpio_flags flags;
struct at91_usbh_data *pdata;
u32 ports;
@@ -514,48 +520,17 @@ static int __devinit ohci_at91_of_init(struct platform_device *pdev)
if (!of_property_read_u32(np, "num-ports", &ports))
pdata->ports = ports;
- for (i = 0; i < 2; i++) {
+ at91_for_each_port(i) {
gpio = of_get_named_gpio_flags(np, "atmel,vbus-gpio", i, &flags);
pdata->vbus_pin[i] = gpio;
if (!gpio_is_valid(gpio))
continue;
pdata->vbus_pin_active_low[i] = flags & OF_GPIO_ACTIVE_LOW;
- ret = gpio_request(gpio, "ohci_vbus");
- if (ret) {
- dev_warn(&pdev->dev, "can't request vbus gpio %d", gpio);
- continue;
- }
- ret = gpio_direction_output(gpio, !(flags & OF_GPIO_ACTIVE_LOW) ^ 1);
- if (ret)
- dev_warn(&pdev->dev, "can't put vbus gpio %d as output %d",
- !(flags & OF_GPIO_ACTIVE_LOW) ^ 1, gpio);
}
- for (i = 0; i < 2; i++) {
- gpio = of_get_named_gpio_flags(np, "atmel,oc-gpio", i, &flags);
- pdata->overcurrent_pin[i] = gpio;
- if (!gpio_is_valid(gpio))
- continue;
- ret = gpio_request(gpio, "ohci_overcurrent");
- if (ret) {
- dev_err(&pdev->dev, "can't request overcurrent gpio %d", gpio);
- continue;
- }
-
- ret = gpio_direction_input(gpio);
- if (ret) {
- dev_err(&pdev->dev, "can't configure overcurrent gpio %d as input", gpio);
- continue;
- }
-
- ret = request_irq(gpio_to_irq(gpio),
- ohci_hcd_at91_overcurrent_irq,
- IRQF_SHARED, "ohci_overcurrent", pdev);
- if (ret) {
- gpio_free(gpio);
- dev_warn(& pdev->dev, "cannot get GPIO IRQ for overcurrent\n");
- }
- }
+ at91_for_each_port(i)
+ pdata->overcurrent_pin[i] =
+ of_get_named_gpio_flags(np, "atmel,oc-gpio", i, &flags);
pdev->dev.platform_data = pdata;
@@ -570,39 +545,73 @@ static int __devinit ohci_at91_of_init(struct platform_device *pdev)
/*-------------------------------------------------------------------------*/
-static int ohci_hcd_at91_drv_probe(struct platform_device *pdev)
+static int __devinit ohci_hcd_at91_drv_probe(struct platform_device *pdev)
{
struct at91_usbh_data *pdata;
int i;
+ int gpio;
+ int ret;
- i = ohci_at91_of_init(pdev);
-
- if (i)
- return i;
+ ret = ohci_at91_of_init(pdev);
+ if (ret)
+ return ret;
pdata = pdev->dev.platform_data;
if (pdata) {
- for (i = 0; i < ARRAY_SIZE(pdata->vbus_pin); i++) {
+ at91_for_each_port(i) {
if (!gpio_is_valid(pdata->vbus_pin[i]))
continue;
- gpio_request(pdata->vbus_pin[i], "ohci_vbus");
+ gpio = pdata->vbus_pin[i];
+
+ ret = gpio_request(gpio, "ohci_vbus");
+ if (ret) {
+ dev_err(&pdev->dev,
+ "can't request vbus gpio %d\n", gpio);
+ continue;
+ }
+ ret = gpio_direction_output(gpio,
+ !pdata->vbus_pin_active_low[i]);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "can't put vbus gpio %d as output %d\n",
+ gpio, !pdata->vbus_pin_active_low[i]);
+ gpio_free(gpio);
+ continue;
+ }
+
ohci_at91_usb_set_power(pdata, i, 1);
}
- for (i = 0; i < ARRAY_SIZE(pdata->overcurrent_pin); i++) {
- int ret;
-
+ at91_for_each_port(i) {
if (!gpio_is_valid(pdata->overcurrent_pin[i]))
continue;
- gpio_request(pdata->overcurrent_pin[i], "ohci_overcurrent");
+ gpio = pdata->overcurrent_pin[i];
+
+ ret = gpio_request(gpio, "ohci_overcurrent");
+ if (ret) {
+ dev_err(&pdev->dev,
+ "can't request overcurrent gpio %d\n",
+ gpio);
+ continue;
+ }
+
+ ret = gpio_direction_input(gpio);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "can't configure overcurrent gpio %d as input\n",
+ gpio);
+ gpio_free(gpio);
+ continue;
+ }
- ret = request_irq(gpio_to_irq(pdata->overcurrent_pin[i]),
+ ret = request_irq(gpio_to_irq(gpio),
ohci_hcd_at91_overcurrent_irq,
IRQF_SHARED, "ohci_overcurrent", pdev);
if (ret) {
- gpio_free(pdata->overcurrent_pin[i]);
- dev_warn(& pdev->dev, "cannot get GPIO IRQ for overcurrent\n");
+ gpio_free(gpio);
+ dev_err(&pdev->dev,
+ "can't get gpio IRQ for overcurrent\n");
}
}
}
@@ -611,20 +620,20 @@ static int ohci_hcd_at91_drv_probe(struct platform_device *pdev)
return usb_hcd_at91_probe(&ohci_at91_hc_driver, pdev);
}
-static int ohci_hcd_at91_drv_remove(struct platform_device *pdev)
+static int __devexit ohci_hcd_at91_drv_remove(struct platform_device *pdev)
{
struct at91_usbh_data *pdata = pdev->dev.platform_data;
int i;
if (pdata) {
- for (i = 0; i < ARRAY_SIZE(pdata->vbus_pin); i++) {
+ at91_for_each_port(i) {
if (!gpio_is_valid(pdata->vbus_pin[i]))
continue;
ohci_at91_usb_set_power(pdata, i, 0);
gpio_free(pdata->vbus_pin[i]);
}
- for (i = 0; i < ARRAY_SIZE(pdata->overcurrent_pin); i++) {
+ at91_for_each_port(i) {
if (!gpio_is_valid(pdata->overcurrent_pin[i]))
continue;
free_irq(gpio_to_irq(pdata->overcurrent_pin[i]), pdev);
@@ -687,7 +696,7 @@ MODULE_ALIAS("platform:at91_ohci");
static struct platform_driver ohci_hcd_at91_driver = {
.probe = ohci_hcd_at91_drv_probe,
- .remove = ohci_hcd_at91_drv_remove,
+ .remove = __devexit_p(ohci_hcd_at91_drv_remove),
.shutdown = usb_hcd_platform_shutdown,
.suspend = ohci_hcd_at91_drv_suspend,
.resume = ohci_hcd_at91_drv_resume,
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c
index 11de5f1be981..32dada8c8b4f 100644
--- a/drivers/usb/host/pci-quirks.c
+++ b/drivers/usb/host/pci-quirks.c
@@ -825,9 +825,13 @@ static void __devinit quirk_usb_handoff_xhci(struct pci_dev *pdev)
}
}
- /* Disable any BIOS SMIs */
- writel(XHCI_LEGACY_DISABLE_SMI,
- base + ext_cap_offset + XHCI_LEGACY_CONTROL_OFFSET);
+ val = readl(base + ext_cap_offset + XHCI_LEGACY_CONTROL_OFFSET);
+ /* Mask off (turn off) any enabled SMIs */
+ val &= XHCI_LEGACY_DISABLE_SMI;
+ /* Mask all SMI events bits, RW1C */
+ val |= XHCI_LEGACY_SMI_EVENTS;
+ /* Disable any BIOS SMIs and clear all SMI events*/
+ writel(val, base + ext_cap_offset + XHCI_LEGACY_CONTROL_OFFSET);
if (usb_is_intel_switchable_xhci(pdev))
usb_enable_xhci_ports(pdev);
diff --git a/drivers/usb/host/uhci-hub.c b/drivers/usb/host/uhci-hub.c
index 045cde4cbc3d..768d54295a20 100644
--- a/drivers/usb/host/uhci-hub.c
+++ b/drivers/usb/host/uhci-hub.c
@@ -196,11 +196,12 @@ static int uhci_hub_status_data(struct usb_hcd *hcd, char *buf)
status = get_hub_status_data(uhci, buf);
switch (uhci->rh_state) {
- case UHCI_RH_SUSPENDING:
case UHCI_RH_SUSPENDED:
/* if port change, ask to be resumed */
- if (status || uhci->resuming_ports)
+ if (status || uhci->resuming_ports) {
+ status = 1;
usb_hcd_resume_root_hub(hcd);
+ }
break;
case UHCI_RH_AUTO_STOPPED:
diff --git a/drivers/usb/host/xhci-dbg.c b/drivers/usb/host/xhci-dbg.c
index e9b0f043455d..4b436f5a4171 100644
--- a/drivers/usb/host/xhci-dbg.c
+++ b/drivers/usb/host/xhci-dbg.c
@@ -119,7 +119,7 @@ static void xhci_print_command_reg(struct xhci_hcd *xhci)
xhci_dbg(xhci, " Event Interrupts %s\n",
(temp & CMD_EIE) ? "enabled " : "disabled");
xhci_dbg(xhci, " Host System Error Interrupts %s\n",
- (temp & CMD_EIE) ? "enabled " : "disabled");
+ (temp & CMD_HSEIE) ? "enabled " : "disabled");
xhci_dbg(xhci, " HC has %sfinished light reset\n",
(temp & CMD_LRESET) ? "not " : "");
}
diff --git a/drivers/usb/host/xhci-ext-caps.h b/drivers/usb/host/xhci-ext-caps.h
index c7f33123d4c0..377f4242dabb 100644
--- a/drivers/usb/host/xhci-ext-caps.h
+++ b/drivers/usb/host/xhci-ext-caps.h
@@ -62,8 +62,9 @@
/* USB Legacy Support Control and Status Register - section 7.1.2 */
/* Add this offset, plus the value of xECP in HCCPARAMS to the base address */
#define XHCI_LEGACY_CONTROL_OFFSET (0x04)
-/* bits 1:2, 5:12, and 17:19 need to be preserved; bits 21:28 should be zero */
-#define XHCI_LEGACY_DISABLE_SMI ((0x3 << 1) + (0xff << 5) + (0x7 << 17))
+/* bits 1:3, 5:12, and 17:19 need to be preserved; bits 21:28 should be zero */
+#define XHCI_LEGACY_DISABLE_SMI ((0x7 << 1) + (0xff << 5) + (0x7 << 17))
+#define XHCI_LEGACY_SMI_EVENTS (0x7 << 29)
/* USB 2.0 xHCI 0.96 L1C capability - section 7.2.2.1.3.2 */
#define XHCI_L1C (1 << 16)
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index cae4c6f2845a..68eaa908ac8e 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -1796,11 +1796,6 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
int i;
/* Free the Event Ring Segment Table and the actual Event Ring */
- if (xhci->ir_set) {
- xhci_writel(xhci, 0, &xhci->ir_set->erst_size);
- xhci_write_64(xhci, 0, &xhci->ir_set->erst_base);
- xhci_write_64(xhci, 0, &xhci->ir_set->erst_dequeue);
- }
size = sizeof(struct xhci_erst_entry)*(xhci->erst.num_entries);
if (xhci->erst.entries)
dma_free_coherent(&pdev->dev, size,
@@ -1812,7 +1807,6 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
xhci->event_ring = NULL;
xhci_dbg(xhci, "Freed event ring\n");
- xhci_write_64(xhci, 0, &xhci->op_regs->cmd_ring);
if (xhci->cmd_ring)
xhci_ring_free(xhci, xhci->cmd_ring);
xhci->cmd_ring = NULL;
@@ -1841,7 +1835,6 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
xhci->medium_streams_pool = NULL;
xhci_dbg(xhci, "Freed medium stream array pool\n");
- xhci_write_64(xhci, 0, &xhci->op_regs->dcbaa_ptr);
if (xhci->dcbaa)
dma_free_coherent(&pdev->dev, sizeof(*xhci->dcbaa),
xhci->dcbaa, xhci->dcbaa->dma);
@@ -2459,6 +2452,8 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
fail:
xhci_warn(xhci, "Couldn't initialize memory\n");
+ xhci_halt(xhci);
+ xhci_reset(xhci);
xhci_mem_cleanup(xhci);
return -ENOMEM;
}
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index ef98b38626fb..7a856a767e77 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -95,6 +95,8 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
xhci->quirks |= XHCI_RESET_ON_RESUME;
xhci_dbg(xhci, "QUIRK: Resetting on resume\n");
}
+ if (pdev->vendor == PCI_VENDOR_ID_VIA)
+ xhci->quirks |= XHCI_RESET_ON_RESUME;
}
/* called during probe() after chip reset completes */
@@ -326,7 +328,7 @@ int __init xhci_register_pci(void)
return pci_register_driver(&xhci_pci_driver);
}
-void __exit xhci_unregister_pci(void)
+void xhci_unregister_pci(void)
{
pci_unregister_driver(&xhci_pci_driver);
}
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 6bd9d53062eb..3d9422f16a20 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -2417,7 +2417,7 @@ hw_died:
u32 irq_pending;
/* Acknowledge the PCI interrupt */
irq_pending = xhci_readl(xhci, &xhci->ir_set->irq_pending);
- irq_pending |= 0x3;
+ irq_pending |= IMAN_IP;
xhci_writel(xhci, irq_pending, &xhci->ir_set->irq_pending);
}
@@ -2734,7 +2734,7 @@ int xhci_queue_intr_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
urb->dev->speed == USB_SPEED_FULL)
urb->interval /= 8;
}
- return xhci_queue_bulk_tx(xhci, GFP_ATOMIC, urb, slot_id, ep_index);
+ return xhci_queue_bulk_tx(xhci, mem_flags, urb, slot_id, ep_index);
}
/*
@@ -3514,7 +3514,7 @@ int xhci_queue_isoc_tx_prepare(struct xhci_hcd *xhci, gfp_t mem_flags,
}
ep_ring->num_trbs_free_temp = ep_ring->num_trbs_free;
- return xhci_queue_isoc_tx(xhci, GFP_ATOMIC, urb, slot_id, ep_index);
+ return xhci_queue_isoc_tx(xhci, mem_flags, urb, slot_id, ep_index);
}
/**** Command Ring Operations ****/
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index e1963d4a430f..36641a7f2371 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -106,6 +106,9 @@ int xhci_halt(struct xhci_hcd *xhci)
STS_HALT, STS_HALT, XHCI_MAX_HALT_USEC);
if (!ret)
xhci->xhc_state |= XHCI_STATE_HALTED;
+ else
+ xhci_warn(xhci, "Host not halted after %u microseconds.\n",
+ XHCI_MAX_HALT_USEC);
return ret;
}
@@ -664,11 +667,11 @@ static void xhci_save_registers(struct xhci_hcd *xhci)
xhci->s3.dev_nt = xhci_readl(xhci, &xhci->op_regs->dev_notification);
xhci->s3.dcbaa_ptr = xhci_read_64(xhci, &xhci->op_regs->dcbaa_ptr);
xhci->s3.config_reg = xhci_readl(xhci, &xhci->op_regs->config_reg);
- xhci->s3.irq_pending = xhci_readl(xhci, &xhci->ir_set->irq_pending);
- xhci->s3.irq_control = xhci_readl(xhci, &xhci->ir_set->irq_control);
xhci->s3.erst_size = xhci_readl(xhci, &xhci->ir_set->erst_size);
xhci->s3.erst_base = xhci_read_64(xhci, &xhci->ir_set->erst_base);
xhci->s3.erst_dequeue = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue);
+ xhci->s3.irq_pending = xhci_readl(xhci, &xhci->ir_set->irq_pending);
+ xhci->s3.irq_control = xhci_readl(xhci, &xhci->ir_set->irq_control);
}
static void xhci_restore_registers(struct xhci_hcd *xhci)
@@ -677,10 +680,11 @@ static void xhci_restore_registers(struct xhci_hcd *xhci)
xhci_writel(xhci, xhci->s3.dev_nt, &xhci->op_regs->dev_notification);
xhci_write_64(xhci, xhci->s3.dcbaa_ptr, &xhci->op_regs->dcbaa_ptr);
xhci_writel(xhci, xhci->s3.config_reg, &xhci->op_regs->config_reg);
- xhci_writel(xhci, xhci->s3.irq_pending, &xhci->ir_set->irq_pending);
- xhci_writel(xhci, xhci->s3.irq_control, &xhci->ir_set->irq_control);
xhci_writel(xhci, xhci->s3.erst_size, &xhci->ir_set->erst_size);
xhci_write_64(xhci, xhci->s3.erst_base, &xhci->ir_set->erst_base);
+ xhci_write_64(xhci, xhci->s3.erst_dequeue, &xhci->ir_set->erst_dequeue);
+ xhci_writel(xhci, xhci->s3.irq_pending, &xhci->ir_set->irq_pending);
+ xhci_writel(xhci, xhci->s3.irq_control, &xhci->ir_set->irq_control);
}
static void xhci_set_cmd_ring_deq(struct xhci_hcd *xhci)
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 91074fdab3eb..3d69c4b2b542 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -205,6 +205,10 @@ struct xhci_op_regs {
#define CMD_PM_INDEX (1 << 11)
/* bits 12:31 are reserved (and should be preserved on writes). */
+/* IMAN - Interrupt Management Register */
+#define IMAN_IP (1 << 1)
+#define IMAN_IE (1 << 0)
+
/* USBSTS - USB status - status bitmasks */
/* HC not running - set to 1 when run/stop bit is cleared. */
#define STS_HALT XHCI_STS_HALT
diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c
index 959145baf3cf..9dcb68f04f03 100644
--- a/drivers/usb/misc/usbtest.c
+++ b/drivers/usb/misc/usbtest.c
@@ -423,7 +423,7 @@ alloc_sglist(int nents, int max, int vary)
unsigned i;
unsigned size = max;
- sg = kmalloc(nents * sizeof *sg, GFP_KERNEL);
+ sg = kmalloc_array(nents, sizeof *sg, GFP_KERNEL);
if (!sg)
return NULL;
sg_init_table(sg, nents);
@@ -904,6 +904,9 @@ test_ctrl_queue(struct usbtest_dev *dev, struct usbtest_param *param)
struct ctrl_ctx context;
int i;
+ if (param->sglen == 0 || param->iterations > UINT_MAX / param->sglen)
+ return -EOPNOTSUPP;
+
spin_lock_init(&context.lock);
context.dev = dev;
init_completion(&context.complete);
@@ -1981,8 +1984,6 @@ usbtest_ioctl(struct usb_interface *intf, unsigned int code, void *buf)
/* queued control messaging */
case 10:
- if (param->sglen == 0)
- break;
retval = 0;
dev_info(&intf->dev,
"TEST 10: queue %d control calls, %d times\n",
@@ -2276,6 +2277,8 @@ usbtest_probe(struct usb_interface *intf, const struct usb_device_id *id)
if (status < 0) {
WARNING(dev, "couldn't get endpoints, %d\n",
status);
+ kfree(dev->buf);
+ kfree(dev);
return status;
}
/* may find bulk or ISO pipes */
diff --git a/drivers/usb/misc/yurex.c b/drivers/usb/misc/yurex.c
index 897edda42270..70201462e19c 100644
--- a/drivers/usb/misc/yurex.c
+++ b/drivers/usb/misc/yurex.c
@@ -99,9 +99,7 @@ static void yurex_delete(struct kref *kref)
usb_put_dev(dev->udev);
if (dev->cntl_urb) {
usb_kill_urb(dev->cntl_urb);
- if (dev->cntl_req)
- usb_free_coherent(dev->udev, YUREX_BUF_SIZE,
- dev->cntl_req, dev->cntl_urb->setup_dma);
+ kfree(dev->cntl_req);
if (dev->cntl_buffer)
usb_free_coherent(dev->udev, YUREX_BUF_SIZE,
dev->cntl_buffer, dev->cntl_urb->transfer_dma);
@@ -234,9 +232,7 @@ static int yurex_probe(struct usb_interface *interface, const struct usb_device_
}
/* allocate buffer for control req */
- dev->cntl_req = usb_alloc_coherent(dev->udev, YUREX_BUF_SIZE,
- GFP_KERNEL,
- &dev->cntl_urb->setup_dma);
+ dev->cntl_req = kmalloc(YUREX_BUF_SIZE, GFP_KERNEL);
if (!dev->cntl_req) {
err("Could not allocate cntl_req");
goto error;
@@ -286,7 +282,7 @@ static int yurex_probe(struct usb_interface *interface, const struct usb_device_
usb_rcvintpipe(dev->udev, dev->int_in_endpointAddr),
dev->int_buffer, YUREX_BUF_SIZE, yurex_interrupt,
dev, 1);
- dev->cntl_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+ dev->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
if (usb_submit_urb(dev->urb, GFP_KERNEL)) {
retval = -EIO;
err("Could not submitting URB");
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index 0f8b82918a40..66aaccf04490 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -137,6 +137,9 @@ static int musb_ulpi_read(struct usb_phy *phy, u32 offset)
int i = 0;
u8 r;
u8 power;
+ int ret;
+
+ pm_runtime_get_sync(phy->io_dev);
/* Make sure the transceiver is not in low power mode */
power = musb_readb(addr, MUSB_POWER);
@@ -154,15 +157,22 @@ static int musb_ulpi_read(struct usb_phy *phy, u32 offset)
while (!(musb_readb(addr, MUSB_ULPI_REG_CONTROL)
& MUSB_ULPI_REG_CMPLT)) {
i++;
- if (i == 10000)
- return -ETIMEDOUT;
+ if (i == 10000) {
+ ret = -ETIMEDOUT;
+ goto out;
+ }
}
r = musb_readb(addr, MUSB_ULPI_REG_CONTROL);
r &= ~MUSB_ULPI_REG_CMPLT;
musb_writeb(addr, MUSB_ULPI_REG_CONTROL, r);
- return musb_readb(addr, MUSB_ULPI_REG_DATA);
+ ret = musb_readb(addr, MUSB_ULPI_REG_DATA);
+
+out:
+ pm_runtime_put(phy->io_dev);
+
+ return ret;
}
static int musb_ulpi_write(struct usb_phy *phy, u32 offset, u32 data)
@@ -171,6 +181,9 @@ static int musb_ulpi_write(struct usb_phy *phy, u32 offset, u32 data)
int i = 0;
u8 r = 0;
u8 power;
+ int ret = 0;
+
+ pm_runtime_get_sync(phy->io_dev);
/* Make sure the transceiver is not in low power mode */
power = musb_readb(addr, MUSB_POWER);
@@ -184,15 +197,20 @@ static int musb_ulpi_write(struct usb_phy *phy, u32 offset, u32 data)
while (!(musb_readb(addr, MUSB_ULPI_REG_CONTROL)
& MUSB_ULPI_REG_CMPLT)) {
i++;
- if (i == 10000)
- return -ETIMEDOUT;
+ if (i == 10000) {
+ ret = -ETIMEDOUT;
+ goto out;
+ }
}
r = musb_readb(addr, MUSB_ULPI_REG_CONTROL);
r &= ~MUSB_ULPI_REG_CMPLT;
musb_writeb(addr, MUSB_ULPI_REG_CONTROL, r);
- return 0;
+out:
+ pm_runtime_put(phy->io_dev);
+
+ return ret;
}
#else
#define musb_ulpi_read NULL
@@ -1904,14 +1922,17 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
if (!musb->isr) {
status = -ENODEV;
- goto fail3;
+ goto fail2;
}
if (!musb->xceiv->io_ops) {
+ musb->xceiv->io_dev = musb->controller;
musb->xceiv->io_priv = musb->mregs;
musb->xceiv->io_ops = &musb_ulpi_access;
}
+ pm_runtime_get_sync(musb->controller);
+
#ifndef CONFIG_MUSB_PIO_ONLY
if (use_dma && dev->dma_mask) {
struct dma_controller *c;
@@ -2023,6 +2044,8 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
goto fail5;
#endif
+ pm_runtime_put(musb->controller);
+
dev_info(dev, "USB %s mode controller at %p using %s, IRQ %d\n",
({char *s;
switch (musb->board_mode) {
@@ -2047,6 +2070,9 @@ fail4:
musb_gadget_cleanup(musb);
fail3:
+ pm_runtime_put_sync(musb->controller);
+
+fail2:
if (musb->irq_wake)
device_init_wakeup(dev, 0);
musb_platform_exit(musb);
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
index 79cb0af779fa..ef8d744800ac 100644
--- a/drivers/usb/musb/musb_host.c
+++ b/drivers/usb/musb/musb_host.c
@@ -2098,7 +2098,7 @@ static int musb_cleanup_urb(struct urb *urb, struct musb_qh *qh)
}
/* turn off DMA requests, discard state, stop polling ... */
- if (is_in) {
+ if (ep->epnum && is_in) {
/* giveback saves bulk toggle */
csr = musb_h_flush_rxfifo(ep, 0);
diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c
index 2ae0bb309994..c7785e81254c 100644
--- a/drivers/usb/musb/omap2430.c
+++ b/drivers/usb/musb/omap2430.c
@@ -282,7 +282,8 @@ static void musb_otg_notifier_work(struct work_struct *data_notifier_work)
static int omap2430_musb_init(struct musb *musb)
{
- u32 l, status = 0;
+ u32 l;
+ int status = 0;
struct device *dev = musb->controller;
struct musb_hdrc_platform_data *plat = dev->platform_data;
struct omap_musb_board_data *data = plat->board_data;
@@ -301,7 +302,7 @@ static int omap2430_musb_init(struct musb *musb)
status = pm_runtime_get_sync(dev);
if (status < 0) {
- dev_err(dev, "pm_runtime_get_sync FAILED");
+ dev_err(dev, "pm_runtime_get_sync FAILED %d\n", status);
goto err1;
}
@@ -333,6 +334,7 @@ static int omap2430_musb_init(struct musb *musb)
setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb);
+ pm_runtime_put_noidle(musb->controller);
return 0;
err1:
@@ -452,14 +454,14 @@ static int __devinit omap2430_probe(struct platform_device *pdev)
goto err2;
}
+ pm_runtime_enable(&pdev->dev);
+
ret = platform_device_add(musb);
if (ret) {
dev_err(&pdev->dev, "failed to register musb device\n");
goto err2;
}
- pm_runtime_enable(&pdev->dev);
-
return 0;
err2:
@@ -478,7 +480,6 @@ static int __devexit omap2430_remove(struct platform_device *pdev)
platform_device_del(glue->musb);
platform_device_put(glue->musb);
- pm_runtime_put(&pdev->dev);
kfree(glue);
return 0;
@@ -491,11 +492,13 @@ static int omap2430_runtime_suspend(struct device *dev)
struct omap2430_glue *glue = dev_get_drvdata(dev);
struct musb *musb = glue_to_musb(glue);
- musb->context.otg_interfsel = musb_readl(musb->mregs,
- OTG_INTERFSEL);
+ if (musb) {
+ musb->context.otg_interfsel = musb_readl(musb->mregs,
+ OTG_INTERFSEL);
- omap2430_low_level_exit(musb);
- usb_phy_set_suspend(musb->xceiv, 1);
+ omap2430_low_level_exit(musb);
+ usb_phy_set_suspend(musb->xceiv, 1);
+ }
return 0;
}
@@ -505,11 +508,13 @@ static int omap2430_runtime_resume(struct device *dev)
struct omap2430_glue *glue = dev_get_drvdata(dev);
struct musb *musb = glue_to_musb(glue);
- omap2430_low_level_init(musb);
- musb_writel(musb->mregs, OTG_INTERFSEL,
- musb->context.otg_interfsel);
+ if (musb) {
+ omap2430_low_level_init(musb);
+ musb_writel(musb->mregs, OTG_INTERFSEL,
+ musb->context.otg_interfsel);
- usb_phy_set_suspend(musb->xceiv, 0);
+ usb_phy_set_suspend(musb->xceiv, 0);
+ }
return 0;
}
diff --git a/drivers/usb/serial/bus.c b/drivers/usb/serial/bus.c
index 7f547dc3a590..ed8adb052ca7 100644
--- a/drivers/usb/serial/bus.c
+++ b/drivers/usb/serial/bus.c
@@ -60,8 +60,6 @@ static int usb_serial_device_probe(struct device *dev)
retval = -ENODEV;
goto exit;
}
- if (port->dev_state != PORT_REGISTERING)
- goto exit;
driver = port->serial->type;
if (driver->port_probe) {
@@ -98,9 +96,6 @@ static int usb_serial_device_remove(struct device *dev)
if (!port)
return -ENODEV;
- if (port->dev_state != PORT_UNREGISTERING)
- return retval;
-
device_remove_file(&port->dev, &dev_attr_port_number);
driver = port->serial->type;
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
index 0310e2df59f5..ec30f95ef399 100644
--- a/drivers/usb/serial/cp210x.c
+++ b/drivers/usb/serial/cp210x.c
@@ -287,7 +287,8 @@ static int cp210x_get_config(struct usb_serial_port *port, u8 request,
/* Issue the request, attempting to read 'size' bytes */
result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
request, REQTYPE_DEVICE_TO_HOST, 0x0000,
- port_priv->bInterfaceNumber, buf, size, 300);
+ port_priv->bInterfaceNumber, buf, size,
+ USB_CTRL_GET_TIMEOUT);
/* Convert data into an array of integers */
for (i = 0; i < length; i++)
@@ -340,12 +341,14 @@ static int cp210x_set_config(struct usb_serial_port *port, u8 request,
result = usb_control_msg(serial->dev,
usb_sndctrlpipe(serial->dev, 0),
request, REQTYPE_HOST_TO_DEVICE, 0x0000,
- port_priv->bInterfaceNumber, buf, size, 300);
+ port_priv->bInterfaceNumber, buf, size,
+ USB_CTRL_SET_TIMEOUT);
} else {
result = usb_control_msg(serial->dev,
usb_sndctrlpipe(serial->dev, 0),
request, REQTYPE_HOST_TO_DEVICE, data[0],
- port_priv->bInterfaceNumber, NULL, 0, 300);
+ port_priv->bInterfaceNumber, NULL, 0,
+ USB_CTRL_SET_TIMEOUT);
}
kfree(buf);
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index ff8605b4b4be..02e7f2d32d52 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -75,7 +75,8 @@ struct ftdi_private {
unsigned long last_dtr_rts; /* saved modem control outputs */
struct async_icount icount;
wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */
- char prev_status, diff_status; /* Used for TIOCMIWAIT */
+ char prev_status; /* Used for TIOCMIWAIT */
+ bool dev_gone; /* Used to abort TIOCMIWAIT */
char transmit_empty; /* If transmitter is empty or not */
struct usb_serial_port *port;
__u16 interface; /* FT2232C, FT2232H or FT4232H port interface
@@ -1681,6 +1682,7 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port)
init_waitqueue_head(&priv->delta_msr_wait);
priv->flags = ASYNC_LOW_LATENCY;
+ priv->dev_gone = false;
if (quirk && quirk->port_probe)
quirk->port_probe(priv);
@@ -1839,6 +1841,9 @@ static int ftdi_sio_port_remove(struct usb_serial_port *port)
dbg("%s", __func__);
+ priv->dev_gone = true;
+ wake_up_interruptible_all(&priv->delta_msr_wait);
+
remove_sysfs_attrs(port);
kref_put(&priv->kref, ftdi_sio_priv_release);
@@ -1982,17 +1987,19 @@ static int ftdi_process_packet(struct tty_struct *tty,
N.B. packet may be processed more than once, but differences
are only processed once. */
status = packet[0] & FTDI_STATUS_B0_MASK;
- if (status & FTDI_RS0_CTS)
- priv->icount.cts++;
- if (status & FTDI_RS0_DSR)
- priv->icount.dsr++;
- if (status & FTDI_RS0_RI)
- priv->icount.rng++;
- if (status & FTDI_RS0_RLSD)
- priv->icount.dcd++;
if (status != priv->prev_status) {
- priv->diff_status |= status ^ priv->prev_status;
- wake_up_interruptible(&priv->delta_msr_wait);
+ char diff_status = status ^ priv->prev_status;
+
+ if (diff_status & FTDI_RS0_CTS)
+ priv->icount.cts++;
+ if (diff_status & FTDI_RS0_DSR)
+ priv->icount.dsr++;
+ if (diff_status & FTDI_RS0_RI)
+ priv->icount.rng++;
+ if (diff_status & FTDI_RS0_RLSD)
+ priv->icount.dcd++;
+
+ wake_up_interruptible_all(&priv->delta_msr_wait);
priv->prev_status = status;
}
@@ -2395,15 +2402,12 @@ static int ftdi_ioctl(struct tty_struct *tty,
*/
case TIOCMIWAIT:
cprev = priv->icount;
- while (1) {
+ while (!priv->dev_gone) {
interruptible_sleep_on(&priv->delta_msr_wait);
/* see if a signal did it */
if (signal_pending(current))
return -ERESTARTSYS;
cnow = priv->icount;
- if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
- cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
- return -EIO; /* no change => error */
if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) ||
@@ -2412,7 +2416,7 @@ static int ftdi_ioctl(struct tty_struct *tty,
}
cprev = cnow;
}
- /* not reached */
+ return -EIO;
break;
case TIOCSERGETLSR:
return get_lsr_info(port, (struct serial_struct __user *)arg);
diff --git a/drivers/usb/serial/metro-usb.c b/drivers/usb/serial/metro-usb.c
index 6e1622f2a297..08d16e8c002d 100644
--- a/drivers/usb/serial/metro-usb.c
+++ b/drivers/usb/serial/metro-usb.c
@@ -27,8 +27,8 @@
/* Product information. */
#define FOCUS_VENDOR_ID 0x0C2E
-#define FOCUS_PRODUCT_ID 0x0720
-#define FOCUS_PRODUCT_ID_UNI 0x0710
+#define FOCUS_PRODUCT_ID_BI 0x0720
+#define FOCUS_PRODUCT_ID_UNI 0x0700
#define METROUSB_SET_REQUEST_TYPE 0x40
#define METROUSB_SET_MODEM_CTRL_REQUEST 10
@@ -47,7 +47,7 @@ struct metrousb_private {
/* Device table list. */
static struct usb_device_id id_table[] = {
- { USB_DEVICE(FOCUS_VENDOR_ID, FOCUS_PRODUCT_ID) },
+ { USB_DEVICE(FOCUS_VENDOR_ID, FOCUS_PRODUCT_ID_BI) },
{ USB_DEVICE(FOCUS_VENDOR_ID, FOCUS_PRODUCT_ID_UNI) },
{ }, /* Terminating entry. */
};
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index 836cfa9a515f..f4465ccddc35 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -708,6 +708,7 @@ static const struct usb_device_id option_ids[] = {
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_FULLSPEED) },
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_FULLSPEED) },
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_HIGHSPEED) },
+ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED) },
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED3) },
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED4) },
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED5) },
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
index ff4a174fa5de..a1a9062954c4 100644
--- a/drivers/usb/serial/pl2303.c
+++ b/drivers/usb/serial/pl2303.c
@@ -420,7 +420,7 @@ static void pl2303_set_termios(struct tty_struct *tty,
control = priv->line_control;
if ((cflag & CBAUD) == B0)
priv->line_control &= ~(CONTROL_DTR | CONTROL_RTS);
- else
+ else if ((old_termios->c_cflag & CBAUD) == B0)
priv->line_control |= (CONTROL_DTR | CONTROL_RTS);
if (control != priv->line_control) {
control = priv->line_control;
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c
index f14465a83dd1..8c8bf806f6fa 100644
--- a/drivers/usb/serial/sierra.c
+++ b/drivers/usb/serial/sierra.c
@@ -221,7 +221,7 @@ static const struct sierra_iface_info typeB_interface_list = {
};
/* 'blacklist' of interfaces not served by this driver */
-static const u8 direct_ip_non_serial_ifaces[] = { 7, 8, 9, 10, 11 };
+static const u8 direct_ip_non_serial_ifaces[] = { 7, 8, 9, 10, 11, 19, 20 };
static const struct sierra_iface_info direct_ip_interface_blacklist = {
.infolen = ARRAY_SIZE(direct_ip_non_serial_ifaces),
.ifaceinfo = direct_ip_non_serial_ifaces,
@@ -298,6 +298,9 @@ static const struct usb_device_id id_table[] = {
/* Sierra Wireless HSPA Non-Composite Device */
{ USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6892, 0xFF, 0xFF, 0xFF)},
{ USB_DEVICE(0x1199, 0x6893) }, /* Sierra Wireless Device */
+ { USB_DEVICE(0x1199, 0x68A2), /* Sierra Wireless MC77xx in QMI mode */
+ .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist
+ },
{ USB_DEVICE(0x1199, 0x68A3), /* Sierra Wireless Direct IP modems */
.driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist
},
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index 69230f01056a..97355a15bbea 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -1059,6 +1059,12 @@ int usb_serial_probe(struct usb_interface *interface,
serial->attached = 1;
}
+ /* Avoid race with tty_open and serial_install by setting the
+ * disconnected flag and not clearing it until all ports have been
+ * registered.
+ */
+ serial->disconnected = 1;
+
if (get_free_serial(serial, num_ports, &minor) == NULL) {
dev_err(&interface->dev, "No more free serial devices\n");
goto probe_error;
@@ -1070,19 +1076,16 @@ int usb_serial_probe(struct usb_interface *interface,
port = serial->port[i];
dev_set_name(&port->dev, "ttyUSB%d", port->number);
dbg ("%s - registering %s", __func__, dev_name(&port->dev));
- port->dev_state = PORT_REGISTERING;
device_enable_async_suspend(&port->dev);
retval = device_add(&port->dev);
- if (retval) {
+ if (retval)
dev_err(&port->dev, "Error registering port device, "
"continuing\n");
- port->dev_state = PORT_UNREGISTERED;
- } else {
- port->dev_state = PORT_REGISTERED;
- }
}
+ serial->disconnected = 0;
+
usb_serial_console_init(debug, minor);
exit:
@@ -1124,22 +1127,8 @@ void usb_serial_disconnect(struct usb_interface *interface)
}
kill_traffic(port);
cancel_work_sync(&port->work);
- if (port->dev_state == PORT_REGISTERED) {
-
- /* Make sure the port is bound so that the
- * driver's port_remove method is called.
- */
- if (!port->dev.driver) {
- int rc;
-
- port->dev.driver =
- &serial->type->driver;
- rc = device_bind_driver(&port->dev);
- }
- port->dev_state = PORT_UNREGISTERING;
+ if (device_is_registered(&port->dev))
device_del(&port->dev);
- port->dev_state = PORT_UNREGISTERED;
- }
}
}
serial->type->disconnect(serial);
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c
index c18538e4a6db..2653e73db623 100644
--- a/drivers/usb/storage/usb.c
+++ b/drivers/usb/storage/usb.c
@@ -132,6 +132,35 @@ static struct us_unusual_dev for_dynamic_ids =
#undef COMPLIANT_DEV
#undef USUAL_DEV
+#ifdef CONFIG_LOCKDEP
+
+static struct lock_class_key us_interface_key[USB_MAXINTERFACES];
+
+static void us_set_lock_class(struct mutex *mutex,
+ struct usb_interface *intf)
+{
+ struct usb_device *udev = interface_to_usbdev(intf);
+ struct usb_host_config *config = udev->actconfig;
+ int i;
+
+ for (i = 0; i < config->desc.bNumInterfaces; i++) {
+ if (config->interface[i] == intf)
+ break;
+ }
+
+ BUG_ON(i == config->desc.bNumInterfaces);
+
+ lockdep_set_class(mutex, &us_interface_key[i]);
+}
+
+#else
+
+static void us_set_lock_class(struct mutex *mutex,
+ struct usb_interface *intf)
+{
+}
+
+#endif
#ifdef CONFIG_PM /* Minimal support for suspend and resume */
@@ -895,6 +924,7 @@ int usb_stor_probe1(struct us_data **pus,
*pus = us = host_to_us(host);
memset(us, 0, sizeof(struct us_data));
mutex_init(&(us->dev_mutex));
+ us_set_lock_class(&us->dev_mutex, intf);
init_completion(&us->cmnd_ready);
init_completion(&(us->notify));
init_waitqueue_head(&us->delay_wait);
diff --git a/drivers/uwb/hwa-rc.c b/drivers/uwb/hwa-rc.c
index 66797e9c5010..810c90ae2c55 100644
--- a/drivers/uwb/hwa-rc.c
+++ b/drivers/uwb/hwa-rc.c
@@ -645,7 +645,8 @@ void hwarc_neep_cb(struct urb *urb)
dev_err(dev, "NEEP: URB error %d\n", urb->status);
}
result = usb_submit_urb(urb, GFP_ATOMIC);
- if (result < 0) {
+ if (result < 0 && result != -ENODEV && result != -EPERM) {
+ /* ignoring unrecoverable errors */
dev_err(dev, "NEEP: Can't resubmit URB (%d) resetting device\n",
result);
goto error;
diff --git a/drivers/uwb/neh.c b/drivers/uwb/neh.c
index a269937be1b8..8cb71bb333c2 100644
--- a/drivers/uwb/neh.c
+++ b/drivers/uwb/neh.c
@@ -107,6 +107,7 @@ struct uwb_rc_neh {
u8 evt_type;
__le16 evt;
u8 context;
+ u8 completed;
uwb_rc_cmd_cb_f cb;
void *arg;
@@ -409,6 +410,7 @@ static void uwb_rc_neh_grok_event(struct uwb_rc *rc, struct uwb_rceb *rceb, size
struct device *dev = &rc->uwb_dev.dev;
struct uwb_rc_neh *neh;
struct uwb_rceb *notif;
+ unsigned long flags;
if (rceb->bEventContext == 0) {
notif = kmalloc(size, GFP_ATOMIC);
@@ -422,7 +424,11 @@ static void uwb_rc_neh_grok_event(struct uwb_rc *rc, struct uwb_rceb *rceb, size
} else {
neh = uwb_rc_neh_lookup(rc, rceb);
if (neh) {
- del_timer_sync(&neh->timer);
+ spin_lock_irqsave(&rc->neh_lock, flags);
+ /* to guard against a timeout */
+ neh->completed = 1;
+ del_timer(&neh->timer);
+ spin_unlock_irqrestore(&rc->neh_lock, flags);
uwb_rc_neh_cb(neh, rceb, size);
} else
dev_warn(dev, "event 0x%02x/%04x/%02x (%zu bytes): nobody cared\n",
@@ -568,6 +574,10 @@ static void uwb_rc_neh_timer(unsigned long arg)
unsigned long flags;
spin_lock_irqsave(&rc->neh_lock, flags);
+ if (neh->completed) {
+ spin_unlock_irqrestore(&rc->neh_lock, flags);
+ return;
+ }
if (neh->context)
__uwb_rc_neh_rm(rc, neh);
else
diff --git a/drivers/uwb/uwb-debug.c b/drivers/uwb/uwb-debug.c
index 2eecec0c13c9..6ec45beb7af5 100644
--- a/drivers/uwb/uwb-debug.c
+++ b/drivers/uwb/uwb-debug.c
@@ -159,13 +159,6 @@ static int cmd_ie_rm(struct uwb_rc *rc, struct uwb_dbg_cmd_ie *ie_to_rm)
return uwb_rc_ie_rm(rc, ie_to_rm->data[0]);
}
-static int command_open(struct inode *inode, struct file *file)
-{
- file->private_data = inode->i_private;
-
- return 0;
-}
-
static ssize_t command_write(struct file *file, const char __user *buf,
size_t len, loff_t *off)
{
@@ -206,7 +199,7 @@ static ssize_t command_write(struct file *file, const char __user *buf,
}
static const struct file_operations command_fops = {
- .open = command_open,
+ .open = simple_open,
.write = command_write,
.read = NULL,
.llseek = no_llseek,
diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
index f0da2c32fbde..1f21d2a1e528 100644
--- a/drivers/vhost/net.c
+++ b/drivers/vhost/net.c
@@ -238,7 +238,7 @@ static void handle_tx(struct vhost_net *net)
vq->heads[vq->upend_idx].len = len;
ubuf->callback = vhost_zerocopy_callback;
- ubuf->arg = vq->ubufs;
+ ubuf->ctx = vq->ubufs;
ubuf->desc = vq->upend_idx;
msg.msg_control = ubuf;
msg.msg_controllen = sizeof(ubuf);
diff --git a/drivers/vhost/test.c b/drivers/vhost/test.c
index fc9a1d75281f..3de00d9fae2e 100644
--- a/drivers/vhost/test.c
+++ b/drivers/vhost/test.c
@@ -155,7 +155,7 @@ static int vhost_test_release(struct inode *inode, struct file *f)
vhost_test_stop(n, &private);
vhost_test_flush(n);
- vhost_dev_cleanup(&n->dev);
+ vhost_dev_cleanup(&n->dev, false);
/* We do an extra flush before freeing memory,
* since jobs can re-queue themselves. */
vhost_test_flush(n);
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
index 947f00d8e091..51e4c1eeec4f 100644
--- a/drivers/vhost/vhost.c
+++ b/drivers/vhost/vhost.c
@@ -1598,10 +1598,9 @@ void vhost_ubuf_put_and_wait(struct vhost_ubuf_ref *ubufs)
kfree(ubufs);
}
-void vhost_zerocopy_callback(void *arg)
+void vhost_zerocopy_callback(struct ubuf_info *ubuf)
{
- struct ubuf_info *ubuf = arg;
- struct vhost_ubuf_ref *ubufs = ubuf->arg;
+ struct vhost_ubuf_ref *ubufs = ubuf->ctx;
struct vhost_virtqueue *vq = ubufs->vq;
/* set len = 1 to mark this desc buffers done DMA */
diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h
index 8dcf4cca6bf2..8de1fd5b8efb 100644
--- a/drivers/vhost/vhost.h
+++ b/drivers/vhost/vhost.h
@@ -188,7 +188,7 @@ bool vhost_enable_notify(struct vhost_dev *, struct vhost_virtqueue *);
int vhost_log_write(struct vhost_virtqueue *vq, struct vhost_log *log,
unsigned int log_num, u64 len);
-void vhost_zerocopy_callback(void *arg);
+void vhost_zerocopy_callback(struct ubuf_info *);
int vhost_zerocopy_signal_used(struct vhost_virtqueue *vq);
#define vq_err(vq, fmt, ...) do { \
diff --git a/drivers/video/au1100fb.c b/drivers/video/au1100fb.c
index befcbd8ef019..ffbce4525468 100644
--- a/drivers/video/au1100fb.c
+++ b/drivers/video/au1100fb.c
@@ -499,7 +499,8 @@ static int __devinit au1100fb_drv_probe(struct platform_device *dev)
au1100fb_fix.mmio_start = regs_res->start;
au1100fb_fix.mmio_len = resource_size(regs_res);
- if (!devm_request_mem_region(au1100fb_fix.mmio_start,
+ if (!devm_request_mem_region(&dev->dev,
+ au1100fb_fix.mmio_start,
au1100fb_fix.mmio_len,
DRIVER_NAME)) {
print_err("fail to lock memory region at 0x%08lx",
@@ -516,7 +517,7 @@ static int __devinit au1100fb_drv_probe(struct platform_device *dev)
fbdev->fb_len = fbdev->panel->xres * fbdev->panel->yres *
(fbdev->panel->bpp >> 3) * AU1100FB_NBR_VIDEO_BUFFERS;
- fbdev->fb_mem = dmam_alloc_coherent(&dev->dev, &dev->dev,
+ fbdev->fb_mem = dmam_alloc_coherent(&dev->dev,
PAGE_ALIGN(fbdev->fb_len),
&fbdev->fb_phys, GFP_KERNEL);
if (!fbdev->fb_mem) {
diff --git a/drivers/video/au1200fb.c b/drivers/video/au1200fb.c
index 3e9a773db09f..7ca79f02056e 100644
--- a/drivers/video/au1200fb.c
+++ b/drivers/video/au1200fb.c
@@ -1724,7 +1724,7 @@ static int __devinit au1200fb_drv_probe(struct platform_device *dev)
/* Allocate the framebuffer to the maximum screen size */
fbdev->fb_len = (win->w[plane].xres * win->w[plane].yres * bpp) / 8;
- fbdev->fb_mem = dmam_alloc_noncoherent(&dev->dev, &dev->dev,
+ fbdev->fb_mem = dmam_alloc_noncoherent(&dev->dev,
PAGE_ALIGN(fbdev->fb_len),
&fbdev->fb_phys, GFP_KERNEL);
if (!fbdev->fb_mem) {
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index 7ed9991fa747..af16884491ed 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -245,6 +245,12 @@ config BACKLIGHT_DA903X
If you have a LCD backlight connected to the WLED output of DA9030
or DA9034 WLED output, say Y here to enable this driver.
+config BACKLIGHT_DA9052
+ tristate "Dialog DA9052/DA9053 WLED"
+ depends on PMIC_DA9052
+ help
+ Enable the Backlight Driver for DA9052-BC and DA9053-AA/Bx PMICs.
+
config BACKLIGHT_MAX8925
tristate "Backlight driver for MAX8925"
depends on MFD_MAX8925
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index 8071eb656147..36855ae887d6 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -29,6 +29,7 @@ obj-$(CONFIG_BACKLIGHT_PROGEAR) += progear_bl.o
obj-$(CONFIG_BACKLIGHT_CARILLO_RANCH) += cr_bllcd.o
obj-$(CONFIG_BACKLIGHT_PWM) += pwm_bl.o
obj-$(CONFIG_BACKLIGHT_DA903X) += da903x_bl.o
+obj-$(CONFIG_BACKLIGHT_DA9052) += da9052_bl.o
obj-$(CONFIG_BACKLIGHT_MAX8925) += max8925_bl.o
obj-$(CONFIG_BACKLIGHT_APPLE) += apple_bl.o
obj-$(CONFIG_BACKLIGHT_TOSA) += tosa_bl.o
diff --git a/drivers/video/backlight/da9052_bl.c b/drivers/video/backlight/da9052_bl.c
new file mode 100644
index 000000000000..b628d68f5162
--- /dev/null
+++ b/drivers/video/backlight/da9052_bl.c
@@ -0,0 +1,187 @@
+/*
+ * Backlight Driver for Dialog DA9052 PMICs
+ *
+ * Copyright(c) 2012 Dialog Semiconductor Ltd.
+ *
+ * Author: David Dajun Chen <dchen@diasemi.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.
+ *
+ */
+
+#include <linux/backlight.h>
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include <linux/mfd/da9052/da9052.h>
+#include <linux/mfd/da9052/reg.h>
+
+#define DA9052_MAX_BRIGHTNESS 0xFF
+
+enum {
+ DA9052_WLEDS_OFF,
+ DA9052_WLEDS_ON,
+};
+
+enum {
+ DA9052_TYPE_WLED1,
+ DA9052_TYPE_WLED2,
+ DA9052_TYPE_WLED3,
+};
+
+static unsigned char wled_bank[] = {
+ DA9052_LED1_CONF_REG,
+ DA9052_LED2_CONF_REG,
+ DA9052_LED3_CONF_REG,
+};
+
+struct da9052_bl {
+ struct da9052 *da9052;
+ uint brightness;
+ uint state;
+ uint led_reg;
+};
+
+static int da9052_adjust_wled_brightness(struct da9052_bl *wleds)
+{
+ unsigned char boost_en;
+ unsigned char i_sink;
+ int ret;
+
+ boost_en = 0x3F;
+ i_sink = 0xFF;
+ if (wleds->state == DA9052_WLEDS_OFF) {
+ boost_en = 0x00;
+ i_sink = 0x00;
+ }
+
+ ret = da9052_reg_write(wleds->da9052, DA9052_BOOST_REG, boost_en);
+ if (ret < 0)
+ return ret;
+
+ ret = da9052_reg_write(wleds->da9052, DA9052_LED_CONT_REG, i_sink);
+ if (ret < 0)
+ return ret;
+
+ ret = da9052_reg_write(wleds->da9052, wled_bank[wleds->led_reg], 0x0);
+ if (ret < 0)
+ return ret;
+
+ msleep(10);
+
+ if (wleds->brightness) {
+ ret = da9052_reg_write(wleds->da9052, wled_bank[wleds->led_reg],
+ wleds->brightness);
+ if (ret < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int da9052_backlight_update_status(struct backlight_device *bl)
+{
+ int brightness = bl->props.brightness;
+ struct da9052_bl *wleds = bl_get_data(bl);
+
+ wleds->brightness = brightness;
+ wleds->state = DA9052_WLEDS_ON;
+
+ return da9052_adjust_wled_brightness(wleds);
+}
+
+static int da9052_backlight_get_brightness(struct backlight_device *bl)
+{
+ struct da9052_bl *wleds = bl_get_data(bl);
+
+ return wleds->brightness;
+}
+
+static const struct backlight_ops da9052_backlight_ops = {
+ .update_status = da9052_backlight_update_status,
+ .get_brightness = da9052_backlight_get_brightness,
+};
+
+static int da9052_backlight_probe(struct platform_device *pdev)
+{
+ struct backlight_device *bl;
+ struct backlight_properties props;
+ struct da9052_bl *wleds;
+
+ wleds = devm_kzalloc(&pdev->dev, sizeof(struct da9052_bl), GFP_KERNEL);
+ if (!wleds)
+ return -ENOMEM;
+
+ wleds->da9052 = dev_get_drvdata(pdev->dev.parent);
+ wleds->brightness = 0;
+ wleds->led_reg = platform_get_device_id(pdev)->driver_data;
+ wleds->state = DA9052_WLEDS_OFF;
+
+ props.type = BACKLIGHT_RAW;
+ props.max_brightness = DA9052_MAX_BRIGHTNESS;
+
+ bl = backlight_device_register(pdev->name, wleds->da9052->dev, wleds,
+ &da9052_backlight_ops, &props);
+ if (IS_ERR(bl)) {
+ dev_err(&pdev->dev, "Failed to register backlight\n");
+ devm_kfree(&pdev->dev, wleds);
+ return PTR_ERR(bl);
+ }
+
+ bl->props.max_brightness = DA9052_MAX_BRIGHTNESS;
+ bl->props.brightness = 0;
+ platform_set_drvdata(pdev, bl);
+
+ return da9052_adjust_wled_brightness(wleds);
+}
+
+static int da9052_backlight_remove(struct platform_device *pdev)
+{
+ struct backlight_device *bl = platform_get_drvdata(pdev);
+ struct da9052_bl *wleds = bl_get_data(bl);
+
+ wleds->brightness = 0;
+ wleds->state = DA9052_WLEDS_OFF;
+ da9052_adjust_wled_brightness(wleds);
+ backlight_device_unregister(bl);
+ devm_kfree(&pdev->dev, wleds);
+
+ return 0;
+}
+
+static struct platform_device_id da9052_wled_ids[] = {
+ {
+ .name = "da9052-wled1",
+ .driver_data = DA9052_TYPE_WLED1,
+ },
+ {
+ .name = "da9052-wled2",
+ .driver_data = DA9052_TYPE_WLED2,
+ },
+ {
+ .name = "da9052-wled3",
+ .driver_data = DA9052_TYPE_WLED3,
+ },
+};
+
+static struct platform_driver da9052_wled_driver = {
+ .probe = da9052_backlight_probe,
+ .remove = da9052_backlight_remove,
+ .id_table = da9052_wled_ids,
+ .driver = {
+ .name = "da9052-wled",
+ .owner = THIS_MODULE,
+ },
+};
+
+module_platform_driver(da9052_wled_driver);
+
+MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>");
+MODULE_DESCRIPTION("Backlight driver for DA9052 PMIC");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:da9052-backlight");
diff --git a/drivers/video/backlight/locomolcd.c b/drivers/video/backlight/locomolcd.c
index be20b5cbe26c..3a6d5419e3e3 100644
--- a/drivers/video/backlight/locomolcd.c
+++ b/drivers/video/backlight/locomolcd.c
@@ -229,14 +229,7 @@ static struct locomo_driver poodle_lcd_driver = {
static int __init locomolcd_init(void)
{
- int ret = locomo_driver_register(&poodle_lcd_driver);
- if (ret)
- return ret;
-
-#ifdef CONFIG_SA1100_COLLIE
- sa1100fb_lcd_power = locomolcd_power;
-#endif
- return 0;
+ return locomo_driver_register(&poodle_lcd_driver);
}
static void __exit locomolcd_exit(void)
diff --git a/drivers/video/kyro/STG4000Reg.h b/drivers/video/kyro/STG4000Reg.h
index 5d6269882589..50f4670e9252 100644
--- a/drivers/video/kyro/STG4000Reg.h
+++ b/drivers/video/kyro/STG4000Reg.h
@@ -73,210 +73,210 @@ typedef enum _OVRL_PIX_FORMAT {
/* Register Table */
typedef struct {
/* 0h */
- volatile unsigned long Thread0Enable; /* 0x0000 */
- volatile unsigned long Thread1Enable; /* 0x0004 */
- volatile unsigned long Thread0Recover; /* 0x0008 */
- volatile unsigned long Thread1Recover; /* 0x000C */
- volatile unsigned long Thread0Step; /* 0x0010 */
- volatile unsigned long Thread1Step; /* 0x0014 */
- volatile unsigned long VideoInStatus; /* 0x0018 */
- volatile unsigned long Core2InSignStart; /* 0x001C */
- volatile unsigned long Core1ResetVector; /* 0x0020 */
- volatile unsigned long Core1ROMOffset; /* 0x0024 */
- volatile unsigned long Core1ArbiterPriority; /* 0x0028 */
- volatile unsigned long VideoInControl; /* 0x002C */
- volatile unsigned long VideoInReg0CtrlA; /* 0x0030 */
- volatile unsigned long VideoInReg0CtrlB; /* 0x0034 */
- volatile unsigned long VideoInReg1CtrlA; /* 0x0038 */
- volatile unsigned long VideoInReg1CtrlB; /* 0x003C */
- volatile unsigned long Thread0Kicker; /* 0x0040 */
- volatile unsigned long Core2InputSign; /* 0x0044 */
- volatile unsigned long Thread0ProgCtr; /* 0x0048 */
- volatile unsigned long Thread1ProgCtr; /* 0x004C */
- volatile unsigned long Thread1Kicker; /* 0x0050 */
- volatile unsigned long GPRegister1; /* 0x0054 */
- volatile unsigned long GPRegister2; /* 0x0058 */
- volatile unsigned long GPRegister3; /* 0x005C */
- volatile unsigned long GPRegister4; /* 0x0060 */
- volatile unsigned long SerialIntA; /* 0x0064 */
-
- volatile unsigned long Fill0[6]; /* GAP 0x0068 - 0x007C */
-
- volatile unsigned long SoftwareReset; /* 0x0080 */
- volatile unsigned long SerialIntB; /* 0x0084 */
-
- volatile unsigned long Fill1[37]; /* GAP 0x0088 - 0x011C */
-
- volatile unsigned long ROMELQV; /* 0x011C */
- volatile unsigned long WLWH; /* 0x0120 */
- volatile unsigned long ROMELWL; /* 0x0124 */
-
- volatile unsigned long dwFill_1; /* GAP 0x0128 */
-
- volatile unsigned long IntStatus; /* 0x012C */
- volatile unsigned long IntMask; /* 0x0130 */
- volatile unsigned long IntClear; /* 0x0134 */
-
- volatile unsigned long Fill2[6]; /* GAP 0x0138 - 0x014C */
-
- volatile unsigned long ROMGPIOA; /* 0x0150 */
- volatile unsigned long ROMGPIOB; /* 0x0154 */
- volatile unsigned long ROMGPIOC; /* 0x0158 */
- volatile unsigned long ROMGPIOD; /* 0x015C */
-
- volatile unsigned long Fill3[2]; /* GAP 0x0160 - 0x0168 */
-
- volatile unsigned long AGPIntID; /* 0x0168 */
- volatile unsigned long AGPIntClassCode; /* 0x016C */
- volatile unsigned long AGPIntBIST; /* 0x0170 */
- volatile unsigned long AGPIntSSID; /* 0x0174 */
- volatile unsigned long AGPIntPMCSR; /* 0x0178 */
- volatile unsigned long VGAFrameBufBase; /* 0x017C */
- volatile unsigned long VGANotify; /* 0x0180 */
- volatile unsigned long DACPLLMode; /* 0x0184 */
- volatile unsigned long Core1VideoClockDiv; /* 0x0188 */
- volatile unsigned long AGPIntStat; /* 0x018C */
+ volatile u32 Thread0Enable; /* 0x0000 */
+ volatile u32 Thread1Enable; /* 0x0004 */
+ volatile u32 Thread0Recover; /* 0x0008 */
+ volatile u32 Thread1Recover; /* 0x000C */
+ volatile u32 Thread0Step; /* 0x0010 */
+ volatile u32 Thread1Step; /* 0x0014 */
+ volatile u32 VideoInStatus; /* 0x0018 */
+ volatile u32 Core2InSignStart; /* 0x001C */
+ volatile u32 Core1ResetVector; /* 0x0020 */
+ volatile u32 Core1ROMOffset; /* 0x0024 */
+ volatile u32 Core1ArbiterPriority; /* 0x0028 */
+ volatile u32 VideoInControl; /* 0x002C */
+ volatile u32 VideoInReg0CtrlA; /* 0x0030 */
+ volatile u32 VideoInReg0CtrlB; /* 0x0034 */
+ volatile u32 VideoInReg1CtrlA; /* 0x0038 */
+ volatile u32 VideoInReg1CtrlB; /* 0x003C */
+ volatile u32 Thread0Kicker; /* 0x0040 */
+ volatile u32 Core2InputSign; /* 0x0044 */
+ volatile u32 Thread0ProgCtr; /* 0x0048 */
+ volatile u32 Thread1ProgCtr; /* 0x004C */
+ volatile u32 Thread1Kicker; /* 0x0050 */
+ volatile u32 GPRegister1; /* 0x0054 */
+ volatile u32 GPRegister2; /* 0x0058 */
+ volatile u32 GPRegister3; /* 0x005C */
+ volatile u32 GPRegister4; /* 0x0060 */
+ volatile u32 SerialIntA; /* 0x0064 */
+
+ volatile u32 Fill0[6]; /* GAP 0x0068 - 0x007C */
+
+ volatile u32 SoftwareReset; /* 0x0080 */
+ volatile u32 SerialIntB; /* 0x0084 */
+
+ volatile u32 Fill1[37]; /* GAP 0x0088 - 0x011C */
+
+ volatile u32 ROMELQV; /* 0x011C */
+ volatile u32 WLWH; /* 0x0120 */
+ volatile u32 ROMELWL; /* 0x0124 */
+
+ volatile u32 dwFill_1; /* GAP 0x0128 */
+
+ volatile u32 IntStatus; /* 0x012C */
+ volatile u32 IntMask; /* 0x0130 */
+ volatile u32 IntClear; /* 0x0134 */
+
+ volatile u32 Fill2[6]; /* GAP 0x0138 - 0x014C */
+
+ volatile u32 ROMGPIOA; /* 0x0150 */
+ volatile u32 ROMGPIOB; /* 0x0154 */
+ volatile u32 ROMGPIOC; /* 0x0158 */
+ volatile u32 ROMGPIOD; /* 0x015C */
+
+ volatile u32 Fill3[2]; /* GAP 0x0160 - 0x0168 */
+
+ volatile u32 AGPIntID; /* 0x0168 */
+ volatile u32 AGPIntClassCode; /* 0x016C */
+ volatile u32 AGPIntBIST; /* 0x0170 */
+ volatile u32 AGPIntSSID; /* 0x0174 */
+ volatile u32 AGPIntPMCSR; /* 0x0178 */
+ volatile u32 VGAFrameBufBase; /* 0x017C */
+ volatile u32 VGANotify; /* 0x0180 */
+ volatile u32 DACPLLMode; /* 0x0184 */
+ volatile u32 Core1VideoClockDiv; /* 0x0188 */
+ volatile u32 AGPIntStat; /* 0x018C */
/*
- volatile unsigned long Fill4[0x0400/4 - 0x0190/4]; //GAP 0x0190 - 0x0400
- volatile unsigned long Fill5[0x05FC/4 - 0x0400/4]; //GAP 0x0400 - 0x05FC Fog Table
- volatile unsigned long Fill6[0x0604/4 - 0x0600/4]; //GAP 0x0600 - 0x0604
- volatile unsigned long Fill7[0x0680/4 - 0x0608/4]; //GAP 0x0608 - 0x0680
- volatile unsigned long Fill8[0x07FC/4 - 0x0684/4]; //GAP 0x0684 - 0x07FC
+ volatile u32 Fill4[0x0400/4 - 0x0190/4]; //GAP 0x0190 - 0x0400
+ volatile u32 Fill5[0x05FC/4 - 0x0400/4]; //GAP 0x0400 - 0x05FC Fog Table
+ volatile u32 Fill6[0x0604/4 - 0x0600/4]; //GAP 0x0600 - 0x0604
+ volatile u32 Fill7[0x0680/4 - 0x0608/4]; //GAP 0x0608 - 0x0680
+ volatile u32 Fill8[0x07FC/4 - 0x0684/4]; //GAP 0x0684 - 0x07FC
*/
- volatile unsigned long Fill4[412]; /* 0x0190 - 0x07FC */
-
- volatile unsigned long TACtrlStreamBase; /* 0x0800 */
- volatile unsigned long TAObjDataBase; /* 0x0804 */
- volatile unsigned long TAPtrDataBase; /* 0x0808 */
- volatile unsigned long TARegionDataBase; /* 0x080C */
- volatile unsigned long TATailPtrBase; /* 0x0810 */
- volatile unsigned long TAPtrRegionSize; /* 0x0814 */
- volatile unsigned long TAConfiguration; /* 0x0818 */
- volatile unsigned long TAObjDataStartAddr; /* 0x081C */
- volatile unsigned long TAObjDataEndAddr; /* 0x0820 */
- volatile unsigned long TAXScreenClip; /* 0x0824 */
- volatile unsigned long TAYScreenClip; /* 0x0828 */
- volatile unsigned long TARHWClamp; /* 0x082C */
- volatile unsigned long TARHWCompare; /* 0x0830 */
- volatile unsigned long TAStart; /* 0x0834 */
- volatile unsigned long TAObjReStart; /* 0x0838 */
- volatile unsigned long TAPtrReStart; /* 0x083C */
- volatile unsigned long TAStatus1; /* 0x0840 */
- volatile unsigned long TAStatus2; /* 0x0844 */
- volatile unsigned long TAIntStatus; /* 0x0848 */
- volatile unsigned long TAIntMask; /* 0x084C */
-
- volatile unsigned long Fill5[235]; /* GAP 0x0850 - 0x0BF8 */
-
- volatile unsigned long TextureAddrThresh; /* 0x0BFC */
- volatile unsigned long Core1Translation; /* 0x0C00 */
- volatile unsigned long TextureAddrReMap; /* 0x0C04 */
- volatile unsigned long RenderOutAGPRemap; /* 0x0C08 */
- volatile unsigned long _3DRegionReadTrans; /* 0x0C0C */
- volatile unsigned long _3DPtrReadTrans; /* 0x0C10 */
- volatile unsigned long _3DParamReadTrans; /* 0x0C14 */
- volatile unsigned long _3DRegionReadThresh; /* 0x0C18 */
- volatile unsigned long _3DPtrReadThresh; /* 0x0C1C */
- volatile unsigned long _3DParamReadThresh; /* 0x0C20 */
- volatile unsigned long _3DRegionReadAGPRemap; /* 0x0C24 */
- volatile unsigned long _3DPtrReadAGPRemap; /* 0x0C28 */
- volatile unsigned long _3DParamReadAGPRemap; /* 0x0C2C */
- volatile unsigned long ZBufferAGPRemap; /* 0x0C30 */
- volatile unsigned long TAIndexAGPRemap; /* 0x0C34 */
- volatile unsigned long TAVertexAGPRemap; /* 0x0C38 */
- volatile unsigned long TAUVAddrTrans; /* 0x0C3C */
- volatile unsigned long TATailPtrCacheTrans; /* 0x0C40 */
- volatile unsigned long TAParamWriteTrans; /* 0x0C44 */
- volatile unsigned long TAPtrWriteTrans; /* 0x0C48 */
- volatile unsigned long TAParamWriteThresh; /* 0x0C4C */
- volatile unsigned long TAPtrWriteThresh; /* 0x0C50 */
- volatile unsigned long TATailPtrCacheAGPRe; /* 0x0C54 */
- volatile unsigned long TAParamWriteAGPRe; /* 0x0C58 */
- volatile unsigned long TAPtrWriteAGPRe; /* 0x0C5C */
- volatile unsigned long SDRAMArbiterConf; /* 0x0C60 */
- volatile unsigned long SDRAMConf0; /* 0x0C64 */
- volatile unsigned long SDRAMConf1; /* 0x0C68 */
- volatile unsigned long SDRAMConf2; /* 0x0C6C */
- volatile unsigned long SDRAMRefresh; /* 0x0C70 */
- volatile unsigned long SDRAMPowerStat; /* 0x0C74 */
-
- volatile unsigned long Fill6[2]; /* GAP 0x0C78 - 0x0C7C */
-
- volatile unsigned long RAMBistData; /* 0x0C80 */
- volatile unsigned long RAMBistCtrl; /* 0x0C84 */
- volatile unsigned long FIFOBistKey; /* 0x0C88 */
- volatile unsigned long RAMBistResult; /* 0x0C8C */
- volatile unsigned long FIFOBistResult; /* 0x0C90 */
+ volatile u32 Fill4[412]; /* 0x0190 - 0x07FC */
+
+ volatile u32 TACtrlStreamBase; /* 0x0800 */
+ volatile u32 TAObjDataBase; /* 0x0804 */
+ volatile u32 TAPtrDataBase; /* 0x0808 */
+ volatile u32 TARegionDataBase; /* 0x080C */
+ volatile u32 TATailPtrBase; /* 0x0810 */
+ volatile u32 TAPtrRegionSize; /* 0x0814 */
+ volatile u32 TAConfiguration; /* 0x0818 */
+ volatile u32 TAObjDataStartAddr; /* 0x081C */
+ volatile u32 TAObjDataEndAddr; /* 0x0820 */
+ volatile u32 TAXScreenClip; /* 0x0824 */
+ volatile u32 TAYScreenClip; /* 0x0828 */
+ volatile u32 TARHWClamp; /* 0x082C */
+ volatile u32 TARHWCompare; /* 0x0830 */
+ volatile u32 TAStart; /* 0x0834 */
+ volatile u32 TAObjReStart; /* 0x0838 */
+ volatile u32 TAPtrReStart; /* 0x083C */
+ volatile u32 TAStatus1; /* 0x0840 */
+ volatile u32 TAStatus2; /* 0x0844 */
+ volatile u32 TAIntStatus; /* 0x0848 */
+ volatile u32 TAIntMask; /* 0x084C */
+
+ volatile u32 Fill5[235]; /* GAP 0x0850 - 0x0BF8 */
+
+ volatile u32 TextureAddrThresh; /* 0x0BFC */
+ volatile u32 Core1Translation; /* 0x0C00 */
+ volatile u32 TextureAddrReMap; /* 0x0C04 */
+ volatile u32 RenderOutAGPRemap; /* 0x0C08 */
+ volatile u32 _3DRegionReadTrans; /* 0x0C0C */
+ volatile u32 _3DPtrReadTrans; /* 0x0C10 */
+ volatile u32 _3DParamReadTrans; /* 0x0C14 */
+ volatile u32 _3DRegionReadThresh; /* 0x0C18 */
+ volatile u32 _3DPtrReadThresh; /* 0x0C1C */
+ volatile u32 _3DParamReadThresh; /* 0x0C20 */
+ volatile u32 _3DRegionReadAGPRemap; /* 0x0C24 */
+ volatile u32 _3DPtrReadAGPRemap; /* 0x0C28 */
+ volatile u32 _3DParamReadAGPRemap; /* 0x0C2C */
+ volatile u32 ZBufferAGPRemap; /* 0x0C30 */
+ volatile u32 TAIndexAGPRemap; /* 0x0C34 */
+ volatile u32 TAVertexAGPRemap; /* 0x0C38 */
+ volatile u32 TAUVAddrTrans; /* 0x0C3C */
+ volatile u32 TATailPtrCacheTrans; /* 0x0C40 */
+ volatile u32 TAParamWriteTrans; /* 0x0C44 */
+ volatile u32 TAPtrWriteTrans; /* 0x0C48 */
+ volatile u32 TAParamWriteThresh; /* 0x0C4C */
+ volatile u32 TAPtrWriteThresh; /* 0x0C50 */
+ volatile u32 TATailPtrCacheAGPRe; /* 0x0C54 */
+ volatile u32 TAParamWriteAGPRe; /* 0x0C58 */
+ volatile u32 TAPtrWriteAGPRe; /* 0x0C5C */
+ volatile u32 SDRAMArbiterConf; /* 0x0C60 */
+ volatile u32 SDRAMConf0; /* 0x0C64 */
+ volatile u32 SDRAMConf1; /* 0x0C68 */
+ volatile u32 SDRAMConf2; /* 0x0C6C */
+ volatile u32 SDRAMRefresh; /* 0x0C70 */
+ volatile u32 SDRAMPowerStat; /* 0x0C74 */
+
+ volatile u32 Fill6[2]; /* GAP 0x0C78 - 0x0C7C */
+
+ volatile u32 RAMBistData; /* 0x0C80 */
+ volatile u32 RAMBistCtrl; /* 0x0C84 */
+ volatile u32 FIFOBistKey; /* 0x0C88 */
+ volatile u32 RAMBistResult; /* 0x0C8C */
+ volatile u32 FIFOBistResult; /* 0x0C90 */
/*
- volatile unsigned long Fill11[0x0CBC/4 - 0x0C94/4]; //GAP 0x0C94 - 0x0CBC
- volatile unsigned long Fill12[0x0CD0/4 - 0x0CC0/4]; //GAP 0x0CC0 - 0x0CD0 3DRegisters
+ volatile u32 Fill11[0x0CBC/4 - 0x0C94/4]; //GAP 0x0C94 - 0x0CBC
+ volatile u32 Fill12[0x0CD0/4 - 0x0CC0/4]; //GAP 0x0CC0 - 0x0CD0 3DRegisters
*/
- volatile unsigned long Fill7[16]; /* 0x0c94 - 0x0cd0 */
+ volatile u32 Fill7[16]; /* 0x0c94 - 0x0cd0 */
- volatile unsigned long SDRAMAddrSign; /* 0x0CD4 */
- volatile unsigned long SDRAMDataSign; /* 0x0CD8 */
- volatile unsigned long SDRAMSignConf; /* 0x0CDC */
+ volatile u32 SDRAMAddrSign; /* 0x0CD4 */
+ volatile u32 SDRAMDataSign; /* 0x0CD8 */
+ volatile u32 SDRAMSignConf; /* 0x0CDC */
/* DWFILL; //GAP 0x0CE0 */
- volatile unsigned long dwFill_2;
-
- volatile unsigned long ISPSignature; /* 0x0CE4 */
-
- volatile unsigned long Fill8[454]; /*GAP 0x0CE8 - 0x13FC */
-
- volatile unsigned long DACPrimAddress; /* 0x1400 */
- volatile unsigned long DACPrimSize; /* 0x1404 */
- volatile unsigned long DACCursorAddr; /* 0x1408 */
- volatile unsigned long DACCursorCtrl; /* 0x140C */
- volatile unsigned long DACOverlayAddr; /* 0x1410 */
- volatile unsigned long DACOverlayUAddr; /* 0x1414 */
- volatile unsigned long DACOverlayVAddr; /* 0x1418 */
- volatile unsigned long DACOverlaySize; /* 0x141C */
- volatile unsigned long DACOverlayVtDec; /* 0x1420 */
-
- volatile unsigned long Fill9[9]; /* GAP 0x1424 - 0x1444 */
-
- volatile unsigned long DACVerticalScal; /* 0x1448 */
- volatile unsigned long DACPixelFormat; /* 0x144C */
- volatile unsigned long DACHorizontalScal; /* 0x1450 */
- volatile unsigned long DACVidWinStart; /* 0x1454 */
- volatile unsigned long DACVidWinEnd; /* 0x1458 */
- volatile unsigned long DACBlendCtrl; /* 0x145C */
- volatile unsigned long DACHorTim1; /* 0x1460 */
- volatile unsigned long DACHorTim2; /* 0x1464 */
- volatile unsigned long DACHorTim3; /* 0x1468 */
- volatile unsigned long DACVerTim1; /* 0x146C */
- volatile unsigned long DACVerTim2; /* 0x1470 */
- volatile unsigned long DACVerTim3; /* 0x1474 */
- volatile unsigned long DACBorderColor; /* 0x1478 */
- volatile unsigned long DACSyncCtrl; /* 0x147C */
- volatile unsigned long DACStreamCtrl; /* 0x1480 */
- volatile unsigned long DACLUTAddress; /* 0x1484 */
- volatile unsigned long DACLUTData; /* 0x1488 */
- volatile unsigned long DACBurstCtrl; /* 0x148C */
- volatile unsigned long DACCrcTrigger; /* 0x1490 */
- volatile unsigned long DACCrcDone; /* 0x1494 */
- volatile unsigned long DACCrcResult1; /* 0x1498 */
- volatile unsigned long DACCrcResult2; /* 0x149C */
- volatile unsigned long DACLinecount; /* 0x14A0 */
-
- volatile unsigned long Fill10[151]; /*GAP 0x14A4 - 0x16FC */
-
- volatile unsigned long DigVidPortCtrl; /* 0x1700 */
- volatile unsigned long DigVidPortStat; /* 0x1704 */
+ volatile u32 dwFill_2;
+
+ volatile u32 ISPSignature; /* 0x0CE4 */
+
+ volatile u32 Fill8[454]; /*GAP 0x0CE8 - 0x13FC */
+
+ volatile u32 DACPrimAddress; /* 0x1400 */
+ volatile u32 DACPrimSize; /* 0x1404 */
+ volatile u32 DACCursorAddr; /* 0x1408 */
+ volatile u32 DACCursorCtrl; /* 0x140C */
+ volatile u32 DACOverlayAddr; /* 0x1410 */
+ volatile u32 DACOverlayUAddr; /* 0x1414 */
+ volatile u32 DACOverlayVAddr; /* 0x1418 */
+ volatile u32 DACOverlaySize; /* 0x141C */
+ volatile u32 DACOverlayVtDec; /* 0x1420 */
+
+ volatile u32 Fill9[9]; /* GAP 0x1424 - 0x1444 */
+
+ volatile u32 DACVerticalScal; /* 0x1448 */
+ volatile u32 DACPixelFormat; /* 0x144C */
+ volatile u32 DACHorizontalScal; /* 0x1450 */
+ volatile u32 DACVidWinStart; /* 0x1454 */
+ volatile u32 DACVidWinEnd; /* 0x1458 */
+ volatile u32 DACBlendCtrl; /* 0x145C */
+ volatile u32 DACHorTim1; /* 0x1460 */
+ volatile u32 DACHorTim2; /* 0x1464 */
+ volatile u32 DACHorTim3; /* 0x1468 */
+ volatile u32 DACVerTim1; /* 0x146C */
+ volatile u32 DACVerTim2; /* 0x1470 */
+ volatile u32 DACVerTim3; /* 0x1474 */
+ volatile u32 DACBorderColor; /* 0x1478 */
+ volatile u32 DACSyncCtrl; /* 0x147C */
+ volatile u32 DACStreamCtrl; /* 0x1480 */
+ volatile u32 DACLUTAddress; /* 0x1484 */
+ volatile u32 DACLUTData; /* 0x1488 */
+ volatile u32 DACBurstCtrl; /* 0x148C */
+ volatile u32 DACCrcTrigger; /* 0x1490 */
+ volatile u32 DACCrcDone; /* 0x1494 */
+ volatile u32 DACCrcResult1; /* 0x1498 */
+ volatile u32 DACCrcResult2; /* 0x149C */
+ volatile u32 DACLinecount; /* 0x14A0 */
+
+ volatile u32 Fill10[151]; /*GAP 0x14A4 - 0x16FC */
+
+ volatile u32 DigVidPortCtrl; /* 0x1700 */
+ volatile u32 DigVidPortStat; /* 0x1704 */
/*
- volatile unsigned long Fill11[0x1FFC/4 - 0x1708/4]; //GAP 0x1708 - 0x1FFC
- volatile unsigned long Fill17[0x3000/4 - 0x2FFC/4]; //GAP 0x2000 - 0x2FFC ALUT
+ volatile u32 Fill11[0x1FFC/4 - 0x1708/4]; //GAP 0x1708 - 0x1FFC
+ volatile u32 Fill17[0x3000/4 - 0x2FFC/4]; //GAP 0x2000 - 0x2FFC ALUT
*/
- volatile unsigned long Fill11[1598];
+ volatile u32 Fill11[1598];
/* DWFILL; //GAP 0x3000 ALUT 256MB offset */
- volatile unsigned long Fill_3;
+ volatile u32 Fill_3;
} STG4000REG;
diff --git a/drivers/video/msm/mddi.c b/drivers/video/msm/mddi.c
index 4527cbf0a4ec..b061d709bc44 100644
--- a/drivers/video/msm/mddi.c
+++ b/drivers/video/msm/mddi.c
@@ -420,7 +420,7 @@ static void mddi_resume(struct msm_mddi_client_data *cdata)
mddi_set_auto_hibernate(&mddi->client_data, 1);
}
-static int __init mddi_get_client_caps(struct mddi_info *mddi)
+static int __devinit mddi_get_client_caps(struct mddi_info *mddi)
{
int i, j;
@@ -622,9 +622,9 @@ uint32_t mddi_remote_read(struct msm_mddi_client_data *cdata, uint32_t reg)
static struct mddi_info mddi_info[2];
-static int __init mddi_clk_setup(struct platform_device *pdev,
- struct mddi_info *mddi,
- unsigned long clk_rate)
+static int __devinit mddi_clk_setup(struct platform_device *pdev,
+ struct mddi_info *mddi,
+ unsigned long clk_rate)
{
int ret;
diff --git a/drivers/video/uvesafb.c b/drivers/video/uvesafb.c
index 260cca7ddb41..26e83d7fdd6f 100644
--- a/drivers/video/uvesafb.c
+++ b/drivers/video/uvesafb.c
@@ -815,8 +815,15 @@ static int __devinit uvesafb_vbe_init(struct fb_info *info)
par->pmi_setpal = pmi_setpal;
par->ypan = ypan;
- if (par->pmi_setpal || par->ypan)
- uvesafb_vbe_getpmi(task, par);
+ if (par->pmi_setpal || par->ypan) {
+ if (__supported_pte_mask & _PAGE_NX) {
+ par->pmi_setpal = par->ypan = 0;
+ printk(KERN_WARNING "uvesafb: NX protection is actively."
+ "We have better not to use the PMI.\n");
+ } else {
+ uvesafb_vbe_getpmi(task, par);
+ }
+ }
#else
/* The protected mode interface is not available on non-x86. */
par->pmi_setpal = par->ypan = 0;
diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c
index 05f0a80818a2..c2d05a8279fd 100644
--- a/drivers/virtio/virtio_balloon.c
+++ b/drivers/virtio/virtio_balloon.c
@@ -28,6 +28,13 @@
#include <linux/slab.h>
#include <linux/module.h>
+/*
+ * Balloon device works in 4K page units. So each page is pointed to by
+ * multiple balloon pages. All memory counters in this driver are in balloon
+ * page units.
+ */
+#define VIRTIO_BALLOON_PAGES_PER_PAGE (PAGE_SIZE >> VIRTIO_BALLOON_PFN_SHIFT)
+
struct virtio_balloon
{
struct virtio_device *vdev;
@@ -42,8 +49,13 @@ struct virtio_balloon
/* Waiting for host to ack the pages we released. */
struct completion acked;
- /* The pages we've told the Host we're not using. */
+ /* Number of balloon pages we've told the Host we're not using. */
unsigned int num_pages;
+ /*
+ * The pages we've told the Host we're not using.
+ * Each page on this list adds VIRTIO_BALLOON_PAGES_PER_PAGE
+ * to num_pages above.
+ */
struct list_head pages;
/* The array of pfns we tell the Host about. */
@@ -66,7 +78,13 @@ static u32 page_to_balloon_pfn(struct page *page)
BUILD_BUG_ON(PAGE_SHIFT < VIRTIO_BALLOON_PFN_SHIFT);
/* Convert pfn from Linux page size to balloon page size. */
- return pfn >> (PAGE_SHIFT - VIRTIO_BALLOON_PFN_SHIFT);
+ return pfn * VIRTIO_BALLOON_PAGES_PER_PAGE;
+}
+
+static struct page *balloon_pfn_to_page(u32 pfn)
+{
+ BUG_ON(pfn % VIRTIO_BALLOON_PAGES_PER_PAGE);
+ return pfn_to_page(pfn / VIRTIO_BALLOON_PAGES_PER_PAGE);
}
static void balloon_ack(struct virtqueue *vq)
@@ -96,12 +114,23 @@ static void tell_host(struct virtio_balloon *vb, struct virtqueue *vq)
wait_for_completion(&vb->acked);
}
+static void set_page_pfns(u32 pfns[], struct page *page)
+{
+ unsigned int i;
+
+ /* Set balloon pfns pointing at this page.
+ * Note that the first pfn points at start of the page. */
+ for (i = 0; i < VIRTIO_BALLOON_PAGES_PER_PAGE; i++)
+ pfns[i] = page_to_balloon_pfn(page) + i;
+}
+
static void fill_balloon(struct virtio_balloon *vb, size_t num)
{
/* We can only do one array worth at a time. */
num = min(num, ARRAY_SIZE(vb->pfns));
- for (vb->num_pfns = 0; vb->num_pfns < num; vb->num_pfns++) {
+ for (vb->num_pfns = 0; vb->num_pfns < num;
+ vb->num_pfns += VIRTIO_BALLOON_PAGES_PER_PAGE) {
struct page *page = alloc_page(GFP_HIGHUSER | __GFP_NORETRY |
__GFP_NOMEMALLOC | __GFP_NOWARN);
if (!page) {
@@ -113,9 +142,9 @@ static void fill_balloon(struct virtio_balloon *vb, size_t num)
msleep(200);
break;
}
- vb->pfns[vb->num_pfns] = page_to_balloon_pfn(page);
+ set_page_pfns(vb->pfns + vb->num_pfns, page);
+ vb->num_pages += VIRTIO_BALLOON_PAGES_PER_PAGE;
totalram_pages--;
- vb->num_pages++;
list_add(&page->lru, &vb->pages);
}
@@ -130,8 +159,9 @@ static void release_pages_by_pfn(const u32 pfns[], unsigned int num)
{
unsigned int i;
- for (i = 0; i < num; i++) {
- __free_page(pfn_to_page(pfns[i]));
+ /* Find pfns pointing at start of each page, get pages and free them. */
+ for (i = 0; i < num; i += VIRTIO_BALLOON_PAGES_PER_PAGE) {
+ __free_page(balloon_pfn_to_page(pfns[i]));
totalram_pages++;
}
}
@@ -143,11 +173,12 @@ static void leak_balloon(struct virtio_balloon *vb, size_t num)
/* We can only do one array worth at a time. */
num = min(num, ARRAY_SIZE(vb->pfns));
- for (vb->num_pfns = 0; vb->num_pfns < num; vb->num_pfns++) {
+ for (vb->num_pfns = 0; vb->num_pfns < num;
+ vb->num_pfns += VIRTIO_BALLOON_PAGES_PER_PAGE) {
page = list_first_entry(&vb->pages, struct page, lru);
list_del(&page->lru);
- vb->pfns[vb->num_pfns] = page_to_balloon_pfn(page);
- vb->num_pages--;
+ set_page_pfns(vb->pfns + vb->num_pfns, page);
+ vb->num_pages -= VIRTIO_BALLOON_PAGES_PER_PAGE;
}
/*
@@ -234,11 +265,14 @@ static void virtballoon_changed(struct virtio_device *vdev)
static inline s64 towards_target(struct virtio_balloon *vb)
{
- u32 v;
+ __le32 v;
+ s64 target;
+
vb->vdev->config->get(vb->vdev,
offsetof(struct virtio_balloon_config, num_pages),
&v, sizeof(v));
- return (s64)v - vb->num_pages;
+ target = le32_to_cpu(v);
+ return target - vb->num_pages;
}
static void update_balloon_size(struct virtio_balloon *vb)
diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c
index 99d8151c824a..1ffd03bf8e10 100644
--- a/drivers/xen/gntdev.c
+++ b/drivers/xen/gntdev.c
@@ -722,7 +722,7 @@ static int gntdev_mmap(struct file *flip, struct vm_area_struct *vma)
vma->vm_flags |= VM_RESERVED|VM_DONTEXPAND;
if (use_ptemod)
- vma->vm_flags |= VM_DONTCOPY|VM_PFNMAP;
+ vma->vm_flags |= VM_DONTCOPY;
vma->vm_private_data = map;
diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c
index b4d4eac761db..f100ce20b16b 100644
--- a/drivers/xen/grant-table.c
+++ b/drivers/xen/grant-table.c
@@ -1029,6 +1029,7 @@ int gnttab_init(void)
int i;
unsigned int max_nr_glist_frames, nr_glist_frames;
unsigned int nr_init_grefs;
+ int ret;
nr_grant_frames = 1;
boot_max_nr_grant_frames = __max_nr_grant_frames();
@@ -1047,12 +1048,16 @@ int gnttab_init(void)
nr_glist_frames = (nr_grant_frames * GREFS_PER_GRANT_FRAME + RPP - 1) / RPP;
for (i = 0; i < nr_glist_frames; i++) {
gnttab_list[i] = (grant_ref_t *)__get_free_page(GFP_KERNEL);
- if (gnttab_list[i] == NULL)
+ if (gnttab_list[i] == NULL) {
+ ret = -ENOMEM;
goto ini_nomem;
+ }
}
- if (gnttab_resume() < 0)
- return -ENODEV;
+ if (gnttab_resume() < 0) {
+ ret = -ENODEV;
+ goto ini_nomem;
+ }
nr_init_grefs = nr_grant_frames * GREFS_PER_GRANT_FRAME;
@@ -1070,7 +1075,7 @@ int gnttab_init(void)
for (i--; i >= 0; i--)
free_page((unsigned long)gnttab_list[i]);
kfree(gnttab_list);
- return -ENOMEM;
+ return ret;
}
EXPORT_SYMBOL_GPL(gnttab_init);
diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c
index 9e14ae6cd49c..412b96cc5305 100644
--- a/drivers/xen/manage.c
+++ b/drivers/xen/manage.c
@@ -132,6 +132,7 @@ static void do_suspend(void)
err = dpm_suspend_end(PMSG_FREEZE);
if (err) {
printk(KERN_ERR "dpm_suspend_end failed: %d\n", err);
+ si.cancelled = 0;
goto out_resume;
}
diff --git a/drivers/xen/xen-pciback/pciback_ops.c b/drivers/xen/xen-pciback/pciback_ops.c
index 63616d7453e6..97f5d264c31e 100644
--- a/drivers/xen/xen-pciback/pciback_ops.c
+++ b/drivers/xen/xen-pciback/pciback_ops.c
@@ -234,7 +234,7 @@ int xen_pcibk_enable_msix(struct xen_pcibk_device *pdev,
if (dev_data)
dev_data->ack_intr = 0;
- return result;
+ return result > 0 ? 0 : result;
}
static
diff --git a/drivers/xen/xenbus/xenbus_probe_frontend.c b/drivers/xen/xenbus/xenbus_probe_frontend.c
index f20c5f178b40..a31b54d48839 100644
--- a/drivers/xen/xenbus/xenbus_probe_frontend.c
+++ b/drivers/xen/xenbus/xenbus_probe_frontend.c
@@ -135,7 +135,7 @@ static int read_backend_details(struct xenbus_device *xendev)
return xenbus_read_otherend_details(xendev, "backend-id", "backend");
}
-static int is_device_connecting(struct device *dev, void *data)
+static int is_device_connecting(struct device *dev, void *data, bool ignore_nonessential)
{
struct xenbus_device *xendev = to_xenbus_device(dev);
struct device_driver *drv = data;
@@ -152,16 +152,41 @@ static int is_device_connecting(struct device *dev, void *data)
if (drv && (dev->driver != drv))
return 0;
+ if (ignore_nonessential) {
+ /* With older QEMU, for PVonHVM guests the guest config files
+ * could contain: vfb = [ 'vnc=1, vnclisten=0.0.0.0']
+ * which is nonsensical as there is no PV FB (there can be
+ * a PVKB) running as HVM guest. */
+
+ if ((strncmp(xendev->nodename, "device/vkbd", 11) == 0))
+ return 0;
+
+ if ((strncmp(xendev->nodename, "device/vfb", 10) == 0))
+ return 0;
+ }
xendrv = to_xenbus_driver(dev->driver);
return (xendev->state < XenbusStateConnected ||
(xendev->state == XenbusStateConnected &&
xendrv->is_ready && !xendrv->is_ready(xendev)));
}
+static int essential_device_connecting(struct device *dev, void *data)
+{
+ return is_device_connecting(dev, data, true /* ignore PV[KBB+FB] */);
+}
+static int non_essential_device_connecting(struct device *dev, void *data)
+{
+ return is_device_connecting(dev, data, false);
+}
-static int exists_connecting_device(struct device_driver *drv)
+static int exists_essential_connecting_device(struct device_driver *drv)
{
return bus_for_each_dev(&xenbus_frontend.bus, NULL, drv,
- is_device_connecting);
+ essential_device_connecting);
+}
+static int exists_non_essential_connecting_device(struct device_driver *drv)
+{
+ return bus_for_each_dev(&xenbus_frontend.bus, NULL, drv,
+ non_essential_device_connecting);
}
static int print_device_status(struct device *dev, void *data)
@@ -192,6 +217,23 @@ static int print_device_status(struct device *dev, void *data)
/* We only wait for device setup after most initcalls have run. */
static int ready_to_wait_for_devices;
+static bool wait_loop(unsigned long start, unsigned int max_delay,
+ unsigned int *seconds_waited)
+{
+ if (time_after(jiffies, start + (*seconds_waited+5)*HZ)) {
+ if (!*seconds_waited)
+ printk(KERN_WARNING "XENBUS: Waiting for "
+ "devices to initialise: ");
+ *seconds_waited += 5;
+ printk("%us...", max_delay - *seconds_waited);
+ if (*seconds_waited == max_delay)
+ return true;
+ }
+
+ schedule_timeout_interruptible(HZ/10);
+
+ return false;
+}
/*
* On a 5-minute timeout, wait for all devices currently configured. We need
* to do this to guarantee that the filesystems and / or network devices
@@ -215,19 +257,14 @@ static void wait_for_devices(struct xenbus_driver *xendrv)
if (!ready_to_wait_for_devices || !xen_domain())
return;
- while (exists_connecting_device(drv)) {
- if (time_after(jiffies, start + (seconds_waited+5)*HZ)) {
- if (!seconds_waited)
- printk(KERN_WARNING "XENBUS: Waiting for "
- "devices to initialise: ");
- seconds_waited += 5;
- printk("%us...", 300 - seconds_waited);
- if (seconds_waited == 300)
- break;
- }
-
- schedule_timeout_interruptible(HZ/10);
- }
+ while (exists_non_essential_connecting_device(drv))
+ if (wait_loop(start, 30, &seconds_waited))
+ break;
+
+ /* Skips PVKB and PVFB check.*/
+ while (exists_essential_connecting_device(drv))
+ if (wait_loop(start, 270, &seconds_waited))
+ break;
if (seconds_waited)
printk("\n");
OpenPOWER on IntegriCloud