summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorScott Wood <scottwood@freescale.com>2013-10-29 19:50:27 (GMT)
committerScott Wood <scottwood@freescale.com>2013-10-29 19:50:37 (GMT)
commitd0ebef8230e267ec47d4d4a65fe3262e2ebb8026 (patch)
tree24b8bb342576f543dac42d59821c4feb7ce07453 /drivers
parent041f2bc64a985b30328de4cb596f04fd913a85de (diff)
downloadlinux-fsl-qoriq-d0ebef8230e267ec47d4d4a65fe3262e2ebb8026.tar.xz
Revert to v3.8 (no RT, no stable)
Diffstat (limited to 'drivers')
-rw-r--r--drivers/acpi/Kconfig3
-rw-r--r--drivers/acpi/glue.c35
-rw-r--r--drivers/acpi/osl.c2
-rw-r--r--drivers/acpi/pci_root.c125
-rw-r--r--drivers/acpi/sleep.c8
-rw-r--r--drivers/acpi/thermal.c16
-rw-r--r--drivers/ata/ahci.c24
-rw-r--r--drivers/ata/ata_piix.c31
-rw-r--r--drivers/ata/libata-acpi.c45
-rw-r--r--drivers/ata/libata-core.c6
-rw-r--r--drivers/ata/libata-sff.c12
-rw-r--r--drivers/ata/sata_highbank.c2
-rw-r--r--drivers/base/bus.c4
-rw-r--r--drivers/base/dd.c2
-rw-r--r--drivers/base/regmap/regcache-rbtree.c2
-rw-r--r--drivers/base/regmap/regmap.c4
-rw-r--r--drivers/block/aoe/aoecmd.c3
-rw-r--r--drivers/block/loop.c33
-rw-r--r--drivers/block/nbd.c10
-rw-r--r--drivers/block/xen-blkback/blkback.c44
-rw-r--r--drivers/block/xen-blkback/common.h25
-rw-r--r--drivers/block/xen-blkback/xenbus.c49
-rw-r--r--drivers/block/xen-blkfront.c30
-rw-r--r--drivers/bluetooth/ath3k.c4
-rw-r--r--drivers/bluetooth/btusb.c2
-rw-r--r--drivers/char/hpet.c14
-rw-r--r--drivers/char/hw_random/core.c19
-rw-r--r--drivers/char/hw_random/virtio-rng.c13
-rw-r--r--drivers/char/random.c37
-rw-r--r--drivers/char/tpm/tpm.c31
-rw-r--r--drivers/char/tpm/tpm.h3
-rw-r--r--drivers/char/virtio_console.c22
-rw-r--r--drivers/clocksource/tcb_clksrc.c44
-rw-r--r--drivers/connector/cn_proc.c8
-rw-r--r--drivers/cpufreq/exynos-cpufreq.c4
-rw-r--r--drivers/crypto/caam/caamalg.c27
-rw-r--r--drivers/crypto/caam/compat.h1
-rw-r--r--drivers/crypto/talitos.c30
-rw-r--r--drivers/crypto/ux500/cryp/cryp_core.c2
-rw-r--r--drivers/dca/dca-core.c5
-rw-r--r--drivers/dma/omap-dma.c20
-rw-r--r--drivers/dma/sh/shdma.c2
-rw-r--r--drivers/edac/edac_mc_sysfs.c12
-rw-r--r--drivers/eisa/pci_eisa.c67
-rw-r--r--drivers/firewire/core-device.c4
-rw-r--r--drivers/firmware/Kconfig18
-rw-r--r--drivers/firmware/dmi_scan.c5
-rw-r--r--drivers/firmware/efivars.c501
-rw-r--r--drivers/gpio/gpio-em.c3
-rw-r--r--drivers/gpio/gpio-mvebu.c7
-rw-r--r--drivers/gpio/gpio-stmpe.c15
-rw-r--r--drivers/gpio/gpiolib-of.c5
-rw-r--r--drivers/gpu/drm/ast/ast_drv.h2
-rw-r--r--drivers/gpu/drm/ast/ast_fb.c43
-rw-r--r--drivers/gpu/drm/ast/ast_ttm.c2
-rw-r--r--drivers/gpu/drm/cirrus/cirrus_drv.h2
-rw-r--r--drivers/gpu/drm/cirrus/cirrus_fbdev.c38
-rw-r--r--drivers/gpu/drm/cirrus/cirrus_ttm.c2
-rw-r--r--drivers/gpu/drm/drm_crtc.c3
-rw-r--r--drivers/gpu/drm/drm_edid.c15
-rw-r--r--drivers/gpu/drm/drm_fops.c6
-rw-r--r--drivers/gpu/drm/drm_gem.c4
-rw-r--r--drivers/gpu/drm/drm_prime.c76
-rw-r--r--drivers/gpu/drm/drm_usb.c2
-rw-r--r--drivers/gpu/drm/gma500/psb_irq.c2
-rw-r--r--drivers/gpu/drm/i915/i915_debugfs.c14
-rw-r--r--drivers/gpu/drm/i915/i915_drv.c12
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h4
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c45
-rw-r--r--drivers/gpu/drm/i915/i915_gem_context.c7
-rw-r--r--drivers/gpu/drm/i915/i915_gem_execbuffer.c18
-rw-r--r--drivers/gpu/drm/i915/i915_gem_stolen.c81
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h11
-rw-r--r--drivers/gpu/drm/i915/i915_trace.h1
-rw-r--r--drivers/gpu/drm/i915/intel_bios.c6
-rw-r--r--drivers/gpu/drm/i915/intel_bios.h4
-rw-r--r--drivers/gpu/drm/i915/intel_crt.c54
-rw-r--r--drivers/gpu/drm/i915/intel_ddi.c25
-rw-r--r--drivers/gpu/drm/i915/intel_display.c114
-rw-r--r--drivers/gpu/drm/i915/intel_dp.c19
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h11
-rw-r--r--drivers/gpu/drm/i915/intel_dvo.c13
-rw-r--r--drivers/gpu/drm/i915/intel_lvds.c9
-rw-r--r--drivers/gpu/drm/i915/intel_panel.c7
-rw-r--r--drivers/gpu/drm/i915/intel_pm.c11
-rw-r--r--drivers/gpu/drm/i915/intel_ringbuffer.h2
-rw-r--r--drivers/gpu/drm/i915/intel_sdvo.c5
-rw-r--r--drivers/gpu/drm/i915/intel_sprite.c8
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_drv.h2
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_fb.c43
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_mode.c23
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_ttm.c4
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/bios/dcb.h3
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bios/dcb.c32
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/devinit/nv50.c14
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_abi16.c18
-rw-r--r--drivers/gpu/drm/radeon/atom.c6
-rw-r--r--drivers/gpu/drm/radeon/atombios_crtc.c9
-rw-r--r--drivers/gpu/drm/radeon/evergreen.c124
-rw-r--r--drivers/gpu/drm/radeon/evergreen_reg.h2
-rw-r--r--drivers/gpu/drm/radeon/ni.c39
-rw-r--r--drivers/gpu/drm/radeon/nid.h4
-rw-r--r--drivers/gpu/drm/radeon/r100.c77
-rw-r--r--drivers/gpu/drm/radeon/r500_reg.h2
-rw-r--r--drivers/gpu/drm/radeon/r600_hdmi.c5
-rw-r--r--drivers/gpu/drm/radeon/radeon_atombios.c21
-rw-r--r--drivers/gpu/drm/radeon/radeon_atpx_handler.c73
-rw-r--r--drivers/gpu/drm/radeon/radeon_benchmark.c16
-rw-r--r--drivers/gpu/drm/radeon/radeon_combios.c9
-rw-r--r--drivers/gpu/drm/radeon/radeon_irq_kms.c12
-rw-r--r--drivers/gpu/drm/radeon/radeon_kms.c4
-rw-r--r--drivers/gpu/drm/radeon/radeon_pm.c8
-rw-r--r--drivers/gpu/drm/radeon/radeon_ring.c3
-rw-r--r--drivers/gpu/drm/radeon/rs600.c52
-rw-r--r--drivers/gpu/drm/radeon/rv515.c56
-rw-r--r--drivers/gpu/drm/radeon/si.c4
-rw-r--r--drivers/gpu/drm/radeon/sid.h2
-rw-r--r--drivers/gpu/drm/udl/udl_connector.c4
-rw-r--r--drivers/gpu/drm/udl/udl_drv.h2
-rw-r--r--drivers/gpu/drm/udl/udl_fb.c48
-rw-r--r--drivers/gpu/vga/vga_switcheroo.c3
-rw-r--r--drivers/hid/hid-core.c2
-rw-r--r--drivers/hid/hid-ids.h10
-rw-r--r--drivers/hid/hid-logitech-dj.c22
-rw-r--r--drivers/hid/hid-magicmouse.c29
-rw-r--r--drivers/hid/hid-sony.c18
-rw-r--r--drivers/hid/hid-wiimote-ext.c8
-rw-r--r--drivers/hid/usbhid/hid-quirks.c2
-rw-r--r--drivers/hwmon/lineage-pem.c2
-rw-r--r--drivers/hwmon/pmbus/ltc2978.c40
-rw-r--r--drivers/hwmon/sht15.c8
-rw-r--r--drivers/hwspinlock/hwspinlock_core.c2
-rw-r--r--drivers/i2c/busses/i2c-omap.c5
-rw-r--r--drivers/i2c/busses/i2c-tegra.c13
-rw-r--r--drivers/i2c/busses/i2c-xiic.c6
-rw-r--r--drivers/ide/alim15x3.c4
-rw-r--r--drivers/ide/hpt366.c4
-rw-r--r--drivers/ide/ide-io-std.c8
-rw-r--r--drivers/ide/ide-io.c2
-rw-r--r--drivers/ide/ide-iops.c4
-rw-r--r--drivers/ide/ide-probe.c4
-rw-r--r--drivers/ide/ide-taskfile.c6
-rw-r--r--drivers/idle/i7300_idle.c8
-rw-r--r--drivers/infiniband/hw/cxgb4/qp.c25
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_cm.c8
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_multicast.c4
-rw-r--r--drivers/infiniband/ulp/srp/ib_srp.c42
-rw-r--r--drivers/infiniband/ulp/srp/ib_srp.h1
-rw-r--r--drivers/input/gameport/gameport.c8
-rw-r--r--drivers/iommu/amd_iommu.c25
-rw-r--r--drivers/iommu/amd_iommu_init.c10
-rw-r--r--drivers/iommu/intel-iommu.c8
-rw-r--r--drivers/md/dm-bufio.c2
-rw-r--r--drivers/md/dm-crypt.c39
-rw-r--r--drivers/md/dm-delay.c8
-rw-r--r--drivers/md/dm-flakey.c7
-rw-r--r--drivers/md/dm-ioctl.c14
-rw-r--r--drivers/md/dm-linear.c7
-rw-r--r--drivers/md/dm-mpath.c8
-rw-r--r--drivers/md/dm-raid.c8
-rw-r--r--drivers/md/dm-raid1.c8
-rw-r--r--drivers/md/dm-snap.c18
-rw-r--r--drivers/md/dm-stripe.c7
-rw-r--r--drivers/md/dm-thin.c80
-rw-r--r--drivers/md/dm-verity.c45
-rw-r--r--drivers/md/dm.c46
-rw-r--r--drivers/md/md.c16
-rw-r--r--drivers/md/persistent-data/dm-btree-remove.c46
-rw-r--r--drivers/md/raid0.c5
-rw-r--r--drivers/md/raid1.c15
-rw-r--r--drivers/md/raid10.c17
-rw-r--r--drivers/md/raid5.c123
-rw-r--r--drivers/md/raid5.h2
-rw-r--r--drivers/media/pci/bt8xx/bttv-driver.c20
-rw-r--r--drivers/media/pci/cx18/cx18-alsa-main.c2
-rw-r--r--drivers/media/pci/cx18/cx18-alsa-pcm.h2
-rw-r--r--drivers/media/pci/ivtv/ivtv-alsa-main.c2
-rw-r--r--drivers/media/pci/ivtv/ivtv-alsa-pcm.h2
-rw-r--r--drivers/media/platform/omap/omap_vout.c12
-rw-r--r--drivers/media/rc/rc-main.c4
-rw-r--r--drivers/media/v4l2-core/v4l2-device.c30
-rw-r--r--drivers/memstick/host/rtsx_pci_ms.c7
-rw-r--r--drivers/mfd/adp5520.c8
-rw-r--r--drivers/mfd/rtsx_pcr.c61
-rw-r--r--drivers/misc/Kconfig41
-rw-r--r--drivers/misc/Makefile1
-rw-r--r--drivers/misc/hwlat_detector.c1212
-rw-r--r--drivers/mmc/core/mmc.c4
-rw-r--r--drivers/mmc/host/Kconfig10
-rw-r--r--drivers/mmc/host/atmel-mci.c16
-rw-r--r--drivers/mmc/host/mmci.c5
-rw-r--r--drivers/mmc/host/rtsx_pci_sdmmc.c18
-rw-r--r--drivers/mmc/host/sdhci-esdhc-imx.c19
-rw-r--r--drivers/mtd/mtdchar.c32
-rw-r--r--drivers/mtd/nand/nand_base.c16
-rw-r--r--drivers/mtd/nand/nand_ids.c80
-rw-r--r--drivers/net/Kconfig1
-rw-r--r--drivers/net/bonding/bond_main.c79
-rw-r--r--drivers/net/bonding/bond_sysfs.c97
-rw-r--r--drivers/net/can/mcp251x.c10
-rw-r--r--drivers/net/can/sja1000/plx_pci.c4
-rw-r--r--drivers/net/can/sja1000/sja1000.c6
-rw-r--r--drivers/net/can/sja1000/sja1000.h2
-rw-r--r--drivers/net/can/sja1000/sja1000_of_platform.c31
-rw-r--r--drivers/net/ethernet/3com/3c59x.c8
-rw-r--r--drivers/net/ethernet/atheros/atl1c/atl1c_main.c8
-rw-r--r--drivers/net/ethernet/atheros/atl1e/atl1e.h3
-rw-r--r--drivers/net/ethernet/atheros/atl1e/atl1e_main.c23
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c1
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h3
-rw-r--r--drivers/net/ethernet/broadcom/tg3.c47
-rw-r--r--drivers/net/ethernet/broadcom/tg3.h2
-rw-r--r--drivers/net/ethernet/chelsio/cxgb/sge.c3
-rw-r--r--drivers/net/ethernet/davicom/dm9000.c214
-rw-r--r--drivers/net/ethernet/davicom/dm9000.h11
-rw-r--r--drivers/net/ethernet/dec/tulip/tulip_core.c1
-rw-r--r--drivers/net/ethernet/freescale/fec_ptp.c3
-rw-r--r--drivers/net/ethernet/freescale/gianfar.c8
-rw-r--r--drivers/net/ethernet/freescale/gianfar_ptp.c3
-rw-r--r--drivers/net/ethernet/ibm/ibmveth.c23
-rw-r--r--drivers/net/ethernet/intel/e1000e/ethtool.c13
-rw-r--r--drivers/net/ethernet/intel/e1000e/netdev.c82
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_main.c21
-rw-r--r--drivers/net/ethernet/marvell/Kconfig2
-rw-r--r--drivers/net/ethernet/marvell/mvneta.c9
-rw-r--r--drivers/net/ethernet/marvell/sky2.c2
-rw-r--r--drivers/net/ethernet/marvell/sky2.h2
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_netdev.c18
-rw-r--r--drivers/net/ethernet/micrel/ks8851.c2
-rw-r--r--drivers/net/ethernet/neterion/s2io.c7
-rw-r--r--drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c10
-rw-r--r--drivers/net/ethernet/realtek/8139too.c2
-rw-r--r--drivers/net/ethernet/realtek/r8169.c37
-rw-r--r--drivers/net/ethernet/sfc/efx.c16
-rw-r--r--drivers/net/ethernet/sfc/efx.h4
-rw-r--r--drivers/net/ethernet/sfc/net_driver.h4
-rw-r--r--drivers/net/ethernet/sfc/nic.c3
-rw-r--r--drivers/net/ethernet/sfc/ptp.c2
-rw-r--r--drivers/net/ethernet/sfc/rx.c25
-rw-r--r--drivers/net/ethernet/tehuti/tehuti.c9
-rw-r--r--drivers/net/ethernet/ti/Kconfig4
-rw-r--r--drivers/net/ethernet/ti/cpmac.c7
-rw-r--r--drivers/net/ethernet/ti/cpsw.c830
-rw-r--r--drivers/net/ethernet/ti/cpsw_ale.c107
-rw-r--r--drivers/net/ethernet/ti/cpsw_ale.h24
-rw-r--r--drivers/net/ethernet/ti/davinci_cpdma.c106
-rw-r--r--drivers/net/ethernet/ti/davinci_cpdma.h12
-rw-r--r--drivers/net/ethernet/ti/davinci_emac.c74
-rw-r--r--drivers/net/ethernet/ti/davinci_mdio.c5
-rw-r--r--drivers/net/ethernet/ti/tlan.c5
-rw-r--r--drivers/net/macvlan.c1
-rw-r--r--drivers/net/netconsole.c15
-rw-r--r--drivers/net/ppp/ppp_generic.c8
-rw-r--r--drivers/net/rionet.c6
-rw-r--r--drivers/net/team/team.c2
-rw-r--r--drivers/net/tun.c2
-rw-r--r--drivers/net/usb/cdc_mbim.c13
-rw-r--r--drivers/net/usb/cdc_ncm.c44
-rw-r--r--drivers/net/usb/qmi_wwan.c49
-rw-r--r--drivers/net/usb/smsc75xx.c12
-rw-r--r--drivers/net/usb/smsc95xx.c6
-rw-r--r--drivers/net/vxlan.c9
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_calib.c4
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/common.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/htc.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_init.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_txrx.c18
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c4
-rw-r--r--drivers/net/wireless/ath/ath9k/link.c29
-rw-r--r--drivers/net/wireless/b43/dma.c65
-rw-r--r--drivers/net/wireless/b43/dma.h2
-rw-r--r--drivers/net/wireless/b43/main.c3
-rw-r--r--drivers/net/wireless/b43/phy_n.c11
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c369
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c64
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/debugfs.c16
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/lib.c9
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/sta.c5
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/ucode.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-devtrace.h10
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/internal.h9
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/tx.c73
-rw-r--r--drivers/net/wireless/libertas/if_sdio.c6
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.c3
-rw-r--r--drivers/net/wireless/mwifiex/cmdevt.c22
-rw-r--r--drivers/net/wireless/mwifiex/init.c8
-rw-r--r--drivers/net/wireless/mwifiex/join.c7
-rw-r--r--drivers/net/wireless/mwifiex/main.h4
-rw-r--r--drivers/net/wireless/mwifiex/pcie.c6
-rw-r--r--drivers/net/wireless/mwifiex/scan.c17
-rw-r--r--drivers/net/wireless/mwifiex/sta_ioctl.c10
-rw-r--r--drivers/net/wireless/p54/p54usb.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2800lib.c8
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00pci.c4
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/hw.c89
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/sw.c9
-rw-r--r--drivers/net/wireless/rtlwifi/usb.c50
-rw-r--r--drivers/net/wireless/rtlwifi/usb.h3
-rw-r--r--drivers/net/xen-netback/interface.c3
-rw-r--r--drivers/net/xen-netback/netback.c8
-rw-r--r--drivers/of/base.c211
-rw-r--r--drivers/pci/access.c4
-rw-r--r--drivers/pci/pci-acpi.c15
-rw-r--r--drivers/pci/pci-driver.c4
-rw-r--r--drivers/pci/pci.c12
-rw-r--r--drivers/pci/pcie/portdrv_pci.c13
-rw-r--r--drivers/pcmcia/vrc4171_card.c1
-rw-r--r--drivers/platform/x86/acer-wmi.c3
-rw-r--r--drivers/platform/x86/msi-wmi.c4
-rw-r--r--drivers/platform/x86/sony-laptop.c2
-rw-r--r--drivers/power/ab8500_btemp.c2
-rw-r--r--drivers/power/abx500_chargalg.c2
-rw-r--r--drivers/power/bq27x00_battery.c2
-rw-r--r--drivers/pps/clients/pps-ldisc.c10
-rw-r--r--drivers/pps/pps.c47
-rw-r--r--drivers/pwm/pwm-spear.c6
-rw-r--r--drivers/regulator/core.c4
-rw-r--r--drivers/remoteproc/Kconfig2
-rw-r--r--drivers/remoteproc/remoteproc_core.c4
-rw-r--r--drivers/remoteproc/ste_modem_rproc.c7
-rw-r--r--drivers/rtc/rtc-cmos.c4
-rw-r--r--drivers/rtc/rtc-mv.c28
-rw-r--r--drivers/s390/char/sclp_cmd.c4
-rw-r--r--drivers/s390/kvm/kvm_virtio.c38
-rw-r--r--drivers/scsi/dc395x.c2
-rw-r--r--drivers/scsi/fcoe/fcoe.c18
-rw-r--r--drivers/scsi/fcoe/fcoe_ctlr.c4
-rw-r--r--drivers/scsi/libfc/fc_exch.c4
-rw-r--r--drivers/scsi/libsas/sas_expander.c12
-rw-r--r--drivers/scsi/qla2xxx/qla_inline.h4
-rw-r--r--drivers/scsi/storvsc_drv.c1
-rw-r--r--drivers/spi/spi-mpc512x-psc.c2
-rw-r--r--drivers/spi/spi-omap2-mcspi.c8
-rw-r--r--drivers/spi/spi-s3c64xx.c41
-rw-r--r--drivers/ssb/driver_chipcommon_pmu.c29
-rw-r--r--drivers/staging/comedi/comedi_fops.c13
-rw-r--r--drivers/staging/comedi/drivers/dt9812.c16
-rw-r--r--drivers/staging/comedi/drivers/ni_labpc.c34
-rw-r--r--drivers/staging/comedi/drivers/s626.c2
-rw-r--r--drivers/staging/vt6656/dpc.c4
-rw-r--r--drivers/staging/vt6656/main_usb.c4
-rw-r--r--drivers/staging/vt6656/rxtx.c2
-rw-r--r--drivers/staging/vt6656/usbpipe.c28
-rw-r--r--drivers/staging/zram/zram_drv.c9
-rw-r--r--drivers/staging/zsmalloc/Kconfig2
-rw-r--r--drivers/staging/zsmalloc/zsmalloc-main.c13
-rw-r--r--drivers/target/iscsi/iscsi_target.c11
-rw-r--r--drivers/target/iscsi/iscsi_target_auth.c5
-rw-r--r--drivers/target/target_core_alua.c3
-rw-r--r--drivers/target/target_core_device.c13
-rw-r--r--drivers/target/target_core_fabric_configfs.c12
-rw-r--r--drivers/target/target_core_file.h2
-rw-r--r--drivers/target/target_core_internal.h2
-rw-r--r--drivers/target/target_core_pscsi.c1
-rw-r--r--drivers/target/target_core_tpg.c10
-rw-r--r--drivers/target/target_core_transport.c4
-rw-r--r--drivers/thermal/thermal_sys.c1
-rw-r--r--drivers/tty/n_gsm.c42
-rw-r--r--drivers/tty/pty.c4
-rw-r--r--drivers/tty/serial/8250/8250.c79
-rw-r--r--drivers/tty/serial/8250/8250_pci.c21
-rw-r--r--drivers/tty/serial/Kconfig4
-rw-r--r--drivers/tty/serial/amba-pl011.c15
-rw-r--r--drivers/tty/serial/atmel_serial.c11
-rw-r--r--drivers/tty/serial/imx.c11
-rw-r--r--drivers/tty/serial/of_serial.c6
-rw-r--r--drivers/tty/serial/omap-serial.c12
-rw-r--r--drivers/tty/serial/serial_core.c4
-rw-r--r--drivers/tty/serial/sunsu.c21
-rw-r--r--drivers/tty/tty_buffer.c7
-rw-r--r--drivers/tty/tty_io.c14
-rw-r--r--drivers/tty/tty_ioctl.c4
-rw-r--r--drivers/tty/tty_ldisc.c10
-rw-r--r--drivers/tty/vt/vc_screen.c6
-rw-r--r--drivers/tty/vt/vt.c138
-rw-r--r--drivers/usb/chipidea/debug.c2
-rw-r--r--drivers/usb/chipidea/udc.c8
-rw-r--r--drivers/usb/chipidea/udc.h4
-rw-r--r--drivers/usb/class/cdc-acm.c3
-rw-r--r--drivers/usb/class/cdc-wdm.c23
-rw-r--r--drivers/usb/core/devio.c2
-rw-r--r--drivers/usb/core/hcd-pci.c23
-rw-r--r--drivers/usb/core/hcd.c4
-rw-r--r--drivers/usb/core/hub.c178
-rw-r--r--drivers/usb/dwc3/core.c1
-rw-r--r--drivers/usb/dwc3/core.h2
-rw-r--r--drivers/usb/dwc3/gadget.c98
-rw-r--r--drivers/usb/gadget/g_ffs.c4
-rw-r--r--drivers/usb/gadget/udc-core.c2
-rw-r--r--drivers/usb/host/ehci-hcd.c10
-rw-r--r--drivers/usb/host/ehci-hub.c2
-rw-r--r--drivers/usb/host/ehci-omap.c10
-rw-r--r--drivers/usb/host/ehci-q.c49
-rw-r--r--drivers/usb/host/ehci-sched.c2
-rw-r--r--drivers/usb/host/ehci-timer.c31
-rw-r--r--drivers/usb/host/ohci-hcd.c10
-rw-r--r--drivers/usb/host/xhci-ring.c47
-rw-r--r--drivers/usb/host/xhci.c3
-rw-r--r--drivers/usb/host/xhci.h8
-rw-r--r--drivers/usb/misc/appledisplay.c1
-rw-r--r--drivers/usb/musb/am35x.c2
-rw-r--r--drivers/usb/musb/blackfin.c2
-rw-r--r--drivers/usb/musb/da8xx.c9
-rw-r--r--drivers/usb/musb/davinci.c7
-rw-r--r--drivers/usb/musb/musb_core.c1
-rw-r--r--drivers/usb/musb/musb_dsps.c2
-rw-r--r--drivers/usb/musb/omap2430.c2
-rw-r--r--drivers/usb/musb/tusb6010.c2
-rw-r--r--drivers/usb/musb/ux500.c12
-rw-r--r--drivers/usb/serial/ark3116.c10
-rw-r--r--drivers/usb/serial/ch341.c11
-rw-r--r--drivers/usb/serial/cp210x.c20
-rw-r--r--drivers/usb/serial/cypress_m8.c14
-rw-r--r--drivers/usb/serial/f81232.c9
-rw-r--r--drivers/usb/serial/ftdi_sio.c63
-rw-r--r--drivers/usb/serial/ftdi_sio_ids.h11
-rw-r--r--drivers/usb/serial/garmin_gps.c7
-rw-r--r--drivers/usb/serial/io_edgeport.c12
-rw-r--r--drivers/usb/serial/io_ti.c13
-rw-r--r--drivers/usb/serial/mct_u232.c35
-rw-r--r--drivers/usb/serial/mos7840.c16
-rw-r--r--drivers/usb/serial/option.c29
-rw-r--r--drivers/usb/serial/oti6858.c10
-rw-r--r--drivers/usb/serial/pl2303.c11
-rw-r--r--drivers/usb/serial/qcaux.c1
-rw-r--r--drivers/usb/serial/qcserial.c7
-rw-r--r--drivers/usb/serial/quatech2.c30
-rw-r--r--drivers/usb/serial/sierra.c8
-rw-r--r--drivers/usb/serial/spcp8x5.c9
-rw-r--r--drivers/usb/serial/ssu100.c31
-rw-r--r--drivers/usb/serial/ti_usb_3410_5052.c10
-rw-r--r--drivers/usb/serial/usb-serial.c18
-rw-r--r--drivers/usb/serial/usb_wwan.c8
-rw-r--r--drivers/usb/storage/cypress_atacb.c16
-rw-r--r--drivers/usb/storage/initializers.c76
-rw-r--r--drivers/usb/storage/initializers.h4
-rw-r--r--drivers/usb/storage/unusual_cypress.h2
-rw-r--r--drivers/usb/storage/unusual_devs.h336
-rw-r--r--drivers/vfio/pci/vfio_pci.c3
-rw-r--r--drivers/vhost/net.c3
-rw-r--r--drivers/video/atmel_lcdfb.c22
-rw-r--r--drivers/video/backlight/adp8860_bl.c2
-rw-r--r--drivers/video/backlight/adp8870_bl.c2
-rw-r--r--drivers/video/console/fbcon.c60
-rw-r--r--drivers/video/console/vgacon.c22
-rw-r--r--drivers/video/ep93xx-fb.c1
-rw-r--r--drivers/video/fbmem.c50
-rw-r--r--drivers/video/fbsysfs.c3
-rw-r--r--drivers/video/fsl-diu-fb.c64
-rw-r--r--drivers/w1/masters/w1-gpio.c6
-rw-r--r--drivers/w1/w1.c3
-rw-r--r--drivers/watchdog/Kconfig1
-rw-r--r--drivers/watchdog/sp5100_tco.c135
-rw-r--r--drivers/watchdog/sp5100_tco.h2
-rw-r--r--drivers/xen/events.c20
-rw-r--r--drivers/xen/evtchn.c10
-rw-r--r--drivers/xen/fallback.c3
-rw-r--r--drivers/xen/xen-pciback/pci_stub.c59
-rw-r--r--drivers/xen/xen-pciback/pciback_ops.c3
-rw-r--r--drivers/xen/xenbus/xenbus_client.c1
462 files changed, 3550 insertions, 7942 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index f5ae996..38c5078 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -268,8 +268,7 @@ config ACPI_CUSTOM_DSDT
default ACPI_CUSTOM_DSDT_FILE != ""
config ACPI_INITRD_TABLE_OVERRIDE
- bool "ACPI tables override via initrd"
- depends on BLK_DEV_INITRD && X86
+ bool "ACPI tables can be passed via uncompressed cpio in initrd"
default n
help
This option provides functionality to override arbitrary ACPI tables
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
index e9e486f..35da181 100644
--- a/drivers/acpi/glue.c
+++ b/drivers/acpi/glue.c
@@ -95,31 +95,40 @@ static int acpi_find_bridge_device(struct device *dev, acpi_handle * handle)
return ret;
}
-static acpi_status do_acpi_find_child(acpi_handle handle, u32 lvl_not_used,
- void *addr_p, void **ret_p)
+/* Get device's handler per its address under its parent */
+struct acpi_find_child {
+ acpi_handle handle;
+ u64 address;
+};
+
+static acpi_status
+do_acpi_find_child(acpi_handle handle, u32 lvl, void *context, void **rv)
{
- unsigned long long addr;
acpi_status status;
-
- status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &addr);
- if (ACPI_SUCCESS(status) && addr == *((u64 *)addr_p)) {
- *ret_p = handle;
- return AE_CTRL_TERMINATE;
+ struct acpi_device_info *info;
+ struct acpi_find_child *find = context;
+
+ status = acpi_get_object_info(handle, &info);
+ if (ACPI_SUCCESS(status)) {
+ if ((info->address == find->address)
+ && (info->valid & ACPI_VALID_ADR))
+ find->handle = handle;
+ kfree(info);
}
return AE_OK;
}
acpi_handle acpi_get_child(acpi_handle parent, u64 address)
{
- void *ret = NULL;
+ struct acpi_find_child find = { NULL, address };
if (!parent)
return NULL;
-
- acpi_walk_namespace(ACPI_TYPE_DEVICE, parent, 1, NULL,
- do_acpi_find_child, &address, &ret);
- return (acpi_handle)ret;
+ acpi_walk_namespace(ACPI_TYPE_DEVICE, parent,
+ 1, do_acpi_find_child, NULL, &find, NULL);
+ return find.handle;
}
+
EXPORT_SYMBOL(acpi_get_child);
static int acpi_bind_one(struct device *dev, acpi_handle handle)
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 2999966..bd22f86 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -642,7 +642,7 @@ void __init acpi_initrd_override(void *data, size_t size)
* Both memblock_reserve and e820_add_region (via arch_reserve_mem_area)
* works fine.
*/
- memblock_reserve(acpi_tables_addr, all_tables_size);
+ memblock_reserve(acpi_tables_addr, acpi_tables_addr + all_tables_size);
arch_reserve_mem_area(acpi_tables_addr, all_tables_size);
p = early_ioremap(acpi_tables_addr, all_tables_size);
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index 77c9a92..7928d4d 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -240,8 +240,8 @@ static acpi_status acpi_pci_query_osc(struct acpi_pci_root *root,
*control &= OSC_PCI_CONTROL_MASKS;
capbuf[OSC_CONTROL_TYPE] = *control | root->osc_control_set;
} else {
- /* Run _OSC query only with existing controls. */
- capbuf[OSC_CONTROL_TYPE] = root->osc_control_set;
+ /* Run _OSC query for all possible controls. */
+ capbuf[OSC_CONTROL_TYPE] = OSC_PCI_CONTROL_MASKS;
}
status = acpi_pci_run_osc(root->device->handle, capbuf, &result);
@@ -454,6 +454,7 @@ static int acpi_pci_root_add(struct acpi_device *device)
acpi_handle handle;
struct acpi_device *child;
u32 flags, base_flags;
+ bool is_osc_granted = false;
root = kzalloc(sizeof(struct acpi_pci_root), GFP_KERNEL);
if (!root)
@@ -524,6 +525,60 @@ static int acpi_pci_root_add(struct acpi_device *device)
flags = base_flags = OSC_PCI_SEGMENT_GROUPS_SUPPORT;
acpi_pci_osc_support(root, flags);
+ /* Indicate support for various _OSC capabilities. */
+ if (pci_ext_cfg_avail())
+ flags |= OSC_EXT_PCI_CONFIG_SUPPORT;
+ if (pcie_aspm_support_enabled()) {
+ flags |= OSC_ACTIVE_STATE_PWR_SUPPORT |
+ OSC_CLOCK_PWR_CAPABILITY_SUPPORT;
+ }
+ if (pci_msi_enabled())
+ flags |= OSC_MSI_SUPPORT;
+ if (flags != base_flags) {
+ status = acpi_pci_osc_support(root, flags);
+ if (ACPI_FAILURE(status)) {
+ dev_info(&device->dev, "ACPI _OSC support "
+ "notification failed, disabling PCIe ASPM\n");
+ pcie_no_aspm();
+ flags = base_flags;
+ }
+ }
+ if (!pcie_ports_disabled
+ && (flags & ACPI_PCIE_REQ_SUPPORT) == ACPI_PCIE_REQ_SUPPORT) {
+ flags = OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL
+ | OSC_PCI_EXPRESS_NATIVE_HP_CONTROL
+ | OSC_PCI_EXPRESS_PME_CONTROL;
+
+ if (pci_aer_available()) {
+ if (aer_acpi_firmware_first())
+ dev_dbg(&device->dev,
+ "PCIe errors handled by BIOS.\n");
+ else
+ flags |= OSC_PCI_EXPRESS_AER_CONTROL;
+ }
+
+ dev_info(&device->dev,
+ "Requesting ACPI _OSC control (0x%02x)\n", flags);
+
+ status = acpi_pci_osc_control_set(device->handle, &flags,
+ OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL);
+ if (ACPI_SUCCESS(status)) {
+ is_osc_granted = true;
+ dev_info(&device->dev,
+ "ACPI _OSC control (0x%02x) granted\n", flags);
+ } else {
+ is_osc_granted = false;
+ dev_info(&device->dev,
+ "ACPI _OSC request failed (%s), "
+ "returned control mask: 0x%02x\n",
+ acpi_format_exception(status), flags);
+ }
+ } else {
+ dev_info(&device->dev,
+ "Unable to request _OSC control "
+ "(_OSC support mask: 0x%02x)\n", flags);
+ }
+
/*
* TBD: Need PCI interface for enumeration/configuration of roots.
*/
@@ -563,66 +618,14 @@ static int acpi_pci_root_add(struct acpi_device *device)
list_for_each_entry(child, &device->children, node)
acpi_pci_bridge_scan(child);
- /* Indicate support for various _OSC capabilities. */
- if (pci_ext_cfg_avail())
- flags |= OSC_EXT_PCI_CONFIG_SUPPORT;
- if (pcie_aspm_support_enabled())
- flags |= OSC_ACTIVE_STATE_PWR_SUPPORT |
- OSC_CLOCK_PWR_CAPABILITY_SUPPORT;
- if (pci_msi_enabled())
- flags |= OSC_MSI_SUPPORT;
- if (flags != base_flags) {
- status = acpi_pci_osc_support(root, flags);
- if (ACPI_FAILURE(status)) {
- dev_info(root->bus->bridge, "ACPI _OSC support "
- "notification failed, disabling PCIe ASPM\n");
- pcie_no_aspm();
- flags = base_flags;
- }
- }
-
- if (!pcie_ports_disabled
- && (flags & ACPI_PCIE_REQ_SUPPORT) == ACPI_PCIE_REQ_SUPPORT) {
- flags = OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL
- | OSC_PCI_EXPRESS_NATIVE_HP_CONTROL
- | OSC_PCI_EXPRESS_PME_CONTROL;
-
- if (pci_aer_available()) {
- if (aer_acpi_firmware_first())
- dev_dbg(root->bus->bridge,
- "PCIe errors handled by BIOS.\n");
- else
- flags |= OSC_PCI_EXPRESS_AER_CONTROL;
- }
-
- dev_info(root->bus->bridge,
- "Requesting ACPI _OSC control (0x%02x)\n", flags);
-
- status = acpi_pci_osc_control_set(device->handle, &flags,
- OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL);
- if (ACPI_SUCCESS(status)) {
- dev_info(root->bus->bridge,
- "ACPI _OSC control (0x%02x) granted\n", flags);
- if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_ASPM) {
- /*
- * We have ASPM control, but the FADT indicates
- * that it's unsupported. Clear it.
- */
- pcie_clear_aspm(root->bus);
- }
- } else {
- dev_info(root->bus->bridge,
- "ACPI _OSC request failed (%s), "
- "returned control mask: 0x%02x\n",
- acpi_format_exception(status), flags);
- pr_info("ACPI _OSC control for PCIe not granted, "
- "disabling ASPM\n");
- pcie_no_aspm();
- }
+ /* ASPM setting */
+ if (is_osc_granted) {
+ if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_ASPM)
+ pcie_clear_aspm(root->bus);
} else {
- dev_info(root->bus->bridge,
- "Unable to request _OSC control "
- "(_OSC support mask: 0x%02x)\n", flags);
+ pr_info("ACPI _OSC control for PCIe not granted, "
+ "disabling ASPM\n");
+ pcie_no_aspm();
}
pci_acpi_add_bus_pm_notifier(device, root->bus);
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c
index df85051..2fcc67d 100644
--- a/drivers/acpi/sleep.c
+++ b/drivers/acpi/sleep.c
@@ -177,14 +177,6 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
},
{
.callback = init_nvs_nosave,
- .ident = "Sony Vaio VGN-FW41E_H",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
- DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FW41E_H"),
- },
- },
- {
- .callback = init_nvs_nosave,
.ident = "Sony Vaio VGN-FW21E",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index 25246e8..506fbd4 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -719,19 +719,9 @@ static int thermal_get_trend(struct thermal_zone_device *thermal,
return -EINVAL;
if (type == THERMAL_TRIP_ACTIVE) {
- unsigned long trip_temp;
- unsigned long temp = KELVIN_TO_MILLICELSIUS(tz->temperature,
- tz->kelvin_offset);
- if (thermal_get_trip_temp(thermal, trip, &trip_temp))
- return -EINVAL;
-
- if (temp > trip_temp) {
- *trend = THERMAL_TREND_RAISING;
- return 0;
- } else {
- /* Fall back on default trend */
- return -EINVAL;
- }
+ /* aggressive active cooling */
+ *trend = THERMAL_TREND_RAISING;
+ return 0;
}
/*
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index 72e3e12..4979127 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -265,30 +265,6 @@ static const struct pci_device_id ahci_pci_tbl[] = {
{ PCI_VDEVICE(INTEL, 0x9c07), board_ahci }, /* Lynx Point-LP RAID */
{ PCI_VDEVICE(INTEL, 0x9c0e), board_ahci }, /* Lynx Point-LP RAID */
{ PCI_VDEVICE(INTEL, 0x9c0f), board_ahci }, /* Lynx Point-LP RAID */
- { PCI_VDEVICE(INTEL, 0x1f22), board_ahci }, /* Avoton AHCI */
- { PCI_VDEVICE(INTEL, 0x1f23), board_ahci }, /* Avoton AHCI */
- { PCI_VDEVICE(INTEL, 0x1f24), board_ahci }, /* Avoton RAID */
- { PCI_VDEVICE(INTEL, 0x1f25), board_ahci }, /* Avoton RAID */
- { PCI_VDEVICE(INTEL, 0x1f26), board_ahci }, /* Avoton RAID */
- { PCI_VDEVICE(INTEL, 0x1f27), board_ahci }, /* Avoton RAID */
- { PCI_VDEVICE(INTEL, 0x1f2e), board_ahci }, /* Avoton RAID */
- { PCI_VDEVICE(INTEL, 0x1f2f), board_ahci }, /* Avoton RAID */
- { PCI_VDEVICE(INTEL, 0x1f32), board_ahci }, /* Avoton AHCI */
- { PCI_VDEVICE(INTEL, 0x1f33), board_ahci }, /* Avoton AHCI */
- { PCI_VDEVICE(INTEL, 0x1f34), board_ahci }, /* Avoton RAID */
- { PCI_VDEVICE(INTEL, 0x1f35), board_ahci }, /* Avoton RAID */
- { PCI_VDEVICE(INTEL, 0x1f36), board_ahci }, /* Avoton RAID */
- { PCI_VDEVICE(INTEL, 0x1f37), board_ahci }, /* Avoton RAID */
- { PCI_VDEVICE(INTEL, 0x1f3e), board_ahci }, /* Avoton RAID */
- { PCI_VDEVICE(INTEL, 0x1f3f), board_ahci }, /* Avoton RAID */
- { PCI_VDEVICE(INTEL, 0x8d02), board_ahci }, /* Wellsburg AHCI */
- { PCI_VDEVICE(INTEL, 0x8d04), board_ahci }, /* Wellsburg RAID */
- { PCI_VDEVICE(INTEL, 0x8d06), board_ahci }, /* Wellsburg RAID */
- { PCI_VDEVICE(INTEL, 0x8d0e), board_ahci }, /* Wellsburg RAID */
- { PCI_VDEVICE(INTEL, 0x8d62), board_ahci }, /* Wellsburg AHCI */
- { PCI_VDEVICE(INTEL, 0x8d64), board_ahci }, /* Wellsburg RAID */
- { PCI_VDEVICE(INTEL, 0x8d66), board_ahci }, /* Wellsburg RAID */
- { PCI_VDEVICE(INTEL, 0x8d6e), board_ahci }, /* Wellsburg RAID */
/* JMicron 360/1/3/5/6, match class to avoid IDE function */
{ PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c
index 78283bb..174eca6 100644
--- a/drivers/ata/ata_piix.c
+++ b/drivers/ata/ata_piix.c
@@ -150,7 +150,6 @@ enum piix_controller_ids {
tolapai_sata,
piix_pata_vmw, /* PIIX4 for VMware, spurious DMA_ERR */
ich8_sata_snb,
- ich8_2port_sata_snb,
};
struct piix_map_db {
@@ -305,7 +304,7 @@ static const struct pci_device_id piix_pci_tbl[] = {
/* SATA Controller IDE (Lynx Point) */
{ 0x8086, 0x8c01, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb },
/* SATA Controller IDE (Lynx Point) */
- { 0x8086, 0x8c08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata_snb },
+ { 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 (Lynx Point-LP) */
@@ -318,23 +317,6 @@ static const struct pci_device_id piix_pci_tbl[] = {
{ 0x8086, 0x9c09, 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 },
- /* SATA Controller IDE (Avoton) */
- { 0x8086, 0x1f20, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb },
- /* SATA Controller IDE (Avoton) */
- { 0x8086, 0x1f21, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb },
- /* SATA Controller IDE (Avoton) */
- { 0x8086, 0x1f30, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
- /* SATA Controller IDE (Avoton) */
- { 0x8086, 0x1f31, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
- /* SATA Controller IDE (Wellsburg) */
- { 0x8086, 0x8d00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb },
- /* SATA Controller IDE (Wellsburg) */
- { 0x8086, 0x8d08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
- /* SATA Controller IDE (Wellsburg) */
- { 0x8086, 0x8d60, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb },
- /* SATA Controller IDE (Wellsburg) */
- { 0x8086, 0x8d68, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
-
{ } /* terminate list */
};
@@ -440,7 +422,6 @@ static const struct piix_map_db *piix_map_db_table[] = {
[ich8m_apple_sata] = &ich8m_apple_map_db,
[tolapai_sata] = &tolapai_map_db,
[ich8_sata_snb] = &ich8_map_db,
- [ich8_2port_sata_snb] = &ich8_2port_map_db,
};
static struct pci_bits piix_enable_bits[] = {
@@ -1244,16 +1225,6 @@ static struct ata_port_info piix_port_info[] = {
.udma_mask = ATA_UDMA6,
.port_ops = &piix_sata_ops,
},
-
- [ich8_2port_sata_snb] =
- {
- .flags = PIIX_SATA_FLAGS | PIIX_FLAG_SIDPR
- | PIIX_FLAG_PIO16,
- .pio_mask = ATA_PIO4,
- .mwdma_mask = ATA_MWDMA2,
- .udma_mask = ATA_UDMA6,
- .port_ops = &piix_sata_ops,
- },
};
#define AHCI_PCI_BAR 5
diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c
index cc8aa9e..ef01ac0 100644
--- a/drivers/ata/libata-acpi.c
+++ b/drivers/ata/libata-acpi.c
@@ -60,8 +60,7 @@ acpi_handle ata_ap_acpi_handle(struct ata_port *ap)
if (ap->flags & ATA_FLAG_ACPI_SATA)
return NULL;
- return ap->scsi_host ?
- DEVICE_ACPI_HANDLE(&ap->scsi_host->shost_gendev) : NULL;
+ return acpi_get_child(DEVICE_ACPI_HANDLE(ap->host->dev), ap->port_no);
}
EXPORT_SYMBOL(ata_ap_acpi_handle);
@@ -240,15 +239,28 @@ void ata_acpi_dissociate(struct ata_host *host)
}
}
-static int __ata_acpi_gtm(struct ata_port *ap, acpi_handle handle,
- struct ata_acpi_gtm *gtm)
+/**
+ * ata_acpi_gtm - execute _GTM
+ * @ap: target ATA port
+ * @gtm: out parameter for _GTM result
+ *
+ * Evaluate _GTM and store the result in @gtm.
+ *
+ * LOCKING:
+ * EH context.
+ *
+ * RETURNS:
+ * 0 on success, -ENOENT if _GTM doesn't exist, -errno on failure.
+ */
+int ata_acpi_gtm(struct ata_port *ap, struct ata_acpi_gtm *gtm)
{
struct acpi_buffer output = { .length = ACPI_ALLOCATE_BUFFER };
union acpi_object *out_obj;
acpi_status status;
int rc = 0;
- status = acpi_evaluate_object(handle, "_GTM", NULL, &output);
+ status = acpi_evaluate_object(ata_ap_acpi_handle(ap), "_GTM", NULL,
+ &output);
rc = -ENOENT;
if (status == AE_NOT_FOUND)
@@ -282,27 +294,6 @@ static int __ata_acpi_gtm(struct ata_port *ap, acpi_handle handle,
return rc;
}
-/**
- * ata_acpi_gtm - execute _GTM
- * @ap: target ATA port
- * @gtm: out parameter for _GTM result
- *
- * Evaluate _GTM and store the result in @gtm.
- *
- * LOCKING:
- * EH context.
- *
- * RETURNS:
- * 0 on success, -ENOENT if _GTM doesn't exist, -errno on failure.
- */
-int ata_acpi_gtm(struct ata_port *ap, struct ata_acpi_gtm *gtm)
-{
- if (ata_ap_acpi_handle(ap))
- return __ata_acpi_gtm(ap, ata_ap_acpi_handle(ap), gtm);
- else
- return -EINVAL;
-}
-
EXPORT_SYMBOL_GPL(ata_acpi_gtm);
/**
@@ -1104,7 +1095,7 @@ static int ata_acpi_bind_host(struct ata_port *ap, acpi_handle *handle)
if (!*handle)
return -ENODEV;
- if (__ata_acpi_gtm(ap, *handle, &ap->__acpi_init_gtm) == 0)
+ if (ata_acpi_gtm(ap, &ap->__acpi_init_gtm) == 0)
ap->pflags |= ATA_PFLAG_INIT_GTM_VALID;
return 0;
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 501c209..46cd3f4 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -2329,7 +2329,7 @@ int ata_dev_configure(struct ata_device *dev)
* from SATA Settings page of Identify Device Data Log.
*/
if (ata_id_has_devslp(dev->id)) {
- u8 *sata_setting = ap->sector_buf;
+ u8 sata_setting[ATA_SECT_SIZE];
int i, j;
dev->flags |= ATA_DFLAG_DEVSLP;
@@ -2437,9 +2437,6 @@ int ata_dev_configure(struct ata_device *dev)
dev->max_sectors = min_t(unsigned int, ATA_MAX_SECTORS_128,
dev->max_sectors);
- if (dev->horkage & ATA_HORKAGE_MAX_SEC_LBA48)
- dev->max_sectors = ATA_MAX_SECTORS_LBA48;
-
if (ap->ops->dev_config)
ap->ops->dev_config(dev);
@@ -4101,7 +4098,6 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
/* Weird ATAPI devices */
{ "TORiSAN DVD-ROM DRD-N216", NULL, ATA_HORKAGE_MAX_SEC_128 },
{ "QUANTUM DAT DAT72-000", NULL, ATA_HORKAGE_ATAPI_MOD16_DMA },
- { "Slimtype DVD A DS8A8SH", NULL, ATA_HORKAGE_MAX_SEC_LBA48 },
/* Devices we expect to fail diagnostics */
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
index ad3130d..d8af325 100644
--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -678,9 +678,9 @@ unsigned int ata_sff_data_xfer_noirq(struct ata_device *dev, unsigned char *buf,
unsigned long flags;
unsigned int consumed;
- local_irq_save_nort(flags);
+ local_irq_save(flags);
consumed = ata_sff_data_xfer32(dev, buf, buflen, rw);
- local_irq_restore_nort(flags);
+ local_irq_restore(flags);
return consumed;
}
@@ -719,7 +719,7 @@ static void ata_pio_sector(struct ata_queued_cmd *qc)
unsigned long flags;
/* FIXME: use a bounce buffer */
- local_irq_save_nort(flags);
+ local_irq_save(flags);
buf = kmap_atomic(page);
/* do the actual data transfer */
@@ -727,7 +727,7 @@ static void ata_pio_sector(struct ata_queued_cmd *qc)
do_write);
kunmap_atomic(buf);
- local_irq_restore_nort(flags);
+ local_irq_restore(flags);
} else {
buf = page_address(page);
ap->ops->sff_data_xfer(qc->dev, buf + offset, qc->sect_size,
@@ -864,7 +864,7 @@ next_sg:
unsigned long flags;
/* FIXME: use bounce buffer */
- local_irq_save_nort(flags);
+ local_irq_save(flags);
buf = kmap_atomic(page);
/* do the actual data transfer */
@@ -872,7 +872,7 @@ next_sg:
count, rw);
kunmap_atomic(buf);
- local_irq_restore_nort(flags);
+ local_irq_restore(flags);
} else {
buf = page_address(page);
consumed = ap->ops->sff_data_xfer(dev, buf + offset,
diff --git a/drivers/ata/sata_highbank.c b/drivers/ata/sata_highbank.c
index b1a664a..5dba77c 100644
--- a/drivers/ata/sata_highbank.c
+++ b/drivers/ata/sata_highbank.c
@@ -251,7 +251,7 @@ static const struct ata_port_info ahci_highbank_port_info = {
};
static struct scsi_host_template ahci_highbank_platform_sht = {
- AHCI_SHT("sata_highbank"),
+ AHCI_SHT("highbank-ahci"),
};
static const struct of_device_id ahci_of_match[] = {
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index 6856303..24eb078 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -290,7 +290,7 @@ int bus_for_each_dev(struct bus_type *bus, struct device *start,
struct device *dev;
int error = 0;
- if (!bus || !bus->p)
+ if (!bus)
return -EINVAL;
klist_iter_init_node(&bus->p->klist_devices, &i,
@@ -324,7 +324,7 @@ struct device *bus_find_device(struct bus_type *bus,
struct klist_iter i;
struct device *dev;
- if (!bus || !bus->p)
+ if (!bus)
return NULL;
klist_iter_init_node(&bus->p->klist_devices, &i,
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index 61d3e1b..e3bbed8 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -172,8 +172,6 @@ static int deferred_probe_initcall(void)
driver_deferred_probe_enable = true;
driver_deferred_probe_trigger();
- /* Sort as many dependencies as possible before exiting initcalls */
- flush_workqueue(deferred_wq);
return 0;
}
late_initcall(deferred_probe_initcall);
diff --git a/drivers/base/regmap/regcache-rbtree.c b/drivers/base/regmap/regcache-rbtree.c
index 79f4fca..e6732cf 100644
--- a/drivers/base/regmap/regcache-rbtree.c
+++ b/drivers/base/regmap/regcache-rbtree.c
@@ -398,7 +398,7 @@ static int regcache_rbtree_sync(struct regmap *map, unsigned int min,
base = 0;
if (max < rbnode->base_reg + rbnode->blklen)
- end = max - rbnode->base_reg + 1;
+ end = rbnode->base_reg + rbnode->blklen - max;
else
end = rbnode->blklen;
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index ab3a020..f00b059 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -662,12 +662,12 @@ struct regmap *regmap_init(struct device *dev,
}
}
- regmap_debugfs_init(map, config->name);
-
ret = regcache_init(map, config);
if (ret != 0)
goto err_range;
+ regmap_debugfs_init(map, config->name);
+
/* Add a devres resource for dev_get_regmap() */
m = devres_alloc(dev_get_regmap_release, sizeof(*m), GFP_KERNEL);
if (!m) {
diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c
index 92b6d7c..25ef5c0 100644
--- a/drivers/block/aoe/aoecmd.c
+++ b/drivers/block/aoe/aoecmd.c
@@ -51,9 +51,8 @@ new_skb(ulong len)
{
struct sk_buff *skb;
- skb = alloc_skb(len + MAX_HEADER, GFP_ATOMIC);
+ skb = alloc_skb(len, GFP_ATOMIC);
if (skb) {
- skb_reserve(skb, MAX_HEADER);
skb_reset_mac_header(skb);
skb_reset_network_header(skb);
skb->protocol = __constant_htons(ETH_P_AOE);
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index f74f2c0..ae12512 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -917,11 +917,6 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
lo->lo_flags |= LO_FLAGS_PARTSCAN;
if (lo->lo_flags & LO_FLAGS_PARTSCAN)
ioctl_by_bdev(bdev, BLKRRPART, 0);
-
- /* Grab the block_device to prevent its destruction after we
- * put /dev/loopXX inode. Later in loop_clr_fd() we bdput(bdev).
- */
- bdgrab(bdev);
return 0;
out_clr:
@@ -1031,10 +1026,8 @@ static int loop_clr_fd(struct loop_device *lo)
memset(lo->lo_encrypt_key, 0, LO_KEY_SIZE);
memset(lo->lo_crypt_name, 0, LO_NAME_SIZE);
memset(lo->lo_file_name, 0, LO_NAME_SIZE);
- if (bdev) {
- bdput(bdev);
+ if (bdev)
invalidate_bdev(bdev);
- }
set_capacity(lo->lo_disk, 0);
loop_sysfs_exit(lo);
if (bdev) {
@@ -1292,9 +1285,11 @@ static int loop_set_capacity(struct loop_device *lo, struct block_device *bdev)
/* the width of sector_t may be narrow for bit-shift */
sz = sec;
sz <<= 9;
+ mutex_lock(&bdev->bd_mutex);
bd_set_size(bdev, sz);
/* let user-space know about the new size */
kobject_uevent(&disk_to_dev(bdev->bd_disk)->kobj, KOBJ_CHANGE);
+ mutex_unlock(&bdev->bd_mutex);
out:
return err;
@@ -1863,15 +1858,11 @@ static int __init loop_init(void)
max_part = (1UL << part_shift) - 1;
}
- if ((1UL << part_shift) > DISK_MAX_PARTS) {
- err = -EINVAL;
- goto misc_out;
- }
+ if ((1UL << part_shift) > DISK_MAX_PARTS)
+ return -EINVAL;
- if (max_loop > 1UL << (MINORBITS - part_shift)) {
- err = -EINVAL;
- goto misc_out;
- }
+ if (max_loop > 1UL << (MINORBITS - part_shift))
+ return -EINVAL;
/*
* If max_loop is specified, create that many devices upfront.
@@ -1889,10 +1880,8 @@ static int __init loop_init(void)
range = 1UL << MINORBITS;
}
- if (register_blkdev(LOOP_MAJOR, "loop")) {
- err = -EIO;
- goto misc_out;
- }
+ if (register_blkdev(LOOP_MAJOR, "loop"))
+ return -EIO;
blk_register_region(MKDEV(LOOP_MAJOR, 0), range,
THIS_MODULE, loop_probe, NULL, NULL);
@@ -1905,10 +1894,6 @@ static int __init loop_init(void)
printk(KERN_INFO "loop: module loaded\n");
return 0;
-
-misc_out:
- misc_deregister(&loop_misc);
- return err;
}
static int loop_exit_cb(int id, void *ptr, void *data)
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index eb591fb..043ddcc 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -595,20 +595,12 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd,
struct request sreq;
dev_info(disk_to_dev(nbd->disk), "NBD_DISCONNECT\n");
- if (!nbd->sock)
- return -EINVAL;
- mutex_unlock(&nbd->tx_lock);
- fsync_bdev(bdev);
- mutex_lock(&nbd->tx_lock);
blk_rq_init(NULL, &sreq);
sreq.cmd_type = REQ_TYPE_SPECIAL;
nbd_cmd(&sreq) = NBD_CMD_DISC;
-
- /* Check again after getting mutex back. */
if (!nbd->sock)
return -EINVAL;
-
nbd_send_req(nbd, &sreq);
return 0;
}
@@ -622,7 +614,6 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd,
nbd_clear_que(nbd);
BUG_ON(!list_empty(&nbd->queue_head));
BUG_ON(!list_empty(&nbd->waiting_queue));
- kill_bdev(bdev);
if (file)
fput(file);
return 0;
@@ -711,7 +702,6 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd,
nbd->file = NULL;
nbd_clear_que(nbd);
dev_warn(disk_to_dev(nbd->disk), "queue cleared\n");
- kill_bdev(bdev);
queue_flag_clear_unlocked(QUEUE_FLAG_DISCARD, nbd->disk->queue);
if (file)
fput(file);
diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c
index ef6d9be..5ac841f 100644
--- a/drivers/block/xen-blkback/blkback.c
+++ b/drivers/block/xen-blkback/blkback.c
@@ -46,7 +46,6 @@
#include <xen/xen.h>
#include <asm/xen/hypervisor.h>
#include <asm/xen/hypercall.h>
-#include <xen/balloon.h>
#include "common.h"
/*
@@ -240,7 +239,6 @@ static void free_persistent_gnts(struct rb_root *root, unsigned int num)
ret = gnttab_unmap_refs(unmap, NULL, pages,
segs_to_unmap);
BUG_ON(ret);
- free_xenballooned_pages(segs_to_unmap, pages);
segs_to_unmap = 0;
}
@@ -529,8 +527,8 @@ static int xen_blkbk_map(struct blkif_request *req,
GFP_KERNEL);
if (!persistent_gnt)
return -ENOMEM;
- if (alloc_xenballooned_pages(1, &persistent_gnt->page,
- false)) {
+ persistent_gnt->page = alloc_page(GFP_KERNEL);
+ if (!persistent_gnt->page) {
kfree(persistent_gnt);
return -ENOMEM;
}
@@ -679,16 +677,6 @@ static int dispatch_discard_io(struct xen_blkif *blkif,
return err;
}
-static int dispatch_other_io(struct xen_blkif *blkif,
- struct blkif_request *req,
- struct pending_req *pending_req)
-{
- free_req(pending_req);
- make_response(blkif, req->u.other.id, req->operation,
- BLKIF_RSP_EOPNOTSUPP);
- return -EIO;
-}
-
static void xen_blk_drain_io(struct xen_blkif *blkif)
{
atomic_set(&blkif->drain, 1);
@@ -810,30 +798,17 @@ __do_block_io_op(struct xen_blkif *blkif)
/* Apply all sanity checks to /private copy/ of request. */
barrier();
-
- switch (req.operation) {
- case BLKIF_OP_READ:
- case BLKIF_OP_WRITE:
- case BLKIF_OP_WRITE_BARRIER:
- case BLKIF_OP_FLUSH_DISKCACHE:
- if (dispatch_rw_block_io(blkif, &req, pending_req))
- goto done;
- break;
- case BLKIF_OP_DISCARD:
+ if (unlikely(req.operation == BLKIF_OP_DISCARD)) {
free_req(pending_req);
if (dispatch_discard_io(blkif, &req))
- goto done;
+ break;
+ } else if (dispatch_rw_block_io(blkif, &req, pending_req))
break;
- default:
- if (dispatch_other_io(blkif, &req, pending_req))
- goto done;
- break;
- }
/* Yield point for this unbounded loop. */
cond_resched();
}
-done:
+
return more_to_do;
}
@@ -1001,7 +976,13 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif,
bio->bi_end_io = end_block_io_op;
}
+ /*
+ * We set it one so that the last submit_bio does not have to call
+ * atomic_inc.
+ */
atomic_set(&pending_req->pendcnt, nbio);
+
+ /* Get a reference count for the disk queue and start sending I/O */
blk_start_plug(&plug);
for (i = 0; i < nbio; i++)
@@ -1029,7 +1010,6 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif,
fail_put_bio:
for (i = 0; i < nbio; i++)
bio_put(biolist[i]);
- atomic_set(&pending_req->pendcnt, 1);
__end_block_io_op(pending_req, -EINVAL);
msleep(1); /* back off a bit */
return -EIO;
diff --git a/drivers/block/xen-blkback/common.h b/drivers/block/xen-blkback/common.h
index 195278a..6072390 100644
--- a/drivers/block/xen-blkback/common.h
+++ b/drivers/block/xen-blkback/common.h
@@ -77,18 +77,11 @@ struct blkif_x86_32_request_discard {
uint64_t nr_sectors;
} __attribute__((__packed__));
-struct blkif_x86_32_request_other {
- uint8_t _pad1;
- blkif_vdev_t _pad2;
- uint64_t id; /* private guest value, echoed in resp */
-} __attribute__((__packed__));
-
struct blkif_x86_32_request {
uint8_t operation; /* BLKIF_OP_??? */
union {
struct blkif_x86_32_request_rw rw;
struct blkif_x86_32_request_discard discard;
- struct blkif_x86_32_request_other other;
} u;
} __attribute__((__packed__));
@@ -120,19 +113,11 @@ struct blkif_x86_64_request_discard {
uint64_t nr_sectors;
} __attribute__((__packed__));
-struct blkif_x86_64_request_other {
- uint8_t _pad1;
- blkif_vdev_t _pad2;
- uint32_t _pad3; /* offsetof(blkif_..,u.discard.id)==8 */
- uint64_t id; /* private guest value, echoed in resp */
-} __attribute__((__packed__));
-
struct blkif_x86_64_request {
uint8_t operation; /* BLKIF_OP_??? */
union {
struct blkif_x86_64_request_rw rw;
struct blkif_x86_64_request_discard discard;
- struct blkif_x86_64_request_other other;
} u;
} __attribute__((__packed__));
@@ -293,11 +278,6 @@ static inline void blkif_get_x86_32_req(struct blkif_request *dst,
dst->u.discard.nr_sectors = src->u.discard.nr_sectors;
break;
default:
- /*
- * Don't know how to translate this op. Only get the
- * ID so failure can be reported to the frontend.
- */
- dst->u.other.id = src->u.other.id;
break;
}
}
@@ -329,11 +309,6 @@ static inline void blkif_get_x86_64_req(struct blkif_request *dst,
dst->u.discard.nr_sectors = src->u.discard.nr_sectors;
break;
default:
- /*
- * Don't know how to translate this op. Only get the
- * ID so failure can be reported to the frontend.
- */
- dst->u.other.id = src->u.other.id;
break;
}
}
diff --git a/drivers/block/xen-blkback/xenbus.c b/drivers/block/xen-blkback/xenbus.c
index 5e237f6..6398072 100644
--- a/drivers/block/xen-blkback/xenbus.c
+++ b/drivers/block/xen-blkback/xenbus.c
@@ -367,7 +367,6 @@ static int xen_blkbk_remove(struct xenbus_device *dev)
be->blkif = NULL;
}
- kfree(be->mode);
kfree(be);
dev_set_drvdata(&dev->dev, NULL);
return 0;
@@ -503,7 +502,6 @@ static void backend_changed(struct xenbus_watch *watch,
= container_of(watch, struct backend_info, backend_watch);
struct xenbus_device *dev = be->dev;
int cdrom = 0;
- unsigned long handle;
char *device_type;
DPRINTK("");
@@ -523,10 +521,10 @@ static void backend_changed(struct xenbus_watch *watch,
return;
}
- if (be->major | be->minor) {
- if (be->major != major || be->minor != minor)
- pr_warn(DRV_PFX "changing physical device (from %x:%x to %x:%x) not supported.\n",
- be->major, be->minor, major, minor);
+ if ((be->major || be->minor) &&
+ ((be->major != major) || (be->minor != minor))) {
+ pr_warn(DRV_PFX "changing physical device (from %x:%x to %x:%x) not supported.\n",
+ be->major, be->minor, major, minor);
return;
}
@@ -544,33 +542,36 @@ static void backend_changed(struct xenbus_watch *watch,
kfree(device_type);
}
- /* Front end dir is a number, which is used as the handle. */
- err = strict_strtoul(strrchr(dev->otherend, '/') + 1, 0, &handle);
- if (err)
- return;
+ if (be->major == 0 && be->minor == 0) {
+ /* Front end dir is a number, which is used as the handle. */
- be->major = major;
- be->minor = minor;
+ char *p = strrchr(dev->otherend, '/') + 1;
+ long handle;
+ err = strict_strtoul(p, 0, &handle);
+ if (err)
+ return;
- err = xen_vbd_create(be->blkif, handle, major, minor,
- !strchr(be->mode, 'w'), cdrom);
+ be->major = major;
+ be->minor = minor;
+
+ err = xen_vbd_create(be->blkif, handle, major, minor,
+ (NULL == strchr(be->mode, 'w')), cdrom);
+ if (err) {
+ be->major = 0;
+ be->minor = 0;
+ xenbus_dev_fatal(dev, err, "creating vbd structure");
+ return;
+ }
- if (err)
- xenbus_dev_fatal(dev, err, "creating vbd structure");
- else {
err = xenvbd_sysfs_addif(dev);
if (err) {
xen_vbd_free(&be->blkif->vbd);
+ be->major = 0;
+ be->minor = 0;
xenbus_dev_fatal(dev, err, "creating sysfs entries");
+ return;
}
- }
- if (err) {
- kfree(be->mode);
- be->mode = NULL;
- be->major = 0;
- be->minor = 0;
- } else {
/* We're potentially connected now */
xen_update_blkif_status(be->blkif);
}
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
index 2e39eaf..11043c1 100644
--- a/drivers/block/xen-blkfront.c
+++ b/drivers/block/xen-blkfront.c
@@ -44,7 +44,7 @@
#include <linux/mutex.h>
#include <linux/scatterlist.h>
#include <linux/bitmap.h>
-#include <linux/list.h>
+#include <linux/llist.h>
#include <xen/xen.h>
#include <xen/xenbus.h>
@@ -68,7 +68,7 @@ enum blkif_state {
struct grant {
grant_ref_t gref;
unsigned long pfn;
- struct list_head node;
+ struct llist_node node;
};
struct blk_shadow {
@@ -105,7 +105,7 @@ struct blkfront_info
struct work_struct work;
struct gnttab_free_callback callback;
struct blk_shadow shadow[BLK_RING_SIZE];
- struct list_head persistent_gnts;
+ struct llist_head persistent_gnts;
unsigned int persistent_gnts_c;
unsigned long shadow_free;
unsigned int feature_flush;
@@ -371,11 +371,10 @@ static int blkif_queue_request(struct request *req)
lsect = fsect + (sg->length >> 9) - 1;
if (info->persistent_gnts_c) {
- BUG_ON(list_empty(&info->persistent_gnts));
- gnt_list_entry = list_first_entry(
- &info->persistent_gnts,
- struct grant, node);
- list_del(&gnt_list_entry->node);
+ BUG_ON(llist_empty(&info->persistent_gnts));
+ gnt_list_entry = llist_entry(
+ llist_del_first(&info->persistent_gnts),
+ struct grant, node);
ref = gnt_list_entry->gref;
buffer_mfn = pfn_to_mfn(gnt_list_entry->pfn);
@@ -791,8 +790,9 @@ static void blkif_restart_queue(struct work_struct *work)
static void blkif_free(struct blkfront_info *info, int suspend)
{
+ struct llist_node *all_gnts;
struct grant *persistent_gnt;
- struct grant *n;
+ struct llist_node *n;
/* Prevent new requests being issued until we fix things up. */
spin_lock_irq(&info->io_lock);
@@ -804,15 +804,13 @@ static void blkif_free(struct blkfront_info *info, int suspend)
/* Remove all persistent grants */
if (info->persistent_gnts_c) {
- list_for_each_entry_safe(persistent_gnt, n,
- &info->persistent_gnts, node) {
- list_del(&persistent_gnt->node);
+ all_gnts = llist_del_all(&info->persistent_gnts);
+ llist_for_each_entry_safe(persistent_gnt, n, all_gnts, node) {
gnttab_end_foreign_access(persistent_gnt->gref, 0, 0UL);
__free_page(pfn_to_page(persistent_gnt->pfn));
kfree(persistent_gnt);
- info->persistent_gnts_c--;
}
- BUG_ON(info->persistent_gnts_c != 0);
+ info->persistent_gnts_c = 0;
}
/* No more gnttab callback work. */
@@ -870,7 +868,7 @@ static void blkif_completion(struct blk_shadow *s, struct blkfront_info *info,
}
/* Add the persistent grant into the list of free grants */
for (i = 0; i < s->req.u.rw.nr_segments; i++) {
- list_add(&s->grants_used[i]->node, &info->persistent_gnts);
+ llist_add(&s->grants_used[i]->node, &info->persistent_gnts);
info->persistent_gnts_c++;
}
}
@@ -1166,7 +1164,7 @@ static int blkfront_probe(struct xenbus_device *dev,
spin_lock_init(&info->io_lock);
info->xbdev = dev;
info->vdevice = vdevice;
- INIT_LIST_HEAD(&info->persistent_gnts);
+ init_llist_head(&info->persistent_gnts);
info->persistent_gnts_c = 0;
info->connected = BLKIF_STATE_DISCONNECTED;
INIT_WORK(&info->work, blkif_restart_queue);
diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c
index 1c0929b..33c9a44 100644
--- a/drivers/bluetooth/ath3k.c
+++ b/drivers/bluetooth/ath3k.c
@@ -73,10 +73,8 @@ static struct usb_device_id ath3k_table[] = {
{ USB_DEVICE(0x03F0, 0x311D) },
/* Atheros AR3012 with sflash firmware*/
- { USB_DEVICE(0x0CF3, 0x0036) },
{ USB_DEVICE(0x0CF3, 0x3004) },
{ USB_DEVICE(0x0CF3, 0x311D) },
- { USB_DEVICE(0x0CF3, 0x817a) },
{ USB_DEVICE(0x13d3, 0x3375) },
{ USB_DEVICE(0x04CA, 0x3005) },
{ USB_DEVICE(0x04CA, 0x3006) },
@@ -107,10 +105,8 @@ MODULE_DEVICE_TABLE(usb, ath3k_table);
static struct usb_device_id ath3k_blist_tbl[] = {
/* Atheros AR3012 with sflash firmware*/
- { USB_DEVICE(0x0CF3, 0x0036), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0x311D), .driver_info = BTUSB_ATH3012 },
- { USB_DEVICE(0x0CF3, 0x817a), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x04ca, 0x3006), .driver_info = BTUSB_ATH3012 },
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 568e703..7e351e3 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -131,10 +131,8 @@ static struct usb_device_id blacklist_table[] = {
{ USB_DEVICE(0x03f0, 0x311d), .driver_info = BTUSB_IGNORE },
/* Atheros 3012 with sflash firmware */
- { USB_DEVICE(0x0cf3, 0x0036), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0x311d), .driver_info = BTUSB_ATH3012 },
- { USB_DEVICE(0x0cf3, 0x817a), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x04ca, 0x3006), .driver_info = BTUSB_ATH3012 },
diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c
index 615d262..fe6d4be 100644
--- a/drivers/char/hpet.c
+++ b/drivers/char/hpet.c
@@ -373,14 +373,26 @@ static int hpet_mmap(struct file *file, struct vm_area_struct *vma)
struct hpet_dev *devp;
unsigned long addr;
+ if (((vma->vm_end - vma->vm_start) != PAGE_SIZE) || vma->vm_pgoff)
+ return -EINVAL;
+
devp = file->private_data;
addr = devp->hd_hpets->hp_hpet_phys;
if (addr & (PAGE_SIZE - 1))
return -ENOSYS;
+ vma->vm_flags |= VM_IO;
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
- return vm_iomap_memory(vma, addr, PAGE_SIZE);
+
+ if (io_remap_pfn_range(vma, vma->vm_start, addr >> PAGE_SHIFT,
+ PAGE_SIZE, vma->vm_page_prot)) {
+ printk(KERN_ERR "%s: io_remap_pfn_range failed\n",
+ __func__);
+ return -EAGAIN;
+ }
+
+ return 0;
#else
return -ENOSYS;
#endif
diff --git a/drivers/char/hw_random/core.c b/drivers/char/hw_random/core.c
index 69ae597..1bafb40 100644
--- a/drivers/char/hw_random/core.c
+++ b/drivers/char/hw_random/core.c
@@ -40,7 +40,6 @@
#include <linux/init.h>
#include <linux/miscdevice.h>
#include <linux/delay.h>
-#include <linux/slab.h>
#include <asm/uaccess.h>
@@ -53,12 +52,8 @@ static struct hwrng *current_rng;
static LIST_HEAD(rng_list);
static DEFINE_MUTEX(rng_mutex);
static int data_avail;
-static u8 *rng_buffer;
-
-static size_t rng_buffer_size(void)
-{
- return SMP_CACHE_BYTES < 32 ? 32 : SMP_CACHE_BYTES;
-}
+static u8 rng_buffer[SMP_CACHE_BYTES < 32 ? 32 : SMP_CACHE_BYTES]
+ __cacheline_aligned;
static inline int hwrng_init(struct hwrng *rng)
{
@@ -121,7 +116,7 @@ static ssize_t rng_dev_read(struct file *filp, char __user *buf,
if (!data_avail) {
bytes_read = rng_get_data(current_rng, rng_buffer,
- rng_buffer_size(),
+ sizeof(rng_buffer),
!(filp->f_flags & O_NONBLOCK));
if (bytes_read < 0) {
err = bytes_read;
@@ -312,14 +307,6 @@ int hwrng_register(struct hwrng *rng)
mutex_lock(&rng_mutex);
- /* kmalloc makes this safe for virt_to_page() in virtio_rng.c */
- err = -ENOMEM;
- if (!rng_buffer) {
- rng_buffer = kmalloc(rng_buffer_size(), GFP_KERNEL);
- if (!rng_buffer)
- goto out_unlock;
- }
-
/* Must not register two RNGs with the same name. */
err = -EEXIST;
list_for_each_entry(tmp, &rng_list, list) {
diff --git a/drivers/char/hw_random/virtio-rng.c b/drivers/char/hw_random/virtio-rng.c
index 1acc4e0..b65c103 100644
--- a/drivers/char/hw_random/virtio-rng.c
+++ b/drivers/char/hw_random/virtio-rng.c
@@ -92,22 +92,14 @@ static int probe_common(struct virtio_device *vdev)
{
int err;
- if (vq) {
- /* We only support one device for now */
- return -EBUSY;
- }
/* We expect a single virtqueue. */
vq = virtio_find_single_vq(vdev, random_recv_done, "input");
- if (IS_ERR(vq)) {
- err = PTR_ERR(vq);
- vq = NULL;
- return err;
- }
+ if (IS_ERR(vq))
+ return PTR_ERR(vq);
err = hwrng_register(&virtio_hwrng);
if (err) {
vdev->config->del_vqs(vdev);
- vq = NULL;
return err;
}
@@ -120,7 +112,6 @@ static void remove_common(struct virtio_device *vdev)
busy = false;
hwrng_unregister(&virtio_hwrng);
vdev->config->del_vqs(vdev);
- vq = NULL;
}
static int virtrng_probe(struct virtio_device *vdev)
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 9d6c416..85e81ec 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -445,7 +445,7 @@ static struct entropy_store input_pool = {
.poolinfo = &poolinfo_table[0],
.name = "input",
.limit = 1,
- .lock = __SPIN_LOCK_UNLOCKED(input_pool.lock),
+ .lock = __SPIN_LOCK_UNLOCKED(&input_pool.lock),
.pool = input_pool_data
};
@@ -454,7 +454,7 @@ static struct entropy_store blocking_pool = {
.name = "blocking",
.limit = 1,
.pull = &input_pool,
- .lock = __SPIN_LOCK_UNLOCKED(blocking_pool.lock),
+ .lock = __SPIN_LOCK_UNLOCKED(&blocking_pool.lock),
.pool = blocking_pool_data
};
@@ -462,7 +462,7 @@ static struct entropy_store nonblocking_pool = {
.poolinfo = &poolinfo_table[1],
.name = "nonblocking",
.pull = &input_pool,
- .lock = __SPIN_LOCK_UNLOCKED(nonblocking_pool.lock),
+ .lock = __SPIN_LOCK_UNLOCKED(&nonblocking_pool.lock),
.pool = nonblocking_pool_data
};
@@ -676,12 +676,9 @@ static void add_timer_randomness(struct timer_rand_state *state, unsigned num)
preempt_disable();
/* if over the trickle threshold, use only 1 in 4096 samples */
if (input_pool.entropy_count > trickle_thresh &&
- ((__this_cpu_inc_return(trickle_count) - 1) & 0xfff)) {
- preempt_enable();
- return;
- }
+ ((__this_cpu_inc_return(trickle_count) - 1) & 0xfff))
+ goto out;
- preempt_enable();
sample.jiffies = jiffies;
sample.cycles = get_cycles();
sample.num = num;
@@ -722,6 +719,8 @@ static void add_timer_randomness(struct timer_rand_state *state, unsigned num)
credit_entropy_bits(&input_pool,
min_t(int, fls(delta>>1), 11));
}
+out:
+ preempt_enable();
}
void add_input_randomness(unsigned int type, unsigned int code,
@@ -742,16 +741,18 @@ EXPORT_SYMBOL_GPL(add_input_randomness);
static DEFINE_PER_CPU(struct fast_pool, irq_randomness);
-void add_interrupt_randomness(int irq, int irq_flags, __u64 ip)
+void add_interrupt_randomness(int irq, int irq_flags)
{
struct entropy_store *r;
struct fast_pool *fast_pool = &__get_cpu_var(irq_randomness);
+ struct pt_regs *regs = get_irq_regs();
unsigned long now = jiffies;
__u32 input[4], cycles = get_cycles();
input[0] = cycles ^ jiffies;
input[1] = irq;
- if (ip) {
+ if (regs) {
+ __u64 ip = instruction_pointer(regs);
input[2] = ip;
input[3] = ip >> 32;
}
@@ -765,11 +766,7 @@ void add_interrupt_randomness(int irq, int irq_flags, __u64 ip)
fast_pool->last = now;
r = nonblocking_pool.initialized ? &input_pool : &nonblocking_pool;
-#ifndef CONFIG_PREEMPT_RT_FULL
__mix_pool_bytes(r, &fast_pool->pool, sizeof(fast_pool->pool), NULL);
-#else
- mix_pool_bytes(r, &fast_pool->pool, sizeof(fast_pool->pool), NULL);
-#endif
/*
* If we don't have a valid cycle counter, and we see
* back-to-back timer interrupts, then skip giving credit for
@@ -855,7 +852,6 @@ static size_t account(struct entropy_store *r, size_t nbytes, int min,
int reserved)
{
unsigned long flags;
- int wakeup_write = 0;
/* Hold lock while accounting */
spin_lock_irqsave(&r->lock, flags);
@@ -877,8 +873,10 @@ static size_t account(struct entropy_store *r, size_t nbytes, int min,
else
r->entropy_count = reserved;
- if (r->entropy_count < random_write_wakeup_thresh)
- wakeup_write = 1;
+ if (r->entropy_count < random_write_wakeup_thresh) {
+ wake_up_interruptible(&random_write_wait);
+ kill_fasync(&fasync, SIGIO, POLL_OUT);
+ }
}
DEBUG_ENT("debiting %zu entropy credits from %s%s\n",
@@ -886,11 +884,6 @@ static size_t account(struct entropy_store *r, size_t nbytes, int min,
spin_unlock_irqrestore(&r->lock, flags);
- if (wakeup_write) {
- wake_up_interruptible(&random_write_wait);
- kill_fasync(&fasync, SIGIO, POLL_OUT);
- }
-
return nbytes;
}
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c
index ba780b7..93211df 100644
--- a/drivers/char/tpm/tpm.c
+++ b/drivers/char/tpm/tpm.c
@@ -1291,7 +1291,7 @@ int tpm_pm_suspend(struct device *dev)
{
struct tpm_chip *chip = dev_get_drvdata(dev);
struct tpm_cmd_t cmd;
- int rc, try;
+ int rc;
u8 dummy_hash[TPM_DIGEST_SIZE] = { 0 };
@@ -1309,32 +1309,9 @@ int tpm_pm_suspend(struct device *dev)
}
/* now do the actual savestate */
- for (try = 0; try < TPM_RETRY; try++) {
- cmd.header.in = savestate_header;
- rc = transmit_cmd(chip, &cmd, SAVESTATE_RESULT_SIZE, NULL);
-
- /*
- * If the TPM indicates that it is too busy to respond to
- * this command then retry before giving up. It can take
- * several seconds for this TPM to be ready.
- *
- * This can happen if the TPM has already been sent the
- * SaveState command before the driver has loaded. TCG 1.2
- * specification states that any communication after SaveState
- * may cause the TPM to invalidate previously saved state.
- */
- if (rc != TPM_WARN_RETRY)
- break;
- msleep(TPM_TIMEOUT_RETRY);
- }
-
- if (rc)
- dev_err(chip->dev,
- "Error (%d) sending savestate before suspend\n", rc);
- else if (try > 0)
- dev_warn(chip->dev, "TPM savestate took %dms\n",
- try * TPM_TIMEOUT_RETRY);
-
+ cmd.header.in = savestate_header;
+ rc = transmit_cmd(chip, &cmd, SAVESTATE_RESULT_SIZE,
+ "sending savestate before suspend");
return rc;
}
EXPORT_SYMBOL_GPL(tpm_pm_suspend);
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 9c12a52..8ef7649 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -32,12 +32,10 @@ enum tpm_const {
TPM_MINOR = 224, /* officially assigned */
TPM_BUFSIZE = 4096,
TPM_NUM_DEVICES = 256,
- TPM_RETRY = 50, /* 5 seconds */
};
enum tpm_timeout {
TPM_TIMEOUT = 5, /* msecs */
- TPM_TIMEOUT_RETRY = 100 /* msecs */
};
/* TPM addresses */
@@ -46,7 +44,6 @@ enum tpm_addr {
TPM_ADDR = 0x4E,
};
-#define TPM_WARN_RETRY 0x800
#define TPM_WARN_DOING_SELFTEST 0x802
#define TPM_ERR_DEACTIVATED 0x6
#define TPM_ERR_DISABLED 0x7
diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
index a4b7aa0..ee4dbea 100644
--- a/drivers/char/virtio_console.c
+++ b/drivers/char/virtio_console.c
@@ -152,8 +152,7 @@ struct ports_device {
spinlock_t ports_lock;
/* To protect the vq operations for the control channel */
- spinlock_t c_ivq_lock;
- spinlock_t c_ovq_lock;
+ spinlock_t cvq_lock;
/* The current config space is stored here */
struct virtio_console_config config;
@@ -576,14 +575,11 @@ static ssize_t __send_control_msg(struct ports_device *portdev, u32 port_id,
vq = portdev->c_ovq;
sg_init_one(sg, &cpkt, sizeof(cpkt));
-
- spin_lock(&portdev->c_ovq_lock);
if (virtqueue_add_buf(vq, sg, 1, 0, &cpkt, GFP_ATOMIC) == 0) {
virtqueue_kick(vq);
while (!virtqueue_get_buf(vq, &len))
cpu_relax();
}
- spin_unlock(&portdev->c_ovq_lock);
return 0;
}
@@ -1719,23 +1715,23 @@ static void control_work_handler(struct work_struct *work)
portdev = container_of(work, struct ports_device, control_work);
vq = portdev->c_ivq;
- spin_lock(&portdev->c_ivq_lock);
+ spin_lock(&portdev->cvq_lock);
while ((buf = virtqueue_get_buf(vq, &len))) {
- spin_unlock(&portdev->c_ivq_lock);
+ spin_unlock(&portdev->cvq_lock);
buf->len = len;
buf->offset = 0;
handle_control_message(portdev, buf);
- spin_lock(&portdev->c_ivq_lock);
+ spin_lock(&portdev->cvq_lock);
if (add_inbuf(portdev->c_ivq, buf) < 0) {
dev_warn(&portdev->vdev->dev,
"Error adding buffer to queue\n");
free_buf(buf, false);
}
}
- spin_unlock(&portdev->c_ivq_lock);
+ spin_unlock(&portdev->cvq_lock);
}
static void out_intr(struct virtqueue *vq)
@@ -2000,12 +1996,10 @@ static int virtcons_probe(struct virtio_device *vdev)
if (multiport) {
unsigned int nr_added_bufs;
- spin_lock_init(&portdev->c_ivq_lock);
- spin_lock_init(&portdev->c_ovq_lock);
+ spin_lock_init(&portdev->cvq_lock);
INIT_WORK(&portdev->control_work, &control_work_handler);
- nr_added_bufs = fill_queue(portdev->c_ivq,
- &portdev->c_ivq_lock);
+ nr_added_bufs = fill_queue(portdev->c_ivq, &portdev->cvq_lock);
if (!nr_added_bufs) {
dev_err(&vdev->dev,
"Error allocating buffers for control queue\n");
@@ -2156,7 +2150,7 @@ static int virtcons_restore(struct virtio_device *vdev)
return ret;
if (use_multiport(portdev))
- fill_queue(portdev->c_ivq, &portdev->c_ivq_lock);
+ fill_queue(portdev->c_ivq, &portdev->cvq_lock);
list_for_each_entry(port, &portdev->ports, list) {
port->in_vq = portdev->in_vqs[port->id];
diff --git a/drivers/clocksource/tcb_clksrc.c b/drivers/clocksource/tcb_clksrc.c
index ac0bb2e..32cb929 100644
--- a/drivers/clocksource/tcb_clksrc.c
+++ b/drivers/clocksource/tcb_clksrc.c
@@ -23,7 +23,8 @@
* this 32 bit free-running counter. the second channel is not used.
*
* - The third channel may be used to provide a 16-bit clockevent
- * source, used in either periodic or oneshot mode.
+ * source, used in either periodic or oneshot mode. This runs
+ * at 32 KiHZ, and can handle delays of up to two seconds.
*
* A boot clocksource and clockevent source are also currently needed,
* unless the relevant platforms (ARM/AT91, AVR32/AT32) are changed so
@@ -73,7 +74,6 @@ static struct clocksource clksrc = {
struct tc_clkevt_device {
struct clock_event_device clkevt;
struct clk *clk;
- u32 freq;
void __iomem *regs;
};
@@ -82,6 +82,13 @@ static struct tc_clkevt_device *to_tc_clkevt(struct clock_event_device *clkevt)
return container_of(clkevt, struct tc_clkevt_device, clkevt);
}
+/* For now, we always use the 32K clock ... this optimizes for NO_HZ,
+ * because using one of the divided clocks would usually mean the
+ * tick rate can never be less than several dozen Hz (vs 0.5 Hz).
+ *
+ * A divided clock could be good for high resolution timers, since
+ * 30.5 usec resolution can seem "low".
+ */
static u32 timer_clock;
static void tc_mode(enum clock_event_mode m, struct clock_event_device *d)
@@ -104,12 +111,11 @@ static void tc_mode(enum clock_event_mode m, struct clock_event_device *d)
case CLOCK_EVT_MODE_PERIODIC:
clk_enable(tcd->clk);
- /* count up to RC, then irq and restart */
+ /* slow clock, count up to RC, then irq and restart */
__raw_writel(timer_clock
| ATMEL_TC_WAVE | ATMEL_TC_WAVESEL_UP_AUTO,
regs + ATMEL_TC_REG(2, CMR));
- __raw_writel((tcd->freq + HZ/2)/HZ,
- tcaddr + ATMEL_TC_REG(2, RC));
+ __raw_writel((32768 + HZ/2) / HZ, tcaddr + ATMEL_TC_REG(2, RC));
/* Enable clock and interrupts on RC compare */
__raw_writel(ATMEL_TC_CPCS, regs + ATMEL_TC_REG(2, IER));
@@ -122,7 +128,7 @@ static void tc_mode(enum clock_event_mode m, struct clock_event_device *d)
case CLOCK_EVT_MODE_ONESHOT:
clk_enable(tcd->clk);
- /* count up to RC, then irq and stop */
+ /* slow clock, count up to RC, then irq and stop */
__raw_writel(timer_clock | ATMEL_TC_CPCSTOP
| ATMEL_TC_WAVE | ATMEL_TC_WAVESEL_UP_AUTO,
regs + ATMEL_TC_REG(2, CMR));
@@ -152,12 +158,8 @@ static struct tc_clkevt_device clkevt = {
.features = CLOCK_EVT_FEAT_PERIODIC
| CLOCK_EVT_FEAT_ONESHOT,
.shift = 32,
-#ifdef CONFIG_ATMEL_TCB_CLKSRC_USE_SLOW_CLOCK
/* Should be lower than at91rm9200's system timer */
.rating = 125,
-#else
- .rating = 200,
-#endif
.set_next_event = tc_next_event,
.set_mode = tc_mode,
},
@@ -183,9 +185,8 @@ static struct irqaction tc_irqaction = {
.handler = ch2_irq,
};
-static void __init setup_clkevents(struct atmel_tc *tc, int divisor_idx)
+static void __init setup_clkevents(struct atmel_tc *tc, int clk32k_divisor_idx)
{
- unsigned divisor = atmel_tc_divisors[divisor_idx];
struct clk *t2_clk = tc->clk[2];
int irq = tc->irq[2];
@@ -193,17 +194,11 @@ static void __init setup_clkevents(struct atmel_tc *tc, int divisor_idx)
clkevt.clk = t2_clk;
tc_irqaction.dev_id = &clkevt;
- timer_clock = divisor_idx;
+ timer_clock = clk32k_divisor_idx;
- if (!divisor)
- clkevt.freq = 32768;
- else
- clkevt.freq = clk_get_rate(t2_clk)/divisor;
-
- clkevt.clkevt.mult = div_sc(clkevt.freq, NSEC_PER_SEC,
- clkevt.clkevt.shift);
- clkevt.clkevt.max_delta_ns =
- clockevent_delta2ns(0xffff, &clkevt.clkevt);
+ clkevt.clkevt.mult = div_sc(32768, NSEC_PER_SEC, clkevt.clkevt.shift);
+ clkevt.clkevt.max_delta_ns
+ = clockevent_delta2ns(0xffff, &clkevt.clkevt);
clkevt.clkevt.min_delta_ns = clockevent_delta2ns(1, &clkevt.clkevt) + 1;
clkevt.clkevt.cpumask = cpumask_of(0);
@@ -332,11 +327,8 @@ static int __init tcb_clksrc_init(void)
clocksource_register_hz(&clksrc, divided_rate);
/* channel 2: periodic and oneshot timer support */
-#ifdef CONFIG_ATMEL_TCB_CLKSRC_USE_SLOW_CLOCK
setup_clkevents(tc, clk32k_divisor_idx);
-#else
- setup_clkevents(tc, best_divisor_idx);
-#endif
+
return 0;
}
arch_initcall(tcb_clksrc_init);
diff --git a/drivers/connector/cn_proc.c b/drivers/connector/cn_proc.c
index 1110478..fce2000 100644
--- a/drivers/connector/cn_proc.c
+++ b/drivers/connector/cn_proc.c
@@ -313,12 +313,6 @@ static void cn_proc_mcast_ctl(struct cn_msg *msg,
(task_active_pid_ns(current) != &init_pid_ns))
return;
- /* Can only change if privileged. */
- if (!capable(CAP_NET_ADMIN)) {
- err = EPERM;
- goto out;
- }
-
mc_op = (enum proc_cn_mcast_op *)msg->data;
switch (*mc_op) {
case PROC_CN_MCAST_LISTEN:
@@ -331,8 +325,6 @@ static void cn_proc_mcast_ctl(struct cn_msg *msg,
err = EINVAL;
break;
}
-
-out:
cn_proc_ack(err, msg->seq, msg->ack);
}
diff --git a/drivers/cpufreq/exynos-cpufreq.c b/drivers/cpufreq/exynos-cpufreq.c
index 41fc550..7012ea8 100644
--- a/drivers/cpufreq/exynos-cpufreq.c
+++ b/drivers/cpufreq/exynos-cpufreq.c
@@ -222,6 +222,8 @@ static int exynos_cpufreq_cpu_init(struct cpufreq_policy *policy)
cpufreq_frequency_table_get_attr(exynos_info->freq_table, policy->cpu);
+ locking_frequency = exynos_getspeed(0);
+
/* set the transition latency value */
policy->cpuinfo.transition_latency = 100000;
@@ -286,8 +288,6 @@ static int __init exynos_cpufreq_init(void)
goto err_vdd_arm;
}
- locking_frequency = exynos_getspeed(0);
-
register_pm_notifier(&exynos_cpufreq_nb);
if (cpufreq_register_driver(&exynos_driver)) {
diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c
index cf268b1..b2a0a07 100644
--- a/drivers/crypto/caam/caamalg.c
+++ b/drivers/crypto/caam/caamalg.c
@@ -1650,7 +1650,11 @@ struct caam_alg_template {
};
static struct caam_alg_template driver_algs[] = {
- /* single-pass ipsec_esp descriptor */
+ /*
+ * single-pass ipsec_esp descriptor
+ * authencesn(*,*) is also registered, although not present
+ * explicitly here.
+ */
{
.name = "authenc(hmac(md5),cbc(aes))",
.driver_name = "authenc-hmac-md5-cbc-aes-caam",
@@ -2213,7 +2217,9 @@ static int __init caam_algapi_init(void)
for (i = 0; i < ARRAY_SIZE(driver_algs); i++) {
/* TODO: check if h/w supports alg */
struct caam_crypto_alg *t_alg;
+ bool done = false;
+authencesn:
t_alg = caam_alg_alloc(ctrldev, &driver_algs[i]);
if (IS_ERR(t_alg)) {
err = PTR_ERR(t_alg);
@@ -2227,8 +2233,25 @@ static int __init caam_algapi_init(void)
dev_warn(ctrldev, "%s alg registration failed\n",
t_alg->crypto_alg.cra_driver_name);
kfree(t_alg);
- } else
+ } else {
list_add_tail(&t_alg->entry, &priv->alg_list);
+ if (driver_algs[i].type == CRYPTO_ALG_TYPE_AEAD &&
+ !memcmp(driver_algs[i].name, "authenc", 7) &&
+ !done) {
+ char *name;
+
+ name = driver_algs[i].name;
+ memmove(name + 10, name + 7, strlen(name) - 7);
+ memcpy(name + 7, "esn", 3);
+
+ name = driver_algs[i].driver_name;
+ memmove(name + 10, name + 7, strlen(name) - 7);
+ memcpy(name + 7, "esn", 3);
+
+ done = true;
+ goto authencesn;
+ }
+ }
}
if (!list_empty(&priv->alg_list))
dev_info(ctrldev, "%s algorithms registered in /proc/crypto\n",
diff --git a/drivers/crypto/caam/compat.h b/drivers/crypto/caam/compat.h
index 762aeff..cf15e78 100644
--- a/drivers/crypto/caam/compat.h
+++ b/drivers/crypto/caam/compat.h
@@ -23,6 +23,7 @@
#include <linux/types.h>
#include <linux/debugfs.h>
#include <linux/circ_buf.h>
+#include <linux/string.h>
#include <net/xfrm.h>
#include <crypto/algapi.h>
diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index 5b2b5e6..09b184a 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -38,6 +38,7 @@
#include <linux/spinlock.h>
#include <linux/rtnetlink.h>
#include <linux/slab.h>
+#include <linux/string.h>
#include <crypto/algapi.h>
#include <crypto/aes.h>
@@ -1973,7 +1974,11 @@ struct talitos_alg_template {
};
static struct talitos_alg_template driver_algs[] = {
- /* AEAD algorithms. These use a single-pass ipsec_esp descriptor */
+ /*
+ * AEAD algorithms. These use a single-pass ipsec_esp descriptor.
+ * authencesn(*,*) is also registered, although not present
+ * explicitly here.
+ */
{ .type = CRYPTO_ALG_TYPE_AEAD,
.alg.crypto = {
.cra_name = "authenc(hmac(sha1),cbc(aes))",
@@ -2815,7 +2820,9 @@ static int talitos_probe(struct platform_device *ofdev)
if (hw_supports(dev, driver_algs[i].desc_hdr_template)) {
struct talitos_crypto_alg *t_alg;
char *name = NULL;
+ bool authenc = false;
+authencesn:
t_alg = talitos_alg_alloc(dev, &driver_algs[i]);
if (IS_ERR(t_alg)) {
err = PTR_ERR(t_alg);
@@ -2830,6 +2837,8 @@ static int talitos_probe(struct platform_device *ofdev)
err = crypto_register_alg(
&t_alg->algt.alg.crypto);
name = t_alg->algt.alg.crypto.cra_driver_name;
+ authenc = authenc ? !authenc :
+ !(bool)memcmp(name, "authenc", 7);
break;
case CRYPTO_ALG_TYPE_AHASH:
err = crypto_register_ahash(
@@ -2842,8 +2851,25 @@ static int talitos_probe(struct platform_device *ofdev)
dev_err(dev, "%s alg registration failed\n",
name);
kfree(t_alg);
- } else
+ } else {
list_add_tail(&t_alg->entry, &priv->alg_list);
+ if (authenc) {
+ struct crypto_alg *alg =
+ &driver_algs[i].alg.crypto;
+
+ name = alg->cra_name;
+ memmove(name + 10, name + 7,
+ strlen(name) - 7);
+ memcpy(name + 7, "esn", 3);
+
+ name = alg->cra_driver_name;
+ memmove(name + 10, name + 7,
+ strlen(name) - 7);
+ memcpy(name + 7, "esn", 3);
+
+ goto authencesn;
+ }
+ }
}
}
if (!list_empty(&priv->alg_list))
diff --git a/drivers/crypto/ux500/cryp/cryp_core.c b/drivers/crypto/ux500/cryp/cryp_core.c
index 22c9063..8bc5fef 100644
--- a/drivers/crypto/ux500/cryp/cryp_core.c
+++ b/drivers/crypto/ux500/cryp/cryp_core.c
@@ -1750,7 +1750,7 @@ static struct platform_driver cryp_driver = {
.shutdown = ux500_cryp_shutdown,
.driver = {
.owner = THIS_MODULE,
- .name = "cryp1",
+ .name = "cryp1"
.pm = &ux500_cryp_pm,
}
};
diff --git a/drivers/dca/dca-core.c b/drivers/dca/dca-core.c
index 819dfda..bc6f5fa 100644
--- a/drivers/dca/dca-core.c
+++ b/drivers/dca/dca-core.c
@@ -420,11 +420,6 @@ void unregister_dca_provider(struct dca_provider *dca, struct device *dev)
raw_spin_lock_irqsave(&dca_lock, flags);
- if (list_empty(&dca_domains)) {
- raw_spin_unlock_irqrestore(&dca_lock, flags);
- return;
- }
-
list_del(&dca->node);
pci_rc = dca_pci_rc_from_dev(dev);
diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c
index 8607724..5a31264 100644
--- a/drivers/dma/omap-dma.c
+++ b/drivers/dma/omap-dma.c
@@ -276,20 +276,12 @@ static void omap_dma_issue_pending(struct dma_chan *chan)
spin_lock_irqsave(&c->vc.lock, flags);
if (vchan_issue_pending(&c->vc) && !c->desc) {
- /*
- * c->cyclic is used only by audio and in this case the DMA need
- * to be started without delay.
- */
- if (!c->cyclic) {
- struct omap_dmadev *d = to_omap_dma_dev(chan->device);
- spin_lock(&d->lock);
- if (list_empty(&c->node))
- list_add_tail(&c->node, &d->pending);
- spin_unlock(&d->lock);
- tasklet_schedule(&d->task);
- } else {
- omap_dma_start_desc(c);
- }
+ struct omap_dmadev *d = to_omap_dma_dev(chan->device);
+ spin_lock(&d->lock);
+ if (list_empty(&c->node))
+ list_add_tail(&c->node, &d->pending);
+ spin_unlock(&d->lock);
+ tasklet_schedule(&d->task);
}
spin_unlock_irqrestore(&c->vc.lock, flags);
}
diff --git a/drivers/dma/sh/shdma.c b/drivers/dma/sh/shdma.c
index b70709b..3315e4b 100644
--- a/drivers/dma/sh/shdma.c
+++ b/drivers/dma/sh/shdma.c
@@ -326,7 +326,7 @@ static int sh_dmae_set_slave(struct shdma_chan *schan,
shdma_chan);
const struct sh_dmae_slave_config *cfg = dmae_find_slave(sh_chan, slave_id);
if (!cfg)
- return -ENXIO;
+ return -ENODEV;
if (!try)
sh_chan->config = cfg;
diff --git a/drivers/edac/edac_mc_sysfs.c b/drivers/edac/edac_mc_sysfs.c
index c9303ed..0ca1ca7 100644
--- a/drivers/edac/edac_mc_sysfs.c
+++ b/drivers/edac/edac_mc_sysfs.c
@@ -330,17 +330,17 @@ static struct device_attribute *dynamic_csrow_dimm_attr[] = {
};
/* possible dynamic channel ce_count attribute files */
-DEVICE_CHANNEL(ch0_ce_count, S_IRUGO,
+DEVICE_CHANNEL(ch0_ce_count, S_IRUGO | S_IWUSR,
channel_ce_count_show, NULL, 0);
-DEVICE_CHANNEL(ch1_ce_count, S_IRUGO,
+DEVICE_CHANNEL(ch1_ce_count, S_IRUGO | S_IWUSR,
channel_ce_count_show, NULL, 1);
-DEVICE_CHANNEL(ch2_ce_count, S_IRUGO,
+DEVICE_CHANNEL(ch2_ce_count, S_IRUGO | S_IWUSR,
channel_ce_count_show, NULL, 2);
-DEVICE_CHANNEL(ch3_ce_count, S_IRUGO,
+DEVICE_CHANNEL(ch3_ce_count, S_IRUGO | S_IWUSR,
channel_ce_count_show, NULL, 3);
-DEVICE_CHANNEL(ch4_ce_count, S_IRUGO,
+DEVICE_CHANNEL(ch4_ce_count, S_IRUGO | S_IWUSR,
channel_ce_count_show, NULL, 4);
-DEVICE_CHANNEL(ch5_ce_count, S_IRUGO,
+DEVICE_CHANNEL(ch5_ce_count, S_IRUGO | S_IWUSR,
channel_ce_count_show, NULL, 5);
/* Total possible dynamic ce_count attribute file table */
diff --git a/drivers/eisa/pci_eisa.c b/drivers/eisa/pci_eisa.c
index 6c3fca9..cdae207 100644
--- a/drivers/eisa/pci_eisa.c
+++ b/drivers/eisa/pci_eisa.c
@@ -19,10 +19,10 @@
/* There is only *one* pci_eisa device per machine, right ? */
static struct eisa_root_device pci_eisa_root;
-static int __init pci_eisa_init(struct pci_dev *pdev)
+static int __init pci_eisa_init(struct pci_dev *pdev,
+ const struct pci_device_id *ent)
{
- int rc, i;
- struct resource *res, *bus_res = NULL;
+ int rc;
if ((rc = pci_enable_device (pdev))) {
printk (KERN_ERR "pci_eisa : Could not enable device %s\n",
@@ -30,30 +30,9 @@ static int __init pci_eisa_init(struct pci_dev *pdev)
return rc;
}
- /*
- * The Intel 82375 PCI-EISA bridge is a subtractive-decode PCI
- * device, so the resources available on EISA are the same as those
- * available on the 82375 bus. This works the same as a PCI-PCI
- * bridge in subtractive-decode mode (see pci_read_bridge_bases()).
- * We assume other PCI-EISA bridges are similar.
- *
- * eisa_root_register() can only deal with a single io port resource,
- * so we use the first valid io port resource.
- */
- pci_bus_for_each_resource(pdev->bus, res, i)
- if (res && (res->flags & IORESOURCE_IO)) {
- bus_res = res;
- break;
- }
-
- if (!bus_res) {
- dev_err(&pdev->dev, "No resources available\n");
- return -1;
- }
-
pci_eisa_root.dev = &pdev->dev;
- pci_eisa_root.res = bus_res;
- pci_eisa_root.bus_base_addr = bus_res->start;
+ pci_eisa_root.res = pdev->bus->resource[0];
+ pci_eisa_root.bus_base_addr = pdev->bus->resource[0]->start;
pci_eisa_root.slots = EISA_MAX_SLOTS;
pci_eisa_root.dma_mask = pdev->dma_mask;
dev_set_drvdata(pci_eisa_root.dev, &pci_eisa_root);
@@ -66,26 +45,22 @@ static int __init pci_eisa_init(struct pci_dev *pdev)
return 0;
}
-/*
- * We have to call pci_eisa_init_early() before pnpacpi_init()/isapnp_init().
- * Otherwise pnp resource will get enabled early and could prevent eisa
- * to be initialized.
- * Also need to make sure pci_eisa_init_early() is called after
- * x86/pci_subsys_init().
- * So need to use subsys_initcall_sync with it.
- */
-static int __init pci_eisa_init_early(void)
-{
- struct pci_dev *dev = NULL;
- int ret;
+static struct pci_device_id pci_eisa_pci_tbl[] = {
+ { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
+ PCI_CLASS_BRIDGE_EISA << 8, 0xffff00, 0 },
+ { 0, }
+};
- for_each_pci_dev(dev)
- if ((dev->class >> 8) == PCI_CLASS_BRIDGE_EISA) {
- ret = pci_eisa_init(dev);
- if (ret)
- return ret;
- }
+static struct pci_driver __refdata pci_eisa_driver = {
+ .name = "pci_eisa",
+ .id_table = pci_eisa_pci_tbl,
+ .probe = pci_eisa_init,
+};
- return 0;
+static int __init pci_eisa_init_module (void)
+{
+ return pci_register_driver (&pci_eisa_driver);
}
-subsys_initcall_sync(pci_eisa_init_early);
+
+device_initcall(pci_eisa_init_module);
+MODULE_DEVICE_TABLE(pci, pci_eisa_pci_tbl);
diff --git a/drivers/firewire/core-device.c b/drivers/firewire/core-device.c
index af3e8aa..3873d53 100644
--- a/drivers/firewire/core-device.c
+++ b/drivers/firewire/core-device.c
@@ -1020,10 +1020,6 @@ static void fw_device_init(struct work_struct *work)
ret = idr_pre_get(&fw_device_idr, GFP_KERNEL) ?
idr_get_new(&fw_device_idr, device, &minor) :
-ENOMEM;
- if (minor >= 1 << MINORBITS) {
- idr_remove(&fw_device_idr, minor);
- minor = -ENOSPC;
- }
up_write(&fw_device_rwsem);
if (ret < 0)
diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
index 42c759a..9b00072 100644
--- a/drivers/firmware/Kconfig
+++ b/drivers/firmware/Kconfig
@@ -53,24 +53,6 @@ config EFI_VARS
Subsequent efibootmgr releases may be found at:
<http://linux.dell.com/efibootmgr>
-config EFI_VARS_PSTORE
- bool "Register efivars backend for pstore"
- depends on EFI_VARS && PSTORE
- default y
- help
- Say Y here to enable use efivars as a backend to pstore. This
- will allow writing console messages, crash dumps, or anything
- else supported by pstore to EFI variables.
-
-config EFI_VARS_PSTORE_DEFAULT_DISABLE
- bool "Disable using efivars as a pstore backend by default"
- depends on EFI_VARS_PSTORE
- default n
- help
- Saying Y here will disable the use of efivars as a storage
- backend for pstore by default. This setting can be overridden
- using the efivars module's pstore_disable parameter.
-
config EFI_PCDP
bool "Console device selection via EFI PCDP or HCDP table"
depends on ACPI && EFI && IA64
diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c
index 4cd392d..982f1f5 100644
--- a/drivers/firmware/dmi_scan.c
+++ b/drivers/firmware/dmi_scan.c
@@ -442,6 +442,7 @@ static int __init dmi_present(const char __iomem *p)
static int __init smbios_present(const char __iomem *p)
{
u8 buf[32];
+ int offset = 0;
memcpy_fromio(buf, p, 32);
if ((buf[5] < 32) && dmi_checksum(buf, buf[5])) {
@@ -460,9 +461,9 @@ static int __init smbios_present(const char __iomem *p)
dmi_ver = 0x0206;
break;
}
- return memcmp(p + 16, "_DMI_", 5) || dmi_present(p + 16);
+ offset = 16;
}
- return 1;
+ return dmi_present(buf + offset);
}
void __init dmi_scan_machine(void)
diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c
index b07cb37..f5596db 100644
--- a/drivers/firmware/efivars.c
+++ b/drivers/firmware/efivars.c
@@ -79,7 +79,6 @@
#include <linux/device.h>
#include <linux/slab.h>
#include <linux/pstore.h>
-#include <linux/ctype.h>
#include <linux/fs.h>
#include <linux/ramfs.h>
@@ -103,11 +102,6 @@ MODULE_VERSION(EFIVARS_VERSION);
*/
#define GUID_LEN 36
-static bool efivars_pstore_disable =
- IS_ENABLED(CONFIG_EFI_VARS_PSTORE_DEFAULT_DISABLE);
-
-module_param_named(pstore_disable, efivars_pstore_disable, bool, 0644);
-
/*
* The maximum size of VariableName + Data = 1024
* Therefore, it's reasonable to save that much
@@ -411,11 +405,10 @@ static efi_status_t
get_var_data(struct efivars *efivars, struct efi_variable *var)
{
efi_status_t status;
- unsigned long flags;
- spin_lock_irqsave(&efivars->lock, flags);
+ spin_lock(&efivars->lock);
status = get_var_data_locked(efivars, var);
- spin_unlock_irqrestore(&efivars->lock, flags);
+ spin_unlock(&efivars->lock);
if (status != EFI_SUCCESS) {
printk(KERN_WARNING "efivars: get_variable() failed 0x%lx!\n",
@@ -424,44 +417,6 @@ get_var_data(struct efivars *efivars, struct efi_variable *var)
return status;
}
-static efi_status_t
-check_var_size_locked(struct efivars *efivars, u32 attributes,
- unsigned long size)
-{
- u64 storage_size, remaining_size, max_size;
- efi_status_t status;
- const struct efivar_operations *fops = efivars->ops;
-
- if (!efivars->ops->query_variable_info)
- return EFI_UNSUPPORTED;
-
- status = fops->query_variable_info(attributes, &storage_size,
- &remaining_size, &max_size);
-
- if (status != EFI_SUCCESS)
- return status;
-
- if (!storage_size || size > remaining_size || size > max_size ||
- (remaining_size - size) < (storage_size / 2))
- return EFI_OUT_OF_RESOURCES;
-
- return status;
-}
-
-
-static efi_status_t
-check_var_size(struct efivars *efivars, u32 attributes, unsigned long size)
-{
- efi_status_t status;
- unsigned long flags;
-
- spin_lock_irqsave(&efivars->lock, flags);
- status = check_var_size_locked(efivars, attributes, size);
- spin_unlock_irqrestore(&efivars->lock, flags);
-
- return status;
-}
-
static ssize_t
efivar_guid_read(struct efivar_entry *entry, char *buf)
{
@@ -582,19 +537,14 @@ efivar_store_raw(struct efivar_entry *entry, const char *buf, size_t count)
return -EINVAL;
}
- spin_lock_irq(&efivars->lock);
-
- status = check_var_size_locked(efivars, new_var->Attributes,
- new_var->DataSize + utf16_strsize(new_var->VariableName, 1024));
-
- if (status == EFI_SUCCESS || status == EFI_UNSUPPORTED)
- status = efivars->ops->set_variable(new_var->VariableName,
- &new_var->VendorGuid,
- new_var->Attributes,
- new_var->DataSize,
- new_var->Data);
+ spin_lock(&efivars->lock);
+ status = efivars->ops->set_variable(new_var->VariableName,
+ &new_var->VendorGuid,
+ new_var->Attributes,
+ new_var->DataSize,
+ new_var->Data);
- spin_unlock_irq(&efivars->lock);
+ spin_unlock(&efivars->lock);
if (status != EFI_SUCCESS) {
printk(KERN_WARNING "efivars: set_variable() failed: status=%lx\n",
@@ -743,7 +693,8 @@ static ssize_t efivarfs_file_write(struct file *file,
u32 attributes;
struct inode *inode = file->f_mapping->host;
unsigned long datasize = count - sizeof(attributes);
- unsigned long newdatasize, varsize;
+ unsigned long newdatasize;
+ u64 storage_size, remaining_size, max_size;
ssize_t bytes = 0;
if (count < sizeof(attributes))
@@ -762,18 +713,28 @@ static ssize_t efivarfs_file_write(struct file *file,
* amounts of memory. Pick a default size of 64K if
* QueryVariableInfo() isn't supported by the firmware.
*/
+ spin_lock(&efivars->lock);
+
+ if (!efivars->ops->query_variable_info)
+ status = EFI_UNSUPPORTED;
+ else {
+ const struct efivar_operations *fops = efivars->ops;
+ status = fops->query_variable_info(attributes, &storage_size,
+ &remaining_size, &max_size);
+ }
- varsize = datasize + utf16_strsize(var->var.VariableName, 1024);
- status = check_var_size(efivars, attributes, varsize);
+ spin_unlock(&efivars->lock);
if (status != EFI_SUCCESS) {
if (status != EFI_UNSUPPORTED)
return efi_status_to_err(status);
- if (datasize > 65536)
- return -ENOSPC;
+ remaining_size = 65536;
}
+ if (datasize > remaining_size)
+ return -ENOSPC;
+
data = kmalloc(datasize, GFP_KERNEL);
if (!data)
return -ENOMEM;
@@ -793,20 +754,7 @@ static ssize_t efivarfs_file_write(struct file *file,
* set_variable call, and removal of the variable from the efivars
* list (in the case of an authenticated delete).
*/
- spin_lock_irq(&efivars->lock);
-
- /*
- * Ensure that the available space hasn't shrunk below the safe level
- */
-
- status = check_var_size_locked(efivars, attributes, varsize);
-
- if (status != EFI_SUCCESS && status != EFI_UNSUPPORTED) {
- spin_unlock_irq(&efivars->lock);
- kfree(data);
-
- return efi_status_to_err(status);
- }
+ spin_lock(&efivars->lock);
status = efivars->ops->set_variable(var->var.VariableName,
&var->var.VendorGuid,
@@ -814,7 +762,7 @@ static ssize_t efivarfs_file_write(struct file *file,
data);
if (status != EFI_SUCCESS) {
- spin_unlock_irq(&efivars->lock);
+ spin_unlock(&efivars->lock);
kfree(data);
return efi_status_to_err(status);
@@ -835,21 +783,21 @@ static ssize_t efivarfs_file_write(struct file *file,
NULL);
if (status == EFI_BUFFER_TOO_SMALL) {
- spin_unlock_irq(&efivars->lock);
+ spin_unlock(&efivars->lock);
mutex_lock(&inode->i_mutex);
i_size_write(inode, newdatasize + sizeof(attributes));
mutex_unlock(&inode->i_mutex);
} else if (status == EFI_NOT_FOUND) {
list_del(&var->list);
- spin_unlock_irq(&efivars->lock);
+ spin_unlock(&efivars->lock);
efivar_unregister(var);
drop_nlink(inode);
d_delete(file->f_dentry);
dput(file->f_dentry);
} else {
- spin_unlock_irq(&efivars->lock);
+ spin_unlock(&efivars->lock);
pr_warn("efivarfs: inconsistent EFI variable implementation? "
"status = %lx\n", status);
}
@@ -871,11 +819,11 @@ static ssize_t efivarfs_file_read(struct file *file, char __user *userbuf,
void *data;
ssize_t size = 0;
- spin_lock_irq(&efivars->lock);
+ spin_lock(&efivars->lock);
status = efivars->ops->get_variable(var->var.VariableName,
&var->var.VendorGuid,
&attributes, &datasize, NULL);
- spin_unlock_irq(&efivars->lock);
+ spin_unlock(&efivars->lock);
if (status != EFI_BUFFER_TOO_SMALL)
return efi_status_to_err(status);
@@ -885,12 +833,12 @@ static ssize_t efivarfs_file_read(struct file *file, char __user *userbuf,
if (!data)
return -ENOMEM;
- spin_lock_irq(&efivars->lock);
+ spin_lock(&efivars->lock);
status = efivars->ops->get_variable(var->var.VariableName,
&var->var.VendorGuid,
&attributes, &datasize,
(data + sizeof(attributes)));
- spin_unlock_irq(&efivars->lock);
+ spin_unlock(&efivars->lock);
if (status != EFI_SUCCESS) {
size = efi_status_to_err(status);
@@ -952,48 +900,6 @@ static struct inode *efivarfs_get_inode(struct super_block *sb,
return inode;
}
-/*
- * Return true if 'str' is a valid efivarfs filename of the form,
- *
- * VariableName-12345678-1234-1234-1234-1234567891bc
- */
-static bool efivarfs_valid_name(const char *str, int len)
-{
- static const char dashes[GUID_LEN] = {
- [8] = 1, [13] = 1, [18] = 1, [23] = 1
- };
- const char *s = str + len - GUID_LEN;
- int i;
-
- /*
- * We need a GUID, plus at least one letter for the variable name,
- * plus the '-' separator
- */
- if (len < GUID_LEN + 2)
- return false;
-
- /* GUID must be preceded by a '-' */
- if (*(s - 1) != '-')
- return false;
-
- /*
- * Validate that 's' is of the correct format, e.g.
- *
- * 12345678-1234-1234-1234-123456789abc
- */
- for (i = 0; i < GUID_LEN; i++) {
- if (dashes[i]) {
- if (*s++ != '-')
- return false;
- } else {
- if (!isxdigit(*s++))
- return false;
- }
- }
-
- return true;
-}
-
static void efivarfs_hex_to_guid(const char *str, efi_guid_t *guid)
{
guid->b[0] = hex_to_bin(str[6]) << 4 | hex_to_bin(str[7]);
@@ -1022,7 +928,11 @@ static int efivarfs_create(struct inode *dir, struct dentry *dentry,
struct efivar_entry *var;
int namelen, i = 0, err = 0;
- if (!efivarfs_valid_name(dentry->d_name.name, dentry->d_name.len))
+ /*
+ * We need a GUID, plus at least one letter for the variable name,
+ * plus the '-' separator
+ */
+ if (dentry->d_name.len < GUID_LEN + 2)
return -EINVAL;
inode = efivarfs_get_inode(dir->i_sb, dir, mode, 0);
@@ -1056,9 +966,9 @@ static int efivarfs_create(struct inode *dir, struct dentry *dentry,
goto out;
kobject_uevent(&var->kobj, KOBJ_ADD);
- spin_lock_irq(&efivars->lock);
+ spin_lock(&efivars->lock);
list_add(&var->list, &efivars->list);
- spin_unlock_irq(&efivars->lock);
+ spin_unlock(&efivars->lock);
d_instantiate(dentry, inode);
dget(dentry);
out:
@@ -1075,7 +985,7 @@ static int efivarfs_unlink(struct inode *dir, struct dentry *dentry)
struct efivars *efivars = var->efivars;
efi_status_t status;
- spin_lock_irq(&efivars->lock);
+ spin_lock(&efivars->lock);
status = efivars->ops->set_variable(var->var.VariableName,
&var->var.VendorGuid,
@@ -1083,102 +993,17 @@ static int efivarfs_unlink(struct inode *dir, struct dentry *dentry)
if (status == EFI_SUCCESS || status == EFI_NOT_FOUND) {
list_del(&var->list);
- spin_unlock_irq(&efivars->lock);
+ spin_unlock(&efivars->lock);
efivar_unregister(var);
drop_nlink(dentry->d_inode);
dput(dentry);
return 0;
}
- spin_unlock_irq(&efivars->lock);
+ spin_unlock(&efivars->lock);
return -EINVAL;
};
-/*
- * Compare two efivarfs file names.
- *
- * An efivarfs filename is composed of two parts,
- *
- * 1. A case-sensitive variable name
- * 2. A case-insensitive GUID
- *
- * So we need to perform a case-sensitive match on part 1 and a
- * case-insensitive match on part 2.
- */
-static int efivarfs_d_compare(const struct dentry *parent, const struct inode *pinode,
- const struct dentry *dentry, const struct inode *inode,
- unsigned int len, const char *str,
- const struct qstr *name)
-{
- int guid = len - GUID_LEN;
-
- if (name->len != len)
- return 1;
-
- /* Case-sensitive compare for the variable name */
- if (memcmp(str, name->name, guid))
- return 1;
-
- /* Case-insensitive compare for the GUID */
- return strncasecmp(name->name + guid, str + guid, GUID_LEN);
-}
-
-static int efivarfs_d_hash(const struct dentry *dentry,
- const struct inode *inode, struct qstr *qstr)
-{
- unsigned long hash = init_name_hash();
- const unsigned char *s = qstr->name;
- unsigned int len = qstr->len;
-
- if (!efivarfs_valid_name(s, len))
- return -EINVAL;
-
- while (len-- > GUID_LEN)
- hash = partial_name_hash(*s++, hash);
-
- /* GUID is case-insensitive. */
- while (len--)
- hash = partial_name_hash(tolower(*s++), hash);
-
- qstr->hash = end_name_hash(hash);
- return 0;
-}
-
-/*
- * Retaining negative dentries for an in-memory filesystem just wastes
- * memory and lookup time: arrange for them to be deleted immediately.
- */
-static int efivarfs_delete_dentry(const struct dentry *dentry)
-{
- return 1;
-}
-
-static struct dentry_operations efivarfs_d_ops = {
- .d_compare = efivarfs_d_compare,
- .d_hash = efivarfs_d_hash,
- .d_delete = efivarfs_delete_dentry,
-};
-
-static struct dentry *efivarfs_alloc_dentry(struct dentry *parent, char *name)
-{
- struct dentry *d;
- struct qstr q;
- int err;
-
- q.name = name;
- q.len = strlen(name);
-
- err = efivarfs_d_hash(NULL, NULL, &q);
- if (err)
- return ERR_PTR(err);
-
- d = d_alloc(parent, &q);
- if (d)
- return d;
-
- return ERR_PTR(-ENOMEM);
-}
-
static int efivarfs_fill_super(struct super_block *sb, void *data, int silent)
{
struct inode *inode = NULL;
@@ -1186,7 +1011,6 @@ static int efivarfs_fill_super(struct super_block *sb, void *data, int silent)
struct efivar_entry *entry, *n;
struct efivars *efivars = &__efivars;
char *name;
- int err = -ENOMEM;
efivarfs_sb = sb;
@@ -1195,7 +1019,6 @@ static int efivarfs_fill_super(struct super_block *sb, void *data, int silent)
sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
sb->s_magic = EFIVARFS_MAGIC;
sb->s_op = &efivarfs_ops;
- sb->s_d_op = &efivarfs_d_ops;
sb->s_time_gran = 1;
inode = efivarfs_get_inode(sb, NULL, S_IFDIR | 0755, 0);
@@ -1236,22 +1059,20 @@ static int efivarfs_fill_super(struct super_block *sb, void *data, int silent)
if (!inode)
goto fail_name;
- dentry = efivarfs_alloc_dentry(root, name);
- if (IS_ERR(dentry)) {
- err = PTR_ERR(dentry);
+ dentry = d_alloc_name(root, name);
+ if (!dentry)
goto fail_inode;
- }
/* copied by the above to local storage in the dentry. */
kfree(name);
- spin_lock_irq(&efivars->lock);
+ spin_lock(&efivars->lock);
efivars->ops->get_variable(entry->var.VariableName,
&entry->var.VendorGuid,
&entry->var.Attributes,
&size,
NULL);
- spin_unlock_irq(&efivars->lock);
+ spin_unlock(&efivars->lock);
mutex_lock(&inode->i_mutex);
inode->i_private = entry;
@@ -1267,7 +1088,7 @@ fail_inode:
fail_name:
kfree(name);
fail:
- return err;
+ return -ENOMEM;
}
static struct dentry *efivarfs_mount(struct file_system_type *fs_type,
@@ -1288,31 +1109,21 @@ static struct file_system_type efivarfs_type = {
.kill_sb = efivarfs_kill_sb,
};
-/*
- * Handle negative dentry.
- */
-static struct dentry *efivarfs_lookup(struct inode *dir, struct dentry *dentry,
- unsigned int flags)
-{
- if (dentry->d_name.len > NAME_MAX)
- return ERR_PTR(-ENAMETOOLONG);
- d_add(dentry, NULL);
- return NULL;
-}
-
static const struct inode_operations efivarfs_dir_inode_operations = {
- .lookup = efivarfs_lookup,
+ .lookup = simple_lookup,
.unlink = efivarfs_unlink,
.create = efivarfs_create,
};
-#ifdef CONFIG_EFI_VARS_PSTORE
+static struct pstore_info efi_pstore_info;
+
+#ifdef CONFIG_PSTORE
static int efi_pstore_open(struct pstore_info *psi)
{
struct efivars *efivars = psi->data;
- spin_lock_irq(&efivars->lock);
+ spin_lock(&efivars->lock);
efivars->walk_entry = list_first_entry(&efivars->list,
struct efivar_entry, list);
return 0;
@@ -1322,7 +1133,7 @@ static int efi_pstore_close(struct pstore_info *psi)
{
struct efivars *efivars = psi->data;
- spin_unlock_irq(&efivars->lock);
+ spin_unlock(&efivars->lock);
return 0;
}
@@ -1396,22 +1207,22 @@ static int efi_pstore_write(enum pstore_type_id type,
efi_guid_t vendor = LINUX_EFI_CRASH_GUID;
struct efivars *efivars = psi->data;
int i, ret = 0;
+ u64 storage_space, remaining_space, max_variable_size;
efi_status_t status = EFI_NOT_FOUND;
- unsigned long flags;
- spin_lock_irqsave(&efivars->lock, flags);
+ spin_lock(&efivars->lock);
/*
* Check if there is a space enough to log.
* size: a size of logging data
* DUMP_NAME_LEN * 2: a maximum size of variable name
*/
-
- status = check_var_size_locked(efivars, PSTORE_EFI_ATTRIBUTES,
- size + DUMP_NAME_LEN * 2);
-
- if (status) {
- spin_unlock_irqrestore(&efivars->lock, flags);
+ status = efivars->ops->query_variable_info(PSTORE_EFI_ATTRIBUTES,
+ &storage_space,
+ &remaining_space,
+ &max_variable_size);
+ if (status || remaining_space < size + DUMP_NAME_LEN * 2) {
+ spin_unlock(&efivars->lock);
*id = part;
return -ENOSPC;
}
@@ -1425,7 +1236,7 @@ static int efi_pstore_write(enum pstore_type_id type,
efivars->ops->set_variable(efi_name, &vendor, PSTORE_EFI_ATTRIBUTES,
size, psi->buf);
- spin_unlock_irqrestore(&efivars->lock, flags);
+ spin_unlock(&efivars->lock);
if (size)
ret = efivar_create_sysfs_entry(efivars,
@@ -1452,7 +1263,7 @@ static int efi_pstore_erase(enum pstore_type_id type, u64 id, int count,
sprintf(name, "dump-type%u-%u-%d-%lu", type, (unsigned int)id, count,
time.tv_sec);
- spin_lock_irq(&efivars->lock);
+ spin_lock(&efivars->lock);
for (i = 0; i < DUMP_NAME_LEN; i++)
efi_name[i] = name[i];
@@ -1496,13 +1307,45 @@ static int efi_pstore_erase(enum pstore_type_id type, u64 id, int count,
if (found)
list_del(&found->list);
- spin_unlock_irq(&efivars->lock);
+ spin_unlock(&efivars->lock);
if (found)
efivar_unregister(found);
return 0;
}
+#else
+static int efi_pstore_open(struct pstore_info *psi)
+{
+ return 0;
+}
+
+static int efi_pstore_close(struct pstore_info *psi)
+{
+ return 0;
+}
+
+static ssize_t efi_pstore_read(u64 *id, enum pstore_type_id *type, int *count,
+ struct timespec *timespec,
+ char **buf, struct pstore_info *psi)
+{
+ return -1;
+}
+
+static int efi_pstore_write(enum pstore_type_id type,
+ enum kmsg_dump_reason reason, u64 *id,
+ unsigned int part, int count, size_t size,
+ struct pstore_info *psi)
+{
+ return 0;
+}
+
+static int efi_pstore_erase(enum pstore_type_id type, u64 id, int count,
+ struct timespec time, struct pstore_info *psi)
+{
+ return 0;
+}
+#endif
static struct pstore_info efi_pstore_info = {
.owner = THIS_MODULE,
@@ -1514,24 +1357,6 @@ static struct pstore_info efi_pstore_info = {
.erase = efi_pstore_erase,
};
-static void efivar_pstore_register(struct efivars *efivars)
-{
- efivars->efi_pstore_info = efi_pstore_info;
- efivars->efi_pstore_info.buf = kmalloc(4096, GFP_KERNEL);
- if (efivars->efi_pstore_info.buf) {
- efivars->efi_pstore_info.bufsize = 1024;
- efivars->efi_pstore_info.data = efivars;
- spin_lock_init(&efivars->efi_pstore_info.buf_lock);
- pstore_register(&efivars->efi_pstore_info);
- }
-}
-#else
-static void efivar_pstore_register(struct efivars *efivars)
-{
- return;
-}
-#endif
-
static ssize_t efivar_create(struct file *filp, struct kobject *kobj,
struct bin_attribute *bin_attr,
char *buf, loff_t pos, size_t count)
@@ -1552,7 +1377,7 @@ static ssize_t efivar_create(struct file *filp, struct kobject *kobj,
return -EINVAL;
}
- spin_lock_irq(&efivars->lock);
+ spin_lock(&efivars->lock);
/*
* Does this variable already exist?
@@ -1570,18 +1395,10 @@ static ssize_t efivar_create(struct file *filp, struct kobject *kobj,
}
}
if (found) {
- spin_unlock_irq(&efivars->lock);
+ spin_unlock(&efivars->lock);
return -EINVAL;
}
- status = check_var_size_locked(efivars, new_var->Attributes,
- new_var->DataSize + utf16_strsize(new_var->VariableName, 1024));
-
- if (status && status != EFI_UNSUPPORTED) {
- spin_unlock_irq(&efivars->lock);
- return efi_status_to_err(status);
- }
-
/* now *really* create the variable via EFI */
status = efivars->ops->set_variable(new_var->VariableName,
&new_var->VendorGuid,
@@ -1592,10 +1409,10 @@ static ssize_t efivar_create(struct file *filp, struct kobject *kobj,
if (status != EFI_SUCCESS) {
printk(KERN_WARNING "efivars: set_variable() failed: status=%lx\n",
status);
- spin_unlock_irq(&efivars->lock);
+ spin_unlock(&efivars->lock);
return -EIO;
}
- spin_unlock_irq(&efivars->lock);
+ spin_unlock(&efivars->lock);
/* Create the entry in sysfs. Locking is not required here */
status = efivar_create_sysfs_entry(efivars,
@@ -1623,7 +1440,7 @@ static ssize_t efivar_delete(struct file *filp, struct kobject *kobj,
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
- spin_lock_irq(&efivars->lock);
+ spin_lock(&efivars->lock);
/*
* Does this variable already exist?
@@ -1641,7 +1458,7 @@ static ssize_t efivar_delete(struct file *filp, struct kobject *kobj,
}
}
if (!found) {
- spin_unlock_irq(&efivars->lock);
+ spin_unlock(&efivars->lock);
return -EINVAL;
}
/* force the Attributes/DataSize to 0 to ensure deletion */
@@ -1657,65 +1474,18 @@ static ssize_t efivar_delete(struct file *filp, struct kobject *kobj,
if (status != EFI_SUCCESS) {
printk(KERN_WARNING "efivars: set_variable() failed: status=%lx\n",
status);
- spin_unlock_irq(&efivars->lock);
+ spin_unlock(&efivars->lock);
return -EIO;
}
list_del(&search_efivar->list);
/* We need to release this lock before unregistering. */
- spin_unlock_irq(&efivars->lock);
+ spin_unlock(&efivars->lock);
efivar_unregister(search_efivar);
/* It's dead Jim.... */
return count;
}
-static bool variable_is_present(efi_char16_t *variable_name, efi_guid_t *vendor)
-{
- struct efivar_entry *entry, *n;
- struct efivars *efivars = &__efivars;
- unsigned long strsize1, strsize2;
- bool found = false;
-
- strsize1 = utf16_strsize(variable_name, 1024);
- list_for_each_entry_safe(entry, n, &efivars->list, list) {
- strsize2 = utf16_strsize(entry->var.VariableName, 1024);
- if (strsize1 == strsize2 &&
- !memcmp(variable_name, &(entry->var.VariableName),
- strsize2) &&
- !efi_guidcmp(entry->var.VendorGuid,
- *vendor)) {
- found = true;
- break;
- }
- }
- return found;
-}
-
-/*
- * Returns the size of variable_name, in bytes, including the
- * terminating NULL character, or variable_name_size if no NULL
- * character is found among the first variable_name_size bytes.
- */
-static unsigned long var_name_strnsize(efi_char16_t *variable_name,
- unsigned long variable_name_size)
-{
- unsigned long len;
- efi_char16_t c;
-
- /*
- * The variable name is, by definition, a NULL-terminated
- * string, so make absolutely sure that variable_name_size is
- * the value we expect it to be. If not, return the real size.
- */
- for (len = 2; len <= variable_name_size; len += sizeof(c)) {
- c = variable_name[(len / sizeof(c)) - 1];
- if (!c)
- break;
- }
-
- return min(len, variable_name_size);
-}
-
/*
* Let's not leave out systab information that snuck into
* the efivars driver
@@ -1824,9 +1594,9 @@ efivar_create_sysfs_entry(struct efivars *efivars,
kfree(short_name);
short_name = NULL;
- spin_lock_irq(&efivars->lock);
+ spin_lock(&efivars->lock);
list_add(&new_efivar->list, &efivars->list);
- spin_unlock_irq(&efivars->lock);
+ spin_unlock(&efivars->lock);
return 0;
}
@@ -1895,9 +1665,9 @@ void unregister_efivars(struct efivars *efivars)
struct efivar_entry *entry, *n;
list_for_each_entry_safe(entry, n, &efivars->list, list) {
- spin_lock_irq(&efivars->lock);
+ spin_lock(&efivars->lock);
list_del(&entry->list);
- spin_unlock_irq(&efivars->lock);
+ spin_unlock(&efivars->lock);
efivar_unregister(entry);
}
if (efivars->new_var)
@@ -1911,28 +1681,6 @@ void unregister_efivars(struct efivars *efivars)
}
EXPORT_SYMBOL_GPL(unregister_efivars);
-/*
- * Print a warning when duplicate EFI variables are encountered and
- * disable the sysfs workqueue since the firmware is buggy.
- */
-static void dup_variable_bug(efi_char16_t *s16, efi_guid_t *vendor_guid,
- unsigned long len16)
-{
- size_t i, len8 = len16 / sizeof(efi_char16_t);
- char *s8;
-
- s8 = kzalloc(len8, GFP_KERNEL);
- if (!s8)
- return;
-
- for (i = 0; i < len8; i++)
- s8[i] = s16[i];
-
- printk(KERN_WARNING "efivars: duplicate variable: %s-%pUl\n",
- s8, vendor_guid);
- kfree(s8);
-}
-
int register_efivars(struct efivars *efivars,
const struct efivar_operations *ops,
struct kobject *parent_kobj)
@@ -1981,24 +1729,6 @@ int register_efivars(struct efivars *efivars,
&vendor_guid);
switch (status) {
case EFI_SUCCESS:
- variable_name_size = var_name_strnsize(variable_name,
- variable_name_size);
-
- /*
- * Some firmware implementations return the
- * same variable name on multiple calls to
- * get_next_variable(). Terminate the loop
- * immediately as there is no guarantee that
- * we'll ever see a different variable name,
- * and may end up looping here forever.
- */
- if (variable_is_present(variable_name, &vendor_guid)) {
- dup_variable_bug(variable_name, &vendor_guid,
- variable_name_size);
- status = EFI_NOT_FOUND;
- break;
- }
-
efivar_create_sysfs_entry(efivars,
variable_name_size,
variable_name,
@@ -2018,8 +1748,15 @@ int register_efivars(struct efivars *efivars,
if (error)
unregister_efivars(efivars);
- if (!efivars_pstore_disable)
- efivar_pstore_register(efivars);
+ efivars->efi_pstore_info = efi_pstore_info;
+
+ efivars->efi_pstore_info.buf = kmalloc(4096, GFP_KERNEL);
+ if (efivars->efi_pstore_info.buf) {
+ efivars->efi_pstore_info.bufsize = 1024;
+ efivars->efi_pstore_info.data = efivars;
+ spin_lock_init(&efivars->efi_pstore_info.buf_lock);
+ pstore_register(&efivars->efi_pstore_info);
+ }
register_filesystem(&efivarfs_type);
diff --git a/drivers/gpio/gpio-em.c b/drivers/gpio/gpio-em.c
index deca78f..bdc8302 100644
--- a/drivers/gpio/gpio-em.c
+++ b/drivers/gpio/gpio-em.c
@@ -299,9 +299,8 @@ static int em_gio_probe(struct platform_device *pdev)
irq_chip->irq_set_type = em_gio_irq_set_type;
irq_chip->flags = IRQCHIP_SKIP_SET_WAKE;
- p->irq_domain = irq_domain_add_simple(pdev->dev.of_node,
+ p->irq_domain = irq_domain_add_linear(pdev->dev.of_node,
pdata->number_of_pins,
- pdata->irq_base,
&em_gio_irq_domain_ops, p);
if (!p->irq_domain) {
ret = -ENXIO;
diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c
index 456663c..6819d63 100644
--- a/drivers/gpio/gpio-mvebu.c
+++ b/drivers/gpio/gpio-mvebu.c
@@ -41,7 +41,6 @@
#include <linux/io.h>
#include <linux/of_irq.h>
#include <linux/of_device.h>
-#include <linux/clk.h>
#include <linux/pinctrl/consumer.h>
/*
@@ -496,7 +495,6 @@ static int mvebu_gpio_probe(struct platform_device *pdev)
struct resource *res;
struct irq_chip_generic *gc;
struct irq_chip_type *ct;
- struct clk *clk;
unsigned int ngpios;
int soc_variant;
int i, cpu, id;
@@ -530,11 +528,6 @@ static int mvebu_gpio_probe(struct platform_device *pdev)
return id;
}
- clk = devm_clk_get(&pdev->dev, NULL);
- /* Not all SoCs require a clock.*/
- if (!IS_ERR(clk))
- clk_prepare_enable(clk);
-
mvchip->soc_variant = soc_variant;
mvchip->chip.label = dev_name(&pdev->dev);
mvchip->chip.dev = &pdev->dev;
diff --git a/drivers/gpio/gpio-stmpe.c b/drivers/gpio/gpio-stmpe.c
index 3ce5bc3..770476a 100644
--- a/drivers/gpio/gpio-stmpe.c
+++ b/drivers/gpio/gpio-stmpe.c
@@ -307,15 +307,11 @@ static const struct irq_domain_ops stmpe_gpio_irq_simple_ops = {
.xlate = irq_domain_xlate_twocell,
};
-static int stmpe_gpio_irq_init(struct stmpe_gpio *stmpe_gpio,
- struct device_node *np)
+static int stmpe_gpio_irq_init(struct stmpe_gpio *stmpe_gpio)
{
- int base = 0;
+ int base = stmpe_gpio->irq_base;
- if (!np)
- base = stmpe_gpio->irq_base;
-
- stmpe_gpio->domain = irq_domain_add_simple(np,
+ stmpe_gpio->domain = irq_domain_add_simple(NULL,
stmpe_gpio->chip.ngpio, base,
&stmpe_gpio_irq_simple_ops, stmpe_gpio);
if (!stmpe_gpio->domain) {
@@ -350,9 +346,6 @@ static int stmpe_gpio_probe(struct platform_device *pdev)
stmpe_gpio->chip = template_chip;
stmpe_gpio->chip.ngpio = stmpe->num_gpios;
stmpe_gpio->chip.dev = &pdev->dev;
-#ifdef CONFIG_OF
- stmpe_gpio->chip.of_node = np;
-#endif
stmpe_gpio->chip.base = pdata ? pdata->gpio_base : -1;
if (pdata)
@@ -373,7 +366,7 @@ static int stmpe_gpio_probe(struct platform_device *pdev)
goto out_free;
if (irq >= 0) {
- ret = stmpe_gpio_irq_init(stmpe_gpio, np);
+ ret = stmpe_gpio_irq_init(stmpe_gpio);
if (ret)
goto out_disable;
diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c
index ea537fa..d542a14 100644
--- a/drivers/gpio/gpiolib-of.c
+++ b/drivers/gpio/gpiolib-of.c
@@ -228,7 +228,7 @@ static void of_gpiochip_add_pin_range(struct gpio_chip *chip)
if (!np)
return;
- for (;; index++) {
+ do {
ret = of_parse_phandle_with_args(np, "gpio-ranges",
"#gpio-range-cells", index, &pinspec);
if (ret)
@@ -257,7 +257,8 @@ static void of_gpiochip_add_pin_range(struct gpio_chip *chip)
if (ret)
break;
- }
+
+ } while (index++);
}
#else
diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h
index cac9c9a..5ccf984 100644
--- a/drivers/gpu/drm/ast/ast_drv.h
+++ b/drivers/gpu/drm/ast/ast_drv.h
@@ -239,8 +239,6 @@ struct ast_fbdev {
void *sysram;
int size;
struct ttm_bo_kmap_obj mapping;
- int x1, y1, x2, y2; /* dirty rect */
- spinlock_t dirty_lock;
};
#define to_ast_crtc(x) container_of(x, struct ast_crtc, base)
diff --git a/drivers/gpu/drm/ast/ast_fb.c b/drivers/gpu/drm/ast/ast_fb.c
index 9138678..d9ec779 100644
--- a/drivers/gpu/drm/ast/ast_fb.c
+++ b/drivers/gpu/drm/ast/ast_fb.c
@@ -52,52 +52,16 @@ static void ast_dirty_update(struct ast_fbdev *afbdev,
int bpp = (afbdev->afb.base.bits_per_pixel + 7)/8;
int ret;
bool unmap = false;
- bool store_for_later = false;
- int x2, y2;
- unsigned long flags;
obj = afbdev->afb.obj;
bo = gem_to_ast_bo(obj);
- /*
- * try and reserve the BO, if we fail with busy
- * then the BO is being moved and we should
- * store up the damage until later.
- */
ret = ast_bo_reserve(bo, true);
if (ret) {
- if (ret != -EBUSY)
- return;
-
- store_for_later = true;
- }
-
- x2 = x + width - 1;
- y2 = y + height - 1;
- spin_lock_irqsave(&afbdev->dirty_lock, flags);
-
- if (afbdev->y1 < y)
- y = afbdev->y1;
- if (afbdev->y2 > y2)
- y2 = afbdev->y2;
- if (afbdev->x1 < x)
- x = afbdev->x1;
- if (afbdev->x2 > x2)
- x2 = afbdev->x2;
-
- if (store_for_later) {
- afbdev->x1 = x;
- afbdev->x2 = x2;
- afbdev->y1 = y;
- afbdev->y2 = y2;
- spin_unlock_irqrestore(&afbdev->dirty_lock, flags);
+ DRM_ERROR("failed to reserve fb bo\n");
return;
}
- afbdev->x1 = afbdev->y1 = INT_MAX;
- afbdev->x2 = afbdev->y2 = 0;
- spin_unlock_irqrestore(&afbdev->dirty_lock, flags);
-
if (!bo->kmap.virtual) {
ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &bo->kmap);
if (ret) {
@@ -107,10 +71,10 @@ static void ast_dirty_update(struct ast_fbdev *afbdev,
}
unmap = true;
}
- for (i = y; i <= y2; i++) {
+ for (i = y; i < y + height; i++) {
/* assume equal stride for now */
src_offset = dst_offset = i * afbdev->afb.base.pitches[0] + (x * bpp);
- memcpy_toio(bo->kmap.virtual + src_offset, afbdev->sysram + src_offset, (x2 - x + 1) * bpp);
+ memcpy_toio(bo->kmap.virtual + src_offset, afbdev->sysram + src_offset, width * bpp);
}
if (unmap)
@@ -341,7 +305,6 @@ int ast_fbdev_init(struct drm_device *dev)
ast->fbdev = afbdev;
afbdev->helper.funcs = &ast_fb_helper_funcs;
- spin_lock_init(&afbdev->dirty_lock);
ret = drm_fb_helper_init(dev, &afbdev->helper,
1, 1);
if (ret) {
diff --git a/drivers/gpu/drm/ast/ast_ttm.c b/drivers/gpu/drm/ast/ast_ttm.c
index 09da339..3602731 100644
--- a/drivers/gpu/drm/ast/ast_ttm.c
+++ b/drivers/gpu/drm/ast/ast_ttm.c
@@ -316,7 +316,7 @@ int ast_bo_reserve(struct ast_bo *bo, bool no_wait)
ret = ttm_bo_reserve(&bo->bo, true, no_wait, false, 0);
if (ret) {
- if (ret != -ERESTARTSYS && ret != -EBUSY)
+ if (ret != -ERESTARTSYS)
DRM_ERROR("reserve failed %p\n", bo);
return ret;
}
diff --git a/drivers/gpu/drm/cirrus/cirrus_drv.h b/drivers/gpu/drm/cirrus/cirrus_drv.h
index 7ca0595..6e0cc72 100644
--- a/drivers/gpu/drm/cirrus/cirrus_drv.h
+++ b/drivers/gpu/drm/cirrus/cirrus_drv.h
@@ -154,8 +154,6 @@ struct cirrus_fbdev {
struct list_head fbdev_list;
void *sysram;
int size;
- int x1, y1, x2, y2; /* dirty rect */
- spinlock_t dirty_lock;
};
struct cirrus_bo {
diff --git a/drivers/gpu/drm/cirrus/cirrus_fbdev.c b/drivers/gpu/drm/cirrus/cirrus_fbdev.c
index 1e64d6f..6c6b4c8 100644
--- a/drivers/gpu/drm/cirrus/cirrus_fbdev.c
+++ b/drivers/gpu/drm/cirrus/cirrus_fbdev.c
@@ -26,51 +26,16 @@ static void cirrus_dirty_update(struct cirrus_fbdev *afbdev,
int bpp = (afbdev->gfb.base.bits_per_pixel + 7)/8;
int ret;
bool unmap = false;
- bool store_for_later = false;
- int x2, y2;
- unsigned long flags;
obj = afbdev->gfb.obj;
bo = gem_to_cirrus_bo(obj);
- /*
- * try and reserve the BO, if we fail with busy
- * then the BO is being moved and we should
- * store up the damage until later.
- */
ret = cirrus_bo_reserve(bo, true);
if (ret) {
- if (ret != -EBUSY)
- return;
- store_for_later = true;
- }
-
- x2 = x + width - 1;
- y2 = y + height - 1;
- spin_lock_irqsave(&afbdev->dirty_lock, flags);
-
- if (afbdev->y1 < y)
- y = afbdev->y1;
- if (afbdev->y2 > y2)
- y2 = afbdev->y2;
- if (afbdev->x1 < x)
- x = afbdev->x1;
- if (afbdev->x2 > x2)
- x2 = afbdev->x2;
-
- if (store_for_later) {
- afbdev->x1 = x;
- afbdev->x2 = x2;
- afbdev->y1 = y;
- afbdev->y2 = y2;
- spin_unlock_irqrestore(&afbdev->dirty_lock, flags);
+ DRM_ERROR("failed to reserve fb bo\n");
return;
}
- afbdev->x1 = afbdev->y1 = INT_MAX;
- afbdev->x2 = afbdev->y2 = 0;
- spin_unlock_irqrestore(&afbdev->dirty_lock, flags);
-
if (!bo->kmap.virtual) {
ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &bo->kmap);
if (ret) {
@@ -317,7 +282,6 @@ int cirrus_fbdev_init(struct cirrus_device *cdev)
cdev->mode_info.gfbdev = gfbdev;
gfbdev->helper.funcs = &cirrus_fb_helper_funcs;
- spin_lock_init(&gfbdev->dirty_lock);
ret = drm_fb_helper_init(cdev->dev, &gfbdev->helper,
cdev->num_crtc, CIRRUSFB_CONN_LIMIT);
diff --git a/drivers/gpu/drm/cirrus/cirrus_ttm.c b/drivers/gpu/drm/cirrus/cirrus_ttm.c
index 2ed8cfc..1413a26 100644
--- a/drivers/gpu/drm/cirrus/cirrus_ttm.c
+++ b/drivers/gpu/drm/cirrus/cirrus_ttm.c
@@ -321,7 +321,7 @@ int cirrus_bo_reserve(struct cirrus_bo *bo, bool no_wait)
ret = ttm_bo_reserve(&bo->bo, true, no_wait, false, 0);
if (ret) {
- if (ret != -ERESTARTSYS && ret != -EBUSY)
+ if (ret != -ERESTARTSYS)
DRM_ERROR("reserve failed %p\n", bo);
return ret;
}
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index bcb2c0a..f2d667b 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -2089,7 +2089,7 @@ uint32_t drm_mode_legacy_fb_format(uint32_t bpp, uint32_t depth)
switch (bpp) {
case 8:
- fmt = DRM_FORMAT_C8;
+ fmt = DRM_FORMAT_RGB332;
break;
case 16:
if (depth == 15)
@@ -3702,7 +3702,6 @@ void drm_fb_get_bpp_depth(uint32_t format, unsigned int *depth,
int *bpp)
{
switch (format) {
- case DRM_FORMAT_C8:
case DRM_FORMAT_RGB332:
case DRM_FORMAT_BGR233:
*depth = 8;
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index dfd9ed3..5a3770f 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -87,6 +87,9 @@ static struct edid_quirk {
int product_id;
u32 quirks;
} edid_quirk_list[] = {
+ /* ASUS VW222S */
+ { "ACI", 0x22a2, EDID_QUIRK_FORCE_REDUCED_BLANKING },
+
/* Acer AL1706 */
{ "ACR", 44358, EDID_QUIRK_PREFER_LARGE_60 },
/* Acer F51 */
@@ -354,14 +357,10 @@ drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter)
break;
}
}
-
- if (i == 4 && print_bad_edid) {
+ if (i == 4)
dev_warn(connector->dev->dev,
"%s: Ignoring invalid EDID block %d.\n",
drm_get_connector_name(connector), j);
-
- connector->bad_edid_counter++;
- }
}
if (valid_extensions != block[0x7e]) {
@@ -894,7 +893,7 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev,
unsigned vblank = (pt->vactive_vblank_hi & 0xf) << 8 | pt->vblank_lo;
unsigned hsync_offset = (pt->hsync_vsync_offset_pulse_width_hi & 0xc0) << 2 | pt->hsync_offset_lo;
unsigned hsync_pulse_width = (pt->hsync_vsync_offset_pulse_width_hi & 0x30) << 4 | pt->hsync_pulse_width_lo;
- unsigned vsync_offset = (pt->hsync_vsync_offset_pulse_width_hi & 0xc) << 2 | pt->vsync_offset_pulse_width_lo >> 4;
+ unsigned vsync_offset = (pt->hsync_vsync_offset_pulse_width_hi & 0xc) >> 2 | pt->vsync_offset_pulse_width_lo >> 4;
unsigned vsync_pulse_width = (pt->hsync_vsync_offset_pulse_width_hi & 0x3) << 4 | (pt->vsync_offset_pulse_width_lo & 0xf);
/* ignore tiny modes */
@@ -975,7 +974,6 @@ set_size:
}
mode->type = DRM_MODE_TYPE_DRIVER;
- mode->vrefresh = drm_mode_vrefresh(mode);
drm_mode_set_name(mode);
return mode;
@@ -2022,8 +2020,7 @@ int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid)
num_modes += add_cvt_modes(connector, edid);
num_modes += add_standard_modes(connector, edid);
num_modes += add_established_modes(connector, edid);
- if (edid->features & DRM_EDID_FEATURE_DEFAULT_GTF)
- num_modes += add_inferred_modes(connector, edid);
+ num_modes += add_inferred_modes(connector, edid);
num_modes += add_cea_modes(connector, edid);
if (quirks & (EDID_QUIRK_PREFER_LARGE_60 | EDID_QUIRK_PREFER_LARGE_75))
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
index 32d7775..133b413 100644
--- a/drivers/gpu/drm/drm_fops.c
+++ b/drivers/gpu/drm/drm_fops.c
@@ -123,7 +123,6 @@ int drm_open(struct inode *inode, struct file *filp)
int retcode = 0;
int need_setup = 0;
struct address_space *old_mapping;
- struct address_space *old_imapping;
minor = idr_find(&drm_minors_idr, minor_id);
if (!minor)
@@ -138,7 +137,6 @@ int drm_open(struct inode *inode, struct file *filp)
if (!dev->open_count++)
need_setup = 1;
mutex_lock(&dev->struct_mutex);
- old_imapping = inode->i_mapping;
old_mapping = dev->dev_mapping;
if (old_mapping == NULL)
dev->dev_mapping = &inode->i_data;
@@ -161,8 +159,8 @@ int drm_open(struct inode *inode, struct file *filp)
err_undo:
mutex_lock(&dev->struct_mutex);
- filp->f_mapping = old_imapping;
- inode->i_mapping = old_imapping;
+ filp->f_mapping = old_mapping;
+ inode->i_mapping = old_mapping;
iput(container_of(dev->dev_mapping, struct inode, i_data));
dev->dev_mapping = old_mapping;
mutex_unlock(&dev->struct_mutex);
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
index 539bae9..24efae4 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -205,11 +205,11 @@ static void
drm_gem_remove_prime_handles(struct drm_gem_object *obj, struct drm_file *filp)
{
if (obj->import_attach) {
- drm_prime_remove_buf_handle(&filp->prime,
+ drm_prime_remove_imported_buf_handle(&filp->prime,
obj->import_attach->dmabuf);
}
if (obj->export_dma_buf) {
- drm_prime_remove_buf_handle(&filp->prime,
+ drm_prime_remove_imported_buf_handle(&filp->prime,
obj->export_dma_buf);
}
}
diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
index 4f6439d..7f12573 100644
--- a/drivers/gpu/drm/drm_prime.c
+++ b/drivers/gpu/drm/drm_prime.c
@@ -61,7 +61,6 @@ struct drm_prime_member {
struct dma_buf *dma_buf;
uint32_t handle;
};
-static int drm_prime_add_buf_handle(struct drm_prime_file_private *prime_fpriv, struct dma_buf *dma_buf, uint32_t handle);
int drm_gem_prime_handle_to_fd(struct drm_device *dev,
struct drm_file *file_priv, uint32_t handle, uint32_t flags,
@@ -69,8 +68,7 @@ int drm_gem_prime_handle_to_fd(struct drm_device *dev,
{
struct drm_gem_object *obj;
void *buf;
- int ret = 0;
- struct dma_buf *dmabuf;
+ int ret;
obj = drm_gem_object_lookup(dev, file_priv, handle);
if (!obj)
@@ -79,44 +77,43 @@ int drm_gem_prime_handle_to_fd(struct drm_device *dev,
mutex_lock(&file_priv->prime.lock);
/* re-export the original imported object */
if (obj->import_attach) {
- dmabuf = obj->import_attach->dmabuf;
- goto out_have_obj;
+ get_dma_buf(obj->import_attach->dmabuf);
+ *prime_fd = dma_buf_fd(obj->import_attach->dmabuf, flags);
+ drm_gem_object_unreference_unlocked(obj);
+ mutex_unlock(&file_priv->prime.lock);
+ return 0;
}
if (obj->export_dma_buf) {
- dmabuf = obj->export_dma_buf;
- goto out_have_obj;
- }
-
- buf = dev->driver->gem_prime_export(dev, obj, flags);
- if (IS_ERR(buf)) {
- /* normally the created dma-buf takes ownership of the ref,
- * but if that fails then drop the ref
- */
- ret = PTR_ERR(buf);
- goto out;
+ get_dma_buf(obj->export_dma_buf);
+ *prime_fd = dma_buf_fd(obj->export_dma_buf, flags);
+ drm_gem_object_unreference_unlocked(obj);
+ } else {
+ buf = dev->driver->gem_prime_export(dev, obj, flags);
+ if (IS_ERR(buf)) {
+ /* normally the created dma-buf takes ownership of the ref,
+ * but if that fails then drop the ref
+ */
+ drm_gem_object_unreference_unlocked(obj);
+ mutex_unlock(&file_priv->prime.lock);
+ return PTR_ERR(buf);
+ }
+ obj->export_dma_buf = buf;
+ *prime_fd = dma_buf_fd(buf, flags);
}
- obj->export_dma_buf = buf;
-
/* if we've exported this buffer the cheat and add it to the import list
* so we get the correct handle back
*/
- ret = drm_prime_add_buf_handle(&file_priv->prime,
- obj->export_dma_buf, handle);
- if (ret)
- goto out;
+ ret = drm_prime_add_imported_buf_handle(&file_priv->prime,
+ obj->export_dma_buf, handle);
+ if (ret) {
+ drm_gem_object_unreference_unlocked(obj);
+ mutex_unlock(&file_priv->prime.lock);
+ return ret;
+ }
- *prime_fd = dma_buf_fd(buf, flags);
mutex_unlock(&file_priv->prime.lock);
return 0;
-
-out_have_obj:
- get_dma_buf(dmabuf);
- *prime_fd = dma_buf_fd(dmabuf, flags);
-out:
- drm_gem_object_unreference_unlocked(obj);
- mutex_unlock(&file_priv->prime.lock);
- return ret;
}
EXPORT_SYMBOL(drm_gem_prime_handle_to_fd);
@@ -133,7 +130,7 @@ int drm_gem_prime_fd_to_handle(struct drm_device *dev,
mutex_lock(&file_priv->prime.lock);
- ret = drm_prime_lookup_buf_handle(&file_priv->prime,
+ ret = drm_prime_lookup_imported_buf_handle(&file_priv->prime,
dma_buf, handle);
if (!ret) {
ret = 0;
@@ -152,7 +149,7 @@ int drm_gem_prime_fd_to_handle(struct drm_device *dev,
if (ret)
goto out_put;
- ret = drm_prime_add_buf_handle(&file_priv->prime,
+ ret = drm_prime_add_imported_buf_handle(&file_priv->prime,
dma_buf, *handle);
if (ret)
goto fail;
@@ -310,7 +307,7 @@ void drm_prime_destroy_file_private(struct drm_prime_file_private *prime_fpriv)
}
EXPORT_SYMBOL(drm_prime_destroy_file_private);
-static int drm_prime_add_buf_handle(struct drm_prime_file_private *prime_fpriv, struct dma_buf *dma_buf, uint32_t handle)
+int drm_prime_add_imported_buf_handle(struct drm_prime_file_private *prime_fpriv, struct dma_buf *dma_buf, uint32_t handle)
{
struct drm_prime_member *member;
@@ -318,14 +315,14 @@ static int drm_prime_add_buf_handle(struct drm_prime_file_private *prime_fpriv,
if (!member)
return -ENOMEM;
- get_dma_buf(dma_buf);
member->dma_buf = dma_buf;
member->handle = handle;
list_add(&member->entry, &prime_fpriv->head);
return 0;
}
+EXPORT_SYMBOL(drm_prime_add_imported_buf_handle);
-int drm_prime_lookup_buf_handle(struct drm_prime_file_private *prime_fpriv, struct dma_buf *dma_buf, uint32_t *handle)
+int drm_prime_lookup_imported_buf_handle(struct drm_prime_file_private *prime_fpriv, struct dma_buf *dma_buf, uint32_t *handle)
{
struct drm_prime_member *member;
@@ -337,20 +334,19 @@ int drm_prime_lookup_buf_handle(struct drm_prime_file_private *prime_fpriv, stru
}
return -ENOENT;
}
-EXPORT_SYMBOL(drm_prime_lookup_buf_handle);
+EXPORT_SYMBOL(drm_prime_lookup_imported_buf_handle);
-void drm_prime_remove_buf_handle(struct drm_prime_file_private *prime_fpriv, struct dma_buf *dma_buf)
+void drm_prime_remove_imported_buf_handle(struct drm_prime_file_private *prime_fpriv, struct dma_buf *dma_buf)
{
struct drm_prime_member *member, *safe;
mutex_lock(&prime_fpriv->lock);
list_for_each_entry_safe(member, safe, &prime_fpriv->head, entry) {
if (member->dma_buf == dma_buf) {
- dma_buf_put(dma_buf);
list_del(&member->entry);
kfree(member);
}
}
mutex_unlock(&prime_fpriv->lock);
}
-EXPORT_SYMBOL(drm_prime_remove_buf_handle);
+EXPORT_SYMBOL(drm_prime_remove_imported_buf_handle);
diff --git a/drivers/gpu/drm/drm_usb.c b/drivers/gpu/drm/drm_usb.c
index 34a156f..3cec306 100644
--- a/drivers/gpu/drm/drm_usb.c
+++ b/drivers/gpu/drm/drm_usb.c
@@ -18,7 +18,7 @@ int drm_get_usb_dev(struct usb_interface *interface,
usbdev = interface_to_usbdev(interface);
dev->usbdev = usbdev;
- dev->dev = &interface->dev;
+ dev->dev = &usbdev->dev;
mutex_lock(&drm_global_mutex);
diff --git a/drivers/gpu/drm/gma500/psb_irq.c b/drivers/gpu/drm/gma500/psb_irq.c
index 029eccf..8652cdf 100644
--- a/drivers/gpu/drm/gma500/psb_irq.c
+++ b/drivers/gpu/drm/gma500/psb_irq.c
@@ -211,7 +211,7 @@ irqreturn_t psb_irq_handler(DRM_IRQ_ARGS)
vdc_stat = PSB_RVDC32(PSB_INT_IDENTITY_R);
- if (vdc_stat & (_PSB_PIPE_EVENT_FLAG|_PSB_IRQ_ASLE))
+ if (vdc_stat & _PSB_PIPE_EVENT_FLAG)
dsp_int = 1;
/* FIXME: Handle Medfield
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 261efc8e..9d4a2c2 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -103,7 +103,7 @@ static const char *cache_level_str(int type)
static void
describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
{
- seq_printf(m, "%pK: %s%s %8zdKiB %04x %04x %d %d %d%s%s%s",
+ seq_printf(m, "%p: %s%s %8zdKiB %04x %04x %d %d %d%s%s%s",
&obj->base,
get_pin_flag(obj),
get_tiling_flag(obj),
@@ -691,7 +691,7 @@ static int i915_error_state(struct seq_file *m, void *unused)
seq_printf(m, "Time: %ld s %ld us\n", error->time.tv_sec,
error->time.tv_usec);
- seq_printf(m, "Kernel: " UTS_RELEASE "\n");
+ seq_printf(m, "Kernel: " UTS_RELEASE);
seq_printf(m, "PCI ID: 0x%04x\n", dev->pci_device);
seq_printf(m, "EIR: 0x%08x\n", error->eir);
seq_printf(m, "IER: 0x%08x\n", error->ier);
@@ -888,7 +888,7 @@ static int i915_cur_delayinfo(struct seq_file *m, void *unused)
u32 gt_perf_status = I915_READ(GEN6_GT_PERF_STATUS);
u32 rp_state_limits = I915_READ(GEN6_RP_STATE_LIMITS);
u32 rp_state_cap = I915_READ(GEN6_RP_STATE_CAP);
- u32 rpstat, cagf;
+ u32 rpstat;
u32 rpupei, rpcurup, rpprevup;
u32 rpdownei, rpcurdown, rpprevdown;
int max_freq;
@@ -907,11 +907,6 @@ static int i915_cur_delayinfo(struct seq_file *m, void *unused)
rpdownei = I915_READ(GEN6_RP_CUR_DOWN_EI);
rpcurdown = I915_READ(GEN6_RP_CUR_DOWN);
rpprevdown = I915_READ(GEN6_RP_PREV_DOWN);
- if (IS_HASWELL(dev))
- cagf = (rpstat & HSW_CAGF_MASK) >> HSW_CAGF_SHIFT;
- else
- cagf = (rpstat & GEN6_CAGF_MASK) >> GEN6_CAGF_SHIFT;
- cagf *= GT_FREQUENCY_MULTIPLIER;
gen6_gt_force_wake_put(dev_priv);
mutex_unlock(&dev->struct_mutex);
@@ -924,7 +919,8 @@ static int i915_cur_delayinfo(struct seq_file *m, void *unused)
gt_perf_status & 0xff);
seq_printf(m, "Render p-state limit: %d\n",
rp_state_limits & 0xff);
- seq_printf(m, "CAGF: %dMHz\n", cagf);
+ seq_printf(m, "CAGF: %dMHz\n", ((rpstat & GEN6_CAGF_MASK) >>
+ GEN6_CAGF_SHIFT) * GT_FREQUENCY_MULTIPLIER);
seq_printf(m, "RP CUR UP EI: %dus\n", rpupei &
GEN6_CURICONT_MASK);
seq_printf(m, "RP CUR UP: %dus\n", rpcurup &
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 79f5fc5..1172658 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -377,15 +377,15 @@ static const struct pci_device_id pciidlist[] = { /* aka */
INTEL_VGA_DEVICE(0x0A06, &intel_haswell_m_info), /* ULT GT1 mobile */
INTEL_VGA_DEVICE(0x0A16, &intel_haswell_m_info), /* ULT GT2 mobile */
INTEL_VGA_DEVICE(0x0A26, &intel_haswell_m_info), /* ULT GT2 mobile */
- INTEL_VGA_DEVICE(0x0D02, &intel_haswell_d_info), /* CRW GT1 desktop */
- INTEL_VGA_DEVICE(0x0D12, &intel_haswell_d_info), /* CRW GT2 desktop */
+ INTEL_VGA_DEVICE(0x0D12, &intel_haswell_d_info), /* CRW GT1 desktop */
INTEL_VGA_DEVICE(0x0D22, &intel_haswell_d_info), /* CRW GT2 desktop */
- INTEL_VGA_DEVICE(0x0D0A, &intel_haswell_d_info), /* CRW GT1 server */
- INTEL_VGA_DEVICE(0x0D1A, &intel_haswell_d_info), /* CRW GT2 server */
+ INTEL_VGA_DEVICE(0x0D32, &intel_haswell_d_info), /* CRW GT2 desktop */
+ INTEL_VGA_DEVICE(0x0D1A, &intel_haswell_d_info), /* CRW GT1 server */
INTEL_VGA_DEVICE(0x0D2A, &intel_haswell_d_info), /* CRW GT2 server */
- INTEL_VGA_DEVICE(0x0D06, &intel_haswell_m_info), /* CRW GT1 mobile */
- INTEL_VGA_DEVICE(0x0D16, &intel_haswell_m_info), /* CRW GT2 mobile */
+ INTEL_VGA_DEVICE(0x0D3A, &intel_haswell_d_info), /* CRW GT2 server */
+ INTEL_VGA_DEVICE(0x0D16, &intel_haswell_m_info), /* CRW GT1 mobile */
INTEL_VGA_DEVICE(0x0D26, &intel_haswell_m_info), /* CRW GT2 mobile */
+ INTEL_VGA_DEVICE(0x0D36, &intel_haswell_m_info), /* CRW GT2 mobile */
INTEL_VGA_DEVICE(0x0f30, &intel_valleyview_m_info),
INTEL_VGA_DEVICE(0x0157, &intel_valleyview_m_info),
INTEL_VGA_DEVICE(0x0155, &intel_valleyview_d_info),
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index e78419f..12ab3bd 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -711,7 +711,6 @@ typedef struct drm_i915_private {
unsigned int int_crt_support:1;
unsigned int lvds_use_ssc:1;
unsigned int display_clock_mode:1;
- unsigned int fdi_rx_polarity_inverted:1;
int lvds_ssc_freq;
unsigned int bios_lvds_val; /* initial [PCH_]LVDS reg val in VBIOS */
unsigned int lvds_val; /* used for checking LVDS channel mode */
@@ -775,7 +774,6 @@ typedef struct drm_i915_private {
unsigned long gtt_start;
unsigned long gtt_mappable_end;
unsigned long gtt_end;
- unsigned long stolen_base; /* limited to low memory (32-bit) */
struct io_mapping *gtt_mapping;
phys_addr_t gtt_base_addr;
@@ -921,7 +919,7 @@ typedef struct drm_i915_private {
bool hw_contexts_disabled;
uint32_t hw_context_size;
- u32 fdi_rx_config;
+ bool fdi_rx_polarity_reversed;
struct i915_suspend_saved_registers regfile;
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 339540d..8febea6 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -91,6 +91,7 @@ i915_gem_wait_for_error(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct completion *x = &dev_priv->error_completion;
+ unsigned long flags;
int ret;
if (!atomic_read(&dev_priv->mm.wedged))
@@ -115,7 +116,9 @@ i915_gem_wait_for_error(struct drm_device *dev)
* end up waiting upon a subsequent completion event that
* will never happen.
*/
- complete(x);
+ spin_lock_irqsave(&x->wait.lock, flags);
+ x->done++;
+ spin_unlock_irqrestore(&x->wait.lock, flags);
}
return 0;
}
@@ -943,9 +946,12 @@ i915_gem_check_wedge(struct drm_i915_private *dev_priv,
if (atomic_read(&dev_priv->mm.wedged)) {
struct completion *x = &dev_priv->error_completion;
bool recovery_complete;
+ unsigned long flags;
/* Give the error handler a chance to run. */
- recovery_complete = completion_done(x);
+ spin_lock_irqsave(&x->wait.lock, flags);
+ recovery_complete = x->done > 0;
+ spin_unlock_irqrestore(&x->wait.lock, flags);
/* Non-interruptible callers can't handle -EAGAIN, hence return
* -EIO unconditionally for these. */
@@ -1912,6 +1918,9 @@ i915_gem_object_move_to_inactive(struct drm_i915_gem_object *obj)
BUG_ON(obj->base.write_domain & ~I915_GEM_GPU_DOMAINS);
BUG_ON(!obj->active);
+ if (obj->pin_count) /* are we a framebuffer? */
+ intel_mark_fb_idle(obj);
+
list_move_tail(&obj->mm_list, &dev_priv->mm.inactive_list);
list_del_init(&obj->ring_list);
@@ -2656,35 +2665,17 @@ static inline int fence_number(struct drm_i915_private *dev_priv,
return fence - dev_priv->fence_regs;
}
-static void i915_gem_write_fence__ipi(void *data)
-{
- wbinvd();
-}
-
static void i915_gem_object_update_fence(struct drm_i915_gem_object *obj,
struct drm_i915_fence_reg *fence,
bool enable)
{
- struct drm_device *dev = obj->base.dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
- int fence_reg = fence_number(dev_priv, fence);
-
- /* In order to fully serialize access to the fenced region and
- * the update to the fence register we need to take extreme
- * measures on SNB+. In theory, the write to the fence register
- * flushes all memory transactions before, and coupled with the
- * mb() placed around the register write we serialise all memory
- * operations with respect to the changes in the tiler. Yet, on
- * SNB+ we need to take a step further and emit an explicit wbinvd()
- * on each processor in order to manually flush all memory
- * transactions before updating the fence register.
- */
- if (HAS_LLC(obj->base.dev))
- on_each_cpu(i915_gem_write_fence__ipi, NULL, 1);
- i915_gem_write_fence(dev, fence_reg, enable ? obj : NULL);
+ struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
+ int reg = fence_number(dev_priv, fence);
+
+ i915_gem_write_fence(obj->base.dev, reg, enable ? obj : NULL);
if (enable) {
- obj->fence_reg = fence_reg;
+ obj->fence_reg = reg;
fence->obj = obj;
list_move_tail(&fence->lru_list, &dev_priv->mm.fence_list);
} else {
@@ -3857,7 +3848,7 @@ void i915_gem_l3_remap(struct drm_device *dev)
u32 misccpctl;
int i;
- if (!HAS_L3_GPU_CACHE(dev))
+ if (!IS_IVYBRIDGE(dev))
return;
if (!dev_priv->l3_parity.remap_info)
@@ -4378,7 +4369,7 @@ static bool mutex_is_locked_by(struct mutex *mutex, struct task_struct *task)
if (!mutex_is_locked(mutex))
return false;
-#if (defined(CONFIG_SMP) || defined(CONFIG_DEBUG_MUTEXES)) && !defined(CONFIG_PREEMPT_RT_BASE)
+#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_MUTEXES)
return mutex->owner == task;
#else
/* Since UP may be pre-empted, we cannot assume that we own the lock */
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index d8ac0a3..a3f06bc 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -157,13 +157,6 @@ create_hw_context(struct drm_device *dev,
return ERR_PTR(-ENOMEM);
}
- if (INTEL_INFO(dev)->gen >= 7) {
- ret = i915_gem_object_set_cache_level(ctx->obj,
- I915_CACHE_LLC_MLC);
- if (ret)
- goto err_out;
- }
-
/* The ring associated with the context object is handled by the normal
* object tracking code. We give an initial ring value simple to pass an
* assertion in the context switch code.
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index eabd3dd..26d08bb 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -43,7 +43,7 @@ eb_create(int size)
{
struct eb_objects *eb;
int count = PAGE_SIZE / sizeof(struct hlist_head) / 2;
- BUILD_BUG_ON_NOT_POWER_OF_2(PAGE_SIZE / sizeof(struct hlist_head));
+ BUILD_BUG_ON(!is_power_of_2(PAGE_SIZE / sizeof(struct hlist_head)));
while (count > size)
count >>= 1;
eb = kzalloc(count*sizeof(struct hlist_head) +
@@ -706,20 +706,15 @@ validate_exec_list(struct drm_i915_gem_exec_object2 *exec,
int count)
{
int i;
- int relocs_total = 0;
- int relocs_max = INT_MAX / sizeof(struct drm_i915_gem_relocation_entry);
for (i = 0; i < count; i++) {
char __user *ptr = (char __user *)(uintptr_t)exec[i].relocs_ptr;
int length; /* limited by fault_in_pages_readable() */
- /* First check for malicious input causing overflow in
- * the worst case where we need to allocate the entire
- * relocation tree as a single array.
- */
- if (exec[i].relocation_count > relocs_max - relocs_total)
+ /* First check for malicious input causing overflow */
+ if (exec[i].relocation_count >
+ INT_MAX / sizeof(struct drm_i915_gem_relocation_entry))
return -EINVAL;
- relocs_total += exec[i].relocation_count;
length = exec[i].relocation_count *
sizeof(struct drm_i915_gem_relocation_entry);
@@ -814,7 +809,6 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
struct intel_ring_buffer *ring;
u32 ctx_id = i915_execbuffer2_get_context_id(*args);
u32 exec_start, exec_len;
- u32 seqno;
u32 mask;
u32 flags;
int ret, mode, i;
@@ -1069,9 +1063,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
goto err;
}
- seqno = intel_ring_get_seqno(ring);
- trace_i915_gem_ring_dispatch(ring, seqno, flags);
- i915_trace_irq_get(ring, seqno);
+ trace_i915_gem_ring_dispatch(ring, intel_ring_get_seqno(ring), flags);
i915_gem_execbuffer_move_to_active(&objects, ring);
i915_gem_execbuffer_retire_commands(dev, file, ring);
diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c
index be24312..8e91083 100644
--- a/drivers/gpu/drm/i915/i915_gem_stolen.c
+++ b/drivers/gpu/drm/i915/i915_gem_stolen.c
@@ -42,50 +42,56 @@
* for is a boon.
*/
-static unsigned long i915_stolen_to_physical(struct drm_device *dev)
+#define PTE_ADDRESS_MASK 0xfffff000
+#define PTE_ADDRESS_MASK_HIGH 0x000000f0 /* i915+ */
+#define PTE_MAPPING_TYPE_UNCACHED (0 << 1)
+#define PTE_MAPPING_TYPE_DCACHE (1 << 1) /* i830 only */
+#define PTE_MAPPING_TYPE_CACHED (3 << 1)
+#define PTE_MAPPING_TYPE_MASK (3 << 1)
+#define PTE_VALID (1 << 0)
+
+/**
+ * i915_stolen_to_phys - take an offset into stolen memory and turn it into
+ * a physical one
+ * @dev: drm device
+ * @offset: address to translate
+ *
+ * Some chip functions require allocations from stolen space and need the
+ * physical address of the memory in question.
+ */
+static unsigned long i915_stolen_to_phys(struct drm_device *dev, u32 offset)
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct pci_dev *pdev = dev_priv->bridge_dev;
u32 base;
+#if 0
/* On the machines I have tested the Graphics Base of Stolen Memory
- * is unreliable, so on those compute the base by subtracting the
- * stolen memory from the Top of Low Usable DRAM which is where the
- * BIOS places the graphics stolen memory.
- *
- * On gen2, the layout is slightly different with the Graphics Segment
- * immediately following Top of Memory (or Top of Usable DRAM). Note
- * it appears that TOUD is only reported by 865g, so we just use the
- * top of memory as determined by the e820 probe.
- *
- * XXX gen2 requires an unavailable symbol and 945gm fails with
- * its value of TOLUD.
+ * is unreliable, so compute the base by subtracting the stolen memory
+ * from the Top of Low Usable DRAM which is where the BIOS places
+ * the graphics stolen memory.
*/
- base = 0;
- if (INTEL_INFO(dev)->gen >= 6) {
- /* Read Base Data of Stolen Memory Register (BDSM) directly.
- * Note that there is also a MCHBAR miror at 0x1080c0 or
- * we could use device 2:0x5c instead.
- */
- pci_read_config_dword(pdev, 0xB0, &base);
- base &= ~4095; /* lower bits used for locking register */
- } else if (INTEL_INFO(dev)->gen > 3 || IS_G33(dev)) {
- /* Read Graphics Base of Stolen Memory directly */
+ if (INTEL_INFO(dev)->gen > 3 || IS_G33(dev)) {
+ /* top 32bits are reserved = 0 */
pci_read_config_dword(pdev, 0xA4, &base);
-#if 0
- } else if (IS_GEN3(dev)) {
+ } else {
+ /* XXX presume 8xx is the same as i915 */
+ pci_bus_read_config_dword(pdev->bus, 2, 0x5C, &base);
+ }
+#else
+ if (INTEL_INFO(dev)->gen > 3 || IS_G33(dev)) {
+ u16 val;
+ pci_read_config_word(pdev, 0xb0, &val);
+ base = val >> 4 << 20;
+ } else {
u8 val;
- /* Stolen is immediately below Top of Low Usable DRAM */
pci_read_config_byte(pdev, 0x9c, &val);
base = val >> 3 << 27;
- base -= dev_priv->mm.gtt->stolen_size;
- } else {
- /* Stolen is immediately above Top of Memory */
- base = max_low_pfn_mapped << PAGE_SHIFT;
-#endif
}
+ base -= dev_priv->mm.gtt->stolen_size;
+#endif
- return base;
+ return base + offset;
}
static void i915_warn_stolen(struct drm_device *dev)
@@ -110,7 +116,7 @@ static void i915_setup_compression(struct drm_device *dev, int size)
if (!compressed_fb)
goto err;
- cfb_base = dev_priv->mm.stolen_base + compressed_fb->start;
+ cfb_base = i915_stolen_to_phys(dev, compressed_fb->start);
if (!cfb_base)
goto err_fb;
@@ -123,7 +129,7 @@ static void i915_setup_compression(struct drm_device *dev, int size)
if (!compressed_llb)
goto err_fb;
- ll_base = dev_priv->mm.stolen_base + compressed_llb->start;
+ ll_base = i915_stolen_to_phys(dev, compressed_llb->start);
if (!ll_base)
goto err_llb;
}
@@ -142,7 +148,7 @@ static void i915_setup_compression(struct drm_device *dev, int size)
}
DRM_DEBUG_KMS("FBC base 0x%08lx, ll base 0x%08lx, size %dM\n",
- (long)cfb_base, (long)ll_base, size >> 20);
+ cfb_base, ll_base, size >> 20);
return;
err_llb:
@@ -174,13 +180,6 @@ int i915_gem_init_stolen(struct drm_device *dev)
struct drm_i915_private *dev_priv = dev->dev_private;
unsigned long prealloc_size = dev_priv->mm.gtt->stolen_size;
- dev_priv->mm.stolen_base = i915_stolen_to_physical(dev);
- if (dev_priv->mm.stolen_base == 0)
- return 0;
-
- DRM_DEBUG_KMS("found %d bytes of stolen memory at %08lx\n",
- dev_priv->mm.gtt->stolen_size, dev_priv->mm.stolen_base);
-
/* Basic memrange allocator for stolen space */
drm_mm_init(&dev_priv->mm.stolen, 0, prealloc_size);
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index ce70f0a..59afb7e 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -3839,7 +3839,7 @@
#define _TRANSB_CHICKEN2 0xf1064
#define TRANS_CHICKEN2(pipe) _PIPE(pipe, _TRANSA_CHICKEN2, _TRANSB_CHICKEN2)
#define TRANS_CHICKEN2_TIMING_OVERRIDE (1<<31)
-#define TRANS_CHICKEN2_FDI_POLARITY_REVERSED (1<<29)
+
#define SOUTH_CHICKEN1 0xc2000
#define FDIA_PHASE_SYNC_SHIFT_OVR 19
@@ -3927,7 +3927,7 @@
#define FDI_10BPC (1<<16)
#define FDI_6BPC (2<<16)
#define FDI_12BPC (3<<16)
-#define FDI_RX_LINK_REVERSAL_OVERRIDE (1<<15)
+#define FDI_LINK_REVERSE_OVERWRITE (1<<15)
#define FDI_DMI_LINK_REVERSE_MASK (1<<14)
#define FDI_RX_PLL_ENABLE (1<<13)
#define FDI_FS_ERR_CORRECT_ENABLE (1<<11)
@@ -4211,9 +4211,7 @@
#define GEN6_RP_INTERRUPT_LIMITS 0xA014
#define GEN6_RPSTAT1 0xA01C
#define GEN6_CAGF_SHIFT 8
-#define HSW_CAGF_SHIFT 7
#define GEN6_CAGF_MASK (0x7f << GEN6_CAGF_SHIFT)
-#define HSW_CAGF_MASK (0x7f << HSW_CAGF_SHIFT)
#define GEN6_RP_CONTROL 0xA024
#define GEN6_RP_MEDIA_TURBO (1<<11)
#define GEN6_RP_MEDIA_MODE_MASK (3<<9)
@@ -4282,8 +4280,8 @@
#define GEN6_PCODE_READ_MIN_FREQ_TABLE 0x9
#define GEN6_PCODE_WRITE_RC6VIDS 0x4
#define GEN6_PCODE_READ_RC6VIDS 0x5
-#define GEN6_ENCODE_RC6_VID(mv) (((mv) - 245) / 5)
-#define GEN6_DECODE_RC6_VID(vids) (((vids) * 5) + 245)
+#define GEN6_ENCODE_RC6_VID(mv) (((mv) / 5) - 245) < 0 ?: 0
+#define GEN6_DECODE_RC6_VID(vids) (((vids) * 5) > 0 ? ((vids) * 5) + 245 : 0)
#define GEN6_PCODE_DATA 0x138128
#define GEN6_PCODE_FREQ_IA_RATIO_SHIFT 8
@@ -4526,7 +4524,6 @@
#define DDI_BUF_EMP_800MV_0DB_HSW (7<<24) /* Sel7 */
#define DDI_BUF_EMP_800MV_3_5DB_HSW (8<<24) /* Sel8 */
#define DDI_BUF_EMP_MASK (0xf<<24)
-#define DDI_BUF_PORT_REVERSAL (1<<16)
#define DDI_BUF_IS_IDLE (1<<7)
#define DDI_A_4_LANES (1<<4)
#define DDI_PORT_WIDTH_X1 (0<<1)
diff --git a/drivers/gpu/drm/i915/i915_trace.h b/drivers/gpu/drm/i915/i915_trace.h
index 29217db..3db4a68 100644
--- a/drivers/gpu/drm/i915/i915_trace.h
+++ b/drivers/gpu/drm/i915/i915_trace.h
@@ -244,6 +244,7 @@ TRACE_EVENT(i915_gem_ring_dispatch,
__entry->ring = ring->id;
__entry->seqno = seqno;
__entry->flags = flags;
+ i915_trace_irq_get(ring, seqno);
),
TP_printk("dev=%u, ring=%u, seqno=%u, flags=%x",
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
index bd83391..55ffba1 100644
--- a/drivers/gpu/drm/i915/intel_bios.c
+++ b/drivers/gpu/drm/i915/intel_bios.c
@@ -351,14 +351,12 @@ parse_general_features(struct drm_i915_private *dev_priv,
dev_priv->lvds_ssc_freq =
intel_bios_ssc_frequency(dev, general->ssc_freq);
dev_priv->display_clock_mode = general->display_clock_mode;
- dev_priv->fdi_rx_polarity_inverted = general->fdi_rx_polarity_inverted;
- DRM_DEBUG_KMS("BDB_GENERAL_FEATURES int_tv_support %d int_crt_support %d lvds_use_ssc %d lvds_ssc_freq %d display_clock_mode %d fdi_rx_polarity_inverted %d\n",
+ DRM_DEBUG_KMS("BDB_GENERAL_FEATURES int_tv_support %d int_crt_support %d lvds_use_ssc %d lvds_ssc_freq %d display_clock_mode %d\n",
dev_priv->int_tv_support,
dev_priv->int_crt_support,
dev_priv->lvds_use_ssc,
dev_priv->lvds_ssc_freq,
- dev_priv->display_clock_mode,
- dev_priv->fdi_rx_polarity_inverted);
+ dev_priv->display_clock_mode);
}
}
diff --git a/drivers/gpu/drm/i915/intel_bios.h b/drivers/gpu/drm/i915/intel_bios.h
index e088d6f..36e57f9 100644
--- a/drivers/gpu/drm/i915/intel_bios.h
+++ b/drivers/gpu/drm/i915/intel_bios.h
@@ -127,9 +127,7 @@ struct bdb_general_features {
/* bits 3 */
u8 disable_smooth_vision:1;
u8 single_dvi:1;
- u8 rsvd9:1;
- u8 fdi_rx_polarity_inverted:1;
- u8 rsvd10:4; /* finish byte */
+ u8 rsvd9:6; /* finish byte */
/* bits 4 */
u8 legacy_monitor_detect;
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
index 625b091..9293878 100644
--- a/drivers/gpu/drm/i915/intel_crt.c
+++ b/drivers/gpu/drm/i915/intel_crt.c
@@ -45,9 +45,6 @@
struct intel_crt {
struct intel_encoder base;
- /* DPMS state is stored in the connector, which we need in the
- * encoder's enable/disable callbacks */
- struct intel_connector *connector;
bool force_hotplug_required;
u32 adpa_reg;
};
@@ -84,6 +81,29 @@ static bool intel_crt_get_hw_state(struct intel_encoder *encoder,
return true;
}
+static void intel_disable_crt(struct intel_encoder *encoder)
+{
+ struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
+ struct intel_crt *crt = intel_encoder_to_crt(encoder);
+ u32 temp;
+
+ temp = I915_READ(crt->adpa_reg);
+ temp &= ~(ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE);
+ temp &= ~ADPA_DAC_ENABLE;
+ I915_WRITE(crt->adpa_reg, temp);
+}
+
+static void intel_enable_crt(struct intel_encoder *encoder)
+{
+ struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
+ struct intel_crt *crt = intel_encoder_to_crt(encoder);
+ u32 temp;
+
+ temp = I915_READ(crt->adpa_reg);
+ temp |= ADPA_DAC_ENABLE;
+ I915_WRITE(crt->adpa_reg, temp);
+}
+
/* Note: The caller is required to filter out dpms modes not supported by the
* platform. */
static void intel_crt_set_dpms(struct intel_encoder *encoder, int mode)
@@ -115,19 +135,6 @@ static void intel_crt_set_dpms(struct intel_encoder *encoder, int mode)
I915_WRITE(crt->adpa_reg, temp);
}
-static void intel_disable_crt(struct intel_encoder *encoder)
-{
- intel_crt_set_dpms(encoder, DRM_MODE_DPMS_OFF);
-}
-
-static void intel_enable_crt(struct intel_encoder *encoder)
-{
- struct intel_crt *crt = intel_encoder_to_crt(encoder);
-
- intel_crt_set_dpms(encoder, crt->connector->base.dpms);
-}
-
-
static void intel_crt_dpms(struct drm_connector *connector, int mode)
{
struct drm_device *dev = connector->dev;
@@ -739,7 +746,6 @@ void intel_crt_init(struct drm_device *dev)
}
connector = &intel_connector->base;
- crt->connector = intel_connector;
drm_connector_init(dev, &intel_connector->base,
&intel_crt_connector_funcs, DRM_MODE_CONNECTOR_VGA);
@@ -794,14 +800,10 @@ void intel_crt_init(struct drm_device *dev)
dev_priv->hotplug_supported_mask |= CRT_HOTPLUG_INT_STATUS;
/*
- * TODO: find a proper way to discover whether we need to set the the
- * polarity and link reversal bits or not, instead of relying on the
- * BIOS.
+ * TODO: find a proper way to discover whether we need to set the
+ * polarity reversal bit or not, instead of relying on the BIOS.
*/
- if (HAS_PCH_LPT(dev)) {
- u32 fdi_config = FDI_RX_POLARITY_REVERSED_LPT |
- FDI_RX_LINK_REVERSAL_OVERRIDE;
-
- dev_priv->fdi_rx_config = I915_READ(_FDI_RXA_CTL) & fdi_config;
- }
+ if (HAS_PCH_LPT(dev))
+ dev_priv->fdi_rx_polarity_reversed =
+ !!(I915_READ(_FDI_RXA_CTL) & FDI_RX_POLARITY_REVERSED_LPT);
}
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index 59b778d..4bad0f7 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -178,8 +178,10 @@ void hsw_fdi_link_train(struct drm_crtc *crtc)
FDI_RX_TP1_TO_TP2_48 | FDI_RX_FDI_DELAY_90);
/* Enable the PCH Receiver FDI PLL */
- rx_ctl_val = dev_priv->fdi_rx_config | FDI_RX_ENHANCE_FRAME_ENABLE |
- FDI_RX_PLL_ENABLE | ((intel_crtc->fdi_lanes - 1) << 19);
+ rx_ctl_val = FDI_RX_PLL_ENABLE | FDI_RX_ENHANCE_FRAME_ENABLE |
+ ((intel_crtc->fdi_lanes - 1) << 19);
+ if (dev_priv->fdi_rx_polarity_reversed)
+ rx_ctl_val |= FDI_RX_POLARITY_REVERSED_LPT;
I915_WRITE(_FDI_RXA_CTL, rx_ctl_val);
POSTING_READ(_FDI_RXA_CTL);
udelay(220);
@@ -201,10 +203,7 @@ void hsw_fdi_link_train(struct drm_crtc *crtc)
DP_TP_CTL_LINK_TRAIN_PAT1 |
DP_TP_CTL_ENABLE);
- /* Configure and enable DDI_BUF_CTL for DDI E with next voltage.
- * DDI E does not support port reversal, the functionality is
- * achieved on the PCH side in FDI_RX_CTL, so no need to set the
- * port reversal bit */
+ /* Configure and enable DDI_BUF_CTL for DDI E with next voltage */
I915_WRITE(DDI_BUF_CTL(PORT_E),
DDI_BUF_CTL_ENABLE |
((intel_crtc->fdi_lanes - 1) << 1) |
@@ -678,11 +677,8 @@ static void intel_ddi_mode_set(struct drm_encoder *encoder,
if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
- struct intel_digital_port *intel_dig_port =
- enc_to_dig_port(encoder);
- intel_dp->DP = intel_dig_port->port_reversal |
- DDI_BUF_CTL_ENABLE | DDI_BUF_EMP_400MV_0DB_HSW;
+ intel_dp->DP = DDI_BUF_CTL_ENABLE | DDI_BUF_EMP_400MV_0DB_HSW;
switch (intel_dp->lane_count) {
case 1:
intel_dp->DP |= DDI_PORT_WIDTH_X1;
@@ -1295,15 +1291,11 @@ static void intel_enable_ddi(struct intel_encoder *intel_encoder)
int type = intel_encoder->type;
if (type == INTEL_OUTPUT_HDMI) {
- struct intel_digital_port *intel_dig_port =
- enc_to_dig_port(encoder);
-
/* In HDMI/DVI mode, the port width, and swing/emphasis values
* are ignored so nothing special needs to be done besides
* enabling the port.
*/
- I915_WRITE(DDI_BUF_CTL(port),
- intel_dig_port->port_reversal | DDI_BUF_CTL_ENABLE);
+ I915_WRITE(DDI_BUF_CTL(port), DDI_BUF_CTL_ENABLE);
} else if (type == INTEL_OUTPUT_EDP) {
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
@@ -1465,7 +1457,6 @@ static const struct drm_encoder_helper_funcs intel_ddi_helper_funcs = {
void intel_ddi_init(struct drm_device *dev, enum port port)
{
- struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_digital_port *intel_dig_port;
struct intel_encoder *intel_encoder;
struct drm_encoder *encoder;
@@ -1506,8 +1497,6 @@ void intel_ddi_init(struct drm_device *dev, enum port port)
intel_encoder->get_hw_state = intel_ddi_get_hw_state;
intel_dig_port->port = port;
- intel_dig_port->port_reversal = I915_READ(DDI_BUF_CTL(port)) &
- DDI_BUF_PORT_REVERSAL;
if (hdmi_connector)
intel_dig_port->hdmi.sdvox_reg = DDI_BUF_CTL(port);
else
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index faeaebc..da1ad9c 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -154,8 +154,8 @@ static const intel_limit_t intel_limits_i9xx_sdvo = {
.vco = { .min = 1400000, .max = 2800000 },
.n = { .min = 1, .max = 6 },
.m = { .min = 70, .max = 120 },
- .m1 = { .min = 8, .max = 18 },
- .m2 = { .min = 3, .max = 7 },
+ .m1 = { .min = 10, .max = 22 },
+ .m2 = { .min = 5, .max = 9 },
.p = { .min = 5, .max = 80 },
.p1 = { .min = 1, .max = 8 },
.p2 = { .dot_limit = 200000,
@@ -2017,29 +2017,18 @@ void intel_unpin_fb_obj(struct drm_i915_gem_object *obj)
/* Computes the linear offset to the base tile and adjusts x, y. bytes per pixel
* is assumed to be a power-of-two. */
-unsigned long intel_gen4_compute_page_offset(int *x, int *y,
- unsigned int tiling_mode,
- unsigned int cpp,
- unsigned int pitch)
+unsigned long intel_gen4_compute_offset_xtiled(int *x, int *y,
+ unsigned int bpp,
+ unsigned int pitch)
{
- if (tiling_mode != I915_TILING_NONE) {
- unsigned int tile_rows, tiles;
-
- tile_rows = *y / 8;
- *y %= 8;
+ int tile_rows, tiles;
- tiles = *x / (512/cpp);
- *x %= 512/cpp;
-
- return tile_rows * pitch * 8 + tiles * 4096;
- } else {
- unsigned int offset;
+ tile_rows = *y / 8;
+ *y %= 8;
+ tiles = *x / (512/bpp);
+ *x %= 512/bpp;
- offset = *y * pitch + *x * cpp;
- *y = 0;
- *x = (offset & 4095) / cpp;
- return offset & -4096;
- }
+ return tile_rows * pitch * 8 + tiles * 4096;
}
static int i9xx_update_plane(struct drm_crtc *crtc, struct drm_framebuffer *fb,
@@ -2116,9 +2105,9 @@ static int i9xx_update_plane(struct drm_crtc *crtc, struct drm_framebuffer *fb,
if (INTEL_INFO(dev)->gen >= 4) {
intel_crtc->dspaddr_offset =
- intel_gen4_compute_page_offset(&x, &y, obj->tiling_mode,
- fb->bits_per_pixel / 8,
- fb->pitches[0]);
+ intel_gen4_compute_offset_xtiled(&x, &y,
+ fb->bits_per_pixel / 8,
+ fb->pitches[0]);
linear_offset -= intel_crtc->dspaddr_offset;
} else {
intel_crtc->dspaddr_offset = linear_offset;
@@ -2209,9 +2198,9 @@ static int ironlake_update_plane(struct drm_crtc *crtc,
linear_offset = y * fb->pitches[0] + x * (fb->bits_per_pixel / 8);
intel_crtc->dspaddr_offset =
- intel_gen4_compute_page_offset(&x, &y, obj->tiling_mode,
- fb->bits_per_pixel / 8,
- fb->pitches[0]);
+ intel_gen4_compute_offset_xtiled(&x, &y,
+ fb->bits_per_pixel / 8,
+ fb->pitches[0]);
linear_offset -= intel_crtc->dspaddr_offset;
DRM_DEBUG_KMS("Writing base %08X %08lX %d %d %d\n",
@@ -3697,7 +3686,6 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc)
struct intel_encoder *encoder;
int pipe = intel_crtc->pipe;
int plane = intel_crtc->plane;
- u32 pctl;
if (!intel_crtc->active)
@@ -3717,13 +3705,6 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc)
intel_disable_plane(dev_priv, plane, pipe);
intel_disable_pipe(dev_priv, pipe);
-
- /* Disable pannel fitter if it is on this pipe. */
- pctl = I915_READ(PFIT_CONTROL);
- if ((pctl & PFIT_ENABLE) &&
- ((pctl & PFIT_PIPE_MASK) >> PFIT_PIPE_SHIFT) == pipe)
- I915_WRITE(PFIT_CONTROL, 0);
-
intel_disable_pll(dev_priv, pipe);
intel_crtc->active = false;
@@ -7012,6 +6993,11 @@ void intel_mark_busy(struct drm_device *dev)
void intel_mark_idle(struct drm_device *dev)
{
+}
+
+void intel_mark_fb_busy(struct drm_i915_gem_object *obj)
+{
+ struct drm_device *dev = obj->base.dev;
struct drm_crtc *crtc;
if (!i915_powersave)
@@ -7021,11 +7007,12 @@ void intel_mark_idle(struct drm_device *dev)
if (!crtc->fb)
continue;
- intel_decrease_pllclock(crtc);
+ if (to_intel_framebuffer(crtc->fb)->obj == obj)
+ intel_increase_pllclock(crtc);
}
}
-void intel_mark_fb_busy(struct drm_i915_gem_object *obj)
+void intel_mark_fb_idle(struct drm_i915_gem_object *obj)
{
struct drm_device *dev = obj->base.dev;
struct drm_crtc *crtc;
@@ -7038,7 +7025,7 @@ void intel_mark_fb_busy(struct drm_i915_gem_object *obj)
continue;
if (to_intel_framebuffer(crtc->fb)->obj == obj)
- intel_increase_pllclock(crtc);
+ intel_decrease_pllclock(crtc);
}
}
@@ -7420,8 +7407,8 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
{
struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct drm_framebuffer *old_fb = crtc->fb;
- struct drm_i915_gem_object *obj = to_intel_framebuffer(fb)->obj;
+ struct intel_framebuffer *intel_fb;
+ struct drm_i915_gem_object *obj;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct intel_unpin_work *work;
unsigned long flags;
@@ -7446,7 +7433,8 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
work->event = event;
work->crtc = crtc;
- work->old_fb_obj = to_intel_framebuffer(old_fb)->obj;
+ intel_fb = to_intel_framebuffer(crtc->fb);
+ work->old_fb_obj = intel_fb->obj;
INIT_WORK(&work->work, intel_unpin_work_fn);
ret = drm_vblank_get(dev, intel_crtc->pipe);
@@ -7466,6 +7454,9 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
intel_crtc->unpin_work = work;
spin_unlock_irqrestore(&dev->event_lock, flags);
+ intel_fb = to_intel_framebuffer(fb);
+ obj = intel_fb->obj;
+
if (atomic_read(&intel_crtc->unpin_work_count) >= 2)
flush_workqueue(dev_priv->wq);
@@ -7503,7 +7494,6 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
cleanup_pending:
atomic_dec(&intel_crtc->unpin_work_count);
- crtc->fb = old_fb;
atomic_sub(1 << intel_crtc->plane, &work->old_fb_obj->pending_flip);
drm_gem_object_unreference(&work->old_fb_obj->base);
drm_gem_object_unreference(&obj->base);
@@ -7732,25 +7722,22 @@ intel_modeset_affected_pipes(struct drm_crtc *crtc, unsigned *modeset_pipes,
if (crtc->enabled)
*prepare_pipes |= 1 << intel_crtc->pipe;
- /*
- * For simplicity do a full modeset on any pipe where the output routing
- * changed. We could be more clever, but that would require us to be
- * more careful with calling the relevant encoder->mode_set functions.
- */
+ /* We only support modeset on one single crtc, hence we need to do that
+ * only for the passed in crtc iff we change anything else than just
+ * disable crtcs.
+ *
+ * This is actually not true, to be fully compatible with the old crtc
+ * helper we automatically disable _any_ output (i.e. doesn't need to be
+ * connected to the crtc we're modesetting on) if it's disconnected.
+ * Which is a rather nutty api (since changed the output configuration
+ * without userspace's explicit request can lead to confusion), but
+ * alas. Hence we currently need to modeset on all pipes we prepare. */
if (*prepare_pipes)
*modeset_pipes = *prepare_pipes;
/* ... and mask these out. */
*modeset_pipes &= ~(*disable_pipes);
*prepare_pipes &= ~(*disable_pipes);
-
- /*
- * HACK: We don't (yet) fully support global modesets. intel_set_config
- * obies this rule, but the modeset restore mode of
- * intel_modeset_setup_hw_state does not.
- */
- *modeset_pipes &= 1 << intel_crtc->pipe;
- *prepare_pipes &= 1 << intel_crtc->pipe;
}
static bool intel_crtc_in_use(struct drm_crtc *crtc)
@@ -8901,18 +8888,6 @@ static struct intel_quirk intel_quirks[] = {
/* Acer Aspire 5734Z must invert backlight brightness */
{ 0x2a42, 0x1025, 0x0459, quirk_invert_brightness },
-
- /* Acer Aspire 4736Z */
- { 0x2a42, 0x1025, 0x0260, quirk_invert_brightness },
-
- /* Acer/eMachines G725 */
- { 0x2a42, 0x1025, 0x0210, quirk_invert_brightness },
-
- /* Acer/eMachines e725 */
- { 0x2a42, 0x1025, 0x0212, quirk_invert_brightness },
-
- /* Acer/Packard Bell NCL20 */
- { 0x2a42, 0x1025, 0x034b, quirk_invert_brightness },
};
static void intel_init_quirks(struct drm_device *dev)
@@ -9391,9 +9366,6 @@ void intel_modeset_cleanup(struct drm_device *dev)
/* flush any delayed tasks or pending work */
flush_scheduled_work();
- /* destroy backlight, if any, before the connectors */
- intel_panel_destroy_backlight(dev);
-
drm_mode_config_cleanup(dev);
}
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index cbe1ec3..fb3715b 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -788,7 +788,6 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
struct intel_dp_m_n m_n;
int pipe = intel_crtc->pipe;
enum transcoder cpu_transcoder = intel_crtc->cpu_transcoder;
- int target_clock;
/*
* Find the lane count in the intel_encoder private
@@ -804,22 +803,13 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
}
}
- target_clock = mode->clock;
- for_each_encoder_on_crtc(dev, crtc, intel_encoder) {
- if (intel_encoder->type == INTEL_OUTPUT_EDP) {
- target_clock = intel_edp_target_clock(intel_encoder,
- mode);
- break;
- }
- }
-
/*
* Compute the GMCH and Link ratios. The '3' here is
* the number of bytes_per_pixel post-LUT, which we always
* set up for 8-bits of R/G/B, or 3 bytes total.
*/
intel_dp_compute_m_n(intel_crtc->bpp, lane_count,
- target_clock, adjusted_mode->clock, &m_n);
+ mode->clock, adjusted_mode->clock, &m_n);
if (IS_HASWELL(dev)) {
I915_WRITE(PIPE_DATA_M1(cpu_transcoder),
@@ -1860,7 +1850,7 @@ intel_dp_start_link_train(struct intel_dp *intel_dp)
for (i = 0; i < intel_dp->lane_count; i++)
if ((intel_dp->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0)
break;
- if (i == intel_dp->lane_count) {
+ if (i == intel_dp->lane_count && voltage_tries == 5) {
++loop_tries;
if (loop_tries == 5) {
DRM_DEBUG_KMS("too many full retries, give up\n");
@@ -2467,14 +2457,17 @@ done:
static void
intel_dp_destroy(struct drm_connector *connector)
{
+ struct drm_device *dev = connector->dev;
struct intel_dp *intel_dp = intel_attached_dp(connector);
struct intel_connector *intel_connector = to_intel_connector(connector);
if (!IS_ERR_OR_NULL(intel_connector->edid))
kfree(intel_connector->edid);
- if (is_edp(intel_dp))
+ if (is_edp(intel_dp)) {
+ intel_panel_destroy_backlight(dev);
intel_panel_fini(&intel_connector->panel);
+ }
drm_sysfs_connector_remove(connector);
drm_connector_cleanup(connector);
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 1c1840f..8a1bd4a 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -377,7 +377,6 @@ struct intel_dp {
struct intel_digital_port {
struct intel_encoder base;
enum port port;
- u32 port_reversal;
struct intel_dp dp;
struct intel_hdmi hdmi;
};
@@ -440,8 +439,9 @@ extern bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg,
extern void intel_dvo_init(struct drm_device *dev);
extern void intel_tv_init(struct drm_device *dev);
extern void intel_mark_busy(struct drm_device *dev);
-extern void intel_mark_fb_busy(struct drm_i915_gem_object *obj);
extern void intel_mark_idle(struct drm_device *dev);
+extern void intel_mark_fb_busy(struct drm_i915_gem_object *obj);
+extern void intel_mark_fb_idle(struct drm_i915_gem_object *obj);
extern bool intel_lvds_init(struct drm_device *dev);
extern void intel_dp_init(struct drm_device *dev, int output_reg,
enum port port);
@@ -627,10 +627,9 @@ extern void intel_update_sprite_watermarks(struct drm_device *dev, int pipe,
extern void intel_update_linetime_watermarks(struct drm_device *dev, int pipe,
struct drm_display_mode *mode);
-extern unsigned long intel_gen4_compute_page_offset(int *x, int *y,
- unsigned int tiling_mode,
- unsigned int bpp,
- unsigned int pitch);
+extern unsigned long intel_gen4_compute_offset_xtiled(int *x, int *y,
+ unsigned int bpp,
+ unsigned int pitch);
extern int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
struct drm_file *file_priv);
diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c
index ba96e04..15da995 100644
--- a/drivers/gpu/drm/i915/intel_dvo.c
+++ b/drivers/gpu/drm/i915/intel_dvo.c
@@ -449,7 +449,6 @@ void intel_dvo_init(struct drm_device *dev)
const struct intel_dvo_device *dvo = &intel_dvo_devices[i];
struct i2c_adapter *i2c;
int gpio;
- bool dvoinit;
/* Allow the I2C driver info to specify the GPIO to be used in
* special cases, but otherwise default to what's defined
@@ -469,17 +468,7 @@ void intel_dvo_init(struct drm_device *dev)
i2c = intel_gmbus_get_adapter(dev_priv, gpio);
intel_dvo->dev = *dvo;
-
- /* GMBUS NAK handling seems to be unstable, hence let the
- * transmitter detection run in bit banging mode for now.
- */
- intel_gmbus_force_bit(i2c, true);
-
- dvoinit = dvo->dev_ops->init(&intel_dvo->dev, i2c);
-
- intel_gmbus_force_bit(i2c, false);
-
- if (!dvoinit)
+ if (!dvo->dev_ops->init(&intel_dvo->dev, i2c))
continue;
intel_encoder->type = INTEL_OUTPUT_DVO;
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index 8b383a6..17aee74 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -556,6 +556,7 @@ static void intel_lvds_destroy(struct drm_connector *connector)
if (!IS_ERR_OR_NULL(lvds_connector->base.edid))
kfree(lvds_connector->base.edid);
+ intel_panel_destroy_backlight(connector->dev);
intel_panel_fini(&lvds_connector->base.panel);
drm_sysfs_connector_remove(connector);
@@ -789,14 +790,6 @@ static const struct dmi_system_id intel_no_lvds[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "X7SPA-H"),
},
},
- {
- .callback = intel_no_lvds_dmi_callback,
- .ident = "Fujitsu Esprimo Q900",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
- DMI_MATCH(DMI_PRODUCT_NAME, "ESPRIMO Q900"),
- },
- },
{ } /* terminating entry */
};
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
index 94d895b..bee8cb6 100644
--- a/drivers/gpu/drm/i915/intel_panel.c
+++ b/drivers/gpu/drm/i915/intel_panel.c
@@ -422,9 +422,6 @@ int intel_panel_setup_backlight(struct drm_connector *connector)
intel_panel_init_backlight(dev);
- if (WARN_ON(dev_priv->backlight))
- return -ENODEV;
-
memset(&props, 0, sizeof(props));
props.type = BACKLIGHT_RAW;
props.max_brightness = _intel_panel_get_max_backlight(dev);
@@ -450,10 +447,8 @@ int intel_panel_setup_backlight(struct drm_connector *connector)
void intel_panel_destroy_backlight(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
- if (dev_priv->backlight) {
+ if (dev_priv->backlight)
backlight_device_unregister(dev_priv->backlight);
- dev_priv->backlight = NULL;
- }
}
#else
int intel_panel_setup_backlight(struct drm_connector *connector)
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 253bcf3..3280cff 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -2572,7 +2572,7 @@ static void gen6_enable_rps(struct drm_device *dev)
I915_WRITE(GEN6_RC_SLEEP, 0);
I915_WRITE(GEN6_RC1e_THRESHOLD, 1000);
I915_WRITE(GEN6_RC6_THRESHOLD, 50000);
- I915_WRITE(GEN6_RC6p_THRESHOLD, 150000);
+ I915_WRITE(GEN6_RC6p_THRESHOLD, 100000);
I915_WRITE(GEN6_RC6pp_THRESHOLD, 64000); /* unused */
/* Check if we are enabling RC6 */
@@ -3560,7 +3560,6 @@ static void cpt_init_clock_gating(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
int pipe;
- uint32_t val;
/*
* On Ibex Peak and Cougar Point, we need to disable clock
@@ -3573,12 +3572,8 @@ static void cpt_init_clock_gating(struct drm_device *dev)
/* The below fixes the weird display corruption, a few pixels shifted
* downward, on (only) LVDS of some HP laptops with IVY.
*/
- for_each_pipe(pipe) {
- val = TRANS_CHICKEN2_TIMING_OVERRIDE;
- if (dev_priv->fdi_rx_polarity_inverted)
- val |= TRANS_CHICKEN2_FDI_POLARITY_REVERSED;
- I915_WRITE(TRANS_CHICKEN2(pipe), val);
- }
+ for_each_pipe(pipe)
+ I915_WRITE(TRANS_CHICKEN2(pipe), TRANS_CHICKEN2_TIMING_OVERRIDE);
/* WADP0ClockGatingDisable */
for_each_pipe(pipe) {
I915_WRITE(TRANS_CHICKEN1(pipe),
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
index 8b5e4ae..6af87cd 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -232,10 +232,8 @@ static inline u32 intel_ring_get_seqno(struct intel_ring_buffer *ring)
static inline void i915_trace_irq_get(struct intel_ring_buffer *ring, u32 seqno)
{
-#ifdef CONFIG_TRACEPOINTS
if (ring->trace_irq_seqno == 0 && ring->irq_get(ring))
ring->trace_irq_seqno = seqno;
-#endif
}
/* DRI warts */
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index 506c331..c275bf0 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -1213,13 +1213,11 @@ static bool intel_sdvo_get_hw_state(struct intel_encoder *encoder,
struct drm_device *dev = encoder->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_sdvo *intel_sdvo = to_intel_sdvo(&encoder->base);
- u16 active_outputs;
u32 tmp;
tmp = I915_READ(intel_sdvo->sdvo_reg);
- intel_sdvo_get_active_outputs(intel_sdvo, &active_outputs);
- if (!(tmp & SDVO_ENABLE) && (active_outputs == 0))
+ if (!(tmp & SDVO_ENABLE))
return false;
if (HAS_PCH_CPT(dev))
@@ -2706,6 +2704,7 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob)
struct intel_sdvo *intel_sdvo;
u32 hotplug_mask;
int i;
+
intel_sdvo = kzalloc(sizeof(struct intel_sdvo), GFP_KERNEL);
if (!intel_sdvo)
return false;
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index 9a8d667..d7b060e 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -122,8 +122,8 @@ ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb,
linear_offset = y * fb->pitches[0] + x * pixel_size;
sprsurf_offset =
- intel_gen4_compute_page_offset(&x, &y, obj->tiling_mode,
- pixel_size, fb->pitches[0]);
+ intel_gen4_compute_offset_xtiled(&x, &y,
+ pixel_size, fb->pitches[0]);
linear_offset -= sprsurf_offset;
/* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET
@@ -287,8 +287,8 @@ ilk_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb,
linear_offset = y * fb->pitches[0] + x * pixel_size;
dvssurf_offset =
- intel_gen4_compute_page_offset(&x, &y, obj->tiling_mode,
- pixel_size, fb->pitches[0]);
+ intel_gen4_compute_offset_xtiled(&x, &y,
+ pixel_size, fb->pitches[0]);
linear_offset -= dvssurf_offset;
if (obj->tiling_mode != I915_TILING_NONE)
diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h b/drivers/gpu/drm/mgag200/mgag200_drv.h
index a657709..5ea5033 100644
--- a/drivers/gpu/drm/mgag200/mgag200_drv.h
+++ b/drivers/gpu/drm/mgag200/mgag200_drv.h
@@ -116,8 +116,6 @@ struct mga_fbdev {
void *sysram;
int size;
struct ttm_bo_kmap_obj mapping;
- int x1, y1, x2, y2; /* dirty rect */
- spinlock_t dirty_lock;
};
struct mga_crtc {
diff --git a/drivers/gpu/drm/mgag200/mgag200_fb.c b/drivers/gpu/drm/mgag200/mgag200_fb.c
index 41eefc4..2f48648 100644
--- a/drivers/gpu/drm/mgag200/mgag200_fb.c
+++ b/drivers/gpu/drm/mgag200/mgag200_fb.c
@@ -28,52 +28,16 @@ static void mga_dirty_update(struct mga_fbdev *mfbdev,
int bpp = (mfbdev->mfb.base.bits_per_pixel + 7)/8;
int ret;
bool unmap = false;
- bool store_for_later = false;
- int x2, y2;
- unsigned long flags;
obj = mfbdev->mfb.obj;
bo = gem_to_mga_bo(obj);
- /*
- * try and reserve the BO, if we fail with busy
- * then the BO is being moved and we should
- * store up the damage until later.
- */
ret = mgag200_bo_reserve(bo, true);
if (ret) {
- if (ret != -EBUSY)
- return;
-
- store_for_later = true;
- }
-
- x2 = x + width - 1;
- y2 = y + height - 1;
- spin_lock_irqsave(&mfbdev->dirty_lock, flags);
-
- if (mfbdev->y1 < y)
- y = mfbdev->y1;
- if (mfbdev->y2 > y2)
- y2 = mfbdev->y2;
- if (mfbdev->x1 < x)
- x = mfbdev->x1;
- if (mfbdev->x2 > x2)
- x2 = mfbdev->x2;
-
- if (store_for_later) {
- mfbdev->x1 = x;
- mfbdev->x2 = x2;
- mfbdev->y1 = y;
- mfbdev->y2 = y2;
- spin_unlock_irqrestore(&mfbdev->dirty_lock, flags);
+ DRM_ERROR("failed to reserve fb bo\n");
return;
}
- mfbdev->x1 = mfbdev->y1 = INT_MAX;
- mfbdev->x2 = mfbdev->y2 = 0;
- spin_unlock_irqrestore(&mfbdev->dirty_lock, flags);
-
if (!bo->kmap.virtual) {
ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &bo->kmap);
if (ret) {
@@ -83,10 +47,10 @@ static void mga_dirty_update(struct mga_fbdev *mfbdev,
}
unmap = true;
}
- for (i = y; i <= y2; i++) {
+ for (i = y; i < y + height; i++) {
/* assume equal stride for now */
src_offset = dst_offset = i * mfbdev->mfb.base.pitches[0] + (x * bpp);
- memcpy_toio(bo->kmap.virtual + src_offset, mfbdev->sysram + src_offset, (x2 - x + 1) * bpp);
+ memcpy_toio(bo->kmap.virtual + src_offset, mfbdev->sysram + src_offset, width * bpp);
}
if (unmap)
@@ -305,7 +269,6 @@ int mgag200_fbdev_init(struct mga_device *mdev)
mdev->mfbdev = mfbdev;
mfbdev->helper.funcs = &mga_fb_helper_funcs;
- spin_lock_init(&mfbdev->dirty_lock);
ret = drm_fb_helper_init(mdev->dev, &mfbdev->helper,
mdev->num_crtc, MGAG200FB_CONN_LIMIT);
diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c
index 2e7c949..d3d99a2 100644
--- a/drivers/gpu/drm/mgag200/mgag200_mode.c
+++ b/drivers/gpu/drm/mgag200/mgag200_mode.c
@@ -382,19 +382,19 @@ static int mga_g200eh_set_plls(struct mga_device *mdev, long clock)
m = n = p = 0;
vcomax = 800000;
vcomin = 400000;
- pllreffreq = 33333;
+ pllreffreq = 3333;
delta = 0xffffffff;
permitteddelta = clock * 5 / 1000;
- for (testp = 16; testp > 0; testp >>= 1) {
+ for (testp = 16; testp > 0; testp--) {
if (clock * testp > vcomax)
continue;
if (clock * testp < vcomin)
continue;
for (testm = 1; testm < 33; testm++) {
- for (testn = 17; testn < 257; testn++) {
+ for (testn = 1; testn < 257; testn++) {
computed = (pllreffreq * testn) /
(testm * testp);
if (computed > clock)
@@ -404,11 +404,11 @@ static int mga_g200eh_set_plls(struct mga_device *mdev, long clock)
if (tmpdelta < delta) {
delta = tmpdelta;
n = testn - 1;
- m = (testm - 1);
+ m = (testm - 1) | ((n >> 1) & 0x80);
p = testp - 1;
}
if ((clock * testp) >= 600000)
- p |= 0x80;
+ p |= 80;
}
}
}
@@ -751,6 +751,8 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc,
int i;
unsigned char misc = 0;
unsigned char ext_vga[6];
+ unsigned char ext_vga_index24;
+ unsigned char dac_index90 = 0;
u8 bppshift;
static unsigned char dacvalue[] = {
@@ -801,6 +803,7 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc,
option2 = 0x0000b000;
break;
case G200_ER:
+ dac_index90 = 0;
break;
}
@@ -849,8 +852,10 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc,
WREG_DAC(i, dacvalue[i]);
}
- if (mdev->type == G200_ER)
- WREG_DAC(0x90, 0);
+ if (mdev->type == G200_ER) {
+ WREG_DAC(0x90, dac_index90);
+ }
+
if (option)
pci_write_config_dword(dev->pdev, PCI_MGA_OPTION, option);
@@ -947,6 +952,8 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc,
if (mdev->type == G200_WB)
ext_vga[1] |= 0x88;
+ ext_vga_index24 = 0x05;
+
/* Set pixel clocks */
misc = 0x2d;
WREG8(MGA_MISC_OUT, misc);
@@ -958,7 +965,7 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc,
}
if (mdev->type == G200_ER)
- WREG_ECRT(0x24, 0x5);
+ WREG_ECRT(24, ext_vga_index24);
if (mdev->type == G200_EV) {
WREG_ECRT(6, 0);
diff --git a/drivers/gpu/drm/mgag200/mgag200_ttm.c b/drivers/gpu/drm/mgag200/mgag200_ttm.c
index 401c989..8fc9d92 100644
--- a/drivers/gpu/drm/mgag200/mgag200_ttm.c
+++ b/drivers/gpu/drm/mgag200/mgag200_ttm.c
@@ -315,8 +315,8 @@ int mgag200_bo_reserve(struct mgag200_bo *bo, bool no_wait)
ret = ttm_bo_reserve(&bo->bo, true, no_wait, false, 0);
if (ret) {
- if (ret != -ERESTARTSYS && ret != -EBUSY)
- DRM_ERROR("reserve failed %p %d\n", bo, ret);
+ if (ret != -ERESTARTSYS)
+ DRM_ERROR("reserve failed %p\n", bo);
return ret;
}
return 0;
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/dcb.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/dcb.h
index 123270e9..b79025d 100644
--- a/drivers/gpu/drm/nouveau/core/include/subdev/bios/dcb.h
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/bios/dcb.h
@@ -16,8 +16,6 @@ enum dcb_output_type {
struct dcb_output {
int index; /* may not be raw dcb index if merging has happened */
- u16 hasht;
- u16 hashm;
enum dcb_output_type type;
uint8_t i2c_index;
uint8_t heads;
@@ -27,7 +25,6 @@ struct dcb_output {
uint8_t or;
uint8_t link;
bool duallink_possible;
- uint8_t extdev;
union {
struct sor_conf {
int link;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/dcb.c b/drivers/gpu/drm/nouveau/core/subdev/bios/dcb.c
index 2d9b9d7..0fd87df 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/dcb.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/bios/dcb.c
@@ -107,18 +107,6 @@ dcb_outp(struct nouveau_bios *bios, u8 idx, u8 *ver, u8 *len)
return 0x0000;
}
-static inline u16
-dcb_outp_hasht(struct dcb_output *outp)
-{
- return (outp->extdev << 8) | (outp->location << 4) | outp->type;
-}
-
-static inline u16
-dcb_outp_hashm(struct dcb_output *outp)
-{
- return (outp->heads << 8) | (outp->link << 6) | outp->or;
-}
-
u16
dcb_outp_parse(struct nouveau_bios *bios, u8 idx, u8 *ver, u8 *len,
struct dcb_output *outp)
@@ -147,28 +135,34 @@ dcb_outp_parse(struct nouveau_bios *bios, u8 idx, u8 *ver, u8 *len,
case DCB_OUTPUT_DP:
outp->link = (conf & 0x00000030) >> 4;
outp->sorconf.link = outp->link; /*XXX*/
- outp->extdev = 0x00;
- if (outp->location != 0)
- outp->extdev = (conf & 0x0000ff00) >> 8;
break;
default:
break;
}
}
-
- outp->hasht = dcb_outp_hasht(outp);
- outp->hashm = dcb_outp_hashm(outp);
}
return dcb;
}
+static inline u16
+dcb_outp_hasht(struct dcb_output *outp)
+{
+ return outp->type;
+}
+
+static inline u16
+dcb_outp_hashm(struct dcb_output *outp)
+{
+ return (outp->heads << 8) | (outp->link << 6) | outp->or;
+}
+
u16
dcb_outp_match(struct nouveau_bios *bios, u16 type, u16 mask,
u8 *ver, u8 *len, struct dcb_output *outp)
{
u16 dcb, idx = 0;
while ((dcb = dcb_outp_parse(bios, idx++, ver, len, outp))) {
- if ((dcb_outp_hasht(outp) & 0x00ff) == (type & 0x00ff)) {
+ if (dcb_outp_hasht(outp) == type) {
if ((dcb_outp_hashm(outp) & mask) == mask)
break;
}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv50.c b/drivers/gpu/drm/nouveau/core/subdev/devinit/nv50.c
index 4a85778..ae7249b 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv50.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/devinit/nv50.c
@@ -78,13 +78,12 @@ nv50_devinit_init(struct nouveau_object *object)
if (ret)
return ret;
- /* if we ran the init tables, we have to execute the first script
- * pointer of each dcb entry's display encoder table in order
- * to properly initialise each encoder.
+ /* if we ran the init tables, execute first script pointer for each
+ * display table output entry that has a matching dcb entry.
*/
- while (priv->base.post && dcb_outp_parse(bios, i, &ver, &hdr, &outp)) {
- if (nvbios_outp_match(bios, outp.hasht, outp.hashm,
- &ver, &hdr, &cnt, &len, &info)) {
+ while (priv->base.post && ver) {
+ u16 data = nvbios_outp_parse(bios, i++, &ver, &hdr, &cnt, &len, &info);
+ if (data && dcb_outp_match(bios, info.type, info.mask, &ver, &len, &outp)) {
struct nvbios_init init = {
.subdev = nv_subdev(priv),
.bios = bios,
@@ -96,8 +95,7 @@ nv50_devinit_init(struct nouveau_object *object)
nvbios_exec(&init);
}
- i++;
- }
+ };
return 0;
}
diff --git a/drivers/gpu/drm/nouveau/nouveau_abi16.c b/drivers/gpu/drm/nouveau/nouveau_abi16.c
index b569fe8..4124192 100644
--- a/drivers/gpu/drm/nouveau/nouveau_abi16.c
+++ b/drivers/gpu/drm/nouveau/nouveau_abi16.c
@@ -386,7 +386,7 @@ nouveau_abi16_ioctl_notifierobj_alloc(ABI16_IOCTL_ARGS)
struct nouveau_drm *drm = nouveau_drm(dev);
struct nouveau_device *device = nv_device(drm->device);
struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv, dev);
- struct nouveau_abi16_chan *chan = NULL, *temp;
+ struct nouveau_abi16_chan *chan, *temp;
struct nouveau_abi16_ntfy *ntfy;
struct nouveau_object *object;
struct nv_dma_class args = {};
@@ -399,11 +399,10 @@ nouveau_abi16_ioctl_notifierobj_alloc(ABI16_IOCTL_ARGS)
if (unlikely(nv_device(abi16->device)->card_type >= NV_C0))
return nouveau_abi16_put(abi16, -EINVAL);
- list_for_each_entry(temp, &abi16->channels, head) {
- if (temp->chan->handle == (NVDRM_CHAN | info->channel)) {
- chan = temp;
+ list_for_each_entry_safe(chan, temp, &abi16->channels, head) {
+ if (chan->chan->handle == (NVDRM_CHAN | info->channel))
break;
- }
+ chan = NULL;
}
if (!chan)
@@ -455,18 +454,17 @@ nouveau_abi16_ioctl_gpuobj_free(ABI16_IOCTL_ARGS)
{
struct drm_nouveau_gpuobj_free *fini = data;
struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv, dev);
- struct nouveau_abi16_chan *chan = NULL, *temp;
+ struct nouveau_abi16_chan *chan, *temp;
struct nouveau_abi16_ntfy *ntfy;
int ret;
if (unlikely(!abi16))
return -ENOMEM;
- list_for_each_entry(temp, &abi16->channels, head) {
- if (temp->chan->handle == (NVDRM_CHAN | fini->channel)) {
- chan = temp;
+ list_for_each_entry_safe(chan, temp, &abi16->channels, head) {
+ if (chan->chan->handle == (NVDRM_CHAN | fini->channel))
break;
- }
+ chan = NULL;
}
if (!chan)
diff --git a/drivers/gpu/drm/radeon/atom.c b/drivers/gpu/drm/radeon/atom.c
index 43672b6..5ce9bf5 100644
--- a/drivers/gpu/drm/radeon/atom.c
+++ b/drivers/gpu/drm/radeon/atom.c
@@ -1389,10 +1389,10 @@ int atom_allocate_fb_scratch(struct atom_context *ctx)
firmware_usage = (struct _ATOM_VRAM_USAGE_BY_FIRMWARE *)(ctx->bios + data_offset);
DRM_DEBUG("atom firmware requested %08x %dkb\n",
- le32_to_cpu(firmware_usage->asFirmwareVramReserveInfo[0].ulStartAddrUsedByFirmware),
- le16_to_cpu(firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb));
+ firmware_usage->asFirmwareVramReserveInfo[0].ulStartAddrUsedByFirmware,
+ firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb);
- usage_bytes = le16_to_cpu(firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb) * 1024;
+ usage_bytes = firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb * 1024;
}
ctx->scratch_size_bytes = 0;
if (usage_bytes == 0)
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c
index 6d6fdb3..9175615 100644
--- a/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -252,6 +252,8 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode)
radeon_crtc->enabled = true;
/* adjust pm to dpms changes BEFORE enabling crtcs */
radeon_pm_compute_clocks(rdev);
+ if (ASIC_IS_DCE6(rdev) && !radeon_crtc->in_mode_set)
+ atombios_powergate_crtc(crtc, ATOM_DISABLE);
atombios_enable_crtc(crtc, ATOM_ENABLE);
if (ASIC_IS_DCE3(rdev) && !ASIC_IS_DCE6(rdev))
atombios_enable_crtc_memreq(crtc, ATOM_ENABLE);
@@ -269,6 +271,8 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode)
atombios_enable_crtc_memreq(crtc, ATOM_DISABLE);
atombios_enable_crtc(crtc, ATOM_DISABLE);
radeon_crtc->enabled = false;
+ if (ASIC_IS_DCE6(rdev) && !radeon_crtc->in_mode_set)
+ atombios_powergate_crtc(crtc, ATOM_ENABLE);
/* adjust pm to dpms changes AFTER disabling crtcs */
radeon_pm_compute_clocks(rdev);
break;
@@ -557,9 +561,6 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
/* use frac fb div on APUs */
if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE61(rdev))
radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV;
- /* use frac fb div on RS780/RS880 */
- if ((rdev->family == CHIP_RS780) || (rdev->family == CHIP_RS880))
- radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV;
if (ASIC_IS_DCE32(rdev) && mode->clock > 165000)
radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV;
} else {
@@ -1843,8 +1844,6 @@ static void atombios_crtc_disable(struct drm_crtc *crtc)
int i;
atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
- if (ASIC_IS_DCE6(rdev))
- atombios_powergate_crtc(crtc, ATOM_ENABLE);
for (i = 0; i < rdev->num_crtc; i++) {
if (rdev->mode_info.crtcs[i] &&
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
index 90dc470..a2d478e 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -105,27 +105,6 @@ void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev)
}
}
-static bool dce4_is_in_vblank(struct radeon_device *rdev, int crtc)
-{
- if (RREG32(EVERGREEN_CRTC_STATUS + crtc_offsets[crtc]) & EVERGREEN_CRTC_V_BLANK)
- return true;
- else
- return false;
-}
-
-static bool dce4_is_counter_moving(struct radeon_device *rdev, int crtc)
-{
- u32 pos1, pos2;
-
- pos1 = RREG32(EVERGREEN_CRTC_STATUS_POSITION + crtc_offsets[crtc]);
- pos2 = RREG32(EVERGREEN_CRTC_STATUS_POSITION + crtc_offsets[crtc]);
-
- if (pos1 != pos2)
- return true;
- else
- return false;
-}
-
/**
* dce4_wait_for_vblank - vblank wait asic callback.
*
@@ -136,28 +115,21 @@ static bool dce4_is_counter_moving(struct radeon_device *rdev, int crtc)
*/
void dce4_wait_for_vblank(struct radeon_device *rdev, int crtc)
{
- unsigned i = 0;
+ int i;
if (crtc >= rdev->num_crtc)
return;
- if (!(RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[crtc]) & EVERGREEN_CRTC_MASTER_EN))
- return;
-
- /* depending on when we hit vblank, we may be close to active; if so,
- * wait for another frame.
- */
- while (dce4_is_in_vblank(rdev, crtc)) {
- if (i++ % 100 == 0) {
- if (!dce4_is_counter_moving(rdev, crtc))
+ if (RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[crtc]) & EVERGREEN_CRTC_MASTER_EN) {
+ for (i = 0; i < rdev->usec_timeout; i++) {
+ if (!(RREG32(EVERGREEN_CRTC_STATUS + crtc_offsets[crtc]) & EVERGREEN_CRTC_V_BLANK))
break;
+ udelay(1);
}
- }
-
- while (!dce4_is_in_vblank(rdev, crtc)) {
- if (i++ % 100 == 0) {
- if (!dce4_is_counter_moving(rdev, crtc))
+ for (i = 0; i < rdev->usec_timeout; i++) {
+ if (RREG32(EVERGREEN_CRTC_STATUS + crtc_offsets[crtc]) & EVERGREEN_CRTC_V_BLANK)
break;
+ udelay(1);
}
}
}
@@ -431,19 +403,6 @@ void evergreen_pm_misc(struct radeon_device *rdev)
rdev->pm.current_vddc = voltage->voltage;
DRM_DEBUG("Setting: vddc: %d\n", voltage->voltage);
}
-
- /* starting with BTC, there is one state that is used for both
- * MH and SH. Difference is that we always use the high clock index for
- * mclk and vddci.
- */
- if ((rdev->pm.pm_method == PM_METHOD_PROFILE) &&
- (rdev->family >= CHIP_BARTS) &&
- rdev->pm.active_crtc_count &&
- ((rdev->pm.profile_index == PM_PROFILE_MID_MH_IDX) ||
- (rdev->pm.profile_index == PM_PROFILE_LOW_MH_IDX)))
- voltage = &rdev->pm.power_state[req_ps_idx].
- clock_info[rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_cm_idx].voltage;
-
/* 0xff01 is a flag rather then an actual voltage */
if (voltage->vddci == 0xff01)
return;
@@ -636,16 +595,6 @@ void evergreen_hpd_init(struct radeon_device *rdev)
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
struct radeon_connector *radeon_connector = to_radeon_connector(connector);
-
- if (connector->connector_type == DRM_MODE_CONNECTOR_eDP ||
- connector->connector_type == DRM_MODE_CONNECTOR_LVDS) {
- /* don't try to enable hpd on eDP or LVDS avoid breaking the
- * aux dp channel on imac and help (but not completely fix)
- * https://bugzilla.redhat.com/show_bug.cgi?id=726143
- * also avoid interrupt storms during dpms.
- */
- continue;
- }
switch (radeon_connector->hpd.hpd) {
case RADEON_HPD_1:
WREG32(DC_HPD1_CONTROL, tmp);
@@ -1363,16 +1312,17 @@ void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *sav
tmp = RREG32(EVERGREEN_CRTC_BLANK_CONTROL + crtc_offsets[i]);
if (!(tmp & EVERGREEN_CRTC_BLANK_DATA_EN)) {
radeon_wait_for_vblank(rdev, i);
- WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 1);
tmp |= EVERGREEN_CRTC_BLANK_DATA_EN;
+ WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 1);
WREG32(EVERGREEN_CRTC_BLANK_CONTROL + crtc_offsets[i], tmp);
+ WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 0);
}
} else {
tmp = RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i]);
if (!(tmp & EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE)) {
radeon_wait_for_vblank(rdev, i);
- WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 1);
tmp |= EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE;
+ WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 1);
WREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i], tmp);
WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 0);
}
@@ -1384,15 +1334,6 @@ void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *sav
break;
udelay(1);
}
-
- /* XXX this is a hack to avoid strange behavior with EFI on certain systems */
- WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 1);
- tmp = RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i]);
- tmp &= ~EVERGREEN_CRTC_MASTER_EN;
- WREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i], tmp);
- WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 0);
- save->crtc_enabled[i] = false;
- /* ***** */
} else {
save->crtc_enabled[i] = false;
}
@@ -1410,22 +1351,6 @@ void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *sav
}
/* wait for the MC to settle */
udelay(100);
-
- /* lock double buffered regs */
- for (i = 0; i < rdev->num_crtc; i++) {
- if (save->crtc_enabled[i]) {
- tmp = RREG32(EVERGREEN_GRPH_UPDATE + crtc_offsets[i]);
- if (!(tmp & EVERGREEN_GRPH_UPDATE_LOCK)) {
- tmp |= EVERGREEN_GRPH_UPDATE_LOCK;
- WREG32(EVERGREEN_GRPH_UPDATE + crtc_offsets[i], tmp);
- }
- tmp = RREG32(EVERGREEN_MASTER_UPDATE_LOCK + crtc_offsets[i]);
- if (!(tmp & 1)) {
- tmp |= 1;
- WREG32(EVERGREEN_MASTER_UPDATE_LOCK + crtc_offsets[i], tmp);
- }
- }
- }
}
void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *save)
@@ -1447,33 +1372,6 @@ void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *s
WREG32(EVERGREEN_VGA_MEMORY_BASE_ADDRESS_HIGH, upper_32_bits(rdev->mc.vram_start));
WREG32(EVERGREEN_VGA_MEMORY_BASE_ADDRESS, (u32)rdev->mc.vram_start);
- /* unlock regs and wait for update */
- for (i = 0; i < rdev->num_crtc; i++) {
- if (save->crtc_enabled[i]) {
- tmp = RREG32(EVERGREEN_MASTER_UPDATE_MODE + crtc_offsets[i]);
- if ((tmp & 0x3) != 0) {
- tmp &= ~0x3;
- WREG32(EVERGREEN_MASTER_UPDATE_MODE + crtc_offsets[i], tmp);
- }
- tmp = RREG32(EVERGREEN_GRPH_UPDATE + crtc_offsets[i]);
- if (tmp & EVERGREEN_GRPH_UPDATE_LOCK) {
- tmp &= ~EVERGREEN_GRPH_UPDATE_LOCK;
- WREG32(EVERGREEN_GRPH_UPDATE + crtc_offsets[i], tmp);
- }
- tmp = RREG32(EVERGREEN_MASTER_UPDATE_LOCK + crtc_offsets[i]);
- if (tmp & 1) {
- tmp &= ~1;
- WREG32(EVERGREEN_MASTER_UPDATE_LOCK + crtc_offsets[i], tmp);
- }
- for (j = 0; j < rdev->usec_timeout; j++) {
- tmp = RREG32(EVERGREEN_GRPH_UPDATE + crtc_offsets[i]);
- if ((tmp & EVERGREEN_GRPH_SURFACE_UPDATE_PENDING) == 0)
- break;
- udelay(1);
- }
- }
- }
-
/* unblackout the MC */
tmp = RREG32(MC_SHARED_BLACKOUT_CNTL);
tmp &= ~BLACKOUT_MODE_MASK;
diff --git a/drivers/gpu/drm/radeon/evergreen_reg.h b/drivers/gpu/drm/radeon/evergreen_reg.h
index 3e9773a..034f4c2 100644
--- a/drivers/gpu/drm/radeon/evergreen_reg.h
+++ b/drivers/gpu/drm/radeon/evergreen_reg.h
@@ -225,8 +225,6 @@
#define EVERGREEN_CRTC_STATUS_POSITION 0x6e90
#define EVERGREEN_MASTER_UPDATE_MODE 0x6ef8
#define EVERGREEN_CRTC_UPDATE_LOCK 0x6ed4
-#define EVERGREEN_MASTER_UPDATE_LOCK 0x6ef4
-#define EVERGREEN_MASTER_UPDATE_MODE 0x6ef8
#define EVERGREEN_DC_GPIO_HPD_MASK 0x64b0
#define EVERGREEN_DC_GPIO_HPD_A 0x64b4
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index 10e1bd1..835992d 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -466,32 +466,21 @@ static void cayman_gpu_init(struct radeon_device *rdev)
(rdev->pdev->device == 0x9907) ||
(rdev->pdev->device == 0x9908) ||
(rdev->pdev->device == 0x9909) ||
- (rdev->pdev->device == 0x990B) ||
- (rdev->pdev->device == 0x990C) ||
- (rdev->pdev->device == 0x990F) ||
(rdev->pdev->device == 0x9910) ||
- (rdev->pdev->device == 0x9917) ||
- (rdev->pdev->device == 0x9999) ||
- (rdev->pdev->device == 0x999C)) {
+ (rdev->pdev->device == 0x9917)) {
rdev->config.cayman.max_simds_per_se = 6;
rdev->config.cayman.max_backends_per_se = 2;
} else if ((rdev->pdev->device == 0x9903) ||
(rdev->pdev->device == 0x9904) ||
(rdev->pdev->device == 0x990A) ||
- (rdev->pdev->device == 0x990D) ||
- (rdev->pdev->device == 0x990E) ||
(rdev->pdev->device == 0x9913) ||
- (rdev->pdev->device == 0x9918) ||
- (rdev->pdev->device == 0x999D)) {
+ (rdev->pdev->device == 0x9918)) {
rdev->config.cayman.max_simds_per_se = 4;
rdev->config.cayman.max_backends_per_se = 2;
} else if ((rdev->pdev->device == 0x9919) ||
(rdev->pdev->device == 0x9990) ||
(rdev->pdev->device == 0x9991) ||
(rdev->pdev->device == 0x9994) ||
- (rdev->pdev->device == 0x9995) ||
- (rdev->pdev->device == 0x9996) ||
- (rdev->pdev->device == 0x999A) ||
(rdev->pdev->device == 0x99A0)) {
rdev->config.cayman.max_simds_per_se = 3;
rdev->config.cayman.max_backends_per_se = 1;
@@ -621,28 +610,15 @@ static void cayman_gpu_init(struct radeon_device *rdev)
WREG32(GB_ADDR_CONFIG, gb_addr_config);
WREG32(DMIF_ADDR_CONFIG, gb_addr_config);
- if (ASIC_IS_DCE6(rdev))
- WREG32(DMIF_ADDR_CALC, gb_addr_config);
WREG32(HDP_ADDR_CONFIG, gb_addr_config);
WREG32(DMA_TILING_CONFIG + DMA0_REGISTER_OFFSET, gb_addr_config);
WREG32(DMA_TILING_CONFIG + DMA1_REGISTER_OFFSET, gb_addr_config);
- if ((rdev->config.cayman.max_backends_per_se == 1) &&
- (rdev->flags & RADEON_IS_IGP)) {
- if ((disabled_rb_mask & 3) == 1) {
- /* RB0 disabled, RB1 enabled */
- tmp = 0x11111111;
- } else {
- /* RB1 disabled, RB0 enabled */
- tmp = 0x00000000;
- }
- } else {
- tmp = gb_addr_config & NUM_PIPES_MASK;
- tmp = r6xx_remap_render_backend(rdev, tmp,
- rdev->config.cayman.max_backends_per_se *
- rdev->config.cayman.max_shader_engines,
- CAYMAN_MAX_BACKENDS, disabled_rb_mask);
- }
+ tmp = gb_addr_config & NUM_PIPES_MASK;
+ tmp = r6xx_remap_render_backend(rdev, tmp,
+ rdev->config.cayman.max_backends_per_se *
+ rdev->config.cayman.max_shader_engines,
+ CAYMAN_MAX_BACKENDS, disabled_rb_mask);
WREG32(GB_BACKEND_MAP, tmp);
cgts_tcc_disable = 0xffff0000;
@@ -1686,7 +1662,6 @@ int cayman_resume(struct radeon_device *rdev)
int cayman_suspend(struct radeon_device *rdev)
{
r600_audio_fini(rdev);
- radeon_vm_manager_fini(rdev);
cayman_cp_enable(rdev, false);
cayman_dma_stop(rdev);
evergreen_irq_suspend(rdev);
diff --git a/drivers/gpu/drm/radeon/nid.h b/drivers/gpu/drm/radeon/nid.h
index e045f8c..48e5022 100644
--- a/drivers/gpu/drm/radeon/nid.h
+++ b/drivers/gpu/drm/radeon/nid.h
@@ -45,10 +45,6 @@
#define ARUBA_GB_ADDR_CONFIG_GOLDEN 0x12010001
#define DMIF_ADDR_CONFIG 0xBD4
-
-/* DCE6 only */
-#define DMIF_ADDR_CALC 0xC00
-
#define SRBM_GFX_CNTL 0x0E44
#define RINGID(x) (((x) & 0x3) << 0)
#define VMID(x) (((x) & 0x7) << 0)
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index 62719ec..8ff7cac 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -69,38 +69,6 @@ MODULE_FIRMWARE(FIRMWARE_R520);
* and others in some cases.
*/
-static bool r100_is_in_vblank(struct radeon_device *rdev, int crtc)
-{
- if (crtc == 0) {
- if (RREG32(RADEON_CRTC_STATUS) & RADEON_CRTC_VBLANK_CUR)
- return true;
- else
- return false;
- } else {
- if (RREG32(RADEON_CRTC2_STATUS) & RADEON_CRTC2_VBLANK_CUR)
- return true;
- else
- return false;
- }
-}
-
-static bool r100_is_counter_moving(struct radeon_device *rdev, int crtc)
-{
- u32 vline1, vline2;
-
- if (crtc == 0) {
- vline1 = (RREG32(RADEON_CRTC_VLINE_CRNT_VLINE) >> 16) & RADEON_CRTC_V_TOTAL;
- vline2 = (RREG32(RADEON_CRTC_VLINE_CRNT_VLINE) >> 16) & RADEON_CRTC_V_TOTAL;
- } else {
- vline1 = (RREG32(RADEON_CRTC2_VLINE_CRNT_VLINE) >> 16) & RADEON_CRTC_V_TOTAL;
- vline2 = (RREG32(RADEON_CRTC2_VLINE_CRNT_VLINE) >> 16) & RADEON_CRTC_V_TOTAL;
- }
- if (vline1 != vline2)
- return true;
- else
- return false;
-}
-
/**
* r100_wait_for_vblank - vblank wait asic callback.
*
@@ -111,33 +79,36 @@ static bool r100_is_counter_moving(struct radeon_device *rdev, int crtc)
*/
void r100_wait_for_vblank(struct radeon_device *rdev, int crtc)
{
- unsigned i = 0;
+ int i;
if (crtc >= rdev->num_crtc)
return;
if (crtc == 0) {
- if (!(RREG32(RADEON_CRTC_GEN_CNTL) & RADEON_CRTC_EN))
- return;
- } else {
- if (!(RREG32(RADEON_CRTC2_GEN_CNTL) & RADEON_CRTC2_EN))
- return;
- }
-
- /* depending on when we hit vblank, we may be close to active; if so,
- * wait for another frame.
- */
- while (r100_is_in_vblank(rdev, crtc)) {
- if (i++ % 100 == 0) {
- if (!r100_is_counter_moving(rdev, crtc))
- break;
+ if (RREG32(RADEON_CRTC_GEN_CNTL) & RADEON_CRTC_EN) {
+ for (i = 0; i < rdev->usec_timeout; i++) {
+ if (!(RREG32(RADEON_CRTC_STATUS) & RADEON_CRTC_VBLANK_CUR))
+ break;
+ udelay(1);
+ }
+ for (i = 0; i < rdev->usec_timeout; i++) {
+ if (RREG32(RADEON_CRTC_STATUS) & RADEON_CRTC_VBLANK_CUR)
+ break;
+ udelay(1);
+ }
}
- }
-
- while (!r100_is_in_vblank(rdev, crtc)) {
- if (i++ % 100 == 0) {
- if (!r100_is_counter_moving(rdev, crtc))
- break;
+ } else {
+ if (RREG32(RADEON_CRTC2_GEN_CNTL) & RADEON_CRTC2_EN) {
+ for (i = 0; i < rdev->usec_timeout; i++) {
+ if (!(RREG32(RADEON_CRTC2_STATUS) & RADEON_CRTC2_VBLANK_CUR))
+ break;
+ udelay(1);
+ }
+ for (i = 0; i < rdev->usec_timeout; i++) {
+ if (RREG32(RADEON_CRTC2_STATUS) & RADEON_CRTC2_VBLANK_CUR)
+ break;
+ udelay(1);
+ }
}
}
}
diff --git a/drivers/gpu/drm/radeon/r500_reg.h b/drivers/gpu/drm/radeon/r500_reg.h
index 8ec2376..ec576aa 100644
--- a/drivers/gpu/drm/radeon/r500_reg.h
+++ b/drivers/gpu/drm/radeon/r500_reg.h
@@ -357,9 +357,7 @@
#define AVIVO_D1CRTC_FRAME_COUNT 0x60a4
#define AVIVO_D1CRTC_STEREO_CONTROL 0x60c4
-#define AVIVO_D1MODE_MASTER_UPDATE_LOCK 0x60e0
#define AVIVO_D1MODE_MASTER_UPDATE_MODE 0x60e4
-#define AVIVO_D1CRTC_UPDATE_LOCK 0x60e8
/* master controls */
#define AVIVO_DC_CRTC_MASTER_EN 0x60f8
diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c
index d89a1f8..ff80efe 100644
--- a/drivers/gpu/drm/radeon/r600_hdmi.c
+++ b/drivers/gpu/drm/radeon/r600_hdmi.c
@@ -489,7 +489,7 @@ void r600_hdmi_enable(struct drm_encoder *encoder)
offset = dig->afmt->offset;
/* Older chipsets require setting HDMI and routing manually */
- if (ASIC_IS_DCE2(rdev) && !ASIC_IS_DCE3(rdev)) {
+ if (rdev->family >= CHIP_R600 && !ASIC_IS_DCE3(rdev)) {
hdmi = HDMI0_ERROR_ACK | HDMI0_ENABLE;
switch (radeon_encoder->encoder_id) {
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
@@ -544,6 +544,7 @@ void r600_hdmi_disable(struct drm_encoder *encoder)
/* Called for ATOM_ENCODER_MODE_HDMI only */
if (!dig || !dig->afmt) {
+ WARN_ON(1);
return;
}
if (!dig->afmt->enabled)
@@ -557,7 +558,7 @@ void r600_hdmi_disable(struct drm_encoder *encoder)
radeon_irq_kms_disable_afmt(rdev, dig->afmt->id);
/* Older chipsets not handled by AtomBIOS */
- if (ASIC_IS_DCE2(rdev) && !ASIC_IS_DCE3(rdev)) {
+ if (rdev->family >= CHIP_R600 && !ASIC_IS_DCE3(rdev)) {
switch (radeon_encoder->encoder_id) {
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
WREG32_P(AVIVO_TMDSA_CNTL, 0,
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c
index 96168ef..f22eb57 100644
--- a/drivers/gpu/drm/radeon/radeon_atombios.c
+++ b/drivers/gpu/drm/radeon/radeon_atombios.c
@@ -2028,8 +2028,6 @@ static int radeon_atombios_parse_power_table_1_3(struct radeon_device *rdev)
num_modes = power_info->info.ucNumOfPowerModeEntries;
if (num_modes > ATOM_MAX_NUMBEROF_POWER_BLOCK)
num_modes = ATOM_MAX_NUMBEROF_POWER_BLOCK;
- if (num_modes == 0)
- return state_index;
rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state) * num_modes, GFP_KERNEL);
if (!rdev->pm.power_state)
return state_index;
@@ -2434,8 +2432,6 @@ static int radeon_atombios_parse_power_table_4_5(struct radeon_device *rdev)
power_info = (union power_info *)(mode_info->atom_context->bios + data_offset);
radeon_atombios_add_pplib_thermal_controller(rdev, &power_info->pplib.sThermalController);
- if (power_info->pplib.ucNumStates == 0)
- return state_index;
rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state) *
power_info->pplib.ucNumStates, GFP_KERNEL);
if (!rdev->pm.power_state)
@@ -2518,7 +2514,6 @@ static int radeon_atombios_parse_power_table_6(struct radeon_device *rdev)
int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo);
u16 data_offset;
u8 frev, crev;
- u8 *power_state_offset;
if (!atom_parse_data_header(mode_info->atom_context, index, NULL,
&frev, &crev, &data_offset))
@@ -2535,17 +2530,15 @@ static int radeon_atombios_parse_power_table_6(struct radeon_device *rdev)
non_clock_info_array = (struct _NonClockInfoArray *)
(mode_info->atom_context->bios + data_offset +
le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset));
- if (state_array->ucNumEntries == 0)
- return state_index;
rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state) *
state_array->ucNumEntries, GFP_KERNEL);
if (!rdev->pm.power_state)
return state_index;
- power_state_offset = (u8 *)state_array->states;
for (i = 0; i < state_array->ucNumEntries; i++) {
mode_index = 0;
- power_state = (union pplib_power_state *)power_state_offset;
- non_clock_array_index = power_state->v2.nonClockInfoIndex;
+ power_state = (union pplib_power_state *)&state_array->states[i];
+ /* XXX this might be an inagua bug... */
+ non_clock_array_index = i; /* power_state->v2.nonClockInfoIndex */
non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *)
&non_clock_info_array->nonClockInfo[non_clock_array_index];
rdev->pm.power_state[i].clock_info = kzalloc(sizeof(struct radeon_pm_clock_info) *
@@ -2557,6 +2550,9 @@ static int radeon_atombios_parse_power_table_6(struct radeon_device *rdev)
if (power_state->v2.ucNumDPMLevels) {
for (j = 0; j < power_state->v2.ucNumDPMLevels; j++) {
clock_array_index = power_state->v2.clockInfoIndex[j];
+ /* XXX this might be an inagua bug... */
+ if (clock_array_index >= clock_info_array->ucNumEntries)
+ continue;
clock_info = (union pplib_clock_info *)
&clock_info_array->clockInfo[clock_array_index * clock_info_array->ucEntrySize];
valid = radeon_atombios_parse_pplib_clock_info(rdev,
@@ -2578,7 +2574,6 @@ static int radeon_atombios_parse_power_table_6(struct radeon_device *rdev)
non_clock_info);
state_index++;
}
- power_state_offset += 2 + power_state->v2.ucNumDPMLevels;
}
/* if multiple clock modes, mark the lowest as no display */
for (i = 0; i < state_index; i++) {
@@ -2625,9 +2620,7 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev)
default:
break;
}
- }
-
- if (state_index == 0) {
+ } else {
rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state), GFP_KERNEL);
if (rdev->pm.power_state) {
rdev->pm.power_state[0].clock_info =
diff --git a/drivers/gpu/drm/radeon/radeon_atpx_handler.c b/drivers/gpu/drm/radeon/radeon_atpx_handler.c
index d96070b..15f5ded 100644
--- a/drivers/gpu/drm/radeon/radeon_atpx_handler.c
+++ b/drivers/gpu/drm/radeon/radeon_atpx_handler.c
@@ -43,12 +43,6 @@ struct atpx_verify_interface {
u32 function_bits; /* supported functions bit vector */
} __packed;
-struct atpx_px_params {
- u16 size; /* structure size in bytes (includes size field) */
- u32 valid_flags; /* which flags are valid */
- u32 flags; /* flags */
-} __packed;
-
struct atpx_power_control {
u16 size;
u8 dgpu_state;
@@ -129,61 +123,9 @@ static void radeon_atpx_parse_functions(struct radeon_atpx_functions *f, u32 mas
}
/**
- * radeon_atpx_validate_functions - validate ATPX functions
- *
- * @atpx: radeon atpx struct
- *
- * Validate that required functions are enabled (all asics).
- * returns 0 on success, error on failure.
- */
-static int radeon_atpx_validate(struct radeon_atpx *atpx)
-{
- /* make sure required functions are enabled */
- /* dGPU power control is required */
- atpx->functions.power_cntl = true;
-
- if (atpx->functions.px_params) {
- union acpi_object *info;
- struct atpx_px_params output;
- size_t size;
- u32 valid_bits;
-
- info = radeon_atpx_call(atpx->handle, ATPX_FUNCTION_GET_PX_PARAMETERS, NULL);
- if (!info)
- return -EIO;
-
- memset(&output, 0, sizeof(output));
-
- size = *(u16 *) info->buffer.pointer;
- if (size < 10) {
- printk("ATPX buffer is too small: %zu\n", size);
- kfree(info);
- return -EINVAL;
- }
- size = min(sizeof(output), size);
-
- memcpy(&output, info->buffer.pointer, size);
-
- valid_bits = output.flags & output.valid_flags;
- /* if separate mux flag is set, mux controls are required */
- if (valid_bits & ATPX_SEPARATE_MUX_FOR_I2C) {
- atpx->functions.i2c_mux_cntl = true;
- atpx->functions.disp_mux_cntl = true;
- }
- /* if any outputs are muxed, mux controls are required */
- if (valid_bits & (ATPX_CRT1_RGB_SIGNAL_MUXED |
- ATPX_TV_SIGNAL_MUXED |
- ATPX_DFP_SIGNAL_MUXED))
- atpx->functions.disp_mux_cntl = true;
-
- kfree(info);
- }
- return 0;
-}
-
-/**
* radeon_atpx_verify_interface - verify ATPX
*
+ * @handle: acpi handle
* @atpx: radeon atpx struct
*
* Execute the ATPX_FUNCTION_VERIFY_INTERFACE ATPX function
@@ -464,19 +406,8 @@ static bool radeon_atpx_pci_probe_handle(struct pci_dev *pdev)
*/
static int radeon_atpx_init(void)
{
- int r;
-
/* set up the ATPX handle */
- r = radeon_atpx_verify_interface(&radeon_atpx_priv.atpx);
- if (r)
- return r;
-
- /* validate the atpx setup */
- r = radeon_atpx_validate(&radeon_atpx_priv.atpx);
- if (r)
- return r;
-
- return 0;
+ return radeon_atpx_verify_interface(&radeon_atpx_priv.atpx);
}
/**
diff --git a/drivers/gpu/drm/radeon/radeon_benchmark.c b/drivers/gpu/drm/radeon/radeon_benchmark.c
index a2f0c24..bedda9c 100644
--- a/drivers/gpu/drm/radeon/radeon_benchmark.c
+++ b/drivers/gpu/drm/radeon/radeon_benchmark.c
@@ -135,15 +135,13 @@ static void radeon_benchmark_move(struct radeon_device *rdev, unsigned size,
sdomain, ddomain, "dma");
}
- if (rdev->asic->copy.blit) {
- time = radeon_benchmark_do_move(rdev, size, saddr, daddr,
- RADEON_BENCHMARK_COPY_BLIT, n);
- if (time < 0)
- goto out_cleanup;
- if (time > 0)
- radeon_benchmark_log_results(n, size, time,
- sdomain, ddomain, "blit");
- }
+ time = radeon_benchmark_do_move(rdev, size, saddr, daddr,
+ RADEON_BENCHMARK_COPY_BLIT, n);
+ if (time < 0)
+ goto out_cleanup;
+ if (time > 0)
+ radeon_benchmark_log_results(n, size, time,
+ sdomain, ddomain, "blit");
out_cleanup:
if (sobj) {
diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c
index 78edadc..3e403bd 100644
--- a/drivers/gpu/drm/radeon/radeon_combios.c
+++ b/drivers/gpu/drm/radeon/radeon_combios.c
@@ -970,15 +970,6 @@ struct radeon_encoder_primary_dac *radeon_combios_get_primary_dac_info(struct
found = 1;
}
- /* quirks */
- /* Radeon 9100 (R200) */
- if ((dev->pdev->device == 0x514D) &&
- (dev->pdev->subsystem_vendor == 0x174B) &&
- (dev->pdev->subsystem_device == 0x7149)) {
- /* vbios value is bad, use the default */
- found = 0;
- }
-
if (!found) /* fallback to defaults */
radeon_legacy_get_primary_dac_info_from_table(rdev, p_dac);
diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c b/drivers/gpu/drm/radeon/radeon_irq_kms.c
index 48f80cd..90374dd 100644
--- a/drivers/gpu/drm/radeon/radeon_irq_kms.c
+++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c
@@ -400,9 +400,6 @@ void radeon_irq_kms_enable_afmt(struct radeon_device *rdev, int block)
{
unsigned long irqflags;
- if (!rdev->ddev->irq_enabled)
- return;
-
spin_lock_irqsave(&rdev->irq.lock, irqflags);
rdev->irq.afmt[block] = true;
radeon_irq_set(rdev);
@@ -422,9 +419,6 @@ void radeon_irq_kms_disable_afmt(struct radeon_device *rdev, int block)
{
unsigned long irqflags;
- if (!rdev->ddev->irq_enabled)
- return;
-
spin_lock_irqsave(&rdev->irq.lock, irqflags);
rdev->irq.afmt[block] = false;
radeon_irq_set(rdev);
@@ -444,9 +438,6 @@ void radeon_irq_kms_enable_hpd(struct radeon_device *rdev, unsigned hpd_mask)
unsigned long irqflags;
int i;
- if (!rdev->ddev->irq_enabled)
- return;
-
spin_lock_irqsave(&rdev->irq.lock, irqflags);
for (i = 0; i < RADEON_MAX_HPD_PINS; ++i)
rdev->irq.hpd[i] |= !!(hpd_mask & (1 << i));
@@ -467,9 +458,6 @@ void radeon_irq_kms_disable_hpd(struct radeon_device *rdev, unsigned hpd_mask)
unsigned long irqflags;
int i;
- if (!rdev->ddev->irq_enabled)
- return;
-
spin_lock_irqsave(&rdev->irq.lock, irqflags);
for (i = 0; i < RADEON_MAX_HPD_PINS; ++i)
rdev->irq.hpd[i] &= !(hpd_mask & (1 << i));
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c
index bc36922..9c312f9 100644
--- a/drivers/gpu/drm/radeon/radeon_kms.c
+++ b/drivers/gpu/drm/radeon/radeon_kms.c
@@ -50,13 +50,9 @@ int radeon_driver_unload_kms(struct drm_device *dev)
if (rdev == NULL)
return 0;
- if (rdev->rmmio == NULL)
- goto done_free;
radeon_acpi_fini(rdev);
radeon_modeset_fini(rdev);
radeon_device_fini(rdev);
-
-done_free:
kfree(rdev);
dev->dev_private = NULL;
return 0;
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c
index 788c64c..0bfa656 100644
--- a/drivers/gpu/drm/radeon/radeon_pm.c
+++ b/drivers/gpu/drm/radeon/radeon_pm.c
@@ -169,7 +169,7 @@ static void radeon_set_power_state(struct radeon_device *rdev)
/* starting with BTC, there is one state that is used for both
* MH and SH. Difference is that we always use the high clock index for
- * mclk and vddci.
+ * mclk.
*/
if ((rdev->pm.pm_method == PM_METHOD_PROFILE) &&
(rdev->family >= CHIP_BARTS) &&
@@ -843,11 +843,7 @@ static int radeon_debugfs_pm_info(struct seq_file *m, void *data)
struct radeon_device *rdev = dev->dev_private;
seq_printf(m, "default engine clock: %u0 kHz\n", rdev->pm.default_sclk);
- /* radeon_get_engine_clock is not reliable on APUs so just print the current clock */
- if ((rdev->family >= CHIP_PALM) && (rdev->flags & RADEON_IS_IGP))
- seq_printf(m, "current engine clock: %u0 kHz\n", rdev->pm.current_sclk);
- else
- seq_printf(m, "current engine clock: %u0 kHz\n", radeon_get_engine_clock(rdev));
+ seq_printf(m, "current engine clock: %u0 kHz\n", radeon_get_engine_clock(rdev));
seq_printf(m, "default memory clock: %u0 kHz\n", rdev->pm.default_mclk);
if (rdev->asic->pm.get_memory_clock)
seq_printf(m, "current memory clock: %u0 kHz\n", radeon_get_memory_clock(rdev));
diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c
index 8adc5b5..cd72062 100644
--- a/drivers/gpu/drm/radeon/radeon_ring.c
+++ b/drivers/gpu/drm/radeon/radeon_ring.c
@@ -161,8 +161,7 @@ int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib,
radeon_semaphore_free(rdev, &ib->semaphore, NULL);
}
/* if we can't remember our last VM flush then flush now! */
- /* XXX figure out why we have to flush for every IB */
- if (ib->vm /*&& !ib->vm->last_flush*/) {
+ if (ib->vm && !ib->vm->last_flush) {
radeon_ring_vm_flush(rdev, ib->ring, ib->vm);
}
if (const_ib) {
diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c
index 46fa1b0..5a0fc74 100644
--- a/drivers/gpu/drm/radeon/rs600.c
+++ b/drivers/gpu/drm/radeon/rs600.c
@@ -52,59 +52,23 @@ static const u32 crtc_offsets[2] =
AVIVO_D2CRTC_H_TOTAL - AVIVO_D1CRTC_H_TOTAL
};
-static bool avivo_is_in_vblank(struct radeon_device *rdev, int crtc)
-{
- if (RREG32(AVIVO_D1CRTC_STATUS + crtc_offsets[crtc]) & AVIVO_D1CRTC_V_BLANK)
- return true;
- else
- return false;
-}
-
-static bool avivo_is_counter_moving(struct radeon_device *rdev, int crtc)
-{
- u32 pos1, pos2;
-
- pos1 = RREG32(AVIVO_D1CRTC_STATUS_POSITION + crtc_offsets[crtc]);
- pos2 = RREG32(AVIVO_D1CRTC_STATUS_POSITION + crtc_offsets[crtc]);
-
- if (pos1 != pos2)
- return true;
- else
- return false;
-}
-
-/**
- * avivo_wait_for_vblank - vblank wait asic callback.
- *
- * @rdev: radeon_device pointer
- * @crtc: crtc to wait for vblank on
- *
- * Wait for vblank on the requested crtc (r5xx-r7xx).
- */
void avivo_wait_for_vblank(struct radeon_device *rdev, int crtc)
{
- unsigned i = 0;
+ int i;
if (crtc >= rdev->num_crtc)
return;
- if (!(RREG32(AVIVO_D1CRTC_CONTROL + crtc_offsets[crtc]) & AVIVO_CRTC_EN))
- return;
-
- /* depending on when we hit vblank, we may be close to active; if so,
- * wait for another frame.
- */
- while (avivo_is_in_vblank(rdev, crtc)) {
- if (i++ % 100 == 0) {
- if (!avivo_is_counter_moving(rdev, crtc))
+ if (RREG32(AVIVO_D1CRTC_CONTROL + crtc_offsets[crtc]) & AVIVO_CRTC_EN) {
+ for (i = 0; i < rdev->usec_timeout; i++) {
+ if (!(RREG32(AVIVO_D1CRTC_STATUS + crtc_offsets[crtc]) & AVIVO_D1CRTC_V_BLANK))
break;
+ udelay(1);
}
- }
-
- while (!avivo_is_in_vblank(rdev, crtc)) {
- if (i++ % 100 == 0) {
- if (!avivo_is_counter_moving(rdev, crtc))
+ for (i = 0; i < rdev->usec_timeout; i++) {
+ if (RREG32(AVIVO_D1CRTC_STATUS + crtc_offsets[crtc]) & AVIVO_D1CRTC_V_BLANK)
break;
+ udelay(1);
}
}
}
diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c
index ffcba73..435ed35 100644
--- a/drivers/gpu/drm/radeon/rv515.c
+++ b/drivers/gpu/drm/radeon/rv515.c
@@ -303,10 +303,8 @@ void rv515_mc_stop(struct radeon_device *rdev, struct rv515_mc_save *save)
tmp = RREG32(AVIVO_D1CRTC_CONTROL + crtc_offsets[i]);
if (!(tmp & AVIVO_CRTC_DISP_READ_REQUEST_DISABLE)) {
radeon_wait_for_vblank(rdev, i);
- WREG32(AVIVO_D1CRTC_UPDATE_LOCK + crtc_offsets[i], 1);
tmp |= AVIVO_CRTC_DISP_READ_REQUEST_DISABLE;
WREG32(AVIVO_D1CRTC_CONTROL + crtc_offsets[i], tmp);
- WREG32(AVIVO_D1CRTC_UPDATE_LOCK + crtc_offsets[i], 0);
}
/* wait for the next frame */
frame_count = radeon_get_vblank_counter(rdev, i);
@@ -315,15 +313,6 @@ void rv515_mc_stop(struct radeon_device *rdev, struct rv515_mc_save *save)
break;
udelay(1);
}
-
- /* XXX this is a hack to avoid strange behavior with EFI on certain systems */
- WREG32(AVIVO_D1CRTC_UPDATE_LOCK + crtc_offsets[i], 1);
- tmp = RREG32(AVIVO_D1CRTC_CONTROL + crtc_offsets[i]);
- tmp &= ~AVIVO_CRTC_EN;
- WREG32(AVIVO_D1CRTC_CONTROL + crtc_offsets[i], tmp);
- WREG32(AVIVO_D1CRTC_UPDATE_LOCK + crtc_offsets[i], 0);
- save->crtc_enabled[i] = false;
- /* ***** */
} else {
save->crtc_enabled[i] = false;
}
@@ -349,22 +338,6 @@ void rv515_mc_stop(struct radeon_device *rdev, struct rv515_mc_save *save)
}
/* wait for the MC to settle */
udelay(100);
-
- /* lock double buffered regs */
- for (i = 0; i < rdev->num_crtc; i++) {
- if (save->crtc_enabled[i]) {
- tmp = RREG32(AVIVO_D1GRPH_UPDATE + crtc_offsets[i]);
- if (!(tmp & AVIVO_D1GRPH_UPDATE_LOCK)) {
- tmp |= AVIVO_D1GRPH_UPDATE_LOCK;
- WREG32(AVIVO_D1GRPH_UPDATE + crtc_offsets[i], tmp);
- }
- tmp = RREG32(AVIVO_D1MODE_MASTER_UPDATE_LOCK + crtc_offsets[i]);
- if (!(tmp & 1)) {
- tmp |= 1;
- WREG32(AVIVO_D1MODE_MASTER_UPDATE_LOCK + crtc_offsets[i], tmp);
- }
- }
- }
}
void rv515_mc_resume(struct radeon_device *rdev, struct rv515_mc_save *save)
@@ -375,7 +348,7 @@ void rv515_mc_resume(struct radeon_device *rdev, struct rv515_mc_save *save)
/* update crtc base addresses */
for (i = 0; i < rdev->num_crtc; i++) {
if (rdev->family >= CHIP_RV770) {
- if (i == 0) {
+ if (i == 1) {
WREG32(R700_D1GRPH_PRIMARY_SURFACE_ADDRESS_HIGH,
upper_32_bits(rdev->mc.vram_start));
WREG32(R700_D1GRPH_SECONDARY_SURFACE_ADDRESS_HIGH,
@@ -394,33 +367,6 @@ void rv515_mc_resume(struct radeon_device *rdev, struct rv515_mc_save *save)
}
WREG32(R_000310_VGA_MEMORY_BASE_ADDRESS, (u32)rdev->mc.vram_start);
- /* unlock regs and wait for update */
- for (i = 0; i < rdev->num_crtc; i++) {
- if (save->crtc_enabled[i]) {
- tmp = RREG32(AVIVO_D1MODE_MASTER_UPDATE_MODE + crtc_offsets[i]);
- if ((tmp & 0x3) != 0) {
- tmp &= ~0x3;
- WREG32(AVIVO_D1MODE_MASTER_UPDATE_MODE + crtc_offsets[i], tmp);
- }
- tmp = RREG32(AVIVO_D1GRPH_UPDATE + crtc_offsets[i]);
- if (tmp & AVIVO_D1GRPH_UPDATE_LOCK) {
- tmp &= ~AVIVO_D1GRPH_UPDATE_LOCK;
- WREG32(AVIVO_D1GRPH_UPDATE + crtc_offsets[i], tmp);
- }
- tmp = RREG32(AVIVO_D1MODE_MASTER_UPDATE_LOCK + crtc_offsets[i]);
- if (tmp & 1) {
- tmp &= ~1;
- WREG32(AVIVO_D1MODE_MASTER_UPDATE_LOCK + crtc_offsets[i], tmp);
- }
- for (j = 0; j < rdev->usec_timeout; j++) {
- tmp = RREG32(AVIVO_D1GRPH_UPDATE + crtc_offsets[i]);
- if ((tmp & AVIVO_D1GRPH_SURFACE_UPDATE_PENDING) == 0)
- break;
- udelay(1);
- }
- }
- }
-
if (rdev->family >= CHIP_R600) {
/* unblackout the MC */
if (rdev->family >= CHIP_RV770)
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c
index 40d766e..ae8b482 100644
--- a/drivers/gpu/drm/radeon/si.c
+++ b/drivers/gpu/drm/radeon/si.c
@@ -1374,7 +1374,7 @@ static void si_select_se_sh(struct radeon_device *rdev,
u32 data = INSTANCE_BROADCAST_WRITES;
if ((se_num == 0xffffffff) && (sh_num == 0xffffffff))
- data |= SH_BROADCAST_WRITES | SE_BROADCAST_WRITES;
+ data = SH_BROADCAST_WRITES | SE_BROADCAST_WRITES;
else if (se_num == 0xffffffff)
data |= SE_BROADCAST_WRITES | SH_INDEX(sh_num);
else if (sh_num == 0xffffffff)
@@ -1659,7 +1659,6 @@ static void si_gpu_init(struct radeon_device *rdev)
WREG32(GB_ADDR_CONFIG, gb_addr_config);
WREG32(DMIF_ADDR_CONFIG, gb_addr_config);
- WREG32(DMIF_ADDR_CALC, gb_addr_config);
WREG32(HDP_ADDR_CONFIG, gb_addr_config);
WREG32(DMA_TILING_CONFIG + DMA0_REGISTER_OFFSET, gb_addr_config);
WREG32(DMA_TILING_CONFIG + DMA1_REGISTER_OFFSET, gb_addr_config);
@@ -4233,7 +4232,6 @@ int si_resume(struct radeon_device *rdev)
int si_suspend(struct radeon_device *rdev)
{
- radeon_vm_manager_fini(rdev);
si_cp_enable(rdev, false);
cayman_dma_stop(rdev);
si_irq_suspend(rdev);
diff --git a/drivers/gpu/drm/radeon/sid.h b/drivers/gpu/drm/radeon/sid.h
index e9a01f0..c056aae 100644
--- a/drivers/gpu/drm/radeon/sid.h
+++ b/drivers/gpu/drm/radeon/sid.h
@@ -60,8 +60,6 @@
#define DMIF_ADDR_CONFIG 0xBD4
-#define DMIF_ADDR_CALC 0xC00
-
#define SRBM_STATUS 0xE50
#define SRBM_SOFT_RESET 0x0E60
diff --git a/drivers/gpu/drm/udl/udl_connector.c b/drivers/gpu/drm/udl/udl_connector.c
index b44d548..fe5cdbc 100644
--- a/drivers/gpu/drm/udl/udl_connector.c
+++ b/drivers/gpu/drm/udl/udl_connector.c
@@ -61,10 +61,6 @@ static int udl_get_modes(struct drm_connector *connector)
int ret;
edid = (struct edid *)udl_get_edid(udl);
- if (!edid) {
- drm_mode_connector_update_edid_property(connector, NULL);
- return 0;
- }
/*
* We only read the main block, but if the monitor reports extension
diff --git a/drivers/gpu/drm/udl/udl_drv.h b/drivers/gpu/drm/udl/udl_drv.h
index cc6d90f..87aa5f5 100644
--- a/drivers/gpu/drm/udl/udl_drv.h
+++ b/drivers/gpu/drm/udl/udl_drv.h
@@ -75,8 +75,6 @@ struct udl_framebuffer {
struct drm_framebuffer base;
struct udl_gem_object *obj;
bool active_16; /* active on the 16-bit channel */
- int x1, y1, x2, y2; /* dirty rect */
- spinlock_t dirty_lock;
};
#define to_udl_fb(x) container_of(x, struct udl_framebuffer, base)
diff --git a/drivers/gpu/drm/udl/udl_fb.c b/drivers/gpu/drm/udl/udl_fb.c
index 1eb060c..d4ab3be 100644
--- a/drivers/gpu/drm/udl/udl_fb.c
+++ b/drivers/gpu/drm/udl/udl_fb.c
@@ -22,9 +22,9 @@
#include <drm/drm_fb_helper.h>
-#define DL_DEFIO_WRITE_DELAY (HZ/20) /* fb_deferred_io.delay in jiffies */
+#define DL_DEFIO_WRITE_DELAY 5 /* fb_deferred_io.delay in jiffies */
-static int fb_defio = 0; /* Optionally enable experimental fb_defio mmap support */
+static int fb_defio = 1; /* Optionally enable experimental fb_defio mmap support */
static int fb_bpp = 16;
module_param(fb_bpp, int, S_IWUSR | S_IRUSR | S_IWGRP | S_IRGRP);
@@ -153,9 +153,6 @@ int udl_handle_damage(struct udl_framebuffer *fb, int x, int y,
struct urb *urb;
int aligned_x;
int bpp = (fb->base.bits_per_pixel / 8);
- int x2, y2;
- bool store_for_later = false;
- unsigned long flags;
if (!fb->active_16)
return 0;
@@ -172,6 +169,8 @@ int udl_handle_damage(struct udl_framebuffer *fb, int x, int y,
}
}
+ start_cycles = get_cycles();
+
aligned_x = DL_ALIGN_DOWN(x, sizeof(unsigned long));
width = DL_ALIGN_UP(width + (x-aligned_x), sizeof(unsigned long));
x = aligned_x;
@@ -181,53 +180,19 @@ int udl_handle_damage(struct udl_framebuffer *fb, int x, int y,
(y + height > fb->base.height))
return -EINVAL;
- /* if we are in atomic just store the info
- can't test inside spin lock */
- if (in_atomic())
- store_for_later = true;
-
- x2 = x + width - 1;
- y2 = y + height - 1;
-
- spin_lock_irqsave(&fb->dirty_lock, flags);
-
- if (fb->y1 < y)
- y = fb->y1;
- if (fb->y2 > y2)
- y2 = fb->y2;
- if (fb->x1 < x)
- x = fb->x1;
- if (fb->x2 > x2)
- x2 = fb->x2;
-
- if (store_for_later) {
- fb->x1 = x;
- fb->x2 = x2;
- fb->y1 = y;
- fb->y2 = y2;
- spin_unlock_irqrestore(&fb->dirty_lock, flags);
- return 0;
- }
-
- fb->x1 = fb->y1 = INT_MAX;
- fb->x2 = fb->y2 = 0;
-
- spin_unlock_irqrestore(&fb->dirty_lock, flags);
- start_cycles = get_cycles();
-
urb = udl_get_urb(dev);
if (!urb)
return 0;
cmd = urb->transfer_buffer;
- for (i = y; i <= y2 ; i++) {
+ for (i = y; i < y + height ; i++) {
const int line_offset = fb->base.pitches[0] * i;
const int byte_offset = line_offset + (x * bpp);
const int dev_byte_offset = (fb->base.width * bpp * i) + (x * bpp);
if (udl_render_hline(dev, bpp, &urb,
(char *) fb->obj->vmapping,
&cmd, byte_offset, dev_byte_offset,
- (x2 - x + 1) * bpp,
+ width * bpp,
&bytes_identical, &bytes_sent))
goto error;
}
@@ -469,7 +434,6 @@ udl_framebuffer_init(struct drm_device *dev,
{
int ret;
- spin_lock_init(&ufb->dirty_lock);
ufb->obj = obj;
ret = drm_framebuffer_init(dev, &ufb->base, &udlfb_funcs);
drm_helper_mode_fill_fb_struct(&ufb->base, mode_cmd);
diff --git a/drivers/gpu/vga/vga_switcheroo.c b/drivers/gpu/vga/vga_switcheroo.c
index cf787e1..fa60add 100644
--- a/drivers/gpu/vga/vga_switcheroo.c
+++ b/drivers/gpu/vga/vga_switcheroo.c
@@ -25,7 +25,6 @@
#include <linux/fb.h>
#include <linux/pci.h>
-#include <linux/console.h>
#include <linux/vga_switcheroo.h>
#include <linux/vgaarb.h>
@@ -338,10 +337,8 @@ static int vga_switchto_stage2(struct vga_switcheroo_client *new_client)
if (new_client->fb_info) {
struct fb_event event;
- console_lock();
event.info = new_client->fb_info;
fb_notifier_call_chain(FB_EVENT_REMAP_ALL_CONSOLE, &event);
- console_unlock();
}
ret = vgasr_priv.handler->switchto(new_client->id);
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index ceb3040..eb2ee11 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1697,7 +1697,6 @@ static const struct hid_device_id hid_have_special_driver[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER) },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) },
{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE) },
- { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGP_MOUSE) },
{ HID_USB_DEVICE(USB_VENDOR_ID_SUNPLUS, USB_DEVICE_ID_SUNPLUS_WDESKTOP) },
{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300) },
{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb304) },
@@ -2071,7 +2070,6 @@ static const struct hid_device_id hid_ignore_list[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_HYBRID) },
{ HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_HEATCONTROL) },
{ HID_USB_DEVICE(USB_VENDOR_ID_MADCATZ, USB_DEVICE_ID_MADCATZ_BEATPAD) },
- { HID_USB_DEVICE(USB_VENDOR_ID_MASTERKIT, USB_DEVICE_ID_MASTERKIT_MA901RADIO) },
{ HID_USB_DEVICE(USB_VENDOR_ID_MCC, USB_DEVICE_ID_MCC_PMD1024LS) },
{ HID_USB_DEVICE(USB_VENDOR_ID_MCC, USB_DEVICE_ID_MCC_PMD1208LS) },
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICKIT1) },
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 160a309..34e2547 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -554,9 +554,6 @@
#define USB_VENDOR_ID_MADCATZ 0x0738
#define USB_DEVICE_ID_MADCATZ_BEATPAD 0x4540
-#define USB_VENDOR_ID_MASTERKIT 0x16c0
-#define USB_DEVICE_ID_MASTERKIT_MA901RADIO 0x05df
-
#define USB_VENDOR_ID_MCC 0x09db
#define USB_DEVICE_ID_MCC_PMD1024LS 0x0076
#define USB_DEVICE_ID_MCC_PMD1208LS 0x007a
@@ -587,9 +584,6 @@
#define USB_VENDOR_ID_MONTEREY 0x0566
#define USB_DEVICE_ID_GENIUS_KB29E 0x3004
-#define USB_VENDOR_ID_MSI 0x1770
-#define USB_DEVICE_ID_MSI_GX680R_LED_PANEL 0xff00
-
#define USB_VENDOR_ID_NATIONAL_SEMICONDUCTOR 0x0400
#define USB_DEVICE_ID_N_S_HARMONY 0xc359
@@ -681,9 +675,6 @@
#define USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3001 0x3001
#define USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3008 0x3008
-#define USB_VENDOR_ID_REALTEK 0x0bda
-#define USB_DEVICE_ID_REALTEK_READER 0x0152
-
#define USB_VENDOR_ID_ROCCAT 0x1e7d
#define USB_DEVICE_ID_ROCCAT_ARVO 0x30d4
#define USB_DEVICE_ID_ROCCAT_ISKU 0x319c
@@ -718,7 +709,6 @@
#define USB_VENDOR_ID_SONY 0x054c
#define USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE 0x024b
-#define USB_DEVICE_ID_SONY_VAIO_VGP_MOUSE 0x0374
#define USB_DEVICE_ID_SONY_PS3_BDREMOTE 0x0306
#define USB_DEVICE_ID_SONY_PS3_CONTROLLER 0x0268
#define USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER 0x042f
diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c
index 8758f38c..9500f2f 100644
--- a/drivers/hid/hid-logitech-dj.c
+++ b/drivers/hid/hid-logitech-dj.c
@@ -459,25 +459,19 @@ static int logi_dj_recv_send_report(struct dj_receiver_dev *djrcv_dev,
struct dj_report *dj_report)
{
struct hid_device *hdev = djrcv_dev->hdev;
- struct hid_report *report;
- struct hid_report_enum *output_report_enum;
- u8 *data = (u8 *)(&dj_report->device_index);
- int i;
+ int sent_bytes;
- output_report_enum = &hdev->report_enum[HID_OUTPUT_REPORT];
- report = output_report_enum->report_id_hash[REPORT_ID_DJ_SHORT];
-
- if (!report) {
- dev_err(&hdev->dev, "%s: unable to find dj report\n", __func__);
+ if (!hdev->hid_output_raw_report) {
+ dev_err(&hdev->dev, "%s:"
+ "hid_output_raw_report is null\n", __func__);
return -ENODEV;
}
- for (i = 0; i < report->field[0]->report_count; i++)
- report->field[0]->value[i] = data[i];
-
- usbhid_submit_report(hdev, report, USB_DIR_OUT);
+ sent_bytes = hdev->hid_output_raw_report(hdev, (u8 *) dj_report,
+ sizeof(struct dj_report),
+ HID_OUTPUT_REPORT);
- return 0;
+ return (sent_bytes < 0) ? sent_bytes : 0;
}
static int logi_dj_recv_query_paired_devices(struct dj_receiver_dev *djrcv_dev)
diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c
index 811062c..25ddf3e 100644
--- a/drivers/hid/hid-magicmouse.c
+++ b/drivers/hid/hid-magicmouse.c
@@ -462,21 +462,6 @@ static int magicmouse_input_mapping(struct hid_device *hdev,
return 0;
}
-static void magicmouse_input_configured(struct hid_device *hdev,
- struct hid_input *hi)
-
-{
- struct magicmouse_sc *msc = hid_get_drvdata(hdev);
-
- int ret = magicmouse_setup_input(msc->input, hdev);
- if (ret) {
- hid_err(hdev, "magicmouse setup input failed (%d)\n", ret);
- /* clean msc->input to notify probe() of the failure */
- msc->input = NULL;
- }
-}
-
-
static int magicmouse_probe(struct hid_device *hdev,
const struct hid_device_id *id)
{
@@ -508,10 +493,15 @@ static int magicmouse_probe(struct hid_device *hdev,
goto err_free;
}
- if (!msc->input) {
- hid_err(hdev, "magicmouse input not registered\n");
- ret = -ENOMEM;
- goto err_stop_hw;
+ /* We do this after hid-input is done parsing reports so that
+ * hid-input uses the most natural button and axis IDs.
+ */
+ if (msc->input) {
+ ret = magicmouse_setup_input(msc->input, hdev);
+ if (ret) {
+ hid_err(hdev, "magicmouse setup input failed (%d)\n", ret);
+ goto err_stop_hw;
+ }
}
if (id->product == USB_DEVICE_ID_APPLE_MAGICMOUSE)
@@ -578,7 +568,6 @@ static struct hid_driver magicmouse_driver = {
.remove = magicmouse_remove,
.raw_event = magicmouse_raw_event,
.input_mapping = magicmouse_input_mapping,
- .input_configured = magicmouse_input_configured,
};
static int __init magicmouse_init(void)
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index 126d6ae..7f33ebf 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -43,19 +43,9 @@ static __u8 *sony_report_fixup(struct hid_device *hdev, __u8 *rdesc,
{
struct sony_sc *sc = hid_get_drvdata(hdev);
- /*
- * Some Sony RF receivers wrongly declare the mouse pointer as a
- * a constant non-data variable.
- */
- if ((sc->quirks & VAIO_RDESC_CONSTANT) && *rsize >= 56 &&
- /* usage page: generic desktop controls */
- /* rdesc[0] == 0x05 && rdesc[1] == 0x01 && */
- /* usage: mouse */
- rdesc[2] == 0x09 && rdesc[3] == 0x02 &&
- /* input (usage page for x,y axes): constant, variable, relative */
- rdesc[54] == 0x81 && rdesc[55] == 0x07) {
- hid_info(hdev, "Fixing up Sony RF Receiver report descriptor\n");
- /* input: data, variable, relative */
+ if ((sc->quirks & VAIO_RDESC_CONSTANT) &&
+ *rsize >= 56 && rdesc[54] == 0x81 && rdesc[55] == 0x07) {
+ hid_info(hdev, "Fixing up Sony Vaio VGX report descriptor\n");
rdesc[55] = 0x06;
}
@@ -227,8 +217,6 @@ static const struct hid_device_id sony_devices[] = {
.driver_data = SIXAXIS_CONTROLLER_BT },
{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE),
.driver_data = VAIO_RDESC_CONSTANT },
- { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGP_MOUSE),
- .driver_data = VAIO_RDESC_CONSTANT },
{ }
};
MODULE_DEVICE_TABLE(hid, sony_devices);
diff --git a/drivers/hid/hid-wiimote-ext.c b/drivers/hid/hid-wiimote-ext.c
index 0472191..38ae877 100644
--- a/drivers/hid/hid-wiimote-ext.c
+++ b/drivers/hid/hid-wiimote-ext.c
@@ -403,14 +403,14 @@ static void handler_nunchuck(struct wiimote_ext *ext, const __u8 *payload)
if (ext->motionp) {
input_report_key(ext->input,
- wiiext_keymap[WIIEXT_KEY_Z], !(payload[5] & 0x04));
+ wiiext_keymap[WIIEXT_KEY_Z], !!(payload[5] & 0x04));
input_report_key(ext->input,
- wiiext_keymap[WIIEXT_KEY_C], !(payload[5] & 0x08));
+ wiiext_keymap[WIIEXT_KEY_C], !!(payload[5] & 0x08));
} else {
input_report_key(ext->input,
- wiiext_keymap[WIIEXT_KEY_Z], !(payload[5] & 0x01));
+ wiiext_keymap[WIIEXT_KEY_Z], !!(payload[5] & 0x01));
input_report_key(ext->input,
- wiiext_keymap[WIIEXT_KEY_C], !(payload[5] & 0x02));
+ wiiext_keymap[WIIEXT_KEY_C], !!(payload[5] & 0x02));
}
input_sync(ext->input);
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c
index 19b8360..e0e6abf 100644
--- a/drivers/hid/usbhid/hid-quirks.c
+++ b/drivers/hid/usbhid/hid-quirks.c
@@ -73,7 +73,6 @@ static const struct hid_blacklist {
{ USB_VENDOR_ID_FORMOSA, USB_DEVICE_ID_FORMOSA_IR_RECEIVER, HID_QUIRK_NO_INIT_REPORTS },
{ USB_VENDOR_ID_FREESCALE, USB_DEVICE_ID_FREESCALE_MX28, HID_QUIRK_NOGET },
{ USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_NOGET },
- { USB_VENDOR_ID_MSI, USB_DEVICE_ID_MSI_GX680R_LED_PANEL, HID_QUIRK_NO_INIT_REPORTS },
{ USB_VENDOR_ID_NOVATEK, USB_DEVICE_ID_NOVATEK_MOUSE, HID_QUIRK_NO_INIT_REPORTS },
{ USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN, HID_QUIRK_NO_INIT_REPORTS },
{ USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN1, HID_QUIRK_NO_INIT_REPORTS },
@@ -81,7 +80,6 @@ static const struct hid_blacklist {
{ USB_VENDOR_ID_PRODIGE, USB_DEVICE_ID_PRODIGE_CORDLESS, HID_QUIRK_NOGET },
{ USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3001, HID_QUIRK_NOGET },
{ USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3008, HID_QUIRK_NOGET },
- { USB_VENDOR_ID_REALTEK, USB_DEVICE_ID_REALTEK_READER, HID_QUIRK_NO_INIT_REPORTS },
{ USB_VENDOR_ID_SENNHEISER, USB_DEVICE_ID_SENNHEISER_BTD500USB, HID_QUIRK_NOGET },
{ USB_VENDOR_ID_SIGMATEL, USB_DEVICE_ID_SIGMATEL_STMP3780, HID_QUIRK_NOGET },
{ USB_VENDOR_ID_SUN, USB_DEVICE_ID_RARITAN_KVM_DONGLE, HID_QUIRK_NOGET },
diff --git a/drivers/hwmon/lineage-pem.c b/drivers/hwmon/lineage-pem.c
index ebbb9f4..41df29f 100644
--- a/drivers/hwmon/lineage-pem.c
+++ b/drivers/hwmon/lineage-pem.c
@@ -422,7 +422,6 @@ static struct attribute *pem_input_attributes[] = {
&sensor_dev_attr_in2_input.dev_attr.attr,
&sensor_dev_attr_curr1_input.dev_attr.attr,
&sensor_dev_attr_power1_input.dev_attr.attr,
- NULL
};
static const struct attribute_group pem_input_group = {
@@ -433,7 +432,6 @@ static struct attribute *pem_fan_attributes[] = {
&sensor_dev_attr_fan1_input.dev_attr.attr,
&sensor_dev_attr_fan2_input.dev_attr.attr,
&sensor_dev_attr_fan3_input.dev_attr.attr,
- NULL
};
static const struct attribute_group pem_fan_group = {
diff --git a/drivers/hwmon/pmbus/ltc2978.c b/drivers/hwmon/pmbus/ltc2978.c
index 6d61307..9652a2c 100644
--- a/drivers/hwmon/pmbus/ltc2978.c
+++ b/drivers/hwmon/pmbus/ltc2978.c
@@ -59,10 +59,10 @@ enum chips { ltc2978, ltc3880 };
struct ltc2978_data {
enum chips id;
int vin_min, vin_max;
- int temp_min, temp_max[2];
+ int temp_min, temp_max;
int vout_min[8], vout_max[8];
int iout_max[2];
- int temp2_max;
+ int temp2_max[2];
struct pmbus_driver_info info;
};
@@ -113,10 +113,9 @@ static int ltc2978_read_word_data_common(struct i2c_client *client, int page,
ret = pmbus_read_word_data(client, page,
LTC2978_MFR_TEMPERATURE_PEAK);
if (ret >= 0) {
- if (lin11_to_val(ret)
- > lin11_to_val(data->temp_max[page]))
- data->temp_max[page] = ret;
- ret = data->temp_max[page];
+ if (lin11_to_val(ret) > lin11_to_val(data->temp_max))
+ data->temp_max = ret;
+ ret = data->temp_max;
}
break;
case PMBUS_VIRT_RESET_VOUT_HISTORY:
@@ -205,9 +204,10 @@ static int ltc3880_read_word_data(struct i2c_client *client, int page, int reg)
ret = pmbus_read_word_data(client, page,
LTC3880_MFR_TEMPERATURE2_PEAK);
if (ret >= 0) {
- if (lin11_to_val(ret) > lin11_to_val(data->temp2_max))
- data->temp2_max = ret;
- ret = data->temp2_max;
+ if (lin11_to_val(ret)
+ > lin11_to_val(data->temp2_max[page]))
+ data->temp2_max[page] = ret;
+ ret = data->temp2_max[page];
}
break;
case PMBUS_VIRT_READ_VIN_MIN:
@@ -248,11 +248,11 @@ static int ltc2978_write_word_data(struct i2c_client *client, int page,
switch (reg) {
case PMBUS_VIRT_RESET_IOUT_HISTORY:
- data->iout_max[page] = 0x7c00;
+ data->iout_max[page] = 0x7fff;
ret = ltc2978_clear_peaks(client, page, data->id);
break;
case PMBUS_VIRT_RESET_TEMP2_HISTORY:
- data->temp2_max = 0x7c00;
+ data->temp2_max[page] = 0x7fff;
ret = ltc2978_clear_peaks(client, page, data->id);
break;
case PMBUS_VIRT_RESET_VOUT_HISTORY:
@@ -262,12 +262,12 @@ static int ltc2978_write_word_data(struct i2c_client *client, int page,
break;
case PMBUS_VIRT_RESET_VIN_HISTORY:
data->vin_min = 0x7bff;
- data->vin_max = 0x7c00;
+ data->vin_max = 0;
ret = ltc2978_clear_peaks(client, page, data->id);
break;
case PMBUS_VIRT_RESET_TEMP_HISTORY:
data->temp_min = 0x7bff;
- data->temp_max[page] = 0x7c00;
+ data->temp_max = 0x7fff;
ret = ltc2978_clear_peaks(client, page, data->id);
break;
default:
@@ -321,14 +321,12 @@ static int ltc2978_probe(struct i2c_client *client,
info = &data->info;
info->write_word_data = ltc2978_write_word_data;
+ data->vout_min[0] = 0xffff;
data->vin_min = 0x7bff;
- data->vin_max = 0x7c00;
data->temp_min = 0x7bff;
- for (i = 0; i < ARRAY_SIZE(data->temp_max); i++)
- data->temp_max[i] = 0x7c00;
- data->temp2_max = 0x7c00;
+ data->temp_max = 0x7fff;
- switch (data->id) {
+ switch (id->driver_data) {
case ltc2978:
info->read_word_data = ltc2978_read_word_data;
info->pages = 8;
@@ -338,6 +336,7 @@ static int ltc2978_probe(struct i2c_client *client,
for (i = 1; i < 8; i++) {
info->func[i] = PMBUS_HAVE_VOUT
| PMBUS_HAVE_STATUS_VOUT;
+ data->vout_min[i] = 0xffff;
}
break;
case ltc3880:
@@ -353,14 +352,11 @@ static int ltc2978_probe(struct i2c_client *client,
| PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT
| PMBUS_HAVE_POUT
| PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP;
- data->iout_max[0] = 0x7c00;
- data->iout_max[1] = 0x7c00;
+ data->vout_min[1] = 0xffff;
break;
default:
return -ENODEV;
}
- for (i = 0; i < info->pages; i++)
- data->vout_min[i] = 0xffff;
return pmbus_do_probe(client, id, info);
}
diff --git a/drivers/hwmon/sht15.c b/drivers/hwmon/sht15.c
index 8047fed..1c85d39 100644
--- a/drivers/hwmon/sht15.c
+++ b/drivers/hwmon/sht15.c
@@ -926,13 +926,7 @@ static int sht15_probe(struct platform_device *pdev)
if (voltage)
data->supply_uV = voltage;
- ret = regulator_enable(data->reg);
- if (ret != 0) {
- dev_err(&pdev->dev,
- "failed to enable regulator: %d\n", ret);
- return ret;
- }
-
+ regulator_enable(data->reg);
/*
* Setup a notifier block to update this if another device
* causes the voltage to change
diff --git a/drivers/hwspinlock/hwspinlock_core.c b/drivers/hwspinlock/hwspinlock_core.c
index 461a0d7..db713c0 100644
--- a/drivers/hwspinlock/hwspinlock_core.c
+++ b/drivers/hwspinlock/hwspinlock_core.c
@@ -416,8 +416,6 @@ static int __hwspin_lock_request(struct hwspinlock *hwlock)
ret = pm_runtime_get_sync(dev);
if (ret < 0) {
dev_err(dev, "%s: can't power on device\n", __func__);
- pm_runtime_put_noidle(dev);
- module_put(dev->driver->owner);
return ret;
}
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index bb51488..4cc2f05 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -881,12 +881,15 @@ omap_i2c_isr(int irq, void *dev_id)
u16 mask;
u16 stat;
- stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG);
+ spin_lock(&dev->lock);
mask = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG);
+ stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG);
if (stat & mask)
ret = IRQ_WAKE_THREAD;
+ spin_unlock(&dev->lock);
+
return ret;
}
diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index 9e622b7..7b38877 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -392,11 +392,7 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
u32 val;
int err = 0;
- err = tegra_i2c_clock_enable(i2c_dev);
- if (err < 0) {
- dev_err(i2c_dev->dev, "Clock enable failed %d\n", err);
- return err;
- }
+ tegra_i2c_clock_enable(i2c_dev);
tegra_periph_reset_assert(i2c_dev->div_clk);
udelay(2);
@@ -603,12 +599,7 @@ static int tegra_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
if (i2c_dev->is_suspended)
return -EBUSY;
- ret = tegra_i2c_clock_enable(i2c_dev);
- if (ret < 0) {
- dev_err(i2c_dev->dev, "Clock enable failed %d\n", ret);
- return ret;
- }
-
+ tegra_i2c_clock_enable(i2c_dev);
for (i = 0; i < num; i++) {
enum msg_end_type end_type = MSG_END_STOP;
if (i < (num - 1)) {
diff --git a/drivers/i2c/busses/i2c-xiic.c b/drivers/i2c/busses/i2c-xiic.c
index fd7d66d..f042f6d 100644
--- a/drivers/i2c/busses/i2c-xiic.c
+++ b/drivers/i2c/busses/i2c-xiic.c
@@ -312,8 +312,10 @@ static void xiic_fill_tx_fifo(struct xiic_i2c *i2c)
/* last message in transfer -> STOP */
data |= XIIC_TX_DYN_STOP_MASK;
dev_dbg(i2c->adap.dev.parent, "%s TX STOP\n", __func__);
- }
- xiic_setreg16(i2c, XIIC_DTR_REG_OFFSET, data);
+
+ xiic_setreg16(i2c, XIIC_DTR_REG_OFFSET, data);
+ } else
+ xiic_setreg8(i2c, XIIC_DTR_REG_OFFSET, data);
}
}
diff --git a/drivers/ide/alim15x3.c b/drivers/ide/alim15x3.c
index 394f142f..36f76e2 100644
--- a/drivers/ide/alim15x3.c
+++ b/drivers/ide/alim15x3.c
@@ -234,7 +234,7 @@ static int init_chipset_ali15x3(struct pci_dev *dev)
isa_dev = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL);
- local_irq_save_nort(flags);
+ local_irq_save(flags);
if (m5229_revision < 0xC2) {
/*
@@ -325,7 +325,7 @@ out:
}
pci_dev_put(north);
pci_dev_put(isa_dev);
- local_irq_restore_nort(flags);
+ local_irq_restore(flags);
return 0;
}
diff --git a/drivers/ide/hpt366.c b/drivers/ide/hpt366.c
index 0d0a966..696b6c1 100644
--- a/drivers/ide/hpt366.c
+++ b/drivers/ide/hpt366.c
@@ -1241,7 +1241,7 @@ static int init_dma_hpt366(ide_hwif_t *hwif,
dma_old = inb(base + 2);
- local_irq_save_nort(flags);
+ local_irq_save(flags);
dma_new = dma_old;
pci_read_config_byte(dev, hwif->channel ? 0x4b : 0x43, &masterdma);
@@ -1252,7 +1252,7 @@ static int init_dma_hpt366(ide_hwif_t *hwif,
if (dma_new != dma_old)
outb(dma_new, base + 2);
- local_irq_restore_nort(flags);
+ local_irq_restore(flags);
printk(KERN_INFO " %s: BM-DMA at 0x%04lx-0x%04lx\n",
hwif->name, base, base + 7);
diff --git a/drivers/ide/ide-io-std.c b/drivers/ide/ide-io-std.c
index 4169433..1976397 100644
--- a/drivers/ide/ide-io-std.c
+++ b/drivers/ide/ide-io-std.c
@@ -175,7 +175,7 @@ void ide_input_data(ide_drive_t *drive, struct ide_cmd *cmd, void *buf,
unsigned long uninitialized_var(flags);
if ((io_32bit & 2) && !mmio) {
- local_irq_save_nort(flags);
+ local_irq_save(flags);
ata_vlb_sync(io_ports->nsect_addr);
}
@@ -186,7 +186,7 @@ void ide_input_data(ide_drive_t *drive, struct ide_cmd *cmd, void *buf,
insl(data_addr, buf, words);
if ((io_32bit & 2) && !mmio)
- local_irq_restore_nort(flags);
+ local_irq_restore(flags);
if (((len + 1) & 3) < 2)
return;
@@ -219,7 +219,7 @@ void ide_output_data(ide_drive_t *drive, struct ide_cmd *cmd, void *buf,
unsigned long uninitialized_var(flags);
if ((io_32bit & 2) && !mmio) {
- local_irq_save_nort(flags);
+ local_irq_save(flags);
ata_vlb_sync(io_ports->nsect_addr);
}
@@ -230,7 +230,7 @@ void ide_output_data(ide_drive_t *drive, struct ide_cmd *cmd, void *buf,
outsl(data_addr, buf, words);
if ((io_32bit & 2) && !mmio)
- local_irq_restore_nort(flags);
+ local_irq_restore(flags);
if (((len + 1) & 3) < 2)
return;
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
index 079ae6b..177db6d 100644
--- a/drivers/ide/ide-io.c
+++ b/drivers/ide/ide-io.c
@@ -659,7 +659,7 @@ void ide_timer_expiry (unsigned long data)
/* disable_irq_nosync ?? */
disable_irq(hwif->irq);
/* local CPU only, as if we were handling an interrupt */
- local_irq_disable_nort();
+ local_irq_disable();
if (hwif->polling) {
startstop = handler(drive);
} else if (drive_is_ready(drive)) {
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c
index f014dd1..376f2dc 100644
--- a/drivers/ide/ide-iops.c
+++ b/drivers/ide/ide-iops.c
@@ -129,12 +129,12 @@ int __ide_wait_stat(ide_drive_t *drive, u8 good, u8 bad,
if ((stat & ATA_BUSY) == 0)
break;
- local_irq_restore_nort(flags);
+ local_irq_restore(flags);
*rstat = stat;
return -EBUSY;
}
}
- local_irq_restore_nort(flags);
+ local_irq_restore(flags);
}
/*
* Allow status to settle, then read it again.
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index 38e69e1..068cef0 100644
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -196,10 +196,10 @@ static void do_identify(ide_drive_t *drive, u8 cmd, u16 *id)
int bswap = 1;
/* local CPU only; some systems need this */
- local_irq_save_nort(flags);
+ local_irq_save(flags);
/* read 512 bytes of id info */
hwif->tp_ops->input_data(drive, NULL, id, SECTOR_SIZE);
- local_irq_restore_nort(flags);
+ local_irq_restore(flags);
drive->dev_flags |= IDE_DFLAG_ID_READ;
#ifdef DEBUG
diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c
index 3a9a1fc..729428e 100644
--- a/drivers/ide/ide-taskfile.c
+++ b/drivers/ide/ide-taskfile.c
@@ -251,7 +251,7 @@ void ide_pio_bytes(ide_drive_t *drive, struct ide_cmd *cmd,
page_is_high = PageHighMem(page);
if (page_is_high)
- local_irq_save_nort(flags);
+ local_irq_save(flags);
buf = kmap_atomic(page) + offset;
@@ -272,7 +272,7 @@ void ide_pio_bytes(ide_drive_t *drive, struct ide_cmd *cmd,
kunmap_atomic(buf);
if (page_is_high)
- local_irq_restore_nort(flags);
+ local_irq_restore(flags);
len -= nr_bytes;
}
@@ -415,7 +415,7 @@ static ide_startstop_t pre_task_out_intr(ide_drive_t *drive,
}
if ((drive->dev_flags & IDE_DFLAG_UNMASK) == 0)
- local_irq_disable_nort();
+ local_irq_disable();
ide_set_handler(drive, &task_pio_intr, WAIT_WORSTCASE);
diff --git a/drivers/idle/i7300_idle.c b/drivers/idle/i7300_idle.c
index ffeebc7..fa080eb 100644
--- a/drivers/idle/i7300_idle.c
+++ b/drivers/idle/i7300_idle.c
@@ -75,7 +75,7 @@ static unsigned long past_skip;
static struct pci_dev *fbd_dev;
-static raw_spinlock_t i7300_idle_lock;
+static spinlock_t i7300_idle_lock;
static int i7300_idle_active;
static u8 i7300_idle_thrtctl_saved;
@@ -457,7 +457,7 @@ static int i7300_idle_notifier(struct notifier_block *nb, unsigned long val,
idle_begin_time = ktime_get();
}
- raw_spin_lock_irqsave(&i7300_idle_lock, flags);
+ spin_lock_irqsave(&i7300_idle_lock, flags);
if (val == IDLE_START) {
cpumask_set_cpu(smp_processor_id(), idle_cpumask);
@@ -506,7 +506,7 @@ static int i7300_idle_notifier(struct notifier_block *nb, unsigned long val,
}
}
end:
- raw_spin_unlock_irqrestore(&i7300_idle_lock, flags);
+ spin_unlock_irqrestore(&i7300_idle_lock, flags);
return 0;
}
@@ -548,7 +548,7 @@ struct debugfs_file_info {
static int __init i7300_idle_init(void)
{
- raw_spin_lock_init(&i7300_idle_lock);
+ spin_lock_init(&i7300_idle_lock);
total_us = 0;
if (i7300_idle_platform_probe(&fbd_dev, &ioat_dev, forceload))
diff --git a/drivers/infiniband/hw/cxgb4/qp.c b/drivers/infiniband/hw/cxgb4/qp.c
index 892cd87..05bfe53 100644
--- a/drivers/infiniband/hw/cxgb4/qp.c
+++ b/drivers/infiniband/hw/cxgb4/qp.c
@@ -100,16 +100,6 @@ static int alloc_host_sq(struct c4iw_rdev *rdev, struct t4_sq *sq)
return 0;
}
-static int alloc_sq(struct c4iw_rdev *rdev, struct t4_sq *sq, int user)
-{
- int ret = -ENOSYS;
- if (user)
- ret = alloc_oc_sq(rdev, sq);
- if (ret)
- ret = alloc_host_sq(rdev, sq);
- return ret;
-}
-
static int destroy_qp(struct c4iw_rdev *rdev, struct t4_wq *wq,
struct c4iw_dev_ucontext *uctx)
{
@@ -178,9 +168,18 @@ static int create_qp(struct c4iw_rdev *rdev, struct t4_wq *wq,
goto free_sw_rq;
}
- ret = alloc_sq(rdev, &wq->sq, user);
- if (ret)
- goto free_hwaddr;
+ if (user) {
+ ret = alloc_oc_sq(rdev, &wq->sq);
+ if (ret)
+ goto free_hwaddr;
+
+ ret = alloc_host_sq(rdev, &wq->sq);
+ if (ret)
+ goto free_sq;
+ } else
+ ret = alloc_host_sq(rdev, &wq->sq);
+ if (ret)
+ goto free_hwaddr;
memset(wq->sq.queue, 0, wq->sq.memsize);
dma_unmap_addr_set(&wq->sq, mapping, wq->sq.dma_addr);
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
index 1ef880d..67b0c1d 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
@@ -758,13 +758,9 @@ void ipoib_cm_send(struct net_device *dev, struct sk_buff *skb, struct ipoib_cm_
if (++priv->tx_outstanding == ipoib_sendq_size) {
ipoib_dbg(priv, "TX ring 0x%x full, stopping kernel net queue\n",
tx->qp->qp_num);
- netif_stop_queue(dev);
- rc = ib_req_notify_cq(priv->send_cq,
- IB_CQ_NEXT_COMP | IB_CQ_REPORT_MISSED_EVENTS);
- if (rc < 0)
+ if (ib_req_notify_cq(priv->send_cq, IB_CQ_NEXT_COMP))
ipoib_warn(priv, "request notify on send CQ failed\n");
- else if (rc)
- ipoib_send_comp_handler(priv->send_cq, dev);
+ netif_stop_queue(dev);
}
}
}
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
index 3800ef5..cecb98a 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
@@ -783,7 +783,7 @@ void ipoib_mcast_restart_task(struct work_struct *work)
ipoib_mcast_stop_thread(dev, 0);
- local_irq_save_nort(flags);
+ local_irq_save(flags);
netif_addr_lock(dev);
spin_lock(&priv->lock);
@@ -865,7 +865,7 @@ void ipoib_mcast_restart_task(struct work_struct *work)
spin_unlock(&priv->lock);
netif_addr_unlock(dev);
- local_irq_restore_nort(flags);
+ local_irq_restore(flags);
/* We have to cancel outside of the spinlock */
list_for_each_entry_safe(mcast, tmcast, &remove_list, list) {
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c
index 7ccf328..d5088ce 100644
--- a/drivers/infiniband/ulp/srp/ib_srp.c
+++ b/drivers/infiniband/ulp/srp/ib_srp.c
@@ -700,24 +700,23 @@ static int srp_reconnect_target(struct srp_target_port *target)
struct Scsi_Host *shost = target->scsi_host;
int i, ret;
+ if (target->state != SRP_TARGET_LIVE)
+ return -EAGAIN;
+
scsi_target_block(&shost->shost_gendev);
srp_disconnect_target(target);
/*
- * Now get a new local CM ID so that we avoid confusing the target in
- * case things are really fouled up. Doing so also ensures that all CM
- * callbacks will have finished before a new QP is allocated.
+ * Now get a new local CM ID so that we avoid confusing the
+ * target in case things are really fouled up.
*/
ret = srp_new_cm_id(target);
- /*
- * Whether or not creating a new CM ID succeeded, create a new
- * QP. This guarantees that all completion callback function
- * invocations have finished before request resetting starts.
- */
- if (ret == 0)
- ret = srp_create_target_ib(target);
- else
- srp_create_target_ib(target);
+ if (ret)
+ goto unblock;
+
+ ret = srp_create_target_ib(target);
+ if (ret)
+ goto unblock;
for (i = 0; i < SRP_CMD_SQ_SIZE; ++i) {
struct srp_request *req = &target->req_ring[i];
@@ -729,12 +728,11 @@ static int srp_reconnect_target(struct srp_target_port *target)
for (i = 0; i < SRP_SQ_SIZE; ++i)
list_add(&target->tx_ring[i]->list, &target->free_tx);
- if (ret == 0)
- ret = srp_connect_target(target);
+ ret = srp_connect_target(target);
+unblock:
scsi_target_unblock(&shost->shost_gendev, ret == 0 ? SDEV_RUNNING :
SDEV_TRANSPORT_OFFLINE);
- target->transport_offline = !!ret;
if (ret)
goto err;
@@ -1354,12 +1352,6 @@ static int srp_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *scmnd)
unsigned long flags;
int len;
- if (unlikely(target->transport_offline)) {
- scmnd->result = DID_NO_CONNECT << 16;
- scmnd->scsi_done(scmnd);
- return 0;
- }
-
spin_lock_irqsave(&target->lock, flags);
iu = __srp_get_tx_iu(target, SRP_IU_CMD);
if (!iu)
@@ -1703,9 +1695,6 @@ static int srp_send_tsk_mgmt(struct srp_target_port *target,
struct srp_iu *iu;
struct srp_tsk_mgmt *tsk_mgmt;
- if (!target->connected || target->qp_in_error)
- return -1;
-
init_completion(&target->tsk_mgmt_done);
spin_lock_irq(&target->lock);
@@ -1747,7 +1736,7 @@ static int srp_abort(struct scsi_cmnd *scmnd)
shost_printk(KERN_ERR, target->scsi_host, "SRP abort called\n");
- if (!req || !srp_claim_req(target, req, scmnd))
+ if (!req || target->qp_in_error || !srp_claim_req(target, req, scmnd))
return FAILED;
srp_send_tsk_mgmt(target, req->index, scmnd->device->lun,
SRP_TSK_ABORT_TASK);
@@ -1765,6 +1754,8 @@ static int srp_reset_device(struct scsi_cmnd *scmnd)
shost_printk(KERN_ERR, target->scsi_host, "SRP reset_device called\n");
+ if (target->qp_in_error)
+ return FAILED;
if (srp_send_tsk_mgmt(target, SRP_TAG_NO_REQ, scmnd->device->lun,
SRP_TSK_LUN_RESET))
return FAILED;
@@ -1981,6 +1972,7 @@ static int srp_add_target(struct srp_host *host, struct srp_target_port *target)
spin_unlock(&host->target_lock);
target->state = SRP_TARGET_LIVE;
+ target->connected = false;
scsi_scan_target(&target->scsi_host->shost_gendev,
0, target->scsi_id, SCAN_WILD_CARD, 0);
diff --git a/drivers/infiniband/ulp/srp/ib_srp.h b/drivers/infiniband/ulp/srp/ib_srp.h
index 66fbedd..de2d0b3 100644
--- a/drivers/infiniband/ulp/srp/ib_srp.h
+++ b/drivers/infiniband/ulp/srp/ib_srp.h
@@ -140,7 +140,6 @@ struct srp_target_port {
unsigned int cmd_sg_cnt;
unsigned int indirect_size;
bool allow_ext_sg;
- bool transport_offline;
/* Everything above this point is used in the hot path of
* command processing. Try to keep them packed into cachelines.
diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c
index 18fdafe..da739d9 100644
--- a/drivers/input/gameport/gameport.c
+++ b/drivers/input/gameport/gameport.c
@@ -87,12 +87,12 @@ static int gameport_measure_speed(struct gameport *gameport)
tx = 1 << 30;
for(i = 0; i < 50; i++) {
- local_irq_save_nort(flags);
+ local_irq_save(flags);
GET_TIME(t1);
for (t = 0; t < 50; t++) gameport_read(gameport);
GET_TIME(t2);
GET_TIME(t3);
- local_irq_restore_nort(flags);
+ local_irq_restore(flags);
udelay(i * 10);
if ((t = DELTA(t2,t1) - DELTA(t3,t2)) < tx) tx = t;
}
@@ -111,11 +111,11 @@ static int gameport_measure_speed(struct gameport *gameport)
tx = 1 << 30;
for(i = 0; i < 50; i++) {
- local_irq_save_nort(flags);
+ local_irq_save(flags);
rdtscl(t1);
for (t = 0; t < 50; t++) gameport_read(gameport);
rdtscl(t2);
- local_irq_restore_nort(flags);
+ local_irq_restore(flags);
udelay(i * 10);
if (t2 - t1 < tx) tx = t2 - t1;
}
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index 4c867f4..c1c74e0 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd_iommu.c
@@ -2466,16 +2466,18 @@ static int device_change_notifier(struct notifier_block *nb,
/* allocate a protection domain if a device is added */
dma_domain = find_protection_domain(devid);
- if (!dma_domain) {
- dma_domain = dma_ops_domain_alloc();
- if (!dma_domain)
- goto out;
- dma_domain->target_dev = devid;
-
- spin_lock_irqsave(&iommu_pd_list_lock, flags);
- list_add_tail(&dma_domain->list, &iommu_pd_list);
- spin_unlock_irqrestore(&iommu_pd_list_lock, flags);
- }
+ if (dma_domain)
+ goto out;
+ dma_domain = dma_ops_domain_alloc();
+ if (!dma_domain)
+ goto out;
+ dma_domain->target_dev = devid;
+
+ spin_lock_irqsave(&iommu_pd_list_lock, flags);
+ list_add_tail(&dma_domain->list, &iommu_pd_list);
+ spin_unlock_irqrestore(&iommu_pd_list_lock, flags);
+
+ dev_data = get_dev_data(dev);
dev->archdata.dma_ops = &amd_iommu_dma_ops;
@@ -3948,9 +3950,6 @@ static struct irq_remap_table *get_irq_table(u16 devid, bool ioapic)
if (!table)
goto out;
- /* Initialize table spin-lock */
- spin_lock_init(&table->lock);
-
if (ioapic)
/* Keep the first 32 indexes free for IOAPIC interrupts */
table->min_index = 32;
diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c
index b6ecddb..faf10ba 100644
--- a/drivers/iommu/amd_iommu_init.c
+++ b/drivers/iommu/amd_iommu_init.c
@@ -1876,6 +1876,11 @@ static int amd_iommu_init_dma(void)
struct amd_iommu *iommu;
int ret;
+ init_device_table_dma();
+
+ for_each_iommu(iommu)
+ iommu_flush_all_caches(iommu);
+
if (iommu_pass_through)
ret = amd_iommu_init_passthrough();
else
@@ -1884,11 +1889,6 @@ static int amd_iommu_init_dma(void)
if (ret)
return ret;
- init_device_table_dma();
-
- for_each_iommu(iommu)
- iommu_flush_all_caches(iommu);
-
amd_iommu_init_api();
amd_iommu_init_notifier();
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index f1e7b86..eca2801 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -4253,19 +4253,13 @@ static void quirk_iommu_rwbf(struct pci_dev *dev)
{
/*
* Mobile 4 Series Chipset neglects to set RWBF capability,
- * but needs it. Same seems to hold for the desktop versions.
+ * but needs it:
*/
printk(KERN_INFO "DMAR: Forcing write-buffer flush capability\n");
rwbf_quirk = 1;
}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2a40, quirk_iommu_rwbf);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e00, quirk_iommu_rwbf);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e10, quirk_iommu_rwbf);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e20, quirk_iommu_rwbf);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e30, quirk_iommu_rwbf);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e40, quirk_iommu_rwbf);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e90, quirk_iommu_rwbf);
#define GGC 0x52
#define GGC_MEMORY_SIZE_MASK (0xf << 8)
diff --git a/drivers/md/dm-bufio.c b/drivers/md/dm-bufio.c
index 64eff90..651ca79 100644
--- a/drivers/md/dm-bufio.c
+++ b/drivers/md/dm-bufio.c
@@ -1026,8 +1026,6 @@ void dm_bufio_prefetch(struct dm_bufio_client *c,
{
struct blk_plug plug;
- BUG_ON(dm_bufio_in_request());
-
blk_start_plug(&plug);
dm_bufio_lock(c);
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index 2ae151e..f7369f9 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -1234,6 +1234,20 @@ static int crypt_decode_key(u8 *key, char *hex, unsigned int size)
return 0;
}
+/*
+ * Encode key into its hex representation
+ */
+static void crypt_encode_key(char *hex, u8 *key, unsigned int size)
+{
+ unsigned int i;
+
+ for (i = 0; i < size; i++) {
+ sprintf(hex, "%02x", *key);
+ hex += 2;
+ key++;
+ }
+}
+
static void crypt_free_tfms(struct crypt_config *cc)
{
unsigned i;
@@ -1703,11 +1717,11 @@ static int crypt_map(struct dm_target *ti, struct bio *bio)
return DM_MAPIO_SUBMITTED;
}
-static void crypt_status(struct dm_target *ti, status_type_t type,
- unsigned status_flags, char *result, unsigned maxlen)
+static int crypt_status(struct dm_target *ti, status_type_t type,
+ unsigned status_flags, char *result, unsigned maxlen)
{
struct crypt_config *cc = ti->private;
- unsigned i, sz = 0;
+ unsigned int sz = 0;
switch (type) {
case STATUSTYPE_INFO:
@@ -1717,11 +1731,17 @@ static void crypt_status(struct dm_target *ti, status_type_t type,
case STATUSTYPE_TABLE:
DMEMIT("%s ", cc->cipher_string);
- if (cc->key_size > 0)
- for (i = 0; i < cc->key_size; i++)
- DMEMIT("%02x", cc->key[i]);
- else
- DMEMIT("-");
+ if (cc->key_size > 0) {
+ if ((maxlen - sz) < ((cc->key_size << 1) + 1))
+ return -ENOMEM;
+
+ crypt_encode_key(result + sz, cc->key, cc->key_size);
+ sz += cc->key_size << 1;
+ } else {
+ if (sz >= maxlen)
+ return -ENOMEM;
+ result[sz++] = '-';
+ }
DMEMIT(" %llu %s %llu", (unsigned long long)cc->iv_offset,
cc->dev->name, (unsigned long long)cc->start);
@@ -1731,6 +1751,7 @@ static void crypt_status(struct dm_target *ti, status_type_t type,
break;
}
+ return 0;
}
static void crypt_postsuspend(struct dm_target *ti)
@@ -1824,7 +1845,7 @@ static int crypt_iterate_devices(struct dm_target *ti,
static struct target_type crypt_target = {
.name = "crypt",
- .version = {1, 12, 1},
+ .version = {1, 12, 0},
.module = THIS_MODULE,
.ctr = crypt_ctr,
.dtr = crypt_dtr,
diff --git a/drivers/md/dm-delay.c b/drivers/md/dm-delay.c
index c0d03b0..cc1bd04 100644
--- a/drivers/md/dm-delay.c
+++ b/drivers/md/dm-delay.c
@@ -293,8 +293,8 @@ static int delay_map(struct dm_target *ti, struct bio *bio)
return delay_bio(dc, dc->read_delay, bio);
}
-static void delay_status(struct dm_target *ti, status_type_t type,
- unsigned status_flags, char *result, unsigned maxlen)
+static int delay_status(struct dm_target *ti, status_type_t type,
+ unsigned status_flags, char *result, unsigned maxlen)
{
struct delay_c *dc = ti->private;
int sz = 0;
@@ -314,6 +314,8 @@ static void delay_status(struct dm_target *ti, status_type_t type,
dc->write_delay);
break;
}
+
+ return 0;
}
static int delay_iterate_devices(struct dm_target *ti,
@@ -335,7 +337,7 @@ out:
static struct target_type delay_target = {
.name = "delay",
- .version = {1, 2, 1},
+ .version = {1, 2, 0},
.module = THIS_MODULE,
.ctr = delay_ctr,
.dtr = delay_dtr,
diff --git a/drivers/md/dm-flakey.c b/drivers/md/dm-flakey.c
index 5d6c04c..9721f2f 100644
--- a/drivers/md/dm-flakey.c
+++ b/drivers/md/dm-flakey.c
@@ -337,8 +337,8 @@ static int flakey_end_io(struct dm_target *ti, struct bio *bio, int error)
return error;
}
-static void flakey_status(struct dm_target *ti, status_type_t type,
- unsigned status_flags, char *result, unsigned maxlen)
+static int flakey_status(struct dm_target *ti, status_type_t type,
+ unsigned status_flags, char *result, unsigned maxlen)
{
unsigned sz = 0;
struct flakey_c *fc = ti->private;
@@ -368,6 +368,7 @@ static void flakey_status(struct dm_target *ti, status_type_t type,
break;
}
+ return 0;
}
static int flakey_ioctl(struct dm_target *ti, unsigned int cmd, unsigned long arg)
@@ -410,7 +411,7 @@ static int flakey_iterate_devices(struct dm_target *ti, iterate_devices_callout_
static struct target_type flakey_target = {
.name = "flakey",
- .version = {1, 3, 1},
+ .version = {1, 3, 0},
.module = THIS_MODULE,
.ctr = flakey_ctr,
.dtr = flakey_dtr,
diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c
index eee353d..0666b5d 100644
--- a/drivers/md/dm-ioctl.c
+++ b/drivers/md/dm-ioctl.c
@@ -1067,7 +1067,6 @@ static void retrieve_status(struct dm_table *table,
num_targets = dm_table_get_num_targets(table);
for (i = 0; i < num_targets; i++) {
struct dm_target *ti = dm_table_get_target(table, i);
- size_t l;
remaining = len - (outptr - outbuf);
if (remaining <= sizeof(struct dm_target_spec)) {
@@ -1094,17 +1093,14 @@ static void retrieve_status(struct dm_table *table,
if (ti->type->status) {
if (param->flags & DM_NOFLUSH_FLAG)
status_flags |= DM_STATUS_NOFLUSH_FLAG;
- ti->type->status(ti, type, status_flags, outptr, remaining);
+ if (ti->type->status(ti, type, status_flags, outptr, remaining)) {
+ param->flags |= DM_BUFFER_FULL_FLAG;
+ break;
+ }
} else
outptr[0] = '\0';
- l = strlen(outptr) + 1;
- if (l == remaining) {
- param->flags |= DM_BUFFER_FULL_FLAG;
- break;
- }
-
- outptr += l;
+ outptr += strlen(outptr) + 1;
used = param->data_start + (outptr - outbuf);
outptr = align_ptr(outptr);
diff --git a/drivers/md/dm-linear.c b/drivers/md/dm-linear.c
index 5be301c..328cad5 100644
--- a/drivers/md/dm-linear.c
+++ b/drivers/md/dm-linear.c
@@ -95,8 +95,8 @@ static int linear_map(struct dm_target *ti, struct bio *bio)
return DM_MAPIO_REMAPPED;
}
-static void linear_status(struct dm_target *ti, status_type_t type,
- unsigned status_flags, char *result, unsigned maxlen)
+static int linear_status(struct dm_target *ti, status_type_t type,
+ unsigned status_flags, char *result, unsigned maxlen)
{
struct linear_c *lc = (struct linear_c *) ti->private;
@@ -110,6 +110,7 @@ static void linear_status(struct dm_target *ti, status_type_t type,
(unsigned long long)lc->start);
break;
}
+ return 0;
}
static int linear_ioctl(struct dm_target *ti, unsigned int cmd,
@@ -154,7 +155,7 @@ static int linear_iterate_devices(struct dm_target *ti,
static struct target_type linear_target = {
.name = "linear",
- .version = {1, 2, 1},
+ .version = {1, 2, 0},
.module = THIS_MODULE,
.ctr = linear_ctr,
.dtr = linear_dtr,
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c
index d267bb5..573bd04 100644
--- a/drivers/md/dm-mpath.c
+++ b/drivers/md/dm-mpath.c
@@ -1378,8 +1378,8 @@ static void multipath_resume(struct dm_target *ti)
* [priority selector-name num_ps_args [ps_args]*
* num_paths num_selector_args [path_dev [selector_args]* ]+ ]+
*/
-static void multipath_status(struct dm_target *ti, status_type_t type,
- unsigned status_flags, char *result, unsigned maxlen)
+static int multipath_status(struct dm_target *ti, status_type_t type,
+ unsigned status_flags, char *result, unsigned maxlen)
{
int sz = 0;
unsigned long flags;
@@ -1485,6 +1485,8 @@ static void multipath_status(struct dm_target *ti, status_type_t type,
}
spin_unlock_irqrestore(&m->lock, flags);
+
+ return 0;
}
static int multipath_message(struct dm_target *ti, unsigned argc, char **argv)
@@ -1693,7 +1695,7 @@ out:
*---------------------------------------------------------------*/
static struct target_type multipath_target = {
.name = "multipath",
- .version = {1, 5, 1},
+ .version = {1, 5, 0},
.module = THIS_MODULE,
.ctr = multipath_ctr,
.dtr = multipath_dtr,
diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c
index 5a578d8..9e58dbd 100644
--- a/drivers/md/dm-raid.c
+++ b/drivers/md/dm-raid.c
@@ -1201,8 +1201,8 @@ static int raid_map(struct dm_target *ti, struct bio *bio)
return DM_MAPIO_SUBMITTED;
}
-static void raid_status(struct dm_target *ti, status_type_t type,
- unsigned status_flags, char *result, unsigned maxlen)
+static int raid_status(struct dm_target *ti, status_type_t type,
+ unsigned status_flags, char *result, unsigned maxlen)
{
struct raid_set *rs = ti->private;
unsigned raid_param_cnt = 1; /* at least 1 for chunksize */
@@ -1344,6 +1344,8 @@ static void raid_status(struct dm_target *ti, status_type_t type,
DMEMIT(" -");
}
}
+
+ return 0;
}
static int raid_iterate_devices(struct dm_target *ti, iterate_devices_callout_fn fn, void *data)
@@ -1403,7 +1405,7 @@ static void raid_resume(struct dm_target *ti)
static struct target_type raid_target = {
.name = "raid",
- .version = {1, 4, 2},
+ .version = {1, 4, 1},
.module = THIS_MODULE,
.ctr = raid_ctr,
.dtr = raid_dtr,
diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c
index 7f24190..fa51918 100644
--- a/drivers/md/dm-raid1.c
+++ b/drivers/md/dm-raid1.c
@@ -1347,8 +1347,8 @@ static char device_status_char(struct mirror *m)
}
-static void mirror_status(struct dm_target *ti, status_type_t type,
- unsigned status_flags, char *result, unsigned maxlen)
+static int mirror_status(struct dm_target *ti, status_type_t type,
+ unsigned status_flags, char *result, unsigned maxlen)
{
unsigned int m, sz = 0;
struct mirror_set *ms = (struct mirror_set *) ti->private;
@@ -1383,6 +1383,8 @@ static void mirror_status(struct dm_target *ti, status_type_t type,
if (ms->features & DM_RAID1_HANDLE_ERRORS)
DMEMIT(" 1 handle_errors");
}
+
+ return 0;
}
static int mirror_iterate_devices(struct dm_target *ti,
@@ -1401,7 +1403,7 @@ static int mirror_iterate_devices(struct dm_target *ti,
static struct target_type mirror_target = {
.name = "mirror",
- .version = {1, 13, 2},
+ .version = {1, 13, 1},
.module = THIS_MODULE,
.ctr = mirror_ctr,
.dtr = mirror_dtr,
diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c
index df74f9f..59fc18a 100644
--- a/drivers/md/dm-snap.c
+++ b/drivers/md/dm-snap.c
@@ -1837,8 +1837,8 @@ static void snapshot_merge_resume(struct dm_target *ti)
start_merge(s);
}
-static void snapshot_status(struct dm_target *ti, status_type_t type,
- unsigned status_flags, char *result, unsigned maxlen)
+static int snapshot_status(struct dm_target *ti, status_type_t type,
+ unsigned status_flags, char *result, unsigned maxlen)
{
unsigned sz = 0;
struct dm_snapshot *snap = ti->private;
@@ -1884,6 +1884,8 @@ static void snapshot_status(struct dm_target *ti, status_type_t type,
maxlen - sz);
break;
}
+
+ return 0;
}
static int snapshot_iterate_devices(struct dm_target *ti,
@@ -2137,8 +2139,8 @@ static void origin_resume(struct dm_target *ti)
ti->max_io_len = get_origin_minimum_chunksize(dev->bdev);
}
-static void origin_status(struct dm_target *ti, status_type_t type,
- unsigned status_flags, char *result, unsigned maxlen)
+static int origin_status(struct dm_target *ti, status_type_t type,
+ unsigned status_flags, char *result, unsigned maxlen)
{
struct dm_dev *dev = ti->private;
@@ -2151,6 +2153,8 @@ static void origin_status(struct dm_target *ti, status_type_t type,
snprintf(result, maxlen, "%s", dev->name);
break;
}
+
+ return 0;
}
static int origin_merge(struct dm_target *ti, struct bvec_merge_data *bvm,
@@ -2177,7 +2181,7 @@ static int origin_iterate_devices(struct dm_target *ti,
static struct target_type origin_target = {
.name = "snapshot-origin",
- .version = {1, 8, 1},
+ .version = {1, 8, 0},
.module = THIS_MODULE,
.ctr = origin_ctr,
.dtr = origin_dtr,
@@ -2190,7 +2194,7 @@ static struct target_type origin_target = {
static struct target_type snapshot_target = {
.name = "snapshot",
- .version = {1, 11, 1},
+ .version = {1, 11, 0},
.module = THIS_MODULE,
.ctr = snapshot_ctr,
.dtr = snapshot_dtr,
@@ -2303,5 +2307,3 @@ module_exit(dm_snapshot_exit);
MODULE_DESCRIPTION(DM_NAME " snapshot target");
MODULE_AUTHOR("Joe Thornber");
MODULE_LICENSE("GPL");
-MODULE_ALIAS("dm-snapshot-origin");
-MODULE_ALIAS("dm-snapshot-merge");
diff --git a/drivers/md/dm-stripe.c b/drivers/md/dm-stripe.c
index aaecefa..c89cde8 100644
--- a/drivers/md/dm-stripe.c
+++ b/drivers/md/dm-stripe.c
@@ -312,8 +312,8 @@ static int stripe_map(struct dm_target *ti, struct bio *bio)
*
*/
-static void stripe_status(struct dm_target *ti, status_type_t type,
- unsigned status_flags, char *result, unsigned maxlen)
+static int stripe_status(struct dm_target *ti, status_type_t type,
+ unsigned status_flags, char *result, unsigned maxlen)
{
struct stripe_c *sc = (struct stripe_c *) ti->private;
char buffer[sc->stripes + 1];
@@ -340,6 +340,7 @@ static void stripe_status(struct dm_target *ti, status_type_t type,
(unsigned long long)sc->stripe[i].physical_start);
break;
}
+ return 0;
}
static int stripe_end_io(struct dm_target *ti, struct bio *bio, int error)
@@ -427,7 +428,7 @@ static int stripe_merge(struct dm_target *ti, struct bvec_merge_data *bvm,
static struct target_type stripe_target = {
.name = "striped",
- .version = {1, 5, 1},
+ .version = {1, 5, 0},
.module = THIS_MODULE,
.ctr = stripe_ctr,
.dtr = stripe_dtr,
diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c
index 2d3a2af..5409607 100644
--- a/drivers/md/dm-thin.c
+++ b/drivers/md/dm-thin.c
@@ -2299,8 +2299,8 @@ static void emit_flags(struct pool_features *pf, char *result,
* <transaction id> <used metadata sectors>/<total metadata sectors>
* <used data sectors>/<total data sectors> <held metadata root>
*/
-static void pool_status(struct dm_target *ti, status_type_t type,
- unsigned status_flags, char *result, unsigned maxlen)
+static int pool_status(struct dm_target *ti, status_type_t type,
+ unsigned status_flags, char *result, unsigned maxlen)
{
int r;
unsigned sz = 0;
@@ -2326,41 +2326,32 @@ static void pool_status(struct dm_target *ti, status_type_t type,
if (!(status_flags & DM_STATUS_NOFLUSH_FLAG) && !dm_suspended(ti))
(void) commit_or_fallback(pool);
- r = dm_pool_get_metadata_transaction_id(pool->pmd, &transaction_id);
- if (r) {
- DMERR("dm_pool_get_metadata_transaction_id returned %d", r);
- goto err;
- }
+ r = dm_pool_get_metadata_transaction_id(pool->pmd,
+ &transaction_id);
+ if (r)
+ return r;
- r = dm_pool_get_free_metadata_block_count(pool->pmd, &nr_free_blocks_metadata);
- if (r) {
- DMERR("dm_pool_get_free_metadata_block_count returned %d", r);
- goto err;
- }
+ r = dm_pool_get_free_metadata_block_count(pool->pmd,
+ &nr_free_blocks_metadata);
+ if (r)
+ return r;
r = dm_pool_get_metadata_dev_size(pool->pmd, &nr_blocks_metadata);
- if (r) {
- DMERR("dm_pool_get_metadata_dev_size returned %d", r);
- goto err;
- }
+ if (r)
+ return r;
- r = dm_pool_get_free_block_count(pool->pmd, &nr_free_blocks_data);
- if (r) {
- DMERR("dm_pool_get_free_block_count returned %d", r);
- goto err;
- }
+ r = dm_pool_get_free_block_count(pool->pmd,
+ &nr_free_blocks_data);
+ if (r)
+ return r;
r = dm_pool_get_data_dev_size(pool->pmd, &nr_blocks_data);
- if (r) {
- DMERR("dm_pool_get_data_dev_size returned %d", r);
- goto err;
- }
+ if (r)
+ return r;
r = dm_pool_get_metadata_snap(pool->pmd, &held_root);
- if (r) {
- DMERR("dm_pool_get_metadata_snap returned %d", r);
- goto err;
- }
+ if (r)
+ return r;
DMEMIT("%llu %llu/%llu %llu/%llu ",
(unsigned long long)transaction_id,
@@ -2397,10 +2388,8 @@ static void pool_status(struct dm_target *ti, status_type_t type,
emit_flags(&pt->requested_pf, result, sz, maxlen);
break;
}
- return;
-err:
- DMEMIT("Error");
+ return 0;
}
static int pool_iterate_devices(struct dm_target *ti,
@@ -2479,7 +2468,7 @@ static struct target_type pool_target = {
.name = "thin-pool",
.features = DM_TARGET_SINGLETON | DM_TARGET_ALWAYS_WRITEABLE |
DM_TARGET_IMMUTABLE,
- .version = {1, 7, 0},
+ .version = {1, 6, 0},
.module = THIS_MODULE,
.ctr = pool_ctr,
.dtr = pool_dtr,
@@ -2687,8 +2676,8 @@ static void thin_postsuspend(struct dm_target *ti)
/*
* <nr mapped sectors> <highest mapped sector>
*/
-static void thin_status(struct dm_target *ti, status_type_t type,
- unsigned status_flags, char *result, unsigned maxlen)
+static int thin_status(struct dm_target *ti, status_type_t type,
+ unsigned status_flags, char *result, unsigned maxlen)
{
int r;
ssize_t sz = 0;
@@ -2698,7 +2687,7 @@ static void thin_status(struct dm_target *ti, status_type_t type,
if (get_pool_mode(tc->pool) == PM_FAIL) {
DMEMIT("Fail");
- return;
+ return 0;
}
if (!tc->td)
@@ -2707,16 +2696,12 @@ static void thin_status(struct dm_target *ti, status_type_t type,
switch (type) {
case STATUSTYPE_INFO:
r = dm_thin_get_mapped_count(tc->td, &mapped);
- if (r) {
- DMERR("dm_thin_get_mapped_count returned %d", r);
- goto err;
- }
+ if (r)
+ return r;
r = dm_thin_get_highest_mapped_block(tc->td, &highest);
- if (r < 0) {
- DMERR("dm_thin_get_highest_mapped_block returned %d", r);
- goto err;
- }
+ if (r < 0)
+ return r;
DMEMIT("%llu ", mapped * tc->pool->sectors_per_block);
if (r)
@@ -2736,10 +2721,7 @@ static void thin_status(struct dm_target *ti, status_type_t type,
}
}
- return;
-
-err:
- DMEMIT("Error");
+ return 0;
}
static int thin_iterate_devices(struct dm_target *ti,
@@ -2766,7 +2748,7 @@ static int thin_iterate_devices(struct dm_target *ti,
static struct target_type thin_target = {
.name = "thin",
- .version = {1, 8, 0},
+ .version = {1, 7, 0},
.module = THIS_MODULE,
.ctr = thin_ctr,
.dtr = thin_dtr,
diff --git a/drivers/md/dm-verity.c b/drivers/md/dm-verity.c
index a746f1d..52cde98 100644
--- a/drivers/md/dm-verity.c
+++ b/drivers/md/dm-verity.c
@@ -93,13 +93,6 @@ struct dm_verity_io {
*/
};
-struct dm_verity_prefetch_work {
- struct work_struct work;
- struct dm_verity *v;
- sector_t block;
- unsigned n_blocks;
-};
-
static struct shash_desc *io_hash_desc(struct dm_verity *v, struct dm_verity_io *io)
{
return (struct shash_desc *)(io + 1);
@@ -431,18 +424,15 @@ static void verity_end_io(struct bio *bio, int error)
* The root buffer is not prefetched, it is assumed that it will be cached
* all the time.
*/
-static void verity_prefetch_io(struct work_struct *work)
+static void verity_prefetch_io(struct dm_verity *v, struct dm_verity_io *io)
{
- struct dm_verity_prefetch_work *pw =
- container_of(work, struct dm_verity_prefetch_work, work);
- struct dm_verity *v = pw->v;
int i;
for (i = v->levels - 2; i >= 0; i--) {
sector_t hash_block_start;
sector_t hash_block_end;
- verity_hash_at_level(v, pw->block, i, &hash_block_start, NULL);
- verity_hash_at_level(v, pw->block + pw->n_blocks - 1, i, &hash_block_end, NULL);
+ verity_hash_at_level(v, io->block, i, &hash_block_start, NULL);
+ verity_hash_at_level(v, io->block + io->n_blocks - 1, i, &hash_block_end, NULL);
if (!i) {
unsigned cluster = ACCESS_ONCE(dm_verity_prefetch_cluster);
@@ -462,25 +452,6 @@ no_prefetch_cluster:
dm_bufio_prefetch(v->bufio, hash_block_start,
hash_block_end - hash_block_start + 1);
}
-
- kfree(pw);
-}
-
-static void verity_submit_prefetch(struct dm_verity *v, struct dm_verity_io *io)
-{
- struct dm_verity_prefetch_work *pw;
-
- pw = kmalloc(sizeof(struct dm_verity_prefetch_work),
- GFP_NOIO | __GFP_NORETRY | __GFP_NOMEMALLOC | __GFP_NOWARN);
-
- if (!pw)
- return;
-
- INIT_WORK(&pw->work, verity_prefetch_io);
- pw->v = v;
- pw->block = io->block;
- pw->n_blocks = io->n_blocks;
- queue_work(v->verify_wq, &pw->work);
}
/*
@@ -527,7 +498,7 @@ static int verity_map(struct dm_target *ti, struct bio *bio)
memcpy(io->io_vec, bio_iovec(bio),
io->io_vec_size * sizeof(struct bio_vec));
- verity_submit_prefetch(v, io);
+ verity_prefetch_io(v, io);
generic_make_request(bio);
@@ -537,8 +508,8 @@ static int verity_map(struct dm_target *ti, struct bio *bio)
/*
* Status: V (valid) or C (corruption found)
*/
-static void verity_status(struct dm_target *ti, status_type_t type,
- unsigned status_flags, char *result, unsigned maxlen)
+static int verity_status(struct dm_target *ti, status_type_t type,
+ unsigned status_flags, char *result, unsigned maxlen)
{
struct dm_verity *v = ti->private;
unsigned sz = 0;
@@ -569,6 +540,8 @@ static void verity_status(struct dm_target *ti, status_type_t type,
DMEMIT("%02x", v->salt[x]);
break;
}
+
+ return 0;
}
static int verity_ioctl(struct dm_target *ti, unsigned cmd,
@@ -887,7 +860,7 @@ bad:
static struct target_type verity_target = {
.name = "verity",
- .version = {1, 2, 0},
+ .version = {1, 1, 0},
.module = THIS_MODULE,
.ctr = verity_ctr,
.dtr = verity_dtr,
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index 0e1699e..314a0e2 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -1677,14 +1677,14 @@ static void dm_request_fn(struct request_queue *q)
if (map_request(ti, clone, md))
goto requeued;
- BUG_ON_NONRT(!irqs_disabled());
+ BUG_ON(!irqs_disabled());
spin_lock(q->queue_lock);
}
goto out;
requeued:
- BUG_ON_NONRT(!irqs_disabled());
+ BUG_ON(!irqs_disabled());
spin_lock(q->queue_lock);
delay_and_out:
@@ -1973,27 +1973,15 @@ static void __bind_mempools(struct mapped_device *md, struct dm_table *t)
{
struct dm_md_mempools *p = dm_table_get_md_mempools(t);
- if (md->io_pool && md->bs) {
- /* The md already has necessary mempools. */
- if (dm_table_get_type(t) == DM_TYPE_BIO_BASED) {
- /*
- * Reload bioset because front_pad may have changed
- * because a different table was loaded.
- */
- bioset_free(md->bs);
- md->bs = p->bs;
- p->bs = NULL;
- } else if (dm_table_get_type(t) == DM_TYPE_REQUEST_BASED) {
- BUG_ON(!md->tio_pool);
- /*
- * There's no need to reload with request-based dm
- * because the size of front_pad doesn't change.
- * Note for future: If you are to reload bioset,
- * prep-ed requests in the queue may refer
- * to bio from the old bioset, so you must walk
- * through the queue to unprep.
- */
- }
+ if (md->io_pool && (md->tio_pool || dm_table_get_type(t) == DM_TYPE_BIO_BASED) && md->bs) {
+ /*
+ * The md already has necessary mempools. Reload just the
+ * bioset because front_pad may have changed because
+ * a different table was loaded.
+ */
+ bioset_free(md->bs);
+ md->bs = p->bs;
+ p->bs = NULL;
goto out;
}
@@ -2433,7 +2421,7 @@ static void dm_queue_flush(struct mapped_device *md)
*/
struct dm_table *dm_swap_table(struct mapped_device *md, struct dm_table *table)
{
- struct dm_table *live_map = NULL, *map = ERR_PTR(-EINVAL);
+ struct dm_table *live_map, *map = ERR_PTR(-EINVAL);
struct queue_limits limits;
int r;
@@ -2456,12 +2444,10 @@ struct dm_table *dm_swap_table(struct mapped_device *md, struct dm_table *table)
dm_table_put(live_map);
}
- if (!live_map) {
- r = dm_calculate_queue_limits(table, &limits);
- if (r) {
- map = ERR_PTR(r);
- goto out;
- }
+ r = dm_calculate_queue_limits(table, &limits);
+ if (r) {
+ map = ERR_PTR(r);
+ goto out;
}
map = __bind(md, table, &limits);
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 0411bde..3db3d1b 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -307,10 +307,6 @@ static void md_make_request(struct request_queue *q, struct bio *bio)
bio_io_error(bio);
return;
}
- if (mddev->ro == 1 && unlikely(rw == WRITE)) {
- bio_endio(bio, bio_sectors(bio) == 0 ? 0 : -EROFS);
- return;
- }
smp_rmb(); /* Ensure implications of 'active' are visible */
rcu_read_lock();
if (mddev->suspended) {
@@ -1564,8 +1560,8 @@ static int super_1_load(struct md_rdev *rdev, struct md_rdev *refdev, int minor_
sector, count, 1) == 0)
return -EINVAL;
}
- } else if (sb->bblog_offset != 0)
- rdev->badblocks.shift = 0;
+ } else if (sb->bblog_offset == 0)
+ rdev->badblocks.shift = -1;
if (!refdev) {
ret = 1;
@@ -2998,9 +2994,6 @@ rdev_size_store(struct md_rdev *rdev, const char *buf, size_t len)
} else if (!sectors)
sectors = (i_size_read(rdev->bdev->bd_inode) >> 9) -
rdev->data_offset;
- if (!my_mddev->pers->resize)
- /* Cannot change size for RAID0 or Linear etc */
- return -EINVAL;
}
if (sectors < my_mddev->dev_sectors)
return -EINVAL; /* component must fit device */
@@ -3221,7 +3214,7 @@ int md_rdev_init(struct md_rdev *rdev)
* be used - I wonder if that matters
*/
rdev->badblocks.count = 0;
- rdev->badblocks.shift = -1; /* disabled until explicitly enabled */
+ rdev->badblocks.shift = 0;
rdev->badblocks.page = kmalloc(PAGE_SIZE, GFP_KERNEL);
seqlock_init(&rdev->badblocks.lock);
if (rdev->badblocks.page == NULL)
@@ -3293,6 +3286,9 @@ static struct md_rdev *md_import_device(dev_t newdev, int super_format, int supe
goto abort_free;
}
}
+ if (super_format == -1)
+ /* hot-add for 0.90, or non-persistent: so no badblocks */
+ rdev->badblocks.shift = -1;
return rdev;
diff --git a/drivers/md/persistent-data/dm-btree-remove.c b/drivers/md/persistent-data/dm-btree-remove.c
index b88757c..c4f2813 100644
--- a/drivers/md/persistent-data/dm-btree-remove.c
+++ b/drivers/md/persistent-data/dm-btree-remove.c
@@ -139,8 +139,15 @@ struct child {
struct btree_node *n;
};
-static int init_child(struct dm_btree_info *info, struct dm_btree_value_type *vt,
- struct btree_node *parent,
+static struct dm_btree_value_type le64_type = {
+ .context = NULL,
+ .size = sizeof(__le64),
+ .inc = NULL,
+ .dec = NULL,
+ .equal = NULL
+};
+
+static int init_child(struct dm_btree_info *info, struct btree_node *parent,
unsigned index, struct child *result)
{
int r, inc;
@@ -157,7 +164,7 @@ static int init_child(struct dm_btree_info *info, struct dm_btree_value_type *vt
result->n = dm_block_data(result->block);
if (inc)
- inc_children(info->tm, result->n, vt);
+ inc_children(info->tm, result->n, &le64_type);
*((__le64 *) value_ptr(parent, index)) =
cpu_to_le64(dm_block_location(result->block));
@@ -229,7 +236,7 @@ static void __rebalance2(struct dm_btree_info *info, struct btree_node *parent,
}
static int rebalance2(struct shadow_spine *s, struct dm_btree_info *info,
- struct dm_btree_value_type *vt, unsigned left_index)
+ unsigned left_index)
{
int r;
struct btree_node *parent;
@@ -237,11 +244,11 @@ static int rebalance2(struct shadow_spine *s, struct dm_btree_info *info,
parent = dm_block_data(shadow_current(s));
- r = init_child(info, vt, parent, left_index, &left);
+ r = init_child(info, parent, left_index, &left);
if (r)
return r;
- r = init_child(info, vt, parent, left_index + 1, &right);
+ r = init_child(info, parent, left_index + 1, &right);
if (r) {
exit_child(info, &left);
return r;
@@ -361,7 +368,7 @@ static void __rebalance3(struct dm_btree_info *info, struct btree_node *parent,
}
static int rebalance3(struct shadow_spine *s, struct dm_btree_info *info,
- struct dm_btree_value_type *vt, unsigned left_index)
+ unsigned left_index)
{
int r;
struct btree_node *parent = dm_block_data(shadow_current(s));
@@ -370,17 +377,17 @@ static int rebalance3(struct shadow_spine *s, struct dm_btree_info *info,
/*
* FIXME: fill out an array?
*/
- r = init_child(info, vt, parent, left_index, &left);
+ r = init_child(info, parent, left_index, &left);
if (r)
return r;
- r = init_child(info, vt, parent, left_index + 1, &center);
+ r = init_child(info, parent, left_index + 1, &center);
if (r) {
exit_child(info, &left);
return r;
}
- r = init_child(info, vt, parent, left_index + 2, &right);
+ r = init_child(info, parent, left_index + 2, &right);
if (r) {
exit_child(info, &left);
exit_child(info, &center);
@@ -427,8 +434,7 @@ static int get_nr_entries(struct dm_transaction_manager *tm,
}
static int rebalance_children(struct shadow_spine *s,
- struct dm_btree_info *info,
- struct dm_btree_value_type *vt, uint64_t key)
+ struct dm_btree_info *info, uint64_t key)
{
int i, r, has_left_sibling, has_right_sibling;
uint32_t child_entries;
@@ -466,13 +472,13 @@ static int rebalance_children(struct shadow_spine *s,
has_right_sibling = i < (le32_to_cpu(n->header.nr_entries) - 1);
if (!has_left_sibling)
- r = rebalance2(s, info, vt, i);
+ r = rebalance2(s, info, i);
else if (!has_right_sibling)
- r = rebalance2(s, info, vt, i - 1);
+ r = rebalance2(s, info, i - 1);
else
- r = rebalance3(s, info, vt, i - 1);
+ r = rebalance3(s, info, i - 1);
return r;
}
@@ -523,7 +529,7 @@ static int remove_raw(struct shadow_spine *s, struct dm_btree_info *info,
if (le32_to_cpu(n->header.flags) & LEAF_NODE)
return do_leaf(n, key, index);
- r = rebalance_children(s, info, vt, key);
+ r = rebalance_children(s, info, key);
if (r)
break;
@@ -544,14 +550,6 @@ static int remove_raw(struct shadow_spine *s, struct dm_btree_info *info,
return r;
}
-static struct dm_btree_value_type le64_type = {
- .context = NULL,
- .size = sizeof(__le64),
- .inc = NULL,
- .dec = NULL,
- .equal = NULL
-};
-
int dm_btree_remove(struct dm_btree_info *info, dm_block_t root,
uint64_t *keys, dm_block_t *new_root)
{
diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c
index d9babda..24b3597 100644
--- a/drivers/md/raid0.c
+++ b/drivers/md/raid0.c
@@ -289,7 +289,7 @@ abort:
kfree(conf->strip_zone);
kfree(conf->devlist);
kfree(conf);
- *private_conf = ERR_PTR(err);
+ *private_conf = NULL;
return err;
}
@@ -411,8 +411,7 @@ static sector_t raid0_size(struct mddev *mddev, sector_t sectors, int raid_disks
"%s does not support generic reshape\n", __func__);
rdev_for_each(rdev, mddev)
- array_sectors += (rdev->sectors &
- ~(sector_t)(mddev->chunk_sectors-1));
+ array_sectors += rdev->sectors;
return array_sectors;
}
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 6af167f..d5bddfc 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -967,7 +967,6 @@ static void raid1_unplug(struct blk_plug_cb *cb, bool from_schedule)
bio_list_merge(&conf->pending_bio_list, &plug->pending);
conf->pending_count += plug->pending_cnt;
spin_unlock_irq(&conf->device_lock);
- wake_up(&conf->wait_barrier);
md_wakeup_thread(mddev->thread);
kfree(plug);
return;
@@ -981,12 +980,7 @@ static void raid1_unplug(struct blk_plug_cb *cb, bool from_schedule)
while (bio) { /* submit pending writes */
struct bio *next = bio->bi_next;
bio->bi_next = NULL;
- if (unlikely((bio->bi_rw & REQ_DISCARD) &&
- !blk_queue_discard(bdev_get_queue(bio->bi_bdev))))
- /* Just ignore it */
- bio_endio(bio, 0);
- else
- generic_make_request(bio);
+ generic_make_request(bio);
bio = next;
}
kfree(plug);
@@ -1006,7 +1000,6 @@ static void make_request(struct mddev *mddev, struct bio * bio)
const unsigned long do_flush_fua = (bio->bi_rw & (REQ_FLUSH | REQ_FUA));
const unsigned long do_discard = (bio->bi_rw
& (REQ_DISCARD | REQ_SECURE));
- const unsigned long do_same = (bio->bi_rw & REQ_WRITE_SAME);
struct md_rdev *blocked_rdev;
struct blk_plug_cb *cb;
struct raid1_plug_cb *plug = NULL;
@@ -1308,8 +1301,7 @@ read_again:
conf->mirrors[i].rdev->data_offset);
mbio->bi_bdev = conf->mirrors[i].rdev->bdev;
mbio->bi_end_io = raid1_end_write_request;
- mbio->bi_rw =
- WRITE | do_flush_fua | do_sync | do_discard | do_same;
+ mbio->bi_rw = WRITE | do_flush_fua | do_sync | do_discard;
mbio->bi_private = r1_bio;
atomic_inc(&r1_bio->remaining);
@@ -2826,9 +2818,6 @@ static int run(struct mddev *mddev)
if (IS_ERR(conf))
return PTR_ERR(conf);
- if (mddev->queue)
- blk_queue_max_write_same_sectors(mddev->queue,
- mddev->chunk_sectors);
rdev_for_each(rdev, mddev) {
if (!mddev->gendisk)
continue;
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 61ab219..64d4824 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -1073,7 +1073,6 @@ static void raid10_unplug(struct blk_plug_cb *cb, bool from_schedule)
bio_list_merge(&conf->pending_bio_list, &plug->pending);
conf->pending_count += plug->pending_cnt;
spin_unlock_irq(&conf->device_lock);
- wake_up(&conf->wait_barrier);
md_wakeup_thread(mddev->thread);
kfree(plug);
return;
@@ -1087,12 +1086,7 @@ static void raid10_unplug(struct blk_plug_cb *cb, bool from_schedule)
while (bio) { /* submit pending writes */
struct bio *next = bio->bi_next;
bio->bi_next = NULL;
- if (unlikely((bio->bi_rw & REQ_DISCARD) &&
- !blk_queue_discard(bdev_get_queue(bio->bi_bdev))))
- /* Just ignore it */
- bio_endio(bio, 0);
- else
- generic_make_request(bio);
+ generic_make_request(bio);
bio = next;
}
kfree(plug);
@@ -1111,7 +1105,6 @@ static void make_request(struct mddev *mddev, struct bio * bio)
const unsigned long do_fua = (bio->bi_rw & REQ_FUA);
const unsigned long do_discard = (bio->bi_rw
& (REQ_DISCARD | REQ_SECURE));
- const unsigned long do_same = (bio->bi_rw & REQ_WRITE_SAME);
unsigned long flags;
struct md_rdev *blocked_rdev;
struct blk_plug_cb *cb;
@@ -1467,8 +1460,7 @@ retry_write:
rdev));
mbio->bi_bdev = rdev->bdev;
mbio->bi_end_io = raid10_end_write_request;
- mbio->bi_rw =
- WRITE | do_sync | do_fua | do_discard | do_same;
+ mbio->bi_rw = WRITE | do_sync | do_fua | do_discard;
mbio->bi_private = r10_bio;
atomic_inc(&r10_bio->remaining);
@@ -1510,8 +1502,7 @@ retry_write:
r10_bio, rdev));
mbio->bi_bdev = rdev->bdev;
mbio->bi_end_io = raid10_end_write_request;
- mbio->bi_rw =
- WRITE | do_sync | do_fua | do_discard | do_same;
+ mbio->bi_rw = WRITE | do_sync | do_fua | do_discard;
mbio->bi_private = r10_bio;
atomic_inc(&r10_bio->remaining);
@@ -3578,8 +3569,6 @@ static int run(struct mddev *mddev)
if (mddev->queue) {
blk_queue_max_discard_sectors(mddev->queue,
mddev->chunk_sectors);
- blk_queue_max_write_same_sectors(mddev->queue,
- mddev->chunk_sectors);
blk_queue_io_min(mddev->queue, chunk_size);
if (conf->geo.raid_disks % conf->geo.near_copies)
blk_queue_io_opt(mddev->queue, chunk_size * conf->geo.raid_disks);
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 0089cb1..19d77a0 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -674,11 +674,9 @@ static void ops_run_io(struct stripe_head *sh, struct stripe_head_state *s)
bi->bi_next = NULL;
if (rrdev)
set_bit(R5_DOUBLE_LOCKED, &sh->dev[i].flags);
-
- if (conf->mddev->gendisk)
- trace_block_bio_remap(bdev_get_queue(bi->bi_bdev),
- bi, disk_devt(conf->mddev->gendisk),
- sh->dev[i].sector);
+ trace_block_bio_remap(bdev_get_queue(bi->bi_bdev),
+ bi, disk_devt(conf->mddev->gendisk),
+ sh->dev[i].sector);
generic_make_request(bi);
}
if (rrdev) {
@@ -706,10 +704,9 @@ static void ops_run_io(struct stripe_head *sh, struct stripe_head_state *s)
rbi->bi_io_vec[0].bv_offset = 0;
rbi->bi_size = STRIPE_SIZE;
rbi->bi_next = NULL;
- if (conf->mddev->gendisk)
- trace_block_bio_remap(bdev_get_queue(rbi->bi_bdev),
- rbi, disk_devt(conf->mddev->gendisk),
- sh->dev[i].sector);
+ trace_block_bio_remap(bdev_get_queue(rbi->bi_bdev),
+ rbi, disk_devt(conf->mddev->gendisk),
+ sh->dev[i].sector);
generic_make_request(rbi);
}
if (!rdev && !rrdev) {
@@ -1418,9 +1415,8 @@ static void __raid_run_ops(struct stripe_head *sh, unsigned long ops_request)
struct raid5_percpu *percpu;
unsigned long cpu;
- cpu = get_cpu_light();
+ cpu = get_cpu();
percpu = per_cpu_ptr(conf->percpu, cpu);
- spin_lock(&percpu->lock);
if (test_bit(STRIPE_OP_BIOFILL, &ops_request)) {
ops_run_biofill(sh);
overlap_clear++;
@@ -1472,8 +1468,7 @@ static void __raid_run_ops(struct stripe_head *sh, unsigned long ops_request)
if (test_and_clear_bit(R5_Overlap, &dev->flags))
wake_up(&sh->raid_conf->wait_for_overlap);
}
- spin_unlock(&percpu->lock);
- put_cpu_light();
+ put_cpu();
}
#ifdef CONFIG_MULTICORE_RAID456
@@ -2324,26 +2319,11 @@ schedule_reconstruction(struct stripe_head *sh, struct stripe_head_state *s,
int level = conf->level;
if (rcw) {
-
- for (i = disks; i--; ) {
- struct r5dev *dev = &sh->dev[i];
-
- if (dev->towrite) {
- set_bit(R5_LOCKED, &dev->flags);
- set_bit(R5_Wantdrain, &dev->flags);
- if (!expand)
- clear_bit(R5_UPTODATE, &dev->flags);
- s->locked++;
- }
- }
/* if we are not expanding this is a proper write request, and
* there will be bios with new data to be drained into the
* stripe cache
*/
if (!expand) {
- if (!s->locked)
- /* False alarm, nothing to do */
- return;
sh->reconstruct_state = reconstruct_state_drain_run;
set_bit(STRIPE_OP_BIODRAIN, &s->ops_request);
} else
@@ -2351,6 +2331,17 @@ schedule_reconstruction(struct stripe_head *sh, struct stripe_head_state *s,
set_bit(STRIPE_OP_RECONSTRUCT, &s->ops_request);
+ for (i = disks; i--; ) {
+ struct r5dev *dev = &sh->dev[i];
+
+ if (dev->towrite) {
+ set_bit(R5_LOCKED, &dev->flags);
+ set_bit(R5_Wantdrain, &dev->flags);
+ if (!expand)
+ clear_bit(R5_UPTODATE, &dev->flags);
+ s->locked++;
+ }
+ }
if (s->locked + conf->max_degraded == disks)
if (!test_and_set_bit(STRIPE_FULL_WRITE, &sh->state))
atomic_inc(&conf->pending_full_writes);
@@ -2359,6 +2350,11 @@ schedule_reconstruction(struct stripe_head *sh, struct stripe_head_state *s,
BUG_ON(!(test_bit(R5_UPTODATE, &sh->dev[pd_idx].flags) ||
test_bit(R5_Wantcompute, &sh->dev[pd_idx].flags)));
+ sh->reconstruct_state = reconstruct_state_prexor_drain_run;
+ set_bit(STRIPE_OP_PREXOR, &s->ops_request);
+ set_bit(STRIPE_OP_BIODRAIN, &s->ops_request);
+ set_bit(STRIPE_OP_RECONSTRUCT, &s->ops_request);
+
for (i = disks; i--; ) {
struct r5dev *dev = &sh->dev[i];
if (i == pd_idx)
@@ -2373,13 +2369,6 @@ schedule_reconstruction(struct stripe_head *sh, struct stripe_head_state *s,
s->locked++;
}
}
- if (!s->locked)
- /* False alarm - nothing to do */
- return;
- sh->reconstruct_state = reconstruct_state_prexor_drain_run;
- set_bit(STRIPE_OP_PREXOR, &s->ops_request);
- set_bit(STRIPE_OP_BIODRAIN, &s->ops_request);
- set_bit(STRIPE_OP_RECONSTRUCT, &s->ops_request);
}
/* keep the parity disk(s) locked while asynchronous operations
@@ -2614,8 +2603,6 @@ handle_failed_sync(struct r5conf *conf, struct stripe_head *sh,
int i;
clear_bit(STRIPE_SYNCING, &sh->state);
- if (test_and_clear_bit(R5_Overlap, &sh->dev[sh->pd_idx].flags))
- wake_up(&conf->wait_for_overlap);
s->syncing = 0;
s->replacing = 0;
/* There is nothing more to do for sync/check/repair.
@@ -2789,7 +2776,6 @@ static void handle_stripe_clean_event(struct r5conf *conf,
{
int i;
struct r5dev *dev;
- int discard_pending = 0;
for (i = disks; i--; )
if (sh->dev[i].written) {
@@ -2818,23 +2804,9 @@ static void handle_stripe_clean_event(struct r5conf *conf,
STRIPE_SECTORS,
!test_bit(STRIPE_DEGRADED, &sh->state),
0);
- } else if (test_bit(R5_Discard, &dev->flags))
- discard_pending = 1;
- }
- if (!discard_pending &&
- test_bit(R5_Discard, &sh->dev[sh->pd_idx].flags)) {
- clear_bit(R5_Discard, &sh->dev[sh->pd_idx].flags);
- clear_bit(R5_UPTODATE, &sh->dev[sh->pd_idx].flags);
- if (sh->qd_idx >= 0) {
- clear_bit(R5_Discard, &sh->dev[sh->qd_idx].flags);
- clear_bit(R5_UPTODATE, &sh->dev[sh->qd_idx].flags);
- }
- /* now that discard is done we can proceed with any sync */
- clear_bit(STRIPE_DISCARD, &sh->state);
- if (test_bit(STRIPE_SYNC_REQUESTED, &sh->state))
- set_bit(STRIPE_HANDLE, &sh->state);
-
- }
+ }
+ } else if (test_bit(R5_Discard, &sh->dev[i].flags))
+ clear_bit(R5_Discard, &sh->dev[i].flags);
if (test_and_clear_bit(STRIPE_FULL_WRITE, &sh->state))
if (atomic_dec_and_test(&conf->pending_full_writes))
@@ -2893,10 +2865,8 @@ static void handle_stripe_dirtying(struct r5conf *conf,
set_bit(STRIPE_HANDLE, &sh->state);
if (rmw < rcw && rmw > 0) {
/* prefer read-modify-write, but need to get some data */
- if (conf->mddev->queue)
- blk_add_trace_msg(conf->mddev->queue,
- "raid5 rmw %llu %d",
- (unsigned long long)sh->sector, rmw);
+ blk_add_trace_msg(conf->mddev->queue, "raid5 rmw %llu %d",
+ (unsigned long long)sh->sector, rmw);
for (i = disks; i--; ) {
struct r5dev *dev = &sh->dev[i];
if ((dev->towrite || i == sh->pd_idx) &&
@@ -2946,7 +2916,7 @@ static void handle_stripe_dirtying(struct r5conf *conf,
}
}
}
- if (rcw && conf->mddev->queue)
+ if (rcw)
blk_add_trace_msg(conf->mddev->queue, "raid5 rcw %llu %d %d %d",
(unsigned long long)sh->sector,
rcw, qread, test_bit(STRIPE_DELAYED, &sh->state));
@@ -3486,15 +3456,9 @@ static void handle_stripe(struct stripe_head *sh)
return;
}
- if (test_bit(STRIPE_SYNC_REQUESTED, &sh->state)) {
- spin_lock(&sh->stripe_lock);
- /* Cannot process 'sync' concurrently with 'discard' */
- if (!test_bit(STRIPE_DISCARD, &sh->state) &&
- test_and_clear_bit(STRIPE_SYNC_REQUESTED, &sh->state)) {
- set_bit(STRIPE_SYNCING, &sh->state);
- clear_bit(STRIPE_INSYNC, &sh->state);
- }
- spin_unlock(&sh->stripe_lock);
+ if (test_and_clear_bit(STRIPE_SYNC_REQUESTED, &sh->state)) {
+ set_bit(STRIPE_SYNCING, &sh->state);
+ clear_bit(STRIPE_INSYNC, &sh->state);
}
clear_bit(STRIPE_DELAYED, &sh->state);
@@ -3654,8 +3618,6 @@ static void handle_stripe(struct stripe_head *sh)
test_bit(STRIPE_INSYNC, &sh->state)) {
md_done_sync(conf->mddev, STRIPE_SECTORS, 1);
clear_bit(STRIPE_SYNCING, &sh->state);
- if (test_and_clear_bit(R5_Overlap, &sh->dev[sh->pd_idx].flags))
- wake_up(&conf->wait_for_overlap);
}
/* If the failed drives are just a ReadError, then we might need
@@ -4061,10 +4023,9 @@ static int chunk_aligned_read(struct mddev *mddev, struct bio * raid_bio)
atomic_inc(&conf->active_aligned_reads);
spin_unlock_irq(&conf->device_lock);
- if (mddev->gendisk)
- trace_block_bio_remap(bdev_get_queue(align_bi->bi_bdev),
- align_bi, disk_devt(mddev->gendisk),
- raid_bio->bi_sector);
+ trace_block_bio_remap(bdev_get_queue(align_bi->bi_bdev),
+ align_bi, disk_devt(mddev->gendisk),
+ raid_bio->bi_sector);
generic_make_request(align_bi);
return 1;
} else {
@@ -4158,8 +4119,7 @@ static void raid5_unplug(struct blk_plug_cb *blk_cb, bool from_schedule)
}
spin_unlock_irq(&conf->device_lock);
}
- if (mddev->queue)
- trace_block_unplug(mddev->queue, cnt, !from_schedule);
+ trace_block_unplug(mddev->queue, cnt, !from_schedule);
kfree(cb);
}
@@ -4222,13 +4182,6 @@ static void make_discard_request(struct mddev *mddev, struct bio *bi)
sh = get_active_stripe(conf, logical_sector, 0, 0, 0);
prepare_to_wait(&conf->wait_for_overlap, &w,
TASK_UNINTERRUPTIBLE);
- set_bit(R5_Overlap, &sh->dev[sh->pd_idx].flags);
- if (test_bit(STRIPE_SYNCING, &sh->state)) {
- release_stripe(sh);
- schedule();
- goto again;
- }
- clear_bit(R5_Overlap, &sh->dev[sh->pd_idx].flags);
spin_lock_irq(&sh->stripe_lock);
for (d = 0; d < conf->raid_disks; d++) {
if (d == sh->pd_idx || d == sh->qd_idx)
@@ -4241,7 +4194,6 @@ static void make_discard_request(struct mddev *mddev, struct bio *bi)
goto again;
}
}
- set_bit(STRIPE_DISCARD, &sh->state);
finish_wait(&conf->wait_for_overlap, &w);
for (d = 0; d < conf->raid_disks; d++) {
if (d == sh->pd_idx || d == sh->qd_idx)
@@ -5141,7 +5093,6 @@ static int raid5_alloc_percpu(struct r5conf *conf)
break;
}
per_cpu_ptr(conf->percpu, cpu)->scribble = scribble;
- spin_lock_init(&per_cpu_ptr(conf->percpu, cpu)->lock);
}
#ifdef CONFIG_HOTPLUG_CPU
conf->cpu_notify.notifier_call = raid456_cpu_notify;
diff --git a/drivers/md/raid5.h b/drivers/md/raid5.h
index 8a57647..18b2c4a 100644
--- a/drivers/md/raid5.h
+++ b/drivers/md/raid5.h
@@ -323,7 +323,6 @@ enum {
STRIPE_COMPUTE_RUN,
STRIPE_OPS_REQ_PENDING,
STRIPE_ON_UNPLUG_LIST,
- STRIPE_DISCARD,
};
/*
@@ -429,7 +428,6 @@ struct r5conf {
int recovery_disabled;
/* per cpu variables */
struct raid5_percpu {
- spinlock_t lock; /* Protection for -RT */
struct page *spare_page; /* Used when checking P/Q in raid6 */
void *scribble; /* space for constructing buffer
* lists and performing address
diff --git a/drivers/media/pci/bt8xx/bttv-driver.c b/drivers/media/pci/bt8xx/bttv-driver.c
index dd53210..45e5d06 100644
--- a/drivers/media/pci/bt8xx/bttv-driver.c
+++ b/drivers/media/pci/bt8xx/bttv-driver.c
@@ -250,19 +250,17 @@ static u8 SRAM_Table[][60] =
vdelay start of active video in 2 * field lines relative to
trailing edge of /VRESET pulse (VDELAY register).
sheight height of active video in 2 * field lines.
- extraheight Added to sheight for cropcap.bounds.height only
videostart0 ITU-R frame line number of the line corresponding
to vdelay in the first field. */
#define CROPCAP(minhdelayx1, hdelayx1, swidth, totalwidth, sqwidth, \
- vdelay, sheight, extraheight, videostart0) \
+ vdelay, sheight, videostart0) \
.cropcap.bounds.left = minhdelayx1, \
/* * 2 because vertically we count field lines times two, */ \
/* e.g. 23 * 2 to 23 * 2 + 576 in PAL-BGHI defrect. */ \
.cropcap.bounds.top = (videostart0) * 2 - (vdelay) + MIN_VDELAY, \
/* 4 is a safety margin at the end of the line. */ \
.cropcap.bounds.width = (totalwidth) - (minhdelayx1) - 4, \
- .cropcap.bounds.height = (sheight) + (extraheight) + (vdelay) - \
- MIN_VDELAY, \
+ .cropcap.bounds.height = (sheight) + (vdelay) - MIN_VDELAY, \
.cropcap.defrect.left = hdelayx1, \
.cropcap.defrect.top = (videostart0) * 2, \
.cropcap.defrect.width = swidth, \
@@ -303,10 +301,9 @@ const struct bttv_tvnorm bttv_tvnorms[] = {
/* totalwidth */ 1135,
/* sqwidth */ 944,
/* vdelay */ 0x20,
- /* sheight */ 576,
- /* bt878 (and bt848?) can capture another
- line below active video. */
- /* extraheight */ 2,
+ /* bt878 (and bt848?) can capture another
+ line below active video. */
+ /* sheight */ (576 + 2) + 0x20 - 2,
/* videostart0 */ 23)
},{
.v4l2_id = V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_KR,
@@ -333,7 +330,6 @@ const struct bttv_tvnorm bttv_tvnorms[] = {
/* sqwidth */ 780,
/* vdelay */ 0x1a,
/* sheight */ 480,
- /* extraheight */ 0,
/* videostart0 */ 23)
},{
.v4l2_id = V4L2_STD_SECAM,
@@ -359,7 +355,6 @@ const struct bttv_tvnorm bttv_tvnorms[] = {
/* sqwidth */ 944,
/* vdelay */ 0x20,
/* sheight */ 576,
- /* extraheight */ 0,
/* videostart0 */ 23)
},{
.v4l2_id = V4L2_STD_PAL_Nc,
@@ -385,7 +380,6 @@ const struct bttv_tvnorm bttv_tvnorms[] = {
/* sqwidth */ 780,
/* vdelay */ 0x1a,
/* sheight */ 576,
- /* extraheight */ 0,
/* videostart0 */ 23)
},{
.v4l2_id = V4L2_STD_PAL_M,
@@ -411,7 +405,6 @@ const struct bttv_tvnorm bttv_tvnorms[] = {
/* sqwidth */ 780,
/* vdelay */ 0x1a,
/* sheight */ 480,
- /* extraheight */ 0,
/* videostart0 */ 23)
},{
.v4l2_id = V4L2_STD_PAL_N,
@@ -437,7 +430,6 @@ const struct bttv_tvnorm bttv_tvnorms[] = {
/* sqwidth */ 944,
/* vdelay */ 0x20,
/* sheight */ 576,
- /* extraheight */ 0,
/* videostart0 */ 23)
},{
.v4l2_id = V4L2_STD_NTSC_M_JP,
@@ -463,7 +455,6 @@ const struct bttv_tvnorm bttv_tvnorms[] = {
/* sqwidth */ 780,
/* vdelay */ 0x16,
/* sheight */ 480,
- /* extraheight */ 0,
/* videostart0 */ 23)
},{
/* that one hopefully works with the strange timing
@@ -493,7 +484,6 @@ const struct bttv_tvnorm bttv_tvnorms[] = {
/* sqwidth */ 944,
/* vdelay */ 0x1a,
/* sheight */ 480,
- /* extraheight */ 0,
/* videostart0 */ 23)
}
};
diff --git a/drivers/media/pci/cx18/cx18-alsa-main.c b/drivers/media/pci/cx18/cx18-alsa-main.c
index b2c8c34..8e971ff 100644
--- a/drivers/media/pci/cx18/cx18-alsa-main.c
+++ b/drivers/media/pci/cx18/cx18-alsa-main.c
@@ -197,7 +197,7 @@ err_exit:
return ret;
}
-static int cx18_alsa_load(struct cx18 *cx)
+static int __init cx18_alsa_load(struct cx18 *cx)
{
struct v4l2_device *v4l2_dev = &cx->v4l2_dev;
struct cx18_stream *s;
diff --git a/drivers/media/pci/cx18/cx18-alsa-pcm.h b/drivers/media/pci/cx18/cx18-alsa-pcm.h
index e2b2c5b..d26e51f 100644
--- a/drivers/media/pci/cx18/cx18-alsa-pcm.h
+++ b/drivers/media/pci/cx18/cx18-alsa-pcm.h
@@ -20,7 +20,7 @@
* 02111-1307 USA
*/
-int snd_cx18_pcm_create(struct snd_cx18_card *cxsc);
+int __init snd_cx18_pcm_create(struct snd_cx18_card *cxsc);
/* Used by cx18-mailbox to announce the PCM data to the module */
void cx18_alsa_announce_pcm_data(struct snd_cx18_card *card, u8 *pcm_data,
diff --git a/drivers/media/pci/ivtv/ivtv-alsa-main.c b/drivers/media/pci/ivtv/ivtv-alsa-main.c
index e970cfa..4a221c6 100644
--- a/drivers/media/pci/ivtv/ivtv-alsa-main.c
+++ b/drivers/media/pci/ivtv/ivtv-alsa-main.c
@@ -205,7 +205,7 @@ err_exit:
return ret;
}
-static int ivtv_alsa_load(struct ivtv *itv)
+static int __init ivtv_alsa_load(struct ivtv *itv)
{
struct v4l2_device *v4l2_dev = &itv->v4l2_dev;
struct ivtv_stream *s;
diff --git a/drivers/media/pci/ivtv/ivtv-alsa-pcm.h b/drivers/media/pci/ivtv/ivtv-alsa-pcm.h
index 186814e..23dfe0d 100644
--- a/drivers/media/pci/ivtv/ivtv-alsa-pcm.h
+++ b/drivers/media/pci/ivtv/ivtv-alsa-pcm.h
@@ -20,4 +20,4 @@
* 02111-1307 USA
*/
-int snd_ivtv_pcm_create(struct snd_ivtv_card *itvsc);
+int __init snd_ivtv_pcm_create(struct snd_ivtv_card *itvsc);
diff --git a/drivers/media/platform/omap/omap_vout.c b/drivers/media/platform/omap/omap_vout.c
index 8e9a668..35cc526 100644
--- a/drivers/media/platform/omap/omap_vout.c
+++ b/drivers/media/platform/omap/omap_vout.c
@@ -205,21 +205,19 @@ static u32 omap_vout_uservirt_to_phys(u32 virtp)
struct vm_area_struct *vma;
struct mm_struct *mm = current->mm;
- /* For kernel direct-mapped memory, take the easy way */
- if (virtp >= PAGE_OFFSET)
- return virt_to_phys((void *) virtp);
-
- down_read(&current->mm->mmap_sem);
vma = find_vma(mm, virtp);
- if (vma && (vma->vm_flags & VM_IO) && vma->vm_pgoff) {
+ /* For kernel direct-mapped memory, take the easy way */
+ if (virtp >= PAGE_OFFSET) {
+ physp = virt_to_phys((void *) virtp);
+ } else if (vma && (vma->vm_flags & VM_IO) && vma->vm_pgoff) {
/* this will catch, kernel-allocated, mmaped-to-usermode
addresses */
physp = (vma->vm_pgoff << PAGE_SHIFT) + (virtp - vma->vm_start);
- up_read(&current->mm->mmap_sem);
} else {
/* otherwise, use get_user_pages() for general userland pages */
int res, nr_pages = 1;
struct page *pages;
+ down_read(&current->mm->mmap_sem);
res = get_user_pages(current, current->mm, virtp, nr_pages, 1,
0, &pages, NULL);
diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c
index d593bc6..601d1ac1 100644
--- a/drivers/media/rc/rc-main.c
+++ b/drivers/media/rc/rc-main.c
@@ -789,10 +789,8 @@ static ssize_t show_protocols(struct device *device,
} else if (dev->raw) {
enabled = dev->raw->enabled_protocols;
allowed = ir_raw_get_allowed_protocols();
- } else {
- mutex_unlock(&dev->lock);
+ } else
return -ENODEV;
- }
IR_dprintk(1, "allowed - 0x%llx, enabled - 0x%llx\n",
(long long)allowed,
diff --git a/drivers/media/v4l2-core/v4l2-device.c b/drivers/media/v4l2-core/v4l2-device.c
index 98a7f5e..513969f 100644
--- a/drivers/media/v4l2-core/v4l2-device.c
+++ b/drivers/media/v4l2-core/v4l2-device.c
@@ -159,21 +159,31 @@ int v4l2_device_register_subdev(struct v4l2_device *v4l2_dev,
sd->v4l2_dev = v4l2_dev;
if (sd->internal_ops && sd->internal_ops->registered) {
err = sd->internal_ops->registered(sd);
- if (err)
- goto error_module;
+ if (err) {
+ module_put(sd->owner);
+ return err;
+ }
}
/* This just returns 0 if either of the two args is NULL */
err = v4l2_ctrl_add_handler(v4l2_dev->ctrl_handler, sd->ctrl_handler, NULL);
- if (err)
- goto error_unregister;
+ if (err) {
+ if (sd->internal_ops && sd->internal_ops->unregistered)
+ sd->internal_ops->unregistered(sd);
+ module_put(sd->owner);
+ return err;
+ }
#if defined(CONFIG_MEDIA_CONTROLLER)
/* Register the entity. */
if (v4l2_dev->mdev) {
err = media_device_register_entity(v4l2_dev->mdev, entity);
- if (err < 0)
- goto error_unregister;
+ if (err < 0) {
+ if (sd->internal_ops && sd->internal_ops->unregistered)
+ sd->internal_ops->unregistered(sd);
+ module_put(sd->owner);
+ return err;
+ }
}
#endif
@@ -182,14 +192,6 @@ int v4l2_device_register_subdev(struct v4l2_device *v4l2_dev,
spin_unlock(&v4l2_dev->lock);
return 0;
-
-error_unregister:
- if (sd->internal_ops && sd->internal_ops->unregistered)
- sd->internal_ops->unregistered(sd);
-error_module:
- module_put(sd->owner);
- sd->v4l2_dev = NULL;
- return err;
}
EXPORT_SYMBOL_GPL(v4l2_device_register_subdev);
diff --git a/drivers/memstick/host/rtsx_pci_ms.c b/drivers/memstick/host/rtsx_pci_ms.c
index 64a779c..f5ddb82 100644
--- a/drivers/memstick/host/rtsx_pci_ms.c
+++ b/drivers/memstick/host/rtsx_pci_ms.c
@@ -426,9 +426,6 @@ static void rtsx_pci_ms_request(struct memstick_host *msh)
dev_dbg(ms_dev(host), "--> %s\n", __func__);
- if (rtsx_pci_card_exclusive_check(host->pcr, RTSX_MS_CARD))
- return;
-
schedule_work(&host->handle_req);
}
@@ -444,10 +441,6 @@ static int rtsx_pci_ms_set_param(struct memstick_host *msh,
dev_dbg(ms_dev(host), "%s: param = %d, value = %d\n",
__func__, param, value);
- err = rtsx_pci_card_exclusive_check(host->pcr, RTSX_MS_CARD);
- if (err)
- return err;
-
switch (param) {
case MEMSTICK_POWER:
if (value == MEMSTICK_POWER_ON)
diff --git a/drivers/mfd/adp5520.c b/drivers/mfd/adp5520.c
index 6b40e0c..210dd03 100644
--- a/drivers/mfd/adp5520.c
+++ b/drivers/mfd/adp5520.c
@@ -36,7 +36,6 @@ struct adp5520_chip {
struct blocking_notifier_head notifier_list;
int irq;
unsigned long id;
- uint8_t mode;
};
static int __adp5520_read(struct i2c_client *client,
@@ -327,10 +326,7 @@ static int adp5520_suspend(struct device *dev)
struct i2c_client *client = to_i2c_client(dev);
struct adp5520_chip *chip = dev_get_drvdata(&client->dev);
- adp5520_read(chip->dev, ADP5520_MODE_STATUS, &chip->mode);
- /* All other bits are W1C */
- chip->mode &= ADP5520_BL_EN | ADP5520_DIM_EN | ADP5520_nSTNBY;
- adp5520_write(chip->dev, ADP5520_MODE_STATUS, 0);
+ adp5520_clr_bits(chip->dev, ADP5520_MODE_STATUS, ADP5520_nSTNBY);
return 0;
}
@@ -339,7 +335,7 @@ static int adp5520_resume(struct device *dev)
struct i2c_client *client = to_i2c_client(dev);
struct adp5520_chip *chip = dev_get_drvdata(&client->dev);
- adp5520_write(chip->dev, ADP5520_MODE_STATUS, chip->mode);
+ adp5520_set_bits(chip->dev, ADP5520_MODE_STATUS, ADP5520_nSTNBY);
return 0;
}
#endif
diff --git a/drivers/mfd/rtsx_pcr.c b/drivers/mfd/rtsx_pcr.c
index 1e2d120..9fc5700 100644
--- a/drivers/mfd/rtsx_pcr.c
+++ b/drivers/mfd/rtsx_pcr.c
@@ -713,25 +713,6 @@ int rtsx_pci_card_power_off(struct rtsx_pcr *pcr, int card)
}
EXPORT_SYMBOL_GPL(rtsx_pci_card_power_off);
-int rtsx_pci_card_exclusive_check(struct rtsx_pcr *pcr, int card)
-{
- unsigned int cd_mask[] = {
- [RTSX_SD_CARD] = SD_EXIST,
- [RTSX_MS_CARD] = MS_EXIST
- };
-
- if (!pcr->ms_pmos) {
- /* When using single PMOS, accessing card is not permitted
- * if the existing card is not the designated one.
- */
- if (pcr->card_exist & (~cd_mask[card]))
- return -EIO;
- }
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(rtsx_pci_card_exclusive_check);
-
int rtsx_pci_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
{
if (pcr->ops->switch_output_voltage)
@@ -777,7 +758,7 @@ static void rtsx_pci_card_detect(struct work_struct *work)
struct delayed_work *dwork;
struct rtsx_pcr *pcr;
unsigned long flags;
- unsigned int card_detect = 0, card_inserted, card_removed;
+ unsigned int card_detect = 0;
u32 irq_status;
dwork = to_delayed_work(work);
@@ -785,35 +766,25 @@ static void rtsx_pci_card_detect(struct work_struct *work)
dev_dbg(&(pcr->pci->dev), "--> %s\n", __func__);
- mutex_lock(&pcr->pcr_mutex);
spin_lock_irqsave(&pcr->lock, flags);
irq_status = rtsx_pci_readl(pcr, RTSX_BIPR);
dev_dbg(&(pcr->pci->dev), "irq_status: 0x%08x\n", irq_status);
- irq_status &= CARD_EXIST;
- card_inserted = pcr->card_inserted & irq_status;
- card_removed = pcr->card_removed;
- pcr->card_inserted = 0;
- pcr->card_removed = 0;
-
- spin_unlock_irqrestore(&pcr->lock, flags);
-
- if (card_inserted || card_removed) {
+ if (pcr->card_inserted || pcr->card_removed) {
dev_dbg(&(pcr->pci->dev),
"card_inserted: 0x%x, card_removed: 0x%x\n",
- card_inserted, card_removed);
+ pcr->card_inserted, pcr->card_removed);
if (pcr->ops->cd_deglitch)
- card_inserted = pcr->ops->cd_deglitch(pcr);
-
- card_detect = card_inserted | card_removed;
+ pcr->card_inserted = pcr->ops->cd_deglitch(pcr);
- pcr->card_exist |= card_inserted;
- pcr->card_exist &= ~card_removed;
+ card_detect = pcr->card_inserted | pcr->card_removed;
+ pcr->card_inserted = 0;
+ pcr->card_removed = 0;
}
- mutex_unlock(&pcr->pcr_mutex);
+ spin_unlock_irqrestore(&pcr->lock, flags);
if ((card_detect & SD_EXIST) && pcr->slots[RTSX_SD_CARD].card_event)
pcr->slots[RTSX_SD_CARD].card_event(
@@ -865,6 +836,10 @@ static irqreturn_t rtsx_pci_isr(int irq, void *dev_id)
}
}
+ if (pcr->card_inserted || pcr->card_removed)
+ schedule_delayed_work(&pcr->carddet_work,
+ msecs_to_jiffies(200));
+
if (int_reg & (NEED_COMPLETE_INT | DELINK_INT)) {
if (int_reg & (TRANS_FAIL_INT | DELINK_INT)) {
pcr->trans_result = TRANS_RESULT_FAIL;
@@ -877,10 +852,6 @@ static irqreturn_t rtsx_pci_isr(int irq, void *dev_id)
}
}
- if (pcr->card_inserted || pcr->card_removed)
- schedule_delayed_work(&pcr->carddet_work,
- msecs_to_jiffies(200));
-
spin_unlock(&pcr->lock);
return IRQ_HANDLED;
}
@@ -1003,14 +974,6 @@ static int rtsx_pci_init_hw(struct rtsx_pcr *pcr)
return err;
}
- /* No CD interrupt if probing driver with card inserted.
- * So we need to initialize pcr->card_exist here.
- */
- if (pcr->ops->cd_deglitch)
- pcr->card_exist = pcr->ops->cd_deglitch(pcr);
- else
- pcr->card_exist = rtsx_pci_readl(pcr, RTSX_BIPR) & CARD_EXIST;
-
return 0;
}
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index bb07512..b151b7c 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -63,7 +63,6 @@ config ATMEL_PWM
config ATMEL_TCLIB
bool "Atmel AT32/AT91 Timer/Counter Library"
depends on (AVR32 || ARCH_AT91)
- default y if PREEMPT_RT_FULL
help
Select this if you want a library to allocate the Timer/Counter
blocks found on many Atmel processors. This facilitates using
@@ -79,7 +78,8 @@ config ATMEL_TCB_CLKSRC
are combined to make a single 32-bit timer.
When GENERIC_CLOCKEVENTS is defined, the third timer channel
- may be used as a clock event device supporting oneshot mode.
+ may be used as a clock event device supporting oneshot mode
+ (delays of up to two seconds) based on the 32 KiHz clock.
config ATMEL_TCB_CLKSRC_BLOCK
int
@@ -93,14 +93,6 @@ config ATMEL_TCB_CLKSRC_BLOCK
TC can be used for other purposes, such as PWM generation and
interval timing.
-config ATMEL_TCB_CLKSRC_USE_SLOW_CLOCK
- bool "TC Block use 32 KiHz clock"
- depends on ATMEL_TCB_CLKSRC
- default y if !PREEMPT_RT_FULL
- help
- Select this to use 32 KiHz base clock rate as TC block clock
- source for clock events.
-
config IBM_ASM
tristate "Device driver for IBM RSA service processor"
depends on X86 && PCI && INPUT
@@ -122,35 +114,6 @@ config IBM_ASM
for information on the specific driver level and support statement
for your IBM server.
-config HWLAT_DETECTOR
- tristate "Testing module to detect hardware-induced latencies"
- depends on DEBUG_FS
- depends on RING_BUFFER
- default m
- ---help---
- A simple hardware latency detector. Use this module to detect
- large latencies introduced by the behavior of the underlying
- system firmware external to Linux. We do this using periodic
- use of stop_machine to grab all available CPUs and measure
- for unexplainable gaps in the CPU timestamp counter(s). By
- default, the module is not enabled until the "enable" file
- within the "hwlat_detector" debugfs directory is toggled.
-
- This module is often used to detect SMI (System Management
- Interrupts) on x86 systems, though is not x86 specific. To
- this end, we default to using a sample window of 1 second,
- during which we will sample for 0.5 seconds. If an SMI or
- similar event occurs during that time, it is recorded
- into an 8K samples global ring buffer until retreived.
-
- WARNING: This software should never be enabled (it can be built
- but should not be turned on after it is loaded) in a production
- environment where high latencies are a concern since the
- sampling mechanism actually introduces latencies for
- regular tasks while the CPU(s) are being held.
-
- If unsure, say N
-
config PHANTOM
tristate "Sensable PHANToM (PCI)"
depends on PCI
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index ec6ee3f..2129377 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -49,4 +49,3 @@ obj-y += carma/
obj-$(CONFIG_USB_SWITCH_FSA9480) += fsa9480.o
obj-$(CONFIG_ALTERA_STAPL) +=altera-stapl/
obj-$(CONFIG_INTEL_MEI) += mei/
-obj-$(CONFIG_HWLAT_DETECTOR) += hwlat_detector.o
diff --git a/drivers/misc/hwlat_detector.c b/drivers/misc/hwlat_detector.c
deleted file mode 100644
index b7b7c90..0000000
--- a/drivers/misc/hwlat_detector.c
+++ /dev/null
@@ -1,1212 +0,0 @@
-/*
- * hwlat_detector.c - A simple Hardware Latency detector.
- *
- * Use this module to detect large system latencies induced by the behavior of
- * certain underlying system hardware or firmware, independent of Linux itself.
- * The code was developed originally to detect the presence of SMIs on Intel
- * and AMD systems, although there is no dependency upon x86 herein.
- *
- * The classical example usage of this module is in detecting the presence of
- * SMIs or System Management Interrupts on Intel and AMD systems. An SMI is a
- * somewhat special form of hardware interrupt spawned from earlier CPU debug
- * modes in which the (BIOS/EFI/etc.) firmware arranges for the South Bridge
- * LPC (or other device) to generate a special interrupt under certain
- * circumstances, for example, upon expiration of a special SMI timer device,
- * due to certain external thermal readings, on certain I/O address accesses,
- * and other situations. An SMI hits a special CPU pin, triggers a special
- * SMI mode (complete with special memory map), and the OS is unaware.
- *
- * Although certain hardware-inducing latencies are necessary (for example,
- * a modern system often requires an SMI handler for correct thermal control
- * and remote management) they can wreak havoc upon any OS-level performance
- * guarantees toward low-latency, especially when the OS is not even made
- * aware of the presence of these interrupts. For this reason, we need a
- * somewhat brute force mechanism to detect these interrupts. In this case,
- * we do it by hogging all of the CPU(s) for configurable timer intervals,
- * sampling the built-in CPU timer, looking for discontiguous readings.
- *
- * WARNING: This implementation necessarily introduces latencies. Therefore,
- * you should NEVER use this module in a production environment
- * requiring any kind of low-latency performance guarantee(s).
- *
- * Copyright (C) 2008-2009 Jon Masters, Red Hat, Inc. <jcm@redhat.com>
- *
- * Includes useful feedback from Clark Williams <clark@redhat.com>
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/ring_buffer.h>
-#include <linux/stop_machine.h>
-#include <linux/time.h>
-#include <linux/hrtimer.h>
-#include <linux/kthread.h>
-#include <linux/debugfs.h>
-#include <linux/seq_file.h>
-#include <linux/uaccess.h>
-#include <linux/version.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-
-#define BUF_SIZE_DEFAULT 262144UL /* 8K*(sizeof(entry)) */
-#define BUF_FLAGS (RB_FL_OVERWRITE) /* no block on full */
-#define U64STR_SIZE 22 /* 20 digits max */
-
-#define VERSION "1.0.0"
-#define BANNER "hwlat_detector: "
-#define DRVNAME "hwlat_detector"
-#define DEFAULT_SAMPLE_WINDOW 1000000 /* 1s */
-#define DEFAULT_SAMPLE_WIDTH 500000 /* 0.5s */
-#define DEFAULT_LAT_THRESHOLD 10 /* 10us */
-
-/* Module metadata */
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Jon Masters <jcm@redhat.com>");
-MODULE_DESCRIPTION("A simple hardware latency detector");
-MODULE_VERSION(VERSION);
-
-/* Module parameters */
-
-static int debug;
-static int enabled;
-static int threshold;
-
-module_param(debug, int, 0); /* enable debug */
-module_param(enabled, int, 0); /* enable detector */
-module_param(threshold, int, 0); /* latency threshold */
-
-/* Buffering and sampling */
-
-static struct ring_buffer *ring_buffer; /* sample buffer */
-static DEFINE_MUTEX(ring_buffer_mutex); /* lock changes */
-static unsigned long buf_size = BUF_SIZE_DEFAULT;
-static struct task_struct *kthread; /* sampling thread */
-
-/* DebugFS filesystem entries */
-
-static struct dentry *debug_dir; /* debugfs directory */
-static struct dentry *debug_max; /* maximum TSC delta */
-static struct dentry *debug_count; /* total detect count */
-static struct dentry *debug_sample_width; /* sample width us */
-static struct dentry *debug_sample_window; /* sample window us */
-static struct dentry *debug_sample; /* raw samples us */
-static struct dentry *debug_threshold; /* threshold us */
-static struct dentry *debug_enable; /* enable/disable */
-
-/* Individual samples and global state */
-
-struct sample; /* latency sample */
-struct data; /* Global state */
-
-/* Sampling functions */
-static int __buffer_add_sample(struct sample *sample);
-static struct sample *buffer_get_sample(struct sample *sample);
-static int get_sample(void *unused);
-
-/* Threading and state */
-static int kthread_fn(void *unused);
-static int start_kthread(void);
-static int stop_kthread(void);
-static void __reset_stats(void);
-static int init_stats(void);
-
-/* Debugfs interface */
-static ssize_t simple_data_read(struct file *filp, char __user *ubuf,
- size_t cnt, loff_t *ppos, const u64 *entry);
-static ssize_t simple_data_write(struct file *filp, const char __user *ubuf,
- size_t cnt, loff_t *ppos, u64 *entry);
-static int debug_sample_fopen(struct inode *inode, struct file *filp);
-static ssize_t debug_sample_fread(struct file *filp, char __user *ubuf,
- size_t cnt, loff_t *ppos);
-static int debug_sample_release(struct inode *inode, struct file *filp);
-static int debug_enable_fopen(struct inode *inode, struct file *filp);
-static ssize_t debug_enable_fread(struct file *filp, char __user *ubuf,
- size_t cnt, loff_t *ppos);
-static ssize_t debug_enable_fwrite(struct file *file,
- const char __user *user_buffer,
- size_t user_size, loff_t *offset);
-
-/* Initialization functions */
-static int init_debugfs(void);
-static void free_debugfs(void);
-static int detector_init(void);
-static void detector_exit(void);
-
-/* Individual latency samples are stored here when detected and packed into
- * the ring_buffer circular buffer, where they are overwritten when
- * more than buf_size/sizeof(sample) samples are received. */
-struct sample {
- u64 seqnum; /* unique sequence */
- u64 duration; /* ktime delta */
- struct timespec timestamp; /* wall time */
- unsigned long lost;
-};
-
-/* keep the global state somewhere. Mostly used under stop_machine. */
-static struct data {
-
- struct mutex lock; /* protect changes */
-
- u64 count; /* total since reset */
- u64 max_sample; /* max hardware latency */
- u64 threshold; /* sample threshold level */
-
- u64 sample_window; /* total sampling window (on+off) */
- u64 sample_width; /* active sampling portion of window */
-
- atomic_t sample_open; /* whether the sample file is open */
-
- wait_queue_head_t wq; /* waitqeue for new sample values */
-
-} data;
-
-/**
- * __buffer_add_sample - add a new latency sample recording to the ring buffer
- * @sample: The new latency sample value
- *
- * This receives a new latency sample and records it in a global ring buffer.
- * No additional locking is used in this case - suited for stop_machine use.
- */
-static int __buffer_add_sample(struct sample *sample)
-{
- return ring_buffer_write(ring_buffer,
- sizeof(struct sample), sample);
-}
-
-/**
- * buffer_get_sample - remove a hardware latency sample from the ring buffer
- * @sample: Pre-allocated storage for the sample
- *
- * This retrieves a hardware latency sample from the global circular buffer
- */
-static struct sample *buffer_get_sample(struct sample *sample)
-{
- struct ring_buffer_event *e = NULL;
- struct sample *s = NULL;
- unsigned int cpu = 0;
-
- if (!sample)
- return NULL;
-
- mutex_lock(&ring_buffer_mutex);
- for_each_online_cpu(cpu) {
- e = ring_buffer_consume(ring_buffer, cpu, NULL, &sample->lost);
- if (e)
- break;
- }
-
- if (e) {
- s = ring_buffer_event_data(e);
- memcpy(sample, s, sizeof(struct sample));
- } else
- sample = NULL;
- mutex_unlock(&ring_buffer_mutex);
-
- return sample;
-}
-
-/**
- * get_sample - sample the CPU TSC and look for likely hardware latencies
- * @unused: This is not used but is a part of the stop_machine API
- *
- * Used to repeatedly capture the CPU TSC (or similar), looking for potential
- * hardware-induced latency. Called under stop_machine, with data.lock held.
- */
-static int get_sample(void *unused)
-{
- ktime_t start, t1, t2;
- s64 diff, total = 0;
- u64 sample = 0;
- int ret = 1;
-
- start = ktime_get(); /* start timestamp */
-
- do {
-
- t1 = ktime_get(); /* we'll look for a discontinuity */
- t2 = ktime_get();
-
- total = ktime_to_us(ktime_sub(t2, start)); /* sample width */
- diff = ktime_to_us(ktime_sub(t2, t1)); /* current diff */
-
- /* This shouldn't happen */
- if (diff < 0) {
- printk(KERN_ERR BANNER "time running backwards\n");
- goto out;
- }
-
- if (diff > sample)
- sample = diff; /* only want highest value */
-
- } while (total <= data.sample_width);
-
- /* If we exceed the threshold value, we have found a hardware latency */
- if (sample > data.threshold) {
- struct sample s;
-
- data.count++;
- s.seqnum = data.count;
- s.duration = sample;
- s.timestamp = CURRENT_TIME;
- __buffer_add_sample(&s);
-
- /* Keep a running maximum ever recorded hardware latency */
- if (sample > data.max_sample)
- data.max_sample = sample;
- }
-
- ret = 0;
-out:
- return ret;
-}
-
-/*
- * kthread_fn - The CPU time sampling/hardware latency detection kernel thread
- * @unused: A required part of the kthread API.
- *
- * Used to periodically sample the CPU TSC via a call to get_sample. We
- * use stop_machine, whith does (intentionally) introduce latency since we
- * need to ensure nothing else might be running (and thus pre-empting).
- * Obviously this should never be used in production environments.
- *
- * stop_machine will schedule us typically only on CPU0 which is fine for
- * almost every real-world hardware latency situation - but we might later
- * generalize this if we find there are any actualy systems with alternate
- * SMI delivery or other non CPU0 hardware latencies.
- */
-static int kthread_fn(void *unused)
-{
- int err = 0;
- u64 interval = 0;
-
- while (!kthread_should_stop()) {
-
- mutex_lock(&data.lock);
-
- err = stop_machine(get_sample, unused, 0);
- if (err) {
- /* Houston, we have a problem */
- mutex_unlock(&data.lock);
- goto err_out;
- }
-
- wake_up(&data.wq); /* wake up reader(s) */
-
- interval = data.sample_window - data.sample_width;
- do_div(interval, USEC_PER_MSEC); /* modifies interval value */
-
- mutex_unlock(&data.lock);
-
- if (msleep_interruptible(interval))
- goto out;
- }
- goto out;
-err_out:
- printk(KERN_ERR BANNER "could not call stop_machine, disabling\n");
- enabled = 0;
-out:
- return err;
-
-}
-
-/**
- * start_kthread - Kick off the hardware latency sampling/detector kthread
- *
- * This starts a kernel thread that will sit and sample the CPU timestamp
- * counter (TSC or similar) and look for potential hardware latencies.
- */
-static int start_kthread(void)
-{
- kthread = kthread_run(kthread_fn, NULL,
- DRVNAME);
- if (IS_ERR(kthread)) {
- printk(KERN_ERR BANNER "could not start sampling thread\n");
- enabled = 0;
- return -ENOMEM;
- }
-
- return 0;
-}
-
-/**
- * stop_kthread - Inform the hardware latency samping/detector kthread to stop
- *
- * This kicks the running hardware latency sampling/detector kernel thread and
- * tells it to stop sampling now. Use this on unload and at system shutdown.
- */
-static int stop_kthread(void)
-{
- int ret;
-
- ret = kthread_stop(kthread);
-
- return ret;
-}
-
-/**
- * __reset_stats - Reset statistics for the hardware latency detector
- *
- * We use data to store various statistics and global state. We call this
- * function in order to reset those when "enable" is toggled on or off, and
- * also at initialization. Should be called with data.lock held.
- */
-static void __reset_stats(void)
-{
- data.count = 0;
- data.max_sample = 0;
- ring_buffer_reset(ring_buffer); /* flush out old sample entries */
-}
-
-/**
- * init_stats - Setup global state statistics for the hardware latency detector
- *
- * We use data to store various statistics and global state. We also use
- * a global ring buffer (ring_buffer) to keep raw samples of detected hardware
- * induced system latencies. This function initializes these structures and
- * allocates the global ring buffer also.
- */
-static int init_stats(void)
-{
- int ret = -ENOMEM;
-
- mutex_init(&data.lock);
- init_waitqueue_head(&data.wq);
- atomic_set(&data.sample_open, 0);
-
- ring_buffer = ring_buffer_alloc(buf_size, BUF_FLAGS);
-
- if (WARN(!ring_buffer, KERN_ERR BANNER
- "failed to allocate ring buffer!\n"))
- goto out;
-
- __reset_stats();
- data.threshold = DEFAULT_LAT_THRESHOLD; /* threshold us */
- data.sample_window = DEFAULT_SAMPLE_WINDOW; /* window us */
- data.sample_width = DEFAULT_SAMPLE_WIDTH; /* width us */
-
- ret = 0;
-
-out:
- return ret;
-
-}
-
-/*
- * simple_data_read - Wrapper read function for global state debugfs entries
- * @filp: The active open file structure for the debugfs "file"
- * @ubuf: The userspace provided buffer to read value into
- * @cnt: The maximum number of bytes to read
- * @ppos: The current "file" position
- * @entry: The entry to read from
- *
- * This function provides a generic read implementation for the global state
- * "data" structure debugfs filesystem entries. It would be nice to use
- * simple_attr_read directly, but we need to make sure that the data.lock
- * spinlock is held during the actual read (even though we likely won't ever
- * actually race here as the updater runs under a stop_machine context).
- */
-static ssize_t simple_data_read(struct file *filp, char __user *ubuf,
- size_t cnt, loff_t *ppos, const u64 *entry)
-{
- char buf[U64STR_SIZE];
- u64 val = 0;
- int len = 0;
-
- memset(buf, 0, sizeof(buf));
-
- if (!entry)
- return -EFAULT;
-
- mutex_lock(&data.lock);
- val = *entry;
- mutex_unlock(&data.lock);
-
- len = snprintf(buf, sizeof(buf), "%llu\n", (unsigned long long)val);
-
- return simple_read_from_buffer(ubuf, cnt, ppos, buf, len);
-
-}
-
-/*
- * simple_data_write - Wrapper write function for global state debugfs entries
- * @filp: The active open file structure for the debugfs "file"
- * @ubuf: The userspace provided buffer to write value from
- * @cnt: The maximum number of bytes to write
- * @ppos: The current "file" position
- * @entry: The entry to write to
- *
- * This function provides a generic write implementation for the global state
- * "data" structure debugfs filesystem entries. It would be nice to use
- * simple_attr_write directly, but we need to make sure that the data.lock
- * spinlock is held during the actual write (even though we likely won't ever
- * actually race here as the updater runs under a stop_machine context).
- */
-static ssize_t simple_data_write(struct file *filp, const char __user *ubuf,
- size_t cnt, loff_t *ppos, u64 *entry)
-{
- char buf[U64STR_SIZE];
- int csize = min(cnt, sizeof(buf));
- u64 val = 0;
- int err = 0;
-
- memset(buf, '\0', sizeof(buf));
- if (copy_from_user(buf, ubuf, csize))
- return -EFAULT;
-
- buf[U64STR_SIZE-1] = '\0'; /* just in case */
- err = strict_strtoull(buf, 10, &val);
- if (err)
- return -EINVAL;
-
- mutex_lock(&data.lock);
- *entry = val;
- mutex_unlock(&data.lock);
-
- return csize;
-}
-
-/**
- * debug_count_fopen - Open function for "count" debugfs entry
- * @inode: The in-kernel inode representation of the debugfs "file"
- * @filp: The active open file structure for the debugfs "file"
- *
- * This function provides an open implementation for the "count" debugfs
- * interface to the hardware latency detector.
- */
-static int debug_count_fopen(struct inode *inode, struct file *filp)
-{
- return 0;
-}
-
-/**
- * debug_count_fread - Read function for "count" debugfs entry
- * @filp: The active open file structure for the debugfs "file"
- * @ubuf: The userspace provided buffer to read value into
- * @cnt: The maximum number of bytes to read
- * @ppos: The current "file" position
- *
- * This function provides a read implementation for the "count" debugfs
- * interface to the hardware latency detector. Can be used to read the
- * number of latency readings exceeding the configured threshold since
- * the detector was last reset (e.g. by writing a zero into "count").
- */
-static ssize_t debug_count_fread(struct file *filp, char __user *ubuf,
- size_t cnt, loff_t *ppos)
-{
- return simple_data_read(filp, ubuf, cnt, ppos, &data.count);
-}
-
-/**
- * debug_count_fwrite - Write function for "count" debugfs entry
- * @filp: The active open file structure for the debugfs "file"
- * @ubuf: The user buffer that contains the value to write
- * @cnt: The maximum number of bytes to write to "file"
- * @ppos: The current position in the debugfs "file"
- *
- * This function provides a write implementation for the "count" debugfs
- * interface to the hardware latency detector. Can be used to write a
- * desired value, especially to zero the total count.
- */
-static ssize_t debug_count_fwrite(struct file *filp,
- const char __user *ubuf,
- size_t cnt,
- loff_t *ppos)
-{
- return simple_data_write(filp, ubuf, cnt, ppos, &data.count);
-}
-
-/**
- * debug_enable_fopen - Dummy open function for "enable" debugfs interface
- * @inode: The in-kernel inode representation of the debugfs "file"
- * @filp: The active open file structure for the debugfs "file"
- *
- * This function provides an open implementation for the "enable" debugfs
- * interface to the hardware latency detector.
- */
-static int debug_enable_fopen(struct inode *inode, struct file *filp)
-{
- return 0;
-}
-
-/**
- * debug_enable_fread - Read function for "enable" debugfs interface
- * @filp: The active open file structure for the debugfs "file"
- * @ubuf: The userspace provided buffer to read value into
- * @cnt: The maximum number of bytes to read
- * @ppos: The current "file" position
- *
- * This function provides a read implementation for the "enable" debugfs
- * interface to the hardware latency detector. Can be used to determine
- * whether the detector is currently enabled ("0\n" or "1\n" returned).
- */
-static ssize_t debug_enable_fread(struct file *filp, char __user *ubuf,
- size_t cnt, loff_t *ppos)
-{
- char buf[4];
-
- if ((cnt < sizeof(buf)) || (*ppos))
- return 0;
-
- buf[0] = enabled ? '1' : '0';
- buf[1] = '\n';
- buf[2] = '\0';
- if (copy_to_user(ubuf, buf, strlen(buf)))
- return -EFAULT;
- return *ppos = strlen(buf);
-}
-
-/**
- * debug_enable_fwrite - Write function for "enable" debugfs interface
- * @filp: The active open file structure for the debugfs "file"
- * @ubuf: The user buffer that contains the value to write
- * @cnt: The maximum number of bytes to write to "file"
- * @ppos: The current position in the debugfs "file"
- *
- * This function provides a write implementation for the "enable" debugfs
- * interface to the hardware latency detector. Can be used to enable or
- * disable the detector, which will have the side-effect of possibly
- * also resetting the global stats and kicking off the measuring
- * kthread (on an enable) or the converse (upon a disable).
- */
-static ssize_t debug_enable_fwrite(struct file *filp,
- const char __user *ubuf,
- size_t cnt,
- loff_t *ppos)
-{
- char buf[4];
- int csize = min(cnt, sizeof(buf));
- long val = 0;
- int err = 0;
-
- memset(buf, '\0', sizeof(buf));
- if (copy_from_user(buf, ubuf, csize))
- return -EFAULT;
-
- buf[sizeof(buf)-1] = '\0'; /* just in case */
- err = strict_strtoul(buf, 10, &val);
- if (0 != err)
- return -EINVAL;
-
- if (val) {
- if (enabled)
- goto unlock;
- enabled = 1;
- __reset_stats();
- if (start_kthread())
- return -EFAULT;
- } else {
- if (!enabled)
- goto unlock;
- enabled = 0;
- err = stop_kthread();
- if (err) {
- printk(KERN_ERR BANNER "cannot stop kthread\n");
- return -EFAULT;
- }
- wake_up(&data.wq); /* reader(s) should return */
- }
-unlock:
- return csize;
-}
-
-/**
- * debug_max_fopen - Open function for "max" debugfs entry
- * @inode: The in-kernel inode representation of the debugfs "file"
- * @filp: The active open file structure for the debugfs "file"
- *
- * This function provides an open implementation for the "max" debugfs
- * interface to the hardware latency detector.
- */
-static int debug_max_fopen(struct inode *inode, struct file *filp)
-{
- return 0;
-}
-
-/**
- * debug_max_fread - Read function for "max" debugfs entry
- * @filp: The active open file structure for the debugfs "file"
- * @ubuf: The userspace provided buffer to read value into
- * @cnt: The maximum number of bytes to read
- * @ppos: The current "file" position
- *
- * This function provides a read implementation for the "max" debugfs
- * interface to the hardware latency detector. Can be used to determine
- * the maximum latency value observed since it was last reset.
- */
-static ssize_t debug_max_fread(struct file *filp, char __user *ubuf,
- size_t cnt, loff_t *ppos)
-{
- return simple_data_read(filp, ubuf, cnt, ppos, &data.max_sample);
-}
-
-/**
- * debug_max_fwrite - Write function for "max" debugfs entry
- * @filp: The active open file structure for the debugfs "file"
- * @ubuf: The user buffer that contains the value to write
- * @cnt: The maximum number of bytes to write to "file"
- * @ppos: The current position in the debugfs "file"
- *
- * This function provides a write implementation for the "max" debugfs
- * interface to the hardware latency detector. Can be used to reset the
- * maximum or set it to some other desired value - if, then, subsequent
- * measurements exceed this value, the maximum will be updated.
- */
-static ssize_t debug_max_fwrite(struct file *filp,
- const char __user *ubuf,
- size_t cnt,
- loff_t *ppos)
-{
- return simple_data_write(filp, ubuf, cnt, ppos, &data.max_sample);
-}
-
-
-/**
- * debug_sample_fopen - An open function for "sample" debugfs interface
- * @inode: The in-kernel inode representation of this debugfs "file"
- * @filp: The active open file structure for the debugfs "file"
- *
- * This function handles opening the "sample" file within the hardware
- * latency detector debugfs directory interface. This file is used to read
- * raw samples from the global ring_buffer and allows the user to see a
- * running latency history. Can be opened blocking or non-blocking,
- * affecting whether it behaves as a buffer read pipe, or does not.
- * Implements simple locking to prevent multiple simultaneous use.
- */
-static int debug_sample_fopen(struct inode *inode, struct file *filp)
-{
- if (!atomic_add_unless(&data.sample_open, 1, 1))
- return -EBUSY;
- else
- return 0;
-}
-
-/**
- * debug_sample_fread - A read function for "sample" debugfs interface
- * @filp: The active open file structure for the debugfs "file"
- * @ubuf: The user buffer that will contain the samples read
- * @cnt: The maximum bytes to read from the debugfs "file"
- * @ppos: The current position in the debugfs "file"
- *
- * This function handles reading from the "sample" file within the hardware
- * latency detector debugfs directory interface. This file is used to read
- * raw samples from the global ring_buffer and allows the user to see a
- * running latency history. By default this will block pending a new
- * value written into the sample buffer, unless there are already a
- * number of value(s) waiting in the buffer, or the sample file was
- * previously opened in a non-blocking mode of operation.
- */
-static ssize_t debug_sample_fread(struct file *filp, char __user *ubuf,
- size_t cnt, loff_t *ppos)
-{
- int len = 0;
- char buf[64];
- struct sample *sample = NULL;
-
- if (!enabled)
- return 0;
-
- sample = kzalloc(sizeof(struct sample), GFP_KERNEL);
- if (!sample)
- return -ENOMEM;
-
- while (!buffer_get_sample(sample)) {
-
- DEFINE_WAIT(wait);
-
- if (filp->f_flags & O_NONBLOCK) {
- len = -EAGAIN;
- goto out;
- }
-
- prepare_to_wait(&data.wq, &wait, TASK_INTERRUPTIBLE);
- schedule();
- finish_wait(&data.wq, &wait);
-
- if (signal_pending(current)) {
- len = -EINTR;
- goto out;
- }
-
- if (!enabled) { /* enable was toggled */
- len = 0;
- goto out;
- }
- }
-
- len = snprintf(buf, sizeof(buf), "%010lu.%010lu\t%llu\n",
- sample->timestamp.tv_sec,
- sample->timestamp.tv_nsec,
- sample->duration);
-
-
- /* handling partial reads is more trouble than it's worth */
- if (len > cnt)
- goto out;
-
- if (copy_to_user(ubuf, buf, len))
- len = -EFAULT;
-
-out:
- kfree(sample);
- return len;
-}
-
-/**
- * debug_sample_release - Release function for "sample" debugfs interface
- * @inode: The in-kernel inode represenation of the debugfs "file"
- * @filp: The active open file structure for the debugfs "file"
- *
- * This function completes the close of the debugfs interface "sample" file.
- * Frees the sample_open "lock" so that other users may open the interface.
- */
-static int debug_sample_release(struct inode *inode, struct file *filp)
-{
- atomic_dec(&data.sample_open);
-
- return 0;
-}
-
-/**
- * debug_threshold_fopen - Open function for "threshold" debugfs entry
- * @inode: The in-kernel inode representation of the debugfs "file"
- * @filp: The active open file structure for the debugfs "file"
- *
- * This function provides an open implementation for the "threshold" debugfs
- * interface to the hardware latency detector.
- */
-static int debug_threshold_fopen(struct inode *inode, struct file *filp)
-{
- return 0;
-}
-
-/**
- * debug_threshold_fread - Read function for "threshold" debugfs entry
- * @filp: The active open file structure for the debugfs "file"
- * @ubuf: The userspace provided buffer to read value into
- * @cnt: The maximum number of bytes to read
- * @ppos: The current "file" position
- *
- * This function provides a read implementation for the "threshold" debugfs
- * interface to the hardware latency detector. It can be used to determine
- * the current threshold level at which a latency will be recorded in the
- * global ring buffer, typically on the order of 10us.
- */
-static ssize_t debug_threshold_fread(struct file *filp, char __user *ubuf,
- size_t cnt, loff_t *ppos)
-{
- return simple_data_read(filp, ubuf, cnt, ppos, &data.threshold);
-}
-
-/**
- * debug_threshold_fwrite - Write function for "threshold" debugfs entry
- * @filp: The active open file structure for the debugfs "file"
- * @ubuf: The user buffer that contains the value to write
- * @cnt: The maximum number of bytes to write to "file"
- * @ppos: The current position in the debugfs "file"
- *
- * This function provides a write implementation for the "threshold" debugfs
- * interface to the hardware latency detector. It can be used to configure
- * the threshold level at which any subsequently detected latencies will
- * be recorded into the global ring buffer.
- */
-static ssize_t debug_threshold_fwrite(struct file *filp,
- const char __user *ubuf,
- size_t cnt,
- loff_t *ppos)
-{
- int ret;
-
- ret = simple_data_write(filp, ubuf, cnt, ppos, &data.threshold);
-
- if (enabled)
- wake_up_process(kthread);
-
- return ret;
-}
-
-/**
- * debug_width_fopen - Open function for "width" debugfs entry
- * @inode: The in-kernel inode representation of the debugfs "file"
- * @filp: The active open file structure for the debugfs "file"
- *
- * This function provides an open implementation for the "width" debugfs
- * interface to the hardware latency detector.
- */
-static int debug_width_fopen(struct inode *inode, struct file *filp)
-{
- return 0;
-}
-
-/**
- * debug_width_fread - Read function for "width" debugfs entry
- * @filp: The active open file structure for the debugfs "file"
- * @ubuf: The userspace provided buffer to read value into
- * @cnt: The maximum number of bytes to read
- * @ppos: The current "file" position
- *
- * This function provides a read implementation for the "width" debugfs
- * interface to the hardware latency detector. It can be used to determine
- * for how many us of the total window us we will actively sample for any
- * hardware-induced latecy periods. Obviously, it is not possible to
- * sample constantly and have the system respond to a sample reader, or,
- * worse, without having the system appear to have gone out to lunch.
- */
-static ssize_t debug_width_fread(struct file *filp, char __user *ubuf,
- size_t cnt, loff_t *ppos)
-{
- return simple_data_read(filp, ubuf, cnt, ppos, &data.sample_width);
-}
-
-/**
- * debug_width_fwrite - Write function for "width" debugfs entry
- * @filp: The active open file structure for the debugfs "file"
- * @ubuf: The user buffer that contains the value to write
- * @cnt: The maximum number of bytes to write to "file"
- * @ppos: The current position in the debugfs "file"
- *
- * This function provides a write implementation for the "width" debugfs
- * interface to the hardware latency detector. It can be used to configure
- * for how many us of the total window us we will actively sample for any
- * hardware-induced latency periods. Obviously, it is not possible to
- * sample constantly and have the system respond to a sample reader, or,
- * worse, without having the system appear to have gone out to lunch. It
- * is enforced that width is less that the total window size.
- */
-static ssize_t debug_width_fwrite(struct file *filp,
- const char __user *ubuf,
- size_t cnt,
- loff_t *ppos)
-{
- char buf[U64STR_SIZE];
- int csize = min(cnt, sizeof(buf));
- u64 val = 0;
- int err = 0;
-
- memset(buf, '\0', sizeof(buf));
- if (copy_from_user(buf, ubuf, csize))
- return -EFAULT;
-
- buf[U64STR_SIZE-1] = '\0'; /* just in case */
- err = strict_strtoull(buf, 10, &val);
- if (0 != err)
- return -EINVAL;
-
- mutex_lock(&data.lock);
- if (val < data.sample_window)
- data.sample_width = val;
- else {
- mutex_unlock(&data.lock);
- return -EINVAL;
- }
- mutex_unlock(&data.lock);
-
- if (enabled)
- wake_up_process(kthread);
-
- return csize;
-}
-
-/**
- * debug_window_fopen - Open function for "window" debugfs entry
- * @inode: The in-kernel inode representation of the debugfs "file"
- * @filp: The active open file structure for the debugfs "file"
- *
- * This function provides an open implementation for the "window" debugfs
- * interface to the hardware latency detector. The window is the total time
- * in us that will be considered one sample period. Conceptually, windows
- * occur back-to-back and contain a sample width period during which
- * actual sampling occurs.
- */
-static int debug_window_fopen(struct inode *inode, struct file *filp)
-{
- return 0;
-}
-
-/**
- * debug_window_fread - Read function for "window" debugfs entry
- * @filp: The active open file structure for the debugfs "file"
- * @ubuf: The userspace provided buffer to read value into
- * @cnt: The maximum number of bytes to read
- * @ppos: The current "file" position
- *
- * This function provides a read implementation for the "window" debugfs
- * interface to the hardware latency detector. The window is the total time
- * in us that will be considered one sample period. Conceptually, windows
- * occur back-to-back and contain a sample width period during which
- * actual sampling occurs. Can be used to read the total window size.
- */
-static ssize_t debug_window_fread(struct file *filp, char __user *ubuf,
- size_t cnt, loff_t *ppos)
-{
- return simple_data_read(filp, ubuf, cnt, ppos, &data.sample_window);
-}
-
-/**
- * debug_window_fwrite - Write function for "window" debugfs entry
- * @filp: The active open file structure for the debugfs "file"
- * @ubuf: The user buffer that contains the value to write
- * @cnt: The maximum number of bytes to write to "file"
- * @ppos: The current position in the debugfs "file"
- *
- * This function provides a write implementation for the "window" debufds
- * interface to the hardware latency detetector. The window is the total time
- * in us that will be considered one sample period. Conceptually, windows
- * occur back-to-back and contain a sample width period during which
- * actual sampling occurs. Can be used to write a new total window size. It
- * is enfoced that any value written must be greater than the sample width
- * size, or an error results.
- */
-static ssize_t debug_window_fwrite(struct file *filp,
- const char __user *ubuf,
- size_t cnt,
- loff_t *ppos)
-{
- char buf[U64STR_SIZE];
- int csize = min(cnt, sizeof(buf));
- u64 val = 0;
- int err = 0;
-
- memset(buf, '\0', sizeof(buf));
- if (copy_from_user(buf, ubuf, csize))
- return -EFAULT;
-
- buf[U64STR_SIZE-1] = '\0'; /* just in case */
- err = strict_strtoull(buf, 10, &val);
- if (0 != err)
- return -EINVAL;
-
- mutex_lock(&data.lock);
- if (data.sample_width < val)
- data.sample_window = val;
- else {
- mutex_unlock(&data.lock);
- return -EINVAL;
- }
- mutex_unlock(&data.lock);
-
- return csize;
-}
-
-/*
- * Function pointers for the "count" debugfs file operations
- */
-static const struct file_operations count_fops = {
- .open = debug_count_fopen,
- .read = debug_count_fread,
- .write = debug_count_fwrite,
- .owner = THIS_MODULE,
-};
-
-/*
- * Function pointers for the "enable" debugfs file operations
- */
-static const struct file_operations enable_fops = {
- .open = debug_enable_fopen,
- .read = debug_enable_fread,
- .write = debug_enable_fwrite,
- .owner = THIS_MODULE,
-};
-
-/*
- * Function pointers for the "max" debugfs file operations
- */
-static const struct file_operations max_fops = {
- .open = debug_max_fopen,
- .read = debug_max_fread,
- .write = debug_max_fwrite,
- .owner = THIS_MODULE,
-};
-
-/*
- * Function pointers for the "sample" debugfs file operations
- */
-static const struct file_operations sample_fops = {
- .open = debug_sample_fopen,
- .read = debug_sample_fread,
- .release = debug_sample_release,
- .owner = THIS_MODULE,
-};
-
-/*
- * Function pointers for the "threshold" debugfs file operations
- */
-static const struct file_operations threshold_fops = {
- .open = debug_threshold_fopen,
- .read = debug_threshold_fread,
- .write = debug_threshold_fwrite,
- .owner = THIS_MODULE,
-};
-
-/*
- * Function pointers for the "width" debugfs file operations
- */
-static const struct file_operations width_fops = {
- .open = debug_width_fopen,
- .read = debug_width_fread,
- .write = debug_width_fwrite,
- .owner = THIS_MODULE,
-};
-
-/*
- * Function pointers for the "window" debugfs file operations
- */
-static const struct file_operations window_fops = {
- .open = debug_window_fopen,
- .read = debug_window_fread,
- .write = debug_window_fwrite,
- .owner = THIS_MODULE,
-};
-
-/**
- * init_debugfs - A function to initialize the debugfs interface files
- *
- * This function creates entries in debugfs for "hwlat_detector", including
- * files to read values from the detector, current samples, and the
- * maximum sample that has been captured since the hardware latency
- * dectector was started.
- */
-static int init_debugfs(void)
-{
- int ret = -ENOMEM;
-
- debug_dir = debugfs_create_dir(DRVNAME, NULL);
- if (!debug_dir)
- goto err_debug_dir;
-
- debug_sample = debugfs_create_file("sample", 0444,
- debug_dir, NULL,
- &sample_fops);
- if (!debug_sample)
- goto err_sample;
-
- debug_count = debugfs_create_file("count", 0444,
- debug_dir, NULL,
- &count_fops);
- if (!debug_count)
- goto err_count;
-
- debug_max = debugfs_create_file("max", 0444,
- debug_dir, NULL,
- &max_fops);
- if (!debug_max)
- goto err_max;
-
- debug_sample_window = debugfs_create_file("window", 0644,
- debug_dir, NULL,
- &window_fops);
- if (!debug_sample_window)
- goto err_window;
-
- debug_sample_width = debugfs_create_file("width", 0644,
- debug_dir, NULL,
- &width_fops);
- if (!debug_sample_width)
- goto err_width;
-
- debug_threshold = debugfs_create_file("threshold", 0644,
- debug_dir, NULL,
- &threshold_fops);
- if (!debug_threshold)
- goto err_threshold;
-
- debug_enable = debugfs_create_file("enable", 0644,
- debug_dir, &enabled,
- &enable_fops);
- if (!debug_enable)
- goto err_enable;
-
- else {
- ret = 0;
- goto out;
- }
-
-err_enable:
- debugfs_remove(debug_threshold);
-err_threshold:
- debugfs_remove(debug_sample_width);
-err_width:
- debugfs_remove(debug_sample_window);
-err_window:
- debugfs_remove(debug_max);
-err_max:
- debugfs_remove(debug_count);
-err_count:
- debugfs_remove(debug_sample);
-err_sample:
- debugfs_remove(debug_dir);
-err_debug_dir:
-out:
- return ret;
-}
-
-/**
- * free_debugfs - A function to cleanup the debugfs file interface
- */
-static void free_debugfs(void)
-{
- /* could also use a debugfs_remove_recursive */
- debugfs_remove(debug_enable);
- debugfs_remove(debug_threshold);
- debugfs_remove(debug_sample_width);
- debugfs_remove(debug_sample_window);
- debugfs_remove(debug_max);
- debugfs_remove(debug_count);
- debugfs_remove(debug_sample);
- debugfs_remove(debug_dir);
-}
-
-/**
- * detector_init - Standard module initialization code
- */
-static int detector_init(void)
-{
- int ret = -ENOMEM;
-
- printk(KERN_INFO BANNER "version %s\n", VERSION);
-
- ret = init_stats();
- if (0 != ret)
- goto out;
-
- ret = init_debugfs();
- if (0 != ret)
- goto err_stats;
-
- if (enabled)
- ret = start_kthread();
-
- goto out;
-
-err_stats:
- ring_buffer_free(ring_buffer);
-out:
- return ret;
-
-}
-
-/**
- * detector_exit - Standard module cleanup code
- */
-static void detector_exit(void)
-{
- int err;
-
- if (enabled) {
- enabled = 0;
- err = stop_kthread();
- if (err)
- printk(KERN_ERR BANNER "cannot stop kthread\n");
- }
-
- free_debugfs();
- ring_buffer_free(ring_buffer); /* free up the ring buffer */
-
-}
-
-module_init(detector_init);
-module_exit(detector_exit);
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 2743b7d..e6e3911 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -368,13 +368,13 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd)
ext_csd[EXT_CSD_SEC_FEATURE_SUPPORT];
card->ext_csd.raw_trim_mult =
ext_csd[EXT_CSD_TRIM_MULT];
- card->ext_csd.raw_partition_support = ext_csd[EXT_CSD_PARTITION_SUPPORT];
if (card->ext_csd.rev >= 4) {
/*
* Enhanced area feature support -- check whether the eMMC
* card has the Enhanced area enabled. If so, export enhanced
* area offset and size to user by adding sysfs interface.
*/
+ card->ext_csd.raw_partition_support = ext_csd[EXT_CSD_PARTITION_SUPPORT];
if ((ext_csd[EXT_CSD_PARTITION_SUPPORT] & 0x2) &&
(ext_csd[EXT_CSD_PARTITION_ATTRIBUTE] & 0x1)) {
hc_erase_grp_sz =
@@ -496,7 +496,7 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd)
* RPMB regions are defined in multiples of 128K.
*/
card->ext_csd.raw_rpmb_size_mult = ext_csd[EXT_CSD_RPMB_MULT];
- if (ext_csd[EXT_CSD_RPMB_MULT] && mmc_host_cmd23(card->host)) {
+ if (ext_csd[EXT_CSD_RPMB_MULT]) {
mmc_part_add(card, ext_csd[EXT_CSD_RPMB_MULT] << 17,
EXT_CSD_PART_CONFIG_ACC_RPMB,
"rpmb", 0, false,
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index 009dabd..8d13c65 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -292,6 +292,16 @@ config MMC_ATMELMCI
If unsure, say N.
+config MMC_ATMELMCI_DMA
+ bool "Atmel MCI DMA support"
+ depends on MMC_ATMELMCI && (AVR32 || ARCH_AT91SAM9G45) && DMA_ENGINE
+ help
+ Say Y here to have the Atmel MCI driver use a DMA engine to
+ do data transfers and thus increase the throughput and
+ reduce the CPU utilization.
+
+ If unsure, say N.
+
config MMC_MSM
tristate "Qualcomm SDCC Controller Support"
depends on MMC && ARCH_MSM
diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c
index e75774f..722af1d 100644
--- a/drivers/mmc/host/atmel-mci.c
+++ b/drivers/mmc/host/atmel-mci.c
@@ -178,7 +178,6 @@ struct atmel_mci {
void __iomem *regs;
struct scatterlist *sg;
- unsigned int sg_len;
unsigned int pio_offset;
unsigned int *buffer;
unsigned int buf_size;
@@ -893,7 +892,6 @@ static u32 atmci_prepare_data(struct atmel_mci *host, struct mmc_data *data)
data->error = -EINPROGRESS;
host->sg = data->sg;
- host->sg_len = data->sg_len;
host->data = data;
host->data_chan = NULL;
@@ -1828,8 +1826,7 @@ static void atmci_read_data_pio(struct atmel_mci *host)
if (offset == sg->length) {
flush_dcache_page(sg_page(sg));
host->sg = sg = sg_next(sg);
- host->sg_len--;
- if (!sg || !host->sg_len)
+ if (!sg)
goto done;
offset = 0;
@@ -1842,8 +1839,7 @@ static void atmci_read_data_pio(struct atmel_mci *host)
flush_dcache_page(sg_page(sg));
host->sg = sg = sg_next(sg);
- host->sg_len--;
- if (!sg || !host->sg_len)
+ if (!sg)
goto done;
offset = 4 - remaining;
@@ -1894,8 +1890,7 @@ static void atmci_write_data_pio(struct atmel_mci *host)
nbytes += 4;
if (offset == sg->length) {
host->sg = sg = sg_next(sg);
- host->sg_len--;
- if (!sg || !host->sg_len)
+ if (!sg)
goto done;
offset = 0;
@@ -1909,8 +1904,7 @@ static void atmci_write_data_pio(struct atmel_mci *host)
nbytes += remaining;
host->sg = sg = sg_next(sg);
- host->sg_len--;
- if (!sg || !host->sg_len) {
+ if (!sg) {
atmci_writel(host, ATMCI_TDR, value);
goto done;
}
@@ -2493,8 +2487,10 @@ static int __exit atmci_remove(struct platform_device *pdev)
atmci_readl(host, ATMCI_SR);
clk_disable(host->mck);
+#ifdef CONFIG_MMC_ATMELMCI_DMA
if (host->dma.chan)
dma_release_channel(host->dma.chan);
+#endif
free_irq(platform_get_irq(pdev, 0), host);
iounmap(host->regs);
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 724f478..1507723 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -930,12 +930,15 @@ static irqreturn_t mmci_pio_irq(int irq, void *dev_id)
struct sg_mapping_iter *sg_miter = &host->sg_miter;
struct variant_data *variant = host->variant;
void __iomem *base = host->base;
+ unsigned long flags;
u32 status;
status = readl(base + MMCISTATUS);
dev_dbg(mmc_dev(host->mmc), "irq1 (pio) %08x\n", status);
+ local_irq_save(flags);
+
do {
unsigned int remain, len;
char *buffer;
@@ -975,6 +978,8 @@ static irqreturn_t mmci_pio_irq(int irq, void *dev_id)
sg_miter_stop(sg_miter);
+ local_irq_restore(flags);
+
/*
* If we have less than the fifo 'half-full' threshold to transfer,
* trigger a PIO interrupt as soon as any data is available.
diff --git a/drivers/mmc/host/rtsx_pci_sdmmc.c b/drivers/mmc/host/rtsx_pci_sdmmc.c
index 468c923..f74b5ad 100644
--- a/drivers/mmc/host/rtsx_pci_sdmmc.c
+++ b/drivers/mmc/host/rtsx_pci_sdmmc.c
@@ -678,19 +678,12 @@ static void sdmmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
struct mmc_command *cmd = mrq->cmd;
struct mmc_data *data = mrq->data;
unsigned int data_size = 0;
- int err;
if (host->eject) {
cmd->error = -ENOMEDIUM;
goto finish;
}
- err = rtsx_pci_card_exclusive_check(host->pcr, RTSX_SD_CARD);
- if (err) {
- cmd->error = err;
- goto finish;
- }
-
mutex_lock(&pcr->pcr_mutex);
rtsx_pci_start_run(pcr);
@@ -908,9 +901,6 @@ static void sdmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
if (host->eject)
return;
- if (rtsx_pci_card_exclusive_check(host->pcr, RTSX_SD_CARD))
- return;
-
mutex_lock(&pcr->pcr_mutex);
rtsx_pci_start_run(pcr);
@@ -1083,10 +1073,6 @@ static int sdmmc_switch_voltage(struct mmc_host *mmc, struct mmc_ios *ios)
if (host->eject)
return -ENOMEDIUM;
- err = rtsx_pci_card_exclusive_check(host->pcr, RTSX_SD_CARD);
- if (err)
- return err;
-
mutex_lock(&pcr->pcr_mutex);
rtsx_pci_start_run(pcr);
@@ -1136,10 +1122,6 @@ static int sdmmc_execute_tuning(struct mmc_host *mmc, u32 opcode)
if (host->eject)
return -ENOMEDIUM;
- err = rtsx_pci_card_exclusive_check(host->pcr, RTSX_SD_CARD);
- if (err)
- return err;
-
mutex_lock(&pcr->pcr_mutex);
rtsx_pci_start_run(pcr);
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index b503113..e07df81 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -237,18 +237,15 @@ static void esdhc_writel_le(struct sdhci_host *host, u32 val, int reg)
static u16 esdhc_readw_le(struct sdhci_host *host, int reg)
{
- struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
- struct pltfm_imx_data *imx_data = pltfm_host->priv;
-
if (unlikely(reg == SDHCI_HOST_VERSION)) {
- reg ^= 2;
- if (is_imx6q_usdhc(imx_data)) {
- /*
- * The usdhc register returns a wrong host version.
- * Correct it here.
- */
- return SDHCI_SPEC_300;
- }
+ u16 val = readw(host->ioaddr + (reg ^ 2));
+ /*
+ * uSDHC supports SDHCI v3.0, but it's encoded as value
+ * 0x3 in host controller version register, which violates
+ * SDHCI_SPEC_300 definition. Work it around here.
+ */
+ if ((val & SDHCI_SPEC_VER_MASK) == 3)
+ return --val;
}
return readw(host->ioaddr + reg);
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index 6e3d6dc..82c0616 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -1159,17 +1159,45 @@ static int mtdchar_mmap(struct file *file, struct vm_area_struct *vma)
struct mtd_file_info *mfi = file->private_data;
struct mtd_info *mtd = mfi->mtd;
struct map_info *map = mtd->priv;
+ resource_size_t start, off;
+ unsigned long len, vma_len;
/* This is broken because it assumes the MTD device is map-based
and that mtd->priv is a valid struct map_info. It should be
replaced with something that uses the mtd_get_unmapped_area()
operation properly. */
if (0 /*mtd->type == MTD_RAM || mtd->type == MTD_ROM*/) {
+ off = get_vm_offset(vma);
+ start = map->phys;
+ len = PAGE_ALIGN((start & ~PAGE_MASK) + map->size);
+ start &= PAGE_MASK;
+ vma_len = get_vm_size(vma);
+
+ /* Overflow in off+len? */
+ if (vma_len + off < off)
+ return -EINVAL;
+ /* Does it fit in the mapping? */
+ if (vma_len + off > len)
+ return -EINVAL;
+
+ off += start;
+ /* Did that overflow? */
+ if (off < start)
+ return -EINVAL;
+ if (set_vm_offset(vma, off) < 0)
+ return -EINVAL;
+ vma->vm_flags |= VM_IO | VM_DONTEXPAND | VM_DONTDUMP;
+
#ifdef pgprot_noncached
- if (file->f_flags & O_DSYNC || map->phys >= __pa(high_memory))
+ if (file->f_flags & O_DSYNC || off >= __pa(high_memory))
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
#endif
- return vm_iomap_memory(vma, map->phys, map->size);
+ if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot))
+ return -EAGAIN;
+
+ return 0;
}
return -ENOSYS;
#else
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index db04f53..3766682 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -1527,14 +1527,6 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
oobreadlen -= toread;
}
}
-
- if (chip->options & NAND_NEED_READRDY) {
- /* Apply delay or wait for ready/busy pin */
- if (!chip->dev_ready)
- udelay(chip->chip_delay);
- else
- nand_wait_ready(mtd);
- }
} else {
memcpy(buf, chip->buffers->databuf + col, bytes);
buf += bytes;
@@ -1799,14 +1791,6 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
len = min(len, readlen);
buf = nand_transfer_oob(chip, buf, ops, len);
- if (chip->options & NAND_NEED_READRDY) {
- /* Apply delay or wait for ready/busy pin */
- if (!chip->dev_ready)
- udelay(chip->chip_delay);
- else
- nand_wait_ready(mtd);
- }
-
readlen -= len;
if (!readlen)
break;
diff --git a/drivers/mtd/nand/nand_ids.c b/drivers/mtd/nand/nand_ids.c
index 9c61238..e3aa274 100644
--- a/drivers/mtd/nand/nand_ids.c
+++ b/drivers/mtd/nand/nand_ids.c
@@ -22,51 +22,49 @@
* 512 512 Byte page size
*/
struct nand_flash_dev nand_flash_ids[] = {
-#define SP_OPTIONS NAND_NEED_READRDY
-#define SP_OPTIONS16 (SP_OPTIONS | NAND_BUSWIDTH_16)
#ifdef CONFIG_MTD_NAND_MUSEUM_IDS
- {"NAND 1MiB 5V 8-bit", 0x6e, 256, 1, 0x1000, SP_OPTIONS},
- {"NAND 2MiB 5V 8-bit", 0x64, 256, 2, 0x1000, SP_OPTIONS},
- {"NAND 4MiB 5V 8-bit", 0x6b, 512, 4, 0x2000, SP_OPTIONS},
- {"NAND 1MiB 3,3V 8-bit", 0xe8, 256, 1, 0x1000, SP_OPTIONS},
- {"NAND 1MiB 3,3V 8-bit", 0xec, 256, 1, 0x1000, SP_OPTIONS},
- {"NAND 2MiB 3,3V 8-bit", 0xea, 256, 2, 0x1000, SP_OPTIONS},
- {"NAND 4MiB 3,3V 8-bit", 0xd5, 512, 4, 0x2000, SP_OPTIONS},
- {"NAND 4MiB 3,3V 8-bit", 0xe3, 512, 4, 0x2000, SP_OPTIONS},
- {"NAND 4MiB 3,3V 8-bit", 0xe5, 512, 4, 0x2000, SP_OPTIONS},
- {"NAND 8MiB 3,3V 8-bit", 0xd6, 512, 8, 0x2000, SP_OPTIONS},
-
- {"NAND 8MiB 1,8V 8-bit", 0x39, 512, 8, 0x2000, SP_OPTIONS},
- {"NAND 8MiB 3,3V 8-bit", 0xe6, 512, 8, 0x2000, SP_OPTIONS},
- {"NAND 8MiB 1,8V 16-bit", 0x49, 512, 8, 0x2000, SP_OPTIONS16},
- {"NAND 8MiB 3,3V 16-bit", 0x59, 512, 8, 0x2000, SP_OPTIONS16},
+ {"NAND 1MiB 5V 8-bit", 0x6e, 256, 1, 0x1000, 0},
+ {"NAND 2MiB 5V 8-bit", 0x64, 256, 2, 0x1000, 0},
+ {"NAND 4MiB 5V 8-bit", 0x6b, 512, 4, 0x2000, 0},
+ {"NAND 1MiB 3,3V 8-bit", 0xe8, 256, 1, 0x1000, 0},
+ {"NAND 1MiB 3,3V 8-bit", 0xec, 256, 1, 0x1000, 0},
+ {"NAND 2MiB 3,3V 8-bit", 0xea, 256, 2, 0x1000, 0},
+ {"NAND 4MiB 3,3V 8-bit", 0xd5, 512, 4, 0x2000, 0},
+ {"NAND 4MiB 3,3V 8-bit", 0xe3, 512, 4, 0x2000, 0},
+ {"NAND 4MiB 3,3V 8-bit", 0xe5, 512, 4, 0x2000, 0},
+ {"NAND 8MiB 3,3V 8-bit", 0xd6, 512, 8, 0x2000, 0},
+
+ {"NAND 8MiB 1,8V 8-bit", 0x39, 512, 8, 0x2000, 0},
+ {"NAND 8MiB 3,3V 8-bit", 0xe6, 512, 8, 0x2000, 0},
+ {"NAND 8MiB 1,8V 16-bit", 0x49, 512, 8, 0x2000, NAND_BUSWIDTH_16},
+ {"NAND 8MiB 3,3V 16-bit", 0x59, 512, 8, 0x2000, NAND_BUSWIDTH_16},
#endif
- {"NAND 16MiB 1,8V 8-bit", 0x33, 512, 16, 0x4000, SP_OPTIONS},
- {"NAND 16MiB 3,3V 8-bit", 0x73, 512, 16, 0x4000, SP_OPTIONS},
- {"NAND 16MiB 1,8V 16-bit", 0x43, 512, 16, 0x4000, SP_OPTIONS16},
- {"NAND 16MiB 3,3V 16-bit", 0x53, 512, 16, 0x4000, SP_OPTIONS16},
-
- {"NAND 32MiB 1,8V 8-bit", 0x35, 512, 32, 0x4000, SP_OPTIONS},
- {"NAND 32MiB 3,3V 8-bit", 0x75, 512, 32, 0x4000, SP_OPTIONS},
- {"NAND 32MiB 1,8V 16-bit", 0x45, 512, 32, 0x4000, SP_OPTIONS16},
- {"NAND 32MiB 3,3V 16-bit", 0x55, 512, 32, 0x4000, SP_OPTIONS16},
-
- {"NAND 64MiB 1,8V 8-bit", 0x36, 512, 64, 0x4000, SP_OPTIONS},
- {"NAND 64MiB 3,3V 8-bit", 0x76, 512, 64, 0x4000, SP_OPTIONS},
- {"NAND 64MiB 1,8V 16-bit", 0x46, 512, 64, 0x4000, SP_OPTIONS16},
- {"NAND 64MiB 3,3V 16-bit", 0x56, 512, 64, 0x4000, SP_OPTIONS16},
-
- {"NAND 128MiB 1,8V 8-bit", 0x78, 512, 128, 0x4000, SP_OPTIONS},
- {"NAND 128MiB 1,8V 8-bit", 0x39, 512, 128, 0x4000, SP_OPTIONS},
- {"NAND 128MiB 3,3V 8-bit", 0x79, 512, 128, 0x4000, SP_OPTIONS},
- {"NAND 128MiB 1,8V 16-bit", 0x72, 512, 128, 0x4000, SP_OPTIONS16},
- {"NAND 128MiB 1,8V 16-bit", 0x49, 512, 128, 0x4000, SP_OPTIONS16},
- {"NAND 128MiB 3,3V 16-bit", 0x74, 512, 128, 0x4000, SP_OPTIONS16},
- {"NAND 128MiB 3,3V 16-bit", 0x59, 512, 128, 0x4000, SP_OPTIONS16},
-
- {"NAND 256MiB 3,3V 8-bit", 0x71, 512, 256, 0x4000, SP_OPTIONS},
+ {"NAND 16MiB 1,8V 8-bit", 0x33, 512, 16, 0x4000, 0},
+ {"NAND 16MiB 3,3V 8-bit", 0x73, 512, 16, 0x4000, 0},
+ {"NAND 16MiB 1,8V 16-bit", 0x43, 512, 16, 0x4000, NAND_BUSWIDTH_16},
+ {"NAND 16MiB 3,3V 16-bit", 0x53, 512, 16, 0x4000, NAND_BUSWIDTH_16},
+
+ {"NAND 32MiB 1,8V 8-bit", 0x35, 512, 32, 0x4000, 0},
+ {"NAND 32MiB 3,3V 8-bit", 0x75, 512, 32, 0x4000, 0},
+ {"NAND 32MiB 1,8V 16-bit", 0x45, 512, 32, 0x4000, NAND_BUSWIDTH_16},
+ {"NAND 32MiB 3,3V 16-bit", 0x55, 512, 32, 0x4000, NAND_BUSWIDTH_16},
+
+ {"NAND 64MiB 1,8V 8-bit", 0x36, 512, 64, 0x4000, 0},
+ {"NAND 64MiB 3,3V 8-bit", 0x76, 512, 64, 0x4000, 0},
+ {"NAND 64MiB 1,8V 16-bit", 0x46, 512, 64, 0x4000, NAND_BUSWIDTH_16},
+ {"NAND 64MiB 3,3V 16-bit", 0x56, 512, 64, 0x4000, NAND_BUSWIDTH_16},
+
+ {"NAND 128MiB 1,8V 8-bit", 0x78, 512, 128, 0x4000, 0},
+ {"NAND 128MiB 1,8V 8-bit", 0x39, 512, 128, 0x4000, 0},
+ {"NAND 128MiB 3,3V 8-bit", 0x79, 512, 128, 0x4000, 0},
+ {"NAND 128MiB 1,8V 16-bit", 0x72, 512, 128, 0x4000, NAND_BUSWIDTH_16},
+ {"NAND 128MiB 1,8V 16-bit", 0x49, 512, 128, 0x4000, NAND_BUSWIDTH_16},
+ {"NAND 128MiB 3,3V 16-bit", 0x74, 512, 128, 0x4000, NAND_BUSWIDTH_16},
+ {"NAND 128MiB 3,3V 16-bit", 0x59, 512, 128, 0x4000, NAND_BUSWIDTH_16},
+
+ {"NAND 256MiB 3,3V 8-bit", 0x71, 512, 256, 0x4000, 0},
/*
* These are the new chips with large page size. The pagesize and the
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 0052e52..6a70184 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -164,7 +164,6 @@ config VXLAN
config NETCONSOLE
tristate "Network console logging support"
- depends on !PREEMPT_RT_FULL
---help---
If you want to log kernel messages over the network, enable this.
See <file:Documentation/networking/netconsole.txt> for details.
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 045dc53..b7d45f3 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -1728,8 +1728,6 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
bond_compute_features(bond);
- bond_update_speed_duplex(new_slave);
-
read_lock(&bond->lock);
new_slave->last_arp_rx = jiffies -
@@ -1782,6 +1780,8 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
new_slave->link == BOND_LINK_DOWN ? "DOWN" :
(new_slave->link == BOND_LINK_UP ? "UP" : "BACK"));
+ bond_update_speed_duplex(new_slave);
+
if (USES_PRIMARY(bond->params.mode) && bond->params.primary[0]) {
/* if there is a primary slave, remember it */
if (strcmp(bond->params.primary, new_slave->dev->name) == 0) {
@@ -1888,7 +1888,6 @@ err_detach:
write_unlock_bh(&bond->lock);
err_close:
- slave_dev->priv_flags &= ~IFF_BONDING;
dev_close(slave_dev);
err_unset_master:
@@ -1944,6 +1943,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
}
block_netpoll_tx();
+ call_netdevice_notifiers(NETDEV_RELEASE, bond_dev);
write_lock_bh(&bond->lock);
slave = bond_get_slave_by_dev(bond, slave_dev);
@@ -1956,11 +1956,12 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
return -EINVAL;
}
- write_unlock_bh(&bond->lock);
/* unregister rx_handler early so bond_handle_frame wouldn't be called
* for this slave anymore.
*/
netdev_rx_handler_unregister(slave_dev);
+ write_unlock_bh(&bond->lock);
+ synchronize_net();
write_lock_bh(&bond->lock);
if (!bond->params.fail_over_mac) {
@@ -2046,10 +2047,8 @@ 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) {
+ if (bond->slave_cnt == 0)
call_netdevice_notifiers(NETDEV_CHANGEADDR, bond->dev);
- call_netdevice_notifiers(NETDEV_RELEASE, bond->dev);
- }
bond_compute_features(bond);
if (!(bond_dev->features & NETIF_F_VLAN_CHALLENGED) &&
@@ -2463,6 +2462,8 @@ static void bond_miimon_commit(struct bonding *bond)
bond_set_backup_slave(slave);
}
+ bond_update_speed_duplex(slave);
+
pr_info("%s: link status definitely up for interface %s, %u Mbps %s duplex.\n",
bond->dev->name, slave->dev->name,
slave->speed, slave->duplex ? "full" : "half");
@@ -3380,22 +3381,20 @@ static int bond_xmit_hash_policy_l2(struct sk_buff *skb, int count)
*/
static int bond_xmit_hash_policy_l23(struct sk_buff *skb, int count)
{
- const struct ethhdr *data;
- const struct iphdr *iph;
- const struct ipv6hdr *ipv6h;
+ struct ethhdr *data = (struct ethhdr *)skb->data;
+ struct iphdr *iph;
+ struct ipv6hdr *ipv6h;
u32 v6hash;
- const __be32 *s, *d;
+ __be32 *s, *d;
if (skb->protocol == htons(ETH_P_IP) &&
- pskb_network_may_pull(skb, sizeof(*iph))) {
+ skb_network_header_len(skb) >= sizeof(*iph)) {
iph = ip_hdr(skb);
- data = (struct ethhdr *)skb->data;
return ((ntohl(iph->saddr ^ iph->daddr) & 0xffff) ^
(data->h_dest[5] ^ data->h_source[5])) % count;
} else if (skb->protocol == htons(ETH_P_IPV6) &&
- pskb_network_may_pull(skb, sizeof(*ipv6h))) {
+ skb_network_header_len(skb) >= sizeof(*ipv6h)) {
ipv6h = ipv6_hdr(skb);
- data = (struct ethhdr *)skb->data;
s = &ipv6h->saddr.s6_addr32[0];
d = &ipv6h->daddr.s6_addr32[0];
v6hash = (s[1] ^ d[1]) ^ (s[2] ^ d[2]) ^ (s[3] ^ d[3]);
@@ -3414,36 +3413,33 @@ static int bond_xmit_hash_policy_l23(struct sk_buff *skb, int count)
static int bond_xmit_hash_policy_l34(struct sk_buff *skb, int count)
{
u32 layer4_xor = 0;
- const struct iphdr *iph;
- const struct ipv6hdr *ipv6h;
- const __be32 *s, *d;
- const __be16 *l4 = NULL;
- __be16 _l4[2];
- int noff = skb_network_offset(skb);
- int poff;
+ struct iphdr *iph;
+ struct ipv6hdr *ipv6h;
+ __be32 *s, *d;
+ __be16 *layer4hdr;
if (skb->protocol == htons(ETH_P_IP) &&
- pskb_may_pull(skb, noff + sizeof(*iph))) {
+ skb_network_header_len(skb) >= sizeof(*iph)) {
iph = ip_hdr(skb);
- poff = proto_ports_offset(iph->protocol);
-
- if (!ip_is_fragment(iph) && poff >= 0) {
- l4 = skb_header_pointer(skb, noff + (iph->ihl << 2) + poff,
- sizeof(_l4), &_l4);
- if (l4)
- layer4_xor = ntohs(l4[0] ^ l4[1]);
+ if (!ip_is_fragment(iph) &&
+ (iph->protocol == IPPROTO_TCP ||
+ iph->protocol == IPPROTO_UDP) &&
+ (skb_headlen(skb) - skb_network_offset(skb) >=
+ iph->ihl * sizeof(u32) + sizeof(*layer4hdr) * 2)) {
+ layer4hdr = (__be16 *)((u32 *)iph + iph->ihl);
+ layer4_xor = ntohs(*layer4hdr ^ *(layer4hdr + 1));
}
return (layer4_xor ^
((ntohl(iph->saddr ^ iph->daddr)) & 0xffff)) % count;
} else if (skb->protocol == htons(ETH_P_IPV6) &&
- pskb_may_pull(skb, noff + sizeof(*ipv6h))) {
+ skb_network_header_len(skb) >= sizeof(*ipv6h)) {
ipv6h = ipv6_hdr(skb);
- poff = proto_ports_offset(ipv6h->nexthdr);
- if (poff >= 0) {
- l4 = skb_header_pointer(skb, noff + sizeof(*ipv6h) + poff,
- sizeof(_l4), &_l4);
- if (l4)
- layer4_xor = ntohs(l4[0] ^ l4[1]);
+ if ((ipv6h->nexthdr == IPPROTO_TCP ||
+ ipv6h->nexthdr == IPPROTO_UDP) &&
+ (skb_headlen(skb) - skb_network_offset(skb) >=
+ sizeof(*ipv6h) + sizeof(*layer4hdr) * 2)) {
+ layer4hdr = (__be16 *)(ipv6h + 1);
+ layer4_xor = ntohs(*layer4hdr ^ *(layer4hdr + 1));
}
s = &ipv6h->saddr.s6_addr32[0];
d = &ipv6h->daddr.s6_addr32[0];
@@ -4925,18 +4921,9 @@ static int __net_init bond_net_init(struct net *net)
static void __net_exit bond_net_exit(struct net *net)
{
struct bond_net *bn = net_generic(net, bond_net_id);
- struct bonding *bond, *tmp_bond;
- LIST_HEAD(list);
bond_destroy_sysfs(bn);
bond_destroy_proc_dir(bn);
-
- /* Kill off any bonds created after unregistering bond rtnl ops */
- rtnl_lock();
- list_for_each_entry_safe(bond, tmp_bond, &bn->dev_list, bond_list)
- unregister_netdevice_queue(bond->dev, &list);
- unregister_netdevice_many(&list);
- rtnl_unlock();
}
static struct pernet_operations bond_net_ops = {
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index ea7a388..1c9e09f 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -183,11 +183,6 @@ int bond_create_slave_symlinks(struct net_device *master,
sprintf(linkname, "slave_%s", slave->name);
ret = sysfs_create_link(&(master->dev.kobj), &(slave->dev.kobj),
linkname);
-
- /* free the master link created earlier in case of error */
- if (ret)
- sysfs_remove_link(&(slave->dev.kobj), "master");
-
return ret;
}
@@ -527,7 +522,7 @@ static ssize_t bonding_store_arp_interval(struct device *d,
goto out;
}
if (new_value < 0) {
- pr_err("%s: Invalid arp_interval value %d not in range 0-%d; rejected.\n",
+ pr_err("%s: Invalid arp_interval value %d not in range 1-%d; rejected.\n",
bond->dev->name, new_value, INT_MAX);
ret = -EINVAL;
goto out;
@@ -542,15 +537,14 @@ static ssize_t bonding_store_arp_interval(struct device *d,
pr_info("%s: Setting ARP monitoring interval to %d.\n",
bond->dev->name, new_value);
bond->params.arp_interval = new_value;
- if (new_value) {
- if (bond->params.miimon) {
- pr_info("%s: ARP monitoring cannot be used with MII monitoring. %s Disabling MII monitoring.\n",
- bond->dev->name, bond->dev->name);
- bond->params.miimon = 0;
- }
- if (!bond->params.arp_targets[0])
- pr_info("%s: ARP monitoring has been set up, but no ARP targets have been specified.\n",
- bond->dev->name);
+ if (bond->params.miimon) {
+ pr_info("%s: ARP monitoring cannot be used with MII monitoring. %s Disabling MII monitoring.\n",
+ bond->dev->name, bond->dev->name);
+ bond->params.miimon = 0;
+ }
+ if (!bond->params.arp_targets[0]) {
+ pr_info("%s: ARP monitoring has been set up, but no ARP targets have been specified.\n",
+ bond->dev->name);
}
if (bond->dev->flags & IFF_UP) {
/* If the interface is up, we may need to fire off
@@ -558,13 +552,10 @@ static ssize_t bonding_store_arp_interval(struct device *d,
* timer will get fired off when the open function
* is called.
*/
- if (!new_value) {
- cancel_delayed_work_sync(&bond->arp_work);
- } else {
- cancel_delayed_work_sync(&bond->mii_work);
- queue_delayed_work(bond->wq, &bond->arp_work, 0);
- }
+ cancel_delayed_work_sync(&bond->mii_work);
+ queue_delayed_work(bond->wq, &bond->arp_work, 0);
}
+
out:
rtnl_unlock();
return ret;
@@ -706,7 +697,7 @@ static ssize_t bonding_store_downdelay(struct device *d,
}
if (new_value < 0) {
pr_err("%s: Invalid down delay value %d not in range %d-%d; rejected.\n",
- bond->dev->name, new_value, 0, INT_MAX);
+ bond->dev->name, new_value, 1, INT_MAX);
ret = -EINVAL;
goto out;
} else {
@@ -761,8 +752,8 @@ static ssize_t bonding_store_updelay(struct device *d,
goto out;
}
if (new_value < 0) {
- pr_err("%s: Invalid up delay value %d not in range %d-%d; rejected.\n",
- bond->dev->name, new_value, 0, INT_MAX);
+ pr_err("%s: Invalid down delay value %d not in range %d-%d; rejected.\n",
+ bond->dev->name, new_value, 1, INT_MAX);
ret = -EINVAL;
goto out;
} else {
@@ -972,37 +963,37 @@ static ssize_t bonding_store_miimon(struct device *d,
}
if (new_value < 0) {
pr_err("%s: Invalid miimon value %d not in range %d-%d; rejected.\n",
- bond->dev->name, new_value, 0, INT_MAX);
+ bond->dev->name, new_value, 1, INT_MAX);
ret = -EINVAL;
goto out;
- }
- pr_info("%s: Setting MII monitoring interval to %d.\n",
- bond->dev->name, new_value);
- bond->params.miimon = new_value;
- if (bond->params.updelay)
- pr_info("%s: Note: Updating updelay (to %d) since it is a multiple of the miimon value.\n",
- bond->dev->name,
- bond->params.updelay * bond->params.miimon);
- if (bond->params.downdelay)
- pr_info("%s: Note: Updating downdelay (to %d) since it is a multiple of the miimon value.\n",
- bond->dev->name,
- bond->params.downdelay * bond->params.miimon);
- if (new_value && bond->params.arp_interval) {
- pr_info("%s: MII monitoring cannot be used with ARP monitoring. Disabling ARP monitoring...\n",
- bond->dev->name);
- bond->params.arp_interval = 0;
- if (bond->params.arp_validate)
- bond->params.arp_validate = BOND_ARP_VALIDATE_NONE;
- }
- if (bond->dev->flags & IFF_UP) {
- /* If the interface is up, we may need to fire off
- * the MII timer. If the interface is down, the
- * timer will get fired off when the open function
- * is called.
- */
- if (!new_value) {
- cancel_delayed_work_sync(&bond->mii_work);
- } else {
+ } else {
+ pr_info("%s: Setting MII monitoring interval to %d.\n",
+ bond->dev->name, new_value);
+ bond->params.miimon = new_value;
+ if (bond->params.updelay)
+ pr_info("%s: Note: Updating updelay (to %d) since it is a multiple of the miimon value.\n",
+ bond->dev->name,
+ bond->params.updelay * bond->params.miimon);
+ if (bond->params.downdelay)
+ pr_info("%s: Note: Updating downdelay (to %d) since it is a multiple of the miimon value.\n",
+ bond->dev->name,
+ bond->params.downdelay * bond->params.miimon);
+ if (bond->params.arp_interval) {
+ pr_info("%s: MII monitoring cannot be used with ARP monitoring. Disabling ARP monitoring...\n",
+ bond->dev->name);
+ bond->params.arp_interval = 0;
+ if (bond->params.arp_validate) {
+ bond->params.arp_validate =
+ BOND_ARP_VALIDATE_NONE;
+ }
+ }
+
+ if (bond->dev->flags & IFF_UP) {
+ /* If the interface is up, we may need to fire off
+ * the MII timer. If the interface is down, the
+ * timer will get fired off when the open function
+ * is called.
+ */
cancel_delayed_work_sync(&bond->arp_work);
queue_delayed_work(bond->wq, &bond->mii_work, 0);
}
diff --git a/drivers/net/can/mcp251x.c b/drivers/net/can/mcp251x.c
index 42b6d69..5eaf47b 100644
--- a/drivers/net/can/mcp251x.c
+++ b/drivers/net/can/mcp251x.c
@@ -922,7 +922,6 @@ static int mcp251x_open(struct net_device *net)
struct mcp251x_priv *priv = netdev_priv(net);
struct spi_device *spi = priv->spi;
struct mcp251x_platform_data *pdata = spi->dev.platform_data;
- unsigned long flags;
int ret;
ret = open_candev(net);
@@ -939,14 +938,9 @@ static int mcp251x_open(struct net_device *net)
priv->tx_skb = NULL;
priv->tx_len = 0;
- flags = IRQF_ONESHOT;
- if (pdata->irq_flags)
- flags |= pdata->irq_flags;
- else
- flags |= IRQF_TRIGGER_FALLING;
-
ret = request_threaded_irq(spi->irq, NULL, mcp251x_can_ist,
- flags, DEVICE_NAME, priv);
+ pdata->irq_flags ? pdata->irq_flags : IRQF_TRIGGER_FALLING,
+ DEVICE_NAME, priv);
if (ret) {
dev_err(&spi->dev, "failed to acquire irq %d\n", spi->irq);
if (pdata->transceiver_enable)
diff --git a/drivers/net/can/sja1000/plx_pci.c b/drivers/net/can/sja1000/plx_pci.c
index 08a606c..11d1062 100644
--- a/drivers/net/can/sja1000/plx_pci.c
+++ b/drivers/net/can/sja1000/plx_pci.c
@@ -348,7 +348,7 @@ static inline int plx_pci_check_sja1000(const struct sja1000_priv *priv)
*/
if ((priv->read_reg(priv, REG_CR) & REG_CR_BASICCAN_INITIAL_MASK) ==
REG_CR_BASICCAN_INITIAL &&
- (priv->read_reg(priv, SJA1000_REG_SR) == REG_SR_BASICCAN_INITIAL) &&
+ (priv->read_reg(priv, REG_SR) == REG_SR_BASICCAN_INITIAL) &&
(priv->read_reg(priv, REG_IR) == REG_IR_BASICCAN_INITIAL))
flag = 1;
@@ -360,7 +360,7 @@ static inline int plx_pci_check_sja1000(const struct sja1000_priv *priv)
* See states on p. 23 of the Datasheet.
*/
if (priv->read_reg(priv, REG_MOD) == REG_MOD_PELICAN_INITIAL &&
- priv->read_reg(priv, SJA1000_REG_SR) == REG_SR_PELICAN_INITIAL &&
+ priv->read_reg(priv, REG_SR) == REG_SR_PELICAN_INITIAL &&
priv->read_reg(priv, REG_IR) == REG_IR_PELICAN_INITIAL)
return flag;
diff --git a/drivers/net/can/sja1000/sja1000.c b/drivers/net/can/sja1000/sja1000.c
index 43921f9..83ee11e 100644
--- a/drivers/net/can/sja1000/sja1000.c
+++ b/drivers/net/can/sja1000/sja1000.c
@@ -91,7 +91,7 @@ static void sja1000_write_cmdreg(struct sja1000_priv *priv, u8 val)
*/
spin_lock_irqsave(&priv->cmdreg_lock, flags);
priv->write_reg(priv, REG_CMR, val);
- priv->read_reg(priv, SJA1000_REG_SR);
+ priv->read_reg(priv, REG_SR);
spin_unlock_irqrestore(&priv->cmdreg_lock, flags);
}
@@ -499,7 +499,7 @@ irqreturn_t sja1000_interrupt(int irq, void *dev_id)
while ((isrc = priv->read_reg(priv, REG_IR)) && (n < SJA1000_MAX_IRQ)) {
n++;
- status = priv->read_reg(priv, SJA1000_REG_SR);
+ status = priv->read_reg(priv, REG_SR);
/* check for absent controller due to hw unplug */
if (status == 0xFF && sja1000_is_absent(priv))
return IRQ_NONE;
@@ -526,7 +526,7 @@ irqreturn_t sja1000_interrupt(int irq, void *dev_id)
/* receive interrupt */
while (status & SR_RBS) {
sja1000_rx(dev);
- status = priv->read_reg(priv, SJA1000_REG_SR);
+ status = priv->read_reg(priv, REG_SR);
/* check for absent controller */
if (status == 0xFF && sja1000_is_absent(priv))
return IRQ_NONE;
diff --git a/drivers/net/can/sja1000/sja1000.h b/drivers/net/can/sja1000/sja1000.h
index aa48e05..afa9984 100644
--- a/drivers/net/can/sja1000/sja1000.h
+++ b/drivers/net/can/sja1000/sja1000.h
@@ -56,7 +56,7 @@
/* SJA1000 registers - manual section 6.4 (Pelican Mode) */
#define REG_MOD 0x00
#define REG_CMR 0x01
-#define SJA1000_REG_SR 0x02
+#define REG_SR 0x02
#define REG_IR 0x03
#define REG_IER 0x04
#define REG_ALC 0x0B
diff --git a/drivers/net/can/sja1000/sja1000_of_platform.c b/drivers/net/can/sja1000/sja1000_of_platform.c
index 8e0c4a0..6433b81 100644
--- a/drivers/net/can/sja1000/sja1000_of_platform.c
+++ b/drivers/net/can/sja1000/sja1000_of_platform.c
@@ -96,8 +96,8 @@ static int sja1000_ofp_probe(struct platform_device *ofdev)
struct net_device *dev;
struct sja1000_priv *priv;
struct resource res;
- u32 prop;
- int err, irq, res_size;
+ const u32 *prop;
+ int err, irq, res_size, prop_size;
void __iomem *base;
err = of_address_to_resource(np, 0, &res);
@@ -138,27 +138,27 @@ static int sja1000_ofp_probe(struct platform_device *ofdev)
priv->read_reg = sja1000_ofp_read_reg;
priv->write_reg = sja1000_ofp_write_reg;
- err = of_property_read_u32(np, "nxp,external-clock-frequency", &prop);
- if (!err)
- priv->can.clock.freq = prop / 2;
+ prop = of_get_property(np, "nxp,external-clock-frequency", &prop_size);
+ if (prop && (prop_size == sizeof(u32)))
+ priv->can.clock.freq = *prop / 2;
else
priv->can.clock.freq = SJA1000_OFP_CAN_CLOCK; /* default */
- err = of_property_read_u32(np, "nxp,tx-output-mode", &prop);
- if (!err)
- priv->ocr |= prop & OCR_MODE_MASK;
+ prop = of_get_property(np, "nxp,tx-output-mode", &prop_size);
+ if (prop && (prop_size == sizeof(u32)))
+ priv->ocr |= *prop & OCR_MODE_MASK;
else
priv->ocr |= OCR_MODE_NORMAL; /* default */
- err = of_property_read_u32(np, "nxp,tx-output-config", &prop);
- if (!err)
- priv->ocr |= (prop << OCR_TX_SHIFT) & OCR_TX_MASK;
+ prop = of_get_property(np, "nxp,tx-output-config", &prop_size);
+ if (prop && (prop_size == sizeof(u32)))
+ priv->ocr |= (*prop << OCR_TX_SHIFT) & OCR_TX_MASK;
else
priv->ocr |= OCR_TX0_PULLDOWN; /* default */
- err = of_property_read_u32(np, "nxp,clock-out-frequency", &prop);
- if (!err && prop) {
- u32 divider = priv->can.clock.freq * 2 / prop;
+ prop = of_get_property(np, "nxp,clock-out-frequency", &prop_size);
+ if (prop && (prop_size == sizeof(u32)) && *prop) {
+ u32 divider = priv->can.clock.freq * 2 / *prop;
if (divider > 1)
priv->cdr |= divider / 2 - 1;
@@ -168,7 +168,8 @@ static int sja1000_ofp_probe(struct platform_device *ofdev)
priv->cdr |= CDR_CLK_OFF; /* default */
}
- if (!of_property_read_bool(np, "nxp,no-comparator-bypass"))
+ prop = of_get_property(np, "nxp,no-comparator-bypass", NULL);
+ if (!prop)
priv->cdr |= CDR_CBP; /* default */
priv->irq_flags = IRQF_SHARED;
diff --git a/drivers/net/ethernet/3com/3c59x.c b/drivers/net/ethernet/3com/3c59x.c
index 0da3917..ed0feb3 100644
--- a/drivers/net/ethernet/3com/3c59x.c
+++ b/drivers/net/ethernet/3com/3c59x.c
@@ -843,9 +843,9 @@ static void poll_vortex(struct net_device *dev)
{
struct vortex_private *vp = netdev_priv(dev);
unsigned long flags;
- local_irq_save_nort(flags);
+ local_irq_save(flags);
(vp->full_bus_master_rx ? boomerang_interrupt:vortex_interrupt)(dev->irq,dev);
- local_irq_restore_nort(flags);
+ local_irq_restore(flags);
}
#endif
@@ -1919,12 +1919,12 @@ static void vortex_tx_timeout(struct net_device *dev)
* Block interrupts because vortex_interrupt does a bare spin_lock()
*/
unsigned long flags;
- local_irq_save_nort(flags);
+ local_irq_save(flags);
if (vp->full_bus_master_tx)
boomerang_interrupt(dev->irq, dev);
else
vortex_interrupt(dev->irq, dev);
- local_irq_restore_nort(flags);
+ local_irq_restore(flags);
}
}
diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
index dbe44ba..0035c01 100644
--- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
+++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
@@ -2075,7 +2075,7 @@ static int atl1c_tx_map(struct atl1c_adapter *adapter,
if (unlikely(pci_dma_mapping_error(adapter->pdev,
buffer_info->dma)))
goto err_dma;
- ATL1C_SET_BUFFER_STATE(buffer_info, ATL1C_BUFFER_BUSY);
+
ATL1C_SET_PCIMAP_TYPE(buffer_info, ATL1C_PCIMAP_SINGLE,
ATL1C_PCIMAP_TODEVICE);
mapped_len += map_len;
@@ -2171,7 +2171,11 @@ static netdev_tx_t atl1c_xmit_frame(struct sk_buff *skb,
}
tpd_req = atl1c_cal_tpd_req(skb);
- spin_lock_irqsave(&adapter->tx_lock, flags);
+ if (!spin_trylock_irqsave(&adapter->tx_lock, flags)) {
+ if (netif_msg_pktdata(adapter))
+ dev_info(&adapter->pdev->dev, "tx locked\n");
+ return NETDEV_TX_LOCKED;
+ }
if (atl1c_tpd_avail(adapter, type) < tpd_req) {
/* no enough descriptor, just stop queue */
diff --git a/drivers/net/ethernet/atheros/atl1e/atl1e.h b/drivers/net/ethernet/atheros/atl1e/atl1e.h
index b5fd934..829b5ad 100644
--- a/drivers/net/ethernet/atheros/atl1e/atl1e.h
+++ b/drivers/net/ethernet/atheros/atl1e/atl1e.h
@@ -186,7 +186,7 @@ struct atl1e_tpd_desc {
/* how about 0x2000 */
#define MAX_TX_BUF_LEN 0x2000
#define MAX_TX_BUF_SHIFT 13
-#define MAX_TSO_SEG_SIZE 0x3c00
+/*#define MAX_TX_BUF_LEN 0x3000 */
/* rrs word 1 bit 0:31 */
#define RRS_RX_CSUM_MASK 0xFFFF
@@ -438,6 +438,7 @@ struct atl1e_adapter {
struct atl1e_hw hw;
struct atl1e_hw_stats hw_stats;
+ bool have_msi;
u32 wol;
u16 link_speed;
u16 link_duplex;
diff --git a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c
index 7569f68..e4466a3 100644
--- a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c
+++ b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c
@@ -1803,7 +1803,8 @@ static netdev_tx_t atl1e_xmit_frame(struct sk_buff *skb,
return NETDEV_TX_OK;
}
tpd_req = atl1e_cal_tdp_req(skb);
- spin_lock_irqsave(&adapter->tx_lock, flags);
+ if (!spin_trylock_irqsave(&adapter->tx_lock, flags))
+ return NETDEV_TX_LOCKED;
if (atl1e_tpd_avail(adapter) < tpd_req) {
/* no enough descriptor, just stop queue */
@@ -1850,19 +1851,34 @@ static void atl1e_free_irq(struct atl1e_adapter *adapter)
struct net_device *netdev = adapter->netdev;
free_irq(adapter->pdev->irq, netdev);
+
+ if (adapter->have_msi)
+ pci_disable_msi(adapter->pdev);
}
static int atl1e_request_irq(struct atl1e_adapter *adapter)
{
struct pci_dev *pdev = adapter->pdev;
struct net_device *netdev = adapter->netdev;
+ int flags = 0;
int err = 0;
- err = request_irq(pdev->irq, atl1e_intr, IRQF_SHARED, netdev->name,
- netdev);
+ adapter->have_msi = true;
+ err = pci_enable_msi(pdev);
+ if (err) {
+ netdev_dbg(netdev,
+ "Unable to allocate MSI interrupt Error: %d\n", err);
+ adapter->have_msi = false;
+ }
+
+ if (!adapter->have_msi)
+ flags |= IRQF_SHARED;
+ err = request_irq(pdev->irq, atl1e_intr, flags, netdev->name, netdev);
if (err) {
netdev_dbg(adapter->netdev,
"Unable to allocate interrupt Error: %d\n", err);
+ if (adapter->have_msi)
+ pci_disable_msi(pdev);
return err;
}
netdev_dbg(netdev, "atl1e_request_irq OK\n");
@@ -2331,7 +2347,6 @@ static int atl1e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
INIT_WORK(&adapter->reset_task, atl1e_reset_task);
INIT_WORK(&adapter->link_chg_task, atl1e_link_chg_task);
- netif_set_gso_max_size(netdev, MAX_TSO_SEG_SIZE);
err = register_netdev(netdev);
if (err) {
netdev_err(netdev, "register netdevice failed\n");
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
index 3a73bb9..a5edac8 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
@@ -2523,7 +2523,6 @@ load_error2:
bp->port.pmf = 0;
load_error1:
bnx2x_napi_disable(bp);
- bnx2x_del_all_napi(bp);
/* clear pf_load status, as it was already set */
bnx2x_clear_pf_load(bp);
load_error0:
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h
index 937f5b5..b4d7b26 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h
@@ -456,9 +456,8 @@ struct bnx2x_fw_port_stats_old {
#define UPDATE_QSTAT(s, t) \
do { \
+ qstats->t##_hi = qstats_old->t##_hi + le32_to_cpu(s.hi); \
qstats->t##_lo = qstats_old->t##_lo + le32_to_cpu(s.lo); \
- qstats->t##_hi = qstats_old->t##_hi + le32_to_cpu(s.hi) \
- + ((qstats->t##_lo < qstats_old->t##_lo) ? 1 : 0); \
} while (0)
#define UPDATE_QSTAT_OLD(f) \
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index 6917998..bdb0869 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -330,7 +330,6 @@ static DEFINE_PCI_DEVICE_TABLE(tg3_pci_tbl) = {
{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5719)},
{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5720)},
{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57762)},
- {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57766)},
{PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9DXX)},
{PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9MXX)},
{PCI_DEVICE(PCI_VENDOR_ID_ALTIMA, PCI_DEVICE_ID_ALTIMA_AC1000)},
@@ -1844,8 +1843,6 @@ static void tg3_link_report(struct tg3 *tp)
tg3_ump_link_report(tp);
}
-
- tp->link_up = netif_carrier_ok(tp->dev);
}
static u16 tg3_advert_flowctrl_1000X(u8 flow_ctrl)
@@ -2499,6 +2496,12 @@ static int tg3_phy_reset_5703_4_5(struct tg3 *tp)
return err;
}
+static void tg3_carrier_on(struct tg3 *tp)
+{
+ netif_carrier_on(tp->dev);
+ tp->link_up = true;
+}
+
static void tg3_carrier_off(struct tg3 *tp)
{
netif_carrier_off(tp->dev);
@@ -2524,7 +2527,7 @@ static int tg3_phy_reset(struct tg3 *tp)
return -EBUSY;
if (netif_running(tp->dev) && tp->link_up) {
- netif_carrier_off(tp->dev);
+ tg3_carrier_off(tp);
tg3_link_report(tp);
}
@@ -4094,14 +4097,6 @@ static void tg3_phy_copper_begin(struct tg3 *tp)
tp->link_config.active_speed = tp->link_config.speed;
tp->link_config.active_duplex = tp->link_config.duplex;
- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714) {
- /* With autoneg disabled, 5715 only links up when the
- * advertisement register has the configured speed
- * enabled.
- */
- tg3_writephy(tp, MII_ADVERTISE, ADVERTISE_ALL);
- }
-
bmcr = 0;
switch (tp->link_config.speed) {
default:
@@ -4230,9 +4225,9 @@ static bool tg3_test_and_report_link_chg(struct tg3 *tp, int curr_link_up)
{
if (curr_link_up != tp->link_up) {
if (curr_link_up) {
- netif_carrier_on(tp->dev);
+ tg3_carrier_on(tp);
} else {
- netif_carrier_off(tp->dev);
+ tg3_carrier_off(tp);
if (tp->phy_flags & TG3_PHYFLG_MII_SERDES)
tp->phy_flags &= ~TG3_PHYFLG_PARALLEL_DETECT;
}
@@ -9104,14 +9099,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
}
if (GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_57765_AX) {
- u32 grc_mode;
-
- /* Fix transmit hangs */
- val = tr32(TG3_CPMU_PADRNG_CTL);
- val |= TG3_CPMU_PADRNG_CTL_RDIV2;
- tw32(TG3_CPMU_PADRNG_CTL, val);
-
- grc_mode = tr32(GRC_MODE);
+ u32 grc_mode = tr32(GRC_MODE);
/* Access the lower 1K of DL PCIE block registers. */
val = grc_mode & ~GRC_MODE_PCIE_PORT_MASK;
@@ -9421,14 +9409,6 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
if (tg3_flag(tp, PCI_EXPRESS))
rdmac_mode |= RDMAC_MODE_FIFO_LONG_BURST;
- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57766) {
- tp->dma_limit = 0;
- if (tp->dev->mtu <= ETH_DATA_LEN) {
- rdmac_mode |= RDMAC_MODE_JMB_2K_MMRR;
- tp->dma_limit = TG3_TX_BD_DMA_MAX_2K;
- }
- }
-
if (tg3_flag(tp, HW_TSO_1) ||
tg3_flag(tp, HW_TSO_2) ||
tg3_flag(tp, HW_TSO_3))
@@ -14419,11 +14399,8 @@ static void tg3_read_vpd(struct tg3 *tp)
if (j + len > block_end)
goto partno;
- if (len >= sizeof(tp->fw_ver))
- len = sizeof(tp->fw_ver) - 1;
- memset(tp->fw_ver, 0, sizeof(tp->fw_ver));
- snprintf(tp->fw_ver, sizeof(tp->fw_ver), "%.*s bc ", len,
- &vpd_data[j]);
+ memcpy(tp->fw_ver, &vpd_data[j], len);
+ strncat(tp->fw_ver, " bc ", vpdlen - len - 1);
}
partno:
diff --git a/drivers/net/ethernet/broadcom/tg3.h b/drivers/net/ethernet/broadcom/tg3.h
index 6f9b74c..d330e81 100644
--- a/drivers/net/ethernet/broadcom/tg3.h
+++ b/drivers/net/ethernet/broadcom/tg3.h
@@ -1159,8 +1159,6 @@
#define CPMU_MUTEX_GNT_DRIVER 0x00001000
#define TG3_CPMU_PHY_STRAP 0x00003664
#define TG3_CPMU_PHY_STRAP_IS_SERDES 0x00000020
-#define TG3_CPMU_PADRNG_CTL 0x00003668
-#define TG3_CPMU_PADRNG_CTL_RDIV2 0x00040000
/* 0x3664 --> 0x36b0 unused */
#define TG3_CPMU_EEE_MODE 0x000036b0
diff --git a/drivers/net/ethernet/chelsio/cxgb/sge.c b/drivers/net/ethernet/chelsio/cxgb/sge.c
index 1420ea8..d84872e 100644
--- a/drivers/net/ethernet/chelsio/cxgb/sge.c
+++ b/drivers/net/ethernet/chelsio/cxgb/sge.c
@@ -1666,7 +1666,8 @@ static int t1_sge_tx(struct sk_buff *skb, struct adapter *adapter,
struct cmdQ *q = &sge->cmdQ[qid];
unsigned int credits, pidx, genbit, count, use_sched_skb = 0;
- spin_lock(&q->lock);
+ if (!spin_trylock(&q->lock))
+ return NETDEV_TX_LOCKED;
reclaim_completed_tx(sge, q);
diff --git a/drivers/net/ethernet/davicom/dm9000.c b/drivers/net/ethernet/davicom/dm9000.c
index d67de83..c73472c 100644
--- a/drivers/net/ethernet/davicom/dm9000.c
+++ b/drivers/net/ethernet/davicom/dm9000.c
@@ -257,107 +257,6 @@ static void dm9000_dumpblk_32bit(void __iomem *reg, int count)
tmp = readl(reg);
}
-/*
- * Sleep, either by using msleep() or if we are suspending, then
- * use mdelay() to sleep.
- */
-static void dm9000_msleep(board_info_t *db, unsigned int ms)
-{
- if (db->in_suspend)
- mdelay(ms);
- else
- msleep(ms);
-}
-
-/* Read a word from phyxcer */
-static int
-dm9000_phy_read(struct net_device *dev, int phy_reg_unused, int reg)
-{
- board_info_t *db = netdev_priv(dev);
- unsigned long flags;
- unsigned int reg_save;
- int ret;
-
- mutex_lock(&db->addr_lock);
-
- spin_lock_irqsave(&db->lock, flags);
-
- /* Save previous register address */
- reg_save = readb(db->io_addr);
-
- /* Fill the phyxcer register into REG_0C */
- iow(db, DM9000_EPAR, DM9000_PHY | reg);
-
- /* Issue phyxcer read command */
- iow(db, DM9000_EPCR, EPCR_ERPRR | EPCR_EPOS);
-
- writeb(reg_save, db->io_addr);
- spin_unlock_irqrestore(&db->lock, flags);
-
- dm9000_msleep(db, 1); /* Wait read complete */
-
- spin_lock_irqsave(&db->lock, flags);
- reg_save = readb(db->io_addr);
-
- iow(db, DM9000_EPCR, 0x0); /* Clear phyxcer read command */
-
- /* The read data keeps on REG_0D & REG_0E */
- ret = (ior(db, DM9000_EPDRH) << 8) | ior(db, DM9000_EPDRL);
-
- /* restore the previous address */
- writeb(reg_save, db->io_addr);
- spin_unlock_irqrestore(&db->lock, flags);
-
- mutex_unlock(&db->addr_lock);
-
- dm9000_dbg(db, 5, "phy_read[%02x] -> %04x\n", reg, ret);
- return ret;
-}
-
-/* Write a word to phyxcer */
-static void
-dm9000_phy_write(struct net_device *dev,
- int phyaddr_unused, int reg, int value)
-{
- board_info_t *db = netdev_priv(dev);
- unsigned long flags;
- unsigned long reg_save;
-
- dm9000_dbg(db, 5, "phy_write[%02x] = %04x\n", reg, value);
- mutex_lock(&db->addr_lock);
-
- spin_lock_irqsave(&db->lock, flags);
-
- /* Save previous register address */
- reg_save = readb(db->io_addr);
-
- /* Fill the phyxcer register into REG_0C */
- iow(db, DM9000_EPAR, DM9000_PHY | reg);
-
- /* Fill the written data into REG_0D & REG_0E */
- iow(db, DM9000_EPDRL, value);
- iow(db, DM9000_EPDRH, value >> 8);
-
- /* Issue phyxcer write command */
- iow(db, DM9000_EPCR, EPCR_EPOS | EPCR_ERPRW);
-
- writeb(reg_save, db->io_addr);
- spin_unlock_irqrestore(&db->lock, flags);
-
- dm9000_msleep(db, 1); /* Wait write complete */
-
- spin_lock_irqsave(&db->lock, flags);
- reg_save = readb(db->io_addr);
-
- iow(db, DM9000_EPCR, 0x0); /* Clear phyxcer write command */
-
- /* restore the previous address */
- writeb(reg_save, db->io_addr);
-
- spin_unlock_irqrestore(&db->lock, flags);
- mutex_unlock(&db->addr_lock);
-}
-
/* dm9000_set_io
*
* select the specified set of io routines to use with the
@@ -895,9 +794,6 @@ dm9000_init_dm9000(struct net_device *dev)
iow(db, DM9000_GPCR, GPCR_GEP_CNTL); /* Let GPIO0 output */
- dm9000_phy_write(dev, 0, MII_BMCR, BMCR_RESET); /* PHY RESET */
- dm9000_phy_write(dev, 0, MII_DM_DSPCR, DSPCR_INIT_PARAM); /* Init */
-
ncr = (db->flags & DM9000_PLATF_EXT_PHY) ? NCR_EXT_PHY : 0;
/* if wol is needed, then always set NCR_WAKEEN otherwise we end
@@ -1304,6 +1200,109 @@ dm9000_open(struct net_device *dev)
return 0;
}
+/*
+ * Sleep, either by using msleep() or if we are suspending, then
+ * use mdelay() to sleep.
+ */
+static void dm9000_msleep(board_info_t *db, unsigned int ms)
+{
+ if (db->in_suspend)
+ mdelay(ms);
+ else
+ msleep(ms);
+}
+
+/*
+ * Read a word from phyxcer
+ */
+static int
+dm9000_phy_read(struct net_device *dev, int phy_reg_unused, int reg)
+{
+ board_info_t *db = netdev_priv(dev);
+ unsigned long flags;
+ unsigned int reg_save;
+ int ret;
+
+ mutex_lock(&db->addr_lock);
+
+ spin_lock_irqsave(&db->lock,flags);
+
+ /* Save previous register address */
+ reg_save = readb(db->io_addr);
+
+ /* Fill the phyxcer register into REG_0C */
+ iow(db, DM9000_EPAR, DM9000_PHY | reg);
+
+ iow(db, DM9000_EPCR, EPCR_ERPRR | EPCR_EPOS); /* Issue phyxcer read command */
+
+ writeb(reg_save, db->io_addr);
+ spin_unlock_irqrestore(&db->lock,flags);
+
+ dm9000_msleep(db, 1); /* Wait read complete */
+
+ spin_lock_irqsave(&db->lock,flags);
+ reg_save = readb(db->io_addr);
+
+ iow(db, DM9000_EPCR, 0x0); /* Clear phyxcer read command */
+
+ /* The read data keeps on REG_0D & REG_0E */
+ ret = (ior(db, DM9000_EPDRH) << 8) | ior(db, DM9000_EPDRL);
+
+ /* restore the previous address */
+ writeb(reg_save, db->io_addr);
+ spin_unlock_irqrestore(&db->lock,flags);
+
+ mutex_unlock(&db->addr_lock);
+
+ dm9000_dbg(db, 5, "phy_read[%02x] -> %04x\n", reg, ret);
+ return ret;
+}
+
+/*
+ * Write a word to phyxcer
+ */
+static void
+dm9000_phy_write(struct net_device *dev,
+ int phyaddr_unused, int reg, int value)
+{
+ board_info_t *db = netdev_priv(dev);
+ unsigned long flags;
+ unsigned long reg_save;
+
+ dm9000_dbg(db, 5, "phy_write[%02x] = %04x\n", reg, value);
+ mutex_lock(&db->addr_lock);
+
+ spin_lock_irqsave(&db->lock,flags);
+
+ /* Save previous register address */
+ reg_save = readb(db->io_addr);
+
+ /* Fill the phyxcer register into REG_0C */
+ iow(db, DM9000_EPAR, DM9000_PHY | reg);
+
+ /* Fill the written data into REG_0D & REG_0E */
+ iow(db, DM9000_EPDRL, value);
+ iow(db, DM9000_EPDRH, value >> 8);
+
+ iow(db, DM9000_EPCR, EPCR_EPOS | EPCR_ERPRW); /* Issue phyxcer write command */
+
+ writeb(reg_save, db->io_addr);
+ spin_unlock_irqrestore(&db->lock, flags);
+
+ dm9000_msleep(db, 1); /* Wait write complete */
+
+ spin_lock_irqsave(&db->lock,flags);
+ reg_save = readb(db->io_addr);
+
+ iow(db, DM9000_EPCR, 0x0); /* Clear phyxcer write command */
+
+ /* restore the previous address */
+ writeb(reg_save, db->io_addr);
+
+ spin_unlock_irqrestore(&db->lock, flags);
+ mutex_unlock(&db->addr_lock);
+}
+
static void
dm9000_shutdown(struct net_device *dev)
{
@@ -1502,12 +1501,7 @@ dm9000_probe(struct platform_device *pdev)
db->flags |= DM9000_PLATF_SIMPLE_PHY;
#endif
- /* Fixing bug on dm9000_probe, takeover dm9000_reset(db),
- * Need 'NCR_MAC_LBK' bit to indeed stable our DM9000 fifo
- * while probe stage.
- */
-
- iow(db, DM9000_NCR, NCR_MAC_LBK | NCR_RST);
+ dm9000_reset(db);
/* try multiple times, DM9000 sometimes gets the read wrong */
for (i = 0; i < 8; i++) {
diff --git a/drivers/net/ethernet/davicom/dm9000.h b/drivers/net/ethernet/davicom/dm9000.h
index 9ce058a..55688bd 100644
--- a/drivers/net/ethernet/davicom/dm9000.h
+++ b/drivers/net/ethernet/davicom/dm9000.h
@@ -69,9 +69,7 @@
#define NCR_WAKEEN (1<<6)
#define NCR_FCOL (1<<4)
#define NCR_FDX (1<<3)
-
-#define NCR_RESERVED (3<<1)
-#define NCR_MAC_LBK (1<<1)
+#define NCR_LBK (3<<1)
#define NCR_RST (1<<0)
#define NSR_SPEED (1<<7)
@@ -169,12 +167,5 @@
#define ISR_LNKCHNG (1<<5)
#define ISR_UNDERRUN (1<<4)
-/* Davicom MII registers.
- */
-
-#define MII_DM_DSPCR 0x1b /* DSP Control Register */
-
-#define DSPCR_INIT_PARAM 0xE100 /* DSP init parameter */
-
#endif /* _DM9000X_H_ */
diff --git a/drivers/net/ethernet/dec/tulip/tulip_core.c b/drivers/net/ethernet/dec/tulip/tulip_core.c
index d25961b..1e9443d 100644
--- a/drivers/net/ethernet/dec/tulip/tulip_core.c
+++ b/drivers/net/ethernet/dec/tulip/tulip_core.c
@@ -1943,7 +1943,6 @@ static void tulip_remove_one(struct pci_dev *pdev)
pci_iounmap(pdev, tp->base_addr);
free_netdev (dev);
pci_release_regions (pdev);
- pci_disable_device (pdev);
pci_set_drvdata (pdev, NULL);
/* pci_power_off (pdev, -1); */
diff --git a/drivers/net/ethernet/freescale/fec_ptp.c b/drivers/net/ethernet/freescale/fec_ptp.c
index 547c9f1..c40526c 100644
--- a/drivers/net/ethernet/freescale/fec_ptp.c
+++ b/drivers/net/ethernet/freescale/fec_ptp.c
@@ -128,7 +128,6 @@ void fec_ptp_start_cyclecounter(struct net_device *ndev)
spin_unlock_irqrestore(&fep->tmreg_lock, flags);
}
-EXPORT_SYMBOL(fec_ptp_start_cyclecounter);
/**
* fec_ptp_adjfreq - adjust ptp cycle frequency
@@ -319,7 +318,6 @@ int fec_ptp_ioctl(struct net_device *ndev, struct ifreq *ifr, int cmd)
return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ?
-EFAULT : 0;
}
-EXPORT_SYMBOL(fec_ptp_ioctl);
/**
* fec_time_keep - call timecounter_read every second to avoid timer overrun
@@ -383,4 +381,3 @@ void fec_ptp_init(struct net_device *ndev, struct platform_device *pdev)
pr_info("registered PHC device on %s\n", ndev->name);
}
}
-EXPORT_SYMBOL(fec_ptp_init);
diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c
index 5c53535..bffb2ed 100644
--- a/drivers/net/ethernet/freescale/gianfar.c
+++ b/drivers/net/ethernet/freescale/gianfar.c
@@ -1663,7 +1663,7 @@ void stop_gfar(struct net_device *dev)
/* Lock it down */
- local_irq_save_nort(flags);
+ local_irq_save(flags);
lock_tx_qs(priv);
lock_rx_qs(priv);
@@ -1671,7 +1671,7 @@ void stop_gfar(struct net_device *dev)
unlock_rx_qs(priv);
unlock_tx_qs(priv);
- local_irq_restore_nort(flags);
+ local_irq_restore(flags);
/* Free the IRQs */
if (priv->device_flags & FSL_GIANFAR_DEV_HAS_MULTI_INTR) {
@@ -2951,7 +2951,7 @@ static void adjust_link(struct net_device *dev)
struct phy_device *phydev = priv->phydev;
int new_state = 0;
- local_irq_save_nort(flags);
+ local_irq_save(flags);
lock_tx_qs(priv);
if (phydev->link) {
@@ -3020,7 +3020,7 @@ static void adjust_link(struct net_device *dev)
if (new_state && netif_msg_link(priv))
phy_print_status(phydev);
unlock_tx_qs(priv);
- local_irq_restore_nort(flags);
+ local_irq_restore(flags);
}
/* Update the hash table based on the current list of multicast
diff --git a/drivers/net/ethernet/freescale/gianfar_ptp.c b/drivers/net/ethernet/freescale/gianfar_ptp.c
index a3f8a25..2e5daee 100644
--- a/drivers/net/ethernet/freescale/gianfar_ptp.c
+++ b/drivers/net/ethernet/freescale/gianfar_ptp.c
@@ -127,6 +127,7 @@ struct gianfar_ptp_registers {
#define DRIVER "gianfar_ptp"
#define DEFAULT_CKSEL 1
+#define N_ALARM 1 /* first alarm is used internally to reset fipers */
#define N_EXT_TS 2
#define REG_SIZE sizeof(struct gianfar_ptp_registers)
@@ -409,7 +410,7 @@ static struct ptp_clock_info ptp_gianfar_caps = {
.owner = THIS_MODULE,
.name = "gianfar clock",
.max_adj = 512000,
- .n_alarm = 0,
+ .n_alarm = N_ALARM,
.n_ext_ts = N_EXT_TS,
.n_per_out = 0,
.pps = 1,
diff --git a/drivers/net/ethernet/ibm/ibmveth.c b/drivers/net/ethernet/ibm/ibmveth.c
index 82c63ac..f2fdbb7 100644
--- a/drivers/net/ethernet/ibm/ibmveth.c
+++ b/drivers/net/ethernet/ibm/ibmveth.c
@@ -1326,7 +1326,7 @@ static const struct net_device_ops ibmveth_netdev_ops = {
static int ibmveth_probe(struct vio_dev *dev, const struct vio_device_id *id)
{
- int rc, i, mac_len;
+ int rc, i;
struct net_device *netdev;
struct ibmveth_adapter *adapter;
unsigned char *mac_addr_p;
@@ -1336,19 +1336,11 @@ static int ibmveth_probe(struct vio_dev *dev, const struct vio_device_id *id)
dev->unit_address);
mac_addr_p = (unsigned char *)vio_get_attribute(dev, VETH_MAC_ADDR,
- &mac_len);
+ NULL);
if (!mac_addr_p) {
dev_err(&dev->dev, "Can't find VETH_MAC_ADDR attribute\n");
return -EINVAL;
}
- /* Workaround for old/broken pHyp */
- if (mac_len == 8)
- mac_addr_p += 2;
- else if (mac_len != 6) {
- dev_err(&dev->dev, "VETH_MAC_ADDR attribute wrong len %d\n",
- mac_len);
- return -EINVAL;
- }
mcastFilterSize_p = (unsigned int *)vio_get_attribute(dev,
VETH_MCAST_FILTER_SIZE, NULL);
@@ -1373,6 +1365,17 @@ static int ibmveth_probe(struct vio_dev *dev, const struct vio_device_id *id)
netif_napi_add(netdev, &adapter->napi, ibmveth_poll, 16);
+ /*
+ * Some older boxes running PHYP non-natively have an OF that returns
+ * a 8-byte local-mac-address field (and the first 2 bytes have to be
+ * ignored) while newer boxes' OF return a 6-byte field. Note that
+ * IEEE 1275 specifies that local-mac-address must be a 6-byte field.
+ * The RPA doc specifies that the first byte must be 10b, so we'll
+ * just look for it to solve this 8 vs. 6 byte field issue
+ */
+ if ((*mac_addr_p & 0x3) != 0x02)
+ mac_addr_p += 2;
+
adapter->mac_addr = 0;
memcpy(&adapter->mac_addr, mac_addr_p, 6);
diff --git a/drivers/net/ethernet/intel/e1000e/ethtool.c b/drivers/net/ethernet/intel/e1000e/ethtool.c
index 522fb10..fd4772a 100644
--- a/drivers/net/ethernet/intel/e1000e/ethtool.c
+++ b/drivers/net/ethernet/intel/e1000e/ethtool.c
@@ -35,7 +35,6 @@
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/vmalloc.h>
-#include <linux/pm_runtime.h>
#include "e1000.h"
@@ -2054,19 +2053,7 @@ static int e1000_get_rxnfc(struct net_device *netdev,
}
}
-static int e1000e_ethtool_begin(struct net_device *netdev)
-{
- return pm_runtime_get_sync(netdev->dev.parent);
-}
-
-static void e1000e_ethtool_complete(struct net_device *netdev)
-{
- pm_runtime_put_sync(netdev->dev.parent);
-}
-
static const struct ethtool_ops e1000_ethtool_ops = {
- .begin = e1000e_ethtool_begin,
- .complete = e1000e_ethtool_complete,
.get_settings = e1000_get_settings,
.set_settings = e1000_set_settings,
.get_drvinfo = e1000_get_drvinfo,
diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c
index 8692eca..643c883 100644
--- a/drivers/net/ethernet/intel/e1000e/netdev.c
+++ b/drivers/net/ethernet/intel/e1000e/netdev.c
@@ -3952,7 +3952,6 @@ static int e1000_open(struct net_device *netdev)
netif_start_queue(netdev);
adapter->idle_check = true;
- hw->mac.get_link_status = true;
pm_runtime_put(&pdev->dev);
/* fire a link status change interrupt to start the watchdog */
@@ -4313,7 +4312,6 @@ static void e1000_phy_read_status(struct e1000_adapter *adapter)
(adapter->hw.phy.media_type == e1000_media_type_copper)) {
int ret_val;
- pm_runtime_get_sync(&adapter->pdev->dev);
ret_val = e1e_rphy(hw, PHY_CONTROL, &phy->bmcr);
ret_val |= e1e_rphy(hw, PHY_STATUS, &phy->bmsr);
ret_val |= e1e_rphy(hw, PHY_AUTONEG_ADV, &phy->advertise);
@@ -4324,7 +4322,6 @@ static void e1000_phy_read_status(struct e1000_adapter *adapter)
ret_val |= e1e_rphy(hw, PHY_EXT_STATUS, &phy->estatus);
if (ret_val)
e_warn("Error reading PHY register\n");
- pm_runtime_put_sync(&adapter->pdev->dev);
} else {
/* Do not read PHY registers if link is not up
* Set values to typical power-on defaults
@@ -5453,7 +5450,8 @@ release:
return retval;
}
-static int __e1000_shutdown(struct pci_dev *pdev, bool runtime)
+static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake,
+ bool runtime)
{
struct net_device *netdev = pci_get_drvdata(pdev);
struct e1000_adapter *adapter = netdev_priv(netdev);
@@ -5477,6 +5475,10 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool runtime)
}
e1000e_reset_interrupt_capability(adapter);
+ retval = pci_save_state(pdev);
+ if (retval)
+ return retval;
+
status = er32(STATUS);
if (status & E1000_STATUS_LU)
wufc &= ~E1000_WUFC_LNKC;
@@ -5532,6 +5534,13 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool runtime)
ew32(WUFC, 0);
}
+ *enable_wake = !!wufc;
+
+ /* make sure adapter isn't asleep if manageability is enabled */
+ if ((adapter->flags & FLAG_MNG_PT_ENABLED) ||
+ (hw->mac.ops.check_mng_mode(hw)))
+ *enable_wake = true;
+
if (adapter->hw.phy.type == e1000_phy_igp_3)
e1000e_igp3_phy_powerdown_workaround_ich8lan(&adapter->hw);
@@ -5540,7 +5549,27 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool runtime)
*/
e1000e_release_hw_control(adapter);
- pci_clear_master(pdev);
+ pci_disable_device(pdev);
+
+ return 0;
+}
+
+static void e1000_power_off(struct pci_dev *pdev, bool sleep, bool wake)
+{
+ if (sleep && wake) {
+ pci_prepare_to_sleep(pdev);
+ return;
+ }
+
+ pci_wake_from_d3(pdev, wake);
+ pci_set_power_state(pdev, PCI_D3hot);
+}
+
+static void e1000_complete_shutdown(struct pci_dev *pdev, bool sleep,
+ bool wake)
+{
+ struct net_device *netdev = pci_get_drvdata(pdev);
+ struct e1000_adapter *adapter = netdev_priv(netdev);
/* The pci-e switch on some quad port adapters will report a
* correctable error when the MAC transitions from D0 to D3. To
@@ -5555,13 +5584,12 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool runtime)
pcie_capability_write_word(us_dev, PCI_EXP_DEVCTL,
(devctl & ~PCI_EXP_DEVCTL_CERE));
- pci_save_state(pdev);
- pci_prepare_to_sleep(pdev);
+ e1000_power_off(pdev, sleep, wake);
pcie_capability_write_word(us_dev, PCI_EXP_DEVCTL, devctl);
+ } else {
+ e1000_power_off(pdev, sleep, wake);
}
-
- return 0;
}
#ifdef CONFIG_PCIEASPM
@@ -5612,7 +5640,9 @@ static int __e1000_resume(struct pci_dev *pdev)
if (aspm_disable_flag)
e1000e_disable_aspm(pdev, aspm_disable_flag);
- pci_set_master(pdev);
+ pci_set_power_state(pdev, PCI_D0);
+ pci_restore_state(pdev);
+ pci_save_state(pdev);
e1000e_set_interrupt_capability(adapter);
if (netif_running(netdev)) {
@@ -5678,8 +5708,14 @@ static int __e1000_resume(struct pci_dev *pdev)
static int e1000_suspend(struct device *dev)
{
struct pci_dev *pdev = to_pci_dev(dev);
+ int retval;
+ bool wake;
+
+ retval = __e1000_shutdown(pdev, &wake, false);
+ if (!retval)
+ e1000_complete_shutdown(pdev, true, wake);
- return __e1000_shutdown(pdev, false);
+ return retval;
}
static int e1000_resume(struct device *dev)
@@ -5702,10 +5738,13 @@ static int e1000_runtime_suspend(struct device *dev)
struct net_device *netdev = pci_get_drvdata(pdev);
struct e1000_adapter *adapter = netdev_priv(netdev);
- if (!e1000e_pm_ready(adapter))
- return 0;
+ if (e1000e_pm_ready(adapter)) {
+ bool wake;
- return __e1000_shutdown(pdev, true);
+ __e1000_shutdown(pdev, &wake, true);
+ }
+
+ return 0;
}
static int e1000_idle(struct device *dev)
@@ -5743,7 +5782,12 @@ static int e1000_runtime_resume(struct device *dev)
static void e1000_shutdown(struct pci_dev *pdev)
{
- __e1000_shutdown(pdev, false);
+ bool wake = false;
+
+ __e1000_shutdown(pdev, &wake, false);
+
+ if (system_state == SYSTEM_POWER_OFF)
+ e1000_complete_shutdown(pdev, false, wake);
}
#ifdef CONFIG_NET_POLL_CONTROLLER
@@ -5864,9 +5908,9 @@ static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev)
"Cannot re-enable PCI device after reset.\n");
result = PCI_ERS_RESULT_DISCONNECT;
} else {
+ pci_set_master(pdev);
pdev->state_saved = true;
pci_restore_state(pdev);
- pci_set_master(pdev);
pci_enable_wake(pdev, PCI_D3hot, 0);
pci_enable_wake(pdev, PCI_D3cold, 0);
@@ -6297,11 +6341,7 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
/* initialize the wol settings based on the eeprom settings */
adapter->wol = adapter->eeprom_wol;
-
- /* make sure adapter isn't asleep if manageability is enabled */
- if (adapter->wol || (adapter->flags & FLAG_MNG_PT_ENABLED) ||
- (hw->mac.ops.check_mng_mode(hw)))
- device_wakeup_enable(&pdev->dev);
+ device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
/* save off EEPROM version number */
e1000_read_nvm(&adapter->hw, 5, 1, &adapter->eeprom_vers);
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 911956e..b3e3294 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -2407,16 +2407,6 @@ static irqreturn_t ixgbe_msix_other(int irq, void *data)
* with the write to EICR.
*/
eicr = IXGBE_READ_REG(hw, IXGBE_EICS);
-
- /* The lower 16bits of the EICR register are for the queue interrupts
- * which should be masked here in order to not accidently clear them if
- * the bits are high when ixgbe_msix_other is called. There is a race
- * condition otherwise which results in possible performance loss
- * especially if the ixgbe_msix_other interrupt is triggering
- * consistently (as it would when PPS is turned on for the X540 device)
- */
- eicr &= 0xFFFF0000;
-
IXGBE_WRITE_REG(hw, IXGBE_EICR, eicr);
if (eicr & IXGBE_EICR_LSC)
@@ -7868,19 +7858,12 @@ static int __init ixgbe_init_module(void)
ixgbe_dbg_init();
#endif /* CONFIG_DEBUG_FS */
- ret = pci_register_driver(&ixgbe_driver);
- if (ret) {
-#ifdef CONFIG_DEBUG_FS
- ixgbe_dbg_exit();
-#endif /* CONFIG_DEBUG_FS */
- return ret;
- }
-
#ifdef CONFIG_IXGBE_DCA
dca_register_notify(&dca_notifier);
#endif
- return 0;
+ ret = pci_register_driver(&ixgbe_driver);
+ return ret;
}
module_init(ixgbe_init_module);
diff --git a/drivers/net/ethernet/marvell/Kconfig b/drivers/net/ethernet/marvell/Kconfig
index 434e33c..edfba93 100644
--- a/drivers/net/ethernet/marvell/Kconfig
+++ b/drivers/net/ethernet/marvell/Kconfig
@@ -33,7 +33,6 @@ config MV643XX_ETH
config MVMDIO
tristate "Marvell MDIO interface support"
- select PHYLIB
---help---
This driver supports the MDIO interface found in the network
interface units of the Marvell EBU SoCs (Kirkwood, Orion5x,
@@ -46,6 +45,7 @@ config MVMDIO
config MVNETA
tristate "Marvell Armada 370/XP network interface support"
depends on MACH_ARMADA_370_XP
+ select PHYLIB
select MVMDIO
---help---
This driver supports the network interface units in the
diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
index 84b312ea..b6025c3 100644
--- a/drivers/net/ethernet/marvell/mvneta.c
+++ b/drivers/net/ethernet/marvell/mvneta.c
@@ -375,6 +375,7 @@ static int rxq_number = 8;
static int txq_number = 8;
static int rxq_def;
+static int txq_def;
#define MVNETA_DRIVER_NAME "mvneta"
#define MVNETA_DRIVER_VERSION "1.0"
@@ -1475,8 +1476,7 @@ error:
static int mvneta_tx(struct sk_buff *skb, struct net_device *dev)
{
struct mvneta_port *pp = netdev_priv(dev);
- u16 txq_id = skb_get_queue_mapping(skb);
- struct mvneta_tx_queue *txq = &pp->txqs[txq_id];
+ struct mvneta_tx_queue *txq = &pp->txqs[txq_def];
struct mvneta_tx_desc *tx_desc;
struct netdev_queue *nq;
int frags = 0;
@@ -1486,7 +1486,7 @@ static int mvneta_tx(struct sk_buff *skb, struct net_device *dev)
goto out;
frags = skb_shinfo(skb)->nr_frags + 1;
- nq = netdev_get_tx_queue(dev, txq_id);
+ nq = netdev_get_tx_queue(dev, txq_def);
/* Get a descriptor for the first part of the packet */
tx_desc = mvneta_txq_next_desc_get(txq);
@@ -2690,7 +2690,7 @@ static int mvneta_probe(struct platform_device *pdev)
return -EINVAL;
}
- dev = alloc_etherdev_mqs(sizeof(struct mvneta_port), txq_number, rxq_number);
+ dev = alloc_etherdev_mq(sizeof(struct mvneta_port), 8);
if (!dev)
return -ENOMEM;
@@ -2844,3 +2844,4 @@ module_param(rxq_number, int, S_IRUGO);
module_param(txq_number, int, S_IRUGO);
module_param(rxq_def, int, S_IRUGO);
+module_param(txq_def, int, S_IRUGO);
diff --git a/drivers/net/ethernet/marvell/sky2.c b/drivers/net/ethernet/marvell/sky2.c
index d23dc5e..3269eb3 100644
--- a/drivers/net/ethernet/marvell/sky2.c
+++ b/drivers/net/ethernet/marvell/sky2.c
@@ -1067,7 +1067,7 @@ static void sky2_ramset(struct sky2_hw *hw, u16 q, u32 start, u32 space)
sky2_write32(hw, RB_ADDR(q, RB_RX_UTHP), tp);
sky2_write32(hw, RB_ADDR(q, RB_RX_LTHP), space/2);
- tp = space - 8192/8;
+ tp = space - 2048/8;
sky2_write32(hw, RB_ADDR(q, RB_RX_UTPP), tp);
sky2_write32(hw, RB_ADDR(q, RB_RX_LTPP), space/4);
} else {
diff --git a/drivers/net/ethernet/marvell/sky2.h b/drivers/net/ethernet/marvell/sky2.h
index ec6dcd8..615ac63 100644
--- a/drivers/net/ethernet/marvell/sky2.h
+++ b/drivers/net/ethernet/marvell/sky2.h
@@ -2074,7 +2074,7 @@ enum {
GM_IS_RX_FF_OR = 1<<1, /* Receive FIFO Overrun */
GM_IS_RX_COMPL = 1<<0, /* Frame Reception Complete */
-#define GMAC_DEF_MSK (GM_IS_TX_FF_UR | GM_IS_RX_FF_OR)
+#define GMAC_DEF_MSK GM_IS_TX_FF_UR
};
/* GMAC_LINK_CTRL 16 bit GMAC Link Control Reg (YUKON only) */
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
index bf3f4bc..75a3f46 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
@@ -1434,11 +1434,12 @@ int mlx4_en_alloc_resources(struct mlx4_en_priv *priv)
}
#ifdef CONFIG_RFS_ACCEL
- if (priv->mdev->dev->caps.comp_pool) {
- priv->dev->rx_cpu_rmap = alloc_irq_cpu_rmap(priv->mdev->dev->caps.comp_pool);
- if (!priv->dev->rx_cpu_rmap)
- goto err;
- }
+ priv->dev->rx_cpu_rmap = alloc_irq_cpu_rmap(priv->rx_ring_num);
+ if (!priv->dev->rx_cpu_rmap)
+ goto err;
+
+ INIT_LIST_HEAD(&priv->filters);
+ spin_lock_init(&priv->filters_lock);
#endif
return 0;
@@ -1596,7 +1597,7 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
err = -ENOMEM;
goto out;
}
- priv->tx_cq = kzalloc(sizeof(struct mlx4_en_cq) * MAX_TX_RINGS,
+ priv->tx_cq = kzalloc(sizeof(struct mlx4_en_cq) * MAX_RX_RINGS,
GFP_KERNEL);
if (!priv->tx_cq) {
err = -ENOMEM;
@@ -1633,11 +1634,6 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
if (err)
goto out;
-#ifdef CONFIG_RFS_ACCEL
- INIT_LIST_HEAD(&priv->filters);
- spin_lock_init(&priv->filters_lock);
-#endif
-
/* Allocate page for receive rings */
err = mlx4_alloc_hwq_res(mdev->dev, &priv->res,
MLX4_EN_PAGE_SIZE, MLX4_EN_PAGE_SIZE);
diff --git a/drivers/net/ethernet/micrel/ks8851.c b/drivers/net/ethernet/micrel/ks8851.c
index 1e42882..286816a 100644
--- a/drivers/net/ethernet/micrel/ks8851.c
+++ b/drivers/net/ethernet/micrel/ks8851.c
@@ -547,7 +547,7 @@ static void ks8851_rx_pkts(struct ks8851_net *ks)
for (; rxfc != 0; rxfc--) {
rxh = ks8851_rdreg32(ks, KS_RXFHSR);
rxstat = rxh & 0xffff;
- rxlen = (rxh >> 16) & 0xfff;
+ rxlen = rxh >> 16;
netif_dbg(ks, rx_status, ks->netdev,
"rx: stat 0x%04x, len 0x%04x\n", rxstat, rxlen);
diff --git a/drivers/net/ethernet/neterion/s2io.c b/drivers/net/ethernet/neterion/s2io.c
index 8757a2c..7c94c08 100644
--- a/drivers/net/ethernet/neterion/s2io.c
+++ b/drivers/net/ethernet/neterion/s2io.c
@@ -4088,7 +4088,12 @@ static netdev_tx_t s2io_xmit(struct sk_buff *skb, struct net_device *dev)
[skb->priority & (MAX_TX_FIFOS - 1)];
fifo = &mac_control->fifos[queue];
- spin_lock_irqsave(&fifo->tx_lock, flags);
+ if (do_spin_lock)
+ spin_lock_irqsave(&fifo->tx_lock, flags);
+ else {
+ if (unlikely(!spin_trylock_irqsave(&fifo->tx_lock, flags)))
+ return NETDEV_TX_LOCKED;
+ }
if (sp->config.multiq) {
if (__netif_subqueue_stopped(dev, fifo->fifo_no)) {
diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
index b3ba6fe..39ab4d0 100644
--- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
+++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
@@ -1726,9 +1726,9 @@ pch_gbe_clean_rx(struct pch_gbe_adapter *adapter,
skb->protocol = eth_type_trans(skb, netdev);
if (tcp_ip_status & PCH_GBE_RXD_ACC_STAT_TCPIPOK)
- skb->ip_summed = CHECKSUM_UNNECESSARY;
- else
skb->ip_summed = CHECKSUM_NONE;
+ else
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
napi_gro_receive(&adapter->napi, skb);
(*work_done)++;
@@ -2114,8 +2114,10 @@ static int pch_gbe_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
struct pch_gbe_tx_ring *tx_ring = adapter->tx_ring;
unsigned long flags;
- spin_lock_irqsave(&tx_ring->tx_lock, flags);
-
+ if (!spin_trylock_irqsave(&tx_ring->tx_lock, flags)) {
+ /* Collision - tell upper layer to requeue */
+ return NETDEV_TX_LOCKED;
+ }
if (unlikely(!PCH_GBE_DESC_UNUSED(tx_ring))) {
netif_stop_queue(netdev);
spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
diff --git a/drivers/net/ethernet/realtek/8139too.c b/drivers/net/ethernet/realtek/8139too.c
index 3bed27d..5dc1616 100644
--- a/drivers/net/ethernet/realtek/8139too.c
+++ b/drivers/net/ethernet/realtek/8139too.c
@@ -2216,7 +2216,7 @@ static void rtl8139_poll_controller(struct net_device *dev)
struct rtl8139_private *tp = netdev_priv(dev);
const int irq = tp->pci_dev->irq;
- disable_irq_nosync(irq);
+ disable_irq(irq);
rtl8139_interrupt(irq, dev);
enable_irq(irq);
}
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
index 2d56d71..998974f 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -3819,30 +3819,6 @@ static void rtl_init_mdio_ops(struct rtl8169_private *tp)
}
}
-static void rtl_speed_down(struct rtl8169_private *tp)
-{
- u32 adv;
- int lpa;
-
- rtl_writephy(tp, 0x1f, 0x0000);
- lpa = rtl_readphy(tp, MII_LPA);
-
- if (lpa & (LPA_10HALF | LPA_10FULL))
- adv = ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full;
- else if (lpa & (LPA_100HALF | LPA_100FULL))
- adv = ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full |
- ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full;
- else
- adv = ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full |
- ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full |
- (tp->mii.supports_gmii ?
- ADVERTISED_1000baseT_Half |
- ADVERTISED_1000baseT_Full : 0);
-
- rtl8169_set_speed(tp->dev, AUTONEG_ENABLE, SPEED_1000, DUPLEX_FULL,
- adv);
-}
-
static void rtl_wol_suspend_quirk(struct rtl8169_private *tp)
{
void __iomem *ioaddr = tp->mmio_addr;
@@ -3873,7 +3849,9 @@ static bool rtl_wol_pll_power_down(struct rtl8169_private *tp)
if (!(__rtl8169_get_wol(tp) & WAKE_ANY))
return false;
- rtl_speed_down(tp);
+ rtl_writephy(tp, 0x1f, 0x0000);
+ rtl_writephy(tp, MII_BMCR, 0x0000);
+
rtl_wol_suspend_quirk(tp);
return true;
@@ -5779,14 +5757,6 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
goto err_stop_0;
}
- /* 8168evl does not automatically pad to minimum length. */
- if (unlikely(tp->mac_version == RTL_GIGA_MAC_VER_34 &&
- skb->len < ETH_ZLEN)) {
- if (skb_padto(skb, ETH_ZLEN))
- goto err_update_stats;
- skb_put(skb, ETH_ZLEN - skb->len);
- }
-
if (unlikely(le32_to_cpu(txd->opts1) & DescOwn))
goto err_stop_0;
@@ -5858,7 +5828,6 @@ err_dma_1:
rtl8169_unmap_tx_skb(d, tp->tx_skb + entry, txd);
err_dma_0:
dev_kfree_skb(skb);
-err_update_stats:
dev->stats.tx_dropped++;
return NETDEV_TX_OK;
diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c
index 0bc0099..bf57b3c 100644
--- a/drivers/net/ethernet/sfc/efx.c
+++ b/drivers/net/ethernet/sfc/efx.c
@@ -779,7 +779,6 @@ efx_realloc_channels(struct efx_nic *efx, u32 rxq_entries, u32 txq_entries)
tx_queue->txd.entries);
}
- efx_device_detach_sync(efx);
efx_stop_all(efx);
efx_stop_interrupts(efx, true);
@@ -833,7 +832,6 @@ out:
efx_start_interrupts(efx, true);
efx_start_all(efx);
- netif_device_attach(efx->net_dev);
return rc;
rollback:
@@ -1643,12 +1641,8 @@ static void efx_stop_all(struct efx_nic *efx)
/* Flush efx_mac_work(), refill_workqueue, monitor_work */
efx_flush_all(efx);
- /* Stop the kernel transmit interface. This is only valid if
- * the device is stopped or detached; otherwise the watchdog
- * may fire immediately.
- */
- WARN_ON(netif_running(efx->net_dev) &&
- netif_device_present(efx->net_dev));
+ /* Stop the kernel transmit interface late, so the watchdog
+ * timer isn't ticking over the flush */
netif_tx_disable(efx->net_dev);
efx_stop_datapath(efx);
@@ -1969,18 +1963,16 @@ static int efx_change_mtu(struct net_device *net_dev, int new_mtu)
if (new_mtu > EFX_MAX_MTU)
return -EINVAL;
- netif_dbg(efx, drv, efx->net_dev, "changing MTU to %d\n", new_mtu);
-
- efx_device_detach_sync(efx);
efx_stop_all(efx);
+ netif_dbg(efx, drv, efx->net_dev, "changing MTU to %d\n", new_mtu);
+
mutex_lock(&efx->mac_lock);
net_dev->mtu = new_mtu;
efx->type->reconfigure_mac(efx);
mutex_unlock(&efx->mac_lock);
efx_start_all(efx);
- netif_device_attach(efx->net_dev);
return 0;
}
diff --git a/drivers/net/ethernet/sfc/efx.h b/drivers/net/ethernet/sfc/efx.h
index d2f790d..50247df 100644
--- a/drivers/net/ethernet/sfc/efx.h
+++ b/drivers/net/ethernet/sfc/efx.h
@@ -171,9 +171,9 @@ static inline void efx_device_detach_sync(struct efx_nic *efx)
* TX scheduler is stopped when we're done and before
* netif_device_present() becomes false.
*/
- netif_tx_lock_bh(dev);
+ netif_tx_lock(dev);
netif_device_detach(dev);
- netif_tx_unlock_bh(dev);
+ netif_tx_unlock(dev);
}
#endif /* EFX_EFX_H */
diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h
index 0a90abd..2d756c1 100644
--- a/drivers/net/ethernet/sfc/net_driver.h
+++ b/drivers/net/ethernet/sfc/net_driver.h
@@ -210,7 +210,6 @@ struct efx_tx_queue {
* Will be %NULL if the buffer slot is currently free.
* @page: The associated page buffer. Valif iff @flags & %EFX_RX_BUF_PAGE.
* Will be %NULL if the buffer slot is currently free.
- * @page_offset: Offset within page. Valid iff @flags & %EFX_RX_BUF_PAGE.
* @len: Buffer length, in bytes.
* @flags: Flags for buffer and packet state.
*/
@@ -220,8 +219,7 @@ struct efx_rx_buffer {
struct sk_buff *skb;
struct page *page;
} u;
- u16 page_offset;
- u16 len;
+ unsigned int len;
u16 flags;
};
#define EFX_RX_BUF_PAGE 0x0001
diff --git a/drivers/net/ethernet/sfc/nic.c b/drivers/net/ethernet/sfc/nic.c
index eaa8e87..0ad790c 100644
--- a/drivers/net/ethernet/sfc/nic.c
+++ b/drivers/net/ethernet/sfc/nic.c
@@ -376,8 +376,7 @@ efx_may_push_tx_desc(struct efx_tx_queue *tx_queue, unsigned int write_count)
return false;
tx_queue->empty_read_count = 0;
- return ((empty_read_count ^ write_count) & ~EFX_EMPTY_COUNT_VALID) == 0
- && tx_queue->write_count - write_count == 1;
+ return ((empty_read_count ^ write_count) & ~EFX_EMPTY_COUNT_VALID) == 0;
}
/* For each entry inserted into the software descriptor ring, create a
diff --git a/drivers/net/ethernet/sfc/ptp.c b/drivers/net/ethernet/sfc/ptp.c
index 3f93624..0767043f 100644
--- a/drivers/net/ethernet/sfc/ptp.c
+++ b/drivers/net/ethernet/sfc/ptp.c
@@ -1439,7 +1439,7 @@ static int efx_phc_settime(struct ptp_clock_info *ptp,
delta = timespec_sub(*e_ts, time_now);
- rc = efx_phc_adjtime(ptp, timespec_to_ns(&delta));
+ efx_phc_adjtime(ptp, timespec_to_ns(&delta));
if (rc != 0)
return rc;
diff --git a/drivers/net/ethernet/sfc/rx.c b/drivers/net/ethernet/sfc/rx.c
index bb579a6..d780a0d 100644
--- a/drivers/net/ethernet/sfc/rx.c
+++ b/drivers/net/ethernet/sfc/rx.c
@@ -90,7 +90,11 @@ static unsigned int rx_refill_threshold;
static inline unsigned int efx_rx_buf_offset(struct efx_nic *efx,
struct efx_rx_buffer *buf)
{
- return buf->page_offset + efx->type->rx_buffer_hash_size;
+ /* Offset is always within one page, so we don't need to consider
+ * the page order.
+ */
+ return ((unsigned int) buf->dma_addr & (PAGE_SIZE - 1)) +
+ efx->type->rx_buffer_hash_size;
}
static inline unsigned int efx_rx_buf_size(struct efx_nic *efx)
{
@@ -183,7 +187,6 @@ static int efx_init_rx_buffers_page(struct efx_rx_queue *rx_queue)
struct efx_nic *efx = rx_queue->efx;
struct efx_rx_buffer *rx_buf;
struct page *page;
- unsigned int page_offset;
struct efx_rx_page_state *state;
dma_addr_t dma_addr;
unsigned index, count;
@@ -208,14 +211,12 @@ static int efx_init_rx_buffers_page(struct efx_rx_queue *rx_queue)
state->dma_addr = dma_addr;
dma_addr += sizeof(struct efx_rx_page_state);
- page_offset = sizeof(struct efx_rx_page_state);
split:
index = rx_queue->added_count & rx_queue->ptr_mask;
rx_buf = efx_rx_buffer(rx_queue, index);
rx_buf->dma_addr = dma_addr + EFX_PAGE_IP_ALIGN;
rx_buf->u.page = page;
- rx_buf->page_offset = page_offset + EFX_PAGE_IP_ALIGN;
rx_buf->len = efx->rx_buffer_len - EFX_PAGE_IP_ALIGN;
rx_buf->flags = EFX_RX_BUF_PAGE;
++rx_queue->added_count;
@@ -226,7 +227,6 @@ static int efx_init_rx_buffers_page(struct efx_rx_queue *rx_queue)
/* Use the second half of the page */
get_page(page);
dma_addr += (PAGE_SIZE >> 1);
- page_offset += (PAGE_SIZE >> 1);
++count;
goto split;
}
@@ -236,8 +236,7 @@ static int efx_init_rx_buffers_page(struct efx_rx_queue *rx_queue)
}
static void efx_unmap_rx_buffer(struct efx_nic *efx,
- struct efx_rx_buffer *rx_buf,
- unsigned int used_len)
+ struct efx_rx_buffer *rx_buf)
{
if ((rx_buf->flags & EFX_RX_BUF_PAGE) && rx_buf->u.page) {
struct efx_rx_page_state *state;
@@ -248,10 +247,6 @@ static void efx_unmap_rx_buffer(struct efx_nic *efx,
state->dma_addr,
efx_rx_buf_size(efx),
DMA_FROM_DEVICE);
- } else if (used_len) {
- dma_sync_single_for_cpu(&efx->pci_dev->dev,
- rx_buf->dma_addr, used_len,
- DMA_FROM_DEVICE);
}
} else if (!(rx_buf->flags & EFX_RX_BUF_PAGE) && rx_buf->u.skb) {
dma_unmap_single(&efx->pci_dev->dev, rx_buf->dma_addr,
@@ -274,7 +269,7 @@ static void efx_free_rx_buffer(struct efx_nic *efx,
static void efx_fini_rx_buffer(struct efx_rx_queue *rx_queue,
struct efx_rx_buffer *rx_buf)
{
- efx_unmap_rx_buffer(rx_queue->efx, rx_buf, 0);
+ efx_unmap_rx_buffer(rx_queue->efx, rx_buf);
efx_free_rx_buffer(rx_queue->efx, rx_buf);
}
@@ -540,10 +535,10 @@ void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index,
goto out;
}
- /* Release and/or sync DMA mapping - assumes all RX buffers
- * consumed in-order per RX queue
+ /* Release card resources - assumes all RX buffers consumed in-order
+ * per RX queue
*/
- efx_unmap_rx_buffer(efx, rx_buf, len);
+ efx_unmap_rx_buffer(efx, rx_buf);
/* Prefetch nice and early so data will (hopefully) be in cache by
* the time we look at it.
diff --git a/drivers/net/ethernet/tehuti/tehuti.c b/drivers/net/ethernet/tehuti/tehuti.c
index 9dfd4f5..1e4d743 100644
--- a/drivers/net/ethernet/tehuti/tehuti.c
+++ b/drivers/net/ethernet/tehuti/tehuti.c
@@ -1630,8 +1630,13 @@ static netdev_tx_t bdx_tx_transmit(struct sk_buff *skb,
unsigned long flags;
ENTER;
-
- spin_lock_irqsave(&priv->tx_lock, flags);
+ local_irq_save(flags);
+ if (!spin_trylock(&priv->tx_lock)) {
+ local_irq_restore(flags);
+ DBG("%s[%s]: TX locked, returning NETDEV_TX_LOCKED\n",
+ BDX_DRV_NAME, ndev->name);
+ return NETDEV_TX_LOCKED;
+ }
/* build tx descriptor */
BDX_ASSERT(f->m.wptr >= f->m.memsz); /* started with valid wptr */
diff --git a/drivers/net/ethernet/ti/Kconfig b/drivers/net/ethernet/ti/Kconfig
index de71b1e..4426151 100644
--- a/drivers/net/ethernet/ti/Kconfig
+++ b/drivers/net/ethernet/ti/Kconfig
@@ -88,8 +88,8 @@ config TLAN
Please email feedback to <torben.mathiasen@compaq.com>.
config CPMAC
- tristate "TI AR7 CPMAC Ethernet support"
- depends on AR7
+ tristate "TI AR7 CPMAC Ethernet support (EXPERIMENTAL)"
+ depends on EXPERIMENTAL && AR7
select PHYLIB
---help---
TI AR7 CPMAC Ethernet support
diff --git a/drivers/net/ethernet/ti/cpmac.c b/drivers/net/ethernet/ti/cpmac.c
index 70d1920..d9625f6 100644
--- a/drivers/net/ethernet/ti/cpmac.c
+++ b/drivers/net/ethernet/ti/cpmac.c
@@ -904,9 +904,10 @@ static int cpmac_set_ringparam(struct net_device *dev,
static void cpmac_get_drvinfo(struct net_device *dev,
struct ethtool_drvinfo *info)
{
- strlcpy(info->driver, "cpmac", sizeof(info->driver));
- strlcpy(info->version, CPMAC_VERSION, sizeof(info->version));
- snprintf(info->bus_info, sizeof(info->bus_info), "%s", "cpmac");
+ strcpy(info->driver, "cpmac");
+ strcpy(info->version, CPMAC_VERSION);
+ info->fw_version[0] = '\0';
+ sprintf(info->bus_info, "%s", "cpmac");
info->regdump_len = 0;
}
diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index 1cfde0c..40aff68 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -32,7 +32,6 @@
#include <linux/of.h>
#include <linux/of_net.h>
#include <linux/of_device.h>
-#include <linux/if_vlan.h>
#include <linux/platform_data/cpsw.h>
@@ -119,20 +118,6 @@ do { \
#define TX_PRIORITY_MAPPING 0x33221100
#define CPDMA_TX_PRIORITY_MAP 0x76543210
-#define CPSW_VLAN_AWARE BIT(1)
-#define CPSW_ALE_VLAN_AWARE 1
-
-#define CPSW_FIFO_NORMAL_MODE (0 << 15)
-#define CPSW_FIFO_DUAL_MAC_MODE (1 << 15)
-#define CPSW_FIFO_RATE_LIMIT_MODE (2 << 15)
-
-#define CPSW_INTPACEEN (0x3f << 16)
-#define CPSW_INTPRESCALE_MASK (0x7FF << 0)
-#define CPSW_CMINTMAX_CNT 63
-#define CPSW_CMINTMIN_CNT 2
-#define CPSW_CMINTMAX_INTVL (1000 / CPSW_CMINTMIN_CNT)
-#define CPSW_CMINTMIN_INTVL ((1000 / CPSW_CMINTMAX_CNT) + 1)
-
#define cpsw_enable_irq(priv) \
do { \
u32 i; \
@@ -146,10 +131,6 @@ do { \
disable_irq_nosync(priv->irqs_table[i]); \
} while (0);
-#define cpsw_slave_index(priv) \
- ((priv->data.dual_emac) ? priv->emac_port : \
- priv->data.active_slave)
-
static int debug_level;
module_param(debug_level, int, 0);
MODULE_PARM_DESC(debug_level, "cpsw debug level (NETIF_MSG bits)");
@@ -171,15 +152,6 @@ struct cpsw_wr_regs {
u32 rx_en;
u32 tx_en;
u32 misc_en;
- u32 mem_allign1[8];
- u32 rx_thresh_stat;
- u32 rx_stat;
- u32 tx_stat;
- u32 misc_stat;
- u32 mem_allign2[8];
- u32 rx_imax;
- u32 tx_imax;
-
};
struct cpsw_ss_regs {
@@ -278,7 +250,7 @@ struct cpsw_ss_regs {
struct cpsw_host_regs {
u32 max_blks;
u32 blk_cnt;
- u32 tx_in_ctl;
+ u32 flow_thresh;
u32 port_vlan;
u32 tx_pri_map;
u32 cpdma_tx_pri_map;
@@ -305,9 +277,6 @@ struct cpsw_slave {
u32 mac_control;
struct cpsw_slave_data *data;
struct phy_device *phy;
- struct net_device *ndev;
- u32 port_vlan;
- u32 open_stat;
};
static inline u32 slave_read(struct cpsw_slave *slave, u32 offset)
@@ -334,8 +303,6 @@ struct cpsw_priv {
struct cpsw_host_regs __iomem *host_port_regs;
u32 msg_enable;
u32 version;
- u32 coal_intvl;
- u32 bus_freq_mhz;
struct net_device_stats stats;
int rx_packet_max;
int host_port;
@@ -348,69 +315,17 @@ struct cpsw_priv {
/* snapshot of IRQ numbers */
u32 irqs_table[4];
u32 num_irqs;
- bool irq_enabled;
- struct cpts *cpts;
- u32 emac_port;
+ struct cpts cpts;
};
#define napi_to_priv(napi) container_of(napi, struct cpsw_priv, napi)
-#define for_each_slave(priv, func, arg...) \
- do { \
- struct cpsw_slave *slave; \
- int n; \
- if (priv->data.dual_emac) \
- (func)((priv)->slaves + priv->emac_port, ##arg);\
- else \
- for (n = (priv)->data.slaves, \
- slave = (priv)->slaves; \
- n; n--) \
- (func)(slave++, ##arg); \
- } while (0)
-#define cpsw_get_slave_ndev(priv, __slave_no__) \
- (priv->slaves[__slave_no__].ndev)
-#define cpsw_get_slave_priv(priv, __slave_no__) \
- ((priv->slaves[__slave_no__].ndev) ? \
- netdev_priv(priv->slaves[__slave_no__].ndev) : NULL) \
-
-#define cpsw_dual_emac_src_port_detect(status, priv, ndev, skb) \
- do { \
- if (!priv->data.dual_emac) \
- break; \
- if (CPDMA_RX_SOURCE_PORT(status) == 1) { \
- ndev = cpsw_get_slave_ndev(priv, 0); \
- priv = netdev_priv(ndev); \
- skb->dev = ndev; \
- } else if (CPDMA_RX_SOURCE_PORT(status) == 2) { \
- ndev = cpsw_get_slave_ndev(priv, 1); \
- priv = netdev_priv(ndev); \
- skb->dev = ndev; \
- } \
- } while (0)
-#define cpsw_add_mcast(priv, addr) \
- do { \
- if (priv->data.dual_emac) { \
- struct cpsw_slave *slave = priv->slaves + \
- priv->emac_port; \
- int slave_port = cpsw_get_slave_port(priv, \
- slave->slave_num); \
- cpsw_ale_add_mcast(priv->ale, addr, \
- 1 << slave_port | 1 << priv->host_port, \
- ALE_VLAN, slave->port_vlan, 0); \
- } else { \
- cpsw_ale_add_mcast(priv->ale, addr, \
- ALE_ALL_PORTS << priv->host_port, \
- 0, 0, 0); \
- } \
+#define for_each_slave(priv, func, arg...) \
+ do { \
+ int idx; \
+ for (idx = 0; idx < (priv)->data.slaves; idx++) \
+ (func)((priv)->slaves + idx, ##arg); \
} while (0)
-static inline int cpsw_get_slave_port(struct cpsw_priv *priv, u32 slave_num)
-{
- if (priv->host_port == 0)
- return slave_num + 1;
- else
- return slave_num;
-}
-
static void cpsw_ndo_set_rx_mode(struct net_device *ndev)
{
struct cpsw_priv *priv = netdev_priv(ndev);
@@ -429,7 +344,8 @@ static void cpsw_ndo_set_rx_mode(struct net_device *ndev)
/* program multicast address list into ALE register */
netdev_for_each_mc_addr(ha, ndev) {
- cpsw_add_mcast(priv, (u8 *)ha->addr);
+ cpsw_ale_add_mcast(priv->ale, (u8 *)ha->addr,
+ ALE_ALL_PORTS << priv->host_port, 0, 0);
}
}
}
@@ -458,12 +374,9 @@ void cpsw_tx_handler(void *token, int len, int status)
struct net_device *ndev = skb->dev;
struct cpsw_priv *priv = netdev_priv(ndev);
- /* Check whether the queue is stopped due to stalled tx dma, if the
- * queue is stopped then start the queue as we have free desc for tx
- */
if (unlikely(netif_queue_stopped(ndev)))
- netif_wake_queue(ndev);
- cpts_tx_timestamp(priv->cpts, skb);
+ netif_start_queue(ndev);
+ cpts_tx_timestamp(&priv->cpts, skb);
priv->stats.tx_packets++;
priv->stats.tx_bytes += len;
dev_kfree_skb_any(skb);
@@ -472,106 +385,82 @@ void cpsw_tx_handler(void *token, int len, int status)
void cpsw_rx_handler(void *token, int len, int status)
{
struct sk_buff *skb = token;
- struct sk_buff *new_skb;
struct net_device *ndev = skb->dev;
struct cpsw_priv *priv = netdev_priv(ndev);
int ret = 0;
- cpsw_dual_emac_src_port_detect(status, priv, ndev, skb);
-
- if (unlikely(status < 0)) {
- /* the interface is going down, skbs are purged */
+ /* free and bail if we are shutting down */
+ if (unlikely(!netif_running(ndev)) ||
+ unlikely(!netif_carrier_ok(ndev))) {
dev_kfree_skb_any(skb);
return;
}
-
- new_skb = netdev_alloc_skb_ip_align(ndev, priv->rx_packet_max);
- if (new_skb) {
+ if (likely(status >= 0)) {
skb_put(skb, len);
- cpts_rx_timestamp(priv->cpts, skb);
+ cpts_rx_timestamp(&priv->cpts, skb);
skb->protocol = eth_type_trans(skb, ndev);
- netif_rx(skb);
+ netif_receive_skb(skb);
priv->stats.rx_bytes += len;
priv->stats.rx_packets++;
- } else {
- priv->stats.rx_dropped++;
- new_skb = skb;
+ skb = NULL;
}
- ret = cpdma_chan_submit(priv->rxch, new_skb, new_skb->data,
- skb_tailroom(new_skb), 0);
- if (WARN_ON(ret < 0))
- dev_kfree_skb_any(new_skb);
+ if (unlikely(!netif_running(ndev))) {
+ if (skb)
+ dev_kfree_skb_any(skb);
+ return;
+ }
+
+ if (likely(!skb)) {
+ skb = netdev_alloc_skb_ip_align(ndev, priv->rx_packet_max);
+ if (WARN_ON(!skb))
+ return;
+
+ ret = cpdma_chan_submit(priv->rxch, skb, skb->data,
+ skb_tailroom(skb), GFP_KERNEL);
+ }
+ WARN_ON(ret < 0);
}
static irqreturn_t cpsw_interrupt(int irq, void *dev_id)
{
struct cpsw_priv *priv = dev_id;
- unsigned long flags;
- u32 rx, tx, rx_thresh;
-
- spin_lock_irqsave(&priv->lock, flags);
- rx_thresh = __raw_readl(&priv->wr_regs->rx_thresh_stat);
- rx = __raw_readl(&priv->wr_regs->rx_stat);
- tx = __raw_readl(&priv->wr_regs->tx_stat);
- if (!rx_thresh && !rx && !tx) {
- spin_unlock_irqrestore(&priv->lock, flags);
- return IRQ_NONE;
- }
- cpsw_intr_disable(priv);
- if (priv->irq_enabled == true) {
+ if (likely(netif_running(priv->ndev))) {
+ cpsw_intr_disable(priv);
cpsw_disable_irq(priv);
- priv->irq_enabled = false;
- }
- spin_unlock_irqrestore(&priv->lock, flags);
-
- if (netif_running(priv->ndev)) {
napi_schedule(&priv->napi);
- return IRQ_HANDLED;
}
+ return IRQ_HANDLED;
+}
- priv = cpsw_get_slave_priv(priv, 1);
- if (!priv)
- return IRQ_NONE;
-
- if (netif_running(priv->ndev)) {
- napi_schedule(&priv->napi);
- return IRQ_HANDLED;
- }
- return IRQ_NONE;
+static inline int cpsw_get_slave_port(struct cpsw_priv *priv, u32 slave_num)
+{
+ if (priv->host_port == 0)
+ return slave_num + 1;
+ else
+ return slave_num;
}
static int cpsw_poll(struct napi_struct *napi, int budget)
{
struct cpsw_priv *priv = napi_to_priv(napi);
int num_tx, num_rx;
- unsigned long flags;
- spin_lock_irqsave(&priv->lock, flags);
num_tx = cpdma_chan_process(priv->txch, 128);
- if (num_tx)
- cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_TX);
-
num_rx = cpdma_chan_process(priv->rxch, budget);
- if (num_rx < budget) {
- struct cpsw_priv *prim_cpsw;
-
- napi_complete(napi);
- cpsw_intr_enable(priv);
- cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_RX);
- prim_cpsw = cpsw_get_slave_priv(priv, 0);
- if (prim_cpsw->irq_enabled == false) {
- cpsw_enable_irq(priv);
- prim_cpsw->irq_enabled = true;
- }
- }
- spin_unlock_irqrestore(&priv->lock, flags);
if (num_rx || num_tx)
cpsw_dbg(priv, intr, "poll %d rx, %d tx pkts\n",
num_rx, num_tx);
+ if (num_rx < budget) {
+ napi_complete(napi);
+ cpsw_intr_enable(priv);
+ cpdma_ctlr_eoi(priv->dma);
+ cpsw_enable_irq(priv);
+ }
+
return num_rx;
}
@@ -659,77 +548,6 @@ static void cpsw_adjust_link(struct net_device *ndev)
}
}
-static int cpsw_get_coalesce(struct net_device *ndev,
- struct ethtool_coalesce *coal)
-{
- struct cpsw_priv *priv = netdev_priv(ndev);
-
- coal->rx_coalesce_usecs = priv->coal_intvl;
- return 0;
-}
-
-static int cpsw_set_coalesce(struct net_device *ndev,
- struct ethtool_coalesce *coal)
-{
- struct cpsw_priv *priv = netdev_priv(ndev);
- u32 int_ctrl;
- u32 num_interrupts = 0;
- u32 prescale = 0;
- u32 addnl_dvdr = 1;
- u32 coal_intvl = 0;
-
- if (!coal->rx_coalesce_usecs)
- return -EINVAL;
-
- coal_intvl = coal->rx_coalesce_usecs;
-
- int_ctrl = readl(&priv->wr_regs->int_control);
- prescale = priv->bus_freq_mhz * 4;
-
- if (coal_intvl < CPSW_CMINTMIN_INTVL)
- coal_intvl = CPSW_CMINTMIN_INTVL;
-
- if (coal_intvl > CPSW_CMINTMAX_INTVL) {
- /* Interrupt pacer works with 4us Pulse, we can
- * throttle further by dilating the 4us pulse.
- */
- addnl_dvdr = CPSW_INTPRESCALE_MASK / prescale;
-
- if (addnl_dvdr > 1) {
- prescale *= addnl_dvdr;
- if (coal_intvl > (CPSW_CMINTMAX_INTVL * addnl_dvdr))
- coal_intvl = (CPSW_CMINTMAX_INTVL
- * addnl_dvdr);
- } else {
- addnl_dvdr = 1;
- coal_intvl = CPSW_CMINTMAX_INTVL;
- }
- }
-
- num_interrupts = (1000 * addnl_dvdr) / coal_intvl;
- writel(num_interrupts, &priv->wr_regs->rx_imax);
- writel(num_interrupts, &priv->wr_regs->tx_imax);
-
- int_ctrl |= CPSW_INTPACEEN;
- int_ctrl &= (~CPSW_INTPRESCALE_MASK);
- int_ctrl |= (prescale & CPSW_INTPRESCALE_MASK);
- writel(int_ctrl, &priv->wr_regs->int_control);
-
- cpsw_notice(priv, timer, "Set coalesce to %d usecs.\n", coal_intvl);
- if (priv->data.dual_emac) {
- int i;
-
- for (i = 0; i < priv->data.slaves; i++) {
- priv = netdev_priv(priv->slaves[i].ndev);
- priv->coal_intvl = coal_intvl;
- }
- } else {
- priv->coal_intvl = coal_intvl;
- }
-
- return 0;
-}
-
static inline int __show_stat(char *buf, int maxlen, const char *name, u32 val)
{
static char *leader = "........................................";
@@ -741,54 +559,6 @@ static inline int __show_stat(char *buf, int maxlen, const char *name, u32 val)
leader + strlen(name), val);
}
-static int cpsw_common_res_usage_state(struct cpsw_priv *priv)
-{
- u32 i;
- u32 usage_count = 0;
-
- if (!priv->data.dual_emac)
- return 0;
-
- for (i = 0; i < priv->data.slaves; i++)
- if (priv->slaves[i].open_stat)
- usage_count++;
-
- return usage_count;
-}
-
-static inline int cpsw_tx_packet_submit(struct net_device *ndev,
- struct cpsw_priv *priv, struct sk_buff *skb)
-{
- if (!priv->data.dual_emac)
- return cpdma_chan_submit(priv->txch, skb, skb->data,
- skb->len, 0);
-
- if (ndev == cpsw_get_slave_ndev(priv, 0))
- return cpdma_chan_submit(priv->txch, skb, skb->data,
- skb->len, 1);
- else
- return cpdma_chan_submit(priv->txch, skb, skb->data,
- skb->len, 2);
-}
-
-static inline void cpsw_add_dual_emac_def_ale_entries(
- struct cpsw_priv *priv, struct cpsw_slave *slave,
- u32 slave_port)
-{
- u32 port_mask = 1 << slave_port | 1 << priv->host_port;
-
- if (priv->version == CPSW_VERSION_1)
- slave_write(slave, slave->port_vlan, CPSW1_PORT_VLAN);
- else
- slave_write(slave, slave->port_vlan, CPSW2_PORT_VLAN);
- cpsw_ale_add_vlan(priv->ale, slave->port_vlan, port_mask,
- port_mask, port_mask, 0);
- cpsw_ale_add_mcast(priv->ale, priv->ndev->broadcast,
- port_mask, ALE_VLAN, slave->port_vlan, 0);
- cpsw_ale_add_ucast(priv->ale, priv->mac_addr,
- priv->host_port, ALE_VLAN, slave->port_vlan);
-}
-
static void cpsw_slave_open(struct cpsw_slave *slave, struct cpsw_priv *priv)
{
char name[32];
@@ -818,11 +588,8 @@ static void cpsw_slave_open(struct cpsw_slave *slave, struct cpsw_priv *priv)
slave_port = cpsw_get_slave_port(priv, slave->slave_num);
- if (priv->data.dual_emac)
- cpsw_add_dual_emac_def_ale_entries(priv, slave, slave_port);
- else
- cpsw_ale_add_mcast(priv->ale, priv->ndev->broadcast,
- 1 << slave_port, 0, 0, ALE_MCAST_FWD_2);
+ cpsw_ale_add_mcast(priv->ale, priv->ndev->broadcast,
+ 1 << slave_port, 0, ALE_MCAST_FWD_2);
slave->phy = phy_connect(priv->ndev, slave->data->phy_id,
&cpsw_adjust_link, 0, slave->data->phy_if);
@@ -837,44 +604,14 @@ static void cpsw_slave_open(struct cpsw_slave *slave, struct cpsw_priv *priv)
}
}
-static inline void cpsw_add_default_vlan(struct cpsw_priv *priv)
-{
- const int vlan = priv->data.default_vlan;
- const int port = priv->host_port;
- u32 reg;
- int i;
-
- reg = (priv->version == CPSW_VERSION_1) ? CPSW1_PORT_VLAN :
- CPSW2_PORT_VLAN;
-
- writel(vlan, &priv->host_port_regs->port_vlan);
-
- for (i = 0; i < priv->data.slaves; i++)
- slave_write(priv->slaves + i, vlan, reg);
-
- cpsw_ale_add_vlan(priv->ale, vlan, ALE_ALL_PORTS << port,
- ALE_ALL_PORTS << port, ALE_ALL_PORTS << port,
- (ALE_PORT_1 | ALE_PORT_2) << port);
-}
-
static void cpsw_init_host_port(struct cpsw_priv *priv)
{
- u32 control_reg;
- u32 fifo_mode;
-
/* soft reset the controller and initialize ale */
soft_reset("cpsw", &priv->regs->soft_reset);
cpsw_ale_start(priv->ale);
/* switch to vlan unaware mode */
- cpsw_ale_control_set(priv->ale, priv->host_port, ALE_VLAN_AWARE,
- CPSW_ALE_VLAN_AWARE);
- control_reg = readl(&priv->regs->control);
- control_reg |= CPSW_VLAN_AWARE;
- writel(control_reg, &priv->regs->control);
- fifo_mode = (priv->data.dual_emac) ? CPSW_FIFO_DUAL_MAC_MODE :
- CPSW_FIFO_NORMAL_MODE;
- writel(fifo_mode, &priv->host_port_regs->tx_in_ctl);
+ cpsw_ale_control_set(priv->ale, 0, ALE_VLAN_AWARE, 0);
/* setup host port priority mapping */
__raw_writel(CPDMA_TX_PRIORITY_MAP,
@@ -884,32 +621,18 @@ static void cpsw_init_host_port(struct cpsw_priv *priv)
cpsw_ale_control_set(priv->ale, priv->host_port,
ALE_PORT_STATE, ALE_PORT_STATE_FORWARD);
- if (!priv->data.dual_emac) {
- cpsw_ale_add_ucast(priv->ale, priv->mac_addr, priv->host_port,
- 0, 0);
- cpsw_ale_add_mcast(priv->ale, priv->ndev->broadcast,
- 1 << priv->host_port, 0, 0, ALE_MCAST_FWD_2);
- }
-}
-
-static void cpsw_slave_stop(struct cpsw_slave *slave, struct cpsw_priv *priv)
-{
- if (!slave->phy)
- return;
- phy_stop(slave->phy);
- phy_disconnect(slave->phy);
- slave->phy = NULL;
+ cpsw_ale_add_ucast(priv->ale, priv->mac_addr, priv->host_port, 0);
+ cpsw_ale_add_mcast(priv->ale, priv->ndev->broadcast,
+ 1 << priv->host_port, 0, ALE_MCAST_FWD_2);
}
static int cpsw_ndo_open(struct net_device *ndev)
{
struct cpsw_priv *priv = netdev_priv(ndev);
- struct cpsw_priv *prim_cpsw;
int i, ret;
u32 reg;
- if (!cpsw_common_res_usage_state(priv))
- cpsw_intr_disable(priv);
+ cpsw_intr_disable(priv);
netif_carrier_off(ndev);
pm_runtime_get_sync(&priv->pdev->dev);
@@ -921,81 +644,53 @@ static int cpsw_ndo_open(struct net_device *ndev)
CPSW_RTL_VERSION(reg));
/* initialize host and slave ports */
- if (!cpsw_common_res_usage_state(priv))
- cpsw_init_host_port(priv);
+ cpsw_init_host_port(priv);
for_each_slave(priv, cpsw_slave_open, priv);
- /* Add default VLAN */
- if (!priv->data.dual_emac)
- cpsw_add_default_vlan(priv);
-
- if (!cpsw_common_res_usage_state(priv)) {
- /* setup tx dma to fixed prio and zero offset */
- cpdma_control_set(priv->dma, CPDMA_TX_PRIO_FIXED, 1);
- cpdma_control_set(priv->dma, CPDMA_RX_BUFFER_OFFSET, 0);
-
- /* disable priority elevation */
- __raw_writel(0, &priv->regs->ptype);
-
- /* enable statistics collection only on all ports */
- __raw_writel(0x7, &priv->regs->stat_port_en);
-
- if (WARN_ON(!priv->data.rx_descs))
- priv->data.rx_descs = 128;
-
- for (i = 0; i < priv->data.rx_descs; i++) {
- struct sk_buff *skb;
-
- ret = -ENOMEM;
- skb = __netdev_alloc_skb_ip_align(priv->ndev,
- priv->rx_packet_max, GFP_KERNEL);
- if (!skb)
- goto err_cleanup;
- ret = cpdma_chan_submit(priv->rxch, skb, skb->data,
- skb_tailroom(skb), 0);
- if (ret < 0) {
- kfree_skb(skb);
- goto err_cleanup;
- }
- }
- /* continue even if we didn't manage to submit all
- * receive descs
- */
- cpsw_info(priv, ifup, "submitted %d rx descriptors\n", i);
- }
+ /* setup tx dma to fixed prio and zero offset */
+ cpdma_control_set(priv->dma, CPDMA_TX_PRIO_FIXED, 1);
+ cpdma_control_set(priv->dma, CPDMA_RX_BUFFER_OFFSET, 0);
- /* Enable Interrupt pacing if configured */
- if (priv->coal_intvl != 0) {
- struct ethtool_coalesce coal;
+ /* disable priority elevation and enable statistics on all ports */
+ __raw_writel(0, &priv->regs->ptype);
- coal.rx_coalesce_usecs = (priv->coal_intvl << 4);
- cpsw_set_coalesce(ndev, &coal);
- }
+ /* enable statistics collection only on the host port */
+ __raw_writel(0x7, &priv->regs->stat_port_en);
- prim_cpsw = cpsw_get_slave_priv(priv, 0);
- if (prim_cpsw->irq_enabled == false) {
- if ((priv == prim_cpsw) || !netif_running(prim_cpsw->ndev)) {
- prim_cpsw->irq_enabled = true;
- cpsw_enable_irq(prim_cpsw);
- }
+ if (WARN_ON(!priv->data.rx_descs))
+ priv->data.rx_descs = 128;
+
+ for (i = 0; i < priv->data.rx_descs; i++) {
+ struct sk_buff *skb;
+
+ ret = -ENOMEM;
+ skb = netdev_alloc_skb_ip_align(priv->ndev,
+ priv->rx_packet_max);
+ if (!skb)
+ break;
+ ret = cpdma_chan_submit(priv->rxch, skb, skb->data,
+ skb_tailroom(skb), GFP_KERNEL);
+ if (WARN_ON(ret < 0))
+ break;
}
+ /* continue even if we didn't manage to submit all receive descs */
+ cpsw_info(priv, ifup, "submitted %d rx descriptors\n", i);
cpdma_ctlr_start(priv->dma);
cpsw_intr_enable(priv);
napi_enable(&priv->napi);
- cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_RX);
- cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_TX);
+ cpdma_ctlr_eoi(priv->dma);
- if (priv->data.dual_emac)
- priv->slaves[priv->emac_port].open_stat = true;
return 0;
+}
-err_cleanup:
- cpdma_ctlr_stop(priv->dma);
- for_each_slave(priv, cpsw_slave_stop, priv);
- pm_runtime_put_sync(&priv->pdev->dev);
- netif_carrier_off(priv->ndev);
- return ret;
+static void cpsw_slave_stop(struct cpsw_slave *slave, struct cpsw_priv *priv)
+{
+ if (!slave->phy)
+ return;
+ phy_stop(slave->phy);
+ phy_disconnect(slave->phy);
+ slave->phy = NULL;
}
static int cpsw_ndo_stop(struct net_device *ndev)
@@ -1006,17 +701,12 @@ static int cpsw_ndo_stop(struct net_device *ndev)
netif_stop_queue(priv->ndev);
napi_disable(&priv->napi);
netif_carrier_off(priv->ndev);
-
- if (cpsw_common_res_usage_state(priv) <= 1) {
- cpsw_intr_disable(priv);
- cpdma_ctlr_int_ctrl(priv->dma, false);
- cpdma_ctlr_stop(priv->dma);
- cpsw_ale_stop(priv->ale);
- }
+ cpsw_intr_disable(priv);
+ cpdma_ctlr_int_ctrl(priv->dma, false);
+ cpdma_ctlr_stop(priv->dma);
+ cpsw_ale_stop(priv->ale);
for_each_slave(priv, cpsw_slave_stop, priv);
pm_runtime_put_sync(&priv->pdev->dev);
- if (priv->data.dual_emac)
- priv->slaves[priv->emac_port].open_stat = false;
return 0;
}
@@ -1034,24 +724,18 @@ static netdev_tx_t cpsw_ndo_start_xmit(struct sk_buff *skb,
return NETDEV_TX_OK;
}
- if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP &&
- priv->cpts->tx_enable)
+ if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP && priv->cpts.tx_enable)
skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
skb_tx_timestamp(skb);
- ret = cpsw_tx_packet_submit(ndev, priv, skb);
+ ret = cpdma_chan_submit(priv->txch, skb, skb->data,
+ skb->len, GFP_KERNEL);
if (unlikely(ret != 0)) {
cpsw_err(priv, tx_err, "desc submit failed\n");
goto fail;
}
- /* If there is no more tx desc left free then we need to
- * tell the kernel to stop sending us tx frames.
- */
- if (unlikely(!cpdma_check_free_tx_desc(priv->txch)))
- netif_stop_queue(ndev);
-
return NETDEV_TX_OK;
fail:
priv->stats.tx_dropped++;
@@ -1086,10 +770,10 @@ static void cpsw_ndo_change_rx_flags(struct net_device *ndev, int flags)
static void cpsw_hwtstamp_v1(struct cpsw_priv *priv)
{
- struct cpsw_slave *slave = &priv->slaves[priv->data.active_slave];
+ struct cpsw_slave *slave = &priv->slaves[priv->data.cpts_active_slave];
u32 ts_en, seq_id;
- if (!priv->cpts->tx_enable && !priv->cpts->rx_enable) {
+ if (!priv->cpts.tx_enable && !priv->cpts.rx_enable) {
slave_write(slave, 0, CPSW1_TS_CTL);
return;
}
@@ -1097,10 +781,10 @@ static void cpsw_hwtstamp_v1(struct cpsw_priv *priv)
seq_id = (30 << CPSW_V1_SEQ_ID_OFS_SHIFT) | ETH_P_1588;
ts_en = EVENT_MSG_BITS << CPSW_V1_MSG_TYPE_OFS;
- if (priv->cpts->tx_enable)
+ if (priv->cpts.tx_enable)
ts_en |= CPSW_V1_TS_TX_EN;
- if (priv->cpts->rx_enable)
+ if (priv->cpts.rx_enable)
ts_en |= CPSW_V1_TS_RX_EN;
slave_write(slave, ts_en, CPSW1_TS_CTL);
@@ -1109,21 +793,16 @@ static void cpsw_hwtstamp_v1(struct cpsw_priv *priv)
static void cpsw_hwtstamp_v2(struct cpsw_priv *priv)
{
- struct cpsw_slave *slave;
+ struct cpsw_slave *slave = &priv->slaves[priv->data.cpts_active_slave];
u32 ctrl, mtype;
- if (priv->data.dual_emac)
- slave = &priv->slaves[priv->emac_port];
- else
- slave = &priv->slaves[priv->data.active_slave];
-
ctrl = slave_read(slave, CPSW2_CONTROL);
ctrl &= ~CTRL_ALL_TS_MASK;
- if (priv->cpts->tx_enable)
+ if (priv->cpts.tx_enable)
ctrl |= CTRL_TX_TS_BITS;
- if (priv->cpts->rx_enable)
+ if (priv->cpts.rx_enable)
ctrl |= CTRL_RX_TS_BITS;
mtype = (30 << TS_SEQ_ID_OFFSET_SHIFT) | EVENT_MSG_BITS;
@@ -1136,7 +815,7 @@ static void cpsw_hwtstamp_v2(struct cpsw_priv *priv)
static int cpsw_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr)
{
struct cpsw_priv *priv = netdev_priv(dev);
- struct cpts *cpts = priv->cpts;
+ struct cpts *cpts = &priv->cpts;
struct hwtstamp_config cfg;
if (copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg)))
@@ -1200,26 +879,14 @@ static int cpsw_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr)
static int cpsw_ndo_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
{
- struct cpsw_priv *priv = netdev_priv(dev);
- struct mii_ioctl_data *data = if_mii(req);
- int slave_no = cpsw_slave_index(priv);
-
if (!netif_running(dev))
return -EINVAL;
- switch (cmd) {
#ifdef CONFIG_TI_CPTS
- case SIOCSHWTSTAMP:
+ if (cmd == SIOCSHWTSTAMP)
return cpsw_hwtstamp_ioctl(dev, req);
#endif
- case SIOCGMIIPHY:
- data->phy_id = priv->slaves[slave_no].phy->addr;
- break;
- default:
- return -ENOTSUPP;
- }
-
- return 0;
+ return -ENOTSUPP;
}
static void cpsw_ndo_tx_timeout(struct net_device *ndev)
@@ -1234,9 +901,7 @@ static void cpsw_ndo_tx_timeout(struct net_device *ndev)
cpdma_chan_start(priv->txch);
cpdma_ctlr_int_ctrl(priv->dma, true);
cpsw_intr_enable(priv);
- cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_RX);
- cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_TX);
-
+ cpdma_ctlr_eoi(priv->dma);
}
static struct net_device_stats *cpsw_ndo_get_stats(struct net_device *ndev)
@@ -1255,79 +920,10 @@ static void cpsw_ndo_poll_controller(struct net_device *ndev)
cpsw_interrupt(ndev->irq, priv);
cpdma_ctlr_int_ctrl(priv->dma, true);
cpsw_intr_enable(priv);
- cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_RX);
- cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_TX);
-
+ cpdma_ctlr_eoi(priv->dma);
}
#endif
-static inline int cpsw_add_vlan_ale_entry(struct cpsw_priv *priv,
- unsigned short vid)
-{
- int ret;
-
- ret = cpsw_ale_add_vlan(priv->ale, vid,
- ALE_ALL_PORTS << priv->host_port,
- 0, ALE_ALL_PORTS << priv->host_port,
- (ALE_PORT_1 | ALE_PORT_2) << priv->host_port);
- if (ret != 0)
- return ret;
-
- ret = cpsw_ale_add_ucast(priv->ale, priv->mac_addr,
- priv->host_port, ALE_VLAN, vid);
- if (ret != 0)
- goto clean_vid;
-
- ret = cpsw_ale_add_mcast(priv->ale, priv->ndev->broadcast,
- ALE_ALL_PORTS << priv->host_port,
- ALE_VLAN, vid, 0);
- if (ret != 0)
- goto clean_vlan_ucast;
- return 0;
-
-clean_vlan_ucast:
- cpsw_ale_del_ucast(priv->ale, priv->mac_addr,
- priv->host_port, ALE_VLAN, vid);
-clean_vid:
- cpsw_ale_del_vlan(priv->ale, vid, 0);
- return ret;
-}
-
-static int cpsw_ndo_vlan_rx_add_vid(struct net_device *ndev,
- unsigned short vid)
-{
- struct cpsw_priv *priv = netdev_priv(ndev);
-
- if (vid == priv->data.default_vlan)
- return 0;
-
- dev_info(priv->dev, "Adding vlanid %d to vlan filter\n", vid);
- return cpsw_add_vlan_ale_entry(priv, vid);
-}
-
-static int cpsw_ndo_vlan_rx_kill_vid(struct net_device *ndev,
- unsigned short vid)
-{
- struct cpsw_priv *priv = netdev_priv(ndev);
- int ret;
-
- if (vid == priv->data.default_vlan)
- return 0;
-
- dev_info(priv->dev, "removing vlanid %d from vlan filter\n", vid);
- ret = cpsw_ale_del_vlan(priv->ale, vid, 0);
- if (ret != 0)
- return ret;
-
- ret = cpsw_ale_del_ucast(priv->ale, priv->mac_addr,
- priv->host_port, ALE_VLAN, vid);
- if (ret != 0)
- return ret;
-
- return cpsw_ale_del_mcast(priv->ale, priv->ndev->broadcast,
- 0, ALE_VLAN, vid);
-}
-
static const struct net_device_ops cpsw_netdev_ops = {
.ndo_open = cpsw_ndo_open,
.ndo_stop = cpsw_ndo_stop,
@@ -1342,18 +938,15 @@ static const struct net_device_ops cpsw_netdev_ops = {
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = cpsw_ndo_poll_controller,
#endif
- .ndo_vlan_rx_add_vid = cpsw_ndo_vlan_rx_add_vid,
- .ndo_vlan_rx_kill_vid = cpsw_ndo_vlan_rx_kill_vid,
};
static void cpsw_get_drvinfo(struct net_device *ndev,
struct ethtool_drvinfo *info)
{
struct cpsw_priv *priv = netdev_priv(ndev);
-
- strlcpy(info->driver, "TI CPSW Driver v1.0", sizeof(info->driver));
- strlcpy(info->version, "1.0", sizeof(info->version));
- strlcpy(info->bus_info, priv->pdev->name, sizeof(info->bus_info));
+ strcpy(info->driver, "TI CPSW Driver v1.0");
+ strcpy(info->version, "1.0");
+ strcpy(info->bus_info, priv->pdev->name);
}
static u32 cpsw_get_msglevel(struct net_device *ndev)
@@ -1381,7 +974,7 @@ static int cpsw_get_ts_info(struct net_device *ndev,
SOF_TIMESTAMPING_RX_SOFTWARE |
SOF_TIMESTAMPING_SOFTWARE |
SOF_TIMESTAMPING_RAW_HARDWARE;
- info->phc_index = priv->cpts->phc_index;
+ info->phc_index = priv->cpts.phc_index;
info->tx_types =
(1 << HWTSTAMP_TX_OFF) |
(1 << HWTSTAMP_TX_ON);
@@ -1400,39 +993,12 @@ static int cpsw_get_ts_info(struct net_device *ndev,
return 0;
}
-static int cpsw_get_settings(struct net_device *ndev,
- struct ethtool_cmd *ecmd)
-{
- struct cpsw_priv *priv = netdev_priv(ndev);
- int slave_no = cpsw_slave_index(priv);
-
- if (priv->slaves[slave_no].phy)
- return phy_ethtool_gset(priv->slaves[slave_no].phy, ecmd);
- else
- return -EOPNOTSUPP;
-}
-
-static int cpsw_set_settings(struct net_device *ndev, struct ethtool_cmd *ecmd)
-{
- struct cpsw_priv *priv = netdev_priv(ndev);
- int slave_no = cpsw_slave_index(priv);
-
- if (priv->slaves[slave_no].phy)
- return phy_ethtool_sset(priv->slaves[slave_no].phy, ecmd);
- else
- return -EOPNOTSUPP;
-}
-
static const struct ethtool_ops cpsw_ethtool_ops = {
.get_drvinfo = cpsw_get_drvinfo,
.get_msglevel = cpsw_get_msglevel,
.set_msglevel = cpsw_set_msglevel,
.get_link = ethtool_op_get_link,
.get_ts_info = cpsw_get_ts_info,
- .get_settings = cpsw_get_settings,
- .set_settings = cpsw_set_settings,
- .get_coalesce = cpsw_get_coalesce,
- .set_coalesce = cpsw_set_coalesce,
};
static void cpsw_slave_init(struct cpsw_slave *slave, struct cpsw_priv *priv,
@@ -1445,7 +1011,6 @@ static void cpsw_slave_init(struct cpsw_slave *slave, struct cpsw_priv *priv,
slave->data = data;
slave->regs = regs + slave_reg_ofs;
slave->sliver = regs + sliver_reg_ofs;
- slave->port_vlan = data->dual_emac_res_vlan;
}
static int cpsw_probe_dt(struct cpsw_platform_data *data,
@@ -1465,16 +1030,12 @@ static int cpsw_probe_dt(struct cpsw_platform_data *data,
}
data->slaves = prop;
- if (of_property_read_u32(node, "active_slave", &prop)) {
- pr_err("Missing active_slave property in the DT.\n");
- if (of_property_read_u32(node, "cpts_active_slave", &prop)) {
- ret = -EINVAL;
- goto error_ret;
- } else {
- pr_err("Using old cpts_active_slave as fallback.\n");
- }
+ if (of_property_read_u32(node, "cpts_active_slave", &prop)) {
+ pr_err("Missing cpts_active_slave property in the DT.\n");
+ ret = -EINVAL;
+ goto error_ret;
}
- data->active_slave = prop;
+ data->cpts_active_slave = prop;
if (of_property_read_u32(node, "cpts_clock_mult", &prop)) {
pr_err("Missing cpts_clock_mult property in the DT.\n");
@@ -1490,10 +1051,12 @@ static int cpsw_probe_dt(struct cpsw_platform_data *data,
}
data->cpts_clock_shift = prop;
- data->slave_data = kcalloc(data->slaves, sizeof(struct cpsw_slave_data),
- GFP_KERNEL);
- if (!data->slave_data)
+ data->slave_data = kzalloc(sizeof(struct cpsw_slave_data) *
+ data->slaves, GFP_KERNEL);
+ if (!data->slave_data) {
+ pr_err("Could not allocate slave memory.\n");
return -EINVAL;
+ }
if (of_property_read_u32(node, "cpdma_channels", &prop)) {
pr_err("Missing cpdma_channels property in the DT.\n");
@@ -1530,9 +1093,6 @@ static int cpsw_probe_dt(struct cpsw_platform_data *data,
}
data->mac_control = prop;
- if (!of_property_read_u32(node, "dual_emac", &prop))
- data->dual_emac = prop;
-
/*
* Populate all the child nodes here...
*/
@@ -1551,7 +1111,7 @@ static int cpsw_probe_dt(struct cpsw_platform_data *data,
struct platform_device *mdio;
parp = of_get_property(slave_node, "phy_id", &lenp);
- if ((parp == NULL) || (lenp != (sizeof(void *) * 2))) {
+ if ((parp == NULL) && (lenp != (sizeof(void *) * 2))) {
pr_err("Missing slave[%d] phy_id property\n", i);
ret = -EINVAL;
goto error_ret;
@@ -1566,18 +1126,6 @@ static int cpsw_probe_dt(struct cpsw_platform_data *data,
if (mac_addr)
memcpy(slave_data->mac_addr, mac_addr, ETH_ALEN);
- if (data->dual_emac) {
- if (of_property_read_u32(slave_node, "dual_emac_res_vlan",
- &prop)) {
- pr_err("Missing dual_emac_res_vlan in DT.\n");
- slave_data->dual_emac_res_vlan = i+1;
- pr_err("Using %d as Reserved VLAN for %d slave\n",
- slave_data->dual_emac_res_vlan, i);
- } else {
- slave_data->dual_emac_res_vlan = prop;
- }
- }
-
i++;
}
@@ -1588,84 +1136,9 @@ error_ret:
return ret;
}
-static int cpsw_probe_dual_emac(struct platform_device *pdev,
- struct cpsw_priv *priv)
-{
- struct cpsw_platform_data *data = &priv->data;
- struct net_device *ndev;
- struct cpsw_priv *priv_sl2;
- int ret = 0, i;
-
- ndev = alloc_etherdev(sizeof(struct cpsw_priv));
- if (!ndev) {
- pr_err("cpsw: error allocating net_device\n");
- return -ENOMEM;
- }
-
- priv_sl2 = netdev_priv(ndev);
- spin_lock_init(&priv_sl2->lock);
- priv_sl2->data = *data;
- priv_sl2->pdev = pdev;
- priv_sl2->ndev = ndev;
- priv_sl2->dev = &ndev->dev;
- priv_sl2->msg_enable = netif_msg_init(debug_level, CPSW_DEBUG);
- priv_sl2->rx_packet_max = max(rx_packet_max, 128);
-
- if (is_valid_ether_addr(data->slave_data[1].mac_addr)) {
- memcpy(priv_sl2->mac_addr, data->slave_data[1].mac_addr,
- ETH_ALEN);
- pr_info("cpsw: Detected MACID = %pM\n", priv_sl2->mac_addr);
- } else {
- random_ether_addr(priv_sl2->mac_addr);
- pr_info("cpsw: Random MACID = %pM\n", priv_sl2->mac_addr);
- }
- memcpy(ndev->dev_addr, priv_sl2->mac_addr, ETH_ALEN);
-
- priv_sl2->slaves = priv->slaves;
- priv_sl2->clk = priv->clk;
-
- priv_sl2->coal_intvl = 0;
- priv_sl2->bus_freq_mhz = priv->bus_freq_mhz;
-
- priv_sl2->cpsw_res = priv->cpsw_res;
- priv_sl2->regs = priv->regs;
- priv_sl2->host_port = priv->host_port;
- priv_sl2->host_port_regs = priv->host_port_regs;
- priv_sl2->wr_regs = priv->wr_regs;
- priv_sl2->dma = priv->dma;
- priv_sl2->txch = priv->txch;
- priv_sl2->rxch = priv->rxch;
- priv_sl2->ale = priv->ale;
- priv_sl2->emac_port = 1;
- priv->slaves[1].ndev = ndev;
- priv_sl2->cpts = priv->cpts;
- priv_sl2->version = priv->version;
-
- for (i = 0; i < priv->num_irqs; i++) {
- priv_sl2->irqs_table[i] = priv->irqs_table[i];
- priv_sl2->num_irqs = priv->num_irqs;
- }
- ndev->features |= NETIF_F_HW_VLAN_FILTER;
-
- ndev->netdev_ops = &cpsw_netdev_ops;
- SET_ETHTOOL_OPS(ndev, &cpsw_ethtool_ops);
- netif_napi_add(ndev, &priv_sl2->napi, cpsw_poll, CPSW_POLL_WEIGHT);
-
- /* register the network device */
- SET_NETDEV_DEV(ndev, &pdev->dev);
- ret = register_netdev(ndev);
- if (ret) {
- pr_err("cpsw: error registering net device\n");
- free_netdev(ndev);
- ret = -ENODEV;
- }
-
- return ret;
-}
-
static int cpsw_probe(struct platform_device *pdev)
{
- struct cpsw_platform_data *data;
+ struct cpsw_platform_data *data = pdev->dev.platform_data;
struct net_device *ndev;
struct cpsw_priv *priv;
struct cpdma_params dma_params;
@@ -1689,11 +1162,6 @@ static int cpsw_probe(struct platform_device *pdev)
priv->dev = &ndev->dev;
priv->msg_enable = netif_msg_init(debug_level, CPSW_DEBUG);
priv->rx_packet_max = max(rx_packet_max, 128);
- priv->cpts = devm_kzalloc(&pdev->dev, sizeof(struct cpts), GFP_KERNEL);
- if (!ndev) {
- pr_err("error allocating cpts\n");
- goto clean_ndev_ret;
- }
/*
* This may be required here for child devices.
@@ -1726,17 +1194,12 @@ static int cpsw_probe(struct platform_device *pdev)
for (i = 0; i < data->slaves; i++)
priv->slaves[i].slave_num = i;
- priv->slaves[0].ndev = ndev;
- priv->emac_port = 0;
-
priv->clk = clk_get(&pdev->dev, "fck");
if (IS_ERR(priv->clk)) {
dev_err(&pdev->dev, "fck is not found\n");
ret = -ENODEV;
goto clean_slave_ret;
}
- priv->coal_intvl = 0;
- priv->bus_freq_mhz = clk_get_rate(priv->clk) / 1000000;
priv->cpsw_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!priv->cpsw_res) {
@@ -1785,7 +1248,7 @@ static int cpsw_probe(struct platform_device *pdev)
switch (priv->version) {
case CPSW_VERSION_1:
priv->host_port_regs = ss_regs + CPSW1_HOST_PORT_OFFSET;
- priv->cpts->reg = ss_regs + CPSW1_CPTS_OFFSET;
+ priv->cpts.reg = ss_regs + CPSW1_CPTS_OFFSET;
dma_params.dmaregs = ss_regs + CPSW1_CPDMA_OFFSET;
dma_params.txhdp = ss_regs + CPSW1_STATERAM_OFFSET;
ale_params.ale_regs = ss_regs + CPSW1_ALE_OFFSET;
@@ -1796,7 +1259,7 @@ static int cpsw_probe(struct platform_device *pdev)
break;
case CPSW_VERSION_2:
priv->host_port_regs = ss_regs + CPSW2_HOST_PORT_OFFSET;
- priv->cpts->reg = ss_regs + CPSW2_CPTS_OFFSET;
+ priv->cpts.reg = ss_regs + CPSW2_CPTS_OFFSET;
dma_params.dmaregs = ss_regs + CPSW2_CPDMA_OFFSET;
dma_params.txhdp = ss_regs + CPSW2_STATERAM_OFFSET;
ale_params.ale_regs = ss_regs + CPSW2_ALE_OFFSET;
@@ -1878,13 +1341,12 @@ static int cpsw_probe(struct platform_device *pdev)
goto clean_ale_ret;
}
priv->irqs_table[k] = i;
- priv->num_irqs = k + 1;
+ priv->num_irqs = k;
}
k++;
}
- priv->irq_enabled = true;
- ndev->features |= NETIF_F_HW_VLAN_FILTER;
+ ndev->flags |= IFF_ALLMULTI; /* see cpsw_ndo_change_rx_flags() */
ndev->netdev_ops = &cpsw_netdev_ops;
SET_ETHTOOL_OPS(ndev, &cpsw_ethtool_ops);
@@ -1899,26 +1361,17 @@ static int cpsw_probe(struct platform_device *pdev)
goto clean_irq_ret;
}
- if (cpts_register(&pdev->dev, priv->cpts,
+ if (cpts_register(&pdev->dev, &priv->cpts,
data->cpts_clock_mult, data->cpts_clock_shift))
dev_err(priv->dev, "error registering cpts device\n");
cpsw_notice(priv, probe, "initialized device (regs %x, irq %d)\n",
priv->cpsw_res->start, ndev->irq);
- if (priv->data.dual_emac) {
- ret = cpsw_probe_dual_emac(pdev, priv);
- if (ret) {
- cpsw_err(priv, probe, "error probe slave 2 emac interface\n");
- goto clean_irq_ret;
- }
- }
-
return 0;
clean_irq_ret:
- for (i = 0; i < priv->num_irqs; i++)
- free_irq(priv->irqs_table[i], priv);
+ free_irq(ndev->irq, priv);
clean_ale_ret:
cpsw_ale_destroy(priv->ale);
clean_dma_ret:
@@ -1941,8 +1394,7 @@ clean_slave_ret:
pm_runtime_disable(&pdev->dev);
kfree(priv->slaves);
clean_ndev_ret:
- kfree(priv->data.slave_data);
- free_netdev(priv->ndev);
+ free_netdev(ndev);
return ret;
}
@@ -1950,17 +1402,12 @@ static int cpsw_remove(struct platform_device *pdev)
{
struct net_device *ndev = platform_get_drvdata(pdev);
struct cpsw_priv *priv = netdev_priv(ndev);
- int i;
+ pr_info("removing device");
platform_set_drvdata(pdev, NULL);
- if (priv->data.dual_emac)
- unregister_netdev(cpsw_get_slave_ndev(priv, 1));
- unregister_netdev(ndev);
-
- cpts_unregister(priv->cpts);
- for (i = 0; i < priv->num_irqs; i++)
- free_irq(priv->irqs_table[i], priv);
+ cpts_unregister(&priv->cpts);
+ free_irq(ndev->irq, priv);
cpsw_ale_destroy(priv->ale);
cpdma_chan_destroy(priv->txch);
cpdma_chan_destroy(priv->rxch);
@@ -1974,10 +1421,8 @@ static int cpsw_remove(struct platform_device *pdev)
pm_runtime_disable(&pdev->dev);
clk_put(priv->clk);
kfree(priv->slaves);
- kfree(priv->data.slave_data);
- if (priv->data.dual_emac)
- free_netdev(cpsw_get_slave_ndev(priv, 1));
free_netdev(ndev);
+
return 0;
}
@@ -2013,7 +1458,6 @@ static const struct of_device_id cpsw_of_mtable[] = {
{ .compatible = "ti,cpsw", },
{ /* sentinel */ },
};
-MODULE_DEVICE_TABLE(of, cpsw_of_mtable);
static struct platform_driver cpsw_driver = {
.driver = {
diff --git a/drivers/net/ethernet/ti/cpsw_ale.c b/drivers/net/ethernet/ti/cpsw_ale.c
index 7fa60d6..0e9ccc2 100644
--- a/drivers/net/ethernet/ti/cpsw_ale.c
+++ b/drivers/net/ethernet/ti/cpsw_ale.c
@@ -148,7 +148,7 @@ static int cpsw_ale_write(struct cpsw_ale *ale, int idx, u32 *ale_entry)
return idx;
}
-int cpsw_ale_match_addr(struct cpsw_ale *ale, u8 *addr, u16 vid)
+static int cpsw_ale_match_addr(struct cpsw_ale *ale, u8 *addr)
{
u32 ale_entry[ALE_ENTRY_WORDS];
int type, idx;
@@ -160,8 +160,6 @@ int cpsw_ale_match_addr(struct cpsw_ale *ale, u8 *addr, u16 vid)
type = cpsw_ale_get_entry_type(ale_entry);
if (type != ALE_TYPE_ADDR && type != ALE_TYPE_VLAN_ADDR)
continue;
- if (cpsw_ale_get_vlan_id(ale_entry) != vid)
- continue;
cpsw_ale_get_addr(ale_entry, entry_addr);
if (memcmp(entry_addr, addr, 6) == 0)
return idx;
@@ -169,22 +167,6 @@ int cpsw_ale_match_addr(struct cpsw_ale *ale, u8 *addr, u16 vid)
return -ENOENT;
}
-int cpsw_ale_match_vlan(struct cpsw_ale *ale, u16 vid)
-{
- u32 ale_entry[ALE_ENTRY_WORDS];
- int type, idx;
-
- for (idx = 0; idx < ale->params.ale_entries; idx++) {
- cpsw_ale_read(ale, idx, ale_entry);
- type = cpsw_ale_get_entry_type(ale_entry);
- if (type != ALE_TYPE_VLAN)
- continue;
- if (cpsw_ale_get_vlan_id(ale_entry) == vid)
- return idx;
- }
- return -ENOENT;
-}
-
static int cpsw_ale_match_free(struct cpsw_ale *ale)
{
u32 ale_entry[ALE_ENTRY_WORDS];
@@ -292,32 +274,19 @@ int cpsw_ale_flush(struct cpsw_ale *ale, int port_mask)
return 0;
}
-static inline void cpsw_ale_set_vlan_entry_type(u32 *ale_entry,
- int flags, u16 vid)
-{
- if (flags & ALE_VLAN) {
- cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_VLAN_ADDR);
- cpsw_ale_set_vlan_id(ale_entry, vid);
- } else {
- cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_ADDR);
- }
-}
-
-int cpsw_ale_add_ucast(struct cpsw_ale *ale, u8 *addr, int port,
- int flags, u16 vid)
+int cpsw_ale_add_ucast(struct cpsw_ale *ale, u8 *addr, int port, int flags)
{
u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0};
int idx;
- cpsw_ale_set_vlan_entry_type(ale_entry, flags, vid);
-
+ cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_ADDR);
cpsw_ale_set_addr(ale_entry, addr);
cpsw_ale_set_ucast_type(ale_entry, ALE_UCAST_PERSISTANT);
cpsw_ale_set_secure(ale_entry, (flags & ALE_SECURE) ? 1 : 0);
cpsw_ale_set_blocked(ale_entry, (flags & ALE_BLOCKED) ? 1 : 0);
cpsw_ale_set_port_num(ale_entry, port);
- idx = cpsw_ale_match_addr(ale, addr, (flags & ALE_VLAN) ? vid : 0);
+ idx = cpsw_ale_match_addr(ale, addr);
if (idx < 0)
idx = cpsw_ale_match_free(ale);
if (idx < 0)
@@ -329,13 +298,12 @@ int cpsw_ale_add_ucast(struct cpsw_ale *ale, u8 *addr, int port,
return 0;
}
-int cpsw_ale_del_ucast(struct cpsw_ale *ale, u8 *addr, int port,
- int flags, u16 vid)
+int cpsw_ale_del_ucast(struct cpsw_ale *ale, u8 *addr, int port)
{
u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0};
int idx;
- idx = cpsw_ale_match_addr(ale, addr, (flags & ALE_VLAN) ? vid : 0);
+ idx = cpsw_ale_match_addr(ale, addr);
if (idx < 0)
return -ENOENT;
@@ -345,19 +313,18 @@ int cpsw_ale_del_ucast(struct cpsw_ale *ale, u8 *addr, int port,
}
int cpsw_ale_add_mcast(struct cpsw_ale *ale, u8 *addr, int port_mask,
- int flags, u16 vid, int mcast_state)
+ int super, int mcast_state)
{
u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0};
int idx, mask;
- idx = cpsw_ale_match_addr(ale, addr, (flags & ALE_VLAN) ? vid : 0);
+ idx = cpsw_ale_match_addr(ale, addr);
if (idx >= 0)
cpsw_ale_read(ale, idx, ale_entry);
- cpsw_ale_set_vlan_entry_type(ale_entry, flags, vid);
-
+ cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_ADDR);
cpsw_ale_set_addr(ale_entry, addr);
- cpsw_ale_set_super(ale_entry, (flags & ALE_BLOCKED) ? 1 : 0);
+ cpsw_ale_set_super(ale_entry, super);
cpsw_ale_set_mcast_state(ale_entry, mcast_state);
mask = cpsw_ale_get_port_mask(ale_entry);
@@ -375,13 +342,12 @@ int cpsw_ale_add_mcast(struct cpsw_ale *ale, u8 *addr, int port_mask,
return 0;
}
-int cpsw_ale_del_mcast(struct cpsw_ale *ale, u8 *addr, int port_mask,
- int flags, u16 vid)
+int cpsw_ale_del_mcast(struct cpsw_ale *ale, u8 *addr, int port_mask)
{
u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0};
int idx;
- idx = cpsw_ale_match_addr(ale, addr, (flags & ALE_VLAN) ? vid : 0);
+ idx = cpsw_ale_match_addr(ale, addr);
if (idx < 0)
return -EINVAL;
@@ -396,55 +362,6 @@ int cpsw_ale_del_mcast(struct cpsw_ale *ale, u8 *addr, int port_mask,
return 0;
}
-int cpsw_ale_add_vlan(struct cpsw_ale *ale, u16 vid, int port, int untag,
- int reg_mcast, int unreg_mcast)
-{
- u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0};
- int idx;
-
- idx = cpsw_ale_match_vlan(ale, vid);
- if (idx >= 0)
- cpsw_ale_read(ale, idx, ale_entry);
-
- cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_VLAN);
- cpsw_ale_set_vlan_id(ale_entry, vid);
-
- cpsw_ale_set_vlan_untag_force(ale_entry, untag);
- cpsw_ale_set_vlan_reg_mcast(ale_entry, reg_mcast);
- cpsw_ale_set_vlan_unreg_mcast(ale_entry, unreg_mcast);
- cpsw_ale_set_vlan_member_list(ale_entry, port);
-
- if (idx < 0)
- idx = cpsw_ale_match_free(ale);
- if (idx < 0)
- idx = cpsw_ale_find_ageable(ale);
- if (idx < 0)
- return -ENOMEM;
-
- cpsw_ale_write(ale, idx, ale_entry);
- return 0;
-}
-
-int cpsw_ale_del_vlan(struct cpsw_ale *ale, u16 vid, int port_mask)
-{
- u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0};
- int idx;
-
- idx = cpsw_ale_match_vlan(ale, vid);
- if (idx < 0)
- return -ENOENT;
-
- cpsw_ale_read(ale, idx, ale_entry);
-
- if (port_mask)
- cpsw_ale_set_vlan_member_list(ale_entry, port_mask);
- else
- cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_FREE);
-
- cpsw_ale_write(ale, idx, ale_entry);
- return 0;
-}
-
struct ale_control_info {
const char *name;
int offset, port_offset;
diff --git a/drivers/net/ethernet/ti/cpsw_ale.h b/drivers/net/ethernet/ti/cpsw_ale.h
index 30daa12..2bd09cb 100644
--- a/drivers/net/ethernet/ti/cpsw_ale.h
+++ b/drivers/net/ethernet/ti/cpsw_ale.h
@@ -64,14 +64,8 @@ enum cpsw_ale_port_state {
};
/* ALE unicast entry flags - passed into cpsw_ale_add_ucast() */
-#define ALE_SECURE BIT(0)
-#define ALE_BLOCKED BIT(1)
-#define ALE_SUPER BIT(2)
-#define ALE_VLAN BIT(3)
-
-#define ALE_PORT_HOST BIT(0)
-#define ALE_PORT_1 BIT(1)
-#define ALE_PORT_2 BIT(2)
+#define ALE_SECURE 1
+#define ALE_BLOCKED 2
#define ALE_MCAST_FWD 0
#define ALE_MCAST_BLOCK_LEARN_FWD 1
@@ -87,17 +81,11 @@ void cpsw_ale_stop(struct cpsw_ale *ale);
int cpsw_ale_set_ageout(struct cpsw_ale *ale, int ageout);
int cpsw_ale_flush(struct cpsw_ale *ale, int port_mask);
int cpsw_ale_flush_multicast(struct cpsw_ale *ale, int port_mask);
-int cpsw_ale_add_ucast(struct cpsw_ale *ale, u8 *addr, int port,
- int flags, u16 vid);
-int cpsw_ale_del_ucast(struct cpsw_ale *ale, u8 *addr, int port,
- int flags, u16 vid);
+int cpsw_ale_add_ucast(struct cpsw_ale *ale, u8 *addr, int port, int flags);
+int cpsw_ale_del_ucast(struct cpsw_ale *ale, u8 *addr, int port);
int cpsw_ale_add_mcast(struct cpsw_ale *ale, u8 *addr, int port_mask,
- int flags, u16 vid, int mcast_state);
-int cpsw_ale_del_mcast(struct cpsw_ale *ale, u8 *addr, int port_mask,
- int flags, u16 vid);
-int cpsw_ale_add_vlan(struct cpsw_ale *ale, u16 vid, int port, int untag,
- int reg_mcast, int unreg_mcast);
-int cpsw_ale_del_vlan(struct cpsw_ale *ale, u16 vid, int port);
+ int super, int mcast_state);
+int cpsw_ale_del_mcast(struct cpsw_ale *ale, u8 *addr, int port_mask);
int cpsw_ale_control_get(struct cpsw_ale *ale, int port, int control);
int cpsw_ale_control_set(struct cpsw_ale *ale, int port,
diff --git a/drivers/net/ethernet/ti/davinci_cpdma.c b/drivers/net/ethernet/ti/davinci_cpdma.c
index 49dfd59..4995673 100644
--- a/drivers/net/ethernet/ti/davinci_cpdma.c
+++ b/drivers/net/ethernet/ti/davinci_cpdma.c
@@ -20,7 +20,6 @@
#include <linux/err.h>
#include <linux/dma-mapping.h>
#include <linux/io.h>
-#include <linux/delay.h>
#include "davinci_cpdma.h"
@@ -61,9 +60,6 @@
#define CPDMA_DESC_EOQ BIT(28)
#define CPDMA_DESC_TD_COMPLETE BIT(27)
#define CPDMA_DESC_PASS_CRC BIT(26)
-#define CPDMA_DESC_TO_PORT_EN BIT(20)
-#define CPDMA_TO_PORT_SHIFT 16
-#define CPDMA_DESC_PORT_MASK (BIT(18) | BIT(17) | BIT(16))
#define CPDMA_TEARDOWN_VALUE 0xfffffffc
@@ -109,13 +105,13 @@ struct cpdma_ctlr {
};
struct cpdma_chan {
- struct cpdma_desc __iomem *head, *tail;
- void __iomem *hdp, *cp, *rxfree;
enum cpdma_state state;
struct cpdma_ctlr *ctlr;
int chan_num;
spinlock_t lock;
+ struct cpdma_desc __iomem *head, *tail;
int count;
+ void __iomem *hdp, *cp, *rxfree;
u32 mask;
cpdma_handler_fn handler;
enum dma_data_direction dir;
@@ -136,14 +132,6 @@ struct cpdma_chan {
#define chan_write(chan, fld, v) __raw_writel(v, (chan)->fld)
#define desc_write(desc, fld, v) __raw_writel((u32)(v), &(desc)->fld)
-#define cpdma_desc_to_port(chan, mode, directed) \
- do { \
- if (!is_rx_chan(chan) && ((directed == 1) || \
- (directed == 2))) \
- mode |= (CPDMA_DESC_TO_PORT_EN | \
- (directed << CPDMA_TO_PORT_SHIFT)); \
- } while (0)
-
/*
* Utility constructs for a cpdma descriptor pool. Some devices (e.g. davinci
* emac) have dedicated on-chip memory for these descriptors. Some other
@@ -229,27 +217,17 @@ desc_from_phys(struct cpdma_desc_pool *pool, dma_addr_t dma)
}
static struct cpdma_desc __iomem *
-cpdma_desc_alloc(struct cpdma_desc_pool *pool, int num_desc, bool is_rx)
+cpdma_desc_alloc(struct cpdma_desc_pool *pool, int num_desc)
{
unsigned long flags;
int index;
- int desc_start;
- int desc_end;
struct cpdma_desc __iomem *desc = NULL;
spin_lock_irqsave(&pool->lock, flags);
- if (is_rx) {
- desc_start = 0;
- desc_end = pool->num_desc/2;
- } else {
- desc_start = pool->num_desc/2;
- desc_end = pool->num_desc;
- }
-
- index = bitmap_find_next_zero_area(pool->bitmap,
- desc_end, desc_start, num_desc, 0);
- if (index < desc_end) {
+ index = bitmap_find_next_zero_area(pool->bitmap, pool->num_desc, 0,
+ num_desc, 0);
+ if (index < pool->num_desc) {
bitmap_set(pool->bitmap, index, num_desc);
desc = pool->iomap + pool->desc_size * index;
pool->used_desc++;
@@ -313,16 +291,14 @@ int cpdma_ctlr_start(struct cpdma_ctlr *ctlr)
}
if (ctlr->params.has_soft_reset) {
- unsigned timeout = 10 * 100;
+ unsigned long timeout = jiffies + HZ/10;
dma_reg_write(ctlr, CPDMA_SOFTRESET, 1);
- while (timeout) {
+ while (time_before(jiffies, timeout)) {
if (dma_reg_read(ctlr, CPDMA_SOFTRESET) == 0)
break;
- udelay(10);
- timeout--;
}
- WARN_ON(!timeout);
+ WARN_ON(!time_before(jiffies, timeout));
}
for (i = 0; i < ctlr->num_chan; i++) {
@@ -463,8 +439,10 @@ int cpdma_ctlr_destroy(struct cpdma_ctlr *ctlr)
if (ctlr->state != CPDMA_STATE_IDLE)
cpdma_ctlr_stop(ctlr);
- for (i = 0; i < ARRAY_SIZE(ctlr->channels); i++)
- cpdma_chan_destroy(ctlr->channels[i]);
+ for (i = 0; i < ARRAY_SIZE(ctlr->channels); i++) {
+ if (ctlr->channels[i])
+ cpdma_chan_destroy(ctlr->channels[i]);
+ }
cpdma_desc_pool_destroy(ctlr->pool);
spin_unlock_irqrestore(&ctlr->lock, flags);
@@ -495,13 +473,11 @@ int cpdma_ctlr_int_ctrl(struct cpdma_ctlr *ctlr, bool enable)
spin_unlock_irqrestore(&ctlr->lock, flags);
return 0;
}
-EXPORT_SYMBOL_GPL(cpdma_ctlr_int_ctrl);
-void cpdma_ctlr_eoi(struct cpdma_ctlr *ctlr, u32 value)
+void cpdma_ctlr_eoi(struct cpdma_ctlr *ctlr)
{
- dma_reg_write(ctlr, CPDMA_MACEOIVECTOR, value);
+ dma_reg_write(ctlr, CPDMA_MACEOIVECTOR, 0);
}
-EXPORT_SYMBOL_GPL(cpdma_ctlr_eoi);
struct cpdma_chan *cpdma_chan_create(struct cpdma_ctlr *ctlr, int chan_num,
cpdma_handler_fn handler)
@@ -676,7 +652,7 @@ static void __cpdma_chan_submit(struct cpdma_chan *chan,
}
int cpdma_chan_submit(struct cpdma_chan *chan, void *token, void *data,
- int len, int directed)
+ int len, gfp_t gfp_mask)
{
struct cpdma_ctlr *ctlr = chan->ctlr;
struct cpdma_desc __iomem *desc;
@@ -692,7 +668,7 @@ int cpdma_chan_submit(struct cpdma_chan *chan, void *token, void *data,
goto unlock_ret;
}
- desc = cpdma_desc_alloc(ctlr->pool, 1, is_rx_chan(chan));
+ desc = cpdma_desc_alloc(ctlr->pool, 1);
if (!desc) {
chan->stats.desc_alloc_fail++;
ret = -ENOMEM;
@@ -706,7 +682,6 @@ int cpdma_chan_submit(struct cpdma_chan *chan, void *token, void *data,
buffer = dma_map_single(ctlr->dev, data, len, chan->dir);
mode = CPDMA_DESC_OWNER | CPDMA_DESC_SOP | CPDMA_DESC_EOP;
- cpdma_desc_to_port(chan, mode, directed);
desc_write(desc, hw_next, 0);
desc_write(desc, hw_buffer, buffer);
@@ -729,29 +704,6 @@ unlock_ret:
}
EXPORT_SYMBOL_GPL(cpdma_chan_submit);
-bool cpdma_check_free_tx_desc(struct cpdma_chan *chan)
-{
- unsigned long flags;
- int index;
- bool ret;
- struct cpdma_ctlr *ctlr = chan->ctlr;
- struct cpdma_desc_pool *pool = ctlr->pool;
-
- spin_lock_irqsave(&pool->lock, flags);
-
- index = bitmap_find_next_zero_area(pool->bitmap,
- pool->num_desc, pool->num_desc/2, 1, 0);
-
- if (index < pool->num_desc)
- ret = true;
- else
- ret = false;
-
- spin_unlock_irqrestore(&pool->lock, flags);
- return ret;
-}
-EXPORT_SYMBOL_GPL(cpdma_check_free_tx_desc);
-
static void __cpdma_chan_free(struct cpdma_chan *chan,
struct cpdma_desc __iomem *desc,
int outlen, int status)
@@ -776,7 +728,6 @@ static int __cpdma_chan_process(struct cpdma_chan *chan)
struct cpdma_ctlr *ctlr = chan->ctlr;
struct cpdma_desc __iomem *desc;
int status, outlen;
- int cb_status = 0;
struct cpdma_desc_pool *pool = ctlr->pool;
dma_addr_t desc_dma;
unsigned long flags;
@@ -798,8 +749,7 @@ static int __cpdma_chan_process(struct cpdma_chan *chan)
status = -EBUSY;
goto unlock_ret;
}
- status = status & (CPDMA_DESC_EOQ | CPDMA_DESC_TD_COMPLETE |
- CPDMA_DESC_PORT_MASK);
+ status = status & (CPDMA_DESC_EOQ | CPDMA_DESC_TD_COMPLETE);
chan->head = desc_from_phys(pool, desc_read(desc, hw_next));
chan_write(chan, cp, desc_dma);
@@ -812,12 +762,8 @@ static int __cpdma_chan_process(struct cpdma_chan *chan)
}
spin_unlock_irqrestore(&chan->lock, flags);
- if (unlikely(status & CPDMA_DESC_TD_COMPLETE))
- cb_status = -ENOSYS;
- else
- cb_status = status;
- __cpdma_chan_free(chan, desc, outlen, cb_status);
+ __cpdma_chan_free(chan, desc, outlen, status);
return status;
unlock_ret:
@@ -876,7 +822,7 @@ int cpdma_chan_stop(struct cpdma_chan *chan)
struct cpdma_desc_pool *pool = ctlr->pool;
unsigned long flags;
int ret;
- unsigned timeout;
+ unsigned long timeout;
spin_lock_irqsave(&chan->lock, flags);
if (chan->state != CPDMA_STATE_ACTIVE) {
@@ -891,15 +837,14 @@ int cpdma_chan_stop(struct cpdma_chan *chan)
dma_reg_write(ctlr, chan->td, chan_linear(chan));
/* wait for teardown complete */
- timeout = 100 * 100; /* 100 ms */
- while (timeout) {
+ timeout = jiffies + HZ/10; /* 100 msec */
+ while (time_before(jiffies, timeout)) {
u32 cp = chan_read(chan, cp);
if ((cp & CPDMA_TEARDOWN_VALUE) == CPDMA_TEARDOWN_VALUE)
break;
- udelay(10);
- timeout--;
+ cpu_relax();
}
- WARN_ON(!timeout);
+ WARN_ON(!time_before(jiffies, timeout));
chan_write(chan, cp, CPDMA_TEARDOWN_VALUE);
/* handle completed packets */
@@ -1039,6 +984,3 @@ unlock_ret:
spin_unlock_irqrestore(&ctlr->lock, flags);
return ret;
}
-EXPORT_SYMBOL_GPL(cpdma_control_set);
-
-MODULE_LICENSE("GPL");
diff --git a/drivers/net/ethernet/ti/davinci_cpdma.h b/drivers/net/ethernet/ti/davinci_cpdma.h
index 86dee48..afa19a0 100644
--- a/drivers/net/ethernet/ti/davinci_cpdma.h
+++ b/drivers/net/ethernet/ti/davinci_cpdma.h
@@ -24,13 +24,6 @@
#define __chan_linear(chan_num) ((chan_num) & (CPDMA_MAX_CHANNELS - 1))
#define chan_linear(chan) __chan_linear((chan)->chan_num)
-#define CPDMA_RX_SOURCE_PORT(__status__) ((__status__ >> 16) & 0x7)
-
-#define CPDMA_EOI_RX_THRESH 0x0
-#define CPDMA_EOI_RX 0x1
-#define CPDMA_EOI_TX 0x2
-#define CPDMA_EOI_MISC 0x3
-
struct cpdma_params {
struct device *dev;
void __iomem *dmaregs;
@@ -89,13 +82,12 @@ int cpdma_chan_dump(struct cpdma_chan *chan);
int cpdma_chan_get_stats(struct cpdma_chan *chan,
struct cpdma_chan_stats *stats);
int cpdma_chan_submit(struct cpdma_chan *chan, void *token, void *data,
- int len, int directed);
+ int len, gfp_t gfp_mask);
int cpdma_chan_process(struct cpdma_chan *chan, int quota);
int cpdma_ctlr_int_ctrl(struct cpdma_ctlr *ctlr, bool enable);
-void cpdma_ctlr_eoi(struct cpdma_ctlr *ctlr, u32 value);
+void cpdma_ctlr_eoi(struct cpdma_ctlr *ctlr);
int cpdma_chan_int_ctrl(struct cpdma_chan *chan, bool enable);
-bool cpdma_check_free_tx_desc(struct cpdma_chan *chan);
enum cpdma_control {
CPDMA_CMD_IDLE, /* write-only */
diff --git a/drivers/net/ethernet/ti/davinci_emac.c b/drivers/net/ethernet/ti/davinci_emac.c
index 5aa9e4d..2a3e2c5 100644
--- a/drivers/net/ethernet/ti/davinci_emac.c
+++ b/drivers/net/ethernet/ti/davinci_emac.c
@@ -120,6 +120,7 @@ static const char emac_version_string[] = "TI DaVinci EMAC Linux v6.1";
#define EMAC_DEF_TX_CH (0) /* Default 0th channel */
#define EMAC_DEF_RX_CH (0) /* Default 0th channel */
#define EMAC_DEF_RX_NUM_DESC (128)
+#define EMAC_DEF_TX_NUM_DESC (128)
#define EMAC_DEF_MAX_TX_CH (1) /* Max TX channels configured */
#define EMAC_DEF_MAX_RX_CH (1) /* Max RX channels configured */
#define EMAC_POLL_WEIGHT (64) /* Default NAPI poll weight */
@@ -341,6 +342,7 @@ struct emac_priv {
u32 mac_hash2;
u32 multicast_hash_cnt[EMAC_NUM_MULTICAST_BITS];
u32 rx_addr_type;
+ atomic_t cur_tx;
const char *phy_id;
#ifdef CONFIG_OF
struct device_node *phy_node;
@@ -478,8 +480,8 @@ static void emac_dump_regs(struct emac_priv *priv)
static void emac_get_drvinfo(struct net_device *ndev,
struct ethtool_drvinfo *info)
{
- strlcpy(info->driver, emac_version_string, sizeof(info->driver));
- strlcpy(info->version, EMAC_MODULE_VERSION, sizeof(info->version));
+ strcpy(info->driver, emac_version_string);
+ strcpy(info->version, EMAC_MODULE_VERSION);
}
/**
@@ -1037,7 +1039,7 @@ static void emac_rx_handler(void *token, int len, int status)
recycle:
ret = cpdma_chan_submit(priv->rxchan, skb, skb->data,
- skb_tailroom(skb), 0);
+ skb_tailroom(skb), GFP_KERNEL);
WARN_ON(ret == -ENOMEM);
if (unlikely(ret < 0))
@@ -1048,12 +1050,12 @@ static void emac_tx_handler(void *token, int len, int status)
{
struct sk_buff *skb = token;
struct net_device *ndev = skb->dev;
+ struct emac_priv *priv = netdev_priv(ndev);
+
+ atomic_dec(&priv->cur_tx);
- /* Check whether the queue is stopped due to stalled tx dma, if the
- * queue is stopped then start the queue as we have free desc for tx
- */
if (unlikely(netif_queue_stopped(ndev)))
- netif_wake_queue(ndev);
+ netif_start_queue(ndev);
ndev->stats.tx_packets++;
ndev->stats.tx_bytes += len;
dev_kfree_skb_any(skb);
@@ -1092,17 +1094,14 @@ static int emac_dev_xmit(struct sk_buff *skb, struct net_device *ndev)
skb_tx_timestamp(skb);
ret_code = cpdma_chan_submit(priv->txchan, skb, skb->data, skb->len,
- 0);
+ GFP_KERNEL);
if (unlikely(ret_code != 0)) {
if (netif_msg_tx_err(priv) && net_ratelimit())
dev_err(emac_dev, "DaVinci EMAC: desc submit failed");
goto fail_tx;
}
- /* If there is no more tx desc left free then we need to
- * tell the kernel to stop sending us tx frames.
- */
- if (unlikely(!cpdma_check_free_tx_desc(priv->txchan)))
+ if (atomic_inc_return(&priv->cur_tx) >= EMAC_DEF_TX_NUM_DESC)
netif_stop_queue(ndev);
return NETDEV_TX_OK;
@@ -1265,6 +1264,7 @@ static int emac_dev_setmac_addr(struct net_device *ndev, void *addr)
/* Store mac addr in priv and rx channel and set it in EMAC hw */
memcpy(priv->mac_addr, sa->sa_data, ndev->addr_len);
memcpy(ndev->dev_addr, sa->sa_data, ndev->addr_len);
+ ndev->addr_assign_type &= ~NET_ADDR_RANDOM;
/* MAC address is configured only after the interface is enabled. */
if (netif_running(ndev)) {
@@ -1438,7 +1438,7 @@ static int emac_poll(struct napi_struct *napi, int budget)
* Polled functionality used by netconsole and others in non interrupt mode
*
*/
-static void emac_poll_controller(struct net_device *ndev)
+void emac_poll_controller(struct net_device *ndev)
{
struct emac_priv *priv = netdev_priv(ndev);
@@ -1558,7 +1558,7 @@ static int emac_dev_open(struct net_device *ndev)
break;
ret = cpdma_chan_submit(priv->rxchan, skb, skb->data,
- skb_tailroom(skb), 0);
+ skb_tailroom(skb), GFP_KERNEL);
if (WARN_ON(ret < 0))
break;
}
@@ -1865,18 +1865,21 @@ static int davinci_emac_probe(struct platform_device *pdev)
/* obtain emac clock from kernel */
- emac_clk = devm_clk_get(&pdev->dev, NULL);
+ emac_clk = clk_get(&pdev->dev, NULL);
if (IS_ERR(emac_clk)) {
dev_err(&pdev->dev, "failed to get EMAC clock\n");
return -EBUSY;
}
emac_bus_frequency = clk_get_rate(emac_clk);
+ clk_put(emac_clk);
/* TODO: Probe PHY here if possible */
ndev = alloc_etherdev(sizeof(struct emac_priv));
- if (!ndev)
- return -ENOMEM;
+ if (!ndev) {
+ rc = -ENOMEM;
+ goto no_ndev;
+ }
platform_set_drvdata(pdev, ndev);
priv = netdev_priv(ndev);
@@ -1890,7 +1893,7 @@ static int davinci_emac_probe(struct platform_device *pdev)
if (!pdata) {
dev_err(&pdev->dev, "no platform data\n");
rc = -ENODEV;
- goto no_pdata;
+ goto probe_quit;
}
/* MAC addr and PHY mask , RMII enable info from platform_data */
@@ -1910,23 +1913,23 @@ static int davinci_emac_probe(struct platform_device *pdev)
if (!res) {
dev_err(&pdev->dev,"error getting res\n");
rc = -ENOENT;
- goto no_pdata;
+ goto probe_quit;
}
priv->emac_base_phys = res->start + pdata->ctrl_reg_offset;
size = resource_size(res);
- if (!devm_request_mem_region(&pdev->dev, res->start,
- size, ndev->name)) {
+ if (!request_mem_region(res->start, size, ndev->name)) {
dev_err(&pdev->dev, "failed request_mem_region() for regs\n");
rc = -ENXIO;
- goto no_pdata;
+ goto probe_quit;
}
- priv->remap_addr = devm_ioremap(&pdev->dev, res->start, size);
+ priv->remap_addr = ioremap(res->start, size);
if (!priv->remap_addr) {
dev_err(&pdev->dev, "unable to map IO\n");
rc = -ENOMEM;
- goto no_pdata;
+ release_mem_region(res->start, size);
+ goto probe_quit;
}
priv->emac_base = priv->remap_addr + pdata->ctrl_reg_offset;
ndev->base_addr = (unsigned long)priv->remap_addr;
@@ -1959,7 +1962,7 @@ static int davinci_emac_probe(struct platform_device *pdev)
if (!priv->dma) {
dev_err(&pdev->dev, "error initializing DMA\n");
rc = -ENOMEM;
- goto no_pdata;
+ goto no_dma;
}
priv->txchan = cpdma_chan_create(priv->dma, tx_chan_num(EMAC_DEF_TX_CH),
@@ -1968,14 +1971,14 @@ static int davinci_emac_probe(struct platform_device *pdev)
emac_rx_handler);
if (WARN_ON(!priv->txchan || !priv->rxchan)) {
rc = -ENOMEM;
- goto no_cpdma_chan;
+ goto no_irq_res;
}
res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
if (!res) {
dev_err(&pdev->dev, "error getting irq res\n");
rc = -ENOENT;
- goto no_cpdma_chan;
+ goto no_irq_res;
}
ndev->irq = res->start;
@@ -1997,7 +2000,7 @@ static int davinci_emac_probe(struct platform_device *pdev)
if (rc) {
dev_err(&pdev->dev, "error in register_netdev\n");
rc = -ENODEV;
- goto no_cpdma_chan;
+ goto no_irq_res;
}
@@ -2012,14 +2015,20 @@ static int davinci_emac_probe(struct platform_device *pdev)
return 0;
-no_cpdma_chan:
+no_irq_res:
if (priv->txchan)
cpdma_chan_destroy(priv->txchan);
if (priv->rxchan)
cpdma_chan_destroy(priv->rxchan);
cpdma_ctlr_destroy(priv->dma);
-no_pdata:
+no_dma:
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ release_mem_region(res->start, resource_size(res));
+ iounmap(priv->remap_addr);
+
+probe_quit:
free_netdev(ndev);
+no_ndev:
return rc;
}
@@ -2032,12 +2041,14 @@ no_pdata:
*/
static int davinci_emac_remove(struct platform_device *pdev)
{
+ struct resource *res;
struct net_device *ndev = platform_get_drvdata(pdev);
struct emac_priv *priv = netdev_priv(ndev);
dev_notice(&ndev->dev, "DaVinci EMAC: davinci_emac_remove()\n");
platform_set_drvdata(pdev, NULL);
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (priv->txchan)
cpdma_chan_destroy(priv->txchan);
@@ -2045,7 +2056,10 @@ static int davinci_emac_remove(struct platform_device *pdev)
cpdma_chan_destroy(priv->rxchan);
cpdma_ctlr_destroy(priv->dma);
+ release_mem_region(res->start, resource_size(res));
+
unregister_netdev(ndev);
+ iounmap(priv->remap_addr);
free_netdev(ndev);
return 0;
diff --git a/drivers/net/ethernet/ti/davinci_mdio.c b/drivers/net/ethernet/ti/davinci_mdio.c
index 12aec17..cca2550 100644
--- a/drivers/net/ethernet/ti/davinci_mdio.c
+++ b/drivers/net/ethernet/ti/davinci_mdio.c
@@ -320,8 +320,10 @@ static int davinci_mdio_probe(struct platform_device *pdev)
int ret, addr;
data = kzalloc(sizeof(*data), GFP_KERNEL);
- if (!data)
+ if (!data) {
+ dev_err(dev, "failed to alloc device data\n");
return -ENOMEM;
+ }
data->bus = mdiobus_alloc();
if (!data->bus) {
@@ -485,7 +487,6 @@ static const struct of_device_id davinci_mdio_of_mtable[] = {
{ .compatible = "ti,davinci_mdio", },
{ /* sentinel */ },
};
-MODULE_DEVICE_TABLE(of, davinci_mdio_of_mtable);
static struct platform_driver davinci_mdio_driver = {
.driver = {
diff --git a/drivers/net/ethernet/ti/tlan.c b/drivers/net/ethernet/ti/tlan.c
index 60c400f..2272538 100644
--- a/drivers/net/ethernet/ti/tlan.c
+++ b/drivers/net/ethernet/ti/tlan.c
@@ -320,7 +320,6 @@ static void tlan_remove_one(struct pci_dev *pdev)
free_netdev(dev);
pci_set_drvdata(pdev, NULL);
- cancel_work_sync(&priv->tlan_tqueue);
}
static void tlan_start(struct net_device *dev)
@@ -1912,8 +1911,10 @@ static void tlan_reset_lists(struct net_device *dev)
list->frame_size = TLAN_MAX_FRAME_SIZE;
list->buffer[0].count = TLAN_MAX_FRAME_SIZE | TLAN_LAST_BUFFER;
skb = netdev_alloc_skb_ip_align(dev, TLAN_MAX_FRAME_SIZE + 5);
- if (!skb)
+ if (!skb) {
+ netdev_err(dev, "Out of memory for received data\n");
break;
+ }
list->buffer[0].address = pci_map_single(priv->pci_dev,
skb->data,
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index e5cb723..d3fb97d 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -628,7 +628,6 @@ void macvlan_common_setup(struct net_device *dev)
ether_setup(dev);
dev->priv_flags &= ~(IFF_XMIT_DST_RELEASE | IFF_TX_SKB_SHARING);
- dev->priv_flags |= IFF_UNICAST_FLT;
dev->netdev_ops = &macvlan_netdev_ops;
dev->destructor = free_netdev;
dev->header_ops = &macvlan_hard_header_ops,
diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c
index 21a942c..6989ebe 100644
--- a/drivers/net/netconsole.c
+++ b/drivers/net/netconsole.c
@@ -630,7 +630,6 @@ static int netconsole_netdev_event(struct notifier_block *this,
goto done;
spin_lock_irqsave(&target_list_lock, flags);
-restart:
list_for_each_entry(nt, &target_list, list) {
netconsole_target_get(nt);
if (nt->np.dev == dev) {
@@ -643,17 +642,15 @@ restart:
case NETDEV_UNREGISTER:
/*
* rtnl_lock already held
- * we might sleep in __netpoll_cleanup()
*/
- spin_unlock_irqrestore(&target_list_lock, flags);
- __netpoll_cleanup(&nt->np);
- spin_lock_irqsave(&target_list_lock, flags);
- dev_put(nt->np.dev);
- nt->np.dev = NULL;
+ if (nt->np.dev) {
+ __netpoll_cleanup(&nt->np);
+ dev_put(nt->np.dev);
+ nt->np.dev = NULL;
+ }
nt->enabled = 0;
stopped = true;
- netconsole_target_put(nt);
- goto restart;
+ break;
}
}
netconsole_target_put(nt);
diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c
index 508570e..0b2706a 100644
--- a/drivers/net/ppp/ppp_generic.c
+++ b/drivers/net/ppp/ppp_generic.c
@@ -1058,15 +1058,7 @@ ppp_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats64)
return stats64;
}
-static struct lock_class_key ppp_tx_busylock;
-static int ppp_dev_init(struct net_device *dev)
-{
- dev->qdisc_tx_busylock = &ppp_tx_busylock;
- return 0;
-}
-
static const struct net_device_ops ppp_netdev_ops = {
- .ndo_init = ppp_dev_init,
.ndo_start_xmit = ppp_start_xmit,
.ndo_do_ioctl = ppp_net_ioctl,
.ndo_get_stats64 = ppp_get_stats64,
diff --git a/drivers/net/rionet.c b/drivers/net/rionet.c
index 7ae06a7..d8b9b1e 100644
--- a/drivers/net/rionet.c
+++ b/drivers/net/rionet.c
@@ -174,7 +174,11 @@ static int rionet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
unsigned long flags;
int add_num = 1;
- spin_lock_irqsave(&rnet->tx_lock, flags);
+ local_irq_save(flags);
+ if (!spin_trylock(&rnet->tx_lock)) {
+ local_irq_restore(flags);
+ return NETDEV_TX_LOCKED;
+ }
if (is_multicast_ether_addr(eth->h_dest))
add_num = nets[rnet->mport->id].nact;
diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c
index 8efe47a..ad86660 100644
--- a/drivers/net/team/team.c
+++ b/drivers/net/team/team.c
@@ -1139,8 +1139,6 @@ static int team_port_del(struct team *team, struct net_device *port_dev)
netdev_set_master(port_dev, NULL);
team_port_disable_netpoll(port);
vlan_vids_del_by_dev(port_dev, dev);
- dev_uc_unsync(port_dev, dev);
- dev_mc_unsync(port_dev, dev);
dev_close(port_dev);
team_port_leave(team, port);
team_port_set_orig_dev_addr(port);
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index cb95fe5..2917a86 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -748,8 +748,6 @@ static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev)
goto drop;
skb_orphan(skb);
- nf_reset(skb);
-
/* Enqueue packet */
skb_queue_tail(&tfile->socket.sk->sk_receive_queue, skb);
diff --git a/drivers/net/usb/cdc_mbim.c b/drivers/net/usb/cdc_mbim.c
index 6bd9167..248d2dc 100644
--- a/drivers/net/usb/cdc_mbim.c
+++ b/drivers/net/usb/cdc_mbim.c
@@ -68,9 +68,18 @@ static int cdc_mbim_bind(struct usbnet *dev, struct usb_interface *intf)
struct cdc_ncm_ctx *ctx;
struct usb_driver *subdriver = ERR_PTR(-ENODEV);
int ret = -ENODEV;
- u8 data_altsetting = cdc_ncm_select_altsetting(dev, intf);
+ u8 data_altsetting = CDC_NCM_DATA_ALTSETTING_NCM;
struct cdc_mbim_state *info = (void *)&dev->data;
+ /* see if interface supports MBIM alternate setting */
+ if (intf->num_altsetting == 2) {
+ if (!cdc_ncm_comm_intf_is_mbim(intf->cur_altsetting))
+ usb_set_interface(dev->udev,
+ intf->cur_altsetting->desc.bInterfaceNumber,
+ CDC_NCM_COMM_ALTSETTING_MBIM);
+ data_altsetting = CDC_NCM_DATA_ALTSETTING_MBIM;
+ }
+
/* Probably NCM, defer for cdc_ncm_bind */
if (!cdc_ncm_comm_intf_is_mbim(intf->cur_altsetting))
goto err;
@@ -134,7 +143,7 @@ static struct sk_buff *cdc_mbim_tx_fixup(struct usbnet *dev, struct sk_buff *skb
goto error;
if (skb) {
- if (skb->len <= ETH_HLEN)
+ if (skb->len <= sizeof(ETH_HLEN))
goto error;
/* mapping VLANs to MBIM sessions:
diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c
index 70fb846..00d3b2d 100644
--- a/drivers/net/usb/cdc_ncm.c
+++ b/drivers/net/usb/cdc_ncm.c
@@ -55,14 +55,6 @@
#define DRIVER_VERSION "14-Mar-2012"
-#if IS_ENABLED(CONFIG_USB_NET_CDC_MBIM)
-static bool prefer_mbim = true;
-#else
-static bool prefer_mbim;
-#endif
-module_param(prefer_mbim, bool, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(prefer_mbim, "Prefer MBIM setting on dual NCM/MBIM functions");
-
static void cdc_ncm_txpath_bh(unsigned long param);
static void cdc_ncm_tx_timeout_start(struct cdc_ncm_ctx *ctx);
static enum hrtimer_restart cdc_ncm_tx_timer_cb(struct hrtimer *hr_timer);
@@ -558,12 +550,9 @@ void cdc_ncm_unbind(struct usbnet *dev, struct usb_interface *intf)
}
EXPORT_SYMBOL_GPL(cdc_ncm_unbind);
-/* Select the MBIM altsetting iff it is preferred and available,
- * returning the number of the corresponding data interface altsetting
- */
-u8 cdc_ncm_select_altsetting(struct usbnet *dev, struct usb_interface *intf)
+static int cdc_ncm_bind(struct usbnet *dev, struct usb_interface *intf)
{
- struct usb_host_interface *alt;
+ int ret;
/* The MBIM spec defines a NCM compatible default altsetting,
* which we may have matched:
@@ -579,27 +568,18 @@ u8 cdc_ncm_select_altsetting(struct usbnet *dev, struct usb_interface *intf)
* endpoint descriptors, shall be constructed according to
* the rules given in section 6 (USB Device Model) of this
* specification."
+ *
+ * Do not bind to such interfaces, allowing cdc_mbim to handle
+ * them
*/
- if (prefer_mbim && intf->num_altsetting == 2) {
- alt = usb_altnum_to_altsetting(intf, CDC_NCM_COMM_ALTSETTING_MBIM);
- if (alt && cdc_ncm_comm_intf_is_mbim(alt) &&
- !usb_set_interface(dev->udev,
- intf->cur_altsetting->desc.bInterfaceNumber,
- CDC_NCM_COMM_ALTSETTING_MBIM))
- return CDC_NCM_DATA_ALTSETTING_MBIM;
- }
- return CDC_NCM_DATA_ALTSETTING_NCM;
-}
-EXPORT_SYMBOL_GPL(cdc_ncm_select_altsetting);
-
-static int cdc_ncm_bind(struct usbnet *dev, struct usb_interface *intf)
-{
- int ret;
-
- /* MBIM backwards compatible function? */
- cdc_ncm_select_altsetting(dev, intf);
- if (cdc_ncm_comm_intf_is_mbim(intf->cur_altsetting))
+#if IS_ENABLED(CONFIG_USB_NET_CDC_MBIM)
+ if ((intf->num_altsetting == 2) &&
+ !usb_set_interface(dev->udev,
+ intf->cur_altsetting->desc.bInterfaceNumber,
+ CDC_NCM_COMM_ALTSETTING_MBIM) &&
+ cdc_ncm_comm_intf_is_mbim(intf->cur_altsetting))
return -ENODEV;
+#endif
/* NCM data altsetting is always 1 */
ret = cdc_ncm_bind_common(dev, intf, 1);
diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
index b69ca0f..19d9035 100644
--- a/drivers/net/usb/qmi_wwan.c
+++ b/drivers/net/usb/qmi_wwan.c
@@ -139,9 +139,16 @@ static int qmi_wwan_bind(struct usbnet *dev, struct usb_interface *intf)
BUILD_BUG_ON((sizeof(((struct usbnet *)0)->data) < sizeof(struct qmi_wwan_state)));
- /* set up initial state */
- info->control = intf;
- info->data = intf;
+ /* control and data is shared? */
+ if (intf->cur_altsetting->desc.bNumEndpoints == 3) {
+ info->control = intf;
+ info->data = intf;
+ goto shared;
+ }
+
+ /* else require a single interrupt status endpoint on control intf */
+ if (intf->cur_altsetting->desc.bNumEndpoints != 1)
+ goto err;
/* and a number of CDC descriptors */
while (len > 3) {
@@ -200,14 +207,25 @@ next_desc:
buf += h->bLength;
}
- /* Use separate control and data interfaces if we found a CDC Union */
- if (cdc_union) {
- info->data = usb_ifnum_to_if(dev->udev, cdc_union->bSlaveInterface0);
- if (desc->bInterfaceNumber != cdc_union->bMasterInterface0 || !info->data) {
- dev_err(&intf->dev, "bogus CDC Union: master=%u, slave=%u\n",
- cdc_union->bMasterInterface0, cdc_union->bSlaveInterface0);
- goto err;
- }
+ /* did we find all the required ones? */
+ if (!(found & (1 << USB_CDC_HEADER_TYPE)) ||
+ !(found & (1 << USB_CDC_UNION_TYPE))) {
+ dev_err(&intf->dev, "CDC functional descriptors missing\n");
+ goto err;
+ }
+
+ /* verify CDC Union */
+ if (desc->bInterfaceNumber != cdc_union->bMasterInterface0) {
+ dev_err(&intf->dev, "bogus CDC Union: master=%u\n", cdc_union->bMasterInterface0);
+ goto err;
+ }
+
+ /* need to save these for unbind */
+ info->control = intf;
+ info->data = usb_ifnum_to_if(dev->udev, cdc_union->bSlaveInterface0);
+ if (!info->data) {
+ dev_err(&intf->dev, "bogus CDC Union: slave=%u\n", cdc_union->bSlaveInterface0);
+ goto err;
}
/* errors aren't fatal - we can live with the dynamic address */
@@ -217,12 +235,11 @@ next_desc:
}
/* claim data interface and set it up */
- if (info->control != info->data) {
- status = usb_driver_claim_interface(driver, info->data, dev);
- if (status < 0)
- goto err;
- }
+ status = usb_driver_claim_interface(driver, info->data, dev);
+ if (status < 0)
+ goto err;
+shared:
status = qmi_wwan_register_subdriver(dev);
if (status < 0 && info->control != info->data) {
usb_set_intfdata(info->data, NULL);
diff --git a/drivers/net/usb/smsc75xx.c b/drivers/net/usb/smsc75xx.c
index 937c09d..251a335 100644
--- a/drivers/net/usb/smsc75xx.c
+++ b/drivers/net/usb/smsc75xx.c
@@ -914,12 +914,8 @@ static int smsc75xx_set_rx_max_frame_length(struct usbnet *dev, int size)
static int smsc75xx_change_mtu(struct net_device *netdev, int new_mtu)
{
struct usbnet *dev = netdev_priv(netdev);
- int ret;
-
- if (new_mtu > MAX_SINGLE_PACKET_SIZE)
- return -EINVAL;
- ret = smsc75xx_set_rx_max_frame_length(dev, new_mtu + ETH_HLEN);
+ int ret = smsc75xx_set_rx_max_frame_length(dev, new_mtu);
if (ret < 0) {
netdev_warn(dev->net, "Failed to set mac rx frame length\n");
return ret;
@@ -1328,7 +1324,7 @@ static int smsc75xx_reset(struct usbnet *dev)
netif_dbg(dev, ifup, dev->net, "FCT_TX_CTL set to 0x%08x\n", buf);
- ret = smsc75xx_set_rx_max_frame_length(dev, dev->net->mtu + ETH_HLEN);
+ ret = smsc75xx_set_rx_max_frame_length(dev, 1514);
if (ret < 0) {
netdev_warn(dev->net, "Failed to set max rx frame length\n");
return ret;
@@ -2140,8 +2136,8 @@ static int smsc75xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
else if (rx_cmd_a & (RX_CMD_A_LONG | RX_CMD_A_RUNT))
dev->net->stats.rx_frame_errors++;
} else {
- /* MAX_SINGLE_PACKET_SIZE + 4(CRC) + 2(COE) + 4(Vlan) */
- if (unlikely(size > (MAX_SINGLE_PACKET_SIZE + ETH_HLEN + 12))) {
+ /* ETH_FRAME_LEN + 4(CRC) + 2(COE) + 4(Vlan) */
+ if (unlikely(size > (ETH_FRAME_LEN + 12))) {
netif_dbg(dev, rx_err, dev->net,
"size err rx_cmd_a=0x%08x\n",
rx_cmd_a);
diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c
index 6214181..9b73670 100644
--- a/drivers/net/usb/smsc95xx.c
+++ b/drivers/net/usb/smsc95xx.c
@@ -1340,8 +1340,6 @@ static int smsc95xx_enter_suspend0(struct usbnet *dev)
ret = smsc95xx_read_reg_nopm(dev, PM_CTRL, &val);
if (ret < 0)
netdev_warn(dev->net, "Error reading PM_CTRL\n");
- else
- ret = 0;
return ret;
}
@@ -1394,8 +1392,6 @@ static int smsc95xx_enter_suspend1(struct usbnet *dev)
ret = smsc95xx_write_reg_nopm(dev, PM_CTRL, val);
if (ret < 0)
netdev_warn(dev->net, "Error writing PM_CTRL\n");
- else
- ret = 0;
return ret;
}
@@ -1417,8 +1413,6 @@ static int smsc95xx_enter_suspend2(struct usbnet *dev)
ret = smsc95xx_write_reg_nopm(dev, PM_CTRL, val);
if (ret < 0)
netdev_warn(dev->net, "Error writing PM_CTRL\n");
- else
- ret = 0;
return ret;
}
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index 6993bfa..656230e 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -1491,15 +1491,6 @@ static __net_init int vxlan_init_net(struct net *net)
static __net_exit void vxlan_exit_net(struct net *net)
{
struct vxlan_net *vn = net_generic(net, vxlan_net_id);
- struct vxlan_dev *vxlan;
- struct hlist_node *pos;
- unsigned h;
-
- rtnl_lock();
- for (h = 0; h < VNI_HASH_SIZE; ++h)
- hlist_for_each_entry(vxlan, pos, &vn->vni_list[h], hlist)
- dev_close(vxlan->dev);
- rtnl_unlock();
if (vn->sock) {
sk_release_kernel(vn->sock->sk);
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
index e99f481..56317b0 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
@@ -976,7 +976,6 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah,
AR_PHY_CL_TAB_1,
AR_PHY_CL_TAB_2 };
- /* Use chip chainmask only for calibration */
ar9003_hw_set_chain_masks(ah, ah->caps.rx_chainmask, ah->caps.tx_chainmask);
if (rtt) {
@@ -1132,9 +1131,6 @@ skip_tx_iqcal:
ar9003_hw_rtt_disable(ah);
}
- /* Revert chainmask to runtime parameters */
- ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask);
-
/* Initialize list pointers */
ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL;
ah->supp_cals = IQ_MISMATCH_CAL;
diff --git a/drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h b/drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h
index c00c13a..6e1915a 100644
--- a/drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h
+++ b/drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h
@@ -519,7 +519,7 @@ static const u32 ar9580_1p0_mac_core[][2] = {
{0x00008258, 0x00000000},
{0x0000825c, 0x40000000},
{0x00008260, 0x00080922},
- {0x00008264, 0x9d400010},
+ {0x00008264, 0x9bc00010},
{0x00008268, 0xffffffff},
{0x0000826c, 0x0000ffff},
{0x00008270, 0x00000000},
diff --git a/drivers/net/wireless/ath/ath9k/common.h b/drivers/net/wireless/ath/ath9k/common.h
index 050ca4a..5f845be 100644
--- a/drivers/net/wireless/ath/ath9k/common.h
+++ b/drivers/net/wireless/ath/ath9k/common.h
@@ -27,7 +27,7 @@
#define WME_MAX_BA WME_BA_BMP_SIZE
#define ATH_TID_MAX_BUFS (2 * WME_MAX_BA)
-#define ATH_RSSI_DUMMY_MARKER 127
+#define ATH_RSSI_DUMMY_MARKER 0x127
#define ATH_RSSI_LPF_LEN 10
#define RSSI_LPF_THRESHOLD -20
#define ATH_RSSI_EP_MULTIPLIER (1<<7)
diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h
index d3b099d..96bfb18 100644
--- a/drivers/net/wireless/ath/ath9k/htc.h
+++ b/drivers/net/wireless/ath/ath9k/htc.h
@@ -22,7 +22,6 @@
#include <linux/firmware.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
#include <linux/leds.h>
#include <linux/slab.h>
#include <net/mac80211.h>
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
index 0663653..05d5ba6 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
@@ -796,7 +796,7 @@ static int ath9k_init_firmware_version(struct ath9k_htc_priv *priv)
* required version.
*/
if (priv->fw_version_major != MAJOR_VERSION_REQ ||
- priv->fw_version_minor < MINOR_VERSION_REQ) {
+ priv->fw_version_minor != MINOR_VERSION_REQ) {
dev_err(priv->dev, "ath9k_htc: Please upgrade to FW version %d.%d\n",
MAJOR_VERSION_REQ, MINOR_VERSION_REQ);
return -EINVAL;
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
index 8788621..b6a5a08 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
@@ -1067,19 +1067,15 @@ static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv,
last_rssi = priv->rx.last_rssi;
- if (ieee80211_is_beacon(hdr->frame_control) &&
- !is_zero_ether_addr(common->curbssid) &&
- ether_addr_equal(hdr->addr3, common->curbssid)) {
- s8 rssi = rxbuf->rxstatus.rs_rssi;
+ if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER))
+ rxbuf->rxstatus.rs_rssi = ATH_EP_RND(last_rssi,
+ ATH_RSSI_EP_MULTIPLIER);
- if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER))
- rssi = ATH_EP_RND(last_rssi, ATH_RSSI_EP_MULTIPLIER);
+ if (rxbuf->rxstatus.rs_rssi < 0)
+ rxbuf->rxstatus.rs_rssi = 0;
- if (rssi < 0)
- rssi = 0;
-
- priv->ah->stats.avgbrssi = rssi;
- }
+ if (ieee80211_is_beacon(fc))
+ priv->ah->stats.avgbrssi = rxbuf->rxstatus.rs_rssi;
rx_status->mactime = be64_to_cpu(rxbuf->rxstatus.rs_tstamp);
rx_status->band = hw->conf.channel->band;
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index e26f92d..7cb7870 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1480,9 +1480,7 @@ static bool ath9k_hw_chip_reset(struct ath_hw *ah,
reset_type = ATH9K_RESET_POWER_ON;
else
reset_type = ATH9K_RESET_COLD;
- } else if (ah->chip_fullsleep || REG_READ(ah, AR_Q_TXE) ||
- (REG_READ(ah, AR_CR) & AR_CR_RXE))
- reset_type = ATH9K_RESET_COLD;
+ }
if (!ath9k_hw_set_reset_reg(ah, reset_type))
return false;
diff --git a/drivers/net/wireless/ath/ath9k/link.c b/drivers/net/wireless/ath/ath9k/link.c
index 7fdac6c..ade3afb 100644
--- a/drivers/net/wireless/ath/ath9k/link.c
+++ b/drivers/net/wireless/ath/ath9k/link.c
@@ -28,21 +28,21 @@ void ath_tx_complete_poll_work(struct work_struct *work)
int i;
bool needreset = false;
- for (i = 0; i < IEEE80211_NUM_ACS; i++) {
- txq = sc->tx.txq_map[i];
-
- ath_txq_lock(sc, txq);
- if (txq->axq_depth) {
- if (txq->axq_tx_inprogress) {
- needreset = true;
- ath_txq_unlock(sc, txq);
- break;
- } else {
- txq->axq_tx_inprogress = true;
+ for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
+ if (ATH_TXQ_SETUP(sc, i)) {
+ txq = &sc->tx.txq[i];
+ ath_txq_lock(sc, txq);
+ if (txq->axq_depth) {
+ if (txq->axq_tx_inprogress) {
+ needreset = true;
+ ath_txq_unlock(sc, txq);
+ break;
+ } else {
+ txq->axq_tx_inprogress = true;
+ }
}
+ ath_txq_unlock_complete(sc, txq);
}
- ath_txq_unlock_complete(sc, txq);
- }
if (needreset) {
ath_dbg(ath9k_hw_common(sc->sc_ah), RESET,
@@ -170,8 +170,7 @@ void ath_rx_poll(unsigned long data)
{
struct ath_softc *sc = (struct ath_softc *)data;
- if (!test_bit(SC_OP_INVALID, &sc->sc_flags))
- ieee80211_queue_work(sc->hw, &sc->hw_check_work);
+ ieee80211_queue_work(sc->hw, &sc->hw_check_work);
}
/*
diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c
index 1221469..38bc5a7 100644
--- a/drivers/net/wireless/b43/dma.c
+++ b/drivers/net/wireless/b43/dma.c
@@ -1487,12 +1487,8 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev,
const struct b43_dma_ops *ops;
struct b43_dmaring *ring;
struct b43_dmadesc_meta *meta;
- static const struct b43_txstatus fake; /* filled with 0 */
- const struct b43_txstatus *txstat;
int slot, firstused;
bool frame_succeed;
- int skip;
- static u8 err_out1, err_out2;
ring = parse_cookie(dev, status->cookie, &slot);
if (unlikely(!ring))
@@ -1505,36 +1501,13 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev,
firstused = ring->current_slot - ring->used_slots + 1;
if (firstused < 0)
firstused = ring->nr_slots + firstused;
-
- skip = 0;
if (unlikely(slot != firstused)) {
/* This possibly is a firmware bug and will result in
- * malfunction, memory leaks and/or stall of DMA functionality.
- */
- if (slot == next_slot(ring, next_slot(ring, firstused))) {
- /* If a single header/data pair was missed, skip over
- * the first two slots in an attempt to recover.
- */
- slot = firstused;
- skip = 2;
- if (!err_out1) {
- /* Report the error once. */
- b43dbg(dev->wl,
- "Skip on DMA ring %d slot %d.\n",
- ring->index, slot);
- err_out1 = 1;
- }
- } else {
- /* More than a single header/data pair were missed.
- * Report this error once.
- */
- if (!err_out2)
- b43dbg(dev->wl,
- "Out of order TX status report on DMA ring %d. Expected %d, but got %d\n",
- ring->index, firstused, slot);
- err_out2 = 1;
- return;
- }
+ * malfunction, memory leaks and/or stall of DMA functionality. */
+ b43dbg(dev->wl, "Out of order TX status report on DMA ring %d. "
+ "Expected %d, but got %d\n",
+ ring->index, firstused, slot);
+ return;
}
ops = ring->ops;
@@ -1549,13 +1522,11 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev,
slot, firstused, ring->index);
break;
}
-
if (meta->skb) {
struct b43_private_tx_info *priv_info =
- b43_get_priv_tx_info(IEEE80211_SKB_CB(meta->skb));
+ b43_get_priv_tx_info(IEEE80211_SKB_CB(meta->skb));
- unmap_descbuffer(ring, meta->dmaaddr,
- meta->skb->len, 1);
+ unmap_descbuffer(ring, meta->dmaaddr, meta->skb->len, 1);
kfree(priv_info->bouncebuffer);
priv_info->bouncebuffer = NULL;
} else {
@@ -1567,9 +1538,8 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev,
struct ieee80211_tx_info *info;
if (unlikely(!meta->skb)) {
- /* This is a scatter-gather fragment of a frame,
- * so the skb pointer must not be NULL.
- */
+ /* This is a scatter-gather fragment of a frame, so
+ * the skb pointer must not be NULL. */
b43dbg(dev->wl, "TX status unexpected NULL skb "
"at slot %d (first=%d) on ring %d\n",
slot, firstused, ring->index);
@@ -1580,18 +1550,9 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev,
/*
* Call back to inform the ieee80211 subsystem about
- * the status of the transmission. When skipping over
- * a missed TX status report, use a status structure
- * filled with zeros to indicate that the frame was not
- * sent (frame_count 0) and not acknowledged
+ * the status of the transmission.
*/
- if (unlikely(skip))
- txstat = &fake;
- else
- txstat = status;
-
- frame_succeed = b43_fill_txstatus_report(dev, info,
- txstat);
+ frame_succeed = b43_fill_txstatus_report(dev, info, status);
#ifdef CONFIG_B43_DEBUG
if (frame_succeed)
ring->nr_succeed_tx_packets++;
@@ -1619,14 +1580,12 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev,
/* Everything unmapped and free'd. So it's not used anymore. */
ring->used_slots--;
- if (meta->is_last_fragment && !skip) {
+ if (meta->is_last_fragment) {
/* This is the last scatter-gather
* fragment of the frame. We are done. */
break;
}
slot = next_slot(ring, slot);
- if (skip > 0)
- --skip;
}
if (ring->stopped) {
B43_WARN_ON(free_slots(ring) < TX_SLOTS_PER_FRAME);
diff --git a/drivers/net/wireless/b43/dma.h b/drivers/net/wireless/b43/dma.h
index 9fdd198..315b96e 100644
--- a/drivers/net/wireless/b43/dma.h
+++ b/drivers/net/wireless/b43/dma.h
@@ -169,7 +169,7 @@ struct b43_dmadesc_generic {
/* DMA engine tuning knobs */
#define B43_TXRING_SLOTS 256
-#define B43_RXRING_SLOTS 256
+#define B43_RXRING_SLOTS 64
#define B43_DMA0_RX_FW598_BUFSIZE (B43_DMA0_RX_FW598_FO + IEEE80211_MAX_FRAME_LEN)
#define B43_DMA0_RX_FW351_BUFSIZE (B43_DMA0_RX_FW351_FO + IEEE80211_MAX_FRAME_LEN)
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 0568273..806e34c 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -4214,6 +4214,7 @@ redo:
mutex_unlock(&wl->mutex);
cancel_delayed_work_sync(&dev->periodic_work);
cancel_work_sync(&wl->tx_work);
+ cancel_work_sync(&wl->firmware_load);
mutex_lock(&wl->mutex);
dev = wl->current_dev;
if (!dev || b43_status(dev) < B43_STAT_STARTED) {
@@ -5433,7 +5434,6 @@ static void b43_bcma_remove(struct bcma_device *core)
/* We must cancel any work here before unregistering from ieee80211,
* as the ieee80211 unreg will destroy the workqueue. */
cancel_work_sync(&wldev->restart_work);
- cancel_work_sync(&wl->firmware_load);
B43_WARN_ON(!wl);
if (!wldev->fw.ucode.data)
@@ -5510,7 +5510,6 @@ static void b43_ssb_remove(struct ssb_device *sdev)
/* We must cancel any work here before unregistering from ieee80211,
* as the ieee80211 unreg will destroy the workqueue. */
cancel_work_sync(&wldev->restart_work);
- cancel_work_sync(&wl->firmware_load);
B43_WARN_ON(!wl);
if (!wldev->fw.ucode.data)
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c
index b70f220..3c35382 100644
--- a/drivers/net/wireless/b43/phy_n.c
+++ b/drivers/net/wireless/b43/phy_n.c
@@ -1564,7 +1564,7 @@ static void b43_nphy_rev3_rssi_cal(struct b43_wldev *dev)
u16 clip_off[2] = { 0xFFFF, 0xFFFF };
u8 vcm_final = 0;
- s32 offset[4];
+ s8 offset[4];
s32 results[8][4] = { };
s32 results_min[4] = { };
s32 poll_results[4] = { };
@@ -1615,7 +1615,7 @@ static void b43_nphy_rev3_rssi_cal(struct b43_wldev *dev)
}
for (i = 0; i < 4; i += 2) {
s32 curr;
- s32 mind = 0x100000;
+ s32 mind = 40;
s32 minpoll = 249;
u8 minvcm = 0;
if (2 * core != i)
@@ -1732,7 +1732,7 @@ static void b43_nphy_rev2_rssi_cal(struct b43_wldev *dev, u8 type)
u8 regs_save_radio[2];
u16 regs_save_phy[2];
- s32 offset[4];
+ s8 offset[4];
u8 core;
u8 rail;
@@ -1799,7 +1799,7 @@ static void b43_nphy_rev2_rssi_cal(struct b43_wldev *dev, u8 type)
}
for (i = 0; i < 4; i++) {
- s32 mind = 0x100000;
+ s32 mind = 40;
u8 minvcm = 0;
s32 minpoll = 249;
s32 curr;
@@ -5165,8 +5165,7 @@ static void b43_nphy_pmu_spur_avoid(struct b43_wldev *dev, bool avoid)
#endif
#ifdef CONFIG_B43_SSB
case B43_BUS_SSB:
- ssb_pmu_spuravoid_pllupdate(&dev->dev->sdev->bus->chipco,
- avoid);
+ /* FIXME */
break;
#endif
}
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c
index 18d3764..21a8242 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c
@@ -1137,8 +1137,9 @@ wlc_lcnphy_set_rx_gain_by_distribution(struct brcms_phy *pi,
gain0_15 = ((biq1 & 0xf) << 12) |
((tia & 0xf) << 8) |
((lna2 & 0x3) << 6) |
- ((lna2 &
- 0x3) << 4) | ((lna1 & 0x3) << 2) | ((lna1 & 0x3) << 0);
+ ((lna2 & 0x3) << 4) |
+ ((lna1 & 0x3) << 2) |
+ ((lna1 & 0x3) << 0);
mod_phy_reg(pi, 0x4b6, (0xffff << 0), gain0_15 << 0);
mod_phy_reg(pi, 0x4b7, (0xf << 0), gain16_19 << 0);
@@ -1156,6 +1157,8 @@ wlc_lcnphy_set_rx_gain_by_distribution(struct brcms_phy *pi,
}
mod_phy_reg(pi, 0x44d, (0x1 << 0), (!trsw) << 0);
+ mod_phy_reg(pi, 0x4b1, (0x3 << 11), lna1 << 11);
+ mod_phy_reg(pi, 0x4e6, (0x3 << 3), lna1 << 3);
}
@@ -1328,6 +1331,43 @@ static u32 wlc_lcnphy_measure_digital_power(struct brcms_phy *pi, u16 nsamples)
return (iq_est.i_pwr + iq_est.q_pwr) / nsamples;
}
+static bool wlc_lcnphy_rx_iq_cal_gain(struct brcms_phy *pi, u16 biq1_gain,
+ u16 tia_gain, u16 lna2_gain)
+{
+ u32 i_thresh_l, q_thresh_l;
+ u32 i_thresh_h, q_thresh_h;
+ struct lcnphy_iq_est iq_est_h, iq_est_l;
+
+ wlc_lcnphy_set_rx_gain_by_distribution(pi, 0, 0, 0, biq1_gain, tia_gain,
+ lna2_gain, 0);
+
+ wlc_lcnphy_rx_gain_override_enable(pi, true);
+ wlc_lcnphy_start_tx_tone(pi, 2000, (40 >> 1), 0);
+ udelay(500);
+ write_radio_reg(pi, RADIO_2064_REG112, 0);
+ if (!wlc_lcnphy_rx_iq_est(pi, 1024, 32, &iq_est_l))
+ return false;
+
+ wlc_lcnphy_start_tx_tone(pi, 2000, 40, 0);
+ udelay(500);
+ write_radio_reg(pi, RADIO_2064_REG112, 0);
+ if (!wlc_lcnphy_rx_iq_est(pi, 1024, 32, &iq_est_h))
+ return false;
+
+ i_thresh_l = (iq_est_l.i_pwr << 1);
+ i_thresh_h = (iq_est_l.i_pwr << 2) + iq_est_l.i_pwr;
+
+ q_thresh_l = (iq_est_l.q_pwr << 1);
+ q_thresh_h = (iq_est_l.q_pwr << 2) + iq_est_l.q_pwr;
+ if ((iq_est_h.i_pwr > i_thresh_l) &&
+ (iq_est_h.i_pwr < i_thresh_h) &&
+ (iq_est_h.q_pwr > q_thresh_l) &&
+ (iq_est_h.q_pwr < q_thresh_h))
+ return true;
+
+ return false;
+}
+
static bool
wlc_lcnphy_rx_iq_cal(struct brcms_phy *pi,
const struct lcnphy_rx_iqcomp *iqcomp,
@@ -1342,8 +1382,8 @@ wlc_lcnphy_rx_iq_cal(struct brcms_phy *pi,
RFOverrideVal0_old, rfoverride2_old, rfoverride2val_old,
rfoverride3_old, rfoverride3val_old, rfoverride4_old,
rfoverride4val_old, afectrlovr_old, afectrlovrval_old;
- int tia_gain;
- u32 received_power, rx_pwr_threshold;
+ int tia_gain, lna2_gain, biq1_gain;
+ bool set_gain;
u16 old_sslpnCalibClkEnCtrl, old_sslpnRxFeClkEnCtrl;
u16 values_to_save[11];
s16 *ptr;
@@ -1368,126 +1408,134 @@ wlc_lcnphy_rx_iq_cal(struct brcms_phy *pi,
goto cal_done;
}
- if (module == 1) {
+ WARN_ON(module != 1);
+ tx_pwr_ctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
+ wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);
- tx_pwr_ctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
- wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);
+ for (i = 0; i < 11; i++)
+ values_to_save[i] =
+ read_radio_reg(pi, rxiq_cal_rf_reg[i]);
+ Core1TxControl_old = read_phy_reg(pi, 0x631);
+
+ or_phy_reg(pi, 0x631, 0x0015);
+
+ RFOverride0_old = read_phy_reg(pi, 0x44c);
+ RFOverrideVal0_old = read_phy_reg(pi, 0x44d);
+ rfoverride2_old = read_phy_reg(pi, 0x4b0);
+ rfoverride2val_old = read_phy_reg(pi, 0x4b1);
+ rfoverride3_old = read_phy_reg(pi, 0x4f9);
+ rfoverride3val_old = read_phy_reg(pi, 0x4fa);
+ rfoverride4_old = read_phy_reg(pi, 0x938);
+ rfoverride4val_old = read_phy_reg(pi, 0x939);
+ afectrlovr_old = read_phy_reg(pi, 0x43b);
+ afectrlovrval_old = read_phy_reg(pi, 0x43c);
+ old_sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da);
+ old_sslpnRxFeClkEnCtrl = read_phy_reg(pi, 0x6db);
- for (i = 0; i < 11; i++)
- values_to_save[i] =
- read_radio_reg(pi, rxiq_cal_rf_reg[i]);
- Core1TxControl_old = read_phy_reg(pi, 0x631);
-
- or_phy_reg(pi, 0x631, 0x0015);
-
- RFOverride0_old = read_phy_reg(pi, 0x44c);
- RFOverrideVal0_old = read_phy_reg(pi, 0x44d);
- rfoverride2_old = read_phy_reg(pi, 0x4b0);
- rfoverride2val_old = read_phy_reg(pi, 0x4b1);
- rfoverride3_old = read_phy_reg(pi, 0x4f9);
- rfoverride3val_old = read_phy_reg(pi, 0x4fa);
- rfoverride4_old = read_phy_reg(pi, 0x938);
- rfoverride4val_old = read_phy_reg(pi, 0x939);
- afectrlovr_old = read_phy_reg(pi, 0x43b);
- afectrlovrval_old = read_phy_reg(pi, 0x43c);
- old_sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da);
- old_sslpnRxFeClkEnCtrl = read_phy_reg(pi, 0x6db);
-
- tx_gain_override_old = wlc_lcnphy_tx_gain_override_enabled(pi);
- if (tx_gain_override_old) {
- wlc_lcnphy_get_tx_gain(pi, &old_gains);
- tx_gain_index_old = pi_lcn->lcnphy_current_index;
- }
+ tx_gain_override_old = wlc_lcnphy_tx_gain_override_enabled(pi);
+ if (tx_gain_override_old) {
+ wlc_lcnphy_get_tx_gain(pi, &old_gains);
+ tx_gain_index_old = pi_lcn->lcnphy_current_index;
+ }
- wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_idx);
+ wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_idx);
- mod_phy_reg(pi, 0x4f9, (0x1 << 0), 1 << 0);
- mod_phy_reg(pi, 0x4fa, (0x1 << 0), 0 << 0);
+ mod_phy_reg(pi, 0x4f9, (0x1 << 0), 1 << 0);
+ mod_phy_reg(pi, 0x4fa, (0x1 << 0), 0 << 0);
- mod_phy_reg(pi, 0x43b, (0x1 << 1), 1 << 1);
- mod_phy_reg(pi, 0x43c, (0x1 << 1), 0 << 1);
+ mod_phy_reg(pi, 0x43b, (0x1 << 1), 1 << 1);
+ mod_phy_reg(pi, 0x43c, (0x1 << 1), 0 << 1);
- write_radio_reg(pi, RADIO_2064_REG116, 0x06);
- write_radio_reg(pi, RADIO_2064_REG12C, 0x07);
- write_radio_reg(pi, RADIO_2064_REG06A, 0xd3);
- write_radio_reg(pi, RADIO_2064_REG098, 0x03);
- write_radio_reg(pi, RADIO_2064_REG00B, 0x7);
- mod_radio_reg(pi, RADIO_2064_REG113, 1 << 4, 1 << 4);
- write_radio_reg(pi, RADIO_2064_REG01D, 0x01);
- write_radio_reg(pi, RADIO_2064_REG114, 0x01);
- write_radio_reg(pi, RADIO_2064_REG02E, 0x10);
- write_radio_reg(pi, RADIO_2064_REG12A, 0x08);
-
- mod_phy_reg(pi, 0x938, (0x1 << 0), 1 << 0);
- mod_phy_reg(pi, 0x939, (0x1 << 0), 0 << 0);
- mod_phy_reg(pi, 0x938, (0x1 << 1), 1 << 1);
- mod_phy_reg(pi, 0x939, (0x1 << 1), 1 << 1);
- mod_phy_reg(pi, 0x938, (0x1 << 2), 1 << 2);
- mod_phy_reg(pi, 0x939, (0x1 << 2), 1 << 2);
- mod_phy_reg(pi, 0x938, (0x1 << 3), 1 << 3);
- mod_phy_reg(pi, 0x939, (0x1 << 3), 1 << 3);
- mod_phy_reg(pi, 0x938, (0x1 << 5), 1 << 5);
- mod_phy_reg(pi, 0x939, (0x1 << 5), 0 << 5);
-
- mod_phy_reg(pi, 0x43b, (0x1 << 0), 1 << 0);
- mod_phy_reg(pi, 0x43c, (0x1 << 0), 0 << 0);
-
- wlc_lcnphy_start_tx_tone(pi, 2000, 120, 0);
- write_phy_reg(pi, 0x6da, 0xffff);
- or_phy_reg(pi, 0x6db, 0x3);
- wlc_lcnphy_set_trsw_override(pi, tx_switch, rx_switch);
- wlc_lcnphy_rx_gain_override_enable(pi, true);
-
- tia_gain = 8;
- rx_pwr_threshold = 950;
- while (tia_gain > 0) {
- tia_gain -= 1;
- wlc_lcnphy_set_rx_gain_by_distribution(pi,
- 0, 0, 2, 2,
- (u16)
- tia_gain, 1, 0);
- udelay(500);
+ write_radio_reg(pi, RADIO_2064_REG116, 0x06);
+ write_radio_reg(pi, RADIO_2064_REG12C, 0x07);
+ write_radio_reg(pi, RADIO_2064_REG06A, 0xd3);
+ write_radio_reg(pi, RADIO_2064_REG098, 0x03);
+ write_radio_reg(pi, RADIO_2064_REG00B, 0x7);
+ mod_radio_reg(pi, RADIO_2064_REG113, 1 << 4, 1 << 4);
+ write_radio_reg(pi, RADIO_2064_REG01D, 0x01);
+ write_radio_reg(pi, RADIO_2064_REG114, 0x01);
+ write_radio_reg(pi, RADIO_2064_REG02E, 0x10);
+ write_radio_reg(pi, RADIO_2064_REG12A, 0x08);
+
+ mod_phy_reg(pi, 0x938, (0x1 << 0), 1 << 0);
+ mod_phy_reg(pi, 0x939, (0x1 << 0), 0 << 0);
+ mod_phy_reg(pi, 0x938, (0x1 << 1), 1 << 1);
+ mod_phy_reg(pi, 0x939, (0x1 << 1), 1 << 1);
+ mod_phy_reg(pi, 0x938, (0x1 << 2), 1 << 2);
+ mod_phy_reg(pi, 0x939, (0x1 << 2), 1 << 2);
+ mod_phy_reg(pi, 0x938, (0x1 << 3), 1 << 3);
+ mod_phy_reg(pi, 0x939, (0x1 << 3), 1 << 3);
+ mod_phy_reg(pi, 0x938, (0x1 << 5), 1 << 5);
+ mod_phy_reg(pi, 0x939, (0x1 << 5), 0 << 5);
- received_power =
- wlc_lcnphy_measure_digital_power(pi, 2000);
- if (received_power < rx_pwr_threshold)
- break;
+ mod_phy_reg(pi, 0x43b, (0x1 << 0), 1 << 0);
+ mod_phy_reg(pi, 0x43c, (0x1 << 0), 0 << 0);
+
+ write_phy_reg(pi, 0x6da, 0xffff);
+ or_phy_reg(pi, 0x6db, 0x3);
+
+ wlc_lcnphy_set_trsw_override(pi, tx_switch, rx_switch);
+ set_gain = false;
+
+ lna2_gain = 3;
+ while ((lna2_gain >= 0) && !set_gain) {
+ tia_gain = 4;
+
+ while ((tia_gain >= 0) && !set_gain) {
+ biq1_gain = 6;
+
+ while ((biq1_gain >= 0) && !set_gain) {
+ set_gain = wlc_lcnphy_rx_iq_cal_gain(pi,
+ (u16)
+ biq1_gain,
+ (u16)
+ tia_gain,
+ (u16)
+ lna2_gain);
+ biq1_gain -= 1;
+ }
+ tia_gain -= 1;
}
- result = wlc_lcnphy_calc_rx_iq_comp(pi, 0xffff);
+ lna2_gain -= 1;
+ }
- wlc_lcnphy_stop_tx_tone(pi);
+ if (set_gain)
+ result = wlc_lcnphy_calc_rx_iq_comp(pi, 1024);
+ else
+ result = false;
- write_phy_reg(pi, 0x631, Core1TxControl_old);
+ wlc_lcnphy_stop_tx_tone(pi);
- write_phy_reg(pi, 0x44c, RFOverrideVal0_old);
- write_phy_reg(pi, 0x44d, RFOverrideVal0_old);
- write_phy_reg(pi, 0x4b0, rfoverride2_old);
- write_phy_reg(pi, 0x4b1, rfoverride2val_old);
- write_phy_reg(pi, 0x4f9, rfoverride3_old);
- write_phy_reg(pi, 0x4fa, rfoverride3val_old);
- write_phy_reg(pi, 0x938, rfoverride4_old);
- write_phy_reg(pi, 0x939, rfoverride4val_old);
- write_phy_reg(pi, 0x43b, afectrlovr_old);
- write_phy_reg(pi, 0x43c, afectrlovrval_old);
- write_phy_reg(pi, 0x6da, old_sslpnCalibClkEnCtrl);
- write_phy_reg(pi, 0x6db, old_sslpnRxFeClkEnCtrl);
+ write_phy_reg(pi, 0x631, Core1TxControl_old);
+
+ write_phy_reg(pi, 0x44c, RFOverrideVal0_old);
+ write_phy_reg(pi, 0x44d, RFOverrideVal0_old);
+ write_phy_reg(pi, 0x4b0, rfoverride2_old);
+ write_phy_reg(pi, 0x4b1, rfoverride2val_old);
+ write_phy_reg(pi, 0x4f9, rfoverride3_old);
+ write_phy_reg(pi, 0x4fa, rfoverride3val_old);
+ write_phy_reg(pi, 0x938, rfoverride4_old);
+ write_phy_reg(pi, 0x939, rfoverride4val_old);
+ write_phy_reg(pi, 0x43b, afectrlovr_old);
+ write_phy_reg(pi, 0x43c, afectrlovrval_old);
+ write_phy_reg(pi, 0x6da, old_sslpnCalibClkEnCtrl);
+ write_phy_reg(pi, 0x6db, old_sslpnRxFeClkEnCtrl);
- wlc_lcnphy_clear_trsw_override(pi);
+ wlc_lcnphy_clear_trsw_override(pi);
- mod_phy_reg(pi, 0x44c, (0x1 << 2), 0 << 2);
+ mod_phy_reg(pi, 0x44c, (0x1 << 2), 0 << 2);
- for (i = 0; i < 11; i++)
- write_radio_reg(pi, rxiq_cal_rf_reg[i],
- values_to_save[i]);
+ for (i = 0; i < 11; i++)
+ write_radio_reg(pi, rxiq_cal_rf_reg[i],
+ values_to_save[i]);
- if (tx_gain_override_old)
- wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_index_old);
- else
- wlc_lcnphy_disable_tx_gain_override(pi);
+ if (tx_gain_override_old)
+ wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_index_old);
+ else
+ wlc_lcnphy_disable_tx_gain_override(pi);
- wlc_lcnphy_set_tx_pwr_ctrl(pi, tx_pwr_ctrl);
- wlc_lcnphy_rx_gain_override_enable(pi, false);
- }
+ wlc_lcnphy_set_tx_pwr_ctrl(pi, tx_pwr_ctrl);
+ wlc_lcnphy_rx_gain_override_enable(pi, false);
cal_done:
kfree(ptr);
@@ -1781,6 +1829,17 @@ wlc_lcnphy_radio_2064_channel_tune_4313(struct brcms_phy *pi, u8 channel)
write_radio_reg(pi, RADIO_2064_REG038, 3);
write_radio_reg(pi, RADIO_2064_REG091, 7);
}
+
+ if (!(pi->sh->boardflags & BFL_FEM)) {
+ u8 reg038[14] = {0xd, 0xe, 0xd, 0xd, 0xd, 0xc,
+ 0xa, 0xb, 0xb, 0x3, 0x3, 0x2, 0x0, 0x0};
+
+ write_radio_reg(pi, RADIO_2064_REG02A, 0xf);
+ write_radio_reg(pi, RADIO_2064_REG091, 0x3);
+ write_radio_reg(pi, RADIO_2064_REG038, 0x3);
+
+ write_radio_reg(pi, RADIO_2064_REG038, reg038[channel - 1]);
+ }
}
static int
@@ -1975,6 +2034,16 @@ wlc_lcnphy_set_tssi_mux(struct brcms_phy *pi, enum lcnphy_tssi_mode pos)
} else {
mod_radio_reg(pi, RADIO_2064_REG03A, 1, 0x1);
mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 0x8);
+ mod_radio_reg(pi, RADIO_2064_REG028, 0x1, 0x0);
+ mod_radio_reg(pi, RADIO_2064_REG11A, 0x4, 1<<2);
+ mod_radio_reg(pi, RADIO_2064_REG036, 0x10, 0x0);
+ mod_radio_reg(pi, RADIO_2064_REG11A, 0x10, 1<<4);
+ mod_radio_reg(pi, RADIO_2064_REG036, 0x3, 0x0);
+ mod_radio_reg(pi, RADIO_2064_REG035, 0xff, 0x77);
+ mod_radio_reg(pi, RADIO_2064_REG028, 0x1e, 0xe<<1);
+ mod_radio_reg(pi, RADIO_2064_REG112, 0x80, 1<<7);
+ mod_radio_reg(pi, RADIO_2064_REG005, 0x7, 1<<1);
+ mod_radio_reg(pi, RADIO_2064_REG029, 0xf0, 0<<4);
}
} else {
mod_phy_reg(pi, 0x4d9, (0x1 << 2), (0x1) << 2);
@@ -2061,12 +2130,14 @@ static void wlc_lcnphy_pwrctrl_rssiparams(struct brcms_phy *pi)
(auxpga_vmid_temp << 0) | (auxpga_gain_temp << 12));
mod_radio_reg(pi, RADIO_2064_REG082, (1 << 5), (1 << 5));
+ mod_radio_reg(pi, RADIO_2064_REG07C, (1 << 0), (1 << 0));
}
static void wlc_lcnphy_tssi_setup(struct brcms_phy *pi)
{
struct phytbl_info tab;
u32 rfseq, ind;
+ u8 tssi_sel;
tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
tab.tbl_width = 32;
@@ -2088,7 +2159,13 @@ static void wlc_lcnphy_tssi_setup(struct brcms_phy *pi)
mod_phy_reg(pi, 0x503, (0x1 << 4), (1) << 4);
- wlc_lcnphy_set_tssi_mux(pi, LCNPHY_TSSI_EXT);
+ if (pi->sh->boardflags & BFL_FEM) {
+ tssi_sel = 0x1;
+ wlc_lcnphy_set_tssi_mux(pi, LCNPHY_TSSI_EXT);
+ } else {
+ tssi_sel = 0xe;
+ wlc_lcnphy_set_tssi_mux(pi, LCNPHY_TSSI_POST_PA);
+ }
mod_phy_reg(pi, 0x4a4, (0x1 << 14), (0) << 14);
mod_phy_reg(pi, 0x4a4, (0x1 << 15), (1) << 15);
@@ -2124,9 +2201,10 @@ static void wlc_lcnphy_tssi_setup(struct brcms_phy *pi)
mod_phy_reg(pi, 0x49a, (0x1ff << 0), (0xff) << 0);
if (LCNREV_IS(pi->pubpi.phy_rev, 2)) {
- mod_radio_reg(pi, RADIO_2064_REG028, 0xf, 0xe);
+ mod_radio_reg(pi, RADIO_2064_REG028, 0xf, tssi_sel);
mod_radio_reg(pi, RADIO_2064_REG086, 0x4, 0x4);
} else {
+ mod_radio_reg(pi, RADIO_2064_REG028, 0x1e, tssi_sel << 1);
mod_radio_reg(pi, RADIO_2064_REG03A, 0x1, 1);
mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 1 << 3);
}
@@ -2173,6 +2251,10 @@ static void wlc_lcnphy_tssi_setup(struct brcms_phy *pi)
mod_phy_reg(pi, 0x4d7, (0xf << 8), (0) << 8);
+ mod_radio_reg(pi, RADIO_2064_REG035, 0xff, 0x0);
+ mod_radio_reg(pi, RADIO_2064_REG036, 0x3, 0x0);
+ mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 0x8);
+
wlc_lcnphy_pwrctrl_rssiparams(pi);
}
@@ -2791,6 +2873,8 @@ static void wlc_lcnphy_idle_tssi_est(struct brcms_phy_pub *ppi)
read_radio_reg(pi, RADIO_2064_REG007) & 1;
u16 SAVE_jtag_auxpga = read_radio_reg(pi, RADIO_2064_REG0FF) & 0x10;
u16 SAVE_iqadc_aux_en = read_radio_reg(pi, RADIO_2064_REG11F) & 4;
+ u8 SAVE_bbmult = wlc_lcnphy_get_bbmult(pi);
+
idleTssi = read_phy_reg(pi, 0x4ab);
suspend = (0 == (bcma_read32(pi->d11core, D11REGOFFS(maccontrol)) &
MCTL_EN_MAC));
@@ -2808,6 +2892,12 @@ static void wlc_lcnphy_idle_tssi_est(struct brcms_phy_pub *ppi)
mod_radio_reg(pi, RADIO_2064_REG0FF, 0x10, 1 << 4);
mod_radio_reg(pi, RADIO_2064_REG11F, 0x4, 1 << 2);
wlc_lcnphy_tssi_setup(pi);
+
+ mod_phy_reg(pi, 0x4d7, (0x1 << 0), (1 << 0));
+ mod_phy_reg(pi, 0x4d7, (0x1 << 6), (1 << 6));
+
+ wlc_lcnphy_set_bbmult(pi, 0x0);
+
wlc_phy_do_dummy_tx(pi, true, OFF);
idleTssi = ((read_phy_reg(pi, 0x4ab) & (0x1ff << 0))
>> 0);
@@ -2829,6 +2919,7 @@ static void wlc_lcnphy_idle_tssi_est(struct brcms_phy_pub *ppi)
mod_phy_reg(pi, 0x44c, (0x1 << 12), (0) << 12);
+ wlc_lcnphy_set_bbmult(pi, SAVE_bbmult);
wlc_lcnphy_set_tx_gain_override(pi, tx_gain_override_old);
wlc_lcnphy_set_tx_gain(pi, &old_gains);
wlc_lcnphy_set_tx_pwr_ctrl(pi, SAVE_txpwrctrl);
@@ -3042,6 +3133,11 @@ static void wlc_lcnphy_tx_pwr_ctrl_init(struct brcms_phy_pub *ppi)
wlc_lcnphy_write_table(pi, &tab);
tab.tbl_offset++;
}
+ mod_phy_reg(pi, 0x4d0, (0x1 << 0), (0) << 0);
+ mod_phy_reg(pi, 0x4d3, (0xff << 0), (0) << 0);
+ mod_phy_reg(pi, 0x4d3, (0xff << 8), (0) << 8);
+ mod_phy_reg(pi, 0x4d0, (0x1 << 4), (0) << 4);
+ mod_phy_reg(pi, 0x4d0, (0x1 << 2), (0) << 2);
mod_phy_reg(pi, 0x410, (0x1 << 7), (0) << 7);
@@ -3843,7 +3939,6 @@ static void wlc_lcnphy_txpwrtbl_iqlo_cal(struct brcms_phy *pi)
target_gains.pad_gain = 21;
target_gains.dac_gain = 0;
wlc_lcnphy_set_tx_gain(pi, &target_gains);
- wlc_lcnphy_set_tx_pwr_by_index(pi, 16);
if (LCNREV_IS(pi->pubpi.phy_rev, 1) || pi_lcn->lcnphy_hw_iqcal_en) {
@@ -3854,6 +3949,7 @@ static void wlc_lcnphy_txpwrtbl_iqlo_cal(struct brcms_phy *pi)
lcnphy_recal ? LCNPHY_CAL_RECAL :
LCNPHY_CAL_FULL), false);
} else {
+ wlc_lcnphy_set_tx_pwr_by_index(pi, 16);
wlc_lcnphy_tx_iqlo_soft_cal_full(pi);
}
@@ -4278,17 +4374,22 @@ wlc_lcnphy_load_tx_gain_table(struct brcms_phy *pi,
if (CHSPEC_IS5G(pi->radio_chanspec))
pa_gain = 0x70;
else
- pa_gain = 0x70;
+ pa_gain = 0x60;
if (pi->sh->boardflags & BFL_FEM)
pa_gain = 0x10;
+
tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
tab.tbl_width = 32;
tab.tbl_len = 1;
tab.tbl_ptr = &val;
for (j = 0; j < 128; j++) {
- gm_gain = gain_table[j].gm;
+ if (pi->sh->boardflags & BFL_FEM)
+ gm_gain = gain_table[j].gm;
+ else
+ gm_gain = 15;
+
val = (((u32) pa_gain << 24) |
(gain_table[j].pad << 16) |
(gain_table[j].pga << 8) | gm_gain);
@@ -4499,7 +4600,10 @@ static void wlc_radio_2064_init(struct brcms_phy *pi)
write_phy_reg(pi, 0x4ea, 0x4688);
- mod_phy_reg(pi, 0x4eb, (0x7 << 0), 2 << 0);
+ if (pi->sh->boardflags & BFL_FEM)
+ mod_phy_reg(pi, 0x4eb, (0x7 << 0), 2 << 0);
+ else
+ mod_phy_reg(pi, 0x4eb, (0x7 << 0), 3 << 0);
mod_phy_reg(pi, 0x4eb, (0x7 << 6), 0 << 6);
@@ -4510,6 +4614,13 @@ static void wlc_radio_2064_init(struct brcms_phy *pi)
wlc_lcnphy_rcal(pi);
wlc_lcnphy_rc_cal(pi);
+
+ if (!(pi->sh->boardflags & BFL_FEM)) {
+ write_radio_reg(pi, RADIO_2064_REG032, 0x6f);
+ write_radio_reg(pi, RADIO_2064_REG033, 0x19);
+ write_radio_reg(pi, RADIO_2064_REG039, 0xe);
+ }
+
}
static void wlc_lcnphy_radio_init(struct brcms_phy *pi)
@@ -4539,22 +4650,20 @@ static void wlc_lcnphy_tbl_init(struct brcms_phy *pi)
wlc_lcnphy_write_table(pi, &tab);
}
- tab.tbl_id = LCNPHY_TBL_ID_RFSEQ;
- tab.tbl_width = 16;
- tab.tbl_ptr = &val;
- tab.tbl_len = 1;
-
- val = 114;
- tab.tbl_offset = 0;
- wlc_lcnphy_write_table(pi, &tab);
+ if (!(pi->sh->boardflags & BFL_FEM)) {
+ tab.tbl_id = LCNPHY_TBL_ID_RFSEQ;
+ tab.tbl_width = 16;
+ tab.tbl_ptr = &val;
+ tab.tbl_len = 1;
- val = 130;
- tab.tbl_offset = 1;
- wlc_lcnphy_write_table(pi, &tab);
+ val = 150;
+ tab.tbl_offset = 0;
+ wlc_lcnphy_write_table(pi, &tab);
- val = 6;
- tab.tbl_offset = 8;
- wlc_lcnphy_write_table(pi, &tab);
+ val = 220;
+ tab.tbl_offset = 1;
+ wlc_lcnphy_write_table(pi, &tab);
+ }
if (CHSPEC_IS2G(pi->radio_chanspec)) {
if (pi->sh->boardflags & BFL_FEM)
@@ -4946,6 +5055,7 @@ void wlc_phy_chanspec_set_lcnphy(struct brcms_phy *pi, u16 chanspec)
wlc_lcnphy_load_tx_iir_filter(pi, true, 3);
mod_phy_reg(pi, 0x4eb, (0x7 << 3), (1) << 3);
+ wlc_lcnphy_tssi_setup(pi);
}
void wlc_phy_detach_lcnphy(struct brcms_phy *pi)
@@ -4984,8 +5094,7 @@ bool wlc_phy_attach_lcnphy(struct brcms_phy *pi)
if (!wlc_phy_txpwr_srom_read_lcnphy(pi))
return false;
- if ((pi->sh->boardflags & BFL_FEM) &&
- (LCNREV_IS(pi->pubpi.phy_rev, 1))) {
+ if (LCNREV_IS(pi->pubpi.phy_rev, 1)) {
if (pi_lcn->lcnphy_tempsense_option == 3) {
pi->hwpwrctrl = true;
pi->hwpwrctrl_capable = true;
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c
index 622c01c..b7e95ac 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c
@@ -1992,70 +1992,70 @@ static const u16 dot11lcn_sw_ctrl_tbl_4313_epa_rev0[] = {
};
static const u16 dot11lcn_sw_ctrl_tbl_4313_rev0[] = {
- 0x000a,
0x0009,
- 0x0006,
- 0x0005,
0x000a,
- 0x0009,
- 0x0006,
0x0005,
- 0x000a,
- 0x0009,
0x0006,
- 0x0005,
- 0x000a,
0x0009,
- 0x0006,
- 0x0005,
0x000a,
- 0x0009,
- 0x0006,
0x0005,
- 0x000a,
- 0x0009,
0x0006,
- 0x0005,
- 0x000a,
0x0009,
- 0x0006,
- 0x0005,
0x000a,
- 0x0009,
- 0x0006,
0x0005,
- 0x000a,
- 0x0009,
0x0006,
- 0x0005,
- 0x000a,
0x0009,
- 0x0006,
- 0x0005,
0x000a,
- 0x0009,
- 0x0006,
0x0005,
- 0x000a,
- 0x0009,
0x0006,
- 0x0005,
+ 0x0009,
0x000a,
+ 0x0005,
+ 0x0006,
0x0009,
+ 0x000a,
+ 0x0005,
0x0006,
+ 0x0009,
+ 0x000a,
0x0005,
+ 0x0006,
+ 0x0009,
0x000a,
+ 0x0005,
+ 0x0006,
0x0009,
+ 0x000a,
+ 0x0005,
0x0006,
+ 0x0009,
+ 0x000a,
0x0005,
+ 0x0006,
+ 0x0009,
0x000a,
+ 0x0005,
+ 0x0006,
0x0009,
+ 0x000a,
+ 0x0005,
0x0006,
+ 0x0009,
+ 0x000a,
0x0005,
+ 0x0006,
+ 0x0009,
0x000a,
+ 0x0005,
+ 0x0006,
0x0009,
+ 0x000a,
+ 0x0005,
0x0006,
+ 0x0009,
+ 0x000a,
0x0005,
+ 0x0006,
};
static const u16 dot11lcn_sw_ctrl_tbl_rev0[] = {
diff --git a/drivers/net/wireless/iwlwifi/dvm/debugfs.c b/drivers/net/wireless/iwlwifi/dvm/debugfs.c
index 2c056b1..5b9533e 100644
--- a/drivers/net/wireless/iwlwifi/dvm/debugfs.c
+++ b/drivers/net/wireless/iwlwifi/dvm/debugfs.c
@@ -2237,15 +2237,15 @@ static ssize_t iwl_dbgfs_log_event_read(struct file *file,
size_t count, loff_t *ppos)
{
struct iwl_priv *priv = file->private_data;
- char *buf = NULL;
- ssize_t ret;
+ char *buf;
+ int pos = 0;
+ ssize_t ret = -ENOMEM;
- ret = iwl_dump_nic_event_log(priv, true, &buf, true);
- if (ret < 0)
- goto err;
- ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret);
-err:
- kfree(buf);
+ ret = pos = iwl_dump_nic_event_log(priv, true, &buf, true);
+ if (buf) {
+ ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
+ kfree(buf);
+ }
return ret;
}
diff --git a/drivers/net/wireless/iwlwifi/dvm/lib.c b/drivers/net/wireless/iwlwifi/dvm/lib.c
index 0348f42..6ff4660 100644
--- a/drivers/net/wireless/iwlwifi/dvm/lib.c
+++ b/drivers/net/wireless/iwlwifi/dvm/lib.c
@@ -1262,15 +1262,6 @@ int iwl_dvm_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
}
/*
- * This can happen upon FW ASSERT: we clear the STATUS_FW_ERROR flag
- * in iwl_down but cancel the workers only later.
- */
- if (!priv->ucode_loaded) {
- IWL_ERR(priv, "Fw not loaded - dropping CMD: %x\n", cmd->id);
- return -EIO;
- }
-
- /*
* Synchronous commands from this op-mode must hold
* the mutex, this ensures we don't try to send two
* (or more) synchronous commands at a time.
diff --git a/drivers/net/wireless/iwlwifi/dvm/sta.c b/drivers/net/wireless/iwlwifi/dvm/sta.c
index a8632a4..bdba954 100644
--- a/drivers/net/wireless/iwlwifi/dvm/sta.c
+++ b/drivers/net/wireless/iwlwifi/dvm/sta.c
@@ -707,7 +707,6 @@ void iwl_clear_ucode_stations(struct iwl_priv *priv,
void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
{
struct iwl_addsta_cmd sta_cmd;
- static const struct iwl_link_quality_cmd zero_lq = {};
struct iwl_link_quality_cmd lq;
int i;
bool found = false;
@@ -746,9 +745,7 @@ void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
else
memcpy(&lq, priv->stations[i].lq,
sizeof(struct iwl_link_quality_cmd));
-
- if (!memcmp(&lq, &zero_lq, sizeof(lq)))
- send_lq = true;
+ send_lq = true;
}
spin_unlock_bh(&priv->sta_lock);
ret = iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
diff --git a/drivers/net/wireless/iwlwifi/dvm/ucode.c b/drivers/net/wireless/iwlwifi/dvm/ucode.c
index 9b138b8..c6467e5 100644
--- a/drivers/net/wireless/iwlwifi/dvm/ucode.c
+++ b/drivers/net/wireless/iwlwifi/dvm/ucode.c
@@ -450,8 +450,6 @@ int iwl_load_ucode_wait_alive(struct iwl_priv *priv,
return -EIO;
}
- priv->ucode_loaded = true;
-
/*
* This step takes a long time (60-80ms!!) and
* WoWLAN image should be loaded quickly, so
@@ -476,6 +474,8 @@ int iwl_load_ucode_wait_alive(struct iwl_priv *priv,
return ret;
}
+ priv->ucode_loaded = true;
+
return 0;
}
diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.h b/drivers/net/wireless/iwlwifi/iwl-devtrace.h
index c85eb37..dc7e26b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-devtrace.h
+++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.h
@@ -349,23 +349,25 @@ TRACE_EVENT(iwlwifi_dev_rx_data,
TRACE_EVENT(iwlwifi_dev_hcmd,
TP_PROTO(const struct device *dev,
struct iwl_host_cmd *cmd, u16 total_size,
- struct iwl_cmd_header *hdr),
- TP_ARGS(dev, cmd, total_size, hdr),
+ const void *hdr, size_t hdr_len),
+ TP_ARGS(dev, cmd, total_size, hdr, hdr_len),
TP_STRUCT__entry(
DEV_ENTRY
__dynamic_array(u8, hcmd, total_size)
__field(u32, flags)
),
TP_fast_assign(
- int i, offset = sizeof(*hdr);
+ int i, offset = hdr_len;
DEV_ASSIGN;
__entry->flags = cmd->flags;
- memcpy(__get_dynamic_array(hcmd), hdr, sizeof(*hdr));
+ memcpy(__get_dynamic_array(hcmd), hdr, hdr_len);
for (i = 0; i < IWL_MAX_CMD_TFDS; i++) {
if (!cmd->len[i])
continue;
+ if (!(cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY))
+ continue;
memcpy((u8 *)__get_dynamic_array(hcmd) + offset,
cmd->data[i], cmd->len[i]);
offset += cmd->len[i];
diff --git a/drivers/net/wireless/iwlwifi/pcie/internal.h b/drivers/net/wireless/iwlwifi/pcie/internal.h
index bc5e9ec..d91d2e8 100644
--- a/drivers/net/wireless/iwlwifi/pcie/internal.h
+++ b/drivers/net/wireless/iwlwifi/pcie/internal.h
@@ -182,15 +182,6 @@ struct iwl_queue {
#define TFD_TX_CMD_SLOTS 256
#define TFD_CMD_SLOTS 32
-/*
- * The FH will write back to the first TB only, so we need
- * to copy some data into the buffer regardless of whether
- * it should be mapped or not. This indicates how much to
- * copy, even for HCMDs it must be big enough to fit the
- * DRAM scratch from the TX cmd, at least 16 bytes.
- */
-#define IWL_HCMD_MIN_COPY_SIZE 16
-
struct iwl_pcie_txq_entry {
struct iwl_device_cmd *cmd;
struct iwl_device_cmd *copy_cmd;
diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c
index d760da9..6c5b867 100644
--- a/drivers/net/wireless/iwlwifi/pcie/tx.c
+++ b/drivers/net/wireless/iwlwifi/pcie/tx.c
@@ -1131,12 +1131,10 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
void *dup_buf = NULL;
dma_addr_t phys_addr;
int idx;
- u16 copy_size, cmd_size, dma_size;
+ u16 copy_size, cmd_size;
bool had_nocopy = false;
int i;
u32 cmd_pos;
- const u8 *cmddata[IWL_MAX_CMD_TFDS];
- u16 cmdlen[IWL_MAX_CMD_TFDS];
copy_size = sizeof(out_cmd->hdr);
cmd_size = sizeof(out_cmd->hdr);
@@ -1145,23 +1143,8 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
BUILD_BUG_ON(IWL_MAX_CMD_TFDS > IWL_NUM_OF_TBS - 1);
for (i = 0; i < IWL_MAX_CMD_TFDS; i++) {
- cmddata[i] = cmd->data[i];
- cmdlen[i] = cmd->len[i];
-
if (!cmd->len[i])
continue;
-
- /* need at least IWL_HCMD_MIN_COPY_SIZE copied */
- if (copy_size < IWL_HCMD_MIN_COPY_SIZE) {
- int copy = IWL_HCMD_MIN_COPY_SIZE - copy_size;
-
- if (copy > cmdlen[i])
- copy = cmdlen[i];
- cmdlen[i] -= copy;
- cmddata[i] += copy;
- copy_size += copy;
- }
-
if (cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY) {
had_nocopy = true;
if (WARN_ON(cmd->dataflags[i] & IWL_HCMD_DFL_DUP)) {
@@ -1181,7 +1164,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
goto free_dup_buf;
}
- dup_buf = kmemdup(cmddata[i], cmdlen[i],
+ dup_buf = kmemdup(cmd->data[i], cmd->len[i],
GFP_ATOMIC);
if (!dup_buf)
return -ENOMEM;
@@ -1191,7 +1174,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
idx = -EINVAL;
goto free_dup_buf;
}
- copy_size += cmdlen[i];
+ copy_size += cmd->len[i];
}
cmd_size += cmd->len[i];
}
@@ -1238,31 +1221,14 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
/* and copy the data that needs to be copied */
cmd_pos = offsetof(struct iwl_device_cmd, payload);
- copy_size = sizeof(out_cmd->hdr);
for (i = 0; i < IWL_MAX_CMD_TFDS; i++) {
- int copy = 0;
-
if (!cmd->len[i])
continue;
-
- /* need at least IWL_HCMD_MIN_COPY_SIZE copied */
- if (copy_size < IWL_HCMD_MIN_COPY_SIZE) {
- copy = IWL_HCMD_MIN_COPY_SIZE - copy_size;
-
- if (copy > cmd->len[i])
- copy = cmd->len[i];
- }
-
- /* copy everything if not nocopy/dup */
- if (!(cmd->dataflags[i] & (IWL_HCMD_DFL_NOCOPY |
- IWL_HCMD_DFL_DUP)))
- copy = cmd->len[i];
-
- if (copy) {
- memcpy((u8 *)out_cmd + cmd_pos, cmd->data[i], copy);
- cmd_pos += copy;
- copy_size += copy;
- }
+ if (cmd->dataflags[i] & (IWL_HCMD_DFL_NOCOPY |
+ IWL_HCMD_DFL_DUP))
+ break;
+ memcpy((u8 *)out_cmd + cmd_pos, cmd->data[i], cmd->len[i]);
+ cmd_pos += cmd->len[i];
}
WARN_ON_ONCE(txq->entries[idx].copy_cmd);
@@ -1288,14 +1254,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
out_cmd->hdr.cmd, le16_to_cpu(out_cmd->hdr.sequence),
cmd_size, q->write_ptr, idx, trans_pcie->cmd_queue);
- /*
- * If the entire command is smaller than IWL_HCMD_MIN_COPY_SIZE, we must
- * still map at least that many bytes for the hardware to write back to.
- * We have enough space, so that's not a problem.
- */
- dma_size = max_t(u16, copy_size, IWL_HCMD_MIN_COPY_SIZE);
-
- phys_addr = dma_map_single(trans->dev, &out_cmd->hdr, dma_size,
+ phys_addr = dma_map_single(trans->dev, &out_cmd->hdr, copy_size,
DMA_BIDIRECTIONAL);
if (unlikely(dma_mapping_error(trans->dev, phys_addr))) {
idx = -ENOMEM;
@@ -1303,15 +1262,14 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
}
dma_unmap_addr_set(out_meta, mapping, phys_addr);
- dma_unmap_len_set(out_meta, len, dma_size);
+ dma_unmap_len_set(out_meta, len, copy_size);
iwl_pcie_txq_build_tfd(trans, txq, phys_addr, copy_size, 1);
- /* map the remaining (adjusted) nocopy/dup fragments */
for (i = 0; i < IWL_MAX_CMD_TFDS; i++) {
- const void *data = cmddata[i];
+ const void *data = cmd->data[i];
- if (!cmdlen[i])
+ if (!cmd->len[i])
continue;
if (!(cmd->dataflags[i] & (IWL_HCMD_DFL_NOCOPY |
IWL_HCMD_DFL_DUP)))
@@ -1319,7 +1277,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
if (cmd->dataflags[i] & IWL_HCMD_DFL_DUP)
data = dup_buf;
phys_addr = dma_map_single(trans->dev, (void *)data,
- cmdlen[i], DMA_BIDIRECTIONAL);
+ cmd->len[i], DMA_BIDIRECTIONAL);
if (dma_mapping_error(trans->dev, phys_addr)) {
iwl_pcie_tfd_unmap(trans, out_meta,
&txq->tfds[q->write_ptr],
@@ -1328,7 +1286,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
goto out;
}
- iwl_pcie_txq_build_tfd(trans, txq, phys_addr, cmdlen[i], 0);
+ iwl_pcie_txq_build_tfd(trans, txq, phys_addr, cmd->len[i], 0);
}
out_meta->flags = cmd->flags;
@@ -1338,7 +1296,8 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
txq->need_update = 1;
- trace_iwlwifi_dev_hcmd(trans->dev, cmd, cmd_size, &out_cmd->hdr);
+ trace_iwlwifi_dev_hcmd(trans->dev, cmd, cmd_size,
+ &out_cmd->hdr, copy_size);
/* start timer if queue currently empty */
if (q->read_ptr == q->write_ptr && trans_pcie->wd_timeout)
diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c
index 4557833..739309e 100644
--- a/drivers/net/wireless/libertas/if_sdio.c
+++ b/drivers/net/wireless/libertas/if_sdio.c
@@ -825,11 +825,6 @@ static void if_sdio_finish_power_on(struct if_sdio_card *card)
sdio_release_host(func);
- /* Set fw_ready before queuing any commands so that
- * lbs_thread won't block from sending them to firmware.
- */
- priv->fw_ready = 1;
-
/*
* FUNC_INIT is required for SD8688 WLAN/BT multiple functions
*/
@@ -844,6 +839,7 @@ static void if_sdio_finish_power_on(struct if_sdio_card *card)
netdev_alert(priv->dev, "CMD_FUNC_INIT cmd failed\n");
}
+ priv->fw_ready = 1;
wake_up(&card->pwron_waitq);
if (!card->started) {
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index 3eca710..cdb11b3 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -1846,8 +1846,7 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy,
}
}
- for (i = 0; i < min_t(u32, request->n_channels,
- MWIFIEX_USER_SCAN_CHAN_MAX); i++) {
+ for (i = 0; i < request->n_channels; i++) {
chan = request->channels[i];
priv->user_scan_cfg->chan_list[i].chan_number = chan->hw_value;
priv->user_scan_cfg->chan_list[i].radio_type = chan->band;
diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c
index bc9a402..5f438e6 100644
--- a/drivers/net/wireless/mwifiex/cmdevt.c
+++ b/drivers/net/wireless/mwifiex/cmdevt.c
@@ -156,20 +156,6 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv,
return -1;
}
- cmd_code = le16_to_cpu(host_cmd->command);
- cmd_size = le16_to_cpu(host_cmd->size);
-
- if (adapter->hw_status == MWIFIEX_HW_STATUS_RESET &&
- cmd_code != HostCmd_CMD_FUNC_SHUTDOWN &&
- cmd_code != HostCmd_CMD_FUNC_INIT) {
- dev_err(adapter->dev,
- "DNLD_CMD: FW in reset state, ignore cmd %#x\n",
- cmd_code);
- mwifiex_complete_cmd(adapter, cmd_node);
- mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
- return -1;
- }
-
/* Set command sequence number */
adapter->seq_num++;
host_cmd->seq_num = cpu_to_le16(HostCmd_SET_SEQ_NO_BSS_INFO
@@ -181,6 +167,9 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv,
adapter->curr_cmd = cmd_node;
spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
+ cmd_code = le16_to_cpu(host_cmd->command);
+ cmd_size = le16_to_cpu(host_cmd->size);
+
/* Adjust skb length */
if (cmd_node->cmd_skb->len > cmd_size)
/*
@@ -499,6 +488,8 @@ int mwifiex_send_cmd_sync(struct mwifiex_private *priv, uint16_t cmd_no,
ret = mwifiex_send_cmd_async(priv, cmd_no, cmd_action, cmd_oid,
data_buf);
+ if (!ret)
+ ret = mwifiex_wait_queue_complete(adapter);
return ret;
}
@@ -601,10 +592,9 @@ int mwifiex_send_cmd_async(struct mwifiex_private *priv, uint16_t cmd_no,
if (cmd_no == HostCmd_CMD_802_11_SCAN) {
mwifiex_queue_scan_cmd(priv, cmd_node);
} else {
+ adapter->cmd_queued = cmd_node;
mwifiex_insert_cmd_to_pending_q(adapter, cmd_node, true);
queue_work(adapter->workqueue, &adapter->main_work);
- if (cmd_node->wait_q_enabled)
- ret = mwifiex_wait_queue_complete(adapter, cmd_node);
}
return ret;
diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c
index 78c3aa6..39f03ce 100644
--- a/drivers/net/wireless/mwifiex/init.c
+++ b/drivers/net/wireless/mwifiex/init.c
@@ -707,14 +707,6 @@ mwifiex_shutdown_drv(struct mwifiex_adapter *adapter)
return ret;
}
- /* cancel current command */
- if (adapter->curr_cmd) {
- dev_warn(adapter->dev, "curr_cmd is still in processing\n");
- del_timer(&adapter->cmd_timer);
- mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd);
- adapter->curr_cmd = NULL;
- }
-
/* shut down mwifiex */
dev_dbg(adapter->dev, "info: shutdown mwifiex...\n");
diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c
index 3473876..88664ae 100644
--- a/drivers/net/wireless/mwifiex/join.c
+++ b/drivers/net/wireless/mwifiex/join.c
@@ -1092,9 +1092,10 @@ mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv,
adhoc_join->bss_descriptor.bssid,
adhoc_join->bss_descriptor.ssid);
- for (i = 0; i < MWIFIEX_SUPPORTED_RATES &&
- bss_desc->supported_rates[i]; i++)
- ;
+ for (i = 0; bss_desc->supported_rates[i] &&
+ i < MWIFIEX_SUPPORTED_RATES;
+ i++)
+ ;
rates_size = i;
/* Copy Data Rates from the Rates recorded in scan response */
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index db39449..1b3cfc8 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -714,6 +714,7 @@ struct mwifiex_adapter {
u16 cmd_wait_q_required;
struct mwifiex_wait_queue cmd_wait_q;
u8 scan_wait_q_woken;
+ struct cmd_ctrl_node *cmd_queued;
spinlock_t queue_lock; /* lock for tx queues */
struct completion fw_load;
u8 country_code[IEEE80211_COUNTRY_STRING_LEN];
@@ -993,8 +994,7 @@ int mwifiex_request_set_multicast_list(struct mwifiex_private *priv,
struct mwifiex_multicast_list *mcast_list);
int mwifiex_copy_mcast_addr(struct mwifiex_multicast_list *mlist,
struct net_device *dev);
-int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter,
- struct cmd_ctrl_node *cmd_queued);
+int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter);
int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss,
struct cfg80211_ssid *req_ssid);
int mwifiex_cancel_hs(struct mwifiex_private *priv, int cmd_type);
diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c
index b7a5387..b879e13 100644
--- a/drivers/net/wireless/mwifiex/pcie.c
+++ b/drivers/net/wireless/mwifiex/pcie.c
@@ -291,7 +291,7 @@ static int mwifiex_pm_wakeup_card(struct mwifiex_adapter *adapter)
i++;
usleep_range(10, 20);
/* 50ms max wait */
- if (i == 5000)
+ if (i == 50000)
break;
}
@@ -1831,9 +1831,9 @@ static void mwifiex_pcie_cleanup(struct mwifiex_adapter *adapter)
if (pdev) {
pci_iounmap(pdev, card->pci_mmap);
pci_iounmap(pdev, card->pci_mmap1);
+
+ pci_release_regions(pdev);
pci_disable_device(pdev);
- pci_release_region(pdev, 2);
- pci_release_region(pdev, 0);
pci_set_drvdata(pdev, NULL);
}
}
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c
index 771be26..973a9d9 100644
--- a/drivers/net/wireless/mwifiex/scan.c
+++ b/drivers/net/wireless/mwifiex/scan.c
@@ -1366,15 +1366,10 @@ int mwifiex_scan_networks(struct mwifiex_private *priv,
list_del(&cmd_node->list);
spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
flags);
+ adapter->cmd_queued = cmd_node;
mwifiex_insert_cmd_to_pending_q(adapter, cmd_node,
true);
queue_work(adapter->workqueue, &adapter->main_work);
-
- /* Perform internal scan synchronously */
- if (!priv->scan_request) {
- dev_dbg(adapter->dev, "wait internal scan\n");
- mwifiex_wait_queue_complete(adapter, cmd_node);
- }
} else {
spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
flags);
@@ -1770,12 +1765,7 @@ check_next_scan:
/* Need to indicate IOCTL complete */
if (adapter->curr_cmd->wait_q_enabled) {
adapter->cmd_wait_q.status = 0;
- if (!priv->scan_request) {
- dev_dbg(adapter->dev,
- "complete internal scan\n");
- mwifiex_complete_cmd(adapter,
- adapter->curr_cmd);
- }
+ mwifiex_complete_cmd(adapter, adapter->curr_cmd);
}
if (priv->report_scan_result)
priv->report_scan_result = false;
@@ -1933,6 +1923,9 @@ int mwifiex_request_scan(struct mwifiex_private *priv,
/* Normal scan */
ret = mwifiex_scan_networks(priv, NULL);
+ if (!ret)
+ ret = mwifiex_wait_queue_complete(priv->adapter);
+
up(&priv->async_sem);
return ret;
diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c
index 1798bc7..f542bb8 100644
--- a/drivers/net/wireless/mwifiex/sta_ioctl.c
+++ b/drivers/net/wireless/mwifiex/sta_ioctl.c
@@ -54,10 +54,16 @@ int mwifiex_copy_mcast_addr(struct mwifiex_multicast_list *mlist,
* This function waits on a cmd wait queue. It also cancels the pending
* request after waking up, in case of errors.
*/
-int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter,
- struct cmd_ctrl_node *cmd_queued)
+int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter)
{
int status;
+ struct cmd_ctrl_node *cmd_queued;
+
+ if (!adapter->cmd_queued)
+ return 0;
+
+ cmd_queued = adapter->cmd_queued;
+ adapter->cmd_queued = NULL;
dev_dbg(adapter->dev, "cmd pending\n");
atomic_inc(&adapter->cmd_pending);
diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c
index 1f78585..800a165 100644
--- a/drivers/net/wireless/p54/p54usb.c
+++ b/drivers/net/wireless/p54/p54usb.c
@@ -84,8 +84,8 @@ static struct usb_device_id p54u_table[] = {
{USB_DEVICE(0x06b9, 0x0121)}, /* Thomson SpeedTouch 121g */
{USB_DEVICE(0x0707, 0xee13)}, /* SMC 2862W-G version 2 */
{USB_DEVICE(0x0803, 0x4310)}, /* Zoom 4410a */
+ {USB_DEVICE(0x083a, 0x4503)}, /* T-Com Sinus 154 data II */
{USB_DEVICE(0x083a, 0x4521)}, /* Siemens Gigaset USB Adapter 54 version 2 */
- {USB_DEVICE(0x083a, 0x4531)}, /* T-Com Sinus 154 data II */
{USB_DEVICE(0x083a, 0xc501)}, /* Zoom Wireless-G 4410 */
{USB_DEVICE(0x083a, 0xf503)}, /* Accton FD7050E ver 1010ec */
{USB_DEVICE(0x0846, 0x4240)}, /* Netgear WG111 (v2) */
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 0b55706..197b446 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -4386,8 +4386,6 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
if (!rt2x00_rt(rt2x00dev, RT5390) &&
!rt2x00_rt(rt2x00dev, RT5392)) {
- u8 min_gain = rt2x00_rt(rt2x00dev, RT3070) ? 1 : 2;
-
rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr);
rt2x00_set_field8(&rfcsr, RFCSR17_TX_LO1_EN, 0);
if (rt2x00_rt(rt2x00dev, RT3070) ||
@@ -4398,10 +4396,8 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
&rt2x00dev->cap_flags))
rt2x00_set_field8(&rfcsr, RFCSR17_R, 1);
}
- if (drv_data->txmixer_gain_24g >= min_gain) {
- rt2x00_set_field8(&rfcsr, RFCSR17_TXMIXER_GAIN,
- drv_data->txmixer_gain_24g);
- }
+ rt2x00_set_field8(&rfcsr, RFCSR17_TXMIXER_GAIN,
+ drv_data->txmixer_gain_24g);
rt2800_rfcsr_write(rt2x00dev, 17, rfcsr);
}
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index cdbfc30..44f8b3f 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -1209,9 +1209,7 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
rt2x00dev->hw->wiphy->interface_modes |=
BIT(NL80211_IFTYPE_ADHOC) |
BIT(NL80211_IFTYPE_AP) |
-#ifdef CONFIG_MAC80211_MESH
BIT(NL80211_IFTYPE_MESH_POINT) |
-#endif
BIT(NL80211_IFTYPE_WDS);
rt2x00dev->hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c
index b1c673e..a0c8cae 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.c
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.c
@@ -52,8 +52,8 @@ int rt2x00pci_regbusy_read(struct rt2x00_dev *rt2x00dev,
udelay(REGISTER_BUSY_DELAY);
}
- printk_once(KERN_ERR "%s() Indirect register access failed: "
- "offset=0x%.08x, value=0x%.08x\n", __func__, offset, *reg);
+ ERROR(rt2x00dev, "Indirect register access failed: "
+ "offset=0x%.08x, value=0x%.08x\n", offset, *reg);
*reg = ~0;
return 0;
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
index c08d0f4..b1ccff4 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
@@ -1377,57 +1377,74 @@ void rtl92cu_card_disable(struct ieee80211_hw *hw)
void rtl92cu_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid)
{
+ /* dummy routine needed for callback from rtl_op_configure_filter() */
+}
+
+/*========================================================================== */
+
+static void _rtl92cu_set_check_bssid(struct ieee80211_hw *hw,
+ enum nl80211_iftype type)
+{
struct rtl_priv *rtlpriv = rtl_priv(hw);
- struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
u32 reg_rcr = rtl_read_dword(rtlpriv, REG_RCR);
+ struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+ u8 filterout_non_associated_bssid = false;
- if (rtlpriv->psc.rfpwr_state != ERFON)
- return;
-
- if (check_bssid) {
- u8 tmp;
+ switch (type) {
+ case NL80211_IFTYPE_ADHOC:
+ case NL80211_IFTYPE_STATION:
+ filterout_non_associated_bssid = true;
+ break;
+ case NL80211_IFTYPE_UNSPECIFIED:
+ case NL80211_IFTYPE_AP:
+ default:
+ break;
+ }
+ if (filterout_non_associated_bssid) {
if (IS_NORMAL_CHIP(rtlhal->version)) {
- reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN);
- tmp = BIT(4);
+ switch (rtlphy->current_io_type) {
+ case IO_CMD_RESUME_DM_BY_SCAN:
+ reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN);
+ rtlpriv->cfg->ops->set_hw_reg(hw,
+ HW_VAR_RCR, (u8 *)(&reg_rcr));
+ /* enable update TSF */
+ _rtl92cu_set_bcn_ctrl_reg(hw, 0, BIT(4));
+ break;
+ case IO_CMD_PAUSE_DM_BY_SCAN:
+ reg_rcr &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);
+ rtlpriv->cfg->ops->set_hw_reg(hw,
+ HW_VAR_RCR, (u8 *)(&reg_rcr));
+ /* disable update TSF */
+ _rtl92cu_set_bcn_ctrl_reg(hw, BIT(4), 0);
+ break;
+ }
} else {
- reg_rcr |= RCR_CBSSID;
- tmp = BIT(4) | BIT(5);
+ reg_rcr |= (RCR_CBSSID);
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR,
+ (u8 *)(&reg_rcr));
+ _rtl92cu_set_bcn_ctrl_reg(hw, 0, (BIT(4)|BIT(5)));
}
- rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR,
- (u8 *) (&reg_rcr));
- _rtl92cu_set_bcn_ctrl_reg(hw, 0, tmp);
- } else {
- u8 tmp;
+ } else if (filterout_non_associated_bssid == false) {
if (IS_NORMAL_CHIP(rtlhal->version)) {
- reg_rcr &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);
- tmp = BIT(4);
+ reg_rcr &= (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN));
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR,
+ (u8 *)(&reg_rcr));
+ _rtl92cu_set_bcn_ctrl_reg(hw, BIT(4), 0);
} else {
- reg_rcr &= ~RCR_CBSSID;
- tmp = BIT(4) | BIT(5);
+ reg_rcr &= (~RCR_CBSSID);
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR,
+ (u8 *)(&reg_rcr));
+ _rtl92cu_set_bcn_ctrl_reg(hw, (BIT(4)|BIT(5)), 0);
}
- reg_rcr &= (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN));
- rtlpriv->cfg->ops->set_hw_reg(hw,
- HW_VAR_RCR, (u8 *) (&reg_rcr));
- _rtl92cu_set_bcn_ctrl_reg(hw, tmp, 0);
}
}
-/*========================================================================== */
-
int rtl92cu_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type)
{
- struct rtl_priv *rtlpriv = rtl_priv(hw);
-
if (_rtl92cu_set_media_status(hw, type))
return -EOPNOTSUPP;
-
- if (rtlpriv->mac80211.link_state == MAC80211_LINKED) {
- if (type != NL80211_IFTYPE_AP)
- rtl92cu_set_check_bssid(hw, true);
- } else {
- rtl92cu_set_check_bssid(hw, false);
- }
-
+ _rtl92cu_set_check_bssid(hw, type);
return 0;
}
@@ -2041,6 +2058,8 @@ void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw,
(shortgi_rate << 4) | (shortgi_rate);
}
rtl_write_dword(rtlpriv, REG_ARFR0 + ratr_index * 4, ratr_value);
+ RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, "%x\n",
+ rtl_read_dword(rtlpriv, REG_ARFR0));
}
void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level)
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
index b450931..b7e6607 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
@@ -285,7 +285,6 @@ static struct usb_device_id rtl8192c_usb_ids[] = {
{RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x817f, rtl92cu_hal_cfg)},
/* RTL8188CUS-VL */
{RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x818a, rtl92cu_hal_cfg)},
- {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x819a, rtl92cu_hal_cfg)},
/* 8188 Combo for BC4 */
{RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8754, rtl92cu_hal_cfg)},
@@ -364,15 +363,9 @@ static struct usb_device_id rtl8192c_usb_ids[] = {
MODULE_DEVICE_TABLE(usb, rtl8192c_usb_ids);
-static int rtl8192cu_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- return rtl_usb_probe(intf, id, &rtl92cu_hal_cfg);
-}
-
static struct usb_driver rtl8192cu_driver = {
.name = "rtl8192cu",
- .probe = rtl8192cu_probe,
+ .probe = rtl_usb_probe,
.disconnect = rtl_usb_disconnect,
.id_table = rtl8192c_usb_ids,
diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c
index 82bc684..1535efd 100644
--- a/drivers/net/wireless/rtlwifi/usb.c
+++ b/drivers/net/wireless/rtlwifi/usb.c
@@ -42,12 +42,8 @@
static void usbctrl_async_callback(struct urb *urb)
{
- if (urb) {
- /* free dr */
- kfree(urb->setup_packet);
- /* free databuf */
- kfree(urb->transfer_buffer);
- }
+ if (urb)
+ kfree(urb->context);
}
static int _usbctrl_vendorreq_async_write(struct usb_device *udev, u8 request,
@@ -59,47 +55,39 @@ static int _usbctrl_vendorreq_async_write(struct usb_device *udev, u8 request,
u8 reqtype;
struct usb_ctrlrequest *dr;
struct urb *urb;
- const u16 databuf_maxlen = REALTEK_USB_VENQT_MAX_BUF_SIZE;
- u8 *databuf;
-
- if (WARN_ON_ONCE(len > databuf_maxlen))
- len = databuf_maxlen;
+ struct rtl819x_async_write_data {
+ u8 data[REALTEK_USB_VENQT_MAX_BUF_SIZE];
+ struct usb_ctrlrequest dr;
+ } *buf;
pipe = usb_sndctrlpipe(udev, 0); /* write_out */
reqtype = REALTEK_USB_VENQT_WRITE;
- dr = kmalloc(sizeof(*dr), GFP_ATOMIC);
- if (!dr)
- return -ENOMEM;
-
- databuf = kmalloc(databuf_maxlen, GFP_ATOMIC);
- if (!databuf) {
- kfree(dr);
+ buf = kmalloc(sizeof(*buf), GFP_ATOMIC);
+ if (!buf)
return -ENOMEM;
- }
urb = usb_alloc_urb(0, GFP_ATOMIC);
if (!urb) {
- kfree(databuf);
- kfree(dr);
+ kfree(buf);
return -ENOMEM;
}
+ dr = &buf->dr;
+
dr->bRequestType = reqtype;
dr->bRequest = request;
dr->wValue = cpu_to_le16(value);
dr->wIndex = cpu_to_le16(index);
dr->wLength = cpu_to_le16(len);
/* data are already in little-endian order */
- memcpy(databuf, pdata, len);
+ memcpy(buf, pdata, len);
usb_fill_control_urb(urb, udev, pipe,
- (unsigned char *)dr, databuf, len,
- usbctrl_async_callback, NULL);
+ (unsigned char *)dr, buf, len,
+ usbctrl_async_callback, buf);
rc = usb_submit_urb(urb, GFP_ATOMIC);
- if (rc < 0) {
- kfree(databuf);
- kfree(dr);
- }
+ if (rc < 0)
+ kfree(buf);
usb_free_urb(urb);
return rc;
}
@@ -854,7 +842,6 @@ static void _rtl_usb_transmit(struct ieee80211_hw *hw, struct sk_buff *skb,
if (unlikely(!_urb)) {
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
"Can't allocate urb. Drop skb!\n");
- kfree_skb(skb);
return;
}
urb_list = &rtlusb->tx_pending[ep_num];
@@ -954,8 +941,7 @@ static struct rtl_intf_ops rtl_usb_ops = {
};
int rtl_usb_probe(struct usb_interface *intf,
- const struct usb_device_id *id,
- struct rtl_hal_cfg *rtl_hal_cfg)
+ const struct usb_device_id *id)
{
int err;
struct ieee80211_hw *hw = NULL;
@@ -990,7 +976,7 @@ int rtl_usb_probe(struct usb_interface *intf,
usb_set_intfdata(intf, hw);
/* init cfg & intf_ops */
rtlpriv->rtlhal.interface = INTF_USB;
- rtlpriv->cfg = rtl_hal_cfg;
+ rtlpriv->cfg = (struct rtl_hal_cfg *)(id->driver_info);
rtlpriv->intf_ops = &rtl_usb_ops;
rtl_dbgp_flag_init(hw);
/* Init IO handler */
diff --git a/drivers/net/wireless/rtlwifi/usb.h b/drivers/net/wireless/rtlwifi/usb.h
index fb986f9..5235136 100644
--- a/drivers/net/wireless/rtlwifi/usb.h
+++ b/drivers/net/wireless/rtlwifi/usb.h
@@ -157,8 +157,7 @@ struct rtl_usb_priv {
int rtl_usb_probe(struct usb_interface *intf,
- const struct usb_device_id *id,
- struct rtl_hal_cfg *rtl92cu_hal_cfg);
+ const struct usb_device_id *id);
void rtl_usb_disconnect(struct usb_interface *intf);
int rtl_usb_suspend(struct usb_interface *pusb_intf, pm_message_t message);
int rtl_usb_resume(struct usb_interface *pusb_intf);
diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c
index 221f426..b8c5193 100644
--- a/drivers/net/xen-netback/interface.c
+++ b/drivers/net/xen-netback/interface.c
@@ -132,7 +132,6 @@ static void xenvif_up(struct xenvif *vif)
static void xenvif_down(struct xenvif *vif)
{
disable_irq(vif->irq);
- del_timer_sync(&vif->credit_timeout);
xen_netbk_deschedule_xenvif(vif);
xen_netbk_remove_xenvif(vif);
}
@@ -364,6 +363,8 @@ void xenvif_disconnect(struct xenvif *vif)
atomic_dec(&vif->refcnt);
wait_event(vif->waiting_to_free, atomic_read(&vif->refcnt) == 0);
+ del_timer_sync(&vif->credit_timeout);
+
if (vif->irq)
unbind_from_irqhandler(vif->irq, vif);
diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c
index cd49ba9..2b9520c 100644
--- a/drivers/net/xen-netback/netback.c
+++ b/drivers/net/xen-netback/netback.c
@@ -911,13 +911,13 @@ static int netbk_count_requests(struct xenvif *vif,
if (frags >= work_to_do) {
netdev_err(vif->dev, "Need more frags\n");
netbk_fatal_tx_err(vif);
- return -ENODATA;
+ return -frags;
}
if (unlikely(frags >= MAX_SKB_FRAGS)) {
netdev_err(vif->dev, "Too many frags\n");
netbk_fatal_tx_err(vif);
- return -E2BIG;
+ return -frags;
}
memcpy(txp, RING_GET_REQUEST(&vif->tx, cons + frags),
@@ -925,7 +925,7 @@ static int netbk_count_requests(struct xenvif *vif,
if (txp->size > first->size) {
netdev_err(vif->dev, "Frag is bigger than frame.\n");
netbk_fatal_tx_err(vif);
- return -EIO;
+ return -frags;
}
first->size -= txp->size;
@@ -935,7 +935,7 @@ static int netbk_count_requests(struct xenvif *vif,
netdev_err(vif->dev, "txp->offset: %x, size: %u\n",
txp->offset, txp->size);
netbk_fatal_tx_err(vif);
- return -EINVAL;
+ return -frags;
}
} while ((txp++)->flags & XEN_NETTXF_more_data);
return frags;
diff --git a/drivers/of/base.c b/drivers/of/base.c
index ec2fd1f..2390ddb 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -55,7 +55,7 @@ static DEFINE_MUTEX(of_aliases_mutex);
/* use when traversing tree through the allnext, child, sibling,
* or parent members of struct device_node.
*/
-DEFINE_RAW_SPINLOCK(devtree_lock);
+DEFINE_RWLOCK(devtree_lock);
int of_n_addr_cells(struct device_node *np)
{
@@ -164,14 +164,16 @@ void of_node_put(struct device_node *node)
EXPORT_SYMBOL(of_node_put);
#endif /* CONFIG_OF_DYNAMIC */
-static struct property *__of_find_property(const struct device_node *np,
- const char *name, int *lenp)
+struct property *of_find_property(const struct device_node *np,
+ const char *name,
+ int *lenp)
{
struct property *pp;
if (!np)
return NULL;
+ read_lock(&devtree_lock);
for (pp = np->properties; pp; pp = pp->next) {
if (of_prop_cmp(pp->name, name) == 0) {
if (lenp)
@@ -179,20 +181,7 @@ static struct property *__of_find_property(const struct device_node *np,
break;
}
}
-
- return pp;
-}
-
-struct property *of_find_property(const struct device_node *np,
- const char *name,
- int *lenp)
-{
- struct property *pp;
- unsigned long flags;
-
- raw_spin_lock_irqsave(&devtree_lock, flags);
- pp = __of_find_property(np, name, lenp);
- raw_spin_unlock_irqrestore(&devtree_lock, flags);
+ read_unlock(&devtree_lock);
return pp;
}
@@ -210,13 +199,13 @@ struct device_node *of_find_all_nodes(struct device_node *prev)
{
struct device_node *np;
- raw_spin_lock(&devtree_lock);
+ read_lock(&devtree_lock);
np = prev ? prev->allnext : of_allnodes;
for (; np != NULL; np = np->allnext)
if (of_node_get(np))
break;
of_node_put(prev);
- raw_spin_unlock(&devtree_lock);
+ read_unlock(&devtree_lock);
return np;
}
EXPORT_SYMBOL(of_find_all_nodes);
@@ -225,20 +214,8 @@ EXPORT_SYMBOL(of_find_all_nodes);
* Find a property with a given name for a given node
* and return the value.
*/
-static const void *__of_get_property(const struct device_node *np,
- const char *name, int *lenp)
-{
- struct property *pp = __of_find_property(np, name, lenp);
-
- return pp ? pp->value : NULL;
-}
-
-/*
- * Find a property with a given name for a given node
- * and return the value.
- */
const void *of_get_property(const struct device_node *np, const char *name,
- int *lenp)
+ int *lenp)
{
struct property *pp = of_find_property(np, name, lenp);
@@ -249,13 +226,13 @@ EXPORT_SYMBOL(of_get_property);
/** Checks if the given "compat" string matches one of the strings in
* the device's "compatible" property
*/
-static int __of_device_is_compatible(const struct device_node *device,
- const char *compat)
+int of_device_is_compatible(const struct device_node *device,
+ const char *compat)
{
const char* cp;
int cplen, l;
- cp = __of_get_property(device, "compatible", &cplen);
+ cp = of_get_property(device, "compatible", &cplen);
if (cp == NULL)
return 0;
while (cplen > 0) {
@@ -268,21 +245,6 @@ static int __of_device_is_compatible(const struct device_node *device,
return 0;
}
-
-/** Checks if the given "compat" string matches one of the strings in
- * the device's "compatible" property
- */
-int of_device_is_compatible(const struct device_node *device,
- const char *compat)
-{
- unsigned long flags;
- int res;
-
- raw_spin_lock_irqsave(&devtree_lock, flags);
- res = __of_device_is_compatible(device, compat);
- raw_spin_unlock_irqrestore(&devtree_lock, flags);
- return res;
-}
EXPORT_SYMBOL(of_device_is_compatible);
/**
@@ -307,19 +269,19 @@ int of_machine_is_compatible(const char *compat)
EXPORT_SYMBOL(of_machine_is_compatible);
/**
- * __of_device_is_available - check if a device is available for use
+ * of_device_is_available - check if a device is available for use
*
- * @device: Node to check for availability, with locks already held
+ * @device: Node to check for availability
*
* Returns 1 if the status property is absent or set to "okay" or "ok",
* 0 otherwise
*/
-static int __of_device_is_available(const struct device_node *device)
+int of_device_is_available(const struct device_node *device)
{
const char *status;
int statlen;
- status = __of_get_property(device, "status", &statlen);
+ status = of_get_property(device, "status", &statlen);
if (status == NULL)
return 1;
@@ -330,26 +292,6 @@ static int __of_device_is_available(const struct device_node *device)
return 0;
}
-
-/**
- * of_device_is_available - check if a device is available for use
- *
- * @device: Node to check for availability
- *
- * Returns 1 if the status property is absent or set to "okay" or "ok",
- * 0 otherwise
- */
-int of_device_is_available(const struct device_node *device)
-{
- unsigned long flags;
- int res;
-
- raw_spin_lock_irqsave(&devtree_lock, flags);
- res = __of_device_is_available(device);
- raw_spin_unlock_irqrestore(&devtree_lock, flags);
- return res;
-
-}
EXPORT_SYMBOL(of_device_is_available);
/**
@@ -362,14 +304,13 @@ EXPORT_SYMBOL(of_device_is_available);
struct device_node *of_get_parent(const struct device_node *node)
{
struct device_node *np;
- unsigned long flags;
if (!node)
return NULL;
- raw_spin_lock_irqsave(&devtree_lock, flags);
+ read_lock(&devtree_lock);
np = of_node_get(node->parent);
- raw_spin_unlock_irqrestore(&devtree_lock, flags);
+ read_unlock(&devtree_lock);
return np;
}
EXPORT_SYMBOL(of_get_parent);
@@ -388,15 +329,14 @@ EXPORT_SYMBOL(of_get_parent);
struct device_node *of_get_next_parent(struct device_node *node)
{
struct device_node *parent;
- unsigned long flags;
if (!node)
return NULL;
- raw_spin_lock_irqsave(&devtree_lock, flags);
+ read_lock(&devtree_lock);
parent = of_node_get(node->parent);
of_node_put(node);
- raw_spin_unlock_irqrestore(&devtree_lock, flags);
+ read_unlock(&devtree_lock);
return parent;
}
@@ -412,15 +352,14 @@ struct device_node *of_get_next_child(const struct device_node *node,
struct device_node *prev)
{
struct device_node *next;
- unsigned long flags;
- raw_spin_lock_irqsave(&devtree_lock, flags);
+ read_lock(&devtree_lock);
next = prev ? prev->sibling : node->child;
for (; next; next = next->sibling)
if (of_node_get(next))
break;
of_node_put(prev);
- raw_spin_unlock_irqrestore(&devtree_lock, flags);
+ read_unlock(&devtree_lock);
return next;
}
EXPORT_SYMBOL(of_get_next_child);
@@ -438,16 +377,16 @@ struct device_node *of_get_next_available_child(const struct device_node *node,
{
struct device_node *next;
- raw_spin_lock(&devtree_lock);
+ read_lock(&devtree_lock);
next = prev ? prev->sibling : node->child;
for (; next; next = next->sibling) {
- if (!__of_device_is_available(next))
+ if (!of_device_is_available(next))
continue;
if (of_node_get(next))
break;
}
of_node_put(prev);
- raw_spin_unlock(&devtree_lock);
+ read_unlock(&devtree_lock);
return next;
}
EXPORT_SYMBOL(of_get_next_available_child);
@@ -485,15 +424,14 @@ EXPORT_SYMBOL(of_get_child_by_name);
struct device_node *of_find_node_by_path(const char *path)
{
struct device_node *np = of_allnodes;
- unsigned long flags;
- raw_spin_lock_irqsave(&devtree_lock, flags);
+ read_lock(&devtree_lock);
for (; np; np = np->allnext) {
if (np->full_name && (of_node_cmp(np->full_name, path) == 0)
&& of_node_get(np))
break;
}
- raw_spin_unlock_irqrestore(&devtree_lock, flags);
+ read_unlock(&devtree_lock);
return np;
}
EXPORT_SYMBOL(of_find_node_by_path);
@@ -513,16 +451,15 @@ struct device_node *of_find_node_by_name(struct device_node *from,
const char *name)
{
struct device_node *np;
- unsigned long flags;
- raw_spin_lock_irqsave(&devtree_lock, flags);
+ read_lock(&devtree_lock);
np = from ? from->allnext : of_allnodes;
for (; np; np = np->allnext)
if (np->name && (of_node_cmp(np->name, name) == 0)
&& of_node_get(np))
break;
of_node_put(from);
- raw_spin_unlock_irqrestore(&devtree_lock, flags);
+ read_unlock(&devtree_lock);
return np;
}
EXPORT_SYMBOL(of_find_node_by_name);
@@ -543,16 +480,15 @@ struct device_node *of_find_node_by_type(struct device_node *from,
const char *type)
{
struct device_node *np;
- unsigned long flags;
- raw_spin_lock_irqsave(&devtree_lock, flags);
+ read_lock(&devtree_lock);
np = from ? from->allnext : of_allnodes;
for (; np; np = np->allnext)
if (np->type && (of_node_cmp(np->type, type) == 0)
&& of_node_get(np))
break;
of_node_put(from);
- raw_spin_unlock_irqrestore(&devtree_lock, flags);
+ read_unlock(&devtree_lock);
return np;
}
EXPORT_SYMBOL(of_find_node_by_type);
@@ -575,20 +511,18 @@ struct device_node *of_find_compatible_node(struct device_node *from,
const char *type, const char *compatible)
{
struct device_node *np;
- unsigned long flags;
- raw_spin_lock_irqsave(&devtree_lock, flags);
+ read_lock(&devtree_lock);
np = from ? from->allnext : of_allnodes;
for (; np; np = np->allnext) {
if (type
&& !(np->type && (of_node_cmp(np->type, type) == 0)))
continue;
- if (__of_device_is_compatible(np, compatible) &&
- of_node_get(np))
+ if (of_device_is_compatible(np, compatible) && of_node_get(np))
break;
}
of_node_put(from);
- raw_spin_unlock_irqrestore(&devtree_lock, flags);
+ read_unlock(&devtree_lock);
return np;
}
EXPORT_SYMBOL(of_find_compatible_node);
@@ -610,9 +544,8 @@ struct device_node *of_find_node_with_property(struct device_node *from,
{
struct device_node *np;
struct property *pp;
- unsigned long flags;
- raw_spin_lock_irqsave(&devtree_lock, flags);
+ read_lock(&devtree_lock);
np = from ? from->allnext : of_allnodes;
for (; np; np = np->allnext) {
for (pp = np->properties; pp; pp = pp->next) {
@@ -624,14 +557,20 @@ struct device_node *of_find_node_with_property(struct device_node *from,
}
out:
of_node_put(from);
- raw_spin_unlock_irqrestore(&devtree_lock, flags);
+ read_unlock(&devtree_lock);
return np;
}
EXPORT_SYMBOL(of_find_node_with_property);
-static
-const struct of_device_id *__of_match_node(const struct of_device_id *matches,
- const struct device_node *node)
+/**
+ * of_match_node - Tell if an device_node has a matching of_match structure
+ * @matches: array of of device match structures to search in
+ * @node: the of device structure to match against
+ *
+ * Low level utility function used by device matching.
+ */
+const struct of_device_id *of_match_node(const struct of_device_id *matches,
+ const struct device_node *node)
{
if (!matches)
return NULL;
@@ -645,33 +584,14 @@ const struct of_device_id *__of_match_node(const struct of_device_id *matches,
match &= node->type
&& !strcmp(matches->type, node->type);
if (matches->compatible[0])
- match &= __of_device_is_compatible(node,
- matches->compatible);
+ match &= of_device_is_compatible(node,
+ matches->compatible);
if (match)
return matches;
matches++;
}
return NULL;
}
-
-/**
- * of_match_node - Tell if an device_node has a matching of_match structure
- * @matches: array of of device match structures to search in
- * @node: the of device structure to match against
- *
- * Low level utility function used by device matching.
- */
-const struct of_device_id *of_match_node(const struct of_device_id *matches,
- const struct device_node *node)
-{
- const struct of_device_id *match;
- unsigned long flags;
-
- raw_spin_lock_irqsave(&devtree_lock, flags);
- match = __of_match_node(matches, node);
- raw_spin_unlock_irqrestore(&devtree_lock, flags);
- return match;
-}
EXPORT_SYMBOL(of_match_node);
/**
@@ -692,22 +612,21 @@ struct device_node *of_find_matching_node_and_match(struct device_node *from,
const struct of_device_id **match)
{
struct device_node *np;
- unsigned long flags;
if (match)
*match = NULL;
- raw_spin_lock_irqsave(&devtree_lock, flags);
+ read_lock(&devtree_lock);
np = from ? from->allnext : of_allnodes;
for (; np; np = np->allnext) {
- if (__of_match_node(matches, np) && of_node_get(np)) {
+ if (of_match_node(matches, np) && of_node_get(np)) {
if (match)
*match = matches;
break;
}
}
of_node_put(from);
- raw_spin_unlock_irqrestore(&devtree_lock, flags);
+ read_unlock(&devtree_lock);
return np;
}
EXPORT_SYMBOL(of_find_matching_node_and_match);
@@ -750,12 +669,12 @@ struct device_node *of_find_node_by_phandle(phandle handle)
{
struct device_node *np;
- raw_spin_lock(&devtree_lock);
+ read_lock(&devtree_lock);
for (np = of_allnodes; np; np = np->allnext)
if (np->phandle == handle)
break;
of_node_get(np);
- raw_spin_unlock(&devtree_lock);
+ read_unlock(&devtree_lock);
return np;
}
EXPORT_SYMBOL(of_find_node_by_phandle);
@@ -1227,18 +1146,18 @@ int of_add_property(struct device_node *np, struct property *prop)
return rc;
prop->next = NULL;
- raw_spin_lock_irqsave(&devtree_lock, flags);
+ write_lock_irqsave(&devtree_lock, flags);
next = &np->properties;
while (*next) {
if (strcmp(prop->name, (*next)->name) == 0) {
/* duplicate ! don't insert it */
- raw_spin_unlock_irqrestore(&devtree_lock, flags);
+ write_unlock_irqrestore(&devtree_lock, flags);
return -1;
}
next = &(*next)->next;
}
*next = prop;
- raw_spin_unlock_irqrestore(&devtree_lock, flags);
+ write_unlock_irqrestore(&devtree_lock, flags);
#ifdef CONFIG_PROC_DEVICETREE
/* try to add to proc as well if it was initialized */
@@ -1268,7 +1187,7 @@ int of_remove_property(struct device_node *np, struct property *prop)
if (rc)
return rc;
- raw_spin_lock_irqsave(&devtree_lock, flags);
+ write_lock_irqsave(&devtree_lock, flags);
next = &np->properties;
while (*next) {
if (*next == prop) {
@@ -1281,7 +1200,7 @@ int of_remove_property(struct device_node *np, struct property *prop)
}
next = &(*next)->next;
}
- raw_spin_unlock_irqrestore(&devtree_lock, flags);
+ write_unlock_irqrestore(&devtree_lock, flags);
if (!found)
return -ENODEV;
@@ -1321,7 +1240,7 @@ int of_update_property(struct device_node *np, struct property *newprop)
if (!oldprop)
return of_add_property(np, newprop);
- raw_spin_lock_irqsave(&devtree_lock, flags);
+ write_lock_irqsave(&devtree_lock, flags);
next = &np->properties;
while (*next) {
if (*next == oldprop) {
@@ -1335,7 +1254,7 @@ int of_update_property(struct device_node *np, struct property *newprop)
}
next = &(*next)->next;
}
- raw_spin_unlock_irqrestore(&devtree_lock, flags);
+ write_unlock_irqrestore(&devtree_lock, flags);
if (!found)
return -ENODEV;
@@ -1408,12 +1327,12 @@ int of_attach_node(struct device_node *np)
if (rc)
return rc;
- raw_spin_lock_irqsave(&devtree_lock, flags);
+ write_lock_irqsave(&devtree_lock, flags);
np->sibling = np->parent->child;
np->allnext = of_allnodes;
np->parent->child = np;
of_allnodes = np;
- raw_spin_unlock_irqrestore(&devtree_lock, flags);
+ write_unlock_irqrestore(&devtree_lock, flags);
of_add_proc_dt_entry(np);
return 0;
@@ -1456,17 +1375,17 @@ int of_detach_node(struct device_node *np)
if (rc)
return rc;
- raw_spin_lock_irqsave(&devtree_lock, flags);
+ write_lock_irqsave(&devtree_lock, flags);
if (of_node_check_flag(np, OF_DETACHED)) {
/* someone already detached it */
- raw_spin_unlock_irqrestore(&devtree_lock, flags);
+ write_unlock_irqrestore(&devtree_lock, flags);
return rc;
}
parent = np->parent;
if (!parent) {
- raw_spin_unlock_irqrestore(&devtree_lock, flags);
+ write_unlock_irqrestore(&devtree_lock, flags);
return rc;
}
@@ -1493,7 +1412,7 @@ int of_detach_node(struct device_node *np)
}
of_node_set_flag(np, OF_DETACHED);
- raw_spin_unlock_irqrestore(&devtree_lock, flags);
+ write_unlock_irqrestore(&devtree_lock, flags);
of_remove_proc_dt_entry(np);
return rc;
diff --git a/drivers/pci/access.c b/drivers/pci/access.c
index 0941838..3af0478 100644
--- a/drivers/pci/access.c
+++ b/drivers/pci/access.c
@@ -465,7 +465,7 @@ void pci_cfg_access_unlock(struct pci_dev *dev)
WARN_ON(!dev->block_cfg_access);
dev->block_cfg_access = 0;
- wake_up_all_locked(&pci_cfg_wait);
+ wake_up_all(&pci_cfg_wait);
raw_spin_unlock_irqrestore(&pci_lock, flags);
}
EXPORT_SYMBOL_GPL(pci_cfg_access_unlock);
@@ -515,7 +515,7 @@ static bool pcie_capability_reg_implemented(struct pci_dev *dev, int pos)
return false;
switch (pos) {
- case PCI_EXP_FLAGS:
+ case PCI_EXP_FLAGS_TYPE:
return true;
case PCI_EXP_DEVCAP:
case PCI_EXP_DEVCTL:
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
index 21354bf..1af4008 100644
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -53,15 +53,14 @@ static void pci_acpi_wake_dev(acpi_handle handle, u32 event, void *context)
return;
}
- /* Clear PME Status if set. */
- if (pci_dev->pme_support)
- pci_check_pme_status(pci_dev);
+ if (!pci_dev->pm_cap || !pci_dev->pme_support
+ || pci_check_pme_status(pci_dev)) {
+ if (pci_dev->pme_poll)
+ pci_dev->pme_poll = false;
- if (pci_dev->pme_poll)
- pci_dev->pme_poll = false;
-
- pci_wakeup_event(pci_dev);
- pm_runtime_resume(&pci_dev->dev);
+ pci_wakeup_event(pci_dev);
+ pm_runtime_resume(&pci_dev->dev);
+ }
if (pci_dev->subordinate)
pci_pme_wakeup_bus(pci_dev->subordinate);
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index 8c1ecc5..f79cbcd 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -628,7 +628,6 @@ static int pci_pm_suspend(struct device *dev)
goto Fixup;
}
- pci_dev->state_saved = false;
if (pm->suspend) {
pci_power_t prev = pci_dev->current_state;
int error;
@@ -775,7 +774,6 @@ static int pci_pm_freeze(struct device *dev)
return 0;
}
- pci_dev->state_saved = false;
if (pm->freeze) {
int error;
@@ -864,7 +862,6 @@ static int pci_pm_poweroff(struct device *dev)
goto Fixup;
}
- pci_dev->state_saved = false;
if (pm->poweroff) {
int error;
@@ -990,7 +987,6 @@ static int pci_pm_runtime_suspend(struct device *dev)
if (!pm || !pm->runtime_suspend)
return -ENOSYS;
- pci_dev->state_saved = false;
pci_dev->no_d3cold = false;
error = pm->runtime_suspend(dev);
suspend_report_result(pm->runtime_suspend, error);
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index d1b4e00..5cb5820 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -651,11 +651,15 @@ static int pci_platform_power_transition(struct pci_dev *dev, pci_power_t state)
error = platform_pci_set_power_state(dev, state);
if (!error)
pci_update_current_state(dev, state);
- } else
+ /* Fall back to PCI_D0 if native PM is not supported */
+ if (!dev->pm_cap)
+ dev->current_state = PCI_D0;
+ } else {
error = -ENODEV;
-
- if (error && !dev->pm_cap) /* Fall back to PCI_D0 */
- dev->current_state = PCI_D0;
+ /* Fall back to PCI_D0 if native PM is not supported */
+ if (!dev->pm_cap)
+ dev->current_state = PCI_D0;
+ }
return error;
}
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c
index ed4d094..08c243a 100644
--- a/drivers/pci/pcie/portdrv_pci.c
+++ b/drivers/pci/pcie/portdrv_pci.c
@@ -185,6 +185,14 @@ static const struct dev_pm_ops pcie_portdrv_pm_ops = {
#endif /* !PM */
/*
+ * PCIe port runtime suspend is broken for some chipsets, so use a
+ * black list to disable runtime PM for these chipsets.
+ */
+static const struct pci_device_id port_runtime_pm_black_list[] = {
+ { /* end: all zeroes */ }
+};
+
+/*
* pcie_portdrv_probe - Probe PCI-Express port devices
* @dev: PCI-Express port device being probed
*
@@ -217,11 +225,16 @@ static int pcie_portdrv_probe(struct pci_dev *dev,
* it by default.
*/
dev->d3cold_allowed = false;
+ if (!pci_match_id(port_runtime_pm_black_list, dev))
+ pm_runtime_put_noidle(&dev->dev);
+
return 0;
}
static void pcie_portdrv_remove(struct pci_dev *dev)
{
+ if (!pci_match_id(port_runtime_pm_black_list, dev))
+ pm_runtime_get_noresume(&dev->dev);
pcie_port_device_remove(dev);
pci_disable_device(dev);
}
diff --git a/drivers/pcmcia/vrc4171_card.c b/drivers/pcmcia/vrc4171_card.c
index d98a086..75806be 100644
--- a/drivers/pcmcia/vrc4171_card.c
+++ b/drivers/pcmcia/vrc4171_card.c
@@ -246,7 +246,6 @@ static int pccard_init(struct pcmcia_socket *sock)
socket = &vrc4171_sockets[slot];
socket->csc_irq = search_nonuse_irq();
socket->io_irq = search_nonuse_irq();
- spin_lock_init(&socket->lock);
return 0;
}
diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c
index 684ce75..afed701 100644
--- a/drivers/platform/x86/acer-wmi.c
+++ b/drivers/platform/x86/acer-wmi.c
@@ -1204,9 +1204,6 @@ static acpi_status WMID_set_capabilities(void)
devices = *((u32 *) obj->buffer.pointer);
} else if (obj->type == ACPI_TYPE_INTEGER) {
devices = (u32) obj->integer.value;
- } else {
- kfree(out.pointer);
- return AE_ERROR;
}
} else {
kfree(out.pointer);
diff --git a/drivers/platform/x86/msi-wmi.c b/drivers/platform/x86/msi-wmi.c
index b96766b..2264331 100644
--- a/drivers/platform/x86/msi-wmi.c
+++ b/drivers/platform/x86/msi-wmi.c
@@ -176,7 +176,7 @@ static void msi_wmi_notify(u32 value, void *context)
pr_debug("Suppressed key event 0x%X - "
"Last press was %lld us ago\n",
key->code, ktime_to_us(diff));
- goto msi_wmi_notify_exit;
+ return;
}
last_pressed[key->code - SCANCODE_BASE] = cur;
@@ -195,8 +195,6 @@ static void msi_wmi_notify(u32 value, void *context)
pr_info("Unknown key pressed - %x\n", eventcode);
} else
pr_info("Unknown event received\n");
-
-msi_wmi_notify_exit:
kfree(response.pointer);
}
diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c
index 0fe987f..b8ad71f 100644
--- a/drivers/platform/x86/sony-laptop.c
+++ b/drivers/platform/x86/sony-laptop.c
@@ -1534,7 +1534,7 @@ static int sony_nc_rfkill_set(void *data, bool blocked)
int argument = sony_rfkill_address[(long) data] + 0x100;
if (!blocked)
- argument |= 0x070000;
+ argument |= 0x030000;
return sony_call_snc_handle(sony_rfkill_handle, argument, &result);
}
diff --git a/drivers/power/ab8500_btemp.c b/drivers/power/ab8500_btemp.c
index 056222e..20e2a7d 100644
--- a/drivers/power/ab8500_btemp.c
+++ b/drivers/power/ab8500_btemp.c
@@ -1123,7 +1123,7 @@ static void __exit ab8500_btemp_exit(void)
platform_driver_unregister(&ab8500_btemp_driver);
}
-device_initcall(ab8500_btemp_init);
+subsys_initcall_sync(ab8500_btemp_init);
module_exit(ab8500_btemp_exit);
MODULE_LICENSE("GPL v2");
diff --git a/drivers/power/abx500_chargalg.c b/drivers/power/abx500_chargalg.c
index eb7b4a6..2970891 100644
--- a/drivers/power/abx500_chargalg.c
+++ b/drivers/power/abx500_chargalg.c
@@ -1698,7 +1698,7 @@ static ssize_t abx500_chargalg_sysfs_charger(struct kobject *kobj,
static struct attribute abx500_chargalg_en_charger = \
{
.name = "chargalg",
- .mode = S_IWUSR,
+ .mode = S_IWUGO,
};
static struct attribute *abx500_chargalg_chg[] = {
diff --git a/drivers/power/bq27x00_battery.c b/drivers/power/bq27x00_battery.c
index 7087d0d..36b34ef 100644
--- a/drivers/power/bq27x00_battery.c
+++ b/drivers/power/bq27x00_battery.c
@@ -448,6 +448,7 @@ static void bq27x00_update(struct bq27x00_device_info *di)
cache.temperature = bq27x00_battery_read_temperature(di);
if (!is_bq27425)
cache.cycle_count = bq27x00_battery_read_cyct(di);
+ cache.cycle_count = bq27x00_battery_read_cyct(di);
cache.power_avg =
bq27x00_battery_read_pwr_avg(di, BQ27x00_POWER_AVG);
@@ -695,6 +696,7 @@ static int bq27x00_powersupply_init(struct bq27x00_device_info *di)
int ret;
di->bat.type = POWER_SUPPLY_TYPE_BATTERY;
+ di->chip = BQ27425;
if (di->chip == BQ27425) {
di->bat.properties = bq27425_battery_props;
di->bat.num_properties = ARRAY_SIZE(bq27425_battery_props);
diff --git a/drivers/pps/clients/pps-ldisc.c b/drivers/pps/clients/pps-ldisc.c
index 60cee9e..79451f2 100644
--- a/drivers/pps/clients/pps-ldisc.c
+++ b/drivers/pps/clients/pps-ldisc.c
@@ -31,7 +31,7 @@
static void pps_tty_dcd_change(struct tty_struct *tty, unsigned int status,
struct pps_event_time *ts)
{
- struct pps_device *pps = pps_lookup_dev(tty);
+ struct pps_device *pps = (struct pps_device *)tty->disc_data;
BUG_ON(pps == NULL);
@@ -67,9 +67,9 @@ static int pps_tty_open(struct tty_struct *tty)
pr_err("cannot register PPS source \"%s\"\n", info.path);
return -ENOMEM;
}
- pps->lookup_cookie = tty;
+ tty->disc_data = pps;
- /* Now open the base class N_TTY ldisc */
+ /* Should open N_TTY ldisc too */
ret = alias_n_tty_open(tty);
if (ret < 0) {
pr_err("cannot open tty ldisc \"%s\"\n", info.path);
@@ -81,6 +81,7 @@ static int pps_tty_open(struct tty_struct *tty)
return 0;
err_unregister:
+ tty->disc_data = NULL;
pps_unregister_source(pps);
return ret;
}
@@ -89,10 +90,11 @@ static void (*alias_n_tty_close)(struct tty_struct *tty);
static void pps_tty_close(struct tty_struct *tty)
{
- struct pps_device *pps = pps_lookup_dev(tty);
+ struct pps_device *pps = (struct pps_device *)tty->disc_data;
alias_n_tty_close(tty);
+ tty->disc_data = NULL;
dev_info(pps->dev, "removed\n");
pps_unregister_source(pps);
}
diff --git a/drivers/pps/pps.c b/drivers/pps/pps.c
index 6437703..2420d5a 100644
--- a/drivers/pps/pps.c
+++ b/drivers/pps/pps.c
@@ -247,15 +247,12 @@ static int pps_cdev_open(struct inode *inode, struct file *file)
struct pps_device *pps = container_of(inode->i_cdev,
struct pps_device, cdev);
file->private_data = pps;
- kobject_get(&pps->dev->kobj);
+
return 0;
}
static int pps_cdev_release(struct inode *inode, struct file *file)
{
- struct pps_device *pps = container_of(inode->i_cdev,
- struct pps_device, cdev);
- kobject_put(&pps->dev->kobj);
return 0;
}
@@ -277,10 +274,8 @@ static void pps_device_destruct(struct device *dev)
{
struct pps_device *pps = dev_get_drvdata(dev);
- cdev_del(&pps->cdev);
-
- /* Now we can release the ID for re-use */
- pr_debug("deallocating pps%d\n", pps->id);
+ /* release id here to protect others from using it while it's
+ * still in use */
mutex_lock(&pps_idr_lock);
idr_remove(&pps_idr, pps->id);
mutex_unlock(&pps_idr_lock);
@@ -337,7 +332,6 @@ int pps_register_cdev(struct pps_device *pps)
goto del_cdev;
}
- /* Override the release function with our own */
pps->dev->release = pps_device_destruct;
pr_debug("source %s got cdev (%d:%d)\n", pps->info.name,
@@ -358,44 +352,11 @@ free_idr:
void pps_unregister_cdev(struct pps_device *pps)
{
- pr_debug("unregistering pps%d\n", pps->id);
- pps->lookup_cookie = NULL;
device_destroy(pps_class, pps->dev->devt);
+ cdev_del(&pps->cdev);
}
/*
- * Look up a pps device by magic cookie.
- * The cookie is usually a pointer to some enclosing device, but this
- * code doesn't care; you should never be dereferencing it.
- *
- * This is a bit of a kludge that is currently used only by the PPS
- * serial line discipline. It may need to be tweaked when a second user
- * is found.
- *
- * There is no function interface for setting the lookup_cookie field.
- * It's initialized to NULL when the pps device is created, and if a
- * client wants to use it, just fill it in afterward.
- *
- * The cookie is automatically set to NULL in pps_unregister_source()
- * so that it will not be used again, even if the pps device cannot
- * be removed from the idr due to pending references holding the minor
- * number in use.
- */
-struct pps_device *pps_lookup_dev(void const *cookie)
-{
- struct pps_device *pps;
- unsigned id;
-
- rcu_read_lock();
- idr_for_each_entry(&pps_idr, pps, id)
- if (cookie == pps->lookup_cookie)
- break;
- rcu_read_unlock();
- return pps;
-}
-EXPORT_SYMBOL(pps_lookup_dev);
-
-/*
* Module stuff
*/
diff --git a/drivers/pwm/pwm-spear.c b/drivers/pwm/pwm-spear.c
index 0c644e7..83b21d9 100644
--- a/drivers/pwm/pwm-spear.c
+++ b/drivers/pwm/pwm-spear.c
@@ -143,7 +143,7 @@ static int spear_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
u32 val;
rc = clk_enable(pc->clk);
- if (rc)
+ if (!rc)
return rc;
val = spear_pwm_readl(pc, pwm->hwpwm, PWMCR);
@@ -209,12 +209,12 @@ static int spear_pwm_probe(struct platform_device *pdev)
pc->chip.npwm = NUM_PWM;
ret = clk_prepare(pc->clk);
- if (ret)
+ if (!ret)
return ret;
if (of_device_is_compatible(np, "st,spear1340-pwm")) {
ret = clk_enable(pc->clk);
- if (ret) {
+ if (!ret) {
clk_unprepare(pc->clk);
return ret;
}
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 5a0f54a..2785843 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -200,8 +200,8 @@ static int regulator_check_consumers(struct regulator_dev *rdev,
}
if (*min_uV > *max_uV) {
- rdev_err(rdev, "Restricting voltage, %u-%uuV\n",
- *min_uV, *max_uV);
+ dev_err(regulator->dev, "Restricting voltage, %u-%uuV\n",
+ regulator->min_uV, regulator->max_uV);
return -EINVAL;
}
diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
index a936efb..96ce101 100644
--- a/drivers/remoteproc/Kconfig
+++ b/drivers/remoteproc/Kconfig
@@ -5,7 +5,7 @@ config REMOTEPROC
tristate
depends on EXPERIMENTAL
depends on HAS_DMA
- select FW_LOADER
+ select FW_CONFIG
select VIRTIO
config OMAP_REMOTEPROC
diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c
index 752b507..dd3bfaf 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -370,12 +370,10 @@ static int rproc_handle_vdev(struct rproc *rproc, struct fw_rsc_vdev *rsc,
/* it is now safe to add the virtio device */
ret = rproc_add_virtio_dev(rvdev, rsc->id);
if (ret)
- goto remove_rvdev;
+ goto free_rvdev;
return 0;
-remove_rvdev:
- list_del(&rvdev->node);
free_rvdev:
kfree(rvdev);
return ret;
diff --git a/drivers/remoteproc/ste_modem_rproc.c b/drivers/remoteproc/ste_modem_rproc.c
index fb95c42..a7743c0 100644
--- a/drivers/remoteproc/ste_modem_rproc.c
+++ b/drivers/remoteproc/ste_modem_rproc.c
@@ -240,8 +240,6 @@ static int sproc_drv_remove(struct platform_device *pdev)
/* Unregister as remoteproc device */
rproc_del(sproc->rproc);
- dma_free_coherent(sproc->rproc->dev.parent, SPROC_FW_SIZE,
- sproc->fw_addr, sproc->fw_dma_addr);
rproc_put(sproc->rproc);
mdev->drv_data = NULL;
@@ -299,13 +297,10 @@ static int sproc_probe(struct platform_device *pdev)
/* Register as a remoteproc device */
err = rproc_add(rproc);
if (err)
- goto free_mem;
+ goto free_rproc;
return 0;
-free_mem:
- dma_free_coherent(rproc->dev.parent, SPROC_FW_SIZE,
- sproc->fw_addr, sproc->fw_dma_addr);
free_rproc:
/* Reset device data upon error */
mdev->drv_data = NULL;
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c
index 1c77423..16630aa 100644
--- a/drivers/rtc/rtc-cmos.c
+++ b/drivers/rtc/rtc-cmos.c
@@ -805,8 +805,9 @@ static int cmos_suspend(struct device *dev)
mask = RTC_IRQMASK;
tmp &= ~mask;
CMOS_WRITE(tmp, RTC_CONTROL);
- hpet_mask_rtc_irq_bit(mask);
+ /* shut down hpet emulation - we don't need it for alarm */
+ hpet_mask_rtc_irq_bit(RTC_PIE|RTC_AIE|RTC_UIE);
cmos_checkintr(cmos, tmp);
}
spin_unlock_irq(&rtc_lock);
@@ -871,7 +872,6 @@ static int cmos_resume(struct device *dev)
rtc_update_irq(cmos->rtc, 1, mask);
tmp &= ~RTC_AIE;
hpet_mask_rtc_irq_bit(RTC_AIE);
- hpet_rtc_timer_init();
} while (mask & RTC_AIE);
spin_unlock_irq(&rtc_lock);
}
diff --git a/drivers/rtc/rtc-mv.c b/drivers/rtc/rtc-mv.c
index 8f87fec..57233c8 100644
--- a/drivers/rtc/rtc-mv.c
+++ b/drivers/rtc/rtc-mv.c
@@ -14,7 +14,6 @@
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/delay.h>
-#include <linux/clk.h>
#include <linux/gfp.h>
#include <linux/module.h>
@@ -42,7 +41,6 @@ struct rtc_plat_data {
struct rtc_device *rtc;
void __iomem *ioaddr;
int irq;
- struct clk *clk;
};
static int mv_rtc_set_time(struct device *dev, struct rtc_time *tm)
@@ -223,7 +221,6 @@ static int mv_rtc_probe(struct platform_device *pdev)
struct rtc_plat_data *pdata;
resource_size_t size;
u32 rtc_time;
- int ret = 0;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res)
@@ -242,17 +239,11 @@ static int mv_rtc_probe(struct platform_device *pdev)
if (!pdata->ioaddr)
return -ENOMEM;
- pdata->clk = devm_clk_get(&pdev->dev, NULL);
- /* Not all SoCs require a clock.*/
- if (!IS_ERR(pdata->clk))
- clk_prepare_enable(pdata->clk);
-
/* make sure the 24 hours mode is enabled */
rtc_time = readl(pdata->ioaddr + RTC_TIME_REG_OFFS);
if (rtc_time & RTC_HOURS_12H_MODE) {
dev_err(&pdev->dev, "24 Hours mode not supported.\n");
- ret = -EINVAL;
- goto out;
+ return -EINVAL;
}
/* make sure it is actually functional */
@@ -261,8 +252,7 @@ static int mv_rtc_probe(struct platform_device *pdev)
rtc_time = readl(pdata->ioaddr + RTC_TIME_REG_OFFS);
if (rtc_time == 0x01000000) {
dev_err(&pdev->dev, "internal RTC not ticking\n");
- ret = -ENODEV;
- goto out;
+ return -ENODEV;
}
}
@@ -278,10 +268,8 @@ static int mv_rtc_probe(struct platform_device *pdev)
} else
pdata->rtc = rtc_device_register(pdev->name, &pdev->dev,
&mv_rtc_ops, THIS_MODULE);
- if (IS_ERR(pdata->rtc)) {
- ret = PTR_ERR(pdata->rtc);
- goto out;
- }
+ if (IS_ERR(pdata->rtc))
+ return PTR_ERR(pdata->rtc);
if (pdata->irq >= 0) {
writel(0, pdata->ioaddr + RTC_ALARM_INTERRUPT_MASK_REG_OFFS);
@@ -294,11 +282,6 @@ static int mv_rtc_probe(struct platform_device *pdev)
}
return 0;
-out:
- if (!IS_ERR(pdata->clk))
- clk_disable_unprepare(pdata->clk);
-
- return ret;
}
static int __exit mv_rtc_remove(struct platform_device *pdev)
@@ -309,9 +292,6 @@ static int __exit mv_rtc_remove(struct platform_device *pdev)
device_init_wakeup(&pdev->dev, 0);
rtc_device_unregister(pdata->rtc);
- if (!IS_ERR(pdata->clk))
- clk_disable_unprepare(pdata->clk);
-
return 0;
}
diff --git a/drivers/s390/char/sclp_cmd.c b/drivers/s390/char/sclp_cmd.c
index 56dcd7c..c44d13f 100644
--- a/drivers/s390/char/sclp_cmd.c
+++ b/drivers/s390/char/sclp_cmd.c
@@ -567,8 +567,6 @@ static void __init sclp_add_standby_memory(void)
add_memory_merged(0);
}
-#define MEM_SCT_SIZE (1UL << SECTION_SIZE_BITS)
-
static void __init insert_increment(u16 rn, int standby, int assigned)
{
struct memory_increment *incr, *new_incr;
@@ -581,7 +579,7 @@ static void __init insert_increment(u16 rn, int standby, int assigned)
new_incr->rn = rn;
new_incr->standby = standby;
if (!standby)
- new_incr->usecount = rzm > MEM_SCT_SIZE ? rzm/MEM_SCT_SIZE : 1;
+ new_incr->usecount = 1;
last_rn = 0;
prev = &sclp_mem_list;
list_for_each_entry(incr, &sclp_mem_list, list) {
diff --git a/drivers/s390/kvm/kvm_virtio.c b/drivers/s390/kvm/kvm_virtio.c
index 03a15e0..8491111 100644
--- a/drivers/s390/kvm/kvm_virtio.c
+++ b/drivers/s390/kvm/kvm_virtio.c
@@ -422,26 +422,6 @@ static void kvm_extint_handler(struct ext_code ext_code,
}
/*
- * For s390-virtio, we expect a page above main storage containing
- * the virtio configuration. Try to actually load from this area
- * in order to figure out if the host provides this page.
- */
-static int __init test_devices_support(unsigned long addr)
-{
- int ret = -EIO;
-
- asm volatile(
- "0: lura 0,%1\n"
- "1: xgr %0,%0\n"
- "2:\n"
- EX_TABLE(0b,2b)
- EX_TABLE(1b,2b)
- : "+d" (ret)
- : "a" (addr)
- : "0", "cc");
- return ret;
-}
-/*
* Init function for virtio
* devices are in a single page above top of "normal" mem
*/
@@ -452,23 +432,21 @@ static int __init kvm_devices_init(void)
if (!MACHINE_IS_KVM)
return -ENODEV;
- if (test_devices_support(real_memory_size) < 0)
- return -ENODEV;
-
- rc = vmem_add_mapping(real_memory_size, PAGE_SIZE);
- if (rc)
- return rc;
-
- kvm_devices = (void *) real_memory_size;
-
kvm_root = root_device_register("kvm_s390");
if (IS_ERR(kvm_root)) {
rc = PTR_ERR(kvm_root);
printk(KERN_ERR "Could not register kvm_s390 root device");
- vmem_remove_mapping(real_memory_size, PAGE_SIZE);
return rc;
}
+ rc = vmem_add_mapping(real_memory_size, PAGE_SIZE);
+ if (rc) {
+ root_device_unregister(kvm_root);
+ return rc;
+ }
+
+ kvm_devices = (void *) real_memory_size;
+
INIT_WORK(&hotplug_work, hotplug_devices);
service_subclass_irq_register();
diff --git a/drivers/scsi/dc395x.c b/drivers/scsi/dc395x.c
index fed486bf..865c64f 100644
--- a/drivers/scsi/dc395x.c
+++ b/drivers/scsi/dc395x.c
@@ -3747,13 +3747,13 @@ static struct DeviceCtlBlk *device_alloc(struct AdapterCtlBlk *acb,
dcb->max_command = 1;
dcb->target_id = target;
dcb->target_lun = lun;
- dcb->dev_mode = eeprom->target[target].cfg0;
#ifndef DC395x_NO_DISCONNECT
dcb->identify_msg =
IDENTIFY(dcb->dev_mode & NTC_DO_DISCONNECT, lun);
#else
dcb->identify_msg = IDENTIFY(0, lun);
#endif
+ dcb->dev_mode = eeprom->target[target].cfg0;
dcb->inquiry7 = 0;
dcb->sync_mode = 0;
dcb->min_nego_period = clock_period[period_index];
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c
index 61c1d2a..666b7ac 100644
--- a/drivers/scsi/fcoe/fcoe.c
+++ b/drivers/scsi/fcoe/fcoe.c
@@ -1272,7 +1272,7 @@ static void fcoe_percpu_thread_destroy(unsigned int cpu)
struct sk_buff *skb;
#ifdef CONFIG_SMP
struct fcoe_percpu_s *p0;
- unsigned targ_cpu = get_cpu_light();
+ unsigned targ_cpu = get_cpu();
#endif /* CONFIG_SMP */
FCOE_DBG("Destroying receive thread for CPU %d\n", cpu);
@@ -1328,7 +1328,7 @@ static void fcoe_percpu_thread_destroy(unsigned int cpu)
kfree_skb(skb);
spin_unlock_bh(&p->fcoe_rx_list.lock);
}
- put_cpu_light();
+ put_cpu();
#else
/*
* This a non-SMP scenario where the singular Rx thread is
@@ -1546,11 +1546,11 @@ err2:
static int fcoe_alloc_paged_crc_eof(struct sk_buff *skb, int tlen)
{
struct fcoe_percpu_s *fps;
- int rc, cpu = get_cpu_light();
+ int rc;
- fps = &per_cpu(fcoe_percpu, cpu);
+ fps = &get_cpu_var(fcoe_percpu);
rc = fcoe_get_paged_crc_eof(skb, tlen, fps);
- put_cpu_light();
+ put_cpu_var(fcoe_percpu);
return rc;
}
@@ -1745,11 +1745,11 @@ static inline int fcoe_filter_frames(struct fc_lport *lport,
return 0;
}
- stats = per_cpu_ptr(lport->stats, get_cpu_light());
+ stats = per_cpu_ptr(lport->stats, get_cpu());
stats->InvalidCRCCount++;
if (stats->InvalidCRCCount < 5)
printk(KERN_WARNING "fcoe: dropping frame with CRC error\n");
- put_cpu_light();
+ put_cpu();
return -EINVAL;
}
@@ -1825,13 +1825,13 @@ static void fcoe_recv_frame(struct sk_buff *skb)
goto drop;
if (!fcoe_filter_frames(lport, fp)) {
- put_cpu_light();
+ put_cpu();
fc_exch_recv(lport, fp);
return;
}
drop:
stats->ErrorFrames++;
- put_cpu_light();
+ put_cpu();
kfree_skb(skb);
}
diff --git a/drivers/scsi/fcoe/fcoe_ctlr.c b/drivers/scsi/fcoe/fcoe_ctlr.c
index 69d36cc..4a909d7 100644
--- a/drivers/scsi/fcoe/fcoe_ctlr.c
+++ b/drivers/scsi/fcoe/fcoe_ctlr.c
@@ -792,7 +792,7 @@ static unsigned long fcoe_ctlr_age_fcfs(struct fcoe_ctlr *fip)
INIT_LIST_HEAD(&del_list);
- stats = per_cpu_ptr(fip->lp->stats, get_cpu_light());
+ stats = per_cpu_ptr(fip->lp->stats, get_cpu());
list_for_each_entry_safe(fcf, next, &fip->fcfs, list) {
deadline = fcf->time + fcf->fka_period + fcf->fka_period / 2;
@@ -828,7 +828,7 @@ static unsigned long fcoe_ctlr_age_fcfs(struct fcoe_ctlr *fip)
sel_time = fcf->time;
}
}
- put_cpu_light();
+ put_cpu();
list_for_each_entry_safe(fcf, next, &del_list, list) {
/* Removes fcf from current list */
diff --git a/drivers/scsi/libfc/fc_exch.c b/drivers/scsi/libfc/fc_exch.c
index 67ca13a..c772d8d 100644
--- a/drivers/scsi/libfc/fc_exch.c
+++ b/drivers/scsi/libfc/fc_exch.c
@@ -730,10 +730,10 @@ static struct fc_exch *fc_exch_em_alloc(struct fc_lport *lport,
}
memset(ep, 0, sizeof(*ep));
- cpu = get_cpu_light();
+ cpu = get_cpu();
pool = per_cpu_ptr(mp->pool, cpu);
spin_lock_bh(&pool->lock);
- put_cpu_light();
+ put_cpu();
/* peek cache of free slot */
if (pool->left != FC_XID_UNKNOWN) {
diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c
index 1924d8b..aec2e0d 100644
--- a/drivers/scsi/libsas/sas_expander.c
+++ b/drivers/scsi/libsas/sas_expander.c
@@ -235,17 +235,6 @@ static void sas_set_ex_phy(struct domain_device *dev, int phy_id, void *rsp)
linkrate = phy->linkrate;
memcpy(sas_addr, phy->attached_sas_addr, SAS_ADDR_SIZE);
- /* Handle vacant phy - rest of dr data is not valid so skip it */
- if (phy->phy_state == PHY_VACANT) {
- memset(phy->attached_sas_addr, 0, SAS_ADDR_SIZE);
- phy->attached_dev_type = NO_DEVICE;
- if (!test_bit(SAS_HA_ATA_EH_ACTIVE, &ha->state)) {
- phy->phy_id = phy_id;
- goto skip;
- } else
- goto out;
- }
-
phy->attached_dev_type = to_dev_type(dr);
if (test_bit(SAS_HA_ATA_EH_ACTIVE, &ha->state))
goto out;
@@ -283,7 +272,6 @@ static void sas_set_ex_phy(struct domain_device *dev, int phy_id, void *rsp)
phy->phy->maximum_linkrate = dr->pmax_linkrate;
phy->phy->negotiated_linkrate = phy->linkrate;
- skip:
if (new_phy)
if (sas_phy_add(phy->phy)) {
sas_phy_free(phy->phy);
diff --git a/drivers/scsi/qla2xxx/qla_inline.h b/drivers/scsi/qla2xxx/qla_inline.h
index 41192aa..c0462c0 100644
--- a/drivers/scsi/qla2xxx/qla_inline.h
+++ b/drivers/scsi/qla2xxx/qla_inline.h
@@ -36,12 +36,12 @@ qla2x00_poll(struct rsp_que *rsp)
{
unsigned long flags;
struct qla_hw_data *ha = rsp->hw;
- local_irq_save_nort(flags);
+ local_irq_save(flags);
if (IS_QLA82XX(ha))
qla82xx_poll(0, rsp);
else
ha->isp_ops->intr_handler(0, rsp);
- local_irq_restore_nort(flags);
+ local_irq_restore(flags);
}
static inline uint8_t *
diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 9f4e560..0144078 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -467,7 +467,6 @@ static struct scatterlist *create_bounce_buffer(struct scatterlist *sgl,
if (!bounce_sgl)
return NULL;
- sg_init_table(bounce_sgl, num_pages);
for (i = 0; i < num_pages; i++) {
page_buf = alloc_page(GFP_ATOMIC);
if (!page_buf)
diff --git a/drivers/spi/spi-mpc512x-psc.c b/drivers/spi/spi-mpc512x-psc.c
index 41e21bf..cb3a310 100644
--- a/drivers/spi/spi-mpc512x-psc.c
+++ b/drivers/spi/spi-mpc512x-psc.c
@@ -164,7 +164,7 @@ static int mpc512x_psc_spi_transfer_rxtx(struct spi_device *spi,
for (i = count; i > 0; i--) {
data = tx_buf ? *tx_buf++ : 0;
- if (len == EOFBYTE && t->cs_change)
+ if (len == EOFBYTE)
setbits32(&fifo->txcmd, MPC512x_PSC_FIFO_EOF);
out_8(&fifo->txdata_8, data);
len--;
diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c
index 56c4166..b610f52 100644
--- a/drivers/spi/spi-omap2-mcspi.c
+++ b/drivers/spi/spi-omap2-mcspi.c
@@ -285,12 +285,8 @@ static int mcspi_wait_for_reg_bit(void __iomem *reg, unsigned long bit)
timeout = jiffies + msecs_to_jiffies(1000);
while (!(__raw_readl(reg) & bit)) {
- if (time_after(jiffies, timeout)) {
- if (!(__raw_readl(reg) & bit))
- return -ETIMEDOUT;
- else
- return 0;
- }
+ if (time_after(jiffies, timeout))
+ return -1;
cpu_relax();
}
return 0;
diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 6796a25..ad93231 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -997,30 +997,25 @@ static irqreturn_t s3c64xx_spi_irq(int irq, void *data)
{
struct s3c64xx_spi_driver_data *sdd = data;
struct spi_master *spi = sdd->master;
- unsigned int val, clr = 0;
+ unsigned int val;
- val = readl(sdd->regs + S3C64XX_SPI_STATUS);
+ val = readl(sdd->regs + S3C64XX_SPI_PENDING_CLR);
- if (val & S3C64XX_SPI_ST_RX_OVERRUN_ERR) {
- clr = S3C64XX_SPI_PND_RX_OVERRUN_CLR;
+ val &= S3C64XX_SPI_PND_RX_OVERRUN_CLR |
+ S3C64XX_SPI_PND_RX_UNDERRUN_CLR |
+ S3C64XX_SPI_PND_TX_OVERRUN_CLR |
+ S3C64XX_SPI_PND_TX_UNDERRUN_CLR;
+
+ writel(val, sdd->regs + S3C64XX_SPI_PENDING_CLR);
+
+ if (val & S3C64XX_SPI_PND_RX_OVERRUN_CLR)
dev_err(&spi->dev, "RX overrun\n");
- }
- if (val & S3C64XX_SPI_ST_RX_UNDERRUN_ERR) {
- clr |= S3C64XX_SPI_PND_RX_UNDERRUN_CLR;
+ if (val & S3C64XX_SPI_PND_RX_UNDERRUN_CLR)
dev_err(&spi->dev, "RX underrun\n");
- }
- if (val & S3C64XX_SPI_ST_TX_OVERRUN_ERR) {
- clr |= S3C64XX_SPI_PND_TX_OVERRUN_CLR;
+ if (val & S3C64XX_SPI_PND_TX_OVERRUN_CLR)
dev_err(&spi->dev, "TX overrun\n");
- }
- if (val & S3C64XX_SPI_ST_TX_UNDERRUN_ERR) {
- clr |= S3C64XX_SPI_PND_TX_UNDERRUN_CLR;
+ if (val & S3C64XX_SPI_PND_TX_UNDERRUN_CLR)
dev_err(&spi->dev, "TX underrun\n");
- }
-
- /* Clear the pending irq by setting and then clearing it */
- writel(clr, sdd->regs + S3C64XX_SPI_PENDING_CLR);
- writel(0, sdd->regs + S3C64XX_SPI_PENDING_CLR);
return IRQ_HANDLED;
}
@@ -1044,13 +1039,9 @@ static void s3c64xx_spi_hwinit(struct s3c64xx_spi_driver_data *sdd, int channel)
writel(0, regs + S3C64XX_SPI_MODE_CFG);
writel(0, regs + S3C64XX_SPI_PACKET_CNT);
- /* Clear any irq pending bits, should set and clear the bits */
- val = S3C64XX_SPI_PND_RX_OVERRUN_CLR |
- S3C64XX_SPI_PND_RX_UNDERRUN_CLR |
- S3C64XX_SPI_PND_TX_OVERRUN_CLR |
- S3C64XX_SPI_PND_TX_UNDERRUN_CLR;
- writel(val, regs + S3C64XX_SPI_PENDING_CLR);
- writel(0, regs + S3C64XX_SPI_PENDING_CLR);
+ /* Clear any irq pending bits */
+ writel(readl(regs + S3C64XX_SPI_PENDING_CLR),
+ regs + S3C64XX_SPI_PENDING_CLR);
writel(0, regs + S3C64XX_SPI_SWAP_CFG);
diff --git a/drivers/ssb/driver_chipcommon_pmu.c b/drivers/ssb/driver_chipcommon_pmu.c
index bc75528..a43415a 100644
--- a/drivers/ssb/driver_chipcommon_pmu.c
+++ b/drivers/ssb/driver_chipcommon_pmu.c
@@ -675,32 +675,3 @@ u32 ssb_pmu_get_controlclock(struct ssb_chipcommon *cc)
return 0;
}
}
-
-void ssb_pmu_spuravoid_pllupdate(struct ssb_chipcommon *cc, int spuravoid)
-{
- u32 pmu_ctl = 0;
-
- switch (cc->dev->bus->chip_id) {
- case 0x4322:
- ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL0, 0x11100070);
- ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL1, 0x1014140a);
- ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL5, 0x88888854);
- if (spuravoid == 1)
- ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL2, 0x05201828);
- else
- ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL2, 0x05001828);
- pmu_ctl = SSB_CHIPCO_PMU_CTL_PLL_UPD;
- break;
- case 43222:
- /* TODO: BCM43222 requires updating PLLs too */
- return;
- default:
- ssb_printk(KERN_ERR PFX
- "Unknown spuravoidance settings for chip 0x%04X, not changing PLL\n",
- cc->dev->bus->chip_id);
- return;
- }
-
- chipco_set32(cc, SSB_CHIPCO_PMU_CTL, pmu_ctl);
-}
-EXPORT_SYMBOL_GPL(ssb_pmu_spuravoid_pllupdate);
diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c
index 6894b3e..9b038e4 100644
--- a/drivers/staging/comedi/comedi_fops.c
+++ b/drivers/staging/comedi/comedi_fops.c
@@ -1547,11 +1547,6 @@ static long comedi_unlocked_ioctl(struct file *file, unsigned int cmd,
/* Device config is special, because it must work on
* an unconfigured device. */
if (cmd == COMEDI_DEVCONFIG) {
- if (minor >= COMEDI_NUM_BOARD_MINORS) {
- /* Device config not appropriate on non-board minors. */
- rc = -ENOTTY;
- goto done;
- }
rc = do_devconfig_ioctl(dev,
(struct comedi_devconfig __user *)arg);
if (rc == 0)
@@ -1779,7 +1774,7 @@ static unsigned int comedi_poll(struct file *file, poll_table *wait)
mask = 0;
read_subdev = comedi_get_read_subdevice(dev_file_info);
- if (read_subdev && read_subdev->async) {
+ if (read_subdev) {
poll_wait(file, &read_subdev->async->wait_head, wait);
if (!read_subdev->busy
|| comedi_buf_read_n_available(read_subdev->async) > 0
@@ -1789,7 +1784,7 @@ static unsigned int comedi_poll(struct file *file, poll_table *wait)
}
}
write_subdev = comedi_get_write_subdevice(dev_file_info);
- if (write_subdev && write_subdev->async) {
+ if (write_subdev) {
poll_wait(file, &write_subdev->async->wait_head, wait);
comedi_buf_write_alloc(write_subdev->async,
write_subdev->async->prealloc_bufsz);
@@ -1831,7 +1826,7 @@ static ssize_t comedi_write(struct file *file, const char __user *buf,
}
s = comedi_get_write_subdevice(dev_file_info);
- if (s == NULL || s->async == NULL) {
+ if (s == NULL) {
retval = -EIO;
goto done;
}
@@ -1942,7 +1937,7 @@ static ssize_t comedi_read(struct file *file, char __user *buf, size_t nbytes,
}
s = comedi_get_read_subdevice(dev_file_info);
- if (s == NULL || s->async == NULL) {
+ if (s == NULL) {
retval = -EIO;
goto done;
}
diff --git a/drivers/staging/comedi/drivers/dt9812.c b/drivers/staging/comedi/drivers/dt9812.c
index 3e7f961..1767998 100644
--- a/drivers/staging/comedi/drivers/dt9812.c
+++ b/drivers/staging/comedi/drivers/dt9812.c
@@ -948,13 +948,12 @@ static int dt9812_di_rinsn(struct comedi_device *dev,
unsigned int *data)
{
struct comedi_dt9812 *devpriv = dev->private;
- unsigned int channel = CR_CHAN(insn->chanspec);
int n;
u8 bits = 0;
dt9812_digital_in(devpriv->slot, &bits);
for (n = 0; n < insn->n; n++)
- data[n] = ((1 << channel) & bits) != 0;
+ data[n] = ((1 << insn->chanspec) & bits) != 0;
return n;
}
@@ -963,13 +962,12 @@ static int dt9812_do_winsn(struct comedi_device *dev,
unsigned int *data)
{
struct comedi_dt9812 *devpriv = dev->private;
- unsigned int channel = CR_CHAN(insn->chanspec);
int n;
u8 bits = 0;
dt9812_digital_out_shadow(devpriv->slot, &bits);
for (n = 0; n < insn->n; n++) {
- u8 mask = 1 << channel;
+ u8 mask = 1 << insn->chanspec;
bits &= ~mask;
if (data[n])
@@ -984,13 +982,13 @@ static int dt9812_ai_rinsn(struct comedi_device *dev,
unsigned int *data)
{
struct comedi_dt9812 *devpriv = dev->private;
- unsigned int channel = CR_CHAN(insn->chanspec);
int n;
for (n = 0; n < insn->n; n++) {
u16 value = 0;
- dt9812_analog_in(devpriv->slot, channel, &value, DT9812_GAIN_1);
+ dt9812_analog_in(devpriv->slot, insn->chanspec, &value,
+ DT9812_GAIN_1);
data[n] = value;
}
return n;
@@ -1001,13 +999,12 @@ static int dt9812_ao_rinsn(struct comedi_device *dev,
unsigned int *data)
{
struct comedi_dt9812 *devpriv = dev->private;
- unsigned int channel = CR_CHAN(insn->chanspec);
int n;
u16 value;
for (n = 0; n < insn->n; n++) {
value = 0;
- dt9812_analog_out_shadow(devpriv->slot, channel, &value);
+ dt9812_analog_out_shadow(devpriv->slot, insn->chanspec, &value);
data[n] = value;
}
return n;
@@ -1018,11 +1015,10 @@ static int dt9812_ao_winsn(struct comedi_device *dev,
unsigned int *data)
{
struct comedi_dt9812 *devpriv = dev->private;
- unsigned int channel = CR_CHAN(insn->chanspec);
int n;
for (n = 0; n < insn->n; n++)
- dt9812_analog_out(devpriv->slot, channel, data[n]);
+ dt9812_analog_out(devpriv->slot, insn->chanspec, data[n]);
return n;
}
diff --git a/drivers/staging/comedi/drivers/ni_labpc.c b/drivers/staging/comedi/drivers/ni_labpc.c
index d999053..d29c4d7 100644
--- a/drivers/staging/comedi/drivers/ni_labpc.c
+++ b/drivers/staging/comedi/drivers/ni_labpc.c
@@ -1202,8 +1202,7 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
else
channel = CR_CHAN(cmd->chanlist[0]);
/* munge channel bits for differential / scan disabled mode */
- if ((mode == MODE_SINGLE_CHAN || mode == MODE_SINGLE_CHAN_INTERVAL) &&
- aref == AREF_DIFF)
+ if (mode != MODE_SINGLE_CHAN && aref == AREF_DIFF)
channel *= 2;
devpriv->command1_bits |= ADC_CHAN_BITS(channel);
devpriv->command1_bits |= thisboard->ai_range_code[range];
@@ -1218,6 +1217,21 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
devpriv->write_byte(devpriv->command1_bits,
dev->iobase + COMMAND1_REG);
}
+ /* setup any external triggering/pacing (command4 register) */
+ devpriv->command4_bits = 0;
+ if (cmd->convert_src != TRIG_EXT)
+ devpriv->command4_bits |= EXT_CONVERT_DISABLE_BIT;
+ /* XXX should discard first scan when using interval scanning
+ * since manual says it is not synced with scan clock */
+ if (labpc_use_continuous_mode(cmd, mode) == 0) {
+ devpriv->command4_bits |= INTERVAL_SCAN_EN_BIT;
+ if (cmd->scan_begin_src == TRIG_EXT)
+ devpriv->command4_bits |= EXT_SCAN_EN_BIT;
+ }
+ /* single-ended/differential */
+ if (aref == AREF_DIFF)
+ devpriv->command4_bits |= ADC_DIFF_BIT;
+ devpriv->write_byte(devpriv->command4_bits, dev->iobase + COMMAND4_REG);
devpriv->write_byte(cmd->chanlist_len,
dev->iobase + INTERVAL_COUNT_REG);
@@ -1297,22 +1311,6 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
devpriv->command3_bits &= ~ADC_FNE_INTR_EN_BIT;
devpriv->write_byte(devpriv->command3_bits, dev->iobase + COMMAND3_REG);
- /* setup any external triggering/pacing (command4 register) */
- devpriv->command4_bits = 0;
- if (cmd->convert_src != TRIG_EXT)
- devpriv->command4_bits |= EXT_CONVERT_DISABLE_BIT;
- /* XXX should discard first scan when using interval scanning
- * since manual says it is not synced with scan clock */
- if (labpc_use_continuous_mode(cmd, mode) == 0) {
- devpriv->command4_bits |= INTERVAL_SCAN_EN_BIT;
- if (cmd->scan_begin_src == TRIG_EXT)
- devpriv->command4_bits |= EXT_SCAN_EN_BIT;
- }
- /* single-ended/differential */
- if (aref == AREF_DIFF)
- devpriv->command4_bits |= ADC_DIFF_BIT;
- devpriv->write_byte(devpriv->command4_bits, dev->iobase + COMMAND4_REG);
-
/* startup acquisition */
/* command2 reg */
diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c
index 5b65b52..6dc1d28 100644
--- a/drivers/staging/comedi/drivers/s626.c
+++ b/drivers/staging/comedi/drivers/s626.c
@@ -1482,7 +1482,7 @@ static int s626_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
case TRIG_NONE:
/* continous acquisition */
devpriv->ai_continous = 1;
- devpriv->ai_sample_count = 1;
+ devpriv->ai_sample_count = 0;
break;
}
diff --git a/drivers/staging/vt6656/dpc.c b/drivers/staging/vt6656/dpc.c
index d409e14..e94f6a1 100644
--- a/drivers/staging/vt6656/dpc.c
+++ b/drivers/staging/vt6656/dpc.c
@@ -1190,7 +1190,7 @@ static BOOL s_bHandleRxEncryption (
if (byDecMode == KEY_CTL_WEP) {
// handle WEP
if ((pDevice->byLocalID <= REV_ID_VT3253_A1) ||
- (((PSKeyTable)(pKey->pvKeyTable))->bSoftWEP == TRUE)) {
+ (((PSKeyTable)(&pKey->pvKeyTable))->bSoftWEP == TRUE)) {
// Software WEP
// 1. 3253A
// 2. WEP 256
@@ -1299,7 +1299,7 @@ static BOOL s_bHostWepRxEncryption (
// handle WEP
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"byDecMode == KEY_CTL_WEP\n");
if ((pDevice->byLocalID <= REV_ID_VT3253_A1) ||
- (((PSKeyTable)(pKey->pvKeyTable))->bSoftWEP == TRUE) ||
+ (((PSKeyTable)(&pKey->pvKeyTable))->bSoftWEP == TRUE) ||
(bOnFly == FALSE)) {
// Software WEP
// 1. 3253A
diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c
index f726970..f33086d 100644
--- a/drivers/staging/vt6656/main_usb.c
+++ b/drivers/staging/vt6656/main_usb.c
@@ -644,6 +644,8 @@ static int vt6656_suspend(struct usb_interface *intf, pm_message_t message)
if (device->flags & DEVICE_FLAGS_OPENED)
device_close(device->dev);
+ usb_put_dev(interface_to_usbdev(intf));
+
return 0;
}
@@ -654,6 +656,8 @@ static int vt6656_resume(struct usb_interface *intf)
if (!device || !device->dev)
return -ENODEV;
+ usb_get_dev(interface_to_usbdev(intf));
+
if (!(device->flags & DEVICE_FLAGS_OPENED))
device_open(device->dev);
diff --git a/drivers/staging/vt6656/rxtx.c b/drivers/staging/vt6656/rxtx.c
index 9213d69..83c04e1 100644
--- a/drivers/staging/vt6656/rxtx.c
+++ b/drivers/staging/vt6656/rxtx.c
@@ -1454,7 +1454,7 @@ s_bPacketToWirelessUsb(
pvRrvTime = pMICHDR = pvRTS = pvCTS = pvTxDataHd = NULL;
if (bNeedEncryption && pTransmitKey->pvKeyTable) {
- if (((PSKeyTable)pTransmitKey->pvKeyTable)->bSoftWEP == TRUE)
+ if (((PSKeyTable)&pTransmitKey->pvKeyTable)->bSoftWEP == TRUE)
bSoftWEP = TRUE; /* WEP 256 */
}
diff --git a/drivers/staging/vt6656/usbpipe.c b/drivers/staging/vt6656/usbpipe.c
index 87815c5..fc68518 100644
--- a/drivers/staging/vt6656/usbpipe.c
+++ b/drivers/staging/vt6656/usbpipe.c
@@ -165,11 +165,6 @@ int PIPEnsControlOut(
if (pDevice->Flags & fMP_CONTROL_WRITES)
return STATUS_FAILURE;
- if (pDevice->Flags & fMP_CONTROL_READS)
- return STATUS_FAILURE;
-
- MP_SET_FLAG(pDevice, fMP_CONTROL_WRITES);
-
pDevice->sUsbCtlRequest.bRequestType = 0x40;
pDevice->sUsbCtlRequest.bRequest = byRequest;
pDevice->sUsbCtlRequest.wValue = cpu_to_le16p(&wValue);
@@ -184,13 +179,12 @@ int PIPEnsControlOut(
ntStatus = usb_submit_urb(pDevice->pControlURB, GFP_ATOMIC);
if (ntStatus != 0) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
- "control send request submission failed: %d\n",
- ntStatus);
- MP_CLEAR_FLAG(pDevice, fMP_CONTROL_WRITES);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"control send request submission failed: %d\n", ntStatus);
return STATUS_FAILURE;
}
-
+ else {
+ MP_SET_FLAG(pDevice, fMP_CONTROL_WRITES);
+ }
spin_unlock_irq(&pDevice->lock);
for (ii = 0; ii <= USB_CTL_WAIT; ii ++) {
@@ -230,11 +224,6 @@ int PIPEnsControlIn(
if (pDevice->Flags & fMP_CONTROL_READS)
return STATUS_FAILURE;
- if (pDevice->Flags & fMP_CONTROL_WRITES)
- return STATUS_FAILURE;
-
- MP_SET_FLAG(pDevice, fMP_CONTROL_READS);
-
pDevice->sUsbCtlRequest.bRequestType = 0xC0;
pDevice->sUsbCtlRequest.bRequest = byRequest;
pDevice->sUsbCtlRequest.wValue = cpu_to_le16p(&wValue);
@@ -248,11 +237,10 @@ int PIPEnsControlIn(
ntStatus = usb_submit_urb(pDevice->pControlURB, GFP_ATOMIC);
if (ntStatus != 0) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
- "control request submission failed: %d\n", ntStatus);
- MP_CLEAR_FLAG(pDevice, fMP_CONTROL_READS);
- return STATUS_FAILURE;
- }
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"control request submission failed: %d\n", ntStatus);
+ }else {
+ MP_SET_FLAG(pDevice, fMP_CONTROL_READS);
+ }
spin_unlock_irq(&pDevice->lock);
for (ii = 0; ii <= USB_CTL_WAIT; ii ++) {
diff --git a/drivers/staging/zram/zram_drv.c b/drivers/staging/zram/zram_drv.c
index 071e058..f2a73bd 100644
--- a/drivers/staging/zram/zram_drv.c
+++ b/drivers/staging/zram/zram_drv.c
@@ -228,12 +228,11 @@ static int zram_bvec_read(struct zram *zram, struct bio_vec *bvec,
return 0;
}
+ user_mem = kmap_atomic(page);
if (is_partial_io(bvec))
/* Use a temporary buffer to decompress the page */
- uncmem = kmalloc(PAGE_SIZE, GFP_NOIO);
-
- user_mem = kmap_atomic(page);
- if (!is_partial_io(bvec))
+ uncmem = kmalloc(PAGE_SIZE, GFP_KERNEL);
+ else
uncmem = user_mem;
if (!uncmem) {
@@ -280,7 +279,7 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index,
* This is a partial IO. We need to read the full page
* before to write the changes.
*/
- uncmem = kmalloc(PAGE_SIZE, GFP_NOIO);
+ uncmem = kmalloc(PAGE_SIZE, GFP_KERNEL);
if (!uncmem) {
pr_info("Error allocating temp memory!\n");
ret = -ENOMEM;
diff --git a/drivers/staging/zsmalloc/Kconfig b/drivers/staging/zsmalloc/Kconfig
index 7fab032..9084565 100644
--- a/drivers/staging/zsmalloc/Kconfig
+++ b/drivers/staging/zsmalloc/Kconfig
@@ -1,5 +1,5 @@
config ZSMALLOC
- bool "Memory allocator for compressed pages"
+ tristate "Memory allocator for compressed pages"
default n
help
zsmalloc is a slab-based memory allocator designed to store
diff --git a/drivers/staging/zsmalloc/zsmalloc-main.c b/drivers/staging/zsmalloc/zsmalloc-main.c
index 851a2ff..09a9d35 100644
--- a/drivers/staging/zsmalloc/zsmalloc-main.c
+++ b/drivers/staging/zsmalloc/zsmalloc-main.c
@@ -222,9 +222,11 @@ struct zs_pool {
/*
* By default, zsmalloc uses a copy-based object mapping method to access
* allocations that span two pages. However, if a particular architecture
- * performs VM mapping faster than copying, then it should be added here
- * so that USE_PGTABLE_MAPPING is defined. This causes zsmalloc to use
- * page table mapping rather than copying for object mapping.
+ * 1) Implements local_flush_tlb_kernel_range() and 2) Performs VM mapping
+ * faster than copying, then it should be added here so that
+ * USE_PGTABLE_MAPPING is defined. This causes zsmalloc to use page table
+ * mapping rather than copying
+ * for object mapping.
*/
#if defined(CONFIG_ARM)
#define USE_PGTABLE_MAPPING
@@ -657,8 +659,11 @@ static inline void __zs_unmap_object(struct mapping_area *area,
struct page *pages[2], int off, int size)
{
unsigned long addr = (unsigned long)area->vm_addr;
+ unsigned long end = addr + (PAGE_SIZE * 2);
- unmap_kernel_range(addr, PAGE_SIZE * 2);
+ flush_cache_vunmap(addr, end);
+ unmap_kernel_range_noflush(addr, PAGE_SIZE * 2);
+ local_flush_tlb_kernel_range(addr, end);
}
#else /* USE_PGTABLE_MAPPING */
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c
index 42a2bf7..339f97f 100644
--- a/drivers/target/iscsi/iscsi_target.c
+++ b/drivers/target/iscsi/iscsi_target.c
@@ -3570,10 +3570,6 @@ check_rsp_state:
spin_lock_bh(&cmd->istate_lock);
cmd->i_state = ISTATE_SENT_STATUS;
spin_unlock_bh(&cmd->istate_lock);
-
- if (atomic_read(&conn->check_immediate_queue))
- return 1;
-
continue;
} else if (ret == 2) {
/* Still must send status,
@@ -3663,7 +3659,7 @@ check_rsp_state:
}
if (atomic_read(&conn->check_immediate_queue))
- return 1;
+ break;
}
return 0;
@@ -3707,15 +3703,12 @@ restart:
signal_pending(current))
goto transport_err;
-get_immediate:
ret = handle_immediate_queue(conn);
if (ret < 0)
goto transport_err;
ret = handle_response_queue(conn);
- if (ret == 1)
- goto get_immediate;
- else if (ret == -EAGAIN)
+ if (ret == -EAGAIN)
goto restart;
else if (ret < 0)
goto transport_err;
diff --git a/drivers/target/iscsi/iscsi_target_auth.c b/drivers/target/iscsi/iscsi_target_auth.c
index a0fc7b9..db0cf7c 100644
--- a/drivers/target/iscsi/iscsi_target_auth.c
+++ b/drivers/target/iscsi/iscsi_target_auth.c
@@ -166,7 +166,6 @@ static int chap_server_compute_md5(
{
char *endptr;
unsigned long id;
- unsigned char id_as_uchar;
unsigned char digest[MD5_SIGNATURE_SIZE];
unsigned char type, response[MD5_SIGNATURE_SIZE * 2 + 2];
unsigned char identifier[10], *challenge = NULL;
@@ -356,9 +355,7 @@ static int chap_server_compute_md5(
goto out;
}
- /* To handle both endiannesses */
- id_as_uchar = id;
- sg_init_one(&sg, &id_as_uchar, 1);
+ sg_init_one(&sg, &id, 1);
ret = crypto_hash_update(&desc, &sg, 1);
if (ret < 0) {
pr_err("crypto_hash_update() failed for id\n");
diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c
index fea564c..7d4ec02 100644
--- a/drivers/target/target_core_alua.c
+++ b/drivers/target/target_core_alua.c
@@ -408,7 +408,6 @@ static inline int core_alua_state_standby(
case REPORT_LUNS:
case RECEIVE_DIAGNOSTIC:
case SEND_DIAGNOSTIC:
- return 0;
case MAINTENANCE_IN:
switch (cdb[1] & 0x1f) {
case MI_REPORT_TARGET_PGS:
@@ -451,7 +450,6 @@ static inline int core_alua_state_unavailable(
switch (cdb[0]) {
case INQUIRY:
case REPORT_LUNS:
- return 0;
case MAINTENANCE_IN:
switch (cdb[1] & 0x1f) {
case MI_REPORT_TARGET_PGS:
@@ -492,7 +490,6 @@ static inline int core_alua_state_transition(
switch (cdb[0]) {
case INQUIRY:
case REPORT_LUNS:
- return 0;
case MAINTENANCE_IN:
switch (cdb[1] & 0x1f) {
case MI_REPORT_TARGET_PGS:
diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c
index 96f4981..f2aa754 100644
--- a/drivers/target/target_core_device.c
+++ b/drivers/target/target_core_device.c
@@ -1182,18 +1182,24 @@ static struct se_lun *core_dev_get_lun(struct se_portal_group *tpg, u32 unpacked
struct se_lun_acl *core_dev_init_initiator_node_lun_acl(
struct se_portal_group *tpg,
- struct se_node_acl *nacl,
u32 mapped_lun,
+ char *initiatorname,
int *ret)
{
struct se_lun_acl *lacl;
+ struct se_node_acl *nacl;
- if (strlen(nacl->initiatorname) >= TRANSPORT_IQN_LEN) {
+ if (strlen(initiatorname) >= TRANSPORT_IQN_LEN) {
pr_err("%s InitiatorName exceeds maximum size.\n",
tpg->se_tpg_tfo->get_fabric_name());
*ret = -EOVERFLOW;
return NULL;
}
+ nacl = core_tpg_get_initiator_node_acl(tpg, initiatorname);
+ if (!nacl) {
+ *ret = -EINVAL;
+ return NULL;
+ }
lacl = kzalloc(sizeof(struct se_lun_acl), GFP_KERNEL);
if (!lacl) {
pr_err("Unable to allocate memory for struct se_lun_acl.\n");
@@ -1204,8 +1210,7 @@ struct se_lun_acl *core_dev_init_initiator_node_lun_acl(
INIT_LIST_HEAD(&lacl->lacl_list);
lacl->mapped_lun = mapped_lun;
lacl->se_lun_nacl = nacl;
- snprintf(lacl->initiatorname, TRANSPORT_IQN_LEN, "%s",
- nacl->initiatorname);
+ snprintf(lacl->initiatorname, TRANSPORT_IQN_LEN, "%s", initiatorname);
return lacl;
}
diff --git a/drivers/target/target_core_fabric_configfs.c b/drivers/target/target_core_fabric_configfs.c
index 04c775c..c57bbbc 100644
--- a/drivers/target/target_core_fabric_configfs.c
+++ b/drivers/target/target_core_fabric_configfs.c
@@ -354,17 +354,9 @@ static struct config_group *target_fabric_make_mappedlun(
ret = -EINVAL;
goto out;
}
- if (mapped_lun > (TRANSPORT_MAX_LUNS_PER_TPG-1)) {
- pr_err("Mapped LUN: %lu exceeds TRANSPORT_MAX_LUNS_PER_TPG"
- "-1: %u for Target Portal Group: %u\n", mapped_lun,
- TRANSPORT_MAX_LUNS_PER_TPG-1,
- se_tpg->se_tpg_tfo->tpg_get_tag(se_tpg));
- ret = -EINVAL;
- goto out;
- }
- lacl = core_dev_init_initiator_node_lun_acl(se_tpg, se_nacl,
- mapped_lun, &ret);
+ lacl = core_dev_init_initiator_node_lun_acl(se_tpg, mapped_lun,
+ config_item_name(acl_ci), &ret);
if (!lacl) {
ret = -EINVAL;
goto out;
diff --git a/drivers/target/target_core_file.h b/drivers/target/target_core_file.h
index 37ffc5b..bc02b01 100644
--- a/drivers/target/target_core_file.h
+++ b/drivers/target/target_core_file.h
@@ -7,7 +7,7 @@
#define FD_DEVICE_QUEUE_DEPTH 32
#define FD_MAX_DEVICE_QUEUE_DEPTH 128
#define FD_BLOCKSIZE 512
-#define FD_MAX_SECTORS 2048
+#define FD_MAX_SECTORS 1024
#define RRF_EMULATE_CDB 0x01
#define RRF_GOT_LBA 0x02
diff --git a/drivers/target/target_core_internal.h b/drivers/target/target_core_internal.h
index 396e1eb..93e9c1f 100644
--- a/drivers/target/target_core_internal.h
+++ b/drivers/target/target_core_internal.h
@@ -45,7 +45,7 @@ struct se_lun *core_dev_add_lun(struct se_portal_group *, struct se_device *, u3
int core_dev_del_lun(struct se_portal_group *, u32);
struct se_lun *core_get_lun_from_tpg(struct se_portal_group *, u32);
struct se_lun_acl *core_dev_init_initiator_node_lun_acl(struct se_portal_group *,
- struct se_node_acl *, u32, int *);
+ u32, char *, int *);
int core_dev_add_initiator_node_lun_acl(struct se_portal_group *,
struct se_lun_acl *, u32, u32);
int core_dev_del_initiator_node_lun_acl(struct se_portal_group *,
diff --git a/drivers/target/target_core_pscsi.c b/drivers/target/target_core_pscsi.c
index 55b9530..2bcfd79 100644
--- a/drivers/target/target_core_pscsi.c
+++ b/drivers/target/target_core_pscsi.c
@@ -940,6 +940,7 @@ pscsi_map_sg(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents,
bio = NULL;
}
+ page++;
len -= bytes;
data_len -= bytes;
off = 0;
diff --git a/drivers/target/target_core_tpg.c b/drivers/target/target_core_tpg.c
index 9169d6a..5192ac0 100644
--- a/drivers/target/target_core_tpg.c
+++ b/drivers/target/target_core_tpg.c
@@ -111,10 +111,16 @@ struct se_node_acl *core_tpg_get_initiator_node_acl(
struct se_node_acl *acl;
spin_lock_irq(&tpg->acl_node_lock);
- acl = __core_tpg_get_initiator_node_acl(tpg, initiatorname);
+ list_for_each_entry(acl, &tpg->acl_node_list, acl_list) {
+ if (!strcmp(acl->initiatorname, initiatorname) &&
+ !acl->dynamic_node_acl) {
+ spin_unlock_irq(&tpg->acl_node_lock);
+ return acl;
+ }
+ }
spin_unlock_irq(&tpg->acl_node_lock);
- return acl;
+ return NULL;
}
/* core_tpg_add_node_to_devs():
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index fcf880f..bd587b7 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -1136,10 +1136,8 @@ target_setup_cmd_from_cdb(struct se_cmd *cmd, unsigned char *cdb)
return ret;
ret = target_check_reservation(cmd);
- if (ret) {
- cmd->scsi_status = SAM_STAT_RESERVATION_CONFLICT;
+ if (ret)
return ret;
- }
ret = dev->transport->parse_cdb(cmd);
if (ret)
diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
index bfbf9fb..8c8ce80 100644
--- a/drivers/thermal/thermal_sys.c
+++ b/drivers/thermal/thermal_sys.c
@@ -1807,7 +1807,6 @@ static int __init thermal_init(void)
idr_destroy(&thermal_cdev_idr);
mutex_destroy(&thermal_idr_lock);
mutex_destroy(&thermal_list_lock);
- return result;
}
result = genetlink_init();
return result;
diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c
index bfd6771..dcc0430 100644
--- a/drivers/tty/n_gsm.c
+++ b/drivers/tty/n_gsm.c
@@ -1689,8 +1689,6 @@ static inline void dlci_put(struct gsm_dlci *dlci)
tty_port_put(&dlci->port);
}
-static void gsm_destroy_network(struct gsm_dlci *dlci);
-
/**
* gsm_dlci_release - release DLCI
* @dlci: DLCI to destroy
@@ -1704,19 +1702,9 @@ static void gsm_dlci_release(struct gsm_dlci *dlci)
{
struct tty_struct *tty = tty_port_tty_get(&dlci->port);
if (tty) {
- mutex_lock(&dlci->mutex);
- gsm_destroy_network(dlci);
- mutex_unlock(&dlci->mutex);
-
- /* tty_vhangup needs the tty_lock, so unlock and
- relock after doing the hangup. */
- tty_unlock(tty);
tty_vhangup(tty);
- tty_lock(tty);
- tty_port_tty_set(&dlci->port, NULL);
tty_kref_put(tty);
}
- dlci->state = DLCI_CLOSED;
dlci_put(dlci);
}
@@ -2959,8 +2947,6 @@ static void gsmtty_close(struct tty_struct *tty, struct file *filp)
if (dlci == NULL)
return;
- if (dlci->state == DLCI_CLOSED)
- return;
mutex_lock(&dlci->mutex);
gsm_destroy_network(dlci);
mutex_unlock(&dlci->mutex);
@@ -2979,8 +2965,6 @@ out:
static void gsmtty_hangup(struct tty_struct *tty)
{
struct gsm_dlci *dlci = tty->driver_data;
- if (dlci->state == DLCI_CLOSED)
- return;
tty_port_hangup(&dlci->port);
gsm_dlci_begin_close(dlci);
}
@@ -2988,12 +2972,9 @@ static void gsmtty_hangup(struct tty_struct *tty)
static int gsmtty_write(struct tty_struct *tty, const unsigned char *buf,
int len)
{
- int sent;
struct gsm_dlci *dlci = tty->driver_data;
- if (dlci->state == DLCI_CLOSED)
- return -EINVAL;
/* Stuff the bytes into the fifo queue */
- sent = kfifo_in_locked(dlci->fifo, buf, len, &dlci->lock);
+ int sent = kfifo_in_locked(dlci->fifo, buf, len, &dlci->lock);
/* Need to kick the channel */
gsm_dlci_data_kick(dlci);
return sent;
@@ -3002,24 +2983,18 @@ static int gsmtty_write(struct tty_struct *tty, const unsigned char *buf,
static int gsmtty_write_room(struct tty_struct *tty)
{
struct gsm_dlci *dlci = tty->driver_data;
- if (dlci->state == DLCI_CLOSED)
- return -EINVAL;
return TX_SIZE - kfifo_len(dlci->fifo);
}
static int gsmtty_chars_in_buffer(struct tty_struct *tty)
{
struct gsm_dlci *dlci = tty->driver_data;
- if (dlci->state == DLCI_CLOSED)
- return -EINVAL;
return kfifo_len(dlci->fifo);
}
static void gsmtty_flush_buffer(struct tty_struct *tty)
{
struct gsm_dlci *dlci = tty->driver_data;
- if (dlci->state == DLCI_CLOSED)
- return;
/* Caution needed: If we implement reliable transport classes
then the data being transmitted can't simply be junked once
it has first hit the stack. Until then we can just blow it
@@ -3038,8 +3013,6 @@ static void gsmtty_wait_until_sent(struct tty_struct *tty, int timeout)
static int gsmtty_tiocmget(struct tty_struct *tty)
{
struct gsm_dlci *dlci = tty->driver_data;
- if (dlci->state == DLCI_CLOSED)
- return -EINVAL;
return dlci->modem_rx;
}
@@ -3049,8 +3022,6 @@ static int gsmtty_tiocmset(struct tty_struct *tty,
struct gsm_dlci *dlci = tty->driver_data;
unsigned int modem_tx = dlci->modem_tx;
- if (dlci->state == DLCI_CLOSED)
- return -EINVAL;
modem_tx &= ~clear;
modem_tx |= set;
@@ -3069,8 +3040,6 @@ static int gsmtty_ioctl(struct tty_struct *tty,
struct gsm_netconfig nc;
int index;
- if (dlci->state == DLCI_CLOSED)
- return -EINVAL;
switch (cmd) {
case GSMIOC_ENABLE_NET:
if (copy_from_user(&nc, (void __user *)arg, sizeof(nc)))
@@ -3097,9 +3066,6 @@ static int gsmtty_ioctl(struct tty_struct *tty,
static void gsmtty_set_termios(struct tty_struct *tty, struct ktermios *old)
{
- struct gsm_dlci *dlci = tty->driver_data;
- if (dlci->state == DLCI_CLOSED)
- return;
/* For the moment its fixed. In actual fact the speed information
for the virtual channel can be propogated in both directions by
the RPN control message. This however rapidly gets nasty as we
@@ -3111,8 +3077,6 @@ static void gsmtty_set_termios(struct tty_struct *tty, struct ktermios *old)
static void gsmtty_throttle(struct tty_struct *tty)
{
struct gsm_dlci *dlci = tty->driver_data;
- if (dlci->state == DLCI_CLOSED)
- return;
if (tty->termios.c_cflag & CRTSCTS)
dlci->modem_tx &= ~TIOCM_DTR;
dlci->throttled = 1;
@@ -3123,8 +3087,6 @@ static void gsmtty_throttle(struct tty_struct *tty)
static void gsmtty_unthrottle(struct tty_struct *tty)
{
struct gsm_dlci *dlci = tty->driver_data;
- if (dlci->state == DLCI_CLOSED)
- return;
if (tty->termios.c_cflag & CRTSCTS)
dlci->modem_tx |= TIOCM_DTR;
dlci->throttled = 0;
@@ -3136,8 +3098,6 @@ static int gsmtty_break_ctl(struct tty_struct *tty, int state)
{
struct gsm_dlci *dlci = tty->driver_data;
int encode = 0; /* Off */
- if (dlci->state == DLCI_CLOSED)
- return -EINVAL;
if (state == -1) /* "On indefinitely" - we can't encode this
properly */
diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c
index c830b60..79ff3a5 100644
--- a/drivers/tty/pty.c
+++ b/drivers/tty/pty.c
@@ -47,6 +47,7 @@ static void pty_close(struct tty_struct *tty, struct file *filp)
/* Review - krefs on tty_link ?? */
if (!tty->link)
return;
+ tty->link->packet = 0;
set_bit(TTY_OTHER_CLOSED, &tty->link->flags);
wake_up_interruptible(&tty->link->read_wait);
wake_up_interruptible(&tty->link->write_wait);
@@ -675,9 +676,6 @@ static int ptmx_open(struct inode *inode, struct file *filp)
nonseekable_open(inode, filp);
- /* We refuse fsnotify events on ptmx, since it's a shared resource */
- filp->f_mode |= FMODE_NONOTIFY;
-
retval = tty_alloc_file(filp);
if (retval)
return retval;
diff --git a/drivers/tty/serial/8250/8250.c b/drivers/tty/serial/8250/8250.c
index f318c96..f932043 100644
--- a/drivers/tty/serial/8250/8250.c
+++ b/drivers/tty/serial/8250/8250.c
@@ -38,7 +38,6 @@
#include <linux/nmi.h>
#include <linux/mutex.h>
#include <linux/slab.h>
-#include <linux/kdb.h>
#ifdef CONFIG_SPARC
#include <linux/sunserialcore.h>
#endif
@@ -81,16 +80,7 @@ static unsigned int skip_txen_test; /* force skip of txen test at init time */
#define DEBUG_INTR(fmt...) do { } while (0)
#endif
-/*
- * On -rt we can have a more delays, and legitimately
- * so - so don't drop work spuriously and spam the
- * syslog:
- */
-#ifdef CONFIG_PREEMPT_RT_FULL
-# define PASS_LIMIT 1000000
-#else
-# define PASS_LIMIT 512
-#endif
+#define PASS_LIMIT 512
#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
@@ -318,28 +308,7 @@ static const struct serial8250_config uart_config[] = {
},
[PORT_8250_CIR] = {
.name = "CIR port"
- },
- [PORT_ALTR_16550_F32] = {
- .name = "Altera 16550 FIFO32",
- .fifo_size = 32,
- .tx_loadsz = 32,
- .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
- .flags = UART_CAP_FIFO | UART_CAP_AFE,
- },
- [PORT_ALTR_16550_F64] = {
- .name = "Altera 16550 FIFO64",
- .fifo_size = 64,
- .tx_loadsz = 64,
- .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
- .flags = UART_CAP_FIFO | UART_CAP_AFE,
- },
- [PORT_ALTR_16550_F128] = {
- .name = "Altera 16550 FIFO128",
- .fifo_size = 128,
- .tx_loadsz = 128,
- .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
- .flags = UART_CAP_FIFO | UART_CAP_AFE,
- },
+ }
};
/* Uart divisor latch read */
@@ -2910,10 +2879,14 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count)
touch_nmi_watchdog();
- if (port->sysrq || oops_in_progress || in_kdb_printk())
- locked = spin_trylock_irqsave(&port->lock, flags);
- else
- spin_lock_irqsave(&port->lock, flags);
+ local_irq_save(flags);
+ if (port->sysrq) {
+ /* serial8250_handle_irq() already took the lock */
+ locked = 0;
+ } else if (oops_in_progress) {
+ locked = spin_trylock(&port->lock);
+ } else
+ spin_lock(&port->lock);
/*
* First save the IER then disable the interrupts
@@ -2945,7 +2918,8 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count)
serial8250_modem_status(up);
if (locked)
- spin_unlock_irqrestore(&port->lock, flags);
+ spin_unlock(&port->lock);
+ local_irq_restore(flags);
}
static int __init serial8250_console_setup(struct console *co, char *options)
@@ -3456,32 +3430,3 @@ module_param_array(probe_rsa, ulong, &probe_rsa_count, 0444);
MODULE_PARM_DESC(probe_rsa, "Probe I/O ports for RSA");
#endif
MODULE_ALIAS_CHARDEV_MAJOR(TTY_MAJOR);
-
-#ifndef MODULE
-/* This module was renamed to 8250_core in 3.7. Keep the old "8250" name
- * working as well for the module options so we don't break people. We
- * need to keep the names identical and the convenient macros will happily
- * refuse to let us do that by failing the build with redefinition errors
- * of global variables. So we stick them inside a dummy function to avoid
- * those conflicts. The options still get parsed, and the redefined
- * MODULE_PARAM_PREFIX lets us keep the "8250." syntax alive.
- *
- * This is hacky. I'm sorry.
- */
-static void __used s8250_options(void)
-{
-#undef MODULE_PARAM_PREFIX
-#define MODULE_PARAM_PREFIX "8250."
-
- module_param_cb(share_irqs, &param_ops_uint, &share_irqs, 0644);
- module_param_cb(nr_uarts, &param_ops_uint, &nr_uarts, 0644);
- module_param_cb(skip_txen_test, &param_ops_uint, &skip_txen_test, 0644);
-#ifdef CONFIG_SERIAL_8250_RSA
- __module_param_call(MODULE_PARAM_PREFIX, probe_rsa,
- &param_array_ops, .arr = &__param_arr_probe_rsa,
- 0444, -1);
-#endif
-}
-#else
-MODULE_ALIAS("8250");
-#endif
diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c
index 5cdb092..a27a98e 100644
--- a/drivers/tty/serial/8250/8250_pci.c
+++ b/drivers/tty/serial/8250/8250_pci.c
@@ -1321,7 +1321,6 @@ pci_wch_ch353_setup(struct serial_private *priv,
/* Unknown vendors/cards - this should not be in linux/pci_ids.h */
#define PCI_SUBDEVICE_ID_UNKNOWN_0x1584 0x1584
-#define PCI_SUBDEVICE_ID_UNKNOWN_0x1588 0x1588
/*
* Master list of serial port init/setup/exit quirks.
@@ -1593,6 +1592,15 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
},
{
.vendor = PCI_VENDOR_ID_PLX,
+ .device = PCI_DEVICE_ID_PLX_9050,
+ .subvendor = PCI_VENDOR_ID_PLX,
+ .subdevice = PCI_SUBDEVICE_ID_UNKNOWN_0x1584,
+ .init = pci_plx9050_init,
+ .setup = pci_default_setup,
+ .exit = pci_plx9050_exit,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_PLX,
.device = PCI_DEVICE_ID_PLX_ROMULUS,
.subvendor = PCI_VENDOR_ID_PLX,
.subdevice = PCI_DEVICE_ID_PLX_ROMULUS,
@@ -3448,12 +3456,7 @@ static struct pci_device_id serial_pci_tbl[] = {
{ PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
PCI_VENDOR_ID_PLX,
PCI_SUBDEVICE_ID_UNKNOWN_0x1584, 0, 0,
- pbn_b2_4_115200 },
- /* Unknown card - subdevice 0x1588 */
- { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
- PCI_VENDOR_ID_PLX,
- PCI_SUBDEVICE_ID_UNKNOWN_0x1588, 0, 0,
- pbn_b2_8_115200 },
+ pbn_b0_4_115200 },
{ PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
PCI_SUBVENDOR_ID_KEYSPAN,
PCI_SUBDEVICE_ID_KEYSPAN_SX2, 0, 0,
@@ -4446,10 +4449,6 @@ static struct pci_device_id serial_pci_tbl[] = {
PCI_VENDOR_ID_IBM, 0x0299,
0, 0, pbn_b0_bt_2_115200 },
- { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9835,
- 0x1000, 0x0012,
- 0, 0, pbn_b0_bt_2_115200 },
-
{ PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9901,
0xA000, 0x1000,
0, 0, pbn_b0_1_115200 },
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
index 02e706e..59c23d0 100644
--- a/drivers/tty/serial/Kconfig
+++ b/drivers/tty/serial/Kconfig
@@ -209,14 +209,14 @@ config SERIAL_SAMSUNG
config SERIAL_SAMSUNG_UARTS_4
bool
depends on PLAT_SAMSUNG
- default y if !(CPU_S3C2410 || CPU_S3C2412 || CPU_S3C2440 || CPU_S3C2442)
+ default y if !(CPU_S3C2410 || SERIAL_S3C2412 || CPU_S3C2440 || CPU_S3C2442)
help
Internal node for the common case of 4 Samsung compatible UARTs
config SERIAL_SAMSUNG_UARTS
int
depends on PLAT_SAMSUNG
- default 6 if CPU_S5P6450
+ default 6 if ARCH_S5P6450
default 4 if SERIAL_SAMSUNG_UARTS_4 || CPU_S3C2416
default 3
help
diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c
index d7294f7..7fca402 100644
--- a/drivers/tty/serial/amba-pl011.c
+++ b/drivers/tty/serial/amba-pl011.c
@@ -1779,19 +1779,13 @@ pl011_console_write(struct console *co, const char *s, unsigned int count)
clk_enable(uap->clk);
- /*
- * local_irq_save(flags);
- *
- * This local_irq_save() is nonsense. If we come in via sysrq
- * handling then interrupts are already disabled. Aside of
- * that the port.sysrq check is racy on SMP regardless.
- */
+ local_irq_save(flags);
if (uap->port.sysrq)
locked = 0;
else if (oops_in_progress)
- locked = spin_trylock_irqsave(&uap->port.lock, flags);
+ locked = spin_trylock(&uap->port.lock);
else
- spin_lock_irqsave(&uap->port.lock, flags);
+ spin_lock(&uap->port.lock);
/*
* First save the CR then disable the interrupts
@@ -1813,7 +1807,8 @@ pl011_console_write(struct console *co, const char *s, unsigned int count)
writew(old_cr, uap->port.membase + UART011_CR);
if (locked)
- spin_unlock_irqrestore(&uap->port.lock, flags);
+ spin_unlock(&uap->port.lock);
+ local_irq_restore(flags);
clk_disable(uap->clk);
}
diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c
index 2d2288d..922e85a 100644
--- a/drivers/tty/serial/atmel_serial.c
+++ b/drivers/tty/serial/atmel_serial.c
@@ -158,7 +158,7 @@ struct atmel_uart_port {
};
static struct atmel_uart_port atmel_ports[ATMEL_MAX_UART];
-static DECLARE_BITMAP(atmel_ports_in_use, ATMEL_MAX_UART);
+static unsigned long atmel_ports_in_use;
#ifdef SUPPORT_SYSRQ
static struct console atmel_console;
@@ -1768,14 +1768,15 @@ static int atmel_serial_probe(struct platform_device *pdev)
if (ret < 0)
/* port id not found in platform data nor device-tree aliases:
* auto-enumerate it */
- ret = find_first_zero_bit(atmel_ports_in_use, ATMEL_MAX_UART);
+ ret = find_first_zero_bit(&atmel_ports_in_use,
+ sizeof(atmel_ports_in_use));
- if (ret >= ATMEL_MAX_UART) {
+ if (ret > ATMEL_MAX_UART) {
ret = -ENODEV;
goto err;
}
- if (test_and_set_bit(ret, atmel_ports_in_use)) {
+ if (test_and_set_bit(ret, &atmel_ports_in_use)) {
/* port already in use */
ret = -EBUSY;
goto err;
@@ -1855,7 +1856,7 @@ static int atmel_serial_remove(struct platform_device *pdev)
/* "port" is allocated statically, so we shouldn't free it */
- clear_bit(port->line, atmel_ports_in_use);
+ clear_bit(port->line, &atmel_ports_in_use);
clk_put(atmel_port->clk);
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index 5c110c8..5981912 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -1213,14 +1213,8 @@ imx_console_write(struct console *co, const char *s, unsigned int count)
struct imx_port_ucrs old_ucr;
unsigned int ucr1;
unsigned long flags;
- int locked = 1;
- if (sport->port.sysrq)
- locked = 0;
- else if (oops_in_progress)
- locked = spin_trylock_irqsave(&sport->port.lock, flags);
- else
- spin_lock_irqsave(&sport->port.lock, flags);
+ spin_lock_irqsave(&sport->port.lock, flags);
/*
* First, save UCR1/2/3 and then disable interrupts
@@ -1247,8 +1241,7 @@ imx_console_write(struct console *co, const char *s, unsigned int count)
imx_port_ucrs_restore(&sport->port, &old_ucr);
- if (locked)
- spin_unlock_irqrestore(&sport->port.lock, flags);
+ spin_unlock_irqrestore(&sport->port.lock, flags);
}
/*
diff --git a/drivers/tty/serial/of_serial.c b/drivers/tty/serial/of_serial.c
index 3490629..e7cae1c 100644
--- a/drivers/tty/serial/of_serial.c
+++ b/drivers/tty/serial/of_serial.c
@@ -240,12 +240,6 @@ static struct of_device_id of_platform_serial_table[] = {
{ .compatible = "ns16850", .data = (void *)PORT_16850, },
{ .compatible = "nvidia,tegra20-uart", .data = (void *)PORT_TEGRA, },
{ .compatible = "nxp,lpc3220-uart", .data = (void *)PORT_LPC3220, },
- { .compatible = "altr,16550-FIFO32",
- .data = (void *)PORT_ALTR_16550_F32, },
- { .compatible = "altr,16550-FIFO64",
- .data = (void *)PORT_ALTR_16550_F64, },
- { .compatible = "altr,16550-FIFO128",
- .data = (void *)PORT_ALTR_16550_F128, },
#ifdef CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL
{ .compatible = "ibm,qpace-nwp-serial",
.data = (void *)PORT_NWPSERIAL, },
diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c
index f33fa96..57d6b29 100644
--- a/drivers/tty/serial/omap-serial.c
+++ b/drivers/tty/serial/omap-serial.c
@@ -1166,10 +1166,13 @@ serial_omap_console_write(struct console *co, const char *s,
pm_runtime_get_sync(up->dev);
- if (up->port.sysrq || oops_in_progress)
- locked = spin_trylock_irqsave(&up->port.lock, flags);
+ local_irq_save(flags);
+ if (up->port.sysrq)
+ locked = 0;
+ else if (oops_in_progress)
+ locked = spin_trylock(&up->port.lock);
else
- spin_lock_irqsave(&up->port.lock, flags);
+ spin_lock(&up->port.lock);
/*
* First save the IER then disable the interrupts
@@ -1198,7 +1201,8 @@ serial_omap_console_write(struct console *co, const char *s,
pm_runtime_mark_last_busy(up->dev);
pm_runtime_put_autosuspend(up->dev);
if (locked)
- spin_unlock_irqrestore(&up->port.lock, flags);
+ spin_unlock(&up->port.lock);
+ local_irq_restore(flags);
}
static int __init
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
index 4293a3e..2c7230a 100644
--- a/drivers/tty/serial/serial_core.c
+++ b/drivers/tty/serial/serial_core.c
@@ -1940,8 +1940,6 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *uport)
mutex_unlock(&port->mutex);
return 0;
}
- put_device(tty_dev);
-
if (console_suspend_enabled || !uart_console(uport))
uport->suspended = 1;
@@ -2007,11 +2005,9 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport)
disable_irq_wake(uport->irq);
uport->irq_wake = 0;
}
- put_device(tty_dev);
mutex_unlock(&port->mutex);
return 0;
}
- put_device(tty_dev);
uport->suspended = 0;
/*
diff --git a/drivers/tty/serial/sunsu.c b/drivers/tty/serial/sunsu.c
index 94b0ad7..220da3f 100644
--- a/drivers/tty/serial/sunsu.c
+++ b/drivers/tty/serial/sunsu.c
@@ -974,7 +974,6 @@ static struct uart_ops sunsu_pops = {
#define UART_NR 4
static struct uart_sunsu_port sunsu_ports[UART_NR];
-static int nr_inst; /* Number of already registered ports */
#ifdef CONFIG_SERIO
@@ -1344,8 +1343,13 @@ static int __init sunsu_console_setup(struct console *co, char *options)
printk("Console: ttyS%d (SU)\n",
(sunsu_reg.minor - 64) + co->index);
- if (co->index > nr_inst)
- return -ENODEV;
+ /*
+ * Check whether an invalid uart number has been specified, and
+ * if so, search for the first available port that does have
+ * console support.
+ */
+ if (co->index >= UART_NR)
+ co->index = 0;
port = &sunsu_ports[co->index].port;
/*
@@ -1410,6 +1414,7 @@ static enum su_type su_get_type(struct device_node *dp)
static int su_probe(struct platform_device *op)
{
+ static int inst;
struct device_node *dp = op->dev.of_node;
struct uart_sunsu_port *up;
struct resource *rp;
@@ -1419,16 +1424,16 @@ static int su_probe(struct platform_device *op)
type = su_get_type(dp);
if (type == SU_PORT_PORT) {
- if (nr_inst >= UART_NR)
+ if (inst >= UART_NR)
return -EINVAL;
- up = &sunsu_ports[nr_inst];
+ up = &sunsu_ports[inst];
} else {
up = kzalloc(sizeof(*up), GFP_KERNEL);
if (!up)
return -ENOMEM;
}
- up->port.line = nr_inst;
+ up->port.line = inst;
spin_lock_init(&up->port.lock);
@@ -1462,8 +1467,6 @@ static int su_probe(struct platform_device *op)
}
dev_set_drvdata(&op->dev, up);
- nr_inst++;
-
return 0;
}
@@ -1491,7 +1494,7 @@ static int su_probe(struct platform_device *op)
dev_set_drvdata(&op->dev, up);
- nr_inst++;
+ inst++;
return 0;
diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c
index 7c021eb..45d9161 100644
--- a/drivers/tty/tty_buffer.c
+++ b/drivers/tty/tty_buffer.c
@@ -473,7 +473,7 @@ static void flush_to_ldisc(struct work_struct *work)
struct tty_ldisc *disc;
tty = port->itty;
- if (tty == NULL)
+ if (WARN_RATELIMIT(tty == NULL, "tty is NULL\n"))
return;
disc = tty_ldisc_ref(tty);
@@ -566,15 +566,10 @@ void tty_flip_buffer_push(struct tty_struct *tty)
buf->tail->commit = buf->tail->used;
spin_unlock_irqrestore(&buf->lock, flags);
-#ifndef CONFIG_PREEMPT_RT_FULL
if (tty->low_latency)
flush_to_ldisc(&buf->work);
else
schedule_work(&buf->work);
-#else
- flush_to_ldisc(&buf->work);
-#endif
-
}
EXPORT_SYMBOL(tty_flip_buffer_push);
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
index f34f98d..da9fde8 100644
--- a/drivers/tty/tty_io.c
+++ b/drivers/tty/tty_io.c
@@ -941,14 +941,6 @@ void start_tty(struct tty_struct *tty)
EXPORT_SYMBOL(start_tty);
-/* We limit tty time update visibility to every 8 seconds or so. */
-static void tty_update_time(struct timespec *time)
-{
- unsigned long sec = get_seconds() & ~7;
- if ((long)(sec - time->tv_sec) > 0)
- time->tv_sec = sec;
-}
-
/**
* tty_read - read method for tty device files
* @file: pointer to tty file
@@ -985,10 +977,8 @@ static ssize_t tty_read(struct file *file, char __user *buf, size_t count,
else
i = -EIO;
tty_ldisc_deref(ld);
-
if (i > 0)
- tty_update_time(&inode->i_atime);
-
+ inode->i_atime = current_fs_time(inode->i_sb);
return i;
}
@@ -1091,7 +1081,7 @@ static inline ssize_t do_tty_write(
}
if (written) {
struct inode *inode = file->f_path.dentry->d_inode;
- tty_update_time(&inode->i_mtime);
+ inode->i_mtime = current_fs_time(inode->i_sb);
ret = written;
}
out:
diff --git a/drivers/tty/tty_ioctl.c b/drivers/tty/tty_ioctl.c
index e4455e0..8481b29 100644
--- a/drivers/tty/tty_ioctl.c
+++ b/drivers/tty/tty_ioctl.c
@@ -617,7 +617,7 @@ static int set_termios(struct tty_struct *tty, void __user *arg, int opt)
if (opt & TERMIOS_WAIT) {
tty_wait_until_sent(tty, 0);
if (signal_pending(current))
- return -ERESTARTSYS;
+ return -EINTR;
}
tty_set_termios(tty, &tmp_termios);
@@ -684,7 +684,7 @@ static int set_termiox(struct tty_struct *tty, void __user *arg, int opt)
if (opt & TERMIOS_WAIT) {
tty_wait_until_sent(tty, 0);
if (signal_pending(current))
- return -ERESTARTSYS;
+ return -EINTR;
}
mutex_lock(&tty->termios_mutex);
diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c
index 78f1be2..c578229 100644
--- a/drivers/tty/tty_ldisc.c
+++ b/drivers/tty/tty_ldisc.c
@@ -934,17 +934,17 @@ void tty_ldisc_release(struct tty_struct *tty, struct tty_struct *o_tty)
* race with the set_ldisc code path.
*/
+ tty_lock_pair(tty, o_tty);
tty_ldisc_halt(tty);
- if (o_tty)
- tty_ldisc_halt(o_tty);
-
tty_ldisc_flush_works(tty);
- if (o_tty)
+ if (o_tty) {
+ tty_ldisc_halt(o_tty);
tty_ldisc_flush_works(o_tty);
+ }
- tty_lock_pair(tty, o_tty);
/* This will need doing differently if we need to lock */
tty_ldisc_kill(tty);
+
if (o_tty)
tty_ldisc_kill(o_tty);
diff --git a/drivers/tty/vt/vc_screen.c b/drivers/tty/vt/vc_screen.c
index 6abb92c..fa7268a 100644
--- a/drivers/tty/vt/vc_screen.c
+++ b/drivers/tty/vt/vc_screen.c
@@ -93,7 +93,7 @@ vcs_poll_data_free(struct vcs_poll_data *poll)
static struct vcs_poll_data *
vcs_poll_data_get(struct file *file)
{
- struct vcs_poll_data *poll = file->private_data, *kill = NULL;
+ struct vcs_poll_data *poll = file->private_data;
if (poll)
return poll;
@@ -122,12 +122,10 @@ vcs_poll_data_get(struct file *file)
file->private_data = poll;
} else {
/* someone else raced ahead of us */
- kill = poll;
+ vcs_poll_data_free(poll);
poll = file->private_data;
}
spin_unlock(&file->f_lock);
- if (kill)
- vcs_poll_data_free(kill);
return poll;
}
diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index 3b1d6bf..8fd8968 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -539,7 +539,7 @@ static void insert_char(struct vc_data *vc, unsigned int nr)
{
unsigned short *p = (unsigned short *) vc->vc_pos;
- scr_memmovew(p + nr, p, (vc->vc_cols - vc->vc_x - nr) * 2);
+ scr_memmovew(p + nr, p, (vc->vc_cols - vc->vc_x) * 2);
scr_memsetw(p, vc->vc_video_erase_char, nr * 2);
vc->vc_need_wrap = 0;
if (DO_UPDATE(vc))
@@ -638,7 +638,7 @@ static inline void save_screen(struct vc_data *vc)
* Redrawing of screen
*/
-void clear_buffer_attributes(struct vc_data *vc)
+static void clear_buffer_attributes(struct vc_data *vc)
{
unsigned short *p = (unsigned short *)vc->vc_origin;
int count = vc->vc_screenbuf_size / 2;
@@ -2987,7 +2987,7 @@ int __init vty_init(const struct file_operations *console_fops)
static struct class *vtconsole_class;
-static int do_bind_con_driver(const struct consw *csw, int first, int last,
+static int bind_con_driver(const struct consw *csw, int first, int last,
int deflt)
{
struct module *owner = csw->owner;
@@ -2998,7 +2998,7 @@ static int do_bind_con_driver(const struct consw *csw, int first, int last,
if (!try_module_get(owner))
return -ENODEV;
- WARN_CONSOLE_UNLOCKED();
+ console_lock();
/* check if driver is registered */
for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
@@ -3083,22 +3083,11 @@ static int do_bind_con_driver(const struct consw *csw, int first, int last,
retval = 0;
err:
+ console_unlock();
module_put(owner);
return retval;
};
-
-static int bind_con_driver(const struct consw *csw, int first, int last,
- int deflt)
-{
- int ret;
-
- console_lock();
- ret = do_bind_con_driver(csw, first, last, deflt);
- console_unlock();
- return ret;
-}
-
#ifdef CONFIG_VT_HW_CONSOLE_BINDING
static int con_is_graphics(const struct consw *csw, int first, int last)
{
@@ -3135,18 +3124,6 @@ static int con_is_graphics(const struct consw *csw, int first, int last)
*/
int unbind_con_driver(const struct consw *csw, int first, int last, int deflt)
{
- int retval;
-
- console_lock();
- retval = do_unbind_con_driver(csw, first, last, deflt);
- console_unlock();
- return retval;
-}
-EXPORT_SYMBOL(unbind_con_driver);
-
-/* unlocked version of unbind_con_driver() */
-int do_unbind_con_driver(const struct consw *csw, int first, int last, int deflt)
-{
struct module *owner = csw->owner;
const struct consw *defcsw = NULL;
struct con_driver *con_driver = NULL, *con_back = NULL;
@@ -3155,7 +3132,7 @@ int do_unbind_con_driver(const struct consw *csw, int first, int last, int deflt
if (!try_module_get(owner))
return -ENODEV;
- WARN_CONSOLE_UNLOCKED();
+ console_lock();
/* check if driver is registered and if it is unbindable */
for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
@@ -3168,8 +3145,10 @@ int do_unbind_con_driver(const struct consw *csw, int first, int last, int deflt
}
}
- if (retval)
+ if (retval) {
+ console_unlock();
goto err;
+ }
retval = -ENODEV;
@@ -3185,11 +3164,15 @@ int do_unbind_con_driver(const struct consw *csw, int first, int last, int deflt
}
}
- if (retval)
+ if (retval) {
+ console_unlock();
goto err;
+ }
- if (!con_is_bound(csw))
+ if (!con_is_bound(csw)) {
+ console_unlock();
goto err;
+ }
first = max(first, con_driver->first);
last = min(last, con_driver->last);
@@ -3216,14 +3199,15 @@ int do_unbind_con_driver(const struct consw *csw, int first, int last, int deflt
if (!con_is_bound(csw))
con_driver->flag &= ~CON_DRIVER_FLAG_INIT;
+ console_unlock();
/* ignore return value, binding should not fail */
- do_bind_con_driver(defcsw, first, last, deflt);
+ bind_con_driver(defcsw, first, last, deflt);
err:
module_put(owner);
return retval;
}
-EXPORT_SYMBOL_GPL(do_unbind_con_driver);
+EXPORT_SYMBOL(unbind_con_driver);
static int vt_bind(struct con_driver *con)
{
@@ -3508,18 +3492,28 @@ int con_debug_leave(void)
}
EXPORT_SYMBOL_GPL(con_debug_leave);
-static int do_register_con_driver(const struct consw *csw, int first, int last)
+/**
+ * register_con_driver - register console driver to console layer
+ * @csw: console driver
+ * @first: the first console to take over, minimum value is 0
+ * @last: the last console to take over, maximum value is MAX_NR_CONSOLES -1
+ *
+ * DESCRIPTION: This function registers a console driver which can later
+ * bind to a range of consoles specified by @first and @last. It will
+ * also initialize the console driver by calling con_startup().
+ */
+int register_con_driver(const struct consw *csw, int first, int last)
{
struct module *owner = csw->owner;
struct con_driver *con_driver;
const char *desc;
int i, retval = 0;
- WARN_CONSOLE_UNLOCKED();
-
if (!try_module_get(owner))
return -ENODEV;
+ console_lock();
+
for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
con_driver = &registered_con_driver[i];
@@ -3572,27 +3566,8 @@ static int do_register_con_driver(const struct consw *csw, int first, int last)
}
err:
- module_put(owner);
- return retval;
-}
-
-/**
- * register_con_driver - register console driver to console layer
- * @csw: console driver
- * @first: the first console to take over, minimum value is 0
- * @last: the last console to take over, maximum value is MAX_NR_CONSOLES -1
- *
- * DESCRIPTION: This function registers a console driver which can later
- * bind to a range of consoles specified by @first and @last. It will
- * also initialize the console driver by calling con_startup().
- */
-int register_con_driver(const struct consw *csw, int first, int last)
-{
- int retval;
-
- console_lock();
- retval = do_register_con_driver(csw, first, last);
console_unlock();
+ module_put(owner);
return retval;
}
EXPORT_SYMBOL(register_con_driver);
@@ -3610,18 +3585,9 @@ EXPORT_SYMBOL(register_con_driver);
*/
int unregister_con_driver(const struct consw *csw)
{
- int retval;
+ int i, retval = -ENODEV;
console_lock();
- retval = do_unregister_con_driver(csw);
- console_unlock();
- return retval;
-}
-EXPORT_SYMBOL(unregister_con_driver);
-
-int do_unregister_con_driver(const struct consw *csw)
-{
- int i, retval = -ENODEV;
/* cannot unregister a bound driver */
if (con_is_bound(csw))
@@ -3647,53 +3613,27 @@ int do_unregister_con_driver(const struct consw *csw)
}
}
err:
+ console_unlock();
return retval;
}
-EXPORT_SYMBOL_GPL(do_unregister_con_driver);
-
-/*
- * If we support more console drivers, this function is used
- * when a driver wants to take over some existing consoles
- * and become default driver for newly opened ones.
- *
- * take_over_console is basically a register followed by unbind
- */
-int do_take_over_console(const struct consw *csw, int first, int last, int deflt)
-{
- int err;
-
- err = do_register_con_driver(csw, first, last);
- /*
- * If we get an busy error we still want to bind the console driver
- * and return success, as we may have unbound the console driver
- * but not unregistered it.
- */
- if (err == -EBUSY)
- err = 0;
- if (!err)
- do_bind_con_driver(csw, first, last, deflt);
-
- return err;
-}
-EXPORT_SYMBOL_GPL(do_take_over_console);
+EXPORT_SYMBOL(unregister_con_driver);
/*
* If we support more console drivers, this function is used
* when a driver wants to take over some existing consoles
* and become default driver for newly opened ones.
*
- * take_over_console is basically a register followed by unbind
+ * take_over_console is basically a register followed by unbind
*/
int take_over_console(const struct consw *csw, int first, int last, int deflt)
{
int err;
err = register_con_driver(csw, first, last);
- /*
- * If we get an busy error we still want to bind the console driver
+ /* if we get an busy error we still want to bind the console driver
* and return success, as we may have unbound the console driver
- * but not unregistered it.
- */
+  * but not unregistered it.
+ */
if (err == -EBUSY)
err = 0;
if (!err)
diff --git a/drivers/usb/chipidea/debug.c b/drivers/usb/chipidea/debug.c
index a62c4a4..3bc244d 100644
--- a/drivers/usb/chipidea/debug.c
+++ b/drivers/usb/chipidea/debug.c
@@ -222,7 +222,7 @@ static struct {
} dbg_data = {
.idx = 0,
.tty = 0,
- .lck = __RW_LOCK_UNLOCKED(dbg_data.lck)
+ .lck = __RW_LOCK_UNLOCKED(lck)
};
/**
diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
index c0f4066..2f45bba 100644
--- a/drivers/usb/chipidea/udc.c
+++ b/drivers/usb/chipidea/udc.c
@@ -461,8 +461,6 @@ static int _hardware_enqueue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq)
mReq->ptr->page[i] =
(mReq->req.dma + i * CI13XXX_PAGE_SIZE) & ~TD_RESERVED_MASK;
- wmb();
-
if (!list_empty(&mEp->qh.queue)) {
struct ci13xxx_req *mReqPrev;
int n = hw_ep_bit(mEp->num, mEp->dir);
@@ -563,12 +561,6 @@ __acquires(mEp->lock)
struct ci13xxx_req *mReq = \
list_entry(mEp->qh.queue.next,
struct ci13xxx_req, queue);
-
- if (mReq->zptr) {
- dma_pool_free(mEp->td_pool, mReq->zptr, mReq->zdma);
- mReq->zptr = NULL;
- }
-
list_del_init(&mReq->queue);
mReq->req.status = -ESHUTDOWN;
diff --git a/drivers/usb/chipidea/udc.h b/drivers/usb/chipidea/udc.h
index d12e8b5..4ff2384d 100644
--- a/drivers/usb/chipidea/udc.h
+++ b/drivers/usb/chipidea/udc.h
@@ -40,7 +40,7 @@ struct ci13xxx_td {
#define TD_CURR_OFFSET (0x0FFFUL << 0)
#define TD_FRAME_NUM (0x07FFUL << 0)
#define TD_RESERVED_MASK (0x0FFFUL << 0)
-} __attribute__ ((packed, aligned(4)));
+} __attribute__ ((packed));
/* DMA layout of queue heads */
struct ci13xxx_qh {
@@ -57,7 +57,7 @@ struct ci13xxx_qh {
/* 9 */
u32 RESERVED;
struct usb_ctrlrequest setup;
-} __attribute__ ((packed, aligned(4)));
+} __attribute__ ((packed));
/**
* struct ci13xxx_req - usb request representation
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index 35d2cf1..2d92cce 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -600,6 +600,7 @@ static void acm_port_destruct(struct tty_port *port)
dev_dbg(&acm->control->dev, "%s\n", __func__);
+ tty_unregister_device(acm_tty_driver, acm->minor);
acm_release_minor(acm);
usb_put_intf(acm->control);
kfree(acm->country_codes);
@@ -1417,8 +1418,6 @@ static void acm_disconnect(struct usb_interface *intf)
stop_data_traffic(acm);
- tty_unregister_device(acm_tty_driver, acm->minor);
-
usb_free_urb(acm->ctrlurb);
for (i = 0; i < ACM_NW; i++)
usb_free_urb(acm->wb[i].urb);
diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c
index 122d056..5f0cb41 100644
--- a/drivers/usb/class/cdc-wdm.c
+++ b/drivers/usb/class/cdc-wdm.c
@@ -56,7 +56,6 @@ MODULE_DEVICE_TABLE (usb, wdm_ids);
#define WDM_RESPONDING 7
#define WDM_SUSPENDING 8
#define WDM_RESETTING 9
-#define WDM_OVERFLOW 10
#define WDM_MAX 16
@@ -156,7 +155,6 @@ static void wdm_in_callback(struct urb *urb)
{
struct wdm_device *desc = urb->context;
int status = urb->status;
- int length = urb->actual_length;
spin_lock(&desc->iuspin);
clear_bit(WDM_RESPONDING, &desc->flags);
@@ -187,17 +185,9 @@ static void wdm_in_callback(struct urb *urb)
}
desc->rerr = status;
- if (length + desc->length > desc->wMaxCommand) {
- /* The buffer would overflow */
- set_bit(WDM_OVERFLOW, &desc->flags);
- } else {
- /* we may already be in overflow */
- if (!test_bit(WDM_OVERFLOW, &desc->flags)) {
- memmove(desc->ubuf + desc->length, desc->inbuf, length);
- desc->length += length;
- desc->reslength = length;
- }
- }
+ desc->reslength = urb->actual_length;
+ memmove(desc->ubuf + desc->length, desc->inbuf, desc->reslength);
+ desc->length += desc->reslength;
skip_error:
wake_up(&desc->wait);
@@ -445,11 +435,6 @@ retry:
rv = -ENODEV;
goto err;
}
- if (test_bit(WDM_OVERFLOW, &desc->flags)) {
- clear_bit(WDM_OVERFLOW, &desc->flags);
- rv = -ENOBUFS;
- goto err;
- }
i++;
if (file->f_flags & O_NONBLOCK) {
if (!test_bit(WDM_READ, &desc->flags)) {
@@ -493,7 +478,6 @@ retry:
spin_unlock_irq(&desc->iuspin);
goto retry;
}
-
if (!desc->reslength) { /* zero length read */
dev_dbg(&desc->intf->dev, "%s: zero length - clearing WDM_READ\n", __func__);
clear_bit(WDM_READ, &desc->flags);
@@ -1020,7 +1004,6 @@ static int wdm_post_reset(struct usb_interface *intf)
struct wdm_device *desc = wdm_find_device(intf);
int rv;
- clear_bit(WDM_OVERFLOW, &desc->flags);
clear_bit(WDM_RESETTING, &desc->flags);
rv = recover_from_urb_loss(desc);
mutex_unlock(&desc->wlock);
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
index ea0a9a1..b78fbe2 100644
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -738,8 +738,6 @@ static int check_ctrlrecip(struct dev_state *ps, unsigned int requesttype,
index &= 0xff;
switch (requesttype & USB_RECIP_MASK) {
case USB_RECIP_ENDPOINT:
- if ((index & ~USB_DIR_IN) == 0)
- return 0;
ret = findintfep(ps->dev, index);
if (ret >= 0)
ret = checkintf(ps, ret);
diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c
index 2b487d4..622b4a4 100644
--- a/drivers/usb/core/hcd-pci.c
+++ b/drivers/usb/core/hcd-pci.c
@@ -173,7 +173,6 @@ int usb_hcd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
struct hc_driver *driver;
struct usb_hcd *hcd;
int retval;
- int hcd_irq = 0;
if (usb_disabled())
return -ENODEV;
@@ -188,19 +187,15 @@ int usb_hcd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
return -ENODEV;
dev->current_state = PCI_D0;
- /*
- * The xHCI driver has its own irq management
- * make sure irq setup is not touched for xhci in generic hcd code
+ /* The xHCI driver supports MSI and MSI-X,
+ * so don't fail if the BIOS doesn't provide a legacy IRQ.
*/
- if ((driver->flags & HCD_MASK) != HCD_USB3) {
- if (!dev->irq) {
- dev_err(&dev->dev,
- "Found HC with no IRQ. Check BIOS/PCI %s setup!\n",
- pci_name(dev));
- retval = -ENODEV;
- goto disable_pci;
- }
- hcd_irq = dev->irq;
+ if (!dev->irq && (driver->flags & HCD_MASK) != HCD_USB3) {
+ dev_err(&dev->dev,
+ "Found HC with no IRQ. Check BIOS/PCI %s setup!\n",
+ pci_name(dev));
+ retval = -ENODEV;
+ goto disable_pci;
}
hcd = usb_create_hcd(driver, &dev->dev, pci_name(dev));
@@ -250,7 +245,7 @@ int usb_hcd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
pci_set_master(dev);
- retval = usb_add_hcd(hcd, hcd_irq, IRQF_SHARED);
+ retval = usb_add_hcd(hcd, dev->irq, IRQF_SHARED);
if (retval != 0)
goto unmap_registers;
set_hs_companion(dev, hcd);
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 59c4d3c..8e64adf 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -2217,7 +2217,7 @@ irqreturn_t usb_hcd_irq (int irq, void *__hcd)
* when the first handler doesn't use it. So let's just
* assume it's never used.
*/
- local_irq_save_nort(flags);
+ local_irq_save(flags);
if (unlikely(HCD_DEAD(hcd) || !HCD_HW_ACCESSIBLE(hcd)))
rc = IRQ_NONE;
@@ -2226,7 +2226,7 @@ irqreturn_t usb_hcd_irq (int irq, void *__hcd)
else
rc = IRQ_HANDLED;
- local_irq_restore_nort(flags);
+ local_irq_restore(flags);
return rc;
}
EXPORT_SYMBOL_GPL(usb_hcd_irq);
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 2a89588..cbf7168 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -2538,35 +2538,70 @@ static int hub_port_wait_reset(struct usb_hub *hub, int port1,
if ((portstatus & USB_PORT_STAT_RESET))
goto delay;
- if (hub_port_warm_reset_required(hub, portstatus))
- return -ENOTCONN;
-
- /* Device went away? */
- if (!(portstatus & USB_PORT_STAT_CONNECTION))
- return -ENOTCONN;
-
- /* bomb out completely if the connection bounced. A USB 3.0
- * connection may bounce if multiple warm resets were issued,
- * but the device may have successfully re-connected. Ignore it.
+ /*
+ * Some buggy devices require a warm reset to be issued even
+ * when the port appears not to be connected.
*/
- if (!hub_is_superspeed(hub->hdev) &&
- (portchange & USB_PORT_STAT_C_CONNECTION))
- return -ENOTCONN;
-
- if ((portstatus & USB_PORT_STAT_ENABLE)) {
- if (!udev)
+ if (!warm) {
+ /*
+ * Some buggy devices can cause an NEC host controller
+ * to transition to the "Error" state after a hot port
+ * reset. This will show up as the port state in
+ * "Inactive", and the port may also report a
+ * disconnect. Forcing a warm port reset seems to make
+ * the device work.
+ *
+ * See https://bugzilla.kernel.org/show_bug.cgi?id=41752
+ */
+ if (hub_port_warm_reset_required(hub, portstatus)) {
+ int ret;
+
+ if ((portchange & USB_PORT_STAT_C_CONNECTION))
+ clear_port_feature(hub->hdev, port1,
+ USB_PORT_FEAT_C_CONNECTION);
+ if (portchange & USB_PORT_STAT_C_LINK_STATE)
+ clear_port_feature(hub->hdev, port1,
+ USB_PORT_FEAT_C_PORT_LINK_STATE);
+ if (portchange & USB_PORT_STAT_C_RESET)
+ clear_port_feature(hub->hdev, port1,
+ USB_PORT_FEAT_C_RESET);
+ dev_dbg(hub->intfdev, "hot reset failed, warm reset port %d\n",
+ port1);
+ ret = hub_port_reset(hub, port1,
+ udev, HUB_BH_RESET_TIME,
+ true);
+ if ((portchange & USB_PORT_STAT_C_CONNECTION))
+ clear_port_feature(hub->hdev, port1,
+ USB_PORT_FEAT_C_CONNECTION);
+ return ret;
+ }
+ /* Device went away? */
+ if (!(portstatus & USB_PORT_STAT_CONNECTION))
+ return -ENOTCONN;
+
+ /* bomb out completely if the connection bounced */
+ if ((portchange & USB_PORT_STAT_C_CONNECTION))
+ return -ENOTCONN;
+
+ if ((portstatus & USB_PORT_STAT_ENABLE)) {
+ if (hub_is_wusb(hub))
+ udev->speed = USB_SPEED_WIRELESS;
+ else if (hub_is_superspeed(hub->hdev))
+ udev->speed = USB_SPEED_SUPER;
+ else if (portstatus & USB_PORT_STAT_HIGH_SPEED)
+ udev->speed = USB_SPEED_HIGH;
+ else if (portstatus & USB_PORT_STAT_LOW_SPEED)
+ udev->speed = USB_SPEED_LOW;
+ else
+ udev->speed = USB_SPEED_FULL;
return 0;
+ }
+ } else {
+ if (!(portstatus & USB_PORT_STAT_CONNECTION) ||
+ hub_port_warm_reset_required(hub,
+ portstatus))
+ return -ENOTCONN;
- if (hub_is_wusb(hub))
- udev->speed = USB_SPEED_WIRELESS;
- else if (hub_is_superspeed(hub->hdev))
- udev->speed = USB_SPEED_SUPER;
- else if (portstatus & USB_PORT_STAT_HIGH_SPEED)
- udev->speed = USB_SPEED_HIGH;
- else if (portstatus & USB_PORT_STAT_LOW_SPEED)
- udev->speed = USB_SPEED_LOW;
- else
- udev->speed = USB_SPEED_FULL;
return 0;
}
@@ -2584,16 +2619,16 @@ delay:
}
static void hub_port_finish_reset(struct usb_hub *hub, int port1,
- struct usb_device *udev, int *status)
+ struct usb_device *udev, int *status, bool warm)
{
switch (*status) {
case 0:
- /* TRSTRCY = 10 ms; plus some extra */
- msleep(10 + 40);
- if (udev) {
- struct usb_hcd *hcd = bus_to_hcd(udev->bus);
-
+ if (!warm) {
+ struct usb_hcd *hcd;
+ /* TRSTRCY = 10 ms; plus some extra */
+ msleep(10 + 40);
update_devnum(udev, 0);
+ hcd = bus_to_hcd(udev->bus);
/* The xHC may think the device is already reset,
* so ignore the status.
*/
@@ -2605,15 +2640,14 @@ static void hub_port_finish_reset(struct usb_hub *hub, int port1,
case -ENODEV:
clear_port_feature(hub->hdev,
port1, USB_PORT_FEAT_C_RESET);
+ /* FIXME need disconnect() for NOTATTACHED device */
if (hub_is_superspeed(hub->hdev)) {
clear_port_feature(hub->hdev, port1,
USB_PORT_FEAT_C_BH_PORT_RESET);
clear_port_feature(hub->hdev, port1,
USB_PORT_FEAT_C_PORT_LINK_STATE);
- clear_port_feature(hub->hdev, port1,
- USB_PORT_FEAT_C_CONNECTION);
}
- if (udev)
+ if (!warm)
usb_set_device_state(udev, *status
? USB_STATE_NOTATTACHED
: USB_STATE_DEFAULT);
@@ -2626,30 +2660,18 @@ static int hub_port_reset(struct usb_hub *hub, int port1,
struct usb_device *udev, unsigned int delay, bool warm)
{
int i, status;
- u16 portchange, portstatus;
- if (!hub_is_superspeed(hub->hdev)) {
- if (warm) {
- dev_err(hub->intfdev, "only USB3 hub support "
- "warm reset\n");
- return -EINVAL;
- }
+ if (!warm) {
/* Block EHCI CF initialization during the port reset.
* Some companion controllers don't like it when they mix.
*/
down_read(&ehci_cf_port_reset_rwsem);
- } else if (!warm) {
- /*
- * If the caller hasn't explicitly requested a warm reset,
- * double check and see if one is needed.
- */
- status = hub_port_status(hub, port1,
- &portstatus, &portchange);
- if (status < 0)
- goto done;
-
- if (hub_port_warm_reset_required(hub, portstatus))
- warm = true;
+ } else {
+ if (!hub_is_superspeed(hub->hdev)) {
+ dev_err(hub->intfdev, "only USB3 hub support "
+ "warm reset\n");
+ return -EINVAL;
+ }
}
/* Reset the port */
@@ -2670,33 +2692,10 @@ static int hub_port_reset(struct usb_hub *hub, int port1,
status);
}
- /* Check for disconnect or reset */
+ /* return on disconnect or reset */
if (status == 0 || status == -ENOTCONN || status == -ENODEV) {
- hub_port_finish_reset(hub, port1, udev, &status);
-
- if (!hub_is_superspeed(hub->hdev))
- goto done;
-
- /*
- * If a USB 3.0 device migrates from reset to an error
- * state, re-issue the warm reset.
- */
- if (hub_port_status(hub, port1,
- &portstatus, &portchange) < 0)
- goto done;
-
- if (!hub_port_warm_reset_required(hub, portstatus))
- goto done;
-
- /*
- * If the port is in SS.Inactive or Compliance Mode, the
- * hot or warm reset failed. Try another warm reset.
- */
- if (!warm) {
- dev_dbg(hub->intfdev, "hot reset failed, warm reset port %d\n",
- port1);
- warm = true;
- }
+ hub_port_finish_reset(hub, port1, udev, &status, warm);
+ goto done;
}
dev_dbg (hub->intfdev,
@@ -2710,7 +2709,7 @@ static int hub_port_reset(struct usb_hub *hub, int port1,
port1);
done:
- if (!hub_is_superspeed(hub->hdev))
+ if (!warm)
up_read(&ehci_cf_port_reset_rwsem);
return status;
@@ -4741,21 +4740,12 @@ static void hub_events(void)
*/
if (hub_port_warm_reset_required(hub, portstatus)) {
int status;
- struct usb_device *udev =
- hub->ports[i - 1]->child;
dev_dbg(hub_dev, "warm reset port %d\n", i);
- if (!udev) {
- status = hub_port_reset(hub, i,
- NULL, HUB_BH_RESET_TIME,
- true);
- if (status < 0)
- hub_port_disable(hub, i, 1);
- } else {
- usb_lock_device(udev);
- status = usb_reset_device(udev);
- usb_unlock_device(udev);
- }
+ status = hub_port_reset(hub, i, NULL,
+ HUB_BH_RESET_TIME, true);
+ if (status < 0)
+ hub_port_disable(hub, i, 1);
connect_change = 0;
}
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index f00c749..3a4004a 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -575,7 +575,6 @@ static int dwc3_remove(struct platform_device *pdev)
break;
}
- dwc3_free_event_buffers(dwc);
dwc3_core_exit(dwc);
return 0;
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 1dae91d..4999563 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -405,6 +405,7 @@ struct dwc3_event_buffer {
* @number: endpoint number (1 - 15)
* @type: set to bmAttributes & USB_ENDPOINT_XFERTYPE_MASK
* @resource_index: Resource transfer index
+ * @current_uf: Current uf received through last event parameter
* @interval: the intervall on which the ISOC transfer is started
* @name: a human readable name e.g. ep1out-bulk
* @direction: true for TX, false for RX
@@ -438,6 +439,7 @@ struct dwc3_ep {
u8 number;
u8 type;
u8 resource_index;
+ u16 current_uf;
u32 interval;
char name[20];
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 09835b6..2fdd767 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -754,19 +754,22 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep,
struct dwc3 *dwc = dep->dwc;
struct dwc3_trb *trb;
+ unsigned int cur_slot;
+
dev_vdbg(dwc->dev, "%s: req %p dma %08llx length %d%s%s\n",
dep->name, req, (unsigned long long) dma,
length, last ? " last" : "",
chain ? " chain" : "");
- /* Skip the LINK-TRB on ISOC */
- if (((dep->free_slot & DWC3_TRB_MASK) == DWC3_TRB_NUM - 1) &&
- usb_endpoint_xfer_isoc(dep->endpoint.desc))
- dep->free_slot++;
-
trb = &dep->trb_pool[dep->free_slot & DWC3_TRB_MASK];
+ cur_slot = dep->free_slot;
dep->free_slot++;
+ /* Skip the LINK-TRB on ISOC */
+ if (((cur_slot & DWC3_TRB_MASK) == DWC3_TRB_NUM - 1) &&
+ usb_endpoint_xfer_isoc(dep->endpoint.desc))
+ return;
+
if (!req->trb) {
dwc3_gadget_move_request_queued(req);
req->trb = trb;
@@ -1088,10 +1091,7 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req)
* notion of current microframe.
*/
if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) {
- if (list_empty(&dep->req_queued)) {
- dwc3_stop_active_transfer(dwc, dep->number);
- dep->flags = DWC3_EP_ENABLED;
- }
+ dwc3_stop_active_transfer(dwc, dep->number);
return 0;
}
@@ -1117,6 +1117,16 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req)
dep->name);
}
+ /*
+ * 3. Missed ISOC Handling. We need to start isoc transfer on the saved
+ * uframe number.
+ */
+ if (usb_endpoint_xfer_isoc(dep->endpoint.desc) &&
+ (dep->flags & DWC3_EP_MISSED_ISOC)) {
+ __dwc3_gadget_start_isoc(dwc, dep, dep->current_uf);
+ dep->flags &= ~DWC3_EP_MISSED_ISOC;
+ }
+
return 0;
}
@@ -1679,29 +1689,14 @@ static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, struct dwc3_ep *dep,
if (trb_status == DWC3_TRBSTS_MISSED_ISOC) {
dev_dbg(dwc->dev, "incomplete IN transfer %s\n",
dep->name);
- /*
- * If missed isoc occurred and there is
- * no request queued then issue END
- * TRANSFER, so that core generates
- * next xfernotready and we will issue
- * a fresh START TRANSFER.
- * If there are still queued request
- * then wait, do not issue either END
- * or UPDATE TRANSFER, just attach next
- * request in request_list during
- * giveback.If any future queued request
- * is successfully transferred then we
- * will issue UPDATE TRANSFER for all
- * request in the request_list.
- */
+ dep->current_uf = event->parameters &
+ ~(dep->interval - 1);
dep->flags |= DWC3_EP_MISSED_ISOC;
} else {
dev_err(dwc->dev, "incomplete IN transfer %s\n",
dep->name);
status = -ECONNRESET;
}
- } else {
- dep->flags &= ~DWC3_EP_MISSED_ISOC;
}
} else {
if (count && (event->status & DEPEVT_STATUS_SHORT))
@@ -1728,23 +1723,6 @@ static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, struct dwc3_ep *dep,
break;
} while (1);
- if (usb_endpoint_xfer_isoc(dep->endpoint.desc) &&
- list_empty(&dep->req_queued)) {
- if (list_empty(&dep->request_list)) {
- /*
- * If there is no entry in request list then do
- * not issue END TRANSFER now. Just set PENDING
- * flag, so that END TRANSFER is issued when an
- * entry is added into request list.
- */
- dep->flags = DWC3_EP_PENDING_REQUEST;
- } else {
- dwc3_stop_active_transfer(dwc, dep->number);
- dep->flags = DWC3_EP_ENABLED;
- }
- return 1;
- }
-
if ((event->status & DEPEVT_STATUS_IOC) &&
(trb->ctrl & DWC3_TRB_CTRL_IOC))
return 0;
@@ -2179,26 +2157,6 @@ static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc)
break;
}
- /* Enable USB2 LPM Capability */
-
- if ((dwc->revision > DWC3_REVISION_194A)
- && (speed != DWC3_DCFG_SUPERSPEED)) {
- reg = dwc3_readl(dwc->regs, DWC3_DCFG);
- reg |= DWC3_DCFG_LPM_CAP;
- dwc3_writel(dwc->regs, DWC3_DCFG, reg);
-
- reg = dwc3_readl(dwc->regs, DWC3_DCTL);
- reg &= ~(DWC3_DCTL_HIRD_THRES_MASK | DWC3_DCTL_L1_HIBER_EN);
-
- /*
- * TODO: This should be configurable. For now using
- * maximum allowed HIRD threshold value of 0b1100
- */
- reg |= DWC3_DCTL_HIRD_THRES(12);
-
- dwc3_writel(dwc->regs, DWC3_DCTL, reg);
- }
-
/* Recent versions support automatic phy suspend and don't need this */
if (dwc->revision < DWC3_REVISION_194A) {
/* Suspend unneeded PHY */
@@ -2505,8 +2463,20 @@ int dwc3_gadget_init(struct dwc3 *dwc)
DWC3_DEVTEN_DISCONNEVTEN);
dwc3_writel(dwc->regs, DWC3_DEVTEN, reg);
- /* automatic phy suspend only on recent versions */
+ /* Enable USB2 LPM and automatic phy suspend only on recent versions */
if (dwc->revision >= DWC3_REVISION_194A) {
+ reg = dwc3_readl(dwc->regs, DWC3_DCFG);
+ reg |= DWC3_DCFG_LPM_CAP;
+ dwc3_writel(dwc->regs, DWC3_DCFG, reg);
+
+ reg = dwc3_readl(dwc->regs, DWC3_DCTL);
+ reg &= ~(DWC3_DCTL_HIRD_THRES_MASK | DWC3_DCTL_L1_HIBER_EN);
+
+ /* TODO: This should be configurable */
+ reg |= DWC3_DCTL_HIRD_THRES(28);
+
+ dwc3_writel(dwc->regs, DWC3_DCTL, reg);
+
dwc3_gadget_usb2_phy_suspend(dwc, false);
dwc3_gadget_usb3_phy_suspend(dwc, false);
}
diff --git a/drivers/usb/gadget/g_ffs.c b/drivers/usb/gadget/g_ffs.c
index 3b343b2..3953dd4 100644
--- a/drivers/usb/gadget/g_ffs.c
+++ b/drivers/usb/gadget/g_ffs.c
@@ -357,7 +357,7 @@ static int gfs_bind(struct usb_composite_dev *cdev)
goto error;
gfs_dev_desc.iProduct = gfs_strings[USB_GADGET_PRODUCT_IDX].id;
- for (i = func_num; i--; ) {
+ for (i = func_num; --i; ) {
ret = functionfs_bind(ffs_tab[i].ffs_data, cdev);
if (unlikely(ret < 0)) {
while (++i < func_num)
@@ -413,7 +413,7 @@ static int gfs_unbind(struct usb_composite_dev *cdev)
gether_cleanup();
gfs_ether_setup = false;
- for (i = func_num; i--; )
+ for (i = func_num; --i; )
if (ffs_tab[i].ffs_data)
functionfs_unbind(ffs_tab[i].ffs_data);
diff --git a/drivers/usb/gadget/udc-core.c b/drivers/usb/gadget/udc-core.c
index 34a3907..4d90a80 100644
--- a/drivers/usb/gadget/udc-core.c
+++ b/drivers/usb/gadget/udc-core.c
@@ -265,7 +265,7 @@ static void usb_gadget_remove_driver(struct usb_udc *udc)
usb_gadget_disconnect(udc->gadget);
udc->driver->disconnect(udc->gadget);
udc->driver->unbind(udc->gadget);
- usb_gadget_udc_stop(udc->gadget, NULL);
+ usb_gadget_udc_stop(udc->gadget, udc->driver);
} else {
usb_gadget_stop(udc->gadget, udc->driver);
}
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 83b5a172..b416a3f 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -302,7 +302,6 @@ static void ehci_quiesce (struct ehci_hcd *ehci)
static void end_unlink_async(struct ehci_hcd *ehci);
static void unlink_empty_async(struct ehci_hcd *ehci);
-static void unlink_empty_async_suspended(struct ehci_hcd *ehci);
static void ehci_work(struct ehci_hcd *ehci);
static void start_unlink_intr(struct ehci_hcd *ehci, struct ehci_qh *qh);
static void end_unlink_intr(struct ehci_hcd *ehci, struct ehci_qh *qh);
@@ -670,6 +669,9 @@ int ehci_setup(struct usb_hcd *hcd)
if (retval)
return retval;
+ if (ehci_is_TDI(ehci))
+ tdi_reset(ehci);
+
ehci_reset(ehci);
return 0;
@@ -746,9 +748,11 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
/* guard against (alleged) silicon errata */
if (cmd & CMD_IAAD)
ehci_dbg(ehci, "IAA with IAAD still set?\n");
- if (ehci->async_iaa)
+ if (ehci->async_iaa) {
COUNT(ehci->stats.iaa);
- end_unlink_async(ehci);
+ end_unlink_async(ehci);
+ } else
+ ehci_dbg(ehci, "IAA with nothing unlinked?\n");
}
/* remote wakeup [4.3.1] */
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
index 7d06e77..4d3b294 100644
--- a/drivers/usb/host/ehci-hub.c
+++ b/drivers/usb/host/ehci-hub.c
@@ -328,7 +328,7 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
ehci->rh_state = EHCI_RH_SUSPENDED;
end_unlink_async(ehci);
- unlink_empty_async_suspended(ehci);
+ unlink_empty_async(ehci);
ehci_handle_intr_unlinks(ehci);
end_free_itds(ehci);
diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c
index 99899e8..ac17a7c 100644
--- a/drivers/usb/host/ehci-omap.c
+++ b/drivers/usb/host/ehci-omap.c
@@ -288,6 +288,7 @@ static int ehci_hcd_omap_remove(struct platform_device *pdev)
{
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);
@@ -297,6 +298,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;
}
@@ -364,7 +372,7 @@ static const struct hc_driver ehci_omap_hc_driver = {
.clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
};
-MODULE_ALIAS("platform:ehci-omap");
+MODULE_ALIAS("platform:omap-ehci");
MODULE_AUTHOR("Texas Instruments, Inc.");
MODULE_AUTHOR("Felipe Balbi <felipe.balbi@nokia.com>");
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c
index 23d1369..fd252f0 100644
--- a/drivers/usb/host/ehci-q.c
+++ b/drivers/usb/host/ehci-q.c
@@ -135,7 +135,7 @@ qh_refresh (struct ehci_hcd *ehci, struct ehci_qh *qh)
* qtd is updated in qh_completions(). Update the QH
* overlay here.
*/
- if (qh->hw->hw_token & ACTIVE_BIT(ehci)) {
+ if (cpu_to_hc32(ehci, qtd->qtd_dma) == qh->hw->hw_current) {
qh->hw->hw_qtd_next = qtd->hw_next;
qtd = NULL;
}
@@ -449,19 +449,11 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh)
else if (last_status == -EINPROGRESS && !urb->unlinked)
continue;
- /*
- * If this was the active qtd when the qh was unlinked
- * and the overlay's token is active, then the overlay
- * hasn't been written back to the qtd yet so use its
- * token instead of the qtd's. After the qtd is
- * processed and removed, the overlay won't be valid
- * any more.
- */
- if (state == QH_STATE_IDLE &&
- qh->qtd_list.next == &qtd->qtd_list &&
- (hw->hw_token & ACTIVE_BIT(ehci))) {
+ /* qh unlinked; token in overlay may be most current */
+ if (state == QH_STATE_IDLE
+ && cpu_to_hc32(ehci, qtd->qtd_dma)
+ == hw->hw_current) {
token = hc32_to_cpu(ehci, hw->hw_token);
- hw->hw_token &= ~ACTIVE_BIT(ehci);
/* An unlink may leave an incomplete
* async transaction in the TT buffer.
@@ -1178,7 +1170,7 @@ static void single_unlink_async(struct ehci_hcd *ehci, struct ehci_qh *qh)
struct ehci_qh *prev;
/* Add to the end of the list of QHs waiting for the next IAAD */
- qh->qh_state = QH_STATE_UNLINK_WAIT;
+ qh->qh_state = QH_STATE_UNLINK;
if (ehci->async_unlink)
ehci->async_unlink_last->unlink_next = qh;
else
@@ -1221,19 +1213,9 @@ static void start_iaa_cycle(struct ehci_hcd *ehci, bool nested)
/* Do only the first waiting QH (nVidia bug?) */
qh = ehci->async_unlink;
-
- /*
- * Intel (?) bug: The HC can write back the overlay region
- * even after the IAA interrupt occurs. In self-defense,
- * always go through two IAA cycles for each QH.
- */
- if (qh->qh_state == QH_STATE_UNLINK_WAIT) {
- qh->qh_state = QH_STATE_UNLINK;
- } else {
- ehci->async_iaa = qh;
- ehci->async_unlink = qh->unlink_next;
- qh->unlink_next = NULL;
- }
+ ehci->async_iaa = qh;
+ ehci->async_unlink = qh->unlink_next;
+ qh->unlink_next = NULL;
/* Make sure the unlinks are all visible to the hardware */
wmb();
@@ -1316,19 +1298,6 @@ static void unlink_empty_async(struct ehci_hcd *ehci)
}
}
-/* The root hub is suspended; unlink all the async QHs */
-static void unlink_empty_async_suspended(struct ehci_hcd *ehci)
-{
- struct ehci_qh *qh;
-
- while (ehci->async->qh_next.qh) {
- qh = ehci->async->qh_next.qh;
- WARN_ON(!list_empty(&qh->qtd_list));
- single_unlink_async(ehci, qh);
- }
- start_iaa_cycle(ehci, false);
-}
-
/* makes sure the async qh will become idle */
/* caller must own ehci->lock */
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
index 010f686..b476daf 100644
--- a/drivers/usb/host/ehci-sched.c
+++ b/drivers/usb/host/ehci-sched.c
@@ -1214,7 +1214,6 @@ itd_urb_transaction (
memset (itd, 0, sizeof *itd);
itd->itd_dma = itd_dma;
- itd->frame = 9999; /* an invalid value */
list_add (&itd->itd_list, &sched->td_list);
}
spin_unlock_irqrestore (&ehci->lock, flags);
@@ -1916,7 +1915,6 @@ sitd_urb_transaction (
memset (sitd, 0, sizeof *sitd);
sitd->sitd_dma = sitd_dma;
- sitd->frame = 9999; /* an invalid value */
list_add (&sitd->sitd_list, &iso_sched->td_list);
}
diff --git a/drivers/usb/host/ehci-timer.c b/drivers/usb/host/ehci-timer.c
index c3fa130..f904071 100644
--- a/drivers/usb/host/ehci-timer.c
+++ b/drivers/usb/host/ehci-timer.c
@@ -113,14 +113,15 @@ static void ehci_poll_ASS(struct ehci_hcd *ehci)
if (want != actual) {
- /* Poll again later, but give up after about 20 ms */
- if (ehci->ASS_poll_count++ < 20) {
- ehci_enable_event(ehci, EHCI_HRTIMER_POLL_ASS, true);
- return;
- }
- ehci_dbg(ehci, "Waited too long for the async schedule status (%x/%x), giving up\n",
- want, actual);
+ /* Poll again later */
+ ehci_enable_event(ehci, EHCI_HRTIMER_POLL_ASS, true);
+ ++ehci->ASS_poll_count;
+ return;
}
+
+ if (ehci->ASS_poll_count > 20)
+ ehci_dbg(ehci, "ASS poll count reached %d\n",
+ ehci->ASS_poll_count);
ehci->ASS_poll_count = 0;
/* The status is up-to-date; restart or stop the schedule as needed */
@@ -159,14 +160,14 @@ static void ehci_poll_PSS(struct ehci_hcd *ehci)
if (want != actual) {
- /* Poll again later, but give up after about 20 ms */
- if (ehci->PSS_poll_count++ < 20) {
- ehci_enable_event(ehci, EHCI_HRTIMER_POLL_PSS, true);
- return;
- }
- ehci_dbg(ehci, "Waited too long for the periodic schedule status (%x/%x), giving up\n",
- want, actual);
+ /* Poll again later */
+ ehci_enable_event(ehci, EHCI_HRTIMER_POLL_PSS, true);
+ return;
}
+
+ if (ehci->PSS_poll_count > 20)
+ ehci_dbg(ehci, "PSS poll count reached %d\n",
+ ehci->PSS_poll_count);
ehci->PSS_poll_count = 0;
/* The status is up-to-date; restart or stop the schedule as needed */
@@ -304,7 +305,7 @@ static void ehci_iaa_watchdog(struct ehci_hcd *ehci)
* (a) SMP races against real IAA firing and retriggering, and
* (b) clean HC shutdown, when IAA watchdog was pending.
*/
- if (1) {
+ if (ehci->async_iaa) {
u32 cmd, status;
/* If we get here, IAA is *REALLY* late. It's barely
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 1a3e81a..180a2b0 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -857,13 +857,9 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd)
}
if (ints & OHCI_INTR_WDH) {
- if (ohci->hcca->done_head == 0) {
- ints &= ~OHCI_INTR_WDH;
- } else {
- spin_lock (&ohci->lock);
- dl_done_list (ohci);
- spin_unlock (&ohci->lock);
- }
+ spin_lock (&ohci->lock);
+ dl_done_list (ohci);
+ spin_unlock (&ohci->lock);
}
if (quirk_zfmicro(ohci) && (ints & OHCI_INTR_SF)) {
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 2573cf4..7f76a49 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -2027,8 +2027,8 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td,
if (event_trb != ep_ring->dequeue &&
event_trb != td->last_trb)
td->urb->actual_length =
- td->urb->transfer_buffer_length -
- EVENT_TRB_LEN(le32_to_cpu(event->transfer_len));
+ td->urb->transfer_buffer_length
+ - TRB_LEN(le32_to_cpu(event->transfer_len));
else
td->urb->actual_length = 0;
@@ -2060,7 +2060,7 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td,
/* Maybe the event was for the data stage? */
td->urb->actual_length =
td->urb->transfer_buffer_length -
- EVENT_TRB_LEN(le32_to_cpu(event->transfer_len));
+ TRB_LEN(le32_to_cpu(event->transfer_len));
xhci_dbg(xhci, "Waiting for status "
"stage event\n");
return 0;
@@ -2096,7 +2096,7 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td,
/* handle completion code */
switch (trb_comp_code) {
case COMP_SUCCESS:
- if (EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)) == 0) {
+ if (TRB_LEN(le32_to_cpu(event->transfer_len)) == 0) {
frame->status = 0;
break;
}
@@ -2141,7 +2141,7 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td,
len += TRB_LEN(le32_to_cpu(cur_trb->generic.field[2]));
}
len += TRB_LEN(le32_to_cpu(cur_trb->generic.field[2])) -
- EVENT_TRB_LEN(le32_to_cpu(event->transfer_len));
+ TRB_LEN(le32_to_cpu(event->transfer_len));
if (trb_comp_code != COMP_STOP_INVAL) {
frame->actual_length = len;
@@ -2199,7 +2199,7 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_td *td,
case COMP_SUCCESS:
/* Double check that the HW transferred everything. */
if (event_trb != td->last_trb ||
- EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)) != 0) {
+ TRB_LEN(le32_to_cpu(event->transfer_len)) != 0) {
xhci_warn(xhci, "WARN Successful completion "
"on short TX\n");
if (td->urb->transfer_flags & URB_SHORT_NOT_OK)
@@ -2227,18 +2227,18 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_td *td,
"%d bytes untransferred\n",
td->urb->ep->desc.bEndpointAddress,
td->urb->transfer_buffer_length,
- EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)));
+ TRB_LEN(le32_to_cpu(event->transfer_len)));
/* Fast path - was this the last TRB in the TD for this URB? */
if (event_trb == td->last_trb) {
- if (EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)) != 0) {
+ if (TRB_LEN(le32_to_cpu(event->transfer_len)) != 0) {
td->urb->actual_length =
td->urb->transfer_buffer_length -
- EVENT_TRB_LEN(le32_to_cpu(event->transfer_len));
+ TRB_LEN(le32_to_cpu(event->transfer_len));
if (td->urb->transfer_buffer_length <
td->urb->actual_length) {
xhci_warn(xhci, "HC gave bad length "
"of %d bytes left\n",
- EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)));
+ TRB_LEN(le32_to_cpu(event->transfer_len)));
td->urb->actual_length = 0;
if (td->urb->transfer_flags & URB_SHORT_NOT_OK)
*status = -EREMOTEIO;
@@ -2280,7 +2280,7 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_td *td,
if (trb_comp_code != COMP_STOP_INVAL)
td->urb->actual_length +=
TRB_LEN(le32_to_cpu(cur_trb->generic.field[2])) -
- EVENT_TRB_LEN(le32_to_cpu(event->transfer_len));
+ TRB_LEN(le32_to_cpu(event->transfer_len));
}
return finish_td(xhci, td, event_trb, event, ep, status, false);
@@ -2368,7 +2368,7 @@ static int handle_tx_event(struct xhci_hcd *xhci,
* transfer type
*/
case COMP_SUCCESS:
- if (EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)) == 0)
+ if (TRB_LEN(le32_to_cpu(event->transfer_len)) == 0)
break;
if (xhci->quirks & XHCI_TRUST_TX_LENGTH)
trb_comp_code = COMP_SHORT_TX;
@@ -2461,21 +2461,14 @@ static int handle_tx_event(struct xhci_hcd *xhci,
* TD list.
*/
if (list_empty(&ep_ring->td_list)) {
- /*
- * A stopped endpoint may generate an extra completion
- * event if the device was suspended. Don't print
- * warnings.
- */
- if (!(trb_comp_code == COMP_STOP ||
- trb_comp_code == COMP_STOP_INVAL)) {
- xhci_warn(xhci, "WARN Event TRB for slot %d ep %d with no TDs queued?\n",
- TRB_TO_SLOT_ID(le32_to_cpu(event->flags)),
- ep_index);
- xhci_dbg(xhci, "Event TRB with TRB type ID %u\n",
- (le32_to_cpu(event->flags) &
- TRB_TYPE_BITMASK)>>10);
- xhci_print_trb_offsets(xhci, (union xhci_trb *) event);
- }
+ xhci_warn(xhci, "WARN Event TRB for slot %d ep %d "
+ "with no TDs queued?\n",
+ TRB_TO_SLOT_ID(le32_to_cpu(event->flags)),
+ ep_index);
+ xhci_dbg(xhci, "Event TRB with TRB type ID %u\n",
+ (le32_to_cpu(event->flags) &
+ TRB_TYPE_BITMASK)>>10);
+ xhci_print_trb_offsets(xhci, (union xhci_trb *) event);
if (ep->skip) {
ep->skip = false;
xhci_dbg(xhci, "td_list is empty while skip "
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 849470b..f1f01a8 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -350,7 +350,7 @@ static int xhci_try_enable_msi(struct usb_hcd *hcd)
* generate interrupts. Don't even try to enable MSI.
*/
if (xhci->quirks & XHCI_BROKEN_MSI)
- goto legacy_irq;
+ return 0;
/* unregister the legacy interrupt */
if (hcd->irq)
@@ -371,7 +371,6 @@ static int xhci_try_enable_msi(struct usb_hcd *hcd)
return -EINVAL;
}
- legacy_irq:
/* fall back to legacy interrupt*/
ret = request_irq(pdev->irq, &usb_hcd_irq, IRQF_SHARED,
hcd->irq_descr, hcd);
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 6a563ef..f791bd0 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -206,8 +206,8 @@ struct xhci_op_regs {
/* bits 12:31 are reserved (and should be preserved on writes). */
/* IMAN - Interrupt Management Register */
-#define IMAN_IE (1 << 1)
-#define IMAN_IP (1 << 0)
+#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. */
@@ -972,10 +972,6 @@ struct xhci_transfer_event {
__le32 flags;
};
-/* Transfer event TRB length bit mask */
-/* bits 0:23 */
-#define EVENT_TRB_LEN(p) ((p) & 0xffffff)
-
/** Transfer Event bit fields **/
#define TRB_TO_EP_ID(p) (((p) >> 16) & 0x1f)
diff --git a/drivers/usb/misc/appledisplay.c b/drivers/usb/misc/appledisplay.c
index ba6a5d6..0fc6e5f 100644
--- a/drivers/usb/misc/appledisplay.c
+++ b/drivers/usb/misc/appledisplay.c
@@ -63,7 +63,6 @@ static const struct usb_device_id appledisplay_table[] = {
{ APPLEDISPLAY_DEVICE(0x9219) },
{ APPLEDISPLAY_DEVICE(0x921c) },
{ APPLEDISPLAY_DEVICE(0x921d) },
- { APPLEDISPLAY_DEVICE(0x9236) },
/* Terminating entry */
{ }
diff --git a/drivers/usb/musb/am35x.c b/drivers/usb/musb/am35x.c
index 59eea21..c107d7c 100644
--- a/drivers/usb/musb/am35x.c
+++ b/drivers/usb/musb/am35x.c
@@ -365,7 +365,7 @@ static int am35x_musb_init(struct musb *musb)
usb_nop_xceiv_register();
musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2);
if (IS_ERR_OR_NULL(musb->xceiv))
- return -EPROBE_DEFER;
+ return -ENODEV;
setup_timer(&otg_workaround, otg_timer, (unsigned long) musb);
diff --git a/drivers/usb/musb/blackfin.c b/drivers/usb/musb/blackfin.c
index dbb31b3..14dab9f 100644
--- a/drivers/usb/musb/blackfin.c
+++ b/drivers/usb/musb/blackfin.c
@@ -406,7 +406,7 @@ static int bfin_musb_init(struct musb *musb)
musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2);
if (IS_ERR_OR_NULL(musb->xceiv)) {
gpio_free(musb->config->gpio_vrsel);
- return -EPROBE_DEFER;
+ return -ENODEV;
}
bfin_musb_reg_init(musb);
diff --git a/drivers/usb/musb/da8xx.c b/drivers/usb/musb/da8xx.c
index 41613a2..97996af 100644
--- a/drivers/usb/musb/da8xx.c
+++ b/drivers/usb/musb/da8xx.c
@@ -327,7 +327,7 @@ static irqreturn_t da8xx_musb_interrupt(int irq, void *hci)
u8 devctl = musb_readb(mregs, MUSB_DEVCTL);
int err;
- err = musb->int_usb & MUSB_INTR_VBUSERROR;
+ err = musb->int_usb & USB_INTR_VBUSERROR;
if (err) {
/*
* The Mentor core doesn't debounce VBUS as needed
@@ -410,7 +410,6 @@ static int da8xx_musb_init(struct musb *musb)
{
void __iomem *reg_base = musb->ctrl_base;
u32 rev;
- int ret = -ENODEV;
musb->mregs += DA8XX_MENTOR_CORE_OFFSET;
@@ -421,10 +420,8 @@ static int da8xx_musb_init(struct musb *musb)
usb_nop_xceiv_register();
musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2);
- if (IS_ERR_OR_NULL(musb->xceiv)) {
- ret = -EPROBE_DEFER;
+ if (IS_ERR_OR_NULL(musb->xceiv))
goto fail;
- }
setup_timer(&otg_workaround, otg_timer, (unsigned long)musb);
@@ -444,7 +441,7 @@ static int da8xx_musb_init(struct musb *musb)
musb->isr = da8xx_musb_interrupt;
return 0;
fail:
- return ret;
+ return -ENODEV;
}
static int da8xx_musb_exit(struct musb *musb)
diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c
index e040d91..b1c01ca 100644
--- a/drivers/usb/musb/davinci.c
+++ b/drivers/usb/musb/davinci.c
@@ -380,14 +380,11 @@ static int davinci_musb_init(struct musb *musb)
{
void __iomem *tibase = musb->ctrl_base;
u32 revision;
- int ret = -ENODEV;
usb_nop_xceiv_register();
musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2);
- if (IS_ERR_OR_NULL(musb->xceiv)) {
- ret = -EPROBE_DEFER;
+ if (IS_ERR_OR_NULL(musb->xceiv))
goto unregister;
- }
musb->mregs += DAVINCI_BASE_OFFSET;
@@ -441,7 +438,7 @@ fail:
usb_put_phy(musb->xceiv);
unregister:
usb_nop_xceiv_unregister();
- return ret;
+ return -ENODEV;
}
static int davinci_musb_exit(struct musb *musb)
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index 60b41cc..fd34867 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -1993,7 +1993,6 @@ fail2:
musb_platform_exit(musb);
fail1:
- pm_runtime_disable(musb->controller);
dev_err(musb->controller,
"musb_init_controller failed with status %d\n", status);
diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c
index 341a4b5..f7d764d 100644
--- a/drivers/usb/musb/musb_dsps.c
+++ b/drivers/usb/musb/musb_dsps.c
@@ -419,7 +419,7 @@ static int dsps_musb_init(struct musb *musb)
usb_nop_xceiv_register();
musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2);
if (IS_ERR_OR_NULL(musb->xceiv))
- return -EPROBE_DEFER;
+ return -ENODEV;
/* Returns zero if e.g. not clocked */
rev = dsps_readl(reg_base, wrp->revision);
diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c
index d7772856..da00af4 100644
--- a/drivers/usb/musb/omap2430.c
+++ b/drivers/usb/musb/omap2430.c
@@ -369,7 +369,7 @@ static int omap2430_musb_init(struct musb *musb)
musb->xceiv = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2);
if (IS_ERR_OR_NULL(musb->xceiv)) {
pr_err("HS USB OTG: no transceiver configured\n");
- return -EPROBE_DEFER;
+ return -ENODEV;
}
musb->isr = omap2430_musb_interrupt;
diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c
index 464bd23..3969813 100644
--- a/drivers/usb/musb/tusb6010.c
+++ b/drivers/usb/musb/tusb6010.c
@@ -1069,7 +1069,7 @@ static int tusb_musb_init(struct musb *musb)
usb_nop_xceiv_register();
musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2);
if (IS_ERR_OR_NULL(musb->xceiv))
- return -EPROBE_DEFER;
+ return -ENODEV;
pdev = to_platform_device(musb->controller);
diff --git a/drivers/usb/musb/ux500.c b/drivers/usb/musb/ux500.c
index 13a3929..a27ca1a 100644
--- a/drivers/usb/musb/ux500.c
+++ b/drivers/usb/musb/ux500.c
@@ -61,7 +61,7 @@ static int ux500_musb_init(struct musb *musb)
musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2);
if (IS_ERR_OR_NULL(musb->xceiv)) {
pr_err("HS USB OTG: no transceiver configured\n");
- return -EPROBE_DEFER;
+ return -ENODEV;
}
musb->isr = ux500_musb_interrupt;
@@ -108,7 +108,7 @@ static int ux500_probe(struct platform_device *pdev)
goto err3;
}
- ret = clk_prepare_enable(clk);
+ ret = clk_enable(clk);
if (ret) {
dev_err(&pdev->dev, "failed to enable clock\n");
goto err4;
@@ -148,7 +148,7 @@ static int ux500_probe(struct platform_device *pdev)
return 0;
err5:
- clk_disable_unprepare(clk);
+ clk_disable(clk);
err4:
clk_put(clk);
@@ -168,7 +168,7 @@ static int ux500_remove(struct platform_device *pdev)
struct ux500_glue *glue = platform_get_drvdata(pdev);
platform_device_unregister(glue->musb);
- clk_disable_unprepare(glue->clk);
+ clk_disable(glue->clk);
clk_put(glue->clk);
kfree(glue);
@@ -182,7 +182,7 @@ static int ux500_suspend(struct device *dev)
struct musb *musb = glue_to_musb(glue);
usb_phy_set_suspend(musb->xceiv, 1);
- clk_disable_unprepare(glue->clk);
+ clk_disable(glue->clk);
return 0;
}
@@ -193,7 +193,7 @@ static int ux500_resume(struct device *dev)
struct musb *musb = glue_to_musb(glue);
int ret;
- ret = clk_prepare_enable(glue->clk);
+ ret = clk_enable(glue->clk);
if (ret) {
dev_err(dev, "failed to enable clock\n");
return ret;
diff --git a/drivers/usb/serial/ark3116.c b/drivers/usb/serial/ark3116.c
index 0b44e45..a88882c 100644
--- a/drivers/usb/serial/ark3116.c
+++ b/drivers/usb/serial/ark3116.c
@@ -62,6 +62,7 @@ static int is_irda(struct usb_serial *serial)
}
struct ark3116_private {
+ wait_queue_head_t delta_msr_wait;
struct async_icount icount;
int irda; /* 1 for irda device */
@@ -145,6 +146,7 @@ static int ark3116_port_probe(struct usb_serial_port *port)
if (!priv)
return -ENOMEM;
+ init_waitqueue_head(&priv->delta_msr_wait);
mutex_init(&priv->hw_lock);
spin_lock_init(&priv->status_lock);
@@ -454,14 +456,10 @@ static int ark3116_ioctl(struct tty_struct *tty,
case TIOCMIWAIT:
for (;;) {
struct async_icount prev = priv->icount;
- interruptible_sleep_on(&port->delta_msr_wait);
+ interruptible_sleep_on(&priv->delta_msr_wait);
/* see if a signal did it */
if (signal_pending(current))
return -ERESTARTSYS;
-
- if (port->serial->disconnected)
- return -EIO;
-
if ((prev.rng == priv->icount.rng) &&
(prev.dsr == priv->icount.dsr) &&
(prev.dcd == priv->icount.dcd) &&
@@ -582,7 +580,7 @@ static void ark3116_update_msr(struct usb_serial_port *port, __u8 msr)
priv->icount.dcd++;
if (msr & UART_MSR_TERI)
priv->icount.rng++;
- wake_up_interruptible(&port->delta_msr_wait);
+ wake_up_interruptible(&priv->delta_msr_wait);
}
}
diff --git a/drivers/usb/serial/ch341.c b/drivers/usb/serial/ch341.c
index 07d4650..d255f66 100644
--- a/drivers/usb/serial/ch341.c
+++ b/drivers/usb/serial/ch341.c
@@ -80,6 +80,7 @@ MODULE_DEVICE_TABLE(usb, id_table);
struct ch341_private {
spinlock_t lock; /* access lock */
+ wait_queue_head_t delta_msr_wait; /* wait queue for modem status */
unsigned baud_rate; /* set baud rate */
u8 line_control; /* set line control value RTS/DTR */
u8 line_status; /* active status of modem control inputs */
@@ -251,6 +252,7 @@ static int ch341_port_probe(struct usb_serial_port *port)
return -ENOMEM;
spin_lock_init(&priv->lock);
+ init_waitqueue_head(&priv->delta_msr_wait);
priv->baud_rate = DEFAULT_BAUD_RATE;
priv->line_control = CH341_BIT_RTS | CH341_BIT_DTR;
@@ -296,7 +298,7 @@ static void ch341_dtr_rts(struct usb_serial_port *port, int on)
priv->line_control &= ~(CH341_BIT_RTS | CH341_BIT_DTR);
spin_unlock_irqrestore(&priv->lock, flags);
ch341_set_handshake(port->serial->dev, priv->line_control);
- wake_up_interruptible(&port->delta_msr_wait);
+ wake_up_interruptible(&priv->delta_msr_wait);
}
static void ch341_close(struct usb_serial_port *port)
@@ -489,7 +491,7 @@ static void ch341_read_int_callback(struct urb *urb)
tty_kref_put(tty);
}
- wake_up_interruptible(&port->delta_msr_wait);
+ wake_up_interruptible(&priv->delta_msr_wait);
}
exit:
@@ -515,14 +517,11 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg)
spin_unlock_irqrestore(&priv->lock, flags);
while (!multi_change) {
- interruptible_sleep_on(&port->delta_msr_wait);
+ interruptible_sleep_on(&priv->delta_msr_wait);
/* see if a signal did it */
if (signal_pending(current))
return -ERESTARTSYS;
- if (port->serial->disconnected)
- return -EIO;
-
spin_lock_irqsave(&priv->lock, flags);
status = priv->line_status;
multi_change = priv->multi_status_change;
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
index 4747d1c..edc0f0d 100644
--- a/drivers/usb/serial/cp210x.c
+++ b/drivers/usb/serial/cp210x.c
@@ -85,7 +85,6 @@ static const struct usb_device_id id_table[] = {
{ USB_DEVICE(0x10C4, 0x813F) }, /* Tams Master Easy Control */
{ USB_DEVICE(0x10C4, 0x814A) }, /* West Mountain Radio RIGblaster P&P */
{ USB_DEVICE(0x10C4, 0x814B) }, /* West Mountain Radio RIGtalk */
- { USB_DEVICE(0x2405, 0x0003) }, /* West Mountain Radio RIGblaster Advantage */
{ USB_DEVICE(0x10C4, 0x8156) }, /* B&G H3000 link cable */
{ USB_DEVICE(0x10C4, 0x815E) }, /* Helicomm IP-Link 1220-DVM */
{ USB_DEVICE(0x10C4, 0x815F) }, /* Timewave HamLinkUSB */
@@ -151,25 +150,6 @@ static const struct usb_device_id id_table[] = {
{ USB_DEVICE(0x1BE3, 0x07A6) }, /* WAGO 750-923 USB Service Cable */
{ USB_DEVICE(0x1E29, 0x0102) }, /* Festo CPX-USB */
{ USB_DEVICE(0x1E29, 0x0501) }, /* Festo CMSP */
- { USB_DEVICE(0x1FB9, 0x0100) }, /* Lake Shore Model 121 Current Source */
- { USB_DEVICE(0x1FB9, 0x0200) }, /* Lake Shore Model 218A Temperature Monitor */
- { USB_DEVICE(0x1FB9, 0x0201) }, /* Lake Shore Model 219 Temperature Monitor */
- { USB_DEVICE(0x1FB9, 0x0202) }, /* Lake Shore Model 233 Temperature Transmitter */
- { USB_DEVICE(0x1FB9, 0x0203) }, /* Lake Shore Model 235 Temperature Transmitter */
- { USB_DEVICE(0x1FB9, 0x0300) }, /* Lake Shore Model 335 Temperature Controller */
- { USB_DEVICE(0x1FB9, 0x0301) }, /* Lake Shore Model 336 Temperature Controller */
- { USB_DEVICE(0x1FB9, 0x0302) }, /* Lake Shore Model 350 Temperature Controller */
- { USB_DEVICE(0x1FB9, 0x0303) }, /* Lake Shore Model 371 AC Bridge */
- { USB_DEVICE(0x1FB9, 0x0400) }, /* Lake Shore Model 411 Handheld Gaussmeter */
- { USB_DEVICE(0x1FB9, 0x0401) }, /* Lake Shore Model 425 Gaussmeter */
- { USB_DEVICE(0x1FB9, 0x0402) }, /* Lake Shore Model 455A Gaussmeter */
- { USB_DEVICE(0x1FB9, 0x0403) }, /* Lake Shore Model 475A Gaussmeter */
- { USB_DEVICE(0x1FB9, 0x0404) }, /* Lake Shore Model 465 Three Axis Gaussmeter */
- { USB_DEVICE(0x1FB9, 0x0600) }, /* Lake Shore Model 625A Superconducting MPS */
- { USB_DEVICE(0x1FB9, 0x0601) }, /* Lake Shore Model 642A Magnet Power Supply */
- { USB_DEVICE(0x1FB9, 0x0602) }, /* Lake Shore Model 648 Magnet Power Supply */
- { USB_DEVICE(0x1FB9, 0x0700) }, /* Lake Shore Model 737 VSM Controller */
- { USB_DEVICE(0x1FB9, 0x0701) }, /* Lake Shore Model 776 Hall Matrix */
{ USB_DEVICE(0x3195, 0xF190) }, /* Link Instruments MSO-19 */
{ USB_DEVICE(0x3195, 0xF280) }, /* Link Instruments MSO-28 */
{ USB_DEVICE(0x3195, 0xF281) }, /* Link Instruments MSO-28 */
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c
index a06076f..fd8c35f 100644
--- a/drivers/usb/serial/cypress_m8.c
+++ b/drivers/usb/serial/cypress_m8.c
@@ -111,6 +111,7 @@ struct cypress_private {
int baud_rate; /* stores current baud rate in
integer form */
int isthrottled; /* if throttled, discard reads */
+ wait_queue_head_t delta_msr_wait; /* used for TIOCMIWAIT */
char prev_status, diff_status; /* used for TIOCMIWAIT */
/* we pass a pointer to this as the argument sent to
cypress_set_termios old_termios */
@@ -448,6 +449,7 @@ static int cypress_generic_port_probe(struct usb_serial_port *port)
kfree(priv);
return -ENOMEM;
}
+ init_waitqueue_head(&priv->delta_msr_wait);
usb_reset_configuration(serial->dev);
@@ -866,16 +868,12 @@ static int cypress_ioctl(struct tty_struct *tty,
switch (cmd) {
/* This code comes from drivers/char/serial.c and ftdi_sio.c */
case TIOCMIWAIT:
- for (;;) {
- interruptible_sleep_on(&port->delta_msr_wait);
+ while (priv != NULL) {
+ interruptible_sleep_on(&priv->delta_msr_wait);
/* see if a signal did it */
if (signal_pending(current))
return -ERESTARTSYS;
-
- if (port->serial->disconnected)
- return -EIO;
-
- {
+ else {
char diff = priv->diff_status;
if (diff == 0)
return -EIO; /* no change => error */
@@ -1189,7 +1187,7 @@ static void cypress_read_int_callback(struct urb *urb)
if (priv->current_status != priv->prev_status) {
priv->diff_status |= priv->current_status ^
priv->prev_status;
- wake_up_interruptible(&port->delta_msr_wait);
+ wake_up_interruptible(&priv->delta_msr_wait);
priv->prev_status = priv->current_status;
}
spin_unlock_irqrestore(&priv->lock, flags);
diff --git a/drivers/usb/serial/f81232.c b/drivers/usb/serial/f81232.c
index 1e64343..6e4eb57 100644
--- a/drivers/usb/serial/f81232.c
+++ b/drivers/usb/serial/f81232.c
@@ -47,6 +47,7 @@ MODULE_DEVICE_TABLE(usb, id_table);
struct f81232_private {
spinlock_t lock;
+ wait_queue_head_t delta_msr_wait;
u8 line_control;
u8 line_status;
};
@@ -111,7 +112,7 @@ static void f81232_process_read_urb(struct urb *urb)
line_status = priv->line_status;
priv->line_status &= ~UART_STATE_TRANSIENT_MASK;
spin_unlock_irqrestore(&priv->lock, flags);
- wake_up_interruptible(&port->delta_msr_wait);
+ wake_up_interruptible(&priv->delta_msr_wait);
if (!urb->actual_length)
return;
@@ -260,14 +261,11 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg)
spin_unlock_irqrestore(&priv->lock, flags);
while (1) {
- interruptible_sleep_on(&port->delta_msr_wait);
+ interruptible_sleep_on(&priv->delta_msr_wait);
/* see if a signal did it */
if (signal_pending(current))
return -ERESTARTSYS;
- if (port->serial->disconnected)
- return -EIO;
-
spin_lock_irqsave(&priv->lock, flags);
status = priv->line_status;
spin_unlock_irqrestore(&priv->lock, flags);
@@ -329,6 +327,7 @@ static int f81232_port_probe(struct usb_serial_port *port)
return -ENOMEM;
spin_lock_init(&priv->lock);
+ init_waitqueue_head(&priv->delta_msr_wait);
usb_set_serial_port_data(port, priv);
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index 77f78ad..90ceef1 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -69,7 +69,9 @@ struct ftdi_private {
int flags; /* some ASYNC_xxxx flags are supported */
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; /* Used for TIOCMIWAIT */
+ bool dev_gone; /* Used to abort TIOCMIWAIT */
char transmit_empty; /* If transmitter is empty or not */
__u16 interface; /* FT2232C, FT2232H or FT4232H port interface
(0 for FT232/245) */
@@ -189,7 +191,6 @@ static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(FTDI_VID, FTDI_OPENDCC_THROTTLE_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_OPENDCC_GATEWAY_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_OPENDCC_GBM_PID) },
- { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_GBM_BOOST_PID) },
{ USB_DEVICE(NEWPORT_VID, NEWPORT_AGILIS_PID) },
{ USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_IOBOARD_PID) },
{ USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_MINI_IOBOARD_PID) },
@@ -641,7 +642,6 @@ static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(FTDI_VID, FTDI_RM_CANVIEW_PID) },
{ USB_DEVICE(ACTON_VID, ACTON_SPECTRAPRO_PID) },
{ USB_DEVICE(CONTEC_VID, CONTEC_COM1USBH_PID) },
- { USB_DEVICE(MITSUBISHI_VID, MITSUBISHI_FXUSB_PID) },
{ USB_DEVICE(BANDB_VID, BANDB_USOTL4_PID) },
{ USB_DEVICE(BANDB_VID, BANDB_USTL4_PID) },
{ USB_DEVICE(BANDB_VID, BANDB_USO9ML2_PID) },
@@ -871,9 +871,7 @@ static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(FTDI_VID, FTDI_DOTEC_PID) },
{ USB_DEVICE(QIHARDWARE_VID, MILKYMISTONE_JTAGSERIAL_PID),
.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
- { USB_DEVICE(ST_VID, ST_STMCLT_2232_PID),
- .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
- { USB_DEVICE(ST_VID, ST_STMCLT_4232_PID),
+ { USB_DEVICE(ST_VID, ST_STMCLT1030_PID),
.driver_info = (kernel_ulong_t)&ftdi_stmclite_quirk },
{ USB_DEVICE(FTDI_VID, FTDI_RF_R106) },
{ USB_DEVICE(FTDI_VID, FTDI_DISTORTEC_JTAG_LOCK_PICK_PID),
@@ -1693,8 +1691,10 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port)
kref_init(&priv->kref);
mutex_init(&priv->cfg_lock);
+ 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);
@@ -1795,24 +1795,20 @@ static int ftdi_8u2232c_probe(struct usb_serial *serial)
}
/*
- * First two ports on JTAG adaptors using an FT4232 such as STMicroelectronics's
- * ST Micro Connect Lite are reserved for JTAG or other non-UART interfaces and
- * can be accessed from userspace.
- * The next two ports are enabled as UARTs by default, where port 2 is
- * a conventional RS-232 UART.
+ * First and second port on STMCLiteadaptors is reserved for JTAG interface
+ * and the forth port for pio
*/
static int ftdi_stmclite_probe(struct usb_serial *serial)
{
struct usb_device *udev = serial->dev;
struct usb_interface *interface = serial->interface;
- if (interface == udev->actconfig->interface[0] ||
- interface == udev->actconfig->interface[1]) {
- dev_info(&udev->dev, "Ignoring serial port reserved for JTAG\n");
- return -ENODEV;
- }
+ if (interface == udev->actconfig->interface[2])
+ return 0;
- return 0;
+ dev_info(&udev->dev, "Ignoring serial port reserved for JTAG\n");
+
+ return -ENODEV;
}
/*
@@ -1844,7 +1840,8 @@ static int ftdi_sio_port_remove(struct usb_serial_port *port)
{
struct ftdi_private *priv = usb_get_serial_port_data(port);
- wake_up_interruptible(&port->delta_msr_wait);
+ priv->dev_gone = true;
+ wake_up_interruptible_all(&priv->delta_msr_wait);
remove_sysfs_attrs(port);
@@ -1889,22 +1886,24 @@ static void ftdi_dtr_rts(struct usb_serial_port *port, int on)
{
struct ftdi_private *priv = usb_get_serial_port_data(port);
- /* Disable flow control */
- if (!on) {
- if (usb_control_msg(port->serial->dev,
+ mutex_lock(&port->serial->disc_mutex);
+ if (!port->serial->disconnected) {
+ /* Disable flow control */
+ if (!on && usb_control_msg(port->serial->dev,
usb_sndctrlpipe(port->serial->dev, 0),
FTDI_SIO_SET_FLOW_CTRL_REQUEST,
FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE,
0, priv->interface, NULL, 0,
WDR_TIMEOUT) < 0) {
- dev_err(&port->dev, "error from flowcontrol urb\n");
+ dev_err(&port->dev, "error from flowcontrol urb\n");
}
+ /* drop RTS and DTR */
+ if (on)
+ set_mctrl(port, TIOCM_DTR | TIOCM_RTS);
+ else
+ clear_mctrl(port, TIOCM_DTR | TIOCM_RTS);
}
- /* drop RTS and DTR */
- if (on)
- set_mctrl(port, TIOCM_DTR | TIOCM_RTS);
- else
- clear_mctrl(port, TIOCM_DTR | TIOCM_RTS);
+ mutex_unlock(&port->serial->disc_mutex);
}
/*
@@ -1993,7 +1992,7 @@ static int ftdi_process_packet(struct tty_struct *tty,
if (diff_status & FTDI_RS0_RLSD)
priv->icount.dcd++;
- wake_up_interruptible(&port->delta_msr_wait);
+ wake_up_interruptible_all(&priv->delta_msr_wait);
priv->prev_status = status;
}
@@ -2450,15 +2449,11 @@ static int ftdi_ioctl(struct tty_struct *tty,
*/
case TIOCMIWAIT:
cprev = priv->icount;
- for (;;) {
- interruptible_sleep_on(&port->delta_msr_wait);
+ while (!priv->dev_gone) {
+ interruptible_sleep_on(&priv->delta_msr_wait);
/* see if a signal did it */
if (signal_pending(current))
return -ERESTARTSYS;
-
- if (port->serial->disconnected)
- return -EIO;
-
cnow = priv->icount;
if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
@@ -2468,6 +2463,8 @@ static int ftdi_ioctl(struct tty_struct *tty,
}
cprev = cnow;
}
+ return -EIO;
+ break;
case TIOCSERGETLSR:
return get_lsr_info(port, (struct serial_struct __user *)arg);
break;
diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h
index 9852827..9d359e1 100644
--- a/drivers/usb/serial/ftdi_sio_ids.h
+++ b/drivers/usb/serial/ftdi_sio_ids.h
@@ -74,7 +74,6 @@
#define FTDI_OPENDCC_THROTTLE_PID 0xBFDA
#define FTDI_OPENDCC_GATEWAY_PID 0xBFDB
#define FTDI_OPENDCC_GBM_PID 0xBFDC
-#define FTDI_OPENDCC_GBM_BOOST_PID 0xBFDD
/* NZR SEM 16+ USB (http://www.nzr.de) */
#define FTDI_NZR_SEM_USB_PID 0xC1E0 /* NZR SEM-LOG16+ */
@@ -585,13 +584,6 @@
#define CONTEC_COM1USBH_PID 0x8311 /* COM-1(USB)H */
/*
- * Mitsubishi Electric Corp. (http://www.meau.com)
- * Submitted by Konstantin Holoborodko
- */
-#define MITSUBISHI_VID 0x06D3
-#define MITSUBISHI_FXUSB_PID 0x0284 /* USB/RS422 converters: FX-USB-AW/-BD */
-
-/*
* Definitions for B&B Electronics products.
*/
#define BANDB_VID 0x0856 /* B&B Electronics Vendor ID */
@@ -1151,8 +1143,7 @@
* STMicroelectonics
*/
#define ST_VID 0x0483
-#define ST_STMCLT_2232_PID 0x3746
-#define ST_STMCLT_4232_PID 0x3747
+#define ST_STMCLT1030_PID 0x3747 /* ST Micro Connect Lite STMCLT1030 */
/*
* Papouch products (http://www.papouch.com/)
diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c
index 34e702b..203358d 100644
--- a/drivers/usb/serial/garmin_gps.c
+++ b/drivers/usb/serial/garmin_gps.c
@@ -959,7 +959,10 @@ static void garmin_close(struct usb_serial_port *port)
if (!serial)
return;
- garmin_clear(garmin_data_p);
+ mutex_lock(&port->serial->disc_mutex);
+
+ if (!port->serial->disconnected)
+ garmin_clear(garmin_data_p);
/* shutdown our urbs */
usb_kill_urb(port->read_urb);
@@ -968,6 +971,8 @@ static void garmin_close(struct usb_serial_port *port)
/* keep reset state so we know that we must start a new session */
if (garmin_data_p->state != STATE_RESET)
garmin_data_p->state = STATE_DISCONNECTED;
+
+ mutex_unlock(&port->serial->disc_mutex);
}
diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c
index adfd73d..7b770c7 100644
--- a/drivers/usb/serial/io_edgeport.c
+++ b/drivers/usb/serial/io_edgeport.c
@@ -110,6 +110,7 @@ struct edgeport_port {
wait_queue_head_t wait_chase; /* for handling sleeping while waiting for chase to finish */
wait_queue_head_t wait_open; /* for handling sleeping while waiting for open to finish */
wait_queue_head_t wait_command; /* for handling sleeping while waiting for command to finish */
+ wait_queue_head_t delta_msr_wait; /* for handling sleeping while waiting for msr change to happen */
struct async_icount icount;
struct usb_serial_port *port; /* loop back to the owner of this object */
@@ -883,6 +884,7 @@ static int edge_open(struct tty_struct *tty, struct usb_serial_port *port)
/* initialize our wait queues */
init_waitqueue_head(&edge_port->wait_open);
init_waitqueue_head(&edge_port->wait_chase);
+ init_waitqueue_head(&edge_port->delta_msr_wait);
init_waitqueue_head(&edge_port->wait_command);
/* initialize our icount structure */
@@ -1667,17 +1669,13 @@ static int edge_ioctl(struct tty_struct *tty,
dev_dbg(&port->dev, "%s (%d) TIOCMIWAIT\n", __func__, port->number);
cprev = edge_port->icount;
while (1) {
- prepare_to_wait(&port->delta_msr_wait,
+ prepare_to_wait(&edge_port->delta_msr_wait,
&wait, TASK_INTERRUPTIBLE);
schedule();
- finish_wait(&port->delta_msr_wait, &wait);
+ finish_wait(&edge_port->delta_msr_wait, &wait);
/* see if a signal did it */
if (signal_pending(current))
return -ERESTARTSYS;
-
- if (port->serial->disconnected)
- return -EIO;
-
cnow = edge_port->icount;
if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
@@ -2057,7 +2055,7 @@ static void handle_new_msr(struct edgeport_port *edge_port, __u8 newMsr)
icount->dcd++;
if (newMsr & EDGEPORT_MSR_DELTA_RI)
icount->rng++;
- wake_up_interruptible(&edge_port->port->delta_msr_wait);
+ wake_up_interruptible(&edge_port->delta_msr_wait);
}
/* Save the new modem status */
diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c
index 1db782d..82afc4d 100644
--- a/drivers/usb/serial/io_ti.c
+++ b/drivers/usb/serial/io_ti.c
@@ -87,6 +87,9 @@ struct edgeport_port {
int close_pending;
int lsr_event;
struct async_icount icount;
+ wait_queue_head_t delta_msr_wait; /* for handling sleeping while
+ waiting for msr change to
+ happen */
struct edgeport_serial *edge_serial;
struct usb_serial_port *port;
__u8 bUartMode; /* Port type, 0: RS232, etc. */
@@ -1515,7 +1518,7 @@ static void handle_new_msr(struct edgeport_port *edge_port, __u8 msr)
icount->dcd++;
if (msr & EDGEPORT_MSR_DELTA_RI)
icount->rng++;
- wake_up_interruptible(&edge_port->port->delta_msr_wait);
+ wake_up_interruptible(&edge_port->delta_msr_wait);
}
/* Save the new modem status */
@@ -1818,6 +1821,7 @@ static int edge_open(struct tty_struct *tty, struct usb_serial_port *port)
dev = port->serial->dev;
memset(&(edge_port->icount), 0x00, sizeof(edge_port->icount));
+ init_waitqueue_head(&edge_port->delta_msr_wait);
/* turn off loopback */
status = ti_do_config(edge_port, UMPC_SET_CLR_LOOPBACK, 0);
@@ -2484,14 +2488,10 @@ static int edge_ioctl(struct tty_struct *tty,
dev_dbg(&port->dev, "%s - TIOCMIWAIT\n", __func__);
cprev = edge_port->icount;
while (1) {
- interruptible_sleep_on(&port->delta_msr_wait);
+ interruptible_sleep_on(&edge_port->delta_msr_wait);
/* see if a signal did it */
if (signal_pending(current))
return -ERESTARTSYS;
-
- if (port->serial->disconnected)
- return -EIO;
-
cnow = edge_port->icount;
if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
@@ -2702,7 +2702,6 @@ static struct usb_serial_driver edgeport_2port_device = {
.set_termios = edge_set_termios,
.tiocmget = edge_tiocmget,
.tiocmset = edge_tiocmset,
- .get_icount = edge_get_icount,
.write = edge_write,
.write_room = edge_write_room,
.chars_in_buffer = edge_chars_in_buffer,
diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c
index 3b9f834..b691175 100644
--- a/drivers/usb/serial/mct_u232.c
+++ b/drivers/usb/serial/mct_u232.c
@@ -114,6 +114,8 @@ struct mct_u232_private {
unsigned char last_msr; /* Modem Status Register */
unsigned int rx_flags; /* Throttling flags */
struct async_icount icount;
+ wait_queue_head_t msr_wait; /* for handling sleeping while waiting
+ for msr change to happen */
};
#define THROTTLED 0x01
@@ -407,6 +409,7 @@ static int mct_u232_port_probe(struct usb_serial_port *port)
return -ENOMEM;
spin_lock_init(&priv->lock);
+ init_waitqueue_head(&priv->msr_wait);
usb_set_serial_port_data(port, priv);
@@ -496,15 +499,19 @@ static void mct_u232_dtr_rts(struct usb_serial_port *port, int on)
unsigned int control_state;
struct mct_u232_private *priv = usb_get_serial_port_data(port);
- spin_lock_irq(&priv->lock);
- if (on)
- priv->control_state |= TIOCM_DTR | TIOCM_RTS;
- else
- priv->control_state &= ~(TIOCM_DTR | TIOCM_RTS);
- control_state = priv->control_state;
- spin_unlock_irq(&priv->lock);
-
- mct_u232_set_modem_ctrl(port, control_state);
+ mutex_lock(&port->serial->disc_mutex);
+ if (!port->serial->disconnected) {
+ /* drop DTR and RTS */
+ spin_lock_irq(&priv->lock);
+ if (on)
+ priv->control_state |= TIOCM_DTR | TIOCM_RTS;
+ else
+ priv->control_state &= ~(TIOCM_DTR | TIOCM_RTS);
+ control_state = priv->control_state;
+ spin_unlock_irq(&priv->lock);
+ mct_u232_set_modem_ctrl(port, control_state);
+ }
+ mutex_unlock(&port->serial->disc_mutex);
}
static void mct_u232_close(struct usb_serial_port *port)
@@ -603,7 +610,7 @@ static void mct_u232_read_int_callback(struct urb *urb)
tty_kref_put(tty);
}
#endif
- wake_up_interruptible(&port->delta_msr_wait);
+ wake_up_interruptible(&priv->msr_wait);
spin_unlock_irqrestore(&priv->lock, flags);
exit:
retval = usb_submit_urb(urb, GFP_ATOMIC);
@@ -812,17 +819,13 @@ static int mct_u232_ioctl(struct tty_struct *tty,
cprev = mct_u232_port->icount;
spin_unlock_irqrestore(&mct_u232_port->lock, flags);
for ( ; ; ) {
- prepare_to_wait(&port->delta_msr_wait,
+ prepare_to_wait(&mct_u232_port->msr_wait,
&wait, TASK_INTERRUPTIBLE);
schedule();
- finish_wait(&port->delta_msr_wait, &wait);
+ finish_wait(&mct_u232_port->msr_wait, &wait);
/* see if a signal did it */
if (signal_pending(current))
return -ERESTARTSYS;
-
- if (port->serial->disconnected)
- return -EIO;
-
spin_lock_irqsave(&mct_u232_port->lock, flags);
cnow = mct_u232_port->icount;
spin_unlock_irqrestore(&mct_u232_port->lock, flags);
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c
index 3b909e0..66d9e08 100644
--- a/drivers/usb/serial/mos7840.c
+++ b/drivers/usb/serial/mos7840.c
@@ -219,6 +219,7 @@ struct moschip_port {
char open;
char open_ports;
wait_queue_head_t wait_chase; /* for handling sleeping while waiting for chase to finish */
+ wait_queue_head_t delta_msr_wait; /* for handling sleeping while waiting for msr change to happen */
int delta_msr_cond;
struct async_icount icount;
struct usb_serial_port *port; /* loop back to the owner of this object */
@@ -422,9 +423,6 @@ static void mos7840_handle_new_msr(struct moschip_port *port, __u8 new_msr)
icount->rng++;
smp_wmb();
}
-
- mos7840_port->delta_msr_cond = 1;
- wake_up_interruptible(&port->port->delta_msr_wait);
}
}
@@ -1133,6 +1131,7 @@ static int mos7840_open(struct tty_struct *tty, struct usb_serial_port *port)
/* initialize our wait queues */
init_waitqueue_head(&mos7840_port->wait_chase);
+ init_waitqueue_head(&mos7840_port->delta_msr_wait);
/* initialize our icount structure */
memset(&(mos7840_port->icount), 0x00, sizeof(mos7840_port->icount));
@@ -2022,6 +2021,8 @@ static void mos7840_change_port_settings(struct tty_struct *tty,
mos7840_port->read_urb_busy = false;
}
}
+ wake_up(&mos7840_port->delta_msr_wait);
+ mos7840_port->delta_msr_cond = 1;
dev_dbg(&port->dev, "%s - mos7840_port->shadowLCR is End %x\n", __func__,
mos7840_port->shadowLCR);
}
@@ -2222,18 +2223,13 @@ static int mos7840_ioctl(struct tty_struct *tty,
while (1) {
/* interruptible_sleep_on(&mos7840_port->delta_msr_wait); */
mos7840_port->delta_msr_cond = 0;
- wait_event_interruptible(port->delta_msr_wait,
- (port->serial->disconnected ||
- mos7840_port->
+ wait_event_interruptible(mos7840_port->delta_msr_wait,
+ (mos7840_port->
delta_msr_cond == 1));
/* see if a signal did it */
if (signal_pending(current))
return -ERESTARTSYS;
-
- if (port->serial->disconnected)
- return -EIO;
-
cnow = mos7840_port->icount;
smp_rmb();
if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index bff059a..567bc77 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -341,13 +341,10 @@ static void option_instat_callback(struct urb *urb);
#define CINTERION_PRODUCT_EU3_E 0x0051
#define CINTERION_PRODUCT_EU3_P 0x0052
#define CINTERION_PRODUCT_PH8 0x0053
-#define CINTERION_PRODUCT_AH6 0x0055
-#define CINTERION_PRODUCT_PLS8 0x0060
/* Olivetti products */
#define OLIVETTI_VENDOR_ID 0x0b3c
#define OLIVETTI_PRODUCT_OLICARD100 0xc000
-#define OLIVETTI_PRODUCT_OLICARD145 0xc003
/* Celot products */
#define CELOT_VENDOR_ID 0x211f
@@ -482,7 +479,6 @@ static const struct option_blacklist_info four_g_w14_blacklist = {
static const struct option_blacklist_info alcatel_x200_blacklist = {
.sendsetup = BIT(0) | BIT(1),
- .reserved = BIT(4),
};
static const struct option_blacklist_info zte_0037_blacklist = {
@@ -579,15 +575,8 @@ static const struct usb_device_id option_ids[] = {
{ USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GLX) },
{ USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GKE) },
{ USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GLE) },
- { USB_DEVICE(QUANTA_VENDOR_ID, 0xea42),
- .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1c05, USB_CLASS_COMM, 0x02, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1c1f, USB_CLASS_COMM, 0x02, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1c23, USB_CLASS_COMM, 0x02, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E173, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t) &net_intf1_blacklist },
- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1441, USB_CLASS_COMM, 0x02, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1442, USB_CLASS_COMM, 0x02, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4505, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist },
{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3765, 0xff, 0xff, 0xff),
@@ -1226,14 +1215,7 @@ static const struct usb_device_id option_ids[] = {
{ USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X060S_X200),
.driver_info = (kernel_ulong_t)&alcatel_x200_blacklist
},
- { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X220_X500D),
- .driver_info = (kernel_ulong_t)&net_intf6_blacklist },
- { USB_DEVICE(ALCATEL_VENDOR_ID, 0x0052),
- .driver_info = (kernel_ulong_t)&net_intf6_blacklist },
- { USB_DEVICE(ALCATEL_VENDOR_ID, 0x00b6),
- .driver_info = (kernel_ulong_t)&net_intf3_blacklist },
- { USB_DEVICE(ALCATEL_VENDOR_ID, 0x00b7),
- .driver_info = (kernel_ulong_t)&net_intf5_blacklist },
+ { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X220_X500D) },
{ USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_L100V),
.driver_info = (kernel_ulong_t)&net_intf4_blacklist },
{ USB_DEVICE(AIRPLUS_VENDOR_ID, AIRPLUS_PRODUCT_MCD650) },
@@ -1264,8 +1246,6 @@ static const struct usb_device_id option_ids[] = {
{ USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_EU3_E) },
{ USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_EU3_P) },
{ USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PH8) },
- { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_AH6) },
- { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PLS8) },
{ USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_HC28_MDM) },
{ USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_HC28_MDMNET) },
{ USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC25_MDM) },
@@ -1274,7 +1254,6 @@ static const struct usb_device_id option_ids[] = {
{ USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC28_MDMNET) },
{ USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD100) },
- { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD145) },
{ USB_DEVICE(CELOT_VENDOR_ID, CELOT_PRODUCT_CT680M) }, /* CT-650 CDMA 450 1xEVDO modem */
{ USB_DEVICE(ONDA_VENDOR_ID, ONDA_MT825UP) }, /* ONDA MT825UP modem */
{ USB_DEVICE_AND_INTERFACE_INFO(SAMSUNG_VENDOR_ID, SAMSUNG_PRODUCT_GT_B3730, USB_CLASS_CDC_DATA, 0x00, 0x00) }, /* Samsung GT-B3730 LTE USB modem.*/
@@ -1352,12 +1331,6 @@ static const struct usb_device_id option_ids[] = {
{ USB_DEVICE(TPLINK_VENDOR_ID, TPLINK_PRODUCT_MA180),
.driver_info = (kernel_ulong_t)&net_intf4_blacklist },
{ USB_DEVICE(CHANGHONG_VENDOR_ID, CHANGHONG_PRODUCT_CH690) },
- { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d01, 0xff, 0x02, 0x01) }, /* D-Link DWM-156 (variant) */
- { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d01, 0xff, 0x00, 0x00) }, /* D-Link DWM-156 (variant) */
- { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d02, 0xff, 0x02, 0x01) },
- { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d02, 0xff, 0x00, 0x00) },
- { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d03, 0xff, 0x02, 0x01) },
- { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d03, 0xff, 0x00, 0x00) },
{ } /* Terminating entry */
};
MODULE_DEVICE_TABLE(usb, option_ids);
diff --git a/drivers/usb/serial/oti6858.c b/drivers/usb/serial/oti6858.c
index ae4495a..d217fd6 100644
--- a/drivers/usb/serial/oti6858.c
+++ b/drivers/usb/serial/oti6858.c
@@ -188,6 +188,7 @@ struct oti6858_private {
u8 setup_done;
struct delayed_work delayed_setup_work;
+ wait_queue_head_t intr_wait;
struct usb_serial_port *port; /* USB port with which associated */
};
@@ -338,6 +339,7 @@ static int oti6858_port_probe(struct usb_serial_port *port)
return -ENOMEM;
spin_lock_init(&priv->lock);
+ init_waitqueue_head(&priv->intr_wait);
priv->port = port;
INIT_DELAYED_WORK(&priv->delayed_setup_work, setup_line);
INIT_DELAYED_WORK(&priv->delayed_write_work, send_data);
@@ -662,15 +664,11 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg)
spin_unlock_irqrestore(&priv->lock, flags);
while (1) {
- wait_event_interruptible(port->delta_msr_wait,
- port->serial->disconnected ||
+ wait_event_interruptible(priv->intr_wait,
priv->status.pin_state != prev);
if (signal_pending(current))
return -ERESTARTSYS;
- if (port->serial->disconnected)
- return -EIO;
-
spin_lock_irqsave(&priv->lock, flags);
status = priv->status.pin_state & PIN_MASK;
spin_unlock_irqrestore(&priv->lock, flags);
@@ -765,7 +763,7 @@ static void oti6858_read_int_callback(struct urb *urb)
if (!priv->transient) {
if (xs->pin_state != priv->status.pin_state)
- wake_up_interruptible(&port->delta_msr_wait);
+ wake_up_interruptible(&priv->intr_wait);
memcpy(&priv->status, xs, OTI6858_CTRL_PKT_SIZE);
}
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
index bb056a1..6002419 100644
--- a/drivers/usb/serial/pl2303.c
+++ b/drivers/usb/serial/pl2303.c
@@ -139,6 +139,7 @@ struct pl2303_serial_private {
struct pl2303_private {
spinlock_t lock;
+ wait_queue_head_t delta_msr_wait;
u8 line_control;
u8 line_status;
};
@@ -232,6 +233,7 @@ static int pl2303_port_probe(struct usb_serial_port *port)
return -ENOMEM;
spin_lock_init(&priv->lock);
+ init_waitqueue_head(&priv->delta_msr_wait);
usb_set_serial_port_data(port, priv);
@@ -605,14 +607,11 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg)
spin_unlock_irqrestore(&priv->lock, flags);
while (1) {
- interruptible_sleep_on(&port->delta_msr_wait);
+ interruptible_sleep_on(&priv->delta_msr_wait);
/* see if a signal did it */
if (signal_pending(current))
return -ERESTARTSYS;
- if (port->serial->disconnected)
- return -EIO;
-
spin_lock_irqsave(&priv->lock, flags);
status = priv->line_status;
spin_unlock_irqrestore(&priv->lock, flags);
@@ -720,7 +719,7 @@ static void pl2303_update_line_status(struct usb_serial_port *port,
spin_unlock_irqrestore(&priv->lock, flags);
if (priv->line_status & UART_BREAK_ERROR)
usb_serial_handle_break(port);
- wake_up_interruptible(&port->delta_msr_wait);
+ wake_up_interruptible(&priv->delta_msr_wait);
tty = tty_port_tty_get(&port->port);
if (!tty)
@@ -785,7 +784,7 @@ static void pl2303_process_read_urb(struct urb *urb)
line_status = priv->line_status;
priv->line_status &= ~UART_STATE_TRANSIENT_MASK;
spin_unlock_irqrestore(&priv->lock, flags);
- wake_up_interruptible(&port->delta_msr_wait);
+ wake_up_interruptible(&priv->delta_msr_wait);
if (!urb->actual_length)
return;
diff --git a/drivers/usb/serial/qcaux.c b/drivers/usb/serial/qcaux.c
index 31f81c3..9b1b96f 100644
--- a/drivers/usb/serial/qcaux.c
+++ b/drivers/usb/serial/qcaux.c
@@ -69,7 +69,6 @@ static struct usb_device_id id_table[] = {
{ USB_VENDOR_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, 0xff, 0xfd, 0xff) }, /* NMEA */
{ USB_VENDOR_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, 0xff, 0xfe, 0xff) }, /* WMC */
{ USB_VENDOR_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, 0xff, 0xff, 0xff) }, /* DIAG */
- { USB_DEVICE_AND_INTERFACE_INFO(0x1fac, 0x0151, 0xff, 0xff, 0xff) },
{ },
};
MODULE_DEVICE_TABLE(usb, id_table);
diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c
index 59b32b7..2466254 100644
--- a/drivers/usb/serial/qcserial.c
+++ b/drivers/usb/serial/qcserial.c
@@ -197,15 +197,12 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id)
if (is_gobi1k) {
/* Gobi 1K USB layout:
- * 0: DM/DIAG (use libqcdm from ModemManager for communication)
+ * 0: serial port (doesn't respond)
* 1: serial port (doesn't respond)
* 2: AT-capable modem port
* 3: QMI/net
*/
- if (ifnum == 0) {
- dev_dbg(dev, "Gobi 1K DM/DIAG interface found\n");
- altsetting = 1;
- } else if (ifnum == 2)
+ if (ifnum == 2)
dev_dbg(dev, "Modem port found\n");
else
altsetting = -1;
diff --git a/drivers/usb/serial/quatech2.c b/drivers/usb/serial/quatech2.c
index 9f34c99..d152be9 100644
--- a/drivers/usb/serial/quatech2.c
+++ b/drivers/usb/serial/quatech2.c
@@ -128,6 +128,7 @@ struct qt2_port_private {
u8 shadowLSR;
u8 shadowMSR;
+ wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */
struct async_icount icount;
struct usb_serial_port *port;
@@ -505,9 +506,8 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg)
spin_unlock_irqrestore(&priv->lock, flags);
while (1) {
- wait_event_interruptible(port->delta_msr_wait,
- (port->serial->disconnected ||
- (priv->icount.rng != prev.rng) ||
+ wait_event_interruptible(priv->delta_msr_wait,
+ ((priv->icount.rng != prev.rng) ||
(priv->icount.dsr != prev.dsr) ||
(priv->icount.dcd != prev.dcd) ||
(priv->icount.cts != prev.cts)));
@@ -515,9 +515,6 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg)
if (signal_pending(current))
return -ERESTARTSYS;
- if (port->serial->disconnected)
- return -EIO;
-
spin_lock_irqsave(&priv->lock, flags);
cur = priv->icount;
spin_unlock_irqrestore(&priv->lock, flags);
@@ -844,6 +841,7 @@ static int qt2_port_probe(struct usb_serial_port *port)
spin_lock_init(&port_priv->lock);
spin_lock_init(&port_priv->urb_lock);
+ init_waitqueue_head(&port_priv->delta_msr_wait);
port_priv->port = port;
port_priv->write_urb = usb_alloc_urb(0, GFP_KERNEL);
@@ -947,17 +945,19 @@ static void qt2_dtr_rts(struct usb_serial_port *port, int on)
struct usb_device *dev = port->serial->dev;
struct qt2_port_private *port_priv = usb_get_serial_port_data(port);
- /* Disable flow control */
- if (!on) {
- if (qt2_setregister(dev, port_priv->device_port,
+ mutex_lock(&port->serial->disc_mutex);
+ if (!port->serial->disconnected) {
+ /* Disable flow control */
+ if (!on && qt2_setregister(dev, port_priv->device_port,
UART_MCR, 0) < 0)
dev_warn(&port->dev, "error from flowcontrol urb\n");
+ /* drop RTS and DTR */
+ if (on)
+ update_mctrl(port_priv, TIOCM_DTR | TIOCM_RTS, 0);
+ else
+ update_mctrl(port_priv, 0, TIOCM_DTR | TIOCM_RTS);
}
- /* drop RTS and DTR */
- if (on)
- update_mctrl(port_priv, TIOCM_DTR | TIOCM_RTS, 0);
- else
- update_mctrl(port_priv, 0, TIOCM_DTR | TIOCM_RTS);
+ mutex_unlock(&port->serial->disc_mutex);
}
static void qt2_update_msr(struct usb_serial_port *port, unsigned char *ch)
@@ -986,7 +986,7 @@ static void qt2_update_msr(struct usb_serial_port *port, unsigned char *ch)
if (newMSR & UART_MSR_TERI)
port_priv->icount.rng++;
- wake_up_interruptible(&port->delta_msr_wait);
+ wake_up_interruptible(&port_priv->delta_msr_wait);
}
}
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c
index d4426c0..af06f2f 100644
--- a/drivers/usb/serial/sierra.c
+++ b/drivers/usb/serial/sierra.c
@@ -861,13 +861,19 @@ static int sierra_open(struct tty_struct *tty, struct usb_serial_port *port)
static void sierra_dtr_rts(struct usb_serial_port *port, int on)
{
+ struct usb_serial *serial = port->serial;
struct sierra_port_private *portdata;
portdata = usb_get_serial_port_data(port);
portdata->rts_state = on;
portdata->dtr_state = on;
- sierra_send_setup(port);
+ if (serial->dev) {
+ mutex_lock(&serial->disc_mutex);
+ if (!serial->disconnected)
+ sierra_send_setup(port);
+ mutex_unlock(&serial->disc_mutex);
+ }
}
static int sierra_startup(struct usb_serial *serial)
diff --git a/drivers/usb/serial/spcp8x5.c b/drivers/usb/serial/spcp8x5.c
index 85de44d..a42536a 100644
--- a/drivers/usb/serial/spcp8x5.c
+++ b/drivers/usb/serial/spcp8x5.c
@@ -149,6 +149,7 @@ enum spcp8x5_type {
struct spcp8x5_private {
spinlock_t lock;
enum spcp8x5_type type;
+ wait_queue_head_t delta_msr_wait;
u8 line_control;
u8 line_status;
};
@@ -178,6 +179,7 @@ static int spcp8x5_port_probe(struct usb_serial_port *port)
return -ENOMEM;
spin_lock_init(&priv->lock);
+ init_waitqueue_head(&priv->delta_msr_wait);
priv->type = type;
usb_set_serial_port_data(port , priv);
@@ -474,7 +476,7 @@ static void spcp8x5_process_read_urb(struct urb *urb)
priv->line_status &= ~UART_STATE_TRANSIENT_MASK;
spin_unlock_irqrestore(&priv->lock, flags);
/* wake up the wait for termios */
- wake_up_interruptible(&port->delta_msr_wait);
+ wake_up_interruptible(&priv->delta_msr_wait);
if (!urb->actual_length)
return;
@@ -524,15 +526,12 @@ static int spcp8x5_wait_modem_info(struct usb_serial_port *port,
while (1) {
/* wake up in bulk read */
- interruptible_sleep_on(&port->delta_msr_wait);
+ interruptible_sleep_on(&priv->delta_msr_wait);
/* see if a signal did it */
if (signal_pending(current))
return -ERESTARTSYS;
- if (port->serial->disconnected)
- return -EIO;
-
spin_lock_irqsave(&priv->lock, flags);
status = priv->line_status;
spin_unlock_irqrestore(&priv->lock, flags);
diff --git a/drivers/usb/serial/ssu100.c b/drivers/usb/serial/ssu100.c
index 44d5949..4543ea3 100644
--- a/drivers/usb/serial/ssu100.c
+++ b/drivers/usb/serial/ssu100.c
@@ -61,6 +61,7 @@ struct ssu100_port_private {
spinlock_t status_lock;
u8 shadowLSR;
u8 shadowMSR;
+ wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */
struct async_icount icount;
};
@@ -354,9 +355,8 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg)
spin_unlock_irqrestore(&priv->status_lock, flags);
while (1) {
- wait_event_interruptible(port->delta_msr_wait,
- (port->serial->disconnected ||
- (priv->icount.rng != prev.rng) ||
+ wait_event_interruptible(priv->delta_msr_wait,
+ ((priv->icount.rng != prev.rng) ||
(priv->icount.dsr != prev.dsr) ||
(priv->icount.dcd != prev.dcd) ||
(priv->icount.cts != prev.cts)));
@@ -364,9 +364,6 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg)
if (signal_pending(current))
return -ERESTARTSYS;
- if (port->serial->disconnected)
- return -EIO;
-
spin_lock_irqsave(&priv->status_lock, flags);
cur = priv->icount;
spin_unlock_irqrestore(&priv->status_lock, flags);
@@ -448,6 +445,7 @@ static int ssu100_port_probe(struct usb_serial_port *port)
return -ENOMEM;
spin_lock_init(&priv->status_lock);
+ init_waitqueue_head(&priv->delta_msr_wait);
usb_set_serial_port_data(port, priv);
@@ -508,16 +506,19 @@ static void ssu100_dtr_rts(struct usb_serial_port *port, int on)
{
struct usb_device *dev = port->serial->dev;
- /* Disable flow control */
- if (!on) {
- if (ssu100_setregister(dev, 0, UART_MCR, 0) < 0)
+ mutex_lock(&port->serial->disc_mutex);
+ if (!port->serial->disconnected) {
+ /* Disable flow control */
+ if (!on &&
+ ssu100_setregister(dev, 0, UART_MCR, 0) < 0)
dev_err(&port->dev, "error from flowcontrol urb\n");
+ /* drop RTS and DTR */
+ if (on)
+ set_mctrl(dev, TIOCM_DTR | TIOCM_RTS);
+ else
+ clear_mctrl(dev, TIOCM_DTR | TIOCM_RTS);
}
- /* drop RTS and DTR */
- if (on)
- set_mctrl(dev, TIOCM_DTR | TIOCM_RTS);
- else
- clear_mctrl(dev, TIOCM_DTR | TIOCM_RTS);
+ mutex_unlock(&port->serial->disc_mutex);
}
static void ssu100_update_msr(struct usb_serial_port *port, u8 msr)
@@ -539,7 +540,7 @@ static void ssu100_update_msr(struct usb_serial_port *port, u8 msr)
priv->icount.dcd++;
if (msr & UART_MSR_TERI)
priv->icount.rng++;
- wake_up_interruptible(&port->delta_msr_wait);
+ wake_up_interruptible(&priv->delta_msr_wait);
}
}
diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c
index 4a8b685..f2530d2 100644
--- a/drivers/usb/serial/ti_usb_3410_5052.c
+++ b/drivers/usb/serial/ti_usb_3410_5052.c
@@ -74,6 +74,7 @@ struct ti_port {
int tp_flags;
int tp_closing_wait;/* in .01 secs */
struct async_icount tp_icount;
+ wait_queue_head_t tp_msr_wait; /* wait for msr change */
wait_queue_head_t tp_write_wait;
struct ti_device *tp_tdev;
struct usb_serial_port *tp_port;
@@ -431,6 +432,7 @@ static int ti_port_probe(struct usb_serial_port *port)
else
tport->tp_uart_base_addr = TI_UART2_BASE_ADDR;
tport->tp_closing_wait = closing_wait;
+ init_waitqueue_head(&tport->tp_msr_wait);
init_waitqueue_head(&tport->tp_write_wait);
if (kfifo_alloc(&tport->write_fifo, TI_WRITE_BUF_SIZE, GFP_KERNEL)) {
kfree(tport);
@@ -782,13 +784,9 @@ static int ti_ioctl(struct tty_struct *tty,
dev_dbg(&port->dev, "%s - TIOCMIWAIT\n", __func__);
cprev = tport->tp_icount;
while (1) {
- interruptible_sleep_on(&port->delta_msr_wait);
+ interruptible_sleep_on(&tport->tp_msr_wait);
if (signal_pending(current))
return -ERESTARTSYS;
-
- if (port->serial->disconnected)
- return -EIO;
-
cnow = tport->tp_icount;
if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
@@ -1402,7 +1400,7 @@ static void ti_handle_new_msr(struct ti_port *tport, __u8 msr)
icount->dcd++;
if (msr & TI_MSR_DELTA_RI)
icount->rng++;
- wake_up_interruptible(&tport->tp_port->delta_msr_wait);
+ wake_up_interruptible(&tport->tp_msr_wait);
spin_unlock_irqrestore(&tport->tp_lock, flags);
}
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index dec95e8..64bda13 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -151,7 +151,6 @@ static void destroy_serial(struct kref *kref)
}
}
- usb_put_intf(serial->interface);
usb_put_dev(serial->dev);
kfree(serial);
}
@@ -615,7 +614,7 @@ static struct usb_serial *create_serial(struct usb_device *dev,
}
serial->dev = usb_get_dev(dev);
serial->type = driver;
- serial->interface = usb_get_intf(interface);
+ serial->interface = interface;
kref_init(&serial->kref);
mutex_init(&serial->disc_mutex);
serial->minor = SERIAL_TTY_NO_MINOR;
@@ -689,20 +688,10 @@ static int serial_carrier_raised(struct tty_port *port)
static void serial_dtr_rts(struct tty_port *port, int on)
{
struct usb_serial_port *p = container_of(port, struct usb_serial_port, port);
- struct usb_serial *serial = p->serial;
- struct usb_serial_driver *drv = serial->type;
+ struct usb_serial_driver *drv = p->serial->type;
- if (!drv->dtr_rts)
- return;
- /*
- * Work-around bug in the tty-layer which can result in dtr_rts
- * being called after a disconnect (and tty_unregister_device
- * has returned). Remove once bug has been squashed.
- */
- mutex_lock(&serial->disc_mutex);
- if (!serial->disconnected)
+ if (drv->dtr_rts)
drv->dtr_rts(p, on);
- mutex_unlock(&serial->disc_mutex);
}
static const struct tty_port_operations serial_port_ops = {
@@ -897,7 +886,6 @@ static int usb_serial_probe(struct usb_interface *interface,
port->port.ops = &serial_port_ops;
port->serial = serial;
spin_lock_init(&port->lock);
- init_waitqueue_head(&port->delta_msr_wait);
/* Keep this for private driver use for the moment but
should probably go away */
INIT_WORK(&port->work, usb_serial_port_work);
diff --git a/drivers/usb/serial/usb_wwan.c b/drivers/usb/serial/usb_wwan.c
index 1355a6c..01c94aa 100644
--- a/drivers/usb/serial/usb_wwan.c
+++ b/drivers/usb/serial/usb_wwan.c
@@ -38,6 +38,7 @@
void usb_wwan_dtr_rts(struct usb_serial_port *port, int on)
{
+ struct usb_serial *serial = port->serial;
struct usb_wwan_port_private *portdata;
struct usb_wwan_intf_private *intfdata;
@@ -47,11 +48,12 @@ void usb_wwan_dtr_rts(struct usb_serial_port *port, int on)
return;
portdata = usb_get_serial_port_data(port);
- /* FIXME: locking */
+ mutex_lock(&serial->disc_mutex);
portdata->rts_state = on;
portdata->dtr_state = on;
-
- intfdata->send_setup(port);
+ if (serial->dev)
+ intfdata->send_setup(port);
+ mutex_unlock(&serial->disc_mutex);
}
EXPORT_SYMBOL(usb_wwan_dtr_rts);
diff --git a/drivers/usb/storage/cypress_atacb.c b/drivers/usb/storage/cypress_atacb.c
index d944088..070b5c0 100644
--- a/drivers/usb/storage/cypress_atacb.c
+++ b/drivers/usb/storage/cypress_atacb.c
@@ -248,26 +248,14 @@ static int cypress_probe(struct usb_interface *intf,
{
struct us_data *us;
int result;
- struct usb_device *device;
result = usb_stor_probe1(&us, intf, id,
(id - cypress_usb_ids) + cypress_unusual_dev_list);
if (result)
return result;
- /* Among CY7C68300 chips, the A revision does not support Cypress ATACB
- * Filter out this revision from EEPROM default descriptor values
- */
- device = interface_to_usbdev(intf);
- if (device->descriptor.iManufacturer != 0x38 ||
- device->descriptor.iProduct != 0x4e ||
- device->descriptor.iSerialNumber != 0x64) {
- us->protocol_name = "Transparent SCSI with Cypress ATACB";
- us->proto_handler = cypress_atacb_passthrough;
- } else {
- us->protocol_name = "Transparent SCSI";
- us->proto_handler = usb_stor_transparent_scsi_command;
- }
+ us->protocol_name = "Transparent SCSI with Cypress ATACB";
+ us->proto_handler = cypress_atacb_passthrough;
result = usb_stor_probe2(us);
return result;
diff --git a/drivers/usb/storage/initializers.c b/drivers/usb/storage/initializers.c
index 105d900..16b0bf0 100644
--- a/drivers/usb/storage/initializers.c
+++ b/drivers/usb/storage/initializers.c
@@ -92,8 +92,8 @@ int usb_stor_ucr61s2b_init(struct us_data *us)
return 0;
}
-/* This places the HUAWEI E220 devices in multi-port mode */
-int usb_stor_huawei_e220_init(struct us_data *us)
+/* This places the HUAWEI usb dongles in multi-port mode */
+static int usb_stor_huawei_feature_init(struct us_data *us)
{
int result;
@@ -104,3 +104,75 @@ int usb_stor_huawei_e220_init(struct us_data *us)
US_DEBUGP("Huawei mode set result is %d\n", result);
return 0;
}
+
+/*
+ * It will send a scsi switch command called rewind' to huawei dongle.
+ * When the dongle receives this command at the first time,
+ * it will reboot immediately. After rebooted, it will ignore this command.
+ * So it is unnecessary to read its response.
+ */
+static int usb_stor_huawei_scsi_init(struct us_data *us)
+{
+ int result = 0;
+ int act_len = 0;
+ struct bulk_cb_wrap *bcbw = (struct bulk_cb_wrap *) us->iobuf;
+ char rewind_cmd[] = {0x11, 0x06, 0x20, 0x00, 0x00, 0x01, 0x01, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+ bcbw->Signature = cpu_to_le32(US_BULK_CB_SIGN);
+ bcbw->Tag = 0;
+ bcbw->DataTransferLength = 0;
+ bcbw->Flags = bcbw->Lun = 0;
+ bcbw->Length = sizeof(rewind_cmd);
+ memset(bcbw->CDB, 0, sizeof(bcbw->CDB));
+ memcpy(bcbw->CDB, rewind_cmd, sizeof(rewind_cmd));
+
+ result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, bcbw,
+ US_BULK_CB_WRAP_LEN, &act_len);
+ US_DEBUGP("transfer actual length=%d, result=%d\n", act_len, result);
+ return result;
+}
+
+/*
+ * It tries to find the supported Huawei USB dongles.
+ * In Huawei, they assign the following product IDs
+ * for all of their mobile broadband dongles,
+ * including the new dongles in the future.
+ * So if the product ID is not included in this list,
+ * it means it is not Huawei's mobile broadband dongles.
+ */
+static int usb_stor_huawei_dongles_pid(struct us_data *us)
+{
+ struct usb_interface_descriptor *idesc;
+ int idProduct;
+
+ idesc = &us->pusb_intf->cur_altsetting->desc;
+ idProduct = us->pusb_dev->descriptor.idProduct;
+ /* The first port is CDROM,
+ * means the dongle in the single port mode,
+ * and a switch command is required to be sent. */
+ if (idesc && idesc->bInterfaceNumber == 0) {
+ if ((idProduct == 0x1001)
+ || (idProduct == 0x1003)
+ || (idProduct == 0x1004)
+ || (idProduct >= 0x1401 && idProduct <= 0x1500)
+ || (idProduct >= 0x1505 && idProduct <= 0x1600)
+ || (idProduct >= 0x1c02 && idProduct <= 0x2202)) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+int usb_stor_huawei_init(struct us_data *us)
+{
+ int result = 0;
+
+ if (usb_stor_huawei_dongles_pid(us)) {
+ if (us->pusb_dev->descriptor.idProduct >= 0x1446)
+ result = usb_stor_huawei_scsi_init(us);
+ else
+ result = usb_stor_huawei_feature_init(us);
+ }
+ return result;
+}
diff --git a/drivers/usb/storage/initializers.h b/drivers/usb/storage/initializers.h
index 529327f..5376d4f 100644
--- a/drivers/usb/storage/initializers.h
+++ b/drivers/usb/storage/initializers.h
@@ -46,5 +46,5 @@ int usb_stor_euscsi_init(struct us_data *us);
* flash reader */
int usb_stor_ucr61s2b_init(struct us_data *us);
-/* This places the HUAWEI E220 devices in multi-port mode */
-int usb_stor_huawei_e220_init(struct us_data *us);
+/* This places the HUAWEI usb dongles in multi-port mode */
+int usb_stor_huawei_init(struct us_data *us);
diff --git a/drivers/usb/storage/unusual_cypress.h b/drivers/usb/storage/unusual_cypress.h
index 65a6a75..2c85530 100644
--- a/drivers/usb/storage/unusual_cypress.h
+++ b/drivers/usb/storage/unusual_cypress.h
@@ -31,7 +31,7 @@ UNUSUAL_DEV( 0x04b4, 0x6831, 0x0000, 0x9999,
"Cypress ISD-300LP",
USB_SC_CYP_ATACB, USB_PR_DEVICE, NULL, 0),
-UNUSUAL_DEV( 0x14cd, 0x6116, 0x0000, 0x0219,
+UNUSUAL_DEV( 0x14cd, 0x6116, 0x0000, 0x9999,
"Super Top",
"USB 2.0 SATA BRIDGE",
USB_SC_CYP_ATACB, USB_PR_DEVICE, NULL, 0),
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
index b75e90b..72923b5 100644
--- a/drivers/usb/storage/unusual_devs.h
+++ b/drivers/usb/storage/unusual_devs.h
@@ -488,13 +488,6 @@ UNUSUAL_DEV( 0x04e8, 0x5122, 0x0000, 0x9999,
USB_SC_DEVICE, USB_PR_DEVICE, NULL,
US_FL_MAX_SECTORS_64 | US_FL_BULK_IGNORE_TAG),
-/* Added by Dmitry Artamonow <mad_soft@inbox.ru> */
-UNUSUAL_DEV( 0x04e8, 0x5136, 0x0000, 0x9999,
- "Samsung",
- "YP-Z3",
- USB_SC_DEVICE, USB_PR_DEVICE, NULL,
- US_FL_MAX_SECTORS_64),
-
/* Entry and supporting patch by Theodore Kilgore <kilgota@auburn.edu>.
* Device uses standards-violating 32-byte Bulk Command Block Wrappers and
* reports itself as "Proprietary SCSI Bulk." Cf. device entry 0x084d:0x0011.
@@ -1534,335 +1527,10 @@ UNUSUAL_DEV( 0x1210, 0x0003, 0x0100, 0x0100,
/* Reported by fangxiaozhi <huananhu@huawei.com>
* This brings the HUAWEI data card devices into multi-port mode
*/
-UNUSUAL_DEV( 0x12d1, 0x1001, 0x0000, 0x0000,
- "HUAWEI MOBILE",
- "Mass Storage",
- USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
- 0),
-UNUSUAL_DEV( 0x12d1, 0x1003, 0x0000, 0x0000,
- "HUAWEI MOBILE",
- "Mass Storage",
- USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
- 0),
-UNUSUAL_DEV( 0x12d1, 0x1004, 0x0000, 0x0000,
- "HUAWEI MOBILE",
- "Mass Storage",
- USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
- 0),
-UNUSUAL_DEV( 0x12d1, 0x1401, 0x0000, 0x0000,
- "HUAWEI MOBILE",
- "Mass Storage",
- USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
- 0),
-UNUSUAL_DEV( 0x12d1, 0x1402, 0x0000, 0x0000,
- "HUAWEI MOBILE",
- "Mass Storage",
- USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
- 0),
-UNUSUAL_DEV( 0x12d1, 0x1403, 0x0000, 0x0000,
- "HUAWEI MOBILE",
- "Mass Storage",
- USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
- 0),
-UNUSUAL_DEV( 0x12d1, 0x1404, 0x0000, 0x0000,
- "HUAWEI MOBILE",
- "Mass Storage",
- USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
- 0),
-UNUSUAL_DEV( 0x12d1, 0x1405, 0x0000, 0x0000,
- "HUAWEI MOBILE",
- "Mass Storage",
- USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
- 0),
-UNUSUAL_DEV( 0x12d1, 0x1406, 0x0000, 0x0000,
- "HUAWEI MOBILE",
- "Mass Storage",
- USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
- 0),
-UNUSUAL_DEV( 0x12d1, 0x1407, 0x0000, 0x0000,
- "HUAWEI MOBILE",
- "Mass Storage",
- USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
- 0),
-UNUSUAL_DEV( 0x12d1, 0x1408, 0x0000, 0x0000,
- "HUAWEI MOBILE",
- "Mass Storage",
- USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
- 0),
-UNUSUAL_DEV( 0x12d1, 0x1409, 0x0000, 0x0000,
- "HUAWEI MOBILE",
- "Mass Storage",
- USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
- 0),
-UNUSUAL_DEV( 0x12d1, 0x140A, 0x0000, 0x0000,
- "HUAWEI MOBILE",
- "Mass Storage",
- USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
- 0),
-UNUSUAL_DEV( 0x12d1, 0x140B, 0x0000, 0x0000,
- "HUAWEI MOBILE",
- "Mass Storage",
- USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
- 0),
-UNUSUAL_DEV( 0x12d1, 0x140C, 0x0000, 0x0000,
- "HUAWEI MOBILE",
- "Mass Storage",
- USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
- 0),
-UNUSUAL_DEV( 0x12d1, 0x140D, 0x0000, 0x0000,
- "HUAWEI MOBILE",
- "Mass Storage",
- USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
- 0),
-UNUSUAL_DEV( 0x12d1, 0x140E, 0x0000, 0x0000,
- "HUAWEI MOBILE",
- "Mass Storage",
- USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
- 0),
-UNUSUAL_DEV( 0x12d1, 0x140F, 0x0000, 0x0000,
- "HUAWEI MOBILE",
- "Mass Storage",
- USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
- 0),
-UNUSUAL_DEV( 0x12d1, 0x1410, 0x0000, 0x0000,
- "HUAWEI MOBILE",
- "Mass Storage",
- USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
- 0),
-UNUSUAL_DEV( 0x12d1, 0x1411, 0x0000, 0x0000,
- "HUAWEI MOBILE",
- "Mass Storage",
- USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
- 0),
-UNUSUAL_DEV( 0x12d1, 0x1412, 0x0000, 0x0000,
- "HUAWEI MOBILE",
- "Mass Storage",
- USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
- 0),
-UNUSUAL_DEV( 0x12d1, 0x1413, 0x0000, 0x0000,
- "HUAWEI MOBILE",
- "Mass Storage",
- USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
- 0),
-UNUSUAL_DEV( 0x12d1, 0x1414, 0x0000, 0x0000,
- "HUAWEI MOBILE",
- "Mass Storage",
- USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
- 0),
-UNUSUAL_DEV( 0x12d1, 0x1415, 0x0000, 0x0000,
- "HUAWEI MOBILE",
- "Mass Storage",
- USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
- 0),
-UNUSUAL_DEV( 0x12d1, 0x1416, 0x0000, 0x0000,
- "HUAWEI MOBILE",
- "Mass Storage",
- USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
- 0),
-UNUSUAL_DEV( 0x12d1, 0x1417, 0x0000, 0x0000,
- "HUAWEI MOBILE",
- "Mass Storage",
- USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
- 0),
-UNUSUAL_DEV( 0x12d1, 0x1418, 0x0000, 0x0000,
- "HUAWEI MOBILE",
- "Mass Storage",
- USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
- 0),
-UNUSUAL_DEV( 0x12d1, 0x1419, 0x0000, 0x0000,
- "HUAWEI MOBILE",
- "Mass Storage",
- USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
- 0),
-UNUSUAL_DEV( 0x12d1, 0x141A, 0x0000, 0x0000,
- "HUAWEI MOBILE",
- "Mass Storage",
- USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
- 0),
-UNUSUAL_DEV( 0x12d1, 0x141B, 0x0000, 0x0000,
- "HUAWEI MOBILE",
- "Mass Storage",
- USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
- 0),
-UNUSUAL_DEV( 0x12d1, 0x141C, 0x0000, 0x0000,
- "HUAWEI MOBILE",
- "Mass Storage",
- USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
- 0),
-UNUSUAL_DEV( 0x12d1, 0x141D, 0x0000, 0x0000,
- "HUAWEI MOBILE",
- "Mass Storage",
- USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
- 0),
-UNUSUAL_DEV( 0x12d1, 0x141E, 0x0000, 0x0000,
- "HUAWEI MOBILE",
- "Mass Storage",
- USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
- 0),
-UNUSUAL_DEV( 0x12d1, 0x141F, 0x0000, 0x0000,
- "HUAWEI MOBILE",
- "Mass Storage",
- USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
- 0),
-UNUSUAL_DEV( 0x12d1, 0x1420, 0x0000, 0x0000,
- "HUAWEI MOBILE",
- "Mass Storage",
- USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
- 0),
-UNUSUAL_DEV( 0x12d1, 0x1421, 0x0000, 0x0000,
- "HUAWEI MOBILE",
- "Mass Storage",
- USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
- 0),
-UNUSUAL_DEV( 0x12d1, 0x1422, 0x0000, 0x0000,
- "HUAWEI MOBILE",
- "Mass Storage",
- USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
- 0),
-UNUSUAL_DEV( 0x12d1, 0x1423, 0x0000, 0x0000,
- "HUAWEI MOBILE",
- "Mass Storage",
- USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
- 0),
-UNUSUAL_DEV( 0x12d1, 0x1424, 0x0000, 0x0000,
- "HUAWEI MOBILE",
- "Mass Storage",
- USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
- 0),
-UNUSUAL_DEV( 0x12d1, 0x1425, 0x0000, 0x0000,
- "HUAWEI MOBILE",
- "Mass Storage",
- USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
- 0),
-UNUSUAL_DEV( 0x12d1, 0x1426, 0x0000, 0x0000,
- "HUAWEI MOBILE",
- "Mass Storage",
- USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
- 0),
-UNUSUAL_DEV( 0x12d1, 0x1427, 0x0000, 0x0000,
- "HUAWEI MOBILE",
- "Mass Storage",
- USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
- 0),
-UNUSUAL_DEV( 0x12d1, 0x1428, 0x0000, 0x0000,
- "HUAWEI MOBILE",
- "Mass Storage",
- USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
- 0),
-UNUSUAL_DEV( 0x12d1, 0x1429, 0x0000, 0x0000,
- "HUAWEI MOBILE",
- "Mass Storage",
- USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
- 0),
-UNUSUAL_DEV( 0x12d1, 0x142A, 0x0000, 0x0000,
- "HUAWEI MOBILE",
- "Mass Storage",
- USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
- 0),
-UNUSUAL_DEV( 0x12d1, 0x142B, 0x0000, 0x0000,
- "HUAWEI MOBILE",
- "Mass Storage",
- USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
- 0),
-UNUSUAL_DEV( 0x12d1, 0x142C, 0x0000, 0x0000,
- "HUAWEI MOBILE",
- "Mass Storage",
- USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
- 0),
-UNUSUAL_DEV( 0x12d1, 0x142D, 0x0000, 0x0000,
- "HUAWEI MOBILE",
- "Mass Storage",
- USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
- 0),
-UNUSUAL_DEV( 0x12d1, 0x142E, 0x0000, 0x0000,
- "HUAWEI MOBILE",
- "Mass Storage",
- USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
- 0),
-UNUSUAL_DEV( 0x12d1, 0x142F, 0x0000, 0x0000,
- "HUAWEI MOBILE",
- "Mass Storage",
- USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
- 0),
-UNUSUAL_DEV( 0x12d1, 0x1430, 0x0000, 0x0000,
- "HUAWEI MOBILE",
- "Mass Storage",
- USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
- 0),
-UNUSUAL_DEV( 0x12d1, 0x1431, 0x0000, 0x0000,
- "HUAWEI MOBILE",
- "Mass Storage",
- USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
- 0),
-UNUSUAL_DEV( 0x12d1, 0x1432, 0x0000, 0x0000,
- "HUAWEI MOBILE",
- "Mass Storage",
- USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
- 0),
-UNUSUAL_DEV( 0x12d1, 0x1433, 0x0000, 0x0000,
- "HUAWEI MOBILE",
- "Mass Storage",
- USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
- 0),
-UNUSUAL_DEV( 0x12d1, 0x1434, 0x0000, 0x0000,
- "HUAWEI MOBILE",
- "Mass Storage",
- USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
- 0),
-UNUSUAL_DEV( 0x12d1, 0x1435, 0x0000, 0x0000,
- "HUAWEI MOBILE",
- "Mass Storage",
- USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
- 0),
-UNUSUAL_DEV( 0x12d1, 0x1436, 0x0000, 0x0000,
- "HUAWEI MOBILE",
- "Mass Storage",
- USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
- 0),
-UNUSUAL_DEV( 0x12d1, 0x1437, 0x0000, 0x0000,
- "HUAWEI MOBILE",
- "Mass Storage",
- USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
- 0),
-UNUSUAL_DEV( 0x12d1, 0x1438, 0x0000, 0x0000,
- "HUAWEI MOBILE",
- "Mass Storage",
- USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
- 0),
-UNUSUAL_DEV( 0x12d1, 0x1439, 0x0000, 0x0000,
- "HUAWEI MOBILE",
- "Mass Storage",
- USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
- 0),
-UNUSUAL_DEV( 0x12d1, 0x143A, 0x0000, 0x0000,
- "HUAWEI MOBILE",
- "Mass Storage",
- USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
- 0),
-UNUSUAL_DEV( 0x12d1, 0x143B, 0x0000, 0x0000,
- "HUAWEI MOBILE",
- "Mass Storage",
- USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
- 0),
-UNUSUAL_DEV( 0x12d1, 0x143C, 0x0000, 0x0000,
- "HUAWEI MOBILE",
- "Mass Storage",
- USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
- 0),
-UNUSUAL_DEV( 0x12d1, 0x143D, 0x0000, 0x0000,
- "HUAWEI MOBILE",
- "Mass Storage",
- USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
- 0),
-UNUSUAL_DEV( 0x12d1, 0x143E, 0x0000, 0x0000,
- "HUAWEI MOBILE",
- "Mass Storage",
- USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
- 0),
-UNUSUAL_DEV( 0x12d1, 0x143F, 0x0000, 0x0000,
+UNUSUAL_VENDOR_INTF(0x12d1, 0x08, 0x06, 0x50,
"HUAWEI MOBILE",
"Mass Storage",
- USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_init,
0),
/* Reported by Vilius Bilinkevicius <vilisas AT xxx DOT lt) */
diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c
index 4a62e12..b28e66c 100644
--- a/drivers/vfio/pci/vfio_pci.c
+++ b/drivers/vfio/pci/vfio_pci.c
@@ -331,7 +331,6 @@ static long vfio_pci_ioctl(void *device_data,
if (!(hdr.flags & VFIO_IRQ_SET_DATA_NONE)) {
size_t size;
- int max = vfio_pci_get_irq_count(vdev, hdr.index);
if (hdr.flags & VFIO_IRQ_SET_DATA_BOOL)
size = sizeof(uint8_t);
@@ -341,7 +340,7 @@ static long vfio_pci_ioctl(void *device_data,
return -EINVAL;
if (hdr.argsz - minsz < hdr.count * size ||
- hdr.start >= max || hdr.start + hdr.count > max)
+ hdr.count > vfio_pci_get_irq_count(vdev, hdr.index))
return -EINVAL;
data = memdup_user((void __user *)(arg + minsz),
diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
index ec6fb3f..959b1cd 100644
--- a/drivers/vhost/net.c
+++ b/drivers/vhost/net.c
@@ -339,8 +339,7 @@ static void handle_tx(struct vhost_net *net)
msg.msg_controllen = 0;
ubufs = NULL;
} else {
- struct ubuf_info *ubuf;
- ubuf = vq->ubuf_info + vq->upend_idx;
+ struct ubuf_info *ubuf = &vq->ubuf_info[head];
vq->heads[vq->upend_idx].len =
VHOST_DMA_IN_PROGRESS;
diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c
index 025428e..12cf5f3 100644
--- a/drivers/video/atmel_lcdfb.c
+++ b/drivers/video/atmel_lcdfb.c
@@ -422,22 +422,17 @@ static int atmel_lcdfb_check_var(struct fb_var_screeninfo *var,
= var->bits_per_pixel;
break;
case 16:
- /* Older SOCs use IBGR:555 rather than BGR:565. */
- if (sinfo->have_intensity_bit)
- var->green.length = 5;
- else
- var->green.length = 6;
-
if (sinfo->lcd_wiring_mode == ATMEL_LCDC_WIRING_RGB) {
- /* RGB:5X5 mode */
- var->red.offset = var->green.length + 5;
+ /* RGB:565 mode */
+ var->red.offset = 11;
var->blue.offset = 0;
} else {
- /* BGR:5X5 mode */
+ /* BGR:565 mode */
var->red.offset = 0;
- var->blue.offset = var->green.length + 5;
+ var->blue.offset = 11;
}
var->green.offset = 5;
+ var->green.length = 6;
var->red.length = var->blue.length = 5;
break;
case 32:
@@ -684,7 +679,8 @@ static int atmel_lcdfb_setcolreg(unsigned int regno, unsigned int red,
case FB_VISUAL_PSEUDOCOLOR:
if (regno < 256) {
- if (sinfo->have_intensity_bit) {
+ if (cpu_is_at91sam9261() || cpu_is_at91sam9263()
+ || cpu_is_at91sam9rl()) {
/* old style I+BGR:555 */
val = ((red >> 11) & 0x001f);
val |= ((green >> 6) & 0x03e0);
@@ -874,10 +870,6 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev)
}
sinfo->info = info;
sinfo->pdev = pdev;
- if (cpu_is_at91sam9261() || cpu_is_at91sam9263() ||
- cpu_is_at91sam9rl()) {
- sinfo->have_intensity_bit = true;
- }
strcpy(info->fix.id, sinfo->pdev->name);
info->flags = ATMEL_LCDFB_FBINFO_DEFAULT;
diff --git a/drivers/video/backlight/adp8860_bl.c b/drivers/video/backlight/adp8860_bl.c
index a77c9ca..6bb72c0 100644
--- a/drivers/video/backlight/adp8860_bl.c
+++ b/drivers/video/backlight/adp8860_bl.c
@@ -783,7 +783,7 @@ static int adp8860_i2c_suspend(struct i2c_client *client, pm_message_t message)
static int adp8860_i2c_resume(struct i2c_client *client)
{
- adp8860_set_bits(client, ADP8860_MDCR, NSTBY | BLEN);
+ adp8860_set_bits(client, ADP8860_MDCR, NSTBY);
return 0;
}
diff --git a/drivers/video/backlight/adp8870_bl.c b/drivers/video/backlight/adp8870_bl.c
index 712c25a..63c882b 100644
--- a/drivers/video/backlight/adp8870_bl.c
+++ b/drivers/video/backlight/adp8870_bl.c
@@ -957,7 +957,7 @@ static int adp8870_i2c_suspend(struct i2c_client *client, pm_message_t message)
static int adp8870_i2c_resume(struct i2c_client *client)
{
- adp8870_set_bits(client, ADP8870_MDCR, NSTBY | BLEN);
+ adp8870_set_bits(client, ADP8870_MDCR, NSTBY);
return 0;
}
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index 6e696e6..fdefa8f 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -529,33 +529,6 @@ static int search_for_mapped_con(void)
return retval;
}
-static int do_fbcon_takeover(int show_logo)
-{
- int err, i;
-
- if (!num_registered_fb)
- return -ENODEV;
-
- if (!show_logo)
- logo_shown = FBCON_LOGO_DONTSHOW;
-
- for (i = first_fb_vc; i <= last_fb_vc; i++)
- con2fb_map[i] = info_idx;
-
- err = do_take_over_console(&fb_con, first_fb_vc, last_fb_vc,
- fbcon_is_default);
-
- if (err) {
- for (i = first_fb_vc; i <= last_fb_vc; i++)
- con2fb_map[i] = -1;
- info_idx = -1;
- } else {
- fbcon_has_console_bind = 1;
- }
-
- return err;
-}
-
static int fbcon_takeover(int show_logo)
{
int err, i;
@@ -842,8 +815,6 @@ static void con2fb_init_display(struct vc_data *vc, struct fb_info *info,
*
* Maps a virtual console @unit to a frame buffer device
* @newidx.
- *
- * This should be called with the console lock held.
*/
static int set_con2fb_map(int unit, int newidx, int user)
{
@@ -861,7 +832,7 @@ static int set_con2fb_map(int unit, int newidx, int user)
if (!search_for_mapped_con() || !con_is_bound(&fb_con)) {
info_idx = newidx;
- return do_fbcon_takeover(0);
+ return fbcon_takeover(0);
}
if (oldidx != -1)
@@ -869,6 +840,7 @@ static int set_con2fb_map(int unit, int newidx, int user)
found = search_fb_in_map(newidx);
+ console_lock();
con2fb_map[unit] = newidx;
if (!err && !found)
err = con2fb_acquire_newinfo(vc, info, unit, oldidx);
@@ -895,6 +867,7 @@ static int set_con2fb_map(int unit, int newidx, int user)
if (!search_fb_in_map(info_idx))
info_idx = newidx;
+ console_unlock();
return err;
}
@@ -1017,7 +990,7 @@ static const char *fbcon_startup(void)
}
/* Setup default font */
- if (!p->fontdata && !vc->vc_font.data) {
+ if (!p->fontdata) {
if (!fontname[0] || !(font = find_font(fontname)))
font = get_default_font(info->var.xres,
info->var.yres,
@@ -1027,8 +1000,6 @@ static const char *fbcon_startup(void)
vc->vc_font.height = font->height;
vc->vc_font.data = (void *)(p->fontdata = font->data);
vc->vc_font.charcount = 256; /* FIXME Need to support more fonts */
- } else {
- p->fontdata = vc->vc_font.data;
}
cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
@@ -1188,9 +1159,9 @@ static void fbcon_init(struct vc_data *vc, int init)
ops->p = &fb_display[fg_console];
}
-static void fbcon_free_font(struct display *p, bool freefont)
+static void fbcon_free_font(struct display *p)
{
- if (freefont && p->userfont && p->fontdata && (--REFCOUNT(p->fontdata) == 0))
+ if (p->userfont && p->fontdata && (--REFCOUNT(p->fontdata) == 0))
kfree(p->fontdata - FONT_EXTRA_WORDS * sizeof(int));
p->fontdata = NULL;
p->userfont = 0;
@@ -1202,8 +1173,8 @@ static void fbcon_deinit(struct vc_data *vc)
struct fb_info *info;
struct fbcon_ops *ops;
int idx;
- bool free_font = true;
+ fbcon_free_font(p);
idx = con2fb_map[vc->vc_num];
if (idx == -1)
@@ -1214,8 +1185,6 @@ static void fbcon_deinit(struct vc_data *vc)
if (!info)
goto finished;
- if (info->flags & FBINFO_MISC_FIRMWARE)
- free_font = false;
ops = info->fbcon_par;
if (!ops)
@@ -1227,10 +1196,6 @@ static void fbcon_deinit(struct vc_data *vc)
ops->flags &= ~FBCON_FLAGS_INIT;
finished:
- fbcon_free_font(p, free_font);
- if (free_font)
- vc->vc_font.data = NULL;
-
if (!con_is_bound(&fb_con))
fbcon_exit();
@@ -3012,7 +2977,7 @@ static int fbcon_unbind(void)
{
int ret;
- ret = do_unbind_con_driver(&fb_con, first_fb_vc, last_fb_vc,
+ ret = unbind_con_driver(&fb_con, first_fb_vc, last_fb_vc,
fbcon_is_default);
if (!ret)
@@ -3027,7 +2992,6 @@ static inline int fbcon_unbind(void)
}
#endif /* CONFIG_VT_HW_CONSOLE_BINDING */
-/* called with console_lock held */
static int fbcon_fb_unbind(int idx)
{
int i, new_idx = -1, ret = 0;
@@ -3054,7 +3018,6 @@ static int fbcon_fb_unbind(int idx)
return ret;
}
-/* called with console_lock held */
static int fbcon_fb_unregistered(struct fb_info *info)
{
int i, idx;
@@ -3087,12 +3050,11 @@ static int fbcon_fb_unregistered(struct fb_info *info)
primary_device = -1;
if (!num_registered_fb)
- do_unregister_con_driver(&fb_con);
+ unregister_con_driver(&fb_con);
return 0;
}
-/* called with console_lock held */
static void fbcon_remap_all(int idx)
{
int i;
@@ -3137,7 +3099,6 @@ static inline void fbcon_select_primary(struct fb_info *info)
}
#endif /* CONFIG_FRAMEBUFFER_DETECT_PRIMARY */
-/* called with console_lock held */
static int fbcon_fb_registered(struct fb_info *info)
{
int ret = 0, i, idx;
@@ -3154,7 +3115,7 @@ static int fbcon_fb_registered(struct fb_info *info)
}
if (info_idx != -1)
- ret = do_fbcon_takeover(1);
+ ret = fbcon_takeover(1);
} else {
for (i = first_fb_vc; i <= last_fb_vc; i++) {
if (con2fb_map_boot[i] == idx)
@@ -3290,7 +3251,6 @@ static int fbcon_event_notify(struct notifier_block *self,
ret = fbcon_fb_unregistered(info);
break;
case FB_EVENT_SET_CONSOLE_MAP:
- /* called with console lock held */
con2fb = event->data;
ret = set_con2fb_map(con2fb->console - 1,
con2fb->framebuffer, 1);
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index 5855d17..d449a74 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -1064,7 +1064,7 @@ static int vgacon_do_font_op(struct vgastate *state,char *arg,int set,int ch512)
unsigned short video_port_status = vga_video_port_reg + 6;
int font_select = 0x00, beg, i;
char *charmap;
- bool clear_attribs = false;
+
if (vga_video_type != VIDEO_TYPE_EGAM) {
charmap = (char *) VGA_MAP_MEM(colourmap, 0);
beg = 0x0e;
@@ -1169,6 +1169,12 @@ static int vgacon_do_font_op(struct vgastate *state,char *arg,int set,int ch512)
/* if 512 char mode is already enabled don't re-enable it. */
if ((set) && (ch512 != vga_512_chars)) {
+ /* attribute controller */
+ for (i = 0; i < MAX_NR_CONSOLES; i++) {
+ struct vc_data *c = vc_cons[i].d;
+ if (c && c->vc_sw == &vga_con)
+ c->vc_hi_font_mask = ch512 ? 0x0800 : 0;
+ }
vga_512_chars = ch512;
/* 256-char: enable intensity bit
512-char: disable intensity bit */
@@ -1179,22 +1185,8 @@ static int vgacon_do_font_op(struct vgastate *state,char *arg,int set,int ch512)
it means, but it works, and it appears necessary */
inb_p(video_port_status);
vga_wattr(state->vgabase, VGA_AR_ENABLE_DISPLAY, 0);
- clear_attribs = true;
}
raw_spin_unlock_irq(&vga_lock);
-
- if (clear_attribs) {
- for (i = 0; i < MAX_NR_CONSOLES; i++) {
- struct vc_data *c = vc_cons[i].d;
- if (c && c->vc_sw == &vga_con) {
- /* force hi font mask to 0, so we always clear
- the bit on either transition */
- c->vc_hi_font_mask = 0x00;
- clear_buffer_attributes(c);
- c->vc_hi_font_mask = ch512 ? 0x0800 : 0;
- }
- }
- }
return 0;
}
diff --git a/drivers/video/ep93xx-fb.c b/drivers/video/ep93xx-fb.c
index e06cd5d..3f2519d 100644
--- a/drivers/video/ep93xx-fb.c
+++ b/drivers/video/ep93xx-fb.c
@@ -23,7 +23,6 @@
#include <linux/slab.h>
#include <linux/clk.h>
#include <linux/fb.h>
-#include <linux/io.h>
#include <linux/platform_data/video-ep93xx.h>
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index 0a49456..3ff0105 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -1177,10 +1177,8 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd,
event.data = &con2fb;
if (!lock_fb_info(info))
return -ENODEV;
- console_lock();
event.info = info;
ret = fb_notifier_call_chain(FB_EVENT_SET_CONSOLE_MAP, &event);
- console_unlock();
unlock_fb_info(info);
break;
case FBIOBLANK:
@@ -1373,12 +1371,15 @@ fb_mmap(struct file *file, struct vm_area_struct * vma)
{
struct fb_info *info = file_fb_info(file);
struct fb_ops *fb;
- unsigned long mmio_pgoff;
+ unsigned long off;
unsigned long start;
u32 len;
if (!info)
return -ENODEV;
+ if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
+ return -EINVAL;
+ off = vma->vm_pgoff << PAGE_SHIFT;
fb = info->fbops;
if (!fb)
return -ENODEV;
@@ -1390,24 +1391,32 @@ fb_mmap(struct file *file, struct vm_area_struct * vma)
return res;
}
- /*
- * Ugh. This can be either the frame buffer mapping, or
- * if pgoff points past it, the mmio mapping.
- */
+ /* frame buffer memory */
start = info->fix.smem_start;
- len = info->fix.smem_len;
- mmio_pgoff = PAGE_ALIGN((start & ~PAGE_MASK) + len) >> PAGE_SHIFT;
- if (vma->vm_pgoff >= mmio_pgoff) {
- vma->vm_pgoff -= mmio_pgoff;
+ len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.smem_len);
+ if (off >= len) {
+ /* memory mapped io */
+ off -= len;
+ if (info->var.accel_flags) {
+ mutex_unlock(&info->mm_lock);
+ return -EINVAL;
+ }
start = info->fix.mmio_start;
- len = info->fix.mmio_len;
+ len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.mmio_len);
}
mutex_unlock(&info->mm_lock);
-
+ start &= PAGE_MASK;
+ if ((vma->vm_end - vma->vm_start + off) > len)
+ return -EINVAL;
+ off += start;
+ vma->vm_pgoff = off >> PAGE_SHIFT;
+ /* VM_IO | VM_DONTEXPAND | VM_DONTDUMP are set by io_remap_pfn_range()*/
vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
- fb_pgprotect(file, vma, start);
-
- return vm_iomap_memory(vma, start, len);
+ fb_pgprotect(file, vma, off);
+ if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
+ vma->vm_end - vma->vm_start, vma->vm_page_prot))
+ return -EAGAIN;
+ return 0;
}
static int
@@ -1641,9 +1650,7 @@ static int do_register_framebuffer(struct fb_info *fb_info)
event.info = fb_info;
if (!lock_fb_info(fb_info))
return -ENODEV;
- console_lock();
fb_notifier_call_chain(FB_EVENT_FB_REGISTERED, &event);
- console_unlock();
unlock_fb_info(fb_info);
return 0;
}
@@ -1659,10 +1666,8 @@ static int do_unregister_framebuffer(struct fb_info *fb_info)
if (!lock_fb_info(fb_info))
return -ENODEV;
- console_lock();
event.info = fb_info;
ret = fb_notifier_call_chain(FB_EVENT_FB_UNBIND, &event);
- console_unlock();
unlock_fb_info(fb_info);
if (ret)
@@ -1677,9 +1682,7 @@ static int do_unregister_framebuffer(struct fb_info *fb_info)
num_registered_fb--;
fb_cleanup_device(fb_info);
event.info = fb_info;
- console_lock();
fb_notifier_call_chain(FB_EVENT_FB_UNREGISTERED, &event);
- console_unlock();
/* this may free fb info */
put_fb_info(fb_info);
@@ -1850,8 +1853,11 @@ int fb_new_modelist(struct fb_info *info)
err = 1;
if (!list_empty(&info->modelist)) {
+ if (!lock_fb_info(info))
+ return -ENODEV;
event.info = info;
err = fb_notifier_call_chain(FB_EVENT_NEW_MODELIST, &event);
+ unlock_fb_info(info);
}
return err;
diff --git a/drivers/video/fbsysfs.c b/drivers/video/fbsysfs.c
index ef476b0..a55e366 100644
--- a/drivers/video/fbsysfs.c
+++ b/drivers/video/fbsysfs.c
@@ -177,8 +177,6 @@ static ssize_t store_modes(struct device *device,
if (i * sizeof(struct fb_videomode) != count)
return -EINVAL;
- if (!lock_fb_info(fb_info))
- return -ENODEV;
console_lock();
list_splice(&fb_info->modelist, &old_list);
fb_videomode_to_modelist((const struct fb_videomode *)buf, i,
@@ -190,7 +188,6 @@ static ssize_t store_modes(struct device *device,
fb_destroy_modelist(&old_list);
console_unlock();
- unlock_fb_info(fb_info);
return 0;
}
diff --git a/drivers/video/fsl-diu-fb.c b/drivers/video/fsl-diu-fb.c
index 41fbd94..19cfd7a 100644
--- a/drivers/video/fsl-diu-fb.c
+++ b/drivers/video/fsl-diu-fb.c
@@ -944,7 +944,7 @@ static u32 fsl_diu_get_pixel_format(unsigned int bits_per_pixel)
#define PF_COMP_0_MASK 0x0000000F
#define PF_COMP_0_SHIFT 0
-#define MAKE_PF(alpha, red, green, blue, size, c0, c1, c2, c3) \
+#define MAKE_PF(alpha, red, blue, green, size, c0, c1, c2, c3) \
cpu_to_le32(PF_BYTE_F | (alpha << PF_ALPHA_C_SHIFT) | \
(blue << PF_BLUE_C_SHIFT) | (green << PF_GREEN_C_SHIFT) | \
(red << PF_RED_C_SHIFT) | (c3 << PF_COMP_3_SHIFT) | \
@@ -954,10 +954,10 @@ static u32 fsl_diu_get_pixel_format(unsigned int bits_per_pixel)
switch (bits_per_pixel) {
case 32:
/* 0x88883316 */
- return MAKE_PF(3, 2, 1, 0, 3, 8, 8, 8, 8);
+ return MAKE_PF(3, 2, 0, 1, 3, 8, 8, 8, 8);
case 24:
/* 0x88082219 */
- return MAKE_PF(4, 0, 1, 2, 2, 8, 8, 8, 0);
+ return MAKE_PF(4, 0, 1, 2, 2, 0, 8, 8, 8);
case 16:
/* 0x65053118 */
return MAKE_PF(4, 2, 1, 0, 1, 5, 6, 5, 0);
@@ -1232,16 +1232,6 @@ static int fsl_diu_ioctl(struct fb_info *info, unsigned int cmd,
return 0;
}
-static inline void fsl_diu_enable_interrupts(struct fsl_diu_data *data)
-{
- u32 int_mask = INT_UNDRUN; /* enable underrun detection */
-
- if (IS_ENABLED(CONFIG_NOT_COHERENT_CACHE))
- int_mask |= INT_VSYNC; /* enable vertical sync */
-
- clrbits32(&data->diu_reg->int_mask, int_mask);
-}
-
/* turn on fb if count == 1
*/
static int fsl_diu_open(struct fb_info *info, int user)
@@ -1261,7 +1251,19 @@ static int fsl_diu_open(struct fb_info *info, int user)
if (res < 0)
mfbi->count--;
else {
- fsl_diu_enable_interrupts(mfbi->parent);
+ struct fsl_diu_data *data = mfbi->parent;
+
+#ifdef CONFIG_NOT_COHERENT_CACHE
+ /*
+ * Enable underrun detection and vertical sync
+ * interrupts.
+ */
+ clrbits32(&data->diu_reg->int_mask,
+ INT_UNDRUN | INT_VSYNC);
+#else
+ /* Enable underrun detection */
+ clrbits32(&data->diu_reg->int_mask, INT_UNDRUN);
+#endif
fsl_diu_enable_panel(info);
}
}
@@ -1281,18 +1283,9 @@ static int fsl_diu_release(struct fb_info *info, int user)
mfbi->count--;
if (mfbi->count == 0) {
struct fsl_diu_data *data = mfbi->parent;
- bool disable = true;
- int i;
- /* Disable interrupts only if all AOIs are closed */
- for (i = 0; i < NUM_AOIS; i++) {
- struct mfb_info *mi = data->fsl_diu_info[i].par;
-
- if (mi->count)
- disable = false;
- }
- if (disable)
- out_be32(&data->diu_reg->int_mask, 0xffffffff);
+ /* Disable interrupts */
+ out_be32(&data->diu_reg->int_mask, 0xffffffff);
fsl_diu_disable_panel(info);
}
@@ -1621,6 +1614,14 @@ static int fsl_diu_probe(struct platform_device *pdev)
out_be32(&data->diu_reg->desc[1], data->dummy_ad.paddr);
out_be32(&data->diu_reg->desc[2], data->dummy_ad.paddr);
+ for (i = 0; i < NUM_AOIS; i++) {
+ ret = install_fb(&data->fsl_diu_info[i]);
+ if (ret) {
+ dev_err(&pdev->dev, "could not register fb %d\n", i);
+ goto error;
+ }
+ }
+
/*
* Older versions of U-Boot leave interrupts enabled, so disable
* all of them and clear the status register.
@@ -1629,21 +1630,12 @@ static int fsl_diu_probe(struct platform_device *pdev)
in_be32(&data->diu_reg->int_status);
ret = request_irq(data->irq, fsl_diu_isr, 0, "fsl-diu-fb",
- data->diu_reg);
+ &data->diu_reg);
if (ret) {
dev_err(&pdev->dev, "could not claim irq\n");
goto error;
}
- for (i = 0; i < NUM_AOIS; i++) {
- ret = install_fb(&data->fsl_diu_info[i]);
- if (ret) {
- dev_err(&pdev->dev, "could not register fb %d\n", i);
- free_irq(data->irq, data->diu_reg);
- goto error;
- }
- }
-
sysfs_attr_init(&data->dev_attr.attr);
data->dev_attr.attr.name = "monitor";
data->dev_attr.attr.mode = S_IRUGO|S_IWUSR;
@@ -1675,7 +1667,7 @@ static int fsl_diu_remove(struct platform_device *pdev)
data = dev_get_drvdata(&pdev->dev);
disable_lcdc(&data->fsl_diu_info[0]);
- free_irq(data->irq, data->diu_reg);
+ free_irq(data->irq, &data->diu_reg);
for (i = 0; i < NUM_AOIS; i++)
uninstall_fb(&data->fsl_diu_info[i]);
diff --git a/drivers/w1/masters/w1-gpio.c b/drivers/w1/masters/w1-gpio.c
index 012817a..85b363a 100644
--- a/drivers/w1/masters/w1-gpio.c
+++ b/drivers/w1/masters/w1-gpio.c
@@ -72,7 +72,7 @@ static int w1_gpio_probe_dt(struct platform_device *pdev)
return 0;
}
-static int w1_gpio_probe(struct platform_device *pdev)
+static int __init w1_gpio_probe(struct platform_device *pdev)
{
struct w1_bus_master *master;
struct w1_gpio_platform_data *pdata;
@@ -158,7 +158,7 @@ static int w1_gpio_probe(struct platform_device *pdev)
return err;
}
-static int w1_gpio_remove(struct platform_device *pdev)
+static int __exit w1_gpio_remove(struct platform_device *pdev)
{
struct w1_bus_master *master = platform_get_drvdata(pdev);
struct w1_gpio_platform_data *pdata = pdev->dev.platform_data;
@@ -210,7 +210,7 @@ static struct platform_driver w1_gpio_driver = {
.of_match_table = of_match_ptr(w1_gpio_dt_ids),
},
.probe = w1_gpio_probe,
- .remove = w1_gpio_remove,
+ .remove = __exit_p(w1_gpio_remove),
.suspend = w1_gpio_suspend,
.resume = w1_gpio_resume,
};
diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c
index 7ce277d..7994d933 100644
--- a/drivers/w1/w1.c
+++ b/drivers/w1/w1.c
@@ -924,8 +924,7 @@ void w1_search(struct w1_master *dev, u8 search_type, w1_slave_found_callback cb
tmp64 = (triplet_ret >> 2);
rn |= (tmp64 << i);
- /* ensure we're called from kthread and not by netlink callback */
- if (!dev->priv && kthread_should_stop()) {
+ if (kthread_should_stop()) {
mutex_unlock(&dev->bus_mutex);
dev_dbg(&dev->dev, "Abort w1_search\n");
return;
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 19fa73a..7f809fd 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -79,7 +79,6 @@ config DA9052_WATCHDOG
config DA9055_WATCHDOG
tristate "Dialog Semiconductor DA9055 Watchdog"
depends on MFD_DA9055
- select WATCHDOG_CORE
help
If you say yes here you get support for watchdog on the Dialog
Semiconductor DA9055 PMIC.
diff --git a/drivers/watchdog/sp5100_tco.c b/drivers/watchdog/sp5100_tco.c
index 0e9d8c4..2b0e000 100644
--- a/drivers/watchdog/sp5100_tco.c
+++ b/drivers/watchdog/sp5100_tco.c
@@ -40,12 +40,13 @@
#include "sp5100_tco.h"
/* Module and version information */
-#define TCO_VERSION "0.05"
+#define TCO_VERSION "0.03"
#define TCO_MODULE_NAME "SP5100 TCO timer"
#define TCO_DRIVER_NAME TCO_MODULE_NAME ", v" TCO_VERSION
/* internal variables */
static u32 tcobase_phys;
+static u32 resbase_phys;
static u32 tco_wdt_fired;
static void __iomem *tcobase;
static unsigned int pm_iobase;
@@ -53,6 +54,10 @@ static DEFINE_SPINLOCK(tco_lock); /* Guards the hardware */
static unsigned long timer_alive;
static char tco_expect_close;
static struct pci_dev *sp5100_tco_pci;
+static struct resource wdt_res = {
+ .name = "Watchdog Timer",
+ .flags = IORESOURCE_MEM,
+};
/* the watchdog platform device */
static struct platform_device *sp5100_tco_platform_device;
@@ -70,6 +75,12 @@ module_param(nowayout, bool, 0);
MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started."
" (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
+static unsigned int force_addr;
+module_param(force_addr, uint, 0);
+MODULE_PARM_DESC(force_addr, "Force the use of specified MMIO address."
+ " ONLY USE THIS PARAMETER IF YOU REALLY KNOW"
+ " WHAT YOU ARE DOING (default=none)");
+
/*
* Some TCO specific functions
*/
@@ -165,6 +176,39 @@ static void tco_timer_enable(void)
}
}
+static void tco_timer_disable(void)
+{
+ int val;
+
+ if (sp5100_tco_pci->revision >= 0x40) {
+ /* For SB800 or later */
+ /* Enable watchdog decode bit and Disable watchdog timer */
+ outb(SB800_PM_WATCHDOG_CONTROL, SB800_IO_PM_INDEX_REG);
+ val = inb(SB800_IO_PM_DATA_REG);
+ val |= SB800_PCI_WATCHDOG_DECODE_EN;
+ val |= SB800_PM_WATCHDOG_DISABLE;
+ outb(val, SB800_IO_PM_DATA_REG);
+ } else {
+ /* For SP5100 or SB7x0 */
+ /* Enable watchdog decode bit */
+ pci_read_config_dword(sp5100_tco_pci,
+ SP5100_PCI_WATCHDOG_MISC_REG,
+ &val);
+
+ val |= SP5100_PCI_WATCHDOG_DECODE_EN;
+
+ pci_write_config_dword(sp5100_tco_pci,
+ SP5100_PCI_WATCHDOG_MISC_REG,
+ val);
+
+ /* Disable Watchdog timer */
+ outb(SP5100_PM_WATCHDOG_CONTROL, SP5100_IO_PM_INDEX_REG);
+ val = inb(SP5100_IO_PM_DATA_REG);
+ val |= SP5100_PM_WATCHDOG_DISABLE;
+ outb(val, SP5100_IO_PM_DATA_REG);
+ }
+}
+
/*
* /dev/watchdog handling
*/
@@ -415,8 +459,74 @@ static unsigned char sp5100_tco_setupdevice(void)
} else
pr_debug("SBResource_MMIO is disabled(0x%04x)\n", val);
- pr_notice("failed to find MMIO address, giving up.\n");
- goto unreg_region;
+ /*
+ * Lastly re-programming the watchdog timer MMIO address,
+ * This method is a last resort...
+ *
+ * Before re-programming, to ensure that the watchdog timer
+ * is disabled, disable the watchdog timer.
+ */
+ tco_timer_disable();
+
+ if (force_addr) {
+ /*
+ * Force the use of watchdog timer MMIO address, and aligned to
+ * 8byte boundary.
+ */
+ force_addr &= ~0x7;
+ val = force_addr;
+
+ pr_info("Force the use of 0x%04x as MMIO address\n", val);
+ } else {
+ /*
+ * Get empty slot into the resource tree for watchdog timer.
+ */
+ if (allocate_resource(&iomem_resource,
+ &wdt_res,
+ SP5100_WDT_MEM_MAP_SIZE,
+ 0xf0000000,
+ 0xfffffff8,
+ 0x8,
+ NULL,
+ NULL)) {
+ pr_err("MMIO allocation failed\n");
+ goto unreg_region;
+ }
+
+ val = resbase_phys = wdt_res.start;
+ pr_debug("Got 0x%04x from resource tree\n", val);
+ }
+
+ /* Restore to the low three bits, if chipset is SB8x0(or later) */
+ if (sp5100_tco_pci->revision >= 0x40) {
+ u8 reserved_bit;
+ reserved_bit = inb(base_addr) & 0x7;
+ val |= (u32)reserved_bit;
+ }
+
+ /* Re-programming the watchdog timer base address */
+ outb(base_addr+0, index_reg);
+ /* Low three bits of BASE are reserved */
+ outb((val >> 0) & 0xf8, data_reg);
+ outb(base_addr+1, index_reg);
+ outb((val >> 8) & 0xff, data_reg);
+ outb(base_addr+2, index_reg);
+ outb((val >> 16) & 0xff, data_reg);
+ outb(base_addr+3, index_reg);
+ outb((val >> 24) & 0xff, data_reg);
+
+ /*
+ * Clear unnecessary the low three bits,
+ * if chipset is SB8x0(or later)
+ */
+ if (sp5100_tco_pci->revision >= 0x40)
+ val &= ~0x7;
+
+ if (!request_mem_region_exclusive(val, SP5100_WDT_MEM_MAP_SIZE,
+ dev_name)) {
+ pr_err("MMIO address 0x%04x already in use\n", val);
+ goto unreg_resource;
+ }
setup_wdt:
tcobase_phys = val;
@@ -456,6 +566,9 @@ setup_wdt:
unreg_mem_region:
release_mem_region(tcobase_phys, SP5100_WDT_MEM_MAP_SIZE);
+unreg_resource:
+ if (resbase_phys)
+ release_resource(&wdt_res);
unreg_region:
release_region(pm_iobase, SP5100_PM_IOPORTS_SIZE);
exit:
@@ -465,6 +578,7 @@ exit:
static int sp5100_tco_init(struct platform_device *dev)
{
int ret;
+ char addr_str[16];
/*
* Check whether or not the hardware watchdog is there. If found, then
@@ -496,14 +610,23 @@ static int sp5100_tco_init(struct platform_device *dev)
clear_bit(0, &timer_alive);
/* Show module parameters */
- pr_info("initialized (0x%p). heartbeat=%d sec (nowayout=%d)\n",
- tcobase, heartbeat, nowayout);
+ if (force_addr == tcobase_phys)
+ /* The force_addr is vaild */
+ sprintf(addr_str, "0x%04x", force_addr);
+ else
+ strcpy(addr_str, "none");
+
+ pr_info("initialized (0x%p). heartbeat=%d sec (nowayout=%d, "
+ "force_addr=%s)\n",
+ tcobase, heartbeat, nowayout, addr_str);
return 0;
exit:
iounmap(tcobase);
release_mem_region(tcobase_phys, SP5100_WDT_MEM_MAP_SIZE);
+ if (resbase_phys)
+ release_resource(&wdt_res);
release_region(pm_iobase, SP5100_PM_IOPORTS_SIZE);
return ret;
}
@@ -518,6 +641,8 @@ static void sp5100_tco_cleanup(void)
misc_deregister(&sp5100_tco_miscdev);
iounmap(tcobase);
release_mem_region(tcobase_phys, SP5100_WDT_MEM_MAP_SIZE);
+ if (resbase_phys)
+ release_resource(&wdt_res);
release_region(pm_iobase, SP5100_PM_IOPORTS_SIZE);
}
diff --git a/drivers/watchdog/sp5100_tco.h b/drivers/watchdog/sp5100_tco.h
index 2b28c00..71594a0 100644
--- a/drivers/watchdog/sp5100_tco.h
+++ b/drivers/watchdog/sp5100_tco.h
@@ -57,7 +57,7 @@
#define SB800_PM_WATCHDOG_DISABLE (1 << 2)
#define SB800_PM_WATCHDOG_SECOND_RES (3 << 0)
#define SB800_ACPI_MMIO_DECODE_EN (1 << 0)
-#define SB800_ACPI_MMIO_SEL (1 << 1)
+#define SB800_ACPI_MMIO_SEL (1 << 2)
#define SB800_PM_WDT_MMIO_OFFSET 0xB00
diff --git a/drivers/xen/events.c b/drivers/xen/events.c
index 8aa3867..74d77df 100644
--- a/drivers/xen/events.c
+++ b/drivers/xen/events.c
@@ -388,23 +388,11 @@ static void unmask_evtchn(int port)
if (unlikely((cpu != cpu_from_evtchn(port))))
do_hypercall = 1;
- else {
- /*
- * Need to clear the mask before checking pending to
- * avoid a race with an event becoming pending.
- *
- * EVTCHNOP_unmask will only trigger an upcall if the
- * mask bit was set, so if a hypercall is needed
- * remask the event.
- */
- sync_clear_bit(port, &s->evtchn_mask[0]);
+ else
evtchn_pending = sync_test_bit(port, &s->evtchn_pending[0]);
- if (unlikely(evtchn_pending && xen_hvm_domain())) {
- sync_set_bit(port, &s->evtchn_mask[0]);
- do_hypercall = 1;
- }
- }
+ if (unlikely(evtchn_pending && xen_hvm_domain()))
+ do_hypercall = 1;
/* Slow path (hypercall) if this is a non-local port or if this is
* an hvm domain and an event is pending (hvm domains don't have
@@ -415,6 +403,8 @@ static void unmask_evtchn(int port)
} else {
struct vcpu_info *vcpu_info = __this_cpu_read(xen_vcpu);
+ sync_clear_bit(port, &s->evtchn_mask[0]);
+
/*
* The following is basically the equivalent of
* 'hw_resend_irq'. Just like a real IO-APIC we 'lose
diff --git a/drivers/xen/evtchn.c b/drivers/xen/evtchn.c
index b2db77e..b1f60a0 100644
--- a/drivers/xen/evtchn.c
+++ b/drivers/xen/evtchn.c
@@ -269,14 +269,6 @@ static int evtchn_bind_to_user(struct per_user_data *u, int port)
u->name, (void *)(unsigned long)port);
if (rc >= 0)
rc = evtchn_make_refcounted(port);
- else {
- /* bind failed, should close the port now */
- struct evtchn_close close;
- close.port = port;
- if (HYPERVISOR_event_channel_op(EVTCHNOP_close, &close) != 0)
- BUG();
- set_port_user(port, NULL);
- }
return rc;
}
@@ -285,8 +277,6 @@ static void evtchn_unbind_from_user(struct per_user_data *u, int port)
{
int irq = irq_from_evtchn(port);
- BUG_ON(irq < 0);
-
unbind_from_irqhandler(irq, (void *)(unsigned long)port);
set_port_user(port, NULL);
diff --git a/drivers/xen/fallback.c b/drivers/xen/fallback.c
index b04fb64..0ef7c4d 100644
--- a/drivers/xen/fallback.c
+++ b/drivers/xen/fallback.c
@@ -44,7 +44,7 @@ int xen_event_channel_op_compat(int cmd, void *arg)
}
EXPORT_SYMBOL_GPL(xen_event_channel_op_compat);
-int xen_physdev_op_compat(int cmd, void *arg)
+int HYPERVISOR_physdev_op_compat(int cmd, void *arg)
{
struct physdev_op op;
int rc;
@@ -78,4 +78,3 @@ int xen_physdev_op_compat(int cmd, void *arg)
return rc;
}
-EXPORT_SYMBOL_GPL(xen_physdev_op_compat);
diff --git a/drivers/xen/xen-pciback/pci_stub.c b/drivers/xen/xen-pciback/pci_stub.c
index a2278ba..9204126 100644
--- a/drivers/xen/xen-pciback/pci_stub.c
+++ b/drivers/xen/xen-pciback/pci_stub.c
@@ -17,7 +17,6 @@
#include <xen/events.h>
#include <asm/xen/pci.h>
#include <asm/xen/hypervisor.h>
-#include <xen/interface/physdev.h>
#include "pciback.h"
#include "conf_space.h"
#include "conf_space_quirks.h"
@@ -86,52 +85,37 @@ static struct pcistub_device *pcistub_device_alloc(struct pci_dev *dev)
static void pcistub_device_release(struct kref *kref)
{
struct pcistub_device *psdev;
- struct pci_dev *dev;
struct xen_pcibk_dev_data *dev_data;
psdev = container_of(kref, struct pcistub_device, kref);
- dev = psdev->dev;
- dev_data = pci_get_drvdata(dev);
+ dev_data = pci_get_drvdata(psdev->dev);
- dev_dbg(&dev->dev, "pcistub_device_release\n");
+ dev_dbg(&psdev->dev->dev, "pcistub_device_release\n");
- xen_unregister_device_domain_owner(dev);
+ xen_unregister_device_domain_owner(psdev->dev);
/* Call the reset function which does not take lock as this
* is called from "unbind" which takes a device_lock mutex.
*/
- __pci_reset_function_locked(dev);
- if (pci_load_and_free_saved_state(dev, &dev_data->pci_saved_state))
- dev_dbg(&dev->dev, "Could not reload PCI state\n");
- else
- pci_restore_state(dev);
-
- if (pci_find_capability(dev, PCI_CAP_ID_MSIX)) {
- struct physdev_pci_device ppdev = {
- .seg = pci_domain_nr(dev->bus),
- .bus = dev->bus->number,
- .devfn = dev->devfn
- };
- int err = HYPERVISOR_physdev_op(PHYSDEVOP_release_msix,
- &ppdev);
-
- if (err)
- dev_warn(&dev->dev, "MSI-X release failed (%d)\n",
- err);
- }
+ __pci_reset_function_locked(psdev->dev);
+ if (pci_load_and_free_saved_state(psdev->dev,
+ &dev_data->pci_saved_state)) {
+ dev_dbg(&psdev->dev->dev, "Could not reload PCI state\n");
+ } else
+ pci_restore_state(psdev->dev);
/* Disable the device */
- xen_pcibk_reset_device(dev);
+ xen_pcibk_reset_device(psdev->dev);
kfree(dev_data);
- pci_set_drvdata(dev, NULL);
+ pci_set_drvdata(psdev->dev, NULL);
/* Clean-up the device */
- xen_pcibk_config_free_dyn_fields(dev);
- xen_pcibk_config_free_dev(dev);
+ xen_pcibk_config_free_dyn_fields(psdev->dev);
+ xen_pcibk_config_free_dev(psdev->dev);
- dev->dev_flags &= ~PCI_DEV_FLAGS_ASSIGNED;
- pci_dev_put(dev);
+ psdev->dev->dev_flags &= ~PCI_DEV_FLAGS_ASSIGNED;
+ pci_dev_put(psdev->dev);
kfree(psdev);
}
@@ -371,19 +355,6 @@ static int pcistub_init_device(struct pci_dev *dev)
if (err)
goto config_release;
- if (pci_find_capability(dev, PCI_CAP_ID_MSIX)) {
- struct physdev_pci_device ppdev = {
- .seg = pci_domain_nr(dev->bus),
- .bus = dev->bus->number,
- .devfn = dev->devfn
- };
-
- err = HYPERVISOR_physdev_op(PHYSDEVOP_prepare_msix, &ppdev);
- if (err)
- dev_err(&dev->dev, "MSI-X preparation failed (%d)\n",
- err);
- }
-
/* We need the device active to save the state. */
dev_dbg(&dev->dev, "save state of device\n");
pci_save_state(dev);
diff --git a/drivers/xen/xen-pciback/pciback_ops.c b/drivers/xen/xen-pciback/pciback_ops.c
index b98cf0c..37c1f82 100644
--- a/drivers/xen/xen-pciback/pciback_ops.c
+++ b/drivers/xen/xen-pciback/pciback_ops.c
@@ -113,8 +113,7 @@ void xen_pcibk_reset_device(struct pci_dev *dev)
if (dev->msi_enabled)
pci_disable_msi(dev);
#endif
- if (pci_is_enabled(dev))
- pci_disable_device(dev);
+ pci_disable_device(dev);
pci_write_config_word(dev, PCI_COMMAND, 0);
diff --git a/drivers/xen/xenbus/xenbus_client.c b/drivers/xen/xenbus/xenbus_client.c
index 61786be..bcf3ba4 100644
--- a/drivers/xen/xenbus/xenbus_client.c
+++ b/drivers/xen/xenbus/xenbus_client.c
@@ -30,7 +30,6 @@
* IN THE SOFTWARE.
*/
-#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/spinlock.h>